Skip to content

Commit 80da0b7

Browse files
committed
Add hello world example based on code from minispartan6-audio.
1 parent 2f8031c commit 80da0b7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+2912
-0
lines changed

src_c/arch/riscv/assert.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
2+
extern void _exit(int rc);
3+
4+
//-----------------------------------------------------------------
5+
// assert_handler:
6+
//-----------------------------------------------------------------
7+
void assert_handler(const char * type, const char *reason, const char *file, int line)
8+
{
9+
printf("%s: %s (%s:%d)\n", type, reason, file, line);
10+
_exit(-1);
11+
}

src_c/arch/riscv/assert.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
#ifndef __ASSERT_H__
2+
#define __ASSERT_H__
3+
4+
extern void assert_handler(const char * type, const char *reason, const char *file, int line);
5+
6+
#define assert(exp) do { if (!(exp)) assert_handler("ASSERT", #exp, __FILE__, __LINE__ ); } while (0)
7+
#define panic(reason) do { assert_handler("PANIC", #reason, __FILE__, __LINE__ ); } while (0)
8+
9+
#endif
10+

src_c/arch/riscv/boot.S

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
2+
.global init
3+
.global main
4+
.global irq_handler
5+
6+
#####################################################
7+
# Entry point
8+
#####################################################
9+
.org 0x0
10+
boot_vector:
11+
j start
12+
13+
#####################################################
14+
# IPC Vector
15+
#####################################################
16+
.org 0x8
17+
ipc_vector:
18+
.zero
19+
20+
#####################################################
21+
# ISR Vector
22+
#####################################################
23+
.org 0x10
24+
j int_vector
25+
26+
#####################################################
27+
# Arg handling
28+
#####################################################
29+
.org 0x20
30+
arg_argc:
31+
.space 4, 0
32+
arg_argv:
33+
.space 256, 0
34+
35+
#####################################################
36+
# Actual ISR vector
37+
#####################################################
38+
int_vector:
39+
#include "exception_asm.h"
40+
41+
#####################################################
42+
# Start
43+
#####################################################
44+
start:
45+
# Setup stack pointer
46+
lui sp, %hi(_sp)
47+
add sp, sp, %lo(_sp)
48+
49+
# Setup IRQ vector
50+
lui t0, %hi(isr_vector)
51+
add t0, t0, %lo(isr_vector)
52+
csrw mtvec, t0
53+
54+
# t0 = _bss_start
55+
lui t0,%hi(_bss_start)
56+
add t0,t0,%lo(_bss_start)
57+
58+
# t1 = _end
59+
lui t1,%hi(_end)
60+
add t1,t1,%lo(_end)
61+
62+
bss_clear:
63+
#ifndef SKIP_BSS_INIT
64+
sw x0, (0)(t0) # Write 0x00 to mem[t0]
65+
add t0, t0, 4 # t0 += 4
66+
blt t0, t1, bss_clear # Branch back to bss_clear if (t0 < t1)
67+
#endif
68+
69+
# Jump to init
70+
jal init
71+
72+
# Run main
73+
# a0 = argc
74+
la a0, arg_argc
75+
lw a0, 0(a0)
76+
# a1 = argv
77+
la a1, arg_argv
78+
jal main
79+
80+
# Exit
81+
jal _exit
82+
83+
#####################################################
84+
# Exit
85+
#####################################################
86+
.global _exit
87+
_exit:
88+
csrw dscratch, x0
89+
_exit_loop:
90+
jal _exit_loop

src_c/arch/riscv/csr.h

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
#ifndef __CSR_H__
2+
#define __CSR_H__
3+
4+
#include <stdint.h>
5+
6+
//-----------------------------------------------------------------
7+
// Defines:
8+
//-----------------------------------------------------------------
9+
#define SR_SIE (1 << 1)
10+
#define SR_MIE (1 << 3)
11+
#define SR_SPIE (1 << 5)
12+
#define SR_MPIE (1 << 7)
13+
14+
#define IRQ_S_SOFT 1
15+
#define IRQ_M_SOFT 3
16+
#define IRQ_S_TIMER 5
17+
#define IRQ_M_TIMER 7
18+
#define IRQ_S_EXT 9
19+
#define IRQ_M_EXT 11
20+
21+
#define SR_IP_MSIP (1 << IRQ_M_SOFT)
22+
#define SR_IP_MTIP (1 << IRQ_M_TIMER)
23+
#define SR_IP_MEIP (1 << IRQ_M_EXT)
24+
#define SR_IP_SSIP (1 << IRQ_S_SOFT)
25+
#define SR_IP_STIP (1 << IRQ_S_TIMER)
26+
#define SR_IP_SEIP (1 << IRQ_S_EXT)
27+
28+
//-----------------------------------------------------------------
29+
// Helpers:
30+
//-----------------------------------------------------------------
31+
#define csr_read(reg) ({ unsigned long __tmp; \
32+
asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
33+
__tmp; })
34+
35+
#define csr_write(reg, val) ({ \
36+
asm volatile ("csrw " #reg ", %0" :: "rK"(val)); })
37+
38+
#define csr_set(reg, bit) ({ unsigned long __tmp; \
39+
asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "rK"(bit)); \
40+
__tmp; })
41+
42+
#define csr_clear(reg, bit) ({ unsigned long __tmp; \
43+
asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "rK"(bit)); \
44+
__tmp; })
45+
46+
#define csr_swap(reg, val) ({ \
47+
unsigned long __v = (unsigned long)(val); \
48+
asm volatile ("csrrw %0, " #reg ", %1" : "=r" (__v) : "rK" (__v) : "memory"); \
49+
__v; })
50+
51+
//-----------------------------------------------------------------
52+
// csr_set_isr_vector: Set exception vector
53+
//-----------------------------------------------------------------
54+
static inline void csr_set_isr_vector(uint32_t addr)
55+
{
56+
asm volatile ("csrw mtvec, %0": : "r" (addr));
57+
}
58+
//-----------------------------------------------------------------
59+
// csr_get_time: Get current time (MTIME)
60+
//-----------------------------------------------------------------
61+
static inline uint32_t csr_get_time(void)
62+
{
63+
uint32_t value;
64+
asm volatile ("csrr %0, time" : "=r" (value) : );
65+
return value;
66+
}
67+
//-----------------------------------------------------------------
68+
// csr_set_time_compare: Set value to generate timer IRQ at
69+
//-----------------------------------------------------------------
70+
static inline void csr_set_time_compare(uint32_t value)
71+
{
72+
// Value 0 is ignored...
73+
if (value == 0) value = 1;
74+
asm volatile ("csrw time, %0": : "r" (value));
75+
}
76+
//-----------------------------------------------------------------
77+
// csr_set_irq_mask: Enable particular interrupts
78+
//-----------------------------------------------------------------
79+
static inline void csr_set_irq_mask(uint32_t mask)
80+
{
81+
asm volatile ("csrs mie,%0": : "r" (mask));
82+
}
83+
//-----------------------------------------------------------------
84+
// csr_clr_irq_mask: Disable particular interrupts
85+
//-----------------------------------------------------------------
86+
static inline void csr_clr_irq_mask(uint32_t mask)
87+
{
88+
asm volatile ("csrc mie,%0": : "r" (mask));
89+
}
90+
//-----------------------------------------------------------------
91+
// csr_get_irq_pending: Bitmap of pending IRQs
92+
//-----------------------------------------------------------------
93+
static inline uint32_t csr_get_irq_pending(void)
94+
{
95+
uint32_t value;
96+
asm volatile ("csrr %0, mip" : "=r" (value) : );
97+
return value;
98+
}
99+
//-----------------------------------------------------------------
100+
// csr_set_irq_pending: Set pending interrupts (SW IRQ)
101+
//-----------------------------------------------------------------
102+
static inline void csr_set_irq_pending(uint32_t mask)
103+
{
104+
asm volatile ("csrs mip,%0": : "r" (mask));
105+
}
106+
//-----------------------------------------------------------------
107+
// csr_irq_ack: Clear pending interrupts
108+
//-----------------------------------------------------------------
109+
static inline void csr_irq_ack(uint32_t mask)
110+
{
111+
asm volatile ("csrc mip,%0": : "r" (mask));
112+
}
113+
//-----------------------------------------------------------------
114+
// csr_set_irq_enable: Global IRQ enable
115+
//-----------------------------------------------------------------
116+
static inline void csr_set_irq_enable(void)
117+
{
118+
uint32_t mask = SR_MIE;
119+
asm volatile ("csrs mstatus,%0": : "r" (mask));
120+
}
121+
//-----------------------------------------------------------------
122+
// csr_clr_irq_enable: Gloabl IRQ disable
123+
//-----------------------------------------------------------------
124+
static inline void csr_clr_irq_enable(void)
125+
{
126+
uint32_t mask = SR_MIE;
127+
asm volatile ("csrc mstatus,%0": : "r" (mask));
128+
}
129+
//-----------------------------------------------------------------
130+
// csr_get_irq_enable: Get current IRQ enable state
131+
//-----------------------------------------------------------------
132+
static inline int csr_get_irq_enable(void)
133+
{
134+
uint32_t value;
135+
uint32_t mask = SR_MIE;
136+
asm volatile ("csrr %0, mstatus" : "=r" (value) : );
137+
return (value & mask) != 0;
138+
}
139+
140+
#endif

src_c/arch/riscv/exception.c

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
#include "exception.h"
2+
#include "assert.h"
3+
#include "csr.h"
4+
5+
//-----------------------------------------------------------------
6+
// Defines:
7+
//-----------------------------------------------------------------
8+
#define SR_MPP_SHIFT 11
9+
#define SR_MPP_MASK 0x3
10+
#define SR_MPP (SR_MPP_MASK << SR_MPP_SHIFT)
11+
#define SR_MPP_M (3 << SR_MPP_SHIFT)
12+
13+
//-----------------------------------------------------------------
14+
// Locals
15+
//-----------------------------------------------------------------
16+
#define CAUSE_MAX_EXC (CAUSE_PAGE_FAULT_STORE + 1)
17+
static fp_exception _exception_table[CAUSE_MAX_EXC];
18+
19+
static fp_irq _irq_handler = 0;
20+
21+
void exception_set_irq_handler(fp_irq handler) { _irq_handler = handler; }
22+
void exception_set_syscall_handler(fp_syscall handler)
23+
{
24+
_exception_table[CAUSE_ECALL_U] = handler;
25+
_exception_table[CAUSE_ECALL_S] = handler;
26+
_exception_table[CAUSE_ECALL_M] = handler;
27+
}
28+
void exception_set_handler(int cause, fp_exception handler)
29+
{
30+
_exception_table[cause] = handler;
31+
}
32+
//-----------------------------------------------------------------
33+
// exception_handler:
34+
//-----------------------------------------------------------------
35+
struct irq_context * exception_handler(struct irq_context *ctx)
36+
{
37+
#ifndef EXCEPTION_SP_FROM_MSCRATCH
38+
// Fix-up MPP so that we stay in machine mode
39+
ctx->status &= ~SR_MPP;
40+
ctx->status |= SR_MPP_M;
41+
#endif
42+
43+
// External interrupt
44+
if (ctx->cause & CAUSE_INTERRUPT)
45+
{
46+
if (_irq_handler)
47+
ctx = _irq_handler(ctx);
48+
else
49+
printf("Unhandled IRQ!\n");
50+
}
51+
// Exception
52+
else
53+
{
54+
switch (ctx->cause)
55+
{
56+
case CAUSE_ECALL_U:
57+
case CAUSE_ECALL_S:
58+
case CAUSE_ECALL_M:
59+
ctx->pc += 4;
60+
break;
61+
}
62+
63+
if (ctx->cause < CAUSE_MAX_EXC && _exception_table[ctx->cause])
64+
ctx = _exception_table[ctx->cause](ctx);
65+
else
66+
{
67+
printf("Unhandled exception: PC 0x%08x Cause %d!\n", ctx->pc, ctx->cause);
68+
assert(!"Unhandled exception");
69+
}
70+
}
71+
72+
return ctx;
73+
}

src_c/arch/riscv/exception.h

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#ifndef __EXCEPTION_H__
2+
#define __EXCEPTION_H__
3+
4+
#include <stdint.h>
5+
#include "csr.h"
6+
7+
//-----------------------------------------------------------------
8+
// Defines:
9+
//-----------------------------------------------------------------
10+
#define REG_RA 1
11+
#define REG_SP 2
12+
#define REG_ARG0 10
13+
#define REG_RET REG_ARG0
14+
#define NUM_GP_REG 32
15+
#define NUM_CSR_REG 3
16+
17+
#define CAUSE_MISALIGNED_FETCH 0
18+
#define CAUSE_FAULT_FETCH 1
19+
#define CAUSE_ILLEGAL_INSTRUCTION 2
20+
#define CAUSE_BREAKPOINT 3
21+
#define CAUSE_MISALIGNED_LOAD 4
22+
#define CAUSE_FAULT_LOAD 5
23+
#define CAUSE_MISALIGNED_STORE 6
24+
#define CAUSE_FAULT_STORE 7
25+
#define CAUSE_ECALL_U 8
26+
#define CAUSE_ECALL_S 9
27+
#define CAUSE_ECALL_M 11
28+
#define CAUSE_PAGE_FAULT_INST 12
29+
#define CAUSE_PAGE_FAULT_LOAD 13
30+
#define CAUSE_PAGE_FAULT_STORE 15
31+
#define CAUSE_INTERRUPT (1 << 31)
32+
33+
//-----------------------------------------------------------------
34+
// Types:
35+
//-----------------------------------------------------------------
36+
struct irq_context
37+
{
38+
uint32_t pc;
39+
uint32_t status;
40+
uint32_t cause;
41+
uint32_t reg[NUM_GP_REG];
42+
};
43+
44+
typedef struct irq_context *(*fp_exception)(struct irq_context *ctx);
45+
typedef struct irq_context *(*fp_irq)(struct irq_context *ctx);
46+
typedef struct irq_context *(*fp_syscall)(struct irq_context *ctx);
47+
48+
//-----------------------------------------------------------------
49+
// context_irq_enable: Set future interrupt enable
50+
//-----------------------------------------------------------------
51+
static void context_irq_enable(struct irq_context *ctx, int enable)
52+
{
53+
// MPIE becomes MIE on return from exception
54+
ctx->status &= ~SR_MPIE;
55+
ctx->status |= (enable ? SR_MPIE : 0);
56+
}
57+
58+
//-----------------------------------------------------------------
59+
// Prototypes:
60+
//-----------------------------------------------------------------
61+
struct irq_context * exception_handler(struct irq_context *ctx);
62+
void exception_set_irq_handler(fp_irq irq_handler);
63+
void exception_set_syscall_handler(fp_syscall syscall_handler);
64+
void exception_set_handler(int cause, fp_exception handler);
65+
66+
#endif
67+

0 commit comments

Comments
 (0)