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