symbian-qemu-0.9.1-12/qemu-symbian-svp/hw/ppc_prep.c
changeset 1 2fb8b9db1c86
equal deleted inserted replaced
0:ffa851df0825 1:2fb8b9db1c86
       
     1 /*
       
     2  * QEMU PPC PREP hardware System Emulator
       
     3  *
       
     4  * Copyright (c) 2003-2007 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 "hw.h"
       
    25 #include "nvram.h"
       
    26 #include "pc.h"
       
    27 #include "fdc.h"
       
    28 #include "net.h"
       
    29 #include "sysemu.h"
       
    30 #include "isa.h"
       
    31 #include "pci.h"
       
    32 #include "ppc.h"
       
    33 #include "boards.h"
       
    34 #include "qemu-log.h"
       
    35 
       
    36 //#define HARD_DEBUG_PPC_IO
       
    37 //#define DEBUG_PPC_IO
       
    38 
       
    39 /* SMP is not enabled, for now */
       
    40 #define MAX_CPUS 1
       
    41 
       
    42 #define MAX_IDE_BUS 2
       
    43 
       
    44 #define BIOS_FILENAME "ppc_rom.bin"
       
    45 #define KERNEL_LOAD_ADDR 0x01000000
       
    46 #define INITRD_LOAD_ADDR 0x01800000
       
    47 
       
    48 #if defined (HARD_DEBUG_PPC_IO) && !defined (DEBUG_PPC_IO)
       
    49 #define DEBUG_PPC_IO
       
    50 #endif
       
    51 
       
    52 #if defined (HARD_DEBUG_PPC_IO)
       
    53 #define PPC_IO_DPRINTF(fmt, args...)                     \
       
    54 do {                                                     \
       
    55     if (loglevel & CPU_LOG_IOPORT) {                     \
       
    56         fprintf(logfile, "%s: " fmt, __func__ , ##args); \
       
    57     } else {                                             \
       
    58         printf("%s : " fmt, __func__ , ##args);          \
       
    59     }                                                    \
       
    60 } while (0)
       
    61 #elif defined (DEBUG_PPC_IO)
       
    62 #define PPC_IO_DPRINTF(fmt, args...)                     \
       
    63 do {                                                     \
       
    64     if (loglevel & CPU_LOG_IOPORT) {                     \
       
    65         fprintf(logfile, "%s: " fmt, __func__ , ##args); \
       
    66     }                                                    \
       
    67 } while (0)
       
    68 #else
       
    69 #define PPC_IO_DPRINTF(fmt, args...) do { } while (0)
       
    70 #endif
       
    71 
       
    72 /* Constants for devices init */
       
    73 static const int ide_iobase[2] = { 0x1f0, 0x170 };
       
    74 static const int ide_iobase2[2] = { 0x3f6, 0x376 };
       
    75 static const int ide_irq[2] = { 13, 13 };
       
    76 
       
    77 #define NE2000_NB_MAX 6
       
    78 
       
    79 static uint32_t ne2000_io[NE2000_NB_MAX] = { 0x300, 0x320, 0x340, 0x360, 0x280, 0x380 };
       
    80 static int ne2000_irq[NE2000_NB_MAX] = { 9, 10, 11, 3, 4, 5 };
       
    81 
       
    82 //static PITState *pit;
       
    83 
       
    84 /* ISA IO ports bridge */
       
    85 #define PPC_IO_BASE 0x80000000
       
    86 
       
    87 #if 0
       
    88 /* Speaker port 0x61 */
       
    89 static int speaker_data_on;
       
    90 static int dummy_refresh_clock;
       
    91 #endif
       
    92 
       
    93 static void speaker_ioport_write (void *opaque, uint32_t addr, uint32_t val)
       
    94 {
       
    95 #if 0
       
    96     speaker_data_on = (val >> 1) & 1;
       
    97     pit_set_gate(pit, 2, val & 1);
       
    98 #endif
       
    99 }
       
   100 
       
   101 static uint32_t speaker_ioport_read (void *opaque, uint32_t addr)
       
   102 {
       
   103 #if 0
       
   104     int out;
       
   105     out = pit_get_out(pit, 2, qemu_get_clock(vm_clock));
       
   106     dummy_refresh_clock ^= 1;
       
   107     return (speaker_data_on << 1) | pit_get_gate(pit, 2) | (out << 5) |
       
   108         (dummy_refresh_clock << 4);
       
   109 #endif
       
   110     return 0;
       
   111 }
       
   112 
       
   113 /* PCI intack register */
       
   114 /* Read-only register (?) */
       
   115 static void _PPC_intack_write (void *opaque,
       
   116                                target_phys_addr_t addr, uint32_t value)
       
   117 {
       
   118 //    printf("%s: 0x" PADDRX " => 0x%08" PRIx32 "\n", __func__, addr, value);
       
   119 }
       
   120 
       
   121 static always_inline uint32_t _PPC_intack_read (target_phys_addr_t addr)
       
   122 {
       
   123     uint32_t retval = 0;
       
   124 
       
   125     if ((addr & 0xf) == 0)
       
   126         retval = pic_intack_read(isa_pic);
       
   127 //   printf("%s: 0x" PADDRX " <= %08" PRIx32 "\n", __func__, addr, retval);
       
   128 
       
   129     return retval;
       
   130 }
       
   131 
       
   132 static uint32_t PPC_intack_readb (void *opaque, target_phys_addr_t addr)
       
   133 {
       
   134     return _PPC_intack_read(addr);
       
   135 }
       
   136 
       
   137 static uint32_t PPC_intack_readw (void *opaque, target_phys_addr_t addr)
       
   138 {
       
   139 #ifdef TARGET_WORDS_BIGENDIAN
       
   140     return bswap16(_PPC_intack_read(addr));
       
   141 #else
       
   142     return _PPC_intack_read(addr);
       
   143 #endif
       
   144 }
       
   145 
       
   146 static uint32_t PPC_intack_readl (void *opaque, target_phys_addr_t addr)
       
   147 {
       
   148 #ifdef TARGET_WORDS_BIGENDIAN
       
   149     return bswap32(_PPC_intack_read(addr));
       
   150 #else
       
   151     return _PPC_intack_read(addr);
       
   152 #endif
       
   153 }
       
   154 
       
   155 static CPUWriteMemoryFunc *PPC_intack_write[] = {
       
   156     &_PPC_intack_write,
       
   157     &_PPC_intack_write,
       
   158     &_PPC_intack_write,
       
   159 };
       
   160 
       
   161 static CPUReadMemoryFunc *PPC_intack_read[] = {
       
   162     &PPC_intack_readb,
       
   163     &PPC_intack_readw,
       
   164     &PPC_intack_readl,
       
   165 };
       
   166 
       
   167 /* PowerPC control and status registers */
       
   168 #if 0 // Not used
       
   169 static struct {
       
   170     /* IDs */
       
   171     uint32_t veni_devi;
       
   172     uint32_t revi;
       
   173     /* Control and status */
       
   174     uint32_t gcsr;
       
   175     uint32_t xcfr;
       
   176     uint32_t ct32;
       
   177     uint32_t mcsr;
       
   178     /* General purpose registers */
       
   179     uint32_t gprg[6];
       
   180     /* Exceptions */
       
   181     uint32_t feen;
       
   182     uint32_t fest;
       
   183     uint32_t fema;
       
   184     uint32_t fecl;
       
   185     uint32_t eeen;
       
   186     uint32_t eest;
       
   187     uint32_t eecl;
       
   188     uint32_t eeint;
       
   189     uint32_t eemck0;
       
   190     uint32_t eemck1;
       
   191     /* Error diagnostic */
       
   192 } XCSR;
       
   193 
       
   194 static void PPC_XCSR_writeb (void *opaque,
       
   195                              target_phys_addr_t addr, uint32_t value)
       
   196 {
       
   197     printf("%s: 0x" PADDRX " => 0x%08" PRIx32 "\n", __func__, addr, value);
       
   198 }
       
   199 
       
   200 static void PPC_XCSR_writew (void *opaque,
       
   201                              target_phys_addr_t addr, uint32_t value)
       
   202 {
       
   203 #ifdef TARGET_WORDS_BIGENDIAN
       
   204     value = bswap16(value);
       
   205 #endif
       
   206     printf("%s: 0x" PADDRX " => 0x%08" PRIx32 "\n", __func__, addr, value);
       
   207 }
       
   208 
       
   209 static void PPC_XCSR_writel (void *opaque,
       
   210                              target_phys_addr_t addr, uint32_t value)
       
   211 {
       
   212 #ifdef TARGET_WORDS_BIGENDIAN
       
   213     value = bswap32(value);
       
   214 #endif
       
   215     printf("%s: 0x" PADDRX " => 0x%08" PRIx32 "\n", __func__, addr, value);
       
   216 }
       
   217 
       
   218 static uint32_t PPC_XCSR_readb (void *opaque, target_phys_addr_t addr)
       
   219 {
       
   220     uint32_t retval = 0;
       
   221 
       
   222     printf("%s: 0x" PADDRX " <= %08" PRIx32 "\n", __func__, addr, retval);
       
   223 
       
   224     return retval;
       
   225 }
       
   226 
       
   227 static uint32_t PPC_XCSR_readw (void *opaque, target_phys_addr_t addr)
       
   228 {
       
   229     uint32_t retval = 0;
       
   230 
       
   231     printf("%s: 0x" PADDRX " <= %08" PRIx32 "\n", __func__, addr, retval);
       
   232 #ifdef TARGET_WORDS_BIGENDIAN
       
   233     retval = bswap16(retval);
       
   234 #endif
       
   235 
       
   236     return retval;
       
   237 }
       
   238 
       
   239 static uint32_t PPC_XCSR_readl (void *opaque, target_phys_addr_t addr)
       
   240 {
       
   241     uint32_t retval = 0;
       
   242 
       
   243     printf("%s: 0x" PADDRX " <= %08" PRIx32 "\n", __func__, addr, retval);
       
   244 #ifdef TARGET_WORDS_BIGENDIAN
       
   245     retval = bswap32(retval);
       
   246 #endif
       
   247 
       
   248     return retval;
       
   249 }
       
   250 
       
   251 static CPUWriteMemoryFunc *PPC_XCSR_write[] = {
       
   252     &PPC_XCSR_writeb,
       
   253     &PPC_XCSR_writew,
       
   254     &PPC_XCSR_writel,
       
   255 };
       
   256 
       
   257 static CPUReadMemoryFunc *PPC_XCSR_read[] = {
       
   258     &PPC_XCSR_readb,
       
   259     &PPC_XCSR_readw,
       
   260     &PPC_XCSR_readl,
       
   261 };
       
   262 #endif
       
   263 
       
   264 /* Fake super-io ports for PREP platform (Intel 82378ZB) */
       
   265 typedef struct sysctrl_t {
       
   266     qemu_irq reset_irq;
       
   267     m48t59_t *nvram;
       
   268     uint8_t state;
       
   269     uint8_t syscontrol;
       
   270     uint8_t fake_io[2];
       
   271     int contiguous_map;
       
   272     int endian;
       
   273 } sysctrl_t;
       
   274 
       
   275 enum {
       
   276     STATE_HARDFILE = 0x01,
       
   277 };
       
   278 
       
   279 static sysctrl_t *sysctrl;
       
   280 
       
   281 static void PREP_io_write (void *opaque, uint32_t addr, uint32_t val)
       
   282 {
       
   283     sysctrl_t *sysctrl = opaque;
       
   284 
       
   285     PPC_IO_DPRINTF("0x%08" PRIx32 " => 0x%02" PRIx32 "\n", addr - PPC_IO_BASE,
       
   286                    val);
       
   287     sysctrl->fake_io[addr - 0x0398] = val;
       
   288 }
       
   289 
       
   290 static uint32_t PREP_io_read (void *opaque, uint32_t addr)
       
   291 {
       
   292     sysctrl_t *sysctrl = opaque;
       
   293 
       
   294     PPC_IO_DPRINTF("0x%08" PRIx32 " <= 0x%02" PRIx32 "\n", addr - PPC_IO_BASE,
       
   295                    sysctrl->fake_io[addr - 0x0398]);
       
   296     return sysctrl->fake_io[addr - 0x0398];
       
   297 }
       
   298 
       
   299 static void PREP_io_800_writeb (void *opaque, uint32_t addr, uint32_t val)
       
   300 {
       
   301     sysctrl_t *sysctrl = opaque;
       
   302 
       
   303     PPC_IO_DPRINTF("0x%08" PRIx32 " => 0x%02" PRIx32 "\n",
       
   304                    addr - PPC_IO_BASE, val);
       
   305     switch (addr) {
       
   306     case 0x0092:
       
   307         /* Special port 92 */
       
   308         /* Check soft reset asked */
       
   309         if (val & 0x01) {
       
   310             qemu_irq_raise(sysctrl->reset_irq);
       
   311         } else {
       
   312             qemu_irq_lower(sysctrl->reset_irq);
       
   313         }
       
   314         /* Check LE mode */
       
   315         if (val & 0x02) {
       
   316             sysctrl->endian = 1;
       
   317         } else {
       
   318             sysctrl->endian = 0;
       
   319         }
       
   320         break;
       
   321     case 0x0800:
       
   322         /* Motorola CPU configuration register : read-only */
       
   323         break;
       
   324     case 0x0802:
       
   325         /* Motorola base module feature register : read-only */
       
   326         break;
       
   327     case 0x0803:
       
   328         /* Motorola base module status register : read-only */
       
   329         break;
       
   330     case 0x0808:
       
   331         /* Hardfile light register */
       
   332         if (val & 1)
       
   333             sysctrl->state |= STATE_HARDFILE;
       
   334         else
       
   335             sysctrl->state &= ~STATE_HARDFILE;
       
   336         break;
       
   337     case 0x0810:
       
   338         /* Password protect 1 register */
       
   339         if (sysctrl->nvram != NULL)
       
   340             m48t59_toggle_lock(sysctrl->nvram, 1);
       
   341         break;
       
   342     case 0x0812:
       
   343         /* Password protect 2 register */
       
   344         if (sysctrl->nvram != NULL)
       
   345             m48t59_toggle_lock(sysctrl->nvram, 2);
       
   346         break;
       
   347     case 0x0814:
       
   348         /* L2 invalidate register */
       
   349         //        tlb_flush(first_cpu, 1);
       
   350         break;
       
   351     case 0x081C:
       
   352         /* system control register */
       
   353         sysctrl->syscontrol = val & 0x0F;
       
   354         break;
       
   355     case 0x0850:
       
   356         /* I/O map type register */
       
   357         sysctrl->contiguous_map = val & 0x01;
       
   358         break;
       
   359     default:
       
   360         printf("ERROR: unaffected IO port write: %04" PRIx32
       
   361                " => %02" PRIx32"\n", addr, val);
       
   362         break;
       
   363     }
       
   364 }
       
   365 
       
   366 static uint32_t PREP_io_800_readb (void *opaque, uint32_t addr)
       
   367 {
       
   368     sysctrl_t *sysctrl = opaque;
       
   369     uint32_t retval = 0xFF;
       
   370 
       
   371     switch (addr) {
       
   372     case 0x0092:
       
   373         /* Special port 92 */
       
   374         retval = 0x00;
       
   375         break;
       
   376     case 0x0800:
       
   377         /* Motorola CPU configuration register */
       
   378         retval = 0xEF; /* MPC750 */
       
   379         break;
       
   380     case 0x0802:
       
   381         /* Motorola Base module feature register */
       
   382         retval = 0xAD; /* No ESCC, PMC slot neither ethernet */
       
   383         break;
       
   384     case 0x0803:
       
   385         /* Motorola base module status register */
       
   386         retval = 0xE0; /* Standard MPC750 */
       
   387         break;
       
   388     case 0x080C:
       
   389         /* Equipment present register:
       
   390          *  no L2 cache
       
   391          *  no upgrade processor
       
   392          *  no cards in PCI slots
       
   393          *  SCSI fuse is bad
       
   394          */
       
   395         retval = 0x3C;
       
   396         break;
       
   397     case 0x0810:
       
   398         /* Motorola base module extended feature register */
       
   399         retval = 0x39; /* No USB, CF and PCI bridge. NVRAM present */
       
   400         break;
       
   401     case 0x0814:
       
   402         /* L2 invalidate: don't care */
       
   403         break;
       
   404     case 0x0818:
       
   405         /* Keylock */
       
   406         retval = 0x00;
       
   407         break;
       
   408     case 0x081C:
       
   409         /* system control register
       
   410          * 7 - 6 / 1 - 0: L2 cache enable
       
   411          */
       
   412         retval = sysctrl->syscontrol;
       
   413         break;
       
   414     case 0x0823:
       
   415         /* */
       
   416         retval = 0x03; /* no L2 cache */
       
   417         break;
       
   418     case 0x0850:
       
   419         /* I/O map type register */
       
   420         retval = sysctrl->contiguous_map;
       
   421         break;
       
   422     default:
       
   423         printf("ERROR: unaffected IO port: %04" PRIx32 " read\n", addr);
       
   424         break;
       
   425     }
       
   426     PPC_IO_DPRINTF("0x%08" PRIx32 " <= 0x%02" PRIx32 "\n",
       
   427                    addr - PPC_IO_BASE, retval);
       
   428 
       
   429     return retval;
       
   430 }
       
   431 
       
   432 static always_inline target_phys_addr_t prep_IO_address (sysctrl_t *sysctrl,
       
   433                                                          target_phys_addr_t
       
   434                                                          addr)
       
   435 {
       
   436     if (sysctrl->contiguous_map == 0) {
       
   437         /* 64 KB contiguous space for IOs */
       
   438         addr &= 0xFFFF;
       
   439     } else {
       
   440         /* 8 MB non-contiguous space for IOs */
       
   441         addr = (addr & 0x1F) | ((addr & 0x007FFF000) >> 7);
       
   442     }
       
   443 
       
   444     return addr;
       
   445 }
       
   446 
       
   447 static void PPC_prep_io_writeb (void *opaque, target_phys_addr_t addr,
       
   448                                 uint32_t value)
       
   449 {
       
   450     sysctrl_t *sysctrl = opaque;
       
   451 
       
   452     addr = prep_IO_address(sysctrl, addr);
       
   453     cpu_outb(NULL, addr, value);
       
   454 }
       
   455 
       
   456 static uint32_t PPC_prep_io_readb (void *opaque, target_phys_addr_t addr)
       
   457 {
       
   458     sysctrl_t *sysctrl = opaque;
       
   459     uint32_t ret;
       
   460 
       
   461     addr = prep_IO_address(sysctrl, addr);
       
   462     ret = cpu_inb(NULL, addr);
       
   463 
       
   464     return ret;
       
   465 }
       
   466 
       
   467 static void PPC_prep_io_writew (void *opaque, target_phys_addr_t addr,
       
   468                                 uint32_t value)
       
   469 {
       
   470     sysctrl_t *sysctrl = opaque;
       
   471 
       
   472     addr = prep_IO_address(sysctrl, addr);
       
   473 #ifdef TARGET_WORDS_BIGENDIAN
       
   474     value = bswap16(value);
       
   475 #endif
       
   476     PPC_IO_DPRINTF("0x" PADDRX " => 0x%08" PRIx32 "\n", addr, value);
       
   477     cpu_outw(NULL, addr, value);
       
   478 }
       
   479 
       
   480 static uint32_t PPC_prep_io_readw (void *opaque, target_phys_addr_t addr)
       
   481 {
       
   482     sysctrl_t *sysctrl = opaque;
       
   483     uint32_t ret;
       
   484 
       
   485     addr = prep_IO_address(sysctrl, addr);
       
   486     ret = cpu_inw(NULL, addr);
       
   487 #ifdef TARGET_WORDS_BIGENDIAN
       
   488     ret = bswap16(ret);
       
   489 #endif
       
   490     PPC_IO_DPRINTF("0x" PADDRX " <= 0x%08" PRIx32 "\n", addr, ret);
       
   491 
       
   492     return ret;
       
   493 }
       
   494 
       
   495 static void PPC_prep_io_writel (void *opaque, target_phys_addr_t addr,
       
   496                                 uint32_t value)
       
   497 {
       
   498     sysctrl_t *sysctrl = opaque;
       
   499 
       
   500     addr = prep_IO_address(sysctrl, addr);
       
   501 #ifdef TARGET_WORDS_BIGENDIAN
       
   502     value = bswap32(value);
       
   503 #endif
       
   504     PPC_IO_DPRINTF("0x" PADDRX " => 0x%08" PRIx32 "\n", addr, value);
       
   505     cpu_outl(NULL, addr, value);
       
   506 }
       
   507 
       
   508 static uint32_t PPC_prep_io_readl (void *opaque, target_phys_addr_t addr)
       
   509 {
       
   510     sysctrl_t *sysctrl = opaque;
       
   511     uint32_t ret;
       
   512 
       
   513     addr = prep_IO_address(sysctrl, addr);
       
   514     ret = cpu_inl(NULL, addr);
       
   515 #ifdef TARGET_WORDS_BIGENDIAN
       
   516     ret = bswap32(ret);
       
   517 #endif
       
   518     PPC_IO_DPRINTF("0x" PADDRX " <= 0x%08" PRIx32 "\n", addr, ret);
       
   519 
       
   520     return ret;
       
   521 }
       
   522 
       
   523 static CPUWriteMemoryFunc *PPC_prep_io_write[] = {
       
   524     &PPC_prep_io_writeb,
       
   525     &PPC_prep_io_writew,
       
   526     &PPC_prep_io_writel,
       
   527 };
       
   528 
       
   529 static CPUReadMemoryFunc *PPC_prep_io_read[] = {
       
   530     &PPC_prep_io_readb,
       
   531     &PPC_prep_io_readw,
       
   532     &PPC_prep_io_readl,
       
   533 };
       
   534 
       
   535 #define NVRAM_SIZE        0x2000
       
   536 
       
   537 /* PowerPC PREP hardware initialisation */
       
   538 static void ppc_prep_init (ram_addr_t ram_size, int vga_ram_size,
       
   539                            const char *boot_device, DisplayState *ds,
       
   540                            const char *kernel_filename,
       
   541                            const char *kernel_cmdline,
       
   542                            const char *initrd_filename,
       
   543                            const char *cpu_model)
       
   544 {
       
   545     CPUState *env = NULL, *envs[MAX_CPUS];
       
   546     char buf[1024];
       
   547     nvram_t nvram;
       
   548     m48t59_t *m48t59;
       
   549     int PPC_io_memory;
       
   550     int linux_boot, i, nb_nics1, bios_size;
       
   551     unsigned long bios_offset;
       
   552     uint32_t kernel_base, kernel_size, initrd_base, initrd_size;
       
   553     PCIBus *pci_bus;
       
   554     qemu_irq *i8259;
       
   555     int ppc_boot_device;
       
   556     int index;
       
   557     BlockDriverState *hd[MAX_IDE_BUS * MAX_IDE_DEVS];
       
   558     BlockDriverState *fd[MAX_FD];
       
   559 
       
   560     sysctrl = qemu_mallocz(sizeof(sysctrl_t));
       
   561     if (sysctrl == NULL)
       
   562         return;
       
   563 
       
   564     linux_boot = (kernel_filename != NULL);
       
   565 
       
   566     /* init CPUs */
       
   567     if (cpu_model == NULL)
       
   568         cpu_model = "default";
       
   569     for (i = 0; i < smp_cpus; i++) {
       
   570         env = cpu_init(cpu_model);
       
   571         if (!env) {
       
   572             fprintf(stderr, "Unable to find PowerPC CPU definition\n");
       
   573             exit(1);
       
   574         }
       
   575         if (env->flags & POWERPC_FLAG_RTC_CLK) {
       
   576             /* POWER / PowerPC 601 RTC clock frequency is 7.8125 MHz */
       
   577             cpu_ppc_tb_init(env, 7812500UL);
       
   578         } else {
       
   579             /* Set time-base frequency to 100 Mhz */
       
   580             cpu_ppc_tb_init(env, 100UL * 1000UL * 1000UL);
       
   581         }
       
   582         qemu_register_reset(&cpu_ppc_reset, env);
       
   583         envs[i] = env;
       
   584     }
       
   585 
       
   586     /* allocate RAM */
       
   587     cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
       
   588 
       
   589     /* allocate and load BIOS */
       
   590     bios_offset = ram_size + vga_ram_size;
       
   591     if (bios_name == NULL)
       
   592         bios_name = BIOS_FILENAME;
       
   593     snprintf(buf, sizeof(buf), "%s/%s", bios_dir, bios_name);
       
   594     bios_size = load_image(buf, phys_ram_base + bios_offset);
       
   595     if (bios_size < 0 || bios_size > BIOS_SIZE) {
       
   596         cpu_abort(env, "qemu: could not load PPC PREP bios '%s'\n", buf);
       
   597         exit(1);
       
   598     }
       
   599     if (env->nip < 0xFFF80000 && bios_size < 0x00100000) {
       
   600         cpu_abort(env, "PowerPC 601 / 620 / 970 need a 1MB BIOS\n");
       
   601     }
       
   602     bios_size = (bios_size + 0xfff) & ~0xfff;
       
   603     cpu_register_physical_memory((uint32_t)(-bios_size),
       
   604                                  bios_size, bios_offset | IO_MEM_ROM);
       
   605 
       
   606     if (linux_boot) {
       
   607         kernel_base = KERNEL_LOAD_ADDR;
       
   608         /* now we can load the kernel */
       
   609         kernel_size = load_image(kernel_filename, phys_ram_base + kernel_base);
       
   610         if (kernel_size < 0) {
       
   611             cpu_abort(env, "qemu: could not load kernel '%s'\n",
       
   612                       kernel_filename);
       
   613             exit(1);
       
   614         }
       
   615         /* load initrd */
       
   616         if (initrd_filename) {
       
   617             initrd_base = INITRD_LOAD_ADDR;
       
   618             initrd_size = load_image(initrd_filename,
       
   619                                      phys_ram_base + initrd_base);
       
   620             if (initrd_size < 0) {
       
   621                 cpu_abort(env, "qemu: could not load initial ram disk '%s'\n",
       
   622                           initrd_filename);
       
   623                 exit(1);
       
   624             }
       
   625         } else {
       
   626             initrd_base = 0;
       
   627             initrd_size = 0;
       
   628         }
       
   629         ppc_boot_device = 'm';
       
   630     } else {
       
   631         kernel_base = 0;
       
   632         kernel_size = 0;
       
   633         initrd_base = 0;
       
   634         initrd_size = 0;
       
   635         ppc_boot_device = '\0';
       
   636         /* For now, OHW cannot boot from the network. */
       
   637         for (i = 0; boot_device[i] != '\0'; i++) {
       
   638             if (boot_device[i] >= 'a' && boot_device[i] <= 'f') {
       
   639                 ppc_boot_device = boot_device[i];
       
   640                 break;
       
   641             }
       
   642         }
       
   643         if (ppc_boot_device == '\0') {
       
   644             fprintf(stderr, "No valid boot device for Mac99 machine\n");
       
   645             exit(1);
       
   646         }
       
   647     }
       
   648 
       
   649     isa_mem_base = 0xc0000000;
       
   650     if (PPC_INPUT(env) != PPC_FLAGS_INPUT_6xx) {
       
   651         cpu_abort(env, "Only 6xx bus is supported on PREP machine\n");
       
   652         exit(1);
       
   653     }
       
   654     i8259 = i8259_init(first_cpu->irq_inputs[PPC6xx_INPUT_INT]);
       
   655     pci_bus = pci_prep_init(i8259);
       
   656     //    pci_bus = i440fx_init();
       
   657     /* Register 8 MB of ISA IO space (needed for non-contiguous map) */
       
   658     PPC_io_memory = cpu_register_io_memory(0, PPC_prep_io_read,
       
   659                                            PPC_prep_io_write, sysctrl);
       
   660     cpu_register_physical_memory(0x80000000, 0x00800000, PPC_io_memory);
       
   661 
       
   662     /* init basic PC hardware */
       
   663     pci_vga_init(pci_bus, ds, phys_ram_base + ram_size, ram_size,
       
   664                  vga_ram_size, 0, 0);
       
   665     //    openpic = openpic_init(0x00000000, 0xF0000000, 1);
       
   666     //    pit = pit_init(0x40, i8259[0]);
       
   667     rtc_init(0x70, i8259[8]);
       
   668 
       
   669     serial_init(0x3f8, i8259[4], 115200, serial_hds[0]);
       
   670     nb_nics1 = nb_nics;
       
   671     if (nb_nics1 > NE2000_NB_MAX)
       
   672         nb_nics1 = NE2000_NB_MAX;
       
   673     for(i = 0; i < nb_nics1; i++) {
       
   674         if (nd_table[i].model == NULL
       
   675             || strcmp(nd_table[i].model, "ne2k_isa") == 0) {
       
   676             isa_ne2000_init(ne2000_io[i], i8259[ne2000_irq[i]], &nd_table[i]);
       
   677         } else {
       
   678             pci_nic_init(pci_bus, &nd_table[i], -1);
       
   679         }
       
   680     }
       
   681 
       
   682     if (drive_get_max_bus(IF_IDE) >= MAX_IDE_BUS) {
       
   683         fprintf(stderr, "qemu: too many IDE bus\n");
       
   684         exit(1);
       
   685     }
       
   686 
       
   687     for(i = 0; i < MAX_IDE_BUS * MAX_IDE_DEVS; i++) {
       
   688         index = drive_get_index(IF_IDE, i / MAX_IDE_DEVS, i % MAX_IDE_DEVS);
       
   689         if (index != -1)
       
   690             hd[i] = drives_table[index].bdrv;
       
   691         else
       
   692             hd[i] = NULL;
       
   693     }
       
   694 
       
   695     for(i = 0; i < MAX_IDE_BUS; i++) {
       
   696         isa_ide_init(ide_iobase[i], ide_iobase2[i], i8259[ide_irq[i]],
       
   697                      hd[2 * i],
       
   698 		     hd[2 * i + 1]);
       
   699     }
       
   700     i8042_init(i8259[1], i8259[12], 0x60);
       
   701     DMA_init(1);
       
   702     //    AUD_init();
       
   703     //    SB16_init();
       
   704 
       
   705     for(i = 0; i < MAX_FD; i++) {
       
   706         index = drive_get_index(IF_FLOPPY, 0, i);
       
   707         if (index != -1)
       
   708             fd[i] = drives_table[index].bdrv;
       
   709         else
       
   710             fd[i] = NULL;
       
   711     }
       
   712     fdctrl_init(i8259[6], 2, 0, 0x3f0, fd);
       
   713 
       
   714     /* Register speaker port */
       
   715     register_ioport_read(0x61, 1, 1, speaker_ioport_read, NULL);
       
   716     register_ioport_write(0x61, 1, 1, speaker_ioport_write, NULL);
       
   717     /* Register fake IO ports for PREP */
       
   718     sysctrl->reset_irq = first_cpu->irq_inputs[PPC6xx_INPUT_HRESET];
       
   719     register_ioport_read(0x398, 2, 1, &PREP_io_read, sysctrl);
       
   720     register_ioport_write(0x398, 2, 1, &PREP_io_write, sysctrl);
       
   721     /* System control ports */
       
   722     register_ioport_read(0x0092, 0x01, 1, &PREP_io_800_readb, sysctrl);
       
   723     register_ioport_write(0x0092, 0x01, 1, &PREP_io_800_writeb, sysctrl);
       
   724     register_ioport_read(0x0800, 0x52, 1, &PREP_io_800_readb, sysctrl);
       
   725     register_ioport_write(0x0800, 0x52, 1, &PREP_io_800_writeb, sysctrl);
       
   726     /* PCI intack location */
       
   727     PPC_io_memory = cpu_register_io_memory(0, PPC_intack_read,
       
   728                                            PPC_intack_write, NULL);
       
   729     cpu_register_physical_memory(0xBFFFFFF0, 0x4, PPC_io_memory);
       
   730     /* PowerPC control and status register group */
       
   731 #if 0
       
   732     PPC_io_memory = cpu_register_io_memory(0, PPC_XCSR_read, PPC_XCSR_write,
       
   733                                            NULL);
       
   734     cpu_register_physical_memory(0xFEFF0000, 0x1000, PPC_io_memory);
       
   735 #endif
       
   736 
       
   737     if (usb_enabled) {
       
   738         usb_ohci_init_pci(pci_bus, 3, -1);
       
   739     }
       
   740 
       
   741     m48t59 = m48t59_init(i8259[8], 0, 0x0074, NVRAM_SIZE, 59);
       
   742     if (m48t59 == NULL)
       
   743         return;
       
   744     sysctrl->nvram = m48t59;
       
   745 
       
   746     /* Initialise NVRAM */
       
   747     nvram.opaque = m48t59;
       
   748     nvram.read_fn = &m48t59_read;
       
   749     nvram.write_fn = &m48t59_write;
       
   750     PPC_NVRAM_set_params(&nvram, NVRAM_SIZE, "PREP", ram_size, ppc_boot_device,
       
   751                          kernel_base, kernel_size,
       
   752                          kernel_cmdline,
       
   753                          initrd_base, initrd_size,
       
   754                          /* XXX: need an option to load a NVRAM image */
       
   755                          0,
       
   756                          graphic_width, graphic_height, graphic_depth);
       
   757 
       
   758     /* Special port to get debug messages from Open-Firmware */
       
   759     register_ioport_write(0x0F00, 4, 1, &PPC_debug_write, NULL);
       
   760 }
       
   761 
       
   762 QEMUMachine prep_machine = {
       
   763     .name = "prep",
       
   764     .desc = "PowerPC PREP platform",
       
   765     .init = ppc_prep_init,
       
   766     .ram_require = BIOS_SIZE + VGA_RAM_SIZE,
       
   767     .max_cpus = MAX_CPUS,
       
   768 };