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