summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIan Moffett <ian@osmora.org>2024-12-17 21:40:34 -0500
committerIan Moffett <ian@osmora.org>2024-12-17 21:44:10 -0500
commitb6cceb40835d6b200aaf8731ba9dac5c3bb62180 (patch)
tree200542caa9d0d0361b389da606f16c1787e605e1
parentf763a3d69cbddab734c51100310504d8113d7ac4 (diff)
kernel/amd64: pci: Allow mapping of 64 bit BARs
Signed-off-by: Ian Moffett <ian@osmora.org>
-rw-r--r--sys/arch/amd64/pci/pci_machdep.c18
-rw-r--r--sys/include/dev/pci/pciregs.h5
2 files changed, 21 insertions, 2 deletions
diff --git a/sys/arch/amd64/pci/pci_machdep.c b/sys/arch/amd64/pci/pci_machdep.c
index ea34b25..1cc2162 100644
--- a/sys/arch/amd64/pci/pci_machdep.c
+++ b/sys/arch/amd64/pci/pci_machdep.c
@@ -103,7 +103,7 @@ int
pci_map_bar(struct pci_device *dev, uint8_t barno, void **vap)
{
uint8_t barreg = pci_get_barreg(dev, barno);
- uintptr_t tmp, bar;
+ uintptr_t tmp, tmp1, bar;
uint32_t size;
if (barreg == 0)
@@ -122,7 +122,21 @@ pci_map_bar(struct pci_device *dev, uint8_t barno, void **vap)
/* Restore old value and map the BAR */
pci_writel(dev, barreg, tmp);
- bar = dev->bar[barno] & PCI_BAR_MEMMASK;
+
+ /*
+ * We'll only need to worry about using one BAR
+ * if the device has a 32-bit MMIO space. However,
+ * with 64-bit MMIO spaces, two BARs are used.
+ */
+ if (PCI_BAR_32(dev->bar[barno])) {
+ bar = dev->bar[barno] & PCI_BAR_MEMMASK;
+ } else {
+ /* Assume 64-bit */
+ tmp = dev->bar[barno] & PCI_BAR_MEMMASK;
+ tmp1 = dev->bar[barno + 1] & PCI_BAR_MEMMASK;
+ bar = COMBINE32(tmp1, tmp);
+ }
+
return bus_map(bar, size, 0, vap);
}
diff --git a/sys/include/dev/pci/pciregs.h b/sys/include/dev/pci/pciregs.h
index 763fade..f0ed4d2 100644
--- a/sys/include/dev/pci/pciregs.h
+++ b/sys/include/dev/pci/pciregs.h
@@ -69,4 +69,9 @@
#define PCI_CAP_MSI 0x05
#define PCI_CAP_MSIX 0x11
+/* PCI BAR defines */
+#define PCI_BAR_TYPE(BAR) ((BAR >> 1) & 3)
+#define PCI_BAR_32(BAR) (PCI_BAR_TYPE(BAR) == 0x0)
+#define PCI_BAR_64(BAR) (PCI_BAR_TYPE(BAR) == 0x2)
+
#endif /* _PCI_PCIREGS_H_ */