hw: use ld_p/st_p instead of ld_raw/st_raw
[qemu/ar7.git] / hw / mips / mips_malta.c
blobf4a7d47129526f6762eccc47251c8cf3cd27f928
1 /*
2 * QEMU Malta board support
4 * Copyright (c) 2006 Aurelien Jarno
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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.
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 #include "qemu/host-utils.h"
51 #include "sysemu/qtest.h"
52 #include "qemu/error-report.h"
53 #include "hw/empty_slot.h"
55 //#define DEBUG_BOARD_INIT
57 #define ENVP_ADDR 0x80002000l
58 #define ENVP_NB_ENTRIES 16
59 #define ENVP_ENTRY_SIZE 256
61 /* Hardware addresses */
62 #define FLASH_ADDRESS 0x1e000000ULL
63 #define FPGA_ADDRESS 0x1f000000ULL
64 #define RESET_ADDRESS 0x1fc00000ULL
66 #define FLASH_SIZE 0x400000
68 #define MAX_IDE_BUS 2
70 typedef struct {
71 MemoryRegion iomem;
72 MemoryRegion iomem_lo; /* 0 - 0x900 */
73 MemoryRegion iomem_hi; /* 0xa00 - 0x100000 */
74 uint32_t leds;
75 uint32_t brk;
76 uint32_t gpout;
77 uint32_t i2cin;
78 uint32_t i2coe;
79 uint32_t i2cout;
80 uint32_t i2csel;
81 CharDriverState *display;
82 char display_text[9];
83 SerialState *uart;
84 } MaltaFPGAState;
86 #define TYPE_MIPS_MALTA "mips-malta"
87 #define MIPS_MALTA(obj) OBJECT_CHECK(MaltaState, (obj), TYPE_MIPS_MALTA)
89 typedef struct {
90 SysBusDevice parent_obj;
92 qemu_irq *i8259;
93 } MaltaState;
95 static ISADevice *pit;
97 static struct _loaderparams {
98 int ram_size;
99 const char *kernel_filename;
100 const char *kernel_cmdline;
101 const char *initrd_filename;
102 } loaderparams;
104 /* Malta FPGA */
105 static void malta_fpga_update_display(void *opaque)
107 char leds_text[9];
108 int i;
109 MaltaFPGAState *s = opaque;
111 for (i = 7 ; i >= 0 ; i--) {
112 if (s->leds & (1 << i))
113 leds_text[i] = '#';
114 else
115 leds_text[i] = ' ';
117 leds_text[8] = '\0';
119 qemu_chr_fe_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text);
120 qemu_chr_fe_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text);
124 * EEPROM 24C01 / 24C02 emulation.
126 * Emulation for serial EEPROMs:
127 * 24C01 - 1024 bit (128 x 8)
128 * 24C02 - 2048 bit (256 x 8)
130 * Typical device names include Microchip 24C02SC or SGS Thomson ST24C02.
133 //~ #define DEBUG
135 #if defined(DEBUG)
136 # define logout(fmt, ...) fprintf(stderr, "MALTA\t%-24s" fmt, __func__, ## __VA_ARGS__)
137 #else
138 # define logout(fmt, ...) ((void)0)
139 #endif
141 struct _eeprom24c0x_t {
142 uint8_t tick;
143 uint8_t address;
144 uint8_t command;
145 uint8_t ack;
146 uint8_t scl;
147 uint8_t sda;
148 uint8_t data;
149 //~ uint16_t size;
150 uint8_t contents[256];
153 typedef struct _eeprom24c0x_t eeprom24c0x_t;
155 static eeprom24c0x_t spd_eeprom = {
156 .contents = {
157 /* 00000000: */ 0x80,0x08,0xFF,0x0D,0x0A,0xFF,0x40,0x00,
158 /* 00000008: */ 0x01,0x75,0x54,0x00,0x82,0x08,0x00,0x01,
159 /* 00000010: */ 0x8F,0x04,0x02,0x01,0x01,0x00,0x00,0x00,
160 /* 00000018: */ 0x00,0x00,0x00,0x14,0x0F,0x14,0x2D,0xFF,
161 /* 00000020: */ 0x15,0x08,0x15,0x08,0x00,0x00,0x00,0x00,
162 /* 00000028: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
163 /* 00000030: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
164 /* 00000038: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x12,0xD0,
165 /* 00000040: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
166 /* 00000048: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
167 /* 00000050: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
168 /* 00000058: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
169 /* 00000060: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
170 /* 00000068: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
171 /* 00000070: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
172 /* 00000078: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x64,0xF4,
176 static void generate_eeprom_spd(uint8_t *eeprom, ram_addr_t ram_size)
178 enum { SDR = 0x4, DDR2 = 0x8 } type;
179 uint8_t *spd = spd_eeprom.contents;
180 uint8_t nbanks = 0;
181 uint16_t density = 0;
182 int i;
184 /* work in terms of MB */
185 ram_size >>= 20;
187 while ((ram_size >= 4) && (nbanks <= 2)) {
188 int sz_log2 = MIN(31 - clz32(ram_size), 14);
189 nbanks++;
190 density |= 1 << (sz_log2 - 2);
191 ram_size -= 1 << sz_log2;
194 /* split to 2 banks if possible */
195 if ((nbanks == 1) && (density > 1)) {
196 nbanks++;
197 density >>= 1;
200 if (density & 0xff00) {
201 density = (density & 0xe0) | ((density >> 8) & 0x1f);
202 type = DDR2;
203 } else if (!(density & 0x1f)) {
204 type = DDR2;
205 } else {
206 type = SDR;
209 if (ram_size) {
210 fprintf(stderr, "Warning: SPD cannot represent final %dMB"
211 " of SDRAM\n", (int)ram_size);
214 /* fill in SPD memory information */
215 spd[2] = type;
216 spd[5] = nbanks;
217 spd[31] = density;
219 /* checksum */
220 spd[63] = 0;
221 for (i = 0; i < 63; i++) {
222 spd[63] += spd[i];
225 /* copy for SMBUS */
226 memcpy(eeprom, spd, sizeof(spd_eeprom.contents));
229 static void generate_eeprom_serial(uint8_t *eeprom)
231 int i, pos = 0;
232 uint8_t mac[6] = { 0x00 };
233 uint8_t sn[5] = { 0x01, 0x23, 0x45, 0x67, 0x89 };
235 /* version */
236 eeprom[pos++] = 0x01;
238 /* count */
239 eeprom[pos++] = 0x02;
241 /* MAC address */
242 eeprom[pos++] = 0x01; /* MAC */
243 eeprom[pos++] = 0x06; /* length */
244 memcpy(&eeprom[pos], mac, sizeof(mac));
245 pos += sizeof(mac);
247 /* serial number */
248 eeprom[pos++] = 0x02; /* serial */
249 eeprom[pos++] = 0x05; /* length */
250 memcpy(&eeprom[pos], sn, sizeof(sn));
251 pos += sizeof(sn);
253 /* checksum */
254 eeprom[pos] = 0;
255 for (i = 0; i < pos; i++) {
256 eeprom[pos] += eeprom[i];
260 static uint8_t eeprom24c0x_read(eeprom24c0x_t *eeprom)
262 logout("%u: scl = %u, sda = %u, data = 0x%02x\n",
263 eeprom->tick, eeprom->scl, eeprom->sda, eeprom->data);
264 return eeprom->sda;
267 static void eeprom24c0x_write(eeprom24c0x_t *eeprom, int scl, int sda)
269 if (eeprom->scl && scl && (eeprom->sda != sda)) {
270 logout("%u: scl = %u->%u, sda = %u->%u i2c %s\n",
271 eeprom->tick, eeprom->scl, scl, eeprom->sda, sda,
272 sda ? "stop" : "start");
273 if (!sda) {
274 eeprom->tick = 1;
275 eeprom->command = 0;
277 } else if (eeprom->tick == 0 && !eeprom->ack) {
278 /* Waiting for start. */
279 logout("%u: scl = %u->%u, sda = %u->%u wait for i2c start\n",
280 eeprom->tick, eeprom->scl, scl, eeprom->sda, sda);
281 } else if (!eeprom->scl && scl) {
282 logout("%u: scl = %u->%u, sda = %u->%u trigger bit\n",
283 eeprom->tick, eeprom->scl, scl, eeprom->sda, sda);
284 if (eeprom->ack) {
285 logout("\ti2c ack bit = 0\n");
286 sda = 0;
287 eeprom->ack = 0;
288 } else if (eeprom->sda == sda) {
289 uint8_t bit = (sda != 0);
290 logout("\ti2c bit = %d\n", bit);
291 if (eeprom->tick < 9) {
292 eeprom->command <<= 1;
293 eeprom->command += bit;
294 eeprom->tick++;
295 if (eeprom->tick == 9) {
296 logout("\tcommand 0x%04x, %s\n", eeprom->command,
297 bit ? "read" : "write");
298 eeprom->ack = 1;
300 } else if (eeprom->tick < 17) {
301 if (eeprom->command & 1) {
302 sda = ((eeprom->data & 0x80) != 0);
304 eeprom->address <<= 1;
305 eeprom->address += bit;
306 eeprom->tick++;
307 eeprom->data <<= 1;
308 if (eeprom->tick == 17) {
309 eeprom->data = eeprom->contents[eeprom->address];
310 logout("\taddress 0x%04x, data 0x%02x\n",
311 eeprom->address, eeprom->data);
312 eeprom->ack = 1;
313 eeprom->tick = 0;
315 } else if (eeprom->tick >= 17) {
316 sda = 0;
318 } else {
319 logout("\tsda changed with raising scl\n");
321 } else {
322 logout("%u: scl = %u->%u, sda = %u->%u\n", eeprom->tick, eeprom->scl,
323 scl, eeprom->sda, sda);
325 eeprom->scl = scl;
326 eeprom->sda = sda;
329 static uint64_t malta_fpga_read(void *opaque, hwaddr addr,
330 unsigned size)
332 MaltaFPGAState *s = opaque;
333 uint32_t val = 0;
334 uint32_t saddr;
336 saddr = (addr & 0xfffff);
338 switch (saddr) {
340 /* SWITCH Register */
341 case 0x00200:
342 val = 0x00000000; /* All switches closed */
343 break;
345 /* STATUS Register */
346 case 0x00208:
347 #ifdef TARGET_WORDS_BIGENDIAN
348 val = 0x00000012;
349 #else
350 val = 0x00000010;
351 #endif
352 break;
354 /* JMPRS Register */
355 case 0x00210:
356 val = 0x00;
357 break;
359 /* LEDBAR Register */
360 case 0x00408:
361 val = s->leds;
362 break;
364 /* BRKRES Register */
365 case 0x00508:
366 val = s->brk;
367 break;
369 /* UART Registers are handled directly by the serial device */
371 /* GPOUT Register */
372 case 0x00a00:
373 val = s->gpout;
374 break;
376 /* XXX: implement a real I2C controller */
378 /* GPINP Register */
379 case 0x00a08:
380 /* IN = OUT until a real I2C control is implemented */
381 if (s->i2csel)
382 val = s->i2cout;
383 else
384 val = 0x00;
385 break;
387 /* I2CINP Register */
388 case 0x00b00:
389 val = ((s->i2cin & ~1) | eeprom24c0x_read(&spd_eeprom));
390 break;
392 /* I2COE Register */
393 case 0x00b08:
394 val = s->i2coe;
395 break;
397 /* I2COUT Register */
398 case 0x00b10:
399 val = s->i2cout;
400 break;
402 /* I2CSEL Register */
403 case 0x00b18:
404 val = s->i2csel;
405 break;
407 default:
408 #if 0
409 printf ("malta_fpga_read: Bad register offset 0x" TARGET_FMT_lx "\n",
410 addr);
411 #endif
412 break;
414 return val;
417 static void malta_fpga_write(void *opaque, hwaddr addr,
418 uint64_t val, unsigned size)
420 MaltaFPGAState *s = opaque;
421 uint32_t saddr;
423 saddr = (addr & 0xfffff);
425 switch (saddr) {
427 /* SWITCH Register */
428 case 0x00200:
429 break;
431 /* JMPRS Register */
432 case 0x00210:
433 break;
435 /* LEDBAR Register */
436 case 0x00408:
437 s->leds = val & 0xff;
438 malta_fpga_update_display(s);
439 break;
441 /* ASCIIWORD Register */
442 case 0x00410:
443 snprintf(s->display_text, 9, "%08X", (uint32_t)val);
444 malta_fpga_update_display(s);
445 break;
447 /* ASCIIPOS0 to ASCIIPOS7 Registers */
448 case 0x00418:
449 case 0x00420:
450 case 0x00428:
451 case 0x00430:
452 case 0x00438:
453 case 0x00440:
454 case 0x00448:
455 case 0x00450:
456 s->display_text[(saddr - 0x00418) >> 3] = (char) val;
457 malta_fpga_update_display(s);
458 break;
460 /* SOFTRES Register */
461 case 0x00500:
462 if (val == 0x42)
463 qemu_system_reset_request ();
464 break;
466 /* BRKRES Register */
467 case 0x00508:
468 s->brk = val & 0xff;
469 break;
471 /* UART Registers are handled directly by the serial device */
473 /* GPOUT Register */
474 case 0x00a00:
475 s->gpout = val & 0xff;
476 break;
478 /* I2COE Register */
479 case 0x00b08:
480 s->i2coe = val & 0x03;
481 break;
483 /* I2COUT Register */
484 case 0x00b10:
485 eeprom24c0x_write(&spd_eeprom, val & 0x02, val & 0x01);
486 s->i2cout = val;
487 break;
489 /* I2CSEL Register */
490 case 0x00b18:
491 s->i2csel = val & 0x01;
492 break;
494 default:
495 #if 0
496 printf ("malta_fpga_write: Bad register offset 0x" TARGET_FMT_lx "\n",
497 addr);
498 #endif
499 break;
503 static const MemoryRegionOps malta_fpga_ops = {
504 .read = malta_fpga_read,
505 .write = malta_fpga_write,
506 .endianness = DEVICE_NATIVE_ENDIAN,
509 static void malta_fpga_reset(void *opaque)
511 MaltaFPGAState *s = opaque;
513 s->leds = 0x00;
514 s->brk = 0x0a;
515 s->gpout = 0x00;
516 s->i2cin = 0x3;
517 s->i2coe = 0x0;
518 s->i2cout = 0x3;
519 s->i2csel = 0x1;
521 s->display_text[8] = '\0';
522 snprintf(s->display_text, 9, " ");
525 static void malta_fpga_led_init(CharDriverState *chr)
527 qemu_chr_fe_printf(chr, "\e[HMalta LEDBAR\r\n");
528 qemu_chr_fe_printf(chr, "+--------+\r\n");
529 qemu_chr_fe_printf(chr, "+ +\r\n");
530 qemu_chr_fe_printf(chr, "+--------+\r\n");
531 qemu_chr_fe_printf(chr, "\n");
532 qemu_chr_fe_printf(chr, "Malta ASCII\r\n");
533 qemu_chr_fe_printf(chr, "+--------+\r\n");
534 qemu_chr_fe_printf(chr, "+ +\r\n");
535 qemu_chr_fe_printf(chr, "+--------+\r\n");
538 static MaltaFPGAState *malta_fpga_init(MemoryRegion *address_space,
539 hwaddr base, qemu_irq uart_irq, CharDriverState *uart_chr)
541 MaltaFPGAState *s;
543 s = (MaltaFPGAState *)g_malloc0(sizeof(MaltaFPGAState));
545 memory_region_init_io(&s->iomem, NULL, &malta_fpga_ops, s,
546 "malta-fpga", 0x100000);
547 memory_region_init_alias(&s->iomem_lo, NULL, "malta-fpga",
548 &s->iomem, 0, 0x900);
549 memory_region_init_alias(&s->iomem_hi, NULL, "malta-fpga",
550 &s->iomem, 0xa00, 0x10000-0xa00);
552 memory_region_add_subregion(address_space, base, &s->iomem_lo);
553 memory_region_add_subregion(address_space, base + 0xa00, &s->iomem_hi);
555 s->display = qemu_chr_new("fpga", "vc:320x200", malta_fpga_led_init);
557 s->uart = serial_mm_init(address_space, base + 0x900, 3, uart_irq,
558 230400, uart_chr, DEVICE_NATIVE_ENDIAN);
560 malta_fpga_reset(s);
561 qemu_register_reset(malta_fpga_reset, s);
563 return s;
566 /* Network support */
567 static void network_init(PCIBus *pci_bus)
569 int i;
571 for(i = 0; i < nb_nics; i++) {
572 NICInfo *nd = &nd_table[i];
573 const char *default_devaddr = NULL;
575 if (i == 0 && (!nd->model || strcmp(nd->model, "pcnet") == 0))
576 /* The malta board has a PCNet card using PCI SLOT 11 */
577 default_devaddr = "0b";
579 pci_nic_init_nofail(nd, pci_bus, "pcnet", default_devaddr);
583 /* ROM and pseudo bootloader
585 The following code implements a very very simple bootloader. It first
586 loads the registers a0 to a3 to the values expected by the OS, and
587 then jump at the kernel address.
589 The bootloader should pass the locations of the kernel arguments and
590 environment variables tables. Those tables contain the 32-bit address
591 of NULL terminated strings. The environment variables table should be
592 terminated by a NULL address.
594 For a simpler implementation, the number of kernel arguments is fixed
595 to two (the name of the kernel and the command line), and the two
596 tables are actually the same one.
598 The registers a0 to a3 should contain the following values:
599 a0 - number of kernel arguments
600 a1 - 32-bit address of the kernel arguments table
601 a2 - 32-bit address of the environment variables table
602 a3 - RAM size in bytes
605 static void write_bootloader (CPUMIPSState *env, uint8_t *base,
606 int64_t kernel_entry)
608 uint32_t *p;
610 /* Small bootloader */
611 p = (uint32_t *)base;
612 stl_p(p++, 0x0bf00160); /* j 0x1fc00580 */
613 stl_p(p++, 0x00000000); /* nop */
615 /* YAMON service vector */
616 stl_p(base + 0x500, 0xbfc00580); /* start: */
617 stl_p(base + 0x504, 0xbfc0083c); /* print_count: */
618 stl_p(base + 0x520, 0xbfc00580); /* start: */
619 stl_p(base + 0x52c, 0xbfc00800); /* flush_cache: */
620 stl_p(base + 0x534, 0xbfc00808); /* print: */
621 stl_p(base + 0x538, 0xbfc00800); /* reg_cpu_isr: */
622 stl_p(base + 0x53c, 0xbfc00800); /* unred_cpu_isr: */
623 stl_p(base + 0x540, 0xbfc00800); /* reg_ic_isr: */
624 stl_p(base + 0x544, 0xbfc00800); /* unred_ic_isr: */
625 stl_p(base + 0x548, 0xbfc00800); /* reg_esr: */
626 stl_p(base + 0x54c, 0xbfc00800); /* unreg_esr: */
627 stl_p(base + 0x550, 0xbfc00800); /* getchar: */
628 stl_p(base + 0x554, 0xbfc00800); /* syscon_read: */
631 /* Second part of the bootloader */
632 p = (uint32_t *) (base + 0x580);
633 stl_p(p++, 0x24040002); /* addiu a0, zero, 2 */
634 stl_p(p++, 0x3c1d0000 | (((ENVP_ADDR - 64) >> 16) & 0xffff)); /* lui sp, high(ENVP_ADDR) */
635 stl_p(p++, 0x37bd0000 | ((ENVP_ADDR - 64) & 0xffff)); /* ori sp, sp, low(ENVP_ADDR) */
636 stl_p(p++, 0x3c050000 | ((ENVP_ADDR >> 16) & 0xffff)); /* lui a1, high(ENVP_ADDR) */
637 stl_p(p++, 0x34a50000 | (ENVP_ADDR & 0xffff)); /* ori a1, a1, low(ENVP_ADDR) */
638 stl_p(p++, 0x3c060000 | (((ENVP_ADDR + 8) >> 16) & 0xffff)); /* lui a2, high(ENVP_ADDR + 8) */
639 stl_p(p++, 0x34c60000 | ((ENVP_ADDR + 8) & 0xffff)); /* ori a2, a2, low(ENVP_ADDR + 8) */
640 stl_p(p++, 0x3c070000 | (loaderparams.ram_size >> 16)); /* lui a3, high(ram_size) */
641 stl_p(p++, 0x34e70000 | (loaderparams.ram_size & 0xffff)); /* ori a3, a3, low(ram_size) */
643 /* Load BAR registers as done by YAMON */
644 stl_p(p++, 0x3c09b400); /* lui t1, 0xb400 */
646 #ifdef TARGET_WORDS_BIGENDIAN
647 stl_p(p++, 0x3c08df00); /* lui t0, 0xdf00 */
648 #else
649 stl_p(p++, 0x340800df); /* ori t0, r0, 0x00df */
650 #endif
651 stl_p(p++, 0xad280068); /* sw t0, 0x0068(t1) */
653 stl_p(p++, 0x3c09bbe0); /* lui t1, 0xbbe0 */
655 #ifdef TARGET_WORDS_BIGENDIAN
656 stl_p(p++, 0x3c08c000); /* lui t0, 0xc000 */
657 #else
658 stl_p(p++, 0x340800c0); /* ori t0, r0, 0x00c0 */
659 #endif
660 stl_p(p++, 0xad280048); /* sw t0, 0x0048(t1) */
661 #ifdef TARGET_WORDS_BIGENDIAN
662 stl_p(p++, 0x3c084000); /* lui t0, 0x4000 */
663 #else
664 stl_p(p++, 0x34080040); /* ori t0, r0, 0x0040 */
665 #endif
666 stl_p(p++, 0xad280050); /* sw t0, 0x0050(t1) */
668 #ifdef TARGET_WORDS_BIGENDIAN
669 stl_p(p++, 0x3c088000); /* lui t0, 0x8000 */
670 #else
671 stl_p(p++, 0x34080080); /* ori t0, r0, 0x0080 */
672 #endif
673 stl_p(p++, 0xad280058); /* sw t0, 0x0058(t1) */
674 #ifdef TARGET_WORDS_BIGENDIAN
675 stl_p(p++, 0x3c083f00); /* lui t0, 0x3f00 */
676 #else
677 stl_p(p++, 0x3408003f); /* ori t0, r0, 0x003f */
678 #endif
679 stl_p(p++, 0xad280060); /* sw t0, 0x0060(t1) */
681 #ifdef TARGET_WORDS_BIGENDIAN
682 stl_p(p++, 0x3c08c100); /* lui t0, 0xc100 */
683 #else
684 stl_p(p++, 0x340800c1); /* ori t0, r0, 0x00c1 */
685 #endif
686 stl_p(p++, 0xad280080); /* sw t0, 0x0080(t1) */
687 #ifdef TARGET_WORDS_BIGENDIAN
688 stl_p(p++, 0x3c085e00); /* lui t0, 0x5e00 */
689 #else
690 stl_p(p++, 0x3408005e); /* ori t0, r0, 0x005e */
691 #endif
692 stl_p(p++, 0xad280088); /* sw t0, 0x0088(t1) */
694 /* Jump to kernel code */
695 stl_p(p++, 0x3c1f0000 | ((kernel_entry >> 16) & 0xffff)); /* lui ra, high(kernel_entry) */
696 stl_p(p++, 0x37ff0000 | (kernel_entry & 0xffff)); /* ori ra, ra, low(kernel_entry) */
697 stl_p(p++, 0x03e00008); /* jr ra */
698 stl_p(p++, 0x00000000); /* nop */
700 /* YAMON subroutines */
701 p = (uint32_t *) (base + 0x800);
702 stl_p(p++, 0x03e00008); /* jr ra */
703 stl_p(p++, 0x24020000); /* li v0,0 */
704 /* 808 YAMON print */
705 stl_p(p++, 0x03e06821); /* move t5,ra */
706 stl_p(p++, 0x00805821); /* move t3,a0 */
707 stl_p(p++, 0x00a05021); /* move t2,a1 */
708 stl_p(p++, 0x91440000); /* lbu a0,0(t2) */
709 stl_p(p++, 0x254a0001); /* addiu t2,t2,1 */
710 stl_p(p++, 0x10800005); /* beqz a0,834 */
711 stl_p(p++, 0x00000000); /* nop */
712 stl_p(p++, 0x0ff0021c); /* jal 870 */
713 stl_p(p++, 0x00000000); /* nop */
714 stl_p(p++, 0x08000205); /* j 814 */
715 stl_p(p++, 0x00000000); /* nop */
716 stl_p(p++, 0x01a00008); /* jr t5 */
717 stl_p(p++, 0x01602021); /* move a0,t3 */
718 /* 0x83c YAMON print_count */
719 stl_p(p++, 0x03e06821); /* move t5,ra */
720 stl_p(p++, 0x00805821); /* move t3,a0 */
721 stl_p(p++, 0x00a05021); /* move t2,a1 */
722 stl_p(p++, 0x00c06021); /* move t4,a2 */
723 stl_p(p++, 0x91440000); /* lbu a0,0(t2) */
724 stl_p(p++, 0x0ff0021c); /* jal 870 */
725 stl_p(p++, 0x00000000); /* nop */
726 stl_p(p++, 0x254a0001); /* addiu t2,t2,1 */
727 stl_p(p++, 0x258cffff); /* addiu t4,t4,-1 */
728 stl_p(p++, 0x1580fffa); /* bnez t4,84c */
729 stl_p(p++, 0x00000000); /* nop */
730 stl_p(p++, 0x01a00008); /* jr t5 */
731 stl_p(p++, 0x01602021); /* move a0,t3 */
732 /* 0x870 */
733 stl_p(p++, 0x3c08b800); /* lui t0,0xb400 */
734 stl_p(p++, 0x350803f8); /* ori t0,t0,0x3f8 */
735 stl_p(p++, 0x91090005); /* lbu t1,5(t0) */
736 stl_p(p++, 0x00000000); /* nop */
737 stl_p(p++, 0x31290040); /* andi t1,t1,0x40 */
738 stl_p(p++, 0x1120fffc); /* beqz t1,878 <outch+0x8> */
739 stl_p(p++, 0x00000000); /* nop */
740 stl_p(p++, 0x03e00008); /* jr ra */
741 stl_p(p++, 0xa1040000); /* sb a0,0(t0) */
745 static void GCC_FMT_ATTR(3, 4) prom_set(uint32_t* prom_buf, int index,
746 const char *string, ...)
748 va_list ap;
749 int32_t table_addr;
751 if (index >= ENVP_NB_ENTRIES)
752 return;
754 if (string == NULL) {
755 prom_buf[index] = 0;
756 return;
759 table_addr = sizeof(int32_t) * ENVP_NB_ENTRIES + index * ENVP_ENTRY_SIZE;
760 prom_buf[index] = tswap32(ENVP_ADDR + table_addr);
762 va_start(ap, string);
763 vsnprintf((char *)prom_buf + table_addr, ENVP_ENTRY_SIZE, string, ap);
764 va_end(ap);
767 /* Kernel */
768 static int64_t load_kernel (void)
770 int64_t kernel_entry, kernel_high;
771 long initrd_size;
772 ram_addr_t initrd_offset;
773 int big_endian;
774 uint32_t *prom_buf;
775 long prom_size;
776 int prom_index = 0;
778 #ifdef TARGET_WORDS_BIGENDIAN
779 big_endian = 1;
780 #else
781 big_endian = 0;
782 #endif
784 if (load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_to_phys, NULL,
785 (uint64_t *)&kernel_entry, NULL, (uint64_t *)&kernel_high,
786 big_endian, ELF_MACHINE, 1) < 0) {
787 fprintf(stderr, "qemu: could not load kernel '%s'\n",
788 loaderparams.kernel_filename);
789 exit(1);
792 /* load initrd */
793 initrd_size = 0;
794 initrd_offset = 0;
795 if (loaderparams.initrd_filename) {
796 initrd_size = get_image_size (loaderparams.initrd_filename);
797 if (initrd_size > 0) {
798 initrd_offset = (kernel_high + ~INITRD_PAGE_MASK) & INITRD_PAGE_MASK;
799 if (initrd_offset + initrd_size > ram_size) {
800 fprintf(stderr,
801 "qemu: memory too small for initial ram disk '%s'\n",
802 loaderparams.initrd_filename);
803 exit(1);
805 initrd_size = load_image_targphys(loaderparams.initrd_filename,
806 initrd_offset,
807 ram_size - initrd_offset);
809 if (initrd_size == (target_ulong) -1) {
810 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
811 loaderparams.initrd_filename);
812 exit(1);
816 /* Setup prom parameters. */
817 prom_size = ENVP_NB_ENTRIES * (sizeof(int32_t) + ENVP_ENTRY_SIZE);
818 prom_buf = g_malloc(prom_size);
820 prom_set(prom_buf, prom_index++, "%s", loaderparams.kernel_filename);
821 if (initrd_size > 0) {
822 prom_set(prom_buf, prom_index++, "rd_start=0x%" PRIx64 " rd_size=%li %s",
823 cpu_mips_phys_to_kseg0(NULL, initrd_offset), initrd_size,
824 loaderparams.kernel_cmdline);
825 } else {
826 prom_set(prom_buf, prom_index++, "%s", loaderparams.kernel_cmdline);
829 prom_set(prom_buf, prom_index++, "memsize");
830 prom_set(prom_buf, prom_index++, "%i",
831 MIN(loaderparams.ram_size, 256 << 20));
832 prom_set(prom_buf, prom_index++, "modetty0");
833 prom_set(prom_buf, prom_index++, "38400n8r");
834 prom_set(prom_buf, prom_index++, NULL);
836 rom_add_blob_fixed("prom", prom_buf, prom_size,
837 cpu_mips_kseg0_to_phys(NULL, ENVP_ADDR));
839 return kernel_entry;
842 static void malta_mips_config(MIPSCPU *cpu)
844 CPUMIPSState *env = &cpu->env;
845 CPUState *cs = CPU(cpu);
847 env->mvp->CP0_MVPConf0 |= ((smp_cpus - 1) << CP0MVPC0_PVPE) |
848 ((smp_cpus * cs->nr_threads - 1) << CP0MVPC0_PTC);
851 static void main_cpu_reset(void *opaque)
853 MIPSCPU *cpu = opaque;
854 CPUMIPSState *env = &cpu->env;
856 cpu_reset(CPU(cpu));
858 /* The bootloader does not need to be rewritten as it is located in a
859 read only location. The kernel location and the arguments table
860 location does not change. */
861 if (loaderparams.kernel_filename) {
862 env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
865 malta_mips_config(cpu);
868 static void cpu_request_exit(void *opaque, int irq, int level)
870 CPUState *cpu = current_cpu;
872 if (cpu && level) {
873 cpu_exit(cpu);
877 static
878 void mips_malta_init(MachineState *machine)
880 ram_addr_t ram_size = machine->ram_size;
881 const char *cpu_model = machine->cpu_model;
882 const char *kernel_filename = machine->kernel_filename;
883 const char *kernel_cmdline = machine->kernel_cmdline;
884 const char *initrd_filename = machine->initrd_filename;
885 char *filename;
886 pflash_t *fl;
887 MemoryRegion *system_memory = get_system_memory();
888 MemoryRegion *ram_high = g_new(MemoryRegion, 1);
889 MemoryRegion *ram_low_preio = g_new(MemoryRegion, 1);
890 MemoryRegion *ram_low_postio;
891 MemoryRegion *bios, *bios_copy = g_new(MemoryRegion, 1);
892 target_long bios_size = FLASH_SIZE;
893 const size_t smbus_eeprom_size = 8 * 256;
894 uint8_t *smbus_eeprom_buf = g_malloc0(smbus_eeprom_size);
895 int64_t kernel_entry;
896 PCIBus *pci_bus;
897 ISABus *isa_bus;
898 MIPSCPU *cpu;
899 CPUMIPSState *env;
900 qemu_irq *isa_irq;
901 qemu_irq *cpu_exit_irq;
902 int piix4_devfn;
903 I2CBus *smbus;
904 int i;
905 DriveInfo *dinfo;
906 DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
907 DriveInfo *fd[MAX_FD];
908 int fl_idx = 0;
909 int fl_sectors = bios_size >> 16;
910 int be;
912 DeviceState *dev = qdev_create(NULL, TYPE_MIPS_MALTA);
913 MaltaState *s = MIPS_MALTA(dev);
915 /* The whole address space decoded by the GT-64120A doesn't generate
916 exception when accessing invalid memory. Create an empty slot to
917 emulate this feature. */
918 empty_slot_init(0, 0x20000000);
920 qdev_init_nofail(dev);
922 /* Make sure the first 3 serial ports are associated with a device. */
923 for(i = 0; i < 3; i++) {
924 if (!serial_hds[i]) {
925 char label[32];
926 snprintf(label, sizeof(label), "serial%d", i);
927 serial_hds[i] = qemu_chr_new(label, "null", NULL);
931 /* init CPUs */
932 if (cpu_model == NULL) {
933 #ifdef TARGET_MIPS64
934 cpu_model = "20Kc";
935 #else
936 cpu_model = "24Kf";
937 #endif
940 for (i = 0; i < smp_cpus; i++) {
941 cpu = cpu_mips_init(cpu_model);
942 if (cpu == NULL) {
943 fprintf(stderr, "Unable to find CPU definition\n");
944 exit(1);
946 env = &cpu->env;
948 /* Init internal devices */
949 cpu_mips_irq_init_cpu(env);
950 cpu_mips_clock_init(env);
951 qemu_register_reset(main_cpu_reset, cpu);
953 cpu = MIPS_CPU(first_cpu);
954 env = &cpu->env;
956 /* allocate RAM */
957 if (ram_size > (2048u << 20)) {
958 fprintf(stderr,
959 "qemu: Too much memory for this machine: %d MB, maximum 2048 MB\n",
960 ((unsigned int)ram_size / (1 << 20)));
961 exit(1);
964 /* register RAM at high address where it is undisturbed by IO */
965 memory_region_init_ram(ram_high, NULL, "mips_malta.ram", ram_size);
966 vmstate_register_ram_global(ram_high);
967 memory_region_add_subregion(system_memory, 0x80000000, ram_high);
969 /* alias for pre IO hole access */
970 memory_region_init_alias(ram_low_preio, NULL, "mips_malta_low_preio.ram",
971 ram_high, 0, MIN(ram_size, (256 << 20)));
972 memory_region_add_subregion(system_memory, 0, ram_low_preio);
974 /* alias for post IO hole access, if there is enough RAM */
975 if (ram_size > (512 << 20)) {
976 ram_low_postio = g_new(MemoryRegion, 1);
977 memory_region_init_alias(ram_low_postio, NULL,
978 "mips_malta_low_postio.ram",
979 ram_high, 512 << 20,
980 ram_size - (512 << 20));
981 memory_region_add_subregion(system_memory, 512 << 20, ram_low_postio);
984 /* generate SPD EEPROM data */
985 generate_eeprom_spd(&smbus_eeprom_buf[0 * 256], ram_size);
986 generate_eeprom_serial(&smbus_eeprom_buf[6 * 256]);
988 #ifdef TARGET_WORDS_BIGENDIAN
989 be = 1;
990 #else
991 be = 0;
992 #endif
993 /* FPGA */
994 /* The CBUS UART is attached to the MIPS CPU INT2 pin, ie interrupt 4 */
995 malta_fpga_init(system_memory, FPGA_ADDRESS, env->irq[4], serial_hds[2]);
997 /* Load firmware in flash / BIOS. */
998 dinfo = drive_get(IF_PFLASH, 0, fl_idx);
999 #ifdef DEBUG_BOARD_INIT
1000 if (dinfo) {
1001 printf("Register parallel flash %d size " TARGET_FMT_lx " at "
1002 "addr %08llx '%s' %x\n",
1003 fl_idx, bios_size, FLASH_ADDRESS,
1004 bdrv_get_device_name(dinfo->bdrv), fl_sectors);
1006 #endif
1007 fl = pflash_cfi01_register(FLASH_ADDRESS, NULL, "mips_malta.bios",
1008 BIOS_SIZE, dinfo ? dinfo->bdrv : NULL,
1009 65536, fl_sectors,
1010 4, 0x0000, 0x0000, 0x0000, 0x0000, be);
1011 bios = pflash_cfi01_get_memory(fl);
1012 fl_idx++;
1013 if (kernel_filename) {
1014 /* Write a small bootloader to the flash location. */
1015 loaderparams.ram_size = MIN(ram_size, 256 << 20);
1016 loaderparams.kernel_filename = kernel_filename;
1017 loaderparams.kernel_cmdline = kernel_cmdline;
1018 loaderparams.initrd_filename = initrd_filename;
1019 kernel_entry = load_kernel();
1020 write_bootloader(env, memory_region_get_ram_ptr(bios), kernel_entry);
1021 } else {
1022 /* Load firmware from flash. */
1023 if (!dinfo) {
1024 /* Load a BIOS image. */
1025 if (bios_name == NULL) {
1026 bios_name = BIOS_FILENAME;
1028 filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
1029 if (filename) {
1030 bios_size = load_image_targphys(filename, FLASH_ADDRESS,
1031 BIOS_SIZE);
1032 g_free(filename);
1033 } else {
1034 bios_size = -1;
1036 if ((bios_size < 0 || bios_size > BIOS_SIZE) &&
1037 !kernel_filename && !qtest_enabled()) {
1038 error_report("Could not load MIPS bios '%s', and no "
1039 "-kernel argument was specified", bios_name);
1040 exit(1);
1043 /* In little endian mode the 32bit words in the bios are swapped,
1044 a neat trick which allows bi-endian firmware. */
1045 #ifndef TARGET_WORDS_BIGENDIAN
1047 uint32_t *end, *addr = rom_ptr(FLASH_ADDRESS);
1048 if (!addr) {
1049 addr = memory_region_get_ram_ptr(bios);
1051 end = (void *)addr + MIN(bios_size, 0x3e0000);
1052 while (addr < end) {
1053 bswap32s(addr);
1054 addr++;
1057 #endif
1061 * Map the BIOS at a 2nd physical location, as on the real board.
1062 * Copy it so that we can patch in the MIPS revision, which cannot be
1063 * handled by an overlapping region as the resulting ROM code subpage
1064 * regions are not executable.
1066 memory_region_init_ram(bios_copy, NULL, "bios.1fc", BIOS_SIZE);
1067 if (!rom_copy(memory_region_get_ram_ptr(bios_copy),
1068 FLASH_ADDRESS, BIOS_SIZE)) {
1069 memcpy(memory_region_get_ram_ptr(bios_copy),
1070 memory_region_get_ram_ptr(bios), BIOS_SIZE);
1072 memory_region_set_readonly(bios_copy, true);
1073 memory_region_add_subregion(system_memory, RESET_ADDRESS, bios_copy);
1075 /* Board ID = 0x420 (Malta Board with CoreLV) */
1076 stl_p(memory_region_get_ram_ptr(bios_copy) + 0x10, 0x00000420);
1078 /* Init internal devices */
1079 cpu_mips_irq_init_cpu(env);
1080 cpu_mips_clock_init(env);
1083 * We have a circular dependency problem: pci_bus depends on isa_irq,
1084 * isa_irq is provided by i8259, i8259 depends on ISA, ISA depends
1085 * on piix4, and piix4 depends on pci_bus. To stop the cycle we have
1086 * qemu_irq_proxy() adds an extra bit of indirection, allowing us
1087 * to resolve the isa_irq -> i8259 dependency after i8259 is initialized.
1089 isa_irq = qemu_irq_proxy(&s->i8259, 16);
1091 /* Northbridge */
1092 pci_bus = gt64120_register(isa_irq);
1094 /* Southbridge */
1095 ide_drive_get(hd, MAX_IDE_BUS);
1097 piix4_devfn = piix4_init(pci_bus, &isa_bus, 80);
1099 /* Interrupt controller */
1100 /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
1101 s->i8259 = i8259_init(isa_bus, env->irq[2]);
1103 isa_bus_irqs(isa_bus, s->i8259);
1104 pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);
1105 pci_create_simple(pci_bus, piix4_devfn + 2, "piix4-usb-uhci");
1106 smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100,
1107 isa_get_irq(NULL, 9), NULL, 0, NULL);
1108 smbus_eeprom_init(smbus, 8, smbus_eeprom_buf, smbus_eeprom_size);
1109 g_free(smbus_eeprom_buf);
1110 pit = pit_init(isa_bus, 0x40, 0, NULL);
1111 cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
1112 DMA_init(0, cpu_exit_irq);
1114 /* Super I/O */
1115 isa_create_simple(isa_bus, "i8042");
1117 rtc_init(isa_bus, 2000, NULL);
1118 serial_isa_init(isa_bus, 0, serial_hds[0]);
1119 serial_isa_init(isa_bus, 1, serial_hds[1]);
1120 if (parallel_hds[0])
1121 parallel_init(isa_bus, 0, parallel_hds[0]);
1122 for(i = 0; i < MAX_FD; i++) {
1123 fd[i] = drive_get(IF_FLOPPY, 0, i);
1125 fdctrl_init_isa(isa_bus, fd);
1127 /* Network card */
1128 network_init(pci_bus);
1130 /* Optional PCI video card */
1131 pci_vga_init(pci_bus);
1134 static int mips_malta_sysbus_device_init(SysBusDevice *sysbusdev)
1136 return 0;
1139 static void mips_malta_class_init(ObjectClass *klass, void *data)
1141 SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
1143 k->init = mips_malta_sysbus_device_init;
1146 static const TypeInfo mips_malta_device = {
1147 .name = TYPE_MIPS_MALTA,
1148 .parent = TYPE_SYS_BUS_DEVICE,
1149 .instance_size = sizeof(MaltaState),
1150 .class_init = mips_malta_class_init,
1153 static QEMUMachine mips_malta_machine = {
1154 .name = "malta",
1155 .desc = "MIPS Malta Core LV",
1156 .init = mips_malta_init,
1157 .max_cpus = 16,
1158 .is_default = 1,
1161 static void mips_malta_register_types(void)
1163 type_register_static(&mips_malta_device);
1166 static void mips_malta_machine_init(void)
1168 qemu_register_machine(&mips_malta_machine);
1171 type_init(mips_malta_register_types)
1172 machine_init(mips_malta_machine_init);