summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-11-12 07:57:53 (GMT)
committerH. Peter Anvin <hpa@zytor.com>2010-11-12 07:57:53 (GMT)
commitfda64bdf4b0e4300b61b0922ed2f2bd3d625da55 (patch)
treeee70d04bff15a14bcbbb4775f930b3cf14c5f6b2
parent37f307f3320fdaa3981ac27867708b7fb01ef9e3 (diff)
downloadabc8000-old-fda64bdf4b0e4300b61b0922ed2f2bd3d625da55.zip
abc8000-old-fda64bdf4b0e4300b61b0922ed2f2bd3d625da55.tar.gz
abc8000-old-fda64bdf4b0e4300b61b0922ed2f2bd3d625da55.tar.bz2
abc8000-old-fda64bdf4b0e4300b61b0922ed2f2bd3d625da55.tar.xz
sysrom: link in the FAT code and try to boot from SD card
-rw-r--r--data/sysrom/Makefile2
-rw-r--r--data/sysrom/sdcard.c133
-rw-r--r--data/sysrom/sysrom.h2
-rw-r--r--data/sysrom/sysstart.c2
4 files changed, 123 insertions, 16 deletions
diff --git a/data/sysrom/Makefile b/data/sysrom/Makefile
index 14062a4..da179c5 100644
--- a/data/sysrom/Makefile
+++ b/data/sysrom/Makefile
@@ -9,7 +9,7 @@ OBJDUMP = m68k-none-elf-objdump
RANLIB = m68k-none-elf-ranlib
PERL = perl
-INCLUDE = -I./include
+INCLUDE = -I./include -I./fat/src
CCWARN = -W -Wall -Wwrite-strings -Wmissing-prototypes
CFLAGS = -m68000 -O2 -fomit-frame-pointer -ffreestanding \
diff --git a/data/sysrom/sdcard.c b/data/sysrom/sdcard.c
index 443ebc1..142dd9d 100644
--- a/data/sysrom/sdcard.c
+++ b/data/sysrom/sdcard.c
@@ -27,6 +27,8 @@
#include <stdio.h>
#include <ioreg.h>
#include "sysrom.h"
+#include "ff.h"
+#include "diskio.h"
#define SECTOR_SIZE 512
@@ -76,7 +78,7 @@ struct sdcard_cid {
};
struct sdcard_info {
- bool ready;
+ DSTATUS status;
int8_t card_type;
unsigned long lbasize;
uint32_t if_cond;
@@ -85,7 +87,9 @@ struct sdcard_info {
struct sdcard_cid cid;
};
-static struct sdcard_info sdc;
+struct sdcard_info sdc = {
+ .status = STA_NOINIT
+};
static int sdcard_send_cmd(uint8_t opcode, uint32_t argument)
{
@@ -218,6 +222,7 @@ static int sdcard_read_block(void *buf, int len, int timeout, const void *xcmd)
/*
* Read a number of sectors; returns the number of sectors read.
+ * The input buffer may be unaligned.
*/
int sdcard_read_sectors(void *buf, uint32_t lba, int count)
{
@@ -250,6 +255,16 @@ int sdcard_read_sectors(void *buf, uint32_t lba, int count)
return okcount;
}
+DRESULT disk_read(BYTE drive, BYTE *buffer, DWORD sectornumber, BYTE sectorcount)
+{
+ int rv;
+
+ (void)drive;
+
+ rv = sdcard_read_sectors(buffer, sectornumber, sectorcount);
+ return (rv == sectorcount) ? RES_OK : RES_ERROR;
+}
+
/*
* Read CSD/CID
*/
@@ -359,6 +374,48 @@ int sdcard_write_sectors(const void *buf, uint32_t lba, int count)
return okcount;
}
+DRESULT disk_write(BYTE drive, const BYTE *buffer, DWORD sectornumber, BYTE sectorcount)
+{
+ int rv;
+
+ if (drive != 0)
+ return STA_NOINIT;
+
+ rv = sdcard_write_sectors(buffer, sectornumber, sectorcount);
+ return (rv == sectorcount) ? RES_OK : RES_ERROR;
+}
+
+DRESULT disk_ioctl(BYTE drive, BYTE command, void *buffer)
+{
+ if (drive != 0)
+ return STA_NOINIT;
+
+ switch (command) {
+ case CTRL_SYNC:
+ return RES_OK;
+ case GET_SECTOR_SIZE:
+ *(WORD *)buffer = 512;
+ return RES_OK;
+ case GET_SECTOR_COUNT:
+ *(DWORD *)buffer = sdc.lbasize;
+ return RES_OK;
+ case GET_BLOCK_SIZE:
+ *(DWORD *)buffer = 1; /* XXX */
+ return RES_OK;
+ case CTRL_ERASE_SECTOR:
+ return RES_OK; /* XXX */
+ default:
+ return RES_PARERR;
+ }
+}
+
+DWORD get_fattime(void)
+{
+ /* No RTC, return 2010-11-11 11:11:11 */
+ return ((2010-1980) << 25) + (11 << 21) + (11 << 16) +
+ (11 << 11) + (11 << 5) + (11 >> 1);
+}
+
static unsigned long sdcard_compute_size(struct sdcard_info *sdi)
{
unsigned int c_size;
@@ -405,19 +462,22 @@ static const char *sdcard_type_name(uint8_t type)
return names[type];
}
-int sdcard_init(void)
+DSTATUS disk_initialize(BYTE drive)
{
uint16_t status;
uint32_t try_sdhc;
int i, rv;
+ if (drive != 0)
+ return STA_NOINIT;
+
memset(&sdc, 0, sizeof sdc);
status = readw(IO_SDC_RD_STATUS(0));
if (!(status & 0x04)) {
printf("No memory card installed\n");
- return -1;
+ return sdc.status = STA_NOINIT|STA_NODISK;
}
/* Generate 256 clock cycles in slow mode, with CS# high */
@@ -430,7 +490,7 @@ int sdcard_init(void)
rv = sdcard_send_cmd(CMD_GO_IDLE_STATE, 0);
if (rv != 0x01) {
printf("sdcard: CMD0 error %02x\n", rv);
- return -1;
+ return sdc.status = STA_NOINIT;
}
/* Switch to fast mode */
@@ -449,7 +509,7 @@ int sdcard_init(void)
/* CMD8 supported */
if (rv & ~0x03) {
printf("sdcard; CMD8 error %02x\n", rv);
- return -1;
+ return sdc.status = STA_NOINIT;
}
/* Shift in the second data byte */
@@ -462,7 +522,7 @@ int sdcard_init(void)
if ((sdc.if_cond & 0x1ff) != 0x1aa) {
printf("sdcard: CMD8 reports unusable card (0x%x)\n",
sdc.if_cond);
- return -1;
+ return sdc.status = STA_NOINIT;
}
try_sdhc = 1 << 30;
} else {
@@ -477,7 +537,7 @@ int sdcard_init(void)
if (rv & ~0x01) {
printf("sdcard: ACMD41 error %02x\n", rv);
- return -1;
+ return sdc.status = STA_NOINIT;
}
} while (rv);
@@ -486,7 +546,7 @@ int sdcard_init(void)
rv = sdcard_send_cmd(CMD_READ_OCR, try_sdhc);
if (rv) {
printf("sdcard: CMD58 error %02x\n", rv);
- return -1;
+ return sdc.status = STA_NOINIT;
}
/* Shift in the second data byte */
writeb(0xff, IO_SDC_WR_B(SDC_START|SDC_BYTE));
@@ -497,7 +557,7 @@ int sdcard_init(void)
rv = sdcard_send_cmd(CMD_SEND_OP_COND, 0);
if (rv & ~0x01) {
printf("sdcard: CMD1 error %02x\n", rv);
- return -1;
+ return sdc.status = STA_NOINIT;
}
} while (rv);
}
@@ -509,7 +569,7 @@ int sdcard_init(void)
rv = sdcard_send_cmd(CMD_SET_BLOCKLEN, 512);
if (rv) {
printf("sdcard: CMD16 error %02x\n", rv);
- return -1;
+ return sdc.status = STA_NOINIT;
}
/*
@@ -533,6 +593,53 @@ int sdcard_init(void)
printf("sdcard: %s card found, capacity %u sectors\n",
sdcard_type_name(sdc.card_type), sdc.lbasize);
- sdc.ready = true;
- return 0;
+ status = readw(IO_SDC_RD_STATUS(0));
+
+ sdc.status = 0;
+ if (!(status & 0x04))
+ sdc.status |= STA_NOINIT;
+ if (!(status & 0x08))
+ sdc.status |= STA_PROTECT;
+
+ return sdc.status;
+}
+
+DSTATUS disk_status(BYTE drive)
+{
+ if (drive != 0)
+ return STA_NOINIT;
+
+ return sdc.status;
+}
+
+/*
+ * Try to load abc8000.sys, and run it if it exists
+ */
+static FATFS sd_fs;
+
+void disk_boot(void)
+{
+ static const char boot_filename[] = "abc8000.sys";
+ FRESULT fr;
+ FIL file;
+ UINT bytesread;
+
+ printf("Mounting SD card...\n");
+ f_mount(0, &sd_fs);
+
+ printf("Opening boot file...\n");
+ fr = f_open(&file, boot_filename, FA_READ|FA_OPEN_EXISTING);
+ if (fr != FR_OK)
+ return;
+
+ printf("Reading boot file...\n");
+ fr = f_read(&file, (void *)0x10000, file.fsize, &bytesread);
+ f_close(&file);
+
+ if (fr != FR_OK)
+ return;
+
+ printf("Jumping to boot file...\n");
+ ((void (*)(void))0x10000)();
}
+
diff --git a/data/sysrom/sysrom.h b/data/sysrom/sysrom.h
index 70c2a5f..1e0a1c4 100644
--- a/data/sysrom/sysrom.h
+++ b/data/sysrom/sysrom.h
@@ -15,7 +15,7 @@ void monitor(void);
__noreturn die(void);
void __spurious_irq(void);
-int sdcard_init(void);
+void disk_boot(void);
int sdcard_read_sectors(void *buf, uint32_t lba, int count);
int sdcard_write_sectors(const void *buf, uint32_t lba, int count);
diff --git a/data/sysrom/sysstart.c b/data/sysrom/sysstart.c
index 2c5af7c..0443fbe 100644
--- a/data/sysrom/sysstart.c
+++ b/data/sysrom/sysstart.c
@@ -223,7 +223,7 @@ void sys_start(void)
picture();
- sdcard_init();
+ disk_boot();
monitor();
die();