diff options
Diffstat (limited to 'sys/arch/amd64')
-rw-r--r-- | sys/arch/amd64/amd64/rbus_machdep.c | 110 |
1 files changed, 29 insertions, 81 deletions
diff --git a/sys/arch/amd64/amd64/rbus_machdep.c b/sys/arch/amd64/amd64/rbus_machdep.c index f5cd151c092..f4a2ebdf53d 100644 --- a/sys/arch/amd64/amd64/rbus_machdep.c +++ b/sys/arch/amd64/amd64/rbus_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rbus_machdep.c,v 1.8 2008/07/07 23:41:58 brad Exp $ */ +/* $OpenBSD: rbus_machdep.c,v 1.9 2009/04/28 18:37:13 kettenis Exp $ */ /* $NetBSD: rbus_machdep.c,v 1.2 1999/10/15 06:43:06 haya Exp $ */ /* @@ -33,101 +33,39 @@ #include <sys/param.h> #include <sys/systm.h> +#include <sys/device.h> #include <sys/extent.h> #include <uvm/uvm_extern.h> -#include <sys/device.h> - #include <machine/bus.h> #include <dev/cardbus/rbus.h> #include <dev/pci/pcivar.h> -#ifndef RBUS_IO_START -#define RBUS_IO_START 0xa000 -#endif -#ifndef RBUS_IO_SIZE -#define RBUS_IO_SIZE 0x1000 +#ifndef RBUS_MEM_START +/* Avoid the ISA hole and everything below it. */ +#define RBUS_MEM_START 0x00100000 #endif -#ifndef RBUS_MIN_START -#define RBUS_MIN_START 0x40000000 /* 1 GB */ +#ifndef RBUS_IO_START +/* Try to avoid onboard legacy devices; just a guess. */ +#define RBUS_IO_START 0xa000 #endif -/* - * Dynamically set the start address for rbus. This must be called - * before rbus is initialized. The start address should be determined - * by the amount of installed memory. Generally 1 GB has been found - * to be a good value, but it fails on some Thinkpads (e.g. 2645-4AU), - * for which 0.5 GB is a good value. It also fails on (at least) - * Thinkpads with 2GB of RAM, for which 2 GB is a good value. - * - * Thus, a general strategy of setting rbus_min_start to the amount of - * memory seems in order. However, the actual amount of memory is - * generally slightly more than the amount found, e.g. 1014MB vs 1024, - * or 2046 vs 2048. - */ -bus_addr_t -rbus_min_start_hint(void) -{ - bus_addr_t rbus_min_start = RBUS_MIN_START; - size_t ram = ptoa(physmem); - - if (ram <= 192 * 1024 * 1024UL) { - /* - * <= 192 MB, so try 0.5 GB. This will work on - * Thinkpad 600E (2645-4AU), which fails at 1 GB, and - * on some other older machines that may have trouble - * with addresses needing more than 20 bits. - */ - rbus_min_start = 512 * 1024 * 1024UL; - } - - if (ram >= 1024 * 1024 * 1024UL) { - /* - * > 1 GB, so try 2 GB. - */ - rbus_min_start = 2 * 1024 * 1024 * 1024UL; - } +struct rbustag rbus_null; - /* Not tested in > 2 GB case. */ - if (ram > 2 * 1024 * 1024 * 1024UL) { - /* - * > 2 GB, so try 3 GB. - */ - rbus_min_start = 3 * 1024 * 1024 * 1024UL; - } - - return (rbus_min_start); -} - -/* - * This function makes an rbus tag for memory space. This rbus tag - * shares the all memory region of ex_iomem. - */ rbus_tag_t rbus_pccbb_parent_mem(struct device *self, struct pci_attach_args *pa) { - bus_addr_t start, rbus_min_start; + struct extent *ex = pa->pa_memex; + bus_addr_t start; bus_size_t size; - extern struct extent *iomem_ex; - struct extent *ex = iomem_ex; - start = ex->ex_start; - - /* XXX: unfortunately, iomem_ex cannot be used for the - * dynamic bus_space allocation. There are some - * hidden memory (or some obstacles which do not - * recognised by the kernel) in the region governed by - * iomem_ex. So I decide to use only very high - * address region. - */ - - rbus_min_start = rbus_min_start_hint(); - if (start < rbus_min_start) - start = rbus_min_start; + if (ex == NULL) + return &rbus_null; + start = RBUS_MEM_START; size = ex->ex_end - start; return (rbus_new_root_share(pa->pa_memt, ex, start, size, 0)); @@ -136,13 +74,23 @@ rbus_pccbb_parent_mem(struct device *self, struct pci_attach_args *pa) rbus_tag_t rbus_pccbb_parent_io(struct device *self, struct pci_attach_args *pa) { + struct extent *ex = pa->pa_ioex; bus_addr_t start; bus_size_t size; - extern struct extent *ioport_ex; - struct extent *ex = ioport_ex; - size = RBUS_IO_SIZE; - start = RBUS_IO_START; + if (ex == NULL) + return &rbus_null; + + start = ex->ex_start; + if (pa->pa_bridgetag == NULL) { + /* + * If we're not behind a PCI-PCI bridge, we must be on + * the root bus. To avoid conflicts with onboard + * legacy devices, we only make a subregion available. + */ + start = max(start, RBUS_IO_START); + } + size = ex->ex_end - start; return (rbus_new_root_share(pa->pa_iot, ex, start, size, 0)); } @@ -151,4 +99,4 @@ void pccbb_attach_hook(struct device *parent, struct device *self, struct pci_attach_args *pa) { -} +} |