Statistics
| Branch: | Revision:

root / hw / mips_malta.c @ 738012be

History | View | Annotate | Download (32.1 kB)

1
/*
2
 * QEMU Malta board support
3
 *
4
 * Copyright (c) 2006 Aurelien Jarno
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24

    
25
#include "hw.h"
26
#include "pc.h"
27
#include "fdc.h"
28
#include "net.h"
29
#include "boards.h"
30
#include "smbus.h"
31
#include "block.h"
32
#include "flash.h"
33
#include "mips.h"
34
#include "mips_cpudevs.h"
35
#include "pci.h"
36
#include "usb-uhci.h"
37
#include "vmware_vga.h"
38
#include "qemu-char.h"
39
#include "sysemu.h"
40
#include "audio/audio.h"
41
#include "boards.h"
42
#include "qemu-log.h"
43
#include "mips-bios.h"
44
#include "ide.h"
45
#include "loader.h"
46
#include "elf.h"
47
#include "mc146818rtc.h"
48

    
49
//#define DEBUG_BOARD_INIT
50

    
51
#define ENVP_ADDR                0x80002000l
52
#define ENVP_NB_ENTRIES                 16
53
#define ENVP_ENTRY_SIZE                 256
54

    
55
#define MAX_IDE_BUS 2
56

    
57
typedef struct {
58
    uint32_t leds;
59
    uint32_t brk;
60
    uint32_t gpout;
61
    uint32_t i2cin;
62
    uint32_t i2coe;
63
    uint32_t i2cout;
64
    uint32_t i2csel;
65
    CharDriverState *display;
66
    char display_text[9];
67
    SerialState *uart;
68
} MaltaFPGAState;
69

    
70
static PITState *pit;
71

    
72
static struct _loaderparams {
73
    int ram_size;
74
    const char *kernel_filename;
75
    const char *kernel_cmdline;
76
    const char *initrd_filename;
77
} loaderparams;
78

    
79
/* Malta FPGA */
80
static void malta_fpga_update_display(void *opaque)
81
{
82
    char leds_text[9];
83
    int i;
84
    MaltaFPGAState *s = opaque;
85

    
86
    for (i = 7 ; i >= 0 ; i--) {
87
        if (s->leds & (1 << i))
88
            leds_text[i] = '#';
89
        else
90
            leds_text[i] = ' ';
91
    }
92
    leds_text[8] = '\0';
93

    
94
    qemu_chr_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text);
95
    qemu_chr_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text);
96
}
97

    
98
/*
99
 * EEPROM 24C01 / 24C02 emulation.
100
 *
101
 * Emulation for serial EEPROMs:
102
 * 24C01 - 1024 bit (128 x 8)
103
 * 24C02 - 2048 bit (256 x 8)
104
 *
105
 * Typical device names include Microchip 24C02SC or SGS Thomson ST24C02.
106
 */
107

    
108
//~ #define DEBUG
109

    
110
#if defined(DEBUG)
111
#  define logout(fmt, ...) fprintf(stderr, "MALTA\t%-24s" fmt, __func__, ## __VA_ARGS__)
112
#else
113
#  define logout(fmt, ...) ((void)0)
114
#endif
115

    
116
struct _eeprom24c0x_t {
117
  uint8_t tick;
118
  uint8_t address;
119
  uint8_t command;
120
  uint8_t ack;
121
  uint8_t scl;
122
  uint8_t sda;
123
  uint8_t data;
124
  //~ uint16_t size;
125
  uint8_t contents[256];
126
};
127

    
128
typedef struct _eeprom24c0x_t eeprom24c0x_t;
129

    
130
static eeprom24c0x_t eeprom = {
131
    .contents = {
132
        /* 00000000: */ 0x80,0x08,0x04,0x0D,0x0A,0x01,0x40,0x00,
133
        /* 00000008: */ 0x01,0x75,0x54,0x00,0x82,0x08,0x00,0x01,
134
        /* 00000010: */ 0x8F,0x04,0x02,0x01,0x01,0x00,0x0E,0x00,
135
        /* 00000018: */ 0x00,0x00,0x00,0x14,0x0F,0x14,0x2D,0x40,
136
        /* 00000020: */ 0x15,0x08,0x15,0x08,0x00,0x00,0x00,0x00,
137
        /* 00000028: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
138
        /* 00000030: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
139
        /* 00000038: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x12,0xD0,
140
        /* 00000040: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
141
        /* 00000048: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
142
        /* 00000050: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
143
        /* 00000058: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
144
        /* 00000060: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
145
        /* 00000068: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
146
        /* 00000070: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
147
        /* 00000078: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x64,0xF4,
148
    },
149
};
150

    
151
static uint8_t eeprom24c0x_read(void)
152
{
153
    logout("%u: scl = %u, sda = %u, data = 0x%02x\n",
154
        eeprom.tick, eeprom.scl, eeprom.sda, eeprom.data);
155
    return eeprom.sda;
156
}
157

    
158
static void eeprom24c0x_write(int scl, int sda)
159
{
160
    if (eeprom.scl && scl && (eeprom.sda != sda)) {
161
        logout("%u: scl = %u->%u, sda = %u->%u i2c %s\n",
162
                eeprom.tick, eeprom.scl, scl, eeprom.sda, sda, sda ? "stop" : "start");
163
        if (!sda) {
164
            eeprom.tick = 1;
165
            eeprom.command = 0;
166
        }
167
    } else if (eeprom.tick == 0 && !eeprom.ack) {
168
        /* Waiting for start. */
169
        logout("%u: scl = %u->%u, sda = %u->%u wait for i2c start\n",
170
                eeprom.tick, eeprom.scl, scl, eeprom.sda, sda);
171
    } else if (!eeprom.scl && scl) {
172
        logout("%u: scl = %u->%u, sda = %u->%u trigger bit\n",
173
                eeprom.tick, eeprom.scl, scl, eeprom.sda, sda);
174
        if (eeprom.ack) {
175
            logout("\ti2c ack bit = 0\n");
176
            sda = 0;
177
            eeprom.ack = 0;
178
        } else if (eeprom.sda == sda) {
179
            uint8_t bit = (sda != 0);
180
            logout("\ti2c bit = %d\n", bit);
181
            if (eeprom.tick < 9) {
182
                eeprom.command <<= 1;
183
                eeprom.command += bit;
184
                eeprom.tick++;
185
                if (eeprom.tick == 9) {
186
                    logout("\tcommand 0x%04x, %s\n", eeprom.command, bit ? "read" : "write");
187
                    eeprom.ack = 1;
188
                }
189
            } else if (eeprom.tick < 17) {
190
                if (eeprom.command & 1) {
191
                    sda = ((eeprom.data & 0x80) != 0);
192
                }
193
                eeprom.address <<= 1;
194
                eeprom.address += bit;
195
                eeprom.tick++;
196
                eeprom.data <<= 1;
197
                if (eeprom.tick == 17) {
198
                    eeprom.data = eeprom.contents[eeprom.address];
199
                    logout("\taddress 0x%04x, data 0x%02x\n", eeprom.address, eeprom.data);
200
                    eeprom.ack = 1;
201
                    eeprom.tick = 0;
202
                }
203
            } else if (eeprom.tick >= 17) {
204
                sda = 0;
205
            }
206
        } else {
207
            logout("\tsda changed with raising scl\n");
208
        }
209
    } else {
210
        logout("%u: scl = %u->%u, sda = %u->%u\n", eeprom.tick, eeprom.scl, scl, eeprom.sda, sda);
211
    }
212
    eeprom.scl = scl;
213
    eeprom.sda = sda;
214
}
215

    
216
static uint32_t malta_fpga_readl(void *opaque, target_phys_addr_t addr)
217
{
218
    MaltaFPGAState *s = opaque;
219
    uint32_t val = 0;
220
    uint32_t saddr;
221

    
222
    saddr = (addr & 0xfffff);
223

    
224
    switch (saddr) {
225

    
226
    /* SWITCH Register */
227
    case 0x00200:
228
        val = 0x00000000;                /* All switches closed */
229
        break;
230

    
231
    /* STATUS Register */
232
    case 0x00208:
233
#ifdef TARGET_WORDS_BIGENDIAN
234
        val = 0x00000012;
235
#else
236
        val = 0x00000010;
237
#endif
238
        break;
239

    
240
    /* JMPRS Register */
241
    case 0x00210:
242
        val = 0x00;
243
        break;
244

    
245
    /* LEDBAR Register */
246
    case 0x00408:
247
        val = s->leds;
248
        break;
249

    
250
    /* BRKRES Register */
251
    case 0x00508:
252
        val = s->brk;
253
        break;
254

    
255
    /* UART Registers are handled directly by the serial device */
256

    
257
    /* GPOUT Register */
258
    case 0x00a00:
259
        val = s->gpout;
260
        break;
261

    
262
    /* XXX: implement a real I2C controller */
263

    
264
    /* GPINP Register */
265
    case 0x00a08:
266
        /* IN = OUT until a real I2C control is implemented */
267
        if (s->i2csel)
268
            val = s->i2cout;
269
        else
270
            val = 0x00;
271
        break;
272

    
273
    /* I2CINP Register */
274
    case 0x00b00:
275
        val = ((s->i2cin & ~1) | eeprom24c0x_read());
276
        break;
277

    
278
    /* I2COE Register */
279
    case 0x00b08:
280
        val = s->i2coe;
281
        break;
282

    
283
    /* I2COUT Register */
284
    case 0x00b10:
285
        val = s->i2cout;
286
        break;
287

    
288
    /* I2CSEL Register */
289
    case 0x00b18:
290
        val = s->i2csel;
291
        break;
292

    
293
    default:
294
#if 0
295
        printf ("malta_fpga_read: Bad register offset 0x" TARGET_FMT_lx "\n",
296
                addr);
297
#endif
298
        break;
299
    }
300
    return val;
301
}
302

    
303
static void malta_fpga_writel(void *opaque, target_phys_addr_t addr,
304
                              uint32_t val)
305
{
306
    MaltaFPGAState *s = opaque;
307
    uint32_t saddr;
308

    
309
    saddr = (addr & 0xfffff);
310

    
311
    switch (saddr) {
312

    
313
    /* SWITCH Register */
314
    case 0x00200:
315
        break;
316

    
317
    /* JMPRS Register */
318
    case 0x00210:
319
        break;
320

    
321
    /* LEDBAR Register */
322
    /* XXX: implement a 8-LED array */
323
    case 0x00408:
324
        s->leds = val & 0xff;
325
        break;
326

    
327
    /* ASCIIWORD Register */
328
    case 0x00410:
329
        snprintf(s->display_text, 9, "%08X", val);
330
        malta_fpga_update_display(s);
331
        break;
332

    
333
    /* ASCIIPOS0 to ASCIIPOS7 Registers */
334
    case 0x00418:
335
    case 0x00420:
336
    case 0x00428:
337
    case 0x00430:
338
    case 0x00438:
339
    case 0x00440:
340
    case 0x00448:
341
    case 0x00450:
342
        s->display_text[(saddr - 0x00418) >> 3] = (char) val;
343
        malta_fpga_update_display(s);
344
        break;
345

    
346
    /* SOFTRES Register */
347
    case 0x00500:
348
        if (val == 0x42)
349
            qemu_system_reset_request ();
350
        break;
351

    
352
    /* BRKRES Register */
353
    case 0x00508:
354
        s->brk = val & 0xff;
355
        break;
356

    
357
    /* UART Registers are handled directly by the serial device */
358

    
359
    /* GPOUT Register */
360
    case 0x00a00:
361
        s->gpout = val & 0xff;
362
        break;
363

    
364
    /* I2COE Register */
365
    case 0x00b08:
366
        s->i2coe = val & 0x03;
367
        break;
368

    
369
    /* I2COUT Register */
370
    case 0x00b10:
371
        eeprom24c0x_write(val & 0x02, val & 0x01);
372
        s->i2cout = val;
373
        break;
374

    
375
    /* I2CSEL Register */
376
    case 0x00b18:
377
        s->i2csel = val & 0x01;
378
        break;
379

    
380
    default:
381
#if 0
382
        printf ("malta_fpga_write: Bad register offset 0x" TARGET_FMT_lx "\n",
383
                addr);
384
#endif
385
        break;
386
    }
387
}
388

    
389
static CPUReadMemoryFunc * const malta_fpga_read[] = {
390
   malta_fpga_readl,
391
   malta_fpga_readl,
392
   malta_fpga_readl
393
};
394

    
395
static CPUWriteMemoryFunc * const malta_fpga_write[] = {
396
   malta_fpga_writel,
397
   malta_fpga_writel,
398
   malta_fpga_writel
399
};
400

    
401
static void malta_fpga_reset(void *opaque)
402
{
403
    MaltaFPGAState *s = opaque;
404

    
405
    s->leds   = 0x00;
406
    s->brk    = 0x0a;
407
    s->gpout  = 0x00;
408
    s->i2cin  = 0x3;
409
    s->i2coe  = 0x0;
410
    s->i2cout = 0x3;
411
    s->i2csel = 0x1;
412

    
413
    s->display_text[8] = '\0';
414
    snprintf(s->display_text, 9, "        ");
415
}
416

    
417
static void malta_fpga_led_init(CharDriverState *chr)
418
{
419
    qemu_chr_printf(chr, "\e[HMalta LEDBAR\r\n");
420
    qemu_chr_printf(chr, "+--------+\r\n");
421
    qemu_chr_printf(chr, "+        +\r\n");
422
    qemu_chr_printf(chr, "+--------+\r\n");
423
    qemu_chr_printf(chr, "\n");
424
    qemu_chr_printf(chr, "Malta ASCII\r\n");
425
    qemu_chr_printf(chr, "+--------+\r\n");
426
    qemu_chr_printf(chr, "+        +\r\n");
427
    qemu_chr_printf(chr, "+--------+\r\n");
428
}
429

    
430
static MaltaFPGAState *malta_fpga_init(target_phys_addr_t base, qemu_irq uart_irq, CharDriverState *uart_chr)
431
{
432
    MaltaFPGAState *s;
433
    int malta;
434

    
435
    s = (MaltaFPGAState *)qemu_mallocz(sizeof(MaltaFPGAState));
436

    
437
    malta = cpu_register_io_memory(malta_fpga_read,
438
                                   malta_fpga_write, s);
439

    
440
    cpu_register_physical_memory(base, 0x900, malta);
441
    /* 0xa00 is less than a page, so will still get the right offsets.  */
442
    cpu_register_physical_memory(base + 0xa00, 0x100000 - 0xa00, malta);
443

    
444
    s->display = qemu_chr_open("fpga", "vc:320x200", malta_fpga_led_init);
445

    
446
#ifdef TARGET_WORDS_BIGENDIAN
447
    s->uart = serial_mm_init(base + 0x900, 3, uart_irq, 230400, uart_chr, 1, 1);
448
#else
449
    s->uart = serial_mm_init(base + 0x900, 3, uart_irq, 230400, uart_chr, 1, 0);
450
#endif
451

    
452
    malta_fpga_reset(s);
453
    qemu_register_reset(malta_fpga_reset, s);
454

    
455
    return s;
456
}
457

    
458
/* Audio support */
459
static void audio_init (PCIBus *pci_bus)
460
{
461
    struct soundhw *c;
462
    int audio_enabled = 0;
463

    
464
    for (c = soundhw; !audio_enabled && c->name; ++c) {
465
        audio_enabled = c->enabled;
466
    }
467

    
468
    if (audio_enabled) {
469
        for (c = soundhw; c->name; ++c) {
470
            if (c->enabled) {
471
                c->init.init_pci(pci_bus);
472
            }
473
        }
474
    }
475
}
476

    
477
/* Network support */
478
static void network_init(void)
479
{
480
    int i;
481

    
482
    for(i = 0; i < nb_nics; i++) {
483
        NICInfo *nd = &nd_table[i];
484
        const char *default_devaddr = NULL;
485

    
486
        if (i == 0 && (!nd->model || strcmp(nd->model, "pcnet") == 0))
487
            /* The malta board has a PCNet card using PCI SLOT 11 */
488
            default_devaddr = "0b";
489

    
490
        pci_nic_init_nofail(nd, "pcnet", default_devaddr);
491
    }
492
}
493

    
494
/* ROM and pseudo bootloader
495

496
   The following code implements a very very simple bootloader. It first
497
   loads the registers a0 to a3 to the values expected by the OS, and
498
   then jump at the kernel address.
499

500
   The bootloader should pass the locations of the kernel arguments and
501
   environment variables tables. Those tables contain the 32-bit address
502
   of NULL terminated strings. The environment variables table should be
503
   terminated by a NULL address.
504

505
   For a simpler implementation, the number of kernel arguments is fixed
506
   to two (the name of the kernel and the command line), and the two
507
   tables are actually the same one.
508

509
   The registers a0 to a3 should contain the following values:
510
     a0 - number of kernel arguments
511
     a1 - 32-bit address of the kernel arguments table
512
     a2 - 32-bit address of the environment variables table
513
     a3 - RAM size in bytes
514
*/
515

    
516
static void write_bootloader (CPUState *env, uint8_t *base,
517
                              int64_t kernel_entry)
518
{
519
    uint32_t *p;
520

    
521
    /* Small bootloader */
522
    p = (uint32_t *)base;
523
    stl_raw(p++, 0x0bf00160);                                      /* j 0x1fc00580 */
524
    stl_raw(p++, 0x00000000);                                      /* nop */
525

    
526
    /* YAMON service vector */
527
    stl_raw(base + 0x500, 0xbfc00580);      /* start: */
528
    stl_raw(base + 0x504, 0xbfc0083c);      /* print_count: */
529
    stl_raw(base + 0x520, 0xbfc00580);      /* start: */
530
    stl_raw(base + 0x52c, 0xbfc00800);      /* flush_cache: */
531
    stl_raw(base + 0x534, 0xbfc00808);      /* print: */
532
    stl_raw(base + 0x538, 0xbfc00800);      /* reg_cpu_isr: */
533
    stl_raw(base + 0x53c, 0xbfc00800);      /* unred_cpu_isr: */
534
    stl_raw(base + 0x540, 0xbfc00800);      /* reg_ic_isr: */
535
    stl_raw(base + 0x544, 0xbfc00800);      /* unred_ic_isr: */
536
    stl_raw(base + 0x548, 0xbfc00800);      /* reg_esr: */
537
    stl_raw(base + 0x54c, 0xbfc00800);      /* unreg_esr: */
538
    stl_raw(base + 0x550, 0xbfc00800);      /* getchar: */
539
    stl_raw(base + 0x554, 0xbfc00800);      /* syscon_read: */
540

    
541

    
542
    /* Second part of the bootloader */
543
    p = (uint32_t *) (base + 0x580);
544
    stl_raw(p++, 0x24040002);                                      /* addiu a0, zero, 2 */
545
    stl_raw(p++, 0x3c1d0000 | (((ENVP_ADDR - 64) >> 16) & 0xffff)); /* lui sp, high(ENVP_ADDR) */
546
    stl_raw(p++, 0x37bd0000 | ((ENVP_ADDR - 64) & 0xffff));        /* ori sp, sp, low(ENVP_ADDR) */
547
    stl_raw(p++, 0x3c050000 | ((ENVP_ADDR >> 16) & 0xffff));       /* lui a1, high(ENVP_ADDR) */
548
    stl_raw(p++, 0x34a50000 | (ENVP_ADDR & 0xffff));               /* ori a1, a1, low(ENVP_ADDR) */
549
    stl_raw(p++, 0x3c060000 | (((ENVP_ADDR + 8) >> 16) & 0xffff)); /* lui a2, high(ENVP_ADDR + 8) */
550
    stl_raw(p++, 0x34c60000 | ((ENVP_ADDR + 8) & 0xffff));         /* ori a2, a2, low(ENVP_ADDR + 8) */
551
    stl_raw(p++, 0x3c070000 | (loaderparams.ram_size >> 16));     /* lui a3, high(ram_size) */
552
    stl_raw(p++, 0x34e70000 | (loaderparams.ram_size & 0xffff));  /* ori a3, a3, low(ram_size) */
553

    
554
    /* Load BAR registers as done by YAMON */
555
    stl_raw(p++, 0x3c09b400);                                      /* lui t1, 0xb400 */
556

    
557
#ifdef TARGET_WORDS_BIGENDIAN
558
    stl_raw(p++, 0x3c08df00);                                      /* lui t0, 0xdf00 */
559
#else
560
    stl_raw(p++, 0x340800df);                                      /* ori t0, r0, 0x00df */
561
#endif
562
    stl_raw(p++, 0xad280068);                                      /* sw t0, 0x0068(t1) */
563

    
564
    stl_raw(p++, 0x3c09bbe0);                                      /* lui t1, 0xbbe0 */
565

    
566
#ifdef TARGET_WORDS_BIGENDIAN
567
    stl_raw(p++, 0x3c08c000);                                      /* lui t0, 0xc000 */
568
#else
569
    stl_raw(p++, 0x340800c0);                                      /* ori t0, r0, 0x00c0 */
570
#endif
571
    stl_raw(p++, 0xad280048);                                      /* sw t0, 0x0048(t1) */
572
#ifdef TARGET_WORDS_BIGENDIAN
573
    stl_raw(p++, 0x3c084000);                                      /* lui t0, 0x4000 */
574
#else
575
    stl_raw(p++, 0x34080040);                                      /* ori t0, r0, 0x0040 */
576
#endif
577
    stl_raw(p++, 0xad280050);                                      /* sw t0, 0x0050(t1) */
578

    
579
#ifdef TARGET_WORDS_BIGENDIAN
580
    stl_raw(p++, 0x3c088000);                                      /* lui t0, 0x8000 */
581
#else
582
    stl_raw(p++, 0x34080080);                                      /* ori t0, r0, 0x0080 */
583
#endif
584
    stl_raw(p++, 0xad280058);                                      /* sw t0, 0x0058(t1) */
585
#ifdef TARGET_WORDS_BIGENDIAN
586
    stl_raw(p++, 0x3c083f00);                                      /* lui t0, 0x3f00 */
587
#else
588
    stl_raw(p++, 0x3408003f);                                      /* ori t0, r0, 0x003f */
589
#endif
590
    stl_raw(p++, 0xad280060);                                      /* sw t0, 0x0060(t1) */
591

    
592
#ifdef TARGET_WORDS_BIGENDIAN
593
    stl_raw(p++, 0x3c08c100);                                      /* lui t0, 0xc100 */
594
#else
595
    stl_raw(p++, 0x340800c1);                                      /* ori t0, r0, 0x00c1 */
596
#endif
597
    stl_raw(p++, 0xad280080);                                      /* sw t0, 0x0080(t1) */
598
#ifdef TARGET_WORDS_BIGENDIAN
599
    stl_raw(p++, 0x3c085e00);                                      /* lui t0, 0x5e00 */
600
#else
601
    stl_raw(p++, 0x3408005e);                                      /* ori t0, r0, 0x005e */
602
#endif
603
    stl_raw(p++, 0xad280088);                                      /* sw t0, 0x0088(t1) */
604

    
605
    /* Jump to kernel code */
606
    stl_raw(p++, 0x3c1f0000 | ((kernel_entry >> 16) & 0xffff));    /* lui ra, high(kernel_entry) */
607
    stl_raw(p++, 0x37ff0000 | (kernel_entry & 0xffff));            /* ori ra, ra, low(kernel_entry) */
608
    stl_raw(p++, 0x03e00008);                                      /* jr ra */
609
    stl_raw(p++, 0x00000000);                                      /* nop */
610

    
611
    /* YAMON subroutines */
612
    p = (uint32_t *) (base + 0x800);
613
    stl_raw(p++, 0x03e00008);                                     /* jr ra */
614
    stl_raw(p++, 0x24020000);                                     /* li v0,0 */
615
   /* 808 YAMON print */
616
    stl_raw(p++, 0x03e06821);                                     /* move t5,ra */
617
    stl_raw(p++, 0x00805821);                                     /* move t3,a0 */
618
    stl_raw(p++, 0x00a05021);                                     /* move t2,a1 */
619
    stl_raw(p++, 0x91440000);                                     /* lbu a0,0(t2) */
620
    stl_raw(p++, 0x254a0001);                                     /* addiu t2,t2,1 */
621
    stl_raw(p++, 0x10800005);                                     /* beqz a0,834 */
622
    stl_raw(p++, 0x00000000);                                     /* nop */
623
    stl_raw(p++, 0x0ff0021c);                                     /* jal 870 */
624
    stl_raw(p++, 0x00000000);                                     /* nop */
625
    stl_raw(p++, 0x08000205);                                     /* j 814 */
626
    stl_raw(p++, 0x00000000);                                     /* nop */
627
    stl_raw(p++, 0x01a00008);                                     /* jr t5 */
628
    stl_raw(p++, 0x01602021);                                     /* move a0,t3 */
629
    /* 0x83c YAMON print_count */
630
    stl_raw(p++, 0x03e06821);                                     /* move t5,ra */
631
    stl_raw(p++, 0x00805821);                                     /* move t3,a0 */
632
    stl_raw(p++, 0x00a05021);                                     /* move t2,a1 */
633
    stl_raw(p++, 0x00c06021);                                     /* move t4,a2 */
634
    stl_raw(p++, 0x91440000);                                     /* lbu a0,0(t2) */
635
    stl_raw(p++, 0x0ff0021c);                                     /* jal 870 */
636
    stl_raw(p++, 0x00000000);                                     /* nop */
637
    stl_raw(p++, 0x254a0001);                                     /* addiu t2,t2,1 */
638
    stl_raw(p++, 0x258cffff);                                     /* addiu t4,t4,-1 */
639
    stl_raw(p++, 0x1580fffa);                                     /* bnez t4,84c */
640
    stl_raw(p++, 0x00000000);                                     /* nop */
641
    stl_raw(p++, 0x01a00008);                                     /* jr t5 */
642
    stl_raw(p++, 0x01602021);                                     /* move a0,t3 */
643
    /* 0x870 */
644
    stl_raw(p++, 0x3c08b800);                                     /* lui t0,0xb400 */
645
    stl_raw(p++, 0x350803f8);                                     /* ori t0,t0,0x3f8 */
646
    stl_raw(p++, 0x91090005);                                     /* lbu t1,5(t0) */
647
    stl_raw(p++, 0x00000000);                                     /* nop */
648
    stl_raw(p++, 0x31290040);                                     /* andi t1,t1,0x40 */
649
    stl_raw(p++, 0x1120fffc);                                     /* beqz t1,878 <outch+0x8> */
650
    stl_raw(p++, 0x00000000);                                     /* nop */
651
    stl_raw(p++, 0x03e00008);                                     /* jr ra */
652
    stl_raw(p++, 0xa1040000);                                     /* sb a0,0(t0) */
653

    
654
}
655

    
656
static void prom_set(uint32_t* prom_buf, int index, const char *string, ...)
657
{
658
    va_list ap;
659
    int32_t table_addr;
660

    
661
    if (index >= ENVP_NB_ENTRIES)
662
        return;
663

    
664
    if (string == NULL) {
665
        prom_buf[index] = 0;
666
        return;
667
    }
668

    
669
    table_addr = sizeof(int32_t) * ENVP_NB_ENTRIES + index * ENVP_ENTRY_SIZE;
670
    prom_buf[index] = tswap32(ENVP_ADDR + table_addr);
671

    
672
    va_start(ap, string);
673
    vsnprintf((char *)prom_buf + table_addr, ENVP_ENTRY_SIZE, string, ap);
674
    va_end(ap);
675
}
676

    
677
/* Kernel */
678
static int64_t load_kernel (void)
679
{
680
    int64_t kernel_entry, kernel_high;
681
    long initrd_size;
682
    ram_addr_t initrd_offset;
683
    int big_endian;
684
    uint32_t *prom_buf;
685
    long prom_size;
686
    int prom_index = 0;
687

    
688
#ifdef TARGET_WORDS_BIGENDIAN
689
    big_endian = 1;
690
#else
691
    big_endian = 0;
692
#endif
693

    
694
    if (load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_to_phys, NULL,
695
                 (uint64_t *)&kernel_entry, NULL, (uint64_t *)&kernel_high,
696
                 big_endian, ELF_MACHINE, 1) < 0) {
697
        fprintf(stderr, "qemu: could not load kernel '%s'\n",
698
                loaderparams.kernel_filename);
699
        exit(1);
700
    }
701

    
702
    /* load initrd */
703
    initrd_size = 0;
704
    initrd_offset = 0;
705
    if (loaderparams.initrd_filename) {
706
        initrd_size = get_image_size (loaderparams.initrd_filename);
707
        if (initrd_size > 0) {
708
            initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & TARGET_PAGE_MASK;
709
            if (initrd_offset + initrd_size > ram_size) {
710
                fprintf(stderr,
711
                        "qemu: memory too small for initial ram disk '%s'\n",
712
                        loaderparams.initrd_filename);
713
                exit(1);
714
            }
715
            initrd_size = load_image_targphys(loaderparams.initrd_filename,
716
                                              initrd_offset,
717
                                              ram_size - initrd_offset);
718
        }
719
        if (initrd_size == (target_ulong) -1) {
720
            fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
721
                    loaderparams.initrd_filename);
722
            exit(1);
723
        }
724
    }
725

    
726
    /* Setup prom parameters. */
727
    prom_size = ENVP_NB_ENTRIES * (sizeof(int32_t) + ENVP_ENTRY_SIZE);
728
    prom_buf = qemu_malloc(prom_size);
729

    
730
    prom_set(prom_buf, prom_index++, loaderparams.kernel_filename);
731
    if (initrd_size > 0) {
732
        prom_set(prom_buf, prom_index++, "rd_start=0x%" PRIx64 " rd_size=%li %s",
733
                 cpu_mips_phys_to_kseg0(NULL, initrd_offset), initrd_size,
734
                 loaderparams.kernel_cmdline);
735
    } else {
736
        prom_set(prom_buf, prom_index++, loaderparams.kernel_cmdline);
737
    }
738

    
739
    prom_set(prom_buf, prom_index++, "memsize");
740
    prom_set(prom_buf, prom_index++, "%i", loaderparams.ram_size);
741
    prom_set(prom_buf, prom_index++, "modetty0");
742
    prom_set(prom_buf, prom_index++, "38400n8r");
743
    prom_set(prom_buf, prom_index++, NULL);
744

    
745
    rom_add_blob_fixed("prom", prom_buf, prom_size,
746
                       cpu_mips_kseg0_to_phys(NULL, ENVP_ADDR));
747

    
748
    return kernel_entry;
749
}
750

    
751
static void main_cpu_reset(void *opaque)
752
{
753
    CPUState *env = opaque;
754
    cpu_reset(env);
755

    
756
    /* The bootloader does not need to be rewritten as it is located in a
757
       read only location. The kernel location and the arguments table
758
       location does not change. */
759
    if (loaderparams.kernel_filename) {
760
        env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
761
    }
762
}
763

    
764
static void cpu_request_exit(void *opaque, int irq, int level)
765
{
766
    CPUState *env = cpu_single_env;
767

    
768
    if (env && level) {
769
        cpu_exit(env);
770
    }
771
}
772

    
773
static
774
void mips_malta_init (ram_addr_t ram_size,
775
                      const char *boot_device,
776
                      const char *kernel_filename, const char *kernel_cmdline,
777
                      const char *initrd_filename, const char *cpu_model)
778
{
779
    char *filename;
780
    ram_addr_t ram_offset;
781
    ram_addr_t bios_offset;
782
    target_long bios_size;
783
    int64_t kernel_entry;
784
    PCIBus *pci_bus;
785
    ISADevice *isa_dev;
786
    CPUState *env;
787
    ISADevice *rtc_state;
788
    FDCtrl *floppy_controller;
789
    MaltaFPGAState *malta_fpga;
790
    qemu_irq *i8259;
791
    qemu_irq *cpu_exit_irq;
792
    int piix4_devfn;
793
    uint8_t *eeprom_buf;
794
    i2c_bus *smbus;
795
    int i;
796
    DriveInfo *dinfo;
797
    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
798
    DriveInfo *fd[MAX_FD];
799
    int fl_idx = 0;
800
    int fl_sectors = 0;
801
    int be;
802

    
803
    /* Make sure the first 3 serial ports are associated with a device. */
804
    for(i = 0; i < 3; i++) {
805
        if (!serial_hds[i]) {
806
            char label[32];
807
            snprintf(label, sizeof(label), "serial%d", i);
808
            serial_hds[i] = qemu_chr_open(label, "null", NULL);
809
        }
810
    }
811

    
812
    /* init CPUs */
813
    if (cpu_model == NULL) {
814
#ifdef TARGET_MIPS64
815
        cpu_model = "20Kc";
816
#else
817
        cpu_model = "24Kf";
818
#endif
819
    }
820
    env = cpu_init(cpu_model);
821
    if (!env) {
822
        fprintf(stderr, "Unable to find CPU definition\n");
823
        exit(1);
824
    }
825
    qemu_register_reset(main_cpu_reset, env);
826

    
827
    /* allocate RAM */
828
    if (ram_size > (256 << 20)) {
829
        fprintf(stderr,
830
                "qemu: Too much memory for this machine: %d MB, maximum 256 MB\n",
831
                ((unsigned int)ram_size / (1 << 20)));
832
        exit(1);
833
    }
834
    ram_offset = qemu_ram_alloc(ram_size);
835
    bios_offset = qemu_ram_alloc(BIOS_SIZE);
836

    
837

    
838
    cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
839

    
840
    /* Map the bios at two physical locations, as on the real board. */
841
    cpu_register_physical_memory(0x1e000000LL,
842
                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
843
    cpu_register_physical_memory(0x1fc00000LL,
844
                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
845

    
846
#ifdef TARGET_WORDS_BIGENDIAN
847
    be = 1;
848
#else
849
    be = 0;
850
#endif
851
    /* FPGA */
852
    malta_fpga = malta_fpga_init(0x1f000000LL, env->irq[2], serial_hds[2]);
853

    
854
    /* Load firmware in flash / BIOS unless we boot directly into a kernel. */
855
    if (kernel_filename) {
856
        /* Write a small bootloader to the flash location. */
857
        loaderparams.ram_size = ram_size;
858
        loaderparams.kernel_filename = kernel_filename;
859
        loaderparams.kernel_cmdline = kernel_cmdline;
860
        loaderparams.initrd_filename = initrd_filename;
861
        kernel_entry = load_kernel();
862
        write_bootloader(env, qemu_get_ram_ptr(bios_offset), kernel_entry);
863
    } else {
864
        dinfo = drive_get(IF_PFLASH, 0, fl_idx);
865
        if (dinfo) {
866
            /* Load firmware from flash. */
867
            bios_size = 0x400000;
868
            fl_sectors = bios_size >> 16;
869
#ifdef DEBUG_BOARD_INIT
870
            printf("Register parallel flash %d size " TARGET_FMT_lx " at "
871
                   "offset %08lx addr %08llx '%s' %x\n",
872
                   fl_idx, bios_size, bios_offset, 0x1e000000LL,
873
                   bdrv_get_device_name(dinfo->bdrv), fl_sectors);
874
#endif
875
            pflash_cfi01_register(0x1e000000LL, bios_offset,
876
                                  dinfo->bdrv, 65536, fl_sectors,
877
                                  4, 0x0000, 0x0000, 0x0000, 0x0000, be);
878
            fl_idx++;
879
        } else {
880
            /* Load a BIOS image. */
881
            if (bios_name == NULL)
882
                bios_name = BIOS_FILENAME;
883
            filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
884
            if (filename) {
885
                bios_size = load_image_targphys(filename, 0x1fc00000LL,
886
                                                BIOS_SIZE);
887
                qemu_free(filename);
888
            } else {
889
                bios_size = -1;
890
            }
891
            if ((bios_size < 0 || bios_size > BIOS_SIZE) && !kernel_filename) {
892
                fprintf(stderr,
893
                        "qemu: Could not load MIPS bios '%s', and no -kernel argument was specified\n",
894
                        bios_name);
895
                exit(1);
896
            }
897
        }
898
        /* In little endian mode the 32bit words in the bios are swapped,
899
           a neat trick which allows bi-endian firmware. */
900
#ifndef TARGET_WORDS_BIGENDIAN
901
        {
902
            uint32_t *addr = qemu_get_ram_ptr(bios_offset);;
903
            uint32_t *end = addr + bios_size;
904
            while (addr < end) {
905
                bswap32s(addr);
906
            }
907
        }
908
#endif
909
    }
910

    
911
    /* Board ID = 0x420 (Malta Board with CoreLV)
912
       XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
913
       map to the board ID. */
914
    stl_phys(0x1fc00010LL, 0x00000420);
915

    
916
    /* Init internal devices */
917
    cpu_mips_irq_init_cpu(env);
918
    cpu_mips_clock_init(env);
919

    
920
    /* Interrupt controller */
921
    /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
922
    i8259 = i8259_init(env->irq[2]);
923

    
924
    /* Northbridge */
925
    pci_bus = pci_gt64120_init(i8259);
926

    
927
    /* Southbridge */
928

    
929
    if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
930
        fprintf(stderr, "qemu: too many IDE bus\n");
931
        exit(1);
932
    }
933

    
934
    for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
935
        hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
936
    }
937

    
938
    piix4_devfn = piix4_init(pci_bus, 80);
939
    isa_bus_irqs(i8259);
940
    pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);
941
    usb_uhci_piix4_init(pci_bus, piix4_devfn + 2);
942
    smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100, isa_reserve_irq(9),
943
                          NULL, NULL, 0);
944
    eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
945
    for (i = 0; i < 8; i++) {
946
        /* TODO: Populate SPD eeprom data.  */
947
        DeviceState *eeprom;
948
        eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");
949
        qdev_prop_set_uint8(eeprom, "address", 0x50 + i);
950
        qdev_prop_set_ptr(eeprom, "data", eeprom_buf + (i * 256));
951
        qdev_init_nofail(eeprom);
952
    }
953
    pit = pit_init(0x40, isa_reserve_irq(0));
954
    cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
955
    DMA_init(0, cpu_exit_irq);
956

    
957
    /* Super I/O */
958
    isa_dev = isa_create_simple("i8042");
959
 
960
    rtc_state = rtc_init(2000, NULL);
961
    serial_isa_init(0, serial_hds[0]);
962
    serial_isa_init(1, serial_hds[1]);
963
    if (parallel_hds[0])
964
        parallel_init(0, parallel_hds[0]);
965
    for(i = 0; i < MAX_FD; i++) {
966
        fd[i] = drive_get(IF_FLOPPY, 0, i);
967
    }
968
    floppy_controller = fdctrl_init_isa(fd);
969

    
970
    /* Sound card */
971
    audio_init(pci_bus);
972

    
973
    /* Network card */
974
    network_init();
975

    
976
    /* Optional PCI video card */
977
    if (cirrus_vga_enabled) {
978
        pci_cirrus_vga_init(pci_bus);
979
    } else if (vmsvga_enabled) {
980
        pci_vmsvga_init(pci_bus);
981
    } else if (std_vga_enabled) {
982
        pci_vga_init(pci_bus, 0, 0);
983
    }
984
}
985

    
986
static QEMUMachine mips_malta_machine = {
987
    .name = "malta",
988
    .desc = "MIPS Malta Core LV",
989
    .init = mips_malta_init,
990
    .is_default = 1,
991
};
992

    
993
static void mips_malta_machine_init(void)
994
{
995
    qemu_register_machine(&mips_malta_machine);
996
}
997

    
998
machine_init(mips_malta_machine_init);