summaryrefslogblamecommitdiffstats
path: root/bsd_eth_drivers/libbsdport/bus.h
blob: 19cb24f65b2004eeea37b40f4bf3b6b6f14fda46 (plain) (tree)





























































































































































                                                                                                                                      



































                                                                         








































































                                                                                                                                                                                                                                                                               
                                                                           

                 
                                                                                                                                                                                    







                                             








                                                                          
#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

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

/* 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 *, bus_dma_segment_t *, int, int);

static inline int
bus_dmamap_load(bus_dma_tag_t tag, bus_dmamap_t map, caddr_t vaddr, bus_size_t size, void (*cb)(void *arg, bus_dma_segment_t *segs, int nseg, int error), 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;
}

#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