summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--interrupt/SConscript16
-rw-r--r--interrupt/clic.h33
-rw-r--r--interrupt/dispatch_clic.cpp25
-rw-r--r--interrupt/dispatch_plic.cpp8
-rw-r--r--interrupt/dispatch_riscv.cpp24
-rw-r--r--interrupt/plic.h25
-rw-r--r--interrupt/vectors_clic.cpp.j223
-rw-r--r--interrupt/vectors_generic.cpp.j214
-rw-r--r--platforms/gd32v.yaml88
-rw-r--r--platforms/index.yaml10
-rw-r--r--platforms/riscv.yaml38
11 files changed, 304 insertions, 0 deletions
diff --git a/interrupt/SConscript b/interrupt/SConscript
index 2380815..4544785 100644
--- a/interrupt/SConscript
+++ b/interrupt/SConscript
@@ -30,6 +30,22 @@ if 'nvic' in periph:
env.Jinja2('vectors_nvic.cpp', 'vectors_nvic.cpp.j2', interrupts = interrupts),
])
+if 'clic' in periph:
+ headers.append('clic.h')
+ for name, data in periph['clic'].items():
+ instances.append({
+ 'type': 'CLIC_t',
+ 'name': name,
+ 'args': [data['offset']],
+ })
+
+ aliases['interrupt_ctl'] = 'CLIC'
+
+ sources.extend([
+ File('dispatch_clic.cpp'),
+ env.Jinja2('vectors_clic.cpp', 'vectors_clic.cpp.j2', interrupts = interrupts),
+ ])
+
env.Jinja2('interrupt.h', '../templates/periph_instances.h.j2', headers = headers, instances = instances, aliases = aliases)
Return('sources')
diff --git a/interrupt/clic.h b/interrupt/clic.h
new file mode 100644
index 0000000..247aeec
--- /dev/null
+++ b/interrupt/clic.h
@@ -0,0 +1,33 @@
+#pragma once
+
+#include "interrupt_enums.h"
+
+#include <mmio/mmio.h>
+
+struct CLIC_int_reg_t {
+ volatile uint8_t IP;
+ volatile uint8_t IE;
+ volatile uint8_t ATTR;
+ volatile uint8_t CTL;
+};
+
+struct CLIC_reg_t {
+ volatile uint32_t CFG;
+ volatile uint32_t INFO;
+ uint32_t _reserved[14];
+ volatile uint32_t TRIG[32];
+ uint32_t _reserved2[976];
+ CLIC_int_reg_t INT[4096];
+};
+
+
+class CLIC_t : public mmio_ptr<CLIC_reg_t> {
+ public:
+ void enable(interrupt::irq n) const {
+ ptr()->INT[int(n)].IE = 1;
+ }
+
+ void enable(interrupt::internal n) const {
+ ptr()->INT[int(n)].IE = 1;
+ }
+};
diff --git a/interrupt/dispatch_clic.cpp b/interrupt/dispatch_clic.cpp
new file mode 100644
index 0000000..64e4bfc
--- /dev/null
+++ b/interrupt/dispatch_clic.cpp
@@ -0,0 +1,25 @@
+#include "interrupt.h"
+
+extern interrupt::vector_t vectors_exception[];
+extern interrupt::vector_t vectors_clic[];
+
+[[gnu::interrupt, gnu::aligned(64)]]
+void riscv_interrupt_handler() {
+ uint32_t cause;
+ asm("csrr %0, mcause" : "=r"(cause));
+
+ uint32_t type = cause & 0x80000000;
+ uint32_t code = cause & 0x00000fff;
+
+ if(type) {
+ vectors_clic[code]();
+ } else {
+ vectors_exception[code]();
+ }
+}
+
+[[gnu::constructor(200)]]
+void riscv_interrupt_init() {
+ asm volatile("csrw mtvec, %0" :: "r"(intptr_t(riscv_interrupt_handler) | 3));
+ asm volatile("csrrsi x0, mstatus, (1 << 3)");
+}
diff --git a/interrupt/dispatch_plic.cpp b/interrupt/dispatch_plic.cpp
new file mode 100644
index 0000000..081013d
--- /dev/null
+++ b/interrupt/dispatch_plic.cpp
@@ -0,0 +1,8 @@
+#include "interrupt.h"
+
+extern interrupt::vector_t vectors_irq[];
+
+template<>
+void interrupt::handler<interrupt::internal::MEI>() {
+ while(1) {}
+}
diff --git a/interrupt/dispatch_riscv.cpp b/interrupt/dispatch_riscv.cpp
new file mode 100644
index 0000000..a91e95a
--- /dev/null
+++ b/interrupt/dispatch_riscv.cpp
@@ -0,0 +1,24 @@
+#include "interrupt.h"
+
+extern interrupt::vector_t vectors_exception[];
+extern interrupt::vector_t vectors_internal[];
+
+[[gnu::interrupt]]
+void riscv_interrupt_handler() {
+ uint32_t cause;
+ asm("csrr %0, mcause" : "=r"(cause));
+
+ uint32_t type = cause & 0x80000000;
+ uint32_t code = cause & 0x7fffffff;
+
+ if(type) {
+ vectors_internal[code]();
+ } else {
+ vectors_exception[code]();
+ }
+}
+
+[[gnu::constructor(200)]]
+void riscv_interrupt_init() {
+ asm volatile("csrw mtvec, %0" :: "r"(riscv_interrupt_handler));
+}
diff --git a/interrupt/plic.h b/interrupt/plic.h
new file mode 100644
index 0000000..46ade92
--- /dev/null
+++ b/interrupt/plic.h
@@ -0,0 +1,25 @@
+#pragma once
+
+class PLIC_t {
+ private:
+ struct PLIC_ctx_reg_t {
+ volatile uint32_t THRESHOLD;
+ volatile uint32_t CLAIM;
+ uint32_t _reserved[1022];
+ };
+
+ struct PLIC_reg_t {
+ volatile uint32_t PRIO[1024];
+ volatile uint32_t PEND[32];
+ uint32_t _reserved[992];
+ volatile uint32_t ENABLE[15872][32];
+ uint32_t _reserved2[14336];
+ PLIC_ctx_reg_t CTX[15872];
+ };
+
+ public:
+ PLIC_reg_t& reg;
+
+ PLIC_t(uint32_t reg_addr) :
+ reg(*(PLIC_reg_t*)reg_addr) {}
+};
diff --git a/interrupt/vectors_clic.cpp.j2 b/interrupt/vectors_clic.cpp.j2
new file mode 100644
index 0000000..7f9dd9f
--- /dev/null
+++ b/interrupt/vectors_clic.cpp.j2
@@ -0,0 +1,23 @@
+#include "interrupt.h"
+
+interrupt::vector_t vectors_clic[] = {
+ {% for i in range(interrupts.irq | max + 1 if interrupts.irq else interrupts.internal | max + 1 if interrupts.internal else 0) %}
+ {% if i in interrupts.internal %}
+ interrupt::handler<interrupt::internal::{{ interrupts.internal[i] }}>,
+ {% elif i in interrupts.irq %}
+ interrupt::handler<interrupt::irq::{{ interrupts.irq[i] }}>,
+ {% else %}
+ 0,
+ {% endif %}
+ {% endfor %}
+};
+
+interrupt::vector_t vectors_exception[] = {
+ {% for i in range(interrupts.exception | max + 1 if interrupts.exception else 0) %}
+ {% if i in interrupts.exception %}
+ interrupt::handler<interrupt::exception::{{ interrupts.exception[i] }}>,
+ {% else %}
+ 0,
+ {% endif %}
+ {% endfor %}
+};
diff --git a/interrupt/vectors_generic.cpp.j2 b/interrupt/vectors_generic.cpp.j2
new file mode 100644
index 0000000..26ef05d
--- /dev/null
+++ b/interrupt/vectors_generic.cpp.j2
@@ -0,0 +1,14 @@
+#include "interrupt.h"
+
+{% for type, entries in interrupts.items() %}
+ interrupt::vector_t vectors_{{ type }}[] = {
+ {% for i in range(entries | max + 1 if entries else 0) %}
+ {% if i in entries %}
+ interrupt::handler<interrupt::{{ type }}::{{ entries[i] }}>,
+ {% else %}
+ 0,
+ {% endif %}
+ {% endfor %}
+ };
+
+{% endfor %}
diff --git a/platforms/gd32v.yaml b/platforms/gd32v.yaml
new file mode 100644
index 0000000..34b2bf8
--- /dev/null
+++ b/platforms/gd32v.yaml
@@ -0,0 +1,88 @@
+- match:
+ mcu: !re gd32vf103
+ mem:
+ flash:
+ origin: 0x08000000
+ size: 128k
+
+ ram:
+ origin: 0x20000000
+ size: 32k
+
+ periph:
+ clic:
+ CLIC:
+ offset: 0xd2000000
+
+ dwc_otg:
+ OTG_FS:
+ offset: 0x50000000
+
+ rcc:
+ RCC:
+ offset: 0x40021000
+ type: f1
+ bus:
+ AHB:
+ 0: DMA1
+ 1: DMA2
+ 2: SRAM
+ 4: FLITF
+ 6: CRC
+ 8: FSMC
+ 10: SDIO
+ 12: USBFS
+
+ APB1:
+ 0: TIM2
+ 1: TIM3
+ 2: TIM4
+ 3: TIM5
+ 4: TIM6
+ 5: TIM7
+ 6: TIM12
+ 7: TIM13
+ 8: TIM14
+ 11: WWDG
+ 14: SPI2
+ 15: SPI3
+ 17: USART2
+ 18: USART3
+ 19: UART4
+ 20: UART5
+ 21: I2C1
+ 22: I2C2
+ 25: CAN
+ 27: BKP
+ 28: PWR
+ 29: DAC
+
+ APB2:
+ 0: AFIO
+ 2: GPIOA
+ 3: GPIOB
+ 4: GPIOC
+ 5: GPIOD
+ 6: GPIOE
+ 7: GPIOF
+ 8: GPIOG
+ 9: ADC1
+ 10: ADC2
+ 11: TIM1
+ 12: SPI1
+ 13: TIM8
+ 14: USART1
+ 15: ADC3
+ 19: TIM9
+ 20: TIM10
+ 21: TIM11
+
+ interrupt:
+ irq:
+ 56: USART1
+
+ define:
+ - STM32F1
+
+ meta:
+ cpu: rv32imac \ No newline at end of file
diff --git a/platforms/index.yaml b/platforms/index.yaml
index 558b535..15a83e6 100644
--- a/platforms/index.yaml
+++ b/platforms/index.yaml
@@ -4,6 +4,16 @@
-: !import stm32/index.yaml
- match:
+ mcu: !re gd32v
+
+ -: !import gd32v.yaml
+
+- match:
cpu: !re cortex-m
-: !import cortex-m.yaml
+
+- match:
+ cpu: !re rv
+
+ -: !import riscv.yaml \ No newline at end of file
diff --git a/platforms/riscv.yaml b/platforms/riscv.yaml
new file mode 100644
index 0000000..ec9ecd7
--- /dev/null
+++ b/platforms/riscv.yaml
@@ -0,0 +1,38 @@
+- match:
+ cpu: rv32imac
+
+ cflags:
+ - -march=rv32imac
+ - -mabi=ilp32
+ - -msmall-data-limit=0
+
+ interrupt:
+ exception:
+ 0: InstructionMisaligned
+ 1: InstructionFault
+ 2: IllegalInstruction
+ 3: Breakpoint
+ 4: LoadMisaligned
+ 5: LoadFault
+ 6: StoreMisaligned
+ 7: StoreFault
+ 8: ECall_U
+ 9: ECall_S
+ 11: ECall_M
+ 12: InstructionPageFault
+ 13: LoadPageFault
+ 15: StorePageFault
+
+ internal:
+ 0: USI
+ 1: SSI
+ 3: MSI
+ 4: UTI
+ 5: STI
+ 7: MTI
+ 8: UEI
+ 9: SEI
+ 11: MEI
+
+ toolchains:
+ - riscv64-unknown-elf