]> git.proxmox.com Git - mirror_qemu.git/blame - hw/mips/mips_malta.c
hw/mips: In KVM mode, inject IRQ2 (I/O) interrupts via ioctls
[mirror_qemu.git] / hw / mips / mips_malta.c
CommitLineData
5856de80
TS
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
83c9f4ca 25#include "hw/hw.h"
0d09e41a
PB
26#include "hw/i386/pc.h"
27#include "hw/char/serial.h"
28#include "hw/block/fdc.h"
1422e32d 29#include "net/net.h"
83c9f4ca 30#include "hw/boards.h"
0d09e41a 31#include "hw/i2c/smbus.h"
737e150e 32#include "block/block.h"
0d09e41a
PB
33#include "hw/block/flash.h"
34#include "hw/mips/mips.h"
35#include "hw/mips/cpudevs.h"
83c9f4ca 36#include "hw/pci/pci.h"
dccfcd0e 37#include "sysemu/char.h"
9c17d615
PB
38#include "sysemu/sysemu.h"
39#include "sysemu/arch_init.h"
1de7afc9 40#include "qemu/log.h"
0d09e41a 41#include "hw/mips/bios.h"
83c9f4ca
PB
42#include "hw/ide.h"
43#include "hw/loader.h"
ca20cf32 44#include "elf.h"
0d09e41a
PB
45#include "hw/timer/mc146818rtc.h"
46#include "hw/timer/i8254.h"
9c17d615 47#include "sysemu/blockdev.h"
022c62cb 48#include "exec/address-spaces.h"
83c9f4ca 49#include "hw/sysbus.h" /* SysBusDevice */
02bccc77 50#include "qemu/host-utils.h"
2c57bd9b 51#include "sysemu/qtest.h"
2e985fe0 52#include "qemu/error-report.h"
cc413a39 53#include "hw/empty_slot.h"
5856de80 54
c8b153d7
TS
55//#define DEBUG_BOARD_INIT
56
409dbce5 57#define ENVP_ADDR 0x80002000l
5856de80
TS
58#define ENVP_NB_ENTRIES 16
59#define ENVP_ENTRY_SIZE 256
60
03a1a8e1
SW
61/* Hardware addresses */
62#define FLASH_ADDRESS 0x1e000000ULL
63#define FPGA_ADDRESS 0x1f000000ULL
64#define RESET_ADDRESS 0x1fc00000ULL
65
66#define FLASH_SIZE 0x400000
67
e4bcb14c
TS
68#define MAX_IDE_BUS 2
69
5856de80 70typedef struct {
ea85df72
AK
71 MemoryRegion iomem;
72 MemoryRegion iomem_lo; /* 0 - 0x900 */
73 MemoryRegion iomem_hi; /* 0xa00 - 0x100000 */
5856de80
TS
74 uint32_t leds;
75 uint32_t brk;
76 uint32_t gpout;
130751ee 77 uint32_t i2cin;
5856de80
TS
78 uint32_t i2coe;
79 uint32_t i2cout;
80 uint32_t i2csel;
81 CharDriverState *display;
82 char display_text[9];
a4bc3afc 83 SerialState *uart;
5856de80
TS
84} MaltaFPGAState;
85
cba5cb67
AF
86#define TYPE_MIPS_MALTA "mips-malta"
87#define MIPS_MALTA(obj) OBJECT_CHECK(MaltaState, (obj), TYPE_MIPS_MALTA)
88
e9b40fd3 89typedef struct {
cba5cb67
AF
90 SysBusDevice parent_obj;
91
e9b40fd3
SW
92 qemu_irq *i8259;
93} MaltaState;
94
64d7e9a4 95static ISADevice *pit;
5856de80 96
7df526e3
TS
97static struct _loaderparams {
98 int ram_size;
99 const char *kernel_filename;
100 const char *kernel_cmdline;
101 const char *initrd_filename;
102} loaderparams;
103
5856de80
TS
104/* Malta FPGA */
105static void malta_fpga_update_display(void *opaque)
106{
107 char leds_text[9];
108 int i;
109 MaltaFPGAState *s = opaque;
110
07cf0ba0
TS
111 for (i = 7 ; i >= 0 ; i--) {
112 if (s->leds & (1 << i))
113 leds_text[i] = '#';
114 else
115 leds_text[i] = ' ';
87ee1669 116 }
07cf0ba0
TS
117 leds_text[8] = '\0';
118
e7e71b0e
AL
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);
5856de80
TS
121}
122
130751ee
TS
123/*
124 * EEPROM 24C01 / 24C02 emulation.
125 *
126 * Emulation for serial EEPROMs:
127 * 24C01 - 1024 bit (128 x 8)
128 * 24C02 - 2048 bit (256 x 8)
129 *
130 * Typical device names include Microchip 24C02SC or SGS Thomson ST24C02.
131 */
132
133//~ #define DEBUG
134
135#if defined(DEBUG)
001faf32 136# define logout(fmt, ...) fprintf(stderr, "MALTA\t%-24s" fmt, __func__, ## __VA_ARGS__)
130751ee 137#else
001faf32 138# define logout(fmt, ...) ((void)0)
130751ee
TS
139#endif
140
c227f099 141struct _eeprom24c0x_t {
130751ee
TS
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];
151};
152
c227f099 153typedef struct _eeprom24c0x_t eeprom24c0x_t;
130751ee 154
35c64807 155static eeprom24c0x_t spd_eeprom = {
284b08f1 156 .contents = {
02bccc77 157 /* 00000000: */ 0x80,0x08,0xFF,0x0D,0x0A,0xFF,0x40,0x00,
130751ee 158 /* 00000008: */ 0x01,0x75,0x54,0x00,0x82,0x08,0x00,0x01,
02bccc77
PB
159 /* 00000010: */ 0x8F,0x04,0x02,0x01,0x01,0x00,0x00,0x00,
160 /* 00000018: */ 0x00,0x00,0x00,0x14,0x0F,0x14,0x2D,0xFF,
130751ee
TS
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,
173 },
174};
175
35c64807 176static void generate_eeprom_spd(uint8_t *eeprom, ram_addr_t ram_size)
02bccc77
PB
177{
178 enum { SDR = 0x4, DDR2 = 0x8 } type;
35c64807 179 uint8_t *spd = spd_eeprom.contents;
02bccc77
PB
180 uint8_t nbanks = 0;
181 uint16_t density = 0;
182 int i;
183
184 /* work in terms of MB */
185 ram_size >>= 20;
186
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;
192 }
193
194 /* split to 2 banks if possible */
195 if ((nbanks == 1) && (density > 1)) {
196 nbanks++;
197 density >>= 1;
198 }
199
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;
207 }
208
209 if (ram_size) {
210 fprintf(stderr, "Warning: SPD cannot represent final %dMB"
211 " of SDRAM\n", (int)ram_size);
212 }
213
214 /* fill in SPD memory information */
215 spd[2] = type;
216 spd[5] = nbanks;
217 spd[31] = density;
218
219 /* checksum */
220 spd[63] = 0;
221 for (i = 0; i < 63; i++) {
222 spd[63] += spd[i];
223 }
35c64807
PB
224
225 /* copy for SMBUS */
226 memcpy(eeprom, spd, sizeof(spd_eeprom.contents));
227}
228
229static void generate_eeprom_serial(uint8_t *eeprom)
230{
231 int i, pos = 0;
232 uint8_t mac[6] = { 0x00 };
233 uint8_t sn[5] = { 0x01, 0x23, 0x45, 0x67, 0x89 };
234
235 /* version */
236 eeprom[pos++] = 0x01;
237
238 /* count */
239 eeprom[pos++] = 0x02;
240
241 /* MAC address */
242 eeprom[pos++] = 0x01; /* MAC */
243 eeprom[pos++] = 0x06; /* length */
244 memcpy(&eeprom[pos], mac, sizeof(mac));
245 pos += sizeof(mac);
246
247 /* serial number */
248 eeprom[pos++] = 0x02; /* serial */
249 eeprom[pos++] = 0x05; /* length */
250 memcpy(&eeprom[pos], sn, sizeof(sn));
251 pos += sizeof(sn);
252
253 /* checksum */
254 eeprom[pos] = 0;
255 for (i = 0; i < pos; i++) {
256 eeprom[pos] += eeprom[i];
257 }
02bccc77
PB
258}
259
35c64807 260static uint8_t eeprom24c0x_read(eeprom24c0x_t *eeprom)
130751ee
TS
261{
262 logout("%u: scl = %u, sda = %u, data = 0x%02x\n",
35c64807
PB
263 eeprom->tick, eeprom->scl, eeprom->sda, eeprom->data);
264 return eeprom->sda;
130751ee
TS
265}
266
35c64807 267static void eeprom24c0x_write(eeprom24c0x_t *eeprom, int scl, int sda)
130751ee 268{
35c64807 269 if (eeprom->scl && scl && (eeprom->sda != sda)) {
130751ee 270 logout("%u: scl = %u->%u, sda = %u->%u i2c %s\n",
35c64807
PB
271 eeprom->tick, eeprom->scl, scl, eeprom->sda, sda,
272 sda ? "stop" : "start");
130751ee 273 if (!sda) {
35c64807
PB
274 eeprom->tick = 1;
275 eeprom->command = 0;
130751ee 276 }
35c64807 277 } else if (eeprom->tick == 0 && !eeprom->ack) {
130751ee
TS
278 /* Waiting for start. */
279 logout("%u: scl = %u->%u, sda = %u->%u wait for i2c start\n",
35c64807
PB
280 eeprom->tick, eeprom->scl, scl, eeprom->sda, sda);
281 } else if (!eeprom->scl && scl) {
130751ee 282 logout("%u: scl = %u->%u, sda = %u->%u trigger bit\n",
35c64807
PB
283 eeprom->tick, eeprom->scl, scl, eeprom->sda, sda);
284 if (eeprom->ack) {
130751ee
TS
285 logout("\ti2c ack bit = 0\n");
286 sda = 0;
35c64807
PB
287 eeprom->ack = 0;
288 } else if (eeprom->sda == sda) {
130751ee
TS
289 uint8_t bit = (sda != 0);
290 logout("\ti2c bit = %d\n", bit);
35c64807
PB
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;
130751ee 299 }
35c64807
PB
300 } else if (eeprom->tick < 17) {
301 if (eeprom->command & 1) {
302 sda = ((eeprom->data & 0x80) != 0);
130751ee 303 }
35c64807
PB
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;
130751ee 314 }
35c64807 315 } else if (eeprom->tick >= 17) {
130751ee
TS
316 sda = 0;
317 }
318 } else {
319 logout("\tsda changed with raising scl\n");
320 }
321 } else {
35c64807
PB
322 logout("%u: scl = %u->%u, sda = %u->%u\n", eeprom->tick, eeprom->scl,
323 scl, eeprom->sda, sda);
130751ee 324 }
35c64807
PB
325 eeprom->scl = scl;
326 eeprom->sda = sda;
130751ee
TS
327}
328
a8170e5e 329static uint64_t malta_fpga_read(void *opaque, hwaddr addr,
ea85df72 330 unsigned size)
5856de80
TS
331{
332 MaltaFPGAState *s = opaque;
333 uint32_t val = 0;
334 uint32_t saddr;
335
336 saddr = (addr & 0xfffff);
337
338 switch (saddr) {
339
340 /* SWITCH Register */
341 case 0x00200:
342 val = 0x00000000; /* All switches closed */
593c0d10 343 break;
5856de80
TS
344
345 /* STATUS Register */
346 case 0x00208:
347#ifdef TARGET_WORDS_BIGENDIAN
348 val = 0x00000012;
349#else
350 val = 0x00000010;
351#endif
352 break;
353
354 /* JMPRS Register */
355 case 0x00210:
356 val = 0x00;
357 break;
358
359 /* LEDBAR Register */
360 case 0x00408:
361 val = s->leds;
362 break;
363
364 /* BRKRES Register */
365 case 0x00508:
366 val = s->brk;
367 break;
368
b6dc7ebb 369 /* UART Registers are handled directly by the serial device */
a4bc3afc 370
5856de80
TS
371 /* GPOUT Register */
372 case 0x00a00:
373 val = s->gpout;
374 break;
375
376 /* XXX: implement a real I2C controller */
377
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;
386
387 /* I2CINP Register */
388 case 0x00b00:
35c64807 389 val = ((s->i2cin & ~1) | eeprom24c0x_read(&spd_eeprom));
5856de80
TS
390 break;
391
392 /* I2COE Register */
393 case 0x00b08:
394 val = s->i2coe;
395 break;
396
397 /* I2COUT Register */
398 case 0x00b10:
399 val = s->i2cout;
400 break;
401
402 /* I2CSEL Register */
403 case 0x00b18:
130751ee 404 val = s->i2csel;
5856de80
TS
405 break;
406
407 default:
408#if 0
3594c774 409 printf ("malta_fpga_read: Bad register offset 0x" TARGET_FMT_lx "\n",
593c0d10 410 addr);
5856de80
TS
411#endif
412 break;
413 }
414 return val;
415}
416
a8170e5e 417static void malta_fpga_write(void *opaque, hwaddr addr,
ea85df72 418 uint64_t val, unsigned size)
5856de80
TS
419{
420 MaltaFPGAState *s = opaque;
421 uint32_t saddr;
422
423 saddr = (addr & 0xfffff);
424
425 switch (saddr) {
426
427 /* SWITCH Register */
428 case 0x00200:
429 break;
430
431 /* JMPRS Register */
432 case 0x00210:
433 break;
434
435 /* LEDBAR Register */
5856de80
TS
436 case 0x00408:
437 s->leds = val & 0xff;
1d7a1197 438 malta_fpga_update_display(s);
5856de80
TS
439 break;
440
441 /* ASCIIWORD Register */
442 case 0x00410:
ea85df72 443 snprintf(s->display_text, 9, "%08X", (uint32_t)val);
5856de80
TS
444 malta_fpga_update_display(s);
445 break;
446
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;
459
460 /* SOFTRES Register */
461 case 0x00500:
462 if (val == 0x42)
463 qemu_system_reset_request ();
464 break;
465
466 /* BRKRES Register */
467 case 0x00508:
468 s->brk = val & 0xff;
469 break;
470
b6dc7ebb 471 /* UART Registers are handled directly by the serial device */
a4bc3afc 472
5856de80
TS
473 /* GPOUT Register */
474 case 0x00a00:
475 s->gpout = val & 0xff;
476 break;
477
478 /* I2COE Register */
479 case 0x00b08:
480 s->i2coe = val & 0x03;
481 break;
482
483 /* I2COUT Register */
484 case 0x00b10:
35c64807 485 eeprom24c0x_write(&spd_eeprom, val & 0x02, val & 0x01);
130751ee 486 s->i2cout = val;
5856de80
TS
487 break;
488
489 /* I2CSEL Register */
490 case 0x00b18:
130751ee 491 s->i2csel = val & 0x01;
5856de80
TS
492 break;
493
494 default:
495#if 0
3594c774 496 printf ("malta_fpga_write: Bad register offset 0x" TARGET_FMT_lx "\n",
593c0d10 497 addr);
5856de80
TS
498#endif
499 break;
500 }
501}
502
ea85df72
AK
503static const MemoryRegionOps malta_fpga_ops = {
504 .read = malta_fpga_read,
505 .write = malta_fpga_write,
506 .endianness = DEVICE_NATIVE_ENDIAN,
5856de80
TS
507};
508
9596ebb7 509static void malta_fpga_reset(void *opaque)
5856de80
TS
510{
511 MaltaFPGAState *s = opaque;
512
513 s->leds = 0x00;
514 s->brk = 0x0a;
515 s->gpout = 0x00;
130751ee 516 s->i2cin = 0x3;
5856de80
TS
517 s->i2coe = 0x0;
518 s->i2cout = 0x3;
519 s->i2csel = 0x1;
520
521 s->display_text[8] = '\0';
522 snprintf(s->display_text, 9, " ");
ceecf1d1
AJ
523}
524
ceecf1d1
AJ
525static void malta_fpga_led_init(CharDriverState *chr)
526{
e7e71b0e
AL
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");
5856de80
TS
536}
537
ea85df72 538static MaltaFPGAState *malta_fpga_init(MemoryRegion *address_space,
a8170e5e 539 hwaddr base, qemu_irq uart_irq, CharDriverState *uart_chr)
5856de80
TS
540{
541 MaltaFPGAState *s;
5856de80 542
7267c094 543 s = (MaltaFPGAState *)g_malloc0(sizeof(MaltaFPGAState));
5856de80 544
2c9b15ca 545 memory_region_init_io(&s->iomem, NULL, &malta_fpga_ops, s,
ea85df72 546 "malta-fpga", 0x100000);
2c9b15ca 547 memory_region_init_alias(&s->iomem_lo, NULL, "malta-fpga",
ea85df72 548 &s->iomem, 0, 0x900);
2c9b15ca 549 memory_region_init_alias(&s->iomem_hi, NULL, "malta-fpga",
ea85df72 550 &s->iomem, 0xa00, 0x10000-0xa00);
a4bc3afc 551
ea85df72
AK
552 memory_region_add_subregion(address_space, base, &s->iomem_lo);
553 memory_region_add_subregion(address_space, base + 0xa00, &s->iomem_hi);
5856de80 554
27143a44 555 s->display = qemu_chr_new("fpga", "vc:320x200", malta_fpga_led_init);
ceecf1d1 556
39186d8a
RH
557 s->uart = serial_mm_init(address_space, base + 0x900, 3, uart_irq,
558 230400, uart_chr, DEVICE_NATIVE_ENDIAN);
a4bc3afc 559
5856de80 560 malta_fpga_reset(s);
a08d4367 561 qemu_register_reset(malta_fpga_reset, s);
5856de80
TS
562
563 return s;
564}
565
5856de80 566/* Network support */
29b358f9 567static void network_init(PCIBus *pci_bus)
5856de80
TS
568{
569 int i;
5856de80
TS
570
571 for(i = 0; i < nb_nics; i++) {
cb457d76 572 NICInfo *nd = &nd_table[i];
5607c388 573 const char *default_devaddr = NULL;
cb457d76
AL
574
575 if (i == 0 && (!nd->model || strcmp(nd->model, "pcnet") == 0))
5856de80 576 /* The malta board has a PCNet card using PCI SLOT 11 */
5607c388 577 default_devaddr = "0b";
cb457d76 578
29b358f9 579 pci_nic_init_nofail(nd, pci_bus, "pcnet", default_devaddr);
5856de80
TS
580 }
581}
582
583/* ROM and pseudo bootloader
584
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.
588
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.
593
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.
597
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
603*/
604
61c56c8c 605static void write_bootloader (CPUMIPSState *env, uint8_t *base,
d7585251 606 int64_t kernel_entry)
5856de80
TS
607{
608 uint32_t *p;
609
610 /* Small bootloader */
d7585251 611 p = (uint32_t *)base;
0983979b
PB
612 stl_p(p++, 0x0bf00160); /* j 0x1fc00580 */
613 stl_p(p++, 0x00000000); /* nop */
5856de80 614
26ea0918 615 /* YAMON service vector */
0983979b
PB
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: */
26ea0918
TS
629
630
5856de80 631 /* Second part of the bootloader */
d7585251 632 p = (uint32_t *) (base + 0x580);
0983979b
PB
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) */
2802bfe3
TS
642
643 /* Load BAR registers as done by YAMON */
0983979b 644 stl_p(p++, 0x3c09b400); /* lui t1, 0xb400 */
a0a8793e
TS
645
646#ifdef TARGET_WORDS_BIGENDIAN
0983979b 647 stl_p(p++, 0x3c08df00); /* lui t0, 0xdf00 */
a0a8793e 648#else
0983979b 649 stl_p(p++, 0x340800df); /* ori t0, r0, 0x00df */
a0a8793e 650#endif
0983979b 651 stl_p(p++, 0xad280068); /* sw t0, 0x0068(t1) */
a0a8793e 652
0983979b 653 stl_p(p++, 0x3c09bbe0); /* lui t1, 0xbbe0 */
2802bfe3
TS
654
655#ifdef TARGET_WORDS_BIGENDIAN
0983979b 656 stl_p(p++, 0x3c08c000); /* lui t0, 0xc000 */
2802bfe3 657#else
0983979b 658 stl_p(p++, 0x340800c0); /* ori t0, r0, 0x00c0 */
2802bfe3 659#endif
0983979b 660 stl_p(p++, 0xad280048); /* sw t0, 0x0048(t1) */
2802bfe3 661#ifdef TARGET_WORDS_BIGENDIAN
0983979b 662 stl_p(p++, 0x3c084000); /* lui t0, 0x4000 */
2802bfe3 663#else
0983979b 664 stl_p(p++, 0x34080040); /* ori t0, r0, 0x0040 */
2802bfe3 665#endif
0983979b 666 stl_p(p++, 0xad280050); /* sw t0, 0x0050(t1) */
2802bfe3
TS
667
668#ifdef TARGET_WORDS_BIGENDIAN
0983979b 669 stl_p(p++, 0x3c088000); /* lui t0, 0x8000 */
2802bfe3 670#else
0983979b 671 stl_p(p++, 0x34080080); /* ori t0, r0, 0x0080 */
2802bfe3 672#endif
0983979b 673 stl_p(p++, 0xad280058); /* sw t0, 0x0058(t1) */
2802bfe3 674#ifdef TARGET_WORDS_BIGENDIAN
0983979b 675 stl_p(p++, 0x3c083f00); /* lui t0, 0x3f00 */
2802bfe3 676#else
0983979b 677 stl_p(p++, 0x3408003f); /* ori t0, r0, 0x003f */
2802bfe3 678#endif
0983979b 679 stl_p(p++, 0xad280060); /* sw t0, 0x0060(t1) */
2802bfe3
TS
680
681#ifdef TARGET_WORDS_BIGENDIAN
0983979b 682 stl_p(p++, 0x3c08c100); /* lui t0, 0xc100 */
2802bfe3 683#else
0983979b 684 stl_p(p++, 0x340800c1); /* ori t0, r0, 0x00c1 */
2802bfe3 685#endif
0983979b 686 stl_p(p++, 0xad280080); /* sw t0, 0x0080(t1) */
2802bfe3 687#ifdef TARGET_WORDS_BIGENDIAN
0983979b 688 stl_p(p++, 0x3c085e00); /* lui t0, 0x5e00 */
2802bfe3 689#else
0983979b 690 stl_p(p++, 0x3408005e); /* ori t0, r0, 0x005e */
2802bfe3 691#endif
0983979b 692 stl_p(p++, 0xad280088); /* sw t0, 0x0088(t1) */
2802bfe3
TS
693
694 /* Jump to kernel code */
0983979b
PB
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 */
26ea0918
TS
699
700 /* YAMON subroutines */
d7585251 701 p = (uint32_t *) (base + 0x800);
0983979b
PB
702 stl_p(p++, 0x03e00008); /* jr ra */
703 stl_p(p++, 0x24020000); /* li v0,0 */
26ea0918 704 /* 808 YAMON print */
0983979b
PB
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 */
26ea0918 718 /* 0x83c YAMON print_count */
0983979b
PB
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 */
26ea0918 732 /* 0x870 */
0983979b
PB
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) */
26ea0918 742
5856de80
TS
743}
744
8b7968f7
SW
745static void GCC_FMT_ATTR(3, 4) prom_set(uint32_t* prom_buf, int index,
746 const char *string, ...)
5856de80
TS
747{
748 va_list ap;
3ddd0065 749 int32_t table_addr;
5856de80
TS
750
751 if (index >= ENVP_NB_ENTRIES)
752 return;
753
5856de80 754 if (string == NULL) {
c938ada2 755 prom_buf[index] = 0;
5856de80
TS
756 return;
757 }
758
c938ada2
AJ
759 table_addr = sizeof(int32_t) * ENVP_NB_ENTRIES + index * ENVP_ENTRY_SIZE;
760 prom_buf[index] = tswap32(ENVP_ADDR + table_addr);
5856de80
TS
761
762 va_start(ap, string);
c938ada2 763 vsnprintf((char *)prom_buf + table_addr, ENVP_ENTRY_SIZE, string, ap);
5856de80
TS
764 va_end(ap);
765}
766
767/* Kernel */
e16ad5b0 768static int64_t load_kernel (void)
5856de80 769{
409dbce5 770 int64_t kernel_entry, kernel_high;
5856de80 771 long initrd_size;
c227f099 772 ram_addr_t initrd_offset;
ca20cf32 773 int big_endian;
c938ada2
AJ
774 uint32_t *prom_buf;
775 long prom_size;
776 int prom_index = 0;
ca20cf32
BS
777
778#ifdef TARGET_WORDS_BIGENDIAN
779 big_endian = 1;
780#else
781 big_endian = 0;
782#endif
5856de80 783
409dbce5
AJ
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) {
5856de80 787 fprintf(stderr, "qemu: could not load kernel '%s'\n",
7df526e3 788 loaderparams.kernel_filename);
acdf72bb 789 exit(1);
5856de80
TS
790 }
791
792 /* load initrd */
793 initrd_size = 0;
74287114 794 initrd_offset = 0;
7df526e3
TS
795 if (loaderparams.initrd_filename) {
796 initrd_size = get_image_size (loaderparams.initrd_filename);
74287114 797 if (initrd_size > 0) {
05b3274b 798 initrd_offset = (kernel_high + ~INITRD_PAGE_MASK) & INITRD_PAGE_MASK;
7df526e3 799 if (initrd_offset + initrd_size > ram_size) {
74287114
TS
800 fprintf(stderr,
801 "qemu: memory too small for initial ram disk '%s'\n",
7df526e3 802 loaderparams.initrd_filename);
74287114
TS
803 exit(1);
804 }
dcac9679
PB
805 initrd_size = load_image_targphys(loaderparams.initrd_filename,
806 initrd_offset,
807 ram_size - initrd_offset);
74287114 808 }
5856de80
TS
809 if (initrd_size == (target_ulong) -1) {
810 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
7df526e3 811 loaderparams.initrd_filename);
5856de80
TS
812 exit(1);
813 }
814 }
815
c938ada2
AJ
816 /* Setup prom parameters. */
817 prom_size = ENVP_NB_ENTRIES * (sizeof(int32_t) + ENVP_ENTRY_SIZE);
7267c094 818 prom_buf = g_malloc(prom_size);
c938ada2 819
f36d53ef 820 prom_set(prom_buf, prom_index++, "%s", loaderparams.kernel_filename);
c938ada2 821 if (initrd_size > 0) {
409dbce5
AJ
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,
7df526e3 824 loaderparams.kernel_cmdline);
c938ada2 825 } else {
f36d53ef 826 prom_set(prom_buf, prom_index++, "%s", loaderparams.kernel_cmdline);
c938ada2
AJ
827 }
828
829 prom_set(prom_buf, prom_index++, "memsize");
94c2b6af
PB
830 prom_set(prom_buf, prom_index++, "%i",
831 MIN(loaderparams.ram_size, 256 << 20));
c938ada2
AJ
832 prom_set(prom_buf, prom_index++, "modetty0");
833 prom_set(prom_buf, prom_index++, "38400n8r");
834 prom_set(prom_buf, prom_index++, NULL);
835
836 rom_add_blob_fixed("prom", prom_buf, prom_size,
409dbce5 837 cpu_mips_kseg0_to_phys(NULL, ENVP_ADDR));
5856de80 838
74287114 839 return kernel_entry;
5856de80
TS
840}
841
ce3960eb 842static void malta_mips_config(MIPSCPU *cpu)
c4cb2578 843{
ce3960eb
AF
844 CPUMIPSState *env = &cpu->env;
845 CPUState *cs = CPU(cpu);
846
c4cb2578 847 env->mvp->CP0_MVPConf0 |= ((smp_cpus - 1) << CP0MVPC0_PVPE) |
ce3960eb 848 ((smp_cpus * cs->nr_threads - 1) << CP0MVPC0_PTC);
c4cb2578
EI
849}
850
5856de80
TS
851static void main_cpu_reset(void *opaque)
852{
1004ee8d
AF
853 MIPSCPU *cpu = opaque;
854 CPUMIPSState *env = &cpu->env;
855
856 cpu_reset(CPU(cpu));
5856de80 857
5c43485f 858 /* The bootloader does not need to be rewritten as it is located in a
5856de80
TS
859 read only location. The kernel location and the arguments table
860 location does not change. */
7df526e3 861 if (loaderparams.kernel_filename) {
fb82fea0 862 env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
fb82fea0 863 }
c4cb2578 864
ce3960eb 865 malta_mips_config(cpu);
5856de80
TS
866}
867
4556bd8b
BS
868static void cpu_request_exit(void *opaque, int irq, int level)
869{
4917cf44 870 CPUState *cpu = current_cpu;
4556bd8b 871
4917cf44
AF
872 if (cpu && level) {
873 cpu_exit(cpu);
4556bd8b
BS
874 }
875}
876
70705261 877static
3ef96221 878void mips_malta_init(MachineState *machine)
5856de80 879{
3ef96221
MA
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;
5cea8590 885 char *filename;
cfe5f011 886 pflash_t *fl;
cfe5f011 887 MemoryRegion *system_memory = get_system_memory();
94c2b6af
PB
888 MemoryRegion *ram_high = g_new(MemoryRegion, 1);
889 MemoryRegion *ram_low_preio = g_new(MemoryRegion, 1);
890 MemoryRegion *ram_low_postio;
a427338b 891 MemoryRegion *bios, *bios_copy = g_new(MemoryRegion, 1);
03a1a8e1 892 target_long bios_size = FLASH_SIZE;
35c64807
PB
893 const size_t smbus_eeprom_size = 8 * 256;
894 uint8_t *smbus_eeprom_buf = g_malloc0(smbus_eeprom_size);
74287114 895 int64_t kernel_entry;
5856de80 896 PCIBus *pci_bus;
48a18b3c 897 ISABus *isa_bus;
7688b134 898 MIPSCPU *cpu;
61c56c8c 899 CPUMIPSState *env;
e9b40fd3 900 qemu_irq *isa_irq;
4556bd8b 901 qemu_irq *cpu_exit_irq;
7b717336 902 int piix4_devfn;
a5c82852 903 I2CBus *smbus;
7b717336 904 int i;
751c6a17 905 DriveInfo *dinfo;
f455e98c 906 DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
fd8014e1 907 DriveInfo *fd[MAX_FD];
c8b153d7 908 int fl_idx = 0;
bb4b3358 909 int fl_sectors = bios_size >> 16;
01e0451a 910 int be;
5856de80 911
cba5cb67
AF
912 DeviceState *dev = qdev_create(NULL, TYPE_MIPS_MALTA);
913 MaltaState *s = MIPS_MALTA(dev);
e9b40fd3 914
cc413a39
AJ
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);
919
e9b40fd3
SW
920 qdev_init_nofail(dev);
921
ffabf037
AJ
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);
27143a44 927 serial_hds[i] = qemu_chr_new(label, "null", NULL);
ffabf037
AJ
928 }
929 }
930
33d68b5f
TS
931 /* init CPUs */
932 if (cpu_model == NULL) {
60aa19ab 933#ifdef TARGET_MIPS64
c9c1a064 934 cpu_model = "20Kc";
33d68b5f 935#else
1c32f43e 936 cpu_model = "24Kf";
33d68b5f
TS
937#endif
938 }
c4cb2578
EI
939
940 for (i = 0; i < smp_cpus; i++) {
7688b134
AF
941 cpu = cpu_mips_init(cpu_model);
942 if (cpu == NULL) {
c4cb2578
EI
943 fprintf(stderr, "Unable to find CPU definition\n");
944 exit(1);
945 }
7688b134
AF
946 env = &cpu->env;
947
c4cb2578
EI
948 /* Init internal devices */
949 cpu_mips_irq_init_cpu(env);
950 cpu_mips_clock_init(env);
1004ee8d 951 qemu_register_reset(main_cpu_reset, cpu);
aaed909a 952 }
182735ef
AF
953 cpu = MIPS_CPU(first_cpu);
954 env = &cpu->env;
5856de80
TS
955
956 /* allocate RAM */
94c2b6af 957 if (ram_size > (2048u << 20)) {
0ccff151 958 fprintf(stderr,
94c2b6af 959 "qemu: Too much memory for this machine: %d MB, maximum 2048 MB\n",
0ccff151
AJ
960 ((unsigned int)ram_size / (1 << 20)));
961 exit(1);
962 }
94c2b6af
PB
963
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);
968
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);
973
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);
982 }
5856de80 983
02bccc77 984 /* generate SPD EEPROM data */
35c64807
PB
985 generate_eeprom_spd(&smbus_eeprom_buf[0 * 256], ram_size);
986 generate_eeprom_serial(&smbus_eeprom_buf[6 * 256]);
02bccc77 987
01e0451a
AL
988#ifdef TARGET_WORDS_BIGENDIAN
989 be = 1;
990#else
991 be = 0;
992#endif
070ce5ed 993 /* FPGA */
68d00192
AJ
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]);
070ce5ed 996
bb4b3358
SW
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",
03a1a8e1 1003 fl_idx, bios_size, FLASH_ADDRESS,
bb4b3358
SW
1004 bdrv_get_device_name(dinfo->bdrv), fl_sectors);
1005 }
1006#endif
03a1a8e1 1007 fl = pflash_cfi01_register(FLASH_ADDRESS, NULL, "mips_malta.bios",
bb4b3358
SW
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++;
c8b153d7
TS
1013 if (kernel_filename) {
1014 /* Write a small bootloader to the flash location. */
94c2b6af 1015 loaderparams.ram_size = MIN(ram_size, 256 << 20);
c8b153d7
TS
1016 loaderparams.kernel_filename = kernel_filename;
1017 loaderparams.kernel_cmdline = kernel_cmdline;
1018 loaderparams.initrd_filename = initrd_filename;
e16ad5b0 1019 kernel_entry = load_kernel();
cfe5f011 1020 write_bootloader(env, memory_region_get_ram_ptr(bios), kernel_entry);
c8b153d7 1021 } else {
bb4b3358
SW
1022 /* Load firmware from flash. */
1023 if (!dinfo) {
c8b153d7 1024 /* Load a BIOS image. */
bb4b3358 1025 if (bios_name == NULL) {
c8b153d7 1026 bios_name = BIOS_FILENAME;
bb4b3358 1027 }
5cea8590
PB
1028 filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
1029 if (filename) {
03a1a8e1 1030 bios_size = load_image_targphys(filename, FLASH_ADDRESS,
5cea8590 1031 BIOS_SIZE);
7267c094 1032 g_free(filename);
5cea8590
PB
1033 } else {
1034 bios_size = -1;
1035 }
2c57bd9b
AF
1036 if ((bios_size < 0 || bios_size > BIOS_SIZE) &&
1037 !kernel_filename && !qtest_enabled()) {
2e985fe0
AJ
1038 error_report("Could not load MIPS bios '%s', and no "
1039 "-kernel argument was specified", bios_name);
1040 exit(1);
c8b153d7 1041 }
070ce5ed 1042 }
3187ef03
TS
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
1046 {
a2b8813d
PB
1047 uint32_t *end, *addr = rom_ptr(FLASH_ADDRESS);
1048 if (!addr) {
1049 addr = memory_region_get_ram_ptr(bios);
1050 }
1817f56a 1051 end = (void *)addr + MIN(bios_size, 0x3e0000);
d7585251
PB
1052 while (addr < end) {
1053 bswap32s(addr);
a30cfee5 1054 addr++;
3187ef03
TS
1055 }
1056 }
1057#endif
070ce5ed
TS
1058 }
1059
a427338b
PB
1060 /*
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.
1065 */
1066 memory_region_init_ram(bios_copy, NULL, "bios.1fc", BIOS_SIZE);
1067 if (!rom_copy(memory_region_get_ram_ptr(bios_copy),
f05d4d94 1068 FLASH_ADDRESS, BIOS_SIZE)) {
a427338b 1069 memcpy(memory_region_get_ram_ptr(bios_copy),
f05d4d94 1070 memory_region_get_ram_ptr(bios), BIOS_SIZE);
a427338b
PB
1071 }
1072 memory_region_set_readonly(bios_copy, true);
1073 memory_region_add_subregion(system_memory, RESET_ADDRESS, bios_copy);
82a9807b 1074
a427338b
PB
1075 /* Board ID = 0x420 (Malta Board with CoreLV) */
1076 stl_p(memory_region_get_ram_ptr(bios_copy) + 0x10, 0x00000420);
5856de80
TS
1077
1078 /* Init internal devices */
d537cf6c 1079 cpu_mips_irq_init_cpu(env);
5856de80 1080 cpu_mips_clock_init(env);
5856de80 1081
5632ae46
AK
1082 /*
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.
1088 */
e9b40fd3 1089 isa_irq = qemu_irq_proxy(&s->i8259, 16);
5856de80
TS
1090
1091 /* Northbridge */
5632ae46 1092 pci_bus = gt64120_register(isa_irq);
5856de80
TS
1093
1094 /* Southbridge */
75717903 1095 ide_drive_get(hd, MAX_IDE_BUS);
e4bcb14c 1096
142e9787 1097 piix4_devfn = piix4_init(pci_bus, &isa_bus, 80);
5632ae46
AK
1098
1099 /* Interrupt controller */
1100 /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
e9b40fd3 1101 s->i8259 = i8259_init(isa_bus, env->irq[2]);
5632ae46 1102
e9b40fd3 1103 isa_bus_irqs(isa_bus, s->i8259);
ae027ad3 1104 pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);
afb9a60e 1105 pci_create_simple(pci_bus, piix4_devfn + 2, "piix4-usb-uhci");
48a18b3c 1106 smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100,
459ae5ea 1107 isa_get_irq(NULL, 9), NULL, 0, NULL);
35c64807
PB
1108 smbus_eeprom_init(smbus, 8, smbus_eeprom_buf, smbus_eeprom_size);
1109 g_free(smbus_eeprom_buf);
319ba9f5 1110 pit = pit_init(isa_bus, 0x40, 0, NULL);
4556bd8b
BS
1111 cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
1112 DMA_init(0, cpu_exit_irq);
5856de80
TS
1113
1114 /* Super I/O */
48a18b3c 1115 isa_create_simple(isa_bus, "i8042");
49a2942d 1116
48a18b3c
HP
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]);
7bcc17dc 1120 if (parallel_hds[0])
48a18b3c 1121 parallel_init(isa_bus, 0, parallel_hds[0]);
e4bcb14c 1122 for(i = 0; i < MAX_FD; i++) {
fd8014e1 1123 fd[i] = drive_get(IF_FLOPPY, 0, i);
e4bcb14c 1124 }
48a18b3c 1125 fdctrl_init_isa(isa_bus, fd);
5856de80 1126
5856de80 1127 /* Network card */
29b358f9 1128 network_init(pci_bus);
11f29511
TS
1129
1130 /* Optional PCI video card */
9c59864d 1131 pci_vga_init(pci_bus);
5856de80
TS
1132}
1133
e9b40fd3
SW
1134static int mips_malta_sysbus_device_init(SysBusDevice *sysbusdev)
1135{
1136 return 0;
1137}
1138
999e12bb
AL
1139static void mips_malta_class_init(ObjectClass *klass, void *data)
1140{
1141 SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
1142
1143 k->init = mips_malta_sysbus_device_init;
1144}
1145
8c43a6f0 1146static const TypeInfo mips_malta_device = {
cba5cb67 1147 .name = TYPE_MIPS_MALTA,
39bffca2
AL
1148 .parent = TYPE_SYS_BUS_DEVICE,
1149 .instance_size = sizeof(MaltaState),
1150 .class_init = mips_malta_class_init,
e9b40fd3
SW
1151};
1152
f80f9ec9 1153static QEMUMachine mips_malta_machine = {
eec2743e
TS
1154 .name = "malta",
1155 .desc = "MIPS Malta Core LV",
1156 .init = mips_malta_init,
c4cb2578 1157 .max_cpus = 16,
0c257437 1158 .is_default = 1,
5856de80 1159};
f80f9ec9 1160
83f7d43a 1161static void mips_malta_register_types(void)
e9b40fd3 1162{
39bffca2 1163 type_register_static(&mips_malta_device);
e9b40fd3
SW
1164}
1165
f80f9ec9
AL
1166static void mips_malta_machine_init(void)
1167{
1168 qemu_register_machine(&mips_malta_machine);
1169}
1170
83f7d43a 1171type_init(mips_malta_register_types)
f80f9ec9 1172machine_init(mips_malta_machine_init);