From: Chris Johns <chr...@rtems.org> - Add PCI IO region support
- Add support map buffers to PCI address space Closes #4245 --- rtemsbsd/include/machine/bus.h | 124 ++++++++++++++++++++++---- rtemsbsd/rtems/rtems-kernel-bus-dma.c | 5 +- rtemsbsd/rtems/rtems-kernel-nexus.c | 23 +++-- 3 files changed, 126 insertions(+), 26 deletions(-) diff --git a/rtemsbsd/include/machine/bus.h b/rtemsbsd/include/machine/bus.h index 2f0e7ad6..8b313f37 100644 --- a/rtemsbsd/include/machine/bus.h +++ b/rtemsbsd/include/machine/bus.h @@ -6,9 +6,13 @@ * @brief TODO. * * File origin from FreeBSD 'sys/amd64/include/bus.h'. + * + * Conditionally supports PCI IO regions (IO Ports). */ /*- + * Copyright (c) 2021 Chris Johns. All rights reserved. + * * Copyright (c) 2009, 2015 embedded brains GmbH. All rights reserved. * * embedded brains GmbH @@ -25,7 +29,7 @@ * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: - * + * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer as * the first lines of this file unmodified. @@ -34,7 +38,7 @@ * documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. @@ -126,6 +130,38 @@ #error "your include paths are wrong" #endif +/* + * Values for the bus space tag, not to be used directly by MI code. + */ +#define BSP_BUS_SPACE_IO 0 /* space is i/o space */ +#define BSP_BUS_SPACE_MEM 1 /* space is mem space */ + +/* + * BSP PCI Support + * + * The RTEMS Nexus bus support can optionaly support PCI spaces that + * mapped to BSP speciic address spaces. Add the following define to + * the BSP header file to enable this support: + * + * #define BSP_HAS_PCI + * + * If enabled a BSP must the following IO region calls: + * + * inb : read 8 bits + * outb : write 8 bits + * inw : read 16 bits + * outw : write 16 bits + * inl : read 32 bits + * outl : write 32 bits + * + * The BSP needs to provide the DRAM address space offset + * PCI_DRAM_OFFSET. This is the base address of the DRAM as seen by a + * PCI master. + * + * i386 BSPs have a special bus.h file and do not use this file. + */ +#include <bsp.h> + /* * Bus address alignment. */ @@ -144,6 +180,7 @@ /* * Bus access. */ +#define BUS_SPACE_INVALID_DATA (~0) #define BUS_SPACE_UNRESTRICTED (~0U) /* @@ -228,29 +265,52 @@ bus_space_barrier(bus_space_tag_t bst __unused, bus_space_handle_t bsh, bus_size * data is returned. */ static __inline uint8_t -bus_space_read_1(bus_space_tag_t bst __unused, bus_space_handle_t bsh, bus_size_t ofs) +bus_space_read_1(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs) { + if (bst == BSP_BUS_SPACE_IO) { +#ifdef BSP_HAS_PCI + return inb(bsh + ofs); +#else + return BUS_SPACE_INVALID_DATA; +#endif + } uint8_t __volatile *bsp = (uint8_t __volatile *)(bsh + ofs); return (*bsp); } static __inline uint16_t -bus_space_read_2(bus_space_tag_t bst __unused, bus_space_handle_t bsh, bus_size_t ofs) +bus_space_read_2(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs) { + if (bst == BSP_BUS_SPACE_IO) { +#ifdef BSP_HAS_PCI + return inw(bsh + ofs); +#else + return BUS_SPACE_INVALID_DATA; +#endif + } uint16_t __volatile *bsp = (uint16_t __volatile *)(bsh + ofs); return (*bsp); } static __inline uint32_t -bus_space_read_4(bus_space_tag_t bst __unused, bus_space_handle_t bsh, bus_size_t ofs) +bus_space_read_4(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs) { + if (bst == BSP_BUS_SPACE_IO) { +#ifdef BSP_HAS_PCI + return inl(bsh + ofs); +#else + return BUS_SPACE_INVALID_DATA; +#endif + } uint32_t __volatile *bsp = (uint32_t __volatile *)(bsh + ofs); return (*bsp); } static __inline uint64_t -bus_space_read_8(bus_space_tag_t bst __unused, bus_space_handle_t bsh, bus_size_t ofs) +bus_space_read_8(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs) { + if (bst == BSP_BUS_SPACE_IO) + return BUS_SPACE_INVALID_DATA; uint64_t __volatile *bsp = (uint64_t __volatile *)(bsh + ofs); return (*bsp); } @@ -262,35 +322,63 @@ bus_space_read_8(bus_space_tag_t bst __unused, bus_space_handle_t bsh, bus_size_ * data is passed by value. */ static __inline void -bus_space_write_1(bus_space_tag_t bst __unused, bus_space_handle_t bsh, bus_size_t ofs, +bus_space_write_1(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, uint8_t val) { - uint8_t __volatile *bsp = (uint8_t __volatile *)(bsh + ofs); - *bsp = val; + if (bst == BSP_BUS_SPACE_IO) { +#ifdef BSP_HAS_PCI + outb(val, bsh + ofs); +#else + return; +#endif + } else { + uint8_t __volatile *bsp = (uint8_t __volatile *)(bsh + ofs); + *bsp = val; + } } static __inline void -bus_space_write_2(bus_space_tag_t bst __unused, bus_space_handle_t bsh, bus_size_t ofs, +bus_space_write_2(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, uint16_t val) { - uint16_t __volatile *bsp = (uint16_t __volatile *)(bsh + ofs); - *bsp = val; + if (bst == BSP_BUS_SPACE_IO) { +#ifdef BSP_HAS_PCI + outw(val, bsh + ofs); +#else + return; +#endif + } else { + uint16_t __volatile *bsp = (uint16_t __volatile *)(bsh + ofs); + *bsp = val; + } } static __inline void -bus_space_write_4(bus_space_tag_t bst __unused, bus_space_handle_t bsh, bus_size_t ofs, +bus_space_write_4(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, uint32_t val) { - uint32_t __volatile *bsp = (uint32_t __volatile *)(bsh + ofs); - *bsp = val; + if (bst == BSP_BUS_SPACE_IO) { +#ifdef BSP_HAS_PCI + outl(val, bsh + ofs); +#else + return; +#endif + } else { + uint32_t __volatile *bsp = (uint32_t __volatile *)(bsh + ofs); + *bsp = val; + } } static __inline void -bus_space_write_8(bus_space_tag_t bst __unused, bus_space_handle_t bsh, bus_size_t ofs, +bus_space_write_8(bus_space_tag_t bst, bus_space_handle_t bsh, bus_size_t ofs, uint64_t val) { - uint64_t __volatile *bsp = (uint64_t __volatile *)(bsh + ofs); - *bsp = val; + if (bst == BSP_BUS_SPACE_IO) { + return; + } else { + uint64_t __volatile *bsp = (uint64_t __volatile *)(bsh + ofs); + *bsp = val; + } } diff --git a/rtemsbsd/rtems/rtems-kernel-bus-dma.c b/rtemsbsd/rtems/rtems-kernel-bus-dma.c index 977ba1c6..fedaa580 100644 --- a/rtemsbsd/rtems/rtems-kernel-bus-dma.c +++ b/rtemsbsd/rtems/rtems-kernel-bus-dma.c @@ -251,7 +251,6 @@ bus_dmamem_alloc(bus_dma_tag_t dmat, void** vaddr, int flags, if (*vaddr == NULL) { free(*mapp, M_DEVBUF); - return ENOMEM; } @@ -292,6 +291,10 @@ bus_dmamap_load_buffer(bus_dma_tag_t dmat, bus_dma_segment_t segs[], vm_offset_t vaddr = (vm_offset_t)buf; int seg; +#ifdef BSP_HAS_PCI + vaddr += PCI_DRAM_OFFSET; +#endif + lastaddr = *lastaddrp; bmask = ~(dmat->boundary - 1); diff --git a/rtemsbsd/rtems/rtems-kernel-nexus.c b/rtemsbsd/rtems/rtems-kernel-nexus.c index bf840a17..2c0eaafc 100644 --- a/rtemsbsd/rtems/rtems-kernel-nexus.c +++ b/rtemsbsd/rtems/rtems-kernel-nexus.c @@ -61,7 +61,12 @@ /* #define DISABLE_INTERRUPT_EXTENSION */ -#if defined(__i386__) || defined(FDT) +#if defined(__i386__) || \ + defined(__powerpc__) +#define ENABLE_RES_IOPORT +#endif + +#if defined(ENABLE_RES_IOPORT) || defined(FDT) #define ENABLE_RESOURCE_ACTIVATE_DEACTIVATE #endif @@ -77,7 +82,7 @@ static struct rman mem_rman; static struct rman irq_rman; -#ifdef __i386__ +#if defined(ENABLE_RES_IOPORT) static struct rman port_rman; #endif @@ -111,9 +116,9 @@ 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__ +#if defined(ENABLE_RES_IOPORT) port_rman.rm_start = 0; - port_rman.rm_end = 0xffff; + port_rman.rm_end = ~0UL; port_rman.rm_type = RMAN_ARRAY; port_rman.rm_descr = "I/O ports"; err = rman_init(&port_rman) != 0; @@ -164,7 +169,7 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, case SYS_RES_IRQ: rm = &irq_rman; break; -#ifdef __i386__ +#if defined(ENABLE_RES_IOPORT) case SYS_RES_IOPORT: rm = &port_rman; break; @@ -193,7 +198,7 @@ nexus_alloc_resource(device_t bus, device_t child, int type, int *rid, } } -#ifdef __i386__ +#if defined(ENABLE_RES_IOPORT) /* * FIXME: This is a quick and dirty hack. Simply reserve resources of * this kind. See also pci_reserve_map(). @@ -225,9 +230,13 @@ nexus_activate_resource(device_t bus, device_t child, int type, int rid, { switch (type) { -#ifdef __i386__ +#if defined(ENABLE_RES_IOPORT) case SYS_RES_IOPORT: +#ifdef __i386__ rman_set_bustag(res, X86_BUS_SPACE_IO); +#else + rman_set_bushandle(res, rman_get_start(res)); +#endif break; #endif case SYS_RES_MEMORY: -- 2.24.1 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel