From a95752d2430fc5db3f3b90c27c3778a31090ae68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20Fr=C3=B6schle?= Date: Sun, 12 May 2013 06:30:17 +0000 Subject: [PATCH] merged trunk changes --- i2cspi_BaS_gcc/.cproject | 60 ++-- .../org.eclipse.core.resources.prefs | 2 + i2cspi_BaS_gcc/Makefile | 10 +- i2cspi_BaS_gcc/bas.lk.in | 3 + i2cspi_BaS_gcc/include/bas_printf.h | 2 + i2cspi_BaS_gcc/include/bas_string.h | 1 + i2cspi_BaS_gcc/include/usb.h | 3 +- i2cspi_BaS_gcc/include/wait.h | 2 + i2cspi_BaS_gcc/include/xhdi_sd.h | 137 ++++++++ i2cspi_BaS_gcc/sources/bas_string.c | 7 + i2cspi_BaS_gcc/sources/exceptions.S | 55 +-- i2cspi_BaS_gcc/sources/mmc.c | 8 +- i2cspi_BaS_gcc/sources/ohci-hcd.c | 1 + i2cspi_BaS_gcc/sources/xhdi_interface.c | 314 ++++++++++++++++++ i2cspi_BaS_gcc/sources/xhdi_sd.c | 215 ++++++++++++ i2cspi_BaS_gcc/sources/xhdi_vec.S | 40 +++ 16 files changed, 800 insertions(+), 60 deletions(-) create mode 100644 i2cspi_BaS_gcc/.settings/org.eclipse.core.resources.prefs create mode 100644 i2cspi_BaS_gcc/include/xhdi_sd.h create mode 100644 i2cspi_BaS_gcc/sources/xhdi_interface.c create mode 100644 i2cspi_BaS_gcc/sources/xhdi_sd.c create mode 100644 i2cspi_BaS_gcc/sources/xhdi_vec.S diff --git a/i2cspi_BaS_gcc/.cproject b/i2cspi_BaS_gcc/.cproject index 928a0bf..03fcccc 100644 --- a/i2cspi_BaS_gcc/.cproject +++ b/i2cspi_BaS_gcc/.cproject @@ -1,5 +1,7 @@ - + + + @@ -127,8 +129,9 @@ - @@ -212,34 +215,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - @@ -253,5 +231,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/i2cspi_BaS_gcc/.settings/org.eclipse.core.resources.prefs b/i2cspi_BaS_gcc/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..99f26c0 --- /dev/null +++ b/i2cspi_BaS_gcc/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +encoding/=UTF-8 diff --git a/i2cspi_BaS_gcc/Makefile b/i2cspi_BaS_gcc/Makefile index f3a9e80..10bb772 100644 --- a/i2cspi_BaS_gcc/Makefile +++ b/i2cspi_BaS_gcc/Makefile @@ -36,7 +36,7 @@ CFLAGS=-mcpu=5474\ -Wno-multichar\ -Winline\ -O \ - -fno-omit-frame-pointer\ + -fomit-frame-pointer\ -fno-strict-aliasing\ -ffreestanding\ -fleading-underscore\ @@ -80,7 +80,10 @@ CSRCS= \ $(SRCDIR)/usb_mouse.c \ $(SRCDIR)/usb_storage.c \ $(SRCDIR)/ehci-hcd.c \ - $(SRCDIR)/ohci-hcd.c + $(SRCDIR)/ohci-hcd.c \ + $(SRCDIR)/flash.c \ + $(SRCDIR)/xhdi_sd.c \ + $(SRCDIR)/xhdi_interface.c ASRCS= \ $(SRCDIR)/startcf.S \ @@ -88,7 +91,8 @@ ASRCS= \ $(SRCDIR)/mmu.S \ $(SRCDIR)/exceptions.S \ $(SRCDIR)/supervisor.S \ - $(SRCDIR)/illegal_instruction.S + $(SRCDIR)/illegal_instruction.S \ + $(SRCDIR)/xhdi_vec.S COBJS=$(patsubst $(SRCDIR)/%.o,$(OBJDIR)/%.o,$(patsubst %.c,%.o,$(CSRCS))) AOBJS=$(patsubst $(SRCDIR)/%.o,$(OBJDIR)/%.o,$(patsubst %.S,%.o,$(ASRCS))) diff --git a/i2cspi_BaS_gcc/bas.lk.in b/i2cspi_BaS_gcc/bas.lk.in index b029720..bcb33ae 100644 --- a/i2cspi_BaS_gcc/bas.lk.in +++ b/i2cspi_BaS_gcc/bas.lk.in @@ -44,6 +44,9 @@ SECTIONS objs/exceptions.o(.text) objs/supervisor.o(.text) objs/illegal_instruction.o(.text) + objs/xhdi_sd.o(.text) + objs/xhdi_interface.o(text) + objs/xhdi_vec.o(text) *(.data) *(.bss) diff --git a/i2cspi_BaS_gcc/include/bas_printf.h b/i2cspi_BaS_gcc/include/bas_printf.h index edc6c25..74d6519 100644 --- a/i2cspi_BaS_gcc/include/bas_printf.h +++ b/i2cspi_BaS_gcc/include/bas_printf.h @@ -22,6 +22,8 @@ #ifndef _BAS_PRINTF_H_ #define _BAS_PRINTF_H_ +#include +#include #include extern void xvsnprintf(char *str, size_t size, const char *fmt, va_list va); diff --git a/i2cspi_BaS_gcc/include/bas_string.h b/i2cspi_BaS_gcc/include/bas_string.h index 7f99cad..01ffe88 100644 --- a/i2cspi_BaS_gcc/include/bas_string.h +++ b/i2cspi_BaS_gcc/include/bas_string.h @@ -12,6 +12,7 @@ extern int strncmp(const char *s1, const char *s2, int max); extern char *strcpy(char *dst, const char *src); +char *strncpy(char *dst, const char *src, int max); extern size_t strlen(const char *str); extern char *strcat(char *dst, const char *src); extern char *strncat(char *dst, const char *src, int max); diff --git a/i2cspi_BaS_gcc/include/usb.h b/i2cspi_BaS_gcc/include/usb.h index 6035982..fb4c73b 100644 --- a/i2cspi_BaS_gcc/include/usb.h +++ b/i2cspi_BaS_gcc/include/usb.h @@ -34,6 +34,7 @@ #include "mod_devicetable.h" #include "pci_ids.h" #include "part.h" +#include "wait.h" #ifdef PCI_XBIOS @@ -337,7 +338,7 @@ int usb_bulk_msg(struct usb_device *dev, unsigned int pipe, void *data, int len, int usb_submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer, int transfer_len, int interval); void usb_disable_asynch(int disable); int usb_maxpacket(struct usb_device *dev, unsigned long pipe); -inline void wait_ms(unsigned long ms); + int usb_get_configuration_no(struct usb_device *dev, unsigned char *buffer, int cfgno); int usb_get_report(struct usb_device *dev, int ifnum, unsigned char type, unsigned char id, void *buf, int size); int usb_get_class_descriptor(struct usb_device *dev, int ifnum, unsigned char type, unsigned char id, void *buf, int size); diff --git a/i2cspi_BaS_gcc/include/wait.h b/i2cspi_BaS_gcc/include/wait.h index 7b33306..757b927 100644 --- a/i2cspi_BaS_gcc/include/wait.h +++ b/i2cspi_BaS_gcc/include/wait.h @@ -28,6 +28,8 @@ #define _WAIT_H_ #include +#include +#include "MCF5475.h" typedef bool (*checker_func)(void); diff --git a/i2cspi_BaS_gcc/include/xhdi_sd.h b/i2cspi_BaS_gcc/include/xhdi_sd.h new file mode 100644 index 0000000..1ed1618 --- /dev/null +++ b/i2cspi_BaS_gcc/include/xhdi_sd.h @@ -0,0 +1,137 @@ +/* + * xhdi_sd.h + * + * 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: 01.05.2013 + * Copyright 2012 M. Fröschle + */ +#ifndef _XHDI_SD_H_ +#define _XHDI_SD_H_ + +/* XHDI function numbers */ + +#define XHDI_VERSION 0 +#define XHDI_INQUIRE_TARGET 1 +#define XHDI_RESERVE 2 +#define XHDI_LOCK 3 +#define XHDI_STOP 4 +#define XHDI_EJECT 5 +#define XHDI_DRIVEMAP 6 +#define XHDI_INQUIRE_DEVICE 7 +#define XHDI_INQUIRE_DRIVER 8 +#define XHDI_NEW_COOKIE 9 +#define XHDI_READ_WRITE 10 +#define XHDI_INQUIRE_TARGET2 11 +#define XHDI_INQUIRE_DEVICE2 12 +#define XHDI_DRIVER_SPECIAL 13 +#define XHDI_GET_CAPACITY 14 +#define XHDI_MEDIUM_CHANGED 15 +#define XHDI_MINT_INFO 16 +#define XHDI_DOS_LIMITS 17 +#define XHDI_LAST_ACCESS 18 +#define XHDI_REACCESS 19 + +/* XHDI error codes */ + +#define E_OK 0 /* OK */ +#define ERROR -1 /* unspecified error */ +#define EDRVNR -2 /* drive not ready */ +#define EUNDEV -15 /* invalid device/target number */ +#define EINVFN -32 /* invalid function number */ +#define EACCDN -36 /* access denied (device currently reserved) */ +#define EDRIVE -46 /* BIOS device not served by driver */ + +/* XHDI device capabilities */ + +#define XH_TARGET_STOPPABLE (1 << 0) +#define XH_TARGET_REMOVABLE (1 << 1) +#define XH_TARGET_LOCKABLE (1 << 2) +#define XH_TARGET_EJECTABLE (1 << 3) +#define XH_TARGET_LOCKED (1 << 29) +#define XH_TARGET_STOPPED (1 << 30) +#define XH_TARGET_RESERVED (1 << 31) + +typedef struct _BPB +{ + uint16_t recsiz; /* Bytes per sector */ + uint16_t clsiz; /* Sectors per cluster */ + uint16_t clsizb; /* Bytes per cluster */ + uint16_t rdlen; /* Directory length */ + uint16_t fsiz; /* Length of the FAT */ + uint16_t fatrec; /* Start of the 2nd FAT */ + uint16_t datrec; /* 1st free sector */ + uint16_t numcl; /* Total numbr of clusters */ + uint16_t bflags; /* Flags as bit-vector */ + /* Bit 0: 0 (12-Bit-FAT), 1 16-Bit-FAT */ + /* Bit 1: 0 (two FATs), 1 (one FAT) */ + /* only available since TOS 2.06 */ +} BPB; + +/* a riddle: how do you typedef a function pointer to a function that returns its own type? ;) */ +typedef void* (*xhdi_call_fun)(int xhdi_fun, ...); + +extern unsigned long xhdi_call(uint16_t *stack); + +extern xhdi_call_fun xhdi_sd_install(xhdi_call_fun old_vector) __attribute__((__interrupt__)); + +extern uint16_t xhdi_version(void); /* XHDI 0 */ + +extern uint32_t xhdi_inquire_target(uint16_t major, uint16_t minor, uint32_t *block_size, uint32_t *flags, + char *product_name); /* XHDI 1 */ + +extern uint32_t xhdi_reserve(uint16_t major, uint16_t minor, uint16_t do_reserve, uint16_t key); /* XHDI 2 */ + +extern uint32_t xhdi_lock(uint16_t major, uint16_t minor, uint16_t do_lock, uint16_t key); /* XHDI 3 */ + +extern uint32_t xhdi_stop(uint16_t major, uint16_t minor, uint16_t do_stop, uint16_t key); /* XHDI 4 */ + +extern uint32_t xhdi_eject(uint16_t major, uint16_t minor, uint16_t do_eject, uint16_t key); /* XHDI 5 */ + +extern uint32_t xhdi_drivemap(void); /* XHDI 6 */ + +extern uint32_t xhdi_inquire_device(uint16_t bios_device, uint16_t *major, uint16_t *minor, + uint32_t *start_sector, /* BPB */ void *bpb); /* XHDI 7 */ + +extern uint32_t xhdi_inquire_driver(uint16_t bios_device, char *name, char *version, + char *company, uint16_t *ahdi_version, uint16_t *maxIPL); /* XHDI 8 */ + +extern uint32_t xhdi_new_cookie(uint32_t newcookie); /* XHDI 9 */ + +extern uint32_t xhdi_read_write(uint16_t major, uint16_t minor, uint16_t rwflag, + uint32_t recno, uint16_t count, void *buf); /* XHDI 10 */ + +extern uint32_t xhdi_inquire_target2(uint16_t major, uint16_t minor, uint32_t *block_size, + uint32_t *device_flags, char *product_name, uint16_t stringlen); /* XHDI 11 */ + +extern uint32_t xhdi_inquire_device2(uint16_t bios_device, uint16_t *major, uint16_t *minor, + uint32_t *start_sector, BPB *bpb, uint32_t *blocks, char *partid); /* XHDI 12 */ + +extern uint32_t xhdi_driver_special(uint32_t key1, uint32_t key2, uint16_t subopcode, void *data); /* XHDI 13 */ + +extern uint32_t xhdi_get_capacity(uint16_t major, uint16_t minor, uint32_t *blocks, uint32_t *bs); /* XHDI 14 */ + +extern uint32_t xhdi_medium_changed(uint16_t major, uint16_t minor); /* XHDI 15 */ + +extern uint32_t xhdi_mint_info(uint16_t opcode, void *data); /* XHDI 16 */ + +extern uint32_t xhdi_dos_limits(uint16_t which, uint32_t limit); /* XHDI 17 */ + +extern uint32_t xhdi_last_access(uint16_t major, uint16_t minor, uint32_t *ms); /* XHDI 18 */ + +extern uint32_t xhdi_reaccess(uint16_t major, uint16_t minor); /* XHDI 19 */ + +#endif /* _XHDI_SD_H_ */ diff --git a/i2cspi_BaS_gcc/sources/bas_string.c b/i2cspi_BaS_gcc/sources/bas_string.c index f8ef732..6fb19b5 100644 --- a/i2cspi_BaS_gcc/sources/bas_string.c +++ b/i2cspi_BaS_gcc/sources/bas_string.c @@ -28,6 +28,13 @@ char *strcpy(char *dst, const char *src) return ptr; } +char *strncpy(char *dst, const char *src, int max) +{ + char *ptr = dst; + + while ((*dst++ = *src++) != '\0' && max-- >= 0); + return ptr; +} int atoi(const char *c) { int value = 0; diff --git a/i2cspi_BaS_gcc/sources/exceptions.S b/i2cspi_BaS_gcc/sources/exceptions.S index e9688e5..2ac61e8 100644 --- a/i2cspi_BaS_gcc/sources/exceptions.S +++ b/i2cspi_BaS_gcc/sources/exceptions.S @@ -20,6 +20,7 @@ .extern _video_tlb .extern _video_sbt .extern cpusha + .extern _xhdi_sd_install /* trap #0 exception vector for installation of xhdi SD card driver */ /* Register read/write macros */ #define MCF_MMU_MMUCR __MMUBAR @@ -131,31 +132,31 @@ move.w #0x2700,sr // disable interrupt subq.l #8,a7 - movem.l d0/a5,(a7) // register sichern + movem.l d0/a5,(a7) // save registers lea MCF_EPORT_EPFR,a5 move.b #\clr_int,(a5) // clear int pending // test auf protect mode --------------------- move.b DIP_SWITCHa,d0 btst #7,d0 - bne irq_protect // ja-> + bne irq_protect // ja-> // ------------------------------------------- - movem.l (a7),d0/a5 // register zurück + movem.l (a7),d0/a5 // restore registers addq.l #8,a7 move.l \vector,-(a7) move #0x2\int_mask\()00,sr rts irq_protect: - move.l usp,a5 // usp holen - tst.b _rt_mod // supervisor? - bne sev_supint // ja -> - mov3q.l #-1,_rt_mod // auf supervisor setzen - move.l a5,_rt_usp // rt_usp speichern - move.l _rt_ssp,a5 // rt_ssp holen + move.l usp,a5 // get usp + tst.b _rt_mod // supervisor mode active? + bne sev_supint // yes -> + mov3q.l #-1,_rt_mod // enable supervisor mode + move.l a5,_rt_usp // save rt_usp + move.l _rt_ssp,a5 // get rt_ssp #ifdef cf_stack - move.l 12(a7),-(a5) // pc transferieren + move.l 12(a7),-(a5) // transfer pc move.l 8(a7),-(a5) // sr,vec #else - move.w 8(a7),-(a5) // vector nr. + move.w 8(a7),-(a5) // vector no move.l 12(a7),-(a5) // pc verschieben move.w 10(a7),-(a5) // sr verschieben #endif @@ -209,15 +210,15 @@ _vec_init: clr.l _rt_ssp clr.l _rt_usp clr.l _rt_vbr - move.l #__RAMBAR0,d0 // sind in rambar0 + move.l #__RAMBAR0,d0 // exception vectors reside in rambar0 movec d0,VBR move.l d0,a0 move.l a0,a2 init_vec: move.l #256,d0 - lea std_exc_vec(pc),a1 // standard vector + lea std_exc_vec(pc),a1 // standard vector init_vec_loop: - move.l a1,(a2)+ // mal standard vector f�r alle setzen + move.l a1,(a2)+ // set standard vector for all exceptions subq.l #1,d0 bne init_vec_loop @@ -265,6 +266,10 @@ init_vec_loop: move.l a1,0xdc(a0) no_protect_vectors: + // trap #0 (without any parameters for now) is used to provide BaS' XHDI + // routine address to EmuTOS. + lea _xhdi_sd_install,a1 + move.l a1,0x80(a0) // trap #0 exception vector // int 1-7 lea irq1(pc),a1 @@ -360,14 +365,14 @@ sev_sup: add.l _rt_vbr,d0 // + basis move.l d0,a5 move.l (a5),12(a7) // hier geht's weiter - movem.l (a7),d0/a5 // register zur�ck + movem.l (a7),d0/a5 // register zurück addq.l #8,a7 rte // und weg //******************************************* reset_vector: move.w #0x2700,sr // disable interrupt move.l #0x31415926,d0 - cmp.l 0x426,d0 // reset vector g�ltg? + cmp.l 0x426,d0 // reset vector gültg? beq std_exc_vec // ja-> jmp _rom_entry // sonst kaltstart acess: @@ -467,7 +472,7 @@ irq6: // mfp // test auf timeout screen adr change ------------------------------------------------------- move.l _video_sbt,d0 beq irq6_non_sca // wenn 0 nichts zu tun - sub.l #0x70000000,d0 // 14 sec abz�hlen + sub.l #0x70000000,d0 // 14 sec abzählen lea MCF_SLT0_SCNT,a5 cmp.l (a5),d0 // aktuelle zeit weg ble irq6_non_sca // noch nicht abgelaufen @@ -487,13 +492,13 @@ irq6: // mfp swap d4 move.l d4,MCF_MMU_MMUAR mvz.w #0x10e,d4 - move.l d4,MCF_MMU_MMUOR // eintr�ge holen aus mmu + move.l d4,MCF_MMU_MMUOR // einträge holen aus mmu nop move.l MCF_MMU_MMUTR,d4 // ID holen lsr.l #2,d4 // bit 9 bis 2 cmp.w #sca_page_ID,d4 // ist screen change ID? bne irq6_sca_pn // nein -> page keine screen area next -// eintrag �ndern +// eintrag �ndern add.l #std_mmutr,d0 move.l d3,d1 // page 0? beq irq6_sca_pn0 // ja -> @@ -527,9 +532,9 @@ irq6_sca_pn: move.l #0x2000,d0 move.l d0,_video_tlb // anfangszustand wieder herstellen - clr.l _video_sbt // zeit l�schen + clr.l _video_sbt // zeit löschen - movem.l (a7),d0-d4/a0-a1 // register zur�ck + movem.l (a7),d0-d4/a0-a1 // register zurück lea 28(a7),a7 irq6_non_sca: // test auf acsi dma ----------------------------------------------------------------- @@ -566,9 +571,9 @@ irq6_2: move.l 0xF0020000,a5 // vector holen add.l _rt_vbr,a5 // basis move.l (a5),d0 // vector holen - move.l 4(a7),a5 // a5 zur�ck + move.l 4(a7),a5 // a5 zurück move.l d0,4(a7) // vector eintragen - move.l (a7)+,d0 // d0 zur�ck + move.l (a7)+,d0 // d0 zurück move #0x2600,sr rts irq6_3: @@ -590,7 +595,7 @@ irq6_3: move.l 0xF0020000,a5 // vector holen: intack routine add.l _rt_vbr,a5 // virtuelle VBR des Systems move.l (a5),12(a7) // hier gehts weiter - movem.l (a7),d0/a5 // register zur�ck + movem.l (a7),d0/a5 // register zurück addq.l #8,a7 move.b #6,2(a7) // intmaske setzen rte // und weg @@ -609,7 +614,7 @@ sev_sup6: move.l 0xF0020000,a5 // vector holen: intack routine add.l _rt_vbr,a5 // virtuelle VBR des Systems move.l (a5),12(a7) // hier gehts weiter - movem.l (a7),d0/a5 // register zur�ck + movem.l (a7),d0/a5 // register zurück rts .data diff --git a/i2cspi_BaS_gcc/sources/mmc.c b/i2cspi_BaS_gcc/sources/mmc.c index 78ca486..f2f5479 100644 --- a/i2cspi_BaS_gcc/sources/mmc.c +++ b/i2cspi_BaS_gcc/sources/mmc.c @@ -26,9 +26,9 @@ #define CS_LOW() { dspi_fifo_val |= MCF_DSPI_DTFR_CS5; } #define SPICLK_FAST() { MCF_DSPI_DCTAR0 = MCF_DSPI_DCTAR_TRSZ(0b111) | /* transfer size = 8 bit */ \ - MCF_DSPI_DCTAR_PCSSCK(0b01) | /* 1 clock DSPICS to DSPISCK delay prescaler */ \ - MCF_DSPI_DCTAR_PASC_1CLK | /* 1 clock DSPISCK to DSPICS negation prescaler */ \ - MCF_DSPI_DCTAR_PDT_1CLK | /* 1 clock delay between DSPICS assertions prescaler */ \ + MCF_DSPI_DCTAR_PCSSCK(0b11) | /* 1 clock DSPICS to DSPISCK delay prescaler */ \ + MCF_DSPI_DCTAR_PASC_3CLK | /* 1 clock DSPISCK to DSPICS negation prescaler */ \ + MCF_DSPI_DCTAR_PDT_3CLK | /* 1 clock delay between DSPICS assertions prescaler */ \ MCF_DSPI_DCTAR_PBR_3CLK | /* 3 clock Baudrate prescaler */ \ MCF_DSPI_DCTAR_ASC(0b0000) | /* 2 */ \ MCF_DSPI_DCTAR_DT(0b0000) | /* 2 */ \ @@ -249,7 +249,7 @@ int rcvr_datablock ( /* 1:OK, 0:Error */ ) { uint8_t token; - uint32_t target = MCF_SLT_SCNT(0) - (200 * 1000L * 132); + uint32_t target = MCF_SLT_SCNT(0) - (400 * 1000L * 132); do { /* Wait for DataStart token in timeout of 200ms */ token = xchg_spi(0xFF); diff --git a/i2cspi_BaS_gcc/sources/ohci-hcd.c b/i2cspi_BaS_gcc/sources/ohci-hcd.c index 094ac26..ae58617 100644 --- a/i2cspi_BaS_gcc/sources/ohci-hcd.c +++ b/i2cspi_BaS_gcc/sources/ohci-hcd.c @@ -48,6 +48,7 @@ #include "usb.h" #include "ohci.h" +#include "wait.h" #undef OHCI_USE_NPS /* force NoPowerSwitching mode */ diff --git a/i2cspi_BaS_gcc/sources/xhdi_interface.c b/i2cspi_BaS_gcc/sources/xhdi_interface.c new file mode 100644 index 0000000..10c8362 --- /dev/null +++ b/i2cspi_BaS_gcc/sources/xhdi_interface.c @@ -0,0 +1,314 @@ +/* + * xhdi_sd.c + * + * 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: 01.05.2013 + * Copyright 2012: M. Fröschle + */ + +#include +#include + +#include "xhdi_sd.h" +#include "bas_printf.h" + + +unsigned long xhdi_call(uint16_t *stack) +{ + uint16_t opcode = *stack; + + switch (opcode) + { + case XHDI_VERSION: + return xhdi_version(); + break; + + case XHDI_INQUIRE_TARGET: + { + struct XHINQTARGET_args + { + uint16_t opcode; + uint16_t major; + uint16_t minor; + uint32_t *blocksize; + uint32_t *deviceflags; + char *productname; + } *args = (struct XHINQTARGET_args *) stack; + + return xhdi_inquire_target(args->major, args->minor, args->blocksize, + args->deviceflags, args->productname); + } + break; + + case XHDI_RESERVE: + { + struct XHRESERVE_args + { + uint16_t opcode; + uint16_t major; + uint16_t minor; + uint16_t do_reserve; + uint16_t key; + } *args = (struct XHRESERVE_args *) stack; + + return xhdi_reserve(args->major, args->minor, args->do_reserve, args->key); + } + + case XHDI_LOCK: + { + struct XHLOCK_args + { + uint16_t opcode; + uint16_t major; + uint16_t minor; + uint16_t do_lock; + uint16_t key; + } *args = (struct XHLOCK_args *) stack; + + return xhdi_lock(args->major, args->minor, args->do_lock, args->key); + } + + case XHDI_STOP: + { + struct XHSTOP_args + { + uint16_t opcode; + uint16_t major; + uint16_t minor; + uint16_t do_stop; + uint16_t key; + } *args = (struct XHSTOP_args *) stack; + + return xhdi_stop(args->major, args->minor, args->do_stop, args->key); + } + + case XHDI_EJECT: + { + struct XHEJECT_args + { + uint16_t opcode; + uint16_t major; + uint16_t minor; + uint16_t do_eject; + uint16_t key; + } *args = (struct XHEJECT_args *) stack; + + return xhdi_eject(args->major, args->minor, args->do_eject, args->key); + } + + case XHDI_DRIVEMAP: + { + return xhdi_drivemap(); + } + + case XHDI_INQUIRE_DEVICE: + { + struct XHINQDEV_args + { + uint16_t opcode; + uint16_t drv; + uint16_t *major; + uint16_t *minor; + uint32_t *start; + BPB *bpb; + } *args = (struct XHINQDEV_args *) stack; + + return xhdi_inquire_device(args->drv, args->major, args->minor, args->start, + args->bpb); + } + + case XHDI_INQUIRE_DRIVER: + { + struct XHINQDRIVER_args + { + uint16_t opcode; + uint16_t dev; + char *name; + char *version; + char *company; + uint16_t *ahdi_version; + uint16_t *maxIPL; + } *args = (struct XHINQDRIVER_args *) stack; + + return xhdi_inquire_driver(args->dev, args->name, args->version, args->company, + args->ahdi_version, args->maxIPL); + } + + case XHDI_NEW_COOKIE: + { + struct XHNEWCOOKIE_args + { + uint16_t opcode; + uint32_t newcookie; + } *args = (struct XHNEWCOOKIE_args *) stack; + + return xhdi_new_cookie(args->newcookie); + } + + case XHDI_READ_WRITE: + { + struct XHREADWRITE_args + { + uint16_t opcode; + uint16_t major; + uint16_t minor; + uint16_t rw; + uint32_t sector; + uint16_t count; + void *buf; + } *args = (struct XHREADWRITE_args *) stack; + + return xhdi_read_write(args->major, args->minor, + args->rw, args->sector, + args->count, args->buf); + } + + case XHDI_INQUIRE_TARGET2: + { + struct XHINQTARGET2_args + { + uint16_t opcode; + uint16_t major; + uint16_t minor; + uint32_t *blocksize; + uint32_t *deviceflags; + char *productname; + uint16_t stringlen; + } *args = (struct XHINQTARGET2_args *) stack; + + return xhdi_inquire_target2(args->major, args->minor, args->blocksize, + args->deviceflags, args->productname, args->stringlen); + } + + case XHDI_INQUIRE_DEVICE2: + { + struct XHINQDEV2_args + { + uint16_t opcode; + uint16_t drv; + uint16_t *major; + uint16_t *minor; + uint32_t *start; + BPB *bpb; + uint32_t *blocks; + char *partid; + } *args = (struct XHINQDEV2_args *) stack; + + return xhdi_inquire_device2(args->drv, args->major, args->minor, args->start, + args->bpb, args->blocks, args->partid); + } + + case XHDI_DRIVER_SPECIAL: + { + struct XHDRIVERSPECIAL_args + { + uint16_t opcode; + uint32_t key1; + uint32_t key2; + uint16_t subopcode; + void *data; + } *args = (struct XHDRIVERSPECIAL_args *) stack; + + return xhdi_driver_special(args->key1, args->key2, args->subopcode, + args->data); + } + + case XHDI_GET_CAPACITY: + { + struct XHGETCAPACITY_args + { + uint16_t opcode; + uint16_t major; + uint16_t minor; + uint32_t *blocks; + uint32_t *blocksize; + } *args = (struct XHGETCAPACITY_args *) stack; + + return xhdi_get_capacity(args->major, args->minor, args->blocks, + args->blocksize); + } + + case XHDI_MEDIUM_CHANGED: + { + struct XHMEDIUMCHANGED_args + { + uint16_t opcode; + uint16_t major; + uint16_t minor; + } *args = (struct XHMEDIUMCHANGED_args *) stack; + + return xhdi_medium_changed(args->major, args->minor); + } + + case XHDI_MINT_INFO: + { + struct XHMINTINFO_args + { + uint16_t opcode; + uint16_t subopcode; + void *data; + } *args = (struct XHMINTINFO_args *) stack; + + return xhdi_mint_info(args->subopcode, args->data); + } + + case XHDI_DOS_LIMITS: + { + struct XHDOSLIMITS_args + { + uint16_t opcode; + uint16_t which; + uint32_t limit; + } *args = (struct XHDOSLIMITS_args *) stack; + + return xhdi_dos_limits(args->which, args->limit); + } + + case XHDI_LAST_ACCESS: + { + struct XHLASTACCESS_args + { + uint16_t opcode; + uint16_t major; + uint16_t minor; + uint32_t *ms; + } *args = (struct XHLASTACCESS_args *) stack; + + return xhdi_last_access(args->major, args->minor, args->ms); + } + + case XHDI_REACCESS: + { + struct XHREACCESS_args + { + uint16_t opcode; + uint16_t major; + uint16_t minor; + } *args = (struct XHREACCESS_args *) stack; + + return xhdi_reaccess(args->major, args->minor); + } + + default: + { + xprintf("unknown XHDI function 0x%x\r\n", opcode); + return EINVFN; + break; + } + } +} + diff --git a/i2cspi_BaS_gcc/sources/xhdi_sd.c b/i2cspi_BaS_gcc/sources/xhdi_sd.c new file mode 100644 index 0000000..e71abde --- /dev/null +++ b/i2cspi_BaS_gcc/sources/xhdi_sd.c @@ -0,0 +1,215 @@ +/* + * xhdi_sd.c + * + * 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: 01.05.2013 + * Copyright 2012 M. Fröschle + */ + +#include +#include + +#include "xhdi_sd.h" +#include "bas_printf.h" +#include "bas_string.h" +#include "diskio.h" + +#define DRIVER_VERSION 0x130 + +#define MY_MAJOR 65 +#define MY_MINOR 0 + +uint16_t xhdi_version(void) +{ + return DRIVER_VERSION; +} + +uint32_t xhdi_inquire_target(uint16_t major, uint16_t minor, uint32_t *block_size, uint32_t *flags, + char *product_name) +{ + return xhdi_inquire_target2(major, minor, block_size, flags, product_name, 33); +} + +uint32_t xhdi_reserve(uint16_t major, uint16_t minor, uint16_t do_reserve, uint16_t key) +{ + return ERROR; /* device cannot be reserved */ +} + +uint32_t xhdi_lock(uint16_t major, uint16_t minor, uint16_t do_lock, uint16_t key) +{ + return ERROR; /* device cannot be locked */ +} + +uint32_t xhdi_stop(uint16_t major, uint16_t minor, uint16_t do_stop, uint16_t key) +{ + return ERROR; /* device cannot be locked */ +} + +uint32_t xhdi_eject(uint16_t major, uint16_t minor, uint16_t do_eject, uint16_t key) +{ + return ERROR; /* device cannot be ejected */ +} + +uint32_t xhdi_drivemap(void) +{ + long map = (1 << ('S' - 'A')); + + return map; +} + +#define MY_MAJOR 65 +#define MY_MINOR 0 + +uint32_t xhdi_inquire_device(uint16_t bios_device, uint16_t *major, uint16_t *minor, + uint32_t *start_sector, /* BPB */ void *bpb) +{ + if (major != NULL) *major = MY_MAJOR; + if (minor != NULL) *minor = MY_MINOR; + if (start_sector != NULL) *start_sector = 0; + + return E_OK; +} + +uint32_t xhdi_inquire_driver(uint16_t bios_device, char *name, char *version, + char *company, uint16_t *ahdi_version, uint16_t *maxIPL) +{ + if (bios_device == 'S' - 'A') + { + if (name != NULL) strcpy(name, "BaS SD-card driver"); + if (version != NULL) strcpy(version, "0.1"); + if (company != NULL) strcpy(company, "Markus Fröschle"); + if (ahdi_version != NULL) *ahdi_version = 300; + if (maxIPL != NULL) *maxIPL = 7; + + return E_OK; + } + return EUNDEV; +} + +uint32_t xhdi_new_cookie(uint32_t newcookie) +{ + return ERROR; +} + +uint32_t xhdi_read_write(uint16_t major, uint16_t minor, uint16_t rwflag, + uint32_t recno, uint16_t count, void *buf) +{ + int ret; + uint16_t num_sectors; + int16_t s_count = count; + uint16_t retries; + const uint16_t max_retries = 5; + + if (major == MY_MAJOR) + { + do { + num_sectors = ((s_count > 1) ? 1 : s_count); + + retries = 0; + do { + ret = ((rwflag & 1) ? disk_write(0, buf, recno, num_sectors) : disk_read(0, buf, recno, num_sectors)); + if (ret != RES_OK && retries > max_retries) + { + xprintf("error: %d\r\n", ret); + return ERROR; + } + else if (ret != RES_OK) + { + retries++; + continue; + } + } while (retries < max_retries && ret != RES_OK); + + buf += num_sectors * 512; + recno += num_sectors; + s_count -= num_sectors; + } while (s_count > 0); + + return E_OK; + } + return EUNDEV; +} + +uint32_t xhdi_inquire_target2(uint16_t major, uint16_t minor, uint32_t *block_size, + uint32_t *device_flags, char *product_name, uint16_t stringlen) +{ + if (major == MY_MAJOR) + { + if (block_size != NULL) *block_size = 512; + if (device_flags != NULL) *device_flags = XH_TARGET_REMOVABLE; + if (product_name != NULL) strncpy(product_name, "BaS SD driver", stringlen); + + return E_OK; + + } + return EUNDEV; +} + +uint32_t xhdi_inquire_device2(uint16_t bios_device, uint16_t *major, uint16_t *minor, + uint32_t *start_sector, BPB *bpb, uint32_t *blocks, char *partid) +{ + + if (bios_device == 'S' - 'A') + { + return E_OK; + } + return EUNDEV; +} + +uint32_t xhdi_driver_special(uint32_t key1, uint32_t key2, uint16_t subopcode, void *data) +{ + return ERROR; +} + +uint32_t xhdi_get_capacity(uint16_t major, uint16_t minor, uint32_t *blocks, uint32_t *bs) +{ + if (major == MY_MAJOR) + { + if (disk_ioctl(0, GET_SECTOR_COUNT, blocks) != RES_OK) + return ERROR; + if (disk_ioctl(0, GET_SECTOR_SIZE, bs) != RES_OK) + return ERROR; + *bs = 512; + return E_OK; + } + return EUNDEV; +} + +uint32_t xhdi_medium_changed(uint16_t major, uint16_t minor) +{ + return ERROR; +} + +uint32_t xhdi_mint_info(uint16_t opcode, void *data) +{ + return ERROR; +} + +uint32_t xhdi_dos_limits(uint16_t which, uint32_t limit) +{ + return ERROR; +} + +uint32_t xhdi_last_access(uint16_t major, uint16_t minor, uint32_t *ms) +{ + return ERROR; +} + +uint32_t xhdi_reaccess(uint16_t major, uint16_t minor) +{ + return ERROR; +} diff --git a/i2cspi_BaS_gcc/sources/xhdi_vec.S b/i2cspi_BaS_gcc/sources/xhdi_vec.S new file mode 100644 index 0000000..71068ef --- /dev/null +++ b/i2cspi_BaS_gcc/sources/xhdi_vec.S @@ -0,0 +1,40 @@ +// +// XHDI entry point +// + .extern _xhdi_call + + .globl _xhdi_vec + .globl _xhdi_sd_install + +// +// this is where the XHDI cookie points to: +// + + .text +_xhdi_vec: + lea -12(sp),sp // save all used registers according to XHDI spec + movem.l d1/a0-a1,(sp) + + pea 16(sp) // forward address of parameters on stack + jsr _xhdi_call // to internal routine + addq.l #4,sp // correct stack + + movem.l (sp),d1/a0-a1 // restore registers + lea 12(sp),sp + rts + + .data +_old_vector: + .ds.l 1 + + .text + +// +// trap #0 handler to bring the address of the disk routines into TOS +// +_xhdi_sd_install: + move.l 4(sp),d0 // address of the old XHDI vector + move.l d0,_old_vector // save it - just in case we need it later + move.l #_xhdi_vec,d0 // return our BaS vector to TOS + move.l d0,a0 // + rte