Statistics
| Branch: | Revision:

root / hw / mips / mips_malta.c @ dccfcd0e

History | View | Annotate | Download (33.7 kB)

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

    
25
#include "hw/hw.h"
26
#include "hw/i386/pc.h"
27
#include "hw/char/serial.h"
28
#include "hw/block/fdc.h"
29
#include "net/net.h"
30
#include "hw/boards.h"
31
#include "hw/i2c/smbus.h"
32
#include "block/block.h"
33
#include "hw/block/flash.h"
34
#include "hw/mips/mips.h"
35
#include "hw/mips/cpudevs.h"
36
#include "hw/pci/pci.h"
37
#include "sysemu/char.h"
38
#include "sysemu/sysemu.h"
39
#include "sysemu/arch_init.h"
40
#include "hw/boards.h"
41
#include "qemu/log.h"
42
#include "hw/mips/bios.h"
43
#include "hw/ide.h"
44
#include "hw/loader.h"
45
#include "elf.h"
46
#include "hw/timer/mc146818rtc.h"
47
#include "hw/timer/i8254.h"
48
#include "sysemu/blockdev.h"
49
#include "exec/address-spaces.h"
50
#include "hw/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(MIPSCPU *cpu)
747
{
748
    CPUMIPSState *env = &cpu->env;
749
    CPUState *cs = CPU(cpu);
750

    
751
    env->mvp->CP0_MVPConf0 |= ((smp_cpus - 1) << CP0MVPC0_PVPE) |
752
                         ((smp_cpus * cs->nr_threads - 1) << CP0MVPC0_PTC);
753
}
754

    
755
static void main_cpu_reset(void *opaque)
756
{
757
    MIPSCPU *cpu = opaque;
758
    CPUMIPSState *env = &cpu->env;
759

    
760
    cpu_reset(CPU(cpu));
761

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

    
769
    malta_mips_config(cpu);
770
}
771

    
772
static void cpu_request_exit(void *opaque, int irq, int level)
773
{
774
    CPUMIPSState *env = cpu_single_env;
775

    
776
    if (env && level) {
777
        cpu_exit(env);
778
    }
779
}
780

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

    
812
    DeviceState *dev = qdev_create(NULL, "mips-malta");
813
    MaltaState *s = DO_UPCAST(MaltaState, busdev.qdev, dev);
814

    
815
    qdev_init_nofail(dev);
816

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

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

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

    
843
        /* Init internal devices */
844
        cpu_mips_irq_init_cpu(env);
845
        cpu_mips_clock_init(env);
846
        qemu_register_reset(main_cpu_reset, cpu);
847
    }
848
    env = first_cpu;
849

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

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

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

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

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

    
939
    /* Init internal devices */
940
    cpu_mips_irq_init_cpu(env);
941
    cpu_mips_clock_init(env);
942

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

    
952
    /* Northbridge */
953
    pci_bus = gt64120_register(isa_irq);
954

    
955
    /* Southbridge */
956
    ide_drive_get(hd, MAX_IDE_BUS);
957

    
958
    piix4_devfn = piix4_init(pci_bus, &isa_bus, 80);
959

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

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

    
975
    /* Super I/O */
976
    isa_create_simple(isa_bus, "i8042");
977

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

    
988
    /* Sound card */
989
    audio_init(isa_bus, pci_bus);
990

    
991
    /* Network card */
992
    network_init();
993

    
994
    /* Optional PCI video card */
995
    pci_vga_init(pci_bus);
996
}
997

    
998
static int mips_malta_sysbus_device_init(SysBusDevice *sysbusdev)
999
{
1000
    return 0;
1001
}
1002

    
1003
static void mips_malta_class_init(ObjectClass *klass, void *data)
1004
{
1005
    SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
1006

    
1007
    k->init = mips_malta_sysbus_device_init;
1008
}
1009

    
1010
static const TypeInfo mips_malta_device = {
1011
    .name          = "mips-malta",
1012
    .parent        = TYPE_SYS_BUS_DEVICE,
1013
    .instance_size = sizeof(MaltaState),
1014
    .class_init    = mips_malta_class_init,
1015
};
1016

    
1017
static QEMUMachine mips_malta_machine = {
1018
    .name = "malta",
1019
    .desc = "MIPS Malta Core LV",
1020
    .init = mips_malta_init,
1021
    .max_cpus = 16,
1022
    .is_default = 1,
1023
    DEFAULT_MACHINE_OPTIONS,
1024
};
1025

    
1026
static void mips_malta_register_types(void)
1027
{
1028
    type_register_static(&mips_malta_device);
1029
}
1030

    
1031
static void mips_malta_machine_init(void)
1032
{
1033
    qemu_register_machine(&mips_malta_machine);
1034
}
1035

    
1036
type_init(mips_malta_register_types)
1037
machine_init(mips_malta_machine_init);