add PCI driver interface enumeration routine

This commit is contained in:
Markus Fröschle
2015-11-20 19:25:57 +00:00
parent 3fc79b9c84
commit 54cd5c8151
10 changed files with 396 additions and 151 deletions

View File

@@ -581,3 +581,30 @@ dump.bdm
Makefile Makefile
mcf5474.gdb mcf5474.gdb
svn-commit.tmp svn-commit.tmp
tos/pci_test/include/bas_printf.h
tos/pci_test/include/bas_string.h
tos/pci_test/include/driver_vec.h
tos/pci_test/include/MCF5475_CLOCK.h
tos/pci_test/include/MCF5475_CTM.h
tos/pci_test/include/MCF5475_DMA.h
tos/pci_test/include/MCF5475_DSPI.h
tos/pci_test/include/MCF5475_EPORT.h
tos/pci_test/include/MCF5475_FBCS.h
tos/pci_test/include/MCF5475_FEC.h
tos/pci_test/include/MCF5475_GPIO.h
tos/pci_test/include/MCF5475_GPT.h
tos/pci_test/include/MCF5475_I2C.h
tos/pci_test/include/MCF5475_INTC.h
tos/pci_test/include/MCF5475_MMU.h
tos/pci_test/include/MCF5475_PAD.h
tos/pci_test/include/MCF5475_PCI.h
tos/pci_test/include/MCF5475_PCIARB.h
tos/pci_test/include/MCF5475_PSC.h
tos/pci_test/include/MCF5475_SDRAMC.h
tos/pci_test/include/MCF5475_SEC.h
tos/pci_test/include/MCF5475_SIU.h
tos/pci_test/include/MCF5475_SLT.h
tos/pci_test/include/MCF5475_SRAM.h
tos/pci_test/include/MCF5475_USB.h
tos/pci_test/include/MCF5475_XLB.h
tos/pci_test/include/MCF5475.h

View File

@@ -216,12 +216,6 @@ firebee/basflash.$(EXE): CFLAGS += -mcpu=5474
# generate pattern rules for different object files # generate pattern rules for different object files
# #
define CC_TEMPLATE define CC_TEMPLATE
#ifeq (firebee,$(1))
#MACHINE=MACHINE_FIREBEE
#else
#MACHINE=MACHINE_M5484LITE
#endif
$(1)/objs/%.o:%.c $(1)/objs/%.o:%.c
$(CC) $$(CFLAGS) -D$$(MACHINE) $(INCLUDE) -c $$< -o $$@ $(CC) $$(CFLAGS) -D$$(MACHINE) $(INCLUDE) -c $$< -o $$@

View File

@@ -39,7 +39,7 @@ enum driver_type
PCI_DRIVER, PCI_DRIVER,
MMU_DRIVER, MMU_DRIVER,
PCI_NATIVE_DRIVER, PCI_NATIVE_DRIVER,
END_OF_DRIVERS = 0xffffffff, /* marks end of driver list */ END_OF_DRIVERS = 0xffffffffL, /* marks end of driver list */
}; };
struct generic_driver_interface struct generic_driver_interface

View File

@@ -33,7 +33,7 @@
#include "interrupts.h" #include "interrupts.h"
#include "wait.h" #include "wait.h"
// #define DEBUG_PCI #define DEBUG_PCI
#ifdef DEBUG_PCI #ifdef DEBUG_PCI
#define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0) #define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0)
#else #else
@@ -392,6 +392,9 @@ uint8_t pci_read_config_byte(int32_t handle, int offset)
int32_t pci_write_config_longword(int32_t handle, int offset, uint32_t value) int32_t pci_write_config_longword(int32_t handle, int offset, uint32_t value)
{ {
/* initiate PCI configuration access to device */ /* initiate PCI configuration access to device */
dbg("initiate configuration access\r\n");
MCF_PCI_PCICAR = MCF_PCI_PCICAR_E | /* enable configuration access special cycle */ MCF_PCI_PCICAR = MCF_PCI_PCICAR_E | /* enable configuration access special cycle */
MCF_PCI_PCICAR_BUSNUM(PCI_BUS_FROM_HANDLE(handle)) | MCF_PCI_PCICAR_BUSNUM(PCI_BUS_FROM_HANDLE(handle)) |
MCF_PCI_PCICAR_DEVNUM(PCI_DEVICE_FROM_HANDLE(handle)) | /* device number, devices 0 - 9 are reserved */ MCF_PCI_PCICAR_DEVNUM(PCI_DEVICE_FROM_HANDLE(handle)) | /* device number, devices 0 - 9 are reserved */
@@ -400,11 +403,15 @@ int32_t pci_write_config_longword(int32_t handle, int offset, uint32_t value)
NOP(); NOP();
dbg("access device\r\n");
* (volatile uint32_t *) PCI_IO_OFFSET = value; /* access device */ * (volatile uint32_t *) PCI_IO_OFFSET = value; /* access device */
dbg("chip errata\r\n");
chip_errata_135(); chip_errata_135();
NOP(); NOP();
dbg("finish config space access cycle\r\n");
/* finish configuration space access cycle */ /* finish configuration space access cycle */
MCF_PCI_PCICAR &= ~MCF_PCI_PCICAR_E; MCF_PCI_PCICAR &= ~MCF_PCI_PCICAR_E;
@@ -562,6 +569,7 @@ int32_t pci_find_device(uint16_t device_id, uint16_t vendor_id, int index)
* pci_find_classcode(uint32_t classcode, int index) * pci_find_classcode(uint32_t classcode, int index)
* *
* Find the index'th pci device with a specific classcode. Bits 0-23 describe this classcode. * Find the index'th pci device with a specific classcode. Bits 0-23 describe this classcode.
*
* Bits 24 - 26 describe what needs to match: 24: prog interface, 25: PCI subclass, 26: PCI base class. * Bits 24 - 26 describe what needs to match: 24: prog interface, 25: PCI subclass, 26: PCI base class.
* If no bits are set, there is a match for each device. * If no bits are set, there is a match for each device.
*/ */
@@ -581,6 +589,7 @@ int32_t pci_find_classcode(uint32_t classcode, int index)
uint8_t htr; uint8_t htr;
handle = PCI_HANDLE(bus, device, 0); handle = PCI_HANDLE(bus, device, 0);
dbg("check handle %d\r\n", handle);
value = pci_read_config_longword(handle, PCIIDR); value = pci_read_config_longword(handle, PCIIDR);
@@ -1041,10 +1050,11 @@ static void pci_bridge_config(uint16_t bus, uint16_t device, uint16_t function)
if (function != 0) if (function != 0)
{ {
dbg("trying to configure a multi-function bridge. Cancelled\r\n"); err("trying to configure a multi-function bridge. Cancelled\r\n");
return; return;
} }
handle = PCI_HANDLE(bus, device, function); handle = PCI_HANDLE(bus, device, function);
dbg("handle=%d\r\n", handle);
pci_write_config_longword(handle, PCIBAR0, 0x40000000); pci_write_config_longword(handle, PCIBAR0, 0x40000000);
pci_write_config_longword(handle, PCIBAR1, 0x0); pci_write_config_longword(handle, PCIBAR1, 0x0);
@@ -1081,6 +1091,7 @@ void pci_scan(void)
/* save handle to index value so that we'll be able to later find our resources */ /* save handle to index value so that we'll be able to later find our resources */
handles[index] = handle; handles[index] = handle;
handles[index + 1] = -1;
if (PCI_VENDOR_ID(value) != 0x1057 && PCI_DEVICE_ID(value) != 0x5806) /* do not configure bridge */ if (PCI_VENDOR_ID(value) != 0x1057 && PCI_DEVICE_ID(value) != 0x5806) /* do not configure bridge */
{ {
@@ -1091,10 +1102,12 @@ void pci_scan(void)
} }
else else
{ {
dbg("");
pci_bridge_config(PCI_BUS_FROM_HANDLE(handle), pci_bridge_config(PCI_BUS_FROM_HANDLE(handle),
PCI_DEVICE_FROM_HANDLE(handle), PCI_DEVICE_FROM_HANDLE(handle),
PCI_FUNCTION_FROM_HANDLE(handle)); PCI_FUNCTION_FROM_HANDLE(handle));
} }
dbg("");
handle = pci_find_device(0x0, 0xFFFF, ++index); handle = pci_find_device(0x0, 0xFFFF, ++index);
} }
xprintf("\r\n...finished\r\n"); xprintf("\r\n...finished\r\n");
@@ -1118,7 +1131,7 @@ void init_eport(void)
MCF_EPORT_EPDDR = 0; /* clear data direction register. All pins as input */ MCF_EPORT_EPDDR = 0; /* clear data direction register. All pins as input */
MCF_EPORT_EPFR = -1; /* clear all EPORT interrupt flags */ MCF_EPORT_EPFR = -1; /* clear all EPORT interrupt flags */
MCF_EPORT_EPIER = 0xfe; /* enable all EPORT interrupts (for now) */ // MCF_EPORT_EPIER = 0xfe; /* enable all EPORT interrupts (for now) */
} }
void init_xlbus_arbiter(void) void init_xlbus_arbiter(void)

View File

@@ -486,8 +486,8 @@ void BaS(void)
dma_irq_enable(); dma_irq_enable();
fec_irq_enable(0, 5, 1); fec_irq_enable(0, 5, 1);
init_pci();
enable_pci_interrupts(); enable_pci_interrupts();
init_pci();
video_init(); video_init();
/* initialize USB devices */ /* initialize USB devices */

View File

@@ -584,22 +584,20 @@ void init_usb(void)
do do
{ {
handle = pci_find_device(0x0000, 0xffff, index++); handle = pci_find_classcode(PCI_CLASS_SERIAL_USB | (1 << 25) | (1 << 26), index++);
if (handle > 0) if (handle > 0)
{ {
uint32_t id = 0; long id;
uint32_t class = 0; long class;
id = pci_read_config_longword(handle, PCIIDR);
class = pci_read_config_longword(handle, PCIREV);
if (PCI_CLASS_CODE(class) == PCI_CLASS_SERIAL_USB)
{
xprintf("serial USB found at bus=0x%x, dev=0x%x, fnc=0x%x (0x%x)\r\n", xprintf("serial USB found at bus=0x%x, dev=0x%x, fnc=0x%x (0x%x)\r\n",
PCI_BUS_FROM_HANDLE(handle), PCI_BUS_FROM_HANDLE(handle),
PCI_DEVICE_FROM_HANDLE(handle), PCI_DEVICE_FROM_HANDLE(handle),
PCI_FUNCTION_FROM_HANDLE(handle), PCI_FUNCTION_FROM_HANDLE(handle),
handle); handle);
id = pci_read_config_longword(handle, PCIIDR);
class = pci_read_config_longword(handle, PCIREV);
if (PCI_SUBCLASS(class) == PCI_CLASS_SERIAL_USB_EHCI) if (PCI_SUBCLASS(class) == PCI_CLASS_SERIAL_USB_EHCI)
{ {
board = ehci_usb_pci_table; board = ehci_usb_pci_table;
@@ -629,7 +627,6 @@ void init_usb(void)
} }
} }
} }
}
} while (handle >= 0); } while (handle >= 0);
xprintf("finished (found %d USB controller(s))\r\n", usb_found); xprintf("finished (found %d USB controller(s))\r\n", usb_found);

View File

@@ -25,15 +25,17 @@
#ifndef _DRIVER_VEC_H_ #ifndef _DRIVER_VEC_H_
#define _DRIVER_VEC_H_ #define _DRIVER_VEC_H_
enum driver_type enum driver_type
{ {
END_OF_DRIVERS, /* marks end of driver list */
BLOCKDEV_DRIVER, BLOCKDEV_DRIVER,
CHARDEV_DRIVER, CHARDEV_DRIVER,
VIDEO_DRIVER,
XHDI_DRIVER, XHDI_DRIVER,
MCD_DRIVER, MCD_DRIVER,
VIDEO_DRIVER,
PCI_DRIVER,
MMU_DRIVER,
PCI_NATIVE_DRIVER,
END_OF_DRIVERS = 0xffffffffL, /* marks end of driver list */
}; };
struct generic_driver_interface struct generic_driver_interface
@@ -44,51 +46,30 @@ struct generic_driver_interface
uint32_t (*ioctl)(uint32_t request, ...); uint32_t (*ioctl)(uint32_t request, ...);
}; };
/* Chained buffer descriptor */
typedef volatile struct MCD_bufDesc_struct MCD_bufDesc;
struct MCD_bufDesc_struct {
uint32_t flags; /* flags describing the DMA */
uint32_t csumResult; /* checksum from checksumming performed since last checksum reset */
int8_t *srcAddr; /* the address to move data from */
int8_t *destAddr; /* the address to move data to */
int8_t *lastDestAddr; /* the last address written to */
uint32_t dmaSize; /* the number of bytes to transfer independent of the transfer size */
MCD_bufDesc *next; /* next buffer descriptor in chain */
uint32_t info; /* private information about this descriptor; DMA does not affect it */
};
/* Progress Query struct */
typedef volatile struct MCD_XferProg_struct {
int8_t *lastSrcAddr; /* the most-recent or last, post-increment source address */
int8_t *lastDestAddr; /* the most-recent or last, post-increment destination address */
uint32_t dmaSize; /* the amount of data transferred for the current buffer */
MCD_bufDesc *currBufDesc;/* pointer to the current buffer descriptor being DMAed */
} MCD_XferProg;
struct dma_driver_interface struct dma_driver_interface
{ {
int32_t version; int32_t version;
int32_t magic; int32_t magic;
int32_t (*dma_set_initiator)(int initiator); int (*dma_set_initiator)(int initiator);
uint32_t (*dma_get_initiator)(int requestor); uint32_t (*dma_get_initiator)(int requestor);
void (*dma_free_initiator)(int requestor); void (*dma_free_initiator)(int requestor);
int32_t (*dma_set_channel)(int requestor, void (*handler)(void)); int (*dma_set_channel)(int requestor, void (*handler)(void));
int (*dma_get_channel)(int requestor); int (*dma_get_channel)(int requestor);
void (*dma_free_channel)(int requestor); void (*dma_free_channel)(int requestor);
void (*dma_clear_channel)(int channel); void (*dma_clear_channel)(int channel);
int (*MCD_startDma)(int channel, int8_t *srcAddr, int16_t srcIncr, int8_t *destAddr, int16_t destIncr, int (*MCD_startDma)(long channel,
uint32_t dmaSize, uint32_t xferSize, uint32_t initiator, int32_t priority, uint32_t flags, int8_t *srcAddr, unsigned int srcIncr, int8_t *destAddr, unsigned int destIncr,
uint32_t funcDesc); unsigned int dmaSize, unsigned int xferSize, unsigned int initiator, int priority,
int (*MCD_dmaStatus)(int channel); unsigned int flags, unsigned int funcDesc);
int (*MCD_XferProgrQuery)(int channel, MCD_XferProg *progRep); int32_t (*MCD_dmaStatus)(int32_t channel);
int (*MCD_killDma)(int channel); int32_t (*MCD_XferProgrQuery)(int32_t channel, /* MCD_XferProg */ void *progRep);
int (*MCD_continDma)(int channel); int32_t (*MCD_killDma)(int32_t channel);
int (*MCD_pauseDma)(int channel); int32_t (*MCD_continDma)(int32_t channel);
int (*MCD_resumeDma)(int channel); int32_t (*MCD_pauseDma)(int32_t channel);
int (*MCD_csumQuery)(int channel, uint32_t *csum); int32_t (*MCD_resumeDma)(int32_t channel);
void *(*dma_malloc)(long amount); int32_t (*MCD_csumQuery)(int32_t channel, uint32_t *csum);
int (*dma_free)(void *addr); void *(*dma_malloc)(uint32_t amount);
int32_t (*dma_free)(void *addr);
}; };
struct xhdi_driver_interface struct xhdi_driver_interface
@@ -96,11 +77,222 @@ struct xhdi_driver_interface
uint32_t (*xhdivec)(); uint32_t (*xhdivec)();
}; };
/*
* Interpretation of offset for color fields: All offsets are from the right,
* inside a "pixel" value, which is exactly 'bits_per_pixel' wide (means: you
* can use the offset as right argument to <<). A pixel afterwards is a bit
* stream and is written to video memory as that unmodified. This implies
* big-endian byte order if bits_per_pixel is greater than 8.
*/
struct fb_bitfield
{
unsigned long offset; /* beginning of bitfield */
unsigned long length; /* length of bitfield */
unsigned long msb_right; /* != 0 : Most significant bit is */
/* right */
};
/*
* the following structures define the interface to the BaS-builtin-framebuffer video driver
*/
struct fb_var_screeninfo
{
unsigned long xres; /* visible resolution */
unsigned long yres;
unsigned long xres_virtual; /* virtual resolution */
unsigned long yres_virtual;
unsigned long xoffset; /* offset from virtual to visible */
unsigned long yoffset; /* resolution */
unsigned long bits_per_pixel; /* guess what */
unsigned long grayscale; /* != 0 Graylevels instead of colors */
struct fb_bitfield red; /* bitfield in fb mem if true color, */
struct fb_bitfield green; /* else only length is significant */
struct fb_bitfield blue;
struct fb_bitfield transp; /* transparency */
unsigned long nonstd; /* != 0 Non standard pixel format */
unsigned long activate; /* see FB_ACTIVATE_* */
unsigned long height; /* height of picture in mm */
unsigned long width; /* width of picture in mm */
unsigned long accel_flags; /* (OBSOLETE) see fb_info.flags */
/* Timing: All values in pixclocks, except pixclock (of course) */
unsigned long pixclock; /* pixel clock in ps (pico seconds) */
unsigned long left_margin; /* time from sync to picture */
unsigned long right_margin; /* time from picture to sync */
unsigned long upper_margin; /* time from sync to picture */
unsigned long lower_margin;
unsigned long hsync_len; /* length of horizontal sync */
unsigned long vsync_len; /* length of vertical sync */
unsigned long sync; /* see FB_SYNC_* */
unsigned long vmode; /* see FB_VMODE_* */
unsigned long rotate; /* angle we rotate counter clockwise */
unsigned long refresh;
unsigned long reserved[4]; /* Reserved for future compatibility */
};
struct fb_fix_screeninfo
{
char id[16]; /* identification string eg "TT Builtin" */
unsigned long smem_start; /* Start of frame buffer mem */
/* (physical address) */
unsigned long smem_len; /* Length of frame buffer mem */
unsigned long type; /* see FB_TYPE_* */
unsigned long type_aux; /* Interleave for interleaved Planes */
unsigned long visual; /* see FB_VISUAL_* */
unsigned short xpanstep; /* zero if no hardware panning */
unsigned short ypanstep; /* zero if no hardware panning */
unsigned short ywrapstep; /* zero if no hardware ywrap */
unsigned long line_length; /* length of a line in bytes */
unsigned long mmio_start; /* Start of Memory Mapped I/O */
/* (physical address) */
unsigned long mmio_len; /* Length of Memory Mapped I/O */
unsigned long accel; /* Indicate to driver which */
/* specific chip/card we have */
unsigned short reserved[3]; /* Reserved for future compatibility */
};
struct fb_chroma
{
unsigned long redx; /* in fraction of 1024 */
unsigned long greenx;
unsigned long bluex;
unsigned long whitex;
unsigned long redy;
unsigned long greeny;
unsigned long bluey;
unsigned long whitey;
};
struct fb_monspecs
{
struct fb_chroma chroma;
struct fb_videomode *modedb; /* mode database */
unsigned char manufacturer[4]; /* Manufacturer */
unsigned char monitor[14]; /* Monitor String */
unsigned char serial_no[14]; /* Serial Number */
unsigned char ascii[14]; /* ? */
unsigned long modedb_len; /* mode database length */
unsigned long model; /* Monitor Model */
unsigned long serial; /* Serial Number - Integer */
unsigned long year; /* Year manufactured */
unsigned long week; /* Week Manufactured */
unsigned long hfmin; /* hfreq lower limit (Hz) */
unsigned long hfmax; /* hfreq upper limit (Hz) */
unsigned long dclkmin; /* pixelclock lower limit (Hz) */
unsigned long dclkmax; /* pixelclock upper limit (Hz) */
unsigned short input; /* display type - see FB_DISP_* */
unsigned short dpms; /* DPMS support - see FB_DPMS_ */
unsigned short signal; /* Signal Type - see FB_SIGNAL_* */
unsigned short vfmin; /* vfreq lower limit (Hz) */
unsigned short vfmax; /* vfreq upper limit (Hz) */
unsigned short gamma; /* Gamma - in fractions of 100 */
unsigned short gtf : 1; /* supports GTF */
unsigned short misc; /* Misc flags - see FB_MISC_* */
unsigned char version; /* EDID version... */
unsigned char revision; /* ...and revision */
unsigned char max_x; /* Maximum horizontal size (cm) */
unsigned char max_y; /* Maximum vertical size (cm) */
};
struct framebuffer_driver_interface
{
struct fb_info **framebuffer_info; /* pointer to an fb_info struct (defined in include/fb.h) */
};
typedef void *PCI_CONV_ADR;
struct pci_bios_interface
{
uint32_t subjar;
uint32_t version;
/* Although we declare this functions as standard gcc functions (cdecl),
* they expect parameters inside registers (fastcall) unsupported by gcc m68k.
* Caller will take care of parameters passing convention.
*/
int32_t (*find_pci_device)(uint32_t id, uint16_t index);
int32_t (*find_pci_classcode)(uint32_t class, uint16_t index);
int32_t (*read_config_byte)(int32_t handle, uint16_t reg, uint8_t *address);
int32_t (*read_config_word)(int32_t handle, uint16_t reg, uint16_t *address);
int32_t (*read_config_longword)(int32_t handle, uint16_t reg, uint32_t *address);
uint8_t (*fast_read_config_byte)(int32_t handle, uint16_t reg);
uint16_t (*fast_read_config_word)(int32_t handle, uint16_t reg);
uint32_t (*fast_read_config_longword)(int32_t handle, uint16_t reg);
int32_t (*write_config_byte)(int32_t handle, uint16_t reg, uint16_t val);
int32_t (*write_config_word)(int32_t handle, uint16_t reg, uint16_t val);
int32_t (*write_config_longword)(int32_t handle, uint16_t reg, uint32_t val);
int32_t (*hook_interrupt)(int32_t handle, uint32_t *routine, uint32_t *parameter);
int32_t (*unhook_interrupt)(int32_t handle);
int32_t (*special_cycle)(uint16_t bus, uint32_t data);
int32_t (*get_routing)(int32_t handle);
int32_t (*set_interrupt)(int32_t handle);
int32_t (*get_resource)(int32_t handle);
int32_t (*get_card_used)(int32_t handle, uint32_t *address);
int32_t (*set_card_used)(int32_t handle, uint32_t *callback);
int32_t (*read_mem_byte)(int32_t handle, uint32_t offset, uint8_t *address);
int32_t (*read_mem_word)(int32_t handle, uint32_t offset, uint16_t *address);
int32_t (*read_mem_longword)(int32_t handle, uint32_t offset, uint32_t *address);
uint8_t (*fast_read_mem_byte)(int32_t handle, uint32_t offset);
uint16_t (*fast_read_mem_word)(int32_t handle, uint32_t offset);
uint32_t (*fast_read_mem_longword)(int32_t handle, uint32_t offset);
int32_t (*write_mem_byte)(int32_t handle, uint32_t offset, uint16_t val);
int32_t (*write_mem_word)(int32_t handle, uint32_t offset, uint16_t val);
int32_t (*write_mem_longword)(int32_t handle, uint32_t offset, uint32_t val);
int32_t (*read_io_byte)(int32_t handle, uint32_t offset, uint8_t *address);
int32_t (*read_io_word)(int32_t handle, uint32_t offset, uint16_t *address);
int32_t (*read_io_longword)(int32_t handle, uint32_t offset, uint32_t *address);
uint8_t (*fast_read_io_byte)(int32_t handle, uint32_t offset);
uint16_t (*fast_read_io_word)(int32_t handle, uint32_t offset);
uint32_t (*fast_read_io_longword)(int32_t handle, uint32_t offset);
int32_t (*write_io_byte)(int32_t handle, uint32_t offset, uint16_t val);
int32_t (*write_io_word)(int32_t handle, uint32_t offset, uint16_t val);
int32_t (*write_io_longword)(int32_t handle, uint32_t offset, uint32_t val);
int32_t (*get_machine_id)(void);
int32_t (*get_pagesize)(void);
int32_t (*virt_to_bus)(int32_t handle, uint32_t address, PCI_CONV_ADR *pointer);
int32_t (*bus_to_virt)(int32_t handle, uint32_t address, PCI_CONV_ADR *pointer);
int32_t (*virt_to_phys)(uint32_t address, PCI_CONV_ADR *pointer);
int32_t (*phys_to_virt)(uint32_t address, PCI_CONV_ADR *pointer);
// int32_t reserved[2];
};
struct mmu_driver_interface
{
int32_t (*map_page_locked)(uint32_t address, uint32_t length, int asid);
int32_t (*unlock_page)(uint32_t address, uint32_t length, int asid);
int32_t (*report_locked_pages)(uint32_t *num_itlb, uint32_t *num_dtlb);
uint32_t (*report_pagesize)(void);
};
struct pci_native_driver_interface
{
uint32_t (*pci_read_config_longword)(int32_t handle, int offset);
uint16_t (*pci_read_config_word)(int32_t handle, int offset);
uint8_t (*pci_read_config_byte)(int32_t handle, int offset);
int32_t (*pci_write_config_longword)(int32_t handle, int offset, uint32_t value);
int32_t (*pci_write_config_word)(int32_t handle, int offset, uint16_t value);
int32_t (*pci_write_config_byte)(int32_t handle, int offset, uint8_t value);
int32_t (*pci_hook_interrupt)(int32_t handle, void *handler, void *parameter);
int32_t (*pci_unhook_interrupt)(int32_t handle);
struct pci_rd * (*pci_get_resource)(int32_t handle);
};
union interface union interface
{ {
struct generic_driver_interface *gdi; struct generic_driver_interface *gdi;
struct xhdi_driver_interface *xhdi; struct xhdi_driver_interface *xhdi;
struct dma_driver_interface *dma; struct dma_driver_interface *dma;
struct framebuffer_driver_interface *fb;
struct pci_bios_interface *pci;
struct mmu_driver_interface *mmu;
struct pci_native_driver_interface *pci_native;
}; };
struct generic_interface struct generic_interface
@@ -117,7 +309,7 @@ struct driver_table
{ {
uint32_t bas_version; uint32_t bas_version;
uint32_t bas_revision; uint32_t bas_revision;
uint32_t (*remove_handler)(); /* calling this will disable the BaS' hook into trap #0 */ void (*remove_handler)(void); /* calling this will disable the BaS' hook into trap #0 */
struct generic_interface *interfaces; struct generic_interface *interfaces;
}; };

View File

@@ -14,8 +14,11 @@
volatile int32_t time, start, end; volatile int32_t time, start, end;
int i; int i;
void do_tests(void) void do_tests(struct pci_native_driver_interface *pci)
{ {
#define PCI_READ_CONFIG_LONGWORD(a, b) pci->pci_read_config_longword(a, b)
#define PCI_WRITE_CONFIG_LONGWORD(a, b) pci->pci_write_config_longword(a, b)
start = MCF_SLT0_SCNT; start = MCF_SLT0_SCNT;
hexdump((uint8_t *) 0, 64); hexdump((uint8_t *) 0, 64);
end = MCF_SLT0_SCNT; end = MCF_SLT0_SCNT;
@@ -24,56 +27,74 @@ void do_tests(void)
xprintf("finished (took %f seconds).\r\n", time / 1000.0); xprintf("finished (took %f seconds).\r\n", time / 1000.0);
} }
struct driver_table *get_bas_drivers(void)
void wait_for_jtag(void)
{ {
long i; struct driver_table *ret = NULL;
do_tests(); __asm__ __volatile__(
" bra.s do_trap \n\t"
" .dc.l 0x5f424153 \n\t" // '_BAS'
"do_trap: trap #0 \n\t"
" move.l d0,%[ret] \n\t"
: [ret] "=m" (ret) /* output */
: /* no inputs */
: /* clobbered */
);
xprintf("wait a little to let things settle...\r\n"); return ret;
for (i = 0; i < 100000L; i++); }
xprintf("INFO: endless loop now. Press reset to reboot\r\n"); void pci_test(void)
while (1) {
; struct driver_table *bas_drivers;
struct generic_interface *ifc;
bool pci_driver_found = false;
struct pci_native_driver_interface *pci_driver = NULL;
bas_drivers = get_bas_drivers();
printf("BaS version: %ld.%02ld\r\n", (long) bas_drivers->bas_version, (long) bas_drivers->bas_revision);
ifc = bas_drivers->interfaces;
do {
struct generic_interface *pci_driver_interface = NULL;
printf("interface type: %ld\r\n", (long) ifc[i].type);
printf("interface version: %ld.%02ld\r\n", (long) ifc[i].version, (long) ifc[i].revision);
printf("interface name: %s\r\n", ifc[i].name);
printf("interface description: %s\r\n", ifc[i].description);
if (ifc[i].type == PCI_NATIVE_DRIVER)
{
pci_driver_found = true;
if (!pci_driver_interface || (ifc[i].version > pci_driver_interface->version ||
(ifc[i].version == pci_driver_interface->version && ifc[i].revision > pci_driver_interface->revision)))
{
/*
* either no PCI driver interface found yet or with lower version or with lower version and higher revision
*
* replace it
*/
pci_driver = ifc[i].interface.pci_native;
pci_driver_interface = &ifc[i];
printf("PCI native driver interface v%d.%02d found\r\n", pci_driver_interface->version, pci_driver_interface->revision);
}
}
} while (ifc[++i].type != END_OF_DRIVERS);
if (pci_driver_found)
{
do_tests(pci_driver);
}
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
printf("FPGA JTAG configuration support\r\n"); printf("PCI test routines\r\n");
printf("test FPGA DDR RAM controller\r\n"); printf("\xbd 2014 M. Fr\x94schle\r\n");
printf("\xbd 2014 M. F\x94schle\r\n");
printf("You may now savely load a new FPGA configuration through the JTAG interface\r\n" Supexec(pci_test);
"and your Firebee will reboot once finished using that new configuration.\r\n");
if (argc == 2)
{
/*
* we got an argument. This is supposed to be the address that we need to jump to after JTAG
* configuration has been finished. Meant to support BaS in RAM testing
*/
char *addr_str = argv[1];
char *addr = NULL;
char *end = NULL;
addr = (char *) strtol(addr_str, &end, 16);
if (addr != NULL && addr <= (char *) 0xe0000000 && addr >= (char *) 0x10000000)
{
/*
* seems to be a valid address
*/
// bas_start = (long) addr;
// printf("BaS start address set to %p\r\n", (void *) bas_start);
}
else
{
// printf("\r\nNote: BaS start address %p not valid. Stick to %p.\r\n", addr, (void *) bas_start);
}
}
Supexec(wait_for_jtag);
return 0; /* just to make the compiler happy, we will never return */ return 0; /* just to make the compiler happy, we will never return */
} }

View File

@@ -232,7 +232,8 @@ void wait_for_jtag(void)
init_video_ddr(); init_video_ddr();
/* begin of tests */ /* begin of tests */
do_tests();
while (1) do_tests();
xprintf("wait a little to let things settle...\r\n"); xprintf("wait a little to let things settle...\r\n");
for (i = 0; i < 100000L; i++); for (i = 0; i < 100000L; i++);