Statistics
| Branch: | Revision:

root / hw / mips_malta.c @ 2d48377a

History | View | Annotate | Download (31.7 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 "pci.h"
35
#include "usb-uhci.h"
36
#include "vmware_vga.h"
37
#include "qemu-char.h"
38
#include "sysemu.h"
39
#include "audio/audio.h"
40
#include "boards.h"
41
#include "qemu-log.h"
42
#include "mips-bios.h"
43
#include "ide.h"
44
#include "loader.h"
45
#include "elf.h"
46

    
47
//#define DEBUG_BOARD_INIT
48

    
49
#define ENVP_ADDR                0x80002000l
50
#define ENVP_NB_ENTRIES                 16
51
#define ENVP_ENTRY_SIZE                 256
52

    
53
#define MAX_IDE_BUS 2
54

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

    
68
static PITState *pit;
69

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

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

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

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

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

    
106
//~ #define DEBUG
107

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

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

    
126
typedef struct _eeprom24c0x_t eeprom24c0x_t;
127

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

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

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

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

    
220
    saddr = (addr & 0xfffff);
221

    
222
    switch (saddr) {
223

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

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

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

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

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

    
253
    /* UART Registers are handled directly by the serial device */
254

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

    
260
    /* XXX: implement a real I2C controller */
261

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

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

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

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

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

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

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

    
307
    saddr = (addr & 0xfffff);
308

    
309
    switch (saddr) {
310

    
311
    /* SWITCH Register */
312
    case 0x00200:
313
        break;
314

    
315
    /* JMPRS Register */
316
    case 0x00210:
317
        break;
318

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

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

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

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

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

    
355
    /* UART Registers are handled directly by the serial device */
356

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

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

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

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

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

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

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

    
399
static void malta_fpga_reset(void *opaque)
400
{
401
    MaltaFPGAState *s = opaque;
402

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

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

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

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

    
433
    s = (MaltaFPGAState *)qemu_mallocz(sizeof(MaltaFPGAState));
434

    
435
    malta = cpu_register_io_memory(malta_fpga_read,
436
                                   malta_fpga_write, s);
437

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

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

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

    
450
    malta_fpga_reset(s);
451
    qemu_register_reset(malta_fpga_reset, s);
452

    
453
    return s;
454
}
455

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

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

    
467
    if (audio_enabled) {
468
        for (c = soundhw; c->name; ++c) {
469
            if (c->enabled) {
470
                c->init.init_pci(pci_bus);
471
            }
472
        }
473
    }
474
}
475
#endif
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
765
void mips_malta_init (ram_addr_t ram_size,
766
                      const char *boot_device,
767
                      const char *kernel_filename, const char *kernel_cmdline,
768
                      const char *initrd_filename, const char *cpu_model)
769
{
770
    char *filename;
771
    ram_addr_t ram_offset;
772
    ram_addr_t bios_offset;
773
    target_long bios_size;
774
    int64_t kernel_entry;
775
    PCIBus *pci_bus;
776
    ISADevice *isa_dev;
777
    CPUState *env;
778
    RTCState *rtc_state;
779
    FDCtrl *floppy_controller;
780
    MaltaFPGAState *malta_fpga;
781
    qemu_irq *i8259;
782
    int piix4_devfn;
783
    uint8_t *eeprom_buf;
784
    i2c_bus *smbus;
785
    int i;
786
    DriveInfo *dinfo;
787
    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
788
    DriveInfo *fd[MAX_FD];
789
    int fl_idx = 0;
790
    int fl_sectors = 0;
791

    
792
    /* Make sure the first 3 serial ports are associated with a device. */
793
    for(i = 0; i < 3; i++) {
794
        if (!serial_hds[i]) {
795
            char label[32];
796
            snprintf(label, sizeof(label), "serial%d", i);
797
            serial_hds[i] = qemu_chr_open(label, "null", NULL);
798
        }
799
    }
800

    
801
    /* init CPUs */
802
    if (cpu_model == NULL) {
803
#ifdef TARGET_MIPS64
804
        cpu_model = "20Kc";
805
#else
806
        cpu_model = "24Kf";
807
#endif
808
    }
809
    env = cpu_init(cpu_model);
810
    if (!env) {
811
        fprintf(stderr, "Unable to find CPU definition\n");
812
        exit(1);
813
    }
814
    qemu_register_reset(main_cpu_reset, env);
815

    
816
    /* allocate RAM */
817
    if (ram_size > (256 << 20)) {
818
        fprintf(stderr,
819
                "qemu: Too much memory for this machine: %d MB, maximum 256 MB\n",
820
                ((unsigned int)ram_size / (1 << 20)));
821
        exit(1);
822
    }
823
    ram_offset = qemu_ram_alloc(ram_size);
824
    bios_offset = qemu_ram_alloc(BIOS_SIZE);
825

    
826

    
827
    cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
828

    
829
    /* Map the bios at two physical locations, as on the real board. */
830
    cpu_register_physical_memory(0x1e000000LL,
831
                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
832
    cpu_register_physical_memory(0x1fc00000LL,
833
                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
834

    
835
    /* FPGA */
836
    malta_fpga = malta_fpga_init(0x1f000000LL, env->irq[2], serial_hds[2]);
837

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

    
895
    /* Board ID = 0x420 (Malta Board with CoreLV)
896
       XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
897
       map to the board ID. */
898
    stl_phys(0x1fc00010LL, 0x00000420);
899

    
900
    /* Init internal devices */
901
    cpu_mips_irq_init_cpu(env);
902
    cpu_mips_clock_init(env);
903

    
904
    /* Interrupt controller */
905
    /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
906
    i8259 = i8259_init(env->irq[2]);
907

    
908
    /* Northbridge */
909
    pci_bus = pci_gt64120_init(i8259);
910

    
911
    /* Southbridge */
912

    
913
    if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
914
        fprintf(stderr, "qemu: too many IDE bus\n");
915
        exit(1);
916
    }
917

    
918
    for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
919
        hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
920
    }
921

    
922
    piix4_devfn = piix4_init(pci_bus, 80);
923
    isa_bus_irqs(i8259);
924
    pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);
925
    usb_uhci_piix4_init(pci_bus, piix4_devfn + 2);
926
    smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100, isa_reserve_irq(9));
927
    eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
928
    for (i = 0; i < 8; i++) {
929
        /* TODO: Populate SPD eeprom data.  */
930
        DeviceState *eeprom;
931
        eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");
932
        qdev_prop_set_uint8(eeprom, "address", 0x50 + i);
933
        qdev_prop_set_ptr(eeprom, "data", eeprom_buf + (i * 256));
934
        qdev_init_nofail(eeprom);
935
    }
936
    pit = pit_init(0x40, isa_reserve_irq(0));
937
    DMA_init(0);
938

    
939
    /* Super I/O */
940
    isa_dev = isa_create_simple("i8042");
941
 
942
    rtc_state = rtc_init(2000);
943
    serial_isa_init(0, serial_hds[0]);
944
    serial_isa_init(1, serial_hds[1]);
945
    if (parallel_hds[0])
946
        parallel_init(0, parallel_hds[0]);
947
    for(i = 0; i < MAX_FD; i++) {
948
        fd[i] = drive_get(IF_FLOPPY, 0, i);
949
    }
950
    floppy_controller = fdctrl_init_isa(fd);
951

    
952
    /* Sound card */
953
#ifdef HAS_AUDIO
954
    audio_init(pci_bus);
955
#endif
956

    
957
    /* Network card */
958
    network_init();
959

    
960
    /* Optional PCI video card */
961
    if (cirrus_vga_enabled) {
962
        pci_cirrus_vga_init(pci_bus);
963
    } else if (vmsvga_enabled) {
964
        pci_vmsvga_init(pci_bus);
965
    } else if (std_vga_enabled) {
966
        pci_vga_init(pci_bus, 0, 0);
967
    }
968
}
969

    
970
static QEMUMachine mips_malta_machine = {
971
    .name = "malta",
972
    .desc = "MIPS Malta Core LV",
973
    .init = mips_malta_init,
974
    .is_default = 1,
975
};
976

    
977
static void mips_malta_machine_init(void)
978
{
979
    qemu_register_machine(&mips_malta_machine);
980
}
981

    
982
machine_init(mips_malta_machine_init);