From 5163fd58134b8da9c62481b6574c93cbffead4d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Fr=C3=B6schle?= Date: Wed, 6 Aug 2014 06:25:41 +0000 Subject: [PATCH 1/3] file release to officially support m548x with EmuTOS From 88c1bd2373c635f75a42119318289c428ea59676 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Fr=C3=B6schle?= Date: Fri, 26 Dec 2014 07:26:10 +0000 Subject: [PATCH 2/3] fixed errornous deactivation of FPGA load --- bas.lk.in | 2 + sys/init_fpga.c | 206 +++++++++++++++++++++++++----------------------- 2 files changed, 108 insertions(+), 100 deletions(-) diff --git a/bas.lk.in b/bas.lk.in index 1f3adef..86fc4b4 100644 --- a/bas.lk.in +++ b/bas.lk.in @@ -236,6 +236,8 @@ SECTIONS * and shouldn't be overwritten on boot */ __FPGA_JTAG_LOADED = __RAMBAR1; + __FPGA_JTAG_VALID = __FPGA_JTAG_LOADED + 4; + /* system variables */ /* RAMBAR0 0 to 0x7FF -> exception vectors */ diff --git a/sys/init_fpga.c b/sys/init_fpga.c index f9cc33c..14b37eb 100644 --- a/sys/init_fpga.c +++ b/sys/init_fpga.c @@ -40,39 +40,42 @@ extern uint8_t _FPGA_CONFIG_SIZE[]; /* * 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 int32_t _FPGA_JTAG_LOADED; +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 FPGA_CONFIG 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 FPGA_CONFIG 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... + */ } /* @@ -80,96 +83,99 @@ 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; - xprintf("FPGA load config (_FPGA_JTAG_LOADED = %x)...", _FPGA_JTAG_LOADED); - if (_FPGA_JTAG_LOADED == 1) - { - xprintf("detected _FPGA_JTAG_LOADED flag. Not overwriting FPGA config.\r\n"); + xprintf("FPGA load config (_FPGA_JTAG_LOADED = %x, _FPGA_JTAG_VALID = %x)...", _FPGA_JTAG_LOADED, _FPGA_JTAG_VALID); + if (_FPGA_JTAG_LOADED == 1 && _FPGA_JTAG_VALID == VALID_JTAG) + { + xprintf("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; - 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; } From f8717947603142b4d91ad5f4491862d08cae8cb8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Fr=C3=B6schle?= Date: Fri, 26 Dec 2014 08:56:30 +0000 Subject: [PATCH 3/3] fixed bug that prevented proper detection of FPGA load skip request --- bas.lk.in | 372 ++++++------ if/driver_vec.c | 281 +++++---- include/driver_vec.h | 229 ++++---- net/fecbd.c | 194 +++---- net/ip.c | 448 +++++++------- net/udp.c | 190 +++--- sys/exceptions.S | 1317 +++++++++++++++++++++--------------------- sys/init_fpga.c | 4 +- 8 files changed, 1547 insertions(+), 1488 deletions(-) diff --git a/bas.lk.in b/bas.lk.in index 86fc4b4..d5df5bd 100644 --- a/bas.lk.in +++ b/bas.lk.in @@ -19,244 +19,244 @@ 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_mouse.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_mouse.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 = __FPGA_JTAG_LOADED + 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 = __FPGA_JTAG_LOADED + 4; - /* system variables */ + /* 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 */ + /* 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/if/driver_vec.c b/if/driver_vec.c index 1d94e03..5ba0f8b 100644 --- a/if/driver_vec.c +++ b/if/driver_vec.c @@ -23,21 +23,21 @@ * Author: Markus Fröschle */ -#include -#include +#include #include "version.h" #include "xhdi_sd.h" #include "dma.h" #include "driver_vec.h" #include "driver_mem.h" #include "pci.h" +#include "mmu.h" /* * driver interface struct for the SD card BaS driver */ -static struct xhdi_driver_interface xhdi_call_interface = +static struct xhdi_driver_interface xhdi_call_interface = { - xhdi_call + xhdi_call }; /* @@ -47,79 +47,81 @@ static struct xhdi_driver_interface xhdi_call_interface = */ static struct dma_driver_interface dma_interface = { - .version = 0x0101, - .magic = 0x444d4143, /* 'DMAC' */ - .dma_set_initiator = dma_set_initiator, - .dma_get_initiator = dma_get_initiator, - .dma_free_initiator = dma_free_initiator, - .dma_set_channel = dma_set_channel, - .dma_get_channel = dma_get_channel, - .dma_free_channel = dma_free_channel, - .dma_clear_channel = dma_clear_channel, - .MCD_startDma = MCD_startDma, - .MCD_dmaStatus = MCD_dmaStatus, - .MCD_XferProgrQuery = MCD_XferProgrQuery, - .MCD_killDma = MCD_killDma, - .MCD_continDma = MCD_continDma, - .MCD_pauseDma = MCD_pauseDma, - .MCD_resumeDma = MCD_resumeDma, - .MCD_csumQuery = MCD_csumQuery, - .dma_malloc = driver_mem_alloc, - .dma_free = driver_mem_free + .version = 0x0101, + .magic = 0x444d4143, /* 'DMAC' */ + .dma_set_initiator = dma_set_initiator, + .dma_get_initiator = dma_get_initiator, + .dma_free_initiator = dma_free_initiator, + .dma_set_channel = dma_set_channel, + .dma_get_channel = dma_get_channel, + .dma_free_channel = dma_free_channel, + .dma_clear_channel = dma_clear_channel, + .MCD_startDma = (int (*)(long, int8_t *, unsigned int, int8_t *, unsigned int, + unsigned int, unsigned int, unsigned int, int, + unsigned int, unsigned int)) MCD_startDma, + .MCD_dmaStatus = (int32_t (*)(int32_t)) MCD_dmaStatus, + .MCD_XferProgrQuery = (int32_t (*)(int32_t, MCD_XferProg *)) MCD_XferProgrQuery, + .MCD_killDma = (int32_t (*)(int32_t)) MCD_killDma, + .MCD_continDma = (int32_t (*)(int32_t)) MCD_continDma, + .MCD_pauseDma = (int32_t (*)(int32_t)) MCD_pauseDma, + .MCD_resumeDma = (int32_t (*)(int32_t)) MCD_resumeDma, + .MCD_csumQuery = (int32_t (*)(int32_t, uint32_t *)) MCD_csumQuery, + .dma_malloc = driver_mem_alloc, + .dma_free = driver_mem_free }; -extern const struct fb_info *info_fb; +extern struct fb_info *info_fb; /* * driver interface struct for the PCI_BIOS BaS driver */ -static struct pci_bios_interface pci_interface = +static struct pci_bios_interface pci_interface = { - .subjar = 0, - .version = 0x00010000, - .find_pci_device = wrapper_find_pci_device, - .find_pci_classcode = wrapper_find_pci_classcode, - .read_config_byte = wrapper_read_config_byte, - .read_config_word = wrapper_read_config_word, - .read_config_longword = wrapper_read_config_longword, - .fast_read_config_byte = wrapper_fast_read_config_byte, - .fast_read_config_word = wrapper_fast_read_config_word, - .fast_read_config_longword = wrapper_fast_read_config_longword, - .write_config_byte = wrapper_write_config_byte, - .write_config_word = wrapper_write_config_word, - .write_config_longword = wrapper_write_config_longword, - .hook_interrupt = wrapper_hook_interrupt, - .unhook_interrupt = wrapper_unhook_interrupt, - .special_cycle = wrapper_special_cycle, - .get_routing = wrapper_get_routing, - .set_interrupt = wrapper_set_interrupt, - .get_resource = wrapper_get_resource, - .get_card_used = wrapper_get_card_used, - .set_card_used = wrapper_set_card_used, - .read_mem_byte = wrapper_read_mem_byte, - .read_mem_word = wrapper_read_mem_word, - .read_mem_longword = wrapper_read_mem_longword, - .fast_read_mem_byte = wrapper_fast_read_mem_byte, - .fast_read_mem_word = wrapper_fast_read_mem_word, - .fast_read_mem_longword = wrapper_fast_read_mem_longword, - .write_mem_byte = wrapper_write_mem_byte, - .write_mem_word = wrapper_write_mem_word, - .write_mem_longword = wrapper_write_mem_longword, - .read_io_byte = wrapper_read_io_byte, - .read_io_word = wrapper_read_io_word, - .read_io_longword = wrapper_read_io_longword, - .fast_read_io_byte = wrapper_fast_read_io_byte, - .fast_read_io_word = wrapper_fast_read_io_word, - .fast_read_io_longword = wrapper_fast_read_io_longword, - .write_io_byte = wrapper_write_io_byte, - .write_io_word = wrapper_write_io_word, - .write_io_longword = wrapper_write_io_longword, - .get_machine_id = wrapper_get_machine_id, - .get_pagesize = wrapper_get_pagesize, - .virt_to_bus = wrapper_virt_to_bus, - .bus_to_virt = wrapper_bus_to_virt, - .virt_to_phys = wrapper_virt_to_phys, - .phys_to_virt = wrapper_phys_to_virt, + .subjar = 0, + .version = 0x00010000, + .find_pci_device = wrapper_find_pci_device, + .find_pci_classcode = wrapper_find_pci_classcode, + .read_config_byte = wrapper_read_config_byte, + .read_config_word = wrapper_read_config_word, + .read_config_longword = wrapper_read_config_longword, + .fast_read_config_byte = wrapper_fast_read_config_byte, + .fast_read_config_word = wrapper_fast_read_config_word, + .fast_read_config_longword = wrapper_fast_read_config_longword, + .write_config_byte = wrapper_write_config_byte, + .write_config_word = wrapper_write_config_word, + .write_config_longword = wrapper_write_config_longword, + .hook_interrupt = wrapper_hook_interrupt, + .unhook_interrupt = wrapper_unhook_interrupt, + .special_cycle = wrapper_special_cycle, + .get_routing = wrapper_get_routing, + .set_interrupt = wrapper_set_interrupt, + .get_resource = wrapper_get_resource, + .get_card_used = wrapper_get_card_used, + .set_card_used = wrapper_set_card_used, + .read_mem_byte = wrapper_read_mem_byte, + .read_mem_word = wrapper_read_mem_word, + .read_mem_longword = wrapper_read_mem_longword, + .fast_read_mem_byte = wrapper_fast_read_mem_byte, + .fast_read_mem_word = wrapper_fast_read_mem_word, + .fast_read_mem_longword = wrapper_fast_read_mem_longword, + .write_mem_byte = wrapper_write_mem_byte, + .write_mem_word = wrapper_write_mem_word, + .write_mem_longword = wrapper_write_mem_longword, + .read_io_byte = wrapper_read_io_byte, + .read_io_word = wrapper_read_io_word, + .read_io_longword = wrapper_read_io_longword, + .fast_read_io_byte = wrapper_fast_read_io_byte, + .fast_read_io_word = wrapper_fast_read_io_word, + .fast_read_io_longword = wrapper_fast_read_io_longword, + .write_io_byte = wrapper_write_io_byte, + .write_io_word = wrapper_write_io_word, + .write_io_longword = wrapper_write_io_longword, + .get_machine_id = wrapper_get_machine_id, + .get_pagesize = wrapper_get_pagesize, + .virt_to_bus = wrapper_virt_to_bus, + .bus_to_virt = wrapper_bus_to_virt, + .virt_to_phys = wrapper_virt_to_phys, + .phys_to_virt = wrapper_phys_to_virt, }; /* @@ -127,69 +129,112 @@ static struct pci_bios_interface pci_interface = */ static struct framebuffer_driver_interface framebuffer_interface = { - .framebuffer_info = &info_fb + .framebuffer_info = &info_fb }; + static struct generic_interface interfaces[] = { - { - /* BaS SD-card driver interface */ + { + /* BaS SD-card driver interface */ - .type = XHDI_DRIVER, - .name = "SDCARD", - .description = "BaS SD Card driver", - .version = 0, - .revision = 1, - .interface.xhdi = &xhdi_call_interface - }, - { - .type = MCD_DRIVER, - .name = "MCDDMA", - .description = "BaS Multichannel DMA driver", - .version = 0, - .revision = 1, - .interface.dma = &dma_interface, - }, - { - .type = VIDEO_DRIVER, - .name = "RADEON", - .description = "BaS RADEON framebuffer driver", - .version = 0, - .revision = 1, - .interface.fb = &framebuffer_interface, - }, - { - .type = PCI_DRIVER, - .name = "PCI", - .description = "BaS PCI_BIOS driver", - .version = 0, - .revision = 1, - .interface.pci = &pci_interface, - }, - /* insert new drivers here */ + .type = XHDI_DRIVER, + .name = "SDCARD", + .description = "BaS SD Card driver", + .version = 0, + .revision = 1, + .interface.xhdi = &xhdi_call_interface + }, + { + .type = MCD_DRIVER, + .name = "MCDDMA", + .description = "BaS Multichannel DMA driver", + .version = 0, + .revision = 1, + .interface.dma = &dma_interface, + }, + { + .type = VIDEO_DRIVER, + .name = "RADEON", + .description = "BaS RADEON framebuffer driver", + .version = 0, + .revision = 1, + .interface.fb = &framebuffer_interface, + }, + { + .type = PCI_DRIVER, + .name = "PCI", + .description = "BaS PCI_BIOS driver", + .version = 0, + .revision = 1, + .interface.pci = &pci_interface, + }, + { + .type = MMU_DRIVER, + .name = "MMU", + .description = "BaS MMU driver", + .version = 0, + .revision = 1, + .interface.mmu = NULL, + }, + /* insert new drivers here */ - { - .type = END_OF_DRIVERS - } + { + .type = END_OF_DRIVERS + } }; +extern void remove_handler(void); /* forward declaration */ + /* * this is the driver table we expose to the OS */ static struct driver_table bas_drivers = { - .bas_version = MAJOR_VERSION, - .bas_revision = MINOR_VERSION, - .remove_handler = NULL, - .interfaces = { interfaces } + .bas_version = MAJOR_VERSION, + .bas_revision = MINOR_VERSION, + .remove_handler = remove_handler, + .interfaces = interfaces }; +void remove_handler(void) +{ + extern void std_exc_vec(void); + uint32_t *trap_0_vector = (uint32_t *) 0x80; + + *trap_0_vector = (uint32_t) std_exc_vec; +} + void __attribute__((interrupt)) get_bas_drivers(void) { - __asm__ __volatile__( - "move.l #%[drivers],d0\n\t" - : /* no output */ - : [drivers] "o" (bas_drivers) /* input */ - : /* clobber */ - ); + __asm__ __volatile( + /* + * sp should now point to the next instruction after the trap + * The trap itself is 2 bytes, the four bytes before that must + * read '_BAS' or we are not meant by this call + */ + " move.l a0,-(sp) \n\t" // save registers + " move.l d0,-(sp) \n\t" + " move.l 12(sp),a0 \n\t" // get return address + " move.l -6(a0),d0 \n\t" // + " cmp.l #0x5f424153,d0 \n\t" // is it '_BAS'? + " beq fetch_drivers \n\t" // yes + /* + * This seems indeed a "normal" trap #0. Better pass control to "normal" trap #0 processing + * If trap #0 isn't set to something sensible, we'll probably crash here, but this must be + * prevented on the caller side. + */ + " move.l (sp)+,d0 \n\t" // restore registers + " move.l (sp)+,a0 \n\t" + " move.l 0x80,-(sp) \n\t" // fetch vector + " rts \n\t" // and jump through it + + "fetch_drivers: \n\t" + " move.l #%[drivers],d0 \n\t" // return driver struct in d0 + " addq.l #4,sp \n\t" // adjust stack + " move.l (sp)+,a0 \n\t" // restore register + : /* no output */ + : [drivers] "o" (bas_drivers) /* input */ + : /* clobber */ + ); } diff --git a/include/driver_vec.h b/include/driver_vec.h index 143e64e..0a9d8a2 100644 --- a/include/driver_vec.h +++ b/include/driver_vec.h @@ -31,52 +31,53 @@ enum driver_type { -// BLOCKDEV_DRIVER, -// CHARDEV_DRIVER, - XHDI_DRIVER, - MCD_DRIVER, - VIDEO_DRIVER, - PCI_DRIVER, - END_OF_DRIVERS, /* marks end of driver list */ + BLOCKDEV_DRIVER, + CHARDEV_DRIVER, + XHDI_DRIVER, + MCD_DRIVER, + VIDEO_DRIVER, + PCI_DRIVER, + MMU_DRIVER, + END_OF_DRIVERS = 0xffffffff /* marks end of driver list */ }; struct generic_driver_interface { - uint32_t (*init)(void); - uint32_t (*read)(void *buf, size_t count); - uint32_t (*write)(const void *buf, size_t count); - uint32_t (*ioctl)(uint32_t request, ...); + uint32_t (*init)(void); + uint32_t (*read)(void *buf, size_t count); + uint32_t (*write)(const void *buf, size_t count); + uint32_t (*ioctl)(uint32_t request, ...); }; struct dma_driver_interface { - int32_t version; - int32_t magic; - int (*dma_set_initiator)(int initiator); - uint32_t (*dma_get_initiator)(int requestor); - void (*dma_free_initiator)(int requestor); - int (*dma_set_channel)(int requestor, void (*handler)(void)); - int (*dma_get_channel)(int requestor); - void (*dma_free_channel)(int requestor); - void (*dma_clear_channel)(int channel); - int (*MCD_startDma)(long channel, - int8_t *srcAddr, unsigned int srcIncr, int8_t *destAddr, unsigned int destIncr, - unsigned int dmaSize, unsigned int xferSize, unsigned int initiator, int priority, - unsigned int flags, unsigned int funcDesc); - int32_t (*MCD_dmaStatus)(int32_t channel); - int32_t (*MCD_XferProgrQuery)(int32_t channel, MCD_XferProg *progRep); - int32_t (*MCD_killDma)(int32_t channel); - int32_t (*MCD_continDma)(int32_t channel); - int32_t (*MCD_pauseDma)(int32_t channel); - int32_t (*MCD_resumeDma)(int32_t channel); - int32_t (*MCD_csumQuery)(int32_t channel, uint32_t *csum); - void *(*dma_malloc)(uint32_t amount); - int32_t (*dma_free)(void *addr); + int32_t version; + int32_t magic; + int (*dma_set_initiator)(int initiator); + uint32_t (*dma_get_initiator)(int requestor); + void (*dma_free_initiator)(int requestor); + int (*dma_set_channel)(int requestor, void (*handler)(void)); + int (*dma_get_channel)(int requestor); + void (*dma_free_channel)(int requestor); + void (*dma_clear_channel)(int channel); + int (*MCD_startDma)(long channel, + int8_t *srcAddr, unsigned int srcIncr, int8_t *destAddr, unsigned int destIncr, + unsigned int dmaSize, unsigned int xferSize, unsigned int initiator, int priority, + unsigned int flags, unsigned int funcDesc); + int32_t (*MCD_dmaStatus)(int32_t channel); + int32_t (*MCD_XferProgrQuery)(int32_t channel, MCD_XferProg *progRep); + int32_t (*MCD_killDma)(int32_t channel); + int32_t (*MCD_continDma)(int32_t channel); + int32_t (*MCD_pauseDma)(int32_t channel); + int32_t (*MCD_resumeDma)(int32_t channel); + int32_t (*MCD_csumQuery)(int32_t channel, uint32_t *csum); + void *(*dma_malloc)(uint32_t amount); + int32_t (*dma_free)(void *addr); }; - + struct xhdi_driver_interface { - uint32_t (*xhdivec)(); + uint32_t (*xhdivec)(); }; /* Interpretation of offset for color fields: All offsets are from the right, @@ -90,7 +91,7 @@ struct fb_bitfield unsigned long offset; /* beginning of bitfield */ unsigned long length; /* length of bitfield */ unsigned long msb_right; /* != 0 : Most significant bit is */ - /* right */ + /* right */ }; /* @@ -103,19 +104,19 @@ struct fb_var_screeninfo unsigned long xres_virtual; /* virtual resolution */ unsigned long yres_virtual; unsigned long xoffset; /* offset from virtual to visible */ - unsigned long yoffset; /* resolution */ + unsigned long yoffset; /* resolution */ - unsigned long bits_per_pixel; /* guess what */ + unsigned long bits_per_pixel; /* guess what */ unsigned long grayscale; /* != 0 Graylevels instead of colors */ struct fb_bitfield red; /* bitfield in fb mem if true color, */ struct fb_bitfield green; /* else only length is significant */ struct fb_bitfield blue; - struct fb_bitfield transp; /* transparency */ + struct fb_bitfield transp; /* transparency */ unsigned long nonstd; /* != 0 Non standard pixel format */ - unsigned long activate; /* see FB_ACTIVATE_* */ + unsigned long activate; /* see FB_ACTIVATE_* */ unsigned long height; /* height of picture in mm */ unsigned long width; /* width of picture in mm */ @@ -130,7 +131,7 @@ struct fb_var_screeninfo unsigned long lower_margin; unsigned long hsync_len; /* length of horizontal sync */ unsigned long vsync_len; /* length of vertical sync */ - unsigned long sync; /* see FB_SYNC_* */ + unsigned long sync; /* see FB_SYNC_* */ unsigned long vmode; /* see FB_VMODE_* */ unsigned long rotate; /* angle we rotate counter clockwise */ unsigned long refresh; @@ -143,7 +144,7 @@ struct fb_fix_screeninfo unsigned long smem_start; /* Start of frame buffer mem */ /* (physical address) */ unsigned long smem_len; /* Length of frame buffer mem */ - unsigned long type; /* see FB_TYPE_* */ + unsigned long type; /* see FB_TYPE_* */ unsigned long type_aux; /* Interleave for interleaved Planes */ unsigned long visual; /* see FB_VISUAL_* */ unsigned short xpanstep; /* zero if no hardware panning */ @@ -160,7 +161,7 @@ struct fb_fix_screeninfo struct fb_chroma { - unsigned long redx; /* in fraction of 1024 */ + unsigned long redx; /* in fraction of 1024 */ unsigned long greenx; unsigned long bluex; unsigned long whitex; @@ -203,87 +204,97 @@ struct fb_monspecs struct framebuffer_driver_interface { - struct fb_info **framebuffer_info; /* pointer to an fb_info struct (defined in include/fb.h) */ + struct fb_info **framebuffer_info; /* pointer to an fb_info struct (defined in include/fb.h) */ }; -struct pci_bios_interface { - uint32_t subjar; - uint32_t version; - /* Although we declare this functions as standard gcc functions (cdecl), - * they expect paramenters inside registers (fastcall) unsupported by gcc m68k. - * Caller will take care of parameters passing convention. - */ - int32_t (*find_pci_device) (uint32_t id, uint16_t index); - int32_t (*find_pci_classcode) (uint32_t class, uint16_t index); - int32_t (*read_config_byte) (int32_t handle, uint16_t reg, uint8_t *address); - int32_t (*read_config_word) (int32_t handle, uint16_t reg, uint16_t *address); - int32_t (*read_config_longword) (int32_t handle, uint16_t reg, uint32_t *address); - uint8_t (*fast_read_config_byte) (int32_t handle, uint16_t reg); - uint16_t (*fast_read_config_word) (int32_t handle, uint16_t reg); - uint32_t (*fast_read_config_longword) (int32_t handle, uint16_t reg); - int32_t (*write_config_byte) (int32_t handle, uint16_t reg, uint16_t val); - int32_t (*write_config_word) (int32_t handle, uint16_t reg, uint16_t val); - int32_t (*write_config_longword) (int32_t handle, uint16_t reg, uint32_t val); - int32_t (*hook_interrupt) (int32_t handle, uint32_t *routine, uint32_t *parameter); - int32_t (*unhook_interrupt) (int32_t handle); - int32_t (*special_cycle) (uint16_t bus, uint32_t data); - int32_t (*get_routing) (int32_t handle); - int32_t (*set_interrupt) (int32_t handle); - int32_t (*get_resource) (int32_t handle); - int32_t (*get_card_used) (int32_t handle, uint32_t *address); - int32_t (*set_card_used) (int32_t handle, uint32_t *callback); - int32_t (*read_mem_byte) (int32_t handle, uint32_t offset, uint8_t *address); - int32_t (*read_mem_word) (int32_t handle, uint32_t offset, uint16_t *address); - int32_t (*read_mem_longword) (int32_t handle, uint32_t offset, uint32_t *address); - uint8_t (*fast_read_mem_byte) (int32_t handle, uint32_t offset); - uint16_t (*fast_read_mem_word) (int32_t handle, uint32_t offset); - uint32_t (*fast_read_mem_longword) (int32_t handle, uint32_t offset); - int32_t (*write_mem_byte) (int32_t handle, uint32_t offset, uint16_t val); - int32_t (*write_mem_word) (int32_t handle, uint32_t offset, uint16_t val); - int32_t (*write_mem_longword) (int32_t handle, uint32_t offset, uint32_t val); - int32_t (*read_io_byte) (int32_t handle, uint32_t offset, uint8_t *address); - int32_t (*read_io_word) (int32_t handle, uint32_t offset, uint16_t *address); - int32_t (*read_io_longword) (int32_t handle, uint32_t offset, uint32_t *address); - uint8_t (*fast_read_io_byte) (int32_t handle, uint32_t offset); - uint16_t (*fast_read_io_word) (int32_t handle, uint32_t offset); - uint32_t (*fast_read_io_longword) (int32_t handle, uint32_t offset); - int32_t (*write_io_byte) (int32_t handle, uint32_t offset, uint16_t val); - int32_t (*write_io_word) (int32_t handle, uint32_t offset, uint16_t val); - int32_t (*write_io_longword) (int32_t handle, uint32_t offset, uint32_t val); - int32_t (*get_machine_id) (void); - int32_t (*get_pagesize) (void); - int32_t (*virt_to_bus) (int32_t handle, uint32_t address, PCI_CONV_ADR *pointer); - int32_t (*bus_to_virt) (int32_t handle, uint32_t address, PCI_CONV_ADR *pointer); - int32_t (*virt_to_phys) (uint32_t address, PCI_CONV_ADR *pointer); - int32_t (*phys_to_virt) (uint32_t address, PCI_CONV_ADR *pointer); +struct pci_bios_interface +{ + uint32_t subjar; + uint32_t version; + /* Although we declare this functions as standard gcc functions (cdecl), + * they expect paramenters inside registers (fastcall) unsupported by gcc m68k. + * Caller will take care of parameters passing convention. + */ + int32_t (*find_pci_device) (uint32_t id, uint16_t index); + int32_t (*find_pci_classcode) (uint32_t class, uint16_t index); + int32_t (*read_config_byte) (int32_t handle, uint16_t reg, uint8_t *address); + int32_t (*read_config_word) (int32_t handle, uint16_t reg, uint16_t *address); + int32_t (*read_config_longword) (int32_t handle, uint16_t reg, uint32_t *address); + uint8_t (*fast_read_config_byte) (int32_t handle, uint16_t reg); + uint16_t (*fast_read_config_word) (int32_t handle, uint16_t reg); + uint32_t (*fast_read_config_longword) (int32_t handle, uint16_t reg); + int32_t (*write_config_byte) (int32_t handle, uint16_t reg, uint16_t val); + int32_t (*write_config_word) (int32_t handle, uint16_t reg, uint16_t val); + int32_t (*write_config_longword) (int32_t handle, uint16_t reg, uint32_t val); + int32_t (*hook_interrupt) (int32_t handle, uint32_t *routine, uint32_t *parameter); + int32_t (*unhook_interrupt) (int32_t handle); + int32_t (*special_cycle) (uint16_t bus, uint32_t data); + int32_t (*get_routing) (int32_t handle); + int32_t (*set_interrupt) (int32_t handle); + int32_t (*get_resource) (int32_t handle); + int32_t (*get_card_used) (int32_t handle, uint32_t *address); + int32_t (*set_card_used) (int32_t handle, uint32_t *callback); + int32_t (*read_mem_byte) (int32_t handle, uint32_t offset, uint8_t *address); + int32_t (*read_mem_word) (int32_t handle, uint32_t offset, uint16_t *address); + int32_t (*read_mem_longword) (int32_t handle, uint32_t offset, uint32_t *address); + uint8_t (*fast_read_mem_byte) (int32_t handle, uint32_t offset); + uint16_t (*fast_read_mem_word) (int32_t handle, uint32_t offset); + uint32_t (*fast_read_mem_longword) (int32_t handle, uint32_t offset); + int32_t (*write_mem_byte) (int32_t handle, uint32_t offset, uint16_t val); + int32_t (*write_mem_word) (int32_t handle, uint32_t offset, uint16_t val); + int32_t (*write_mem_longword) (int32_t handle, uint32_t offset, uint32_t val); + int32_t (*read_io_byte) (int32_t handle, uint32_t offset, uint8_t *address); + int32_t (*read_io_word) (int32_t handle, uint32_t offset, uint16_t *address); + int32_t (*read_io_longword) (int32_t handle, uint32_t offset, uint32_t *address); + uint8_t (*fast_read_io_byte) (int32_t handle, uint32_t offset); + uint16_t (*fast_read_io_word) (int32_t handle, uint32_t offset); + uint32_t (*fast_read_io_longword) (int32_t handle, uint32_t offset); + int32_t (*write_io_byte) (int32_t handle, uint32_t offset, uint16_t val); + int32_t (*write_io_word) (int32_t handle, uint32_t offset, uint16_t val); + int32_t (*write_io_longword) (int32_t handle, uint32_t offset, uint32_t val); + int32_t (*get_machine_id) (void); + int32_t (*get_pagesize) (void); + int32_t (*virt_to_bus) (int32_t handle, uint32_t address, PCI_CONV_ADR *pointer); + int32_t (*bus_to_virt) (int32_t handle, uint32_t address, PCI_CONV_ADR *pointer); + int32_t (*virt_to_phys) (uint32_t address, PCI_CONV_ADR *pointer); + int32_t (*phys_to_virt) (uint32_t address, PCI_CONV_ADR *pointer); // int32_t reserved[2]; }; +struct mmu_driver_interface +{ + int32_t (*map_page_locked)(uint32_t address, uint32_t length, int asid); + int32_t (*unlock_page)(uint32_t address, uint32_t length, int asid); + int32_t (*report_locked_pages)(uint32_t *num_itlb, uint32_t *num_dtlb); + uint32_t (*report_pagesize)(void); +}; + union interface { - struct generic_driver_interface *gdi; - struct xhdi_driver_interface *xhdi; - struct dma_driver_interface *dma; - struct framebuffer_driver_interface *fb; - struct pci_bios_interface *pci; + struct generic_driver_interface *gdi; + struct xhdi_driver_interface *xhdi; + struct dma_driver_interface *dma; + struct framebuffer_driver_interface *fb; + struct pci_bios_interface *pci; + struct mmu_driver_interface *mmu; }; struct generic_interface { - enum driver_type type; - char name[16]; - char description[64]; - int version; - int revision; - union interface interface; + enum driver_type type; + char name[16]; + char description[64]; + int version; + int revision; + union interface interface; }; struct driver_table { - uint32_t bas_version; - uint32_t bas_revision; - uint32_t (*remove_handler)(); /* calling this will disable the BaS' hook into trap #0 */ - struct generic_interface *interfaces[]; + uint32_t bas_version; + uint32_t bas_revision; + void (*remove_handler)(void); /* calling this will disable the BaS' hook into trap #0 */ + struct generic_interface *interfaces; }; diff --git a/net/fecbd.c b/net/fecbd.c index 49b1d0c..c309c5b 100644 --- a/net/fecbd.c +++ b/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/net/ip.c b/net/ip.c index c536908..9b26e48 100644 --- a/net/ip.c +++ b/net/ip.c @@ -1,5 +1,5 @@ /* - * File: ip.c + * File: ip.c * Purpose: Internet Protcol device driver * * Notes: @@ -13,7 +13,7 @@ #include -#define IP_DEBUG +//#define IP_DEBUG #if defined(IP_DEBUG) #define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0) #else @@ -22,300 +22,300 @@ 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]; - } + if (info != 0) + { + return (uint8_t *) &info->myip[0]; + } dbg("info is NULL!\n\t"); - return 0; + 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; - } + { + 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"); - 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"); - - nbuf_free(pNbuf); - return; - } + /* + * Verify valid IP header and destination IP + */ + if (!validate_ip_hdr(nif, ipframe)) + { + dbg("not a valid IP packet!\r\n"); - pNbuf->offset += (IP_IHL(ipframe) * 4); - pNbuf->length = (uint16_t)(IP_LENGTH(ipframe) - (IP_IHL(ipframe) * 4)); + nbuf_free(pNbuf); + 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; + 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; } diff --git a/net/udp.c b/net/udp.c index 385e4e3..189dd7f 100644 --- a/net/udp.c +++ b/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) - { - dbg("%s: nif is NULL\r\n", __FUNCTION__); - return 0; - } + if (nif == NULL) + { + dbg("%s: nif is NULL\r\n", __FUNCTION__); + 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("%s: sent UDP request to %d.%d.%d.%d from %d.%d.%d.%d\r\n", __FUNCTION__, - dest[0], dest[1], dest[2], dest[3], - myip[0], myip[1], myip[2], myip[3]); + dbg("%s: sent UDP request to %d.%d.%d.%d from %d.%d.%d.%d\r\n", __FUNCTION__, + 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("%s: packet received\r\n", __FUNCTION__); + dbg("%s: packet received\r\n", __FUNCTION__); - /* - * 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 - { - dbg("%s: received UDP packet for non-supported port\n", __FUNCTION__); - nbuf_free(pNbuf); - } + /* + * 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("%s: received UDP packet for non-supported port\n", __FUNCTION__); + nbuf_free(pNbuf); + } - return; + return; } diff --git a/sys/exceptions.S b/sys/exceptions.S index ede0336..adee71f 100644 --- a/sys/exceptions.S +++ b/sys/exceptions.S @@ -27,26 +27,26 @@ #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 __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 - /* PCI interrupt handlers */ - .extern _irq5_handler - .extern _irq7_handler + /* PCI interrupt handlers */ + .extern _irq5_handler + .extern _irq7_handler /* Register read/write macros */ -#define MCF_MMU_MMUCR __MMUBAR +#define MCF_MMU_MMUCR __MMUBAR #define MCF_MMU_MMUOR __MMUBAR+0x04 #define MCF_MMU_MMUSR __MMUBAR+0x08 #define MCF_MMU_MMUAR __MMUBAR+0x10 @@ -67,66 +67,67 @@ #define MCF_PSC3_PSCRB_8BIT __MBAR+0x890C #define MCF_PSC3_PSCTB_8BIT __MBAR+0x890C - .global _vec_init + .global _std_exc_vec + .global _vec_init - // 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 //mmu --------------------------------------------------- /* Register read/write macros */ -#define MCF_MMU_MMUCR __MMUBAR +#define MCF_MMU_MMUCR __MMUBAR #define MCF_MMU_MMUOR __MMUBAR+0x04 #define MCF_MMU_MMUSR __MMUBAR+0x08 #define MCF_MMU_MMUAR __MMUBAR+0x10 @@ -175,16 +176,16 @@ #define MCF_MMU_MMUDR_SZ(x) (((x)&0x3)<<0x8) #define MCF_MMU_MMUDR_PA(x) (((x)&0x3FFFFF)<<0xA) -#define std_mmutr (MCF_MMU_MMUTR_SG|MCF_MMU_MMUTR_V) -#define writethrough_mmudr (MCF_MMU_MMUDR_SZ(00)|MCF_MMU_MMUDR_CM(00)|MCF_MMU_MMUDR_R|MCF_MMU_MMUDR_W|MCF_MMU_MMUDR_X) -#define copyback_mmudr (MCF_MMU_MMUDR_SZ(00)|MCF_MMU_MMUDR_CM(01)|MCF_MMU_MMUDR_R|MCF_MMU_MMUDR_W|MCF_MMU_MMUDR_X) +#define std_mmutr (MCF_MMU_MMUTR_SG|MCF_MMU_MMUTR_V) +#define writethrough_mmudr (MCF_MMU_MMUDR_SZ(00)|MCF_MMU_MMUDR_CM(00)|MCF_MMU_MMUDR_R|MCF_MMU_MMUDR_W|MCF_MMU_MMUDR_X) +#define copyback_mmudr (MCF_MMU_MMUDR_SZ(00)|MCF_MMU_MMUDR_CM(01)|MCF_MMU_MMUDR_R|MCF_MMU_MMUDR_W|MCF_MMU_MMUDR_X) - // equates for (experimental) video page copying via Coldfire DMA - .equ MCD_SINGLE_DMA, 0x100 - .equ MCD_TT_FLAGS_CW, 0x2 - .equ MCD_TT_FLAGS_RL, 0x1 - .equ MCD_TT_FLAGS_SP, 0x4 - .equ DMA_ALWAYS, 0 + // equates for (experimental) video page copying via Coldfire DMA + .equ MCD_SINGLE_DMA, 0x100 + .equ MCD_TT_FLAGS_CW, 0x2 + .equ MCD_TT_FLAGS_RL, 0x1 + .equ MCD_TT_FLAGS_SP, 0x4 + .equ DMA_ALWAYS, 0 //--------------------------------------------------- /********************************************************************* * @@ -206,21 +207,21 @@ /**********************************************************/ // macros /**********************************************************/ - .altmacro - .macro irq vector,int_mask,clr_int - move.w #0x2700,sr // disable interrupt - subq.l #8,a7 - movem.l d0/a5,(a7) // save registers + .altmacro + .macro irq vector,int_mask,clr_int + move.w #0x2700,sr // disable interrupt + subq.l #8,a7 + movem.l d0/a5,(a7) // 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 (a7),d0/a5 // restore registers - addq.l #8,a7 - move.l \vector,-(a7) - move #0x2\int_mask\()00,sr - rts - .endm + movem.l (a7),d0/a5 // restore registers + addq.l #8,a7 + move.l \vector,-(a7) + move #0x2\int_mask\()00,sr + rts + .endm /* * FIXME: this is a GNU gas kludge. Ugly, but I just can't come up with any smarter solution @@ -228,7 +229,7 @@ * GNU as does not support multi-character constants. At least I don't know of any way it would. * The following might look more than strange, but I considered the statement * - * mchar move.l, 'T,'E,'S,'T,-(SP) + * mchar move.l, 'T,'E,'S,'T,-(SP) * * somewhat more readable than * @@ -237,620 +238,620 @@ * If anybody knows of any better way on how to do this - please do! * */ - .macro mchar st,a,b,c,d,tgt - \st #\a << 24|\b<<16|\c<<8|\d,\tgt - .endm + .macro mchar st,a,b,c,d,tgt + \st #\a << 24|\b<<16|\c<<8|\d,\tgt + .endm .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 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) - - .extern _get_bas_drivers + lea access(pc),a1 // set illegal access exception handler + move.l a1,0x08(a0) + + .extern _get_bas_drivers // 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 irq1(pc),a1 - move.l a1,0x104(a0) - lea irq2(pc),a1 - move.l a1,0x108(a0) - lea irq3(pc),a1 - move.l a1,0x10c(a0) - lea irq4(pc),a1 - move.l a1,0x110(a0) - lea irq5(pc),a1 - move.l a1,0x114(a0) - lea irq6(pc),a1 - move.l a1,0x118(a0) - lea irq7(pc),a1 - move.l a1,0x11c(a0) + lea irq1(pc),a1 + move.l a1,0x104(a0) + lea irq2(pc),a1 + move.l a1,0x108(a0) + lea irq3(pc),a1 + move.l a1,0x10c(a0) + lea irq4(pc),a1 + move.l a1,0x110(a0) + lea irq5(pc),a1 + move.l a1,0x114(a0) + lea irq6(pc),a1 + move.l a1,0x118(a0) + lea irq7(pc),a1 + move.l a1,0x11c(a0) // install PSC vectors (used for PIC communication on the FireBee) - lea handler_psc3(pc),a1 - // PSC3 interrupt source = 32 - move.l a1,(INT_SOURCE_PSC3 + 64) * 4(a0) + lea handler_psc3(pc),a1 + // PSC3 interrupt source = 32 + move.l a1,(INT_SOURCE_PSC3 + 64) * 4(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) #ifndef MACHINE_FIREBEE // FEC1 not wired on the FireBee - 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: - move.w #0x2700,sr // disable interrupt - subq.l #8,a7 - movem.l d0/a5,(sp) // save registers - move.w 8(sp),d0 // fetch vector - and.l #0x3fc,d0 // mask out vector number +_std_exc_vec: + move.w #0x2700,sr // disable interrupt + subq.l #8,a7 + 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(a7) // store exception routine address + move.l 4(sp),a5 // restore a5 + move.l d0,4(a7) // store exception routine address - move.w 10(a7),d0 // restore original SR - bset #13,d0 // set supervisor bit - move.w d0,sr // - move.l (a7)+,d0 // restore d0 - rts // jump to exception routine + move.w 10(a7),d0 // restore original SR + bset #13,d0 // set supervisor bit + move.w d0,sr // + move.l (a7)+,d0 // restore d0 + rts // jump to exception routine 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 interrupt - move.l d0,-(sp) // ++ vr + move.w #0x2700,sr // disable interrupt + move.l d0,-(sp) // ++ vr - move.w 4(sp),d0 // get format_status word from stack - andi.l #0x0c03,d0 // mask out fault status bits - cmpi.l #0x0401,d0 // TLB miss on opword of instruction fetch? - beq access_mmu // yes - cmpi.l #0x0402,d0 // TLB miss on extension word of instruction fetch? - beq access_mmu // yes - cmpi.l #0x0802,d0 // TLB miss on data write? - beq access_mmu // yes - cmpi.l #0x0c02,d0 // TLB miss on data read, or read-modify-write? - beq access_mmu // yes + move.w 4(sp),d0 // get format_status word from stack + andi.l #0x0c03,d0 // mask out fault status bits + cmpi.l #0x0401,d0 // TLB miss on opword of instruction fetch? + beq access_mmu // yes + cmpi.l #0x0402,d0 // TLB miss on extension word of instruction fetch? + beq access_mmu // yes + cmpi.l #0x0802,d0 // TLB miss on data write? + beq access_mmu // yes + cmpi.l #0x0c02,d0 // TLB miss on data read, or read-modify-write? + beq access_mmu // yes - bra bus_error // everything else is a classic bus error + bra bus_error // everything else is a classic bus error access_mmu: - move.l MCF_MMU_MMUSR,d0 // did the last fault hit in TLB? - btst #1,d0 // yes, it did. So we already mapped that page - bne bus_error // and this must be a real bus error + move.l MCF_MMU_MMUSR,d0 // did the last fault hit in TLB? + btst #1,d0 // yes, it did. So we already mapped that page + bne bus_error // and this must be a real bus error - move.l MCF_MMU_MMUAR,d0 - cmp.l #__FASTRAM_END,d0 // above max User RAM area? - bge bus_error // -> bus error + move.l MCF_MMU_MMUAR,d0 + cmp.l #__FASTRAM_END,d0 // above max User RAM area? + bge bus_error // -> bus error - lea -5*4(sp),sp // save gcc scratch registers - movem.l d0-d1/a0-a2,(sp) + lea -5*4(sp),sp // save gcc scratch registers + movem.l d0-d1/a0-a2,(sp) - move.l d0,-(sp) // fault address - jsr _mmutr_miss // else we have an MMU TLB miss - addq.l #4,sp + move.l d0,-(sp) // fault address + jsr _mmutr_miss // else we have an MMU TLB miss + addq.l #4,sp - movem.l (sp),d0-d1/a0-a2 // restore gcc scratch registers - lea 5*4(sp),sp + movem.l (sp),d0-d1/a0-a2 // restore gcc scratch registers + lea 5 * 4(sp),sp - move.l (sp)+,d0 // restore register + move.l (sp)+,d0 // restore register - rte + rte bus_error: - move.l (sp)+,d0 // restore register - bra std_exc_vec - + move.l (sp)+,d0 // restore register + bra _std_exc_vec + zero_divide: - move.w #0x2700,sr // disable interrupt - move.l a0,-(a7) - move.l d0,-(a7) - move.l 12(a7),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,-(a7) + move.l d0,-(a7) + move.l 12(a7),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(a7) - move.l (a7)+,d0 - move.l (a7)+,a0 - rte - -#ifdef _NOT_USED_ -linea: - move.w #0x2700,sr // disable interrupt - halt - nop - nop -linef: - move.w #0x2700,sr // disable interrupt - halt - nop - nop -format: - move.w #0x2700,sr // disable interrupt - halt - nop - nop + move.l a0,12(a7) + move.l (a7)+,d0 + move.l (a7)+,a0 + rte -//floating point +#ifdef _NOT_USED_ +linea: + move.w #0x2700,sr // disable interrupt + halt + nop + nop +linef: + move.w #0x2700,sr // disable interrupt + halt + nop + nop +format: + 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 + irq 0x64,1,0x02 -irq2: // hbl - // move.b #3,2(a7) - // rte - irq 0x68,2,0x04 +irq2: // hbl + // move.b #3,2(a7) + // rte + irq 0x68,2,0x04 irq3: - irq 0x6c,3,0x08 + irq 0x6c,3,0x08 -irq4: // vbl - irq 0x70,4,0x10 +irq4: // vbl + irq 0x70,4,0x10 -#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 -irq6: - irq 0x74,5,0x20 +irq6: + irq 0x74,5,0x20 -irq7: // irq7 is tied to PCI INTA# and PCI INTB# on the M5484LITE +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: - .ascii "IRQ7!" - .dc.b 13,10,0 + .ascii "IRQ7!" + .dc.b 13,10,0 -#elif MACHINE_FIREBEE /* these handlers are only meaningful for the Firebee */ -irq5: // irq5 is tied to PCI INTC# and PCI INTD# on the M5484LITE - irq 0x74,5,0x20 +#elif MACHINE_FIREBEE /* these handlers are only meaningful for the Firebee */ +irq5: // irq5 is tied to PCI INTC# and PCI INTD# on the M5484LITE + irq 0x74,5,0x20 -irq6: // MFP interrupt from FPGA - move.w #0x2700,sr // disable interrupt - subq.l #8,a7 - movem.l d0/a5,(a7) // save registers +irq6: // MFP interrupt from FPGA + move.w #0x2700,sr // disable interrupt + subq.l #8,a7 + movem.l d0/a5,(a7) // 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) - // there was a potential bug here before: would also clear all other edge port interrupts that might have happened... - // move.b #0x40,(a5) // clear int6 from edge port + // there was a potential bug here before: would also clear all other edge port interrupts that might have happened... + // move.b #0x40,(a5) // clear int6 from edge port // screen adr change timed out? - move.l _video_sbt,d0 - beq irq6_non_sca // nothing to do if 0 - sub.l #0x70000000,d0 // substract 14 seconds - lea MCF_SLT0_SCNT,a5 - cmp.l (a5),d0 // time reached? - ble irq6_non_sca // not yet + move.l _video_sbt,d0 + beq irq6_non_sca // nothing to do if 0 + sub.l #0x70000000,d0 // substract 14 seconds + lea MCF_SLT0_SCNT,a5 + cmp.l (a5),d0 // time reached? + ble irq6_non_sca // not yet - lea -28(a7),a7 // save more registers - movem.l d0-d4/a0-a1,(a7) // - clr.l d3 // beginn mit 0 - jsr _flush_and_invalidate_caches + lea -28(a7),a7 // save more registers + movem.l d0-d4/a0-a1,(a7) // + clr.l d3 // beginn mit 0 + jsr _flush_and_invalidate_caches // eintrag suchen irq6_next_sca: - move.l d3,d0 - move.l d0,MCF_MMU_MMUAR // addresse - move.l #0x106,d4 - move.l d4,MCF_MMU_MMUOR // suchen -> - nop - move.l MCF_MMU_MMUOR,d4 - clr.w d4 - swap d4 - move.l d4,MCF_MMU_MMUAR - mvz.w #0x10e,d4 - move.l d4,MCF_MMU_MMUOR // einträge holen aus mmu - nop - move.l MCF_MMU_MMUTR,d4 // ID holen - lsr.l #2,d4 // bit 9 bis 2 - cmp.w #sca_page_ID,d4 // ist screen change ID? - bne irq6_sca_pn // nein -> page keine screen area next + move.l d3,d0 + move.l d0,MCF_MMU_MMUAR // addresse + move.l #0x106,d4 + move.l d4,MCF_MMU_MMUOR // suchen -> + nop + move.l MCF_MMU_MMUOR,d4 + clr.w d4 + swap d4 + move.l d4,MCF_MMU_MMUAR + mvz.w #0x10e,d4 + move.l d4,MCF_MMU_MMUOR // einträge holen aus mmu + nop + move.l MCF_MMU_MMUTR,d4 // ID holen + lsr.l #2,d4 // bit 9 bis 2 + cmp.w #sca_page_ID,d4 // ist screen change ID? + bne irq6_sca_pn // nein -> page keine screen area next // eintrag �ndern - add.l #std_mmutr,d0 - move.l d3,d1 // page 0? - beq irq6_sca_pn0 // ja -> - add.l #copyback_mmudr,d1 // sonst page cb - bra irq6_sca_pn1c + add.l #std_mmutr,d0 + move.l d3,d1 // page 0? + beq irq6_sca_pn0 // ja -> + add.l #copyback_mmudr,d1 // sonst page cb + bra irq6_sca_pn1c irq6_sca_pn0: - add.l #writethrough_mmudr|MCF_MMU_MMUDR_LK,d1 // page wt and locked + add.l #writethrough_mmudr|MCF_MMU_MMUDR_LK,d1 // page wt and locked irq6_sca_pn1c: - mvz.w #0x10b,d2 // MMU update - move.l d0,MCF_MMU_MMUTR - move.l d1,MCF_MMU_MMUDR - move.l d2,MCF_MMU_MMUOR // setze tlb data only - nop + mvz.w #0x10b,d2 // MMU update + move.l d0,MCF_MMU_MMUTR + move.l d1,MCF_MMU_MMUDR + move.l d2,MCF_MMU_MMUOR // setze tlb data only + nop // page copy - move.l d3,a0 - add.l #0x60000000,a0 - move.l d3,a1 - move.l #0x10000,d4 // one whole page (1 MB) + move.l d3,a0 + add.l #0x60000000,a0 + move.l d3,a1 + move.l #0x10000,d4 // one whole page (1 MB) #define _DO_CPU_COPY #ifndef _DO_CPU_COPY - // experiment: do video page copy using Coldfire DMA + // experiment: do video page copy using Coldfire DMA - lea -15 * 4(sp),sp - movem.l d0-d1/a0-a1,(sp) // save gcc scratch registers - clr.l -(sp) // no special functions - move.l #MCD_SINGLE_DMA|MCD_TT_FLAGS_CW|MCD_TT_FLAGS_RL|MCD_TT_FLAGS_SP,-(sp) - mov3q #7,-(sp) // highest DMA priority - move.l #DMA_ALWAYS,-(sp) // do memory to memory DMA - move.l #1,-(sp) // copy 4 bytes at a time - move.l #0x100000,-(sp) // copy 1 Megabyte - move.l #4,-(sp) // destination increment - move.l a1,-(sp) // destination adress - move.l #4,-(sp) // source increment - move.l a0,-(sp) // source adress - move.l #1,-(sp) // channel 1 - jsr _MCD_startDma + lea -15 * 4(sp),sp + movem.l d0-d1/a0-a1,(sp) // save gcc scratch registers + clr.l -(sp) // no special functions + move.l #MCD_SINGLE_DMA|MCD_TT_FLAGS_CW|MCD_TT_FLAGS_RL|MCD_TT_FLAGS_SP,-(sp) + mov3q #7,-(sp) // highest DMA priority + move.l #DMA_ALWAYS,-(sp) // do memory to memory DMA + move.l #1,-(sp) // copy 4 bytes at a time + move.l #0x100000,-(sp) // copy 1 Megabyte + move.l #4,-(sp) // destination increment + move.l a1,-(sp) // destination adress + move.l #4,-(sp) // source increment + move.l a0,-(sp) // source adress + move.l #1,-(sp) // channel 1 + jsr _MCD_startDma - movem.l (sp),d0-d1/a0-a1 // restore gcc scratch registers - lea 15 * 4(sp),sp // adjust stack + movem.l (sp),d0-d1/a0-a1 // restore gcc scratch registers + lea 15 * 4(sp),sp // adjust stack wait_dma_finished: - clr.l -(sp) - jsr _MCD_dmaStatus - addq.l #4,sp - tst.l d0 - cmp.l #6,d0 - bne wait_dma_finished + clr.l -(sp) + jsr _MCD_dmaStatus + addq.l #4,sp + tst.l d0 + cmp.l #6,d0 + bne wait_dma_finished #else -irq6_vcd0_loop: - move.l (a0)+,(a1)+ // page copy - move.l (a0)+,(a1)+ - move.l (a0)+,(a1)+ - move.l (a0)+,(a1)+ - subq.l #1,d4 - bne irq6_vcd0_loop +irq6_vcd0_loop: + move.l (a0)+,(a1)+ // page copy + move.l (a0)+,(a1)+ + move.l (a0)+,(a1)+ + move.l (a0)+,(a1)+ + subq.l #1,d4 + bne irq6_vcd0_loop #endif /* _DO_CPU_COPY */ irq6_sca_pn: - add.l #0x00100000,d3 // next - cmp.l #0x00d00000,d3 // ende? - blt irq6_next_sca // nein-> + add.l #0x00100000,d3 // next + cmp.l #0x00d00000,d3 // ende? + blt irq6_next_sca // nein-> - move.l #0x2000,d0 - move.l d0,_video_tlb // anfangszustand wieder herstellen - clr.l _video_sbt // zeit löschen + move.l #0x2000,d0 + move.l d0,_video_tlb // anfangszustand wieder herstellen + clr.l _video_sbt // zeit löschen - movem.l (sp),d0-d4/a0-a1 // restore registers - lea 7 * 4(sp),sp + movem.l (sp),d0-d4/a0-a1 // restore registers + lea 7 * 4(sp),sp irq6_non_sca: // test auf acsi dma ----------------------------------------------------------------- - lea 0xfffffa0b,a5 - bset #7,-4(a5) // int ena - btst.b #7,(a5) // acsi dma int? - beq non_acsi_dma - bsr acsi_dma + lea 0xfffffa0b,a5 + bset #7,-4(a5) // int ena + btst.b #7,(a5) // acsi dma int? + beq non_acsi_dma + bsr acsi_dma non_acsi_dma: // ---------------------------------------------------------------------------------- - tst.b (a5) - bne irq6_1 - tst.b 2(a5) - bne irq6_1 - movem.l (a7),d0/a5 - addq.l #8,a7 - rte + tst.b (a5) + bne irq6_1 + tst.b 2(a5) + bne irq6_1 + movem.l (a7),d0/a5 + addq.l #8,a7 + rte 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 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 irq6_2 + lea MCF_GPIO_PODR_FEC1L,a5 + bset.b #4,(a5) // led off irq6_2: // test auf protect mode --------------------- - move.b DIP_SWITCHa,d0 - btst #7,d0 - bne irq6_3 // ja-> -// ------------------------------------------- - move.l 0xF0020000,a5 // vector holen - add.l _rt_vbr,a5 // basis - move.l (a5),d0 // vector holen - move.l 4(a7),a5 // a5 zurück - move.l d0,4(a7) // vector eintragen - move.l (a7)+,d0 // d0 zurück - move #0x2600,sr - rts + move.b DIP_SWITCHa,d0 + btst #7,d0 + bne irq6_3 // ja-> +// ------------------------------------------- + move.l 0xF0020000,a5 // vector holen + add.l _rt_vbr,a5 // basis + move.l (a5),d0 // vector holen + move.l 4(a7),a5 // a5 zurück + move.l d0,4(a7) // vector eintragen + move.l (a7)+,d0 // d0 zurück + move #0x2600,sr + rts irq6_3: - move.l usp,a5 // usp holen - tst.b _rt_mod // supervisor? - bne sev_sup6 // ja -> - mov3q.l #-1,_rt_mod // auf supervisor setzen - move.l a5,_rt_usp // rt_usp speichern - move.l _rt_ssp,a5 // rt_ssp holen - move.l 12(a7),-(a5) // pc transferieren - move.l 8(a7),-(a5) // sr transferieren - move.l a5,usp // usp setzen - move.l 0xF0020000,a5 // vector holen: intack routine - add.l _rt_vbr,a5 // virtuelle VBR des Systems - move.l (a5),12(a7) // hier gehts weiter - movem.l (a7),d0/a5 // register zurück - addq.l #8,a7 - move.b #6,2(a7) // intmaske setzen - rte // und weg + move.l usp,a5 // usp holen + tst.b _rt_mod // supervisor? + bne sev_sup6 // ja -> + mov3q.l #-1,_rt_mod // auf supervisor setzen + move.l a5,_rt_usp // rt_usp speichern + move.l _rt_ssp,a5 // rt_ssp holen + move.l 12(a7),-(a5) // pc transferieren + move.l 8(a7),-(a5) // sr transferieren + move.l a5,usp // usp setzen + move.l 0xF0020000,a5 // vector holen: intack routine + add.l _rt_vbr,a5 // virtuelle VBR des Systems + move.l (a5),12(a7) // hier gehts weiter + movem.l (a7),d0/a5 // register zurück + addq.l #8,a7 + move.b #6,2(a7) // intmaske setzen + rte // und weg sev_sup6: - move.l 12(a7),-(a5) // pc transferieren - move.l 8(a7),-(a5) // sr,vec - bset #5,2(a5) // auf super setzen - move.l a5,usp // usp setzen - move.l 0xF0020000,a5 // vector holen: intack routine - add.l _rt_vbr,a5 // virtuelle VBR des Systems - move.l (a5),12(a7) // hier gehts weiter - movem.l (a7),d0/a5 // register zurück - rts + move.l 12(a7),-(a5) // pc transferieren + move.l 8(a7),-(a5) // sr,vec + bset #5,2(a5) // auf super setzen + move.l a5,usp // usp setzen + move.l 0xF0020000,a5 // vector holen: intack routine + add.l _rt_vbr,a5 // virtuelle VBR des Systems + move.l (a5),12(a7) // hier gehts weiter + movem.l (a7),d0/a5 // register zurück + rts - .data -blinker:.long 0 + .data +blinker:.long 0 - .text + .text /* * pseudo dma */ -acsi_dma: // atari dma - move.l a1,-(a7) - move.l d1,-(a7) - - 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) +acsi_dma: // atari dma + move.l a1,-(a7) + move.l d1,-(a7) - 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 - - moveq #'.',d1 - move.b d1,MCF_PSC0_PSCTB_8BIT + 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 - sub.l #16,d0 // byt counter -16 - bpl acsi_dma_rl - bra acsi_dma_finished + moveq #'.',d1 + move.b d1,MCF_PSC0_PSCTB_8BIT + + 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 - - moveq #'.',d1 - move.b d1,MCF_PSC0_PSCTB_8BIT + 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 - sub.l #16,d0 // byt counter -16 - bpl acsi_dma_wl + moveq #'.',d1 + move.b d1,MCF_PSC0_PSCTB_8BIT + + 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 - - move.w #0x0d0a,d1 - move.w d1,MCF_PSC0_PSCTB_8BIT - - move.l (a7)+,d1 - move.l (a7)+,a1 - rts + 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.l (a7)+,d1 + move.l (a7)+,a1 + rts /* * irq 7 = pseudo bus error */ 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 /* * psc3 com PIC MCF */ handler_psc3: - move.w #0x2700,sr // disable interrupt - lea -20(a7),a7 - movem.l d0-d2/a0/a3,(a7) - lea MCF_PSC3_PSCRB_8BIT,a3 - move.b (a3),d1 - cmp.b #2,d1 // anforderung rtc daten? - bne psc3_fertig + move.w #0x2700,sr // disable interrupt + lea -20(a7),a7 + movem.l d0-d2/a0/a3,(a7) + lea MCF_PSC3_PSCRB_8BIT,a3 + move.b (a3),d1 + cmp.b #2,d1 // anforderung rtc daten? + bne psc3_fertig - lea MCF_PSC0_PSCTB_8BIT,a0 // ++ vr - mchar move.l,'\P,'\I,'C,' ,(a0) - mchar move.l,'I,'N,'T,'\ ,(a0) - mchar move.l,'R,'T,'C,'!,(a0) - mchar move.l,0x0d,0x0a,0,0,(a0) + lea MCF_PSC0_PSCTB_8BIT,a0 // ++ vr + mchar move.l,'\P,'\I,'C,' ,(a0) + mchar move.l,'I,'N,'T,'\ ,(a0) + mchar move.l,'R,'T,'C,'!,(a0) + mchar move.l,0x0d,0x0a,0,0,(a0) - lea 0xffff8961,a0 - lea MCF_PSC3_PSCTB_8BIT,a3 - clr.l d1 - moveq #64,d2 - move.b #0x82,(a3) // header: rtcd mcf->pic + lea 0xffff8961,a0 + lea MCF_PSC3_PSCTB_8BIT,a3 + clr.l d1 + moveq #64,d2 + move.b #0x82,(a3) // header: rtcd mcf->pic loop_sr2: - move.b d1,(a0) - move.b 2(a0),d0 - move.b d0,(a3) - addq.l #1,d1 - cmp.b d1,d2 - bne loop_sr2 + move.b d1,(a0) + move.b 2(a0),d0 + move.b d0,(a3) + addq.l #1,d1 + cmp.b d1,d2 + bne loop_sr2 psc3_fertig: - movem.l (a7),d0-d2/a0/a3 // restore saved registers - lea 20(a7),a7 - RTE + movem.l (a7),d0-d2/a0/a3 // restore saved registers + lea 20(a7),a7 + RTE /* * general purpose timer 0 (GPT0): video change, later also others. GPT0 is used as @@ -858,153 +859,153 @@ psc3_fertig: * vbasehi is written to, i.e. when the video base address gets changed */ handler_gpt0: - move #0x2700,sr // disable interrupts + move #0x2700,sr // disable interrupts - lea -28(a7),a7 // save registers - movem.l d0-d4/a0-a1,(a7) + lea -28(a7),a7 // save registers + movem.l d0-d4/a0-a1,(a7) - mvz.b vbasehi,d0 // screen base address high - cmp.w #2,d0 // screen base lower than 0x20000? - blt video_chg_end // yes, do nothing - cmp.w #0xd0,d0 // lower than 0xd00000? - normal Falcon video area, mapped - // to 60d00000 (FPGA video memory) - blt sca_other // + mvz.b vbasehi,d0 // screen base address high + cmp.w #2,d0 // screen base lower than 0x20000? + blt video_chg_end // yes, do nothing + cmp.w #0xd0,d0 // lower than 0xd00000? - normal Falcon video area, mapped + // to 60d00000 (FPGA video memory) + blt sca_other // - lea MCF_SLT0_SCNT,a0 - move.l (a0),_video_sbt // save time + lea MCF_SLT0_SCNT,a0 + move.l (a0),_video_sbt // save time - // FIXME: don't we need to get out here? + // FIXME: don't we need to get out here? sca_other: - lsl.l #8,d0 // build new screen start address from Atari register contents - move.b 0xffff8203,d0 // mid byte - lsl.l #8,d0 - move.b 0xffff820d,d0 // low byte - move.l d0,d3 + lsl.l #8,d0 // build new screen start address from Atari register contents + move.b 0xffff8203,d0 // mid byte + lsl.l #8,d0 + move.b 0xffff820d,d0 // low byte + move.l d0,d3 video_chg_1page: // check if page is already marked as video page - moveq #20,d4 - move.l d0,d2 - lsr.l d4,d2 // new page - move.l _video_tlb,d4 - bset.l d2,d4 // set as changed - bne video_chg_2page // was it set already? - move.l d4,_video_tlb - jsr _flush_and_invalidate_caches + moveq #20,d4 + move.l d0,d2 + lsr.l d4,d2 // new page + move.l _video_tlb,d4 + bset.l d2,d4 // set as changed + bne video_chg_2page // was it set already? + move.l d4,_video_tlb + jsr _flush_and_invalidate_caches video_copy_data: - move.l d4,_video_tlb - and.l #0x00f00000,d0 - move.l d0,a0 - move.l a0,a1 - add.l #0x60000000,a1 - move.l #0x10000,d4 // whole page + move.l d4,_video_tlb + and.l #0x00f00000,d0 + move.l d0,a0 + move.l a0,a1 + add.l #0x60000000,a1 + move.l #0x10000,d4 // whole page #ifndef _DO_CPU_COPY - // experiment: do video page copy using Coldfire DMA + // experiment: do video page copy using Coldfire DMA - lea -15 * 4(sp),sp - movem.l d0-d1/a0-a1,(sp) // save gcc scratch registers + lea -15 * 4(sp),sp + movem.l d0-d1/a0-a1,(sp) // save gcc scratch registers - clr.l -(sp) // no special functions - move.l #MCD_SINGLE_DMA|MCD_TT_FLAGS_CW|MCD_TT_FLAGS_RL|MCD_TT_FLAGS_SP,-(sp) - mov3q #7,-(sp) // highest DMA priority - move.l #DMA_ALWAYS,-(sp) // do memory to memory DMA - move.l #1,-(sp) // copy 4 bytes at a time - move.l #0x100000,-(sp) // copy 1 Megabyte - move.l #4,-(sp) // destination increment - move.l a1,-(sp) // destination adress - move.l #4,-(sp) // source increment - move.l a0,-(sp) // source adress - move.l #1,-(sp) // channel 1 - jsr _MCD_startDma + clr.l -(sp) // no special functions + move.l #MCD_SINGLE_DMA|MCD_TT_FLAGS_CW|MCD_TT_FLAGS_RL|MCD_TT_FLAGS_SP,-(sp) + mov3q #7,-(sp) // highest DMA priority + move.l #DMA_ALWAYS,-(sp) // do memory to memory DMA + move.l #1,-(sp) // copy 4 bytes at a time + move.l #0x100000,-(sp) // copy 1 Megabyte + move.l #4,-(sp) // destination increment + move.l a1,-(sp) // destination adress + move.l #4,-(sp) // source increment + move.l a0,-(sp) // source adress + move.l #1,-(sp) // channel 1 + jsr _MCD_startDma .wait_dma_finished: - clr.l -(sp) - jsr _MCD_dmaStatus - addq.l #4,sp - tst.l d0 - cmp.l #6,d0 - bne .wait_dma_finished + clr.l -(sp) + jsr _MCD_dmaStatus + addq.l #4,sp + tst.l d0 + cmp.l #6,d0 + bne .wait_dma_finished - movem.l (sp),d0-d1/a0-a1 // restore gcc scratch registers - lea 15 * 4(sp),sp // adjust stack + movem.l (sp),d0-d1/a0-a1 // restore gcc scratch registers + lea 15 * 4(sp),sp // adjust stack #else video_copy_data_loop: - move.l (a0)+,(a1)+ // copy video page contents to real screen - move.l (a0)+,(a1)+ - move.l (a0)+,(a1)+ - move.l (a0)+,(a1)+ - subq.l #1,d4 - bne video_copy_data_loop + move.l (a0)+,(a1)+ // copy video page contents to real screen + move.l (a0)+,(a1)+ + move.l (a0)+,(a1)+ + move.l (a0)+,(a1)+ + subq.l #1,d4 + bne video_copy_data_loop #endif // eintrag suchen - move.l d0,MCF_MMU_MMUAR // adress - move.l #0x106,d4 - move.l d4,MCF_MMU_MMUOR // search -> new one will be offered if not found - nop - move.l MCF_MMU_MMUOR,d4 - clr.w d4 - swap d4 - move.l d4,MCF_MMU_MMUAR - move.l d0,d1 - add.l #MCF_MMU_MMUTR_ID(sca_page_ID)|std_mmutr,d0 - add.l #0x60000000|writethrough_mmudr|MCF_MMU_MMUDR_LK,d1 - mvz.w #0x10b,d2 // MMU update - move.l d0,MCF_MMU_MMUTR - move.l d1,MCF_MMU_MMUDR - move.l d2,MCF_MMU_MMUOR // setzen vidoe maped to 60xxx only data - nop + move.l d0,MCF_MMU_MMUAR // adress + move.l #0x106,d4 + move.l d4,MCF_MMU_MMUOR // search -> new one will be offered if not found + nop + move.l MCF_MMU_MMUOR,d4 + clr.w d4 + swap d4 + move.l d4,MCF_MMU_MMUAR + move.l d0,d1 + add.l #MCF_MMU_MMUTR_ID(sca_page_ID)|std_mmutr,d0 + add.l #0x60000000|writethrough_mmudr|MCF_MMU_MMUDR_LK,d1 + mvz.w #0x10b,d2 // MMU update + move.l d0,MCF_MMU_MMUTR + move.l d1,MCF_MMU_MMUDR + move.l d2,MCF_MMU_MMUOR // setzen vidoe maped to 60xxx only data + nop video_chg_2page: // test of adjacent page is needed also - move.l d3,d0 - mvz.w 0xffff8210,d4 // byts pro zeile - mvz.w 0xffff82aa,d2 // zeilen ende - mvz.w 0xffff82a8,d1 // zeilenstart - sub.l d1,d2 // differenz = anzahl zeilen - mulu d2,d4 // maximal 480 zeilen - add.l d4,d0 // video gr�sse - cmp.l #__STRAM_END,d0 // maximale addresse - bge video_chg_end // wenn gleich oder gr�sser -> fertig - moveq #20,d4 - move.l d0,d2 - lsr.l d4,d2 // neue page - move.l _video_tlb,d4 - bset.l d2,d4 // setzen als ge�ndert - beq video_copy_data // nein nochmal + move.l d3,d0 + mvz.w 0xffff8210,d4 // byts pro zeile + mvz.w 0xffff82aa,d2 // zeilen ende + mvz.w 0xffff82a8,d1 // zeilenstart + sub.l d1,d2 // differenz = anzahl zeilen + mulu d2,d4 // maximal 480 zeilen + add.l d4,d0 // video gr�sse + cmp.l #__STRAM_END,d0 // maximale addresse + bge video_chg_end // wenn gleich oder gr�sser -> fertig + moveq #20,d4 + move.l d0,d2 + lsr.l d4,d2 // neue page + move.l _video_tlb,d4 + bset.l d2,d4 // setzen als ge�ndert + beq video_copy_data // nein nochmal video_chg_end: - lea MCF_GPT0_GMS,a0 // clear interrupt - bclr.b #0,3(a0) - nop - bset.b #0,3(a0) + lea MCF_GPT0_GMS,a0 // clear interrupt + bclr.b #0,3(a0) + nop + bset.b #0,3(a0) - movem.l (a7),d0-d4/a0-a1 // restore saved registers - lea 7 * 4(sp),a7 - rte + movem.l (a7),d0-d4/a0-a1 // restore saved registers + lea 7 * 4(sp),a7 + 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 // disable interrupts - link a6,#-4*4 // make room for - movem.l d0-d1/a0-a1,(sp) // gcc scratch registers and save them + 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 - move.w 4(a6),d0 // fetch vector number from stack - lsr.l #2,d0 // move it in place - andi.l #0x000000ff,d0 // mask it out - move.l d0,-(sp) // push it - jsr _isr_execute_handler // call the C handler - lea 4(sp),sp // adjust stack - movem.l (sp),d0-d1/a0-a1 // restore registers - unlk a6 // cleanup stack - rte + move.w 4(a6),d0 // fetch vector number from stack + lsr.l #2,d0 // move it in place + andi.l #0x000000ff,d0 // mask it out + move.l d0,-(sp) // push it + jsr _isr_execute_handler // call the C handler + lea 4(sp),sp // adjust stack + movem.l (sp),d0-d1/a0-a1 // restore registers + unlk a6 // cleanup stack + rte diff --git a/sys/init_fpga.c b/sys/init_fpga.c index 14b37eb..05b9717 100644 --- a/sys/init_fpga.c +++ b/sys/init_fpga.c @@ -87,13 +87,15 @@ bool init_fpga(void) volatile int32_t time, start, end; int i; - xprintf("FPGA load config (_FPGA_JTAG_LOADED = %x, _FPGA_JTAG_VALID = %x)...", _FPGA_JTAG_LOADED, _FPGA_JTAG_VALID); + xprintf("FPGA load config...\r\n"); + xprintf("_FPGA_JTAG_LOADED = %x, _FPGA_JTAG_VALID = %x)\r\n", _FPGA_JTAG_LOADED, _FPGA_JTAG_VALID); if (_FPGA_JTAG_LOADED == 1 && _FPGA_JTAG_VALID == VALID_JTAG) { xprintf("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; + _FPGA_JTAG_VALID = 0; return true; }