Compare commits

...

55 Commits

Author SHA1 Message Date
Markus Fröschle
705c9610f3 branched to enable main branch to return to the old MMU handling code since the new style couldn't be made to work (for now). 2014-06-20 16:06:08 +00:00
Markus Fröschle
69c982c795 moved FPGA config GPIO initialization into init_fpga.c to enable external JTAG FPGA configuration 2014-06-20 12:02:11 +00:00
David Gálvez
4d40bd775a make PCI memory non-cacheable 2014-05-25 19:13:45 +00:00
David Gálvez
d98727a182 add missing parameter initialization 2014-05-25 17:00:19 +00:00
Markus Fröschle
927833d601 eliminated wrong types warning when calling memcpy() 2014-05-12 07:40:55 +00:00
Markus Fröschle
65a7986e34 reformatted 2014-05-11 20:38:33 +00:00
Markus Fröschle
ccec42e55c modified dbg() in several files 2014-05-11 20:31:57 +00:00
Markus Fröschle
dc646c75ad reformatted assembler code 2014-05-11 14:08:27 +00:00
Markus Fröschle
b0fb7b8df3 fixed wrong MMU mapping of emulated Falcon video memory (phys and virt
where the wrong way round)
2014-05-11 06:57:09 +00:00
Markus Fröschle
fb9c4aaa1d modified project to support Qt Creator inferior debugging through BDM. 2014-05-11 06:40:48 +00:00
Markus Fröschle
2f311aedbf modified dbg() macro
corrected irq6 handler
reimplemented MFP interrupt LED blinker in C
2014-05-10 13:21:11 +00:00
Markus Fröschle
5a836c6ca7 reformatted assembly 2014-04-22 10:47:36 +00:00
Markus Fröschle
e94becff75 added to QtCreator 2014-04-22 10:44:56 +00:00
Markus Fröschle
dee448549c translated copy loop to C 2014-02-04 20:06:29 +00:00
Markus Fröschle
fcd3b885ce started "translating" MMU update code for video pages 2014-02-04 07:17:51 +00:00
Markus Fröschle
91ae86a487 completed page loop 2014-02-03 21:42:25 +00:00
Markus Fröschle
25f66ae7f9 more conversion to C 2014-02-02 22:27:10 +00:00
Markus Fröschle
fe5b7d466d translated more of the assembler code into C 2014-02-02 21:35:46 +00:00
Markus Fröschle
ff3514c2d0 added missing include file to SVN 2014-02-02 10:16:16 +00:00
Markus Fröschle
90371bb3c9 optimized for size - reduces codesize by half 2014-02-01 23:54:32 +00:00
Markus Fröschle
5a557524b0 moved PSC3 interrupt handler to C code 2014-02-01 23:37:30 +00:00
Markus Fröschle
1fb6c756ae modified to throw errors if an unknown machine type is detected 2014-01-28 15:49:05 +00:00
Markus Fröschle
8a1da417e7 modified ACR settings 2014-01-28 14:11:08 +00:00
Markus Fröschle
703352fc9d added m54455 (Freescale EVB) platform 2014-01-21 14:52:46 +00:00
Markus Fröschle
6a6e7cf84e fixed: compare virtual address instead of physical in lookup_mapping() 2014-01-21 12:43:32 +00:00
Markus Fröschle
430f03a8ed fixed bug in determining if access error hit in TLB (checked bit 0 instead of 1). 2014-01-20 14:23:55 +00:00
Markus Fröschle
d3fb521ad1 modified MMU mapping table to use symbolic constants from include file 2014-01-19 19:26:52 +00:00
Markus Fröschle
bf8cea26ab simplified MMU code. Still hangs somewhere in EmuTOS 2014-01-19 18:27:05 +00:00
Markus Fröschle
0f5942436a removed locked MMU pages 2014-01-18 20:59:42 +00:00
Markus Fröschle
8544307830 removed inlining in wait.c, added (simple) map-based MMU handling 2014-01-18 14:03:25 +00:00
Markus Fröschle
386a921f84 modified to map memory dynamically based on a static memory map 2014-01-18 08:04:44 +00:00
Markus Fröschle
58418f2436 moved ACR register handling macros to include file 2014-01-17 06:45:33 +00:00
Markus Fröschle
8025af85dd modified access_error to do all MMU mappings dynamically 2014-01-16 20:42:04 +00:00
Markus Fröschle
1c316ec11b extended mmu_map_page() by size and flags args 2014-01-16 16:29:29 +00:00
Markus Fröschle
3779d1cb2e modified ACRs to cover complete SDRAM 2014-01-16 16:18:43 +00:00
Markus Fröschle
c9c76a4757 test using ACR0 & ACR2 to provide supervisor stack access 2014-01-15 16:03:54 +00:00
Markus Fröschle
afa9490c1e fixed typo in strcmp() 2014-01-15 07:17:21 +00:00
Markus Fröschle
26cadc699a fixed formatting 2014-01-14 21:39:05 +00:00
Markus Fröschle
9da82d046b modified comments 2014-01-14 21:15:56 +00:00
Markus Fröschle
4112590363 moved page alignment responsibility to caller 2014-01-14 20:28:13 +00:00
Markus Fröschle
fdf945c702 fixed missing parameter in debug print 2014-01-14 18:18:20 +00:00
Markus Fröschle
9b89377caf removed type field from isr_register_handler() and friends 2014-01-14 07:48:38 +00:00
Markus Fröschle
3966bfd6ec fixed comments 2014-01-13 22:05:20 +00:00
Markus Fröschle
bdf5cd6c0d added vim modeline to asm sources. Needs "set modeline:set modeline=5" in .vimrc 2014-01-13 21:34:24 +00:00
Markus Fröschle
ba1a951952 cleaned up debug printouts 2014-01-13 21:30:39 +00:00
Markus Fröschle
fcb5204fc8 renamed mmutr_miss() to mmu_map_page() (that's what its doing) 2014-01-13 21:26:42 +00:00
Markus Fröschle
63b19853a9 corrected FASTRAM_END comparision 2014-01-13 21:20:24 +00:00
Markus Fröschle
be94d72097 refactored assembler routines from exceptions.S into mmu.c (access exception handler). Seems to be better, but still hang. 2014-01-13 19:39:42 +00:00
Markus Fröschle
9b099d935c implemented safe stack for access exception handler 2014-01-13 15:13:29 +00:00
Markus Fröschle
a97469a53d switch to a safe stack in access_exception.
Assembles, but not tested yet.
2014-01-13 07:19:09 +00:00
Markus Fröschle
3a1c07a2e8 added better matching descriptive text to debug messages 2014-01-08 13:57:35 +00:00
Markus Fröschle
4f29f6af80 FEC interrupts to level 1 2014-01-08 09:59:44 +00:00
Markus Fröschle
8d53a1feb9 fixed - carelessly choosen - interrupt level for FEC interrupts 2014-01-08 09:01:43 +00:00
Markus Fröschle
99e5352807 changed MAC address to original address dbug assigns 2014-01-07 10:50:22 +00:00
Markus Fröschle
785ca43b11 cleaned up 2014-01-07 05:57:17 +00:00
47 changed files with 2165 additions and 1461 deletions

View File

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

1
BaS_gcc.config Normal file
View File

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

1
BaS_gcc.creator Normal file
View File

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

231
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

2
BaS_gcc.includes Normal file
View File

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

View File

@@ -15,7 +15,7 @@ ifeq (Y,$(COMPILE_ELF))
TCPREFIX=m68k-elf-
EXE=elf
FORMAT=elf32-m68k
else
else
TCPREFIX=m68k-atari-mint-
EXE=s19
FORMAT=srec
@@ -32,20 +32,21 @@ NATIVECC=gcc
INCLUDE=-Iinclude
CFLAGS=-mcpu=5474 \
-Wall \
-Os \
-g3 \
-fomit-frame-pointer \
-ffreestanding \
-fleading-underscore \
-Wa,--register-prefix-optional
CFLAGS_OPTIMIZED = -mcpu=5474 \
-Wall \
-g3 \
-O2 \
-fomit-frame-pointer \
-ffreestanding \
-fleading-underscore \
-Wa,--register-prefix-optional
TRGTDIRS= ./firebee ./m5484lite
TRGTDIRS= ./firebee ./m5484lite ./m54455
OBJDIRS=$(patsubst %, %/objs,$(TRGTDIRS))
TOOLDIR=util
@@ -135,7 +136,7 @@ CSRCS= \
x86pcibios.c \
\
basflash.c \
basflash_start.c
basflash_start.c
ASRCS= \
@@ -170,32 +171,35 @@ clean:
# flags for targets
m5484lite/bas.$(EXE): MACHINE=MACHINE_M5484LITE
m54455/bas.$(EXE): MACHINE=MACHINE_M54455
firebee/bas.$(EXE): MACHINE=MACHINE_FIREBEE
m5484lite/ram.$(EXE): MACHINE=MACHINE_M5484LITE
m54455/ram.$(EXE): MACHINE=MACHINE_M54455
firebee/ram.$(EXE): MACHINE=MACHINE_FIREBEE
m5484lite/basflash.$(EXE): MACHINE=MACHINE_M5484LITE
m54455/basflash.$(EXE): MACHINE=MACHINE_M54455
firebee/basflash.$(EXE): MACHINE=MACHINE_FIREBEE
#
# generate pattern rules for different object files
#
define CC_TEMPLATE
ifeq (firebee,$(1))
MACHINE=MACHINE_FIREBEE
else
MACHINE=MACHINE_M5484LITE
endif
#ifeq (firebee,$(1))
#MACHINE=MACHINE_FIREBEE
#else
#MACHINE=MACHINE_M5484LITE
#endif
# always optimize x86 emulator objects
$(1)/objs/x86decode.o: CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/x86sys.o: CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/x86debug.o: CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/x86prim_ops.o:CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/x86ops.o: CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/x86ops2.o: CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/x86fpu.o: CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/x86biosemu.o: CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/x86pcibios.o: CFLAGS=$(CFLAGS_OPTIMIZED)
#$(1)/objs/x86decode.o: CFLAGS=$(CFLAGS_OPTIMIZED)
#$(1)/objs/x86sys.o: CFLAGS=$(CFLAGS_OPTIMIZED)
#$(1)/objs/x86debug.o: CFLAGS=$(CFLAGS_OPTIMIZED)
#$(1)/objs/x86prim_ops.o:CFLAGS=$(CFLAGS_OPTIMIZED)
#$(1)/objs/x86ops.o: CFLAGS=$(CFLAGS_OPTIMIZED)
#$(1)/objs/x86ops2.o: CFLAGS=$(CFLAGS_OPTIMIZED)
#$(1)/objs/x86fpu.o: CFLAGS=$(CFLAGS_OPTIMIZED)
#$(1)/objs/x86biosemu.o: CFLAGS=$(CFLAGS_OPTIMIZED)
#$(1)/objs/x86pcibios.o: CFLAGS=$(CFLAGS_OPTIMIZED)
$(1)/objs/%.o:%.c
$(CC) $$(CFLAGS) -D$$(MACHINE) $(INCLUDE) -c $$< -o $$@
@@ -257,7 +261,7 @@ endif
$(1)_MAPFILE_RAM=$(1)/$$(basename $$(RAM_EXEC)).map
$(1)/$$(RAM_EXEC): $(1)/$(LIBBAS) $(LDCSRC)
$(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)
$(OBJCOPY) -O srec $$@ $$(basename $$@).s19
else
@@ -280,21 +284,21 @@ $(foreach DIR,$(TRGTDIRS),$(eval $(call EX_TEMPLATE,$(DIR))))
indent: $(CSRCS)
indent $<
.PHONY: tags
tags:
ctags $(patsubst %,%/*,$(VPATH))
.PHONY: printvars
printvars:
@$(foreach V,$(.VARIABLES), $(if $(filter-out environment% default automatic, $(origin $V)),$(warning $V=$($V))))
ifeq (MACHINE_M5484LITE,$$(MACHINE))
MNAME=m5484lite
else ifeq (MACHINE_FIREBEE,$(MACHINE))
MNAME=firebee
MNAME=firebee
endif
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

View File

@@ -1,9 +1,11 @@
#ifdef MACHINE_FIREBEE
#if defined(MACHINE_FIREBEE)
#include "firebee.h"
#endif /* MACHINE_FIREBEE */
#ifdef MACHINE_M5484LITE
#elif defined(MACHINE_M5484LITE)
#include "m5484l.h"
#elif defined(MACHINE_M54455)
#include "m54455.h"
#else
#error "unknown machine!"
#endif /* MACHINE_M5484LITE */
/* make bas_rom access flags rx if compiling to RAM */
@@ -177,6 +179,7 @@ SECTIONS
#else
__FASTRAM_END = TARGET_ADDRESS;
#endif
__FASTRAM_SIZE = __FASTRAM_END - __FASTRAM;
/* Init CS0 (BootFLASH @ E000_0000 - E07F_FFFF 8Mbytes) */
___BOOT_FLASH = BOOTFLASH_BASE_ADDRESS;

View File

@@ -29,13 +29,17 @@
#include "cache.h"
#include "exceptions.h"
#if MACHINE_FIREBEE
#if defined(MACHINE_FIREBEE)
#include "firebee.h"
#elif MACHINE_M5484LITE
#elif defined(MACHINE_M5484LITE)
#include "m5484l.h"
#elif defined(MACHINE_M54455)
#include "m54455.h"
#else
#error "unknown machine!"
#endif /* MACHINE_FIREBEE */
//#define DBG_DMA
#define DBG_DMA
#ifdef DBG_DMA
#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0)
#else
@@ -592,11 +596,15 @@ int dma_interrupt_handler(void *arg1, void *arg2)
void *dma_memcpy(void *dst, void *src, size_t n)
{
int ret;
volatile int32_t time;
volatile int32_t start;
volatile int32_t end;
#ifdef DBG_DMA
int32_t time;
int32_t start;
int32_t end;
start = MCF_SLT0_SCNT;
#endif /* DBG_DMA */
ret = MCD_startDma(1, src, 4, dst, 4, n, 4, DMA_ALWAYS, 0, MCD_SINGLE_DMA, 0);
if (ret == MCD_OK)
{
@@ -640,8 +648,10 @@ void *dma_memcpy(void *dst, void *src, size_t n)
#endif
} while (ret != MCD_DONE);
#ifdef DBG_DMA
end = MCF_SLT0_SCNT;
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);
return dst;

View File

@@ -340,6 +340,17 @@ static err_t verify(uint8_t *dst, uint8_t *src, uint32_t length)
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)
{
DRESULT res;
@@ -372,7 +383,7 @@ void srec_execute(char *flasher_filename)
{
/* next pass: copy data to destination */
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)
{
/* next pass: verify data */

View File

@@ -47,8 +47,8 @@ static struct xhdi_driver_interface xhdi_call_interface =
static struct dma_driver_interface dma_interface =
{
.version = 0x0101,
.magic = 'DMAC',
.dma_set_initiator = &dma_set_initiator,
.magic = 0x444d4143, /* 'DMAC' */
.dma_set_initiator = dma_set_initiator,
.dma_get_initiator = dma_get_initiator,
.dma_free_initiator = dma_free_initiator,
.dma_set_channel = dma_set_channel,

View File

@@ -35,6 +35,7 @@ extern char *strncat(char *dst, const char *src, size_t max);
extern int atoi(const char *c);
extern void *memcpy(void *dst, const void *src, 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);
#define isdigit(c) (((c) >= '0') && ((c) <= '9'))

View File

@@ -50,17 +50,17 @@ struct dma_driver_interface
{
int32_t version;
int32_t magic;
int32_t (*dma_set_initiator)(int32_t initiator);
uint32_t (*dma_get_initiator)(int32_t requestor);
void (*dma_free_initiator)(int32_t requestor);
int32_t (*dma_set_channel)(int32_t requestor, void (*handler)(void));
int32_t (*dma_get_channel)(int32_t requestor);
void (*dma_free_channel)(int32_t requestor);
void (*dma_clear_channel)(int32_t channel);
int32_t (*MCD_startDma)(long channel,
int8_t *srcAddr, uint32_t srcIncr, int8_t *destAddr, uint32_t destIncr,
uint32_t dmaSize, uint32_t xferSize, uint32_t initiator, int32_t priority,
uint32_t flags, uint32_t funcDesc);
int (*dma_set_initiator)(int initiator);
uint32_t (*dma_get_initiator)(int requestor);
void (*dma_free_initiator)(int requestor);
int (*dma_set_channel)(int requestor, void (*handler)(void));
int (*dma_get_channel)(int requestor);
void (*dma_free_channel)(int requestor);
void (*dma_clear_channel)(int channel);
int (*MCD_startDma)(long channel,
int8_t *srcAddr, unsigned int srcIncr, int8_t *destAddr, unsigned int destIncr,
unsigned int dmaSize, unsigned int xferSize, unsigned int initiator, int priority,
unsigned int flags, unsigned int funcDesc);
int32_t (*MCD_dmaStatus)(int32_t channel);
int32_t (*MCD_XferProgrQuery)(int32_t channel, MCD_XferProg *progRep);
int32_t (*MCD_killDma)(int32_t channel);

View File

@@ -27,7 +27,7 @@
* 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_SIZE 0x800000 /* FireBee has 8 MByte Flash */

View File

@@ -79,11 +79,11 @@
#define INT_SOURCE_GPT0 62 // GPT0 timer interrupt
#define FEC0_INTC_LVL 5 /* interrupt level for FEC0 */
#define FEC0_INTC_PRI 7 /* interrupt priority for FEC0 */
#define FEC0_INTC_LVL 1 /* interrupt level for FEC0 */
#define FEC0_INTC_PRI 2 /* interrupt priority for FEC0 */
#define FEC1_INTC_LVL 5 /* interrupt level for FEC1 */
#define FEC1_INTC_PRI 7 /* interrupt priority for FEC1 */
#define FEC1_INTC_LVL 1 /* interrupt level 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_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
extern void isr_init(void);
extern int isr_register_handler(int type, int vector, int (*handler)(void *, void *), void *hdev, void *harg);
extern void isr_remove_handler(int type ,int (*handler)(void *, void *));
extern int isr_register_handler(int vector, int (*handler)(void *, void *), void *hdev, void *harg);
extern void isr_remove_handler(int (*handler)(void *, void *));
extern bool isr_execute_handler(int vector);
#endif /* _INTERRUPTS_H_ */

View File

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

49
include/m54455.h Normal file
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"
/*
* 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 */
/*
* 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
*/
@@ -35,6 +94,6 @@ extern long video_tlb;
extern long video_sbt;
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_ */

View File

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

View File

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

View File

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

View File

@@ -29,55 +29,23 @@
#include <bas_types.h>
#if MACHINE_FIREBEE
#if defined(MACHINE_FIREBEE)
#include "firebee.h"
#elif MACHINE_M5484LITE
#elif defined(MACHINE_M5484LITE)
#include "m5484l.h"
#elif defined(MACHINE_M54455)
#include "m54455.h"
#else
#error "unknown machine"
#endif /* MACHINE_FIREBEE */
#include "MCF5475.h"
typedef bool (*checker_func)(void);
extern __inline__ void wait(uint32_t) __attribute__((always_inline));
extern __inline__ bool waitfor(uint32_t us, checker_func condition) __attribute__((always_inline));
extern void wait(uint32_t);
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_ */

View File

@@ -40,276 +40,300 @@ static unsigned char tx_queue[QUEUE_LEN];
static unsigned char wptr = 0, rptr = 0;
// structure to keep track of ikbd state
static struct {
unsigned char cmd;
unsigned char state;
unsigned char expect;
static struct
{
unsigned char cmd;
unsigned char state;
unsigned char expect;
// joystick state
unsigned char joystick[2];
// joystick state
unsigned char joystick[2];
// mouse state
unsigned short mouse_pos_x, mouse_pos_y;
unsigned char mouse_buttons;
// mouse state
unsigned short mouse_pos_x, mouse_pos_y;
unsigned char mouse_buttons;
} ikbd;
// #define IKBD_DEBUG
void ikbd_init() {
// reset ikbd state
memset(&ikbd, 0, sizeof(ikbd));
ikbd.state = IKBD_DEFAULT;
void ikbd_init()
{
// reset ikbd state
memset(&ikbd, 0, sizeof(ikbd));
ikbd.state = IKBD_DEFAULT;
}
static void enqueue(unsigned char b) {
if(((wptr + 1)&(QUEUE_LEN-1)) == rptr) {
xprintf("IKBD: !!!!!!! tx queue overflow !!!!!!!!!\n");
return;
}
static void enqueue(unsigned char b)
{
if (((wptr + 1)&(QUEUE_LEN-1)) == rptr)
{
xprintf("IKBD: !!!!!!! tx queue overflow !!!!!!!!!\n");
return;
}
tx_queue[wptr] = b;
wptr = (wptr+1)&(QUEUE_LEN-1);
tx_queue[wptr] = b;
wptr = (wptr + 1) & (QUEUE_LEN - 1);
}
// convert internal joystick format into atari ikbd format
static unsigned char joystick_map2ikbd(unsigned in) {
unsigned char out = 0;
static unsigned char joystick_map2ikbd(unsigned in)
{
unsigned char out = 0;
if(in & JOY_UP) out |= 0x01;
if(in & JOY_DOWN) out |= 0x02;
if(in & JOY_LEFT) out |= 0x04;
if(in & JOY_RIGHT) out |= 0x08;
if(in & JOY_BTN1) out |= 0x80;
if (in & JOY_UP) out |= 0x01;
if (in & JOY_DOWN) out |= 0x02;
if (in & JOY_LEFT) out |= 0x04;
if (in & JOY_RIGHT) out |= 0x08;
if (in & JOY_BTN1) out |= 0x80;
return out;
return out;
}
// process inout from atari core into ikbd
void ikbd_handle_input(unsigned char cmd) {
// expecting a second byte for command
if(ikbd.expect) {
ikbd.expect--;
void ikbd_handle_input(unsigned char cmd)
{
// expecting a second byte for command
if (ikbd.expect)
{
ikbd.expect--;
// last byte of command received
if(!ikbd.expect) {
switch(ikbd.cmd) {
case 0x07: // set mouse button action
xprintf("IKBD: mouse button action = %x\n", cmd);
// last byte of command received
if (!ikbd.expect)
{
switch(ikbd.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)
if(cmd & 0x04) ikbd.state |= IKBD_STATE_MOUSE_BUTTON_AS_KEY;
else ikbd.state &= ~IKBD_STATE_MOUSE_BUTTON_AS_KEY;
// bit 2: Mouse buttons act like keys (LEFT=0x74 & RIGHT=0x75)
if(cmd & 0x04) ikbd.state |= IKBD_STATE_MOUSE_BUTTON_AS_KEY;
else ikbd.state &= ~IKBD_STATE_MOUSE_BUTTON_AS_KEY;
break;
break;
case 0x80: // ibkd reset
// reply "everything is ok"
enqueue(0xf0);
break;
case 0x80: // ibkd reset
// reply "everything is ok"
enqueue(0xf0);
break;
default:
break;
}
default:
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 0x07:
xprintf("IKBD: Set mouse button action");
ikbd.expect = 1;
break;
case 0x08:
xprintf("IKBD: Set relative mouse positioning");
ikbd.state &= ~IKBD_STATE_MOUSE_DISABLED;
ikbd.state &= ~IKBD_STATE_MOUSE_ABSOLUTE;
break;
case 0x08:
xprintf("IKBD: Set relative mouse positioning");
ikbd.state &= ~IKBD_STATE_MOUSE_DISABLED;
ikbd.state &= ~IKBD_STATE_MOUSE_ABSOLUTE;
break;
case 0x09:
xprintf("IKBD: Set absolute mouse positioning");
ikbd.state &= ~IKBD_STATE_MOUSE_DISABLED;
ikbd.state |= IKBD_STATE_MOUSE_ABSOLUTE;
ikbd.expect = 4;
break;
case 0x09:
xprintf("IKBD: Set absolute mouse positioning");
ikbd.state &= ~IKBD_STATE_MOUSE_DISABLED;
ikbd.state |= IKBD_STATE_MOUSE_ABSOLUTE;
ikbd.expect = 4;
break;
case 0x0b:
xprintf("IKBD: Set Mouse threshold");
ikbd.expect = 2;
break;
case 0x0b:
xprintf("IKBD: Set Mouse threshold");
ikbd.expect = 2;
break;
case 0x0f:
xprintf("IKBD: Set Y at bottom");
ikbd.state |= IKBD_STATE_MOUSE_Y_BOTTOM;
break;
case 0x0f:
xprintf("IKBD: Set Y at bottom");
ikbd.state |= IKBD_STATE_MOUSE_Y_BOTTOM;
break;
case 0x10:
xprintf("IKBD: Set Y at top");
ikbd.state &= ~IKBD_STATE_MOUSE_Y_BOTTOM;
break;
case 0x10:
xprintf("IKBD: Set Y at top");
ikbd.state &= ~IKBD_STATE_MOUSE_Y_BOTTOM;
break;
case 0x12:
xprintf("IKBD: Disable mouse");
ikbd.state |= IKBD_STATE_MOUSE_DISABLED;
break;
case 0x12:
xprintf("IKBD: Disable mouse");
ikbd.state |= IKBD_STATE_MOUSE_DISABLED;
break;
case 0x14:
xprintf("IKBD: Set Joystick event reporting");
ikbd.state |= IKBD_STATE_JOYSTICK_EVENT_REPORTING;
break;
case 0x14:
xprintf("IKBD: Set Joystick event reporting");
ikbd.state |= IKBD_STATE_JOYSTICK_EVENT_REPORTING;
break;
case 0x15:
xprintf("IKBD: Set Joystick interrogation mode");
ikbd.state &= ~IKBD_STATE_JOYSTICK_EVENT_REPORTING;
break;
case 0x15:
xprintf("IKBD: Set Joystick interrogation mode");
ikbd.state &= ~IKBD_STATE_JOYSTICK_EVENT_REPORTING;
break;
case 0x16: // interrogate joystick
// send reply
enqueue(0xfd);
enqueue(joystick_map2ikbd(ikbd.joystick[0]));
enqueue(joystick_map2ikbd(ikbd.joystick[1]));
break;
case 0x16: // interrogate joystick
// send reply
enqueue(0xfd);
enqueue(joystick_map2ikbd(ikbd.joystick[0]));
enqueue(joystick_map2ikbd(ikbd.joystick[1]));
break;
case 0x1a:
xprintf("IKBD: Disable joysticks");
ikbd.state &= ~IKBD_STATE_JOYSTICK_EVENT_REPORTING;
break;
case 0x1a:
xprintf("IKBD: Disable joysticks");
ikbd.state &= ~IKBD_STATE_JOYSTICK_EVENT_REPORTING;
break;
case 0x1c:
xprintf("IKBD: Interrogate time of day");
case 0x1c:
xprintf("IKBD: Interrogate time of day");
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;
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:
xprintf("IKBD: Reset");
ikbd.expect = 1;
ikbd.state = IKBD_DEFAULT;
break;
case 0x80:
xprintf("IKBD: Reset");
ikbd.expect = 1;
ikbd.state = IKBD_DEFAULT;
break;
default:
xprintf("IKBD: unknown command: %x\n", cmd);
break;
}
default:
xprintf("IKBD: unknown command: %x\n", cmd);
break;
}
}
void ikbd_poll(void) {
static int mtimer = 0;
if(CheckTimer(mtimer)) {
mtimer = GetTimer(10);
// check for incoming ikbd data
static int mtimer = 0;
if (CheckTimer(mtimer))
{
mtimer = GetTimer(10);
// 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();
SPI(UIO_IKBD_IN);
while(SPI(0))
ikbd_handle_input(SPI(0));
SPI(UIO_IKBD_OUT);
SPI(tx_queue[rptr]);
DisableIO();
}
// send data from queue if present
if(rptr == wptr) return;
// transmit data from queue
EnableIO();
SPI(UIO_IKBD_OUT);
SPI(tx_queue[rptr]);
DisableIO();
rptr = (rptr+1)&(QUEUE_LEN-1);
rptr = (rptr + 1) & (QUEUE_LEN - 1);
}
void ikbd_joystick(unsigned char joystick, unsigned char map) {
// todo: suppress events for joystick 0 as long as mouse
// is enabled?
if(ikbd.state & IKBD_STATE_JOYSTICK_EVENT_REPORTING) {
void ikbd_joystick(unsigned char joystick, unsigned char map)
{
// todo: suppress events for joystick 0 as long as mouse
// is enabled?
if (ikbd.state & IKBD_STATE_JOYSTICK_EVENT_REPORTING)
{
#ifdef IKBD_DEBUG
xprintf("IKBD: joy %d %x\n", joystick, map);
xprintf("IKBD: joy %d %x\n", joystick, map);
#endif
// only report joystick data for joystick 0 if the mouse is disabled
if((ikbd.state & IKBD_STATE_MOUSE_DISABLED) || (joystick == 1)) {
enqueue(0xfe + joystick);
enqueue(joystick_map2ikbd(map));
// only report joystick data for joystick 0 if the mouse is disabled
if ((ikbd.state & IKBD_STATE_MOUSE_DISABLED) || (joystick == 1))
{
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
else
xprintf("IKBD: no monitor, drop joy %d %x\n", joystick, map);
else
xprintf("IKBD: no monitor, drop joy %d %x\n", joystick, map);
#endif
// save state of joystick for interrogation mode
ikbd.joystick[joystick] = map;
// save state of joystick for interrogation mode
ikbd.joystick[joystick] = map;
}
void ikbd_keyboard(unsigned char code) {
void ikbd_keyboard(unsigned char code)
{
#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
enqueue(code);
enqueue(code);
}
void ikbd_mouse(uint8_t b, int8_t x, int8_t y) {
if(ikbd.state & IKBD_STATE_MOUSE_DISABLED)
return;
void ikbd_mouse(uint8_t b, int8_t x, int8_t y)
{
if (ikbd.state & IKBD_STATE_MOUSE_DISABLED)
return;
// joystick and mouse buttons are wired together in
// atari st
b |= (ikbd.joystick[0] & JOY_BTN1)?1:0;
b |= (ikbd.joystick[1] & JOY_BTN1)?2:0;
static unsigned char b_old = 0;
// monitor state of two mouse buttons
if(b != b_old) {
// check if mouse buttons are supposed to be treated like keys
if(ikbd.state & IKBD_STATE_MOUSE_BUTTON_AS_KEY) {
// Mouse buttons act like keys (LEFT=0x74 & RIGHT=0x75)
// handle left mouse button
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));
// joystick and mouse buttons are wired together in
// atari st
b |= (ikbd.joystick[0] & JOY_BTN1)?1:0;
b |= (ikbd.joystick[1] & JOY_BTN1)?2:0;
static unsigned char b_old = 0;
// monitor state of two mouse buttons
if (b != b_old)
{
// check if mouse buttons are supposed to be treated like keys
if (ikbd.state & IKBD_STATE_MOUSE_BUTTON_AS_KEY)
{
// Mouse buttons act like keys (LEFT=0x74 & RIGHT=0x75)
// handle left mouse button
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(ikbd.state & IKBD_STATE_MOUSE_BUTTON_AS_KEY) {
b = 0;
// if mouse position is 0/0 quit here
if(!x && !y) return;
}
if(ikbd.state & IKBD_STATE_MOUSE_BUTTON_AS_KEY)
{
b = 0;
// if mouse position is 0/0 quit here
if(!x && !y) return;
}
#endif
if(ikbd.state & IKBD_STATE_MOUSE_ABSOLUTE) {
} else {
// 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);
}
if (ikbd.state & IKBD_STATE_MOUSE_ABSOLUTE)
{
}
else
{
// 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
set $vbr = 0x00000000
#monitor bdm-ctl-set 0x0801 0x00000000
set $mbar = 0xFF000000
#monitor bdm-ctl-set 0x0C0F 0xFF000000
@@ -22,30 +22,30 @@ end
define setup-dram
# Init CS0 (BootFLASH @ E000_0000 - E07F_FFFF 8Mbytes)
set *((long *) 0xFF000500) = 0xE0000000
set *((long *) 0xFF000508) = 0x00041180
set *((long *) 0xFF000504) = 0x007F0001
set *((long *) 0xFF000500) = 0xE0000000
set *((long *) 0xFF000508) = 0x00041180
set *((long *) 0xFF000504) = 0x007F0001
# set *((long *) 0xFF00050C) = 0xFFF00000 # ATARI I/O address
# SDRAM Initialization @ 0000_0000 - 1FFF_FFFF 512Mbytes
set *((long *) 0xFF000004) = 0x000002AA
set *((long *) 0xFF000020) = 0x0000001A
set *((long *) 0xFF000024) = 0x0800001A
set *((long *) 0xFF000028) = 0x1000001A
set *((long *) 0xFF00002C) = 0x1800001A
set *((long *) 0xFF000108) = 0x73622830
set *((long *) 0xFF00010C) = 0x46770000
set *((long *) 0xFF000004) = 0x000002AA
set *((long *) 0xFF000020) = 0x0000001A
set *((long *) 0xFF000024) = 0x0800001A
set *((long *) 0xFF000028) = 0x1000001A
set *((long *) 0xFF00002C) = 0x1800001A
set *((long *) 0xFF000108) = 0x73622830
set *((long *) 0xFF00010C) = 0x46770000
set *((long *) 0xFF000104) = 0xE10D0002
set *((long *) 0xFF000100) = 0x40010000
set *((long *) 0xFF000100) = 0x048D0000
set *((long *) 0xFF000104) = 0xE10D0002
set *((long *) 0xFF000104) = 0xE10D0004
set *((long *) 0xFF000104) = 0xE10D0004
set *((long *) 0xFF000100) = 0x008D0000
set *((long *) 0xFF000104) = 0x710D0F00
set *((long *) 0xFF000104) = 0xE10D0002
set *((long *) 0xFF000100) = 0x40010000
set *((long *) 0xFF000100) = 0x048D0000
set *((long *) 0xFF000104) = 0xE10D0002
set *((long *) 0xFF000104) = 0xE10D0004
set *((long *) 0xFF000104) = 0xE10D0004
set *((long *) 0xFF000100) = 0x008D0000
set *((long *) 0xFF000104) = 0x710D0F00
end
define cu
@@ -61,6 +61,11 @@ define ib
setup-dram
end
define run
continue
end
tr
ib
load
add-symbol-file ../emutos/emutos2.img 0xe00000
load firebee/ram.elf

View File

@@ -13,8 +13,10 @@
#include "firebee.h"
#elif defined(MACHINE_M5484LITE)
#include "m5484l.h"
#elif defined(MACHINE_M54455)
#include "m54455.h"
#else
#error "unknown machine"
#error "unknown machine!"
#endif
//#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))
break;
}
if (timeout >= FEC_MII_TIMEOUT)
{
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)
{
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) */
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;
}
}
#ifdef DBG_AM79

View File

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

View File

@@ -18,13 +18,15 @@
#include "firebee.h"
#elif defined(MACHINE_M5484LITE)
#include "m5484l.h"
#elif defined(MACHINE_M54455)
#include "m54455.h"
#else
#error "Unknown machine!"
#endif
#define 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
#define dbg(format, arg...) do { ; } while (0)
#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 */
fec_mii_init(fec_ch, SYSCLK / 1000);
dbg("%s: PHY reset\r\n", __FUNCTION__);
dbg("PHY reset\r\n");
/* Reset the PHY */
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)
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);
@@ -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))
return 0;
dbg("%s: PHY Enable Auto-Negotiation\r\n", __FUNCTION__);
dbg("PHY Enable Auto-Negotiation\r\n");
/* Enable Auto-Negotiation */
if (!fec_mii_write(fec_ch, phy_addr, BCM5222_CTRL, (BCM5222_CTRL_ANE | BCM5222_CTRL_RESTART_AN)))
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 */
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)
{
dbg("%s: PHY auto-negociation complete\r\n", __FUNCTION__);
dbg("PHY auto-negociation complete\r\n");
/* Read Auxiliary Control/Status Register */
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
{
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) */
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
fec_duplex(fec_ch, FEC_MII_HALF_DUPLEX);
dbg("%s: PHY Mode: ", __FUNCTION__);
dbg("PHY Mode: ");
if (settings & BCM5222_ACSR_100BTX)
dbg("%s: 100Mbps\r\n", __FUNCTION__);
dbg("100Mbps\r\n");
else
dbg("%s: 10Mbps\r\n", __FUNCTION__);
dbg("10Mbps\r\n");
if (settings & BCM5222_ACSR_FDX)
dbg("%s: Full-duplex\r\n", __FUNCTION__);
dbg("Full-duplex\r\n");
else
dbg("%s: Half-duplex\r\n", __FUNCTION__);
dbg("Half-duplex\r\n");
return 1;
}

View File

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

144
net/fec.c
View File

@@ -17,21 +17,24 @@
#include "bas_string.h"
#include "bas_printf.h"
#include "util.h"
#include "wait.h"
#include "am79c874.h"
#include "bcm5222.h"
//#include "bcm5222.h"
#include <stdbool.h>
#if defined(MACHINE_FIREBEE)
#include "firebee.h"
#elif defined(MACHINE_M5484LITE)
#include "m5484l.h"
#elif defined(MACHINE_M54455)
#include "m54455.h"
#else
#error Unknown machine!
#endif
//#define DBG_FEC
#define 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
#define dbg(format, arg...) do { ; } while (0)
#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++)
{
wait(1);
if (MCF_FEC_EIR(ch) & MCF_FEC_EIR_MII)
break;
}
if(timeout == FEC_MII_TIMEOUT)
if (timeout == FEC_MII_TIMEOUT)
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++)
{
wait(1);
if (MCF_FEC_EIR(ch) & MCF_FEC_EIR_MII)
break;
}
if(timeout == FEC_MII_TIMEOUT)
if (timeout == FEC_MII_TIMEOUT)
return 0;
/*
@@ -232,33 +237,33 @@ void fec_log_init(uint8_t ch)
*/
void fec_log_dump(uint8_t ch)
{
dbg("%s: \r\n FEC%d Log\r\n", __FUNCTION__, ch);
dbg("%s: ---------------\r\n", __FUNCTION__);
dbg("%s: Total: %4d\r\n", __FUNCTION__, fec_log[ch].total);
dbg("%s: hberr: %4d\r\n", __FUNCTION__, fec_log[ch].hberr);
dbg("%s: babr: %4d\r\n", __FUNCTION__, fec_log[ch].babr);
dbg("%s: babt: %4d\r\n", __FUNCTION__, fec_log[ch].babt);
dbg("%s: gra: %4d\r\n", __FUNCTION__, fec_log[ch].gra);
dbg("%s: txf: %4d\r\n", __FUNCTION__, fec_log[ch].txf);
dbg("%s: mii: %4d\r\n", __FUNCTION__, fec_log[ch].mii);
dbg("%s: lc: %4d\r\n", __FUNCTION__, fec_log[ch].lc);
dbg("%s: rl: %4d\r\n", __FUNCTION__, fec_log[ch].rl);
dbg("%s: xfun: %4d\r\n", __FUNCTION__, fec_log[ch].xfun);
dbg("%s: xferr: %4d\r\n", __FUNCTION__, fec_log[ch].xferr);
dbg("%s: rferr: %4d\r\n", __FUNCTION__, fec_log[ch].rferr);
dbg("%s: dtxf: %4d\r\n", __FUNCTION__, fec_log[ch].dtxf);
dbg("%s: drxf: %4d\r\n", __FUNCTION__, fec_log[ch].drxf);
dbg("%s: \r\nRFSW:\r\n", __FUNCTION__);
dbg("%s: inv: %4d\r\n", __FUNCTION__, fec_log[ch].rfsw_inv);
dbg("%s: m: %4d\r\n", __FUNCTION__, fec_log[ch].rfsw_m);
dbg("%s: bc: %4d\r\n", __FUNCTION__, fec_log[ch].rfsw_bc);
dbg("%s: mc: %4d\r\n", __FUNCTION__, fec_log[ch].rfsw_mc);
dbg("%s: lg: %4d\r\n", __FUNCTION__, fec_log[ch].rfsw_lg);
dbg("%s: no: %4d\r\n", __FUNCTION__, fec_log[ch].rfsw_no);
dbg("%s: cr: %4d\r\n", __FUNCTION__, fec_log[ch].rfsw_cr);
dbg("%s: ov: %4d\r\n", __FUNCTION__, fec_log[ch].rfsw_ov);
dbg("%s: tr: %4d\r\n", __FUNCTION__, fec_log[ch].rfsw_tr);
dbg("%s: ---------------\r\n\r\n", __FUNCTION__);
dbg("\r\n FEC%d Log\r\n", __FUNCTION__, ch);
dbg(" ---------------\r\n", __FUNCTION__);
dbg(" Total: %4d\r\n", fec_log[ch].total);
dbg(" hberr: %4d\r\n", fec_log[ch].hberr);
dbg(" babr: %4d\r\n", fec_log[ch].babr);
dbg(" babt: %4d\r\n", fec_log[ch].babt);
dbg(" gra: %4d\r\n", fec_log[ch].gra);
dbg(" txf: %4d\r\n", fec_log[ch].txf);
dbg(" mii: %4d\r\n", fec_log[ch].mii);
dbg(" lc: %4d\r\n", fec_log[ch].lc);
dbg(" rl: %4d\r\n", fec_log[ch].rl);
dbg(" xfun: %4d\r\n", fec_log[ch].xfun);
dbg(" xferr: %4d\r\n", fec_log[ch].xferr);
dbg(" rferr: %4d\r\n", fec_log[ch].rferr);
dbg(" dtxf: %4d\r\n", fec_log[ch].dtxf);
dbg(" drxf: %4d\r\n", fec_log[ch].drxf);
dbg(" \r\nRFSW:\r\n");
dbg(" inv: %4d\r\n", fec_log[ch].rfsw_inv);
dbg(" m: %4d\r\n", fec_log[ch].rfsw_m);
dbg(" bc: %4d\r\n", fec_log[ch].rfsw_bc);
dbg(" mc: %4d\r\n", fec_log[ch].rfsw_mc);
dbg(" lg: %4d\r\n", fec_log[ch].rfsw_lg);
dbg(" no: %4d\r\n", fec_log[ch].rfsw_no);
dbg(" cr: %4d\r\n", fec_log[ch].rfsw_cr);
dbg(" ov: %4d\r\n", fec_log[ch].rfsw_ov);
dbg(" tr: %4d\r\n", fec_log[ch].rfsw_tr);
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_MAX_FL(ETH_MAX_FRM)
//#ifdef FEC_PROMISCUOUS
| MCF_FEC_RCR_PROM
//#endif
| MCF_FEC_RCR_FCE;
if (mode == FEC_MODE_MII)
@@ -541,13 +544,13 @@ void fec_rx_start(uint8_t ch, int8_t *rxbd)
* Make the initiator assignment
*/
res = dma_set_initiator(DMA_FEC_RX(ch));
dbg("%s: dma_set_initiator(DMA_FEC_RX(%d)): %d\r\n", __FUNCTION__, ch, res);
dbg("dma_set_initiator(DMA_FEC_RX(%d)): %d\r\n", ch, res);
/*
* Grab the initiator number
*/
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
@@ -555,7 +558,7 @@ void fec_rx_start(uint8_t ch, int8_t *rxbd)
*/
channel = dma_set_channel(DMA_FEC_RX(ch),
(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
@@ -580,7 +583,7 @@ void fec_rx_start(uint8_t ch, int8_t *rxbd)
| MCD_NO_CSUM
| 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 +607,13 @@ void fec_rx_continue(uint8_t 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
*/
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);
}
/*
@@ -668,7 +671,7 @@ void fec_rx_frame(uint8_t ch, NIF *nif)
NBUF *cur_nbuf, *new_nbuf;
int keep;
dbg("%s: started\r\n", __FUNCTION__);
dbg("started\r\n");
while ((pRxBD = fecbd_rx_alloc(ch)) != NULL)
{
@@ -730,7 +733,7 @@ void fec_rx_frame(uint8_t ch, NIF *nif)
new_nbuf = nbuf_alloc();
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
@@ -786,7 +789,7 @@ void fec_rx_frame(uint8_t ch, NIF *nif)
else
{
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
@@ -850,13 +853,13 @@ void fec_tx_start(uint8_t ch, int8_t *txbd)
* Make the initiator assignment
*/
res = dma_set_initiator(DMA_FEC_TX(ch));
dbg("%s: dma_set_initiator(%d) = %d\r\n", __FUNCTION__, ch, res);
dbg("dma_set_initiator(%d) = %d\r\n", ch, res);
/*
* Grab the initiator number
*/
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 +868,7 @@ void fec_tx_start(uint8_t ch, int8_t *txbd)
*/
channel = dma_set_channel(DMA_FEC_TX(ch),
(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
@@ -890,7 +893,7 @@ void fec_tx_start(uint8_t ch, int8_t *txbd)
| MCD_NO_CSUM
| MCD_NO_BYTE_SWAP
);
dbg("%s: DMA tx task started\r\n", __FUNCTION__);
dbg("DMA tx task started\r\n");
}
/*
@@ -913,14 +916,13 @@ void fec_tx_continue(uint8_t ch)
* selected FEC
*/
channel = dma_get_channel(DMA_FEC_TX(ch));
dbg("%s: dma_get_channel(DMA_FEC_TX(%d)) = %d\r\n",
__FUNCTION__, ch, channel);
dbg("dma_get_channel(DMA_FEC_TX(%d)) = %d\r\n", ch, channel);
/*
* Continue/restart the DMA task
*/
MCD_continDma(channel);
dbg("%s: DMA TX task continue\r\n", __FUNCTION__);
dbg("DMA TX task continue\r\n");
}
/*
@@ -994,7 +996,7 @@ void fec_tx_frame(uint8_t ch)
NBUF *pNbuf;
bool is_empty = true;
dbg("%s:\r\n", __FUNCTION__);
dbg("\r\n");
while ((pTxBD = fecbd_tx_free(ch)) != NULL)
{
fec_log[ch].dtxf++;
@@ -1008,7 +1010,7 @@ void fec_tx_frame(uint8_t ch)
* Free up the network buffer that was just transmitted
*/
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
@@ -1019,7 +1021,7 @@ void fec_tx_frame(uint8_t ch)
}
if (is_empty)
dbg("%s: transmit queue was empty!\r\n", __FUNCTION__);
dbg("transmit queue was empty!\r\n");
}
void fec0_tx_frame(void)
@@ -1057,8 +1059,8 @@ int fec_send(uint8_t ch, NIF *nif, uint8_t *dst, uint8_t *src, uint16_t type, NB
/* Check the length */
if ((nbuf->length + ETH_HDR_LEN) > ETH_MTU)
{
dbg("%s: nbuf->length (%d) + ETH_HDR_LEN (%d) exceeds ETH_MTU (%d)\r\n",
__FUNCTION__, nbuf->length, ETH_HDR_LEN, ETH_MTU);
dbg("nbuf->length (%d) + ETH_HDR_LEN (%d) exceeds ETH_MTU (%d)\r\n",
nbuf->length, ETH_HDR_LEN, ETH_MTU);
return 0;
}
@@ -1190,7 +1192,7 @@ static void fec_irq_handler(uint8_t ch)
event = eir & MCF_FEC_EIMR(ch);
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
@@ -1201,8 +1203,8 @@ static void fec_irq_handler(uint8_t ch)
{
fec_log[ch].total++;
fec_log[ch].rferr++;
dbg("%s: RFERR\r\n", __FUNCTION__);
dbg("%s: FECRFSR%d = 0x%08x\r\n", __FUNCTION__, ch, MCF_FEC_FECRFSR(ch));
dbg("RFERR\r\n");
dbg("FECRFSR%d = 0x%08x\r\n", ch, MCF_FEC_FECRFSR(ch));
//fec_eth_stop(ch);
}
@@ -1210,14 +1212,14 @@ static void fec_irq_handler(uint8_t ch)
{
fec_log[ch].total++;
fec_log[ch].xferr++;
dbg("%s: XFERR\r\n", __FUNCTION__);
dbg("XFERR\r\n");
}
if (event & MCF_FEC_EIR_XFUN)
{
fec_log[ch].total++;
fec_log[ch].xfun++;
dbg("%s: XFUN\r\n", __FUNCTION__);
dbg("XFUN\r\n");
//fec_eth_stop(ch);
}
@@ -1225,54 +1227,54 @@ static void fec_irq_handler(uint8_t ch)
{
fec_log[ch].total++;
fec_log[ch].rl++;
dbg("%s: RL\r\n", __FUNCTION__);
dbg("RL\r\n");
}
if (event & MCF_FEC_EIR_LC)
{
fec_log[ch].total++;
fec_log[ch].lc++;
dbg("%s: LC\r\n", __FUNCTION__);
dbg("LC\r\n");
}
if (event & MCF_FEC_EIR_MII)
{
fec_log[ch].mii++;
dbg("%s: MII\r\n", __FUNCTION__);
dbg("MII\r\n");
}
if (event & MCF_FEC_EIR_TXF)
{
fec_log[ch].txf++;
dbg("%s: TXF\r\n", __FUNCTION__);
dbg("TXF\r\n");
fec_log_dump(0);
}
if (event & MCF_FEC_EIR_GRA)
{
fec_log[ch].gra++;
dbg("%s: GRA\r\n", __FUNCTION__);
dbg("GRA\r\n");
}
if (event & MCF_FEC_EIR_BABT)
{
fec_log[ch].total++;
fec_log[ch].babt++;
dbg("%s: BABT\r\n", __FUNCTION__);
dbg("BABT\r\n");
}
if (event & MCF_FEC_EIR_BABR)
{
fec_log[ch].total++;
fec_log[ch].babr++;
dbg("%s: BABR\r\n", __FUNCTION__);
dbg("BABR\r\n");
}
if (event & MCF_FEC_EIR_HBERR)
{
fec_log[ch].total++;
fec_log[ch].hberr++;
dbg("%s: HBERR\r\n", __FUNCTION__);
dbg("HBERR\r\n");
}
}
@@ -1342,9 +1344,9 @@ void fec_eth_setup(uint8_t ch, uint8_t trcvr, uint8_t speed, uint8_t duplex, con
*/
#if defined(MACHINE_FIREBEE)
if (am79c874_init(0, 0, speed, duplex))
dbg("%s: PHY init completed\r\n", __FUNCTION__);
dbg("PHY init completed\r\n");
else
dbg("%s: PHY init failed\r\n", __FUNCTION__);
dbg("PHY init failed\r\n");
#elif defined(MACHINE_M548X)
bcm_5222_init(0, 0, speed, duplex);
#else
@@ -1397,7 +1399,7 @@ void fec_eth_stop(uint8_t ch)
*/
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
*/

View File

@@ -11,7 +11,7 @@
#include "bas_printf.h"
#include <stddef.h>
//#define DBG_FECBD
#define DBG_FECBD
#ifdef DBG_FECBD
#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg); } while (0)
#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
* aside for buffer descriptors
*/
FECBD *RxBD;
FECBD *TxBD;
static FECBD *RxBD;
static FECBD *TxBD;
/*
* Macros to easier access to the BD ring
@@ -65,7 +65,7 @@ void fecbd_init(uint8_t ch)
NBUF *nbuf;
int i;
dbg("%s:\r\n", __FUNCTION__);
dbg("\r\n");
/*
* Align Buffer Descriptors to 4-byte boundary
@@ -73,7 +73,7 @@ void fecbd_init(uint8_t ch)
RxBD = (FECBD *)(((int) unaligned_bds + 3) & 0xFFFFFFFC);
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
@@ -84,7 +84,7 @@ void fecbd_init(uint8_t ch)
nbuf = nbuf_alloc();
if (nbuf == NULL)
{
dbg("%s: could not allocate network buffer\r\n", __FUNCTION__);
dbg("could not allocate network buffer\r\n");
return;
}
@@ -102,7 +102,7 @@ void fecbd_init(uint8_t ch)
*/
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

View File

@@ -7,13 +7,15 @@
* Modifications:
*/
#include "net.h"
#include "bas_printf.h"
#include "bas_string.h"
#include <stdint.h>
#include <stddef.h>
//#define IP_DEBUG
#define 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
#define dbg(format, arg...) do { ; } while (0)
#endif
@@ -42,7 +44,7 @@ uint8_t *ip_get_myip(IP_INFO *info)
{
return (uint8_t *) &info->myip[0];
}
dbg("%s: info is NULL!\n\t", __FUNCTION__);
dbg("info is NULL!\n\t");
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);
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;
}
@@ -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);
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]);
return 0;
}
@@ -176,9 +178,9 @@ int ip_send(NIF *nif, uint8_t *dest, uint8_t *src, uint8_t protocol, NBUF *pNbuf
else
{
route = bc;
dbg("%s: route = broadcast\r\n", __FUNCTION__);
dbg("%s: nif = %p\r\n", __FUNCTION__, nif);
dbg("%s: nif->send = %p\r\n", __FUNCTION__, nif->send);
dbg("route = broadcast\r\n");
dbg("nif = %p\r\n", nif);
dbg("nif->send = %p\r\n", nif->send);
}
return nif->send(nif, route, &nif->hwa[0], ETH_FRM_IP, pNbuf);
@@ -280,7 +282,7 @@ void ip_handler(NIF *nif, NBUF *pNbuf)
*/
ip_frame_hdr *ipframe;
dbg("%s: packet received\r\n", __FUNCTION__);
dbg("packet received\r\n");
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))
{
dbg("not a valid IP packet!\r\n");
nbuf_free(pNbuf);
return;
}
@@ -308,6 +312,8 @@ void ip_handler(NIF *nif, NBUF *pNbuf)
udp_handler(nif,pNbuf);
break;
default:
dbg("no protocol handler registered for protocol %d\r\n",
__FUNCTION__, IP_PROTOCOL(ipframe));
nbuf_free(pNbuf);
break;
}

View File

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

View File

@@ -39,6 +39,7 @@ void udp_init(void)
for (index = 0; index < UDP_MAX_PORTS; ++index)
{
udp_port_table[index].port = 0;
udp_port_table[index].handler = 0;
}
udp_port = DEFAULT_UDP_PORT; /* next free port */
@@ -88,7 +89,7 @@ static void *udp_port_handler(uint16_t port)
{
if (udp_port_table[index].port == port)
{
return (void *)udp_port_table[index].handler;
return (void *) udp_port_table[index].handler;
}
}
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
*/
udp_frame_hdr *udpframe;

View File

@@ -74,7 +74,15 @@ extern void run_bios(struct radeonfb_info *rinfo);
#define MIN_MAPPED_VRAM (1024*768*4)
#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[] =
{
@@ -231,7 +239,7 @@ extern struct fb_info *info_fb;
#define rinfo ((struct radeonfb_info *) info_fb->par)
static uint32_t inreg(uint32_t addr)
{
return(INREG(addr));
return INREG(addr);
}
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;
}
#ifndef MCF5445X
static uint32_t read_vline_crnt(struct radeonfb_info *rinfo)
{
return((INREG(CRTC_VLINE_CRNT_VLINE) >> 16) & 0x3FF);
}
#endif
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);
dbg("%s:hz %d\r\n", __FUNCTION__, (int32_t) hz);
hTotal = ((INREG(CRTC_H_TOTAL_DISP) & 0x1ff) + 1) * 8;
vTotal = ((INREG(CRTC_V_TOTAL_DISP) & 0x3ff) + 1);
dbg("%s:hTotal=%d\r\n", __FUNCTION__, hTotal);
dbg("%s:vTotal=%d\r\n", __FUNCTION__, vTotal);
vclk = (double) hTotal * (double) vTotal * hz;
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;
denom = 2 * m;
break;
case 2:
n = ((INPLL(M_SPLL_REF_FB_DIV) >> 8) & 0xff);
m = (INPLL(M_SPLL_REF_FB_DIV) & 0xff);
num = 2 * n;
denom = 2 * m;
break;
case 0:
default:
num = 1;
denom = 1;
break;
}
ppll_div_sel = INREG8(CLOCK_CNTL_INDEX + 1) & 0x3;
radeon_pll_errata_after_index(rinfo);
n = (INPLL(PPLL_DIV_0 + ppll_div_sel) & 0x7ff);
m = (INPLL(PPLL_REF_DIV) & 0x3ff);
num *= n;
denom *= m;
switch((INPLL(PPLL_DIV_0 + ppll_div_sel) >> 16) & 0x7)
{
case 1:
denom *= 2;
break;
case 2:
denom *= 4;
break;
case 3:
denom *= 8;
break;
case 4:
denom *= 3;
break;
case 6:
denom *= 6;
break;
case 7:
denom *= 12;
break;
@@ -567,6 +586,7 @@ static int radeon_probe_pll_params(struct radeonfb_info *rinfo)
vclk *= (double) denom;
vclk /= (double) (1000 * num);
xtal = (int32_t) vclk;
if ((xtal > 26900) && (xtal < 27100))
xtal = 2700; /* 27 MHz */
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);
return -1; /* error */
}
tmp = INPLL(M_SPLL_REF_FB_DIV);
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.ref_clk = 2700;
break;
case PCI_DEVICE_ID_ATI_RADEON_QL:
case PCI_DEVICE_ID_ATI_RADEON_QN:
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.ref_clk = 2700;
break;
case PCI_DEVICE_ID_ATI_RADEON_Id:
case PCI_DEVICE_ID_ATI_RADEON_Ie:
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.ref_clk = 2700;
break;
case PCI_DEVICE_ID_ATI_RADEON_ND:
case PCI_DEVICE_ID_ATI_RADEON_NE:
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.ref_clk = 2700;
break;
case PCI_DEVICE_ID_ATI_RADEON_QD:
case PCI_DEVICE_ID_ATI_RADEON_QE:
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__);
goto found;
}
/*
* Fall back to already-set defaults...
*/
dbg("%s: Used default PLL infos\r\n", __FUNCTION__);
found:
/*
* 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__,
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)
{
if (var->bits_per_pixel != 16)
return var->bits_per_pixel;
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;
int nom, den;
uint32_t pitch;
dbg("%s:\r\n", __FUNCTION__);
/* 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:
v.bits_per_pixel = 8;
break;
case 9 ... 16:
v.bits_per_pixel = 16;
break;
#if 0 /* Doesn't seem to work */
case 17 ... 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:
v.bits_per_pixel = 32;
break;
default:
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.transp.offset = v.transp.length = 0;
break;
case 15:
nom = 2;
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.transp.offset = v.transp.length = 0;
break;
case 16:
nom = 2;
den = 1;
@@ -785,6 +820,7 @@ int radeonfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
v.blue.length = 5;
v.transp.offset = v.transp.length = 0;
break;
case 24:
nom = 4;
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.transp.offset = v.transp.length = 0;
break;
case 32:
nom = 4;
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.length = 8;
break;
default:
dbg("radeonfb: mode %d x %d x %d rejected, color depth invalid\r\n ",
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;
if (v.xres_virtual < v.xres)
v.xres_virtual = v.xres;
/*
* XXX I'm adjusting xres_virtual to the pitch, that may help XFree
* 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);
memcpy(var, &v, sizeof(v));
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");
if ((var->xoffset + var->xres) > var->xres_virtual)
return -1; //-EINVAL;
if (((var->yoffset * var->xres_virtual) + var->xoffset) >=
(rinfo->mapped_vram - (var->yres * var->xres * (var->bits_per_pixel / 8))))
return -1; //-EINVAL;
if (rinfo->asleep)
return 0;
radeon_wait_for_fifo(rinfo, 2);
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);
OUTREG(CRTC_OFFSET, rinfo->fb_offset);
return 0;
return 0;
}
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;
uint32_t tmp;
uint32_t value = 0;
switch(cmd)
{
/*
@@ -899,6 +944,7 @@ int radeonfb_ioctl(unsigned int cmd, unsigned long arg, struct fb_info *info)
tmp &= ~(LVDS_ON | LVDS_BLON);
}
OUTREG(LVDS_GEN_CNTL, tmp);
if (value & 0x02)
{
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);
return 0;
case FBIO_RADEON_GET_MIRROR:
if (!rinfo->is_mobility)
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)
value |= 0x02;
return 0;
default:
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)
return 0;
dbg("radeonfb: radeon_screen_blank\r\n");
radeon_engine_idle();
val = INREG(CRTC_EXT_CNTL);
val &= ~(CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS | CRTC_VSYNC_DIS);
switch(blank)
{
case FB_BLANK_VSYNC_SUSPEND:
val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS);
break;
case FB_BLANK_HSYNC_SUSPEND:
val |= (CRTC_DISPLAY_DIS | CRTC_HSYNC_DIS);
break;
case FB_BLANK_POWERDOWN:
val |= (CRTC_DISPLAY_DIS | CRTC_VSYNC_DIS | CRTC_HSYNC_DIS);
break;
case FB_BLANK_NORMAL:
val |= CRTC_DISPLAY_DIS;
break;
case FB_BLANK_UNBLANK:
default:
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));
}
break;
case MT_LCD:
rinfo->lvds_timer = 0;
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 */
if (mode_switch || blank == FB_BLANK_NORMAL)
break;
/* Asic bug, when turning off LVDS_ON, we have to make sure
* RADEON_PIXCLK_LVDS_ALWAYS_ON bit is off
*/
tmp_pix_clks = INPLL(PIXCLKS_CNTL);
if (rinfo->is_mobility || rinfo->is_IGP)
OUTPLLP(PIXCLKS_CNTL, 0, ~PIXCLK_LVDS_ALWAYS_ONb);
val &= ~(LVDS_BL_MOD_EN);
OUTREG(LVDS_GEN_CNTL, val);
wait(100);
val &= ~(LVDS_ON | LVDS_EN);
OUTREG(LVDS_GEN_CNTL, val);
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->init_state.lvds_gen_cntl &= ~LVDS_STATE_MASK;
rinfo->init_state.lvds_gen_cntl |= val & LVDS_STATE_MASK;
if (rinfo->is_mobility || rinfo->is_IGP)
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)
{
struct radeonfb_info *rinfo = info->par;
if (rinfo->asleep)
return 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;
uint32_t pindex;
if (regno > 255)
return 1;
red >>= 8;
green >>= 8;
blue >>= 8;
rinfo->palette[regno].red = red;
rinfo->palette[regno].green = green;
rinfo->palette[regno].blue = blue;
/* default */
pindex = regno;
if (!rinfo->asleep)
@@ -1069,7 +1135,9 @@ static int radeon_setcolreg(unsigned regno, unsigned red, unsigned green,
return 1;
if (rinfo->depth == 15 && regno > 31)
return 1;
/* For 565, the green component is mixed one order
/*
* For 565, the green component is mixed one order
* below
*/
if (rinfo->depth == 16)
@@ -1095,6 +1163,7 @@ int radeonfb_setcolreg(unsigned regno, unsigned red, unsigned green,
struct radeonfb_info *rinfo = info->par;
uint32_t dac_cntl2, vclk_cntl = 0;
int rc;
if (!rinfo->asleep)
{
if (rinfo->is_mobility)
@@ -1102,6 +1171,7 @@ int radeonfb_setcolreg(unsigned regno, unsigned red, unsigned green,
vclk_cntl = INPLL(VCLK_ECP_CNTL);
OUTPLL(VCLK_ECP_CNTL, vclk_cntl & ~PIXCLK_DAC_ALWAYS_ONb);
}
/* Make sure we are on first palette */
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);
if (!rinfo->asleep && rinfo->is_mobility)
OUTPLL(VCLK_ECP_CNTL, vclk_cntl);
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_pitch = INREG(CRTC_PITCH);
save->surface_cntl = INREG(SURFACE_CNTL);
/* FP regs */
save->fp_crtc_h_total_disp = INREG(FP_CRTC_H_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->vclk_ecp_cntl = INPLL(VCLK_ECP_CNTL);
/* PLL regs */
save->clk_cntl_index = INREG(CLOCK_CNTL_INDEX) & ~0x3f;
radeon_pll_errata_after_index(rinfo);
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)
{
int i;
dbg("radeonfb: radeon_write_pll_regs\r\n");
radeon_wait_for_fifo(rinfo, 20);
#if 0
/* Workaround from XFree */
if (rinfo->is_mobility)
@@ -1180,22 +1255,27 @@ static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_reg
}
}
#endif
/* 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);
/* Reset PPLL & enable atomic update */
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));
/* Switch to selected PPLL divider */
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_data(rinfo);
/* Set PPLL ref. div */
if (rinfo->family == CHIP_FAMILY_R300 || rinfo->family == CHIP_FAMILY_RS300
|| rinfo->family == CHIP_FAMILY_R350 || rinfo->family == CHIP_FAMILY_RV350)
{
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.
*/
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 */
while (INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R);
OUTPLLP(PPLL_REF_DIV, PPLL_ATOMIC_UPDATE_W, ~PPLL_ATOMIC_UPDATE_W);
/* Wait read update complete */
/* FIXME: Certain revisions of R300 can't recover here. Not sure of
the cause yet, but this workaround will mask the problem for now.
Other chips usually will pass at the very first test, so the
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);
/* Clear reset & atomic update */
OUTPLLP(PPLL_CNTL, 0, ~(PPLL_RESET | PPLL_SLEEP | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN));
/* We may want some locking ... oh well */
radeon_msleep(5);
/* Switch back VCLK source to PPLL */
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
static int32_t start_timer;
/* delayed LVDS panel power up/down */
if (rinfo->lvds_timer)
{
@@ -1263,10 +1349,11 @@ static void radeon_timer_func(void)
}
else
start_timer = 0;
#endif
#endif /* FIXME_LATER */
if (rinfo->RenderCallback != NULL)
rinfo->RenderCallback(rinfo);
if ((info->screen_mono != NULL) && info->update_mono)
{
int32_t foreground = 255, background = 0;
@@ -1275,21 +1362,25 @@ static void radeon_timer_func(void)
int dst_x = 0;
int w = (int)info->var.xres_virtual;
int h = (int)info->var.yres_virtual;
// info->fbops->SetClippingRectangle(info,0,0,w-1,h-1);
src_buf = (uint8_t*)((int32_t)src_buf & ~3);
dst_x -= (int32_t)skipleft;
w += (int32_t)skipleft;
info->fbops->SetupForScanlineCPUToScreenColorExpandFill(info,(int)foreground,(int)background,3,0xffffffff);
info->fbops->SubsequentScanlineCPUToScreenColorExpandFill(info,(int)dst_x,0,w,h,skipleft);
while (--h >= 0)
{
info->fbops->SubsequentScanline(info, (unsigned long *) src_buf);
src_buf += (info->var.xres_virtual >> 3);
}
// info->fbops->DisableClipping(info);
if (info->update_mono > 0)
info->update_mono = 0;
}
if ((info->var.xres_virtual != info->var.xres)
|| (info->var.yres_virtual != info->var.yres))
{
@@ -1310,6 +1401,7 @@ static void radeon_timer_func(void)
x -= 8;
chg = 1;
}
if (((y + info->var.yres) < info->var.yres_virtual) && (rinfo->cursor_y >= (info->var.yres - 8)))
{
y += 8;
@@ -1329,7 +1421,9 @@ static void radeon_timer_func(void)
disp = rinfo->cursor_show;
if (disp)
info->fbops->HideCursor(info);
fb_pan_display(info,&var);
if (disp)
info->fbops->ShowCursor(info);
}
@@ -1345,14 +1439,19 @@ void radeon_write_mode(struct radeonfb_info *rinfo, struct radeon_regs *mode, in
{
int i;
int primary_mon = PRIMARY_MONITOR(rinfo);
dbg("radeonfb: radeon_write_mode\r\n");
if (!regs_only)
radeon_screen_blank(rinfo, FB_BLANK_NORMAL, 0);
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);
/* 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_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
#endif
OUTREG(CRTC_OFFSET_CNTL, 0);
OUTREG(CRTC_PITCH, mode->crtc_pitch);
OUTREG(SURFACE_CNTL, mode->surface_cntl);
radeon_write_pll_regs(rinfo, mode);
if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD))
{
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_TRANSMITTER_CNTL, mode->tmds_transmitter_cntl);
}
if (!regs_only)
radeon_screen_blank(rinfo, FB_BLANK_UNBLANK, 0);
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 const struct {
static const struct
{
int divider;
int bitvalue;
} *post_div,
post_divs[] = {
post_divs[] =
{
{ 1, 0 },
{ 2, 1 },
{ 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 uses_dvo = 0;
/* 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
* 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 disp_output_cntl;
int source;
/* FP2 path not enabled */
if ((fp2_gen_cntl & FP2_ON) == 0)
break;
/* Not all chip revs have the same format for this register,
* extract the source selection
*/
@@ -1464,9 +1571,11 @@ static void radeon_calc_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs
}
else
source = (fp2_gen_cntl >> 13) & 0x1;
/* sourced from CRTC2 -> exit */
if (source == 1)
break;
/* so we end up on CRTC1, let's set uses_dvo to 1 now */
uses_dvo = 1;
break;
@@ -1476,27 +1585,32 @@ static void radeon_calc_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs
#endif
if (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;
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;
/* 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
*/
if (uses_dvo && (post_div->divider & 1))
continue;
if (pll_output_freq >= rinfo->pll.ppll_min &&
pll_output_freq <= rinfo->pll.ppll_max)
break;
}
/* If we fall through the bottom, try the "default value"
given by the terminal post_div->bitvalue */
if ( !post_div->divider )
if (!post_div->divider)
{
post_div = &post_divs[post_div->bitvalue];
pll_output_freq = post_div->divider * freq;
}
/* If we fall through the bottom, try the "default value"
given by the terminal post_div->bitvalue */
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));
if (!newmode)
return -1; //-ENOMEM;
/* We always want engine to be idle on a mode switch, even
* 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;
}
}
dotClock = 1000000000 / pixClock;
freq = dotClock / 10; /* x100 */
hsync_wid = (hSyncEnd - hSyncStart) / 8;
if (hsync_wid == 0)
hsync_wid = 1;
else if (hsync_wid > 0x3f) /* max */
hsync_wid = 0x3f;
if (mode->vmode & FB_VMODE_DOUBLE)
{
vSyncStart <<= 1;
vSyncEnd <<= 1;
vTotal <<= 1;
}
vsync_wid = vSyncEnd - vSyncStart;
if (vsync_wid == 0)
vsync_wid = 1;
else if (vsync_wid > 0x1f) /* max */
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 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;
@@ -1624,6 +1744,7 @@ int radeonfb_set_par(struct fb_info *info)
/* Clear auto-center etc... */
newmode->crtc_more_cntl = rinfo->init_state.crtc_more_cntl;
newmode->crtc_more_cntl &= 0xfffffff0;
if ((primary_mon == MT_DFP) || (primary_mon == MT_LCD))
{
newmode->crtc_ext_cntl = VGA_ATI_LINEAR | XCRT_CNT_EN;
@@ -1633,13 +1754,16 @@ int radeonfb_set_par(struct fb_info *info)
}
else
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->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));
if (mode->vmode & FB_VMODE_DOUBLE)
newmode->crtc_v_total_disp = ((vTotal - 1) & 0xffff) | (((mode->yres << 1) - 1) << 16);
else
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));
/* We first calculate the engine pitch */
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.
*/
newmode->surface_cntl = 0;
if (rinfo->big_endian)
{
/* Setup swapping on both apertures, though we currently
@@ -1674,12 +1799,13 @@ int radeonfb_set_par(struct fb_info *info)
}
/* Clear surface registers */
for(i = 0; i < 8; i++)
for (i = 0; i < 8; i++)
{
newmode->surf_lower_bound[i] = 0;
newmode->surf_upper_bound[i] = 0x1f;
newmode->surf_info[i] = 0;
}
rinfo->bpp = mode->bits_per_pixel;
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_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);
if (IS_R300_VARIANT(rinfo) || (rinfo->family == CHIP_FAMILY_R200))
{
newmode->fp_gen_cntl &= ~R200_FP_SOURCE_SEL_MASK;
@@ -1734,10 +1861,12 @@ int radeonfb_set_par(struct fb_info *info)
}
else
newmode->fp_gen_cntl |= FP_SEL_CRTC1;
newmode->lvds_gen_cntl = rinfo->init_state.lvds_gen_cntl;
newmode->lvds_pll_cntl = rinfo->init_state.lvds_pll_cntl;
newmode->tmds_crc = rinfo->init_state.tmds_crc;
newmode->tmds_transmitter_cntl = rinfo->init_state.tmds_transmitter_cntl;
if (primary_mon == MT_LCD)
{
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->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_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_v_sync_strt_wid = ((rinfo->panel_info.vOver_plus & 0xfff) | (vsync_wid << 16) | (v_sync_pol << 23));
}
/* do it! */
if (!rinfo->asleep)
{
@@ -1778,10 +1909,12 @@ int radeonfb_set_par(struct fb_info *info)
/* (re)initialize the engine */
radeon_engine_init(rinfo);
}
/* Update fix */
info->fix.line_length = rinfo->pitch*64;
info->fix.visual = rinfo->depth == 8 ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
driver_mem_free(newmode);
return 0;
}

View File

@@ -48,6 +48,7 @@
#include "bootp.h"
#include "interrupts.h"
#include "exceptions.h"
#include "net_timer.h"
//#define BAS_DEBUG
#if defined(BAS_DEBUG)
@@ -251,7 +252,7 @@ static ARP_INFO arp_info;
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 */
IP_ADDR myip = {192, 168, 1, 100};
IP_ADDR gateway = {192, 168, 1, 1};
@@ -264,7 +265,7 @@ void network_init(void)
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);
return;
@@ -276,7 +277,7 @@ void network_init(void)
handler = dma_interrupt_handler;
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);
return;

View File

@@ -44,24 +44,24 @@ uint32_t cacr_get(void)
void flush_and_invalidate_caches(void)
{
__asm__ (
" clr.l d0\n\t"
" clr.l d1\n\t"
" move.l d0,a0\n\t"
"cfa_setloop:\n\t"
" cpushl bc,(a0) | flush\n\t"
" lea 0x10(a0),a0 | index+1\n\t"
" addq.l #1,d1 | index+1\n\t"
" cmpi.w #512,d1 | all sets?\n\t"
" bne.s cfa_setloop | no->\n\t"
" clr.l d1\n\t"
" addq.l #1,d0\n\t"
" move.l d0,a0\n\t"
" cmpi.w #4,d0 | all ways?\n\t"
" bne.s cfa_setloop | no->\n\t"
/* input */ :
/* output */ :
/* clobber */ : "d0", "d1", "a0"
__asm__ __volatile__(
" clr.l d0 \n\t"
" clr.l d1 \n\t"
" move.l d0,a0 \n\t"
"cfa_setloop: \n\t"
" cpushl bc,(a0) | flush\n\t"
" lea 0x10(a0),a0 | index+1\n\t"
" addq.l #1,d1 | index+1\n\t"
" cmpi.w #512,d1 | all sets?\n\t"
" bne.s cfa_setloop | no->\n\t"
" clr.l d1 \n\t"
" addq.l #1,d0 \n\t"
" move.l d0,a0 \n\t"
" cmpi.w #4,d0 | all ways?\n\t"
" bne.s cfa_setloop | no->\n\t"
/* input */ :
/* output */ :
/* clobber */ : "d0", "d1", "a0"
);
}
@@ -81,25 +81,35 @@ void flush_icache_range(void *address, size_t size)
if (start_set > end_set) {
/* from the begining to the lowest address */
for (set = 0; set <= end_set; set += (0x10 - 3)) {
asm volatile("cpushl ic,(%0)\n\t"
"addq.l #1,%0\n\t"
"cpushl ic,(%0)\n\t"
"addq.l #1,%0\n\t"
"cpushl ic,(%0)\n\t"
"addq.l #1,%0\n\t"
"cpushl ic,(%0)" : "=a" (set) : "a" (set));
__asm__ __volatile__(
" cpushl ic,(%[set]) \n\t"
" addq.l #1,%[set] \n\t"
" cpushl ic,(%[set]) \n\t"
" addq.l #1,%[set] \n\t"
" cpushl ic,(%[set]) \n\t"
" 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 */
end_set = LAST_ICACHE_ADDR;
}
for (set = start_set; set <= end_set; set += (0x10 - 3)) {
asm volatile("cpushl ic,(%0)\n\t"
"addq.l #1,%0\n\t"
"cpushl ic,(%0)\n\t"
"addq%.l #1,%0\n\t"
"cpushl ic,(%0)\n\t"
"addq.l #1,%0\n\t"
"cpushl ic,(%0)" : "=a" (set) : "a" (set));
__asm__ __volatile__(
" cpushl ic,(%[set]) \n\t"
" addq.l #1,%[set] \n\t"
" cpushl ic,(%[set]) \n\t"
" addq.l #1,%[set] \n\t"
" cpushl ic,(%[set]) \n\t"
" 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) {
/* from the begining to the lowest address */
for (set = 0; set <= end_set; set += (0x10 - 3)) {
asm volatile("cpushl dc,(%0)\n\t"
"addq.l #1,%0\n\t"
"cpushl dc,(%0)\n\t"
"addq.l #1,%0\n\t"
"cpushl dc,(%0)\n\t"
"addq.l #1,%0\n\t"
"cpushl dc,(%0)" : "=a" (set) : "a" (set));
for (set = 0; set <= end_set; set += (0x10 - 3))
{
__asm__ __volatile__(
" cpushl dc,(%[set]) \n\t"
" addq.l #1,%[set] \n\t"
" cpushl dc,(%[set]) \n\t"
" addq.l #1,%[set] \n\t"
" 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 */
end_set = LAST_DCACHE_ADDR;
}
for (set = start_set; set <= end_set; set += (0x10 - 3)) {
asm volatile("cpushl dc,(%0)\n\t"
"addq.l #1,%0\n\t"
"cpushl dc,(%0)\n\t"
"addq%.l #1,%0\n\t"
"cpushl dc,(%0)\n\t"
"addq.l #1,%0\n\t"
"cpushl dc,(%0)" : "=a" (set) : "a" (set));
for (set = start_set; set <= end_set; set += (0x10 - 3))
{
__asm__ __volatile__(
" cpushl dc,(%[set]) \n\t"
" addq.l #1,%[set] \n\t"
" cpushl dc,(%[set]) \n\t"
" addq%.l #1,%[set] \n\t"
" 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 "exceptions.h" /* set_ipl() */
#if MACHINE_FIREBEE
#if defined(MACHINE_FIREBEE)
#include "firebee.h"
#elif MACHINE_M5484LITE
#elif defined(MACHINE_M5484LITE)
#include "m5484l.h"
#elif defined(MACHINE_M54455)
#include "m54455.h"
#else
#error "unknown machine!"
#endif
//#define DBG_DM

File diff suppressed because it is too large Load Diff

View File

@@ -38,59 +38,50 @@ extern uint8_t _FPGA_FLASH_DATA[];
extern uint8_t _FPGA_FLASH_DATA_SIZE[];
#define FPGA_FLASH_DATA_SIZE ((uint32_t) &_FPGA_FLASH_DATA_SIZE[0])
#ifdef _NOT_USED_
void test_longword(void)
void config_gpio_for_fpga_config(void)
{
uint32_t *fpga_data = (uint32_t *) FPGA_FLASH_DATA;
const uint32_t *fpga_flash_data_end = (uint32_t *) FPGA_FLASH_DATA + FPGA_FLASH_DATA_SIZE;
do
{
uint32_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");
#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 */
}
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;
do
{
uint16_t value = *fpga_data++;
xprintf("WORDS: addr=%p, value=%04x\r", fpga_data, value);
} while (fpga_data < fpga_flash_data_end);
xprintf("finished. \r\n");
/*
* configure FEC1L port directions to enable external JTAG configuration download to FPGA
*/
MCF_GPIO_PDDR_FEC1L = 0 |
MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L4; /* bit 4 = LED => output */
/* all other bits = input */
/*
* unfortunately, the GPIO module cannot trigger interrupts. That means FPGA_CONFIG needs to be polled to detect
* external FPGA (re)configuration and reset the system in that case. Could be done from the OS as well...
*/
}
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
*/
void init_fpga(void)
bool init_fpga(void)
{
uint8_t *fpga_data;
volatile int32_t time, start, end;
int i;
xprintf("FPGA load config... ");
start = MCF_SLT0_SCNT;
start = MCF_SLT0_SCNT;
config_gpio_for_fpga_config();
MCF_GPIO_PODR_FEC1L &= ~FPGA_CLOCK; /* FPGA clock => low */
/* pulling FPGA_CONFIG to low resets the FPGA */
@@ -109,7 +100,7 @@ void init_fpga(void)
* 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,
* 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
* 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.
@@ -159,11 +150,12 @@ void init_fpga(void)
#endif /* _NOT_USED_ */
end = MCF_SLT0_SCNT;
time = (start - end) / (SYSCLK / 1000) / 1000;
xprintf("finished (took %f seconds).\r\n", time / 1000.0);
config_gpio_for_jtag_config();
return true;
}
else
{
xprintf("FAILED!\r\n");
}
xprintf("FAILED!\r\n");
config_gpio_for_jtag_config();
return false;
}

View File

@@ -30,13 +30,16 @@
#include "exceptions.h"
#include "interrupts.h"
#include "bas_printf.h"
#include "startcf.h"
#include "cache.h"
#include "util.h"
extern void (*rt_vbr[])(void);
#define VBR rt_vbr
#define 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
#define dbg(format, arg...) do { ; } while (0)
#endif
@@ -57,7 +60,7 @@ int register_interrupt_handler(uint8_t source, uint8_t level, uint8_t priority,
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;
}
@@ -68,7 +71,7 @@ int register_interrupt_handler(uint8_t source, uint8_t level, uint8_t priority,
{
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);
return -1;
}
@@ -88,31 +91,29 @@ int register_interrupt_handler(uint8_t source, uint8_t level, uint8_t priority,
return 0;
}
#ifndef UIF_MAX_ISR_ENTRY
#define UIF_MAX_ISR_ENTRY (20)
#ifndef MAX_ISR_ENTRY
#define MAX_ISR_ENTRY (20)
#endif
typedef struct
{
int vector;
int type;
int (*handler)(void *, void *);
void *hdev;
void *harg;
} ISRENTRY;
ISRENTRY isrtab[UIF_MAX_ISR_ENTRY];
ISRENTRY isrtab[MAX_ISR_ENTRY];
void isr_init(void)
{
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].type = 0;
isrtab[index].handler = 0;
isrtab[index].hdev = 0;
isrtab[index].harg = 0;
@@ -120,41 +121,36 @@ void isr_init(void)
}
int isr_register_handler(int type, int vector,
int (*handler)(void *, void *), void *hdev, void *harg)
int isr_register_handler(int vector, int (*handler)(void *, void *), void *hdev, void *harg)
{
/*
* This function places an interrupt handler in the ISR table,
* thereby registering it so that the low-level handler may call it.
*
* 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
* 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
* structure used by the device driver for that particular device.
*/
int index;
if ((vector == 0) ||
((type != ISR_DBUG_ISR) && (type != ISR_USER_ISR)) ||
(handler == NULL))
if ((vector == 0) || (handler == NULL))
{
dbg("%s: illegal type, vector or handler!\r\n", __FUNCTION__);
dbg("illegal vector or handler!\r\n");
return false;
}
for (index = 0; index < UIF_MAX_ISR_ENTRY; index++)
for (index = 0; index < MAX_ISR_ENTRY; index++)
{
if ((isrtab[index].vector == vector) &&
(isrtab[index].type == type))
if (isrtab[index].vector == vector)
{
/* only one entry of each type per vector */
dbg("%s: already set handler with this type and vector (%d, %d)\r\n", __FUNCTION__, type, vector);
/* one cross each, only! */
dbg("already set handler with this vector (%d, %d)\r\n", vector);
return false;
}
if (isrtab[index].vector == 0)
{
isrtab[index].vector = vector;
isrtab[index].type = type;
isrtab[index].handler = handler;
isrtab[index].hdev = hdev;
isrtab[index].harg = harg;
@@ -162,26 +158,24 @@ int isr_register_handler(int type, int vector,
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 */
}
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
* entries that matches 'type' and 'handler'.
* entries that matches 'handler'.
*/
int index;
for (index = 0; index < UIF_MAX_ISR_ENTRY; index++)
for (index = 0; index < MAX_ISR_ENTRY; index++)
{
if ((isrtab[index].handler == handler) &&
(isrtab[index].type == type))
if (isrtab[index].handler == handler)
{
isrtab[index].vector = 0;
isrtab[index].type = 0;
isrtab[index].handler = 0;
isrtab[index].hdev = 0;
isrtab[index].harg = 0;
@@ -189,7 +183,7 @@ void isr_remove_handler(int type, int (*handler)(void *, void *))
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;
/*
* 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) &&
(isrtab[index].type == ISR_DBUG_ISR))
if (isrtab[index].vector == vector)
{
retval = true;
if (isrtab[index].handler(isrtab[index].hdev, isrtab[index].harg))
{
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;
}
/*
* 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;
}

668
sys/mmu.c
View File

@@ -24,26 +24,6 @@
* Copyright 2013 M. Froeschle
*/
#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_AMM(x) (((x) & 1) << 10)
#define ACR_CM(x) (((x) & 3) << 5)
#define ACR_CM_CACHEABLE_WT 0x0
#define ACR_CM_CACHEABLE_CB 0x1
#define ACR_CM_CACHE_INH_PRECISE 0x2
#define ACR_CM_CACHE_INH_IMPRECISE 0x3
#define ACR_SP(x) (((x) & 1) << 3)
#define ACR_W(x) (((x) & 1) << 2)
#include <stdint.h>
#include "bas_printf.h"
#include "bas_types.h"
@@ -56,16 +36,18 @@
#include "firebee.h"
#elif defined(MACHINE_M5484LITE)
#include "m5484l.h"
#elif defined(MACHINE_M54455)
#include "m54455.h"
#else
#error "unknown machine!"
#endif /* MACHINE_FIREBEE */
//#define DEBUG_MMU
#ifdef DEBUG_MMU
#define dbg(format, arg...) do { xprintf("DEBUG: " format, ##arg);} while(0)
#define DBG_MMU
#ifdef DBG_MMU
#define dbg(format, arg...) do { xprintf("DEBUG %s(): " format, __FUNCTION__, ##arg);} while(0)
#else
#define dbg(format, arg...) do {;} while (0)
#endif /* DEBUG_MMU */
#endif /* DBG_MMU */
/*
* set ASID register
@@ -77,18 +59,18 @@ inline uint32_t set_asid(uint32_t value)
uint32_t ret = rt_asid;
__asm__ __volatile__(
"movec %[value],ASID\n\t"
: /* no output */
: [value] "r" (value)
:
);
"movec %[value],ASID\n\t"
: /* no output */
: [value] "r" (value)
:
);
rt_asid = value;
return ret;
}
/*
* set ACRx register
* saves new value to rt_acrx and returns former value
@@ -97,13 +79,13 @@ inline uint32_t set_acr0(uint32_t value)
{
extern uint32_t rt_acr0;
uint32_t ret = rt_acr0;
__asm__ __volatile__(
"movec %[value],ACR0\n\t"
: /* not output */
: [value] "r" (value)
:
);
"movec %[value],ACR0\n\t"
: /* not output */
: [value] "r" (value)
:
);
rt_acr0 = value;
return ret;
@@ -117,13 +99,13 @@ inline uint32_t set_acr1(uint32_t value)
{
extern uint32_t rt_acr1;
uint32_t ret = rt_acr1;
__asm__ __volatile__(
"movec %[value],ACR1\n\t"
: /* not output */
: [value] "r" (value)
:
);
"movec %[value],ACR1\n\t"
: /* not output */
: [value] "r" (value)
:
);
rt_acr1 = value;
return ret;
@@ -138,13 +120,13 @@ inline uint32_t set_acr2(uint32_t value)
{
extern uint32_t rt_acr2;
uint32_t ret = rt_acr2;
__asm__ __volatile__(
"movec %[value],ACR2\n\t"
: /* not output */
: [value] "r" (value)
:
);
"movec %[value],ACR2\n\t"
: /* not output */
: [value] "r" (value)
:
);
rt_acr2 = value;
return ret;
@@ -158,13 +140,13 @@ inline uint32_t set_acr3(uint32_t value)
{
extern uint32_t rt_acr3;
uint32_t ret = rt_acr3;
__asm__ __volatile__(
"movec %[value],ACR3\n\t"
: /* not output */
: [value] "r" (value)
:
);
"movec %[value],ACR3\n\t"
: /* not output */
: [value] "r" (value)
:
);
rt_acr3 = value;
return ret;
@@ -176,264 +158,376 @@ inline uint32_t set_mmubar(uint32_t value)
uint32_t ret = rt_mmubar;
__asm__ __volatile__(
"movec %[value],MMUBAR\n\t"
: /* no output */
: [value] "r" (value)
: /* no clobber */
);
"movec %[value],MMUBAR\n\t"
: /* no output */
: [value] "r" (value)
: /* no clobber */
);
rt_mmubar = value;
NOP();
return ret;
}
/*
* TODO: this would be nicer in an include file
*/
extern uint8_t _SYS_SRAM[];
#define SYS_SRAM_ADDRESS ((uint32_t) &_SYS_SRAM[0])
extern uint8_t _SYS_SRAM_SIZE[];
extern uint8_t _FASTRAM_END[];
struct mmu_mapping
{
uint32_t phys;
uint32_t virt;
uint32_t length;
uint32_t pagesize;
struct map_flags flags;
};
static struct mmu_mapping locked_map[] =
{
{
/* Falcon video memory. Needs special care */
0x60d00000,
0xd00000,
0x100000,
MMU_PAGE_SIZE_1M,
{ CACHE_WRITETHROUGH, SV_USER, SCA_PAGE_ID, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE },
},
};
static int num_locked_mmu_maps = sizeof(locked_map) / sizeof(struct mmu_mapping);
static struct mmu_mapping memory_map[] =
{
/* map OS system vectors supervisor-protected */
{
0,
0,
0x800,
MMU_PAGE_SIZE_1K,
{ CACHE_WRITETHROUGH, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE },
},
{
0x800,
0x800,
0x800,
MMU_PAGE_SIZE_1K,
{ CACHE_WRITETHROUGH, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE },
},
{
/* when the first 4k are filled with 1k pages, we can switch to 8k pages */
0x1000,
0x1000,
0xff000,
MMU_PAGE_SIZE_8K,
{ CACHE_WRITETHROUGH, SV_USER, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE },
},
{
/* arrived at a 1Meg border, we can switch to 1Meg pages */
0x100000,
0x100000,
0xc00000,
MMU_PAGE_SIZE_1M,
{ CACHE_WRITETHROUGH, SV_USER, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE },
},
/* Falcon video ram left out intentionally here (see above) */
{
/* ROM */
0xe00000,
0xe00000,
0x100000,
MMU_PAGE_SIZE_1M,
{ CACHE_WRITETHROUGH, SV_USER, 0, ACCESS_READ | ACCESS_EXECUTE },
},
{
/* FASTRAM */
0x1000000,
0x1000000,
(uint32_t) _FASTRAM_END - 0x1000000,
MMU_PAGE_SIZE_1M,
{ CACHE_WRITETHROUGH, SV_USER, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE },
},
{
/* MBAR */
MBAR_ADDRESS,
MBAR_ADDRESS,
0x100000,
MMU_PAGE_SIZE_1M,
{ CACHE_NOCACHE_PRECISE, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE },
},
{
/* RAMBAR0 */
RAMBAR0_ADDRESS,
RAMBAR0_ADDRESS,
(uint32_t) _RAMBAR0_SIZE,
MMU_PAGE_SIZE_1K,
{ CACHE_WRITETHROUGH, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE },
},
{
/* RAMBAR1 */
RAMBAR1_ADDRESS,
RAMBAR1_ADDRESS,
(uint32_t) _RAMBAR1_SIZE,
MMU_PAGE_SIZE_1K,
{ CACHE_WRITETHROUGH, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE },
},
{
/* SYSTEM SRAM */
SYS_SRAM_ADDRESS,
SYS_SRAM_ADDRESS,
(uint32_t) _SYS_SRAM_SIZE,
MMU_PAGE_SIZE_8K,
{ CACHE_WRITETHROUGH, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE | ACCESS_EXECUTE },
},
{
/* Firebee FPGA registers */
(uint32_t) 0xf0000000,
(uint32_t) 0xf0000000,
(uint32_t) 0x08000000,
MMU_PAGE_SIZE_1M,
{ CACHE_NOCACHE_PRECISE, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE },
},
{
/* Falcon I/O registers */
(uint32_t) 0xfff00000,
(uint32_t) 0xfff00000,
(uint32_t) 0x100000,
MMU_PAGE_SIZE_1M,
{ CACHE_NOCACHE_PRECISE, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE },
},
{
/* the same, but different virtual address */
(uint32_t) 0x00f00000,
(uint32_t) 0xfff00000,
(uint32_t) 0x100000,
MMU_PAGE_SIZE_1M,
{ CACHE_NOCACHE_PRECISE, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE },
},
{
/* PCI memory */
(uint32_t) PCI_MEMORY_OFFSET,
(uint32_t) PCI_MEMORY_OFFSET,
(uint32_t) PCI_MEMORY_SIZE,
MMU_PAGE_SIZE_1M,
{ CACHE_NOCACHE_PRECISE, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE },
},
{
/* PCI I/O */
(uint32_t) PCI_IO_OFFSET,
(uint32_t) PCI_IO_OFFSET,
(uint32_t) PCI_IO_SIZE,
MMU_PAGE_SIZE_1M,
{ CACHE_NOCACHE_PRECISE, SV_PROTECT, 0, ACCESS_READ | ACCESS_WRITE },
}
};
static int num_mmu_maps = sizeof(memory_map) / sizeof(struct mmu_mapping);
static struct mmu_mapping *lookup_mapping(uint32_t virt)
{
int i;
/*
* dumb, for now
*/
for (i = 0; i < num_mmu_maps; i++)
{
if (virt >= memory_map[i].virt && virt <= memory_map[i].virt + memory_map[i].length - 1)
return &memory_map[i];
}
return NULL;
}
void mmu_init(void)
{
extern uint8_t _MMUBAR[];
uint32_t MMUBAR = (uint32_t) &_MMUBAR[0];
extern uint8_t _TOS[];
uint32_t TOS = (uint32_t) &_TOS[0];
int i;
set_asid(0); /* do not use address extension (ASID provides virtual 48 bit addresses */
/*
* need to set data ACRs in a way that supervisor access to all memory regions
* becomes possible. Otherways it might be that the supervisor stack ends up in an unmapped
* region when further MMU TLB entries force a page steal. This would lead to a double
* fault since the CPU wouldn't be able to push its exception stack frame during an access
* exception
*/
/* set data access attributes in ACR0 and ACR1 */
set_acr0(ACR_W(0) | /* read and write accesses permitted */
ACR_SP(0) | /* supervisor and user mode access permitted */
ACR_CM(ACR_CM_CACHE_INH_PRECISE) | /* cache inhibit, precise */
ACR_AMM(0) | /* control region > 16 MB */
ACR_S(ACR_S_ALL) | /* match addresses in user and supervisor mode */
ACR_E(1) | /* enable ACR */
#if MACHINE_FIREBEE
ACR_ADMSK(0x3f) | /* cover 1GB area from 0xc0000000 to 0xffffffff */
ACR_BA(0xc0000000)); /* (equals area from 3 to 4 GB */
#elif MACHINE_M5484LITE
ACR_ADMSK(0x7f) | /* cover 2 GB area from 0x80000000 to 0xffffffff */
ACR_BA(0x80000000));
#endif /* MACHINE_FIREBEE */
// set_acr1(0x601fc000);
set_acr1(ACR_W(0) |
ACR_SP(0) |
ACR_CM(0) |
#if MACHINE_FIREBEE
ACR_CM(ACR_CM_CACHEABLE_WT) | /* video RAM on the Firebee */
#elif MACHINE_M5484LITE
ACR_CM(ACR_CM_CACHE_INH_PRECISE) | /* Compact Flash on the M548xLITE */
#endif /* MACHINE_FIREBEE */
ACR_AMM(0) |
ACR_S(ACR_S_ALL) |
set_acr0(ACR_WRITE_PROTECT(0) | /* read and write accesses permitted */
ACR_SUPERVISOR_PROTECT(0) | /* supervisor and user mode access permitted */
ACR_CACHE_MODE(CACHE_WRITETHROUGH) | /* cacheable, write through */
ACR_ADDRESS_MASK_MODE(1) | /* region 13 MByte */
ACR_S(ACR_S_SUPERVISOR_MODE) | /* memory only visible from supervisor mode */
ACR_E(1) | /* enable ACR */
ACR_ADMSK(0x0a) | /* cover 12 MByte from 0x0 */
ACR_BA(0)); /* start from 0x0 */
set_acr1(ACR_WRITE_PROTECT(0) | /* read and write accesses permitted */
ACR_SUPERVISOR_PROTECT(0) | /* supervisor and user mode access permitted */
ACR_CACHE_MODE(CACHE_WRITETHROUGH) | /* cacheable, write through */
ACR_ADDRESS_MASK_MODE(0) | /* region > 16 MByte */
ACR_S(ACR_S_SUPERVISOR_MODE) | /* memory only visible from supervisor mode */
ACR_E(1) | /* enable ACR */
ACR_ADMSK(0x1f) | /* cover 495 MByte from 0x1000000 */
ACR_BA(0x01000000)); /* all Fast RAM */
/*
* set instruction access attributes in ACR2 and ACR3. This is the same as above, basically:
* enable supervisor access to all SDRAM
*/
set_acr2(ACR_WRITE_PROTECT(0) |
ACR_SUPERVISOR_PROTECT(0) |
ACR_CACHE_MODE(CACHE_WRITETHROUGH) |
ACR_ADDRESS_MASK_MODE(1) |
ACR_S(ACR_S_SUPERVISOR_MODE) |
ACR_E(1) |
ACR_ADMSK(0x0c) |
ACR_BA(0x0));
set_acr3(ACR_WRITE_PROTECT(0) |
ACR_SUPERVISOR_PROTECT(0) |
ACR_CACHE_MODE(CACHE_WRITETHROUGH) |
ACR_ADDRESS_MASK_MODE(0) |
ACR_S(ACR_S_SUPERVISOR_MODE) |
ACR_E(1) |
ACR_ADMSK(0x1f) |
ACR_BA(0x60000000));
/* set instruction access attributes in ACR2 and ACR3 */
//set_acr2(0xe007c400);
set_acr2(ACR_W(0) |
ACR_SP(0) |
ACR_CM(0) |
ACR_CM(ACR_CM_CACHEABLE_WT) |
ACR_AMM(1) |
ACR_S(ACR_S_ALL) |
ACR_E(1) |
ACR_ADMSK(0x7) |
ACR_BA(0xe0000000));
/* disable ACR3 */
set_acr3(0x0);
ACR_BA(0x0f));
set_mmubar(MMUBAR + 1); /* set and enable MMUBAR */
/* clear all MMU TLB entries */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_CA;
/* create locked TLB entries */
/*
* 0x0000'0000 - 0x000F'FFFF (first MB of physical memory) locked virtual = physical
*/
MCF_MMU_MMUTR = 0x0 | /* virtual address */
MCF_MMU_MMUTR_SG | /* shared global */
MCF_MMU_MMUTR_V; /* valid */
MCF_MMU_MMUDR = 0x0 | /* physical address */
MCF_MMU_MMUDR_SZ(0) | /* 1 MB page size */
MCF_MMU_MMUDR_CM(0x1) | /* cacheable, copyback */
MCF_MMU_MMUDR_R | /* read access enable */
MCF_MMU_MMUDR_W | /* write access enable */
MCF_MMU_MMUDR_X | /* execute access enable */
MCF_MMU_MMUDR_LK; /* lock entry */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ACC | /* access TLB, data */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ITLB | /* instruction */
MCF_MMU_MMUOR_ACC | /* access TLB */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
/*
* 0x00d0'0000 - 0x00df'ffff (last megabyte of ST RAM = Falcon video memory) locked ID = 6
* mapped to physical address 0x60d0'0000 (FPGA video memory)
* video RAM: read write execute normal write true
*/
MCF_MMU_MMUTR = 0x00d00000 | /* virtual address */
#if defined(MACHINE_FIREBEE)
MCF_MMU_MMUTR_ID(SCA_PAGE_ID) |
#endif /* MACHINE_FIREBEE */
MCF_MMU_MMUTR_SG | /* shared global */
MCF_MMU_MMUTR_V; /* valid */
#if defined(MACHINE_FIREBEE)
/* map FPGA video memory for FireBee only */
MCF_MMU_MMUDR = 0x60d00000 | /* physical address */
#elif defined(MACHINE_M5484LITE)
MCF_MMU_MMUDR = 0x00d00000 | /* physical address */
#endif /* MACHINE_FIREBEE */
MCF_MMU_MMUDR_SZ(0) | /* 1 MB page size */
MCF_MMU_MMUDR_CM(0x0) | /* cachable writethrough */
/* caveat: can't be supervisor protected since TOS puts the application stack there! */
//MCF_MMU_MMUDR_SP | /* supervisor protect */
MCF_MMU_MMUDR_R | /* read access enable */
MCF_MMU_MMUDR_W | /* write access enable */
MCF_MMU_MMUDR_X | /* execute access enable */
MCF_MMU_MMUDR_LK; /* lock entry */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ACC | /* access TLB, data */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ITLB | /* instruction */
MCF_MMU_MMUOR_ACC | /* access TLB */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
#if defined(MACHINE_FIREBEE)
video_tlb = 0x2000; /* set page as video page */
video_sbt = 0x0; /* clear time */
#endif /* MACHINE_FIREBEE */
/*
* Make the TOS (in SDRAM) read-only
* This maps virtual 0x00e0'0000 - 0x00ef'ffff to the same virtual address
*/
MCF_MMU_MMUTR = TOS | /* virtual address */
MCF_MMU_MMUTR_SG | /* shared global */
MCF_MMU_MMUTR_V; /* valid */
MCF_MMU_MMUDR = TOS | /* physical address */
MCF_MMU_MMUDR_SZ(0) | /* 1 MB page size */
MCF_MMU_MMUDR_CM(0x1) | /* cachable copyback */
MCF_MMU_MMUDR_R | /* read access enable */
//MCF_MMU_MMUDR_W | /* write access enable (FIXME: for now) */
MCF_MMU_MMUDR_X | /* execute access enable */
MCF_MMU_MMUDR_LK; /* lock entry */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ACC | /* access TLB, data */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ITLB | /* instruction */
MCF_MMU_MMUOR_ACC | /* access TLB */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
#if MACHINE_FIREBEE
/*
* Map FireBee I/O area (0xfff0'0000 - 0xffff'ffff physical) to the Falcon-compatible I/O
* area (0x00f0'0000 - 0x00ff'ffff virtual) for the FireBee
*/
MCF_MMU_MMUTR = 0x00f00000 | /* virtual address */
MCF_MMU_MMUTR_SG | /* shared global */
MCF_MMU_MMUTR_V; /* valid */
MCF_MMU_MMUDR = 0xfff00000 | /* physical address */
MCF_MMU_MMUDR_SZ(0) | /* 1 MB page size */
MCF_MMU_MMUDR_CM(0x2) | /* nocache precise */
MCF_MMU_MMUDR_SP | /* supervisor protect */
MCF_MMU_MMUDR_R | /* read access enable */
MCF_MMU_MMUDR_W | /* write access enable */
MCF_MMU_MMUDR_X | /* execute access enable */
MCF_MMU_MMUDR_LK; /* lock entry */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ACC | /* access TLB, data */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ITLB | /* instruction */
MCF_MMU_MMUOR_ACC | /* access TLB */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
#endif /* MACHINE_FIREBEE */
/*
* Map (locked) the second last MB of physical SDRAM (this is where BaS .data and .bss reside) to the same
* virtual address. This is also used when BaS is in RAM
*/
MCF_MMU_MMUTR = (SDRAM_START + SDRAM_SIZE - 0x00200000) | /* virtual address */
MCF_MMU_MMUTR_SG | /* shared global */
MCF_MMU_MMUTR_V; /* valid */
MCF_MMU_MMUDR = (SDRAM_START + SDRAM_SIZE - 0x00200000) | /* physical address */
MCF_MMU_MMUDR_SZ(0) | /* 1 MB page size */
MCF_MMU_MMUDR_CM(0x0) | /* cacheable writethrough */
MCF_MMU_MMUDR_SP | /* supervisor protect */
MCF_MMU_MMUDR_R | /* read access enable */
MCF_MMU_MMUDR_W | /* write access enable */
MCF_MMU_MMUDR_X | /* execute access enable */
MCF_MMU_MMUDR_LK; /* lock entry */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ACC | /* access TLB, data */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ITLB | /* instruction */
MCF_MMU_MMUOR_ACC | /* access TLB */
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
* virtual address. Used uncached for drivers.
*/
MCF_MMU_MMUTR = (SDRAM_START + SDRAM_SIZE - 0x00100000) | /* virtual address */
MCF_MMU_MMUTR_SG | /* shared global */
MCF_MMU_MMUTR_V; /* valid */
MCF_MMU_MMUDR = (SDRAM_START + SDRAM_SIZE - 0x00100000) | /* physical address */
MCF_MMU_MMUDR_SZ(0) | /* 1 MB page size */
MCF_MMU_MMUDR_CM(0x2) | /* nocache precise */
MCF_MMU_MMUDR_SP | /* supervisor protect */
MCF_MMU_MMUDR_R | /* read access enable */
MCF_MMU_MMUDR_W | /* write access enable */
//MCF_MMU_MMUDR_X | /* execute access enable */
MCF_MMU_MMUDR_LK; /* lock entry */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ACC | /* access TLB, data */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ITLB | /* instruction */
MCF_MMU_MMUOR_ACC | /* access TLB */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
}
void mmutr_miss(uint32_t address)
{
dbg("MMU TLB MISS at 0x%08x\r\n", address);
flush_and_invalidate_caches();
switch (address)
/* map locked TLB entries */
for (i = 0; i < num_locked_mmu_maps; i++)
{
case keyctl:
case keybd:
/* do something to emulate the IKBD access */
dbg("IKBD access\r\n");
break;
mmu_map_page(locked_map[i].virt, locked_map[i].phys, locked_map->pagesize, locked_map->flags);
case midictl:
case midi:
/* do something to emulate MIDI access */
dbg("MIDI ACIA access\r\n");
break;
default:
/* add missed page to TLB */
MCF_MMU_MMUTR = (address & 0xfff00000) | /* virtual aligned to 1M */
MCF_MMU_MMUTR_SG | /* shared global */
MCF_MMU_MMUTR_V; /* valid */
MCF_MMU_MMUDR = (address & 0xfff00000) | /* physical aligned to 1M */
MCF_MMU_MMUDR_SZ(0) | /* 1 MB page size */
MCF_MMU_MMUDR_CM(0x1) | /* cacheable copyback */
MCF_MMU_MMUDR_R | /* read access enable */
MCF_MMU_MMUDR_W | /* write access enable */
MCF_MMU_MMUDR_X; /* execute access enable */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ACC | /* access TLB, data */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ITLB | /* instruction */
MCF_MMU_MMUOR_ACC | /* access TLB */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
if (locked_map[i].flags.page_id == SCA_PAGE_ID)
{
video_tlb = 0x2000;
video_sbt = 0x0;
}
}
}
/*
* handle an access error
* upper level routine called from access_exception inside exceptions.S
*/
bool access_exception(uint32_t pc, uint32_t format_status)
{
int fault_status;
uint32_t fault_address;
uint32_t mmu_status;
/*
* extract fault status from format_status exception stack field
*/
fault_status = format_status & 0xc030000;
mmu_status = MCF_MMU_MMUSR;
/*
* determine if access fault was caused by a TLB miss
*/
switch (fault_status)
{
case 0x4010000: /* TLB miss on opword of instruction fetch */
case 0x4020000: /* TLB miss on extension word of instruction fetch */
//fault_address = pc;
//break;
case 0x8020000: /* TLB miss on data write */
case 0xc020000: /* TLB miss on data read or read-modify-write */
fault_address = MCF_MMU_MMUAR;
/*
* the following line must stay commented or we risk a double fault (debugging
* output requiring itself a page mapping):
*/
// dbg("access fault - TLB miss at %p. Fault status = 0x0%x\r\n", pc, fault_status);
break;
default:
return false;
}
if (mmu_status & MCF_MMU_MMUSR_HIT) /* did the last fault hit in TLB? */
{
/*
* if yes, then we already mapped that page during a previous turn and this is in fact a bus error
*/
return false;
}
else
{
struct mmu_mapping *map;
if ((map = lookup_mapping(fault_address)) != NULL)
{
uint32_t mask;
switch (map->pagesize)
{
case MMU_PAGE_SIZE_1M:
mask = ~(0x100000 - 1);
break;
case MMU_PAGE_SIZE_4K:
mask = ~(0x1000 - 1);
break;
case MMU_PAGE_SIZE_8K:
mask = ~(0x2000 - 1);
break;
case MMU_PAGE_SIZE_1K:
mask = ~(0x400 - 1);
break;
}
mmu_map_page(fault_address & mask, fault_address & mask, map->pagesize, map->flags);
return true;
}
}
return false;
}
void mmu_map_page(uint32_t virt, uint32_t phys, uint32_t map_size, struct map_flags flags)
{
/*
* add page to TLB
*/
MCF_MMU_MMUTR = virt | /* virtual address */
MCF_MMU_MMUTR_ID(flags.page_id) |
MCF_MMU_MMUTR_SG | /* shared global */
MCF_MMU_MMUTR_V; /* valid */
MCF_MMU_MMUDR = phys | /* physical address */
MCF_MMU_MMUDR_SZ(map_size) | /* 1 MB page size */
MCF_MMU_MMUDR_CM(flags.cache_mode) |
(flags.access & ACCESS_READ ? MCF_MMU_MMUDR_R : 0) | /* read access enable */
(flags.access & ACCESS_WRITE ? MCF_MMU_MMUDR_W : 0) | /* write access enable */
(flags.access & ACCESS_EXECUTE ? MCF_MMU_MMUDR_X : 0); /* execute access enable */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ACC | /* access TLB, data */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
MCF_MMU_MMUOR = MCF_MMU_MMUOR_ITLB | /* instruction */
MCF_MMU_MMUOR_ACC | /* access TLB */
MCF_MMU_MMUOR_UAA; /* update allocation address field */
dbg("mapped virt=%p to phys=%p\r\n", virt, phys);
}

View File

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

View File

@@ -2,7 +2,7 @@
* File: sysinit.c
* Purpose: Power-on Reset configuration of the Firebee board.
*
* Notes:
* Notes:
*
* This file is part of BaS_gcc.
*
@@ -37,14 +37,17 @@
#include "wait.h"
#include "util.h"
#include "version.h"
#ifdef MACHINE_FIREBEE
#if defined(MACHINE_FIREBEE)
#include "firebee.h"
#endif /* MACHINE_FIREBEE */
#ifdef MACHINE_M5484LITE
#elif defined(MACHINE_M5484LITE)
#include "m5484l.h"
#elif defined(MACHINE_M54455)
#include "m54455.h"
#else
#error "unknown machine"
#endif /* MACHINE_M5484LITE */
#
#include "dma.h"
#include "mod_devicetable.h"
#include "pci_ids.h"
@@ -52,12 +55,14 @@
#include "usb.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 */
/*
* init SLICE TIMER 0
* init SLICE TIMER 0
* all = 32.538 sec = 30.736mHz
* BYT0 = 127.1ms/tick = 7.876Hz offset 0
* BYT1 = 496.5us/tick = 2.014kHz offset 1
@@ -86,16 +91,16 @@ void init_gpio(void)
* configure all four 547x GPIO module DMA pins:
*
* /DACK1 - DMA acknowledge 1
* /DACK0 - DMA acknowledge 0
* /DREQ1 - DMA request 1
* /DREQ0 - DMA request 0
*
* /DACK0 - DMA acknowledge 0
* /DREQ1 - DMA request 1
* /DREQ0 - DMA request 0
*
* for DMA operation
*/
MCF_PAD_PAR_DMA = MCF_PAD_PAR_DMA_PAR_DACK0(0b11) |
MCF_PAD_PAR_DMA_PAR_DACK1(0b11) |
MCF_PAD_PAR_DMA_PAR_DREQ1(0b11) |
MCF_PAD_PAR_DMA_PAR_DREQ0(0b11);
MCF_PAD_PAR_DMA = MCF_PAD_PAR_DMA_PAR_DACK0(0x3) |
MCF_PAD_PAR_DMA_PAR_DACK1(0x3) |
MCF_PAD_PAR_DMA_PAR_DREQ1(0x3) |
MCF_PAD_PAR_DMA_PAR_DREQ0(0x3);
/*
* 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_TIN2(MCF_PAD_PAR_TIMER_PAR_TIN2_IRQ2) |
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 */
MCF_FBCS1_CSAR = 0xFFF00000; /* ATARI I/O ADRESS */
MCF_FBCS1_CSCR = MCF_FBCS_CSCR_PS_16 /* 16BIT PORT */
| MCF_FBCS_CSCR_WS(8) /* DEFAULT 8WS */
| MCF_FBCS_CSCR_AA; /* AA */
| MCF_FBCS_CSCR_WS(8) /* DEFAULT 8WS */
| MCF_FBCS_CSCR_AA; /* AA */
MCF_FBCS1_CSMR = MCF_FBCS_CSMR_BAM_1M | MCF_FBCS_CSMR_V;
MCF_FBCS2_CSAR = 0xF0000000; // NEUER I/O ADRESS-BEREICH
MCF_FBCS2_CSCR = MCF_FBCS_CSCR_PS_32 // 32BIT PORT
| MCF_FBCS_CSCR_WS(8) // DEFAULT 4WS
| MCF_FBCS_CSCR_AA; // AA
| MCF_FBCS_CSCR_WS(8) // DEFAULT 4WS
| MCF_FBCS_CSCR_AA; // AA
MCF_FBCS2_CSMR = (MCF_FBCS_CSMR_BAM_128M // F000'0000-F7FF'FFFF
| MCF_FBCS_CSMR_V);
MCF_FBCS3_CSAR = 0xF8000000; // NEUER I/O ADRESS-BEREICH
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_FBCS_CSMR_V);
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_FBCS_CSCR_BSTR // BURST READ ENABLE
| MCF_FBCS_CSCR_BSTW; // BURST WRITE ENABLE
| MCF_FBCS_CSCR_BSTR // BURST READ ENABLE
| MCF_FBCS_CSCR_BSTW; // BURST WRITE ENABLE
MCF_FBCS4_CSMR = MCF_FBCS_CSMR_BAM_1G // 4000'0000-7FFF'FFFF
| MCF_FBCS_CSMR_V;
#elif MACHINE_M5484LITE
@@ -462,7 +453,7 @@ void init_fbcs()
| MCF_FBCS_CSCR_WS(32)
| MCF_FBCS_CSCR_ASET(1)
| MCF_FBCS_CSCR_AA;
MCF_FBCS5_CSMR = MCF_FBCS_CSMR_BAM_256M
MCF_FBCS5_CSMR = MCF_FBCS_CSMR_BAM_256M
| MCF_FBCS_CSMR_V;
#endif /* MACHINE_FIREBEE */
@@ -580,7 +571,7 @@ void init_video_ddr(void) {
/*
* 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 ehci_usb_pci_table[];
@@ -666,18 +657,20 @@ static bool i2c_bus_free(void)
/*
* TFP410 (DVI) on
*/
void dvi_on(void) {
void dvi_on(void)
{
uint8_t receivedByte;
uint8_t dummyByte; /* only used for a dummy read */
int num_tries = 0;
xprintf("DVI digital video output initialization: ");
MCF_I2C_I2FDR = 0x3c; /* divide system clock by 1280: 100kHz standard */
do {
do
{
/* 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 */
MCF_I2C_I2CR = 0x0;
@@ -814,16 +807,16 @@ void init_ac97(void) {
int va;
int vb;
int vc;
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_PAR_CTS2_BCLK
| MCF_PAD_PAR_PSC2_PAR_CTS2_BCLK
| MCF_PAD_PAR_PSC2_PAR_TXD2
| MCF_PAD_PAR_PSC2_PAR_RXD2;
MCF_PSC2_PSCMR1 = 0x0;
MCF_PSC2_PSCMR2 = 0x0;
MCF_PSC2_PSCIMR = 0x0300;
MCF_PSC2_PSCSICR = 0x03; //AC97
MCF_PSC2_PSCSICR = 0x03; //AC97
MCF_PSC2_PSCRFCR = 0x0f000000;
MCF_PSC2_PSCTFCR = 0x0f000000;
MCF_PSC2_PSCRFAR = 0x00F0;
@@ -844,7 +837,7 @@ void init_ac97(void) {
{
MCF_PSC2_PSCTB_AC97 = 0x0; //SLOT2-12:WR REG ALLES 0
}
// read register
MCF_PSC2_PSCTB_AC97 = 0xc0000000; //START SLOT1 + SLOT2, FIRST FRAME
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
}
wait(50);
va = MCF_PSC2_PSCTB_AC97;
if ((va & 0x80000fff) == 0x80000800) {
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 *) 0x51a = 0x5555aaaa; /* memval3 TOS system variable */
/* TT-RAM */
/* TT-RAM */
* (uint32_t *) 0x5a4 = FASTRAM_END; /* ramtop TOS system variable */
* (uint32_t *) 0x5a8 = 0x1357bd13; /* ramvalid TOS system variable */
* (uint32_t *) 0x5a4 = FASTRAM_END; /* ramtop TOS system variable */
* (uint32_t *) 0x5a8 = 0x1357bd13; /* ramvalid TOS system variable */
/* Jump into FireTOS */
typedef void void_func(void);
@@ -974,7 +967,7 @@ void initialize_hardware(void)
init_serial();
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
"Firebee"
#elif MACHINE_M5484LITE
@@ -1052,7 +1045,7 @@ void initialize_hardware(void)
/*
* 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_fbcs();
@@ -1090,6 +1083,7 @@ void initialize_hardware(void)
/* the following only makes sense _after_ DDRAM has been initialized */
clear_bss_segment();
xprintf(".bss segment cleared\r\n");
if (BAS_LMA != BAS_IN_RAM)
{
@@ -1103,39 +1097,17 @@ void initialize_hardware(void)
#if MACHINE_FIREBEE
if (coldboot) /* does not work with BDM */
;
init_fpga();
fpga_configured = init_fpga();
init_pll();
init_video_ddr();
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 */
driver_mem_init();
init_pci();
video_init();
/* do not try to init USB for now on the Firebee, it hangs the machine */
#ifndef MACHINE_FIREBEE
//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)
{
dev->irq_handle = NULL;
if(new != NULL)
if (new != NULL)
{
driver_mem_free(new);
new = NULL;
@@ -61,8 +61,9 @@ int usb_mouse_deregister(struct usb_device *dev)
/* registering the mouse */
int usb_mouse_register(struct usb_device *dev)
{
if(!mouse_installed && (dev->devnum != -1) && (usb_mouse_probe(dev, 0) == 1))
{ /* Ok, we found a mouse */
if (!mouse_installed && (dev->devnum != -1) && (usb_mouse_probe(dev, 0) == 1))
{
/* Ok, we found a mouse */
mse_printf("USB MOUSE found (USB: %d, devnum: %d)\r\n", dev->usbnum, dev->devnum);
mouse_installed = 1;
dev->deregister = usb_mouse_deregister;
@@ -76,12 +77,12 @@ int usb_mouse_register(struct usb_device *dev)
int drv_usb_mouse_init(void)
{
int i, j;
if(mouse_installed)
if (mouse_installed)
return -1;
/* 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 */
if (dev == NULL)
@@ -109,27 +110,27 @@ static int usb_mouse_irq(struct usb_device *dev)
int level;
#endif
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);
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;
break;
}
}
if(change)
if (change)
{
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]);
#ifdef CONFIG_USB_INTERRUPT_POLLING
level = set_ipl(7); /* mask interrupts */
#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];
old_buttons = old[1];
@@ -143,24 +144,24 @@ static int usb_mouse_irq(struct usb_device *dev)
buttons = new[0];
old_buttons = old[0];
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];
}
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(0xF2);
}
}
if(wheel != 0) /* actually like Eiffel */
if (wheel != 0) /* actually like Eiffel */
{
#define REPEAT_WHEEL 3
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(0xC8);
@@ -168,7 +169,7 @@ static int usb_mouse_irq(struct usb_device *dev)
}
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(0xD0);
@@ -197,24 +198,24 @@ static int usb_mouse_probe(struct usb_device *dev, unsigned int ifnum)
struct usb_interface_descriptor *iface;
struct usb_endpoint_descriptor *ep;
int pipe, maxp;
if(dev->descriptor.bNumConfigurations != 1)
if (dev->descriptor.bNumConfigurations != 1)
return 0;
iface = &dev->config.if_desc[ifnum];
if(iface->bInterfaceClass != 3)
if (iface->bInterfaceClass != 3)
return 0;
if(iface->bInterfaceSubClass != 1)
if (iface->bInterfaceSubClass != 1)
return 0;
if(iface->bInterfaceProtocol != 2)
if (iface->bInterfaceProtocol != 2)
return 0;
if(iface->bNumEndpoints != 1)
if (iface->bNumEndpoints != 1)
return 0;
ep = &iface->ep_desc[0];
if(!(ep->bEndpointAddress & 0x80))
if (!(ep->bEndpointAddress & 0x80))
return 0;
if((ep->bmAttributes & 3) != 3)
if ((ep->bmAttributes & 3) != 3)
return 0;
new = (unsigned char *)driver_mem_alloc(8);
if(new == NULL)
if (new == NULL)
return 0;
mse_printf("USB MOUSE found set protocol...\r\n");
/* 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 cmp;
for (i = 0; i < max; i++)
{
cmp = (*s1 - *s2);
cmp = (* (const char *) s1 - * (const char *) s2);
if (cmp != 0) return cmp;
}
return cmp;
@@ -75,7 +75,7 @@ int strcmp(const char *s1, const char *s2)
for (i = 0; *s1++ && *s2++; i++)
{
cmp * (*s1 - *s2);
cmp = (*s1 - *s2);
if (cmp != 0) return cmp;
}
return cmp;

View File

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

View File

@@ -27,5 +27,43 @@
#include <stdint.h>
#include <MCF5475.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

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