summaryrefslogtreecommitdiffstats
path: root/freebsd/sys/mips
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2013-11-06 16:20:21 +0100
committerSebastian Huber <sebastian.huber@embedded-brains.de>2013-11-11 10:08:08 +0100
commit66659ff1ad6831b0ea7425fa6ecd8a8687523658 (patch)
tree48e22b475fa8854128e0861a33fed6f78c8094b5 /freebsd/sys/mips
parentDefine __GLOBL1() and __GLOBL() (diff)
downloadrtems-libbsd-66659ff1ad6831b0ea7425fa6ecd8a8687523658.tar.bz2
Update to FreeBSD 9.2
Diffstat (limited to 'freebsd/sys/mips')
-rw-r--r--freebsd/sys/mips/include/machine/cpufunc.h140
-rw-r--r--freebsd/sys/mips/include/machine/cpuregs.h13
-rw-r--r--freebsd/sys/mips/include/machine/in_cksum.h4
-rw-r--r--freebsd/sys/mips/include/machine/pci_cfgreg.h8
-rw-r--r--freebsd/sys/mips/mips/legacy.c20
-rw-r--r--freebsd/sys/mips/pci/pci_bus.c147
6 files changed, 210 insertions, 122 deletions
diff --git a/freebsd/sys/mips/include/machine/cpufunc.h b/freebsd/sys/mips/include/machine/cpufunc.h
index d32e4920..bfabe90b 100644
--- a/freebsd/sys/mips/include/machine/cpufunc.h
+++ b/freebsd/sys/mips/include/machine/cpufunc.h
@@ -69,6 +69,9 @@
static __inline void
mips_barrier(void)
{
+#ifdef CPU_CNMIPS
+ __asm __volatile("" : : : "memory");
+#else
__asm __volatile (".set noreorder\n\t"
"nop\n\t"
"nop\n\t"
@@ -80,6 +83,7 @@ mips_barrier(void)
"nop\n\t"
".set reorder\n\t"
: : : "memory");
+#endif
}
static __inline void
@@ -91,8 +95,15 @@ mips_cp0_sync(void)
static __inline void
mips_wbflush(void)
{
+#if defined(CPU_CNMIPS)
+ __asm __volatile (".set noreorder\n\t"
+ "syncw\n\t"
+ ".set reorder\n"
+ : : : "memory");
+#else
__asm __volatile ("sync" : : : "memory");
mips_barrier();
+#endif
}
static __inline void
@@ -108,8 +119,13 @@ mips_write_membar(void)
}
#ifdef _KERNEL
+/*
+ * XXX
+ * It would be nice to add variants that read/write register_t, to avoid some
+ * ABI checks.
+ */
#if defined(__mips_n32) || defined(__mips_n64)
-#define MIPS_RDRW64_COP0(n,r) \
+#define MIPS_RW64_COP0(n,r) \
static __inline uint64_t \
mips_rd_ ## n (void) \
{ \
@@ -131,18 +147,49 @@ mips_wr_ ## n (uint64_t a0) \
mips_barrier(); \
} struct __hack
+#define MIPS_RW64_COP0_SEL(n,r,s) \
+static __inline uint64_t \
+mips_rd_ ## n(void) \
+{ \
+ int v0; \
+ __asm __volatile ("dmfc0 %[v0], $"__XSTRING(r)", "__XSTRING(s)";" \
+ : [v0] "=&r"(v0)); \
+ mips_barrier(); \
+ return (v0); \
+} \
+static __inline void \
+mips_wr_ ## n(uint64_t a0) \
+{ \
+ __asm __volatile ("dmtc0 %[a0], $"__XSTRING(r)", "__XSTRING(s)";" \
+ __XSTRING(COP0_SYNC)";" \
+ : \
+ : [a0] "r"(a0)); \
+ mips_barrier(); \
+} struct __hack
+
#if defined(__mips_n64)
-MIPS_RDRW64_COP0(entrylo0, MIPS_COP_0_TLB_LO0);
-MIPS_RDRW64_COP0(entrylo1, MIPS_COP_0_TLB_LO1);
-MIPS_RDRW64_COP0(entryhi, MIPS_COP_0_TLB_HI);
-MIPS_RDRW64_COP0(pagemask, MIPS_COP_0_TLB_PG_MASK);
+MIPS_RW64_COP0(excpc, MIPS_COP_0_EXC_PC);
+MIPS_RW64_COP0(entryhi, MIPS_COP_0_TLB_HI);
+MIPS_RW64_COP0(pagemask, MIPS_COP_0_TLB_PG_MASK);
+#ifdef CPU_CNMIPS
+MIPS_RW64_COP0_SEL(cvmcount, MIPS_COP_0_COUNT, 6);
+MIPS_RW64_COP0_SEL(cvmctl, MIPS_COP_0_COUNT, 7);
+MIPS_RW64_COP0_SEL(cvmmemctl, MIPS_COP_0_COMPARE, 7);
+MIPS_RW64_COP0_SEL(icache_err, MIPS_COP_0_CACHE_ERR, 0);
+MIPS_RW64_COP0_SEL(dcache_err, MIPS_COP_0_CACHE_ERR, 1);
#endif
-MIPS_RDRW64_COP0(xcontext, MIPS_COP_0_TLB_XCONTEXT);
+#endif
+#if defined(__mips_n64) || defined(__mips_n32) /* PHYSADDR_64_BIT */
+MIPS_RW64_COP0(entrylo0, MIPS_COP_0_TLB_LO0);
+MIPS_RW64_COP0(entrylo1, MIPS_COP_0_TLB_LO1);
+#endif
+MIPS_RW64_COP0(xcontext, MIPS_COP_0_TLB_XCONTEXT);
-#undef MIPS_RDRW64_COP0
+#undef MIPS_RW64_COP0
+#undef MIPS_RW64_COP0_SEL
#endif
-#define MIPS_RDRW32_COP0(n,r) \
+#define MIPS_RW32_COP0(n,r) \
static __inline uint32_t \
mips_rd_ ## n (void) \
{ \
@@ -164,7 +211,7 @@ mips_wr_ ## n (uint32_t a0) \
mips_barrier(); \
} struct __hack
-#define MIPS_RDRW32_COP0_SEL(n,r,s) \
+#define MIPS_RW32_COP0_SEL(n,r,s) \
static __inline uint32_t \
mips_rd_ ## n(void) \
{ \
@@ -199,42 +246,55 @@ static __inline void mips_sync_icache (void)
}
#endif
-MIPS_RDRW32_COP0(compare, MIPS_COP_0_COMPARE);
-MIPS_RDRW32_COP0(config, MIPS_COP_0_CONFIG);
-MIPS_RDRW32_COP0_SEL(config1, MIPS_COP_0_CONFIG, 1);
-MIPS_RDRW32_COP0_SEL(config2, MIPS_COP_0_CONFIG, 2);
-MIPS_RDRW32_COP0_SEL(config3, MIPS_COP_0_CONFIG, 3);
-MIPS_RDRW32_COP0(count, MIPS_COP_0_COUNT);
-MIPS_RDRW32_COP0(index, MIPS_COP_0_TLB_INDEX);
-MIPS_RDRW32_COP0(wired, MIPS_COP_0_TLB_WIRED);
-MIPS_RDRW32_COP0(cause, MIPS_COP_0_CAUSE);
-MIPS_RDRW32_COP0(status, MIPS_COP_0_STATUS);
+MIPS_RW32_COP0(compare, MIPS_COP_0_COMPARE);
+MIPS_RW32_COP0(config, MIPS_COP_0_CONFIG);
+MIPS_RW32_COP0_SEL(config1, MIPS_COP_0_CONFIG, 1);
+MIPS_RW32_COP0_SEL(config2, MIPS_COP_0_CONFIG, 2);
+MIPS_RW32_COP0_SEL(config3, MIPS_COP_0_CONFIG, 3);
+#ifdef CPU_CNMIPS
+MIPS_RW32_COP0_SEL(config4, MIPS_COP_0_CONFIG, 4);
+#endif
+#ifdef CPU_NLM
+MIPS_RW32_COP0_SEL(config6, MIPS_COP_0_CONFIG, 6);
+MIPS_RW32_COP0_SEL(config7, MIPS_COP_0_CONFIG, 7);
+#endif
+MIPS_RW32_COP0(count, MIPS_COP_0_COUNT);
+MIPS_RW32_COP0(index, MIPS_COP_0_TLB_INDEX);
+MIPS_RW32_COP0(wired, MIPS_COP_0_TLB_WIRED);
+MIPS_RW32_COP0(cause, MIPS_COP_0_CAUSE);
+#if !defined(__mips_n64)
+MIPS_RW32_COP0(excpc, MIPS_COP_0_EXC_PC);
+#endif
+MIPS_RW32_COP0(status, MIPS_COP_0_STATUS);
/* XXX: Some of these registers are specific to MIPS32. */
#if !defined(__mips_n64)
-MIPS_RDRW32_COP0(entrylo0, MIPS_COP_0_TLB_LO0);
-MIPS_RDRW32_COP0(entrylo1, MIPS_COP_0_TLB_LO1);
-MIPS_RDRW32_COP0(entryhi, MIPS_COP_0_TLB_HI);
-MIPS_RDRW32_COP0(pagemask, MIPS_COP_0_TLB_PG_MASK);
+MIPS_RW32_COP0(entryhi, MIPS_COP_0_TLB_HI);
+MIPS_RW32_COP0(pagemask, MIPS_COP_0_TLB_PG_MASK);
+#endif
+#if !defined(__mips_n64) && !defined(__mips_n32) /* !PHYSADDR_64_BIT */
+MIPS_RW32_COP0(entrylo0, MIPS_COP_0_TLB_LO0);
+MIPS_RW32_COP0(entrylo1, MIPS_COP_0_TLB_LO1);
#endif
-MIPS_RDRW32_COP0(prid, MIPS_COP_0_PRID);
+MIPS_RW32_COP0(prid, MIPS_COP_0_PRID);
/* XXX 64-bit? */
-MIPS_RDRW32_COP0_SEL(ebase, MIPS_COP_0_PRID, 1);
-MIPS_RDRW32_COP0(watchlo, MIPS_COP_0_WATCH_LO);
-MIPS_RDRW32_COP0_SEL(watchlo1, MIPS_COP_0_WATCH_LO, 1);
-MIPS_RDRW32_COP0_SEL(watchlo2, MIPS_COP_0_WATCH_LO, 2);
-MIPS_RDRW32_COP0_SEL(watchlo3, MIPS_COP_0_WATCH_LO, 3);
-MIPS_RDRW32_COP0(watchhi, MIPS_COP_0_WATCH_HI);
-MIPS_RDRW32_COP0_SEL(watchhi1, MIPS_COP_0_WATCH_HI, 1);
-MIPS_RDRW32_COP0_SEL(watchhi2, MIPS_COP_0_WATCH_HI, 2);
-MIPS_RDRW32_COP0_SEL(watchhi3, MIPS_COP_0_WATCH_HI, 3);
-
-MIPS_RDRW32_COP0_SEL(perfcnt0, MIPS_COP_0_PERFCNT, 0);
-MIPS_RDRW32_COP0_SEL(perfcnt1, MIPS_COP_0_PERFCNT, 1);
-MIPS_RDRW32_COP0_SEL(perfcnt2, MIPS_COP_0_PERFCNT, 2);
-MIPS_RDRW32_COP0_SEL(perfcnt3, MIPS_COP_0_PERFCNT, 3);
-
-#undef MIPS_RDRW32_COP0
+MIPS_RW32_COP0_SEL(ebase, MIPS_COP_0_PRID, 1);
+MIPS_RW32_COP0(watchlo, MIPS_COP_0_WATCH_LO);
+MIPS_RW32_COP0_SEL(watchlo1, MIPS_COP_0_WATCH_LO, 1);
+MIPS_RW32_COP0_SEL(watchlo2, MIPS_COP_0_WATCH_LO, 2);
+MIPS_RW32_COP0_SEL(watchlo3, MIPS_COP_0_WATCH_LO, 3);
+MIPS_RW32_COP0(watchhi, MIPS_COP_0_WATCH_HI);
+MIPS_RW32_COP0_SEL(watchhi1, MIPS_COP_0_WATCH_HI, 1);
+MIPS_RW32_COP0_SEL(watchhi2, MIPS_COP_0_WATCH_HI, 2);
+MIPS_RW32_COP0_SEL(watchhi3, MIPS_COP_0_WATCH_HI, 3);
+
+MIPS_RW32_COP0_SEL(perfcnt0, MIPS_COP_0_PERFCNT, 0);
+MIPS_RW32_COP0_SEL(perfcnt1, MIPS_COP_0_PERFCNT, 1);
+MIPS_RW32_COP0_SEL(perfcnt2, MIPS_COP_0_PERFCNT, 2);
+MIPS_RW32_COP0_SEL(perfcnt3, MIPS_COP_0_PERFCNT, 3);
+
+#undef MIPS_RW32_COP0
+#undef MIPS_RW32_COP0_SEL
static __inline register_t
intr_disable(void)
diff --git a/freebsd/sys/mips/include/machine/cpuregs.h b/freebsd/sys/mips/include/machine/cpuregs.h
index 456c545c..01d710d2 100644
--- a/freebsd/sys/mips/include/machine/cpuregs.h
+++ b/freebsd/sys/mips/include/machine/cpuregs.h
@@ -198,12 +198,10 @@
#endif
/* CPU dependent mtc0 hazard hook */
-#ifdef CPU_CNMIPS
-#define COP0_SYNC nop; nop; nop; nop; nop;
+#if defined(CPU_CNMIPS) || defined(CPU_RMI)
+#define COP0_SYNC
#elif defined(CPU_SB1)
#define COP0_SYNC ssnop; ssnop; ssnop; ssnop; ssnop; ssnop; ssnop; ssnop; ssnop
-#elif defined(CPU_RMI)
-#define COP0_SYNC
#else
/*
* Pick a reasonable default based on the "typical" spacing described in the
@@ -571,6 +569,7 @@
* 16/1 MIPS_COP_0_CONFIG1 ..33 Configuration register 1.
* 16/2 MIPS_COP_0_CONFIG2 ..33 Configuration register 2.
* 16/3 MIPS_COP_0_CONFIG3 ..33 Configuration register 3.
+ * 16/4 MIPS_COP_0_CONFIG4 ..33 Configuration register 4.
* 17 MIPS_COP_0_LLADDR .336 Load Linked Address.
* 18 MIPS_COP_0_WATCH_LO .336 WatchLo register.
* 19 MIPS_COP_0_WATCH_HI .333 WatchHi register.
@@ -656,7 +655,7 @@
#define MIPS_CONFIG1_TLBSZ_MASK 0x7E000000 /* bits 30..25 # tlb entries minus one */
#define MIPS_CONFIG1_TLBSZ_SHIFT 25
-#define MIPS_MAX_TLB_ENTRIES 64
+#define MIPS_MAX_TLB_ENTRIES 128
#define MIPS_CONFIG1_IS_MASK 0x01C00000 /* bits 24..22 icache sets per way */
#define MIPS_CONFIG1_IS_SHIFT 22
@@ -679,6 +678,10 @@
#define MIPS_CONFIG1_EP 0x00000002 /* EJTAG implemented */
#define MIPS_CONFIG1_FP 0x00000001 /* FPU implemented */
+#define MIPS_CONFIG4_MMUSIZEEXT 0x000000FF /* bits 7.. 0 MMU Size Extension */
+#define MIPS_CONFIG4_MMUEXTDEF 0x0000C000 /* bits 15.14 MMU Extension Definition */
+#define MIPS_CONFIG4_MMUEXTDEF_MMUSIZEEXT 0x00004000 /* This values denotes CONFIG4 bits */
+
/*
* Values for the code field in a break instruction.
*/
diff --git a/freebsd/sys/mips/include/machine/in_cksum.h b/freebsd/sys/mips/include/machine/in_cksum.h
index 37d88e2e..633efa1f 100644
--- a/freebsd/sys/mips/include/machine/in_cksum.h
+++ b/freebsd/sys/mips/include/machine/in_cksum.h
@@ -40,6 +40,7 @@
#define in_cksum(m, len) in_cksum_skip(m, len, 0)
+#if defined(IPVERSION) && (IPVERSION == 4)
/*
* It it useful to have an Internet checksum routine which is inlineable
* and optimized specifically for the task of computing IP header checksums
@@ -66,9 +67,12 @@ in_cksum_update(struct ip *ip)
} while(0)
#endif
+#endif
#ifdef _KERNEL
+#if defined(IPVERSION) && (IPVERSION == 4)
u_int in_cksum_hdr(const struct ip *ip);
+#endif
u_short in_addword(u_short sum, u_short b);
u_short in_pseudo(u_int sum, u_int b, u_int c);
u_short in_cksum_skip(struct mbuf *m, int len, int skip);
diff --git a/freebsd/sys/mips/include/machine/pci_cfgreg.h b/freebsd/sys/mips/include/machine/pci_cfgreg.h
index bc72418d..ea5e3198 100644
--- a/freebsd/sys/mips/include/machine/pci_cfgreg.h
+++ b/freebsd/sys/mips/include/machine/pci_cfgreg.h
@@ -27,6 +27,9 @@
*
*/
+#ifndef __X86_PCI_CFGREG_H__
+#define __X86_PCI_CFGREG_H__
+
#define CONF1_ADDR_PORT 0x0cf8
#define CONF1_DATA_PORT 0x0cfc
@@ -43,10 +46,15 @@
#define CONF2_ENABLE_CHK 0x0e
#define CONF2_ENABLE_RES 0x0e
+u_long hostb_alloc_start(int type, u_long start, u_long end, u_long count);
int pcie_cfgregopen(uint64_t base, uint8_t minbus, uint8_t maxbus);
int pci_cfgregopen(void);
u_int32_t pci_cfgregread(int bus, int slot, int func, int reg, int bytes);
void pci_cfgregwrite(int bus, int slot, int func, int reg, u_int32_t data, int bytes);
+#ifdef __HAVE_PIR
void pci_pir_open(void);
int pci_pir_probe(int bus, int require_parse);
int pci_pir_route_interrupt(int bus, int device, int func, int pin);
+#endif
+
+#endif /* !__X86_PCI_CFGREG_H__ */
diff --git a/freebsd/sys/mips/mips/legacy.c b/freebsd/sys/mips/mips/legacy.c
index c81ccc5e..3a2fab02 100644
--- a/freebsd/sys/mips/mips/legacy.c
+++ b/freebsd/sys/mips/mips/legacy.c
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
#include <i386/bios/mca_machdep.h>
#endif
+#include <machine/clock.h>
#include <machine/legacyvar.h>
#include <machine/resource.h>
@@ -351,9 +352,22 @@ cpu_read_ivar(device_t dev, device_t child, int index, uintptr_t *result)
{
struct cpu_device *cpdev;
- if (index != CPU_IVAR_PCPU)
+ switch (index) {
+ case CPU_IVAR_PCPU:
+ cpdev = device_get_ivars(child);
+ *result = (uintptr_t)cpdev->cd_pcpu;
+ break;
+#ifndef __rtems__
+ case CPU_IVAR_NOMINAL_MHZ:
+ if (tsc_is_invariant) {
+ *result = (uintptr_t)(atomic_load_acq_64(&tsc_freq) /
+ 1000000);
+ break;
+ }
+ /* FALLTHROUGH */
+#endif /* __rtems__ */
+ default:
return (ENOENT);
- cpdev = device_get_ivars(child);
- *result = (uintptr_t)cpdev->cd_pcpu;
+ }
return (0);
}
diff --git a/freebsd/sys/mips/pci/pci_bus.c b/freebsd/sys/mips/pci/pci_bus.c
index ad0342ec..cfab0049 100644
--- a/freebsd/sys/mips/pci/pci_bus.c
+++ b/freebsd/sys/mips/pci/pci_bus.c
@@ -53,13 +53,6 @@ __FBSDID("$FreeBSD$");
#include <rtems/bsd/local/pcib_if.h>
-#ifndef __rtems__
-static int pcibios_pcib_route_interrupt(device_t pcib, device_t dev,
- int pin);
-#else /* __rtems__ */
-int pcibios_pcib_route_interrupt(device_t pcib, device_t dev, int pin);
-#endif /* __rtems__ */
-
int
legacy_pcib_maxslots(device_t dev)
{
@@ -68,7 +61,7 @@ legacy_pcib_maxslots(device_t dev)
/* read configuration space register */
-u_int32_t
+uint32_t
legacy_pcib_read_config(device_t dev, u_int bus, u_int slot, u_int func,
u_int reg, int bytes)
{
@@ -79,11 +72,26 @@ legacy_pcib_read_config(device_t dev, u_int bus, u_int slot, u_int func,
void
legacy_pcib_write_config(device_t dev, u_int bus, u_int slot, u_int func,
- u_int reg, u_int32_t data, int bytes)
+ u_int reg, uint32_t data, int bytes)
{
pci_cfgregwrite(bus, slot, func, reg, data, bytes);
}
+/* route interrupt */
+
+static int
+legacy_pcib_route_interrupt(device_t pcib, device_t dev, int pin)
+{
+
+#ifdef __HAVE_PIR
+ return (pci_pir_route_interrupt(pci_get_bus(dev), pci_get_slot(dev),
+ pci_get_function(dev), pin));
+#else
+ /* No routing possible */
+ return (PCI_INVALID_IRQ);
+#endif
+}
+
/* Pass MSI requests up to the nexus. */
static int
@@ -135,6 +143,7 @@ legacy_pcib_is_host_bridge(int bus, int slot, int func,
uint32_t id, uint8_t class, uint8_t subclass,
uint8_t *busnum)
{
+#ifdef __i386__
const char *s = NULL;
static uint8_t pxb[4]; /* hack for 450nx */
@@ -352,6 +361,14 @@ legacy_pcib_is_host_bridge(int bus, int slot, int func,
}
return s;
+#else
+ const char *s = NULL;
+
+ *busnum = 0;
+ if (class == PCIC_BRIDGE && subclass == PCIS_BRIDGE_HOST)
+ s = "Host to PCI bridge";
+ return s;
+#endif
}
/*
@@ -362,7 +379,7 @@ static void
legacy_pcib_identify(driver_t *driver, device_t parent)
{
int bus, slot, func;
- u_int8_t hdrtype;
+ uint8_t hdrtype;
int found = 0;
int pcifunchigh;
int found824xx = 0;
@@ -405,8 +422,8 @@ legacy_pcib_identify(driver_t *driver, device_t parent)
/*
* Read the IDs and class from the device.
*/
- u_int32_t id;
- u_int8_t class, subclass, busnum;
+ uint32_t id;
+ uint8_t class, subclass, busnum;
const char *s;
device_t *devs;
int ndevs, i;
@@ -493,21 +510,23 @@ legacy_pcib_probe(device_t dev)
static int
legacy_pcib_attach(device_t dev)
{
+#ifdef __HAVE_PIR
device_t pir;
+#endif
int bus;
+ bus = pcib_get_bus(dev);
+#ifdef __HAVE_PIR
/*
* Look for a PCI BIOS interrupt routing table as that will be
* our method of routing interrupts if we have one.
*/
- bus = pcib_get_bus(dev);
-#ifndef __rtems__
if (pci_pir_probe(bus, 0)) {
pir = BUS_ADD_CHILD(device_get_parent(dev), 0, "pir", 0);
if (pir != NULL)
device_probe_and_attach(pir);
}
-#endif /* __rtems__ */
+#endif
device_add_child(dev, "pci", bus);
return bus_generic_attach(dev);
}
@@ -543,35 +562,45 @@ legacy_pcib_write_ivar(device_t dev, device_t child, int which,
return ENOENT;
}
+/*
+ * Helper routine for x86 Host-PCI bridge driver resource allocation.
+ * This is used to adjust the start address of wildcard allocation
+ * requests to avoid low addresses that are known to be problematic.
+ *
+ * If no memory preference is given, use upper 32MB slot most BIOSes
+ * use for their memory window. This is typically only used on older
+ * laptops that don't have PCI busses behind a PCI bridge, so assuming
+ * > 32MB is likely OK.
+ *
+ * However, this can cause problems for other chipsets, so we make
+ * this tunable by hw.pci.host_mem_start.
+ */
SYSCTL_DECL(_hw_pci);
-static unsigned long legacy_host_mem_start = 0x80000000;
-TUNABLE_ULONG("hw.pci.host_mem_start", &legacy_host_mem_start);
-SYSCTL_ULONG(_hw_pci, OID_AUTO, host_mem_start, CTLFLAG_RDTUN,
- &legacy_host_mem_start, 0x80000000,
- "Limit the host bridge memory to being above this address. Must be\n\
-set at boot via a tunable.");
+static unsigned long host_mem_start = 0x80000000;
+TUNABLE_ULONG("hw.pci.host_mem_start", &host_mem_start);
+SYSCTL_ULONG(_hw_pci, OID_AUTO, host_mem_start, CTLFLAG_RDTUN, &host_mem_start,
+ 0, "Limit the host bridge memory to being above this address.");
+
+u_long
+hostb_alloc_start(int type, u_long start, u_long end, u_long count)
+{
+
+ if (start + count - 1 != end) {
+ if (type == SYS_RES_MEMORY && start < host_mem_start)
+ start = host_mem_start;
+ if (type == SYS_RES_IOPORT && start < 0x1000)
+ start = 0x1000;
+ }
+ return (start);
+}
struct resource *
legacy_pcib_alloc_resource(device_t dev, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
- /*
- * If no memory preference is given, use upper 32MB slot most
- * bioses use for their memory window. Typically other bridges
- * before us get in the way to assert their preferences on memory.
- * Hardcoding like this sucks, so a more MD/MI way needs to be
- * found to do it. This is typically only used on older laptops
- * that don't have pci busses behind pci bridge, so assuming > 32MB
- * is liekly OK.
- *
- * However, this can cause problems for other chipsets, so we make
- * this tunable by hw.pci.host_mem_start.
- */
- if (type == SYS_RES_MEMORY && start == 0UL && end == ~0UL)
- start = legacy_host_mem_start;
- if (type == SYS_RES_IOPORT && start == 0UL && end == ~0UL)
- start = 0x1000;
+
+ start = hostb_alloc_start(type, start, end, count);
return (bus_generic_alloc_resource(dev, child, type, rid, start, end,
count, flags));
}
@@ -600,7 +629,7 @@ static device_method_t legacy_pcib_methods[] = {
DEVMETHOD(pcib_maxslots, legacy_pcib_maxslots),
DEVMETHOD(pcib_read_config, legacy_pcib_read_config),
DEVMETHOD(pcib_write_config, legacy_pcib_write_config),
- DEVMETHOD(pcib_route_interrupt, pcibios_pcib_route_interrupt),
+ DEVMETHOD(pcib_route_interrupt, legacy_pcib_route_interrupt),
DEVMETHOD(pcib_alloc_msi, legacy_pcib_alloc_msi),
DEVMETHOD(pcib_release_msi, pcib_release_msi),
DEVMETHOD(pcib_alloc_msix, legacy_pcib_alloc_msix),
@@ -616,7 +645,6 @@ DEFINE_CLASS_0(pcib, legacy_pcib_driver, legacy_pcib_methods, 1);
DRIVER_MODULE(pcib, legacy, legacy_pcib_driver, hostb_devclass, 0, 0);
-#ifndef __rtems__
/*
* Install placeholder to claim the resources owned by the
* PCI bus interface. This could be used to extract the
@@ -665,7 +693,7 @@ static devclass_t pcibus_pnp_devclass;
DEFINE_CLASS_0(pcibus_pnp, pcibus_pnp_driver, pcibus_pnp_methods, 1);
DRIVER_MODULE(pcibus_pnp, isa, pcibus_pnp_driver, pcibus_pnp_devclass, 0, 0);
-
+#ifdef __HAVE_PIR
/*
* Provide a PCI-PCI bridge driver for PCI busses behind PCI-PCI bridges
* that appear in the PCIBIOS Interrupt Routing Table to use the routing
@@ -676,39 +704,17 @@ static int pcibios_pcib_probe(device_t bus);
static device_method_t pcibios_pcib_pci_methods[] = {
/* Device interface */
DEVMETHOD(device_probe, pcibios_pcib_probe),
- DEVMETHOD(device_attach, pcib_attach),
- DEVMETHOD(device_shutdown, bus_generic_shutdown),
- DEVMETHOD(device_suspend, bus_generic_suspend),
- DEVMETHOD(device_resume, bus_generic_resume),
-
- /* Bus interface */
- DEVMETHOD(bus_read_ivar, pcib_read_ivar),
- DEVMETHOD(bus_write_ivar, pcib_write_ivar),
- DEVMETHOD(bus_alloc_resource, pcib_alloc_resource),
- DEVMETHOD(bus_release_resource, bus_generic_release_resource),
- DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
- DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
- DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
- DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
/* pcib interface */
- DEVMETHOD(pcib_maxslots, pcib_maxslots),
- DEVMETHOD(pcib_read_config, pcib_read_config),
- DEVMETHOD(pcib_write_config, pcib_write_config),
- DEVMETHOD(pcib_route_interrupt, pcibios_pcib_route_interrupt),
- DEVMETHOD(pcib_alloc_msi, pcib_alloc_msi),
- DEVMETHOD(pcib_release_msi, pcib_release_msi),
- DEVMETHOD(pcib_alloc_msix, pcib_alloc_msix),
- DEVMETHOD(pcib_release_msix, pcib_release_msix),
- DEVMETHOD(pcib_map_msi, pcib_map_msi),
+ DEVMETHOD(pcib_route_interrupt, legacy_pcib_route_interrupt),
- DEVMETHOD_END
+ {0, 0}
};
static devclass_t pcib_devclass;
-DEFINE_CLASS_0(pcib, pcibios_pcib_driver, pcibios_pcib_pci_methods,
- sizeof(struct pcib_softc));
+DEFINE_CLASS_1(pcib, pcibios_pcib_driver, pcibios_pcib_pci_methods,
+ sizeof(struct pcib_softc), pcib_driver);
DRIVER_MODULE(pcibios_pcib, pci, pcibios_pcib_driver, pcib_devclass, 0, 0);
static int
@@ -727,11 +733,4 @@ pcibios_pcib_probe(device_t dev)
device_set_desc(dev, "PCIBIOS PCI-PCI bridge");
return (-2000);
}
-
-static int
-pcibios_pcib_route_interrupt(device_t pcib, device_t dev, int pin)
-{
- return (pci_pir_route_interrupt(pci_get_bus(dev), pci_get_slot(dev),
- pci_get_function(dev), pin));
-}
-#endif /* __rtems__ */
+#endif