Skip to content

Commit 836d140

Browse files
committed
sw: update PLIC HAL to use new autogen interface
Signed-off-by: Alice Ziuziakowska <a.ziuziakowska@lowrisc.org>
1 parent 04c050f commit 836d140

6 files changed

Lines changed: 135 additions & 104 deletions

File tree

sw/device/lib/hal/mocha.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ timer_t mocha_system_timer(void)
117117
plic_t mocha_system_plic(void)
118118
{
119119
#if defined(__riscv_zcherihybrid)
120-
return (plic_t)create_mmio_capability(plic_base, 0x4004004u);
120+
return (plic_t)create_mmio_capability(plic_base, sizeof(struct plic_memory_layout));
121121
#else /* !defined(__riscv_zcherihybrid) */
122122
return (plic_t)plic_base;
123123
#endif /* defined(__riscv_zcherihybrid) */

sw/device/lib/hal/mocha.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,12 @@
2323

2424
static const uintptr_t dram_base = 0x80000000ul;
2525

26-
// In order of memory map.
26+
enum mocha_system_irq : uint32_t {
27+
mocha_system_irq_spi_device = (1u << 7),
28+
mocha_system_irq_uart = (1u << 8),
29+
};
30+
31+
/* In order of memory map. */
2732
mailbox_t mocha_system_mailbox(void);
2833
gpio_t mocha_system_gpio(void);
2934
clkmgr_t mocha_system_clkmgr(void);

sw/device/lib/hal/plic.c

Lines changed: 88 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -5,115 +5,159 @@
55
#include "hal/plic.h"
66
#include "hal/mmio.h"
77
#include <stdbool.h>
8+
#include <stddef.h>
89
#include <stdint.h>
910

10-
uint8_t plic_interrupt_priority_get(plic_t plic, uint8_t intr_id)
11+
#define array_len(arr) (sizeof(arr) / sizeof((arr)[0]))
12+
13+
void plic_init(plic_t plic)
14+
{
15+
plic_machine_interrupt_disable_all(plic);
16+
plic_supervisor_interrupt_disable_all(plic);
17+
}
18+
19+
uint8_t plic_interrupt_priority_get(plic_t plic, uint32_t intr)
1120
{
12-
if (intr_id >= PLIC_NUM_SRC) {
13-
return 0;
21+
if (intr == 0u) {
22+
return 0u;
1423
}
15-
return (DEV_READ(plic + PLIC_PRIO_REG + 4 * intr_id) & PLIC_PRIO_MASK);
24+
25+
size_t id = __builtin_ctz(intr);
26+
plic_prio prio = VOLATILE_READ(plic->prio[id]);
27+
return prio.prio;
1628
}
1729

18-
void plic_interrupt_priority_set(plic_t plic, uint8_t intr_id, uint8_t prio)
30+
void plic_interrupt_priority_set(plic_t plic, uint32_t intrs, uint8_t priority)
1931
{
20-
if (intr_id < PLIC_NUM_SRC) {
21-
DEV_WRITE(plic + PLIC_PRIO_REG + 4 * intr_id, prio & PLIC_PRIO_MASK);
32+
if (intrs == 0u) {
33+
return;
2234
}
35+
36+
uint32_t remain = intrs;
37+
do {
38+
size_t id = __builtin_ctz(remain);
39+
remain &= ~(1u << id);
40+
plic_prio prio = { .prio = priority };
41+
VOLATILE_WRITE(plic->prio[id], prio);
42+
} while (remain != 0u);
43+
}
44+
45+
uint32_t plic_machine_interrupt_enable_get(plic_t plic)
46+
{
47+
return VOLATILE_READ(plic->ie0);
2348
}
2449

25-
bool plic_interrupt_is_pending(plic_t plic, uint8_t intr_id)
50+
uint32_t plic_supervisor_interrupt_enable_get(plic_t plic)
2651
{
27-
return ((DEV_READ(plic + PLIC_IP_REG) & (1 << intr_id)) != 0);
52+
return VOLATILE_READ(plic->ie1);
2853
}
2954

30-
bool plic_machine_interrupt_enable_get(plic_t plic, uint8_t intr_id)
55+
void plic_machine_interrupt_enable_set(plic_t plic, uint32_t intrs)
3156
{
32-
return ((DEV_READ(plic + PLIC_IE0_REG) & (1 << intr_id)) != 0);
57+
VOLATILE_WRITE(plic->ie0, intrs);
3358
}
3459

35-
bool plic_supervisor_interrupt_enable_get(plic_t plic, uint8_t intr_id)
60+
void plic_supervisor_interrupt_enable_set(plic_t plic, uint32_t intrs)
3661
{
37-
return ((DEV_READ(plic + PLIC_IE1_REG) & (1 << intr_id)) != 0);
62+
VOLATILE_WRITE(plic->ie1, intrs);
3863
}
3964

40-
void plic_machine_interrupt_enable(plic_t plic, uint8_t intr_id)
65+
void plic_machine_interrupt_enable(plic_t plic, uint32_t intrs)
4166
{
42-
DEV_WRITE(plic + PLIC_IE0_REG, DEV_READ(plic + PLIC_IE0_REG) | (1 << intr_id));
67+
uint32_t ie0 = VOLATILE_READ(plic->ie0);
68+
VOLATILE_WRITE(plic->ie0, ie0 |= intrs);
4369
}
4470

45-
void plic_supervisor_interrupt_enable(plic_t plic, uint8_t intr_id)
71+
void plic_supervisor_interrupt_enable(plic_t plic, uint32_t intrs)
4672
{
47-
DEV_WRITE(plic + PLIC_IE1_REG, DEV_READ(plic + PLIC_IE1_REG) | (1 << intr_id));
73+
uint32_t ie1 = VOLATILE_READ(plic->ie1);
74+
VOLATILE_WRITE(plic->ie1, ie1 |= intrs);
4875
}
4976

50-
void plic_machine_interrupt_disable(plic_t plic, uint8_t intr_id)
77+
void plic_machine_interrupt_disable(plic_t plic, uint32_t intrs)
5178
{
52-
DEV_WRITE(plic + PLIC_IE0_REG, DEV_READ(plic + PLIC_IE0_REG) & ~(1 << intr_id));
79+
uint32_t ie0 = VOLATILE_READ(plic->ie0);
80+
VOLATILE_WRITE(plic->ie0, ie0 & ~intrs);
5381
}
5482

55-
void plic_supervisor_interrupt_disable(plic_t plic, uint8_t intr_id)
83+
void plic_supervisor_interrupt_disable(plic_t plic, uint32_t intrs)
5684
{
57-
DEV_WRITE(plic + PLIC_IE1_REG, DEV_READ(plic + PLIC_IE1_REG) & ~(1 << intr_id));
85+
uint32_t ie1 = VOLATILE_READ(plic->ie1);
86+
VOLATILE_WRITE(plic->ie1, ie1 & ~intrs);
5887
}
5988

6089
void plic_machine_interrupt_disable_all(plic_t plic)
6190
{
62-
DEV_WRITE(plic + PLIC_IE0_REG, 0);
91+
VOLATILE_WRITE(plic->ie0, 0u);
6392
}
6493

6594
void plic_supervisor_interrupt_disable_all(plic_t plic)
6695
{
67-
DEV_WRITE(plic + PLIC_IE1_REG, 0);
96+
VOLATILE_WRITE(plic->ie1, 0u);
6897
}
6998

70-
uint8_t plic_machine_priority_threshold_get(plic_t plic)
99+
bool plic_interrupt_all_pending(plic_t plic, uint32_t intrs)
71100
{
72-
return (DEV_READ(plic + PLIC_THRESHOLD0_REG) & PLIC_PRIO_MASK);
101+
return (VOLATILE_READ(plic->ip) & intrs) == intrs;
73102
}
74103

75-
uint8_t plic_supervisor_priority_threshold_get(plic_t plic)
104+
bool plic_interrupt_any_pending(plic_t plic, uint32_t intrs)
76105
{
77-
return (DEV_READ(plic + PLIC_THRESHOLD1_REG) & PLIC_PRIO_MASK);
106+
return (VOLATILE_READ(plic->ip) & intrs) != 0u;
78107
}
79108

80-
void plic_machine_priority_threshold_set(plic_t plic, uint8_t prio)
109+
uint8_t plic_machine_priority_threshold_get(plic_t plic)
81110
{
82-
DEV_WRITE(plic + PLIC_THRESHOLD0_REG, prio & PLIC_PRIO_MASK);
111+
plic_threshold0 threshold = VOLATILE_READ(plic->threshold0);
112+
return threshold.threshold0;
83113
}
84114

85-
void plic_supervisor_priority_threshold_set(plic_t plic, uint8_t prio)
115+
uint8_t plic_supervisor_priority_threshold_get(plic_t plic)
86116
{
87-
DEV_WRITE(plic + PLIC_THRESHOLD1_REG, prio & PLIC_PRIO_MASK);
117+
plic_threshold1 threshold = VOLATILE_READ(plic->threshold1);
118+
return threshold.threshold1;
88119
}
89120

90-
uint8_t plic_machine_interrupt_claim(plic_t plic)
121+
void plic_machine_priority_threshold_set(plic_t plic, uint8_t prio)
91122
{
92-
return (uint8_t)DEV_READ(plic + PLIC_CC0_REG);
123+
plic_threshold0 threshold = { .threshold0 = prio };
124+
VOLATILE_WRITE(plic->threshold0, threshold);
93125
}
94126

95-
uint8_t plic_supervisor_interrupt_claim(plic_t plic)
127+
void plic_supervisor_priority_threshold_set(plic_t plic, uint8_t prio)
96128
{
97-
return (uint8_t)DEV_READ(plic + PLIC_CC1_REG);
129+
plic_threshold1 threshold = { .threshold1 = prio };
130+
VOLATILE_WRITE(plic->threshold1, threshold);
98131
}
99132

100-
void plic_machine_interrupt_complete(plic_t plic, uint8_t intr_id)
133+
uint32_t plic_machine_interrupt_claim(plic_t plic)
101134
{
102-
DEV_WRITE(plic + PLIC_CC0_REG, (uint32_t)intr_id);
135+
plic_cc0 claim = VOLATILE_READ(plic->cc0);
136+
return (1u << claim.cc0);
103137
}
104138

105-
void plic_supervisor_interrupt_complete(plic_t plic, uint8_t intr_id)
139+
uint32_t plic_supervisor_interrupt_claim(plic_t plic)
106140
{
107-
DEV_WRITE(plic + PLIC_CC1_REG, (uint32_t)intr_id);
141+
plic_cc1 claim = VOLATILE_READ(plic->cc1);
142+
return (1u << claim.cc1);
108143
}
109144

110-
void plic_alert_trigger(plic_t plic)
145+
void plic_machine_interrupt_complete(plic_t plic, uint32_t intr)
111146
{
112-
DEV_WRITE(plic + PLIC_ALERT_TEST_REG, 1);
147+
if (intr == 0u) {
148+
return;
149+
}
150+
size_t id = __builtin_ctz(intr);
151+
plic_cc0 complete = { .cc0 = id };
152+
VOLATILE_WRITE(plic->cc0, complete);
113153
}
114154

115-
void plic_init(plic_t plic)
155+
void plic_supervisor_interrupt_complete(plic_t plic, uint32_t intr)
116156
{
117-
plic_machine_interrupt_disable_all(plic);
118-
plic_supervisor_interrupt_disable_all(plic);
157+
if (intr == 0u) {
158+
return;
159+
}
160+
size_t id = __builtin_ctz(intr);
161+
plic_cc1 complete = { .cc1 = id };
162+
VOLATILE_WRITE(plic->cc1, complete);
119163
}

sw/device/lib/hal/plic.h

Lines changed: 19 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,46 +4,32 @@
44

55
#pragma once
66

7+
#include "autogen/plic.h"
78
#include <stdbool.h>
89
#include <stdint.h>
910

10-
#define PLIC_PRIO_REG (0x0)
11-
#define PLIC_PRIO_MASK (0x3)
12-
13-
#define PLIC_IP_REG (0x1000)
14-
#define PLIC_IE0_REG (0x2000)
15-
#define PLIC_IE1_REG (0x2100)
16-
#define PLIC_THRESHOLD0_REG (0x200000)
17-
#define PLIC_THRESHOLD1_REG (0x201000)
18-
#define PLIC_CC0_REG (0x200004)
19-
#define PLIC_CC1_REG (0x201004)
20-
#define PLIC_MSIP0_REG (0x4000000)
21-
#define PLIC_MSIP1_REG (0x4000004)
22-
#define PLIC_ALERT_TEST_REG (0x4004000)
23-
24-
#define PLIC_NUM_SRC (32)
25-
26-
typedef void *plic_t;
11+
/* initialistation */
12+
void plic_init(plic_t plic);
2713

28-
uint8_t plic_interrupt_priority_get(plic_t plic, uint8_t intr_id);
29-
void plic_interrupt_priority_set(plic_t plic, uint8_t intr_id, uint8_t prio);
30-
bool plic_interrupt_is_pending(plic_t plic, uint8_t intr_id);
31-
bool plic_machine_interrupt_enable_get(plic_t plic, uint8_t intr_id);
32-
bool plic_supervisor_interrupt_enable_get(plic_t plic, uint8_t intr_id);
33-
void plic_machine_interrupt_enable(plic_t plic, uint8_t intr_id);
34-
void plic_supervisor_interrupt_enable(plic_t plic, uint8_t intr_id);
35-
void plic_machine_interrupt_disable(plic_t plic, uint8_t intr_id);
36-
void plic_supervisor_interrupt_disable(plic_t plic, uint8_t intr_id);
14+
uint8_t plic_interrupt_priority_get(plic_t plic, uint32_t intr);
15+
void plic_interrupt_priority_set(plic_t plic, uint32_t intrs, uint8_t prio);
16+
uint32_t plic_machine_interrupt_enable_get(plic_t plic);
17+
uint32_t plic_supervisor_interrupt_enable_get(plic_t plic);
18+
void plic_machine_interrupt_enable_set(plic_t plic, uint32_t intrs);
19+
void plic_supervisor_interrupt_enable_set(plic_t plic, uint32_t intrs);
20+
void plic_machine_interrupt_enable(plic_t plic, uint32_t intrs);
21+
void plic_supervisor_interrupt_enable(plic_t plic, uint32_t intrs);
22+
void plic_machine_interrupt_disable(plic_t plic, uint32_t intrs);
23+
void plic_supervisor_interrupt_disable(plic_t plic, uint32_t intrs);
3724
void plic_machine_interrupt_disable_all(plic_t plic);
3825
void plic_supervisor_interrupt_disable_all(plic_t plic);
26+
bool plic_interrupt_all_pending(plic_t plic, uint32_t intrs);
27+
bool plic_interrupt_any_pending(plic_t plic, uint32_t intrs);
3928
uint8_t plic_machine_priority_threshold_get(plic_t plic);
4029
uint8_t plic_supervisor_priority_threshold_get(plic_t plic);
4130
void plic_machine_priority_threshold_set(plic_t plic, uint8_t prio);
4231
void plic_supervisor_priority_threshold_set(plic_t plic, uint8_t prio);
43-
uint8_t plic_machine_interrupt_claim(plic_t plic);
44-
uint8_t plic_supervisor_interrupt_claim(plic_t plic);
45-
void plic_machine_interrupt_complete(plic_t plic, uint8_t intr_id);
46-
void plic_supervisor_interrupt_complete(plic_t plic, uint8_t intr_id);
47-
void plic_alert_trigger(plic_t plic);
48-
49-
void plic_init(plic_t plic);
32+
uint32_t plic_machine_interrupt_claim(plic_t plic);
33+
uint32_t plic_supervisor_interrupt_claim(plic_t plic);
34+
void plic_machine_interrupt_complete(plic_t plic, uint32_t intr);
35+
void plic_supervisor_interrupt_complete(plic_t plic, uint32_t intr);

sw/device/tests/plic/smoketest.c

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -20,27 +20,27 @@ bool reg_test(plic_t plic)
2020
plic_init(plic);
2121

2222
plic_interrupt_priority_set(plic, 4, 2);
23-
if ((plic_interrupt_priority_get(plic, 4) & PLIC_PRIO_MASK) != 2) {
23+
if ((plic_interrupt_priority_get(plic, 4) != 2)) {
2424
return false;
2525
}
2626

27-
plic_machine_interrupt_enable(plic, 22);
28-
if (!plic_machine_interrupt_enable_get(plic, 22)) {
27+
plic_machine_interrupt_enable(plic, 1 << 22);
28+
if (!(plic_machine_interrupt_enable_get(plic) & (1 << 22))) {
2929
return false;
3030
}
3131

32-
plic_machine_interrupt_disable(plic, 22);
33-
if (plic_machine_interrupt_enable_get(plic, 22)) {
32+
plic_machine_interrupt_disable(plic, 1 << 22);
33+
if (plic_machine_interrupt_enable_get(plic) & (1 << 22)) {
3434
return false;
3535
}
3636

37-
plic_supervisor_interrupt_enable(plic, 13);
38-
if (!plic_supervisor_interrupt_enable_get(plic, 13)) {
37+
plic_supervisor_interrupt_enable(plic, 1 << 13);
38+
if (!(plic_supervisor_interrupt_enable_get(plic) & (1 << 13))) {
3939
return false;
4040
}
4141

42-
plic_supervisor_interrupt_disable(plic, 13);
43-
if (plic_supervisor_interrupt_enable_get(plic, 13)) {
42+
plic_supervisor_interrupt_disable(plic, 1 << 13);
43+
if (plic_supervisor_interrupt_enable_get(plic) & (1 << 13)) {
4444
return false;
4545
}
4646

@@ -49,20 +49,19 @@ bool reg_test(plic_t plic)
4949

5050
bool uart_machine_irq_test(plic_t plic, uart_t uart)
5151
{
52-
uint8_t intr_id;
52+
uint32_t intr_id;
5353

5454
const int MIP_RD_RETRY_COUNT = 20;
55-
const int UART_INTR_ID = 8;
5655
const uint64_t MEIP_MASK = (1 << 11);
5756

5857
plic_init(plic);
59-
plic_interrupt_priority_set(plic, UART_INTR_ID, 3);
58+
plic_interrupt_priority_set(plic, mocha_system_irq_uart, 3);
6059
plic_machine_priority_threshold_set(plic, 0);
6160

6261
uart_interrupt_disable_all(uart);
6362
uart_interrupt_enable(uart, UART_INTR_RX_FRAME_ERR);
6463

65-
plic_machine_interrupt_enable(plic, UART_INTR_ID);
64+
plic_machine_interrupt_enable(plic, mocha_system_irq_uart);
6665

6766
// Check that mip MEIP is clear
6867
if ((csr_mip_get() & MEIP_MASK) != 0) {
@@ -94,20 +93,19 @@ bool uart_machine_irq_test(plic_t plic, uart_t uart)
9493

9594
bool uart_supervisor_irq_test(plic_t plic, uart_t uart)
9695
{
97-
uint8_t intr_id;
96+
uint32_t intr_id;
9897

9998
const int MIP_RD_RETRY_COUNT = 20;
100-
const int UART_INTR_ID = 8;
10199
const uint64_t SEIP_MASK = (1 << 9);
102100

103101
plic_init(plic);
104-
plic_interrupt_priority_set(plic, UART_INTR_ID, 3);
102+
plic_interrupt_priority_set(plic, mocha_system_irq_uart, 3);
105103
plic_supervisor_priority_threshold_set(plic, 0);
106104

107105
uart_interrupt_disable_all(uart);
108106
uart_interrupt_enable(uart, UART_INTR_RX_TIMEOUT);
109107

110-
plic_supervisor_interrupt_enable(plic, UART_INTR_ID);
108+
plic_supervisor_interrupt_enable(plic, mocha_system_irq_uart);
111109

112110
// Check that mip SEIP is clear
113111
if ((csr_mip_get() & SEIP_MASK) != 0) {

0 commit comments

Comments
 (0)