1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25: #include "hw.h"
26: #include "pc.h"
27: #include "fdc.h"
28: #include "net.h"
29: #include "boards.h"
30: #include "smbus.h"
31: #include "block.h"
32: #include "flash.h"
33: #include "mips.h"
34: #include "pci.h"
35: #include "qemu-char.h"
36: #include "sysemu.h"
37: #include "audio/audio.h"
38: #include "boards.h"
39:
40:
41:
42: #ifdef TARGET_WORDS_BIGENDIAN
43: #define BIOS_FILENAME "mips_bios.bin"
44: #else
45: #define BIOS_FILENAME "mipsel_bios.bin"
46: #endif
47:
48: #ifdef TARGET_MIPS64
49: #define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffULL)
50: #else
51: #define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffU)
52: #endif
53:
54: #define ENVP_ADDR (int32_t)0x80002000
55: #define VIRT_TO_PHYS_ADDEND (-((int64_t)(int32_t)0x80000000))
56:
57: #define ENVP_NB_ENTRIES 16
58: #define ENVP_ENTRY_SIZE 256
59:
60: #define MAX_IDE_BUS 2
61:
62: extern FILE *logfile;
63:
64: typedef struct {
65: uint32_t leds;
66: uint32_t brk;
67: uint32_t gpout;
68: uint32_t i2cin;
69: uint32_t i2coe;
70: uint32_t i2cout;
71: uint32_t i2csel;
72: CharDriverState *display;
73: char display_text[9];
74: SerialState *uart;
75: } MaltaFPGAState;
76:
77: static PITState *pit;
78:
79: static struct _loaderparams {
80: int ram_size;
81: const char *kernel_filename;
82: const char *kernel_cmdline;
83: const char *initrd_filename;
84: } loaderparams;
85:
86:
87: static void malta_fpga_update_display(void *opaque)
88: {
89: char leds_text[9];
90: int i;
91: MaltaFPGAState *s = opaque;
92:
93: for (i = 7 ; i >= 0 ; i--) {
94: if (s->leds & (1 << i))
95: leds_text[i] = '#';
96: else
97: leds_text[i] = ' ';
98: }
99: leds_text[8] = '\0';
100:
101: qemu_chr_printf(s->display, "\e[H\n\n|\e[32m%-8.8s\e[00m|\r\n", leds_text);
102: qemu_chr_printf(s->display, "\n\n\n\n|\e[31m%-8.8s\e[00m|", s->display_text);
103: }
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117: #if defined(DEBUG)
118: # define logout(fmt, args...) fprintf(stderr, "MALTA\t%-24s" fmt, __func__, ##args)
119: #else
120: # define logout(fmt, args...) ((void)0)
121: #endif
122:
123: struct _eeprom24c0x_t {
124: uint8_t tick;
125: uint8_t address;
126: uint8_t command;
127: uint8_t ack;
128: uint8_t scl;
129: uint8_t sda;
130: uint8_t data;
131:
132: uint8_t contents[256];
133: };
134:
135: typedef struct _eeprom24c0x_t eeprom24c0x_t;
136:
137: static eeprom24c0x_t eeprom = {
138: contents: {
139: 0x80,0x08,0x04,0x0D,0x0A,0x01,0x40,0x00,
140: 0x01,0x75,0x54,0x00,0x82,0x08,0x00,0x01,
141: 0x8F,0x04,0x02,0x01,0x01,0x00,0x0E,0x00,
142: 0x00,0x00,0x00,0x14,0x0F,0x14,0x2D,0x40,
143: 0x15,0x08,0x15,0x08,0x00,0x00,0x00,0x00,
144: 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
145: 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
146: 0x00,0x00,0x00,0x00,0x00,0x00,0x12,0xD0,
147: 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
148: 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
149: 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
150: 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
151: 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
152: 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
153: 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
154: 0x00,0x00,0x00,0x00,0x00,0x00,0x64,0xF4,
155: },
156: };
157:
158: static uint8_t eeprom24c0x_read()
159: {
160: logout("%u: scl = %u, sda = %u, data = 0x%02x\n",
161: eeprom.tick, eeprom.scl, eeprom.sda, eeprom.data);
162: return eeprom.sda;
163: }
164:
165: static void eeprom24c0x_write(int scl, int sda)
166: {
167: if (eeprom.scl && scl && (eeprom.sda != sda)) {
168: logout("%u: scl = %u->%u, sda = %u->%u i2c %s\n",
169: eeprom.tick, eeprom.scl, scl, eeprom.sda, sda, sda ? "stop" : "start");
170: if (!sda) {
171: eeprom.tick = 1;
172: eeprom.command = 0;
173: }
174: } else if (eeprom.tick == 0 && !eeprom.ack) {
175:
176: logout("%u: scl = %u->%u, sda = %u->%u wait for i2c start\n",
177: eeprom.tick, eeprom.scl, scl, eeprom.sda, sda);
178: } else if (!eeprom.scl && scl) {
179: logout("%u: scl = %u->%u, sda = %u->%u trigger bit\n",
180: eeprom.tick, eeprom.scl, scl, eeprom.sda, sda);
181: if (eeprom.ack) {
182: logout("\ti2c ack bit = 0\n");
183: sda = 0;
184: eeprom.ack = 0;
185: } else if (eeprom.sda == sda) {
186: uint8_t bit = (sda != 0);
187: logout("\ti2c bit = %d\n", bit);
188: if (eeprom.tick < 9) {
189: eeprom.command <<= 1;
190: eeprom.command += bit;
191: eeprom.tick++;
192: if (eeprom.tick == 9) {
193: logout("\tcommand 0x%04x, %s\n", eeprom.command, bit ? "read" : "write");
194: eeprom.ack = 1;
195: }
196: } else if (eeprom.tick < 17) {
197: if (eeprom.command & 1) {
198: sda = ((eeprom.data & 0x80) != 0);
199: }
200: eeprom.address <<= 1;
201: eeprom.address += bit;
202: eeprom.tick++;
203: eeprom.data <<= 1;
204: if (eeprom.tick == 17) {
205: eeprom.data = eeprom.contents[eeprom.address];
206: logout("\taddress 0x%04x, data 0x%02x\n", eeprom.address, eeprom.data);
207: eeprom.ack = 1;
208: eeprom.tick = 0;
209: }
210: } else if (eeprom.tick >= 17) {
211: sda = 0;
212: }
213: } else {
214: logout("\tsda changed with raising scl\n");
215: }
216: } else {
217: logout("%u: scl = %u->%u, sda = %u->%u\n", eeprom.tick, eeprom.scl, scl, eeprom.sda, sda);
218: }
219: eeprom.scl = scl;
220: eeprom.sda = sda;
221: }
222:
223: static uint32_t malta_fpga_readl(void *opaque, target_phys_addr_t addr)
224: {
225: MaltaFPGAState *s = opaque;
226: uint32_t val = 0;
227: uint32_t saddr;
228:
229: saddr = (addr & 0xfffff);
230:
231: switch (saddr) {
232:
233:
234: case 0x00200:
235: val = 0x00000000;
236: break;
237:
238:
239: case 0x00208:
240: #ifdef TARGET_WORDS_BIGENDIAN
241: val = 0x00000012;
242: #else
243: val = 0x00000010;
244: #endif
245: break;
246:
247:
248: case 0x00210:
249: val = 0x00;
250: break;
251:
252:
253: case 0x00408:
254: val = s->leds;
255: break;
256:
257:
258: case 0x00508:
259: val = s->brk;
260: break;
261:
262:
263:
264:
265: case 0x00a00:
266: val = s->gpout;
267: break;
268:
269:
270:
271:
272: case 0x00a08:
273:
274: if (s->i2csel)
275: val = s->i2cout;
276: else
277: val = 0x00;
278: break;
279:
280:
281: case 0x00b00:
282: val = ((s->i2cin & ~1) | eeprom24c0x_read());
283: break;
284:
285:
286: case 0x00b08:
287: val = s->i2coe;
288: break;
289:
290:
291: case 0x00b10:
292: val = s->i2cout;
293: break;
294:
295:
296: case 0x00b18:
297: val = s->i2csel;
298: break;
299:
300: default:
301: #if 0
302: printf ("malta_fpga_read: Bad register offset 0x" TARGET_FMT_lx "\n",
303: addr);
304: #endif
305: break;
306: }
307: return val;
308: }
309:
310: static void malta_fpga_writel(void *opaque, target_phys_addr_t addr,
311: uint32_t val)
312: {
313: MaltaFPGAState *s = opaque;
314: uint32_t saddr;
315:
316: saddr = (addr & 0xfffff);
317:
318: switch (saddr) {
319:
320:
321: case 0x00200:
322: break;
323:
324:
325: case 0x00210:
326: break;
327:
328:
329:
330: case 0x00408:
331: s->leds = val & 0xff;
332: break;
333:
334:
335: case 0x00410:
336: snprintf(s->display_text, 9, "%08X", val);
337: malta_fpga_update_display(s);
338: break;
339:
340:
341: case 0x00418:
342: case 0x00420:
343: case 0x00428:
344: case 0x00430:
345: case 0x00438:
346: case 0x00440:
347: case 0x00448:
348: case 0x00450:
349: s->display_text[(saddr - 0x00418) >> 3] = (char) val;
350: malta_fpga_update_display(s);
351: break;
352:
353:
354: case 0x00500:
355: if (val == 0x42)
356: qemu_system_reset_request ();
357: break;
358:
359:
360: case 0x00508:
361: s->brk = val & 0xff;
362: break;
363:
364:
365:
366:
367: case 0x00a00:
368: s->gpout = val & 0xff;
369: break;
370:
371:
372: case 0x00b08:
373: s->i2coe = val & 0x03;
374: break;
375:
376:
377: case 0x00b10:
378: eeprom24c0x_write(val & 0x02, val & 0x01);
379: s->i2cout = val;
380: break;
381:
382:
383: case 0x00b18:
384: s->i2csel = val & 0x01;
385: break;
386:
387: default:
388: #if 0
389: printf ("malta_fpga_write: Bad register offset 0x" TARGET_FMT_lx "\n",
390: addr);
391: #endif
392: break;
393: }
394: }
395:
396: static CPUReadMemoryFunc *malta_fpga_read[] = {
397: malta_fpga_readl,
398: malta_fpga_readl,
399: malta_fpga_readl
400: };
401:
402: static CPUWriteMemoryFunc *malta_fpga_write[] = {
403: malta_fpga_writel,
404: malta_fpga_writel,
405: malta_fpga_writel
406: };
407:
408: static void malta_fpga_reset(void *opaque)
409: {
410: MaltaFPGAState *s = opaque;
411:
412: s->leds = 0x00;
413: s->brk = 0x0a;
414: s->gpout = 0x00;
415: s->i2cin = 0x3;
416: s->i2coe = 0x0;
417: s->i2cout = 0x3;
418: s->i2csel = 0x1;
419:
420: s->display_text[8] = '\0';
421: snprintf(s->display_text, 9, " ");
422: malta_fpga_update_display(s);
423: }
424:
425: static MaltaFPGAState *malta_fpga_init(target_phys_addr_t base, CPUState *env)
426: {
427: MaltaFPGAState *s;
428: CharDriverState *uart_chr;
429: int malta;
430:
431: s = (MaltaFPGAState *)qemu_mallocz(sizeof(MaltaFPGAState));
432:
433: malta = cpu_register_io_memory(0, malta_fpga_read,
434: malta_fpga_write, s);
435:
436: cpu_register_physical_memory(base, 0x900, malta);
437: cpu_register_physical_memory(base + 0xa00, 0x100000 - 0xa00, malta);
438:
439: s->display = qemu_chr_open("vc");
440: qemu_chr_printf(s->display, "\e[HMalta LEDBAR\r\n");
441: qemu_chr_printf(s->display, "+--------+\r\n");
442: qemu_chr_printf(s->display, "+ +\r\n");
443: qemu_chr_printf(s->display, "+--------+\r\n");
444: qemu_chr_printf(s->display, "\n");
445: qemu_chr_printf(s->display, "Malta ASCII\r\n");
446: qemu_chr_printf(s->display, "+--------+\r\n");
447: qemu_chr_printf(s->display, "+ +\r\n");
448: qemu_chr_printf(s->display, "+--------+\r\n");
449:
450: uart_chr = qemu_chr_open("vc");
451: qemu_chr_printf(uart_chr, "CBUS UART\r\n");
452: s->uart = serial_mm_init(base + 0x900, 3, env->irq[2], uart_chr, 1);
453:
454: malta_fpga_reset(s);
455: qemu_register_reset(malta_fpga_reset, s);
456:
457: return s;
458: }
459:
460:
461: #ifdef HAS_AUDIO
462: static void audio_init (PCIBus *pci_bus)
463: {
464: struct soundhw *c;
465: int audio_enabled = 0;
466:
467: for (c = soundhw; !audio_enabled && c->name; ++c) {
468: audio_enabled = c->enabled;
469: }
470:
471: if (audio_enabled) {
472: AudioState *s;
473:
474: s = AUD_init ();
475: if (s) {
476: for (c = soundhw; c->name; ++c) {
477: if (c->enabled)
478: c->init.init_pci (pci_bus, s);
479: }
480: }
481: }
482: }
483: #endif
484:
485:
486: static void network_init (PCIBus *pci_bus)
487: {
488: int i;
489: NICInfo *nd;
490:
491: for(i = 0; i < nb_nics; i++) {
492: nd = &nd_table[i];
493: if (!nd->model) {
494: nd->model = "pcnet";
495: }
496: if (i == 0 && strcmp(nd->model, "pcnet") == 0) {
497:
498: pci_nic_init(pci_bus, nd, 88);
499: } else {
500: pci_nic_init(pci_bus, nd, -1);
501: }
502: }
503: }
504:
505:
506:
507:
508:
509:
510:
511:
512:
513:
514:
515:
516:
517:
518:
519:
520:
521:
522:
523:
524:
525:
526:
527: static void write_bootloader (CPUState *env, unsigned long bios_offset, int64_t kernel_entry)
528: {
529: uint32_t *p;
530:
531:
532: p = (uint32_t *) (phys_ram_base + bios_offset);
533: stl_raw(p++, 0x0bf00160);
534: stl_raw(p++, 0x00000000);
535:
536:
537: stl_raw(phys_ram_base + bios_offset + 0x500, 0xbfc00580);
538: stl_raw(phys_ram_base + bios_offset + 0x504, 0xbfc0083c);
539: stl_raw(phys_ram_base + bios_offset + 0x520, 0xbfc00580);
540: stl_raw(phys_ram_base + bios_offset + 0x52c, 0xbfc00800);
541: stl_raw(phys_ram_base + bios_offset + 0x534, 0xbfc00808);
542: stl_raw(phys_ram_base + bios_offset + 0x538, 0xbfc00800);
543: stl_raw(phys_ram_base + bios_offset + 0x53c, 0xbfc00800);
544: stl_raw(phys_ram_base + bios_offset + 0x540, 0xbfc00800);
545: stl_raw(phys_ram_base + bios_offset + 0x544, 0xbfc00800);
546: stl_raw(phys_ram_base + bios_offset + 0x548, 0xbfc00800);
547: stl_raw(phys_ram_base + bios_offset + 0x54c, 0xbfc00800);
548: stl_raw(phys_ram_base + bios_offset + 0x550, 0xbfc00800);
549: stl_raw(phys_ram_base + bios_offset + 0x554, 0xbfc00800);
550:
551:
552:
553: p = (uint32_t *) (phys_ram_base + bios_offset + 0x580);
554: stl_raw(p++, 0x24040002);
555: stl_raw(p++, 0x3c1d0000 | (((ENVP_ADDR - 64) >> 16) & 0xffff));
556: stl_raw(p++, 0x37bd0000 | ((ENVP_ADDR - 64) & 0xffff));
557: stl_raw(p++, 0x3c050000 | ((ENVP_ADDR >> 16) & 0xffff));
558: stl_raw(p++, 0x34a50000 | (ENVP_ADDR & 0xffff));
559: stl_raw(p++, 0x3c060000 | (((ENVP_ADDR + 8) >> 16) & 0xffff));
560: stl_raw(p++, 0x34c60000 | ((ENVP_ADDR + 8) & 0xffff));
561: stl_raw(p++, 0x3c070000 | (loaderparams.ram_size >> 16));
562: stl_raw(p++, 0x34e70000 | (loaderparams.ram_size &