Skip to content

Commit 4b022dd

Browse files
committed
Only clear uart interrupt when reading status register
1 parent 620e5d3 commit 4b022dd

File tree

2 files changed

+15
-17
lines changed

2 files changed

+15
-17
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ Read/write pointers are stored modulo `capacity + 1`. A buffer is empty when `rp
7676

7777
Note that the processor itself does not prevent code from overflowing the TX buffer. Users are expected to check the Status register and avoid writing too much data at once.
7878

79-
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. The interrupt for a given port is cleared when any register for that port is accessed.
79+
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. The interrupt for a given port is cleared when the Status register for that port is accessed.
8080

8181
Internally, UART interrupts are implemented using the `uart_flags` variable.
8282

src/cpu/worker.mlog.jinja

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -809,21 +809,6 @@ access_uart:
809809

810810
op add $$offset $$offset {{UART_RX_OFFSET}}
811811

812-
#% do free_locals("$$uart")
813-
# check if interrupt is pending for this port
814-
op shl $mask 1 $$uart_shift
815-
op and $mask uart_flags $mask
816-
jump access_uart__no_clear_ip equal $mask 0
817-
818-
# clear pending interrupt
819-
op not $mask $mask
820-
op and uart_flags uart_flags $mask
821-
822-
# set interrupt_flags.poll
823-
op or csr_mip csr_mip 0b10000000000000000000000000000000
824-
#% do declare_locals(access_uart_locals)
825-
access_uart__no_clear_ip:
826-
827812
op add $$uart $$uart_shift {{UART_START_LINK}}
828813
getlink $$uart $$uart
829814

@@ -1052,7 +1037,7 @@ load_mmio_word__not_zero:
10521037

10531038
load_mmio_word__uart_status:
10541039
#% do declare_locals(access_uart_locals)
1055-
#% do free_locals("$$offset")
1040+
#% do free_locals("$$offset", "$$uart")
10561041
# interrupt enabled
10571042
op shr result uart_flags $$uart_shift
10581043
op and result result 0b10000
@@ -1079,6 +1064,19 @@ load_mmio_word__uart_status__rx_empty:
10791064
op or result result 0b00010
10801065
load_mmio_word__uart_status__rx_not_full:
10811066

1067+
# check if interrupt is pending for this port
1068+
op shl $mask 1 $$uart_shift
1069+
op and $mask uart_flags $mask
1070+
jump load_mmio_word__uart_status__no_clear_interrupt equal $mask 0
1071+
1072+
# clear pending interrupt
1073+
op not $mask $mask
1074+
op and uart_flags uart_flags $mask
1075+
1076+
# set interrupt_flags.poll
1077+
op or csr_mip csr_mip 0b10000000000000000000000000000000
1078+
load_mmio_word__uart_status__no_clear_interrupt:
1079+
10821080
set @counter ret
10831081

10841082
# instruction decoder

0 commit comments

Comments
 (0)