From 36a16f5c7fa0a037b48d0a91dff4fdcf81ed162f Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 30 Sep 2015 14:52:57 +0200 Subject: i386: Quick and dirty hack to get PCI working --- freebsd/sys/dev/pci/pci.c | 9 +++++ freebsd/sys/x86/pci/pci_bus.c | 6 ++++ libbsd.txt | 2 ++ rtemsbsd/rtems/rtems-bsd-nexus.c | 73 +++++++++++++++++++++++++++++++++++++--- 4 files changed, 86 insertions(+), 4 deletions(-) diff --git a/freebsd/sys/dev/pci/pci.c b/freebsd/sys/dev/pci/pci.c index 426d06a2..e76b6b9e 100644 --- a/freebsd/sys/dev/pci/pci.c +++ b/freebsd/sys/dev/pci/pci.c @@ -4206,6 +4206,15 @@ pci_reserve_map(device_t dev, device_t child, int type, int *rid, * Allocate enough resource, and then write back the * appropriate BAR for that resource. */ +#if defined(__rtems__) && defined(__i386__) + /* + * FIXME: This is a quick and dirty hack. Use the BIOS or whoever + * provided values. The nexus device reserves such allocation requests + * offhandedly. + */ + start = map; + end = map + count; +#endif /* __rtems__ */ resource_list_add(rl, type, *rid, start, end, count); res = resource_list_reserve(rl, dev, child, type, rid, start, end, count, flags & ~RF_ACTIVE); diff --git a/freebsd/sys/x86/pci/pci_bus.c b/freebsd/sys/x86/pci/pci_bus.c index 7e4e07f4..c14b17ff 100644 --- a/freebsd/sys/x86/pci/pci_bus.c +++ b/freebsd/sys/x86/pci/pci_bus.c @@ -600,7 +600,13 @@ legacy_pcib_alloc_resource(device_t dev, device_t child, int type, int *rid, u_long start, u_long end, u_long count, u_int flags) { +#if defined(__rtems__) && defined(__i386__) + /* + * FIXME: This is a quick and dirty hack. See pci_reserve_map(). + */ +#else /* __rtems__ */ start = hostb_alloc_start(type, start, end, count); +#endif /* __rtems__ */ return (bus_generic_alloc_resource(dev, child, type, rid, start, end, count, flags)); } diff --git a/libbsd.txt b/libbsd.txt index 06d833fd..a4368069 100644 --- a/libbsd.txt +++ b/libbsd.txt @@ -326,6 +326,8 @@ rtems_mdns_gethostname(). == Issues and TODO +* PCI support on x86 uses a quick and dirty hack, see pci_reserve_map(). + * Priority queues are broken with clustered scheduling. * Per-CPU data should be enabled once the new stack is ready for SMP. diff --git a/rtemsbsd/rtems/rtems-bsd-nexus.c b/rtemsbsd/rtems/rtems-bsd-nexus.c index f7e4eba5..22c56040 100644 --- a/rtemsbsd/rtems/rtems-bsd-nexus.c +++ b/rtemsbsd/rtems/rtems-bsd-nexus.c @@ -48,6 +48,7 @@ #include #include #include +#include #include #include @@ -66,6 +67,10 @@ static struct rman mem_rman; static struct rman irq_rman; +#ifdef __i386__ +static struct rman port_rman; +#endif + static int nexus_probe(device_t dev) { @@ -105,6 +110,18 @@ nexus_probe(device_t dev) err = rman_manage_region(&irq_rman, irq_rman.rm_start, irq_rman.rm_end); BSD_ASSERT(err == 0); +#ifdef __i386__ + port_rman.rm_start = 0; + port_rman.rm_end = 0xffff; + port_rman.rm_type = RMAN_ARRAY; + port_rman.rm_descr = "I/O ports"; + err = rman_init(&port_rman) != 0; + BSD_ASSERT(err == 0); + err = rman_manage_region(&port_rman, port_rman.rm_start, + port_rman.rm_end); + BSD_ASSERT(err == 0); +#endif + SET_FOREACH(nd, nexus) { device_add_child(dev, nd->name, nd->unit); } @@ -135,6 +152,7 @@ static struct resource * nexus_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 = NULL; struct rman *rm; const rtems_bsd_device *nd; @@ -145,15 +163,18 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, case SYS_RES_IRQ: rm = &irq_rman; break; +#ifdef __i386__ + case SYS_RES_IOPORT: + rm = &port_rman; + break; +#endif default: - return (NULL); + return (res); } SET_FOREACH(nd, nexus) { if (strcmp(device_get_name(child), nd->name) == 0 && device_get_unit(child) == nd->unit) { - struct resource *res = NULL; - if (nexus_get_start(nd, type, &start)) { res = rman_reserve_resource(rm, start, end, count, flags, child); @@ -168,7 +189,22 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, } } - return (NULL); +#ifdef __i386__ + /* + * FIXME: This is a quick and dirty hack. Simply reserve resources of + * this kind. See also pci_reserve_map(). + */ + if (start + count - end <= 1UL) { + res = rman_reserve_resource(rm, start, end, count, flags, + child); + if (res != NULL) { + rman_set_rid(res, *rid); + rman_set_bushandle(res, rman_get_start(res)); + } + } +#endif + + return (res); } static int @@ -178,6 +214,31 @@ nexus_release_resource(device_t bus, device_t child, int type, int rid, return (rman_release_resource(res)); } +#ifdef __i386__ +static int +nexus_activate_resource(device_t bus, device_t child, int type, int rid, + struct resource *res) +{ + switch (type) { + case SYS_RES_IOPORT: + rman_set_bustag(res, X86_BUS_SPACE_IO); + break; + case SYS_RES_MEMORY: + rman_set_bustag(res, X86_BUS_SPACE_MEM); + break; + } + return (rman_activate_resource(res)); +} + +static int +nexus_deactivate_resource(device_t bus, device_t child, int type, int rid, + struct resource *res) +{ + + return (rman_deactivate_resource(res)); +} +#endif + struct nexus_intr { driver_filter_t *filt; driver_intr_t *intr; @@ -292,6 +353,10 @@ static device_method_t nexus_methods[] = { DEVMETHOD(bus_add_child, bus_generic_add_child), DEVMETHOD(bus_alloc_resource, nexus_alloc_resource), DEVMETHOD(bus_release_resource, nexus_release_resource), +#ifdef __i386__ + DEVMETHOD(bus_activate_resource, nexus_activate_resource), + DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource), +#endif DEVMETHOD(bus_setup_intr, nexus_setup_intr), DEVMETHOD(bus_teardown_intr, nexus_teardown_intr), -- cgit v1.2.3