diff options
author | Robert Mustacchi <rm@fingolfin.org> | 2022-01-19 21:33:26 +0000 |
---|---|---|
committer | Robert Mustacchi <rm@fingolfin.org> | 2022-02-17 19:50:22 +0000 |
commit | cd0d4b4073e62fa22997078b1595f399434a1047 (patch) | |
tree | 1da292b58016ab3ca2633d9849c6524900035bf8 /usr/src/uts/intel | |
parent | 55855f50d61b53851853bf1fdcdb04d4b63a1734 (diff) | |
download | illumos-gate-cd0d4b4073e62fa22997078b1595f399434a1047.tar.gz |
14450 Want PCI platform resource discovery module
Reviewed by: Rich Lowe <richlowe@richlowe.net>
Reviewed by: Patrick Mooney <pmooney@pfmooney.com>
Reviewed by: Andy Fiddaman <andy@omnios.org>
Approved by: Dan McDonald <danmcd@joyent.com>
Diffstat (limited to 'usr/src/uts/intel')
-rw-r--r-- | usr/src/uts/intel/Makefile.files | 2 | ||||
-rw-r--r-- | usr/src/uts/intel/io/pci/mps_table.h | 131 | ||||
-rw-r--r-- | usr/src/uts/intel/io/pci/pci_autoconfig.c | 27 | ||||
-rw-r--r-- | usr/src/uts/intel/io/pci/pci_boot.c | 380 | ||||
-rw-r--r-- | usr/src/uts/intel/io/pci/pci_memlist.c | 4 | ||||
-rw-r--r-- | usr/src/uts/intel/io/pci/pci_resource.c | 722 | ||||
-rw-r--r-- | usr/src/uts/intel/io/pci/pcihrt.h | 71 | ||||
-rw-r--r-- | usr/src/uts/intel/pci_autoconfig/Makefile | 4 |
8 files changed, 98 insertions, 1243 deletions
diff --git a/usr/src/uts/intel/Makefile.files b/usr/src/uts/intel/Makefile.files index 2e7455a93a..7f464e2ec8 100644 --- a/usr/src/uts/intel/Makefile.files +++ b/usr/src/uts/intel/Makefile.files @@ -141,7 +141,7 @@ PCIEB_OBJS += pcieb_x86.o PIT_BEEP_OBJS += pit_beep.o POWER_OBJS += power.o PCI_AUTOCONFIG_OBJS += pci_autoconfig.o pci_boot.o pcie_nvidia.o \ - pci_memlist.o pci_resource.o + pci_memlist.o RADEON_OBJS += r300_cmdbuf.o radeon_cp.o radeon_drv.o \ radeon_state.o radeon_irq.o radeon_mem.o SD_OBJS += sd.o sd_xbuf.o diff --git a/usr/src/uts/intel/io/pci/mps_table.h b/usr/src/uts/intel/io/pci/mps_table.h deleted file mode 100644 index 8f8c1dc24e..0000000000 --- a/usr/src/uts/intel/io/pci/mps_table.h +++ /dev/null @@ -1,131 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - * - * mps_table.h -- MP Specification table definitions - */ - -#ifndef _MPS_TABLE_H -#define _MPS_TABLE_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - - -struct mps_fps_hdr { /* MP Floating Pointer Structure */ - uint32_t fps_sig; /* _MP_ (0x5F4D505F) */ - uint32_t fps_mpct_paddr; /* paddr of MP Configuration Table */ - uchar_t fps_len; /* in paragraph (16-bytes units) */ - uchar_t fps_spec_rev; /* MP Spec. version no. */ - uchar_t fps_cksum; /* checksum of complete structure */ - uchar_t fps_featinfo1; /* mp feature info byte 1 */ - uchar_t fps_featinfo2; /* mp feature info byte 2 */ - uchar_t fps_featinfo3; /* mp feature info byte 3 */ - uchar_t fps_featinfo4; /* mp feature info byte 4 */ - uchar_t fps_featinfo5; /* mp feature info byte 5 */ -}; - -struct mps_ct_hdr { /* MP Configuration Table Header */ - uint32_t ct_sig; /* "PCMP" */ - uint16_t ct_len; /* base configuration in bytes */ - uchar_t ct_spec_rev; /* MP Spec. version no. */ - uchar_t ct_cksum; /* base configuration table checksum */ - char ct_oem_id[8]; /* string identifies the manufacturer */ - char ct_prod_id[12]; /* string identifies the product */ - uint32_t ct_oem_ptr; /* paddr to an OEM-defined table */ - uint16_t ct_oem_tbl_len; /* size of base OEM table in bytes */ - uint16_t ct_entry_cnt; /* no. of entries in the base table */ - uint32_t ct_local_apic; /* paddr of local APIC */ - uint16_t ct_ext_tbl_len; /* extended table in bytes */ - uchar_t ct_ext_cksum; /* checksum for the extended table */ -}; - -/* Base MP Configuration Table entry type definitions */ -#define CPU_TYPE 0 -#define BUS_TYPE 1 -#define IO_APIC_TYPE 2 -#define IO_INTR_TYPE 3 -#define LOCAL_INTR_TYPE 4 - -/* Base MP Configuration Table entry size definitions */ -#define CPU_SIZE 20 -#define BUS_SIZE 8 -#define IO_APIC_SIZE 8 -#define IO_INTR_SIZE 8 -#define LOCAL_INTR_SIZE 8 - -/* Extended MP Configuration Table entry type definitions */ -#define SYS_AS_MAPPING 128 -#define BUS_HIERARCHY_DESC 129 -#define COMP_BUS_AS_MODIFIER 130 - -/* Extended MP Configuration Table entry size definitions */ -#define SYS_AS_MAPPING_SIZE 20 -#define BUS_HIERARCHY_DESC_SIZE 8 -#define COMP_BUS_AS_MODIFIER_SIZE 8 - -struct sasm { /* System Address Space Mapping Entry */ - uchar_t sasm_type; /* type 128 */ - uchar_t sasm_len; /* entry length in bytes (20) */ - uchar_t sasm_bus_id; /* bus id where this is mapped */ - uchar_t sasm_as_type; /* system address type */ -/* system address type definitions */ -#define IO_TYPE 0 -#define MEM_TYPE 1 -#define PREFETCH_TYPE 2 -#define BUSRANGE_TYPE 3 - uint32_t sasm_as_base; /* starting address */ - uint32_t sasm_as_base_hi; - uint32_t sasm_as_len; /* no. of addresses visiblie to the bus */ - uint32_t sasm_as_len_hi; -}; - -struct bhd { /* Bus Hierarchy Descriptor Entry */ - uchar_t bhd_type; /* type 129 */ - uchar_t bhd_len; /* entry length in bytes (8) */ - uchar_t bhd_bus_id; /* bus id of this bus */ - uchar_t bhd_bus_info; /* bus information */ -/* Bus Information bit definition */ -#define BHD_BUS_INFO_SD 1 /* Subtractive Decode Bus */ - uchar_t bhd_parent; -}; - -struct cbasm { /* Compatibility Bus Address Space Modifier Entry */ - uchar_t cbasm_type; /* type 130 */ - uchar_t cbasm_len; /* entry length in bytes (8) */ - uchar_t cbasm_bus_id; /* bus to be modified */ - uchar_t cbasm_addr_mod; /* address modifier */ -/* Address Modifier bit definiton */ -#define CBASM_ADDR_MOD_PR 1 /* 1 = subtracted, 0 = added */ - uint32_t cbasm_pr_list; /* identify list of predefined address ranges */ -}; - -#ifdef __cplusplus -} -#endif - -#endif /* _MPS_TABLE_H */ diff --git a/usr/src/uts/intel/io/pci/pci_autoconfig.c b/usr/src/uts/intel/io/pci/pci_autoconfig.c index 713493eedb..af7ba637d8 100644 --- a/usr/src/uts/intel/io/pci/pci_autoconfig.c +++ b/usr/src/uts/intel/io/pci/pci_autoconfig.c @@ -21,6 +21,7 @@ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2022 Oxide Computer Company */ /* @@ -40,8 +41,10 @@ #include <sys/reboot.h> #include <sys/pci_cfgspace_impl.h> #include <sys/mutex.h> +#include <sys/plat/pci_prd.h> extern int pci_boot_debug; +extern int pci_boot_maxbus; /* * Interface routines @@ -49,7 +52,7 @@ extern int pci_boot_debug; void pci_enumerate(int); void pci_setup_tree(void); void pci_reprogram(void); -void bus_res_fini(void); +dev_info_t *pci_boot_bus_to_dip(uint32_t); static struct modlmisc modlmisc = { &mod_miscops, "PCI BIOS interface" @@ -59,13 +62,23 @@ static struct modlinkage modlinkage = { MODREV_1, (void *)&modlmisc, NULL }; +static pci_prd_upcalls_t pci_upcalls = { + .pru_bus2dip_f = pci_boot_bus_to_dip +}; + int _init(void) { int err; - if ((err = mod_install(&modlinkage)) != 0) + if ((err = pci_prd_init(&pci_upcalls)) != 0) { + return (err); + } + + if ((err = mod_install(&modlinkage)) != 0) { + pci_prd_fini(); return (err); + } impl_bus_add_probe(pci_enumerate); return (0); @@ -80,7 +93,7 @@ _fini(void) return (err); impl_bus_delete_probe(pci_enumerate); - bus_res_fini(); + pci_prd_fini(); return (0); } @@ -102,6 +115,14 @@ pci_enumerate(int reprogram) extern void add_pci_fixes(void); extern void undo_pci_fixes(void); + /* + * On our first pass through here actually determine what the maximum + * bus that we should use is. + */ + if (reprogram == 0) { + pci_boot_maxbus = pci_prd_max_bus(); + } + add_pci_fixes(); if (reprogram) { diff --git a/usr/src/uts/intel/io/pci/pci_boot.c b/usr/src/uts/intel/io/pci/pci_boot.c index f2cff30ed3..25bae81079 100644 --- a/usr/src/uts/intel/io/pci/pci_boot.c +++ b/usr/src/uts/intel/io/pci/pci_boot.c @@ -23,6 +23,7 @@ * Copyright 2019 Joyent, Inc. * Copyright 2019 Western Digital Corporation * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. + * Copyright 2022 Oxide Computer Company */ /* @@ -101,18 +102,21 @@ * 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. + * pci_prd_root_complex_iter() + * The platform is asked to tell us of all root + * complexes that it knows about (e.g. using the + * _BBN method via ACPI). This will include buses + * that we've already discovered and those that we + * potentially haven't. Anything that has not been + * previously discovered (or inferred to exist) is + * then 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 + * based on what the platform provideds through the + * pci platform interfaces defined in + * sys/plat/pci_prd.h. On i86pc this is driven by + * ACPI and BIOS tables. * <foreach bus> * fix_ppb_res() * Reprogram pci(e) bridges which have not already @@ -158,7 +162,6 @@ #include <sys/pcie_impl.h> #include <sys/memlist.h> #include <sys/bootconf.h> -#include <io/pci/mps_table.h> #include <sys/pci_cfgacc.h> #include <sys/pci_cfgspace.h> #include <sys/pci_cfgspace_impl.h> @@ -172,6 +175,7 @@ #include <sys/iommulib.h> #include <sys/devcache.h> #include <sys/pci_cfgacc_x86.h> +#include <sys/plat/pci_prd.h> #define pci_getb (*pci_getb_func) #define pci_getw (*pci_getw_func) @@ -242,16 +246,13 @@ struct pci_devfunc { extern int apic_nvidia_io_max; extern int pseudo_isa; -extern int pci_bios_maxbus; static uchar_t max_dev_pci = 32; /* PCI standard */ +int pci_boot_maxbus; 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 */ -extern volatile int acpi_resource_discovery; -extern uint64_t mcfg_mem_base; extern void pci_cfgacc_add_workaround(uint16_t, uchar_t, uchar_t); extern dev_info_t *pcie_get_rc_dip(dev_info_t *); @@ -269,12 +270,11 @@ static void add_ppb_props(dev_info_t *, uchar_t, uchar_t, uchar_t, int, ushort_t); static void add_model_prop(dev_info_t *, uint_t); static void add_bus_range_prop(int); -static void add_bus_slot_names_prop(int); static void add_ranges_prop(int, int); static void add_bus_available_prop(int); static int get_pci_cap(uchar_t bus, uchar_t dev, uchar_t func, uint8_t cap_id); static void fix_ppb_res(uchar_t, boolean_t); -static void alloc_res_array(); +static void alloc_res_array(void); static void create_ioapic_node(int bus, int dev, int fn, ushort_t vendorid, ushort_t deviceid); static void pciex_slot_names_prop(dev_info_t *, ushort_t); @@ -283,7 +283,6 @@ static void memlist_remove_list(struct memlist **list, struct memlist *remove_list); static void ck804_fix_aer_ptr(dev_info_t *, pcie_req_id_t); -static void pci_scan_bbn(void); static int pci_unitaddr_cache_valid(void); static int pci_bus_unitaddr(int); static void pci_unitaddr_cache_create(void); @@ -292,8 +291,6 @@ static int pci_cache_unpack_nvlist(nvf_handle_t, nvlist_t *, char *); static int pci_cache_pack_nvlist(nvf_handle_t, nvlist_t **); static void pci_cache_free_list(nvf_handle_t); -extern int pci_slot_names_prop(int, char *, int); - /* set non-zero to force PCI peer-bus renumbering */ int pci_bus_always_renumber = 0; @@ -326,6 +323,13 @@ typedef struct { nvf_handle_t puafd_handle; int pua_cache_valid = 0; +dev_info_t * +pci_boot_bus_to_dip(uint32_t busno) +{ + ASSERT3U(busno, <=, pci_boot_maxbus); + return (pci_bus_res[busno].dip); +} + static void dump_memlists_impl(const char *tag, int bus) { @@ -356,80 +360,21 @@ dump_memlists_impl(const char *tag, int bus) } } -/*ARGSUSED*/ -static ACPI_STATUS -pci_process_acpi_device(ACPI_HANDLE hdl, UINT32 level, void *ctx, void **rv) +static boolean_t +pci_rc_scan_cb(uint32_t busno, void *arg) { - ACPI_DEVICE_INFO *adi; - int busnum; - - /* - * Use AcpiGetObjectInfo() to find the device _HID - * If not a PCI root-bus, ignore this device and continue - * the walk - */ - if (ACPI_FAILURE(AcpiGetObjectInfo(hdl, &adi))) - return (AE_OK); - - if (!(adi->Valid & ACPI_VALID_HID)) { - AcpiOsFree(adi); - return (AE_OK); - } - - if (strncmp(adi->HardwareId.String, PCI_ROOT_HID_STRING, - sizeof (PCI_ROOT_HID_STRING)) && - strncmp(adi->HardwareId.String, PCI_EXPRESS_ROOT_HID_STRING, - sizeof (PCI_EXPRESS_ROOT_HID_STRING))) { - AcpiOsFree(adi); - return (AE_OK); + if (busno > pci_boot_maxbus) { + dcmn_err(CE_NOTE, "platform root complex scan returned bus " + "with invalid bus id: 0x%x", busno); + return (B_TRUE); } - AcpiOsFree(adi); - - /* - * acpica_get_busno() will check the presence of _BBN and - * fail if not present. It will then use the _CRS method to - * retrieve the actual bus number assigned, it will fall back - * to _BBN should the _CRS method fail. - */ - if (ACPI_SUCCESS(acpica_get_busno(hdl, &busnum))) { - /* - * Ignore invalid _BBN return values here (rather - * than panic) and emit a warning; something else - * may suffer failure as a result of the broken BIOS. - */ - if ((busnum < 0) || (busnum > pci_bios_maxbus)) { - dcmn_err(CE_NOTE, - "pci_process_acpi_device: invalid _BBN 0x%x", - busnum); - return (AE_CTRL_DEPTH); - } - - /* PCI with valid _BBN */ - if (pci_bus_res[busnum].par_bus == (uchar_t)-1 && - pci_bus_res[busnum].dip == NULL) - create_root_bus_dip((uchar_t)busnum); - return (AE_CTRL_DEPTH); + if (pci_bus_res[busno].par_bus == (uchar_t)-1 && + pci_bus_res[busno].dip == NULL) { + create_root_bus_dip((uchar_t)busno); } - /* PCI and no _BBN, continue walk */ - return (AE_OK); -} - -/* - * Scan the ACPI namespace for all top-level instances of _BBN - * in order to discover childless root-bridges (which enumeration - * may not find; root-bridges are inferred by the existence of - * children). This scan should find all root-bridges that have - * been enumerated, and any childless root-bridges not enumerated. - * Root-bridge for bus 0 may not have a _BBN object. - */ -static void -pci_scan_bbn() -{ - void *rv; - - (void) AcpiGetDevices(NULL, pci_process_acpi_device, NULL, &rv); + return (B_TRUE); } static void @@ -596,7 +541,7 @@ pci_unitaddr_cache_create(void) index = 0; listp = nvf_list(puafd_handle); - for (i = 0; i <= pci_bios_maxbus; i++) { + for (i = 0; i <= pci_boot_maxbus; i++) { /* skip non-root (peer) PCI busses */ if ((pci_bus_res[i].par_bus != (uchar_t)-1) || (pci_bus_res[i].dip == NULL)) @@ -622,7 +567,7 @@ pci_setup_tree(void) uint_t i, root_bus_addr = 0; alloc_res_array(); - for (i = 0; i <= pci_bios_maxbus; i++) { + for (i = 0; i <= pci_boot_maxbus; i++) { pci_bus_res[i].par_bus = (uchar_t)-1; pci_bus_res[i].root_addr = (uchar_t)-1; pci_bus_res[i].sub_bus = i; @@ -635,7 +580,7 @@ pci_setup_tree(void) /* * Now enumerate peer busses * - * We loop till pci_bios_maxbus. On most systems, there is + * We loop till pci_boot_maxbus. On most systems, there is * one more bus at the high end, which implements the ISA * compatibility bus. We don't care about that. * @@ -646,144 +591,11 @@ pci_setup_tree(void) * However, we stop enumerating phantom peers with no * device below. */ - for (i = 1; i <= pci_bios_maxbus; i++) { + for (i = 1; i <= pci_boot_maxbus; i++) { if (pci_bus_res[i].dip == NULL) { pci_bus_res[i].root_addr = root_bus_addr++; } enumerate_bus_devs(i, CONFIG_INFO); - - /* add slot-names property for named pci hot-plug slots */ - add_bus_slot_names_prop(i); - } -} - -/* - * >0 = present, 0 = not present, <0 = error - */ -static int -pci_bbn_present(int bus) -{ - ACPI_HANDLE hdl; - int rv; - - /* no dip means no _BBN */ - if (pci_bus_res[bus].dip == NULL) - return (0); - - rv = -1; /* default return value in case of error below */ - if (ACPI_SUCCESS(acpica_get_handle(pci_bus_res[bus].dip, &hdl))) { - switch (AcpiEvaluateObject(hdl, "_BBN", NULL, NULL)) { - case AE_OK: - rv = 1; - break; - case AE_NOT_FOUND: - rv = 0; - break; - default: - break; - } - } - - return (rv); -} - -/* - * Return non-zero if any PCI bus in the system has an associated - * _BBN object, 0 otherwise. - */ -static int -pci_roots_have_bbn(void) -{ - int i; - - /* - * Scan the PCI busses and look for at least 1 _BBN - */ - for (i = 0; i <= pci_bios_maxbus; i++) { - /* skip non-root (peer) PCI busses */ - if (pci_bus_res[i].par_bus != (uchar_t)-1) - continue; - - if (pci_bbn_present(i) > 0) - return (1); - } - return (0); - -} - -/* - * return non-zero if the machine is one on which we renumber - * the internal pci unit-addresses - */ -static int -pci_bus_renumber() -{ - ACPI_TABLE_HEADER *fadt; - - if (pci_bus_always_renumber) - return (1); - - /* get the FADT */ - if (AcpiGetTable(ACPI_SIG_FADT, 1, (ACPI_TABLE_HEADER **)&fadt) != - AE_OK) - return (0); - - /* compare OEM Table ID to "SUNm31" */ - if (strncmp("SUNm31", fadt->OemId, 6)) - return (0); - else - return (1); -} - -/* - * Initial enumeration of the physical PCI bus hierarchy can - * leave 'gaps' in the order of peer PCI bus unit-addresses. - * Systems with more than one peer PCI bus *must* have an ACPI - * _BBN object associated with each peer bus; use the presence - * of this object to remove gaps in the numbering of the peer - * PCI bus unit-addresses - only peer busses with an associated - * _BBN are counted. - */ -static void -pci_renumber_root_busses(void) -{ - int pci_regs[] = {0, 0, 0}; - int i, root_addr = 0; - - /* - * Currently, we only enable the re-numbering on specific - * Sun machines; this is a work-around for the more complicated - * issue of upgrade changing physical device paths - */ - if (!pci_bus_renumber()) - return; - - /* - * If we find no _BBN objects at all, we either don't need - * to do anything or can't do anything anyway - */ - if (!pci_roots_have_bbn()) - return; - - for (i = 0; i <= pci_bios_maxbus; i++) { - /* skip non-root (peer) PCI busses */ - if (pci_bus_res[i].par_bus != (uchar_t)-1) - continue; - - if (pci_bbn_present(i) < 1) { - pci_bus_res[i].root_addr = (uchar_t)-1; - continue; - } - - ASSERT(pci_bus_res[i].dip != NULL); - if (pci_bus_res[i].root_addr != root_addr) { - /* update reg property for node */ - pci_bus_res[i].root_addr = root_addr; - pci_regs[0] = pci_bus_res[i].root_addr; - (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, - pci_bus_res[i].dip, "reg", (int *)pci_regs, 3); - } - root_addr++; } } @@ -810,12 +622,12 @@ remove_subtractive_res() int i, j; struct memlist *list; - for (i = 0; i <= pci_bios_maxbus; i++) { + for (i = 0; i <= pci_boot_maxbus; i++) { if (pci_bus_res[i].subtractive) { /* remove used io ports */ list = pci_bus_res[i].io_used; while (list) { - for (j = 0; j <= pci_bios_maxbus; j++) + for (j = 0; j <= pci_boot_maxbus; j++) (void) memlist_remove( &pci_bus_res[j].io_avail, list->ml_address, list->ml_size); @@ -824,7 +636,7 @@ remove_subtractive_res() /* remove used mem resource */ list = pci_bus_res[i].mem_used; while (list) { - for (j = 0; j <= pci_bios_maxbus; j++) { + for (j = 0; j <= pci_boot_maxbus; j++) { (void) memlist_remove( &pci_bus_res[j].mem_avail, list->ml_address, list->ml_size); @@ -837,7 +649,7 @@ remove_subtractive_res() /* remove used prefetchable mem resource */ list = pci_bus_res[i].pmem_used; while (list) { - for (j = 0; j <= pci_bios_maxbus; j++) { + for (j = 0; j <= pci_boot_maxbus; j++) { (void) memlist_remove( &pci_bus_res[j].pmem_avail, list->ml_address, list->ml_size); @@ -905,7 +717,7 @@ get_parbus_res(uchar_t parbus, uchar_t bus, uint64_t size, uint64_t align, * 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) && !pci_prd_multi_root_ok()) { return (0); } @@ -1593,10 +1405,16 @@ pci_reprogram(void) int bus; /* - * Scan ACPI namespace for _BBN objects, make sure that - * childless root-bridges appear in devinfo tree + * Ask platform code for all of the root complexes it knows about in + * case we have missed anything in the scan. This is to ensure that we + * have them show up in the devinfo tree. This scan should find any + * existing entries as well. After this, go through each bus and + * ask the platform if it wants to change the name of the slot. */ - pci_scan_bbn(); + pci_prd_root_complex_iter(pci_rc_scan_cb, NULL); + for (bus = 0; bus <= pci_boot_maxbus; bus++) { + pci_prd_slot_name(bus, pci_bus_res[bus].dip); + } pci_unitaddr_cache_init(); /* @@ -1607,7 +1425,7 @@ pci_reprogram(void) int new_addr; int index = 0; - for (bus = 0; bus <= pci_bios_maxbus; bus++) { + for (bus = 0; bus <= pci_boot_maxbus; bus++) { /* skip non-root (peer) PCI busses */ if ((pci_bus_res[bus].par_bus != (uchar_t)-1) || (pci_bus_res[bus].dip == NULL)) @@ -1626,14 +1444,13 @@ pci_reprogram(void) } } else { /* perform legacy processing */ - pci_renumber_root_busses(); pci_unitaddr_cache_create(); } /* * Do root-bus resource discovery */ - for (bus = 0; bus <= pci_bios_maxbus; bus++) { + for (bus = 0; bus <= pci_boot_maxbus; bus++) { /* skip non-root (peer) PCI busses */ if (pci_bus_res[bus].par_bus != (uchar_t)-1) continue; @@ -1683,7 +1500,7 @@ pci_reprogram(void) memlist_free_all(&isa_res.mem_used); /* add bus-range property for root/peer bus nodes */ - for (i = 0; i <= pci_bios_maxbus; i++) { + for (i = 0; i <= pci_boot_maxbus; i++) { /* create bus-range property on root/peer buses */ if (pci_bus_res[i].par_bus == (uchar_t)-1) add_bus_range_prop(i); @@ -1705,10 +1522,10 @@ pci_reprogram(void) /* reprogram the non-subtractive PPB */ if (pci_reconfig) - for (i = 0; i <= pci_bios_maxbus; i++) + for (i = 0; i <= pci_boot_maxbus; i++) fix_ppb_res(i, B_FALSE); - for (i = 0; i <= pci_bios_maxbus; i++) { + for (i = 0; i <= pci_boot_maxbus; i++) { /* configure devices not configured by BIOS */ if (pci_reconfig) { /* @@ -1722,7 +1539,7 @@ pci_reprogram(void) } /* All dev programmed, so we can create available prop */ - for (i = 0; i <= pci_bios_maxbus; i++) + for (i = 0; i <= pci_boot_maxbus; i++) add_bus_available_prop(i); } @@ -1734,10 +1551,11 @@ populate_bus_res(uchar_t bus) { /* scan BIOS structures */ - pci_bus_res[bus].pmem_avail = find_bus_res(bus, PREFETCH_TYPE); - pci_bus_res[bus].mem_avail = find_bus_res(bus, MEM_TYPE); - pci_bus_res[bus].io_avail = find_bus_res(bus, IO_TYPE); - pci_bus_res[bus].bus_avail = find_bus_res(bus, BUSRANGE_TYPE); + pci_bus_res[bus].pmem_avail = pci_prd_find_resource(bus, + PCI_PRD_R_PREFETCH); + pci_bus_res[bus].mem_avail = pci_prd_find_resource(bus, PCI_PRD_R_MMIO); + pci_bus_res[bus].io_avail = pci_prd_find_resource(bus, PCI_PRD_R_IO); + pci_bus_res[bus].bus_avail = pci_prd_find_resource(bus, PCI_PRD_R_BUS); /* * attempt to initialize sub_bus from the largest range-end @@ -2054,7 +1872,7 @@ add_pci_fixes(void) { int i; - for (i = 0; i <= pci_bios_maxbus; i++) { + for (i = 0; i <= pci_boot_maxbus; i++) { /* * For each bus, apply needed fixes to the appropriate devices. * This must be done before the main enumeration loop because @@ -3197,8 +3015,8 @@ add_ppb_props(dev_info_t *dip, uchar_t bus, uchar_t dev, uchar_t func, * Some BIOSes lie about max pci busses, we allow for * such mistakes here */ - if (subbus > pci_bios_maxbus) { - pci_bios_maxbus = subbus; + if (subbus > pci_boot_maxbus) { + pci_boot_maxbus = subbus; alloc_res_array(); } @@ -3436,66 +3254,6 @@ add_bus_range_prop(int bus) } /* - * Add slot-names property for any named pci hot-plug slots - */ -static void -add_bus_slot_names_prop(int bus) -{ - char slotprop[256]; - int len; - extern int pci_irq_nroutes; - char *slotcap_name; - - /* - * If no irq routing table, then go with the slot-names as set up - * in pciex_slot_names_prop() from slot capability register (if any). - */ - if (pci_irq_nroutes == 0) - return; - - /* - * Otherise delete the slot-names we already have and use the irq - * routing table values as returned by pci_slot_names_prop() instead, - * but keep any property of value "pcie0" as that can't be represented - * in the irq routing table. - */ - if (pci_bus_res[bus].dip != NULL) { - if (ddi_prop_lookup_string(DDI_DEV_T_ANY, pci_bus_res[bus].dip, - DDI_PROP_DONTPASS, "slot-names", &slotcap_name) != - DDI_SUCCESS || strcmp(slotcap_name, "pcie0") != 0) - (void) ndi_prop_remove(DDI_DEV_T_NONE, - pci_bus_res[bus].dip, "slot-names"); - } - - len = pci_slot_names_prop(bus, slotprop, sizeof (slotprop)); - if (len > 0) { - /* - * Only create a peer bus node if this bus may be a peer bus. - * It may be a peer bus if the dip is NULL and if par_bus is - * -1 (par_bus is -1 if this bus was not found to be - * subordinate to any PCI-PCI bridge). - * If it's not a peer bus, then the ACPI BBN-handling code - * will remove it later. - */ - if (pci_bus_res[bus].par_bus == (uchar_t)-1 && - pci_bus_res[bus].dip == NULL) { - - create_root_bus_dip(bus); - } - if (pci_bus_res[bus].dip != NULL) { - ASSERT((len % sizeof (int)) == 0); - (void) ndi_prop_update_int_array(DDI_DEV_T_NONE, - pci_bus_res[bus].dip, "slot-names", - (int *)slotprop, len / sizeof (int)); - } else { - cmn_err(CE_NOTE, "!BIOS BUG: Invalid bus number in PCI " - "IRQ routing table; Not adding slot-names " - "property for incorrect bus %d", bus); - } - } -} - -/* * Handle both PCI root and PCI-PCI bridge range properties; * non-zero 'ppb' argument select PCI-PCI bridges versus root. */ @@ -3652,11 +3410,11 @@ add_bus_available_prop(int bus) static void alloc_res_array(void) { - static int array_size = 0; - int old_size; + static uint_t array_size = 0; + uint_t old_size; void *old_res; - if (array_size > pci_bios_maxbus + 1) + if (array_size > pci_boot_maxbus + 1) return; /* array is big enough */ old_size = array_size; @@ -3665,7 +3423,7 @@ alloc_res_array(void) if (array_size == 0) array_size = 16; /* start with a reasonable number */ - while (array_size <= pci_bios_maxbus + 1) + while (array_size <= pci_boot_maxbus + 1) array_size <<= 1; pci_bus_res = (struct pci_bus_resource *)kmem_zalloc( array_size * sizeof (struct pci_bus_resource), KM_SLEEP); diff --git a/usr/src/uts/intel/io/pci/pci_memlist.c b/usr/src/uts/intel/io/pci/pci_memlist.c index 5786591420..4da76951e9 100644 --- a/usr/src/uts/intel/io/pci/pci_memlist.c +++ b/usr/src/uts/intel/io/pci/pci_memlist.c @@ -40,8 +40,8 @@ #include <sys/pci_impl.h> #include <sys/debug.h> -extern int pci_boot_debug; -#define dprintf if (pci_boot_debug) printf +int pci_memlist_debug; +#define dprintf if (pci_memlist_debug) printf void memlist_dump(struct memlist *listp) diff --git a/usr/src/uts/intel/io/pci/pci_resource.c b/usr/src/uts/intel/io/pci/pci_resource.c deleted file mode 100644 index 57dbe12427..0000000000 --- a/usr/src/uts/intel/io/pci/pci_resource.c +++ /dev/null @@ -1,722 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License (the "License"). - * You may not use this file except in compliance with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2010 Sun Microsystems, Inc. All rights reserved. - * 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 - */ - -#include <sys/types.h> -#include <sys/memlist.h> -#include <sys/pci_impl.h> -#include <sys/systm.h> -#include <sys/cmn_err.h> -#include <sys/acpi/acpi.h> -#include <sys/acpica.h> -#include "mps_table.h" -#include "pcihrt.h" - -extern int pci_boot_debug; -extern int pci_bios_maxbus; -#define dprintf if (pci_boot_debug) printf - -static int tbl_init = 0; -static uchar_t *mps_extp = NULL; -static uchar_t *mps_ext_endp = NULL; -static struct php_entry *hrt_hpep; -static int hrt_entry_cnt = 0; -static int acpi_cb_cnt = 0; - -static void mps_probe(void); -static void acpi_pci_probe(void); -static int mps_find_bus_res(int, int, struct memlist **); -static void hrt_probe(void); -static int hrt_find_bus_res(int, int, struct memlist **); -static int acpi_find_bus_res(int, int, struct memlist **); -static uchar_t *find_sig(uchar_t *cp, int len, char *sig); -static int checksum(unsigned char *cp, int len); -static ACPI_STATUS acpi_wr_cb(ACPI_RESOURCE *rp, void *context); -void bus_res_fini(void); -static void acpi_trim_bus_ranges(void); - -struct memlist *acpi_io_res[256]; -struct memlist *acpi_mem_res[256]; -struct memlist *acpi_pmem_res[256]; -struct memlist *acpi_bus_res[256]; - -/* - * -1 = attempt ACPI resource discovery - * 0 = don't attempt ACPI resource discovery - * 1 = ACPI resource discovery successful - */ -volatile int acpi_resource_discovery = -1; - -struct memlist * -find_bus_res(int bus, int type) -{ - struct memlist *res = NULL; - boolean_t bios = B_TRUE; - - /* if efi-systab property exist, there is no BIOS */ - if (ddi_prop_exists(DDI_DEV_T_ANY, ddi_root_node(), DDI_PROP_DONTPASS, - "efi-systab")) { - bios = B_FALSE; - } - - if (tbl_init == 0) { - tbl_init = 1; - acpi_pci_probe(); - if (bios) { - hrt_probe(); - mps_probe(); - } - } - - if (acpi_find_bus_res(bus, type, &res) > 0) - return (res); - - if (bios && hrt_find_bus_res(bus, type, &res) > 0) - return (res); - - if (bios) - (void) mps_find_bus_res(bus, type, &res); - return (res); -} - - -static void -acpi_pci_probe(void) -{ - ACPI_HANDLE ah; - dev_info_t *dip; - int bus; - - if (acpi_resource_discovery == 0) - return; - - for (bus = 0; bus <= pci_bios_maxbus; bus++) { - /* if no dip or no ACPI handle, no resources to discover */ - dip = pci_bus_res[bus].dip; - if ((dip == NULL) || - (ACPI_FAILURE(acpica_get_handle(dip, &ah)))) - continue; - - (void) AcpiWalkResources(ah, "_CRS", acpi_wr_cb, - (void *)(uintptr_t)bus); - } - - if (acpi_cb_cnt > 0) { - acpi_resource_discovery = 1; - acpi_trim_bus_ranges(); - } -} - -/* - * Trim overlapping bus ranges in acpi_bus_res[] - * Some BIOSes report root-bridges with bus ranges that - * overlap, for example:"0..255" and "8..255". Lower-numbered - * ranges are trimmed by upper-numbered ranges (so "0..255" would - * be trimmed to "0..7", in the example). - */ -static void -acpi_trim_bus_ranges() -{ - struct memlist *ranges, *current; - int bus; - - ranges = NULL; - - /* - * Assumptions: - * - there exists at most 1 bus range entry for each bus number - * - there are no (broken) ranges that start at the same bus number - */ - for (bus = 0; bus < 256; bus++) { - struct memlist *prev, *orig, *new; - /* skip buses with no range entry */ - if ((orig = acpi_bus_res[bus]) == NULL) - continue; - - /* - * create copy of existing range and overload - * 'prev' pointer to link existing to new copy - */ - new = memlist_alloc(); - new->ml_address = orig->ml_address; - new->ml_size = orig->ml_size; - new->ml_prev = orig; - - /* sorted insertion of 'new' into ranges list */ - for (current = ranges, prev = NULL; current != NULL; - prev = current, current = current->ml_next) - if (new->ml_address < current->ml_address) - break; - - if (prev == NULL) { - /* place at beginning of (possibly) empty list */ - new->ml_next = ranges; - ranges = new; - } else { - /* place in list (possibly at end) */ - new->ml_next = current; - prev->ml_next = new; - } - } - - /* scan the list, perform trimming */ - current = ranges; - while (current != NULL) { - struct memlist *next = current->ml_next; - - /* done when no range above current */ - if (next == NULL) - break; - - /* - * trim size in original range element - * (current->ml_prev points to the original range) - */ - if ((current->ml_address + current->ml_size) > next->ml_address) - current->ml_prev->ml_size = - next->ml_address - current->ml_address; - - current = next; - } - - /* discard the list */ - memlist_free_all(&ranges); /* OK if ranges == NULL */ -} - -static int -acpi_find_bus_res(int bus, int type, struct memlist **res) -{ - - switch (type) { - case IO_TYPE: - *res = acpi_io_res[bus]; - break; - case MEM_TYPE: - *res = acpi_mem_res[bus]; - break; - case PREFETCH_TYPE: - *res = acpi_pmem_res[bus]; - break; - case BUSRANGE_TYPE: - *res = acpi_bus_res[bus]; - break; - default: - *res = NULL; - break; - } - - /* memlist_count() treats NULL head as zero-length */ - return (memlist_count(*res)); -} - -void -bus_res_fini(void) -{ - int bus; - - for (bus = 0; bus <= pci_bios_maxbus; bus++) { - memlist_free_all(&acpi_io_res[bus]); - memlist_free_all(&acpi_mem_res[bus]); - memlist_free_all(&acpi_pmem_res[bus]); - memlist_free_all(&acpi_bus_res[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_IO_RANGE: - return (&acpi_io_res[bus]); - break; - - case ACPI_BUS_NUMBER_RANGE: - return (&acpi_bus_res[bus]); - break; - } - - 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); -} - - -ACPI_STATUS -acpi_wr_cb(ACPI_RESOURCE *rp, void *context) -{ - int bus = (intptr_t)context; - - /* ignore consumed resources */ - if (rp->Data.Address.ProducerConsumer == 1) - return (AE_OK); - - switch (rp->Type) { - case ACPI_RESOURCE_TYPE_IRQ: - /* never expect to see a PCI bus produce an Interrupt */ - dprintf("%s\n", "IRQ"); - break; - - case ACPI_RESOURCE_TYPE_DMA: - /* never expect to see a PCI bus produce DMA */ - dprintf("%s\n", "DMA"); - break; - - case ACPI_RESOURCE_TYPE_START_DEPENDENT: - dprintf("%s\n", "START_DEPENDENT"); - break; - - case ACPI_RESOURCE_TYPE_END_DEPENDENT: - dprintf("%s\n", "END_DEPENDENT"); - break; - - case ACPI_RESOURCE_TYPE_IO: - if (rp->Data.Io.AddressLength == 0) - break; - 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: - /* only expect to see this as a consumer */ - dprintf("%s\n", "FIXED_IO"); - break; - - case ACPI_RESOURCE_TYPE_VENDOR: - dprintf("%s\n", "VENDOR"); - break; - - case ACPI_RESOURCE_TYPE_END_TAG: - dprintf("%s\n", "END_TAG"); - break; - - case ACPI_RESOURCE_TYPE_MEMORY24: - /* only expect to see this as a consumer */ - dprintf("%s\n", "MEMORY24"); - break; - - case ACPI_RESOURCE_TYPE_MEMORY32: - /* only expect to see this as a consumer */ - dprintf("%s\n", "MEMORY32"); - break; - - case ACPI_RESOURCE_TYPE_FIXED_MEMORY32: - /* only expect to see this as a consumer */ - dprintf("%s\n", "FIXED_MEMORY32"); - break; - - case ACPI_RESOURCE_TYPE_ADDRESS16: - if (rp->Data.Address16.Address.AddressLength == 0) - break; - acpi_cb_cnt++; - memlist_insert(rlistpp(rp->Data.Address16.ResourceType, - 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: - if (rp->Data.Address32.Address.AddressLength == 0) - break; - acpi_cb_cnt++; - memlist_insert(rlistpp(rp->Data.Address32.ResourceType, - 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: - if (rp->Data.Address64.Address.AddressLength == 0) - break; - - acpi_cb_cnt++; - memlist_insert(rlistpp(rp->Data.Address64.ResourceType, - 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 (rp->Data.ExtAddress64.Address.AddressLength == 0) - break; - acpi_cb_cnt++; - memlist_insert(rlistpp(rp->Data.ExtAddress64.ResourceType, - 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: - /* never expect to see a PCI bus produce an Interrupt */ - dprintf("%s\n", "EXTENDED_IRQ"); - break; - - case ACPI_RESOURCE_TYPE_GENERIC_REGISTER: - /* never expect to see a PCI bus produce an GAS */ - dprintf("%s\n", "GENERIC_REGISTER"); - break; - } - - return (AE_OK); -} - -static void -mps_probe() -{ - uchar_t *extp; - struct mps_fps_hdr *fpp = NULL; - struct mps_ct_hdr *ctp; - uintptr_t ebda_start, base_end; - ushort_t ebda_seg, base_size, ext_len, base_len, base_end_seg; - - base_size = *((ushort_t *)(0x413)); - ebda_seg = *((ushort_t *)(0x40e)); - ebda_start = ((uint32_t)ebda_seg) << 4; - if (ebda_seg != 0) { - fpp = (struct mps_fps_hdr *)find_sig( - (uchar_t *)ebda_start, 1024, "_MP_"); - } - if (fpp == NULL) { - base_end_seg = (base_size > 512) ? 0x9FC0 : 0x7FC0; - if (base_end_seg != ebda_seg) { - base_end = ((uintptr_t)base_end_seg) << 4; - fpp = (struct mps_fps_hdr *)find_sig( - (uchar_t *)base_end, 1024, "_MP_"); - } - } - if (fpp == NULL) { - fpp = (struct mps_fps_hdr *)find_sig( - (uchar_t *)0xF0000, 0x10000, "_MP_"); - } - - if (fpp == NULL) { - dprintf("MP Spec table doesn't exist"); - return; - } else { - dprintf("Found MP Floating Pointer Structure at %p\n", - (void *)fpp); - } - - if (checksum((uchar_t *)fpp, fpp->fps_len * 16) != 0) { - dprintf("MP Floating Pointer Structure checksum error"); - return; - } - - ctp = (struct mps_ct_hdr *)(uintptr_t)fpp->fps_mpct_paddr; - if (ctp->ct_sig != 0x504d4350) { /* check "PCMP" signature */ - dprintf("MP Configuration Table signature is wrong"); - return; - } - - base_len = ctp->ct_len; - if (checksum((uchar_t *)ctp, base_len) != 0) { - dprintf("MP Configuration Table checksum error"); - return; - } - if (ctp->ct_spec_rev != 4) { /* not MPSpec rev 1.4 */ - dprintf("MP Spec 1.1 found - extended table doesn't exist"); - return; - } - if ((ext_len = ctp->ct_ext_tbl_len) == 0) { - dprintf("MP Spec 1.4 found - extended table doesn't exist"); - return; - } - extp = (uchar_t *)ctp + base_len; - if (((checksum(extp, ext_len) + ctp->ct_ext_cksum) & 0xFF) != 0) { - dprintf("MP Extended Table checksum error"); - return; - } - mps_extp = extp; - mps_ext_endp = mps_extp + ext_len; -} - - -static int -mps_find_bus_res(int bus, int type, struct memlist **res) -{ - struct sasm *sasmp; - uchar_t *extp; - int res_cnt; - - if (mps_extp == NULL) - return (0); - extp = mps_extp; - res_cnt = 0; - while (extp < mps_ext_endp) { - switch (*extp) { - case SYS_AS_MAPPING: - sasmp = (struct sasm *)extp; - if (((int)sasmp->sasm_as_type) == type && - ((int)sasmp->sasm_bus_id) == bus) { - uint64_t base, len; - - base = (uint64_t)sasmp->sasm_as_base | - (uint64_t)sasmp->sasm_as_base_hi << 32; - len = (uint64_t)sasmp->sasm_as_len | - (uint64_t)sasmp->sasm_as_len_hi << 32; - memlist_insert(res, base, len); - res_cnt++; - } - extp += SYS_AS_MAPPING_SIZE; - break; - case BUS_HIERARCHY_DESC: - extp += BUS_HIERARCHY_DESC_SIZE; - break; - case COMP_BUS_AS_MODIFIER: - extp += COMP_BUS_AS_MODIFIER_SIZE; - break; - default: - cmn_err(CE_WARN, "Unknown descriptor type %d" - " in BIOS Multiprocessor Spec table.", - *extp); - while (*res) { - struct memlist *tmp = *res; - *res = tmp->ml_next; - memlist_free(tmp); - } - return (0); - } - } - return (res_cnt); -} - -static void -hrt_probe() -{ - struct hrt_hdr *hrtp; - - dprintf("search PCI Hot-Plug Resource Table starting at 0xF0000\n"); - if ((hrtp = (struct hrt_hdr *)find_sig((uchar_t *)0xF0000, - 0x10000, "$HRT")) == NULL) { - dprintf("NO PCI Hot-Plug Resource Table"); - return; - } - dprintf("Found PCI Hot-Plug Resource Table at %p\n", (void *)hrtp); - if (hrtp->hrt_ver != 1) { - dprintf("PCI Hot-Plug Resource Table version no. <> 1\n"); - return; - } - hrt_entry_cnt = (int)hrtp->hrt_entry_cnt; - dprintf("No. of PCI hot-plug slot entries = 0x%x\n", hrt_entry_cnt); - hrt_hpep = (struct php_entry *)(hrtp + 1); -} - -static int -hrt_find_bus_res(int bus, int type, struct memlist **res) -{ - int res_cnt, i; - struct php_entry *hpep; - - if (hrt_hpep == NULL || hrt_entry_cnt == 0) - return (0); - hpep = hrt_hpep; - res_cnt = 0; - for (i = 0; i < hrt_entry_cnt; i++, hpep++) { - if (hpep->php_pri_bus != bus) - continue; - if (type == IO_TYPE) { - if (hpep->php_io_start == 0 || hpep->php_io_size == 0) - continue; - memlist_insert(res, (uint64_t)hpep->php_io_start, - (uint64_t)hpep->php_io_size); - res_cnt++; - } else if (type == MEM_TYPE) { - if (hpep->php_mem_start == 0 || hpep->php_mem_size == 0) - continue; - memlist_insert(res, - (uint64_t)(((int)hpep->php_mem_start) << 16), - (uint64_t)(((int)hpep->php_mem_size) << 16)); - res_cnt++; - } else if (type == PREFETCH_TYPE) { - if (hpep->php_pfmem_start == 0 || - hpep->php_pfmem_size == 0) - continue; - memlist_insert(res, - (uint64_t)(((int)hpep->php_pfmem_start) << 16), - (uint64_t)(((int)hpep->php_pfmem_size) << 16)); - res_cnt++; - } - } - return (res_cnt); -} - -static uchar_t * -find_sig(uchar_t *cp, int len, char *sig) -{ - long i; - - /* Search for the "_MP_" or "$HRT" signature */ - for (i = 0; i < len; i += 16) { - if (cp[0] == sig[0] && cp[1] == sig[1] && - cp[2] == sig[2] && cp[3] == sig[3]) - return (cp); - cp += 16; - } - return (NULL); -} - -static int -checksum(unsigned char *cp, int len) -{ - int i; - unsigned int cksum; - - for (i = cksum = 0; i < len; i++) - cksum += (unsigned int) *cp++; - - return ((int)(cksum & 0xFF)); -} - -#ifdef UNUSED_BUS_HIERARY_INFO - -/* - * At this point, the bus hierarchy entries do not appear to - * provide anything we can't find out from PCI config space. - * The only interesting bit is the ISA bus number, which we - * don't care. - */ -int -mps_find_parent_bus(int bus) -{ - struct sasm *sasmp; - uchar_t *extp; - - if (mps_extp == NULL) - return (-1); - - extp = mps_extp; - while (extp < mps_ext_endp) { - bhdp = (struct bhd *)extp; - switch (*extp) { - case SYS_AS_MAPPING: - extp += SYS_AS_MAPPING_SIZE; - break; - case BUS_HIERARCHY_DESC: - if (bhdp->bhd_bus_id == bus) - return (bhdp->bhd_parent); - extp += BUS_HIERARCHY_DESC_SIZE; - break; - case COMP_BUS_AS_MODIFIER: - extp += COMP_BUS_AS_MODIFIER_SIZE; - break; - default: - cmn_err(CE_WARN, "Unknown descriptor type %d" - " in BIOS Multiprocessor Spec table.", - *extp); - return (-1); - } - } - return (-1); -} - -int -hrt_find_bus_range(int bus) -{ - int i, max_bus, sub_bus; - struct php_entry *hpep; - - if (hrt_hpep == NULL || hrt_entry_cnt == 0) { - return (-1); - } - hpep = hrt_hpep; - max_bus = -1; - for (i = 0; i < hrt_entry_cnt; i++, hpep++) { - if (hpep->php_pri_bus != bus) - continue; - sub_bus = (int)hpep->php_subord_bus; - if (sub_bus > max_bus) - max_bus = sub_bus; - } - return (max_bus); -} - -#endif /* UNUSED_BUS_HIERARY_INFO */ diff --git a/usr/src/uts/intel/io/pci/pcihrt.h b/usr/src/uts/intel/io/pci/pcihrt.h deleted file mode 100644 index 7192eca2c5..0000000000 --- a/usr/src/uts/intel/io/pci/pcihrt.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - * CDDL HEADER START - * - * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. - * - * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE - * or http://www.opensolaris.org/os/licensing. - * See the License for the specific language governing permissions - * and limitations under the License. - * - * When distributing Covered Code, include this CDDL HEADER in each - * file and include the License file at usr/src/OPENSOLARIS.LICENSE. - * If applicable, add the following below this CDDL HEADER, with the - * fields enclosed by brackets "[]" replaced with your own identifying - * information: Portions Copyright [yyyy] [name of copyright owner] - * - * CDDL HEADER END - */ -/* - * Copyright 2005 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. - */ - -/* - * pcihrt.h -- PCI Hot-Plug Resource Table - */ - -#ifndef _PCIHRT_H -#define _PCIHRT_H - -#pragma ident "%Z%%M% %I% %E% SMI" - -#ifdef __cplusplus -extern "C" { -#endif - -struct hrt_hdr { /* PCI Hot-Plug Configuration Resource Table header */ - uint32_t hrt_sig; /* $HRT */ - uint16_t hrt_avail_imap; /* Bitmap of unused IRQs */ - uint16_t hrt_used_imap; /* Bitmap of IRQs used by PCI */ - uchar_t hrt_entry_cnt; /* no. of PCI hot-plug slot entries */ - uchar_t hrt_ver; /* version no. = 1 */ - uchar_t hrt_resv0; /* reserved */ - uchar_t hrt_resv1; /* reserved */ - uchar_t hrt_resv2; /* reserved */ - uchar_t hrt_resv3; /* reserved */ - uchar_t hrt_resv4; /* reserved */ - uchar_t hrt_resv5; /* reserved */ -}; - -struct php_entry { /* PCI hot-plug slot entry */ - uchar_t php_devno; /* PCI dev/func no. of the slot */ - uchar_t php_pri_bus; /* Primary bus of this slot */ - uchar_t php_sec_bus; /* Secondary bus of this slot */ - uchar_t php_subord_bus; /* Max Subordinate bus of this slot */ - uint16_t php_io_start; /* allocated I/O space starting addr */ - uint16_t php_io_size; /* allocated I/O space size in bytes */ - uint16_t php_mem_start; /* allocated Memory space start addr */ - uint16_t php_mem_size; /* allocated Memory space size in 64k */ - uint16_t php_pfmem_start; /* allocated Prefetchable Memory start */ - uint16_t php_pfmem_size; /* allocated Prefetchable size in 64k */ -}; - -#ifdef __cplusplus -} -#endif - -#endif /* _PCIHRT_H */ diff --git a/usr/src/uts/intel/pci_autoconfig/Makefile b/usr/src/uts/intel/pci_autoconfig/Makefile index 74498aea94..f3c034cb03 100644 --- a/usr/src/uts/intel/pci_autoconfig/Makefile +++ b/usr/src/uts/intel/pci_autoconfig/Makefile @@ -57,9 +57,9 @@ ALL_TARGET = $(BINARY) INSTALL_TARGET = $(BINARY) $(ROOTMODULE) # -# Depends on acpica ACPI CA interpreter and PCI-E framework +# Depends on the platform's resource discovery and PCI-E framework # -LDFLAGS += -Nmisc/acpica -Nmisc/pcie +LDFLAGS += -Nmisc/pcie -Nmisc/pci_prd # # Default build targets. |