summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Rosenfeld <hans.rosenfeld@joyent.com>2018-03-26 16:16:18 +0200
committerHans Rosenfeld <hans.rosenfeld@joyent.com>2018-04-06 15:22:44 +0200
commit58cc4d26d2f2ea99f0f9aa988f720d8782bd9bb6 (patch)
tree1fc3f176e3c1ff9f16a7277be2bae949a1be3c68
parent6a175f35f25ea47a4b116ad2dd1a0600fdf5a2bc (diff)
downloadillumos-joyent-58cc4d26d2f2ea99f0f9aa988f720d8782bd9bb6.tar.gz
OS-6840 want support for PCI BAR size >= 4G
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com> Reviewed by: Patrick Mooney <patrick.mooney@joyent.com> Reviewed by: Robert Mustacchi <rm@joyent.com Approved by: Jerry Jelinek <jerry.jelinek@joyent.com>
-rw-r--r--usr/src/uts/common/sys/pci.h1
-rw-r--r--usr/src/uts/common/sys/pci_impl.h2
-rw-r--r--usr/src/uts/intel/io/pci/pci_boot.c47
-rw-r--r--usr/src/uts/intel/io/pci/pci_pci.c11
4 files changed, 42 insertions, 19 deletions
diff --git a/usr/src/uts/common/sys/pci.h b/usr/src/uts/common/sys/pci.h
index 364fd0f37e..5ed82542c2 100644
--- a/usr/src/uts/common/sys/pci.h
+++ b/usr/src/uts/common/sys/pci.h
@@ -582,6 +582,7 @@ extern "C" {
#define PCI_BASE_TYPE_M 0x00000006 /* type indicator mask */
#define PCI_BASE_PREF_M 0x00000008 /* prefetch mask */
#define PCI_BASE_M_ADDR_M 0xfffffff0 /* memory address mask */
+#define PCI_BASE_M_ADDR64_M 0xfffffffffffffff0ULL /* 64bit mem addr mask */
#define PCI_BASE_IO_ADDR_M 0xfffffffe /* I/O address mask */
#define PCI_BASE_ROM_ADDR_M 0xfffff800 /* ROM address mask */
diff --git a/usr/src/uts/common/sys/pci_impl.h b/usr/src/uts/common/sys/pci_impl.h
index 429d6860bd..c998accbcb 100644
--- a/usr/src/uts/common/sys/pci_impl.h
+++ b/usr/src/uts/common/sys/pci_impl.h
@@ -107,7 +107,7 @@ struct pci_bus_resource {
boolean_t io_reprogram; /* need io reprog on this bus */
boolean_t mem_reprogram; /* need mem reprog on this bus */
boolean_t subtractive; /* subtractive PPB */
- uint_t mem_size; /* existing children required MEM space size */
+ uint64_t mem_size; /* existing children required MEM space size */
uint_t io_size; /* existing children required I/O space size */
};
diff --git a/usr/src/uts/intel/io/pci/pci_boot.c b/usr/src/uts/intel/io/pci/pci_boot.c
index 5e29a66d04..e7d131d25d 100644
--- a/usr/src/uts/intel/io/pci/pci_boot.c
+++ b/usr/src/uts/intel/io/pci/pci_boot.c
@@ -893,8 +893,9 @@ fix_ppb_res(uchar_t secbus, boolean_t prog_sub)
{
uchar_t bus, dev, func;
uchar_t parbus, subbus;
- uint_t io_base, io_limit, mem_base, mem_limit;
- uint_t io_size, mem_size, io_align, mem_align;
+ uint_t io_base, io_limit, mem_base;
+ uint_t io_size, io_align;
+ uint64_t mem_size, mem_align, mem_limit;
uint64_t addr = 0;
int *regp = NULL;
uint_t reglen;
@@ -1049,9 +1050,9 @@ fix_ppb_res(uchar_t secbus, boolean_t prog_sub)
pci_bus_res[parbus].io_reprogram;
cmn_err(CE_NOTE, "!add io-range on subtractive"
- " ppb[%x/%x/%x]: 0x%x ~ 0x%x\n",
- bus, dev, func, (uint32_t)addr,
- (uint32_t)addr + io_size - 1);
+ " ppb[%x/%x/%x]: "
+ "0x%"PRIx64" ~ 0x%"PRIx64"\n",
+ bus, dev, func, addr, addr + io_size - 1);
}
}
/*
@@ -1066,9 +1067,10 @@ fix_ppb_res(uchar_t secbus, boolean_t prog_sub)
pci_bus_res[parbus].mem_reprogram;
cmn_err(CE_NOTE, "!add mem-range on "
- "subtractive ppb[%x/%x/%x]: 0x%x ~ 0x%x\n",
- bus, dev, func, (uint32_t)addr,
- (uint32_t)addr + mem_size - 1);
+ "subtractive ppb[%x/%x/%x]: "
+ "0x%"PRIx64" ~ 0x%"PRIx64"\n",
+ bus, dev, func,
+ addr, addr + mem_size - 1);
}
}
@@ -1197,15 +1199,15 @@ fix_ppb_res(uchar_t secbus, boolean_t prog_sub)
if (is_vga(list, MEM))
continue;
if (mem_base == 0) {
- mem_base = (uint_t)list->ml_address;
+ mem_base = list->ml_address;
mem_base = P2ALIGN(mem_base,
PPB_MEM_ALIGNMENT);
- mem_limit = (uint_t)(list->ml_address +
+ mem_limit = (list->ml_address +
list->ml_size - 1);
} else {
if ((list->ml_address + list->ml_size) >
mem_limit) {
- mem_limit = (uint_t)
+ mem_limit =
(list->ml_address +
list->ml_size - 1);
}
@@ -1265,7 +1267,7 @@ fix_ppb_res(uchar_t secbus, boolean_t prog_sub)
add_ranges_prop(secbus, 1);
cmn_err(CE_NOTE, "!reprogram mem-range on"
- " ppb[%x/%x/%x]: 0x%x ~ 0x%x\n",
+ " ppb[%x/%x/%x]: 0x%x ~ 0x%"PRIx64"\n",
bus, dev, func, mem_base, mem_limit);
}
}
@@ -2360,7 +2362,8 @@ add_reg_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func,
{
uchar_t baseclass, subclass, progclass, header;
ushort_t bar_sz;
- uint_t value = 0, len, devloc;
+ uint64_t value = 0;
+ uint_t devloc;
uint_t base, base_hi, type;
ushort_t offset, end;
int max_basereg, j, reprogram = 0;
@@ -2444,6 +2447,7 @@ add_reg_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func,
/* construct phys hi,med.lo, size hi, lo */
if ((pciide && j < 4) || (base & PCI_BASE_SPACE_IO)) {
int hard_decode = 0;
+ uint_t len;
/* i/o space */
bar_sz = PCI_BAR_SZ_32;
@@ -2528,26 +2532,33 @@ add_reg_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func,
nreg++, nasgn++;
} else {
+ uint64_t len;
/* memory space */
if ((base & PCI_BASE_TYPE_M) == PCI_BASE_TYPE_ALL) {
bar_sz = PCI_BAR_SZ_64;
base_hi = pci_getl(bus, dev, func, offset + 4);
+ pci_putl(bus, dev, func, offset + 4, 0xffffffff);
+ value |= (uint64_t)pci_getl(bus, dev, func,
+ offset + 4) << 32;
+ pci_putl(bus, dev, func, offset + 4, base_hi);
phys_hi = PCI_ADDR_MEM64;
+ value &= PCI_BASE_M_ADDR64_M;
} else {
bar_sz = PCI_BAR_SZ_32;
base_hi = 0;
phys_hi = PCI_ADDR_MEM32;
+ value &= PCI_BASE_M_ADDR_M;
}
/* skip base regs with size of 0 */
- value &= PCI_BASE_M_ADDR_M;
-
if (value == 0)
continue;
len = ((value ^ (value-1)) + 1) >> 1;
regs[nreg].pci_size_low =
- assigned[nasgn].pci_size_low = len;
+ assigned[nasgn].pci_size_low = len & 0xffffffff;
+ regs[nreg].pci_size_hi =
+ assigned[nasgn].pci_size_hi = len >> 32;
phys_hi |= (devloc | offset);
if (base & PCI_BASE_PREF_M)
@@ -2644,7 +2655,7 @@ add_reg_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func,
} else
cmn_err(CE_WARN, "failed to program "
"mem space [%d/%d/%d] BAR@0x%x"
- " length 0x%x",
+ " length 0x%"PRIx64,
bus, dev, func, offset, len);
}
assigned[nasgn].pci_phys_low = base;
@@ -2677,6 +2688,8 @@ add_reg_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func,
value = 0;
if (value != 0) {
+ uint_t len;
+
regs[nreg].pci_phys_hi = (PCI_ADDR_MEM32 | devloc) + offset;
assigned[nasgn].pci_phys_hi = (PCI_RELOCAT_B |
PCI_ADDR_MEM32 | devloc) + offset;
diff --git a/usr/src/uts/intel/io/pci/pci_pci.c b/usr/src/uts/intel/io/pci/pci_pci.c
index 9f0ed4d67f..5d781e40b6 100644
--- a/usr/src/uts/intel/io/pci/pci_pci.c
+++ b/usr/src/uts/intel/io/pci/pci_pci.c
@@ -561,12 +561,21 @@ ppb_ctlops(dev_info_t *dip, dev_info_t *rdip,
if (ctlop == DDI_CTLOPS_NREGS)
*(int *)result = totreg;
else if (ctlop == DDI_CTLOPS_REGSIZE) {
+ uint64_t rs;
+
rn = *(int *)arg;
if (rn >= totreg) {
kmem_free(drv_regp, reglen);
return (DDI_FAILURE);
}
- *(off_t *)result = drv_regp[rn].pci_size_low;
+
+ rs = drv_regp[rn].pci_size_low |
+ ((uint64_t)drv_regp[rn].pci_size_hi << 32);
+ if (rs > OFF_MAX) {
+ kmem_free(drv_regp, reglen);
+ return (DDI_FAILURE);
+ }
+ *(off_t *)result = rs;
}
kmem_free(drv_regp, reglen);