fixed bug that prevented proper detection of FPGA load skip request

This commit is contained in:
Markus Fröschle
2014-12-26 08:56:30 +00:00
parent 88c1bd2373
commit f871794760
8 changed files with 1547 additions and 1488 deletions

372
bas.lk.in
View File

@@ -19,244 +19,244 @@ MEMORY
{ {
bas_rom (ROMFLAGS) : ORIGIN = TARGET_ADDRESS, LENGTH = 0x00100000 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 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 driver_ram (WX) : ORIGIN = SDRAM_START + SDRAM_SIZE - 0x00100000, LENGTH = 0x00100000
} }
SECTIONS SECTIONS
{ {
/* BaS in ROM */ /* BaS in ROM */
.text : .text :
{ {
OBJDIR/startcf.o(.text) /* this one is the entry point so it must be the first */ OBJDIR/startcf.o(.text) /* this one is the entry point so it must be the first */
OBJDIR/sysinit.o(.text) OBJDIR/sysinit.o(.text)
OBJDIR/fault_vectors.o(.text) OBJDIR/fault_vectors.o(.text)
#ifdef MACHINE_FIREBEE #ifdef MACHINE_FIREBEE
OBJDIR/init_fpga.o(.text) OBJDIR/init_fpga.o(.text)
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
OBJDIR/wait.o(.text) OBJDIR/wait.o(.text)
OBJDIR/exceptions.o(.text) OBJDIR/exceptions.o(.text)
OBJDIR/driver_vec.o(.text) OBJDIR/driver_vec.o(.text)
OBJDIR/interrupts.o(.text) OBJDIR/interrupts.o(.text)
OBJDIR/mmu.o(.text) OBJDIR/mmu.o(.text)
OBJDIR/BaS.o(.text) OBJDIR/BaS.o(.text)
OBJDIR/pci.o(.text) OBJDIR/pci.o(.text)
OBJDIR/pci_wrappers.o(.text) OBJDIR/pci_wrappers.o(.text)
OBJDIR/usb.o(.text) OBJDIR/usb.o(.text)
OBJDIR/driver_mem.o(.text) OBJDIR/driver_mem.o(.text)
OBJDIR/usb_mouse.o(.text) OBJDIR/usb_mouse.o(.text)
OBJDIR/ohci-hcd.o(.text) OBJDIR/ohci-hcd.o(.text)
OBJDIR/ehci-hcd.o(.text) OBJDIR/ehci-hcd.o(.text)
OBJDIR/wait.o(.text) OBJDIR/wait.o(.text)
OBJDIR/nbuf.o(.text) OBJDIR/nbuf.o(.text)
OBJDIR/net_timer.o(.text) OBJDIR/net_timer.o(.text)
OBJDIR/queue.o(.text) OBJDIR/queue.o(.text)
OBJDIR/nif.o(.text) OBJDIR/nif.o(.text)
OBJDIR/fecbd.o(.text) OBJDIR/fecbd.o(.text)
OBJDIR/fec.o(.text) OBJDIR/fec.o(.text)
OBJDIR/am79c874.o(.text) OBJDIR/am79c874.o(.text)
OBJDIR/bcm5222.o(.text) OBJDIR/bcm5222.o(.text)
OBJDIR/ip.o(.text) OBJDIR/ip.o(.text)
OBJDIR/udp.o(text) OBJDIR/udp.o(text)
OBJDIR/bootp.o(text) OBJDIR/bootp.o(text)
OBJDIR/tftp.o(text) OBJDIR/tftp.o(text)
OBJDIR/arp.o(text) OBJDIR/arp.o(text)
OBJDIR/unicode.o(.text) OBJDIR/unicode.o(.text)
OBJDIR/mmc.o(.text) OBJDIR/mmc.o(.text)
OBJDIR/ff.o(.text) OBJDIR/ff.o(.text)
OBJDIR/sd_card.o(.text) OBJDIR/sd_card.o(.text)
OBJDIR/s19reader.o(.text) OBJDIR/s19reader.o(.text)
OBJDIR/bas_printf.o(.text) OBJDIR/bas_printf.o(.text)
OBJDIR/bas_string.o(.text) OBJDIR/bas_string.o(.text)
OBJDIR/printf_helper.o(.text) OBJDIR/printf_helper.o(.text)
OBJDIR/cache.o(.text) OBJDIR/cache.o(.text)
OBJDIR/dma.o(.text) OBJDIR/dma.o(.text)
OBJDIR/MCD_dmaApi.o(.text) OBJDIR/MCD_dmaApi.o(.text)
OBJDIR/MCD_tasks.o(.text) OBJDIR/MCD_tasks.o(.text)
OBJDIR/MCD_tasksInit.o(.text) OBJDIR/MCD_tasksInit.o(.text)
OBJDIR/video.o(.text) OBJDIR/video.o(.text)
OBJDIR/videl.o(.text) OBJDIR/videl.o(.text)
OBJDIR/fbmem.o(.text) OBJDIR/fbmem.o(.text)
OBJDIR/fbmon.o(.text) OBJDIR/fbmon.o(.text)
OBJDIR/fbmodedb.o(.text) OBJDIR/fbmodedb.o(.text)
OBJDIR/offscreen.o(.text) OBJDIR/offscreen.o(.text)
OBJDIR/x86decode.o(.text) OBJDIR/x86decode.o(.text)
OBJDIR/x86ops.o(.text) OBJDIR/x86ops.o(.text)
OBJDIR/x86ops2.o(.text) OBJDIR/x86ops2.o(.text)
OBJDIR/x86fpu.o(.text) OBJDIR/x86fpu.o(.text)
OBJDIR/x86sys.o(.text) OBJDIR/x86sys.o(.text)
OBJDIR/x86biosemu.o(.text) OBJDIR/x86biosemu.o(.text)
OBJDIR/x86debug.o(.text) OBJDIR/x86debug.o(.text)
OBJDIR/x86prim_ops.o(.text) OBJDIR/x86prim_ops.o(.text)
OBJDIR/x86pcibios.o(.text) OBJDIR/x86pcibios.o(.text)
OBJDIR/radeon_base.o(.text) OBJDIR/radeon_base.o(.text)
OBJDIR/radeon_accel.o(.text) OBJDIR/radeon_accel.o(.text)
OBJDIR/radeon_cursor.o(.text) OBJDIR/radeon_cursor.o(.text)
OBJDIR/radeon_monitor.o(.text) OBJDIR/radeon_monitor.o(.text)
OBJDIR/xhdi_sd.o(.text) OBJDIR/xhdi_sd.o(.text)
OBJDIR/xhdi_interface.o(.text) OBJDIR/xhdi_interface.o(.text)
OBJDIR/xhdi_vec.o(.text) OBJDIR/xhdi_vec.o(.text)
#ifdef COMPILE_RAM #ifdef COMPILE_RAM
/* /*
* if we compile to RAM anyway, there is no need to copy anything * if we compile to RAM anyway, there is no need to copy anything
*/ */
. = ALIGN(4); . = ALIGN(4);
__BAS_DATA_START = .; __BAS_DATA_START = .;
*(.data) *(.data)
__BAS_DATA_END = .; __BAS_DATA_END = .;
__BAS_BSS_START = .; __BAS_BSS_START = .;
*(.bss) *(.bss)
__BAS_BSS_END = .; __BAS_BSS_END = .;
#endif /* COMPILE_RAM */ #endif /* COMPILE_RAM */
#if (FORMAT_ELF == 1) #if (FORMAT_ELF == 1)
*(.rodata) *(.rodata)
*(.rodata.*) *(.rodata.*)
#endif #endif
} > bas_rom } > bas_rom
#if (TARGET_ADDRESS == BOOTFLASH_BASE_ADDRESS) #if (TARGET_ADDRESS == BOOTFLASH_BASE_ADDRESS)
/* /*
* put BaS .data and .bss segments to flash, but relocate it to RAM after initialize_hardware() ran * put BaS .data and .bss segments to flash, but relocate it to RAM after initialize_hardware() ran
*/ */
.bas : .bas :
AT (ALIGN(ADDR(.text) + SIZEOF(.text), 4)) AT (ALIGN(ADDR(.text) + SIZEOF(.text), 4))
{ {
. = ALIGN(4); /* same alignment than AT() statement! */ . = ALIGN(4); /* same alignment than AT() statement! */
__BAS_DATA_START = .; __BAS_DATA_START = .;
*(.data) *(.data)
__BAS_DATA_END = .; __BAS_DATA_END = .;
__BAS_BSS_START = .; __BAS_BSS_START = .;
*(.bss) *(.bss)
__BAS_BSS_END = .; __BAS_BSS_END = .;
. = ALIGN(16); . = ALIGN(16);
} > bas_ram } > bas_ram
#endif #endif
.driver_memory : .driver_memory :
{ {
. = ALIGN(4); . = ALIGN(4);
_driver_mem_buffer = .; _driver_mem_buffer = .;
//. = . + DRIVER_MEM_BUFFER_SIZE; //. = . + DRIVER_MEM_BUFFER_SIZE;
} > driver_ram } > driver_ram
/* /*
* Global memory map * Global memory map
*/ */
/* SDRAM Initialization */ /* SDRAM Initialization */
___SDRAM = SDRAM_START; ___SDRAM = SDRAM_START;
___SDRAM_SIZE = SDRAM_SIZE; ___SDRAM_SIZE = SDRAM_SIZE;
_SDRAM_VECTOR_TABLE = ___SDRAM; _SDRAM_VECTOR_TABLE = ___SDRAM;
/* ST-RAM */ /* ST-RAM */
__STRAM = ___SDRAM; __STRAM = ___SDRAM;
__STRAM_END = __TOS; __STRAM_END = __TOS;
/* TOS */ /* TOS */
__TOS = 0x00e00000; __TOS = 0x00e00000;
/* FastRAM */ /* FastRAM */
__FASTRAM = 0x10000000; __FASTRAM = 0x10000000;
__TARGET_ADDRESS = TARGET_ADDRESS; __TARGET_ADDRESS = TARGET_ADDRESS;
#if TARGET_ADDRESS == BOOTFLASH_BASE_ADDRESS #if TARGET_ADDRESS == BOOTFLASH_BASE_ADDRESS
__FASTRAM_END = __BAS_IN_RAM; __FASTRAM_END = __BAS_IN_RAM;
#else #else
__FASTRAM_END = TARGET_ADDRESS; __FASTRAM_END = TARGET_ADDRESS;
#endif #endif
__FASTRAM_SIZE = __FASTRAM_END - __FASTRAM; __FASTRAM_SIZE = __FASTRAM_END - __FASTRAM;
/* Init CS0 (BootFLASH @ E000_0000 - E07F_FFFF 8Mbytes) */ /* Init CS0 (BootFLASH @ E000_0000 - E07F_FFFF 8Mbytes) */
___BOOT_FLASH = BOOTFLASH_BASE_ADDRESS; ___BOOT_FLASH = BOOTFLASH_BASE_ADDRESS;
___BOOT_FLASH_SIZE = BOOTFLASH_SIZE; ___BOOT_FLASH_SIZE = BOOTFLASH_SIZE;
#if TARGET_ADDRESS == BOOTFLASH_BASE_ADDRESS #if TARGET_ADDRESS == BOOTFLASH_BASE_ADDRESS
/* BaS */ /* BaS */
__BAS_LMA = LOADADDR(.bas); __BAS_LMA = LOADADDR(.bas);
__BAS_IN_RAM = ADDR(.bas); __BAS_IN_RAM = ADDR(.bas);
__BAS_SIZE = SIZEOF(.bas); __BAS_SIZE = SIZEOF(.bas);
#else #else
/* BaS is already in RAM - no need to copy anything */ /* BaS is already in RAM - no need to copy anything */
__BAS_IN_RAM = __FASTRAM_END; __BAS_IN_RAM = __FASTRAM_END;
__BAS_SIZE = 0; __BAS_SIZE = 0;
__BAS_LMA = __BAS_IN_RAM; __BAS_LMA = __BAS_IN_RAM;
#endif #endif
/* Other flash components */ /* Other flash components */
__FIRETOS = 0xe0400000; __FIRETOS = 0xe0400000;
__EMUTOS = EMUTOS_BASE_ADDRESS; __EMUTOS = EMUTOS_BASE_ADDRESS;
__EMUTOS_SIZE = 0x00100000; __EMUTOS_SIZE = 0x00100000;
/* where FPGA data lives in flash */ /* where FPGA data lives in flash */
__FPGA_CONFIG = 0xe0700000; __FPGA_CONFIG = 0xe0700000;
__FPGA_CONFIG_SIZE = 0x100000; __FPGA_CONFIG_SIZE = 0x100000;
/* VIDEO RAM BASIS */ /* VIDEO RAM BASIS */
__VRAM = 0x60000000; __VRAM = 0x60000000;
/* Memory mapped registers */ /* Memory mapped registers */
__MBAR = 0xFF000000; __MBAR = 0xFF000000;
/* 32KB on-chip System SRAM */ /* 32KB on-chip System SRAM */
__SYS_SRAM = __MBAR + 0x10000; __SYS_SRAM = __MBAR + 0x10000;
__SYS_SRAM_SIZE = 0x00008000; __SYS_SRAM_SIZE = 0x00008000;
/* MMU memory mapped registers */ /* MMU memory mapped registers */
__MMUBAR = 0xFF040000; __MMUBAR = 0xFF040000;
/* /*
* 4KB on-chip Core SRAM0: -> exception table * 4KB on-chip Core SRAM0: -> exception table
*/ */
__RAMBAR0 = 0xFF100000; __RAMBAR0 = 0xFF100000;
__RAMBAR0_SIZE = 0x00001000; __RAMBAR0_SIZE = 0x00001000;
/* 4KB on-chip Core SRAM1 */ /* 4KB on-chip Core SRAM1 */
__RAMBAR1 = 0xFF101000; __RAMBAR1 = 0xFF101000;
__RAMBAR1_SIZE = 0x00001000; __RAMBAR1_SIZE = 0x00001000;
__SUP_SP = __RAMBAR1 + __RAMBAR1_SIZE - 4; __SUP_SP = __RAMBAR1 + __RAMBAR1_SIZE - 4;
/* /*
* this flag (if 1) indicates that FPGA configuration has been loaded through JTAG * this flag (if 1) indicates that FPGA configuration has been loaded through JTAG
* and shouldn't be overwritten on boot * and shouldn't be overwritten on boot
*/ */
__FPGA_JTAG_LOADED = __RAMBAR1; __FPGA_JTAG_LOADED = __RAMBAR1;
__FPGA_JTAG_VALID = __FPGA_JTAG_LOADED + 4; __FPGA_JTAG_VALID = __FPGA_JTAG_LOADED + 4;
/* system variables */ /* system variables */
/* RAMBAR0 0 to 0x7FF -> exception vectors */ /* RAMBAR0 0 to 0x7FF -> exception vectors */
_rt_mod = __RAMBAR0 + 0x800; _rt_mod = __RAMBAR0 + 0x800;
_rt_ssp = __RAMBAR0 + 0x804; _rt_ssp = __RAMBAR0 + 0x804;
_rt_usp = __RAMBAR0 + 0x808; _rt_usp = __RAMBAR0 + 0x808;
_rt_vbr = __RAMBAR0 + 0x80C; /* (8)01 */ _rt_vbr = __RAMBAR0 + 0x80C; /* (8)01 */
_rt_cacr = __RAMBAR0 + 0x810; /* 002 */ _rt_cacr = __RAMBAR0 + 0x810; /* 002 */
_rt_asid = __RAMBAR0 + 0x814; /* 003 */ _rt_asid = __RAMBAR0 + 0x814; /* 003 */
_rt_acr0 = __RAMBAR0 + 0x818; /* 004 */ _rt_acr0 = __RAMBAR0 + 0x818; /* 004 */
_rt_acr1 = __RAMBAR0 + 0x81c; /* 005 */ _rt_acr1 = __RAMBAR0 + 0x81c; /* 005 */
_rt_acr2 = __RAMBAR0 + 0x820; /* 006 */ _rt_acr2 = __RAMBAR0 + 0x820; /* 006 */
_rt_acr3 = __RAMBAR0 + 0x824; /* 007 */ _rt_acr3 = __RAMBAR0 + 0x824; /* 007 */
_rt_mmubar = __RAMBAR0 + 0x828; /* 008 */ _rt_mmubar = __RAMBAR0 + 0x828; /* 008 */
_rt_sr = __RAMBAR0 + 0x82c; _rt_sr = __RAMBAR0 + 0x82c;
_d0_save = __RAMBAR0 + 0x830; _d0_save = __RAMBAR0 + 0x830;
_a7_save = __RAMBAR0 + 0x834; _a7_save = __RAMBAR0 + 0x834;
_video_tlb = __RAMBAR0 + 0x838; _video_tlb = __RAMBAR0 + 0x838;
_video_sbt = __RAMBAR0 + 0x83C; _video_sbt = __RAMBAR0 + 0x83C;
_rt_mbar = __RAMBAR0 + 0x844; /* (c)0f */ _rt_mbar = __RAMBAR0 + 0x844; /* (c)0f */
} }

View File

@@ -23,21 +23,21 @@
* Author: Markus Fröschle * Author: Markus Fröschle
*/ */
#include <stdint.h> #include <bas_types.h>
#include <stddef.h>
#include "version.h" #include "version.h"
#include "xhdi_sd.h" #include "xhdi_sd.h"
#include "dma.h" #include "dma.h"
#include "driver_vec.h" #include "driver_vec.h"
#include "driver_mem.h" #include "driver_mem.h"
#include "pci.h" #include "pci.h"
#include "mmu.h"
/* /*
* driver interface struct for the SD card BaS driver * 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 = static struct dma_driver_interface dma_interface =
{ {
.version = 0x0101, .version = 0x0101,
.magic = 0x444d4143, /* 'DMAC' */ .magic = 0x444d4143, /* 'DMAC' */
.dma_set_initiator = dma_set_initiator, .dma_set_initiator = dma_set_initiator,
.dma_get_initiator = dma_get_initiator, .dma_get_initiator = dma_get_initiator,
.dma_free_initiator = dma_free_initiator, .dma_free_initiator = dma_free_initiator,
.dma_set_channel = dma_set_channel, .dma_set_channel = dma_set_channel,
.dma_get_channel = dma_get_channel, .dma_get_channel = dma_get_channel,
.dma_free_channel = dma_free_channel, .dma_free_channel = dma_free_channel,
.dma_clear_channel = dma_clear_channel, .dma_clear_channel = dma_clear_channel,
.MCD_startDma = MCD_startDma, .MCD_startDma = (int (*)(long, int8_t *, unsigned int, int8_t *, unsigned int,
.MCD_dmaStatus = MCD_dmaStatus, unsigned int, unsigned int, unsigned int, int,
.MCD_XferProgrQuery = MCD_XferProgrQuery, unsigned int, unsigned int)) MCD_startDma,
.MCD_killDma = MCD_killDma, .MCD_dmaStatus = (int32_t (*)(int32_t)) MCD_dmaStatus,
.MCD_continDma = MCD_continDma, .MCD_XferProgrQuery = (int32_t (*)(int32_t, MCD_XferProg *)) MCD_XferProgrQuery,
.MCD_pauseDma = MCD_pauseDma, .MCD_killDma = (int32_t (*)(int32_t)) MCD_killDma,
.MCD_resumeDma = MCD_resumeDma, .MCD_continDma = (int32_t (*)(int32_t)) MCD_continDma,
.MCD_csumQuery = MCD_csumQuery, .MCD_pauseDma = (int32_t (*)(int32_t)) MCD_pauseDma,
.dma_malloc = driver_mem_alloc, .MCD_resumeDma = (int32_t (*)(int32_t)) MCD_resumeDma,
.dma_free = driver_mem_free .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 * 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, .subjar = 0,
.version = 0x00010000, .version = 0x00010000,
.find_pci_device = wrapper_find_pci_device, .find_pci_device = wrapper_find_pci_device,
.find_pci_classcode = wrapper_find_pci_classcode, .find_pci_classcode = wrapper_find_pci_classcode,
.read_config_byte = wrapper_read_config_byte, .read_config_byte = wrapper_read_config_byte,
.read_config_word = wrapper_read_config_word, .read_config_word = wrapper_read_config_word,
.read_config_longword = wrapper_read_config_longword, .read_config_longword = wrapper_read_config_longword,
.fast_read_config_byte = wrapper_fast_read_config_byte, .fast_read_config_byte = wrapper_fast_read_config_byte,
.fast_read_config_word = wrapper_fast_read_config_word, .fast_read_config_word = wrapper_fast_read_config_word,
.fast_read_config_longword = wrapper_fast_read_config_longword, .fast_read_config_longword = wrapper_fast_read_config_longword,
.write_config_byte = wrapper_write_config_byte, .write_config_byte = wrapper_write_config_byte,
.write_config_word = wrapper_write_config_word, .write_config_word = wrapper_write_config_word,
.write_config_longword = wrapper_write_config_longword, .write_config_longword = wrapper_write_config_longword,
.hook_interrupt = wrapper_hook_interrupt, .hook_interrupt = wrapper_hook_interrupt,
.unhook_interrupt = wrapper_unhook_interrupt, .unhook_interrupt = wrapper_unhook_interrupt,
.special_cycle = wrapper_special_cycle, .special_cycle = wrapper_special_cycle,
.get_routing = wrapper_get_routing, .get_routing = wrapper_get_routing,
.set_interrupt = wrapper_set_interrupt, .set_interrupt = wrapper_set_interrupt,
.get_resource = wrapper_get_resource, .get_resource = wrapper_get_resource,
.get_card_used = wrapper_get_card_used, .get_card_used = wrapper_get_card_used,
.set_card_used = wrapper_set_card_used, .set_card_used = wrapper_set_card_used,
.read_mem_byte = wrapper_read_mem_byte, .read_mem_byte = wrapper_read_mem_byte,
.read_mem_word = wrapper_read_mem_word, .read_mem_word = wrapper_read_mem_word,
.read_mem_longword = wrapper_read_mem_longword, .read_mem_longword = wrapper_read_mem_longword,
.fast_read_mem_byte = wrapper_fast_read_mem_byte, .fast_read_mem_byte = wrapper_fast_read_mem_byte,
.fast_read_mem_word = wrapper_fast_read_mem_word, .fast_read_mem_word = wrapper_fast_read_mem_word,
.fast_read_mem_longword = wrapper_fast_read_mem_longword, .fast_read_mem_longword = wrapper_fast_read_mem_longword,
.write_mem_byte = wrapper_write_mem_byte, .write_mem_byte = wrapper_write_mem_byte,
.write_mem_word = wrapper_write_mem_word, .write_mem_word = wrapper_write_mem_word,
.write_mem_longword = wrapper_write_mem_longword, .write_mem_longword = wrapper_write_mem_longword,
.read_io_byte = wrapper_read_io_byte, .read_io_byte = wrapper_read_io_byte,
.read_io_word = wrapper_read_io_word, .read_io_word = wrapper_read_io_word,
.read_io_longword = wrapper_read_io_longword, .read_io_longword = wrapper_read_io_longword,
.fast_read_io_byte = wrapper_fast_read_io_byte, .fast_read_io_byte = wrapper_fast_read_io_byte,
.fast_read_io_word = wrapper_fast_read_io_word, .fast_read_io_word = wrapper_fast_read_io_word,
.fast_read_io_longword = wrapper_fast_read_io_longword, .fast_read_io_longword = wrapper_fast_read_io_longword,
.write_io_byte = wrapper_write_io_byte, .write_io_byte = wrapper_write_io_byte,
.write_io_word = wrapper_write_io_word, .write_io_word = wrapper_write_io_word,
.write_io_longword = wrapper_write_io_longword, .write_io_longword = wrapper_write_io_longword,
.get_machine_id = wrapper_get_machine_id, .get_machine_id = wrapper_get_machine_id,
.get_pagesize = wrapper_get_pagesize, .get_pagesize = wrapper_get_pagesize,
.virt_to_bus = wrapper_virt_to_bus, .virt_to_bus = wrapper_virt_to_bus,
.bus_to_virt = wrapper_bus_to_virt, .bus_to_virt = wrapper_bus_to_virt,
.virt_to_phys = wrapper_virt_to_phys, .virt_to_phys = wrapper_virt_to_phys,
.phys_to_virt = wrapper_phys_to_virt, .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 = static struct framebuffer_driver_interface framebuffer_interface =
{ {
.framebuffer_info = &info_fb .framebuffer_info = &info_fb
}; };
static struct generic_interface interfaces[] = static struct generic_interface interfaces[] =
{ {
{ {
/* BaS SD-card driver interface */ /* BaS SD-card driver interface */
.type = XHDI_DRIVER, .type = XHDI_DRIVER,
.name = "SDCARD", .name = "SDCARD",
.description = "BaS SD Card driver", .description = "BaS SD Card driver",
.version = 0, .version = 0,
.revision = 1, .revision = 1,
.interface.xhdi = &xhdi_call_interface .interface.xhdi = &xhdi_call_interface
}, },
{ {
.type = MCD_DRIVER, .type = MCD_DRIVER,
.name = "MCDDMA", .name = "MCDDMA",
.description = "BaS Multichannel DMA driver", .description = "BaS Multichannel DMA driver",
.version = 0, .version = 0,
.revision = 1, .revision = 1,
.interface.dma = &dma_interface, .interface.dma = &dma_interface,
}, },
{ {
.type = VIDEO_DRIVER, .type = VIDEO_DRIVER,
.name = "RADEON", .name = "RADEON",
.description = "BaS RADEON framebuffer driver", .description = "BaS RADEON framebuffer driver",
.version = 0, .version = 0,
.revision = 1, .revision = 1,
.interface.fb = &framebuffer_interface, .interface.fb = &framebuffer_interface,
}, },
{ {
.type = PCI_DRIVER, .type = PCI_DRIVER,
.name = "PCI", .name = "PCI",
.description = "BaS PCI_BIOS driver", .description = "BaS PCI_BIOS driver",
.version = 0, .version = 0,
.revision = 1, .revision = 1,
.interface.pci = &pci_interface, .interface.pci = &pci_interface,
}, },
/* insert new drivers here */ {
.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 * this is the driver table we expose to the OS
*/ */
static struct driver_table bas_drivers = static struct driver_table bas_drivers =
{ {
.bas_version = MAJOR_VERSION, .bas_version = MAJOR_VERSION,
.bas_revision = MINOR_VERSION, .bas_revision = MINOR_VERSION,
.remove_handler = NULL, .remove_handler = remove_handler,
.interfaces = { interfaces } .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) void __attribute__((interrupt)) get_bas_drivers(void)
{ {
__asm__ __volatile__( __asm__ __volatile(
"move.l #%[drivers],d0\n\t" /*
: /* no output */ * sp should now point to the next instruction after the trap
: [drivers] "o" (bas_drivers) /* input */ * The trap itself is 2 bytes, the four bytes before that must
: /* clobber */ * 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 */
);
} }

View File

@@ -31,52 +31,53 @@
enum driver_type enum driver_type
{ {
// BLOCKDEV_DRIVER, BLOCKDEV_DRIVER,
// CHARDEV_DRIVER, CHARDEV_DRIVER,
XHDI_DRIVER, XHDI_DRIVER,
MCD_DRIVER, MCD_DRIVER,
VIDEO_DRIVER, VIDEO_DRIVER,
PCI_DRIVER, PCI_DRIVER,
END_OF_DRIVERS, /* marks end of driver list */ MMU_DRIVER,
END_OF_DRIVERS = 0xffffffff /* marks end of driver list */
}; };
struct generic_driver_interface struct generic_driver_interface
{ {
uint32_t (*init)(void); uint32_t (*init)(void);
uint32_t (*read)(void *buf, size_t count); uint32_t (*read)(void *buf, size_t count);
uint32_t (*write)(const void *buf, size_t count); uint32_t (*write)(const void *buf, size_t count);
uint32_t (*ioctl)(uint32_t request, ...); uint32_t (*ioctl)(uint32_t request, ...);
}; };
struct dma_driver_interface struct dma_driver_interface
{ {
int32_t version; int32_t version;
int32_t magic; int32_t magic;
int (*dma_set_initiator)(int initiator); int (*dma_set_initiator)(int initiator);
uint32_t (*dma_get_initiator)(int requestor); uint32_t (*dma_get_initiator)(int requestor);
void (*dma_free_initiator)(int requestor); void (*dma_free_initiator)(int requestor);
int (*dma_set_channel)(int requestor, void (*handler)(void)); int (*dma_set_channel)(int requestor, void (*handler)(void));
int (*dma_get_channel)(int requestor); int (*dma_get_channel)(int requestor);
void (*dma_free_channel)(int requestor); void (*dma_free_channel)(int requestor);
void (*dma_clear_channel)(int channel); void (*dma_clear_channel)(int channel);
int (*MCD_startDma)(long channel, int (*MCD_startDma)(long channel,
int8_t *srcAddr, unsigned int srcIncr, int8_t *destAddr, unsigned int destIncr, 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 dmaSize, unsigned int xferSize, unsigned int initiator, int priority,
unsigned int flags, unsigned int funcDesc); unsigned int flags, unsigned int funcDesc);
int32_t (*MCD_dmaStatus)(int32_t channel); int32_t (*MCD_dmaStatus)(int32_t channel);
int32_t (*MCD_XferProgrQuery)(int32_t channel, MCD_XferProg *progRep); int32_t (*MCD_XferProgrQuery)(int32_t channel, MCD_XferProg *progRep);
int32_t (*MCD_killDma)(int32_t channel); int32_t (*MCD_killDma)(int32_t channel);
int32_t (*MCD_continDma)(int32_t channel); int32_t (*MCD_continDma)(int32_t channel);
int32_t (*MCD_pauseDma)(int32_t channel); int32_t (*MCD_pauseDma)(int32_t channel);
int32_t (*MCD_resumeDma)(int32_t channel); int32_t (*MCD_resumeDma)(int32_t channel);
int32_t (*MCD_csumQuery)(int32_t channel, uint32_t *csum); int32_t (*MCD_csumQuery)(int32_t channel, uint32_t *csum);
void *(*dma_malloc)(uint32_t amount); void *(*dma_malloc)(uint32_t amount);
int32_t (*dma_free)(void *addr); int32_t (*dma_free)(void *addr);
}; };
struct xhdi_driver_interface struct xhdi_driver_interface
{ {
uint32_t (*xhdivec)(); uint32_t (*xhdivec)();
}; };
/* Interpretation of offset for color fields: All offsets are from the right, /* 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 offset; /* beginning of bitfield */
unsigned long length; /* length of bitfield */ unsigned long length; /* length of bitfield */
unsigned long msb_right; /* != 0 : Most significant bit is */ 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 xres_virtual; /* virtual resolution */
unsigned long yres_virtual; unsigned long yres_virtual;
unsigned long xoffset; /* offset from virtual to visible */ 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 */ unsigned long grayscale; /* != 0 Graylevels instead of colors */
struct fb_bitfield red; /* bitfield in fb mem if true color, */ struct fb_bitfield red; /* bitfield in fb mem if true color, */
struct fb_bitfield green; /* else only length is significant */ struct fb_bitfield green; /* else only length is significant */
struct fb_bitfield blue; struct fb_bitfield blue;
struct fb_bitfield transp; /* transparency */ struct fb_bitfield transp; /* transparency */
unsigned long nonstd; /* != 0 Non standard pixel format */ 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 height; /* height of picture in mm */
unsigned long width; /* width 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 lower_margin;
unsigned long hsync_len; /* length of horizontal sync */ unsigned long hsync_len; /* length of horizontal sync */
unsigned long vsync_len; /* length of vertical 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 vmode; /* see FB_VMODE_* */
unsigned long rotate; /* angle we rotate counter clockwise */ unsigned long rotate; /* angle we rotate counter clockwise */
unsigned long refresh; unsigned long refresh;
@@ -143,7 +144,7 @@ struct fb_fix_screeninfo
unsigned long smem_start; /* Start of frame buffer mem */ unsigned long smem_start; /* Start of frame buffer mem */
/* (physical address) */ /* (physical address) */
unsigned long smem_len; /* Length of frame buffer mem */ 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 type_aux; /* Interleave for interleaved Planes */
unsigned long visual; /* see FB_VISUAL_* */ unsigned long visual; /* see FB_VISUAL_* */
unsigned short xpanstep; /* zero if no hardware panning */ unsigned short xpanstep; /* zero if no hardware panning */
@@ -160,7 +161,7 @@ struct fb_fix_screeninfo
struct fb_chroma struct fb_chroma
{ {
unsigned long redx; /* in fraction of 1024 */ unsigned long redx; /* in fraction of 1024 */
unsigned long greenx; unsigned long greenx;
unsigned long bluex; unsigned long bluex;
unsigned long whitex; unsigned long whitex;
@@ -203,87 +204,97 @@ struct fb_monspecs
struct framebuffer_driver_interface 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 { struct pci_bios_interface
uint32_t subjar; {
uint32_t version; uint32_t subjar;
/* Although we declare this functions as standard gcc functions (cdecl), uint32_t version;
* they expect paramenters inside registers (fastcall) unsupported by gcc m68k. /* Although we declare this functions as standard gcc functions (cdecl),
* Caller will take care of parameters passing convention. * 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 (*find_pci_device) (uint32_t id, uint16_t index);
int32_t (*read_config_byte) (int32_t handle, uint16_t reg, uint8_t *address); int32_t (*find_pci_classcode) (uint32_t class, uint16_t index);
int32_t (*read_config_word) (int32_t handle, uint16_t reg, uint16_t *address); int32_t (*read_config_byte) (int32_t handle, uint16_t reg, uint8_t *address);
int32_t (*read_config_longword) (int32_t handle, uint16_t reg, uint32_t *address); int32_t (*read_config_word) (int32_t handle, uint16_t reg, uint16_t *address);
uint8_t (*fast_read_config_byte) (int32_t handle, uint16_t reg); int32_t (*read_config_longword) (int32_t handle, uint16_t reg, uint32_t *address);
uint16_t (*fast_read_config_word) (int32_t handle, uint16_t reg); uint8_t (*fast_read_config_byte) (int32_t handle, uint16_t reg);
uint32_t (*fast_read_config_longword) (int32_t handle, uint16_t reg); uint16_t (*fast_read_config_word) (int32_t handle, uint16_t reg);
int32_t (*write_config_byte) (int32_t handle, uint16_t reg, uint16_t val); uint32_t (*fast_read_config_longword) (int32_t handle, uint16_t reg);
int32_t (*write_config_word) (int32_t handle, uint16_t reg, uint16_t val); int32_t (*write_config_byte) (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 (*write_config_word) (int32_t handle, uint16_t reg, uint16_t val);
int32_t (*hook_interrupt) (int32_t handle, uint32_t *routine, uint32_t *parameter); int32_t (*write_config_longword) (int32_t handle, uint16_t reg, uint32_t val);
int32_t (*unhook_interrupt) (int32_t handle); int32_t (*hook_interrupt) (int32_t handle, uint32_t *routine, uint32_t *parameter);
int32_t (*special_cycle) (uint16_t bus, uint32_t data); int32_t (*unhook_interrupt) (int32_t handle);
int32_t (*get_routing) (int32_t handle); int32_t (*special_cycle) (uint16_t bus, uint32_t data);
int32_t (*set_interrupt) (int32_t handle); int32_t (*get_routing) (int32_t handle);
int32_t (*get_resource) (int32_t handle); int32_t (*set_interrupt) (int32_t handle);
int32_t (*get_card_used) (int32_t handle, uint32_t *address); int32_t (*get_resource) (int32_t handle);
int32_t (*set_card_used) (int32_t handle, uint32_t *callback); int32_t (*get_card_used) (int32_t handle, uint32_t *address);
int32_t (*read_mem_byte) (int32_t handle, uint32_t offset, uint8_t *address); int32_t (*set_card_used) (int32_t handle, uint32_t *callback);
int32_t (*read_mem_word) (int32_t handle, uint32_t offset, uint16_t *address); int32_t (*read_mem_byte) (int32_t handle, uint32_t offset, uint8_t *address);
int32_t (*read_mem_longword) (int32_t handle, uint32_t offset, uint32_t *address); int32_t (*read_mem_word) (int32_t handle, uint32_t offset, uint16_t *address);
uint8_t (*fast_read_mem_byte) (int32_t handle, uint32_t offset); int32_t (*read_mem_longword) (int32_t handle, uint32_t offset, uint32_t *address);
uint16_t (*fast_read_mem_word) (int32_t handle, uint32_t offset); uint8_t (*fast_read_mem_byte) (int32_t handle, uint32_t offset);
uint32_t (*fast_read_mem_longword) (int32_t handle, uint32_t offset); uint16_t (*fast_read_mem_word) (int32_t handle, uint32_t offset);
int32_t (*write_mem_byte) (int32_t handle, uint32_t offset, uint16_t val); uint32_t (*fast_read_mem_longword) (int32_t handle, uint32_t offset);
int32_t (*write_mem_word) (int32_t handle, uint32_t offset, uint16_t val); int32_t (*write_mem_byte) (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 (*write_mem_word) (int32_t handle, uint32_t offset, uint16_t val);
int32_t (*read_io_byte) (int32_t handle, uint32_t offset, uint8_t *address); int32_t (*write_mem_longword) (int32_t handle, uint32_t offset, uint32_t val);
int32_t (*read_io_word) (int32_t handle, uint32_t offset, uint16_t *address); int32_t (*read_io_byte) (int32_t handle, uint32_t offset, uint8_t *address);
int32_t (*read_io_longword) (int32_t handle, uint32_t offset, uint32_t *address); int32_t (*read_io_word) (int32_t handle, uint32_t offset, uint16_t *address);
uint8_t (*fast_read_io_byte) (int32_t handle, uint32_t offset); int32_t (*read_io_longword) (int32_t handle, uint32_t offset, uint32_t *address);
uint16_t (*fast_read_io_word) (int32_t handle, uint32_t offset); uint8_t (*fast_read_io_byte) (int32_t handle, uint32_t offset);
uint32_t (*fast_read_io_longword) (int32_t handle, uint32_t offset); uint16_t (*fast_read_io_word) (int32_t handle, uint32_t offset);
int32_t (*write_io_byte) (int32_t handle, uint32_t offset, uint16_t val); uint32_t (*fast_read_io_longword) (int32_t handle, uint32_t offset);
int32_t (*write_io_word) (int32_t handle, uint32_t offset, uint16_t val); int32_t (*write_io_byte) (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 (*write_io_word) (int32_t handle, uint32_t offset, uint16_t val);
int32_t (*get_machine_id) (void); int32_t (*write_io_longword) (int32_t handle, uint32_t offset, uint32_t val);
int32_t (*get_pagesize) (void); int32_t (*get_machine_id) (void);
int32_t (*virt_to_bus) (int32_t handle, uint32_t address, PCI_CONV_ADR *pointer); int32_t (*get_pagesize) (void);
int32_t (*bus_to_virt) (int32_t handle, uint32_t address, PCI_CONV_ADR *pointer); int32_t (*virt_to_bus) (int32_t handle, uint32_t address, PCI_CONV_ADR *pointer);
int32_t (*virt_to_phys) (uint32_t address, PCI_CONV_ADR *pointer); int32_t (*bus_to_virt) (int32_t handle, uint32_t address, PCI_CONV_ADR *pointer);
int32_t (*phys_to_virt) (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]; // 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 union interface
{ {
struct generic_driver_interface *gdi; struct generic_driver_interface *gdi;
struct xhdi_driver_interface *xhdi; struct xhdi_driver_interface *xhdi;
struct dma_driver_interface *dma; struct dma_driver_interface *dma;
struct framebuffer_driver_interface *fb; struct framebuffer_driver_interface *fb;
struct pci_bios_interface *pci; struct pci_bios_interface *pci;
struct mmu_driver_interface *mmu;
}; };
struct generic_interface struct generic_interface
{ {
enum driver_type type; enum driver_type type;
char name[16]; char name[16];
char description[64]; char description[64];
int version; int version;
int revision; int revision;
union interface interface; union interface interface;
}; };
struct driver_table struct driver_table
{ {
uint32_t bas_version; uint32_t bas_version;
uint32_t bas_revision; uint32_t bas_revision;
uint32_t (*remove_handler)(); /* calling this will disable the BaS' hook into trap #0 */ void (*remove_handler)(void); /* calling this will disable the BaS' hook into trap #0 */
struct generic_interface *interfaces[]; struct generic_interface *interfaces;
}; };

View File

@@ -11,7 +11,7 @@
#include "bas_printf.h" #include "bas_printf.h"
#include <stddef.h> #include <stddef.h>
#define DBG_FECBD //#define DBG_FECBD
#ifdef DBG_FECBD #ifdef DBG_FECBD
#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0) #define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0)
#else #else
@@ -62,94 +62,94 @@ static int iRxbd;
*/ */
void fecbd_init(uint8_t ch) void fecbd_init(uint8_t ch)
{ {
NBUF *nbuf; NBUF *nbuf;
int i; int i;
dbg("\r\n"); dbg("\r\n");
/* /*
* Align Buffer Descriptors to 4-byte boundary * Align Buffer Descriptors to 4-byte boundary
*/ */
RxBD = (FECBD *)(((int) unaligned_bds + 3) & 0xFFFFFFFC); RxBD = (FECBD *)(((int) unaligned_bds + 3) & 0xFFFFFFFC);
TxBD = (FECBD *)((int) RxBD + (sizeof(FECBD) * 2 * NRXBD)); TxBD = (FECBD *)((int) RxBD + (sizeof(FECBD) * 2 * NRXBD));
dbg("initialise RX buffer descriptor ring\r\n"); dbg("initialise RX buffer descriptor ring\r\n");
/* /*
* Initialize the Rx Buffer Descriptor ring * Initialize the Rx Buffer Descriptor ring
*/ */
for (i = 0; i < NRXBD; ++i) for (i = 0; i < NRXBD; ++i)
{ {
/* Grab a network buffer from the free list */ /* Grab a network buffer from the free list */
nbuf = nbuf_alloc(); nbuf = nbuf_alloc();
if (nbuf == NULL) if (nbuf == NULL)
{ {
dbg("could not allocate network buffer\r\n"); dbg("could not allocate network buffer\r\n");
return; return;
} }
/* Initialize the BD */ /* Initialize the BD */
RxBD(ch,i).status = RX_BD_E | RX_BD_INTERRUPT; RxBD(ch,i).status = RX_BD_E | RX_BD_INTERRUPT;
RxBD(ch,i).length = RX_BUF_SZ; RxBD(ch,i).length = RX_BUF_SZ;
RxBD(ch,i).data = nbuf->data; RxBD(ch,i).data = nbuf->data;
/* Add the network buffer to the Rx queue */ /* Add the network buffer to the Rx queue */
nbuf_add(NBUF_RX_RING, nbuf); nbuf_add(NBUF_RX_RING, nbuf);
} }
/* /*
* Set the WRAP bit on the last one * Set the WRAP bit on the last one
*/ */
RxBD(ch, i - 1).status |= RX_BD_W; RxBD(ch, i - 1).status |= RX_BD_W;
dbg("initialise TX buffer descriptor ring\r\n"); dbg("initialise TX buffer descriptor ring\r\n");
/* /*
* Initialize the Tx Buffer Descriptor ring * Initialize the Tx Buffer Descriptor ring
*/ */
for (i = 0; i < NTXBD; ++i) for (i = 0; i < NTXBD; ++i)
{ {
TxBD(ch, i).status = TX_BD_INTERRUPT; TxBD(ch, i).status = TX_BD_INTERRUPT;
TxBD(ch, i).length = 0; TxBD(ch, i).length = 0;
TxBD(ch, i).data = NULL; TxBD(ch, i).data = NULL;
} }
/* /*
* Set the WRAP bit on the last one * Set the WRAP bit on the last one
*/ */
TxBD(ch, i - 1).status |= TX_BD_W; TxBD(ch, i - 1).status |= TX_BD_W;
/* /*
* Initialize the buffer descriptor indexes * Initialize the buffer descriptor indexes
*/ */
iTxbd_new = iTxbd_old = iRxbd = 0; iTxbd_new = iTxbd_old = iRxbd = 0;
} }
void fecbd_dump(uint8_t ch) void fecbd_dump(uint8_t ch)
{ {
#ifdef DBG_FECBD #ifdef DBG_FECBD
int i; int i;
xprintf("\n------------ FEC%d BDs -----------\n",ch); xprintf("\n------------ FEC%d BDs -----------\n",ch);
xprintf("RxBD Ring\n"); xprintf("RxBD Ring\n");
for (i = 0; i < NRXBD; i++) for (i = 0; i < NRXBD; i++)
{ {
xprintf("%02d: BD Addr=0x%08x, Ctrl=0x%04x, Lgth=%04d, DataPtr=0x%08x\n", xprintf("%02d: BD Addr=0x%08x, Ctrl=0x%04x, Lgth=%04d, DataPtr=0x%08x\n",
i, &RxBD(ch, i), i, &RxBD(ch, i),
RxBD(ch, i).status, RxBD(ch, i).status,
RxBD(ch, i).length, RxBD(ch, i).length,
RxBD(ch, i).data); RxBD(ch, i).data);
} }
xprintf("TxBD Ring\n"); xprintf("TxBD Ring\n");
for (i = 0; i < NTXBD; i++) for (i = 0; i < NTXBD; i++)
{ {
xprintf("%02d: BD Addr=0x%08x, Ctrl=0x%04x, Lgth=%04d, DataPtr=0x%08x\n", xprintf("%02d: BD Addr=0x%08x, Ctrl=0x%04x, Lgth=%04d, DataPtr=0x%08x\n",
i, &TxBD(ch, i), i, &TxBD(ch, i),
TxBD(ch, i).status, TxBD(ch, i).status,
TxBD(ch, i).length, TxBD(ch, i).length,
TxBD(ch, i).data); TxBD(ch, i).data);
} }
xprintf("--------------------------------\n\n"); xprintf("--------------------------------\n\n");
#endif /* DBG_FECBD */ #endif /* DBG_FECBD */
} }
@@ -165,28 +165,28 @@ void fecbd_dump(uint8_t ch)
*/ */
uint32_t fecbd_get_start(uint8_t ch, uint8_t direction) uint32_t fecbd_get_start(uint8_t ch, uint8_t direction)
{ {
switch (direction) switch (direction)
{ {
case Rx: case Rx:
return (uint32_t)((int)RxBD + (ch * sizeof(FECBD) * NRXBD)); return (uint32_t)((int)RxBD + (ch * sizeof(FECBD) * NRXBD));
case Tx: case Tx:
default: default:
return (uint32_t)((int)TxBD + (ch * sizeof(FECBD) * NTXBD)); return (uint32_t)((int)TxBD + (ch * sizeof(FECBD) * NTXBD));
} }
} }
FECBD *fecbd_rx_alloc(uint8_t ch) FECBD *fecbd_rx_alloc(uint8_t ch)
{ {
int i = iRxbd; int i = iRxbd;
/* Check to see if the ring of BDs is full */ /* Check to see if the ring of BDs is full */
if (RxBD(ch, i).status & RX_BD_E) if (RxBD(ch, i).status & RX_BD_E)
return NULL; return NULL;
/* Increment the circular index */ /* Increment the circular index */
iRxbd = (uint8_t)((iRxbd + 1) % NRXBD); 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) 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 */ /* Check to see if the ring of BDs is full */
if (TxBD(ch, i).status & TX_BD_R) if (TxBD(ch, i).status & TX_BD_R)
return NULL; return NULL;
/* Increment the circular index */ /* Increment the circular index */
iTxbd_new = (uint8_t)((iTxbd_new + 1) % NTXBD); 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) 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 */ /* Check to see if the ring of BDs is empty */
if ((TxBD(ch, i).data == NULL) || (TxBD(ch, i).status & TX_BD_R)) if ((TxBD(ch, i).data == NULL) || (TxBD(ch, i).status & TX_BD_R))
return NULL; return NULL;
/* Increment the circular index */ /* Increment the circular index */
iTxbd_old = (uint8_t)((iTxbd_old + 1) % NTXBD); iTxbd_old = (uint8_t)((iTxbd_old + 1) % NTXBD);
return &TxBD(ch, i); return &TxBD(ch, i);
} }

448
net/ip.c
View File

@@ -1,5 +1,5 @@
/* /*
* File: ip.c * File: ip.c
* Purpose: Internet Protcol device driver * Purpose: Internet Protcol device driver
* *
* Notes: * Notes:
@@ -13,7 +13,7 @@
#include <stddef.h> #include <stddef.h>
#define IP_DEBUG //#define IP_DEBUG
#if defined(IP_DEBUG) #if defined(IP_DEBUG)
#define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0) #define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0)
#else #else
@@ -22,300 +22,300 @@
void ip_init(IP_INFO *info, IP_ADDR_P myip, IP_ADDR_P gateway, IP_ADDR_P netmask) 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++) for (index = 0; index < sizeof(IP_ADDR); index++)
{ {
info->myip[index] = myip[index]; info->myip[index] = myip[index];
info->gateway[index] = gateway[index]; info->gateway[index] = gateway[index];
info->netmask[index] = netmask[index]; info->netmask[index] = netmask[index];
info->broadcast[index] = 0xFF; info->broadcast[index] = 0xFF;
} }
info->rx = 0; info->rx = 0;
info->rx_unsup = 0; info->rx_unsup = 0;
info->tx = 0; info->tx = 0;
info->err = 0; info->err = 0;
} }
uint8_t *ip_get_myip(IP_INFO *info) uint8_t *ip_get_myip(IP_INFO *info)
{ {
if (info != 0) if (info != 0)
{ {
return (uint8_t *) &info->myip[0]; return (uint8_t *) &info->myip[0];
} }
dbg("info is NULL!\n\t"); dbg("info is NULL!\n\t");
return 0; return 0;
} }
int ip_addr_compare(IP_ADDR_P addr1, IP_ADDR_P addr2) int ip_addr_compare(IP_ADDR_P addr1, IP_ADDR_P addr2)
{ {
int i; int i;
for (i = 0; i < sizeof(IP_ADDR); i++) for (i = 0; i < sizeof(IP_ADDR); i++)
{ {
if (addr1[i] != addr2[i]) if (addr1[i] != addr2[i])
return 0; return 0;
} }
return 1; return 1;
} }
uint8_t *ip_resolve_route(NIF *nif, IP_ADDR_P destip) uint8_t *ip_resolve_route(NIF *nif, IP_ADDR_P destip)
{ {
/* /*
* This function determines whether or not an outgoing IP * This function determines whether or not an outgoing IP
* packet needs to be transmitted on the local net or sent * packet needs to be transmitted on the local net or sent
* to the router for transmission. * to the router for transmission.
*/ */
IP_INFO *info; IP_INFO *info;
IP_ADDR mask, result; IP_ADDR mask, result;
IP_ADDR bc = { 255, 255, 255, 255 }; IP_ADDR bc = { 255, 255, 255, 255 };
int i; 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) if (memcmp(destip, bc, 4) == 0)
{ {
dbg("destip is broadcast address, no gateway needed\r\n"); dbg("destip is broadcast address, no gateway needed\r\n");
return destip; return destip;
} }
/* create mask for local IP */ /* create mask for local IP */
for (i = 0; i < sizeof(IP_ADDR); i++) for (i = 0; i < sizeof(IP_ADDR); i++)
{ {
mask[i] = info->myip[i] & info->netmask[i]; mask[i] = info->myip[i] & info->netmask[i];
} }
/* apply mask to the destination IP */ /* apply mask to the destination IP */
for (i = 0; i < sizeof(IP_ADDR); i++) for (i = 0; i < sizeof(IP_ADDR); i++)
{ {
result[i] = mask[i] & destip[i]; result[i] = mask[i] & destip[i];
} }
/* See if destination IP is local or not */ /* See if destination IP is local or not */
if (ip_addr_compare(mask, result)) if (ip_addr_compare(mask, result))
{ {
/* The destination IP is on the local net */ /* The destination IP is on the local net */
return arp_resolve(nif, ETH_FRM_IP, destip); return arp_resolve(nif, ETH_FRM_IP, destip);
} }
else else
{ {
/* The destination IP is not on the local net */ /* The destination IP is not on the local net */
return arp_resolve(nif, ETH_FRM_IP, info->gateway); 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) 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 * This function assembles an IP datagram and passes it
* onto the hardware to be sent over the network. * onto the hardware to be sent over the network.
*/ */
uint8_t *route; uint8_t *route;
ip_frame_hdr *ipframe; ip_frame_hdr *ipframe;
/* /*
* Construct the IP header * Construct the IP header
*/ */
ipframe = (ip_frame_hdr*) &pNbuf->data[IP_HDR_OFFSET]; ipframe = (ip_frame_hdr*) &pNbuf->data[IP_HDR_OFFSET];
/* IP version 4, Internet Header Length of 5 32-bit words */ /* IP version 4, Internet Header Length of 5 32-bit words */
ipframe->version_ihl = 0x45; ipframe->version_ihl = 0x45;
/* Type of Service == 0, normal and routine */ /* Type of Service == 0, normal and routine */
ipframe->service_type = 0x00; ipframe->service_type = 0x00;
/* Total length of data */ /* Total length of data */
ipframe->total_length = (uint16_t) (pNbuf->length + IP_HDR_SIZE); ipframe->total_length = (uint16_t) (pNbuf->length + IP_HDR_SIZE);
/* User defined identification */ /* User defined identification */
ipframe->identification = 0x0000; ipframe->identification = 0x0000;
/* Fragment Flags and Offset -- Don't fragment, last frag */ /* Fragment Flags and Offset -- Don't fragment, last frag */
ipframe->flags_frag_offset = 0x0000; ipframe->flags_frag_offset = 0x0000;
/* Time To Live */ /* Time To Live */
ipframe->ttl = 0xFF; ipframe->ttl = 0xFF;
/* Protocol */ /* Protocol */
ipframe->protocol = protocol; ipframe->protocol = protocol;
/* Checksum, computed later, zeroed for computation */ /* Checksum, computed later, zeroed for computation */
ipframe->checksum = 0x0000; ipframe->checksum = 0x0000;
/* source IP address */ /* source IP address */
ipframe->source_addr[0] = src[0]; ipframe->source_addr[0] = src[0];
ipframe->source_addr[1] = src[1]; ipframe->source_addr[1] = src[1];
ipframe->source_addr[2] = src[2]; ipframe->source_addr[2] = src[2];
ipframe->source_addr[3] = src[3]; ipframe->source_addr[3] = src[3];
/* dest IP address */ /* dest IP address */
ipframe->dest_addr[0] = dest[0]; ipframe->dest_addr[0] = dest[0];
ipframe->dest_addr[1] = dest[1]; ipframe->dest_addr[1] = dest[1];
ipframe->dest_addr[2] = dest[2]; ipframe->dest_addr[2] = dest[2];
ipframe->dest_addr[3] = dest[3]; ipframe->dest_addr[3] = dest[3];
/* Compute checksum */ /* Compute checksum */
ipframe->checksum = ip_chksum((uint16_t *) ipframe, IP_HDR_SIZE); ipframe->checksum = ip_chksum((uint16_t *) ipframe, IP_HDR_SIZE);
/* Increment the packet length by the size of the IP header */ /* Increment the packet length by the size of the IP header */
pNbuf->length += IP_HDR_SIZE; pNbuf->length += IP_HDR_SIZE;
/* /*
* Determine the hardware address of the recipient * Determine the hardware address of the recipient
*/ */
IP_ADDR bc = { 255, 255, 255, 255}; IP_ADDR bc = { 255, 255, 255, 255};
if (memcmp(bc, dest, 4) != 0) if (memcmp(bc, dest, 4) != 0)
{ {
route = ip_resolve_route(nif, dest); route = ip_resolve_route(nif, dest);
if (route == NULL) if (route == NULL)
{ {
dbg("Unable to locate %d.%d.%d.%d\r\n", dbg("Unable to locate %d.%d.%d.%d\r\n",
dest[0], dest[1], dest[2], dest[3]); dest[0], dest[1], dest[2], dest[3]);
return 0; return 0;
} }
} }
else else
{ {
route = bc; route = bc;
dbg("route = broadcast\r\n"); dbg("route = broadcast\r\n");
dbg("nif = %p\r\n", nif); dbg("nif = %p\r\n", nif);
dbg("nif->send = %p\r\n", nif->send); 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) #if defined(DEBUG_PRINT)
void dump_ip_frame(ip_frame_hdr *ipframe) void dump_ip_frame(ip_frame_hdr *ipframe)
{ {
xprintf("Version: %02X\n", ((ipframe->version_ihl & 0x00f0) >> 4)); xprintf("Version: %02X\n", ((ipframe->version_ihl & 0x00f0) >> 4));
xprintf("IHL: %02X\n", ipframe->version_ihl & 0x000f); xprintf("IHL: %02X\n", ipframe->version_ihl & 0x000f);
xprintf("Service: %02X\n", ipframe->service_type); xprintf("Service: %02X\n", ipframe->service_type);
xprintf("Length: %04X\n", ipframe->total_length); xprintf("Length: %04X\n", ipframe->total_length);
xprintf("Ident: %04X\n", ipframe->identification); xprintf("Ident: %04X\n", ipframe->identification);
xprintf("Flags: %02X\n", ((ipframe->flags_frag_offset & 0xC000) >> 14)); xprintf("Flags: %02X\n", ((ipframe->flags_frag_offset & 0xC000) >> 14));
xprintf("Frag: %04X\n", ipframe->flags_frag_offset & 0x3FFF); xprintf("Frag: %04X\n", ipframe->flags_frag_offset & 0x3FFF);
xprintf("TTL: %02X\n", ipframe->ttl); xprintf("TTL: %02X\n", ipframe->ttl);
xprintf("Protocol: %02X\n", ipframe->protocol); xprintf("Protocol: %02X\n", ipframe->protocol);
xprintf("Chksum: %04X\n", ipframe->checksum); xprintf("Chksum: %04X\n", ipframe->checksum);
xprintf("Source : %d.%d.%d.%d\n", xprintf("Source : %d.%d.%d.%d\n",
ipframe->source_addr[0], ipframe->source_addr[0],
ipframe->source_addr[1], ipframe->source_addr[1],
ipframe->source_addr[2], ipframe->source_addr[2],
ipframe->source_addr[3]); ipframe->source_addr[3]);
xprintf("Dest : %d.%d.%d.%d\n", xprintf("Dest : %d.%d.%d.%d\n",
ipframe->dest_addr[0], ipframe->dest_addr[0],
ipframe->dest_addr[1], ipframe->dest_addr[1],
ipframe->dest_addr[2], ipframe->dest_addr[2],
ipframe->dest_addr[3]); ipframe->dest_addr[3]);
xprintf("Options: %08X\n", ipframe->options); xprintf("Options: %08X\n", ipframe->options);
} }
#endif #endif
uint16_t ip_chksum(uint16_t *data, int num) uint16_t ip_chksum(uint16_t *data, int num)
{ {
int chksum, ichksum; int chksum, ichksum;
uint16_t temp; uint16_t temp;
chksum = 0; chksum = 0;
num = num >> 1; /* from bytes to words */ num = num >> 1; /* from bytes to words */
for (; num; num--, data++) for (; num; num--, data++)
{ {
temp = *data; temp = *data;
ichksum = chksum + temp; ichksum = chksum + temp;
ichksum = ichksum & 0x0000FFFF; ichksum = ichksum & 0x0000FFFF;
if ((ichksum < temp) || (ichksum < chksum)) if ((ichksum < temp) || (ichksum < chksum))
{ {
ichksum += 1; ichksum += 1;
ichksum = ichksum & 0x0000FFFF; ichksum = ichksum & 0x0000FFFF;
} }
chksum = ichksum; chksum = ichksum;
} }
return (uint16_t) ~chksum; return (uint16_t) ~chksum;
} }
static int validate_ip_hdr(NIF *nif, ip_frame_hdr *ipframe) static int validate_ip_hdr(NIF *nif, ip_frame_hdr *ipframe)
{ {
int index, chksum; int index, chksum;
IP_INFO *info; IP_INFO *info;
/* /*
* Check the IP Version * Check the IP Version
*/ */
if (IP_VERSION(ipframe) != 4) if (IP_VERSION(ipframe) != 4)
return 0; return 0;
/* /*
* Check Internet Header Length * Check Internet Header Length
*/ */
if (IP_IHL(ipframe) < 5) if (IP_IHL(ipframe) < 5)
return 0; return 0;
/* /*
* Check the destination IP address * Check the destination IP address
*/ */
info = nif_get_protocol_info(nif,ETH_FRM_IP); info = nif_get_protocol_info(nif,ETH_FRM_IP);
for (index = 0; index < sizeof(IP_ADDR); index++) for (index = 0; index < sizeof(IP_ADDR); index++)
if (info->myip[index] != ipframe->dest_addr[index]) if (info->myip[index] != ipframe->dest_addr[index])
return 0; return 0;
/* /*
* Check the checksum * Check the checksum
*/ */
chksum = (int)((uint16_t) IP_CHKSUM(ipframe)); chksum = (int)((uint16_t) IP_CHKSUM(ipframe));
IP_CHKSUM(ipframe) = 0; IP_CHKSUM(ipframe) = 0;
if (ip_chksum((uint16_t *) ipframe, IP_IHL(ipframe) * 4) != chksum) if (ip_chksum((uint16_t *) ipframe, IP_IHL(ipframe) * 4) != chksum)
return 0; 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) void ip_handler(NIF *nif, NBUF *pNbuf)
{ {
/* /*
* IP packet handler * IP packet handler
*/ */
ip_frame_hdr *ipframe; ip_frame_hdr *ipframe;
dbg("packet received\r\n"); dbg("packet received\r\n");
ipframe = (ip_frame_hdr *) &pNbuf->data[pNbuf->offset]; ipframe = (ip_frame_hdr *) &pNbuf->data[pNbuf->offset];
/* /*
* Verify valid IP header and destination IP * Verify valid IP header and destination IP
*/ */
if (!validate_ip_hdr(nif, ipframe)) if (!validate_ip_hdr(nif, ipframe))
{ {
dbg("not a valid IP packet!\r\n"); dbg("not a valid IP packet!\r\n");
nbuf_free(pNbuf);
return;
}
pNbuf->offset += (IP_IHL(ipframe) * 4); nbuf_free(pNbuf);
pNbuf->length = (uint16_t)(IP_LENGTH(ipframe) - (IP_IHL(ipframe) * 4)); return;
}
/* pNbuf->offset += (IP_IHL(ipframe) * 4);
* Call the appriopriate handler pNbuf->length = (uint16_t)(IP_LENGTH(ipframe) - (IP_IHL(ipframe) * 4));
*/
switch (IP_PROTOCOL(ipframe)) /*
{ * Call the appriopriate handler
case IP_PROTO_ICMP: */
// FIXME: icmp_handler(nif, pNbuf); switch (IP_PROTOCOL(ipframe))
break; {
case IP_PROTO_UDP: case IP_PROTO_ICMP:
udp_handler(nif,pNbuf); // FIXME: icmp_handler(nif, pNbuf);
break; break;
default: case IP_PROTO_UDP:
dbg("no protocol handler registered for protocol %d\r\n", udp_handler(nif,pNbuf);
__FUNCTION__, IP_PROTOCOL(ipframe)); break;
nbuf_free(pNbuf); default:
break; dbg("no protocol handler registered for protocol %d\r\n",
} __FUNCTION__, IP_PROTOCOL(ipframe));
return; nbuf_free(pNbuf);
break;
}
return;
} }

190
net/udp.c
View File

@@ -21,8 +21,8 @@
typedef struct typedef struct
{ {
uint16_t port; uint16_t port;
void (*handler)(NIF *, NBUF *); void (*handler)(NIF *, NBUF *);
} UDP_BOUND_PORT; } UDP_BOUND_PORT;
#define UDP_MAX_PORTS (5) /* plenty for this implementation */ #define UDP_MAX_PORTS (5) /* plenty for this implementation */
@@ -34,151 +34,151 @@ static uint16_t udp_port;
void udp_init(void) void udp_init(void)
{ {
int index; int index;
for (index = 0; index < UDP_MAX_PORTS; ++index) for (index = 0; index < UDP_MAX_PORTS; ++index)
{ {
udp_port_table[index].port = 0; udp_port_table[index].port = 0;
udp_port_table[index].handler = 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) 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 *)) void udp_bind_port(uint16_t port, void (*handler)(NIF *, NBUF *))
{ {
int index; int index;
for (index = 0; index < UDP_MAX_PORTS; ++index) for (index = 0; index < UDP_MAX_PORTS; ++index)
{ {
if (udp_port_table[index].port == 0) if (udp_port_table[index].port == 0)
{ {
udp_port_table[index].port = port; udp_port_table[index].port = port;
udp_port_table[index].handler = handler; udp_port_table[index].handler = handler;
return; return;
} }
} }
} }
void udp_free_port(uint16_t port) void udp_free_port(uint16_t port)
{ {
int index; int index;
for (index = 0; index < UDP_MAX_PORTS; ++index) for (index = 0; index < UDP_MAX_PORTS; ++index)
{ {
if (udp_port_table[index].port == port) if (udp_port_table[index].port == port)
{ {
udp_port_table[index].port = 0; udp_port_table[index].port = 0;
return; return;
} }
} }
} }
static void *udp_port_handler(uint16_t port) static void *udp_port_handler(uint16_t port)
{ {
int index; int index;
for (index = 0; index < UDP_MAX_PORTS; ++index) for (index = 0; index < UDP_MAX_PORTS; ++index)
{ {
if (udp_port_table[index].port == port) if (udp_port_table[index].port == port)
{ {
return (void *) udp_port_table[index].handler; return (void *) udp_port_table[index].handler;
} }
} }
return NULL; return NULL;
} }
uint16_t udp_obtain_free_port(void) uint16_t udp_obtain_free_port(void)
{ {
uint16_t port; uint16_t port;
port = udp_port; port = udp_port;
if (--udp_port <= 255) if (--udp_port <= 255)
udp_port = DEFAULT_UDP_PORT; udp_port = DEFAULT_UDP_PORT;
return port; return port;
} }
int udp_send(NIF *nif, uint8_t *dest, int sport, int dport, NBUF *pNbuf) int udp_send(NIF *nif, uint8_t *dest, int sport, int dport, NBUF *pNbuf)
{ {
uint8_t *myip; uint8_t *myip;
if (nif == NULL) if (nif == NULL)
{ {
dbg("%s: nif is NULL\r\n", __FUNCTION__); dbg("%s: nif is NULL\r\n", __FUNCTION__);
return 0; return 0;
} }
/* /*
* This function takes data, creates a UDP frame from it and * This function takes data, creates a UDP frame from it and
* passes it onto the IP layer * passes it onto the IP layer
*/ */
udp_frame_hdr *udpframe; 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 */ /* Set UDP source port */
udpframe->src_port = (uint16_t) sport; udpframe->src_port = (uint16_t) sport;
/* Set UDP destination port */ /* Set UDP destination port */
udpframe->dest_port = (uint16_t) dport; udpframe->dest_port = (uint16_t) dport;
/* Set length */ /* Set length */
udpframe->length = (uint16_t) (pNbuf->length + UDP_HDR_SIZE); udpframe->length = (uint16_t) (pNbuf->length + UDP_HDR_SIZE);
/* No checksum calcualation needed */ /* No checksum calcualation needed */
udpframe->chksum = (uint16_t) 0; udpframe->chksum = (uint16_t) 0;
/* Add the length of the UDP packet to the total length of the packet */ /* Add the length of the UDP packet to the total length of the packet */
pNbuf->length += 8; 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__, 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], dest[0], dest[1], dest[2], dest[3],
myip[0], myip[1], myip[2], myip[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) void udp_handler(NIF *nif, NBUF *pNbuf)
{ {
/* /*
* This function handles incoming UDP packets * This function handles incoming UDP packets
*/ */
udp_frame_hdr *udpframe; udp_frame_hdr *udpframe;
void (*handler)(NIF *, NBUF *); 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 * Adjust the length and valid data offset of the packet we are
* passing on * passing on
*/ */
pNbuf->length -= UDP_HDR_SIZE; pNbuf->length -= UDP_HDR_SIZE;
pNbuf->offset += UDP_HDR_SIZE; pNbuf->offset += UDP_HDR_SIZE;
/* /*
* Traverse the list of bound ports to see if there is a higher * Traverse the list of bound ports to see if there is a higher
* level protocol to pass the packet on to * level protocol to pass the packet on to
*/ */
if ((handler = (void(*)(NIF*, NBUF*)) udp_port_handler(UDP_DEST(udpframe))) != NULL) if ((handler = (void(*)(NIF*, NBUF*)) udp_port_handler(UDP_DEST(udpframe))) != NULL)
handler(nif, pNbuf); handler(nif, pNbuf);
else else
{ {
dbg("%s: received UDP packet for non-supported port\n", __FUNCTION__); dbg("%s: received UDP packet for non-supported port\n", __FUNCTION__);
nbuf_free(pNbuf); nbuf_free(pNbuf);
} }
return; return;
} }

File diff suppressed because it is too large Load Diff

View File

@@ -87,13 +87,15 @@ bool init_fpga(void)
volatile int32_t time, start, end; volatile int32_t time, start, end;
int i; 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) if (_FPGA_JTAG_LOADED == 1 && _FPGA_JTAG_VALID == VALID_JTAG)
{ {
xprintf("detected _FPGA_JTAG_LOADED flag. Not overwriting FPGA config.\r\n"); 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 */ /* reset the flag so that next boot will load config again from flash */
_FPGA_JTAG_LOADED = 0; _FPGA_JTAG_LOADED = 0;
_FPGA_JTAG_VALID = 0;
return true; return true;
} }