Statistics
| Branch: | Revision:

root / hw / mips_malta.c @ 3d08ff69

History | View | Annotate | Download (31.9 kB)

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

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

    
48
//#define DEBUG_BOARD_INIT
49

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

    
54
#define MAX_IDE_BUS 2
55

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

    
69
static PITState *pit;
70

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

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

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

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

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

    
107
//~ #define DEBUG
108

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

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

    
127
typedef struct _eeprom24c0x_t eeprom24c0x_t;
128

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

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

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

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

    
221
    saddr = (addr & 0xfffff);
222

    
223
    switch (saddr) {
224

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
308
    saddr = (addr & 0xfffff);
309

    
310
    switch (saddr) {
311

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
454
    return s;
455
}
456

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

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

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

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

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

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

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

    
495
/* ROM and pseudo bootloader
496

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

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

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

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

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

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

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

    
542

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

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

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

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

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

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

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

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

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

    
655
}
656

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

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

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

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

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

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

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

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

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

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

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

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

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

    
749
    return kernel_entry;
750
}
751

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

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

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

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

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

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

    
828

    
829
    cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
830

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

    
837
#ifdef TARGET_WORDS_BIGENDIAN
838
    be = 1;
839
#else
840
    be = 0;
841
#endif
842
    /* FPGA */
843
    malta_fpga = malta_fpga_init(0x1f000000LL, env->irq[2], serial_hds[2]);
844

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

    
902
    /* Board ID = 0x420 (Malta Board with CoreLV)
903
       XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
904
       map to the board ID. */
905
    stl_phys(0x1fc00010LL, 0x00000420);
906

    
907
    /* Init internal devices */
908
    cpu_mips_irq_init_cpu(env);
909
    cpu_mips_clock_init(env);
910

    
911
    /* Interrupt controller */
912
    /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
913
    i8259 = i8259_init(env->irq[2]);
914

    
915
    /* Northbridge */
916
    pci_bus = pci_gt64120_init(i8259);
917

    
918
    /* Southbridge */
919

    
920
    if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
921
        fprintf(stderr, "qemu: too many IDE bus\n");
922
        exit(1);
923
    }
924

    
925
    for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
926
        hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
927
    }
928

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

    
947
    /* Super I/O */
948
    isa_dev = isa_create_simple("i8042");
949
 
950
    rtc_state = rtc_init(2000);
951
    serial_isa_init(0, serial_hds[0]);
952
    serial_isa_init(1, serial_hds[1]);
953
    if (parallel_hds[0])
954
        parallel_init(0, parallel_hds[0]);
955
    for(i = 0; i < MAX_FD; i++) {
956
        fd[i] = drive_get(IF_FLOPPY, 0, i);
957
    }
958
    floppy_controller = fdctrl_init_isa(fd);
959

    
960
    /* Sound card */
961
#ifdef HAS_AUDIO
962
    audio_init(pci_bus);
963
#endif
964

    
965
    /* Network card */
966
    network_init();
967

    
968
    /* Optional PCI video card */
969
    if (cirrus_vga_enabled) {
970
        pci_cirrus_vga_init(pci_bus);
971
    } else if (vmsvga_enabled) {
972
        pci_vmsvga_init(pci_bus);
973
    } else if (std_vga_enabled) {
974
        pci_vga_init(pci_bus, 0, 0);
975
    }
976
}
977

    
978
static QEMUMachine mips_malta_machine = {
979
    .name = "malta",
980
    .desc = "MIPS Malta Core LV",
981
    .init = mips_malta_init,
982
    .is_default = 1,
983
};
984

    
985
static void mips_malta_machine_init(void)
986
{
987
    qemu_register_machine(&mips_malta_machine);
988
}
989

    
990
machine_init(mips_malta_machine_init);