Statistics
| Branch: | Revision:

root / hw / mips_malta.c @ 0dad6c35

History | View | Annotate | Download (34.5 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 "arch_init.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
#include "blockdev.h"
49
#include "exec-memory.h"
50
#include "sysbus.h"             /* SysBusDevice */
51

    
52
//#define DEBUG_BOARD_INIT
53

    
54
#define ENVP_ADDR                0x80002000l
55
#define ENVP_NB_ENTRIES                 16
56
#define ENVP_ENTRY_SIZE                 256
57

    
58
#define MAX_IDE_BUS 2
59

    
60
typedef struct {
61
    MemoryRegion iomem;
62
    MemoryRegion iomem_lo; /* 0 - 0x900 */
63
    MemoryRegion iomem_hi; /* 0xa00 - 0x100000 */
64
    uint32_t leds;
65
    uint32_t brk;
66
    uint32_t gpout;
67
    uint32_t i2cin;
68
    uint32_t i2coe;
69
    uint32_t i2cout;
70
    uint32_t i2csel;
71
    CharDriverState *display;
72
    char display_text[9];
73
    SerialState *uart;
74
} MaltaFPGAState;
75

    
76
typedef struct {
77
    SysBusDevice busdev;
78
    qemu_irq *i8259;
79
} MaltaState;
80

    
81
static ISADevice *pit;
82

    
83
static struct _loaderparams {
84
    int ram_size;
85
    const char *kernel_filename;
86
    const char *kernel_cmdline;
87
    const char *initrd_filename;
88
} loaderparams;
89

    
90
/* Malta FPGA */
91
static void malta_fpga_update_display(void *opaque)
92
{
93
    char leds_text[9];
94
    int i;
95
    MaltaFPGAState *s = opaque;
96

    
97
    for (i = 7 ; i >= 0 ; i--) {
98
        if (s->leds & (1 << i))
99
            leds_text[i] = '#';
100
        else
101
            leds_text[i] = ' ';
102
    }
103
    leds_text[8] = '\0';
104

    
105
    qemu_chr_fe_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text);
106
    qemu_chr_fe_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text);
107
}
108

    
109
/*
110
 * EEPROM 24C01 / 24C02 emulation.
111
 *
112
 * Emulation for serial EEPROMs:
113
 * 24C01 - 1024 bit (128 x 8)
114
 * 24C02 - 2048 bit (256 x 8)
115
 *
116
 * Typical device names include Microchip 24C02SC or SGS Thomson ST24C02.
117
 */
118

    
119
//~ #define DEBUG
120

    
121
#if defined(DEBUG)
122
#  define logout(fmt, ...) fprintf(stderr, "MALTA\t%-24s" fmt, __func__, ## __VA_ARGS__)
123
#else
124
#  define logout(fmt, ...) ((void)0)
125
#endif
126

    
127
struct _eeprom24c0x_t {
128
  uint8_t tick;
129
  uint8_t address;
130
  uint8_t command;
131
  uint8_t ack;
132
  uint8_t scl;
133
  uint8_t sda;
134
  uint8_t data;
135
  //~ uint16_t size;
136
  uint8_t contents[256];
137
};
138

    
139
typedef struct _eeprom24c0x_t eeprom24c0x_t;
140

    
141
static eeprom24c0x_t eeprom = {
142
    .contents = {
143
        /* 00000000: */ 0x80,0x08,0x04,0x0D,0x0A,0x01,0x40,0x00,
144
        /* 00000008: */ 0x01,0x75,0x54,0x00,0x82,0x08,0x00,0x01,
145
        /* 00000010: */ 0x8F,0x04,0x02,0x01,0x01,0x00,0x0E,0x00,
146
        /* 00000018: */ 0x00,0x00,0x00,0x14,0x0F,0x14,0x2D,0x40,
147
        /* 00000020: */ 0x15,0x08,0x15,0x08,0x00,0x00,0x00,0x00,
148
        /* 00000028: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
149
        /* 00000030: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
150
        /* 00000038: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x12,0xD0,
151
        /* 00000040: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
152
        /* 00000048: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
153
        /* 00000050: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
154
        /* 00000058: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
155
        /* 00000060: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
156
        /* 00000068: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
157
        /* 00000070: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
158
        /* 00000078: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x64,0xF4,
159
    },
160
};
161

    
162
static uint8_t eeprom24c0x_read(void)
163
{
164
    logout("%u: scl = %u, sda = %u, data = 0x%02x\n",
165
        eeprom.tick, eeprom.scl, eeprom.sda, eeprom.data);
166
    return eeprom.sda;
167
}
168

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

    
227
static uint64_t malta_fpga_read(void *opaque, target_phys_addr_t addr,
228
                                unsigned size)
229
{
230
    MaltaFPGAState *s = opaque;
231
    uint32_t val = 0;
232
    uint32_t saddr;
233

    
234
    saddr = (addr & 0xfffff);
235

    
236
    switch (saddr) {
237

    
238
    /* SWITCH Register */
239
    case 0x00200:
240
        val = 0x00000000;                /* All switches closed */
241
        break;
242

    
243
    /* STATUS Register */
244
    case 0x00208:
245
#ifdef TARGET_WORDS_BIGENDIAN
246
        val = 0x00000012;
247
#else
248
        val = 0x00000010;
249
#endif
250
        break;
251

    
252
    /* JMPRS Register */
253
    case 0x00210:
254
        val = 0x00;
255
        break;
256

    
257
    /* LEDBAR Register */
258
    case 0x00408:
259
        val = s->leds;
260
        break;
261

    
262
    /* BRKRES Register */
263
    case 0x00508:
264
        val = s->brk;
265
        break;
266

    
267
    /* UART Registers are handled directly by the serial device */
268

    
269
    /* GPOUT Register */
270
    case 0x00a00:
271
        val = s->gpout;
272
        break;
273

    
274
    /* XXX: implement a real I2C controller */
275

    
276
    /* GPINP Register */
277
    case 0x00a08:
278
        /* IN = OUT until a real I2C control is implemented */
279
        if (s->i2csel)
280
            val = s->i2cout;
281
        else
282
            val = 0x00;
283
        break;
284

    
285
    /* I2CINP Register */
286
    case 0x00b00:
287
        val = ((s->i2cin & ~1) | eeprom24c0x_read());
288
        break;
289

    
290
    /* I2COE Register */
291
    case 0x00b08:
292
        val = s->i2coe;
293
        break;
294

    
295
    /* I2COUT Register */
296
    case 0x00b10:
297
        val = s->i2cout;
298
        break;
299

    
300
    /* I2CSEL Register */
301
    case 0x00b18:
302
        val = s->i2csel;
303
        break;
304

    
305
    default:
306
#if 0
307
        printf ("malta_fpga_read: Bad register offset 0x" TARGET_FMT_lx "\n",
308
                addr);
309
#endif
310
        break;
311
    }
312
    return val;
313
}
314

    
315
static void malta_fpga_write(void *opaque, target_phys_addr_t addr,
316
                             uint64_t val, unsigned size)
317
{
318
    MaltaFPGAState *s = opaque;
319
    uint32_t saddr;
320

    
321
    saddr = (addr & 0xfffff);
322

    
323
    switch (saddr) {
324

    
325
    /* SWITCH Register */
326
    case 0x00200:
327
        break;
328

    
329
    /* JMPRS Register */
330
    case 0x00210:
331
        break;
332

    
333
    /* LEDBAR Register */
334
    /* XXX: implement a 8-LED array */
335
    case 0x00408:
336
        s->leds = val & 0xff;
337
        break;
338

    
339
    /* ASCIIWORD Register */
340
    case 0x00410:
341
        snprintf(s->display_text, 9, "%08X", (uint32_t)val);
342
        malta_fpga_update_display(s);
343
        break;
344

    
345
    /* ASCIIPOS0 to ASCIIPOS7 Registers */
346
    case 0x00418:
347
    case 0x00420:
348
    case 0x00428:
349
    case 0x00430:
350
    case 0x00438:
351
    case 0x00440:
352
    case 0x00448:
353
    case 0x00450:
354
        s->display_text[(saddr - 0x00418) >> 3] = (char) val;
355
        malta_fpga_update_display(s);
356
        break;
357

    
358
    /* SOFTRES Register */
359
    case 0x00500:
360
        if (val == 0x42)
361
            qemu_system_reset_request ();
362
        break;
363

    
364
    /* BRKRES Register */
365
    case 0x00508:
366
        s->brk = val & 0xff;
367
        break;
368

    
369
    /* UART Registers are handled directly by the serial device */
370

    
371
    /* GPOUT Register */
372
    case 0x00a00:
373
        s->gpout = val & 0xff;
374
        break;
375

    
376
    /* I2COE Register */
377
    case 0x00b08:
378
        s->i2coe = val & 0x03;
379
        break;
380

    
381
    /* I2COUT Register */
382
    case 0x00b10:
383
        eeprom24c0x_write(val & 0x02, val & 0x01);
384
        s->i2cout = val;
385
        break;
386

    
387
    /* I2CSEL Register */
388
    case 0x00b18:
389
        s->i2csel = val & 0x01;
390
        break;
391

    
392
    default:
393
#if 0
394
        printf ("malta_fpga_write: Bad register offset 0x" TARGET_FMT_lx "\n",
395
                addr);
396
#endif
397
        break;
398
    }
399
}
400

    
401
static const MemoryRegionOps malta_fpga_ops = {
402
    .read = malta_fpga_read,
403
    .write = malta_fpga_write,
404
    .endianness = DEVICE_NATIVE_ENDIAN,
405
};
406

    
407
static void malta_fpga_reset(void *opaque)
408
{
409
    MaltaFPGAState *s = opaque;
410

    
411
    s->leds   = 0x00;
412
    s->brk    = 0x0a;
413
    s->gpout  = 0x00;
414
    s->i2cin  = 0x3;
415
    s->i2coe  = 0x0;
416
    s->i2cout = 0x3;
417
    s->i2csel = 0x1;
418

    
419
    s->display_text[8] = '\0';
420
    snprintf(s->display_text, 9, "        ");
421
}
422

    
423
static void malta_fpga_led_init(CharDriverState *chr)
424
{
425
    qemu_chr_fe_printf(chr, "\e[HMalta LEDBAR\r\n");
426
    qemu_chr_fe_printf(chr, "+--------+\r\n");
427
    qemu_chr_fe_printf(chr, "+        +\r\n");
428
    qemu_chr_fe_printf(chr, "+--------+\r\n");
429
    qemu_chr_fe_printf(chr, "\n");
430
    qemu_chr_fe_printf(chr, "Malta ASCII\r\n");
431
    qemu_chr_fe_printf(chr, "+--------+\r\n");
432
    qemu_chr_fe_printf(chr, "+        +\r\n");
433
    qemu_chr_fe_printf(chr, "+--------+\r\n");
434
}
435

    
436
static MaltaFPGAState *malta_fpga_init(MemoryRegion *address_space,
437
         target_phys_addr_t base, qemu_irq uart_irq, CharDriverState *uart_chr)
438
{
439
    MaltaFPGAState *s;
440

    
441
    s = (MaltaFPGAState *)g_malloc0(sizeof(MaltaFPGAState));
442

    
443
    memory_region_init_io(&s->iomem, &malta_fpga_ops, s,
444
                          "malta-fpga", 0x100000);
445
    memory_region_init_alias(&s->iomem_lo, "malta-fpga",
446
                             &s->iomem, 0, 0x900);
447
    memory_region_init_alias(&s->iomem_hi, "malta-fpga",
448
                             &s->iomem, 0xa00, 0x10000-0xa00);
449

    
450
    memory_region_add_subregion(address_space, base, &s->iomem_lo);
451
    memory_region_add_subregion(address_space, base + 0xa00, &s->iomem_hi);
452

    
453
    s->display = qemu_chr_new("fpga", "vc:320x200", malta_fpga_led_init);
454

    
455
    s->uart = serial_mm_init(address_space, base + 0x900, 3, uart_irq,
456
                             230400, uart_chr, DEVICE_NATIVE_ENDIAN);
457

    
458
    malta_fpga_reset(s);
459
    qemu_register_reset(malta_fpga_reset, s);
460

    
461
    return s;
462
}
463

    
464
/* Network support */
465
static void network_init(void)
466
{
467
    int i;
468

    
469
    for(i = 0; i < nb_nics; i++) {
470
        NICInfo *nd = &nd_table[i];
471
        const char *default_devaddr = NULL;
472

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

    
477
        pci_nic_init_nofail(nd, "pcnet", default_devaddr);
478
    }
479
}
480

    
481
/* ROM and pseudo bootloader
482

483
   The following code implements a very very simple bootloader. It first
484
   loads the registers a0 to a3 to the values expected by the OS, and
485
   then jump at the kernel address.
486

487
   The bootloader should pass the locations of the kernel arguments and
488
   environment variables tables. Those tables contain the 32-bit address
489
   of NULL terminated strings. The environment variables table should be
490
   terminated by a NULL address.
491

492
   For a simpler implementation, the number of kernel arguments is fixed
493
   to two (the name of the kernel and the command line), and the two
494
   tables are actually the same one.
495

496
   The registers a0 to a3 should contain the following values:
497
     a0 - number of kernel arguments
498
     a1 - 32-bit address of the kernel arguments table
499
     a2 - 32-bit address of the environment variables table
500
     a3 - RAM size in bytes
501
*/
502

    
503
static void write_bootloader (CPUState *env, uint8_t *base,
504
                              int64_t kernel_entry)
505
{
506
    uint32_t *p;
507

    
508
    /* Small bootloader */
509
    p = (uint32_t *)base;
510
    stl_raw(p++, 0x0bf00160);                                      /* j 0x1fc00580 */
511
    stl_raw(p++, 0x00000000);                                      /* nop */
512

    
513
    /* YAMON service vector */
514
    stl_raw(base + 0x500, 0xbfc00580);      /* start: */
515
    stl_raw(base + 0x504, 0xbfc0083c);      /* print_count: */
516
    stl_raw(base + 0x520, 0xbfc00580);      /* start: */
517
    stl_raw(base + 0x52c, 0xbfc00800);      /* flush_cache: */
518
    stl_raw(base + 0x534, 0xbfc00808);      /* print: */
519
    stl_raw(base + 0x538, 0xbfc00800);      /* reg_cpu_isr: */
520
    stl_raw(base + 0x53c, 0xbfc00800);      /* unred_cpu_isr: */
521
    stl_raw(base + 0x540, 0xbfc00800);      /* reg_ic_isr: */
522
    stl_raw(base + 0x544, 0xbfc00800);      /* unred_ic_isr: */
523
    stl_raw(base + 0x548, 0xbfc00800);      /* reg_esr: */
524
    stl_raw(base + 0x54c, 0xbfc00800);      /* unreg_esr: */
525
    stl_raw(base + 0x550, 0xbfc00800);      /* getchar: */
526
    stl_raw(base + 0x554, 0xbfc00800);      /* syscon_read: */
527

    
528

    
529
    /* Second part of the bootloader */
530
    p = (uint32_t *) (base + 0x580);
531
    stl_raw(p++, 0x24040002);                                      /* addiu a0, zero, 2 */
532
    stl_raw(p++, 0x3c1d0000 | (((ENVP_ADDR - 64) >> 16) & 0xffff)); /* lui sp, high(ENVP_ADDR) */
533
    stl_raw(p++, 0x37bd0000 | ((ENVP_ADDR - 64) & 0xffff));        /* ori sp, sp, low(ENVP_ADDR) */
534
    stl_raw(p++, 0x3c050000 | ((ENVP_ADDR >> 16) & 0xffff));       /* lui a1, high(ENVP_ADDR) */
535
    stl_raw(p++, 0x34a50000 | (ENVP_ADDR & 0xffff));               /* ori a1, a1, low(ENVP_ADDR) */
536
    stl_raw(p++, 0x3c060000 | (((ENVP_ADDR + 8) >> 16) & 0xffff)); /* lui a2, high(ENVP_ADDR + 8) */
537
    stl_raw(p++, 0x34c60000 | ((ENVP_ADDR + 8) & 0xffff));         /* ori a2, a2, low(ENVP_ADDR + 8) */
538
    stl_raw(p++, 0x3c070000 | (loaderparams.ram_size >> 16));     /* lui a3, high(ram_size) */
539
    stl_raw(p++, 0x34e70000 | (loaderparams.ram_size & 0xffff));  /* ori a3, a3, low(ram_size) */
540

    
541
    /* Load BAR registers as done by YAMON */
542
    stl_raw(p++, 0x3c09b400);                                      /* lui t1, 0xb400 */
543

    
544
#ifdef TARGET_WORDS_BIGENDIAN
545
    stl_raw(p++, 0x3c08df00);                                      /* lui t0, 0xdf00 */
546
#else
547
    stl_raw(p++, 0x340800df);                                      /* ori t0, r0, 0x00df */
548
#endif
549
    stl_raw(p++, 0xad280068);                                      /* sw t0, 0x0068(t1) */
550

    
551
    stl_raw(p++, 0x3c09bbe0);                                      /* lui t1, 0xbbe0 */
552

    
553
#ifdef TARGET_WORDS_BIGENDIAN
554
    stl_raw(p++, 0x3c08c000);                                      /* lui t0, 0xc000 */
555
#else
556
    stl_raw(p++, 0x340800c0);                                      /* ori t0, r0, 0x00c0 */
557
#endif
558
    stl_raw(p++, 0xad280048);                                      /* sw t0, 0x0048(t1) */
559
#ifdef TARGET_WORDS_BIGENDIAN
560
    stl_raw(p++, 0x3c084000);                                      /* lui t0, 0x4000 */
561
#else
562
    stl_raw(p++, 0x34080040);                                      /* ori t0, r0, 0x0040 */
563
#endif
564
    stl_raw(p++, 0xad280050);                                      /* sw t0, 0x0050(t1) */
565

    
566
#ifdef TARGET_WORDS_BIGENDIAN
567
    stl_raw(p++, 0x3c088000);                                      /* lui t0, 0x8000 */
568
#else
569
    stl_raw(p++, 0x34080080);                                      /* ori t0, r0, 0x0080 */
570
#endif
571
    stl_raw(p++, 0xad280058);                                      /* sw t0, 0x0058(t1) */
572
#ifdef TARGET_WORDS_BIGENDIAN
573
    stl_raw(p++, 0x3c083f00);                                      /* lui t0, 0x3f00 */
574
#else
575
    stl_raw(p++, 0x3408003f);                                      /* ori t0, r0, 0x003f */
576
#endif
577
    stl_raw(p++, 0xad280060);                                      /* sw t0, 0x0060(t1) */
578

    
579
#ifdef TARGET_WORDS_BIGENDIAN
580
    stl_raw(p++, 0x3c08c100);                                      /* lui t0, 0xc100 */
581
#else
582
    stl_raw(p++, 0x340800c1);                                      /* ori t0, r0, 0x00c1 */
583
#endif
584
    stl_raw(p++, 0xad280080);                                      /* sw t0, 0x0080(t1) */
585
#ifdef TARGET_WORDS_BIGENDIAN
586
    stl_raw(p++, 0x3c085e00);                                      /* lui t0, 0x5e00 */
587
#else
588
    stl_raw(p++, 0x3408005e);                                      /* ori t0, r0, 0x005e */
589
#endif
590
    stl_raw(p++, 0xad280088);                                      /* sw t0, 0x0088(t1) */
591

    
592
    /* Jump to kernel code */
593
    stl_raw(p++, 0x3c1f0000 | ((kernel_entry >> 16) & 0xffff));    /* lui ra, high(kernel_entry) */
594
    stl_raw(p++, 0x37ff0000 | (kernel_entry & 0xffff));            /* ori ra, ra, low(kernel_entry) */
595
    stl_raw(p++, 0x03e00008);                                      /* jr ra */
596
    stl_raw(p++, 0x00000000);                                      /* nop */
597

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

    
641
}
642

    
643
static void GCC_FMT_ATTR(3, 4) prom_set(uint32_t* prom_buf, int index,
644
                                        const char *string, ...)
645
{
646
    va_list ap;
647
    int32_t table_addr;
648

    
649
    if (index >= ENVP_NB_ENTRIES)
650
        return;
651

    
652
    if (string == NULL) {
653
        prom_buf[index] = 0;
654
        return;
655
    }
656

    
657
    table_addr = sizeof(int32_t) * ENVP_NB_ENTRIES + index * ENVP_ENTRY_SIZE;
658
    prom_buf[index] = tswap32(ENVP_ADDR + table_addr);
659

    
660
    va_start(ap, string);
661
    vsnprintf((char *)prom_buf + table_addr, ENVP_ENTRY_SIZE, string, ap);
662
    va_end(ap);
663
}
664

    
665
/* Kernel */
666
static int64_t load_kernel (void)
667
{
668
    int64_t kernel_entry, kernel_high;
669
    long initrd_size;
670
    ram_addr_t initrd_offset;
671
    int big_endian;
672
    uint32_t *prom_buf;
673
    long prom_size;
674
    int prom_index = 0;
675

    
676
#ifdef TARGET_WORDS_BIGENDIAN
677
    big_endian = 1;
678
#else
679
    big_endian = 0;
680
#endif
681

    
682
    if (load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_to_phys, NULL,
683
                 (uint64_t *)&kernel_entry, NULL, (uint64_t *)&kernel_high,
684
                 big_endian, ELF_MACHINE, 1) < 0) {
685
        fprintf(stderr, "qemu: could not load kernel '%s'\n",
686
                loaderparams.kernel_filename);
687
        exit(1);
688
    }
689

    
690
    /* load initrd */
691
    initrd_size = 0;
692
    initrd_offset = 0;
693
    if (loaderparams.initrd_filename) {
694
        initrd_size = get_image_size (loaderparams.initrd_filename);
695
        if (initrd_size > 0) {
696
            initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & TARGET_PAGE_MASK;
697
            if (initrd_offset + initrd_size > ram_size) {
698
                fprintf(stderr,
699
                        "qemu: memory too small for initial ram disk '%s'\n",
700
                        loaderparams.initrd_filename);
701
                exit(1);
702
            }
703
            initrd_size = load_image_targphys(loaderparams.initrd_filename,
704
                                              initrd_offset,
705
                                              ram_size - initrd_offset);
706
        }
707
        if (initrd_size == (target_ulong) -1) {
708
            fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
709
                    loaderparams.initrd_filename);
710
            exit(1);
711
        }
712
    }
713

    
714
    /* Setup prom parameters. */
715
    prom_size = ENVP_NB_ENTRIES * (sizeof(int32_t) + ENVP_ENTRY_SIZE);
716
    prom_buf = g_malloc(prom_size);
717

    
718
    prom_set(prom_buf, prom_index++, "%s", loaderparams.kernel_filename);
719
    if (initrd_size > 0) {
720
        prom_set(prom_buf, prom_index++, "rd_start=0x%" PRIx64 " rd_size=%li %s",
721
                 cpu_mips_phys_to_kseg0(NULL, initrd_offset), initrd_size,
722
                 loaderparams.kernel_cmdline);
723
    } else {
724
        prom_set(prom_buf, prom_index++, "%s", loaderparams.kernel_cmdline);
725
    }
726

    
727
    prom_set(prom_buf, prom_index++, "memsize");
728
    prom_set(prom_buf, prom_index++, "%i", loaderparams.ram_size);
729
    prom_set(prom_buf, prom_index++, "modetty0");
730
    prom_set(prom_buf, prom_index++, "38400n8r");
731
    prom_set(prom_buf, prom_index++, NULL);
732

    
733
    rom_add_blob_fixed("prom", prom_buf, prom_size,
734
                       cpu_mips_kseg0_to_phys(NULL, ENVP_ADDR));
735

    
736
    return kernel_entry;
737
}
738

    
739
static void malta_mips_config(CPUState *env)
740
{
741
    env->mvp->CP0_MVPConf0 |= ((smp_cpus - 1) << CP0MVPC0_PVPE) |
742
                         ((smp_cpus * env->nr_threads - 1) << CP0MVPC0_PTC);
743
}
744

    
745
static void main_cpu_reset(void *opaque)
746
{
747
    CPUState *env = opaque;
748
    cpu_reset(env);
749

    
750
    /* The bootloader does not need to be rewritten as it is located in a
751
       read only location. The kernel location and the arguments table
752
       location does not change. */
753
    if (loaderparams.kernel_filename) {
754
        env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
755
    }
756

    
757
    malta_mips_config(env);
758
}
759

    
760
static void cpu_request_exit(void *opaque, int irq, int level)
761
{
762
    CPUState *env = cpu_single_env;
763

    
764
    if (env && level) {
765
        cpu_exit(env);
766
    }
767
}
768

    
769
static
770
void mips_malta_init (ram_addr_t ram_size,
771
                      const char *boot_device,
772
                      const char *kernel_filename, const char *kernel_cmdline,
773
                      const char *initrd_filename, const char *cpu_model)
774
{
775
    char *filename;
776
    pflash_t *fl;
777
    MemoryRegion *system_memory = get_system_memory();
778
    MemoryRegion *ram = g_new(MemoryRegion, 1);
779
    MemoryRegion *bios, *bios_alias = g_new(MemoryRegion, 1);
780
    target_long bios_size;
781
    int64_t kernel_entry;
782
    PCIBus *pci_bus;
783
    ISABus *isa_bus;
784
    CPUState *env;
785
    qemu_irq *isa_irq;
786
    qemu_irq *cpu_exit_irq;
787
    int piix4_devfn;
788
    i2c_bus *smbus;
789
    int i;
790
    DriveInfo *dinfo;
791
    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
792
    DriveInfo *fd[MAX_FD];
793
    int fl_idx = 0;
794
    int fl_sectors = 0;
795
    int be;
796

    
797
    DeviceState *dev = qdev_create(NULL, "mips-malta");
798
    MaltaState *s = DO_UPCAST(MaltaState, busdev.qdev, dev);
799

    
800
    qdev_init_nofail(dev);
801

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

    
811
    /* init CPUs */
812
    if (cpu_model == NULL) {
813
#ifdef TARGET_MIPS64
814
        cpu_model = "20Kc";
815
#else
816
        cpu_model = "24Kf";
817
#endif
818
    }
819

    
820
    for (i = 0; i < smp_cpus; i++) {
821
        env = cpu_init(cpu_model);
822
        if (!env) {
823
            fprintf(stderr, "Unable to find CPU definition\n");
824
            exit(1);
825
        }
826
        /* Init internal devices */
827
        cpu_mips_irq_init_cpu(env);
828
        cpu_mips_clock_init(env);
829
        qemu_register_reset(main_cpu_reset, env);
830
    }
831
    env = first_cpu;
832

    
833
    /* allocate RAM */
834
    if (ram_size > (256 << 20)) {
835
        fprintf(stderr,
836
                "qemu: Too much memory for this machine: %d MB, maximum 256 MB\n",
837
                ((unsigned int)ram_size / (1 << 20)));
838
        exit(1);
839
    }
840
    memory_region_init_ram(ram, "mips_malta.ram", ram_size);
841
    vmstate_register_ram_global(ram);
842
    memory_region_add_subregion(system_memory, 0, ram);
843

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

    
852
    /* Load firmware in flash / BIOS unless we boot directly into a kernel. */
853
    if (kernel_filename) {
854
        /* Write a small bootloader to the flash location. */
855
        bios = g_new(MemoryRegion, 1);
856
        memory_region_init_ram(bios, "mips_malta.bios", BIOS_SIZE);
857
        vmstate_register_ram_global(bios);
858
        memory_region_set_readonly(bios, true);
859
        memory_region_init_alias(bios_alias, "bios.1fc", bios, 0, BIOS_SIZE);
860
        /* Map the bios at two physical locations, as on the real board. */
861
        memory_region_add_subregion(system_memory, 0x1e000000LL, bios);
862
        memory_region_add_subregion(system_memory, 0x1fc00000LL, bios_alias);
863
        loaderparams.ram_size = ram_size;
864
        loaderparams.kernel_filename = kernel_filename;
865
        loaderparams.kernel_cmdline = kernel_cmdline;
866
        loaderparams.initrd_filename = initrd_filename;
867
        kernel_entry = load_kernel();
868
        write_bootloader(env, memory_region_get_ram_ptr(bios), kernel_entry);
869
    } else {
870
        dinfo = drive_get(IF_PFLASH, 0, fl_idx);
871
        if (dinfo) {
872
            /* Load firmware from flash. */
873
            bios_size = 0x400000;
874
            fl_sectors = bios_size >> 16;
875
#ifdef DEBUG_BOARD_INIT
876
            printf("Register parallel flash %d size " TARGET_FMT_lx " at "
877
                   "addr %08llx '%s' %x\n",
878
                   fl_idx, bios_size, 0x1e000000LL,
879
                   bdrv_get_device_name(dinfo->bdrv), fl_sectors);
880
#endif
881
            fl = pflash_cfi01_register(0x1e000000LL,
882
                                       NULL, "mips_malta.bios", BIOS_SIZE,
883
                                       dinfo->bdrv, 65536, fl_sectors,
884
                                       4, 0x0000, 0x0000, 0x0000, 0x0000, be);
885
            bios = pflash_cfi01_get_memory(fl);
886
            /* Map the bios at two physical locations, as on the real board. */
887
            memory_region_init_alias(bios_alias, "bios.1fc",
888
                                     bios, 0, BIOS_SIZE);
889
            memory_region_add_subregion(system_memory, 0x1fc00000LL,
890
                                        bios_alias);
891
           fl_idx++;
892
        } else {
893
            bios = g_new(MemoryRegion, 1);
894
            memory_region_init_ram(bios, "mips_malta.bios", BIOS_SIZE);
895
            vmstate_register_ram_global(bios);
896
            memory_region_set_readonly(bios, true);
897
            memory_region_init_alias(bios_alias, "bios.1fc",
898
                                     bios, 0, BIOS_SIZE);
899
            /* Map the bios at two physical locations, as on the real board. */
900
            memory_region_add_subregion(system_memory, 0x1e000000LL, bios);
901
            memory_region_add_subregion(system_memory, 0x1fc00000LL,
902
                                        bios_alias);
903
            /* Load a BIOS image. */
904
            if (bios_name == NULL)
905
                bios_name = BIOS_FILENAME;
906
            filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
907
            if (filename) {
908
                bios_size = load_image_targphys(filename, 0x1fc00000LL,
909
                                                BIOS_SIZE);
910
                g_free(filename);
911
            } else {
912
                bios_size = -1;
913
            }
914
            if ((bios_size < 0 || bios_size > BIOS_SIZE) && !kernel_filename) {
915
                fprintf(stderr,
916
                        "qemu: Could not load MIPS bios '%s', and no -kernel argument was specified\n",
917
                        bios_name);
918
                exit(1);
919
            }
920
        }
921
        /* In little endian mode the 32bit words in the bios are swapped,
922
           a neat trick which allows bi-endian firmware. */
923
#ifndef TARGET_WORDS_BIGENDIAN
924
        {
925
            uint32_t *addr = memory_region_get_ram_ptr(bios);
926
            uint32_t *end = addr + bios_size;
927
            while (addr < end) {
928
                bswap32s(addr);
929
                addr++;
930
            }
931
        }
932
#endif
933
    }
934

    
935
    /* Board ID = 0x420 (Malta Board with CoreLV)
936
       XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
937
       map to the board ID. */
938
    stl_p(memory_region_get_ram_ptr(bios) + 0x10, 0x00000420);
939

    
940
    /* Init internal devices */
941
    cpu_mips_irq_init_cpu(env);
942
    cpu_mips_clock_init(env);
943

    
944
    /*
945
     * We have a circular dependency problem: pci_bus depends on isa_irq,
946
     * isa_irq is provided by i8259, i8259 depends on ISA, ISA depends
947
     * on piix4, and piix4 depends on pci_bus.  To stop the cycle we have
948
     * qemu_irq_proxy() adds an extra bit of indirection, allowing us
949
     * to resolve the isa_irq -> i8259 dependency after i8259 is initialized.
950
     */
951
    isa_irq = qemu_irq_proxy(&s->i8259, 16);
952

    
953
    /* Northbridge */
954
    pci_bus = gt64120_register(isa_irq);
955

    
956
    /* Southbridge */
957
    ide_drive_get(hd, MAX_IDE_BUS);
958

    
959
    piix4_devfn = piix4_init(pci_bus, &isa_bus, 80);
960

    
961
    /* Interrupt controller */
962
    /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
963
    s->i8259 = i8259_init(isa_bus, env->irq[2]);
964

    
965
    isa_bus_irqs(isa_bus, s->i8259);
966
    pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);
967
    usb_uhci_piix4_init(pci_bus, piix4_devfn + 2);
968
    smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100,
969
                          isa_get_irq(NULL, 9), NULL, NULL, 0);
970
    /* TODO: Populate SPD eeprom data.  */
971
    smbus_eeprom_init(smbus, 8, NULL, 0);
972
    pit = pit_init(isa_bus, 0x40, 0);
973
    cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
974
    DMA_init(0, cpu_exit_irq);
975

    
976
    /* Super I/O */
977
    isa_create_simple(isa_bus, "i8042");
978

    
979
    rtc_init(isa_bus, 2000, NULL);
980
    serial_isa_init(isa_bus, 0, serial_hds[0]);
981
    serial_isa_init(isa_bus, 1, serial_hds[1]);
982
    if (parallel_hds[0])
983
        parallel_init(isa_bus, 0, parallel_hds[0]);
984
    for(i = 0; i < MAX_FD; i++) {
985
        fd[i] = drive_get(IF_FLOPPY, 0, i);
986
    }
987
    fdctrl_init_isa(isa_bus, fd);
988

    
989
    /* Sound card */
990
    audio_init(isa_bus, pci_bus);
991

    
992
    /* Network card */
993
    network_init();
994

    
995
    /* Optional PCI video card */
996
    if (cirrus_vga_enabled) {
997
        pci_cirrus_vga_init(pci_bus);
998
    } else if (vmsvga_enabled) {
999
        pci_vmsvga_init(pci_bus);
1000
    } else if (std_vga_enabled) {
1001
        pci_vga_init(pci_bus);
1002
    }
1003
}
1004

    
1005
static int mips_malta_sysbus_device_init(SysBusDevice *sysbusdev)
1006
{
1007
    return 0;
1008
}
1009

    
1010
static void mips_malta_class_init(ObjectClass *klass, void *data)
1011
{
1012
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
1013

    
1014
    k->init = mips_malta_sysbus_device_init;
1015
}
1016

    
1017
static TypeInfo mips_malta_device = {
1018
    .name          = "mips-malta",
1019
    .parent        = TYPE_SYS_BUS_DEVICE,
1020
    .instance_size = sizeof(MaltaState),
1021
    .class_init    = mips_malta_class_init,
1022
};
1023

    
1024
static QEMUMachine mips_malta_machine = {
1025
    .name = "malta",
1026
    .desc = "MIPS Malta Core LV",
1027
    .init = mips_malta_init,
1028
    .max_cpus = 16,
1029
    .is_default = 1,
1030
};
1031

    
1032
static void mips_malta_device_init(void)
1033
{
1034
    type_register_static(&mips_malta_device);
1035
}
1036

    
1037
static void mips_malta_machine_init(void)
1038
{
1039
    qemu_register_machine(&mips_malta_machine);
1040
}
1041

    
1042
device_init(mips_malta_device_init);
1043
machine_init(mips_malta_machine_init);