Remove the PCI_IOSPACE_SIZE and PCI_IOSPACE_ADDR hack from nexus.c. Implement

this in the Sibyte PCI hostbridge driver instead.

The nexus driver sees resource allocation requests for memory and irq
resources only. These are legitimate resources on all MIPS platforms.

Suggested by: imp
This commit is contained in:
neel 2010-02-12 02:59:49 +00:00
parent 2d898efa0f
commit f2eeadb198
4 changed files with 132 additions and 47 deletions

View File

@ -60,14 +60,6 @@ TARGET_XLR_XLS opt_global.h
TICK_USE_YAMON_FREQ opt_global.h
TICK_USE_MALTA_RTC opt_global.h
#
# The MIPS architecture does not have separate memory and i/o address space
# like x86. However some MIPS processors provide a memory-mapped window that
# maps onto the PCI I/O space.
#
PCI_IOSPACE_SIZE opt_global.h
PCI_IOSPACE_ADDR opt_global.h
#
# The highest memory address that can be used by the kernel in units of KB.
#

View File

@ -8,9 +8,6 @@ options CPU_SB1
files "../sibyte/files.sibyte"
hints "SWARM.hints"
options PCI_IOSPACE_ADDR=0xFC000000
options PCI_IOSPACE_SIZE=0x02000000
#
# 32-bit kernel cannot deal with physical memory beyond 4GB
# XXX pmap assumes that all the memory can be mapped using KSEG0

View File

@ -77,7 +77,6 @@ struct nexus_device {
static struct rman irq_rman;
static struct rman mem_rman;
static struct rman port_rman;
static struct resource *
nexus_alloc_resource(device_t, device_t, int, int *, u_long,
@ -161,21 +160,6 @@ nexus_probe(device_t dev)
panic("%s: mem_rman", __func__);
}
/*
* MIPS has no concept of the x86 I/O address space but some cpus
* provide a memory mapped window to access the PCI I/O BARs.
*/
port_rman.rm_start = 0;
#ifdef PCI_IOSPACE_SIZE
port_rman.rm_end = PCI_IOSPACE_SIZE - 1;
#endif
port_rman.rm_type = RMAN_ARRAY;
port_rman.rm_descr = "I/O ports";
if (rman_init(&port_rman) != 0 ||
rman_manage_region(&port_rman, 0, port_rman.rm_end) != 0)
panic("%s: port_rman", __func__);
return (0);
}
@ -241,7 +225,6 @@ nexus_print_all_resources(device_t dev)
retval += resource_list_print_type(rl, "mem", SYS_RES_MEMORY, "%#lx");
retval += resource_list_print_type(rl, "irq", SYS_RES_IRQ, "%ld");
retval += resource_list_print_type(rl, "port", SYS_RES_IOPORT, "%#lx");
return (retval);
}
@ -368,9 +351,6 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid,
case SYS_RES_MEMORY:
rm = &mem_rman;
break;
case SYS_RES_IOPORT:
rm = &port_rman;
break;
default:
printf("%s: unknown resource type %d\n", __func__, type);
return (0);
@ -400,21 +380,17 @@ static int
nexus_activate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
void *vaddr;
u_int32_t paddr, psize;
/*
* If this is a memory resource, track the direct mapping
* in the uncached MIPS KSEG1 segment.
*/
/* XXX we shouldn't be supporting sys_res_ioport here */
if ((type == SYS_RES_MEMORY) || (type == SYS_RES_IOPORT)) {
caddr_t vaddr = 0;
u_int32_t paddr;
u_int32_t psize;
u_int32_t poffs;
if (type == SYS_RES_MEMORY) {
paddr = rman_get_start(r);
psize = rman_get_size(r);
poffs = paddr - trunc_page(paddr);
vaddr = (caddr_t) pmap_mapdev(paddr-poffs, psize+poffs) + poffs;
vaddr = pmap_mapdev(paddr, psize);
rman_set_virtual(r, vaddr);
rman_set_bustag(r, mips_bus_space_generic);
@ -501,7 +477,7 @@ nexus_deactivate_resource(device_t bus, device_t child, int type, int rid,
{
vm_offset_t va;
if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) {
if (type == SYS_RES_MEMORY) {
va = (vm_offset_t)rman_get_virtual(r);
pmap_unmapdev(va, rman_get_size(r));
}

View File

@ -30,6 +30,7 @@
#include <sys/systm.h>
#include <sys/module.h>
#include <sys/bus.h>
#include <sys/rman.h>
#include <sys/pcpu.h>
#include <sys/smp.h>
@ -45,6 +46,7 @@
#include <machine/pmap.h>
#include <machine/resource.h>
#include <machine/bus.h>
#include "pcib_if.h"
@ -58,7 +60,11 @@ static struct {
} zbpci_config_space[MAXCPU];
static const vm_paddr_t CFG_PADDR_BASE = 0xFE000000;
static const u_long PCI_IOSPACE_ADDR = 0xFC000000;
static const u_long PCI_IOSPACE_SIZE = 0x02000000;
static struct rman port_rman;
static int
zbpci_probe(device_t dev)
{
@ -73,13 +79,32 @@ zbpci_attach(device_t dev)
int n, rid, size;
vm_offset_t va;
struct resource *res;
/*
* Reserve the physical memory window used to map PCI I/O space.
*/
rid = 0;
res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid,
PCI_IOSPACE_ADDR,
PCI_IOSPACE_ADDR + PCI_IOSPACE_SIZE - 1,
PCI_IOSPACE_SIZE, 0);
if (res == NULL)
panic("Cannot allocate resource for PCI I/O space mapping.");
port_rman.rm_start = 0;
port_rman.rm_end = PCI_IOSPACE_SIZE - 1;
port_rman.rm_type = RMAN_ARRAY;
port_rman.rm_descr = "PCI I/O ports";
if (rman_init(&port_rman) != 0 ||
rman_manage_region(&port_rman, 0, PCI_IOSPACE_SIZE - 1) != 0)
panic("%s: port_rman", __func__);
/*
* Reserve the the physical memory that is used to read/write to the
* pci config space but don't activate it. We are using a page worth
* of KVA as a window over this region.
*/
rid = 0;
rid = 1;
size = (PCI_BUSMAX + 1) * (PCI_SLOTMAX + 1) * (PCI_FUNCMAX + 1) * 256;
res = bus_alloc_resource(dev, SYS_RES_MEMORY, &rid, CFG_PADDR_BASE,
CFG_PADDR_BASE + size - 1, size, 0);
@ -115,6 +140,101 @@ zbpci_attach(device_t dev)
return (bus_generic_attach(dev));
}
static struct resource *
zbpci_alloc_resource(device_t bus, device_t child, int type, int *rid,
u_long start, u_long end, u_long count, u_int flags)
{
struct resource *res;
/*
* Handle PCI I/O port resources here and pass everything else to nexus.
*/
if (type != SYS_RES_IOPORT) {
res = bus_generic_alloc_resource(bus, child, type, rid,
start, end, count, flags);
return (res);
}
res = rman_reserve_resource(&port_rman, start, end, count,
flags, child);
if (res == NULL)
return (NULL);
rman_set_rid(res, *rid);
/* Activate the resource is requested */
if (flags & RF_ACTIVE) {
if (bus_activate_resource(child, type, *rid, res) != 0) {
rman_release_resource(res);
return (NULL);
}
}
return (res);
}
static int
zbpci_activate_resource(device_t bus, device_t child, int type, int rid,
struct resource *res)
{
void *vaddr;
u_long paddr, psize;
if (type != SYS_RES_IOPORT) {
return (bus_generic_activate_resource(bus, child, type,
rid, res));
}
/*
* Map the I/O space resource through the memory window starting
* at PCI_IOSPACE_ADDR.
*/
paddr = rman_get_start(res) + PCI_IOSPACE_ADDR;
psize = rman_get_size(res);
vaddr = pmap_mapdev(paddr, psize);
rman_set_virtual(res, vaddr);
rman_set_bustag(res, mips_bus_space_generic);
rman_set_bushandle(res, (bus_space_handle_t)vaddr);
return (rman_activate_resource(res));
}
static int
zbpci_release_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
int error;
if (type != SYS_RES_IOPORT)
return (bus_generic_release_resource(bus, child, type, rid, r));
if (rman_get_flags(r) & RF_ACTIVE) {
error = bus_deactivate_resource(child, type, rid, r);
if (error)
return (error);
}
return (rman_release_resource(r));
}
static int
zbpci_deactivate_resource(device_t bus, device_t child, int type, int rid,
struct resource *r)
{
vm_offset_t va;
if (type != SYS_RES_IOPORT) {
return (bus_generic_deactivate_resource(bus, child, type,
rid, r));
}
va = (vm_offset_t)rman_get_virtual(r);
pmap_unmapdev(va, rman_get_size(r));
return (rman_deactivate_resource(r));
}
static int
zbpci_read_ivar(device_t dev, device_t child, int which, uintptr_t *result)
{
@ -248,10 +368,10 @@ static device_method_t zbpci_methods[] ={
/* Bus interface */
DEVMETHOD(bus_read_ivar, zbpci_read_ivar),
DEVMETHOD(bus_write_ivar, bus_generic_write_ivar),
DEVMETHOD(bus_alloc_resource, bus_generic_alloc_resource),
DEVMETHOD(bus_activate_resource, bus_generic_activate_resource),
DEVMETHOD(bus_deactivate_resource, bus_generic_deactivate_resource),
DEVMETHOD(bus_release_resource, bus_generic_release_resource),
DEVMETHOD(bus_alloc_resource, zbpci_alloc_resource),
DEVMETHOD(bus_activate_resource, zbpci_activate_resource),
DEVMETHOD(bus_deactivate_resource, zbpci_deactivate_resource),
DEVMETHOD(bus_release_resource, zbpci_release_resource),
DEVMETHOD(bus_setup_intr, bus_generic_setup_intr),
DEVMETHOD(bus_teardown_intr, bus_generic_teardown_intr),
DEVMETHOD(bus_add_child, bus_generic_add_child),