From 8081df42a610445f1b7fc97ae38aea2c70e363aa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Fr=C3=B6schle?= Date: Fri, 26 Dec 2014 09:36:45 +0000 Subject: [PATCH] merged fixes from 0.8.6.1 (errornous skip of FPGA load) --- BaS_gcc/bas.lk.in | 382 ++++++++-------- BaS_gcc/net/fecbd.c | 194 ++++----- BaS_gcc/net/ip.c | 451 ++++++++++--------- BaS_gcc/net/udp.c | 182 ++++---- BaS_gcc/sys/exceptions.S | 910 ++++++++++++++++++++------------------- BaS_gcc/sys/init_fpga.c | 223 +++++----- 6 files changed, 1177 insertions(+), 1165 deletions(-) diff --git a/BaS_gcc/bas.lk.in b/BaS_gcc/bas.lk.in index 7e955c8..749104b 100644 --- a/BaS_gcc/bas.lk.in +++ b/BaS_gcc/bas.lk.in @@ -10,254 +10,256 @@ /* make bas_rom access flags rx if compiling to RAM */ #ifdef COMPILE_RAM -#define ROMFLAGS WX +#define ROMFLAGS WX #else -#define ROMFLAGS RX +#define ROMFLAGS RX #endif /* COMPILE_RAM */ MEMORY { bas_rom (ROMFLAGS) : ORIGIN = TARGET_ADDRESS, LENGTH = 0x00100000 /* - * target to copy BaS data segment to. 1M should be enough for now - */ + * target to copy BaS data segment to. 1M should be enough for now + */ bas_ram (WX) : ORIGIN = SDRAM_START + SDRAM_SIZE - 0x00200000, LENGTH = 0x00100000 /* - * driver_ram is an uncached, reserved memory area for drivers (e.g. USB) that need this type of memory - */ + * driver_ram is an uncached, reserved memory area for drivers (e.g. USB) that need this type of memory + */ driver_ram (WX) : ORIGIN = SDRAM_START + SDRAM_SIZE - 0x00100000, LENGTH = 0x00100000 } SECTIONS { - /* BaS in ROM */ - .text : - { - OBJDIR/startcf.o(.text) /* this one is the entry point so it must be the first */ + /* BaS in ROM */ + .text : + { + OBJDIR/startcf.o(.text) /* this one is the entry point so it must be the first */ - OBJDIR/sysinit.o(.text) - OBJDIR/fault_vectors.o(.text) + OBJDIR/sysinit.o(.text) + OBJDIR/fault_vectors.o(.text) #ifdef MACHINE_FIREBEE - OBJDIR/init_fpga.o(.text) + OBJDIR/init_fpga.o(.text) #endif /* MACHINE_FIREBEE */ - OBJDIR/wait.o(.text) - OBJDIR/exceptions.o(.text) - OBJDIR/driver_vec.o(.text) - OBJDIR/interrupts.o(.text) - OBJDIR/mmu.o(.text) + OBJDIR/wait.o(.text) + OBJDIR/exceptions.o(.text) + OBJDIR/driver_vec.o(.text) + OBJDIR/interrupts.o(.text) + OBJDIR/mmu.o(.text) - OBJDIR/BaS.o(.text) - OBJDIR/pci.o(.text) - OBJDIR/pci_wrappers.o(.text) - OBJDIR/usb.o(.text) - OBJDIR/driver_mem.o(.text) - OBJDIR/usb_hub.o(.text) - OBJDIR/usb_mouse.o(.text) - OBJDIR/usb_kbd.o(.text) - OBJDIR/ohci-hcd.o(.text) - OBJDIR/ehci-hcd.o(.text) - OBJDIR/wait.o(.text) + OBJDIR/BaS.o(.text) + OBJDIR/pci.o(.text) + OBJDIR/pci_wrappers.o(.text) + OBJDIR/usb.o(.text) + OBJDIR/driver_mem.o(.text) + OBJDIR/usb_hub.o(.text) + OBJDIR/usb_mouse.o(.text) + OBJDIR/usb_kbd.o(.text) + OBJDIR/ohci-hcd.o(.text) + OBJDIR/ehci-hcd.o(.text) + OBJDIR/wait.o(.text) - OBJDIR/nbuf.o(.text) - OBJDIR/net_timer.o(.text) - OBJDIR/queue.o(.text) - OBJDIR/nif.o(.text) - OBJDIR/fecbd.o(.text) - OBJDIR/fec.o(.text) - OBJDIR/am79c874.o(.text) - OBJDIR/bcm5222.o(.text) - OBJDIR/ip.o(.text) - OBJDIR/udp.o(text) - OBJDIR/bootp.o(text) - OBJDIR/tftp.o(text) - OBJDIR/arp.o(text) + OBJDIR/nbuf.o(.text) + OBJDIR/net_timer.o(.text) + OBJDIR/queue.o(.text) + OBJDIR/nif.o(.text) + OBJDIR/fecbd.o(.text) + OBJDIR/fec.o(.text) + OBJDIR/am79c874.o(.text) + OBJDIR/bcm5222.o(.text) + OBJDIR/ip.o(.text) + OBJDIR/udp.o(text) + OBJDIR/bootp.o(text) + OBJDIR/tftp.o(text) + OBJDIR/arp.o(text) - OBJDIR/unicode.o(.text) - OBJDIR/mmc.o(.text) - OBJDIR/ff.o(.text) - OBJDIR/sd_card.o(.text) - OBJDIR/s19reader.o(.text) - OBJDIR/bas_printf.o(.text) - OBJDIR/bas_string.o(.text) - OBJDIR/printf_helper.o(.text) - OBJDIR/cache.o(.text) - OBJDIR/dma.o(.text) - OBJDIR/MCD_dmaApi.o(.text) - OBJDIR/MCD_tasks.o(.text) - OBJDIR/MCD_tasksInit.o(.text) + OBJDIR/unicode.o(.text) + OBJDIR/mmc.o(.text) + OBJDIR/ff.o(.text) + OBJDIR/sd_card.o(.text) + OBJDIR/s19reader.o(.text) + OBJDIR/bas_printf.o(.text) + OBJDIR/bas_string.o(.text) + OBJDIR/printf_helper.o(.text) + OBJDIR/cache.o(.text) + OBJDIR/dma.o(.text) + OBJDIR/MCD_dmaApi.o(.text) + OBJDIR/MCD_tasks.o(.text) + OBJDIR/MCD_tasksInit.o(.text) - OBJDIR/video.o(.text) - OBJDIR/videl.o(.text) - OBJDIR/fbmem.o(.text) - OBJDIR/fbmon.o(.text) - OBJDIR/fbmodedb.o(.text) - OBJDIR/offscreen.o(.text) + OBJDIR/video.o(.text) + OBJDIR/videl.o(.text) + OBJDIR/fbmem.o(.text) + OBJDIR/fbmon.o(.text) + OBJDIR/fbmodedb.o(.text) + OBJDIR/offscreen.o(.text) - OBJDIR/x86decode.o(.text) - OBJDIR/x86ops.o(.text) - OBJDIR/x86ops2.o(.text) - OBJDIR/x86fpu.o(.text) - OBJDIR/x86sys.o(.text) - OBJDIR/x86biosemu.o(.text) - OBJDIR/x86debug.o(.text) - OBJDIR/x86prim_ops.o(.text) - OBJDIR/x86pcibios.o(.text) + OBJDIR/x86decode.o(.text) + OBJDIR/x86ops.o(.text) + OBJDIR/x86ops2.o(.text) + OBJDIR/x86fpu.o(.text) + OBJDIR/x86sys.o(.text) + OBJDIR/x86biosemu.o(.text) + OBJDIR/x86debug.o(.text) + OBJDIR/x86prim_ops.o(.text) + OBJDIR/x86pcibios.o(.text) - OBJDIR/radeon_base.o(.text) - OBJDIR/radeon_accel.o(.text) - OBJDIR/radeon_cursor.o(.text) - OBJDIR/radeon_monitor.o(.text) + OBJDIR/radeon_base.o(.text) + OBJDIR/radeon_accel.o(.text) + OBJDIR/radeon_cursor.o(.text) + OBJDIR/radeon_monitor.o(.text) - OBJDIR/xhdi_sd.o(.text) - OBJDIR/xhdi_interface.o(.text) - OBJDIR/xhdi_vec.o(.text) + OBJDIR/xhdi_sd.o(.text) + OBJDIR/xhdi_interface.o(.text) + OBJDIR/xhdi_vec.o(.text) #ifdef COMPILE_RAM - /* - * if we compile to RAM anyway, there is no need to copy anything - */ - . = ALIGN(4); - __BAS_DATA_START = .; - *(.data) - __BAS_DATA_END = .; - __BAS_BSS_START = .; - *(.bss) - __BAS_BSS_END = .; + /* + * if we compile to RAM anyway, there is no need to copy anything + */ + . = ALIGN(4); + __BAS_DATA_START = .; + *(.data) + __BAS_DATA_END = .; + __BAS_BSS_START = .; + *(.bss) + __BAS_BSS_END = .; #endif /* COMPILE_RAM */ #if (FORMAT_ELF == 1) - *(.rodata) - *(.rodata.*) + *(.rodata) + *(.rodata.*) #endif - } > bas_rom + } > bas_rom #if (TARGET_ADDRESS == BOOTFLASH_BASE_ADDRESS) - /* - * put BaS .data and .bss segments to flash, but relocate it to RAM after initialize_hardware() ran - */ - .bas : - AT (ALIGN(ADDR(.text) + SIZEOF(.text), 4)) - { - . = ALIGN(4); /* same alignment than AT() statement! */ - __BAS_DATA_START = .; - *(.data) - __BAS_DATA_END = .; - __BAS_BSS_START = .; - *(.bss) - __BAS_BSS_END = .; + /* + * put BaS .data and .bss segments to flash, but relocate it to RAM after initialize_hardware() ran + */ + .bas : + AT (ALIGN(ADDR(.text) + SIZEOF(.text), 4)) + { + . = ALIGN(4); /* same alignment than AT() statement! */ + __BAS_DATA_START = .; + *(.data) + __BAS_DATA_END = .; + __BAS_BSS_START = .; + *(.bss) + __BAS_BSS_END = .; - . = ALIGN(16); - } > bas_ram + . = ALIGN(16); + } > bas_ram #endif - .driver_memory : - { - . = ALIGN(4); - _driver_mem_buffer = .; - //. = . + DRIVER_MEM_BUFFER_SIZE; - } > driver_ram + .driver_memory : + { + . = ALIGN(4); + _driver_mem_buffer = .; + //. = . + DRIVER_MEM_BUFFER_SIZE; + } > driver_ram - /* - * Global memory map - */ + /* + * Global memory map + */ - /* SDRAM Initialization */ - ___SDRAM = SDRAM_START; - ___SDRAM_SIZE = SDRAM_SIZE; - _SDRAM_VECTOR_TABLE = ___SDRAM; + /* SDRAM Initialization */ + ___SDRAM = SDRAM_START; + ___SDRAM_SIZE = SDRAM_SIZE; + _SDRAM_VECTOR_TABLE = ___SDRAM; - /* ST-RAM */ - __STRAM = ___SDRAM; - __STRAM_END = __TOS; + /* ST-RAM */ + __STRAM = ___SDRAM; + __STRAM_END = __TOS; - /* TOS */ - __TOS = 0x00e00000; + /* TOS */ + __TOS = 0x00e00000; - /* FastRAM */ - __FASTRAM = 0x10000000; - __TARGET_ADDRESS = TARGET_ADDRESS; + /* FastRAM */ + __FASTRAM = 0x10000000; + __TARGET_ADDRESS = TARGET_ADDRESS; #if TARGET_ADDRESS == BOOTFLASH_BASE_ADDRESS - __FASTRAM_END = __BAS_IN_RAM; + __FASTRAM_END = __BAS_IN_RAM; #else - __FASTRAM_END = TARGET_ADDRESS; + __FASTRAM_END = TARGET_ADDRESS; #endif - __FASTRAM_SIZE = __FASTRAM_END - __FASTRAM; + __FASTRAM_SIZE = __FASTRAM_END - __FASTRAM; - /* Init CS0 (BootFLASH @ E000_0000 - E07F_FFFF 8Mbytes) */ - ___BOOT_FLASH = BOOTFLASH_BASE_ADDRESS; - ___BOOT_FLASH_SIZE = BOOTFLASH_SIZE; + /* Init CS0 (BootFLASH @ E000_0000 - E07F_FFFF 8Mbytes) */ + ___BOOT_FLASH = BOOTFLASH_BASE_ADDRESS; + ___BOOT_FLASH_SIZE = BOOTFLASH_SIZE; #if TARGET_ADDRESS == BOOTFLASH_BASE_ADDRESS - /* BaS */ - __BAS_LMA = LOADADDR(.bas); - __BAS_IN_RAM = ADDR(.bas); - __BAS_SIZE = SIZEOF(.bas); + /* BaS */ + __BAS_LMA = LOADADDR(.bas); + __BAS_IN_RAM = ADDR(.bas); + __BAS_SIZE = SIZEOF(.bas); #else - /* BaS is already in RAM - no need to copy anything */ - __BAS_IN_RAM = __FASTRAM_END; - __BAS_SIZE = 0; - __BAS_LMA = __BAS_IN_RAM; + /* BaS is already in RAM - no need to copy anything */ + __BAS_IN_RAM = __FASTRAM_END; + __BAS_SIZE = 0; + __BAS_LMA = __BAS_IN_RAM; #endif - /* Other flash components */ - __FIRETOS = 0xe0400000; - __EMUTOS = EMUTOS_BASE_ADDRESS; - __EMUTOS_SIZE = 0x00100000; + /* Other flash components */ + __FIRETOS = 0xe0400000; + __EMUTOS = EMUTOS_BASE_ADDRESS; + __EMUTOS_SIZE = 0x00100000; - /* where FPGA data lives in flash */ - __FPGA_CONFIG = 0xe0700000; - __FPGA_CONFIG_SIZE = 0x100000; + /* where FPGA data lives in flash */ + __FPGA_CONFIG = 0xe0700000; + __FPGA_CONFIG_SIZE = 0x100000; - /* VIDEO RAM BASIS */ - __VRAM = 0x60000000; + /* VIDEO RAM BASIS */ + __VRAM = 0x60000000; - /* Memory mapped registers */ - __MBAR = 0xFF000000; + /* Memory mapped registers */ + __MBAR = 0xFF000000; - /* 32KB on-chip System SRAM */ - __SYS_SRAM = __MBAR + 0x10000; - __SYS_SRAM_SIZE = 0x00008000; + /* 32KB on-chip System SRAM */ + __SYS_SRAM = __MBAR + 0x10000; + __SYS_SRAM_SIZE = 0x00008000; - /* MMU memory mapped registers */ - __MMUBAR = 0xFF040000; + /* MMU memory mapped registers */ + __MMUBAR = 0xFF040000; - /* - * 4KB on-chip Core SRAM0: -> exception table - */ - __RAMBAR0 = 0xFF100000; - __RAMBAR0_SIZE = 0x00001000; + /* + * 4KB on-chip Core SRAM0: -> exception table + */ + __RAMBAR0 = 0xFF100000; + __RAMBAR0_SIZE = 0x00001000; - /* 4KB on-chip Core SRAM1 */ - __RAMBAR1 = 0xFF101000; - __RAMBAR1_SIZE = 0x00001000; - __SUP_SP = __RAMBAR1 + __RAMBAR1_SIZE - 4; + /* 4KB on-chip Core SRAM1 */ + __RAMBAR1 = 0xFF101000; + __RAMBAR1_SIZE = 0x00001000; + __SUP_SP = __RAMBAR1 + __RAMBAR1_SIZE - 4; - /* - * this flag (if 1) indicates that FPGA configuration has been loaded through JTAG - * and shouldn't be overwritten on boot - */ - __FPGA_JTAG_LOADED = __RAMBAR1; - __FPGA_JTAG_VALID = __RAMBAR1 + 4; - /* system variables */ + /* + * this flag (if 1) indicates that FPGA configuration has been loaded through JTAG + * and shouldn't be overwritten on boot + */ + __FPGA_JTAG_LOADED = __RAMBAR1; + __FPGA_JTAG_VALID = __RAMBAR1 + 4; + /* system variables */ - /* RAMBAR0 0 to 0x7FF -> exception vectors */ - _rt_mod = __RAMBAR0 + 0x800; - _rt_ssp = __RAMBAR0 + 0x804; - _rt_usp = __RAMBAR0 + 0x808; - _rt_vbr = __RAMBAR0 + 0x80C; /* (8)01 */ - _rt_cacr = __RAMBAR0 + 0x810; /* 002 */ - _rt_asid = __RAMBAR0 + 0x814; /* 003 */ - _rt_acr0 = __RAMBAR0 + 0x818; /* 004 */ - _rt_acr1 = __RAMBAR0 + 0x81c; /* 005 */ - _rt_acr2 = __RAMBAR0 + 0x820; /* 006 */ - _rt_acr3 = __RAMBAR0 + 0x824; /* 007 */ - _rt_mmubar = __RAMBAR0 + 0x828; /* 008 */ - _rt_sr = __RAMBAR0 + 0x82c; - _d0_save = __RAMBAR0 + 0x830; - _a7_save = __RAMBAR0 + 0x834; - _video_tlb = __RAMBAR0 + 0x838; - _video_sbt = __RAMBAR0 + 0x83C; - _rt_mbar = __RAMBAR0 + 0x844; /* (c)0f */ + /* system variables */ + + /* RAMBAR0 0 to 0x7FF -> exception vectors */ + _rt_mod = __RAMBAR0 + 0x800; + _rt_ssp = __RAMBAR0 + 0x804; + _rt_usp = __RAMBAR0 + 0x808; + _rt_vbr = __RAMBAR0 + 0x80C; /* (8)01 */ + _rt_cacr = __RAMBAR0 + 0x810; /* 002 */ + _rt_asid = __RAMBAR0 + 0x814; /* 003 */ + _rt_acr0 = __RAMBAR0 + 0x818; /* 004 */ + _rt_acr1 = __RAMBAR0 + 0x81c; /* 005 */ + _rt_acr2 = __RAMBAR0 + 0x820; /* 006 */ + _rt_acr3 = __RAMBAR0 + 0x824; /* 007 */ + _rt_mmubar = __RAMBAR0 + 0x828; /* 008 */ + _rt_sr = __RAMBAR0 + 0x82c; + _d0_save = __RAMBAR0 + 0x830; + _a7_save = __RAMBAR0 + 0x834; + _video_tlb = __RAMBAR0 + 0x838; + _video_sbt = __RAMBAR0 + 0x83C; + _rt_mbar = __RAMBAR0 + 0x844; /* (c)0f */ } diff --git a/BaS_gcc/net/fecbd.c b/BaS_gcc/net/fecbd.c index 49b1d0c..c309c5b 100644 --- a/BaS_gcc/net/fecbd.c +++ b/BaS_gcc/net/fecbd.c @@ -11,7 +11,7 @@ #include "bas_printf.h" #include -#define DBG_FECBD +//#define DBG_FECBD #ifdef DBG_FECBD #define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0) #else @@ -62,94 +62,94 @@ static int iRxbd; */ void fecbd_init(uint8_t ch) { - NBUF *nbuf; - int i; + NBUF *nbuf; + int i; dbg("\r\n"); - /* - * Align Buffer Descriptors to 4-byte boundary - */ - RxBD = (FECBD *)(((int) unaligned_bds + 3) & 0xFFFFFFFC); - TxBD = (FECBD *)((int) RxBD + (sizeof(FECBD) * 2 * NRXBD)); + /* + * Align Buffer Descriptors to 4-byte boundary + */ + RxBD = (FECBD *)(((int) unaligned_bds + 3) & 0xFFFFFFFC); + TxBD = (FECBD *)((int) RxBD + (sizeof(FECBD) * 2 * NRXBD)); dbg("initialise RX buffer descriptor ring\r\n"); - /* - * Initialize the Rx Buffer Descriptor ring - */ - for (i = 0; i < NRXBD; ++i) - { - /* Grab a network buffer from the free list */ - nbuf = nbuf_alloc(); - if (nbuf == NULL) - { + /* + * Initialize the Rx Buffer Descriptor ring + */ + for (i = 0; i < NRXBD; ++i) + { + /* Grab a network buffer from the free list */ + nbuf = nbuf_alloc(); + if (nbuf == NULL) + { dbg("could not allocate network buffer\r\n"); - return; - } + return; + } - /* 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; + /* 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); - } + /* 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; + /* + * Set the WRAP bit on the last one + */ + RxBD(ch, i - 1).status |= RX_BD_W; dbg("initialise TX buffer descriptor ring\r\n"); - /* - * 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; - } + /* + * 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; + /* + * 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; + /* + * Initialize the buffer descriptor indexes + */ + iTxbd_new = iTxbd_old = iRxbd = 0; } void fecbd_dump(uint8_t ch) { #ifdef DBG_FECBD - int i; + int i; - xprintf("\n------------ FEC%d BDs -----------\n",ch); - xprintf("RxBD Ring\n"); - for (i = 0; i < NRXBD; i++) - { - xprintf("%02d: BD Addr=0x%08x, Ctrl=0x%04x, Lgth=%04d, DataPtr=0x%08x\n", - i, &RxBD(ch, i), - RxBD(ch, i).status, - RxBD(ch, i).length, - RxBD(ch, i).data); - } - xprintf("TxBD Ring\n"); - for (i = 0; i < NTXBD; i++) - { - xprintf("%02d: BD Addr=0x%08x, Ctrl=0x%04x, Lgth=%04d, DataPtr=0x%08x\n", - i, &TxBD(ch, i), - TxBD(ch, i).status, - TxBD(ch, i).length, - TxBD(ch, i).data); - } - xprintf("--------------------------------\n\n"); + xprintf("\n------------ FEC%d BDs -----------\n",ch); + xprintf("RxBD Ring\n"); + for (i = 0; i < NRXBD; i++) + { + xprintf("%02d: BD Addr=0x%08x, Ctrl=0x%04x, Lgth=%04d, DataPtr=0x%08x\n", + i, &RxBD(ch, i), + RxBD(ch, i).status, + RxBD(ch, i).length, + RxBD(ch, i).data); + } + xprintf("TxBD Ring\n"); + for (i = 0; i < NTXBD; i++) + { + xprintf("%02d: BD Addr=0x%08x, Ctrl=0x%04x, Lgth=%04d, DataPtr=0x%08x\n", + i, &TxBD(ch, i), + TxBD(ch, i).status, + TxBD(ch, i).length, + TxBD(ch, i).data); + } + xprintf("--------------------------------\n\n"); #endif /* DBG_FECBD */ } @@ -165,28 +165,28 @@ void fecbd_dump(uint8_t ch) */ uint32_t fecbd_get_start(uint8_t ch, uint8_t direction) { - switch (direction) - { - case Rx: - return (uint32_t)((int)RxBD + (ch * sizeof(FECBD) * NRXBD)); - case Tx: - default: - return (uint32_t)((int)TxBD + (ch * sizeof(FECBD) * NTXBD)); - } + switch (direction) + { + case Rx: + return (uint32_t)((int)RxBD + (ch * sizeof(FECBD) * NRXBD)); + case Tx: + default: + return (uint32_t)((int)TxBD + (ch * sizeof(FECBD) * NTXBD)); + } } FECBD *fecbd_rx_alloc(uint8_t ch) { - int i = iRxbd; + int i = iRxbd; - /* Check to see if the ring of BDs is full */ - if (RxBD(ch, i).status & RX_BD_E) - return NULL; + /* Check to see if the ring of BDs is full */ + if (RxBD(ch, i).status & RX_BD_E) + return NULL; - /* Increment the circular index */ - iRxbd = (uint8_t)((iRxbd + 1) % NRXBD); + /* Increment the circular index */ + iRxbd = (uint8_t)((iRxbd + 1) % NRXBD); - return &RxBD(ch, i); + return &RxBD(ch, i); } /* @@ -201,16 +201,16 @@ FECBD *fecbd_rx_alloc(uint8_t ch) */ FECBD *fecbd_tx_alloc(uint8_t ch) { - int i = iTxbd_new; + int i = iTxbd_new; - /* Check to see if the ring of BDs is full */ - if (TxBD(ch, i).status & TX_BD_R) - return NULL; + /* Check to see if the ring of BDs is full */ + if (TxBD(ch, i).status & TX_BD_R) + return NULL; - /* Increment the circular index */ - iTxbd_new = (uint8_t)((iTxbd_new + 1) % NTXBD); + /* Increment the circular index */ + iTxbd_new = (uint8_t)((iTxbd_new + 1) % NTXBD); - return &TxBD(ch, i); + return &TxBD(ch, i); } /* @@ -226,14 +226,14 @@ FECBD *fecbd_tx_alloc(uint8_t ch) */ FECBD *fecbd_tx_free(uint8_t ch) { - int i = iTxbd_old; + int i = iTxbd_old; - /* Check to see if the ring of BDs is empty */ - if ((TxBD(ch, i).data == NULL) || (TxBD(ch, i).status & TX_BD_R)) - return NULL; + /* Check to see if the ring of BDs is empty */ + if ((TxBD(ch, i).data == NULL) || (TxBD(ch, i).status & TX_BD_R)) + return NULL; - /* Increment the circular index */ - iTxbd_old = (uint8_t)((iTxbd_old + 1) % NTXBD); + /* Increment the circular index */ + iTxbd_old = (uint8_t)((iTxbd_old + 1) % NTXBD); - return &TxBD(ch, i); + return &TxBD(ch, i); } diff --git a/BaS_gcc/net/ip.c b/BaS_gcc/net/ip.c index 2a82f96..b3951ce 100644 --- a/BaS_gcc/net/ip.c +++ b/BaS_gcc/net/ip.c @@ -1,5 +1,5 @@ /* - * File: ip.c + * File: ip.c * Purpose: Internet Protcol device driver * * Notes: @@ -12,7 +12,7 @@ #include "bas_string.h" -#define IP_DEBUG +//#define IP_DEBUG #if defined(IP_DEBUG) #define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0) #else @@ -21,300 +21,297 @@ void ip_init(IP_INFO *info, IP_ADDR_P myip, IP_ADDR_P gateway, IP_ADDR_P netmask) { - int index; + int index; - for (index = 0; index < sizeof(IP_ADDR); index++) - { - info->myip[index] = myip[index]; - info->gateway[index] = gateway[index]; - info->netmask[index] = netmask[index]; - info->broadcast[index] = 0xFF; - } + for (index = 0; index < sizeof(IP_ADDR); index++) + { + info->myip[index] = myip[index]; + info->gateway[index] = gateway[index]; + info->netmask[index] = netmask[index]; + info->broadcast[index] = 0xFF; + } - info->rx = 0; - info->rx_unsup = 0; - info->tx = 0; - info->err = 0; + info->rx = 0; + info->rx_unsup = 0; + info->tx = 0; + info->err = 0; } uint8_t *ip_get_myip(IP_INFO *info) { - if (info != 0) - { - return (uint8_t *) &info->myip[0]; - } - dbg("info is NULL!\n\t"); - return 0; + if (info != 0) + { + return (uint8_t *) &info->myip[0]; + } + dbg("info is NULL!\n\t"); + return 0; } int ip_addr_compare(IP_ADDR_P addr1, IP_ADDR_P addr2) { - int i; + int i; - for (i = 0; i < sizeof(IP_ADDR); i++) - { - if (addr1[i] != addr2[i]) - return 0; - } - return 1; + for (i = 0; i < sizeof(IP_ADDR); i++) + { + if (addr1[i] != addr2[i]) + return 0; + } + return 1; } uint8_t *ip_resolve_route(NIF *nif, IP_ADDR_P destip) { - /* - * This function determines whether or not an outgoing IP - * packet needs to be transmitted on the local net or sent - * to the router for transmission. - */ - IP_INFO *info; - IP_ADDR mask, result; - IP_ADDR bc = { 255, 255, 255, 255 }; - int i; + /* + * This function determines whether or not an outgoing IP + * packet needs to be transmitted on the local net or sent + * to the router for transmission. + */ + IP_INFO *info; + IP_ADDR mask, result; + IP_ADDR bc = { 255, 255, 255, 255 }; + int i; - info = nif_get_protocol_info(nif, ETH_FRM_IP); + info = nif_get_protocol_info(nif, ETH_FRM_IP); - if (memcmp(destip, bc, 4) == 0) - { - dbg("destip is broadcast address, no gateway needed\r\n"); - return destip; - } + if (memcmp(destip, bc, 4) == 0) + { + dbg("destip is broadcast address, no gateway needed\r\n"); + return destip; + } - /* create mask for local IP */ - for (i = 0; i < sizeof(IP_ADDR); i++) - { - mask[i] = info->myip[i] & info->netmask[i]; - } + /* create mask for local IP */ + for (i = 0; i < sizeof(IP_ADDR); i++) + { + mask[i] = info->myip[i] & info->netmask[i]; + } - /* apply mask to the destination IP */ - for (i = 0; i < sizeof(IP_ADDR); i++) - { - result[i] = mask[i] & destip[i]; - } + /* apply mask to the destination IP */ + for (i = 0; i < sizeof(IP_ADDR); i++) + { + result[i] = mask[i] & destip[i]; + } - /* See if destination IP is local or not */ - if (ip_addr_compare(mask, result)) - { - /* The destination IP is on the local net */ - return arp_resolve(nif, ETH_FRM_IP, destip); - } - else - { - /* The destination IP is not on the local net */ - return arp_resolve(nif, ETH_FRM_IP, info->gateway); - } + /* See if destination IP is local or not */ + if (ip_addr_compare(mask, result)) + { + /* The destination IP is on the local net */ + return arp_resolve(nif, ETH_FRM_IP, destip); + } + else + { + /* The destination IP is not on the local net */ + return arp_resolve(nif, ETH_FRM_IP, info->gateway); + } } int ip_send(NIF *nif, uint8_t *dest, uint8_t *src, uint8_t protocol, NBUF *pNbuf) { - /* - * This function assembles an IP datagram and passes it - * onto the hardware to be sent over the network. - */ - uint8_t *route; - ip_frame_hdr *ipframe; + /* + * This function assembles an IP datagram and passes it + * onto the hardware to be sent over the network. + */ + uint8_t *route; + ip_frame_hdr *ipframe; - /* - * Construct the IP header - */ - ipframe = (ip_frame_hdr*) &pNbuf->data[IP_HDR_OFFSET]; + /* + * Construct the IP header + */ + ipframe = (ip_frame_hdr*) &pNbuf->data[IP_HDR_OFFSET]; - /* IP version 4, Internet Header Length of 5 32-bit words */ - ipframe->version_ihl = 0x45; + /* IP version 4, Internet Header Length of 5 32-bit words */ + ipframe->version_ihl = 0x45; - /* Type of Service == 0, normal and routine */ - ipframe->service_type = 0x00; + /* Type of Service == 0, normal and routine */ + ipframe->service_type = 0x00; - /* Total length of data */ - ipframe->total_length = (uint16_t) (pNbuf->length + IP_HDR_SIZE); + /* Total length of data */ + ipframe->total_length = (uint16_t) (pNbuf->length + IP_HDR_SIZE); - /* User defined identification */ - ipframe->identification = 0x0000; + /* User defined identification */ + ipframe->identification = 0x0000; - /* Fragment Flags and Offset -- Don't fragment, last frag */ - ipframe->flags_frag_offset = 0x0000; + /* Fragment Flags and Offset -- Don't fragment, last frag */ + ipframe->flags_frag_offset = 0x0000; - /* Time To Live */ - ipframe->ttl = 0xFF; + /* Time To Live */ + ipframe->ttl = 0xFF; - /* Protocol */ - ipframe->protocol = protocol; + /* Protocol */ + ipframe->protocol = protocol; - /* Checksum, computed later, zeroed for computation */ - ipframe->checksum = 0x0000; + /* Checksum, computed later, zeroed for computation */ + ipframe->checksum = 0x0000; - /* source IP address */ - ipframe->source_addr[0] = src[0]; - ipframe->source_addr[1] = src[1]; - ipframe->source_addr[2] = src[2]; - ipframe->source_addr[3] = src[3]; + /* source IP address */ + ipframe->source_addr[0] = src[0]; + ipframe->source_addr[1] = src[1]; + ipframe->source_addr[2] = src[2]; + ipframe->source_addr[3] = src[3]; - /* dest IP address */ - ipframe->dest_addr[0] = dest[0]; - ipframe->dest_addr[1] = dest[1]; - ipframe->dest_addr[2] = dest[2]; - ipframe->dest_addr[3] = dest[3]; + /* dest IP address */ + ipframe->dest_addr[0] = dest[0]; + ipframe->dest_addr[1] = dest[1]; + ipframe->dest_addr[2] = dest[2]; + ipframe->dest_addr[3] = dest[3]; - /* Compute checksum */ - ipframe->checksum = ip_chksum((uint16_t *) ipframe, IP_HDR_SIZE); + /* Compute checksum */ + ipframe->checksum = ip_chksum((uint16_t *) ipframe, IP_HDR_SIZE); - /* Increment the packet length by the size of the IP header */ - pNbuf->length += IP_HDR_SIZE; + /* Increment the packet length by the size of the IP header */ + pNbuf->length += IP_HDR_SIZE; - /* - * Determine the hardware address of the recipient - */ - IP_ADDR bc = { 255, 255, 255, 255}; - if (memcmp(bc, dest, 4) != 0) - { - route = ip_resolve_route(nif, dest); - if (route == NULL) - { - dbg("Unable to locate %d.%d.%d.%d\r\n", - dest[0], dest[1], dest[2], dest[3]); - return 0; - } - } - else - { - route = bc; - dbg("route = broadcast\r\n"); - dbg("nif = %p\r\n", nif); - dbg("nif->send = %p\r\n", nif->send); - } + /* + * Determine the hardware address of the recipient + */ + IP_ADDR bc = { 255, 255, 255, 255}; + if (memcmp(bc, dest, 4) != 0) + { + route = ip_resolve_route(nif, dest); + if (route == NULL) + { + dbg("Unable to locate %d.%d.%d.%d\r\n", + dest[0], dest[1], dest[2], dest[3]); + return 0; + } + } + else + { + route = bc; + dbg("route = broadcast\r\n"); + dbg("nif = %p\r\n", nif); + dbg("nif->send = %p\r\n", nif->send); + } - return nif->send(nif, route, &nif->hwa[0], ETH_FRM_IP, pNbuf); + return nif->send(nif, route, &nif->hwa[0], ETH_FRM_IP, pNbuf); } #if defined(DEBUG_PRINT) void dump_ip_frame(ip_frame_hdr *ipframe) { - xprintf("Version: %02X\n", ((ipframe->version_ihl & 0x00f0) >> 4)); - xprintf("IHL: %02X\n", ipframe->version_ihl & 0x000f); - xprintf("Service: %02X\n", ipframe->service_type); - xprintf("Length: %04X\n", ipframe->total_length); - xprintf("Ident: %04X\n", ipframe->identification); - xprintf("Flags: %02X\n", ((ipframe->flags_frag_offset & 0xC000) >> 14)); - xprintf("Frag: %04X\n", ipframe->flags_frag_offset & 0x3FFF); - xprintf("TTL: %02X\n", ipframe->ttl); - xprintf("Protocol: %02X\n", ipframe->protocol); - xprintf("Chksum: %04X\n", ipframe->checksum); - xprintf("Source : %d.%d.%d.%d\n", - ipframe->source_addr[0], - ipframe->source_addr[1], - ipframe->source_addr[2], - ipframe->source_addr[3]); - xprintf("Dest : %d.%d.%d.%d\n", - ipframe->dest_addr[0], - ipframe->dest_addr[1], - ipframe->dest_addr[2], - ipframe->dest_addr[3]); - xprintf("Options: %08X\n", ipframe->options); + xprintf("Version: %02X\n", ((ipframe->version_ihl & 0x00f0) >> 4)); + xprintf("IHL: %02X\n", ipframe->version_ihl & 0x000f); + xprintf("Service: %02X\n", ipframe->service_type); + xprintf("Length: %04X\n", ipframe->total_length); + xprintf("Ident: %04X\n", ipframe->identification); + xprintf("Flags: %02X\n", ((ipframe->flags_frag_offset & 0xC000) >> 14)); + xprintf("Frag: %04X\n", ipframe->flags_frag_offset & 0x3FFF); + xprintf("TTL: %02X\n", ipframe->ttl); + xprintf("Protocol: %02X\n", ipframe->protocol); + xprintf("Chksum: %04X\n", ipframe->checksum); + xprintf("Source : %d.%d.%d.%d\n", + ipframe->source_addr[0], + ipframe->source_addr[1], + ipframe->source_addr[2], + ipframe->source_addr[3]); + xprintf("Dest : %d.%d.%d.%d\n", + ipframe->dest_addr[0], + ipframe->dest_addr[1], + ipframe->dest_addr[2], + ipframe->dest_addr[3]); + xprintf("Options: %08X\n", ipframe->options); } #endif uint16_t ip_chksum(uint16_t *data, int num) { - int chksum, ichksum; - uint16_t temp; + int chksum, ichksum; + uint16_t temp; - chksum = 0; - num = num >> 1; /* from bytes to words */ - for (; num; num--, data++) - { - temp = *data; - ichksum = chksum + temp; - ichksum = ichksum & 0x0000FFFF; - if ((ichksum < temp) || (ichksum < chksum)) - { - ichksum += 1; - ichksum = ichksum & 0x0000FFFF; - } - chksum = ichksum; - } - return (uint16_t) ~chksum; + chksum = 0; + num = num >> 1; /* from bytes to words */ + for (; num; num--, data++) + { + temp = *data; + ichksum = chksum + temp; + ichksum = ichksum & 0x0000FFFF; + if ((ichksum < temp) || (ichksum < chksum)) + { + ichksum += 1; + ichksum = ichksum & 0x0000FFFF; + } + chksum = ichksum; + } + return (uint16_t) ~chksum; } static int validate_ip_hdr(NIF *nif, ip_frame_hdr *ipframe) { - int index, chksum; - IP_INFO *info; + int index, chksum; + IP_INFO *info; - /* - * Check the IP Version - */ - if (IP_VERSION(ipframe) != 4) - return 0; + /* + * Check the IP Version + */ + if (IP_VERSION(ipframe) != 4) + return 0; - /* - * Check Internet Header Length - */ - if (IP_IHL(ipframe) < 5) - return 0; + /* + * Check Internet Header Length + */ + if (IP_IHL(ipframe) < 5) + return 0; - /* - * Check the destination IP address - */ - info = nif_get_protocol_info(nif,ETH_FRM_IP); - for (index = 0; index < sizeof(IP_ADDR); index++) - if (info->myip[index] != ipframe->dest_addr[index]) - return 0; + /* + * Check the destination IP address + */ + info = nif_get_protocol_info(nif,ETH_FRM_IP); + for (index = 0; index < sizeof(IP_ADDR); index++) + if (info->myip[index] != ipframe->dest_addr[index]) + return 0; - /* - * Check the checksum - */ - chksum = (int)((uint16_t) IP_CHKSUM(ipframe)); - IP_CHKSUM(ipframe) = 0; + /* + * Check the checksum + */ + chksum = (int)((uint16_t) IP_CHKSUM(ipframe)); + IP_CHKSUM(ipframe) = 0; - if (ip_chksum((uint16_t *) ipframe, IP_IHL(ipframe) * 4) != chksum) - return 0; + if (ip_chksum((uint16_t *) ipframe, IP_IHL(ipframe) * 4) != chksum) + return 0; - IP_CHKSUM(ipframe) = (uint16_t) chksum; + IP_CHKSUM(ipframe) = (uint16_t) chksum; - return 1; + return 1; } void ip_handler(NIF *nif, NBUF *pNbuf) { - /* - * IP packet handler - */ - ip_frame_hdr *ipframe; + /* + * IP packet handler + */ + ip_frame_hdr *ipframe; - dbg("packet received\r\n"); + dbg("packet received\r\n"); - ipframe = (ip_frame_hdr *) &pNbuf->data[pNbuf->offset]; + ipframe = (ip_frame_hdr *) &pNbuf->data[pNbuf->offset]; - /* - * Verify valid IP header and destination IP - */ - if (!validate_ip_hdr(nif, ipframe)) - { - dbg("not a valid IP packet!\r\n"); + /* + * Verify valid IP header and destination IP + */ + if (!validate_ip_hdr(nif, ipframe)) + { + dbg("not a valid IP packet!\r\n"); - nbuf_free(pNbuf); - return; - } + nbuf_free(pNbuf); + return; + } - pNbuf->offset += (IP_IHL(ipframe) * 4); - pNbuf->length = (uint16_t)(IP_LENGTH(ipframe) - (IP_IHL(ipframe) * 4)); - - /* - * Call the appriopriate handler - */ - switch (IP_PROTOCOL(ipframe)) - { - case IP_PROTO_ICMP: - // FIXME: icmp_handler(nif, pNbuf); - break; - case IP_PROTO_UDP: - udp_handler(nif,pNbuf); - break; - default: - dbg("no protocol handler registered for protocol %d\r\n", - __FUNCTION__, IP_PROTOCOL(ipframe)); - nbuf_free(pNbuf); - break; - } - return; + /* + * Call the appriopriate handler + */ + switch (IP_PROTOCOL(ipframe)) + { + case IP_PROTO_ICMP: + // FIXME: icmp_handler(nif, pNbuf); + break; + case IP_PROTO_UDP: + udp_handler(nif,pNbuf); + break; + default: + dbg("no protocol handler registered for protocol %d\r\n", + __FUNCTION__, IP_PROTOCOL(ipframe)); + nbuf_free(pNbuf); + break; + } + return; } diff --git a/BaS_gcc/net/udp.c b/BaS_gcc/net/udp.c index 3e4c9bc..cd84c4e 100644 --- a/BaS_gcc/net/udp.c +++ b/BaS_gcc/net/udp.c @@ -21,8 +21,8 @@ typedef struct { - uint16_t port; - void (*handler)(NIF *, NBUF *); + uint16_t port; + void (*handler)(NIF *, NBUF *); } UDP_BOUND_PORT; #define UDP_MAX_PORTS (5) /* plenty for this implementation */ @@ -34,151 +34,151 @@ static uint16_t udp_port; void udp_init(void) { - int index; + int index; - for (index = 0; index < UDP_MAX_PORTS; ++index) - { - udp_port_table[index].port = 0; - udp_port_table[index].handler = 0; - } + for (index = 0; index < UDP_MAX_PORTS; ++index) + { + udp_port_table[index].port = 0; + udp_port_table[index].handler = 0; + } - udp_port = DEFAULT_UDP_PORT; /* next free port */ + udp_port = DEFAULT_UDP_PORT; /* next free port */ } void udp_prime_port(uint16_t init_port) { - udp_port = init_port; + udp_port = init_port; } void udp_bind_port(uint16_t port, void (*handler)(NIF *, NBUF *)) { - int index; + int index; - for (index = 0; index < UDP_MAX_PORTS; ++index) - { - if (udp_port_table[index].port == 0) - { - udp_port_table[index].port = port; - udp_port_table[index].handler = handler; + for (index = 0; index < UDP_MAX_PORTS; ++index) + { + if (udp_port_table[index].port == 0) + { + udp_port_table[index].port = port; + udp_port_table[index].handler = handler; - return; - } - } + return; + } + } } void udp_free_port(uint16_t port) { - int index; + int index; - for (index = 0; index < UDP_MAX_PORTS; ++index) - { - if (udp_port_table[index].port == port) - { - udp_port_table[index].port = 0; + for (index = 0; index < UDP_MAX_PORTS; ++index) + { + if (udp_port_table[index].port == port) + { + udp_port_table[index].port = 0; - return; - } - } + return; + } + } } static void *udp_port_handler(uint16_t port) { - int index; + int index; - for (index = 0; index < UDP_MAX_PORTS; ++index) - { - if (udp_port_table[index].port == port) - { - return (void *) udp_port_table[index].handler; - } - } - return NULL; + for (index = 0; index < UDP_MAX_PORTS; ++index) + { + if (udp_port_table[index].port == port) + { + return (void *) udp_port_table[index].handler; + } + } + return NULL; } uint16_t udp_obtain_free_port(void) { - uint16_t port; + uint16_t port; - port = udp_port; - if (--udp_port <= 255) - udp_port = DEFAULT_UDP_PORT; + port = udp_port; + if (--udp_port <= 255) + udp_port = DEFAULT_UDP_PORT; - return port; + return port; } int udp_send(NIF *nif, uint8_t *dest, int sport, int dport, NBUF *pNbuf) { - uint8_t *myip; + uint8_t *myip; - if (nif == NULL) - { + if (nif == NULL) + { dbg("nif is NULL\r\n"); - return 0; - } + return 0; + } - /* - * This function takes data, creates a UDP frame from it and - * passes it onto the IP layer - */ - udp_frame_hdr *udpframe; + /* + * This function takes data, creates a UDP frame from it and + * passes it onto the IP layer + */ + udp_frame_hdr *udpframe; - udpframe = (udp_frame_hdr *) &pNbuf->data[UDP_HDR_OFFSET]; + udpframe = (udp_frame_hdr *) &pNbuf->data[UDP_HDR_OFFSET]; - /* Set UDP source port */ - udpframe->src_port = (uint16_t) sport; + /* Set UDP source port */ + udpframe->src_port = (uint16_t) sport; - /* Set UDP destination port */ - udpframe->dest_port = (uint16_t) dport; + /* Set UDP destination port */ + udpframe->dest_port = (uint16_t) dport; - /* Set length */ - udpframe->length = (uint16_t) (pNbuf->length + UDP_HDR_SIZE); + /* Set length */ + udpframe->length = (uint16_t) (pNbuf->length + UDP_HDR_SIZE); - /* No checksum calcualation needed */ - udpframe->chksum = (uint16_t) 0; + /* No checksum calcualation needed */ + udpframe->chksum = (uint16_t) 0; - /* Add the length of the UDP packet to the total length of the packet */ - pNbuf->length += 8; + /* Add the length of the UDP packet to the total length of the packet */ + pNbuf->length += 8; - myip = ip_get_myip(nif_get_protocol_info(nif, ETH_FRM_IP)); + myip = ip_get_myip(nif_get_protocol_info(nif, ETH_FRM_IP)); dbg("sent UDP request to %d.%d.%d.%d from %d.%d.%d.%d\r\n", - dest[0], dest[1], dest[2], dest[3], - myip[0], myip[1], myip[2], myip[3]); + dest[0], dest[1], dest[2], dest[3], + myip[0], myip[1], myip[2], myip[3]); - return (ip_send(nif, dest, myip, IP_PROTO_UDP, pNbuf)); + return (ip_send(nif, dest, myip, IP_PROTO_UDP, pNbuf)); } void udp_handler(NIF *nif, NBUF *pNbuf) { - /* - * This function handles incoming UDP packets - */ - udp_frame_hdr *udpframe; - void (*handler)(NIF *, NBUF *); + /* + * This function handles incoming UDP packets + */ + udp_frame_hdr *udpframe; + void (*handler)(NIF *, NBUF *); - udpframe = (udp_frame_hdr *) &pNbuf->data[pNbuf->offset]; + udpframe = (udp_frame_hdr *) &pNbuf->data[pNbuf->offset]; dbg("packet received\r\n",); - /* - * Adjust the length and valid data offset of the packet we are - * passing on - */ - pNbuf->length -= UDP_HDR_SIZE; - pNbuf->offset += UDP_HDR_SIZE; + /* + * Adjust the length and valid data offset of the packet we are + * passing on + */ + pNbuf->length -= UDP_HDR_SIZE; + pNbuf->offset += UDP_HDR_SIZE; - /* - * Traverse the list of bound ports to see if there is a higher - * level protocol to pass the packet on to - */ - if ((handler = (void(*)(NIF*, NBUF*)) udp_port_handler(UDP_DEST(udpframe))) != NULL) - handler(nif, pNbuf); - else - { + /* + * Traverse the list of bound ports to see if there is a higher + * level protocol to pass the packet on to + */ + if ((handler = (void(*)(NIF*, NBUF*)) udp_port_handler(UDP_DEST(udpframe))) != NULL) + handler(nif, pNbuf); + else + { dbg("received UDP packet for non-supported port\n"); - nbuf_free(pNbuf); - } + nbuf_free(pNbuf); + } - return; + return; } diff --git a/BaS_gcc/sys/exceptions.S b/BaS_gcc/sys/exceptions.S index 8e4c108..ae1ef7c 100644 --- a/BaS_gcc/sys/exceptions.S +++ b/BaS_gcc/sys/exceptions.S @@ -27,531 +27,531 @@ #include "m5484l.h" #endif /* MACHINE_FIREBEE */ - .extern __SUP_SP - .extern _rom_entry - .extern __RAMBAR0 - .extern _rt_mod - .extern _rt_ssp - .extern _rt_usp - .extern _rt_vbr - .extern _mmutr_miss - .extern __MBAR - .extern __MMUBAR - .extern _video_tlb - .extern _video_sbt - .extern _flush_and_invalidate_caches - .extern _get_bas_drivers + .extern __SUP_SP + .extern _rom_entry + .extern __RAMBAR0 + .extern _rt_mod + .extern _rt_ssp + .extern _rt_usp + .extern _rt_vbr + .extern _mmutr_miss + .extern __MBAR + .extern __MMUBAR + .extern _video_tlb + .extern _video_sbt + .extern _flush_and_invalidate_caches + .extern _get_bas_drivers - /* PCI interrupt handlers */ - .extern _irq5_handler - .extern _irq6_handler - .extern _irq7_handler + /* PCI interrupt handlers */ + .extern _irq5_handler + .extern _irq6_handler + .extern _irq7_handler - .global _vec_init - .global _std_exc_vec /* needed by driver_vec.c */ + .global _vec_init + .global _std_exc_vec /* needed by driver_vec.c */ /* Register read/write equates */ - /* MMU */ - .equ MCF_MMU_MMUCR, __MMUBAR - .equ MCF_MMU_MMUOR, __MMUBAR+0x04 - .equ MCF_MMU_MMUSR, __MMUBAR+0x08 - .equ MCF_MMU_MMUAR, __MMUBAR+0x10 - .equ MCF_MMU_MMUTR, __MMUBAR+0x14 - .equ MCF_MMU_MMUDR, __MMUBAR+0x18 + /* MMU */ + .equ MCF_MMU_MMUCR, __MMUBAR + .equ MCF_MMU_MMUOR, __MMUBAR+0x04 + .equ MCF_MMU_MMUSR, __MMUBAR+0x08 + .equ MCF_MMU_MMUAR, __MMUBAR+0x10 + .equ MCF_MMU_MMUTR, __MMUBAR+0x14 + .equ MCF_MMU_MMUDR, __MMUBAR+0x18 - /* EPORT flag register */ - .equ MCF_EPORT_EPFR, __MBAR+0xf0c + /* EPORT flag register */ + .equ MCF_EPORT_EPFR, __MBAR+0xf0c - /* FEC1 port output data direction register */ - .equ MCF_GPIO_PODR_FEC1L, __MBAR+0xa07 + /* FEC1 port output data direction register */ + .equ MCF_GPIO_PODR_FEC1L, __MBAR+0xa07 - /* PSC0 transmit buffer register */ - .equ MCF_PSC0_PSCTB_8BIT, __MBAR+0x860c + /* PSC0 transmit buffer register */ + .equ MCF_PSC0_PSCTB_8BIT, __MBAR+0x860c - /* GPT mode select register */ - .equ MCF_GPT0_GMS, __MBAR+0x800 + /* GPT mode select register */ + .equ MCF_GPT0_GMS, __MBAR+0x800 - /* Slice timer 0 count register */ - .equ MCF_SLT0_SCNT, __MBAR+0x908 + /* Slice timer 0 count register */ + .equ MCF_SLT0_SCNT, __MBAR+0x908 - // interrupt sources - .equ INT_SOURCE_EPORT_EPF1,1 // edge port flag 1 - .equ INT_SOURCE_EPORT_EPF2,2 // edge port flag 2 - .equ INT_SOURCE_EPORT_EPF3,3 // edge port flag 3 - .equ INT_SOURCE_EPORT_EPF4,4 // edge port flag 4 - .equ INT_SOURCE_EPORT_EPF5,5 // edge port flag 5 - .equ INT_SOURCE_EPORT_EPF6,6 // edge port flag 6 - .equ INT_SOURCE_EPORT_EPF7,7 // edge port flag 7 - .equ INT_SOURCE_USB_EP0ISR,15 // USB endpoint 0 interrupt - .equ INT_SOURCE_USB_EP1ISR,16 // USB endpoint 1 interrupt - .equ INT_SOURCE_USB_EP2ISR,17 // USB endpoint 2 interrupt - .equ INT_SOURCE_USB_EP3ISR,18 // USB endpoint 3 interrupt - .equ INT_SOURCE_USB_EP4ISR,19 // USB endpoint 4 interrupt - .equ INT_SOURCE_USB_EP5ISR,20 // USB endpoint 5 interrupt - .equ INT_SOURCE_USB_EP6ISR,21 // USB endpoint 6 interrupt - .equ INT_SOURCE_USB_USBISR,22 // USB general interrupt - .equ INT_SOURCE_USB_USBAISR,23 // USB core interrupt - .equ INT_SOURCE_USB_ANY,24 // OR of all USB interrupts - .equ INT_SOURCE_USB_DSPI_OVF,25 // DSPI overflow or underflow - .equ INT_SOURCE_USB_DSPI_RFOF,26 // receive FIFO overflow interrupt - .equ INT_SOURCE_USB_DSPI_RFDF,27 // receive FIFO drain interrupt - .equ INT_SOURCE_USB_DSPI_TFUF,28 // transmit FIFO underflow interrupt - .equ INT_SOURCE_USB_DSPI_TCF,29 // transfer complete interrupt - .equ INT_SOURCE_USB_DSPI_TFFF,30 // transfer FIFO fill interrupt - .equ INT_SOURCE_USB_DSPI_EOQF,31 // end of queue interrupt - .equ INT_SOURCE_PSC3,32 // PSC3 interrupt - .equ INT_SOURCE_PSC2,33 // PSC2 interrupt - .equ INT_SOURCE_PSC1,34 // PSC1 interrupt - .equ INT_SOURCE_PSC0,35 // PSC0 interrupt - .equ INT_SOURCE_CTIMERS,36 // combined source for comm timers - .equ INT_SOURCE_SEC,37 // SEC interrupt - .equ INT_SOURCE_FEC1,38 // FEC1 interrupt - .equ INT_SOURCE_FEC0,39 // FEC0 interrupt - .equ INT_SOURCE_I2C,40 // I2C interrupt - .equ INT_SOURCE_PCIARB,41 // PCI arbiter interrupt - .equ INT_SOURCE_CBPCI,42 // COMM bus PCI interrupt - .equ INT_SOURCE_XLBPCI,43 // XLB PCI interrupt - .equ INT_SOURCE_XLBARB,47 // XLBARB to PCI interrupt - .equ INT_SOURCE_DMA,48 // multichannel DMA interrupt - .equ INT_SOURCE_CAN0_ERROR,49 // FlexCAN error interrupt - .equ INT_SOURCE_CAN0_BUSOFF,50 // FlexCAN bus off interrupt - .equ INT_SOURCE_CAN0_MBOR,51 // message buffer ORed interrupt - .equ INT_SOURCE_SLT1,53 // slice timer 1 interrupt - .equ INT_SOURCE_SLT0,54 // slice timer 0 interrupt - .equ INT_SOURCE_CAN1_ERROR,55 // FlexCAN error interrupt - .equ INT_SOURCE_CAN1_BUSOFF,56 // FlexCAN bus off interrupt - .equ INT_SOURCE_CAN1_MBOR,57 // message buffer ORed interrupt - .equ INT_SOURCE_GPT3,59 // GPT3 timer interrupt - .equ INT_SOURCE_GPT2,60 // GPT2 timer interrupt - .equ INT_SOURCE_GPT1,61 // GPT1 timer interrupt - .equ INT_SOURCE_GPT0,62 // GPT0 timer interrupt + // interrupt sources + .equ INT_SOURCE_EPORT_EPF1,1 // edge port flag 1 + .equ INT_SOURCE_EPORT_EPF2,2 // edge port flag 2 + .equ INT_SOURCE_EPORT_EPF3,3 // edge port flag 3 + .equ INT_SOURCE_EPORT_EPF4,4 // edge port flag 4 + .equ INT_SOURCE_EPORT_EPF5,5 // edge port flag 5 + .equ INT_SOURCE_EPORT_EPF6,6 // edge port flag 6 + .equ INT_SOURCE_EPORT_EPF7,7 // edge port flag 7 + .equ INT_SOURCE_USB_EP0ISR,15 // USB endpoint 0 interrupt + .equ INT_SOURCE_USB_EP1ISR,16 // USB endpoint 1 interrupt + .equ INT_SOURCE_USB_EP2ISR,17 // USB endpoint 2 interrupt + .equ INT_SOURCE_USB_EP3ISR,18 // USB endpoint 3 interrupt + .equ INT_SOURCE_USB_EP4ISR,19 // USB endpoint 4 interrupt + .equ INT_SOURCE_USB_EP5ISR,20 // USB endpoint 5 interrupt + .equ INT_SOURCE_USB_EP6ISR,21 // USB endpoint 6 interrupt + .equ INT_SOURCE_USB_USBISR,22 // USB general interrupt + .equ INT_SOURCE_USB_USBAISR,23 // USB core interrupt + .equ INT_SOURCE_USB_ANY,24 // OR of all USB interrupts + .equ INT_SOURCE_USB_DSPI_OVF,25 // DSPI overflow or underflow + .equ INT_SOURCE_USB_DSPI_RFOF,26 // receive FIFO overflow interrupt + .equ INT_SOURCE_USB_DSPI_RFDF,27 // receive FIFO drain interrupt + .equ INT_SOURCE_USB_DSPI_TFUF,28 // transmit FIFO underflow interrupt + .equ INT_SOURCE_USB_DSPI_TCF,29 // transfer complete interrupt + .equ INT_SOURCE_USB_DSPI_TFFF,30 // transfer FIFO fill interrupt + .equ INT_SOURCE_USB_DSPI_EOQF,31 // end of queue interrupt + .equ INT_SOURCE_PSC3,32 // PSC3 interrupt + .equ INT_SOURCE_PSC2,33 // PSC2 interrupt + .equ INT_SOURCE_PSC1,34 // PSC1 interrupt + .equ INT_SOURCE_PSC0,35 // PSC0 interrupt + .equ INT_SOURCE_CTIMERS,36 // combined source for comm timers + .equ INT_SOURCE_SEC,37 // SEC interrupt + .equ INT_SOURCE_FEC1,38 // FEC1 interrupt + .equ INT_SOURCE_FEC0,39 // FEC0 interrupt + .equ INT_SOURCE_I2C,40 // I2C interrupt + .equ INT_SOURCE_PCIARB,41 // PCI arbiter interrupt + .equ INT_SOURCE_CBPCI,42 // COMM bus PCI interrupt + .equ INT_SOURCE_XLBPCI,43 // XLB PCI interrupt + .equ INT_SOURCE_XLBARB,47 // XLBARB to PCI interrupt + .equ INT_SOURCE_DMA,48 // multichannel DMA interrupt + .equ INT_SOURCE_CAN0_ERROR,49 // FlexCAN error interrupt + .equ INT_SOURCE_CAN0_BUSOFF,50 // FlexCAN bus off interrupt + .equ INT_SOURCE_CAN0_MBOR,51 // message buffer ORed interrupt + .equ INT_SOURCE_SLT1,53 // slice timer 1 interrupt + .equ INT_SOURCE_SLT0,54 // slice timer 0 interrupt + .equ INT_SOURCE_CAN1_ERROR,55 // FlexCAN error interrupt + .equ INT_SOURCE_CAN1_BUSOFF,56 // FlexCAN bus off interrupt + .equ INT_SOURCE_CAN1_MBOR,57 // message buffer ORed interrupt + .equ INT_SOURCE_GPT3,59 // GPT3 timer interrupt + .equ INT_SOURCE_GPT2,60 // GPT2 timer interrupt + .equ INT_SOURCE_GPT1,61 // GPT1 timer interrupt + .equ INT_SOURCE_GPT0,62 // GPT0 timer interrupt // Atari register equates (provided by FPGA) - .equ vbasehi, 0xffff8201 + .equ vbasehi, 0xffff8201 /* * macros */ - .altmacro - .macro irq vector,int_mask,clr_int - move.w #0x2700,sr // disable interrupt - subq.l #8,sp - movem.l d0/a5,(sp) // save registers + .altmacro + .macro irq vector,int_mask,clr_int + move.w #0x2700,sr // disable interrupt + subq.l #8,sp + movem.l d0/a5,(sp) // save registers - lea MCF_EPORT_EPFR,a5 - move.b #\clr_int,(a5) // clear int pending + lea MCF_EPORT_EPFR,a5 + move.b #\clr_int,(a5) // clear int pending - movem.l (sp),d0/a5 // restore registers - addq.l #8,sp - move.l \vector,-(sp) - move #0x2\int_mask\()00,sr - rts - .endm + movem.l (sp),d0/a5 // restore registers + addq.l #8,sp + move.l \vector,-(sp) + move #0x2\int_mask\()00,sr + rts + .endm - .text + .text _vec_init: - move.l a2,-(sp) // Backup registers + move.l a2,-(sp) // Backup registers - mov3q.l #-1,_rt_mod // rt_mod auf super - clr.l _rt_ssp - clr.l _rt_usp - clr.l _rt_vbr - move.l #__RAMBAR0,d0 // exception vectors reside in rambar0 - movec d0,VBR - move.l d0,a0 - move.l a0,a2 + mov3q.l #-1,_rt_mod // rt_mod auf super + clr.l _rt_ssp + clr.l _rt_usp + clr.l _rt_vbr + move.l #__RAMBAR0,d0 // exception vectors reside in rambar0 + movec d0,VBR + move.l d0,a0 + move.l a0,a2 /* * first, set standard vector for all exceptions */ init_vec: - move.l #256,d0 - lea std_exc_vec(pc),a1 // standard vector + move.l #256,d0 + lea std_exc_vec(pc),a1 // standard vector init_vec_loop: - move.l a1,(a2)+ // set standard vector for all exceptions - subq.l #1,d0 - bne init_vec_loop + move.l a1,(a2)+ // set standard vector for all exceptions + subq.l #1,d0 + bne init_vec_loop - move.l #__SUP_SP,(a0) // set initial stack pointer at start of exception vector table + move.l #__SUP_SP,(a0) // set initial stack pointer at start of exception vector table - lea reset_vector(pc),a1 // set reset vector - move.l a1,0x04(a0) + lea reset_vector(pc),a1 // set reset vector + move.l a1,0x04(a0) - lea access(pc),a1 // set illegal access exception handler - move.l a1,0x08(a0) + lea access(pc),a1 // set illegal access exception handler + move.l a1,0x08(a0) // trap #0 (without any parameters for now) is used to provide BaS' driver addresses to the OS - lea _get_bas_drivers(pc),a1 - move.l a1,0x80(a0) // trap #0 exception vector + lea _get_bas_drivers(pc),a1 + move.l a1,0x80(a0) // trap #0 exception vector #ifdef MACHINE_FIREBEE // ACP interrupts 1-7 (user-defined, generated by FPGA on the FireBee, M5484LITE has irq7 and irq5 for PCI) - lea mfp_irq1(pc),a1 - move.l a1,0x104(a0) - lea mfp_irq2(pc),a1 - move.l a1,0x108(a0) - lea mfp_irq3(pc),a1 - move.l a1,0x10c(a0) - lea mfp_irq4(pc),a1 - move.l a1,0x110(a0) - lea mfp_irq5(pc),a1 - move.l a1,0x114(a0) - lea mfp_irq6(pc),a1 - move.l a1,0x118(a0) - lea mfp_irq7(pc),a1 - move.l a1,0x11c(a0) + lea mfp_irq1(pc),a1 + move.l a1,0x104(a0) + lea mfp_irq2(pc),a1 + move.l a1,0x108(a0) + lea mfp_irq3(pc),a1 + move.l a1,0x10c(a0) + lea mfp_irq4(pc),a1 + move.l a1,0x110(a0) + lea mfp_irq5(pc),a1 + move.l a1,0x114(a0) + lea mfp_irq6(pc),a1 + move.l a1,0x118(a0) + lea mfp_irq7(pc),a1 + move.l a1,0x11c(a0) // timer vectors (triggers when vbashi gets changed, used for video page copy) - lea handler_gpt0(pc),a1 - // GPT0 interrupt source = 62 - move.l a1,(INT_SOURCE_GPT0 + 64) * 4(a0) + lea handler_gpt0(pc),a1 + // GPT0 interrupt source = 62 + move.l a1,(INT_SOURCE_GPT0 + 64) * 4(a0) #endif /* MACHINE_FIREBEE */ // install lowlevel_isr_handler for the three GPT timers - lea _lowlevel_isr_handler(pc),a1 - move.l a1,(INT_SOURCE_GPT1 + 64) * 4(a0) - move.l a1,(INT_SOURCE_GPT2 + 64) * 4(a0) - move.l a1,(INT_SOURCE_GPT3 + 64) * 4(a0) + lea _lowlevel_isr_handler(pc),a1 + move.l a1,(INT_SOURCE_GPT1 + 64) * 4(a0) + move.l a1,(INT_SOURCE_GPT2 + 64) * 4(a0) + move.l a1,(INT_SOURCE_GPT3 + 64) * 4(a0) // install lowlevel_isr_handler for the FEC0 interrupt - move.l a1,(INT_SOURCE_FEC0 + 64) * 4(a0) + move.l a1,(INT_SOURCE_FEC0 + 64) * 4(a0) // install lowlevel_isr_handler for the PSC3 interrupt - move.l a1,(INT_SOURCE_PSC3 + 64) * 4(a0) + move.l a1,(INT_SOURCE_PSC3 + 64) * 4(a0) // install lowlevel_isr_handler for the XLBPCI interrupt - move.l a1,(INT_SOURCE_XLBPCI + 64) * 4(a0) + move.l a1,(INT_SOURCE_XLBPCI + 64) * 4(a0) #ifndef MACHINE_FIREBEE // FEC1 not wired on the FireBee, but used on other machines - move.l a1,(INT_SOURCE_FEC1 + 64) * 4(a0) + move.l a1,(INT_SOURCE_FEC1 + 64) * 4(a0) #endif // install lowlevel_isr_handler for DMA interrupts - move.l a1,(INT_SOURCE_DMA + 64) * 4(a0) + move.l a1,(INT_SOURCE_DMA + 64) * 4(a0) - move.l (sp)+,a2 // Restore registers - rts + move.l (sp)+,a2 // Restore registers + rts /* * exception vector routines */ vector_table_start: std_exc_vec: _std_exc_vec: - //move.w #0x2700,sr // disable interrupt - subq.l #8,sp - movem.l d0/a5,(sp) // save registers - move.w 8(sp),d0 // fetch vector - and.l #0x3fc,d0 // mask out vector number + //move.w #0x2700,sr // disable interrupt + subq.l #8,sp + movem.l d0/a5,(sp) // save registers + move.w 8(sp),d0 // fetch vector + and.l #0x3fc,d0 // mask out vector number #ifdef DBG_EXC - // printout vector number of exception + // printout vector number of exception - lea -4 * 4(sp),sp // reserve stack space - movem.l d0-d1/a0-a1,(sp) // save gcc scratch registers + lea -4 * 4(sp),sp // reserve stack space + movem.l d0-d1/a0-a1,(sp) // save gcc scratch registers - lsr.l #2,d0 // shift vector number in place - cmp.l #33,d0 - beq noprint - cmp.l #34,d0 - beq noprint - cmp.l #45,d0 - beq noprint - cmp.l #46,d0 - beq noprint - move.l 4 * 4 + 8 + 4(sp),-(sp) // pc at exception - move.l d0,-(sp) // provide it to xprintf() - pea exception_text - jsr _xprintf // call xprintf() - add.l #3*4,sp // adjust stack + lsr.l #2,d0 // shift vector number in place + cmp.l #33,d0 + beq noprint + cmp.l #34,d0 + beq noprint + cmp.l #45,d0 + beq noprint + cmp.l #46,d0 + beq noprint + move.l 4 * 4 + 8 + 4(sp),-(sp) // pc at exception + move.l d0,-(sp) // provide it to xprintf() + pea exception_text + jsr _xprintf // call xprintf() + add.l #3*4,sp // adjust stack noprint: - movem.l (sp),d0-d1/a0-a1 // restore registers - lea 4 * 4(sp),sp + movem.l (sp),d0-d1/a0-a1 // restore registers + lea 4 * 4(sp),sp #endif /* DBG_EXC */ - add.l _rt_vbr,d0 // + VBR - move.l d0,a5 - move.l (a5),d0 // fetch exception routine address + add.l _rt_vbr,d0 // + VBR + move.l d0,a5 + move.l (a5),d0 // fetch exception routine address - move.l 4(sp),a5 // restore a5 - move.l d0,4(sp) // store exception routine address + move.l 4(sp),a5 // restore a5 + move.l d0,4(sp) // store exception routine address - // FIXME: not clear why we would need the following? - //move.w 10(sp),d0 // restore original SR - //bset #13,d0 // set supervisor bit - //move.w d0,sr // - move.l (sp)+,d0 // restore d0 - rts // jump to exception handler + // FIXME: not clear why we would need the following? + //move.w 10(sp),d0 // restore original SR + //bset #13,d0 // set supervisor bit + //move.w d0,sr // + move.l (sp)+,d0 // restore d0 + rts // jump to exception handler exception_text: - .ascii "DEBUG: EXCEPTION %d caught at %p" - .byte 13, 10, 0 - .align 4 + .ascii "DEBUG: EXCEPTION %d caught at %p" + .byte 13, 10, 0 + .align 4 reset_vector: - move.w #0x2700,sr // disable interrupt - move.l #0x31415926,d0 - cmp.l 0x426,d0 // _resvalid: reset vector valid? - beq std_exc_vec // yes-> - jmp _rom_entry // no, cold start machine + move.w #0x2700,sr // disable interrupt + move.l #0x31415926,d0 + cmp.l 0x426,d0 // _resvalid: reset vector valid? + beq std_exc_vec // yes-> + jmp _rom_entry // no, cold start machine access: - move.w #0x2700,sr // disable interrupts + move.w #0x2700,sr // disable interrupts - link a6,#-4 * 4 // make room for gcc scratch registers - movem.l d0-d1/a0-a1,(sp) // save them + link a6,#-4 * 4 // make room for gcc scratch registers + movem.l d0-d1/a0-a1,(sp) // save them - move.l 4(a6),-(sp) // push format_status - move.l 8(a6),-(sp) // pc at exception - move.l MCF_MMU_MMUAR,-(sp) // MMU fault address - move.l MCF_MMU_MMUSR,-(sp) // MMU status regisrter - move.w #0x2300,sr // can lower interrupt mask now that MMU status is safe - jsr _mmutr_miss // call C routine - lea 4 * 4(sp),sp // adjust stack + move.l 4(a6),-(sp) // push format_status + move.l 8(a6),-(sp) // pc at exception + move.l MCF_MMU_MMUAR,-(sp) // MMU fault address + move.l MCF_MMU_MMUSR,-(sp) // MMU status regisrter + move.w #0x2300,sr // can lower interrupt mask now that MMU status is safe + jsr _mmutr_miss // call C routine + lea 4 * 4(sp),sp // adjust stack - tst.l d0 // exception handler signals bus error - bne bus_error + tst.l d0 // exception handler signals bus error + bne bus_error - movem.l (sp),d0-d1/a0-a1 // restore registers - unlk a6 - rte + movem.l (sp),d0-d1/a0-a1 // restore registers + unlk a6 + rte bus_error: - movem.l (sp),d0-d1/a0-a1 // restore registers - unlk a6 - bra std_exc_vec + movem.l (sp),d0-d1/a0-a1 // restore registers + unlk a6 + bra std_exc_vec zero_divide: - move.w #0x2700,sr // disable interrupt - move.l a0,-(sp) - move.l d0,-(sp) - move.l 12(sp),a0 // pc - move.w (a0)+,d0 // command word - btst #7,d0 // long? - beq zd_word // nein-> - addq.l #2,a0 + move.w #0x2700,sr // disable interrupt + move.l a0,-(sp) + move.l d0,-(sp) + move.l 12(sp),a0 // pc + move.w (a0)+,d0 // command word + btst #7,d0 // long? + beq zd_word // nein-> + addq.l #2,a0 zd_word: - and.l 0x3f,d0 // mask out ea field - cmp.w #0x08,d0 // -(ax) or less? - ble zd_end - addq.l #2,a0 - cmp.w #0x39,d0 // xxx.L - bne zd_nal - addq.l #2,a0 - bra zd_end + and.l 0x3f,d0 // mask out ea field + cmp.w #0x08,d0 // -(ax) or less? + ble zd_end + addq.l #2,a0 + cmp.w #0x39,d0 // xxx.L + bne zd_nal + addq.l #2,a0 + bra zd_end -zd_nal: cmp.w #0x3c,d0 // immediate? - bne zd_end // no-> - btst #7,d0 // long? - beq zd_end // no - addq.l #2,a0 +zd_nal: cmp.w #0x3c,d0 // immediate? + bne zd_end // no-> + btst #7,d0 // long? + beq zd_end // no + addq.l #2,a0 zd_end: - move.l a0,12(sp) - move.l (sp)+,d0 - move.l (sp)+,a0 - rte + move.l a0,12(sp) + move.l (sp)+,d0 + move.l (sp)+,a0 + rte #ifdef _NOT_USED_ linea: - move.w #0x2700,sr // disable interrupt - halt - nop - nop + move.w #0x2700,sr // disable interrupt + halt + nop + nop linef: - move.w #0x2700,sr // disable interrupt - halt - nop - nop + move.w #0x2700,sr // disable interrupt + halt + nop + nop format: - move.w #0x2700,sr // disable interrupt - halt - nop - nop + move.w #0x2700,sr // disable interrupt + halt + nop + nop //floating point flpoow: - move.w #0x2700,sr // disable interrupt - halt - nop - nop + move.w #0x2700,sr // disable interrupt + halt + nop + nop #endif /* _NOT_USED */ irq1: - irq 0x64,1,0x02 // IRQ1 + irq 0x64,1,0x02 // IRQ1 irq2: - irq 0x68,2,0x04 // IRQ2 + irq 0x68,2,0x04 // IRQ2 irq3: - irq 0x6c,3,0x08 // IRQ3 + irq 0x6c,3,0x08 // IRQ3 irq4: - irq 0x70,4,0x10 // IRQ4 + irq 0x70,4,0x10 // IRQ4 irq5: - irq 0x74,5,0x20 // IRQ5 + irq 0x74,5,0x20 // IRQ5 irq6: - irq 0x78,6,0x40 // IRQ6 + irq 0x78,6,0x40 // IRQ6 irq7: - irq 0x7c,7,0x80 // IRQ7 + irq 0x7c,7,0x80 // IRQ7 mfp_irq1: - irq 0x104,1,0x02 // IRQ1 + irq 0x104,1,0x02 // IRQ1 mfp_irq2: - irq 0x108,2,0x04 // IRQ2 + irq 0x108,2,0x04 // IRQ2 mfp_irq3: - irq 0x10c,3,0x08 // IRQ3 + irq 0x10c,3,0x08 // IRQ3 mfp_irq4: - irq 0x110,4,0x10 // IRQ4 + irq 0x110,4,0x10 // IRQ4 -#if MACHINE_M5484LITE_notyet // handlers for M5484LITE +#if MACHINE_M5484LITE_notyet // handlers for M5484LITE -irq5: // irq5 is tied to PCI INTC# and PCI INTD# on the M5484LITE - move.w #0x2700,sr // disable interrupts +irq5: // irq5 is tied to PCI INTC# and PCI INTD# on the M5484LITE + move.w #0x2700,sr // disable interrupts - lea -4*4(sp),sp // save gcc scratch registers - movem.l d0-d1/a0-a1,(sp) + lea -4*4(sp),sp // save gcc scratch registers + movem.l d0-d1/a0-a1,(sp) - jsr _irq5_handler // call C handler routine + jsr _irq5_handler // call C handler routine - movem.l (sp),d0-d1/a0-a1 // restore registers - lea 4*4(sp),sp + movem.l (sp),d0-d1/a0-a1 // restore registers + lea 4*4(sp),sp - rte // return from exception + rte // return from exception irq5text: - .ascii "IRQ5!" - .dc.b 13,10,0 + .ascii "IRQ5!" + .dc.b 13,10,0 mfp_irq6: - irq 0x74,5,0x20 + irq 0x74,5,0x20 -mfp_irq7: // irq7 is tied to PCI INTA# and PCI INTB# on the M5484LITE +mfp_irq7: // irq7 is tied to PCI INTA# and PCI INTB# on the M5484LITE - move.w #0x2700,sr // disable interrupts + move.w #0x2700,sr // disable interrupts - lea -4*4(sp),sp // save gcc scratch registers - movem.l d0-d1/a0-a1,(sp) + lea -4*4(sp),sp // save gcc scratch registers + movem.l d0-d1/a0-a1,(sp) - jsr _irq7_handler // call C handler routine + jsr _irq7_handler // call C handler routine - movem.l (sp),d0-d1/a0-a1 // restore registers - lea 4*4(sp),sp + movem.l (sp),d0-d1/a0-a1 // restore registers + lea 4*4(sp),sp - rte // return from exception + rte // return from exception irq7text: - .data - .ascii "IRQ7!" - .dc.b 13,10,0 - .text + .data + .ascii "IRQ7!" + .dc.b 13,10,0 + .text -#elif MACHINE_FIREBEE /* these handlers are only meaningful for the Firebee */ -mfp_irq5: move.w #0x2700,sr // disable interrupts - subq.l #4,sp // extra space +#elif MACHINE_FIREBEE /* these handlers are only meaningful for the Firebee */ +mfp_irq5: move.w #0x2700,sr // disable interrupts + subq.l #4,sp // extra space - link a6,#-4 * 4 // save gcc scratch registers - movem.l d0-d1/a0-a1,(sp) + link a6,#-4 * 4 // save gcc scratch registers + movem.l d0-d1/a0-a1,(sp) - jsr _irq5_handler // call C handler routine + jsr _irq5_handler // call C handler routine - tst.l d0 // handled? - bne irq5_forward + tst.l d0 // handled? + bne irq5_forward - movem.l (sp),d0-d1/a0-a1 // restore registers - unlk a6 - addq.l #4,sp + movem.l (sp),d0-d1/a0-a1 // restore registers + unlk a6 + addq.l #4,sp - rte // return from exception + rte // return from exception -irq5_forward: move.l 0x74,a0 // fetch OS irq5 vector - add.l _rt_vbr,a0 // add runtime vbr - move.l a0,4(a6) // put on stack +irq5_forward: move.l 0x74,a0 // fetch OS irq5 vector + add.l _rt_vbr,a0 // add runtime vbr + move.l a0,4(a6) // put on stack - movem.l (sp),d0-d1/a0-a1 // restore registers - unlk a6 // - move.w #0x2500,sr // set interrupt level - rts // jump through vector + movem.l (sp),d0-d1/a0-a1 // restore registers + unlk a6 // + move.w #0x2500,sr // set interrupt level + rts // jump through vector #ifdef _NOT_USED_ -mfp_irq6: move.w #0x2700,sr // disable interrupt - subq.l #4,sp // extra space - link a6,#-4 * 4 // save gcc scratch registers - movem.l d0-d1/a0-a1,(sp) +mfp_irq6: move.w #0x2700,sr // disable interrupt + subq.l #4,sp // extra space + link a6,#-4 * 4 // save gcc scratch registers + movem.l d0-d1/a0-a1,(sp) - move.l 4(a6),-(sp) // format status word - move.l 8(a6),-(sp) // pc at exception - jsr _irq6_handler // call C handler - lea 8(sp),sp // fix stack + move.l 4(a6),-(sp) // format status word + move.l 8(a6),-(sp) // pc at exception + jsr _irq6_handler // call C handler + lea 8(sp),sp // fix stack - tst.l d0 // interrupt handled? - bne irq6_forward // no, forward to TOS + tst.l d0 // interrupt handled? + bne irq6_forward // no, forward to TOS - movem.l (sp),d0-d1/a0-a1 // restore registers - unlk a6 - addq.l #4,sp // "extra space" not needed in this case - rte + movem.l (sp),d0-d1/a0-a1 // restore registers + unlk a6 + addq.l #4,sp // "extra space" not needed in this case + rte mfp_irq6_forward: - move.l 0xf0020000,a0 // fetch FPGA "autovector" - add.l _rt_vbr,a0 // add runtime VBR - move.l (a0),4(a6) // fetch handler address and put it on "extra space" + move.l 0xf0020000,a0 // fetch FPGA "autovector" + add.l _rt_vbr,a0 // add runtime VBR + move.l (a0),4(a6) // fetch handler address and put it on "extra space" - movem.l (sp),d0-d1/a0-a1 - unlk a6 - move.w #0x2600,sr // set interrupt level + movem.l (sp),d0-d1/a0-a1 + unlk a6 + move.w #0x2600,sr // set interrupt level - rts // jump through vector + rts // jump through vector #else /* _NOT_USED_ */ - // this is the old code from Fredi + // this is the old code from Fredi mfp_irq6: - // MFP interrupt from FPGA - move.w #0x2700,sr // disable interrupt - subq.l #8,sp - movem.l d0/a5,(sp) // save registers + // MFP interrupt from FPGA + move.w #0x2700,sr // disable interrupt + subq.l #8,sp + movem.l d0/a5,(sp) // save registers - lea MCF_EPORT_EPFR,a5 // clear int6 from edge port - bset #6,(a5) + lea MCF_EPORT_EPFR,a5 // clear int6 from edge port + bset #6,(a5) mfp_irq6_non_sca: // test auf acsi dma ----------------------------------------------------------------- - lea 0xfffffa0b,a5 - bset #7,-4(a5) // int ena - btst.b #7,(a5) // acsi dma int? - beq mfp_non_acsi_dma - bsr acsi_dma + lea 0xfffffa0b,a5 + bset #7,-4(a5) // int ena + btst.b #7,(a5) // acsi dma int? + beq mfp_non_acsi_dma + bsr acsi_dma mfp_non_acsi_dma: // ---------------------------------------------------------------------------------- - tst.b (a5) - bne mfp_irq6_1 - tst.b 2(a5) - bne mfp_irq6_1 - movem.l (sp),d0/a5 - addq.l #8,sp - rte + tst.b (a5) + bne mfp_irq6_1 + tst.b 2(a5) + bne mfp_irq6_1 + movem.l (sp),d0/a5 + addq.l #8,sp + rte mfp_irq6_1: - lea MCF_GPIO_PODR_FEC1L,a5 - bclr.b #4,(a5) // led on - lea blinker,a5 - addq.l #1,(a5) // +1 - move.l (a5),d0 - and.l #0x80,d0 - bne mfp_irq6_2 - lea MCF_GPIO_PODR_FEC1L,a5 - bset.b #4,(a5) // led off + lea MCF_GPIO_PODR_FEC1L,a5 + bclr.b #4,(a5) // led on + lea blinker,a5 + addq.l #1,(a5) // +1 + move.l (a5),d0 + and.l #0x80,d0 + bne mfp_irq6_2 + lea MCF_GPIO_PODR_FEC1L,a5 + bset.b #4,(a5) // led off /* * Firebee inthandler. 0xf0020000 delivers the interrupt vector @@ -569,78 +569,84 @@ mfp_irq6_1: */ mfp_irq6_2: - move.l 0xF0020000,a5 // vector holen - add.l _rt_vbr,a5 // basis - move.l (a5),d0 // vector holen - move.l 4(sp),a5 // a5 zurück - move.l d0,4(sp) // vector eintragen - move.l (sp)+,d0 // d0 zurück - move #0x2600,sr - rts + move.l 0xF0020000,a5 // vector holen + add.l _rt_vbr,a5 // basis + move.l (a5),d0 // vector holen + move.l 4(sp),a5 // a5 zurück + move.l d0,4(sp) // vector eintragen + move.l (sp)+,d0 // d0 zurück + move #0x2600,sr + rts - .data -blinker:.long 0 + .data +blinker:.long 0 - .text + .text /* * pseudo dma */ -acsi_dma: // atari dma - move.l a1,-(sp) - move.l d1,-(sp) +acsi_dma: // atari dma + move.l a1,-(sp) + move.l d1,-(sp) - lea 0xf0020110,a5 // fifo daten + //lea MCF_PSC0_PSCTB_8BIT,a1 // ++ vr + // mchar move.l, 'D,'M','A,'\ ,(a1) + //move.l #"DMA ",(a1) + // mchar move.l,'I,'N,'T,'!,(a1) + // move.l #'INT!',(a1) + + lea 0xf0020110,a5 // fifo daten acsi_dma_start: - move.l -12(a5),a1 // dma adresse - move.l -8(a5),d0 // byt counter - ble acsi_dma_end - btst.b #0,-16(a5) // write? (dma modus reg) - bne acsi_dma_wl // ja-> + move.l -12(a5),a1 // dma adresse + move.l -8(a5),d0 // byt counter + ble acsi_dma_end + btst.b #0,-16(a5) // write? (dma modus reg) + bne acsi_dma_wl // ja-> acsi_dma_rl: - tst.b -4(a5) // dma req? - bpl acsi_dma_finished // nein-> - move.l (a5),(a1)+ // read 4 bytes - move.l (a5),(a1)+ // read 4 bytes - move.l (a5),(a1)+ // read 4 bytes - move.l (a5),(a1)+ // read 4 bytes + tst.b -4(a5) // dma req? + bpl acsi_dma_finished // nein-> + move.l (a5),(a1)+ // read 4 bytes + move.l (a5),(a1)+ // read 4 bytes + move.l (a5),(a1)+ // read 4 bytes + move.l (a5),(a1)+ // read 4 bytes - moveq #'.',d1 - move.b d1,MCF_PSC0_PSCTB_8BIT + moveq #'.',d1 + move.b d1,MCF_PSC0_PSCTB_8BIT - sub.l #16,d0 // byt counter -16 - bpl acsi_dma_rl - bra acsi_dma_finished + sub.l #16,d0 // byt counter -16 + bpl acsi_dma_rl + bra acsi_dma_finished acsi_dma_wl: - tst.b -4(a5) // dma req? - bpl acsi_dma_finished // nein-> - move.l (a1)+,(a5) // write 4 byts - move.l (a1)+,(a5) // write 4 byts - move.l (a1)+,(a5) // write 4 byts - move.l (a1)+,(a5) // write 4 byts + tst.b -4(a5) // dma req? + bpl acsi_dma_finished // nein-> + move.l (a1)+,(a5) // write 4 byts + move.l (a1)+,(a5) // write 4 byts + move.l (a1)+,(a5) // write 4 byts + move.l (a1)+,(a5) // write 4 byts - moveq #'.',d1 - move.b d1,MCF_PSC0_PSCTB_8BIT + moveq #'.',d1 + move.b d1,MCF_PSC0_PSCTB_8BIT - sub.l #16,d0 // byt counter -16 - bpl acsi_dma_wl + sub.l #16,d0 // byt counter -16 + bpl acsi_dma_wl acsi_dma_finished: - move.l a1,-12(a5) // adresse zur�ck - move.l d0,-8(a5) // byt counter zur�ck + move.l a1,-12(a5) // adresse zur�ck + move.l d0,-8(a5) // byt counter zur�ck acsi_dma_end: - tst.b -4(a5) // dma req? - bmi acsi_dma_start // ja-> - lea 0xfffffa0b,a5 - bclr.b #7,4(a5) // clear int in service mfp - bclr.b #7,(a5) // clear int pending mfp 0xfffffa0b + tst.b -4(a5) // dma req? + bmi acsi_dma_start // ja-> + lea 0xfffffa0b,a5 + bclr.b #7,4(a5) // clear int in service mfp + bclr.b #7,(a5) // clear int pending mfp 0xfffffa0b - move.w #0x0d0a,d1 - move.w d1,MCF_PSC0_PSCTB_8BIT + move.w #0x0d0a,d1 + move.w d1,MCF_PSC0_PSCTB_8BIT - move.l (sp)+,d1 - move.l (sp)+,a1 - rts + move.l (sp)+,d1 + move.l (sp)+,a1 + rts #endif /* _NOT_USED_ */ @@ -648,26 +654,26 @@ acsi_dma_end: * irq 7 = pseudo bus error */ mfp_irq7: - lea -12(sp),sp - movem.l d0/a0,(sp) + lea -12(sp),sp + movem.l d0/a0,(sp) - move.l __RAMBAR0+0x008,a0 // real access error handler - move.l a0,8(sp) // this will be the return address for rts + move.l __RAMBAR0+0x008,a0 // real access error handler + move.l a0,8(sp) // this will be the return address for rts - move.w 12(sp),d0 // format/vector word - andi.l #0xf000,d0 // keep only the format - ori.l #2*4,d0 // simulate vector #2, no fault - move.w d0,12(sp) + move.w 12(sp),d0 // format/vector word + andi.l #0xf000,d0 // keep only the format + ori.l #2*4,d0 // simulate vector #2, no fault + move.w d0,12(sp) - // TODO: Inside an interrupt handler, 16(sp) is the return address. - // For an Access Error, it should be the address of the fault instruction instead + // TODO: Inside an interrupt handler, 16(sp) is the return address. + // For an Access Error, it should be the address of the fault instruction instead - lea MCF_EPORT_EPFR,a0 - bset #7,(a0) // clear int 7 + lea MCF_EPORT_EPFR,a0 + bset #7,(a0) // clear int 7 - move.l (sp)+,d0 // restore registers - move.l (sp)+,a0 - rts // Forward to the Access Error handler + move.l (sp)+,d0 // restore registers + move.l (sp)+,a0 + rts // Forward to the Access Error handler /* @@ -679,45 +685,45 @@ mfp_irq7: */ handler_gpt0: - .extern _gpt0_interrupt_handler + .extern _gpt0_interrupt_handler - move.w #0x2700,sr // disable interrupts - link a6,#-4 * 4 // make room for - movem.l d0-d1/a0-a1,(sp) // gcc scratch registers and save them, - // other registers will be handled by gcc itself + move.w #0x2700,sr // disable interrupts + link a6,#-4 * 4 // make room for + movem.l d0-d1/a0-a1,(sp) // gcc scratch registers and save them, + // other registers will be handled by gcc itself - move.w 4(a6),d0 // fetch vector number from stack - move.l d0,-(sp) // push it - jsr _gpt0_interrupt_handler // call C handler - addq.l #4,sp // adjust stack + move.w 4(a6),d0 // fetch vector number from stack + move.l d0,-(sp) // push it + jsr _gpt0_interrupt_handler // call C handler + addq.l #4,sp // adjust stack - movem.l (sp),d0-d1/a0-a1 // restore registers + movem.l (sp),d0-d1/a0-a1 // restore registers - unlk a6 - rte + unlk a6 + rte #endif /* MACHINE_FIREBEE */ /* * low-level interrupt service routine for routines registered with * isr_register_handler() */ - .global _lowlevel_isr_handler - .extern _isr_execute_handler + .global _lowlevel_isr_handler + .extern _isr_execute_handler _lowlevel_isr_handler: - move.w #0x2700,sr // do not disturb - link a6,#-4 * 4 // make room for - movem.l d0-d1/a0-a1,(sp) // gcc scratch registers and save them, - // other registers will be handled by gcc itself + move.w #0x2700,sr // do not disturb + link a6,#-4 * 4 // make room for + movem.l d0-d1/a0-a1,(sp) // gcc scratch registers and save them, + // other registers will be handled by gcc itself - move.w 4(a6),d0 // fetch vector number from stack - lsr.l #2,d0 // move it in place - andi.l #0xff,d0 // mask it out - move.l d0,-(sp) // push it - jsr _isr_execute_handler // call the C handler - addq.l #4,sp // adjust stack + move.w 4(a6),d0 // fetch vector number from stack + lsr.l #2,d0 // move it in place + andi.l #0xff,d0 // mask it out + move.l d0,-(sp) // push it + jsr _isr_execute_handler // call the C handler + addq.l #4,sp // adjust stack - movem.l (sp),d0-d1/a0-a1 // restore registers - unlk a6 - rte + movem.l (sp),d0-d1/a0-a1 // restore registers + unlk a6 + rte diff --git a/BaS_gcc/sys/init_fpga.c b/BaS_gcc/sys/init_fpga.c index b7c785b..2b8b041 100644 --- a/BaS_gcc/sys/init_fpga.c +++ b/BaS_gcc/sys/init_fpga.c @@ -34,54 +34,57 @@ #define dbg(format, arg...) do { ; } while (0) #endif -#define FPGA_STATUS (1 << 0) -#define FPGA_CLOCK (1 << 1) -#define FPGA_CONFIG (1 << 2) -#define FPGA_DATA0 (1 << 3) -#define FPGA_CONF_DONE (1 << 5) +#define FPGA_STATUS (1 << 0) +#define FPGA_CLOCK (1 << 1) +#define FPGA_CONFIG (1 << 2) +#define FPGA_DATA0 (1 << 3) +#define FPGA_CONF_DONE (1 << 5) extern uint8_t _FPGA_CONFIG[]; -#define FPGA_FLASH_DATA &_FPGA_CONFIG[0] +#define FPGA_FLASH_DATA &_FPGA_CONFIG[0] extern uint8_t _FPGA_CONFIG_SIZE[]; -#define FPGA_FLASH_DATA_SIZE ((uint32_t) &_FPGA_CONFIG_SIZE[0]) +#define FPGA_FLASH_DATA_SIZE ((uint32_t) &_FPGA_CONFIG_SIZE[0]) /* * flag located in processor SRAM1 that indicates that the FPGA configuration has - * been loaded through JTAG. init_fpga() will honour this and not overwrite config. + * been loaded through the onboard JTAG interface. + * init_fpga() will honour this and not overwrite config. */ extern bool _FPGA_JTAG_LOADED; extern long _FPGA_JTAG_VALID; -#define VALID_JTAG 0xaffeaffe +#define VALID_JTAG 0xaffeaffe +extern int32_t _FPGA_JTAG_VALID; +#define VALID_JTAG 0xaffeaffe void config_gpio_for_fpga_config(void) { #if defined(MACHINE_FIREBEE) - /* - * Configure GPIO FEC1L port directions (needed to load FPGA configuration) - */ - MCF_GPIO_PDDR_FEC1L = 0 | /* bit 7 = input */ - 0 | /* bit 6 = input */ - 0 | /* bit 5 = input */ - MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L4 | /* bit 4 = LED => output */ - MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L3 | /* bit 3 = PRG_DQ0 => output */ - MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L2 | /* bit 2 = FPGA_CONFIG => output */ - MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L1 | /* bit 1 = PRG_CLK (FPGA) => output */ - 0; /* bit 0 => input */ + /* + * Configure GPIO FEC1L port directions (needed to load FPGA configuration) + */ + MCF_GPIO_PDDR_FEC1L = 0 | /* bit 7 = input */ + 0 | /* bit 6 = input */ + 0 | /* bit 5 = input */ + MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L4 | /* bit 4 = LED => output */ + MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L3 | /* bit 3 = PRG_DQ0 => output */ + MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L2 | /* bit 2 = FPGA_CONFIG => output */ + MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L1 | /* bit 1 = PRG_CLK (FPGA) => output */ + 0; /* bit 0 => input */ #endif /* MACHINE_FIREBEE */ } void config_gpio_for_jtag_config(void) { - /* - * configure FEC1L port directions to enable external JTAG configuration download to FPGA - */ - MCF_GPIO_PDDR_FEC1L = 0 | - MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L4; /* bit 4 = LED => output */ - /* all other bits = input */ - /* - * unfortunately, the GPIO module cannot trigger interrupts. That means CONF_DONE needs to be polled to detect - * external FPGA (re)configuration and reset the system in that case. Could be done from the OS as well... - */ + /* + * configure FEC1L port directions to enable external JTAG configuration download to FPGA + */ + MCF_GPIO_PDDR_FEC1L = 0 | + MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L4; /* bit 4 = LED => output */ + /* all other bits = input */ + /* + * unfortunately, the GPIO module cannot trigger interrupts. That means CONF_DONE needs to be polled to detect + * external FPGA (re)configuration and reset the system in that case. Could be done from the OS as well... + */ } /* @@ -89,96 +92,100 @@ void config_gpio_for_jtag_config(void) */ bool init_fpga(void) { - uint8_t *fpga_data; - volatile int32_t time, start, end; - int i; + uint8_t *fpga_data; + volatile int32_t time, start, end; + int i; - dbg("FPGA load config\r\n(_FPGA_JTAG_LOADED = %x, _FPGA_JTAG_VALID = %x)...\r\n", _FPGA_JTAG_LOADED, _FPGA_JTAG_VALID); - if (_FPGA_JTAG_LOADED == true && _FPGA_JTAG_VALID == VALID_JTAG) - { - dbg("detected _FPGA_JTAG_LOADED flag. Not overwriting FPGA config.\r\n"); + dbg("FPGA load config\r\n(_FPGA_JTAG_LOADED = %x, _FPGA_JTAG_VALID = %x)...\r\n", _FPGA_JTAG_LOADED, _FPGA_JTAG_VALID); + if (_FPGA_JTAG_LOADED == true && _FPGA_JTAG_VALID == VALID_JTAG) + { + dbg("detected _FPGA_JTAG_LOADED flag. Not overwriting FPGA config.\r\n"); - /* reset the flag so that next boot will load config again from flash */ - _FPGA_JTAG_LOADED = 0; - return true; - } - start = MCF_SLT0_SCNT; + /* reset the flag so that next boot will load config again from flash */ + _FPGA_JTAG_LOADED = 0; + _FPGA_JTAG_VALID = 0; - config_gpio_for_fpga_config(); - MCF_GPIO_PODR_FEC1L &= ~FPGA_CLOCK; /* FPGA clock => low */ + return true; + } + start = MCF_SLT0_SCNT; - /* pulling FPGA_CONFIG to low resets the FPGA */ - MCF_GPIO_PODR_FEC1L &= ~FPGA_CONFIG; /* FPGA config => low */ - wait(10); /* give it some time to do its reset stuff */ + config_gpio_for_fpga_config(); + MCF_GPIO_PODR_FEC1L &= ~FPGA_CLOCK; /* FPGA clock => low */ - while ((MCF_GPIO_PPDSDR_FEC1L & FPGA_STATUS) && (MCF_GPIO_PPDSDR_FEC1L & FPGA_CONF_DONE)); + /* pulling FPGA_CONFIG to low resets the FPGA */ + MCF_GPIO_PODR_FEC1L &= ~FPGA_CONFIG; /* FPGA config => low */ + wait(10); /* give it some time to do its reset stuff */ - MCF_GPIO_PODR_FEC1L |= FPGA_CONFIG; /* pull FPGA_CONFIG high to start config cycle */ - while (!(MCF_GPIO_PPDSDR_FEC1L & FPGA_STATUS)); /* wait until status becomes high */ + while ((MCF_GPIO_PPDSDR_FEC1L & FPGA_STATUS) && (MCF_GPIO_PPDSDR_FEC1L & FPGA_CONF_DONE)); - /* - * excerpt from an Altera configuration manual: - * - * The low-to-high transition of nCONFIG on the FPGA begins the configuration cycle. The - * configuration cycle consists of 3 stages�reset, configuration, and initialization. - * While nCONFIG is low, the device is in reset. When the device comes out of reset, - * nCONFIG must be at a logic high level in order for the device to release the open-drain - * nSTATUS pin. After nSTATUS is released, it is pulled high by a pull-up resistor and the FPGA - * is ready to receive configuration data. Before and during configuration, all user I/O pins - * are tri-stated. Stratix series, Arria series, and Cyclone series have weak pull-up resistors - * on the I/O pins which are on, before and during configuration. - * - * To begin configuration, nCONFIG and nSTATUS must be at a logic high level. You can delay - * configuration by holding the nCONFIG low. The device receives configuration data on its - * DATA0 pins. Configuration data is latched into the FPGA on the rising edge of DCLK. After - * the FPGA has received all configuration data successfully, it releases the CONF_DONE pin, - * which is pulled high by a pull-up resistor. A low to high transition on CONF_DONE indicates - * configuration is complete and initialization of the device can begin. - */ + MCF_GPIO_PODR_FEC1L |= FPGA_CONFIG; /* pull FPGA_CONFIG high to start config cycle */ + while (!(MCF_GPIO_PPDSDR_FEC1L & FPGA_STATUS)) + ; /* wait until status becomes high */ - const uint8_t *fpga_flash_data_end = FPGA_FLASH_DATA + FPGA_FLASH_DATA_SIZE; + /* + * excerpt from an Altera configuration manual: + * + * The low-to-high transition of nCONFIG on the FPGA begins the configuration cycle. The + * configuration cycle consists of 3 stages�reset, configuration, and initialization. + * While nCONFIG is low, the device is in reset. When the device comes out of reset, + * nCONFIG must be at a logic high level in order for the device to release the open-drain + * nSTATUS pin. After nSTATUS is released, it is pulled high by a pull-up resistor and the FPGA + * is ready to receive configuration data. Before and during configuration, all user I/O pins + * are tri-stated. Stratix series, Arria series, and Cyclone series have weak pull-up resistors + * on the I/O pins which are on, before and during configuration. + * + * To begin configuration, nCONFIG and nSTATUS must be at a logic high level. You can delay + * configuration by holding the nCONFIG low. The device receives configuration data on its + * DATA0 pins. Configuration data is latched into the FPGA on the rising edge of DCLK. After + * the FPGA has received all configuration data successfully, it releases the CONF_DONE pin, + * which is pulled high by a pull-up resistor. A low to high transition on CONF_DONE indicates + * configuration is complete and initialization of the device can begin. + */ - fpga_data = (uint8_t *) FPGA_FLASH_DATA; - do - { - uint8_t value = *fpga_data++; - for (i = 0; i < 8; i++, value >>= 1) - { + const uint8_t *fpga_flash_data_end = FPGA_FLASH_DATA + FPGA_FLASH_DATA_SIZE; - if (value & 1) - { - /* bit set -> toggle DATA0 to high */ - MCF_GPIO_PODR_FEC1L |= FPGA_DATA0; - } - else - { - /* bit is cleared -> toggle DATA0 to low */ - MCF_GPIO_PODR_FEC1L &= ~FPGA_DATA0; - } - /* toggle DCLK -> FPGA reads the bit */ - MCF_GPIO_PODR_FEC1L |= FPGA_CLOCK; - MCF_GPIO_PODR_FEC1L &= ~FPGA_CLOCK; - } - } while ((!(MCF_GPIO_PPDSDR_FEC1L & FPGA_CONF_DONE)) && (fpga_data < fpga_flash_data_end)); + fpga_data = (uint8_t *) FPGA_FLASH_DATA; + do + { + uint8_t value = *fpga_data++; + for (i = 0; i < 8; i++, value >>= 1) + { - if (fpga_data < fpga_flash_data_end) - { + if (value & 1) + { + /* bit set -> toggle DATA0 to high */ + MCF_GPIO_PODR_FEC1L |= FPGA_DATA0; + } + else + { + /* bit is cleared -> toggle DATA0 to low */ + MCF_GPIO_PODR_FEC1L &= ~FPGA_DATA0; + } + /* toggle DCLK -> FPGA reads the bit */ + MCF_GPIO_PODR_FEC1L |= FPGA_CLOCK; + MCF_GPIO_PODR_FEC1L &= ~FPGA_CLOCK; + } + } while ((!(MCF_GPIO_PPDSDR_FEC1L & FPGA_CONF_DONE)) && (fpga_data < fpga_flash_data_end)); + + if (fpga_data < fpga_flash_data_end) + { #ifdef _NOT_USED_ - while (fpga_data++ < fpga_flash_data_end) - { - /* toggle a little more since it's fun ;) */ - MCF_GPIO_PODR_FEC1L |= FPGA_CLOCK; - MCF_GPIO_PODR_FEC1L &= ~FPGA_CLOCK; - } + while (fpga_data++ < fpga_flash_data_end) + { + /* toggle a little more since it's fun ;) */ + MCF_GPIO_PODR_FEC1L |= FPGA_CLOCK; + MCF_GPIO_PODR_FEC1L &= ~FPGA_CLOCK; + } #endif /* _NOT_USED_ */ - end = MCF_SLT0_SCNT; - time = (start - end) / (SYSCLK / 1000) / 1000; + end = MCF_SLT0_SCNT; + time = (start - end) / (SYSCLK / 1000) / 1000; - xprintf("finished (took %f seconds).\r\n", time / 1000.0); - config_gpio_for_jtag_config(); - return true; - } - xprintf("FAILED!\r\n"); - config_gpio_for_jtag_config(); - return false; + xprintf("finished (took %f seconds).\r\n", time / 1000.0); + config_gpio_for_jtag_config(); + return true; + } + xprintf("FAILED!\r\n"); + config_gpio_for_jtag_config(); + + return false; }