From 424a276deefb369e88a50b5239b5a2b96ff02de3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Fr=C3=B6schle?= Date: Fri, 20 Nov 2015 19:25:57 +0000 Subject: [PATCH] add PCI driver interface enumeration routine --- BaS_gcc/BaS_gcc.files | 27 ++ BaS_gcc/Makefile | 6 - BaS_gcc/include/driver_vec.h | 2 +- BaS_gcc/include/pci_ids.h | 2 +- BaS_gcc/pci/pci.c | 19 +- BaS_gcc/sys/BaS.c | 2 +- BaS_gcc/sys/sysinit.c | 51 ++-- BaS_gcc/tos/pci_test/include/driver_vec.h | 330 +++++++++++++++++----- BaS_gcc/tos/pci_test/sources/pci_test.c | 105 ++++--- BaS_gcc/tos/vmem_test/sources/vmem_test.c | 3 +- 10 files changed, 396 insertions(+), 151 deletions(-) diff --git a/BaS_gcc/BaS_gcc.files b/BaS_gcc/BaS_gcc.files index f7b077c..b874fef 100644 --- a/BaS_gcc/BaS_gcc.files +++ b/BaS_gcc/BaS_gcc.files @@ -581,3 +581,30 @@ dump.bdm Makefile mcf5474.gdb 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 diff --git a/BaS_gcc/Makefile b/BaS_gcc/Makefile index 4fa1ae3..1172d54 100644 --- a/BaS_gcc/Makefile +++ b/BaS_gcc/Makefile @@ -216,12 +216,6 @@ firebee/basflash.$(EXE): CFLAGS += -mcpu=5474 # generate pattern rules for different object files # define CC_TEMPLATE -#ifeq (firebee,$(1)) - #MACHINE=MACHINE_FIREBEE -#else - #MACHINE=MACHINE_M5484LITE -#endif - $(1)/objs/%.o:%.c $(CC) $$(CFLAGS) -D$$(MACHINE) $(INCLUDE) -c $$< -o $$@ diff --git a/BaS_gcc/include/driver_vec.h b/BaS_gcc/include/driver_vec.h index a50193a..61a7ae8 100644 --- a/BaS_gcc/include/driver_vec.h +++ b/BaS_gcc/include/driver_vec.h @@ -39,7 +39,7 @@ enum driver_type PCI_DRIVER, MMU_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 diff --git a/BaS_gcc/include/pci_ids.h b/BaS_gcc/include/pci_ids.h index 843d5ab..f57d92e 100644 --- a/BaS_gcc/include/pci_ids.h +++ b/BaS_gcc/include/pci_ids.h @@ -45,7 +45,7 @@ #define PCI_CLASS_BRIDGE_HOST 0x0600 #define PCI_CLASS_BRIDGE_ISA 0x0601 #define PCI_CLASS_BRIDGE_EISA 0x0602 -#define PCI_CLASS_BRIDGE_MC 0x0603 +#define PCI_CLASS_BRIDGE_MC 0x0603 #define PCI_CLASS_BRIDGE_PCI 0x0604 #define PCI_CLASS_BRIDGE_PCMCIA 0x0605 #define PCI_CLASS_BRIDGE_NUBUS 0x0606 diff --git a/BaS_gcc/pci/pci.c b/BaS_gcc/pci/pci.c index b2a8169..23a0d6d 100644 --- a/BaS_gcc/pci/pci.c +++ b/BaS_gcc/pci/pci.c @@ -33,7 +33,7 @@ #include "interrupts.h" #include "wait.h" -// #define DEBUG_PCI +#define DEBUG_PCI #ifdef DEBUG_PCI #define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0) #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) { /* 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_BUSNUM(PCI_BUS_FROM_HANDLE(handle)) | 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(); + dbg("access device\r\n"); * (volatile uint32_t *) PCI_IO_OFFSET = value; /* access device */ + + dbg("chip errata\r\n"); chip_errata_135(); NOP(); + dbg("finish config space access cycle\r\n"); /* finish configuration space access cycle */ 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) * * 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. * 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; handle = PCI_HANDLE(bus, device, 0); + dbg("check handle %d\r\n", handle); 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) { - dbg("trying to configure a multi-function bridge. Cancelled\r\n"); + err("trying to configure a multi-function bridge. Cancelled\r\n"); return; } handle = PCI_HANDLE(bus, device, function); + dbg("handle=%d\r\n", handle); pci_write_config_longword(handle, PCIBAR0, 0x40000000); 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 */ handles[index] = handle; + handles[index + 1] = -1; if (PCI_VENDOR_ID(value) != 0x1057 && PCI_DEVICE_ID(value) != 0x5806) /* do not configure bridge */ { @@ -1091,10 +1102,12 @@ void pci_scan(void) } else { + dbg(""); pci_bridge_config(PCI_BUS_FROM_HANDLE(handle), PCI_DEVICE_FROM_HANDLE(handle), PCI_FUNCTION_FROM_HANDLE(handle)); } + dbg(""); handle = pci_find_device(0x0, 0xFFFF, ++index); } 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_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) diff --git a/BaS_gcc/sys/BaS.c b/BaS_gcc/sys/BaS.c index 5614cde..edfdc70 100644 --- a/BaS_gcc/sys/BaS.c +++ b/BaS_gcc/sys/BaS.c @@ -486,8 +486,8 @@ void BaS(void) dma_irq_enable(); fec_irq_enable(0, 5, 1); - init_pci(); enable_pci_interrupts(); + init_pci(); video_init(); /* initialize USB devices */ diff --git a/BaS_gcc/sys/sysinit.c b/BaS_gcc/sys/sysinit.c index 1bdf092..1ca6645 100644 --- a/BaS_gcc/sys/sysinit.c +++ b/BaS_gcc/sys/sysinit.c @@ -584,49 +584,46 @@ void init_usb(void) do { - handle = pci_find_device(0x0000, 0xffff, index++); + handle = pci_find_classcode(PCI_CLASS_SERIAL_USB | (1 << 25) | (1 << 26), index++); if (handle > 0) { - uint32_t id = 0; - uint32_t class = 0; + long id; + long class; + xprintf("serial USB found at bus=0x%x, dev=0x%x, fnc=0x%x (0x%x)\r\n", + PCI_BUS_FROM_HANDLE(handle), + PCI_DEVICE_FROM_HANDLE(handle), + PCI_FUNCTION_FROM_HANDLE(handle), + handle); id = pci_read_config_longword(handle, PCIIDR); class = pci_read_config_longword(handle, PCIREV); - if (PCI_CLASS_CODE(class) == PCI_CLASS_SERIAL_USB) + if (PCI_SUBCLASS(class) == PCI_CLASS_SERIAL_USB_EHCI) { - xprintf("serial USB found at bus=0x%x, dev=0x%x, fnc=0x%x (0x%x)\r\n", - PCI_BUS_FROM_HANDLE(handle), - PCI_DEVICE_FROM_HANDLE(handle), - PCI_FUNCTION_FROM_HANDLE(handle), - handle); - if (PCI_SUBCLASS(class) == PCI_CLASS_SERIAL_USB_EHCI) + board = ehci_usb_pci_table; + while (board->vendor) { - board = ehci_usb_pci_table; - while (board->vendor) + if ((board->vendor == PCI_VENDOR_ID(id)) && board->device == PCI_DEVICE_ID(id)) { - if ((board->vendor == PCI_VENDOR_ID(id)) && board->device == PCI_DEVICE_ID(id)) + if (usb_init(handle, board) >= 0) { - if (usb_init(handle, board) >= 0) - { - usb_found++; - } + usb_found++; } - board++; } + board++; } - if (PCI_SUBCLASS(class) == PCI_CLASS_SERIAL_USB_OHCI) + } + if (PCI_SUBCLASS(class) == PCI_CLASS_SERIAL_USB_OHCI) + { + board = ohci_usb_pci_table; + while (board->vendor) { - board = ohci_usb_pci_table; - while (board->vendor) + if ((board->vendor == PCI_VENDOR_ID(id)) && board->device == PCI_DEVICE_ID(id)) { - if ((board->vendor == PCI_VENDOR_ID(id)) && board->device == PCI_DEVICE_ID(id)) - { - if (usb_init(handle, board) >= 0) - usb_found++; - } - board++; + if (usb_init(handle, board) >= 0) + usb_found++; } + board++; } } } diff --git a/BaS_gcc/tos/pci_test/include/driver_vec.h b/BaS_gcc/tos/pci_test/include/driver_vec.h index 8b9352a..86f59ff 100644 --- a/BaS_gcc/tos/pci_test/include/driver_vec.h +++ b/BaS_gcc/tos/pci_test/include/driver_vec.h @@ -25,100 +25,292 @@ #ifndef _DRIVER_VEC_H_ #define _DRIVER_VEC_H_ - enum driver_type { - END_OF_DRIVERS, /* marks end of driver list */ - BLOCKDEV_DRIVER, - CHARDEV_DRIVER, - VIDEO_DRIVER, - XHDI_DRIVER, - MCD_DRIVER, + BLOCKDEV_DRIVER, + CHARDEV_DRIVER, + XHDI_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 { - uint32_t (*init)(void); - uint32_t (*read)(void *buf, size_t count); - uint32_t (*write)(const void *buf, size_t count); - uint32_t (*ioctl)(uint32_t request, ...); + uint32_t (*init)(void); + uint32_t (*read)(void *buf, size_t count); + uint32_t (*write)(const void *buf, size_t count); + 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 { - int32_t version; - int32_t magic; - int32_t (*dma_set_initiator)(int initiator); - uint32_t (*dma_get_initiator)(int requestor); - void (*dma_free_initiator)(int requestor); - int32_t (*dma_set_channel)(int requestor, void (*handler)(void)); - int (*dma_get_channel)(int requestor); - void (*dma_free_channel)(int requestor); - void (*dma_clear_channel)(int channel); - int (*MCD_startDma)(int channel, int8_t *srcAddr, int16_t srcIncr, int8_t *destAddr, int16_t destIncr, - uint32_t dmaSize, uint32_t xferSize, uint32_t initiator, int32_t priority, uint32_t flags, - uint32_t funcDesc); - int (*MCD_dmaStatus)(int channel); - int (*MCD_XferProgrQuery)(int channel, MCD_XferProg *progRep); - int (*MCD_killDma)(int channel); - int (*MCD_continDma)(int channel); - int (*MCD_pauseDma)(int channel); - int (*MCD_resumeDma)(int channel); - int (*MCD_csumQuery)(int channel, uint32_t *csum); - void *(*dma_malloc)(long amount); - int (*dma_free)(void *addr); + int32_t version; + int32_t magic; + int (*dma_set_initiator)(int initiator); + uint32_t (*dma_get_initiator)(int requestor); + void (*dma_free_initiator)(int requestor); + int (*dma_set_channel)(int requestor, void (*handler)(void)); + int (*dma_get_channel)(int requestor); + void (*dma_free_channel)(int requestor); + void (*dma_clear_channel)(int channel); + int (*MCD_startDma)(long channel, + int8_t *srcAddr, unsigned int srcIncr, int8_t *destAddr, unsigned int destIncr, + unsigned int dmaSize, unsigned int xferSize, unsigned int initiator, int priority, + unsigned int flags, unsigned int funcDesc); + int32_t (*MCD_dmaStatus)(int32_t channel); + int32_t (*MCD_XferProgrQuery)(int32_t channel, /* MCD_XferProg */ void *progRep); + int32_t (*MCD_killDma)(int32_t channel); + int32_t (*MCD_continDma)(int32_t channel); + int32_t (*MCD_pauseDma)(int32_t channel); + int32_t (*MCD_resumeDma)(int32_t channel); + int32_t (*MCD_csumQuery)(int32_t channel, uint32_t *csum); + void *(*dma_malloc)(uint32_t amount); + int32_t (*dma_free)(void *addr); }; - + 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 { - struct generic_driver_interface *gdi; - struct xhdi_driver_interface *xhdi; - struct dma_driver_interface *dma; + struct generic_driver_interface *gdi; + struct xhdi_driver_interface *xhdi; + 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 { - enum driver_type type; - char name[16]; - char description[64]; - int version; - int revision; - union interface interface; + enum driver_type type; + char name[16]; + char description[64]; + int version; + int revision; + union interface interface; }; struct driver_table { - uint32_t bas_version; - uint32_t bas_revision; - uint32_t (*remove_handler)(); /* calling this will disable the BaS' hook into trap #0 */ - struct generic_interface *interfaces; + uint32_t bas_version; + uint32_t bas_revision; + void (*remove_handler)(void); /* calling this will disable the BaS' hook into trap #0 */ + struct generic_interface *interfaces; }; diff --git a/BaS_gcc/tos/pci_test/sources/pci_test.c b/BaS_gcc/tos/pci_test/sources/pci_test.c index 1482e35..d97e9a8 100644 --- a/BaS_gcc/tos/pci_test/sources/pci_test.c +++ b/BaS_gcc/tos/pci_test/sources/pci_test.c @@ -14,8 +14,11 @@ volatile int32_t time, start, end; 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; hexdump((uint8_t *) 0, 64); end = MCF_SLT0_SCNT; @@ -24,56 +27,74 @@ void do_tests(void) xprintf("finished (took %f seconds).\r\n", time / 1000.0); } - - -void wait_for_jtag(void) +struct driver_table *get_bas_drivers(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"); - for (i = 0; i < 100000L; i++); + return ret; +} - xprintf("INFO: endless loop now. Press reset to reboot\r\n"); - while (1) - ; +void pci_test(void) +{ + 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[]) { - printf("FPGA JTAG configuration support\r\n"); - printf("test FPGA DDR RAM controller\r\n"); - printf("\xbd 2014 M. F\x94schle\r\n"); + printf("PCI test routines\r\n"); + printf("\xbd 2014 M. Fr\x94schle\r\n"); - printf("You may now savely load a new FPGA configuration through the JTAG interface\r\n" - "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); + Supexec(pci_test); return 0; /* just to make the compiler happy, we will never return */ } diff --git a/BaS_gcc/tos/vmem_test/sources/vmem_test.c b/BaS_gcc/tos/vmem_test/sources/vmem_test.c index 7735949..ef2c000 100644 --- a/BaS_gcc/tos/vmem_test/sources/vmem_test.c +++ b/BaS_gcc/tos/vmem_test/sources/vmem_test.c @@ -232,7 +232,8 @@ void wait_for_jtag(void) init_video_ddr(); /* begin of tests */ - do_tests(); + + while (1) do_tests(); xprintf("wait a little to let things settle...\r\n"); for (i = 0; i < 100000L; i++);