PCI memory access working
This commit is contained in:
@@ -50,10 +50,9 @@ INCDIR=include
|
||||
INCLUDE+=-I$(INCDIR)
|
||||
|
||||
CSRCS=\
|
||||
$(SRCDIR)/pci_test.c \
|
||||
$(SRCDIR)/bas_printf.c
|
||||
$(SRCDIR)/pci_test.c
|
||||
|
||||
ASRCS=$(SRCDIR)/printf_helper.S
|
||||
ASRCS=
|
||||
|
||||
COBJS=$(patsubst $(SRCDIR)/%.o,%.o,$(patsubst %.c,%.o,$(CSRCS)))
|
||||
AOBJS=$(patsubst $(SRCDIR)/%.o,%.o,$(patsubst %.S,%.o,$(ASRCS)))
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
/*
|
||||
* bas_types.h
|
||||
*
|
||||
* Created on: 17.11.2012
|
||||
* Author: mfro
|
||||
*
|
||||
* This file is part of BaS_gcc.
|
||||
*
|
||||
@@ -15,21 +19,17 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with BaS_gcc. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Copyright 2010 - 2012 F. Aschwanden
|
||||
* Copyright 2011 - 2012 V. Riviere
|
||||
* Copyright 2012 M. Froeschle
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _BAS_PRINTF_H_
|
||||
#define _BAS_PRINTF_H_
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#ifndef BAS_TYPES_H_
|
||||
#define BAS_TYPES_H_
|
||||
|
||||
extern void xvsnprintf(char *str, size_t size, const char *fmt, va_list va);
|
||||
extern void xvprintf(const char *fmt, va_list va);
|
||||
extern void xprintf(const char *fmt, ...);
|
||||
extern void xsnprintf(char *str, size_t size, const char *fmt, ...);
|
||||
extern void xputchar(int c);
|
||||
extern int sprintf(char *str, const char *format, ...);
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h> /* for sizeof() etc. */
|
||||
|
||||
|
||||
extern void display_progress(void);
|
||||
extern void hexdump(uint8_t buffer[], int size);
|
||||
#endif /* _BAS_PRINTF_H_ */
|
||||
#endif /* BAS_TYPES_H_ */
|
||||
@@ -21,26 +21,33 @@
|
||||
* Author: Markus Fröschle
|
||||
*/
|
||||
|
||||
#include <bas_types.h>
|
||||
#include "util.h" /* for swpX() */
|
||||
|
||||
#define PCI_MEMORY_OFFSET 0x80000000
|
||||
#define PCI_MEMORY_SIZE 0x40000000 /* 1 GByte PCI memory window */
|
||||
#define PCI_IO_OFFSET 0xD0000000
|
||||
#define PCI_IO_SIZE 0x10000000 /* 128 MByte PCI I/O window */
|
||||
#define PCI_IO_SIZE 0x10000000 /* 256 MByte PCI I/O window */
|
||||
|
||||
#define PCI_LANESWAP_B(x) (x ^ 3)
|
||||
#define PCI_LANESWAP_W(x) (x ^ 2)
|
||||
#define PCI_LANESWAP_L(x) (x) /* for completeness only */
|
||||
/*
|
||||
* Note: the byte offsets are in little endian format, so you can't use them
|
||||
* on byteswapped (Motorola format) values!
|
||||
* Note: the byte offsets are in little endian format, so for pci_xxx_config_byte()
|
||||
* accesses to hit the right offset, you'll need to wrap them into PCI_LANESWAP_B()
|
||||
* and for pci_xxx_config_word() into PCI_LANESWAP_W()
|
||||
*/
|
||||
#define PCIIDR 0x00 /* PCI Configuration ID Register */
|
||||
#define PCICSR 0x04 /* PCI Command/Status Register */
|
||||
#define PCICR 0x04 /* PCI Command Register */
|
||||
#define PCISR 0x06 /* PCI Status Register */
|
||||
#define PCIREV 0x08 /* PCI Revision ID Register */
|
||||
#define PCICCR 0x0B /* PCI Class Code Register */
|
||||
#define PCICLSR 0x0C /* PCI Cache Line Size Register */
|
||||
#define PCILTR 0x0D /* PCI Latency Timer Register */
|
||||
#define PCIHTR 0x0E /* PCI Header Type Register */
|
||||
#define PCIBISTR 0x0F /* PCI Build-In Self Test Register */
|
||||
#define PCICR 0x06 /* PCI Command Register */
|
||||
#define PCISR 0x04 /* PCI Status Register */
|
||||
#define PCIREV 0x0B /* PCI Revision ID Register */
|
||||
#define PCICCR 0x08 /* PCI Class Code Register */
|
||||
#define PCICLSR 0x0F /* PCI Cache Line Size Register */
|
||||
#define PCILTR 0x0E /* PCI Latency Timer Register */
|
||||
#define PCIHTR 0x0D /* PCI Header Type Register */
|
||||
#define PCIBISTR 0x0C /* PCI Build-In Self Test Register */
|
||||
|
||||
#define PCIBAR0 0x10 /* PCI Base Address Register for Memory
|
||||
Accesses to Local, Runtime, and DMA */
|
||||
#define PCIBAR1 0x14 /* PCI Base Address Register for I/O
|
||||
@@ -53,13 +60,13 @@
|
||||
#define PCIBAR5 0x24 /* PCI Base Address Register, reserved */
|
||||
#define PCICIS 0x28 /* PCI Cardbus CIS Pointer, not support*/
|
||||
#define PCISVID 0x2E /* PCI Subsystem Vendor ID */
|
||||
#define PCISID 0x2E /* PCI Subsystem ID */
|
||||
#define PCISID 0x2D /* PCI Subsystem ID */
|
||||
#define PCIERBAR 0x30 /* PCI Expansion ROM Base Register */
|
||||
#define CAP_PTR 0x34 /* New Capability Pointer */
|
||||
#define PCIILR 0x3C /* PCI Interrupt Line Register */
|
||||
#define PCIIPR 0x3D /* PCI Interrupt Pin Register */
|
||||
#define PCIMGR 0x3E /* PCI Min_Gnt Register */
|
||||
#define PCIMLR 0x3F /* PCI Max_Lat Register */
|
||||
#define PCIILR 0x3F /* PCI Interrupt Line Register */
|
||||
#define PCIIPR 0x3E /* PCI Interrupt Pin Register */
|
||||
#define PCIMGR 0x3D /* PCI Min_Gnt Register */
|
||||
#define PCIMLR 0x3C /* PCI Max_Lat Register */
|
||||
#define PMCAPID 0x40 /* Power Management Capability ID */
|
||||
#define PMNEXT 0x41 /* Power Management Next Capability
|
||||
Pointer */
|
||||
@@ -79,41 +86,41 @@
|
||||
/*
|
||||
* bit definitions for PCICSR lower half (Command Register)
|
||||
*/
|
||||
#define PCICSR_IO (1 << 0) /* if set: device responds to I/O space accesses */
|
||||
#define PCICSR_MEMORY (1 << 1) /* if set: device responds to memory space accesses */
|
||||
#define PCICSR_MASTER (1 << 2) /* if set: device is master */
|
||||
#define PCICSR_SPECIAL (1 << 3) /* if set: device reacts on special cycles */
|
||||
#define PCICSR_MEMWI (1 << 4) /* if set: device deals with memory write and invalidate */
|
||||
#define PCICSR_VGA_SNOOP (1 << 5) /* if set: capable of palette snoop */
|
||||
#define PCICSR_PERR (1 << 6) /* if set: reacts to parity errors */
|
||||
#define PCICSR_STEPPING (1 << 7) /* if set: stepping enabled */
|
||||
#define PCICSR_SERR (1 << 8) /* if set: SERR pin enabled */
|
||||
#define PCICSR_FAST_BTOB_E (1 << 9) /* if set: fast back-to-back enabled */
|
||||
#define PCICSR_INT_DISABLE (1 << 10) /* if set: disable interrupts from this device */
|
||||
#define PCICR_IO (1 << 0) /* if set: device responds to I/O space accesses */
|
||||
#define PCICR_MEMORY (1 << 1) /* if set: device responds to memory space accesses */
|
||||
#define PCICR_MASTER (1 << 2) /* if set: device is master */
|
||||
#define PCICR_SPECIAL (1 << 3) /* if set: device reacts on special cycles */
|
||||
#define PCICR_MEMWI (1 << 4) /* if set: device deals with memory write and invalidate */
|
||||
#define PCICR_VGA_SNOOP (1 << 5) /* if set: capable of palette snoop */
|
||||
#define PCICR_PERR (1 << 6) /* if set: reacts to parity errors */
|
||||
#define PCICR_STEPPING (1 << 7) /* if set: stepping enabled */
|
||||
#define PCICR_SERR (1 << 8) /* if set: SERR pin enabled */
|
||||
#define PCICR_FAST_BTOB_E (1 << 9) /* if set: fast back-to-back enabled */
|
||||
#define PCICR_INT_DISABLE (1 << 10) /* if set: disable interrupts from this device */
|
||||
/*
|
||||
* bit definitions for PCICSR upper half (Status Register)
|
||||
*/
|
||||
#define PCICSR_INTERRUPT (1 << 3) /* device requested interrupt */
|
||||
#define PCICSR_CAPABILITIES (1 << 4) /* if set, capabilities pointer is valid */
|
||||
#define PCICSR_66MHZ (1 << 5) /* 66 MHz capable */
|
||||
#define PCICSR_UDF (1 << 6) /* UDF supported */
|
||||
#define PCICSR_FAST_BTOB (1 << 7) /* Fast back-to-back enabled */
|
||||
#define PCICSR_DPARITY_ERROR (1 << 8) /* data parity error detected */
|
||||
#define PCISR_INTERRUPT (1 << 3) /* device requested interrupt */
|
||||
#define PCISR_CAPABILITIES (1 << 4) /* if set, capabilities pointer is valid */
|
||||
#define PCISR_66MHZ (1 << 5) /* 66 MHz capable */
|
||||
#define PCISR_UDF (1 << 6) /* UDF supported */
|
||||
#define PCISR_FAST_BTOB (1 << 7) /* Fast back-to-back enabled */
|
||||
#define PCISR_DPARITY_ERROR (1 << 8) /* data parity error detected */
|
||||
|
||||
#define PCICSR_T_ABORT_S (1 << 11) /* target abort signaled */
|
||||
#define PCICSR_T_ABORT_R (1 << 12) /* target abort received */
|
||||
#define PCICSR_M_ABORT_R (1 << 13) /* master abort received */
|
||||
#define PCICSR_S_ERROR_S (1 << 14) /* system error signaled */
|
||||
#define PCICSR_PARITY_ERR (1 << 15) /* data parity error */
|
||||
#define PCISR_T_ABORT_S (1 << 11) /* target abort signaled */
|
||||
#define PCISR_T_ABORT_R (1 << 12) /* target abort received */
|
||||
#define PCISR_M_ABORT_R (1 << 13) /* master abort received */
|
||||
#define PCISR_S_ERROR_S (1 << 14) /* system error signaled */
|
||||
#define PCISR_PARITY_ERR (1 << 15) /* data parity error */
|
||||
|
||||
/* Header type 1 (PCI-to-PCI bridges) */
|
||||
#define PCI_PRIMARY_BUS 0x18 /* Primary bus number */
|
||||
#define PCI_SECONDARY_BUS 0x19 /* Secondary bus number */
|
||||
#define PCI_SUBORDINATE_BUS 0x1A /* Highest bus number behind the bridge */
|
||||
#define PCI_SEC_LATENCY_TIMER 0x1B /* Latency timer for secondary interface */
|
||||
#define PCI_PRIMARY_BUS 0x1B /* Primary bus number */
|
||||
#define PCI_SECONDARY_BUS 0x1A /* Secondary bus number */
|
||||
#define PCI_SUBORDINATE_BUS 0x19 /* Highest bus number behind the bridge */
|
||||
#define PCI_SEC_LATENCY_TIMER 0x18 /* Latency timer for secondary interface */
|
||||
#define PCI_IO_BASE 0x1C /* I/O range behind the bridge */
|
||||
#define PCI_IO_LIMIT 0x1D
|
||||
#define PCI_SEC_STATUS 0x1E /* Secondary status register, only bit 14 used */
|
||||
#define PCI_SEC_STATUS 0x1C /* Secondary status register, only bit 14 used */
|
||||
#define PCI_MEMORY_BASE 0x20 /* Memory range behind */
|
||||
#define PCI_MEMORY_LIMIT 0x22
|
||||
#define PCI_PREF_MEMORY_BASE 0x24 /* Prefetchable memory range behind */
|
||||
@@ -184,28 +191,28 @@ typedef struct /* structure of address conversion */
|
||||
/* PCI configuration space macros */
|
||||
|
||||
/* register 0x00 macros */
|
||||
#define PCI_VENDOR_ID(i) swpw((uint16_t)(((i) & 0xffff0000) >> 16))
|
||||
#define PCI_DEVICE_ID(i) swpw((uint16_t) ((i) & 0xffff))
|
||||
#define PCI_DEVICE_ID(i) (uint16_t)(((i) & 0xffff0000) >> 16)
|
||||
#define PCI_VENDOR_ID(i) (uint16_t) ((i) & 0xffff)
|
||||
|
||||
/* register 0x04 macros */
|
||||
#define PCI_STATUS(i) ((i) & 0xffff)
|
||||
#define PCI_COMMAND(i) (((i) >> 16) & 0xffff)
|
||||
|
||||
/* register 0x08 macros */
|
||||
#define PCI_CLASS_CODE(i) ((swpl((i)) & 0xff000000) >> 24)
|
||||
#define PCI_SUBCLASS(i) ((swpl((i)) & 0xffff0000) >> 16)
|
||||
#define PCI_PROG_IF(i) ((swpl((i)) & 0x0000ff00) >> 8)
|
||||
#define PCI_REVISION_ID(i) ((swpl((i)) & 0x000000ff))
|
||||
#define PCI_CLASS_CODE(i) (((i) & 0xff000000) >> 24)
|
||||
#define PCI_SUBCLASS(i) (((i) & 0x00ff0000) >> 16)
|
||||
#define PCI_PROG_IF(i) (((i) & 0x0000ff00) >> 8)
|
||||
#define PCI_REVISION_ID(i) (((i) & 0x000000ff))
|
||||
|
||||
/* register 0x0c macros */
|
||||
#define PCI_BIST(i) ((swpl((i)) & 0xff000000) >> 24)
|
||||
#define PCI_HEADER_TYPE(i) ((swpl((i)) & 0x00ff0000) >> 16)
|
||||
#define PCI_LAT_TIMER(i) ((swpl((i)) & 0x0000ff00) >> 8)
|
||||
#define PCI_CACHELINE_SIZE(i) ((swpl((i)) & 0x000000ff))
|
||||
#define PCI_BIST(i) (((i) & 0xff000000) >> 24)
|
||||
#define PCI_HEADER_TYPE(i) (((i) & 0x00ff0000) >> 16)
|
||||
#define PCI_LAT_TIMER(i) (((i) & 0x0000ff00) >> 8)
|
||||
#define PCI_CACHELINE_SIZE(i) (((i) & 0x000000ff))
|
||||
|
||||
/* register 0x2c macros */
|
||||
#define PCI_SUBSYS_ID(i) (((i) & 0xffff0000) >> 16)
|
||||
#define PCI_SUBSYS_VID(i) (((i) & 0xffff))
|
||||
#define PCI_SUBSYS_ID(i) ((i) & 0xffff0000) >> 16)
|
||||
#define PCI_SUBSYS_VID(i) ((i) & 0xffff))
|
||||
|
||||
/* register 0x34 macros */
|
||||
#define PCI_CAPABILITIES(i) ((i) & 0xff)
|
||||
@@ -222,6 +229,17 @@ typedef struct /* structure of address conversion */
|
||||
#define PCI_IOBAR_ADR(i) (((i) & 0xfffffffc))
|
||||
#define PCI_MEMBAR_ADR(i) (((i) & 0xfffffff0))
|
||||
|
||||
extern void init_eport(void);
|
||||
extern void init_xlbus_arbiter(void);
|
||||
extern void init_pci(void);
|
||||
extern int pci_handle2index(int32_t handle);
|
||||
|
||||
extern int32_t pci_find_device(uint16_t device_id, uint16_t vendor_id, int index);
|
||||
extern int32_t pci_find_classcode(uint32_t classcode, int index);
|
||||
|
||||
extern int32_t pci_get_interrupt_cause(void);
|
||||
extern int32_t pci_call_interrupt_chain(int32_t handle, int32_t data);
|
||||
|
||||
/*
|
||||
* match bits for pci_find_classcode()
|
||||
*/
|
||||
@@ -229,6 +247,104 @@ typedef struct /* structure of address conversion */
|
||||
#define PCI_FIND_SUB_CLASS (1 << 25)
|
||||
#define PCI_FIND_PROG_IF (1 << 24)
|
||||
|
||||
extern uint32_t pci_read_config_longword(int32_t handle, int offset);
|
||||
extern uint16_t pci_read_config_word(int32_t handle, int offset);
|
||||
extern uint8_t pci_read_config_byte(int32_t handle, int offset);
|
||||
|
||||
extern int32_t pci_write_config_longword(int32_t handle, int offset, uint32_t value);
|
||||
extern int32_t pci_write_config_word(int32_t handle, int offset, uint16_t value);
|
||||
extern int32_t pci_write_config_byte(int32_t handle, int offset, uint8_t value);
|
||||
|
||||
typedef int (*pci_interrupt_handler)(int param);
|
||||
|
||||
extern int32_t pci_hook_interrupt(int32_t handle, void *handler, void *parameter);
|
||||
extern int32_t pci_unhook_interrupt(int32_t handle);
|
||||
|
||||
extern struct pci_rd *pci_get_resource(int32_t handle);
|
||||
|
||||
/*
|
||||
* Not implemented PCI_BIOS functions
|
||||
*/
|
||||
extern uint8_t pci_fast_read_config_byte(int32_t handle, uint16_t reg);
|
||||
extern uint16_t pci_fast_read_config_word(int32_t handle, uint16_t reg);
|
||||
extern uint32_t pci_fast_read_config_longword(int32_t handle, uint16_t reg);
|
||||
extern int32_t pci_special_cycle(uint16_t bus, uint32_t data);
|
||||
extern int32_t pci_get_routing(int32_t handle);
|
||||
extern int32_t pci_set_interrupt(int32_t handle);
|
||||
extern int32_t pci_get_card_used(int32_t handle, uint32_t *address);
|
||||
extern int32_t pci_set_card_used(int32_t handle, uint32_t *callback);
|
||||
extern int32_t pci_read_mem_byte(int32_t handle, uint32_t offset, uint8_t *address);
|
||||
extern int32_t pci_read_mem_word(int32_t handle, uint32_t offset, uint16_t *address);
|
||||
extern int32_t pci_read_mem_longword(int32_t handle, uint32_t offset, uint32_t *address);
|
||||
extern uint8_t pci_fast_read_mem_byte(int32_t handle, uint32_t offset);
|
||||
extern uint16_t pci_fast_read_mem_word(int32_t handle, uint32_t offset);
|
||||
extern uint32_t pci_fast_read_mem_longword(int32_t handle, uint32_t offset);
|
||||
extern int32_t pci_write_mem_byte(int32_t handle, uint32_t offset, uint16_t val);
|
||||
extern int32_t pci_write_mem_word(int32_t handle, uint32_t offset, uint16_t val);
|
||||
extern int32_t pci_write_mem_longword(int32_t handle, uint32_t offset, uint32_t val);
|
||||
extern int32_t pci_read_io_byte(int32_t handle, uint32_t offset, uint8_t *address);
|
||||
extern int32_t pci_read_io_word(int32_t handle, uint32_t offset, uint16_t *address);
|
||||
extern int32_t pci_read_io_longword(int32_t handle, uint32_t offset, uint32_t *address);
|
||||
extern uint8_t pci_fast_read_io_byte(int32_t handle, uint32_t offset);
|
||||
extern uint16_t pci_fast_read_io_word(int32_t handle, uint32_t offset);
|
||||
extern uint32_t pci_fast_read_io_longword(int32_t handle, uint32_t offset);
|
||||
extern int32_t pci_write_io_byte(int32_t handle, uint32_t offset, uint16_t val);
|
||||
extern int32_t pci_write_io_word(int32_t handle, uint32_t offset, uint16_t val);
|
||||
extern int32_t pci_write_io_longword(int32_t handle, uint32_t offset, uint32_t val);
|
||||
extern int32_t pci_get_machine_id(void);
|
||||
extern int32_t pci_get_pagesize(void);
|
||||
extern int32_t pci_virt_to_bus(int32_t handle, uint32_t address, PCI_CONV_ADR *pointer);
|
||||
extern int32_t pci_bus_to_virt(int32_t handle, uint32_t address, PCI_CONV_ADR *pointer);
|
||||
extern int32_t pci_virt_to_phys(uint32_t address, PCI_CONV_ADR *pointer);
|
||||
extern int32_t pci_phys_to_virt(uint32_t address, PCI_CONV_ADR *pointer);
|
||||
|
||||
/*
|
||||
* prototypes for PCI wrapper routines
|
||||
*/
|
||||
extern int32_t wrapper_find_pci_device(uint32_t id, uint16_t index);
|
||||
extern int32_t wrapper_find_pci_classcode(uint32_t class, uint16_t index);
|
||||
extern int32_t wrapper_read_config_byte(int32_t handle, uint16_t reg, uint8_t *address);
|
||||
extern int32_t wrapper_read_config_word(int32_t handle, uint16_t reg, uint16_t *address);
|
||||
extern int32_t wrapper_read_config_longword(int32_t handle, uint16_t reg, uint32_t *address);
|
||||
extern uint8_t wrapper_fast_read_config_byte(int32_t handle, uint16_t reg);
|
||||
extern uint16_t wrapper_fast_read_config_word(int32_t handle, uint16_t reg);
|
||||
extern uint32_t wrapper_fast_read_config_longword(int32_t handle, uint16_t reg);
|
||||
extern int32_t wrapper_write_config_byte(int32_t handle, uint16_t reg, uint16_t val);
|
||||
extern int32_t wrapper_write_config_word(int32_t handle, uint16_t reg, uint16_t val);
|
||||
extern int32_t wrapper_write_config_longword(int32_t handle, uint16_t reg, uint32_t val);
|
||||
extern int32_t wrapper_hook_interrupt(int32_t handle, uint32_t *routine, uint32_t *parameter);
|
||||
extern int32_t wrapper_unhook_interrupt(int32_t handle);
|
||||
extern int32_t wrapper_special_cycle(uint16_t bus, uint32_t data);
|
||||
extern int32_t wrapper_get_routing(int32_t handle);
|
||||
extern int32_t wrapper_set_interrupt(int32_t handle);
|
||||
extern int32_t wrapper_get_resource(int32_t handle);
|
||||
extern int32_t wrapper_get_card_used(int32_t handle, uint32_t *address);
|
||||
extern int32_t wrapper_set_card_used(int32_t handle, uint32_t *callback);
|
||||
extern int32_t wrapper_read_mem_byte(int32_t handle, uint32_t offset, uint8_t *address);
|
||||
extern int32_t wrapper_read_mem_word(int32_t handle, uint32_t offset, uint16_t *address);
|
||||
extern int32_t wrapper_read_mem_longword(int32_t handle, uint32_t offset, uint32_t *address);
|
||||
extern uint8_t wrapper_fast_read_mem_byte(int32_t handle, uint32_t offset);
|
||||
extern uint16_t wrapper_fast_read_mem_word(int32_t handle, uint32_t offset);
|
||||
extern uint32_t wrapper_fast_read_mem_longword(int32_t handle, uint32_t offset);
|
||||
extern int32_t wrapper_write_mem_byte(int32_t handle, uint32_t offset, uint16_t val);
|
||||
extern int32_t wrapper_write_mem_word(int32_t handle, uint32_t offset, uint16_t val);
|
||||
extern int32_t wrapper_write_mem_longword(int32_t handle, uint32_t offset, uint32_t val);
|
||||
extern int32_t wrapper_read_io_byte(int32_t handle, uint32_t offset, uint8_t *address);
|
||||
extern int32_t wrapper_read_io_word(int32_t handle, uint32_t offset, uint16_t *address);
|
||||
extern int32_t wrapper_read_io_longword(int32_t handle, uint32_t offset, uint32_t *address);
|
||||
extern uint8_t wrapper_fast_read_io_byte(int32_t handle, uint32_t offset);
|
||||
extern uint16_t wrapper_fast_read_io_word(int32_t handle, uint32_t offset);
|
||||
extern uint32_t wrapper_fast_read_io_longword(int32_t handle, uint32_t offset);
|
||||
extern int32_t wrapper_write_io_byte(int32_t handle, uint32_t offset, uint16_t val);
|
||||
extern int32_t wrapper_write_io_word(int32_t handle, uint32_t offset, uint16_t val);
|
||||
extern int32_t wrapper_write_io_longword(int32_t handle, uint32_t offset, uint32_t val);
|
||||
extern int32_t wrapper_get_machine_id(void);
|
||||
extern int32_t wrapper_get_pagesize(void);
|
||||
extern int32_t wrapper_virt_to_bus(int32_t handle, uint32_t address, PCI_CONV_ADR *pointer);
|
||||
extern int32_t wrapper_bus_to_virt(int32_t handle, uint32_t address, PCI_CONV_ADR *pointer);
|
||||
extern int32_t wrapper_virt_to_phys(uint32_t address, PCI_CONV_ADR *pointer);
|
||||
extern int32_t wrapper_phys_to_virt(uint32_t address, PCI_CONV_ADR *pointer);
|
||||
|
||||
#define PCI_MK_CONF_ADDR(bus, device, function) (MCF_PCI_PCICAR_E | \
|
||||
((bus) << 16) | \
|
||||
((device << 8) | \
|
||||
@@ -239,4 +355,6 @@ typedef struct /* structure of address conversion */
|
||||
#define PCI_DEVICE_FROM_HANDLE(h) (((h) & 0xf8) >> 3)
|
||||
#define PCI_FUNCTION_FROM_HANDLE(h) (((h) & 0x7))
|
||||
|
||||
extern void pci_dump_registers(int32_t handle);
|
||||
|
||||
#endif /* _PCI_H_ */
|
||||
|
||||
128
tos/pci_test/include/util.h
Normal file
128
tos/pci_test/include/util.h
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* util.h
|
||||
*
|
||||
* Byteswapping macros lend from EmuTOS sources
|
||||
*
|
||||
* This file is part of BaS_gcc.
|
||||
*
|
||||
* BaS_gcc is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* BaS_gcc is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with BaS_gcc. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Created on: 27.10.2013
|
||||
* Author: mfro
|
||||
*/
|
||||
|
||||
#ifndef UTIL_H_
|
||||
#define UTIL_H_
|
||||
|
||||
#include <bas_types.h>
|
||||
|
||||
#define NOP() __asm__ __volatile__("nop\n\t" : : : "memory")
|
||||
|
||||
/*
|
||||
* uint16_t swpw(uint16_t val);
|
||||
* swap endianess of val, 16 bits only.
|
||||
*/
|
||||
static inline uint16_t swpw(uint16_t w)
|
||||
{
|
||||
return (w << 8) | (w >> 8);
|
||||
}
|
||||
|
||||
/*
|
||||
* uint32_t swpl(uint32_t val);
|
||||
* swap endianess of val, 32 bits only.
|
||||
* e.g. ABCD => DCBA
|
||||
*/
|
||||
static inline uint32_t swpl(uint32_t l)
|
||||
{
|
||||
return ((l & 0xff000000) >> 24) | ((l & 0x00ff0000) >> 8) |
|
||||
((l & 0x0000ff00) << 8) | (l << 24);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* WORD swpw2(ULONG val);
|
||||
* swap endianness of val, treated as two 16-bit words.
|
||||
* e.g. ABCD => BADC
|
||||
*/
|
||||
|
||||
#define swpw2(a) \
|
||||
__extension__ \
|
||||
({unsigned long _tmp; \
|
||||
__asm__ __volatile__ \
|
||||
("move.b (%1),%0\n\t" \
|
||||
"move.b 1(%1),(%1)\n\t" \
|
||||
"move.b %0,1(%1)\n\t" \
|
||||
"move.b 2(%1),%0\n\t" \
|
||||
"move.b 3(%1),2(%1)\n\t" \
|
||||
"move.b %0,3(%1)" \
|
||||
: "=d"(_tmp) /* outputs */ \
|
||||
: "a"(&a) /* inputs */ \
|
||||
: "cc", "memory" /* clobbered */ \
|
||||
); \
|
||||
})
|
||||
|
||||
/*
|
||||
* WORD set_sr(WORD new);
|
||||
* sets sr to the new value, and return the old sr value
|
||||
*/
|
||||
|
||||
#define set_sr(a) \
|
||||
__extension__ \
|
||||
({short _r, _a = (a); \
|
||||
__asm__ __volatile__ \
|
||||
("move.w sr,%0\n\t" \
|
||||
"move.w %1,sr" \
|
||||
: "=&d"(_r) /* outputs */ \
|
||||
: "nd"(_a) /* inputs */ \
|
||||
: "cc", "memory" /* clobbered */ \
|
||||
); \
|
||||
_r; \
|
||||
})
|
||||
|
||||
|
||||
/*
|
||||
* WORD get_sr(void);
|
||||
* returns the current value of sr.
|
||||
*/
|
||||
|
||||
#define get_sr() \
|
||||
__extension__ \
|
||||
({short _r; \
|
||||
__asm__ volatile \
|
||||
("move.w sr,%0" \
|
||||
: "=dm"(_r) /* outputs */ \
|
||||
: /* inputs */ \
|
||||
: "cc", "memory" /* clobbered */ \
|
||||
); \
|
||||
_r; \
|
||||
})
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* void regsafe_call(void *addr)
|
||||
* Saves all registers to the stack, calls the function
|
||||
* that addr points to, and restores the registers afterwards.
|
||||
*/
|
||||
#define regsafe_call(addr) \
|
||||
__extension__ \
|
||||
({__asm__ volatile ("lea -60(sp),sp\n\t" \
|
||||
"movem.l d0-d7/a0-a6,(sp)"); \
|
||||
((void (*) (void)) addr)(); \
|
||||
__asm__ volatile ("movem.l (sp),d0-d7/a0-a6\n\t" \
|
||||
"lea 60(sp),sp"); \
|
||||
})
|
||||
|
||||
|
||||
#endif /* UTIL_H_ */
|
||||
@@ -1,456 +0,0 @@
|
||||
/*
|
||||
* tc.printf.c: A public-domain, minimal printf/sprintf routine that prints
|
||||
* through the putchar() routine. Feel free to use for
|
||||
* anything... -- 7/17/87 Paul Placeway
|
||||
*/
|
||||
/*-
|
||||
* Copyright (c) 1980, 1991 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include "MCF5475.h"
|
||||
#include "bas_printf.h"
|
||||
#include "bas_string.h"
|
||||
|
||||
/*
|
||||
* Lexical definitions.
|
||||
*
|
||||
* All lexical space is allocated dynamically.
|
||||
* The eighth/sixteenth bit of characters is used to prevent recognition,
|
||||
* and eventually stripped.
|
||||
*/
|
||||
#define META 0200
|
||||
#define ASCII 0177
|
||||
#define QUOTE ((char) 0200) /* Eighth char bit used for 'ing */
|
||||
#define TRIM 0177 /* Mask to strip quote bit */
|
||||
#define UNDER 0000000 /* No extra bits to do both */
|
||||
#define BOLD 0000000 /* Bold flag */
|
||||
#define STANDOUT META /* Standout flag */
|
||||
#define LITERAL 0000000 /* Literal character flag */
|
||||
#define ATTRIBUTES 0200 /* The bits used for attributes */
|
||||
#define CHAR 0000177 /* Mask to mask out the character */
|
||||
|
||||
#define INF 32766 /* should be bigger than any field to print */
|
||||
|
||||
static char snil[] = "(nil)";
|
||||
|
||||
void xputchar(int c)
|
||||
{
|
||||
__asm__ __volatile__
|
||||
(
|
||||
".extern printf_helper\n\t"
|
||||
"move.b %0,d0\n\t"
|
||||
"bsr printf_helper\n\t"
|
||||
/* output */:
|
||||
/* input */: "r" (c)
|
||||
/* clobber */: "d0","d2","a0","memory"
|
||||
);
|
||||
}
|
||||
|
||||
static void doprnt(void (*addchar)(int), const char *sfmt, va_list ap)
|
||||
{
|
||||
char buf[128];
|
||||
char *bp;
|
||||
const char *f;
|
||||
float flt;
|
||||
long l;
|
||||
unsigned long u;
|
||||
int i;
|
||||
int fmt;
|
||||
unsigned char pad = ' ';
|
||||
int flush_left = 0;
|
||||
int f_width = 0;
|
||||
int prec = INF;
|
||||
int hash = 0;
|
||||
int do_long = 0;
|
||||
int sign = 0;
|
||||
int attributes = 0;
|
||||
|
||||
f = sfmt;
|
||||
for (; *f; f++)
|
||||
{
|
||||
if (*f != '%')
|
||||
{
|
||||
/* then just out the char */
|
||||
(*addchar)((int) (((unsigned char) *f) | attributes));
|
||||
}
|
||||
else
|
||||
{
|
||||
f++; /* skip the % */
|
||||
|
||||
if (*f == '-')
|
||||
{ /* minus: flush left */
|
||||
flush_left = 1;
|
||||
f++;
|
||||
}
|
||||
|
||||
if (*f == '0' || *f == '.')
|
||||
{
|
||||
/* padding with 0 rather than blank */
|
||||
pad = '0';
|
||||
f++;
|
||||
}
|
||||
if (*f == '*')
|
||||
{
|
||||
/* field width */
|
||||
f_width = va_arg(ap, int);
|
||||
f++;
|
||||
}
|
||||
else if (isdigit((unsigned char)*f))
|
||||
{
|
||||
f_width = atoi(f);
|
||||
while (isdigit((unsigned char)*f))
|
||||
f++; /* skip the digits */
|
||||
}
|
||||
|
||||
if (*f == '.')
|
||||
{ /* precision */
|
||||
f++;
|
||||
if (*f == '*')
|
||||
{
|
||||
prec = va_arg(ap, int);
|
||||
f++;
|
||||
}
|
||||
else if (isdigit((unsigned char)*f))
|
||||
{
|
||||
prec = atoi(f);
|
||||
while (isdigit((unsigned char)*f))
|
||||
f++; /* skip the digits */
|
||||
}
|
||||
}
|
||||
|
||||
if (*f == '#')
|
||||
{ /* alternate form */
|
||||
hash = 1;
|
||||
f++;
|
||||
}
|
||||
|
||||
if (*f == 'l')
|
||||
{ /* long format */
|
||||
do_long++;
|
||||
f++;
|
||||
if (*f == 'l')
|
||||
{
|
||||
do_long++;
|
||||
f++;
|
||||
}
|
||||
}
|
||||
|
||||
fmt = (unsigned char) *f;
|
||||
if (fmt != 'S' && fmt != 'Q' && isupper(fmt))
|
||||
{
|
||||
do_long = 1;
|
||||
fmt = tolower(fmt);
|
||||
}
|
||||
bp = buf;
|
||||
switch (fmt)
|
||||
{ /* do the format */
|
||||
case 'd':
|
||||
switch (do_long)
|
||||
{
|
||||
case 0:
|
||||
l = (long) (va_arg(ap, int));
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
l = va_arg(ap, long);
|
||||
break;
|
||||
}
|
||||
|
||||
if (l < 0)
|
||||
{
|
||||
sign = 1;
|
||||
l = -l;
|
||||
}
|
||||
do
|
||||
{
|
||||
*bp++ = (char) (l % 10) + '0';
|
||||
} while ((l /= 10) > 0);
|
||||
if (sign)
|
||||
*bp++ = '-';
|
||||
f_width = f_width - (int) (bp - buf);
|
||||
if (!flush_left)
|
||||
while (f_width-- > 0)
|
||||
(*addchar)((int) (pad | attributes));
|
||||
for (bp--; bp >= buf; bp--)
|
||||
(*addchar)((int) (((unsigned char) *bp) | attributes));
|
||||
if (flush_left)
|
||||
while (f_width-- > 0)
|
||||
(*addchar)((int) (' ' | attributes));
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
/* this is actually more than stupid, but does work for now */
|
||||
flt = (float) (va_arg(ap, double)); /* beware: va_arg() extends float to double! */
|
||||
if (flt < 0)
|
||||
{
|
||||
sign = 1;
|
||||
flt = -flt;
|
||||
}
|
||||
{
|
||||
int quotient, remainder;
|
||||
|
||||
quotient = (int) flt;
|
||||
remainder = (flt - quotient) * 10E5;
|
||||
|
||||
for (i = 0; i < 6; i++)
|
||||
{
|
||||
*bp++ = (char) (remainder % 10) + '0';
|
||||
remainder /= 10;
|
||||
}
|
||||
*bp++ = '.';
|
||||
do
|
||||
{
|
||||
*bp++ = (char) (quotient % 10) + '0';
|
||||
} while ((quotient /= 10) > 0);
|
||||
if (sign)
|
||||
*bp++ = '-';
|
||||
f_width = f_width - (int) (bp - buf);
|
||||
if (!flush_left)
|
||||
while (f_width-- > 0)
|
||||
(*addchar)((int) (pad | attributes));
|
||||
for (bp--; bp >= buf; bp--)
|
||||
(*addchar)((int) (((unsigned char) *bp) | attributes));
|
||||
if (flush_left)
|
||||
while (f_width-- > 0)
|
||||
(*addchar)((int) (' ' | attributes));
|
||||
}
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
do_long = 1;
|
||||
hash = 1;
|
||||
fmt = 'x';
|
||||
/* no break */
|
||||
case 'o':
|
||||
case 'x':
|
||||
case 'u':
|
||||
switch (do_long)
|
||||
{
|
||||
case 0:
|
||||
u = (unsigned long) (va_arg(ap, unsigned int));
|
||||
break;
|
||||
case 1:
|
||||
default:
|
||||
u = va_arg(ap, unsigned long);
|
||||
break;
|
||||
}
|
||||
if (fmt == 'u')
|
||||
{ /* unsigned decimal */
|
||||
do
|
||||
{
|
||||
*bp++ = (char) (u % 10) + '0';
|
||||
} while ((u /= 10) > 0);
|
||||
}
|
||||
else if (fmt == 'o')
|
||||
{ /* octal */
|
||||
do
|
||||
{
|
||||
*bp++ = (char) (u % 8) + '0';
|
||||
} while ((u /= 8) > 0);
|
||||
if (hash)
|
||||
*bp++ = '0';
|
||||
}
|
||||
else if (fmt == 'x')
|
||||
{ /* hex */
|
||||
do
|
||||
{
|
||||
i = (int) (u % 16);
|
||||
if (i < 10)
|
||||
*bp++ = i + '0';
|
||||
else
|
||||
*bp++ = i - 10 + 'a';
|
||||
} while ((u /= 16) > 0);
|
||||
if (hash)
|
||||
{
|
||||
*bp++ = 'x';
|
||||
*bp++ = '0';
|
||||
}
|
||||
}
|
||||
i = f_width - (int) (bp - buf);
|
||||
if (!flush_left)
|
||||
while (i-- > 0)
|
||||
(*addchar)((int) (pad | attributes));
|
||||
for (bp--; bp >= buf; bp--)
|
||||
(*addchar)((int) (((unsigned char) *bp) | attributes));
|
||||
if (flush_left)
|
||||
while (i-- > 0)
|
||||
(*addchar)((int) (' ' | attributes));
|
||||
break;
|
||||
|
||||
case 'c':
|
||||
i = va_arg(ap, int);
|
||||
(*addchar)((int) (i | attributes));
|
||||
break;
|
||||
|
||||
case 'S':
|
||||
case 'Q':
|
||||
case 's':
|
||||
case 'q':
|
||||
bp = va_arg(ap, char *);
|
||||
if (!bp)
|
||||
bp = snil;
|
||||
f_width = f_width - strlen((char *) bp);
|
||||
if (!flush_left)
|
||||
while (f_width-- > 0)
|
||||
(*addchar)((int) (pad | attributes));
|
||||
for (i = 0; *bp && i < prec; i++)
|
||||
{
|
||||
if (fmt == 'q' && (*bp & QUOTE))
|
||||
(*addchar)((int) ('\\' | attributes));
|
||||
(*addchar)(
|
||||
(int) (((unsigned char) *bp & TRIM) | attributes));
|
||||
bp++;
|
||||
}
|
||||
if (flush_left)
|
||||
while (f_width-- > 0)
|
||||
(*addchar)((int) (' ' | attributes));
|
||||
break;
|
||||
|
||||
case 'a':
|
||||
attributes = va_arg(ap, int);
|
||||
break;
|
||||
|
||||
case '%':
|
||||
(*addchar)((int) ('%' | attributes));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
flush_left = 0, f_width = 0, prec = INF, hash = 0, do_long = 0;
|
||||
sign = 0;
|
||||
pad = ' ';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static char *xstring, *xestring;
|
||||
|
||||
void xaddchar(int c)
|
||||
{
|
||||
if (xestring == xstring)
|
||||
*xstring = '\0';
|
||||
else
|
||||
*xstring++ = (char) c;
|
||||
}
|
||||
|
||||
int sprintf(char *str, const char *format, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, format);
|
||||
|
||||
xstring = str;
|
||||
|
||||
doprnt(xaddchar, format, va);
|
||||
va_end(va);
|
||||
*xstring++ = '\0';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void xsnprintf(char *str, size_t size, const char *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
|
||||
xstring = str;
|
||||
xestring = str + size - 1;
|
||||
doprnt(xaddchar, fmt, va);
|
||||
va_end(va);
|
||||
*xstring++ = '\0';
|
||||
}
|
||||
|
||||
void xprintf(const char *fmt, ...)
|
||||
{
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
doprnt(xputchar, fmt, va);
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
void xvprintf(const char *fmt, va_list va)
|
||||
{
|
||||
doprnt(xputchar, fmt, va);
|
||||
}
|
||||
|
||||
void xvsnprintf(char *str, size_t size, const char *fmt, va_list va)
|
||||
{
|
||||
xstring = str;
|
||||
xestring = str + size - 1;
|
||||
doprnt(xaddchar, fmt, va);
|
||||
*xstring++ = '\0';
|
||||
}
|
||||
|
||||
|
||||
void display_progress()
|
||||
{
|
||||
static int _progress_index;
|
||||
char progress_char[] = "|/-\\";
|
||||
|
||||
xputchar(progress_char[_progress_index++ % strlen(progress_char)]);
|
||||
xputchar('\r');
|
||||
}
|
||||
|
||||
void hexdump(uint8_t buffer[], int size)
|
||||
{
|
||||
int i;
|
||||
int line = 0;
|
||||
uint8_t *bp = buffer;
|
||||
|
||||
while (bp < buffer + size) {
|
||||
uint8_t *lbp = bp;
|
||||
|
||||
xprintf("%08x ", line);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (bp + i > buffer + size) {
|
||||
break;
|
||||
}
|
||||
xprintf("%02x ", (uint8_t) *lbp++);
|
||||
}
|
||||
|
||||
lbp = bp;
|
||||
for (i = 0; i < 16; i++) {
|
||||
int8_t c = *lbp++;
|
||||
|
||||
if (bp + i > buffer + size) {
|
||||
break;
|
||||
}
|
||||
if (c > ' ' && c < '~') {
|
||||
xprintf("%c", c);
|
||||
} else {
|
||||
xprintf(".");
|
||||
}
|
||||
}
|
||||
xprintf("\r\n");
|
||||
|
||||
bp += 16;
|
||||
line += 16;
|
||||
}
|
||||
}
|
||||
@@ -1,156 +0,0 @@
|
||||
/*
|
||||
* bas_string.c
|
||||
*
|
||||
* This file is part of BaS_gcc.
|
||||
*
|
||||
* BaS_gcc is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* BaS_gcc is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with BaS_gcc. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Created on: 26.02.2013
|
||||
* Author: Markus Fröschle
|
||||
*/
|
||||
|
||||
#include "bas_types.h"
|
||||
#include <stdint.h>
|
||||
#include "bas_string.h"
|
||||
|
||||
void *memcpy(void *dst, const void *src, size_t n)
|
||||
{
|
||||
uint8_t *to = dst;
|
||||
|
||||
while (to < (uint8_t *) dst + n)
|
||||
*to++ = * (uint8_t *) src++;
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
void bzero(void *s, size_t n)
|
||||
{
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
((unsigned char *) s)[i] = '\0';
|
||||
}
|
||||
|
||||
void *memset(void *s, int c, size_t n)
|
||||
{
|
||||
uint8_t *dst = s;
|
||||
|
||||
do
|
||||
{
|
||||
*dst++ = c;
|
||||
} while ((dst - (uint8_t *) s) < n);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
int memcmp(const void *s1, const void *s2, size_t max)
|
||||
{
|
||||
int i;
|
||||
int cmp;
|
||||
|
||||
for (i = 0; i < max; i++)
|
||||
{
|
||||
cmp = (* (const char *) s1 - * (const char *) s2);
|
||||
if (cmp != 0) return cmp;
|
||||
}
|
||||
return cmp;
|
||||
}
|
||||
|
||||
int strcmp(const char *s1, const char *s2)
|
||||
{
|
||||
int i;
|
||||
int cmp;
|
||||
|
||||
for (i = 0; *s1++ && *s2++; i++)
|
||||
{
|
||||
cmp = (*s1 - *s2);
|
||||
if (cmp != 0) return cmp;
|
||||
}
|
||||
return cmp;
|
||||
}
|
||||
|
||||
int strncmp(const char *s1, const char *s2, size_t max)
|
||||
{
|
||||
int i;
|
||||
int cmp;
|
||||
|
||||
for (i = 0; i < max && *s1++ && *s2++; i++);
|
||||
{
|
||||
cmp = (*s1 - *s2);
|
||||
if (cmp != 0) return cmp;
|
||||
}
|
||||
return cmp;
|
||||
}
|
||||
|
||||
char *strcpy(char *dst, const char *src)
|
||||
{
|
||||
char *ptr = dst;
|
||||
|
||||
while ((*dst++ = *src++) != '\0');
|
||||
return ptr;
|
||||
}
|
||||
|
||||
char *strncpy(char *dst, const char *src, size_t max)
|
||||
{
|
||||
char *ptr = dst;
|
||||
|
||||
while ((*dst++ = *src++) != '\0' && max-- >= 0);
|
||||
return ptr;
|
||||
}
|
||||
|
||||
int atoi(const char *c)
|
||||
{
|
||||
int value = 0;
|
||||
while (isdigit(*c))
|
||||
{
|
||||
value *= 10;
|
||||
value += (int) (*c - '0');
|
||||
c++;
|
||||
}
|
||||
return value;
|
||||
}
|
||||
|
||||
size_t strlen(const char *s)
|
||||
{
|
||||
const char *start = s;
|
||||
|
||||
while (*s++);
|
||||
|
||||
return s - start - 1;
|
||||
}
|
||||
|
||||
|
||||
char *strcat(char *dst, const char *src)
|
||||
{
|
||||
char *ret = dst;
|
||||
dst = &dst[strlen(dst)];
|
||||
while ((*dst++ = *src++) != '\0');
|
||||
return ret;
|
||||
}
|
||||
|
||||
char *strncat(char *dst, const char *src, size_t max)
|
||||
{
|
||||
size_t i;
|
||||
char *ret = dst;
|
||||
|
||||
dst = &dst[strlen(dst)];
|
||||
for (i = 0; i < max && *src; i++)
|
||||
{
|
||||
*dst++ = *src++;
|
||||
}
|
||||
*dst++ = '\0';
|
||||
|
||||
return ret;
|
||||
}
|
||||
@@ -1,9 +1,9 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <mint/osbind.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "bas_printf.h"
|
||||
#include "MCF5475.h"
|
||||
#include "driver_vec.h"
|
||||
#include "pci.h"
|
||||
@@ -15,17 +15,97 @@
|
||||
volatile int32_t time, start, end;
|
||||
int i;
|
||||
|
||||
#define swpw(a) ((a) >> 8 | (a) << 8)
|
||||
/*
|
||||
* PCI device class descriptions displayed during PCI bus scan
|
||||
*/
|
||||
static struct pci_class
|
||||
{
|
||||
int classcode;
|
||||
char *description;
|
||||
} pci_classes[] =
|
||||
{
|
||||
{ 0x00, "device was built prior definition of the class code field" },
|
||||
{ 0x01, "Mass Storage Controller" },
|
||||
{ 0x02, "Network Controller" },
|
||||
{ 0x03, "Display Controller" },
|
||||
{ 0x04, "Multimedia Controller" },
|
||||
{ 0x05, "Memory Controller" },
|
||||
{ 0x06, "Bridge Device" },
|
||||
{ 0x07, "Simple Communication Controller" },
|
||||
{ 0x08, "Base System Peripherial" },
|
||||
{ 0x09, "Input Device" },
|
||||
{ 0x0a, "Docking Station" },
|
||||
{ 0x0b, "Processor" },
|
||||
{ 0x0c, "Serial Bus Controller" },
|
||||
{ 0x0d, "Wireless Controller" },
|
||||
{ 0x0e, "Intelligent I/O Controller" },
|
||||
{ 0x0f, "Satellite Communication Controller" },
|
||||
{ 0x10, "Encryption/Decryption Controller" },
|
||||
{ 0x11, "Data Acquisition and Signal Processing Controller" },
|
||||
{ 0xff, "Device does not fit any defined class" },
|
||||
};
|
||||
static int num_pci_classes = sizeof(pci_classes) / sizeof(struct pci_class);
|
||||
|
||||
/*
|
||||
* retrieve device class (in cleartext) for a PCI classcode
|
||||
*/
|
||||
static char *device_class(int classcode)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < num_pci_classes; i++)
|
||||
{
|
||||
if (pci_classes[i].classcode == classcode)
|
||||
{
|
||||
return pci_classes[i].description;
|
||||
}
|
||||
}
|
||||
return "unknown device class";
|
||||
}
|
||||
|
||||
void hexdump(uint8_t buffer[], int size)
|
||||
{
|
||||
int i;
|
||||
int line = 0;
|
||||
uint8_t *bp = buffer;
|
||||
|
||||
while (bp < buffer + size) {
|
||||
uint8_t *lbp = bp;
|
||||
|
||||
printf("%08lx ", (uintptr_t) buffer + line);
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (bp + i > buffer + size) {
|
||||
break;
|
||||
}
|
||||
printf("%02x ", (uint8_t) *lbp++);
|
||||
}
|
||||
|
||||
lbp = bp;
|
||||
for (i = 0; i < 16; i++) {
|
||||
int8_t c = *lbp++;
|
||||
|
||||
if (bp + i > buffer + size) {
|
||||
break;
|
||||
}
|
||||
if (c > ' ' && c < '~') {
|
||||
printf("%c", c);
|
||||
} else {
|
||||
printf(".");
|
||||
}
|
||||
}
|
||||
printf("\r\n");
|
||||
|
||||
bp += 16;
|
||||
line += 16;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
time = (start - end) / (SYSCLK / 1000) / 1000;
|
||||
|
||||
printf("enumerate PCI devices\r\n");
|
||||
|
||||
@@ -42,20 +122,69 @@ void do_tests(struct pci_native_driver_interface *pci)
|
||||
{
|
||||
uint32_t value;
|
||||
|
||||
value = (*pci->pci_read_config_longword)(handle, PCIIDR);
|
||||
value = swpl((*pci->pci_read_config_longword)(handle, PCIIDR));
|
||||
|
||||
printf(" %02x | %02x | %02x |%04x|%04x|%04x| (0x%02x)\r\n",
|
||||
(char) PCI_BUS_FROM_HANDLE(handle),
|
||||
(char) PCI_DEVICE_FROM_HANDLE(handle),
|
||||
(char) PCI_FUNCTION_FROM_HANDLE(handle),
|
||||
(short) PCI_VENDOR_ID(value), (short) PCI_DEVICE_ID(value),
|
||||
(unsigned char) handle,
|
||||
(char) (*pci->pci_read_config_byte)(handle, PCICCR));
|
||||
printf(" %02x | %02x | %02x |%04x|%04x|%04x| %s (0x%02x, 0x%04x)\r\n",
|
||||
PCI_BUS_FROM_HANDLE(handle),
|
||||
PCI_DEVICE_FROM_HANDLE(handle),
|
||||
PCI_FUNCTION_FROM_HANDLE(handle),
|
||||
PCI_VENDOR_ID(value), PCI_DEVICE_ID(value),
|
||||
handle,
|
||||
device_class((*pci->pci_read_config_byte)(handle, PCI_LANESWAP_B(PCICCR))),
|
||||
(*pci->pci_read_config_byte)(handle, PCI_LANESWAP_B(PCICCR)),
|
||||
(*pci->pci_read_config_word)(handle, PCI_LANESWAP_W(PCICCR)));
|
||||
|
||||
handle = (*pci->pci_find_device)(0x0, 0xFFFF, ++index);
|
||||
}
|
||||
|
||||
struct pci_rd *rd;
|
||||
int flags;
|
||||
|
||||
handle = 0xa0;
|
||||
|
||||
rd = (*pci->pci_get_resource)(handle); /* get resource descriptor for ATI graphics card */
|
||||
if (rd != NULL)
|
||||
{
|
||||
do
|
||||
{
|
||||
flags = rd->flags;
|
||||
|
||||
printf("Start address: 0x%08lx\r\n", rd->start);
|
||||
printf("Length: 0x%08lx\r\n", rd->length);
|
||||
printf("Offset: 0x%08lx\r\n", rd->offset);
|
||||
printf("DMA offset: 0x%08lx\r\n", rd->dmaoffset);
|
||||
printf("FLAGS: %s%s%s%s%s%s%s\r\n",
|
||||
flags & FLG_IO ? "FLG_IO, " : "",
|
||||
flags & FLG_ROM ? "FLG_ROM, " : "",
|
||||
flags & FLG_8BIT ? "FLG_8BIT, " : "",
|
||||
flags & FLG_16BIT ? "FLG_16BIT, " : "",
|
||||
flags & FLG_32BIT ? "FLG_32BIT, " : "",
|
||||
(flags & FLG_ENDMASK) == ORD_MOTOROLA ? "ORD_MOTOROLA" :
|
||||
(flags & FLG_ENDMASK) == ORD_INTEL_AS ? "ORD_INTEL_AS" :
|
||||
(flags & FLG_ENDMASK) == ORD_INTEL_LS ? "ORD_INTEL_LS" :
|
||||
(flags & FLG_ENDMASK) == ORD_UNKNOWN ? "ORD_UNKNOWN" :
|
||||
"", "");
|
||||
printf("\r\n");
|
||||
|
||||
if (rd->start != 0L)
|
||||
{
|
||||
hexdump((uint8_t *) rd->start + rd->offset, 128);
|
||||
|
||||
memset((uint8_t *) rd-> start + rd->offset, 0, 128);
|
||||
|
||||
printf("memory cleared\r\n");
|
||||
hexdump((uint8_t *) rd->start + rd->offset, 128);
|
||||
}
|
||||
|
||||
rd = (struct pci_rd *) (((uintptr_t) rd) + (uintptr_t) rd->next);
|
||||
} while (!(flags & FLG_LAST));
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("resource descriptor for handle 0x%02x not found\r\n", handle);
|
||||
}
|
||||
|
||||
printf("\r\n...finished\r\n");
|
||||
printf("finished (took %f seconds).\r\n", time / 1000.0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user