Encapsulate some types related to cpu word length.

The purpose is to facilitate porting to RV64.

Signed-off-by: Wang Chen <wangchen20@iscas.ac.cn>
This commit is contained in:
Wang Chen
2024-03-27 14:11:18 +08:00
committed by Chen Wang
parent 1976f03d28
commit fd1d098906
63 changed files with 960 additions and 864 deletions

View File

@@ -5,7 +5,7 @@
* QEMU RISC-V Virt machine with 16550a UART and VirtIO MMIO
*/
/*
/*
* maximum number of CPUs
* see https://github.com/qemu/qemu/blob/master/include/hw/riscv/virt.h
* #define VIRT_CPUS_MAX 8
@@ -14,7 +14,7 @@
/*
* MemoryMap
* see https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c, virt_memmap[]
* see https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c, virt_memmap[]
* 0x00001000 -- boot ROM, provided by qemu
* 0x02000000 -- CLINT
* 0x0C000000 -- PLIC

View File

@@ -1,30 +1,32 @@
#define SIZE_PTR .word
.section .rodata
.global HEAP_START
HEAP_START: .word _heap_start
HEAP_START: SIZE_PTR _heap_start
.global HEAP_SIZE
HEAP_SIZE: .word _heap_size
HEAP_SIZE: SIZE_PTR _heap_size
.global TEXT_START
TEXT_START: .word _text_start
TEXT_START: SIZE_PTR _text_start
.global TEXT_END
TEXT_END: .word _text_end
TEXT_END: SIZE_PTR _text_end
.global DATA_START
DATA_START: .word _data_start
DATA_START: SIZE_PTR _data_start
.global DATA_END
DATA_END: .word _data_end
DATA_END: SIZE_PTR _data_end
.global RODATA_START
RODATA_START: .word _rodata_start
RODATA_START: SIZE_PTR _rodata_start
.global RODATA_END
RODATA_END: .word _rodata_end
RODATA_END: SIZE_PTR _rodata_end
.global BSS_START
BSS_START: .word _bss_start
BSS_START: SIZE_PTR _bss_start
.global BSS_END
BSS_END: .word _bss_end
BSS_END: SIZE_PTR _bss_end

View File

@@ -3,24 +3,24 @@
/*
* Following global vars are defined in mem.S
*/
extern uint32_t TEXT_START;
extern uint32_t TEXT_END;
extern uint32_t DATA_START;
extern uint32_t DATA_END;
extern uint32_t RODATA_START;
extern uint32_t RODATA_END;
extern uint32_t BSS_START;
extern uint32_t BSS_END;
extern uint32_t HEAP_START;
extern uint32_t HEAP_SIZE;
extern ptr_t TEXT_START;
extern ptr_t TEXT_END;
extern ptr_t DATA_START;
extern ptr_t DATA_END;
extern ptr_t RODATA_START;
extern ptr_t RODATA_END;
extern ptr_t BSS_START;
extern ptr_t BSS_END;
extern ptr_t HEAP_START;
extern ptr_t HEAP_SIZE;
/*
* _alloc_start points to the actual start address of heap pool
* _alloc_end points to the actual end address of heap pool
* _num_pages holds the actual max number of pages we can allocate.
*/
static uint32_t _alloc_start = 0;
static uint32_t _alloc_end = 0;
static ptr_t _alloc_start = 0;
static ptr_t _alloc_end = 0;
static uint32_t _num_pages = 0;
#define PAGE_SIZE 4096
@@ -70,9 +70,9 @@ static inline int _is_last(struct Page *page)
/*
* align the address to the border of page(4K)
*/
static inline uint32_t _align_page(uint32_t address)
static inline ptr_t _align_page(ptr_t address)
{
uint32_t order = (1 << PAGE_ORDER) - 1;
ptr_t order = (1 << PAGE_ORDER) - 1;
return (address + order) & (~order);
}
@@ -155,12 +155,12 @@ void page_free(void *p)
/*
* Assert (TBD) if p is invalid
*/
if (!p || (uint32_t)p >= _alloc_end) {
if (!p || (ptr_t)p >= _alloc_end) {
return;
}
/* get the first page descriptor of this memory block */
struct Page *page = (struct Page *)HEAP_START;
page += ((uint32_t)p - _alloc_start)/ PAGE_SIZE;
page += ((ptr_t)p - _alloc_start)/ PAGE_SIZE;
/* loop and clear all the page descriptors of the memory block */
while (!_is_free(page)) {
if (_is_last(page)) {

View File

@@ -5,7 +5,7 @@
* QEMU RISC-V Virt machine with 16550a UART and VirtIO MMIO
*/
/*
/*
* maximum number of CPUs
* see https://github.com/qemu/qemu/blob/master/include/hw/riscv/virt.h
* #define VIRT_CPUS_MAX 8
@@ -14,7 +14,7 @@
/*
* MemoryMap
* see https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c, virt_memmap[]
* see https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c, virt_memmap[]
* 0x00001000 -- boot ROM, provided by qemu
* 0x02000000 -- CLINT
* 0x0C000000 -- PLIC

View File

@@ -6,4 +6,6 @@ typedef unsigned short uint16_t;
typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
typedef uint32_t ptr_t;
#endif /* __TYPES_H__ */

View File

@@ -1,3 +1,7 @@
#define LOAD lw
#define STORE sw
#define SIZE_REG 4
# Save all General-Purpose(GP) registers to context.
# struct context *base = &ctx_task;
# base->ra = ra;
@@ -10,34 +14,34 @@
# which is a global value and would not be changed
# during context-switch.
.macro reg_save base
sw ra, 0(\base)
sw sp, 4(\base)
sw t0, 16(\base)
sw t1, 20(\base)
sw t2, 24(\base)
sw s0, 28(\base)
sw s1, 32(\base)
sw a0, 36(\base)
sw a1, 40(\base)
sw a2, 44(\base)
sw a3, 48(\base)
sw a4, 52(\base)
sw a5, 56(\base)
sw a6, 60(\base)
sw a7, 64(\base)
sw s2, 68(\base)
sw s3, 72(\base)
sw s4, 76(\base)
sw s5, 80(\base)
sw s6, 84(\base)
sw s7, 88(\base)
sw s8, 92(\base)
sw s9, 96(\base)
sw s10, 100(\base)
sw s11, 104(\base)
sw t3, 108(\base)
sw t4, 112(\base)
sw t5, 116(\base)
STORE ra, 0*SIZE_REG(\base)
STORE sp, 1*SIZE_REG(\base)
STORE t0, 4*SIZE_REG(\base)
STORE t1, 5*SIZE_REG(\base)
STORE t2, 6*SIZE_REG(\base)
STORE s0, 7*SIZE_REG(\base)
STORE s1, 8*SIZE_REG(\base)
STORE a0, 9*SIZE_REG(\base)
STORE a1, 10*SIZE_REG(\base)
STORE a2, 11*SIZE_REG(\base)
STORE a3, 12*SIZE_REG(\base)
STORE a4, 13*SIZE_REG(\base)
STORE a5, 14*SIZE_REG(\base)
STORE a6, 15*SIZE_REG(\base)
STORE a7, 16*SIZE_REG(\base)
STORE s2, 17*SIZE_REG(\base)
STORE s3, 18*SIZE_REG(\base)
STORE s4, 19*SIZE_REG(\base)
STORE s5, 20*SIZE_REG(\base)
STORE s6, 21*SIZE_REG(\base)
STORE s7, 22*SIZE_REG(\base)
STORE s8, 23*SIZE_REG(\base)
STORE s9, 24*SIZE_REG(\base)
STORE s10, 25*SIZE_REG(\base)
STORE s11, 26*SIZE_REG(\base)
STORE t3, 27*SIZE_REG(\base)
STORE t4, 28*SIZE_REG(\base)
STORE t5, 29*SIZE_REG(\base)
# we don't save t6 here, due to we have used
# it as base, we have to save t6 in an extra step
# outside of reg_save
@@ -49,35 +53,35 @@
# ra = base->ra;
# ......
.macro reg_restore base
lw ra, 0(\base)
lw sp, 4(\base)
lw t0, 16(\base)
lw t1, 20(\base)
lw t2, 24(\base)
lw s0, 28(\base)
lw s1, 32(\base)
lw a0, 36(\base)
lw a1, 40(\base)
lw a2, 44(\base)
lw a3, 48(\base)
lw a4, 52(\base)
lw a5, 56(\base)
lw a6, 60(\base)
lw a7, 64(\base)
lw s2, 68(\base)
lw s3, 72(\base)
lw s4, 76(\base)
lw s5, 80(\base)
lw s6, 84(\base)
lw s7, 88(\base)
lw s8, 92(\base)
lw s9, 96(\base)
lw s10, 100(\base)
lw s11, 104(\base)
lw t3, 108(\base)
lw t4, 112(\base)
lw t5, 116(\base)
lw t6, 120(\base)
LOAD ra, 0*SIZE_REG(\base)
LOAD sp, 1*SIZE_REG(\base)
LOAD t0, 4*SIZE_REG(\base)
LOAD t1, 5*SIZE_REG(\base)
LOAD t2, 6*SIZE_REG(\base)
LOAD s0, 7*SIZE_REG(\base)
LOAD s1, 8*SIZE_REG(\base)
LOAD a0, 9*SIZE_REG(\base)
LOAD a1, 10*SIZE_REG(\base)
LOAD a2, 11*SIZE_REG(\base)
LOAD a3, 12*SIZE_REG(\base)
LOAD a4, 13*SIZE_REG(\base)
LOAD a5, 14*SIZE_REG(\base)
LOAD a6, 15*SIZE_REG(\base)
LOAD a7, 16*SIZE_REG(\base)
LOAD s2, 17*SIZE_REG(\base)
LOAD s3, 18*SIZE_REG(\base)
LOAD s4, 19*SIZE_REG(\base)
LOAD s5, 20*SIZE_REG(\base)
LOAD s6, 21*SIZE_REG(\base)
LOAD s7, 22*SIZE_REG(\base)
LOAD s8, 23*SIZE_REG(\base)
LOAD s9, 24*SIZE_REG(\base)
LOAD s10, 25*SIZE_REG(\base)
LOAD s11, 26*SIZE_REG(\base)
LOAD t3, 27*SIZE_REG(\base)
LOAD t4, 28*SIZE_REG(\base)
LOAD t5, 29*SIZE_REG(\base)
LOAD t6, 30*SIZE_REG(\base)
.endm
# Something to note about save/restore:
@@ -104,9 +108,9 @@ switch_to:
# Save the actual t6 register, which we swapped into
# mscratch
mv t5, t6 # t5 points to the context of current task
csrr t6, mscratch # read t6 back from mscratch
sw t6, 120(t5) # save t6 with t5 as base
mv t5, t6 # t5 points to the context of current task
csrr t6, mscratch # read t6 back from mscratch
STORE t6, 30*SIZE_REG(t5) # save t6 with t5 as base
1:
# switch mscratch to point to the context of the next task

View File

@@ -1,30 +1,32 @@
#define SIZE_PTR .word
.section .rodata
.global HEAP_START
HEAP_START: .word _heap_start
HEAP_START: SIZE_PTR _heap_start
.global HEAP_SIZE
HEAP_SIZE: .word _heap_size
HEAP_SIZE: SIZE_PTR _heap_size
.global TEXT_START
TEXT_START: .word _text_start
TEXT_START: SIZE_PTR _text_start
.global TEXT_END
TEXT_END: .word _text_end
TEXT_END: SIZE_PTR _text_end
.global DATA_START
DATA_START: .word _data_start
DATA_START: SIZE_PTR _data_start
.global DATA_END
DATA_END: .word _data_end
DATA_END: SIZE_PTR _data_end
.global RODATA_START
RODATA_START: .word _rodata_start
RODATA_START: SIZE_PTR _rodata_start
.global RODATA_END
RODATA_END: .word _rodata_end
RODATA_END: SIZE_PTR _rodata_end
.global BSS_START
BSS_START: .word _bss_start
BSS_START: SIZE_PTR _bss_start
.global BSS_END
BSS_END: .word _bss_end
BSS_END: SIZE_PTR _bss_end

View File

@@ -3,24 +3,24 @@
/*
* Following global vars are defined in mem.S
*/
extern uint32_t TEXT_START;
extern uint32_t TEXT_END;
extern uint32_t DATA_START;
extern uint32_t DATA_END;
extern uint32_t RODATA_START;
extern uint32_t RODATA_END;
extern uint32_t BSS_START;
extern uint32_t BSS_END;
extern uint32_t HEAP_START;
extern uint32_t HEAP_SIZE;
extern ptr_t TEXT_START;
extern ptr_t TEXT_END;
extern ptr_t DATA_START;
extern ptr_t DATA_END;
extern ptr_t RODATA_START;
extern ptr_t RODATA_END;
extern ptr_t BSS_START;
extern ptr_t BSS_END;
extern ptr_t HEAP_START;
extern ptr_t HEAP_SIZE;
/*
* _alloc_start points to the actual start address of heap pool
* _alloc_end points to the actual end address of heap pool
* _num_pages holds the actual max number of pages we can allocate.
*/
static uint32_t _alloc_start = 0;
static uint32_t _alloc_end = 0;
static ptr_t _alloc_start = 0;
static ptr_t _alloc_end = 0;
static uint32_t _num_pages = 0;
#define PAGE_SIZE 4096
@@ -70,9 +70,9 @@ static inline int _is_last(struct Page *page)
/*
* align the address to the border of page(4K)
*/
static inline uint32_t _align_page(uint32_t address)
static inline ptr_t _align_page(ptr_t address)
{
uint32_t order = (1 << PAGE_ORDER) - 1;
ptr_t order = (1 << PAGE_ORDER) - 1;
return (address + order) & (~order);
}
@@ -155,12 +155,12 @@ void page_free(void *p)
/*
* Assert (TBD) if p is invalid
*/
if (!p || (uint32_t)p >= _alloc_end) {
if (!p || (ptr_t)p >= _alloc_end) {
return;
}
/* get the first page descriptor of this memory block */
struct Page *page = (struct Page *)HEAP_START;
page += ((uint32_t)p - _alloc_start)/ PAGE_SIZE;
page += ((ptr_t)p - _alloc_start)/ PAGE_SIZE;
/* loop and clear all the page descriptors of the memory block */
while (!_is_free(page)) {
if (_is_last(page)) {

View File

@@ -5,7 +5,7 @@
* QEMU RISC-V Virt machine with 16550a UART and VirtIO MMIO
*/
/*
/*
* maximum number of CPUs
* see https://github.com/qemu/qemu/blob/master/include/hw/riscv/virt.h
* #define VIRT_CPUS_MAX 8
@@ -14,7 +14,7 @@
/*
* MemoryMap
* see https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c, virt_memmap[]
* see https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c, virt_memmap[]
* 0x00001000 -- boot ROM, provided by qemu
* 0x02000000 -- CLINT
* 0x0C000000 -- PLIC

View File

@@ -7,8 +7,9 @@ typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
/*
* RISCV32: register is 32bits width
*/
* Register Width
*/
typedef uint32_t reg_t;
typedef uint32_t ptr_t;
#endif /* __TYPES_H__ */

View File

@@ -1,3 +1,7 @@
#define LOAD lw
#define STORE sw
#define SIZE_REG 4
# Save all General-Purpose(GP) registers to context.
# struct context *base = &ctx_task;
# base->ra = ra;
@@ -10,34 +14,34 @@
# which is a global value and would not be changed
# during context-switch.
.macro reg_save base
sw ra, 0(\base)
sw sp, 4(\base)
sw t0, 16(\base)
sw t1, 20(\base)
sw t2, 24(\base)
sw s0, 28(\base)
sw s1, 32(\base)
sw a0, 36(\base)
sw a1, 40(\base)
sw a2, 44(\base)
sw a3, 48(\base)
sw a4, 52(\base)
sw a5, 56(\base)
sw a6, 60(\base)
sw a7, 64(\base)
sw s2, 68(\base)
sw s3, 72(\base)
sw s4, 76(\base)
sw s5, 80(\base)
sw s6, 84(\base)
sw s7, 88(\base)
sw s8, 92(\base)
sw s9, 96(\base)
sw s10, 100(\base)
sw s11, 104(\base)
sw t3, 108(\base)
sw t4, 112(\base)
sw t5, 116(\base)
STORE ra, 0*SIZE_REG(\base)
STORE sp, 1*SIZE_REG(\base)
STORE t0, 4*SIZE_REG(\base)
STORE t1, 5*SIZE_REG(\base)
STORE t2, 6*SIZE_REG(\base)
STORE s0, 7*SIZE_REG(\base)
STORE s1, 8*SIZE_REG(\base)
STORE a0, 9*SIZE_REG(\base)
STORE a1, 10*SIZE_REG(\base)
STORE a2, 11*SIZE_REG(\base)
STORE a3, 12*SIZE_REG(\base)
STORE a4, 13*SIZE_REG(\base)
STORE a5, 14*SIZE_REG(\base)
STORE a6, 15*SIZE_REG(\base)
STORE a7, 16*SIZE_REG(\base)
STORE s2, 17*SIZE_REG(\base)
STORE s3, 18*SIZE_REG(\base)
STORE s4, 19*SIZE_REG(\base)
STORE s5, 20*SIZE_REG(\base)
STORE s6, 21*SIZE_REG(\base)
STORE s7, 22*SIZE_REG(\base)
STORE s8, 23*SIZE_REG(\base)
STORE s9, 24*SIZE_REG(\base)
STORE s10, 25*SIZE_REG(\base)
STORE s11, 26*SIZE_REG(\base)
STORE t3, 27*SIZE_REG(\base)
STORE t4, 28*SIZE_REG(\base)
STORE t5, 29*SIZE_REG(\base)
# we don't save t6 here, due to we have used
# it as base, we have to save t6 in an extra step
# outside of reg_save
@@ -49,35 +53,35 @@
# ra = base->ra;
# ......
.macro reg_restore base
lw ra, 0(\base)
lw sp, 4(\base)
lw t0, 16(\base)
lw t1, 20(\base)
lw t2, 24(\base)
lw s0, 28(\base)
lw s1, 32(\base)
lw a0, 36(\base)
lw a1, 40(\base)
lw a2, 44(\base)
lw a3, 48(\base)
lw a4, 52(\base)
lw a5, 56(\base)
lw a6, 60(\base)
lw a7, 64(\base)
lw s2, 68(\base)
lw s3, 72(\base)
lw s4, 76(\base)
lw s5, 80(\base)
lw s6, 84(\base)
lw s7, 88(\base)
lw s8, 92(\base)
lw s9, 96(\base)
lw s10, 100(\base)
lw s11, 104(\base)
lw t3, 108(\base)
lw t4, 112(\base)
lw t5, 116(\base)
lw t6, 120(\base)
LOAD ra, 0*SIZE_REG(\base)
LOAD sp, 1*SIZE_REG(\base)
LOAD t0, 4*SIZE_REG(\base)
LOAD t1, 5*SIZE_REG(\base)
LOAD t2, 6*SIZE_REG(\base)
LOAD s0, 7*SIZE_REG(\base)
LOAD s1, 8*SIZE_REG(\base)
LOAD a0, 9*SIZE_REG(\base)
LOAD a1, 10*SIZE_REG(\base)
LOAD a2, 11*SIZE_REG(\base)
LOAD a3, 12*SIZE_REG(\base)
LOAD a4, 13*SIZE_REG(\base)
LOAD a5, 14*SIZE_REG(\base)
LOAD a6, 15*SIZE_REG(\base)
LOAD a7, 16*SIZE_REG(\base)
LOAD s2, 17*SIZE_REG(\base)
LOAD s3, 18*SIZE_REG(\base)
LOAD s4, 19*SIZE_REG(\base)
LOAD s5, 20*SIZE_REG(\base)
LOAD s6, 21*SIZE_REG(\base)
LOAD s7, 22*SIZE_REG(\base)
LOAD s8, 23*SIZE_REG(\base)
LOAD s9, 24*SIZE_REG(\base)
LOAD s10, 25*SIZE_REG(\base)
LOAD s11, 26*SIZE_REG(\base)
LOAD t3, 27*SIZE_REG(\base)
LOAD t4, 28*SIZE_REG(\base)
LOAD t5, 29*SIZE_REG(\base)
LOAD t6, 30*SIZE_REG(\base)
.endm
# Something to note about save/restore:
@@ -104,9 +108,9 @@ switch_to:
# Save the actual t6 register, which we swapped into
# mscratch
mv t5, t6 # t5 points to the context of current task
csrr t6, mscratch # read t6 back from mscratch
sw t6, 120(t5) # save t6 with t5 as base
mv t5, t6 # t5 points to the context of current task
csrr t6, mscratch # read t6 back from mscratch
STORE t6, 30*SIZE_REG(t5) # save t6 with t5 as base
1:
# switch mscratch to point to the context of the next task

View File

@@ -1,30 +1,32 @@
#define SIZE_PTR .word
.section .rodata
.global HEAP_START
HEAP_START: .word _heap_start
HEAP_START: SIZE_PTR _heap_start
.global HEAP_SIZE
HEAP_SIZE: .word _heap_size
HEAP_SIZE: SIZE_PTR _heap_size
.global TEXT_START
TEXT_START: .word _text_start
TEXT_START: SIZE_PTR _text_start
.global TEXT_END
TEXT_END: .word _text_end
TEXT_END: SIZE_PTR _text_end
.global DATA_START
DATA_START: .word _data_start
DATA_START: SIZE_PTR _data_start
.global DATA_END
DATA_END: .word _data_end
DATA_END: SIZE_PTR _data_end
.global RODATA_START
RODATA_START: .word _rodata_start
RODATA_START: SIZE_PTR _rodata_start
.global RODATA_END
RODATA_END: .word _rodata_end
RODATA_END: SIZE_PTR _rodata_end
.global BSS_START
BSS_START: .word _bss_start
BSS_START: SIZE_PTR _bss_start
.global BSS_END
BSS_END: .word _bss_end
BSS_END: SIZE_PTR _bss_end

View File

@@ -3,24 +3,24 @@
/*
* Following global vars are defined in mem.S
*/
extern uint32_t TEXT_START;
extern uint32_t TEXT_END;
extern uint32_t DATA_START;
extern uint32_t DATA_END;
extern uint32_t RODATA_START;
extern uint32_t RODATA_END;
extern uint32_t BSS_START;
extern uint32_t BSS_END;
extern uint32_t HEAP_START;
extern uint32_t HEAP_SIZE;
extern ptr_t TEXT_START;
extern ptr_t TEXT_END;
extern ptr_t DATA_START;
extern ptr_t DATA_END;
extern ptr_t RODATA_START;
extern ptr_t RODATA_END;
extern ptr_t BSS_START;
extern ptr_t BSS_END;
extern ptr_t HEAP_START;
extern ptr_t HEAP_SIZE;
/*
* _alloc_start points to the actual start address of heap pool
* _alloc_end points to the actual end address of heap pool
* _num_pages holds the actual max number of pages we can allocate.
*/
static uint32_t _alloc_start = 0;
static uint32_t _alloc_end = 0;
static ptr_t _alloc_start = 0;
static ptr_t _alloc_end = 0;
static uint32_t _num_pages = 0;
#define PAGE_SIZE 4096
@@ -70,9 +70,9 @@ static inline int _is_last(struct Page *page)
/*
* align the address to the border of page(4K)
*/
static inline uint32_t _align_page(uint32_t address)
static inline ptr_t _align_page(ptr_t address)
{
uint32_t order = (1 << PAGE_ORDER) - 1;
ptr_t order = (1 << PAGE_ORDER) - 1;
return (address + order) & (~order);
}
@@ -155,12 +155,12 @@ void page_free(void *p)
/*
* Assert (TBD) if p is invalid
*/
if (!p || (uint32_t)p >= _alloc_end) {
if (!p || (ptr_t)p >= _alloc_end) {
return;
}
/* get the first page descriptor of this memory block */
struct Page *page = (struct Page *)HEAP_START;
page += ((uint32_t)p - _alloc_start)/ PAGE_SIZE;
page += ((ptr_t)p - _alloc_start)/ PAGE_SIZE;
/* loop and clear all the page descriptors of the memory block */
while (!_is_free(page)) {
if (_is_last(page)) {

View File

@@ -5,7 +5,7 @@
* QEMU RISC-V Virt machine with 16550a UART and VirtIO MMIO
*/
/*
/*
* maximum number of CPUs
* see https://github.com/qemu/qemu/blob/master/include/hw/riscv/virt.h
* #define VIRT_CPUS_MAX 8
@@ -14,7 +14,7 @@
/*
* MemoryMap
* see https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c, virt_memmap[]
* see https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c, virt_memmap[]
* 0x00001000 -- boot ROM, provided by qemu
* 0x02000000 -- CLINT
* 0x0C000000 -- PLIC

View File

@@ -7,8 +7,9 @@ typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
/*
* RISCV32: register is 32bits width
*/
* Register Width
*/
typedef uint32_t reg_t;
typedef uint32_t ptr_t;
#endif /* __TYPES_H__ */

View File

@@ -1,3 +1,7 @@
#define LOAD lw
#define STORE sw
#define SIZE_REG 4
# Save all General-Purpose(GP) registers to context.
# struct context *base = &ctx_task;
# base->ra = ra;
@@ -10,34 +14,34 @@
# which is a global value and would not be changed
# during context-switch.
.macro reg_save base
sw ra, 0(\base)
sw sp, 4(\base)
sw t0, 16(\base)
sw t1, 20(\base)
sw t2, 24(\base)
sw s0, 28(\base)
sw s1, 32(\base)
sw a0, 36(\base)
sw a1, 40(\base)
sw a2, 44(\base)
sw a3, 48(\base)
sw a4, 52(\base)
sw a5, 56(\base)
sw a6, 60(\base)
sw a7, 64(\base)
sw s2, 68(\base)
sw s3, 72(\base)
sw s4, 76(\base)
sw s5, 80(\base)
sw s6, 84(\base)
sw s7, 88(\base)
sw s8, 92(\base)
sw s9, 96(\base)
sw s10, 100(\base)
sw s11, 104(\base)
sw t3, 108(\base)
sw t4, 112(\base)
sw t5, 116(\base)
STORE ra, 0*SIZE_REG(\base)
STORE sp, 1*SIZE_REG(\base)
STORE t0, 4*SIZE_REG(\base)
STORE t1, 5*SIZE_REG(\base)
STORE t2, 6*SIZE_REG(\base)
STORE s0, 7*SIZE_REG(\base)
STORE s1, 8*SIZE_REG(\base)
STORE a0, 9*SIZE_REG(\base)
STORE a1, 10*SIZE_REG(\base)
STORE a2, 11*SIZE_REG(\base)
STORE a3, 12*SIZE_REG(\base)
STORE a4, 13*SIZE_REG(\base)
STORE a5, 14*SIZE_REG(\base)
STORE a6, 15*SIZE_REG(\base)
STORE a7, 16*SIZE_REG(\base)
STORE s2, 17*SIZE_REG(\base)
STORE s3, 18*SIZE_REG(\base)
STORE s4, 19*SIZE_REG(\base)
STORE s5, 20*SIZE_REG(\base)
STORE s6, 21*SIZE_REG(\base)
STORE s7, 22*SIZE_REG(\base)
STORE s8, 23*SIZE_REG(\base)
STORE s9, 24*SIZE_REG(\base)
STORE s10, 25*SIZE_REG(\base)
STORE s11, 26*SIZE_REG(\base)
STORE t3, 27*SIZE_REG(\base)
STORE t4, 28*SIZE_REG(\base)
STORE t5, 29*SIZE_REG(\base)
# we don't save t6 here, due to we have used
# it as base, we have to save t6 in an extra step
# outside of reg_save
@@ -49,35 +53,35 @@
# ra = base->ra;
# ......
.macro reg_restore base
lw ra, 0(\base)
lw sp, 4(\base)
lw t0, 16(\base)
lw t1, 20(\base)
lw t2, 24(\base)
lw s0, 28(\base)
lw s1, 32(\base)
lw a0, 36(\base)
lw a1, 40(\base)
lw a2, 44(\base)
lw a3, 48(\base)
lw a4, 52(\base)
lw a5, 56(\base)
lw a6, 60(\base)
lw a7, 64(\base)
lw s2, 68(\base)
lw s3, 72(\base)
lw s4, 76(\base)
lw s5, 80(\base)
lw s6, 84(\base)
lw s7, 88(\base)
lw s8, 92(\base)
lw s9, 96(\base)
lw s10, 100(\base)
lw s11, 104(\base)
lw t3, 108(\base)
lw t4, 112(\base)
lw t5, 116(\base)
lw t6, 120(\base)
LOAD ra, 0*SIZE_REG(\base)
LOAD sp, 1*SIZE_REG(\base)
LOAD t0, 4*SIZE_REG(\base)
LOAD t1, 5*SIZE_REG(\base)
LOAD t2, 6*SIZE_REG(\base)
LOAD s0, 7*SIZE_REG(\base)
LOAD s1, 8*SIZE_REG(\base)
LOAD a0, 9*SIZE_REG(\base)
LOAD a1, 10*SIZE_REG(\base)
LOAD a2, 11*SIZE_REG(\base)
LOAD a3, 12*SIZE_REG(\base)
LOAD a4, 13*SIZE_REG(\base)
LOAD a5, 14*SIZE_REG(\base)
LOAD a6, 15*SIZE_REG(\base)
LOAD a7, 16*SIZE_REG(\base)
LOAD s2, 17*SIZE_REG(\base)
LOAD s3, 18*SIZE_REG(\base)
LOAD s4, 19*SIZE_REG(\base)
LOAD s5, 20*SIZE_REG(\base)
LOAD s6, 21*SIZE_REG(\base)
LOAD s7, 22*SIZE_REG(\base)
LOAD s8, 23*SIZE_REG(\base)
LOAD s9, 24*SIZE_REG(\base)
LOAD s10, 25*SIZE_REG(\base)
LOAD s11, 26*SIZE_REG(\base)
LOAD t3, 27*SIZE_REG(\base)
LOAD t4, 28*SIZE_REG(\base)
LOAD t5, 29*SIZE_REG(\base)
LOAD t6, 30*SIZE_REG(\base)
.endm
# Something to note about save/restore:
@@ -100,9 +104,9 @@ trap_vector:
# Save the actual t6 register, which we swapped into
# mscratch
mv t5, t6 # t5 points to the context of current task
csrr t6, mscratch # read t6 back from mscratch
sw t6, 120(t5) # save t6 with t5 as base
mv t5, t6 # t5 points to the context of current task
csrr t6, mscratch # read t6 back from mscratch
STORE t6, 30*SIZE_REG(t5) # save t6 with t5 as base
# Restore the context pointer into mscratch
csrw mscratch, t5
@@ -137,9 +141,9 @@ switch_to:
# Save the actual t6 register, which we swapped into
# mscratch
mv t5, t6 # t5 points to the context of current task
csrr t6, mscratch # read t6 back from mscratch
sw t6, 120(t5) # save t6 with t5 as base
mv t5, t6 # t5 points to the context of current task
csrr t6, mscratch # read t6 back from mscratch
STORE t6, 30*SIZE_REG(t5) # save t6 with t5 as base
1:
# switch mscratch to point to the context of the next task

View File

@@ -1,30 +1,32 @@
#define SIZE_PTR .word
.section .rodata
.global HEAP_START
HEAP_START: .word _heap_start
HEAP_START: SIZE_PTR _heap_start
.global HEAP_SIZE
HEAP_SIZE: .word _heap_size
HEAP_SIZE: SIZE_PTR _heap_size
.global TEXT_START
TEXT_START: .word _text_start
TEXT_START: SIZE_PTR _text_start
.global TEXT_END
TEXT_END: .word _text_end
TEXT_END: SIZE_PTR _text_end
.global DATA_START
DATA_START: .word _data_start
DATA_START: SIZE_PTR _data_start
.global DATA_END
DATA_END: .word _data_end
DATA_END: SIZE_PTR _data_end
.global RODATA_START
RODATA_START: .word _rodata_start
RODATA_START: SIZE_PTR _rodata_start
.global RODATA_END
RODATA_END: .word _rodata_end
RODATA_END: SIZE_PTR _rodata_end
.global BSS_START
BSS_START: .word _bss_start
BSS_START: SIZE_PTR _bss_start
.global BSS_END
BSS_END: .word _bss_end
BSS_END: SIZE_PTR _bss_end

View File

@@ -3,24 +3,24 @@
/*
* Following global vars are defined in mem.S
*/
extern uint32_t TEXT_START;
extern uint32_t TEXT_END;
extern uint32_t DATA_START;
extern uint32_t DATA_END;
extern uint32_t RODATA_START;
extern uint32_t RODATA_END;
extern uint32_t BSS_START;
extern uint32_t BSS_END;
extern uint32_t HEAP_START;
extern uint32_t HEAP_SIZE;
extern ptr_t TEXT_START;
extern ptr_t TEXT_END;
extern ptr_t DATA_START;
extern ptr_t DATA_END;
extern ptr_t RODATA_START;
extern ptr_t RODATA_END;
extern ptr_t BSS_START;
extern ptr_t BSS_END;
extern ptr_t HEAP_START;
extern ptr_t HEAP_SIZE;
/*
* _alloc_start points to the actual start address of heap pool
* _alloc_end points to the actual end address of heap pool
* _num_pages holds the actual max number of pages we can allocate.
*/
static uint32_t _alloc_start = 0;
static uint32_t _alloc_end = 0;
static ptr_t _alloc_start = 0;
static ptr_t _alloc_end = 0;
static uint32_t _num_pages = 0;
#define PAGE_SIZE 4096
@@ -70,9 +70,9 @@ static inline int _is_last(struct Page *page)
/*
* align the address to the border of page(4K)
*/
static inline uint32_t _align_page(uint32_t address)
static inline ptr_t _align_page(ptr_t address)
{
uint32_t order = (1 << PAGE_ORDER) - 1;
ptr_t order = (1 << PAGE_ORDER) - 1;
return (address + order) & (~order);
}
@@ -155,12 +155,12 @@ void page_free(void *p)
/*
* Assert (TBD) if p is invalid
*/
if (!p || (uint32_t)p >= _alloc_end) {
if (!p || (ptr_t)p >= _alloc_end) {
return;
}
/* get the first page descriptor of this memory block */
struct Page *page = (struct Page *)HEAP_START;
page += ((uint32_t)p - _alloc_start)/ PAGE_SIZE;
page += ((ptr_t)p - _alloc_start)/ PAGE_SIZE;
/* loop and clear all the page descriptors of the memory block */
while (!_is_free(page)) {
if (_is_last(page)) {

View File

@@ -5,7 +5,7 @@
* QEMU RISC-V Virt machine with 16550a UART and VirtIO MMIO
*/
/*
/*
* maximum number of CPUs
* see https://github.com/qemu/qemu/blob/master/include/hw/riscv/virt.h
* #define VIRT_CPUS_MAX 8
@@ -14,7 +14,7 @@
/*
* MemoryMap
* see https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c, virt_memmap[]
* see https://github.com/qemu/qemu/blob/master/hw/riscv/virt.c, virt_memmap[]
* 0x00001000 -- boot ROM, provided by qemu
* 0x02000000 -- CLINT
* 0x0C000000 -- PLIC

View File

@@ -92,6 +92,10 @@ static inline void w_mie(reg_t x)
asm volatile("csrw mie, %0" : : "r" (x));
}
/* Machine-mode Cause Masks */
#define MCAUSE_MASK_INTERRUPT (reg_t)0x80000000
#define MCAUSE_MASK_ECODE (reg_t)0x7FFFFFFF
static inline reg_t r_mcause()
{
reg_t x;

View File

@@ -13,9 +13,9 @@ void trap_init()
reg_t trap_handler(reg_t epc, reg_t cause)
{
reg_t return_pc = epc;
reg_t cause_code = cause & 0xfff;
reg_t cause_code = cause & MCAUSE_MASK_ECODE;
if (cause & 0x80000000) {
if (cause & MCAUSE_MASK_INTERRUPT) {
/* Asynchronous trap - interrupt */
switch (cause_code) {
case 3:

View File

@@ -7,8 +7,9 @@ typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
/*
* RISCV32: register is 32bits width
*/
* Register Width
*/
typedef uint32_t reg_t;
typedef uint32_t ptr_t;
#endif /* __TYPES_H__ */

View File

@@ -1,3 +1,7 @@
#define LOAD lw
#define STORE sw
#define SIZE_REG 4
# Save all General-Purpose(GP) registers to context.
# struct context *base = &ctx_task;
# base->ra = ra;
@@ -10,34 +14,34 @@
# which is a global value and would not be changed
# during context-switch.
.macro reg_save base
sw ra, 0(\base)
sw sp, 4(\base)
sw t0, 16(\base)
sw t1, 20(\base)
sw t2, 24(\base)
sw s0, 28(\base)
sw s1, 32(\base)
sw a0, 36(\base)
sw a1, 40(\base)
sw a2, 44(\base)
sw a3, 48(\base)
sw a4, 52(\base)
sw a5, 56(\base)
sw a6, 60(\base)
sw a7, 64(\base)
sw s2, 68(\base)
sw s3, 72(\base)
sw s4, 76(\base)
sw s5, 80(\base)
sw s6, 84(\base)
sw s7, 88(\base)
sw s8, 92(\base)
sw s9, 96(\base)
sw s10, 100(\base)
sw s11, 104(\base)
sw t3, 108(\base)
sw t4, 112(\base)
sw t5, 116(\base)
STORE ra, 0*SIZE_REG(\base)
STORE sp, 1*SIZE_REG(\base)
STORE t0, 4*SIZE_REG(\base)
STORE t1, 5*SIZE_REG(\base)
STORE t2, 6*SIZE_REG(\base)
STORE s0, 7*SIZE_REG(\base)
STORE s1, 8*SIZE_REG(\base)
STORE a0, 9*SIZE_REG(\base)
STORE a1, 10*SIZE_REG(\base)
STORE a2, 11*SIZE_REG(\base)
STORE a3, 12*SIZE_REG(\base)
STORE a4, 13*SIZE_REG(\base)
STORE a5, 14*SIZE_REG(\base)
STORE a6, 15*SIZE_REG(\base)
STORE a7, 16*SIZE_REG(\base)
STORE s2, 17*SIZE_REG(\base)
STORE s3, 18*SIZE_REG(\base)
STORE s4, 19*SIZE_REG(\base)
STORE s5, 20*SIZE_REG(\base)
STORE s6, 21*SIZE_REG(\base)
STORE s7, 22*SIZE_REG(\base)
STORE s8, 23*SIZE_REG(\base)
STORE s9, 24*SIZE_REG(\base)
STORE s10, 25*SIZE_REG(\base)
STORE s11, 26*SIZE_REG(\base)
STORE t3, 27*SIZE_REG(\base)
STORE t4, 28*SIZE_REG(\base)
STORE t5, 29*SIZE_REG(\base)
# we don't save t6 here, due to we have used
# it as base, we have to save t6 in an extra step
# outside of reg_save
@@ -49,35 +53,35 @@
# ra = base->ra;
# ......
.macro reg_restore base
lw ra, 0(\base)
lw sp, 4(\base)
lw t0, 16(\base)
lw t1, 20(\base)
lw t2, 24(\base)
lw s0, 28(\base)
lw s1, 32(\base)
lw a0, 36(\base)
lw a1, 40(\base)
lw a2, 44(\base)
lw a3, 48(\base)
lw a4, 52(\base)
lw a5, 56(\base)
lw a6, 60(\base)
lw a7, 64(\base)
lw s2, 68(\base)
lw s3, 72(\base)
lw s4, 76(\base)
lw s5, 80(\base)
lw s6, 84(\base)
lw s7, 88(\base)
lw s8, 92(\base)
lw s9, 96(\base)
lw s10, 100(\base)
lw s11, 104(\base)
lw t3, 108(\base)
lw t4, 112(\base)
lw t5, 116(\base)
lw t6, 120(\base)
LOAD ra, 0*SIZE_REG(\base)
LOAD sp, 1*SIZE_REG(\base)
LOAD t0, 4*SIZE_REG(\base)
LOAD t1, 5*SIZE_REG(\base)
LOAD t2, 6*SIZE_REG(\base)
LOAD s0, 7*SIZE_REG(\base)
LOAD s1, 8*SIZE_REG(\base)
LOAD a0, 9*SIZE_REG(\base)
LOAD a1, 10*SIZE_REG(\base)
LOAD a2, 11*SIZE_REG(\base)
LOAD a3, 12*SIZE_REG(\base)
LOAD a4, 13*SIZE_REG(\base)
LOAD a5, 14*SIZE_REG(\base)
LOAD a6, 15*SIZE_REG(\base)
LOAD a7, 16*SIZE_REG(\base)
LOAD s2, 17*SIZE_REG(\base)
LOAD s3, 18*SIZE_REG(\base)
LOAD s4, 19*SIZE_REG(\base)
LOAD s5, 20*SIZE_REG(\base)
LOAD s6, 21*SIZE_REG(\base)
LOAD s7, 22*SIZE_REG(\base)
LOAD s8, 23*SIZE_REG(\base)
LOAD s9, 24*SIZE_REG(\base)
LOAD s10, 25*SIZE_REG(\base)
LOAD s11, 26*SIZE_REG(\base)
LOAD t3, 27*SIZE_REG(\base)
LOAD t4, 28*SIZE_REG(\base)
LOAD t5, 29*SIZE_REG(\base)
LOAD t6, 30*SIZE_REG(\base)
.endm
# Something to note about save/restore:
@@ -100,9 +104,9 @@ trap_vector:
# Save the actual t6 register, which we swapped into
# mscratch
mv t5, t6 # t5 points to the context of current task
csrr t6, mscratch # read t6 back from mscratch
sw t6, 120(t5) # save t6 with t5 as base
mv t5, t6 # t5 points to the context of current task
csrr t6, mscratch # read t6 back from mscratch
STORE t6, 30*SIZE_REG(t5) # save t6 with t5 as base
# Restore the context pointer into mscratch
csrw mscratch, t5
@@ -137,9 +141,9 @@ switch_to:
# Save the actual t6 register, which we swapped into
# mscratch
mv t5, t6 # t5 points to the context of current task
csrr t6, mscratch # read t6 back from mscratch
sw t6, 120(t5) # save t6 with t5 as base
mv t5, t6 # t5 points to the context of current task
csrr t6, mscratch # read t6 back from mscratch
STORE t6, 30*SIZE_REG(t5) # save t6 with t5 as base
1:
# switch mscratch to point to the context of the next task

View File

@@ -1,30 +1,32 @@
#define SIZE_PTR .word
.section .rodata
.global HEAP_START
HEAP_START: .word _heap_start
HEAP_START: SIZE_PTR _heap_start
.global HEAP_SIZE
HEAP_SIZE: .word _heap_size
HEAP_SIZE: SIZE_PTR _heap_size
.global TEXT_START
TEXT_START: .word _text_start
TEXT_START: SIZE_PTR _text_start
.global TEXT_END
TEXT_END: .word _text_end
TEXT_END: SIZE_PTR _text_end
.global DATA_START
DATA_START: .word _data_start
DATA_START: SIZE_PTR _data_start
.global DATA_END
DATA_END: .word _data_end
DATA_END: SIZE_PTR _data_end
.global RODATA_START
RODATA_START: .word _rodata_start
RODATA_START: SIZE_PTR _rodata_start
.global RODATA_END
RODATA_END: .word _rodata_end
RODATA_END: SIZE_PTR _rodata_end
.global BSS_START
BSS_START: .word _bss_start
BSS_START: SIZE_PTR _bss_start
.global BSS_END
BSS_END: .word _bss_end
BSS_END: SIZE_PTR _bss_end

View File

@@ -3,24 +3,24 @@
/*
* Following global vars are defined in mem.S
*/
extern uint32_t TEXT_START;
extern uint32_t TEXT_END;
extern uint32_t DATA_START;
extern uint32_t DATA_END;
extern uint32_t RODATA_START;
extern uint32_t RODATA_END;
extern uint32_t BSS_START;
extern uint32_t BSS_END;
extern uint32_t HEAP_START;
extern uint32_t HEAP_SIZE;
extern ptr_t TEXT_START;
extern ptr_t TEXT_END;
extern ptr_t DATA_START;
extern ptr_t DATA_END;
extern ptr_t RODATA_START;
extern ptr_t RODATA_END;
extern ptr_t BSS_START;
extern ptr_t BSS_END;
extern ptr_t HEAP_START;
extern ptr_t HEAP_SIZE;
/*
* _alloc_start points to the actual start address of heap pool
* _alloc_end points to the actual end address of heap pool
* _num_pages holds the actual max number of pages we can allocate.
*/
static uint32_t _alloc_start = 0;
static uint32_t _alloc_end = 0;
static ptr_t _alloc_start = 0;
static ptr_t _alloc_end = 0;
static uint32_t _num_pages = 0;
#define PAGE_SIZE 4096
@@ -70,9 +70,9 @@ static inline int _is_last(struct Page *page)
/*
* align the address to the border of page(4K)
*/
static inline uint32_t _align_page(uint32_t address)
static inline ptr_t _align_page(ptr_t address)
{
uint32_t order = (1 << PAGE_ORDER) - 1;
ptr_t order = (1 << PAGE_ORDER) - 1;
return (address + order) & (~order);
}
@@ -155,12 +155,12 @@ void page_free(void *p)
/*
* Assert (TBD) if p is invalid
*/
if (!p || (uint32_t)p >= _alloc_end) {
if (!p || (ptr_t)p >= _alloc_end) {
return;
}
/* get the first page descriptor of this memory block */
struct Page *page = (struct Page *)HEAP_START;
page += ((uint32_t)p - _alloc_start)/ PAGE_SIZE;
page += ((ptr_t)p - _alloc_start)/ PAGE_SIZE;
/* loop and clear all the page descriptors of the memory block */
while (!_is_free(page)) {
if (_is_last(page)) {

View File

@@ -92,6 +92,10 @@ static inline void w_mie(reg_t x)
asm volatile("csrw mie, %0" : : "r" (x));
}
/* Machine-mode Cause Masks */
#define MCAUSE_MASK_INTERRUPT (reg_t)0x80000000
#define MCAUSE_MASK_ECODE (reg_t)0x7FFFFFFF
static inline reg_t r_mcause()
{
reg_t x;

View File

@@ -29,9 +29,9 @@ void external_interrupt_handler()
reg_t trap_handler(reg_t epc, reg_t cause)
{
reg_t return_pc = epc;
reg_t cause_code = cause & 0xfff;
reg_t cause_code = cause & MCAUSE_MASK_ECODE;
if (cause & 0x80000000) {
if (cause & MCAUSE_MASK_INTERRUPT) {
/* Asynchronous trap - interrupt */
switch (cause_code) {
case 3:

View File

@@ -7,8 +7,9 @@ typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
/*
* RISCV32: register is 32bits width
*/
* Register Width
*/
typedef uint32_t reg_t;
typedef uint32_t ptr_t;
#endif /* __TYPES_H__ */

View File

@@ -1,3 +1,7 @@
#define LOAD lw
#define STORE sw
#define SIZE_REG 4
# Save all General-Purpose(GP) registers to context.
# struct context *base = &ctx_task;
# base->ra = ra;
@@ -10,34 +14,34 @@
# which is a global value and would not be changed
# during context-switch.
.macro reg_save base
sw ra, 0(\base)
sw sp, 4(\base)
sw t0, 16(\base)
sw t1, 20(\base)
sw t2, 24(\base)
sw s0, 28(\base)
sw s1, 32(\base)
sw a0, 36(\base)
sw a1, 40(\base)
sw a2, 44(\base)
sw a3, 48(\base)
sw a4, 52(\base)
sw a5, 56(\base)
sw a6, 60(\base)
sw a7, 64(\base)
sw s2, 68(\base)
sw s3, 72(\base)
sw s4, 76(\base)
sw s5, 80(\base)
sw s6, 84(\base)
sw s7, 88(\base)
sw s8, 92(\base)
sw s9, 96(\base)
sw s10, 100(\base)
sw s11, 104(\base)
sw t3, 108(\base)
sw t4, 112(\base)
sw t5, 116(\base)
STORE ra, 0*SIZE_REG(\base)
STORE sp, 1*SIZE_REG(\base)
STORE t0, 4*SIZE_REG(\base)
STORE t1, 5*SIZE_REG(\base)
STORE t2, 6*SIZE_REG(\base)
STORE s0, 7*SIZE_REG(\base)
STORE s1, 8*SIZE_REG(\base)
STORE a0, 9*SIZE_REG(\base)
STORE a1, 10*SIZE_REG(\base)
STORE a2, 11*SIZE_REG(\base)
STORE a3, 12*SIZE_REG(\base)
STORE a4, 13*SIZE_REG(\base)
STORE a5, 14*SIZE_REG(\base)
STORE a6, 15*SIZE_REG(\base)
STORE a7, 16*SIZE_REG(\base)
STORE s2, 17*SIZE_REG(\base)
STORE s3, 18*SIZE_REG(\base)
STORE s4, 19*SIZE_REG(\base)
STORE s5, 20*SIZE_REG(\base)
STORE s6, 21*SIZE_REG(\base)
STORE s7, 22*SIZE_REG(\base)
STORE s8, 23*SIZE_REG(\base)
STORE s9, 24*SIZE_REG(\base)
STORE s10, 25*SIZE_REG(\base)
STORE s11, 26*SIZE_REG(\base)
STORE t3, 27*SIZE_REG(\base)
STORE t4, 28*SIZE_REG(\base)
STORE t5, 29*SIZE_REG(\base)
# we don't save t6 here, due to we have used
# it as base, we have to save t6 in an extra step
# outside of reg_save
@@ -49,35 +53,35 @@
# ra = base->ra;
# ......
.macro reg_restore base
lw ra, 0(\base)
lw sp, 4(\base)
lw t0, 16(\base)
lw t1, 20(\base)
lw t2, 24(\base)
lw s0, 28(\base)
lw s1, 32(\base)
lw a0, 36(\base)
lw a1, 40(\base)
lw a2, 44(\base)
lw a3, 48(\base)
lw a4, 52(\base)
lw a5, 56(\base)
lw a6, 60(\base)
lw a7, 64(\base)
lw s2, 68(\base)
lw s3, 72(\base)
lw s4, 76(\base)
lw s5, 80(\base)
lw s6, 84(\base)
lw s7, 88(\base)
lw s8, 92(\base)
lw s9, 96(\base)
lw s10, 100(\base)
lw s11, 104(\base)
lw t3, 108(\base)
lw t4, 112(\base)
lw t5, 116(\base)
lw t6, 120(\base)
LOAD ra, 0*SIZE_REG(\base)
LOAD sp, 1*SIZE_REG(\base)
LOAD t0, 4*SIZE_REG(\base)
LOAD t1, 5*SIZE_REG(\base)
LOAD t2, 6*SIZE_REG(\base)
LOAD s0, 7*SIZE_REG(\base)
LOAD s1, 8*SIZE_REG(\base)
LOAD a0, 9*SIZE_REG(\base)
LOAD a1, 10*SIZE_REG(\base)
LOAD a2, 11*SIZE_REG(\base)
LOAD a3, 12*SIZE_REG(\base)
LOAD a4, 13*SIZE_REG(\base)
LOAD a5, 14*SIZE_REG(\base)
LOAD a6, 15*SIZE_REG(\base)
LOAD a7, 16*SIZE_REG(\base)
LOAD s2, 17*SIZE_REG(\base)
LOAD s3, 18*SIZE_REG(\base)
LOAD s4, 19*SIZE_REG(\base)
LOAD s5, 20*SIZE_REG(\base)
LOAD s6, 21*SIZE_REG(\base)
LOAD s7, 22*SIZE_REG(\base)
LOAD s8, 23*SIZE_REG(\base)
LOAD s9, 24*SIZE_REG(\base)
LOAD s10, 25*SIZE_REG(\base)
LOAD s11, 26*SIZE_REG(\base)
LOAD t3, 27*SIZE_REG(\base)
LOAD t4, 28*SIZE_REG(\base)
LOAD t5, 29*SIZE_REG(\base)
LOAD t6, 30*SIZE_REG(\base)
.endm
# Something to note about save/restore:
@@ -100,9 +104,9 @@ trap_vector:
# Save the actual t6 register, which we swapped into
# mscratch
mv t5, t6 # t5 points to the context of current task
csrr t6, mscratch # read t6 back from mscratch
sw t6, 120(t5) # save t6 with t5 as base
mv t5, t6 # t5 points to the context of current task
csrr t6, mscratch # read t6 back from mscratch
STORE t6, 30*SIZE_REG(t5) # save t6 with t5 as base
# Restore the context pointer into mscratch
csrw mscratch, t5
@@ -137,9 +141,9 @@ switch_to:
# Save the actual t6 register, which we swapped into
# mscratch
mv t5, t6 # t5 points to the context of current task
csrr t6, mscratch # read t6 back from mscratch
sw t6, 120(t5) # save t6 with t5 as base
mv t5, t6 # t5 points to the context of current task
csrr t6, mscratch # read t6 back from mscratch
STORE t6, 30*SIZE_REG(t5) # save t6 with t5 as base
1:
# switch mscratch to point to the context of the next task

View File

@@ -1,30 +1,32 @@
#define SIZE_PTR .word
.section .rodata
.global HEAP_START
HEAP_START: .word _heap_start
HEAP_START: SIZE_PTR _heap_start
.global HEAP_SIZE
HEAP_SIZE: .word _heap_size
HEAP_SIZE: SIZE_PTR _heap_size
.global TEXT_START
TEXT_START: .word _text_start
TEXT_START: SIZE_PTR _text_start
.global TEXT_END
TEXT_END: .word _text_end
TEXT_END: SIZE_PTR _text_end
.global DATA_START
DATA_START: .word _data_start
DATA_START: SIZE_PTR _data_start
.global DATA_END
DATA_END: .word _data_end
DATA_END: SIZE_PTR _data_end
.global RODATA_START
RODATA_START: .word _rodata_start
RODATA_START: SIZE_PTR _rodata_start
.global RODATA_END
RODATA_END: .word _rodata_end
RODATA_END: SIZE_PTR _rodata_end
.global BSS_START
BSS_START: .word _bss_start
BSS_START: SIZE_PTR _bss_start
.global BSS_END
BSS_END: .word _bss_end
BSS_END: SIZE_PTR _bss_end

View File

@@ -3,24 +3,24 @@
/*
* Following global vars are defined in mem.S
*/
extern uint32_t TEXT_START;
extern uint32_t TEXT_END;
extern uint32_t DATA_START;
extern uint32_t DATA_END;
extern uint32_t RODATA_START;
extern uint32_t RODATA_END;
extern uint32_t BSS_START;
extern uint32_t BSS_END;
extern uint32_t HEAP_START;
extern uint32_t HEAP_SIZE;
extern ptr_t TEXT_START;
extern ptr_t TEXT_END;
extern ptr_t DATA_START;
extern ptr_t DATA_END;
extern ptr_t RODATA_START;
extern ptr_t RODATA_END;
extern ptr_t BSS_START;
extern ptr_t BSS_END;
extern ptr_t HEAP_START;
extern ptr_t HEAP_SIZE;
/*
* _alloc_start points to the actual start address of heap pool
* _alloc_end points to the actual end address of heap pool
* _num_pages holds the actual max number of pages we can allocate.
*/
static uint32_t _alloc_start = 0;
static uint32_t _alloc_end = 0;
static ptr_t _alloc_start = 0;
static ptr_t _alloc_end = 0;
static uint32_t _num_pages = 0;
#define PAGE_SIZE 4096
@@ -70,9 +70,9 @@ static inline int _is_last(struct Page *page)
/*
* align the address to the border of page(4K)
*/
static inline uint32_t _align_page(uint32_t address)
static inline ptr_t _align_page(ptr_t address)
{
uint32_t order = (1 << PAGE_ORDER) - 1;
ptr_t order = (1 << PAGE_ORDER) - 1;
return (address + order) & (~order);
}
@@ -155,12 +155,12 @@ void page_free(void *p)
/*
* Assert (TBD) if p is invalid
*/
if (!p || (uint32_t)p >= _alloc_end) {
if (!p || (ptr_t)p >= _alloc_end) {
return;
}
/* get the first page descriptor of this memory block */
struct Page *page = (struct Page *)HEAP_START;
page += ((uint32_t)p - _alloc_start)/ PAGE_SIZE;
page += ((ptr_t)p - _alloc_start)/ PAGE_SIZE;
/* loop and clear all the page descriptors of the memory block */
while (!_is_free(page)) {
if (_is_last(page)) {

View File

@@ -92,6 +92,10 @@ static inline void w_mie(reg_t x)
asm volatile("csrw mie, %0" : : "r" (x));
}
/* Machine-mode Cause Masks */
#define MCAUSE_MASK_INTERRUPT (reg_t)0x80000000
#define MCAUSE_MASK_ECODE (reg_t)0x7FFFFFFF
static inline reg_t r_mcause()
{
reg_t x;

View File

@@ -30,9 +30,9 @@ void external_interrupt_handler()
reg_t trap_handler(reg_t epc, reg_t cause)
{
reg_t return_pc = epc;
reg_t cause_code = cause & 0xfff;
reg_t cause_code = cause & MCAUSE_MASK_ECODE;
if (cause & 0x80000000) {
if (cause & MCAUSE_MASK_INTERRUPT) {
/* Asynchronous trap - interrupt */
switch (cause_code) {
case 3:

View File

@@ -7,8 +7,9 @@ typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
/*
* RISCV32: register is 32bits width
*/
* Register Width
*/
typedef uint32_t reg_t;
typedef uint32_t ptr_t;
#endif /* __TYPES_H__ */

View File

@@ -1,3 +1,7 @@
#define LOAD lw
#define STORE sw
#define SIZE_REG 4
# Save all General-Purpose(GP) registers to context.
# struct context *base = &ctx_task;
# base->ra = ra;
@@ -10,34 +14,34 @@
# which is a global value and would not be changed
# during context-switch.
.macro reg_save base
sw ra, 0(\base)
sw sp, 4(\base)
sw t0, 16(\base)
sw t1, 20(\base)
sw t2, 24(\base)
sw s0, 28(\base)
sw s1, 32(\base)
sw a0, 36(\base)
sw a1, 40(\base)
sw a2, 44(\base)
sw a3, 48(\base)
sw a4, 52(\base)
sw a5, 56(\base)
sw a6, 60(\base)
sw a7, 64(\base)
sw s2, 68(\base)
sw s3, 72(\base)
sw s4, 76(\base)
sw s5, 80(\base)
sw s6, 84(\base)
sw s7, 88(\base)
sw s8, 92(\base)
sw s9, 96(\base)
sw s10, 100(\base)
sw s11, 104(\base)
sw t3, 108(\base)
sw t4, 112(\base)
sw t5, 116(\base)
STORE ra, 0*SIZE_REG(\base)
STORE sp, 1*SIZE_REG(\base)
STORE t0, 4*SIZE_REG(\base)
STORE t1, 5*SIZE_REG(\base)
STORE t2, 6*SIZE_REG(\base)
STORE s0, 7*SIZE_REG(\base)
STORE s1, 8*SIZE_REG(\base)
STORE a0, 9*SIZE_REG(\base)
STORE a1, 10*SIZE_REG(\base)
STORE a2, 11*SIZE_REG(\base)
STORE a3, 12*SIZE_REG(\base)
STORE a4, 13*SIZE_REG(\base)
STORE a5, 14*SIZE_REG(\base)
STORE a6, 15*SIZE_REG(\base)
STORE a7, 16*SIZE_REG(\base)
STORE s2, 17*SIZE_REG(\base)
STORE s3, 18*SIZE_REG(\base)
STORE s4, 19*SIZE_REG(\base)
STORE s5, 20*SIZE_REG(\base)
STORE s6, 21*SIZE_REG(\base)
STORE s7, 22*SIZE_REG(\base)
STORE s8, 23*SIZE_REG(\base)
STORE s9, 24*SIZE_REG(\base)
STORE s10, 25*SIZE_REG(\base)
STORE s11, 26*SIZE_REG(\base)
STORE t3, 27*SIZE_REG(\base)
STORE t4, 28*SIZE_REG(\base)
STORE t5, 29*SIZE_REG(\base)
# we don't save t6 here, due to we have used
# it as base, we have to save t6 in an extra step
# outside of reg_save
@@ -49,35 +53,35 @@
# ra = base->ra;
# ......
.macro reg_restore base
lw ra, 0(\base)
lw sp, 4(\base)
lw t0, 16(\base)
lw t1, 20(\base)
lw t2, 24(\base)
lw s0, 28(\base)
lw s1, 32(\base)
lw a0, 36(\base)
lw a1, 40(\base)
lw a2, 44(\base)
lw a3, 48(\base)
lw a4, 52(\base)
lw a5, 56(\base)
lw a6, 60(\base)
lw a7, 64(\base)
lw s2, 68(\base)
lw s3, 72(\base)
lw s4, 76(\base)
lw s5, 80(\base)
lw s6, 84(\base)
lw s7, 88(\base)
lw s8, 92(\base)
lw s9, 96(\base)
lw s10, 100(\base)
lw s11, 104(\base)
lw t3, 108(\base)
lw t4, 112(\base)
lw t5, 116(\base)
lw t6, 120(\base)
LOAD ra, 0*SIZE_REG(\base)
LOAD sp, 1*SIZE_REG(\base)
LOAD t0, 4*SIZE_REG(\base)
LOAD t1, 5*SIZE_REG(\base)
LOAD t2, 6*SIZE_REG(\base)
LOAD s0, 7*SIZE_REG(\base)
LOAD s1, 8*SIZE_REG(\base)
LOAD a0, 9*SIZE_REG(\base)
LOAD a1, 10*SIZE_REG(\base)
LOAD a2, 11*SIZE_REG(\base)
LOAD a3, 12*SIZE_REG(\base)
LOAD a4, 13*SIZE_REG(\base)
LOAD a5, 14*SIZE_REG(\base)
LOAD a6, 15*SIZE_REG(\base)
LOAD a7, 16*SIZE_REG(\base)
LOAD s2, 17*SIZE_REG(\base)
LOAD s3, 18*SIZE_REG(\base)
LOAD s4, 19*SIZE_REG(\base)
LOAD s5, 20*SIZE_REG(\base)
LOAD s6, 21*SIZE_REG(\base)
LOAD s7, 22*SIZE_REG(\base)
LOAD s8, 23*SIZE_REG(\base)
LOAD s9, 24*SIZE_REG(\base)
LOAD s10, 25*SIZE_REG(\base)
LOAD s11, 26*SIZE_REG(\base)
LOAD t3, 27*SIZE_REG(\base)
LOAD t4, 28*SIZE_REG(\base)
LOAD t5, 29*SIZE_REG(\base)
LOAD t6, 30*SIZE_REG(\base)
.endm
# Something to note about save/restore:
@@ -100,13 +104,13 @@ trap_vector:
# Save the actual t6 register, which we swapped into
# mscratch
mv t5, t6 # t5 points to the context of current task
csrr t6, mscratch # read t6 back from mscratch
sw t6, 120(t5) # save t6 with t5 as base
mv t5, t6 # t5 points to the context of current task
csrr t6, mscratch # read t6 back from mscratch
STORE t6, 30*SIZE_REG(t5) # save t6 with t5 as base
# save mepc to context of current task
csrr a0, mepc
sw a0, 124(t5)
STORE a0, 31*SIZE_REG(t5)
# Restore the context pointer into mscratch
csrw mscratch, t5
@@ -134,7 +138,7 @@ switch_to:
# switch mscratch to point to the context of the next task
csrw mscratch, a0
# set mepc to the pc of the next task
lw a1, 124(a0)
LOAD a1, 31*SIZE_REG(a0)
csrw mepc, a1
# Restore all GP registers

View File

@@ -1,30 +1,32 @@
#define SIZE_PTR .word
.section .rodata
.global HEAP_START
HEAP_START: .word _heap_start
HEAP_START: SIZE_PTR _heap_start
.global HEAP_SIZE
HEAP_SIZE: .word _heap_size
HEAP_SIZE: SIZE_PTR _heap_size
.global TEXT_START
TEXT_START: .word _text_start
TEXT_START: SIZE_PTR _text_start
.global TEXT_END
TEXT_END: .word _text_end
TEXT_END: SIZE_PTR _text_end
.global DATA_START
DATA_START: .word _data_start
DATA_START: SIZE_PTR _data_start
.global DATA_END
DATA_END: .word _data_end
DATA_END: SIZE_PTR _data_end
.global RODATA_START
RODATA_START: .word _rodata_start
RODATA_START: SIZE_PTR _rodata_start
.global RODATA_END
RODATA_END: .word _rodata_end
RODATA_END: SIZE_PTR _rodata_end
.global BSS_START
BSS_START: .word _bss_start
BSS_START: SIZE_PTR _bss_start
.global BSS_END
BSS_END: .word _bss_end
BSS_END: SIZE_PTR _bss_end

View File

@@ -58,7 +58,7 @@ struct context {
// upon is trap frame
// save the pc to run in next schedule cycle
reg_t pc; // offset: 31 *4 = 124
reg_t pc; // offset: 31 * sizeof(reg_t)
};
extern int task_create(void (*task)(void));

View File

@@ -3,24 +3,24 @@
/*
* Following global vars are defined in mem.S
*/
extern uint32_t TEXT_START;
extern uint32_t TEXT_END;
extern uint32_t DATA_START;
extern uint32_t DATA_END;
extern uint32_t RODATA_START;
extern uint32_t RODATA_END;
extern uint32_t BSS_START;
extern uint32_t BSS_END;
extern uint32_t HEAP_START;
extern uint32_t HEAP_SIZE;
extern ptr_t TEXT_START;
extern ptr_t TEXT_END;
extern ptr_t DATA_START;
extern ptr_t DATA_END;
extern ptr_t RODATA_START;
extern ptr_t RODATA_END;
extern ptr_t BSS_START;
extern ptr_t BSS_END;
extern ptr_t HEAP_START;
extern ptr_t HEAP_SIZE;
/*
* _alloc_start points to the actual start address of heap pool
* _alloc_end points to the actual end address of heap pool
* _num_pages holds the actual max number of pages we can allocate.
*/
static uint32_t _alloc_start = 0;
static uint32_t _alloc_end = 0;
static ptr_t _alloc_start = 0;
static ptr_t _alloc_end = 0;
static uint32_t _num_pages = 0;
#define PAGE_SIZE 4096
@@ -70,9 +70,9 @@ static inline int _is_last(struct Page *page)
/*
* align the address to the border of page(4K)
*/
static inline uint32_t _align_page(uint32_t address)
static inline ptr_t _align_page(ptr_t address)
{
uint32_t order = (1 << PAGE_ORDER) - 1;
ptr_t order = (1 << PAGE_ORDER) - 1;
return (address + order) & (~order);
}
@@ -155,12 +155,12 @@ void page_free(void *p)
/*
* Assert (TBD) if p is invalid
*/
if (!p || (uint32_t)p >= _alloc_end) {
if (!p || (ptr_t)p >= _alloc_end) {
return;
}
/* get the first page descriptor of this memory block */
struct Page *page = (struct Page *)HEAP_START;
page += ((uint32_t)p - _alloc_start)/ PAGE_SIZE;
page += ((ptr_t)p - _alloc_start)/ PAGE_SIZE;
/* loop and clear all the page descriptors of the memory block */
while (!_is_free(page)) {
if (_is_last(page)) {

View File

@@ -92,6 +92,10 @@ static inline void w_mie(reg_t x)
asm volatile("csrw mie, %0" : : "r" (x));
}
/* Machine-mode Cause Masks */
#define MCAUSE_MASK_INTERRUPT (reg_t)0x80000000
#define MCAUSE_MASK_ECODE (reg_t)0x7FFFFFFF
static inline reg_t r_mcause()
{
reg_t x;

View File

@@ -31,9 +31,9 @@ void external_interrupt_handler()
reg_t trap_handler(reg_t epc, reg_t cause)
{
reg_t return_pc = epc;
reg_t cause_code = cause & 0xfff;
reg_t cause_code = cause & MCAUSE_MASK_ECODE;
if (cause & 0x80000000) {
if (cause & MCAUSE_MASK_INTERRUPT) {
/* Asynchronous trap - interrupt */
switch (cause_code) {
case 3:

View File

@@ -7,8 +7,9 @@ typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
/*
* RISCV32: register is 32bits width
*/
* Register Width
*/
typedef uint32_t reg_t;
typedef uint32_t ptr_t;
#endif /* __TYPES_H__ */

View File

@@ -1,3 +1,7 @@
#define LOAD lw
#define STORE sw
#define SIZE_REG 4
# Save all General-Purpose(GP) registers to context.
# struct context *base = &ctx_task;
# base->ra = ra;
@@ -10,34 +14,34 @@
# which is a global value and would not be changed
# during context-switch.
.macro reg_save base
sw ra, 0(\base)
sw sp, 4(\base)
sw t0, 16(\base)
sw t1, 20(\base)
sw t2, 24(\base)
sw s0, 28(\base)
sw s1, 32(\base)
sw a0, 36(\base)
sw a1, 40(\base)
sw a2, 44(\base)
sw a3, 48(\base)
sw a4, 52(\base)
sw a5, 56(\base)
sw a6, 60(\base)
sw a7, 64(\base)
sw s2, 68(\base)
sw s3, 72(\base)
sw s4, 76(\base)
sw s5, 80(\base)
sw s6, 84(\base)
sw s7, 88(\base)
sw s8, 92(\base)
sw s9, 96(\base)
sw s10, 100(\base)
sw s11, 104(\base)
sw t3, 108(\base)
sw t4, 112(\base)
sw t5, 116(\base)
STORE ra, 0*SIZE_REG(\base)
STORE sp, 1*SIZE_REG(\base)
STORE t0, 4*SIZE_REG(\base)
STORE t1, 5*SIZE_REG(\base)
STORE t2, 6*SIZE_REG(\base)
STORE s0, 7*SIZE_REG(\base)
STORE s1, 8*SIZE_REG(\base)
STORE a0, 9*SIZE_REG(\base)
STORE a1, 10*SIZE_REG(\base)
STORE a2, 11*SIZE_REG(\base)
STORE a3, 12*SIZE_REG(\base)
STORE a4, 13*SIZE_REG(\base)
STORE a5, 14*SIZE_REG(\base)
STORE a6, 15*SIZE_REG(\base)
STORE a7, 16*SIZE_REG(\base)
STORE s2, 17*SIZE_REG(\base)
STORE s3, 18*SIZE_REG(\base)
STORE s4, 19*SIZE_REG(\base)
STORE s5, 20*SIZE_REG(\base)
STORE s6, 21*SIZE_REG(\base)
STORE s7, 22*SIZE_REG(\base)
STORE s8, 23*SIZE_REG(\base)
STORE s9, 24*SIZE_REG(\base)
STORE s10, 25*SIZE_REG(\base)
STORE s11, 26*SIZE_REG(\base)
STORE t3, 27*SIZE_REG(\base)
STORE t4, 28*SIZE_REG(\base)
STORE t5, 29*SIZE_REG(\base)
# we don't save t6 here, due to we have used
# it as base, we have to save t6 in an extra step
# outside of reg_save
@@ -49,35 +53,35 @@
# ra = base->ra;
# ......
.macro reg_restore base
lw ra, 0(\base)
lw sp, 4(\base)
lw t0, 16(\base)
lw t1, 20(\base)
lw t2, 24(\base)
lw s0, 28(\base)
lw s1, 32(\base)
lw a0, 36(\base)
lw a1, 40(\base)
lw a2, 44(\base)
lw a3, 48(\base)
lw a4, 52(\base)
lw a5, 56(\base)
lw a6, 60(\base)
lw a7, 64(\base)
lw s2, 68(\base)
lw s3, 72(\base)
lw s4, 76(\base)
lw s5, 80(\base)
lw s6, 84(\base)
lw s7, 88(\base)
lw s8, 92(\base)
lw s9, 96(\base)
lw s10, 100(\base)
lw s11, 104(\base)
lw t3, 108(\base)
lw t4, 112(\base)
lw t5, 116(\base)
lw t6, 120(\base)
LOAD ra, 0*SIZE_REG(\base)
LOAD sp, 1*SIZE_REG(\base)
LOAD t0, 4*SIZE_REG(\base)
LOAD t1, 5*SIZE_REG(\base)
LOAD t2, 6*SIZE_REG(\base)
LOAD s0, 7*SIZE_REG(\base)
LOAD s1, 8*SIZE_REG(\base)
LOAD a0, 9*SIZE_REG(\base)
LOAD a1, 10*SIZE_REG(\base)
LOAD a2, 11*SIZE_REG(\base)
LOAD a3, 12*SIZE_REG(\base)
LOAD a4, 13*SIZE_REG(\base)
LOAD a5, 14*SIZE_REG(\base)
LOAD a6, 15*SIZE_REG(\base)
LOAD a7, 16*SIZE_REG(\base)
LOAD s2, 17*SIZE_REG(\base)
LOAD s3, 18*SIZE_REG(\base)
LOAD s4, 19*SIZE_REG(\base)
LOAD s5, 20*SIZE_REG(\base)
LOAD s6, 21*SIZE_REG(\base)
LOAD s7, 22*SIZE_REG(\base)
LOAD s8, 23*SIZE_REG(\base)
LOAD s9, 24*SIZE_REG(\base)
LOAD s10, 25*SIZE_REG(\base)
LOAD s11, 26*SIZE_REG(\base)
LOAD t3, 27*SIZE_REG(\base)
LOAD t4, 28*SIZE_REG(\base)
LOAD t5, 29*SIZE_REG(\base)
LOAD t6, 30*SIZE_REG(\base)
.endm
# Something to note about save/restore:
@@ -100,13 +104,13 @@ trap_vector:
# Save the actual t6 register, which we swapped into
# mscratch
mv t5, t6 # t5 points to the context of current task
csrr t6, mscratch # read t6 back from mscratch
sw t6, 120(t5) # save t6 with t5 as base
mv t5, t6 # t5 points to the context of current task
csrr t6, mscratch # read t6 back from mscratch
STORE t6, 30*SIZE_REG(t5) # save t6 with t5 as base
# save mepc to context of current task
csrr a0, mepc
sw a0, 124(t5)
STORE a0, 31*SIZE_REG(t5)
# Restore the context pointer into mscratch
csrw mscratch, t5
@@ -134,7 +138,7 @@ switch_to:
# switch mscratch to point to the context of the next task
csrw mscratch, a0
# set mepc to the pc of the next task
lw a1, 124(a0)
LOAD a1, 31*SIZE_REG(a0)
csrw mepc, a1
# Restore all GP registers

View File

@@ -1,30 +1,32 @@
#define SIZE_PTR .word
.section .rodata
.global HEAP_START
HEAP_START: .word _heap_start
HEAP_START: SIZE_PTR _heap_start
.global HEAP_SIZE
HEAP_SIZE: .word _heap_size
HEAP_SIZE: SIZE_PTR _heap_size
.global TEXT_START
TEXT_START: .word _text_start
TEXT_START: SIZE_PTR _text_start
.global TEXT_END
TEXT_END: .word _text_end
TEXT_END: SIZE_PTR _text_end
.global DATA_START
DATA_START: .word _data_start
DATA_START: SIZE_PTR _data_start
.global DATA_END
DATA_END: .word _data_end
DATA_END: SIZE_PTR _data_end
.global RODATA_START
RODATA_START: .word _rodata_start
RODATA_START: SIZE_PTR _rodata_start
.global RODATA_END
RODATA_END: .word _rodata_end
RODATA_END: SIZE_PTR _rodata_end
.global BSS_START
BSS_START: .word _bss_start
BSS_START: SIZE_PTR _bss_start
.global BSS_END
BSS_END: .word _bss_end
BSS_END: SIZE_PTR _bss_end

View File

@@ -58,7 +58,7 @@ struct context {
// upon is trap frame
// save the pc to run in next schedule cycle
reg_t pc; // offset: 31 *4 = 124
reg_t pc; // offset: 31 * sizeof(reg_t)
};
extern int task_create(void (*task)(void));

View File

@@ -3,24 +3,24 @@
/*
* Following global vars are defined in mem.S
*/
extern uint32_t TEXT_START;
extern uint32_t TEXT_END;
extern uint32_t DATA_START;
extern uint32_t DATA_END;
extern uint32_t RODATA_START;
extern uint32_t RODATA_END;
extern uint32_t BSS_START;
extern uint32_t BSS_END;
extern uint32_t HEAP_START;
extern uint32_t HEAP_SIZE;
extern ptr_t TEXT_START;
extern ptr_t TEXT_END;
extern ptr_t DATA_START;
extern ptr_t DATA_END;
extern ptr_t RODATA_START;
extern ptr_t RODATA_END;
extern ptr_t BSS_START;
extern ptr_t BSS_END;
extern ptr_t HEAP_START;
extern ptr_t HEAP_SIZE;
/*
* _alloc_start points to the actual start address of heap pool
* _alloc_end points to the actual end address of heap pool
* _num_pages holds the actual max number of pages we can allocate.
*/
static uint32_t _alloc_start = 0;
static uint32_t _alloc_end = 0;
static ptr_t _alloc_start = 0;
static ptr_t _alloc_end = 0;
static uint32_t _num_pages = 0;
#define PAGE_SIZE 4096
@@ -70,9 +70,9 @@ static inline int _is_last(struct Page *page)
/*
* align the address to the border of page(4K)
*/
static inline uint32_t _align_page(uint32_t address)
static inline ptr_t _align_page(ptr_t address)
{
uint32_t order = (1 << PAGE_ORDER) - 1;
ptr_t order = (1 << PAGE_ORDER) - 1;
return (address + order) & (~order);
}
@@ -155,12 +155,12 @@ void page_free(void *p)
/*
* Assert (TBD) if p is invalid
*/
if (!p || (uint32_t)p >= _alloc_end) {
if (!p || (ptr_t)p >= _alloc_end) {
return;
}
/* get the first page descriptor of this memory block */
struct Page *page = (struct Page *)HEAP_START;
page += ((uint32_t)p - _alloc_start)/ PAGE_SIZE;
page += ((ptr_t)p - _alloc_start)/ PAGE_SIZE;
/* loop and clear all the page descriptors of the memory block */
while (!_is_free(page)) {
if (_is_last(page)) {

View File

@@ -92,6 +92,10 @@ static inline void w_mie(reg_t x)
asm volatile("csrw mie, %0" : : "r" (x));
}
/* Machine-mode Cause Masks */
#define MCAUSE_MASK_INTERRUPT (reg_t)0x80000000
#define MCAUSE_MASK_ECODE (reg_t)0x7FFFFFFF
static inline reg_t r_mcause()
{
reg_t x;

View File

@@ -31,9 +31,9 @@ void external_interrupt_handler()
reg_t trap_handler(reg_t epc, reg_t cause)
{
reg_t return_pc = epc;
reg_t cause_code = cause & 0xfff;
reg_t cause_code = cause & MCAUSE_MASK_ECODE;
if (cause & 0x80000000) {
if (cause & MCAUSE_MASK_INTERRUPT) {
/* Asynchronous trap - interrupt */
switch (cause_code) {
case 3:

View File

@@ -7,8 +7,9 @@ typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
/*
* RISCV32: register is 32bits width
*/
* Register Width
*/
typedef uint32_t reg_t;
typedef uint32_t ptr_t;
#endif /* __TYPES_H__ */

View File

@@ -1,3 +1,7 @@
#define LOAD lw
#define STORE sw
#define SIZE_REG 4
# Save all General-Purpose(GP) registers to context.
# struct context *base = &ctx_task;
# base->ra = ra;
@@ -10,34 +14,34 @@
# which is a global value and would not be changed
# during context-switch.
.macro reg_save base
sw ra, 0(\base)
sw sp, 4(\base)
sw t0, 16(\base)
sw t1, 20(\base)
sw t2, 24(\base)
sw s0, 28(\base)
sw s1, 32(\base)
sw a0, 36(\base)
sw a1, 40(\base)
sw a2, 44(\base)
sw a3, 48(\base)
sw a4, 52(\base)
sw a5, 56(\base)
sw a6, 60(\base)
sw a7, 64(\base)
sw s2, 68(\base)
sw s3, 72(\base)
sw s4, 76(\base)
sw s5, 80(\base)
sw s6, 84(\base)
sw s7, 88(\base)
sw s8, 92(\base)
sw s9, 96(\base)
sw s10, 100(\base)
sw s11, 104(\base)
sw t3, 108(\base)
sw t4, 112(\base)
sw t5, 116(\base)
STORE ra, 0*SIZE_REG(\base)
STORE sp, 1*SIZE_REG(\base)
STORE t0, 4*SIZE_REG(\base)
STORE t1, 5*SIZE_REG(\base)
STORE t2, 6*SIZE_REG(\base)
STORE s0, 7*SIZE_REG(\base)
STORE s1, 8*SIZE_REG(\base)
STORE a0, 9*SIZE_REG(\base)
STORE a1, 10*SIZE_REG(\base)
STORE a2, 11*SIZE_REG(\base)
STORE a3, 12*SIZE_REG(\base)
STORE a4, 13*SIZE_REG(\base)
STORE a5, 14*SIZE_REG(\base)
STORE a6, 15*SIZE_REG(\base)
STORE a7, 16*SIZE_REG(\base)
STORE s2, 17*SIZE_REG(\base)
STORE s3, 18*SIZE_REG(\base)
STORE s4, 19*SIZE_REG(\base)
STORE s5, 20*SIZE_REG(\base)
STORE s6, 21*SIZE_REG(\base)
STORE s7, 22*SIZE_REG(\base)
STORE s8, 23*SIZE_REG(\base)
STORE s9, 24*SIZE_REG(\base)
STORE s10, 25*SIZE_REG(\base)
STORE s11, 26*SIZE_REG(\base)
STORE t3, 27*SIZE_REG(\base)
STORE t4, 28*SIZE_REG(\base)
STORE t5, 29*SIZE_REG(\base)
# we don't save t6 here, due to we have used
# it as base, we have to save t6 in an extra step
# outside of reg_save
@@ -49,35 +53,35 @@
# ra = base->ra;
# ......
.macro reg_restore base
lw ra, 0(\base)
lw sp, 4(\base)
lw t0, 16(\base)
lw t1, 20(\base)
lw t2, 24(\base)
lw s0, 28(\base)
lw s1, 32(\base)
lw a0, 36(\base)
lw a1, 40(\base)
lw a2, 44(\base)
lw a3, 48(\base)
lw a4, 52(\base)
lw a5, 56(\base)
lw a6, 60(\base)
lw a7, 64(\base)
lw s2, 68(\base)
lw s3, 72(\base)
lw s4, 76(\base)
lw s5, 80(\base)
lw s6, 84(\base)
lw s7, 88(\base)
lw s8, 92(\base)
lw s9, 96(\base)
lw s10, 100(\base)
lw s11, 104(\base)
lw t3, 108(\base)
lw t4, 112(\base)
lw t5, 116(\base)
lw t6, 120(\base)
LOAD ra, 0*SIZE_REG(\base)
LOAD sp, 1*SIZE_REG(\base)
LOAD t0, 4*SIZE_REG(\base)
LOAD t1, 5*SIZE_REG(\base)
LOAD t2, 6*SIZE_REG(\base)
LOAD s0, 7*SIZE_REG(\base)
LOAD s1, 8*SIZE_REG(\base)
LOAD a0, 9*SIZE_REG(\base)
LOAD a1, 10*SIZE_REG(\base)
LOAD a2, 11*SIZE_REG(\base)
LOAD a3, 12*SIZE_REG(\base)
LOAD a4, 13*SIZE_REG(\base)
LOAD a5, 14*SIZE_REG(\base)
LOAD a6, 15*SIZE_REG(\base)
LOAD a7, 16*SIZE_REG(\base)
LOAD s2, 17*SIZE_REG(\base)
LOAD s3, 18*SIZE_REG(\base)
LOAD s4, 19*SIZE_REG(\base)
LOAD s5, 20*SIZE_REG(\base)
LOAD s6, 21*SIZE_REG(\base)
LOAD s7, 22*SIZE_REG(\base)
LOAD s8, 23*SIZE_REG(\base)
LOAD s9, 24*SIZE_REG(\base)
LOAD s10, 25*SIZE_REG(\base)
LOAD s11, 26*SIZE_REG(\base)
LOAD t3, 27*SIZE_REG(\base)
LOAD t4, 28*SIZE_REG(\base)
LOAD t5, 29*SIZE_REG(\base)
LOAD t6, 30*SIZE_REG(\base)
.endm
# Something to note about save/restore:
@@ -100,13 +104,13 @@ trap_vector:
# Save the actual t6 register, which we swapped into
# mscratch
mv t5, t6 # t5 points to the context of current task
csrr t6, mscratch # read t6 back from mscratch
sw t6, 120(t5) # save t6 with t5 as base
mv t5, t6 # t5 points to the context of current task
csrr t6, mscratch # read t6 back from mscratch
STORE t6, 30*SIZE_REG(t5) # save t6 with t5 as base
# save mepc to context of current task
csrr a0, mepc
sw a0, 124(t5)
STORE a0, 31*SIZE_REG(t5)
# Restore the context pointer into mscratch
csrw mscratch, t5
@@ -134,7 +138,7 @@ switch_to:
# switch mscratch to point to the context of the next task
csrw mscratch, a0
# set mepc to the pc of the next task
lw a1, 124(a0)
LOAD a1, 31*SIZE_REG(a0)
csrw mepc, a1
# Restore all GP registers

View File

@@ -1,30 +1,32 @@
#define SIZE_PTR .word
.section .rodata
.global HEAP_START
HEAP_START: .word _heap_start
HEAP_START: SIZE_PTR _heap_start
.global HEAP_SIZE
HEAP_SIZE: .word _heap_size
HEAP_SIZE: SIZE_PTR _heap_size
.global TEXT_START
TEXT_START: .word _text_start
TEXT_START: SIZE_PTR _text_start
.global TEXT_END
TEXT_END: .word _text_end
TEXT_END: SIZE_PTR _text_end
.global DATA_START
DATA_START: .word _data_start
DATA_START: SIZE_PTR _data_start
.global DATA_END
DATA_END: .word _data_end
DATA_END: SIZE_PTR _data_end
.global RODATA_START
RODATA_START: .word _rodata_start
RODATA_START: SIZE_PTR _rodata_start
.global RODATA_END
RODATA_END: .word _rodata_end
RODATA_END: SIZE_PTR _rodata_end
.global BSS_START
BSS_START: .word _bss_start
BSS_START: SIZE_PTR _bss_start
.global BSS_END
BSS_END: .word _bss_end
BSS_END: SIZE_PTR _bss_end

View File

@@ -58,7 +58,7 @@ struct context {
// upon is trap frame
// save the pc to run in next schedule cycle
reg_t pc; // offset: 31 *4 = 124
reg_t pc; // offset: 31 * sizeof(reg_t)
};
extern int task_create(void (*task)(void));

View File

@@ -3,24 +3,24 @@
/*
* Following global vars are defined in mem.S
*/
extern uint32_t TEXT_START;
extern uint32_t TEXT_END;
extern uint32_t DATA_START;
extern uint32_t DATA_END;
extern uint32_t RODATA_START;
extern uint32_t RODATA_END;
extern uint32_t BSS_START;
extern uint32_t BSS_END;
extern uint32_t HEAP_START;
extern uint32_t HEAP_SIZE;
extern ptr_t TEXT_START;
extern ptr_t TEXT_END;
extern ptr_t DATA_START;
extern ptr_t DATA_END;
extern ptr_t RODATA_START;
extern ptr_t RODATA_END;
extern ptr_t BSS_START;
extern ptr_t BSS_END;
extern ptr_t HEAP_START;
extern ptr_t HEAP_SIZE;
/*
* _alloc_start points to the actual start address of heap pool
* _alloc_end points to the actual end address of heap pool
* _num_pages holds the actual max number of pages we can allocate.
*/
static uint32_t _alloc_start = 0;
static uint32_t _alloc_end = 0;
static ptr_t _alloc_start = 0;
static ptr_t _alloc_end = 0;
static uint32_t _num_pages = 0;
#define PAGE_SIZE 4096
@@ -70,9 +70,9 @@ static inline int _is_last(struct Page *page)
/*
* align the address to the border of page(4K)
*/
static inline uint32_t _align_page(uint32_t address)
static inline ptr_t _align_page(ptr_t address)
{
uint32_t order = (1 << PAGE_ORDER) - 1;
ptr_t order = (1 << PAGE_ORDER) - 1;
return (address + order) & (~order);
}
@@ -155,12 +155,12 @@ void page_free(void *p)
/*
* Assert (TBD) if p is invalid
*/
if (!p || (uint32_t)p >= _alloc_end) {
if (!p || (ptr_t)p >= _alloc_end) {
return;
}
/* get the first page descriptor of this memory block */
struct Page *page = (struct Page *)HEAP_START;
page += ((uint32_t)p - _alloc_start)/ PAGE_SIZE;
page += ((ptr_t)p - _alloc_start)/ PAGE_SIZE;
/* loop and clear all the page descriptors of the memory block */
while (!_is_free(page)) {
if (_is_last(page)) {

View File

@@ -92,6 +92,10 @@ static inline void w_mie(reg_t x)
asm volatile("csrw mie, %0" : : "r" (x));
}
/* Machine-mode Cause Masks */
#define MCAUSE_MASK_INTERRUPT (reg_t)0x80000000
#define MCAUSE_MASK_ECODE (reg_t)0x7FFFFFFF
static inline reg_t r_mcause()
{
reg_t x;

View File

@@ -31,9 +31,9 @@ void external_interrupt_handler()
reg_t trap_handler(reg_t epc, reg_t cause)
{
reg_t return_pc = epc;
reg_t cause_code = cause & 0xfff;
reg_t cause_code = cause & MCAUSE_MASK_ECODE;
if (cause & 0x80000000) {
if (cause & MCAUSE_MASK_INTERRUPT) {
/* Asynchronous trap - interrupt */
switch (cause_code) {
case 3:

View File

@@ -7,8 +7,9 @@ typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
/*
* RISCV32: register is 32bits width
*/
* Register Width
*/
typedef uint32_t reg_t;
typedef uint32_t ptr_t;
#endif /* __TYPES_H__ */

View File

@@ -1,3 +1,7 @@
#define LOAD lw
#define STORE sw
#define SIZE_REG 4
# Save all General-Purpose(GP) registers to context.
# struct context *base = &ctx_task;
# base->ra = ra;
@@ -10,34 +14,34 @@
# which is a global value and would not be changed
# during context-switch.
.macro reg_save base
sw ra, 0(\base)
sw sp, 4(\base)
sw t0, 16(\base)
sw t1, 20(\base)
sw t2, 24(\base)
sw s0, 28(\base)
sw s1, 32(\base)
sw a0, 36(\base)
sw a1, 40(\base)
sw a2, 44(\base)
sw a3, 48(\base)
sw a4, 52(\base)
sw a5, 56(\base)
sw a6, 60(\base)
sw a7, 64(\base)
sw s2, 68(\base)
sw s3, 72(\base)
sw s4, 76(\base)
sw s5, 80(\base)
sw s6, 84(\base)
sw s7, 88(\base)
sw s8, 92(\base)
sw s9, 96(\base)
sw s10, 100(\base)
sw s11, 104(\base)
sw t3, 108(\base)
sw t4, 112(\base)
sw t5, 116(\base)
STORE ra, 0*SIZE_REG(\base)
STORE sp, 1*SIZE_REG(\base)
STORE t0, 4*SIZE_REG(\base)
STORE t1, 5*SIZE_REG(\base)
STORE t2, 6*SIZE_REG(\base)
STORE s0, 7*SIZE_REG(\base)
STORE s1, 8*SIZE_REG(\base)
STORE a0, 9*SIZE_REG(\base)
STORE a1, 10*SIZE_REG(\base)
STORE a2, 11*SIZE_REG(\base)
STORE a3, 12*SIZE_REG(\base)
STORE a4, 13*SIZE_REG(\base)
STORE a5, 14*SIZE_REG(\base)
STORE a6, 15*SIZE_REG(\base)
STORE a7, 16*SIZE_REG(\base)
STORE s2, 17*SIZE_REG(\base)
STORE s3, 18*SIZE_REG(\base)
STORE s4, 19*SIZE_REG(\base)
STORE s5, 20*SIZE_REG(\base)
STORE s6, 21*SIZE_REG(\base)
STORE s7, 22*SIZE_REG(\base)
STORE s8, 23*SIZE_REG(\base)
STORE s9, 24*SIZE_REG(\base)
STORE s10, 25*SIZE_REG(\base)
STORE s11, 26*SIZE_REG(\base)
STORE t3, 27*SIZE_REG(\base)
STORE t4, 28*SIZE_REG(\base)
STORE t5, 29*SIZE_REG(\base)
# we don't save t6 here, due to we have used
# it as base, we have to save t6 in an extra step
# outside of reg_save
@@ -49,35 +53,35 @@
# ra = base->ra;
# ......
.macro reg_restore base
lw ra, 0(\base)
lw sp, 4(\base)
lw t0, 16(\base)
lw t1, 20(\base)
lw t2, 24(\base)
lw s0, 28(\base)
lw s1, 32(\base)
lw a0, 36(\base)
lw a1, 40(\base)
lw a2, 44(\base)
lw a3, 48(\base)
lw a4, 52(\base)
lw a5, 56(\base)
lw a6, 60(\base)
lw a7, 64(\base)
lw s2, 68(\base)
lw s3, 72(\base)
lw s4, 76(\base)
lw s5, 80(\base)
lw s6, 84(\base)
lw s7, 88(\base)
lw s8, 92(\base)
lw s9, 96(\base)
lw s10, 100(\base)
lw s11, 104(\base)
lw t3, 108(\base)
lw t4, 112(\base)
lw t5, 116(\base)
lw t6, 120(\base)
LOAD ra, 0*SIZE_REG(\base)
LOAD sp, 1*SIZE_REG(\base)
LOAD t0, 4*SIZE_REG(\base)
LOAD t1, 5*SIZE_REG(\base)
LOAD t2, 6*SIZE_REG(\base)
LOAD s0, 7*SIZE_REG(\base)
LOAD s1, 8*SIZE_REG(\base)
LOAD a0, 9*SIZE_REG(\base)
LOAD a1, 10*SIZE_REG(\base)
LOAD a2, 11*SIZE_REG(\base)
LOAD a3, 12*SIZE_REG(\base)
LOAD a4, 13*SIZE_REG(\base)
LOAD a5, 14*SIZE_REG(\base)
LOAD a6, 15*SIZE_REG(\base)
LOAD a7, 16*SIZE_REG(\base)
LOAD s2, 17*SIZE_REG(\base)
LOAD s3, 18*SIZE_REG(\base)
LOAD s4, 19*SIZE_REG(\base)
LOAD s5, 20*SIZE_REG(\base)
LOAD s6, 21*SIZE_REG(\base)
LOAD s7, 22*SIZE_REG(\base)
LOAD s8, 23*SIZE_REG(\base)
LOAD s9, 24*SIZE_REG(\base)
LOAD s10, 25*SIZE_REG(\base)
LOAD s11, 26*SIZE_REG(\base)
LOAD t3, 27*SIZE_REG(\base)
LOAD t4, 28*SIZE_REG(\base)
LOAD t5, 29*SIZE_REG(\base)
LOAD t6, 30*SIZE_REG(\base)
.endm
# Something to note about save/restore:
@@ -100,13 +104,13 @@ trap_vector:
# Save the actual t6 register, which we swapped into
# mscratch
mv t5, t6 # t5 points to the context of current task
csrr t6, mscratch # read t6 back from mscratch
sw t6, 120(t5) # save t6 with t5 as base
mv t5, t6 # t5 points to the context of current task
csrr t6, mscratch # read t6 back from mscratch
STORE t6, 30*SIZE_REG(t5) # save t6 with t5 as base
# save mepc to context of current task
csrr a0, mepc
sw a0, 124(t5)
STORE a0, 31*SIZE_REG(t5)
# Restore the context pointer into mscratch
csrw mscratch, t5
@@ -135,7 +139,7 @@ switch_to:
# switch mscratch to point to the context of the next task
csrw mscratch, a0
# set mepc to the pc of the next task
lw a1, 124(a0)
LOAD a1, 31*SIZE_REG(a0)
csrw mepc, a1
# Restore all GP registers

View File

@@ -1,30 +1,32 @@
#define SIZE_PTR .word
.section .rodata
.global HEAP_START
HEAP_START: .word _heap_start
HEAP_START: SIZE_PTR _heap_start
.global HEAP_SIZE
HEAP_SIZE: .word _heap_size
HEAP_SIZE: SIZE_PTR _heap_size
.global TEXT_START
TEXT_START: .word _text_start
TEXT_START: SIZE_PTR _text_start
.global TEXT_END
TEXT_END: .word _text_end
TEXT_END: SIZE_PTR _text_end
.global DATA_START
DATA_START: .word _data_start
DATA_START: SIZE_PTR _data_start
.global DATA_END
DATA_END: .word _data_end
DATA_END: SIZE_PTR _data_end
.global RODATA_START
RODATA_START: .word _rodata_start
RODATA_START: SIZE_PTR _rodata_start
.global RODATA_END
RODATA_END: .word _rodata_end
RODATA_END: SIZE_PTR _rodata_end
.global BSS_START
BSS_START: .word _bss_start
BSS_START: SIZE_PTR _bss_start
.global BSS_END
BSS_END: .word _bss_end
BSS_END: SIZE_PTR _bss_end

View File

@@ -58,7 +58,7 @@ struct context {
// upon is trap frame
// save the pc to run in next schedule cycle
reg_t pc; // offset: 31 *4 = 124
reg_t pc; // offset: 31 * sizeof(reg_t)
};
extern int task_create(void (*task)(void));

View File

@@ -3,24 +3,24 @@
/*
* Following global vars are defined in mem.S
*/
extern uint32_t TEXT_START;
extern uint32_t TEXT_END;
extern uint32_t DATA_START;
extern uint32_t DATA_END;
extern uint32_t RODATA_START;
extern uint32_t RODATA_END;
extern uint32_t BSS_START;
extern uint32_t BSS_END;
extern uint32_t HEAP_START;
extern uint32_t HEAP_SIZE;
extern ptr_t TEXT_START;
extern ptr_t TEXT_END;
extern ptr_t DATA_START;
extern ptr_t DATA_END;
extern ptr_t RODATA_START;
extern ptr_t RODATA_END;
extern ptr_t BSS_START;
extern ptr_t BSS_END;
extern ptr_t HEAP_START;
extern ptr_t HEAP_SIZE;
/*
* _alloc_start points to the actual start address of heap pool
* _alloc_end points to the actual end address of heap pool
* _num_pages holds the actual max number of pages we can allocate.
*/
static uint32_t _alloc_start = 0;
static uint32_t _alloc_end = 0;
static ptr_t _alloc_start = 0;
static ptr_t _alloc_end = 0;
static uint32_t _num_pages = 0;
#define PAGE_SIZE 4096
@@ -70,9 +70,9 @@ static inline int _is_last(struct Page *page)
/*
* align the address to the border of page(4K)
*/
static inline uint32_t _align_page(uint32_t address)
static inline ptr_t _align_page(ptr_t address)
{
uint32_t order = (1 << PAGE_ORDER) - 1;
ptr_t order = (1 << PAGE_ORDER) - 1;
return (address + order) & (~order);
}
@@ -155,12 +155,12 @@ void page_free(void *p)
/*
* Assert (TBD) if p is invalid
*/
if (!p || (uint32_t)p >= _alloc_end) {
if (!p || (ptr_t)p >= _alloc_end) {
return;
}
/* get the first page descriptor of this memory block */
struct Page *page = (struct Page *)HEAP_START;
page += ((uint32_t)p - _alloc_start)/ PAGE_SIZE;
page += ((ptr_t)p - _alloc_start)/ PAGE_SIZE;
/* loop and clear all the page descriptors of the memory block */
while (!_is_free(page)) {
if (_is_last(page)) {

View File

@@ -92,6 +92,10 @@ static inline void w_mie(reg_t x)
asm volatile("csrw mie, %0" : : "r" (x));
}
/* Machine-mode Cause Masks */
#define MCAUSE_MASK_INTERRUPT (reg_t)0x80000000
#define MCAUSE_MASK_ECODE (reg_t)0x7FFFFFFF
static inline reg_t r_mcause()
{
reg_t x;

View File

@@ -32,9 +32,9 @@ void external_interrupt_handler()
reg_t trap_handler(reg_t epc, reg_t cause, struct context *cxt)
{
reg_t return_pc = epc;
reg_t cause_code = cause & 0xfff;
reg_t cause_code = cause & MCAUSE_MASK_ECODE;
if (cause & 0x80000000) {
if (cause & MCAUSE_MASK_INTERRUPT) {
/* Asynchronous trap - interrupt */
switch (cause_code) {
case 3:

View File

@@ -7,8 +7,9 @@ typedef unsigned int uint32_t;
typedef unsigned long long uint64_t;
/*
* RISCV32: register is 32bits width
*/
* Register Width
*/
typedef uint32_t reg_t;
typedef uint32_t ptr_t;
#endif /* __TYPES_H__ */

View File

@@ -8,7 +8,8 @@ include ../defines.mk
DEFS +=
CROSS_COMPILE = riscv64-unknown-elf-
CFLAGS += -nostdlib -fno-builtin -march=rv32g -mabi=ilp32 -g -Wall
CFLAGS += -nostdlib -fno-builtin -g -Wall
CFLAGS += -march=rv32g -mabi=ilp32
LDFLAGS ?= -T os.ld
QEMU = qemu-system-riscv32