Commit e5733356241f92e565f0aed731d265c8b1ae3956
1 parent
4e588a4d
heathrow nvram support - use different device ids for different macios
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1511 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
84 additions
and
6 deletions
hw/ppc_chrp.c
| ... | ... | @@ -31,7 +31,7 @@ |
| 31 | 31 | #define INITRD_LOAD_ADDR 0x01800000 |
| 32 | 32 | |
| 33 | 33 | /* MacIO devices (mapped inside the MacIO address space): CUDA, DBDMA, |
| 34 | - NVRAM (not implemented). */ | |
| 34 | + NVRAM */ | |
| 35 | 35 | |
| 36 | 36 | static int dbdma_mem_index; |
| 37 | 37 | static int cuda_mem_index; |
| ... | ... | @@ -39,6 +39,7 @@ static int ide0_mem_index = -1; |
| 39 | 39 | static int ide1_mem_index = -1; |
| 40 | 40 | static int openpic_mem_index = -1; |
| 41 | 41 | static int heathrow_pic_mem_index = -1; |
| 42 | +static int macio_nvram_mem_index = -1; | |
| 42 | 43 | |
| 43 | 44 | /* DBDMA: currently no op - should suffice right now */ |
| 44 | 45 | |
| ... | ... | @@ -83,6 +84,53 @@ static CPUReadMemoryFunc *dbdma_read[] = { |
| 83 | 84 | &dbdma_readl, |
| 84 | 85 | }; |
| 85 | 86 | |
| 87 | +/* macio style NVRAM device */ | |
| 88 | +typedef struct MacIONVRAMState { | |
| 89 | + uint8_t data[0x2000]; | |
| 90 | +} MacIONVRAMState; | |
| 91 | + | |
| 92 | +static void macio_nvram_writeb (void *opaque, target_phys_addr_t addr, uint32_t value) | |
| 93 | +{ | |
| 94 | + MacIONVRAMState *s = opaque; | |
| 95 | + addr = (addr >> 4) & 0x1fff; | |
| 96 | + s->data[addr] = value; | |
| 97 | + // printf("macio_nvram_writeb %04x = %02x\n", addr, value); | |
| 98 | +} | |
| 99 | + | |
| 100 | +static uint32_t macio_nvram_readb (void *opaque, target_phys_addr_t addr) | |
| 101 | +{ | |
| 102 | + MacIONVRAMState *s = opaque; | |
| 103 | + uint32_t value; | |
| 104 | + | |
| 105 | + addr = (addr >> 4) & 0x1fff; | |
| 106 | + value = s->data[addr]; | |
| 107 | + // printf("macio_nvram_readb %04x = %02x\n", addr, value); | |
| 108 | + return value; | |
| 109 | +} | |
| 110 | + | |
| 111 | +static CPUWriteMemoryFunc *macio_nvram_write[] = { | |
| 112 | + &macio_nvram_writeb, | |
| 113 | + &macio_nvram_writeb, | |
| 114 | + &macio_nvram_writeb, | |
| 115 | +}; | |
| 116 | + | |
| 117 | +static CPUReadMemoryFunc *macio_nvram_read[] = { | |
| 118 | + &macio_nvram_readb, | |
| 119 | + &macio_nvram_readb, | |
| 120 | + &macio_nvram_readb, | |
| 121 | +}; | |
| 122 | + | |
| 123 | +static MacIONVRAMState *macio_nvram_init(void) | |
| 124 | +{ | |
| 125 | + MacIONVRAMState *s; | |
| 126 | + s = qemu_mallocz(sizeof(MacIONVRAMState)); | |
| 127 | + if (!s) | |
| 128 | + return NULL; | |
| 129 | + macio_nvram_mem_index = cpu_register_io_memory(0, macio_nvram_read, | |
| 130 | + macio_nvram_write, s); | |
| 131 | + return s; | |
| 132 | +} | |
| 133 | + | |
| 86 | 134 | static void macio_map(PCIDevice *pci_dev, int region_num, |
| 87 | 135 | uint32_t addr, uint32_t size, int type) |
| 88 | 136 | { |
| ... | ... | @@ -100,9 +148,11 @@ static void macio_map(PCIDevice *pci_dev, int region_num, |
| 100 | 148 | cpu_register_physical_memory(addr + 0x40000, 0x40000, |
| 101 | 149 | openpic_mem_index); |
| 102 | 150 | } |
| 151 | + if (macio_nvram_mem_index >= 0) | |
| 152 | + cpu_register_physical_memory(addr + 0x60000, 0x20000, macio_nvram_mem_index); | |
| 103 | 153 | } |
| 104 | 154 | |
| 105 | -static void macio_init(PCIBus *bus) | |
| 155 | +static void macio_init(PCIBus *bus, int device_id) | |
| 106 | 156 | { |
| 107 | 157 | PCIDevice *d; |
| 108 | 158 | |
| ... | ... | @@ -112,8 +162,8 @@ static void macio_init(PCIBus *bus) |
| 112 | 162 | in PearPC */ |
| 113 | 163 | d->config[0x00] = 0x6b; // vendor_id |
| 114 | 164 | d->config[0x01] = 0x10; |
| 115 | - d->config[0x02] = 0x22; | |
| 116 | - d->config[0x03] = 0x00; | |
| 165 | + d->config[0x02] = device_id; | |
| 166 | + d->config[0x03] = device_id >> 8; | |
| 117 | 167 | |
| 118 | 168 | d->config[0x0a] = 0x00; // class_sub = pci2pci |
| 119 | 169 | d->config[0x0b] = 0xff; // class_base = bridge |
| ... | ... | @@ -219,6 +269,28 @@ static void pic_irq_request(void *opaque, int level) |
| 219 | 269 | { |
| 220 | 270 | } |
| 221 | 271 | |
| 272 | +static uint8_t nvram_chksum(const uint8_t *buf, int n) | |
| 273 | +{ | |
| 274 | + int sum, i; | |
| 275 | + sum = 0; | |
| 276 | + for(i = 0; i < n; i++) | |
| 277 | + sum += buf[i]; | |
| 278 | + return (sum & 0xff) + (sum >> 8); | |
| 279 | +} | |
| 280 | + | |
| 281 | +/* set a free Mac OS NVRAM partition */ | |
| 282 | +void pmac_format_nvram_partition(uint8_t *buf, int len) | |
| 283 | +{ | |
| 284 | + char partition_name[12] = "wwwwwwwwwwww"; | |
| 285 | + | |
| 286 | + buf[0] = 0x7f; /* free partition magic */ | |
| 287 | + buf[1] = 0; /* checksum */ | |
| 288 | + buf[2] = len >> 8; | |
| 289 | + buf[3] = len; | |
| 290 | + memcpy(buf + 4, partition_name, 12); | |
| 291 | + buf[1] = nvram_chksum(buf, 16); | |
| 292 | +} | |
| 293 | + | |
| 222 | 294 | /* PowerPC CHRP hardware initialisation */ |
| 223 | 295 | static void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device, |
| 224 | 296 | DisplayState *ds, const char **fd_filename, |
| ... | ... | @@ -369,7 +441,13 @@ static void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device, |
| 369 | 441 | adb_kbd_init(&adb_bus); |
| 370 | 442 | adb_mouse_init(&adb_bus); |
| 371 | 443 | |
| 372 | - macio_init(pci_bus); | |
| 444 | + { | |
| 445 | + MacIONVRAMState *nvr; | |
| 446 | + nvr = macio_nvram_init(); | |
| 447 | + pmac_format_nvram_partition(nvr->data, 0x2000); | |
| 448 | + } | |
| 449 | + | |
| 450 | + macio_init(pci_bus, 0x0017); | |
| 373 | 451 | |
| 374 | 452 | nvram = m48t59_init(8, 0xFFF04000, 0x0074, NVRAM_SIZE); |
| 375 | 453 | |
| ... | ... | @@ -416,7 +494,7 @@ static void ppc_chrp_init(int ram_size, int vga_ram_size, int boot_device, |
| 416 | 494 | adb_kbd_init(&adb_bus); |
| 417 | 495 | adb_mouse_init(&adb_bus); |
| 418 | 496 | |
| 419 | - macio_init(pci_bus); | |
| 497 | + macio_init(pci_bus, 0x0022); | |
| 420 | 498 | |
| 421 | 499 | nvram = m48t59_init(8, 0xFFF04000, 0x0074, NVRAM_SIZE); |
| 422 | 500 | ... | ... |