From d96e0b82bc536a79174603bc06246a875385cd54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Fr=C3=B6schle?= Date: Sat, 2 Aug 2014 08:25:07 +0000 Subject: [PATCH] added tos programs that are used to interface to BaS_gcc from TOS. These programs are currently not build by default (need to call make in their respective directory for now). They expect to find a libcmini copy on the same directory level than you have your BaS_gcc folder. --- BaS_gcc/tos/jtagwait/Makefile | 97 +++++++++++ BaS_gcc/tos/jtagwait/include/driver_vec.h | 125 ++++++++++++++ BaS_gcc/tos/jtagwait/jtagwait.config | 1 + BaS_gcc/tos/jtagwait/jtagwait.creator | 1 + BaS_gcc/tos/jtagwait/jtagwait.creator.user | 186 +++++++++++++++++++++ BaS_gcc/tos/jtagwait/jtagwait.files | 2 + BaS_gcc/tos/jtagwait/jtagwait.includes | 1 + BaS_gcc/tos/jtagwait/sources/jtagwait.c | 72 ++++++++ BaS_gcc/tos/mcdcook/Makefile | 117 +++++++++++++ BaS_gcc/tos/mcdcook/include/driver_vec.h | 125 ++++++++++++++ BaS_gcc/tos/mcdcook/sources/mcdcook.c | 121 ++++++++++++++ 11 files changed, 848 insertions(+) create mode 100755 BaS_gcc/tos/jtagwait/Makefile create mode 100644 BaS_gcc/tos/jtagwait/include/driver_vec.h create mode 100644 BaS_gcc/tos/jtagwait/jtagwait.config create mode 100644 BaS_gcc/tos/jtagwait/jtagwait.creator create mode 100644 BaS_gcc/tos/jtagwait/jtagwait.creator.user create mode 100644 BaS_gcc/tos/jtagwait/jtagwait.files create mode 100644 BaS_gcc/tos/jtagwait/jtagwait.includes create mode 100644 BaS_gcc/tos/jtagwait/sources/jtagwait.c create mode 100755 BaS_gcc/tos/mcdcook/Makefile create mode 100644 BaS_gcc/tos/mcdcook/include/driver_vec.h create mode 100644 BaS_gcc/tos/mcdcook/sources/mcdcook.c diff --git a/BaS_gcc/tos/jtagwait/Makefile b/BaS_gcc/tos/jtagwait/Makefile new file mode 100755 index 0000000..2773cd5 --- /dev/null +++ b/BaS_gcc/tos/jtagwait/Makefile @@ -0,0 +1,97 @@ +CROSS=Y + +CROSSBINDIR_IS_Y=m68k-atari-mint- +CROSSBINDIR_IS_N= + +CROSSBINDIR=$(CROSSBINDIR_IS_$(CROSS)) + +UNAME := $(shell uname) +ifeq ($(CROSS), Y) +ifeq ($(UNAME),Linux) +PREFIX=m68k-atari-mint +HATARI=hatari +else +PREFIX=m68k-atari-mint +HATARI=/usr/local/bin/hatari +endif +else +PREFIX=/usr +endif + +DEPEND=depend +TOPDIR = ../.. + +INCLUDE=-I$(TOPDIR)/../libcmini/include -nostdlib +LIBS=-lcmini -nostdlib -lgcc +CC=$(PREFIX)/bin/gcc + +CC=$(CROSSBINDIR)gcc +STRIP=$(CROSSBINDIR)strip +STACK=$(CROSSBINDIR)stack + +APP=jtagwait.prg +TEST_APP=$(APP) + +CFLAGS=\ + -Os\ + -g\ + -Wl,-Map,mapfile\ + -Wall + +SRCDIR=sources +INCDIR=include +INCLUDE+=-I$(INCDIR) + +CSRCS=\ + $(SRCDIR)/jtagwait.c +ASRCS= + +COBJS=$(patsubst $(SRCDIR)/%.o,%.o,$(patsubst %.c,%.o,$(CSRCS))) +AOBJS=$(patsubst $(SRCDIR)/%.o,%.o,$(patsubst %.S,%.o,$(ASRCS))) +OBJS=$(COBJS) $(AOBJS) + +TRGTDIRS=./m5475 ./m5475/mshort +OBJDIRS=$(patsubst %,%/objs,$(TRGTDIRS)) + +# +# multilib flags. These must match m68k-atari-mint-gcc -print-multi-lib output +# +m5475/$(APP):CFLAGS += -mcpu=5475 +m5475/mshort/$(APP): CFLAGS += -mcpu=5475 -mshort + +all:$(patsubst %,%/$(APP),$(TRGTDIRS)) +# +# generate pattern rules for multilib object files. +# +define CC_TEMPLATE +$(1)/objs/%.o:$(SRCDIR)/%.c + $(CC) $$(CFLAGS) $(INCLUDE) -c $$< -o $$@ + +$(1)/objs/%.o:$(SRCDIR)/%.S + $(CC) $$(CFLAGS) $(INCLUDE) -c $$< -o $$@ + +$(1)_OBJS=$(patsubst %,$(1)/objs/%,$(OBJS)) +$(1)/$(APP): $$($(1)_OBJS) + $(CC) $$(CFLAGS) -o $$@ $(TOPDIR)/../libcmini/$(1)/startup.o $$($(1)_OBJS) -L$(TOPDIR)/../libcmini/$(1) $(LIBS) + $(STRIP) $$@ +endef +$(foreach DIR,$(TRGTDIRS),$(eval $(call CC_TEMPLATE,$(DIR)))) + +$(DEPEND): $(ASRCS) $(CSRCS) + -rm -f $(DEPEND) + for d in $(TRGTDIRS);\ + do $(CC) $(CFLAGS) $(INCLUDE) -M $(ASRCS) $(CSRCS) | sed -e "s#^\(.*\).o:#$$d/objs/\1.o:#" >> $(DEPEND); \ + done + + +clean: + @rm -f $(patsubst %,%/objs/*.o,$(TRGTDIRS)) $(patsubst %,%/$(APP),$(TRGTDIRS)) + @rm -f $(DEPEND) mapfile + +.PHONY: printvars +printvars: + @$(foreach V,$(.VARIABLES), $(if $(filter-out environment% default automatic, $(origin $V)),$(warning $V=$($V)))) + +ifneq (clean,$(MAKECMDGOALS)) +-include $(DEPEND) +endif diff --git a/BaS_gcc/tos/jtagwait/include/driver_vec.h b/BaS_gcc/tos/jtagwait/include/driver_vec.h new file mode 100644 index 0000000..8b9352a --- /dev/null +++ b/BaS_gcc/tos/jtagwait/include/driver_vec.h @@ -0,0 +1,125 @@ +/* + * driver_vec.h + * + * Interface for exposure of BaS drivers to the OS + * + * 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 . + * + * Created on: 24.10.2013 + * Author: Markus Fröschle + */ + +#ifndef _DRIVER_VEC_H_ +#define _DRIVER_VEC_H_ + + +enum driver_type +{ + END_OF_DRIVERS, /* marks end of driver list */ + BLOCKDEV_DRIVER, + CHARDEV_DRIVER, + VIDEO_DRIVER, + XHDI_DRIVER, + MCD_DRIVER, +}; + +struct generic_driver_interface +{ + uint32_t (*init)(void); + uint32_t (*read)(void *buf, size_t count); + uint32_t (*write)(const void *buf, size_t count); + uint32_t (*ioctl)(uint32_t request, ...); +}; + + +/* Chained buffer descriptor */ +typedef volatile struct MCD_bufDesc_struct MCD_bufDesc; +struct MCD_bufDesc_struct { + uint32_t flags; /* flags describing the DMA */ + uint32_t csumResult; /* checksum from checksumming performed since last checksum reset */ + int8_t *srcAddr; /* the address to move data from */ + int8_t *destAddr; /* the address to move data to */ + int8_t *lastDestAddr; /* the last address written to */ + uint32_t dmaSize; /* the number of bytes to transfer independent of the transfer size */ + MCD_bufDesc *next; /* next buffer descriptor in chain */ + uint32_t info; /* private information about this descriptor; DMA does not affect it */ +}; + +/* Progress Query struct */ +typedef volatile struct MCD_XferProg_struct { + int8_t *lastSrcAddr; /* the most-recent or last, post-increment source address */ + int8_t *lastDestAddr; /* the most-recent or last, post-increment destination address */ + uint32_t dmaSize; /* the amount of data transferred for the current buffer */ + MCD_bufDesc *currBufDesc;/* pointer to the current buffer descriptor being DMAed */ +} MCD_XferProg; + +struct dma_driver_interface +{ + int32_t version; + int32_t magic; + int32_t (*dma_set_initiator)(int initiator); + uint32_t (*dma_get_initiator)(int requestor); + void (*dma_free_initiator)(int requestor); + int32_t (*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)(int channel, int8_t *srcAddr, int16_t srcIncr, int8_t *destAddr, int16_t destIncr, + uint32_t dmaSize, uint32_t xferSize, uint32_t initiator, int32_t priority, uint32_t flags, + uint32_t funcDesc); + int (*MCD_dmaStatus)(int channel); + int (*MCD_XferProgrQuery)(int channel, MCD_XferProg *progRep); + int (*MCD_killDma)(int channel); + int (*MCD_continDma)(int channel); + int (*MCD_pauseDma)(int channel); + int (*MCD_resumeDma)(int channel); + int (*MCD_csumQuery)(int channel, uint32_t *csum); + void *(*dma_malloc)(long amount); + int (*dma_free)(void *addr); +}; + +struct xhdi_driver_interface +{ + uint32_t (*xhdivec)(); +}; + +union interface +{ + struct generic_driver_interface *gdi; + struct xhdi_driver_interface *xhdi; + struct dma_driver_interface *dma; +}; + +struct generic_interface +{ + enum driver_type type; + char name[16]; + char description[64]; + int version; + int revision; + union interface interface; +}; + +struct driver_table +{ + uint32_t bas_version; + uint32_t bas_revision; + uint32_t (*remove_handler)(); /* calling this will disable the BaS' hook into trap #0 */ + struct generic_interface *interfaces; +}; + + +#endif /* _DRIVER_VEC_H_ */ diff --git a/BaS_gcc/tos/jtagwait/jtagwait.config b/BaS_gcc/tos/jtagwait/jtagwait.config new file mode 100644 index 0000000..8cec188 --- /dev/null +++ b/BaS_gcc/tos/jtagwait/jtagwait.config @@ -0,0 +1 @@ +// ADD PREDEFINED MACROS HERE! diff --git a/BaS_gcc/tos/jtagwait/jtagwait.creator b/BaS_gcc/tos/jtagwait/jtagwait.creator new file mode 100644 index 0000000..e94cbbd --- /dev/null +++ b/BaS_gcc/tos/jtagwait/jtagwait.creator @@ -0,0 +1 @@ +[General] diff --git a/BaS_gcc/tos/jtagwait/jtagwait.creator.user b/BaS_gcc/tos/jtagwait/jtagwait.creator.user new file mode 100644 index 0000000..e0172af --- /dev/null +++ b/BaS_gcc/tos/jtagwait/jtagwait.creator.user @@ -0,0 +1,186 @@ + + + + + + ProjectExplorer.Project.ActiveTarget + 0 + + + ProjectExplorer.Project.EditorSettings + + true + false + true + + Cpp + + CppGlobal + + + + QmlJS + + QmlJSGlobal + + + 2 + UTF-8 + false + 4 + false + true + 1 + true + 0 + true + 0 + 8 + true + 1 + true + true + true + true + + + + ProjectExplorer.Project.PluginSettings + + + + ProjectExplorer.Project.Target.0 + + Desktop + Desktop + {8a828d48-5359-4872-acb6-81070c6b7c12} + 0 + 0 + 0 + + /home/mfro/Dokumente/Development/workspace/jtagwait + + + + all + + false + + + true + Make + + GenericProjectManager.GenericMakeStep + + 1 + Build + + ProjectExplorer.BuildSteps.Build + + + + + clean + + true + + + true + Make + + GenericProjectManager.GenericMakeStep + + 1 + Clean + + ProjectExplorer.BuildSteps.Clean + + 2 + false + + Default + Default + GenericProjectManager.GenericBuildConfiguration + + 1 + + + 0 + Deploy + + ProjectExplorer.BuildSteps.Deploy + + 1 + Deploy locally + + ProjectExplorer.DefaultDeployConfiguration + + 1 + + + + false + false + false + false + true + 0.01 + 10 + true + 1 + 25 + + 1 + true + false + true + valgrind + + 0 + 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + + 2 + + + + false + %{buildDir} + Custom Executable + + ProjectExplorer.CustomExecutableRunConfiguration + 3768 + true + false + false + false + true + + 1 + + + + ProjectExplorer.Project.TargetCount + 1 + + + ProjectExplorer.Project.Updater.EnvironmentId + {d01d0a15-4efd-4fa2-8e2c-f26845794427} + + + ProjectExplorer.Project.Updater.FileVersion + 15 + + diff --git a/BaS_gcc/tos/jtagwait/jtagwait.files b/BaS_gcc/tos/jtagwait/jtagwait.files new file mode 100644 index 0000000..dcdeec8 --- /dev/null +++ b/BaS_gcc/tos/jtagwait/jtagwait.files @@ -0,0 +1,2 @@ +include/driver_vec.h +sources/jtagwait.c \ No newline at end of file diff --git a/BaS_gcc/tos/jtagwait/jtagwait.includes b/BaS_gcc/tos/jtagwait/jtagwait.includes new file mode 100644 index 0000000..2996fba --- /dev/null +++ b/BaS_gcc/tos/jtagwait/jtagwait.includes @@ -0,0 +1 @@ +include \ No newline at end of file diff --git a/BaS_gcc/tos/jtagwait/sources/jtagwait.c b/BaS_gcc/tos/jtagwait/sources/jtagwait.c new file mode 100644 index 0000000..3a4f7c8 --- /dev/null +++ b/BaS_gcc/tos/jtagwait/sources/jtagwait.c @@ -0,0 +1,72 @@ +#include +#include +#include +#include + +#include "driver_vec.h" + +#define FPGA_JTAG_LOADED_FLAG ((volatile int32_t *) 0xFF101000) + +#define _MBAR ((volatile uint8_t *) 0xFF000000) +#define MCF_GPIO_PDDR_FEC1L ((volatile uint8_t *)(&_MBAR[0xA17])) +#define MCF_GPIO_PDDR_FEC1L_PDDR_FEC1L4 (0x10) +#define MCF_GPIO_PPDSDR_FEC1L ((volatile uint8_t *)(&_MBAR[0xA27])) +#define FPGA_CONFIG (1 << 2) +#define FPGA_CONF_DONE (1 << 5) + +static inline uint32_t set_ipl(uint32_t ipl) +{ + uint32_t ret; + + __asm__ __volatile__( + " move.w sr,%[ret]\r\n" /* retrieve status register */ + " andi.l #0x07,%[ipl]\n\t" /* mask out ipl bits on new value */ + " lsl.l #8,%[ipl]\n\t" /* shift them to position */ + " move.l %[ret],d0\n\t" /* retrieve original value */ + " andi.l #0x0000f8ff,d0\n\t" /* clear ipl part */ + " or.l %[ipl],d0\n\t" /* or in new value */ + " move.w d0,sr\n\t" /* put it in place */ + " andi.l #0x0700,%[ret]\r\n" /* mask out ipl bits */ + " lsr.l #8,%[ret]\r\n" /* shift them to position */ + : [ret] "=&d" (ret) /* output */ + : [ipl] "d" (ipl) /* input */ + : "d0" /* clobber */ + ); + + return ret; +} + +void wait_for_jtag(void) +{ + set_ipl(7); /* disable interrupts */ + /* + * 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 */ + /* + * now that this GPIO ports have been switched to input, we can poll for FPGA config + * started from the JTAG interface (CONFIGn goes high) and finish (CONF_DONE goes high) + */ + while (*MCF_GPIO_PPDSDR_FEC1L & FPGA_CONFIG); /* wait for JTAG reset */ + while (!(*MCF_GPIO_PPDSDR_FEC1L & FPGA_CONFIG)); /* wait for JTAG config load starting */ + while (!(*MCF_GPIO_PPDSDR_FEC1L & FPGA_CONF_DONE)); /* wait for JTAG config load finished */ + + *FPGA_JTAG_LOADED_FLAG = 1; /* indicate jtag loaded FPGA config to BaS */ + + __asm__ __volatile__( + "jmp 0xE0000000\n\t" + ); +} + +int main(int argc, char *argv[]) +{ + printf("\033E\r\nFPGA JTAG configuration support\r\n"); + printf("You may now savely load a new FPGA configuration through the JTAG interface\r\n" + "and your Firebee will reboot once finished using that new configuration.\r\n"); + Supexec(wait_for_jtag); + + return 0; /* just to make the compiler happy, we will never return */ +} + diff --git a/BaS_gcc/tos/mcdcook/Makefile b/BaS_gcc/tos/mcdcook/Makefile new file mode 100755 index 0000000..46afdfc --- /dev/null +++ b/BaS_gcc/tos/mcdcook/Makefile @@ -0,0 +1,117 @@ +CROSS=Y + +CROSSBINDIR_IS_Y=m68k-atari-mint- +CROSSBINDIR_IS_N= + +CROSSBINDIR=$(CROSSBINDIR_IS_$(CROSS)) + +UNAME := $(shell uname) +ifeq ($(CROSS), Y) +ifeq ($(UNAME),Linux) +PREFIX=m68k-atari-mint +HATARI=hatari +else +PREFIX=m68k-atari-mint +HATARI=/usr/local/bin/hatari +endif +else +PREFIX=/usr +endif + +DEPEND=depend +TOPDIR= ../.. + +INCLUDE=-I$(TOPDIR)/../libcmini/include -nostdlib +LIBS=-lcmini -nostdlib -lgcc +CC=$(PREFIX)/bin/gcc + +CC=$(CROSSBINDIR)gcc +STRIP=$(CROSSBINDIR)strip +STACK=$(CROSSBINDIR)stack + +APP=mcdcook.prg +TEST_APP=$(APP) + +CFLAGS=\ + -Os\ + -g\ + -Wl,-Map,mapfile\ + -Wall + +SRCDIR=sources +INCDIR=include +INCLUDE+=-I$(INCDIR) + +CSRCS=\ + $(SRCDIR)/mcdcook.c +ASRCS= + +COBJS=$(patsubst $(SRCDIR)/%.o,%.o,$(patsubst %.c,%.o,$(CSRCS))) +AOBJS=$(patsubst $(SRCDIR)/%.o,%.o,$(patsubst %.S,%.o,$(ASRCS))) +OBJS=$(COBJS) $(AOBJS) + +TRGTDIRS=. ./m68020-60 ./m5475 ./mshort ./m68020-60/mshort ./m5475/mshort +OBJDIRS=$(patsubst %,%/objs,$(TRGTDIRS)) + +# +# multilib flags. These must match m68k-atari-mint-gcc -print-multi-lib output +# +m68020-60/$(APP):CFLAGS += -m68020-60 +m5475/$(APP):CFLAGS += -mcpu=5475 +mshort/$(APP):CFLAGS += -mshort +m68020-60/mshort/$(APP): CFLAGS += -m68020-60 -mshort +m5475/mshort/$(APP): CFLAGS += -mcpu=5475 -mshort + +ctest: $(TEST_APP) +all:$(patsubst %,%/$(APP),$(TRGTDIRS)) +# +# generate pattern rules for multilib object files. +# +define CC_TEMPLATE +$(1)/objs/%.o:$(SRCDIR)/%.c + $(CC) $$(CFLAGS) $(INCLUDE) -c $$< -o $$@ + +$(1)/objs/%.o:$(SRCDIR)/%.S + $(CC) $$(CFLAGS) $(INCLUDE) -c $$< -o $$@ + +$(1)_OBJS=$(patsubst %,$(1)/objs/%,$(OBJS)) +$(1)/$(APP): $$($(1)_OBJS) + $(CC) $$(CFLAGS) -o $$@ $(TOPDIR)/../libcmini/$(1)/startup.o $$($(1)_OBJS) -L$(TOPDIR)/../libcmini/$(1) $(LIBS) + $(STRIP) $$@ +endef +$(foreach DIR,$(TRGTDIRS),$(eval $(call CC_TEMPLATE,$(DIR)))) + +$(DEPEND): $(ASRCS) $(CSRCS) + -rm -f $(DEPEND) + for d in $(TRGTDIRS);\ + do $(CC) $(CFLAGS) $(INCLUDE) -M $(ASRCS) $(CSRCS) | sed -e "s#^\(.*\).o:#$$d/objs/\1.o:#" >> $(DEPEND); \ + done + + +clean: + @rm -f $(patsubst %,%/objs/*.o,$(TRGTDIRS)) $(patsubst %,%/$(APP),$(TRGTDIRS)) + @rm -f $(DEPEND) mapfile + +.PHONY: printvars +printvars: + @$(foreach V,$(.VARIABLES), $(if $(filter-out environment% default automatic, $(origin $V)),$(warning $V=$($V)))) + +ifneq (clean,$(MAKECMDGOALS)) +-include $(DEPEND) +endif + +test: $(TEST_APP) + $(HATARI) --grab -w --tos $(TOPDIR)/../emutos/etos512k.img \ + --machine falcon -s 14 --cpuclock 32 --cpulevel 3 --vdi true --vdi-planes 4 \ + --vdi-width 640 --vdi-height 480 -d . $(APP) + +ftest: $(TEST_APP) + $(HATARI) --grab -w --tos /usr/share/hatari/TOS404.IMG \ + --machine falcon --cpuclock 32 --cpulevel 3 \ + -d . $(APP) + +sttest: $(TEST_APP) + $(HATARI) --grab -w --tos "/usr/share/hatari/tos106de.img" \ + --machine st --cpuclock 32 --cpulevel 3 --vdi true --vdi-planes 4 \ + --vdi-width 640 --vdi-height 480 \ + -d . $(APP) diff --git a/BaS_gcc/tos/mcdcook/include/driver_vec.h b/BaS_gcc/tos/mcdcook/include/driver_vec.h new file mode 100644 index 0000000..8b9352a --- /dev/null +++ b/BaS_gcc/tos/mcdcook/include/driver_vec.h @@ -0,0 +1,125 @@ +/* + * driver_vec.h + * + * Interface for exposure of BaS drivers to the OS + * + * 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 . + * + * Created on: 24.10.2013 + * Author: Markus Fröschle + */ + +#ifndef _DRIVER_VEC_H_ +#define _DRIVER_VEC_H_ + + +enum driver_type +{ + END_OF_DRIVERS, /* marks end of driver list */ + BLOCKDEV_DRIVER, + CHARDEV_DRIVER, + VIDEO_DRIVER, + XHDI_DRIVER, + MCD_DRIVER, +}; + +struct generic_driver_interface +{ + uint32_t (*init)(void); + uint32_t (*read)(void *buf, size_t count); + uint32_t (*write)(const void *buf, size_t count); + uint32_t (*ioctl)(uint32_t request, ...); +}; + + +/* Chained buffer descriptor */ +typedef volatile struct MCD_bufDesc_struct MCD_bufDesc; +struct MCD_bufDesc_struct { + uint32_t flags; /* flags describing the DMA */ + uint32_t csumResult; /* checksum from checksumming performed since last checksum reset */ + int8_t *srcAddr; /* the address to move data from */ + int8_t *destAddr; /* the address to move data to */ + int8_t *lastDestAddr; /* the last address written to */ + uint32_t dmaSize; /* the number of bytes to transfer independent of the transfer size */ + MCD_bufDesc *next; /* next buffer descriptor in chain */ + uint32_t info; /* private information about this descriptor; DMA does not affect it */ +}; + +/* Progress Query struct */ +typedef volatile struct MCD_XferProg_struct { + int8_t *lastSrcAddr; /* the most-recent or last, post-increment source address */ + int8_t *lastDestAddr; /* the most-recent or last, post-increment destination address */ + uint32_t dmaSize; /* the amount of data transferred for the current buffer */ + MCD_bufDesc *currBufDesc;/* pointer to the current buffer descriptor being DMAed */ +} MCD_XferProg; + +struct dma_driver_interface +{ + int32_t version; + int32_t magic; + int32_t (*dma_set_initiator)(int initiator); + uint32_t (*dma_get_initiator)(int requestor); + void (*dma_free_initiator)(int requestor); + int32_t (*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)(int channel, int8_t *srcAddr, int16_t srcIncr, int8_t *destAddr, int16_t destIncr, + uint32_t dmaSize, uint32_t xferSize, uint32_t initiator, int32_t priority, uint32_t flags, + uint32_t funcDesc); + int (*MCD_dmaStatus)(int channel); + int (*MCD_XferProgrQuery)(int channel, MCD_XferProg *progRep); + int (*MCD_killDma)(int channel); + int (*MCD_continDma)(int channel); + int (*MCD_pauseDma)(int channel); + int (*MCD_resumeDma)(int channel); + int (*MCD_csumQuery)(int channel, uint32_t *csum); + void *(*dma_malloc)(long amount); + int (*dma_free)(void *addr); +}; + +struct xhdi_driver_interface +{ + uint32_t (*xhdivec)(); +}; + +union interface +{ + struct generic_driver_interface *gdi; + struct xhdi_driver_interface *xhdi; + struct dma_driver_interface *dma; +}; + +struct generic_interface +{ + enum driver_type type; + char name[16]; + char description[64]; + int version; + int revision; + union interface interface; +}; + +struct driver_table +{ + uint32_t bas_version; + uint32_t bas_revision; + uint32_t (*remove_handler)(); /* calling this will disable the BaS' hook into trap #0 */ + struct generic_interface *interfaces; +}; + + +#endif /* _DRIVER_VEC_H_ */ diff --git a/BaS_gcc/tos/mcdcook/sources/mcdcook.c b/BaS_gcc/tos/mcdcook/sources/mcdcook.c new file mode 100644 index 0000000..5d55a0d --- /dev/null +++ b/BaS_gcc/tos/mcdcook/sources/mcdcook.c @@ -0,0 +1,121 @@ +#include +#include +#include +#include + +#include "driver_vec.h" + +struct driver_table *get_bas_drivers(void) +{ + struct driver_table *ret = NULL; + + __asm__ __volatile( + " trap #0\n\t" + " move.l d0,%[ret]\n\t" + : [ret] "=m" (ret) /* output */ + : /* no inputs */ + : /* clobbered */ + ); + + return ret; +} + +static uint32_t cookieptr(void) +{ + return * (uint32_t *) 0x5a0L; +} + +void setcookie(uint32_t cookie, uint32_t value) +{ + uint32_t *cookiejar = (uint32_t *) Supexec(cookieptr); + int num_slots; + int max_slots; + + num_slots = max_slots = 0; + do + { + if (cookiejar[0] == cookie) + { + cookiejar[1] = value; + return; + } + cookiejar = &(cookiejar[2]); + num_slots++; + } while (cookiejar[-2]); + + /* + * Here we are at the end of the list and did not find our cookie. + * Let's check if there is any space left and append our value to the + * list if so. If not, we are lost (extending the cookie jar does only + * work from TSRs) + */ + if (cookiejar[-1]) + max_slots = cookiejar[-1]; + + if (max_slots > num_slots) + { + /* relief, there is space left, extend the list */ + cookiejar[0] = cookiejar[-2]; + cookiejar[1] = cookiejar[-1]; + /* add the new element */ + cookiejar[-2] = cookie; + cookiejar[-1] = value; + } + else + printf("cannot set cookie, cookie jar is full!\r\n"); +} + +# define COOKIE_DMAC 0x444D4143L /* FireTOS DMA API */ + +static char *dt_to_str(enum driver_type dt) +{ + switch (dt) + { + case BLOCKDEV_DRIVER: return "generic block device driver"; + case CHARDEV_DRIVER: return "generic character device driver"; + case VIDEO_DRIVER: return "video/framebuffer driver"; + case XHDI_DRIVER: return "XHDI compatible hard disk driver"; + case MCD_DRIVER: return "multichannel DMA driver"; + default: return "unknown driver type"; + } +} + +int main(int argc, char *argv[]) +{ + struct driver_table *dt; + void *ssp; + + (void) Cconws("retrieve BaS driver interface\r\n"); + + ssp = (void *) Super(0L); + dt = get_bas_drivers(); + if (dt) + { + struct generic_interface *ifc = &dt->interfaces[0]; + + printf("BaS driver table found at %p, BaS version is %d.%d\r\n", dt, + dt->bas_version, dt->bas_revision); + + while (ifc->type != END_OF_DRIVERS) + { + printf("driver \"%s (%s)\" found,\r\n" + "interface type is %d (%s),\r\n" + "version %d.%d\r\n\r\n", + ifc->name, ifc->description, ifc->type, dt_to_str(ifc->type), + ifc->version, ifc->revision); + if (ifc->type == MCD_DRIVER) + { + setcookie(COOKIE_DMAC, ifc->interface.dma); + printf("\r\nDMAC cookie set to %p\r\n", ifc->interface.dma); + } + ifc++; + } + } + Super(ssp); + + while (Cconis()) Cconin(); /* eat keys */ + printf("press any key to continue\n\r"); + // while (! Cconis()); + return 0; +} +