From 89376b7141edb6f927fb940c27391cda6e67c785 Mon Sep 17 00:00:00 2001 From: Joel Sherrill Date: Thu, 19 Feb 2009 19:55:40 +0000 Subject: Initial import. --- bsd_eth_drivers/libbsdport/bus.h | 324 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 324 insertions(+) create mode 100644 bsd_eth_drivers/libbsdport/bus.h (limited to 'bsd_eth_drivers/libbsdport/bus.h') 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 +#include +#include +#include +#include + +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 + +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 + +#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 -- cgit v1.2.3