Statistics
| Branch: | Revision:

root / hw / mips_malta.c @ c06aaf01

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 "fdc.h"
28
#include "net.h"
29
#include "boards.h"
30
#include "smbus.h"
31
#include "block.h"
32
#include "flash.h"
33
#include "mips.h"
34
#include "mips_cpudevs.h"
35
#include "pci.h"
36
#include "vmware_vga.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-memory.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, target_phys_addr_t 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, target_phys_addr_t 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
         target_phys_addr_t 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 (ram_addr_t ram_size,
780
                      const char *boot_device,
781
                      const char *kernel_filename, const char *kernel_cmdline,
782
                      const char *initrd_filename, const char *cpu_model)
783
{
784
    char *filename;
785
    pflash_t *fl;
786
    MemoryRegion *system_memory = get_system_memory();
787
    MemoryRegion *ram = g_new(MemoryRegion, 1);
788
    MemoryRegion *bios, *bios_alias = g_new(MemoryRegion, 1);
789
    target_long bios_size = FLASH_SIZE;
790
    int64_t kernel_entry;
791
    PCIBus *pci_bus;
792
    ISABus *isa_bus;
793
    MIPSCPU *cpu;
794
    CPUMIPSState *env;
795
    qemu_irq *isa_irq;
796
    qemu_irq *cpu_exit_irq;
797
    int piix4_devfn;
798
    i2c_bus *smbus;
799
    int i;
800
    DriveInfo *dinfo;
801
    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
802
    DriveInfo *fd[MAX_FD];
803
    int fl_idx = 0;
804
    int fl_sectors = bios_size >> 16;
805
    int be;
806

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

    
810
    qdev_init_nofail(dev);
811

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

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

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

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

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

    
856
#ifdef TARGET_WORDS_BIGENDIAN
857
    be = 1;
858
#else
859
    be = 0;
860
#endif
861
    /* FPGA */
862
    malta_fpga_init(system_memory, FPGA_ADDRESS, env->irq[2], serial_hds[2]);
863

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

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

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

    
933
    /* Init internal devices */
934
    cpu_mips_irq_init_cpu(env);
935
    cpu_mips_clock_init(env);
936

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

    
946
    /* Northbridge */
947
    pci_bus = gt64120_register(isa_irq);
948

    
949
    /* Southbridge */
950
    ide_drive_get(hd, MAX_IDE_BUS);
951

    
952
    piix4_devfn = piix4_init(pci_bus, &isa_bus, 80);
953

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

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

    
969
    /* Super I/O */
970
    isa_create_simple(isa_bus, "i8042");
971

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

    
982
    /* Sound card */
983
    audio_init(isa_bus, pci_bus);
984

    
985
    /* Network card */
986
    network_init();
987

    
988
    /* Optional PCI video card */
989
    if (cirrus_vga_enabled) {
990
        pci_cirrus_vga_init(pci_bus);
991
    } else if (vmsvga_enabled) {
992
        pci_vmsvga_init(pci_bus);
993
    } else if (std_vga_enabled) {
994
        pci_vga_init(pci_bus);
995
    }
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 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
};
1024

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

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

    
1035
type_init(mips_malta_register_types)
1036
machine_init(mips_malta_machine_init);