Statistics
| Branch: | Revision:

root / hw / mips_malta.c @ 5c02c033

History | View | Annotate | Download (31.8 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
#ifdef TARGET_MIPS64
50
#define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffULL)
51
#else
52
#define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffU)
53
#endif
54

    
55
#define ENVP_ADDR (int32_t)0x80002000
56
#define VIRT_TO_PHYS_ADDEND (-((int64_t)(int32_t)0x80000000))
57

    
58
#define ENVP_NB_ENTRIES                 16
59
#define ENVP_ENTRY_SIZE                 256
60

    
61
#define MAX_IDE_BUS 2
62

    
63
typedef struct {
64
    uint32_t leds;
65
    uint32_t brk;
66
    uint32_t gpout;
67
    uint32_t i2cin;
68
    uint32_t i2coe;
69
    uint32_t i2cout;
70
    uint32_t i2csel;
71
    CharDriverState *display;
72
    char display_text[9];
73
    SerialState *uart;
74
} MaltaFPGAState;
75

    
76
static PITState *pit;
77

    
78
static struct _loaderparams {
79
    int ram_size;
80
    const char *kernel_filename;
81
    const char *kernel_cmdline;
82
    const char *initrd_filename;
83
} loaderparams;
84

    
85
/* Malta FPGA */
86
static void malta_fpga_update_display(void *opaque)
87
{
88
    char leds_text[9];
89
    int i;
90
    MaltaFPGAState *s = opaque;
91

    
92
    for (i = 7 ; i >= 0 ; i--) {
93
        if (s->leds & (1 << i))
94
            leds_text[i] = '#';
95
        else
96
            leds_text[i] = ' ';
97
    }
98
    leds_text[8] = '\0';
99

    
100
    qemu_chr_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text);
101
    qemu_chr_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text);
102
}
103

    
104
/*
105
 * EEPROM 24C01 / 24C02 emulation.
106
 *
107
 * Emulation for serial EEPROMs:
108
 * 24C01 - 1024 bit (128 x 8)
109
 * 24C02 - 2048 bit (256 x 8)
110
 *
111
 * Typical device names include Microchip 24C02SC or SGS Thomson ST24C02.
112
 */
113

    
114
//~ #define DEBUG
115

    
116
#if defined(DEBUG)
117
#  define logout(fmt, ...) fprintf(stderr, "MALTA\t%-24s" fmt, __func__, ## __VA_ARGS__)
118
#else
119
#  define logout(fmt, ...) ((void)0)
120
#endif
121

    
122
struct _eeprom24c0x_t {
123
  uint8_t tick;
124
  uint8_t address;
125
  uint8_t command;
126
  uint8_t ack;
127
  uint8_t scl;
128
  uint8_t sda;
129
  uint8_t data;
130
  //~ uint16_t size;
131
  uint8_t contents[256];
132
};
133

    
134
typedef struct _eeprom24c0x_t eeprom24c0x_t;
135

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

    
157
static uint8_t eeprom24c0x_read(void)
158
{
159
    logout("%u: scl = %u, sda = %u, data = 0x%02x\n",
160
        eeprom.tick, eeprom.scl, eeprom.sda, eeprom.data);
161
    return eeprom.sda;
162
}
163

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

    
222
static uint32_t malta_fpga_readl(void *opaque, target_phys_addr_t addr)
223
{
224
    MaltaFPGAState *s = opaque;
225
    uint32_t val = 0;
226
    uint32_t saddr;
227

    
228
    saddr = (addr & 0xfffff);
229

    
230
    switch (saddr) {
231

    
232
    /* SWITCH Register */
233
    case 0x00200:
234
        val = 0x00000000;                /* All switches closed */
235
        break;
236

    
237
    /* STATUS Register */
238
    case 0x00208:
239
#ifdef TARGET_WORDS_BIGENDIAN
240
        val = 0x00000012;
241
#else
242
        val = 0x00000010;
243
#endif
244
        break;
245

    
246
    /* JMPRS Register */
247
    case 0x00210:
248
        val = 0x00;
249
        break;
250

    
251
    /* LEDBAR Register */
252
    case 0x00408:
253
        val = s->leds;
254
        break;
255

    
256
    /* BRKRES Register */
257
    case 0x00508:
258
        val = s->brk;
259
        break;
260

    
261
    /* UART Registers are handled directly by the serial device */
262

    
263
    /* GPOUT Register */
264
    case 0x00a00:
265
        val = s->gpout;
266
        break;
267

    
268
    /* XXX: implement a real I2C controller */
269

    
270
    /* GPINP Register */
271
    case 0x00a08:
272
        /* IN = OUT until a real I2C control is implemented */
273
        if (s->i2csel)
274
            val = s->i2cout;
275
        else
276
            val = 0x00;
277
        break;
278

    
279
    /* I2CINP Register */
280
    case 0x00b00:
281
        val = ((s->i2cin & ~1) | eeprom24c0x_read());
282
        break;
283

    
284
    /* I2COE Register */
285
    case 0x00b08:
286
        val = s->i2coe;
287
        break;
288

    
289
    /* I2COUT Register */
290
    case 0x00b10:
291
        val = s->i2cout;
292
        break;
293

    
294
    /* I2CSEL Register */
295
    case 0x00b18:
296
        val = s->i2csel;
297
        break;
298

    
299
    default:
300
#if 0
301
        printf ("malta_fpga_read: Bad register offset 0x" TARGET_FMT_lx "\n",
302
                addr);
303
#endif
304
        break;
305
    }
306
    return val;
307
}
308

    
309
static void malta_fpga_writel(void *opaque, target_phys_addr_t addr,
310
                              uint32_t val)
311
{
312
    MaltaFPGAState *s = opaque;
313
    uint32_t saddr;
314

    
315
    saddr = (addr & 0xfffff);
316

    
317
    switch (saddr) {
318

    
319
    /* SWITCH Register */
320
    case 0x00200:
321
        break;
322

    
323
    /* JMPRS Register */
324
    case 0x00210:
325
        break;
326

    
327
    /* LEDBAR Register */
328
    /* XXX: implement a 8-LED array */
329
    case 0x00408:
330
        s->leds = val & 0xff;
331
        break;
332

    
333
    /* ASCIIWORD Register */
334
    case 0x00410:
335
        snprintf(s->display_text, 9, "%08X", val);
336
        malta_fpga_update_display(s);
337
        break;
338

    
339
    /* ASCIIPOS0 to ASCIIPOS7 Registers */
340
    case 0x00418:
341
    case 0x00420:
342
    case 0x00428:
343
    case 0x00430:
344
    case 0x00438:
345
    case 0x00440:
346
    case 0x00448:
347
    case 0x00450:
348
        s->display_text[(saddr - 0x00418) >> 3] = (char) val;
349
        malta_fpga_update_display(s);
350
        break;
351

    
352
    /* SOFTRES Register */
353
    case 0x00500:
354
        if (val == 0x42)
355
            qemu_system_reset_request ();
356
        break;
357

    
358
    /* BRKRES Register */
359
    case 0x00508:
360
        s->brk = val & 0xff;
361
        break;
362

    
363
    /* UART Registers are handled directly by the serial device */
364

    
365
    /* GPOUT Register */
366
    case 0x00a00:
367
        s->gpout = val & 0xff;
368
        break;
369

    
370
    /* I2COE Register */
371
    case 0x00b08:
372
        s->i2coe = val & 0x03;
373
        break;
374

    
375
    /* I2COUT Register */
376
    case 0x00b10:
377
        eeprom24c0x_write(val & 0x02, val & 0x01);
378
        s->i2cout = val;
379
        break;
380

    
381
    /* I2CSEL Register */
382
    case 0x00b18:
383
        s->i2csel = val & 0x01;
384
        break;
385

    
386
    default:
387
#if 0
388
        printf ("malta_fpga_write: Bad register offset 0x" TARGET_FMT_lx "\n",
389
                addr);
390
#endif
391
        break;
392
    }
393
}
394

    
395
static CPUReadMemoryFunc * const malta_fpga_read[] = {
396
   malta_fpga_readl,
397
   malta_fpga_readl,
398
   malta_fpga_readl
399
};
400

    
401
static CPUWriteMemoryFunc * const malta_fpga_write[] = {
402
   malta_fpga_writel,
403
   malta_fpga_writel,
404
   malta_fpga_writel
405
};
406

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

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

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

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

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

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

    
443
    malta = cpu_register_io_memory(malta_fpga_read,
444
                                   malta_fpga_write, s);
445

    
446
    cpu_register_physical_memory(base, 0x900, malta);
447
    /* 0xa00 is less than a page, so will still get the right offsets.  */
448
    cpu_register_physical_memory(base + 0xa00, 0x100000 - 0xa00, malta);
449

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

    
452
    s->uart = serial_mm_init(base + 0x900, 3, uart_irq, 230400, uart_chr, 1);
453

    
454
    malta_fpga_reset(s);
455
    qemu_register_reset(malta_fpga_reset, s);
456

    
457
    return s;
458
}
459

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

    
467
    for (c = soundhw; !audio_enabled && c->name; ++c) {
468
        audio_enabled = c->enabled;
469
    }
470

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

    
481
/* Network support */
482
static void network_init(void)
483
{
484
    int i;
485

    
486
    for(i = 0; i < nb_nics; i++) {
487
        NICInfo *nd = &nd_table[i];
488
        const char *default_devaddr = NULL;
489

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

    
494
        pci_nic_init_nofail(nd, "pcnet", default_devaddr);
495
    }
496
}
497

    
498
/* ROM and pseudo bootloader
499

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

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

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

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

    
520
static void write_bootloader (CPUState *env, uint8_t *base,
521
                              int64_t kernel_entry)
522
{
523
    uint32_t *p;
524

    
525
    /* Small bootloader */
526
    p = (uint32_t *)base;
527
    stl_raw(p++, 0x0bf00160);                                      /* j 0x1fc00580 */
528
    stl_raw(p++, 0x00000000);                                      /* nop */
529

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

    
545

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

    
558
    /* Load BAR registers as done by YAMON */
559
    stl_raw(p++, 0x3c09b400);                                      /* lui t1, 0xb400 */
560

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

    
568
    stl_raw(p++, 0x3c09bbe0);                                      /* lui t1, 0xbbe0 */
569

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

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

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

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

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

    
658
}
659

    
660
static void prom_set(uint32_t* prom_buf, int index, const char *string, ...)
661
{
662
    va_list ap;
663
    int32_t table_addr;
664

    
665
    if (index >= ENVP_NB_ENTRIES)
666
        return;
667

    
668
    if (string == NULL) {
669
        prom_buf[index] = 0;
670
        return;
671
    }
672

    
673
    table_addr = sizeof(int32_t) * ENVP_NB_ENTRIES + index * ENVP_ENTRY_SIZE;
674
    prom_buf[index] = tswap32(ENVP_ADDR + table_addr);
675

    
676
    va_start(ap, string);
677
    vsnprintf((char *)prom_buf + table_addr, ENVP_ENTRY_SIZE, string, ap);
678
    va_end(ap);
679
}
680

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

    
692
#ifdef TARGET_WORDS_BIGENDIAN
693
    big_endian = 1;
694
#else
695
    big_endian = 0;
696
#endif
697

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

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

    
730
    /* Setup prom parameters. */
731
    prom_size = ENVP_NB_ENTRIES * (sizeof(int32_t) + ENVP_ENTRY_SIZE);
732
    prom_buf = qemu_malloc(prom_size);
733

    
734
    prom_set(prom_buf, prom_index++, loaderparams.kernel_filename);
735
    if (initrd_size > 0) {
736
        prom_set(prom_buf, prom_index++, "rd_start=0x" TARGET_FMT_lx " rd_size=%li %s",
737
                 PHYS_TO_VIRT(initrd_offset), initrd_size,
738
                 loaderparams.kernel_cmdline);
739
    } else {
740
        prom_set(prom_buf, prom_index++, loaderparams.kernel_cmdline);
741
    }
742

    
743
    prom_set(prom_buf, prom_index++, "memsize");
744
    prom_set(prom_buf, prom_index++, "%i", loaderparams.ram_size);
745
    prom_set(prom_buf, prom_index++, "modetty0");
746
    prom_set(prom_buf, prom_index++, "38400n8r");
747
    prom_set(prom_buf, prom_index++, NULL);
748

    
749
    rom_add_blob_fixed("prom", prom_buf, prom_size,
750
                       ENVP_ADDR + VIRT_TO_PHYS_ADDEND);
751

    
752
    return kernel_entry;
753
}
754

    
755
static void main_cpu_reset(void *opaque)
756
{
757
    CPUState *env = opaque;
758
    cpu_reset(env);
759

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

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

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

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

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

    
830

    
831
    cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
832

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

    
839
    /* FPGA */
840
    malta_fpga = malta_fpga_init(0x1f000000LL, env->irq[2], serial_hds[2]);
841

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

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

    
904
    /* Init internal devices */
905
    cpu_mips_irq_init_cpu(env);
906
    cpu_mips_clock_init(env);
907

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

    
912
    /* Northbridge */
913
    pci_bus = pci_gt64120_init(i8259);
914

    
915
    /* Southbridge */
916

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

    
922
    for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
923
        hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
924
    }
925

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

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

    
956
    /* Sound card */
957
#ifdef HAS_AUDIO
958
    audio_init(pci_bus);
959
#endif
960

    
961
    /* Network card */
962
    network_init();
963

    
964
    /* Optional PCI video card */
965
    if (cirrus_vga_enabled) {
966
        pci_cirrus_vga_init(pci_bus);
967
    } else if (vmsvga_enabled) {
968
        pci_vmsvga_init(pci_bus);
969
    } else if (std_vga_enabled) {
970
        pci_vga_init(pci_bus, 0, 0);
971
    }
972
}
973

    
974
static QEMUMachine mips_malta_machine = {
975
    .name = "malta",
976
    .desc = "MIPS Malta Core LV",
977
    .init = mips_malta_init,
978
    .is_default = 1,
979
};
980

    
981
static void mips_malta_machine_init(void)
982
{
983
    qemu_register_machine(&mips_malta_machine);
984
}
985

    
986
machine_init(mips_malta_machine_init);