Statistics
| Branch: | Revision:

root / hw / mips_malta.c @ 7d932dfd

History | View | Annotate | Download (32.2 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 "usb-uhci.h"
37
#include "vmware_vga.h"
38
#include "qemu-char.h"
39
#include "sysemu.h"
40
#include "audio/audio.h"
41
#include "boards.h"
42
#include "qemu-log.h"
43
#include "mips-bios.h"
44
#include "ide.h"
45
#include "loader.h"
46
#include "elf.h"
47
#include "mc146818rtc.h"
48

    
49
//#define DEBUG_BOARD_INIT
50

    
51
#define ENVP_ADDR                0x80002000l
52
#define ENVP_NB_ENTRIES                 16
53
#define ENVP_ENTRY_SIZE                 256
54

    
55
#define MAX_IDE_BUS 2
56

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

    
70
static PITState *pit;
71

    
72
static struct _loaderparams {
73
    int ram_size;
74
    const char *kernel_filename;
75
    const char *kernel_cmdline;
76
    const char *initrd_filename;
77
} loaderparams;
78

    
79
/* Malta FPGA */
80
static void malta_fpga_update_display(void *opaque)
81
{
82
    char leds_text[9];
83
    int i;
84
    MaltaFPGAState *s = opaque;
85

    
86
    for (i = 7 ; i >= 0 ; i--) {
87
        if (s->leds & (1 << i))
88
            leds_text[i] = '#';
89
        else
90
            leds_text[i] = ' ';
91
    }
92
    leds_text[8] = '\0';
93

    
94
    qemu_chr_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text);
95
    qemu_chr_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text);
96
}
97

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

    
108
//~ #define DEBUG
109

    
110
#if defined(DEBUG)
111
#  define logout(fmt, ...) fprintf(stderr, "MALTA\t%-24s" fmt, __func__, ## __VA_ARGS__)
112
#else
113
#  define logout(fmt, ...) ((void)0)
114
#endif
115

    
116
struct _eeprom24c0x_t {
117
  uint8_t tick;
118
  uint8_t address;
119
  uint8_t command;
120
  uint8_t ack;
121
  uint8_t scl;
122
  uint8_t sda;
123
  uint8_t data;
124
  //~ uint16_t size;
125
  uint8_t contents[256];
126
};
127

    
128
typedef struct _eeprom24c0x_t eeprom24c0x_t;
129

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

    
151
static uint8_t eeprom24c0x_read(void)
152
{
153
    logout("%u: scl = %u, sda = %u, data = 0x%02x\n",
154
        eeprom.tick, eeprom.scl, eeprom.sda, eeprom.data);
155
    return eeprom.sda;
156
}
157

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

    
216
static uint32_t malta_fpga_readl(void *opaque, target_phys_addr_t addr)
217
{
218
    MaltaFPGAState *s = opaque;
219
    uint32_t val = 0;
220
    uint32_t saddr;
221

    
222
    saddr = (addr & 0xfffff);
223

    
224
    switch (saddr) {
225

    
226
    /* SWITCH Register */
227
    case 0x00200:
228
        val = 0x00000000;                /* All switches closed */
229
        break;
230

    
231
    /* STATUS Register */
232
    case 0x00208:
233
#ifdef TARGET_WORDS_BIGENDIAN
234
        val = 0x00000012;
235
#else
236
        val = 0x00000010;
237
#endif
238
        break;
239

    
240
    /* JMPRS Register */
241
    case 0x00210:
242
        val = 0x00;
243
        break;
244

    
245
    /* LEDBAR Register */
246
    case 0x00408:
247
        val = s->leds;
248
        break;
249

    
250
    /* BRKRES Register */
251
    case 0x00508:
252
        val = s->brk;
253
        break;
254

    
255
    /* UART Registers are handled directly by the serial device */
256

    
257
    /* GPOUT Register */
258
    case 0x00a00:
259
        val = s->gpout;
260
        break;
261

    
262
    /* XXX: implement a real I2C controller */
263

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

    
273
    /* I2CINP Register */
274
    case 0x00b00:
275
        val = ((s->i2cin & ~1) | eeprom24c0x_read());
276
        break;
277

    
278
    /* I2COE Register */
279
    case 0x00b08:
280
        val = s->i2coe;
281
        break;
282

    
283
    /* I2COUT Register */
284
    case 0x00b10:
285
        val = s->i2cout;
286
        break;
287

    
288
    /* I2CSEL Register */
289
    case 0x00b18:
290
        val = s->i2csel;
291
        break;
292

    
293
    default:
294
#if 0
295
        printf ("malta_fpga_read: Bad register offset 0x" TARGET_FMT_lx "\n",
296
                addr);
297
#endif
298
        break;
299
    }
300
    return val;
301
}
302

    
303
static void malta_fpga_writel(void *opaque, target_phys_addr_t addr,
304
                              uint32_t val)
305
{
306
    MaltaFPGAState *s = opaque;
307
    uint32_t saddr;
308

    
309
    saddr = (addr & 0xfffff);
310

    
311
    switch (saddr) {
312

    
313
    /* SWITCH Register */
314
    case 0x00200:
315
        break;
316

    
317
    /* JMPRS Register */
318
    case 0x00210:
319
        break;
320

    
321
    /* LEDBAR Register */
322
    /* XXX: implement a 8-LED array */
323
    case 0x00408:
324
        s->leds = val & 0xff;
325
        break;
326

    
327
    /* ASCIIWORD Register */
328
    case 0x00410:
329
        snprintf(s->display_text, 9, "%08X", val);
330
        malta_fpga_update_display(s);
331
        break;
332

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

    
346
    /* SOFTRES Register */
347
    case 0x00500:
348
        if (val == 0x42)
349
            qemu_system_reset_request ();
350
        break;
351

    
352
    /* BRKRES Register */
353
    case 0x00508:
354
        s->brk = val & 0xff;
355
        break;
356

    
357
    /* UART Registers are handled directly by the serial device */
358

    
359
    /* GPOUT Register */
360
    case 0x00a00:
361
        s->gpout = val & 0xff;
362
        break;
363

    
364
    /* I2COE Register */
365
    case 0x00b08:
366
        s->i2coe = val & 0x03;
367
        break;
368

    
369
    /* I2COUT Register */
370
    case 0x00b10:
371
        eeprom24c0x_write(val & 0x02, val & 0x01);
372
        s->i2cout = val;
373
        break;
374

    
375
    /* I2CSEL Register */
376
    case 0x00b18:
377
        s->i2csel = val & 0x01;
378
        break;
379

    
380
    default:
381
#if 0
382
        printf ("malta_fpga_write: Bad register offset 0x" TARGET_FMT_lx "\n",
383
                addr);
384
#endif
385
        break;
386
    }
387
}
388

    
389
static CPUReadMemoryFunc * const malta_fpga_read[] = {
390
   malta_fpga_readl,
391
   malta_fpga_readl,
392
   malta_fpga_readl
393
};
394

    
395
static CPUWriteMemoryFunc * const malta_fpga_write[] = {
396
   malta_fpga_writel,
397
   malta_fpga_writel,
398
   malta_fpga_writel
399
};
400

    
401
static void malta_fpga_reset(void *opaque)
402
{
403
    MaltaFPGAState *s = opaque;
404

    
405
    s->leds   = 0x00;
406
    s->brk    = 0x0a;
407
    s->gpout  = 0x00;
408
    s->i2cin  = 0x3;
409
    s->i2coe  = 0x0;
410
    s->i2cout = 0x3;
411
    s->i2csel = 0x1;
412

    
413
    s->display_text[8] = '\0';
414
    snprintf(s->display_text, 9, "        ");
415
}
416

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

    
430
static MaltaFPGAState *malta_fpga_init(target_phys_addr_t base, qemu_irq uart_irq, CharDriverState *uart_chr)
431
{
432
    MaltaFPGAState *s;
433
    int malta;
434

    
435
    s = (MaltaFPGAState *)qemu_mallocz(sizeof(MaltaFPGAState));
436

    
437
    malta = cpu_register_io_memory(malta_fpga_read,
438
                                   malta_fpga_write, s);
439

    
440
    cpu_register_physical_memory(base, 0x900, malta);
441
    /* 0xa00 is less than a page, so will still get the right offsets.  */
442
    cpu_register_physical_memory(base + 0xa00, 0x100000 - 0xa00, malta);
443

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

    
446
#ifdef TARGET_WORDS_BIGENDIAN
447
    s->uart = serial_mm_init(base + 0x900, 3, uart_irq, 230400, uart_chr, 1, 1);
448
#else
449
    s->uart = serial_mm_init(base + 0x900, 3, uart_irq, 230400, uart_chr, 1, 0);
450
#endif
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_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, cpu_mips_kseg0_to_phys, NULL,
697
                 (uint64_t *)&kernel_entry, NULL, (uint64_t *)&kernel_high,
698
                 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%" PRIx64 " rd_size=%li %s",
735
                 cpu_mips_phys_to_kseg0(NULL, 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
                       cpu_mips_kseg0_to_phys(NULL, ENVP_ADDR));
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 bootloader 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 void cpu_request_exit(void *opaque, int irq, int level)
767
{
768
    CPUState *env = cpu_single_env;
769

    
770
    if (env && level) {
771
        cpu_exit(env);
772
    }
773
}
774

    
775
static
776
void mips_malta_init (ram_addr_t ram_size,
777
                      const char *boot_device,
778
                      const char *kernel_filename, const char *kernel_cmdline,
779
                      const char *initrd_filename, const char *cpu_model)
780
{
781
    char *filename;
782
    ram_addr_t ram_offset;
783
    ram_addr_t bios_offset;
784
    target_long bios_size;
785
    int64_t kernel_entry;
786
    PCIBus *pci_bus;
787
    ISADevice *isa_dev;
788
    CPUState *env;
789
    ISADevice *rtc_state;
790
    FDCtrl *floppy_controller;
791
    MaltaFPGAState *malta_fpga;
792
    qemu_irq *i8259;
793
    qemu_irq *cpu_exit_irq;
794
    int piix4_devfn;
795
    uint8_t *eeprom_buf;
796
    i2c_bus *smbus;
797
    int i;
798
    DriveInfo *dinfo;
799
    DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
800
    DriveInfo *fd[MAX_FD];
801
    int fl_idx = 0;
802
    int fl_sectors = 0;
803
    int be;
804

    
805
    /* Make sure the first 3 serial ports are associated with a device. */
806
    for(i = 0; i < 3; i++) {
807
        if (!serial_hds[i]) {
808
            char label[32];
809
            snprintf(label, sizeof(label), "serial%d", i);
810
            serial_hds[i] = qemu_chr_open(label, "null", NULL);
811
        }
812
    }
813

    
814
    /* init CPUs */
815
    if (cpu_model == NULL) {
816
#ifdef TARGET_MIPS64
817
        cpu_model = "20Kc";
818
#else
819
        cpu_model = "24Kf";
820
#endif
821
    }
822
    env = cpu_init(cpu_model);
823
    if (!env) {
824
        fprintf(stderr, "Unable to find CPU definition\n");
825
        exit(1);
826
    }
827
    qemu_register_reset(main_cpu_reset, env);
828

    
829
    /* allocate RAM */
830
    if (ram_size > (256 << 20)) {
831
        fprintf(stderr,
832
                "qemu: Too much memory for this machine: %d MB, maximum 256 MB\n",
833
                ((unsigned int)ram_size / (1 << 20)));
834
        exit(1);
835
    }
836
    ram_offset = qemu_ram_alloc(ram_size);
837
    bios_offset = qemu_ram_alloc(BIOS_SIZE);
838

    
839

    
840
    cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
841

    
842
    /* Map the bios at two physical locations, as on the real board. */
843
    cpu_register_physical_memory(0x1e000000LL,
844
                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
845
    cpu_register_physical_memory(0x1fc00000LL,
846
                                 BIOS_SIZE, bios_offset | IO_MEM_ROM);
847

    
848
#ifdef TARGET_WORDS_BIGENDIAN
849
    be = 1;
850
#else
851
    be = 0;
852
#endif
853
    /* FPGA */
854
    malta_fpga = malta_fpga_init(0x1f000000LL, env->irq[2], serial_hds[2]);
855

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

    
913
    /* Board ID = 0x420 (Malta Board with CoreLV)
914
       XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
915
       map to the board ID. */
916
    stl_phys(0x1fc00010LL, 0x00000420);
917

    
918
    /* Init internal devices */
919
    cpu_mips_irq_init_cpu(env);
920
    cpu_mips_clock_init(env);
921

    
922
    /* Interrupt controller */
923
    /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
924
    i8259 = i8259_init(env->irq[2]);
925

    
926
    /* Northbridge */
927
    pci_bus = pci_gt64120_init(i8259);
928

    
929
    /* Southbridge */
930

    
931
    if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
932
        fprintf(stderr, "qemu: too many IDE bus\n");
933
        exit(1);
934
    }
935

    
936
    for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
937
        hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
938
    }
939

    
940
    piix4_devfn = piix4_init(pci_bus, 80);
941
    isa_bus_irqs(i8259);
942
    pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);
943
    usb_uhci_piix4_init(pci_bus, piix4_devfn + 2);
944
    smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100, isa_reserve_irq(9),
945
                          NULL, NULL, 0);
946
    eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
947
    for (i = 0; i < 8; i++) {
948
        /* TODO: Populate SPD eeprom data.  */
949
        DeviceState *eeprom;
950
        eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");
951
        qdev_prop_set_uint8(eeprom, "address", 0x50 + i);
952
        qdev_prop_set_ptr(eeprom, "data", eeprom_buf + (i * 256));
953
        qdev_init_nofail(eeprom);
954
    }
955
    pit = pit_init(0x40, isa_reserve_irq(0));
956
    cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
957
    DMA_init(0, cpu_exit_irq);
958

    
959
    /* Super I/O */
960
    isa_dev = isa_create_simple("i8042");
961
 
962
    rtc_state = rtc_init(2000, NULL);
963
    serial_isa_init(0, serial_hds[0]);
964
    serial_isa_init(1, serial_hds[1]);
965
    if (parallel_hds[0])
966
        parallel_init(0, parallel_hds[0]);
967
    for(i = 0; i < MAX_FD; i++) {
968
        fd[i] = drive_get(IF_FLOPPY, 0, i);
969
    }
970
    floppy_controller = fdctrl_init_isa(fd);
971

    
972
    /* Sound card */
973
#ifdef HAS_AUDIO
974
    audio_init(pci_bus);
975
#endif
976

    
977
    /* Network card */
978
    network_init();
979

    
980
    /* Optional PCI video card */
981
    if (cirrus_vga_enabled) {
982
        pci_cirrus_vga_init(pci_bus);
983
    } else if (vmsvga_enabled) {
984
        pci_vmsvga_init(pci_bus);
985
    } else if (std_vga_enabled) {
986
        pci_vga_init(pci_bus, 0, 0);
987
    }
988
}
989

    
990
static QEMUMachine mips_malta_machine = {
991
    .name = "malta",
992
    .desc = "MIPS Malta Core LV",
993
    .init = mips_malta_init,
994
    .is_default = 1,
995
};
996

    
997
static void mips_malta_machine_init(void)
998
{
999
    qemu_register_machine(&mips_malta_machine);
1000
}
1001

    
1002
machine_init(mips_malta_machine_init);