socz80: move to the new issue sd driver
authorAlan Cox <alan@linux.intel.com>
Fri, 30 Jan 2015 23:39:04 +0000 (23:39 +0000)
committerAlan Cox <alan@linux.intel.com>
Fri, 30 Jan 2015 23:39:04 +0000 (23:39 +0000)
With this in place we mount the root file system and blow up trying to start
init.

Kernel/platform-socz80/Makefile
Kernel/platform-socz80/config.h
Kernel/platform-socz80/devices.c
Kernel/platform-socz80/devsd.c [deleted file]
Kernel/platform-socz80/devsd.h [deleted file]
Kernel/platform-socz80/devsd_hw.s [deleted file]
Kernel/platform-socz80/devsdspi.c [new file with mode: 0644]
Kernel/platform-socz80/fuzix.lnk
Kernel/platform-socz80/main.c
Kernel/platform-socz80/socz80.s

index 448866a..fca4864 100644 (file)
@@ -1,23 +1,31 @@
 
-CSRCS = devlpr.c devtty.c devsd.c devrd.c
+CSRCS = devlpr.c devtty.c devrd.c devsdspi.c
 CSRCS += devices.c main.c
 
-ASRCS = crt0.s devsd_hw.s devrd_hw.s socz80.s
+ASRCS = crt0.s devrd_hw.s socz80.s
 ASRCS += tricks.s usermem.s commonmem.s
 
+DSRCS = ../dev/devsd.c ../dev/mbr.c ../dev/blkdev.c
+DOBJS = $(patsubst ../dev/%.c,%.rel, $(DSRCS))
+
 COBJS = $(CSRCS:.c=.rel)
 AOBJS = $(ASRCS:.s=.rel)
-OBJS  = $(COBJS) $(AOBJS)
+OBJS  = $(COBJS) $(AOBJS) $(DOBJS)
+
+CROSS_CCOPTS += -I../dev/
 
-JUNK = $(CSRCS:.c=.lst) $(CSRCS:.c=.asm) $(CSRCS:.c=.sym) $(ASRCS:.s=.lst) $(ASRCS:.s=.sym) $(CSRCS:.c=.rst) $(ASRCS:.s=.rst)
+JUNK = *.rel *.lst *.asm *.sym *.rst *.map *.ihx *.bin
 
 all:   $(OBJS)
 
+$(AOBJS): %.rel: %.s
+       $(CROSS_AS) $(ASOPTS) $<
+
 $(COBJS): %.rel: %.c
        $(CROSS_CC) $(CROSS_CCOPTS) -c $<
 
-$(AOBJS): %.rel: %.s
-       $(CROSS_AS) $(ASOPTS) $<
+$(DOBJS): %.rel: ../dev/%.c
+       $(CROSS_CC) $(CROSS_CCOPTS) -c $<
 
 clean:
        rm -f $(OBJS) $(JUNK)  core *~ 
index 79a386a..c80e571 100644 (file)
@@ -34,3 +34,6 @@
 #define TTYDEV   BOOT_TTY /* Device used by kernel for messages, panics */
 #define NBUFS    10       /* Number of block buffers */
 #define NMOUNTS         4        /* Number of mounts at a time */
+
+#define MAX_BLKDEV  1    /* Only the one SPI supported for now */
+#define SD_DRIVE_COUNT 1
\ No newline at end of file
index 76d715e..4eb4c84 100644 (file)
@@ -2,26 +2,27 @@
 #include <tty.h>
 #include <version.h>
 #include <kdata.h>
-#include <devsd.h>
 #include <devrd.h>
 #include <devsys.h>
 #include <devlpr.h>
 #include <devtty.h>
+#include <devsd.h>
+#include <blkdev.h>
 
 struct devsw dev_tab[] =  /* The device driver switch table */
 {
 // minor    open         close        read      write       ioctl
 // -----------------------------------------------------------------
   /* 0: /dev/sd                SD disc block devices  */
-  {  sd_open,     no_close,    sd_read,   sd_write,   no_ioctl },
+  {  blkdev_open,  no_close,   blkdev_read,    blkdev_write,   blkdev_ioctl },
   /* 1: /dev/hd                Hard disc block devices (RAMdisc) */
-  {  rd_open,     no_close,    rd_read,   rd_write,   no_ioctl },
+  {  rd_open,      no_close,    rd_read,   rd_write,   no_ioctl },
   /* 2: /dev/tty       TTY devices */
   {  tty_open,     tty_close,   tty_read,  tty_write,  tty_ioctl },
   /* 3: /dev/lpr       Printer devices */
   {  lpr_open,     lpr_close,   no_rdwr,   lpr_write,  no_ioctl  },
   /* 4: /dev/mem etc   System devices (one offs) */
-  {  no_open,      no_close,    sys_read, sys_write, sys_ioctl  },
+  {  no_open,      no_close,    sys_read,  sys_write,  sys_ioctl  },
   /* Pack to 7 with nxio if adding private devices and start at 8 */
 };
 
@@ -37,5 +38,5 @@ bool validdev(uint16_t dev)
 
 void device_init(void)
 {
-  sd_init();
+  devsd_init();
 }
diff --git a/Kernel/platform-socz80/devsd.c b/Kernel/platform-socz80/devsd.c
deleted file mode 100644 (file)
index 7bd9e62..0000000
+++ /dev/null
@@ -1,395 +0,0 @@
-/*-----------------------------------------------------------------------*/
-/* socz80 SD card driver                                                 */
-/* Based on:                                                             */
-/*   MMCv3/SDv1/SDv2 (in SPI mode) control module  (C)ChaN, 2007         */
-/*  (from http://www.cl.cam.ac.uk/teaching/1011/P31/lib/diskio.c)        */
-/* and http://elm-chan.org/docs/mmc/mmc_e.html                           */
-/*-----------------------------------------------------------------------*/
-
-#include <kernel.h>
-#include <kdata.h>
-#include <printf.h>
-#include <timer.h>
-#include <devsd.h>
-#include <stdbool.h>
-
-/* keep track of current card type, UZI partition offset */
-static int sd_card_type;
-static unsigned long sd_first_uzi_sector;
-
-/* used to track current transfer in progress */
-static int sd_blockdev_count;
-static char *sd_dptr;
-static int sd_dlen;
-static uint16_t sd_blocks;
-static unsigned long sd_next_block;
-
-void sd_setup(uint8_t minor, uint8_t rawflag)
-{
-    blkno_t block;
-
-    if(rawflag){
-        sd_dlen = udata.u_count;
-        sd_dptr = udata.u_base;
-        block = udata.u_offset >> 9;
-        sd_blocks = sd_dlen >> 9;
-    }else{
-        sd_dlen = 512;
-        sd_dptr = udata.u_buf->bf_data;
-        block = udata.u_buf->bf_blk;
-        sd_blocks = 1;
-    }
-
-    if(sd_blocks != 1)
-        panic("sd: unexpected block count");
-
-    sd_next_block = sd_first_uzi_sector + /* start of our partition */
-        (((unsigned long)minor) << UZI_BLOCKDEV_SIZE_LOG2_SECTORS) + /* start of this minor device */
-        ((unsigned long)block); /* requested sector */
-}
-
-int sd_open(uint8_t minor, uint16_t flag)
-{
-    flag;
-    if(minor < sd_blockdev_count){
-        return 0;
-    } else {
-        udata.u_error = EIO;
-        return -1;
-    }
-}
-
-int sd_readwrite(uint8_t minor, uint8_t rawflag, bool do_write)
-{
-    int attempt;
-    for(attempt=0; attempt<5; attempt++){
-        sd_setup(minor, rawflag);
-        if(do_write){
-            if(sd_write_sector(sd_dptr, sd_next_block))
-                return sd_blocks;
-        }else{
-            if(sd_read_sector(sd_dptr, sd_next_block))
-                return sd_blocks;
-        }
-        kputs("sd: failed, resetting.\n");
-        if(sd_init())
-            break;
-    }
-    return -1;
-}
-
-int sd_read(uint8_t minor, uint8_t rawflag, uint8_t flag)
-{
-    flag;
-    return sd_readwrite(minor, rawflag, false);
-}
-
-int sd_write(uint8_t minor, uint8_t rawflag, uint8_t flag)
-{
-    flag;
-    return sd_readwrite(minor, rawflag, true);
-}
-
-static const char cardname[] = "     MMC\0\0SDv1\0?>???SDv2\0";
-
-/* Stop sdcc inlining a ton of crap each time */
-static unsigned long shift11(unsigned long p)
-{
-    return (p >> 11);
-}
-
-void sd_print_partition(unsigned char *p)
-{
-    long size;
-    if(!*p)
-        return;
-        
-    size = *(unsigned long *)(p + 4);
-    
-    kprintf("sd: partition type 0x%x, offset %uMB, length %uMB (%s)\n",
-             *p,
-             (unsigned int)shift11(*(unsigned long *)(p + 4)),
-             (unsigned int)shift11(size),
-             *p != UZI_PARTITION_TYPE ? "ignored" : 
-             (sd_blockdev_count == 0 ? "UZI" : "unused"));
-
-    /* We will use the first partition with the appropriate type */
-    if(*p == UZI_PARTITION_TYPE && sd_blockdev_count == 0){
-        sd_first_uzi_sector = *((unsigned long*)&p[4]);
-        /* 16 bit shift */
-        sd_blockdev_count = size >> UZI_BLOCKDEV_SIZE_LOG2_SECTORS;
-        /* Allow a smaller than 32MB final 'device' */
-        if (size & 0xFFFF)
-            sd_blockdev_count++;
-    }
-}
-
-int sd_init(void)
-{
-    int n;
-    unsigned long sector_count;
-    unsigned char *sector;
-    unsigned char *p; /* into sector */
-
-    sd_first_uzi_sector = 0;
-    sd_blockdev_count = 0;
-
-    kputs("sd: Probing ... ");
-
-    if (!(sd_card_type = sd_spi_init())) {
-        kputs("No card found\n");
-        return -1;
-    }
-    
-    /* read and compute card size */
-    sector_count = sd_get_size_sectors();
-    if(!sector_count){
-        kputs("Weird card\n");
-        return -1;
-    }
-    n = shift11(sector_count);
-
-    kprintf("Found %s card (%dMB, b%s addressed)\n", 
-                cardname + 5 * (sd_card_type & ~CT_BLOCK),
-                n,
-                (sd_card_type & CT_BLOCK) ? "lock" : "yte");
-
-    /* read partition table, locate the UZI partition */
-    sector = (unsigned char*)tmpbuf();
-    if(!sd_read_sector(sector, 0)){
-        kputs("sd: Failed to read partition table\n");
-    }else{
-        p = sector + 510;
-        if(*p != 0x55 || p[1] != 0xAA){ /* check for presence of MBR boot signature */
-            kputs("sd: Cannot find MBR partition table\n");
-        }else{
-            p = sector + 0x1BE + 4;
-            for(n = 4; n > 0; n--) {
-                sd_print_partition(p);
-                p+=16;
-            }
-            if(sd_blockdev_count == 0){
-                kprintf("sd: No UZI partition (type 0x%x) found\n", UZI_PARTITION_TYPE);
-            }
-        }
-    }
-
-    if(sd_blockdev_count > NUM_DEV_SD)
-        sd_blockdev_count = NUM_DEV_SD;
-
-    if(sd_blockdev_count)
-        kprintf("sd: %d block devices, max 32MB each\n", sd_blockdev_count);
-
-    brelse((bufptr)sector);
-
-    return 0; /* success */
-}
-
-int sd_spi_init(void)
-{
-    unsigned char n, cmd, card_type, ocr[4];
-    timer_t timer;
-
-    sd_spi_mode0();
-    sd_spi_raise_cs();
-
-    sd_spi_clock(255); /* 250kHz */
-    for (n = 20; n; n--)
-        sd_spi_receive_byte(); /* 160 dummy clocks */
-
-    card_type = 0;
-    /* Enter Idle state */
-    if (sd_send_command(CMD0, 0) == 1) {
-        /* initialisation timeout 1 second */
-        timer = set_timer_sec(1);
-        if (sd_send_command(CMD8, (uint32_t)0x1AA) == 1) {    /* SDHC */
-            /* Get trailing return value of R7 resp */
-            for (n = 0; n < 4; n++) ocr[n] = sd_spi_receive_byte();
-            /* The card can work at vdd range of 2.7-3.6V */
-            if (ocr[2] == 0x01 && ocr[3] == 0xAA) {
-                /* Wait for leaving idle state (ACMD41 with HCS bit) */
-                while(!timer_expired(timer) && sd_send_command(ACMD41, (uint32_t)1 << 30));
-                /* Check CCS bit in the OCR */
-                if (!timer_expired(timer) && sd_send_command(CMD58, 0) == 0) {
-                    for (n = 0; n < 4; n++) ocr[n] = sd_spi_receive_byte();
-                    card_type = (ocr[0] & 0x40) ? CT_SD2 | CT_BLOCK : CT_SD2;   /* SDv2 */
-                }
-            }
-        } else { /* SDSC or MMC */
-            if (sd_send_command(ACMD41, 0) <= 1)    {
-                /* SDv1 */
-                card_type = CT_SD1;
-                cmd = ACMD41;
-            } else {
-                /* MMCv3 */
-                card_type = CT_MMC;
-                cmd = CMD1;
-            }
-            /* Wait for leaving idle state */
-            while(!timer_expired(timer) && sd_send_command(cmd, 0));
-            /* Set R/W block length to 512 */
-            if(timer_expired(timer) || sd_send_command(CMD16, (uint32_t)512) != 0)
-                card_type = 0;
-        }
-    }
-    sd_spi_release();
-
-    if (card_type) {
-        if(card_type == CT_MMC)
-            sd_spi_clock(3); /* 16MHz (can do up to 20MHz with MMC) */
-        else
-            sd_spi_clock(2); /* 21MHz (can do up to 25MHz with SD) */
-        return card_type;
-    }
-
-    return 0; /* failed */
-}
-
-void sd_spi_release(void)
-{
-    sd_spi_raise_cs();
-    sd_spi_receive_byte();
-}
-
-int sd_spi_wait_ready(void)
-{
-    unsigned char res;
-    timer_t timer;
-
-    timer = set_timer_ms(100); /* 100ms */
-    sd_spi_receive_byte();
-    do{
-        res = sd_spi_receive_byte();
-    }while ((res != 0xFF) && !timer_expired(timer));
-
-    return res;
-}
-
-int sd_spi_transmit_block(void *ptr, int length)
-{
-    unsigned char reply;
-
-    if(sd_spi_wait_ready() != 0xFF)
-        return 0; /* failed */
-
-    sd_spi_transmit_byte(0xFE);
-    sd_spi_transmit_from_memory(ptr, length);
-    sd_spi_transmit_byte(0xFF); /* dummy CRC */
-    sd_spi_transmit_byte(0xFF);
-    reply = sd_spi_receive_byte();
-    if((reply & 0x1f) != 0x05)
-        return 0; /* failed */
-    return 1; /* hooray! */
-}
-
-int sd_spi_receive_block(void *ptr, int length)
-{
-    unsigned int timer;
-    unsigned char b;
-
-    timer = set_timer_ms(200); /* 200ms */
-
-    do{
-        b = sd_spi_receive_byte();
-    }while(b == 0xFF && !timer_expired(timer));
-    if(b != 0xFE)
-        return 0; /* failed */
-
-    return sd_spi_receive_to_memory(ptr, length); /* returns nonzero */
-}
-
-int sd_send_command(unsigned char cmd, uint32_t arg)
-{
-    unsigned char n, res;
-
-    if (cmd & 0x80) {   /* ACMD<n> is the command sequense of CMD55-CMD<n> */
-        cmd &= 0x7F;
-        res = sd_send_command(CMD55, 0);
-        if (res > 1) 
-            return res;
-    }
-
-    /* Select the card and wait for ready */
-    sd_spi_raise_cs();
-    sd_spi_lower_cs();
-    if (sd_spi_wait_ready() != 0xFF) 
-        return 0xFF;
-
-    /* Send command packet */
-    sd_spi_transmit_byte(cmd);                               /* Start + Command index */
-    sd_spi_transmit_byte((unsigned char)(arg >> 24));        /* Argument[31..24] */
-    sd_spi_transmit_byte((unsigned char)(arg >> 16));        /* Argument[23..16] */
-    sd_spi_transmit_byte((unsigned char)(arg >> 8));         /* Argument[15..8] */
-    sd_spi_transmit_byte((unsigned char)arg);                /* Argument[7..0] */
-    /* there's only a few commands (in native mode) that need correct CRCs */
-    n = 0x01;                                                /* Dummy CRC + Stop */
-    if (cmd == CMD0) n = 0x95;                               /* Valid CRC for CMD0(0) */
-    if (cmd == CMD8) n = 0x87;                               /* Valid CRC for CMD8(0x1AA) */
-    sd_spi_transmit_byte(n);
-
-    /* Receive command response */
-    if (cmd == CMD12) 
-        sd_spi_receive_byte();          /* Skip a stuff byte when stop reading */
-    n = 10;                             /* Wait for a valid response in timeout of 10 attempts */
-    do{
-        res = sd_spi_receive_byte();
-    }while ((res & 0x80) && --n);
-
-    return res;         /* Return with the response value */
-}
-
-unsigned long sd_get_size_sectors(void)
-{
-    unsigned char csd[16], n;
-    unsigned long sectors = 0;
-
-    if(sd_send_command(CMD9, 0) == 0 && sd_spi_receive_block(csd, 16)){
-        if ((csd[0] >> 6) == 1) {      /* SDC ver 2.00 */
-            sectors = (csd[9] + ((unsigned int)csd[8] << 8) + 1) << 10;
-        } else {                                       /* SDC ver 1.XX or MMC*/
-            n = (csd[5] & 15) + ((csd[10] & 128) >> 7) + ((csd[9] & 3) << 1) + 2;
-            sectors = (csd[8] >> 6) + ((unsigned int)csd[7] << 2) + ((unsigned int)(csd[6] & 3) << 10) + 1;
-            sectors = sectors << (n - 9);
-        }
-    }
-    sd_spi_release();
-    return sectors;
-}
-
-int sd_read_sector(void *ptr, unsigned long lba)
-{
-    int r = 0;
-
-    if(sd_card_type == CT_NONE)
-        return r;
-
-    if(!(sd_card_type & CT_BLOCK))
-        lba = lba << 9; /* multiply by 512 to get byte address */
-
-    if(sd_send_command(CMD17, lba) == 0 && sd_spi_receive_block(ptr, 512)){
-        r = -1;
-    }
-
-    sd_spi_release();
-
-    return r;
-}
-
-int sd_write_sector(void *ptr, unsigned long lba)
-{
-    int r = 0;
-
-    if(sd_card_type == CT_NONE)
-        return r;
-
-    if(!(sd_card_type & CT_BLOCK))
-        lba = lba << 9; /* multiply by 512 to get byte address */
-
-    if(sd_send_command(CMD24, lba) == 0 && sd_spi_transmit_block(ptr, 512)){
-        r = -1;
-    }
-
-    sd_spi_release();
-
-    return r;
-}
diff --git a/Kernel/platform-socz80/devsd.h b/Kernel/platform-socz80/devsd.h
deleted file mode 100644 (file)
index bcf9038..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-#ifndef __DEVSD_DOT_H__
-#define __DEVSD_DOT_H__
-
-#define UZI_PARTITION_TYPE 0x5A    /* ASCII "Z", Wikipedia suggests this partition type is not widely used */
-#define UZI_BLOCKDEV_SIZE_LOG2_SECTORS 16 /* Each device is 2^16 sectors ie 2^16 * 2^9 = 2^25 = 32MB */
-
-/* public interface */
-int sd_read(uint8_t minor, uint8_t rawflag, uint8_t flag);
-int sd_write(uint8_t minor, uint8_t rawflag, uint8_t flag);
-int sd_init(void);
-int sd_open(uint8_t minor, uint16_t flag);
-
-/* private interface */
-int sd_spi_init(void);
-int sd_read_sector(void *ptr, unsigned long lba);
-int sd_write_sector(void *ptr, unsigned long lba);
-unsigned long sd_get_size_sectors(void);
-
-/* internal functions */
-void sd_spi_clock(int divisor); 
-/* 
-   sd_clock sets SPI bus to 64.0 / (1+divisor) MHz 
-     0=64MHz, 1=32MHz, 2=21.33MHz, 3=16MHz, 4=12.8MHz, 
-     5=10.66MHz, 6=9.14MHz, 7=8MHz, 15=4MHz, etc 
-     255 = 0.25MHz, about right for MMC/SPI initialisation
-*/
-
-void sd_spi_mode0(void);
-void sd_spi_raise_cs(void);
-void sd_spi_lower_cs(void);
-void sd_spi_release(void);
-int sd_spi_wait_ready(void);
-void sd_spi_transmit_byte(unsigned char byte);
-unsigned char sd_spi_receive_byte(void);
-int sd_spi_receive_block(void *ptr, int length); /* waits for card ready then calls sd_spi_receive_to_memory */
-int sd_spi_transmit_block(void *ptr, int length); /* waits for card ready then calls sd_spi_receive_to_memory */
-int sd_spi_receive_to_memory(void *ptr, int length);
-int sd_spi_transmit_from_memory(void *ptr, int length);
-int sd_send_command(unsigned char cmd, uint32_t arg);
-
-/* Definitions for MMC/SDC command */
-#define CMD0    (0x40+0)    /* GO_IDLE_STATE */
-#define CMD1    (0x40+1)    /* SEND_OP_COND (MMC) */
-#define ACMD41  (0xC0+41)   /* SEND_OP_COND (SDC) */
-#define CMD8    (0x40+8)    /* SEND_IF_COND */
-#define CMD9    (0x40+9)    /* SEND_CSD */
-#define CMD10   (0x40+10)   /* SEND_CID */
-#define CMD12   (0x40+12)   /* STOP_TRANSMISSION */
-#define ACMD13  (0xC0+13)   /* SD_STATUS (SDC) */
-#define CMD16   (0x40+16)   /* SET_BLOCKLEN */
-#define CMD17   (0x40+17)   /* READ_SINGLE_BLOCK */
-#define CMD18   (0x40+18)   /* READ_MULTIPLE_BLOCK */
-#define CMD23   (0x40+23)   /* SET_BLOCK_COUNT (MMC) */
-#define ACMD23  (0xC0+23)   /* SET_WR_BLK_ERASE_COUNT (SDC) */
-#define CMD24   (0x40+24)   /* WRITE_BLOCK */
-#define CMD25   (0x40+25)   /* WRITE_MULTIPLE_BLOCK */
-#define CMD55   (0x40+55)   /* APP_CMD */
-#define CMD58   (0x40+58)   /* READ_OCR */
-
-#define CT_NONE 0x00
-#define CT_MMC 0x01
-#define CT_SD1 0x02
-#define CT_SD2 0x04
-#define CT_SDC (CT_SD1|CT_SD2)
-#define CT_BLOCK 0x08
-
-#endif /* __DEVSD_DOT_H__ */
diff --git a/Kernel/platform-socz80/devsd_hw.s b/Kernel/platform-socz80/devsd_hw.s
deleted file mode 100644 (file)
index c21a9be..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-; 2013-12-19 William R Sowerbutts
-
-            .module devsd_hw
-
-            ; exported symbols
-            .globl _sd_spi_clock
-            .globl _sd_spi_raise_cs
-            .globl _sd_spi_lower_cs
-            .globl _sd_spi_receive_byte
-            .globl _sd_spi_transmit_byte
-            .globl _sd_spi_receive_to_memory
-            .globl _sd_spi_transmit_from_memory
-           .globl _sd_spi_mode0
-
-            .include "socz80.def"
-
-            .area _CODE
-
-_sd_spi_clock:
-            pop de
-            pop hl
-            push hl
-            push de
-            ld a, l
-            out (SD_SPI_DIVISOR), a
-            ret
-
-_sd_spi_raise_cs:
-            ld a, #0xFF
-            out (SD_SPI_CHIPSELECT), a
-            ret
-
-_sd_spi_lower_cs:
-            ld a, #0xFE
-            out (SD_SPI_CHIPSELECT), a
-            ret
-
-_sd_spi_mode0:
-          xor a
-           out (SD_SPI_MODE), a
-           ret
-
-_sd_spi_receive_byte:
-            ; read a byte
-            ld a, #0xFF
-            out (SD_SPI_TX), a
-            in a, (SD_SPI_RX)
-            ld h, #0
-            ld l, a
-            ret
-
-_sd_spi_transmit_from_memory:
-            pop de  ; return address
-            pop hl  ; memory pointer
-            pop bc  ; byte count
-            push bc ; now put the stack back ...
-            push hl
-            push de
-tnextbyte:
-            ld a, (hl)
-            out (SD_SPI_TX), a
-            inc hl
-            dec bc
-            ld a, b
-            or c
-            jr nz, tnextbyte
-            ; return success in HL
-            ld hl, #1
-            ret
-
-
-_sd_spi_receive_to_memory:
-            pop de  ; return address
-            pop hl  ; memory pointer
-            pop bc  ; byte count
-            push bc ; now put the stack back ...
-            push hl
-            push de
-rnextbyte:
-            ld a, #0xFF
-            out (SD_SPI_TX), a
-            in a, (SD_SPI_RX)
-            ld (hl), a
-            inc hl
-            dec bc
-            ld a, b
-            or c
-            jr nz, rnextbyte
-            ; there's also a 16-bit CRC that we discard
-            call _sd_spi_receive_byte
-            call _sd_spi_receive_byte
-            ; return success in HL
-            ld hl, #1
-            ret
-
-_sd_spi_transmit_byte:
-            pop de
-            pop hl
-            push hl
-            push de
-            ld a, l
-            out (SD_SPI_TX), a
-            ret
diff --git a/Kernel/platform-socz80/devsdspi.c b/Kernel/platform-socz80/devsdspi.c
new file mode 100644 (file)
index 0000000..1433b58
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+ *     SPI glue for the SocZ80. Based on Will Sowerbutts's UZI180 for SocZ80
+ *     and his implementation for the N8VEM Mark 4
+ */
+
+#include <kernel.h>
+#include <kdata.h>
+#include <printf.h>
+#include <timer.h>
+#include <stdbool.h>
+#include "config.h"
+#include <blkdev.h>
+
+/* We should revisit this if we are willing to rely on the later VHDL
+   being used. At that point we've got mode setting but more importantly
+   the tx port is r/w as rx/tx so the port can sit in (c) */
+
+__sfr __at 0x30 sd_spi_chipselect;
+__sfr __at 0x31 sd_spi_status;
+__sfr __at 0x32 sd_spi_tx;
+__sfr __at 0x33 sd_spi_rx;
+__sfr __at 0x34 sd_spi_divisor;
+__sfr __at 0x35 sd_spi_gpio;           /* only on later VHDL */
+__sfr __at 0x36 sd_spi_mode;           /* only on later VHDL */
+
+#define SD_SPI_TX 0x32
+#define SD_SPI_RX 0x33
+
+void sd_spi_mode0(uint8_t drive)
+{
+  used(drive);
+  sd_spi_mode = 0;
+}
+
+void sd_spi_clock(uint8_t drive, bool go_fast)
+{
+  used(drive);
+//  sd_spi_mode0(drive);
+  /* Currently the sd driver just uses 'slow' and 'fast'. That's ok for
+     sd but mmc really needs to be 16MHz */
+  if (go_fast)
+    sd_spi_divisor = 3;        //2
+  else
+    sd_spi_divisor = 255;
+}
+
+void sd_spi_raise_cs(uint8_t drive)
+{
+  used(drive);
+  sd_spi_chipselect = 0xFF;
+}
+
+void sd_spi_lower_cs(uint8_t drive)
+{
+  used(drive);
+  sd_spi_chipselect = 0xFE;
+}
+
+void sd_spi_transmit_byte(uint8_t drive, unsigned char byte)
+{
+  used(drive);
+  sd_spi_tx = byte;
+}
+
+uint8_t sd_spi_receive_byte(uint8_t drive)
+{
+  uint8_t r;
+  used(drive);
+  sd_spi_tx = 0xFF;
+  r = sd_spi_rx;
+  return r;
+}
+
+COMMON_MEMORY
+
+bool sd_spi_receive_sector(uint8_t drive) __naked
+{
+  used(drive);
+  __asm
+    ld a, (_blk_op+BLKPARAM_IS_USER_OFFSET);
+    ld hl, (_blk_op+BLKPARAM_ADDR_OFFSET);
+    or a       ; Set the Z flag up and save it, dont do it twice
+    push af
+    call nz,map_process_always
+    call rx256
+    call rx256
+    pop af
+    call nz,map_kernel
+    ret
+rx256:
+    ld a,#0xFF
+    ld bc, #SD_SPI_RX   ; b = 0, c = port
+rx256_1:
+    out (SD_SPI_TX),a   ; we could use (c),a on newer VHDL
+    ini
+    jr nz, rx256_1
+    ret
+  __endasm;
+}
+
+bool sd_spi_transmit_sector(uint8_t drive) __naked
+{
+  used(drive);
+  __asm
+    ld a, (_blk_op+BLKPARAM_IS_USER_OFFSET)
+    ld hl, (_blk_op+BLKPARAM_ADDR_OFFSET)
+    or a       ; Set the Z flag up and save it, dont do it twice
+    push af
+    call nz,map_process_always
+    call tx256
+    call tx256
+    pop af
+    call nz,map_kernel
+    ret
+tx256:
+    ld a,#0xFF
+    ld bc, #SD_SPI_RX * 256
+tx256_1:
+    out (SD_SPI_TX),a   ; we could use (c),a on newer VHDL
+    outi
+    jr nz, tx256_1
+    ret
+  __endasm;
+}
index 8b145ad..368b9b8 100644 (file)
@@ -18,8 +18,6 @@ lowlevel-z80.rel
 timer.rel
 kdata.rel
 platform-socz80/devrd.rel
-platform-socz80/devsd.rel
-platform-socz80/devsd_hw.rel
 platform-socz80/devrd_hw.rel
 platform-socz80/devices.rel
 devio.rel
@@ -36,4 +34,8 @@ mm.rel
 devsys.rel
 platform-socz80/devlpr.rel
 platform-socz80/devtty.rel
+platform-socz80/devsd.rel
+platform-socz80/blkdev.rel
+platform-socz80/mbr.rel
+platform-socz80/devsdspi.rel
 -e
index c4e2e99..b2408d9 100644 (file)
@@ -15,28 +15,25 @@ void platform_idle(void)
 
 __sfr __at 0x00 uart0_status;
 __sfr __at 0x01 uart0_data;
-__sfr __at 0x10 timer_status;
-__sfr __at 0x11 timer_command;
 __sfr __at 0x28 uart1_status;
 __sfr __at 0x29 uart1_data;
 
+extern uint16_t irqwork;
+
 void platform_interrupt(void)
 {
     uint8_t st0 = uart0_status;
     uint8_t st1 = uart1_status;
-    uint8_t ts = timer_status;
+    uint8_t ts = irqwork;
     uint8_t d;
 
-    if (ts & 0x80)
-        timer_command = 0;     /* Ack the timer */
-    if (st0 & 0xC0) {
-        kprintf("st0 %x\n", st0);    
-        uart0_status = st0 & 0xFC;
-        if (st0 & 0x80) {      /* RX data */
+    irqwork = 0;
+    if (ts & 0xC0) {
+        if (ts & 0x80) {       /* RX data */
             d = uart0_data;
             tty_inproc(1, d);
         }
-        if (st0 & 0x40)                /* TX idle */
+        if (ts & 0x40)         /* TX idle */
             tty_outproc(1);
     }
     if (st1 & 0xC0) {
@@ -48,7 +45,7 @@ void platform_interrupt(void)
         if (st1 & 0x40)                /* TX idle */
             tty_outproc(2);
     }
-    if (ts & 0x80)
+    if (ts & 1)
         timer_interrupt();
 }
 
index 6d094fe..34dae43 100644 (file)
@@ -20,6 +20,7 @@
            .globl map_restore
            .globl platform_interrupt_all
            .globl _kernel_flag
+           .globl _irqwork
 
             ; exported debugging tools
             .globl _trap_monitor
@@ -97,8 +98,32 @@ _trap_monitor:
             ; it's never a dull day with ROM around!
 
 platform_interrupt_all:
+           in a,(TIMER_STATUS)
+           bit 7, a
+           jr z, not_timer
+           ld a,(_irqwork)
+           set 0, a
+           ld (_irqwork),a
+           xor a
+           out (TIMER_STATUS),a
+not_timer:
+           in a,(UART0_STATUS)
+           ld b, a
+           and #0xC0
+           ret z
+           ld a, #0xfc
+           and b
+           out (UART0_STATUS),a
+           and #0xC0
+           ld hl,#_irqwork
+           or (hl)
+           ld (hl),a
            ret
 
+; FIXME: this in common is not ideal but not clear where it should go
+; to allow queued stuff to be handled reliably
+_irqwork:   .dw 0
+
 ; -----------------------------------------------------------------------------
 ; KERNEL MEMORY BANK (below 0xF000, only accessible when the kernel is mapped)
 ; -----------------------------------------------------------------------------
@@ -275,6 +300,33 @@ readlastbytes:
             inir
             ret
 
+mmu_state_dump:
+            push bc
+            push hl
+            ld c, #0
+            ld b, #16
+dumpnextframe:
+            ld hl, #mmumsg
+            call outstring
+            ld a, c
+            out (MMU_SELECT), a
+            call outnibble
+            ld a, #':'
+            call outchar
+            ld a, #' '
+            call outchar
+            in a, (MMU_FRAMEHI)
+            ld h, a
+            in a, (MMU_FRAMELO)
+            ld l, a
+            call outhl
+            call outnewline
+            inc c
+            djnz dumpnextframe
+            pop hl
+            pop bc
+            ret
+
 
 ;------------------------------------------------------------------------------
 ; COMMON MEMORY PROCEDURES FOLLOW
@@ -328,33 +380,6 @@ _program_vectors:
 mmumsg:     .ascii "MMU page "
             .db 0
 
-mmu_state_dump:
-            push bc
-            push hl
-            ld c, #0
-            ld b, #16
-dumpnextframe:
-            ld hl, #mmumsg
-            call outstring
-            ld a, c
-            out (MMU_SELECT), a
-            call outnibble
-            ld a, #':'
-            call outchar
-            ld a, #' '
-            call outchar
-            in a, (MMU_FRAMEHI)
-            ld h, a
-            in a, (MMU_FRAMELO)
-            ld l, a
-            call outhl
-            call outnewline
-            inc c
-            djnz dumpnextframe
-            pop hl
-            pop bc
-            ret
-
 
 ;
 ; Mapping routines. Not yet all fixed up for the new style memory management