summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2010-11-13 06:33:01 (GMT)
committerH. Peter Anvin <hpa@zytor.com>2014-02-11 02:07:50 (GMT)
commitfa0da67856a709eda3de3921b2a9733012990bec (patch)
treed8a21af4cdb132d7412c91580dd498c1447e658a
parent7d330bba74eb29d65d82cd357f457b7d4ec6482b (diff)
downloadabc8000-fa0da67856a709eda3de3921b2a9733012990bec.zip
abc8000-fa0da67856a709eda3de3921b2a9733012990bec.tar.gz
abc8000-fa0da67856a709eda3de3921b2a9733012990bec.tar.bz2
abc8000-fa0da67856a709eda3de3921b2a9733012990bec.tar.xz
sysrom: build and boot abc8000.sys
We can now load and boot abc8000.sys -- but it doesn't execute correctly (is execution from SDRAM broken?) Lots of debugging messages which need to be cleaned up, and the code refactored between disk and ROM.
-rw-r--r--data/sysrom/.gitignore1
-rw-r--r--data/sysrom/Makefile28
-rw-r--r--data/sysrom/abc/init.asm50
-rw-r--r--data/sysrom/abc/main.c8
-rw-r--r--data/sysrom/abc8000.ld54
-rw-r--r--data/sysrom/lib/conio.c (renamed from data/sysrom/conio.c)0
-rw-r--r--data/sysrom/sdcard.c106
7 files changed, 207 insertions, 40 deletions
diff --git a/data/sysrom/.gitignore b/data/sysrom/.gitignore
index 0ba0132..9492ef5 100644
--- a/data/sysrom/.gitignore
+++ b/data/sysrom/.gitignore
@@ -1,6 +1,7 @@
*.bin
*.elf
*.map
+*.sys
*.i
*.o
*.s
diff --git a/data/sysrom/Makefile b/data/sysrom/Makefile
index da179c5..3121bd5 100644
--- a/data/sysrom/Makefile
+++ b/data/sysrom/Makefile
@@ -19,20 +19,20 @@ CFLAGS = -m68000 -O2 -fomit-frame-pointer -ffreestanding \
$(INCLUDE) $(CCWARN)
LIBGCC := '$(shell $(CC) $(CFLAGS) -print-libgcc-file-name)'
-LINKMAP = sysrom.ld
+LDFLAGS =
-LDFLAGS = -T $(LINKMAP)
-
-OBJS = $(patsubst %.asm,%.o,$(wildcard *.asm)) \
- $(patsubst %.c,%.o,$(wildcard *.c)) \
- font/sysfont.o
+SYSOBJS = $(patsubst %.asm,%.o,$(wildcard *.asm)) \
+ $(patsubst %.c,%.o,$(wildcard *.c))
+ABCOBJS = $(patsubst %.asm,%.o,$(wildcard abc/*.asm)) \
+ $(patsubst %.c,%.o,$(wildcard abc/*.c))
LIBOBJS = $(patsubst %.asm,%.o,$(wildcard lib/*.asm)) \
- $(patsubst %.c,%.o,$(wildcard lib/*.c fat/src/*.c))
+ $(patsubst %.c,%.o,$(wildcard lib/*.c fat/src/*.c)) \
+ font/sysfont.o
LIB = libsys.a
-all: sysrom.bin sysrom.map
+all: sysrom.bin sysrom.map abc8000.sys abc8000.map
FONT = 8x16-abc-l1.bdf
font/sysfont.c: font/$(FONT) font/bdf2c.pl
@@ -42,8 +42,14 @@ sysrom.bin: sysrom.elf
$(OBJCOPY) -O binary $< $@
$(PERL) padto.pl $@ 4096
-sysrom.elf: $(OBJS) $(LINKMAP) $(LIB)
- $(LD) $(LDFLAGS) -o $@ $(OBJS) $(LIB) $(LIBGCC)
+sysrom.elf: $(SYSOBJS) $(LIB) sysrom.ld
+ $(LD) $(LDFLAGS) -T sysrom.ld -o $@ $(SYSOBJS) $(LIB) $(LIBGCC)
+
+abc8000.elf: $(ABCOBJS) $(LIB) abc8000.ld
+ $(LD) $(LDFLAGS) -T abc8000.ld -o $@ $(ABCOBJS) $(LIB) $(LIBGCC)
+
+abc8000.sys: abc8000.elf
+ $(OBJCOPY) -O binary $< $@
$(LIB): $(LIBOBJS)
rm -f $@
@@ -71,7 +77,7 @@ MAKEDEPS = -Wp,-MT,$@,-MD,$(dir $@).$(notdir $@).d
-x assembler-with-cpp -E -o $@ $<
clean:
- for d in . font lib fat/src; do \
+ for d in . abc font lib fat/src; do \
rm -f $$d/*.o $$d/*.i $$d/*.s $$d/*.bin $$d/*.map ; \
rm -f $$d/*.elf $$d/*.a $$d/.*.d ; \
done
diff --git a/data/sysrom/abc/init.asm b/data/sysrom/abc/init.asm
new file mode 100644
index 0000000..94cda14
--- /dev/null
+++ b/data/sysrom/abc/init.asm
@@ -0,0 +1,50 @@
+/*
+ * Initial bootstrap before we can run C code
+ */
+#include <ioreg.h>
+
+ .section ".init","ax"
+ .globl _start
+_start:
+ /* Write Hello, World! on the serial port */
+ move.l #IO_SERIAL_DATA, %a0 /* Data port */
+ lea.l 2(%a0), %a2 /* Status port */
+ move.l #hello_str, %a1
+1:
+ btst #1, (%a2) /* TX FIFO available */
+ bne 1b
+ move.b (%a1)+, %d0
+ beq 2f
+ move.b %d0,(%a0)
+ bra 1b
+2:
+
+ /* Clear the BSS */
+ clr.l %d0
+ move.l #__bss_start, %a0
+ move.w #__bss_clear_count - 1, %d1
+bss_clear_loop:
+ move.l %d0, (%a0)+
+ move.l %d0, (%a0)+
+ move.l %d0, (%a0)+
+ move.l %d0, (%a0)+
+ move.l %d0, (%a0)+
+ move.l %d0, (%a0)+
+ move.l %d0, (%a0)+
+ move.l %d0, (%a0)+
+ dbf %d1, bss_clear_loop
+
+ jmp (main)
+
+ .section ".rodata","a"
+hello_str:
+ .ascii "*** Hello, On-Disk World! ***\r\n"
+ .byte 0
+
+ .bss
+ .balign 64
+ .globl __stack, __stack_top
+__stack:
+ .space 8192
+__stack_top:
+ .size __stack, .-__stack
diff --git a/data/sysrom/abc/main.c b/data/sysrom/abc/main.c
new file mode 100644
index 0000000..722303f
--- /dev/null
+++ b/data/sysrom/abc/main.c
@@ -0,0 +1,8 @@
+#include <stdio.h>
+
+int main(void)
+{
+ printf("Hello, World!\n");
+
+ return 0;
+}
diff --git a/data/sysrom/abc8000.ld b/data/sysrom/abc8000.ld
new file mode 100644
index 0000000..c2c7cc9
--- /dev/null
+++ b/data/sysrom/abc8000.ld
@@ -0,0 +1,54 @@
+OUTPUT_FORMAT("elf32-m68k", "elf32-m68k", "elf32-m68k")
+OUTPUT_ARCH(m68k)
+ENTRY(_start)
+SECTIONS
+{
+ /*
+ * This is where we get loaded by the firmware
+ */
+ . = 0x10000;
+ .init : {
+ *(.init)
+ } = 0x4e754e75
+
+ .text : {
+ __text_start = .;
+ *(.text)
+ *(.text.*)
+ __text_end = .;
+ } = 0x4e754e75
+
+ . = ALIGN(4);
+ .rodata : {
+ __rodata_start = .;
+ *(.rodata)
+ *(.rodata.*)
+ __rodata_end = .;
+ }
+
+ . = ALIGN(4);
+ .data : {
+ __data_start = .;
+ *(.data)
+ *(.data.*)
+ __data_end = .;
+ }
+
+ . = ALIGN(32);
+ .bss : {
+ __bss_start = .;
+ *(.bss)
+ *(.bss.*)
+ *(COMMON)
+ __bss_end = .;
+ }
+
+ __bss_clear_count = (__bss_end - __bss_start + 31) >> 5;
+
+ /*
+ * Sections we don't need...
+ */
+ /DISCARD/ : {
+ *(.eh_frame)
+ }
+}
diff --git a/data/sysrom/conio.c b/data/sysrom/lib/conio.c
index 6e5ddd2..6e5ddd2 100644
--- a/data/sysrom/conio.c
+++ b/data/sysrom/lib/conio.c
diff --git a/data/sysrom/sdcard.c b/data/sysrom/sdcard.c
index 7bd3aac..0263969 100644
--- a/data/sysrom/sdcard.c
+++ b/data/sysrom/sdcard.c
@@ -30,7 +30,8 @@
#include "ff.h"
#include "diskio.h"
-#define SECTOR_SIZE 512
+#define SECTOR_SHIFT 9
+#define SECTOR_SIZE (1UL << SECTOR_SHIFT)
enum sdcard_cmd {
CMD_GO_IDLE_STATE = 0, /* a.k.a. reset */
@@ -136,17 +137,22 @@ static int sdcard_read_block(void *buf, int len, int timeout, const void *xcmd)
uint32_t *pl;
uint16_t *pw;
uint8_t *pb = buf;
- uint16_t ccrc, xcrc;
+ uint16_t zcrc;
const uint16_t *xcp = xcmd;
+ int i;
for (;;) {
tok = readb(IO_SDC_RD_B(SDC_BYTE|SDC_START|SDC_CLEAR_CRC));
if (tok == 0xfe)
break;
- if (tok < 0xfe)
+ if (tok < 0xfe) {
+ printf("sdcard_read_block: bad token: %02x\n", tok);
return -1; /* Bad token */
- if (!--timeout)
+ }
+ if (!--timeout) {
+ printf("sdcard_read_block: reply timeout\n");
return -1; /* Timeout */
+ }
}
/* Shift in the next data byte */
@@ -162,19 +168,10 @@ static int sdcard_read_block(void *buf, int len, int timeout, const void *xcmd)
* This is unsafe for small blocks, but we only need to do this
* for full sectors (used to send STOP_TRANSMISSION).
*/
- pw = (uint16_t *)pb;
- if (xcp) {
- int i;
+ if (xcp)
+ len -= 6; /* Handle the last 6 bytes specially */
- for (i = 3; i; i--) {
- writew(*xcp++, IO_SDC_WR_W(0));
- *pw++ = readw(IO_SDC_RD_W(SDC_START));
- len -= 2;
- }
- }
-
- len -= 2;
- pl = (uint32_t *)pw;
+ pl = (uint32_t *)pb;
{
unsigned int dwords = len >> 2;
@@ -207,17 +204,45 @@ static int sdcard_read_block(void *buf, int len, int timeout, const void *xcmd)
*pb++ = readb(IO_SDC_RD_BH(SDC_START|SDC_BYTE));
/*
- * Now there are exactly 2 bytes left, and they are already
- * latched... read the CRC at this time.
+ * If we're sending a command in parallel, then we have to
+ * read in the last 6 bytes in parallel with transmitting the
+ * command out. Because pb may be misaligned at this point,
+ * do the reads as byte I/O on the host bus side.
+ */
+ if (xcp) {
+ for (i = 0; i < 3; i++) {
+ writew(*xcp++, IO_SDC_WR_W(0));
+ *pb++ = readb(IO_SDC_RD_BH(0));
+ *pb++ = readb(IO_SDC_RD_B(SDC_START));
+ }
+ }
+
+ {
+ int i, j;
+ const uint8_t *p = buf;
+
+ for (i = 0; p < pb; i += 16) {
+ for (j = 0; j < 16; j++) {
+ printf("%02x ", *p++);
+ }
+ printf("\n");
+ }
+ }
+
+ /*
+ * Now the CRC is latched in the shift register, and the CRC
+ * in the CRC generator should be zero. Shift in the first
+ * byte after the CRC for the next round.
*/
- ccrc = readw(IO_SDC_RD_CRC16(0));
- /* Do this with byte operations just in case the buffer is unaligned */
- pb[0] = readb(IO_SDC_RD_BH(0));
- pb[1] = readb(IO_SDC_RD_B(SDC_START));
- xcrc = readw(IO_SDC_RD_W(SDC_BYTE|SDC_START));
+ zcrc = readw(IO_SDC_RD_CRC16(SDC_START|SDC_BYTE));
+
+ if (zcrc != 0x0000) {
+ printf("sdcard_read_block: CRC error (zcrc = %04x)\n", zcrc);
+ return -1;
+ }
- return (ccrc == xcrc) ? 0 : -1;
+ return 0;
}
/*
@@ -228,16 +253,23 @@ int sdcard_read_sectors(void *buf, uint32_t lba, int count)
{
int rv;
int okcount = 0;
- static const uint8_t stop_transmission[6] =
- { 0x40|CMD_STOP_TRANSMISSION, 0x00, 0x00, 0x00, 0x00, 0x61 };
+ static const uint16_t stop_transmission[3] =
+ { (0x40|CMD_STOP_TRANSMISSION) << 8, 0x0000, 0x0061 };
uint8_t resp;
if (!count)
return 0;
+ printf("sdcard: reading %d sectors at %u to %p\n", count, lba, buf);
+
+ if (sdc.card_type == 1)
+ lba <<= SECTOR_SHIFT; /* Convert to a byte address */
+
rv = sdcard_send_cmd(CMD_READ_MULTIPLE_BLOCK, lba);
- if (rv)
+ if (rv) {
+ printf("sdcard: read_multiple error %02x\n", rv);
return 0;
+ }
while (count--) {
rv = sdcard_read_block(buf, SECTOR_SIZE, 200000,
@@ -247,15 +279,24 @@ int sdcard_read_sectors(void *buf, uint32_t lba, int count)
okcount++;
}
+ /* The first byte after the stop command is undefined */
+ (void)readb(IO_SDC_RD_B(SDC_BYTE|SDC_START));
+
/* Wait for the response to the STOP TRANSMISSION command */
do {
resp = readb(IO_SDC_RD_B(SDC_BYTE|SDC_START));
} while (resp & 0x80);
+ if (resp) {
+ printf("sdcard: read_sectors: terminate command error %02x\n",
+ resp);
+ }
+
return okcount;
}
-DRESULT disk_read(BYTE drive, BYTE *buffer, DWORD sectornumber, BYTE sectorcount)
+DRESULT disk_read(BYTE drive, BYTE *buffer,
+ DWORD sectornumber, BYTE sectorcount)
{
int rv;
@@ -294,9 +335,16 @@ int sdcard_write_sectors(const void *buf, uint32_t lba, int count)
if (!count)
return 0;
+ printf("sdcard: writing %d sectors at %u from %p\n", count, lba, buf);
+
+ if (sdc.card_type == 1)
+ lba <<= SECTOR_SHIFT; /* Convert to a byte address */
+
rv = sdcard_send_cmd(CMD_WRITE_MULTIPLE_BLOCK, lba);
- if (rv)
+ if (rv) {
+ printf("sdcard: write_multiple error %02x\n", rv);
return 0;
+ }
while (count--) {
uint16_t dbfloops = (SECTOR_SIZE >> 5) - 1;