Statistics
| Branch: | Revision:

root / hw / mips_malta.c @ 33d68b5f

History | View | Annotate | Download (20.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 "vl.h"
26

    
27
#ifdef TARGET_WORDS_BIGENDIAN
28
#define BIOS_FILENAME "mips_bios.bin"
29
#else
30
#define BIOS_FILENAME "mipsel_bios.bin"
31
#endif
32

    
33
#ifdef MIPS_HAS_MIPS64
34
#define INITRD_LOAD_ADDR         (int64_t)0x80800000
35
#else
36
#define INITRD_LOAD_ADDR         (int32_t)0x80800000
37
#endif
38

    
39
#define ENVP_ADDR                (int32_t)0x80002000
40
#define VIRT_TO_PHYS_ADDEND         (-((int64_t)(int32_t)0x80000000))
41

    
42
#define ENVP_NB_ENTRIES                 16
43
#define ENVP_ENTRY_SIZE                 256
44

    
45

    
46
extern FILE *logfile;
47

    
48
typedef struct {
49
    uint32_t leds;
50
    uint32_t brk;
51
    uint32_t gpout;
52
    uint32_t i2cin;
53
    uint32_t i2coe;
54
    uint32_t i2cout;
55
    uint32_t i2csel;
56
    CharDriverState *display;
57
    char display_text[9];
58
} MaltaFPGAState;
59

    
60
static PITState *pit;
61

    
62
/* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
63
static void pic_irq_request(void *opaque, int level)
64
{
65
    cpu_mips_irq_request(opaque, 2, level);
66
}
67

    
68
/* Malta FPGA */
69
static void malta_fpga_update_display(void *opaque)
70
{
71
    char leds_text[9];
72
    int i;
73
    MaltaFPGAState *s = opaque;
74

    
75
    for (i = 7 ; i >= 0 ; i--) {
76
        if (s->leds & (1 << i))
77
            leds_text[i] = '#';
78
        else
79
            leds_text[i] = ' ';
80
    }
81
    leds_text[8] = '\0';
82

    
83
    qemu_chr_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text);
84
    qemu_chr_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text);
85
}
86

    
87
/*
88
 * EEPROM 24C01 / 24C02 emulation.
89
 *
90
 * Emulation for serial EEPROMs:
91
 * 24C01 - 1024 bit (128 x 8)
92
 * 24C02 - 2048 bit (256 x 8)
93
 *
94
 * Typical device names include Microchip 24C02SC or SGS Thomson ST24C02.
95
 */
96

    
97
//~ #define DEBUG
98

    
99
#if defined(DEBUG)
100
#  define logout(fmt, args...) fprintf(stderr, "MALTA\t%-24s" fmt, __func__, ##args)
101
#else
102
#  define logout(fmt, args...) ((void)0)
103
#endif
104

    
105
struct _eeprom24c0x_t {
106
  uint8_t tick;
107
  uint8_t address;
108
  uint8_t command;
109
  uint8_t ack;
110
  uint8_t scl;
111
  uint8_t sda;
112
  uint8_t data;
113
  //~ uint16_t size;
114
  uint8_t contents[256];
115
};
116

    
117
typedef struct _eeprom24c0x_t eeprom24c0x_t;
118

    
119
static eeprom24c0x_t eeprom = {
120
    contents: {
121
        /* 00000000: */ 0x80,0x08,0x04,0x0D,0x0A,0x01,0x40,0x00,
122
        /* 00000008: */ 0x01,0x75,0x54,0x00,0x82,0x08,0x00,0x01,
123
        /* 00000010: */ 0x8F,0x04,0x02,0x01,0x01,0x00,0x0E,0x00,
124
        /* 00000018: */ 0x00,0x00,0x00,0x14,0x0F,0x14,0x2D,0x40,
125
        /* 00000020: */ 0x15,0x08,0x15,0x08,0x00,0x00,0x00,0x00,
126
        /* 00000028: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
127
        /* 00000030: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
128
        /* 00000038: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x12,0xD0,
129
        /* 00000040: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
130
        /* 00000048: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
131
        /* 00000050: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
132
        /* 00000058: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
133
        /* 00000060: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
134
        /* 00000068: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
135
        /* 00000070: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
136
        /* 00000078: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x64,0xF4,
137
    },
138
};
139

    
140
static uint8_t eeprom24c0x_read()
141
{
142
    logout("%u: scl = %u, sda = %u, data = 0x%02x\n",
143
        eeprom.tick, eeprom.scl, eeprom.sda, eeprom.data);
144
    return eeprom.sda;
145
}
146

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

    
205
static uint32_t malta_fpga_readl(void *opaque, target_phys_addr_t addr)
206
{
207
    MaltaFPGAState *s = opaque;
208
    uint32_t val = 0;
209
    uint32_t saddr;
210

    
211
    saddr = (addr & 0xfffff);
212

    
213
    switch (saddr) {
214

    
215
    /* SWITCH Register */
216
    case 0x00200:
217
        val = 0x00000000;                /* All switches closed */
218
        break;
219

    
220
    /* STATUS Register */
221
    case 0x00208:
222
#ifdef TARGET_WORDS_BIGENDIAN
223
        val = 0x00000012;
224
#else
225
        val = 0x00000010;
226
#endif
227
        break;
228

    
229
    /* JMPRS Register */
230
    case 0x00210:
231
        val = 0x00;
232
        break;
233

    
234
    /* LEDBAR Register */
235
    case 0x00408:
236
        val = s->leds;
237
        break;
238

    
239
    /* BRKRES Register */
240
    case 0x00508:
241
        val = s->brk;
242
        break;
243

    
244
    /* GPOUT Register */
245
    case 0x00a00:
246
        val = s->gpout;
247
        break;
248

    
249
    /* XXX: implement a real I2C controller */
250

    
251
    /* GPINP Register */
252
    case 0x00a08:
253
        /* IN = OUT until a real I2C control is implemented */
254
        if (s->i2csel)
255
            val = s->i2cout;
256
        else
257
            val = 0x00;
258
        break;
259

    
260
    /* I2CINP Register */
261
    case 0x00b00:
262
        val = ((s->i2cin & ~1) | eeprom24c0x_read());
263
        break;
264

    
265
    /* I2COE Register */
266
    case 0x00b08:
267
        val = s->i2coe;
268
        break;
269

    
270
    /* I2COUT Register */
271
    case 0x00b10:
272
        val = s->i2cout;
273
        break;
274

    
275
    /* I2CSEL Register */
276
    case 0x00b18:
277
        val = s->i2csel;
278
        break;
279

    
280
    default:
281
#if 0
282
        printf ("malta_fpga_read: Bad register offset 0x" TARGET_FMT_lx "\n",
283
                addr);
284
#endif
285
        break;
286
    }
287
    return val;
288
}
289

    
290
static void malta_fpga_writel(void *opaque, target_phys_addr_t addr,
291
                              uint32_t val)
292
{
293
    MaltaFPGAState *s = opaque;
294
    uint32_t saddr;
295

    
296
    saddr = (addr & 0xfffff);
297

    
298
    switch (saddr) {
299

    
300
    /* SWITCH Register */
301
    case 0x00200:
302
        break;
303

    
304
    /* JMPRS Register */
305
    case 0x00210:
306
        break;
307

    
308
    /* LEDBAR Register */
309
    /* XXX: implement a 8-LED array */
310
    case 0x00408:
311
        s->leds = val & 0xff;
312
        break;
313

    
314
    /* ASCIIWORD Register */
315
    case 0x00410:
316
        snprintf(s->display_text, 9, "%08X", val);
317
        malta_fpga_update_display(s);
318
        break;
319

    
320
    /* ASCIIPOS0 to ASCIIPOS7 Registers */
321
    case 0x00418:
322
    case 0x00420:
323
    case 0x00428:
324
    case 0x00430:
325
    case 0x00438:
326
    case 0x00440:
327
    case 0x00448:
328
    case 0x00450:
329
        s->display_text[(saddr - 0x00418) >> 3] = (char) val;
330
        malta_fpga_update_display(s);
331
        break;
332

    
333
    /* SOFTRES Register */
334
    case 0x00500:
335
        if (val == 0x42)
336
            qemu_system_reset_request ();
337
        break;
338

    
339
    /* BRKRES Register */
340
    case 0x00508:
341
        s->brk = val & 0xff;
342
        break;
343

    
344
    /* GPOUT Register */
345
    case 0x00a00:
346
        s->gpout = val & 0xff;
347
        break;
348

    
349
    /* I2COE Register */
350
    case 0x00b08:
351
        s->i2coe = val & 0x03;
352
        break;
353

    
354
    /* I2COUT Register */
355
    case 0x00b10:
356
        eeprom24c0x_write(val & 0x02, val & 0x01);
357
        s->i2cout = val;
358
        break;
359

    
360
    /* I2CSEL Register */
361
    case 0x00b18:
362
        s->i2csel = val & 0x01;
363
        break;
364

    
365
    default:
366
#if 0
367
        printf ("malta_fpga_write: Bad register offset 0x" TARGET_FMT_lx "\n",
368
                addr);
369
#endif
370
        break;
371
    }
372
}
373

    
374
static CPUReadMemoryFunc *malta_fpga_read[] = {
375
   malta_fpga_readl,
376
   malta_fpga_readl,
377
   malta_fpga_readl
378
};
379

    
380
static CPUWriteMemoryFunc *malta_fpga_write[] = {
381
   malta_fpga_writel,
382
   malta_fpga_writel,
383
   malta_fpga_writel
384
};
385

    
386
void malta_fpga_reset(void *opaque)
387
{
388
    MaltaFPGAState *s = opaque;
389

    
390
    s->leds   = 0x00;
391
    s->brk    = 0x0a;
392
    s->gpout  = 0x00;
393
    s->i2cin  = 0x3;
394
    s->i2coe  = 0x0;
395
    s->i2cout = 0x3;
396
    s->i2csel = 0x1;
397

    
398
    s->display_text[8] = '\0';
399
    snprintf(s->display_text, 9, "        ");
400
    malta_fpga_update_display(s);
401
}
402

    
403
MaltaFPGAState *malta_fpga_init(target_phys_addr_t base)
404
{
405
    MaltaFPGAState *s;
406
    int malta;
407

    
408
    s = (MaltaFPGAState *)qemu_mallocz(sizeof(MaltaFPGAState));
409

    
410
    malta = cpu_register_io_memory(0, malta_fpga_read,
411
                                   malta_fpga_write, s);
412
    cpu_register_physical_memory(base, 0x100000, malta);
413

    
414
    s->display = qemu_chr_open("vc");
415
    qemu_chr_printf(s->display, "\e[HMalta LEDBAR\r\n");
416
    qemu_chr_printf(s->display, "+--------+\r\n");
417
    qemu_chr_printf(s->display, "+        +\r\n");
418
    qemu_chr_printf(s->display, "+--------+\r\n");
419
    qemu_chr_printf(s->display, "\n");
420
    qemu_chr_printf(s->display, "Malta ASCII\r\n");
421
    qemu_chr_printf(s->display, "+--------+\r\n");
422
    qemu_chr_printf(s->display, "+        +\r\n");
423
    qemu_chr_printf(s->display, "+--------+\r\n");
424

    
425
    malta_fpga_reset(s);
426
    qemu_register_reset(malta_fpga_reset, s);
427

    
428
    return s;
429
}
430

    
431
/* Audio support */
432
#ifdef HAS_AUDIO
433
static void audio_init (PCIBus *pci_bus)
434
{
435
    struct soundhw *c;
436
    int audio_enabled = 0;
437

    
438
    for (c = soundhw; !audio_enabled && c->name; ++c) {
439
        audio_enabled = c->enabled;
440
    }
441

    
442
    if (audio_enabled) {
443
        AudioState *s;
444

    
445
        s = AUD_init ();
446
        if (s) {
447
            for (c = soundhw; c->name; ++c) {
448
                if (c->enabled) {
449
                    if (c->isa) {
450
                        fprintf(stderr, "qemu: Unsupported Sound Card: %s\n", c->name);
451
                        exit(1);
452
                    }
453
                    else {
454
                        if (pci_bus) {
455
                            c->init.init_pci (pci_bus, s);
456
                        }
457
                    }
458
                }
459
            }
460
        }
461
    }
462
}
463
#endif
464

    
465
/* Network support */
466
static void network_init (PCIBus *pci_bus)
467
{
468
    int i;
469
    NICInfo *nd;
470

    
471
    for(i = 0; i < nb_nics; i++) {
472
        nd = &nd_table[i];
473
        if (!nd->model) {
474
            nd->model = "pcnet";
475
        }
476
        if (i == 0  && strcmp(nd->model, "pcnet") == 0) {
477
            /* The malta board has a PCNet card using PCI SLOT 11 */
478
            pci_nic_init(pci_bus, nd, 88);
479
        } else {
480
            pci_nic_init(pci_bus, nd, -1);
481
        }
482
    }
483
}
484

    
485
/* ROM and pseudo bootloader
486

487
   The following code implements a very very simple bootloader. It first
488
   loads the registers a0 to a3 to the values expected by the OS, and
489
   then jump at the kernel address.
490

491
   The bootloader should pass the locations of the kernel arguments and
492
   environment variables tables. Those tables contain the 32-bit address
493
   of NULL terminated strings. The environment variables table should be
494
   terminated by a NULL address.
495

496
   For a simpler implementation, the number of kernel arguments is fixed
497
   to two (the name of the kernel and the command line), and the two
498
   tables are actually the same one.
499

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

    
507
static void write_bootloader (CPUState *env, unsigned long bios_offset, int64_t kernel_addr)
508
{
509
    uint32_t *p;
510

    
511
    /* Small bootloader */
512
    p = (uint32_t *) (phys_ram_base + bios_offset);
513
    stl_raw(p++, 0x0bf00010);                                      /* j 0x1fc00040 */
514
    stl_raw(p++, 0x00000000);                                      /* nop */
515

    
516
    /* Second part of the bootloader */
517
    p = (uint32_t *) (phys_ram_base + bios_offset + 0x040);
518
    stl_raw(p++, 0x3c040000);                                      /* lui a0, 0 */
519
    stl_raw(p++, 0x34840002);                                      /* ori a0, a0, 2 */
520
    stl_raw(p++, 0x3c050000 | ((ENVP_ADDR >> 16) & 0xffff));       /* lui a1, high(ENVP_ADDR) */
521
    stl_raw(p++, 0x34a50000 | (ENVP_ADDR & 0xffff));               /* ori a1, a0, low(ENVP_ADDR) */
522
    stl_raw(p++, 0x3c060000 | (((ENVP_ADDR + 8) >> 16) & 0xffff)); /* lui a2, high(ENVP_ADDR + 8) */
523
    stl_raw(p++, 0x34c60000 | ((ENVP_ADDR + 8) & 0xffff));         /* ori a2, a2, low(ENVP_ADDR + 8) */
524
    stl_raw(p++, 0x3c070000 | (env->ram_size >> 16));              /* lui a3, high(env->ram_size) */
525
    stl_raw(p++, 0x34e70000 | (env->ram_size & 0xffff));           /* ori a3, a3, low(env->ram_size) */
526
    stl_raw(p++, 0x3c1f0000 | ((kernel_addr >> 16) & 0xffff));     /* lui ra, high(kernel_addr) */;
527
    stl_raw(p++, 0x37ff0000 | (kernel_addr & 0xffff));             /* ori ra, ra, low(kernel_addr) */
528
    stl_raw(p++, 0x03e00008);                                      /* jr ra */
529
    stl_raw(p++, 0x00000000);                                      /* nop */
530
}
531

    
532
static void prom_set(int index, const char *string, ...)
533
{
534
    va_list ap;
535
    int32_t *p;
536
    int32_t table_addr;
537
    char *s;
538

    
539
    if (index >= ENVP_NB_ENTRIES)
540
        return;
541

    
542
    p = (int32_t *) (phys_ram_base + ENVP_ADDR + VIRT_TO_PHYS_ADDEND);
543
    p += index;
544

    
545
    if (string == NULL) {
546
        stl_raw(p, 0);
547
        return;
548
    }
549

    
550
    table_addr = ENVP_ADDR + sizeof(int32_t) * ENVP_NB_ENTRIES + index * ENVP_ENTRY_SIZE;
551
    s = (char *) (phys_ram_base + VIRT_TO_PHYS_ADDEND + table_addr);
552

    
553
    stl_raw(p, table_addr);
554

    
555
    va_start(ap, string);
556
    vsnprintf (s, ENVP_ENTRY_SIZE, string, ap);
557
    va_end(ap);
558
}
559

    
560
/* Kernel */
561
static int64_t load_kernel (CPUState *env)
562
{
563
    int64_t kernel_addr = 0;
564
    int index = 0;
565
    long initrd_size;
566

    
567
    if (load_elf(env->kernel_filename, VIRT_TO_PHYS_ADDEND, &kernel_addr) < 0) {
568
        fprintf(stderr, "qemu: could not load kernel '%s'\n",
569
                env->kernel_filename);
570
      exit(1);
571
    }
572

    
573
    /* load initrd */
574
    initrd_size = 0;
575
    if (env->initrd_filename) {
576
        initrd_size = load_image(env->initrd_filename,
577
                                 phys_ram_base + INITRD_LOAD_ADDR + VIRT_TO_PHYS_ADDEND);
578
        if (initrd_size == (target_ulong) -1) {
579
            fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
580
                    env->initrd_filename);
581
            exit(1);
582
        }
583
    }
584

    
585
    /* Store command line.  */
586
    prom_set(index++, env->kernel_filename);
587
    if (initrd_size > 0)
588
        prom_set(index++, "rd_start=0x" TARGET_FMT_lx " rd_size=%li %s", INITRD_LOAD_ADDR, initrd_size, env->kernel_cmdline);
589
    else
590
        prom_set(index++, env->kernel_cmdline);
591

    
592
    /* Setup minimum environment variables */
593
    prom_set(index++, "memsize");
594
    prom_set(index++, "%i", env->ram_size);
595
    prom_set(index++, "modetty0");
596
    prom_set(index++, "38400n8r");
597
    prom_set(index++, NULL);
598

    
599
    return kernel_addr;
600
}
601

    
602
static void main_cpu_reset(void *opaque)
603
{
604
    CPUState *env = opaque;
605
    cpu_reset(env);
606

    
607
    /* The bootload does not need to be rewritten as it is located in a
608
       read only location. The kernel location and the arguments table
609
       location does not change. */
610
    if (env->kernel_filename)
611
        load_kernel (env);
612
}
613

    
614
static
615
void mips_malta_init (int ram_size, int vga_ram_size, int boot_device,
616
                      DisplayState *ds, const char **fd_filename, int snapshot,
617
                      const char *kernel_filename, const char *kernel_cmdline,
618
                      const char *initrd_filename, const char *cpu_model)
619
{
620
    char buf[1024];
621
    unsigned long bios_offset;
622
    int64_t kernel_addr;
623
    PCIBus *pci_bus;
624
    CPUState *env;
625
    RTCState *rtc_state;
626
    /* fdctrl_t *floppy_controller; */
627
    MaltaFPGAState *malta_fpga;
628
    int ret;
629
    mips_def_t *def;
630

    
631
    /* init CPUs */
632
    if (cpu_model == NULL) {
633
#ifdef MIPS_HAS_MIPS64
634
        cpu_model = "R4000";
635
#else
636
        cpu_model = "4KEc";
637
#endif
638
    }
639
    if (mips_find_by_name(cpu_model, &def) != 0)
640
        def = NULL;
641
    env = cpu_init();
642
    cpu_mips_register(env, def);
643
    register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
644
    qemu_register_reset(main_cpu_reset, env);
645

    
646
    /* allocate RAM */
647
    cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
648

    
649
    /* Map the bios at two physical locations, as on the real board */
650
    bios_offset = ram_size + vga_ram_size;
651
    cpu_register_physical_memory(0x1e000000LL,
652
                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
653
    cpu_register_physical_memory(0x1fc00000LL,
654
                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
655

    
656
    /* Load a BIOS image except if a kernel image has been specified. In
657
       the later case, just write a small bootloader to the flash
658
       location. */
659
    if (kernel_filename) {
660
        env->ram_size = ram_size;
661
        env->kernel_filename = kernel_filename;
662
        env->kernel_cmdline = kernel_cmdline;
663
        env->initrd_filename = initrd_filename;
664
        kernel_addr = load_kernel(env);
665
        write_bootloader(env, bios_offset, kernel_addr);
666
    } else {
667
        snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
668
        ret = load_image(buf, phys_ram_base + bios_offset);
669
        if (ret < 0 || ret > BIOS_SIZE) {
670
            fprintf(stderr, "qemu: Warning, could not load MIPS bios '%s'\n",
671
                    buf);
672
            exit(1);
673
        }
674
    }
675

    
676
    /* Board ID = 0x420 (Malta Board with CoreLV)
677
       XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
678
       map to the board ID. */
679
    stl_raw(phys_ram_base + bios_offset + 0x10, 0x00000420);
680

    
681
    /* Init internal devices */
682
    cpu_mips_clock_init(env);
683
    cpu_mips_irqctrl_init();
684

    
685
    /* FPGA */
686
    malta_fpga = malta_fpga_init(0x1f000000LL);
687

    
688
    /* Interrupt controller */
689
    isa_pic = pic_init(pic_irq_request, env);
690

    
691
    /* Northbridge */
692
    pci_bus = pci_gt64120_init(isa_pic);
693

    
694
    /* Southbridge */
695
    piix4_init(pci_bus, 80);
696
    pci_piix3_ide_init(pci_bus, bs_table, 81);
697
    usb_uhci_init(pci_bus, 82);
698
    piix4_pm_init(pci_bus, 83);
699
    pit = pit_init(0x40, 0);
700
    DMA_init(0);
701

    
702
    /* Super I/O */
703
    kbd_init();
704
    rtc_state = rtc_init(0x70, 8);
705
    if (serial_hds[0])
706
        serial_init(&pic_set_irq_new, isa_pic, 0x3f8, 4, serial_hds[0]);
707
    if (serial_hds[1])
708
        serial_init(&pic_set_irq_new, isa_pic, 0x2f8, 3, serial_hds[1]);
709
    if (parallel_hds[0])
710
        parallel_init(0x378, 7, parallel_hds[0]);
711
    /* XXX: The floppy controller does not work correctly, something is
712
       probably wrong.
713
    floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table); */
714

    
715
    /* Sound card */
716
#ifdef HAS_AUDIO
717
    audio_init(pci_bus);
718
#endif
719

    
720
    /* Network card */
721
    network_init(pci_bus);
722
}
723

    
724
QEMUMachine mips_malta_machine = {
725
    "malta",
726
    "MIPS Malta Core LV",
727
    mips_malta_init,
728
};