Skip to content

Commit ea6c986

Browse files
committed
Implement UART interrupts
1 parent 6a7a9fa commit ea6c986

File tree

25 files changed

+688
-184
lines changed

25 files changed

+688
-184
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ logicids.json
2525

2626
.kotlin/
2727

28+
compile_commands.json
29+
2830
## Gradle
2931
.gradle
3032
**/build/

README.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,25 @@ Read/write pointers are stored modulo `capacity + 1`. A buffer is empty when `rp
8686

8787
Note that the processor itself does not set the TX overflow flag or prevent code from overflowing the TX buffer. Users are expected to check the Line Status Register and avoid writing too much data at once.
8888

89+
If any UART interrupt is pending, `mip.MEIP` will become pending. To make UART interrupts visible to S-mode, M-mode software must either delegate `mip.MEIP` via `mideleg`, or manually update `mip.SEIP` in an M-mode interrupt handler.
90+
91+
Internally, UART interrupts are implemented using the `uart_flags` variable.
92+
93+
| 31:24 | 23:16 | 15:8 | 7:0 |
94+
| ----- | ----- | ----- | ----- |
95+
| UART3 | UART2 | UART1 | UART0 |
96+
97+
| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
98+
| ----------- | ------------ | ------------ | ----------- | ----------- | ------------ | ------------ | ----------- |
99+
| MSI pending | RLSI pending | THRI pending | RDI pending | MSI enabled | RLSI enabled | THRI enabled | RDI enabled |
100+
101+
| Interrupt | Description |
102+
| --------- | ---------------------------------- |
103+
| MSI | Modem Status |
104+
| RLSI | Receiver Line Status |
105+
| THRI | Transmitter Holding Register Empty |
106+
| RDI | Receiver Data Ready |
107+
89108
### Syscon
90109

91110
Address `0xfffffff0` contains a simple memory-mapped peripheral which can be used to control the system by writing values from the following table. Unsupported values will have no effect if written. Reads will always return `0`.

linux/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
### objdump
66

77
```
8-
riscv32-unknown-linux-gnu-objdump --disassembler-color=on --visualize-jumps=color --start-address=0xc00109ac --stop-address=0xc0010a2c --disassemble --source --line-numbers --show-all-symbols --wide output/build/vmlinux
8+
riscv32-unknown-linux-gnu-objdump --disassembler-color=on --visualize-jumps=color --disassemble --source --line-numbers --show-all-symbols --wide output/build/vmlinux --start-address=0xc00109ac --stop-address=0xc0010a2c
9+
10+
riscv32-unknown-linux-gnu-objdump --disassembler-color=on --visualize-jumps=color --disassemble --source --line-numbers --show-all-symbols --wide output/build/vmlinux --disassemble=handle_irq_desc
911
```
1012

1113
### GDB

linux/buildroot/.clangd

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
CompileFlags:
2+
Remove: [-mno-riscv-attribute, -fzero-init-padding-bits=all, -fconserve-stack, -fno-allow-store-data-races, -mfunction-return=thunk-extern, -mindirect-branch-cs-prefix, -mindirect-branch-register, -mindirect-branch=thunk-extern, -mskip-rax-setup, -mpreferred-stack-boundary=3, -mno-fp-ret-in-387]
3+
Diagnostics:
4+
MissingIncludes: Strict

linux/buildroot/Config.in

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
source "$BR2_EXTERNAL_MLOGV32_PATH/package/mlogv32-drivers/Config.in"
572 Bytes
Binary file not shown.

linux/buildroot/board/mlogv32/dts/mlogv32.dts

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
// SBI: console=hvc
1111
// UART0: console=ttyS0
1212
// for debugging: kgdboc_earlycon=sbi kgdboc=ttyS0 kgdbwait
13-
bootargs = "earlycon=sbi console=hvc";
13+
bootargs = "earlycon=sbi console=ttyS0";
1414
stdout-path = &uart0;
1515
};
1616

@@ -57,7 +57,7 @@
5757
"sstc",
5858
"svade";
5959

60-
intc: interrupt-controller {
60+
cpu0_intc: interrupt-controller {
6161
compatible = "riscv,cpu-intc";
6262
#interrupt-cells = <1>;
6363
interrupt-controller;
@@ -67,7 +67,14 @@
6767

6868
timer {
6969
compatible = "riscv,timer";
70-
interrupts-extended = <&intc 5>;
70+
interrupts-extended = <&cpu0_intc 5>;
71+
};
72+
73+
intc: interrupt-controller {
74+
compatible = "mlogv32,cpu-intc";
75+
#interrupt-cells = <1>;
76+
interrupt-controller;
77+
interrupts-extended = <&cpu0_intc 11>;
7178
};
7279

7380
soc {
@@ -80,13 +87,43 @@
8087
compatible = "ns16550a";
8188
reg = <0xf0000010 0x20>;
8289
reg-shift = <2>;
83-
interrupts-extended = <&intc 9>;
90+
interrupts-extended = <&intc 11>;
8491
clock-frequency = <(38400*16)>;
8592
fifo-size = <253>;
8693
no-loopback-test;
8794
// TODO: https://github.com/torvalds/linux/blob/8c2e52ebbe885c7eeaabd3b7ddcdc1246fc400d2/drivers/tty/serial/8250/8250_of.c#L233
8895
};
8996

97+
uart1: serial@f0000030 {
98+
compatible = "ns16550a";
99+
reg = <0xf0000030 0x20>;
100+
reg-shift = <2>;
101+
interrupts-extended = <&intc 11>;
102+
clock-frequency = <(38400*16)>;
103+
fifo-size = <253>;
104+
no-loopback-test;
105+
};
106+
107+
uart2: serial@f0000050 {
108+
compatible = "ns16550a";
109+
reg = <0xf0000050 0x20>;
110+
reg-shift = <2>;
111+
interrupts-extended = <&intc 11>;
112+
clock-frequency = <(38400*16)>;
113+
fifo-size = <253>;
114+
no-loopback-test;
115+
};
116+
117+
uart3: serial@f0000070 {
118+
compatible = "ns16550a";
119+
reg = <0xf0000070 0x20>;
120+
reg-shift = <2>;
121+
interrupts-extended = <&intc 11>;
122+
clock-frequency = <(38400*16)>;
123+
fifo-size = <253>;
124+
no-loopback-test;
125+
};
126+
90127
syscon: syscon@fffffff0 {
91128
compatible = "syscon";
92129
reg = <0xfffffff0 0x4>;

linux/buildroot/board/mlogv32/linux.config

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,8 @@ CONFIG_SERIAL_8250=y
3838
# CONFIG_SERIAL_8250_DEPRECATED_OPTIONS is not set
3939
# CONFIG_SERIAL_8250_16550A_VARIANTS is not set
4040
CONFIG_SERIAL_8250_CONSOLE=y
41+
CONFIG_SERIAL_8250_EXTENDED=y
42+
CONFIG_SERIAL_8250_SHARE_IRQ=y
4143
CONFIG_SERIAL_OF_PLATFORM=y
4244
CONFIG_SERIAL_EARLYCON_RISCV_SBI=y
4345
CONFIG_HVC_RISCV_SBI=y

linux/buildroot/configs/mlogv32_defconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ BR2_ROOTFS_MERGED_USR=y
1919
BR2_LINUX_KERNEL=y
2020
BR2_LINUX_KERNEL_USE_CUSTOM_CONFIG=y
2121
BR2_LINUX_KERNEL_CUSTOM_CONFIG_FILE="$(BR2_EXTERNAL_MLOGV32_PATH)/board/mlogv32/linux.config"
22+
BR2_LINUX_KERNEL_EXT_MLOGV32_DRIVERS=y
2223
BR2_PACKAGE_READLINE=y
2324
BR2_TARGET_ROOTFS_CRAMFS=y
2425
BR2_TARGET_ROOTFS_CRAMFS_XIP=y

linux/buildroot/external.mk

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,16 @@
1+
include $(sort $(wildcard $(BR2_EXTERNAL_MLOGV32_PATH)/package/*/*.mk))
2+
13
.PHONY: save-configs
24
save-configs: linux-update-defconfig
35
$(MAKE) savedefconfig BR2_DEFCONFIG=$(BR2_EXTERNAL_MLOGV32_PATH)/configs/mlogv32_defconfig
46

57
.PHONY: dtbs
68
dtbs: $(BR2_EXTERNAL_MLOGV32_PATH)/board/mlogv32/dts/mlogv32.dtb
79

10+
.PHONY: gen-compile-commands
11+
gen-compile-commands:
12+
cd $(LINUX_DIR) && scripts/clang-tools/gen_compile_commands.py -o $(BR2_EXTERNAL_MLOGV32_PATH)/compile_commands.json
13+
814
.PHONY: zsbl
915
zsbl:
1016
riscv32-unknown-elf-gcc \

0 commit comments

Comments
 (0)