#ifndef _MACHINE_BUS_H_
#define _MACHINE_BUS_H_
#include <sys/atomic.h>
#ifdef _KERNEL
#define BSDB_ACCESS 0x01
#define BSDB_MAP 0x02
#define BSDB_ASSERT 0x04
#define BSDB_MAPDETAIL 0x08
#define BSDB_ALL_ACCESS 0x10
extern int bus_space_debug;
#define BSHDB_ACCESS 0x01
#define BSHDB_NO_ACCESS 0x02
#if defined(BUS_SPACE_DEBUG)
#include <sys/systm.h>
#define BUS_SPACE_PRINTF(l, s) do { \
if(bus_space_debug & (l)) printf s; \
} while(0)
#define BUS_SPACE_TRACE(t, h, s) do { \
if ( (((bus_space_debug & BSDB_ALL_ACCESS) != 0) && \
(((h).bh_flags & BSHDB_NO_ACCESS) == 0)) || \
(((bus_space_debug & BSDB_ACCESS) != 0) && \
(((h).bh_flags & BSHDB_ACCESS) != 0))) \
printf s; \
} while(0)
#define BUS_SPACE_SET_FLAGS(t, h, f) ((h).bh_flags |= (f))
#define BUS_SPACE_CLEAR_FLAGS(t, h, f) ((h).bh_flags &= ~(f))
#define BUS_SPACE_FLAG_DECL(s) int s
#define BUS_SPACE_SAVE_FLAGS(t, h, s) (s = (h).bh_flags)
#define BUS_SPACE_RESTORE_FLAGS(t, h, s) (s = (h).bh_flags)
#define BUS_SPACE_ASSERT(t, h, o, n) do { \
if (bus_space_debug & BSDB_ASSERT) \
bus_space_assert(t, &(h), o, n); \
} while(0)
#else
#define BUS_SPACE_PRINTF(l, s)
#define BUS_SPACE_TRACE(t, h, s)
#define BUS_SPACE_SET_FLAGS(t, h, f)
#define BUS_SPACE_CLEAR_FLAGS(t, h, f)
#define BUS_SPACE_FLAG_DECL(s)
#define BUS_SPACE_SAVE_FLAGS(t, h, s)
#define BUS_SPACE_RESTORE_FLAGS(t, h, s)
#define BUS_SPACE_ASSERT(t, h, o, n)
#endif
enum sparc_bus_type {
UPA_BUS_SPACE,
SBUS_BUS_SPACE,
PCI_CONFIG_BUS_SPACE,
PCI_IO_BUS_SPACE,
PCI_MEMORY_BUS_SPACE,
LAST_BUS_SPACE
};
#define SPARC_BUS_SPACE UPA_BUS_SPACE
typedef const struct sparc_bus_space_tag *bus_space_tag_t;
typedef u_long bus_addr_t;
typedef u_long bus_size_t;
typedef struct _bus_space_handle {
paddr_t bh_ptr;
#ifdef BUS_SPACE_DEBUG
bus_space_tag_t bh_tag;
bus_size_t bh_size;
int bh_flags;
#endif
} bus_space_handle_t;
#define BUS_ADDR_IOSPACE(x) ((x)>>32)
#define BUS_ADDR_PADDR(x) ((x)&0xffffffff)
#define BUS_ADDR(io, pa) ((((bus_addr_t)io)<<32)|(pa))
struct sparc_bus_space_tag {
void *cookie;
bus_space_tag_t parent;
enum sparc_bus_type default_type;
u_int8_t asi;
u_int8_t sasi;
char name[32];
int (*sparc_bus_alloc)(bus_space_tag_t,
bus_space_tag_t,
bus_addr_t, bus_addr_t,
bus_size_t, bus_size_t, bus_size_t,
int, bus_addr_t *, bus_space_handle_t *);
void (*sparc_bus_free)(bus_space_tag_t,
bus_space_tag_t,
bus_space_handle_t, bus_size_t);
int (*sparc_bus_map)(bus_space_tag_t,
bus_space_tag_t,
bus_addr_t, bus_size_t,
int, bus_space_handle_t *);
int (*sparc_bus_protect)(bus_space_tag_t,
bus_space_tag_t,
bus_space_handle_t, bus_size_t, int);
int (*sparc_bus_unmap)(bus_space_tag_t,
bus_space_tag_t,
bus_space_handle_t, bus_size_t);
int (*sparc_bus_subregion)(bus_space_tag_t,
bus_space_tag_t,
bus_space_handle_t, bus_size_t,
bus_size_t, bus_space_handle_t *);
paddr_t (*sparc_bus_mmap)(bus_space_tag_t,
bus_space_tag_t,
bus_addr_t, off_t, int, int);
void *(*sparc_intr_establish)(bus_space_tag_t,
bus_space_tag_t,
int, int, int,
int (*)(void *), void *,
const char *);
void *(*sparc_intr_establish_cpu)(bus_space_tag_t,
bus_space_tag_t,
int, int, int,
struct cpu_info *,
int (*)(void *), void *,
const char *);
bus_addr_t (*sparc_bus_addr)(bus_space_tag_t,
bus_space_tag_t, bus_space_handle_t);
};
int bus_space_alloc(
bus_space_tag_t,
bus_addr_t,
bus_addr_t,
bus_size_t,
bus_size_t,
bus_size_t,
int,
bus_addr_t *,
bus_space_handle_t *);
void bus_space_free(
bus_space_tag_t,
bus_space_handle_t,
bus_size_t);
int bus_space_map(
bus_space_tag_t,
bus_addr_t,
bus_size_t,
int,
bus_space_handle_t *);
int bus_space_protect(
bus_space_tag_t,
bus_space_handle_t,
bus_size_t,
int);
int bus_space_unmap(
bus_space_tag_t,
bus_space_handle_t,
bus_size_t);
int bus_space_subregion(
bus_space_tag_t,
bus_space_handle_t,
bus_size_t,
bus_size_t,
bus_space_handle_t *);
static void bus_space_barrier(
bus_space_tag_t,
bus_space_handle_t,
bus_size_t,
bus_size_t,
int);
paddr_t bus_space_mmap(
bus_space_tag_t,
bus_addr_t,
off_t,
int,
int);
void *bus_intr_establish(
bus_space_tag_t,
int,
int,
int,
int (*)(void *),
void *,
const char *);
void *bus_intr_establish_cpu(
bus_space_tag_t,
int,
int,
int,
struct cpu_info *,
int (*)(void *),
void *,
const char *);
void *bus_intr_allocate(
bus_space_tag_t,
int (*)(void *),
void *,
int,
int,
volatile u_int64_t *,
volatile u_int64_t *,
const char *);
void bus_intr_free(void *);
void bus_space_render_tag(
bus_space_tag_t,
char *,
size_t);
void *bus_space_vaddr(
bus_space_tag_t,
bus_space_handle_t);
#ifdef BUS_SPACE_DEBUG
void bus_space_assert(bus_space_tag_t,
const bus_space_handle_t *,
bus_size_t, int);
void bus_space_render_tag(bus_space_tag_t, char*, size_t);
#endif
#define _BS_PRECALL(t,f) \
while (t->f == NULL) \
t = t->parent;
#define _BS_POSTCALL
#define _BS_CALL(t,f) \
(*(t)->f)
#define BUS_SPACE_BARRIER_READ 0x01
#define BUS_SPACE_BARRIER_WRITE 0x02
static inline void
bus_space_barrier(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o,
bus_size_t s, int f)
{
#ifdef notyet
switch (f) {
case (BUS_SPACE_BARRIER_READ|BUS_SPACE_BARRIER_WRITE):
__membar("#LoadLoad|#StoreStore");
break;
case BUS_SPACE_BARRIER_READ:
membar("#LoadLoad");
break;
case BUS_SPACE_BARRIER_WRITE:
membar("#StoreStore");
break;
default:
break;
}
#else
__membar("#Sync");
#endif
}
#include <sparc64/sparc64/busop.h>
#define BUS_SPACE_MAP_CACHEABLE 0x0001
#define BUS_SPACE_MAP_LINEAR 0x0002
#define BUS_SPACE_MAP_READONLY 0x0004
#define BUS_SPACE_MAP_PREFETCHABLE 0x0008
#define BUS_SPACE_MAP_PROMADDRESS 0x0010
#define BUS_SPACE_MAP_BUS1 0x0100
#define BUS_SPACE_MAP_BUS2 0x0200
#define BUS_SPACE_MAP_BUS3 0x0400
#define BUS_SPACE_MAP_BUS4 0x0800
#define BUS_INTR_ESTABLISH_MPSAFE 0x0001
#define BUS_INTR_ESTABLISH_SOFTINTR 0x0002
#define BUS_DMA_WAITOK 0x0000
#define BUS_DMA_NOWAIT 0x0001
#define BUS_DMA_ALLOCNOW 0x0002
#define BUS_DMA_COHERENT 0x0004
#define BUS_DMA_NOWRITE 0x0008
#define BUS_DMA_BUS1 0x0010
#define BUS_DMA_BUS2 0x0020
#define BUS_DMA_BUS3 0x0040
#define BUS_DMA_BUS4 0x0080
#define BUS_DMA_STREAMING 0x0100
#define BUS_DMA_READ 0x0200
#define BUS_DMA_WRITE 0x0400
#define BUS_DMA_ZERO 0x0800
#define BUS_DMA_OVERRUN 0x1000
#define BUS_DMA_64BIT 0x2000
#define BUS_DMA_NOCACHE BUS_DMA_BUS1
#define BUS_DMA_DVMA BUS_DMA_BUS2
#define BUS_DMA_24BIT BUS_DMA_BUS3
#define BUS_DMA_RAW BUS_DMA_STREAMING
struct mbuf;
struct uio;
#define BUS_DMASYNC_PREREAD 0x01
#define BUS_DMASYNC_POSTREAD 0x02
#define BUS_DMASYNC_PREWRITE 0x04
#define BUS_DMASYNC_POSTWRITE 0x08
typedef struct sparc_bus_dma_tag *bus_dma_tag_t;
typedef struct sparc_bus_dmamap *bus_dmamap_t;
struct sparc_bus_dma_segment {
bus_addr_t ds_addr;
bus_size_t ds_len;
bus_size_t _ds_boundary;
bus_size_t _ds_align;
void *_ds_mlist;
};
typedef struct sparc_bus_dma_segment bus_dma_segment_t;
struct sparc_bus_dma_tag {
void *_cookie;
struct sparc_bus_dma_tag* _parent;
int (*_dmamap_create)(bus_dma_tag_t, bus_dma_tag_t, bus_size_t,
int, bus_size_t, bus_size_t, int, bus_dmamap_t *);
void (*_dmamap_destroy)(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t);
int (*_dmamap_load)(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t,
void *, bus_size_t, struct proc *, int);
int (*_dmamap_load_mbuf)(bus_dma_tag_t, bus_dma_tag_t,
bus_dmamap_t, struct mbuf *, int);
int (*_dmamap_load_uio)(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t,
struct uio *, int);
int (*_dmamap_load_raw)(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t,
bus_dma_segment_t *, int, bus_size_t, int);
void (*_dmamap_unload)(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t);
void (*_dmamap_sync)(bus_dma_tag_t, bus_dma_tag_t, bus_dmamap_t,
bus_addr_t, bus_size_t, int);
int (*_dmamem_alloc)(bus_dma_tag_t, bus_dma_tag_t, bus_size_t,
bus_size_t, bus_size_t, bus_dma_segment_t *, int, int *,
int);
void (*_dmamem_free)(bus_dma_tag_t, bus_dma_tag_t,
bus_dma_segment_t *, int);
int (*_dmamem_map)(bus_dma_tag_t, bus_dma_tag_t,
bus_dma_segment_t *, int, size_t, caddr_t *, int);
void (*_dmamem_unmap)(bus_dma_tag_t, bus_dma_tag_t, caddr_t,
size_t);
paddr_t (*_dmamem_mmap)(bus_dma_tag_t, bus_dma_tag_t,
bus_dma_segment_t *, int, off_t, int, int);
};
#define _BD_PRECALL(t,f) \
while (t->f == NULL) { \
t = t->_parent; \
}
#define _BD_CALL(t,f) \
(*(t)->f)
#define _BD_POSTCALL
static inline int
bus_dmamap_create(bus_dma_tag_t t, bus_size_t s, int n, bus_size_t m,
bus_size_t b, int f, bus_dmamap_t *p)
{
int r;
const bus_dma_tag_t t0 = t;
_BD_PRECALL(t, _dmamap_create);
r = _BD_CALL(t, _dmamap_create)(t, t0, s, n, m, b, f, p);
_BD_POSTCALL;
return (r);
}
static inline void
bus_dmamap_destroy(bus_dma_tag_t t, bus_dmamap_t p)
{
const bus_dma_tag_t t0 = t;
_BD_PRECALL(t, _dmamap_destroy);
_BD_CALL(t, _dmamap_destroy)(t, t0, p);
_BD_POSTCALL;
}
static inline int
bus_dmamap_load(bus_dma_tag_t t, bus_dmamap_t m, void *b, bus_size_t s,
struct proc *p, int f)
{
const bus_dma_tag_t t0 = t;
int r;
_BD_PRECALL(t, _dmamap_load);
r = _BD_CALL(t, _dmamap_load)(t, t0, m, b, s, p, f);
_BD_POSTCALL;
return (r);
}
static inline int
bus_dmamap_load_mbuf(bus_dma_tag_t t, bus_dmamap_t m, struct mbuf *b,
int f)
{
const bus_dma_tag_t t0 = t;
int r;
_BD_PRECALL(t, _dmamap_load_mbuf);
r = _BD_CALL(t, _dmamap_load_mbuf)(t, t0, m, b, f);
_BD_POSTCALL;
return (r);
}
static inline int
bus_dmamap_load_uio(bus_dma_tag_t t, bus_dmamap_t m, struct uio * u, int f)
{
const bus_dma_tag_t t0 = t;
int r;
_BD_PRECALL(t, _dmamap_load_uio);
r = _BD_CALL(t, _dmamap_load_uio)(t, t0, m, u, f);
_BD_POSTCALL;
return (r);
}
static inline int
bus_dmamap_load_raw(bus_dma_tag_t t, bus_dmamap_t m, bus_dma_segment_t *sg,
int n, bus_size_t s, int f)
{
const bus_dma_tag_t t0 = t;
int r;
_BD_PRECALL(t, _dmamap_load_raw);
r = _BD_CALL(t, _dmamap_load_raw)(t, t0, m, sg, n, s, f);
_BD_POSTCALL;
return (r);
}
static inline void
bus_dmamap_unload(bus_dma_tag_t t, bus_dmamap_t p)
{
const bus_dma_tag_t t0 = t;
_BD_PRECALL(t, _dmamap_unload);
_BD_CALL(t, _dmamap_unload)(t, t0, p);
_BD_POSTCALL;
}
static inline void
bus_dmamap_sync(bus_dma_tag_t t, bus_dmamap_t p, bus_addr_t o, bus_size_t l,
int ops)
{
const bus_dma_tag_t t0 = t;
_BD_PRECALL(t, _dmamap_sync);
_BD_CALL(t, _dmamap_sync)(t, t0, p, o, l, ops);
_BD_POSTCALL;
}
static inline int
bus_dmamem_alloc(bus_dma_tag_t t, bus_size_t s, bus_size_t a, bus_size_t b,
bus_dma_segment_t *sg, int n, int *r, int f)
{
const bus_dma_tag_t t0 = t;
int ret;
_BD_PRECALL(t, _dmamem_alloc);
ret = _BD_CALL(t, _dmamem_alloc)(t, t0, s, a, b, sg, n, r, f);
_BD_POSTCALL;
return (ret);
}
static inline void
bus_dmamem_free(bus_dma_tag_t t, bus_dma_segment_t *sg, int n)
{
const bus_dma_tag_t t0 = t;
_BD_PRECALL(t, _dmamem_free);
_BD_CALL(t, _dmamem_free)(t, t0, sg, n);
_BD_POSTCALL;
}
static inline int
bus_dmamem_map(bus_dma_tag_t t, bus_dma_segment_t *sg, int n, size_t s,
caddr_t *k, int f)
{
const bus_dma_tag_t t0 = t;
int r;
_BD_PRECALL(t, _dmamem_map);
r = _BD_CALL(t, _dmamem_map)(t, t0, sg, n, s, k, f);
_BD_POSTCALL;
return (r);
}
static inline void
bus_dmamem_unmap(bus_dma_tag_t t, caddr_t k, size_t s)
{
const bus_dma_tag_t t0 = t;
_BD_PRECALL(t, _dmamem_unmap);
_BD_CALL(t, _dmamem_unmap)(t, t0, k, s);
_BD_POSTCALL;
}
static inline paddr_t
bus_dmamem_mmap(bus_dma_tag_t t, bus_dma_segment_t *sg, int n, off_t o, int p,
int f)
{
const bus_dma_tag_t t0 = t;
int r;
_BD_PRECALL(t, _dmamem_mmap);
r = _BD_CALL(t, _dmamem_mmap)(t, t0, sg, n, o, p, f);
_BD_POSTCALL;
return (r);
}
struct sparc_bus_dmamap {
bus_addr_t _dm_dvmastart;
bus_size_t _dm_dvmasize;
bus_size_t _dm_size;
bus_size_t _dm_maxsegsz;
bus_size_t _dm_boundary;
int _dm_segcnt;
int _dm_flags;
#define _DM_TYPE_LOAD 0
#define _DM_TYPE_SEGS 1
#define _DM_TYPE_UIO 2
#define _DM_TYPE_MBUF 3
int _dm_type;
void *_dm_source;
void *_dm_cookie;
bus_size_t dm_mapsize;
int dm_nsegs;
bus_dma_segment_t dm_segs[1];
};
#endif
#endif