From ab7371532f4fc6026f1f7c05e2fa65abfb95f592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Fr=C3=B6schle?= Date: Sun, 5 Oct 2014 17:50:15 +0000 Subject: [PATCH] implemented hook_interrupt() in PCI code enabled PCI interrupts ohci seems to damage something in PCI config -> PCI device enumeration does not top with latest device networking in EmuTOS lost (probably a result of PCI interrupt implementation) --- .gdbinit | 2 +- dma/dma.c | 2 +- flash_scripts/flash_m548x_etos.bdm | 2 +- include/interrupts.h | 31 +- include/mmu.h | 10 +- include/ohci.h | 322 +++--- include/pci.h | 38 +- include/pci_ids.h | 20 +- include/wait.h | 2 + net/fec.c | 1704 ++++++++++++++-------------- pci/ehci-hcd.c | 10 + pci/ohci-hcd.c | 156 ++- pci/pci.c | 256 +++-- sys/BaS.c | 462 ++++---- sys/exceptions.S | 67 +- sys/interrupts.c | 123 +- sys/mmu.c | 159 ++- sys/sysinit.c | 19 +- usb/usb.c | 7 +- usb/usb_mouse.c | 2 + util/wait.c | 25 +- 21 files changed, 1842 insertions(+), 1577 deletions(-) diff --git a/.gdbinit b/.gdbinit index 408bc03..cd00d0a 100644 --- a/.gdbinit +++ b/.gdbinit @@ -3,7 +3,7 @@ define tr #!killall m68k-bdm-gdbserver target remote | m68k-bdm-gdbserver pipe /dev/bdmcf3 #target remote localhost:1234 - #target remote | m68k-bdm-gdbserver pipe /dev/tblcf3 + #target remote | m68k-bdm-gdbserver pipe /dev/tblcf1 #target dbug /dev/ttyS0 #monitor bdm-reset end diff --git a/dma/dma.c b/dma/dma.c index 45447dd..14d1e62 100644 --- a/dma/dma.c +++ b/dma/dma.c @@ -39,7 +39,7 @@ #error "unknown machine!" #endif /* MACHINE_FIREBEE */ -//#define DBG_DMA +#define DBG_DMA #ifdef DBG_DMA #define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0) #else diff --git a/flash_scripts/flash_m548x_etos.bdm b/flash_scripts/flash_m548x_etos.bdm index e0333bd..6f1cbb3 100755 --- a/flash_scripts/flash_m548x_etos.bdm +++ b/flash_scripts/flash_m548x_etos.bdm @@ -63,4 +63,4 @@ erase 0xe0000000 37 erase 0xe0000000 38 erase 0xe0000000 39 -load ../../emutos/emutos-m548x_bas.elf +load ../../emutos/emutos-m548x-bas_gcc.elf diff --git a/include/interrupts.h b/include/interrupts.h index 95f2f99..7411648 100644 --- a/include/interrupts.h +++ b/include/interrupts.h @@ -95,14 +95,41 @@ #define FEC1TX_DMA_PRI 4 #define FECTX_DMA_PRI(x) ((x == 0) ? FEC0TX_DMA_PRI : FEC1TX_DMA_PRI) -extern int register_interrupt_handler(uint8_t source, uint8_t level, uint8_t priority, uint8_t intr, void (*handler)(void)); - #define ISR_DBUG_ISR 0x01 #define ISR_USER_ISR 0x02 +#if defined(MACHINE_FIREBEE) +/* Firebee FPGA interrupt controller */ +#define FPGA_INTR_CONTROL ((volatile uint32_t *) 0xf0010000) +#define FPGA_INTR_ENABLE ((volatile uint32_t *) 0xf0010004) +#define FPGA_INTR_CLEAR ((volatile uint32_t *) 0xf0010008) +#define FPGA_INTR_PENDING ((volatile uint32_t *) 0xff01000c) + +/* register bits for Firebee FPGA-based interrupt controller */ +#define FPGA_INTR_PIC (1) +#define FPGA_INTR_ETHERNET (1 << 1) +#define FPGA_INTR_DVI (1 << 2) +#define FPGA_INTR_PCI_INTA (1 << 3) +#define FPGA_INTR_PCI_INTB (1 << 4) +#define FPGA_INTR_PCI_INTC (1 << 5) +#define FPGA_INTR_PCI_INTD (1 << 6) +#define FPGA_INTR_INT_DSP (1 << 7) +#define FPGA_INTR_INT_VSYNC (1 << 8) +#define FPGA_INTR_INT_HSYNC (1 << 9) +#define FPGA_INTR_INT_HSYNC_IRQ2 (1 << 26) +#define FPGA_INTR_INT_CTR0_IRQ3 (1 << 27) +#define FPGA_INTR_INT_VSYNC_IRQ4 (1 << 28) +#define FPGA_INTR_INT_FPGA_IRQ5 (1 << 29) +#define FPGA_INTR_INT_MFP_IRQ6 (1 << 30) +#define FPGA_INTR_INT_IRQ7 (1 << 31) + +#endif /* MACHINE_FIREBEE */ + extern void isr_init(void); extern int isr_register_handler(int vector, int (*handler)(void *, void *), void *hdev, void *harg); extern void isr_remove_handler(int (*handler)(void *, void *)); extern bool isr_execute_handler(int vector); extern int pic_interrupt_handler(void *arg1, void *arg2); +extern int xlbpci_interrupt_handler(void *arg1, void *arg2); +extern int pciarb_interrupt_handler(void *arg1, void *arg2); #endif /* _INTERRUPTS_H_ */ diff --git a/include/mmu.h b/include/mmu.h index f2c5c04..63b62f8 100644 --- a/include/mmu.h +++ b/include/mmu.h @@ -58,10 +58,10 @@ enum mmu_page_size { - MMU_PAGE_SIZE_1M = 0, - MMU_PAGE_SIZE_4K = 1, - MMU_PAGE_SIZE_8K = 2, - MMU_PAGE_SIZE_1K = 3 + MMU_PAGE_SIZE_1M = 0, + MMU_PAGE_SIZE_4K = 1, + MMU_PAGE_SIZE_8K = 2, + MMU_PAGE_SIZE_1K = 3 }; #define SIZE_1M 0x100000 /* 1 Megabyte */ @@ -100,7 +100,7 @@ extern long video_sbt; struct page_descriptor; extern void mmu_init(void); -extern int mmu_map_page(uint32_t virt, uint32_t phys, enum mmu_page_size sz, uint8_t page_id, const struct page_descriptor *flags); +extern int mmu_map_page(int32_t virt, int32_t phys, enum mmu_page_size sz, uint8_t page_id, const struct page_descriptor *flags); /* * API functions for the BaS driver interface diff --git a/include/ohci.h b/include/ohci.h index 9ffb901..0f7d68b 100644 --- a/include/ohci.h +++ b/include/ohci.h @@ -6,62 +6,62 @@ * * usb-ohci.h */ - + #define USB_OHCI_MAX_ROOT_PORTS 4 static int cc_to_error[16] = { /* mapping of the OHCI CC status to error codes */ - /* No Error */ 0, - /* CRC Error */ USB_ST_CRC_ERR, - /* Bit Stuff */ USB_ST_BIT_ERR, - /* Data Togg */ USB_ST_CRC_ERR, - /* Stall */ USB_ST_STALLED, - /* DevNotResp */ -1, - /* PIDCheck */ USB_ST_BIT_ERR, - /* UnExpPID */ USB_ST_BIT_ERR, - /* DataOver */ USB_ST_BUF_ERR, - /* DataUnder */ USB_ST_BUF_ERR, - /* reservd */ -1, - /* reservd */ -1, - /* BufferOver */ USB_ST_BUF_ERR, - /* BuffUnder */ USB_ST_BUF_ERR, - /* Not Access */ -1, - /* Not Access */ -1 + /* No Error */ 0, + /* CRC Error */ USB_ST_CRC_ERR, + /* Bit Stuff */ USB_ST_BIT_ERR, + /* Data Togg */ USB_ST_CRC_ERR, + /* Stall */ USB_ST_STALLED, + /* DevNotResp */ -1, + /* PIDCheck */ USB_ST_BIT_ERR, + /* UnExpPID */ USB_ST_BIT_ERR, + /* DataOver */ USB_ST_BUF_ERR, + /* DataUnder */ USB_ST_BUF_ERR, + /* reservd */ -1, + /* reservd */ -1, + /* BufferOver */ USB_ST_BUF_ERR, + /* BuffUnder */ USB_ST_BUF_ERR, + /* Not Access */ -1, + /* Not Access */ -1 }; static const char *cc_to_string[16] = { - "No Error", - "CRC: Last data packet from endpoint contained a CRC error.", - "BITSTUFFING:\r\nLast data packet from endpoint contained a bit stuffing violation", - "DATATOGGLEMISMATCH:\r\n Last packet from endpoint had data toggle PID\r\n" \ - "that did not match the expected value.", - "STALL: TD was moved to the Done Queue because the endpoint returned a STALL PID", - "DEVICENOTRESPONDING:\r\nDevice did not respond to token (IN) or did\r\n" \ - "not provide a handshake (OUT)", - "PIDCHECKFAILURE:\r\nCheck bits on PID from endpoint failed on data PID\r\n"\ - "(IN) or handshake (OUT)", - "UNEXPECTEDPID:\r\nReceive PID was not valid when encountered or PID\r\n" \ - "value is not defined.", - "DATAOVERRUN:\r\nThe amount of data returned by the endpoint exceeded\r\n" \ - "either the size of the maximum data packet allowed\r\n" \ - "from the endpoint (found in MaximumPacketSize field\r\n" \ - "of ED) or the remaining buffer size.", - "DATAUNDERRUN:\r\nThe endpoint returned less than MaximumPacketSize\r\n" \ - "and that amount was not sufficient to fill the\r\n" \ - "specified buffer", - "reserved1", - "reserved2", - "BUFFEROVERRUN:\r\nDuring an IN, HC received data from endpoint faster\r\n" \ - "than it could be written to system memory", - "BUFFERUNDERRUN:\r\nDuring an OUT, HC could not retrieve data from\r\n" \ - "system memory fast enough to keep up with data USB data rate.", - "NOT ACCESSED:\r\nThis code is set by software before the TD is placed\r\n" \ - "on a list to be processed by the HC.(1)", - "NOT ACCESSED:\r\nThis code is set by software before the TD is placed\r\n" \ - "on a list to be processed by the HC.(2)", + "No Error", + "CRC: Last data packet from endpoint contained a CRC error.", + "BITSTUFFING:\r\nLast data packet from endpoint contained a bit stuffing violation", + "DATATOGGLEMISMATCH:\r\n Last packet from endpoint had data toggle PID\r\n" \ + "that did not match the expected value.", + "STALL: TD was moved to the Done Queue because the endpoint returned a STALL PID", + "DEVICENOTRESPONDING:\r\nDevice did not respond to token (IN) or did\r\n" \ + "not provide a handshake (OUT)", + "PIDCHECKFAILURE:\r\nCheck bits on PID from endpoint failed on data PID\r\n"\ + "(IN) or handshake (OUT)", + "UNEXPECTEDPID:\r\nReceive PID was not valid when encountered or PID\r\n" \ + "value is not defined.", + "DATAOVERRUN:\r\nThe amount of data returned by the endpoint exceeded\r\n" \ + "either the size of the maximum data packet allowed\r\n" \ + "from the endpoint (found in MaximumPacketSize field\r\n" \ + "of ED) or the remaining buffer size.", + "DATAUNDERRUN:\r\nThe endpoint returned less than MaximumPacketSize\r\n" \ + "and that amount was not sufficient to fill the\r\n" \ + "specified buffer", + "reserved1", + "reserved2", + "BUFFEROVERRUN:\r\nDuring an IN, HC received data from endpoint faster\r\n" \ + "than it could be written to system memory", + "BUFFERUNDERRUN:\r\nDuring an OUT, HC could not retrieve data from\r\n" \ + "system memory fast enough to keep up with data USB data rate.", + "NOT ACCESSED:\r\nThis code is set by software before the TD is placed\r\n" \ + "on a list to be processed by the HC.(1)", + "NOT ACCESSED:\r\nThis code is set by software before the TD is placed\r\n" \ + "on a list to be processed by the HC.(2)", }; /* ED States */ @@ -75,24 +75,24 @@ static const char *cc_to_string[16] = /* usb_ohci_ed */ struct ed { - uint32_t hwINFO; - uint32_t hwTailP; - uint32_t hwHeadP; - uint32_t hwNextED; + uint32_t hwINFO; + uint32_t hwTailP; + uint32_t hwHeadP; + uint32_t hwNextED; - struct ed *ed_prev; - uint8_t int_period; - uint8_t int_branch; - uint8_t int_load; - uint8_t int_interval; - uint8_t state; - uint8_t type; - uint16_t last_iso; - struct ed *ed_rm_list; + struct ed *ed_prev; + uint8_t int_period; + uint8_t int_branch; + uint8_t int_load; + uint8_t int_interval; + uint8_t state; + uint8_t type; + uint16_t last_iso; + struct ed *ed_rm_list; - struct usb_device *usb_dev; - void *purb; - uint32_t unused[2]; + struct usb_device *usb_dev; + void *purb; + uint32_t unused[2]; } __attribute__((aligned(16))); typedef struct ed ed_t; @@ -137,21 +137,21 @@ typedef struct ed ed_t; struct td { - uint32_t hwINFO; - uint32_t hwCBP; /* Current Buffer Pointer */ - uint32_t hwNextTD; /* Next TD Pointer */ - uint32_t hwBE; /* Memory Buffer End Pointer */ + uint32_t hwINFO; + uint32_t hwCBP; /* Current Buffer Pointer */ + uint32_t hwNextTD; /* Next TD Pointer */ + uint32_t hwBE; /* Memory Buffer End Pointer */ - uint16_t hwPSW[MAXPSW]; - uint8_t unused; - uint8_t index; - struct ed *ed; - struct td *next_dl_td; - struct usb_device *usb_dev; - int transfer_len; - uint32_t data; + uint16_t hwPSW[MAXPSW]; + uint8_t unused; + uint8_t index; + struct ed *ed; + struct td *next_dl_td; + struct usb_device *usb_dev; + int transfer_len; + uint32_t data; - uint32_t unused2[2]; + uint32_t unused2[2]; } __attribute__((aligned(32))); typedef struct td td_t; @@ -166,16 +166,16 @@ typedef struct td td_t; #define NUM_INTS 32 /* part of the OHCI standard */ struct ohci_hcca { - uint32_t int_table[NUM_INTS]; /* Interrupt ED table */ + uint32_t int_table[NUM_INTS]; /* Interrupt ED table */ #if defined(CONFIG_MPC5200) - uint16_t pad1; /* set to 0 on each frame_no change */ - uint16_t frame_no; /* current frame number */ + uint16_t pad1; /* set to 0 on each frame_no change */ + uint16_t frame_no; /* current frame number */ #else - uint16_t frame_no; /* current frame number */ - uint16_t pad1; /* set to 0 on each frame_no change */ + uint16_t frame_no; /* current frame number */ + uint16_t pad1; /* set to 0 on each frame_no change */ #endif - uint32_t done_head; /* info returned for an interrupt */ - uint8_t reserved_for_hc[116]; + uint32_t done_head; /* info returned for an interrupt */ + uint8_t reserved_for_hc[116]; } __attribute__((aligned(256))); /* @@ -185,35 +185,35 @@ struct ohci_hcca */ struct ohci_regs { - /* control and status registers */ - uint32_t revision; - uint32_t control; - uint32_t cmdstatus; - uint32_t intrstatus; - uint32_t intrenable; - uint32_t intrdisable; - /* memory pointers */ - uint32_t hcca; - uint32_t ed_periodcurrent; - uint32_t ed_controlhead; - uint32_t ed_controlcurrent; - uint32_t ed_bulkhead; - uint32_t ed_bulkcurrent; - uint32_t donehead; - /* frame counters */ - uint32_t fminterval; - uint32_t fmremaining; - uint32_t fmnumber; - uint32_t periodicstart; - uint32_t lsthresh; - /* Root hub ports */ + /* control and status registers */ + uint32_t revision; + uint32_t control; + uint32_t cmdstatus; + uint32_t intrstatus; + uint32_t intrenable; + uint32_t intrdisable; + /* memory pointers */ + uint32_t hcca; + uint32_t ed_periodcurrent; + uint32_t ed_controlhead; + uint32_t ed_controlcurrent; + uint32_t ed_bulkhead; + uint32_t ed_bulkcurrent; + uint32_t donehead; + /* frame counters */ + uint32_t fminterval; + uint32_t fmremaining; + uint32_t fmnumber; + uint32_t periodicstart; + uint32_t lsthresh; + /* Root hub ports */ struct ohci_roothub_regs { - uint32_t a; - uint32_t b; - uint32_t status; - uint32_t portstatus[USB_OHCI_MAX_ROOT_PORTS]; - } roothub; + uint32_t a; + uint32_t b; + uint32_t status; + uint32_t portstatus[USB_OHCI_MAX_ROOT_PORTS]; + } roothub; } __attribute__((aligned(32))); /* Some EHCI controls */ @@ -270,11 +270,11 @@ struct ohci_regs /* Virtual Root HUB */ struct virt_root_hub { - int devnum; /* Address of Root Hub endpoint */ - void *dev; /* was urb */ - void *int_addr; - int send; - int interval; + int devnum; /* Address of Root Hub endpoint */ + void *dev; /* was urb */ + void *int_addr; + int send; + int interval; }; /* USB HUB CONSTANTS (not OHCI-specific; see hub.h) */ @@ -372,18 +372,18 @@ struct virt_root_hub #define N_URB_TD 48 typedef struct { - ed_t *ed; - uint16_t length; /* number of tds associated with this request */ - uint16_t td_cnt; /* number of tds already serviced */ - struct usb_device *dev; - int state; - uint32_t pipe; - void *transfer_buffer; - int transfer_buffer_length; - int interval; - int actual_length; - int finished; - td_t *td[N_URB_TD]; /* list pointer to all corresponding TDs associated with this request */ + ed_t *ed; + uint16_t length; /* number of tds associated with this request */ + uint16_t td_cnt; /* number of tds already serviced */ + struct usb_device *dev; + int state; + uint32_t pipe; + void *transfer_buffer; + int transfer_buffer_length; + int interval; + int actual_length; + int finished; + td_t *td[N_URB_TD]; /* list pointer to all corresponding TDs associated with this request */ } urb_priv_t; #define URB_DEL 1 @@ -391,8 +391,8 @@ typedef struct struct ohci_device { - ed_t ed[NUM_EDS]; - int ed_cnt; + ed_t ed[NUM_EDS]; + int ed_cnt; }; /* @@ -404,45 +404,45 @@ struct ohci_device typedef struct ohci { - /* ------- common part -------- */ - long handle; /* PCI BIOS */ - const struct pci_device_id *ent; - int usbnum; + /* ------- common part -------- */ + long handle; /* PCI BIOS */ + const struct pci_device_id *ent; + int usbnum; /* ---- end of common part ---- */ - int big_endian; /* PCI BIOS */ - int controller; - struct ohci_hcca *hcca_unaligned; - struct ohci_hcca *hcca; /* hcca */ - td_t *td_unaligned; - struct ohci_device *ohci_dev_unaligned; - /* this allocates EDs for all possible endpoints */ - struct ohci_device *ohci_dev; + int big_endian; /* PCI BIOS */ + int controller; + struct ohci_hcca *hcca_unaligned; + struct ohci_hcca *hcca; /* hcca */ + td_t *td_unaligned; + struct ohci_device *ohci_dev_unaligned; + /* this allocates EDs for all possible endpoints */ + struct ohci_device *ohci_dev; - int irq_enabled; - int stat_irq; - int irq; - int disabled; /* e.g. got a UE, we're hung */ - int sleeping; + int irq_enabled; + int stat_irq; + int irq; + int disabled; /* e.g. got a UE, we're hung */ + int sleeping; #define OHCI_FLAGS_NEC 0x80000000 - uint32_t flags; /* for HC bugs */ + uint32_t flags; /* for HC bugs */ - uint32_t offset; - uint32_t dma_offset; - struct ohci_regs *regs; /* OHCI controller's memory */ + uint32_t offset; + uint32_t dma_offset; + struct ohci_regs *regs; /* OHCI controller's memory */ - int ohci_int_load[32]; /* load of the 32 Interrupt Chains (for load balancing)*/ - ed_t *ed_rm_list[2]; /* lists of all endpoints to be removed */ - ed_t *ed_bulktail; /* last endpoint of bulk list */ - ed_t *ed_controltail; /* last endpoint of control list */ - int intrstatus; - uint32_t hc_control; /* copy of the hc control reg */ - uint32_t ndp; /* copy NDP from roothub_a */ - struct virt_root_hub rh; + int ohci_int_load[32]; /* load of the 32 Interrupt Chains (for load balancing)*/ + ed_t *ed_rm_list[2]; /* lists of all endpoints to be removed */ + ed_t *ed_bulktail; /* last endpoint of bulk list */ + ed_t *ed_controltail; /* last endpoint of control list */ + int intrstatus; + uint32_t hc_control; /* copy of the hc control reg */ + uint32_t ndp; /* copy NDP from roothub_a */ + struct virt_root_hub rh; - const char *slot_name; + const char *slot_name; - /* device which was disconnected */ - struct usb_device *devgone; + /* device which was disconnected */ + struct usb_device *devgone; } ohci_t; /* hcd */ @@ -458,7 +458,7 @@ static ed_t * ep_add_ed(ohci_t * ohci, struct usb_device * usb_dev, uint32_t pip static inline void ed_free(struct ed *ed) { - ed->usb_dev = NULL; + ed->usb_dev = NULL; } diff --git a/include/pci.h b/include/pci.h index 909bb9a..d7ee070 100644 --- a/include/pci.h +++ b/include/pci.h @@ -44,13 +44,13 @@ #define PCIHTR 0x0E /* PCI Header Type Register */ #define PCIBISTR 0x0F /* PCI Build-In Self Test Register */ #define PCIBAR0 0x10 /* PCI Base Address Register for Memory - Accesses to Local, Runtime, and DMA */ + Accesses to Local, Runtime, and DMA */ #define PCIBAR1 0x14 /* PCI Base Address Register for I/O - Accesses to Local, Runtime, and DMA */ + Accesses to Local, Runtime, and DMA */ #define PCIBAR2 0x18 /* PCI Base Address Register for Memory - Accesses to Local Address Space 0 */ + Accesses to Local Address Space 0 */ #define PCIBAR3 0x1C /* PCI Base Address Register for Memory - Accesses to Local Address Space 1 */ + Accesses to Local Address Space 1 */ #define PCIBAR4 0x20 /* PCI Base Address Register, reserved */ #define PCIBAR5 0x24 /* PCI Base Address Register, reserved */ #define PCICIS 0x28 /* PCI Cardbus CIS Pointer, not support*/ @@ -64,7 +64,7 @@ #define PCIMLR 0x3F /* PCI Max_Lat Register */ #define PMCAPID 0x40 /* Power Management Capability ID */ #define PMNEXT 0x41 /* Power Management Next Capability - Pointer */ + Pointer */ #define PMC 0x42 /* Power Management Capabilities */ #define PMCSR 0x44 /* Power Management Control/Status */ #define PMCSR_BSE 0x46 /* PMCSR Bridge Support Extensions */ @@ -74,7 +74,7 @@ #define HS_CSR 0x4A /* Hot Swap Control/Status */ #define PVPDCNTL 0x4C /* PCI Vital Product Data Control */ #define PVPD_NEXT 0x4D /* PCI Vital Product Data Next - Capability Pointer */ + Capability Pointer */ #define PVPDAD 0x4E /* PCI Vital Product Data Address */ #define PVPDATA 0x50 /* PCI VPD Data */ @@ -128,18 +128,18 @@ struct pci_rd /* structure of resource descriptor */ { - unsigned short next; /* length of the following structure */ - unsigned short flags; /* type of resource and misc. flags */ - unsigned long start; /* start-address of resource */ - unsigned long length; /* length of resource */ - unsigned long offset; /* offset PCI to phys. CPU Address */ - unsigned long dmaoffset; /* offset for DMA-transfers */ + unsigned short next; /* length of the following structure */ + unsigned short flags; /* type of resource and misc. flags */ + unsigned long start; /* start-address of resource */ + unsigned long length; /* length of resource */ + unsigned long offset; /* offset PCI to phys. CPU Address */ + unsigned long dmaoffset; /* offset for DMA-transfers */ } __attribute__ ((packed)); typedef struct /* structure of address conversion */ { - unsigned long adr; /* calculated address (CPU<->PCI) */ - unsigned long len; /* length of memory range */ + unsigned long adr; /* calculated address (CPU<->PCI) */ + unsigned long len; /* length of memory range */ } PCI_CONV_ADR; /******************************************************************************/ @@ -227,10 +227,14 @@ typedef struct /* structure of address conversion */ 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() */ @@ -337,9 +341,9 @@ 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) | \ - (function)) + ((bus) << 16) | \ + ((device << 8) | \ + (function)) #define PCI_HANDLE(bus, slot, function) (0 | ((bus & 0xff) << 10 | (slot & 0x1f) << 3 | (function & 7))) #define PCI_BUS_FROM_HANDLE(h) (((h) & 0xff00) >> 10) diff --git a/include/pci_ids.h b/include/pci_ids.h index 052b269..843d5ab 100644 --- a/include/pci_ids.h +++ b/include/pci_ids.h @@ -598,8 +598,10 @@ #define PCI_DEVICE_ID_NEC_VL 0x0016 /* PCI-VL Bridge */ #define PCI_DEVICE_ID_NEC_STARALPHA2 0x002c /* STAR ALPHA2 */ #define PCI_DEVICE_ID_NEC_CBUS_2 0x002d /* PCI-Cbus Bridge */ +#define PCI_DEVICE_ID_NEC_USB_A 0x0031 #define PCI_DEVICE_ID_NEC_USB 0x0035 /* PCI-USB Host */ #define PCI_DEVICE_ID_NEC_USB_2 0x00e0 /* PCI-USB 2 Host */ +#define PCI_DEVICE_ID_NEC_USB_3 0x00f0 #define PCI_DEVICE_ID_NEC_CBUS_3 0x003b #define PCI_DEVICE_ID_NEC_NAPCCARD 0x003e #define PCI_DEVICE_ID_NEC_PCX2 0x0046 /* PowerVR */ @@ -798,7 +800,7 @@ #define PCI_VENDOR_ID_ANIGMA 0x1051 #define PCI_DEVICE_ID_ANIGMA_MC145575 0x0100 - + #define PCI_VENDOR_ID_EFAR 0x1055 #define PCI_DEVICE_ID_EFAR_SLC90E66_1 0x9130 #define PCI_DEVICE_ID_EFAR_SLC90E66_0 0x9460 @@ -1507,7 +1509,7 @@ #define PCI_VENDOR_ID_ZIATECH 0x1138 #define PCI_DEVICE_ID_ZIATECH_5550_HC 0x5550 - + #define PCI_VENDOR_ID_CYCLONE 0x113c #define PCI_DEVICE_ID_CYCLONE_SDK 0x0001 @@ -1707,8 +1709,8 @@ #define PCI_DEVICE_ID_RP8OCTA 0x0005 #define PCI_DEVICE_ID_RP8J 0x0006 #define PCI_DEVICE_ID_RP4J 0x0007 -#define PCI_DEVICE_ID_RP8SNI 0x0008 -#define PCI_DEVICE_ID_RP16SNI 0x0009 +#define PCI_DEVICE_ID_RP8SNI 0x0008 +#define PCI_DEVICE_ID_RP16SNI 0x0009 #define PCI_DEVICE_ID_RPP4 0x000A #define PCI_DEVICE_ID_RPP8 0x000B #define PCI_DEVICE_ID_RP8M 0x000C @@ -1719,9 +1721,9 @@ #define PCI_DEVICE_ID_URP8INTF 0x0802 #define PCI_DEVICE_ID_URP16INTF 0x0803 #define PCI_DEVICE_ID_URP8OCTA 0x0805 -#define PCI_DEVICE_ID_UPCI_RM3_8PORT 0x080C +#define PCI_DEVICE_ID_UPCI_RM3_8PORT 0x080C #define PCI_DEVICE_ID_UPCI_RM3_4PORT 0x080D -#define PCI_DEVICE_ID_CRP16INTF 0x0903 +#define PCI_DEVICE_ID_CRP16INTF 0x0903 #define PCI_VENDOR_ID_CYCLADES 0x120e #define PCI_DEVICE_ID_CYCLOM_Y_Lo 0x0100 @@ -2143,7 +2145,7 @@ #define PCI_DEVICE_ID_RASTEL_2PORT 0x2000 #define PCI_VENDOR_ID_ZOLTRIX 0x15b0 -#define PCI_DEVICE_ID_ZOLTRIX_2BD0 0x2bd0 +#define PCI_DEVICE_ID_ZOLTRIX_2BD0 0x2bd0 #define PCI_VENDOR_ID_MELLANOX 0x15b3 #define PCI_DEVICE_ID_MELLANOX_TAVOR 0x5a44 @@ -2288,8 +2290,8 @@ #define PCI_DEVICE_ID_INTEL_82092AA_0 0x1221 #define PCI_DEVICE_ID_INTEL_82092AA_1 0x1222 #define PCI_DEVICE_ID_INTEL_7116 0x1223 -#define PCI_DEVICE_ID_INTEL_7505_0 0x2550 -#define PCI_DEVICE_ID_INTEL_7505_1 0x2552 +#define PCI_DEVICE_ID_INTEL_7505_0 0x2550 +#define PCI_DEVICE_ID_INTEL_7505_1 0x2552 #define PCI_DEVICE_ID_INTEL_7205_0 0x255d #define PCI_DEVICE_ID_INTEL_82596 0x1226 #define PCI_DEVICE_ID_INTEL_82865 0x1227 diff --git a/include/wait.h b/include/wait.h index 0b9adb1..90b2736 100644 --- a/include/wait.h +++ b/include/wait.h @@ -44,6 +44,8 @@ typedef bool (*checker_func)(void); extern void wait(uint32_t); +extern void wait_us(uint32_t); /* this is just an alias to the above */ + inline static void udelay(long us) { wait((uint32_t) us); diff --git a/net/fec.c b/net/fec.c index 4481ef5..77e9250 100644 --- a/net/fec.c +++ b/net/fec.c @@ -32,7 +32,7 @@ #error Unknown machine! #endif -// #define DBG_FEC +#define DBG_FEC #ifdef DBG_FEC #define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0) #else @@ -63,56 +63,56 @@ FEC_EVENT_LOG fec_log[2]; */ int fec_mii_write(uint8_t ch, uint8_t phy_addr, uint8_t reg_addr, uint16_t data) { - int timeout; - uint32_t eimr; + int timeout; + uint32_t eimr; - /* - * Clear the MII interrupt bit - */ - MCF_FEC_EIR(ch) = MCF_FEC_EIR_MII; + /* + * Clear the MII interrupt bit + */ + MCF_FEC_EIR(ch) = MCF_FEC_EIR_MII; - /* - * Write to the MII Management Frame Register to kick-off - * the MII write - */ - MCF_FEC_MMFR(ch) = 0 - | MCF_FEC_MMFR_ST_01 - | MCF_FEC_MMFR_OP_WRITE - | MCF_FEC_MMFR_PA(phy_addr) - | MCF_FEC_MMFR_RA(reg_addr) - | MCF_FEC_MMFR_TA_10 - | MCF_FEC_MMFR_DATA(data); + /* + * Write to the MII Management Frame Register to kick-off + * the MII write + */ + MCF_FEC_MMFR(ch) = 0 + | MCF_FEC_MMFR_ST_01 + | MCF_FEC_MMFR_OP_WRITE + | MCF_FEC_MMFR_PA(phy_addr) + | MCF_FEC_MMFR_RA(reg_addr) + | MCF_FEC_MMFR_TA_10 + | MCF_FEC_MMFR_DATA(data); - /* - * Mask the MII interrupt - */ - eimr = MCF_FEC_EIMR(ch); - MCF_FEC_EIMR(ch) &= ~MCF_FEC_EIMR_MII; + /* + * Mask the MII interrupt + */ + eimr = MCF_FEC_EIMR(ch); + MCF_FEC_EIMR(ch) &= ~MCF_FEC_EIMR_MII; - /* - * Poll for the MII interrupt (interrupt should be masked) - */ - for (timeout = 0; timeout < FEC_MII_TIMEOUT; timeout++) - { - wait(1); - if (MCF_FEC_EIR(ch) & MCF_FEC_EIR_MII) - break; - } + /* + * Poll for the MII interrupt (interrupt should be masked) + */ + for (timeout = 0; timeout < FEC_MII_TIMEOUT; timeout++) + { + wait(1); + if (MCF_FEC_EIR(ch) & MCF_FEC_EIR_MII) + break; + } - if (timeout == FEC_MII_TIMEOUT) - return 0; + if (timeout == FEC_MII_TIMEOUT) + return 0; - /* - * Clear the MII interrupt bit - */ - MCF_FEC_EIR(ch) = MCF_FEC_EIR_MII; + /* + * Clear the MII interrupt bit + */ + MCF_FEC_EIR(ch) = MCF_FEC_EIR_MII; - /* - * Restore the EIMR - */ - MCF_FEC_EIMR(ch) = eimr; + /* + * Restore the EIMR + */ + MCF_FEC_EIMR(ch) = eimr; - return 1; + return 1; } /* @@ -137,45 +137,45 @@ int fec_mii_write(uint8_t ch, uint8_t phy_addr, uint8_t reg_addr, uint16_t data) */ int fec_mii_read(uint8_t ch, uint8_t phy_addr, uint8_t reg_addr, uint16_t *data) { - int timeout; + int timeout; - /* - * Clear the MII interrupt bit - */ - MCF_FEC_EIR(ch) = MCF_FEC_EIR_MII; + /* + * Clear the MII interrupt bit + */ + MCF_FEC_EIR(ch) = MCF_FEC_EIR_MII; - /* - * Write to the MII Management Frame Register to kick-off - * the MII read - */ - MCF_FEC_MMFR(ch) = 0 - | MCF_FEC_MMFR_ST_01 - | MCF_FEC_MMFR_OP_READ - | MCF_FEC_MMFR_PA(phy_addr) - | MCF_FEC_MMFR_RA(reg_addr) - | MCF_FEC_MMFR_TA_10; + /* + * Write to the MII Management Frame Register to kick-off + * the MII read + */ + MCF_FEC_MMFR(ch) = 0 + | MCF_FEC_MMFR_ST_01 + | MCF_FEC_MMFR_OP_READ + | MCF_FEC_MMFR_PA(phy_addr) + | MCF_FEC_MMFR_RA(reg_addr) + | MCF_FEC_MMFR_TA_10; - /* - * Poll for the MII interrupt (interrupt should be masked) - */ - for (timeout = 0; timeout < FEC_MII_TIMEOUT; timeout++) - { - wait(1); - if (MCF_FEC_EIR(ch) & MCF_FEC_EIR_MII) - break; - } + /* + * Poll for the MII interrupt (interrupt should be masked) + */ + for (timeout = 0; timeout < FEC_MII_TIMEOUT; timeout++) + { + wait(1); + if (MCF_FEC_EIR(ch) & MCF_FEC_EIR_MII) + break; + } - if (timeout == FEC_MII_TIMEOUT) - return 0; + if (timeout == FEC_MII_TIMEOUT) + return 0; - /* - * Clear the MII interrupt bit - */ - MCF_FEC_EIR(ch) = MCF_FEC_EIR_MII; + /* + * Clear the MII interrupt bit + */ + MCF_FEC_EIR(ch) = MCF_FEC_EIR_MII; - *data = (uint16_t)(MCF_FEC_MMFR(ch) & 0x0000FFFF); + *data = (uint16_t)(MCF_FEC_MMFR(ch) & 0x0000FFFF); - return 1; + return 1; } /* @@ -187,14 +187,14 @@ int fec_mii_read(uint8_t ch, uint8_t phy_addr, uint8_t reg_addr, uint16_t *data) */ void fec_mii_init(uint8_t ch, uint32_t sys_clk) { - /* - * Initialize the MII clock (EMDC) frequency - * - * Desired MII clock is 2.5MHz - * MII Speed Setting = System_Clock / (2.5MHz * 2) - * (plus 1 to make sure we round up) - */ - MCF_FEC_MSCR(ch) = MCF_FEC_MSCR_MII_SPEED((sys_clk / 5) + 1); + /* + * Initialize the MII clock (EMDC) frequency + * + * Desired MII clock is 2.5MHz + * MII Speed Setting = System_Clock / (2.5MHz * 2) + * (plus 1 to make sure we round up) + */ + MCF_FEC_MSCR(ch) = MCF_FEC_MSCR_MII_SPEED((sys_clk / 5) + 1); } /* Initialize the MIB counters @@ -204,7 +204,7 @@ void fec_mii_init(uint8_t ch, uint32_t sys_clk) */ void fec_mib_init(uint8_t ch) { - //To do + //To do } /* @@ -215,7 +215,7 @@ void fec_mib_init(uint8_t ch) */ void fec_mib_dump(uint8_t ch) { - //To do + //To do } /* @@ -226,7 +226,7 @@ void fec_mib_dump(uint8_t ch) */ void fec_log_init(uint8_t ch) { - memset(&fec_log[ch], 0, sizeof(FEC_EVENT_LOG)); + memset(&fec_log[ch], 0, sizeof(FEC_EVENT_LOG)); } /* @@ -237,33 +237,33 @@ void fec_log_init(uint8_t ch) */ void fec_log_dump(uint8_t ch) { - dbg("\r\n FEC%d Log\r\n", __FUNCTION__, ch); - dbg(" ---------------\r\n", __FUNCTION__); - dbg(" Total: %4d\r\n", fec_log[ch].total); - dbg(" hberr: %4d\r\n", fec_log[ch].hberr); - dbg(" babr: %4d\r\n", fec_log[ch].babr); - dbg(" babt: %4d\r\n", fec_log[ch].babt); - dbg(" gra: %4d\r\n", fec_log[ch].gra); - dbg(" txf: %4d\r\n", fec_log[ch].txf); - dbg(" mii: %4d\r\n", fec_log[ch].mii); - dbg(" lc: %4d\r\n", fec_log[ch].lc); - dbg(" rl: %4d\r\n", fec_log[ch].rl); - dbg(" xfun: %4d\r\n", fec_log[ch].xfun); - dbg(" xferr: %4d\r\n", fec_log[ch].xferr); - dbg(" rferr: %4d\r\n", fec_log[ch].rferr); - dbg(" dtxf: %4d\r\n", fec_log[ch].dtxf); - dbg(" drxf: %4d\r\n", fec_log[ch].drxf); - dbg(" \r\nRFSW:\r\n"); - dbg(" inv: %4d\r\n", fec_log[ch].rfsw_inv); - dbg(" m: %4d\r\n", fec_log[ch].rfsw_m); - dbg(" bc: %4d\r\n", fec_log[ch].rfsw_bc); - dbg(" mc: %4d\r\n", fec_log[ch].rfsw_mc); - dbg(" lg: %4d\r\n", fec_log[ch].rfsw_lg); - dbg(" no: %4d\r\n", fec_log[ch].rfsw_no); - dbg(" cr: %4d\r\n", fec_log[ch].rfsw_cr); - dbg(" ov: %4d\r\n", fec_log[ch].rfsw_ov); - dbg(" tr: %4d\r\n", fec_log[ch].rfsw_tr); - dbg(" ---------------\r\n\r\n"); + dbg("\r\n FEC%d Log\r\n", __FUNCTION__, ch); + dbg(" ---------------\r\n", __FUNCTION__); + dbg(" Total: %4d\r\n", fec_log[ch].total); + dbg(" hberr: %4d\r\n", fec_log[ch].hberr); + dbg(" babr: %4d\r\n", fec_log[ch].babr); + dbg(" babt: %4d\r\n", fec_log[ch].babt); + dbg(" gra: %4d\r\n", fec_log[ch].gra); + dbg(" txf: %4d\r\n", fec_log[ch].txf); + dbg(" mii: %4d\r\n", fec_log[ch].mii); + dbg(" lc: %4d\r\n", fec_log[ch].lc); + dbg(" rl: %4d\r\n", fec_log[ch].rl); + dbg(" xfun: %4d\r\n", fec_log[ch].xfun); + dbg(" xferr: %4d\r\n", fec_log[ch].xferr); + dbg(" rferr: %4d\r\n", fec_log[ch].rferr); + dbg(" dtxf: %4d\r\n", fec_log[ch].dtxf); + dbg(" drxf: %4d\r\n", fec_log[ch].drxf); + dbg(" \r\nRFSW:\r\n"); + dbg(" inv: %4d\r\n", fec_log[ch].rfsw_inv); + dbg(" m: %4d\r\n", fec_log[ch].rfsw_m); + dbg(" bc: %4d\r\n", fec_log[ch].rfsw_bc); + dbg(" mc: %4d\r\n", fec_log[ch].rfsw_mc); + dbg(" lg: %4d\r\n", fec_log[ch].rfsw_lg); + dbg(" no: %4d\r\n", fec_log[ch].rfsw_no); + dbg(" cr: %4d\r\n", fec_log[ch].rfsw_cr); + dbg(" ov: %4d\r\n", fec_log[ch].rfsw_ov); + dbg(" tr: %4d\r\n", fec_log[ch].rfsw_tr); + dbg(" ---------------\r\n\r\n"); } /* @@ -274,30 +274,30 @@ void fec_log_dump(uint8_t ch) */ void fec_debug_dump(uint8_t ch) { - dbg("\r\n------------- FEC%d -------------\r\n",ch); - dbg("EIR %08x \r\n", MCF_FEC_EIR(ch)); - dbg("EIMR %08x \r\n", MCF_FEC_EIMR(ch)); - dbg("ECR %08x \r\n", MCF_FEC_ECR(ch)); - dbg("RCR %08x \r\n", MCF_FEC_RCR(ch)); - dbg("R_HASH %08x \r\n", MCF_FEC_RHR_HASH(ch)); - dbg("TCR %08x \r\n", MCF_FEC_TCR(ch)); - dbg("FECTFWR %08x \r\n", MCF_FEC_FECTFWR(ch)); - dbg("FECRFSR %08x \r\n", MCF_FEC_FECRFSR(ch)); - dbg("FECRFCR %08x \r\n", MCF_FEC_FECRFCR(ch)); - dbg("FECRLRFP %08x \r\n", MCF_FEC_FECRLRFP(ch)); - dbg("FECRLWFP %08x \r\n", MCF_FEC_FECRLWFP(ch)); - dbg("FECRFAR %08x \r\n", MCF_FEC_FECRFAR(ch)); - dbg("FECRFRP %08x \r\n", MCF_FEC_FECRFRP(ch)); - dbg("FECRFWP %08x \r\n", MCF_FEC_FECRFWP(ch)); - dbg("FECTFSR %08x \r\n", MCF_FEC_FECTFSR(ch)); - dbg("FECTFCR %08x \r\n", MCF_FEC_FECTFCR(ch)); - dbg("FECTLRFP %08x \r\n", MCF_FEC_FECTLRFP(ch)); - dbg("FECTLWFP %08x \r\n", MCF_FEC_FECTLWFP(ch)); - dbg("FECTFAR %08x \r\n", MCF_FEC_FECTFAR(ch)); - dbg("FECTFRP %08x \r\n", MCF_FEC_FECTFRP(ch)); - dbg("FECTFWP %08x \r\n", MCF_FEC_FECTFWP(ch)); - dbg("FRST %08x \r\n", MCF_FEC_FECFRST(ch)); - dbg("--------------------------------\r\n\r\n"); + dbg("\r\n------------- FEC%d -------------\r\n",ch); + dbg("EIR %08x \r\n", MCF_FEC_EIR(ch)); + dbg("EIMR %08x \r\n", MCF_FEC_EIMR(ch)); + dbg("ECR %08x \r\n", MCF_FEC_ECR(ch)); + dbg("RCR %08x \r\n", MCF_FEC_RCR(ch)); + dbg("R_HASH %08x \r\n", MCF_FEC_RHR_HASH(ch)); + dbg("TCR %08x \r\n", MCF_FEC_TCR(ch)); + dbg("FECTFWR %08x \r\n", MCF_FEC_FECTFWR(ch)); + dbg("FECRFSR %08x \r\n", MCF_FEC_FECRFSR(ch)); + dbg("FECRFCR %08x \r\n", MCF_FEC_FECRFCR(ch)); + dbg("FECRLRFP %08x \r\n", MCF_FEC_FECRLRFP(ch)); + dbg("FECRLWFP %08x \r\n", MCF_FEC_FECRLWFP(ch)); + dbg("FECRFAR %08x \r\n", MCF_FEC_FECRFAR(ch)); + dbg("FECRFRP %08x \r\n", MCF_FEC_FECRFRP(ch)); + dbg("FECRFWP %08x \r\n", MCF_FEC_FECRFWP(ch)); + dbg("FECTFSR %08x \r\n", MCF_FEC_FECTFSR(ch)); + dbg("FECTFCR %08x \r\n", MCF_FEC_FECTFCR(ch)); + dbg("FECTLRFP %08x \r\n", MCF_FEC_FECTLRFP(ch)); + dbg("FECTLWFP %08x \r\n", MCF_FEC_FECTLWFP(ch)); + dbg("FECTFAR %08x \r\n", MCF_FEC_FECTFAR(ch)); + dbg("FECTFRP %08x \r\n", MCF_FEC_FECTFRP(ch)); + dbg("FECTFWP %08x \r\n", MCF_FEC_FECTFWP(ch)); + dbg("FRST %08x \r\n", MCF_FEC_FECFRST(ch)); + dbg("--------------------------------\r\n\r\n"); } /* @@ -309,18 +309,18 @@ void fec_debug_dump(uint8_t ch) */ void fec_duplex(uint8_t ch, uint8_t duplex) { - switch (duplex) - { - case FEC_MII_HALF_DUPLEX: - MCF_FEC_RCR(ch) |= MCF_FEC_RCR_DRT; - MCF_FEC_TCR(ch) &= (uint32_t) ~MCF_FEC_TCR_FDEN; - break; - case FEC_MII_FULL_DUPLEX: - default: - MCF_FEC_RCR(ch) &= (uint32_t) ~MCF_FEC_RCR_DRT; - MCF_FEC_TCR(ch) |= MCF_FEC_TCR_FDEN; - break; - } + switch (duplex) + { + case FEC_MII_HALF_DUPLEX: + MCF_FEC_RCR(ch) |= MCF_FEC_RCR_DRT; + MCF_FEC_TCR(ch) &= (uint32_t) ~MCF_FEC_TCR_FDEN; + break; + case FEC_MII_FULL_DUPLEX: + default: + MCF_FEC_RCR(ch) &= (uint32_t) ~MCF_FEC_RCR_DRT; + MCF_FEC_TCR(ch) |= MCF_FEC_TCR_FDEN; + break; + } } /* @@ -334,27 +334,27 @@ void fec_duplex(uint8_t ch, uint8_t duplex) */ uint8_t fec_hash_address(const uint8_t *addr) { - uint32_t crc; - uint8_t byte; - int i, j; + uint32_t crc; + uint8_t byte; + int i, j; - crc = 0xFFFFFFFF; - for (i = 0; i < 6; ++i) - { - byte = addr[i]; - for (j = 0; j < 8; ++j) - { - if ((byte & 0x01) ^ (crc & 0x01)) - { - crc >>= 1; - crc = crc ^ 0xEDB88320; - } - else - crc >>= 1; - byte >>= 1; - } - } - return (uint8_t)(crc >> 26); + crc = 0xFFFFFFFF; + for (i = 0; i < 6; ++i) + { + byte = addr[i]; + for (j = 0; j < 8; ++j) + { + if ((byte & 0x01) ^ (crc & 0x01)) + { + crc >>= 1; + crc = crc ^ 0xEDB88320; + } + else + crc >>= 1; + byte >>= 1; + } + } + return (uint8_t)(crc >> 26); } /* @@ -367,23 +367,23 @@ uint8_t fec_hash_address(const uint8_t *addr) */ void fec_set_address(uint8_t ch, const uint8_t *pa) { - uint8_t crc; + uint8_t crc; - /* - * Set the Physical Address - */ - MCF_FEC_PALR(ch) = (uint32_t) ((pa[0] << 24) | (pa[1] << 16) | (pa[2] << 8) | pa[3]); - MCF_FEC_PAHR(ch) = (uint32_t) ((pa[4] << 24) | (pa[5] << 16)); + /* + * Set the Physical Address + */ + MCF_FEC_PALR(ch) = (uint32_t) ((pa[0] << 24) | (pa[1] << 16) | (pa[2] << 8) | pa[3]); + MCF_FEC_PAHR(ch) = (uint32_t) ((pa[4] << 24) | (pa[5] << 16)); - /* - * Calculate and set the hash for given Physical Address - * in the Individual Address Hash registers - */ - crc = fec_hash_address(pa); - if(crc >= 32) - MCF_FEC_IAUR(ch) |= (uint32_t) (1 << (crc - 32)); - else - MCF_FEC_IALR(ch) |= (uint32_t) (1 << crc); + /* + * Calculate and set the hash for given Physical Address + * in the Individual Address Hash registers + */ + crc = fec_hash_address(pa); + if(crc >= 32) + MCF_FEC_IAUR(ch) |= (uint32_t) (1 << (crc - 32)); + else + MCF_FEC_IALR(ch) |= (uint32_t) (1 << crc); } /* @@ -394,32 +394,32 @@ void fec_set_address(uint8_t ch, const uint8_t *pa) */ void fec_reset(uint8_t ch) { - int i; + int i; - /* Clear any events in the FIFO status registers */ - MCF_FEC_FECRFSR(ch) = (0 - | MCF_FEC_FECRFSR_OF - | MCF_FEC_FECRFSR_UF - | MCF_FEC_FECRFSR_RXW - | MCF_FEC_FECRFSR_FAE - | MCF_FEC_FECRFSR_IP); - MCF_FEC_FECTFSR(ch) = (0 - | MCF_FEC_FECTFSR_OF - | MCF_FEC_FECTFSR_UF - | MCF_FEC_FECTFSR_TXW - | MCF_FEC_FECTFSR_FAE - | MCF_FEC_FECTFSR_IP); + /* Clear any events in the FIFO status registers */ + MCF_FEC_FECRFSR(ch) = (0 + | MCF_FEC_FECRFSR_OF + | MCF_FEC_FECRFSR_UF + | MCF_FEC_FECRFSR_RXW + | MCF_FEC_FECRFSR_FAE + | MCF_FEC_FECRFSR_IP); + MCF_FEC_FECTFSR(ch) = (0 + | MCF_FEC_FECTFSR_OF + | MCF_FEC_FECTFSR_UF + | MCF_FEC_FECTFSR_TXW + | MCF_FEC_FECTFSR_FAE + | MCF_FEC_FECTFSR_IP); - /* Reset the FIFOs */ - MCF_FEC_FECFRST(ch) |= MCF_FEC_FECFRST_SW_RST; - MCF_FEC_FECFRST(ch) &= ~MCF_FEC_FECFRST_SW_RST; + /* Reset the FIFOs */ + MCF_FEC_FECFRST(ch) |= MCF_FEC_FECFRST_SW_RST; + MCF_FEC_FECFRST(ch) &= ~MCF_FEC_FECFRST_SW_RST; - /* Set the Reset bit and clear the Enable bit */ - MCF_FEC_ECR(ch) = MCF_FEC_ECR_RESET; + /* Set the Reset bit and clear the Enable bit */ + MCF_FEC_ECR(ch) = MCF_FEC_ECR_RESET; - /* Wait at least 8 clock cycles */ - for (i = 0; i < 10; ++i) - NOP(); + /* Wait at least 8 clock cycles */ + for (i = 0; i < 10; ++i) + NOP(); } /* @@ -432,99 +432,99 @@ void fec_reset(uint8_t ch) */ void fec_init(uint8_t ch, uint8_t mode, const uint8_t *pa) { - /* - * Enable all the external interface signals - */ - if (mode == FEC_MODE_7WIRE) - { - if (ch == 1) - MCF_PAD_PAR_FECI2CIRQ |= MCF_PAD_PAR_FECI2CIRQ_PAR_E17; - else - MCF_PAD_PAR_FECI2CIRQ |= MCF_PAD_PAR_FECI2CIRQ_PAR_E07; - } - else if (mode == FEC_MODE_MII) - { - if (ch == 1) - MCF_PAD_PAR_FECI2CIRQ |= 0 - | MCF_PAD_PAR_FECI2CIRQ_PAR_E1MDC_E1MDC - | MCF_PAD_PAR_FECI2CIRQ_PAR_E1MDIO_E1MDIO - | MCF_PAD_PAR_FECI2CIRQ_PAR_E1MII - | MCF_PAD_PAR_FECI2CIRQ_PAR_E17; - else - MCF_PAD_PAR_FECI2CIRQ |= 0 - | MCF_PAD_PAR_FECI2CIRQ_PAR_E0MDC - | MCF_PAD_PAR_FECI2CIRQ_PAR_E0MDIO - | MCF_PAD_PAR_FECI2CIRQ_PAR_E0MII - | MCF_PAD_PAR_FECI2CIRQ_PAR_E07; - } + /* + * Enable all the external interface signals + */ + if (mode == FEC_MODE_7WIRE) + { + if (ch == 1) + MCF_PAD_PAR_FECI2CIRQ |= MCF_PAD_PAR_FECI2CIRQ_PAR_E17; + else + MCF_PAD_PAR_FECI2CIRQ |= MCF_PAD_PAR_FECI2CIRQ_PAR_E07; + } + else if (mode == FEC_MODE_MII) + { + if (ch == 1) + MCF_PAD_PAR_FECI2CIRQ |= 0 + | MCF_PAD_PAR_FECI2CIRQ_PAR_E1MDC_E1MDC + | MCF_PAD_PAR_FECI2CIRQ_PAR_E1MDIO_E1MDIO + | MCF_PAD_PAR_FECI2CIRQ_PAR_E1MII + | MCF_PAD_PAR_FECI2CIRQ_PAR_E17; + else + MCF_PAD_PAR_FECI2CIRQ |= 0 + | MCF_PAD_PAR_FECI2CIRQ_PAR_E0MDC + | MCF_PAD_PAR_FECI2CIRQ_PAR_E0MDIO + | MCF_PAD_PAR_FECI2CIRQ_PAR_E0MII + | MCF_PAD_PAR_FECI2CIRQ_PAR_E07; + } - /* - * Clear the Individual and Group Address Hash registers - */ - MCF_FEC_IALR(ch) = 0; - MCF_FEC_IAUR(ch) = 0; - MCF_FEC_GALR(ch) = 0; - MCF_FEC_GAUR(ch) = 0; + /* + * Clear the Individual and Group Address Hash registers + */ + MCF_FEC_IALR(ch) = 0; + MCF_FEC_IAUR(ch) = 0; + MCF_FEC_GALR(ch) = 0; + MCF_FEC_GAUR(ch) = 0; - /* - * Set the Physical Address for the selected FEC - */ - fec_set_address(ch, pa); + /* + * Set the Physical Address for the selected FEC + */ + fec_set_address(ch, pa); - /* - * Mask all FEC interrupts - */ - MCF_FEC_EIMR(ch) = MCF_FEC_EIMR_MASK_ALL; + /* + * Mask all FEC interrupts + */ + MCF_FEC_EIMR(ch) = MCF_FEC_EIMR_MASK_ALL; - /* - * Clear all FEC interrupt events - */ - MCF_FEC_EIR(ch) = MCF_FEC_EIR_CLEAR_ALL; + /* + * Clear all FEC interrupt events + */ + MCF_FEC_EIR(ch) = MCF_FEC_EIR_CLEAR_ALL; - /* - * Initialize the Receive Control Register - */ - MCF_FEC_RCR(ch) = 0 - | MCF_FEC_RCR_MAX_FL(ETH_MAX_FRM) - | MCF_FEC_RCR_PROM - | MCF_FEC_RCR_FCE; + /* + * Initialize the Receive Control Register + */ + MCF_FEC_RCR(ch) = 0 + | MCF_FEC_RCR_MAX_FL(ETH_MAX_FRM) + | MCF_FEC_RCR_PROM + | MCF_FEC_RCR_FCE; - if (mode == FEC_MODE_MII) - MCF_FEC_RCR(ch) |= MCF_FEC_RCR_MII_MODE; + if (mode == FEC_MODE_MII) + MCF_FEC_RCR(ch) |= MCF_FEC_RCR_MII_MODE; - else if (mode == FEC_MODE_LOOPBACK) - MCF_FEC_RCR(ch) |= MCF_FEC_RCR_LOOP; + else if (mode == FEC_MODE_LOOPBACK) + MCF_FEC_RCR(ch) |= MCF_FEC_RCR_LOOP; - /* - * Initialize the Transmit Control Register - */ - MCF_FEC_TCR(ch) = MCF_FEC_TCR_FDEN; + /* + * Initialize the Transmit Control Register + */ + MCF_FEC_TCR(ch) = MCF_FEC_TCR_FDEN; - /* - * Set Rx FIFO alarm and granularity - */ - MCF_FEC_FECRFCR(ch) = 0 - | MCF_FEC_FECRFCR_FRMEN - | MCF_FEC_FECRFCR_RXW_MSK - | MCF_FEC_FECRFCR_GR(7); - MCF_FEC_FECRFAR(ch) = MCF_FEC_FECRFAR_ALARM(768); + /* + * Set Rx FIFO alarm and granularity + */ + MCF_FEC_FECRFCR(ch) = 0 + | MCF_FEC_FECRFCR_FRMEN + | MCF_FEC_FECRFCR_RXW_MSK + | MCF_FEC_FECRFCR_GR(7); + MCF_FEC_FECRFAR(ch) = MCF_FEC_FECRFAR_ALARM(768); - /* - * Set Tx FIFO watermark, alarm and granularity - */ - MCF_FEC_FECTFCR(ch) = 0 - | MCF_FEC_FECTFCR_FRMEN - | MCF_FEC_FECTFCR_TXW_MASK - | MCF_FEC_FECTFCR_GR(7); - MCF_FEC_FECTFAR(ch) = MCF_FEC_FECTFAR_ALARM(256); - MCF_FEC_FECTFWR(ch) = MCF_FEC_FECTFWR_X_WMRK_256; + /* + * Set Tx FIFO watermark, alarm and granularity + */ + MCF_FEC_FECTFCR(ch) = 0 + | MCF_FEC_FECTFCR_FRMEN + | MCF_FEC_FECTFCR_TXW_MASK + | MCF_FEC_FECTFCR_GR(7); + MCF_FEC_FECTFAR(ch) = MCF_FEC_FECTFAR_ALARM(256); + MCF_FEC_FECTFWR(ch) = MCF_FEC_FECTFWR_X_WMRK_256; - /* - * Enable the transmitter to append the CRC - */ - MCF_FEC_FECCTCWR(ch) = 0 - | MCF_FEC_FECCTCWR_TFCW - | MCF_FEC_FECCTCWR_CRC; + /* + * Enable the transmitter to append the CRC + */ + MCF_FEC_FECCTCWR(ch) = 0 + | MCF_FEC_FECCTCWR_TFCW + | MCF_FEC_FECCTCWR_CRC; } /* @@ -536,61 +536,61 @@ void fec_init(uint8_t ch, uint8_t mode, const uint8_t *pa) */ void fec_rx_start(uint8_t ch, int8_t *rxbd) { - uint32_t initiator; - int channel; + uint32_t initiator; + int channel; #ifdef DBG_FEC - int res; + int res; #endif - /* - * Make the initiator assignment - */ + /* + * Make the initiator assignment + */ #if defined(DBG_FEC) res = #else (void) #endif dma_set_initiator(DMA_FEC_RX(ch)); - dbg("dma_set_initiator(DMA_FEC_RX(%d)): %d\r\n", ch, res); + dbg("dma_set_initiator(DMA_FEC_RX(%d)): %d\r\n", ch, res); - /* - * Grab the initiator number - */ - initiator = dma_get_initiator(DMA_FEC_RX(ch)); - dbg("dma_get_initiator(DMA_FEC_RX(%d)) = %d\r\n", ch, initiator); + /* + * Grab the initiator number + */ + initiator = dma_get_initiator(DMA_FEC_RX(ch)); + dbg("dma_get_initiator(DMA_FEC_RX(%d)) = %d\r\n", ch, initiator); - /* - * Determine the DMA channel running the task for the - * selected FEC - */ - channel = dma_set_channel(DMA_FEC_RX(ch), - (ch == 0) ? fec0_rx_frame : fec1_rx_frame); - dbg("DMA channel for FEC%1d: %d\r\n", ch, channel); + /* + * Determine the DMA channel running the task for the + * selected FEC + */ + channel = dma_set_channel(DMA_FEC_RX(ch), + (ch == 0) ? fec0_rx_frame : fec1_rx_frame); + dbg("DMA channel for FEC%1d: %d\r\n", ch, channel); - /* - * Start the Rx DMA task - */ - MCD_startDma(channel, - (int8_t *) rxbd, - 0, - (int8_t *) MCF_FEC_FECRFDR(ch), - 0, - RX_BUF_SZ, - 0, - initiator, - FECRX_DMA_PRI(ch), - 0 - | MCD_FECRX_DMA - | MCD_INTERRUPT - | MCD_TT_FLAGS_CW - | MCD_TT_FLAGS_RL - | MCD_TT_FLAGS_SP - , - 0 - | MCD_NO_CSUM - | MCD_NO_BYTE_SWAP - ); - dbg("Rx DMA task for FEC%1d started\r\n", ch); + /* + * Start the Rx DMA task + */ + MCD_startDma(channel, + (int8_t *) rxbd, + 0, + (int8_t *) MCF_FEC_FECRFDR(ch), + 0, + RX_BUF_SZ, + 0, + initiator, + FECRX_DMA_PRI(ch), + 0 + | MCD_FECRX_DMA + | MCD_INTERRUPT + | MCD_TT_FLAGS_CW + | MCD_TT_FLAGS_RL + | MCD_TT_FLAGS_SP + , + 0 + | MCD_NO_CSUM + | MCD_NO_BYTE_SWAP + ); + dbg("Rx DMA task for FEC%1d started\r\n", ch); } /* @@ -606,21 +606,21 @@ void fec_rx_start(uint8_t ch, int8_t *rxbd) */ void fec_rx_continue(uint8_t ch) { - int channel; + int channel; - /* - * Determine the DMA channel running the task for the - * selected FEC - */ - channel = dma_get_channel(DMA_FEC_RX(ch)); + /* + * Determine the DMA channel running the task for the + * selected FEC + */ + channel = dma_get_channel(DMA_FEC_RX(ch)); - dbg("RX DMA channel for FEC%1d is %d\r\n", ch, channel); + dbg("RX DMA channel for FEC%1d is %d\r\n", ch, channel); - /* - * Continue/restart the DMA task - */ - MCD_continDma(channel); - dbg("RX dma on channel %d continued\r\n", channel); + /* + * Continue/restart the DMA task + */ + MCD_continDma(channel); + dbg("RX dma on channel %d continued\r\n", channel); } /* @@ -631,35 +631,35 @@ void fec_rx_continue(uint8_t ch) */ void fec_rx_stop (uint8_t ch) { - uint32_t mask; - int channel; + uint32_t mask; + int channel; - /* Save off the EIMR value */ - mask = MCF_FEC_EIMR(ch); + /* Save off the EIMR value */ + mask = MCF_FEC_EIMR(ch); - /* Mask all interrupts */ - MCF_FEC_EIMR(ch) = 0; + /* Mask all interrupts */ + MCF_FEC_EIMR(ch) = 0; - /* - * Determine the DMA channel running the task for the - * selected FEC - */ - channel = dma_get_channel(DMA_FEC_RX(ch)); + /* + * Determine the DMA channel running the task for the + * selected FEC + */ + channel = dma_get_channel(DMA_FEC_RX(ch)); - /* Kill the FEC Rx DMA task */ - MCD_killDma(channel); + /* Kill the FEC Rx DMA task */ + MCD_killDma(channel); - /* - * Free up the FEC requestor from the software maintained - * initiator list - */ - dma_free_initiator(DMA_FEC_RX(ch)); + /* + * Free up the FEC requestor from the software maintained + * initiator list + */ + dma_free_initiator(DMA_FEC_RX(ch)); - /* Free up the DMA channel */ - dma_free_channel(DMA_FEC_RX(ch)); + /* Free up the DMA channel */ + dma_free_channel(DMA_FEC_RX(ch)); - /* Restore the interrupt mask register value */ - MCF_FEC_EIMR(ch) = mask; + /* Restore the interrupt mask register value */ + MCF_FEC_EIMR(ch) = mask; } /* @@ -673,171 +673,171 @@ void fec_rx_stop (uint8_t ch) */ void fec_rx_frame(uint8_t ch, NIF *nif) { - ETH_HDR *eth_hdr; - FECBD *pRxBD; - NBUF *cur_nbuf, *new_nbuf; - int keep; + ETH_HDR *eth_hdr; + FECBD *pRxBD; + NBUF *cur_nbuf, *new_nbuf; + int keep; - dbg("started\r\n"); + dbg("started\r\n"); - while ((pRxBD = fecbd_rx_alloc(ch)) != NULL) - { - fec_log[ch].drxf++; - keep = true; + while ((pRxBD = fecbd_rx_alloc(ch)) != NULL) + { + fec_log[ch].drxf++; + keep = true; - /* - * Check the Receive Frame Status Word for errors - * - The L bit should always be set - * - No undefined bits should be set - * - The upper 5 bits of the length should be cleared - */ - if (!(pRxBD->status & RX_BD_L) || (pRxBD->status & 0x0608) - || (pRxBD->length & 0xF800)) - { - keep = false; - fec_log[ch].rfsw_inv++; - } - else if (pRxBD->status & RX_BD_ERROR) - { - keep = false; - if (pRxBD->status & RX_BD_NO) - fec_log[ch].rfsw_no++; - if (pRxBD->status & RX_BD_CR) - fec_log[ch].rfsw_cr++; - if (pRxBD->status & RX_BD_OV) - fec_log[ch].rfsw_ov++; - if (pRxBD->status & RX_BD_TR) - fec_log[ch].rfsw_tr++; - } - else - { - if (pRxBD->status & RX_BD_LG) - fec_log[ch].rfsw_lg++; - if (pRxBD->status & RX_BD_M) - fec_log[ch].rfsw_m++; - if (pRxBD->status & RX_BD_BC) - fec_log[ch].rfsw_bc++; - if (pRxBD->status & RX_BD_MC) - fec_log[ch].rfsw_mc++; - } + /* + * Check the Receive Frame Status Word for errors + * - The L bit should always be set + * - No undefined bits should be set + * - The upper 5 bits of the length should be cleared + */ + if (!(pRxBD->status & RX_BD_L) || (pRxBD->status & 0x0608) + || (pRxBD->length & 0xF800)) + { + keep = false; + fec_log[ch].rfsw_inv++; + } + else if (pRxBD->status & RX_BD_ERROR) + { + keep = false; + if (pRxBD->status & RX_BD_NO) + fec_log[ch].rfsw_no++; + if (pRxBD->status & RX_BD_CR) + fec_log[ch].rfsw_cr++; + if (pRxBD->status & RX_BD_OV) + fec_log[ch].rfsw_ov++; + if (pRxBD->status & RX_BD_TR) + fec_log[ch].rfsw_tr++; + } + else + { + if (pRxBD->status & RX_BD_LG) + fec_log[ch].rfsw_lg++; + if (pRxBD->status & RX_BD_M) + fec_log[ch].rfsw_m++; + if (pRxBD->status & RX_BD_BC) + fec_log[ch].rfsw_bc++; + if (pRxBD->status & RX_BD_MC) + fec_log[ch].rfsw_mc++; + } - if (keep) - { - /* - * Pull the network buffer off the Rx ring queue - */ - cur_nbuf = nbuf_remove(NBUF_RX_RING); + if (keep) + { + /* + * Pull the network buffer off the Rx ring queue + */ + cur_nbuf = nbuf_remove(NBUF_RX_RING); - /* - * Copy the buffer descriptor information to the network buffer - */ - cur_nbuf->length = (pRxBD->length - (ETH_HDR_LEN + ETH_CRC_LEN)); - cur_nbuf->offset = ETH_HDR_LEN; + /* + * Copy the buffer descriptor information to the network buffer + */ + cur_nbuf->length = (pRxBD->length - (ETH_HDR_LEN + ETH_CRC_LEN)); + cur_nbuf->offset = ETH_HDR_LEN; - /* - * Get a new buffer pointer for this buffer descriptor - */ - new_nbuf = nbuf_alloc(); - if (new_nbuf == NULL) - { - dbg("nbuf_alloc() failed\n"); + /* + * Get a new buffer pointer for this buffer descriptor + */ + new_nbuf = nbuf_alloc(); + if (new_nbuf == NULL) + { + dbg("nbuf_alloc() failed\n"); - /* - * Can't allocate a new network buffer, so we - * have to trash the received data and reuse the buffer - * hoping that some buffers will free up in the system - * and this frame will be re-transmitted by the host - */ - pRxBD->length = RX_BUF_SZ; - pRxBD->status &= (RX_BD_W | RX_BD_INTERRUPT); - pRxBD->status |= RX_BD_E; - nbuf_add(NBUF_RX_RING, cur_nbuf); - fec_rx_continue(ch); + /* + * Can't allocate a new network buffer, so we + * have to trash the received data and reuse the buffer + * hoping that some buffers will free up in the system + * and this frame will be re-transmitted by the host + */ + pRxBD->length = RX_BUF_SZ; + pRxBD->status &= (RX_BD_W | RX_BD_INTERRUPT); + pRxBD->status |= RX_BD_E; + nbuf_add(NBUF_RX_RING, cur_nbuf); + fec_rx_continue(ch); - continue; - } + continue; + } - /* - * Add the new network buffer to the Rx ring queue - */ - nbuf_add(NBUF_RX_RING, new_nbuf); + /* + * Add the new network buffer to the Rx ring queue + */ + nbuf_add(NBUF_RX_RING, new_nbuf); - /* - * Re-initialize the buffer descriptor - pointing it - * to the new data buffer. The previous data buffer - * will be passed up the stack - */ - pRxBD->data = new_nbuf->data; - pRxBD->length = RX_BUF_SZ; - pRxBD->status &= (RX_BD_W | RX_BD_INTERRUPT); - pRxBD->status |= RX_BD_E; + /* + * Re-initialize the buffer descriptor - pointing it + * to the new data buffer. The previous data buffer + * will be passed up the stack + */ + pRxBD->data = new_nbuf->data; + pRxBD->length = RX_BUF_SZ; + pRxBD->status &= (RX_BD_W | RX_BD_INTERRUPT); + pRxBD->status |= RX_BD_E; - /* - * Let the DMA know that there is a new Rx BD (in case the - * ring was full and the DMA was waiting for an empty one) - */ - fec_rx_continue(ch); + /* + * Let the DMA know that there is a new Rx BD (in case the + * ring was full and the DMA was waiting for an empty one) + */ + fec_rx_continue(ch); - /* - * Get pointer to the frame data inside the network buffer - */ - eth_hdr = (ETH_HDR *) cur_nbuf->data; + /* + * Get pointer to the frame data inside the network buffer + */ + eth_hdr = (ETH_HDR *) cur_nbuf->data; - /* - * Pass the received packet up the network stack if the - * protocol is supported in our network interface (NIF) - */ - if (nif_protocol_exist(nif, eth_hdr->type)) - { - hexdump((uint8_t *) eth_hdr, ETH_MAX_FRM); - nif_protocol_handler(nif, eth_hdr->type, cur_nbuf); - } - else - { - nbuf_free(cur_nbuf); - dbg("got unsupported packet %d, trashed it\r\n", eth_hdr->type); - } - } - else - { - /* - * This frame isn't a keeper - * Reset the status and length, but don't need to get another - * buffer since we are trashing the data in the current one - */ - pRxBD->length = RX_BUF_SZ; - pRxBD->status &= (RX_BD_W | RX_BD_INTERRUPT); - pRxBD->status |= RX_BD_E; + /* + * Pass the received packet up the network stack if the + * protocol is supported in our network interface (NIF) + */ + if (nif_protocol_exist(nif, eth_hdr->type)) + { + hexdump((uint8_t *) eth_hdr, ETH_MAX_FRM); + nif_protocol_handler(nif, eth_hdr->type, cur_nbuf); + } + else + { + nbuf_free(cur_nbuf); + dbg("got unsupported packet %d, trashed it\r\n", eth_hdr->type); + } + } + else + { + /* + * This frame isn't a keeper + * Reset the status and length, but don't need to get another + * buffer since we are trashing the data in the current one + */ + pRxBD->length = RX_BUF_SZ; + pRxBD->status &= (RX_BD_W | RX_BD_INTERRUPT); + pRxBD->status |= RX_BD_E; - /* - * Move the current buffer from the beginning to the end of the - * Rx ring queue - */ - cur_nbuf = nbuf_remove(NBUF_RX_RING); - nbuf_add(NBUF_RX_RING, cur_nbuf); + /* + * Move the current buffer from the beginning to the end of the + * Rx ring queue + */ + cur_nbuf = nbuf_remove(NBUF_RX_RING); + nbuf_add(NBUF_RX_RING, cur_nbuf); - /* - * Let the DMA know that there are new Rx BDs (in case - * it is waiting for an empty one) - */ - fec_rx_continue(ch); - } - } + /* + * Let the DMA know that there are new Rx BDs (in case + * it is waiting for an empty one) + */ + fec_rx_continue(ch); + } + } } void fec0_rx_frame(void) { - extern NIF nif1; + extern NIF nif1; - fec_rx_frame(0, &nif1); + fec_rx_frame(0, &nif1); } void fec1_rx_frame(void) { - extern NIF nif1; + extern NIF nif1; - fec_rx_frame(1, &nif1); + fec_rx_frame(1, &nif1); } /* @@ -849,64 +849,64 @@ void fec1_rx_frame(void) */ void fec_tx_start(uint8_t ch, int8_t *txbd) { - uint32_t initiator; - int channel; - void fec0_tx_frame(void); - void fec1_tx_frame(void); + uint32_t initiator; + int channel; + void fec0_tx_frame(void); + void fec1_tx_frame(void); #ifdef DBG_FEC - int res; + int res; #endif - /* - * Make the initiator assignment - */ + /* + * Make the initiator assignment + */ #ifdef DBG_FEC res = #else (void) #endif dma_set_initiator(DMA_FEC_TX(ch)); - dbg("dma_set_initiator(%d) = %d\r\n", ch, res); + dbg("dma_set_initiator(%d) = %d\r\n", ch, res); - /* - * Grab the initiator number - */ - initiator = dma_get_initiator(DMA_FEC_TX(ch)); - dbg("dma_get_initiator(%d) = %d\r\n", ch, initiator); + /* + * Grab the initiator number + */ + initiator = dma_get_initiator(DMA_FEC_TX(ch)); + dbg("dma_get_initiator(%d) = %d\r\n", ch, initiator); - /* - * Determine the DMA channel running the task for the - * selected FEC - */ - channel = dma_set_channel(DMA_FEC_TX(ch), - (ch == 0) ? fec0_tx_frame : fec1_tx_frame); - dbg("dma_set_channel(%d, ...) = %d\r\n", ch, channel); + /* + * Determine the DMA channel running the task for the + * selected FEC + */ + channel = dma_set_channel(DMA_FEC_TX(ch), + (ch == 0) ? fec0_tx_frame : fec1_tx_frame); + dbg("dma_set_channel(%d, ...) = %d\r\n", ch, channel); - /* - * Start the Tx DMA task - */ - MCD_startDma(channel, - (int8_t *) txbd, - 0, - (int8_t*) MCF_FEC_FECTFDR(ch), - 0, - ETH_MTU, - 0, - initiator, - FECTX_DMA_PRI(ch), - 0 - | MCD_FECTX_DMA - | MCD_INTERRUPT - | MCD_TT_FLAGS_CW - | MCD_TT_FLAGS_RL - | MCD_TT_FLAGS_SP - , - 0 - | MCD_NO_CSUM - | MCD_NO_BYTE_SWAP - ); - dbg("DMA tx task started\r\n"); + /* + * Start the Tx DMA task + */ + MCD_startDma(channel, + (int8_t *) txbd, + 0, + (int8_t*) MCF_FEC_FECTFDR(ch), + 0, + ETH_MTU, + 0, + initiator, + FECTX_DMA_PRI(ch), + 0 + | MCD_FECTX_DMA + | MCD_INTERRUPT + | MCD_TT_FLAGS_CW + | MCD_TT_FLAGS_RL + | MCD_TT_FLAGS_SP + , + 0 + | MCD_NO_CSUM + | MCD_NO_BYTE_SWAP + ); + dbg("DMA tx task started\r\n"); } /* @@ -922,20 +922,20 @@ void fec_tx_start(uint8_t ch, int8_t *txbd) */ void fec_tx_continue(uint8_t ch) { - int channel; + int channel; - /* - * Determine the DMA channel running the task for the - * selected FEC - */ - channel = dma_get_channel(DMA_FEC_TX(ch)); - dbg("dma_get_channel(DMA_FEC_TX(%d)) = %d\r\n", ch, channel); + /* + * Determine the DMA channel running the task for the + * selected FEC + */ + channel = dma_get_channel(DMA_FEC_TX(ch)); + dbg("dma_get_channel(DMA_FEC_TX(%d)) = %d\r\n", ch, channel); - /* - * Continue/restart the DMA task - */ - MCD_continDma(channel); - dbg("DMA TX task continue\r\n"); + /* + * Continue/restart the DMA task + */ + MCD_continDma(channel); + dbg("DMA TX task continue\r\n"); } /* @@ -946,53 +946,53 @@ void fec_tx_continue(uint8_t ch) */ void fec_tx_stop(uint8_t ch) { - uint32_t mask; - int channel; + uint32_t mask; + int channel; - /* Save off the EIMR value */ - mask = MCF_FEC_EIMR(ch); + /* Save off the EIMR value */ + mask = MCF_FEC_EIMR(ch); - /* Mask all interrupts */ - MCF_FEC_EIMR(ch) = 0; + /* Mask all interrupts */ + MCF_FEC_EIMR(ch) = 0; - /* If the Ethernet is still enabled... */ - if (MCF_FEC_ECR(ch) & MCF_FEC_ECR_ETHER_EN) - { - /* Issue the Graceful Transmit Stop */ - MCF_FEC_TCR(ch) |= MCF_FEC_TCR_GTS; + /* If the Ethernet is still enabled... */ + if (MCF_FEC_ECR(ch) & MCF_FEC_ECR_ETHER_EN) + { + /* Issue the Graceful Transmit Stop */ + MCF_FEC_TCR(ch) |= MCF_FEC_TCR_GTS; - /* Wait for the Graceful Stop Complete interrupt */ - while (!(MCF_FEC_EIR(ch) & MCF_FEC_EIR_GRA)) - { - if (!(MCF_FEC_ECR(ch) & MCF_FEC_ECR_ETHER_EN)) - break; - } + /* Wait for the Graceful Stop Complete interrupt */ + while (!(MCF_FEC_EIR(ch) & MCF_FEC_EIR_GRA)) + { + if (!(MCF_FEC_ECR(ch) & MCF_FEC_ECR_ETHER_EN)) + break; + } - /* Clear the Graceful Stop Complete interrupt */ - MCF_FEC_EIR(ch) = MCF_FEC_EIR_GRA; - } + /* Clear the Graceful Stop Complete interrupt */ + MCF_FEC_EIR(ch) = MCF_FEC_EIR_GRA; + } - /* - * Determine the DMA channel running the task for the - * selected FEC - */ - channel = dma_get_channel(DMA_FEC_TX(ch)); + /* + * Determine the DMA channel running the task for the + * selected FEC + */ + channel = dma_get_channel(DMA_FEC_TX(ch)); - /* Kill the FEC Tx DMA task */ - MCD_killDma(channel); + /* Kill the FEC Tx DMA task */ + MCD_killDma(channel); - /* - * Free up the FEC requestor from the software maintained - * initiator list - */ - dma_free_initiator(DMA_FEC_TX(ch)); + /* + * Free up the FEC requestor from the software maintained + * initiator list + */ + dma_free_initiator(DMA_FEC_TX(ch)); - /* Free up the DMA channel */ - dma_free_channel(DMA_FEC_TX(ch)); + /* Free up the DMA channel */ + dma_free_channel(DMA_FEC_TX(ch)); - /* Restore the interrupt mask register value */ - MCF_FEC_EIMR(ch) = mask; + /* Restore the interrupt mask register value */ + MCF_FEC_EIMR(ch) = mask; } /* @@ -1005,46 +1005,46 @@ void fec_tx_stop(uint8_t ch) */ void fec_tx_frame(uint8_t ch) { - FECBD *pTxBD; - NBUF *pNbuf; - bool is_empty = true; + FECBD *pTxBD; + NBUF *pNbuf; + bool is_empty = true; - dbg("\r\n"); - while ((pTxBD = fecbd_tx_free(ch)) != NULL) - { - fec_log[ch].dtxf++; + dbg("\r\n"); + while ((pTxBD = fecbd_tx_free(ch)) != NULL) + { + fec_log[ch].dtxf++; - /* - * Grab the network buffer associated with this buffer descriptor - */ - pNbuf = nbuf_remove(NBUF_TX_RING); + /* + * Grab the network buffer associated with this buffer descriptor + */ + pNbuf = nbuf_remove(NBUF_TX_RING); - /* - * Free up the network buffer that was just transmitted - */ - nbuf_free(pNbuf); - dbg("free buffer %p from TX ring\r\n", pNbuf); + /* + * Free up the network buffer that was just transmitted + */ + nbuf_free(pNbuf); + dbg("free buffer %p from TX ring\r\n", pNbuf); - /* - * Re-initialize the Tx BD - */ - pTxBD->data = NULL; - pTxBD->length = 0; - is_empty = false; + /* + * Re-initialize the Tx BD + */ + pTxBD->data = NULL; + pTxBD->length = 0; + is_empty = false; - } - if (is_empty) - dbg("transmit queue was empty!\r\n"); + } + if (is_empty) + dbg("transmit queue was empty!\r\n"); } void fec0_tx_frame(void) { - fec_tx_frame(0); + fec_tx_frame(0); } void fec1_tx_frame(void) { - fec_tx_frame(1); + fec_tx_frame(1); } /* @@ -1066,58 +1066,58 @@ void fec1_tx_frame(void) */ int fec_send(uint8_t ch, NIF *nif, uint8_t *dst, uint8_t *src, uint16_t type, NBUF *nbuf) { - FECBD *pTxBD; + FECBD *pTxBD; - /* Check the length */ - if ((nbuf->length + ETH_HDR_LEN) > ETH_MTU) - { - dbg("nbuf->length (%d) + ETH_HDR_LEN (%d) exceeds ETH_MTU (%d)\r\n", - nbuf->length, ETH_HDR_LEN, ETH_MTU); - return 0; - } + /* Check the length */ + if ((nbuf->length + ETH_HDR_LEN) > ETH_MTU) + { + dbg("nbuf->length (%d) + ETH_HDR_LEN (%d) exceeds ETH_MTU (%d)\r\n", + nbuf->length, ETH_HDR_LEN, ETH_MTU); + return 0; + } - /* - * Copy the destination address, source address, and Ethernet - * type into the packet - */ - memcpy(&nbuf->data[0], dst, 6); - memcpy(&nbuf->data[6], src, 6); - memcpy(&nbuf->data[12], &type, 2); + /* + * Copy the destination address, source address, and Ethernet + * type into the packet + */ + memcpy(&nbuf->data[0], dst, 6); + memcpy(&nbuf->data[6], src, 6); + memcpy(&nbuf->data[12], &type, 2); - /* - * Grab the next available Tx Buffer Descriptor - */ - while ((pTxBD = fecbd_tx_alloc(ch)) == NULL) {}; + /* + * Grab the next available Tx Buffer Descriptor + */ + while ((pTxBD = fecbd_tx_alloc(ch)) == NULL) {}; - /* - * Put the network buffer into the Tx waiting queue - */ - nbuf_add(NBUF_TX_RING, nbuf); + /* + * Put the network buffer into the Tx waiting queue + */ + nbuf_add(NBUF_TX_RING, nbuf); - /* - * Setup the buffer descriptor for transmission - */ - pTxBD->data = nbuf->data; - pTxBD->length = nbuf->length + ETH_HDR_LEN; - pTxBD->status |= (TX_BD_R | TX_BD_L); + /* + * Setup the buffer descriptor for transmission + */ + pTxBD->data = nbuf->data; + pTxBD->length = nbuf->length + ETH_HDR_LEN; + pTxBD->status |= (TX_BD_R | TX_BD_L); - /* - * Continue the Tx DMA task (in case it was waiting for a new - * TxBD to be ready - */ - fec_tx_continue(ch); + /* + * Continue the Tx DMA task (in case it was waiting for a new + * TxBD to be ready + */ + fec_tx_continue(ch); - return 1; + return 1; } int fec0_send(NIF *nif, uint8_t *dst, uint8_t *src, uint16_t type, NBUF *nbuf) { - return fec_send(0, nif, dst, src, type, nbuf); + return fec_send(0, nif, dst, src, type, nbuf); } int fec1_send(NIF *nif, uint8_t *dst, uint8_t *src, uint16_t type, NBUF *nbuf) { - return fec_send(1, nif, dst, src, type, nbuf); + return fec_send(1, nif, dst, src, type, nbuf); } /* @@ -1130,30 +1130,30 @@ int fec1_send(NIF *nif, uint8_t *dst, uint8_t *src, uint16_t type, NBUF *nbuf) */ void fec_irq_enable(uint8_t ch, uint8_t lvl, uint8_t pri) { - /* - * Setup the appropriate ICR - */ - MCF_INTC_ICR((ch == 0) ? 39 : 38) = (uint8_t)(0 - | MCF_INTC_ICR_IP(pri) - | MCF_INTC_ICR_IL(lvl)); + /* + * Setup the appropriate ICR + */ + MCF_INTC_ICR((ch == 0) ? 39 : 38) = (uint8_t)(0 + | MCF_INTC_ICR_IP(pri) + | MCF_INTC_ICR_IL(lvl)); - /* - * Clear any pending FEC interrupt events - */ - MCF_FEC_EIR(ch) = MCF_FEC_EIR_CLEAR_ALL; + /* + * Clear any pending FEC interrupt events + */ + MCF_FEC_EIR(ch) = MCF_FEC_EIR_CLEAR_ALL; - /* - * Unmask all FEC interrupts - */ - MCF_FEC_EIMR(ch) = MCF_FEC_EIMR_UNMASK_ALL; + /* + * Unmask all FEC interrupts + */ + MCF_FEC_EIMR(ch) = MCF_FEC_EIMR_UNMASK_ALL; - /* - * Unmask the FEC interrupt in the interrupt controller - */ - if (ch == 0) - MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK39; - else - MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK38; + /* + * Unmask the FEC interrupt in the interrupt controller + */ + if (ch == 0) + MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK39; + else + MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK38; } @@ -1166,18 +1166,18 @@ void fec_irq_enable(uint8_t ch, uint8_t lvl, uint8_t pri) void fec_irq_disable(uint8_t ch) { - /* - * Mask all FEC interrupts - */ - MCF_FEC_EIMR(ch) = MCF_FEC_EIMR_MASK_ALL; + /* + * Mask all FEC interrupts + */ + MCF_FEC_EIMR(ch) = MCF_FEC_EIMR_MASK_ALL; - /* - * Mask the FEC interrupt in the interrupt controller - */ - if (ch == 0) - MCF_INTC_IMRH |= MCF_INTC_IMRH_INT_MASK39; - else - MCF_INTC_IMRH |= MCF_INTC_IMRH_INT_MASK38; + /* + * Mask the FEC interrupt in the interrupt controller + */ + if (ch == 0) + MCF_INTC_IMRH |= MCF_INTC_IMRH_INT_MASK39; + else + MCF_INTC_IMRH |= MCF_INTC_IMRH_INT_MASK38; } /* @@ -1192,100 +1192,100 @@ void fec_irq_disable(uint8_t ch) */ static void fec_irq_handler(uint8_t ch) { - uint32_t event, eir; + uint32_t event, eir; - /* - * Determine which interrupt(s) asserted by AND'ing the - * pending interrupts with those that aren't masked. - */ - eir = MCF_FEC_EIR(ch); - event = eir & MCF_FEC_EIMR(ch); + /* + * Determine which interrupt(s) asserted by AND'ing the + * pending interrupts with those that aren't masked. + */ + eir = MCF_FEC_EIR(ch); + event = eir & MCF_FEC_EIMR(ch); - if (event != eir) - dbg("pending but not enabled: 0x%08x\r\n", (event ^ eir)); + if (event != eir) + dbg("pending but not enabled: 0x%08x\r\n", (event ^ eir)); - /* - * Clear the event(s) in the EIR immediately - */ - MCF_FEC_EIR(ch) = event; + /* + * Clear the event(s) in the EIR immediately + */ + MCF_FEC_EIR(ch) = event; - if (event & MCF_FEC_EIR_RFERR) - { - fec_log[ch].total++; - fec_log[ch].rferr++; - dbg("RFERR\r\n"); - dbg("FECRFSR%d = 0x%08x\r\n", ch, MCF_FEC_FECRFSR(ch)); - //fec_eth_stop(ch); - } + if (event & MCF_FEC_EIR_RFERR) + { + fec_log[ch].total++; + fec_log[ch].rferr++; + dbg("RFERR\r\n"); + dbg("FECRFSR%d = 0x%08x\r\n", ch, MCF_FEC_FECRFSR(ch)); + //fec_eth_stop(ch); + } - if (event & MCF_FEC_EIR_XFERR) - { - fec_log[ch].total++; - fec_log[ch].xferr++; - dbg("XFERR\r\n"); - } + if (event & MCF_FEC_EIR_XFERR) + { + fec_log[ch].total++; + fec_log[ch].xferr++; + dbg("XFERR\r\n"); + } - if (event & MCF_FEC_EIR_XFUN) - { - fec_log[ch].total++; - fec_log[ch].xfun++; - dbg("XFUN\r\n"); - //fec_eth_stop(ch); - } + if (event & MCF_FEC_EIR_XFUN) + { + fec_log[ch].total++; + fec_log[ch].xfun++; + dbg("XFUN\r\n"); + //fec_eth_stop(ch); + } - if (event & MCF_FEC_EIR_RL) - { - fec_log[ch].total++; - fec_log[ch].rl++; - dbg("RL\r\n"); - } + if (event & MCF_FEC_EIR_RL) + { + fec_log[ch].total++; + fec_log[ch].rl++; + dbg("RL\r\n"); + } - if (event & MCF_FEC_EIR_LC) - { - fec_log[ch].total++; - fec_log[ch].lc++; - dbg("LC\r\n"); - } + if (event & MCF_FEC_EIR_LC) + { + fec_log[ch].total++; + fec_log[ch].lc++; + dbg("LC\r\n"); + } - if (event & MCF_FEC_EIR_MII) - { - fec_log[ch].mii++; - dbg("MII\r\n"); - } + if (event & MCF_FEC_EIR_MII) + { + fec_log[ch].mii++; + dbg("MII\r\n"); + } - if (event & MCF_FEC_EIR_TXF) - { - fec_log[ch].txf++; - dbg("TXF\r\n"); - fec_log_dump(0); - } + if (event & MCF_FEC_EIR_TXF) + { + fec_log[ch].txf++; + dbg("TXF\r\n"); + fec_log_dump(0); + } - if (event & MCF_FEC_EIR_GRA) - { - fec_log[ch].gra++; - dbg("GRA\r\n"); - } + if (event & MCF_FEC_EIR_GRA) + { + fec_log[ch].gra++; + dbg("GRA\r\n"); + } - if (event & MCF_FEC_EIR_BABT) - { - fec_log[ch].total++; - fec_log[ch].babt++; - dbg("BABT\r\n"); - } + if (event & MCF_FEC_EIR_BABT) + { + fec_log[ch].total++; + fec_log[ch].babt++; + dbg("BABT\r\n"); + } - if (event & MCF_FEC_EIR_BABR) - { - fec_log[ch].total++; - fec_log[ch].babr++; - dbg("BABR\r\n"); - } + if (event & MCF_FEC_EIR_BABR) + { + fec_log[ch].total++; + fec_log[ch].babr++; + dbg("BABR\r\n"); + } - if (event & MCF_FEC_EIR_HBERR) - { - fec_log[ch].total++; - fec_log[ch].hberr++; - dbg("HBERR\r\n"); - } + if (event & MCF_FEC_EIR_HBERR) + { + fec_log[ch].total++; + fec_log[ch].hberr++; + dbg("HBERR\r\n"); + } } /* @@ -1295,21 +1295,21 @@ static void fec_irq_handler(uint8_t ch) int fec0_interrupt_handler(void* arg1, void* arg2) { (void) arg1; /* not used */ - (void) arg2; + (void) arg2; - fec_irq_handler(0); + fec_irq_handler(0); - return 1; + return 1; } int fec1_interrupt_handler(void* arg1, void* arg2) { (void) arg1; /* not used */ - (void) arg2; + (void) arg2; - fec_irq_handler(1); + fec_irq_handler(1); - return 1; + return 1; } /* @@ -1324,60 +1324,60 @@ int fec1_interrupt_handler(void* arg1, void* arg2) */ void fec_eth_setup(uint8_t ch, uint8_t trcvr, uint8_t speed, uint8_t duplex, const uint8_t *mac) { - /* - * Disable FEC interrupts - */ - fec_irq_disable(ch); + /* + * Disable FEC interrupts + */ + fec_irq_disable(ch); - /* - * Initialize the event log - */ - fec_log_init(ch); + /* + * Initialize the event log + */ + fec_log_init(ch); - /* - * Initialize the network buffers and fec buffer descriptors - */ - nbuf_init(); - fecbd_init(ch); + /* + * Initialize the network buffers and fec buffer descriptors + */ + nbuf_init(); + fecbd_init(ch); - /* - * Initialize the FEC - */ - fec_reset(ch); - fec_init(ch, trcvr, mac); + /* + * Initialize the FEC + */ + fec_reset(ch); + fec_init(ch, trcvr, mac); - if (trcvr == FEC_MODE_MII) - { - /* - * Initialize the MII interface - */ + if (trcvr == FEC_MODE_MII) + { + /* + * Initialize the MII interface + */ #if defined(MACHINE_FIREBEE) - if (am79c874_init(0, 0, speed, duplex)) - dbg("PHY init completed\r\n"); - else - dbg("PHY init failed\r\n"); + if (am79c874_init(0, 0, speed, duplex)) + dbg("PHY init completed\r\n"); + else + dbg("PHY init failed\r\n"); #elif defined(MACHINE_M548X) - bcm_5222_init(0, 0, speed, duplex); + bcm_5222_init(0, 0, speed, duplex); #else - fec_mii_init(ch, SYSCLK / 1000); + fec_mii_init(ch, SYSCLK / 1000); #endif /* MACHINE_FIREBEE */ - } + } - /* - * Initialize and enable FEC interrupts - */ - fec_irq_enable(ch, FEC_INTC_LVL(ch), FEC_INTC_PRI(ch)); + /* + * Initialize and enable FEC interrupts + */ + fec_irq_enable(ch, FEC_INTC_LVL(ch), FEC_INTC_PRI(ch)); - /* - * Enable the multi-channel DMA tasks - */ - fec_rx_start(ch, (int8_t*) fecbd_get_start(ch, Rx)); - fec_tx_start(ch, (int8_t*) fecbd_get_start(ch, Tx)); + /* + * Enable the multi-channel DMA tasks + */ + fec_rx_start(ch, (int8_t*) fecbd_get_start(ch, Rx)); + fec_tx_start(ch, (int8_t*) fecbd_get_start(ch, Tx)); - /* - * Enable the FEC channel - */ - MCF_FEC_ECR(ch) |= MCF_FEC_ECR_ETHER_EN; + /* + * Enable the FEC channel + */ + MCF_FEC_ECR(ch) |= MCF_FEC_ECR_ETHER_EN; } /* @@ -1388,7 +1388,7 @@ void fec_eth_setup(uint8_t ch, uint8_t trcvr, uint8_t speed, uint8_t duplex, con */ void fec_eth_reset(uint8_t ch) { - // To do + // To do } @@ -1400,43 +1400,43 @@ void fec_eth_reset(uint8_t ch) */ void fec_eth_stop(uint8_t ch) { - int level; + int level; - /* - * Disable interrupts - */ - level = set_ipl(7); + /* + * Disable interrupts + */ + level = set_ipl(7); - dbg("fec %d stopped\r\n", ch); - /* - * Gracefully disable the receiver and transmitter - */ - fec_tx_stop(ch); - fec_rx_stop(ch); + dbg("fec %d stopped\r\n", ch); + /* + * Gracefully disable the receiver and transmitter + */ + fec_tx_stop(ch); + fec_rx_stop(ch); - /* - * Disable FEC interrupts - */ - fec_irq_disable(ch); + /* + * Disable FEC interrupts + */ + fec_irq_disable(ch); - /* - * Disable the FEC channel - */ - MCF_FEC_ECR(ch) &= ~MCF_FEC_ECR_ETHER_EN; + /* + * Disable the FEC channel + */ + MCF_FEC_ECR(ch) &= ~MCF_FEC_ECR_ETHER_EN; #ifdef DBG_FEC - nbuf_debug_dump(); - fec_log_dump(ch); + nbuf_debug_dump(); + fec_log_dump(ch); #endif - /* - * Flush the network buffers - */ - nbuf_flush(); + /* + * Flush the network buffers + */ + nbuf_flush(); - /* - * Restore interrupt level - */ - set_ipl(level); + /* + * Restore interrupt level + */ + set_ipl(level); } diff --git a/pci/ehci-hcd.c b/pci/ehci-hcd.c index 768dd63..36dc374 100644 --- a/pci/ehci-hcd.c +++ b/pci/ehci-hcd.c @@ -28,6 +28,7 @@ #include "cache.h" #include "usb.h" #include "ehci.h" +#include "pci.h" #define DBG_EHCI #ifdef DBG_EHCI @@ -124,6 +125,15 @@ struct pci_device_id ehci_usb_pci_table[] = 0, 0 }, /* NEC PCI OHCI module ids */ + { + PCI_VENDOR_ID_NEC, + PCI_DEVICE_ID_NEC_USB_3, + PCI_ANY_ID, + PCI_ANY_ID, + PCI_CLASS_SERIAL_USB_EHCI, + 0, + 0 + }, { PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_ISP1561_2, diff --git a/pci/ohci-hcd.c b/pci/ohci-hcd.c index c5d0ca7..6805ac0 100644 --- a/pci/ohci-hcd.c +++ b/pci/ohci-hcd.c @@ -43,17 +43,18 @@ */ -#include "wait.h" /* for wait routines */ +#include "wait.h" /* for wait_ms routines */ #include "bas_printf.h" #include "bas_string.h" /* for memset() */ #include "pci.h" +#include "interrupts.h" #undef OHCI_USE_NPS /* force NoPowerSwitching mode */ #undef OHCI_VERBOSE_DEBUG /* not always helpful */ #undef OHCI_FILL_TRACE -//#define DEBUG_OHCI +#define DEBUG_OHCI #ifdef DEBUG_OHCI #define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0) #else @@ -126,6 +127,15 @@ struct pci_device_id ohci_usb_pci_table[] = 0, 0 }, /* NEC PCI OHCI module ids */ + { + PCI_VENDOR_ID_NEC, + PCI_DEVICE_ID_NEC_USB_A, + PCI_ANY_ID, + PCI_ANY_ID, + PCI_CLASS_SERIAL_USB_OHCI, + 0, + 0 + }, /* NEC PCI OHCI module ids */ { PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_ISP1561, @@ -148,7 +158,7 @@ struct pci_device_id ohci_usb_pci_table[] = }; /* global ohci_t */ -static ohci_t gohci[2]; +static ohci_t gohci[10]; int ohci_inited; static inline uint32_t roothub_a(ohci_t *ohci) { return readl(&ohci->regs->roothub.a); } @@ -157,7 +167,6 @@ static inline uint32_t roothub_status(ohci_t *ohci) { return readl(&ohci->regs-> static inline uint32_t roothub_portstatus(ohci_t *ohci, int i) { return readl(&ohci->regs->roothub.portstatus[i]); } /* forward declaration */ -static void flush_data_cache(ohci_t *ohci); static int hc_interrupt(ohci_t *ohci); static void td_submit_job(ohci_t *ohci, struct usb_device *dev, uint32_t pipe, void *buffer, int transfer_len, struct devrequest *setup, @@ -550,10 +559,13 @@ static int sohci_submit_job(ohci_t *ohci, urb_priv_t *urb, struct devrequest *se /* link the ed into a chain if is not already */ if (ed->state != ED_OPER) + { ep_link(ohci, ed); + } /* fill the TDs and link it to the ed */ td_submit_job(ohci, dev, pipe, buffer, transfer_len, setup, purb_priv, interval); + return 0; } @@ -571,7 +583,7 @@ static inline int sohci_return_job(ohci_t *ohci, urb_priv_t *urb) readl(®s->intrenable); /* PCI posting flush */ /* call interrupt device routine */ -// dbg("irq_handle device %d", urb->dev->devnum); + dbg("irq_handle device %d", urb->dev->devnum); urb->dev->irq_handle(urb->dev); writel(OHCI_INTR_WDH, ®s->intrdisable); @@ -1374,7 +1386,7 @@ static int ohci_submit_rh_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pip #else if (ohci->irq) { - wait(10); + wait_ms(10); } #endif @@ -1462,7 +1474,7 @@ static int ohci_submit_rh_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pip OK(0); case (RH_PORT_POWER): WR_RH_PORTSTAT(RH_PS_PPS); - wait(100); + wait_ms(100); OK(0); case (RH_PORT_ENABLE): /* BUG IN HUP CODE *********/ if (RD_RH_PORTSTAT & RH_PS_CCS) @@ -1562,7 +1574,7 @@ static int ohci_submit_rh_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pip #else if (ohci->irq) { - wait(10); + wait_ms(10); } #endif @@ -1582,7 +1594,7 @@ static int ohci_submit_rh_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pip if (ohci->irq) { - wait(10); + wait_ms(10); } #endif @@ -1629,7 +1641,7 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pipe #else if (ohci->irq) { - wait(10); + wait_ms(10); } #endif @@ -1646,7 +1658,7 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pipe } #if 0 - wait(10); + wait_ms(10); /* ohci_dump_status(ohci); */ #endif @@ -1663,7 +1675,7 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pipe timeout = 1000; } - /* wait for it to complete */ + /* wait_ms for it to complete */ while (ohci->irq) { /* check whether the controller is done */ @@ -1702,13 +1714,13 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pipe if (--timeout) { - wait(10); + wait_ms(10); if (!urb->finished) - xprintf("*"); + xprintf("*\r\n"); } else { - err("OHCI usb-%s-%c CTL:TIMEOUT", ohci->slot_name, (char)ohci->controller + '0'); + err("OHCI usb-%s-%c CTL:TIMEOUT", ohci->slot_name, (char) ohci->controller + '0'); dbg("submit_common_msg: TO status %x\r\n", stat); urb->finished = 1; stat = USB_ST_CRC_ERR; @@ -1722,7 +1734,7 @@ static int submit_common_msg(ohci_t *ohci, struct usb_device *dev, uint32_t pipe pkt_print(ohci, urb, dev, pipe, buffer, transfer_len, setup, "RET(ctlr)", usb_pipein(pipe)); #else if (ohci->irq) - wait(10); + wait_ms(10); #endif /* free TDs in urb_priv */ if (!usb_pipeint(pipe)) @@ -1749,7 +1761,7 @@ int ohci_submit_control_msg(struct usb_device *dev, uint32_t pipe, void *buffer, #else if (ohci->irq) { - wait(10); + wait_ms(10); } #endif @@ -1796,7 +1808,7 @@ static int hc_reset(ohci_t *ohci) * Some multi-function controllers (e.g. ISP1562) allow root hub * resetting via EHCI registers only. */ - short index = 0; + int index = 0; long handle; do @@ -1831,7 +1843,7 @@ static int hc_reset(ohci_t *ohci) err("USB RootHub reset timed out!\r\n"); break; } - wait(1); + wait_ms(1); } } } @@ -1845,6 +1857,7 @@ static int hc_reset(ohci_t *ohci) } while (handle >= 0); } + if ((ohci->controller == 0) && (ohci->ent->vendor == PCI_VENDOR_ID_NEC) && (ohci->ent->device == PCI_DEVICE_ID_NEC_USB)) { @@ -1853,26 +1866,28 @@ static int hc_reset(ohci_t *ohci) { dbg("USB OHCI set 48MHz clock\r\n"); pci_write_config_longword(ohci->handle, 0xE4, 0x21); // oscillator & disable ehci - wait(10); + wait_us(1); } //else #else { pci_write_config_longword(ohci->handle, 0xE4, pci_read_config_longword(ohci->handle, 0xE4) | 0x01); // disable ehci - wait(10); + wait_us(1); } #endif } dbg("control: %x\r\n", readl(&ohci->regs->control)); + if (readl(&ohci->regs->control) & OHCI_CTRL_IR) { /* SMM owns the HC */ - writel(OHCI_OCR, &ohci->regs->cmdstatus);/* request ownership */ + writel(OHCI_OCR, &ohci->regs->cmdstatus); /* request ownership */ + err("USB HC TakeOver from SMM"); while (readl(&ohci->regs->control) & OHCI_CTRL_IR) { - wait(10); + wait_us(10); if (--smm_timeout == 0) { err("USB HC TakeOver failed!"); @@ -1884,17 +1899,12 @@ static int hc_reset(ohci_t *ohci) /* Disable HC interrupts */ writel(OHCI_INTR_MIE, &ohci->regs->intrdisable); -#ifdef DEBUG_OHCI - ohci_dump_status(ohci); -#endif /* DEBUG_OHCI */ - dbg("USB OHCI HC reset_hc usb-%s-%c: ctrl = 0x%X\r\n", ohci->slot_name, (char) ohci->controller + '0', readl(&ohci->regs->control)); /* Reset USB (needed by some controllers) */ ohci->hc_control = 0; writel(ohci->hc_control, &ohci->regs->control); - wait(50); /* HC Reset requires max 10 us delay */ writel(OHCI_HCR, &ohci->regs->cmdstatus); @@ -1908,12 +1918,11 @@ static int hc_reset(ohci_t *ohci) #endif /* DEBUG_OHCI */ return -1; } - wait(10); + wait_us(1); } return 0; } -/*-------------------------------------------------------------------------*/ /* * Start an OHCI controller, set the BUS operational @@ -1935,7 +1944,7 @@ static int hc_start(ohci_t *ohci) writel(0, &ohci->regs->ed_controlhead); writel(0, &ohci->regs->ed_bulkhead); - writel((uint32_t) ohci->hcca - ohci->dma_offset, &ohci->regs->hcca); /* a reset clears this */ + writel((uint32_t) ohci->hcca, &ohci->regs->hcca); /* a reset clears this */ fminterval = 0x2edf; writel((fminterval * 9) / 10, &ohci->regs->periodicstart); @@ -1951,7 +1960,8 @@ static int hc_start(ohci_t *ohci) /* disable all interrupts */ mask = (OHCI_INTR_SO | OHCI_INTR_WDH | OHCI_INTR_SF | OHCI_INTR_RD | - OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC | OHCI_INTR_OC | OHCI_INTR_MIE); + OHCI_INTR_UE | OHCI_INTR_FNO | OHCI_INTR_RHSC | + OHCI_INTR_OC | OHCI_INTR_MIE); writel(mask, &ohci->regs->intrdisable); /* clear all interrupts */ @@ -1970,9 +1980,12 @@ static int hc_start(ohci_t *ohci) #endif /* OHCI_USE_NPS */ /* POTPGT delay is bits 24-31, in 2 ms units. */ -#define mdelay(n) ({unsigned long msec = (n); while (msec--) wait(1); }) +#define mdelay(n) ({unsigned long msec = (n); while (msec--) wait_ms(1); }) + + dbg("wait_ms(0x%x)\r\n", (ohci->ndp >> 23) & 0x1fe); mdelay((ohci->ndp >> 23) & 0x1fe); - ohci->ndp &= RH_A_NDP; + + // ohci->ndp &= RH_A_NDP; /* connect the virtual root hub */ ohci->rh.devnum = 0; @@ -1981,33 +1994,7 @@ static int hc_start(ohci_t *ohci) } -#ifdef CONFIG_USB_INTERRUPT_POLLING -/* Poll USB interrupt. */ -void ohci_usb_event_poll(int interrupt) -{ - if (ohci_inited) - { - int i; - for (i = 0; i < (sizeof(gohci) / sizeof(ohci_t)); i++) - { - ohci_t *ohci = &gohci[i]; - if (!ohci->handle || ohci->disabled) - continue; - else - { - flush_data_cache(ohci); - if (interrupt) - ohci->irq = 0; - hc_interrupt(ohci); - if (interrupt) - ohci->irq = -1; - } - } - } -} - -#endif /* CONFIG_USB_INTERRUPT_POLLING */ /* * an interrupt happens @@ -2018,6 +2005,7 @@ static int hc_interrupt(ohci_t *ohci) int ints; int stat = -1; + dbg("\r\n"); if ((ohci->hcca->done_head != 0) && !(swpl(ohci->hcca->done_head) & 0x01)) { ints = OHCI_INTR_WDH; @@ -2050,18 +2038,6 @@ static int hc_interrupt(ohci_t *ohci) if (ints & OHCI_INTR_RHSC) /* root hub status change */ { -#ifdef USB_POLL_HUB - if ((queue_poll_hub != NULL) && (rh_check_port_status(ohci) >= 0)) - { - if (ohci->irq) - xQueueAltSend(queue_poll_hub, (void *)&ohci->usbnum, 0); - else - { - portBASE_TYPE xNeedSwitch = pdFALSE; - xNeedSwitch = xQueueSendFromISR(queue_poll_hub, &ohci->usbnum, xNeedSwitch); - } /* to fix xNeedSwitch usage */ - } -#endif /* USB_POLL_HUB */ stat = 0xff; } @@ -2085,7 +2061,7 @@ static int hc_interrupt(ohci_t *ohci) #else if (ohci->irq) { - wait(1); + wait_ms(1); } #endif /* HC Reset */ @@ -2099,7 +2075,7 @@ static int hc_interrupt(ohci_t *ohci) { if (ohci->irq) { - wait(1); + wait_ms(1); } writel(OHCI_INTR_WDH, ®s->intrdisable); @@ -2122,29 +2098,26 @@ static int hc_interrupt(ohci_t *ohci) { unsigned int frame = swpw(ohci->hcca->frame_no) & 1; - if (ohci->irq) - wait(1); + wait_ms(1); writel(OHCI_INTR_SF, ®s->intrdisable); if (ohci->ed_rm_list[frame] != NULL) + { writel(OHCI_INTR_SF, ®s->intrenable); + } stat = 0xff; } writel(ints, ®s->intrstatus); + return stat; } -#ifndef CONFIG_USB_INTERRUPT_POLLING - static int handle_usb_interrupt(ohci_t *ohci) { - if (!ohci->irq_enabled) + if(!ohci->irq_enabled) { - dbg("no interrupts enabled\r\n"); - return 0; } - // flush_data_cache(ohci); no need for that ohci->irq = 0; ohci->stat_irq = hc_interrupt(ohci); ohci->irq = -1; @@ -2157,11 +2130,14 @@ void ohci_usb_enable_interrupt(int enable) int i; dbg("usb_enable_interrupt(%d)", enable); - for (i = 0; i < (sizeof(gohci) / sizeof(ohci_t)); i++) + + for(i = 0; i < (sizeof(gohci) / sizeof(ohci_t)); i++) { ohci_t *ohci = &gohci[i]; - if (!ohci->handle) + if(!ohci->handle) + { continue; + } ohci->irq_enabled = enable; if (enable) writel(OHCI_INTR_MIE, &ohci->regs->intrenable); @@ -2170,15 +2146,15 @@ void ohci_usb_enable_interrupt(int enable) } } -#endif /* !CONFIG_USB_INTERRUPT_POLLING */ - /* De-allocate all resources.. */ static void hc_release_ohci(ohci_t *ohci) { - dbg("USB HC release OHCI usb-%s-%c", ohci->slot_name, (char)ohci->controller + '0'); + dbg("USB HC release OHCI usb-%s-%c", ohci->slot_name, (char) ohci->controller + '0'); if (!ohci->disabled) + { hc_reset(ohci); + } } static void hc_free_buffers(ohci_t *ohci) @@ -2206,7 +2182,7 @@ static void hc_free_buffers(ohci_t *ohci) int ohci_usb_lowlevel_init(int32_t handle, const struct pci_device_id *ent, void **priv) { uint32_t usb_base_addr = 0xFFFFFFFF; - ohci_t *ohci = &gohci[PCI_FUNCTION_FROM_HANDLE(handle) & 1]; + ohci_t *ohci = &gohci[pci_handle2index(handle)]; struct pci_rd *pci_rsc_desc = pci_get_resource(handle); /* USB OHCI */ if (handle && (ent != NULL)) @@ -2372,9 +2348,11 @@ int ohci_usb_lowlevel_init(int32_t handle, const struct pci_device_id *ent, void #ifdef DEBUG_OHCI ohci_dump(ohci, 1); #endif - pci_hook_interrupt(handle, handle_usb_interrupt, ohci); + pci_hook_interrupt(handle, (pci_interrupt_handler) handle_usb_interrupt, ohci); if (priv != NULL) + { *priv = (void *) ohci; + } ohci_inited = 1; diff --git a/pci/pci.c b/pci/pci.c index 277a7c2..196b8d9 100644 --- a/pci/pci.c +++ b/pci/pci.c @@ -33,12 +33,13 @@ #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 #define dbg(format, arg...) do { ; } while (0) #endif /* DEBUG_PCI */ +#define err(format, arg...) do { xprintf("ERROR: %s(): " format, __FUNCTION__, ##arg); } while (0) #define pci_config_wait() do { __asm__ __volatile("tpf" ::: "memory"); } while (0) @@ -122,36 +123,41 @@ static inline __attribute__((aligned(16))) void chip_errata_135(void) */ __asm__ __volatile( - " .extern __MBAR\n\t" - " clr.l d0\n\t" - " move.l d0,__MBAR+0xF0C\n\t" /* Must use direct addressing. write to EPORT module */ + " .extern __MBAR \n\t" + " clr.l d0 \n\t" + " move.l d0,__MBAR+0xF0C \n\t" /* Must use direct addressing. write to EPORT module */ /* xlbus -> slavebus -> eport, writing '0' to register */ /* has no effect */ - " rts\n\t" - " tpf.l #0x0\n\t" - " tpf.l #0x0\n\t" - " tpf.l #0x0\n\t" - " tpf.l #0x0\n\t" - " tpf.l #0x0\n\t" + " rts \n\t" + " tpf.l #0x0 \n\t" + " tpf.l #0x0 \n\t" + " tpf.l #0x0 \n\t" + " tpf.l #0x0 \n\t" + " tpf.l #0x0 \n\t" ::: "memory"); } - - -__attribute__((interrupt)) void pci_arb_interrupt(void) +static inline void chip_errata_055(int32_t handle) { - dbg("XLBARB slave error interrupt\r\n"); - MCF_XLB_XARB_SR |= ~MCF_XLB_XARB_SR_SEA; -} + uint32_t dummy; -__attribute__((interrupt)) void xlb_pci_interrupt(void) -{ - dbg("XLBPCI interrupt\r\n"); -} + return; /* test */ -__attribute__((interrupt)) void pci_interrupt(void) -{ - dbg("PCI interrupt\r\n"); + /* initiate PCI configuration access to device */ + MCF_PCI_PCICAR = MCF_PCI_PCICAR_E | /* enable configuration access special cycle */ + MCF_PCI_PCICAR_BUSNUM(3) | /* note: invalid bus number */ + MCF_PCI_PCICAR_DEVNUM(PCI_DEVICE_FROM_HANDLE(handle)) | /* device number, devices 0 - 9 are reserved */ + MCF_PCI_PCICAR_FUNCNUM(PCI_FUNCTION_FROM_HANDLE(handle)) | /* function number */ + MCF_PCI_PCICAR_DWORD(0); + + /* issue a dummy read to an unsupported bus number (will fail) */ + dummy = * (volatile uint32_t *) PCI_IO_OFFSET; /* access device */ + + /* silently clear the PCI errors we produced just now */ + MCF_PCI_PCIISR = 0xffffffff; /* clear all errors */ + MCF_PCI_PCIGSCR = MCF_PCI_PCIGSCR_PE | MCF_PCI_PCIGSCR_SE; + + (void) dummy; } /* @@ -162,14 +168,14 @@ __attribute__((interrupt)) void pci_interrupt(void) #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-function" -static int32_t pci_get_interrupt_cause(int32_t *handles) +int32_t pci_get_interrupt_cause(void) { int32_t handle; - + int32_t *hdl = &handles[0]; /* * loop through all PCI devices... */ - while ((handle = *handles++) != -1) + while ((handle = *hdl++) != -1) { uint16_t command_register = swpw(pci_read_config_word(handle, PCICR)); uint16_t status_register = swpw(pci_read_config_word(handle, PCISR)); @@ -188,7 +194,7 @@ static int32_t pci_get_interrupt_cause(int32_t *handles) return -1; } -static int32_t pci_call_interrupt_chain(int32_t handle, int32_t data) +int32_t pci_call_interrupt_chain(int32_t handle, int32_t data) { int i; @@ -205,58 +211,12 @@ static int32_t pci_call_interrupt_chain(int32_t handle, int32_t data) } #pragma GCC diagnostic pop -/* - * This gets called from irq5 in exceptions.S - * Once we arrive here, the SR has been set to disable interrupts and the gcc scratch registers have been saved - */ -void irq5_handler(void) -{ - int32_t handle; - int32_t value = 0; - int32_t newvalue; - MCF_EPORT_EPFR |= (1 << 5); /* clear interrupt from edge port */ - - xprintf("IRQ5!\r\n"); - - if ((handle = pci_get_interrupt_cause(handles)) > 0) - { - newvalue = pci_call_interrupt_chain(handle, value); - if (newvalue == value) - { - dbg("interrupt not handled!\r\n"); - } - } -} - -#ifdef MACHINE_M5484LITE -/* - * This gets called from irq7 in exceptions.S - * Once we arrive here, the SR has been set to disable interrupts and the gcc scratch registers have been saved - */ -void irq7_handler(void) -{ - int32_t handle; - int32_t value = 0; - int32_t newvalue; - - MCF_EPORT_EPFR |= (1 << 7); - dbg("IRQ7!\r\n"); - if ((handle = pci_get_interrupt_cause(handles)) > 0) - { - newvalue = pci_call_interrupt_chain(handle, value); - if (newvalue == value) - { - dbg("interrupt not handled!\r\n"); - } - } -} -#endif /* MACHINE_M548X */ /* * retrieve handle for i'th device */ -static int handle2index(int32_t handle) +int pci_handle2index(int32_t handle) { int i; @@ -287,6 +247,67 @@ static char *device_class(int classcode) return "not found"; } +/* + * do error checking after a PCI transaction + */ +static int pci_check_status(void) +{ + uint32_t pcisr; + uint32_t pcigscr; + + int ret = 0; + + pcisr = MCF_PCI_PCIISR; /* retrieve initiator status register */ + + if (pcisr & MCF_PCI_PCIISR_RE) + { + dbg("PCI initiator retry error. Cleared.\r\n"); + MCF_PCI_PCIISR |= MCF_PCI_PCIISR_RE; + + ret = 1; + } + + if (pcisr & MCF_PCI_PCIISR_IA) + { + dbg("PCI initiator abort. Error cleared\r\n"); + MCF_PCI_PCIISR |= MCF_PCI_PCIISR_IA; + + ret = 1; + } + + if (pcisr & MCF_PCI_PCIISR_TA) + { + dbg("PCI initiator target abort error. Error cleared\r\n"); + MCF_PCI_PCIISR |= MCF_PCI_PCIISR_TA; + + ret = 1; + } + + pcigscr = MCF_PCI_PCIGSCR; + + if (pcigscr & MCF_PCI_PCIGSCR_PE) + { + dbg("PCI parity error. Error cleared\r\n"); + MCF_PCI_PCIGSCR |= MCF_PCI_PCIGSCR_PE; + + ret = 1; + } + + if (pcigscr & MCF_PCI_PCIGSCR_SE) + { + dbg("PCI system error. Error cleared\r\n"); + MCF_PCI_PCIGSCR |= MCF_PCI_PCIGSCR_SE; + + ret = 1; + } + + if (!ret) + { + dbg("no error\r\n"); + } + return ret; +} + /* * read an uint32_t from configuration space of card with handle and offset * @@ -297,22 +318,23 @@ uint32_t pci_read_config_longword(int32_t handle, int offset) uint32_t value; /* initiate PCI configuration access to device */ - 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_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 */ MCF_PCI_PCICAR_FUNCNUM(PCI_FUNCTION_FROM_HANDLE(handle)) | /* function number */ MCF_PCI_PCICAR_DWORD(offset / 4); - __asm__ __volatile__("nop" ::: "memory"); /* this is what the Linux BSP does */ + NOP(); - pci_config_wait(); value = * (volatile uint32_t *) PCI_IO_OFFSET; /* access device */ - __asm__ __volatile__("tpf" ::: "memory"); /* this is what the Linux BSP does */ + NOP(); /* finish PCI configuration access special cycle (allow regular PCI accesses) */ MCF_PCI_PCICAR &= ~MCF_PCI_PCICAR_E; + pci_check_status(); + return value; } @@ -329,15 +351,17 @@ uint16_t pci_read_config_word(int32_t handle, int offset) MCF_PCI_PCICAR_FUNCNUM(PCI_FUNCTION_FROM_HANDLE(handle)) | MCF_PCI_PCICAR_DWORD(offset / 4); - __asm__ __volatile("nop" ::: "memory"); /* this is what Linux BSP does */ + NOP(); value = * (volatile uint16_t *) PCI_IO_OFFSET + (offset & 2); - __asm__ __volatile("tpf" ::: "memory"); + NOP(); /* finish PCI configuration access special cycle */ MCF_PCI_PCICAR &= ~MCF_PCI_PCICAR_E; + pci_check_status(); + return value; } @@ -352,14 +376,16 @@ uint8_t pci_read_config_byte(int32_t handle, int offset) MCF_PCI_PCICAR_FUNCNUM(PCI_FUNCTION_FROM_HANDLE(handle)) | /* function number */ MCF_PCI_PCICAR_DWORD(offset / 4); - __asm__ __volatile__("nop" ::: "memory"); + NOP(); value = * (volatile uint8_t *) (PCI_IO_OFFSET + (offset & 3)); - __asm__ __volatile__("tpf" ::: "memory"); + NOP(); MCF_PCI_PCICAR &= ~MCF_PCI_PCICAR_E; + pci_check_status(); + return value; } @@ -376,18 +402,18 @@ int32_t pci_write_config_longword(int32_t handle, int offset, uint32_t value) MCF_PCI_PCICAR_DEVNUM(PCI_DEVICE_FROM_HANDLE(handle)) | /* device number, devices 0 - 9 are reserved */ MCF_PCI_PCICAR_FUNCNUM(PCI_FUNCTION_FROM_HANDLE(handle)) | /* function number */ MCF_PCI_PCICAR_DWORD(offset / 4); - chip_errata_135(); - __asm__ __volatile__("nop" ::: "memory"); + NOP(); * (volatile uint32_t *) PCI_IO_OFFSET = value; /* access device */ chip_errata_135(); - __asm__ __volatile__("tpf" ::: "memory"); + NOP(); /* finish configuration space access cycle */ MCF_PCI_PCICAR &= ~MCF_PCI_PCICAR_E; - chip_errata_135(); + + pci_check_status(); return PCI_SUCCESSFUL; } @@ -405,16 +431,15 @@ int32_t pci_write_config_word(int32_t handle, int offset, uint16_t value) MCF_PCI_PCICAR_DWORD(offset / 4); chip_errata_135(); - __asm__ __volatile__("tpf" ::: "memory"); + NOP(); * (volatile uint16_t *) (PCI_IO_OFFSET + (offset & 2)) = value; chip_errata_135(); - __asm__ __volatile__("tpf" ::: "memory"); - /* finish configuration space access cycle */ MCF_PCI_PCICAR &= ~MCF_PCI_PCICAR_E; - chip_errata_135(); + + pci_check_status(); return PCI_SUCCESSFUL; } @@ -431,7 +456,7 @@ int32_t pci_write_config_byte(int32_t handle, int offset, uint8_t value) MCF_PCI_PCICAR_DWORD(offset / 4); chip_errata_135(); - __asm__ __volatile__("tpf" ::: "memory"); + NOP(); * (volatile uint8_t *) (PCI_IO_OFFSET + (offset & 3)) = value; chip_errata_135(); @@ -441,7 +466,7 @@ int32_t pci_write_config_byte(int32_t handle, int offset, uint8_t value) /* finish configuration space access cycle */ MCF_PCI_PCICAR &= ~MCF_PCI_PCICAR_E; - chip_errata_135(); + pci_check_status(); return PCI_SUCCESSFUL; } @@ -455,11 +480,15 @@ struct pci_rd *pci_get_resource(int32_t handle) int index = -1; struct pci_rd *ret; - index = handle2index(handle); + index = pci_handle2index(handle); if (index == -1) + { ret = NULL; + } else + { ret = &resource_descriptors[index][0]; + } dbg("pci_get_resource: resource struct for handle %lx (index %d) is at %p\r\n", handle, index, ret); @@ -840,7 +869,7 @@ static void pci_device_config(uint16_t bus, uint16_t device, uint16_t function) handle = PCI_HANDLE(bus, device, function); /* find index into resource descriptor table for handle */ - index = handle2index(handle); + index = pci_handle2index(handle); if (index == -1) { @@ -992,9 +1021,11 @@ static void pci_device_config(uint16_t bus, uint16_t device, uint16_t function) il = pci_read_config_byte(handle, PCIIPR); dbg("device requests interrupts on interrupt pin %d\r\n", il); - /* if so, register interrupts */ + /* enable interrupt on PCI device */ - /* TODO: register interrupts here */ + il = pci_read_config_byte(handle, PCICR); + il &= ~PCICSR_INT_DISABLE; + pci_write_config_byte(handle, PCICR, il); /* * enable device memory or I/O access @@ -1133,18 +1164,13 @@ void init_pci(void) xprintf("initializing PCI bridge:\r\n"); (void) res; /* for now */ - res = register_interrupt_handler(0, INT_SOURCE_PCIARB, 5, 5, pci_arb_interrupt); - dbg("registered interrupt handler for PCI arbiter: %s\r\n", - (res < 0 ? "failed" : "succeeded")); - register_interrupt_handler(0, INT_SOURCE_XLBPCI, 5, 5, xlb_pci_interrupt); - dbg("registered interrupt handler for XLB PCI: %s\r\n", - (res < 0 ? "failed" : "succeeded")); init_eport(); init_xlbus_arbiter(); MCF_PCI_PCIGSCR = 1; /* reset PCI */ +#ifdef _NOT_USED_ /* * setup the PCI arbiter */ @@ -1152,6 +1178,7 @@ void init_pci(void) | MCF_PCIARB_PACR_EXTMPRI(0xf) /* external master priority: high */ | MCF_PCIARB_PACR_INTMINTEN /* enable "internal master broken" interrupt */ | MCF_PCIARB_PACR_EXTMINTEN(0x0f); /* enable "external master broken" interrupt */ +#endif #ifdef _NOT_USED_ /* since this is already done in sysinit.c */ #if MACHINE_FIREBEE @@ -1173,18 +1200,18 @@ void init_pci(void) /* Setup burst parameters */ MCF_PCI_PCICR1 = MCF_PCI_PCICR1_CACHELINESIZE(8) | MCF_PCI_PCICR1_LATTIMER(0xff); /* TODO: test increased latency timer */ -#ifdef _NOT_USED_ + MCF_PCI_PCICR2 = MCF_PCI_PCICR2_MINGNT(1) | MCF_PCI_PCICR2_MAXLAT(32); -#endif /* _NOT_USED_ */ - MCF_PCI_PCICR2 = 0; /* this is what Linux does */ + + // MCF_PCI_PCICR2 = 0; /* this is what Linux does */ /* error signaling */ -#ifdef NOT_USED + MCF_PCI_PCIICR = MCF_PCI_PCIICR_TAE | /* target abort enable */ MCF_PCI_PCIICR_IAE; /* initiator abort enable */ -#endif /* NOT_USED */ - MCF_PCI_PCIICR = 0; /* this is what Linux does */ + + // MCF_PCI_PCIICR = 0; /* this is what Linux does */ MCF_PCI_PCIGSCR |= MCF_PCI_PCIGSCR_SEE; /* system error interrupt enable */ @@ -1194,20 +1221,21 @@ void init_pci(void) MCF_PCI_PCIIW0BTAR = (PCI_MEMORY_OFFSET | (((PCI_MEMORY_SIZE - 1) >> 8) & 0xffff0000)) | ((PCI_MEMORY_OFFSET >> 16) & 0xff00); + NOP(); dbg("PCIIW0BTAR=0x%08x\r\n", MCF_PCI_PCIIW0BTAR); /* initiator window 1 base / translation adress register */ MCF_PCI_PCIIW1BTAR = (PCI_IO_OFFSET | ((PCI_IO_SIZE - 1) >> 8)) & 0xffff0000; - + NOP(); /* initiator window 2 base / translation address register */ MCF_PCI_PCIIW2BTAR = 0L; /* not used */ - + NOP(); /* initiator window configuration register */ MCF_PCI_PCIIWCR = MCF_PCI_PCIIWCR_WINCTRL0_MEMRDLINE | MCF_PCI_PCIIWCR_WINCTRL1_IO | MCF_PCI_PCIIWCR_WINCTRL0_E | MCF_PCI_PCIIWCR_WINCTRL1_E; - + NOP(); /* * Initialize target control register. * Used when an external bus master accesses the Coldfire PCI as target @@ -1219,7 +1247,7 @@ void init_pci(void) /* reset PCI devices */ MCF_PCI_PCIGSCR &= ~MCF_PCI_PCIGSCR_PR; - do {;} while (MCF_PCI_PCIGSCR & MCF_PCI_PCIGSCR_PR); /* wait until reset finished */ + do { NOP(); } while (MCF_PCI_PCIGSCR & MCF_PCI_PCIGSCR_PR); /* wait until reset finished */ xprintf("finished\r\n"); /* initialize/clear resource descriptor table */ @@ -1235,7 +1263,7 @@ void init_pci(void) * give devices a chance to come up befor attempting to configure them, * necessary to properly detect the FireBee USB chip */ - wait(600000); + wait_ms(400); /* * do normal initialization diff --git a/sys/BaS.c b/sys/BaS.c index 8e520a3..83e3198 100644 --- a/sys/BaS.c +++ b/sys/BaS.c @@ -48,6 +48,8 @@ #include "interrupts.h" #include "exceptions.h" #include "net_timer.h" +#include "pci.h" +#include "video.h" //#define BAS_DEBUG #if defined(BAS_DEBUG) @@ -76,10 +78,10 @@ extern uint8_t _EMUTOS_SIZE[]; */ static inline bool pic_txready(void) { - if (MCF_PSC3_PSCSR & MCF_PSC_PSCSR_TXRDY) - return true; + if (MCF_PSC3_PSCSR & MCF_PSC_PSCSR_TXRDY) + return true; - return false; + return false; } /* @@ -87,84 +89,84 @@ static inline bool pic_txready(void) */ static inline bool pic_rxready(void) { - if (MCF_PSC3_PSCSR & MCF_PSC_PSCSR_RXRDY) - return true; + if (MCF_PSC3_PSCSR & MCF_PSC_PSCSR_RXRDY) + return true; - return false; + return false; } void write_pic_byte(uint8_t value) { - /* Wait until the transmitter is ready or 1000us are passed */ - waitfor(1000, pic_txready); + /* Wait until the transmitter is ready or 1000us are passed */ + waitfor(1000, pic_txready); - /* Transmit the byte */ - *(volatile uint8_t*)(&MCF_PSC3_PSCTB_8BIT) = value; // Really 8-bit + /* Transmit the byte */ + *(volatile uint8_t*)(&MCF_PSC3_PSCTB_8BIT) = value; // Really 8-bit } uint8_t read_pic_byte(void) { - /* Wait until a byte has been received or 1000us are passed */ - waitfor(1000, pic_rxready); + /* Wait until a byte has been received or 1000us are passed */ + waitfor(1000, pic_rxready); - /* Return the received byte */ - return * (volatile uint8_t *) (&MCF_PSC3_PSCTB_8BIT); // Really 8-bit + /* Return the received byte */ + return * (volatile uint8_t *) (&MCF_PSC3_PSCTB_8BIT); // Really 8-bit } void pic_init(void) { - char answer[4] = "OLD"; + char answer[4] = "OLD"; - xprintf("initialize the PIC: "); + xprintf("initialize the PIC: "); - /* Send the PIC initialization string */ - write_pic_byte('A'); - write_pic_byte('C'); - write_pic_byte('P'); - write_pic_byte('F'); + /* Send the PIC initialization string */ + write_pic_byte('A'); + write_pic_byte('C'); + write_pic_byte('P'); + write_pic_byte('F'); - /* Read the 3-char answer string. Should be "OK!". */ - answer[0] = read_pic_byte(); - answer[1] = read_pic_byte(); - answer[2] = read_pic_byte(); - answer[3] = '\0'; + /* Read the 3-char answer string. Should be "OK!". */ + answer[0] = read_pic_byte(); + answer[1] = read_pic_byte(); + answer[2] = read_pic_byte(); + answer[3] = '\0'; - if (answer[0] != 'O' || answer[1] != 'K' || answer[2] != '!') - { - dbg("PIC initialization failed. Already initialized?\r\n"); - } - else - { - xprintf("%s\r\n", answer); - } + if (answer[0] != 'O' || answer[1] != 'K' || answer[2] != '!') + { + dbg("PIC initialization failed. Already initialized?\r\n"); + } + else + { + xprintf("%s\r\n", answer); + } } void nvram_init(void) { - int i; + int i; - xprintf("Restore the NVRAM data: "); + xprintf("Restore the NVRAM data: "); - /* Request for NVRAM backup data */ - write_pic_byte(0x01); + /* Request for NVRAM backup data */ + write_pic_byte(0x01); - /* Check answer type */ - if (read_pic_byte() != 0x81) - { - // FIXME: PIC protocol error - xprintf("FAILED\r\n"); - return; - } + /* Check answer type */ + if (read_pic_byte() != 0x81) + { + // FIXME: PIC protocol error + xprintf("FAILED\r\n"); + return; + } - /* Restore the NVRAM backup to the FPGA */ - for (i = 0; i < 64; i++) - { - uint8_t data = read_pic_byte(); - *(volatile uint8_t*)0xffff8961 = i; - *(volatile uint8_t*)0xffff8963 = data; - } + /* Restore the NVRAM backup to the FPGA */ + for (i = 0; i < 64; i++) + { + uint8_t data = read_pic_byte(); + *(volatile uint8_t*)0xffff8961 = i; + *(volatile uint8_t*)0xffff8963 = data; + } - xprintf("finished\r\n"); + xprintf("finished\r\n"); } #define KBD_ACIA_CONTROL ((uint8_t *) 0xfffffc00) @@ -174,70 +176,77 @@ void nvram_init(void) void acia_init() { - xprintf("init ACIA: "); - /* init ACIA */ - * KBD_ACIA_CONTROL = 3; /* master reset */ - NOP(); + xprintf("init ACIA: "); + /* init ACIA */ + * KBD_ACIA_CONTROL = 3; /* master reset */ + NOP(); - * MIDI_ACIA_CONTROL = 3; /* master reset */ - NOP(); + * MIDI_ACIA_CONTROL = 3; /* master reset */ + NOP(); - * KBD_ACIA_CONTROL = 0x96; /* clock div = 64, 8N1, RTS low, TX int disable, RX int enable */ - NOP(); + * KBD_ACIA_CONTROL = 0x96; /* clock div = 64, 8N1, RTS low, TX int disable, RX int enable */ + NOP(); - * MFP_INTR_IN_SERVICE_A = -1; - NOP(); + * MFP_INTR_IN_SERVICE_A = -1; + NOP(); - * MFP_INTR_IN_SERVICE_B = -1; - NOP(); + * MFP_INTR_IN_SERVICE_B = -1; + NOP(); - xprintf("finished\r\n"); + xprintf("finished\r\n"); } -/* ACP interrupt controller */ -#define FPGA_INTR_CONTRL (volatile uint32_t *) 0xf0010000 -#define FPGA_INTR_ENABLE (volatile uint8_t *) 0xf0010004 -#define FPGA_INTR_PENDIN (volatile uint32_t *) 0xf0010008 - void enable_coldfire_interrupts() { - xprintf("enable interrupts: "); + xprintf("enable interrupts: "); #if defined(MACHINE_FIREBEE) - *FPGA_INTR_CONTRL = 0L; /* disable all interrupts */ + *FPGA_INTR_CONTROL = 0L; /* disable all interrupts */ #endif /* MACHINE_FIREBEE */ - MCF_EPORT_EPPAR = 0xaaa8; /* all interrupts on falling edge */ + + MCF_EPORT_EPPAR = 0xaaa8; /* all interrupts on falling edge */ #if defined(MACHINE_FIREBEE) - /* - * TIN0 on the Coldfire is connected to the FPGA. TIN0 triggers every write - * access to 0xff8201 (vbasehi), i.e. everytime the video base address is written - */ - MCF_GPT0_GMS = MCF_GPT_GMS_ICT(1) | /* timer 0 on, video change capture on rising edge */ - MCF_GPT_GMS_IEN | - MCF_GPT_GMS_TMS(1); - /* route GPT0 interrupt on interrupt controller */ - MCF_INTC_ICR62 = 0x3f; /* interrupt level 7, interrupt priority 7 */ + /* + * TIN0 on the Coldfire is connected to the FPGA. TIN0 triggers every write + * access to 0xff8201 (vbasehi), i.e. everytime the video base address is written + */ + MCF_GPT0_GMS = MCF_GPT_GMS_ICT(1) | /* timer 0 on, video change capture on rising edge */ + MCF_GPT_GMS_IEN | + MCF_GPT_GMS_TMS(1); + /* route GPT0 interrupt on interrupt controller */ + MCF_INTC_ICR62 = 0x3f; /* interrupt level 7, interrupt priority 7 */ - *FPGA_INTR_ENABLE = 0xfe; /* enable int 1-7 */ - MCF_EPORT_EPIER = 0xfe; /* int 1-7 on */ - MCF_EPORT_EPFR = 0xff; /* clear all pending interrupts */ - MCF_INTC_IMRL = 0xffffff00; /* int 1-7 on */ - MCF_INTC_IMRH = 0xbffffffe; /* psc3 and timer 0 int on */ + + MCF_EPORT_EPIER = 0xfe; /* int 1-7 on */ + MCF_EPORT_EPFR = 0xff; /* clear all pending interrupts */ + MCF_INTC_IMRL = 0xffffff00; /* int 1-7 on */ + MCF_INTC_IMRH = 0xbffffffe; /* psc3 and timer 0 int on */ + *FPGA_INTR_ENABLE = FPGA_INTR_INT_IRQ7 | + FPGA_INTR_INT_MFP_IRQ6 | + FPGA_INTR_INT_FPGA_IRQ5 | + FPGA_INTR_INT_VSYNC_IRQ4 | + FPGA_INTR_INT_CTR0_IRQ3 | + FPGA_INTR_INT_HSYNC_IRQ2 | + FPGA_INTR_PCI_INTA | + FPGA_INTR_PCI_INTB | + FPGA_INTR_PCI_INTC | + FPGA_INTR_PCI_INTD | + FPGA_INTR_ETHERNET; #endif - xprintf("finished\r\n"); + xprintf("finished\r\n"); } void disable_coldfire_interrupts() { #if defined(MACHINE_FIREBEE) - *FPGA_INTR_ENABLE = 0; /* disable all interrupts */ + *FPGA_INTR_ENABLE = 0; /* disable all interrupts */ #endif /* MACHINE_FIREBEE */ - MCF_EPORT_EPIER = 0x0; - MCF_EPORT_EPFR = 0x0; - MCF_INTC_IMRL = 0xfffffffe; - MCF_INTC_IMRH = 0xffffffff; + MCF_EPORT_EPIER = 0x0; + MCF_EPORT_EPFR = 0x0; + MCF_INTC_IMRL = 0xfffffffe; + MCF_INTC_IMRH = 0xffffffff; } @@ -252,178 +261,175 @@ NIF nif2; */ void init_isr(void) { - isr_init(); /* need to call that explicitely, otherwise isr table might be full */ + isr_init(); /* need to call that explicitely, otherwise isr table might be full */ - /* - * register the FEC interrupt handler - */ - if (!isr_register_handler(64 + INT_SOURCE_FEC0, fec0_interrupt_handler, NULL, (void *) &nif1)) - { - dbg("unable to register isr for FEC0\r\n"); - return; - } + /* + * register the FEC interrupt handler + */ + if (!isr_register_handler(64 + INT_SOURCE_FEC0, fec0_interrupt_handler, NULL, (void *) &nif1)) + { + dbg("unable to register isr for FEC0\r\n"); + return; + } - /* - * Register the DMA interrupt handler - */ + /* + * Register the DMA interrupt handler + */ - if (!isr_register_handler(64 + INT_SOURCE_DMA, dma_interrupt_handler, NULL,NULL)) - { - dbg("Error: Unable to register isr for DMA\r\n"); - return; - } + if (!isr_register_handler(64 + INT_SOURCE_DMA, dma_interrupt_handler, NULL,NULL)) + { + dbg("Error: Unable to register isr for DMA\r\n"); + return; + } - dma_irq_enable(5, 3); /* TODO: need to match the FEC driver's specs in MiNT? */ + dma_irq_enable(5, 3); /* TODO: need to match the FEC driver's specs in MiNT? */ - /* - * register the PIC interrupt handler - */ - if (isr_register_handler(64 + INT_SOURCE_PSC3, pic_interrupt_handler, NULL, NULL)) - { - dbg("Error: unable to register ISR for PSC3\r\n"); - return; - } + /* + * register the PIC interrupt handler + */ + if (isr_register_handler(64 + INT_SOURCE_PSC3, pic_interrupt_handler, NULL, NULL)) + { + dbg("Error: unable to register ISR for PSC3\r\n"); + return; + } + + /* + * register the XLB PCI interrupt handler + */ + if (!isr_register_handler(64 + INT_SOURCE_XLBPCI, xlbpci_interrupt_handler, NULL, NULL)) + { + dbg("Error: unable to register isr for XLB PIC interrupts\r\n"); + return; + } + MCF_XLB_XARB_IMR = MCF_XLB_XARB_IMR_SEAE | /* slave error acknowledge interrupt */ + MCF_XLB_XARB_IMR_MME | /* multiple master at prio 0 interrupt */ + MCF_XLB_XARB_IMR_TTAE | /* TT address only interrupt */ + MCF_XLB_XARB_IMR_TTRE | /* TT reserved interrupt enable */ + MCF_XLB_XARB_IMR_ECWE | /* external control word interrupt */ + MCF_XLB_XARB_IMR_TTME | /* TBST/TSIZ mismatch interrupt */ + MCF_XLB_XARB_IMR_BAE; /* bus activity tenure timeout interrupt */ + + if (!isr_register_handler(64 + INT_SOURCE_PCIARB, pciarb_interrupt_handler, NULL, NULL)) + { + dbg("Error: unable to register isr for PCIARB interrupts\r\n"); + + return; + } + MCF_PCIARB_PACR = MCF_PCIARB_PACR_EXTMINTEN(0x1f) | /* external master broken interrupt */ + MCF_PCIARB_PACR_INTMINTEN; /* internal master broken interrupt */ } void BaS(void) { - uint8_t *src; - uint8_t *dst = (uint8_t *) TOS; + uint8_t *src; + uint8_t *dst = (uint8_t *) TOS; #if defined(MACHINE_FIREBEE) /* LITE board has no pic and (currently) no nvram */ - pic_init(); - nvram_init(); + pic_init(); + nvram_init(); #endif /* MACHINE_FIREBEE */ - xprintf("copy EmuTOS: "); + xprintf("copy EmuTOS: "); - /* copy EMUTOS */ - src = (uint8_t *) EMUTOS; - dma_memcpy(dst, src, EMUTOS_SIZE); - xprintf("finished\r\n"); + /* copy EMUTOS */ + src = (uint8_t *) EMUTOS; + dma_memcpy(dst, src, EMUTOS_SIZE); + xprintf("finished\r\n"); - xprintf("initialize MMU: "); - mmu_init(); - xprintf("finished\r\n"); + xprintf("initialize MMU: "); + mmu_init(); + xprintf("finished\r\n"); - xprintf("initialize exception vector table: "); - vec_init(); - xprintf("finished\r\n"); + xprintf("initialize exception vector table: "); + vec_init(); + xprintf("finished\r\n"); - xprintf("flush caches: "); - flush_and_invalidate_caches(); - xprintf("finished\r\n"); - xprintf("enable MMU: "); - MCF_MMU_MMUCR = MCF_MMU_MMUCR_EN; /* MMU on */ - NOP(); /* force pipeline sync */ - xprintf("finished\r\n"); + xprintf("flush caches: "); + flush_and_invalidate_caches(); + xprintf("finished\r\n"); + xprintf("enable MMU: "); + MCF_MMU_MMUCR = MCF_MMU_MMUCR_EN; /* MMU on */ + NOP(); /* force pipeline sync */ + xprintf("finished\r\n"); - #ifdef MACHINE_FIREBEE - xprintf("IDE reset: "); - /* IDE reset */ - * (volatile uint8_t *) (0xffff8802 - 2) = 14; - * (volatile uint8_t *) (0xffff8802 - 0) = 0x80; - wait(1); + #ifdef MACHINE_FIREBEE + xprintf("IDE reset: "); + /* IDE reset */ + * (volatile uint8_t *) (0xffff8802 - 2) = 14; + * (volatile uint8_t *) (0xffff8802 - 0) = 0x80; + wait(1); - * (volatile uint8_t *) (0xffff8802 - 0) = 0; + * (volatile uint8_t *) (0xffff8802 - 0) = 0; - xprintf("finished\r\n"); - xprintf("enable video: "); - /* - * video setup (25MHz) - */ - * (volatile uint32_t *) (0xf0000410 + 0) = 0x032002ba; /* horizontal 640x480 */ - * (volatile uint32_t *) (0xf0000410 + 4) = 0x020c020a; /* vertical 640x480 */ - * (volatile uint32_t *) (0xf0000410 + 8) = 0x0190015d; /* horizontal 320x240 */ - * (volatile uint32_t *) (0xf0000410 + 12) = 0x020C020A; /* vertical 320x230 */ + xprintf("finished\r\n"); + xprintf("enable video: "); + /* + * video setup (25MHz) + */ + * (volatile uint32_t *) (0xf0000410 + 0) = 0x032002ba; /* horizontal 640x480 */ + * (volatile uint32_t *) (0xf0000410 + 4) = 0x020c020a; /* vertical 640x480 */ + * (volatile uint32_t *) (0xf0000410 + 8) = 0x0190015d; /* horizontal 320x240 */ + * (volatile uint32_t *) (0xf0000410 + 12) = 0x020C020A; /* vertical 320x230 */ -#ifdef _NOT_USED_ -// 32MHz - * (volatile uint32_t *) (0xf0000410 + 0) = 0x037002ba; /* horizontal 640x480 */ - * (volatile uint32_t *) (0xf0000410 + 4) = 0x020d020a; /* vertical 640x480 */ - * (volatile uint32_t *) (0xf0000410 + 8) = 0x02a001e0; /* horizontal 320x240 */ - * (volatile uint32_t *) (0xf0000410 + 12) = 0x05a00160; /* vertical 320x230 */ -#endif /* _NOT_USED_ */ - - /* fifo on, refresh on, ddrcs and cke on, video dac on */ - * (volatile uint32_t *) (0xf0000410 - 0x20) = 0x01070002; - - xprintf("finished\r\n"); - - enable_coldfire_interrupts(); - -#ifdef _NOT_USED_ - screen_init(); - - /* experimental */ - { - int i; - uint32_t *scradr = 0xd00000; - - for (i = 0; i < 100; i++) - { - uint32_t *p = scradr; - - for (p = scradr; p < scradr + 1024 * 150L; p++) - { - *p = 0xffffffff; - } - - for (p = scradr; p < scradr + 1024 * 150L; p++) - { - *p = 0x0; - } - } - } -#endif /* _NOT_USED_ */ + /* fifo on, refresh on, ddrcs and cke on, video dac on */ + * (volatile uint32_t *) (0xf0000410 - 0x20) = 0x01070002; + xprintf("finished\r\n"); #endif /* MACHINE_FIREBEE */ - sd_card_init(); + sd_card_init(); - /* - * memory setup - */ - memset((void *) 0x400, 0, 0x400); + /* + * memory setup + */ + memset((void *) 0x400, 0, 0x400); #if defined(MACHINE_FIREBEE) - /* set Falcon bus control register */ - /* sets bit 3 and 6. Both are undefined on an original Falcon? */ + /* set Falcon bus control register */ + /* sets bit 3 and 6. Both are undefined on an original Falcon? */ - * (volatile uint8_t *) 0xffff8007 = 0x48; + * (volatile uint8_t *) 0xffff8007 = 0x48; #endif /* MACHINE_FIREBEE */ - /* ST RAM */ + /* ST RAM */ - * (uint32_t *) 0x42e = STRAM_END; /* phystop TOS system variable */ - * (uint32_t *) 0x420 = 0x752019f3; /* memvalid TOS system variable */ - * (uint32_t *) 0x43a = 0x237698aa; /* memval2 TOS system variable */ - * (uint32_t *) 0x51a = 0x5555aaaa; /* memval3 TOS system variable */ + * (uint32_t *) 0x42e = STRAM_END; /* phystop TOS system variable */ + * (uint32_t *) 0x420 = 0x752019f3; /* memvalid TOS system variable */ + * (uint32_t *) 0x43a = 0x237698aa; /* memval2 TOS system variable */ + * (uint32_t *) 0x51a = 0x5555aaaa; /* memval3 TOS system variable */ - /* TT-RAM */ + /* TT-RAM */ - * (uint32_t *) 0x5a4 = FASTRAM_END; /* ramtop TOS system variable */ - * (uint32_t *) 0x5a8 = 0x1357bd13; /* ramvalid TOS system variable */ + * (uint32_t *) 0x5a4 = FASTRAM_END; /* ramtop TOS system variable */ + * (uint32_t *) 0x5a8 = 0x1357bd13; /* ramvalid TOS system variable */ #if defined(MACHINE_FIREBEE) /* m5484lite has no ACIA and no dip switch... */ - acia_init(); + acia_init(); #endif /* MACHINE_FIREBEE */ - srec_execute("BASFLASH.S19"); + srec_execute("BASFLASH.S19"); - /* Jump into the OS */ - typedef void void_func(void); - struct rom_header - { - void *initial_sp; - void_func *initial_pc; - }; + /* Jump into the OS */ + typedef void void_func(void); + struct rom_header + { + void *initial_sp; + void_func *initial_pc; + }; - xprintf("BaS initialization finished, enable interrupts\r\n"); - enable_coldfire_interrupts(); - init_isr(); + xprintf("BaS initialization finished, enable interrupts\r\n"); + init_isr(); + enable_coldfire_interrupts(); + init_pci(); + video_init(); + set_ipl(0); /* enable interrupts */ - xprintf("call EmuTOS\r\n"); - struct rom_header *os_header = (struct rom_header *) TOS; - os_header->initial_pc(); + /* initialize USB devices */ + init_usb(); + + //set_ipl(7); /* disable interrupts */ + + xprintf("call EmuTOS\r\n"); + struct rom_header *os_header = (struct rom_header *) TOS; + os_header->initial_pc(); } diff --git a/sys/exceptions.S b/sys/exceptions.S index cf39f72..fffe98a 100644 --- a/sys/exceptions.S +++ b/sys/exceptions.S @@ -216,6 +216,9 @@ init_vec_loop: // install lowlevel_isr_handler for the PSC3 interrupt move.l a1,(INT_SOURCE_PSC3 + 64) * 4(a0) +// install lowlevel_isr_handler for the XLBPCI interrupt + move.l a1,(INT_SOURCE_XLBPCI + 64) * 4(a0) + #ifndef MACHINE_FIREBEE // FEC1 not wired on the FireBee, but used on other machines move.l a1,(INT_SOURCE_FEC1 + 64) * 4(a0) @@ -429,10 +432,65 @@ irq7text: .text #elif MACHINE_FIREBEE /* these handlers are only meaningful for the Firebee */ -irq5: - irq 0x74,5,0x20 -irq6: // MFP interrupt from FPGA +irq5: move.w #0x2700,sr // disable interrupts + subq.l #4,sp // extra space + + link a6,#-4 * 4 // save gcc scratch registers + movem.l d0-d1/a0-a1,(sp) + + jsr _irq5_handler // call C handler routine + + tst.l d0 // handled? + bne irq5_forward + + movem.l (sp),d0-d1/a0-a1 // restore registers + unlk a6 + addq.l #4,sp + + rte // return from exception + +irq5_forward: move.l 0x74,a0 // fetch OS irq5 vector + add.l _rt_vbr,a0 // add runtime vbr + move.l a0,4(a6) // put on stack + + movem.l (sp),d0-d1/a0-a1 // restore registers + unlk a6 // + move.w #0x2500,sr // set interrupt level + rts // jump through vector + + +irq6: move.w #0x2700,sr // disable interrupt + subq.l #4,sp // extra space + link a6,#-4 * 4 // save gcc scratch registers + movem.l d0-d1/a0-a1,(sp) + + move.l 4(a6),-(sp) // format status word + move.l 8(a6),-(sp) // pc at exception + jsr _irq6_interrupt_handler // call C handler + lea 8(sp),sp // fix stack + + tst.l d0 // interrupt handled? + bne irq6_forward // no, forward to TOS + + movem.l (sp),d0-d1/a0-a1 // restore registers + unlk a6 + addq.l #4,sp // extra word not needed in this case + rte + +irq6_forward: + move.l 0xf0020000,a0 // fetch "autovector" + add.l _rt_vbr,a0 // add runtime VBR + move.l (a0),4(a6) // fetch handler address and put it on stack + + movem.l (sp),d0-d1/a0-a1 + unlk a6 + move.w #0x2600,sr // set interrupt level + + rts // jump through vector + +#ifdef _NOT_USED_ + // MFP interrupt from FPGA move.w #0x2700,sr // disable interrupt subq.l #8,sp movem.l d0/a5,(sp) // save registers @@ -555,6 +613,9 @@ acsi_dma_end: move.l (sp)+,d1 move.l (sp)+,a1 rts + +#endif /* _NOT_USED_ */ + /* * irq 7 = pseudo bus error */ diff --git a/sys/interrupts.c b/sys/interrupts.c index 3a313f5..c17f89b 100644 --- a/sys/interrupts.c +++ b/sys/interrupts.c @@ -35,63 +35,19 @@ #include "cache.h" #include "util.h" #include "dma.h" +#include "pci.h" extern void (*rt_vbr[])(void); #define VBR rt_vbr -//#define IRQ_DEBUG +#define IRQ_DEBUG #if defined(IRQ_DEBUG) #define dbg(format, arg...) do { xprintf("DEBUG %s(): " format, __FUNCTION__, ##arg); } while (0) #else #define dbg(format, arg...) do { ; } while (0) #endif +#define err(format, arg...) do { xprintf("DEBUG %s(): " format, __FUNCTION__, ##arg); } while (0) -/* - * register an interrupt handler at the Coldfire interrupt controller and add the handler to - * the interrupt vector table - */ -int register_interrupt_handler(uint8_t source, uint8_t level, uint8_t priority, uint8_t intr, void (*handler)(void)) -{ - int ipl; - int i; - volatile uint8_t *ICR = &MCF_INTC_ICR01 - 1; - uint8_t lp; - - source &= 63; - priority &= 7; - - if (source < 1 || source > 63) - { - dbg("interrupt source %d not defined\r\n", source); - return -1; - } - - lp = MCF_INTC_ICR_IL(level) | MCF_INTC_ICR_IP(priority); - - /* check if this combination is already set somewhere */ - for (i = 1; i < 64; i++) - { - if (ICR[i] == lp) - { - dbg("level %d and priority %d already used for interrupt source %d!\r\n", - level, priority, i); - return -1; - } - } - - /* disable interrupts */ - ipl = set_ipl(7); - - VBR[64 + source] = handler; /* first 64 vectors are system exceptions */ - - /* set level and priority in interrupt controller */ - ICR[source] = lp; - - /* set interrupt mask to where it was before */ - set_ipl(ipl); - - return 0; -} #ifndef MAX_ISR_ENTRY #define MAX_ISR_ENTRY (20) @@ -236,12 +192,19 @@ int pic_interrupt_handler(void *arg1, void *arg2) return 1; } - -void video_addr_timeout(void) +int xlbpci_interrupt_handler(void *arg1, void *arg2) { - dbg("video address timeout\r\n"); + dbg("XLB PCI interrupt\r\n"); + + return 1; } +int pciarb_interrupt_handler(void *arg1, void *arg2) +{ + dbg("PCI ARB interrupt\r\n"); + + return 1; +} /* * blink the Firebee's LED to show we are still alive @@ -288,6 +251,7 @@ bool irq6_interrupt_handler(uint32_t sf1, uint32_t sf2) { bool handled = false; + //err("IRQ6!\r\n"); MCF_EPORT_EPFR |= (1 << 6); /* clear int6 from edge port */ if (FALCON_MFP_IPRA || FALCON_MFP_IPRB) @@ -298,6 +262,65 @@ bool irq6_interrupt_handler(uint32_t sf1, uint32_t sf2) return handled; } +#if defined(MACHINE_FIREBEE) +/* + * This gets called from irq5 in exceptions.S + * Once we arrive here, the SR has been set to disable interrupts and the gcc scratch registers have been saved + */ +int irq5_handler(void) +{ + int32_t handle; + int32_t value = 0; + int32_t newvalue; + + err("FPGA_INTR_CONTROL = 0x%08x\r\n", * FPGA_INTR_CONTROL); + err("FPGA_INTR_ENABLE = 0x%08x\r\n", * FPGA_INTR_ENABLE); + err("FPGA_INTR_CLEAR = 0x%08x\r\n", * FPGA_INTR_CLEAR); + err("FPGA_INTR_PENDING = 0x%08x\r\n", * FPGA_INTR_PENDING); + + * FPGA_INTR_CLEAR &= ~0x20000000UL; /* clear interrupt from FPGA */ + err("\r\nFPGA_INTR_CLEAR = 0x%08x\r\n", * FPGA_INTR_CLEAR); + //MCF_EPORT_EPFR |= (1 << 5); /* clear interrupt from edge port */ + + //xprintf("IRQ5!\r\n"); + + if ((handle = pci_get_interrupt_cause()) > 0) + { + newvalue = pci_call_interrupt_chain(handle, value); + if (newvalue == value) + { + dbg("interrupt not handled!\r\n"); + return 1; + } + } + return 0; +} +#endif /* MACHINE_FIREBEE */ + +#ifdef MACHINE_M5484LITE +/* + * This gets called from irq7 in exceptions.S + * Once we arrive here, the SR has been set to disable interrupts and the gcc scratch registers have been saved + */ +void irq7_handler(void) +{ + int32_t handle; + int32_t value = 0; + int32_t newvalue; + + MCF_EPORT_EPFR |= (1 << 7); + dbg("IRQ7!\r\n"); + if ((handle = pci_get_interrupt_cause()) > 0) + { + newvalue = pci_call_interrupt_chain(handle, value); + if (newvalue == value) + { + dbg("interrupt not handled!\r\n"); + } + } +} +#endif /* MACHINE_M548X */ + #if defined(MACHINE_FIREBEE) #define vbasehi (* (volatile uint8_t *) 0xffff8201) #define vbasemid (* (volatile uint8_t *) 0xffff8203) diff --git a/sys/mmu.c b/sys/mmu.c index 0936025..acbe374 100644 --- a/sys/mmu.c +++ b/sys/mmu.c @@ -213,6 +213,7 @@ struct virt_to_phys uint32_t physical_offset; }; +#if defined(MACHINE_FIREBEE) static struct virt_to_phys translation[] = { /* virtual , length , offset */ @@ -221,9 +222,33 @@ static struct virt_to_phys translation[] = { 0x00f00000, 0x00100000, 0xff000000 }, /* map Falcon I/O area to FPGA */ { 0x01000000, 0x1f000000, 0x00000000 }, /* map rest of ram virt = phys */ }; +#elif defined(MACHINE_M5484LITE) +static struct virt_to_phys translation[] = +{ + /* virtual , length , offset */ + { 0x00000000, 0x00e00000, 0x00000000 }, /* map first 14 MByte to first 14 Mb of SD ram */ + { 0x00e00000, 0x00100000, 0x00000000 }, /* map TOS to SDRAM */ + { 0x01000000, 0x04000000, 0x00000000 }, /* map rest of ram virt = phys */ + { 0x60000000, 0x10000000, 0x00000000 }, /* map CPLD CF card I/O area */ + +}; +#elif defined(MACHINE_M54455) +/* FIXME: this is not determined yet! */ +static struct virt_to_phys translation[] = +{ + /* virtual , length , offset */ + { 0x00000000, 0x00e00000, 0x60000000 }, /* map first 14 MByte to first 14 Mb of video ram */ + { 0x00e00000, 0x00100000, 0x00000000 }, /* map TOS to SDRAM */ + { 0x00f00000, 0x00100000, 0xff000000 }, /* map Falcon I/O area to FPGA */ + { 0x01000000, 0x1f000000, 0x00000000 }, /* map rest of ram virt = phys */ +}; +#else +#error unknown machine! +#endif + static int num_translations = sizeof(translation) / sizeof(struct virt_to_phys); -static inline uint32_t lookup_phys(uint32_t virt) +static inline int32_t lookup_phys(int32_t virt) { int i; @@ -235,6 +260,7 @@ static inline uint32_t lookup_phys(uint32_t virt) } } err("virtual address 0x%lx not found in translation table!\r\n", virt); + return -1; } @@ -253,19 +279,23 @@ struct page_descriptor * page descriptors. Size depending on DEFAULT_PAGE_SIZE, either 1M (resulting in 512 * bytes size) or 8k pages (64k descriptor array size) */ -static struct page_descriptor pages[512UL * 1024 * 1024 / DEFAULT_PAGE_SIZE]; +static struct page_descriptor pages[SDRAM_SIZE / DEFAULT_PAGE_SIZE]; -int mmu_map_instruction_page(uint32_t virt, uint8_t asid) +int mmu_map_instruction_page(int32_t virt, uint8_t asid) { const uint32_t size_mask = ~ (DEFAULT_PAGE_SIZE - 1); /* pagesize */ int page_index = (virt & size_mask) / DEFAULT_PAGE_SIZE; /* index into page_descriptor array */ struct page_descriptor *page = &pages[page_index]; /* attributes of page to map */ int ipl; - uint32_t phys = lookup_phys(virt); /* virtual to physical translation of page */ + int32_t phys = lookup_phys(virt); /* virtual to physical translation of page */ if (phys == -1) + { + /* no valid mapping found, caller will issue a bus error in return */ + return 0; + } #ifdef DBG_MMU register int sp asm("sp"); @@ -307,17 +337,21 @@ int mmu_map_instruction_page(uint32_t virt, uint8_t asid) return 1; } -int mmu_map_data_page(uint32_t virt, uint8_t asid) +int mmu_map_data_page(int32_t virt, uint8_t asid) { uint16_t ipl; const uint32_t size_mask = ~ (DEFAULT_PAGE_SIZE - 1); /* pagesize */ int page_index = (virt & size_mask) / DEFAULT_PAGE_SIZE; /* index into page_descriptor array */ struct page_descriptor *page = &pages[page_index]; /* attributes of page to map */ - uint32_t phys = lookup_phys(virt); /* virtual to physical translation of page */ + int32_t phys = lookup_phys(virt); /* virtual to physical translation of page */ if (phys == -1) + { + /* no valid mapping found, caller will issue a bus error in return */ + return 0; + } #ifdef DBG_MMU register int sp asm("sp"); @@ -365,7 +399,7 @@ int mmu_map_data_page(uint32_t virt, uint8_t asid) * per instruction as a minimum, more for performance. Thus locked pages (that can't be touched by the * LRU algorithm) should be used sparsingly. */ -int mmu_map_page(uint32_t virt, uint32_t phys, enum mmu_page_size sz, uint8_t page_id, const struct page_descriptor *flags) +int mmu_map_page(int32_t virt, int32_t phys, enum mmu_page_size sz, uint8_t page_id, const struct page_descriptor *flags) { int size_mask; int ipl; @@ -447,7 +481,8 @@ void mmu_init(void) { uint32_t addr = i * DEFAULT_PAGE_SIZE; - if (addr >= 0x00f00000 && addr < 0x00ffffff) +#if defined(MACHINE_FIREBEE) + if (addr >= 0x00f00000UL && addr < 0x00ffffffUL) /* Falcon I/O area on the Firebee */ { pages[i].cache_mode = CACHE_NOCACHE_PRECISE; pages[i].execute = 0; @@ -457,7 +492,7 @@ void mmu_init(void) pages[i].global = 1; pages[i].supervisor_protect = 1; } - else if (addr >= 0x0 && addr < 0x00e00000) /* ST-RAM, potential video memory */ + else if (addr >= 0x0UL && addr < 0x00e00000UL) /* ST-RAM, potential video memory */ { pages[i].cache_mode = CACHE_WRITETHROUGH; pages[i].execute = 1; @@ -467,7 +502,7 @@ void mmu_init(void) pages[i].execute = 1; pages[i].global = 1; } - else if (addr >= 0x00e00000 && addr < 0x00f00000) /* EmuTOS */ + else if (addr >= 0x00e00000UL && addr < 0x00f00000UL) /* EmuTOS */ { pages[i].cache_mode = CACHE_COPYBACK; pages[i].execute = 1; @@ -488,16 +523,107 @@ void mmu_init(void) } pages[i].locked = 0; /* not locked */ pages[0].supervisor_protect = 0; /* protect system vectors */ + +#elif defined(MACHINE_M5484LITE) + if (addr >= 0x60000000UL && addr < 0x70000000UL) /* Compact Flash on the m5484lite */ + { + pages[i].cache_mode = CACHE_NOCACHE_PRECISE; + pages[i].execute = 0; + pages[i].read = 1; + pages[i].write = 1; + pages[i].execute = 0; + pages[i].global = 1; + pages[i].supervisor_protect = 1; + } + else if (addr >= 0x0UL && addr < 0x00e00000UL) /* ST-RAM, potential video memory */ + { + pages[i].cache_mode = CACHE_WRITETHROUGH; + pages[i].execute = 1; + pages[i].supervisor_protect = 0; + pages[i].read = 1; + pages[i].write = 1; + pages[i].execute = 1; + pages[i].global = 1; + } + else if (addr >= 0x00e00000UL && addr < 0x00f00000UL) /* EmuTOS */ + { + pages[i].cache_mode = CACHE_COPYBACK; + pages[i].execute = 1; + pages[i].supervisor_protect = 1; + pages[i].read = 1; + pages[i].write = 0; + pages[i].execute = 1; + pages[i].global = 1; + } + else + { + pages[i].cache_mode = CACHE_COPYBACK; /* rest of RAM */ + pages[i].execute = 1; + pages[i].read = 1; + pages[i].write = 1; + pages[i].supervisor_protect = 0; + pages[i].global = 1; + } + pages[i].locked = 0; /* not locked */ + pages[0].supervisor_protect = 0; /* protect system vectors */ + +#elif defined(MACHINE_M54455) + if (addr >= 0x60000000UL && addr < 0x70000000UL) /* Compact Flash on the m5484lite */ + { + pages[i].cache_mode = CACHE_NOCACHE_PRECISE; + pages[i].execute = 0; + pages[i].read = 1; + pages[i].write = 1; + pages[i].execute = 0; + pages[i].global = 1; + pages[i].supervisor_protect = 1; + } + else if (addr >= 0x0UL && addr < 0x00e00000UL) /* ST-RAM, potential video memory */ + { + pages[i].cache_mode = CACHE_WRITETHROUGH; + pages[i].execute = 1; + pages[i].supervisor_protect = 0; + pages[i].read = 1; + pages[i].write = 1; + pages[i].execute = 1; + pages[i].global = 1; + } + else if (addr >= 0x00e00000UL && addr < 0x00f00000UL) /* EmuTOS */ + { + pages[i].cache_mode = CACHE_COPYBACK; + pages[i].execute = 1; + pages[i].supervisor_protect = 1; + pages[i].read = 1; + pages[i].write = 0; + pages[i].execute = 1; + pages[i].global = 1; + } + else + { + pages[i].cache_mode = CACHE_COPYBACK; /* rest of RAM */ + pages[i].execute = 1; + pages[i].read = 1; + pages[i].write = 1; + pages[i].supervisor_protect = 0; + pages[i].global = 1; + } + pages[i].locked = 0; /* not locked */ + pages[0].supervisor_protect = 0; /* protect system vectors */ +#else +#error Unknown machine! +#endif /* MACHINE_FIREBEE */ } set_asid(0); /* do not use address extension (ASID provides virtual 48 bit addresses */ /* set data access attributes in ACR0 and ACR1 */ + + /* map PCI address space */ set_acr0(ACR_W(0) | /* read and write accesses permitted */ - ACR_SP(0) | /* supervisor and user mode access permitted */ + ACR_SP(1) | /* supervisor and user mode access permitted */ ACR_CM(ACR_CM_CACHE_INH_PRECISE) | /* cache inhibit, precise */ ACR_AMM(0) | /* control region > 16 MB */ - ACR_S(ACR_S_ALL) | /* match addresses in user and supervisor mode */ + ACR_S(ACR_S_SUPERVISOR_MODE) | /* match addresses in supervisor mode only */ ACR_E(1) | /* enable ACR */ #if defined(MACHINE_FIREBEE) ACR_ADMSK(0x7f) | /* cover 2GB area from 0x80000000 to 0xffffffff */ @@ -520,11 +646,11 @@ void mmu_init(void) ACR_SP(0) | ACR_CM(0) | #if defined(MACHINE_FIREBEE) - ACR_CM(ACR_CM_CACHEABLE_WT) | /* flash on the Firebee */ + ACR_CM(ACR_CM_CACHEABLE_WT) | #elif defined(MACHINE_M5484LITE) - ACR_CM(ACR_CM_CACHE_INH_PRECISE) | /* Compact Flash on the M548xLITE */ + ACR_CM(ACR_CM_CACHEABLE_WT) | #elif defined(MACHINE_M54455) - ACR_CM(ACR_CM_CACHE_INH_PRECISE) | /* FIXME: not determined yet */ + ACR_CM(ACR_CM_CACHEABLE_WT) | #else #error unknown machine! #endif /* MACHINE_FIREBEE */ @@ -568,6 +694,7 @@ void mmu_init(void) /* 0x00000000 - 0x00100000 (first MB of physical memory) locked virt = phys */ mmu_map_page(0x0, 0x0, MMU_PAGE_SIZE_1M, 0, &flags); +#ifdef _NOT_USED_ #if defined(MACHINE_FIREBEE) /* * 0x00d00000 - 0x00e00000 (last megabyte of ST RAM = Falcon video memory) locked ID = 6 @@ -581,8 +708,8 @@ void mmu_init(void) flags.execute = 1; flags.locked = true; mmu_map_page(0x00d00000, 0x60d00000, MMU_PAGE_SIZE_1M, SCA_PAGE_ID, &flags); - #endif /* MACHINE_FIREBEE */ +#endif /* * Make the TOS (in SDRAM) read-only diff --git a/sys/sysinit.c b/sys/sysinit.c index fb1c96a..8ab7901 100644 --- a/sys/sysinit.c +++ b/sys/sysinit.c @@ -30,7 +30,6 @@ #include "startcf.h" #include "cache.h" #include "sysinit.h" -#include "pci.h" #include "bas_printf.h" #include "bas_string.h" #include "bas_types.h" @@ -52,7 +51,6 @@ #include "pci_ids.h" #include "driver_mem.h" #include "usb.h" -#include "video.h" #define DEBUG_SYSINIT #ifdef DEBUG_SYSINIT @@ -708,9 +706,11 @@ void init_usb(void) uint32_t id = 0; uint32_t pci_class = 0; + dbg("PCI device handle = %x\r\n", handle); + id = pci_read_config_longword(handle, PCIIDR); pci_class = pci_read_config_longword(handle, PCIREV); - dbg("compare class code 0x%x to 0x%x\r\n", PCI_CLASS_CODE(pci_class), PCI_CLASS_SERIAL_USB); + if (PCI_CLASS_CODE(pci_class) == PCI_CLASS_SERIAL_USB) { xprintf("serial USB found at bus=0x%x, dev=0x%x, fnc=0x%x (0x%x)\r\n", @@ -718,14 +718,12 @@ void init_usb(void) PCI_DEVICE_FROM_HANDLE(handle), PCI_FUNCTION_FROM_HANDLE(handle), handle); - dbg("compare subclass code 0x%x against 0x%x\r\n", PCI_SUBCLASS(pci_class), PCI_CLASS_SERIAL_USB_EHCI); + if (PCI_SUBCLASS(pci_class) == PCI_CLASS_SERIAL_USB_EHCI) { board = ehci_usb_pci_table; while (board->vendor) { - dbg("compare vendor id 0x%x against 0x%x\r\n", board->vendor, PCI_VENDOR_ID(id)); - dbg("compare device id 0x%x against 0x%x\r\n", board->device, PCI_DEVICE_ID(id)); if ((board->vendor == PCI_VENDOR_ID(id)) && board->device == PCI_DEVICE_ID(id)) { dbg("match. trying to init board\r\n"); @@ -738,15 +736,12 @@ void init_usb(void) } } - dbg("compare subclass code 0x%x against 0x%x\r\n", PCI_SUBCLASS(pci_class), PCI_CLASS_SERIAL_USB_OHCI); if (PCI_SUBCLASS(pci_class) == PCI_CLASS_SERIAL_USB_OHCI) { board = ohci_usb_pci_table; while (board->vendor) { - dbg("matched. compare vendor id 0x%x against 0x%x\r\n", board->vendor, PCI_VENDOR_ID(id)); - dbg("compare device id 0x%x against 0x%x\r\n", 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) @@ -759,7 +754,6 @@ void init_usb(void) } } } - dbg("PCI device handle = %x\r\n", handle); } while (handle >= 0); xprintf("finished (found %d USB host controller(s))\r\n", usb_found); @@ -1228,11 +1222,6 @@ void initialize_hardware(void) #endif /* MACHINE_FIREBEE */ driver_mem_init(); - init_pci(); - video_init(); - - /* initialize USB devices */ - init_usb(); #if MACHINE_FIREBEE init_ac97(); diff --git a/usb/usb.c b/usb/usb.c index 15bc1bd..e09e190 100644 --- a/usb/usb.c +++ b/usb/usb.c @@ -529,7 +529,7 @@ int usb_parse_config(struct usb_device *dev, unsigned char *buffer, int cfgno) if (head->bDescriptorType != USB_DT_CONFIG) { - dbg(" ERROR: NOT USB_CONFIG_DESC %x\r\n", head->bDescriptorType); + dbg(" ERROR: NOT USB_CONFIG_DESC (0x%x instead of 0x%x)\r\n", head->bDescriptorType, USB_DT_CONFIG); return -1; } memcpy(&dev->config, buffer, buffer[0]); @@ -1089,6 +1089,7 @@ int usb_new_device(struct usb_device *dev) unsigned char *tmpbuf; dbg("\r\n"); + #ifndef CONFIG_LEGACY_USB_INIT_SEQ struct usb_device_descriptor *desc; int port = -1; @@ -1113,6 +1114,7 @@ int usb_new_device(struct usb_device *dev) return 1; } +//#define CONFIG_LEGACY_USB_INIT_SEQ #ifdef CONFIG_LEGACY_USB_INIT_SEQ /* * this is the old and known way of initializing devices, it is @@ -1244,6 +1246,9 @@ int usb_new_device(struct usb_device *dev) dev->descriptor.idProduct = swpw(dev->descriptor.idProduct); dev->descriptor.bcdDevice = swpw(dev->descriptor.bcdDevice); + dbg("vendor: 0x%x, prod: 0x%x, dev: 0x%x\r\n", + dev->descriptor.idVendor, dev->descriptor.idProduct, dev->descriptor.bcdDevice); + /* only support for one config for now */ usb_get_configuration_no(dev, &tmpbuf[0], 0); usb_parse_config(dev, &tmpbuf[0], 0); diff --git a/usb/usb_mouse.c b/usb/usb_mouse.c index f8c842c..d5f9e4b 100644 --- a/usb/usb_mouse.c +++ b/usb/usb_mouse.c @@ -216,12 +216,14 @@ static int usb_mouse_probe(struct usb_device *dev, unsigned int ifnum) int pipe; int maxp; +#ifdef _NOT_USED_ if (dev->descriptor.bNumConfigurations != 1) { dbg("dev->descriptor.bNumConfigurations != 1\r\n"); return 0; } +#endif iface = &dev->config.if_desc[ifnum]; diff --git a/util/wait.c b/util/wait.c index 0b29495..621aa2f 100644 --- a/util/wait.c +++ b/util/wait.c @@ -31,7 +31,7 @@ uint32_t get_timer(void) { - return MCF_SLT_SCNT(0); + return MCF_SLT_SCNT(0); } /* * wait for the specified number of us on slice timer 0. Replaces the original routines that had @@ -39,17 +39,18 @@ uint32_t get_timer(void) */ void wait(uint32_t us) { - int32_t target = MCF_SLT_SCNT(0) - (us * (SYSCLK / 1000)); + int32_t target = MCF_SLT_SCNT(0) - (us * (SYSCLK / 1000)); - while (MCF_SLT_SCNT(0) - target > 0); + while (MCF_SLT_SCNT(0) - target > 0); } +void wait_us() __attribute__ ((weak, alias("wait"))); /* * same as above, but with milliseconds wait time */ void wait_ms(uint32_t ms) { - wait(ms * 1000); + wait(ms * 1000); } /* * the same as above, with a checker function which gets called while @@ -57,13 +58,13 @@ void wait_ms(uint32_t ms) */ bool waitfor(uint32_t us, checker_func condition) { - int32_t target = MCF_SLT_SCNT(0) - (us * (SYSCLK / 1000)); - bool res; + int32_t target = MCF_SLT_SCNT(0) - (us * (SYSCLK / 1000)); + bool res; - do - { - if ((res = (*condition)())) - return res; - } while (MCF_SLT_SCNT(0) - target > 0); - return false; + do + { + if ((res = (*condition)())) + return res; + } while (MCF_SLT_SCNT(0) - target > 0); + return false; }