summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cf-code/cf-fsi-fw.S76
-rw-r--r--cf-fsi-fw.h85
-rw-r--r--cf-fsi-test.c38
3 files changed, 122 insertions, 77 deletions
diff --git a/cf-code/cf-fsi-fw.S b/cf-code/cf-fsi-fw.S
index aa6a388..b771b79 100644
--- a/cf-code/cf-fsi-fw.S
+++ b/cf-code/cf-fsi-fw.S
@@ -161,13 +161,37 @@ _vecs:
.endr
/*
- * Main entry point
+ * Header info
*/
.org 0x400
+_header_info:
+ .short SYS_SIG /* 0x00 */
+ .short FW_VERSION /* 0x02 */
+ .byte API_VERSION_MAJ /* 0x04 */
+ .byte API_VERSION_MIN /* 0x05 */
+ .byte 0,0 /* 0x06 pad */
+#ifdef ENABLE_TRACE
+ .long FW_OPTION_TRACE_EN /* 0x08 */
+#else
+ .long 0
+#endif
+
+ /*
+ * Config area
+ */
+ .org 0x400 + HDR_CMD_STAT_AREA
+_cmd_stat_base:
+ .long SRAM_BASE_BE
+
+ /*
+ * Main entry point
+ */
+ .org 0x500
.global _start
_start:
/* Get base addresses */
- movea.l #SRAM_BASE_BE,%a1
+ lea %pc@(_cmd_stat_base),%a0
+ movea.l %a0@(0),%a1
movea.l #GPIO_BASE,%a4
movea.l %a4,%a5
add.l #CLOCK_GPIO_VREG,%a5
@@ -240,18 +264,8 @@ _start:
/* Configure GPIOs to output */
bsr config_gpio_out
- /* Populate version & signature */
- move.w #SYS_SIG,%a1@(SYS_SIG_REG)
- move.b #FW_VERSION,%a1@(FW_VERS_REG)
-
- /* This must happen last as it's the signal to the host
- * that we are ready
- */
-#ifdef ENABLE_TRACE
- move.b #(API_VERSION + API_VERSION_TRACE_EN),%a1@(API_VERS_REG)
-#else
- move.b #API_VERSION,%a1@(API_VERS_REG)
-#endif
+ /* Mark command complete, indicates we are ready */
+ move.b #STAT_COMPLETE,%a1@(CMD_STAT_REG)
/*
* Main command loop
@@ -266,7 +280,7 @@ main_loop:
*/
1: move.b %a1@(ARB_REG),%d2
bne arbitration_request
- move.l %a1@(CMD_REG),%d2
+ move.l %a1@(CMD_STAT_REG),%d2
tst.b %d2
bne command_request
stop #0x2000
@@ -301,11 +315,9 @@ command_request:
/* Mask interrupts */
move.w #0x2007,%sr
- /* Mark ourselves as sending a command */
- move.b #STAT_SENDING,%a1@(STAT_REG)
-
- /* Clear command register */
- move.b #CMD_NONE,%a1@(CMD_REG + 3)
+ /* Clear the command/status register */
+ moveq.l #0,%d0
+ move.l %d0,%a1@(CMD_STAT_REG)
/* Start command ? */
cmpi.b #CMD_COMMAND,%d2
@@ -320,7 +332,7 @@ command_request:
beq start_idle_clocks
/* Error */
- move.b #STAT_ERR_INVAL_CMD,%a1@(STAT_REG)
+ move.b #STAT_ERR_INVAL_CMD,%a1@(CMD_STAT_REG)
bra main_loop
/*
@@ -389,7 +401,7 @@ start_command:
beq 1f
subq.l #1,%d3
bne 0b
- move.b #STAT_ERR_MTOE,%a1@(STAT_REG)
+ move.b #STAT_ERR_MTOE,%a1@(CMD_STAT_REG)
bra send_delay
1: /* Got start bit, clock in slave ID and response tag */
@@ -454,7 +466,9 @@ start_command:
move.b %d4,%a1@(STAT_RCRC)
/* Mark command complete */
- move.b #STAT_COMPLETE,%a1@(STAT_REG)
+ moveq.l #STAT_COMPLETE,%d0
+ byterev %d0
+ move.l %d0,%a1@(CMD_STAT_REG)
send_delay:
/* Send delay after every command */
@@ -485,8 +499,11 @@ start_break:
move.l #FSI_POST_BREAK_CLOCKS,%d3
clock_out_zeros %d3
- /* That's it */
- move.b #STAT_COMPLETE,%a1@(STAT_REG)
+ /* Mark command complete */
+ moveq.l #STAT_COMPLETE,%d0
+ byterev %d0
+ move.l %d0,%a1@(CMD_STAT_REG)
+
bra main_loop
start_idle_clocks:
@@ -498,8 +515,11 @@ start_idle_clocks:
move.b %d2,%d3
clock_out_zeros %d3
- /* That's it */
- move.b #STAT_COMPLETE,%a1@(STAT_REG)
+ /* Mark command complete */
+ moveq.l #STAT_COMPLETE,%d0
+ byterev %d0
+ move.l %d0,%a1@(CMD_STAT_REG)
+
bra main_loop
config_gpio_out:
@@ -549,7 +569,7 @@ bad_exception:
sub.l %d1,%d0
lsr.l #2,%d0
move.b %d0,%a1@(BAD_INT_VEC)
- move.b #STAT_ERR_INVAL_IRQ,%a1@(STAT_REG)
+ move.b #STAT_ERR_INVAL_IRQ,%a1@(CMD_STAT_REG)
halt
/* Bad exception stubs */
diff --git a/cf-fsi-fw.h b/cf-fsi-fw.h
index 4942901..0c4453f 100644
--- a/cf-fsi-fw.h
+++ b/cf-fsi-fw.h
@@ -2,16 +2,52 @@
#define __CF_FSI_FW_H
/*
- * SRAM layout: Main part
+ * uCode file layout
+ *
+ * 0000...03ff : m68k exception vectors
+ * 0400...04ff : Header info & boot config block
+ * 0500....... : Code & stack
*/
-/* Command register:
+/*
+ * Header info & boot config area
+ *
+ * The Header info is built into the ucode and provide version and
+ * platform information.
+ *
+ * the Boot config needs to be adjusted by the ARM prior to starting
+ * the ucode if the Command/Status area isn't at 0x320000 in CF space
+ * (ie. beginning of SRAM).
+ */
+
+#define HDR_OFFSET 0x400
+
+/* Info: Signature & version */
+#define HDR_SYS_SIG 0x00 /* 2 bytes system signature */
+#define SYS_SIG_ROMULUS 0x526d /* 'Rm' */
+#define SYS_SIG_WITHERSPOON 0x5773 /* 'Ws' */
+#define HDR_FW_VERS 0x02 /* 2 bytes Major.Minor */
+#define HDR_API_VERS 0x04 /* 2 bytes Major.Minor */
+#define API_VERSION_MAJ 1 /* Current version */
+#define API_VERSION_MIN 1
+#define HDR_FW_OPTIONS 0x08 /* 4 bytes option flags */
+#define FW_OPTION_TRACE_EN 0x00000001 /* FW tracing enabled */
+
+/* Boot Config: Address of Command/Status area */
+#define HDR_CMD_STAT_AREA 0x80 /* 4 bytes CF address */
+
+/*
+ * Command/Status area layout: Main part
+ */
+
+/* Command/Status register:
*
* +---------------------------+
- * | rsvd | RLEN | CLEN | CMD |
+ * | STAT | RLEN | CLEN | CMD |
* | 8 | 8 | 8 | 8 |
* +---------------------------+
- * | | |
+ * | | | |
+ * status | | |
* Response len | |
* (in bits) | |
* | |
@@ -19,8 +55,11 @@
* (in bits) |
* |
* Command code
+ *
+ * Due to the big endian layout, that means that a byte read will
+ * return the status byte
*/
-#define CMD_REG 0x00
+#define CMD_STAT_REG 0x00
#define CMD_REG_CMD_MASK 0x000000ff
#define CMD_REG_CMD_SHIFT 0
#define CMD_NONE 0x00
@@ -32,40 +71,24 @@
#define CMD_REG_CLEN_SHIFT 8
#define CMD_REG_RLEN_MASK 0x00ff0000
#define CMD_REG_RLEN_SHIFT 16
+#define CMD_REG_STAT_MASK 0xff000000
+#define CMD_REG_STAT_SHIFT 24
+#define STAT_WORKING 0x00
+#define STAT_COMPLETE 0x01
+#define STAT_ERR_INVAL_CMD 0x80
+#define STAT_ERR_INVAL_IRQ 0x81
+#define STAT_ERR_MTOE 0x82
-/* Status register
- *
- */
-#define STAT_REG 0x04 /* Status */
-#define STAT_STOPPED 0x00
-#define STAT_SENDING 0x01
-#define STAT_COMPLETE 0x02
-#define STAT_ERR_INVAL_CMD 0x80
-#define STAT_ERR_INVAL_IRQ 0x81
-#define STAT_ERR_MTOE 0x82
-
-/* Response tag */
-#define STAT_RTAG 0x05
+/* Response tag & CRC */
+#define STAT_RTAG 0x04
/* Response CRC */
-#define STAT_RCRC 0x06
+#define STAT_RCRC 0x05
/* Echo and Send delay */
#define ECHO_DLY_REG 0x08
#define SEND_DLY_REG 0x09
-/* Signature & version */
-#define SYS_SIG_REG 0x0c /* 2 bytes system signature */
-#define SYS_SIG_ROMULUS 0x526d /* 'Rm' */
-#define SYS_SIG_WITHERSPOON 0x5773 /* 'Ws' */
-#define FW_VERS_REG 0x0e
-#define API_VERS_REG 0x0f
-
-/* Current API version */
-#define API_VERSION_MASK 0x7f
-#define API_VERSION 1
-#define API_VERSION_TRACE_EN 0x80
-
/* Command data area
*
* Last byte of message must be left aligned
diff --git a/cf-fsi-test.c b/cf-fsi-test.c
index ef9435b..bf209f3 100644
--- a/cf-fsi-test.c
+++ b/cf-fsi-test.c
@@ -222,12 +222,26 @@ static void start_cf(void)
static void load_cf_code(void)
{
extern uint8_t cf_code_start, cf_code_end;
+ uint16_t sig, fw_vers, api_vers;
+ uint32_t fw_options;
uint8_t *code = &cf_code_start;
uint8_t *mem = cfmem;
while(code < &cf_code_end)
writeb(*(code++), mem++);
+
+ sig = ntohs(readw(cfmem + HDR_OFFSET + HDR_SYS_SIG));
+ fw_vers = ntohs(readw(cfmem + HDR_OFFSET + HDR_FW_VERS));
+ api_vers = ntohs(readw(cfmem + HDR_OFFSET + HDR_API_VERS));
+ fw_options = ntohl(readl(cfmem + HDR_OFFSET + HDR_FW_OPTIONS));
+
+ trace_enabled = !!(fw_options & FW_OPTION_TRACE_EN);
+
+ printf("SYS_SIG=%.4x FW_VERSION=%d API_VERSION=%d.%d (trace %s)\n",
+ sig, fw_vers, api_vers >> 8, api_vers & 0xff,
+ trace_enabled ? "enabled" : "disabled");
+
}
static void gpio_source_arm(void)
@@ -544,9 +558,8 @@ static void dump_stuff(void)
{
int i;
- printf("CMD:%08x STAT:%02x RTAG=%02x RCRC=%02x RDATA=%02x #INT=%08x\n",
- ntohl(readl(sysreg + SRAM_BASE + CMD_REG)),
- readb(sysreg + SRAM_BASE + STAT_REG),
+ printf("CMD:%08x RTAG=%02x RCRC=%02x RDATA=%02x #INT=%08x\n",
+ ntohl(readl(sysreg + SRAM_BASE + CMD_STAT_REG)),
readb(sysreg + SRAM_BASE + STAT_RTAG),
readb(sysreg + SRAM_BASE + STAT_RCRC),
ntohl(readl(sysreg + SRAM_BASE + RSP_DATA)),
@@ -564,11 +577,8 @@ static int do_command(uint32_t op)
uint32_t timeout = 100000;
uint8_t stat;
- /* Clear status reg */
- writeb(0, sysreg + SRAM_BASE + STAT_REG);
-
/* Send command */
- writel(htonl(op), sysreg + SRAM_BASE + CMD_REG);
+ writel(htonl(op), sysreg + SRAM_BASE + CMD_STAT_REG);
/* Ring doorbell */
writel(0x2, sysreg + CVIC_BASE + CVIC_TRIG_REG);
@@ -581,7 +591,7 @@ static int do_command(uint32_t op)
dump_stuff();
return -ETIMEDOUT;
}
- stat = readb(sysreg + SRAM_BASE + STAT_REG);
+ stat = readb(sysreg + SRAM_BASE + CMD_STAT_REG);
} while(stat < STAT_COMPLETE || stat == 0xff);
if (stat == STAT_COMPLETE)
@@ -738,19 +748,11 @@ int main(int argc, char *argv[])
/* Start ColdFire */
start_cf();
- /* Wait for ack API version register*/
+ /* Wait for status register to say command complete */
do {
- val = readb(sysreg + SRAM_BASE + API_VERS_REG);
+ val = readb(sysreg + SRAM_BASE + CMD_STAT_REG);
} while (val == 0x00);
- trace_enabled = !!(val & API_VERSION_TRACE_EN);
-
- printf("SYS_SIG=%.4x FW_VERSION=%d API_VERSION=%d (trace %s)\n",
- ntohs(readw(sysreg + SRAM_BASE + SYS_SIG_REG)),
- readb(sysreg + SRAM_BASE + FW_VERS_REG),
- val & API_VERSION_MASK,
- trace_enabled ? "enabled" : "disabled");
-
/* Configure echo & send delay */
writeb(16, sysreg + SRAM_BASE + ECHO_DLY_REG);
writeb(16, sysreg + SRAM_BASE + SEND_DLY_REG);
OpenPOWER on IntegriCloud