Skip to content

Commit 1fbb422

Browse files
committed
Trivial bootstrap for Linux kernel for test SoC
1 parent ea8b9a0 commit 1fbb422

12 files changed

+701
-0
lines changed

boot.S

+142
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
#####################################################
2+
# Entry point
3+
#####################################################
4+
.org 0x0
5+
boot_vector:
6+
j start
7+
8+
#####################################################
9+
# ISR Vector
10+
#####################################################
11+
.org 0x20
12+
.global isr_vector
13+
isr_vector:
14+
csrrw sp, mscratch, sp
15+
addi sp, sp, -(35*4)
16+
17+
# Save registers
18+
sw x31, (4*34)(sp)
19+
sw x30, (4*33)(sp)
20+
sw x29, (4*32)(sp)
21+
sw x28, (4*31)(sp)
22+
sw x27, (4*30)(sp)
23+
sw x26, (4*29)(sp)
24+
sw x25, (4*28)(sp)
25+
sw x24, (4*27)(sp)
26+
sw x23, (4*26)(sp)
27+
sw x22, (4*25)(sp)
28+
sw x21, (4*24)(sp)
29+
sw x20, (4*23)(sp)
30+
sw x19, (4*22)(sp)
31+
sw x18, (4*21)(sp)
32+
sw x17, (4*20)(sp)
33+
sw x16, (4*19)(sp)
34+
sw x15, (4*18)(sp)
35+
sw x14, (4*17)(sp)
36+
sw x13, (4*16)(sp)
37+
sw x12, (4*15)(sp)
38+
sw x11, (4*14)(sp)
39+
sw x10, (4*13)(sp)
40+
sw x9, (4*12)(sp)
41+
sw x8, (4*11)(sp)
42+
sw x7, (4*10)(sp)
43+
sw x6, (4* 9)(sp)
44+
sw x5, (4* 8)(sp)
45+
sw x4, (4* 7)(sp)
46+
sw x3, (4* 6)(sp)
47+
sw x2, (4* 5)(sp) # SP
48+
sw x1, (4* 4)(sp) # RA
49+
50+
csrr s0, mcause
51+
sw s0, (4* 2)(sp)
52+
53+
csrr s0, mstatus
54+
sw s0, (4* 1)(sp)
55+
56+
csrr s0, mepc
57+
sw s0, (4* 0)(sp)
58+
59+
# Call ISR handler
60+
mv a0, sp
61+
jal exception_handler
62+
mv sp, a0
63+
64+
# Restore registers
65+
lw s0, (4* 0)(sp)
66+
csrw mepc, s0
67+
68+
lw s0, (4* 1)(sp)
69+
csrw mstatus, s0
70+
71+
lw x1, (4* 4)(sp)
72+
lw x3, (4* 6)(sp)
73+
lw x4, (4* 7)(sp)
74+
lw x5, (4* 8)(sp)
75+
lw x6, (4* 9)(sp)
76+
lw x7, (4*10)(sp)
77+
lw x8, (4*11)(sp)
78+
lw x9, (4*12)(sp)
79+
lw x10, (4*13)(sp)
80+
lw x11, (4*14)(sp)
81+
lw x12, (4*15)(sp)
82+
lw x13, (4*16)(sp)
83+
lw x14, (4*17)(sp)
84+
lw x15, (4*18)(sp)
85+
lw x16, (4*19)(sp)
86+
lw x17, (4*20)(sp)
87+
lw x18, (4*21)(sp)
88+
lw x19, (4*22)(sp)
89+
lw x20, (4*23)(sp)
90+
lw x21, (4*24)(sp)
91+
lw x22, (4*25)(sp)
92+
lw x23, (4*26)(sp)
93+
lw x24, (4*27)(sp)
94+
lw x25, (4*28)(sp)
95+
lw x26, (4*29)(sp)
96+
lw x27, (4*30)(sp)
97+
lw x28, (4*31)(sp)
98+
lw x29, (4*32)(sp)
99+
lw x30, (4*33)(sp)
100+
lw x31, (4*34)(sp)
101+
102+
addi sp, sp, (35*4)
103+
csrrw sp, mscratch, sp
104+
mret
105+
106+
#####################################################
107+
# Start
108+
#####################################################
109+
start:
110+
# Setup stack pointer
111+
lui sp, %hi(_sp)
112+
add sp, sp, %lo(_sp)
113+
114+
# Setup IRQ vector
115+
lui t0, %hi(isr_vector)
116+
add t0, t0, %lo(isr_vector)
117+
csrw mtvec, t0
118+
119+
# t0 = _bss_start
120+
lui t0,%hi(_bss_start)
121+
add t0,t0,%lo(_bss_start)
122+
123+
# t1 = _end
124+
lui t1,%hi(_end)
125+
add t1,t1,%lo(_end)
126+
127+
bss_clear:
128+
sw x0, (0)(t0) # Write 0x00 to mem[t0]
129+
add t0, t0, 4 # t0 += 4
130+
blt t0, t1, bss_clear # Branch back to bss_clear if (t0 < t1)
131+
132+
# Run main
133+
jal main
134+
135+
#####################################################
136+
# Exit
137+
#####################################################
138+
.global _exit
139+
_exit:
140+
csrw dscratch, x0
141+
_exit_loop:
142+
jal _exit_loop

csr.h

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#ifndef __CSR_H__
2+
#define __CSR_H__
3+
4+
#include <stdint.h>
5+
6+
//-----------------------------------------------------------------
7+
// Defines:
8+
//-----------------------------------------------------------------
9+
#define MSTATUS_MPP_SHIFT 11
10+
#define PRV_S 1
11+
#define PRV_M 3
12+
13+
//-----------------------------------------------------------------
14+
// Helpers:
15+
//-----------------------------------------------------------------
16+
#define csr_read(reg) ({ unsigned long __tmp; \
17+
asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \
18+
__tmp; })
19+
20+
#define csr_write(reg, val) ({ \
21+
asm volatile ("csrw " #reg ", %0" :: "rK"(val)); })
22+
23+
#define csr_set(reg, bit) ({ unsigned long __tmp; \
24+
asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "rK"(bit)); \
25+
__tmp; })
26+
27+
#define csr_clear(reg, bit) ({ unsigned long __tmp; \
28+
asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "rK"(bit)); \
29+
__tmp; })
30+
31+
#endif

custom.ld

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
GROUP("libgcc.a")
2+
3+
MEMORY
4+
{
5+
sram (rwx) : ORIGIN = BASE_ADDRESS, LENGTH = 31M
6+
rom (r) : ORIGIN = BASE_ADDRESS + 0x1F00000, LENGTH = 1M
7+
}
8+
9+
SECTIONS
10+
{
11+
/* first section is .text which is used for code */
12+
.text :
13+
{
14+
*(.text .text.*) /* remaining code */
15+
*(.rodata) /* read-only data (constants) */
16+
*(.rodata*)
17+
*(.rdata*)
18+
. = ALIGN(4);
19+
} > sram
20+
21+
/* .data section which is used for initialized data */
22+
.data :
23+
{
24+
*(.got.plt) *(.got)
25+
*(.shdata)
26+
*(.data .data.* .gnu.linkonce.d.*)
27+
. = ALIGN(16);
28+
*(.lit8)
29+
*(.lit4)
30+
*(.sdata .sdata.* .gnu.linkonce.s.*)
31+
. = ALIGN (8);
32+
*(.ram)
33+
. = ALIGN (8);
34+
_edata = .;
35+
} > sram
36+
37+
.bss :
38+
{
39+
. = ALIGN(4);
40+
_bss_start = . ;
41+
42+
*(.bss*)
43+
*(.sbss*)
44+
*(COMMON)
45+
/* Allocate room for stack */
46+
. = ALIGN(8) ;
47+
. += 4096 ;
48+
_sp = . - 16;
49+
} > sram
50+
51+
. = ALIGN(4);
52+
_end = . ;
53+
54+
.payload :
55+
{
56+
*(.payload)
57+
}
58+
59+
.dtb :
60+
{
61+
*(.dtb)
62+
} > rom
63+
}

exception.c

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#include "exception.h"
2+
#include "csr.h"
3+
#include "serial.h"
4+
5+
//-----------------------------------------------------------------
6+
// Locals
7+
//-----------------------------------------------------------------
8+
#define CAUSE_MAX_EXC (CAUSE_PAGE_FAULT_STORE + 1)
9+
static fp_exception _exception_table[CAUSE_MAX_EXC];
10+
11+
//-----------------------------------------------------------------
12+
// exception_set_handler: Register exception handler
13+
//-----------------------------------------------------------------
14+
void exception_set_handler(int cause, fp_exception handler)
15+
{
16+
_exception_table[cause] = handler;
17+
}
18+
//-----------------------------------------------------------------
19+
// exception_handler:
20+
//-----------------------------------------------------------------
21+
struct irq_context * exception_handler(struct irq_context *ctx)
22+
{
23+
switch (ctx->cause)
24+
{
25+
case CAUSE_ECALL_U:
26+
case CAUSE_ECALL_S:
27+
case CAUSE_ECALL_M:
28+
ctx->pc += 4;
29+
break;
30+
}
31+
32+
if (ctx->cause < CAUSE_MAX_EXC && _exception_table[ctx->cause])
33+
ctx = _exception_table[ctx->cause](ctx);
34+
else
35+
{
36+
serial_putstr("Unhandled exception, stopping...\n");
37+
_exit(-1);
38+
}
39+
return ctx;
40+
}

exception.h

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
#ifndef __EXCEPTION_H__
2+
#define __EXCEPTION_H__
3+
4+
#include <stdint.h>
5+
6+
//-----------------------------------------------------------------
7+
// Defines:
8+
//-----------------------------------------------------------------
9+
#define REG_RA 1
10+
#define REG_SP 2
11+
#define REG_ARG0 10
12+
#define REG_RET REG_ARG0
13+
#define NUM_GP_REG 32
14+
#define NUM_CSR_REG 3
15+
16+
#define CAUSE_MISALIGNED_FETCH 0
17+
#define CAUSE_FAULT_FETCH 1
18+
#define CAUSE_ILLEGAL_INSTRUCTION 2
19+
#define CAUSE_BREAKPOINT 3
20+
#define CAUSE_MISALIGNED_LOAD 4
21+
#define CAUSE_FAULT_LOAD 5
22+
#define CAUSE_MISALIGNED_STORE 6
23+
#define CAUSE_FAULT_STORE 7
24+
#define CAUSE_ECALL_U 8
25+
#define CAUSE_ECALL_S 9
26+
#define CAUSE_ECALL_M 11
27+
#define CAUSE_PAGE_FAULT_INST 12
28+
#define CAUSE_PAGE_FAULT_LOAD 13
29+
#define CAUSE_PAGE_FAULT_STORE 15
30+
#define CAUSE_INTERRUPT (1 << 31)
31+
32+
//-----------------------------------------------------------------
33+
// Types:
34+
//-----------------------------------------------------------------
35+
struct irq_context
36+
{
37+
uint32_t pc;
38+
uint32_t status;
39+
uint32_t cause;
40+
uint32_t reg[NUM_GP_REG];
41+
};
42+
43+
typedef struct irq_context *(*fp_exception)(struct irq_context *ctx);
44+
45+
//-----------------------------------------------------------------
46+
// Prototypes:
47+
//-----------------------------------------------------------------
48+
struct irq_context * exception_handler(struct irq_context *ctx);
49+
void exception_set_handler(int cause, fp_exception handler);
50+
extern void _exit(int arg);
51+
52+
#endif
53+

main.c

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
#include <stdint.h>
2+
#include "csr.h"
3+
#include "exception.h"
4+
#include "syscalls.h"
5+
#include "serial.h"
6+
7+
//-----------------------------------------------------------------
8+
// Defines:
9+
//-----------------------------------------------------------------
10+
#define SERIAL_BASE 0x92000000
11+
12+
//-----------------------------------------------------------------
13+
// Globals:
14+
//-----------------------------------------------------------------
15+
extern uint32_t _payload_start;
16+
extern uint32_t _dtb_start;
17+
extern uint32_t _sp;
18+
19+
//-----------------------------------------------------------------
20+
// main:
21+
//-----------------------------------------------------------------
22+
int main(void)
23+
{
24+
uint32_t entry_addr = (uint32_t)&_payload_start;
25+
uint32_t dtb_addr = (uint32_t)&_dtb_start;
26+
27+
// Setup serial port
28+
serial_init(SERIAL_BASE, 0 /* NOT USED */);
29+
serial_putstr("Booting...\n");
30+
31+
// Register fault handlers
32+
exception_set_handler(CAUSE_ECALL_S, handle_syscall);
33+
34+
// Boot kernel
35+
csr_write(mstatus, PRV_S << MSTATUS_MPP_SHIFT);
36+
37+
// Configure interrupt / exception delegation
38+
// Delegate everything except super/machine level syscalls
39+
csr_write(medeleg, ~(1 << CAUSE_ECALL_S));
40+
csr_write(mideleg, ~0);
41+
42+
// Boot target
43+
csr_write(mepc, entry_addr);
44+
45+
// Set machine mode exception stack
46+
csr_write(mscratch, &_sp);
47+
48+
// Switch from machine mode to supervisor mode
49+
register uintptr_t a0 asm ("a0") = 0;
50+
register uintptr_t a1 asm ("a1") = dtb_addr;
51+
asm volatile ("mret" : : "r" (a0), "r" (a1));
52+
53+
return 0;
54+
}
55+

0 commit comments

Comments
 (0)