Compare commits
3 commits
7a3c98f2b4
...
a1b9321a74
Author | SHA1 | Date | |
---|---|---|---|
|
a1b9321a74 | ||
|
ad34ff9b86 | ||
|
be6678c0e6 |
8 changed files with 124 additions and 43 deletions
|
@ -1,21 +1,65 @@
|
|||
# For a quick reference on RISC-V assembly:
|
||||
# https://risc-v.guru/instructions/
|
||||
|
||||
# Kernel entry point
|
||||
#
|
||||
# qemu -kernel loads the kernel at 0x80000000
|
||||
# and causes each hart (i.e. CPU) to jump there.
|
||||
# kernel.ld causes the following code to
|
||||
# be placed at 0x80000000.
|
||||
|
||||
.section .text
|
||||
.global _entry
|
||||
_entry:
|
||||
# Clear all the registers.
|
||||
li x1, 0x0
|
||||
li x2, 0x0
|
||||
li x3, 0x0
|
||||
li x4, 0x0
|
||||
li x5, 0x0
|
||||
li x6, 0x0
|
||||
li x7, 0x0
|
||||
li x8, 0x0
|
||||
li x9, 0x0
|
||||
li x10, 0x0
|
||||
li x11, 0x0
|
||||
li x12, 0x0
|
||||
li x13, 0x0
|
||||
li x14, 0x0
|
||||
li x15, 0x0
|
||||
li x16, 0x0
|
||||
li x17, 0x0
|
||||
li x18, 0x0
|
||||
li x19, 0x0
|
||||
li x20, 0x0
|
||||
li x21, 0x0
|
||||
li x22, 0x0
|
||||
li x23, 0x0
|
||||
li x24, 0x0
|
||||
li x25, 0x0
|
||||
li x26, 0x0
|
||||
li x27, 0x0
|
||||
li x28, 0x0
|
||||
li x29, 0x0
|
||||
li x30, 0x0
|
||||
li x31, 0x0
|
||||
|
||||
# set up a stack for C.
|
||||
# stack0 is declared in start.c,
|
||||
# with a 4096-byte stack per CPU.
|
||||
# sp = stack0 + (hartid * 4096)
|
||||
la sp, stack0
|
||||
li a0, 1024*4
|
||||
csrr a1, mhartid
|
||||
addi a1, a1, 1
|
||||
mul a0, a0, a1
|
||||
add sp, sp, a0
|
||||
li a0, 1024*4 # a0 = 4096
|
||||
|
||||
# Control and Status Register Read
|
||||
csrr a1, mhartid # a1 = unique hart (core) id
|
||||
addi a1, a1, 1 # a1 += 1
|
||||
mul a0, a0, a1 # a0 *= a1, aka a0 = 4096 * (hartid + 1), the base of the stack for this hart
|
||||
add sp, sp, a0 # sp += a0, stack pointer is now properly configured
|
||||
|
||||
# jump to start() in start.c
|
||||
call start
|
||||
|
||||
# Infinite spin loop.
|
||||
spin:
|
||||
j spin
|
||||
|
|
|
@ -9,6 +9,11 @@ SECTIONS
|
|||
*/
|
||||
. = 0x80000000;
|
||||
|
||||
/*
|
||||
* This section contains the code. This is, the machine language instructions
|
||||
* that will be executed by the processor. In here we will find symbols
|
||||
* that reference the functions in your object file.
|
||||
*/
|
||||
.text : {
|
||||
*(.text .text.*)
|
||||
. = ALIGN(0x1000);
|
||||
|
@ -19,6 +24,10 @@ SECTIONS
|
|||
PROVIDE(etext = .);
|
||||
}
|
||||
|
||||
/*
|
||||
* This contains any data that is marked as read only.
|
||||
* It is not unusual to find this data interleaved with the text section.
|
||||
*/
|
||||
.rodata : {
|
||||
. = ALIGN(16);
|
||||
*(.srodata .srodata.*) /* do not need to distinguish this from .rodata */
|
||||
|
@ -26,6 +35,10 @@ SECTIONS
|
|||
*(.rodata .rodata.*)
|
||||
}
|
||||
|
||||
/*
|
||||
* This section contains initialized global and static variables.
|
||||
* Any global object that has been explicitly initialized to a value different than zero.
|
||||
*/
|
||||
.data : {
|
||||
. = ALIGN(16);
|
||||
*(.sdata .sdata.*) /* do not need to distinguish this from .data */
|
||||
|
@ -33,6 +46,12 @@ SECTIONS
|
|||
*(.data .data.*)
|
||||
}
|
||||
|
||||
/*
|
||||
* Contains all uninitialized global and static var iables. These are usually
|
||||
* zeroed out by the startup code before we reach the main function. However,
|
||||
* In an embedded system we usually provide our own startup code, which means
|
||||
* we need to remember to do this ourselves.
|
||||
*/
|
||||
.bss : {
|
||||
. = ALIGN(16);
|
||||
*(.sbss .sbss.*) /* do not need to distinguish this from .bss */
|
||||
|
@ -40,5 +59,6 @@ SECTIONS
|
|||
*(.bss .bss.*)
|
||||
}
|
||||
|
||||
/* PROVIDE, see vm.c */
|
||||
PROVIDE(end = .);
|
||||
}
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
# For a quick reference on RISC-V assembly:
|
||||
# https://risc-v.guru/instructions/
|
||||
|
||||
# Kernel trap handling
|
||||
#
|
||||
# interrupts and exceptions while in supervisor
|
||||
# mode come here.
|
||||
|
@ -5,7 +9,7 @@
|
|||
# the current stack is a kernel stack.
|
||||
# push all registers, call kerneltrap().
|
||||
# when kerneltrap() returns, restore registers, return.
|
||||
#
|
||||
|
||||
.globl kerneltrap
|
||||
.globl kernelvec
|
||||
.align 4
|
||||
|
@ -53,7 +57,8 @@ kernelvec:
|
|||
ld ra, 0(sp)
|
||||
ld sp, 8(sp)
|
||||
ld gp, 16(sp)
|
||||
# not tp (contains hartid), in case we moved CPUs
|
||||
# Skip tp (thread pointer aka x4) (contains hartid)
|
||||
# in case we moved CPUs
|
||||
ld t0, 32(sp)
|
||||
ld t1, 40(sp)
|
||||
ld t2, 48(sp)
|
||||
|
@ -87,9 +92,11 @@ kernelvec:
|
|||
# return to whatever we were doing in the kernel.
|
||||
sret
|
||||
|
||||
# machine-mode timer interrupt
|
||||
#
|
||||
# machine-mode timer interrupt.
|
||||
#
|
||||
# See: start.c for timervec declaration
|
||||
# extern void timervec();
|
||||
|
||||
.globl timervec
|
||||
.align 4
|
||||
timervec:
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
#include "param.h"
|
||||
#include "memlayout.h"
|
||||
#include "riscv.h"
|
||||
#include "defs.h"
|
||||
|
||||
void main();
|
||||
void timerinit();
|
||||
|
|
|
@ -1,12 +1,18 @@
|
|||
# For a quick reference on RISC-V assembly:
|
||||
# https://risc-v.guru/instructions/
|
||||
|
||||
# Context switch
|
||||
#
|
||||
# void swtch(struct context *old, struct context *new);
|
||||
#
|
||||
# Save current registers in old. Load from new.
|
||||
|
||||
#
|
||||
# See: defs.h for swtch declaration
|
||||
# See: proc.h for struct context definition
|
||||
#
|
||||
# void swtch(struct context *old, struct context *new);
|
||||
|
||||
.globl swtch
|
||||
swtch:
|
||||
# sd = Store Double (64 bits)
|
||||
sd ra, 0(a0)
|
||||
sd sp, 8(a0)
|
||||
sd s0, 16(a0)
|
||||
|
@ -22,6 +28,7 @@ swtch:
|
|||
sd s10, 96(a0)
|
||||
sd s11, 104(a0)
|
||||
|
||||
# ld = Load Double (64 bits)
|
||||
ld ra, 0(a1)
|
||||
ld sp, 8(a1)
|
||||
ld s0, 16(a1)
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
# For a quick reference on RISC-V assembly:
|
||||
# https://risc-v.guru/instructions/
|
||||
|
||||
# Trampoline code
|
||||
#
|
||||
# low-level code to handle traps from user space into
|
||||
# the kernel, and returns from kernel to user.
|
||||
|
@ -8,7 +12,6 @@
|
|||
# to work when it switches page tables.
|
||||
# kernel.ld causes this code to start at
|
||||
# a page boundary.
|
||||
#
|
||||
|
||||
#include "riscv.h"
|
||||
#include "memlayout.h"
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
# For a quick reference on RISC-V assembly:
|
||||
# https://risc-v.guru/instructions/
|
||||
|
||||
# Initial process that execs /init.
|
||||
# This code runs in user space.
|
||||
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
#include "kernel/types.h"
|
||||
#include "kernel/stat.h"
|
||||
#include "user/user.h"
|
||||
|
||||
int
|
||||
|
|
Loading…
Reference in a new issue