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