summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJocelyn Mayer <l_indien@magic.fr>2014-02-09 16:53:20 +0100
committerAndreas Färber <andreas.faerber@web.de>2014-03-02 18:02:43 +0100
commit4be9d6e46808336623188417aa0f21d9d34b208a (patch)
treef5c0d304d8d676d92169782db03bba8ffceb8c51
parent943890a4f4667cefc82ea9a1959e03426a4e4807 (diff)
downloadqemu-openhackware-4be9d6e46808336623188417aa0f21d9d34b208a.tar.gz
ohw.diff
-rw-r--r--src/bios.h18
-rw-r--r--src/bloc.c96
-rw-r--r--src/libpart/apple.c25
-rw-r--r--src/libpart/core.c57
-rw-r--r--src/libpart/isofs.c2
-rw-r--r--src/libpart/libpart.h3
-rw-r--r--src/libpart/prep.c2
-rw-r--r--src/main.c23
-rw-r--r--src/nvram.c6
-rw-r--r--src/of.c465
-rw-r--r--src/pci.c236
11 files changed, 679 insertions, 254 deletions
diff --git a/src/bios.h b/src/bios.h
index b420fff..83d9af4 100644
--- a/src/bios.h
+++ b/src/bios.h
@@ -64,6 +64,7 @@ enum {
ARCH_CHRP,
ARCH_MAC99,
ARCH_POP,
+ ARCH_HEATHROW,
};
/* Hardware definition(s) */
@@ -174,6 +175,7 @@ int bd_write (bloc_device_t *bd, const void *buffer, int len);
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 @@ uint32_t bd_CHS2sect (bloc_device_t *bd,
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 @@ void *OF_register_pci_device (void *parent, pci_dev_t *dev,
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 --git a/src/bloc.c b/src/bloc.c
index 6883ee0..309b343 100644
--- a/src/bloc.c
+++ b/src/bloc.c
@@ -55,6 +55,7 @@ struct bloc_device_t {
/* Partitions */
part_t *parts, *bparts;
part_t *boot_part;
+ int bpartnum;
/* Chain */
bloc_device_t *next;
};
@@ -66,6 +67,7 @@ static int fdc_read_sector (bloc_device_t *bd, void *buffer, int secnum);
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_close (unused bloc_device_t *bd)
{
}
+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 @@ uint32_t bd_maxbloc (bloc_device_t *bd)
}
/* 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 @@ part_t **_bd_bparts (bloc_device_t *bd)
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 @@ part_t *bd_probe (int boot_device)
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 @@ static ide_ops_t *ide_pci_ops;
/* 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 @@ static ide_ops_t ide_pci_pc_ops = {
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 @@ void ide_pci_pc_register (uint32_t io_base0, uint32_t io_base1,
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 int ide_reset (bloc_device_t *bd)
}
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 @@ static int ide_initialize (bloc_device_t *bd, int device)
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 @@ static int ide_initialize (bloc_device_t *bd, int device)
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 @@ static void atapi_pad_req (void *buffer, int len)
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 @@ static int atapi_read_sector (bloc_device_t *bd, void *buffer, int secnum)
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 --git a/src/libpart/apple.c b/src/libpart/apple.c
index b006c61..1d72f67 100644
--- a/src/libpart/apple.c
+++ b/src/libpart/apple.c
@@ -199,14 +199,18 @@ part_t *Apple_probe_partitions (bloc_device_t *bd)
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_t *Apple_probe_partitions (bloc_device_t *bd)
*/
}
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 @@ part_t *Apple_probe_partitions (bloc_device_t *bd)
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 @@ part_t *Apple_probe_partitions (bloc_device_t *bd)
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 @@ part_t *Apple_probe_partitions (bloc_device_t *bd)
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_t *Apple_probe_partitions (bloc_device_t *bd)
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 --git a/src/libpart/core.c b/src/libpart/core.c
index 030104d..bc2feb0 100644
--- a/src/libpart/core.c
+++ b/src/libpart/core.c
@@ -126,7 +126,7 @@ void part_set_blocsize (bloc_device_t *bd, part_t *part, uint32_t blocsize)
}
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 @@ int part_register (bloc_device_t *bd, part_t *partition,
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 @@ int part_register (bloc_device_t *bd, part_t *partition,
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_t *part_get_raw (bloc_device_t *bd)
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 @@ part_t *part_probe (bloc_device_t *bd, int set_raw)
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 @@ part_t *part_probe (bloc_device_t *bd, int set_raw)
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 @@ int part_set_boot_file (part_t *part, uint32_t start, uint32_t offset,
part->boot_size.offset = 0;
part->boot_load = 0;
part->boot_entry = 0;
+ part->flags |= PART_FLAG_BOOT;
return 0;
}
diff --git a/src/libpart/isofs.c b/src/libpart/isofs.c
index 466a2e7..bbf8a50 100644
--- a/src/libpart/isofs.c
+++ b/src/libpart/isofs.c
@@ -242,7 +242,7 @@ part_t *isofs_probe_partitions (bloc_device_t *bd)
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 --git a/src/libpart/libpart.h b/src/libpart/libpart.h
index b8c38c9..a982b8f 100644
--- a/src/libpart/libpart.h
+++ b/src/libpart/libpart.h
@@ -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 @@ struct part_t {
};
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 --git a/src/libpart/prep.c b/src/libpart/prep.c
index b3bcdb9..b957bb9 100644
--- a/src/libpart/prep.c
+++ b/src/libpart/prep.c
@@ -164,7 +164,7 @@ part_t *PREP_find_partition (bloc_device_t *bd)
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 --git a/src/main.c b/src/main.c
index 081f517..ad80833 100644
--- a/src/main.c
+++ b/src/main.c
@@ -364,20 +364,24 @@ int main (void)
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 @@ int main (void)
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 @@ int main (void)
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 --git a/src/nvram.c b/src/nvram.c
index 58d63df..c78a079 100644
--- a/src/nvram.c
+++ b/src/nvram.c
@@ -334,6 +334,7 @@ int NVRAM_format (nvram_t *nvram)
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 @@ nvram_t *NVRAM_get_config (uint32_t *RAM_size, int *boot_device,
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 --git a/src/of.c b/src/of.c
index d1fc300..33582c3 100644
--- a/src/of.c
+++ b/src/of.c
@@ -489,7 +489,7 @@ static OF_node_t *OF_node_create (OF_env_t *env, OF_node_t *parent,
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 @@ static OF_prop_t *OF_prop_string_new (OF_env_t *env, OF_node_t *node,
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 @@ static OF_env_t *OF_env_main;
__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 @@ int OF_init (void)
return -1;
}
OF_prop_string_new(OF_env, OF_node_root, "device_type", "bootrom");
-#if 0
+ 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", "PPC Open Hack'Ware " BIOS_VERSION);
-#else
- 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 @@ int OF_init (void)
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", &regs, 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 @@ int OF_init (void)
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 @@ int OF_init (void)
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 @@ int OF_init (void)
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 @@ int OF_init (void)
}
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", &regs, 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 @@ int OF_init (void)
/* "/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 @@ static void *OF_pci_device_new (OF_env_t *OF_env, OF_node_t *parent,
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 @@ void *OF_register_pci_host (pci_dev_t *dev, uint16_t rev, uint32_t ccode,
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 @@ void *OF_register_pci_host (pci_dev_t *dev, uint16_t rev, uint32_t ccode,
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 @@ void *OF_register_pci_device (void *parent, pci_dev_t *dev,
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 @@ void OF_finalize_pci_host (void *dev, int first_bus, int nb_busses)
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 @@ void OF_finalize_pci_device (void *dev, uint8_t bus, uint8_t devfn,
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 @@ void OF_finalize_pci_device (void *dev, uint8_t bus, uint8_t devfn,
} 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 @@ int OF_register_stdio (const unsigned char *dev_in,
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 @@ void OF_finalize_pci_macio (void *dev, uint32_t base_address, uint32_t size,
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 @@ void OF_finalize_pci_macio (void *dev, uint32_t base_address, uint32_t size,
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 @@ void OF_finalize_pci_macio (void *dev, uint32_t base_address, uint32_t size,
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",
+ &regs, 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 @@ void OF_finalize_pci_macio (void *dev, uint32_t base_address, uint32_t size,
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 useful to get MacOS X debug messages */
{
OF_regprop_t regs[8];
@@ -2645,85 +2843,12 @@ void OF_finalize_pci_macio (void *dev, uint32_t base_address, uint32_t size,
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 @@ void OF_finalize_pci_macio (void *dev, uint32_t base_address, uint32_t size,
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 @@ void OF_finalize_pci_macio (void *dev, uint32_t base_address, uint32_t size,
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 @@ void OF_finalize_pci_macio (void *dev, uint32_t base_address, uint32_t size,
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 @@ void OF_finalize_pci_macio (void *dev, uint32_t base_address, uint32_t size,
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", &regs, 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 @@ static void OF_mmu_map (OF_env_t *OF_env)
/* 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 @@ void *OF_blockdev_register (void *parent, void *private,
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 @@ static void OF_vga_set_depth (OF_env_t *OF_env, OF_prop_t *prop,
}
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 @@ void OF_vga_register (const unsigned char *name, unused uint32_t address,
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 @@ static void OF_interpret (OF_env_t *OF_env)
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 @@ static void OF_interpret (OF_env_t *OF_env)
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 @@ static void OF_interpret (OF_env_t *OF_env)
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 @@ static void OF_interpret (OF_env_t *OF_env)
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 @@ static void OF_quiesce (OF_env_t *OF_env)
{
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 --git a/src/pci.c b/src/pci.c
index 10e6eb3..38aad27 100644
--- a/src/pci.c
+++ b/src/pci.c
@@ -99,8 +99,8 @@ struct pci_device_t {
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 @@ struct pci_ops_t {
/* 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 @@ static pci_ops_t uninorth_pci_ops = {
&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 pci_subclass_t undef_subclass[] = {
},
};
+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 pci_dev_t ide_devices[] = {
},
};
-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 @@ static int ide_config_cb (pci_device_t *device)
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 @@ static int ata_config_cb (pci_device_t *device)
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 @@ static pci_subclass_t mass_subclass[] = {
},
{
0x01, "IDE controller", "ide", ide_devices, NULL,
- &ide_config_cb, NULL,
+ NULL, NULL,
},
{
0x02, "Floppy disk controller", NULL, NULL, NULL,
@@ -546,7 +622,7 @@ static pci_subclass_t mass_subclass[] = {
},
{
0x05, "ATA controller", "ata", NULL, NULL,
- &ata_config_cb, NULL,
+ NULL, NULL,
},
{
0x80, "misc mass-storage controller", NULL, NULL, NULL,
@@ -646,7 +722,9 @@ static int vga_config_cb (pci_device_t *device)
/* 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 @@ static pci_dev_t PREP_fake_bridge = {
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 @@ static pci_dev_t hbrg_devices[] = {
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 @@ static pci_dev_t hbrg_devices[] = {
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 int macio_config_cb (pci_device_t *device)
}
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 @@ static inline void pci_update_device (pci_bridge_t *bridge,
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 @@ static inline void pci_update_device (pci_bridge_t *bridge,
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 @@ static pci_u_t *pci_check_device (pci_host_t **hostp, pci_host_t **phost,
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 @@ static pci_u_t *pci_check_device (pci_host_t **hostp, pci_host_t **phost,
/* 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 @@ static pci_u_t *pci_check_device (pci_host_t **hostp, pci_host_t **phost,
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 @@ static pci_u_t *pci_check_device (pci_host_t **hostp, pci_host_t **phost,
/* 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 @@ static pci_u_t *pci_check_device (pci_host_t **hostp, pci_host_t **phost,
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 @@ static pci_u_t *pci_check_device (pci_host_t **hostp, pci_host_t **phost,
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 @@ static int pci_check_host (pci_host_t **hostp,
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 @@ pci_host_t *pci_init (void)
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