init commit of lab2_challenge3

lab2_challenge3_multicoremem
liguo 9 months ago
parent 5b9d0b55ea
commit c4427c64d2

@ -20,7 +20,7 @@ ifneq (,)
mabi := -mabi=$(if $(is_32bit),ilp32,lp64)
endif
CFLAGS := -Wall -Werror -fno-builtin -nostdlib -D__NO_INLINE__ -mcmodel=medany -g -Og -std=gnu99 -Wno-unused -Wno-attributes -fno-delete-null-pointer-checks -fno-PIE $(march)
CFLAGS := -Wall -Werror -fno-builtin -nostdlib -D__NO_INLINE__ -mcmodel=medany -g -O0 -std=gnu99 -Wno-unused -Wno-attributes -fno-delete-null-pointer-checks -fno-PIE $(march)
COMPILE := $(CC) -MMD -MP $(CFLAGS) $(SPROJS_INCLUDE)
#--------------------- utils -----------------------
@ -63,21 +63,24 @@ SPIKE_INF_LIB := $(OBJ_DIR)/spike_interface.a
#--------------------- user -----------------------
USER_CPPS := user/*.c
USER_CPP0 := user/app_alloc0.c user/user_lib.c
USER_CPP1 := user/app_alloc1.c user/user_lib.c
USER_CPPS := $(wildcard $(USER_CPPS))
USER_OBJS := $(addprefix $(OBJ_DIR)/, $(patsubst %.c,%.o,$(USER_CPPS)))
USER_CPP0 := $(wildcard $(USER_CPP0))
USER_CPP1 := $(wildcard $(USER_CPP1))
USER_OBJ0 := $(addprefix $(OBJ_DIR)/, $(patsubst %.c,%.o,$(USER_CPP0)))
USER_OBJ1 := $(addprefix $(OBJ_DIR)/, $(patsubst %.c,%.o,$(USER_CPP1)))
USER_TARGET := $(OBJ_DIR)/app_sum_sequence
USER_TARGET0 := $(OBJ_DIR)/app_alloc0
USER_TARGET1 := $(OBJ_DIR)/app_alloc1
#------------------------targets------------------------
$(OBJ_DIR):
@-mkdir -p $(OBJ_DIR)
@-mkdir -p $(dir $(UTIL_OBJS))
@-mkdir -p $(dir $(SPIKE_INF_OBJS))
@-mkdir -p $(dir $(KERNEL_OBJS))
@-mkdir -p $(dir $(USER_OBJS))
@-mkdir -p $(dir $(USER_OBJ0))
@-mkdir -p $(dir $(USER_OBJ1))
$(OBJ_DIR)/%.o : %.c
@echo "compiling" $<
@ -102,9 +105,14 @@ $(KERNEL_TARGET): $(OBJ_DIR) $(UTIL_LIB) $(SPIKE_INF_LIB) $(KERNEL_OBJS) $(KERNE
@$(COMPILE) $(KERNEL_OBJS) $(UTIL_LIB) $(SPIKE_INF_LIB) -o $@ -T $(KERNEL_LDS)
@echo "PKE core has been built into" \"$@\"
$(USER_TARGET): $(OBJ_DIR) $(UTIL_LIB) $(USER_OBJS)
$(USER_TARGET0): $(OBJ_DIR) $(UTIL_LIB) $(USER_OBJ0)
@echo "linking" $@ ...
@$(COMPILE) --entry=main $(USER_OBJ0) $(UTIL_LIB) -o $@
@echo "User app has been built into" \"$@\"
$(USER_TARGET1): $(OBJ_DIR) $(UTIL_LIB) $(USER_OBJ1)
@echo "linking" $@ ...
@$(COMPILE) --entry=main $(USER_OBJS) $(UTIL_LIB) -o $@
@$(COMPILE) --entry=main $(USER_OBJ1) $(UTIL_LIB) -o $@
@echo "User app has been built into" \"$@\"
-include $(wildcard $(OBJ_DIR)/*/*.d)
@ -112,16 +120,16 @@ $(USER_TARGET): $(OBJ_DIR) $(UTIL_LIB) $(USER_OBJS)
.DEFAULT_GOAL := $(all)
all: $(KERNEL_TARGET) $(USER_TARGET)
all: $(KERNEL_TARGET) $(USER_TARGET0) $(USER_TARGET1)
.PHONY:all
run: $(KERNEL_TARGET) $(USER_TARGET)
run: $(KERNEL_TARGET) $(USER_TARGET0) $(USER_TARGET1)
@echo "********************HUST PKE********************"
spike $(KERNEL_TARGET) $(USER_TARGET)
spike -p2 $(KERNEL_TARGET) $(USER_TARGET0) $(USER_TARGET1)
# need openocd!
gdb:$(KERNEL_TARGET) $(USER_TARGET)
spike --rbb-port=9824 -H $(KERNEL_TARGET) $(USER_TARGET) &
gdb:$(KERNEL_TARGET) $(USER_TARGET0) $(USER_TARGET1)
spike --rbb-port=9824 -H -p2 $(KERNEL_TARGET) $(USER_TARGET0) $(USER_TARGET1) &
@sleep 1
openocd -f ./.spike.cfg &
@sleep 1
@ -135,7 +143,8 @@ gdb_clean:
objdump:
riscv64-unknown-elf-objdump -d $(KERNEL_TARGET) > $(OBJ_DIR)/kernel_dump
riscv64-unknown-elf-objdump -d $(USER_TARGET) > $(OBJ_DIR)/user_dump
riscv64-unknown-elf-objdump -d $(USER_TARGET0) > $(OBJ_DIR)/app_alloc0_dump
riscv64-unknown-elf-objdump -d $(USER_TARGET1) > $(OBJ_DIR)/app_alloc1_dump
cscope:
find ./ -name "*.c" > cscope.files

@ -1,8 +1,8 @@
#ifndef _CONFIG_H_
#define _CONFIG_H_
// we use only one HART (cpu) in fundamental experiments
#define NCPU 1
// we use two HART (cpu) in challenge3
#define NCPU 2
//interval of timer interrupt. added @lab1_3
#define TIMER_INTERVAL 1000000

@ -123,7 +123,7 @@ void load_bincode_from_host_elf(process *p) {
size_t argc = parse_args(&arg_bug_msg);
if (!argc) panic("You need to specify the application program!\n");
sprint("Application: %s\n", arg_bug_msg.argv[0]);
sprint("hartid = ?: Application: %s\n", arg_bug_msg.argv[0]);
//elf loading. elf_ctx is defined in kernel/elf.h, used to track the loading process.
elf_ctx elfloader;
@ -148,5 +148,5 @@ void load_bincode_from_host_elf(process *p) {
// close the host spike file
spike_file_close( info.f );
sprint("Application program entry point (virtual address): 0x%lx\n", p->trapframe->epc);
sprint("hartid = ?: Application program entry point (virtual address): 0x%lx\n", p->trapframe->epc);
}

@ -52,7 +52,7 @@ void load_user_program(process *proc) {
// USER_STACK_TOP = 0x7ffff000, defined in kernel/memlayout.h
proc->trapframe->regs.sp = USER_STACK_TOP; //virtual address of user stack top
sprint("user frame 0x%lx, user stack 0x%lx, user kstack 0x%lx \n", proc->trapframe,
sprint("hartid = ?: user frame 0x%lx, user stack 0x%lx, user kstack 0x%lx \n", proc->trapframe,
proc->trapframe->regs.sp, proc->kstack);
// load_bincode_from_host_elf() is defined in kernel/elf.c
@ -77,7 +77,7 @@ void load_user_program(process *proc) {
// s_start: S-mode entry point of riscv-pke OS kernel.
//
int s_start(void) {
sprint("Enter supervisor mode...\n");
sprint("hartid = ?: Enter supervisor mode...\n");
// in the beginning, we use Bare mode (direct) memory mapping as in lab1.
// but now, we are going to switch to the paging mode @lab2_1.
// note, the code still works in Bare mode when calling pmm_init() and kern_vm_init().
@ -97,7 +97,11 @@ int s_start(void) {
// the application code (elf) is first loaded into memory, and then put into execution
load_user_program(&user_app);
sprint("Switch to user mode...\n");
sprint("hartid = ?: Switch to user mode...\n");
uint64 hartid = 0;
vm_alloc_stage[hartid] = 1;
// switch_to() is defined in kernel/process.c
switch_to(&user_app);

@ -16,7 +16,7 @@ static void handle_misaligned_store() { panic("Misaligned AMO!"); }
// added @lab1_3
static void handle_timer() {
int cpuid = 0;
int cpuid = read_csr(mhartid);
// setup the timer fired at next time (TIMER_INTERVAL from now)
*(uint64*)CLINT_MTIMECMP(cpuid) = *(uint64*)CLINT_MTIMECMP(cpuid) + TIMER_INTERVAL;

@ -15,6 +15,7 @@ extern uint64 g_mem_size;
static uint64 free_mem_start_addr; //beginning address of free memory
static uint64 free_mem_end_addr; //end address of free memory (not included)
int vm_alloc_stage[NCPU] = { 0 }; // 0 for kernel alloc, 1 for user alloc
typedef struct node {
struct node *next;
} list_node;
@ -51,8 +52,11 @@ void free_page(void *pa) {
//
void *alloc_page(void) {
list_node *n = g_free_mem_list.next;
uint64 hartid = 0;
if (vm_alloc_stage[hartid]) {
sprint("hartid = %ld: alloc page 0x%x\n", hartid, n);
}
if (n) g_free_mem_list.next = n->next;
return (void *)n;
}

@ -1,6 +1,8 @@
#ifndef _PMM_H_
#define _PMM_H_
#include "config.h"
// Initialize phisical memeory manager
void pmm_init();
// Allocate a free phisical page
@ -8,4 +10,6 @@ void* alloc_page();
// Free an allocated page
void free_page(void* pa);
extern int vm_alloc_stage[NCPU];
#endif

@ -0,0 +1,20 @@
#ifndef _SYNC_UTILS_H_
#define _SYNC_UTILS_H_
static inline void sync_barrier(volatile int *counter, int all) {
int local;
asm volatile("amoadd.w %0, %2, (%1)\n"
: "=r"(local)
: "r"(counter), "r"(1)
: "memory");
if (local + 1 < all) {
do {
asm volatile("lw %0, (%1)\n" : "=r"(local) : "r"(counter) : "memory");
} while (local < all);
}
}
#endif

@ -30,9 +30,10 @@ ssize_t sys_user_print(const char* buf, size_t n) {
// implement the SYS_user_exit syscall
//
ssize_t sys_user_exit(uint64 code) {
sprint("User exit with code:%d.\n", code);
sprint("hartid = ?: User exit with code:%d.\n", code);
// in lab1, PKE considers only one app (one process).
// therefore, shutdown the system when the app calls exit()
sprint("hartid = ?: shutdown with code:%d.\n", code);
shutdown(code);
}
@ -45,7 +46,7 @@ uint64 sys_user_allocate_page() {
g_ufree_page += PGSIZE;
user_vm_map((pagetable_t)current->pagetable, va, PGSIZE, (uint64)pa,
prot_to_type(PROT_WRITE | PROT_READ, 1));
sprint("hartid = ?: vaddr 0x%x is mapped to paddr 0x%x\n", va, pa);
return va;
}

@ -0,0 +1,24 @@
#include "user_lib.h"
#include "util/types.h"
#define N 5
#define BASE 0
int main(void) {
void *p[N];
for (int i = 0; i < N; i++) {
p[i] = naive_malloc();
int *pi = p[i];
*pi = BASE + i;
printu("=== user alloc 0 @ vaddr 0x%x\n", p[i]);
}
for (int i = 0; i < N; i++) {
int *pi = p[i];
printu("=== user0: %d\n", *pi);
naive_free(p[i]);
}
exit(0);
}

@ -0,0 +1,24 @@
#include "user_lib.h"
#include "util/types.h"
#define N 5
#define BASE 5
int main(void) {
void *p[N];
for (int i = 0; i < N; i++) {
p[i] = naive_malloc();
int *pi = p[i];
*pi = BASE + i;
printu(">>> user alloc 1 @ vaddr 0x%x\n", p[i]);
}
for (int i = 0; i < N; i++) {
int *pi = p[i];
printu(">>> user 1: %d\n", *pi);
naive_free(p[i]);
}
exit(0);
}

@ -1,28 +0,0 @@
/*
* The application of lab2_3.
*/
#include "user_lib.h"
#include "util/types.h"
//
// compute the summation of an arithmetic sequence. for a given "n", compute
// result = n + (n-1) + (n-2) + ... + 0
// sum_sequence() calls itself recursively till 0. The recursive call, however,
// may consume more memory (from stack) than a physical 4KB page, leading to a page fault.
// PKE kernel needs to improved to handle such page fault by expanding the stack.
//
uint64 sum_sequence(uint64 n) {
if (n == 0)
return 0;
else
return sum_sequence( n-1 ) + n;
}
int main(void) {
// we need a large enough "n" to trigger pagefaults in the user stack
uint64 n = 1000;
printu("Summation of an arithmetic sequence from 0 to %ld is: %ld \n", n, sum_sequence(1000) );
exit(0);
}
Loading…
Cancel
Save