diff options
author | Hans Rosenfeld <hans.rosenfeld@joyent.com> | 2018-03-26 16:16:18 +0200 |
---|---|---|
committer | Hans Rosenfeld <hans.rosenfeld@joyent.com> | 2018-04-06 15:22:44 +0200 |
commit | 58cc4d26d2f2ea99f0f9aa988f720d8782bd9bb6 (patch) | |
tree | 1fc3f176e3c1ff9f16a7277be2bae949a1be3c68 | |
parent | 6a175f35f25ea47a4b116ad2dd1a0600fdf5a2bc (diff) | |
download | illumos-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.h | 1 | ||||
-rw-r--r-- | usr/src/uts/common/sys/pci_impl.h | 2 | ||||
-rw-r--r-- | usr/src/uts/intel/io/pci/pci_boot.c | 47 | ||||
-rw-r--r-- | usr/src/uts/intel/io/pci/pci_pci.c | 11 |
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); |