Port-amd64 archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: x86 pcitag_t change proposal/patch
Oh, and here's the patch this time.
Index: sys/arch/x86/include/pci_machdep_common.h
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/include/pci_machdep_common.h,v
retrieving revision 1.11
diff -d -u -a -p -r1.11 pci_machdep_common.h
--- sys/arch/x86/include/pci_machdep_common.h 9 Dec 2012 21:30:02 -0000
1.11
+++ sys/arch/x86/include/pci_machdep_common.h 26 Apr 2013 13:20:02 -0000
@@ -47,26 +47,24 @@
*
* Configuration tag; created from a {bus,device,function} triplet by
* pci_make_tag(), and passed to pci_conf_read() and pci_conf_write().
- * We could instead always pass the {bus,device,function} triplet to
- * the read and write routines, but this would cause extra overhead.
- *
- * Mode 2 is historical and deprecated by the Revision 2.0 specification.
- *
- *
- * Mode 1 tag:
- * 31 24 16 15 11 10 8
- * +---------------------------------------------------------------+
- * |1| 0 | BUS | DEV |FUNC | 0 |
- * +---------------------------------------------------------------+
*/
-union x86_pci_tag_u {
- uint32_t mode1;
- struct {
- uint16_t port;
- uint8_t enable;
- uint8_t forward;
- } mode2;
-};
+
+#define X86_PCITAG_FUNC_BITS ((uint32_t)__BITS( 2, 0))
+#define X86_PCITAG_DEV_BITS ((uint32_t)__BITS( 7, 3))
+#define X86_PCITAG_DEVFUNC_BITS ((uint32_t)__BITS( 7, 0))
+#define X86_PCITAG_BUS_BITS ((uint32_t)__BITS(15, 8))
+#define X86_PCITAG_BDF_BITS ((uint32_t)__BITS(15, 0))
+
+#define X86_PCITAG_FUNC(tag) __SHIFTOUT(tag, X86_PCITAG_FUNC_BITS)
+#define X86_PCITAG_DEV(tag) __SHIFTOUT(tag, X86_PCITAG_DEV_BITS)
+#define X86_PCITAG_DEVFUNC(tag) __SHIFTOUT(tag, X86_PCITAG_DEVFUNC_BITS)
+#define X86_PCITAG_BUS(tag) __SHIFTOUT(tag, X86_PCITAG_BUS_BITS)
+#define X86_PCITAG_BDF(tag) __SHIFTOUT(tag, X86_PCITAG_BDF_BITS)
+
+#define X86_PCITAG_MAKE(b, d, f) \
+ ((pcitag_t)(__SHIFTIN(f, X86_PCITAG_FUNC_BITS) | \
+ __SHIFTIN(d, X86_PCITAG_DEV_BITS) | \
+ __SHIFTIN(b, X86_PCITAG_BUS_BITS)))
extern struct x86_bus_dma_tag pci_bus_dma_tag;
#ifdef _LP64
@@ -80,7 +78,7 @@ struct pci_chipset_tag;
* Types provided to machine-independent PCI code
*/
typedef struct pci_chipset_tag *pci_chipset_tag_t;
-typedef union x86_pci_tag_u pcitag_t;
+typedef uint32_t pcitag_t;
struct pci_chipset_tag {
pci_chipset_tag_t pc_super;
Index: sys/arch/x86/pci/pci_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/pci/pci_machdep.c,v
retrieving revision 1.56
diff -d -u -a -p -r1.56 pci_machdep.c
--- sys/arch/x86/pci/pci_machdep.c 1 Mar 2012 20:16:27 -0000 1.56
+++ sys/arch/x86/pci/pci_machdep.c 26 Apr 2013 13:20:02 -0000
@@ -174,10 +174,20 @@ struct pci_bridge_hook_arg {
#define PCI_MODE2_ENABLE_REG 0x0cf8
#define PCI_MODE2_FORWARD_REG 0x0cfa
-#define _tag(b, d, f) \
- {.mode1 = PCI_MODE1_ENABLE | ((b) << 16) | ((d) << 11) | ((f) << 8)}
+#define MODE2_SELECTOR_ENABLE_BITS ((uint32_t)__BITS( 7, 0))
+#define MODE2_SELECTOR_FORWARD_BITS ((uint32_t)__BITS(15, 8))
+
+#define MODE2_SELECTOR_ENABLE(sel) \
+ __SHIFTOUT(sel, MODE2_SELECTOR_ENABLE_BITS)
+#define MODE2_SELECTOR_FORWARD(sel) \
+ __SHIFTOUT(sel, MODE2_SELECTOR_FORWARD_BITS)
+
+#define MODE2_SELECTOR_COMPOSE(enab, forw) \
+ (__SHIFTIN(enab, MODE2_SELECTOR_ENABLE_BITS) | \
+ __SHIFTIN(forw, MODE2_SELECTOR_FORWARD_BITS))
+
#define _qe(bus, dev, fcn, vend, prod) \
- {_tag(bus, dev, fcn), PCI_ID_CODE(vend, prod)}
+ {X86_PCITAG_MAKE(bus, dev, fcn), PCI_ID_CODE(vend, prod)}
const struct {
pcitag_t tag;
pcireg_t id;
@@ -201,7 +211,6 @@ const struct {
/* VIA Technologies VX900 */
_qe(0, 0, 0, PCI_VENDOR_VIATECH, PCI_PRODUCT_VIATECH_VX900_HB)
};
-#undef _tag
#undef _qe
/*
@@ -316,18 +325,12 @@ pci_conf_unlock(struct pci_conf_lock *oc
static uint32_t
pci_conf_selector(pcitag_t tag, int reg)
{
- static const pcitag_t mode2_mask = {
- .mode2 = {
- .enable = 0xff
- , .forward = 0xff
- }
- };
-
switch (pci_mode) {
case 1:
- return tag.mode1 | reg;
+ return PCI_MODE1_ENABLE | (X86_PCITAG_BDF(tag) << 8) | reg;
case 2:
- return tag.mode1 & mode2_mask.mode1;
+ return MODE2_SELECTOR_COMPOSE(
+ 0xf0 | (X86_PCITAG_FUNC(tag) << 1), X86_PCITAG_BUS(tag));
default:
panic("%s: mode not configured", __func__);
}
@@ -340,7 +343,7 @@ pci_conf_port(pcitag_t tag, int reg)
case 1:
return PCI_MODE1_DATA_REG;
case 2:
- return tag.mode2.port | reg;
+ return 0xc000 | (X86_PCITAG_DEV(tag) << 8) | reg;
default:
panic("%s: mode not configured", __func__);
}
@@ -349,17 +352,16 @@ pci_conf_port(pcitag_t tag, int reg)
static void
pci_conf_select(uint32_t sel)
{
- pcitag_t tag;
switch (pci_mode) {
case 1:
outl(PCI_MODE1_ADDRESS_REG, sel);
return;
case 2:
- tag.mode1 = sel;
- outb(PCI_MODE2_ENABLE_REG, tag.mode2.enable);
- if (tag.mode2.enable != 0)
- outb(PCI_MODE2_FORWARD_REG, tag.mode2.forward);
+ outb(PCI_MODE2_ENABLE_REG, MODE2_SELECTOR_ENABLE(sel));
+ if (MODE2_SELECTOR_ENABLE(sel) != 0)
+ outb(PCI_MODE2_FORWARD_REG,
+ MODE2_SELECTOR_FORWARD(sel));
return;
default:
panic("%s: mode not configured", __func__);
@@ -399,7 +401,6 @@ pcitag_t
pci_make_tag(pci_chipset_tag_t pc, int bus, int device, int function)
{
pci_chipset_tag_t ipc;
- pcitag_t tag;
for (ipc = pc; ipc != NULL; ipc = ipc->pc_super) {
if ((ipc->pc_present & PCI_OVERRIDE_MAKE_TAG) == 0)
@@ -408,25 +409,11 @@ pci_make_tag(pci_chipset_tag_t pc, int b
pc, bus, device, function);
}
- switch (pci_mode) {
- case 1:
- if (bus >= 256 || device >= 32 || function >= 8)
- panic("%s: bad request", __func__);
-
- tag.mode1 = PCI_MODE1_ENABLE |
- (bus << 16) | (device << 11) | (function << 8);
- return tag;
- case 2:
- if (bus >= 256 || device >= 16 || function >= 8)
- panic("%s: bad request", __func__);
+ KASSERT(bus < 256);
+ KASSERT(device < 32);
+ KASSERT(function < 8);
- tag.mode2.port = 0xc000 | (device << 8);
- tag.mode2.enable = 0xf0 | (function << 1);
- tag.mode2.forward = bus;
- return tag;
- default:
- panic("%s: mode not configured", __func__);
- }
+ return X86_PCITAG_MAKE(bus, device, function);
}
void
@@ -443,26 +430,14 @@ pci_decompose_tag(pci_chipset_tag_t pc,
return;
}
- switch (pci_mode) {
- case 1:
- if (bp != NULL)
- *bp = (tag.mode1 >> 16) & 0xff;
- if (dp != NULL)
- *dp = (tag.mode1 >> 11) & 0x1f;
- if (fp != NULL)
- *fp = (tag.mode1 >> 8) & 0x7;
- return;
- case 2:
- if (bp != NULL)
- *bp = tag.mode2.forward & 0xff;
- if (dp != NULL)
- *dp = (tag.mode2.port >> 8) & 0xf;
- if (fp != NULL)
- *fp = (tag.mode2.enable >> 1) & 0x7;
- return;
- default:
- panic("%s: mode not configured", __func__);
- }
+ if (fp != NULL)
+ *fp = X86_PCITAG_FUNC(tag);
+ if (dp != NULL)
+ *dp = X86_PCITAG_DEV(tag);
+ if (bp != NULL)
+ *bp = X86_PCITAG_BUS(tag);
+
+ return;
}
pcireg_t
@@ -480,6 +455,11 @@ pci_conf_read(pci_chipset_tag_t pc, pcit
return (*ipc->pc_ov->ov_conf_read)(ipc->pc_ctx, pc, tag, reg);
}
+ if (__predict_false(reg >= PCI_CONF_SIZE ||
+ (pci_mode == 2 && X86_PCITAG_DEV(tag) >= 16))) {
+ return 0xffffffff;
+ }
+
pci_conf_lock(&ocl, pci_conf_selector(tag, reg));
data = inl(pci_conf_port(tag, reg));
pci_conf_unlock(&ocl);
@@ -502,6 +482,11 @@ pci_conf_write(pci_chipset_tag_t pc, pci
return;
}
+ if (__predict_false(reg >= PCI_CONF_SIZE ||
+ (pci_mode == 2 && X86_PCITAG_DEV(tag) >= 16))) {
+ return;
+ }
+
pci_conf_lock(&ocl, pci_conf_selector(tag, reg));
outl(pci_conf_port(tag, reg), data);
pci_conf_unlock(&ocl);
@@ -540,7 +525,7 @@ pci_mode_detect(void)
if (PCI_VENDOR(pcim1_quirk_tbl[i].id) == PCI_VENDOR_INVALID)
continue;
- t.mode1 = pcim1_quirk_tbl[i].tag.mode1;
+ t = pcim1_quirk_tbl[i].tag;
idreg = pci_conf_read(NULL, t, PCI_ID_REG); /* needs "pci_mode"
*/
if (idreg == pcim1_quirk_tbl[i].id) {
#ifdef DEBUG
Index: sys/arch/xen/xen/xpci_xenbus.c
===================================================================
RCS file: /cvsroot/src/sys/arch/xen/xen/xpci_xenbus.c,v
retrieving revision 1.12
diff -d -u -a -p -r1.12 xpci_xenbus.c
--- sys/arch/xen/xen/xpci_xenbus.c 5 Dec 2012 01:46:22 -0000 1.12
+++ sys/arch/xen/xen/xpci_xenbus.c 26 Apr 2013 13:20:03 -0000
@@ -384,12 +384,11 @@ pci_bus_maxdevs(pci_chipset_tag_t pc, in
pcitag_t
pci_make_tag(pci_chipset_tag_t pc, int bus, int device, int function)
{
- pcitag_t tag;
- KASSERT((function & ~0x7) == 0);
- KASSERT((device & ~0x1f) == 0);
- KASSERT((bus & ~0xff) == 0);
- tag.mode1 = (bus << 8) | (device << 3) | (function << 0);
- return tag;
+ KASSERT(bus < 256);
+ KASSERT(device < 32);
+ KASSERT(function < 8);
+
+ return X86_PCITAG_MAKE(bus, device, function);
}
void
@@ -397,11 +396,11 @@ pci_decompose_tag(pci_chipset_tag_t pc,
int *bp, int *dp, int *fp)
{
if (bp != NULL)
- *bp = (tag.mode1 >> 8) & 0xff;
+ *bp = X86_PCITAG_BUS(tag);
if (dp != NULL)
- *dp = (tag.mode1 >> 3) & 0x1f;
+ *dp = X86_PCITAG_DEV(tag);
if (fp != NULL)
- *fp = (tag.mode1 >> 0) & 0x7;
+ *fp = X86_PCITAG_FUNC(tag);
return;
}
@@ -433,15 +432,14 @@ static int
xpci_conf_read( pci_chipset_tag_t pc, pcitag_t tag, int reg, int size,
pcireg_t *value)
{
- int bus, dev, func;
struct xen_pci_op op = {
.cmd = XEN_PCI_OP_conf_read,
.domain = 0, /* XXX */
};
- pci_decompose_tag(pc, tag, &bus, &dev, &func);
- DPRINTF(("pci_conf_read %d:%d:%d reg 0x%x", bus, dev, func, reg));
- op.bus = bus;
- op.devfn = (dev << 3) | func;
+ DPRINTF(("xpci_conf_read %d:%d:%d reg 0x%x", X86_PCITAG_BUS(tag),
+ X86_PCITAG_DEV(tag), X86_PCITAG_FUNC(tag), reg));
+ op.bus = X86_PCITAG_BUS(tag);
+ op.devfn = X86_PCITAG_DEVFUNC(tag);
op.offset = reg;
op.size = size;
xpci_do_op(&op);
@@ -489,15 +487,14 @@ static int
xpci_conf_write(pci_chipset_tag_t pc, pcitag_t tag, int reg, int size,
pcireg_t data)
{
- int bus, dev, func;
struct xen_pci_op op = {
.cmd = XEN_PCI_OP_conf_write,
.domain = 0, /* XXX */
};
- pci_decompose_tag(pc, tag, &bus, &dev, &func);
- DPRINTF(("pci_conf_write %d:%d:%d reg 0x%x val 0x%x", bus, dev, func,
reg, data));
- op.bus = bus;
- op.devfn = (dev << 3) | func;
+ DPRINTF(("xpci_conf_write %d:%d:%d reg 0x%x", X86_PCITAG_BUS(tag),
+ X86_PCITAG_DEV(tag), X86_PCITAG_FUNC(tag), reg, data));
+ op.bus = X86_PCITAG_BUS(tag);
+ op.devfn = X86_PCITAG_DEVFUNC(tag);
op.offset = reg;
op.size = size;
op.value = data;
Home |
Main Index |
Thread Index |
Old Index