diff options
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/cmd/bhyve/mevent.c | 5 | ||||
-rw-r--r-- | usr/src/lib/cfgadm_plugins/ccid/Makefile | 2 | ||||
-rw-r--r-- | usr/src/lib/cfgadm_plugins/ccid/sparc/Makefile | 20 | ||||
-rw-r--r-- | usr/src/lib/cfgadm_plugins/ccid/sparcv9/Makefile | 21 | ||||
-rw-r--r-- | usr/src/lib/libctf/common/ctf_dwarf.c | 40 | ||||
-rw-r--r-- | usr/src/pkg/manifests/driver-misc-ccid.mf | 2 | ||||
-rw-r--r-- | usr/src/tools/stabs/sparc/Makefile | 4 | ||||
-rw-r--r-- | usr/src/tools/stabs/stabs.c | 3 | ||||
-rw-r--r-- | usr/src/uts/i86pc/sys/pci_cfgacc_x86.h | 7 | ||||
-rw-r--r-- | usr/src/uts/intel/io/pci/pci_boot.c | 767 | ||||
-rw-r--r-- | usr/src/uts/intel/io/pci/pci_memlist.c | 11 | ||||
-rw-r--r-- | usr/src/uts/intel/io/pci/pci_resource.c | 116 | ||||
-rw-r--r-- | usr/src/uts/intel/pci_autoconfig/Makefile | 21 | ||||
-rw-r--r-- | usr/src/uts/sparc/Makefile.sparc | 25 | ||||
-rw-r--r-- | usr/src/uts/sparc/ccid/Makefile | 42 |
15 files changed, 781 insertions, 305 deletions
diff --git a/usr/src/cmd/bhyve/mevent.c b/usr/src/cmd/bhyve/mevent.c index 408a648a96..f3ffc6bcaf 100644 --- a/usr/src/cmd/bhyve/mevent.c +++ b/usr/src/cmd/bhyve/mevent.c @@ -713,8 +713,9 @@ mevent_dispatch(void) /* Block awaiting events */ ret = port_get(portfd, &pev, NULL); - if (ret != 0 && errno != EINTR) { - perror("Error return from port_get"); + if (ret != 0) { + if (errno != EINTR) + perror("Error return from port_get"); continue; } diff --git a/usr/src/lib/cfgadm_plugins/ccid/Makefile b/usr/src/lib/cfgadm_plugins/ccid/Makefile index 7d4af31c7d..232f1ec3b5 100644 --- a/usr/src/lib/cfgadm_plugins/ccid/Makefile +++ b/usr/src/lib/cfgadm_plugins/ccid/Makefile @@ -27,7 +27,7 @@ include ../../Makefile.lib -$(INTEL_BLD)SUBDIRS = $(MACH) $(BUILD64) $(MACH64) +SUBDIRS = $(MACH) $(BUILD64) $(MACH64) all := TARGET= all clean := TARGET= clean diff --git a/usr/src/lib/cfgadm_plugins/ccid/sparc/Makefile b/usr/src/lib/cfgadm_plugins/ccid/sparc/Makefile new file mode 100644 index 0000000000..66d7a51776 --- /dev/null +++ b/usr/src/lib/cfgadm_plugins/ccid/sparc/Makefile @@ -0,0 +1,20 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2019, Joyent, Inc. +# + +include ../Makefile.com + +.KEEP_STATE: + +install: all $(ROOTLIBS) $(ROOTLINKS) diff --git a/usr/src/lib/cfgadm_plugins/ccid/sparcv9/Makefile b/usr/src/lib/cfgadm_plugins/ccid/sparcv9/Makefile new file mode 100644 index 0000000000..f2eb3c97a2 --- /dev/null +++ b/usr/src/lib/cfgadm_plugins/ccid/sparcv9/Makefile @@ -0,0 +1,21 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2019, Joyent, Inc. +# + +include ../Makefile.com +include ../../../Makefile.lib.64 + +.KEEP_STATE: + +install: all $(ROOTLIBS64) $(ROOTLINKS64) diff --git a/usr/src/lib/libctf/common/ctf_dwarf.c b/usr/src/lib/libctf/common/ctf_dwarf.c index 3079831715..cbe1661003 100644 --- a/usr/src/lib/libctf/common/ctf_dwarf.c +++ b/usr/src/lib/libctf/common/ctf_dwarf.c @@ -1751,40 +1751,12 @@ ctf_dwarf_create_reference(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp, return (ctf_dwmap_add(cup, *idp, die, B_FALSE)); } -/* - * Get the size of the type of a particular die. Note that this is a simple - * version that doesn't attempt to traverse further than expecting a single - * sized type reference (so no qualifiers etc.). Nor does it attempt to do as - * much as ctf_type_size() - which we cannot use here as that doesn't look up - * dynamic types, and we don't yet want to do a ctf_update(). - */ -static int -ctf_dwarf_get_type_size(ctf_cu_t *cup, Dwarf_Die die, size_t *sizep) -{ - const ctf_type_t *t; - Dwarf_Die tdie; - ctf_id_t tid; - int ret; - - if ((ret = ctf_dwarf_refdie(cup, die, DW_AT_type, &tdie)) != 0) - return (ret); - - if ((ret = ctf_dwarf_convert_type(cup, tdie, &tid, - CTF_ADD_NONROOT)) != 0) - return (ret); - - if ((t = ctf_dyn_lookup_by_id(cup->cu_ctfp, tid)) == NULL) - return (ENOENT); - - *sizep = ctf_get_ctt_size(cup->cu_ctfp, t, NULL, NULL); - return (0); -} - static int ctf_dwarf_create_enum(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp, int isroot) { size_t size = 0; Dwarf_Die child; + Dwarf_Unsigned dw; ctf_id_t id; char *name; int ret; @@ -1795,7 +1767,15 @@ ctf_dwarf_create_enum(ctf_cu_t *cup, Dwarf_Die die, ctf_id_t *idp, int isroot) if (ret == ENOENT) name = NULL; - (void) ctf_dwarf_get_type_size(cup, die, &size); + /* + * Enumerations may have a size associated with them, particularly if + * they're packed. Note, a Dwarf_Unsigned is larger than a size_t on an + * ILP32 system. + */ + if (ctf_dwarf_unsigned(cup, die, DW_AT_byte_size, &dw) == 0 && + dw < SIZE_MAX) { + size = (size_t)dw; + } id = ctf_add_enum(cup->cu_ctfp, isroot, name, size); ctf_dprintf("added enum %s (%d)\n", name, id); diff --git a/usr/src/pkg/manifests/driver-misc-ccid.mf b/usr/src/pkg/manifests/driver-misc-ccid.mf index e0d1ca0155..cdb387df3e 100644 --- a/usr/src/pkg/manifests/driver-misc-ccid.mf +++ b/usr/src/pkg/manifests/driver-misc-ccid.mf @@ -24,7 +24,7 @@ set name=pkg.description \ set name=pkg.summary value="CCID driver" set name=info.classification \ value=org.opensolaris.category.2008:System/Hardware -set name=variant.arch value=i386 +set name=variant.arch value=$(ARCH) dir path=kernel group=sys variant.opensolaris.zone=global dir path=kernel/drv group=sys variant.opensolaris.zone=global dir path=kernel/drv/$(ARCH64) group=sys variant.opensolaris.zone=global diff --git a/usr/src/tools/stabs/sparc/Makefile b/usr/src/tools/stabs/sparc/Makefile index 671caf6b7b..7854779369 100644 --- a/usr/src/tools/stabs/sparc/Makefile +++ b/usr/src/tools/stabs/sparc/Makefile @@ -47,9 +47,9 @@ include ../../Makefile.tools FILEMODE = 555 -CFLAGS += $(CCVERBOSE) - INC_PATH = -I$(STABS_SRC) +# GCC false positive in stabs.c +CERRWARN += -_gcc=-Wno-clobbered LDLIBS += -lm NATIVE_LIBS += libm.so diff --git a/usr/src/tools/stabs/stabs.c b/usr/src/tools/stabs/stabs.c index 54029bf4d7..c5446345d8 100644 --- a/usr/src/tools/stabs/stabs.c +++ b/usr/src/tools/stabs/stabs.c @@ -261,9 +261,8 @@ lookup(int h) static char * whitesp(char *cp) { - char *orig, c; + char c; - orig = cp; for (c = *cp++; isspace(c); c = *cp++) ; --cp; diff --git a/usr/src/uts/i86pc/sys/pci_cfgacc_x86.h b/usr/src/uts/i86pc/sys/pci_cfgacc_x86.h index 74adccb3bc..5fa57068bf 100644 --- a/usr/src/uts/i86pc/sys/pci_cfgacc_x86.h +++ b/usr/src/uts/i86pc/sys/pci_cfgacc_x86.h @@ -21,6 +21,9 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. + * */ #ifndef _SYS_PCI_CFGACC_X86_H @@ -66,8 +69,8 @@ extern "C" { #define IS_AMD_8132_CHIP(vid, did) \ (((vid) == AMD_NTBRDIGE_VID) && \ - (((did) == AMD_8132_BRIDGE_DID)) || \ - (((did) == AMD_8132_IOAPIC_DID))) + (((did) == AMD_8132_BRIDGE_DID) || \ + ((did) == AMD_8132_IOAPIC_DID))) #define MSR_AMD_NB_MMIO_CFG_BADDR 0xc0010058 #define AMD_MMIO_CFG_BADDR_ADDR_MASK 0xFFFFFFF00000ULL diff --git a/usr/src/uts/intel/io/pci/pci_boot.c b/usr/src/uts/intel/io/pci/pci_boot.c index 3996face8b..a034c00411 100644 --- a/usr/src/uts/intel/io/pci/pci_boot.c +++ b/usr/src/uts/intel/io/pci/pci_boot.c @@ -22,6 +22,131 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2019 Joyent, Inc. * Copyright 2019 Western Digital Corporation + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. + */ + +/* + * PCI bus enumeration and device programming are done in several passes. The + * following is a high level overview of this process. + * + * pci_enumerate(reprogram=0) + * The main entry point to PCI bus enumeration is + * pci_enumerate(). This function is invoked + * twice, once to set up the PCI portion of the + * device tree, and then a second time to + * reprogram any devices which were not set up by + * the system firmware. On this first call, the + * reprogram parameter is set to 0. + * add_pci_fixes() + * enumerate_bus_devs(CONFIG_FIX) + * <foreach bus> + * process_devfunc(CONFIG_FIX) + * Some devices need a specific action taking in + * order for subsequent enumeration to be + * successful. add_pci_fixes() retrieves the + * vendor and device IDs for each item on the bus + * and applies fixes as required. It also creates + * a list which is used by undo_pci_fixes() to + * reverse the process later. + * pci_setup_tree() + * enumerate_bus_devs(CONFIG_INFO) + * <foreach bus> + * process_devfunc(CONFIG_INFO) + * <set up most device properties> + * The next stage is to enumerate the bus and set + * up the bulk of the properties for each device. + * This is where the generic properties such as + * 'device-id' are created. + * <if PPB device> + * add_ppb_props() + * For a PCI-to-PCI bridge (ppb) device, any + * memory ranges for IO, memory or pre-fetchable + * memory that have been programmed by the system + * firmware (BIOS/EFI) are retrieved and stored in + * bus-specific lists (pci_bus_res[bus].io_avail, + * mem_avail and pmem_avail). The contents of + * these lists are used to set the initial 'ranges' + * property on the ppb device. Later, as children + * are found for this bridge, resources will be + * removed from these avail lists as necessary. + * This is an initial pass so the ppb devices can + * still be reprogrammed later in fix_ppb_res(). + * <else> + * <add to list of non-PPB devices for the bus> + * Any non-PPB device on the bus is recorded in a + * bus-specific list, to be set up (and possibly + * reprogrammed) later. + * add_reg_props(CONFIG_INFO) + * The final step in this phase is to add the + * initial 'reg' and 'assigned-addresses' + * properties to all devices. At the same time, + * any IO or memory ranges which have been + * assigned to the bus are moved from the avail + * list to the corresponding used one. If no + * resources have been assigned to a device at + * this stage, then it is flagged for subsequent + * reprogramming. + * undo_pci_fixes() + * Any fixes which were applied in add_pci_fixes() + * are now undone before returning, using the + * undo list which was created earier. + * + * pci_enumerate(reprogram=1) + * The second bus enumeration pass is to take care + * of any devices that were not set up by the + * system firmware. These devices were flagged + * during the first pass. This pass is bracketed + * by the same pci fix application and removal as + * the first. + * add_pci_fixes() + * As for first pass. + * pci_reprogram() + * pci_scan_bbn() + * The ACPI namespace is scanned for top-level + * instances of _BBN in order to enumerate the + * root-bridges in the system. If a root bridge is + * found that has not been previously discovered + * (existence inferred through its children) then + * it is added to the system. + * <foreach ROOT bus> + * populate_bus_res() + * Find resources associated with this root bus + * from either ACPI or BIOS tables. See + * find_bus_res() in pci_resource.c + * <foreach bus> + * fix_ppb_res() + * Reprogram pci(e) bridges which have not already + * had resources assigned, or which are under a + * bus that has been flagged for reprogramming. + * If the parent bus has not been flagged, then IO + * space is reprogrammed only if there are no + * assigned IO resources. Memory space is + * reprogrammed only if there is both no assigned + * ordinary memory AND no assigned pre-fetchable + * memory. However, if memory reprogramming is + * necessary then both ordinary and prefetch are + * done together so that both memory ranges end up + * in the avail lists for add_reg_props() to find + * later. + * enumerate_bus_devs(CONFIG_NEW) + * <foreach non-PPB device on the bus> + * add_reg_props(CONFIG_NEW) + * Using the list of non-PPB devices on the bus + * which was assembled during the first pass, add + * or update the 'reg' and 'assigned-address' + * properties for these devices. For devices which + * have been flagged for reprogramming or have no + * assigned resources, this is where resources are + * finally assigned and programmed into the + * device. This can result in these properties + * changing from their previous values. + * <foreach bus> + * add_bus_available_prop() + * Finally, the 'available' properties is set on + * each device, representing that device's final + * unallocated (available) IO and memory ranges. + * undo_pci_fixes() + * As for first pass. */ #include <sys/types.h> @@ -54,7 +179,12 @@ #define pci_putb (*pci_putb_func) #define pci_putw (*pci_putw_func) #define pci_putl (*pci_putl_func) -#define dcmn_err if (pci_boot_debug) cmn_err +#define dcmn_err if (pci_boot_debug != 0) cmn_err +#define bus_debug(bus) (pci_boot_debug != 0 && pci_debug_bus_start != -1 && \ + pci_debug_bus_end != -1 && (bus) >= pci_debug_bus_start && \ + (bus) <= pci_debug_bus_end) +#define dump_memlists(tag, bus) \ + if (bus_debug((bus))) dump_memlists_impl((tag), (bus)) #define CONFIG_INFO 0 #define CONFIG_UPDATE 1 @@ -80,6 +210,15 @@ enum io_mem { MEM }; +/* for get_parbus_res */ + +enum parbus_mem { + PB_IO, + PB_MEM, + PB_PMEM +}; + + /* See AMD-8111 Datasheet Rev 3.03, Page 149: */ #define LPC_IO_CONTROL_REG_1 0x40 #define AMD8111_ENABLENMI (uint8_t)0x80 @@ -106,6 +245,8 @@ extern int pseudo_isa; extern int pci_bios_maxbus; static uchar_t max_dev_pci = 32; /* PCI standard */ int pci_boot_debug = 0; +int pci_debug_bus_start = -1; +int pci_debug_bus_end = -1; extern struct memlist *find_bus_res(int, int); static struct pci_fixundo *undolist = NULL; static int num_root_bus = 0; /* count of root buses */ @@ -185,6 +326,35 @@ typedef struct { nvf_handle_t puafd_handle; int pua_cache_valid = 0; +static void +dump_memlists_impl(const char *tag, int bus) +{ + printf("Memlist dump at %s - bus %x\n", tag, bus); + if (pci_bus_res[bus].io_used != NULL) { + printf(" io_used "); + memlist_dump(pci_bus_res[bus].io_used); + } + if (pci_bus_res[bus].io_avail != NULL) { + printf(" io_avail "); + memlist_dump(pci_bus_res[bus].io_avail); + } + if (pci_bus_res[bus].mem_used != NULL) { + printf(" mem_used "); + memlist_dump(pci_bus_res[bus].mem_used); + } + if (pci_bus_res[bus].mem_avail != NULL) { + printf(" mem_avail "); + memlist_dump(pci_bus_res[bus].mem_avail); + } + if (pci_bus_res[bus].pmem_used != NULL) { + printf(" pmem_used "); + memlist_dump(pci_bus_res[bus].pmem_used); + } + if (pci_bus_res[bus].pmem_avail != NULL) { + printf(" pmem_avail "); + memlist_dump(pci_bus_res[bus].pmem_avail); + } +} /*ARGSUSED*/ static ACPI_STATUS @@ -230,7 +400,7 @@ pci_process_acpi_device(ACPI_HANDLE hdl, UINT32 level, void *ctx, void **rv) */ if ((busnum < 0) || (busnum > pci_bios_maxbus)) { dcmn_err(CE_NOTE, - "pci_process_acpi_device: invalid _BBN 0x%x\n", + "pci_process_acpi_device: invalid _BBN 0x%x", busnum); return (AE_CTRL_DEPTH); } @@ -718,33 +888,55 @@ setup_bus_res(int bus) (void) memlist_remove(&pci_bus_res[bus].bus_avail, bus, 1); } +/* + * Allocate a resource from the parent bus + */ static uint64_t -get_parbus_io_res(uchar_t parbus, uchar_t bus, uint64_t size, uint64_t align) +get_parbus_res(uchar_t parbus, uchar_t bus, uint64_t size, uint64_t align, + enum parbus_mem mem) { uint64_t addr = 0; uchar_t res_bus; /* * Skip root(peer) buses in multiple-root-bus systems when - * ACPI resource discovery was not successfully done. + * ACPI resource discovery was not successfully done; the + * initial resources set on each root bus might not be correctly + * accounted for in this case. */ if ((pci_bus_res[parbus].par_bus == (uchar_t)-1) && - (num_root_bus > 1) && (acpi_resource_discovery <= 0)) + (num_root_bus > 1) && (acpi_resource_discovery <= 0)) { return (0); + } + /* + * Set res_bus to the bus from which resources should be allocated. + * A device under a subtractive PPB can allocate resources from its + * parent bus if there are no resources available on its own bus, so + * iterate up the chain until resources are found or the root is + * reached. + */ res_bus = parbus; while (pci_bus_res[res_bus].subtractive) { - if (pci_bus_res[res_bus].io_avail) + if (mem == PB_IO && pci_bus_res[res_bus].io_avail != NULL) + break; + if (mem == PB_MEM && pci_bus_res[res_bus].mem_avail != NULL) + break; + if (mem == PB_PMEM && pci_bus_res[res_bus].pmem_avail != NULL) break; res_bus = pci_bus_res[res_bus].par_bus; + /* Has the root bus been reached? */ if (res_bus == (uchar_t)-1) - break; /* root bus already */ + break; } - if (pci_bus_res[res_bus].io_avail) { + switch (mem) { + case PB_IO: + if (pci_bus_res[res_bus].io_avail == NULL) + break; addr = memlist_find(&pci_bus_res[res_bus].io_avail, size, align); - if (addr) { + if (addr > 0) { memlist_insert(&pci_bus_res[res_bus].io_used, addr, size); @@ -755,38 +947,13 @@ get_parbus_io_res(uchar_t parbus, uchar_t bus, uint64_t size, uint64_t align) /* add the new resource */ memlist_insert(&pci_bus_res[bus].io_avail, addr, size); } - } - - return (addr); -} - -static uint64_t -get_parbus_mem_res(uchar_t parbus, uchar_t bus, uint64_t size, uint64_t align) -{ - uint64_t addr = 0; - uchar_t res_bus; - - /* - * Skip root(peer) buses in multiple-root-bus systems when - * ACPI resource discovery was not successfully done. - */ - if ((pci_bus_res[parbus].par_bus == (uchar_t)-1) && - (num_root_bus > 1) && (acpi_resource_discovery <= 0)) - return (0); - - res_bus = parbus; - while (pci_bus_res[res_bus].subtractive) { - if (pci_bus_res[res_bus].mem_avail) + break; + case PB_MEM: + if (pci_bus_res[res_bus].mem_avail == NULL) break; - res_bus = pci_bus_res[res_bus].par_bus; - if (res_bus == (uchar_t)-1) - break; /* root bus already */ - } - - if (pci_bus_res[res_bus].mem_avail) { addr = memlist_find(&pci_bus_res[res_bus].mem_avail, size, align); - if (addr) { + if (addr > 0) { memlist_insert(&pci_bus_res[res_bus].mem_used, addr, size); (void) memlist_remove(&pci_bus_res[res_bus].pmem_avail, @@ -799,6 +966,27 @@ get_parbus_mem_res(uchar_t parbus, uchar_t bus, uint64_t size, uint64_t align) /* add the new resource */ memlist_insert(&pci_bus_res[bus].mem_avail, addr, size); } + break; + case PB_PMEM: + if (pci_bus_res[res_bus].pmem_avail == NULL) + break; + addr = memlist_find(&pci_bus_res[res_bus].pmem_avail, + size, align); + if (addr > 0) { + memlist_insert(&pci_bus_res[res_bus].pmem_used, + addr, size); + (void) memlist_remove(&pci_bus_res[res_bus].mem_avail, + addr, size); + + /* free the old resource */ + memlist_free_all(&pci_bus_res[bus].pmem_avail); + memlist_free_all(&pci_bus_res[bus].pmem_used); + + /* add the new resource */ + memlist_insert(&pci_bus_res[bus].pmem_avail, + addr, size); + } + break; } return (addr); @@ -842,33 +1030,54 @@ get_pci_cap(uchar_t bus, uchar_t dev, uchar_t func, uint8_t cap_id) * Does this resource element live in the legacy VGA range? */ -int +static boolean_t is_vga(struct memlist *elem, enum io_mem io) { - if (io == IO) { if ((elem->ml_address == 0x3b0 && elem->ml_size == 0xc) || (elem->ml_address == 0x3c0 && elem->ml_size == 0x20)) - return (1); + return (B_TRUE); } else { if (elem->ml_address == 0xa0000 && elem->ml_size == 0x20000) - return (1); + return (B_TRUE); } - return (0); + return (B_FALSE); } /* * Does this entire resource list consist only of legacy VGA resources? */ -int +static boolean_t list_is_vga_only(struct memlist *l, enum io_mem io) { do { if (!is_vga(l, io)) - return (0); + return (B_FALSE); } while ((l = l->ml_next) != NULL); - return (1); + return (B_TRUE); +} + +/* + * Find the start and end addresses that cover the range for all list entries, + * excluding legacy VGA addresses. Relies on the list being sorted. + */ +static void +pci_memlist_range(struct memlist *list, enum io_mem iomem, uint64_t *basep, + uint64_t *limitp) +{ + *limitp = *basep = 0; + + for (; list != NULL; list = list->ml_next) { + if (is_vga(list, iomem)) + continue; + + if (*basep == 0) + *basep = list->ml_address; + + if (list->ml_address + list->ml_size >= *limitp) + *limitp = list->ml_address + list->ml_size - 1; + } } /* @@ -876,7 +1085,7 @@ list_is_vga_only(struct memlist *l, enum io_mem io) * to reprogram the bridge when its * i) SECBUS == SUBBUS || * ii) IOBASE > IOLIM || - * iii) MEMBASE > MEMLIM + * iii) MEMBASE > MEMLIM && PMEMBASE > PMEMLIM * This must be done after one full pass through the PCI tree to collect * all BIOS-configured resources, so that we know what resources are * free and available to assign to the unconfigured PPBs. @@ -889,13 +1098,15 @@ fix_ppb_res(uchar_t secbus, boolean_t prog_sub) uint_t io_base, io_limit, mem_base; uint_t io_size, io_align; uint64_t mem_size, mem_align, mem_limit; + uint64_t pmem_size, pmem_base, pmem_limit; uint64_t addr = 0; int *regp = NULL; - uint_t reglen; + uint_t val, reglen; int rv, cap_ptr, physhi; dev_info_t *dip; uint16_t cmd_reg; - struct memlist *list, *scratch_list; + struct memlist *scratch_list; + boolean_t reprogram_mem; /* skip root (peer) PCI busses */ if (pci_bus_res[secbus].par_bus == (uchar_t)-1) @@ -921,6 +1132,9 @@ fix_ppb_res(uchar_t secbus, boolean_t prog_sub) dev = (uchar_t)PCI_REG_DEV_G(physhi); bus = (uchar_t)PCI_REG_BUS_G(physhi); + dump_memlists("fix_ppb_res start bus", bus); + dump_memlists("fix_ppb_res start secbus", secbus); + /* * If pcie bridge, check to see if link is enabled */ @@ -930,7 +1144,7 @@ fix_ppb_res(uchar_t secbus, boolean_t prog_sub) (uint16_t)cap_ptr + PCIE_LINKCTL); if (cmd_reg & PCIE_LINKCTL_LINK_DISABLE) { dcmn_err(CE_NOTE, - "!fix_ppb_res: ppb[%x/%x/%x] link is disabled.\n", + "!fix_ppb_res: ppb[%x/%x/%x] link is disabled.", bus, dev, func); return; } @@ -970,7 +1184,7 @@ fix_ppb_res(uchar_t secbus, boolean_t prog_sub) add_bus_range_prop(secbus); cmn_err(CE_NOTE, "!reprogram bus-range on ppb" - "[%x/%x/%x]: %x ~ %x\n", bus, dev, func, + "[%x/%x/%x]: %x ~ %x", bus, dev, func, secbus, subbus); } } @@ -1035,8 +1249,8 @@ fix_ppb_res(uchar_t secbus, boolean_t prog_sub) * Add an arbitrary I/O resource to the subtractive PPB */ if (pci_bus_res[secbus].io_avail == NULL) { - addr = get_parbus_io_res(parbus, secbus, io_size, - io_align); + addr = get_parbus_res(parbus, secbus, io_size, + io_align, PB_IO); if (addr) { add_ranges_prop(secbus, 1); pci_bus_res[secbus].io_reprogram = @@ -1044,7 +1258,7 @@ fix_ppb_res(uchar_t secbus, boolean_t prog_sub) cmn_err(CE_NOTE, "!add io-range on subtractive" " ppb[%x/%x/%x]: " - "0x%"PRIx64" ~ 0x%"PRIx64"\n", + "0x%"PRIx64" ~ 0x%"PRIx64"", bus, dev, func, addr, addr + io_size - 1); } } @@ -1052,8 +1266,8 @@ fix_ppb_res(uchar_t secbus, boolean_t prog_sub) * Add an arbitrary memory resource to the subtractive PPB */ if (pci_bus_res[secbus].mem_avail == NULL) { - addr = get_parbus_mem_res(parbus, secbus, mem_size, - mem_align); + addr = get_parbus_res(parbus, secbus, mem_size, + mem_align, PB_MEM); if (addr) { add_ranges_prop(secbus, 1); pci_bus_res[secbus].mem_reprogram = @@ -1061,7 +1275,7 @@ fix_ppb_res(uchar_t secbus, boolean_t prog_sub) cmn_err(CE_NOTE, "!add mem-range on " "subtractive ppb[%x/%x/%x]: " - "0x%"PRIx64" ~ 0x%"PRIx64"\n", + "0x%"PRIx64" ~ 0x%"PRIx64"", bus, dev, func, addr, addr + mem_size - 1); } @@ -1075,11 +1289,11 @@ fix_ppb_res(uchar_t secbus, boolean_t prog_sub) * parent bus needed reprogramming and so do we, or because I/O space is * disabled in base/limit or command register. */ - io_base = pci_getb(bus, dev, func, PCI_BCNF_IO_BASE_LOW); + val = io_base = pci_getb(bus, dev, func, PCI_BCNF_IO_BASE_LOW); io_limit = pci_getb(bus, dev, func, PCI_BCNF_IO_LIMIT_LOW); io_base = (io_base & PCI_BCNF_IO_MASK) << PCI_BCNF_IO_SHIFT; io_limit = ((io_limit & PCI_BCNF_IO_MASK) << PCI_BCNF_IO_SHIFT) | 0xfff; - if ((io_base & PCI_BCNF_ADDR_MASK) == PCI_BCNF_IO_32BIT) { + if ((val & PCI_BCNF_ADDR_MASK) == PCI_BCNF_IO_32BIT) { uint16_t io_base_hi, io_limit_hi; io_base_hi = pci_getw(bus, dev, func, PCI_BCNF_IO_BASE_HI); io_limit_hi = pci_getw(bus, dev, func, PCI_BCNF_IO_LIMIT_HI); @@ -1096,35 +1310,26 @@ fix_ppb_res(uchar_t secbus, boolean_t prog_sub) (io_base > io_limit) || (!(cmd_reg & PCI_COMM_IO))) && !list_is_vga_only(scratch_list, IO)) { + if (pci_bus_res[secbus].io_used) { memlist_subsume(&pci_bus_res[secbus].io_used, &pci_bus_res[secbus].io_avail); } + if (pci_bus_res[secbus].io_avail && - (!pci_bus_res[parbus].io_reprogram) && - (!pci_bus_res[parbus].subtractive)) { - /* rechoose old io ports info */ - list = pci_bus_res[secbus].io_avail; - io_base = 0; - do { - if (is_vga(list, IO)) - continue; - if (!io_base) { - io_base = (uint_t)list->ml_address; - io_limit = (uint_t)list->ml_address + - list->ml_size - 1; - io_base = - P2ALIGN(io_base, PPB_IO_ALIGNMENT); - } else { - if (list->ml_address + list->ml_size > - io_limit) { - io_limit = (uint_t) - (list->ml_address + - list->ml_size - 1); - } - } - } while ((list = list->ml_next) != NULL); + !pci_bus_res[parbus].io_reprogram && + !pci_bus_res[parbus].subtractive) { + /* re-choose old io ports info */ + + uint64_t base, limit; + + pci_memlist_range(pci_bus_res[secbus].io_avail, + IO, &base, &limit); + io_base = (uint_t)base; + io_limit = (uint_t)limit; + /* 4K aligned */ + io_base = P2ALIGN(base, PPB_IO_ALIGNMENT); io_limit = P2ROUNDUP(io_limit, PPB_IO_ALIGNMENT) - 1; io_size = io_limit - io_base + 1; ASSERT(io_base <= io_limit); @@ -1138,8 +1343,8 @@ fix_ppb_res(uchar_t secbus, boolean_t prog_sub) pci_bus_res[secbus].io_reprogram = B_TRUE; } else { /* get new io ports from parent bus */ - addr = get_parbus_io_res(parbus, secbus, io_size, - io_align); + addr = get_parbus_res(parbus, secbus, io_size, + io_align, PB_IO); if (addr) { io_base = addr; io_limit = addr + io_size - 1; @@ -1157,7 +1362,7 @@ fix_ppb_res(uchar_t secbus, boolean_t prog_sub) add_ranges_prop(secbus, 1); cmn_err(CE_NOTE, "!reprogram io-range on" - " ppb[%x/%x/%x]: 0x%x ~ 0x%x\n", + " ppb[%x/%x/%x]: 0x%x ~ 0x%x", bus, dev, func, io_base, io_limit); } } @@ -1166,46 +1371,76 @@ fix_ppb_res(uchar_t secbus, boolean_t prog_sub) /* * Check memory space as we did I/O space. */ + mem_base = (uint_t)pci_getw(bus, dev, func, PCI_BCNF_MEM_BASE); - mem_base = (mem_base & 0xfff0) << 16; + mem_base = (mem_base & PCI_BCNF_MEM_MASK) << PCI_BCNF_MEM_SHIFT; mem_limit = (uint_t)pci_getw(bus, dev, func, PCI_BCNF_MEM_LIMIT); - mem_limit = ((mem_limit & 0xfff0) << 16) | 0xfffff; + mem_limit = ((mem_limit & PCI_BCNF_MEM_MASK) << PCI_BCNF_MEM_SHIFT) + | 0xfffff; + + val = (uint_t)pci_getw(bus, dev, func, PCI_BCNF_PF_LIMIT_LOW); + pmem_limit = ((val & PCI_BCNF_MEM_MASK) << PCI_BCNF_MEM_SHIFT) | + 0xfffff; + val = (uint_t)pci_getw(bus, dev, func, PCI_BCNF_PF_BASE_LOW); + pmem_base = ((val & PCI_BCNF_MEM_MASK) << PCI_BCNF_MEM_SHIFT); + + if ((val & PCI_BCNF_ADDR_MASK) == PCI_BCNF_PF_MEM_64BIT) { + uint32_t pf_addr_hi, pf_limit_hi; + + pf_addr_hi = pci_getl(bus, dev, func, PCI_BCNF_PF_BASE_HIGH); + pf_limit_hi = pci_getl(bus, dev, func, PCI_BCNF_PF_LIMIT_HIGH); + pmem_base |= (uint64_t)pf_addr_hi << 32; + pmem_limit |= (uint64_t)pf_limit_hi << 32; + } + + /* + * Reprogram memory if any of: + * + * - The parent bus is flagged for reprogramming; + * - Mem space is currently disabled in the command register; + * - Both mem and pmem space are disabled via base/limit. + * + * Always reprogram both mem and pmem together since this leaves + * resources in the 'avail' list for add_reg_props() to subsequently + * find and assign. + */ + reprogram_mem = pci_bus_res[parbus].mem_reprogram || + !(cmd_reg & PCI_COMM_MAE) || + (mem_base > mem_limit && pmem_base > pmem_limit); scratch_list = memlist_dup(pci_bus_res[secbus].mem_avail); memlist_merge(&pci_bus_res[secbus].mem_used, &scratch_list); - if ((pci_bus_res[parbus].mem_reprogram || - (mem_base > mem_limit) || - (!(cmd_reg & PCI_COMM_MAE))) && - !list_is_vga_only(scratch_list, MEM)) { + if (reprogram_mem && !list_is_vga_only(scratch_list, MEM)) { + if (pci_bus_res[secbus].mem_used) { memlist_subsume(&pci_bus_res[secbus].mem_used, &pci_bus_res[secbus].mem_avail); } + + /* + * At this point, if the parent bus has not been + * reprogrammed and there is memory in this bus' available + * pool, then it can just be re-used. Otherwise a new range + * is requested from the parent bus - note that + * get_parbus_res() also takes care of constructing new + * avail and used lists for the bus. + * + * For a subtractive parent bus, always request a fresh + * memory range. + */ if (pci_bus_res[secbus].mem_avail && - (!pci_bus_res[parbus].mem_reprogram) && - (!pci_bus_res[parbus].subtractive)) { - /* rechoose old mem resource */ - list = pci_bus_res[secbus].mem_avail; - mem_base = 0; - do { - if (is_vga(list, MEM)) - continue; - if (mem_base == 0) { - mem_base = list->ml_address; - mem_base = P2ALIGN(mem_base, - PPB_MEM_ALIGNMENT); - mem_limit = (list->ml_address + - list->ml_size - 1); - } else { - if ((list->ml_address + list->ml_size) > - mem_limit) { - mem_limit = - (list->ml_address + - list->ml_size - 1); - } - } - } while ((list = list->ml_next) != NULL); + !pci_bus_res[parbus].mem_reprogram && + !pci_bus_res[parbus].subtractive) { + /* re-choose old mem resource */ + + uint64_t base; + + pci_memlist_range(pci_bus_res[secbus].mem_avail, + MEM, &base, &mem_limit); + mem_base = (uint_t)base; + + mem_base = P2ALIGN(mem_base, PPB_MEM_ALIGNMENT); mem_limit = P2ROUNDUP(mem_limit, PPB_MEM_ALIGNMENT) - 1; mem_size = mem_limit + 1 - mem_base; ASSERT(mem_base <= mem_limit); @@ -1219,54 +1454,126 @@ fix_ppb_res(uchar_t secbus, boolean_t prog_sub) pci_bus_res[secbus].mem_reprogram = B_TRUE; } else { /* get new mem resource from parent bus */ - addr = get_parbus_mem_res(parbus, secbus, mem_size, - mem_align); + addr = get_parbus_res(parbus, secbus, mem_size, + mem_align, PB_MEM); if (addr) { mem_base = addr; mem_limit = addr + mem_size - 1; pci_bus_res[secbus].mem_reprogram = B_TRUE; } } + } + memlist_free_all(&scratch_list); + + /* Prefetch memory */ - if (pci_bus_res[secbus].mem_reprogram) { - /* reprogram PPB MEM regs */ - pci_putw(bus, dev, func, PCI_BCNF_MEM_BASE, - (uint16_t)((mem_base>>16) & 0xfff0)); - pci_putw(bus, dev, func, PCI_BCNF_MEM_LIMIT, - (uint16_t)((mem_limit>>16) & 0xfff0)); + scratch_list = memlist_dup(pci_bus_res[secbus].pmem_avail); + memlist_merge(&pci_bus_res[secbus].pmem_used, &scratch_list); + + /* + * Only reprogram prefetchable memory If the MEM access bit is + * currently enabled. If it is not, then prefetchable memory will be + * disabled anyway via base/limit below. + */ + if (reprogram_mem && !list_is_vga_only(scratch_list, MEM) && + (cmd_reg & PCI_COMM_MAE)) { + + if (pci_bus_res[secbus].pmem_used) { + memlist_subsume(&pci_bus_res[secbus].pmem_used, + &pci_bus_res[secbus].pmem_avail); + } + + /* Same logic as for non-prefetch memory, see above */ + if (pci_bus_res[secbus].pmem_avail && + !pci_bus_res[parbus].mem_reprogram && + !pci_bus_res[parbus].subtractive) { + /* re-choose old mem resource */ + + pci_memlist_range(pci_bus_res[secbus].pmem_avail, + MEM, &pmem_base, &pmem_limit); + + pmem_base = P2ALIGN(pmem_base, PPB_MEM_ALIGNMENT); + pmem_limit = P2ROUNDUP(pmem_limit, + PPB_MEM_ALIGNMENT) - 1; + pmem_size = pmem_limit + 1 - pmem_base; + ASSERT(pmem_base <= pmem_limit); + memlist_free_all(&pci_bus_res[secbus].pmem_avail); + memlist_insert(&pci_bus_res[secbus].pmem_avail, + pmem_base, pmem_size); + memlist_insert(&pci_bus_res[parbus].pmem_used, + pmem_base, pmem_size); + (void) memlist_remove(&pci_bus_res[parbus].pmem_avail, + pmem_base, pmem_size); + pci_bus_res[secbus].mem_reprogram = B_TRUE; + } else { + /* get new mem resource from parent bus */ + addr = get_parbus_res(parbus, secbus, mem_size, + mem_align, PB_PMEM); + if (addr) { + pmem_base = addr; + pmem_limit = addr + mem_size - 1; + pci_bus_res[secbus].mem_reprogram = B_TRUE; + } + } + } + + memlist_free_all(&scratch_list); + + if (pci_bus_res[secbus].mem_reprogram) { + /* reprogram PPB MEM regs */ + + pci_putw(bus, dev, func, PCI_BCNF_MEM_BASE, + (uint16_t)((mem_base >> PCI_BCNF_MEM_SHIFT) & + PCI_BCNF_MEM_MASK)); + pci_putw(bus, dev, func, PCI_BCNF_MEM_LIMIT, + (uint16_t)((mem_limit >> PCI_BCNF_MEM_SHIFT) & + PCI_BCNF_MEM_MASK)); + + cmn_err(CE_NOTE, "!reprogram mem-range on" + " ppb[%x/%x/%x]: 0x%x ~ 0x%"PRIx64"", + bus, dev, func, mem_base, mem_limit); + + if (!(cmd_reg & PCI_COMM_MAE)) { /* - * Disable PMEM window by setting base > limit. - * We currently don't reprogram the PMEM like we've - * done for I/O and MEM. (Devices that support prefetch - * can use non-prefetch MEM.) Anyway, if the MEM access - * bit is initially disabled by BIOS, we disable the - * PMEM window manually by setting PMEM base > PMEM - * limit here, in case there are incorrect values in - * them from BIOS, so that we won't get in trouble once - * the MEM access bit is enabled at the end of this - * function. + * If the MEM access bit is initially disabled by BIOS, + * we disable the PMEM window manually by setting PMEM + * base > PMEM limit here, in case there are incorrect + * values in them from BIOS, so that we won't get in + * trouble once the MEM access bit is enabled at the + * end of this function. */ - if (!(cmd_reg & PCI_COMM_MAE)) { - pci_putw(bus, dev, func, PCI_BCNF_PF_BASE_LOW, - 0xfff0); - pci_putw(bus, dev, func, PCI_BCNF_PF_LIMIT_LOW, - 0x0); - pci_putl(bus, dev, func, PCI_BCNF_PF_BASE_HIGH, - 0xffffffff); - pci_putl(bus, dev, func, PCI_BCNF_PF_LIMIT_HIGH, - 0x0); - } + pci_putw(bus, dev, func, PCI_BCNF_PF_BASE_LOW, 0xfff0); + pci_putw(bus, dev, func, PCI_BCNF_PF_LIMIT_LOW, 0x0); + pci_putl(bus, dev, func, PCI_BCNF_PF_BASE_HIGH, + 0xffffffff); + pci_putl(bus, dev, func, PCI_BCNF_PF_LIMIT_HIGH, 0x0); - add_ranges_prop(secbus, 1); + } else { - cmn_err(CE_NOTE, "!reprogram mem-range on" - " ppb[%x/%x/%x]: 0x%x ~ 0x%"PRIx64"\n", - bus, dev, func, mem_base, mem_limit); + pci_putw(bus, dev, func, PCI_BCNF_PF_BASE_LOW, + ((pmem_base & 0xffffffff) >> PCI_BCNF_MEM_SHIFT) & + PCI_BCNF_MEM_MASK); + pci_putl(bus, dev, func, PCI_BCNF_PF_BASE_HIGH, + pmem_base >> 32); + + pci_putw(bus, dev, func, PCI_BCNF_PF_LIMIT_LOW, + ((pmem_limit & 0xffffffff) >> PCI_BCNF_MEM_SHIFT) & + PCI_BCNF_MEM_MASK); + pci_putl(bus, dev, func, PCI_BCNF_PF_LIMIT_HIGH, + pmem_limit >> 32); + + cmn_err(CE_NOTE, "!reprogram pmem-range on" + " ppb[%x/%x/%x]: 0x%"PRIx64" ~ 0x%"PRIx64"", + bus, dev, func, pmem_base, pmem_limit); } + + add_ranges_prop(secbus, 1); } - memlist_free_all(&scratch_list); cmd_enable: + dump_memlists("fix_ppb_res end bus", bus); + dump_memlists("fix_ppb_res end secbus", secbus); + if (pci_bus_res[secbus].io_avail) cmd_reg |= PCI_COMM_IO | PCI_COMM_ME; if (pci_bus_res[secbus].mem_avail) @@ -1467,7 +1774,6 @@ populate_bus_res(uchar_t bus) add_ranges_prop(bus, 0); } - /* * Create top-level bus dips, i.e. /pci@0,0, /pci@1,0... */ @@ -1513,12 +1819,16 @@ enumerate_bus_devs(uchar_t bus, int config_op) ushort_t venid; struct pci_devfunc *devlist = NULL, *entry; - if (config_op == CONFIG_NEW) { - dcmn_err(CE_NOTE, "configuring pci bus 0x%x", bus); - } else if (config_op == CONFIG_FIX) { - dcmn_err(CE_NOTE, "fixing devices on pci bus 0x%x", bus); - } else - dcmn_err(CE_NOTE, "enumerating pci bus 0x%x", bus); + if (pci_debug_bus_start == -1 || bus_debug(bus)) { + if (config_op == CONFIG_NEW) { + dcmn_err(CE_NOTE, "configuring pci bus 0x%x", bus); + } else if (config_op == CONFIG_FIX) { + dcmn_err(CE_NOTE, + "fixing devices on pci bus 0x%x", bus); + } else { + dcmn_err(CE_NOTE, "enumerating pci bus 0x%x", bus); + } + } if (config_op == CONFIG_NEW) { devlist = (struct pci_devfunc *)pci_bus_res[bus].privdata; @@ -1542,9 +1852,6 @@ enumerate_bus_devs(uchar_t bus, int config_op) nfunc = 1; for (func = 0; func < nfunc; func++) { - dcmn_err(CE_NOTE, "probing dev 0x%x, func 0x%x", - dev, func); - venid = pci_getw(bus, dev, func, PCI_CONF_VENID); if ((venid == 0xffff) || (venid == 0)) { @@ -2388,7 +2695,7 @@ 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; - uint64_t value = 0; + uint64_t value = 0, fbase; uint_t devloc; uint_t base, base_hi, type; ushort_t offset, end; @@ -2410,6 +2717,8 @@ add_reg_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func, pmem_avail = &pci_bus_res[bus].pmem_avail; pmem_used = &pci_bus_res[bus].pmem_used; + dump_memlists("add_reg_props start", bus); + devloc = (uint_t)bus << 16 | (uint_t)dev << 11 | (uint_t)func << 8; regs[0].pci_phys_hi = devloc; nreg = 1; /* rest of regs[0] is all zero */ @@ -2454,7 +2763,7 @@ add_reg_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func, end = PCI_CONF_BASE0 + max_basereg * sizeof (uint_t); for (j = 0, offset = PCI_CONF_BASE0; offset < end; j++, offset += bar_sz) { - uint_t command; + uint_t command = 0; /* determine the size of the address space */ base = pci_getl(bus, dev, func, offset); @@ -2612,51 +2921,63 @@ add_reg_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func, */ if ((*pmem_avail && (phys_hi & PCI_PREFETCH_B)) || - *mem_avail) + *mem_avail) { break; + } } } regs[nreg].pci_phys_hi = assigned[nasgn].pci_phys_hi = phys_hi; assigned[nasgn].pci_phys_hi |= PCI_RELOCAT_B; - assigned[nasgn].pci_phys_mid = base_hi; type = base & ~PCI_BASE_M_ADDR_M; base &= PCI_BASE_M_ADDR_M; + fbase = (((uint64_t)base_hi) << 32) | base; + if (config_op == CONFIG_INFO) { /* take out of the resource map of the bus */ - if (base != 0) { + if (fbase != 0) { /* remove from PMEM and MEM space */ (void) memlist_remove(mem_avail, - base, len); + fbase, len); (void) memlist_remove(pmem_avail, - base, len); + fbase, len); /* only note as used in correct map */ if (phys_hi & PCI_PREFETCH_B) memlist_insert(pmem_used, - base, len); + fbase, len); else memlist_insert(mem_used, - base, len); + fbase, len); } else { reprogram = 1; } pci_bus_res[bus].mem_size += len; - } else if ((*mem_avail && base == 0) || - pci_bus_res[bus].mem_reprogram) { + } else if (pci_bus_res[bus].mem_reprogram || + (fbase == 0 && + (*mem_avail != NULL || *pmem_avail != NULL))) { + + fbase = 0; + /* * When desired, attempt a prefetchable * allocation first */ - if (phys_hi & PCI_PREFETCH_B) { - base = (uint_t)memlist_find(pmem_avail, + if ((phys_hi & PCI_PREFETCH_B) && + *pmem_avail != NULL) { + fbase = memlist_find(pmem_avail, len, len); - if (base != 0) { + if (fbase != 0) { memlist_insert(pmem_used, - base, len); - (void) memlist_remove(mem_avail, - base, len); + fbase, len); + (void) memlist_remove( + pmem_avail, fbase, len); + cmn_err(CE_NOTE, "!program " + "[%x/%x/%x] BAR@0x%x" + " 0x%lx length 0x%lx", + bus, dev, func, offset, + fbase, len); } } /* @@ -2664,28 +2985,58 @@ add_reg_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func, * desired, or failed, attempt ordinary * memory allocation */ - if (base == 0) { - base = (uint_t)memlist_find(mem_avail, + if (fbase == 0 && *mem_avail != NULL) { + fbase = memlist_find(mem_avail, len, len); - if (base != 0) { + if (fbase != 0) { memlist_insert(mem_used, - base, len); + fbase, len); (void) memlist_remove( - pmem_avail, base, len); + mem_avail, fbase, len); + cmn_err(CE_NOTE, "!program " + "[%x/%x/%x] BAR@0x%x" + " 0x%lx length 0x%lx", + bus, dev, func, offset, + fbase, len); } } - if (base != 0) { + + base_hi = fbase >> 32; + base = fbase & 0xffffffff; + + if (fbase != 0) { pci_putl(bus, dev, func, offset, base | type); base = pci_getl(bus, dev, func, offset); + + if (bar_sz == PCI_BAR_SZ_64) { + pci_putl(bus, dev, func, + offset + 4, base_hi); + base_hi = pci_getl(bus, dev, + func, offset + 4); + } + base &= PCI_BASE_M_ADDR_M; - } else + } else { cmn_err(CE_WARN, "failed to program " - "mem space [%d/%d/%d] BAR@0x%x" + "mem space [%x/%x/%x] BAR@0x%x" " length 0x%"PRIx64, bus, dev, func, offset, len); + } } + + assigned[nasgn].pci_phys_mid = base_hi; assigned[nasgn].pci_phys_low = base; + + dcmn_err(CE_NOTE, + "![%x/%x/%x] --- %08x.%x.%x.%x.%x", + bus, dev, func, + assigned[nasgn].pci_phys_hi, + assigned[nasgn].pci_phys_mid, + assigned[nasgn].pci_phys_low, + assigned[nasgn].pci_size_hi, + assigned[nasgn].pci_size_low); + nreg++, nasgn++; } } @@ -2803,6 +3154,8 @@ add_reg_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func, } done: + dump_memlists("add_reg_props end", bus); + (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, "reg", (int *)regs, nreg * sizeof (pci_regspec_t) / sizeof (int)); (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, dip, @@ -2826,6 +3179,9 @@ add_ppb_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func, ASSERT(secbus <= subbus); + dump_memlists("add_ppb_props start bus", bus); + dump_memlists("add_ppb_props start secbus", secbus); + /* * Check if it's a subtractive PPB. */ @@ -2901,12 +3257,12 @@ add_ppb_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func, */ val = (uint64_t)pci_getw(bus, dev, func, PCI_CONF_COMM); if (val & PCI_COMM_IO) { - val = (uint_t)pci_getb(bus, dev, func, PCI_BCNF_IO_BASE_LOW); - io_range[0] = ((val & PCI_BCNF_IO_MASK) << PCI_BCNF_IO_SHIFT); val = (uint_t)pci_getb(bus, dev, func, PCI_BCNF_IO_LIMIT_LOW); io_range[1] = ((val & PCI_BCNF_IO_MASK) << PCI_BCNF_IO_SHIFT) | 0xfff; - if ((io_range[0] & PCI_BCNF_ADDR_MASK) == PCI_BCNF_IO_32BIT) { + val = (uint_t)pci_getb(bus, dev, func, PCI_BCNF_IO_BASE_LOW); + io_range[0] = ((val & PCI_BCNF_IO_MASK) << PCI_BCNF_IO_SHIFT); + if ((val & PCI_BCNF_ADDR_MASK) == PCI_BCNF_IO_32BIT) { uint16_t io_base_hi, io_limit_hi; io_base_hi = pci_getw(bus, dev, func, PCI_BCNF_IO_BASE_HI); @@ -2936,7 +3292,7 @@ add_ppb_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func, (void) memlist_remove(&pci_bus_res[bus].io_avail, io_range[0], (io_range[1] - io_range[0] + 1)); } - dcmn_err(CE_NOTE, "bus %d io-range: 0x%" PRIx64 "-%" PRIx64, + dcmn_err(CE_NOTE, "bus %x io-range: 0x%" PRIx64 "-%" PRIx64, secbus, io_range[0], io_range[1]); } @@ -2948,29 +3304,25 @@ add_ppb_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func, 0xfffff; if (mem_range[0] != 0 && mem_range[0] < mem_range[1]) { memlist_insert(&pci_bus_res[secbus].mem_avail, - (uint64_t)mem_range[0], - (uint64_t)(mem_range[1] - mem_range[0] + 1)); + mem_range[0], mem_range[1] - mem_range[0] + 1); memlist_insert(&pci_bus_res[bus].mem_used, - (uint64_t)mem_range[0], - (uint64_t)(mem_range[1] - mem_range[0] + 1)); + mem_range[0], mem_range[1] - mem_range[0] + 1); /* remove from parent resource list */ (void) memlist_remove(&pci_bus_res[bus].mem_avail, - (uint64_t)mem_range[0], - (uint64_t)(mem_range[1] - mem_range[0] + 1)); + mem_range[0], mem_range[1] - mem_range[0] + 1); (void) memlist_remove(&pci_bus_res[bus].pmem_avail, - (uint64_t)mem_range[0], - (uint64_t)(mem_range[1] - mem_range[0] + 1)); - dcmn_err(CE_NOTE, "bus %d mem-range: 0x%" PRIx64 "-%" PRIx64, + mem_range[0], mem_range[1] - mem_range[0] + 1); + dcmn_err(CE_NOTE, "bus %x mem-range: 0x%" PRIx64 "-%" PRIx64, secbus, mem_range[0], mem_range[1]); } /* prefetchable memory range */ - val = (uint_t)pci_getw(bus, dev, func, PCI_BCNF_PF_BASE_LOW); - pmem_range[0] = ((val & PCI_BCNF_MEM_MASK) << PCI_BCNF_MEM_SHIFT); val = (uint_t)pci_getw(bus, dev, func, PCI_BCNF_PF_LIMIT_LOW); pmem_range[1] = ((val & PCI_BCNF_MEM_MASK) << PCI_BCNF_MEM_SHIFT) | 0xfffff; - if ((pmem_range[0] & PCI_BCNF_ADDR_MASK) == PCI_BCNF_PF_MEM_64BIT) { + val = (uint_t)pci_getw(bus, dev, func, PCI_BCNF_PF_BASE_LOW); + pmem_range[0] = ((val & PCI_BCNF_MEM_MASK) << PCI_BCNF_MEM_SHIFT); + if ((val & PCI_BCNF_ADDR_MASK) == PCI_BCNF_PF_MEM_64BIT) { uint32_t pf_addr_hi, pf_limit_hi; pf_addr_hi = pci_getl(bus, dev, func, PCI_BCNF_PF_BASE_HIGH); pf_limit_hi = pci_getl(bus, dev, func, PCI_BCNF_PF_LIMIT_HIGH); @@ -2979,19 +3331,15 @@ add_ppb_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func, } if (pmem_range[0] != 0 && pmem_range[0] < pmem_range[1]) { memlist_insert(&pci_bus_res[secbus].pmem_avail, - (uint64_t)pmem_range[0], - (uint64_t)(pmem_range[1] - pmem_range[0] + 1)); + pmem_range[0], pmem_range[1] - pmem_range[0] + 1); memlist_insert(&pci_bus_res[bus].pmem_used, - (uint64_t)pmem_range[0], - (uint64_t)(pmem_range[1] - pmem_range[0] + 1)); + pmem_range[0], pmem_range[1] - pmem_range[0] + 1); /* remove from parent resource list */ (void) memlist_remove(&pci_bus_res[bus].pmem_avail, - (uint64_t)pmem_range[0], - (uint64_t)(pmem_range[1] - pmem_range[0] + 1)); + pmem_range[0], pmem_range[1] - pmem_range[0] + 1); (void) memlist_remove(&pci_bus_res[bus].mem_avail, - (uint64_t)pmem_range[0], - (uint64_t)(pmem_range[1] - pmem_range[0] + 1)); - dcmn_err(CE_NOTE, "bus %d pmem-range: 0x%" PRIx64 "-%" PRIx64, + pmem_range[0], pmem_range[1] - pmem_range[0] + 1); + dcmn_err(CE_NOTE, "bus %x pmem-range: 0x%" PRIx64 "-%" PRIx64, secbus, pmem_range[0], pmem_range[1]); } @@ -3034,6 +3382,9 @@ add_ppb_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func, } add_bus_range_prop(secbus); add_ranges_prop(secbus, 1); + + dump_memlists("add_ppb_props end bus", bus); + dump_memlists("add_ppb_props end secbus", secbus); } extern const struct pci_class_strings_s class_pci[]; @@ -3194,6 +3545,8 @@ add_ranges_prop(int bus, int ppb) if (pci_bus_res[bus].dip == NULL) return; + dump_memlists("add_ranges_prop", bus); + iolist = memlist = pmemlist = (struct memlist *)NULL; memlist_merge(&pci_bus_res[bus].io_avail, &iolist); diff --git a/usr/src/uts/intel/io/pci/pci_memlist.c b/usr/src/uts/intel/io/pci/pci_memlist.c index 9dc553c5ba..5786591420 100644 --- a/usr/src/uts/intel/io/pci/pci_memlist.c +++ b/usr/src/uts/intel/io/pci/pci_memlist.c @@ -21,6 +21,9 @@ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. + * */ /* @@ -43,13 +46,13 @@ extern int pci_boot_debug; void memlist_dump(struct memlist *listp) { - dprintf("memlist 0x%p content", (void *)listp); + dprintf("memlist 0x%p content: ", (void *)listp); while (listp) { - dprintf("(0x%x%x, 0x%x%x)", - (int)(listp->ml_address >> 32), (int)listp->ml_address, - (int)(listp->ml_size >> 32), (int)listp->ml_size); + dprintf("(0x%lx, 0x%lx) ", + listp->ml_address, listp->ml_size); listp = listp->ml_next; } + dprintf("\n"); } struct memlist * diff --git a/usr/src/uts/intel/io/pci/pci_resource.c b/usr/src/uts/intel/io/pci/pci_resource.c index 4e5c7c051a..57dbe12427 100644 --- a/usr/src/uts/intel/io/pci/pci_resource.c +++ b/usr/src/uts/intel/io/pci/pci_resource.c @@ -23,6 +23,7 @@ * Use is subject to license terms. * * Copyright 2016 Joyent, Inc. + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. * * pci_resource.c -- routines to retrieve available bus resources from * the MP Spec. Table and Hotplug Resource Table @@ -248,23 +249,52 @@ bus_res_fini(void) } } - -struct memlist ** -rlistpp(UINT8 t, UINT8 flags, int bus) +static struct memlist ** +rlistpp(UINT8 t, UINT8 caching, int bus) { switch (t) { + case ACPI_MEMORY_RANGE: + if (caching == ACPI_PREFETCHABLE_MEMORY) + return (&acpi_pmem_res[bus]); + else + return (&acpi_mem_res[bus]); + break; - case ACPI_MEMORY_RANGE: - /* is this really the best we've got? */ - if (((flags >> 1) & 0x3) == ACPI_PREFETCHABLE_MEMORY) - return (&acpi_pmem_res[bus]); - else - return (&acpi_mem_res[bus]); + case ACPI_IO_RANGE: + return (&acpi_io_res[bus]); + break; - case ACPI_IO_RANGE: return &acpi_io_res[bus]; - case ACPI_BUS_NUMBER_RANGE: return &acpi_bus_res[bus]; + case ACPI_BUS_NUMBER_RANGE: + return (&acpi_bus_res[bus]); + break; } - return ((struct memlist **)NULL); + + return (NULL); +} + +static void +acpi_dbg(uint_t bus, uint64_t addr, uint64_t len, uint8_t caching, uint8_t type, + char *tag) +{ + char *s; + + switch (type) { + case ACPI_MEMORY_RANGE: + s = "MEM"; + break; + case ACPI_IO_RANGE: + s = "IO"; + break; + case ACPI_BUS_NUMBER_RANGE: + s = "BUS"; + break; + default: + s = "???"; + break; + } + + dprintf("ACPI: bus %x %s/%s %lx/%lx (Caching: %x)\n", bus, + tag, s, addr, len, caching); } @@ -302,6 +332,10 @@ acpi_wr_cb(ACPI_RESOURCE *rp, void *context) acpi_cb_cnt++; memlist_insert(&acpi_io_res[bus], rp->Data.Io.Minimum, rp->Data.Io.AddressLength); + if (pci_boot_debug != 0) { + acpi_dbg(bus, rp->Data.Io.Minimum, + rp->Data.Io.AddressLength, 0, ACPI_IO_RANGE, "IO"); + } break; case ACPI_RESOURCE_TYPE_FIXED_IO: @@ -337,9 +371,16 @@ acpi_wr_cb(ACPI_RESOURCE *rp, void *context) break; acpi_cb_cnt++; memlist_insert(rlistpp(rp->Data.Address16.ResourceType, - rp->Data.Address16.Info.TypeSpecific, bus), + rp->Data.Address.Info.Mem.Caching, bus), rp->Data.Address16.Address.Minimum, rp->Data.Address16.Address.AddressLength); + if (pci_boot_debug != 0) { + acpi_dbg(bus, + rp->Data.Address16.Address.Minimum, + rp->Data.Address16.Address.AddressLength, + rp->Data.Address.Info.Mem.Caching, + rp->Data.Address16.ResourceType, "ADDRESS16"); + } break; case ACPI_RESOURCE_TYPE_ADDRESS32: @@ -347,38 +388,51 @@ acpi_wr_cb(ACPI_RESOURCE *rp, void *context) break; acpi_cb_cnt++; memlist_insert(rlistpp(rp->Data.Address32.ResourceType, - rp->Data.Address32.Info.TypeSpecific, bus), + rp->Data.Address.Info.Mem.Caching, bus), rp->Data.Address32.Address.Minimum, rp->Data.Address32.Address.AddressLength); + if (pci_boot_debug != 0) { + acpi_dbg(bus, + rp->Data.Address32.Address.Minimum, + rp->Data.Address32.Address.AddressLength, + rp->Data.Address.Info.Mem.Caching, + rp->Data.Address32.ResourceType, "ADDRESS32"); + } break; case ACPI_RESOURCE_TYPE_ADDRESS64: - /* - * We comment out this block because we currently cannot deal with - * PCI 64-bit addresses. Will revisit this when we add PCI 64-bit MMIO - * support. - */ -#if 0 - if (rp->Data.Address64.AddressLength == 0) + if (rp->Data.Address64.Address.AddressLength == 0) break; + acpi_cb_cnt++; memlist_insert(rlistpp(rp->Data.Address64.ResourceType, - rp->Data.Address64.Info.TypeSpecific, bus), - rp->Data.Address64.Minimum, - rp->Data.Address64.AddressLength); -#endif + rp->Data.Address.Info.Mem.Caching, bus), + rp->Data.Address64.Address.Minimum, + rp->Data.Address64.Address.AddressLength); + if (pci_boot_debug != 0) { + acpi_dbg(bus, + rp->Data.Address64.Address.Minimum, + rp->Data.Address64.Address.AddressLength, + rp->Data.Address.Info.Mem.Caching, + rp->Data.Address64.ResourceType, "ADDRESS64"); + } break; case ACPI_RESOURCE_TYPE_EXTENDED_ADDRESS64: -#if 0 /* Will revisit this when we add PCI 64-bit MMIO support */ - if (rp->Data.ExtAddress64.AddressLength == 0) + if (rp->Data.ExtAddress64.Address.AddressLength == 0) break; acpi_cb_cnt++; memlist_insert(rlistpp(rp->Data.ExtAddress64.ResourceType, - rp->Data.ExtAddress64.Info.TypeSpecific, bus), - rp->Data.ExtAddress64.Minimum, - rp->Data.ExtAddress64.AddressLength); -#endif + rp->Data.Address.Info.Mem.Caching, bus), + rp->Data.ExtAddress64.Address.Minimum, + rp->Data.ExtAddress64.Address.AddressLength); + if (pci_boot_debug != 0) { + acpi_dbg(bus, + rp->Data.ExtAddress64.Address.Minimum, + rp->Data.ExtAddress64.Address.AddressLength, + rp->Data.Address.Info.Mem.Caching, + rp->Data.ExtAddress64.ResourceType, "EXTADDRESS64"); + } break; case ACPI_RESOURCE_TYPE_EXTENDED_IRQ: diff --git a/usr/src/uts/intel/pci_autoconfig/Makefile b/usr/src/uts/intel/pci_autoconfig/Makefile index afbf30e155..f133091b1f 100644 --- a/usr/src/uts/intel/pci_autoconfig/Makefile +++ b/usr/src/uts/intel/pci_autoconfig/Makefile @@ -24,6 +24,7 @@ # Use is subject to license terms. # # Copyright 2016 Joyent, Inc. +# Copyright 2020 OmniOS Community Edition (OmniOSce) Association. # # This makefile drives the production of the PCI autoconfiguration # kernel module. @@ -41,7 +42,6 @@ UTSBASE = ../.. # MODULE = pci_autoconfig OBJECTS = $(PCI_AUTOCONFIG_OBJS:%=$(OBJS_DIR)/%) -LINTS = $(PCI_AUTOCONFIG_OBJS:%.o=$(LINTS_DIR)/%.ln) ROOTMODULE = $(ROOT_MISC_DIR)/$(MODULE) INC_PATH += -I$(UTSBASE)/i86pc @@ -54,7 +54,6 @@ include $(UTSBASE)/intel/Makefile.intel # Define targets # ALL_TARGET = $(BINARY) -LINT_TARGET = $(MODULE).lint INSTALL_TARGET = $(BINARY) $(ROOTMODULE) # @@ -63,18 +62,6 @@ INSTALL_TARGET = $(BINARY) $(ROOTMODULE) LDFLAGS += -dy -Nmisc/acpica -Nmisc/pcie # -# For now, disable these lint checks; maintainers should endeavor -# to investigate and remove these for maximum lint coverage. -# Please do not carry these forward to new Makefiles. -# -LINTTAGS += -erroff=E_BAD_PTR_CAST_ALIGN -LINTTAGS += -erroff=E_ASSIGN_NARROW_CONV - -CERRWARN += -_gcc=-Wno-parentheses -$(OBJS_DIR)/pci_boot.o := CERRWARN += -_gcc=-Wno-unused-function -$(OBJS_DIR)/pci_resource.o := CERRWARN += -_gcc=-Wno-unused-function - -# # Default build targets. # .KEEP_STATE: @@ -87,12 +74,6 @@ clean: $(CLEAN_DEPS) clobber: $(CLOBBER_DEPS) -lint: $(LINT_DEPS) - -modlintlib: $(MODLINTLIB_DEPS) - -clean.lint: $(CLEAN_LINT_DEPS) - install: $(INSTALL_DEPS) # diff --git a/usr/src/uts/sparc/Makefile.sparc b/usr/src/uts/sparc/Makefile.sparc index e592b8a8ff..5033722aba 100644 --- a/usr/src/uts/sparc/Makefile.sparc +++ b/usr/src/uts/sparc/Makefile.sparc @@ -290,13 +290,32 @@ DRV_KMODS += bge dmfe eri fas hme qfe DRV_KMODS += openeepr options sd ses st DRV_KMODS += ssd DRV_KMODS += ecpp -DRV_KMODS += hid hubd ehci ohci uhci usb_mid usb_ia scsa2usb usbprn ugen -DRV_KMODS += usbser usbsacm usbsksp usbsprl -DRV_KMODS += usb_as usb_ac + +# +# USB specific modules +# +DRV_KMODS += ccid +DRV_KMODS += hid +DRV_KMODS += hubd +DRV_KMODS += ehci +DRV_KMODS += ohci +DRV_KMODS += uhci +DRV_KMODS += usb_mid +DRV_KMODS += usb_ia +DRV_KMODS += scsa2usb +DRV_KMODS += usbprn +DRV_KMODS += ugen +DRV_KMODS += usbser +DRV_KMODS += usbsacm +DRV_KMODS += usbsksp +DRV_KMODS += usbsprl +DRV_KMODS += usb_as +DRV_KMODS += usb_ac DRV_KMODS += usbskel DRV_KMODS += usbvc DRV_KMODS += usbftdi DRV_KMODS += usbecm + DRV_KMODS += hci1394 av1394 scsa1394 dcam1394 DRV_KMODS += sbp2 DRV_KMODS += ib ibp eibnx eoib rdsib sdp iser daplt hermon tavor sol_ucma sol_uverbs diff --git a/usr/src/uts/sparc/ccid/Makefile b/usr/src/uts/sparc/ccid/Makefile new file mode 100644 index 0000000000..b3684e93af --- /dev/null +++ b/usr/src/uts/sparc/ccid/Makefile @@ -0,0 +1,42 @@ +# +# This file and its contents are supplied under the terms of the +# Common Development and Distribution License ("CDDL"), version 1.0. +# You may only use this file in accordance with the terms of version +# 1.0 of the CDDL. +# +# A full copy of the text of the CDDL should have accompanied this +# source. A copy of the CDDL is also available via the Internet at +# http://www.illumos.org/license/CDDL. +# + +# +# Copyright 2019, Joyent, Inc. +# + +UTSBASE = ../.. + +MODULE = ccid +OBJECTS = $(CCID_OBJS:%=$(OBJS_DIR)/%) +ROOTMODULE = $(ROOT_DRV_DIR)/$(MODULE) + +include $(UTSBASE)/sparc/Makefile.sparc + +ALL_TARGET = $(BINARY) +INSTALL_TARGET = $(BINARY) $(ROOTMODULE) +CPPFLAGS += -I$(SRC)/common/ccid + +LDFLAGS += -dy -N misc/usba + +.KEEP_STATE: + +def: $(DEF_DEPS) + +all: $(ALL_DEPS) + +clean: $(CLEAN_DEPS) + +clobber: $(CLOBBER_DEPS) + +install: $(INSTALL_DEPS) + +include $(UTSBASE)/sparc/Makefile.targ |