pci_resource.c revision 8fc7923fdc5ec102fd07ccf5c85608bb0e55f529
/*
* 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
* 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 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* pci_resource.c -- routines to retrieve available bus resources from
* the MP Spec. Table and Hotplug Resource Table
*/
#include <sys/pci_impl.h>
#include "mps_table.h"
#include "pcihrt.h"
extern int pci_boot_debug;
extern int pci_bios_nbus;
static int tbl_init = 0;
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 **);
void bus_res_fini(void);
/*
* -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 *
{
if (tbl_init == 0) {
tbl_init = 1;
hrt_probe();
mps_probe();
}
return (res);
return (res);
return (res);
}
static void
acpi_pci_probe(void)
{
int bus;
if (acpi_resource_discovery == 0)
return;
/* if no dip or no ACPI handle, no resources to discover */
continue;
}
if (acpi_cb_cnt > 0)
}
static int
{
switch (type) {
case IO_TYPE:
break;
case MEM_TYPE:
break;
case PREFETCH_TYPE:
break;
case BUSRANGE_TYPE:
break;
default:
break;
}
/* memlist_count() treats NULL head as zero-length */
return (memlist_count(*res));
}
void
bus_res_fini(void)
{
int bus;
}
}
struct memlist **
{
switch (t) {
case ACPI_MEMORY_RANGE:
/* is this really the best we've got? */
return (&acpi_pmem_res[bus]);
else
return (&acpi_mem_res[bus]);
}
}
{
/* ignore consumed resources */
return (AE_OK);
case ACPI_RESOURCE_TYPE_IRQ:
/* never expect to see a PCI bus produce an Interrupt */
break;
case ACPI_RESOURCE_TYPE_DMA:
/* never expect to see a PCI bus produce DMA */
break;
break;
break;
case ACPI_RESOURCE_TYPE_IO:
break;
acpi_cb_cnt++;
break;
/* only expect to see this as a consumer */
break;
break;
break;
/* only expect to see this as a consumer */
break;
/* only expect to see this as a consumer */
break;
/* only expect to see this as a consumer */
break;
break;
acpi_cb_cnt++;
break;
break;
acpi_cb_cnt++;
break;
break;
acpi_cb_cnt++;
break;
break;
acpi_cb_cnt++;
break;
/* never expect to see a PCI bus produce an Interrupt */
break;
/* never expect to see a PCI bus produce an GAS */
break;
}
return (AE_OK);
}
static void
{
struct mps_ct_hdr *ctp;
if (ebda_seg != 0) {
}
if (base_end_seg != ebda_seg) {
}
}
}
dprintf("MP Spec table doesn't exist");
return;
} else {
dprintf("Found MP Floating Pointer Structure at %p\n",
(void *)fpp);
}
dprintf("MP Floating Pointer Structure checksum error");
return;
}
dprintf("MP Configuration Table signature is wrong");
return;
}
dprintf("MP Configuration Table checksum error");
return;
}
dprintf("MP Spec 1.1 found - extended table doesn't exist");
return;
}
dprintf("MP Spec 1.4 found - extended table doesn't exist");
return;
}
dprintf("MP Extended Table checksum error");
return;
}
}
static int
{
int res_cnt;
return (0);
res_cnt = 0;
while (extp < mps_ext_endp) {
switch (*extp) {
case SYS_AS_MAPPING:
if (sasmp->sasm_as_base_hi != 0 ||
sasmp->sasm_as_len_hi != 0) {
printf("64 bits address space\n");
break;
}
sasmp->sasm_as_len);
res_cnt++;
}
break;
case BUS_HIERARCHY_DESC:
break;
case COMP_BUS_AS_MODIFIER:
break;
default:
" in BIOS Multiprocessor Spec table.",
*extp);
while (*res) {
}
return (0);
}
}
return (res_cnt);
}
static void
{
dprintf("search PCI Hot-Plug Resource Table starting at 0xF0000\n");
dprintf("NO PCI Hot-Plug Resource Table");
return;
}
dprintf("PCI Hot-Plug Resource Table version no. <> 1\n");
return;
}
}
static int
{
int res_cnt, i;
return (0);
res_cnt = 0;
for (i = 0; i < hrt_entry_cnt; i++, hpep++) {
continue;
continue;
res_cnt++;
continue;
res_cnt++;
} else if (type == PREFETCH_TYPE) {
if (hpep->php_pfmem_start == 0 ||
hpep->php_pfmem_size == 0)
continue;
res_cnt++;
}
}
return (res_cnt);
}
static uchar_t *
{
long i;
/* Search for the "_MP_" or "$HRT" signature */
for (i = 0; i < len; i += 16) {
return (cp);
cp += 16;
}
return (NULL);
}
static int
{
int i;
unsigned int cksum;
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)
{
return (-1);
while (extp < mps_ext_endp) {
switch (*extp) {
case SYS_AS_MAPPING:
break;
case BUS_HIERARCHY_DESC:
return (bhdp->bhd_parent);
break;
case COMP_BUS_AS_MODIFIER:
break;
default:
" in BIOS Multiprocessor Spec table.",
*extp);
return (-1);
}
}
return (-1);
}
int
hrt_find_bus_range(int bus)
{
return (-1);
}
max_bus = -1;
for (i = 0; i < hrt_entry_cnt; i++, hpep++) {
continue;
}
return (max_bus);
}
#endif /* UNUSED_BUS_HIERARY_INFO */