[6-freebsd-12 PATCH v2 1/2] rtemsbsd/bus: Add PCI support to the nexus bus
chrisj at rtems.org
chrisj at rtems.org
Tue Feb 16 02:10:49 UTC 2021
From: Chris Johns <chrisj at 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
More information about the devel
mailing list