/* PCIMgr_Veneers.h      useful definitions for access to PCI devices via MicroDigital PCIManager
 *
 * This library code is (c) 2003 MicroDigital Ltd,
 * but is made available on an open-source basis to assist programmers
 * in developing Risc OS drivers for PCI expansion cards.
 * If you use any of it in your own code, please mention MicroDigital in the credits.
 * You may redistribute this library providing it is complete and unmodified.
 * If you make any improvements, please email them to "dprosser@microdigital.co.uk"
 * to include in future releases, so other programmers can benefit.
 */

#include "kernel.h"     /* used for interrupts on and off macros */
#include "swis.h"

/* SWI numbers */
#define PCI_ReturnNumberOfDevices        (0x050E40)
#define PCI_ReadID                       (0x050E41)
#define PCI_RegisterDriver               (0x050E42)
#define PCI_DeRegisterDriver             (0x050E43)
#define PCI_ConfigurationRead            (0x050E44)
#define PCI_ConfigurationWrite           (0x050E45)
#define PCI_AddressMapping               (0x050E46)
#define PCI_ConfigurationReadBlock       (0x050E47)
#define PCI_InterruptMapping             (0x050E48)
#define PCI_FlushCaches                  (0x050E49)

#define MicroDigital_ClaimDeviceVector   (0x054001)
#define MicroDigital_ReleaseDeviceVector (0x054002)

/* SWI  PCI_ReadID returns following struct */
typedef struct {
  unsigned long VenDevID,
                SlotNum,
                ClassCode,
                SubVenDevID,
                CMOSBase;
} PCIMgr_ReadIDInfo;

/* SWI  PCI_AddressMapping returns array of following struct */
typedef struct {  
  unsigned long  BAR,                        /* number of Base Address Register area, plus BARTYPE flags of area type */
                 PCI_Base_Physical;          /* base adrs in physical memory map */
  volatile unsigned long
                *PCI_Base_Logical32;         /* ditto in logical memory map: for memory, io and ROM space */
  unsigned long  PCI_Base_Size;              /* in bytes */
  volatile unsigned char *PCI_Base_Logical8; /* for byte io only */
} PCIMgr_AdrsMap;

#define PCIMgr_BARTYPE_IOAREA      (0x040000000)
#define PCIMgr_BARTYPE_ROMAREA     (0x080000000)
/* otherwise BAR is memory area */

/* SWI  PCI_InterruptMapping returns following struct */
typedef struct {
  unsigned long Dev,                        /* interrupt channel device number */
                Mask;                       /* enable mask */
  volatile unsigned long
               *EnableReg,                  /* adrs of enable register: OR with mask to enable */
               *RawStatusReg,               /* mask bit(s) set if active request */
               *IRQStatusReg;               /* mask bit(s) set if active request AND enabled */
} PCIMgr_IntrMap;

/* struct for converting logical buffer addresses to physical prior to DMA */
typedef struct {
  unsigned long PageID;
  void         *Logical;
  unsigned long Physical;
} PageInfo;

/* struct for holding relevant details of a Dynamic Area buffer */
typedef struct {
  unsigned long DA_handle,           /* handle for use with Dynamic Area SWIs */
                Size,                /* actual allocated size, in bytes */
                Physical;            /* base address in physical space, to give to DMA controllers */
  void         *Logical;             /* base address in logical memory space, for program use */
} PCIMgr_DABufferInfo;

long PCIMgr_ReturnNumberOfDevices (void);
void PCIMgr_ReadID (long LogicalDevID, PCIMgr_ReadIDInfo *Info);
long PCIMgr_RegisterDriver (unsigned long VenDevID, unsigned long InterestMask, unsigned long PrivateId, char *name);
long PCIMgr_DeRegisterDriver (long LogicalDevID, unsigned long PrivateId);
 unsigned long PCIMgr_ConfigurationRead (long LogicalDevID, unsigned long Offset);
unsigned long PCIMgr_ConfigurationWrite (long LogicalDevID, unsigned long Offset, unsigned long Data);
unsigned long PCIMgr_AddressMapping (long LogicalDevID, PCIMgr_AdrsMap *Buffer, long BufLength);
unsigned long PCIMgr_ConfigurationReadBlock (long LogicalDevID, unsigned char *Buffer);
unsigned long PCIMgr_InterruptMapping (long LogicalDevID, PCIMgr_IntrMap *Buffer);
void PCIMgr_FlushCaches (void *Area, long Length);
void PCIMgr_ClaimDeviceVector (PCIMgr_IntrMap *Buffer, volatile unsigned long *Reg, unsigned long Mask, int (*Handler)(_kernel_swi_regs *, void *), void *WkSpc);
void PCIMgr_ReleaseDeviceVector (PCIMgr_IntrMap *Buffer, volatile unsigned long *Reg, unsigned long Mask, int (*Handler)(_kernel_swi_regs *, void *), void *WkSpc);
void PCIMgr_Log2Phys (int Count, PageInfo *Pages);
void PCIMgr_Phys2Log (int Count, PageInfo *Pages);
_kernel_oserror *PCIMgr_CreateDynamicArea (char *name, int size, int boundary, PCIMgr_DABufferInfo *result);
void PCIMgr_RemoveDynamicArea (PCIMgr_DABufferInfo *area);
int PCIMgr_ReadMonotonicTime(void);

void PCIMgr_DA_handler(void);

#define ensure_irqs_off(x)     (int) _kernel_irqs_disabled(); _kernel_irqs_off()
#define ensure_irqs_on(x)      (int) _kernel_irqs_disabled(); _kernel_irqs_on()
#define restore_irqs(x)        if (!(x)) {_kernel_irqs_on();}

/* end */

