Statistics
| Branch: | Revision:

root / hw / mips_malta.c @ 1de7afc9

History | View | Annotate | Download (33.5 kB)

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

    
25
#include "hw.h"
26
#include "pc.h"
27
#include "serial.h"
28
#include "fdc.h"
29
#include "net/net.h"
30
#include "boards.h"
31
#include "smbus.h"
32
#include "block/block.h"
33
#include "flash.h"
34
#include "mips.h"
35
#include "mips_cpudevs.h"
36
#include "pci/pci.h"
37
#include "qemu-char.h"
38
#include "sysemu.h"
39
#include "arch_init.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
#include "mc146818rtc.h"
47
#include "i8254.h"
48
#include "blockdev.h"
49
#include "exec/address-spaces.h"
50
#include "sysbus.h"             /* SysBusDevice */
51

    
52
//#define DEBUG_BOARD_INIT
53

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

    
58
/* Hardware addresses */
59
#define FLASH_ADDRESS 0x1e000000ULL
60
#define FPGA_ADDRESS  0x1f000000ULL
61
#define RESET_ADDRESS 0x1fc00000ULL
62

    
63
#define FLASH_SIZE    0x400000
64

    
65
#define MAX_IDE_BUS 2
66

    
67
typedef struct {
68
    MemoryRegion iomem;
69
    MemoryRegion iomem_lo; /* 0 - 0x900 */
70
    MemoryRegion iomem_hi; /* 0xa00 - 0x100000 */
71
    uint32_t leds;
72
    uint32_t brk;
73
    uint32_t gpout;
74
    uint32_t i2cin;
75
    uint32_t i2coe;
76
    uint32_t i2cout;
77
    uint32_t i2csel;
78
    CharDriverState *display;
79
    char display_text[9];
80
    SerialState *uart;
81
} MaltaFPGAState;
82

    
83
typedef struct {
84
    SysBusDevice busdev;
85
    qemu_irq *i8259;
86
} MaltaState;
87

    
88
static ISADevice *pit;
89

    
90
static struct _loaderparams {
91
    int ram_size;
92
    const char *kernel_filename;
93
    const char *kernel_cmdline;
94
    const char *initrd_filename;
95
} loaderparams;
96

    
97
/* Malta FPGA */
98
static void malta_fpga_update_display(void *opaque)
99
{
100
    char leds_text[9];
101
    int i;
102
    MaltaFPGAState *s = opaque;
103

    
104
    for (i = 7 ; i >= 0 ; i--) {
105
        if (s->leds & (1 << i))
106
            leds_text[i] = '#';
107
        else
108
            leds_text[i] = ' ';
109
    }
110
    leds_text[8] = '\0';
111

    
112
    qemu_chr_fe_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text);
113
    qemu_chr_fe_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text);
114
}
115

    
116
/*
117
 * EEPROM 24C01 / 24C02 emulation.
118
 *
119
 * Emulation for serial EEPROMs:
120
 * 24C01 - 1024 bit (128 x 8)
121
 * 24C02 - 2048 bit (256 x 8)
122
 *
123
 * Typical device names include Microchip 24C02SC or SGS Thomson ST24C02.
124
 */
125

    
126
//~ #define DEBUG
127

    
128
#if defined(DEBUG)
129
#  define logout(fmt, ...) fprintf(stderr, "MALTA\t%-24s" fmt, __func__, ## __VA_ARGS__)
130
#else
131
#  define logout(fmt, ...) ((void)0)
132
#endif
133

    
134
struct _eeprom24c0x_t {
135
  uint8_t tick;
136
  uint8_t address;
137
  uint8_t command;
138
  uint8_t ack;
139
  uint8_t scl;
140
  uint8_t sda;
141
  uint8_t data;
142
  //~ uint16_t size;
143
  uint8_t contents[256];
144
};
145

    
146
typedef struct _eeprom24c0x_t eeprom24c0x_t;
147

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

    
169
static uint8_t eeprom24c0x_read(void)
170
{
171
    logout("%u: scl = %u, sda = %u, data = 0x%02x\n",
172
        eeprom.tick, eeprom.scl, eeprom.sda, eeprom.data);
173
    return eeprom.sda;
174
}
175

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

    
234
static uint64_t malta_fpga_read(void *opaque, hwaddr addr,
235
                                unsigned size)
236
{
237
    MaltaFPGAState *s = opaque;
238
    uint32_t val = 0;
239
    uint32_t saddr;
240

    
241
    saddr = (addr & 0xfffff);
242

    
243
    switch (saddr) {
244

    
245
    /* SWITCH Register */
246
    case 0x00200:
247
        val = 0x00000000;                /* All switches closed */
248
        break;
249

    
250
    /* STATUS Register */
251
    case 0x00208:
252
#ifdef TARGET_WORDS_BIGENDIAN
253
        val = 0x00000012;
254
#else
255
        val = 0x00000010;
256
#endif
257
        break;
258

    
259
    /* JMPRS Register */
260
    case 0x00210:
261
        val = 0x00;
262
        break;
263

    
264
    /* LEDBAR Register */
265
    case 0x00408:
266
        val = s->leds;
267
        break;
268

    
269
    /* BRKRES Register */
270
    case 0x00508:
271
        val = s->brk;
272
        break;
273

    
274
    /* UART Registers are handled directly by the serial device */
275

    
276
    /* GPOUT Register */
277
    case 0x00a00:
278
        val = s->gpout;
279
        break;
280

    
281
    /* XXX: implement a real I2C controller */
282

    
283
    /* GPINP Register */
284
    case 0x00a08:
285
        /* IN = OUT until a real I2C control is implemented */
286
        if (s->i2csel)
287
            val = s->i2cout;
288
        else
289
            val = 0x00;
290
        break;
291

    
292
    /* I2CINP Register */
293
    case 0x00b00:
294
        val = ((s->i2cin & ~1) | eeprom24c0x_read());
295
        break;
296

    
297
    /* I2COE Register */
298
    case 0x00b08:
299
        val = s->i2coe;
300
        break;
301

    
302
    /* I2COUT Register */
303
    case 0x00b10:
304
        val = s->i2cout;
305
        break;
306

    
307
    /* I2CSEL Register */
308
    case 0x00b18:
309
        val = s->i2csel;
310
        break;
311

    
312
    default:
313
#if 0
314
        printf ("malta_fpga_read: Bad register offset 0x" TARGET_FMT_lx "\n",
315
                addr);
316
#endif
317
        break;
318
    }
319
    return val;
320
}
321

    
322
static void malta_fpga_write(void *opaque, hwaddr addr,
323
                             uint64_t val, unsigned size)
324
{
325
    MaltaFPGAState *s = opaque;
326
    uint32_t saddr;
327

    
328
    saddr = (addr & 0xfffff);
329

    
330
    switch (saddr) {
331

    
332
    /* SWITCH Register */
333
    case 0x00200:
334
        break;
335

    
336
    /* JMPRS Register */
337
    case 0x00210:
338
        break;
339

    
340
    /* LEDBAR Register */
341
    case 0x00408:
342
        s->leds = val & 0xff;
343
        malta_fpga_update_display(s);
344
        break;
345

    
346
    /* ASCIIWORD Register */
347
    case 0x00410:
348
        snprintf(s->display_text, 9, "%08X", (uint32_t)val);
349
        malta_fpga_update_display(s);
350
        break;
351

    
352
    /* ASCIIPOS0 to ASCIIPOS7 Registers */
353
    case 0x00418:
354
    case 0x00420:
355
    case 0x00428:
356
    case 0x00430:
357
    case 0x00438:
358
    case 0x00440:
359
    case 0x00448:
360
    case 0x00450:
361
        s->display_text[(saddr - 0x00418) >> 3] = (char) val;
362
        malta_fpga_update_display(s);
363
        break;
364

    
365
    /* SOFTRES Register */
366
    case 0x00500:
367
        if (val == 0x42)
368
            qemu_system_reset_request ();
369
        break;
370

    
371
    /* BRKRES Register */
372
    case 0x00508:
373
        s->brk = val & 0xff;
374
        break;
375

    
376
    /* UART Registers are handled directly by the serial device */
377

    
378
    /* GPOUT Register */
379
    case 0x00a00:
380
        s->gpout = val & 0xff;
381
        break;
382

    
383
    /* I2COE Register */
384
    case 0x00b08:
385
        s->i2coe = val & 0x03;
386
        break;
387

    
388
    /* I2COUT Register */
389
    case 0x00b10:
390
        eeprom24c0x_write(val & 0x02, val & 0x01);
391
        s->i2cout = val;
392
        break;
393

    
394
    /* I2CSEL Register */
395
    case 0x00b18:
396
        s->i2csel = val & 0x01;
397
        break;
398

    
399
    default:
400
#if 0
401
        printf ("malta_fpga_write: Bad register offset 0x" TARGET_FMT_lx "\n",
402
                addr);
403
#endif
404
        break;
405
    }
406
}
407

    
408
static const MemoryRegionOps malta_fpga_ops = {
409
    .read = malta_fpga_read,
410
    .write = malta_fpga_write,
411
    .endianness = DEVICE_NATIVE_ENDIAN,
412
};
413

    
414
static void malta_fpga_reset(void *opaque)
415
{
416
    MaltaFPGAState *s = opaque;
417

    
418
    s->leds   = 0x00;
419
    s->brk    = 0x0a;
420
    s->gpout  = 0x00;
421
    s->i2cin  = 0x3;
422
    s->i2coe  = 0x0;
423
    s->i2cout = 0x3;
424
    s->i2csel = 0x1;
425

    
426
    s->display_text[8] = '\0';
427
    snprintf(s->display_text, 9, "        ");
428
}
429

    
430
static void malta_fpga_led_init(CharDriverState *chr)
431
{
432
    qemu_chr_fe_printf(chr, "\e[HMalta LEDBAR\r\n");
433
    qemu_chr_fe_printf(chr, "+--------+\r\n");
434
    qemu_chr_fe_printf(chr, "+        +\r\n");
435
    qemu_chr_fe_printf(chr, "+--------+\r\n");
436
    qemu_chr_fe_printf(chr, "\n");
437
    qemu_chr_fe_printf(chr, "Malta ASCII\r\n");
438
    qemu_chr_fe_printf(chr, "+--------+\r\n");
439
    qemu_chr_fe_printf(chr, "+        +\r\n");
440
    qemu_chr_fe_printf(chr, "+--------+\r\n");
441
}
442

    
443
static MaltaFPGAState *malta_fpga_init(MemoryRegion *address_space,
444
         hwaddr base, qemu_irq uart_irq, CharDriverState *uart_chr)
445
{
446
    MaltaFPGAState *s;
447

    
448
    s = (MaltaFPGAState *)g_malloc0(sizeof(MaltaFPGAState));
449

    
450
    memory_region_init_io(&s->iomem, &malta_fpga_ops, s,
451
                          "malta-fpga", 0x100000);
452
    memory_region_init_alias(&s->iomem_lo, "malta-fpga",
453
                             &s->iomem, 0, 0x900);
454
    memory_region_init_alias(&s->iomem_hi, "malta-fpga",
455
                             &s->iomem, 0xa00, 0x10000-0xa00);
456

    
457
    memory_region_add_subregion(address_space, base, &s->iomem_lo);
458
    memory_region_add_subregion(address_space, base + 0xa00, &s->iomem_hi);
459

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

    
462
    s->uart = serial_mm_init(address_space, base + 0x900, 3, uart_irq,
463
                             230400, uart_chr, DEVICE_NATIVE_ENDIAN);
464

    
465
    malta_fpga_reset(s);
466
    qemu_register_reset(malta_fpga_reset, s);
467

    
468
    return s;
469
}
470

    
471
/* Network support */
472
static void network_init(void)
473
{
474
    int i;
475

    
476
    for(i = 0; i < nb_nics; i++) {
477
        NICInfo *nd = &nd_table[i];
478
        const char *default_devaddr = NULL;
479

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

    
484
        pci_nic_init_nofail(nd, "pcnet", default_devaddr);
485
    }
486
}
487

    
488
/* ROM and pseudo bootloader
489

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

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

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

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

    
510
static void write_bootloader (CPUMIPSState *env, uint8_t *base,
511
                              int64_t kernel_entry)
512
{
513
    uint32_t *p;
514

    
515
    /* Small bootloader */
516
    p = (uint32_t *)base;
517
    stl_raw(p++, 0x0bf00160);                                      /* j 0x1fc00580 */
518
    stl_raw(p++, 0x00000000);                                      /* nop */
519

    
520
    /* YAMON service vector */
521
    stl_raw(base + 0x500, 0xbfc00580);      /* start: */
522
    stl_raw(base + 0x504, 0xbfc0083c);      /* print_count: */
523
    stl_raw(base + 0x520, 0xbfc00580);      /* start: */
524
    stl_raw(base + 0x52c, 0xbfc00800);      /* flush_cache: */
525
    stl_raw(base + 0x534, 0xbfc00808);      /* print: */
526
    stl_raw(base + 0x538, 0xbfc00800);      /* reg_cpu_isr: */
527
    stl_raw(base + 0x53c, 0xbfc00800);      /* unred_cpu_isr: */
528
    stl_raw(base + 0x540, 0xbfc00800);      /* reg_ic_isr: */
529
    stl_raw(base + 0x544, 0xbfc00800);      /* unred_ic_isr: */
530
    stl_raw(base + 0x548, 0xbfc00800);      /* reg_esr: */
531
    stl_raw(base + 0x54c, 0xbfc00800);      /* unreg_esr: */
532
    stl_raw(base + 0x550, 0xbfc00800);      /* getchar: */
533
    stl_raw(base + 0x554, 0xbfc00800);      /* syscon_read: */
534

    
535

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

    
548
    /* Load BAR registers as done by YAMON */
549
    stl_raw(p++, 0x3c09b400);                                      /* lui t1, 0xb400 */
550

    
551
#ifdef TARGET_WORDS_BIGENDIAN
552
    stl_raw(p++, 0x3c08df00);                                      /* lui t0, 0xdf00 */
553
#else
554
    stl_raw(p++, 0x340800df);                                      /* ori t0, r0, 0x00df */
555
#endif
556
    stl_raw(p++, 0xad280068);                                      /* sw t0, 0x0068(t1) */
557

    
558
    stl_raw(p++, 0x3c09bbe0);                                      /* lui t1, 0xbbe0 */
559

    
560
#ifdef TARGET_WORDS_BIGENDIAN
561
    stl_raw(p++, 0x3c08c000);                                      /* lui t0, 0xc000 */
562
#else
563
    stl_raw(p++, 0x340800c0);                                      /* ori t0, r0, 0x00c0 */
564
#endif
565
    stl_raw(p++, 0xad280048);                                      /* sw t0, 0x0048(t1) */
566
#ifdef TARGET_WORDS_BIGENDIAN
567
    stl_raw(p++, 0x3c084000);                                      /* lui t0, 0x4000 */
568
#else
569
    stl_raw(p++, 0x34080040);                                      /* ori t0, r0, 0x0040 */
570
#endif
571
    stl_raw(p++, 0xad280050);                                      /* sw t0, 0x0050(t1) */
572

    
573
#ifdef TARGET_WORDS_BIGENDIAN
574
    stl_raw(p++, 0x3c088000);                                      /* lui t0, 0x8000 */
575
#else
576
    stl_raw(p++, 0x34080080);                                      /* ori t0, r0, 0x0080 */
577
#endif
578
    stl_raw(p++, 0xad280058);                                      /* sw t0, 0x0058(t1) */
579
#ifdef TARGET_WORDS_BIGENDIAN
580
    stl_raw(p++, 0x3c083f00);                                      /* lui t0, 0x3f00 */
581
#else
582
    stl_raw(p++, 0x3408003f);                                      /* ori t0, r0, 0x003f */
583
#endif
584
    stl_raw(p++, 0xad280060);                                      /* sw t0, 0x0060(t1) */
585

    
586
#ifdef TARGET_WORDS_BIGENDIAN
587
    stl_raw(p++, 0x3c08c100);                                      /* lui t0, 0xc100 */
588
#else
589
    stl_raw(p++, 0x340800c1);                                      /* ori t0, r0, 0x00c1 */
590
#endif
591
    stl_raw(p++, 0xad280080);                                      /* sw t0, 0x0080(t1) */
592
#ifdef TARGET_WORDS_BIGENDIAN
593
    stl_raw(p++, 0x3c085e00);                                      /* lui t0, 0x5e00 */
594
#else
595
    stl_raw(p++, 0x3408005e);                                      /* ori t0, r0, 0x005e */
596
#endif
597
    stl_raw(p++, 0xad280088);                                      /* sw t0, 0x0088(t1) */
598

    
599
    /* Jump to kernel code */
600
    stl_raw(p++, 0x3c1f0000 | ((kernel_entry >> 16) & 0xffff));    /* lui ra, high(kernel_entry) */
601
    stl_raw(p++, 0x37ff0000 | (kernel_entry & 0xffff));            /* ori ra, ra, low(kernel_entry) */
602
    stl_raw(p++, 0x03e00008);                                      /* jr ra */
603
    stl_raw(p++, 0x00000000);                                      /* nop */
604

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

    
648
}
649

    
650
static void GCC_FMT_ATTR(3, 4) prom_set(uint32_t* prom_buf, int index,
651
                                        const char *string, ...)
652
{
653
    va_list ap;
654
    int32_t table_addr;
655

    
656
    if (index >= ENVP_NB_ENTRIES)
657
        return;
658

    
659
    if (string == NULL) {
660
        prom_buf[index] = 0;
661
        return;
662
    }
663

    
664
    table_addr = sizeof(int32_t) * ENVP_NB_ENTRIES + index * ENVP_ENTRY_SIZE;
665
    prom_buf[index] = tswap32(ENVP_ADDR + table_addr);
666

    
667
    va_start(ap, string);
668
    vsnprintf((char *)prom_buf + table_addr, ENVP_ENTRY_SIZE, string, ap);
669
    va_end(ap);
670
}
671

    
672
/* Kernel */
673
static int64_t load_kernel (void)
674
{
675
    int64_t kernel_entry, kernel_high;
676
    long initrd_size;
677
    ram_addr_t initrd_offset;
678
    int big_endian;
679
    uint32_t *prom_buf;
680
    long prom_size;
681
    int prom_index = 0;
682

    
683
#ifdef TARGET_WORDS_BIGENDIAN
684
    big_endian = 1;
685
#else
686
    big_endian = 0;
687
#endif
688

    
689
    if (load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_to_phys, NULL,
690
                 (uint64_t *)&kernel_entry, NULL, (uint64_t *)&kernel_high,
691
                 big_endian, ELF_MACHINE, 1) < 0) {
692
        fprintf(stderr, "qemu: could not load kernel '%s'\n",
693
                loaderparams.kernel_filename);
694
        exit(1);
695
    }
696

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

    
721
    /* Setup prom parameters. */
722
    prom_size = ENVP_NB_ENTRIES * (sizeof(int32_t) + ENVP_ENTRY_SIZE);
723
    prom_buf = g_malloc(prom_size);
724

    
725
    prom_set(prom_buf, prom_index++, "%s", loaderparams.kernel_filename);
726
    if (initrd_size > 0) {
727
        prom_set(prom_buf, prom_index++, "rd_start=0x%" PRIx64 " rd_size=%li %s",
728
                 cpu_mips_phys_to_kseg0(NULL, initrd_offset), initrd_size,
729
                 loaderparams.kernel_cmdline);
730
    } else {
731
        prom_set(prom_buf, prom_index++, "%s", loaderparams.kernel_cmdline);
732
    }
733

    
734
    prom_set(prom_buf, prom_index++, "memsize");
735
    prom_set(prom_buf, prom_index++, "%i", loaderparams.ram_size);
736
    prom_set(prom_buf, prom_index++, "modetty0");
737
    prom_set(prom_buf, prom_index++, "38400n8r");
738
    prom_set(prom_buf, prom_index++, NULL);
739

    
740
    rom_add_blob_fixed("prom", prom_buf, prom_size,
741
                       cpu_mips_kseg0_to_phys(NULL, ENVP_ADDR));
742

    
743
    return kernel_entry;
744
}
745

    
746
static void malta_mips_config(CPUMIPSState *env)
747
{
748
    env->mvp->CP0_MVPConf0 |= ((smp_cpus - 1) << CP0MVPC0_PVPE) |
749
                         ((smp_cpus * env->nr_threads - 1) << CP0MVPC0_PTC);
750
}
751

    
752
static void main_cpu_reset(void *opaque)
753
{
754
    MIPSCPU *cpu = opaque;
755
    CPUMIPSState *env = &cpu->env;
756

    
757
    cpu_reset(CPU(cpu));
758

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

    
766
    malta_mips_config(env);
767
}
768

    
769
static void cpu_request_exit(void *opaque, int irq, int level)
770
{
771
    CPUMIPSState *env = cpu_single_env;
772

    
773
    if (env && level) {
774
        cpu_exit(env);
775
    }
776
}
777

    
778
static
779
void mips_malta_init(QEMUMachineInitArgs *args)
780
{
781
    ram_addr_t ram_size = args->ram_size;
782
    const char *cpu_model = args->cpu_model;
783
    const char *kernel_filename = args->kernel_filename;
784
    const char *kernel_cmdline = args->kernel_cmdline;
785
    const char *initrd_filename = args->initrd_filename;
786
    char *filename;
787
    pflash_t *fl;
788
    MemoryRegion *system_memory = get_system_memory();
789
    MemoryRegion *ram = g_new(MemoryRegion, 1);
790
    MemoryRegion *bios, *bios_alias = g_new(MemoryRegion, 1);
791
    target_long bios_size = FLASH_SIZE;
792
    int64_t kernel_entry;
793
    PCIBus *pci_bus;
794
    ISABus *isa_bus;
795
    MIPSCPU *cpu;
796
    CPUMIPSState *env;
797
    qemu_irq *isa_irq;
798
    qemu_irq *cpu_exit_irq;
799
    int piix4_devfn;
800
    i2c_bus *smbus;
801
    int i;
802
    DriveInfo *dinfo;
803
    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
804
    DriveInfo *fd[MAX_FD];
805
    int fl_idx = 0;
806
    int fl_sectors = bios_size >> 16;
807
    int be;
808

    
809
    DeviceState *dev = qdev_create(NULL, "mips-malta");
810
    MaltaState *s = DO_UPCAST(MaltaState, busdev.qdev, dev);
811

    
812
    qdev_init_nofail(dev);
813

    
814
    /* Make sure the first 3 serial ports are associated with a device. */
815
    for(i = 0; i < 3; i++) {
816
        if (!serial_hds[i]) {
817
            char label[32];
818
            snprintf(label, sizeof(label), "serial%d", i);
819
            serial_hds[i] = qemu_chr_new(label, "null", NULL);
820
        }
821
    }
822

    
823
    /* init CPUs */
824
    if (cpu_model == NULL) {
825
#ifdef TARGET_MIPS64
826
        cpu_model = "20Kc";
827
#else
828
        cpu_model = "24Kf";
829
#endif
830
    }
831

    
832
    for (i = 0; i < smp_cpus; i++) {
833
        cpu = cpu_mips_init(cpu_model);
834
        if (cpu == NULL) {
835
            fprintf(stderr, "Unable to find CPU definition\n");
836
            exit(1);
837
        }
838
        env = &cpu->env;
839

    
840
        /* Init internal devices */
841
        cpu_mips_irq_init_cpu(env);
842
        cpu_mips_clock_init(env);
843
        qemu_register_reset(main_cpu_reset, cpu);
844
    }
845
    env = first_cpu;
846

    
847
    /* allocate RAM */
848
    if (ram_size > (256 << 20)) {
849
        fprintf(stderr,
850
                "qemu: Too much memory for this machine: %d MB, maximum 256 MB\n",
851
                ((unsigned int)ram_size / (1 << 20)));
852
        exit(1);
853
    }
854
    memory_region_init_ram(ram, "mips_malta.ram", ram_size);
855
    vmstate_register_ram_global(ram);
856
    memory_region_add_subregion(system_memory, 0, ram);
857

    
858
#ifdef TARGET_WORDS_BIGENDIAN
859
    be = 1;
860
#else
861
    be = 0;
862
#endif
863
    /* FPGA */
864
    /* The CBUS UART is attached to the MIPS CPU INT2 pin, ie interrupt 4 */
865
    malta_fpga_init(system_memory, FPGA_ADDRESS, env->irq[4], serial_hds[2]);
866

    
867
    /* Load firmware in flash / BIOS. */
868
    dinfo = drive_get(IF_PFLASH, 0, fl_idx);
869
#ifdef DEBUG_BOARD_INIT
870
    if (dinfo) {
871
        printf("Register parallel flash %d size " TARGET_FMT_lx " at "
872
               "addr %08llx '%s' %x\n",
873
               fl_idx, bios_size, FLASH_ADDRESS,
874
               bdrv_get_device_name(dinfo->bdrv), fl_sectors);
875
    }
876
#endif
877
    fl = pflash_cfi01_register(FLASH_ADDRESS, NULL, "mips_malta.bios",
878
                               BIOS_SIZE, dinfo ? dinfo->bdrv : NULL,
879
                               65536, fl_sectors,
880
                               4, 0x0000, 0x0000, 0x0000, 0x0000, be);
881
    bios = pflash_cfi01_get_memory(fl);
882
    fl_idx++;
883
    if (kernel_filename) {
884
        /* Write a small bootloader to the flash location. */
885
        loaderparams.ram_size = ram_size;
886
        loaderparams.kernel_filename = kernel_filename;
887
        loaderparams.kernel_cmdline = kernel_cmdline;
888
        loaderparams.initrd_filename = initrd_filename;
889
        kernel_entry = load_kernel();
890
        write_bootloader(env, memory_region_get_ram_ptr(bios), kernel_entry);
891
    } else {
892
        /* Load firmware from flash. */
893
        if (!dinfo) {
894
            /* Load a BIOS image. */
895
            if (bios_name == NULL) {
896
                bios_name = BIOS_FILENAME;
897
            }
898
            filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
899
            if (filename) {
900
                bios_size = load_image_targphys(filename, FLASH_ADDRESS,
901
                                                BIOS_SIZE);
902
                g_free(filename);
903
            } else {
904
                bios_size = -1;
905
            }
906
            if ((bios_size < 0 || bios_size > BIOS_SIZE) && !kernel_filename) {
907
                fprintf(stderr,
908
                        "qemu: Could not load MIPS bios '%s', and no -kernel argument was specified\n",
909
                        bios_name);
910
                exit(1);
911
            }
912
        }
913
        /* In little endian mode the 32bit words in the bios are swapped,
914
           a neat trick which allows bi-endian firmware. */
915
#ifndef TARGET_WORDS_BIGENDIAN
916
        {
917
            uint32_t *addr = memory_region_get_ram_ptr(bios);
918
            uint32_t *end = addr + bios_size;
919
            while (addr < end) {
920
                bswap32s(addr);
921
                addr++;
922
            }
923
        }
924
#endif
925
    }
926

    
927
    /* Map the BIOS at a 2nd physical location, as on the real board. */
928
    memory_region_init_alias(bios_alias, "bios.1fc", bios, 0, BIOS_SIZE);
929
    memory_region_add_subregion(system_memory, RESET_ADDRESS, bios_alias);
930

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

    
936
    /* Init internal devices */
937
    cpu_mips_irq_init_cpu(env);
938
    cpu_mips_clock_init(env);
939

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

    
949
    /* Northbridge */
950
    pci_bus = gt64120_register(isa_irq);
951

    
952
    /* Southbridge */
953
    ide_drive_get(hd, MAX_IDE_BUS);
954

    
955
    piix4_devfn = piix4_init(pci_bus, &isa_bus, 80);
956

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

    
961
    isa_bus_irqs(isa_bus, s->i8259);
962
    pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);
963
    pci_create_simple(pci_bus, piix4_devfn + 2, "piix4-usb-uhci");
964
    smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100,
965
                          isa_get_irq(NULL, 9), NULL, 0, NULL);
966
    /* TODO: Populate SPD eeprom data.  */
967
    smbus_eeprom_init(smbus, 8, NULL, 0);
968
    pit = pit_init(isa_bus, 0x40, 0, NULL);
969
    cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
970
    DMA_init(0, cpu_exit_irq);
971

    
972
    /* Super I/O */
973
    isa_create_simple(isa_bus, "i8042");
974

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

    
985
    /* Sound card */
986
    audio_init(isa_bus, pci_bus);
987

    
988
    /* Network card */
989
    network_init();
990

    
991
    /* Optional PCI video card */
992
    pci_vga_init(pci_bus);
993
}
994

    
995
static int mips_malta_sysbus_device_init(SysBusDevice *sysbusdev)
996
{
997
    return 0;
998
}
999

    
1000
static void mips_malta_class_init(ObjectClass *klass, void *data)
1001
{
1002
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
1003

    
1004
    k->init = mips_malta_sysbus_device_init;
1005
}
1006

    
1007
static TypeInfo mips_malta_device = {
1008
    .name          = "mips-malta",
1009
    .parent        = TYPE_SYS_BUS_DEVICE,
1010
    .instance_size = sizeof(MaltaState),
1011
    .class_init    = mips_malta_class_init,
1012
};
1013

    
1014
static QEMUMachine mips_malta_machine = {
1015
    .name = "malta",
1016
    .desc = "MIPS Malta Core LV",
1017
    .init = mips_malta_init,
1018
    .max_cpus = 16,
1019
    .is_default = 1,
1020
};
1021

    
1022
static void mips_malta_register_types(void)
1023
{
1024
    type_register_static(&mips_malta_device);
1025
}
1026

    
1027
static void mips_malta_machine_init(void)
1028
{
1029
    qemu_register_machine(&mips_malta_machine);
1030
}
1031

    
1032
type_init(mips_malta_register_types)
1033
machine_init(mips_malta_machine_init);