Merge from trunk

This commit is contained in:
David Gálvez
2014-07-10 11:09:09 +00:00
parent 98dacfbc69
commit 9a93782b77
54 changed files with 3647 additions and 1000 deletions

View File

@@ -1,7 +1,8 @@
#set disassemble-next-line on #set disassemble-next-line on
define tr define tr
#target remote | m68k-bdm-gdbserver pipe /dev/bdmcf3 !killall m68k-bdm-gdbserver
target remote | m68k-bdm-gdbserver pipe /dev/tblcf3 target remote | m68k-bdm-gdbserver pipe /dev/bdmcf3
#target remote | m68k-bdm-gdbserver pipe /dev/tblcf3
#target dbug /dev/ttyS0 #target dbug /dev/ttyS0
#monitor bdm-reset #monitor bdm-reset
end end

View File

@@ -0,0 +1 @@
// ADD PREDEFINED MACROS HERE!

View File

@@ -0,0 +1 @@
[General]

231
pci_BaS_gcc/BaS_gcc.files Normal file
View File

@@ -0,0 +1,231 @@
dma/dma.c
dma/MCD_dmaApi.c
dma/MCD_tasks.c
dma/MCD_tasksInit.c
exe/basflash.c
exe/basflash_start.c
firebee/bas.elf
firebee/bas.lk
firebee/bas.map
firebee/bas.s19
firebee/basflash.elf
firebee/basflash.map
firebee/basflash.s19
firebee/bashflash.lk
firebee/depend
firebee/libbas.a
firebee/ram.elf
firebee/ram.lk
firebee/ram.map
firebee/ram.s19
flash/flash.c
flash/s19reader.c
fs/cc932.c
fs/cc936.c
fs/cc949.c
fs/cc950.c
fs/ccsbcs.c
fs/ff.c
fs/unicode.c
if/driver_vec.c
include/acia.h
include/am79c874.h
include/arp.h
include/ati_ids.h
include/bas_printf.h
include/bas_string.h
include/bas_types.h
include/bas_utils.h
include/bcm5222.h
include/bootp.h
include/cache.h
include/diskio.h
include/dma.h
include/driver_mem.h
include/driver_vec.h
include/edid.h
include/ehci.h
include/eth.h
include/exceptions.h
include/fb.h
include/fec.h
include/fecbd.h
include/ff.h
include/ffconf.h
include/firebee.h
include/i2c-algo-bit.h
include/i2c.h
include/icmp.h
include/ikbd.h
include/interrupts.h
include/ip.h
include/m54455.h
include/m5484l.h
include/MCD_dma.h
include/mcd_initiators.h
include/MCD_progCheck.h
include/MCD_tasksInit.h
include/MCF5475.h
include/MCF5475_CLOCK.h
include/MCF5475_CTM.h
include/MCF5475_DMA.h
include/MCF5475_DSPI.h
include/MCF5475_EPORT.h
include/MCF5475_FBCS.h
include/MCF5475_FEC.h
include/MCF5475_GPIO.h
include/MCF5475_GPT.h
include/MCF5475_I2C.h
include/MCF5475_INTC.h
include/MCF5475_MMU.h
include/MCF5475_PAD.h
include/MCF5475_PCI.h
include/MCF5475_PCIARB.h
include/MCF5475_PSC.h
include/MCF5475_SDRAMC.h
include/MCF5475_SEC.h
include/MCF5475_SIU.h
include/MCF5475_SLT.h
include/MCF5475_SRAM.h
include/MCF5475_USB.h
include/MCF5475_XLB.h
include/mmu.h
include/mod_devicetable.h
include/nbuf.h
include/net.h
include/net_timer.h
include/nif.h
include/ohci.h
include/part.h
include/pci.h
include/pci_ids.h
include/queue.h
include/radeon_reg.h
include/radeonfb.h
include/s19reader.h
include/screen.h
include/sd_card.h
include/startcf.h
include/sysinit.h
include/tftp.h
include/udp.h
include/usb.h
include/usb_defs.h
include/user_io.h
include/util.h
include/version.h
include/videl.h
include/video.h
include/wait.h
include/x86debug.h
include/x86decode.h
include/x86emu.h
include/x86emui.h
include/x86fpu.h
include/x86fpu_regs.h
include/x86ops.h
include/x86pcibios.h
include/x86prim_asm.h
include/x86prim_ops.h
include/x86regs.h
include/xhdi_sd.h
kbd/ikbd.c
m54455/bas.elf
m54455/bas.lk
m54455/bas.map
m54455/bas.s19
m54455/basflash.elf
m54455/basflash.map
m54455/basflash.s19
m54455/bashflash.lk
m54455/depend
m54455/libbas.a
m54455/ram.elf
m54455/ram.lk
m54455/ram.map
m54455/ram.s19
m5484lite/bas.elf
m5484lite/bas.lk
m5484lite/bas.map
m5484lite/bas.s19
m5484lite/basflash.elf
m5484lite/basflash.map
m5484lite/basflash.s19
m5484lite/bashflash.lk
m5484lite/depend
m5484lite/libbas.a
m5484lite/ram.elf
m5484lite/ram.lk
m5484lite/ram.map
m5484lite/ram.s19
net/am79c874.c
net/arp.c
net/bcm5222.c
net/bootp.c
net/fec.c
net/fecbd.c
net/ip.c
net/nbuf.c
net/net_timer.c
net/nif.c
net/queue.c
net/tftp.c
net/udp.c
nutil/s19header
nutil/s19header.c
pci/ehci-hcd.c
pci/ohci-hcd.c
pci/pci.c
radeon/radeon_accel.c
radeon/radeon_base.c
radeon/radeon_cursor.c
radeon/radeon_monitor.c
spi/dspi.c
spi/mmc.c
spi/sd_card.c
sys/BaS.c
sys/cache.c
sys/driver_mem.c
sys/exceptions.S
sys/fault_vectors.c
sys/init_fpga.c
sys/interrupts.c
sys/mmu.c
sys/startcf.S
sys/sysinit.c
usb/usb.c
usb/usb_mouse.c
util/bas_printf.c
util/bas_string.c
util/printf_helper.S
util/wait.c
video/fbmem.c
video/fbmodedb.c
video/fbmon.c
video/fnt_st_8x16.c
video/offscreen.c
video/vdi_fill.c
video/videl.c
video/video.c
x86emu/x86biosemu.c
x86emu/x86debug.c
x86emu/x86decode.c
x86emu/x86fpu.c
x86emu/x86ops.c
x86emu/x86ops2.c
x86emu/x86pcibios.c
x86emu/x86prim_ops.c
x86emu/x86sys.c
xhdi/xhdi_interface.c
xhdi/xhdi_sd.c
xhdi/xhdi_vec.S
bas.lk.in
bas_firebee.bdm
bas_m5484.bdm
basflash.lk.in
check.bdm
COPYING
COPYING.LESSER
dump.bdm
mcf5474.gdb
Makefile

View File

@@ -0,0 +1,2 @@
include
/usr/m68k-elf/include

1689
pci_BaS_gcc/Doxyfile Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -15,7 +15,7 @@ ifeq (Y,$(COMPILE_ELF))
TCPREFIX=m68k-elf- TCPREFIX=m68k-elf-
EXE=elf EXE=elf
FORMAT=elf32-m68k FORMAT=elf32-m68k
else else
TCPREFIX=m68k-atari-mint- TCPREFIX=m68k-atari-mint-
EXE=s19 EXE=s19
FORMAT=srec FORMAT=srec
@@ -32,20 +32,21 @@ NATIVECC=gcc
INCLUDE=-Iinclude INCLUDE=-Iinclude
CFLAGS=-mcpu=5474 \ CFLAGS=-mcpu=5474 \
-Wall \ -Wall \
-Os \ -g3 \
-fomit-frame-pointer \ -fomit-frame-pointer \
-ffreestanding \ -ffreestanding \
-fleading-underscore \ -fleading-underscore \
-Wa,--register-prefix-optional -Wa,--register-prefix-optional
CFLAGS_OPTIMIZED = -mcpu=5474 \ CFLAGS_OPTIMIZED = -mcpu=5474 \
-Wall \ -Wall \
-g3 \
-O2 \ -O2 \
-fomit-frame-pointer \ -fomit-frame-pointer \
-ffreestanding \ -ffreestanding \
-fleading-underscore \ -fleading-underscore \
-Wa,--register-prefix-optional -Wa,--register-prefix-optional
TRGTDIRS= ./firebee ./m5484lite TRGTDIRS= ./firebee ./m5484lite ./m54455
OBJDIRS=$(patsubst %, %/objs,$(TRGTDIRS)) OBJDIRS=$(patsubst %, %/objs,$(TRGTDIRS))
TOOLDIR=util TOOLDIR=util
@@ -123,6 +124,7 @@ CSRCS= \
radeon_accel.c \ radeon_accel.c \
radeon_cursor.c \ radeon_cursor.c \
radeon_monitor.c \ radeon_monitor.c \
fnt_st_8x16.c \
\ \
x86decode.c \ x86decode.c \
x86sys.c \ x86sys.c \
@@ -135,7 +137,7 @@ CSRCS= \
x86pcibios.c \ x86pcibios.c \
\ \
basflash.c \ basflash.c \
basflash_start.c basflash_start.c
ASRCS= \ ASRCS= \
@@ -171,32 +173,35 @@ clean:
# flags for targets # flags for targets
m5484lite/bas.$(EXE): MACHINE=MACHINE_M5484LITE m5484lite/bas.$(EXE): MACHINE=MACHINE_M5484LITE
m54455/bas.$(EXE): MACHINE=MACHINE_M54455
firebee/bas.$(EXE): MACHINE=MACHINE_FIREBEE firebee/bas.$(EXE): MACHINE=MACHINE_FIREBEE
m5484lite/ram.$(EXE): MACHINE=MACHINE_M5484LITE m5484lite/ram.$(EXE): MACHINE=MACHINE_M5484LITE
m54455/ram.$(EXE): MACHINE=MACHINE_M54455
firebee/ram.$(EXE): MACHINE=MACHINE_FIREBEE firebee/ram.$(EXE): MACHINE=MACHINE_FIREBEE
m5484lite/basflash.$(EXE): MACHINE=MACHINE_M5484LITE m5484lite/basflash.$(EXE): MACHINE=MACHINE_M5484LITE
m54455/basflash.$(EXE): MACHINE=MACHINE_M54455
firebee/basflash.$(EXE): MACHINE=MACHINE_FIREBEE firebee/basflash.$(EXE): MACHINE=MACHINE_FIREBEE
# #
# generate pattern rules for different object files # generate pattern rules for different object files
# #
define CC_TEMPLATE define CC_TEMPLATE
ifeq (firebee,$(1)) #ifeq (firebee,$(1))
MACHINE=MACHINE_FIREBEE #MACHINE=MACHINE_FIREBEE
else #else
MACHINE=MACHINE_M5484LITE #MACHINE=MACHINE_M5484LITE
endif #endif
# always optimize x86 emulator objects # always optimize x86 emulator objects
$(1)/objs/x86decode.o: CFLAGS=$(CFLAGS_OPTIMIZED) #$(1)/objs/x86decode.o: CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/x86sys.o: CFLAGS=$(CFLAGS_OPTIMIZED) #$(1)/objs/x86sys.o: CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/x86debug.o: CFLAGS=$(CFLAGS_OPTIMIZED) #$(1)/objs/x86debug.o: CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/x86prim_ops.o:CFLAGS=$(CFLAGS_OPTIMIZED) #$(1)/objs/x86prim_ops.o:CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/x86ops.o: CFLAGS=$(CFLAGS_OPTIMIZED) #$(1)/objs/x86ops.o: CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/x86ops2.o: CFLAGS=$(CFLAGS_OPTIMIZED) #$(1)/objs/x86ops2.o: CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/x86fpu.o: CFLAGS=$(CFLAGS_OPTIMIZED) #$(1)/objs/x86fpu.o: CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/x86biosemu.o: CFLAGS=$(CFLAGS_OPTIMIZED) #$(1)/objs/x86biosemu.o: CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/x86pcibios.o: CFLAGS=$(CFLAGS_OPTIMIZED) #$(1)/objs/x86pcibios.o: CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/%.o:%.c $(1)/objs/%.o:%.c
$(CC) $$(CFLAGS) -D$$(MACHINE) $(INCLUDE) -c $$< -o $$@ $(CC) $$(CFLAGS) -D$$(MACHINE) $(INCLUDE) -c $$< -o $$@
@@ -258,7 +263,7 @@ endif
$(1)_MAPFILE_RAM=$(1)/$$(basename $$(RAM_EXEC)).map $(1)_MAPFILE_RAM=$(1)/$$(basename $$(RAM_EXEC)).map
$(1)/$$(RAM_EXEC): $(1)/$(LIBBAS) $(LDCSRC) $(1)/$$(RAM_EXEC): $(1)/$(LIBBAS) $(LDCSRC)
$(CPP) $(INCLUDE) -DCOMPILE_RAM -DOBJDIR=$(1)/objs -P -DFORMAT_ELF=$(FORMAT_ELF) -D$$(MACHINE) $(LDCSRC) -o $(1)/$$(LDRFILE) $(CPP) $(INCLUDE) -DCOMPILE_RAM -DOBJDIR=$(1)/objs -P -DFORMAT_ELF=$(FORMAT_ELF) -D$$(MACHINE) $(LDCSRC) -o $(1)/$$(LDRFILE)
$(LD) --oformat $$(FORMAT) -Map $$($(1)_MAPFILE_RAM) --cref -T $(1)/$$(LDRFILE) -o $$@ $(LD) -g --oformat $$(FORMAT) -Map $$($(1)_MAPFILE_RAM) --cref -T $(1)/$$(LDRFILE) -o $$@
ifeq ($(COMPILE_ELF),Y) ifeq ($(COMPILE_ELF),Y)
$(OBJCOPY) -O srec $$@ $$(basename $$@).s19 $(OBJCOPY) -O srec $$@ $$(basename $$@).s19
else else
@@ -281,21 +286,21 @@ $(foreach DIR,$(TRGTDIRS),$(eval $(call EX_TEMPLATE,$(DIR))))
indent: $(CSRCS) indent: $(CSRCS)
indent $< indent $<
.PHONY: tags .PHONY: tags
tags: tags:
ctags $(patsubst %,%/*,$(VPATH)) ctags $(patsubst %,%/*,$(VPATH))
.PHONY: printvars .PHONY: printvars
printvars: printvars:
@$(foreach V,$(.VARIABLES), $(if $(filter-out environment% default automatic, $(origin $V)),$(warning $V=$($V)))) @$(foreach V,$(.VARIABLES), $(if $(filter-out environment% default automatic, $(origin $V)),$(warning $V=$($V))))
ifeq (MACHINE_M5484LITE,$$(MACHINE)) ifeq (MACHINE_M5484LITE,$$(MACHINE))
MNAME=m5484lite MNAME=m5484lite
else ifeq (MACHINE_FIREBEE,$(MACHINE)) else ifeq (MACHINE_FIREBEE,$(MACHINE))
MNAME=firebee MNAME=firebee
endif endif
tools: tools:
$(NATIVECC) $(INCLUDE) -c $(TOOLDIR)/s19header.c -o $(TOOLDIR)/s19header.o $(NATIVECC) $(INCLUDE) -c $(TOOLDIR)/s19header.c -o $(TOOLDIR)/s19header.o
$(NATIVECC) -o $(TOOLDIR)/s19header $(TOOLDIR)/s19header.o $(NATIVECC) -o $(TOOLDIR)/s19header $(TOOLDIR)/s19header.o

View File

@@ -1,9 +1,11 @@
#ifdef MACHINE_FIREBEE #if defined(MACHINE_FIREBEE)
#include "firebee.h" #include "firebee.h"
#endif /* MACHINE_FIREBEE */ #elif defined(MACHINE_M5484LITE)
#ifdef MACHINE_M5484LITE
#include "m5484l.h" #include "m5484l.h"
#elif defined(MACHINE_M54455)
#include "m54455.h"
#else
#error "unknown machine!"
#endif /* MACHINE_M5484LITE */ #endif /* MACHINE_M5484LITE */
/* make bas_rom access flags rx if compiling to RAM */ /* make bas_rom access flags rx if compiling to RAM */
@@ -21,7 +23,7 @@ MEMORY
*/ */
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
} }
@@ -42,8 +44,8 @@ SECTIONS
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)
@@ -107,7 +109,7 @@ SECTIONS
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
@@ -117,7 +119,7 @@ SECTIONS
*(.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 */
@@ -139,7 +141,7 @@ SECTIONS
*(.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);
@@ -152,16 +154,16 @@ SECTIONS
_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;
@@ -172,16 +174,17 @@ SECTIONS
/* 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;
/* 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 */
@@ -201,35 +204,40 @@ SECTIONS
__EMUTOS_SIZE = 0x00100000; __EMUTOS_SIZE = 0x00100000;
/* where FPGA data lives in flash */ /* where FPGA data lives in flash */
__FPGA_FLASH_DATA = 0xe0700000; __FPGA_CONFIG = 0xe0700000;
__FPGA_FLASH_DATA_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 = __RAMBAR0 + __RAMBAR0_SIZE - 4; __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;
/* 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;

View File

@@ -29,13 +29,17 @@
#include "cache.h" #include "cache.h"
#include "exceptions.h" #include "exceptions.h"
#if MACHINE_FIREBEE #if defined(MACHINE_FIREBEE)
#include "firebee.h" #include "firebee.h"
#elif MACHINE_M5484LITE #elif defined(MACHINE_M5484LITE)
#include "m5484l.h" #include "m5484l.h"
#elif defined(MACHINE_M54455)
#include "m54455.h"
#else
#error "unknown machine!"
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
//#define DBG_DMA // #define DBG_DMA
#ifdef DBG_DMA #ifdef DBG_DMA
#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0) #define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0)
#else #else
@@ -54,13 +58,13 @@ struct dma_channel
static char used_reqs[32] = static char used_reqs[32] =
{ {
DMA_ALWAYS, DMA_DSPI_RXFIFO, DMA_DSPI_TXFIFO, DMA_DREQ0, DMA_ALWAYS, DMA_DSPI_RXFIFO, DMA_DSPI_TXFIFO, DMA_DREQ0,
DMA_PSC0_RX, DMA_PSC0_TX, DMA_USB_EP0, DMA_USB_EP1, DMA_PSC0_RX, DMA_PSC0_TX, DMA_USB_EP0, DMA_USB_EP1,
DMA_USB_EP2, DMA_USB_EP3, DMA_PCI_TX, DMA_PCI_RX, DMA_USB_EP2, DMA_USB_EP3, DMA_PCI_TX, DMA_PCI_RX,
DMA_PSC1_RX, DMA_PSC1_TX, DMA_I2C_RX, DMA_I2C_TX, DMA_PSC1_RX, DMA_PSC1_TX, DMA_I2C_RX, DMA_I2C_TX,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0 0, 0, 0, 0
}; };
static struct dma_channel dma_channel[NCHANNELS] = static struct dma_channel dma_channel[NCHANNELS] =
@@ -221,7 +225,7 @@ int dma_set_initiator(int initiator)
else /* No empty slots */ else /* No empty slots */
{ {
dbg("%s: no free slot\r\n", __FUNCTION__); dbg("%s: no free slot\r\n", __FUNCTION__);
return 1; return 1;
} }
break; break;
@@ -526,7 +530,7 @@ int dma_get_channel(int requestor)
} }
/* /*
* Remove the channel being initiated by the given requestor from * Remove the channel being initiated by the given requestor from
* the active list * the active list
* *
* Parameters: * Parameters:
@@ -547,8 +551,8 @@ void dma_free_channel(int requestor)
} }
} }
/* /*
* This is the catch-all interrupt handler for the mult-channel DMA * This is the catch-all interrupt handler for the mult-channel DMA
*/ */
int dma_interrupt_handler(void *arg1, void *arg2) int dma_interrupt_handler(void *arg1, void *arg2)
{ {
@@ -556,8 +560,8 @@ int dma_interrupt_handler(void *arg1, void *arg2)
(void) set_ipl(7); (void) set_ipl(7);
/* /*
* Determine which interrupt(s) triggered by AND'ing the * Determine which interrupt(s) triggered by AND'ing the
* pending interrupts with those that aren't masked. * pending interrupts with those that aren't masked.
*/ */
interrupts = MCF_DMA_DIPR & ~MCF_DMA_DIMR; interrupts = MCF_DMA_DIPR & ~MCF_DMA_DIMR;
@@ -592,11 +596,15 @@ int dma_interrupt_handler(void *arg1, void *arg2)
void *dma_memcpy(void *dst, void *src, size_t n) void *dma_memcpy(void *dst, void *src, size_t n)
{ {
int ret; int ret;
volatile int32_t time;
volatile int32_t start; #ifdef DBG_DMA
volatile int32_t end; int32_t time;
int32_t start;
int32_t end;
start = MCF_SLT0_SCNT; start = MCF_SLT0_SCNT;
#endif /* DBG_DMA */
ret = MCD_startDma(1, src, 4, dst, 4, n, 4, DMA_ALWAYS, 0, MCD_SINGLE_DMA, 0); ret = MCD_startDma(1, src, 4, dst, 4, n, 4, DMA_ALWAYS, 0, MCD_SINGLE_DMA, 0);
if (ret == MCD_OK) if (ret == MCD_OK)
{ {
@@ -640,8 +648,10 @@ void *dma_memcpy(void *dst, void *src, size_t n)
#endif #endif
} while (ret != MCD_DONE); } while (ret != MCD_DONE);
#ifdef DBG_DMA
end = MCF_SLT0_SCNT; end = MCF_SLT0_SCNT;
time = (start - end) / (SYSCLK / 1000) / 1000; time = (start - end) / (SYSCLK / 1000) / 1000;
#endif /* DBG_DMA */
dbg("%s: took %d ms (%f Mbytes/second)\r\n", __FUNCTION__, time, n / (float) time / 1000.0); dbg("%s: took %d ms (%f Mbytes/second)\r\n", __FUNCTION__, time, n / (float) time / 1000.0);
return dst; return dst;

View File

@@ -340,6 +340,17 @@ static err_t verify(uint8_t *dst, uint8_t *src, uint32_t length)
return OK; return OK;
} }
/*
* needed to avoid missing type cast warning below
*/
static inline err_t srec_memcpy(uint8_t *dst, uint8_t *src, size_t n)
{
err_t e = OK;
memcpy((void *) dst, (void *) src, n);
return e;
}
void srec_execute(char *flasher_filename) void srec_execute(char *flasher_filename)
{ {
DRESULT res; DRESULT res;
@@ -372,7 +383,7 @@ void srec_execute(char *flasher_filename)
{ {
/* next pass: copy data to destination */ /* next pass: copy data to destination */
xprintf("OK.\r\ncopy/flash data: "); xprintf("OK.\r\ncopy/flash data: ");
err = read_srecords(flasher_filename, &start_address, &length, memcpy); err = read_srecords(flasher_filename, &start_address, &length, srec_memcpy);
if (err == OK) if (err == OK)
{ {
/* next pass: verify data */ /* next pass: verify data */

View File

@@ -1,4 +1,4 @@
#!/usr/local/bin/bdmctrl #!/usr/local/bin/bdmctrl -D2
# #
# firebee board initialization for bdmctrl # firebee board initialization for bdmctrl
# #
@@ -21,32 +21,32 @@ write 0xFF000508 0x00001180 4
write 0xFF000504 0x007F0001 4 write 0xFF000504 0x007F0001 4
# SDRAM Initialization @ 0000_0000 - 1FFF_FFFF 512Mbytes # SDRAM Initialization @ 0000_0000 - 1FFF_FFFF 512Mbytes
write 0xFF000004 0x000002AA 4 # SDRAMDS configuration #write 0xFF000004 0x000002AA 4 # SDRAMDS configuration
write 0xFF000020 0x0000001A 4 # SDRAM CS0 configuration (128Mbytes 0000_0000 - 07FF_FFFF) #write 0xFF000020 0x0000001A 4 # SDRAM CS0 configuration (128Mbytes 0000_0000 - 07FF_FFFF)
write 0xFF000024 0x0800001A 4 # SDRAM CS1 configuration (128Mbytes 0800_0000 - 0FFF_FFFF) #write 0xFF000024 0x0800001A 4 # SDRAM CS1 configuration (128Mbytes 0800_0000 - 0FFF_FFFF)
write 0xFF000028 0x1000001A 4 # SDRAM CS2 configuration (128Mbytes 1000_0000 - 17FF_FFFF) #write 0xFF000028 0x1000001A 4 # SDRAM CS2 configuration (128Mbytes 1000_0000 - 17FF_FFFF)
write 0xFF00002C 0x1800001A 4 # SDRAM CS3 configuration (128Mbytes 1800_0000 - 1FFF_FFFF) #write 0xFF00002C 0x1800001A 4 # SDRAM CS3 configuration (128Mbytes 1800_0000 - 1FFF_FFFF)
write 0xFF000108 0x73622830 4 # SDCFG1 #write 0xFF000108 0x73622830 4 # SDCFG1
write 0xFF00010C 0x46770000 4 # SDCFG2 #write 0xFF00010C 0x46770000 4 # SDCFG2
write 0xFF000104 0xE10D0002 4 # SDCR + IPALL #write 0xFF000104 0xE10D0002 4 # SDCR + IPALL
write 0xFF000100 0x40010000 4 # SDMR (write to LEMR) #write 0xFF000100 0x40010000 4 # SDMR (write to LEMR)
write 0xFF000100 0x048D0000 4 # SDMR (write to LMR) #write 0xFF000100 0x048D0000 4 # SDMR (write to LMR)
sleep 100 #sleep 100
write 0xFF000104 0xE10D0002 4 # SDCR + IPALL #write 0xFF000104 0xE10D0002 4 # SDCR + IPALL
write 0xFF000104 0xE10D0004 4 # SDCR + IREF (first refresh) #write 0xFF000104 0xE10D0004 4 # SDCR + IREF (first refresh)
write 0xFF000104 0xE10D0004 4 # SDCR + IREF (first refresh) #write 0xFF000104 0xE10D0004 4 # SDCR + IREF (first refresh)
write 0xFF000100 0x008D0000 4 # SDMR (write to LMR) #write 0xFF000100 0x008D0000 4 # SDMR (write to LMR)
write 0xFF000104 0x710D0F00 4 # SDCR (lock SDMR and enable refresh) #write 0xFF000104 0x710D0F00 4 # SDCR (lock SDMR and enable refresh)
sleep 10 #sleep 10
# use system sdram as flashlib scratch area. # use system sdram as flashlib scratch area.
# TODO: plugin flashing seems to work o.k. now for smaller binaries, while it doesn't for larger ones (EmuTOS) yet. # TODO: plugin flashing seems to work o.k. now for smaller binaries, while it doesn't for larger ones (EmuTOS) yet.
# This seems to be related to large flash buffers and PC-relative adressing of the plugin # This seems to be related to large flash buffers and PC-relative adressing of the plugin
flash-plugin 0x1000 0xf000 flash29.plugin #flash-plugin 0x1000 0xf000 flash29-5475.plugin
# notify flashlib that we have flash at address 0xE0000000, length 0x7FFFFF, plugin is flash29 # notify flashlib that we have flash at address 0xE0000000, length 0x7FFFFF, plugin is flash29
flash 0xE0000000 flash 0xe0000000
# Erase flash from 0xE0000000 to 0xE00FFFFF (reserved space for BaS) # Erase flash from 0xE0000000 to 0xE00FFFFF (reserved space for BaS)
# #
@@ -55,17 +55,44 @@ flash 0xE0000000
# #
# contrary to documentation, it seems we need to erase-wait after each sector # contrary to documentation, it seems we need to erase-wait after each sector
erase 0xE0000000 0 erase 0xe0000000 0
erase 0xE0000000 1 erase-wait 0xe0000000
erase 0xE0000000 2 erase 0xe0000000 0x1000
erase 0xE0000000 3 erase-wait 0xe0000000
erase 0xE0000000 4 erase 0xe0000000 0x2000
erase 0xE0000000 5 erase-wait 0xe0000000
erase 0xE0000000 7 erase 0xe0000000 0x3000
erase 0xE0000000 8 erase-wait 0xe0000000
erase 0xE0000000 9 erase 0xe0000000 0x4000
erase 0xE0000000 10 erase-wait 0xe0000000
erase-wait 0xE0000000 erase 0xe0000000 0x5000
erase-wait 0xe0000000
erase 0xe0000000 0x6000
erase-wait 0xe0000000
erase 0xe0000000 0x7000
erase-wait 0xe0000000
erase 0xe0000000 0x8000
erase-wait 0xe0000000
erase 0xe0000000 0x10000
erase-wait 0xe0000000
erase 0xe0000000 0x18000
erase-wait 0xe0000000
erase 0xe0000000 0x20000
erase-wait 0xe0000000
erase 0xe0000000 0x28000
erase-wait 0xe0000000
erase 0xe0000000 0x30000
erase-wait 0xe0000000
erase 0xe0000000 0x38000
erase-wait 0xe0000000
erase 0xe0000000 0x40000
erase-wait 0xe0000000
erase 0xe0000000 0x48000
erase-wait 0xe0000000
erase 0xe0000000 0x50000
erase-wait 0xe0000000
erase 0xe0000000 0x58000
erase-wait 0xe0000000
load -v ../firebee/bas.elf load -v ../firebee/bas.elf
wait wait

View File

@@ -48,8 +48,8 @@ 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 = '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,

View File

@@ -35,6 +35,7 @@ extern char *strncat(char *dst, const char *src, size_t max);
extern int atoi(const char *c); extern int atoi(const char *c);
extern void *memcpy(void *dst, const void *src, size_t n); extern void *memcpy(void *dst, const void *src, size_t n);
extern void *memset(void *s, int c, size_t n); extern void *memset(void *s, int c, size_t n);
extern int memcmp(const void *s1, const void *s2, size_t max);
extern void bzero(void *s, size_t n); extern void bzero(void *s, size_t n);
#define isdigit(c) (((c) >= '0') && ((c) <= '9')) #define isdigit(c) (((c) >= '0') && ((c) <= '9'))

View File

@@ -52,17 +52,17 @@ struct dma_driver_interface
{ {
int32_t version; int32_t version;
int32_t magic; int32_t magic;
int32_t (*dma_set_initiator)(int32_t initiator); int (*dma_set_initiator)(int initiator);
uint32_t (*dma_get_initiator)(int32_t requestor); uint32_t (*dma_get_initiator)(int requestor);
void (*dma_free_initiator)(int32_t requestor); void (*dma_free_initiator)(int requestor);
int32_t (*dma_set_channel)(int32_t requestor, void (*handler)(void)); int (*dma_set_channel)(int requestor, void (*handler)(void));
int32_t (*dma_get_channel)(int32_t requestor); int (*dma_get_channel)(int requestor);
void (*dma_free_channel)(int32_t requestor); void (*dma_free_channel)(int requestor);
void (*dma_clear_channel)(int32_t channel); void (*dma_clear_channel)(int channel);
int32_t (*MCD_startDma)(long channel, int (*MCD_startDma)(long channel,
int8_t *srcAddr, uint32_t srcIncr, int8_t *destAddr, uint32_t destIncr, int8_t *srcAddr, unsigned int srcIncr, int8_t *destAddr, unsigned int destIncr,
uint32_t dmaSize, uint32_t xferSize, uint32_t initiator, int32_t priority, unsigned int dmaSize, unsigned int xferSize, unsigned int initiator, int priority,
uint32_t flags, uint32_t 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);

View File

@@ -27,7 +27,7 @@
* Author: Markus Fröschle * Author: Markus Fröschle
*/ */
#define SYSCLK 132000 #define SYSCLK 132000 /* NOTE: 132 _is_ correct. 133 _is_ wrong. Do not change! */
#define BOOTFLASH_BASE_ADDRESS 0xE0000000 #define BOOTFLASH_BASE_ADDRESS 0xE0000000
#define BOOTFLASH_SIZE 0x800000 /* FireBee has 8 MByte Flash */ #define BOOTFLASH_SIZE 0x800000 /* FireBee has 8 MByte Flash */

View File

@@ -0,0 +1,98 @@
/*
* font.h - font specific definitions
*
* Copyright (c) 2001 Lineo, Inc.
* Copyright (c) 2004 by Authors:
*
* Authors:
* MAD Martin Doering
*
* This file is distributed under the GPL, version 2 or at your
* option any later version. See doc/license.txt for details.
*/
#ifndef FONT_H
#define FONT_H
#include <stdint.h>
/* font header flags */
#define F_DEFAULT 1 /* this is the default font (face and size) */
#define F_HORZ_OFF 2 /* there are left and right offset tables */
#define F_STDFORM 4 /* is the font in standard format */
#define F_MONOSPACE 8 /* is the font monospaced */
/* font style bits */
#define F_THICKEN 1
#define F_LIGHT 2
#define F_SKEW 4
#define F_UNDER 8
#define F_OUTLINE 16
#define F_SHADOW 32
/* font specific linea variables */
extern const uint16_t *v_fnt_ad; /* address of current monospace font */
extern const uint16_t *v_off_ad; /* address of font offset table */
extern uint16_t v_fnt_nd; /* ascii code of last cell in font */
extern uint16_t v_fnt_st; /* ascii code of first cell in font */
extern uint16_t v_fnt_wr; /* font cell wrap */
/* character cell specific linea variables */
extern uint16_t v_cel_ht; /* cell height (width is 8) */
extern uint16_t v_cel_mx; /* needed by MiNT: columns on the screen minus 1 */
extern uint16_t v_cel_my; /* needed by MiNT: rows on the screen minus 1 */
extern uint16_t v_cel_wr; /* needed by MiNT: length (in int8_ts) of a line of characters */
/*
* font_ring is a struct of four pointers, each of which points to
* a list of font headers linked together to form a string.
*/
extern struct font_head *font_ring[4]; /* Ring of available fonts */
extern int16_t font_count; /* all three fonts and NULL */
/* the font header descibes a font */
struct font_head {
int16_t font_id;
int16_t point;
int8_t name[32];
uint16_t first_ade;
uint16_t last_ade;
uint16_t top;
uint16_t ascent;
uint16_t half;
uint16_t descent;
uint16_t bottom;
uint16_t max_char_width;
uint16_t max_cell_width;
uint16_t left_offset; /* amount character slants left when skewed */
uint16_t right_offset; /* amount character slants right */
uint16_t thicken; /* number of pixels to smear */
uint16_t ul_size; /* size of the underline */
uint16_t lighten; /* mask to and with to lighten */
uint16_t skew; /* mask for skewing */
uint16_t flags;
const uint8_t *hor_table; /* horizontal offsets */
const uint16_t *off_table; /* character offsets */
const uint16_t *dat_table; /* character definitions */
uint16_t form_width;
uint16_t form_height;
struct font_head *next_font;/* pointer to next font */
uint16_t font_seg;
};
/* prototypes */
void font_init(void); /* initialize BIOS font ring */
void font_set_default(void); /* choose the default font */
#endif /* FONT_H */

View File

@@ -79,11 +79,11 @@
#define INT_SOURCE_GPT0 62 // GPT0 timer interrupt #define INT_SOURCE_GPT0 62 // GPT0 timer interrupt
#define FEC0_INTC_LVL 5 /* interrupt level for FEC0 */ #define FEC0_INTC_LVL 1 /* interrupt level for FEC0 */
#define FEC0_INTC_PRI 7 /* interrupt priority for FEC0 */ #define FEC0_INTC_PRI 2 /* interrupt priority for FEC0 */
#define FEC1_INTC_LVL 5 /* interrupt level for FEC1 */ #define FEC1_INTC_LVL 1 /* interrupt level for FEC1 */
#define FEC1_INTC_PRI 7 /* interrupt priority for FEC1 */ #define FEC1_INTC_PRI 2 /* interrupt priority for FEC1 */
#define FEC_INTC_LVL(x) ((x == 0) ? FEC0_INTC_LVL : FEC1_INTC_LVL) #define FEC_INTC_LVL(x) ((x == 0) ? FEC0_INTC_LVL : FEC1_INTC_LVL)
#define FEC_INTC_PRI(x) ((x == 0) ? FEC0_INTC_PRI : FEC1_INTC_PRI) #define FEC_INTC_PRI(x) ((x == 0) ? FEC0_INTC_PRI : FEC1_INTC_PRI)
@@ -101,7 +101,7 @@ extern int register_interrupt_handler(uint8_t source, uint8_t level, uint8_t pri
#define ISR_USER_ISR 0x02 #define ISR_USER_ISR 0x02
extern void isr_init(void); extern void isr_init(void);
extern int isr_register_handler(int type, int vector, int (*handler)(void *, void *), void *hdev, void *harg); extern int isr_register_handler(int vector, int (*handler)(void *, void *), void *hdev, void *harg);
extern void isr_remove_handler(int type ,int (*handler)(void *, void *)); extern void isr_remove_handler(int (*handler)(void *, void *));
extern bool isr_execute_handler(int vector); extern bool isr_execute_handler(int vector);
#endif /* _INTERRUPTS_H_ */ #endif /* _INTERRUPTS_H_ */

View File

@@ -9,7 +9,6 @@
#ifndef _IP_H #ifndef _IP_H
#define _IP_H #define _IP_H
/********************************************************************/
/* 32-bit IP Addresses */ /* 32-bit IP Addresses */
typedef uint8_t IP_ADDR[4]; typedef uint8_t IP_ADDR[4];
@@ -57,7 +56,6 @@ typedef struct
#define IP_HDR_OFFSET ETH_HDR_LEN #define IP_HDR_OFFSET ETH_HDR_LEN
#define IP_HDR_SIZE 20 /* no options */ #define IP_HDR_SIZE 20 /* no options */
/********************************************************************/
typedef struct typedef struct
{ {
@@ -71,7 +69,6 @@ typedef struct
unsigned int err; unsigned int err;
} IP_INFO; } IP_INFO;
/********************************************************************/
extern void ip_handler(NIF *nif, NBUF *nbf); extern void ip_handler(NIF *nif, NBUF *nbf);
uint16_t ip_chksum(uint16_t *data, int num); uint16_t ip_chksum(uint16_t *data, int num);

View File

@@ -0,0 +1,49 @@
#ifndef _M54455_H_
#define _M54455_H_
/*
* m54455.h
*
* preprocessor definitions for the M54455 Freescale machine. This file should contain nothing but preprocessor
* definition that evaluate to numbers. It is intended for use in C sources as well as in linker control
* files, so care must be taken to not break the syntax of either one.
*
* This file is part of BaS_gcc.
*
* BaS_gcc is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* BaS_gcc is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with BaS_gcc. If not, see <http://www.gnu.org/licenses/>.
*
* Created on: 26.02.2013
* Author: Markus Fröschle
*/
#define SYSCLK 133000
#define BOOTFLASH_BASE_ADDRESS 0xe0000000
#define BOOTFLASH_SIZE 0x800000
#define BOOTFLASH_BAM (BOOTFLASH_SIZE - 1)
#define SDRAM_START 0x00000000 /* start at address 0 */
#define SDRAM_SIZE 0x8000000
#ifdef COMPILE_RAM
#define TARGET_ADDRESS (SDRAM_START + SDRAM_SIZE - 0x200000)
#else
#define TARGET_ADDRESS BOOTFLASH_BASE_ADDRESS
#endif /* COMPILE_RAM */
#define DRIVER_MEM_BUFFER_SIZE 0x100000
#define EMUTOS_BASE_ADDRESS 0xe0100000
#endif /* _M54455_H_ */

View File

@@ -26,8 +26,67 @@
#include "bas_types.h" #include "bas_types.h"
/*
* ACR register handling macros
*/
#define ACR_BA(x) ((x) & 0xffff0000)
#define ACR_ADMSK(x) (((x) & 0xffff) << 16)
#define ACR_E(x) (((x) & 1) << 15)
#define ACR_S(x) (((x) & 3) << 13)
#define ACR_S_USERMODE 0
#define ACR_S_SUPERVISOR_MODE 1
#define ACR_S_ALL 2
#define ACR_ADDRESS_MASK_MODE(x) (((x) & 1) << 10)
#define ACR_CACHE_MODE(x) (((x) & 3) << 5)
#define ACR_SUPERVISOR_PROTECT(x) (((x) & 1) << 3)
#define ACR_WRITE_PROTECT(x) (((x) & 1) << 2)
/*
* MMU register handling macros
*/
#define SCA_PAGE_ID 6 /* indicates video memory page */ #define SCA_PAGE_ID 6 /* indicates video memory page */
/*
* MMU page sizes
*/
#define MMU_PAGE_SIZE_1M 0
#define MMU_PAGE_SIZE_4K 1
#define MMU_PAGE_SIZE_8K 2
#define MMU_PAGE_SIZE_1K 3
/*
* cache modes
*/
#define CACHE_WRITETHROUGH 0
#define CACHE_COPYBACK 1
#define CACHE_NOCACHE_PRECISE 2
#define CACHE_NOCACHE_IMPRECISE 3
/*
* page flags
*/
#define SV_PROTECT 1
#define SV_USER 0
#define ACCESS_READ (1 << 0)
#define ACCESS_WRITE (1 << 1)
#define ACCESS_EXECUTE (1 << 2)
struct map_flags
{
unsigned cache_mode:2;
unsigned protection:1;
unsigned page_id:8;
unsigned access:3;
unsigned unused:18;
};
/* /*
* global variables from linker script * global variables from linker script
*/ */
@@ -35,6 +94,6 @@ extern long video_tlb;
extern long video_sbt; extern long video_sbt;
extern void mmu_init(void); extern void mmu_init(void);
extern void mmutr_miss(uint32_t addresss); extern void mmu_map_page(uint32_t virt, uint32_t phys, uint32_t map_size, struct map_flags flags);
#endif /* _MMU_H_ */ #endif /* _MMU_H_ */

View File

@@ -28,13 +28,17 @@
#ifndef __SYSINIT_H__ #ifndef __SYSINIT_H__
#define __SYSINIT_H__ #define __SYSINIT_H__
#include <stdbool.h>
/* function(s) from init_fpga.c */ /* function(s) from init_fpga.c */
extern void init_fpga(void); extern bool init_fpga(void);
extern void init_usb(void); extern void init_usb(void);
/* fault_vectors */ /* fault_vectors */
extern void setup_vectors(void); extern void setup_vectors(void);
extern bool fpga_configured;
#endif /* __SYSINIT_H__ */ #endif /* __SYSINIT_H__ */

View File

@@ -145,7 +145,7 @@ __extension__ \
__extension__ \ __extension__ \
({__asm__ volatile ("lea -60(sp),sp\n\t" \ ({__asm__ volatile ("lea -60(sp),sp\n\t" \
"movem.l d0-d7/a0-a6,(sp)"); \ "movem.l d0-d7/a0-a6,(sp)"); \
((void (*)(void))addr)(); \ ((void (*) (void)) addr)(); \
__asm__ volatile ("movem.l (sp),d0-d7/a0-a6\n\t" \ __asm__ volatile ("movem.l (sp),d0-d7/a0-a6\n\t" \
"lea 60(sp),sp"); \ "lea 60(sp),sp"); \
}) })

View File

@@ -29,7 +29,7 @@
*/ */
#define MAJOR_VERSION 0 #define MAJOR_VERSION 0
#define MINOR_VERSION 83 #define MINOR_VERSION 85
#endif /* VERSION_H_ */ #endif /* VERSION_H_ */

View File

@@ -29,55 +29,23 @@
#include <bas_types.h> #include <bas_types.h>
#if MACHINE_FIREBEE #if defined(MACHINE_FIREBEE)
#include "firebee.h" #include "firebee.h"
#elif MACHINE_M5484LITE #elif defined(MACHINE_M5484LITE)
#include "m5484l.h" #include "m5484l.h"
#elif defined(MACHINE_M54455)
#include "m54455.h"
#else
#error "unknown machine"
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
#include "MCF5475.h" #include "MCF5475.h"
typedef bool (*checker_func)(void); typedef bool (*checker_func)(void);
extern __inline__ void wait(uint32_t) __attribute__((always_inline)); extern void wait(uint32_t);
extern __inline__ bool waitfor(uint32_t us, checker_func condition) __attribute__((always_inline)); extern bool waitfor(uint32_t us, checker_func condition);
extern uint32_t get_timer(void);
extern void wait_ms(uint32_t ms);
extern __inline__ uint32_t get_timer(void)
{
return MCF_SLT_SCNT(0);
}
/*
* wait for the specified number of us on slice timer 0. Replaces the original routines that had
* the number of useconds to wait for hardcoded in their name.
*/
extern __inline__ void wait(uint32_t us)
{
int32_t target = MCF_SLT_SCNT(0) - (us * (SYSCLK / 1000));
while (MCF_SLT_SCNT(0) - target > 0);
}
/*
* same as above, but with milliseconds wait time
*/
extern __inline__ void wait_ms(uint32_t ms)
{
wait(ms * 1000);
}
/*
* the same as above, with a checker function which gets called while
* busy waiting and allows for an early return if it returns true
*/
extern __inline__ bool waitfor(uint32_t us, checker_func condition)
{
int32_t target = MCF_SLT_SCNT(0) - (us * (SYSCLK / 1000));
bool res;
do
{
if ((res = (*condition)()))
return res;
} while (MCF_SLT_SCNT(0) - target > 0);
return false;
}
#endif /* _WAIT_H_ */ #endif /* _WAIT_H_ */

View File

@@ -40,276 +40,300 @@ static unsigned char tx_queue[QUEUE_LEN];
static unsigned char wptr = 0, rptr = 0; static unsigned char wptr = 0, rptr = 0;
// structure to keep track of ikbd state // structure to keep track of ikbd state
static struct { static struct
unsigned char cmd; {
unsigned char state; unsigned char cmd;
unsigned char expect; unsigned char state;
unsigned char expect;
// joystick state // joystick state
unsigned char joystick[2]; unsigned char joystick[2];
// mouse state // mouse state
unsigned short mouse_pos_x, mouse_pos_y; unsigned short mouse_pos_x, mouse_pos_y;
unsigned char mouse_buttons; unsigned char mouse_buttons;
} ikbd; } ikbd;
// #define IKBD_DEBUG // #define IKBD_DEBUG
void ikbd_init() { void ikbd_init()
// reset ikbd state {
memset(&ikbd, 0, sizeof(ikbd)); // reset ikbd state
ikbd.state = IKBD_DEFAULT; memset(&ikbd, 0, sizeof(ikbd));
ikbd.state = IKBD_DEFAULT;
} }
static void enqueue(unsigned char b) { static void enqueue(unsigned char b)
if(((wptr + 1)&(QUEUE_LEN-1)) == rptr) { {
xprintf("IKBD: !!!!!!! tx queue overflow !!!!!!!!!\n"); if (((wptr + 1)&(QUEUE_LEN-1)) == rptr)
return; {
} xprintf("IKBD: !!!!!!! tx queue overflow !!!!!!!!!\n");
return;
}
tx_queue[wptr] = b; tx_queue[wptr] = b;
wptr = (wptr+1)&(QUEUE_LEN-1); wptr = (wptr + 1) & (QUEUE_LEN - 1);
} }
// convert internal joystick format into atari ikbd format // convert internal joystick format into atari ikbd format
static unsigned char joystick_map2ikbd(unsigned in) { static unsigned char joystick_map2ikbd(unsigned in)
unsigned char out = 0; {
unsigned char out = 0;
if(in & JOY_UP) out |= 0x01; if (in & JOY_UP) out |= 0x01;
if(in & JOY_DOWN) out |= 0x02; if (in & JOY_DOWN) out |= 0x02;
if(in & JOY_LEFT) out |= 0x04; if (in & JOY_LEFT) out |= 0x04;
if(in & JOY_RIGHT) out |= 0x08; if (in & JOY_RIGHT) out |= 0x08;
if(in & JOY_BTN1) out |= 0x80; if (in & JOY_BTN1) out |= 0x80;
return out; return out;
} }
// process inout from atari core into ikbd // process inout from atari core into ikbd
void ikbd_handle_input(unsigned char cmd) { void ikbd_handle_input(unsigned char cmd)
// expecting a second byte for command {
if(ikbd.expect) { // expecting a second byte for command
ikbd.expect--; if (ikbd.expect)
{
ikbd.expect--;
// last byte of command received // last byte of command received
if(!ikbd.expect) { if (!ikbd.expect)
switch(ikbd.cmd) { {
case 0x07: // set mouse button action switch(ikbd.cmd)
xprintf("IKBD: mouse button action = %x\n", cmd); {
case 0x07: // set mouse button action
xprintf("IKBD: mouse button action = %x\n", cmd);
// bit 2: Mouse buttons act like keys (LEFT=0x74 & RIGHT=0x75) // bit 2: Mouse buttons act like keys (LEFT=0x74 & RIGHT=0x75)
if(cmd & 0x04) ikbd.state |= IKBD_STATE_MOUSE_BUTTON_AS_KEY; if(cmd & 0x04) ikbd.state |= IKBD_STATE_MOUSE_BUTTON_AS_KEY;
else ikbd.state &= ~IKBD_STATE_MOUSE_BUTTON_AS_KEY; else ikbd.state &= ~IKBD_STATE_MOUSE_BUTTON_AS_KEY;
break; break;
case 0x80: // ibkd reset case 0x80: // ibkd reset
// reply "everything is ok" // reply "everything is ok"
enqueue(0xf0); enqueue(0xf0);
break; break;
default: default:
break; break;
} }
}
return;
} }
return; ikbd.cmd = cmd;
}
ikbd.cmd = cmd; switch(cmd)
{
case 0x07:
xprintf("IKBD: Set mouse button action");
ikbd.expect = 1;
break;
switch(cmd) { case 0x08:
case 0x07: xprintf("IKBD: Set relative mouse positioning");
xprintf("IKBD: Set mouse button action"); ikbd.state &= ~IKBD_STATE_MOUSE_DISABLED;
ikbd.expect = 1; ikbd.state &= ~IKBD_STATE_MOUSE_ABSOLUTE;
break; break;
case 0x08: case 0x09:
xprintf("IKBD: Set relative mouse positioning"); xprintf("IKBD: Set absolute mouse positioning");
ikbd.state &= ~IKBD_STATE_MOUSE_DISABLED; ikbd.state &= ~IKBD_STATE_MOUSE_DISABLED;
ikbd.state &= ~IKBD_STATE_MOUSE_ABSOLUTE; ikbd.state |= IKBD_STATE_MOUSE_ABSOLUTE;
break; ikbd.expect = 4;
break;
case 0x09: case 0x0b:
xprintf("IKBD: Set absolute mouse positioning"); xprintf("IKBD: Set Mouse threshold");
ikbd.state &= ~IKBD_STATE_MOUSE_DISABLED; ikbd.expect = 2;
ikbd.state |= IKBD_STATE_MOUSE_ABSOLUTE; break;
ikbd.expect = 4;
break;
case 0x0b: case 0x0f:
xprintf("IKBD: Set Mouse threshold"); xprintf("IKBD: Set Y at bottom");
ikbd.expect = 2; ikbd.state |= IKBD_STATE_MOUSE_Y_BOTTOM;
break; break;
case 0x0f: case 0x10:
xprintf("IKBD: Set Y at bottom"); xprintf("IKBD: Set Y at top");
ikbd.state |= IKBD_STATE_MOUSE_Y_BOTTOM; ikbd.state &= ~IKBD_STATE_MOUSE_Y_BOTTOM;
break; break;
case 0x10: case 0x12:
xprintf("IKBD: Set Y at top"); xprintf("IKBD: Disable mouse");
ikbd.state &= ~IKBD_STATE_MOUSE_Y_BOTTOM; ikbd.state |= IKBD_STATE_MOUSE_DISABLED;
break; break;
case 0x12: case 0x14:
xprintf("IKBD: Disable mouse"); xprintf("IKBD: Set Joystick event reporting");
ikbd.state |= IKBD_STATE_MOUSE_DISABLED; ikbd.state |= IKBD_STATE_JOYSTICK_EVENT_REPORTING;
break; break;
case 0x14: case 0x15:
xprintf("IKBD: Set Joystick event reporting"); xprintf("IKBD: Set Joystick interrogation mode");
ikbd.state |= IKBD_STATE_JOYSTICK_EVENT_REPORTING; ikbd.state &= ~IKBD_STATE_JOYSTICK_EVENT_REPORTING;
break; break;
case 0x15: case 0x16: // interrogate joystick
xprintf("IKBD: Set Joystick interrogation mode"); // send reply
ikbd.state &= ~IKBD_STATE_JOYSTICK_EVENT_REPORTING; enqueue(0xfd);
break; enqueue(joystick_map2ikbd(ikbd.joystick[0]));
enqueue(joystick_map2ikbd(ikbd.joystick[1]));
break;
case 0x16: // interrogate joystick case 0x1a:
// send reply xprintf("IKBD: Disable joysticks");
enqueue(0xfd); ikbd.state &= ~IKBD_STATE_JOYSTICK_EVENT_REPORTING;
enqueue(joystick_map2ikbd(ikbd.joystick[0])); break;
enqueue(joystick_map2ikbd(ikbd.joystick[1]));
break;
case 0x1a: case 0x1c:
xprintf("IKBD: Disable joysticks"); xprintf("IKBD: Interrogate time of day");
ikbd.state &= ~IKBD_STATE_JOYSTICK_EVENT_REPORTING;
break;
case 0x1c: enqueue(0xfc);
xprintf("IKBD: Interrogate time of day"); enqueue(0x13); // year bcd
enqueue(0x03); // month bcd
enqueue(0x07); // day bcd
enqueue(0x20); // hour bcd
enqueue(0x58); // minute bcd
enqueue(0x00); // second bcd
break;
enqueue(0xfc);
enqueue(0x13); // year bcd
enqueue(0x03); // month bcd
enqueue(0x07); // day bcd
enqueue(0x20); // hour bcd
enqueue(0x58); // minute bcd
enqueue(0x00); // second bcd
break;
case 0x80: case 0x80:
xprintf("IKBD: Reset"); xprintf("IKBD: Reset");
ikbd.expect = 1; ikbd.expect = 1;
ikbd.state = IKBD_DEFAULT; ikbd.state = IKBD_DEFAULT;
break; break;
default: default:
xprintf("IKBD: unknown command: %x\n", cmd); xprintf("IKBD: unknown command: %x\n", cmd);
break; break;
} }
} }
void ikbd_poll(void) { void ikbd_poll(void) {
static int mtimer = 0; static int mtimer = 0;
if(CheckTimer(mtimer)) { if (CheckTimer(mtimer))
mtimer = GetTimer(10); {
mtimer = GetTimer(10);
// check for incoming ikbd data
// check for incoming ikbd data
EnableIO();
SPI(UIO_IKBD_IN);
while(SPI(0))
ikbd_handle_input(SPI(0));
DisableIO();
}
// send data from queue if present
if(rptr == wptr) return;
// transmit data from queue
EnableIO(); EnableIO();
SPI(UIO_IKBD_IN); SPI(UIO_IKBD_OUT);
SPI(tx_queue[rptr]);
while(SPI(0))
ikbd_handle_input(SPI(0));
DisableIO(); DisableIO();
}
// send data from queue if present rptr = (rptr + 1) & (QUEUE_LEN - 1);
if(rptr == wptr) return;
// transmit data from queue
EnableIO();
SPI(UIO_IKBD_OUT);
SPI(tx_queue[rptr]);
DisableIO();
rptr = (rptr+1)&(QUEUE_LEN-1);
} }
void ikbd_joystick(unsigned char joystick, unsigned char map) { void ikbd_joystick(unsigned char joystick, unsigned char map)
// todo: suppress events for joystick 0 as long as mouse {
// is enabled? // todo: suppress events for joystick 0 as long as mouse
// is enabled?
if(ikbd.state & IKBD_STATE_JOYSTICK_EVENT_REPORTING) {
if (ikbd.state & IKBD_STATE_JOYSTICK_EVENT_REPORTING)
{
#ifdef IKBD_DEBUG #ifdef IKBD_DEBUG
xprintf("IKBD: joy %d %x\n", joystick, map); xprintf("IKBD: joy %d %x\n", joystick, map);
#endif #endif
// only report joystick data for joystick 0 if the mouse is disabled // only report joystick data for joystick 0 if the mouse is disabled
if((ikbd.state & IKBD_STATE_MOUSE_DISABLED) || (joystick == 1)) { if ((ikbd.state & IKBD_STATE_MOUSE_DISABLED) || (joystick == 1))
enqueue(0xfe + joystick); {
enqueue(joystick_map2ikbd(map)); enqueue(0xfe + joystick);
enqueue(joystick_map2ikbd(map));
}
if (!(ikbd.state & IKBD_STATE_MOUSE_DISABLED))
{
// the fire button also generates a mouse event if
// mouse reporting is enabled
if ((map & JOY_BTN1) != (ikbd.joystick[joystick] & JOY_BTN1))
{
// generate mouse event (ikbd_joystick_buttons is evaluated inside
// user_io_mouse)
ikbd.joystick[joystick] = map;
ikbd_mouse(0, 0, 0);
}
}
} }
if(!(ikbd.state & IKBD_STATE_MOUSE_DISABLED)) {
// the fire button also generates a mouse event if
// mouse reporting is enabled
if((map & JOY_BTN1) != (ikbd.joystick[joystick] & JOY_BTN1)) {
// generate mouse event (ikbd_joystick_buttons is evaluated inside
// user_io_mouse)
ikbd.joystick[joystick] = map;
ikbd_mouse(0, 0, 0);
}
}
}
#ifdef IKBD_DEBUG #ifdef IKBD_DEBUG
else else
xprintf("IKBD: no monitor, drop joy %d %x\n", joystick, map); xprintf("IKBD: no monitor, drop joy %d %x\n", joystick, map);
#endif #endif
// save state of joystick for interrogation mode // save state of joystick for interrogation mode
ikbd.joystick[joystick] = map; ikbd.joystick[joystick] = map;
} }
void ikbd_keyboard(unsigned char code) { void ikbd_keyboard(unsigned char code)
{
#ifdef IKBD_DEBUG #ifdef IKBD_DEBUG
xprintf("IKBD: send keycode %x%s\n", code&0x7f, (code&0x80)?" BREAK":""); xprintf("IKBD: send keycode %x%s\n", code&0x7f, (code&0x80)?" BREAK":"");
#endif #endif
enqueue(code); enqueue(code);
} }
void ikbd_mouse(uint8_t b, int8_t x, int8_t y) { void ikbd_mouse(uint8_t b, int8_t x, int8_t y)
if(ikbd.state & IKBD_STATE_MOUSE_DISABLED) {
return; if (ikbd.state & IKBD_STATE_MOUSE_DISABLED)
return;
// joystick and mouse buttons are wired together in // joystick and mouse buttons are wired together in
// atari st // atari st
b |= (ikbd.joystick[0] & JOY_BTN1)?1:0; b |= (ikbd.joystick[0] & JOY_BTN1)?1:0;
b |= (ikbd.joystick[1] & JOY_BTN1)?2:0; b |= (ikbd.joystick[1] & JOY_BTN1)?2:0;
static unsigned char b_old = 0; static unsigned char b_old = 0;
// monitor state of two mouse buttons // monitor state of two mouse buttons
if(b != b_old) { if (b != b_old)
// check if mouse buttons are supposed to be treated like keys {
if(ikbd.state & IKBD_STATE_MOUSE_BUTTON_AS_KEY) { // check if mouse buttons are supposed to be treated like keys
// Mouse buttons act like keys (LEFT=0x74 & RIGHT=0x75) if (ikbd.state & IKBD_STATE_MOUSE_BUTTON_AS_KEY)
{
// handle left mouse button // Mouse buttons act like keys (LEFT=0x74 & RIGHT=0x75)
if((b ^ b_old) & 1) ikbd_keyboard(0x74 | ((b&1)?0x00:0x80));
// handle right mouse button // handle left mouse button
if((b ^ b_old) & 2) ikbd_keyboard(0x75 | ((b&2)?0x00:0x80)); if((b ^ b_old) & 1) ikbd_keyboard(0x74 | ((b&1)?0x00:0x80));
// handle right mouse button
if((b ^ b_old) & 2) ikbd_keyboard(0x75 | ((b&2)?0x00:0x80));
}
b_old = b;
} }
b_old = b;
}
#if 0 #if 0
if(ikbd.state & IKBD_STATE_MOUSE_BUTTON_AS_KEY) { if(ikbd.state & IKBD_STATE_MOUSE_BUTTON_AS_KEY)
b = 0; {
// if mouse position is 0/0 quit here b = 0;
if(!x && !y) return; // if mouse position is 0/0 quit here
} if(!x && !y) return;
}
#endif #endif
if(ikbd.state & IKBD_STATE_MOUSE_ABSOLUTE) { if (ikbd.state & IKBD_STATE_MOUSE_ABSOLUTE)
} else { {
// atari has mouse button bits swapped }
enqueue(0xf8|((b&1)?2:0)|((b&2)?1:0)); else
enqueue(x); {
enqueue((ikbd.state & IKBD_STATE_MOUSE_Y_BOTTOM)?-y:y); // atari has mouse button bits swapped
} enqueue(0xf8|((b&1)?2:0)|((b&2)?1:0));
enqueue(x);
enqueue((ikbd.state & IKBD_STATE_MOUSE_Y_BOTTOM)?-y:y);
}
} }

View File

@@ -5,7 +5,7 @@
define addresses define addresses
set $vbr = 0x00000000 set $vbr = 0x00000000
#monitor bdm-ctl-set 0x0801 0x00000000 #monitor bdm-ctl-set 0x0801 0x00000000
set $mbar = 0xFF000000 set $mbar = 0xFF000000
#monitor bdm-ctl-set 0x0C0F 0xFF000000 #monitor bdm-ctl-set 0x0C0F 0xFF000000
@@ -22,30 +22,30 @@ end
define setup-dram define setup-dram
# Init CS0 (BootFLASH @ E000_0000 - E07F_FFFF 8Mbytes) # Init CS0 (BootFLASH @ E000_0000 - E07F_FFFF 8Mbytes)
set *((long *) 0xFF000500) = 0xE0000000 set *((long *) 0xFF000500) = 0xE0000000
set *((long *) 0xFF000508) = 0x00041180 set *((long *) 0xFF000508) = 0x00041180
set *((long *) 0xFF000504) = 0x007F0001 set *((long *) 0xFF000504) = 0x007F0001
# set *((long *) 0xFF00050C) = 0xFFF00000 # ATARI I/O address # set *((long *) 0xFF00050C) = 0xFFF00000 # ATARI I/O address
# SDRAM Initialization @ 0000_0000 - 1FFF_FFFF 512Mbytes # SDRAM Initialization @ 0000_0000 - 1FFF_FFFF 512Mbytes
set *((long *) 0xFF000004) = 0x000002AA set *((long *) 0xFF000004) = 0x000002AA
set *((long *) 0xFF000020) = 0x0000001A set *((long *) 0xFF000020) = 0x0000001A
set *((long *) 0xFF000024) = 0x0800001A set *((long *) 0xFF000024) = 0x0800001A
set *((long *) 0xFF000028) = 0x1000001A set *((long *) 0xFF000028) = 0x1000001A
set *((long *) 0xFF00002C) = 0x1800001A set *((long *) 0xFF00002C) = 0x1800001A
set *((long *) 0xFF000108) = 0x73622830 set *((long *) 0xFF000108) = 0x73622830
set *((long *) 0xFF00010C) = 0x46770000 set *((long *) 0xFF00010C) = 0x46770000
set *((long *) 0xFF000104) = 0xE10D0002 set *((long *) 0xFF000104) = 0xE10D0002
set *((long *) 0xFF000100) = 0x40010000 set *((long *) 0xFF000100) = 0x40010000
set *((long *) 0xFF000100) = 0x048D0000 set *((long *) 0xFF000100) = 0x048D0000
set *((long *) 0xFF000104) = 0xE10D0002 set *((long *) 0xFF000104) = 0xE10D0002
set *((long *) 0xFF000104) = 0xE10D0004 set *((long *) 0xFF000104) = 0xE10D0004
set *((long *) 0xFF000104) = 0xE10D0004 set *((long *) 0xFF000104) = 0xE10D0004
set *((long *) 0xFF000100) = 0x008D0000 set *((long *) 0xFF000100) = 0x008D0000
set *((long *) 0xFF000104) = 0x710D0F00 set *((long *) 0xFF000104) = 0x710D0F00
end end
define cu define cu
@@ -61,6 +61,11 @@ define ib
setup-dram setup-dram
end end
define run
continue
end
tr tr
ib ib
load add-symbol-file ../emutos/emutos2.img 0xe00000
load firebee/ram.elf

View File

@@ -13,8 +13,10 @@
#include "firebee.h" #include "firebee.h"
#elif defined(MACHINE_M5484LITE) #elif defined(MACHINE_M5484LITE)
#include "m5484l.h" #include "m5484l.h"
#elif defined(MACHINE_M54455)
#include "m54455.h"
#else #else
#error "unknown machine" #error "unknown machine!"
#endif #endif
//#define DBG_AM79 //#define DBG_AM79
@@ -63,6 +65,7 @@ int am79c874_init(uint8_t fec_ch, uint8_t phy_addr, uint8_t speed, uint8_t duple
if (!(settings & MII_AM79C874_CR_RESET)) if (!(settings & MII_AM79C874_CR_RESET))
break; break;
} }
if (timeout >= FEC_MII_TIMEOUT) if (timeout >= FEC_MII_TIMEOUT)
{ {
dbg("%s: PHY reset failed\r\n", __FUNCTION__); dbg("%s: PHY reset failed\r\n", __FUNCTION__);
@@ -88,11 +91,14 @@ int am79c874_init(uint8_t fec_ch, uint8_t phy_addr, uint8_t speed, uint8_t duple
if (timeout >= FEC_MII_TIMEOUT) if (timeout >= FEC_MII_TIMEOUT)
{ {
dbg("%s: PHY Set the default mode\r\n", __FUNCTION__); dbg("%s: Auto-negotiation failed (timeout). Set default mode (100Mbps, full duplex)\r\n", __FUNCTION__);
/* Set the default mode (Full duplex, 100 Mbps) */ /* Set the default mode (Full duplex, 100 Mbps) */
if (!fec_mii_write(fec_ch, phy_addr, MII_AM79C874_CR, MII_AM79C874_CR_100MB | MII_AM79C874_CR_DPLX)) if (!fec_mii_write(fec_ch, phy_addr, MII_AM79C874_CR, MII_AM79C874_CR_100MB | MII_AM79C874_CR_DPLX))
{
dbg("%s: forced setting 100Mbps/full failed.\r\n", __FUNCTION__);
return 0; return 0;
}
} }
#ifdef DBG_AM79 #ifdef DBG_AM79

View File

@@ -11,7 +11,7 @@
#include <stdbool.h> #include <stdbool.h>
#include <stddef.h> #include <stddef.h>
#define DBG_ARP //#define DBG_ARP
#ifdef DBG_ARP #ifdef DBG_ARP
#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0) #define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0)
#else #else

View File

@@ -18,13 +18,15 @@
#include "firebee.h" #include "firebee.h"
#elif defined(MACHINE_M5484LITE) #elif defined(MACHINE_M5484LITE)
#include "m5484l.h" #include "m5484l.h"
#elif defined(MACHINE_M54455)
#include "m54455.h"
#else #else
#error "Unknown machine!" #error "Unknown machine!"
#endif #endif
#define DBG_BCM #define DBG_BCM
#ifdef DBG_BCM #ifdef DBG_BCM
#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0) #define dbg(format, arg...) do { xprintf("DEBUG %s(): " format, __FUNCTION__, ##arg); } while (0)
#else #else
#define dbg(format, arg...) do { ; } while (0) #define dbg(format, arg...) do { ; } while (0)
#endif /* DBG_BCM */ #endif /* DBG_BCM */
@@ -53,7 +55,7 @@ int bcm5222_init(uint8_t fec_ch, uint8_t phy_addr, uint8_t speed, uint8_t duplex
/* Initialize the MII interface */ /* Initialize the MII interface */
fec_mii_init(fec_ch, SYSCLK / 1000); fec_mii_init(fec_ch, SYSCLK / 1000);
dbg("%s: PHY reset\r\n", __FUNCTION__); dbg("PHY reset\r\n");
/* Reset the PHY */ /* Reset the PHY */
if (!fec_mii_write(fec_ch, phy_addr, BCM5222_CTRL, BCM5222_CTRL_RESET | BCM5222_CTRL_ANE)) if (!fec_mii_write(fec_ch, phy_addr, BCM5222_CTRL, BCM5222_CTRL_RESET | BCM5222_CTRL_ANE))
@@ -69,7 +71,7 @@ int bcm5222_init(uint8_t fec_ch, uint8_t phy_addr, uint8_t speed, uint8_t duplex
if(timeout >= FEC_MII_TIMEOUT) if(timeout >= FEC_MII_TIMEOUT)
return 0; return 0;
dbg("%s: PHY reset OK\r\n", __FUNCTION__); dbg("PHY reset OK\r\n");
settings = (BCM5222_AN_ADV_NEXT_PAGE | BCM5222_AN_ADV_PAUSE); settings = (BCM5222_AN_ADV_NEXT_PAGE | BCM5222_AN_ADV_PAUSE);
@@ -87,13 +89,13 @@ int bcm5222_init(uint8_t fec_ch, uint8_t phy_addr, uint8_t speed, uint8_t duplex
if (!fec_mii_write(fec_ch, phy_addr, BCM5222_AN_ADV, settings)) if (!fec_mii_write(fec_ch, phy_addr, BCM5222_AN_ADV, settings))
return 0; return 0;
dbg("%s: PHY Enable Auto-Negotiation\r\n", __FUNCTION__); dbg("PHY Enable Auto-Negotiation\r\n");
/* Enable Auto-Negotiation */ /* Enable Auto-Negotiation */
if (!fec_mii_write(fec_ch, phy_addr, BCM5222_CTRL, (BCM5222_CTRL_ANE | BCM5222_CTRL_RESTART_AN))) if (!fec_mii_write(fec_ch, phy_addr, BCM5222_CTRL, (BCM5222_CTRL_ANE | BCM5222_CTRL_RESTART_AN)))
return 0; return 0;
dbg("%s: PHY Wait for auto-negotiation to complete\r\n", __FUNCTION__); dbg("PHY Wait for auto-negotiation to complete\r\n");
/* Wait for auto-negotiation to complete */ /* Wait for auto-negotiation to complete */
for (timeout = 0; timeout < FEC_MII_TIMEOUT; timeout++) for (timeout = 0; timeout < FEC_MII_TIMEOUT; timeout++)
@@ -106,7 +108,7 @@ int bcm5222_init(uint8_t fec_ch, uint8_t phy_addr, uint8_t speed, uint8_t duplex
if (timeout < FEC_MII_TIMEOUT) if (timeout < FEC_MII_TIMEOUT)
{ {
dbg("%s: PHY auto-negociation complete\r\n", __FUNCTION__); dbg("PHY auto-negociation complete\r\n");
/* Read Auxiliary Control/Status Register */ /* Read Auxiliary Control/Status Register */
if (!fec_mii_read(fec_ch, phy_addr, BCM5222_ACSR, &settings)) if (!fec_mii_read(fec_ch, phy_addr, BCM5222_ACSR, &settings))
@@ -114,7 +116,7 @@ int bcm5222_init(uint8_t fec_ch, uint8_t phy_addr, uint8_t speed, uint8_t duplex
} }
else else
{ {
dbg("%s: auto negotiation failed, PHY Set the default mode\r\n", __FUNCTION__); dbg("auto negotiation failed, PHY Set the default mode\r\n");
/* Set the default mode (Full duplex, 100 Mbps) */ /* Set the default mode (Full duplex, 100 Mbps) */
if (!fec_mii_write(fec_ch, phy_addr, BCM5222_ACSR, settings = (BCM5222_ACSR_100BTX | BCM5222_ACSR_FDX))) if (!fec_mii_write(fec_ch, phy_addr, BCM5222_ACSR, settings = (BCM5222_ACSR_100BTX | BCM5222_ACSR_FDX)))
@@ -127,17 +129,17 @@ int bcm5222_init(uint8_t fec_ch, uint8_t phy_addr, uint8_t speed, uint8_t duplex
else else
fec_duplex(fec_ch, FEC_MII_HALF_DUPLEX); fec_duplex(fec_ch, FEC_MII_HALF_DUPLEX);
dbg("%s: PHY Mode: ", __FUNCTION__); dbg("PHY Mode: ");
if (settings & BCM5222_ACSR_100BTX) if (settings & BCM5222_ACSR_100BTX)
dbg("%s: 100Mbps\r\n", __FUNCTION__); dbg("100Mbps\r\n");
else else
dbg("%s: 10Mbps\r\n", __FUNCTION__); dbg("10Mbps\r\n");
if (settings & BCM5222_ACSR_FDX) if (settings & BCM5222_ACSR_FDX)
dbg("%s: Full-duplex\r\n", __FUNCTION__); dbg("Full-duplex\r\n");
else else
dbg("%s: Half-duplex\r\n", __FUNCTION__); dbg("Half-duplex\r\n");
return 1; return 1;
} }

View File

@@ -13,7 +13,7 @@
#define DBG_BOOTP #define DBG_BOOTP
#ifdef DBG_BOOTP #ifdef DBG_BOOTP
#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0) #define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0)
#else #else
#define dbg(format, arg...) do { ; } while (0) #define dbg(format, arg...) do { ; } while (0)
#endif /* DBG_BOOTP */ #endif /* DBG_BOOTP */
@@ -94,7 +94,7 @@ void bootp_handler(NIF *nif, NBUF *nbuf)
struct bootp_packet *rx_p; struct bootp_packet *rx_p;
udp_frame_hdr *udpframe; udp_frame_hdr *udpframe;
dbg("%s\n", __FUNCTION__); dbg("\r\n");
rx_p = (struct bootp_packet *) &nbuf->data[nbuf->offset]; rx_p = (struct bootp_packet *) &nbuf->data[nbuf->offset];
udpframe = (udp_frame_hdr *) &nbuf->data[nbuf->offset - UDP_HDR_SIZE]; udpframe = (udp_frame_hdr *) &nbuf->data[nbuf->offset - UDP_HDR_SIZE];

View File

@@ -17,21 +17,24 @@
#include "bas_string.h" #include "bas_string.h"
#include "bas_printf.h" #include "bas_printf.h"
#include "util.h" #include "util.h"
#include "wait.h"
#include "am79c874.h" #include "am79c874.h"
#include "bcm5222.h" //#include "bcm5222.h"
#include <stdbool.h> #include <stdbool.h>
#if defined(MACHINE_FIREBEE) #if defined(MACHINE_FIREBEE)
#include "firebee.h" #include "firebee.h"
#elif defined(MACHINE_M5484LITE) #elif defined(MACHINE_M5484LITE)
#include "m5484l.h" #include "m5484l.h"
#elif defined(MACHINE_M54455)
#include "m54455.h"
#else #else
#error Unknown machine! #error Unknown machine!
#endif #endif
//#define DBG_FEC // #define DBG_FEC
#ifdef DBG_FEC #ifdef DBG_FEC
#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0) #define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0)
#else #else
#define dbg(format, arg...) do { ; } while (0) #define dbg(format, arg...) do { ; } while (0)
#endif /* DBG_FEC */ #endif /* DBG_FEC */
@@ -91,11 +94,12 @@ int fec_mii_write(uint8_t ch, uint8_t phy_addr, uint8_t reg_addr, uint16_t data)
*/ */
for (timeout = 0; timeout < FEC_MII_TIMEOUT; timeout++) for (timeout = 0; timeout < FEC_MII_TIMEOUT; timeout++)
{ {
wait(1);
if (MCF_FEC_EIR(ch) & MCF_FEC_EIR_MII) if (MCF_FEC_EIR(ch) & MCF_FEC_EIR_MII)
break; break;
} }
if(timeout == FEC_MII_TIMEOUT) if (timeout == FEC_MII_TIMEOUT)
return 0; return 0;
/* /*
@@ -156,11 +160,12 @@ int fec_mii_read(uint8_t ch, uint8_t phy_addr, uint8_t reg_addr, uint16_t *data)
*/ */
for (timeout = 0; timeout < FEC_MII_TIMEOUT; timeout++) for (timeout = 0; timeout < FEC_MII_TIMEOUT; timeout++)
{ {
wait(1);
if (MCF_FEC_EIR(ch) & MCF_FEC_EIR_MII) if (MCF_FEC_EIR(ch) & MCF_FEC_EIR_MII)
break; break;
} }
if(timeout == FEC_MII_TIMEOUT) if (timeout == FEC_MII_TIMEOUT)
return 0; return 0;
/* /*
@@ -232,33 +237,33 @@ void fec_log_init(uint8_t ch)
*/ */
void fec_log_dump(uint8_t ch) void fec_log_dump(uint8_t ch)
{ {
dbg("%s: \r\n FEC%d Log\r\n", __FUNCTION__, ch); dbg("\r\n FEC%d Log\r\n", __FUNCTION__, ch);
dbg("%s: ---------------\r\n", __FUNCTION__); dbg(" ---------------\r\n", __FUNCTION__);
dbg("%s: Total: %4d\r\n", __FUNCTION__, fec_log[ch].total); dbg(" Total: %4d\r\n", fec_log[ch].total);
dbg("%s: hberr: %4d\r\n", __FUNCTION__, fec_log[ch].hberr); dbg(" hberr: %4d\r\n", fec_log[ch].hberr);
dbg("%s: babr: %4d\r\n", __FUNCTION__, fec_log[ch].babr); dbg(" babr: %4d\r\n", fec_log[ch].babr);
dbg("%s: babt: %4d\r\n", __FUNCTION__, fec_log[ch].babt); dbg(" babt: %4d\r\n", fec_log[ch].babt);
dbg("%s: gra: %4d\r\n", __FUNCTION__, fec_log[ch].gra); dbg(" gra: %4d\r\n", fec_log[ch].gra);
dbg("%s: txf: %4d\r\n", __FUNCTION__, fec_log[ch].txf); dbg(" txf: %4d\r\n", fec_log[ch].txf);
dbg("%s: mii: %4d\r\n", __FUNCTION__, fec_log[ch].mii); dbg(" mii: %4d\r\n", fec_log[ch].mii);
dbg("%s: lc: %4d\r\n", __FUNCTION__, fec_log[ch].lc); dbg(" lc: %4d\r\n", fec_log[ch].lc);
dbg("%s: rl: %4d\r\n", __FUNCTION__, fec_log[ch].rl); dbg(" rl: %4d\r\n", fec_log[ch].rl);
dbg("%s: xfun: %4d\r\n", __FUNCTION__, fec_log[ch].xfun); dbg(" xfun: %4d\r\n", fec_log[ch].xfun);
dbg("%s: xferr: %4d\r\n", __FUNCTION__, fec_log[ch].xferr); dbg(" xferr: %4d\r\n", fec_log[ch].xferr);
dbg("%s: rferr: %4d\r\n", __FUNCTION__, fec_log[ch].rferr); dbg(" rferr: %4d\r\n", fec_log[ch].rferr);
dbg("%s: dtxf: %4d\r\n", __FUNCTION__, fec_log[ch].dtxf); dbg(" dtxf: %4d\r\n", fec_log[ch].dtxf);
dbg("%s: drxf: %4d\r\n", __FUNCTION__, fec_log[ch].drxf); dbg(" drxf: %4d\r\n", fec_log[ch].drxf);
dbg("%s: \r\nRFSW:\r\n", __FUNCTION__); dbg(" \r\nRFSW:\r\n");
dbg("%s: inv: %4d\r\n", __FUNCTION__, fec_log[ch].rfsw_inv); dbg(" inv: %4d\r\n", fec_log[ch].rfsw_inv);
dbg("%s: m: %4d\r\n", __FUNCTION__, fec_log[ch].rfsw_m); dbg(" m: %4d\r\n", fec_log[ch].rfsw_m);
dbg("%s: bc: %4d\r\n", __FUNCTION__, fec_log[ch].rfsw_bc); dbg(" bc: %4d\r\n", fec_log[ch].rfsw_bc);
dbg("%s: mc: %4d\r\n", __FUNCTION__, fec_log[ch].rfsw_mc); dbg(" mc: %4d\r\n", fec_log[ch].rfsw_mc);
dbg("%s: lg: %4d\r\n", __FUNCTION__, fec_log[ch].rfsw_lg); dbg(" lg: %4d\r\n", fec_log[ch].rfsw_lg);
dbg("%s: no: %4d\r\n", __FUNCTION__, fec_log[ch].rfsw_no); dbg(" no: %4d\r\n", fec_log[ch].rfsw_no);
dbg("%s: cr: %4d\r\n", __FUNCTION__, fec_log[ch].rfsw_cr); dbg(" cr: %4d\r\n", fec_log[ch].rfsw_cr);
dbg("%s: ov: %4d\r\n", __FUNCTION__, fec_log[ch].rfsw_ov); dbg(" ov: %4d\r\n", fec_log[ch].rfsw_ov);
dbg("%s: tr: %4d\r\n", __FUNCTION__, fec_log[ch].rfsw_tr); dbg(" tr: %4d\r\n", fec_log[ch].rfsw_tr);
dbg("%s: ---------------\r\n\r\n", __FUNCTION__); dbg(" ---------------\r\n\r\n");
} }
/* /*
@@ -481,9 +486,7 @@ void fec_init(uint8_t ch, uint8_t mode, const uint8_t *pa)
*/ */
MCF_FEC_RCR(ch) = 0 MCF_FEC_RCR(ch) = 0
| MCF_FEC_RCR_MAX_FL(ETH_MAX_FRM) | MCF_FEC_RCR_MAX_FL(ETH_MAX_FRM)
//#ifdef FEC_PROMISCUOUS
| MCF_FEC_RCR_PROM | MCF_FEC_RCR_PROM
//#endif
| MCF_FEC_RCR_FCE; | MCF_FEC_RCR_FCE;
if (mode == FEC_MODE_MII) if (mode == FEC_MODE_MII)
@@ -535,19 +538,26 @@ void fec_rx_start(uint8_t ch, int8_t *rxbd)
{ {
uint32_t initiator; uint32_t initiator;
int channel; int channel;
#ifdef DBG_FEC
int res; int res;
#endif
/* /*
* Make the initiator assignment * Make the initiator assignment
*/ */
res = dma_set_initiator(DMA_FEC_RX(ch)); #if defined(DBG_FEC)
dbg("%s: dma_set_initiator(DMA_FEC_RX(%d)): %d\r\n", __FUNCTION__, ch, res); res =
#else
(void)
#endif
dma_set_initiator(DMA_FEC_RX(ch));
dbg("dma_set_initiator(DMA_FEC_RX(%d)): %d\r\n", ch, res);
/* /*
* Grab the initiator number * Grab the initiator number
*/ */
initiator = dma_get_initiator(DMA_FEC_RX(ch)); initiator = dma_get_initiator(DMA_FEC_RX(ch));
dbg("%s: dma_get_initiator(DMA_FEC_RX(%d)) = %d\r\n", __FUNCTION__, ch, initiator); dbg("dma_get_initiator(DMA_FEC_RX(%d)) = %d\r\n", ch, initiator);
/* /*
* Determine the DMA channel running the task for the * Determine the DMA channel running the task for the
@@ -555,7 +565,7 @@ void fec_rx_start(uint8_t ch, int8_t *rxbd)
*/ */
channel = dma_set_channel(DMA_FEC_RX(ch), channel = dma_set_channel(DMA_FEC_RX(ch),
(ch == 0) ? fec0_rx_frame : fec1_rx_frame); (ch == 0) ? fec0_rx_frame : fec1_rx_frame);
dbg("%s: DMA channel for FEC%1d: %d\r\n", __FUNCTION__, ch, channel); dbg("DMA channel for FEC%1d: %d\r\n", ch, channel);
/* /*
* Start the Rx DMA task * Start the Rx DMA task
@@ -569,18 +579,18 @@ void fec_rx_start(uint8_t ch, int8_t *rxbd)
0, 0,
initiator, initiator,
FECRX_DMA_PRI(ch), FECRX_DMA_PRI(ch),
0 0
| MCD_FECRX_DMA | MCD_FECRX_DMA
| MCD_INTERRUPT | MCD_INTERRUPT
| MCD_TT_FLAGS_CW | MCD_TT_FLAGS_CW
| MCD_TT_FLAGS_RL | MCD_TT_FLAGS_RL
| MCD_TT_FLAGS_SP | MCD_TT_FLAGS_SP
, ,
0 0
| MCD_NO_CSUM | MCD_NO_CSUM
| MCD_NO_BYTE_SWAP | MCD_NO_BYTE_SWAP
); );
dbg("%s: Rx DMA task for FEC%1d started\r\n", __FUNCTION__, ch); dbg("Rx DMA task for FEC%1d started\r\n", ch);
} }
/* /*
@@ -604,13 +614,13 @@ void fec_rx_continue(uint8_t ch)
*/ */
channel = dma_get_channel(DMA_FEC_RX(ch)); channel = dma_get_channel(DMA_FEC_RX(ch));
dbg("%s: RX DMA channel for FEC%1d is %d\r\n", __FUNCTION__, ch, channel); dbg("RX DMA channel for FEC%1d is %d\r\n", ch, channel);
/* /*
* Continue/restart the DMA task * Continue/restart the DMA task
*/ */
MCD_continDma(channel); MCD_continDma(channel);
dbg("%s: RX dma on channel %d continued\r\n", __FUNCTION__, channel); dbg("RX dma on channel %d continued\r\n", channel);
} }
/* /*
@@ -639,9 +649,9 @@ void fec_rx_stop (uint8_t ch)
/* Kill the FEC Rx DMA task */ /* Kill the FEC Rx DMA task */
MCD_killDma(channel); MCD_killDma(channel);
/* /*
* Free up the FEC requestor from the software maintained * Free up the FEC requestor from the software maintained
* initiator list * initiator list
*/ */
dma_free_initiator(DMA_FEC_RX(ch)); dma_free_initiator(DMA_FEC_RX(ch));
@@ -653,7 +663,7 @@ void fec_rx_stop (uint8_t ch)
} }
/* /*
* Receive Frame interrupt handler - this handler is called by the * Receive Frame interrupt handler - this handler is called by the
* DMA interrupt handler indicating that a packet was successfully * DMA interrupt handler indicating that a packet was successfully
* transferred out of the Rx FIFO. * transferred out of the Rx FIFO.
* *
@@ -668,7 +678,7 @@ void fec_rx_frame(uint8_t ch, NIF *nif)
NBUF *cur_nbuf, *new_nbuf; NBUF *cur_nbuf, *new_nbuf;
int keep; int keep;
dbg("%s: started\r\n", __FUNCTION__); dbg("started\r\n");
while ((pRxBD = fecbd_rx_alloc(ch)) != NULL) while ((pRxBD = fecbd_rx_alloc(ch)) != NULL)
{ {
@@ -681,7 +691,7 @@ void fec_rx_frame(uint8_t ch, NIF *nif)
* - No undefined bits should be set * - No undefined bits should be set
* - The upper 5 bits of the length should be cleared * - The upper 5 bits of the length should be cleared
*/ */
if (!(pRxBD->status & RX_BD_L) || (pRxBD->status & 0x0608) if (!(pRxBD->status & RX_BD_L) || (pRxBD->status & 0x0608)
|| (pRxBD->length & 0xF800)) || (pRxBD->length & 0xF800))
{ {
keep = false; keep = false;
@@ -713,8 +723,8 @@ void fec_rx_frame(uint8_t ch, NIF *nif)
if (keep) if (keep)
{ {
/* /*
* Pull the network buffer off the Rx ring queue * Pull the network buffer off the Rx ring queue
*/ */
cur_nbuf = nbuf_remove(NBUF_RX_RING); cur_nbuf = nbuf_remove(NBUF_RX_RING);
@@ -730,7 +740,7 @@ void fec_rx_frame(uint8_t ch, NIF *nif)
new_nbuf = nbuf_alloc(); new_nbuf = nbuf_alloc();
if (new_nbuf == NULL) if (new_nbuf == NULL)
{ {
dbg("%s: nbuf_alloc() failed\n", __FUNCTION__); dbg("nbuf_alloc() failed\n");
/* /*
* Can't allocate a new network buffer, so we * Can't allocate a new network buffer, so we
@@ -764,7 +774,7 @@ void fec_rx_frame(uint8_t ch, NIF *nif)
/* /*
* Let the DMA know that there is a new Rx BD (in case the * Let the DMA know that there is a new Rx BD (in case the
* ring was full and the DMA was waiting for an empty one) * ring was full and the DMA was waiting for an empty one)
*/ */
fec_rx_continue(ch); fec_rx_continue(ch);
@@ -775,7 +785,7 @@ void fec_rx_frame(uint8_t ch, NIF *nif)
eth_hdr = (ETH_HDR *) cur_nbuf->data; eth_hdr = (ETH_HDR *) cur_nbuf->data;
/* /*
* Pass the received packet up the network stack if the * Pass the received packet up the network stack if the
* protocol is supported in our network interface (NIF) * protocol is supported in our network interface (NIF)
*/ */
if (nif_protocol_exist(nif, eth_hdr->type)) if (nif_protocol_exist(nif, eth_hdr->type))
@@ -786,12 +796,12 @@ void fec_rx_frame(uint8_t ch, NIF *nif)
else else
{ {
nbuf_free(cur_nbuf); nbuf_free(cur_nbuf);
dbg("%s: got unsupported packet %d, trashed it\r\n", __FUNCTION__, eth_hdr->type); dbg("got unsupported packet %d, trashed it\r\n", eth_hdr->type);
} }
} }
else else
{ {
/* /*
* This frame isn't a keeper * This frame isn't a keeper
* Reset the status and length, but don't need to get another * Reset the status and length, but don't need to get another
* buffer since we are trashing the data in the current one * buffer since we are trashing the data in the current one
@@ -801,7 +811,7 @@ void fec_rx_frame(uint8_t ch, NIF *nif)
pRxBD->status |= RX_BD_E; pRxBD->status |= RX_BD_E;
/* /*
* Move the current buffer from the beginning to the end of the * Move the current buffer from the beginning to the end of the
* Rx ring queue * Rx ring queue
*/ */
cur_nbuf = nbuf_remove(NBUF_RX_RING); cur_nbuf = nbuf_remove(NBUF_RX_RING);
@@ -841,22 +851,28 @@ void fec_tx_start(uint8_t ch, int8_t *txbd)
{ {
uint32_t initiator; uint32_t initiator;
int channel; int channel;
int result;
void fec0_tx_frame(void); void fec0_tx_frame(void);
void fec1_tx_frame(void); void fec1_tx_frame(void);
#ifdef DBG_FEC
int res; int res;
#endif
/* /*
* Make the initiator assignment * Make the initiator assignment
*/ */
res = dma_set_initiator(DMA_FEC_TX(ch)); #ifdef DBG_FEC
dbg("%s: dma_set_initiator(%d) = %d\r\n", __FUNCTION__, ch, res); res =
#else
(void)
#endif
dma_set_initiator(DMA_FEC_TX(ch));
dbg("dma_set_initiator(%d) = %d\r\n", ch, res);
/* /*
* Grab the initiator number * Grab the initiator number
*/ */
initiator = dma_get_initiator(DMA_FEC_TX(ch)); initiator = dma_get_initiator(DMA_FEC_TX(ch));
dbg("%s: dma_get_initiator(%d) = %d\r\n", __FUNCTION__, ch, initiator); dbg("dma_get_initiator(%d) = %d\r\n", ch, initiator);
/* /*
@@ -865,7 +881,7 @@ void fec_tx_start(uint8_t ch, int8_t *txbd)
*/ */
channel = dma_set_channel(DMA_FEC_TX(ch), channel = dma_set_channel(DMA_FEC_TX(ch),
(ch == 0) ? fec0_tx_frame : fec1_tx_frame); (ch == 0) ? fec0_tx_frame : fec1_tx_frame);
dbg("%s: dma_set_channel(%d, ...) = %d\r\n", __FUNCTION__, ch, channel); dbg("dma_set_channel(%d, ...) = %d\r\n", ch, channel);
/* /*
* Start the Tx DMA task * Start the Tx DMA task
@@ -879,18 +895,18 @@ void fec_tx_start(uint8_t ch, int8_t *txbd)
0, 0,
initiator, initiator,
FECTX_DMA_PRI(ch), FECTX_DMA_PRI(ch),
0 0
| MCD_FECTX_DMA | MCD_FECTX_DMA
| MCD_INTERRUPT | MCD_INTERRUPT
| MCD_TT_FLAGS_CW | MCD_TT_FLAGS_CW
| MCD_TT_FLAGS_RL | MCD_TT_FLAGS_RL
| MCD_TT_FLAGS_SP | MCD_TT_FLAGS_SP
, ,
0 0
| MCD_NO_CSUM | MCD_NO_CSUM
| MCD_NO_BYTE_SWAP | MCD_NO_BYTE_SWAP
); );
dbg("%s: DMA tx task started\r\n", __FUNCTION__); dbg("DMA tx task started\r\n");
} }
/* /*
@@ -913,14 +929,13 @@ void fec_tx_continue(uint8_t ch)
* selected FEC * selected FEC
*/ */
channel = dma_get_channel(DMA_FEC_TX(ch)); channel = dma_get_channel(DMA_FEC_TX(ch));
dbg("%s: dma_get_channel(DMA_FEC_TX(%d)) = %d\r\n", dbg("dma_get_channel(DMA_FEC_TX(%d)) = %d\r\n", ch, channel);
__FUNCTION__, ch, channel);
/* /*
* Continue/restart the DMA task * Continue/restart the DMA task
*/ */
MCD_continDma(channel); MCD_continDma(channel);
dbg("%s: DMA TX task continue\r\n", __FUNCTION__); dbg("DMA TX task continue\r\n");
} }
/* /*
@@ -967,9 +982,9 @@ void fec_tx_stop(uint8_t ch)
/* Kill the FEC Tx DMA task */ /* Kill the FEC Tx DMA task */
MCD_killDma(channel); MCD_killDma(channel);
/* /*
* Free up the FEC requestor from the software maintained * Free up the FEC requestor from the software maintained
* initiator list * initiator list
*/ */
dma_free_initiator(DMA_FEC_TX(ch)); dma_free_initiator(DMA_FEC_TX(ch));
@@ -981,7 +996,7 @@ void fec_tx_stop(uint8_t ch)
} }
/* /*
* Trasmit Frame interrupt handler - this handler is called by the * Trasmit Frame interrupt handler - this handler is called by the
* DMA interrupt handler indicating that a packet was successfully * DMA interrupt handler indicating that a packet was successfully
* transferred to the Tx FIFO. * transferred to the Tx FIFO.
* *
@@ -994,7 +1009,7 @@ void fec_tx_frame(uint8_t ch)
NBUF *pNbuf; NBUF *pNbuf;
bool is_empty = true; bool is_empty = true;
dbg("%s:\r\n", __FUNCTION__); dbg("\r\n");
while ((pTxBD = fecbd_tx_free(ch)) != NULL) while ((pTxBD = fecbd_tx_free(ch)) != NULL)
{ {
fec_log[ch].dtxf++; fec_log[ch].dtxf++;
@@ -1008,7 +1023,7 @@ void fec_tx_frame(uint8_t ch)
* Free up the network buffer that was just transmitted * Free up the network buffer that was just transmitted
*/ */
nbuf_free(pNbuf); nbuf_free(pNbuf);
dbg("%s: free buffer %p from TX ring\r\n", __FUNCTION__, pNbuf); dbg("free buffer %p from TX ring\r\n", pNbuf);
/* /*
* Re-initialize the Tx BD * Re-initialize the Tx BD
@@ -1017,9 +1032,9 @@ void fec_tx_frame(uint8_t ch)
pTxBD->length = 0; pTxBD->length = 0;
is_empty = false; is_empty = false;
} }
if (is_empty) if (is_empty)
dbg("%s: transmit queue was empty!\r\n", __FUNCTION__); dbg("transmit queue was empty!\r\n");
} }
void fec0_tx_frame(void) void fec0_tx_frame(void)
@@ -1042,7 +1057,7 @@ void fec1_tx_frame(void)
* dst Destination MAC Address * dst Destination MAC Address
* src Source MAC Address * src Source MAC Address
* type Ethernet Frame Type * type Ethernet Frame Type
* length Number of bytes to be transmitted (doesn't include type, * length Number of bytes to be transmitted (doesn't include type,
* src, or dest byte count) * src, or dest byte count)
* pkt Pointer packet network buffer * pkt Pointer packet network buffer
* *
@@ -1057,14 +1072,14 @@ int fec_send(uint8_t ch, NIF *nif, uint8_t *dst, uint8_t *src, uint16_t type, NB
/* Check the length */ /* Check the length */
if ((nbuf->length + ETH_HDR_LEN) > ETH_MTU) if ((nbuf->length + ETH_HDR_LEN) > ETH_MTU)
{ {
dbg("%s: nbuf->length (%d) + ETH_HDR_LEN (%d) exceeds ETH_MTU (%d)\r\n", dbg("nbuf->length (%d) + ETH_HDR_LEN (%d) exceeds ETH_MTU (%d)\r\n",
__FUNCTION__, nbuf->length, ETH_HDR_LEN, ETH_MTU); nbuf->length, ETH_HDR_LEN, ETH_MTU);
return 0; return 0;
} }
/* /*
* Copy the destination address, source address, and Ethernet * Copy the destination address, source address, and Ethernet
* type into the packet * type into the packet
*/ */
memcpy(&nbuf->data[0], dst, 6); memcpy(&nbuf->data[0], dst, 6);
memcpy(&nbuf->data[6], src, 6); memcpy(&nbuf->data[6], src, 6);
@@ -1080,7 +1095,7 @@ int fec_send(uint8_t ch, NIF *nif, uint8_t *dst, uint8_t *src, uint16_t type, NB
*/ */
nbuf_add(NBUF_TX_RING, nbuf); nbuf_add(NBUF_TX_RING, nbuf);
/* /*
* Setup the buffer descriptor for transmission * Setup the buffer descriptor for transmission
*/ */
pTxBD->data = nbuf->data; pTxBD->data = nbuf->data;
@@ -1190,7 +1205,7 @@ static void fec_irq_handler(uint8_t ch)
event = eir & MCF_FEC_EIMR(ch); event = eir & MCF_FEC_EIMR(ch);
if (event != eir) if (event != eir)
dbg("%s: pending but not enabled: 0x%08x\r\n", __FUNCTION__, (event ^ eir)); dbg("pending but not enabled: 0x%08x\r\n", (event ^ eir));
/* /*
* Clear the event(s) in the EIR immediately * Clear the event(s) in the EIR immediately
@@ -1201,8 +1216,8 @@ static void fec_irq_handler(uint8_t ch)
{ {
fec_log[ch].total++; fec_log[ch].total++;
fec_log[ch].rferr++; fec_log[ch].rferr++;
dbg("%s: RFERR\r\n", __FUNCTION__); dbg("RFERR\r\n");
dbg("%s: FECRFSR%d = 0x%08x\r\n", __FUNCTION__, ch, MCF_FEC_FECRFSR(ch)); dbg("FECRFSR%d = 0x%08x\r\n", ch, MCF_FEC_FECRFSR(ch));
//fec_eth_stop(ch); //fec_eth_stop(ch);
} }
@@ -1210,14 +1225,14 @@ static void fec_irq_handler(uint8_t ch)
{ {
fec_log[ch].total++; fec_log[ch].total++;
fec_log[ch].xferr++; fec_log[ch].xferr++;
dbg("%s: XFERR\r\n", __FUNCTION__); dbg("XFERR\r\n");
} }
if (event & MCF_FEC_EIR_XFUN) if (event & MCF_FEC_EIR_XFUN)
{ {
fec_log[ch].total++; fec_log[ch].total++;
fec_log[ch].xfun++; fec_log[ch].xfun++;
dbg("%s: XFUN\r\n", __FUNCTION__); dbg("XFUN\r\n");
//fec_eth_stop(ch); //fec_eth_stop(ch);
} }
@@ -1225,54 +1240,54 @@ static void fec_irq_handler(uint8_t ch)
{ {
fec_log[ch].total++; fec_log[ch].total++;
fec_log[ch].rl++; fec_log[ch].rl++;
dbg("%s: RL\r\n", __FUNCTION__); dbg("RL\r\n");
} }
if (event & MCF_FEC_EIR_LC) if (event & MCF_FEC_EIR_LC)
{ {
fec_log[ch].total++; fec_log[ch].total++;
fec_log[ch].lc++; fec_log[ch].lc++;
dbg("%s: LC\r\n", __FUNCTION__); dbg("LC\r\n");
} }
if (event & MCF_FEC_EIR_MII) if (event & MCF_FEC_EIR_MII)
{ {
fec_log[ch].mii++; fec_log[ch].mii++;
dbg("%s: MII\r\n", __FUNCTION__); dbg("MII\r\n");
} }
if (event & MCF_FEC_EIR_TXF) if (event & MCF_FEC_EIR_TXF)
{ {
fec_log[ch].txf++; fec_log[ch].txf++;
dbg("%s: TXF\r\n", __FUNCTION__); dbg("TXF\r\n");
fec_log_dump(0); fec_log_dump(0);
} }
if (event & MCF_FEC_EIR_GRA) if (event & MCF_FEC_EIR_GRA)
{ {
fec_log[ch].gra++; fec_log[ch].gra++;
dbg("%s: GRA\r\n", __FUNCTION__); dbg("GRA\r\n");
} }
if (event & MCF_FEC_EIR_BABT) if (event & MCF_FEC_EIR_BABT)
{ {
fec_log[ch].total++; fec_log[ch].total++;
fec_log[ch].babt++; fec_log[ch].babt++;
dbg("%s: BABT\r\n", __FUNCTION__); dbg("BABT\r\n");
} }
if (event & MCF_FEC_EIR_BABR) if (event & MCF_FEC_EIR_BABR)
{ {
fec_log[ch].total++; fec_log[ch].total++;
fec_log[ch].babr++; fec_log[ch].babr++;
dbg("%s: BABR\r\n", __FUNCTION__); dbg("BABR\r\n");
} }
if (event & MCF_FEC_EIR_HBERR) if (event & MCF_FEC_EIR_HBERR)
{ {
fec_log[ch].total++; fec_log[ch].total++;
fec_log[ch].hberr++; fec_log[ch].hberr++;
dbg("%s: HBERR\r\n", __FUNCTION__); dbg("HBERR\r\n");
} }
} }
@@ -1282,7 +1297,7 @@ static void fec_irq_handler(uint8_t ch)
*/ */
int fec0_interrupt_handler(void* arg1, void* arg2) int fec0_interrupt_handler(void* arg1, void* arg2)
{ {
(void) arg1; (void) arg1; /* not used */
(void) arg2; (void) arg2;
fec_irq_handler(0); fec_irq_handler(0);
@@ -1292,7 +1307,7 @@ int fec0_interrupt_handler(void* arg1, void* arg2)
int fec1_interrupt_handler(void* arg1, void* arg2) int fec1_interrupt_handler(void* arg1, void* arg2)
{ {
(void) arg1; (void) arg1; /* not used */
(void) arg2; (void) arg2;
fec_irq_handler(1); fec_irq_handler(1);
@@ -1342,9 +1357,9 @@ void fec_eth_setup(uint8_t ch, uint8_t trcvr, uint8_t speed, uint8_t duplex, con
*/ */
#if defined(MACHINE_FIREBEE) #if defined(MACHINE_FIREBEE)
if (am79c874_init(0, 0, speed, duplex)) if (am79c874_init(0, 0, speed, duplex))
dbg("%s: PHY init completed\r\n", __FUNCTION__); dbg("PHY init completed\r\n");
else else
dbg("%s: PHY init failed\r\n", __FUNCTION__); dbg("PHY init failed\r\n");
#elif defined(MACHINE_M548X) #elif defined(MACHINE_M548X)
bcm_5222_init(0, 0, speed, duplex); bcm_5222_init(0, 0, speed, duplex);
#else #else
@@ -1397,7 +1412,7 @@ void fec_eth_stop(uint8_t ch)
*/ */
level = set_ipl(7); level = set_ipl(7);
dbg("%s: fec %d stopped\r\n", __FUNCTION__, ch); dbg("fec %d stopped\r\n", ch);
/* /*
* Gracefully disable the receiver and transmitter * Gracefully disable the receiver and transmitter
*/ */
@@ -1419,12 +1434,12 @@ void fec_eth_stop(uint8_t ch)
fec_log_dump(ch); fec_log_dump(ch);
#endif #endif
/* /*
* Flush the network buffers * Flush the network buffers
*/ */
nbuf_flush(); nbuf_flush();
/* /*
* Restore interrupt level * Restore interrupt level
*/ */
set_ipl(level); set_ipl(level);

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
@@ -31,14 +31,14 @@
* *
*/ */
FECBD unaligned_bds[(2 * NRXBD) + (2 * NTXBD) + 1]; static FECBD unaligned_bds[(2 * NRXBD) + (2 * NTXBD) + 1];
/* /*
* These pointers are used to reference into the chunck of data set * These pointers are used to reference into the chunck of data set
* aside for buffer descriptors * aside for buffer descriptors
*/ */
FECBD *RxBD; static FECBD *RxBD;
FECBD *TxBD; static FECBD *TxBD;
/* /*
* Macros to easier access to the BD ring * Macros to easier access to the BD ring
@@ -65,7 +65,7 @@ void fecbd_init(uint8_t ch)
NBUF *nbuf; NBUF *nbuf;
int i; int i;
dbg("%s:\r\n", __FUNCTION__); dbg("\r\n");
/* /*
* Align Buffer Descriptors to 4-byte boundary * Align Buffer Descriptors to 4-byte boundary
@@ -73,7 +73,7 @@ void fecbd_init(uint8_t ch)
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("%s: initialise RX buffer descriptor ring\r\n", __FUNCTION__); dbg("initialise RX buffer descriptor ring\r\n");
/* /*
* Initialize the Rx Buffer Descriptor ring * Initialize the Rx Buffer Descriptor ring
@@ -84,7 +84,7 @@ void fecbd_init(uint8_t ch)
nbuf = nbuf_alloc(); nbuf = nbuf_alloc();
if (nbuf == NULL) if (nbuf == NULL)
{ {
dbg("%s: could not allocate network buffer\r\n", __FUNCTION__); dbg("could not allocate network buffer\r\n");
return; return;
} }
@@ -102,7 +102,7 @@ void fecbd_init(uint8_t ch)
*/ */
RxBD(ch, i - 1).status |= RX_BD_W; RxBD(ch, i - 1).status |= RX_BD_W;
dbg("%s: initialise TX buffer descriptor ring\r\n", __FUNCTION__); dbg("initialise TX buffer descriptor ring\r\n");
/* /*
* Initialize the Tx Buffer Descriptor ring * Initialize the Tx Buffer Descriptor ring

View File

@@ -7,13 +7,15 @@
* Modifications: * Modifications:
*/ */
#include "net.h" #include "net.h"
#include "bas_printf.h"
#include "bas_string.h"
#include <stdint.h> #include <stdint.h>
#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: " format, ##arg); } while (0) #define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0)
#else #else
#define dbg(format, arg...) do { ; } while (0) #define dbg(format, arg...) do { ; } while (0)
#endif #endif
@@ -42,7 +44,7 @@ uint8_t *ip_get_myip(IP_INFO *info)
{ {
return (uint8_t *) &info->myip[0]; return (uint8_t *) &info->myip[0];
} }
dbg("%s: info is NULL!\n\t", __FUNCTION__); dbg("info is NULL!\n\t");
return 0; return 0;
} }
@@ -72,9 +74,9 @@ uint8_t *ip_resolve_route(NIF *nif, IP_ADDR_P destip)
info = nif_get_protocol_info(nif, ETH_FRM_IP); info = nif_get_protocol_info(nif, ETH_FRM_IP);
if (memcmp(destip, bc) == 0) if (memcmp(destip, bc, 4) == 0)
{ {
dbg("%s: destip is broadcast address, no gateway needed\r\n", __FUNCTION__); dbg("destip is broadcast address, no gateway needed\r\n");
return destip; return destip;
} }
@@ -168,7 +170,7 @@ int ip_send(NIF *nif, uint8_t *dest, uint8_t *src, uint8_t protocol, NBUF *pNbuf
route = ip_resolve_route(nif, dest); route = ip_resolve_route(nif, dest);
if (route == NULL) if (route == NULL)
{ {
dbg("%s: Unable to locate %d.%d.%d.%d\r\n", __FUNCTION__, 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;
} }
@@ -176,9 +178,9 @@ int ip_send(NIF *nif, uint8_t *dest, uint8_t *src, uint8_t protocol, NBUF *pNbuf
else else
{ {
route = bc; route = bc;
dbg("%s: route = broadcast\r\n", __FUNCTION__); dbg("route = broadcast\r\n");
dbg("%s: nif = %p\r\n", __FUNCTION__, nif); dbg("nif = %p\r\n", nif);
dbg("%s: nif->send = %p\r\n", __FUNCTION__, 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);
@@ -280,7 +282,7 @@ void ip_handler(NIF *nif, NBUF *pNbuf)
*/ */
ip_frame_hdr *ipframe; ip_frame_hdr *ipframe;
dbg("%s: packet received\r\n", __FUNCTION__); dbg("packet received\r\n");
ipframe = (ip_frame_hdr *) &pNbuf->data[pNbuf->offset]; ipframe = (ip_frame_hdr *) &pNbuf->data[pNbuf->offset];
@@ -289,6 +291,8 @@ void ip_handler(NIF *nif, NBUF *pNbuf)
*/ */
if (!validate_ip_hdr(nif, ipframe)) if (!validate_ip_hdr(nif, ipframe))
{ {
dbg("not a valid IP packet!\r\n");
nbuf_free(pNbuf); nbuf_free(pNbuf);
return; return;
} }
@@ -308,6 +312,8 @@ void ip_handler(NIF *nif, NBUF *pNbuf)
udp_handler(nif,pNbuf); udp_handler(nif,pNbuf);
break; break;
default: default:
dbg("no protocol handler registered for protocol %d\r\n",
__FUNCTION__, IP_PROTOCOL(ipframe));
nbuf_free(pNbuf); nbuf_free(pNbuf);
break; break;
} }

View File

@@ -24,6 +24,8 @@
#include "firebee.h" #include "firebee.h"
#elif defined(MACHINE_M5484LITE) #elif defined(MACHINE_M5484LITE)
#include "m5484l.h" #include "m5484l.h"
#elif defined(MACHINE_M54455)
#include "m54455.h"
#else #else
#error unknown machine! #error unknown machine!
#endif #endif
@@ -152,8 +154,7 @@ bool timer_init(uint8_t ch, uint8_t lvl, uint8_t pri)
/* /*
* Register the timer interrupt handler * Register the timer interrupt handler
*/ */
if (!isr_register_handler(ISR_DBUG_ISR, if (!isr_register_handler(TIMER_VECTOR(ch),
TIMER_VECTOR(ch),
(int (*)(void *,void *)) timer_default_isr, (int (*)(void *,void *)) timer_default_isr,
NULL, NULL,
(void *) &net_timer[ch]) (void *) &net_timer[ch])

View File

@@ -39,6 +39,7 @@ void udp_init(void)
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 = DEFAULT_UDP_PORT; /* next free port */ udp_port = DEFAULT_UDP_PORT; /* next free port */
@@ -88,7 +89,7 @@ static void *udp_port_handler(uint16_t port)
{ {
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;
@@ -116,7 +117,7 @@ int udp_send(NIF *nif, uint8_t *dest, int sport, int dport, NBUF *pNbuf)
} }
/* /*
* This function takes data and creates a UDP frame 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;

View File

@@ -35,7 +35,7 @@
//#define DEBUG_PCI //#define DEBUG_PCI
#ifdef DEBUG_PCI #ifdef DEBUG_PCI
#define dbg(format, arg...) do { xprintf("DEBUG: " format "", ##arg); } while (0) #define dbg(format, arg...) do { xprintf("DEBUG: " format, __FUNCTION__, ##arg); } while (0)
#else #else
#define dbg(format, arg...) do { ; } while (0) #define dbg(format, arg...) do { ; } while (0)
#endif /* DEBUG_PCI */ #endif /* DEBUG_PCI */
@@ -162,7 +162,7 @@ static int32_t pci_get_interrupt_cause(int32_t *handles)
return handle; return handle;
} }
} }
dbg("%s: no interrupt cause found\r\n", __FUNCTION__); dbg("%s: no interrupt cause found\r\n");
return -1; return -1;
} }
@@ -189,7 +189,7 @@ void irq5_handler(void)
newvalue = pci_call_interrupt_chain(handle, value); newvalue = pci_call_interrupt_chain(handle, value);
if (newvalue == value) if (newvalue == value)
{ {
dbg("%s: interrupt not handled!\r\n", __FUNCTION__); dbg("%s: interrupt not handled!\r\n");
} }
} }
} }
@@ -211,7 +211,7 @@ void irq7_handler(void)
newvalue = pci_call_interrupt_chain(handle, value); newvalue = pci_call_interrupt_chain(handle, value);
if (newvalue == value) if (newvalue == value)
{ {
dbg("%s: interrupt not handled!\r\n", __FUNCTION__); dbg("%s: interrupt not handled!\r\n");
} }
} }
} }
@@ -810,7 +810,7 @@ static void pci_device_config(uint16_t bus, uint16_t device, uint16_t function)
*/ */
struct pci_rd *rd = &descriptors[barnum]; struct pci_rd *rd = &descriptors[barnum];
dbg("%s: address = %08x\r\n", __FUNCTION__, address); dbg("%s: address = %08x\r\n", address);
if (IS_PCI_MEM_BAR(address)) if (IS_PCI_MEM_BAR(address))
{ {
/* adjust base address to card's alignment requirements */ /* adjust base address to card's alignment requirements */
@@ -899,10 +899,10 @@ static void pci_device_config(uint16_t bus, uint16_t device, uint16_t function)
/* write it to PCIERBAR and enable ROM */ /* write it to PCIERBAR and enable ROM */
pci_write_config_longword(handle, PCIERBAR, swpl(address | 1)); pci_write_config_longword(handle, PCIERBAR, swpl(address | 1));
dbg("%s: set PCIERBAR on device 0x%02x to 0x%08x\r\n", __FUNCTION__, handle, address | 1); dbg("%s: set PCIERBAR on device 0x%02x to 0x%08x\r\n", handle, address | 1);
/* read value back just to be sure */ /* read value back just to be sure */
dbg("%s: PCIERBAR = %p\r\n", __FUNCTION__, swpl(pci_read_config_longword(handle, PCIERBAR))); dbg("%s: PCIERBAR = %p\r\n", swpl(pci_read_config_longword(handle, PCIERBAR)));
rd->next = sizeof(struct pci_rd); rd->next = sizeof(struct pci_rd);

View File

@@ -74,7 +74,15 @@ extern void run_bios(struct radeonfb_info *rinfo);
#define MIN_MAPPED_VRAM (1024*768*4) #define MIN_MAPPED_VRAM (1024*768*4)
#define CHIP_DEF(id, family, flags) \ #define CHIP_DEF(id, family, flags) \
{ PCI_VENDOR_ID_ATI, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (flags) | (CHIP_FAMILY_##family) } { \
PCI_VENDOR_ID_ATI, \
id, \
PCI_ANY_ID, \
PCI_ANY_ID, \
0, \
0, \
(flags) | (CHIP_FAMILY_##family) \
}
struct pci_device_id radeonfb_pci_table[] = struct pci_device_id radeonfb_pci_table[] =
{ {
@@ -231,7 +239,7 @@ extern struct fb_info *info_fb;
#define rinfo ((struct radeonfb_info *) info_fb->par) #define rinfo ((struct radeonfb_info *) info_fb->par)
static uint32_t inreg(uint32_t addr) static uint32_t inreg(uint32_t addr)
{ {
return(INREG(addr)); return INREG(addr);
} }
static void outreg(uint32_t addr, uint32_t val) static void outreg(uint32_t addr, uint32_t val)
@@ -332,12 +340,10 @@ static int round_div(int num, int den)
return(num + (den / 2)) / den; return(num + (den / 2)) / den;
} }
#ifndef MCF5445X
static uint32_t read_vline_crnt(struct radeonfb_info *rinfo) static uint32_t read_vline_crnt(struct radeonfb_info *rinfo)
{ {
return((INREG(CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3FF); return((INREG(CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3FF);
} }
#endif
static int radeon_map_ROM(struct radeonfb_info *rinfo) static int radeon_map_ROM(struct radeonfb_info *rinfo)
{ {
@@ -510,10 +516,12 @@ static int radeon_probe_pll_params(struct radeonfb_info *rinfo)
hz = US_TO_TIMER(1000000.0) / (double)(stop_tv - start_tv); hz = US_TO_TIMER(1000000.0) / (double)(stop_tv - start_tv);
dbg("%s:hz %d\r\n", __FUNCTION__, (int32_t) hz); dbg("%s:hz %d\r\n", __FUNCTION__, (int32_t) hz);
hTotal = ((INREG(CRTC_H_TOTAL_DISP) & 0x1ff) + 1) * 8; hTotal = ((INREG(CRTC_H_TOTAL_DISP) & 0x1ff) + 1) * 8;
vTotal = ((INREG(CRTC_V_TOTAL_DISP) & 0x3ff) + 1); vTotal = ((INREG(CRTC_V_TOTAL_DISP) & 0x3ff) + 1);
dbg("%s:hTotal=%d\r\n", __FUNCTION__, hTotal); dbg("%s:hTotal=%d\r\n", __FUNCTION__, hTotal);
dbg("%s:vTotal=%d\r\n", __FUNCTION__, vTotal); dbg("%s:vTotal=%d\r\n", __FUNCTION__, vTotal);
vclk = (double) hTotal * (double) vTotal * hz; vclk = (double) hTotal * (double) vTotal * hz;
dbg("%s:vclk=%d\r\n", __FUNCTION__, (int) vclk); dbg("%s:vclk=%d\r\n", __FUNCTION__, (int) vclk);
@@ -525,41 +533,52 @@ static int radeon_probe_pll_params(struct radeonfb_info *rinfo)
num = 2 * n; num = 2 * n;
denom = 2 * m; denom = 2 * m;
break; break;
case 2: case 2:
n = ((INPLL(M_SPLL_REF_FB_DIV) >> 8) & 0xff); n = ((INPLL(M_SPLL_REF_FB_DIV) >> 8) & 0xff);
m = (INPLL(M_SPLL_REF_FB_DIV) & 0xff); m = (INPLL(M_SPLL_REF_FB_DIV) & 0xff);
num = 2 * n; num = 2 * n;
denom = 2 * m; denom = 2 * m;
break; break;
case 0: case 0:
default: default:
num = 1; num = 1;
denom = 1; denom = 1;
break; break;
} }
ppll_div_sel = INREG8(CLOCK_CNTL_INDEX + 1) & 0x3; ppll_div_sel = INREG8(CLOCK_CNTL_INDEX + 1) & 0x3;
radeon_pll_errata_after_index(rinfo); radeon_pll_errata_after_index(rinfo);
n = (INPLL(PPLL_DIV_0 + ppll_div_sel) & 0x7ff); n = (INPLL(PPLL_DIV_0 + ppll_div_sel) & 0x7ff);
m = (INPLL(PPLL_REF_DIV) & 0x3ff); m = (INPLL(PPLL_REF_DIV) & 0x3ff);
num *= n; num *= n;
denom *= m; denom *= m;
switch((INPLL(PPLL_DIV_0 + ppll_div_sel) >> 16) & 0x7) switch((INPLL(PPLL_DIV_0 + ppll_div_sel) >> 16) & 0x7)
{ {
case 1: case 1:
denom *= 2; denom *= 2;
break; break;
case 2: case 2:
denom *= 4; denom *= 4;
break; break;
case 3: case 3:
denom *= 8; denom *= 8;
break; break;
case 4: case 4:
denom *= 3; denom *= 3;
break; break;
case 6: case 6:
denom *= 6; denom *= 6;
break; break;
case 7: case 7:
denom *= 12; denom *= 12;
break; break;
@@ -567,6 +586,7 @@ static int radeon_probe_pll_params(struct radeonfb_info *rinfo)
vclk *= (double) denom; vclk *= (double) denom;
vclk /= (double) (1000 * num); vclk /= (double) (1000 * num);
xtal = (int32_t) vclk; xtal = (int32_t) vclk;
if ((xtal > 26900) && (xtal < 27100)) if ((xtal > 26900) && (xtal < 27100))
xtal = 2700; /* 27 MHz */ xtal = 2700; /* 27 MHz */
else if ((xtal > 14200) && (xtal < 14400)) else if ((xtal > 14200) && (xtal < 14400))
@@ -578,6 +598,7 @@ static int radeon_probe_pll_params(struct radeonfb_info *rinfo)
dbg("%s: xtal calculation failed: %d\r\n", __FUNCTION__, xtal); dbg("%s: xtal calculation failed: %d\r\n", __FUNCTION__, xtal);
return -1; /* error */ return -1; /* error */
} }
tmp = INPLL(M_SPLL_REF_FB_DIV); tmp = INPLL(M_SPLL_REF_FB_DIV);
ref_div = INPLL(PPLL_REF_DIV) & 0x3ff; ref_div = INPLL(PPLL_REF_DIV) & 0x3ff;
@@ -619,6 +640,7 @@ static void radeon_get_pllinfo(struct radeonfb_info *rinfo)
rinfo->pll.sclk = 23000; rinfo->pll.sclk = 23000;
rinfo->pll.ref_clk = 2700; rinfo->pll.ref_clk = 2700;
break; break;
case PCI_DEVICE_ID_ATI_RADEON_QL: case PCI_DEVICE_ID_ATI_RADEON_QL:
case PCI_DEVICE_ID_ATI_RADEON_QN: case PCI_DEVICE_ID_ATI_RADEON_QN:
case PCI_DEVICE_ID_ATI_RADEON_QO: case PCI_DEVICE_ID_ATI_RADEON_QO:
@@ -630,6 +652,7 @@ static void radeon_get_pllinfo(struct radeonfb_info *rinfo)
rinfo->pll.sclk = 27500; rinfo->pll.sclk = 27500;
rinfo->pll.ref_clk = 2700; rinfo->pll.ref_clk = 2700;
break; break;
case PCI_DEVICE_ID_ATI_RADEON_Id: case PCI_DEVICE_ID_ATI_RADEON_Id:
case PCI_DEVICE_ID_ATI_RADEON_Ie: case PCI_DEVICE_ID_ATI_RADEON_Ie:
case PCI_DEVICE_ID_ATI_RADEON_If: case PCI_DEVICE_ID_ATI_RADEON_If:
@@ -640,6 +663,7 @@ static void radeon_get_pllinfo(struct radeonfb_info *rinfo)
rinfo->pll.sclk = 25000; rinfo->pll.sclk = 25000;
rinfo->pll.ref_clk = 2700; rinfo->pll.ref_clk = 2700;
break; break;
case PCI_DEVICE_ID_ATI_RADEON_ND: case PCI_DEVICE_ID_ATI_RADEON_ND:
case PCI_DEVICE_ID_ATI_RADEON_NE: case PCI_DEVICE_ID_ATI_RADEON_NE:
case PCI_DEVICE_ID_ATI_RADEON_NF: case PCI_DEVICE_ID_ATI_RADEON_NF:
@@ -650,6 +674,7 @@ static void radeon_get_pllinfo(struct radeonfb_info *rinfo)
rinfo->pll.sclk = 27000; rinfo->pll.sclk = 27000;
rinfo->pll.ref_clk = 2700; rinfo->pll.ref_clk = 2700;
break; break;
case PCI_DEVICE_ID_ATI_RADEON_QD: case PCI_DEVICE_ID_ATI_RADEON_QD:
case PCI_DEVICE_ID_ATI_RADEON_QE: case PCI_DEVICE_ID_ATI_RADEON_QE:
case PCI_DEVICE_ID_ATI_RADEON_QF: case PCI_DEVICE_ID_ATI_RADEON_QF:
@@ -690,10 +715,12 @@ static void radeon_get_pllinfo(struct radeonfb_info *rinfo)
dbg("%s: Retreived PLL infos from registers\r\n", __FUNCTION__); dbg("%s: Retreived PLL infos from registers\r\n", __FUNCTION__);
goto found; goto found;
} }
/* /*
* Fall back to already-set defaults... * Fall back to already-set defaults...
*/ */
dbg("%s: Used default PLL infos\r\n", __FUNCTION__); dbg("%s: Used default PLL infos\r\n", __FUNCTION__);
found: found:
/* /*
* Some methods fail to retreive SCLK and MCLK values, we apply default * Some methods fail to retreive SCLK and MCLK values, we apply default
@@ -707,13 +734,15 @@ found:
dbg("%s: Reference=%d MHz (RefDiv=0x%x) Memory=%d MHz\r\n", __FUNCTION__, dbg("%s: Reference=%d MHz (RefDiv=0x%x) Memory=%d MHz\r\n", __FUNCTION__,
rinfo->pll.ref_clk / 100, rinfo->pll.ref_div, rinfo->pll.mclk / 100); rinfo->pll.ref_clk / 100, rinfo->pll.ref_div, rinfo->pll.mclk / 100);
dbg("%s: System=%d MHz PLL min %d, max %d\r\n", __FUNCTION__, rinfo->pll.sclk / 100, rinfo->pll.ppll_min, rinfo->pll.ppll_max); dbg("%s: System=%d MHz PLL min %d, max %d\r\n", __FUNCTION__,
rinfo->pll.sclk / 100, rinfo->pll.ppll_min, rinfo->pll.ppll_max);
} }
static int var_to_depth(const struct fb_var_screeninfo *var) static int var_to_depth(const struct fb_var_screeninfo *var)
{ {
if (var->bits_per_pixel != 16) if (var->bits_per_pixel != 16)
return var->bits_per_pixel; return var->bits_per_pixel;
return(var->green.length == 5) ? 15 : 16; return(var->green.length == 5) ? 15 : 16;
} }
@@ -723,6 +752,7 @@ int radeonfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
struct fb_var_screeninfo v; struct fb_var_screeninfo v;
int nom, den; int nom, den;
uint32_t pitch; uint32_t pitch;
dbg("%s:\r\n", __FUNCTION__); dbg("%s:\r\n", __FUNCTION__);
/* clocks over 135 MHz have heat isues with DVI on RV100 */ /* clocks over 135 MHz have heat isues with DVI on RV100 */
@@ -742,9 +772,11 @@ int radeonfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
case 0 ... 8: case 0 ... 8:
v.bits_per_pixel = 8; v.bits_per_pixel = 8;
break; break;
case 9 ... 16: case 9 ... 16:
v.bits_per_pixel = 16; v.bits_per_pixel = 16;
break; break;
#if 0 /* Doesn't seem to work */ #if 0 /* Doesn't seem to work */
case 17 ... 24: case 17 ... 24:
v.bits_per_pixel = 24; v.bits_per_pixel = 24;
@@ -753,6 +785,7 @@ int radeonfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
case 25 ... 32: case 25 ... 32:
v.bits_per_pixel = 32; v.bits_per_pixel = 32;
break; break;
default: default:
return -1; //-EINVAL; return -1; //-EINVAL;
} }
@@ -765,6 +798,7 @@ int radeonfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
v.red.length = v.green.length = v.blue.length = 8; v.red.length = v.green.length = v.blue.length = 8;
v.transp.offset = v.transp.length = 0; v.transp.offset = v.transp.length = 0;
break; break;
case 15: case 15:
nom = 2; nom = 2;
den = 1; den = 1;
@@ -774,6 +808,7 @@ int radeonfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
v.red.length = v.green.length = v.blue.length = 5; v.red.length = v.green.length = v.blue.length = 5;
v.transp.offset = v.transp.length = 0; v.transp.offset = v.transp.length = 0;
break; break;
case 16: case 16:
nom = 2; nom = 2;
den = 1; den = 1;
@@ -785,6 +820,7 @@ int radeonfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
v.blue.length = 5; v.blue.length = 5;
v.transp.offset = v.transp.length = 0; v.transp.offset = v.transp.length = 0;
break; break;
case 24: case 24:
nom = 4; nom = 4;
den = 1; den = 1;
@@ -794,6 +830,7 @@ int radeonfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
v.red.length = v.blue.length = v.green.length = 8; v.red.length = v.blue.length = v.green.length = 8;
v.transp.offset = v.transp.length = 0; v.transp.offset = v.transp.length = 0;
break; break;
case 32: case 32:
nom = 4; nom = 4;
den = 1; den = 1;
@@ -804,6 +841,7 @@ int radeonfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
v.transp.offset = 24; v.transp.offset = 24;
v.transp.length = 8; v.transp.length = 8;
break; break;
default: default:
dbg("radeonfb: mode %d x %d x %d rejected, color depth invalid\r\n ", dbg("radeonfb: mode %d x %d x %d rejected, color depth invalid\r\n ",
var->xres, var->yres, var->bits_per_pixel); var->xres, var->yres, var->bits_per_pixel);
@@ -814,6 +852,7 @@ int radeonfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
v.yres_virtual = v.yres; v.yres_virtual = v.yres;
if (v.xres_virtual < v.xres) if (v.xres_virtual < v.xres)
v.xres_virtual = v.xres; v.xres_virtual = v.xres;
/* /*
* XXX I'm adjusting xres_virtual to the pitch, that may help XFree * XXX I'm adjusting xres_virtual to the pitch, that may help XFree
* with some panels, though I don't quite like this solution * with some panels, though I don't quite like this solution
@@ -848,6 +887,7 @@ int radeonfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
dbg("%s: using mode %d x %d \r\n", __FUNCTION__, v.xres, v.yres); dbg("%s: using mode %d x %d \r\n", __FUNCTION__, v.xres, v.yres);
memcpy(var, &v, sizeof(v)); memcpy(var, &v, sizeof(v));
return 0; return 0;
} }
@@ -857,16 +897,20 @@ int radeonfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
// DPRINT("radeonfb: radeonfb_pan_display\r\n"); // DPRINT("radeonfb: radeonfb_pan_display\r\n");
if ((var->xoffset + var->xres) > var->xres_virtual) if ((var->xoffset + var->xres) > var->xres_virtual)
return -1; //-EINVAL; return -1; //-EINVAL;
if (((var->yoffset * var->xres_virtual) + var->xoffset) >= if (((var->yoffset * var->xres_virtual) + var->xoffset) >=
(rinfo->mapped_vram - (var->yres * var->xres * (var->bits_per_pixel / 8)))) (rinfo->mapped_vram - (var->yres * var->xres * (var->bits_per_pixel / 8))))
return -1; //-EINVAL; return -1; //-EINVAL;
if (rinfo->asleep) if (rinfo->asleep)
return 0; return 0;
radeon_wait_for_fifo(rinfo, 2); radeon_wait_for_fifo(rinfo, 2);
rinfo->fb_offset = ((var->yoffset * var->xres_virtual + var->xoffset) * var->bits_per_pixel / 8) & ~7; rinfo->fb_offset = ((var->yoffset * var->xres_virtual + var->xoffset) * var->bits_per_pixel / 8) & ~7;
rinfo->dst_pitch_offset = (rinfo->pitch << 22) | ((rinfo->fb_local_base + rinfo->fb_offset) >> 10); rinfo->dst_pitch_offset = (rinfo->pitch << 22) | ((rinfo->fb_local_base + rinfo->fb_offset) >> 10);
OUTREG(CRTC_OFFSET, rinfo->fb_offset); OUTREG(CRTC_OFFSET, rinfo->fb_offset);
return 0;
return 0;
} }
short mirror; short mirror;
@@ -876,6 +920,7 @@ int radeonfb_ioctl(unsigned int cmd, unsigned long arg, struct fb_info *info)
struct radeonfb_info *rinfo = info->par; struct radeonfb_info *rinfo = info->par;
uint32_t tmp; uint32_t tmp;
uint32_t value = 0; uint32_t value = 0;
switch(cmd) switch(cmd)
{ {
/* /*
@@ -899,6 +944,7 @@ int radeonfb_ioctl(unsigned int cmd, unsigned long arg, struct fb_info *info)
tmp &= ~(LVDS_ON | LVDS_BLON); tmp &= ~(LVDS_ON | LVDS_BLON);
} }
OUTREG(LVDS_GEN_CNTL, tmp); OUTREG(LVDS_GEN_CNTL, tmp);
if (value & 0x02) if (value & 0x02)
{ {
tmp = INREG(CRTC_EXT_CNTL); tmp = INREG(CRTC_EXT_CNTL);
@@ -913,6 +959,7 @@ int radeonfb_ioctl(unsigned int cmd, unsigned long arg, struct fb_info *info)
} }
OUTREG(CRTC_EXT_CNTL, tmp); OUTREG(CRTC_EXT_CNTL, tmp);
return 0; return 0;
case FBIO_RADEON_GET_MIRROR: case FBIO_RADEON_GET_MIRROR:
if (!rinfo->is_mobility) if (!rinfo->is_mobility)
return -1; //-EINVAL; return -1; //-EINVAL;
@@ -923,6 +970,7 @@ int radeonfb_ioctl(unsigned int cmd, unsigned long arg, struct fb_info *info)
if (CRTC_CRT_ON & tmp) if (CRTC_CRT_ON & tmp)
value |= 0x02; value |= 0x02;
return 0; return 0;
default: default:
return -1; //-EINVAL; return -1; //-EINVAL;
} }
@@ -937,24 +985,30 @@ int32_t radeon_screen_blank(struct radeonfb_info *rinfo, int32_t blank, int32_t
if (rinfo->lock_blank) if (rinfo->lock_blank)
return 0; return 0;
dbg("radeonfb: radeon_screen_blank\r\n"); dbg("radeonfb: radeon_screen_blank\r\n");
radeon_engine_idle(); radeon_engine_idle();
val = INREG(CRTC_EXT_CNTL); val = INREG(CRTC_EXT_CNTL);
val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS | CRTC_VSYNC_DIS); val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS | CRTC_VSYNC_DIS);
switch(blank) switch(blank)
{ {
case FB_BLANK_VSYNC_SUSPEND: case FB_BLANK_VSYNC_SUSPEND:
val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS); val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS);
break; break;
case FB_BLANK_HSYNC_SUSPEND: case FB_BLANK_HSYNC_SUSPEND:
val |= (CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS); val |= (CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS);
break; break;
case FB_BLANK_POWERDOWN: case FB_BLANK_POWERDOWN:
val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS | CRTC_HSYNC_DIS); val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS | CRTC_HSYNC_DIS);
break; break;
case FB_BLANK_NORMAL: case FB_BLANK_NORMAL:
val |= CRTC_DISPLAY_DIS; val |= CRTC_DISPLAY_DIS;
break; break;
case FB_BLANK_UNBLANK: case FB_BLANK_UNBLANK:
default: default:
unblank = 1; unblank = 1;
@@ -974,6 +1028,7 @@ int32_t radeon_screen_blank(struct radeonfb_info *rinfo, int32_t blank, int32_t
OUTREGP(FP_GEN_CNTL, 0, ~(FP_FPON | FP_TMDS_EN)); OUTREGP(FP_GEN_CNTL, 0, ~(FP_FPON | FP_TMDS_EN));
} }
break; break;
case MT_LCD: case MT_LCD:
rinfo->lvds_timer = 0; rinfo->lvds_timer = 0;
val = INREG(LVDS_GEN_CNTL); val = INREG(LVDS_GEN_CNTL);
@@ -1007,15 +1062,19 @@ int32_t radeon_screen_blank(struct radeonfb_info *rinfo, int32_t blank, int32_t
/* We don't do a full switch-off on a simple mode switch */ /* We don't do a full switch-off on a simple mode switch */
if (mode_switch || blank == FB_BLANK_NORMAL) if (mode_switch || blank == FB_BLANK_NORMAL)
break; break;
/* Asic bug, when turning off LVDS_ON, we have to make sure /* Asic bug, when turning off LVDS_ON, we have to make sure
* RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off * RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
*/ */
tmp_pix_clks = INPLL(PIXCLKS_CNTL); tmp_pix_clks = INPLL(PIXCLKS_CNTL);
if (rinfo->is_mobility || rinfo->is_IGP) if (rinfo->is_mobility || rinfo->is_IGP)
OUTPLLP(PIXCLKS_CNTL, 0, ~PIXCLK_LVDS_ALWAYS_ONb); OUTPLLP(PIXCLKS_CNTL, 0, ~PIXCLK_LVDS_ALWAYS_ONb);
val &= ~(LVDS_BL_MOD_EN); val &= ~(LVDS_BL_MOD_EN);
OUTREG(LVDS_GEN_CNTL, val); OUTREG(LVDS_GEN_CNTL, val);
wait(100); wait(100);
val &= ~(LVDS_ON | LVDS_EN); val &= ~(LVDS_ON | LVDS_EN);
OUTREG(LVDS_GEN_CNTL, val); OUTREG(LVDS_GEN_CNTL, val);
val &= ~LVDS_DIGON; val &= ~LVDS_DIGON;
@@ -1023,6 +1082,7 @@ int32_t radeon_screen_blank(struct radeonfb_info *rinfo, int32_t blank, int32_t
rinfo->lvds_timer = (int32_t)rinfo->panel_info.pwr_delay; rinfo->lvds_timer = (int32_t)rinfo->panel_info.pwr_delay;
rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK; rinfo->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK;
rinfo->init_state.lvds_gen_cntl |= val & LVDS_STATE_MASK; rinfo->init_state.lvds_gen_cntl |= val & LVDS_STATE_MASK;
if (rinfo->is_mobility || rinfo->is_IGP) if (rinfo->is_mobility || rinfo->is_IGP)
OUTPLL(PIXCLKS_CNTL, tmp_pix_clks); OUTPLL(PIXCLKS_CNTL, tmp_pix_clks);
} }
@@ -1039,8 +1099,10 @@ int32_t radeon_screen_blank(struct radeonfb_info *rinfo, int32_t blank, int32_t
int radeonfb_blank(int blank, struct fb_info *info) int radeonfb_blank(int blank, struct fb_info *info)
{ {
struct radeonfb_info *rinfo = info->par; struct radeonfb_info *rinfo = info->par;
if (rinfo->asleep) if (rinfo->asleep)
return 0; return 0;
return radeon_screen_blank(rinfo, blank, 0); return radeon_screen_blank(rinfo, blank, 0);
} }
@@ -1049,14 +1111,18 @@ static int radeon_setcolreg(unsigned regno, unsigned red, unsigned green,
{ {
struct radeonfb_info *rinfo = info->par; struct radeonfb_info *rinfo = info->par;
uint32_t pindex; uint32_t pindex;
if (regno > 255) if (regno > 255)
return 1; return 1;
red >>= 8; red >>= 8;
green >>= 8; green >>= 8;
blue >>= 8; blue >>= 8;
rinfo->palette[regno].red = red; rinfo->palette[regno].red = red;
rinfo->palette[regno].green = green; rinfo->palette[regno].green = green;
rinfo->palette[regno].blue = blue; rinfo->palette[regno].blue = blue;
/* default */ /* default */
pindex = regno; pindex = regno;
if (!rinfo->asleep) if (!rinfo->asleep)
@@ -1069,7 +1135,9 @@ static int radeon_setcolreg(unsigned regno, unsigned red, unsigned green,
return 1; return 1;
if (rinfo->depth == 15 && regno > 31) if (rinfo->depth == 15 && regno > 31)
return 1; return 1;
/* For 565, the green component is mixed one order
/*
* For 565, the green component is mixed one order
* below * below
*/ */
if (rinfo->depth == 16) if (rinfo->depth == 16)
@@ -1095,6 +1163,7 @@ int radeonfb_setcolreg(unsigned regno, unsigned red, unsigned green,
struct radeonfb_info *rinfo = info->par; struct radeonfb_info *rinfo = info->par;
uint32_t dac_cntl2, vclk_cntl = 0; uint32_t dac_cntl2, vclk_cntl = 0;
int rc; int rc;
if (!rinfo->asleep) if (!rinfo->asleep)
{ {
if (rinfo->is_mobility) if (rinfo->is_mobility)
@@ -1102,6 +1171,7 @@ int radeonfb_setcolreg(unsigned regno, unsigned red, unsigned green,
vclk_cntl = INPLL(VCLK_ECP_CNTL); vclk_cntl = INPLL(VCLK_ECP_CNTL);
OUTPLL(VCLK_ECP_CNTL, vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb); OUTPLL(VCLK_ECP_CNTL, vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb);
} }
/* Make sure we are on first palette */ /* Make sure we are on first palette */
if (rinfo->has_CRTC2) if (rinfo->has_CRTC2)
{ {
@@ -1113,6 +1183,7 @@ int radeonfb_setcolreg(unsigned regno, unsigned red, unsigned green,
rc = radeon_setcolreg(regno, red, green, blue, transp, info); rc = radeon_setcolreg(regno, red, green, blue, transp, info);
if (!rinfo->asleep && rinfo->is_mobility) if (!rinfo->asleep && rinfo->is_mobility)
OUTPLL(VCLK_ECP_CNTL, vclk_cntl); OUTPLL(VCLK_ECP_CNTL, vclk_cntl);
return rc; return rc;
} }
@@ -1129,6 +1200,7 @@ static void radeon_save_state(struct radeonfb_info *rinfo, struct radeon_regs *s
save->crtc_v_sync_strt_wid = INREG(CRTC_V_SYNC_STRT_WID); save->crtc_v_sync_strt_wid = INREG(CRTC_V_SYNC_STRT_WID);
save->crtc_pitch = INREG(CRTC_PITCH); save->crtc_pitch = INREG(CRTC_PITCH);
save->surface_cntl = INREG(SURFACE_CNTL); save->surface_cntl = INREG(SURFACE_CNTL);
/* FP regs */ /* FP regs */
save->fp_crtc_h_total_disp = INREG(FP_CRTC_H_TOTAL_DISP); save->fp_crtc_h_total_disp = INREG(FP_CRTC_H_TOTAL_DISP);
save->fp_crtc_v_total_disp = INREG(FP_CRTC_V_TOTAL_DISP); save->fp_crtc_v_total_disp = INREG(FP_CRTC_V_TOTAL_DISP);
@@ -1143,6 +1215,7 @@ static void radeon_save_state(struct radeonfb_info *rinfo, struct radeon_regs *s
save->tmds_transmitter_cntl = INREG(TMDS_TRANSMITTER_CNTL); save->tmds_transmitter_cntl = INREG(TMDS_TRANSMITTER_CNTL);
save->vclk_ecp_cntl = INPLL(VCLK_ECP_CNTL); save->vclk_ecp_cntl = INPLL(VCLK_ECP_CNTL);
/* PLL regs */ /* PLL regs */
save->clk_cntl_index = INREG(CLOCK_CNTL_INDEX) & ~0x3f; save->clk_cntl_index = INREG(CLOCK_CNTL_INDEX) & ~0x3f;
radeon_pll_errata_after_index(rinfo); radeon_pll_errata_after_index(rinfo);
save->ppll_div_3 = INPLL(PPLL_DIV_3); save->ppll_div_3 = INPLL(PPLL_DIV_3);
@@ -1152,8 +1225,10 @@ static void radeon_save_state(struct radeonfb_info *rinfo, struct radeon_regs *s
static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *mode) static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *mode)
{ {
int i; int i;
dbg("radeonfb: radeon_write_pll_regs\r\n"); dbg("radeonfb: radeon_write_pll_regs\r\n");
radeon_wait_for_fifo(rinfo, 20); radeon_wait_for_fifo(rinfo, 20);
#if 0 #if 0
/* Workaround from XFree */ /* Workaround from XFree */
if (rinfo->is_mobility) if (rinfo->is_mobility)
@@ -1180,22 +1255,27 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg
} }
} }
#endif #endif
/* Swich VCKL clock input to CPUCLK so it stays fed while PPLL updates*/ /* Swich VCKL clock input to CPUCLK so it stays fed while PPLL updates*/
OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_CPUCLK, ~VCLK_SRC_SEL_MASK); OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_CPUCLK, ~VCLK_SRC_SEL_MASK);
/* Reset PPLL & enable atomic update */ /* Reset PPLL & enable atomic update */
OUTPLLP(PPLL_CNTL, PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN, OUTPLLP(PPLL_CNTL, PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN,
~(PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN)); ~(PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN));
/* Switch to selected PPLL divider */ /* Switch to selected PPLL divider */
OUTREGP(CLOCK_CNTL_INDEX, mode->clk_cntl_index & PPLL_DIV_SEL_MASK, ~PPLL_DIV_SEL_MASK); OUTREGP(CLOCK_CNTL_INDEX, mode->clk_cntl_index & PPLL_DIV_SEL_MASK, ~PPLL_DIV_SEL_MASK);
radeon_pll_errata_after_index(rinfo); radeon_pll_errata_after_index(rinfo);
radeon_pll_errata_after_data(rinfo); radeon_pll_errata_after_data(rinfo);
/* Set PPLL ref. div */ /* Set PPLL ref. div */
if (rinfo->family == CHIP_FAMILY_R300 || rinfo->family == CHIP_FAMILY_RS300 if (rinfo->family == CHIP_FAMILY_R300 || rinfo->family == CHIP_FAMILY_RS300
|| rinfo->family == CHIP_FAMILY_R350 || rinfo->family == CHIP_FAMILY_RV350) || rinfo->family == CHIP_FAMILY_R350 || rinfo->family == CHIP_FAMILY_RV350)
{ {
if (mode->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) if (mode->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK)
{ {
/* When restoring console mode, use saved PPLL_REF_DIV /*
* When restoring console mode, use saved PPLL_REF_DIV
* setting. * setting.
*/ */
OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, 0); OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, 0);
@@ -1216,17 +1296,22 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg
/* Write update */ /* Write update */
while (INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R); while (INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R);
OUTPLLP(PPLL_REF_DIV, PPLL_ATOMIC_UPDATE_W, ~PPLL_ATOMIC_UPDATE_W); OUTPLLP(PPLL_REF_DIV, PPLL_ATOMIC_UPDATE_W, ~PPLL_ATOMIC_UPDATE_W);
/* Wait read update complete */ /* Wait read update complete */
/* FIXME: Certain revisions of R300 can't recover here. Not sure of /* FIXME: Certain revisions of R300 can't recover here. Not sure of
the cause yet, but this workaround will mask the problem for now. the cause yet, but this workaround will mask the problem for now.
Other chips usually will pass at the very first test, so the Other chips usually will pass at the very first test, so the
workaround shouldn't have any effect on them. */ workaround shouldn't have any effect on them. */
for(i = 0; (i < 10000 && INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R); i++);
for (i = 0; (i < 10000 && INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R); i++);
OUTPLL(HTOTAL_CNTL, 0); OUTPLL(HTOTAL_CNTL, 0);
/* Clear reset & atomic update */ /* Clear reset & atomic update */
OUTPLLP(PPLL_CNTL, 0, ~(PPLL_RESET | PPLL_SLEEP | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN)); OUTPLLP(PPLL_CNTL, 0, ~(PPLL_RESET | PPLL_SLEEP | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN));
/* We may want some locking ... oh well */ /* We may want some locking ... oh well */
radeon_msleep(5); radeon_msleep(5);
/* Switch back VCLK source to PPLL */ /* Switch back VCLK source to PPLL */
OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_PPLLCLK, ~VCLK_SRC_SEL_MASK); OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_PPLLCLK, ~VCLK_SRC_SEL_MASK);
} }
@@ -1248,6 +1333,7 @@ static void radeon_timer_func(void)
#ifdef FIXME_LATER #ifdef FIXME_LATER
static int32_t start_timer; static int32_t start_timer;
/* delayed LVDS panel power up/down */ /* delayed LVDS panel power up/down */
if (rinfo->lvds_timer) if (rinfo->lvds_timer)
{ {
@@ -1263,10 +1349,11 @@ static void radeon_timer_func(void)
} }
else else
start_timer = 0; start_timer = 0;
#endif #endif /* FIXME_LATER */
if (rinfo->RenderCallback != NULL) if (rinfo->RenderCallback != NULL)
rinfo->RenderCallback(rinfo); rinfo->RenderCallback(rinfo);
if ((info->screen_mono != NULL) && info->update_mono) if ((info->screen_mono != NULL) && info->update_mono)
{ {
int32_t foreground = 255, background = 0; int32_t foreground = 255, background = 0;
@@ -1275,21 +1362,25 @@ static void radeon_timer_func(void)
int dst_x = 0; int dst_x = 0;
int w = (int)info->var.xres_virtual; int w = (int)info->var.xres_virtual;
int h = (int)info->var.yres_virtual; int h = (int)info->var.yres_virtual;
// info->fbops->SetClippingRectangle(info,0,0,w-1,h-1); // info->fbops->SetClippingRectangle(info,0,0,w-1,h-1);
src_buf = (uint8_t*)((int32_t)src_buf & ~3); src_buf = (uint8_t*)((int32_t)src_buf & ~3);
dst_x -= (int32_t)skipleft; dst_x -= (int32_t)skipleft;
w += (int32_t)skipleft; w += (int32_t)skipleft;
info->fbops->SetupForScanlineCPUToScreenColorExpandFill(info,(int)foreground,(int)background,3,0xffffffff); info->fbops->SetupForScanlineCPUToScreenColorExpandFill(info,(int)foreground,(int)background,3,0xffffffff);
info->fbops->SubsequentScanlineCPUToScreenColorExpandFill(info,(int)dst_x,0,w,h,skipleft); info->fbops->SubsequentScanlineCPUToScreenColorExpandFill(info,(int)dst_x,0,w,h,skipleft);
while (--h >= 0) while (--h >= 0)
{ {
info->fbops->SubsequentScanline(info, (unsigned long *) src_buf); info->fbops->SubsequentScanline(info, (unsigned long *) src_buf);
src_buf += (info->var.xres_virtual >> 3); src_buf += (info->var.xres_virtual >> 3);
} }
// info->fbops->DisableClipping(info); // info->fbops->DisableClipping(info);
if (info->update_mono > 0) if (info->update_mono > 0)
info->update_mono = 0; info->update_mono = 0;
} }
if ((info->var.xres_virtual != info->var.xres) if ((info->var.xres_virtual != info->var.xres)
|| (info->var.yres_virtual != info->var.yres)) || (info->var.yres_virtual != info->var.yres))
{ {
@@ -1310,6 +1401,7 @@ static void radeon_timer_func(void)
x -= 8; x -= 8;
chg = 1; chg = 1;
} }
if (((y + info->var.yres) < info->var.yres_virtual) && (rinfo->cursor_y >= (info->var.yres - 8))) if (((y + info->var.yres) < info->var.yres_virtual) && (rinfo->cursor_y >= (info->var.yres - 8)))
{ {
y += 8; y += 8;
@@ -1329,7 +1421,9 @@ static void radeon_timer_func(void)
disp = rinfo->cursor_show; disp = rinfo->cursor_show;
if (disp) if (disp)
info->fbops->HideCursor(info); info->fbops->HideCursor(info);
fb_pan_display(info,&var); fb_pan_display(info,&var);
if (disp) if (disp)
info->fbops->ShowCursor(info); info->fbops->ShowCursor(info);
} }
@@ -1345,14 +1439,19 @@ void radeon_write_mode(struct radeonfb_info *rinfo, struct radeon_regs *mode, in
{ {
int i; int i;
int primary_mon = PRIMARY_MONITOR(rinfo); int primary_mon = PRIMARY_MONITOR(rinfo);
dbg("radeonfb: radeon_write_mode\r\n"); dbg("radeonfb: radeon_write_mode\r\n");
if (!regs_only) if (!regs_only)
radeon_screen_blank(rinfo, FB_BLANK_NORMAL, 0); radeon_screen_blank(rinfo, FB_BLANK_NORMAL, 0);
radeon_wait_for_fifo(rinfo, 31); radeon_wait_for_fifo(rinfo, 31);
for(i=0; i<10; i++)
for (i = 0; i < 10; i++)
OUTREG(common_regs[i].reg, common_regs[i].val); OUTREG(common_regs[i].reg, common_regs[i].val);
/* Apply surface registers */ /* Apply surface registers */
for(i=0; i<8; i++) for (i = 0; i < 8; i++)
{ {
OUTREG(SURFACE0_LOWER_BOUND + 0x10*i, mode->surf_lower_bound[i]); OUTREG(SURFACE0_LOWER_BOUND + 0x10*i, mode->surf_lower_bound[i]);
OUTREG(SURFACE0_UPPER_BOUND + 0x10*i, mode->surf_upper_bound[i]); OUTREG(SURFACE0_UPPER_BOUND + 0x10*i, mode->surf_upper_bound[i]);
@@ -1380,9 +1479,11 @@ void radeon_write_mode(struct radeonfb_info *rinfo, struct radeon_regs *mode, in
else else
#endif #endif
OUTREG(CRTC_OFFSET_CNTL, 0); OUTREG(CRTC_OFFSET_CNTL, 0);
OUTREG(CRTC_PITCH, mode->crtc_pitch); OUTREG(CRTC_PITCH, mode->crtc_pitch);
OUTREG(SURFACE_CNTL, mode->surface_cntl); OUTREG(SURFACE_CNTL, mode->surface_cntl);
radeon_write_pll_regs(rinfo, mode); radeon_write_pll_regs(rinfo, mode);
if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD))
{ {
radeon_wait_for_fifo(rinfo, 10); radeon_wait_for_fifo(rinfo, 10);
@@ -1396,6 +1497,7 @@ void radeon_write_mode(struct radeonfb_info *rinfo, struct radeon_regs *mode, in
OUTREG(TMDS_CRC, mode->tmds_crc); OUTREG(TMDS_CRC, mode->tmds_crc);
OUTREG(TMDS_TRANSMITTER_CNTL, mode->tmds_transmitter_cntl); OUTREG(TMDS_TRANSMITTER_CNTL, mode->tmds_transmitter_cntl);
} }
if (!regs_only) if (!regs_only)
radeon_screen_blank(rinfo, FB_BLANK_UNBLANK, 0); radeon_screen_blank(rinfo, FB_BLANK_UNBLANK, 0);
radeon_wait_for_fifo(rinfo, 2); radeon_wait_for_fifo(rinfo, 2);
@@ -1407,11 +1509,13 @@ void radeon_write_mode(struct radeonfb_info *rinfo, struct radeon_regs *mode, in
*/ */
static void radeon_calc_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *regs, uint32_t freq) static void radeon_calc_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *regs, uint32_t freq)
{ {
static const struct { static const struct
{
int divider; int divider;
int bitvalue; int bitvalue;
} *post_div, } *post_div,
post_divs[] = { post_divs[] =
{
{ 1, 0 }, { 1, 0 },
{ 2, 1 }, { 2, 1 },
{ 4, 2 }, { 4, 2 },
@@ -1424,6 +1528,7 @@ static void radeon_calc_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs
}; };
int fb_div, pll_output_freq = 0; int fb_div, pll_output_freq = 0;
int uses_dvo = 0; int uses_dvo = 0;
/* Check if the DVO port is enabled and sourced from the primary CRTC. I'm /* Check if the DVO port is enabled and sourced from the primary CRTC. I'm
* not sure which model starts having FP2_GEN_CNTL, I assume anything more * not sure which model starts having FP2_GEN_CNTL, I assume anything more
* recent than an r(v)100... * recent than an r(v)100...
@@ -1443,9 +1548,11 @@ static void radeon_calc_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs
uint32_t fp2_gen_cntl = INREG(FP2_GEN_CNTL); uint32_t fp2_gen_cntl = INREG(FP2_GEN_CNTL);
uint32_t disp_output_cntl; uint32_t disp_output_cntl;
int source; int source;
/* FP2 path not enabled */ /* FP2 path not enabled */
if ((fp2_gen_cntl & FP2_ON) == 0) if ((fp2_gen_cntl & FP2_ON) == 0)
break; break;
/* Not all chip revs have the same format for this register, /* Not all chip revs have the same format for this register,
* extract the source selection * extract the source selection
*/ */
@@ -1464,9 +1571,11 @@ static void radeon_calc_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs
} }
else else
source = (fp2_gen_cntl >> 13) & 0x1; source = (fp2_gen_cntl >> 13) & 0x1;
/* sourced from CRTC2 -> exit */ /* sourced from CRTC2 -> exit */
if (source == 1) if (source == 1)
break; break;
/* so we end up on CRTC1, let's set uses_dvo to 1 now */ /* so we end up on CRTC1, let's set uses_dvo to 1 now */
uses_dvo = 1; uses_dvo = 1;
break; break;
@@ -1476,27 +1585,32 @@ static void radeon_calc_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs
#endif #endif
if (freq > rinfo->pll.ppll_max) if (freq > rinfo->pll.ppll_max)
freq = rinfo->pll.ppll_max; freq = rinfo->pll.ppll_max;
if (freq*12 < rinfo->pll.ppll_min) if (freq * 12 < rinfo->pll.ppll_min)
freq = rinfo->pll.ppll_min / 12; freq = rinfo->pll.ppll_min / 12;
for(post_div = &post_divs[0]; post_div->divider; ++post_div) for (post_div = &post_divs[0]; post_div->divider; ++post_div)
{ {
pll_output_freq = post_div->divider * freq; pll_output_freq = post_div->divider * freq;
/* If we output to the DVO port (external TMDS), we don't allow an
/*
* If we output to the DVO port (external TMDS), we don't allow an
* odd PLL divider as those aren't supported on this path * odd PLL divider as those aren't supported on this path
*/ */
if (uses_dvo && (post_div->divider & 1)) if (uses_dvo && (post_div->divider & 1))
continue; continue;
if (pll_output_freq >= rinfo->pll.ppll_min && if (pll_output_freq >= rinfo->pll.ppll_min &&
pll_output_freq <= rinfo->pll.ppll_max) pll_output_freq <= rinfo->pll.ppll_max)
break; break;
} }
/* If we fall through the bottom, try the "default value" /* If we fall through the bottom, try the "default value"
given by the terminal post_div->bitvalue */ given by the terminal post_div->bitvalue */
if ( !post_div->divider ) if (!post_div->divider)
{ {
post_div = &post_divs[post_div->bitvalue]; post_div = &post_divs[post_div->bitvalue];
pll_output_freq = post_div->divider * freq; pll_output_freq = post_div->divider * freq;
} }
/* If we fall through the bottom, try the "default value" /* If we fall through the bottom, try the "default value"
given by the terminal post_div->bitvalue */ given by the terminal post_div->bitvalue */
if ( !post_div->divider ) if ( !post_div->divider )
@@ -1535,6 +1649,7 @@ int radeonfb_set_par(struct fb_info *info)
newmode = (struct radeon_regs *) driver_mem_alloc(sizeof(struct radeon_regs)); newmode = (struct radeon_regs *) driver_mem_alloc(sizeof(struct radeon_regs));
if (!newmode) if (!newmode)
return -1; //-ENOMEM; return -1; //-ENOMEM;
/* We always want engine to be idle on a mode switch, even /* We always want engine to be idle on a mode switch, even
* if we won't actually change the mode * if we won't actually change the mode
*/ */
@@ -1582,24 +1697,29 @@ int radeonfb_set_par(struct fb_info *info)
newmode->ppll_ref_div = rinfo->panel_info.ref_divider; newmode->ppll_ref_div = rinfo->panel_info.ref_divider;
} }
} }
dotClock = 1000000000 / pixClock; dotClock = 1000000000 / pixClock;
freq = dotClock / 10; /* x100 */ freq = dotClock / 10; /* x100 */
hsync_wid = (hSyncEnd - hSyncStart) / 8; hsync_wid = (hSyncEnd - hSyncStart) / 8;
if (hsync_wid == 0) if (hsync_wid == 0)
hsync_wid = 1; hsync_wid = 1;
else if (hsync_wid > 0x3f) /* max */ else if (hsync_wid > 0x3f) /* max */
hsync_wid = 0x3f; hsync_wid = 0x3f;
if (mode->vmode & FB_VMODE_DOUBLE) if (mode->vmode & FB_VMODE_DOUBLE)
{ {
vSyncStart <<= 1; vSyncStart <<= 1;
vSyncEnd <<= 1; vSyncEnd <<= 1;
vTotal <<= 1; vTotal <<= 1;
} }
vsync_wid = vSyncEnd - vSyncStart; vsync_wid = vSyncEnd - vSyncStart;
if (vsync_wid == 0) if (vsync_wid == 0)
vsync_wid = 1; vsync_wid = 1;
else if (vsync_wid > 0x1f) /* max */ else if (vsync_wid > 0x1f) /* max */
vsync_wid = 0x1f; vsync_wid = 0x1f;
// FIXME: this doesn't seem to be used anywhere hSyncPol = mode->sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1; // FIXME: this doesn't seem to be used anywhere hSyncPol = mode->sync & FB_SYNC_HOR_HIGH_ACT ? 0 : 1;
// FIXME: this doesn't seem to be used anywhere vSyncPol = mode->sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1; // FIXME: this doesn't seem to be used anywhere vSyncPol = mode->sync & FB_SYNC_VERT_HIGH_ACT ? 0 : 1;
// FIXME: this doesn't seem to be used anywhere cSync = mode->sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0; // FIXME: this doesn't seem to be used anywhere cSync = mode->sync & FB_SYNC_COMP_HIGH_ACT ? (1 << 4) : 0;
@@ -1624,6 +1744,7 @@ int radeonfb_set_par(struct fb_info *info)
/* Clear auto-center etc... */ /* Clear auto-center etc... */
newmode->crtc_more_cntl = rinfo->init_state.crtc_more_cntl; newmode->crtc_more_cntl = rinfo->init_state.crtc_more_cntl;
newmode->crtc_more_cntl &= 0xfffffff0; newmode->crtc_more_cntl &= 0xfffffff0;
if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD)) if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD))
{ {
newmode->crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN; newmode->crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN;
@@ -1633,13 +1754,16 @@ int radeonfb_set_par(struct fb_info *info)
} }
else else
newmode->crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN | CRTC_CRT_ON; newmode->crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN | CRTC_CRT_ON;
newmode->dac_cntl = /* INREG(DAC_CNTL) | */ DAC_MASK_ALL | DAC_VGA_ADR_EN | DAC_8BIT_EN; newmode->dac_cntl = /* INREG(DAC_CNTL) | */ DAC_MASK_ALL | DAC_VGA_ADR_EN | DAC_8BIT_EN;
newmode->crtc_h_total_disp = ((((hTotal / 8) - 1) & 0x3ff) | (((mode->xres / 8) - 1) << 16)); newmode->crtc_h_total_disp = ((((hTotal / 8) - 1) & 0x3ff) | (((mode->xres / 8) - 1) << 16));
newmode->crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) | (hsync_wid << 16) | (h_sync_pol << 23)); newmode->crtc_h_sync_strt_wid = ((hsync_start & 0x1fff) | (hsync_wid << 16) | (h_sync_pol << 23));
if (mode->vmode & FB_VMODE_DOUBLE) if (mode->vmode & FB_VMODE_DOUBLE)
newmode->crtc_v_total_disp = ((vTotal - 1) & 0xffff) | (((mode->yres << 1) - 1) << 16); newmode->crtc_v_total_disp = ((vTotal - 1) & 0xffff) | (((mode->yres << 1) - 1) << 16);
else else
newmode->crtc_v_total_disp = ((vTotal - 1) & 0xffff) | ((mode->yres - 1) << 16); newmode->crtc_v_total_disp = ((vTotal - 1) & 0xffff) | ((mode->yres - 1) << 16);
newmode->crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) | (vsync_wid << 16) | (v_sync_pol << 23)); newmode->crtc_v_sync_strt_wid = (((vSyncStart - 1) & 0xfff) | (vsync_wid << 16) | (v_sync_pol << 23));
/* We first calculate the engine pitch */ /* We first calculate the engine pitch */
rinfo->pitch = ((mode->xres_virtual * ((mode->bits_per_pixel + 1) / 8) + 0x3f) & ~(0x3f)) >> 6; rinfo->pitch = ((mode->xres_virtual * ((mode->bits_per_pixel + 1) / 8) + 0x3f) & ~(0x3f)) >> 6;
@@ -1653,6 +1777,7 @@ int radeonfb_set_par(struct fb_info *info)
* swapper as well, so we leave it unset now. * swapper as well, so we leave it unset now.
*/ */
newmode->surface_cntl = 0; newmode->surface_cntl = 0;
if (rinfo->big_endian) if (rinfo->big_endian)
{ {
/* Setup swapping on both apertures, though we currently /* Setup swapping on both apertures, though we currently
@@ -1674,12 +1799,13 @@ int radeonfb_set_par(struct fb_info *info)
} }
/* Clear surface registers */ /* Clear surface registers */
for(i = 0; i < 8; i++) for (i = 0; i < 8; i++)
{ {
newmode->surf_lower_bound[i] = 0; newmode->surf_lower_bound[i] = 0;
newmode->surf_upper_bound[i] = 0x1f; newmode->surf_upper_bound[i] = 0x1f;
newmode->surf_info[i] = 0; newmode->surf_info[i] = 0;
} }
rinfo->bpp = mode->bits_per_pixel; rinfo->bpp = mode->bits_per_pixel;
rinfo->depth = depth; rinfo->depth = depth;
@@ -1724,6 +1850,7 @@ int radeonfb_set_par(struct fb_info *info)
& ~(FP_SEL_CRTC2 | FP_RMX_HVSYNC_CONTROL_EN | FP_DFP_SYNC_SEL | FP_CRT_SYNC_SEL & ~(FP_SEL_CRTC2 | FP_RMX_HVSYNC_CONTROL_EN | FP_DFP_SYNC_SEL | FP_CRT_SYNC_SEL
| FP_CRTC_LOCK_8DOT | FP_USE_SHADOW_EN | FP_CRTC_USE_SHADOW_VEND | FP_CRT_SYNC_ALT)); | FP_CRTC_LOCK_8DOT | FP_USE_SHADOW_EN | FP_CRTC_USE_SHADOW_VEND | FP_CRT_SYNC_ALT));
newmode->fp_gen_cntl |= (FP_CRTC_DONT_SHADOW_VPAR | FP_CRTC_DONT_SHADOW_HEND | FP_PANEL_FORMAT); newmode->fp_gen_cntl |= (FP_CRTC_DONT_SHADOW_VPAR | FP_CRTC_DONT_SHADOW_HEND | FP_PANEL_FORMAT);
if (IS_R300_VARIANT(rinfo) || (rinfo->family == CHIP_FAMILY_R200)) if (IS_R300_VARIANT(rinfo) || (rinfo->family == CHIP_FAMILY_R200))
{ {
newmode->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK; newmode->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
@@ -1734,10 +1861,12 @@ int radeonfb_set_par(struct fb_info *info)
} }
else else
newmode->fp_gen_cntl |= FP_SEL_CRTC1; newmode->fp_gen_cntl |= FP_SEL_CRTC1;
newmode->lvds_gen_cntl = rinfo->init_state.lvds_gen_cntl; newmode->lvds_gen_cntl = rinfo->init_state.lvds_gen_cntl;
newmode->lvds_pll_cntl = rinfo->init_state.lvds_pll_cntl; newmode->lvds_pll_cntl = rinfo->init_state.lvds_pll_cntl;
newmode->tmds_crc = rinfo->init_state.tmds_crc; newmode->tmds_crc = rinfo->init_state.tmds_crc;
newmode->tmds_transmitter_cntl = rinfo->init_state.tmds_transmitter_cntl; newmode->tmds_transmitter_cntl = rinfo->init_state.tmds_transmitter_cntl;
if (primary_mon == MT_LCD) if (primary_mon == MT_LCD)
{ {
newmode->lvds_gen_cntl |= (LVDS_ON | LVDS_BLON); newmode->lvds_gen_cntl |= (LVDS_ON | LVDS_BLON);
@@ -1755,11 +1884,13 @@ int radeonfb_set_par(struct fb_info *info)
newmode->tmds_transmitter_cntl |= TMDS_PLL_EN; newmode->tmds_transmitter_cntl |= TMDS_PLL_EN;
newmode->crtc_ext_cntl &= ~CRTC_CRT_ON; newmode->crtc_ext_cntl &= ~CRTC_CRT_ON;
} }
newmode->fp_crtc_h_total_disp = (((rinfo->panel_info.hblank / 8) & 0x3ff) | (((mode->xres / 8) - 1) << 16)); newmode->fp_crtc_h_total_disp = (((rinfo->panel_info.hblank / 8) & 0x3ff) | (((mode->xres / 8) - 1) << 16));
newmode->fp_crtc_v_total_disp = (rinfo->panel_info.vblank & 0xffff) | ((mode->yres - 1) << 16); newmode->fp_crtc_v_total_disp = (rinfo->panel_info.vblank & 0xffff) | ((mode->yres - 1) << 16);
newmode->fp_h_sync_strt_wid = ((rinfo->panel_info.hOver_plus & 0x1fff) | (hsync_wid << 16) | (h_sync_pol << 23)); newmode->fp_h_sync_strt_wid = ((rinfo->panel_info.hOver_plus & 0x1fff) | (hsync_wid << 16) | (h_sync_pol << 23));
newmode->fp_v_sync_strt_wid = ((rinfo->panel_info.vOver_plus & 0xfff) | (vsync_wid << 16) | (v_sync_pol << 23)); newmode->fp_v_sync_strt_wid = ((rinfo->panel_info.vOver_plus & 0xfff) | (vsync_wid << 16) | (v_sync_pol << 23));
} }
/* do it! */ /* do it! */
if (!rinfo->asleep) if (!rinfo->asleep)
{ {
@@ -1778,10 +1909,12 @@ int radeonfb_set_par(struct fb_info *info)
/* (re)initialize the engine */ /* (re)initialize the engine */
radeon_engine_init(rinfo); radeon_engine_init(rinfo);
} }
/* Update fix */ /* Update fix */
info->fix.line_length = rinfo->pitch*64; info->fix.line_length = rinfo->pitch*64;
info->fix.visual = rinfo->depth == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR; info->fix.visual = rinfo->depth == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
driver_mem_free(newmode); driver_mem_free(newmode);
return 0; return 0;
} }

View File

@@ -44,11 +44,13 @@
* *
*/ */
#include "bas_types.h"
#include "bas_printf.h"
#include "radeonfb.h" #include "radeonfb.h"
#define DBG_RADEON #define DBG_RADEON
#ifdef DBG_RADEON #ifdef DBG_RADEON
#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0) #define dbg(format, arg...) do { xprintf("DEBUG %s(): " format, __FUNCTION__, ##arg); } while (0)
#else #else
#define dbg(format, arg...) do { ; } while (0) #define dbg(format, arg...) do { ; } while (0)
#endif /* DBG_RADEON */ #endif /* DBG_RADEON */
@@ -66,20 +68,20 @@
#define CURSOR_SWAPPING_DECL_MMIO #define CURSOR_SWAPPING_DECL_MMIO
#define CURSOR_SWAPPING_DECL unsigned long __surface_cntl=0; #define CURSOR_SWAPPING_DECL unsigned long __surface_cntl=0;
#define CURSOR_SWAPPING_START() \ #define CURSOR_SWAPPING_START() \
if(rinfo->big_endian) \ if (rinfo->big_endian) \
OUTREG(SURFACE_CNTL, \ OUTREG(SURFACE_CNTL, \
((__surface_cntl = INREG(SURFACE_CNTL)) | \ ((__surface_cntl = INREG(SURFACE_CNTL)) | \
NONSURF_AP0_SWP_32BPP) & \ NONSURF_AP0_SWP_32BPP) & \
~NONSURF_AP0_SWP_16BPP); ~NONSURF_AP0_SWP_16BPP);
#define CURSOR_SWAPPING_END() \ #define CURSOR_SWAPPING_END() \
if(rinfo->big_endian) \ if (rinfo->big_endian) \
(OUTREG(SURFACE_CNTL, __surface_cntl)); (OUTREG(SURFACE_CNTL, __surface_cntl));
/* Set cursor foreground and background colors */ /* Set cursor foreground and background colors */
void radeon_set_cursor_colors(struct fb_info *info, int bg, int fg) void radeon_set_cursor_colors(struct fb_info *info, int bg, int fg)
{ {
struct radeonfb_info *rinfo = info->par; struct radeonfb_info *rinfo = info->par;
unsigned long *pixels = (unsigned long *)((unsigned long) rinfo->fb_base+rinfo->cursor_start); unsigned long *pixels = (unsigned long *)((unsigned long) rinfo->fb_base + rinfo->cursor_start);
int pixel, i; int pixel, i;
CURSOR_SWAPPING_DECL_MMIO CURSOR_SWAPPING_DECL_MMIO
CURSOR_SWAPPING_DECL CURSOR_SWAPPING_DECL
@@ -88,15 +90,17 @@ void radeon_set_cursor_colors(struct fb_info *info, int bg, int fg)
fg |= 0xff000000; fg |= 0xff000000;
bg |= 0xff000000; bg |= 0xff000000;
/* Don't recolour the image if we don't have to. */ /* Don't recolour the image if we don't have to. */
if(fg == rinfo->cursor_fg && bg == rinfo->cursor_bg) if (fg == rinfo->cursor_fg && bg == rinfo->cursor_bg)
return; return;
CURSOR_SWAPPING_START(); CURSOR_SWAPPING_START();
/* Note: We assume that the pixels are either fully opaque or fully
/*
* Note: We assume that the pixels are either fully opaque or fully
* transparent, so we won't premultiply them, and we can just * transparent, so we won't premultiply them, and we can just
* check for non-zero pixel values; those are either fg or bg * check for non-zero pixel values; those are either fg or bg
*/ */
for(i = 0; i < CURSOR_WIDTH * CURSOR_HEIGHT; i++, pixels++) for (i = 0; i < CURSOR_WIDTH * CURSOR_HEIGHT; i++, pixels++)
if((pixel = *pixels)) if ((pixel = *pixels))
*pixels = (pixel == rinfo->cursor_fg) ? fg : bg; *pixels = (pixel == rinfo->cursor_fg) ? fg : bg;
CURSOR_SWAPPING_END(); CURSOR_SWAPPING_END();
rinfo->cursor_fg = fg; rinfo->cursor_fg = fg;
@@ -112,27 +116,30 @@ void radeon_set_cursor_position(struct fb_info *info, int x, int y)
struct fb_var_screeninfo *mode = &info->var; struct fb_var_screeninfo *mode = &info->var;
int xorigin = 0; int xorigin = 0;
int yorigin = 0; int yorigin = 0;
if(mode->vmode & FB_VMODE_DOUBLE) if (mode->vmode & FB_VMODE_DOUBLE)
y <<= 1; y <<= 1;
if(x < 0) if (x < 0)
xorigin = 1 - x; xorigin = 1 - x;
if(y < 0) if (y < 0)
yorigin = 1 - y; yorigin = 1 - y;
// DPRINTVALHEX("radeonfb: RADEONSetCursorPosition: cursor_start ",rinfo->cursor_start); // DPRINTVALHEX("radeonfb: RADEONSetCursorPosition: cursor_start ",rinfo->cursor_start);
// DPRINTVAL(" x ",x); // DPRINTVAL(" x ",x);
// DPRINTVAL(" y ",y); // DPRINTVAL(" y ",y);
// DPRINT("\r\n"); // DPRINT("\r\n");
OUTREG(CUR_HORZ_VERT_OFF, (CUR_LOCK | (xorigin << 16) | yorigin)); OUTREG(CUR_HORZ_VERT_OFF, (CUR_LOCK | (xorigin << 16) | yorigin));
OUTREG(CUR_HORZ_VERT_POSN, (CUR_LOCK | ((xorigin ? 0 : x) << 16) | (yorigin ? 0 : y))); OUTREG(CUR_HORZ_VERT_POSN, (CUR_LOCK | ((xorigin ? 0 : x) << 16) | (yorigin ? 0 : y)));
OUTREG(CUR_OFFSET, rinfo->cursor_start + yorigin * 256); OUTREG(CUR_OFFSET, rinfo->cursor_start + yorigin * 256);
rinfo->cursor_x = (unsigned long)x; rinfo->cursor_x = (unsigned long)x;
if(mode->vmode & FB_VMODE_DOUBLE) if (mode->vmode & FB_VMODE_DOUBLE)
rinfo->cursor_y = (unsigned long)y >> 1; rinfo->cursor_y = (unsigned long) y >> 1;
else else
rinfo->cursor_y = (unsigned long)y; rinfo->cursor_y = (unsigned long) y;
} }
/* Copy cursor image from `image' to video memory. RADEONSetCursorPosition /*
* Copy cursor image from `image' to video memory. RADEONSetCursorPosition
* will be called after this, so we can ignore xorigin and yorigin. * will be called after this, so we can ignore xorigin and yorigin.
*/ */
void radeon_load_cursor_image(struct fb_info *info, unsigned short *mask, unsigned short *data, int zoom) void radeon_load_cursor_image(struct fb_info *info, unsigned short *mask, unsigned short *data, int zoom)
@@ -143,11 +150,14 @@ void radeon_load_cursor_image(struct fb_info *info, unsigned short *mask, unsign
unsigned short chunk, mchunk; unsigned short chunk, mchunk;
unsigned long i, j, k; unsigned long i, j, k;
CURSOR_SWAPPING_DECL CURSOR_SWAPPING_DECL
// DPRINTVALHEX("radeonfb: RADEONLoadCursorImage: cursor_start ",rinfo->cursor_start); // DPRINTVALHEX("radeonfb: RADEONLoadCursorImage: cursor_start ",rinfo->cursor_start);
// DPRINT("\r\n"); // DPRINT("\r\n");
save = INREG(CRTC_GEN_CNTL) & ~(unsigned long) (3 << 20); save = INREG(CRTC_GEN_CNTL) & ~(unsigned long) (3 << 20);
save |= (unsigned long) (2 << 20); save |= (unsigned long) (2 << 20);
OUTREG(CRTC_GEN_CNTL, save & (unsigned long)~CRTC_CUR_EN); OUTREG(CRTC_GEN_CNTL, save & (unsigned long)~CRTC_CUR_EN);
/* /*
* Convert the bitmap to ARGB32. * Convert the bitmap to ARGB32.
*/ */
@@ -157,22 +167,22 @@ void radeon_load_cursor_image(struct fb_info *info, unsigned short *mask, unsign
{ {
case 1: case 1:
default: default:
for(i = 0; i < CURSOR_HEIGHT; i++) for (i = 0; i < CURSOR_HEIGHT; i++)
{ {
if(i < 16) if (i < 16)
{ {
mchunk = *mask++; mchunk = *mask++;
chunk = *data++; chunk = *data++;
} }
else else
mchunk = chunk = 0; mchunk = chunk = 0;
for(j = 0; j < CURSOR_WIDTH / ARGB_PER_CHUNK; j++) for (j = 0; j < CURSOR_WIDTH / ARGB_PER_CHUNK; j++)
{ {
for(k = 0; k < ARGB_PER_CHUNK; k++, chunk <<= 1, mchunk <<= 1) for (k = 0; k < ARGB_PER_CHUNK; k++, chunk <<= 1, mchunk <<= 1)
{ {
if(mchunk & 0x8000) if (mchunk & 0x8000)
{ {
if(chunk & 0x8000) if (chunk & 0x8000)
*d++ = 0xff000000; /* Black, fully opaque. */ *d++ = 0xff000000; /* Black, fully opaque. */
else else
*d++ = 0xffffffff; /* White, fully opaque. */ *d++ = 0xffffffff; /* White, fully opaque. */
@@ -184,13 +194,13 @@ void radeon_load_cursor_image(struct fb_info *info, unsigned short *mask, unsign
} }
break; break;
case 2: case 2:
for(i = 0; i < CURSOR_HEIGHT; i++) for (i = 0; i < CURSOR_HEIGHT; i++)
{ {
if(i < 16*2) if (i < 16*2)
{ {
mchunk = *mask; mchunk = *mask;
chunk = *data; chunk = *data;
if((i & 1) == 1) if ((i & 1) == 1)
{ {
mask++; mask++;
data++; data++;
@@ -198,13 +208,13 @@ void radeon_load_cursor_image(struct fb_info *info, unsigned short *mask, unsign
} }
else else
mchunk = chunk = 0; mchunk = chunk = 0;
for(j = 0; j < CURSOR_WIDTH / ARGB_PER_CHUNK; j+=2) for (j = 0; j < CURSOR_WIDTH / ARGB_PER_CHUNK; j+=2)
{ {
for(k = 0; k < ARGB_PER_CHUNK; k++, chunk <<= 1, mchunk <<= 1) for (k = 0; k < ARGB_PER_CHUNK; k++, chunk <<= 1, mchunk <<= 1)
{ {
if(mchunk & 0x8000) if (mchunk & 0x8000)
{ {
if(chunk & 0x8000) if (chunk & 0x8000)
{ {
*d++ = 0xff000000; /* Black, fully opaque. */ *d++ = 0xff000000; /* Black, fully opaque. */
*d++ = 0xff000000; *d++ = 0xff000000;
@@ -225,13 +235,13 @@ void radeon_load_cursor_image(struct fb_info *info, unsigned short *mask, unsign
} }
break; break;
case 4: case 4:
for(i = 0; i < CURSOR_HEIGHT; i++) for (i = 0; i < CURSOR_HEIGHT; i++)
{ {
if(i < 16*4) if (i < 16 * 4)
{ {
mchunk = *mask; mchunk = *mask;
chunk = *data; chunk = *data;
if((i & 3) == 3) if ((i & 3) == 3)
{ {
mask++; mask++;
data++; data++;
@@ -239,13 +249,13 @@ void radeon_load_cursor_image(struct fb_info *info, unsigned short *mask, unsign
} }
else else
mchunk = chunk = 0; mchunk = chunk = 0;
for(j = 0; j < CURSOR_WIDTH / ARGB_PER_CHUNK; j+=4) for (j = 0; j < CURSOR_WIDTH / ARGB_PER_CHUNK; j+=4)
{ {
for(k = 0; k < ARGB_PER_CHUNK; k++, chunk <<= 1, mchunk <<= 1) for (k = 0; k < ARGB_PER_CHUNK; k++, chunk <<= 1, mchunk <<= 1)
{ {
if(mchunk & 0x8000) if (mchunk & 0x8000)
{ {
if(chunk & 0x8000) if (chunk & 0x8000)
{ {
*d++ = 0xff000000; /* Black, fully opaque. */ *d++ = 0xff000000; /* Black, fully opaque. */
*d++ = 0xff000000; *d++ = 0xff000000;
@@ -282,6 +292,7 @@ void radeon_load_cursor_image(struct fb_info *info, unsigned short *mask, unsign
void radeon_hide_cursor(struct fb_info *info) void radeon_hide_cursor(struct fb_info *info)
{ {
struct radeonfb_info *rinfo = info->par; struct radeonfb_info *rinfo = info->par;
// DPRINT("radeonfb: RADEONHideCursor\r\n"); // DPRINT("radeonfb: RADEONHideCursor\r\n");
OUTREGP(CRTC_GEN_CNTL, 0, ~CRTC_CUR_EN); OUTREGP(CRTC_GEN_CNTL, 0, ~CRTC_CUR_EN);
rinfo->cursor_show = 0; rinfo->cursor_show = 0;
@@ -291,6 +302,7 @@ void radeon_hide_cursor(struct fb_info *info)
void radeon_show_cursor(struct fb_info *info) void radeon_show_cursor(struct fb_info *info)
{ {
struct radeonfb_info *rinfo = info->par; struct radeonfb_info *rinfo = info->par;
// DPRINT("radeonfb: RADEONShowCursor\r\n"); // DPRINT("radeonfb: RADEONShowCursor\r\n");
OUTREGP(CRTC_GEN_CNTL, CRTC_CUR_EN, ~CRTC_CUR_EN); OUTREGP(CRTC_GEN_CNTL, CRTC_CUR_EN, ~CRTC_CUR_EN);
rinfo->cursor_show = 1; rinfo->cursor_show = 1;
@@ -303,9 +315,9 @@ long radeon_cursor_init(struct fb_info *info)
int size_bytes = CURSOR_WIDTH * 4 * CURSOR_HEIGHT; int size_bytes = CURSOR_WIDTH * 4 * CURSOR_HEIGHT;
unsigned long fbarea = offscreen_alloc(rinfo->info, size_bytes + 256); unsigned long fbarea = offscreen_alloc(rinfo->info, size_bytes + 256);
dbg("radeonfb: %s: fbarea: %p\r\n", __FUNCTION__, fbarea); dbg("radeonfb: %s: fbarea: %p\r\n", fbarea);
if(!fbarea) if (!fbarea)
rinfo->cursor_start = 0; rinfo->cursor_start = 0;
else else
{ {

View File

@@ -48,6 +48,7 @@
#include "bootp.h" #include "bootp.h"
#include "interrupts.h" #include "interrupts.h"
#include "exceptions.h" #include "exceptions.h"
#include "net_timer.h"
//#define BAS_DEBUG //#define BAS_DEBUG
#if defined(BAS_DEBUG) #if defined(BAS_DEBUG)
@@ -95,20 +96,20 @@ static inline bool pic_rxready(void)
void write_pic_byte(uint8_t value) void write_pic_byte(uint8_t value)
{ {
/* Wait until the transmitter is ready or 1000us are passed */ /* Wait until the transmitter is ready or 1000us are passed */
waitfor(1000, pic_txready); waitfor(1000, pic_txready);
/* Transmit the byte */ /* Transmit the byte */
*(volatile uint8_t*)(&MCF_PSC3_PSCTB_8BIT) = value; // Really 8-bit *(volatile uint8_t*)(&MCF_PSC3_PSCTB_8BIT) = value; // Really 8-bit
} }
uint8_t read_pic_byte(void) uint8_t read_pic_byte(void)
{ {
/* Wait until a byte has been received or 1000us are passed */ /* Wait until a byte has been received or 1000us are passed */
waitfor(1000, pic_rxready); waitfor(1000, pic_rxready);
/* Return the received byte */ /* Return the received byte */
return *(volatile uint8_t*)(&MCF_PSC3_PSCTB_8BIT); // Really 8-bit return *(volatile uint8_t*)(&MCF_PSC3_PSCTB_8BIT); // Really 8-bit
} }
void pic_init(void) void pic_init(void)
@@ -251,7 +252,7 @@ static ARP_INFO arp_info;
void network_init(void) void network_init(void)
{ {
uint8_t mac[6] = {0x00, 0xcf, 0x54, 0x12, 0x34, 0x56}; uint8_t mac[6] = {0x00, 0xcf, 0x54, 0x85, 0xcf, 0x01}; /* this is the original MAC address dbug assigns */
uint8_t bc[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; /* this is our broadcast MAC address */ uint8_t bc[6] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; /* this is our broadcast MAC address */
IP_ADDR myip = {192, 168, 1, 100}; IP_ADDR myip = {192, 168, 1, 100};
IP_ADDR gateway = {192, 168, 1, 1}; IP_ADDR gateway = {192, 168, 1, 1};
@@ -264,19 +265,19 @@ void network_init(void)
isr_init(); /* need to call that explicitely, otherwise isr table might be full */ isr_init(); /* need to call that explicitely, otherwise isr table might be full */
if (!isr_register_handler(ISR_DBUG_ISR, vector, handler, NULL, (void *) &nif1)) if (!isr_register_handler(vector, handler, NULL, (void *) &nif1))
{ {
dbg("%s: unable to register handler for vector %d\r\n", __FUNCTION__, vector); dbg("%s: unable to register handler for vector %d\r\n", __FUNCTION__, vector);
return; return;
} }
/* /*
* Register the DMA interrupt handler * Register the DMA interrupt handler
*/ */
handler = dma_interrupt_handler; handler = dma_interrupt_handler;
vector = 112; vector = 112;
if (!isr_register_handler(ISR_DBUG_ISR, vector, handler, NULL,NULL)) if (!isr_register_handler(vector, handler, NULL,NULL))
{ {
dbg("%s: Error: Unable to register handler for vector %s\r\n", __FUNCTION__, vector); dbg("%s: Error: Unable to register handler for vector %s\r\n", __FUNCTION__, vector);
return; return;
@@ -290,10 +291,10 @@ void network_init(void)
memcpy(nif1.hwa, mac, 6); memcpy(nif1.hwa, mac, 6);
memcpy(nif1.broadcast, bc, 6); memcpy(nif1.broadcast, bc, 6);
dbg("%s: ethernet address is %02X:%02X:%02X:%02X:%02X:%02X\r\n", __FUNCTION__, dbg("%s: ethernet address is %02X:%02X:%02X:%02X:%02X:%02X\r\n", __FUNCTION__,
nif1.hwa[0], nif1.hwa[1], nif1.hwa[2], nif1.hwa[0], nif1.hwa[1], nif1.hwa[2],
nif1.hwa[3], nif1.hwa[4], nif1.hwa[5]); nif1.hwa[3], nif1.hwa[4], nif1.hwa[5]);
timer_init(TIMER_NETWORK, TMR_INTC_LVL, TMR_INTC_PRI); timer_init(TIMER_NETWORK, TMR_INTC_LVL, TMR_INTC_PRI);
arp_init(&arp_info); arp_init(&arp_info);
@@ -345,16 +346,16 @@ void BaS(void)
MCF_MMU_MMUCR = MCF_MMU_MMUCR_EN; /* MMU on */ MCF_MMU_MMUCR = MCF_MMU_MMUCR_EN; /* MMU on */
NOP(); /* force pipeline sync */ NOP(); /* force pipeline sync */
xprintf("finished\r\n"); xprintf("finished\r\n");
#ifdef MACHINE_FIREBEE #ifdef MACHINE_FIREBEE
xprintf("IDE reset: "); xprintf("IDE reset: ");
/* IDE reset */ /* IDE reset */
* (volatile uint8_t *) (0xffff8802 - 2) = 14; * (volatile uint8_t *) (0xffff8802 - 2) = 14;
* (volatile uint8_t *) (0xffff8802 - 0) = 0x80; * (volatile uint8_t *) (0xffff8802 - 0) = 0x80;
wait(1); wait(1);
* (volatile uint8_t *) (0xffff8802 - 0) = 0; * (volatile uint8_t *) (0xffff8802 - 0) = 0;
xprintf("finished\r\n"); xprintf("finished\r\n");
xprintf("enable video: "); xprintf("enable video: ");
/* /*
@@ -383,22 +384,22 @@ void BaS(void)
#ifdef _NOT_USED_ #ifdef _NOT_USED_
screen_init(); screen_init();
/* experimental */ /* experimental */
{ {
int i; int i;
uint32_t *scradr = 0xd00000; uint32_t *scradr = 0xd00000;
for (i = 0; i < 100; i++) for (i = 0; i < 100; i++)
{ {
uint32_t *p = scradr; uint32_t *p = scradr;
for (p = scradr; p < scradr + 1024 * 150L; p++)
{
*p = 0xffffffff;
}
for (p = scradr; p < scradr + 1024 * 150L; p++) for (p = scradr; p < scradr + 1024 * 150L; p++)
{ {
*p = 0xffffffff;
}
for (p = scradr; p < scradr + 1024 * 150L; p++)
{
*p = 0x0; *p = 0x0;
} }
} }
@@ -441,10 +442,11 @@ void BaS(void)
/* Jump into the OS */ /* Jump into the OS */
typedef void void_func(void); typedef void void_func(void);
typedef struct { struct rom_header
{
void *initial_sp; void *initial_sp;
void_func *initial_pc; void_func *initial_pc;
} ROM_HEADER; };
xprintf("BaS initialization finished, enable interrupts\r\n"); xprintf("BaS initialization finished, enable interrupts\r\n");
enable_coldfire_interrupts(); enable_coldfire_interrupts();
@@ -453,6 +455,6 @@ void BaS(void)
network_init(); network_init();
xprintf("call EmuTOS\r\n"); xprintf("call EmuTOS\r\n");
ROM_HEADER* os_header = (ROM_HEADER*)TOS; struct rom_header *os_header = (struct rom_header *) TOS;
os_header->initial_pc(); os_header->initial_pc();
} }

View File

@@ -44,24 +44,24 @@ uint32_t cacr_get(void)
void flush_and_invalidate_caches(void) void flush_and_invalidate_caches(void)
{ {
__asm__ ( __asm__ __volatile__(
" clr.l d0\n\t" " clr.l d0 \n\t"
" clr.l d1\n\t" " clr.l d1 \n\t"
" move.l d0,a0\n\t" " move.l d0,a0 \n\t"
"cfa_setloop:\n\t" "cfa_setloop: \n\t"
" cpushl bc,(a0) | flush\n\t" " cpushl bc,(a0) | flush\n\t"
" lea 0x10(a0),a0 | index+1\n\t" " lea 0x10(a0),a0 | index+1\n\t"
" addq.l #1,d1 | index+1\n\t" " addq.l #1,d1 | index+1\n\t"
" cmpi.w #512,d1 | all sets?\n\t" " cmpi.w #512,d1 | all sets?\n\t"
" bne.s cfa_setloop | no->\n\t" " bne.s cfa_setloop | no->\n\t"
" clr.l d1\n\t" " clr.l d1 \n\t"
" addq.l #1,d0\n\t" " addq.l #1,d0 \n\t"
" move.l d0,a0\n\t" " move.l d0,a0 \n\t"
" cmpi.w #4,d0 | all ways?\n\t" " cmpi.w #4,d0 | all ways?\n\t"
" bne.s cfa_setloop | no->\n\t" " bne.s cfa_setloop | no->\n\t"
/* input */ : /* input */ :
/* output */ : /* output */ :
/* clobber */ : "d0", "d1", "a0" /* clobber */ : "d0", "d1", "a0"
); );
} }
@@ -81,25 +81,35 @@ void flush_icache_range(void *address, size_t size)
if (start_set > end_set) { if (start_set > end_set) {
/* from the begining to the lowest address */ /* from the begining to the lowest address */
for (set = 0; set <= end_set; set += (0x10 - 3)) { for (set = 0; set <= end_set; set += (0x10 - 3)) {
asm volatile("cpushl ic,(%0)\n\t" __asm__ __volatile__(
"addq.l #1,%0\n\t" " cpushl ic,(%[set]) \n\t"
"cpushl ic,(%0)\n\t" " addq.l #1,%[set] \n\t"
"addq.l #1,%0\n\t" " cpushl ic,(%[set]) \n\t"
"cpushl ic,(%0)\n\t" " addq.l #1,%[set] \n\t"
"addq.l #1,%0\n\t" " cpushl ic,(%[set]) \n\t"
"cpushl ic,(%0)" : "=a" (set) : "a" (set)); " addq.l #1,%[set] \n\t"
" cpushl ic,(%[set]) \n\t"
: /* output parameters */
: [set] "a" (set) /* input parameters */
:
);
} }
/* next loop will finish the cache ie pass the hole */ /* next loop will finish the cache ie pass the hole */
end_set = LAST_ICACHE_ADDR; end_set = LAST_ICACHE_ADDR;
} }
for (set = start_set; set <= end_set; set += (0x10 - 3)) { for (set = start_set; set <= end_set; set += (0x10 - 3)) {
asm volatile("cpushl ic,(%0)\n\t" __asm__ __volatile__(
"addq.l #1,%0\n\t" " cpushl ic,(%[set]) \n\t"
"cpushl ic,(%0)\n\t" " addq.l #1,%[set] \n\t"
"addq%.l #1,%0\n\t" " cpushl ic,(%[set]) \n\t"
"cpushl ic,(%0)\n\t" " addq.l #1,%[set] \n\t"
"addq.l #1,%0\n\t" " cpushl ic,(%[set]) \n\t"
"cpushl ic,(%0)" : "=a" (set) : "a" (set)); " addq.l #1,%[set] \n\t"
" cpushl ic,(%[set])"
: /* output parameters */
: [set] "a" (set)
:
);
} }
} }
@@ -121,25 +131,37 @@ void flush_dcache_range(void *address, size_t size)
if (start_set > end_set) { if (start_set > end_set) {
/* from the begining to the lowest address */ /* from the begining to the lowest address */
for (set = 0; set <= end_set; set += (0x10 - 3)) { for (set = 0; set <= end_set; set += (0x10 - 3))
asm volatile("cpushl dc,(%0)\n\t" {
"addq.l #1,%0\n\t" __asm__ __volatile__(
"cpushl dc,(%0)\n\t" " cpushl dc,(%[set]) \n\t"
"addq.l #1,%0\n\t" " addq.l #1,%[set] \n\t"
"cpushl dc,(%0)\n\t" " cpushl dc,(%[set]) \n\t"
"addq.l #1,%0\n\t" " addq.l #1,%[set] \n\t"
"cpushl dc,(%0)" : "=a" (set) : "a" (set)); " cpushl dc,(%[set]) \n\t"
" addq.l #1,%[set] \n\t"
" cpushl dc,(%[set]) \n\t"
: /* output parameters */
: [set] "a" (set)
: /* clobbered registers */
);
} }
/* next loop will finish the cache ie pass the hole */ /* next loop will finish the cache ie pass the hole */
end_set = LAST_DCACHE_ADDR; end_set = LAST_DCACHE_ADDR;
} }
for (set = start_set; set <= end_set; set += (0x10 - 3)) { for (set = start_set; set <= end_set; set += (0x10 - 3))
asm volatile("cpushl dc,(%0)\n\t" {
"addq.l #1,%0\n\t" __asm__ __volatile__(
"cpushl dc,(%0)\n\t" " cpushl dc,(%[set]) \n\t"
"addq%.l #1,%0\n\t" " addq.l #1,%[set] \n\t"
"cpushl dc,(%0)\n\t" " cpushl dc,(%[set]) \n\t"
"addq.l #1,%0\n\t" " addq%.l #1,%[set] \n\t"
"cpushl dc,(%0)" : "=a" (set) : "a" (set)); " cpushl dc,(%[set]) \n\t"
" addq.l #1,%[set] \n\t"
" cpushl dc,(%[set]) \n\t"
: /* output parameters */
: [set] "a" (set)
: /* clobbered registers */
);
} }
} }

View File

@@ -18,10 +18,14 @@
#include "usb.h" #include "usb.h"
#include "exceptions.h" /* set_ipl() */ #include "exceptions.h" /* set_ipl() */
#if MACHINE_FIREBEE #if defined(MACHINE_FIREBEE)
#include "firebee.h" #include "firebee.h"
#elif MACHINE_M5484LITE #elif defined(MACHINE_M5484LITE)
#include "m5484l.h" #include "m5484l.h"
#elif defined(MACHINE_M54455)
#include "m54455.h"
#else
#error "unknown machine!"
#endif #endif
//#define DBG_DM //#define DBG_DM

View File

@@ -33,64 +33,69 @@
#define FPGA_DATA0 (1 << 3) #define FPGA_DATA0 (1 << 3)
#define FPGA_CONF_DONE (1 << 5) #define FPGA_CONF_DONE (1 << 5)
extern uint8_t _FPGA_FLASH_DATA[]; extern uint8_t _FPGA_CONFIG[];
#define FPGA_FLASH_DATA &_FPGA_FLASH_DATA[0] #define FPGA_FLASH_DATA &_FPGA_CONFIG[0]
extern uint8_t _FPGA_FLASH_DATA_SIZE[]; extern uint8_t _FPGA_CONFIG_SIZE[];
#define FPGA_FLASH_DATA_SIZE ((uint32_t) &_FPGA_FLASH_DATA_SIZE[0]) #define FPGA_FLASH_DATA_SIZE ((uint32_t) &_FPGA_CONFIG_SIZE[0])
/*
* flag located in processor SRAM1 that indicates that the FPGA configuration has
* been loaded through JTAG. init_fpga() will honour this and not overwrite config.
*/
extern int32_t _FPGA_JTAG_LOADED;
#ifdef _NOT_USED_ void config_gpio_for_fpga_config(void)
void test_longword(void)
{ {
uint32_t *fpga_data = (uint32_t *) FPGA_FLASH_DATA; #if defined(MACHINE_FIREBEE)
const uint32_t *fpga_flash_data_end = (uint32_t *) FPGA_FLASH_DATA + FPGA_FLASH_DATA_SIZE; /*
do * Configure GPIO FEC1L port directions (needed to load FPGA configuration)
{ */
uint32_t value = *fpga_data++; MCF_GPIO_PDDR_FEC1L = 0 | /* bit 7 = input */
xprintf("LONGWORDS: addr=%p, value=%08x\r", fpga_data, value); 0 | /* bit 6 = input */
} while (fpga_data < fpga_flash_data_end); 0 | /* bit 5 = input */
xprintf("finished. \r\n"); 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 test_word(void) void config_gpio_for_jtag_config(void)
{ {
uint16_t *fpga_data = (uint16_t *) FPGA_FLASH_DATA; /*
const uint16_t *fpga_flash_data_end = (uint16_t *) FPGA_FLASH_DATA + FPGA_FLASH_DATA_SIZE; * configure FEC1L port directions to enable external JTAG configuration download to FPGA
*/
do MCF_GPIO_PDDR_FEC1L = 0 |
{ MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L4; /* bit 4 = LED => output */
uint16_t value = *fpga_data++; /* all other bits = input */
xprintf("WORDS: addr=%p, value=%04x\r", fpga_data, value); /*
} while (fpga_data < fpga_flash_data_end); * unfortunately, the GPIO module cannot trigger interrupts. That means FPGA_CONFIG needs to be polled to detect
xprintf("finished. \r\n"); * external FPGA (re)configuration and reset the system in that case. Could be done from the OS as well...
*/
} }
void test_byte(void)
{
uint8_t *fpga_data = (uint8_t *) FPGA_FLASH_DATA;
const uint8_t *fpga_flash_data_end = (uint8_t *) FPGA_FLASH_DATA + FPGA_FLASH_DATA_SIZE;
do
{
uint8_t value = *fpga_data++;
xprintf("LONGWORDS: addr=%p, value=%08x\r", fpga_data, value);
} while (fpga_data < fpga_flash_data_end);
xprintf("finished. \r\n");
}
#endif /* _NOT_USED_ */
/* /*
* load FPGA * load FPGA
*/ */
void init_fpga(void) bool init_fpga(void)
{ {
uint8_t *fpga_data; uint8_t *fpga_data;
volatile int32_t time, start, end; volatile int32_t time, start, end;
int i; int i;
xprintf("FPGA load config... "); xprintf("FPGA load config (_FPGA_JTAG_LOADED = %x)...", _FPGA_JTAG_LOADED);
start = MCF_SLT0_SCNT; if (_FPGA_JTAG_LOADED == 1)
{
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;
config_gpio_for_fpga_config();
MCF_GPIO_PODR_FEC1L &= ~FPGA_CLOCK; /* FPGA clock => low */ MCF_GPIO_PODR_FEC1L &= ~FPGA_CLOCK; /* FPGA clock => low */
/* pulling FPGA_CONFIG to low resets the FPGA */ /* pulling FPGA_CONFIG to low resets the FPGA */
@@ -109,7 +114,7 @@ void init_fpga(void)
* configuration cycle consists of 3 stages<65>reset, configuration, and initialization. * configuration cycle consists of 3 stages<65>reset, configuration, and initialization.
* While nCONFIG is low, the device is in reset. When the device comes out of reset, * 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 * 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 * 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 * 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 * 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. * on the I/O pins which are on, before and during configuration.
@@ -159,11 +164,12 @@ void init_fpga(void)
#endif /* _NOT_USED_ */ #endif /* _NOT_USED_ */
end = MCF_SLT0_SCNT; end = MCF_SLT0_SCNT;
time = (start - end) / (SYSCLK / 1000) / 1000; time = (start - end) / (SYSCLK / 1000) / 1000;
xprintf("finished (took %f seconds).\r\n", time / 1000.0); xprintf("finished (took %f seconds).\r\n", time / 1000.0);
config_gpio_for_jtag_config();
return true;
} }
else xprintf("FAILED!\r\n");
{ config_gpio_for_jtag_config();
xprintf("FAILED!\r\n"); return false;
}
} }

View File

@@ -30,13 +30,16 @@
#include "exceptions.h" #include "exceptions.h"
#include "interrupts.h" #include "interrupts.h"
#include "bas_printf.h" #include "bas_printf.h"
#include "startcf.h"
#include "cache.h"
#include "util.h"
extern void (*rt_vbr[])(void); extern void (*rt_vbr[])(void);
#define VBR rt_vbr #define VBR rt_vbr
#define IRQ_DEBUG #define IRQ_DEBUG
#if defined(IRQ_DEBUG) #if defined(IRQ_DEBUG)
#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0) #define dbg(format, arg...) do { xprintf("DEBUG %s(): " format, __FUNCTION__, ##arg); } while (0)
#else #else
#define dbg(format, arg...) do { ; } while (0) #define dbg(format, arg...) do { ; } while (0)
#endif #endif
@@ -57,7 +60,7 @@ int register_interrupt_handler(uint8_t source, uint8_t level, uint8_t priority,
if (source < 1 || source > 63) if (source < 1 || source > 63)
{ {
dbg("%s: interrupt source %d not defined\r\n", __FUNCTION__, source); dbg("interrupt source %d not defined\r\n", source);
return -1; return -1;
} }
@@ -68,7 +71,7 @@ int register_interrupt_handler(uint8_t source, uint8_t level, uint8_t priority,
{ {
if (ICR[i] == lp) if (ICR[i] == lp)
{ {
dbg("%s: level %d and priority %d already used for interrupt source %d!\r\n", __FUNCTION__, dbg("level %d and priority %d already used for interrupt source %d!\r\n",
level, priority, i); level, priority, i);
return -1; return -1;
} }
@@ -88,31 +91,29 @@ int register_interrupt_handler(uint8_t source, uint8_t level, uint8_t priority,
return 0; return 0;
} }
#ifndef UIF_MAX_ISR_ENTRY #ifndef MAX_ISR_ENTRY
#define UIF_MAX_ISR_ENTRY (20) #define MAX_ISR_ENTRY (20)
#endif #endif
typedef struct typedef struct
{ {
int vector; int vector;
int type;
int (*handler)(void *, void *); int (*handler)(void *, void *);
void *hdev; void *hdev;
void *harg; void *harg;
} ISRENTRY; } ISRENTRY;
ISRENTRY isrtab[UIF_MAX_ISR_ENTRY]; ISRENTRY isrtab[MAX_ISR_ENTRY];
void isr_init(void) void isr_init(void)
{ {
int index; int index;
for (index = 0; index < UIF_MAX_ISR_ENTRY; index++) for (index = 0; index < MAX_ISR_ENTRY; index++)
{ {
isrtab[index].vector = 0; isrtab[index].vector = 0;
isrtab[index].type = 0;
isrtab[index].handler = 0; isrtab[index].handler = 0;
isrtab[index].hdev = 0; isrtab[index].hdev = 0;
isrtab[index].harg = 0; isrtab[index].harg = 0;
@@ -120,41 +121,36 @@ void isr_init(void)
} }
int isr_register_handler(int type, int vector, int isr_register_handler(int vector, int (*handler)(void *, void *), void *hdev, void *harg)
int (*handler)(void *, void *), void *hdev, void *harg)
{ {
/* /*
* This function places an interrupt handler in the ISR table, * This function places an interrupt handler in the ISR table,
* thereby registering it so that the low-level handler may call it. * thereby registering it so that the low-level handler may call it.
* *
* The two parameters are intended for the first arg to be a * The two parameters are intended for the first arg to be a
* pointer to the device itself, and the second a pointer to a data * pointer to the device itself, and the second a pointer to a data
* structure used by the device driver for that particular device. * structure used by the device driver for that particular device.
*/ */
int index; int index;
if ((vector == 0) || if ((vector == 0) || (handler == NULL))
((type != ISR_DBUG_ISR) && (type != ISR_USER_ISR)) ||
(handler == NULL))
{ {
dbg("%s: illegal type, vector or handler!\r\n", __FUNCTION__); dbg("illegal vector or handler!\r\n");
return false; return false;
} }
for (index = 0; index < UIF_MAX_ISR_ENTRY; index++) for (index = 0; index < MAX_ISR_ENTRY; index++)
{ {
if ((isrtab[index].vector == vector) && if (isrtab[index].vector == vector)
(isrtab[index].type == type))
{ {
/* only one entry of each type per vector */ /* one cross each, only! */
dbg("%s: already set handler with this type and vector (%d, %d)\r\n", __FUNCTION__, type, vector); dbg("already set handler with this vector (%d, %d)\r\n", vector);
return false; return false;
} }
if (isrtab[index].vector == 0) if (isrtab[index].vector == 0)
{ {
isrtab[index].vector = vector; isrtab[index].vector = vector;
isrtab[index].type = type;
isrtab[index].handler = handler; isrtab[index].handler = handler;
isrtab[index].hdev = hdev; isrtab[index].hdev = hdev;
isrtab[index].harg = harg; isrtab[index].harg = harg;
@@ -162,26 +158,24 @@ int isr_register_handler(int type, int vector,
return true; return true;
} }
} }
dbg("%s: no available slots to register handler for vector %d\n\r", __FUNCTION__, vector); dbg("no available slots to register handler for vector %d\n\r", vector);
return false; /* no available slots */ return false; /* no available slots */
} }
void isr_remove_handler(int type, int (*handler)(void *, void *)) void isr_remove_handler(int (*handler)(void *, void *))
{ {
/* /*
* This routine removes from the ISR table all * This routine removes from the ISR table all
* entries that matches 'type' and 'handler'. * entries that matches 'handler'.
*/ */
int index; int index;
for (index = 0; index < UIF_MAX_ISR_ENTRY; index++) for (index = 0; index < MAX_ISR_ENTRY; index++)
{ {
if ((isrtab[index].handler == handler) && if (isrtab[index].handler == handler)
(isrtab[index].type == type))
{ {
isrtab[index].vector = 0; isrtab[index].vector = 0;
isrtab[index].type = 0;
isrtab[index].handler = 0; isrtab[index].handler = 0;
isrtab[index].hdev = 0; isrtab[index].hdev = 0;
isrtab[index].harg = 0; isrtab[index].harg = 0;
@@ -189,7 +183,7 @@ void isr_remove_handler(int type, int (*handler)(void *, void *))
return; return;
} }
} }
dbg("%s: no such handler registered (type=%d, handler=%p\r\n", __FUNCTION__, type, handler); dbg("no such handler registered (handler=%p\r\n", handler);
} }
@@ -203,22 +197,216 @@ bool isr_execute_handler(int vector)
bool retval = false; bool retval = false;
/* /*
* First locate a BaS Interrupt Service Routine handler. * locate a BaS Interrupt Service Routine handler.
*/ */
for (index = 0; index < UIF_MAX_ISR_ENTRY; index++) for (index = 0; index < MAX_ISR_ENTRY; index++)
{ {
if ((isrtab[index].vector == vector) && if (isrtab[index].vector == vector)
(isrtab[index].type == ISR_DBUG_ISR))
{ {
retval = true; retval = true;
if (isrtab[index].handler(isrtab[index].hdev, isrtab[index].harg)) if (isrtab[index].handler(isrtab[index].hdev, isrtab[index].harg))
{ {
return retval; return retval;
} }
} }
} }
dbg("%s: no BaS isr handler for vector %d found\r\n", __FUNCTION__, vector); dbg("no BaS isr handler for vector %d found\r\n", vector);
return retval; return retval;
} }
/*
* PIC interrupt handler for Firebee
*/
void pic_interrupt_handler(void)
{
uint8_t rcv_byte;
rcv_byte = MCF_PSC3_PSCRB_8BIT;
if (rcv_byte == 2) // PIC requests RTC data
{
uint8_t *rtc_reg= (uint8_t *) 0xffff8961;
uint8_t *rtc_data = (uint8_t *) 0xffff8963;
int index = 0;
xprintf("PIC interrupt requesting RTC data\r\n");
MCF_PSC3_PSCTB_8BIT = 0x82; // header byte to PIC
do
{
*rtc_reg = 0;
MCF_PSC3_PSCTB_8BIT = *rtc_data;
} while (index++ < 64);
}
}
extern int32_t video_sbt;
extern int32_t video_tlb;
void video_addr_timeout(void)
{
uint32_t addr = 0x0L;
uint32_t *src;
uint32_t *dst;
uint32_t asid;
dbg("video address timeout\r\n");
flush_and_invalidate_caches();
do
{
uint32_t tlb;
uint32_t page_attr;
/*
* search tlb entry id for addr (if not available, the MMU
* will provide a new one based on its LRU algorithm)
*/
MCF_MMU_MMUAR = addr;
MCF_MMU_MMUOR =
MCF_MMU_MMUOR_STLB |
MCF_MMU_MMUOR_RW |
MCF_MMU_MMUOR_ACC;
NOP();
tlb = (MCF_MMU_MMUOR >> 16) & 0xffff;
/*
* retrieve tlb entry with the found TLB entry id
*/
MCF_MMU_MMUAR = tlb;
MCF_MMU_MMUOR =
MCF_MMU_MMUOR_STLB |
MCF_MMU_MMUOR_ADR |
MCF_MMU_MMUOR_RW |
MCF_MMU_MMUOR_ACC;
NOP();
asid = (MCF_MMU_MMUTR >> 2) & 0x1fff; /* fetch ASID of page */;
if (asid != sca_page_ID) /* check if screen area */
{
addr += 0x100000;
continue; /* next page */
}
/* modify found TLB entry */
if (addr == 0x0)
{
page_attr =
MCF_MMU_MMUDR_LK |
MCF_MMU_MMUDR_SZ(0) |
MCF_MMU_MMUDR_CM(0) |
MCF_MMU_MMUDR_R |
MCF_MMU_MMUDR_W |
MCF_MMU_MMUDR_X;
}
else
{
page_attr =
MCF_MMU_MMUTR_SG |
MCF_MMU_MMUTR_V;
}
MCF_MMU_MMUTR = addr;
MCF_MMU_MMUDR = page_attr;
MCF_MMU_MMUOR =
MCF_MMU_MMUOR_STLB |
MCF_MMU_MMUOR_ADR |
MCF_MMU_MMUOR_ACC |
MCF_MMU_MMUOR_UAA;
NOP();
dst = (uint32_t *) 0x60000000 + addr;
src = (uint32_t *) addr;
while (dst < (uint32_t *) 0x60000000 + addr + 0x10000)
{
*dst++ = *src++;
*dst++ = *src++;
*dst++ = *src++;
*dst++ = *src++;
}
addr += 0x100000;
} while (addr < 0xd00000);
video_tlb = 0x2000;
video_sbt = 0;
}
/*
* blink the Firebee's LED to show we are still alive
*/
void blink_led(void)
{
static uint16_t blinker = 0;
if ((blinker++ & 0x80) > 0)
{
MCF_GPIO_PODR_FEC1L |= (1 << 4); /* LED off */
}
else
{
MCF_GPIO_PODR_FEC1L &= ~(1 << 4); /* LED on */
}
}
/*
* Atari MFP interrupt registers.
*
* TODO: should go into a header file
*/
#define FALCON_MFP_IERA *((volatile uint8_t *) 0xfffffa07)
#define FALCON_MFP_IERB *((volatile uint8_t *) 0xfffffa09)
#define FALCON_MFP_IPRA *((volatile uint8_t *) 0xfffffa0b)
#define FALCON_MFP_IPRB *((volatile uint8_t *) 0xfffffa0d)
#define FALCON_MFP_IMRA *((volatile uint8_t *) 0xfffffa13)
#define FALCON_MFP_IMRB *((volatile uint8_t *) 0xfffffa15)
bool irq6_acsi_dma_interrupt(void)
{
dbg("ACSI DMA interrupt\r\n");
/*
* TODO: implement handler
*/
return false;
}
bool irq6_interrupt_handler(uint32_t sf1, uint32_t sf2)
{
bool handled = false;
MCF_EPORT_EPFR |= (1 << 6); /* clear int6 from edge port */
if (video_sbt != 0 && (video_sbt - 0x70000000) > MCF_SLT0_SCNT)
{
video_addr_timeout();
handled = true;
}
/*
* check if ACSI DMA interrupt
*/
if (FALCON_MFP_IERA & (1 << 7))
{
/* ACSI interrupt is enabled */
if (FALCON_MFP_IPRA & (1 << 7))
{
irq6_acsi_dma_interrupt();
handled = true;
}
}
if (FALCON_MFP_IPRA || FALCON_MFP_IPRB)
{
blink_led();
}
return handled;
}

View File

@@ -56,6 +56,8 @@
#include "firebee.h" #include "firebee.h"
#elif defined(MACHINE_M5484LITE) #elif defined(MACHINE_M5484LITE)
#include "m5484l.h" #include "m5484l.h"
#elif defined(MACHINE_M54455)
#include "m54455.h"
#else #else
#error "unknown machine!" #error "unknown machine!"
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
@@ -80,7 +82,7 @@ inline uint32_t set_asid(uint32_t value)
"movec %[value],ASID\n\t" "movec %[value],ASID\n\t"
: /* no output */ : /* no output */
: [value] "r" (value) : [value] "r" (value)
: :
); );
rt_asid = value; rt_asid = value;
@@ -88,7 +90,7 @@ inline uint32_t set_asid(uint32_t value)
return ret; return ret;
} }
/* /*
* set ACRx register * set ACRx register
* saves new value to rt_acrx and returns former value * saves new value to rt_acrx and returns former value
@@ -97,7 +99,7 @@ inline uint32_t set_acr0(uint32_t value)
{ {
extern uint32_t rt_acr0; extern uint32_t rt_acr0;
uint32_t ret = rt_acr0; uint32_t ret = rt_acr0;
__asm__ __volatile__( __asm__ __volatile__(
"movec %[value],ACR0\n\t" "movec %[value],ACR0\n\t"
: /* not output */ : /* not output */
@@ -117,7 +119,7 @@ inline uint32_t set_acr1(uint32_t value)
{ {
extern uint32_t rt_acr1; extern uint32_t rt_acr1;
uint32_t ret = rt_acr1; uint32_t ret = rt_acr1;
__asm__ __volatile__( __asm__ __volatile__(
"movec %[value],ACR1\n\t" "movec %[value],ACR1\n\t"
: /* not output */ : /* not output */
@@ -138,7 +140,7 @@ inline uint32_t set_acr2(uint32_t value)
{ {
extern uint32_t rt_acr2; extern uint32_t rt_acr2;
uint32_t ret = rt_acr2; uint32_t ret = rt_acr2;
__asm__ __volatile__( __asm__ __volatile__(
"movec %[value],ACR2\n\t" "movec %[value],ACR2\n\t"
: /* not output */ : /* not output */
@@ -158,7 +160,7 @@ inline uint32_t set_acr3(uint32_t value)
{ {
extern uint32_t rt_acr3; extern uint32_t rt_acr3;
uint32_t ret = rt_acr3; uint32_t ret = rt_acr3;
__asm__ __volatile__( __asm__ __volatile__(
"movec %[value],ACR3\n\t" "movec %[value],ACR3\n\t"
: /* not output */ : /* not output */
@@ -193,7 +195,7 @@ void mmu_init(void)
uint32_t MMUBAR = (uint32_t) &_MMUBAR[0]; uint32_t MMUBAR = (uint32_t) &_MMUBAR[0];
extern uint8_t _TOS[]; extern uint8_t _TOS[];
uint32_t TOS = (uint32_t) &_TOS[0]; uint32_t TOS = (uint32_t) &_TOS[0];
set_asid(0); /* do not use address extension (ASID provides virtual 48 bit addresses */ set_asid(0); /* do not use address extension (ASID provides virtual 48 bit addresses */
/* set data access attributes in ACR0 and ACR1 */ /* set data access attributes in ACR0 and ACR1 */
@@ -203,29 +205,38 @@ void mmu_init(void)
ACR_AMM(0) | /* control region > 16 MB */ ACR_AMM(0) | /* control region > 16 MB */
ACR_S(ACR_S_ALL) | /* match addresses in user and supervisor mode */ ACR_S(ACR_S_ALL) | /* match addresses in user and supervisor mode */
ACR_E(1) | /* enable ACR */ ACR_E(1) | /* enable ACR */
#if MACHINE_FIREBEE #if defined(MACHINE_FIREBEE)
ACR_ADMSK(0x3f) | /* cover 1GB area from 0xc0000000 to 0xffffffff */ ACR_ADMSK(0x7f) | /* cover 1GB area from 0xc0000000 to 0xffffffff */
ACR_BA(0xc0000000)); /* (equals area from 3 to 4 GB */ ACR_BA(0x80000000)); /* (equals area from 3 to 4 GB */
#elif MACHINE_M5484LITE #elif defined(MACHINE_M5484LITE)
ACR_ADMSK(0x7f) | /* cover 2 GB area from 0x80000000 to 0xffffffff */ ACR_ADMSK(0x7f) | /* cover 2 GB area from 0x80000000 to 0xffffffff */
ACR_BA(0x80000000)); ACR_BA(0x80000000));
#elif defined(MACHINE_M54455)
ACR_ADMSK(0x7f) |
ACR_BA(0x80000000)); /* FIXME: not determined yet */
#else
#error unknown machine!
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
// set_acr1(0x601fc000); // set_acr1(0x601fc000);
set_acr1(ACR_W(0) | set_acr1(ACR_W(0) |
ACR_SP(0) | ACR_SP(0) |
ACR_CM(0) | ACR_CM(0) |
#if MACHINE_FIREBEE #if defined(MACHINE_FIREBEE)
ACR_CM(ACR_CM_CACHEABLE_WT) | /* video RAM on the Firebee */ ACR_CM(ACR_CM_CACHEABLE_WT) | /* video RAM on the Firebee */
#elif MACHINE_M5484LITE #elif defined(MACHINE_M5484LITE)
ACR_CM(ACR_CM_CACHE_INH_PRECISE) | /* Compact Flash on the M548xLITE */ ACR_CM(ACR_CM_CACHE_INH_PRECISE) | /* Compact Flash on the M548xLITE */
#elif defined(MACHINE_M54455)
ACR_CM(ACR_CM_CACHE_INH_PRECISE) | /* FIXME: not determined yet */
#else
#error unknown machine!
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
ACR_AMM(0) | ACR_AMM(0) |
ACR_S(ACR_S_ALL) | ACR_S(ACR_S_ALL) |
ACR_E(1) | ACR_E(1) |
ACR_ADMSK(0x1f) | ACR_ADMSK(0x1f) |
ACR_BA(0x60000000)); ACR_BA(0x60000000));
/* set instruction access attributes in ACR2 and ACR3 */ /* set instruction access attributes in ACR2 and ACR3 */
//set_acr2(0xe007c400); //set_acr2(0xe007c400);
@@ -273,7 +284,7 @@ void mmu_init(void)
* mapped to physical address 0x60d0'0000 (FPGA video memory) * mapped to physical address 0x60d0'0000 (FPGA video memory)
* video RAM: read write execute normal write true * video RAM: read write execute normal write true
*/ */
MCF_MMU_MMUTR = 0x00d00000 | /* virtual address */ MCF_MMU_MMUTR = 0x00d00000 | /* virtual address */
#if defined(MACHINE_FIREBEE) #if defined(MACHINE_FIREBEE)
MCF_MMU_MMUTR_ID(SCA_PAGE_ID) | MCF_MMU_MMUTR_ID(SCA_PAGE_ID) |
@@ -285,6 +296,10 @@ void mmu_init(void)
MCF_MMU_MMUDR = 0x60d00000 | /* physical address */ MCF_MMU_MMUDR = 0x60d00000 | /* physical address */
#elif defined(MACHINE_M5484LITE) #elif defined(MACHINE_M5484LITE)
MCF_MMU_MMUDR = 0x00d00000 | /* physical address */ MCF_MMU_MMUDR = 0x00d00000 | /* physical address */
#elif defined(MACHINE_M54455)
MCF_MMU_MMUDR = 0x60d00000 | /* FIXME: not determined yet */
#else
#error unknown machine!
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
MCF_MMU_MMUDR_SZ(0) | /* 1 MB page size */ MCF_MMU_MMUDR_SZ(0) | /* 1 MB page size */
MCF_MMU_MMUDR_CM(0x0) | /* cachable writethrough */ MCF_MMU_MMUDR_CM(0x0) | /* cachable writethrough */
@@ -370,7 +385,7 @@ void mmu_init(void)
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ITLB | /* instruction */ MCF_MMU_MMUOR = MCF_MMU_MMUOR_ITLB | /* instruction */
MCF_MMU_MMUOR_ACC | /* access TLB */ MCF_MMU_MMUOR_ACC | /* access TLB */
MCF_MMU_MMUOR_UAA; /* update allocation address field */ MCF_MMU_MMUOR_UAA; /* update allocation address field */
/* /*
* Map (locked) the very last MB of physical SDRAM (this is where the driver buffers reside) to the same * Map (locked) the very last MB of physical SDRAM (this is where the driver buffers reside) to the same
* virtual address. Used uncached for drivers. * virtual address. Used uncached for drivers.

View File

@@ -1,3 +1,4 @@
/* /*
* This object file must be the first to be linked, * This object file must be the first to be linked,
* so it will be placed at the very beginning of the ROM. * so it will be placed at the very beginning of the ROM.
@@ -49,7 +50,8 @@ _rom_entry:
lea __SUP_SP,a7 lea __SUP_SP,a7
move.l #0,(sp) move.l #0,(sp)
/* Initialize the processor caches. /*
* Initialize the processor caches.
* The instruction cache is fully enabled. * The instruction cache is fully enabled.
* The data cache is enabled, but cache-inhibited by default. * The data cache is enabled, but cache-inhibited by default.
* Later, the MMU will fully activate the data cache for specific areas. * Later, the MMU will fully activate the data cache for specific areas.

View File

@@ -2,7 +2,7 @@
* File: sysinit.c * File: sysinit.c
* Purpose: Power-on Reset configuration of the Firebee board. * Purpose: Power-on Reset configuration of the Firebee board.
* *
* Notes: * Notes:
* *
* This file is part of BaS_gcc. * This file is part of BaS_gcc.
* *
@@ -37,14 +37,17 @@
#include "wait.h" #include "wait.h"
#include "util.h" #include "util.h"
#include "version.h" #include "version.h"
#ifdef MACHINE_FIREBEE #if defined(MACHINE_FIREBEE)
#include "firebee.h" #include "firebee.h"
#endif /* MACHINE_FIREBEE */ #elif defined(MACHINE_M5484LITE)
#ifdef MACHINE_M5484LITE
#include "m5484l.h" #include "m5484l.h"
#elif defined(MACHINE_M54455)
#include "m54455.h"
#else
#error "unknown machine"
#endif /* MACHINE_M5484LITE */ #endif /* MACHINE_M5484LITE */
#
#include "dma.h" #include "dma.h"
#include "mod_devicetable.h" #include "mod_devicetable.h"
#include "pci_ids.h" #include "pci_ids.h"
@@ -52,12 +55,14 @@
#include "usb.h" #include "usb.h"
#include "video.h" #include "video.h"
#define UNUSED(x) (void)(x) /* Unused variable */ #define UNUSED(x) (void)(x) /* Unused variable */
bool fpga_configured = false; /* for FPGA JTAG configuration */
extern volatile long _VRAM; /* start address of video ram from linker script */ extern volatile long _VRAM; /* start address of video ram from linker script */
/* /*
* init SLICE TIMER 0 * init SLICE TIMER 0
* all = 32.538 sec = 30.736mHz * all = 32.538 sec = 30.736mHz
* BYT0 = 127.1ms/tick = 7.876Hz offset 0 * BYT0 = 127.1ms/tick = 7.876Hz offset 0
* BYT1 = 496.5us/tick = 2.014kHz offset 1 * BYT1 = 496.5us/tick = 2.014kHz offset 1
@@ -86,16 +91,16 @@ void init_gpio(void)
* configure all four 547x GPIO module DMA pins: * configure all four 547x GPIO module DMA pins:
* *
* /DACK1 - DMA acknowledge 1 * /DACK1 - DMA acknowledge 1
* /DACK0 - DMA acknowledge 0 * /DACK0 - DMA acknowledge 0
* /DREQ1 - DMA request 1 * /DREQ1 - DMA request 1
* /DREQ0 - DMA request 0 * /DREQ0 - DMA request 0
* *
* for DMA operation * for DMA operation
*/ */
MCF_PAD_PAR_DMA = MCF_PAD_PAR_DMA_PAR_DACK0(0b11) | MCF_PAD_PAR_DMA = MCF_PAD_PAR_DMA_PAR_DACK0(0x3) |
MCF_PAD_PAR_DMA_PAR_DACK1(0b11) | MCF_PAD_PAR_DMA_PAR_DACK1(0x3) |
MCF_PAD_PAR_DMA_PAR_DREQ1(0b11) | MCF_PAD_PAR_DMA_PAR_DREQ1(0x3) |
MCF_PAD_PAR_DMA_PAR_DREQ0(0b11); MCF_PAD_PAR_DMA_PAR_DREQ0(0x3);
/* /*
* configure FEC0 pin assignment on GPIO module as FEC0 * configure FEC0 pin assignment on GPIO module as FEC0
@@ -204,20 +209,6 @@ void init_gpio(void)
MCF_PAD_PAR_TIMER_PAR_TOUT3 | MCF_PAD_PAR_TIMER_PAR_TOUT3 |
MCF_PAD_PAR_TIMER_PAR_TIN2(MCF_PAD_PAR_TIMER_PAR_TIN2_IRQ2) | MCF_PAD_PAR_TIMER_PAR_TIN2(MCF_PAD_PAR_TIMER_PAR_TIN2_IRQ2) |
MCF_PAD_PAR_TIMER_PAR_TOUT2; MCF_PAD_PAR_TIMER_PAR_TOUT2;
#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 */
#endif /* MACHINE_FIREBEE */
} }
/* /*
@@ -427,27 +418,27 @@ void init_fbcs()
#if MACHINE_FIREBEE /* FBC setup for FireBee */ #if MACHINE_FIREBEE /* FBC setup for FireBee */
MCF_FBCS1_CSAR = 0xFFF00000; /* ATARI I/O ADRESS */ MCF_FBCS1_CSAR = 0xFFF00000; /* ATARI I/O ADRESS */
MCF_FBCS1_CSCR = MCF_FBCS_CSCR_PS_16 /* 16BIT PORT */ MCF_FBCS1_CSCR = MCF_FBCS_CSCR_PS_16 /* 16BIT PORT */
| MCF_FBCS_CSCR_WS(8) /* DEFAULT 8WS */ | MCF_FBCS_CSCR_WS(8) /* DEFAULT 8WS */
| MCF_FBCS_CSCR_AA; /* AA */ | MCF_FBCS_CSCR_AA; /* AA */
MCF_FBCS1_CSMR = MCF_FBCS_CSMR_BAM_1M | MCF_FBCS_CSMR_V; MCF_FBCS1_CSMR = MCF_FBCS_CSMR_BAM_1M | MCF_FBCS_CSMR_V;
MCF_FBCS2_CSAR = 0xF0000000; // NEUER I/O ADRESS-BEREICH MCF_FBCS2_CSAR = 0xF0000000; // NEUER I/O ADRESS-BEREICH
MCF_FBCS2_CSCR = MCF_FBCS_CSCR_PS_32 // 32BIT PORT MCF_FBCS2_CSCR = MCF_FBCS_CSCR_PS_32 // 32BIT PORT
| MCF_FBCS_CSCR_WS(8) // DEFAULT 4WS | MCF_FBCS_CSCR_WS(8) // DEFAULT 4WS
| MCF_FBCS_CSCR_AA; // AA | MCF_FBCS_CSCR_AA; // AA
MCF_FBCS2_CSMR = (MCF_FBCS_CSMR_BAM_128M // F000'0000-F7FF'FFFF MCF_FBCS2_CSMR = (MCF_FBCS_CSMR_BAM_128M // F000'0000-F7FF'FFFF
| MCF_FBCS_CSMR_V); | MCF_FBCS_CSMR_V);
MCF_FBCS3_CSAR = 0xF8000000; // NEUER I/O ADRESS-BEREICH MCF_FBCS3_CSAR = 0xF8000000; // NEUER I/O ADRESS-BEREICH
MCF_FBCS3_CSCR = MCF_FBCS_CSCR_PS_16 // 16BIT PORT MCF_FBCS3_CSCR = MCF_FBCS_CSCR_PS_16 // 16BIT PORT
| MCF_FBCS_CSCR_AA; // AA | MCF_FBCS_CSCR_AA; // AA
MCF_FBCS3_CSMR = (MCF_FBCS_CSMR_BAM_64M // F800'0000-FBFF'FFFF MCF_FBCS3_CSMR = (MCF_FBCS_CSMR_BAM_64M // F800'0000-FBFF'FFFF
| MCF_FBCS_CSMR_V); | MCF_FBCS_CSMR_V);
MCF_FBCS4_CSAR = 0x40000000; // VIDEO RAM BEREICH, #FB_CS3 WIRD NICHT BENÜTZT, DECODE DIREKT AUF DEM FPGA MCF_FBCS4_CSAR = 0x40000000; // VIDEO RAM BEREICH, #FB_CS3 WIRD NICHT BENÜTZT, DECODE DIREKT AUF DEM FPGA
MCF_FBCS4_CSCR = MCF_FBCS_CSCR_PS_32 // 32BIT PORT MCF_FBCS4_CSCR = MCF_FBCS_CSCR_PS_32 // 32BIT PORT
| MCF_FBCS_CSCR_BSTR // BURST READ ENABLE | MCF_FBCS_CSCR_BSTR // BURST READ ENABLE
| MCF_FBCS_CSCR_BSTW; // BURST WRITE ENABLE | MCF_FBCS_CSCR_BSTW; // BURST WRITE ENABLE
MCF_FBCS4_CSMR = MCF_FBCS_CSMR_BAM_1G // 4000'0000-7FFF'FFFF MCF_FBCS4_CSMR = MCF_FBCS_CSMR_BAM_1G // 4000'0000-7FFF'FFFF
| MCF_FBCS_CSMR_V; | MCF_FBCS_CSMR_V;
#elif MACHINE_M5484LITE #elif MACHINE_M5484LITE
@@ -462,7 +453,7 @@ void init_fbcs()
| MCF_FBCS_CSCR_WS(32) | MCF_FBCS_CSCR_WS(32)
| MCF_FBCS_CSCR_ASET(1) | MCF_FBCS_CSCR_ASET(1)
| MCF_FBCS_CSCR_AA; | MCF_FBCS_CSCR_AA;
MCF_FBCS5_CSMR = MCF_FBCS_CSMR_BAM_256M MCF_FBCS5_CSMR = MCF_FBCS_CSMR_BAM_256M
| MCF_FBCS_CSMR_V; | MCF_FBCS_CSMR_V;
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
@@ -580,7 +571,7 @@ void init_video_ddr(void) {
/* /*
* probe for NEC compatible USB host controller and install if found * probe for NEC compatible USB host controller and install if found
*/ */
void init_usb(void) void init_usb(void)
{ {
extern struct pci_device_id ohci_usb_pci_table[]; extern struct pci_device_id ohci_usb_pci_table[];
extern struct pci_device_id ehci_usb_pci_table[]; extern struct pci_device_id ehci_usb_pci_table[];
@@ -666,18 +657,20 @@ static bool i2c_bus_free(void)
/* /*
* TFP410 (DVI) on * TFP410 (DVI) on
*/ */
void dvi_on(void) { void dvi_on(void)
{
uint8_t receivedByte; uint8_t receivedByte;
uint8_t dummyByte; /* only used for a dummy read */ uint8_t dummyByte; /* only used for a dummy read */
int num_tries = 0; int num_tries = 0;
xprintf("DVI digital video output initialization: "); xprintf("DVI digital video output initialization: ");
MCF_I2C_I2FDR = 0x3c; /* divide system clock by 1280: 100kHz standard */ MCF_I2C_I2FDR = 0x3c; /* divide system clock by 1280: 100kHz standard */
do { do
{
/* disable all i2c interrupt routing targets */ /* disable all i2c interrupt routing targets */
MCF_I2C_I2ICR = 0x0; //~(MCF_I2C_I2ICR_IE | MCF_I2C_I2ICR_RE | MCF_I2C_I2ICR_TE | MCF_I2C_I2ICR_BNBE); MCF_I2C_I2ICR = 0x0; // ~(MCF_I2C_I2ICR_IE | MCF_I2C_I2ICR_RE | MCF_I2C_I2ICR_TE | MCF_I2C_I2ICR_BNBE);
/* disable i2c, disable i2c interrupts, slave, receive, i2c = acknowledge, no repeat start */ /* disable i2c, disable i2c interrupts, slave, receive, i2c = acknowledge, no repeat start */
MCF_I2C_I2CR = 0x0; MCF_I2C_I2CR = 0x0;
@@ -814,16 +807,16 @@ void init_ac97(void) {
int va; int va;
int vb; int vb;
int vc; int vc;
xprintf("AC97 sound chip initialization: "); xprintf("AC97 sound chip initialization: ");
MCF_PAD_PAR_PSC2 = MCF_PAD_PAR_PSC2_PAR_RTS2_RTS // PSC2=TX,RX BCLK,CTS->AC'97 MCF_PAD_PAR_PSC2 = MCF_PAD_PAR_PSC2_PAR_RTS2_RTS // PSC2=TX,RX BCLK,CTS->AC'97
| MCF_PAD_PAR_PSC2_PAR_CTS2_BCLK | MCF_PAD_PAR_PSC2_PAR_CTS2_BCLK
| MCF_PAD_PAR_PSC2_PAR_TXD2 | MCF_PAD_PAR_PSC2_PAR_TXD2
| MCF_PAD_PAR_PSC2_PAR_RXD2; | MCF_PAD_PAR_PSC2_PAR_RXD2;
MCF_PSC2_PSCMR1 = 0x0; MCF_PSC2_PSCMR1 = 0x0;
MCF_PSC2_PSCMR2 = 0x0; MCF_PSC2_PSCMR2 = 0x0;
MCF_PSC2_PSCIMR = 0x0300; MCF_PSC2_PSCIMR = 0x0300;
MCF_PSC2_PSCSICR = 0x03; //AC97 MCF_PSC2_PSCSICR = 0x03; //AC97
MCF_PSC2_PSCRFCR = 0x0f000000; MCF_PSC2_PSCRFCR = 0x0f000000;
MCF_PSC2_PSCTFCR = 0x0f000000; MCF_PSC2_PSCTFCR = 0x0f000000;
MCF_PSC2_PSCRFAR = 0x00F0; MCF_PSC2_PSCRFAR = 0x00F0;
@@ -844,7 +837,7 @@ void init_ac97(void) {
{ {
MCF_PSC2_PSCTB_AC97 = 0x0; //SLOT2-12:WR REG ALLES 0 MCF_PSC2_PSCTB_AC97 = 0x0; //SLOT2-12:WR REG ALLES 0
} }
// read register // read register
MCF_PSC2_PSCTB_AC97 = 0xc0000000; //START SLOT1 + SLOT2, FIRST FRAME MCF_PSC2_PSCTB_AC97 = 0xc0000000; //START SLOT1 + SLOT2, FIRST FRAME
MCF_PSC2_PSCTB_AC97 = 0x82000000; //SLOT1:master volume MCF_PSC2_PSCTB_AC97 = 0x82000000; //SLOT1:master volume
@@ -854,7 +847,7 @@ void init_ac97(void) {
MCF_PSC2_PSCTB_AC97 = 0x00000000; //SLOT2-12:RD REG ALLES 0 MCF_PSC2_PSCTB_AC97 = 0x00000000; //SLOT2-12:RD REG ALLES 0
} }
wait(50); wait(50);
va = MCF_PSC2_PSCTB_AC97; va = MCF_PSC2_PSCTB_AC97;
if ((va & 0x80000fff) == 0x80000800) { if ((va & 0x80000fff) == 0x80000800) {
vb = MCF_PSC2_PSCTB_AC97; vb = MCF_PSC2_PSCTB_AC97;
@@ -958,10 +951,10 @@ void initialize_hardware(void)
* (volatile uint32_t *) 0x43a = 0x237698aa; /* memval2 TOS system variable */ * (volatile uint32_t *) 0x43a = 0x237698aa; /* memval2 TOS system variable */
* (volatile uint32_t *) 0x51a = 0x5555aaaa; /* memval3 TOS system variable */ * (volatile uint32_t *) 0x51a = 0x5555aaaa; /* memval3 TOS system variable */
/* TT-RAM */ /* TT-RAM */
* (uint32_t *) 0x5a4 = FASTRAM_END; /* ramtop TOS system variable */ * (uint32_t *) 0x5a4 = FASTRAM_END; /* ramtop TOS system variable */
* (uint32_t *) 0x5a8 = 0x1357bd13; /* ramvalid TOS system variable */ * (uint32_t *) 0x5a8 = 0x1357bd13; /* ramvalid TOS system variable */
/* Jump into FireTOS */ /* Jump into FireTOS */
typedef void void_func(void); typedef void void_func(void);
@@ -974,7 +967,7 @@ void initialize_hardware(void)
init_serial(); init_serial();
xprintf("\n\n"); xprintf("\n\n");
xprintf("%s BASIS system (BaS) v %d.%d (%s, %s)\r\n\r\n", xprintf("%s BASIS system (BaS) v %d.%d (%s, %s)\r\n\r\n",
#if MACHINE_FIREBEE #if MACHINE_FIREBEE
"Firebee" "Firebee"
#elif MACHINE_M5484LITE #elif MACHINE_M5484LITE
@@ -1052,7 +1045,7 @@ void initialize_hardware(void)
/* /*
* Determine the processor revision * Determine the processor revision
*/ */
xprintf(" (revision %d)\r\n",((MCF_SIU_JTAGID & MCF_SIU_JTAGID_REV) >> 28)); xprintf(" (revision %d)\r\n", ((MCF_SIU_JTAGID & MCF_SIU_JTAGID_REV) >> 28));
init_slt(); init_slt();
init_fbcs(); init_fbcs();
@@ -1090,6 +1083,7 @@ void initialize_hardware(void)
/* the following only makes sense _after_ DDRAM has been initialized */ /* the following only makes sense _after_ DDRAM has been initialized */
clear_bss_segment(); clear_bss_segment();
xprintf(".bss segment cleared\r\n");
if (BAS_LMA != BAS_IN_RAM) if (BAS_LMA != BAS_IN_RAM)
{ {
@@ -1103,39 +1097,17 @@ void initialize_hardware(void)
#if MACHINE_FIREBEE #if MACHINE_FIREBEE
if (coldboot) /* does not work with BDM */ if (coldboot) /* does not work with BDM */
; ;
init_fpga(); fpga_configured = init_fpga();
init_pll(); init_pll();
init_video_ddr(); init_video_ddr();
dvi_on(); dvi_on();
#ifdef _NOT_USED_
/* experimental */
{
int i;
uint32_t *scradr = (uint32_t *) 0xd00000;
for (i = 0; i < 100; i++)
{
uint32_t *p = scradr;
for (p = scradr; p < scradr + 1024 * 150L; p++)
{
*p = 0xffffffff;
}
for (p = scradr; p < scradr + 1024 * 150L; p++)
{
*p = 0x0;
}
}
}
#endif /* _NOT_USED_ */
#endif /* MACHINE_FIREBEE */ #endif /* MACHINE_FIREBEE */
driver_mem_init(); driver_mem_init();
init_pci(); init_pci();
video_init(); video_init();
/* do not try to init USB for now on the Firebee, it hangs the machine */ /* do not try to init USB for now on the Firebee, it hangs the machine */
#ifndef MACHINE_FIREBEE #ifndef MACHINE_FIREBEE
//init_usb(); //init_usb();

View File

@@ -48,7 +48,7 @@ static int usb_mouse_probe(struct usb_device *dev, unsigned int ifnum);
int usb_mouse_deregister(struct usb_device *dev) int usb_mouse_deregister(struct usb_device *dev)
{ {
dev->irq_handle = NULL; dev->irq_handle = NULL;
if(new != NULL) if (new != NULL)
{ {
driver_mem_free(new); driver_mem_free(new);
new = NULL; new = NULL;
@@ -61,8 +61,9 @@ int usb_mouse_deregister(struct usb_device *dev)
/* registering the mouse */ /* registering the mouse */
int usb_mouse_register(struct usb_device *dev) int usb_mouse_register(struct usb_device *dev)
{ {
if(!mouse_installed && (dev->devnum != -1) && (usb_mouse_probe(dev, 0) == 1)) if (!mouse_installed && (dev->devnum != -1) && (usb_mouse_probe(dev, 0) == 1))
{ /* Ok, we found a mouse */ {
/* Ok, we found a mouse */
mse_printf("USB MOUSE found (USB: %d, devnum: %d)\r\n", dev->usbnum, dev->devnum); mse_printf("USB MOUSE found (USB: %d, devnum: %d)\r\n", dev->usbnum, dev->devnum);
mouse_installed = 1; mouse_installed = 1;
dev->deregister = usb_mouse_deregister; dev->deregister = usb_mouse_deregister;
@@ -76,12 +77,12 @@ int usb_mouse_register(struct usb_device *dev)
int drv_usb_mouse_init(void) int drv_usb_mouse_init(void)
{ {
int i, j; int i, j;
if(mouse_installed) if (mouse_installed)
return -1; return -1;
/* scan all USB Devices */ /* scan all USB Devices */
for(j = 0; j < USB_MAX_BUS; j++) for (j = 0; j < USB_MAX_BUS; j++)
{ {
for(i = 0; i < USB_MAX_DEVICE; i++) for (i = 0; i < USB_MAX_DEVICE; i++)
{ {
struct usb_device *dev = usb_get_dev_index(i, j); /* get device */ struct usb_device *dev = usb_get_dev_index(i, j); /* get device */
if (dev == NULL) if (dev == NULL)
@@ -109,27 +110,27 @@ static int usb_mouse_irq(struct usb_device *dev)
int level; int level;
#endif #endif
int i, change = 0; int i, change = 0;
if((dev->irq_status != 0) || (dev->irq_act_len < 3) || (dev->irq_act_len > 8)) if ((dev->irq_status != 0) || (dev->irq_act_len < 3) || (dev->irq_act_len > 8))
{ {
mse_printf("USB MOUSE error %lX, len %d\r\n", dev->irq_status, dev->irq_act_len); mse_printf("USB MOUSE error %lX, len %d\r\n", dev->irq_status, dev->irq_act_len);
return 1; return 1;
} }
for(i = 0; i < dev->irq_act_len; i++) for (i = 0; i < dev->irq_act_len; i++)
{ {
if(new[i] != old[i]) if (new[i] != old[i])
{ {
change = 1; change = 1;
break; break;
} }
} }
if(change) if (change)
{ {
char wheel = 0, buttons, old_buttons; char wheel = 0, buttons, old_buttons;
mse_printf("USB MOUSE len:%d %02X %02X %02X %02X %02X %02X\r\n", dev->irq_act_len, new[0], new[1], new[2], new[3], new[4], new[5]); mse_printf("USB MOUSE len:%d %02X %02X %02X %02X %02X %02X\r\n", dev->irq_act_len, new[0], new[1], new[2], new[3], new[4], new[5]);
#ifdef CONFIG_USB_INTERRUPT_POLLING #ifdef CONFIG_USB_INTERRUPT_POLLING
level = set_ipl(7); /* mask interrupts */ level = set_ipl(7); /* mask interrupts */
#endif #endif
if((dev->irq_act_len >= 6) && (new[0] == 1)) /* report-ID */ if ((dev->irq_act_len >= 6) && (new[0] == 1)) /* report-ID */
{ {
buttons = new[1]; buttons = new[1];
old_buttons = old[1]; old_buttons = old[1];
@@ -143,24 +144,24 @@ static int usb_mouse_irq(struct usb_device *dev)
buttons = new[0]; buttons = new[0];
old_buttons = old[0]; old_buttons = old[0];
new[0] = ((new[0] & 1) << 1) + ((new[0] & 2) >> 1) + 0xF8; new[0] = ((new[0] & 1) << 1) + ((new[0] & 2) >> 1) + 0xF8;
if(dev->irq_act_len >= 3) if (dev->irq_act_len >= 3)
wheel = new[3]; wheel = new[3];
} }
if((buttons ^ old_buttons) & 4) /* 3rd button */ if ((buttons ^ old_buttons) & 4) /* 3rd button */
{ {
if(buttons & 4) if (buttons & 4)
{ {
usb_kbd_send_code(0x72); /* ENTER */ usb_kbd_send_code(0x72); /* ENTER */
usb_kbd_send_code(0xF2); usb_kbd_send_code(0xF2);
} }
} }
if(wheel != 0) /* actually like Eiffel */ if (wheel != 0) /* actually like Eiffel */
{ {
#define REPEAT_WHEEL 3 #define REPEAT_WHEEL 3
int i; int i;
if(wheel > 0) if (wheel > 0)
{ {
for(i = 0; i < REPEAT_WHEEL; i++) for (i = 0; i < REPEAT_WHEEL; i++)
{ {
usb_kbd_send_code(0x48); /* UP */ usb_kbd_send_code(0x48); /* UP */
usb_kbd_send_code(0xC8); usb_kbd_send_code(0xC8);
@@ -168,7 +169,7 @@ static int usb_mouse_irq(struct usb_device *dev)
} }
else else
{ {
for(i = 0; i < REPEAT_WHEEL; i++) for (i = 0; i < REPEAT_WHEEL; i++)
{ {
usb_kbd_send_code(0x50); /* DOWN */ usb_kbd_send_code(0x50); /* DOWN */
usb_kbd_send_code(0xD0); usb_kbd_send_code(0xD0);
@@ -197,24 +198,24 @@ static int usb_mouse_probe(struct usb_device *dev, unsigned int ifnum)
struct usb_interface_descriptor *iface; struct usb_interface_descriptor *iface;
struct usb_endpoint_descriptor *ep; struct usb_endpoint_descriptor *ep;
int pipe, maxp; int pipe, maxp;
if(dev->descriptor.bNumConfigurations != 1) if (dev->descriptor.bNumConfigurations != 1)
return 0; return 0;
iface = &dev->config.if_desc[ifnum]; iface = &dev->config.if_desc[ifnum];
if(iface->bInterfaceClass != 3) if (iface->bInterfaceClass != 3)
return 0; return 0;
if(iface->bInterfaceSubClass != 1) if (iface->bInterfaceSubClass != 1)
return 0; return 0;
if(iface->bInterfaceProtocol != 2) if (iface->bInterfaceProtocol != 2)
return 0; return 0;
if(iface->bNumEndpoints != 1) if (iface->bNumEndpoints != 1)
return 0; return 0;
ep = &iface->ep_desc[0]; ep = &iface->ep_desc[0];
if(!(ep->bEndpointAddress & 0x80)) if (!(ep->bEndpointAddress & 0x80))
return 0; return 0;
if((ep->bmAttributes & 3) != 3) if ((ep->bmAttributes & 3) != 3)
return 0; return 0;
new = (unsigned char *)driver_mem_alloc(8); new = (unsigned char *)driver_mem_alloc(8);
if(new == NULL) if (new == NULL)
return 0; return 0;
mse_printf("USB MOUSE found set protocol...\r\n"); mse_printf("USB MOUSE found set protocol...\r\n");
/* ok, we found a USB Mouse, install it */ /* ok, we found a USB Mouse, install it */

View File

@@ -55,14 +55,14 @@ void *memset(void *s, int c, size_t n)
} }
int memcmp(const char *s1, const char *s2, size_t max) int memcmp(const void *s1, const void *s2, size_t max)
{ {
int i; int i;
int cmp; int cmp;
for (i = 0; i < max; i++) for (i = 0; i < max; i++)
{ {
cmp = (*s1 - *s2); cmp = (* (const char *) s1 - * (const char *) s2);
if (cmp != 0) return cmp; if (cmp != 0) return cmp;
} }
return cmp; return cmp;
@@ -75,7 +75,7 @@ int strcmp(const char *s1, const char *s2)
for (i = 0; *s1++ && *s2++; i++) for (i = 0; *s1++ && *s2++; i++)
{ {
cmp * (*s1 - *s2); cmp = (*s1 - *s2);
if (cmp != 0) return cmp; if (cmp != 0) return cmp;
} }
return cmp; return cmp;

View File

@@ -34,3 +34,5 @@ printf_helper:
lea __MBAR+0x860C,a0 // PSCSTB0 transmitter buffer register lea __MBAR+0x860C,a0 // PSCSTB0 transmitter buffer register
move.b d0,(a0) // send byte move.b d0,(a0) // send byte
rts rts
// vim: set syntax=asm68k :

View File

@@ -27,5 +27,43 @@
#include <stdint.h> #include <stdint.h>
#include <MCF5475.h> #include <MCF5475.h>
#include <wait.h> #include <wait.h>
uint32_t get_timer(void)
{
return MCF_SLT_SCNT(0);
}
/*
* wait for the specified number of us on slice timer 0. Replaces the original routines that had
* the number of useconds to wait for hardcoded in their name.
*/
void wait(uint32_t us)
{
int32_t target = MCF_SLT_SCNT(0) - (us * (SYSCLK / 1000));
while (MCF_SLT_SCNT(0) - target > 0);
}
/*
* same as above, but with milliseconds wait time
*/
void wait_ms(uint32_t ms)
{
wait(ms * 1000);
}
/*
* the same as above, with a checker function which gets called while
* busy waiting and allows for an early return if it returns true
*/
bool waitfor(uint32_t us, checker_func condition)
{
int32_t target = MCF_SLT_SCNT(0) - (us * (SYSCLK / 1000));
bool res;
do
{
if ((res = (*condition)()))
return res;
} while (MCF_SLT_SCNT(0) - target > 0);
return false;
}

View File

@@ -18,7 +18,7 @@
#define DBG_MODES #define DBG_MODES
#ifdef DBG_MODES #ifdef DBG_MODES
#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0) #define dbg(format, arg...) do { xprintf("DEBUG: " format, __FUNCTION__, ##arg); } while (0)
#else #else
#define dbg(format, arg...) do { ; } while (0) #define dbg(format, arg...) do { ; } while (0)
#endif /* DBG_MODES */ #endif /* DBG_MODES */

View File

@@ -7,11 +7,10 @@
* option any later version. See doc/license.txt for details. * option any later version. See doc/license.txt for details.
*/ */
#include "config.h" #include "bas_types.h"
#include "portab.h"
#include "font.h" #include "font.h"
static const UWORD off_table[] = static const uint16_t off_table[] =
{ {
0x0000, 0x0008, 0x0010, 0x0018, 0x0020, 0x0028, 0x0030, 0x0038, 0x0000, 0x0008, 0x0010, 0x0018, 0x0020, 0x0028, 0x0030, 0x0038,
0x0040, 0x0048, 0x0050, 0x0058, 0x0060, 0x0068, 0x0070, 0x0078, 0x0040, 0x0048, 0x0050, 0x0058, 0x0060, 0x0068, 0x0070, 0x0078,
@@ -48,7 +47,7 @@ static const UWORD off_table[] =
0x0800, 0x0800,
}; };
static const UWORD dat_table[] = static const uint16_t dat_table[] =
{ {
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1104, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x1104,

View File

@@ -11,7 +11,12 @@
* option any later version. See doc/license.txt for details. * option any later version. See doc/license.txt for details.
*/ */
#define DBG_VIDEL 0 #define DBG_VIDEL
#ifdef DBG_VIDEL
#define dbg(format, arg...) do { xprintf("DEBUG: %s(): " format, __FUNCTION__, ##arg); } while (0)
#else
#define dbg(format, arg...) do { ; } while (0)
#endif /* DBG_VIDEL */
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
@@ -300,14 +305,14 @@ static uint16_t get_videl_bpp(void)
static uint16_t get_videl_width(void) static uint16_t get_videl_width(void)
{ {
return (*(volatile uint16_t *)0xffff8210) * 16 / get_videl_bpp(); return ( * (volatile uint16_t *) 0xffff8210) * 16 / get_videl_bpp();
} }
static uint16_t get_videl_height(void) static uint16_t get_videl_height(void)
{ {
uint16_t vdb = *(volatile uint16_t *)0xffff82a8; uint16_t vdb = * (volatile uint16_t *) 0xffff82a8;
uint16_t vde = *(volatile uint16_t *)0xffff82aa; uint16_t vde = * (volatile uint16_t *) 0xffff82aa;
uint16_t vmode = *(volatile uint16_t *)0xffff82c2; uint16_t vmode = * (volatile uint16_t *) 0xffff82c2;
/* visible y resolution: /* visible y resolution:
* Graphics display starts at line VDB and ends at line * Graphics display starts at line VDB and ends at line
@@ -332,11 +337,14 @@ const VMODE_ENTRY *lookup_videl_mode(int16_t mode,int16_t monitor)
{ {
const VMODE_ENTRY *vmode_init_table, *p; const VMODE_ENTRY *vmode_init_table, *p;
if (mode&VIDEL_VGA) { if (mode&VIDEL_VGA)
{
vmode_init_table = vga_init_table; vmode_init_table = vga_init_table;
/* ignore bits that don't affect initialisation data */ /* ignore bits that don't affect initialisation data */
mode &= ~(VIDEL_VERTICAL|VIDEL_PAL); mode &= ~(VIDEL_VERTICAL|VIDEL_PAL);
} else { }
else
{
vmode_init_table = nonvga_init_table; vmode_init_table = nonvga_init_table;
} }
@@ -368,34 +376,38 @@ static int16_t determine_width(int16_t mode)
/* /*
* determine vctl based on video mode and monitor type * determine vctl based on video mode and monitor type
*/ */
static int16_t determine_vctl(int16_t mode,int16_t monitor) static int16_t determine_vctl(int16_t mode, int16_t monitor)
{ {
int16_t vctl; int16_t vctl;
if (mode&VIDEL_VGA) { if (mode & VIDEL_VGA)
vctl = (mode&VIDEL_80COL) ? 0x08 : 0x04; {
if (mode&VIDEL_VERTICAL) vctl = (mode & VIDEL_80COL) ? 0x08 : 0x04;
if (mode & VIDEL_VERTICAL)
vctl |= 0x01; vctl |= 0x01;
} else { }
vctl = (mode&VIDEL_80COL) ? 0x04 : 0x00; else
if (mode&VIDEL_VERTICAL) {
vctl = (mode & VIDEL_80COL) ? 0x04 : 0x00;
if (mode & VIDEL_VERTICAL)
vctl |= 0x02; vctl |= 0x02;
} }
if (!(mode&VIDEL_COMPAT)) if (!(mode & VIDEL_COMPAT))
return vctl; return vctl;
switch(mode&VIDEL_BPPMASK) { switch (mode & VIDEL_BPPMASK)
case VIDEL_1BPP: {
if (!(mode&VIDEL_VGA) && (monitor == MON_MONO)) case VIDEL_1BPP:
vctl = 0x08; if (!(mode & VIDEL_VGA) && (monitor == MON_MONO))
break; vctl = 0x08;
case VIDEL_2BPP: break;
vctl = (mode&VIDEL_VGA)? 0x09 : 0x04; case VIDEL_2BPP:
break; vctl = (mode & VIDEL_VGA)? 0x09 : 0x04;
case VIDEL_4BPP: break;
vctl = (mode&VIDEL_VGA)? 0x05 : 0x00; case VIDEL_4BPP:
break; vctl = (mode & VIDEL_VGA)? 0x05 : 0x00;
break;
} }
return vctl; return vctl;
@@ -407,25 +419,28 @@ static int16_t determine_vctl(int16_t mode,int16_t monitor)
*/ */
static int16_t determine_regc0(int16_t mode,int16_t monitor) static int16_t determine_regc0(int16_t mode,int16_t monitor)
{ {
if (mode&VIDEL_VGA) if (mode & VIDEL_VGA)
return 0x0186; return 0x0186;
if (!(mode&VIDEL_COMPAT)) if (!(mode & VIDEL_COMPAT))
return (monitor==MON_TV)?0x0183:0x0181; return (monitor == MON_TV) ? 0x0183 : 0x0181;
/* handle ST-compatible modes */ /* handle ST-compatible modes */
if ((mode&(VIDEL_80COL|VIDEL_BPPMASK)) == (VIDEL_80COL|VIDEL_1BPP)) { /* 80-column, 2-colour */ if ((mode & (VIDEL_80COL | VIDEL_BPPMASK)) == (VIDEL_80COL | VIDEL_1BPP))
switch(monitor) { {
case MON_MONO: /* 80-column, 2-colour */
return 0x0080; switch(monitor)
case MON_TV: {
return 0x0183; case MON_MONO:
default: return 0x0080;
return 0x0181; case MON_TV:
return 0x0183;
default:
return 0x0181;
} }
} }
return (monitor==MON_TV)?0x0083:0x0081; return (monitor == MON_TV) ? 0x0083 : 0x0081;
} }
@@ -445,7 +460,7 @@ static int set_videl_vga(int16_t mode)
if (!p) if (!p)
return -1; return -1;
videlregs[0x0a] = (mode&VIDEL_PAL) ? 2 : 0; /* video sync to 50Hz if PAL */ videlregs[0x0a] = (mode & VIDEL_PAL) ? 2 : 0; /* video sync to 50Hz if PAL */
// FIXME: vsync() can't work if the screen is initially turned off // FIXME: vsync() can't work if the screen is initially turned off
//vsync(); /* wait for vbl so we're not interrupted :-) */ //vsync(); /* wait for vbl so we're not interrupted :-) */
@@ -476,28 +491,30 @@ static int set_videl_vga(int16_t mode)
videlword(0xc0) = determine_regc0(mode,monitor); videlword(0xc0) = determine_regc0(mode,monitor);
videlword(0x66) = 0x0000; /* clear SPSHIFT */ videlword(0x66) = 0x0000; /* clear SPSHIFT */
switch(mode&VIDEL_BPPMASK) { /* set SPSHIFT / ST shift */ switch(mode & VIDEL_BPPMASK)
case VIDEL_1BPP: /* 2 colours (mono) */ {
if (monitor == MON_MONO) /* set SPSHIFT / ST shift */
videlregs[0x60] = 0x02; case VIDEL_1BPP: /* 2 colours (mono) */
else videlword(0x66) = 0x0400; if (monitor == MON_MONO)
break; videlregs[0x60] = 0x02;
case VIDEL_2BPP: /* 4 colours */ else videlword(0x66) = 0x0400;
videlregs[0x60] = 0x01; break;
videlword(0x10) = linewidth; /* writing to the ST shifter has */ case VIDEL_2BPP: /* 4 colours */
videlword(0xc2) = vctl; /* just overwritten these registers */ videlregs[0x60] = 0x01;
break; videlword(0x10) = linewidth; /* writing to the ST shifter has */
case VIDEL_4BPP: /* 16 colours */ videlword(0xc2) = vctl; /* just overwritten these registers */
/* if not ST-compatible, SPSHIFT was already set correctly above */ break;
if (mode&VIDEL_COMPAT) case VIDEL_4BPP: /* 16 colours */
videlregs[0x60] = 0x00; /* else set ST shifter */ /* if not ST-compatible, SPSHIFT was already set correctly above */
break; if (mode & VIDEL_COMPAT)
case VIDEL_8BPP: /* 256 colours */ videlregs[0x60] = 0x00; /* else set ST shifter */
videlword(0x66) = 0x0010; break;
break; case VIDEL_8BPP: /* 256 colours */
case VIDEL_TRUECOLOR: /* 65536 colours (Truecolor) */ videlword(0x66) = 0x0010;
videlword(0x66) = 0x0100; break;
break; case VIDEL_TRUECOLOR: /* 65536 colours (Truecolor) */
videlword(0x66) = 0x0100;
break;
} }
return 0; return 0;
@@ -518,8 +535,8 @@ int16_t vsetmode(int16_t mode)
if (mode == -1) if (mode == -1)
return current_video_mode; return current_video_mode;
#if DBG_VIDEL #ifdef DBG_VIDEL
kprintf("vsetmode(0x%04x)\n", mode); xprintf("vsetmode(0x%04x)\n", mode);
#endif #endif
if (set_videl_vga(mode) < 0) /* invalid mode */ if (set_videl_vga(mode) < 0) /* invalid mode */
@@ -577,26 +594,30 @@ int32_t vgetsize(int16_t mode)
monitor = vmontype(); monitor = vmontype();
mode &= VIDEL_VALID; /* ignore invalid bits */ mode &= VIDEL_VALID; /* ignore invalid bits */
if ((mode&VIDEL_BPPMASK) > VIDEL_TRUECOLOR) { /* fixup invalid bpp */ if ((mode & VIDEL_BPPMASK) > VIDEL_TRUECOLOR)
{
/* fixup invalid bpp */
mode &= ~VIDEL_BPPMASK; mode &= ~VIDEL_BPPMASK;
mode |= VIDEL_TRUECOLOR; mode |= VIDEL_TRUECOLOR;
} }
p = lookup_videl_mode(mode,monitor); p = lookup_videl_mode(mode, monitor);
if (!p) { /* invalid mode */ if (!p)
if (mode&VIDEL_COMPAT) {
/* invalid mode */
if (mode & VIDEL_COMPAT)
return ST_VRAM_SIZE; return ST_VRAM_SIZE;
mode &= ~(VIDEL_OVERSCAN|VIDEL_PAL);/* ignore less-important bits */ mode &= ~(VIDEL_OVERSCAN|VIDEL_PAL);/* ignore less-important bits */
p = lookup_videl_mode(mode,monitor);/* & try again */ p = lookup_videl_mode(mode, monitor);/* & try again */
if (!p) /* "can't happen" */ if (!p) /* "can't happen" */
return FALCON_VRAM_SIZE; return FALCON_VRAM_SIZE;
} }
vctl = determine_vctl(mode,monitor); vctl = determine_vctl(mode, monitor);
height = p->vde - p->vdb; height = p->vde - p->vdb;
if (!(vctl&0x02)) if (!(vctl & 0x02))
height >>= 1; height >>= 1;
if (vctl&0x01) if (vctl & 0x01)
height >>= 1; height >>= 1;
return (int32_t)determine_width(mode) * 2 * height; return (int32_t)determine_width(mode) * 2 * height;
@@ -605,18 +626,21 @@ int32_t vgetsize(int16_t mode)
/* /*
* convert from Falcon palette format to STe palette format * convert from Falcon palette format to STe palette format
*/ */
#define falc2ste(a) ((((a)>>1)&0x08)|(((a)>>5)&0x07)) #define falc2ste(a) ((((a) >> 1) & 0x08) | (((a) >> 5) & 0x07))
static void convert2ste(int16_t *ste,int32_t *falcon) static void convert2ste(int16_t *ste,int32_t *falcon)
{ {
union { union
{
int32_t l; int32_t l;
uint8_t b[4]; uint8_t b[4];
} u; } u;
int i; int i;
for (i = 0; i < 16; i++) { for (i = 0; i < 16; i++)
{
u.l = *falcon++; u.l = *falcon++;
*ste++ = (falc2ste(u.b[0])<<8) | (falc2ste(u.b[1])<<4) | falc2ste(u.b[3]); *ste++ = (falc2ste(u.b[0]) << 8) | (falc2ste(u.b[1]) << 4) | falc2ste(u.b[3]);
} }
} }
@@ -629,10 +653,10 @@ static int use_ste_palette(int16_t videomode)
if (vmontype() == MON_MONO) /* always for ST mono monitor */ if (vmontype() == MON_MONO) /* always for ST mono monitor */
return true; return true;
if ((videomode&VIDEL_BPPMASK) == VIDEL_2BPP) /* always for 4-colour modes */ if ((videomode & VIDEL_BPPMASK) == VIDEL_2BPP) /* always for 4-colour modes */
return true; return true;
if ((videomode&VIDEL_COMPAT) && ((videomode&VIDEL_BPPMASK) == VIDEL_4BPP)) if ((videomode & VIDEL_COMPAT) && ((videomode & VIDEL_BPPMASK) == VIDEL_4BPP))
return true; /* and for ST low */ return true; /* and for ST low */
return false; return false;
@@ -652,10 +676,11 @@ static int use_ste_palette(int16_t videomode)
* address | 0x01 load first 16 Falcon palette regs from address * address | 0x01 load first 16 Falcon palette regs from address
* 0 | 0x01 load 256 Falcon palette regs from falcon_shadow_palette[] * 0 | 0x01 load 256 Falcon palette regs from falcon_shadow_palette[]
*/ */
int16_t vsetrgb(int16_t index,int16_t count,int32_t *rgb) int16_t vsetrgb(int16_t index,int16_t count, int32_t *rgb)
{ {
int32_t *shadow, *source; int32_t *shadow, *source;
union { union
{
int32_t l; int32_t l;
uint8_t b[4]; uint8_t b[4];
} u; } u;
@@ -664,8 +689,8 @@ int16_t vsetrgb(int16_t index,int16_t count,int32_t *rgb)
if ((index < 0) || (count <= 0)) if ((index < 0) || (count <= 0))
return -1; /* Generic error */ return -1; /* Generic error */
limit = (get_videl_bpp()<=4) ? 16 : 256; limit = (get_videl_bpp() <= 4) ? 16 : 256;
if ((index+count) > limit) if ((index + count) > limit)
return -1; /* Generic error */ return -1; /* Generic error */
/* /*
@@ -674,7 +699,7 @@ int16_t vsetrgb(int16_t index,int16_t count,int32_t *rgb)
*/ */
shadow = falcon_shadow_palette + index; shadow = falcon_shadow_palette + index;
source = rgb; source = rgb;
while(count--) { while (count--) {
u.l = *source++; u.l = *source++;
u.b[0] = u.b[1]; /* shift R & G */ u.b[0] = u.b[1]; /* shift R & G */
u.b[1] = u.b[2]; u.b[1] = u.b[2];
@@ -696,7 +721,7 @@ int16_t vsetrgb(int16_t index,int16_t count,int32_t *rgb)
return 0; /* OK */ return 0; /* OK */
} }
colorptr = (limit==256) ? (int16_t *) 0x01L : (int16_t *) ((int32_t) falcon_shadow_palette|0x01L); colorptr = (limit == 256) ? (int16_t *) 0x01L : (int16_t *) ((int32_t) falcon_shadow_palette|0x01L);
set_palette(colorptr); set_palette(colorptr);
return 0; /* OK */ return 0; /* OK */
@@ -708,7 +733,8 @@ int16_t vsetrgb(int16_t index,int16_t count,int32_t *rgb)
int16_t vgetrgb(int16_t index,int16_t count,int32_t *rgb) int16_t vgetrgb(int16_t index,int16_t count,int32_t *rgb)
{ {
int32_t *shadow; int32_t *shadow;
union { union
{
int32_t l; int32_t l;
uint8_t b[4]; uint8_t b[4];
} u; } u;
@@ -717,12 +743,13 @@ int16_t vgetrgb(int16_t index,int16_t count,int32_t *rgb)
if ((index < 0) || (count <= 0)) if ((index < 0) || (count <= 0))
return -1; /* Generic error */ return -1; /* Generic error */
limit = (get_videl_bpp()<=4) ? 16 : 256; limit = (get_videl_bpp() <= 4) ? 16 : 256;
if ((index+count) > limit) if ((index + count) > limit)
return -1; /* Generic error */ return -1; /* Generic error */
shadow = falcon_shadow_palette + index; shadow = falcon_shadow_palette + index;
while(count--) { while (count--)
{
u.l = *shadow++; u.l = *shadow++;
u.b[2] = u.b[1]; /* shift R & G right*/ u.b[2] = u.b[1]; /* shift R & G right*/
u.b[1] = u.b[0]; u.b[1] = u.b[0];
@@ -769,7 +796,7 @@ int16_t vfixmode(int16_t mode)
if (mode & VIDEL_VGA) /* if mode has VGA set, */ if (mode & VIDEL_VGA) /* if mode has VGA set, */
mode ^= (VIDEL_VERTICAL | VIDEL_VGA); /* clear it & flip vertical */ mode ^= (VIDEL_VERTICAL | VIDEL_VGA); /* clear it & flip vertical */
if (mode & VIDEL_COMPAT) { if (mode & VIDEL_COMPAT) {
if ((mode&VIDEL_BPPMASK) == VIDEL_1BPP) if ((mode & VIDEL_BPPMASK) == VIDEL_1BPP)
mode |= VIDEL_VERTICAL; /* set vertical for ST high */ mode |= VIDEL_VERTICAL; /* set vertical for ST high */
else mode &= ~VIDEL_VERTICAL; /* clear it for ST medium, low */ else mode &= ~VIDEL_VERTICAL; /* clear it for ST medium, low */
} }
@@ -786,7 +813,7 @@ int16_t videl_check_moderez(int16_t moderez)
current_mode = get_videl_mode(); current_mode = get_videl_mode();
return_mode = vfixmode(moderez);/* adjust */ return_mode = vfixmode(moderez);/* adjust */
return (return_mode==current_mode)?0:return_mode; return (return_mode == current_mode) ? 0 : return_mode;
} }
uint32_t videl_vram_size(void) uint32_t videl_vram_size(void)
@@ -832,7 +859,7 @@ void initialise_falcon_palette(int16_t mode)
* although it is probably not important since we don't use those * although it is probably not important since we don't use those
* registers. * registers.
*/ */
limit = ((mode&VIDEL_BPPMASK)==VIDEL_8BPP) ? 256 : 16; limit = ((mode & VIDEL_BPPMASK) == VIDEL_8BPP) ? 256 : 16;
for (i = 0; i < limit; i++) for (i = 0; i < limit; i++)
fcol_regs[i] = falcon_shadow_palette[i]; fcol_regs[i] = falcon_shadow_palette[i];
@@ -840,7 +867,7 @@ void initialise_falcon_palette(int16_t mode)
* if appropriate, set up the STe shadow & real palette registers * if appropriate, set up the STe shadow & real palette registers
*/ */
if (use_ste_palette(mode)) { if (use_ste_palette(mode)) {
convert2ste(ste_shadow_palette,falcon_shadow_palette); convert2ste(ste_shadow_palette, falcon_shadow_palette);
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
col_regs[i] = ste_shadow_palette[i]; col_regs[i] = ste_shadow_palette[i];
} }

View File

@@ -61,3 +61,5 @@ _xhdi_sd_install:
move.l #_xhdi_vec,d0 // return our BaS vector to TOS move.l #_xhdi_vec,d0 // return our BaS vector to TOS
move.l d0,a0 // move.l d0,a0 //
rte rte
// vim: set syntax=asm68k :