]> git.proxmox.com Git - mirror_qemu.git/blame - hw/mips/mips_malta.c
MAINTAINERS: Add entry for MIPS KVM
[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"
b0311811 54#include "sysemu/kvm.h"
5856de80 55
c8b153d7
TS
56//#define DEBUG_BOARD_INIT
57
409dbce5 58#define ENVP_ADDR 0x80002000l
5856de80
TS
59#define ENVP_NB_ENTRIES 16
60#define ENVP_ENTRY_SIZE 256
61
03a1a8e1
SW
62/* Hardware addresses */
63#define FLASH_ADDRESS 0x1e000000ULL
64#define FPGA_ADDRESS 0x1f000000ULL
65#define RESET_ADDRESS 0x1fc00000ULL
66
67#define FLASH_SIZE 0x400000
68
e4bcb14c
TS
69#define MAX_IDE_BUS 2
70
5856de80 71typedef struct {
ea85df72
AK
72 MemoryRegion iomem;
73 MemoryRegion iomem_lo; /* 0 - 0x900 */
74 MemoryRegion iomem_hi; /* 0xa00 - 0x100000 */
5856de80
TS
75 uint32_t leds;
76 uint32_t brk;
77 uint32_t gpout;
130751ee 78 uint32_t i2cin;
5856de80
TS
79 uint32_t i2coe;
80 uint32_t i2cout;
81 uint32_t i2csel;
82 CharDriverState *display;
83 char display_text[9];
a4bc3afc 84 SerialState *uart;
5856de80
TS
85} MaltaFPGAState;
86
cba5cb67
AF
87#define TYPE_MIPS_MALTA "mips-malta"
88#define MIPS_MALTA(obj) OBJECT_CHECK(MaltaState, (obj), TYPE_MIPS_MALTA)
89
e9b40fd3 90typedef struct {
cba5cb67
AF
91 SysBusDevice parent_obj;
92
e9b40fd3
SW
93 qemu_irq *i8259;
94} MaltaState;
95
64d7e9a4 96static ISADevice *pit;
5856de80 97
7df526e3
TS
98static struct _loaderparams {
99 int ram_size;
100 const char *kernel_filename;
101 const char *kernel_cmdline;
102 const char *initrd_filename;
103} loaderparams;
104
5856de80
TS
105/* Malta FPGA */
106static void malta_fpga_update_display(void *opaque)
107{
108 char leds_text[9];
109 int i;
110 MaltaFPGAState *s = opaque;
111
07cf0ba0
TS
112 for (i = 7 ; i >= 0 ; i--) {
113 if (s->leds & (1 << i))
114 leds_text[i] = '#';
115 else
116 leds_text[i] = ' ';
87ee1669 117 }
07cf0ba0
TS
118 leds_text[8] = '\0';
119
e7e71b0e
AL
120 qemu_chr_fe_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text);
121 qemu_chr_fe_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text);
5856de80
TS
122}
123
130751ee
TS
124/*
125 * EEPROM 24C01 / 24C02 emulation.
126 *
127 * Emulation for serial EEPROMs:
128 * 24C01 - 1024 bit (128 x 8)
129 * 24C02 - 2048 bit (256 x 8)
130 *
131 * Typical device names include Microchip 24C02SC or SGS Thomson ST24C02.
132 */
133
134//~ #define DEBUG
135
136#if defined(DEBUG)
001faf32 137# define logout(fmt, ...) fprintf(stderr, "MALTA\t%-24s" fmt, __func__, ## __VA_ARGS__)
130751ee 138#else
001faf32 139# define logout(fmt, ...) ((void)0)
130751ee
TS
140#endif
141
c227f099 142struct _eeprom24c0x_t {
130751ee
TS
143 uint8_t tick;
144 uint8_t address;
145 uint8_t command;
146 uint8_t ack;
147 uint8_t scl;
148 uint8_t sda;
149 uint8_t data;
150 //~ uint16_t size;
151 uint8_t contents[256];
152};
153
c227f099 154typedef struct _eeprom24c0x_t eeprom24c0x_t;
130751ee 155
35c64807 156static eeprom24c0x_t spd_eeprom = {
284b08f1 157 .contents = {
02bccc77 158 /* 00000000: */ 0x80,0x08,0xFF,0x0D,0x0A,0xFF,0x40,0x00,
130751ee 159 /* 00000008: */ 0x01,0x75,0x54,0x00,0x82,0x08,0x00,0x01,
02bccc77
PB
160 /* 00000010: */ 0x8F,0x04,0x02,0x01,0x01,0x00,0x00,0x00,
161 /* 00000018: */ 0x00,0x00,0x00,0x14,0x0F,0x14,0x2D,0xFF,
130751ee
TS
162 /* 00000020: */ 0x15,0x08,0x15,0x08,0x00,0x00,0x00,0x00,
163 /* 00000028: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
164 /* 00000030: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
165 /* 00000038: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x12,0xD0,
166 /* 00000040: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
167 /* 00000048: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
168 /* 00000050: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
169 /* 00000058: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
170 /* 00000060: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
171 /* 00000068: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
172 /* 00000070: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
173 /* 00000078: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x64,0xF4,
174 },
175};
176
35c64807 177static void generate_eeprom_spd(uint8_t *eeprom, ram_addr_t ram_size)
02bccc77
PB
178{
179 enum { SDR = 0x4, DDR2 = 0x8 } type;
35c64807 180 uint8_t *spd = spd_eeprom.contents;
02bccc77
PB
181 uint8_t nbanks = 0;
182 uint16_t density = 0;
183 int i;
184
185 /* work in terms of MB */
186 ram_size >>= 20;
187
188 while ((ram_size >= 4) && (nbanks <= 2)) {
189 int sz_log2 = MIN(31 - clz32(ram_size), 14);
190 nbanks++;
191 density |= 1 << (sz_log2 - 2);
192 ram_size -= 1 << sz_log2;
193 }
194
195 /* split to 2 banks if possible */
196 if ((nbanks == 1) && (density > 1)) {
197 nbanks++;
198 density >>= 1;
199 }
200
201 if (density & 0xff00) {
202 density = (density & 0xe0) | ((density >> 8) & 0x1f);
203 type = DDR2;
204 } else if (!(density & 0x1f)) {
205 type = DDR2;
206 } else {
207 type = SDR;
208 }
209
210 if (ram_size) {
211 fprintf(stderr, "Warning: SPD cannot represent final %dMB"
212 " of SDRAM\n", (int)ram_size);
213 }
214
215 /* fill in SPD memory information */
216 spd[2] = type;
217 spd[5] = nbanks;
218 spd[31] = density;
219
220 /* checksum */
221 spd[63] = 0;
222 for (i = 0; i < 63; i++) {
223 spd[63] += spd[i];
224 }
35c64807
PB
225
226 /* copy for SMBUS */
227 memcpy(eeprom, spd, sizeof(spd_eeprom.contents));
228}
229
230static void generate_eeprom_serial(uint8_t *eeprom)
231{
232 int i, pos = 0;
233 uint8_t mac[6] = { 0x00 };
234 uint8_t sn[5] = { 0x01, 0x23, 0x45, 0x67, 0x89 };
235
236 /* version */
237 eeprom[pos++] = 0x01;
238
239 /* count */
240 eeprom[pos++] = 0x02;
241
242 /* MAC address */
243 eeprom[pos++] = 0x01; /* MAC */
244 eeprom[pos++] = 0x06; /* length */
245 memcpy(&eeprom[pos], mac, sizeof(mac));
246 pos += sizeof(mac);
247
248 /* serial number */
249 eeprom[pos++] = 0x02; /* serial */
250 eeprom[pos++] = 0x05; /* length */
251 memcpy(&eeprom[pos], sn, sizeof(sn));
252 pos += sizeof(sn);
253
254 /* checksum */
255 eeprom[pos] = 0;
256 for (i = 0; i < pos; i++) {
257 eeprom[pos] += eeprom[i];
258 }
02bccc77
PB
259}
260
35c64807 261static uint8_t eeprom24c0x_read(eeprom24c0x_t *eeprom)
130751ee
TS
262{
263 logout("%u: scl = %u, sda = %u, data = 0x%02x\n",
35c64807
PB
264 eeprom->tick, eeprom->scl, eeprom->sda, eeprom->data);
265 return eeprom->sda;
130751ee
TS
266}
267
35c64807 268static void eeprom24c0x_write(eeprom24c0x_t *eeprom, int scl, int sda)
130751ee 269{
35c64807 270 if (eeprom->scl && scl && (eeprom->sda != sda)) {
130751ee 271 logout("%u: scl = %u->%u, sda = %u->%u i2c %s\n",
35c64807
PB
272 eeprom->tick, eeprom->scl, scl, eeprom->sda, sda,
273 sda ? "stop" : "start");
130751ee 274 if (!sda) {
35c64807
PB
275 eeprom->tick = 1;
276 eeprom->command = 0;
130751ee 277 }
35c64807 278 } else if (eeprom->tick == 0 && !eeprom->ack) {
130751ee
TS
279 /* Waiting for start. */
280 logout("%u: scl = %u->%u, sda = %u->%u wait for i2c start\n",
35c64807
PB
281 eeprom->tick, eeprom->scl, scl, eeprom->sda, sda);
282 } else if (!eeprom->scl && scl) {
130751ee 283 logout("%u: scl = %u->%u, sda = %u->%u trigger bit\n",
35c64807
PB
284 eeprom->tick, eeprom->scl, scl, eeprom->sda, sda);
285 if (eeprom->ack) {
130751ee
TS
286 logout("\ti2c ack bit = 0\n");
287 sda = 0;
35c64807
PB
288 eeprom->ack = 0;
289 } else if (eeprom->sda == sda) {
130751ee
TS
290 uint8_t bit = (sda != 0);
291 logout("\ti2c bit = %d\n", bit);
35c64807
PB
292 if (eeprom->tick < 9) {
293 eeprom->command <<= 1;
294 eeprom->command += bit;
295 eeprom->tick++;
296 if (eeprom->tick == 9) {
297 logout("\tcommand 0x%04x, %s\n", eeprom->command,
298 bit ? "read" : "write");
299 eeprom->ack = 1;
130751ee 300 }
35c64807
PB
301 } else if (eeprom->tick < 17) {
302 if (eeprom->command & 1) {
303 sda = ((eeprom->data & 0x80) != 0);
130751ee 304 }
35c64807
PB
305 eeprom->address <<= 1;
306 eeprom->address += bit;
307 eeprom->tick++;
308 eeprom->data <<= 1;
309 if (eeprom->tick == 17) {
310 eeprom->data = eeprom->contents[eeprom->address];
311 logout("\taddress 0x%04x, data 0x%02x\n",
312 eeprom->address, eeprom->data);
313 eeprom->ack = 1;
314 eeprom->tick = 0;
130751ee 315 }
35c64807 316 } else if (eeprom->tick >= 17) {
130751ee
TS
317 sda = 0;
318 }
319 } else {
320 logout("\tsda changed with raising scl\n");
321 }
322 } else {
35c64807
PB
323 logout("%u: scl = %u->%u, sda = %u->%u\n", eeprom->tick, eeprom->scl,
324 scl, eeprom->sda, sda);
130751ee 325 }
35c64807
PB
326 eeprom->scl = scl;
327 eeprom->sda = sda;
130751ee
TS
328}
329
a8170e5e 330static uint64_t malta_fpga_read(void *opaque, hwaddr addr,
ea85df72 331 unsigned size)
5856de80
TS
332{
333 MaltaFPGAState *s = opaque;
334 uint32_t val = 0;
335 uint32_t saddr;
336
337 saddr = (addr & 0xfffff);
338
339 switch (saddr) {
340
341 /* SWITCH Register */
342 case 0x00200:
343 val = 0x00000000; /* All switches closed */
593c0d10 344 break;
5856de80
TS
345
346 /* STATUS Register */
347 case 0x00208:
348#ifdef TARGET_WORDS_BIGENDIAN
349 val = 0x00000012;
350#else
351 val = 0x00000010;
352#endif
353 break;
354
355 /* JMPRS Register */
356 case 0x00210:
357 val = 0x00;
358 break;
359
360 /* LEDBAR Register */
361 case 0x00408:
362 val = s->leds;
363 break;
364
365 /* BRKRES Register */
366 case 0x00508:
367 val = s->brk;
368 break;
369
b6dc7ebb 370 /* UART Registers are handled directly by the serial device */
a4bc3afc 371
5856de80
TS
372 /* GPOUT Register */
373 case 0x00a00:
374 val = s->gpout;
375 break;
376
377 /* XXX: implement a real I2C controller */
378
379 /* GPINP Register */
380 case 0x00a08:
381 /* IN = OUT until a real I2C control is implemented */
382 if (s->i2csel)
383 val = s->i2cout;
384 else
385 val = 0x00;
386 break;
387
388 /* I2CINP Register */
389 case 0x00b00:
35c64807 390 val = ((s->i2cin & ~1) | eeprom24c0x_read(&spd_eeprom));
5856de80
TS
391 break;
392
393 /* I2COE Register */
394 case 0x00b08:
395 val = s->i2coe;
396 break;
397
398 /* I2COUT Register */
399 case 0x00b10:
400 val = s->i2cout;
401 break;
402
403 /* I2CSEL Register */
404 case 0x00b18:
130751ee 405 val = s->i2csel;
5856de80
TS
406 break;
407
408 default:
409#if 0
3594c774 410 printf ("malta_fpga_read: Bad register offset 0x" TARGET_FMT_lx "\n",
593c0d10 411 addr);
5856de80
TS
412#endif
413 break;
414 }
415 return val;
416}
417
a8170e5e 418static void malta_fpga_write(void *opaque, hwaddr addr,
ea85df72 419 uint64_t val, unsigned size)
5856de80
TS
420{
421 MaltaFPGAState *s = opaque;
422 uint32_t saddr;
423
424 saddr = (addr & 0xfffff);
425
426 switch (saddr) {
427
428 /* SWITCH Register */
429 case 0x00200:
430 break;
431
432 /* JMPRS Register */
433 case 0x00210:
434 break;
435
436 /* LEDBAR Register */
5856de80
TS
437 case 0x00408:
438 s->leds = val & 0xff;
1d7a1197 439 malta_fpga_update_display(s);
5856de80
TS
440 break;
441
442 /* ASCIIWORD Register */
443 case 0x00410:
ea85df72 444 snprintf(s->display_text, 9, "%08X", (uint32_t)val);
5856de80
TS
445 malta_fpga_update_display(s);
446 break;
447
448 /* ASCIIPOS0 to ASCIIPOS7 Registers */
449 case 0x00418:
450 case 0x00420:
451 case 0x00428:
452 case 0x00430:
453 case 0x00438:
454 case 0x00440:
455 case 0x00448:
456 case 0x00450:
457 s->display_text[(saddr - 0x00418) >> 3] = (char) val;
458 malta_fpga_update_display(s);
459 break;
460
461 /* SOFTRES Register */
462 case 0x00500:
463 if (val == 0x42)
464 qemu_system_reset_request ();
465 break;
466
467 /* BRKRES Register */
468 case 0x00508:
469 s->brk = val & 0xff;
470 break;
471
b6dc7ebb 472 /* UART Registers are handled directly by the serial device */
a4bc3afc 473
5856de80
TS
474 /* GPOUT Register */
475 case 0x00a00:
476 s->gpout = val & 0xff;
477 break;
478
479 /* I2COE Register */
480 case 0x00b08:
481 s->i2coe = val & 0x03;
482 break;
483
484 /* I2COUT Register */
485 case 0x00b10:
35c64807 486 eeprom24c0x_write(&spd_eeprom, val & 0x02, val & 0x01);
130751ee 487 s->i2cout = val;
5856de80
TS
488 break;
489
490 /* I2CSEL Register */
491 case 0x00b18:
130751ee 492 s->i2csel = val & 0x01;
5856de80
TS
493 break;
494
495 default:
496#if 0
3594c774 497 printf ("malta_fpga_write: Bad register offset 0x" TARGET_FMT_lx "\n",
593c0d10 498 addr);
5856de80
TS
499#endif
500 break;
501 }
502}
503
ea85df72
AK
504static const MemoryRegionOps malta_fpga_ops = {
505 .read = malta_fpga_read,
506 .write = malta_fpga_write,
507 .endianness = DEVICE_NATIVE_ENDIAN,
5856de80
TS
508};
509
9596ebb7 510static void malta_fpga_reset(void *opaque)
5856de80
TS
511{
512 MaltaFPGAState *s = opaque;
513
514 s->leds = 0x00;
515 s->brk = 0x0a;
516 s->gpout = 0x00;
130751ee 517 s->i2cin = 0x3;
5856de80
TS
518 s->i2coe = 0x0;
519 s->i2cout = 0x3;
520 s->i2csel = 0x1;
521
522 s->display_text[8] = '\0';
523 snprintf(s->display_text, 9, " ");
ceecf1d1
AJ
524}
525
ceecf1d1
AJ
526static void malta_fpga_led_init(CharDriverState *chr)
527{
e7e71b0e
AL
528 qemu_chr_fe_printf(chr, "\e[HMalta LEDBAR\r\n");
529 qemu_chr_fe_printf(chr, "+--------+\r\n");
530 qemu_chr_fe_printf(chr, "+ +\r\n");
531 qemu_chr_fe_printf(chr, "+--------+\r\n");
532 qemu_chr_fe_printf(chr, "\n");
533 qemu_chr_fe_printf(chr, "Malta ASCII\r\n");
534 qemu_chr_fe_printf(chr, "+--------+\r\n");
535 qemu_chr_fe_printf(chr, "+ +\r\n");
536 qemu_chr_fe_printf(chr, "+--------+\r\n");
5856de80
TS
537}
538
ea85df72 539static MaltaFPGAState *malta_fpga_init(MemoryRegion *address_space,
a8170e5e 540 hwaddr base, qemu_irq uart_irq, CharDriverState *uart_chr)
5856de80
TS
541{
542 MaltaFPGAState *s;
5856de80 543
7267c094 544 s = (MaltaFPGAState *)g_malloc0(sizeof(MaltaFPGAState));
5856de80 545
2c9b15ca 546 memory_region_init_io(&s->iomem, NULL, &malta_fpga_ops, s,
ea85df72 547 "malta-fpga", 0x100000);
2c9b15ca 548 memory_region_init_alias(&s->iomem_lo, NULL, "malta-fpga",
ea85df72 549 &s->iomem, 0, 0x900);
2c9b15ca 550 memory_region_init_alias(&s->iomem_hi, NULL, "malta-fpga",
ea85df72 551 &s->iomem, 0xa00, 0x10000-0xa00);
a4bc3afc 552
ea85df72
AK
553 memory_region_add_subregion(address_space, base, &s->iomem_lo);
554 memory_region_add_subregion(address_space, base + 0xa00, &s->iomem_hi);
5856de80 555
27143a44 556 s->display = qemu_chr_new("fpga", "vc:320x200", malta_fpga_led_init);
ceecf1d1 557
39186d8a
RH
558 s->uart = serial_mm_init(address_space, base + 0x900, 3, uart_irq,
559 230400, uart_chr, DEVICE_NATIVE_ENDIAN);
a4bc3afc 560
5856de80 561 malta_fpga_reset(s);
a08d4367 562 qemu_register_reset(malta_fpga_reset, s);
5856de80
TS
563
564 return s;
565}
566
5856de80 567/* Network support */
29b358f9 568static void network_init(PCIBus *pci_bus)
5856de80
TS
569{
570 int i;
5856de80
TS
571
572 for(i = 0; i < nb_nics; i++) {
cb457d76 573 NICInfo *nd = &nd_table[i];
5607c388 574 const char *default_devaddr = NULL;
cb457d76
AL
575
576 if (i == 0 && (!nd->model || strcmp(nd->model, "pcnet") == 0))
5856de80 577 /* The malta board has a PCNet card using PCI SLOT 11 */
5607c388 578 default_devaddr = "0b";
cb457d76 579
29b358f9 580 pci_nic_init_nofail(nd, pci_bus, "pcnet", default_devaddr);
5856de80
TS
581 }
582}
583
584/* ROM and pseudo bootloader
585
586 The following code implements a very very simple bootloader. It first
587 loads the registers a0 to a3 to the values expected by the OS, and
588 then jump at the kernel address.
589
590 The bootloader should pass the locations of the kernel arguments and
591 environment variables tables. Those tables contain the 32-bit address
592 of NULL terminated strings. The environment variables table should be
593 terminated by a NULL address.
594
595 For a simpler implementation, the number of kernel arguments is fixed
596 to two (the name of the kernel and the command line), and the two
597 tables are actually the same one.
598
599 The registers a0 to a3 should contain the following values:
600 a0 - number of kernel arguments
601 a1 - 32-bit address of the kernel arguments table
602 a2 - 32-bit address of the environment variables table
603 a3 - RAM size in bytes
604*/
605
61c56c8c 606static void write_bootloader (CPUMIPSState *env, uint8_t *base,
b0311811 607 int64_t run_addr, int64_t kernel_entry)
5856de80
TS
608{
609 uint32_t *p;
610
611 /* Small bootloader */
d7585251 612 p = (uint32_t *)base;
b0311811
JH
613
614 stl_p(p++, 0x08000000 | /* j 0x1fc00580 */
615 ((run_addr + 0x580) & 0x0fffffff) >> 2);
0983979b 616 stl_p(p++, 0x00000000); /* nop */
5856de80 617
26ea0918 618 /* YAMON service vector */
b0311811
JH
619 stl_p(base + 0x500, run_addr + 0x0580); /* start: */
620 stl_p(base + 0x504, run_addr + 0x083c); /* print_count: */
621 stl_p(base + 0x520, run_addr + 0x0580); /* start: */
622 stl_p(base + 0x52c, run_addr + 0x0800); /* flush_cache: */
623 stl_p(base + 0x534, run_addr + 0x0808); /* print: */
624 stl_p(base + 0x538, run_addr + 0x0800); /* reg_cpu_isr: */
625 stl_p(base + 0x53c, run_addr + 0x0800); /* unred_cpu_isr: */
626 stl_p(base + 0x540, run_addr + 0x0800); /* reg_ic_isr: */
627 stl_p(base + 0x544, run_addr + 0x0800); /* unred_ic_isr: */
628 stl_p(base + 0x548, run_addr + 0x0800); /* reg_esr: */
629 stl_p(base + 0x54c, run_addr + 0x0800); /* unreg_esr: */
630 stl_p(base + 0x550, run_addr + 0x0800); /* getchar: */
631 stl_p(base + 0x554, run_addr + 0x0800); /* syscon_read: */
26ea0918
TS
632
633
5856de80 634 /* Second part of the bootloader */
d7585251 635 p = (uint32_t *) (base + 0x580);
0983979b
PB
636 stl_p(p++, 0x24040002); /* addiu a0, zero, 2 */
637 stl_p(p++, 0x3c1d0000 | (((ENVP_ADDR - 64) >> 16) & 0xffff)); /* lui sp, high(ENVP_ADDR) */
638 stl_p(p++, 0x37bd0000 | ((ENVP_ADDR - 64) & 0xffff)); /* ori sp, sp, low(ENVP_ADDR) */
639 stl_p(p++, 0x3c050000 | ((ENVP_ADDR >> 16) & 0xffff)); /* lui a1, high(ENVP_ADDR) */
640 stl_p(p++, 0x34a50000 | (ENVP_ADDR & 0xffff)); /* ori a1, a1, low(ENVP_ADDR) */
641 stl_p(p++, 0x3c060000 | (((ENVP_ADDR + 8) >> 16) & 0xffff)); /* lui a2, high(ENVP_ADDR + 8) */
642 stl_p(p++, 0x34c60000 | ((ENVP_ADDR + 8) & 0xffff)); /* ori a2, a2, low(ENVP_ADDR + 8) */
643 stl_p(p++, 0x3c070000 | (loaderparams.ram_size >> 16)); /* lui a3, high(ram_size) */
644 stl_p(p++, 0x34e70000 | (loaderparams.ram_size & 0xffff)); /* ori a3, a3, low(ram_size) */
2802bfe3
TS
645
646 /* Load BAR registers as done by YAMON */
0983979b 647 stl_p(p++, 0x3c09b400); /* lui t1, 0xb400 */
a0a8793e
TS
648
649#ifdef TARGET_WORDS_BIGENDIAN
0983979b 650 stl_p(p++, 0x3c08df00); /* lui t0, 0xdf00 */
a0a8793e 651#else
0983979b 652 stl_p(p++, 0x340800df); /* ori t0, r0, 0x00df */
a0a8793e 653#endif
0983979b 654 stl_p(p++, 0xad280068); /* sw t0, 0x0068(t1) */
a0a8793e 655
0983979b 656 stl_p(p++, 0x3c09bbe0); /* lui t1, 0xbbe0 */
2802bfe3
TS
657
658#ifdef TARGET_WORDS_BIGENDIAN
0983979b 659 stl_p(p++, 0x3c08c000); /* lui t0, 0xc000 */
2802bfe3 660#else
0983979b 661 stl_p(p++, 0x340800c0); /* ori t0, r0, 0x00c0 */
2802bfe3 662#endif
0983979b 663 stl_p(p++, 0xad280048); /* sw t0, 0x0048(t1) */
2802bfe3 664#ifdef TARGET_WORDS_BIGENDIAN
0983979b 665 stl_p(p++, 0x3c084000); /* lui t0, 0x4000 */
2802bfe3 666#else
0983979b 667 stl_p(p++, 0x34080040); /* ori t0, r0, 0x0040 */
2802bfe3 668#endif
0983979b 669 stl_p(p++, 0xad280050); /* sw t0, 0x0050(t1) */
2802bfe3
TS
670
671#ifdef TARGET_WORDS_BIGENDIAN
0983979b 672 stl_p(p++, 0x3c088000); /* lui t0, 0x8000 */
2802bfe3 673#else
0983979b 674 stl_p(p++, 0x34080080); /* ori t0, r0, 0x0080 */
2802bfe3 675#endif
0983979b 676 stl_p(p++, 0xad280058); /* sw t0, 0x0058(t1) */
2802bfe3 677#ifdef TARGET_WORDS_BIGENDIAN
0983979b 678 stl_p(p++, 0x3c083f00); /* lui t0, 0x3f00 */
2802bfe3 679#else
0983979b 680 stl_p(p++, 0x3408003f); /* ori t0, r0, 0x003f */
2802bfe3 681#endif
0983979b 682 stl_p(p++, 0xad280060); /* sw t0, 0x0060(t1) */
2802bfe3
TS
683
684#ifdef TARGET_WORDS_BIGENDIAN
0983979b 685 stl_p(p++, 0x3c08c100); /* lui t0, 0xc100 */
2802bfe3 686#else
0983979b 687 stl_p(p++, 0x340800c1); /* ori t0, r0, 0x00c1 */
2802bfe3 688#endif
0983979b 689 stl_p(p++, 0xad280080); /* sw t0, 0x0080(t1) */
2802bfe3 690#ifdef TARGET_WORDS_BIGENDIAN
0983979b 691 stl_p(p++, 0x3c085e00); /* lui t0, 0x5e00 */
2802bfe3 692#else
0983979b 693 stl_p(p++, 0x3408005e); /* ori t0, r0, 0x005e */
2802bfe3 694#endif
0983979b 695 stl_p(p++, 0xad280088); /* sw t0, 0x0088(t1) */
2802bfe3
TS
696
697 /* Jump to kernel code */
0983979b
PB
698 stl_p(p++, 0x3c1f0000 | ((kernel_entry >> 16) & 0xffff)); /* lui ra, high(kernel_entry) */
699 stl_p(p++, 0x37ff0000 | (kernel_entry & 0xffff)); /* ori ra, ra, low(kernel_entry) */
700 stl_p(p++, 0x03e00008); /* jr ra */
701 stl_p(p++, 0x00000000); /* nop */
26ea0918
TS
702
703 /* YAMON subroutines */
d7585251 704 p = (uint32_t *) (base + 0x800);
0983979b
PB
705 stl_p(p++, 0x03e00008); /* jr ra */
706 stl_p(p++, 0x24020000); /* li v0,0 */
b0311811 707 /* 808 YAMON print */
0983979b
PB
708 stl_p(p++, 0x03e06821); /* move t5,ra */
709 stl_p(p++, 0x00805821); /* move t3,a0 */
710 stl_p(p++, 0x00a05021); /* move t2,a1 */
711 stl_p(p++, 0x91440000); /* lbu a0,0(t2) */
712 stl_p(p++, 0x254a0001); /* addiu t2,t2,1 */
713 stl_p(p++, 0x10800005); /* beqz a0,834 */
714 stl_p(p++, 0x00000000); /* nop */
715 stl_p(p++, 0x0ff0021c); /* jal 870 */
716 stl_p(p++, 0x00000000); /* nop */
717 stl_p(p++, 0x08000205); /* j 814 */
718 stl_p(p++, 0x00000000); /* nop */
719 stl_p(p++, 0x01a00008); /* jr t5 */
720 stl_p(p++, 0x01602021); /* move a0,t3 */
26ea0918 721 /* 0x83c YAMON print_count */
0983979b
PB
722 stl_p(p++, 0x03e06821); /* move t5,ra */
723 stl_p(p++, 0x00805821); /* move t3,a0 */
724 stl_p(p++, 0x00a05021); /* move t2,a1 */
725 stl_p(p++, 0x00c06021); /* move t4,a2 */
726 stl_p(p++, 0x91440000); /* lbu a0,0(t2) */
727 stl_p(p++, 0x0ff0021c); /* jal 870 */
728 stl_p(p++, 0x00000000); /* nop */
729 stl_p(p++, 0x254a0001); /* addiu t2,t2,1 */
730 stl_p(p++, 0x258cffff); /* addiu t4,t4,-1 */
731 stl_p(p++, 0x1580fffa); /* bnez t4,84c */
732 stl_p(p++, 0x00000000); /* nop */
733 stl_p(p++, 0x01a00008); /* jr t5 */
734 stl_p(p++, 0x01602021); /* move a0,t3 */
26ea0918 735 /* 0x870 */
0983979b
PB
736 stl_p(p++, 0x3c08b800); /* lui t0,0xb400 */
737 stl_p(p++, 0x350803f8); /* ori t0,t0,0x3f8 */
738 stl_p(p++, 0x91090005); /* lbu t1,5(t0) */
739 stl_p(p++, 0x00000000); /* nop */
740 stl_p(p++, 0x31290040); /* andi t1,t1,0x40 */
741 stl_p(p++, 0x1120fffc); /* beqz t1,878 <outch+0x8> */
742 stl_p(p++, 0x00000000); /* nop */
743 stl_p(p++, 0x03e00008); /* jr ra */
744 stl_p(p++, 0xa1040000); /* sb a0,0(t0) */
26ea0918 745
5856de80
TS
746}
747
8b7968f7
SW
748static void GCC_FMT_ATTR(3, 4) prom_set(uint32_t* prom_buf, int index,
749 const char *string, ...)
5856de80
TS
750{
751 va_list ap;
3ddd0065 752 int32_t table_addr;
5856de80
TS
753
754 if (index >= ENVP_NB_ENTRIES)
755 return;
756
5856de80 757 if (string == NULL) {
c938ada2 758 prom_buf[index] = 0;
5856de80
TS
759 return;
760 }
761
c938ada2
AJ
762 table_addr = sizeof(int32_t) * ENVP_NB_ENTRIES + index * ENVP_ENTRY_SIZE;
763 prom_buf[index] = tswap32(ENVP_ADDR + table_addr);
5856de80
TS
764
765 va_start(ap, string);
c938ada2 766 vsnprintf((char *)prom_buf + table_addr, ENVP_ENTRY_SIZE, string, ap);
5856de80
TS
767 va_end(ap);
768}
769
770/* Kernel */
e16ad5b0 771static int64_t load_kernel (void)
5856de80 772{
409dbce5 773 int64_t kernel_entry, kernel_high;
5856de80 774 long initrd_size;
c227f099 775 ram_addr_t initrd_offset;
ca20cf32 776 int big_endian;
c938ada2
AJ
777 uint32_t *prom_buf;
778 long prom_size;
779 int prom_index = 0;
b0311811 780 uint64_t (*xlate_to_kseg0) (void *opaque, uint64_t addr);
ca20cf32
BS
781
782#ifdef TARGET_WORDS_BIGENDIAN
783 big_endian = 1;
784#else
785 big_endian = 0;
786#endif
5856de80 787
409dbce5
AJ
788 if (load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_to_phys, NULL,
789 (uint64_t *)&kernel_entry, NULL, (uint64_t *)&kernel_high,
790 big_endian, ELF_MACHINE, 1) < 0) {
5856de80 791 fprintf(stderr, "qemu: could not load kernel '%s'\n",
7df526e3 792 loaderparams.kernel_filename);
acdf72bb 793 exit(1);
5856de80 794 }
b0311811
JH
795 if (kvm_enabled()) {
796 xlate_to_kseg0 = cpu_mips_kvm_um_phys_to_kseg0;
797 } else {
798 xlate_to_kseg0 = cpu_mips_phys_to_kseg0;
799 }
5856de80
TS
800
801 /* load initrd */
802 initrd_size = 0;
74287114 803 initrd_offset = 0;
7df526e3
TS
804 if (loaderparams.initrd_filename) {
805 initrd_size = get_image_size (loaderparams.initrd_filename);
74287114 806 if (initrd_size > 0) {
05b3274b 807 initrd_offset = (kernel_high + ~INITRD_PAGE_MASK) & INITRD_PAGE_MASK;
7df526e3 808 if (initrd_offset + initrd_size > ram_size) {
74287114
TS
809 fprintf(stderr,
810 "qemu: memory too small for initial ram disk '%s'\n",
7df526e3 811 loaderparams.initrd_filename);
74287114
TS
812 exit(1);
813 }
dcac9679
PB
814 initrd_size = load_image_targphys(loaderparams.initrd_filename,
815 initrd_offset,
816 ram_size - initrd_offset);
74287114 817 }
5856de80
TS
818 if (initrd_size == (target_ulong) -1) {
819 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
7df526e3 820 loaderparams.initrd_filename);
5856de80
TS
821 exit(1);
822 }
823 }
824
c938ada2
AJ
825 /* Setup prom parameters. */
826 prom_size = ENVP_NB_ENTRIES * (sizeof(int32_t) + ENVP_ENTRY_SIZE);
7267c094 827 prom_buf = g_malloc(prom_size);
c938ada2 828
f36d53ef 829 prom_set(prom_buf, prom_index++, "%s", loaderparams.kernel_filename);
c938ada2 830 if (initrd_size > 0) {
409dbce5 831 prom_set(prom_buf, prom_index++, "rd_start=0x%" PRIx64 " rd_size=%li %s",
b0311811 832 xlate_to_kseg0(NULL, initrd_offset), initrd_size,
7df526e3 833 loaderparams.kernel_cmdline);
c938ada2 834 } else {
f36d53ef 835 prom_set(prom_buf, prom_index++, "%s", loaderparams.kernel_cmdline);
c938ada2
AJ
836 }
837
838 prom_set(prom_buf, prom_index++, "memsize");
94c2b6af
PB
839 prom_set(prom_buf, prom_index++, "%i",
840 MIN(loaderparams.ram_size, 256 << 20));
b0311811 841
c938ada2
AJ
842 prom_set(prom_buf, prom_index++, "modetty0");
843 prom_set(prom_buf, prom_index++, "38400n8r");
844 prom_set(prom_buf, prom_index++, NULL);
845
846 rom_add_blob_fixed("prom", prom_buf, prom_size,
409dbce5 847 cpu_mips_kseg0_to_phys(NULL, ENVP_ADDR));
5856de80 848
74287114 849 return kernel_entry;
5856de80
TS
850}
851
ce3960eb 852static void malta_mips_config(MIPSCPU *cpu)
c4cb2578 853{
ce3960eb
AF
854 CPUMIPSState *env = &cpu->env;
855 CPUState *cs = CPU(cpu);
856
c4cb2578 857 env->mvp->CP0_MVPConf0 |= ((smp_cpus - 1) << CP0MVPC0_PVPE) |
ce3960eb 858 ((smp_cpus * cs->nr_threads - 1) << CP0MVPC0_PTC);
c4cb2578
EI
859}
860
5856de80
TS
861static void main_cpu_reset(void *opaque)
862{
1004ee8d
AF
863 MIPSCPU *cpu = opaque;
864 CPUMIPSState *env = &cpu->env;
865
866 cpu_reset(CPU(cpu));
5856de80 867
5c43485f 868 /* The bootloader does not need to be rewritten as it is located in a
5856de80
TS
869 read only location. The kernel location and the arguments table
870 location does not change. */
7df526e3 871 if (loaderparams.kernel_filename) {
fb82fea0 872 env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
fb82fea0 873 }
c4cb2578 874
ce3960eb 875 malta_mips_config(cpu);
b0311811
JH
876
877 if (kvm_enabled()) {
878 /* Start running from the bootloader we wrote to end of RAM */
879 env->active_tc.PC = 0x40000000 + loaderparams.ram_size;
880 }
5856de80
TS
881}
882
4556bd8b
BS
883static void cpu_request_exit(void *opaque, int irq, int level)
884{
4917cf44 885 CPUState *cpu = current_cpu;
4556bd8b 886
4917cf44
AF
887 if (cpu && level) {
888 cpu_exit(cpu);
4556bd8b
BS
889 }
890}
891
70705261 892static
3ef96221 893void mips_malta_init(MachineState *machine)
5856de80 894{
3ef96221 895 ram_addr_t ram_size = machine->ram_size;
b0311811 896 ram_addr_t ram_low_size;
3ef96221
MA
897 const char *cpu_model = machine->cpu_model;
898 const char *kernel_filename = machine->kernel_filename;
899 const char *kernel_cmdline = machine->kernel_cmdline;
900 const char *initrd_filename = machine->initrd_filename;
5cea8590 901 char *filename;
cfe5f011 902 pflash_t *fl;
cfe5f011 903 MemoryRegion *system_memory = get_system_memory();
94c2b6af
PB
904 MemoryRegion *ram_high = g_new(MemoryRegion, 1);
905 MemoryRegion *ram_low_preio = g_new(MemoryRegion, 1);
906 MemoryRegion *ram_low_postio;
a427338b 907 MemoryRegion *bios, *bios_copy = g_new(MemoryRegion, 1);
03a1a8e1 908 target_long bios_size = FLASH_SIZE;
35c64807
PB
909 const size_t smbus_eeprom_size = 8 * 256;
910 uint8_t *smbus_eeprom_buf = g_malloc0(smbus_eeprom_size);
b0311811 911 int64_t kernel_entry, bootloader_run_addr;
5856de80 912 PCIBus *pci_bus;
48a18b3c 913 ISABus *isa_bus;
7688b134 914 MIPSCPU *cpu;
61c56c8c 915 CPUMIPSState *env;
e9b40fd3 916 qemu_irq *isa_irq;
4556bd8b 917 qemu_irq *cpu_exit_irq;
7b717336 918 int piix4_devfn;
a5c82852 919 I2CBus *smbus;
7b717336 920 int i;
751c6a17 921 DriveInfo *dinfo;
f455e98c 922 DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
fd8014e1 923 DriveInfo *fd[MAX_FD];
c8b153d7 924 int fl_idx = 0;
bb4b3358 925 int fl_sectors = bios_size >> 16;
01e0451a 926 int be;
5856de80 927
cba5cb67
AF
928 DeviceState *dev = qdev_create(NULL, TYPE_MIPS_MALTA);
929 MaltaState *s = MIPS_MALTA(dev);
e9b40fd3 930
cc413a39
AJ
931 /* The whole address space decoded by the GT-64120A doesn't generate
932 exception when accessing invalid memory. Create an empty slot to
933 emulate this feature. */
934 empty_slot_init(0, 0x20000000);
935
e9b40fd3
SW
936 qdev_init_nofail(dev);
937
ffabf037
AJ
938 /* Make sure the first 3 serial ports are associated with a device. */
939 for(i = 0; i < 3; i++) {
940 if (!serial_hds[i]) {
941 char label[32];
942 snprintf(label, sizeof(label), "serial%d", i);
27143a44 943 serial_hds[i] = qemu_chr_new(label, "null", NULL);
ffabf037
AJ
944 }
945 }
946
33d68b5f
TS
947 /* init CPUs */
948 if (cpu_model == NULL) {
60aa19ab 949#ifdef TARGET_MIPS64
c9c1a064 950 cpu_model = "20Kc";
33d68b5f 951#else
1c32f43e 952 cpu_model = "24Kf";
33d68b5f
TS
953#endif
954 }
c4cb2578
EI
955
956 for (i = 0; i < smp_cpus; i++) {
7688b134
AF
957 cpu = cpu_mips_init(cpu_model);
958 if (cpu == NULL) {
c4cb2578
EI
959 fprintf(stderr, "Unable to find CPU definition\n");
960 exit(1);
961 }
7688b134
AF
962 env = &cpu->env;
963
c4cb2578
EI
964 /* Init internal devices */
965 cpu_mips_irq_init_cpu(env);
966 cpu_mips_clock_init(env);
1004ee8d 967 qemu_register_reset(main_cpu_reset, cpu);
aaed909a 968 }
182735ef
AF
969 cpu = MIPS_CPU(first_cpu);
970 env = &cpu->env;
5856de80
TS
971
972 /* allocate RAM */
94c2b6af 973 if (ram_size > (2048u << 20)) {
0ccff151 974 fprintf(stderr,
94c2b6af 975 "qemu: Too much memory for this machine: %d MB, maximum 2048 MB\n",
0ccff151
AJ
976 ((unsigned int)ram_size / (1 << 20)));
977 exit(1);
978 }
94c2b6af
PB
979
980 /* register RAM at high address where it is undisturbed by IO */
981 memory_region_init_ram(ram_high, NULL, "mips_malta.ram", ram_size);
982 vmstate_register_ram_global(ram_high);
983 memory_region_add_subregion(system_memory, 0x80000000, ram_high);
984
985 /* alias for pre IO hole access */
986 memory_region_init_alias(ram_low_preio, NULL, "mips_malta_low_preio.ram",
987 ram_high, 0, MIN(ram_size, (256 << 20)));
988 memory_region_add_subregion(system_memory, 0, ram_low_preio);
989
990 /* alias for post IO hole access, if there is enough RAM */
991 if (ram_size > (512 << 20)) {
992 ram_low_postio = g_new(MemoryRegion, 1);
993 memory_region_init_alias(ram_low_postio, NULL,
994 "mips_malta_low_postio.ram",
995 ram_high, 512 << 20,
996 ram_size - (512 << 20));
997 memory_region_add_subregion(system_memory, 512 << 20, ram_low_postio);
998 }
5856de80 999
02bccc77 1000 /* generate SPD EEPROM data */
35c64807
PB
1001 generate_eeprom_spd(&smbus_eeprom_buf[0 * 256], ram_size);
1002 generate_eeprom_serial(&smbus_eeprom_buf[6 * 256]);
02bccc77 1003
01e0451a
AL
1004#ifdef TARGET_WORDS_BIGENDIAN
1005 be = 1;
1006#else
1007 be = 0;
1008#endif
070ce5ed 1009 /* FPGA */
68d00192
AJ
1010 /* The CBUS UART is attached to the MIPS CPU INT2 pin, ie interrupt 4 */
1011 malta_fpga_init(system_memory, FPGA_ADDRESS, env->irq[4], serial_hds[2]);
070ce5ed 1012
bb4b3358
SW
1013 /* Load firmware in flash / BIOS. */
1014 dinfo = drive_get(IF_PFLASH, 0, fl_idx);
1015#ifdef DEBUG_BOARD_INIT
1016 if (dinfo) {
1017 printf("Register parallel flash %d size " TARGET_FMT_lx " at "
1018 "addr %08llx '%s' %x\n",
03a1a8e1 1019 fl_idx, bios_size, FLASH_ADDRESS,
bb4b3358
SW
1020 bdrv_get_device_name(dinfo->bdrv), fl_sectors);
1021 }
1022#endif
03a1a8e1 1023 fl = pflash_cfi01_register(FLASH_ADDRESS, NULL, "mips_malta.bios",
bb4b3358
SW
1024 BIOS_SIZE, dinfo ? dinfo->bdrv : NULL,
1025 65536, fl_sectors,
1026 4, 0x0000, 0x0000, 0x0000, 0x0000, be);
1027 bios = pflash_cfi01_get_memory(fl);
1028 fl_idx++;
c8b153d7 1029 if (kernel_filename) {
b0311811
JH
1030 ram_low_size = MIN(ram_size, 256 << 20);
1031 /* For KVM T&E we reserve 1MB of RAM for running bootloader */
1032 if (kvm_enabled()) {
1033 ram_low_size -= 0x100000;
1034 bootloader_run_addr = 0x40000000 + ram_low_size;
1035 } else {
1036 bootloader_run_addr = 0xbfc00000;
1037 }
1038
c8b153d7 1039 /* Write a small bootloader to the flash location. */
b0311811 1040 loaderparams.ram_size = ram_low_size;
c8b153d7
TS
1041 loaderparams.kernel_filename = kernel_filename;
1042 loaderparams.kernel_cmdline = kernel_cmdline;
1043 loaderparams.initrd_filename = initrd_filename;
e16ad5b0 1044 kernel_entry = load_kernel();
b0311811
JH
1045
1046 write_bootloader(env, memory_region_get_ram_ptr(bios),
1047 bootloader_run_addr, kernel_entry);
1048 if (kvm_enabled()) {
1049 /* Write the bootloader code @ the end of RAM, 1MB reserved */
1050 write_bootloader(env, memory_region_get_ram_ptr(ram_low_preio) +
1051 ram_low_size,
1052 bootloader_run_addr, kernel_entry);
1053 }
c8b153d7 1054 } else {
bb4b3358
SW
1055 /* Load firmware from flash. */
1056 if (!dinfo) {
c8b153d7 1057 /* Load a BIOS image. */
bb4b3358 1058 if (bios_name == NULL) {
c8b153d7 1059 bios_name = BIOS_FILENAME;
bb4b3358 1060 }
5cea8590
PB
1061 filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
1062 if (filename) {
03a1a8e1 1063 bios_size = load_image_targphys(filename, FLASH_ADDRESS,
5cea8590 1064 BIOS_SIZE);
7267c094 1065 g_free(filename);
5cea8590
PB
1066 } else {
1067 bios_size = -1;
1068 }
2c57bd9b
AF
1069 if ((bios_size < 0 || bios_size > BIOS_SIZE) &&
1070 !kernel_filename && !qtest_enabled()) {
2e985fe0
AJ
1071 error_report("Could not load MIPS bios '%s', and no "
1072 "-kernel argument was specified", bios_name);
1073 exit(1);
c8b153d7 1074 }
070ce5ed 1075 }
3187ef03
TS
1076 /* In little endian mode the 32bit words in the bios are swapped,
1077 a neat trick which allows bi-endian firmware. */
1078#ifndef TARGET_WORDS_BIGENDIAN
1079 {
a2b8813d
PB
1080 uint32_t *end, *addr = rom_ptr(FLASH_ADDRESS);
1081 if (!addr) {
1082 addr = memory_region_get_ram_ptr(bios);
1083 }
1817f56a 1084 end = (void *)addr + MIN(bios_size, 0x3e0000);
d7585251
PB
1085 while (addr < end) {
1086 bswap32s(addr);
a30cfee5 1087 addr++;
3187ef03
TS
1088 }
1089 }
1090#endif
070ce5ed
TS
1091 }
1092
a427338b
PB
1093 /*
1094 * Map the BIOS at a 2nd physical location, as on the real board.
1095 * Copy it so that we can patch in the MIPS revision, which cannot be
1096 * handled by an overlapping region as the resulting ROM code subpage
1097 * regions are not executable.
1098 */
1099 memory_region_init_ram(bios_copy, NULL, "bios.1fc", BIOS_SIZE);
1100 if (!rom_copy(memory_region_get_ram_ptr(bios_copy),
f05d4d94 1101 FLASH_ADDRESS, BIOS_SIZE)) {
a427338b 1102 memcpy(memory_region_get_ram_ptr(bios_copy),
f05d4d94 1103 memory_region_get_ram_ptr(bios), BIOS_SIZE);
a427338b
PB
1104 }
1105 memory_region_set_readonly(bios_copy, true);
1106 memory_region_add_subregion(system_memory, RESET_ADDRESS, bios_copy);
82a9807b 1107
a427338b
PB
1108 /* Board ID = 0x420 (Malta Board with CoreLV) */
1109 stl_p(memory_region_get_ram_ptr(bios_copy) + 0x10, 0x00000420);
5856de80
TS
1110
1111 /* Init internal devices */
d537cf6c 1112 cpu_mips_irq_init_cpu(env);
5856de80 1113 cpu_mips_clock_init(env);
5856de80 1114
5632ae46
AK
1115 /*
1116 * We have a circular dependency problem: pci_bus depends on isa_irq,
1117 * isa_irq is provided by i8259, i8259 depends on ISA, ISA depends
1118 * on piix4, and piix4 depends on pci_bus. To stop the cycle we have
1119 * qemu_irq_proxy() adds an extra bit of indirection, allowing us
1120 * to resolve the isa_irq -> i8259 dependency after i8259 is initialized.
1121 */
e9b40fd3 1122 isa_irq = qemu_irq_proxy(&s->i8259, 16);
5856de80
TS
1123
1124 /* Northbridge */
5632ae46 1125 pci_bus = gt64120_register(isa_irq);
5856de80
TS
1126
1127 /* Southbridge */
75717903 1128 ide_drive_get(hd, MAX_IDE_BUS);
e4bcb14c 1129
142e9787 1130 piix4_devfn = piix4_init(pci_bus, &isa_bus, 80);
5632ae46
AK
1131
1132 /* Interrupt controller */
1133 /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
e9b40fd3 1134 s->i8259 = i8259_init(isa_bus, env->irq[2]);
5632ae46 1135
e9b40fd3 1136 isa_bus_irqs(isa_bus, s->i8259);
ae027ad3 1137 pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);
afb9a60e 1138 pci_create_simple(pci_bus, piix4_devfn + 2, "piix4-usb-uhci");
48a18b3c 1139 smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100,
459ae5ea 1140 isa_get_irq(NULL, 9), NULL, 0, NULL);
35c64807
PB
1141 smbus_eeprom_init(smbus, 8, smbus_eeprom_buf, smbus_eeprom_size);
1142 g_free(smbus_eeprom_buf);
319ba9f5 1143 pit = pit_init(isa_bus, 0x40, 0, NULL);
4556bd8b
BS
1144 cpu_exit_irq = qemu_allocate_irqs(cpu_request_exit, NULL, 1);
1145 DMA_init(0, cpu_exit_irq);
5856de80
TS
1146
1147 /* Super I/O */
48a18b3c 1148 isa_create_simple(isa_bus, "i8042");
49a2942d 1149
48a18b3c
HP
1150 rtc_init(isa_bus, 2000, NULL);
1151 serial_isa_init(isa_bus, 0, serial_hds[0]);
1152 serial_isa_init(isa_bus, 1, serial_hds[1]);
7bcc17dc 1153 if (parallel_hds[0])
48a18b3c 1154 parallel_init(isa_bus, 0, parallel_hds[0]);
e4bcb14c 1155 for(i = 0; i < MAX_FD; i++) {
fd8014e1 1156 fd[i] = drive_get(IF_FLOPPY, 0, i);
e4bcb14c 1157 }
48a18b3c 1158 fdctrl_init_isa(isa_bus, fd);
5856de80 1159
5856de80 1160 /* Network card */
29b358f9 1161 network_init(pci_bus);
11f29511
TS
1162
1163 /* Optional PCI video card */
9c59864d 1164 pci_vga_init(pci_bus);
5856de80
TS
1165}
1166
e9b40fd3
SW
1167static int mips_malta_sysbus_device_init(SysBusDevice *sysbusdev)
1168{
1169 return 0;
1170}
1171
999e12bb
AL
1172static void mips_malta_class_init(ObjectClass *klass, void *data)
1173{
1174 SysBusDeviceClass *k = SYS_BUS_DEVICE_CLASS(klass);
1175
1176 k->init = mips_malta_sysbus_device_init;
1177}
1178
8c43a6f0 1179static const TypeInfo mips_malta_device = {
cba5cb67 1180 .name = TYPE_MIPS_MALTA,
39bffca2
AL
1181 .parent = TYPE_SYS_BUS_DEVICE,
1182 .instance_size = sizeof(MaltaState),
1183 .class_init = mips_malta_class_init,
e9b40fd3
SW
1184};
1185
f80f9ec9 1186static QEMUMachine mips_malta_machine = {
eec2743e
TS
1187 .name = "malta",
1188 .desc = "MIPS Malta Core LV",
1189 .init = mips_malta_init,
c4cb2578 1190 .max_cpus = 16,
0c257437 1191 .is_default = 1,
5856de80 1192};
f80f9ec9 1193
83f7d43a 1194static void mips_malta_register_types(void)
e9b40fd3 1195{
39bffca2 1196 type_register_static(&mips_malta_device);
e9b40fd3
SW
1197}
1198
f80f9ec9
AL
1199static void mips_malta_machine_init(void)
1200{
1201 qemu_register_machine(&mips_malta_machine);
1202}
1203
83f7d43a 1204type_init(mips_malta_register_types)
f80f9ec9 1205machine_init(mips_malta_machine_init);