From 682106059371744f556808cd4fc2e19afc8c81ef Mon Sep 17 00:00:00 2001 From: Alan Cox Date: Fri, 30 Jan 2015 23:39:04 +0000 Subject: [PATCH] socz80: move to the new issue sd driver With this in place we mount the root file system and blow up trying to start init. --- Kernel/platform-socz80/Makefile | 20 +- Kernel/platform-socz80/config.h | 3 + Kernel/platform-socz80/devices.c | 11 +- Kernel/platform-socz80/devsd.c | 395 ------------------------------ Kernel/platform-socz80/devsd.h | 67 ----- Kernel/platform-socz80/devsd_hw.s | 103 -------- Kernel/platform-socz80/devsdspi.c | 124 ++++++++++ Kernel/platform-socz80/fuzix.lnk | 6 +- Kernel/platform-socz80/main.c | 19 +- Kernel/platform-socz80/socz80.s | 79 ++++-- 10 files changed, 211 insertions(+), 616 deletions(-) delete mode 100644 Kernel/platform-socz80/devsd.c delete mode 100644 Kernel/platform-socz80/devsd.h delete mode 100644 Kernel/platform-socz80/devsd_hw.s create mode 100644 Kernel/platform-socz80/devsdspi.c diff --git a/Kernel/platform-socz80/Makefile b/Kernel/platform-socz80/Makefile index 448866a4..fca48645 100644 --- a/Kernel/platform-socz80/Makefile +++ b/Kernel/platform-socz80/Makefile @@ -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 *~ diff --git a/Kernel/platform-socz80/config.h b/Kernel/platform-socz80/config.h index 79a386a7..c80e571a 100644 --- a/Kernel/platform-socz80/config.h +++ b/Kernel/platform-socz80/config.h @@ -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 diff --git a/Kernel/platform-socz80/devices.c b/Kernel/platform-socz80/devices.c index 76d715e1..4eb4c845 100644 --- a/Kernel/platform-socz80/devices.c +++ b/Kernel/platform-socz80/devices.c @@ -2,26 +2,27 @@ #include #include #include -#include #include #include #include #include +#include +#include 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 index 7bd9e620..00000000 --- a/Kernel/platform-socz80/devsd.c +++ /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 -#include -#include -#include -#include -#include - -/* 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 is the command sequense of CMD55-CMD */ - 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 index bcf90384..00000000 --- a/Kernel/platform-socz80/devsd.h +++ /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 index c21a9bec..00000000 --- a/Kernel/platform-socz80/devsd_hw.s +++ /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 index 00000000..1433b58b --- /dev/null +++ b/Kernel/platform-socz80/devsdspi.c @@ -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 +#include +#include +#include +#include +#include "config.h" +#include + +/* 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; +} diff --git a/Kernel/platform-socz80/fuzix.lnk b/Kernel/platform-socz80/fuzix.lnk index 8b145ad3..368b9b81 100644 --- a/Kernel/platform-socz80/fuzix.lnk +++ b/Kernel/platform-socz80/fuzix.lnk @@ -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 diff --git a/Kernel/platform-socz80/main.c b/Kernel/platform-socz80/main.c index c4e2e99a..b2408d98 100644 --- a/Kernel/platform-socz80/main.c +++ b/Kernel/platform-socz80/main.c @@ -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(); } diff --git a/Kernel/platform-socz80/socz80.s b/Kernel/platform-socz80/socz80.s index 6d094fe4..34dae43c 100644 --- a/Kernel/platform-socz80/socz80.s +++ b/Kernel/platform-socz80/socz80.s @@ -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 -- 2.34.1