From ae6cc2d36baec9dee3a82d5542354fcac6b7679c Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Fri, 4 Apr 2008 18:16:06 +0200 Subject: [m68k] Add Freescale Coldfire V4E Architecture support - Added m68k vector, exception & interrupt handlers - Added m68k macros to access m68k movec registers - Added Coldfire support code (MultiChannelDMA) - Added board support for phytec phyCore-MCF baseboard - Added board support for konzeptpark MCB2 prototype Signed-off-by: Carsten Schlote --- arch/m68k/mach-mcfv4e/Kconfig | 18 + arch/m68k/mach-mcfv4e/Makefile | 19 + arch/m68k/mach-mcfv4e/dma_utils.c | 502 +++++ arch/m68k/mach-mcfv4e/fec.c | 1440 +++++++++++++++ arch/m68k/mach-mcfv4e/fecbd.c | 232 +++ arch/m68k/mach-mcfv4e/mcdapi/MCD_dmaApi.c | 907 +++++++++ arch/m68k/mach-mcfv4e/mcdapi/MCD_library.dox | 10 + arch/m68k/mach-mcfv4e/mcdapi/MCD_tasks.c | 2449 +++++++++++++++++++++++++ arch/m68k/mach-mcfv4e/mcdapi/MCD_tasksInit.c | 225 +++ arch/m68k/mach-mcfv4e/mcdapi/Makefile | 26 + arch/m68k/mach-mcfv4e/mcdapi/ReleaseNotes.txt | 27 + arch/m68k/mach-mcfv4e/mcf_clocksource.c | 138 ++ arch/m68k/mach-mcfv4e/mcf_reset_cpu.c | 45 + arch/m68k/mach-mcfv4e/multichannel_dma.c | 51 + arch/m68k/mach-mcfv4e/net/Makefile | 26 + arch/m68k/mach-mcfv4e/net/nbuf.c | 239 +++ arch/m68k/mach-mcfv4e/net/net.c | 156 ++ arch/m68k/mach-mcfv4e/net/queue.c | 128 ++ 18 files changed, 6638 insertions(+) create mode 100644 arch/m68k/mach-mcfv4e/Kconfig create mode 100644 arch/m68k/mach-mcfv4e/Makefile create mode 100644 arch/m68k/mach-mcfv4e/dma_utils.c create mode 100644 arch/m68k/mach-mcfv4e/fec.c create mode 100644 arch/m68k/mach-mcfv4e/fecbd.c create mode 100644 arch/m68k/mach-mcfv4e/mcdapi/MCD_dmaApi.c create mode 100644 arch/m68k/mach-mcfv4e/mcdapi/MCD_library.dox create mode 100644 arch/m68k/mach-mcfv4e/mcdapi/MCD_tasks.c create mode 100644 arch/m68k/mach-mcfv4e/mcdapi/MCD_tasksInit.c create mode 100644 arch/m68k/mach-mcfv4e/mcdapi/Makefile create mode 100644 arch/m68k/mach-mcfv4e/mcdapi/ReleaseNotes.txt create mode 100644 arch/m68k/mach-mcfv4e/mcf_clocksource.c create mode 100644 arch/m68k/mach-mcfv4e/mcf_reset_cpu.c create mode 100644 arch/m68k/mach-mcfv4e/multichannel_dma.c create mode 100644 arch/m68k/mach-mcfv4e/net/Makefile create mode 100644 arch/m68k/mach-mcfv4e/net/nbuf.c create mode 100644 arch/m68k/mach-mcfv4e/net/net.c create mode 100644 arch/m68k/mach-mcfv4e/net/queue.c (limited to 'arch/m68k/mach-mcfv4e') diff --git a/arch/m68k/mach-mcfv4e/Kconfig b/arch/m68k/mach-mcfv4e/Kconfig new file mode 100644 index 0000000000..aaba27e5e8 --- /dev/null +++ b/arch/m68k/mach-mcfv4e/Kconfig @@ -0,0 +1,18 @@ + +menu "M68k/Coldfire V4E specific settings" + +config COPY_LOWMEM_VECTORS + bool "Copy vectors to SDRAM address 0" + default y + help + This copies the vector table to SDRAM address 0 (default address) + +config USE_LOWMEM_VECTORS + bool "Use vectors at SDRAM address 0" + default n + depends on COPY_LOWMEM_VECTORS + help + This copies the vector table to SDRAM address 0 (default address) and + also uses this vector location + +endmenu diff --git a/arch/m68k/mach-mcfv4e/Makefile b/arch/m68k/mach-mcfv4e/Makefile new file mode 100644 index 0000000000..f75834be54 --- /dev/null +++ b/arch/m68k/mach-mcfv4e/Makefile @@ -0,0 +1,19 @@ +# +# Generic code for Coldfire V4E targets (MCF547x/MCF548x) +# +obj-y += mcf_clocksource.o +obj-y += mcf_reset_cpu.o + +# +# FEC support +# +obj-y += multichannel_dma.o +obj-y += dma_utils.o +obj-y += fec.o +obj-y += fecbd.o + +# +# FreeScale MultiDMA Library +# +obj-y += mcdapi/ +obj-y += net/ diff --git a/arch/m68k/mach-mcfv4e/dma_utils.c b/arch/m68k/mach-mcfv4e/dma_utils.c new file mode 100644 index 0000000000..15b520abc2 --- /dev/null +++ b/arch/m68k/mach-mcfv4e/dma_utils.c @@ -0,0 +1,502 @@ +/* + * File: dma_utils.c + * Purpose: General purpose utilities for the multi-channel DMA + * + * Notes: The methodology used in these utilities assumes that + * no single initiator will be tied to more than one + * task/channel + */ + +#include +#include +#include +#include +#include + +#include + +/* + * This global keeps track of which initiators have been + * used of the available assignments. Initiators 0-15 are + * hardwired. Initiators 16-31 are multiplexed and controlled + * via the Initiatior Mux Control Registe (IMCR). The + * assigned requestor is stored with the associated initiator + * number. + */ +static int8_t used_reqs[32] = +{ + DMA_ALWAYS, DMA_DSPI_RX, DMA_DSPI_TX, DMA_DREQ0, + DMA_PSC0_RX, DMA_PSC0_TX, DMA_USBEP0, DMA_USBEP1, + DMA_USBEP2, DMA_USBEP3, DMA_PCI_TX, DMA_PCI_RX, + DMA_PSC1_RX, DMA_PSC1_TX, DMA_I2C_RX, DMA_I2C_TX, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0, + 0, 0, 0, 0 +}; + +/* + * This global keeps track of which channels have been assigned + * to tasks. This methology assumes that no single initiator + * will be tied to more than one task/channel + */ +typedef struct +{ + int req; + void (*handler)(void); +} DMA_CHANNEL_STRUCT; + +static DMA_CHANNEL_STRUCT dma_channel[NCHANNELS] = +{ + {-1,NULL}, {-1,NULL}, {-1,NULL}, {-1,NULL}, + {-1,NULL}, {-1,NULL}, {-1,NULL}, {-1,NULL}, + {-1,NULL}, {-1,NULL}, {-1,NULL}, {-1,NULL}, + {-1,NULL}, {-1,NULL}, {-1,NULL}, {-1,NULL} +}; + +/* + * Enable all DMA interrupts + * + * Parameters: + * pri Interrupt Priority + * lvl Interrupt Level + */ +void +dma_irq_enable(uint8_t lvl, uint8_t pri) +{ +//FIXME ASSERT(lvl > 0 && lvl < 8); +//FIXME ASSERT(pri < 8); + + /* Setup the DMA ICR (#48) */ + MCF_INTC_ICR48 = 0 + | MCF_INTC_ICRn_IP(pri) + | MCF_INTC_ICRn_IL(lvl); + + /* Unmask all task interrupts */ + MCF_DMA_DIMR = 0; + + /* Clear the interrupt pending register */ + MCF_DMA_DIPR = 0; + + /* Unmask the DMA interrupt in the interrupt controller */ + MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK48; +} + +/* + * Disable all DMA interrupts + */ +void +dma_irq_disable(void) +{ + /* Mask all task interrupts */ + MCF_DMA_DIMR = (uint32_t)~0; + + /* Clear any pending task interrupts */ + MCF_DMA_DIPR = (uint32_t)~0; + + /* Mask the DMA interrupt in the interrupt controller */ + MCF_INTC_IMRH |= MCF_INTC_IMRH_INT_MASK48; +} + +/* + * Attempt to enable the provided Initiator in the Initiator + * Mux Control Register + * + * Parameters: + * initiator Initiator identifier + * + * Return Value: + * 1 if unable to make the assignment + * 0 successful + */ +int +dma_set_initiator(int initiator) +{ + switch (initiator) + { + /* These initiators are always active */ + case DMA_ALWAYS: + case DMA_DSPI_RX: + case DMA_DSPI_TX: + case DMA_DREQ0: + case DMA_PSC0_RX: + case DMA_PSC0_TX: + case DMA_USBEP0: + case DMA_USBEP1: + case DMA_USBEP2: + case DMA_USBEP3: + case DMA_PCI_TX: + case DMA_PCI_RX: + case DMA_PSC1_RX: + case DMA_PSC1_TX: + case DMA_I2C_RX: + case DMA_I2C_TX: + break; + case DMA_FEC0_RX: + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC16(3)) + | MCF_DMA_IMCR_SRC16_FEC0RX; + used_reqs[16] = DMA_FEC0_RX; + break; + case DMA_FEC0_TX: + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC17(3)) + | MCF_DMA_IMCR_SRC17_FEC0TX; + used_reqs[17] = DMA_FEC0_TX; + break; + case DMA_FEC1_RX: + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC20(3)) + | MCF_DMA_IMCR_SRC20_FEC1RX; + used_reqs[20] = DMA_FEC1_RX; + break; + case DMA_FEC1_TX: + if (used_reqs[21] == 0) + { + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC21(3)) + | MCF_DMA_IMCR_SRC21_FEC1TX; + used_reqs[21] = DMA_FEC1_TX; + } + else if (used_reqs[25] == 0) + { + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC25(3)) + | MCF_DMA_IMCR_SRC25_FEC1TX; + used_reqs[25] = DMA_FEC1_TX; + } + else if (used_reqs[31] == 0) + { + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC31(3)) + | MCF_DMA_IMCR_SRC31_FEC1TX; + used_reqs[31] = DMA_FEC1_TX; + } + else /* No empty slots */ + return 1; + break; + case DMA_DREQ1: + if (used_reqs[29] == 0) + { + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC29(3)) + | MCF_DMA_IMCR_SRC29_DREQ1; + used_reqs[29] = DMA_DREQ1; + } + else if (used_reqs[21] == 0) + { + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC21(3)) + | MCF_DMA_IMCR_SRC21_DREQ1; + used_reqs[21] = DMA_DREQ1; + } + else /* No empty slots */ + return 1; + break; + case DMA_CTM0: + if (used_reqs[24] == 0) + { + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC24(3)) + | MCF_DMA_IMCR_SRC24_CTM0; + used_reqs[24] = DMA_CTM0; + } + else /* No empty slots */ + return 1; + break; + case DMA_CTM1: + if (used_reqs[25] == 0) + { + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC25(3)) + | MCF_DMA_IMCR_SRC25_CTM1; + used_reqs[25] = DMA_CTM1; + } + else /* No empty slots */ + return 1; + break; + case DMA_CTM2: + if (used_reqs[26] == 0) + { + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC26(3)) + | MCF_DMA_IMCR_SRC26_CTM2; + used_reqs[26] = DMA_CTM2; + } + else /* No empty slots */ + return 1; + break; + case DMA_CTM3: + if (used_reqs[27] == 0) + { + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC27(3)) + | MCF_DMA_IMCR_SRC27_CTM3; + used_reqs[27] = DMA_CTM3; + } + else /* No empty slots */ + return 1; + break; + case DMA_CTM4: + if (used_reqs[28] == 0) + { + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC28(3)) + | MCF_DMA_IMCR_SRC28_CTM4; + used_reqs[28] = DMA_CTM4; + } + else /* No empty slots */ + return 1; + break; + case DMA_CTM5: + if (used_reqs[29] == 0) + { + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC29(3)) + | MCF_DMA_IMCR_SRC29_CTM5; + used_reqs[29] = DMA_CTM5; + } + else /* No empty slots */ + return 1; + break; + case DMA_CTM6: + if (used_reqs[30] == 0) + { + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC30(3)) + | MCF_DMA_IMCR_SRC30_CTM6; + used_reqs[30] = DMA_CTM6; + } + else /* No empty slots */ + return 1; + break; + case DMA_CTM7: + if (used_reqs[31] == 0) + { + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC31(3)) + | MCF_DMA_IMCR_SRC31_CTM7; + used_reqs[31] = DMA_CTM7; + } + else /* No empty slots */ + return 1; + break; + case DMA_USBEP4: + if (used_reqs[26] == 0) + { + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC26(3)) + | MCF_DMA_IMCR_SRC26_USBEP4; + used_reqs[26] = DMA_USBEP4; + } + else /* No empty slots */ + return 1; + break; + case DMA_USBEP5: + if (used_reqs[27] == 0) + { + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC27(3)) + | MCF_DMA_IMCR_SRC27_USBEP5; + used_reqs[27] = DMA_USBEP5; + } + else /* No empty slots */ + return 1; + break; + case DMA_USBEP6: + if (used_reqs[28] == 0) + { + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC28(3)) + | MCF_DMA_IMCR_SRC28_USBEP6; + used_reqs[28] = DMA_USBEP6; + } + else /* No empty slots */ + return 1; + break; + case DMA_PSC2_RX: + if (used_reqs[28] == 0) + { + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC28(3)) + | MCF_DMA_IMCR_SRC28_PSC2RX; + used_reqs[28] = DMA_PSC2_RX; + } + else /* No empty slots */ + return 1; + break; + case DMA_PSC2_TX: + if (used_reqs[29] == 0) + { + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC29(3)) + | MCF_DMA_IMCR_SRC29_PSC2TX; + used_reqs[29] = DMA_PSC2_TX; + } + else /* No empty slots */ + return 1; + break; + case DMA_PSC3_RX: + if (used_reqs[30] == 0) + { + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC30(3)) + | MCF_DMA_IMCR_SRC30_PSC3RX; + used_reqs[30] = DMA_PSC3_RX; + } + else /* No empty slots */ + return 1; + break; + case DMA_PSC3_TX: + if (used_reqs[31] == 0) + { + MCF_DMA_IMCR = (MCF_DMA_IMCR & ~MCF_DMA_IMCR_SRC31(3)) + | MCF_DMA_IMCR_SRC31_PSC3TX; + used_reqs[31] = DMA_PSC3_TX; + } + else /* No empty slots */ + return 1; + break; + default: + return 1; + } + return 0; +} + +/* + * Return the initiator number for the given requestor + * + * Parameters: + * requestor Initiator/Requestor identifier + * + * Return Value: + * The initiator number (0-31) if initiator has been assigned + * 0 (always initiator) otherwise + */ +uint32_t +dma_get_initiator(int requestor) +{ + uint32_t i; + + for (i=0; i>=1) + { + if (interrupts & 0x1) + { + /* If there is a handler, call it */ + if (dma_channel[i].handler != NULL) + dma_channel[i].handler(); + } + } + + enable_interrupts(); // board_irq_enable(); + return 1; +} diff --git a/arch/m68k/mach-mcfv4e/fec.c b/arch/m68k/mach-mcfv4e/fec.c new file mode 100644 index 0000000000..551f00f005 --- /dev/null +++ b/arch/m68k/mach-mcfv4e/fec.c @@ -0,0 +1,1440 @@ +/* + * File: fec.c + * Purpose: Driver for the Fast Ethernet Controller (FEC) + * + * Notes: + */ +#include +#include + +#include +#include +#include +#include +#include +#include + + +#define TRUE 1 +#define FALSE 0 +#define ASSERT(x) if (!(x)) hang(); +#define nop() __asm__ __volatile__("nop\n") + + +FEC_EVENT_LOG fec_log[2]; + +/* + * Write a value to a PHY's MII register. + * + * Parameters: + * ch FEC channel + * phy_addr Address of the PHY. + * reg_addr Address of the register in the PHY. + * data Data to be written to the PHY register. + * + * Return Values: + * 1 on failure + * 0 on success. + * + * Please refer to your PHY manual for registers and their meanings. + * mii_write() polls for the FEC's MII interrupt event (which should + * be masked from the interrupt handler) and clears it. If after a + * suitable amount of time the event isn't triggered, a value of 0 + * is returned. + */ +int +fec_mii_write(uint8_t ch, uint8_t phy_addr, uint8_t reg_addr, uint16_t data) +{ + int timeout; + uint32_t eimr; + + ASSERT(ch == 0 || ch == 1); + + /* + * 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); + + /* + * 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++) + { + if (MCF_FEC_EIR(ch) & MCF_FEC_EIR_MII) + break; + } + if(timeout == FEC_MII_TIMEOUT) + return 1; + + /* + * Clear the MII interrupt bit + */ + MCF_FEC_EIR(ch) = MCF_FEC_EIR_MII; + + /* + * Restore the EIMR + */ + MCF_FEC_EIMR(ch) = eimr; + + return 0; +} + +/* + * Read a value from a PHY's MII register. + * + * Parameters: + * ch FEC channel + * phy_addr Address of the PHY. + * reg_addr Address of the register in the PHY. + * data Pointer to storage for the Data to be read + * from the PHY register (passed by reference) + * + * Return Values: + * 1 on failure + * 0 on success. + * + * Please refer to your PHY manual for registers and their meanings. + * mii_read() polls for the FEC's MII interrupt event (which should + * be masked from the interrupt handler) and clears it. If after a + * suitable amount of time the event isn't triggered, a value of 0 + * is returned. + */ +int +fec_mii_read(uint8_t ch, uint8_t phy_addr, uint8_t reg_addr, uint16_t *data) +{ + int timeout; + + ASSERT(ch == 0 || ch == 1); + + /* + * 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; + + /* + * Poll for the MII interrupt (interrupt should be masked) + */ + for (timeout = 0; timeout < FEC_MII_TIMEOUT; timeout++) + { + if (MCF_FEC_EIR(ch) & MCF_FEC_EIR_MII) + break; + } + + if(timeout == FEC_MII_TIMEOUT) + return 1; + + /* + * Clear the MII interrupt bit + */ + MCF_FEC_EIR(ch) = MCF_FEC_EIR_MII; + + *data = (uint16_t)(MCF_FEC_MMFR(ch) & 0x0000FFFF); + + return 0; +} + +/* + * Initialize the MII interface controller + * + * Parameters: + * ch FEC channel + * sys_clk System Clock Frequency (in MHz) + */ +void +fec_mii_init(uint8_t ch, uint32_t sys_clk) +{ + ASSERT(ch == 0 || ch == 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 + * + * Parameters: + * ch FEC channel + */ +void +fec_mib_init(uint8_t ch) +{ + ASSERT(ch == 0 || ch == 1); +//To do +} + +/* Display the MIB counters + * + * Parameters: + * ch FEC channel + */ +void +fec_mib_dump(uint8_t ch) +{ + ASSERT(ch == 0 || ch == 1); +//To do +} + +/* Initialize the FEC log + * + * Parameters: + * ch FEC channel + */ +void +fec_log_init(uint8_t ch) +{ + ASSERT(ch == 0 || ch == 1); + memset(&fec_log[ch],0,sizeof(FEC_EVENT_LOG)); +} + +/* Display the FEC log + * + * Parameters: + * ch FEC channel + */ +void +fec_log_dump(uint8_t ch) +{ + ASSERT(ch == 0 || ch == 1); + printf("\n FEC%d Log\n---------------\n",ch); + printf("Total: %4d\n",fec_log[ch].total); + printf("hberr: %4d\n",fec_log[ch].hberr); + printf("babr: %4d\n",fec_log[ch].babr); + printf("babt: %4d\n",fec_log[ch].babt); + printf("gra: %4d\n",fec_log[ch].gra); + printf("txf: %4d\n",fec_log[ch].txf); + printf("mii: %4d\n",fec_log[ch].mii); + printf("lc: %4d\n",fec_log[ch].lc); + printf("rl: %4d\n",fec_log[ch].rl); + printf("xfun: %4d\n",fec_log[ch].xfun); + printf("xferr: %4d\n",fec_log[ch].xferr); + printf("rferr: %4d\n",fec_log[ch].rferr); + printf("dtxf: %4d\n",fec_log[ch].dtxf); + printf("drxf: %4d\n",fec_log[ch].drxf); + printf("\nRFSW:\n"); + printf("inv: %4d\n",fec_log[ch].rfsw_inv); + printf("m: %4d\n",fec_log[ch].rfsw_m); + printf("bc: %4d\n",fec_log[ch].rfsw_bc); + printf("mc: %4d\n",fec_log[ch].rfsw_mc); + printf("lg: %4d\n",fec_log[ch].rfsw_lg); + printf("no: %4d\n",fec_log[ch].rfsw_no); + printf("cr: %4d\n",fec_log[ch].rfsw_cr); + printf("ov: %4d\n",fec_log[ch].rfsw_ov); + printf("tr: %4d\n",fec_log[ch].rfsw_tr); + printf("---------------\n\n"); +} + +/* + * Display some of the registers for debugging + * + * Parameters: + * ch FEC channel + */ +void +fec_debug_dump(uint8_t ch) +{ + printf("\n------------- FEC%d -------------\n",ch); + printf("EIR %08x \n",MCF_FEC_EIR(ch)); + printf("EIMR %08x \n",MCF_FEC_EIMR(ch)); + printf("ECR %08x \n",MCF_FEC_ECR(ch)); + printf("RCR %08x \n",MCF_FEC_RCR(ch)); + printf("R_HASH %08x \n",MCF_FEC_R_HASH(ch)); + printf("TCR %08x \n",MCF_FEC_TCR(ch)); + printf("FECTFWR %08x \n",MCF_FEC_FECTFWR(ch)); + printf("FECRFSR %08x \n",MCF_FEC_FECRFSR(ch)); + printf("FECRFCR %08x \n",MCF_FEC_FECRFCR(ch)); + printf("FECRLRFP %08x \n",MCF_FEC_FECRLRFP(ch)); + printf("FECRLWFP %08x \n",MCF_FEC_FECRLWFP(ch)); + printf("FECRFAR %08x \n",MCF_FEC_FECRFAR(ch)); + printf("FECRFRP %08x \n",MCF_FEC_FECRFRP(ch)); + printf("FECRFWP %08x \n",MCF_FEC_FECRFWP(ch)); + printf("FECTFSR %08x \n",MCF_FEC_FECTFSR(ch)); + printf("FECTFCR %08x \n",MCF_FEC_FECTFCR(ch)); + printf("FECTLRFP %08x \n",MCF_FEC_FECTLRFP(ch)); + printf("FECTLWFP %08x \n",MCF_FEC_FECTLWFP(ch)); + printf("FECTFAR %08x \n",MCF_FEC_FECTFAR(ch)); + printf("FECTFRP %08x \n",MCF_FEC_FECTFRP(ch)); + printf("FECTFWP %08x \n",MCF_FEC_FECTFWP(ch)); + printf("FRST %08x \n",MCF_FEC_FRST(ch)); + printf("--------------------------------\n\n"); +} + +/* + * Set the duplex on the selected FEC controller + * + * Parameters: + * ch FEC channel + * duplex FEC_MII_FULL_DUPLEX or FEC_MII_HALF_DUPLEX + */ +void +fec_duplex (uint8_t ch, uint8_t duplex) +{ + ASSERT(ch == 0 || ch == 1); + + 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; + } +} + +/* + * Generate the hash table settings for the given address + * + * Parameters: + * addr 48-bit (6 byte) Address to generate the hash for + * + * Return Value: + * The 6 most significant bits of the 32-bit CRC result + */ +uint8_t +fec_hash_address(const uint8_t *addr) +{ + 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); +} + +/* + * Set the Physical (Hardware) Address and the Individual Address + * Hash in the selected FEC + * + * Parameters: + * ch FEC channel + * pa Physical (Hardware) Address for the selected FEC + */ +void +fec_set_address (uint8_t ch, const uint8_t *pa) +{ + uint8_t crc; + + ASSERT(ch == 0 || ch == 1); + + /* + * Set the Physical Address + */ + MCF_FEC_PALR(ch) = (uint32_t)((pa[0]<<24) | (pa[1]<<16) | (pa[2]<<8) | pa[3]); + MCF_FEC_PAUR(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); +} + +/* + * Reset the selected FEC controller + * + * Parameters: + * ch FEC channel + */ +void +fec_reset (uint8_t ch) +{ + int i; + + ASSERT(ch == 0 || ch == 1); + + /* 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_FECRFSR_OF + | MCF_FEC_FECRFSR_UF + | MCF_FEC_FECRFSR_RXW + | MCF_FEC_FECRFSR_FAE + | MCF_FEC_FECRFSR_IP); + + /* Reset the FIFOs */ + MCF_FEC_FRST(ch) |= MCF_FEC_FRST_SW_RST; + MCF_FEC_FRST(ch) &= ~MCF_FEC_FRST_SW_RST; + + /* 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(); +} + +/* + * Initialize the selected FEC + * + * Parameters: + * ch FEC channel + * mode External interface mode (MII, 7-wire, or internal loopback) + * pa Physical (Hardware) Address for the selected FEC + */ +void +fec_init (uint8_t ch, uint8_t mode, const uint8_t *pa) +{ + ASSERT(ch == 0 || ch == 1); + + /* + * Enable all the external interface signals + */ + if (mode == FEC_MODE_7WIRE) + { + if (ch == 1) + MCF_GPIO_PAR_FECI2CIRQ |= MCF_GPIO_PAR_FECI2CIRQ_PAR_E17; + else + MCF_GPIO_PAR_FECI2CIRQ |= MCF_GPIO_PAR_FECI2CIRQ_PAR_E07; + } + else if (mode == FEC_MODE_MII) + { + if (ch == 1) + MCF_GPIO_PAR_FECI2CIRQ |= 0 + | MCF_GPIO_PAR_FECI2CIRQ_PAR_E1MDC_EMDC + | MCF_GPIO_PAR_FECI2CIRQ_PAR_E1MDIO_EMDIO + | MCF_GPIO_PAR_FECI2CIRQ_PAR_E1MII + | MCF_GPIO_PAR_FECI2CIRQ_PAR_E17; + else + MCF_GPIO_PAR_FECI2CIRQ |= 0 + | MCF_GPIO_PAR_FECI2CIRQ_PAR_E0MDC + | MCF_GPIO_PAR_FECI2CIRQ_PAR_E0MDIO + | MCF_GPIO_PAR_FECI2CIRQ_PAR_E0MII + | MCF_GPIO_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; + + /* + * 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; + + /* + * 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) + #ifdef FEC_PROMISCUOUS + | MCF_FEC_RCR_PROM + #endif + | MCF_FEC_RCR_FCE; + + 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; + + /* + * 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_FRM + | 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_FRM + | MCF_FEC_FECTFCR_TXW_MSK + | 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_CTCWR(ch) = 0 + | MCF_FEC_CTCWR_TFCW + | MCF_FEC_CTCWR_CRC; +} + +/* + * Start the FEC Rx DMA task + * + * Parameters: + * ch FEC channel + * rxbd First Rx buffer descriptor in the chain + */ +void +fec_rx_start(uint8_t ch, int8_t *rxbd) +{ + uint32_t initiator; + int channel, result; + + ASSERT(ch == 0 || ch == 1); + + /* + * Make the initiator assignment + */ + result = dma_set_initiator(DMA_FEC_RX(ch)); + ASSERT(result == 0); + + /* + * Grab the initiator number + */ + initiator = dma_get_initiator(DMA_FEC_RX(ch)); + + /* + * 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); + ASSERT(channel != -1); + + /* + * Start the Rx DMA task + */ + /* + * Start the Rx DMA task + */ + MCD_startDma(channel, + (s8*)rxbd, + 0, + (s8*)MCF_FEC_FECRFDR_ADDR(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 + ); +} + +/* + * Continue the Rx DMA task + * + * This routine is called after the DMA task has halted after + * encountering an Rx buffer descriptor that wasn't marked as + * ready. There is no harm in calling the DMA continue routine + * if the DMA is not halted. + * + * Parameters: + * ch FEC channel + */ +void +fec_rx_continue(uint8_t ch) +{ + int channel; + + ASSERT(ch == 0 || ch == 1); + + /* + * Determine the DMA channel running the task for the + * selected FEC + */ + channel = dma_get_channel(DMA_FEC_RX(ch)); + ASSERT(channel != -1); + + /* + * Continue/restart the DMA task + */ + MCD_continDma(channel); +} + +/* + * Stop all frame receptions on the selected FEC + * + * Parameters: + * ch FEC channel + */ +void +fec_rx_stop (uint8_t ch) +{ + uint32_t mask; + int channel; + + ASSERT(ch == 0 || ch == 1); + + /* Save off the EIMR value */ + mask = MCF_FEC_EIMR(ch); + + /* 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)); + ASSERT(channel != -1); + + /* 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 DMA channel */ + dma_free_channel(DMA_FEC_RX(ch)); + + /* Restore the interrupt mask register value */ + MCF_FEC_EIMR(ch) = mask; +} + +/* + * Receive Frame interrupt handler - this handler is called by the + * DMA interrupt handler indicating that a packet was successfully + * transferred out of the Rx FIFO. + * + * Parameters: + * nif Pointer to Network Interface structure + * ch FEC channel + */ +NBUF * +fec_rx_frame(uint8_t ch, NIF *nif) +{ +// ETH_HDR *eth_hdr; + FECBD *pRxBD; + NBUF *cur_nbuf, *new_nbuf; + int keep; + + 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++; + } + + if (keep) + { + /* + * Pull the network buffer off the Rx ring queue + */ + cur_nbuf = nbuf_remove(NBUF_RX_RING); + ASSERT(cur_nbuf); + ASSERT(cur_nbuf->data == pRxBD->data); + + /* + * 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; + cur_nbuf->length = (pRxBD->length - (ETH_CRC_LEN)); + cur_nbuf->offset = 0; + + /* + * Get a new buffer pointer for this buffer descriptor + */ + new_nbuf = nbuf_alloc(); + if (new_nbuf == NULL) + { + #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG + printf("nbuf_alloc() failed\n"); + #endif + /* + * 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; + } + + /* + * 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; + + + /* + * 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; + + /* + * Pass the received packet up the network stack if the + * protocol is supported in our network interface (NIF) + */ +//FIXME if (nif_protocol_exist(nif,eth_hdr->type)) +// { +// nif_protocol_handler(nif, eth_hdr->type, cur_nbuf); +// } +// else +// nbuf_free(cur_nbuf); + return(cur_nbuf); + } + 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); + + /* + * Let the DMA know that there are new Rx BDs (in case + * it is waiting for an empty one) + */ + fec_rx_continue(ch); + } + } + return NULL; +} + +void +fec0_rx_frame(void) +{ +// extern NIF nif1; +// fec_rx_frame(0, 0); +} + +void +fec1_rx_frame(void) +{ +// extern NIF nif1; +// fec_rx_frame(1, 0); +} + +/* + * Start the FEC Tx DMA task + * + * Parameters: + * ch FEC channel + * txbd First Tx buffer descriptor in the chain + */ +void +fec_tx_start(uint8_t ch, int8_t *txbd) +{ + uint32_t initiator; + int channel, result; + void fec0_tx_frame(void); + void fec1_tx_frame(void); + + /* + * Make the initiator assignment + */ + result = dma_set_initiator(DMA_FEC_TX(ch)); + ASSERT(result == 0); + + /* + * Grab the initiator number + */ + initiator = dma_get_initiator(DMA_FEC_TX(ch)); + ASSERT(initiator != 0); + + /* + * 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); + ASSERT(channel != -1); + + /* + * Start the Tx DMA task + */ + MCD_startDma(channel, + (s8*)txbd, + 0, + (s8*)MCF_FEC_FECTFDR_ADDR(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 + ); +} + +/* + * Continue the Tx DMA task + * + * This routine is called after the DMA task has halted after + * encountering an Tx buffer descriptor that wasn't marked as + * ready. There is no harm in calling the continue DMA routine + * if the DMA was not paused. + * + * Parameters: + * ch FEC channel + */ +void +fec_tx_continue(uint8_t ch) +{ + int channel; + + /* + * Determine the DMA channel running the task for the + * selected FEC + */ + channel = dma_get_channel(DMA_FEC_TX(ch)); + ASSERT(channel > 0); + + /* + * Continue/restart the DMA task + */ + MCD_continDma((int)channel); +} + +/* + * Stop all transmissions on the selected FEC and kill the DMA task + * + * Parameters: + * ch FEC channel + */ +void +fec_tx_stop (uint8_t ch) +{ + uint32_t mask; + int channel; + + ASSERT(ch == 0 || ch == 1); + + /* Save off the EIMR value */ + mask = MCF_FEC_EIMR(ch); + + /* 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; + + /* 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; + } + + /* + * Determine the DMA channel running the task for the + * selected FEC + */ + channel = dma_get_channel(DMA_FEC_TX(ch)); + ASSERT(channel > 0); + + /* 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 DMA channel */ + dma_free_channel(DMA_FEC_TX(ch)); + + /* Restore the interrupt mask register value */ + MCF_FEC_EIMR(ch) = mask; +} + +/* + * Trasmit Frame interrupt handler - this handler is called by the + * DMA interrupt handler indicating that a packet was successfully + * transferred to the Tx FIFO. + * + * Parameters: + * ch FEC channel + */ +void +fec_tx_frame(uint8_t ch) +{ + FECBD *pTxBD; + NBUF *pNbuf; + + 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); + ASSERT(pNbuf); + ASSERT(pNbuf->data == pTxBD->data); + + /* + * Free up the network buffer that was just transmitted + */ + nbuf_free(pNbuf); + + /* + * Re-initialize the Tx BD + */ + pTxBD->data = NULL; + pTxBD->length = 0; + } +} + +void +fec0_tx_frame(void) +{ + fec_tx_frame(0); +} + +void +fec1_tx_frame(void) +{ + fec_tx_frame(1); +} + +/* + * Send a packet out the selected FEC + * + * Parameters: + * ch FEC channel + * nif Pointer to Network Interface (NIF) structure + * dst Destination MAC Address + * src Source MAC Address + * type Ethernet Frame Type + * length Number of bytes to be transmitted (doesn't include type, + * src, or dest byte count) + * pkt Pointer packet network buffer + * + * Return Value: + * 1 success + * 0 otherwise + */ +int +fec_send (uint8_t ch, NIF *nif, uint8_t *dst, uint8_t *src, uint16_t type, NBUF *nbuf) +{ + FECBD *pTxBD; + ASSERT(ch == 0 || ch == 1); + + /* Check the length */ + if ((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); + + /* + * 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); + + /* + * 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); + + 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); +} + +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); +} + +/* + * Enable interrupts on the selected FEC + * + * Parameters: + * ch FEC channel + * pri Interrupt Priority + * lvl Interrupt Level + */ +void +fec_irq_enable(uint8_t ch, uint8_t lvl, uint8_t pri) +{ + ASSERT(ch == 0 || ch == 1); + ASSERT(lvl > 0 && lvl < 8); + ASSERT(pri < 8); + + /* + * Setup the appropriate ICR + */ + MCF_INTC_ICRn((ch == 0) ? 39 : 38) = (uint8_t)(0 + | MCF_INTC_ICRn_IP(pri) + | MCF_INTC_ICRn_IL(lvl)); + + /* + * 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 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; +} + +/* + * Disable interrupts on the selected FEC + * + * Parameters: + * ch FEC channel + */ +void +fec_irq_disable(uint8_t ch) +{ + ASSERT(ch == 0 || ch == 1); + + /* + * 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; +} + +/* + * FEC interrupt handler + * All interrupts are multiplexed into a single vector for each + * FEC module. The lower level interrupt handler passes in the + * channel to this handler. Note that the receive interrupt is + * generated by the Multi-channel DMA FEC Rx task. + * + * Parameters: + * ch FEC channel + */ +static void +fec_irq_handler(uint8_t ch) +{ + 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); + + #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG + if (event != eir) + printf("Pending but not enabled: 0x%08X\n",(event ^ eir)); + #endif + + /* + * 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++; + #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG + printf("RFERR\n"); + printf("FECRFSR%d = 0x%08x\n",ch,MCF_FEC_FECRFSR(ch)); + fec_eth_stop(ch); + #endif + } + if (event & MCF_FEC_EIR_XFERR) + { + fec_log[ch].total++; + fec_log[ch].xferr++; + #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG + printf("XFERR\n"); + #endif + } + if (event & MCF_FEC_EIR_XFUN) + { + fec_log[ch].total++; + fec_log[ch].xfun++; + #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG + printf("XFUN\n"); + fec_eth_stop(ch); + #endif + } + if (event & MCF_FEC_EIR_RL) + { + fec_log[ch].total++; + fec_log[ch].rl++; + #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG + printf("RL\n"); + #endif + } + if (event & MCF_FEC_EIR_LC) + { + fec_log[ch].total++; + fec_log[ch].lc++; + #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG + printf("LC\n"); + #endif + } + if (event & MCF_FEC_EIR_MII) + { + fec_log[ch].mii++; + } + if (event & MCF_FEC_EIR_TXF) + { + fec_log[ch].txf++; + } + if (event & MCF_FEC_EIR_GRA) + { + fec_log[ch].gra++; + } + if (event & MCF_FEC_EIR_BABT) + { + fec_log[ch].total++; + fec_log[ch].babt++; + #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG + printf("BABT\n"); + #endif + } + if (event & MCF_FEC_EIR_BABR) + { + fec_log[ch].total++; + fec_log[ch].babr++; + #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG + printf("BABR\n"); + #endif + } + if (event & MCF_FEC_EIR_HBERR) + { + fec_log[ch].total++; + fec_log[ch].hberr++; + #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG + printf("HBERR\n"); + #endif + } +} + +int +fec0_interrupt_handler(void* arg1, void* arg2) +{ + (void) arg1; + (void) arg2; + fec_irq_handler(0); + return 1; +} + +int +fec1_interrupt_handler(void* arg1, void* arg2) +{ + (void) arg1; + (void) arg2; + fec_irq_handler(1); + return 1; +} + +/* + * Configure the selected Ethernet port and enable all operations + * + * Parameters: + * ch FEC channel + * trcvr Transceiver mode (MII, 7-Wire or internal loopback) + * speed Maximum operating speed (MII only) + * duplex Full or Half-duplex (MII only) + * mac Physical (MAC) Address + */ +void +fec_eth_setup(uint8_t ch, uint8_t trcvr, uint8_t speed, uint8_t duplex, const uint8_t *mac) +{ + ASSERT(ch == 0 || ch == 1); + + /* + * Disable FEC interrupts + */ + fec_irq_disable(ch); + + /* + * Initialize the event log + */ + fec_log_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); + + if (trcvr == FEC_MODE_MII) + { + /* + * Initialize the MII interface + */ + fec_mii_init(ch, CFG_SYSTEM_CORE_CLOCK); + } + + /* + * 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 FEC channel + */ + MCF_FEC_ECR(ch) |= MCF_FEC_ECR_ETHER_EN; +} +/* + * Reset the selected Ethernet port + * + * Parameters: + * ch FEC channel + */ +void +fec_eth_reset(uint8_t ch) +{ +// To do +} + +/* + * Stop the selected Ethernet port + * + * Parameters: + * ch FEC channel + */ +void +fec_eth_stop(uint8_t ch) +{ + int level; + + /* + * Disable interrupts + */ + level = asm_set_ipl(7); + + /* + * Gracefully disable the receiver and transmitter + */ + fec_tx_stop(ch); + fec_rx_stop(ch); + + /* + * Disable FEC interrupts + */ + fec_irq_disable(ch); + + /* + * Disable the FEC channel + */ + MCF_FEC_ECR(ch) &= ~MCF_FEC_ECR_ETHER_EN; + + #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG + nbuf_debug_dump(); + fec_log_dump(ch); + #endif + + /* + * Flush the network buffers + */ + nbuf_flush(); + + /* + * Restore interrupt level + */ + asm_set_ipl(level); +} diff --git a/arch/m68k/mach-mcfv4e/fecbd.c b/arch/m68k/mach-mcfv4e/fecbd.c new file mode 100644 index 0000000000..26fb16d98d --- /dev/null +++ b/arch/m68k/mach-mcfv4e/fecbd.c @@ -0,0 +1,232 @@ +/* + * File: fecbd.c + * Purpose: Provide a simple buffer management driver + * + * Notes: + */ +#include +#include + +#include +#include +#include +#include +#include +#include + +#define ASSERT(x) if (!(x)) hang(); + +/* + * This implements a simple static buffer descriptor + * ring for each channel and each direction + * + * FEC Buffer Descriptors need to be aligned to a 4-byte boundary. + * In order to accomplish this, data is over-allocated and manually + * aligned at runtime + * + * Enough space is allocated for each of the two FEC channels to have + * NRXBD Rx BDs and NTXBD Tx BDs + * + */ +FECBD unaligned_bds[(2 * NRXBD) + (2 * NTXBD) + 1]; + +/* + * These pointers are used to reference into the chunck of data set + * aside for buffer descriptors + */ +FECBD *RxBD; +FECBD *TxBD; + +/* + * Macros to easier access to the BD ring + */ +#define RxBD(ch,i) RxBD[(ch * NRXBD) + i] +#define TxBD(ch,i) TxBD[(ch * NTXBD) + i] + +/* + * Buffer descriptor indexes + */ +static int iTxbd_new; +static int iTxbd_old; +static int iRxbd; + +/* + * Initialize the FEC Buffer Descriptor ring + * Buffer Descriptor format is defined by the MCDAPI + * + * Parameters: + * ch FEC channel + */ +void +fecbd_init(uint8_t ch) +{ + NBUF *nbuf; + int i; + + /* + * Align Buffer Descriptors to 4-byte boundary + */ + RxBD = (FECBD *)(((int)unaligned_bds + 3) & 0xFFFFFFFC); + TxBD = (FECBD *)((int)RxBD + (sizeof(FECBD) * 2 * NRXBD)); + + /* + * Initialize the Rx Buffer Descriptor ring + */ + for (i = 0; i < NRXBD; ++i) + { + /* Grab a network buffer from the free list */ + nbuf = nbuf_alloc(); + ASSERT(nbuf); + + /* Initialize the BD */ + RxBD(ch,i).status = RX_BD_E | RX_BD_INTERRUPT; + RxBD(ch,i).length = RX_BUF_SZ; + RxBD(ch,i).data = nbuf->data; + + /* Add the network buffer to the Rx queue */ + nbuf_add(NBUF_RX_RING, nbuf); + } + + /* + * Set the WRAP bit on the last one + */ + RxBD(ch,i-1).status |= RX_BD_W; + + /* + * Initialize the Tx Buffer Descriptor ring + */ + for (i = 0; i < NTXBD; ++i) + { + TxBD(ch,i).status = TX_BD_INTERRUPT; + TxBD(ch,i).length = 0; + TxBD(ch,i).data = NULL; + } + + /* + * Set the WRAP bit on the last one + */ + TxBD(ch,i-1).status |= TX_BD_W; + + /* + * Initialize the buffer descriptor indexes + */ + iTxbd_new = iTxbd_old = iRxbd = 0; +} + +void +fecbd_dump(uint8_t ch) +{ + #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG + int i; + + printf("\n------------ FEC%d BDs -----------\n",ch); + printf("RxBD Ring\n"); + for (i=0; i +#include +#include +#include + +/* + * This is an API-internal pointer to the DMA's registers + */ +dmaRegs *MCD_dmaBar; + +/* + * These are the real and model task tables as generated by the + * build process + */ +extern TaskTableEntry MCD_realTaskTableSrc[NCHANNELS]; +extern TaskTableEntry MCD_modelTaskTableSrc[NUMOFVARIANTS]; + +/* + * However, this (usually) gets relocated to on-chip SRAM, at which + * point we access them as these tables + */ +volatile TaskTableEntry *MCD_taskTable; +TaskTableEntry *MCD_modelTaskTable; + + +/* + * MCD_chStatus[] is an array of status indicators for remembering + * whether a DMA has ever been attempted on each channel, pausing + * status, etc. + */ +static int MCD_chStatus[NCHANNELS] = +{ + MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, + MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, + MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, + MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA, MCD_NO_DMA +}; + +/* + * Prototypes for local functions + */ +static void MCD_memcpy (int *dest, int *src, u32 size); +static void MCD_resmActions (int channel); + +/* + * Buffer descriptors used for storage of progress info for single Dmas + * Also used as storage for the DMA for CRCs for single DMAs + * Otherwise, the DMA does not parse these buffer descriptors + */ +#ifdef MCD_INCLUDE_EU +extern MCD_bufDesc MCD_singleBufDescs[NCHANNELS]; +#else +MCD_bufDesc MCD_singleBufDescs[NCHANNELS]; +#endif +MCD_bufDesc *MCD_relocBuffDesc; + + +/* + * Defines for the debug control register's functions + */ +#define DBG_CTL_COMP1_TASK (0x00002000) /* have comparator 1 look for a task # */ +#define DBG_CTL_ENABLE (DBG_CTL_AUTO_ARM | \ + DBG_CTL_BREAK | \ + DBG_CTL_INT_BREAK | \ + DBG_CTL_COMP1_TASK) +#define DBG_CTL_DISABLE (DBG_CTL_AUTO_ARM | \ + DBG_CTL_INT_BREAK | \ + DBG_CTL_COMP1_TASK) +#define DBG_KILL_ALL_STAT (0xFFFFFFFF) + +/* + * Offset to context save area where progress info is stored + */ +#define CSAVE_OFFSET 10 + +/* + * Defines for Byte Swapping + */ +#define MCD_BYTE_SWAP_KILLER 0xFFF8888F +#define MCD_NO_BYTE_SWAP_ATALL 0x00040000 + +/* + * Execution Unit Identifiers + */ +#define MAC 0 /* legacy - not used */ +#define LUAC 1 /* legacy - not used */ +#define CRC 2 /* legacy - not used */ +#define LURC 3 /* Logic Unit with CRC */ + +/* + * Task Identifiers + */ +#define TASK_CHAINNOEU 0 +#define TASK_SINGLENOEU 1 +#ifdef MCD_INCLUDE_EU +#define TASK_CHAINEU 2 +#define TASK_SINGLEEU 3 +#define TASK_FECRX 4 +#define TASK_FECTX 5 +#else +#define TASK_CHAINEU 0 +#define TASK_SINGLEEU 1 +#define TASK_FECRX 2 +#define TASK_FECTX 3 +#endif + +/* + * Structure to remember which variant is on which channel + * TBD- need this? + */ +typedef struct MCD_remVariants_struct MCD_remVariant; +struct MCD_remVariants_struct +{ + int remDestRsdIncr[NCHANNELS]; /* -1,0,1 */ + int remSrcRsdIncr[NCHANNELS]; /* -1,0,1 */ + s16 remDestIncr[NCHANNELS]; /* DestIncr */ + s16 remSrcIncr[NCHANNELS]; /* srcIncr */ + u32 remXferSize[NCHANNELS]; /* xferSize */ +}; + +/* + * Structure to remember the startDma parameters for each channel + */ +MCD_remVariant MCD_remVariants; + +/* + * Function: MCD_initDma + * Purpose: Initializes the DMA API by setting up a pointer to the DMA + * registers, relocating and creating the appropriate task + * structures, and setting up some global settings + * Arguments: + * dmaBarAddr - pointer to the multichannel DMA registers + * taskTableDest - location to move DMA task code and structs to + * flags - operational parameters + * Return Value: + * MCD_TABLE_UNALIGNED if taskTableDest is not 512-byte aligned + * MCD_OK otherwise + */ +extern u32 MCD_funcDescTab0[]; + +int MCD_initDma (dmaRegs *dmaBarAddr, void *taskTableDest, u32 flags) +{ + int i; + TaskTableEntry *entryPtr; + + /* setup the local pointer to register set */ + MCD_dmaBar = dmaBarAddr; + + /* do we need to move/create a task table */ + if ((flags & MCD_RELOC_TASKS) != 0) + { + int fixedSize; + u32 *fixedPtr; + /*int *tablePtr = taskTableDest;TBD*/ + int varTabsOffset, funcDescTabsOffset, contextSavesOffset; + int taskDescTabsOffset; + int taskTableSize, varTabsSize, funcDescTabsSize, contextSavesSize; + int taskDescTabSize; + + int i; + + /* check if physical address is aligned on 512 byte boundary */ + if (((u32)taskTableDest & 0x000001ff) != 0) + return(MCD_TABLE_UNALIGNED); + + MCD_taskTable = taskTableDest; /* set up local pointer to task Table */ + + /* + * Create a task table: + * - compute aligned base offsets for variable tables and + * function descriptor tables, then + * - loop through the task table and setup the pointers + * - copy over model task table with the the actual task descriptor + * tables + */ + + taskTableSize = NCHANNELS * sizeof(TaskTableEntry); + /* align variable tables to size */ + varTabsOffset = taskTableSize + (u32)taskTableDest; + if ((varTabsOffset & (VAR_TAB_SIZE - 1)) != 0) + varTabsOffset = (varTabsOffset + VAR_TAB_SIZE) & (~VAR_TAB_SIZE); + /* align function descriptor tables */ + varTabsSize = NCHANNELS * VAR_TAB_SIZE; + funcDescTabsOffset = varTabsOffset + varTabsSize; + + if ((funcDescTabsOffset & (FUNCDESC_TAB_SIZE - 1)) != 0) + funcDescTabsOffset = (funcDescTabsOffset + FUNCDESC_TAB_SIZE) & + (~FUNCDESC_TAB_SIZE); + + funcDescTabsSize = FUNCDESC_TAB_NUM * FUNCDESC_TAB_SIZE; + contextSavesOffset = funcDescTabsOffset + funcDescTabsSize; + contextSavesSize = (NCHANNELS * CONTEXT_SAVE_SIZE); + fixedSize = taskTableSize + varTabsSize + funcDescTabsSize + + contextSavesSize; + + /* zero the thing out */ + fixedPtr = (u32 *)taskTableDest; + for (i = 0;i<(fixedSize/4);i++) + fixedPtr[i] = 0; + + entryPtr = (TaskTableEntry*)MCD_taskTable; + /* set up fixed pointers */ + for (i = 0; i < NCHANNELS; i++) + { + entryPtr[i].varTab = (u32)varTabsOffset; /* update ptr to local value */ + entryPtr[i].FDTandFlags = (u32)funcDescTabsOffset | MCD_TT_FLAGS_DEF; + entryPtr[i].contextSaveSpace = (u32)contextSavesOffset; + varTabsOffset += VAR_TAB_SIZE; +#ifdef MCD_INCLUDE_EU /* if not there is only one, just point to the same one */ + funcDescTabsOffset += FUNCDESC_TAB_SIZE; +#endif + contextSavesOffset += CONTEXT_SAVE_SIZE; + } + /* copy over the function descriptor table */ + for ( i = 0; i < FUNCDESC_TAB_NUM; i++) + { + MCD_memcpy((void*)(entryPtr[i].FDTandFlags & ~MCD_TT_FLAGS_MASK), + (void*)MCD_funcDescTab0, FUNCDESC_TAB_SIZE); + } + + /* copy model task table to where the context saves stuff leaves off*/ + MCD_modelTaskTable = (TaskTableEntry*)contextSavesOffset; + + MCD_memcpy ((void*)MCD_modelTaskTable, (void*)MCD_modelTaskTableSrc, + NUMOFVARIANTS * sizeof(TaskTableEntry)); + + entryPtr = MCD_modelTaskTable; /* point to local version of + model task table */ + taskDescTabsOffset = (u32)MCD_modelTaskTable + + (NUMOFVARIANTS * sizeof(TaskTableEntry)); + + /* copy actual task code and update TDT ptrs in local model task table */ + for (i = 0; i < NUMOFVARIANTS; i++) + { + taskDescTabSize = entryPtr[i].TDTend - entryPtr[i].TDTstart + 4; + MCD_memcpy ((void*)taskDescTabsOffset, (void*)entryPtr[i].TDTstart, taskDescTabSize); + entryPtr[i].TDTstart = (u32)taskDescTabsOffset; + taskDescTabsOffset += taskDescTabSize; + entryPtr[i].TDTend = (u32)taskDescTabsOffset - 4; + } +#ifdef MCD_INCLUDE_EU /* Tack single DMA BDs onto end of code so API controls + where they are since DMA might write to them */ + MCD_relocBuffDesc = (MCD_bufDesc*)(entryPtr[NUMOFVARIANTS - 1].TDTend + 4); +#else /* DMA does not touch them so they can be wherever and we don't need to + waste SRAM on them */ + MCD_relocBuffDesc = MCD_singleBufDescs; +#endif + } + else + { + /* point the would-be relocated task tables and the + buffer descriptors to the ones the linker generated */ + + if (((u32)MCD_realTaskTableSrc & 0x000001ff) != 0) + return(MCD_TABLE_UNALIGNED); + + /* need to add code to make sure that every thing else is aligned properly TBD*/ + /* this is problematic if we init more than once or after running tasks, + need to add variable to see if we have aleady init'd */ + entryPtr = MCD_realTaskTableSrc; + for (i = 0; i < NCHANNELS; i++) + { + if (((entryPtr[i].varTab & (VAR_TAB_SIZE - 1)) != 0) || + ((entryPtr[i].FDTandFlags & (FUNCDESC_TAB_SIZE - 1)) != 0)) + return(MCD_TABLE_UNALIGNED); + } + + MCD_taskTable = MCD_realTaskTableSrc; + MCD_modelTaskTable = MCD_modelTaskTableSrc; + MCD_relocBuffDesc = MCD_singleBufDescs; + } + + + /* Make all channels as totally inactive, and remember them as such: */ + + MCD_dmaBar->taskbar = (u32) MCD_taskTable; + for (i = 0; i < NCHANNELS; i++) + { + MCD_dmaBar->taskControl[i] = 0x0; + MCD_chStatus[i] = MCD_NO_DMA; + } + + /* Set up pausing mechanism to inactive state: */ + MCD_dmaBar->debugComp1 = 0; /* no particular values yet for either comparator registers */ + MCD_dmaBar->debugComp2 = 0; + MCD_dmaBar->debugControl = DBG_CTL_DISABLE; + MCD_dmaBar->debugStatus = DBG_KILL_ALL_STAT; + + /* enable or disable commbus prefetch, really need an ifdef or + something to keep from trying to set this in the 8220 */ + if ((flags & MCD_COMM_PREFETCH_EN) != 0) + MCD_dmaBar->ptdControl &= ~PTD_CTL_COMM_PREFETCH; + else + MCD_dmaBar->ptdControl |= PTD_CTL_COMM_PREFETCH; + + return(MCD_OK); +} + +/* Function: MCD_dmaStatus + * Purpose: Returns the status of the DMA on the requested channel + * Arguments: channel - channel number + * Returns: Predefined status indicators + */ +int MCD_dmaStatus (int channel) +{ + u16 tcrValue; + + if((channel < 0) || (channel >= NCHANNELS)) + return(MCD_CHANNEL_INVALID); + + tcrValue = MCD_dmaBar->taskControl[channel]; + if ((tcrValue & TASK_CTL_EN) == 0) + { /* nothing running */ + /* if last reported with task enabled */ + if ( MCD_chStatus[channel] == MCD_RUNNING + || MCD_chStatus[channel] == MCD_IDLE) + MCD_chStatus[channel] = MCD_DONE; + } + else /* something is running */ + { + /* There are three possibilities: paused, running or idle. */ + if ( MCD_chStatus[channel] == MCD_RUNNING + || MCD_chStatus[channel] == MCD_IDLE) + { + MCD_dmaBar->ptdDebug = PTD_DBG_TSK_VLD_INIT; + /* This register is selected to know which initiator is + actually asserted. */ + if ((MCD_dmaBar->ptdDebug >> channel ) & 0x1 ) + MCD_chStatus[channel] = MCD_RUNNING; + else + MCD_chStatus[channel] = MCD_IDLE; + /* do not change the status if it is already paused. */ + } + } + return MCD_chStatus[channel]; +} + +/* Function: MCD_startDma + * Ppurpose: Starts a particular kind of DMA + * Arguments: see below + * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK + */ + +int MCD_startDma ( + int channel, /* the channel on which to run the DMA */ + s8 *srcAddr, /* the address to move data from, or physical buffer-descriptor address */ + s16 srcIncr, /* the amount to increment the source address per transfer */ + s8 *destAddr, /* the address to move data to */ + s16 destIncr, /* the amount to increment the destination address per transfer */ + u32 dmaSize, /* the number of bytes to transfer independent of the transfer size */ + u32 xferSize, /* the number bytes in of each data movement (1, 2, or 4) */ + u32 initiator, /* what device initiates the DMA */ + int priority, /* priority of the DMA */ + u32 flags, /* flags describing the DMA */ + u32 funcDesc /* a description of byte swapping, bit swapping, and CRC actions */ +#ifdef MCD_NEED_ADDR_TRANS + s8 *srcAddrVirt /* virtual buffer descriptor address TBD*/ +#endif +) +{ + int srcRsdIncr, destRsdIncr; + int *cSave; + short xferSizeIncr; + int tcrCount = 0; +#ifdef MCD_INCLUDE_EU + u32 *realFuncArray; +#endif + + if((channel < 0) || (channel >= NCHANNELS)) + return(MCD_CHANNEL_INVALID); + + /* tbd - need to determine the proper response to a bad funcDesc when not + including EU functions, for now, assign a benign funcDesc, but maybe + should return an error */ +#ifndef MCD_INCLUDE_EU + funcDesc = MCD_FUNC_NOEU1; +#endif + +#ifdef MCD_DEBUG +printf("startDma:Setting up params\n"); +#endif + /* Set us up for task-wise priority. We don't technically need to do this on every start, but + since the register involved is in the same longword as other registers that users are in control + of, setting it more than once is probably preferable. That since the documentation doesn't seem + to be completely consistent about the nature of the PTD control register. */ + MCD_dmaBar->ptdControl |= (u16) 0x8000; +#if 1 /* Not sure what we need to keep here rtm TBD */ + /* Calculate additional parameters to the regular DMA calls. */ + srcRsdIncr = srcIncr < 0 ? -1 : (srcIncr > 0 ? 1 : 0); + destRsdIncr = destIncr < 0 ? -1 : (destIncr > 0 ? 1 : 0); + + xferSizeIncr = (xferSize & 0xffff) | 0x20000000; + + /* Remember for each channel which variant is running. */ + MCD_remVariants.remSrcRsdIncr[channel] = srcRsdIncr; + MCD_remVariants.remDestRsdIncr[channel] = destRsdIncr; + MCD_remVariants.remDestIncr[channel] = destIncr; + MCD_remVariants.remSrcIncr[channel] = srcIncr; + MCD_remVariants.remXferSize[channel] = xferSize; +#endif + + cSave = (int*)(MCD_taskTable[channel].contextSaveSpace) + CSAVE_OFFSET + CURRBD; + +#ifdef MCD_INCLUDE_EU /* may move this to EU specific calls */ + realFuncArray = (u32 *) (MCD_taskTable[channel].FDTandFlags & 0xffffff00); + /* Modify the LURC's normal and byte-residue-loop functions according to parameter. */ + realFuncArray[(LURC*16)] = xferSize == 4 ? + funcDesc : xferSize == 2 ? + funcDesc & 0xfffff00f : funcDesc & 0xffff000f; + realFuncArray[(LURC*16+1)] = (funcDesc & MCD_BYTE_SWAP_KILLER) | MCD_NO_BYTE_SWAP_ATALL; +#endif + /* Write the initiator field in the TCR, and also set the initiator-hold + bit. Note that,due to a hardware quirk, this could collide with an + MDE access to the initiator-register file, so we have to verify that the write + reads back correctly. */ + + MCD_dmaBar->taskControl[channel] = + (initiator << 8) | TASK_CTL_HIPRITSKEN | TASK_CTL_HLDINITNUM; + + while(((MCD_dmaBar->taskControl[channel] & 0x1fff) != + ((initiator << 8) | TASK_CTL_HIPRITSKEN | TASK_CTL_HLDINITNUM)) && + (tcrCount < 1000)) + { + tcrCount++; + /*MCD_dmaBar->ptd_tcr[channel] = (initiator << 8) | 0x0020;*/ + MCD_dmaBar->taskControl[channel] = + (initiator << 8) | TASK_CTL_HIPRITSKEN | TASK_CTL_HLDINITNUM; + } + + MCD_dmaBar->priority[channel] = (u8)priority & PRIORITY_PRI_MASK; + /* should be albe to handle this stuff with only one write to ts reg - tbd */ + if (channel < 8 && channel >= 0) + { + MCD_dmaBar->taskSize0 &= ~(0xf << (7-channel)*4); + MCD_dmaBar->taskSize0 |= (xferSize & 3) << (((7 - channel)*4) + 2); + MCD_dmaBar->taskSize0 |= (xferSize & 3) << ((7 - channel)*4); + } + else + { + MCD_dmaBar->taskSize1 &= ~(0xf << (15-channel)*4); + MCD_dmaBar->taskSize1 |= (xferSize & 3) << (((15 - channel)*4) + 2); + MCD_dmaBar->taskSize1 |= (xferSize & 3) << ((15 - channel)*4); + } + + /* setup task table flags/options which mostly control the line buffers */ + MCD_taskTable[channel].FDTandFlags &= ~MCD_TT_FLAGS_MASK; + MCD_taskTable[channel].FDTandFlags |= (MCD_TT_FLAGS_MASK & flags); + + if (flags & MCD_FECTX_DMA) + { + /* TDTStart and TDTEnd */ + MCD_taskTable[channel].TDTstart = MCD_modelTaskTable[TASK_FECTX].TDTstart; + MCD_taskTable[channel].TDTend = MCD_modelTaskTable[TASK_FECTX].TDTend; + MCD_startDmaENetXmit(srcAddr, srcAddr, destAddr, MCD_taskTable, channel); + } + else if (flags & MCD_FECRX_DMA) + { + /* TDTStart and TDTEnd */ + MCD_taskTable[channel].TDTstart = MCD_modelTaskTable[TASK_FECRX].TDTstart; + MCD_taskTable[channel].TDTend = MCD_modelTaskTable[TASK_FECRX].TDTend; + MCD_startDmaENetRcv(srcAddr, srcAddr, destAddr, MCD_taskTable, channel); + } + else if(flags & MCD_SINGLE_DMA) + { + /* this buffer descriptor is used for storing off initial parameters for later + progress query calculation and for the DMA to write the resulting checksum + The DMA does not use this to determine how to operate, that info is passed + with the init routine*/ + MCD_relocBuffDesc[channel].srcAddr = srcAddr; + MCD_relocBuffDesc[channel].destAddr = destAddr; + MCD_relocBuffDesc[channel].lastDestAddr = destAddr; /* definitely not its final value */ + MCD_relocBuffDesc[channel].dmaSize = dmaSize; + MCD_relocBuffDesc[channel].flags = 0; /* not used */ + MCD_relocBuffDesc[channel].csumResult = 0; /* not used */ + MCD_relocBuffDesc[channel].next = 0; /* not used */ + + /* Initialize the progress-querying stuff to show no progress:*/ + ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[SRCPTR + CSAVE_OFFSET] = (int)srcAddr; + ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[DESTPTR + CSAVE_OFFSET] = (int)destAddr; + ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[DCOUNT + CSAVE_OFFSET] = 0; + ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[CURRBD + CSAVE_OFFSET] = + (u32) &(MCD_relocBuffDesc[channel]); + /* tbd - need to keep the user from trying to call the EU routine + when MCD_INCLUDE_EU is not defined */ + if( funcDesc == MCD_FUNC_NOEU1 || funcDesc == MCD_FUNC_NOEU2) + { + /* TDTStart and TDTEnd */ + MCD_taskTable[channel].TDTstart = MCD_modelTaskTable[TASK_SINGLENOEU].TDTstart; + MCD_taskTable[channel].TDTend = MCD_modelTaskTable[TASK_SINGLENOEU].TDTend; + MCD_startDmaSingleNoEu(srcAddr, srcIncr, destAddr, destIncr, dmaSize, + xferSizeIncr, flags, (int *)&(MCD_relocBuffDesc[channel]), cSave, + MCD_taskTable, channel); + } + else + { + /* TDTStart and TDTEnd */ + MCD_taskTable[channel].TDTstart = MCD_modelTaskTable[TASK_SINGLEEU].TDTstart; + MCD_taskTable[channel].TDTend = MCD_modelTaskTable[TASK_SINGLEEU].TDTend; + MCD_startDmaSingleEu(srcAddr, srcIncr, destAddr, destIncr, dmaSize, + xferSizeIncr, flags, (int *)&(MCD_relocBuffDesc[channel]), cSave, + MCD_taskTable, channel); + } + } + else + { /* chained DMAS */ + /* Initialize the progress-querying stuff to show no progress:*/ +#if 1 /* (!defined(MCD_NEED_ADDR_TRANS)) */ + ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[SRCPTR + CSAVE_OFFSET] + = (int)((MCD_bufDesc*) srcAddr)->srcAddr; + ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[DESTPTR + CSAVE_OFFSET] + = (int)((MCD_bufDesc*) srcAddr)->destAddr; +#else /* if using address translation, need the virtual addr of the first buffdesc */ + ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[SRCPTR + CSAVE_OFFSET] + = (int)((MCD_bufDesc*) srcAddrVirt)->srcAddr; + ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[DESTPTR + CSAVE_OFFSET] + = (int)((MCD_bufDesc*) srcAddrVirt)->destAddr; +#endif + ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[DCOUNT + CSAVE_OFFSET] = 0; + ((volatile int *)MCD_taskTable[channel].contextSaveSpace)[CURRBD + CSAVE_OFFSET] = (u32) srcAddr; + + if( funcDesc == MCD_FUNC_NOEU1 || funcDesc == MCD_FUNC_NOEU2) + { + /*TDTStart and TDTEnd*/ + MCD_taskTable[channel].TDTstart = MCD_modelTaskTable[TASK_CHAINNOEU].TDTstart; + MCD_taskTable[channel].TDTend = MCD_modelTaskTable[TASK_CHAINNOEU].TDTend; + MCD_startDmaChainNoEu((int *)srcAddr, srcIncr, destIncr, xferSize, + xferSizeIncr, cSave, MCD_taskTable, channel); + } + else + { + /*TDTStart and TDTEnd*/ + MCD_taskTable[channel].TDTstart = MCD_modelTaskTable[TASK_CHAINEU].TDTstart; + MCD_taskTable[channel].TDTend = MCD_modelTaskTable[TASK_CHAINEU].TDTend; + MCD_startDmaChainEu((int *)srcAddr, srcIncr, destIncr, xferSize, + xferSizeIncr, cSave, MCD_taskTable, channel); + } + } + MCD_chStatus[channel] = MCD_IDLE; + return(MCD_OK); +} + +/* Function: MCD_XferProgrQuery + * Purpose: Returns progress of DMA on requested channel + * Arguments: channel - channel to retrieve progress for + * progRep - pointer to user supplied MCD_XferProg struct + * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK + * + * Notes: + * MCD_XferProgrQuery() upon completing or after aborting a DMA, or + * while the DMA is in progress, this function returns the first + * DMA-destination address not (or not yet) used in the DMA. When + * encountering a non-ready buffer descriptor, the information for + * the last completed descriptor is returned. + * + * MCD_XferProgQuery() has to avoid the possibility of getting + * partially-updated information in the event that we should happen + * to query DMA progress just as the DMA is updating it. It does that + * by taking advantage of the fact context is not saved frequently for + * the most part. We therefore read it at least twice until we get the + * same information twice in a row. + * + * Because a small, but not insignificant, amount of time is required + * to write out the progress-query information, especially upon + * completion of the DMA, it would be wise to guarantee some time lag + * between successive readings of the progress-query information. + */ + +/* + * How many iterations of the loop below to execute to stabilize values + */ +#define STABTIME 0 + +int MCD_XferProgrQuery (int channel, MCD_XferProg *progRep) +{ + MCD_XferProg prevRep; + int again; /* true if we are to try again to get consistent results */ + int i; /* used as a time-waste counter */ + int destDiffBytes; /* Total number of bytes that we think actually got xfered. */ + int numIterations; /* number of iterations */ + int bytesNotXfered; /* bytes that did not get xfered. */ + s8 *LWAlignedInitDestAddr, *LWAlignedCurrDestAddr; + int subModVal, addModVal; /* Mode values to added and subtracted from the + final destAddr */ + + if((channel < 0) || (channel >= NCHANNELS)) + return(MCD_CHANNEL_INVALID); + + /* Read a trial value for the progress-reporting values*/ + prevRep.lastSrcAddr = + (s8 *) ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[SRCPTR + CSAVE_OFFSET]; + prevRep.lastDestAddr = + (s8 *) ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[DESTPTR + CSAVE_OFFSET]; + prevRep.dmaSize = ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[DCOUNT + CSAVE_OFFSET]; + prevRep.currBufDesc = + (MCD_bufDesc*) ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[CURRBD + CSAVE_OFFSET]; + /* Repeatedly reread those values until they match previous values: */ + do { + /* Waste a little bit of time to ensure stability: */ + for (i = 0; i < STABTIME; i++) + i += i >> 2; /* make sure this loop does something so that it doesn't get optimized out */ + /* Check them again: */ + progRep->lastSrcAddr = + (s8 *) ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[SRCPTR + CSAVE_OFFSET]; + progRep->lastDestAddr = + (s8 *) ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[DESTPTR + CSAVE_OFFSET]; + progRep->dmaSize = ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[DCOUNT + CSAVE_OFFSET]; + progRep->currBufDesc = + (MCD_bufDesc*) ((volatile int*) MCD_taskTable[channel].contextSaveSpace)[CURRBD + CSAVE_OFFSET]; + /* See if they match: */ + if ( prevRep.lastSrcAddr != progRep->lastSrcAddr + || prevRep.lastDestAddr != progRep->lastDestAddr + || prevRep.dmaSize != progRep->dmaSize + || prevRep.currBufDesc != progRep->currBufDesc) + { + /* If they don't match, remember previous values and try again:*/ + prevRep.lastSrcAddr = progRep->lastSrcAddr; + prevRep.lastDestAddr = progRep->lastDestAddr; + prevRep.dmaSize = progRep->dmaSize; + prevRep.currBufDesc = progRep->currBufDesc; + again = MCD_TRUE; + } + else + again = MCD_FALSE; + } while (again == MCD_TRUE); + + + /* Update the dCount, srcAddr and destAddr */ + /* To calculate dmaCount, we consider destination address. C + overs M1,P1,Z for destination */ + switch(MCD_remVariants.remDestRsdIncr[channel]) { + case MINUS1: + subModVal = ((int)progRep->lastDestAddr) & ((MCD_remVariants.remXferSize[channel]) - 1); + addModVal = ((int)progRep->currBufDesc->destAddr) & ((MCD_remVariants.remXferSize[channel]) - 1); + LWAlignedInitDestAddr = (progRep->currBufDesc->destAddr) - addModVal; + LWAlignedCurrDestAddr = (progRep->lastDestAddr) - subModVal; + destDiffBytes = LWAlignedInitDestAddr - LWAlignedCurrDestAddr; + bytesNotXfered = (destDiffBytes/MCD_remVariants.remDestIncr[channel]) * + ( MCD_remVariants.remDestIncr[channel] + + MCD_remVariants.remXferSize[channel]); + progRep->dmaSize = destDiffBytes - bytesNotXfered + addModVal - subModVal; + break; + case ZERO: + progRep->lastDestAddr = progRep->currBufDesc->destAddr; + break; + case PLUS1: + /* This value has to be subtracted from the final calculated dCount. */ + subModVal = ((int)progRep->currBufDesc->destAddr) & ((MCD_remVariants.remXferSize[channel]) - 1); + /* These bytes are already in lastDestAddr. */ + addModVal = ((int)progRep->lastDestAddr) & ((MCD_remVariants.remXferSize[channel]) - 1); + LWAlignedInitDestAddr = (progRep->currBufDesc->destAddr) - subModVal; + LWAlignedCurrDestAddr = (progRep->lastDestAddr) - addModVal; + destDiffBytes = (progRep->lastDestAddr - LWAlignedInitDestAddr); + numIterations = ( LWAlignedCurrDestAddr - LWAlignedInitDestAddr)/MCD_remVariants.remDestIncr[channel]; + bytesNotXfered = numIterations * + ( MCD_remVariants.remDestIncr[channel] + - MCD_remVariants.remXferSize[channel]); + progRep->dmaSize = destDiffBytes - bytesNotXfered - subModVal; + break; + default: + break; + } + + /* This covers M1,P1,Z for source */ + switch(MCD_remVariants.remSrcRsdIncr[channel]) { + case MINUS1: + progRep->lastSrcAddr = + progRep->currBufDesc->srcAddr + + ( MCD_remVariants.remSrcIncr[channel] * + (progRep->dmaSize/MCD_remVariants.remXferSize[channel])); + break; + case ZERO: + progRep->lastSrcAddr = progRep->currBufDesc->srcAddr; + break; + case PLUS1: + progRep->lastSrcAddr = + progRep->currBufDesc->srcAddr + + ( MCD_remVariants.remSrcIncr[channel] * + (progRep->dmaSize/MCD_remVariants.remXferSize[channel])); + break; + default: break; + } + + return(MCD_OK); +} + +/* MCD_resmActions() does the majority of the actions of a DMA resume. + * It is called from MCD_killDma() and MCD_resumeDma(). It has to be + * a separate function because the kill function has to negate the task + * enable before resuming it, but the resume function has to do nothing + * if there is no DMA on that channel (i.e., if the enable bit is 0). + */ +static void MCD_resmActions (int channel) +{ + MCD_dmaBar->debugControl = DBG_CTL_DISABLE; + MCD_dmaBar->debugStatus = MCD_dmaBar->debugStatus; + MCD_dmaBar->ptdDebug = PTD_DBG_TSK_VLD_INIT; /* This register is selected to know + which initiator is actually asserted. */ + if((MCD_dmaBar->ptdDebug >> channel ) & 0x1) + MCD_chStatus[channel] = MCD_RUNNING; + else + MCD_chStatus[channel] = MCD_IDLE; +} + +/* Function: MCD_killDma + * Purpose: Halt the DMA on the requested channel, without any + * intention of resuming the DMA. + * Arguments: channel - requested channel + * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK + * + * Notes: + * A DMA may be killed from any state, including paused state, and it + * always goes to the MCD_HALTED state even if it is killed while in + * the MCD_NO_DMA or MCD_IDLE states. + */ +int MCD_killDma (int channel) +{ + /* MCD_XferProg progRep; */ + + if((channel < 0) || (channel >= NCHANNELS)) + return(MCD_CHANNEL_INVALID); + + MCD_dmaBar->taskControl[channel] = 0x0; + MCD_resumeDma (channel); + /* + * This must be after the write to the TCR so that the task doesn't + * start up again momentarily, and before the status assignment so + * as to override whatever MCD_resumeDma() may do to the channel + * status. + */ + MCD_chStatus[channel] = MCD_HALTED; + + /* + * Update the current buffer descriptor's lastDestAddr field + * + * MCD_XferProgrQuery (channel, &progRep); + * progRep.currBufDesc->lastDestAddr = progRep.lastDestAddr; + */ + return(MCD_OK); +} + +/* Function: MCD_continDma + * Purpose: Continue a DMA which as stopped due to encountering an + * unready buffer descriptor. + * Arguments: channel - channel to continue the DMA on + * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK + * + * Notes: + * This routine does not check to see if there is a task which can + * be continued. Also this routine should not be used with single DMAs. + */ +int MCD_continDma (int channel) +{ + if((channel < 0) || (channel >= NCHANNELS)) + return(MCD_CHANNEL_INVALID); + + MCD_dmaBar->taskControl[channel] |= TASK_CTL_EN; + MCD_chStatus[channel] = MCD_RUNNING; + + return(MCD_OK); +} + +/* + * MCD_pauseDma() and MCD_resumeDma() below use the DMA's debug unit + * to freeze a task and resume it. We freeze a task by breakpointing + * on the stated task. That is, not any specific place in the task, + * but any time that task executes. In particular, when that task + * executes, we want to freeze that task and only that task. + * + * The bits of the debug control register influence interrupts vs. + * breakpoints as follows: + * - Bits 14 and 0 enable or disable debug functions. If enabled, you + * will get the interrupt but you may or may not get a breakpoint. + * - Bits 2 and 1 decide whether you also get a breakpoint in addition + * to an interrupt. + * + * The debug unit can do these actions in response to either internally + * detected breakpoint conditions from the comparators, or in response + * to the external breakpoint pin, or both. + * - Bits 14 and 1 perform the above-described functions for + * internally-generated conditions, i.e., the debug comparators. + * - Bits 0 and 2 perform the above-described functions for external + * conditions, i.e., the breakpoint external pin. + * + * Note that, although you "always" get the interrupt when you turn + * the debug functions, the interrupt can nevertheless, if desired, be + * masked by the corresponding bit in the PTD's IMR. Note also that + * this means that bits 14 and 0 must enable debug functions before + * bits 1 and 2, respectively, have any effect. + * + * NOTE: It's extremely important to not pause more than one DMA channel + * at a time. + ********************************************************************/ + +/* Function: MCD_pauseDma + * Purpose: Pauses the DMA on a given channel (if any DMA is running + * on that channel). + * Arguments: channel + * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK + */ +int MCD_pauseDma (int channel) +{ + /* MCD_XferProg progRep; */ + + if((channel < 0) || (channel >= NCHANNELS)) + return(MCD_CHANNEL_INVALID); + + if (MCD_dmaBar->taskControl[channel] & TASK_CTL_EN) + { + MCD_dmaBar->debugComp1 = channel; + MCD_dmaBar->debugControl = DBG_CTL_ENABLE | (1 << (channel + 16)); + MCD_chStatus[channel] = MCD_PAUSED; + + /* + * Update the current buffer descriptor's lastDestAddr field + * + * MCD_XferProgrQuery (channel, &progRep); + * progRep.currBufDesc->lastDestAddr = progRep.lastDestAddr; + */ + } + return(MCD_OK); +} + +/* Function: MCD_resumeDma + * Purpose: Resumes the DMA on a given channel (if any DMA is + * running on that channel). + * Arguments: channel - channel on which to resume DMA + * Returns: MCD_CHANNEL_INVALID if channel is invalid, else MCD_OK + */ +int MCD_resumeDma (int channel) +{ + if((channel < 0) || (channel >= NCHANNELS)) + return(MCD_CHANNEL_INVALID); + + if (MCD_dmaBar->taskControl[channel] & TASK_CTL_EN) + MCD_resmActions (channel); + + return(MCD_OK); +} + +/* Function: MCD_csumQuery + * Purpose: Provide the checksum after performing a non-chained DMA + * Arguments: channel - channel to report on + * csum - pointer to where to write the checksum/CRC + * Returns: MCD_ERROR if the channel is invalid, else MCD_OK + * + * Notes: + * + */ +int MCD_csumQuery (int channel, u32 *csum) +{ +#ifdef MCD_INCLUDE_EU + if((channel < 0) || (channel >= NCHANNELS)) + return(MCD_CHANNEL_INVALID); + + *csum = MCD_relocBuffDesc[channel].csumResult; + return(MCD_OK); +#else + return(MCD_ERROR); +#endif +} + +/* Function: MCD_getCodeSize + * Purpose: Provide the size requirements of the microcoded tasks + * Returns: Size in bytes + */ +int MCD_getCodeSize(void) +{ +#ifdef MCD_INCLUDE_EU + return(0x2b5c); +#else + return(0x173c); +#endif +} + +/* Function: MCD_getVersion + * Purpose: Provide the version string and number + * Arguments: longVersion - user supplied pointer to a pointer to a char + * which points to the version string + * Returns: Version number and version string (by reference) + */ +char MCD_versionString[] = "Multi-channel DMA API Alpha v0.3 (2004-04-26)"; +#define MCD_REV_MAJOR 0x00 +#define MCD_REV_MINOR 0x03 + +int MCD_getVersion(char **longVersion) +{ + *longVersion = MCD_versionString; + return((MCD_REV_MAJOR << 8) | MCD_REV_MINOR); +} + +/* Private version of memcpy() + * Note that everything this is used for is longword-aligned. + */ +static void MCD_memcpy (int *dest, int *src, u32 size) +{ + u32 i; + + for (i = 0; i < size; i += sizeof(int), dest++, src++) + *dest = *src; +} diff --git a/arch/m68k/mach-mcfv4e/mcdapi/MCD_library.dox b/arch/m68k/mach-mcfv4e/mcdapi/MCD_library.dox new file mode 100644 index 0000000000..ec3a730730 --- /dev/null +++ b/arch/m68k/mach-mcfv4e/mcdapi/MCD_library.dox @@ -0,0 +1,10 @@ +/** @page mcfv4e_MCDlib MultiChannelDMA library for Coldfire V4e + * + * The MCD library is taken as is from sources publically available from + * FreeScale Semiconductors az http://www.freescale.com + * + * It is slight reformatted and cleaned up, but otherwise unchanged to support + * later merged with updated MCD library releases. + * + * See the PDF document supplied with the library for API documentation + */ diff --git a/arch/m68k/mach-mcfv4e/mcdapi/MCD_tasks.c b/arch/m68k/mach-mcfv4e/mcdapi/MCD_tasks.c new file mode 100644 index 0000000000..3bfed232d7 --- /dev/null +++ b/arch/m68k/mach-mcfv4e/mcdapi/MCD_tasks.c @@ -0,0 +1,2449 @@ +/* + * File: MCD_tasks.c + * Purpose: Contains task code and structures for Multi-channel DMA + * + * Notes: + */ +#include +#include + +u32 MCD_varTab0[]; +u32 MCD_varTab1[]; +u32 MCD_varTab2[]; +u32 MCD_varTab3[]; +u32 MCD_varTab4[]; +u32 MCD_varTab5[]; +u32 MCD_varTab6[]; +u32 MCD_varTab7[]; +u32 MCD_varTab8[]; +u32 MCD_varTab9[]; +u32 MCD_varTab10[]; +u32 MCD_varTab11[]; +u32 MCD_varTab12[]; +u32 MCD_varTab13[]; +u32 MCD_varTab14[]; +u32 MCD_varTab15[]; + +u32 MCD_funcDescTab0[]; +#ifdef MCD_INCLUDE_EU +u32 MCD_funcDescTab1[]; +u32 MCD_funcDescTab2[]; +u32 MCD_funcDescTab3[]; +u32 MCD_funcDescTab4[]; +u32 MCD_funcDescTab5[]; +u32 MCD_funcDescTab6[]; +u32 MCD_funcDescTab7[]; +u32 MCD_funcDescTab8[]; +u32 MCD_funcDescTab9[]; +u32 MCD_funcDescTab10[]; +u32 MCD_funcDescTab11[]; +u32 MCD_funcDescTab12[]; +u32 MCD_funcDescTab13[]; +u32 MCD_funcDescTab14[]; +u32 MCD_funcDescTab15[]; +#endif + +u32 MCD_contextSave0[]; +u32 MCD_contextSave1[]; +u32 MCD_contextSave2[]; +u32 MCD_contextSave3[]; +u32 MCD_contextSave4[]; +u32 MCD_contextSave5[]; +u32 MCD_contextSave6[]; +u32 MCD_contextSave7[]; +u32 MCD_contextSave8[]; +u32 MCD_contextSave9[]; +u32 MCD_contextSave10[]; +u32 MCD_contextSave11[]; +u32 MCD_contextSave12[]; +u32 MCD_contextSave13[]; +u32 MCD_contextSave14[]; +u32 MCD_contextSave15[]; + +u32 MCD_realTaskTableSrc[] = +{ + 0x00000000, + 0x00000000, + (u32)MCD_varTab0, /* Task 0 Variable Table */ + (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */ + 0x00000000, + 0x00000000, + (u32)MCD_contextSave0, /* Task 0 context save space */ + 0x00000000, + 0x00000000, + 0x00000000, + (u32)MCD_varTab1, /* Task 1 Variable Table */ +#ifdef MCD_INCLUDE_EU + (u32)MCD_funcDescTab1, /* Task 1 Function Descriptor Table & Flags */ +#else + (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */ +#endif + 0x00000000, + 0x00000000, + (u32)MCD_contextSave1, /* Task 1 context save space */ + 0x00000000, + 0x00000000, + 0x00000000, + (u32)MCD_varTab2, /* Task 2 Variable Table */ +#ifdef MCD_INCLUDE_EU + (u32)MCD_funcDescTab2, /* Task 2 Function Descriptor Table & Flags */ +#else + (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */ +#endif + 0x00000000, + 0x00000000, + (u32)MCD_contextSave2, /* Task 2 context save space */ + 0x00000000, + 0x00000000, + 0x00000000, + (u32)MCD_varTab3, /* Task 3 Variable Table */ +#ifdef MCD_INCLUDE_EU + (u32)MCD_funcDescTab3, /* Task 3 Function Descriptor Table & Flags */ +#else + (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */ +#endif + 0x00000000, + 0x00000000, + (u32)MCD_contextSave3, /* Task 3 context save space */ + 0x00000000, + 0x00000000, + 0x00000000, + (u32)MCD_varTab4, /* Task 4 Variable Table */ +#ifdef MCD_INCLUDE_EU + (u32)MCD_funcDescTab4, /* Task 4 Function Descriptor Table & Flags */ +#else + (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */ +#endif + 0x00000000, + 0x00000000, + (u32)MCD_contextSave4, /* Task 4 context save space */ + 0x00000000, + 0x00000000, + 0x00000000, + (u32)MCD_varTab5, /* Task 5 Variable Table */ +#ifdef MCD_INCLUDE_EU + (u32)MCD_funcDescTab5, /* Task 5 Function Descriptor Table & Flags */ +#else + (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */ +#endif + 0x00000000, + 0x00000000, + (u32)MCD_contextSave5, /* Task 5 context save space */ + 0x00000000, + 0x00000000, + 0x00000000, + (u32)MCD_varTab6, /* Task 6 Variable Table */ +#ifdef MCD_INCLUDE_EU + (u32)MCD_funcDescTab6, /* Task 6 Function Descriptor Table & Flags */ +#else + (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */ +#endif + 0x00000000, + 0x00000000, + (u32)MCD_contextSave6, /* Task 6 context save space */ + 0x00000000, + 0x00000000, + 0x00000000, + (u32)MCD_varTab7, /* Task 7 Variable Table */ +#ifdef MCD_INCLUDE_EU + (u32)MCD_funcDescTab7, /* Task 7 Function Descriptor Table & Flags */ +#else + (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */ +#endif + 0x00000000, + 0x00000000, + (u32)MCD_contextSave7, /* Task 7 context save space */ + 0x00000000, + 0x00000000, + 0x00000000, + (u32)MCD_varTab8, /* Task 8 Variable Table */ +#ifdef MCD_INCLUDE_EU + (u32)MCD_funcDescTab8, /* Task 8 Function Descriptor Table & Flags */ +#else + (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */ +#endif + 0x00000000, + 0x00000000, + (u32)MCD_contextSave8, /* Task 8 context save space */ + 0x00000000, + 0x00000000, + 0x00000000, + (u32)MCD_varTab9, /* Task 9 Variable Table */ +#ifdef MCD_INCLUDE_EU + (u32)MCD_funcDescTab9, /* Task 9 Function Descriptor Table & Flags */ +#else + (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */ +#endif + 0x00000000, + 0x00000000, + (u32)MCD_contextSave9, /* Task 9 context save space */ + 0x00000000, + 0x00000000, + 0x00000000, + (u32)MCD_varTab10, /* Task 10 Variable Table */ +#ifdef MCD_INCLUDE_EU + (u32)MCD_funcDescTab10, /* Task 10 Function Descriptor Table & Flags */ +#else + (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */ +#endif + 0x00000000, + 0x00000000, + (u32)MCD_contextSave10, /* Task 10 context save space */ + 0x00000000, + 0x00000000, + 0x00000000, + (u32)MCD_varTab11, /* Task 11 Variable Table */ +#ifdef MCD_INCLUDE_EU + (u32)MCD_funcDescTab11, /* Task 11 Function Descriptor Table & Flags */ +#else + (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */ +#endif + 0x00000000, + 0x00000000, + (u32)MCD_contextSave11, /* Task 11 context save space */ + 0x00000000, + 0x00000000, + 0x00000000, + (u32)MCD_varTab12, /* Task 12 Variable Table */ +#ifdef MCD_INCLUDE_EU + (u32)MCD_funcDescTab12, /* Task 12 Function Descriptor Table & Flags */ +#else + (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */ +#endif + 0x00000000, + 0x00000000, + (u32)MCD_contextSave12, /* Task 12 context save space */ + 0x00000000, + 0x00000000, + 0x00000000, + (u32)MCD_varTab13, /* Task 13 Variable Table */ +#ifdef MCD_INCLUDE_EU + (u32)MCD_funcDescTab13, /* Task 13 Function Descriptor Table & Flags */ +#else + (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */ +#endif + 0x00000000, + 0x00000000, + (u32)MCD_contextSave13, /* Task 13 context save space */ + 0x00000000, + 0x00000000, + 0x00000000, + (u32)MCD_varTab14, /* Task 14 Variable Table */ +#ifdef MCD_INCLUDE_EU + (u32)MCD_funcDescTab14, /* Task 14 Function Descriptor Table & Flags */ +#else + (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */ +#endif + 0x00000000, + 0x00000000, + (u32)MCD_contextSave14, /* Task 14 context save space */ + 0x00000000, + 0x00000000, + 0x00000000, + (u32)MCD_varTab15, /* Task 15 Variable Table */ +#ifdef MCD_INCLUDE_EU + (u32)MCD_funcDescTab15, /* Task 15 Function Descriptor Table & Flags */ +#else + (u32)MCD_funcDescTab0, /* Task 0 Function Descriptor Table & Flags */ +#endif + 0x00000000, + 0x00000000, + (u32)MCD_contextSave15, /* Task 15 context save space */ + 0x00000000, +}; + + +u32 MCD_varTab0[] = +{ /* Task 0 Variable Table */ + 0x00000000, /* var[0] */ + 0x00000000, /* var[1] */ + 0x00000000, /* var[2] */ + 0x00000000, /* var[3] */ + 0x00000000, /* var[4] */ + 0x00000000, /* var[5] */ + 0x00000000, /* var[6] */ + 0x00000000, /* var[7] */ + 0x00000000, /* var[8] */ + 0x00000000, /* var[9] */ + 0x00000000, /* var[10] */ + 0x00000000, /* var[11] */ + 0x00000000, /* var[12] */ + 0x00000000, /* var[13] */ + 0x00000000, /* var[14] */ + 0x00000000, /* var[15] */ + 0x00000000, /* var[16] */ + 0x00000000, /* var[17] */ + 0x00000000, /* var[18] */ + 0x00000000, /* var[19] */ + 0x00000000, /* var[20] */ + 0x00000000, /* var[21] */ + 0x00000000, /* var[22] */ + 0x00000000, /* var[23] */ + 0xe0000000, /* inc[0] */ + 0x20000000, /* inc[1] */ + 0x2000ffff, /* inc[2] */ + 0x00000000, /* inc[3] */ + 0x00000000, /* inc[4] */ + 0x00000000, /* inc[5] */ + 0x00000000, /* inc[6] */ + 0x00000000, /* inc[7] */ +}; + + +u32 MCD_varTab1[] = +{ /* Task 1 Variable Table */ + 0x00000000, /* var[0] */ + 0x00000000, /* var[1] */ + 0x00000000, /* var[2] */ + 0x00000000, /* var[3] */ + 0x00000000, /* var[4] */ + 0x00000000, /* var[5] */ + 0x00000000, /* var[6] */ + 0x00000000, /* var[7] */ + 0x00000000, /* var[8] */ + 0x00000000, /* var[9] */ + 0x00000000, /* var[10] */ + 0x00000000, /* var[11] */ + 0x00000000, /* var[12] */ + 0x00000000, /* var[13] */ + 0x00000000, /* var[14] */ + 0x00000000, /* var[15] */ + 0x00000000, /* var[16] */ + 0x00000000, /* var[17] */ + 0x00000000, /* var[18] */ + 0x00000000, /* var[19] */ + 0x00000000, /* var[20] */ + 0x00000000, /* var[21] */ + 0x00000000, /* var[22] */ + 0x00000000, /* var[23] */ + 0xe0000000, /* inc[0] */ + 0x20000000, /* inc[1] */ + 0x2000ffff, /* inc[2] */ + 0x00000000, /* inc[3] */ + 0x00000000, /* inc[4] */ + 0x00000000, /* inc[5] */ + 0x00000000, /* inc[6] */ + 0x00000000, /* inc[7] */ +}; + +u32 MCD_varTab2[]= +{ /* Task 2 Variable Table */ + 0x00000000, /* var[0] */ + 0x00000000, /* var[1] */ + 0x00000000, /* var[2] */ + 0x00000000, /* var[3] */ + 0x00000000, /* var[4] */ + 0x00000000, /* var[5] */ + 0x00000000, /* var[6] */ + 0x00000000, /* var[7] */ + 0x00000000, /* var[8] */ + 0x00000000, /* var[9] */ + 0x00000000, /* var[10] */ + 0x00000000, /* var[11] */ + 0x00000000, /* var[12] */ + 0x00000000, /* var[13] */ + 0x00000000, /* var[14] */ + 0x00000000, /* var[15] */ + 0x00000000, /* var[16] */ + 0x00000000, /* var[17] */ + 0x00000000, /* var[18] */ + 0x00000000, /* var[19] */ + 0x00000000, /* var[20] */ + 0x00000000, /* var[21] */ + 0x00000000, /* var[22] */ + 0x00000000, /* var[23] */ + 0xe0000000, /* inc[0] */ + 0x20000000, /* inc[1] */ + 0x2000ffff, /* inc[2] */ + 0x00000000, /* inc[3] */ + 0x00000000, /* inc[4] */ + 0x00000000, /* inc[5] */ + 0x00000000, /* inc[6] */ + 0x00000000, /* inc[7] */ +}; + +u32 MCD_varTab3[]= +{ /* Task 3 Variable Table */ + 0x00000000, /* var[0] */ + 0x00000000, /* var[1] */ + 0x00000000, /* var[2] */ + 0x00000000, /* var[3] */ + 0x00000000, /* var[4] */ + 0x00000000, /* var[5] */ + 0x00000000, /* var[6] */ + 0x00000000, /* var[7] */ + 0x00000000, /* var[8] */ + 0x00000000, /* var[9] */ + 0x00000000, /* var[10] */ + 0x00000000, /* var[11] */ + 0x00000000, /* var[12] */ + 0x00000000, /* var[13] */ + 0x00000000, /* var[14] */ + 0x00000000, /* var[15] */ + 0x00000000, /* var[16] */ + 0x00000000, /* var[17] */ + 0x00000000, /* var[18] */ + 0x00000000, /* var[19] */ + 0x00000000, /* var[20] */ + 0x00000000, /* var[21] */ + 0x00000000, /* var[22] */ + 0x00000000, /* var[23] */ + 0xe0000000, /* inc[0] */ + 0x20000000, /* inc[1] */ + 0x2000ffff, /* inc[2] */ + 0x00000000, /* inc[3] */ + 0x00000000, /* inc[4] */ + 0x00000000, /* inc[5] */ + 0x00000000, /* inc[6] */ + 0x00000000, /* inc[7] */ +}; + +u32 MCD_varTab4[]= +{ /* Task 4 Variable Table */ + 0x00000000, /* var[0] */ + 0x00000000, /* var[1] */ + 0x00000000, /* var[2] */ + 0x00000000, /* var[3] */ + 0x00000000, /* var[4] */ + 0x00000000, /* var[5] */ + 0x00000000, /* var[6] */ + 0x00000000, /* var[7] */ + 0x00000000, /* var[8] */ + 0x00000000, /* var[9] */ + 0x00000000, /* var[10] */ + 0x00000000, /* var[11] */ + 0x00000000, /* var[12] */ + 0x00000000, /* var[13] */ + 0x00000000, /* var[14] */ + 0x00000000, /* var[15] */ + 0x00000000, /* var[16] */ + 0x00000000, /* var[17] */ + 0x00000000, /* var[18] */ + 0x00000000, /* var[19] */ + 0x00000000, /* var[20] */ + 0x00000000, /* var[21] */ + 0x00000000, /* var[22] */ + 0x00000000, /* var[23] */ + 0xe0000000, /* inc[0] */ + 0x20000000, /* inc[1] */ + 0x2000ffff, /* inc[2] */ + 0x00000000, /* inc[3] */ + 0x00000000, /* inc[4] */ + 0x00000000, /* inc[5] */ + 0x00000000, /* inc[6] */ + 0x00000000, /* inc[7] */ +}; + +u32 MCD_varTab5[]= +{ /* Task 5 Variable Table */ + 0x00000000, /* var[0] */ + 0x00000000, /* var[1] */ + 0x00000000, /* var[2] */ + 0x00000000, /* var[3] */ + 0x00000000, /* var[4] */ + 0x00000000, /* var[5] */ + 0x00000000, /* var[6] */ + 0x00000000, /* var[7] */ + 0x00000000, /* var[8] */ + 0x00000000, /* var[9] */ + 0x00000000, /* var[10] */ + 0x00000000, /* var[11] */ + 0x00000000, /* var[12] */ + 0x00000000, /* var[13] */ + 0x00000000, /* var[14] */ + 0x00000000, /* var[15] */ + 0x00000000, /* var[16] */ + 0x00000000, /* var[17] */ + 0x00000000, /* var[18] */ + 0x00000000, /* var[19] */ + 0x00000000, /* var[20] */ + 0x00000000, /* var[21] */ + 0x00000000, /* var[22] */ + 0x00000000, /* var[23] */ + 0xe0000000, /* inc[0] */ + 0x20000000, /* inc[1] */ + 0x2000ffff, /* inc[2] */ + 0x00000000, /* inc[3] */ + 0x00000000, /* inc[4] */ + 0x00000000, /* inc[5] */ + 0x00000000, /* inc[6] */ + 0x00000000, /* inc[7] */ +}; + +u32 MCD_varTab6[]= +{ /* Task 6 Variable Table */ + 0x00000000, /* var[0] */ + 0x00000000, /* var[1] */ + 0x00000000, /* var[2] */ + 0x00000000, /* var[3] */ + 0x00000000, /* var[4] */ + 0x00000000, /* var[5] */ + 0x00000000, /* var[6] */ + 0x00000000, /* var[7] */ + 0x00000000, /* var[8] */ + 0x00000000, /* var[9] */ + 0x00000000, /* var[10] */ + 0x00000000, /* var[11] */ + 0x00000000, /* var[12] */ + 0x00000000, /* var[13] */ + 0x00000000, /* var[14] */ + 0x00000000, /* var[15] */ + 0x00000000, /* var[16] */ + 0x00000000, /* var[17] */ + 0x00000000, /* var[18] */ + 0x00000000, /* var[19] */ + 0x00000000, /* var[20] */ + 0x00000000, /* var[21] */ + 0x00000000, /* var[22] */ + 0x00000000, /* var[23] */ + 0xe0000000, /* inc[0] */ + 0x20000000, /* inc[1] */ + 0x2000ffff, /* inc[2] */ + 0x00000000, /* inc[3] */ + 0x00000000, /* inc[4] */ + 0x00000000, /* inc[5] */ + 0x00000000, /* inc[6] */ + 0x00000000, /* inc[7] */ +}; + +u32 MCD_varTab7[]= +{ /* Task 7 Variable Table */ + 0x00000000, /* var[0] */ + 0x00000000, /* var[1] */ + 0x00000000, /* var[2] */ + 0x00000000, /* var[3] */ + 0x00000000, /* var[4] */ + 0x00000000, /* var[5] */ + 0x00000000, /* var[6] */ + 0x00000000, /* var[7] */ + 0x00000000, /* var[8] */ + 0x00000000, /* var[9] */ + 0x00000000, /* var[10] */ + 0x00000000, /* var[11] */ + 0x00000000, /* var[12] */ + 0x00000000, /* var[13] */ + 0x00000000, /* var[14] */ + 0x00000000, /* var[15] */ + 0x00000000, /* var[16] */ + 0x00000000, /* var[17] */ + 0x00000000, /* var[18] */ + 0x00000000, /* var[19] */ + 0x00000000, /* var[20] */ + 0x00000000, /* var[21] */ + 0x00000000, /* var[22] */ + 0x00000000, /* var[23] */ + 0xe0000000, /* inc[0] */ + 0x20000000, /* inc[1] */ + 0x2000ffff, /* inc[2] */ + 0x00000000, /* inc[3] */ + 0x00000000, /* inc[4] */ + 0x00000000, /* inc[5] */ + 0x00000000, /* inc[6] */ + 0x00000000, /* inc[7] */ +}; + +u32 MCD_varTab8[]= +{ /* Task 8 Variable Table */ + 0x00000000, /* var[0] */ + 0x00000000, /* var[1] */ + 0x00000000, /* var[2] */ + 0x00000000, /* var[3] */ + 0x00000000, /* var[4] */ + 0x00000000, /* var[5] */ + 0x00000000, /* var[6] */ + 0x00000000, /* var[7] */ + 0x00000000, /* var[8] */ + 0x00000000, /* var[9] */ + 0x00000000, /* var[10] */ + 0x00000000, /* var[11] */ + 0x00000000, /* var[12] */ + 0x00000000, /* var[13] */ + 0x00000000, /* var[14] */ + 0x00000000, /* var[15] */ + 0x00000000, /* var[16] */ + 0x00000000, /* var[17] */ + 0x00000000, /* var[18] */ + 0x00000000, /* var[19] */ + 0x00000000, /* var[20] */ + 0x00000000, /* var[21] */ + 0x00000000, /* var[22] */ + 0x00000000, /* var[23] */ + 0xe0000000, /* inc[0] */ + 0x20000000, /* inc[1] */ + 0x2000ffff, /* inc[2] */ + 0x00000000, /* inc[3] */ + 0x00000000, /* inc[4] */ + 0x00000000, /* inc[5] */ + 0x00000000, /* inc[6] */ + 0x00000000, /* inc[7] */ +}; + +u32 MCD_varTab9[]= +{ /* Task 9 Variable Table */ + 0x00000000, /* var[0] */ + 0x00000000, /* var[1] */ + 0x00000000, /* var[2] */ + 0x00000000, /* var[3] */ + 0x00000000, /* var[4] */ + 0x00000000, /* var[5] */ + 0x00000000, /* var[6] */ + 0x00000000, /* var[7] */ + 0x00000000, /* var[8] */ + 0x00000000, /* var[9] */ + 0x00000000, /* var[10] */ + 0x00000000, /* var[11] */ + 0x00000000, /* var[12] */ + 0x00000000, /* var[13] */ + 0x00000000, /* var[14] */ + 0x00000000, /* var[15] */ + 0x00000000, /* var[16] */ + 0x00000000, /* var[17] */ + 0x00000000, /* var[18] */ + 0x00000000, /* var[19] */ + 0x00000000, /* var[20] */ + 0x00000000, /* var[21] */ + 0x00000000, /* var[22] */ + 0x00000000, /* var[23] */ + 0xe0000000, /* inc[0] */ + 0x20000000, /* inc[1] */ + 0x2000ffff, /* inc[2] */ + 0x00000000, /* inc[3] */ + 0x00000000, /* inc[4] */ + 0x00000000, /* inc[5] */ + 0x00000000, /* inc[6] */ + 0x00000000, /* inc[7] */ +}; + +u32 MCD_varTab10[]= +{ /* Task 10 Variable Table */ + 0x00000000, /* var[0] */ + 0x00000000, /* var[1] */ + 0x00000000, /* var[2] */ + 0x00000000, /* var[3] */ + 0x00000000, /* var[4] */ + 0x00000000, /* var[5] */ + 0x00000000, /* var[6] */ + 0x00000000, /* var[7] */ + 0x00000000, /* var[8] */ + 0x00000000, /* var[9] */ + 0x00000000, /* var[10] */ + 0x00000000, /* var[11] */ + 0x00000000, /* var[12] */ + 0x00000000, /* var[13] */ + 0x00000000, /* var[14] */ + 0x00000000, /* var[15] */ + 0x00000000, /* var[16] */ + 0x00000000, /* var[17] */ + 0x00000000, /* var[18] */ + 0x00000000, /* var[19] */ + 0x00000000, /* var[20] */ + 0x00000000, /* var[21] */ + 0x00000000, /* var[22] */ + 0x00000000, /* var[23] */ + 0xe0000000, /* inc[0] */ + 0x20000000, /* inc[1] */ + 0x2000ffff, /* inc[2] */ + 0x00000000, /* inc[3] */ + 0x00000000, /* inc[4] */ + 0x00000000, /* inc[5] */ + 0x00000000, /* inc[6] */ + 0x00000000, /* inc[7] */ +}; + +u32 MCD_varTab11[]= +{ /* Task 11 Variable Table */ + 0x00000000, /* var[0] */ + 0x00000000, /* var[1] */ + 0x00000000, /* var[2] */ + 0x00000000, /* var[3] */ + 0x00000000, /* var[4] */ + 0x00000000, /* var[5] */ + 0x00000000, /* var[6] */ + 0x00000000, /* var[7] */ + 0x00000000, /* var[8] */ + 0x00000000, /* var[9] */ + 0x00000000, /* var[10] */ + 0x00000000, /* var[11] */ + 0x00000000, /* var[12] */ + 0x00000000, /* var[13] */ + 0x00000000, /* var[14] */ + 0x00000000, /* var[15] */ + 0x00000000, /* var[16] */ + 0x00000000, /* var[17] */ + 0x00000000, /* var[18] */ + 0x00000000, /* var[19] */ + 0x00000000, /* var[20] */ + 0x00000000, /* var[21] */ + 0x00000000, /* var[22] */ + 0x00000000, /* var[23] */ + 0xe0000000, /* inc[0] */ + 0x20000000, /* inc[1] */ + 0x2000ffff, /* inc[2] */ + 0x00000000, /* inc[3] */ + 0x00000000, /* inc[4] */ + 0x00000000, /* inc[5] */ + 0x00000000, /* inc[6] */ + 0x00000000, /* inc[7] */ +}; + +u32 MCD_varTab12[]= +{ /* Task 12 Variable Table */ + 0x00000000, /* var[0] */ + 0x00000000, /* var[1] */ + 0x00000000, /* var[2] */ + 0x00000000, /* var[3] */ + 0x00000000, /* var[4] */ + 0x00000000, /* var[5] */ + 0x00000000, /* var[6] */ + 0x00000000, /* var[7] */ + 0x00000000, /* var[8] */ + 0x00000000, /* var[9] */ + 0x00000000, /* var[10] */ + 0x00000000, /* var[11] */ + 0x00000000, /* var[12] */ + 0x00000000, /* var[13] */ + 0x00000000, /* var[14] */ + 0x00000000, /* var[15] */ + 0x00000000, /* var[16] */ + 0x00000000, /* var[17] */ + 0x00000000, /* var[18] */ + 0x00000000, /* var[19] */ + 0x00000000, /* var[20] */ + 0x00000000, /* var[21] */ + 0x00000000, /* var[22] */ + 0x00000000, /* var[23] */ + 0xe0000000, /* inc[0] */ + 0x20000000, /* inc[1] */ + 0x2000ffff, /* inc[2] */ + 0x00000000, /* inc[3] */ + 0x00000000, /* inc[4] */ + 0x00000000, /* inc[5] */ + 0x00000000, /* inc[6] */ + 0x00000000, /* inc[7] */ +}; + +u32 MCD_varTab13[]= +{ /* Task 13 Variable Table */ + 0x00000000, /* var[0] */ + 0x00000000, /* var[1] */ + 0x00000000, /* var[2] */ + 0x00000000, /* var[3] */ + 0x00000000, /* var[4] */ + 0x00000000, /* var[5] */ + 0x00000000, /* var[6] */ + 0x00000000, /* var[7] */ + 0x00000000, /* var[8] */ + 0x00000000, /* var[9] */ + 0x00000000, /* var[10] */ + 0x00000000, /* var[11] */ + 0x00000000, /* var[12] */ + 0x00000000, /* var[13] */ + 0x00000000, /* var[14] */ + 0x00000000, /* var[15] */ + 0x00000000, /* var[16] */ + 0x00000000, /* var[17] */ + 0x00000000, /* var[18] */ + 0x00000000, /* var[19] */ + 0x00000000, /* var[20] */ + 0x00000000, /* var[21] */ + 0x00000000, /* var[22] */ + 0x00000000, /* var[23] */ + 0xe0000000, /* inc[0] */ + 0x20000000, /* inc[1] */ + 0x2000ffff, /* inc[2] */ + 0x00000000, /* inc[3] */ + 0x00000000, /* inc[4] */ + 0x00000000, /* inc[5] */ + 0x00000000, /* inc[6] */ + 0x00000000, /* inc[7] */ +}; + +u32 MCD_varTab14[]= +{ /* Task 14 Variable Table */ + 0x00000000, /* var[0] */ + 0x00000000, /* var[1] */ + 0x00000000, /* var[2] */ + 0x00000000, /* var[3] */ + 0x00000000, /* var[4] */ + 0x00000000, /* var[5] */ + 0x00000000, /* var[6] */ + 0x00000000, /* var[7] */ + 0x00000000, /* var[8] */ + 0x00000000, /* var[9] */ + 0x00000000, /* var[10] */ + 0x00000000, /* var[11] */ + 0x00000000, /* var[12] */ + 0x00000000, /* var[13] */ + 0x00000000, /* var[14] */ + 0x00000000, /* var[15] */ + 0x00000000, /* var[16] */ + 0x00000000, /* var[17] */ + 0x00000000, /* var[18] */ + 0x00000000, /* var[19] */ + 0x00000000, /* var[20] */ + 0x00000000, /* var[21] */ + 0x00000000, /* var[22] */ + 0x00000000, /* var[23] */ + 0xe0000000, /* inc[0] */ + 0x20000000, /* inc[1] */ + 0x2000ffff, /* inc[2] */ + 0x00000000, /* inc[3] */ + 0x00000000, /* inc[4] */ + 0x00000000, /* inc[5] */ + 0x00000000, /* inc[6] */ + 0x00000000, /* inc[7] */ +}; + +u32 MCD_varTab15[]= +{ /* Task 15 Variable Table */ + 0x00000000, /* var[0] */ + 0x00000000, /* var[1] */ + 0x00000000, /* var[2] */ + 0x00000000, /* var[3] */ + 0x00000000, /* var[4] */ + 0x00000000, /* var[5] */ + 0x00000000, /* var[6] */ + 0x00000000, /* var[7] */ + 0x00000000, /* var[8] */ + 0x00000000, /* var[9] */ + 0x00000000, /* var[10] */ + 0x00000000, /* var[11] */ + 0x00000000, /* var[12] */ + 0x00000000, /* var[13] */ + 0x00000000, /* var[14] */ + 0x00000000, /* var[15] */ + 0x00000000, /* var[16] */ + 0x00000000, /* var[17] */ + 0x00000000, /* var[18] */ + 0x00000000, /* var[19] */ + 0x00000000, /* var[20] */ + 0x00000000, /* var[21] */ + 0x00000000, /* var[22] */ + 0x00000000, /* var[23] */ + 0xe0000000, /* inc[0] */ + 0x20000000, /* inc[1] */ + 0x2000ffff, /* inc[2] */ + 0x00000000, /* inc[3] */ + 0x00000000, /* inc[4] */ + 0x00000000, /* inc[5] */ + 0x00000000, /* inc[6] */ + 0x00000000, /* inc[7] */ +}; + +u32 MCD_funcDescTab0[]= +{ /* Task 0 Function Descriptor Table */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xa0045670, /* mainFunc(), EU# 3 */ + 0xa0000000, /* rsduFunc(), EU# 3 */ + 0xa0000000, /* crcAccumVal(), EU# 3 */ + 0x20000000, /* setCrcAccum(), EU# 3 */ + 0x21800000, /* and(), EU# 3 */ + 0x21e00000, /* or(), EU# 3 */ + 0x20400000, /* add(), EU# 3 */ + 0x20500000, /* sub(), EU# 3 */ + 0x205a0000, /* andNot(), EU# 3 */ + 0x20a00000, /* shiftR(), EU# 3 */ + 0x202fa000, /* andReadyBit(), EU# 3 */ + 0x202f9000, /* andNotReadyBit(), EU# 3 */ + 0x202ea000, /* andWrapBit(), EU# 3 */ + 0x202da000, /* andLastBit(), EU# 3 */ + 0x202e2000, /* andInterruptBit(), EU# 3 */ + 0x202f2000, /* andCrcRestartBit(), EU# 3 */ +}; + +#ifdef MCD_INCLUDE_EU +u32 MCD_funcDescTab1[]= +{ /* Task 1 Function Descriptor Table */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xa0045670, /* mainFunc(), EU# 3 */ + 0xa0000000, /* rsduFunc(), EU# 3 */ + 0xa0000000, /* crcAccumVal(), EU# 3 */ + 0x20000000, /* setCrcAccum(), EU# 3 */ + 0x21800000, /* and(), EU# 3 */ + 0x21e00000, /* or(), EU# 3 */ + 0x20400000, /* add(), EU# 3 */ + 0x20500000, /* sub(), EU# 3 */ + 0x205a0000, /* andNot(), EU# 3 */ + 0x20a00000, /* shiftR(), EU# 3 */ + 0x202fa000, /* andReadyBit(), EU# 3 */ + 0x202f9000, /* andNotReadyBit(), EU# 3 */ + 0x202ea000, /* andWrapBit(), EU# 3 */ + 0x202da000, /* andLastBit(), EU# 3 */ + 0x202e2000, /* andInterruptBit(), EU# 3 */ + 0x202f2000, /* andCrcRestartBit(), EU# 3 */ +}; + +u32 MCD_funcDescTab2[]= +{ /* Task 2 Function Descriptor Table */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xa0045670, /* mainFunc(), EU# 3 */ + 0xa0000000, /* rsduFunc(), EU# 3 */ + 0xa0000000, /* crcAccumVal(), EU# 3 */ + 0x20000000, /* setCrcAccum(), EU# 3 */ + 0x21800000, /* and(), EU# 3 */ + 0x21e00000, /* or(), EU# 3 */ + 0x20400000, /* add(), EU# 3 */ + 0x20500000, /* sub(), EU# 3 */ + 0x205a0000, /* andNot(), EU# 3 */ + 0x20a00000, /* shiftR(), EU# 3 */ + 0x202fa000, /* andReadyBit(), EU# 3 */ + 0x202f9000, /* andNotReadyBit(), EU# 3 */ + 0x202ea000, /* andWrapBit(), EU# 3 */ + 0x202da000, /* andLastBit(), EU# 3 */ + 0x202e2000, /* andInterruptBit(), EU# 3 */ + 0x202f2000, /* andCrcRestartBit(), EU# 3 */ +}; + +u32 MCD_funcDescTab3[]= +{ /* Task 3 Function Descriptor Table */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xa0045670, /* mainFunc(), EU# 3 */ + 0xa0000000, /* rsduFunc(), EU# 3 */ + 0xa0000000, /* crcAccumVal(), EU# 3 */ + 0x20000000, /* setCrcAccum(), EU# 3 */ + 0x21800000, /* and(), EU# 3 */ + 0x21e00000, /* or(), EU# 3 */ + 0x20400000, /* add(), EU# 3 */ + 0x20500000, /* sub(), EU# 3 */ + 0x205a0000, /* andNot(), EU# 3 */ + 0x20a00000, /* shiftR(), EU# 3 */ + 0x202fa000, /* andReadyBit(), EU# 3 */ + 0x202f9000, /* andNotReadyBit(), EU# 3 */ + 0x202ea000, /* andWrapBit(), EU# 3 */ + 0x202da000, /* andLastBit(), EU# 3 */ + 0x202e2000, /* andInterruptBit(), EU# 3 */ + 0x202f2000, /* andCrcRestartBit(), EU# 3 */ +}; + +u32 MCD_funcDescTab4[]= +{ /* Task 4 Function Descriptor Table */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xa0045670, /* mainFunc(), EU# 3 */ + 0xa0000000, /* rsduFunc(), EU# 3 */ + 0xa0000000, /* crcAccumVal(), EU# 3 */ + 0x20000000, /* setCrcAccum(), EU# 3 */ + 0x21800000, /* and(), EU# 3 */ + 0x21e00000, /* or(), EU# 3 */ + 0x20400000, /* add(), EU# 3 */ + 0x20500000, /* sub(), EU# 3 */ + 0x205a0000, /* andNot(), EU# 3 */ + 0x20a00000, /* shiftR(), EU# 3 */ + 0x202fa000, /* andReadyBit(), EU# 3 */ + 0x202f9000, /* andNotReadyBit(), EU# 3 */ + 0x202ea000, /* andWrapBit(), EU# 3 */ + 0x202da000, /* andLastBit(), EU# 3 */ + 0x202e2000, /* andInterruptBit(), EU# 3 */ + 0x202f2000, /* andCrcRestartBit(), EU# 3 */ +}; + +u32 MCD_funcDescTab5[]= +{ /* Task 5 Function Descriptor Table */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xa0045670, /* mainFunc(), EU# 3 */ + 0xa0000000, /* rsduFunc(), EU# 3 */ + 0xa0000000, /* crcAccumVal(), EU# 3 */ + 0x20000000, /* setCrcAccum(), EU# 3 */ + 0x21800000, /* and(), EU# 3 */ + 0x21e00000, /* or(), EU# 3 */ + 0x20400000, /* add(), EU# 3 */ + 0x20500000, /* sub(), EU# 3 */ + 0x205a0000, /* andNot(), EU# 3 */ + 0x20a00000, /* shiftR(), EU# 3 */ + 0x202fa000, /* andReadyBit(), EU# 3 */ + 0x202f9000, /* andNotReadyBit(), EU# 3 */ + 0x202ea000, /* andWrapBit(), EU# 3 */ + 0x202da000, /* andLastBit(), EU# 3 */ + 0x202e2000, /* andInterruptBit(), EU# 3 */ + 0x202f2000, /* andCrcRestartBit(), EU# 3 */ +}; + +u32 MCD_funcDescTab6[]= +{ /* Task 6 Function Descriptor Table */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xa0045670, /* mainFunc(), EU# 3 */ + 0xa0000000, /* rsduFunc(), EU# 3 */ + 0xa0000000, /* crcAccumVal(), EU# 3 */ + 0x20000000, /* setCrcAccum(), EU# 3 */ + 0x21800000, /* and(), EU# 3 */ + 0x21e00000, /* or(), EU# 3 */ + 0x20400000, /* add(), EU# 3 */ + 0x20500000, /* sub(), EU# 3 */ + 0x205a0000, /* andNot(), EU# 3 */ + 0x20a00000, /* shiftR(), EU# 3 */ + 0x202fa000, /* andReadyBit(), EU# 3 */ + 0x202f9000, /* andNotReadyBit(), EU# 3 */ + 0x202ea000, /* andWrapBit(), EU# 3 */ + 0x202da000, /* andLastBit(), EU# 3 */ + 0x202e2000, /* andInterruptBit(), EU# 3 */ + 0x202f2000, /* andCrcRestartBit(), EU# 3 */ +}; + +u32 MCD_funcDescTab7[]= +{ /* Task 7 Function Descriptor Table */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xa0045670, /* mainFunc(), EU# 3 */ + 0xa0000000, /* rsduFunc(), EU# 3 */ + 0xa0000000, /* crcAccumVal(), EU# 3 */ + 0x20000000, /* setCrcAccum(), EU# 3 */ + 0x21800000, /* and(), EU# 3 */ + 0x21e00000, /* or(), EU# 3 */ + 0x20400000, /* add(), EU# 3 */ + 0x20500000, /* sub(), EU# 3 */ + 0x205a0000, /* andNot(), EU# 3 */ + 0x20a00000, /* shiftR(), EU# 3 */ + 0x202fa000, /* andReadyBit(), EU# 3 */ + 0x202f9000, /* andNotReadyBit(), EU# 3 */ + 0x202ea000, /* andWrapBit(), EU# 3 */ + 0x202da000, /* andLastBit(), EU# 3 */ + 0x202e2000, /* andInterruptBit(), EU# 3 */ + 0x202f2000, /* andCrcRestartBit(), EU# 3 */ +}; + +u32 MCD_funcDescTab8[]= +{ /* Task 8 Function Descriptor Table */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xa0045670, /* mainFunc(), EU# 3 */ + 0xa0000000, /* rsduFunc(), EU# 3 */ + 0xa0000000, /* crcAccumVal(), EU# 3 */ + 0x20000000, /* setCrcAccum(), EU# 3 */ + 0x21800000, /* and(), EU# 3 */ + 0x21e00000, /* or(), EU# 3 */ + 0x20400000, /* add(), EU# 3 */ + 0x20500000, /* sub(), EU# 3 */ + 0x205a0000, /* andNot(), EU# 3 */ + 0x20a00000, /* shiftR(), EU# 3 */ + 0x202fa000, /* andReadyBit(), EU# 3 */ + 0x202f9000, /* andNotReadyBit(), EU# 3 */ + 0x202ea000, /* andWrapBit(), EU# 3 */ + 0x202da000, /* andLastBit(), EU# 3 */ + 0x202e2000, /* andInterruptBit(), EU# 3 */ + 0x202f2000, /* andCrcRestartBit(), EU# 3 */ +}; + +u32 MCD_funcDescTab9[]= +{ /* Task 9 Function Descriptor Table */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xa0045670, /* mainFunc(), EU# 3 */ + 0xa0000000, /* rsduFunc(), EU# 3 */ + 0xa0000000, /* crcAccumVal(), EU# 3 */ + 0x20000000, /* setCrcAccum(), EU# 3 */ + 0x21800000, /* and(), EU# 3 */ + 0x21e00000, /* or(), EU# 3 */ + 0x20400000, /* add(), EU# 3 */ + 0x20500000, /* sub(), EU# 3 */ + 0x205a0000, /* andNot(), EU# 3 */ + 0x20a00000, /* shiftR(), EU# 3 */ + 0x202fa000, /* andReadyBit(), EU# 3 */ + 0x202f9000, /* andNotReadyBit(), EU# 3 */ + 0x202ea000, /* andWrapBit(), EU# 3 */ + 0x202da000, /* andLastBit(), EU# 3 */ + 0x202e2000, /* andInterruptBit(), EU# 3 */ + 0x202f2000, /* andCrcRestartBit(), EU# 3 */ +}; + +u32 MCD_funcDescTab10[]= +{ /* Task 10 Function Descriptor Table */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xa0045670, /* mainFunc(), EU# 3 */ + 0xa0000000, /* rsduFunc(), EU# 3 */ + 0xa0000000, /* crcAccumVal(), EU# 3 */ + 0x20000000, /* setCrcAccum(), EU# 3 */ + 0x21800000, /* and(), EU# 3 */ + 0x21e00000, /* or(), EU# 3 */ + 0x20400000, /* add(), EU# 3 */ + 0x20500000, /* sub(), EU# 3 */ + 0x205a0000, /* andNot(), EU# 3 */ + 0x20a00000, /* shiftR(), EU# 3 */ + 0x202fa000, /* andReadyBit(), EU# 3 */ + 0x202f9000, /* andNotReadyBit(), EU# 3 */ + 0x202ea000, /* andWrapBit(), EU# 3 */ + 0x202da000, /* andLastBit(), EU# 3 */ + 0x202e2000, /* andInterruptBit(), EU# 3 */ + 0x202f2000, /* andCrcRestartBit(), EU# 3 */ +}; + +u32 MCD_funcDescTab11[]= +{ /* Task 11 Function Descriptor Table */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xa0045670, /* mainFunc(), EU# 3 */ + 0xa0000000, /* rsduFunc(), EU# 3 */ + 0xa0000000, /* crcAccumVal(), EU# 3 */ + 0x20000000, /* setCrcAccum(), EU# 3 */ + 0x21800000, /* and(), EU# 3 */ + 0x21e00000, /* or(), EU# 3 */ + 0x20400000, /* add(), EU# 3 */ + 0x20500000, /* sub(), EU# 3 */ + 0x205a0000, /* andNot(), EU# 3 */ + 0x20a00000, /* shiftR(), EU# 3 */ + 0x202fa000, /* andReadyBit(), EU# 3 */ + 0x202f9000, /* andNotReadyBit(), EU# 3 */ + 0x202ea000, /* andWrapBit(), EU# 3 */ + 0x202da000, /* andLastBit(), EU# 3 */ + 0x202e2000, /* andInterruptBit(), EU# 3 */ + 0x202f2000, /* andCrcRestartBit(), EU# 3 */ +}; + +u32 MCD_funcDescTab12[]= +{ /* Task 12 Function Descriptor Table */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xa0045670, /* mainFunc(), EU# 3 */ + 0xa0000000, /* rsduFunc(), EU# 3 */ + 0xa0000000, /* crcAccumVal(), EU# 3 */ + 0x20000000, /* setCrcAccum(), EU# 3 */ + 0x21800000, /* and(), EU# 3 */ + 0x21e00000, /* or(), EU# 3 */ + 0x20400000, /* add(), EU# 3 */ + 0x20500000, /* sub(), EU# 3 */ + 0x205a0000, /* andNot(), EU# 3 */ + 0x20a00000, /* shiftR(), EU# 3 */ + 0x202fa000, /* andReadyBit(), EU# 3 */ + 0x202f9000, /* andNotReadyBit(), EU# 3 */ + 0x202ea000, /* andWrapBit(), EU# 3 */ + 0x202da000, /* andLastBit(), EU# 3 */ + 0x202e2000, /* andInterruptBit(), EU# 3 */ + 0x202f2000, /* andCrcRestartBit(), EU# 3 */ +}; + +u32 MCD_funcDescTab13[]= +{ /* Task 13 Function Descriptor Table */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xa0045670, /* mainFunc(), EU# 3 */ + 0xa0000000, /* rsduFunc(), EU# 3 */ + 0xa0000000, /* crcAccumVal(), EU# 3 */ + 0x20000000, /* setCrcAccum(), EU# 3 */ + 0x21800000, /* and(), EU# 3 */ + 0x21e00000, /* or(), EU# 3 */ + 0x20400000, /* add(), EU# 3 */ + 0x20500000, /* sub(), EU# 3 */ + 0x205a0000, /* andNot(), EU# 3 */ + 0x20a00000, /* shiftR(), EU# 3 */ + 0x202fa000, /* andReadyBit(), EU# 3 */ + 0x202f9000, /* andNotReadyBit(), EU# 3 */ + 0x202ea000, /* andWrapBit(), EU# 3 */ + 0x202da000, /* andLastBit(), EU# 3 */ + 0x202e2000, /* andInterruptBit(), EU# 3 */ + 0x202f2000, /* andCrcRestartBit(), EU# 3 */ +}; + +u32 MCD_funcDescTab14[]= +{ /* Task 14 Function Descriptor Table */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xa0045670, /* mainFunc(), EU# 3 */ + 0xa0000000, /* rsduFunc(), EU# 3 */ + 0xa0000000, /* crcAccumVal(), EU# 3 */ + 0x20000000, /* setCrcAccum(), EU# 3 */ + 0x21800000, /* and(), EU# 3 */ + 0x21e00000, /* or(), EU# 3 */ + 0x20400000, /* add(), EU# 3 */ + 0x20500000, /* sub(), EU# 3 */ + 0x205a0000, /* andNot(), EU# 3 */ + 0x20a00000, /* shiftR(), EU# 3 */ + 0x202fa000, /* andReadyBit(), EU# 3 */ + 0x202f9000, /* andNotReadyBit(), EU# 3 */ + 0x202ea000, /* andWrapBit(), EU# 3 */ + 0x202da000, /* andLastBit(), EU# 3 */ + 0x202e2000, /* andInterruptBit(), EU# 3 */ + 0x202f2000, /* andCrcRestartBit(), EU# 3 */ +}; + +u32 MCD_funcDescTab15[]= +{ /* Task 15 Function Descriptor Table */ + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0xa0045670, /* mainFunc(), EU# 3 */ + 0xa0000000, /* rsduFunc(), EU# 3 */ + 0xa0000000, /* crcAccumVal(), EU# 3 */ + 0x20000000, /* setCrcAccum(), EU# 3 */ + 0x21800000, /* and(), EU# 3 */ + 0x21e00000, /* or(), EU# 3 */ + 0x20400000, /* add(), EU# 3 */ + 0x20500000, /* sub(), EU# 3 */ + 0x205a0000, /* andNot(), EU# 3 */ + 0x20a00000, /* shiftR(), EU# 3 */ + 0x202fa000, /* andReadyBit(), EU# 3 */ + 0x202f9000, /* andNotReadyBit(), EU# 3 */ + 0x202ea000, /* andWrapBit(), EU# 3 */ + 0x202da000, /* andLastBit(), EU# 3 */ + 0x202e2000, /* andInterruptBit(), EU# 3 */ + 0x202f2000, /* andCrcRestartBit(), EU# 3 */ +}; +#endif /*MCD_INCLUDE_EU*/ + +u32 MCD_contextSave0[128]; /* Task 0 context save space */ +u32 MCD_contextSave1[128]; /* Task 1 context save space */ +u32 MCD_contextSave2[128]; /* Task 2 context save space */ +u32 MCD_contextSave3[128]; /* Task 3 context save space */ +u32 MCD_contextSave4[128]; /* Task 4 context save space */ +u32 MCD_contextSave5[128]; /* Task 5 context save space */ +u32 MCD_contextSave6[128]; /* Task 6 context save space */ +u32 MCD_contextSave7[128]; /* Task 7 context save space */ +u32 MCD_contextSave8[128]; /* Task 8 context save space */ +u32 MCD_contextSave9[128]; /* Task 9 context save space */ +u32 MCD_contextSave10[128]; /* Task 10 context save space */ +u32 MCD_contextSave11[128]; /* Task 11 context save space */ +u32 MCD_contextSave12[128]; /* Task 12 context save space */ +u32 MCD_contextSave13[128]; /* Task 13 context save space */ +u32 MCD_contextSave14[128]; /* Task 14 context save space */ +u32 MCD_contextSave15[128]; /* Task 15 context save space */ + + +u32 MCD_ChainNoEu_TDT[]; +u32 MCD_SingleNoEu_TDT[]; +#ifdef MCD_INCLUDE_EU +u32 MCD_ChainEu_TDT[]; +u32 MCD_SingleEu_TDT[]; +#endif +u32 MCD_ENetRcv_TDT[]; +u32 MCD_ENetXmit_TDT[]; + +u32 MCD_modelTaskTableSrc[]= +{ + (u32)MCD_ChainNoEu_TDT, + (u32)&((u8*)MCD_ChainNoEu_TDT)[0x0000016c], + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + (u32)MCD_SingleNoEu_TDT, + (u32)&((u8*)MCD_SingleNoEu_TDT)[0x000000d4], + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +#ifdef MCD_INCLUDE_EU + (u32)MCD_ChainEu_TDT, + (u32)&((u8*)MCD_ChainEu_TDT)[0x000001b4], + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + (u32)MCD_SingleEu_TDT, + (u32)&((u8*)MCD_SingleEu_TDT)[0x00000124], + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +#endif + (u32)MCD_ENetRcv_TDT, + (u32)&((u8*)MCD_ENetRcv_TDT)[0x0000009c], + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + (u32)MCD_ENetXmit_TDT, + (u32)&((u8*)MCD_ENetXmit_TDT)[0x000000d0], + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, + 0x00000000, +}; +u32 MCD_ChainNoEu_TDT[]= +{ + 0x80004000, /* 0000(:370): LCDEXT: idx0 = 0x00000000; ; */ + 0x8118801b, /* 0004(:370): LCD: idx1 = var2; idx1 once var0; idx1 += inc3 */ + 0xb8c60018, /* 0008(:371): LCD: idx2 = *(idx1 + var12); idx2 once var0; idx2 += inc3 */ + 0x10002b10, /* 000C(:372): DRD1A: var10 = idx2; FN=0 MORE init=0 WS=0 RS=0 */ + 0x7000000d, /* 0010(:373): DRD2A: EU0=0 EU1=0 EU2=0 EU3=13 EXT MORE init=0 WS=0 RS=0 */ + 0x018cf89f, /* 0014(:373): DRD2B1: var6 = EU3(); EU3(idx2) */ + 0x6000000a, /* 0018(:374): DRD2A: EU0=0 EU1=0 EU2=0 EU3=10 EXT init=0 WS=0 RS=0 */ + 0x080cf89f, /* 001C(:374): DRD2B1: idx0 = EU3(); EU3(idx2) */ + 0x000001f8, /* 0020(:0): NOP */ + 0x98180364, /* 0024(:378): LCD: idx0 = idx0; idx0 == var13; idx0 += inc4 */ + 0x8118801b, /* 0028(:380): LCD: idx1 = var2; idx1 once var0; idx1 += inc3 */ + 0xf8c6001a, /* 002C(:381): LCDEXT: idx2 = *(idx1 + var12 + 8); idx2 once var0; idx2 += inc3 */ + 0xb8c6601b, /* 0030(:382): LCD: idx3 = *(idx1 + var12 + 12); ; idx3 += inc3 */ + 0x10002710, /* 0034(:384): DRD1A: var9 = idx2; FN=0 MORE init=0 WS=0 RS=0 */ + 0x00000f18, /* 0038(:385): DRD1A: var3 = idx3; FN=0 init=0 WS=0 RS=0 */ + 0xb8c6001d, /* 003C(:387): LCD: idx2 = *(idx1 + var12 + 20); idx2 once var0; idx2 += inc3 */ + 0x10001310, /* 0040(:388): DRD1A: var4 = idx2; FN=0 MORE init=0 WS=0 RS=0 */ + 0x60000007, /* 0044(:389): DRD2A: EU0=0 EU1=0 EU2=0 EU3=7 EXT init=0 WS=0 RS=0 */ + 0x014cf88b, /* 0048(:389): DRD2B1: var5 = EU3(); EU3(idx2,var11) */ + 0x98c6001c, /* 004C(:391): LCD: idx2 = idx1 + var12 + 4; idx2 once var0; idx2 += inc3 */ + 0x00000710, /* 0050(:392): DRD1A: var1 = idx2; FN=0 init=0 WS=0 RS=0 */ + 0x98c70018, /* 0054(:393): LCD: idx2 = idx1 + var14; idx2 once var0; idx2 += inc3 */ + 0x10001f10, /* 0058(:394): DRD1A: var7 = idx2; FN=0 MORE init=0 WS=0 RS=0 */ + 0x0000c818, /* 005C(:395): DRD1A: *idx2 = var3; FN=0 init=0 WS=0 RS=0 */ + 0x000001f8, /* 0060(:0): NOP */ + 0xc1476018, /* 0064(:399): LCDEXT: idx1 = var2 + var14; ; idx1 += inc3 */ + 0xc003231d, /* 0068(:399): LCDEXT: idx2 = var0, idx3 = var6; idx3 == var12; idx2 += inc3, idx3 += inc5 */ + 0x811a601b, /* 006C(:400): LCD: idx4 = var2; ; idx4 += inc3 */ + 0xc1862102, /* 0070(:403): LCDEXT: idx5 = var3, idx6 = var12; idx6 < var4; idx5 += inc0, idx6 += inc2 */ + 0x849be009, /* 0074(:403): LCD: idx7 = var9; ; idx7 += inc1 */ + 0x03fed7b8, /* 0078(:406): DRD1A: *idx7; FN=0 init=31 WS=3 RS=3 */ + 0xda9b001b, /* 007C(:408): LCDEXT: idx5 = idx5, idx6 = idx6; idx5 once var0; idx5 += inc3, idx6 += inc3 */ + 0x9b9be01b, /* 0080(:408): LCD: idx7 = idx7; ; idx7 += inc3 */ + 0x1000cb20, /* 0084(:409): DRD1A: *idx2 = idx4; FN=0 MORE init=0 WS=0 RS=0 */ + 0x70000006, /* 0088(:410): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */ + 0x088cf88f, /* 008C(:410): DRD2B1: idx2 = EU3(); EU3(idx2,var15) */ + 0x1000cb28, /* 0090(:411): DRD1A: *idx2 = idx5; FN=0 MORE init=0 WS=0 RS=0 */ + 0x70000006, /* 0094(:412): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */ + 0x088cf88f, /* 0098(:412): DRD2B1: idx2 = EU3(); EU3(idx2,var15) */ + 0x1000cb30, /* 009C(:413): DRD1A: *idx2 = idx6; FN=0 MORE init=0 WS=0 RS=0 */ + 0x70000006, /* 00A0(:414): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */ + 0x088cf88f, /* 00A4(:414): DRD2B1: idx2 = EU3(); EU3(idx2,var15) */ + 0x1000cb38, /* 00A8(:415): DRD1A: *idx2 = idx7; FN=0 MORE init=0 WS=0 RS=0 */ + 0x0000c728, /* 00AC(:416): DRD1A: *idx1 = idx5; FN=0 init=0 WS=0 RS=0 */ + 0x000001f8, /* 00B0(:0): NOP */ + 0xc1476018, /* 00B4(:420): LCDEXT: idx1 = var2 + var14; ; idx1 += inc3 */ + 0xc003241d, /* 00B8(:420): LCDEXT: idx2 = var0, idx3 = var6; idx3 == var16; idx2 += inc3, idx3 += inc5 */ + 0x811a601b, /* 00BC(:421): LCD: idx4 = var2; ; idx4 += inc3 */ + 0xda9b001b, /* 00C0(:424): LCDEXT: idx5 = idx5, idx6 = idx6; idx5 once var0; idx5 += inc3, idx6 += inc3 */ + 0x9b9be01b, /* 00C4(:424): LCD: idx7 = idx7; ; idx7 += inc3 */ + 0x0000d3a0, /* 00C8(:425): DRD1A: *idx4; FN=0 init=0 WS=0 RS=0 */ + 0xc1862102, /* 00CC(:427): LCDEXT: idx5 = var3, idx6 = var12; idx6 < var4; idx5 += inc0, idx6 += inc2 */ + 0x849be009, /* 00D0(:427): LCD: idx7 = var9; ; idx7 += inc1 */ + 0x0bfed7b8, /* 00D4(:430): DRD1A: *idx7; FN=0 TFD init=31 WS=3 RS=3 */ + 0xda9b001b, /* 00D8(:432): LCDEXT: idx5 = idx5, idx6 = idx6; idx5 once var0; idx5 += inc3, idx6 += inc3 */ + 0x9b9be01b, /* 00DC(:432): LCD: idx7 = idx7; ; idx7 += inc3 */ + 0x1000cb20, /* 00E0(:433): DRD1A: *idx2 = idx4; FN=0 MORE init=0 WS=0 RS=0 */ + 0x70000006, /* 00E4(:434): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */ + 0x088cf88f, /* 00E8(:434): DRD2B1: idx2 = EU3(); EU3(idx2,var15) */ + 0x1000cb28, /* 00EC(:435): DRD1A: *idx2 = idx5; FN=0 MORE init=0 WS=0 RS=0 */ + 0x70000006, /* 00F0(:436): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */ + 0x088cf88f, /* 00F4(:436): DRD2B1: idx2 = EU3(); EU3(idx2,var15) */ + 0x1000cb30, /* 00F8(:437): DRD1A: *idx2 = idx6; FN=0 MORE init=0 WS=0 RS=0 */ + 0x70000006, /* 00FC(:438): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */ + 0x088cf88f, /* 0100(:438): DRD2B1: idx2 = EU3(); EU3(idx2,var15) */ + 0x1000cb38, /* 0104(:439): DRD1A: *idx2 = idx7; FN=0 MORE init=0 WS=0 RS=0 */ + 0x0000c728, /* 0108(:440): DRD1A: *idx1 = idx5; FN=0 init=0 WS=0 RS=0 */ + 0x000001f8, /* 010C(:0): NOP */ + 0x8118801b, /* 0110(:444): LCD: idx1 = var2; idx1 once var0; idx1 += inc3 */ + 0xd8c60018, /* 0114(:446): LCDEXT: idx2 = idx1 + var12; idx2 once var0; idx2 += inc3 */ + 0x98c6601c, /* 0118(:446): LCD: idx3 = idx1 + var12 + 4; ; idx3 += inc3 */ + 0x6000000b, /* 011C(:447): DRD2A: EU0=0 EU1=0 EU2=0 EU3=11 EXT init=0 WS=0 RS=0 */ + 0x0c8cfc9f, /* 0120(:447): DRD2B1: *idx2 = EU3(); EU3(*idx2) */ + 0x000001f8, /* 0124(:0): NOP */ + 0xa146001e, /* 0128(:450): LCD: idx1 = *(var2 + var12 + 24); idx1 once var0; idx1 += inc3 */ + 0x10000b08, /* 012C(:451): DRD1A: var2 = idx1; FN=0 MORE init=0 WS=0 RS=0 */ + 0x10002050, /* 0130(:452): DRD1A: var8 = var10; FN=0 MORE init=0 WS=0 RS=0 */ + 0xb8c60018, /* 0134(:453): LCD: idx2 = *(idx1 + var12); idx2 once var0; idx2 += inc3 */ + 0x10002b10, /* 0138(:454): DRD1A: var10 = idx2; FN=0 MORE init=0 WS=0 RS=0 */ + 0x7000000a, /* 013C(:455): DRD2A: EU0=0 EU1=0 EU2=0 EU3=10 EXT MORE init=0 WS=0 RS=0 */ + 0x080cf89f, /* 0140(:455): DRD2B1: idx0 = EU3(); EU3(idx2) */ + 0x6000000d, /* 0144(:456): DRD2A: EU0=0 EU1=0 EU2=0 EU3=13 EXT init=0 WS=0 RS=0 */ + 0x018cf89f, /* 0148(:456): DRD2B1: var6 = EU3(); EU3(idx2) */ + 0x000001f8, /* 014C(:0): NOP */ + 0x8618801b, /* 0150(:462): LCD: idx1 = var12; idx1 once var0; idx1 += inc3 */ + 0x7000000e, /* 0154(:463): DRD2A: EU0=0 EU1=0 EU2=0 EU3=14 EXT MORE init=0 WS=0 RS=0 */ + 0x084cf21f, /* 0158(:463): DRD2B1: idx1 = EU3(); EU3(var8) */ + 0xd8990336, /* 015C(:464): LCDEXT: idx2 = idx1; idx2 > var12; idx2 += inc6 */ + 0x8019801b, /* 0160(:464): LCD: idx3 = var0; idx3 once var0; idx3 += inc3 */ + 0x040001f8, /* 0164(:465): DRD1A: FN=0 INT init=0 WS=0 RS=0 */ + 0x000001f8, /* 0168(:0): NOP */ + 0x000001f8, /* 016C(:0): NOP */ +}; +u32 MCD_SingleNoEu_TDT[]= +{ + 0x8198001b, /* 0000(:657): LCD: idx0 = var3; idx0 once var0; idx0 += inc3 */ + 0x7000000d, /* 0004(:658): DRD2A: EU0=0 EU1=0 EU2=0 EU3=13 EXT MORE init=0 WS=0 RS=0 */ + 0x080cf81f, /* 0008(:658): DRD2B1: idx0 = EU3(); EU3(idx0) */ + 0x8198801b, /* 000C(:659): LCD: idx1 = var3; idx1 once var0; idx1 += inc3 */ + 0x6000000e, /* 0010(:660): DRD2A: EU0=0 EU1=0 EU2=0 EU3=14 EXT init=0 WS=0 RS=0 */ + 0x084cf85f, /* 0014(:660): DRD2B1: idx1 = EU3(); EU3(idx1) */ + 0x000001f8, /* 0018(:0): NOP */ + 0x8298001b, /* 001C(:664): LCD: idx0 = var5; idx0 once var0; idx0 += inc3 */ + 0x7000000d, /* 0020(:665): DRD2A: EU0=0 EU1=0 EU2=0 EU3=13 EXT MORE init=0 WS=0 RS=0 */ + 0x010cf81f, /* 0024(:665): DRD2B1: var4 = EU3(); EU3(idx0) */ + 0x6000000e, /* 0028(:666): DRD2A: EU0=0 EU1=0 EU2=0 EU3=14 EXT init=0 WS=0 RS=0 */ + 0x018cf81f, /* 002C(:666): DRD2B1: var6 = EU3(); EU3(idx0) */ + 0xc202601b, /* 0030(:669): LCDEXT: idx0 = var4, idx1 = var4; ; idx0 += inc3, idx1 += inc3 */ + 0xc002221c, /* 0034(:669): LCDEXT: idx2 = var0, idx3 = var4; idx3 == var8; idx2 += inc3, idx3 += inc4 */ + 0x809a601b, /* 0038(:670): LCD: idx4 = var1; ; idx4 += inc3 */ + 0xc10420c2, /* 003C(:673): LCDEXT: idx5 = var2, idx6 = var8; idx6 < var3; idx5 += inc0, idx6 += inc2 */ + 0x839be009, /* 0040(:673): LCD: idx7 = var7; ; idx7 += inc1 */ + 0x03fed7b8, /* 0044(:676): DRD1A: *idx7; FN=0 init=31 WS=3 RS=3 */ + 0xda9b001b, /* 0048(:678): LCDEXT: idx5 = idx5, idx6 = idx6; idx5 once var0; idx5 += inc3, idx6 += inc3 */ + 0x9b9be01b, /* 004C(:678): LCD: idx7 = idx7; ; idx7 += inc3 */ + 0x70000006, /* 0050(:680): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */ + 0x088cf889, /* 0054(:680): DRD2B1: idx2 = EU3(); EU3(idx2,var9) */ + 0x1000cb28, /* 0058(:681): DRD1A: *idx2 = idx5; FN=0 MORE init=0 WS=0 RS=0 */ + 0x70000006, /* 005C(:682): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */ + 0x088cf889, /* 0060(:682): DRD2B1: idx2 = EU3(); EU3(idx2,var9) */ + 0x1000cb30, /* 0064(:683): DRD1A: *idx2 = idx6; FN=0 MORE init=0 WS=0 RS=0 */ + 0x70000006, /* 0068(:684): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */ + 0x088cf889, /* 006C(:684): DRD2B1: idx2 = EU3(); EU3(idx2,var9) */ + 0x0000cb38, /* 0070(:685): DRD1A: *idx2 = idx7; FN=0 init=0 WS=0 RS=0 */ + 0x000001f8, /* 0074(:0): NOP */ + 0xc202601b, /* 0078(:689): LCDEXT: idx0 = var4, idx1 = var4; ; idx0 += inc3, idx1 += inc3 */ + 0xc002229c, /* 007C(:689): LCDEXT: idx2 = var0, idx3 = var4; idx3 == var10; idx2 += inc3, idx3 += inc4 */ + 0x809a601b, /* 0080(:690): LCD: idx4 = var1; ; idx4 += inc3 */ + 0xda9b001b, /* 0084(:693): LCDEXT: idx5 = idx5, idx6 = idx6; idx5 once var0; idx5 += inc3, idx6 += inc3 */ + 0x9b9be01b, /* 0088(:693): LCD: idx7 = idx7; ; idx7 += inc3 */ + 0x0000d3a0, /* 008C(:694): DRD1A: *idx4; FN=0 init=0 WS=0 RS=0 */ + 0xc10420c2, /* 0090(:696): LCDEXT: idx5 = var2, idx6 = var8; idx6 < var3; idx5 += inc0, idx6 += inc2 */ + 0x839be009, /* 0094(:696): LCD: idx7 = var7; ; idx7 += inc1 */ + 0x0bfed7b8, /* 0098(:699): DRD1A: *idx7; FN=0 TFD init=31 WS=3 RS=3 */ + 0xda9b001b, /* 009C(:701): LCDEXT: idx5 = idx5, idx6 = idx6; idx5 once var0; idx5 += inc3, idx6 += inc3 */ + 0x9b9be01b, /* 00A0(:701): LCD: idx7 = idx7; ; idx7 += inc3 */ + 0x70000006, /* 00A4(:703): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */ + 0x088cf889, /* 00A8(:703): DRD2B1: idx2 = EU3(); EU3(idx2,var9) */ + 0x1000cb28, /* 00AC(:704): DRD1A: *idx2 = idx5; FN=0 MORE init=0 WS=0 RS=0 */ + 0x70000006, /* 00B0(:705): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */ + 0x088cf889, /* 00B4(:705): DRD2B1: idx2 = EU3(); EU3(idx2,var9) */ + 0x1000cb30, /* 00B8(:706): DRD1A: *idx2 = idx6; FN=0 MORE init=0 WS=0 RS=0 */ + 0x70000006, /* 00BC(:707): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */ + 0x088cf889, /* 00C0(:707): DRD2B1: idx2 = EU3(); EU3(idx2,var9) */ + 0x0000cb38, /* 00C4(:708): DRD1A: *idx2 = idx7; FN=0 init=0 WS=0 RS=0 */ + 0x000001f8, /* 00C8(:0): NOP */ + 0xc318022d, /* 00CC(:712): LCDEXT: idx0 = var6; idx0 > var8; idx0 += inc5 */ + 0x8018801b, /* 00D0(:712): LCD: idx1 = var0; idx1 once var0; idx1 += inc3 */ + 0x040001f8, /* 00D4(:713): DRD1A: FN=0 INT init=0 WS=0 RS=0 */ +}; +#ifdef MCD_INCLUDE_EU +u32 MCD_ChainEu_TDT[]= +{ + 0x80004000, /* 0000(:947): LCDEXT: idx0 = 0x00000000; ; */ + 0x8198801b, /* 0004(:947): LCD: idx1 = var3; idx1 once var0; idx1 += inc3 */ + 0xb8c68018, /* 0008(:948): LCD: idx2 = *(idx1 + var13); idx2 once var0; idx2 += inc3 */ + 0x10002f10, /* 000C(:949): DRD1A: var11 = idx2; FN=0 MORE init=0 WS=0 RS=0 */ + 0x7000000d, /* 0010(:950): DRD2A: EU0=0 EU1=0 EU2=0 EU3=13 EXT MORE init=0 WS=0 RS=0 */ + 0x01ccf89f, /* 0014(:950): DRD2B1: var7 = EU3(); EU3(idx2) */ + 0x6000000a, /* 0018(:951): DRD2A: EU0=0 EU1=0 EU2=0 EU3=10 EXT init=0 WS=0 RS=0 */ + 0x080cf89f, /* 001C(:951): DRD2B1: idx0 = EU3(); EU3(idx2) */ + 0x000001f8, /* 0020(:0): NOP */ + 0x981803a4, /* 0024(:955): LCD: idx0 = idx0; idx0 == var14; idx0 += inc4 */ + 0x8198801b, /* 0028(:957): LCD: idx1 = var3; idx1 once var0; idx1 += inc3 */ + 0xf8c6801a, /* 002C(:958): LCDEXT: idx2 = *(idx1 + var13 + 8); idx2 once var0; idx2 += inc3 */ + 0xb8c6e01b, /* 0030(:959): LCD: idx3 = *(idx1 + var13 + 12); ; idx3 += inc3 */ + 0x10002b10, /* 0034(:961): DRD1A: var10 = idx2; FN=0 MORE init=0 WS=0 RS=0 */ + 0x00001318, /* 0038(:962): DRD1A: var4 = idx3; FN=0 init=0 WS=0 RS=0 */ + 0xb8c6801d, /* 003C(:964): LCD: idx2 = *(idx1 + var13 + 20); idx2 once var0; idx2 += inc3 */ + 0x10001710, /* 0040(:965): DRD1A: var5 = idx2; FN=0 MORE init=0 WS=0 RS=0 */ + 0x60000007, /* 0044(:966): DRD2A: EU0=0 EU1=0 EU2=0 EU3=7 EXT init=0 WS=0 RS=0 */ + 0x018cf88c, /* 0048(:966): DRD2B1: var6 = EU3(); EU3(idx2,var12) */ + 0x98c6801c, /* 004C(:968): LCD: idx2 = idx1 + var13 + 4; idx2 once var0; idx2 += inc3 */ + 0x00000b10, /* 0050(:969): DRD1A: var2 = idx2; FN=0 init=0 WS=0 RS=0 */ + 0x98c78018, /* 0054(:970): LCD: idx2 = idx1 + var15; idx2 once var0; idx2 += inc3 */ + 0x10002310, /* 0058(:971): DRD1A: var8 = idx2; FN=0 MORE init=0 WS=0 RS=0 */ + 0x0000c820, /* 005C(:972): DRD1A: *idx2 = var4; FN=0 init=0 WS=0 RS=0 */ + 0x000001f8, /* 0060(:0): NOP */ + 0x8698801b, /* 0064(:976): LCD: idx1 = var13; idx1 once var0; idx1 += inc3 */ + 0x7000000f, /* 0068(:977): DRD2A: EU0=0 EU1=0 EU2=0 EU3=15 EXT MORE init=0 WS=0 RS=0 */ + 0x084cf2df, /* 006C(:977): DRD2B1: idx1 = EU3(); EU3(var11) */ + 0xd899042d, /* 0070(:978): LCDEXT: idx2 = idx1; idx2 >= var16; idx2 += inc5 */ + 0x8019801b, /* 0074(:978): LCD: idx3 = var0; idx3 once var0; idx3 += inc3 */ + 0x60000003, /* 0078(:979): DRD2A: EU0=0 EU1=0 EU2=0 EU3=3 EXT init=0 WS=0 RS=0 */ + 0x2cd7c7df, /* 007C(:979): DRD2B2: EU3(var13) */ + 0xd8990364, /* 0080(:980): LCDEXT: idx2 = idx1; idx2 == var13; idx2 += inc4 */ + 0x8019801b, /* 0084(:980): LCD: idx3 = var0; idx3 once var0; idx3 += inc3 */ + 0x60000003, /* 0088(:981): DRD2A: EU0=0 EU1=0 EU2=0 EU3=3 EXT init=0 WS=0 RS=0 */ + 0x2c17c7df, /* 008C(:981): DRD2B2: EU3(var1) */ + 0x000001f8, /* 0090(:0): NOP */ + 0xc1c7e018, /* 0094(:984): LCDEXT: idx1 = var3 + var15; ; idx1 += inc3 */ + 0xc003a35e, /* 0098(:984): LCDEXT: idx2 = var0, idx3 = var7; idx3 == var13; idx2 += inc3, idx3 += inc6 */ + 0x819a601b, /* 009C(:985): LCD: idx4 = var3; ; idx4 += inc3 */ + 0xc206a142, /* 00A0(:988): LCDEXT: idx5 = var4, idx6 = var13; idx6 < var5; idx5 += inc0, idx6 += inc2 */ + 0x851be009, /* 00A4(:988): LCD: idx7 = var10; ; idx7 += inc1 */ + 0x63fe0000, /* 00A8(:991): DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=31 WS=3 RS=3 */ + 0x0d4cfddf, /* 00AC(:991): DRD2B1: *idx5 = EU3(); EU3(*idx7) */ + 0xda9b001b, /* 00B0(:993): LCDEXT: idx5 = idx5, idx6 = idx6; idx5 once var0; idx5 += inc3, idx6 += inc3 */ + 0x9b9be01b, /* 00B4(:993): LCD: idx7 = idx7; ; idx7 += inc3 */ + 0x70000002, /* 00B8(:994): DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */ + 0x004cf81f, /* 00BC(:994): DRD2B1: var1 = EU3(); EU3(idx0) */ + 0x1000cb20, /* 00C0(:995): DRD1A: *idx2 = idx4; FN=0 MORE init=0 WS=0 RS=0 */ + 0x70000006, /* 00C4(:996): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */ + 0x088cf891, /* 00C8(:996): DRD2B1: idx2 = EU3(); EU3(idx2,var17) */ + 0x1000cb28, /* 00CC(:997): DRD1A: *idx2 = idx5; FN=0 MORE init=0 WS=0 RS=0 */ + 0x70000006, /* 00D0(:998): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */ + 0x088cf891, /* 00D4(:998): DRD2B1: idx2 = EU3(); EU3(idx2,var17) */ + 0x1000cb30, /* 00D8(:999): DRD1A: *idx2 = idx6; FN=0 MORE init=0 WS=0 RS=0 */ + 0x70000006, /* 00DC(:1000): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */ + 0x088cf891, /* 00E0(:1000): DRD2B1: idx2 = EU3(); EU3(idx2,var17) */ + 0x1000cb38, /* 00E4(:1001): DRD1A: *idx2 = idx7; FN=0 MORE init=0 WS=0 RS=0 */ + 0x0000c728, /* 00E8(:1002): DRD1A: *idx1 = idx5; FN=0 init=0 WS=0 RS=0 */ + 0x000001f8, /* 00EC(:0): NOP */ + 0xc1c7e018, /* 00F0(:1006): LCDEXT: idx1 = var3 + var15; ; idx1 += inc3 */ + 0xc003a49e, /* 00F4(:1006): LCDEXT: idx2 = var0, idx3 = var7; idx3 == var18; idx2 += inc3, idx3 += inc6 */ + 0x819a601b, /* 00F8(:1007): LCD: idx4 = var3; ; idx4 += inc3 */ + 0xda9b001b, /* 00FC(:1010): LCDEXT: idx5 = idx5, idx6 = idx6; idx5 once var0; idx5 += inc3, idx6 += inc3 */ + 0x9b9be01b, /* 0100(:1010): LCD: idx7 = idx7; ; idx7 += inc3 */ + 0x0000d3a0, /* 0104(:1011): DRD1A: *idx4; FN=0 init=0 WS=0 RS=0 */ + 0xc206a142, /* 0108(:1013): LCDEXT: idx5 = var4, idx6 = var13; idx6 < var5; idx5 += inc0, idx6 += inc2 */ + 0x851be009, /* 010C(:1013): LCD: idx7 = var10; ; idx7 += inc1 */ + 0x6bfe0000, /* 0110(:1016): DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 TFD EXT init=31 WS=3 RS=3 */ + 0x0d4cfddf, /* 0114(:1016): DRD2B1: *idx5 = EU3(); EU3(*idx7) */ + 0xda9b001b, /* 0118(:1018): LCDEXT: idx5 = idx5, idx6 = idx6; idx5 once var0; idx5 += inc3, idx6 += inc3 */ + 0x9b9be01b, /* 011C(:1018): LCD: idx7 = idx7; ; idx7 += inc3 */ + 0x70000002, /* 0120(:1019): DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */ + 0x004cf81f, /* 0124(:1019): DRD2B1: var1 = EU3(); EU3(idx0) */ + 0x1000cb20, /* 0128(:1020): DRD1A: *idx2 = idx4; FN=0 MORE init=0 WS=0 RS=0 */ + 0x70000006, /* 012C(:1021): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */ + 0x088cf891, /* 0130(:1021): DRD2B1: idx2 = EU3(); EU3(idx2,var17) */ + 0x1000cb28, /* 0134(:1022): DRD1A: *idx2 = idx5; FN=0 MORE init=0 WS=0 RS=0 */ + 0x70000006, /* 0138(:1023): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */ + 0x088cf891, /* 013C(:1023): DRD2B1: idx2 = EU3(); EU3(idx2,var17) */ + 0x1000cb30, /* 0140(:1024): DRD1A: *idx2 = idx6; FN=0 MORE init=0 WS=0 RS=0 */ + 0x70000006, /* 0144(:1025): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */ + 0x088cf891, /* 0148(:1025): DRD2B1: idx2 = EU3(); EU3(idx2,var17) */ + 0x1000cb38, /* 014C(:1026): DRD1A: *idx2 = idx7; FN=0 MORE init=0 WS=0 RS=0 */ + 0x0000c728, /* 0150(:1027): DRD1A: *idx1 = idx5; FN=0 init=0 WS=0 RS=0 */ + 0x000001f8, /* 0154(:0): NOP */ + 0x8198801b, /* 0158(:1031): LCD: idx1 = var3; idx1 once var0; idx1 += inc3 */ + 0xd8c68018, /* 015C(:1033): LCDEXT: idx2 = idx1 + var13; idx2 once var0; idx2 += inc3 */ + 0x98c6e01c, /* 0160(:1033): LCD: idx3 = idx1 + var13 + 4; ; idx3 += inc3 */ + 0x6000000b, /* 0164(:1034): DRD2A: EU0=0 EU1=0 EU2=0 EU3=11 EXT init=0 WS=0 RS=0 */ + 0x0c8cfc9f, /* 0168(:1034): DRD2B1: *idx2 = EU3(); EU3(*idx2) */ + 0x0000cc08, /* 016C(:1035): DRD1A: *idx3 = var1; FN=0 init=0 WS=0 RS=0 */ + 0xa1c6801e, /* 0170(:1038): LCD: idx1 = *(var3 + var13 + 24); idx1 once var0; idx1 += inc3 */ + 0x10000f08, /* 0174(:1039): DRD1A: var3 = idx1; FN=0 MORE init=0 WS=0 RS=0 */ + 0x10002458, /* 0178(:1040): DRD1A: var9 = var11; FN=0 MORE init=0 WS=0 RS=0 */ + 0xb8c68018, /* 017C(:1041): LCD: idx2 = *(idx1 + var13); idx2 once var0; idx2 += inc3 */ + 0x10002f10, /* 0180(:1042): DRD1A: var11 = idx2; FN=0 MORE init=0 WS=0 RS=0 */ + 0x7000000a, /* 0184(:1043): DRD2A: EU0=0 EU1=0 EU2=0 EU3=10 EXT MORE init=0 WS=0 RS=0 */ + 0x080cf89f, /* 0188(:1043): DRD2B1: idx0 = EU3(); EU3(idx2) */ + 0x6000000d, /* 018C(:1044): DRD2A: EU0=0 EU1=0 EU2=0 EU3=13 EXT init=0 WS=0 RS=0 */ + 0x01ccf89f, /* 0190(:1044): DRD2B1: var7 = EU3(); EU3(idx2) */ + 0x000001f8, /* 0194(:0): NOP */ + 0x8698801b, /* 0198(:1050): LCD: idx1 = var13; idx1 once var0; idx1 += inc3 */ + 0x7000000e, /* 019C(:1051): DRD2A: EU0=0 EU1=0 EU2=0 EU3=14 EXT MORE init=0 WS=0 RS=0 */ + 0x084cf25f, /* 01A0(:1051): DRD2B1: idx1 = EU3(); EU3(var9) */ + 0xd899037f, /* 01A4(:1052): LCDEXT: idx2 = idx1; idx2 > var13; idx2 += inc7 */ + 0x8019801b, /* 01A8(:1052): LCD: idx3 = var0; idx3 once var0; idx3 += inc3 */ + 0x040001f8, /* 01AC(:1053): DRD1A: FN=0 INT init=0 WS=0 RS=0 */ + 0x000001f8, /* 01B0(:0): NOP */ + 0x000001f8, /* 01B4(:0): NOP */ +}; +u32 MCD_SingleEu_TDT[]= +{ + 0x8218001b, /* 0000(:1248): LCD: idx0 = var4; idx0 once var0; idx0 += inc3 */ + 0x7000000d, /* 0004(:1249): DRD2A: EU0=0 EU1=0 EU2=0 EU3=13 EXT MORE init=0 WS=0 RS=0 */ + 0x080cf81f, /* 0008(:1249): DRD2B1: idx0 = EU3(); EU3(idx0) */ + 0x8218801b, /* 000C(:1250): LCD: idx1 = var4; idx1 once var0; idx1 += inc3 */ + 0x6000000e, /* 0010(:1251): DRD2A: EU0=0 EU1=0 EU2=0 EU3=14 EXT init=0 WS=0 RS=0 */ + 0x084cf85f, /* 0014(:1251): DRD2B1: idx1 = EU3(); EU3(idx1) */ + 0x000001f8, /* 0018(:0): NOP */ + 0x8318001b, /* 001C(:1255): LCD: idx0 = var6; idx0 once var0; idx0 += inc3 */ + 0x7000000d, /* 0020(:1256): DRD2A: EU0=0 EU1=0 EU2=0 EU3=13 EXT MORE init=0 WS=0 RS=0 */ + 0x014cf81f, /* 0024(:1256): DRD2B1: var5 = EU3(); EU3(idx0) */ + 0x6000000e, /* 0028(:1257): DRD2A: EU0=0 EU1=0 EU2=0 EU3=14 EXT init=0 WS=0 RS=0 */ + 0x01ccf81f, /* 002C(:1257): DRD2B1: var7 = EU3(); EU3(idx0) */ + 0x8498001b, /* 0030(:1260): LCD: idx0 = var9; idx0 once var0; idx0 += inc3 */ + 0x7000000f, /* 0034(:1261): DRD2A: EU0=0 EU1=0 EU2=0 EU3=15 EXT MORE init=0 WS=0 RS=0 */ + 0x080cf19f, /* 0038(:1261): DRD2B1: idx0 = EU3(); EU3(var6) */ + 0xd81882a4, /* 003C(:1262): LCDEXT: idx1 = idx0; idx1 >= var10; idx1 += inc4 */ + 0x8019001b, /* 0040(:1262): LCD: idx2 = var0; idx2 once var0; idx2 += inc3 */ + 0x60000003, /* 0044(:1263): DRD2A: EU0=0 EU1=0 EU2=0 EU3=3 EXT init=0 WS=0 RS=0 */ + 0x2c97c7df, /* 0048(:1263): DRD2B2: EU3(var9) */ + 0xd818826d, /* 004C(:1264): LCDEXT: idx1 = idx0; idx1 == var9; idx1 += inc5 */ + 0x8019001b, /* 0050(:1264): LCD: idx2 = var0; idx2 once var0; idx2 += inc3 */ + 0x60000003, /* 0054(:1265): DRD2A: EU0=0 EU1=0 EU2=0 EU3=3 EXT init=0 WS=0 RS=0 */ + 0x2c17c7df, /* 0058(:1265): DRD2B2: EU3(var1) */ + 0x000001f8, /* 005C(:0): NOP */ + 0xc282e01b, /* 0060(:1268): LCDEXT: idx0 = var5, idx1 = var5; ; idx0 += inc3, idx1 += inc3 */ + 0xc002a25e, /* 0064(:1268): LCDEXT: idx2 = var0, idx3 = var5; idx3 == var9; idx2 += inc3, idx3 += inc6 */ + 0x811a601b, /* 0068(:1269): LCD: idx4 = var2; ; idx4 += inc3 */ + 0xc184a102, /* 006C(:1272): LCDEXT: idx5 = var3, idx6 = var9; idx6 < var4; idx5 += inc0, idx6 += inc2 */ + 0x841be009, /* 0070(:1272): LCD: idx7 = var8; ; idx7 += inc1 */ + 0x63fe0000, /* 0074(:1275): DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 EXT init=31 WS=3 RS=3 */ + 0x0d4cfddf, /* 0078(:1275): DRD2B1: *idx5 = EU3(); EU3(*idx7) */ + 0xda9b001b, /* 007C(:1277): LCDEXT: idx5 = idx5, idx6 = idx6; idx5 once var0; idx5 += inc3, idx6 += inc3 */ + 0x9b9be01b, /* 0080(:1277): LCD: idx7 = idx7; ; idx7 += inc3 */ + 0x70000002, /* 0084(:1279): DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */ + 0x004cf99f, /* 0088(:1279): DRD2B1: var1 = EU3(); EU3(idx6) */ + 0x70000006, /* 008C(:1280): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */ + 0x088cf88b, /* 0090(:1280): DRD2B1: idx2 = EU3(); EU3(idx2,var11) */ + 0x1000cb28, /* 0094(:1281): DRD1A: *idx2 = idx5; FN=0 MORE init=0 WS=0 RS=0 */ + 0x70000006, /* 0098(:1282): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */ + 0x088cf88b, /* 009C(:1282): DRD2B1: idx2 = EU3(); EU3(idx2,var11) */ + 0x1000cb30, /* 00A0(:1283): DRD1A: *idx2 = idx6; FN=0 MORE init=0 WS=0 RS=0 */ + 0x70000006, /* 00A4(:1284): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */ + 0x088cf88b, /* 00A8(:1284): DRD2B1: idx2 = EU3(); EU3(idx2,var11) */ + 0x0000cb38, /* 00AC(:1285): DRD1A: *idx2 = idx7; FN=0 init=0 WS=0 RS=0 */ + 0x000001f8, /* 00B0(:0): NOP */ + 0xc282e01b, /* 00B4(:1289): LCDEXT: idx0 = var5, idx1 = var5; ; idx0 += inc3, idx1 += inc3 */ + 0xc002a31e, /* 00B8(:1289): LCDEXT: idx2 = var0, idx3 = var5; idx3 == var12; idx2 += inc3, idx3 += inc6 */ + 0x811a601b, /* 00BC(:1290): LCD: idx4 = var2; ; idx4 += inc3 */ + 0xda9b001b, /* 00C0(:1293): LCDEXT: idx5 = idx5, idx6 = idx6; idx5 once var0; idx5 += inc3, idx6 += inc3 */ + 0x9b9be01b, /* 00C4(:1293): LCD: idx7 = idx7; ; idx7 += inc3 */ + 0x0000d3a0, /* 00C8(:1294): DRD1A: *idx4; FN=0 init=0 WS=0 RS=0 */ + 0xc184a102, /* 00CC(:1296): LCDEXT: idx5 = var3, idx6 = var9; idx6 < var4; idx5 += inc0, idx6 += inc2 */ + 0x841be009, /* 00D0(:1296): LCD: idx7 = var8; ; idx7 += inc1 */ + 0x6bfe0000, /* 00D4(:1299): DRD2A: EU0=0 EU1=0 EU2=0 EU3=0 TFD EXT init=31 WS=3 RS=3 */ + 0x0d4cfddf, /* 00D8(:1299): DRD2B1: *idx5 = EU3(); EU3(*idx7) */ + 0xda9b001b, /* 00DC(:1301): LCDEXT: idx5 = idx5, idx6 = idx6; idx5 once var0; idx5 += inc3, idx6 += inc3 */ + 0x9b9be01b, /* 00E0(:1301): LCD: idx7 = idx7; ; idx7 += inc3 */ + 0x70000002, /* 00E4(:1303): DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT MORE init=0 WS=0 RS=0 */ + 0x004cf99f, /* 00E8(:1303): DRD2B1: var1 = EU3(); EU3(idx6) */ + 0x70000006, /* 00EC(:1304): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */ + 0x088cf88b, /* 00F0(:1304): DRD2B1: idx2 = EU3(); EU3(idx2,var11) */ + 0x1000cb28, /* 00F4(:1305): DRD1A: *idx2 = idx5; FN=0 MORE init=0 WS=0 RS=0 */ + 0x70000006, /* 00F8(:1306): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */ + 0x088cf88b, /* 00FC(:1306): DRD2B1: idx2 = EU3(); EU3(idx2,var11) */ + 0x1000cb30, /* 0100(:1307): DRD1A: *idx2 = idx6; FN=0 MORE init=0 WS=0 RS=0 */ + 0x70000006, /* 0104(:1308): DRD2A: EU0=0 EU1=0 EU2=0 EU3=6 EXT MORE init=0 WS=0 RS=0 */ + 0x088cf88b, /* 0108(:1308): DRD2B1: idx2 = EU3(); EU3(idx2,var11) */ + 0x0000cb38, /* 010C(:1309): DRD1A: *idx2 = idx7; FN=0 init=0 WS=0 RS=0 */ + 0x000001f8, /* 0110(:0): NOP */ + 0x8144801c, /* 0114(:1312): LCD: idx0 = var2 + var9 + 4; idx0 once var0; idx0 += inc3 */ + 0x0000c008, /* 0118(:1313): DRD1A: *idx0 = var1; FN=0 init=0 WS=0 RS=0 */ + 0xc398027f, /* 011C(:1315): LCDEXT: idx0 = var7; idx0 > var9; idx0 += inc7 */ + 0x8018801b, /* 0120(:1315): LCD: idx1 = var0; idx1 once var0; idx1 += inc3 */ + 0x040001f8, /* 0124(:1316): DRD1A: FN=0 INT init=0 WS=0 RS=0 */ +}; +#endif +u32 MCD_ENetRcv_TDT[]= +{ + 0x80004000, /* 0000(:1389): LCDEXT: idx0 = 0x00000000; ; */ + 0x81988000, /* 0004(:1389): LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */ + 0x10000788, /* 0008(:1390): DRD1A: var1 = *idx1; FN=0 MORE init=0 WS=0 RS=0 */ + 0x6000000a, /* 000C(:1391): DRD2A: EU0=0 EU1=0 EU2=0 EU3=10 EXT init=0 WS=0 RS=0 */ + 0x080cf05f, /* 0010(:1391): DRD2B1: idx0 = EU3(); EU3(var1) */ + 0x98180209, /* 0014(:1394): LCD: idx0 = idx0; idx0 != var8; idx0 += inc1 */ + 0x81c40004, /* 0018(:1396): LCD: idx1 = var3 + var8 + 4; idx1 once var0; idx1 += inc0 */ + 0x7000000e, /* 001C(:1397): DRD2A: EU0=0 EU1=0 EU2=0 EU3=14 EXT MORE init=0 WS=0 RS=0 */ + 0x010cf05f, /* 0020(:1397): DRD2B1: var4 = EU3(); EU3(var1) */ + 0x7000000c, /* 0024(:1398): DRD2A: EU0=0 EU1=0 EU2=0 EU3=12 EXT MORE init=0 WS=0 RS=0 */ + 0x01ccf05f, /* 0028(:1398): DRD2B1: var7 = EU3(); EU3(var1) */ + 0x70000004, /* 002C(:1399): DRD2A: EU0=0 EU1=0 EU2=0 EU3=4 EXT MORE init=0 WS=0 RS=0 */ + 0x014cf049, /* 0030(:1399): DRD2B1: var5 = EU3(); EU3(var1,var9) */ + 0x70000004, /* 0034(:1400): DRD2A: EU0=0 EU1=0 EU2=0 EU3=4 EXT MORE init=0 WS=0 RS=0 */ + 0x004cf04a, /* 0038(:1400): DRD2B1: var1 = EU3(); EU3(var1,var10) */ + 0x00000b88, /* 003C(:1403): DRD1A: var2 = *idx1; FN=0 init=0 WS=0 RS=0 */ + 0xc4030150, /* 0040(:1406): LCDEXT: idx1 = var8, idx2 = var6; idx1 < var5; idx1 += inc2, idx2 += inc0 */ + 0x8119e012, /* 0044(:1406): LCD: idx3 = var2; ; idx3 += inc2 */ + 0x03e0cf90, /* 0048(:1409): DRD1A: *idx3 = *idx2; FN=0 init=31 WS=0 RS=0 */ + 0x81188000, /* 004C(:1412): LCD: idx1 = var2; idx1 once var0; idx1 += inc0 */ + 0x000ac788, /* 0050(:1413): DRD1A: *idx1 = *idx1; FN=0 init=0 WS=1 RS=1 */ + 0xc4030000, /* 0054(:1415): LCDEXT: idx1 = var8, idx2 = var6; idx1 once var0; idx1 += inc0, idx2 += inc0 */ + 0x8199e000, /* 0058(:1415): LCD: idx3 = var3; ; idx3 += inc0 */ + 0x70000004, /* 005C(:1421): DRD2A: EU0=0 EU1=0 EU2=0 EU3=4 EXT MORE init=0 WS=0 RS=0 */ + 0x084cfc8b, /* 0060(:1421): DRD2B1: idx1 = EU3(); EU3(*idx2,var11) */ + 0x60000005, /* 0064(:1422): DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 EXT init=0 WS=0 RS=0 */ + 0x0cccf841, /* 0068(:1422): DRD2B1: *idx3 = EU3(); EU3(idx1,var1) */ + 0x81c60000, /* 006C(:1428): LCD: idx1 = var3 + var12; idx1 once var0; idx1 += inc0 */ + 0xc399021b, /* 0070(:1430): LCDEXT: idx2 = var7; idx2 > var8; idx2 += inc3 */ + 0x80198000, /* 0074(:1430): LCD: idx3 = var0; idx3 once var0; idx3 += inc0 */ + 0x00008400, /* 0078(:1431): DRD1A: idx1 = var0; FN=0 init=0 WS=0 RS=0 */ + 0x00000f08, /* 007C(:1432): DRD1A: var3 = idx1; FN=0 init=0 WS=0 RS=0 */ + 0x81988000, /* 0080(:1435): LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */ + 0x10000788, /* 0084(:1436): DRD1A: var1 = *idx1; FN=0 MORE init=0 WS=0 RS=0 */ + 0x6000000a, /* 0088(:1437): DRD2A: EU0=0 EU1=0 EU2=0 EU3=10 EXT init=0 WS=0 RS=0 */ + 0x080cf05f, /* 008C(:1437): DRD2B1: idx0 = EU3(); EU3(var1) */ + 0xc2188209, /* 0090(:1440): LCDEXT: idx1 = var4; idx1 != var8; idx1 += inc1 */ + 0x80190000, /* 0094(:1440): LCD: idx2 = var0; idx2 once var0; idx2 += inc0 */ + 0x040001f8, /* 0098(:1441): DRD1A: FN=0 INT init=0 WS=0 RS=0 */ + 0x000001f8, /* 009C(:0): NOP */ +}; +u32 MCD_ENetXmit_TDT[]= +{ + 0x80004000, /* 0000(:1516): LCDEXT: idx0 = 0x00000000; ; */ + 0x81988000, /* 0004(:1516): LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */ + 0x10000788, /* 0008(:1517): DRD1A: var1 = *idx1; FN=0 MORE init=0 WS=0 RS=0 */ + 0x6000000a, /* 000C(:1518): DRD2A: EU0=0 EU1=0 EU2=0 EU3=10 EXT init=0 WS=0 RS=0 */ + 0x080cf05f, /* 0010(:1518): DRD2B1: idx0 = EU3(); EU3(var1) */ + 0x98180309, /* 0014(:1521): LCD: idx0 = idx0; idx0 != var12; idx0 += inc1 */ + 0x80004003, /* 0018(:1523): LCDEXT: idx1 = 0x00000003; ; */ + 0x81c60004, /* 001C(:1523): LCD: idx2 = var3 + var12 + 4; idx2 once var0; idx2 += inc0 */ + 0x7000000e, /* 0020(:1524): DRD2A: EU0=0 EU1=0 EU2=0 EU3=14 EXT MORE init=0 WS=0 RS=0 */ + 0x014cf05f, /* 0024(:1524): DRD2B1: var5 = EU3(); EU3(var1) */ + 0x7000000c, /* 0028(:1525): DRD2A: EU0=0 EU1=0 EU2=0 EU3=12 EXT MORE init=0 WS=0 RS=0 */ + 0x028cf05f, /* 002C(:1525): DRD2B1: var10 = EU3(); EU3(var1) */ + 0x7000000d, /* 0030(:1526): DRD2A: EU0=0 EU1=0 EU2=0 EU3=13 EXT MORE init=0 WS=0 RS=0 */ + 0x018cf05f, /* 0034(:1526): DRD2B1: var6 = EU3(); EU3(var1) */ + 0x70000004, /* 0038(:1527): DRD2A: EU0=0 EU1=0 EU2=0 EU3=4 EXT MORE init=0 WS=0 RS=0 */ + 0x01ccf04d, /* 003C(:1527): DRD2B1: var7 = EU3(); EU3(var1,var13) */ + 0x10000b90, /* 0040(:1528): DRD1A: var2 = *idx2; FN=0 MORE init=0 WS=0 RS=0 */ + 0x60000004, /* 0044(:1529): DRD2A: EU0=0 EU1=0 EU2=0 EU3=4 EXT init=0 WS=0 RS=0 */ + 0x020cf0a1, /* 0048(:1529): DRD2B1: var8 = EU3(); EU3(var2,idx1) */ + 0xc3188312, /* 004C(:1532): LCDEXT: idx1 = var6; idx1 > var12; idx1 += inc2 */ + 0x83c70000, /* 0050(:1532): LCD: idx2 = var7 + var14; idx2 once var0; idx2 += inc0 */ + 0x00001f10, /* 0054(:1533): DRD1A: var7 = idx2; FN=0 init=0 WS=0 RS=0 */ + 0xc583a3c3, /* 0058(:1535): LCDEXT: idx1 = var11, idx2 = var7; idx2 >= var15; idx1 += inc0, idx2 += inc3 */ + 0x81042325, /* 005C(:1535): LCD: idx3 = var2, idx4 = var8; idx4 == var12; idx3 += inc4, idx4 += inc5 */ + 0x03e0c798, /* 0060(:1540): DRD1A: *idx1 = *idx3; FN=0 init=31 WS=0 RS=0 */ + 0xd8990000, /* 0064(:1543): LCDEXT: idx1 = idx1, idx2 = idx2; idx1 once var0; idx1 += inc0, idx2 += inc0 */ + 0x9999e000, /* 0068(:1543): LCD: idx3 = idx3; ; idx3 += inc0 */ + 0x000acf98, /* 006C(:1544): DRD1A: *idx3 = *idx3; FN=0 init=0 WS=1 RS=1 */ + 0xd8992306, /* 0070(:1546): LCDEXT: idx1 = idx1, idx2 = idx2; idx2 > var12; idx1 += inc0, idx2 += inc6 */ + 0x9999e03f, /* 0074(:1546): LCD: idx3 = idx3; ; idx3 += inc7 */ + 0x03eac798, /* 0078(:1549): DRD1A: *idx1 = *idx3; FN=0 init=31 WS=1 RS=1 */ + 0xd8990000, /* 007C(:1552): LCDEXT: idx1 = idx1, idx2 = idx2; idx1 once var0; idx1 += inc0, idx2 += inc0 */ + 0x9999e000, /* 0080(:1552): LCD: idx3 = idx3; ; idx3 += inc0 */ + 0x000acf98, /* 0084(:1553): DRD1A: *idx3 = *idx3; FN=0 init=0 WS=1 RS=1 */ + 0xd8990000, /* 0088(:1555): LCDEXT: idx1 = idx1, idx2 = idx2; idx1 once var0; idx1 += inc0, idx2 += inc0 */ + 0x99832302, /* 008C(:1555): LCD: idx3 = idx3, idx4 = var6; idx4 > var12; idx3 += inc0, idx4 += inc2 */ + 0x0beac798, /* 0090(:1558): DRD1A: *idx1 = *idx3; FN=0 TFD init=31 WS=1 RS=1 */ + 0x81988000, /* 0094(:1560): LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */ + 0x6000000b, /* 0098(:1561): DRD2A: EU0=0 EU1=0 EU2=0 EU3=11 EXT init=0 WS=0 RS=0 */ + 0x0c4cfc5f, /* 009C(:1561): DRD2B1: *idx1 = EU3(); EU3(*idx1) */ + 0x81c80000, /* 00A0(:1563): LCD: idx1 = var3 + var16; idx1 once var0; idx1 += inc0 */ + 0xc5190312, /* 00A4(:1565): LCDEXT: idx2 = var10; idx2 > var12; idx2 += inc2 */ + 0x80198000, /* 00A8(:1565): LCD: idx3 = var0; idx3 once var0; idx3 += inc0 */ + 0x00008400, /* 00AC(:1566): DRD1A: idx1 = var0; FN=0 init=0 WS=0 RS=0 */ + 0x00000f08, /* 00B0(:1567): DRD1A: var3 = idx1; FN=0 init=0 WS=0 RS=0 */ + 0x81988000, /* 00B4(:1570): LCD: idx1 = var3; idx1 once var0; idx1 += inc0 */ + 0x10000788, /* 00B8(:1571): DRD1A: var1 = *idx1; FN=0 MORE init=0 WS=0 RS=0 */ + 0x6000000a, /* 00BC(:1572): DRD2A: EU0=0 EU1=0 EU2=0 EU3=10 EXT init=0 WS=0 RS=0 */ + 0x080cf05f, /* 00C0(:1572): DRD2B1: idx0 = EU3(); EU3(var1) */ + 0xc2988309, /* 00C4(:1575): LCDEXT: idx1 = var5; idx1 != var12; idx1 += inc1 */ + 0x80190000, /* 00C8(:1575): LCD: idx2 = var0; idx2 once var0; idx2 += inc0 */ + 0x040001f8, /* 00CC(:1576): DRD1A: FN=0 INT init=0 WS=0 RS=0 */ + 0x000001f8, /* 00D0(:0): NOP */ +}; + +#ifdef MCD_INCLUDE_EU +MCD_bufDesc MCD_singleBufDescs[NCHANNELS]; +#endif diff --git a/arch/m68k/mach-mcfv4e/mcdapi/MCD_tasksInit.c b/arch/m68k/mach-mcfv4e/mcdapi/MCD_tasksInit.c new file mode 100644 index 0000000000..14104f7185 --- /dev/null +++ b/arch/m68k/mach-mcfv4e/mcdapi/MCD_tasksInit.c @@ -0,0 +1,225 @@ +/* + * File: MCD_tasksInit.c + * Purpose: Functions for initializing variable tables of different + * types of tasks. + * + * Notes: + */ + +/* + * Do not edit! + */ + +#include +#include + +extern dmaRegs *MCD_dmaBar; + + +/* + * Task 0 + */ + +void MCD_startDmaChainNoEu(int *currBD, short srcIncr, short destIncr, int xferSize, short xferSizeIncr, int *cSave, volatile TaskTableEntry *taskTable, int channel) +{ + + MCD_SET_VAR(taskTable+channel, 2, (u32)currBD); /* var[2] */ + MCD_SET_VAR(taskTable+channel, 25, (u32)(0xe000 << 16) | (0xffff & srcIncr)); /* inc[1] */ + MCD_SET_VAR(taskTable+channel, 24, (u32)(0xe000 << 16) | (0xffff & destIncr)); /* inc[0] */ + MCD_SET_VAR(taskTable+channel, 11, (u32)xferSize); /* var[11] */ + MCD_SET_VAR(taskTable+channel, 26, (u32)(0x2000 << 16) | (0xffff & xferSizeIncr)); /* inc[2] */ + MCD_SET_VAR(taskTable+channel, 0, (u32)cSave); /* var[0] */ + MCD_SET_VAR(taskTable+channel, 1, (u32)0x00000000); /* var[1] */ + MCD_SET_VAR(taskTable+channel, 3, (u32)0x00000000); /* var[3] */ + MCD_SET_VAR(taskTable+channel, 4, (u32)0x00000000); /* var[4] */ + MCD_SET_VAR(taskTable+channel, 5, (u32)0x00000000); /* var[5] */ + MCD_SET_VAR(taskTable+channel, 6, (u32)0x00000000); /* var[6] */ + MCD_SET_VAR(taskTable+channel, 7, (u32)0x00000000); /* var[7] */ + MCD_SET_VAR(taskTable+channel, 8, (u32)0x00000000); /* var[8] */ + MCD_SET_VAR(taskTable+channel, 9, (u32)0x00000000); /* var[9] */ + MCD_SET_VAR(taskTable+channel, 10, (u32)0x00000000); /* var[10] */ + MCD_SET_VAR(taskTable+channel, 12, (u32)0x00000000); /* var[12] */ + MCD_SET_VAR(taskTable+channel, 13, (u32)0x80000000); /* var[13] */ + MCD_SET_VAR(taskTable+channel, 14, (u32)0x00000010); /* var[14] */ + MCD_SET_VAR(taskTable+channel, 15, (u32)0x00000004); /* var[15] */ + MCD_SET_VAR(taskTable+channel, 16, (u32)0x08000000); /* var[16] */ + MCD_SET_VAR(taskTable+channel, 27, (u32)0x00000000); /* inc[3] */ + MCD_SET_VAR(taskTable+channel, 28, (u32)0x80000000); /* inc[4] */ + MCD_SET_VAR(taskTable+channel, 29, (u32)0x80000001); /* inc[5] */ + MCD_SET_VAR(taskTable+channel, 30, (u32)0x40000000); /* inc[6] */ + + /* Set the task's Enable bit in its Task Control Register */ + MCD_dmaBar->taskControl[channel] |= (u16)0x8000; +} + + +/* + * Task 1 + */ + +void MCD_startDmaSingleNoEu(char *srcAddr, short srcIncr, char *destAddr, short destIncr, int dmaSize, short xferSizeIncr, int flags, int *currBD, int *cSave, volatile TaskTableEntry *taskTable, int channel) +{ + + MCD_SET_VAR(taskTable+channel, 7, (u32)srcAddr); /* var[7] */ + MCD_SET_VAR(taskTable+channel, 25, (u32)(0xe000 << 16) | (0xffff & srcIncr)); /* inc[1] */ + MCD_SET_VAR(taskTable+channel, 2, (u32)destAddr); /* var[2] */ + MCD_SET_VAR(taskTable+channel, 24, (u32)(0xe000 << 16) | (0xffff & destIncr)); /* inc[0] */ + MCD_SET_VAR(taskTable+channel, 3, (u32)dmaSize); /* var[3] */ + MCD_SET_VAR(taskTable+channel, 26, (u32)(0x2000 << 16) | (0xffff & xferSizeIncr)); /* inc[2] */ + MCD_SET_VAR(taskTable+channel, 5, (u32)flags); /* var[5] */ + MCD_SET_VAR(taskTable+channel, 1, (u32)currBD); /* var[1] */ + MCD_SET_VAR(taskTable+channel, 0, (u32)cSave); /* var[0] */ + MCD_SET_VAR(taskTable+channel, 4, (u32)0x00000000); /* var[4] */ + MCD_SET_VAR(taskTable+channel, 6, (u32)0x00000000); /* var[6] */ + MCD_SET_VAR(taskTable+channel, 8, (u32)0x00000000); /* var[8] */ + MCD_SET_VAR(taskTable+channel, 9, (u32)0x00000004); /* var[9] */ + MCD_SET_VAR(taskTable+channel, 10, (u32)0x08000000); /* var[10] */ + MCD_SET_VAR(taskTable+channel, 27, (u32)0x00000000); /* inc[3] */ + MCD_SET_VAR(taskTable+channel, 28, (u32)0x80000001); /* inc[4] */ + MCD_SET_VAR(taskTable+channel, 29, (u32)0x40000000); /* inc[5] */ + + /* Set the task's Enable bit in its Task Control Register */ + MCD_dmaBar->taskControl[channel] |= (u16)0x8000; +} + + +/* + * Task 2 + */ + +void MCD_startDmaChainEu(int *currBD, short srcIncr, short destIncr, int xferSize, short xferSizeIncr, int *cSave, volatile TaskTableEntry *taskTable, int channel) +{ + + MCD_SET_VAR(taskTable+channel, 3, (u32)currBD); /* var[3] */ + MCD_SET_VAR(taskTable+channel, 25, (u32)(0xe000 << 16) | (0xffff & srcIncr)); /* inc[1] */ + MCD_SET_VAR(taskTable+channel, 24, (u32)(0xe000 << 16) | (0xffff & destIncr)); /* inc[0] */ + MCD_SET_VAR(taskTable+channel, 12, (u32)xferSize); /* var[12] */ + MCD_SET_VAR(taskTable+channel, 26, (u32)(0x2000 << 16) | (0xffff & xferSizeIncr)); /* inc[2] */ + MCD_SET_VAR(taskTable+channel, 0, (u32)cSave); /* var[0] */ + MCD_SET_VAR(taskTable+channel, 1, (u32)0x00000000); /* var[1] */ + MCD_SET_VAR(taskTable+channel, 2, (u32)0x00000000); /* var[2] */ + MCD_SET_VAR(taskTable+channel, 4, (u32)0x00000000); /* var[4] */ + MCD_SET_VAR(taskTable+channel, 5, (u32)0x00000000); /* var[5] */ + MCD_SET_VAR(taskTable+channel, 6, (u32)0x00000000); /* var[6] */ + MCD_SET_VAR(taskTable+channel, 7, (u32)0x00000000); /* var[7] */ + MCD_SET_VAR(taskTable+channel, 8, (u32)0x00000000); /* var[8] */ + MCD_SET_VAR(taskTable+channel, 9, (u32)0x00000000); /* var[9] */ + MCD_SET_VAR(taskTable+channel, 10, (u32)0x00000000); /* var[10] */ + MCD_SET_VAR(taskTable+channel, 11, (u32)0x00000000); /* var[11] */ + MCD_SET_VAR(taskTable+channel, 13, (u32)0x00000000); /* var[13] */ + MCD_SET_VAR(taskTable+channel, 14, (u32)0x80000000); /* var[14] */ + MCD_SET_VAR(taskTable+channel, 15, (u32)0x00000010); /* var[15] */ + MCD_SET_VAR(taskTable+channel, 16, (u32)0x00000001); /* var[16] */ + MCD_SET_VAR(taskTable+channel, 17, (u32)0x00000004); /* var[17] */ + MCD_SET_VAR(taskTable+channel, 18, (u32)0x08000000); /* var[18] */ + MCD_SET_VAR(taskTable+channel, 27, (u32)0x00000000); /* inc[3] */ + MCD_SET_VAR(taskTable+channel, 28, (u32)0x80000000); /* inc[4] */ + MCD_SET_VAR(taskTable+channel, 29, (u32)0xc0000000); /* inc[5] */ + MCD_SET_VAR(taskTable+channel, 30, (u32)0x80000001); /* inc[6] */ + MCD_SET_VAR(taskTable+channel, 31, (u32)0x40000000); /* inc[7] */ + + /* Set the task's Enable bit in its Task Control Register */ + MCD_dmaBar->taskControl[channel] |= (u16)0x8000; +} + + +/* + * Task 3 + */ + +void MCD_startDmaSingleEu(char *srcAddr, short srcIncr, char *destAddr, short destIncr, int dmaSize, short xferSizeIncr, int flags, int *currBD, int *cSave, volatile TaskTableEntry *taskTable, int channel) +{ + + MCD_SET_VAR(taskTable+channel, 8, (u32)srcAddr); /* var[8] */ + MCD_SET_VAR(taskTable+channel, 25, (u32)(0xe000 << 16) | (0xffff & srcIncr)); /* inc[1] */ + MCD_SET_VAR(taskTable+channel, 3, (u32)destAddr); /* var[3] */ + MCD_SET_VAR(taskTable+channel, 24, (u32)(0xe000 << 16) | (0xffff & destIncr)); /* inc[0] */ + MCD_SET_VAR(taskTable+channel, 4, (u32)dmaSize); /* var[4] */ + MCD_SET_VAR(taskTable+channel, 26, (u32)(0x2000 << 16) | (0xffff & xferSizeIncr)); /* inc[2] */ + MCD_SET_VAR(taskTable+channel, 6, (u32)flags); /* var[6] */ + MCD_SET_VAR(taskTable+channel, 2, (u32)currBD); /* var[2] */ + MCD_SET_VAR(taskTable+channel, 0, (u32)cSave); /* var[0] */ + MCD_SET_VAR(taskTable+channel, 1, (u32)0x00000000); /* var[1] */ + MCD_SET_VAR(taskTable+channel, 5, (u32)0x00000000); /* var[5] */ + MCD_SET_VAR(taskTable+channel, 7, (u32)0x00000000); /* var[7] */ + MCD_SET_VAR(taskTable+channel, 9, (u32)0x00000000); /* var[9] */ + MCD_SET_VAR(taskTable+channel, 10, (u32)0x00000001); /* var[10] */ + MCD_SET_VAR(taskTable+channel, 11, (u32)0x00000004); /* var[11] */ + MCD_SET_VAR(taskTable+channel, 12, (u32)0x08000000); /* var[12] */ + MCD_SET_VAR(taskTable+channel, 27, (u32)0x00000000); /* inc[3] */ + MCD_SET_VAR(taskTable+channel, 28, (u32)0xc0000000); /* inc[4] */ + MCD_SET_VAR(taskTable+channel, 29, (u32)0x80000000); /* inc[5] */ + MCD_SET_VAR(taskTable+channel, 30, (u32)0x80000001); /* inc[6] */ + MCD_SET_VAR(taskTable+channel, 31, (u32)0x40000000); /* inc[7] */ + + /* Set the task's Enable bit in its Task Control Register */ + MCD_dmaBar->taskControl[channel] |= (u16)0x8000; +} + + +/* + * Task 4 + */ + +void MCD_startDmaENetRcv(char *bDBase, char *currBD, char *rcvFifoPtr, volatile TaskTableEntry *taskTable, int channel) +{ + + MCD_SET_VAR(taskTable+channel, 0, (u32)bDBase); /* var[0] */ + MCD_SET_VAR(taskTable+channel, 3, (u32)currBD); /* var[3] */ + MCD_SET_VAR(taskTable+channel, 6, (u32)rcvFifoPtr); /* var[6] */ + MCD_SET_VAR(taskTable+channel, 1, (u32)0x00000000); /* var[1] */ + MCD_SET_VAR(taskTable+channel, 2, (u32)0x00000000); /* var[2] */ + MCD_SET_VAR(taskTable+channel, 4, (u32)0x00000000); /* var[4] */ + MCD_SET_VAR(taskTable+channel, 5, (u32)0x00000000); /* var[5] */ + MCD_SET_VAR(taskTable+channel, 7, (u32)0x00000000); /* var[7] */ + MCD_SET_VAR(taskTable+channel, 8, (u32)0x00000000); /* var[8] */ + MCD_SET_VAR(taskTable+channel, 9, (u32)0x0000ffff); /* var[9] */ + MCD_SET_VAR(taskTable+channel, 10, (u32)0x30000000); /* var[10] */ + MCD_SET_VAR(taskTable+channel, 11, (u32)0x0fffffff); /* var[11] */ + MCD_SET_VAR(taskTable+channel, 12, (u32)0x00000008); /* var[12] */ + MCD_SET_VAR(taskTable+channel, 24, (u32)0x00000000); /* inc[0] */ + MCD_SET_VAR(taskTable+channel, 25, (u32)0x60000000); /* inc[1] */ + MCD_SET_VAR(taskTable+channel, 26, (u32)0x20000004); /* inc[2] */ + MCD_SET_VAR(taskTable+channel, 27, (u32)0x40000000); /* inc[3] */ + + /* Set the task's Enable bit in its Task Control Register */ + MCD_dmaBar->taskControl[channel] |= (u16)0x8000; +} + + +/* + * Task 5 + */ + +void MCD_startDmaENetXmit(char *bDBase, char *currBD, char *xmitFifoPtr, volatile TaskTableEntry *taskTable, int channel) +{ + + MCD_SET_VAR(taskTable+channel, 0, (u32)bDBase); /* var[0] */ + MCD_SET_VAR(taskTable+channel, 3, (u32)currBD); /* var[3] */ + MCD_SET_VAR(taskTable+channel, 11, (u32)xmitFifoPtr); /* var[11] */ + MCD_SET_VAR(taskTable+channel, 1, (u32)0x00000000); /* var[1] */ + MCD_SET_VAR(taskTable+channel, 2, (u32)0x00000000); /* var[2] */ + MCD_SET_VAR(taskTable+channel, 4, (u32)0x00000000); /* var[4] */ + MCD_SET_VAR(taskTable+channel, 5, (u32)0x00000000); /* var[5] */ + MCD_SET_VAR(taskTable+channel, 6, (u32)0x00000000); /* var[6] */ + MCD_SET_VAR(taskTable+channel, 7, (u32)0x00000000); /* var[7] */ + MCD_SET_VAR(taskTable+channel, 8, (u32)0x00000000); /* var[8] */ + MCD_SET_VAR(taskTable+channel, 9, (u32)0x00000000); /* var[9] */ + MCD_SET_VAR(taskTable+channel, 10, (u32)0x00000000); /* var[10] */ + MCD_SET_VAR(taskTable+channel, 12, (u32)0x00000000); /* var[12] */ + MCD_SET_VAR(taskTable+channel, 13, (u32)0x0000ffff); /* var[13] */ + MCD_SET_VAR(taskTable+channel, 14, (u32)0xffffffff); /* var[14] */ + MCD_SET_VAR(taskTable+channel, 15, (u32)0x00000004); /* var[15] */ + MCD_SET_VAR(taskTable+channel, 16, (u32)0x00000008); /* var[16] */ + MCD_SET_VAR(taskTable+channel, 24, (u32)0x00000000); /* inc[0] */ + MCD_SET_VAR(taskTable+channel, 25, (u32)0x60000000); /* inc[1] */ + MCD_SET_VAR(taskTable+channel, 26, (u32)0x40000000); /* inc[2] */ + MCD_SET_VAR(taskTable+channel, 27, (u32)0xc000fffc); /* inc[3] */ + MCD_SET_VAR(taskTable+channel, 28, (u32)0xe0000004); /* inc[4] */ + MCD_SET_VAR(taskTable+channel, 29, (u32)0x80000000); /* inc[5] */ + MCD_SET_VAR(taskTable+channel, 30, (u32)0x4000ffff); /* inc[6] */ + MCD_SET_VAR(taskTable+channel, 31, (u32)0xe0000001); /* inc[7] */ + + /* Set the task's Enable bit in its Task Control Register */ + MCD_dmaBar->taskControl[channel] |= (u16)0x8000; +} diff --git a/arch/m68k/mach-mcfv4e/mcdapi/Makefile b/arch/m68k/mach-mcfv4e/mcdapi/Makefile new file mode 100644 index 0000000000..7e2d5ab466 --- /dev/null +++ b/arch/m68k/mach-mcfv4e/mcdapi/Makefile @@ -0,0 +1,26 @@ +# +# (C) Copyright 2007 Carsten Schlote +# See file CREDITS for list of people who contributed to this project. +# +# This file is part of U-Boot V2. +# +# U-Boot V2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# U-Boot V2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with U-Boot V2. If not, see . +# + +# +# FreeScale MultiDMA Library +# +obj-y += MCD_dmaApi.o MCD_tasks.o MCD_tasksInit.o + + diff --git a/arch/m68k/mach-mcfv4e/mcdapi/ReleaseNotes.txt b/arch/m68k/mach-mcfv4e/mcdapi/ReleaseNotes.txt new file mode 100644 index 0000000000..bc10e713f9 --- /dev/null +++ b/arch/m68k/mach-mcfv4e/mcdapi/ReleaseNotes.txt @@ -0,0 +1,27 @@ + +Multi-channel DMA API Release Notes + +Version 0.3 + +* MCD_INCLUDE_EU functionality supported(microcode changes for all tasks +except ethernet). +* Fixed bug when using MCD_END_FRAME which would cause the DMA to transfer +zero bytes and then complete. +* Code cleanup. + + +Version 0.2 (Slight Update) + +* Modified casts and task table implementations that were causing +warnings (and even errors on certain compilers) +* Cosmetic changes to clean up MCD_dmaApi.c and MCD_dma.h +* Fixed table declarations so that MCD_tasks.c will compile if + MCD_INCLUDE_EU is defined (Note: EU functionality still not supported) + +Version 0.1 (Initial release) + +Alpha version +MCD_INCLUDE_EU functionality not supported. +MCD_INCLUDE_JBIG not supported. + + diff --git a/arch/m68k/mach-mcfv4e/mcf_clocksource.c b/arch/m68k/mach-mcfv4e/mcf_clocksource.c new file mode 100644 index 0000000000..1278bf83ec --- /dev/null +++ b/arch/m68k/mach-mcfv4e/mcf_clocksource.c @@ -0,0 +1,138 @@ +/* + * Copyright (c) 2008 Carsten Schlote + * See file CREDITS for list of people who contributed to this project. + * + * This file is part of U-Boot V2. + * + * U-Boot V2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * U-Boot V2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with U-Boot V2. If not, see . + */ + +/** @file + * Implements the clocksource for Coldfire V4E + */ +#include +#include +#include +#include +#include +#include //FIXME - move to other file + +#ifdef CONFIG_USE_IRQ + +static uint32_t mcf_sltirq_hits; // FIXME: test code + +static int slt_timer_default_isr(void *not_used, void *t) +{ + struct mcf5xxx_slt *slt = MCF_SLT_Address(0); + if ( MCF_INTC_IPRH | MCF_INTC_IPRH_INT54 ) + { + if (slt->SSR & MCF_SLT_SSR_ST) + { + slt->SSR = 0UL + | MCF_SLT_SSR_ST; + } + mcf_sltirq_hits++; + return 1; + } + return 0; +} +#endif + + +static uint64_t mcf_clocksource_read(void) +{ + struct mcf5xxx_slt *slt = MCF_SLT_Address(0); + uint32_t sltcnt; + uint64_t rc = 0; + + if (slt->SSR & MCF_SLT_SSR_ST) + { +#ifndef CONFIG_USE_IRQ + slt->SSR = 0UL + | MCF_SLT_SSR_ST; +#endif + + rc = 0xffffffffULL + 1; + } + + sltcnt = 0xffffffffUL - slt->SCNT; + + rc += sltcnt; + + return rc; +} + + +static struct clocksource cs = { + .read = mcf_clocksource_read, + .mask = 0xffffffff, + .mult = 1, + .shift = 0, +}; + +static int clocksource_init (void) +{ + struct mcf5xxx_slt *slt = MCF_SLT_Address(0); + uint32_t sltclk = mcfv4e_get_bus_clk() * 1000000; + + /* Setup a slice timer terminal count */ + slt->STCNT = 0xffffffff; + + /* Reset status bits */ + slt->SSR = 0UL + | MCF_SLT_SSR_ST + | MCF_SLT_SSR_BE; + + /* Start timer to run continously */ + slt->SCR = 0UL + | MCF_SLT_SCR_TEN + | MCF_SLT_SCR_RUN + | MCF_SLT_SCR_IEN; // FIXME - add irq handler + + /* Setup up multiplier */ + cs.mult = clocksource_hz2mult(sltclk, cs.shift); + + /* + * Register the timer interrupt handler + */ + init_clock(&cs); + + return 0; +} + +core_initcall(clocksource_init); + +#ifdef CONFIG_USE_IRQ + +static int clocksource_irq_init(void) +{ + if (!mcf_interrupts_register_handler( + 118, // FIXME! + (int (*)(void*,void*))slt_timer_default_isr, + NULL, + NULL) + ) + { + return 1; + } + // Setup ICR + MCF_INTC_ICR54 = MCF_INTC_ICRn_IL(1) | MCF_INTC_ICRn_IP(0); + // Enable IRQ source + MCF_INTC_IMRH &= ~MCF_INTC_IMRH_INT_MASK54; + return 0; +} + +postcore_initcall(clocksource_irq_init); + +#endif diff --git a/arch/m68k/mach-mcfv4e/mcf_reset_cpu.c b/arch/m68k/mach-mcfv4e/mcf_reset_cpu.c new file mode 100644 index 0000000000..5a3368f901 --- /dev/null +++ b/arch/m68k/mach-mcfv4e/mcf_reset_cpu.c @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2008 Carsten Schlote + * See file CREDITS for list of people who contributed to this project. + * + * This file is part of U-Boot V2. + * + * U-Boot V2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * U-Boot V2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with U-Boot V2. If not, see . + */ + +/** @file + * Implements a watchdog triggered reset for V4e Coldfire cores + */ +#include +#include + +/** + * Reset the cpu by setting up the watchdog timer and let it time out + */ +void reset_cpu (ulong ignored) +{ + while ( ignored ) { ; }; + + /* Disable watchdog and set Time-Out field to minimum timeout value */ + MCF_GPT_GMS0 = 0; + MCF_GPT_GCIR0 = MCF_GPT_GCIR_PRE(1) | MCF_GPT_GCIR_CNT(0xffff); + + /* Enable watchdog */ + MCF_GPT_GMS0 = MCF_GPT_GMS_OCPW(0xA5) | MCF_GPT_GMS_WDEN | MCF_GPT_GMS_CE | MCF_GPT_GMS_TMS_GPIO; + + while (1); + /*NOTREACHED*/ +} +EXPORT_SYMBOL(reset_cpu); + diff --git a/arch/m68k/mach-mcfv4e/multichannel_dma.c b/arch/m68k/mach-mcfv4e/multichannel_dma.c new file mode 100644 index 0000000000..11aceeb9b9 --- /dev/null +++ b/arch/m68k/mach-mcfv4e/multichannel_dma.c @@ -0,0 +1,51 @@ +/* + * U-Boot Header File + * + * Generic Clocksource for V4E + * + * Copyright (c) 2007 Carsten Schlote + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +#include +#include +#include +#include +#include + + +static int mcdapi_init(void) +{ + /* + * Initialize the Multi-channel DMA + */ + MCD_initDma ((dmaRegs*)(__MBAR+0x8000), + (void *)CFG_SYS_SRAM_ADDRESS, + MCD_COMM_PREFETCH_EN | MCD_RELOC_TASKS); + + /* + * Enable interrupts in DMA and INTC + */ + dma_irq_enable(DMA_INTC_LVL, DMA_INTC_PRI); + + return 0; +} + +postcore_initcall(mcdapi_init); + diff --git a/arch/m68k/mach-mcfv4e/net/Makefile b/arch/m68k/mach-mcfv4e/net/Makefile new file mode 100644 index 0000000000..45badfaaac --- /dev/null +++ b/arch/m68k/mach-mcfv4e/net/Makefile @@ -0,0 +1,26 @@ +# +# (C) Copyright 2007 Carsten Schlote +# See file CREDITS for list of people who contributed to this project. +# +# This file is part of U-Boot V2. +# +# U-Boot V2 is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# U-Boot V2 is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with U-Boot V2. If not, see . +# + +# +# Support code for current FEC driver code - must be eliminated later... +# +obj-y += nbuf.o queue.o net.o + + diff --git a/arch/m68k/mach-mcfv4e/net/nbuf.c b/arch/m68k/mach-mcfv4e/net/nbuf.c new file mode 100644 index 0000000000..d7ae921bed --- /dev/null +++ b/arch/m68k/mach-mcfv4e/net/nbuf.c @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2008 Carsten Schlote + * See file CREDITS for list of people who contributed to this project. + * + * This file is part of U-Boot V2. + * + * U-Boot V2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * U-Boot V2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with U-Boot V2. If not, see . + */ + +/** @file + * Implementation of network buffer scheme. + * @todo Obsolete this file + */ +#include +#include +#include + +#include +#include + +#include + + +#define ASSERT(x) + +/** + * Queues used for network buffer storage + */ +QUEUE nbuf_queue[NBUF_MAXQ]; + +/* + * Some devices require line-aligned buffers. In order to accomplish + * this, the nbuf data is over-allocated and adjusted. The following + * array keeps track of the original data pointer returned by malloc + */ +ADDRESS unaligned_buffers[NBUF_MAX]; + +/** + * Initialize all the network buffer queues + * + * Return Value: + * 0 success + * 1 failure + */ +int +nbuf_init(void) +{ + int i; + NBUF *nbuf; + + for (i=0; idata = (uint8_t *)((uint32_t)(unaligned_buffers[i] + 15) & 0xFFFFFFF0); + if (!nbuf->data) + { + ASSERT(nbuf->data); + return 1; + } + + /* Initialize the network buffer */ + nbuf->offset = 0; + nbuf->length = 0; + + /* Add the network buffer to the free list */ + queue_add(&nbuf_queue[NBUF_FREE], (QNODE *)nbuf); + } + + #ifdef CONFIG_DRIVER_NET_MCF54XX_DEBUG + printf("NBUF allocation complete\n"); + nbuf_debug_dump(); + #endif + + return 0; +} +/** + * Return all the allocated memory to the heap + */ +void +nbuf_flush(void) +{ + NBUF *nbuf; + int i, level = asm_set_ipl(7); + int n = 0; + + for (i=0; ioffset = 0; + nbuf->length = NBUF_SZ; + queue_add(&nbuf_queue[NBUF_FREE],(QNODE *)nbuf); + + asm_set_ipl(level); +} +/** + * Remove a network buffer from the specified queue + * + * Parameters: + * q The index that identifies the queue to pull the buffer from + */ +NBUF * +nbuf_remove(int q) +{ + NBUF *nbuf; + int level = asm_set_ipl(7); + + nbuf = (NBUF *)queue_remove(&nbuf_queue[q]); + asm_set_ipl(level); + return nbuf; +} +/** + * Add a network buffer to the specified queue + * + * Parameters: + * q The index that identifies the queue to add the buffer to + */ +void +nbuf_add(int q, NBUF *nbuf) +{ + int level = asm_set_ipl(7); + queue_add(&nbuf_queue[q],(QNODE *)nbuf); + asm_set_ipl(level); +} +/** + * Put all the network buffers back into the free list + */ +void +nbuf_reset(void) +{ + NBUF *nbuf; + int i, level = asm_set_ipl(7); + + for (i=1; idata, + nbuf->offset, + nbuf->length); + nbuf = (NBUF *)nbuf->node.next; + } + } + + asm_set_ipl(level); +#endif +} diff --git a/arch/m68k/mach-mcfv4e/net/net.c b/arch/m68k/mach-mcfv4e/net/net.c new file mode 100644 index 0000000000..76e28531b6 --- /dev/null +++ b/arch/m68k/mach-mcfv4e/net/net.c @@ -0,0 +1,156 @@ +/* + * Copyright (c) 2008 Carsten Schlote + * See file CREDITS for list of people who contributed to this project. + * + * This file is part of U-Boot V2. + * + * U-Boot V2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * U-Boot V2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with U-Boot V2. If not, see . + */ + +/** @file + * Network initialization for MCF V4E FEC support code + * @todo Obsolete this file + */ +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include //FIXME - move to other file + +int netif_init(int channel) +{ + uint8_t* board_get_ethaddr(uint8_t*); + +#ifdef CONFIG_USE_IRQ + int vector; + int (*handler)(void *, void *); + + disable_interrupts(); + + /* + * Register the FEC0 interrupt handler + */ + handler = (channel == 0) ? fec0_interrupt_handler + : fec1_interrupt_handler; + vector = (channel == 0) ? 103 : 102; + + if (!mcf_interrupts_register_handler( + vector,handler, NULL,(void *)0xdeadbeef)) + { + printf("Error: Unable to register handler\n"); + return 0; + } + + /* + * Register the DMA interrupt handler + */ + handler = dma_interrupt_handler; + vector = 112; + + if (!mcf_interrupts_register_handler( + vector,handler, NULL,NULL)) + { + printf("Error: Unable to register handler\n"); + return 0; + } +#endif + /* + * Enable interrupts + */ + enable_interrupts(); + + return 1; +} + +int netif_setup(int channel) +{ + uint8_t mac[6]; + /* + * Get user programmed MAC address + */ +// board_get_ethaddr(mac); + + + /* + * Initialize the network interface structure + */ +// nif_init(&nif1); +// nif1.mtu = ETH_MTU; +// nif1.send = (DBUG_ETHERNET_PORT == 0) ? fec0_send : fec1_send; + + /* + * Initialize the dBUG Ethernet port + */ + fec_eth_setup(channel, /* Which FEC to use */ + FEC_MODE_MII, /* Use MII mode */ + FEC_MII_100BASE_TX, /* Allow 10 and 100Mbps */ + FEC_MII_FULL_DUPLEX, /* Allow Full and Half Duplex */ + mac); + + /* + * Copy the Ethernet address to the NIF structure + */ +// memcpy(nif1.hwa, mac, 6); + + #ifdef DEBUG + printf("Ethernet Address is %02X:%02X:%02X:%02X:%02X:%02X\n",\ + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); + #endif + + return 1; +} + +int netif_done(int channel) +{ + /* + * Download complete, clean up + */ +#ifdef CONFIG_USE_IRQ + int (*handler)(void *, void *); +#endif + /* + * Disable interrupts + */ + disable_interrupts(); + + /* + * Disable the Instruction Cache + */ + mcf5xxx_wr_cacr(MCF5XXX_CACR_ICINVA); + + /* + * Disable the dBUG Ethernet port + */ + fec_eth_stop(channel); + + /* + * Remove the interrupt handlers + */ +#ifdef CONFIG_USE_IRQ + handler = (channel == 0) ? fec0_interrupt_handler + : fec1_interrupt_handler; + mcf_interrupts_remove_handler(handler); + mcf_interrupts_remove_handler(dma_interrupt_handler); +#endif + return 1; +} + + diff --git a/arch/m68k/mach-mcfv4e/net/queue.c b/arch/m68k/mach-mcfv4e/net/queue.c new file mode 100644 index 0000000000..55f938af3e --- /dev/null +++ b/arch/m68k/mach-mcfv4e/net/queue.c @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2008 Carsten Schlote + * See file CREDITS for list of people who contributed to this project. + * + * This file is part of U-Boot V2. + * + * U-Boot V2 is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * U-Boot V2 is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with U-Boot V2. If not, see . + */ + +/** @file + * Implements a first in, first out linked list + * + * @note Simple selfcontaining basic code + * @todo Replace by u-boot standard list functions + */ +#include +#include + +/** Initialize the specified queue to an empty state + * + * @param[in] + * q Pointer to queue structure + */ +void queue_init(QUEUE *q) +{ + q->head = NULL; +} + +/** + * Check for an empty queue + * + * @param[in] q Pointer to queue structure + * @return + * 1 if Queue is empty + * 0 otherwise + */ +int +queue_isempty(QUEUE *q) +{ + return (q->head == NULL); +} + +/** + * Add an item to the end of the queue + * + * @param[in] q Pointer to queue structure + * @param[in] node New node to add to the queue + */ +void queue_add(QUEUE *q, QNODE *node) +{ + if (queue_isempty(q)) + { + q->head = q->tail = node; + } + else + { + q->tail->next = node; + q->tail = node; + } + + node->next = NULL; +} + +/** Remove and return first (oldest) entry from the specified queue + * + * @param[in] q Pointer to queue structure + * @return + * Node at head of queue - NULL if queue is empty + */ +QNODE* +queue_remove(QUEUE *q) +{ + QNODE *oldest; + + if (queue_isempty(q)) + return NULL; + + oldest = q->head; + q->head = oldest->next; + return oldest; +} + +/** Peek into the queue and return pointer to first (oldest) entry. + * + * The queue is not modified + * + * @param[in] q Pointer to queue structure + * @return + * Node at head of queue - NULL if queue is empty + */ +QNODE* +queue_peek(QUEUE *q) +{ + return q->head; +} + +/** Move entire contents of one queue to the other + * + * @param[in] src Pointer to source queue + * @param[in] dst Pointer to destination queue + */ +void +queue_move(QUEUE *dst, QUEUE *src) +{ + if (queue_isempty(src)) + return; + + if (queue_isempty(dst)) + dst->head = src->head; + else + dst->tail->next = src->head; + + dst->tail = src->tail; + src->head = NULL; + return; +} + -- cgit v1.2.3