mirror of
https://git.freebsd.org/ports.git
synced 2025-07-01 01:20:31 -04:00
how to deal with it. This affects !386 only and is based on the respective Linux support code. Approved by: flz
306 lines
7.6 KiB
C
306 lines
7.6 KiB
C
--- hw/xfree86/os-support/bus/freebsdPci.c.orig Thu Sep 6 02:48:26 2007
|
|
+++ hw/xfree86/os-support/bus/freebsdPci.c Sat Sep 29 12:22:56 2007
|
|
@@ -109,10 +109,6 @@
|
|
#define PCI_CPU(val) (val)
|
|
#endif
|
|
|
|
-
|
|
-#define BUS(tag) (((tag)>>16)&0xff)
|
|
-#define DFN(tag) (((tag)>>8)&0xff)
|
|
-
|
|
static int pciFd = -1;
|
|
|
|
void
|
|
@@ -133,9 +129,12 @@
|
|
{
|
|
struct pci_io io;
|
|
int error;
|
|
- io.pi_sel.pc_bus = BUS(tag);
|
|
- io.pi_sel.pc_dev = DFN(tag) >> 3;
|
|
- io.pi_sel.pc_func = DFN(tag) & 7;
|
|
+#ifndef INCLUDE_XF86_NO_DOMAIN
|
|
+ io.pi_sel.pc_domain = PCI_DOM_FROM_TAG(tag);
|
|
+#endif
|
|
+ io.pi_sel.pc_bus = PCI_BUS_NO_DOMAIN(PCI_BUS_FROM_TAG(tag));
|
|
+ io.pi_sel.pc_dev = PCI_DEV_FROM_TAG(tag);
|
|
+ io.pi_sel.pc_func = PCI_FUNC_FROM_TAG(tag);
|
|
io.pi_reg = off;
|
|
io.pi_width = 4;
|
|
error = ioctl(pciFd, PCIOCREAD, &io);
|
|
@@ -148,9 +147,12 @@
|
|
freebsdPciCfgWrite(PCITAG tag, int off, CARD32 val)
|
|
{
|
|
struct pci_io io;
|
|
- io.pi_sel.pc_bus = BUS(tag);
|
|
- io.pi_sel.pc_dev = DFN(tag) >> 3;
|
|
- io.pi_sel.pc_func = DFN(tag) & 7;
|
|
+#ifndef INCLUDE_XF86_NO_DOMAIN
|
|
+ io.pi_sel.pc_domain = PCI_DOM_FROM_TAG(tag);
|
|
+#endif
|
|
+ io.pi_sel.pc_bus = PCI_BUS_NO_DOMAIN(PCI_BUS_FROM_TAG(tag));
|
|
+ io.pi_sel.pc_dev = PCI_DEV_FROM_TAG(tag);
|
|
+ io.pi_sel.pc_func = PCI_FUNC_FROM_TAG(tag);
|
|
io.pi_reg = off;
|
|
io.pi_width = 4;
|
|
io.pi_data = PCI_CPU(val);
|
|
@@ -164,3 +166,260 @@
|
|
val = (val & ~mask) | (bits & mask);
|
|
freebsdPciCfgWrite(tag, off, val);
|
|
}
|
|
+
|
|
+#ifndef INCLUDE_XF86_NO_DOMAIN
|
|
+
|
|
+/* This probably shouldn't be FreeBSD-specific. */
|
|
+static pciConfigPtr
|
|
+xf86GetPciHostConfigFromTag(PCITAG Tag)
|
|
+{
|
|
+ int bus = PCI_BUS_FROM_TAG(Tag);
|
|
+ pciBusInfo_t *pBusInfo;
|
|
+
|
|
+ while ((bus < pciNumBuses) && (pBusInfo = pciBusInfo[bus])) {
|
|
+ if (bus == pBusInfo->primary_bus)
|
|
+ return pBusInfo->bridge;
|
|
+ bus = pBusInfo->primary_bus;
|
|
+ }
|
|
+
|
|
+ return NULL; /* Bad data */
|
|
+}
|
|
+
|
|
+/*
|
|
+ * This is ugly, but until I can extract this information from the kernel,
|
|
+ * it'll have to do. The default I/O space size is 64K, and 4G for memory.
|
|
+ * Anything else needs to go in this table. (PowerPC folk take note.)
|
|
+ *
|
|
+ * Please keep this table in ascending vendor/device order.
|
|
+ */
|
|
+static const struct pciSizes {
|
|
+ unsigned short vendor, device;
|
|
+ unsigned long io_size, mem_size;
|
|
+} pciControllerSizes[] = {
|
|
+ {
|
|
+ PCI_VENDOR_SUN, PCI_CHIP_PSYCHO,
|
|
+ 1U << 16, 1U << 31
|
|
+ },
|
|
+ {
|
|
+ PCI_VENDOR_SUN, PCI_CHIP_SCHIZO,
|
|
+ 1U << 24, 1U << 31 /* ??? */
|
|
+ },
|
|
+ {
|
|
+ PCI_VENDOR_SUN, PCI_CHIP_SABRE,
|
|
+ 1U << 24, (unsigned long)(1ULL << 32)
|
|
+ },
|
|
+ {
|
|
+ PCI_VENDOR_SUN, PCI_CHIP_HUMMINGBIRD,
|
|
+ 1U << 24, (unsigned long)(1ULL << 32)
|
|
+ }
|
|
+};
|
|
+#define NUM_SIZES (sizeof(pciControllerSizes) / sizeof(pciControllerSizes[0]))
|
|
+
|
|
+static const struct pciSizes *
|
|
+freebsdGetSizesStruct(PCITAG Tag)
|
|
+{
|
|
+ static const struct pciSizes default_size = {
|
|
+ 0, 0, 1U << 16, (unsigned long)(1ULL << 32)
|
|
+ };
|
|
+ pciConfigPtr pPCI;
|
|
+ int i;
|
|
+
|
|
+ /* Find host bridge */
|
|
+ if ((pPCI = xf86GetPciHostConfigFromTag(Tag))) {
|
|
+ /* Look up vendor/device */
|
|
+ for (i = 0; i < NUM_SIZES; i++) {
|
|
+ if ((pPCI->pci_vendor ==
|
|
+ pciControllerSizes[i].vendor) &&
|
|
+ (pPCI->pci_device ==
|
|
+ pciControllerSizes[i].device)) {
|
|
+ return & pciControllerSizes[i];
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* Default to 64KB I/O and 4GB memory. */
|
|
+ return & default_size;
|
|
+}
|
|
+
|
|
+static __inline__ unsigned long
|
|
+freebsdGetIOSize(PCITAG Tag)
|
|
+{
|
|
+ const struct pciSizes * const sizes = freebsdGetSizesStruct(Tag);
|
|
+ return sizes->io_size;
|
|
+}
|
|
+
|
|
+static __inline__ void
|
|
+freebsdGetSizes(PCITAG Tag, unsigned long *io_size, unsigned long *mem_size)
|
|
+{
|
|
+ const struct pciSizes * const sizes = freebsdGetSizesStruct(Tag);
|
|
+
|
|
+ *io_size = sizes->io_size;
|
|
+ *mem_size = sizes->mem_size;
|
|
+}
|
|
+
|
|
+_X_EXPORT int
|
|
+xf86GetPciDomain(PCITAG Tag)
|
|
+{
|
|
+ return PCI_DOM_FROM_TAG(Tag);
|
|
+}
|
|
+
|
|
+_X_EXPORT pointer
|
|
+xf86MapDomainMemory(int ScreenNum, int Flags, PCITAG Tag, ADDRESS Base,
|
|
+ unsigned long Size)
|
|
+{
|
|
+ return xf86MapVidMem(ScreenNum, Flags, Base, Size);
|
|
+}
|
|
+
|
|
+_X_EXPORT IOADDRESS
|
|
+xf86MapDomainIO(int ScreenNum, int Flags, PCITAG Tag, IOADDRESS Base,
|
|
+ unsigned long Size)
|
|
+{
|
|
+ return Base;
|
|
+}
|
|
+
|
|
+_X_EXPORT int
|
|
+xf86ReadDomainMemory(PCITAG Tag, ADDRESS Base, int Len, unsigned char *Buf)
|
|
+{
|
|
+ int ret, length, rlength;
|
|
+
|
|
+ /* Read in 64kB chunks. */
|
|
+ ret = 0;
|
|
+ while ((length = Len) > 0) {
|
|
+ if (length > 0x010000) length = 0x010000;
|
|
+ rlength = xf86ReadBIOS(Base, 0, Buf, length);
|
|
+ if (rlength < 0) {
|
|
+ ret = rlength;
|
|
+ break;
|
|
+ }
|
|
+ ret += rlength;
|
|
+ if (rlength < length) break;
|
|
+ Base += rlength;
|
|
+ Buf += rlength;
|
|
+ Len -= rlength;
|
|
+ }
|
|
+
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+resPtr
|
|
+xf86BusAccWindowsFromOS(void)
|
|
+{
|
|
+ pciConfigPtr *ppPCI, pPCI;
|
|
+ resPtr pRes = NULL;
|
|
+ resRange range;
|
|
+ unsigned long io_size, mem_size;
|
|
+ int domain;
|
|
+
|
|
+ if ((ppPCI = xf86scanpci(0))) {
|
|
+ for (; (pPCI = *ppPCI); ppPCI++) {
|
|
+ if ((pPCI->pci_base_class != PCI_CLASS_BRIDGE) ||
|
|
+ (pPCI->pci_sub_class != PCI_SUBCLASS_BRIDGE_HOST))
|
|
+ continue;
|
|
+
|
|
+ domain = xf86GetPciDomain(pPCI->tag);
|
|
+ freebsdGetSizes(pPCI->tag, &io_size, &mem_size);
|
|
+
|
|
+ RANGE(range, 0, (ADDRESS)(mem_size - 1),
|
|
+ RANGE_TYPE(ResExcMemBlock, domain));
|
|
+ pRes = xf86AddResToList(pRes, &range, -1);
|
|
+
|
|
+ RANGE(range, 0, (IOADDRESS)(io_size - 1),
|
|
+ RANGE_TYPE(ResExcIoBlock, domain));
|
|
+ pRes = xf86AddResToList(pRes, &range, -1);
|
|
+
|
|
+ if (domain <= 0)
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return pRes;
|
|
+}
|
|
+
|
|
+resPtr
|
|
+xf86PciBusAccWindowsFromOS(void)
|
|
+{
|
|
+ pciConfigPtr *ppPCI, pPCI;
|
|
+ resPtr pRes = NULL;
|
|
+ resRange range;
|
|
+ unsigned long io_size, mem_size;
|
|
+ int domain;
|
|
+
|
|
+ if ((ppPCI = xf86scanpci(0))) {
|
|
+ for (; (pPCI = *ppPCI); ppPCI++) {
|
|
+ if ((pPCI->pci_base_class != PCI_CLASS_BRIDGE) ||
|
|
+ (pPCI->pci_sub_class != PCI_SUBCLASS_BRIDGE_HOST))
|
|
+ continue;
|
|
+
|
|
+ domain = xf86GetPciDomain(pPCI->tag);
|
|
+ freebsdGetSizes(pPCI->tag, &io_size, &mem_size);
|
|
+
|
|
+ RANGE(range, 0, (ADDRESS)(mem_size - 1),
|
|
+ RANGE_TYPE(ResExcMemBlock, domain));
|
|
+ pRes = xf86AddResToList(pRes, &range, -1);
|
|
+
|
|
+ RANGE(range, 0, (IOADDRESS)(io_size - 1),
|
|
+ RANGE_TYPE(ResExcIoBlock, domain));
|
|
+ pRes = xf86AddResToList(pRes, &range, -1);
|
|
+
|
|
+ if (domain <= 0)
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return pRes;
|
|
+}
|
|
+
|
|
+resPtr
|
|
+xf86AccResFromOS(resPtr pRes)
|
|
+{
|
|
+ pciConfigPtr *ppPCI, pPCI;
|
|
+ resRange range;
|
|
+ unsigned long io_size, mem_size;
|
|
+ int domain;
|
|
+
|
|
+ if ((ppPCI = xf86scanpci(0))) {
|
|
+ for (; (pPCI = *ppPCI); ppPCI++) {
|
|
+ if ((pPCI->pci_base_class != PCI_CLASS_BRIDGE) ||
|
|
+ (pPCI->pci_sub_class != PCI_SUBCLASS_BRIDGE_HOST))
|
|
+ continue;
|
|
+
|
|
+ domain = xf86GetPciDomain(pPCI->tag);
|
|
+ freebsdGetSizes(pPCI->tag, &io_size, &mem_size);
|
|
+
|
|
+ /*
|
|
+ * At minimum, the top and bottom resources must be
|
|
+ * claimed, so that resources that are (or appear to
|
|
+ * be) unallocated can be relocated.
|
|
+ */
|
|
+ RANGE(range, 0x00000000u, 0x0009ffffu,
|
|
+ RANGE_TYPE(ResExcMemBlock, domain));
|
|
+ pRes = xf86AddResToList(pRes, &range, -1);
|
|
+ RANGE(range, 0x000c0000u, 0x000effffu,
|
|
+ RANGE_TYPE(ResExcMemBlock, domain));
|
|
+ pRes = xf86AddResToList(pRes, &range, -1);
|
|
+ RANGE(range, 0x000f0000u, 0x000fffffu,
|
|
+ RANGE_TYPE(ResExcMemBlock, domain));
|
|
+ pRes = xf86AddResToList(pRes, &range, -1);
|
|
+
|
|
+ RANGE(range, (ADDRESS)(mem_size - 1),
|
|
+ (ADDRESS)(mem_size - 1),
|
|
+ RANGE_TYPE(ResExcMemBlock, domain));
|
|
+ pRes = xf86AddResToList(pRes, &range, -1);
|
|
+
|
|
+ RANGE(range, 0x00000000u, 0x00000000u,
|
|
+ RANGE_TYPE(ResExcIoBlock, domain));
|
|
+ pRes = xf86AddResToList(pRes, &range, -1);
|
|
+ RANGE(range, (IOADDRESS)(io_size - 1),
|
|
+ (IOADDRESS)(io_size - 1),
|
|
+ RANGE_TYPE(ResExcIoBlock, domain));
|
|
+ pRes = xf86AddResToList(pRes, &range, -1);
|
|
+
|
|
+ if (domain <= 0)
|
|
+ break;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return pRes;
|
|
+}
|
|
+
|
|
+#endif /* !INCLUDE_XF86_NO_DOMAIN */
|