summaryrefslogtreecommitdiffstats
path: root/bsd_eth_drivers/libbsdport/bus.h
diff options
context:
space:
mode:
Diffstat (limited to 'bsd_eth_drivers/libbsdport/bus.h')
-rw-r--r--bsd_eth_drivers/libbsdport/bus.h324
1 files changed, 324 insertions, 0 deletions
diff --git a/bsd_eth_drivers/libbsdport/bus.h b/bsd_eth_drivers/libbsdport/bus.h
new file mode 100644
index 0000000..76d78a8
--- /dev/null
+++ b/bsd_eth_drivers/libbsdport/bus.h
@@ -0,0 +1,324 @@
+#ifndef LIBBSDPORT_SYS_BUS_H
+#define LIBBSDPORT_SYS_BUS_H
+
+#include <rtems.h>
+#include <sys/errno.h>
+#include <bsp.h>
+#include <devicet.h>
+#include <sys/mbuf.h>
+
+typedef uint32_t bus_addr_t;
+typedef size_t bus_size_t;
+
+typedef enum {
+ bus_space_mem = 0,
+ bus_space_io = 1
+} bus_space_tag_t;
+
+struct resource;
+
+typedef bus_addr_t bus_space_handle_t;
+
+/* The 'bus_space_xxx()' inlines can be helped if the
+ * tag is hardcoded in the driver so that the compiler
+ * can optimize part of the implementation away.
+ */
+
+#define BUS_SPACE_BARRIER_WRITE 1
+#define BUS_SPACE_BARRIER_READ 2
+
+#if defined(__i386__)
+
+#include <rtems/score/cpu.h>
+
+static inline void
+bus_space_barrier(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, int width, int type)
+{
+}
+
+#define BUS_SPACE_DECL(type, width, nwidth) \
+static inline type \
+bus_space_read_##nwidth(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) \
+{ \
+type v; \
+ if ( bus_space_io == t ) { \
+ /* this is a macro setting the second argument */ \
+ inport_##width( h+o, v ); \
+ } else { \
+ v = *(volatile type __attribute__((may_alias)) *)(h+o); \
+ } \
+ return v; \
+} \
+ \
+static inline void \
+bus_space_write_##nwidth(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, type v) \
+{ \
+ if ( bus_space_io == t ) { \
+ outport_##width( h+o, v ); \
+ } else { \
+ *(volatile type __attribute__((may_alias)) *)(h+o) = v; \
+ }\
+}
+
+BUS_SPACE_DECL(u_int32_t, long, 4)
+BUS_SPACE_DECL(u_int16_t, word, 2)
+BUS_SPACE_DECL(u_int8_t, byte, 1)
+
+#elif defined(__PPC__)
+
+#include <libcpu/io.h>
+
+#if defined(_IO_BASE) && _IO_BASE == 0
+#define BUS_SPACE_ALWAYS_MEM 1
+#else
+#define BUS_SPACE_ALWAYS_MEM 0
+#endif
+
+static inline void
+bus_space_barrier(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, int width, int type)
+{
+ asm volatile("eieio");
+}
+
+
+#define BUS_SPACE_DECL(type, width, nwidth, op) \
+static inline type \
+bus_space_read_##nwidth(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) \
+{ \
+type v; \
+ if ( !BUS_SPACE_ALWAYS_MEM && bus_space_io == t ) { \
+ /* this is a macro setting the second argument */ \
+ v = in_##op((volatile type *)(_IO_BASE+h+o)); \
+ } else { \
+ v = in_##op((volatile type *)(h+o)); \
+ } \
+ return v; \
+} \
+ \
+static inline void \
+bus_space_write_##nwidth(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, type v) \
+{ \
+ if ( !BUS_SPACE_ALWAYS_MEM && bus_space_io == t ) { \
+ out_##op((volatile type *)(_IO_BASE+h+o), v); \
+ } else { \
+ out_##op((volatile type *)(h+o), v); \
+ }\
+}
+
+BUS_SPACE_DECL(u_int32_t, long, 4, le32)
+BUS_SPACE_DECL(u_int16_t, word, 2, le16)
+BUS_SPACE_DECL(u_int8_t, byte, 1, 8)
+
+#undef BUS_SPACE_ALWAYS_MEM
+
+#else
+#error "Missing definitions of bus_space_XXX() for this CPU architecture"
+#endif
+
+
+#undef BUS_SPACE_DECL
+
+#ifndef BUS_PROBE_DEFAULT
+#define BUS_PROBE_DEFAULT 0
+#endif
+
+/* error codes are > 0 ; low priority says that probe
+ * was successful but another driver returning BUS_PROBE_DEFAULT
+ * is to be preferred...
+ */
+#ifndef BUS_PROBE_LOW_PRIORITY
+#define BUS_PROBE_LOW_PRIORITY (-1)
+#endif
+
+
+
+/* types -> -1 means unsupported */
+#define SYS_RES_IOPORT 1
+#define SYS_RES_MEMORY 2
+#define SYS_RES_IRQ 3
+
+/* flags (1<<31) means unsupported */
+#define RF_ACTIVE (1<<1)
+#define RF_SHAREABLE (1<<2)
+
+struct resource *
+bus_alloc_resource_any(device_t dev, int type, int *prid, unsigned flags);
+
+#define FILTER_STRAY 1
+#define FILTER_HANDLED 0
+
+typedef void (*driver_intr_t)(void *);
+typedef int (*driver_filter_t)(void *);
+
+int
+bus_setup_intr(device_t dev, struct resource *r, int flags, driver_filter_t filter, driver_intr_t handler, void *arg, void **cookiep);
+
+/* Flags currently ignored... */
+#define INTR_MPSAFE 0
+#define INTR_TYPE_NET 0
+/* INTR_FAST indicates that a 'handler' is actually
+ * a 'fast' handler which already uses taskqueues
+ */
+#define INTR_FAST 1
+
+int
+bus_teardown_intr(device_t dev, struct resource *r, void *cookiep);
+
+static inline int
+bus_release_resource(device_t dev, int type, int rid, struct resource *r)
+{
+ return 0;
+}
+
+#define bus_generic_detach(dev) do {} while (0)
+
+#define bus_generic_suspend(dev) (0)
+#define bus_generic_resume(dev) (0)
+
+bus_space_handle_t
+rman_get_bushandle(struct resource *r);
+
+bus_space_tag_t
+rman_get_bustag(struct resource *r);
+
+#ifndef BUS_DMA_NOWAIT
+/* ignored anyways */
+#define BUS_DMA_NOWAIT 0
+#endif
+
+#ifndef BUS_DMA_WAITOK
+/* ignored anyways */
+#define BUS_DMA_WAITOK 0
+#endif
+
+#ifndef BUS_DMA_COHERENT
+/* ignored anyways */
+#define BUS_DMA_COHERENT 0
+#endif
+
+#ifndef BUS_DMA_ZERO
+/* ignored anyways */
+#define BUS_DMA_ZERO 0
+#endif
+
+#ifndef BUS_DMA_ALLOCNOW
+/* ignored anyways */
+#define BUS_DMA_ALLOCNOW 0
+#endif
+
+/* unused */
+#ifndef BUS_SPACE_MAXADDR
+#define BUS_SPACE_MAXADDR 0xdeadbeef
+#endif
+
+/* unused */
+#ifndef BUS_SPACE_MAXADDR_32BIT
+#define BUS_SPACE_MAXADDR_32BIT 0xdeadbeef
+#endif
+
+/* unused */
+#ifndef BUS_SPACE_MAXSIZE_32BIT
+#define BUS_SPACE_MAXSIZE_32BIT 0x10000000
+#endif
+
+typedef struct _bus_dma_tag_t {
+ unsigned alignment;
+ unsigned maxsize;
+ unsigned maxsegs;
+} * bus_dma_tag_t;
+
+typedef struct _bus_dma_segment_t {
+ bus_addr_t ds_addr;
+ bus_size_t ds_len;
+} bus_dma_segment_t;
+
+typedef void *bus_dmamap_t;
+
+int
+bus_dma_tag_create(void *parent, unsigned alignment, unsigned bounds, uint32_t lowadd, uint32_t hiaddr, void (*filter)(void*), void *filterarg, unsigned maxsize, int nsegs, unsigned maxsegsize, unsigned flags, void (*lockfunc)(void*), void *lockarg, bus_dma_tag_t *ptag);
+
+void
+bus_dma_tag_destroy(bus_dma_tag_t tag);
+
+int
+bus_dmamem_alloc(bus_dma_tag_t tag, void **p_vaddr, unsigned flags, bus_dmamap_t *p_map);
+
+void
+bus_dmamem_free(bus_dma_tag_t tag, void *vaddr, bus_dmamap_t map);
+
+#ifndef CPU2BUSADDR
+#ifndef PCI_DRAM_OFFSET
+#define PCI_DRAM_OFFSET 0
+#endif
+#define CPU2BUSADDR(x) ((uint32_t)(x) + (PCI_DRAM_OFFSET))
+#endif
+
+#define kvtop(a) CPU2BUSADDR((bus_addr_t)(a))
+#define vtophys(a) CPU2BUSADDR((bus_addr_t)(a))
+
+
+static inline int
+bus_dmamap_load_mbuf_sg(bus_dma_tag_t tag, bus_dmamap_t map, struct mbuf *m_head, bus_dma_segment_t *segs, int *pnsegs, unsigned flags)
+{
+struct mbuf *m;
+int n;
+ for ( m=m_head, n=0; m; m=m->m_next, n++ ) {
+ if ( n >= tag->maxsegs ) {
+ return EFBIG;
+ }
+ segs[n].ds_addr = CPU2BUSADDR(mtod(m, unsigned));
+ segs[n].ds_len = m->m_len;
+ }
+ *pnsegs = n;
+ return 0;
+}
+
+static inline bus_dma_tag_t
+bus_get_dma_tag(device_t dev)
+{
+ return 0;
+}
+
+typedef void bus_dmamap_callback_t (void *arg, bus_dma_segment_t *segs, int nseg, int error);
+
+static inline int
+bus_dmamap_load(bus_dma_tag_t tag, bus_dmamap_t map, caddr_t vaddr, bus_size_t size, bus_dmamap_callback_t cb, void *arg, unsigned flags)
+{
+bus_dma_segment_t segs[1];
+ segs[0].ds_addr = CPU2BUSADDR(vaddr);
+ segs[0].ds_len = size;
+ cb(arg, segs, 1, 0);
+ return 0;
+}
+
+typedef void bus_dmamap_callback2_t (void *arg, bus_dma_segment_t *segs, int nsegs, bus_size_t mapsize, int error);
+
+static inline int
+bus_dmamap_load_mbuf(bus_dma_tag_t tag, bus_dmamap_t map, struct mbuf *m_head, bus_dmamap_callback2_t cb, void *arg, unsigned flags)
+{
+/* hopefully there's enough stack ... */
+bus_dma_segment_t segs[tag->maxsegs];
+struct mbuf *m;
+int n;
+bus_size_t sz;
+ for ( m=m_head, sz=0, n=0; m; m=m->m_next, n++ ) {
+ if ( n >= tag->maxsegs ) {
+ cb(arg, segs, n, sz, EFBIG);
+ return EFBIG;
+ }
+ segs[n].ds_addr = CPU2BUSADDR(mtod(m, unsigned));
+ sz += (segs[n].ds_len = m->m_len);
+ }
+ cb(arg, segs, n, sz, 0);
+ return 0;
+}
+
+#define bus_dmamap_unload(tag, map) do {} while (0)
+
+/* should we do something if we have no HW snooping ? */
+#define bus_dmamap_sync(tag, map, flags) do { membarrier_rw(); } while (0)
+
+#define bus_dmamap_create(tag, flags, pmap) ( *(pmap) = 0, 0 )
+#define bus_dmamap_destroy(tag, map) do {} while (0)
+
+#endif