Statistics
| Branch: | Revision:

root / hw / mips_malta.c @ c938ada2

History | View | Annotate | Download (31.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.h"
26
#include "pc.h"
27
#include "fdc.h"
28
#include "net.h"
29
#include "boards.h"
30
#include "smbus.h"
31
#include "block.h"
32
#include "flash.h"
33
#include "mips.h"
34
#include "pci.h"
35
#include "qemu-char.h"
36
#include "sysemu.h"
37
#include "audio/audio.h"
38
#include "boards.h"
39
#include "qemu-log.h"
40
#include "mips-bios.h"
41
#include "ide.h"
42
#include "loader.h"
43
#include "elf.h"
44

    
45
//#define DEBUG_BOARD_INIT
46

    
47
#ifdef TARGET_MIPS64
48
#define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffULL)
49
#else
50
#define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffU)
51
#endif
52

    
53
#define ENVP_ADDR (int32_t)0x80002000
54
#define VIRT_TO_PHYS_ADDEND (-((int64_t)(int32_t)0x80000000))
55

    
56
#define ENVP_NB_ENTRIES                 16
57
#define ENVP_ENTRY_SIZE                 256
58

    
59
#define MAX_IDE_BUS 2
60

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

    
74
static PITState *pit;
75

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

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

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

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

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

    
112
//~ #define DEBUG
113

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

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

    
132
typedef struct _eeprom24c0x_t eeprom24c0x_t;
133

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

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

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

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

    
226
    saddr = (addr & 0xfffff);
227

    
228
    switch (saddr) {
229

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

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

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

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

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

    
259
    /* UART Registers are handled directly by the serial device */
260

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

    
266
    /* XXX: implement a real I2C controller */
267

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

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

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

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

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

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

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

    
313
    saddr = (addr & 0xfffff);
314

    
315
    switch (saddr) {
316

    
317
    /* SWITCH Register */
318
    case 0x00200:
319
        break;
320

    
321
    /* JMPRS Register */
322
    case 0x00210:
323
        break;
324

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

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

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

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

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

    
361
    /* UART Registers are handled directly by the serial device */
362

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

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

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

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

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

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

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

    
405
static void malta_fpga_reset(void *opaque)
406
{
407
    MaltaFPGAState *s = opaque;
408

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

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

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

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

    
439
    s = (MaltaFPGAState *)qemu_mallocz(sizeof(MaltaFPGAState));
440

    
441
    malta = cpu_register_io_memory(malta_fpga_read,
442
                                   malta_fpga_write, s);
443

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

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

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

    
452
    malta_fpga_reset(s);
453
    qemu_register_reset(malta_fpga_reset, s);
454

    
455
    return s;
456
}
457

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

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

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

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

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

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

    
492
        pci_nic_init_nofail(nd, "pcnet", default_devaddr);
493
    }
494
}
495

    
496
/* ROM and pseudo bootloader
497

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

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

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

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

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

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

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

    
543

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

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

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

    
566
    stl_raw(p++, 0x3c09bbe0);                                      /* lui t1, 0xbbe0 */
567

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

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

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

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

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

    
656
}
657

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

    
663
    if (index >= ENVP_NB_ENTRIES)
664
        return;
665

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

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

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

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

    
690
#ifdef TARGET_WORDS_BIGENDIAN
691
    big_endian = 1;
692
#else
693
    big_endian = 0;
694
#endif
695

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

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

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

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

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

    
747
    rom_add_blob_fixed("prom", prom_buf, prom_size,
748
                       ENVP_ADDR + VIRT_TO_PHYS_ADDEND);
749

    
750
    return kernel_entry;
751
}
752

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

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

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

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

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

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

    
828

    
829
    cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
830

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

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

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

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

    
902
    /* Init internal devices */
903
    cpu_mips_irq_init_cpu(env);
904
    cpu_mips_clock_init(env);
905

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

    
910
    /* Northbridge */
911
    pci_bus = pci_gt64120_init(i8259);
912

    
913
    /* Southbridge */
914

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

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

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

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

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

    
959
    /* Network card */
960
    network_init();
961

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

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

    
979
static void mips_malta_machine_init(void)
980
{
981
    qemu_register_machine(&mips_malta_machine);
982
}
983

    
984
machine_init(mips_malta_machine_init);