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:
parent
2d898efa0f
commit
f2eeadb198
@ -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.
|
||||
#
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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),
|
||||
|
Loading…
Reference in New Issue
Block a user