From 37cbd0651a08f8afbaaf7e95de88f3a0a6c1baed Mon Sep 17 00:00:00 2001 From: kettenis Date: Fri, 18 Jul 2008 22:05:29 +0000 Subject: [PATCH] Determine the free address space by looking at the "available" property of the PCI host bridge if we're not running on an UltraBook. Fix allocation of bus number such that it works on machines that have OpenBoot 4.x. --- sys/arch/sparc64/sparc64/rbus_machdep.c | 71 +++++++++++++++++++------ 1 file changed, 56 insertions(+), 15 deletions(-) diff --git a/sys/arch/sparc64/sparc64/rbus_machdep.c b/sys/arch/sparc64/sparc64/rbus_machdep.c index 4479e15607f..358367eec9e 100644 --- a/sys/arch/sparc64/sparc64/rbus_machdep.c +++ b/sys/arch/sparc64/sparc64/rbus_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rbus_machdep.c,v 1.2 2007/11/25 00:38:49 kettenis Exp $ */ +/* $OpenBSD: rbus_machdep.c,v 1.3 2008/07/18 22:05:29 kettenis Exp $ */ /* * Copyright (c) 2007 Mark Kettenis @@ -31,11 +31,12 @@ struct rbustag rbus_null; /* - * The PROM doesn't really understand CardBus bridges. So it treats - * the memory and IO window register as ordinary BARs and assigns - * address space to them. We re-use that address space for rbus. - * This is a bit of a hack, but it seems to work and saves us from - * tracking down available address space globally. + * The PROM doesn't really understand PCMCIA/CardBus bridges, and + * leaves them mostly alone. However, on the UltraBook machines, it + * treats the memory and IO window register as ordinary BARs and + * assigns address space to them. We re-use that address space for + * rbus. This is a bit of a hack, but it seems to work and saves us + * from tracking down available address space globally. */ rbus_tag_t @@ -44,17 +45,37 @@ rbus_pccbb_parent_mem(struct device *self, struct pci_attach_args *pa) struct ofw_pci_register addr[5]; int naddr, len, i; int space, reg; + int node = PCITAG_NODE(pa->pa_tag); + char buf[32]; + + /* Check for the UltraBook PCMCIA controller. *// + if (OF_getprop(node, "name", &buf, sizeof(buf)) > 0 && + strcmp(buf, "pcma") == 0) { + len = OF_getprop(PCITAG_NODE(pa->pa_tag), "assigned-addresses", + &addr, sizeof(addr)); + naddr = len / sizeof(struct ofw_pci_register); + + for (i = 0; i < naddr; i++) { + space = addr[i].phys_hi & OFW_PCI_PHYS_HI_SPACEMASK; + if (space != OFW_PCI_PHYS_HI_SPACE_MEM32) + continue; + reg = addr[i].phys_hi & OFW_PCI_PHYS_HI_REGISTERMASK; + if (reg < PCI_CB_MEMBASE0 || reg > PCI_CB_IOLIMIT1) + continue; + + return (rbus_new_root_delegate(pa->pa_memt, + addr[i].phys_lo, addr[i].size_lo, 0)); + } + } - len = OF_getprop(PCITAG_NODE(pa->pa_tag), "assigned-addresses", - &addr, sizeof(addr)); + len = OF_getprop(OF_parent(node), "available", &addr, sizeof(addr)); naddr = len / sizeof(struct ofw_pci_register); for (i = 0; i < naddr; i++) { space = addr[i].phys_hi & OFW_PCI_PHYS_HI_SPACEMASK; if (space != OFW_PCI_PHYS_HI_SPACE_MEM32) continue; - reg = addr[i].phys_hi & OFW_PCI_PHYS_HI_REGISTERMASK; - if (reg < PCI_CB_MEMBASE0 || reg > PCI_CB_IOLIMIT1) + if (addr[i].size_hi == 0 && addr[i].size_lo < 0x10000000) continue; return (rbus_new_root_delegate(pa->pa_memt, @@ -70,17 +91,37 @@ rbus_pccbb_parent_io(struct device *self, struct pci_attach_args *pa) struct ofw_pci_register addr[5]; int naddr, len, i; int space, reg; + int node = PCITAG_NODE(pa->pa_tag); + char buf[32]; + + /* Check for the UltraBook PCMCIA controller. *// + if (OF_getprop(node, "name", &buf, sizeof(buf)) > 0 && + strcmp(buf, "pcma") == 0) { + len = OF_getprop(PCITAG_NODE(pa->pa_tag), "assigned-addresses", + &addr, sizeof(addr)); + naddr = len / sizeof(struct ofw_pci_register); + + for (i = 0; i < naddr; i++) { + space = addr[i].phys_hi & OFW_PCI_PHYS_HI_SPACEMASK; + if (space != OFW_PCI_PHYS_HI_SPACE_IO) + continue; + reg = addr[i].phys_hi & OFW_PCI_PHYS_HI_REGISTERMASK; + if (reg < PCI_CB_MEMBASE0 || reg > PCI_CB_IOLIMIT1) + continue; + + return (rbus_new_root_delegate(pa->pa_iot, + addr[i].phys_lo, addr[i].size_lo, 0)); + } + } - len = OF_getprop(PCITAG_NODE(pa->pa_tag), "assigned-addresses", - &addr, sizeof(addr)); + len = OF_getprop(OF_parent(node), "available", &addr, sizeof(addr)); naddr = len / sizeof(struct ofw_pci_register); for (i = 0; i < naddr; i++) { space = addr[i].phys_hi & OFW_PCI_PHYS_HI_SPACEMASK; if (space != OFW_PCI_PHYS_HI_SPACE_IO) continue; - reg = addr[i].phys_hi & OFW_PCI_PHYS_HI_REGISTERMASK; - if (reg < PCI_CB_MEMBASE0 || reg > PCI_CB_IOLIMIT1) + if (addr[i].size_hi == 0 && addr[i].size_lo < 0x00001000) continue; return (rbus_new_root_delegate(pa->pa_iot, @@ -107,7 +148,7 @@ pccbb_attach_hook(struct device *parent, struct device *self, sizeof(busrange)) != sizeof(busrange)) return; - bus = busrange[1] + 1; + bus = busrange[0] + 1; while (bus < 256 && pc->busnode[bus]) bus++; if (bus == 256) -- 2.20.1