Page MenuHomeFreeBSD

D21096.diff
No OneTemporary

D21096.diff

Index: head/sys/compat/linuxkpi/common/include/linux/gfp.h
===================================================================
--- head/sys/compat/linuxkpi/common/include/linux/gfp.h
+++ head/sys/compat/linuxkpi/common/include/linux/gfp.h
@@ -56,6 +56,7 @@
#define __GFP_IO 0
#define __GFP_NO_KSWAPD 0
+#define __GFP_KSWAPD_RECLAIM 0
#define __GFP_WAIT M_WAITOK
#define __GFP_DMA32 (1U << 24) /* LinuxKPI only */
#define __GFP_BITS_SHIFT 25
Index: head/sys/compat/linuxkpi/common/include/linux/io.h
===================================================================
--- head/sys/compat/linuxkpi/common/include/linux/io.h
+++ head/sys/compat/linuxkpi/common/include/linux/io.h
@@ -42,6 +42,32 @@
* XXX This is all x86 specific. It should be bus space access.
*/
+
+/* rmb and wmb are declared in machine/atomic.h, so should be included first. */
+#ifndef __io_br
+#define __io_br() __compiler_membar()
+#endif
+
+#ifndef __io_ar
+#ifdef rmb
+#define __io_ar() rmb()
+#else
+#define __io_ar() __compiler_membar()
+#endif
+#endif
+
+#ifndef __io_bw
+#ifdef wmb
+#define __io_bw() wmb()
+#else
+#define __io_bw() __compiler_membar()
+#endif
+#endif
+
+#ifndef __io_aw
+#define __io_aw() __compiler_membar()
+#endif
+
/* Access MMIO registers atomically without barriers and byte swapping. */
static inline uint8_t
@@ -112,9 +138,9 @@
{
uint8_t v;
- __compiler_membar();
+ __io_br();
v = *(const volatile uint8_t *)addr;
- __compiler_membar();
+ __io_ar();
return (v);
}
#define readb(addr) readb(addr)
@@ -123,9 +149,9 @@
static inline void
writeb(uint8_t v, volatile void *addr)
{
- __compiler_membar();
+ __io_bw();
*(volatile uint8_t *)addr = v;
- __compiler_membar();
+ __io_aw();
}
#define writeb(v, addr) writeb(v, addr)
@@ -135,9 +161,9 @@
{
uint16_t v;
- __compiler_membar();
- v = *(const volatile uint16_t *)addr;
- __compiler_membar();
+ __io_br();
+ v = le16toh(__raw_readw(addr));
+ __io_ar();
return (v);
}
#define readw(addr) readw(addr)
@@ -146,9 +172,9 @@
static inline void
writew(uint16_t v, volatile void *addr)
{
- __compiler_membar();
- *(volatile uint16_t *)addr = v;
- __compiler_membar();
+ __io_bw();
+ __raw_writew(htole16(v), addr);
+ __io_aw();
}
#define writew(v, addr) writew(v, addr)
@@ -158,9 +184,9 @@
{
uint32_t v;
- __compiler_membar();
- v = *(const volatile uint32_t *)addr;
- __compiler_membar();
+ __io_br();
+ v = le32toh(__raw_readl(addr));
+ __io_ar();
return (v);
}
#define readl(addr) readl(addr)
@@ -169,9 +195,9 @@
static inline void
writel(uint32_t v, volatile void *addr)
{
- __compiler_membar();
- *(volatile uint32_t *)addr = v;
- __compiler_membar();
+ __io_bw();
+ __raw_writel(htole32(v), addr);
+ __io_aw();
}
#define writel(v, addr) writel(v, addr)
@@ -183,9 +209,9 @@
{
uint64_t v;
- __compiler_membar();
- v = *(const volatile uint64_t *)addr;
- __compiler_membar();
+ __io_br();
+ v = le64toh(__raw_readq(addr));
+ __io_ar();
return (v);
}
#define readq(addr) readq(addr)
@@ -193,9 +219,9 @@
static inline void
writeq(uint64_t v, volatile void *addr)
{
- __compiler_membar();
- *(volatile uint64_t *)addr = v;
- __compiler_membar();
+ __io_bw();
+ __raw_writeq(htole64(v), addr);
+ __io_aw();
}
#define writeq(v, addr) writeq(v, addr)
#endif
@@ -206,7 +232,7 @@
static inline uint8_t
readb_relaxed(const volatile void *addr)
{
- return (*(const volatile uint8_t *)addr);
+ return (__raw_readb(addr));
}
#define readb_relaxed(addr) readb_relaxed(addr)
@@ -214,7 +240,7 @@
static inline void
writeb_relaxed(uint8_t v, volatile void *addr)
{
- *(volatile uint8_t *)addr = v;
+ __raw_writeb(v, addr);
}
#define writeb_relaxed(v, addr) writeb_relaxed(v, addr)
@@ -222,7 +248,7 @@
static inline uint16_t
readw_relaxed(const volatile void *addr)
{
- return (*(const volatile uint16_t *)addr);
+ return (le16toh(__raw_readw(addr)));
}
#define readw_relaxed(addr) readw_relaxed(addr)
@@ -230,7 +256,7 @@
static inline void
writew_relaxed(uint16_t v, volatile void *addr)
{
- *(volatile uint16_t *)addr = v;
+ __raw_writew(htole16(v), addr);
}
#define writew_relaxed(v, addr) writew_relaxed(v, addr)
@@ -238,7 +264,7 @@
static inline uint32_t
readl_relaxed(const volatile void *addr)
{
- return (*(const volatile uint32_t *)addr);
+ return (le32toh(__raw_readl(addr)));
}
#define readl_relaxed(addr) readl_relaxed(addr)
@@ -246,7 +272,7 @@
static inline void
writel_relaxed(uint32_t v, volatile void *addr)
{
- *(volatile uint32_t *)addr = v;
+ __raw_writel(htole32(v), addr);
}
#define writel_relaxed(v, addr) writel_relaxed(v, addr)
@@ -256,14 +282,14 @@
static inline uint64_t
readq_relaxed(const volatile void *addr)
{
- return (*(const volatile uint64_t *)addr);
+ return (le64toh(__raw_readq(addr)));
}
#define readq_relaxed(addr) readq_relaxed(addr)
static inline void
writeq_relaxed(uint64_t v, volatile void *addr)
{
- *(volatile uint64_t *)addr = v;
+ __raw_writeq(htole64(v), addr);
}
#define writeq_relaxed(v, addr) writeq_relaxed(v, addr)
#endif
@@ -290,7 +316,13 @@
static inline uint16_t
ioread16be(const volatile void *addr)
{
- return (bswap16(readw(addr)));
+ uint16_t v;
+
+ __io_br();
+ v = (be16toh(__raw_readw(addr)));
+ __io_ar();
+
+ return (v);
}
#define ioread16be(addr) ioread16be(addr)
@@ -306,7 +338,13 @@
static inline uint32_t
ioread32be(const volatile void *addr)
{
- return (bswap32(readl(addr)));
+ uint32_t v;
+
+ __io_br();
+ v = (be32toh(__raw_readl(addr)));
+ __io_ar();
+
+ return (v);
}
#define ioread32be(addr) ioread32be(addr)
@@ -338,7 +376,9 @@
static inline void
iowrite32be(uint32_t v, volatile void *addr)
{
- writel(bswap32(v), addr);
+ __io_bw();
+ __raw_writel(htobe32(v), addr);
+ __io_aw();
}
#define iowrite32be(v, addr) iowrite32be(v, addr)
Index: head/sys/compat/linuxkpi/common/include/linux/pci.h
===================================================================
--- head/sys/compat/linuxkpi/common/include/linux/pci.h
+++ head/sys/compat/linuxkpi/common/include/linux/pci.h
@@ -205,6 +205,7 @@
struct pci_bus {
struct pci_dev *self;
+ int domain;
int number;
};
@@ -270,26 +271,6 @@
return (found);
}
-static inline unsigned long
-pci_resource_start(struct pci_dev *pdev, int bar)
-{
- struct resource_list_entry *rle;
-
- if ((rle = linux_pci_get_bar(pdev, bar)) == NULL)
- return (0);
- return rle->start;
-}
-
-static inline unsigned long
-pci_resource_len(struct pci_dev *pdev, int bar)
-{
- struct resource_list_entry *rle;
-
- if ((rle = linux_pci_get_bar(pdev, bar)) == NULL)
- return (0);
- return rle->count;
-}
-
static inline int
pci_resource_type(struct pci_dev *pdev, int bar)
{
@@ -447,6 +428,9 @@
pdev->dev.msix_max = 0;
}
+unsigned long pci_resource_start(struct pci_dev *pdev, int bar);
+unsigned long pci_resource_len(struct pci_dev *pdev, int bar);
+
static inline bus_addr_t
pci_bus_address(struct pci_dev *pdev, int bar)
{
@@ -633,7 +617,7 @@
/* XXX This should not be necessary. */
#define pcix_set_mmrbc(d, v) 0
#define pcix_get_max_mmrbc(d) 0
-#define pcie_set_readrq(d, v) 0
+#define pcie_set_readrq(d, v) pci_set_max_read_req(&(d)->dev, (v))
#define PCI_DMA_BIDIRECTIONAL 0
#define PCI_DMA_TODEVICE 1
Index: head/sys/compat/linuxkpi/common/src/linux_pci.c
===================================================================
--- head/sys/compat/linuxkpi/common/src/linux_pci.c
+++ head/sys/compat/linuxkpi/common/src/linux_pci.c
@@ -29,12 +29,12 @@
#include <sys/param.h>
#include <sys/systm.h>
+#include <sys/bus.h>
#include <sys/malloc.h>
#include <sys/kernel.h>
#include <sys/sysctl.h>
#include <sys/lock.h>
#include <sys/mutex.h>
-#include <sys/bus.h>
#include <sys/fcntl.h>
#include <sys/file.h>
#include <sys/filio.h>
@@ -209,7 +209,6 @@
struct pci_driver *pdrv;
const struct pci_device_id *id;
device_t parent;
- devclass_t devclass;
int error;
linux_set_current(curthread);
@@ -218,7 +217,6 @@
pdev = device_get_softc(dev);
parent = device_get_parent(dev);
- devclass = device_get_devclass(parent);
if (pdrv->isdrm) {
dinfo = device_get_ivars(parent);
device_set_ivars(dev, dinfo);
@@ -254,6 +252,7 @@
pbus = malloc(sizeof(*pbus), M_DEVBUF, M_WAITOK | M_ZERO);
pbus->self = pdev;
pbus->number = pci_get_bus(dev);
+ pbus->domain = pci_get_domain(dev);
pdev->bus = pbus;
spin_lock(&pci_lock);
@@ -386,6 +385,36 @@
return (-ENXIO);
pdrv->isdrm = false;
return (_linux_pci_register_driver(pdrv, dc));
+}
+
+unsigned long
+pci_resource_start(struct pci_dev *pdev, int bar)
+{
+ struct resource_list_entry *rle;
+ unsigned long newstart;
+ device_t dev;
+
+ if ((rle = linux_pci_get_bar(pdev, bar)) == NULL)
+ return (0);
+ dev = pci_find_dbsf(pdev->bus->domain, pdev->bus->number,
+ PCI_SLOT(pdev->devfn), PCI_FUNC(pdev->devfn));
+ MPASS(dev != NULL);
+ if (BUS_TRANSLATE_RESOURCE(dev, rle->type, rle->start, &newstart)) {
+ device_printf(pdev->dev.bsddev, "translate of %#lx failed\n",
+ rle->start);
+ return (0);
+ }
+ return (newstart);
+}
+
+unsigned long
+pci_resource_len(struct pci_dev *pdev, int bar)
+{
+ struct resource_list_entry *rle;
+
+ if ((rle = linux_pci_get_bar(pdev, bar)) == NULL)
+ return (0);
+ return (rle->count);
}
int
Index: head/sys/dev/ofw/ofwpci.c
===================================================================
--- head/sys/dev/ofw/ofwpci.c
+++ head/sys/dev/ofw/ofwpci.c
@@ -76,6 +76,8 @@
struct resource *);
static int ofw_pci_adjust_resource(device_t, device_t, int,
struct resource *, rman_res_t, rman_res_t);
+static int ofw_pci_translate_resource(device_t bus, int type,
+ rman_res_t start, rman_res_t *newstart);
#ifdef __powerpc__
static bus_space_tag_t ofw_pci_bus_get_bus_tag(device_t, device_t);
@@ -116,6 +118,7 @@
DEVMETHOD(bus_activate_resource, ofw_pci_activate_resource),
DEVMETHOD(bus_deactivate_resource, ofw_pci_deactivate_resource),
DEVMETHOD(bus_adjust_resource, ofw_pci_adjust_resource),
+ DEVMETHOD(bus_translate_resource, ofw_pci_translate_resource),
#ifdef __powerpc__
DEVMETHOD(bus_get_bus_tag, ofw_pci_bus_get_bus_tag),
#endif
@@ -476,6 +479,45 @@
return (error);
}
return (rman_release_resource(res));
+}
+
+static int
+ofw_pci_translate_resource(device_t bus, int type, rman_res_t start,
+ rman_res_t *newstart)
+{
+ struct ofw_pci_softc *sc;
+ struct ofw_pci_range *rp;
+ int space;
+
+ sc = device_get_softc(bus);
+
+ /*
+ * Map this through the ranges list
+ */
+ for (rp = sc->sc_range; rp < sc->sc_range + sc->sc_nrange &&
+ rp->pci_hi != 0; rp++) {
+ if (start < rp->pci || start >= rp->pci + rp->size)
+ continue;
+
+ switch (rp->pci_hi & OFW_PCI_PHYS_HI_SPACEMASK) {
+ case OFW_PCI_PHYS_HI_SPACE_IO:
+ space = SYS_RES_IOPORT;
+ break;
+ case OFW_PCI_PHYS_HI_SPACE_MEM32:
+ case OFW_PCI_PHYS_HI_SPACE_MEM64:
+ space = SYS_RES_MEMORY;
+ break;
+ default:
+ space = -1;
+ }
+
+ if (type == space) {
+ start += (rp->host - rp->pci);
+ break;
+ }
+ }
+ *newstart = start;
+ return (0);
}
static int
Index: head/sys/dev/pci/vga_pci.c
===================================================================
--- head/sys/dev/pci/vga_pci.c
+++ head/sys/dev/pci/vga_pci.c
@@ -142,11 +142,35 @@
return (1);
}
+static void
+vga_pci_reset(device_t dev)
+{
+ int ps;
+ /*
+ * FLR is unsupported on GPUs so attempt a power-management reset by cycling
+ * the device in/out of D3 state.
+ * PCI spec says we can only go into D3 state from D0 state.
+ * Transition from D[12] into D0 before going to D3 state.
+ */
+ ps = pci_get_powerstate(dev);
+ if (ps != PCI_POWERSTATE_D0 && ps != PCI_POWERSTATE_D3)
+ pci_set_powerstate(dev, PCI_POWERSTATE_D0);
+ if (pci_get_powerstate(dev) != PCI_POWERSTATE_D3)
+ pci_set_powerstate(dev, PCI_POWERSTATE_D3);
+ pci_set_powerstate(dev, ps);
+}
+
+
void *
vga_pci_map_bios(device_t dev, size_t *size)
{
- int rid;
+ struct vga_resource *vr;
struct resource *res;
+ device_t pcib;
+ uint32_t rom_addr;
+ uint16_t config;
+ volatile char *bios;
+ int i, rid, found;
#if defined(__amd64__) || defined(__i386__)
if (vga_pci_is_boot_display(dev)) {
@@ -164,21 +188,96 @@
}
#endif
- rid = PCIR_BIOS;
+ pcib = device_get_parent(device_get_parent(dev));
+ if (device_get_devclass(device_get_parent(pcib)) ==
+ devclass_find("pci")) {
+ /*
+ * The parent bridge is a PCI-to-PCI bridge: check the
+ * value of the "VGA Enable" bit.
+ */
+ config = pci_read_config(pcib, PCIR_BRIDGECTL_1, 2);
+ if ((config & PCIB_BCR_VGA_ENABLE) == 0) {
+ config |= PCIB_BCR_VGA_ENABLE;
+ pci_write_config(pcib, PCIR_BRIDGECTL_1, config, 2);
+ }
+ }
+
+ switch(pci_read_config(dev, PCIR_HDRTYPE, 1)) {
+ case PCIM_HDRTYPE_BRIDGE:
+ rid = PCIR_BIOS_1;
+ break;
+ case PCIM_HDRTYPE_CARDBUS:
+ rid = 0;
+ break;
+ default:
+ rid = PCIR_BIOS;
+ break;
+ }
+ if (rid == 0)
+ return (NULL);
res = vga_pci_alloc_resource(dev, NULL, SYS_RES_MEMORY, &rid, 0,
~0, 1, RF_ACTIVE);
+
if (res == NULL) {
+ device_printf(dev, "vga_pci_alloc_resource failed\n");
return (NULL);
}
+ bios = rman_get_virtual(res);
+ *size = rman_get_size(res);
+ for (found = i = 0; i < hz; i++) {
+ found = (bios[0] == 0x55 && bios[1] == 0xaa);
+ if (found)
+ break;
+ pause("vgabios", 1);
+ }
+ if (found)
+ return (__DEVOLATILE(void *, bios));
+ if (bootverbose)
+ device_printf(dev, "initial ROM mapping failed -- resetting\n");
+ /*
+ * Enable ROM decode
+ */
+ vga_pci_reset(dev);
+ rom_addr = pci_read_config(dev, rid, 4);
+ rom_addr &= 0x7ff;
+ rom_addr |= rman_get_start(res) | 0x1;
+ pci_write_config(dev, rid, rom_addr, 4);
+ vr = lookup_res(device_get_softc(dev), rid);
+ vga_pci_release_resource(dev, NULL, SYS_RES_MEMORY, rid,
+ vr->vr_res);
+
+ /*
+ * re-allocate
+ */
+ res = vga_pci_alloc_resource(dev, NULL, SYS_RES_MEMORY, &rid, 0,
+ ~0, 1, RF_ACTIVE);
+ if (res == NULL) {
+ device_printf(dev, "vga_pci_alloc_resource failed\n");
+ return (NULL);
+ }
+ bios = rman_get_virtual(res);
*size = rman_get_size(res);
- return (rman_get_virtual(res));
+ for (found = i = 0; i < 3*hz; i++) {
+ found = (bios[0] == 0x55 && bios[1] == 0xaa);
+ if (found)
+ break;
+ pause("vgabios", 1);
+ }
+ if (found)
+ return (__DEVOLATILE(void *, bios));
+ device_printf(dev, "ROM mapping failed\n");
+ vr = lookup_res(device_get_softc(dev), rid);
+ vga_pci_release_resource(dev, NULL, SYS_RES_MEMORY, rid,
+ vr->vr_res);
+ return (NULL);
}
void
vga_pci_unmap_bios(device_t dev, void *bios)
{
struct vga_resource *vr;
+ int rid;
if (bios == NULL) {
return;
@@ -192,16 +291,28 @@
return;
}
#endif
-
+ switch(pci_read_config(dev, PCIR_HDRTYPE, 1)) {
+ case PCIM_HDRTYPE_BRIDGE:
+ rid = PCIR_BIOS_1;
+ break;
+ case PCIM_HDRTYPE_CARDBUS:
+ rid = 0;
+ break;
+ default:
+ rid = PCIR_BIOS;
+ break;
+ }
+ if (rid == 0)
+ return;
/*
* Look up the PCIR_BIOS resource in our softc. It should match
* the address we returned previously.
*/
- vr = lookup_res(device_get_softc(dev), PCIR_BIOS);
+ vr = lookup_res(device_get_softc(dev), rid);
KASSERT(vr->vr_res != NULL, ("vga_pci_unmap_bios: bios not mapped"));
KASSERT(rman_get_virtual(vr->vr_res) == bios,
("vga_pci_unmap_bios: mismatch"));
- vga_pci_release_resource(dev, NULL, SYS_RES_MEMORY, PCIR_BIOS,
+ vga_pci_release_resource(dev, NULL, SYS_RES_MEMORY, rid,
vr->vr_res);
}
Index: head/sys/kern/bus_if.m
===================================================================
--- head/sys/kern/bus_if.m
+++ head/sys/kern/bus_if.m
@@ -76,6 +76,18 @@
{
return (0);
}
+
+ static int
+ null_translate_resource(device_t bus, int type, rman_res_t start,
+ rman_res_t *newstart)
+ {
+ if (device_get_parent(bus) != NULL)
+ return (BUS_TRANSLATE_RESOURCE(device_get_parent(bus),
+ type, start, newstart));
+
+ *newstart = start;
+ return (0);
+ }
};
/**
@@ -405,6 +417,23 @@
rman_res_t _start;
rman_res_t _end;
};
+
+
+/**
+ * @brief translate a resource value
+ *
+ *
+ * @param _dev the device associated with the resource
+ * @param _type the type of resource
+ * @param _start the starting address of the resource range
+ * @param _newstart the new starting address of the resource range
+ */
+METHOD int translate_resource {
+ device_t _dev;
+ int _type;
+ rman_res_t _start;
+ rman_res_t *_newstart;
+} DEFAULT null_translate_resource;
/**
* @brief Release a resource
Index: head/sys/kern/subr_bus.c
===================================================================
--- head/sys/kern/subr_bus.c
+++ head/sys/kern/subr_bus.c
@@ -3971,7 +3971,6 @@
return (0);
}
-
/**
* @brief Helper function for implementing BUS_PRINT_CHILD().
*
Index: head/sys/sys/bus.h
===================================================================
--- head/sys/sys/bus.h
+++ head/sys/sys/bus.h
@@ -434,6 +434,8 @@
bus_generic_alloc_resource(device_t bus, device_t child, int type,
int *rid, rman_res_t start, rman_res_t end,
rman_res_t count, u_int flags);
+int bus_generic_translate_resource(device_t dev, int type, rman_res_t start,
+ rman_res_t *newstart);
int bus_generic_attach(device_t dev);
int bus_generic_bind_intr(device_t dev, device_t child,
struct resource *irq, int cpu);

File Metadata

Mime Type
text/plain
Expires
Tue, Apr 29, 3:42 AM (5 h, 30 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
17836763
Default Alt Text
D21096.diff (16 KB)

Event Timeline