[6-freebsd-12 PATCH 1/2] rtemsbsd/bus: Add PCI support to the nexus bus

chrisj at rtems.org chrisj at rtems.org
Tue Feb 16 02:02:28 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