Skip to content

Commit c57cdd1

Browse files
committed
Add sw support for PLIC
1 parent d4a6baf commit c57cdd1

File tree

6 files changed

+104
-8
lines changed

6 files changed

+104
-8
lines changed

sw/c/common/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
add_library(common OBJECT demo_system.c uart.c timer.c gpio.c pwm.c spi.c crt0.S)
1+
add_library(common OBJECT demo_system.c uart.c timer.c gpio.c pwm.c spi.c plic.c crt0.S)
22
target_include_directories(common INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}")

sw/c/common/demo_system.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,23 @@
2626

2727
#define DEFAULT_SPI SPI_FROM_BASE_ADDR(SPI0_BASE)
2828

29+
// Add PLIC definitions
30+
#define PLIC_BASE 0x80005000
31+
32+
// PLIC Register offsets
33+
#define PLIC_PRIORITY_BASE 0x000000
34+
#define PLIC_PENDING_BASE 0x001000
35+
#define PLIC_ENABLE_BASE 0x002000
36+
#define PLIC_THRESHOLD_BASE 0x200000
37+
#define PLIC_CLAIM_BASE 0x200004
38+
39+
// PLIC configuration
40+
#define PLIC_MAX_PRIORITY 7
41+
#define PLIC_PRIORITY_MASK 0x7
42+
43+
// Source IDs
44+
#define PLIC_SOURCE_UART0 0
45+
2946
/**
3047
* Writes character to default UART. Signature matches c stdlib function
3148
* of the same name.

sw/c/common/plic.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#include "plic.h"
2+
#include "demo_system.h"
3+
#include "dev_access.h"
4+
5+
void plic_init(void) {
6+
// Enable machine external interrupts
7+
enable_interrupts(1 << 11); // Set mie.meie bit
8+
9+
// Set threshold to 0 (allow all priorities)
10+
plic_set_threshold(0);
11+
}
12+
13+
void plic_set_priority(uint32_t source, uint32_t priority) {
14+
uint32_t addr = PLIC_BASE + PLIC_PRIORITY_BASE + (source * 4);
15+
DEV_WRITE(addr, priority & PLIC_PRIORITY_MASK);
16+
}
17+
18+
void plic_enable_interrupt(uint32_t source) {
19+
uint32_t addr = PLIC_BASE + PLIC_ENABLE_BASE;
20+
uint32_t current = DEV_READ(addr);
21+
DEV_WRITE(addr, current | (1 << source));
22+
}
23+
24+
void plic_disable_interrupt(uint32_t source) {
25+
uint32_t addr = PLIC_BASE + PLIC_ENABLE_BASE;
26+
uint32_t current = DEV_READ(addr);
27+
DEV_WRITE(addr, current & ~(1 << source));
28+
}
29+
30+
void plic_set_threshold(uint32_t threshold) {
31+
DEV_WRITE(PLIC_BASE + PLIC_THRESHOLD_BASE, threshold & PLIC_PRIORITY_MASK);
32+
}
33+
34+
uint32_t plic_claim_interrupt(void) {
35+
return DEV_READ(PLIC_BASE + PLIC_CLAIM_BASE);
36+
}
37+
38+
void plic_complete_interrupt(uint32_t source) {
39+
DEV_WRITE(PLIC_BASE + PLIC_CLAIM_BASE, source);
40+
}

sw/c/common/plic.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#ifndef PLIC_H__
2+
#define PLIC_H__
3+
4+
#include <stdint.h>
5+
6+
// Initialize PLIC
7+
void plic_init(void);
8+
9+
// Set priority for an interrupt source
10+
void plic_set_priority(uint32_t source, uint32_t priority);
11+
12+
// Enable/disable interrupt source
13+
void plic_enable_interrupt(uint32_t source);
14+
void plic_disable_interrupt(uint32_t source);
15+
16+
// Set priority threshold
17+
void plic_set_threshold(uint32_t threshold);
18+
19+
// Claim and complete interrupts
20+
uint32_t plic_claim_interrupt(void);
21+
void plic_complete_interrupt(uint32_t source);
22+
23+
#endif // PLIC_H__

sw/c/common/uart.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,16 @@
66

77
#include "demo_system.h"
88
#include "dev_access.h"
9+
#include "plic.h"
910

1011
void uart_enable_rx_int(void) {
11-
enable_interrupts(UART_IRQ);
12+
// Set UART interrupt priority (e.g., priority 2)
13+
plic_set_priority(PLIC_SOURCE_UART0, 2);
14+
15+
// Enable UART interrupt in PLIC
16+
plic_enable_interrupt(PLIC_SOURCE_UART0);
17+
18+
// Enable global interrupts
1219
set_global_interrupt_enable(1);
1320
}
1421

sw/c/demo/hello_world/main.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,31 @@
88
#include "gpio.h"
99
#include "pwm.h"
1010
#include "timer.h"
11+
#include "plic.h"
1112

1213
#define USE_GPIO_SHIFT_REG 0
1314

1415
void test_uart_irq_handler(void) __attribute__((interrupt));
1516

1617
void test_uart_irq_handler(void) {
17-
int uart_in_char;
18-
19-
while ((uart_in_char = uart_in(DEFAULT_UART)) != -1) {
20-
uart_out(DEFAULT_UART, uart_in_char);
21-
uart_out(DEFAULT_UART, '\r');
22-
uart_out(DEFAULT_UART, '\n');
18+
uint32_t source = plic_claim_interrupt();
19+
20+
if (source == PLIC_SOURCE_UART0) {
21+
int uart_in_char;
22+
while ((uart_in_char = uart_in(DEFAULT_UART)) != -1) {
23+
uart_out(DEFAULT_UART, uart_in_char);
24+
uart_out(DEFAULT_UART, '\r');
25+
uart_out(DEFAULT_UART, '\n');
26+
}
27+
plic_complete_interrupt(source);
2328
}
2429
}
2530

2631
int main(void) {
32+
// Initialize PLIC
33+
plic_init();
34+
35+
// Install exception handlers
2736
install_exception_handler(UART_IRQ_NUM, &test_uart_irq_handler);
2837
uart_enable_rx_int();
2938

0 commit comments

Comments
 (0)