diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/bios.h OpenHackWare-release-0.4/src/bios.h --- OpenHackWare-release-0.4.org/src/bios.h 2005-04-06 23:20:22.000000000 +0200 +++ OpenHackWare-release-0.4/src/bios.h 2005-07-07 01:10:20.000000000 +0200 @@ -64,6 +64,7 @@ ARCH_CHRP, ARCH_MAC99, ARCH_POP, + ARCH_HEATHROW, }; /* Hardware definition(s) */ @@ -174,6 +175,7 @@ int bd_ioctl (bloc_device_t *bd, int func, void *args); uint32_t bd_seclen (bloc_device_t *bd); void bd_close (bloc_device_t *bd); +void bd_reset_all(void); uint32_t bd_seclen (bloc_device_t *bd); uint32_t bd_maxbloc (bloc_device_t *bd); void bd_sect2CHS (bloc_device_t *bd, uint32_t secnum, @@ -183,12 +185,12 @@ part_t *bd_probe (int boot_device); bloc_device_t *bd_get (int device); void bd_put (bloc_device_t *bd); -void bd_set_boot_part (bloc_device_t *bd, part_t *partition); +void bd_set_boot_part (bloc_device_t *bd, part_t *partition, int partnum); part_t **_bd_parts (bloc_device_t *bd); void ide_pci_pc_register (uint32_t io_base0, uint32_t io_base1, uint32_t io_base2, uint32_t io_base3, - void *OF_private); + void *OF_private0, void *OF_private1); void ide_pci_pmac_register (uint32_t io_base0, uint32_t io_base1, void *OF_private); @@ -399,17 +401,23 @@ uint16_t min_grant, uint16_t max_latency); void OF_finalize_pci_host (void *dev, int first_bus, int nb_busses); void OF_finalize_pci_device (void *dev, uint8_t bus, uint8_t devfn, - uint32_t *regions, uint32_t *sizes); + uint32_t *regions, uint32_t *sizes, + int irq_line); void OF_finalize_pci_macio (void *dev, uint32_t base_address, uint32_t size, void *private_data); +void OF_finalize_pci_ide (void *dev, + uint32_t io_base0, uint32_t io_base1, + uint32_t io_base2, uint32_t io_base3); int OF_register_bus (const unsigned char *name, uint32_t address, const unsigned char *type); int OF_register_serial (const unsigned char *bus, const unsigned char *name, uint32_t io_base, int irq); int OF_register_stdio (const unsigned char *dev_in, const unsigned char *dev_out); -void OF_vga_register (const unsigned char *name, uint32_t address, - int width, int height, int depth); +void OF_vga_register (const unsigned char *name, unused uint32_t address, + int width, int height, int depth, + unsigned long vga_bios_addr, + unsigned long vga_bios_size); void *OF_blockdev_register (void *parent, void *private, const unsigned char *type, const unsigned char *name, int devnum, diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/bloc.c OpenHackWare-release-0.4/src/bloc.c --- OpenHackWare-release-0.4.org/src/bloc.c 2005-04-06 23:21:00.000000000 +0200 +++ OpenHackWare-release-0.4/src/bloc.c 2005-07-08 00:28:26.000000000 +0200 @@ -55,6 +55,7 @@ /* Partitions */ part_t *parts, *bparts; part_t *boot_part; + int bpartnum; /* Chain */ bloc_device_t *next; }; @@ -66,6 +67,7 @@ static int ide_initialize (bloc_device_t *bd, int device); static int ide_read_sector (bloc_device_t *bd, void *buffer, int secnum); +static int ide_reset (bloc_device_t *bd); static int mem_initialize (bloc_device_t *bd, int device); static int mem_read_sector (bloc_device_t *bd, void *buffer, int secnum); @@ -212,6 +214,17 @@ { } +void bd_reset_all(void) +{ + bloc_device_t *bd; + for (bd = bd_list; bd != NULL; bd = bd->next) { + if (bd->init == &ide_initialize) { + /* reset IDE drive because Darwin wants all IDE devices to be reset */ + ide_reset(bd); + } + } +} + uint32_t bd_seclen (bloc_device_t *bd) { return bd->seclen; @@ -223,10 +236,12 @@ } /* XXX: to be suppressed */ -void bd_set_boot_part (bloc_device_t *bd, part_t *partition) +void bd_set_boot_part (bloc_device_t *bd, part_t *partition, int partnum) { + dprintf("%s: part %p (%p) %d\n", __func__, partition, bd->boot_part, partnum); if (bd->boot_part == NULL) { bd->boot_part = partition; + bd->bpartnum = partnum; } } @@ -240,6 +255,13 @@ return &bd->bparts; } +void bd_set_boot_device (bloc_device_t *bd) +{ +#if defined (USE_OPENFIRMWARE) + OF_blockdev_set_boot_device(bd->OF_private, bd->bpartnum, "\\\\ofwboot"); +#endif +} + part_t *bd_probe (int boot_device) { char devices[] = { /*'a', 'b',*/ 'c', 'd', 'e', 'f', 'm', '\0', }; @@ -272,9 +294,7 @@ tmp = part_probe(bd, force_raw); if (boot_device == bd->device) { boot_part = tmp; -#if defined (USE_OPENFIRMWARE) - OF_blockdev_set_boot_device(bd->OF_private, 2, "\\\\ofwboot"); -#endif + bd_set_boot_device(bd); } } @@ -717,34 +737,29 @@ /* IDE PCI access for pc */ static uint8_t ide_pci_port_read (bloc_device_t *bd, int port) { - eieio(); - - return *(uint8_t *)(bd->io_base + port); + uint8_t value; + value = inb(bd->io_base + port); + return value; } static void ide_pci_port_write (bloc_device_t *bd, int port, uint8_t value) { - *(uint8_t *)(bd->io_base + port) = value; - eieio(); + outb(bd->io_base + port, value); } static uint32_t ide_pci_data_readl (bloc_device_t *bd) { - eieio(); - - return *((uint32_t *)bd->io_base); + return inl(bd->io_base); } static void ide_pci_data_writel (bloc_device_t *bd, uint32_t val) { - *(uint32_t *)(bd->io_base) = val; - eieio(); + outl(bd->io_base, val); } static void ide_pci_control_write (bloc_device_t *bd, uint32_t val) { - *((uint8_t *)bd->tmp) = val; - eieio(); + outb(bd->tmp + 2, val); } static ide_ops_t ide_pci_pc_ops = { @@ -761,7 +776,7 @@ void ide_pci_pc_register (uint32_t io_base0, uint32_t io_base1, uint32_t io_base2, uint32_t io_base3, - unused void *OF_private) + void *OF_private0, void *OF_private1) { if (ide_pci_ops == NULL) { ide_pci_ops = malloc(sizeof(ide_ops_t)); @@ -770,19 +785,19 @@ memcpy(ide_pci_ops, &ide_pci_pc_ops, sizeof(ide_ops_t)); } if ((io_base0 != 0 || io_base1 != 0) && - ide_pci_ops->base[0] == 0 && ide_pci_ops->base[1] == 0) { + ide_pci_ops->base[0] == 0 && ide_pci_ops->base[2] == 0) { ide_pci_ops->base[0] = io_base0; - ide_pci_ops->base[1] = io_base1; + ide_pci_ops->base[2] = io_base1; #ifdef USE_OPENFIRMWARE - ide_pci_ops->OF_private[0] = OF_private; + ide_pci_ops->OF_private[0] = OF_private0; #endif } if ((io_base2 != 0 || io_base3 != 0) && - ide_pci_ops->base[2] == 0 && ide_pci_ops->base[3] == 0) { - ide_pci_ops->base[2] = io_base2; + ide_pci_ops->base[1] == 0 && ide_pci_ops->base[3] == 0) { + ide_pci_ops->base[1] = io_base2; ide_pci_ops->base[3] = io_base3; #ifdef USE_OPENFIRMWARE - ide_pci_ops->OF_private[1] = OF_private; + ide_pci_ops->OF_private[1] = OF_private1; #endif } } @@ -935,6 +950,8 @@ } static void atapi_pad_req (void *buffer, int len); +static void atapi_make_req (bloc_device_t *bd, uint32_t *buffer, + int maxlen); static int atapi_read_sector (bloc_device_t *bd, void *buffer, int secnum); static int ide_initialize (bloc_device_t *bd, int device) @@ -1035,9 +1052,7 @@ DPRINTF("INQUIRY\n"); len = spc_inquiry_req(&atapi_buffer, 36); atapi_pad_req(&atapi_buffer, len); - ide_port_write(bd, 0x07, 0xA0); - for (i = 0; i < 3; i++) - ide_data_writel(bd, ldswap32(&atapi_buffer[i])); + atapi_make_req(bd, atapi_buffer, 36); status = ide_port_read(bd, 0x07); if (status != 0x48) { ERROR("ATAPI INQUIRY : status %0x != 0x48\n", status); @@ -1053,9 +1068,7 @@ DPRINTF("READ_CAPACITY\n"); len = mmc_read_capacity_req(&atapi_buffer); atapi_pad_req(&atapi_buffer, len); - ide_port_write(bd, 0x07, 0xA0); - for (i = 0; i < 3; i++) - ide_data_writel(bd, ldswap32(&atapi_buffer[i])); + atapi_make_req(bd, atapi_buffer, 8); status = ide_port_read(bd, 0x07); if (status != 0x48) { ERROR("ATAPI READ_CAPACITY : status %0x != 0x48\n", status); @@ -1105,6 +1118,22 @@ memset(p + len, 0, 12 - len); } +static void atapi_make_req (bloc_device_t *bd, uint32_t *buffer, + int maxlen) +{ + int i; + /* select drive */ + if (bd->drv == 0) + ide_port_write(bd, 0x06, 0x40); + else + ide_port_write(bd, 0x06, 0x50); + ide_port_write(bd, 0x04, maxlen & 0xff); + ide_port_write(bd, 0x05, (maxlen >> 8) & 0xff); + ide_port_write(bd, 0x07, 0xA0); + for (i = 0; i < 3; i++) + ide_data_writel(bd, ldswap32(&buffer[i])); +} + static int atapi_read_sector (bloc_device_t *bd, void *buffer, int secnum) { uint32_t atapi_buffer[4]; @@ -1112,16 +1141,9 @@ uint32_t status, value; int i, len; - /* select drive */ - if (bd->drv == 0) - ide_port_write(bd, 0x06, 0x40); - else - ide_port_write(bd, 0x06, 0x50); len = mmc_read12_req(atapi_buffer, secnum, 1); atapi_pad_req(&atapi_buffer, len); - ide_port_write(bd, 0x07, 0xA0); - for (i = 0; i < 3; i++) - ide_data_writel(bd, ldswap32(&atapi_buffer[i])); + atapi_make_req(bd, atapi_buffer, bd->seclen); status = ide_port_read(bd, 0x07); if (status != 0x48) { ERROR("ATAPI READ12 : status %0x != 0x48\n", status); diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/libpart/apple.c OpenHackWare-release-0.4/src/libpart/apple.c --- OpenHackWare-release-0.4.org/src/libpart/apple.c 2005-03-31 09:23:33.000000000 +0200 +++ OpenHackWare-release-0.4/src/libpart/apple.c 2005-07-03 16:17:41.000000000 +0200 @@ -199,14 +199,18 @@ if (len == 0) { /* Place holder. Skip it */ DPRINTF("%s placeholder part\t%d\n", __func__, i); + part->flags = PART_TYPE_APPLE | PART_FLAG_DUMMY; + part_register(bd, part, name, i); } else if (strncmp("Apple_Void", type, 32) == 0) { /* Void partition. Skip it */ DPRINTF("%s Void part\t%d [%s]\n", __func__, i, type); + part->flags = PART_TYPE_APPLE | PART_FLAG_DUMMY; + part_register(bd, part, name, i); } else if (strncmp("Apple_Free", type, 32) == 0) { /* Free space. Skip it */ DPRINTF("%s Free part (%d)\n", __func__, i); part->flags = PART_TYPE_APPLE | PART_FLAG_DUMMY; - part_register(bd, part, name); + part_register(bd, part, name, i); } else if (strncmp("Apple_partition_map", type, 32) == 0 || strncmp("Apple_Partition_Map", type, 32) == 0 #if 0 // Is this really used or is it just a mistake ? @@ -226,7 +230,7 @@ */ } part->flags = PART_TYPE_APPLE | PART_FLAG_DUMMY; - part_register(bd, part, name); + part_register(bd, part, name, i); } else if (strncmp("Apple_Driver", type, 32) == 0 || strncmp("Apple_Driver43", type, 32) == 0 || strncmp("Apple_Driver43_CD", type, 32) == 0 || @@ -236,8 +240,12 @@ strncmp("Apple_Driver_IOKit", type, 32) == 0) { /* Drivers. don't care for now */ DPRINTF("%s Drivers part\t%d [%s]\n", __func__, i, type); + part->flags = PART_TYPE_APPLE | PART_FLAG_DRIVER; + part_register(bd, part, name, i); } else if (strncmp("Apple_Patches", type, 32) == 0) { /* Patches: don't care for now */ + part->flags = PART_TYPE_APPLE | PART_FLAG_PATCH; + part_register(bd, part, name, i); DPRINTF("%s Patches part\t%d [%s]\n", __func__, i, type); } else if (strncmp("Apple_HFS", type, 32) == 0 || strncmp("Apple_MFS", type, 32) == 0 || @@ -256,9 +264,8 @@ count = partmap->bloc_cnt * HFS_BLOCSIZE; if (partmap->boot_size == 0 || partmap->boot_load == 0) { printf("Not a bootable partition %d %d (%p %p)\n", - partmap->boot_size, partmap->boot_load,boot_part, part); - if (boot_part == NULL) - boot_part = part; + partmap->boot_size, partmap->boot_load, + boot_part, part); part->flags = PART_TYPE_APPLE | PART_FLAG_FS; } else { part->boot_start.bloc = partmap->boot_start; @@ -278,8 +285,8 @@ boot_part = part; part->flags = PART_TYPE_APPLE | PART_FLAG_FS | PART_FLAG_BOOT; } - printf("Partition: %d %s st %0x size %0x", - i, name, partmap->start_bloc, partmap->bloc_cnt); + printf("Partition: %d '%s' '%s' st %0x size %0x", + i, name, type, partmap->start_bloc, partmap->bloc_cnt); #ifndef DEBUG printf("\n"); #endif @@ -290,11 +297,13 @@ part->boot_load, part->boot_entry); DPRINTF(" load %0x entry %0x %0x\n", partmap->boot_load2, partmap->boot_entry2, HFS_BLOCSIZE); - part_register(bd, part, name); + part_register(bd, part, name, i); } else { memcpy(tmp, type, 32); tmp[32] = '\0'; ERROR("Unknown partition type [%s]\n", tmp); + part->flags = PART_TYPE_APPLE | PART_FLAG_DUMMY; + part_register(bd, part, name, i); } } error: diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/libpart/core.c OpenHackWare-release-0.4/src/libpart/core.c --- OpenHackWare-release-0.4.org/src/libpart/core.c 2005-03-31 09:23:33.000000000 +0200 +++ OpenHackWare-release-0.4/src/libpart/core.c 2005-07-03 16:17:41.000000000 +0200 @@ -126,7 +126,7 @@ } int part_register (bloc_device_t *bd, part_t *partition, - const unsigned char *name) + const unsigned char *name, int partnum) { part_t **cur; @@ -134,6 +134,7 @@ partition->bd = bd; partition->next = NULL; partition->name = strdup(name); + partition->partnum = partnum; for (cur = _bd_parts(bd); *cur != NULL; cur = &(*cur)->next) continue; *cur = partition; @@ -141,29 +142,15 @@ return 0; } -static inline int set_boot_part (bloc_device_t *bd, int partnum) -{ - part_t *cur; - - cur = part_get(bd, partnum); - if (cur == NULL) - return -1; - bd_set_boot_part(bd, cur); - - return 0; -} - part_t *part_get (bloc_device_t *bd, int partnum) { part_t **listp, *cur; - int i; listp = _bd_parts(bd); - cur = *listp; - for (i = 0; i != partnum; i++) { - if (cur == NULL) + + for (cur = *listp; cur != NULL; cur = cur->next) { + if (cur->partnum == partnum) break; - cur = cur->next; } return cur; @@ -192,17 +179,20 @@ part_set_blocsize(bd, part, 512); part->bd = bd; part->flags = PART_TYPE_RAW | PART_FLAG_BOOT; - part_register(bd, part, "Raw"); + part_register(bd, part, "Raw", 0); return part; } +bloc_device_t *part_get_bd (part_t *part) +{ + return part->bd; +} + part_t *part_probe (bloc_device_t *bd, int set_raw) { - part_t *part0, *boot_part, **cur; + part_t *part0 = NULL, *boot_part, **cur; - /* Register the 0 partition: raw partition containing the whole disk */ - part0 = part_get_raw(bd); /* Try to find a valid boot partition */ boot_part = Apple_probe_partitions(bd); if (boot_part == NULL) { @@ -210,10 +200,13 @@ if (boot_part == NULL && arch == ARCH_PREP) boot_part = PREP_find_partition(bd); if (boot_part == NULL && set_raw != 0) { - boot_part = part0; - set_boot_part(bd, 0); + dprintf("Use bloc device as raw partition\n"); } } + if (_bd_parts(bd) == NULL) { + /* Register the 0 partition: raw partition containing the whole disk */ + part0 = part_get_raw(bd); + } /* Probe filesystem on each found partition */ for (cur = _bd_parts(bd); *cur != NULL; cur = &(*cur)->next) { const unsigned char *map, *type; @@ -248,23 +241,28 @@ type = "unknown"; break; } - DPRINTF("Probe filesystem on %s %s partition '%s' %s\n", + dprintf("Probe filesystem on %s %s partition '%s' %s %p\n", type, map, (*cur)->name, - ((*cur)->flags) & PART_FLAG_BOOT ? "(bootable)" : ""); + ((*cur)->flags) & PART_FLAG_BOOT ? "(bootable)" : "", *cur); if (((*cur)->flags) & PART_FLAG_FS) { if (((*cur)->flags) & PART_FLAG_BOOT) (*cur)->fs = fs_probe(*cur, 1); else (*cur)->fs = fs_probe(*cur, 0); + } else if (((*cur)->flags) & PART_TYPE_RAW) { + (*cur)->fs = fs_probe(*cur, 2); } else { (*cur)->fs = fs_probe(*cur, 2); } - if (((*cur)->flags) & PART_FLAG_BOOT) { - bd_set_boot_part(bd, *cur); fs_get_bootfile((*cur)->fs); + if (((*cur)->flags) & PART_FLAG_BOOT) { + dprintf("Partition is bootable (%d)\n", (*cur)->partnum); + bd_set_boot_part(bd, *cur, (*cur)->partnum); + if (boot_part == NULL) + boot_part = *cur; } } - DPRINTF("Boot partition: %p %p %p %p\n", boot_part, boot_part->fs, + dprintf("Boot partition: %p %p %p %p\n", boot_part, boot_part->fs, part_fs(boot_part), part0); return boot_part; @@ -279,6 +277,7 @@ part->boot_size.offset = 0; part->boot_load = 0; part->boot_entry = 0; + part->flags |= PART_FLAG_BOOT; return 0; } diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/libpart/isofs.c OpenHackWare-release-0.4/src/libpart/isofs.c --- OpenHackWare-release-0.4.org/src/libpart/isofs.c 2005-03-31 09:23:33.000000000 +0200 +++ OpenHackWare-release-0.4/src/libpart/isofs.c 2005-07-03 16:17:41.000000000 +0200 @@ -242,7 +242,7 @@ part->boot_start.bloc, part->boot_size.bloc, part->boot_load, part->boot_entry); part->flags = PART_TYPE_ISO9660 | PART_FLAG_BOOT; - part_register(bd, part, name); + part_register(bd, part, name, i + 1); fs_raw_set_bootfile(part, part->boot_start.bloc, part->boot_start.offset, part->boot_size.bloc, diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/libpart/libpart.h OpenHackWare-release-0.4/src/libpart/libpart.h --- OpenHackWare-release-0.4.org/src/libpart/libpart.h 2005-03-31 09:23:33.000000000 +0200 +++ OpenHackWare-release-0.4/src/libpart/libpart.h 2005-07-03 16:17:41.000000000 +0200 @@ -30,6 +30,7 @@ struct part_t { bloc_device_t *bd; + int partnum; uint32_t start; /* Partition first bloc */ uint32_t size; /* Partition size, in blocs */ uint32_t spb; @@ -54,7 +55,7 @@ }; int part_register (bloc_device_t *bd, part_t *partition, - const unsigned char *name); + const unsigned char *name, int partnum); void part_set_blocsize (bloc_device_t *bd, part_t *part, uint32_t blocsize); void part_private_set (part_t *part, void *private); void *part_private_get (part_t *part); diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/libpart/prep.c OpenHackWare-release-0.4/src/libpart/prep.c --- OpenHackWare-release-0.4.org/src/libpart/prep.c 2005-03-31 09:23:33.000000000 +0200 +++ OpenHackWare-release-0.4/src/libpart/prep.c 2005-07-03 16:17:41.000000000 +0200 @@ -164,7 +164,7 @@ part->boot_load = 0; part->boot_entry = boot_offset - part->bloc_size; part->flags = PART_TYPE_PREP | PART_FLAG_BOOT; - part_register(bd, part, "PREP boot"); + part_register(bd, part, "PREP boot", i); fs_raw_set_bootfile(part, part->boot_start.bloc, part->boot_start.offset, part->boot_size.bloc, diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/main.c OpenHackWare-release-0.4/src/main.c --- OpenHackWare-release-0.4.org/src/main.c 2005-03-31 09:23:33.000000000 +0200 +++ OpenHackWare-release-0.4/src/main.c 2005-06-07 23:48:39.000000000 +0200 @@ -364,20 +364,24 @@ void *load_base, *load_entry, *last_alloc, *load_end; uint32_t memsize, boot_image_size, cmdline_size, ramdisk_size; uint32_t boot_base, boot_nb; - int boot_device; + int boot_device, i; + static const uint32_t isa_base_tab[3] = { + 0x80000000, /* PREP */ + 0xFE000000, /* Grackle (Heathrow) */ + 0xF2000000, /* UniNorth (Mac99) */ + }; /* Retrieve NVRAM configuration */ - nvram_retry: + for(i = 0; i < 3; i++) { + isa_io_base = isa_base_tab[i]; nvram = NVRAM_get_config(&memsize, &boot_device, &boot_image, &boot_image_size, &cmdline, &cmdline_size, &ramdisk, &ramdisk_size); - if (nvram == NULL) { - /* Retry with another isa_io_base */ - if (isa_io_base == 0x80000000) { - isa_io_base = 0xF2000000; - goto nvram_retry; + if (nvram) + break; } + if (i == 3) { ERROR("Unable to load configuration from NVRAM. Aborting...\n"); return -1; } @@ -402,7 +406,7 @@ cpu_name = CPU_get_name(pvr); OF_register_cpu(cpu_name, 0, pvr, 200 * 1000 * 1000, 200 * 1000 * 1000, - 100 * 1000 * 1000, 10 * 1000 * 1000, + 100 * 1000 * 1000, 100 * 1000 * 1000, 0x0092); } OF_register_memory(memsize, 512 * 1024 /* TOFIX */); @@ -433,9 +437,12 @@ vga_puts(copyright); vga_puts("\n"); +#if 0 /* QEMU is quite incoherent: d is cdrom, not second drive */ + /* XXX: should probe CD-ROM position */ if (boot_device == 'd') boot_device = 'e'; +#endif /* Open boot device */ boot_part = bd_probe(boot_device); if (boot_device == 'm') { diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/nvram.c OpenHackWare-release-0.4/src/nvram.c --- OpenHackWare-release-0.4.org/src/nvram.c 2005-03-31 09:23:33.000000000 +0200 +++ OpenHackWare-release-0.4/src/nvram.c 2005-06-04 23:44:03.000000000 +0200 @@ -334,6 +334,7 @@ ret = NVRAM_chrp_format(nvram); break; case ARCH_MAC99: + case ARCH_HEATHROW: /* XXX: may be incorrect */ ret = NVRAM_mac99_format(nvram); break; case ARCH_POP: @@ -409,13 +410,12 @@ arch = ARCH_MAC99; } else if (strcmp(sign, "POP") == 0) { arch = ARCH_POP; + } else if (strcmp(sign, "HEATHROW") == 0) { + arch = ARCH_HEATHROW; } else { ERROR("Unknown PPC architecture: '%s'\n", sign); return NULL; } - /* HACK */ - if (arch == ARCH_CHRP) - arch = ARCH_MAC99; lword = NVRAM_get_lword(nvram, 0x30); *RAM_size = lword; byte = NVRAM_get_byte(nvram, 0x34); diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/of.c OpenHackWare-release-0.4/src/of.c --- OpenHackWare-release-0.4.org/src/of.c 2005-04-06 23:17:26.000000000 +0200 +++ OpenHackWare-release-0.4/src/of.c 2005-07-07 23:30:08.000000000 +0200 @@ -489,7 +489,7 @@ ERROR("%s can't alloc new node '%s' name\n", __func__, name); return NULL; } - new->prop_address = OF_prop_int_new(env, new, "address", address); + new->prop_address = OF_prop_int_new(env, new, "unit-address", address); if (new->prop_address == NULL) { free(new->prop_name->value); free(new->prop_name); @@ -1017,6 +1017,33 @@ string, strlen(string) + 1); } +/* convert '\1' char to '\0' */ +static OF_prop_t *OF_prop_string_new1 (OF_env_t *env, OF_node_t *node, + const unsigned char *name, + const unsigned char *string) +{ + int len, i; + OF_prop_t *ret; + unsigned char *str; + + if (strchr(string, '\1') == NULL) { + return OF_prop_string_new(env, node, name, string); + } else { + len = strlen(string) + 1; + str = malloc(len); + if (!str) + return NULL; + memcpy(str, string, len); + for(i = 0; i < len; i++) + if (str[i] == '\1') + str[i] = '\0'; + ret = OF_property_new(env, node, name, + str, len); + free(str); + return ret; + } +} + __attribute__ (( section (".OpenFirmware") )) static OF_prop_t *OF_prop_int_new (OF_env_t *env, OF_node_t *node, const unsigned char *name, uint32_t value) @@ -1421,15 +1448,12 @@ __attribute__ (( section (".OpenFirmware") )) int OF_init (void) { - const unsigned char compat_str[] = #if 0 "PowerMac3,1\0MacRISC\0Power Macintosh\0"; "PowerMac1,2\0MacRISC\0Power Macintosh\0"; "AAPL,PowerMac G3\0PowerMac G3\0MacRISC\0Power Macintosh\0"; "AAPL,PowerMac3,0\0MacRISC\0Power Macintosh\0"; "AAPL,Gossamer\0MacRISC\0Power Macintosh\0"; -#else - "AAPL,PowerMac G3\0PowerMac G3\0MacRISC\0Power Macintosh\0"; #endif OF_env_t *OF_env; OF_node_t *als, *opt, *chs, *pks; @@ -1455,15 +1479,21 @@ return -1; } OF_prop_string_new(OF_env, OF_node_root, "device_type", "bootrom"); -#if 0 - OF_prop_string_new(OF_env, OF_node_root, - "model", "PPC Open Hack'Ware " BIOS_VERSION); -#else + if (arch == ARCH_HEATHROW) { + const unsigned char compat_str[] = + "PowerMac1,1\0MacRISC\0Power Macintosh"; + OF_property_new(OF_env, OF_node_root, "compatible", + compat_str, sizeof(compat_str)); OF_prop_string_new(OF_env, OF_node_root, - "model", compat_str); -#endif + "model", "Power Macintosh"); + } else { + const unsigned char compat_str[] = + "PowerMac3,1\0MacRISC\0Power Macintosh"; OF_property_new(OF_env, OF_node_root, "compatible", compat_str, sizeof(compat_str)); + OF_prop_string_new(OF_env, OF_node_root, + "model", "PowerMac3,1"); + } #if 0 OF_prop_string_new(OF_env, OF_node_root, "copyright", copyright); #else @@ -1561,14 +1591,15 @@ range.size = 0x00800000; OF_property_new(OF_env, rom, "ranges", &range, sizeof(OF_range_t)); OF_prop_int_new(OF_env, rom, "#address-cells", 1); + /* "/rom/boot-rom@fff00000" node */ - brom = OF_node_new(OF_env, OF_node_root, "boot-rom", 0xfff00000); + brom = OF_node_new(OF_env, rom, "boot-rom", 0xfff00000); if (brom == NULL) { ERROR("Cannot create 'boot-rom'\n"); return -1; } regs.address = 0xFFF00000; - regs.size = 0x00010000; + regs.size = 0x00100000; OF_property_new(OF_env, brom, "reg", ®s, sizeof(OF_regprop_t)); OF_prop_string_new(OF_env, brom, "write-characteristic", "flash"); OF_prop_string_new(OF_env, brom, "BootROM-build-date", @@ -1577,7 +1608,7 @@ OF_prop_string_new(OF_env, brom, "copyright", copyright); OF_prop_string_new(OF_env, brom, "model", BIOS_str); OF_prop_int_new(OF_env, brom, "result", 0); -#if 0 +#if 1 { /* Hack taken 'as-is' from PearPC */ unsigned char info[] = { @@ -1596,7 +1627,9 @@ OF_node_put(OF_env, brom); OF_node_put(OF_env, rom); } +#if 0 /* From here, hardcoded hacks to get a Mac-like machine */ + /* XXX: Core99 does not seem to like this NVRAM tree */ /* "/nvram@fff04000" node */ { OF_regprop_t regs; @@ -1617,6 +1650,7 @@ OF_prop_int_new(OF_env, chs, "nvram", OF_pack_handle(OF_env, nvr)); OF_node_put(OF_env, nvr); } +#endif /* "/pseudo-hid" : hid emulation as Apple does */ { OF_node_t *hid; @@ -1663,7 +1697,27 @@ } OF_node_put(OF_env, hid); } + if (arch == ARCH_MAC99) { + OF_node_t *unin; + OF_regprop_t regs; + unin = OF_node_new(OF_env, OF_node_root, + "uni-n", 0xf8000000); + if (unin == NULL) { + ERROR("Cannot create 'uni-n'\n"); + return -1; + } + OF_prop_string_new(OF_env, unin, "device-type", "memory-controller"); + OF_prop_string_new(OF_env, unin, "model", "AAPL,UniNorth"); + OF_prop_string_new(OF_env, unin, "compatible", "uni-north"); + regs.address = 0xf8000000; + regs.size = 0x01000000; + OF_property_new(OF_env, unin, "reg", ®s, sizeof(regs)); + OF_prop_int_new(OF_env, unin, "#address-cells", 1); + OF_prop_int_new(OF_env, unin, "#size-cells", 1); + OF_prop_int_new(OF_env, unin, "device-rev", 3); + OF_node_put(OF_env, unin); + } #if 1 /* This is mandatory for claim to work * but I don't know where it should really be (in cpu ?) @@ -1693,7 +1747,9 @@ /* "/options/boot-args" node */ { - const unsigned char *args = "-v rootdev cdrom"; + // const unsigned char *args = "-v rootdev cdrom"; + //const unsigned char *args = "-v io=0xffffffff"; + const unsigned char *args = "-v"; /* Ask MacOS X to print debug messages */ // OF_prop_string_new(OF_env, chs, "machargs", args); // OF_prop_string_new(OF_env, opt, "boot-command", args); @@ -2013,17 +2069,17 @@ OF_prop_int_new(OF_env, node, "min-grant", min_grant); OF_prop_int_new(OF_env, node, "max-latency", max_latency); if (dev->type != NULL) - OF_prop_string_new(OF_env, node, "device_type", dev->type); + OF_prop_string_new1(OF_env, node, "device_type", dev->type); if (dev->compat != NULL) - OF_prop_string_new(OF_env, node, "compatible", dev->compat); + OF_prop_string_new1(OF_env, node, "compatible", dev->compat); if (dev->model != NULL) - OF_prop_string_new(OF_env, node, "model", dev->model); + OF_prop_string_new1(OF_env, node, "model", dev->model); if (dev->acells != 0) OF_prop_int_new(OF_env, node, "#address-cells", dev->acells); if (dev->scells != 0) - OF_prop_int_new(OF_env, node, "#interrupt-cells", dev->acells); + OF_prop_int_new(OF_env, node, "#size-cells", dev->scells); if (dev->icells != 0) - OF_prop_int_new(OF_env, node, "#size-cells", dev->acells); + OF_prop_int_new(OF_env, node, "#interrupt-cells", dev->icells); dprintf("Done %p %p\n", parent, node); return node; @@ -2040,8 +2096,9 @@ OF_env_t *OF_env; pci_range_t ranges[3]; OF_regprop_t regs[1]; - OF_node_t *pci_host; + OF_node_t *pci_host, *als; int nranges; + unsigned char buffer[OF_NAMELEN_MAX]; OF_env = OF_env_main; dprintf("register PCI host '%s' '%s' '%s' '%s'\n", @@ -2052,6 +2109,17 @@ ERROR("Cannot create pci host\n"); return NULL; } + + als = OF_node_get(OF_env, "aliases"); + if (als == NULL) { + ERROR("Cannot get 'aliases'\n"); + return NULL; + } + sprintf(buffer, "/%s", dev->name); + OF_prop_string_set(OF_env, als, "pci", buffer); + OF_node_put(OF_env, als); + + regs[0].address = cfg_base; regs[0].size = cfg_len; OF_property_new(OF_env, pci_host, "reg", regs, sizeof(OF_regprop_t)); @@ -2136,6 +2204,11 @@ return pci_dev; } +/* XXX: suppress that, used for interrupt map init */ +OF_node_t *pci_host_node; +uint32_t pci_host_interrupt_map[7 * 32]; +int pci_host_interrupt_map_len = 0; + void OF_finalize_pci_host (void *dev, int first_bus, int nb_busses) { OF_env_t *OF_env; @@ -2145,10 +2218,12 @@ regs[0].address = first_bus; regs[0].size = nb_busses; OF_property_new(OF_env, dev, "bus-range", regs, sizeof(OF_regprop_t)); + pci_host_node = dev; } void OF_finalize_pci_device (void *dev, uint8_t bus, uint8_t devfn, - uint32_t *regions, uint32_t *sizes) + uint32_t *regions, uint32_t *sizes, + int irq_line) { OF_env_t *OF_env; pci_reg_prop_t pregs[6], rregs[6]; @@ -2156,6 +2231,7 @@ int i, j, k; OF_env = OF_env_main; + /* XXX: only useful for VGA card in fact */ if (regions[0] != 0x00000000) OF_prop_int_set(OF_env, dev, "address", regions[0] & ~0x0000000F); for (i = 0, j = 0, k = 0; i < 6; i++) { @@ -2222,7 +2298,22 @@ } else { OF_property_new(OF_env, dev, "assigned-addresses", NULL, 0); } -#if 0 + if (irq_line >= 0) { + int i; + OF_prop_int_new(OF_env, dev, "interrupts", 1); + i = pci_host_interrupt_map_len; + pci_host_interrupt_map[i++] = (devfn << 8) & 0xf800; + pci_host_interrupt_map[i++] = 0; + pci_host_interrupt_map[i++] = 0; + pci_host_interrupt_map[i++] = 0; + pci_host_interrupt_map[i++] = 0; /* pic handle will be patched later */ + pci_host_interrupt_map[i++] = irq_line; + if (arch != ARCH_HEATHROW) { + pci_host_interrupt_map[i++] = 1; + } + pci_host_interrupt_map_len = i; + } +#if 1 { OF_prop_t *prop_name = ((OF_node_t *)dev)->prop_name; @@ -2390,6 +2481,54 @@ return 0; } +static void keylargo_ata(OF_node_t *mio, uint32_t base_address, + uint32_t base, int irq1, int irq2, + uint16_t pic_phandle) +{ + OF_env_t *OF_env = OF_env_main; + OF_node_t *ata; + OF_regprop_t regs[2]; + + ata = OF_node_new(OF_env, mio, "ata-4", base); + if (ata == NULL) { + ERROR("Cannot create 'ata-4'\n"); + return; + } + OF_prop_string_new(OF_env, ata, "device_type", "ata"); +#if 1 + OF_prop_string_new(OF_env, ata, "compatible", "key2largo-ata"); + OF_prop_string_new(OF_env, ata, "model", "ata-4"); + OF_prop_string_new(OF_env, ata, "cable-type", "80-conductor"); +#else + OF_prop_string_new(OF_env, ata, "compatible", "cmd646-ata"); + OF_prop_string_new(OF_env, ata, "model", "ata-4"); +#endif + OF_prop_int_new(OF_env, ata, "#address-cells", 1); + OF_prop_int_new(OF_env, ata, "#size-cells", 0); + regs[0].address = base; + regs[0].size = 0x00001000; +#if 0 // HACK: Don't set up DMA registers + regs[1].address = 0x00008A00; + regs[1].size = 0x00001000; + OF_property_new(OF_env, ata, "reg", + regs, 2 * sizeof(OF_regprop_t)); +#else + OF_property_new(OF_env, ata, "reg", + regs, sizeof(OF_regprop_t)); +#endif + OF_prop_int_new(OF_env, ata, "interrupt-parent", pic_phandle); + regs[0].address = irq1; + regs[0].size = 0x00000001; + regs[1].address = irq2; + regs[1].size = 0x00000000; + OF_property_new(OF_env, ata, "interrupts", + regs, 2 * sizeof(OF_regprop_t)); + if (base == 0x1f000) + ide_pci_pmac_register(base_address + base, 0x00000000, ata); + else + ide_pci_pmac_register(0x00000000, base_address + base, ata); +} + void OF_finalize_pci_macio (void *dev, uint32_t base_address, uint32_t size, void *private_data) { @@ -2398,6 +2537,8 @@ pci_reg_prop_t pregs[2]; OF_node_t *mio, *chs, *als; uint16_t pic_phandle; + int rec_len; + OF_prop_t *mio_reg; OF_DPRINTF("mac-io: %p\n", dev); OF_env = OF_env_main; @@ -2416,10 +2557,14 @@ mio = dev; mio->private_data = private_data; pregs[0].addr.hi = 0x00000000; - pregs[0].addr.mid = 0x82013810; + pregs[0].addr.mid = 0x00000000; pregs[0].addr.lo = 0x00000000; pregs[0].size_hi = base_address; pregs[0].size_lo = size; + mio_reg = OF_property_get(OF_env, mio, "reg"); + if (mio_reg && mio_reg->vlen >= 5 * 4) { + pregs[0].addr.mid = ((pci_reg_prop_t *)mio_reg->value)->addr.hi; + } OF_property_new(OF_env, mio, "ranges", &pregs, sizeof(pci_reg_prop_t)); #if 0 @@ -2431,8 +2576,32 @@ OF_property_new(OF_env, mio, "assigned-addresses", &pregs, sizeof(pci_reg_prop_t)); #endif + + if (arch == ARCH_HEATHROW) { + /* Heathrow PIC */ + OF_regprop_t regs; + OF_node_t *mpic; + const char compat_str[] = "heathrow\0mac-risc"; + + mpic = OF_node_new(OF_env, mio, "interrupt-controller", 0x10); + if (mpic == NULL) { + ERROR("Cannot create 'mpic'\n"); + goto out; + } + OF_prop_string_new(OF_env, mpic, "device_type", "interrupt-controller"); + OF_property_new(OF_env, mpic, "compatible", compat_str, sizeof(compat_str)); + OF_prop_int_new(OF_env, mpic, "#interrupt-cells", 1); + regs.address = 0x10; + regs.size = 0x20; + OF_property_new(OF_env, mpic, "reg", + ®s, sizeof(regs)); + OF_property_new(OF_env, mpic, "interrupt-controller", NULL, 0); + pic_phandle = OF_pack_handle(OF_env, mpic); + OF_prop_int_new(OF_env, chs, "interrupt-controller", pic_phandle); + OF_node_put(OF_env, mpic); + rec_len = 6; + } else { /* OpenPIC */ - { OF_regprop_t regs[4]; OF_node_t *mpic; mpic = OF_node_new(OF_env, mio, "interrupt-controller", 0x40000); @@ -2455,8 +2624,37 @@ pic_phandle = OF_pack_handle(OF_env, mpic); OF_prop_int_new(OF_env, chs, "interrupt-controller", pic_phandle); OF_node_put(OF_env, mpic); + rec_len = 7; } -#if 1 + + /* patch pci host table */ + /* XXX: do it after the PCI init */ + { + int i; + uint32_t tab[4]; + + for(i = 0; i < pci_host_interrupt_map_len; i += rec_len) + pci_host_interrupt_map[i + 4] = pic_phandle; +#if 0 + dprintf("interrupt-map:\n"); + for(i = 0; i < pci_host_interrupt_map_len; i++) { + dprintf(" %08x", pci_host_interrupt_map[i]); + if ((i % rec_len) == (rec_len - 1)) + dprintf("\n"); + } + dprintf("\n"); +#endif + OF_property_new(OF_env, pci_host_node, "interrupt-map", + pci_host_interrupt_map, + pci_host_interrupt_map_len * sizeof(uint32_t)); + tab[0] = 0xf800; + tab[1] = 0; + tab[2] = 0; + tab[3] = 0; + OF_property_new(OF_env, pci_host_node, "interrupt-map-mask", + tab, 4 * sizeof(uint32_t)); + } +#if 0 /* escc is usefull to get MacOS X debug messages */ { OF_regprop_t regs[8]; @@ -2645,85 +2843,12 @@ OF_node_put(OF_env, scc); } #endif - /* IDE controller */ - { - OF_node_t *ata; - OF_regprop_t regs[2]; - ata = OF_node_new(OF_env, mio, "ata-4", 0x1f000); - if (ata == NULL) { - ERROR("Cannot create 'ata-4'\n"); - goto out; - } - OF_prop_string_new(OF_env, ata, "device_type", "ata"); -#if 1 - OF_prop_string_new(OF_env, ata, "compatible", "keylargo-ata"); - OF_prop_string_new(OF_env, ata, "model", "ata-4"); -#else - OF_prop_string_new(OF_env, ata, "compatible", "cmd646-ata"); - OF_prop_string_new(OF_env, ata, "model", "ata-4"); -#endif - OF_prop_int_new(OF_env, ata, "#address-cells", 1); - OF_prop_int_new(OF_env, ata, "#size-cells", 0); - regs[0].address = 0x0001F000; - regs[0].size = 0x00001000; -#if 0 // HACK: Don't set up DMA registers - regs[1].address = 0x00008A00; - regs[1].size = 0x00001000; - OF_property_new(OF_env, ata, "reg", - regs, 2 * sizeof(OF_regprop_t)); -#else - OF_property_new(OF_env, ata, "reg", - regs, sizeof(OF_regprop_t)); -#endif - OF_prop_int_new(OF_env, ata, "interrupt-parent", pic_phandle); - regs[0].address = 0x00000013; - regs[0].size = 0x00000001; - regs[1].address = 0x0000000B; - regs[1].size = 0x00000000; - OF_property_new(OF_env, ata, "interrupts", - regs, 2 * sizeof(OF_regprop_t)); - ide_pci_pmac_register(base_address + 0x1f000, 0x00000000, ata); - - } - { - OF_node_t *ata; - OF_regprop_t regs[2]; - ata = OF_node_new(OF_env, mio, "ata-4", 0x20000); - if (ata == NULL) { - ERROR("Cannot create 'ata-4'\n"); - goto out; - } - OF_prop_string_new(OF_env, ata, "device_type", "ata"); -#if 1 - OF_prop_string_new(OF_env, ata, "compatible", "keylargo-ata"); - OF_prop_string_new(OF_env, ata, "model", "ata-4"); -#else - OF_prop_string_new(OF_env, ata, "compatible", "cmd646-ata"); - OF_prop_string_new(OF_env, ata, "model", "ata-4"); -#endif - OF_prop_int_new(OF_env, ata, "#address-cells", 1); - OF_prop_int_new(OF_env, ata, "#size-cells", 0); - regs[0].address = 0x00020000; - regs[0].size = 0x00001000; -#if 0 // HACK: Don't set up DMA registers - regs[1].address = 0x00008A00; - regs[1].size = 0x00001000; - OF_property_new(OF_env, ata, "reg", - regs, 2 * sizeof(OF_regprop_t)); -#else - OF_property_new(OF_env, ata, "reg", - regs, sizeof(OF_regprop_t)); -#endif - OF_prop_int_new(OF_env, ata, "interrupt-parent", pic_phandle); - regs[0].address = 0x00000014; - regs[0].size = 0x00000001; - regs[1].address = 0x0000000B; - regs[1].size = 0x00000000; - OF_property_new(OF_env, ata, "interrupts", - regs, 2 * sizeof(OF_regprop_t)); - ide_pci_pmac_register(0x00000000, base_address + 0x20000, ata); - + /* Keylargo IDE controller: need some work (DMA problem ?) */ + if (arch == ARCH_MAC99) { + keylargo_ata(mio, base_address, 0x1f000, 0x13, 0xb, pic_phandle); + keylargo_ata(mio, base_address, 0x20000, 0x14, 0xb, pic_phandle); } +#if 0 /* Timer */ { OF_node_t *tmr; @@ -2746,10 +2871,11 @@ regs, sizeof(OF_regprop_t)); OF_node_put(OF_env, tmr); } +#endif /* VIA-PMU */ { /* Controls adb, RTC and power-mgt (forget it !) */ - OF_node_t *via, *adb, *rtc; + OF_node_t *via, *adb; OF_regprop_t regs[1]; #if 0 // THIS IS A HACK AND IS COMPLETELY ABSURD ! // (but needed has Qemu doesn't emulate via-pmu). @@ -2773,14 +2899,21 @@ regs[0].size = 0x00002000; OF_property_new(OF_env, via, "reg", regs, sizeof(OF_regprop_t)); OF_prop_int_new(OF_env, via, "interrupt-parent", pic_phandle); + if (arch == ARCH_HEATHROW) { + OF_prop_int_new(OF_env, via, "interrupts", 0x12); + } else { regs[0].address = 0x00000019; regs[0].size = 0x00000001; OF_property_new(OF_env, via, "interrupts", regs, sizeof(OF_regprop_t)); + } + /* force usage of OF bus speeds */ + OF_prop_int_new(OF_env, via, "BusSpeedCorrect", 1); #if 0 OF_prop_int_new(OF_env, via, "pmu-version", 0x00D0740C); #endif -#if 1 + { + OF_node_t *kbd, *mouse; /* ADB pseudo-device */ adb = OF_node_new(OF_env, via, "adb", OF_ADDRESS_NONE); if (adb == NULL) { @@ -2797,9 +2930,26 @@ OF_prop_int_new(OF_env, adb, "#size-cells", 0); OF_pack_get_path(OF_env, tmp, 512, adb); OF_prop_string_new(OF_env, als, "adb", tmp); - /* XXX: add "keyboard@2" and "mouse@3" */ - OF_node_put(OF_env, adb); -#endif + + kbd = OF_node_new(OF_env, adb, "keyboard", 2); + if (kbd == NULL) { + ERROR("Cannot create 'kbd'\n"); + goto out; + } + OF_prop_string_new(OF_env, kbd, "device_type", "keyboard"); + OF_prop_int_new(OF_env, kbd, "reg", 2); + + mouse = OF_node_new(OF_env, adb, "mouse", 3); + if (mouse == NULL) { + ERROR("Cannot create 'mouse'\n"); + goto out; + } + OF_prop_string_new(OF_env, mouse, "device_type", "mouse"); + OF_prop_int_new(OF_env, mouse, "reg", 3); + OF_prop_int_new(OF_env, mouse, "#buttons", 3); + } + { + OF_node_t *rtc; rtc = OF_node_new(OF_env, via, "rtc", OF_ADDRESS_NONE); if (rtc == NULL) { @@ -2813,14 +2963,68 @@ OF_prop_string_new(OF_env, rtc, "compatible", "rtc"); #endif OF_node_put(OF_env, rtc); - OF_node_put(OF_env, via); } + // OF_node_put(OF_env, via); + } + { + OF_node_t *pmgt; + pmgt = OF_node_new(OF_env, mio, "power-mgt", OF_ADDRESS_NONE); + OF_prop_string_new(OF_env, pmgt, "device_type", "power-mgt"); + OF_prop_string_new(OF_env, pmgt, "compatible", "cuda"); + OF_prop_string_new(OF_env, pmgt, "mgt-kind", "min-consumption-pwm-led"); + OF_node_put(OF_env, pmgt); + } + + if (arch == ARCH_HEATHROW) { + /* NVRAM */ + OF_node_t *nvr; + OF_regprop_t regs; + nvr = OF_node_new(OF_env, mio, "nvram", 0x60000); + OF_prop_string_new(OF_env, nvr, "device_type", "nvram"); + regs.address = 0x60000; + regs.size = 0x00020000; + OF_property_new(OF_env, nvr, "reg", ®s, sizeof(regs)); + OF_prop_int_new(OF_env, nvr, "#bytes", 0x2000); + OF_node_put(OF_env, nvr); + } + out: // OF_node_put(OF_env, mio); OF_node_put(OF_env, chs); OF_node_put(OF_env, als); } +void OF_finalize_pci_ide (void *dev, + uint32_t io_base0, uint32_t io_base1, + uint32_t io_base2, uint32_t io_base3) +{ + OF_env_t *OF_env = OF_env_main; + OF_node_t *pci_ata = dev; + OF_node_t *ata, *atas[2]; + int i; + + OF_prop_int_new(OF_env, pci_ata, "#address-cells", 1); + OF_prop_int_new(OF_env, pci_ata, "#size-cells", 0); + + /* XXX: Darwin handles only one device */ + for(i = 0; i < 1; i++) { + ata = OF_node_new(OF_env, pci_ata, "ata-4", i); + if (ata == NULL) { + ERROR("Cannot create 'ata-4'\n"); + return; + } + OF_prop_string_new(OF_env, ata, "device_type", "ata"); + OF_prop_string_new(OF_env, ata, "compatible", "cmd646-ata"); + OF_prop_string_new(OF_env, ata, "model", "ata-4"); + OF_prop_int_new(OF_env, ata, "#address-cells", 1); + OF_prop_int_new(OF_env, ata, "#size-cells", 0); + OF_prop_int_new(OF_env, ata, "reg", i); + atas[i] = ata; + } + ide_pci_pc_register(io_base0, io_base1, io_base2, io_base3, + atas[0], atas[1]); +} + /*****************************************************************************/ /* Fake package */ static void OF_method_fake (OF_env_t *OF_env) @@ -2862,11 +3066,11 @@ /* As we get a 1:1 mapping, do nothing */ ihandle = popd(OF_env); args = (void *)popd(OF_env); - address = popd(OF_env); - virt = popd(OF_env); - size = popd(OF_env); popd(OF_env); - OF_DPRINTF("Translate address %0x %0x %0x %0x\n", ihandle, address, + size = popd(OF_env); + virt = popd(OF_env); + address = popd(OF_env); + OF_DPRINTF("Map %0x %0x %0x %0x\n", ihandle, address, virt, size); pushd(OF_env, 0); } @@ -3270,7 +3474,7 @@ OF_prop_string_new(OF_env, dsk, "device_type", "block"); OF_prop_string_new(OF_env, dsk, "category", type); OF_prop_int_new(OF_env, dsk, "device_id", devnum); - OF_prop_int_new(OF_env, dsk, "reg", 0); + OF_prop_int_new(OF_env, dsk, "reg", devnum); OF_method_new(OF_env, dsk, "open", &OF_blockdev_open); OF_method_new(OF_env, dsk, "seek", &OF_blockdev_seek); OF_method_new(OF_env, dsk, "read", &OF_blockdev_read); @@ -3432,7 +3636,8 @@ } void OF_vga_register (const unsigned char *name, unused uint32_t address, - int width, int height, int depth) + int width, int height, int depth, + unsigned long vga_bios_addr, unsigned long vga_bios_size) { OF_env_t *OF_env; unsigned char tmp[OF_NAMELEN_MAX]; @@ -3504,6 +3709,18 @@ OF_prop_string_new(OF_env, als, "display", tmp); OF_node_put(OF_env, als); /* XXX: may also need read-rectangle */ + + if (vga_bios_size >= 8) { + const uint8_t *p; + int size; + /* check the QEMU VGA BIOS header */ + p = (const uint8_t *)vga_bios_addr; + if (p[0] == 'N' && p[1] == 'D' && p[2] == 'R' && p[3] == 'V') { + size = *(uint32_t *)(p + 4); + OF_property_new(OF_env, disp, "driver,AAPL,MacOS,PowerPC", + p + 8, size); + } + } out: OF_node_put(OF_env, disp); } @@ -4451,7 +4668,10 @@ break; case 0x233441d3: /* MacOS X 10.2 and OpenDarwin 1.41 */ /* Create "memory-map" pseudo device */ - popd(OF_env); + { + OF_node_t *map; + uint32_t phandle; + /* Find "/packages" */ chs = OF_pack_find_by_name(OF_env, OF_node_root, "/chosen"); if (chs == NULL) { @@ -4459,10 +4679,6 @@ ERROR("Cannot get '/chosen'\n"); break; } - { -#if 1 - OF_node_t *map; - uint32_t phandle; map = OF_node_new(OF_env, chs, "memory-map", OF_ADDRESS_NONE); if (map == NULL) { pushd(OF_env, -1); @@ -4473,11 +4689,8 @@ OF_node_put(OF_env, map); OF_node_put(OF_env, chs); pushd(OF_env, phandle); - } -#else - pushd(OF_env, 0); -#endif pushd(OF_env, 0); + } break; case 0x32a2d18e: /* MacOS X 10.2 and OpenDarwin 6.02 */ /* Return screen ihandle */ @@ -4540,9 +4753,10 @@ case 0x4ad41f2d: /* Yaboot: wait 10 ms: sure ! */ break; + default: /* ERROR */ - printf("Script:\n%s\n", FString); + printf("Script: len=%d\n%s\n", (int)strlen(FString), FString); printf("Call %0x NOT IMPLEMENTED !\n", crc); bug(); break; @@ -4581,6 +4795,7 @@ { OF_CHECK_NBARGS(OF_env, 0); /* Should free all OF resources */ + bd_reset_all(); #if defined (DEBUG_BIOS) { uint16_t loglevel = 0x02 | 0x10 | 0x80; diff -wruN --exclude '*~' --exclude '*.o' --exclude '*.bin' --exclude '*.out' --exclude mkdiff OpenHackWare-release-0.4.org/src/pci.c OpenHackWare-release-0.4/src/pci.c --- OpenHackWare-release-0.4.org/src/pci.c 2005-03-31 09:23:33.000000000 +0200 +++ OpenHackWare-release-0.4/src/pci.c 2005-07-07 23:27:37.000000000 +0200 @@ -99,8 +99,8 @@ uint16_t min_grant; uint16_t max_latency; uint8_t irq_line; - uint32_t regions[6]; - uint32_t sizes[6]; + uint32_t regions[7]; /* the region 6 is the PCI ROM */ + uint32_t sizes[7]; pci_device_t *next; }; @@ -158,6 +158,7 @@ /* IRQ numbers assigned to PCI IRQs */ static uint8_t prep_pci_irqs[4] = { 9, 11, 9, 11 }; +static uint8_t heathrow_pci_irqs[4] = { 0x15, 0x16, 0x17, 0x18 }; static uint8_t pmac_pci_irqs[4] = { 8, 9, 10, 11 }; /* PREP PCI host */ @@ -399,6 +400,79 @@ &uninorth_config_readl, &uninorth_config_writel, }; +/* Grackle PCI host */ + +static uint32_t grackle_cfg_address (pci_bridge_t *bridge, + uint8_t bus, uint8_t devfn, + uint8_t offset) +{ + uint32_t addr; + addr = 0x80000000 | (bus << 16) | (devfn << 8) | (offset & 0xfc); + stswap32((uint32_t *)bridge->cfg_addr, addr); + return bridge->cfg_data + (offset & 3); +} + +static uint8_t grackle_config_readb (pci_bridge_t *bridge, + uint8_t bus, uint8_t devfn, + uint8_t offset) +{ + uint32_t addr; + addr = grackle_cfg_address(bridge, bus, devfn, offset); + return *((uint8_t *)addr); +} + +static void grackle_config_writeb (pci_bridge_t *bridge, + uint8_t bus, uint8_t devfn, + uint8_t offset, uint8_t val) +{ + uint32_t addr; + addr = grackle_cfg_address(bridge, bus, devfn, offset); + *((uint8_t *)addr) = val; +} + +static uint16_t grackle_config_readw (pci_bridge_t *bridge, + uint8_t bus, uint8_t devfn, + uint8_t offset) +{ + uint32_t addr; + addr = grackle_cfg_address(bridge, bus, devfn, offset); + return ldswap16((uint16_t *)addr); +} + +static void grackle_config_writew (pci_bridge_t *bridge, + uint8_t bus, uint8_t devfn, + uint8_t offset, uint16_t val) +{ + uint32_t addr; + addr = grackle_cfg_address(bridge, bus, devfn, offset); + stswap16((uint16_t *)addr, val); +} + +static uint32_t grackle_config_readl (pci_bridge_t *bridge, + uint8_t bus, uint8_t devfn, + uint8_t offset) +{ + uint32_t addr; + addr = grackle_cfg_address(bridge, bus, devfn, offset); + return ldswap32((uint32_t *)addr); +} + +static void grackle_config_writel (pci_bridge_t *bridge, + uint8_t bus, uint8_t devfn, + uint8_t offset, uint32_t val) +{ + uint32_t addr; + + addr = grackle_cfg_address(bridge, bus, devfn, offset); + stswap32((uint32_t *)addr, val); +} + +static pci_ops_t grackle_pci_ops = { + &grackle_config_readb, &grackle_config_writeb, + &grackle_config_readw, &grackle_config_writew, + &grackle_config_readl, &grackle_config_writel, +}; + static inline uint8_t pci_config_readb (pci_bridge_t *bridge, uint8_t bus, uint8_t devfn, uint8_t offset) @@ -466,12 +540,22 @@ }, }; +static int ide_config_cb2 (pci_device_t *device) +{ + OF_finalize_pci_ide(device->common.OF_private, + device->regions[0] & ~0x0000000F, + device->regions[1] & ~0x0000000F, + device->regions[2] & ~0x0000000F, + device->regions[3] & ~0x0000000F); + return 0; +} + static pci_dev_t ide_devices[] = { { - 0x8086, 0x0100, - NULL, "Qemu IDE", "Qemu IDE", "ide", + 0x1095, 0x0646, /* CMD646 IDE controller */ + "pci-ide", "pci-ata", NULL, NULL, 0, 0, 0, - NULL, NULL, + ide_config_cb2, NULL, }, { 0xFFFF, 0xFFFF, @@ -481,7 +565,9 @@ }, }; -static int ide_config_cb (pci_device_t *device) +#if 0 +/* should base it on PCI ID, not on arch */ +static int ide_config_cb (unused pci_device_t *device) { printf("Register IDE controller\n"); switch (arch) { @@ -491,14 +577,8 @@ device->common.OF_private); break; default: - ide_pci_pc_register(device->regions[0] & ~0x0000000F, - device->regions[1] & ~0x0000000F, - device->regions[2] & ~0x0000000F, - device->regions[3] & ~0x0000000F, - device->common.OF_private); break; } - return 0; } @@ -512,16 +592,12 @@ device->common.OF_private); break; default: - ide_pci_pc_register(device->regions[0] & ~0x0000000F, - device->regions[1] & ~0x0000000F, - device->regions[2] & ~0x0000000F, - device->regions[3] & ~0x0000000F, - device->common.OF_private); break; } return 0; } +#endif static pci_subclass_t mass_subclass[] = { { @@ -530,7 +606,7 @@ }, { 0x01, "IDE controller", "ide", ide_devices, NULL, - &ide_config_cb, NULL, + NULL, NULL, }, { 0x02, "Floppy disk controller", NULL, NULL, NULL, @@ -546,7 +622,7 @@ }, { 0x05, "ATA controller", "ata", NULL, NULL, - &ata_config_cb, NULL, + NULL, NULL, }, { 0x80, "misc mass-storage controller", NULL, NULL, NULL, @@ -646,7 +722,9 @@ /* VGA 640x480x16 */ OF_vga_register(device->common.device->name, device->regions[0] & ~0x0000000F, - vga_width, vga_height, vga_depth); + vga_width, vga_height, vga_depth, + device->regions[6] & ~0x0000000F, + device->sizes[6]); } vga_console_register(); @@ -750,6 +828,13 @@ NULL, &PREP_pci_ops, }; +pci_dev_t grackle_fake_bridge = { + 0xFFFF, 0xFFFF, + "pci", "pci-bridge", "DEC,21154", "DEC,21154.pci-bridge", + -1, -1, -1, + NULL, &grackle_pci_ops, +}; + static pci_dev_t hbrg_devices[] = { { 0x106B, 0x0020, NULL, @@ -758,8 +843,8 @@ NULL, &uninorth_agp_fake_bridge, }, { - 0x106B, 0x001F, - NULL, "pci", "AAPL,UniNorth", "uni-north", + 0x106B, 0x001F, NULL, + "pci", "AAPL,UniNorth", "uni-north", 3, 2, 1, NULL, &uninorth_fake_bridge, }, @@ -770,10 +855,10 @@ NULL, &uninorth_fake_bridge, }, { - 0x1011, 0x0026, NULL, - "pci-bridge", NULL, NULL, + 0x1057, 0x0002, "pci", + "pci", "MOT,MPC106", "grackle", 3, 2, 1, - NULL, &PREP_pci_ops, + NULL, &grackle_fake_bridge, }, { 0x1057, 0x4801, NULL, @@ -1443,7 +1528,14 @@ } static const pci_dev_t misc_pci[] = { - /* Apple Mac-io controller */ + /* Paddington Mac I/O */ + { + 0x106B, 0x0017, + "mac-io", "mac-io", "AAPL,343S1211", "paddington\1heathrow", + 1, 1, 1, + &macio_config_cb, NULL, + }, + /* KeyLargo Mac I/O */ { 0x106B, 0x0022, "mac-io", "mac-io", "AAPL,Keylargo", "Keylargo", @@ -1599,7 +1691,7 @@ uint8_t min_grant, uint8_t max_latency, int irq_line) { - uint32_t cmd; + uint32_t cmd, addr; int i; device->min_grant = min_grant; @@ -1611,22 +1703,28 @@ printf("MAP PCI device %d:%d to IRQ %d\n", device->bus, device->devfn, irq_line); } - for (i = 0; i < 6; i++) { + for (i = 0; i < 7; i++) { if ((device->regions[i] & ~0xF) != 0x00000000 && (device->regions[i] & ~0xF) != 0xFFFFFFF0) { printf("Map PCI device %d:%d %d to %0x %0x (%s)\n", device->bus, device->devfn, i, device->regions[i], device->sizes[i], - device->regions[i] & 0x00000001 ? "I/O" : "memory"); + (device->regions[i] & 0x00000001) && i != 6 ? "I/O" : + "memory"); + if (i != 6) { cmd = pci_config_readl(bridge, device->bus, device->devfn, 0x04); if (device->regions[i] & 0x00000001) cmd |= 0x00000001; else cmd |= 0x00000002; pci_config_writel(bridge, device->bus, device->devfn, 0x04, cmd); + } + if (i == 6) + addr = 0x30; /* PCI ROM */ + else + addr = 0x10 + (i * sizeof(uint32_t)); pci_config_writel(bridge, device->bus, device->devfn, - 0x10 + (i * sizeof(uint32_t)), - device->regions[i]); + addr, device->regions[i]); } } } @@ -1900,7 +1998,7 @@ goto out; } ret = (pci_u_t *)newd; - max_areas = 6; + max_areas = 7; /* register PCI device in OF tree */ if (bridge->dev.common.type == PCI_FAKE_BRIDGE) { newd->common.OF_private = @@ -1927,6 +2025,9 @@ /* Handle 64 bits memory mapping */ continue; } + if (i == 6) + addr = 0x30; /* PCI ROM */ + else addr = 0x10 + (i * sizeof(uint32_t)); /* Get region size * Note: we assume it's always a power of 2 @@ -1935,7 +2036,7 @@ smask = pci_config_readl(bridge, bus, devfn, addr); if (smask == 0x00000000 || smask == 0xFFFFFFFF) continue; - if (smask & 0x00000001) { + if ((smask & 0x00000001) != 0 && i != 6) { /* I/O space */ base = io_base; /* Align to a minimum of 256 bytes (arbitrary) */ @@ -1947,6 +2048,8 @@ /* Align to a minimum of 64 kB (arbitrary) */ min_align = 1 << 16; amask = 0x0000000F; + if (i == 6) + smask |= 1; /* PCI ROM enable */ } omask = smask & amask; smask &= ~amask; @@ -1980,7 +2083,10 @@ if (irq_pin > 0) { /* assign the IRQ */ irq_pin = ((devfn >> 3) + irq_pin - 1) & 3; - if (arch == ARCH_PREP) { + /* XXX: should base it on the PCI bridge type, not the arch */ + switch(arch) { + case ARCH_PREP: + { int elcr_port, val; irq_line = prep_pci_irqs[irq_pin]; /* set the IRQ to level-sensitive */ @@ -1988,14 +2094,22 @@ val = inb(elcr_port); val |= 1 << (irq_line & 7); outb(elcr_port, val); - } else { + } + break; + case ARCH_MAC99: irq_line = pmac_pci_irqs[irq_pin]; + break; + case ARCH_HEATHROW: + irq_line = heathrow_pci_irqs[irq_pin]; + break; + default: + break; } } update_device: pci_update_device(bridge, newd, min_grant, max_latency, irq_line); OF_finalize_pci_device(newd->common.OF_private, bus, devfn, - newd->regions, newd->sizes); + newd->regions, newd->sizes, irq_line); /* Call special inits if needed */ if (dev->config_cb != NULL) (*dev->config_cb)(newd); @@ -2049,6 +2163,32 @@ case ARCH_CHRP: /* TODO */ break; + case ARCH_HEATHROW: + dev = pci_find_device(0x06, 0x00, 0xFF, checkv, checkp); + if (dev == NULL) + return -1; + fake_host = pci_add_host(hostp, dev, + (0x06 << 24) | (0x00 << 16) | (0xFF << 8)); + if (fake_host == NULL) + return -1; + fake_host->dev.common.type = PCI_FAKE_HOST; + dev = &grackle_fake_bridge; + if (dev == NULL) + goto free_fake_host; + fake_bridge = pci_add_bridge(fake_host, 0, 0, dev, + (0x06 << 24) | (0x04 << 16) | (0xFF << 8), + cfg_base, cfg_len, + cfg_base + 0x7ec00000, + cfg_base + 0x7ee00000, + mem_base, mem_len, + io_base, io_len, + rbase, rlen, + 0, + &grackle_pci_ops); + if (fake_bridge == NULL) + goto free_fake_host; + fake_bridge->dev.common.type = PCI_FAKE_BRIDGE; + break; case ARCH_MAC99: dev = pci_find_device(0x06, 0x00, 0xFF, checkv, checkp); if (dev == NULL) @@ -2167,6 +2307,30 @@ case ARCH_CHRP: /* TODO */ break; + case ARCH_HEATHROW: + cfg_base = 0x80000000; + cfg_len = 0x7f000000; + mem_base = 0x80000000; + mem_len = 0x01000000; + io_base = 0xfe000000; + io_len = 0x00800000; +#if 1 + rbase = 0xfd000000; + rlen = 0x01000000; +#else + rbase = 0x00000000; + rlen = 0x01000000; +#endif + if (pci_check_host(&pci_main, cfg_base, cfg_len, + mem_base, mem_len, io_base, io_len, rbase, rlen, + 0x1057, 0x0002) == 0) { + isa_io_base = io_base; + busnum++; + } + for (curh = pci_main; curh->next != NULL; curh = curh->next) + continue; + pci_check_devices(curh); + break; case ARCH_MAC99: /* We are supposed to have 3 host bridges: * - the uninorth AGP bridge at 0xF0000000