]> git.proxmox.com Git - qemu.git/blame - hw/mips_malta.c
pckbd: improve debugging
[qemu.git] / hw / 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
87ecb68b
PB
25#include "hw.h"
26#include "pc.h"
ded7ba9c 27#include "fdc.h"
87ecb68b
PB
28#include "net.h"
29#include "boards.h"
30#include "smbus.h"
c8b153d7
TS
31#include "block.h"
32#include "flash.h"
87ecb68b 33#include "mips.h"
b970ea8f 34#include "mips_cpudevs.h"
87ecb68b 35#include "pci.h"
18e08a55
MT
36#include "usb-uhci.h"
37#include "vmware_vga.h"
87ecb68b
PB
38#include "qemu-char.h"
39#include "sysemu.h"
40#include "audio/audio.h"
41#include "boards.h"
3b3fb322 42#include "qemu-log.h"
bba831e8 43#include "mips-bios.h"
977e1244 44#include "ide.h"
ca20cf32
BS
45#include "loader.h"
46#include "elf.h"
1d914fa0 47#include "mc146818rtc.h"
5856de80 48
c8b153d7
TS
49//#define DEBUG_BOARD_INIT
50
409dbce5 51#define ENVP_ADDR 0x80002000l
5856de80
TS
52#define ENVP_NB_ENTRIES 16
53#define ENVP_ENTRY_SIZE 256
54
e4bcb14c
TS
55#define MAX_IDE_BUS 2
56
5856de80
TS
57typedef struct {
58 uint32_t leds;
59 uint32_t brk;
60 uint32_t gpout;
130751ee 61 uint32_t i2cin;
5856de80
TS
62 uint32_t i2coe;
63 uint32_t i2cout;
64 uint32_t i2csel;
65 CharDriverState *display;
66 char display_text[9];
a4bc3afc 67 SerialState *uart;
5856de80
TS
68} MaltaFPGAState;
69
70static PITState *pit;
71
7df526e3
TS
72static struct _loaderparams {
73 int ram_size;
74 const char *kernel_filename;
75 const char *kernel_cmdline;
76 const char *initrd_filename;
77} loaderparams;
78
5856de80
TS
79/* Malta FPGA */
80static void malta_fpga_update_display(void *opaque)
81{
82 char leds_text[9];
83 int i;
84 MaltaFPGAState *s = opaque;
85
07cf0ba0
TS
86 for (i = 7 ; i >= 0 ; i--) {
87 if (s->leds & (1 << i))
88 leds_text[i] = '#';
89 else
90 leds_text[i] = ' ';
87ee1669 91 }
07cf0ba0
TS
92 leds_text[8] = '\0';
93
94 qemu_chr_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text);
95 qemu_chr_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text);
5856de80
TS
96}
97
130751ee
TS
98/*
99 * EEPROM 24C01 / 24C02 emulation.
100 *
101 * Emulation for serial EEPROMs:
102 * 24C01 - 1024 bit (128 x 8)
103 * 24C02 - 2048 bit (256 x 8)
104 *
105 * Typical device names include Microchip 24C02SC or SGS Thomson ST24C02.
106 */
107
108//~ #define DEBUG
109
110#if defined(DEBUG)
001faf32 111# define logout(fmt, ...) fprintf(stderr, "MALTA\t%-24s" fmt, __func__, ## __VA_ARGS__)
130751ee 112#else
001faf32 113# define logout(fmt, ...) ((void)0)
130751ee
TS
114#endif
115
c227f099 116struct _eeprom24c0x_t {
130751ee
TS
117 uint8_t tick;
118 uint8_t address;
119 uint8_t command;
120 uint8_t ack;
121 uint8_t scl;
122 uint8_t sda;
123 uint8_t data;
124 //~ uint16_t size;
125 uint8_t contents[256];
126};
127
c227f099 128typedef struct _eeprom24c0x_t eeprom24c0x_t;
130751ee 129
c227f099 130static eeprom24c0x_t eeprom = {
284b08f1 131 .contents = {
130751ee
TS
132 /* 00000000: */ 0x80,0x08,0x04,0x0D,0x0A,0x01,0x40,0x00,
133 /* 00000008: */ 0x01,0x75,0x54,0x00,0x82,0x08,0x00,0x01,
134 /* 00000010: */ 0x8F,0x04,0x02,0x01,0x01,0x00,0x0E,0x00,
135 /* 00000018: */ 0x00,0x00,0x00,0x14,0x0F,0x14,0x2D,0x40,
136 /* 00000020: */ 0x15,0x08,0x15,0x08,0x00,0x00,0x00,0x00,
137 /* 00000028: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
138 /* 00000030: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
139 /* 00000038: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x12,0xD0,
140 /* 00000040: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
141 /* 00000048: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
142 /* 00000050: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
143 /* 00000058: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
144 /* 00000060: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
145 /* 00000068: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
146 /* 00000070: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
147 /* 00000078: */ 0x00,0x00,0x00,0x00,0x00,0x00,0x64,0xF4,
148 },
149};
150
a5f1b965 151static uint8_t eeprom24c0x_read(void)
130751ee
TS
152{
153 logout("%u: scl = %u, sda = %u, data = 0x%02x\n",
154 eeprom.tick, eeprom.scl, eeprom.sda, eeprom.data);
155 return eeprom.sda;
156}
157
158static void eeprom24c0x_write(int scl, int sda)
159{
160 if (eeprom.scl && scl && (eeprom.sda != sda)) {
161 logout("%u: scl = %u->%u, sda = %u->%u i2c %s\n",
162 eeprom.tick, eeprom.scl, scl, eeprom.sda, sda, sda ? "stop" : "start");
163 if (!sda) {
164 eeprom.tick = 1;
165 eeprom.command = 0;
166 }
167 } else if (eeprom.tick == 0 && !eeprom.ack) {
168 /* Waiting for start. */
169 logout("%u: scl = %u->%u, sda = %u->%u wait for i2c start\n",
170 eeprom.tick, eeprom.scl, scl, eeprom.sda, sda);
171 } else if (!eeprom.scl && scl) {
172 logout("%u: scl = %u->%u, sda = %u->%u trigger bit\n",
173 eeprom.tick, eeprom.scl, scl, eeprom.sda, sda);
174 if (eeprom.ack) {
175 logout("\ti2c ack bit = 0\n");
176 sda = 0;
177 eeprom.ack = 0;
178 } else if (eeprom.sda == sda) {
179 uint8_t bit = (sda != 0);
180 logout("\ti2c bit = %d\n", bit);
181 if (eeprom.tick < 9) {
182 eeprom.command <<= 1;
183 eeprom.command += bit;
184 eeprom.tick++;
185 if (eeprom.tick == 9) {
186 logout("\tcommand 0x%04x, %s\n", eeprom.command, bit ? "read" : "write");
187 eeprom.ack = 1;
188 }
189 } else if (eeprom.tick < 17) {
190 if (eeprom.command & 1) {
191 sda = ((eeprom.data & 0x80) != 0);
192 }
193 eeprom.address <<= 1;
194 eeprom.address += bit;
195 eeprom.tick++;
196 eeprom.data <<= 1;
197 if (eeprom.tick == 17) {
198 eeprom.data = eeprom.contents[eeprom.address];
199 logout("\taddress 0x%04x, data 0x%02x\n", eeprom.address, eeprom.data);
200 eeprom.ack = 1;
201 eeprom.tick = 0;
202 }
203 } else if (eeprom.tick >= 17) {
204 sda = 0;
205 }
206 } else {
207 logout("\tsda changed with raising scl\n");
208 }
209 } else {
210 logout("%u: scl = %u->%u, sda = %u->%u\n", eeprom.tick, eeprom.scl, scl, eeprom.sda, sda);
211 }
212 eeprom.scl = scl;
213 eeprom.sda = sda;
214}
215
c227f099 216static uint32_t malta_fpga_readl(void *opaque, target_phys_addr_t addr)
5856de80
TS
217{
218 MaltaFPGAState *s = opaque;
219 uint32_t val = 0;
220 uint32_t saddr;
221
222 saddr = (addr & 0xfffff);
223
224 switch (saddr) {
225
226 /* SWITCH Register */
227 case 0x00200:
228 val = 0x00000000; /* All switches closed */
593c0d10 229 break;
5856de80
TS
230
231 /* STATUS Register */
232 case 0x00208:
233#ifdef TARGET_WORDS_BIGENDIAN
234 val = 0x00000012;
235#else
236 val = 0x00000010;
237#endif
238 break;
239
240 /* JMPRS Register */
241 case 0x00210:
242 val = 0x00;
243 break;
244
245 /* LEDBAR Register */
246 case 0x00408:
247 val = s->leds;
248 break;
249
250 /* BRKRES Register */
251 case 0x00508:
252 val = s->brk;
253 break;
254
b6dc7ebb 255 /* UART Registers are handled directly by the serial device */
a4bc3afc 256
5856de80
TS
257 /* GPOUT Register */
258 case 0x00a00:
259 val = s->gpout;
260 break;
261
262 /* XXX: implement a real I2C controller */
263
264 /* GPINP Register */
265 case 0x00a08:
266 /* IN = OUT until a real I2C control is implemented */
267 if (s->i2csel)
268 val = s->i2cout;
269 else
270 val = 0x00;
271 break;
272
273 /* I2CINP Register */
274 case 0x00b00:
130751ee 275 val = ((s->i2cin & ~1) | eeprom24c0x_read());
5856de80
TS
276 break;
277
278 /* I2COE Register */
279 case 0x00b08:
280 val = s->i2coe;
281 break;
282
283 /* I2COUT Register */
284 case 0x00b10:
285 val = s->i2cout;
286 break;
287
288 /* I2CSEL Register */
289 case 0x00b18:
130751ee 290 val = s->i2csel;
5856de80
TS
291 break;
292
293 default:
294#if 0
3594c774 295 printf ("malta_fpga_read: Bad register offset 0x" TARGET_FMT_lx "\n",
593c0d10 296 addr);
5856de80
TS
297#endif
298 break;
299 }
300 return val;
301}
302
c227f099 303static void malta_fpga_writel(void *opaque, target_phys_addr_t addr,
5856de80
TS
304 uint32_t val)
305{
306 MaltaFPGAState *s = opaque;
307 uint32_t saddr;
308
309 saddr = (addr & 0xfffff);
310
311 switch (saddr) {
312
313 /* SWITCH Register */
314 case 0x00200:
315 break;
316
317 /* JMPRS Register */
318 case 0x00210:
319 break;
320
321 /* LEDBAR Register */
322 /* XXX: implement a 8-LED array */
323 case 0x00408:
324 s->leds = val & 0xff;
325 break;
326
327 /* ASCIIWORD Register */
328 case 0x00410:
329 snprintf(s->display_text, 9, "%08X", val);
330 malta_fpga_update_display(s);
331 break;
332
333 /* ASCIIPOS0 to ASCIIPOS7 Registers */
334 case 0x00418:
335 case 0x00420:
336 case 0x00428:
337 case 0x00430:
338 case 0x00438:
339 case 0x00440:
340 case 0x00448:
341 case 0x00450:
342 s->display_text[(saddr - 0x00418) >> 3] = (char) val;
343 malta_fpga_update_display(s);
344 break;
345
346 /* SOFTRES Register */
347 case 0x00500:
348 if (val == 0x42)
349 qemu_system_reset_request ();
350 break;
351
352 /* BRKRES Register */
353 case 0x00508:
354 s->brk = val & 0xff;
355 break;
356
b6dc7ebb 357 /* UART Registers are handled directly by the serial device */
a4bc3afc 358
5856de80
TS
359 /* GPOUT Register */
360 case 0x00a00:
361 s->gpout = val & 0xff;
362 break;
363
364 /* I2COE Register */
365 case 0x00b08:
366 s->i2coe = val & 0x03;
367 break;
368
369 /* I2COUT Register */
370 case 0x00b10:
130751ee
TS
371 eeprom24c0x_write(val & 0x02, val & 0x01);
372 s->i2cout = val;
5856de80
TS
373 break;
374
375 /* I2CSEL Register */
376 case 0x00b18:
130751ee 377 s->i2csel = val & 0x01;
5856de80
TS
378 break;
379
380 default:
381#if 0
3594c774 382 printf ("malta_fpga_write: Bad register offset 0x" TARGET_FMT_lx "\n",
593c0d10 383 addr);
5856de80
TS
384#endif
385 break;
386 }
387}
388
d60efc6b 389static CPUReadMemoryFunc * const malta_fpga_read[] = {
5856de80
TS
390 malta_fpga_readl,
391 malta_fpga_readl,
392 malta_fpga_readl
393};
394
d60efc6b 395static CPUWriteMemoryFunc * const malta_fpga_write[] = {
5856de80
TS
396 malta_fpga_writel,
397 malta_fpga_writel,
398 malta_fpga_writel
399};
400
9596ebb7 401static void malta_fpga_reset(void *opaque)
5856de80
TS
402{
403 MaltaFPGAState *s = opaque;
404
405 s->leds = 0x00;
406 s->brk = 0x0a;
407 s->gpout = 0x00;
130751ee 408 s->i2cin = 0x3;
5856de80
TS
409 s->i2coe = 0x0;
410 s->i2cout = 0x3;
411 s->i2csel = 0x1;
412
413 s->display_text[8] = '\0';
414 snprintf(s->display_text, 9, " ");
ceecf1d1
AJ
415}
416
ceecf1d1
AJ
417static void malta_fpga_led_init(CharDriverState *chr)
418{
419 qemu_chr_printf(chr, "\e[HMalta LEDBAR\r\n");
420 qemu_chr_printf(chr, "+--------+\r\n");
421 qemu_chr_printf(chr, "+ +\r\n");
422 qemu_chr_printf(chr, "+--------+\r\n");
423 qemu_chr_printf(chr, "\n");
424 qemu_chr_printf(chr, "Malta ASCII\r\n");
425 qemu_chr_printf(chr, "+--------+\r\n");
426 qemu_chr_printf(chr, "+ +\r\n");
427 qemu_chr_printf(chr, "+--------+\r\n");
5856de80
TS
428}
429
c227f099 430static MaltaFPGAState *malta_fpga_init(target_phys_addr_t base, qemu_irq uart_irq, CharDriverState *uart_chr)
5856de80
TS
431{
432 MaltaFPGAState *s;
433 int malta;
434
435 s = (MaltaFPGAState *)qemu_mallocz(sizeof(MaltaFPGAState));
436
1eed09cb 437 malta = cpu_register_io_memory(malta_fpga_read,
5856de80 438 malta_fpga_write, s);
a4bc3afc 439
b6dc7ebb 440 cpu_register_physical_memory(base, 0x900, malta);
8da3ff18 441 /* 0xa00 is less than a page, so will still get the right offsets. */
b6dc7ebb 442 cpu_register_physical_memory(base + 0xa00, 0x100000 - 0xa00, malta);
5856de80 443
ceecf1d1
AJ
444 s->display = qemu_chr_open("fpga", "vc:320x200", malta_fpga_led_init);
445
2d48377a
BS
446#ifdef TARGET_WORDS_BIGENDIAN
447 s->uart = serial_mm_init(base + 0x900, 3, uart_irq, 230400, uart_chr, 1, 1);
448#else
449 s->uart = serial_mm_init(base + 0x900, 3, uart_irq, 230400, uart_chr, 1, 0);
450#endif
a4bc3afc 451
5856de80 452 malta_fpga_reset(s);
a08d4367 453 qemu_register_reset(malta_fpga_reset, s);
5856de80
TS
454
455 return s;
456}
457
458/* Audio support */
459#ifdef HAS_AUDIO
460static void audio_init (PCIBus *pci_bus)
461{
462 struct soundhw *c;
463 int audio_enabled = 0;
464
465 for (c = soundhw; !audio_enabled && c->name; ++c) {
466 audio_enabled = c->enabled;
467 }
468
469 if (audio_enabled) {
0d9acba8
PB
470 for (c = soundhw; c->name; ++c) {
471 if (c->enabled) {
22d83b14 472 c->init.init_pci(pci_bus);
5856de80
TS
473 }
474 }
475 }
476}
477#endif
478
479/* Network support */
5607c388 480static void network_init(void)
5856de80
TS
481{
482 int i;
5856de80
TS
483
484 for(i = 0; i < nb_nics; i++) {
cb457d76 485 NICInfo *nd = &nd_table[i];
5607c388 486 const char *default_devaddr = NULL;
cb457d76
AL
487
488 if (i == 0 && (!nd->model || strcmp(nd->model, "pcnet") == 0))
5856de80 489 /* The malta board has a PCNet card using PCI SLOT 11 */
5607c388 490 default_devaddr = "0b";
cb457d76 491
07caea31 492 pci_nic_init_nofail(nd, "pcnet", default_devaddr);
5856de80
TS
493 }
494}
495
496/* ROM and pseudo bootloader
497
498 The following code implements a very very simple bootloader. It first
499 loads the registers a0 to a3 to the values expected by the OS, and
500 then jump at the kernel address.
501
502 The bootloader should pass the locations of the kernel arguments and
503 environment variables tables. Those tables contain the 32-bit address
504 of NULL terminated strings. The environment variables table should be
505 terminated by a NULL address.
506
507 For a simpler implementation, the number of kernel arguments is fixed
508 to two (the name of the kernel and the command line), and the two
509 tables are actually the same one.
510
511 The registers a0 to a3 should contain the following values:
512 a0 - number of kernel arguments
513 a1 - 32-bit address of the kernel arguments table
514 a2 - 32-bit address of the environment variables table
515 a3 - RAM size in bytes
516*/
517
d7585251
PB
518static void write_bootloader (CPUState *env, uint8_t *base,
519 int64_t kernel_entry)
5856de80
TS
520{
521 uint32_t *p;
522
523 /* Small bootloader */
d7585251 524 p = (uint32_t *)base;
26ea0918 525 stl_raw(p++, 0x0bf00160); /* j 0x1fc00580 */
3ddd0065 526 stl_raw(p++, 0x00000000); /* nop */
5856de80 527
26ea0918 528 /* YAMON service vector */
d7585251
PB
529 stl_raw(base + 0x500, 0xbfc00580); /* start: */
530 stl_raw(base + 0x504, 0xbfc0083c); /* print_count: */
531 stl_raw(base + 0x520, 0xbfc00580); /* start: */
532 stl_raw(base + 0x52c, 0xbfc00800); /* flush_cache: */
533 stl_raw(base + 0x534, 0xbfc00808); /* print: */
534 stl_raw(base + 0x538, 0xbfc00800); /* reg_cpu_isr: */
535 stl_raw(base + 0x53c, 0xbfc00800); /* unred_cpu_isr: */
536 stl_raw(base + 0x540, 0xbfc00800); /* reg_ic_isr: */
537 stl_raw(base + 0x544, 0xbfc00800); /* unred_ic_isr: */
538 stl_raw(base + 0x548, 0xbfc00800); /* reg_esr: */
539 stl_raw(base + 0x54c, 0xbfc00800); /* unreg_esr: */
540 stl_raw(base + 0x550, 0xbfc00800); /* getchar: */
541 stl_raw(base + 0x554, 0xbfc00800); /* syscon_read: */
26ea0918
TS
542
543
5856de80 544 /* Second part of the bootloader */
d7585251 545 p = (uint32_t *) (base + 0x580);
d52fff71
TS
546 stl_raw(p++, 0x24040002); /* addiu a0, zero, 2 */
547 stl_raw(p++, 0x3c1d0000 | (((ENVP_ADDR - 64) >> 16) & 0xffff)); /* lui sp, high(ENVP_ADDR) */
471ea271 548 stl_raw(p++, 0x37bd0000 | ((ENVP_ADDR - 64) & 0xffff)); /* ori sp, sp, low(ENVP_ADDR) */
3ddd0065 549 stl_raw(p++, 0x3c050000 | ((ENVP_ADDR >> 16) & 0xffff)); /* lui a1, high(ENVP_ADDR) */
471ea271 550 stl_raw(p++, 0x34a50000 | (ENVP_ADDR & 0xffff)); /* ori a1, a1, low(ENVP_ADDR) */
3ddd0065
TS
551 stl_raw(p++, 0x3c060000 | (((ENVP_ADDR + 8) >> 16) & 0xffff)); /* lui a2, high(ENVP_ADDR + 8) */
552 stl_raw(p++, 0x34c60000 | ((ENVP_ADDR + 8) & 0xffff)); /* ori a2, a2, low(ENVP_ADDR + 8) */
7df526e3
TS
553 stl_raw(p++, 0x3c070000 | (loaderparams.ram_size >> 16)); /* lui a3, high(ram_size) */
554 stl_raw(p++, 0x34e70000 | (loaderparams.ram_size & 0xffff)); /* ori a3, a3, low(ram_size) */
2802bfe3
TS
555
556 /* Load BAR registers as done by YAMON */
a0a8793e
TS
557 stl_raw(p++, 0x3c09b400); /* lui t1, 0xb400 */
558
559#ifdef TARGET_WORDS_BIGENDIAN
560 stl_raw(p++, 0x3c08df00); /* lui t0, 0xdf00 */
561#else
562 stl_raw(p++, 0x340800df); /* ori t0, r0, 0x00df */
563#endif
564 stl_raw(p++, 0xad280068); /* sw t0, 0x0068(t1) */
565
2802bfe3
TS
566 stl_raw(p++, 0x3c09bbe0); /* lui t1, 0xbbe0 */
567
568#ifdef TARGET_WORDS_BIGENDIAN
569 stl_raw(p++, 0x3c08c000); /* lui t0, 0xc000 */
570#else
571 stl_raw(p++, 0x340800c0); /* ori t0, r0, 0x00c0 */
572#endif
573 stl_raw(p++, 0xad280048); /* sw t0, 0x0048(t1) */
574#ifdef TARGET_WORDS_BIGENDIAN
575 stl_raw(p++, 0x3c084000); /* lui t0, 0x4000 */
576#else
577 stl_raw(p++, 0x34080040); /* ori t0, r0, 0x0040 */
578#endif
579 stl_raw(p++, 0xad280050); /* sw t0, 0x0050(t1) */
580
581#ifdef TARGET_WORDS_BIGENDIAN
582 stl_raw(p++, 0x3c088000); /* lui t0, 0x8000 */
583#else
584 stl_raw(p++, 0x34080080); /* ori t0, r0, 0x0080 */
585#endif
586 stl_raw(p++, 0xad280058); /* sw t0, 0x0058(t1) */
587#ifdef TARGET_WORDS_BIGENDIAN
588 stl_raw(p++, 0x3c083f00); /* lui t0, 0x3f00 */
589#else
590 stl_raw(p++, 0x3408003f); /* ori t0, r0, 0x003f */
591#endif
592 stl_raw(p++, 0xad280060); /* sw t0, 0x0060(t1) */
593
594#ifdef TARGET_WORDS_BIGENDIAN
595 stl_raw(p++, 0x3c08c100); /* lui t0, 0xc100 */
596#else
597 stl_raw(p++, 0x340800c1); /* ori t0, r0, 0x00c1 */
598#endif
599 stl_raw(p++, 0xad280080); /* sw t0, 0x0080(t1) */
600#ifdef TARGET_WORDS_BIGENDIAN
601 stl_raw(p++, 0x3c085e00); /* lui t0, 0x5e00 */
602#else
603 stl_raw(p++, 0x3408005e); /* ori t0, r0, 0x005e */
604#endif
605 stl_raw(p++, 0xad280088); /* sw t0, 0x0088(t1) */
606
607 /* Jump to kernel code */
74287114
TS
608 stl_raw(p++, 0x3c1f0000 | ((kernel_entry >> 16) & 0xffff)); /* lui ra, high(kernel_entry) */
609 stl_raw(p++, 0x37ff0000 | (kernel_entry & 0xffff)); /* ori ra, ra, low(kernel_entry) */
3ddd0065
TS
610 stl_raw(p++, 0x03e00008); /* jr ra */
611 stl_raw(p++, 0x00000000); /* nop */
26ea0918
TS
612
613 /* YAMON subroutines */
d7585251 614 p = (uint32_t *) (base + 0x800);
26ea0918
TS
615 stl_raw(p++, 0x03e00008); /* jr ra */
616 stl_raw(p++, 0x24020000); /* li v0,0 */
617 /* 808 YAMON print */
618 stl_raw(p++, 0x03e06821); /* move t5,ra */
619 stl_raw(p++, 0x00805821); /* move t3,a0 */
620 stl_raw(p++, 0x00a05021); /* move t2,a1 */
621 stl_raw(p++, 0x91440000); /* lbu a0,0(t2) */
622 stl_raw(p++, 0x254a0001); /* addiu t2,t2,1 */
623 stl_raw(p++, 0x10800005); /* beqz a0,834 */
624 stl_raw(p++, 0x00000000); /* nop */
625 stl_raw(p++, 0x0ff0021c); /* jal 870 */
626 stl_raw(p++, 0x00000000); /* nop */
627 stl_raw(p++, 0x08000205); /* j 814 */
628 stl_raw(p++, 0x00000000); /* nop */
629 stl_raw(p++, 0x01a00008); /* jr t5 */
630 stl_raw(p++, 0x01602021); /* move a0,t3 */
631 /* 0x83c YAMON print_count */
632 stl_raw(p++, 0x03e06821); /* move t5,ra */
633 stl_raw(p++, 0x00805821); /* move t3,a0 */
634 stl_raw(p++, 0x00a05021); /* move t2,a1 */
635 stl_raw(p++, 0x00c06021); /* move t4,a2 */
636 stl_raw(p++, 0x91440000); /* lbu a0,0(t2) */
637 stl_raw(p++, 0x0ff0021c); /* jal 870 */
638 stl_raw(p++, 0x00000000); /* nop */
639 stl_raw(p++, 0x254a0001); /* addiu t2,t2,1 */
640 stl_raw(p++, 0x258cffff); /* addiu t4,t4,-1 */
641 stl_raw(p++, 0x1580fffa); /* bnez t4,84c */
642 stl_raw(p++, 0x00000000); /* nop */
643 stl_raw(p++, 0x01a00008); /* jr t5 */
644 stl_raw(p++, 0x01602021); /* move a0,t3 */
645 /* 0x870 */
646 stl_raw(p++, 0x3c08b800); /* lui t0,0xb400 */
647 stl_raw(p++, 0x350803f8); /* ori t0,t0,0x3f8 */
648 stl_raw(p++, 0x91090005); /* lbu t1,5(t0) */
649 stl_raw(p++, 0x00000000); /* nop */
650 stl_raw(p++, 0x31290040); /* andi t1,t1,0x40 */
651 stl_raw(p++, 0x1120fffc); /* beqz t1,878 <outch+0x8> */
652 stl_raw(p++, 0x00000000); /* nop */
653 stl_raw(p++, 0x03e00008); /* jr ra */
654 stl_raw(p++, 0xa1040000); /* sb a0,0(t0) */
655
5856de80
TS
656}
657
c938ada2 658static void prom_set(uint32_t* prom_buf, int index, const char *string, ...)
5856de80
TS
659{
660 va_list ap;
3ddd0065 661 int32_t table_addr;
5856de80
TS
662
663 if (index >= ENVP_NB_ENTRIES)
664 return;
665
5856de80 666 if (string == NULL) {
c938ada2 667 prom_buf[index] = 0;
5856de80
TS
668 return;
669 }
670
c938ada2
AJ
671 table_addr = sizeof(int32_t) * ENVP_NB_ENTRIES + index * ENVP_ENTRY_SIZE;
672 prom_buf[index] = tswap32(ENVP_ADDR + table_addr);
5856de80
TS
673
674 va_start(ap, string);
c938ada2 675 vsnprintf((char *)prom_buf + table_addr, ENVP_ENTRY_SIZE, string, ap);
5856de80
TS
676 va_end(ap);
677}
678
679/* Kernel */
e16ad5b0 680static int64_t load_kernel (void)
5856de80 681{
409dbce5 682 int64_t kernel_entry, kernel_high;
5856de80 683 long initrd_size;
c227f099 684 ram_addr_t initrd_offset;
ca20cf32 685 int big_endian;
c938ada2
AJ
686 uint32_t *prom_buf;
687 long prom_size;
688 int prom_index = 0;
ca20cf32
BS
689
690#ifdef TARGET_WORDS_BIGENDIAN
691 big_endian = 1;
692#else
693 big_endian = 0;
694#endif
5856de80 695
409dbce5
AJ
696 if (load_elf(loaderparams.kernel_filename, cpu_mips_kseg0_to_phys, NULL,
697 (uint64_t *)&kernel_entry, NULL, (uint64_t *)&kernel_high,
698 big_endian, ELF_MACHINE, 1) < 0) {
5856de80 699 fprintf(stderr, "qemu: could not load kernel '%s'\n",
7df526e3 700 loaderparams.kernel_filename);
acdf72bb 701 exit(1);
5856de80
TS
702 }
703
704 /* load initrd */
705 initrd_size = 0;
74287114 706 initrd_offset = 0;
7df526e3
TS
707 if (loaderparams.initrd_filename) {
708 initrd_size = get_image_size (loaderparams.initrd_filename);
74287114
TS
709 if (initrd_size > 0) {
710 initrd_offset = (kernel_high + ~TARGET_PAGE_MASK) & TARGET_PAGE_MASK;
7df526e3 711 if (initrd_offset + initrd_size > ram_size) {
74287114
TS
712 fprintf(stderr,
713 "qemu: memory too small for initial ram disk '%s'\n",
7df526e3 714 loaderparams.initrd_filename);
74287114
TS
715 exit(1);
716 }
dcac9679
PB
717 initrd_size = load_image_targphys(loaderparams.initrd_filename,
718 initrd_offset,
719 ram_size - initrd_offset);
74287114 720 }
5856de80
TS
721 if (initrd_size == (target_ulong) -1) {
722 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n",
7df526e3 723 loaderparams.initrd_filename);
5856de80
TS
724 exit(1);
725 }
726 }
727
c938ada2
AJ
728 /* Setup prom parameters. */
729 prom_size = ENVP_NB_ENTRIES * (sizeof(int32_t) + ENVP_ENTRY_SIZE);
730 prom_buf = qemu_malloc(prom_size);
731
732 prom_set(prom_buf, prom_index++, loaderparams.kernel_filename);
733 if (initrd_size > 0) {
409dbce5
AJ
734 prom_set(prom_buf, prom_index++, "rd_start=0x%" PRIx64 " rd_size=%li %s",
735 cpu_mips_phys_to_kseg0(NULL, initrd_offset), initrd_size,
7df526e3 736 loaderparams.kernel_cmdline);
c938ada2
AJ
737 } else {
738 prom_set(prom_buf, prom_index++, loaderparams.kernel_cmdline);
739 }
740
741 prom_set(prom_buf, prom_index++, "memsize");
742 prom_set(prom_buf, prom_index++, "%i", loaderparams.ram_size);
743 prom_set(prom_buf, prom_index++, "modetty0");
744 prom_set(prom_buf, prom_index++, "38400n8r");
745 prom_set(prom_buf, prom_index++, NULL);
746
747 rom_add_blob_fixed("prom", prom_buf, prom_size,
409dbce5 748 cpu_mips_kseg0_to_phys(NULL, ENVP_ADDR));
5856de80 749
74287114 750 return kernel_entry;
5856de80
TS
751}
752
753static void main_cpu_reset(void *opaque)
754{
755 CPUState *env = opaque;
756 cpu_reset(env);
757
5c43485f 758 /* The bootloader does not need to be rewritten as it is located in a
5856de80
TS
759 read only location. The kernel location and the arguments table
760 location does not change. */
7df526e3 761 if (loaderparams.kernel_filename) {
fb82fea0 762 env->CP0_Status &= ~((1 << CP0St_BEV) | (1 << CP0St_ERL));
fb82fea0 763 }
5856de80
TS
764}
765
70705261 766static
c227f099 767void mips_malta_init (ram_addr_t ram_size,
3023f332 768 const char *boot_device,
5856de80 769 const char *kernel_filename, const char *kernel_cmdline,
94fc95cd 770 const char *initrd_filename, const char *cpu_model)
5856de80 771{
5cea8590 772 char *filename;
c227f099
AL
773 ram_addr_t ram_offset;
774 ram_addr_t bios_offset;
c8b153d7 775 target_long bios_size;
74287114 776 int64_t kernel_entry;
5856de80 777 PCIBus *pci_bus;
ae027ad3 778 ISADevice *isa_dev;
5856de80 779 CPUState *env;
1d914fa0 780 ISADevice *rtc_state;
5c02c033 781 FDCtrl *floppy_controller;
5856de80 782 MaltaFPGAState *malta_fpga;
d537cf6c 783 qemu_irq *i8259;
7b717336
TS
784 int piix4_devfn;
785 uint8_t *eeprom_buf;
786 i2c_bus *smbus;
787 int i;
751c6a17 788 DriveInfo *dinfo;
f455e98c 789 DriveInfo *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
fd8014e1 790 DriveInfo *fd[MAX_FD];
c8b153d7
TS
791 int fl_idx = 0;
792 int fl_sectors = 0;
3d08ff69 793 int be;
5856de80 794
ffabf037
AJ
795 /* Make sure the first 3 serial ports are associated with a device. */
796 for(i = 0; i < 3; i++) {
797 if (!serial_hds[i]) {
798 char label[32];
799 snprintf(label, sizeof(label), "serial%d", i);
800 serial_hds[i] = qemu_chr_open(label, "null", NULL);
801 }
802 }
803
33d68b5f
TS
804 /* init CPUs */
805 if (cpu_model == NULL) {
60aa19ab 806#ifdef TARGET_MIPS64
c9c1a064 807 cpu_model = "20Kc";
33d68b5f 808#else
1c32f43e 809 cpu_model = "24Kf";
33d68b5f
TS
810#endif
811 }
aaed909a
FB
812 env = cpu_init(cpu_model);
813 if (!env) {
814 fprintf(stderr, "Unable to find CPU definition\n");
815 exit(1);
816 }
a08d4367 817 qemu_register_reset(main_cpu_reset, env);
5856de80
TS
818
819 /* allocate RAM */
0ccff151
AJ
820 if (ram_size > (256 << 20)) {
821 fprintf(stderr,
822 "qemu: Too much memory for this machine: %d MB, maximum 256 MB\n",
823 ((unsigned int)ram_size / (1 << 20)));
824 exit(1);
825 }
dcac9679 826 ram_offset = qemu_ram_alloc(ram_size);
dcac9679
PB
827 bios_offset = qemu_ram_alloc(BIOS_SIZE);
828
829
830 cpu_register_physical_memory(0, ram_size, ram_offset | IO_MEM_RAM);
5856de80 831
c8b153d7 832 /* Map the bios at two physical locations, as on the real board. */
5856de80
TS
833 cpu_register_physical_memory(0x1e000000LL,
834 BIOS_SIZE, bios_offset | IO_MEM_ROM);
835 cpu_register_physical_memory(0x1fc00000LL,
836 BIOS_SIZE, bios_offset | IO_MEM_ROM);
837
3d08ff69
BS
838#ifdef TARGET_WORDS_BIGENDIAN
839 be = 1;
840#else
841 be = 0;
842#endif
070ce5ed 843 /* FPGA */
470d86b7 844 malta_fpga = malta_fpga_init(0x1f000000LL, env->irq[2], serial_hds[2]);
070ce5ed 845
c8b153d7
TS
846 /* Load firmware in flash / BIOS unless we boot directly into a kernel. */
847 if (kernel_filename) {
848 /* Write a small bootloader to the flash location. */
849 loaderparams.ram_size = ram_size;
850 loaderparams.kernel_filename = kernel_filename;
851 loaderparams.kernel_cmdline = kernel_cmdline;
852 loaderparams.initrd_filename = initrd_filename;
e16ad5b0 853 kernel_entry = load_kernel();
d7585251 854 write_bootloader(env, qemu_get_ram_ptr(bios_offset), kernel_entry);
c8b153d7 855 } else {
751c6a17
GH
856 dinfo = drive_get(IF_PFLASH, 0, fl_idx);
857 if (dinfo) {
c8b153d7
TS
858 /* Load firmware from flash. */
859 bios_size = 0x400000;
860 fl_sectors = bios_size >> 16;
861#ifdef DEBUG_BOARD_INIT
862 printf("Register parallel flash %d size " TARGET_FMT_lx " at "
863 "offset %08lx addr %08llx '%s' %x\n",
864 fl_idx, bios_size, bios_offset, 0x1e000000LL,
751c6a17 865 bdrv_get_device_name(dinfo->bdrv), fl_sectors);
c8b153d7
TS
866#endif
867 pflash_cfi01_register(0x1e000000LL, bios_offset,
751c6a17 868 dinfo->bdrv, 65536, fl_sectors,
3d08ff69 869 4, 0x0000, 0x0000, 0x0000, 0x0000, be);
c8b153d7
TS
870 fl_idx++;
871 } else {
872 /* Load a BIOS image. */
873 if (bios_name == NULL)
874 bios_name = BIOS_FILENAME;
5cea8590
PB
875 filename = qemu_find_file(QEMU_FILE_TYPE_BIOS, bios_name);
876 if (filename) {
877 bios_size = load_image_targphys(filename, 0x1fc00000LL,
878 BIOS_SIZE);
879 qemu_free(filename);
880 } else {
881 bios_size = -1;
882 }
c8b153d7
TS
883 if ((bios_size < 0 || bios_size > BIOS_SIZE) && !kernel_filename) {
884 fprintf(stderr,
885 "qemu: Could not load MIPS bios '%s', and no -kernel argument was specified\n",
5cea8590 886 bios_name);
c8b153d7
TS
887 exit(1);
888 }
070ce5ed 889 }
3187ef03
TS
890 /* In little endian mode the 32bit words in the bios are swapped,
891 a neat trick which allows bi-endian firmware. */
892#ifndef TARGET_WORDS_BIGENDIAN
893 {
d7585251
PB
894 uint32_t *addr = qemu_get_ram_ptr(bios_offset);;
895 uint32_t *end = addr + bios_size;
896 while (addr < end) {
897 bswap32s(addr);
3187ef03
TS
898 }
899 }
900#endif
070ce5ed
TS
901 }
902
5856de80
TS
903 /* Board ID = 0x420 (Malta Board with CoreLV)
904 XXX: theoretically 0x1e000010 should map to flash and 0x1fc00010 should
905 map to the board ID. */
d7585251 906 stl_phys(0x1fc00010LL, 0x00000420);
5856de80
TS
907
908 /* Init internal devices */
d537cf6c 909 cpu_mips_irq_init_cpu(env);
5856de80 910 cpu_mips_clock_init(env);
5856de80 911
5856de80 912 /* Interrupt controller */
d537cf6c
PB
913 /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
914 i8259 = i8259_init(env->irq[2]);
5856de80
TS
915
916 /* Northbridge */
d537cf6c 917 pci_bus = pci_gt64120_init(i8259);
5856de80
TS
918
919 /* Southbridge */
e4bcb14c
TS
920
921 if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
922 fprintf(stderr, "qemu: too many IDE bus\n");
923 exit(1);
924 }
925
926 for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
f455e98c 927 hd[i] = drive_get(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
e4bcb14c
TS
928 }
929
7b717336 930 piix4_devfn = piix4_init(pci_bus, 80);
ae027ad3
SW
931 isa_bus_irqs(i8259);
932 pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);
afcc3cdf 933 usb_uhci_piix4_init(pci_bus, piix4_devfn + 2);
53b67b30
BS
934 smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100, isa_reserve_irq(9),
935 NULL, NULL, 0);
7b717336
TS
936 eeprom_buf = qemu_mallocz(8 * 256); /* XXX: make this persistent */
937 for (i = 0; i < 8; i++) {
938 /* TODO: Populate SPD eeprom data. */
1ea96673 939 DeviceState *eeprom;
02e2da45 940 eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");
5b7f5327 941 qdev_prop_set_uint8(eeprom, "address", 0x50 + i);
ee6847d1 942 qdev_prop_set_ptr(eeprom, "data", eeprom_buf + (i * 256));
e23a1b33 943 qdev_init_nofail(eeprom);
7b717336 944 }
ae027ad3 945 pit = pit_init(0x40, isa_reserve_irq(0));
5856de80
TS
946 DMA_init(0);
947
948 /* Super I/O */
2e15e23b 949 isa_dev = isa_create_simple("i8042");
ae027ad3 950
32e0c826 951 rtc_state = rtc_init(2000);
ac0be998
GH
952 serial_isa_init(0, serial_hds[0]);
953 serial_isa_init(1, serial_hds[1]);
7bcc17dc 954 if (parallel_hds[0])
021f0674 955 parallel_init(0, parallel_hds[0]);
e4bcb14c 956 for(i = 0; i < MAX_FD; i++) {
fd8014e1 957 fd[i] = drive_get(IF_FLOPPY, 0, i);
e4bcb14c 958 }
86c86157 959 floppy_controller = fdctrl_init_isa(fd);
5856de80
TS
960
961 /* Sound card */
962#ifdef HAS_AUDIO
963 audio_init(pci_bus);
964#endif
965
966 /* Network card */
5607c388 967 network_init();
11f29511
TS
968
969 /* Optional PCI video card */
1f605a76 970 if (cirrus_vga_enabled) {
fbe1b595 971 pci_cirrus_vga_init(pci_bus);
1f605a76 972 } else if (vmsvga_enabled) {
fbe1b595 973 pci_vmsvga_init(pci_bus);
1f605a76 974 } else if (std_vga_enabled) {
fbe1b595 975 pci_vga_init(pci_bus, 0, 0);
1f605a76 976 }
5856de80
TS
977}
978
f80f9ec9 979static QEMUMachine mips_malta_machine = {
eec2743e
TS
980 .name = "malta",
981 .desc = "MIPS Malta Core LV",
982 .init = mips_malta_init,
0c257437 983 .is_default = 1,
5856de80 984};
f80f9ec9
AL
985
986static void mips_malta_machine_init(void)
987{
988 qemu_register_machine(&mips_malta_machine);
989}
990
991machine_init(mips_malta_machine_init);