Browse Source

abcio: more handler functions; prioritize the ABC interrupt

Functions for setting up handlers etc; change the interrupt dispatcher
to give priority to the ABC-bus interrupt.x
H. Peter Anvin 3 years ago
parent
commit
eaee1583d8
8 changed files with 5695 additions and 5638 deletions
  1. BIN
      fpga/output_files/max80.jbc
  2. BIN
      fpga/output_files/max80.jic
  3. BIN
      fpga/output_files/max80.pof
  4. BIN
      fpga/output_files/max80.sof
  5. 45 2
      fw/abcio.c
  6. 6 1
      fw/abcio.h
  7. 5634 5634
      fw/boot.mif
  8. 10 1
      fw/irqasm.S

BIN
fpga/output_files/max80.jbc


BIN
fpga/output_files/max80.jic


BIN
fpga/output_files/max80.pof


BIN
fpga/output_files/max80.sof


+ 45 - 2
fw/abcio.c

@@ -9,8 +9,9 @@
 #include "irq.h"
 #include "abcio.h"
 
-struct abc_dev *abc_device[64];
+static struct abc_dev *abc_device[64];
 static struct abc_dev *selected_dev;
+static uint8_t abc_devsel = -1;
 
 static inline void abc_select(struct abc_dev *dev)
 {
@@ -52,7 +53,7 @@ IRQHANDLER(abc)
 
 	case 1:
 	{
-	    struct abc_dev *dev = abc_device[data & 0x3f];
+	    struct abc_dev *dev = abc_device[abc_devsel = data & 0x3f];
 	    abc_select(dev);
 
 	    if (dev)
@@ -62,6 +63,7 @@ IRQHANDLER(abc)
 
 	case 7:
 	    /* XXX: broadcast reset to devices? */
+	    abc_devsel = -1;
 	    abc_select(NULL);
 	    break;
 
@@ -92,3 +94,44 @@ IRQHANDLER(abc)
 
     ABC_BUSY_STATUS = what;
 }
+
+void abc_setup_out_queue(struct abc_dev *dev, void *buf, size_t len,
+			 uint8_t status, uint8_t status_first_mask)
+{
+    mask_irq(ABC_IRQ);
+
+    dev->status_first_out_mask = status_first_mask;
+    dev->out_buf = buf;
+    dev->out_cnt = len;
+    ABC_INP1_DATA = dev->inp_data[1] = status;
+
+    unmask_irq(ABC_IRQ);
+}
+
+void abc_setup_inp_queue(struct abc_dev *dev, const void *buf, size_t len,
+			 uint8_t status, uint8_t status_first_mask)
+{
+    mask_irq(ABC_IRQ);
+
+    dev->status_first_inp_mask = status_first_mask;
+    dev->inp_buf = buf;
+    dev->inp_cnt = len;
+    ABC_INP0_DATA = *dev->inp_buf++;
+    ABC_INP1_DATA = dev->inp_data[1] = status;
+
+    unmask_irq(ABC_IRQ);
+}
+
+void abc_register(struct abc_dev *dev, unsigned int devsel)
+{
+    if (devsel > 63)
+	return;
+
+    mask_irq(ABC_IRQ);
+
+    abc_device[devsel] = dev;
+    if (devsel == abc_devsel)
+	abc_select(dev);
+
+    unmask_irq(ABC_IRQ);
+}

+ 6 - 1
fw/abcio.h

@@ -1,4 +1,5 @@
 #ifndef ABCIO_H
+#define ABCIO_H
 
 #include <stddef.h>
 #include <stdint.h>
@@ -25,6 +26,10 @@ struct abc_dev {
     void (*callback_inp)(struct abc_dev *, uint8_t addr);
 };
 
-extern struct abc_dev *abc_device[64];
+void abc_setup_out_queue(struct abc_dev *dev, void *buf, size_t len,
+			 uint8_t status, uint8_t status_first_mask);
+void abc_setup_inp_queue(struct abc_dev *dev, const void *buf, size_t len,
+			 uint8_t status, uint8_t status_first_mask);
+void abc_register(struct abc_dev *dev, unsigned int devsel);
 
 #endif /* ABCIO_H */

File diff suppressed because it is too large
+ 5634 - 5634
fw/boot.mif


+ 10 - 1
fw/irqasm.S

@@ -13,9 +13,17 @@
 	.option norvc	// Alignment matters more here
 _irq:
 	addqxi sp,sp,0
-
 	// s10 contains the IRQ return address, s11 the mask of
 	// IRQs to be handled.
+
+	// Priority for ABC-bus I/O
+	andi s0,s11,1 << ABC_IRQ
+	beqz s0,1f
+	jal irqhandler_abc
+	sub s11,s11,s0
+	beqz s11,.L_done
+1:
+
 	li s1, 0
 .Lirq_loop:
 	// ctz would make this more efficient...
@@ -68,6 +76,7 @@ _irq:
 	addi s1,s1,4*1
 	bnez s11,.Lirq_loop
 
+.L_done:
 	mret
 	.type _irq, @function
 	.size _irq, . - _irq

Some files were not shown because too many files changed in this diff