summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cf-code/cf-fsi-fw.S50
-rw-r--r--cf-fsi-fw.h11
-rw-r--r--cf-fsi-test.c2
3 files changed, 54 insertions, 9 deletions
diff --git a/cf-code/cf-fsi-fw.S b/cf-code/cf-fsi-fw.S
index a68ce68..533cf39 100644
--- a/cf-code/cf-fsi-fw.S
+++ b/cf-code/cf-fsi-fw.S
@@ -200,21 +200,56 @@ _start:
move.b #FW_VERSION,%a1@(FW_VERS_REG)
move.b #API_VERSION,%a1@(API_VERS_REG)
+ /* Clear arbitration register */
+ move.b #0,%a1@(ARB_REG)
+
/*
* Main command loop
*/
main_loop:
lea %a1@(TRACEBUF),%a3
- /* Wait for command */
-1: move.l %a1@(CMD_REG),%d2
+ /* Wait arbitration request or command
+ *
+ * Note: This can run with interrupts enabled as a result of
+ * the stop op, so %d0 can be clobbered at any time.
+ */
+1: move.b %a1@(ARB_REG),%d2
+ bne arbitration_request
+ move.l %a1@(CMD_REG),%d2
tst.b %d2
- bne 1f
+ bne command_request
stop #0x2000
bra 1b
+arbitration_request:
/* Mask interrupts */
-1: move.w #0x2007,%sr
+ move.w #0x2007,%sr
+
+ /* Ack request */
+ move.b #ARB_ARM_ACK,%a1@(ARB_REG)
+
+ /* Wait until it's cleared by the host */
+0: move.b %a1@(ARB_REG),%d1
+ bne 1f
+
+ /* Got it, re-load the GPIO caches */
+ move.l %a5@(0),%DCLK
+ move.l %a4@(0),%DDAT
+
+ /* Reconfigure data as output just in case ... */
+ bsr config_gpio_out
+
+ /* Back to main loop */
+ bra main_loop
+
+ /* Wait, we'll get an interrupt when the host clears it */
+1: stop #0x2000
+ bra 0b
+
+command_request:
+ /* Mask interrupts */
+ move.w #0x2007,%sr
/* Mark ourselves as sending a command */
move.b #STAT_SENDING,%a1@(STAT_REG)
@@ -443,10 +478,13 @@ config_gpio_in:
move.l %d0,%a4@(4)
rts
- /* Interrupt handler */
+ /* Interrupt handler
+ *
+ * Note: Must only clobber %d0
+ */
_int:
addq.l #1,%a1@(INT_CNT)
- moveq.l #CVIC_SW_IRQ, %d0
+ moveq.l #CVIC_SW_IRQ,%d0
move.l %d0,%a2@(CVIC_SW_IRQ_CLR)
rte
diff --git a/cf-fsi-fw.h b/cf-fsi-fw.h
index 44bd8cc..36df3c9 100644
--- a/cf-fsi-fw.h
+++ b/cf-fsi-fw.h
@@ -2,7 +2,7 @@
#define __CF_FSI_FW_H
/*
- * SRAM layout
+ * SRAM layout: Main part
*/
/* Command register:
@@ -74,7 +74,7 @@
/* Misc */
#define INT_CNT 0x30 /* 32-bit interrupt count */
#define BAD_INT_VEC 0x34
-#define TRACEBUF 0x40
+#define TRACEBUF 0x100
#define TR_CLKOSTART 0x00
#define TR_OLEN 0x01/* + len */
#define TR_CLKOBIT0 0x02
@@ -87,5 +87,12 @@
#define TR_CLKIBIT0 0x80
#define TR_CLKIBIT1 0x81
+/*
+ * SRAM layout: GPIO arbitration part
+ */
+#define ARB_REG 0x40
+#define ARB_ARM_REQ 0x01
+#define ARB_ARM_ACK 0x02
+
#endif /* __CF_FSI_FW_H */
diff --git a/cf-fsi-test.c b/cf-fsi-test.c
index 65c240c..56e8a8f 100644
--- a/cf-fsi-test.c
+++ b/cf-fsi-test.c
@@ -104,7 +104,7 @@ static inline void writeq(uint64_t val, void *addr)
#define GPIO_AA_SRC_BIT 0x00010000
#define GPIO_R_SRC_BIT 0x00000100
-#define CVIC_BASE 0x000c2000
+#define CVIC_BASE 0x000c2000 /* 1e602000 */
#define CVIC_EN_REG 0x10
#define CVIC_TRIG_REG 0x18
OpenPOWER on IntegriCloud