diff --git a/board/avaota-f1/cdk/avaota_f1.cdkproj b/board/avaota-f1/cdk/avaota_f1.cdkproj
index 9f8ae57d..3c34cccd 100644
--- a/board/avaota-f1/cdk/avaota_f1.cdkproj
+++ b/board/avaota-f1/cdk/avaota_f1.cdkproj
@@ -238,6 +238,7 @@
+
@@ -276,6 +277,9 @@
+
+
+
@@ -507,6 +511,9 @@
+
+
+
@@ -534,6 +541,17 @@
+
+
+ 0x20181C8;;;
+ ;;32;;MHZ;;up
+
+ 1
+ 1
+
+ 100:4;100:8;100:8;100:8;
+ 1
+
@@ -637,7 +655,7 @@
None (-O0)
Maximum (-g3)
- $(ProjectPath);../../../include/;../../../include/arch/riscv/;../../../include/cli/;../../../include/drivers/chips/sun300iw1/;../../../include/drivers/mmc/;../../../include/drivers/pmu/reg/;../../../include/drivers/pmu/;../../../include/drivers/reg/;../../../include/drivers/usb/;../../../include/image/;../../../include/lib/elf/;../../../include/lib/fatfs/;../../../include/lib/fdt/;../../../include/drivers/;../../../include/drivers/chips/;../../../include/drivers/mtd
+ $(ProjectPath);../../../include/;../../../include/arch/riscv/;../../../include/cli/;../../../include/drivers/chips/sun300iw1/;../../../include/drivers/mmc/;../../../include/drivers/pmu/reg/;../../../include/drivers/pmu/;../../../include/drivers/reg/;../../../include/drivers/usb/;../../../include/image/;../../../include/lib/elf/;../../../include/lib/fatfs/;../../../include/lib/fdt/;../../../include/drivers/;../../../include/drivers/chips/;../../../include/drivers/mtd/;../../../include/drivers/intc/
-nostdlib -nostdinc -march=rv32imafcxthead -mabi=ilp32f -Wno-int-to-pointer-cast -Wno-int-to-pointer-cast -Wno-shift-count-overflow -Wno-builtin-declaration-mismatch -Wno-pointer-to-int-cast -Wno-implicit-function-declaration -Wno-discarded-qualifiers -Wno-unused-function -Wno-unused-variable -Wno-unused-but-set-variable -Wno-parentheses
no
no
@@ -654,7 +672,7 @@
- $(ProjectPath);../../../include/;../../../include/arch/riscv/;../../../include/cli/;../../../include/drivers/chips/sun300iw1/;../../../include/drivers/mmc/;../../../include/drivers/pmu/reg/;../../../include/drivers/pmu/;../../../include/drivers/reg/;../../../include/drivers/usb/;../../../include/image/;../../../include/lib/elf/;../../../include/lib/fatfs/;../../../include/lib/fdt/;../../../include/drivers/;../../../include/drivers/chips/
+ $(ProjectPath);../../../include/;../../../include/arch/riscv/;../../../include/cli/;../../../include/drivers/chips/sun300iw1/;../../../include/drivers/mmc/;../../../include/drivers/pmu/reg/;../../../include/drivers/pmu/;../../../include/drivers/reg/;../../../include/drivers/usb/;../../../include/image/;../../../include/lib/elf/;../../../include/lib/fatfs/;../../../include/lib/fdt/;../../../include/drivers/;../../../include/drivers/chips/;../../../include/drivers/intc/
none
@@ -668,6 +686,8 @@
no
start-group
no
+ none
+ no
yes
@@ -723,12 +743,15 @@
+ yes
no
4444
no
6666
5000
+ localhost
+ 3333
openocd-sifive
latest
@@ -751,15 +774,4 @@
-
-
- 0x20181C8;;;
- ;;32;;MHZ;;up
-
- 1
- 1
-
- 100:4;100:8;100:8;100:8;
- 1
-
diff --git a/board/avaota-f1/cdk/config.h b/board/avaota-f1/cdk/config.h
index a53a0d5c..1af4787a 100644
--- a/board/avaota-f1/cdk/config.h
+++ b/board/avaota-f1/cdk/config.h
@@ -5,7 +5,7 @@
// Project Info
#define PROJECT_NAME "SyterKit"
-#define PROJECT_VERSION "0.3.0"
+#define PROJECT_VERSION "0.4.0.2"
#define PROJECT_GIT_HASH "58dcc02e"
#define PROJECT_C_COMPILER "riscv64-unknown-elf-gcc"
#define PROJECT_C_COMPILER_VERSION "10.4.0"
diff --git a/board/avaota-f1/start.S b/board/avaota-f1/start.S
index 209bfd3d..450170b6 100644
--- a/board/avaota-f1/start.S
+++ b/board/avaota-f1/start.S
@@ -179,87 +179,87 @@ vectors:
mret
/*
- * IRQ vectors.
- */
- .align 6
- .globl irq_handler
+ * IRQ vectors.
+ */
+ .align 6
+ .globl irq_handler
irq_handler:
- csrw mscratch, sp
- addi sp, sp, -(37 * REGSZ)
- SREG x1, 1 * REGSZ(x2)
- SREG x3, 3 * REGSZ(x2)
- SREG x4, 4 * REGSZ(x2)
- SREG x5, 5 * REGSZ(x2)
- SREG x6, 6 * REGSZ(x2)
- SREG x7, 7 * REGSZ(x2)
- SREG x8, 8 * REGSZ(x2)
- SREG x9, 9 * REGSZ(x2)
- SREG x10, 10 * REGSZ(x2)
- SREG x11, 11 * REGSZ(x2)
- SREG x12, 12 * REGSZ(x2)
- SREG x13, 13 * REGSZ(x2)
- SREG x14, 14 * REGSZ(x2)
- SREG x15, 15 * REGSZ(x2)
- SREG x16, 16 * REGSZ(x2)
- SREG x17, 17 * REGSZ(x2)
- SREG x18, 18 * REGSZ(x2)
- SREG x19, 19 * REGSZ(x2)
- SREG x20, 20 * REGSZ(x2)
- SREG x21, 21 * REGSZ(x2)
- SREG x22, 22 * REGSZ(x2)
- SREG x23, 23 * REGSZ(x2)
- SREG x24, 24 * REGSZ(x2)
- SREG x25, 25 * REGSZ(x2)
- SREG x26, 26 * REGSZ(x2)
- SREG x27, 27 * REGSZ(x2)
- SREG x28, 28 * REGSZ(x2)
- SREG x29, 29 * REGSZ(x2)
- SREG x30, 30 * REGSZ(x2)
- SREG x31, 31 * REGSZ(x2)
- csrrw t0, mscratch, x0
- csrr s0, mstatus
- csrr t1, mepc
- csrr t2, mbadaddr
- csrr t3, mcause
- SREG t0, 2 * REGSZ(x2)
- SREG s0, 32 * REGSZ(x2)
- SREG t1, 33 * REGSZ(x2)
- SREG t2, 34 * REGSZ(x2)
- SREG t3, 35 * REGSZ(x2)
- li x5, -1
- SREG x5, 36 * REGSZ(x2)
- move a0, sp
- jal riscv_handle_exception
- csrr a0, mscratch
- LREG x1, 1 * REGSZ(a0)
- LREG x2, 2 * REGSZ(a0)
- LREG x3, 3 * REGSZ(a0)
- LREG x4, 4 * REGSZ(a0)
- LREG x5, 5 * REGSZ(a0)
- LREG x6, 6 * REGSZ(a0)
- LREG x7, 7 * REGSZ(a0)
- LREG x8, 8 * REGSZ(a0)
- LREG x9, 9 * REGSZ(a0)
- LREG x11, 11 * REGSZ(a0)
- LREG x12, 12 * REGSZ(a0)
- LREG x13, 13 * REGSZ(a0)
- LREG x14, 14 * REGSZ(a0)
- LREG x15, 15 * REGSZ(a0)
- LREG x16, 16 * REGSZ(a0)
- LREG x17, 17 * REGSZ(a0)
- LREG x18, 18 * REGSZ(a0)
- LREG x19, 19 * REGSZ(a0)
- LREG x20, 20 * REGSZ(a0)
- LREG x21, 21 * REGSZ(a0)
- LREG x22, 22 * REGSZ(a0)
- LREG x23, 23 * REGSZ(a0)
- LREG x24, 24 * REGSZ(a0)
- LREG x25, 25 * REGSZ(a0)
- LREG x26, 26 * REGSZ(a0)
- LREG x27, 27 * REGSZ(a0)
- LREG x28, 28 * REGSZ(a0)
- LREG x29, 29 * REGSZ(a0)
- LREG x30, 30 * REGSZ(a0)
- LREG x31, 31 * REGSZ(a0)
- LREG x10, 10 * REGSZ(a0)
- mret
+ csrw mscratch, sp
+ addi sp, sp, -(37 * REGSZ)
+ SREG x1, 1 * REGSZ(x2)
+ SREG x3, 3 * REGSZ(x2)
+ SREG x4, 4 * REGSZ(x2)
+ SREG x5, 5 * REGSZ(x2)
+ SREG x6, 6 * REGSZ(x2)
+ SREG x7, 7 * REGSZ(x2)
+ SREG x8, 8 * REGSZ(x2)
+ SREG x9, 9 * REGSZ(x2)
+ SREG x10, 10 * REGSZ(x2)
+ SREG x11, 11 * REGSZ(x2)
+ SREG x12, 12 * REGSZ(x2)
+ SREG x13, 13 * REGSZ(x2)
+ SREG x14, 14 * REGSZ(x2)
+ SREG x15, 15 * REGSZ(x2)
+ SREG x16, 16 * REGSZ(x2)
+ SREG x17, 17 * REGSZ(x2)
+ SREG x18, 18 * REGSZ(x2)
+ SREG x19, 19 * REGSZ(x2)
+ SREG x20, 20 * REGSZ(x2)
+ SREG x21, 21 * REGSZ(x2)
+ SREG x22, 22 * REGSZ(x2)
+ SREG x23, 23 * REGSZ(x2)
+ SREG x24, 24 * REGSZ(x2)
+ SREG x25, 25 * REGSZ(x2)
+ SREG x26, 26 * REGSZ(x2)
+ SREG x27, 27 * REGSZ(x2)
+ SREG x28, 28 * REGSZ(x2)
+ SREG x29, 29 * REGSZ(x2)
+ SREG x30, 30 * REGSZ(x2)
+ SREG x31, 31 * REGSZ(x2)
+ csrrw t0, mscratch, x0
+ csrr s0, mstatus
+ csrr t1, mepc
+ csrr t2, mbadaddr
+ csrr t3, mcause
+ SREG t0, 2 * REGSZ(x2)
+ SREG s0, 32 * REGSZ(x2)
+ SREG t1, 33 * REGSZ(x2)
+ SREG t2, 34 * REGSZ(x2)
+ SREG t3, 35 * REGSZ(x2)
+ li x5, -1
+ SREG x5, 36 * REGSZ(x2)
+ move a0, sp
+ jal riscv_handle_exception
+ csrr a0, mscratch
+ LREG x1, 1 * REGSZ(a0)
+ LREG x2, 2 * REGSZ(a0)
+ LREG x3, 3 * REGSZ(a0)
+ LREG x4, 4 * REGSZ(a0)
+ LREG x5, 5 * REGSZ(a0)
+ LREG x6, 6 * REGSZ(a0)
+ LREG x7, 7 * REGSZ(a0)
+ LREG x8, 8 * REGSZ(a0)
+ LREG x9, 9 * REGSZ(a0)
+ LREG x11, 11 * REGSZ(a0)
+ LREG x12, 12 * REGSZ(a0)
+ LREG x13, 13 * REGSZ(a0)
+ LREG x14, 14 * REGSZ(a0)
+ LREG x15, 15 * REGSZ(a0)
+ LREG x16, 16 * REGSZ(a0)
+ LREG x17, 17 * REGSZ(a0)
+ LREG x18, 18 * REGSZ(a0)
+ LREG x19, 19 * REGSZ(a0)
+ LREG x20, 20 * REGSZ(a0)
+ LREG x21, 21 * REGSZ(a0)
+ LREG x22, 22 * REGSZ(a0)
+ LREG x23, 23 * REGSZ(a0)
+ LREG x24, 24 * REGSZ(a0)
+ LREG x25, 25 * REGSZ(a0)
+ LREG x26, 26 * REGSZ(a0)
+ LREG x27, 27 * REGSZ(a0)
+ LREG x28, 28 * REGSZ(a0)
+ LREG x29, 29 * REGSZ(a0)
+ LREG x30, 30 * REGSZ(a0)
+ LREG x31, 31 * REGSZ(a0)
+ LREG x10, 10 * REGSZ(a0)
+ mret
diff --git a/include/arch/riscv/csr.h b/include/arch/riscv/csr.h
index e7553f4d..bfb8d2b7 100644
--- a/include/arch/riscv/csr.h
+++ b/include/arch/riscv/csr.h
@@ -74,6 +74,12 @@ extern "C" {
#define MIE_SEIE (1 << 9) /**< Supervisor External Interrupt Enable */
#define MIE_MEIE (1 << 11) /**< Machine External Interrupt Enable */
+/* RISC-V Privilege */
+#define PRV_U (0)
+#define PRV_S (1)
+#define PRV_H (2)
+#define PRV_M (3)
+
/**
* @brief Swap the value of a CSR with a new value.
*
diff --git a/include/drivers/intc/sys-clic.h b/include/drivers/intc/sys-clic.h
new file mode 100644
index 00000000..87d55f7a
--- /dev/null
+++ b/include/drivers/intc/sys-clic.h
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef _SYS_CLIC_H_
+#define _SYS_CLIC_H_
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif// __cplusplus
+
+#define CLIC_IRQ_NUM (186)
+
+typedef enum irq_trigger_type {
+ IRQ_TRIGGER_TYPE_LEVEL,
+ IRQ_TRIGGER_TYPE_EDGE_RISING,
+ IRQ_TRIGGER_TYPE_EDGE_FALLING,
+ IRQ_TRIGGER_TYPE_EDGE_BOTH
+} irq_trigger_type_t;
+
+typedef struct irq_controller {
+ uint16_t id;
+ uint16_t irq_cnt;
+ uint16_t parent_id;
+ uint16_t irq_id;
+ uint64_t reg_base_addr;
+} irq_controller_t;
+
+/**
+ * @brief Handles the IRQ
+ *
+ */
+void do_irq();
+
+/**
+ * @brief Initializes the interrupt mechanism
+ *
+ * @return 0 on success, or an error code
+ */
+int arch_interrupt_init(void);
+
+/**
+ * @brief Exits the interrupt mechanism
+ *
+ * @return 0 on success, or an error code
+ */
+int arch_interrupt_exit(void);
+
+#ifdef __cplusplus
+}
+#endif// __cplusplus
+
+#endif// _SYS_CLIC_H_
\ No newline at end of file
diff --git a/include/drivers/reg/reg-clic.h b/include/drivers/reg/reg-clic.h
new file mode 100644
index 00000000..67267453
--- /dev/null
+++ b/include/drivers/reg/reg-clic.h
@@ -0,0 +1,69 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#ifndef __REG_CLIC_H__
+#define __REG_CLIC_H__
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif// __cplusplus
+
+/* RISC-V CLIC register offset */
+#define CLIC_CFG_REG_OFF 0x00
+#define CLIC_INFO_REG_OFF 0x04
+
+#define CLIC_MINTTHRESH_REG_OFF 0x08
+
+#define CLIC_INT_IP_REG_OFF 0x1000
+#define CLIC_INT_IE_REG_OFF 0x1001
+#define CLIC_INT_ATTR_REG_OFF 0x1002
+#define CLIC_INT_CTRL_REG_OFF 0x1003
+
+#define CLIC_INT_REG_ADDR_INTERVAL 0x4
+
+#define CLIC_INT_X_IP_REG_OFF(id) (0x1000 + ((id) *CLIC_INT_REG_ADDR_INTERVAL))
+#define CLIC_INT_X_IE_REG_OFF(id) (0x1001 + ((id) *CLIC_INT_REG_ADDR_INTERVAL))
+#define CLIC_INT_X_ATTR_REG_OFF(id) (0x1002 + ((id) *CLIC_INT_REG_ADDR_INTERVAL))
+#define CLIC_INT_X_CTRL_REG_OFF(id) (0x1003 + ((id) *CLIC_INT_REG_ADDR_INTERVAL))
+
+#define CLIC_INX_X_32BIT_REG_OFF(id) \
+ (0x1000 + ((id) *CLIC_INT_REG_ADDR_INTERVAL))
+
+/* CLIC_CFG_REG */
+#define PREEMPTION_PRIORITY_BITS_SHIFT 1
+#define PREEMPTION_PRIORITY_BITS_MASK (0xF << PREEMPTION_PRIORITY_BITS_SHIFT)
+
+/* CLIC_INFO_REG */
+#define IRQ_CNT_SHIFT 0
+#define IRQ_CNT_MASK (0x1FFF << IRQ_CNT_SHIFT)
+
+#define HW_VERSION_SHIFT 13
+#define HW_VERSION_MASK (0xF << HW_VERSION_SHIFT)
+
+#define HW_IMPL_VERSION_SHIFT 17
+#define HW_IMPL_VERSION_MASK (0xF << HW_IMPL_VERSION_SHIFT)
+
+#define CTRL_REG_BITS_SHIFT 21
+#define CTRL_REG_BITS_MASK (0xF << CTRL_REG_BITS_SHIFT)
+
+/* CLIC_INT_IP_REG */
+#define IP_SHIFT 0
+#define IP_BIT_MASK (0x1 << IP_SHIFT)
+
+/* CLIC_INT_IE_REG */
+#define IE_SHIFT 0
+#define IE_BIT_MASK (0x1 << IE_SHIFT)
+
+/* CLIC_INT_ATTR_REG */
+#define HW_VECTOR_IRQ_SHIFT 0
+#define HW_VECTOR_IRQ_BIT_MASK (0x1 << HW_VECTOR_IRQ_SHIFT)
+
+#define TRIGGER_TYPE_SHIFT 1
+#define TRIGGER_TYPE_BIT_MASK (0x3 << TRIGGER_TYPE_SHIFT)
+
+#ifdef __cplusplus
+}
+#endif// __cplusplus
+
+#endif// __REG_CLIC_H__
\ No newline at end of file
diff --git a/src/arch/riscv/riscv32_e907/exception.c b/src/arch/riscv/riscv32_e907/exception.c
index 659b78b1..3d6cea42 100644
--- a/src/arch/riscv/riscv32_e907/exception.c
+++ b/src/arch/riscv/riscv32_e907/exception.c
@@ -14,6 +14,8 @@
#include
#include
+#include
+
#if defined(__riscv_flen)
#if __riscv_flen >= 32
extern void f32_read(int n, uint32_t *v);
@@ -115,19 +117,6 @@ struct instruction_info_t {
unsigned int sign_extend : 1;
};
-/**
- * @brief Structure for IRQ handler
- *
- * @param data Pointer to data associated with the IRQ handler
- * @param func Function pointer to the IRQ handler function
- */
-typedef struct _irq_handler {
- void *data;
- void (*func)(void *data);
-} irq_handler_t;
-
-static irq_handler_t core_interrupt_handler[8] = {0};
-
static struct instruction_info_t insn_info[] = {
#if __riscv_xlen == 128
{0x00002000, 0x0000e003, 2, 7, 8, 0, 1, 16, 1}, /* C.LQ */
@@ -274,9 +263,9 @@ static void show_regs(struct pt_regs_t *regs) {
printk_error("Bad address: 0x%08x\r\n", regs->badvaddr);
printk_error("Stored ra: 0x%08x\r\n", regs->x[1]);
printk_error("Stored sp: 0x%08x\r\n", regs->x[2]);
- printk_error("========== backtrace ==========\n");
- dump_stack();
- backtrace((char *)regs->epc, (long *)regs->x[2], (char *)regs->x[1]);
+ printk_error("========== backtrace ==========\n");
+ dump_stack();
+ backtrace((char *) regs->epc, (long *) regs->x[2], (char *) regs->x[1]);
}
static struct instruction_info_t *match_instruction(unsigned long insn) {
@@ -429,7 +418,7 @@ void riscv_handle_exception(struct pt_regs_t *regs) {
case 6: /* Hypervisor timer interrupt */
case 7: /* Machine timer interrupt */
csr_clear(mip, pending);
- (core_interrupt_handler[cause].func)(core_interrupt_handler[cause].data);
+ do_irq();
break;
case 8: /* User external interrupt */
case 9: /* Supervisor external interrupt */
@@ -472,6 +461,3 @@ void riscv_handle_exception(struct pt_regs_t *regs) {
}
abort();
}
-
-static void dummy_interrupt_function(void *data) {
-}
diff --git a/src/drivers/intc/sys-clic.c b/src/drivers/intc/sys-clic.c
new file mode 100644
index 00000000..e5ce4cc2
--- /dev/null
+++ b/src/drivers/intc/sys-clic.c
@@ -0,0 +1,232 @@
+/* SPDX-License-Identifier: GPL-2.0+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+#include
+
+#include
+
+#include
+#include
+
+static irq_handler_t sunxi_int_handlers[CLIC_IRQ_NUM];
+static irq_controller_t sunxi_clic_controller;
+
+static int sunxi_plat_irq_init(void) {
+ uint32_t i;
+ irq_controller_t *ic;
+ ic = &sunxi_clic_controller;
+ ic->reg_base_addr = (SUNXI_RISCV_CLINT_BASE + 0x800000);
+ ic->irq_cnt = 208;
+ ic->parent_id = 0;
+ ic->irq_id = 0;
+ return 0;
+}
+
+static inline void sunxi_clic_set_irq_ctrl_bit(uint32_t reg_addr, uint8_t mask, int is_set) {
+ uint8_t reg_data = readb(reg_addr);
+ if (is_set)
+ reg_data |= mask;
+ else
+ reg_data &= ~mask;
+ writeb(reg_data, reg_addr);
+}
+
+static inline void sunxi_clic_set_enable(uint32_t reg_addr, int enabled) {
+ sunxi_clic_set_irq_ctrl_bit(reg_addr, IE_BIT_MASK, enabled);
+}
+
+static inline void sunxi_clic_set_pending(uint32_t reg_addr, int pending) {
+ sunxi_clic_set_irq_ctrl_bit(reg_addr, IP_BIT_MASK, pending);
+}
+
+static inline void sunxi_clic_set_vec_mode(uint32_t reg_addr, int vec_mode) {
+ sunxi_clic_set_irq_ctrl_bit(reg_addr, HW_VECTOR_IRQ_BIT_MASK, vec_mode);
+}
+
+static inline void sunxi_clic_set_trigger_type(uint32_t reg_addr, irq_trigger_type_t type) {
+ uint8_t reg_data, field_value;
+ if (type == IRQ_TRIGGER_TYPE_LEVEL) {
+ field_value = 0;
+ } else if (type == IRQ_TRIGGER_TYPE_EDGE_RISING) {
+ field_value = 1;
+ } else if (type == IRQ_TRIGGER_TYPE_EDGE_FALLING) {
+ field_value = 3;
+ } else {
+ return;
+ }
+ reg_data = readb(reg_addr);
+ reg_data &= ~TRIGGER_TYPE_BIT_MASK;
+ reg_data |= field_value << TRIGGER_TYPE_SHIFT;
+ writeb(reg_data, reg_addr);
+}
+
+static int sunxi_clic_init(const struct irq_controller *ic) {
+ uint32_t i, reg_data, irq_cnt, preemption_bits;
+ uint32_t reg_addr;
+
+ sunxi_plat_irq_init();
+ reg_addr = ic->reg_base_addr + CLIC_INFO_REG_OFF;
+ reg_data = readl(reg_addr);
+
+ irq_cnt = (reg_data & IRQ_CNT_MASK) >> IRQ_CNT_SHIFT;
+ printk_trace("CLIC: irq_cnt:%d ic->irq_cnt:%d\n", irq_cnt, ic->irq_cnt);
+ if (ic->irq_cnt != irq_cnt)
+ return -1;
+ preemption_bits = (reg_data & CTRL_REG_BITS_MASK) >> CTRL_REG_BITS_SHIFT;
+ preemption_bits <<= PREEMPTION_PRIORITY_BITS_SHIFT;
+ preemption_bits &= PREEMPTION_PRIORITY_BITS_MASK;
+ reg_addr = ic->reg_base_addr + CLIC_CFG_REG_OFF;
+
+ writel(preemption_bits, reg_addr);
+ for (i = 0; i < irq_cnt; i++) {
+ //disable all interrupt
+ reg_addr = ic->reg_base_addr + CLIC_INT_X_IE_REG_OFF(i);
+ sunxi_clic_set_enable(reg_addr, 0);
+ reg_addr = ic->reg_base_addr + CLIC_INT_X_ATTR_REG_OFF(i);
+ sunxi_clic_set_vec_mode(reg_addr, 0);
+ //clear pending
+ reg_addr = ic->reg_base_addr + CLIC_INT_X_IP_REG_OFF(i);
+ sunxi_clic_set_pending(reg_addr, 1);
+ }
+ reg_addr = ic->reg_base_addr + CLIC_INT_X_IE_REG_OFF(i);
+ printk_trace("CLIC: addr 0x%x(0x%x)set_enable 0\n", reg_addr, readb(reg_addr));
+ reg_addr = ic->reg_base_addr + CLIC_INT_X_ATTR_REG_OFF(i);
+ printk_trace("CLIC: addr 0x%x(0x%x) set_vec 1\n", reg_addr, readb(reg_addr));
+ reg_addr = ic->reg_base_addr + CLIC_INT_X_IP_REG_OFF(i);
+ printk_trace("CLIC: addr 0x%x(0x%x) clear pending 1\n", reg_addr, readb(reg_addr));
+ return 0;
+}
+
+static int sunxi_clic_irq_enable(const struct irq_controller *ic, uint32_t irq_id) {
+ uint32_t reg_addr;
+ reg_addr = ic->reg_base_addr + CLIC_INT_X_IE_REG_OFF(irq_id);
+ sunxi_clic_set_enable(reg_addr, 1);
+ return 0;
+}
+
+static int sunxi_clic_irq_disable(const struct irq_controller *ic, uint32_t irq_id) {
+ uint32_t reg_addr;
+ reg_addr = ic->reg_base_addr + CLIC_INT_X_IE_REG_OFF(irq_id);
+ sunxi_clic_set_enable(reg_addr, 0);
+ return 0;
+}
+
+static int sunxi_clic_irq_is_enabled(const struct irq_controller *ic, uint32_t irq_id) {
+ if (readb((ic->reg_base_addr + CLIC_INT_X_IE_REG_OFF(irq_id))) & IE_BIT_MASK)
+ return 1;
+ return 0;
+}
+
+static int sunxi_clic_irq_is_pending(const struct irq_controller *ic, uint32_t irq_id) {
+ if (readb((ic->reg_base_addr + CLIC_INT_X_IP_REG_OFF(irq_id))) & IP_BIT_MASK)
+ return 1;
+ return 0;
+}
+
+static int sunxi_clic_irq_set_pending(const struct irq_controller *ic, uint32_t irq_id,
+ int pending) {
+ uint32_t reg_addr;
+ reg_addr = ic->reg_base_addr + CLIC_INT_X_IP_REG_OFF(irq_id);
+ sunxi_clic_set_pending(reg_addr, pending);
+ return 0;
+}
+
+static int sunxi_clic_irq_set_trigger_type(const struct irq_controller *ic, uint32_t irq_id, irq_trigger_type_t type) {
+ uint32_t reg_addr;
+ if (type == IRQ_TRIGGER_TYPE_EDGE_BOTH)
+ return -1;
+ reg_addr = ic->reg_base_addr + CLIC_INT_X_ATTR_REG_OFF(irq_id);
+ sunxi_clic_set_trigger_type(reg_addr, type);
+ return 0;
+}
+
+static void default_isr(void *data) {
+ printk_debug("default_isr(): called from IRQ %d\n", (uint32_t) data);
+ while (1)
+ ;
+}
+
+static void sunxi_clic_spi_handler(int irq_no) {
+ if (sunxi_int_handlers[irq_no].func != default_isr) {
+ sunxi_int_handlers[irq_no].func(
+ sunxi_int_handlers[irq_no].data);
+ }
+}
+
+void irq_free_handler(int irq) {
+ if (irq >= CLIC_IRQ_NUM) {
+ return;
+ }
+ sunxi_int_handlers[irq].data = NULL;
+ sunxi_int_handlers[irq].func = default_isr;
+}
+
+int irq_enable(int irq_no) {
+ if (irq_no >= CLIC_IRQ_NUM) {
+ printf("CLIC: irq NO.(%d) > CLIC_IRQ_NUM(%d)\n", irq_no, CLIC_IRQ_NUM);
+ return -1;
+ }
+ sunxi_clic_irq_enable(&sunxi_clic_controller, irq_no);
+ return 0;
+}
+
+int irq_disable(int irq_no) {
+ if (irq_no >= CLIC_IRQ_NUM) {
+ printf("CLIC: irq NO.(%d) > CLIC_IRQ_NUM(%d) !!\n", irq_no, CLIC_IRQ_NUM);
+ return -1;
+ }
+ sunxi_clic_irq_disable(&sunxi_clic_controller, irq_no);
+ return 0;
+}
+
+void irq_install_handler(int irq, interrupt_handler_t handle_irq, void *data) {
+ if (irq >= CLIC_IRQ_NUM || !handle_irq) {
+ return;
+ }
+ sunxi_int_handlers[irq].data = data;
+ sunxi_int_handlers[irq].func = handle_irq;
+}
+
+void do_irq() {
+ uint32_t idnum = 0;
+ uint32_t rv_mcause = 0;
+
+ asm volatile("csrr %0, mcause"
+ : "=r"(rv_mcause));
+ printk_trace("CLIC: rv_mcause:0x%x riscv_mode:0x%lx\n", rv_mcause, riscv_mode);
+ csr_clear(mie, MIE_MSIE);
+
+ do {
+ idnum = (rv_mcause & 0xFFF);
+ if (idnum != 0) {
+ sunxi_clic_spi_handler(idnum);
+ irq_enable(idnum);
+ return;
+ }
+ } while (idnum != 0);
+
+ csr_set(mie, MIE_MSIE);
+ return;
+}
+
+int arch_interrupt_init(void) {
+ sunxi_clic_init(&sunxi_clic_controller);
+ csr_set(mstatus, MSTATUS_MIE);
+ csr_set(mie, MIE_MEIE);
+ return 0;
+}
+
+int arch_interrupt_exit(void) {
+ csr_clear(mstatus, MSTATUS_MIE);
+ csr_clear(mie, MIE_MEIE);
+ /* reinit to clear pending */
+ sunxi_clic_init(&sunxi_clic_controller);
+ return 0;
+}
\ No newline at end of file
diff --git a/src/drivers/intc/sys-gic.c b/src/drivers/intc/sys-gic.c
index e3004572..2e4205c7 100644
--- a/src/drivers/intc/sys-gic.c
+++ b/src/drivers/intc/sys-gic.c
@@ -133,6 +133,7 @@ static void default_isr(void *data) {
while (1)
;
}
+
static void gic_sgi_handler(uint32_t irq_no) {
printk_debug("GIC: SGI irq %d coming... \n", irq_no);
}
@@ -185,7 +186,7 @@ int sunxi_gic_cpu_interface_exit(void) {
void do_irq(struct arm_regs_t *regs) {
uint32_t idnum = readl(GIC_INT_ACK_REG);
-
+
if ((idnum == 1022) || (idnum == 1023)) {
printk_error("GIC: spurious irq !!\n");
return;