diff options
author | Federico G. Schwindt <fgsch@cvs.openbsd.org> | 2008-07-02 03:00:01 +0000 |
---|---|---|
committer | Federico G. Schwindt <fgsch@cvs.openbsd.org> | 2008-07-02 03:00:01 +0000 |
commit | 2bbeb14e7d0899f31acede7fbb290dbc5480da3f (patch) | |
tree | f39071575f28d23f2b03197ef34e218abb2f48d0 /sys/arch/amd64 | |
parent | 51e6641b4d0c8f6d4ba6f5724a6eda1b34251931 (diff) |
* Dynamically set the rbus start address. from netbsd.
* For amd64, remove pcibios traces.
* make RBUS_IO_START, RBUS_IO_SIZE, RBUS_MIN_START and RBUS_MEM_SIZE
(on i386) configurable via kernel options.
* Remove unneeded headers.
* Some cleanups.
originally reported in pr/5829 and tested by viq <viq at viq dot ath dot cx>.
fixes ian@ laptop too.
kettenis@ and miod@ agrees that although not perfect, this is the right
direction.
Diffstat (limited to 'sys/arch/amd64')
-rw-r--r-- | sys/arch/amd64/amd64/rbus_machdep.c | 144 | ||||
-rw-r--r-- | sys/arch/amd64/include/rbus_machdep.h | 22 |
2 files changed, 93 insertions, 73 deletions
diff --git a/sys/arch/amd64/amd64/rbus_machdep.c b/sys/arch/amd64/amd64/rbus_machdep.c index 0e2ce763bc5..6d072e2f42d 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.6 2007/12/20 13:34:48 kettenis Exp $ */ +/* $OpenBSD: rbus_machdep.c,v 1.7 2008/07/02 03:00:00 fgsch Exp $ */ /* $NetBSD: rbus_machdep.c,v 1.2 1999/10/15 06:43:06 haya Exp $ */ /* @@ -31,104 +31,124 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -/*#include "pcibios.h"*/ - #include <sys/param.h> #include <sys/systm.h> #include <sys/extent.h> #include <uvm/uvm_extern.h> -#include <sys/sysctl.h> - #include <sys/device.h> #include <machine/bus.h> #include <dev/cardbus/rbus.h> -#include <dev/isa/isareg.h> -#include <dev/isa/isavar.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 +#endif + +#ifndef RBUS_MIN_START +#define RBUS_MIN_START 0x40000000 /* 1 GB */ +#endif -/********************************************************************** - * rbus_tag_t rbus_fakeparent_mem(struct pci_attach_args *pa) +/* + * 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. * - * This function makes an rbus tag for memory space. This rbus tag - * shares the all memory region of ex_iomem. - **********************************************************************/ -#define RBUS_MEM_START 0x40000000 -#define RBUS_MEM_SIZE 0x00100000 + * Thus, a general strategy of setting rbus_min_start to the amount of + * memory seems in order. However, the actually 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; + } + + /* 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, min_start; + bus_addr_t start, rbus_min_start; bus_size_t size; - struct extent *ex; + extern struct extent *iomem_ex; + struct extent *ex = iomem_ex; - size = RBUS_MEM_SIZE; - start = min_start = max(RBUS_MEM_START, ptoa(physmem)); -#if NPCIBIOS > 0 - if ((ex = pciaddr_search(PCIADDR_SEARCH_MEM, &start, size)) == NULL) -#endif - { - extern struct extent *iomem_ex; - 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. - * - * if defined PCIBIOS_ADDR_FIXUP, PCI device using - * area which is not recognised by the kernel are - * already reserved. - */ + start = ex->ex_start; - if (start < min_start) { - start = min_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. + */ - size = ex->ex_end - start; - } - - return rbus_new_root_share(pa->pa_memt, ex, start, size, 0); -} + rbus_min_start = rbus_min_start_hint(); + if (start < rbus_min_start) + start = rbus_min_start; + size = ex->ex_end - start; -/********************************************************************** - * rbus_tag_t rbus_pccbb_parent_io(struct pci_attach_args *pa) - **********************************************************************/ -#define RBUS_IO_START 0xa000 -#define RBUS_IO_SIZE 0x1000 + return (rbus_new_root_share(pa->pa_memt, ex, start, size, 0)); +} rbus_tag_t rbus_pccbb_parent_io(struct device *self, struct pci_attach_args *pa) { - struct extent *ex; bus_addr_t start; bus_size_t size; + extern struct extent *ioport_ex; + struct extent *ex = ioport_ex; - size = RBUS_IO_SIZE; + size = RBUS_IO_SIZE; start = RBUS_IO_START; -#if NPCIBIOS > 0 - if ((ex = pciaddr_search(PCIADDR_SEARCH_IO, &start, size)) == NULL) -#endif - { - extern struct extent *ioport_ex; - ex = ioport_ex; - } - return rbus_new_root_share(pa->pa_iot, ex, start, size, 0); + return (rbus_new_root_share(pa->pa_iot, ex, start, size, 0)); } void pccbb_attach_hook(struct device *parent, struct device *self, struct pci_attach_args *pa) { -} +} diff --git a/sys/arch/amd64/include/rbus_machdep.h b/sys/arch/amd64/include/rbus_machdep.h index 0ab405f539c..f61370b904a 100644 --- a/sys/arch/amd64/include/rbus_machdep.h +++ b/sys/arch/amd64/include/rbus_machdep.h @@ -1,4 +1,4 @@ -/* $OpenBSD: rbus_machdep.h,v 1.3 2007/12/20 13:34:48 kettenis Exp $ */ +/* $OpenBSD: rbus_machdep.h,v 1.4 2008/07/02 03:00:00 fgsch Exp $ */ /* $NetBSD: rbus_machdep.h,v 1.2 1999/10/15 06:43:05 haya Exp $ */ /* @@ -31,9 +31,8 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - -#if !defined _ARCH_AMD64_AMD64_RBUS_MACHDEP_H_ -#define _ARCH_AMD64_AMD64_RBUS_MACHDEP_H_ +#ifndef _AMD64_RBUS_MACHDEP_H_ +#define _AMD64_RBUS_MACHDEP_H_ struct pci_attach_args; /* XXX */ @@ -43,13 +42,14 @@ struct pci_attach_args; /* XXX */ #define md_space_unmap(bt, bsh, size, adrp) \ _bus_space_unmap((bt), (bsh), (size), (adrp)) +rbus_tag_t rbus_pccbb_parent_io(struct device *, + struct pci_attach_args *); +rbus_tag_t rbus_pccbb_parent_mem(struct device *, + struct pci_attach_args *); -rbus_tag_t rbus_pccbb_parent_io(struct device *self, - struct pci_attach_args *pa); -rbus_tag_t rbus_pccbb_parent_mem(struct device *self, - struct pci_attach_args *pa); +bus_addr_t rbus_min_start_hint(void); -void pccbb_attach_hook(struct device *, struct device *, - struct pci_attach_args *); +void pccbb_attach_hook(struct device *, struct device *, + struct pci_attach_args *); -#endif /* _ARCH_AMD64_AMD64_RBUS_MACHDEP_H_ */ +#endif /* _AMD64_RBUS_MACHDEP_H_ */ |