]> Git Repo - qemu.git/blob - hw/ppc_prep.c
PowerPC system emulation fixes (Jocelyn Mayer)
[qemu.git] / hw / ppc_prep.c
1 /*
2  * QEMU PPC PREP hardware System Emulator
3  * 
4  * Copyright (c) 2003-2004 Jocelyn Mayer
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 #include <stdlib.h>
25 #include <stdio.h>
26 #include <stdarg.h>
27 #include <string.h>
28 #include <getopt.h>
29 #include <inttypes.h>
30 #include <unistd.h>
31 #include <sys/mman.h>
32 #include <fcntl.h>
33 #include <signal.h>
34 #include <time.h>
35 #include <sys/time.h>
36 #include <malloc.h>
37 #include <termios.h>
38 #include <sys/poll.h>
39 #include <errno.h>
40 #include <sys/wait.h>
41 #include <netinet/in.h>
42
43 #include "cpu.h"
44 #include "vl.h"
45 #include "m48t59.h"
46
47 //#define HARD_DEBUG_PPC_IO
48 //#define DEBUG_PPC_IO
49
50 extern int loglevel;
51 extern FILE *logfile;
52
53 #if defined (HARD_DEBUG_PPC_IO) && !defined (DEBUG_PPC_IO)
54 #define DEBUG_PPC_IO
55 #endif
56
57 #if defined (HARD_DEBUG_PPC_IO)
58 #define PPC_IO_DPRINTF(fmt, args...)                     \
59 do {                                                     \
60     if (loglevel > 0) {                                  \
61         fprintf(logfile, "%s: " fmt, __func__ , ##args); \
62     } else {                                             \
63         printf("%s : " fmt, __func__ , ##args);          \
64     }                                                    \
65 } while (0)
66 #elif defined (DEBUG_PPC_IO)
67 #define PPC_IO_DPRINTF(fmt, args...)                     \
68 do {                                                     \
69     if (loglevel > 0) {                                  \
70         fprintf(logfile, "%s: " fmt, __func__ , ##args); \
71     }                                                    \
72 } while (0)
73 #else
74 #define PPC_IO_DPRINTF(fmt, args...) do { } while (0)
75 #endif
76
77 #define BIOS_FILENAME "ppc_rom.bin"
78 #define LINUX_BOOT_FILENAME "linux_boot.bin"
79
80 #define KERNEL_LOAD_ADDR    0x00000000
81 #define KERNEL_STACK_ADDR   0x00400000
82 #define INITRD_LOAD_ADDR    0x00800000
83
84 int load_kernel(const char *filename, uint8_t *addr, 
85                 uint8_t *real_addr)
86 {
87     int fd, size;
88     int setup_sects;
89
90     fd = open(filename, O_RDONLY);
91     if (fd < 0)
92         return -1;
93
94     /* load 16 bit code */
95     if (read(fd, real_addr, 512) != 512)
96         goto fail;
97     setup_sects = real_addr[0x1F1];
98     if (!setup_sects)
99         setup_sects = 4;
100     if (read(fd, real_addr + 512, setup_sects * 512) != 
101         setup_sects * 512)
102         goto fail;
103     
104     /* load 32 bit code */
105     size = read(fd, addr, 16 * 1024 * 1024);
106     if (size < 0)
107         goto fail;
108     close(fd);
109     return size;
110  fail:
111     close(fd);
112     return -1;
113 }
114
115 static const int ide_iobase[2] = { 0x1f0, 0x170 };
116 static const int ide_iobase2[2] = { 0x3f6, 0x376 };
117 static const int ide_irq[2] = { 13, 13 };
118
119 #define NE2000_NB_MAX 6
120
121 static uint32_t ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 };
122 static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 };
123
124 /* IO ports emulation */
125 #define PPC_IO_BASE 0x80000000
126
127 static void PPC_io_writeb (uint32_t addr, uint32_t value, uint32_t vaddr)
128 {
129     /* Don't polute serial port output */
130 #if 0
131     if ((addr < 0x800003F0 || addr > 0x80000400) &&
132         (addr < 0x80000074 || addr > 0x80000077) &&
133         (addr < 0x80000020 || addr > 0x80000021) &&
134         (addr < 0x800000a0 || addr > 0x800000a1) &&
135         (addr < 0x800001f0 || addr > 0x800001f7) &&
136         (addr < 0x80000170 || addr > 0x80000177)) 
137 #endif
138     {
139         PPC_IO_DPRINTF("0x%08x => 0x%02x\n", addr - PPC_IO_BASE, value);
140     }
141     cpu_outb(NULL, addr - PPC_IO_BASE, value);
142 }
143
144 static uint32_t PPC_io_readb (uint32_t addr)
145 {
146     uint32_t ret = cpu_inb(NULL, addr - PPC_IO_BASE);
147
148 #if 0
149     if ((addr < 0x800003F0 || addr > 0x80000400) &&
150         (addr < 0x80000074 || addr > 0x80000077) &&
151         (addr < 0x80000020 || addr > 0x80000021) &&
152         (addr < 0x800000a0 || addr > 0x800000a1) &&
153         (addr < 0x800001f0 || addr > 0x800001f7) &&
154         (addr < 0x80000170 || addr > 0x80000177) &&
155         (addr < 0x8000060 || addr > 0x8000064))
156 #endif
157     {
158         PPC_IO_DPRINTF("0x%08x <= 0x%02x\n", addr - PPC_IO_BASE, ret);
159     }
160
161     return ret;
162 }
163
164 static void PPC_io_writew (uint32_t addr, uint32_t value, uint32_t vaddr)
165 {
166     if ((addr < 0x800001f0 || addr > 0x800001f7) &&
167         (addr < 0x80000170 || addr > 0x80000177)) {
168         PPC_IO_DPRINTF("0x%08x => 0x%04x\n", addr - PPC_IO_BASE, value);
169     }
170     cpu_outw(NULL, addr - PPC_IO_BASE, value);
171 }
172
173 static uint32_t PPC_io_readw (uint32_t addr)
174 {
175     uint32_t ret = cpu_inw(NULL, addr - PPC_IO_BASE);
176
177     if ((addr < 0x800001f0 || addr > 0x800001f7) &&
178         (addr < 0x80000170 || addr > 0x80000177)) {
179         PPC_IO_DPRINTF("0x%08x <= 0x%04x\n", addr - PPC_IO_BASE, ret);
180     }
181
182     return ret;
183 }
184
185 static void PPC_io_writel (uint32_t addr, uint32_t value, uint32_t vaddr)
186 {
187     PPC_IO_DPRINTF("0x%08x => 0x%08x\n", addr - PPC_IO_BASE, value);
188     cpu_outl(NULL, addr - PPC_IO_BASE, value);
189 }
190
191 static uint32_t PPC_io_readl (uint32_t addr)
192 {
193     uint32_t ret = cpu_inl(NULL, addr - PPC_IO_BASE);
194
195     PPC_IO_DPRINTF("0x%08x <= 0x%08x\n", addr - PPC_IO_BASE, ret);
196
197     return ret;
198 }
199
200 static CPUWriteMemoryFunc *PPC_io_write[] = {
201     &PPC_io_writeb,
202     &PPC_io_writew,
203     &PPC_io_writel,
204 };
205
206 static CPUReadMemoryFunc *PPC_io_read[] = {
207     &PPC_io_readb,
208     &PPC_io_readw,
209     &PPC_io_readl,
210 };
211
212 uint32_t pic_intack_read(CPUState *env);
213
214 /* Read-only register (?) */
215 static void _PPC_ioB_write (uint32_t addr, uint32_t value, uint32_t vaddr)
216 {
217     //    printf("%s: 0x%08x => 0x%08x\n", __func__, addr, value);
218 }
219
220 static uint32_t _PPC_ioB_read (uint32_t addr)
221 {
222     uint32_t retval = 0;
223
224     if (addr == 0xBFFFFFF0)
225         retval = pic_intack_read(NULL);
226        //   printf("%s: 0x%08x <= %d\n", __func__, addr, retval);
227
228     return retval;
229 }
230
231 static CPUWriteMemoryFunc *PPC_ioB_write[] = {
232     &_PPC_ioB_write,
233     &_PPC_ioB_write,
234     &_PPC_ioB_write,
235 };
236
237 static CPUReadMemoryFunc *PPC_ioB_read[] = {
238     &_PPC_ioB_read,
239     &_PPC_ioB_read,
240     &_PPC_ioB_read,
241 };
242
243 #if 0
244 static CPUWriteMemoryFunc *PPC_io3_write[] = {
245     &PPC_io3_writeb,
246     &PPC_io3_writew,
247     &PPC_io3_writel,
248 };
249
250 static CPUReadMemoryFunc *PPC_io3_read[] = {
251     &PPC_io3_readb,
252     &PPC_io3_readw,
253     &PPC_io3_readl,
254 };
255 #endif
256
257 /* Fake super-io ports for PREP platform (Intel 82378ZB) */
258 static uint8_t PREP_fake_io[2];
259 static uint8_t NVRAM_lock;
260
261 static void PREP_io_write (void *opaque, uint32_t addr, uint32_t val)
262 {
263     PPC_IO_DPRINTF("0x%08x => 0x%08x\n", addr - PPC_IO_BASE, val);
264     PREP_fake_io[addr - 0x0398] = val;
265 }
266
267 static uint32_t PREP_io_read (void *opaque, uint32_t addr)
268 {
269     PPC_IO_DPRINTF("0x%08x <= 0x%08x\n", addr - PPC_IO_BASE, PREP_fake_io[addr - 0x0398]);
270     return PREP_fake_io[addr - 0x0398];
271 }
272
273 static uint8_t syscontrol;
274
275 static void PREP_io_800_writeb (void *opaque, uint32_t addr, uint32_t val)
276 {
277     PPC_IO_DPRINTF("0x%08x => 0x%08x\n", addr - PPC_IO_BASE, val);
278     switch (addr) {
279     case 0x0092:
280         /* Special port 92 */
281         /* Check soft reset asked */
282         if (val & 0x80) {
283             printf("Soft reset asked... Stop emulation\n");
284             abort();
285         }
286         /* Check LE mode */
287         if (val & 0x40) {
288             printf("Little Endian mode isn't supported (yet ?)\n");
289             abort();
290         }
291         break;
292     case 0x0808:
293         /* Hardfile light register: don't care */
294         break;
295     case 0x0810:
296         /* Password protect 1 register */
297         NVRAM_lock ^= 0x01;
298         break;
299     case 0x0812:
300         /* Password protect 2 register */
301         NVRAM_lock ^= 0x02;
302         break;
303     case 0x0814:
304         /* L2 invalidate register: don't care */
305         break;
306     case 0x081C:
307         /* system control register */
308         syscontrol = val;
309         break;
310     case 0x0850:
311         /* I/O map type register */
312         if (val & 0x80) {
313             printf("No support for non-continuous I/O map mode\n");
314             abort();
315         }
316         break;
317     default:
318         break;
319     }
320 }
321
322 static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr)
323 {
324     uint32_t retval = 0xFF;
325
326     switch (addr) {
327     case 0x0092:
328         /* Special port 92 */
329         retval = 0x40;
330         break;
331     case 0x080C:
332         /* Equipment present register:
333          *  no L2 cache
334          *  no upgrade processor
335          *  no cards in PCI slots
336          *  SCSI fuse is bad
337          */
338         retval = 0xFC;
339         break;
340     case 0x0818:
341         /* Keylock */
342         retval = 0x00;
343         break;
344     case 0x081C:
345         /* system control register
346          * 7 - 6 / 1 - 0: L2 cache enable
347          */
348         retval = syscontrol;
349         break;
350     case 0x0823:
351         /* */
352         retval = 0x03; /* no L2 cache */
353         break;
354     case 0x0850:
355         /* I/O map type register */
356         retval = 0x00;
357         break;
358     default:
359         break;
360     }
361     PPC_IO_DPRINTF("0x%08x <= 0x%08x\n", addr - PPC_IO_BASE, retval);
362
363     return retval;
364 }
365
366 #define NVRAM_SIZE        0x2000
367 #define NVRAM_END         0x1FF0
368 #define NVRAM_OSAREA_SIZE 512
369 #define NVRAM_CONFSIZE    1024
370
371 static inline void NVRAM_set_byte (void *opaque, uint32_t addr, uint8_t value)
372 {
373     m48t59_set_addr(opaque, addr);
374     m48t59_write(opaque, value);
375 }
376
377 static inline uint8_t NVRAM_get_byte (void *opaque, uint32_t addr)
378 {
379     m48t59_set_addr(opaque, addr);
380     return m48t59_read(opaque);
381 }
382
383 static inline void NVRAM_set_word (void *opaque, uint32_t addr, uint16_t value)
384 {
385     m48t59_set_addr(opaque, addr);
386     m48t59_write(opaque, value >> 8);
387     m48t59_set_addr(opaque, addr + 1);
388     m48t59_write(opaque, value & 0xFF);
389 }
390
391 static inline uint16_t NVRAM_get_word (void *opaque, uint32_t addr)
392 {
393     uint16_t tmp;
394
395     m48t59_set_addr(opaque, addr);
396     tmp = m48t59_read(opaque) << 8;
397     m48t59_set_addr(opaque, addr + 1);
398     tmp |= m48t59_read(opaque);
399
400     return tmp;
401 }
402
403 static inline void NVRAM_set_lword (void *opaque, uint32_t addr,
404                                     uint32_t value)
405 {
406     m48t59_set_addr(opaque, addr);
407     m48t59_write(opaque, value >> 24);
408     m48t59_set_addr(opaque, addr + 1);
409     m48t59_write(opaque, (value >> 16) & 0xFF);
410     m48t59_set_addr(opaque, addr + 2);
411     m48t59_write(opaque, (value >> 8) & 0xFF);
412     m48t59_set_addr(opaque, addr + 3);
413     m48t59_write(opaque, value & 0xFF);
414 }
415
416 static inline uint32_t NVRAM_get_lword (void *opaque, uint32_t addr)
417 {
418     uint32_t tmp;
419
420     m48t59_set_addr(opaque, addr);
421     tmp = m48t59_read(opaque) << 24;
422     m48t59_set_addr(opaque, addr + 1);
423     tmp |= m48t59_read(opaque) << 16;
424     m48t59_set_addr(opaque, addr + 2);
425     tmp |= m48t59_read(opaque) << 8;
426     m48t59_set_addr(opaque, addr + 3);
427     tmp |= m48t59_read(opaque);
428
429     return tmp;
430 }
431
432 static uint16_t NVRAM_crc_update (uint16_t prev, uint16_t value)
433 {
434     uint16_t tmp;
435     uint16_t pd, pd1, pd2;
436
437     tmp = prev >> 8;
438     pd = prev ^ value;
439     pd1 = pd & 0x000F;
440     pd2 = ((pd >> 4) & 0x000F) ^ pd1;
441     tmp ^= (pd1 << 3) | (pd1 << 8);
442     tmp ^= pd2 | (pd2 << 7) | (pd2 << 12);
443
444     return tmp;
445 }
446
447 static void NVRAM_set_crc (void *opaque, uint32_t addr,
448                            uint32_t start, uint32_t count)
449 {
450     uint32_t i;
451     uint16_t crc = 0xFFFF;
452     int odd = 0;
453
454     if (count & 1)
455         odd = 1;
456     count &= ~1;
457     for (i = 0; i != count; i++) {
458         crc = NVRAM_crc_update(crc, NVRAM_get_word(opaque, start + i));
459     }
460     if (odd) {
461         crc = NVRAM_crc_update(crc, NVRAM_get_byte(opaque, start + i) << 8);
462     }
463     NVRAM_set_word(opaque, addr, crc);
464 }
465
466 static void prep_NVRAM_init (void)
467 {
468     void *opaque;
469
470     opaque = m48t59_init(8, 0x0074, NVRAM_SIZE);
471     /* NVRAM header */
472     /* 0x00: NVRAM size in kB */
473     NVRAM_set_word(opaque, 0x00, NVRAM_SIZE >> 10);
474     /* 0x02: NVRAM version */
475     NVRAM_set_byte(opaque, 0x02, 0x01);
476     /* 0x03: NVRAM revision */
477     NVRAM_set_byte(opaque, 0x03, 0x01);
478     /* 0x08: last OS */
479     NVRAM_set_byte(opaque, 0x08, 0x00); /* Unknown */
480     /* 0x09: endian */
481     NVRAM_set_byte(opaque, 0x09, 'B');  /* Big-endian */
482     /* 0x0A: OSArea usage */
483     NVRAM_set_byte(opaque, 0x0A, 0x00); /* Empty */
484     /* 0x0B: PM mode */
485     NVRAM_set_byte(opaque, 0x0B, 0x00); /* Normal */
486     /* Restart block description record */
487     /* 0x0C: restart block version */
488     NVRAM_set_word(opaque, 0x0C, 0x01);
489     /* 0x0E: restart block revision */
490     NVRAM_set_word(opaque, 0x0E, 0x01);
491     /* 0x20: restart address */
492     NVRAM_set_lword(opaque, 0x20, 0x00);
493     /* 0x24: save area address */
494     NVRAM_set_lword(opaque, 0x24, 0x00);
495     /* 0x28: save area length */
496     NVRAM_set_lword(opaque, 0x28, 0x00);
497     /* 0x1C: checksum of restart block */
498     NVRAM_set_crc(opaque, 0x1C, 0x0C, 32);
499
500     /* Security section */
501     /* Set all to zero */
502     /* 0xC4: pointer to global environment area */
503     NVRAM_set_lword(opaque, 0xC4, 0x0100);
504     /* 0xC8: size of global environment area */
505     NVRAM_set_lword(opaque, 0xC8,
506                     NVRAM_END - NVRAM_OSAREA_SIZE - NVRAM_CONFSIZE - 0x0100);
507     /* 0xD4: pointer to configuration area */
508     NVRAM_set_lword(opaque, 0xD4, NVRAM_END - NVRAM_CONFSIZE);
509     /* 0xD8: size of configuration area */
510     NVRAM_set_lword(opaque, 0xD8, NVRAM_CONFSIZE);
511     /* 0xE8: pointer to OS specific area */
512     NVRAM_set_lword(opaque, 0xE8,
513                     NVRAM_END - NVRAM_CONFSIZE - NVRAM_OSAREA_SIZE);
514     /* 0xD8: size of OS specific area */
515     NVRAM_set_lword(opaque, 0xEC, NVRAM_OSAREA_SIZE);
516
517     /* Configuration area */
518     /* RTC init */
519     //    NVRAM_set_lword(opaque, 0x1FFC, 0x50);
520
521     /* 0x04: checksum 0 => OS area   */
522     NVRAM_set_crc(opaque, 0x04, 0x00,
523                   NVRAM_END - NVRAM_CONFSIZE - NVRAM_OSAREA_SIZE);
524     /* 0x06: checksum of config area */
525     NVRAM_set_crc(opaque, 0x06, NVRAM_END - NVRAM_CONFSIZE, NVRAM_CONFSIZE);
526 }
527
528 int load_initrd (const char *filename, uint8_t *addr)
529 {
530     int fd, size;
531
532     printf("Load initrd\n");
533     fd = open(filename, O_RDONLY);
534     if (fd < 0)
535         return -1;
536     size = read(fd, addr, 16 * 1024 * 1024);
537     if (size < 0)
538         goto fail;
539     close(fd);
540     printf("Load initrd: %d\n", size);
541     return size;
542  fail:
543     close(fd);
544     printf("Load initrd failed\n");
545     return -1;
546 }
547
548 /* Quick hack for PPC memory infos... */
549 static void put_long (void *addr, uint32_t l)
550 {
551     char *pos = addr;
552     pos[0] = (l >> 24) & 0xFF;
553     pos[1] = (l >> 16) & 0xFF;
554     pos[2] = (l >> 8) & 0xFF;
555     pos[3] = l & 0xFF;
556 }
557
558 /* bootloader infos are in the form:
559  * uint32_t TAG
560  * uint32_t TAG_size (from TAG to next TAG).
561  * data
562  * ....
563  */
564 #if !defined (USE_OPEN_FIRMWARE)
565 static void *set_bootinfo_tag (void *addr, uint32_t tag, uint32_t size,
566                                void *data)
567 {
568     char *pos = addr;
569
570     put_long(pos, tag);
571     pos += 4;
572     put_long(pos, size + 8);
573     pos += 4;
574     memcpy(pos, data, size);
575     pos += size;
576
577     return pos;
578 }
579 #endif
580
581 typedef struct boot_dev_t {
582     const unsigned char *name;
583     int major;
584     int minor;
585 } boot_dev_t;
586
587 static boot_dev_t boot_devs[] = 
588 {
589     { "/dev/fd0", 2, 0, },
590     { "/dev/fd1", 2, 1, },
591     { "/dev/hda", 3, 1, },
592 //    { "/dev/ide/host0/bus0/target0/lun0/part1", 3, 1, },
593 //    { "/dev/hdc", 22, 0, },
594     { "/dev/hdc", 22, 1, },
595     { "/dev/ram0 init=/linuxrc", 1, 0, },
596 };
597
598 /* BATU:
599  * BEPI  : bloc virtual address
600  * BL    : area size bits (128 kB is 0, 256 1, 512 3, ...
601  * Vs/Vp
602  * BATL:
603  * BPRN  : bloc real address align on 4MB boundary
604  * WIMG  : cache access mode : not used
605  * PP    : protection bits
606  */
607 static void setup_BAT (CPUPPCState *env, int BAT,
608                        uint32_t virtual, uint32_t physical,
609                        uint32_t size, int Vs, int Vp, int PP)
610 {
611     uint32_t sz_bits, tmp_sz, align, tmp;
612     
613     sz_bits = 0;
614     align = 131072;
615     for (tmp_sz = size / 131072; tmp_sz != 1; tmp_sz = tmp_sz >> 1) {
616         sz_bits = (sz_bits << 1) + 1;
617         align = align << 1;
618     }
619     tmp = virtual & ~(align - 1);  /* Align virtual area start */
620     tmp |= sz_bits << 2;           /* Fix BAT size             */
621     tmp |= Vs << 1;                /* Supervisor access        */
622     tmp |= Vp;                     /* User access              */
623     env->DBAT[0][BAT] = tmp;
624     env->IBAT[0][BAT] = tmp;
625     tmp = physical & ~(align - 1); /* Align physical area start */
626     tmp |= 0;                      /* Don't care about WIMG     */
627     tmp |= PP;                     /* Protection                */
628     env->DBAT[1][BAT] = tmp;
629     env->IBAT[1][BAT] = tmp;
630     printf("Set BATU0 to 0x%08x BATL0 to 0x%08x\n",
631            env->DBAT[0][BAT], env->DBAT[1][BAT]);
632 }
633
634 static void VGA_printf (uint8_t *s)
635 {
636     uint16_t *arg_ptr;
637     unsigned int format_width, i;
638     int in_format;
639     uint16_t arg, digit, nibble;
640     uint8_t c;
641
642     arg_ptr = (uint16_t *)((void *)&s);
643     in_format = 0;
644     format_width = 0;
645     while ((c = *s) != '\0') {
646         if (c == '%') {
647             in_format = 1;
648             format_width = 0;
649         } else if (in_format) {
650             if ((c >= '0') && (c <= '9')) {
651                 format_width = (format_width * 10) + (c - '0');
652             } else if (c == 'x') {
653                 arg_ptr++; // increment to next arg
654                 arg = *arg_ptr;
655                 if (format_width == 0)
656                     format_width = 4;
657                 digit = format_width - 1;
658                 for (i = 0; i < format_width; i++) {
659                     nibble = (arg >> (4 * digit)) & 0x000f;
660                     if (nibble <= 9)
661                         PPC_io_writeb(PPC_IO_BASE + 0x500, nibble + '0', 0);
662                     else
663                         PPC_io_writeb(PPC_IO_BASE + 0x500, nibble + 'A', 0);
664                     digit--;
665                 }
666                 in_format = 0;
667             }
668             //else if (c == 'd') {
669             //  in_format = 0;
670             //  }
671         } else {
672             PPC_io_writeb(PPC_IO_BASE + 0x500, c, 0);
673         }
674         s++;
675     }
676 }
677
678 static void VGA_init (void)
679 {
680     /* Basic VGA init, inspired by plex86 VGAbios */
681     printf("Init VGA...\n");
682 #if 1
683     /* switch to color mode and enable CPU access 480 lines */
684     PPC_io_writeb(PPC_IO_BASE + 0x3C2, 0xC3, 0);
685     /* more than 64k 3C4/04 */
686     PPC_io_writeb(PPC_IO_BASE + 0x3C4, 0x04, 0);
687     PPC_io_writeb(PPC_IO_BASE + 0x3C5, 0x02, 0);
688 #endif
689     VGA_printf("PPC VGA BIOS...\n");
690 }
691
692 extern CPUPPCState *global_env;
693
694 void PPC_init_hw (/*CPUPPCState *env,*/ uint32_t mem_size,
695                   uint32_t kernel_addr, uint32_t kernel_size,
696                   uint32_t stack_addr, int boot_device,
697                   const unsigned char *initrd_file)
698 {
699     CPUPPCState *env = global_env;
700     char *p;
701 #if !defined (USE_OPEN_FIRMWARE)
702     char *tmp;
703     uint32_t tmpi[2];
704 #endif
705
706     printf("RAM size: %u 0x%08x (%u)\n", mem_size, mem_size, mem_size >> 20);
707 #if defined (USE_OPEN_FIRMWARE)
708     setup_memory(env, mem_size);
709 #endif
710
711     /* Fake bootloader */
712     {
713 #if 1
714         uint32_t offset = 
715             *((uint32_t *)((uint32_t)phys_ram_base + kernel_addr));
716 #else
717         uint32_t offset = 12;
718 #endif
719         env->nip = kernel_addr + offset;
720         printf("Start address: 0x%08x\n", env->nip);
721     }
722     /* Set up msr according to PREP specification */
723     msr_ee = 0;
724     msr_fp = 1;
725     msr_pr = 0; /* Start in supervisor mode */
726     msr_me = 1;
727     msr_fe0 = msr_fe1 = 0;
728     msr_ip = 0;
729     msr_ir = msr_dr = 1;
730 //    msr_sf = 0;
731     msr_le = msr_ile = 0;
732     env->gpr[1] = stack_addr; /* Let's have a stack */
733     env->gpr[2] = 0;
734     env->gpr[8] = kernel_addr;
735     /* There is a bug in  2.4 kernels:
736      * if a decrementer exception is pending when it enables msr_ee,
737      * it's not ready to handle it...
738      */
739     env->decr = 0xFFFFFFFF;
740     p = (void *)(phys_ram_base + kernel_addr);
741 #if !defined (USE_OPEN_FIRMWARE)
742     /* Let's register the whole memory available only in supervisor mode */
743     setup_BAT(env, 0, 0x00000000, 0x00000000, mem_size, 1, 0, 2);
744     /* Avoid open firmware init call (to get a console)
745      * This will make the kernel think we are a PREP machine...
746      */
747     put_long(p, 0xdeadc0de);
748     /* Build a real stack room */
749     p = (void *)(phys_ram_base + stack_addr);
750     put_long(p, stack_addr);
751     p -= 32;
752     env->gpr[1] -= 32;
753     /* Pretend there are no residual data */
754     env->gpr[3] = 0;
755     if (initrd_file != NULL) {
756         int size;
757         env->gpr[4] = (kernel_addr + kernel_size + 4095) & ~4095;
758         size = load_initrd(initrd_file,
759                            (void *)((uint32_t)phys_ram_base + env->gpr[4]));
760         if (size < 0) {
761             /* No initrd */
762             env->gpr[4] = env->gpr[5] = 0;
763         } else {
764             env->gpr[5] = size;
765             boot_device = 'e';
766         }
767         printf("Initrd loaded at 0x%08x (%d) (0x%08x 0x%08x)\n",
768                env->gpr[4], env->gpr[5], kernel_addr, kernel_size);
769     } else {
770         env->gpr[4] = env->gpr[5] = 0;
771     }
772     /* We have to put bootinfos after the BSS
773      * The BSS starts after the kernel end.
774      */
775 #if 0
776     p = (void *)(((uint32_t)phys_ram_base + kernel_addr +
777                   kernel_size + (1 << 20) - 1) & ~((1 << 20) - 1));
778 #else
779     p = (void *)((uint32_t)phys_ram_base + kernel_addr + 0x400000);
780 #endif
781     if (loglevel > 0) {
782         fprintf(logfile, "bootinfos: %p 0x%08x\n",
783                 p, (uint32_t)p - (uint32_t)phys_ram_base);
784     } else {
785         printf("bootinfos: %p 0x%08x\n",
786                p, (uint32_t)p - (uint32_t)phys_ram_base);
787     }
788     /* Command line: let's put it after bootinfos */
789 #if 0
790     sprintf(p + 0x1000, "console=ttyS0,9600 root=%02x%02x mem=%dM",
791             boot_devs[boot_device - 'a'].major,
792             boot_devs[boot_device - 'a'].minor,
793             mem_size >> 20);
794 #else
795     sprintf(p + 0x1000, "console=ttyS0,9600 console=tty0 root=%s mem=%dM",
796             boot_devs[boot_device - 'a'].name,
797             mem_size >> 20);
798 #endif
799     env->gpr[6] = (uint32_t)p + 0x1000 - (uint32_t)phys_ram_base;
800     env->gpr[7] = env->gpr[6] + strlen(p + 0x1000);
801     if (loglevel > 0) {
802         fprintf(logfile, "cmdline: %p 0x%08x [%s]\n",
803                 p + 0x1000, env->gpr[6], p + 0x1000);
804     } else {
805         printf("cmdline: %p 0x%08x [%s]\n",
806                p + 0x1000, env->gpr[6], p + 0x1000);
807     }
808     /* BI_FIRST */
809     p = set_bootinfo_tag(p, 0x1010, 0, 0);
810     /* BI_CMD_LINE */
811     p = set_bootinfo_tag(p, 0x1012, env->gpr[7] - env->gpr[6],
812                          (void *)(env->gpr[6] + (uint32_t)phys_ram_base));
813     /* BI_MEM_SIZE */
814     tmp = (void *)tmpi;
815     tmp[0] = (mem_size >> 24) & 0xFF;
816     tmp[1] = (mem_size >> 16) & 0xFF;
817     tmp[2] = (mem_size >> 8) & 0xFF;
818     tmp[3] = mem_size & 0xFF;
819     p = set_bootinfo_tag(p, 0x1017, 4, tmpi);
820     /* BI_INITRD */
821     tmp[0] = (env->gpr[4] >> 24) & 0xFF;
822     tmp[1] = (env->gpr[4] >> 16) & 0xFF;
823     tmp[2] = (env->gpr[4] >> 8) & 0xFF;
824     tmp[3] = env->gpr[4] & 0xFF;
825     tmp[4] = (env->gpr[5] >> 24) & 0xFF;
826     tmp[5] = (env->gpr[5] >> 16) & 0xFF;
827     tmp[6] = (env->gpr[5] >> 8) & 0xFF;
828     tmp[7] = env->gpr[5] & 0xFF;
829     p = set_bootinfo_tag(p, 0x1014, 8, tmpi);
830     env->gpr[4] = env->gpr[5] = 0;
831     /* BI_LAST */
832     p = set_bootinfo_tag(p, 0x1011, 0, 0);
833 #else
834     /* Set up MMU:
835      * kernel is loaded at kernel_addr and wants to be seen at 0x01000000
836      */
837     setup_BAT(env, 0, 0x01000000, kernel_addr, 0x00400000, 1, 0, 2);
838     {
839 #if 0
840         uint32_t offset = 
841             *((uint32_t *)((uint32_t)phys_ram_base + kernel_addr));
842 #else
843         uint32_t offset = 12;
844 #endif
845         env->nip = 0x01000000 | (kernel_addr + offset);
846         printf("Start address: 0x%08x\n", env->nip);
847     }
848     env->gpr[1] = env->nip + (1 << 22);
849     p = (void *)(phys_ram_base + stack_addr);
850     put_long(p - 32, stack_addr);
851     env->gpr[1] -= 32;
852     printf("Kernel starts at 0x%08x stack 0x%08x\n", env->nip, env->gpr[1]);
853     /* We want all lower address not to be translated */
854     setup_BAT(env, 1, 0x00000000, 0x00000000, 0x010000000, 1, 1, 2);
855     /* We also need a BAT to access OF */
856     setup_BAT(env, 2, 0xFFFE0000, mem_size - 131072, 131072, 1, 0, 1);
857     /* Setup OF entry point */
858     {
859         char *p;
860         p = (char *)phys_ram_base + mem_size - 131072;
861         /* Special opcode to call OF */
862         *p++ = 0x18; *p++ = 0x00; *p++ = 0x00; *p++ = 0x02;
863         /* blr */
864         *p++ = 0x4E; *p++ = 0x80; *p++ = 0x00; *p++ = 0x20;
865     }
866     env->gpr[5] = 0xFFFE0000;
867     /* Register translations */
868     {
869         OF_transl_t translations[3] = {
870             { 0x01000000, 0x00400000, kernel_addr, 0x00000002, },
871             { 0x00000000, 0x01000000, 0x00000000, 0x00000002, },
872             { 0xFFFE0000, 0x00020000, mem_size - (128 * 1024),
873               0x00000001, },
874         };
875         OF_register_translations(3, translations);
876     }
877     /* Quite artificial, for now */
878     OF_register_bus("isa", "isa");
879     OF_register_serial("isa", "serial", 4, 0x3f8);
880     OF_register_stdio("serial", "serial");
881     /* Set up RTAS service */
882     RTAS_init();
883     /* Command line: let's put it just over the stack */
884 #if 0
885 #if 0
886     p = (void *)(((uint32_t)phys_ram_base + kernel_addr +
887                   kernel_size + (1 << 20) - 1) & ~((1 << 20) - 1));
888 #else
889     p = (void *)((uint32_t)phys_ram_base + kernel_addr + 0x400000);
890 #endif
891 #if 1
892     sprintf(p, "console=ttyS0,9600 root=%02x%02x mem=%dM",
893             boot_devs[boot_device - 'a'].major,
894             boot_devs[boot_device - 'a'].minor,
895             mem_size >> 20);
896 #else
897     sprintf(p, "console=ttyS0,9600 root=%s mem=%dM ne2000=0x300,9",
898             boot_devs[boot_device - 'a'].name,
899             mem_size >> 20);
900 #endif
901     OF_register_bootargs(p);
902 #endif
903 #endif
904 }
905
906 void PPC_end_init (void)
907 {
908     VGA_init();
909 }
910
911 /* PC hardware initialisation */
912 void ppc_prep_init(int ram_size, int vga_ram_size, int boot_device,
913                    DisplayState *ds, const char **fd_filename, int snapshot,
914                    const char *kernel_filename, const char *kernel_cmdline,
915                    const char *initrd_filename)
916 {
917     char buf[1024];
918     int PPC_io_memory;
919     int ret, linux_boot, initrd_size, i, nb_nics1, fd;
920
921     linux_boot = (kernel_filename != NULL);
922
923     /* allocate RAM */
924     cpu_register_physical_memory(0, ram_size, 0);
925
926     if (linux_boot) {
927         /* now we can load the kernel */
928         ret = load_image(kernel_filename, phys_ram_base + KERNEL_LOAD_ADDR);
929         if (ret < 0) {
930             fprintf(stderr, "qemu: could not load kernel '%s'\n", 
931                     kernel_filename);
932             exit(1);
933         }
934         /* load initrd */
935         initrd_size = 0;
936 #if 0
937         if (initrd_filename) {
938             initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
939             if (initrd_size < 0) {
940                 fprintf(stderr, "qemu: could not load initial ram disk '%s'\n", 
941                         initrd_filename);
942                 exit(1);
943             }
944         }
945 #endif
946         PPC_init_hw(/*env,*/ ram_size, KERNEL_LOAD_ADDR, ret,
947                     KERNEL_STACK_ADDR, boot_device, initrd_filename);
948     } else {
949         /* allocate ROM */
950         //        snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
951         snprintf(buf, sizeof(buf), "%s", BIOS_FILENAME);
952         printf("load BIOS at %p\n", phys_ram_base + 0x000f0000);
953         ret = load_image(buf, phys_ram_base + 0x000f0000);
954         if (ret != 0x10000) {
955             fprintf(stderr, "qemu: could not load PPC bios '%s' (%d)\n%m\n",
956                     buf, ret);
957             exit(1);
958         }
959     }
960
961     /* init basic PC hardware */
962     vga_initialize(ds, phys_ram_base + ram_size, ram_size, 
963                    vga_ram_size);
964     rtc_init(0x70, 8);
965     pic_init();
966     //    pit_init(0x40, 0);
967
968     fd = serial_open_device();
969     serial_init(0x3f8, 4, fd);
970 #if 1
971     nb_nics1 = nb_nics;
972     if (nb_nics1 > NE2000_NB_MAX)
973         nb_nics1 = NE2000_NB_MAX;
974     for(i = 0; i < nb_nics1; i++) {
975         ne2000_init(ne2000_io[i], ne2000_irq[i], &nd_table[i]);
976     }
977 #endif
978
979     for(i = 0; i < 2; i++) {
980         ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i],
981                  bs_table[2 * i], bs_table[2 * i + 1]);
982     }
983     kbd_init();
984     AUD_init();
985     DMA_init();
986     //    SB16_init();
987
988     fdctrl_init(6, 2, 0, 0x3f0, fd_table);
989
990     /* Register 64 kB of IO space */
991     PPC_io_memory = cpu_register_io_memory(0, PPC_io_read, PPC_io_write);
992     cpu_register_physical_memory(0x80000000, 0x10000, PPC_io_memory);
993     /* Register fake IO ports for PREP */
994     register_ioport_read(0x398, 2, 1, &PREP_io_read, NULL);
995     register_ioport_write(0x398, 2, 1, &PREP_io_write, NULL);
996     /* System control ports */
997     register_ioport_write(0x0092, 0x1, 1, &PREP_io_800_writeb, NULL);
998     register_ioport_read(0x0800, 0x52, 1, &PREP_io_800_readb, NULL);
999     register_ioport_write(0x0800, 0x52, 1, &PREP_io_800_writeb, NULL);
1000     /* PCI intack location (0xfef00000 / 0xbffffff0) */
1001     PPC_io_memory = cpu_register_io_memory(0, PPC_ioB_read, PPC_ioB_write);
1002     cpu_register_physical_memory(0xBFFFFFF0, 0x4, PPC_io_memory);
1003     //    cpu_register_physical_memory(0xFEF00000, 0x4, PPC_io_memory);
1004     prep_NVRAM_init();
1005
1006     PPC_end_init();
1007 }
This page took 0.079155 seconds and 4 git commands to generate.