Statistics
| Branch: | Revision:

root / hw / mips / mips_malta.c @ 997aba8e

History | View | Annotate | Download (33.6 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 "qemu/log.h"
41
#include "hw/mips/bios.h"
42
#include "hw/ide.h"
43
#include "hw/loader.h"
44
#include "elf.h"
45
#include "hw/timer/mc146818rtc.h"
46
#include "hw/timer/i8254.h"
47
#include "sysemu/blockdev.h"
48
#include "exec/address-spaces.h"
49
#include "hw/sysbus.h"             /* SysBusDevice */
50

    
51
//#define DEBUG_BOARD_INIT
52

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

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

    
62
#define FLASH_SIZE    0x400000
63

    
64
#define MAX_IDE_BUS 2
65

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

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

    
87
static ISADevice *pit;
88

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

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

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

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

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

    
125
//~ #define DEBUG
126

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

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

    
145
typedef struct _eeprom24c0x_t eeprom24c0x_t;
146

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

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

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

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

    
240
    saddr = (addr & 0xfffff);
241

    
242
    switch (saddr) {
243

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
327
    saddr = (addr & 0xfffff);
328

    
329
    switch (saddr) {
330

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
467
    return s;
468
}
469

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

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

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

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

    
487
/* ROM and pseudo bootloader
488

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

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

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

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

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

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

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

    
534

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

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

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

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

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

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

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

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

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

    
647
}
648

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

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

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

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

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

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

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

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

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

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

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

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

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

    
742
    return kernel_entry;
743
}
744

    
745
static void malta_mips_config(MIPSCPU *cpu)
746
{
747
    CPUMIPSState *env = &cpu->env;
748
    CPUState *cs = CPU(cpu);
749

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

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

    
759
    cpu_reset(CPU(cpu));
760

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

    
768
    malta_mips_config(cpu);
769
}
770

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

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

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

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

    
814
    qdev_init_nofail(dev);
815

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1003
    k->init = mips_malta_sysbus_device_init;
1004
}
1005

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

    
1013
static QEMUMachine mips_malta_machine = {
1014
    .name = "malta",
1015
    .desc = "MIPS Malta Core LV",
1016
    .init = mips_malta_init,
1017
    .max_cpus = 16,
1018
    .is_default = 1,
1019
    DEFAULT_MACHINE_OPTIONS,
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);