/*
"bus.h"
created by: grayspace aka J. Leveille
for: UbixOS Project
date: May 11, 2002
purpose: master header file for all things BUS related
*/
#ifndef _BUS_H
#define _BUS_H
/* Intel 32-bit architecture */
#if TCPU_IA32
/* DMA channels */
#define MIN_DMA_CHANNEL (0)
#define MAX_DMA_CHANNEL (7)
#define NUM_DMA_CHANNELS (MAX_DMA_CHANNEL - MIN_DMA_CHANNEL - 1)
/* IRQs */
#define MIN_IRQ (0)
#define MAX_IRQ (15)
#define NUM_IRQS (MAX_IRQ - MIN_IRQ - 1)
/* Port IO Range */
#define MIN_PORTIO_ADDR (0)
#define MAX_PORTIO_ADDR (65535)
#define MAXBITS_PORTIO_ADDR (16)
/* NOTE: 'BI_' denotes roughly something related to BUS info */
/* for building/use-with device-info/bus-resource-info structures */
#define BI_NUMBITS_IRQS (4)
#define BI_NUMBITS_DMA_CHANNELS (3)
#define BI_IRQ_BIT (0)
#define BI_DMA_CHANNEL_BIT (BI_IRQ_BIT + BI_NUMBITS_IRQS)
#define BI_IRQ_MASK\
MAKEMASK_GS( BI_NUMBITS_IRQS, BI_IRQ_BIT )
#define BI_DMA_CHANNEL_MASK\
MAKEMASK_GS( BI_NUMBITS_DMA_CHANNELS, BI_DMA_CHANNEL_BIT )
#define BI_NUMBITS_PORTIO_BASEADDR (16)
#define BI_NUMBITS_PORTIO_OVERADDR (16)
#define BI_PORTIO_BASEADDR_BIT (0)
#define BI_PORTIO_OVERADDR_BIT ( BI_PORTIO_BASEADDR_BIT\
+ BI_NUMBITS_PORTIO_BASEADDR )
#define BI_PORTIO_BASEADDR_MASK\
MAKEMASK_GS( BI_NUMBITS_PORTIO_BASEADDR, BI_PORTIO_BASEADDR_BIT )
#define BI_PORTIO_OVERADDR_MASK\
MAKEMASK_GS( BI_NUMBITS_PORTIO_OVERADDR, BI_PORTIO_OVERADDR_BIT )
/* maximum number of DMAs and IRQs a device can use
NOTE: *must* be same */
#define BI_MAX_DMAANDIRQS (2)
#define BI_MAX_DMAS (BI_MAX_DMAANDIRQS)
#define BI_MAX_IRQS (BI_MAX_DMAANDIRQS)
/* maximum number of Port IO ranges a device can use */
#define BI_MAX_PORTIO_RANGES (4)
/* structure for storing a device's bus resources */
typedef struct tagBUS_RESOURCES
{
/* DMA and IRQ info */
BYTEg a_dmairq[BI_MAX_DMAANDIRQS];
/*
bits [0,1] number of IRQs used
bits [2,3] number of DMA channels used
bits [4,7] number of port IO ranges used
*/
BYTEg resource_counts;
/* Port IO Ranges */
DWORDg a_portiorange[BI_MAX_PORTIO_RANGES];
}
BUS_RESOURCES;
/* NOTE: 'BUS_RES' denotes interface functions/macros on
the 'BUS_RESOURCES' structure */
#if (BI_IRQ_BIT == 0)
/* get IRQ 'idx' from resource description 'br' */
#define BUS_RES_GETIRQ( br, idx ) ((br).a_dmairq[(idx)]&BI_IRQ_MASK)
/* set IRQ 'idx' in resource description 'br' to 'irq' */
#define BUS_RES_SETIRQ( br, idx, irq )\
(br).a_dmairq[(idx)] &= BI_IRQ_MASK;\
(br).a_dmairq[(idx)] |= (irq)
#else
/* get IRQ 'idx' from resource description 'br' */
#define BUS_RES_GETIRQ( br, idx )\
GETBITVAL_GS( (br).a_dmairq[(idx)], BI_IRQ_MASK, BI_IRQ_BIT )
/* set IRQ 'idx' in resource description 'br' to 'irq' */
#define BUS_RES_SETIRQ( br, idx, irq )\
SETBITVAL_FAST_GS( (br).a_dmairq[(idx)],\
BI_IRQ_MASK,\
BI_IRQ_BIT,\
(irq) )
#endif
/* get DMA 'idx' from resource description 'br' */
#define BUS_RES_GETDMA( br, idx )\
GETBITVAL_GS( (br).a_dmairq[(idx)], BI_DMA_MASK, BI_DMA_BIT )
/* set DMA 'idx' in resource description 'br' to 'dma' */
#define BUS_RES_SETDMA( br, idx, dma )\
SETBITVAL_FAST_GS( (br).a_dmairq[(idx)],\
BI_DMA_MASK,\
BI_DMA_BIT,\
(dma) )
#if (BI_PORTIO_BASEADDR_BIT == 0) && (BI_PORTIO_OVERADDR_BIT == BI_NUMBITS_PORTIO_BASEADDR )
/* get port IO base address 'idx' from resource description 'br' */
#define BUS_RES_GETPORTIOBASE( br, idx )\
((br).a_portiorange[(idx)]&BI_PORTIO_BASEADDR_MASK)
/* get port IO 'over' address 'idx' from resource description 'br' */
#define BUS_RES_GETPORTIOOVER( br, idx )\
((br).a_portiorange[(idx)]>>BI_PORTIO_OVERADDR_BIT)
/* get port IO range 'idx' from resource description 'br'
into 'baseaddr_o' and 'overaddr_o' */
#define BUS_RES_GETPORTIORANGE( br, idx, baseaddr_o, overaddr_o )\
(baseaddr_o)\
= ((br).a_portiorange[(idx)] & BI_PORTIO_BASEADDR_MASK);\
(overaddr_o)\
= ((br).a_portiorange[(idx)] >> BI_PORTIO_OVERADDR_BIT)
/* set port IO range 'idx' in resource description 'br'
to 'baseaddr' and 'overaddr' */
#define BUS_RES_SETPORTIORANGE( br, idx, baseaddr, overaddr )\
((br).a_portiorange[(idx)]\
= ((overaddr)<<BI_PORTIO_OVERADDR_BIT);\
((br).a_portiorange[(idx)]\
|= (baseaddr)
#else /* #if (BI_PORTIO_BASEADDR_BIT == 0)
&& (BI_PORTIO_OVERADDR_BIT == BI_NUMBITS_PORTIO_BASEADDR ) */
/* get port IO base address 'idx' from resource description 'br' */
#define BUS_RES_GETPORTIOBASE( br, idx )\
GETBITVAL_GS( (br).a_portiorange[(idx)],\
BI_PORTIO_BASEADDR_MASK,\
BI_PORTIO_BASEADDR_BIT )
/* get port IO 'over' address 'idx' from resource description 'br' */
#define BUS_RES_GETPORTIOOVER( br, idx )\
GETBITVAL_GS( (br).a_portiorange[(idx)],\
BI_PORTIO_OVERADDR_MASK,\
BI_PORTIO_OVERADDR_BIT )
/* get port IO range 'idx' from resource description 'br'
into 'baseaddr_o' and 'overaddr_o' */
#define BUS_RES_GETPORTIORANGE( br, idx, baseaddr_o, overaddr_o )\
(baseaddr_o)\
= GETBITVAL_GS( (br).a_portiorange[(idx)],\
BI_PORTIO_BASEADDR_MASK,\
BI_PORTIO_BASEADDR_BIT );\
(overaddr_o)\
= GETBITVAL_GS( (br).a_portiorange[(idx)],\
BI_PORTIO_OVERADDR_MASK,\
BI_PORTIO_OVERADDR_BIT )
/* set port IO range 'idx' in resource description 'br'
to 'baseaddr' and 'overaddr' */
#define BUS_RES_SETPORTIORANGE( br, idx, baseaddr, overaddr )\
SETBITVAL_FAST_GS( (br).a_portiorange[(idx)],\
BI_PORTIO_BASEADDR_MASK,\
BI_PORTIO_BASEADDR_BIT,\
(baseaddr) )\
SETBITVAL_FAST_GS( (br).a_portiorange[(idx)],\
BI_PORTIO_OVERADDR_MASK,\
BI_PORTIO_OVERADDR_BIT,\
(overaddr) )
#endif /* #else #if (BI_PORTIO_BASEADDR_BIT == 0)
&& ( BI_PORTIO_OVERADDR_BIT
== BI_NUMBITS_PORTIO_BASEADDR ) */
/* HACK: because no defines used for bit numbers */
/* get number of IRQs used/assign-to device */
#define BUS_RES_GETIRQSUSED( br )\
(((br).resource_counts & 0x0C)>>2)
/* set number of IRQs used/assign-to device */
#define BUS_RES_SETIRQSUSED( br, irqsused )\
(br).resource_counts &= ~0x0C;\
(br).resource_counts |= ((irqsused)<<2)
/* get number of DMAs used/assign-to device */
#define BUS_RES_GETDMASUSED( br )\
((br).resource_counts & 3)
/* set number of DMAs used/assign-to device */
#define BUS_RES_SETDMASUSED( br, dmasused )\
(br).resource_counts &= ~3;\
(br).resource_counts |= (dmasused)
/* get number of port IO ranges used/assign-to device */
#define BUS_RES_GETPORTIORANGESUSED( br )\
(((br).resource_counts)>>4)
/* get number of port IO ranges used/assign-to device */
#define BUS_RES_SETPORTIORANGESUSED( br, rangesused )\
(br).resource_counts &= 0x0F;\
(br).resource_counts |= ((rangesused)<<4)
#else /* #if TCPU_IA32 */
#error unknown target CPU!!!
#endif /* #if TCPU_??? */
#endif /* _BUS_H */