diff options
-rw-r--r-- | Makefile.in | 6 | ||||
-rw-r--r-- | bbl/bbl.ac | 4 | ||||
-rw-r--r-- | bbl/bbl.c | 17 | ||||
-rw-r--r-- | bbl/bbl.h | 1 | ||||
-rw-r--r-- | bbl/bbl.lds | 4 | ||||
-rw-r--r-- | bbl/bbl.mk.in | 6 | ||||
-rw-r--r-- | bbl/kernel_elf.c | 50 | ||||
-rw-r--r-- | bbl/payload.S | 10 | ||||
-rwxr-xr-x | configure | 204 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | machine/htif.c | 54 | ||||
-rw-r--r-- | machine/mentry.S | 11 | ||||
-rw-r--r-- | machine/minit.c | 8 | ||||
-rw-r--r-- | machine/mtrap.h | 1 | ||||
-rw-r--r-- | pk/mmap.c | 12 | ||||
-rw-r--r-- | pk/mmap.h | 1 | ||||
-rw-r--r-- | pk/pk.lds | 4 |
17 files changed, 277 insertions, 118 deletions
diff --git a/Makefile.in b/Makefile.in index b2aca28..7b9bb81 100644 --- a/Makefile.in +++ b/Makefile.in @@ -35,7 +35,6 @@ default : all project_name := @PACKAGE_TARNAME@ src_dir := @srcdir@ scripts_dir := $(src_dir)/scripts -bbl_payload := @BBL_PAYLOAD@ # If the version information is not in the configure script, then we # assume that we are in a working directory. We use the vcs-version.sh @@ -84,7 +83,10 @@ VPATH := $(addprefix $(src_dir)/, $(sprojs_enabled)) # - CXXFLAGS : flags for C++ compiler (eg. -Wall,-g,-O3) CC := @CC@ -CFLAGS := @CFLAGS@ $(CFLAGS) -DBBL_PAYLOAD=\"$(bbl_payload)\" +READELF := @READELF@ +OBJCOPY := @OBJCOPY@ +CFLAGS := @CFLAGS@ $(CFLAGS) -DBBL_PAYLOAD=\"bbl_payload\" +BBL_PAYLOAD := @BBL_PAYLOAD@ COMPILE := $(CC) -MMD -MP $(CFLAGS) \ $(sprojs_include) # Linker @@ -1,5 +1,5 @@ -AC_ARG_ENABLE([logo], AS_HELP_STRING([--disable-logo], [Disable boot logo])) -AS_IF([test "x$enable_logo" != "xno"], [ +AC_ARG_ENABLE([logo], AS_HELP_STRING([--enable-logo], [Enable boot logo])) +AS_IF([test "x$enable_logo" == "xyes"], [ AC_DEFINE([PK_ENABLE_LOGO],,[Define if the RISC-V logo is to be displayed]) ]) @@ -6,24 +6,25 @@ #include "config.h" #include <string.h> -static volatile uintptr_t entry_point; +static const void* entry_point; void boot_other_hart() { - while (!entry_point) - ; - mb(); - enter_supervisor_mode((void *)entry_point, read_csr(mhartid), 0); + const void* entry; + do { + entry = entry_point; + mb(); + } while (!entry); + enter_supervisor_mode(entry, read_csr(mhartid), 0); } void boot_loader() { - extern char _payload_start, _payload_end; - uintptr_t entry = load_kernel_elf(&_payload_start, &_payload_end - &_payload_start); + extern char _payload_start; #ifdef PK_ENABLE_LOGO print_logo(); #endif mb(); - entry_point = entry; + entry_point = &_payload_start; boot_other_hart(); } @@ -8,7 +8,6 @@ #include <stdint.h> #include <stddef.h> -uintptr_t load_kernel_elf(void* blob, size_t size); void print_logo(); #endif // !__ASSEMBLER__ diff --git a/bbl/bbl.lds b/bbl/bbl.lds index 6833e47..b90e99f 100644 --- a/bbl/bbl.lds +++ b/bbl/bbl.lds @@ -44,9 +44,9 @@ SECTIONS /* HTIF, isolated onto separate page */ /*--------------------------------------------------------------------*/ . = ALIGN(0x1000); - htif : + .htif : { - *(htif) + *(.htif) } . = ALIGN(0x1000); diff --git a/bbl/bbl.mk.in b/bbl/bbl.mk.in index 1bb4cd1..5abe2cd 100644 --- a/bbl/bbl.mk.in +++ b/bbl/bbl.mk.in @@ -8,13 +8,15 @@ bbl_hdrs = \ bbl.h \ bbl_c_srcs = \ - kernel_elf.c \ logo.c \ bbl_asm_srcs = \ payload.S \ -payload.o: $(bbl_payload) +payload.o: bbl_payload + +bbl_payload: $(BBL_PAYLOAD) + if $(READELF) -h $< 2> /dev/null > /dev/null; then $(OBJCOPY) -O binary $< $@; else cp $< $@; fi bbl_test_srcs = diff --git a/bbl/kernel_elf.c b/bbl/kernel_elf.c deleted file mode 100644 index 096a690..0000000 --- a/bbl/kernel_elf.c +++ /dev/null @@ -1,50 +0,0 @@ -// See LICENSE for license details. - -#include "mtrap.h" -#include "bbl.h" -#include "bits.h" -#include "vm.h" -#include <elf.h> -#include <string.h> - -uintptr_t load_kernel_elf(void* blob, size_t size) -{ - Elf_Ehdr* eh = blob; - if (sizeof(*eh) > size || - !(eh->e_ident[0] == '\177' && eh->e_ident[1] == 'E' && - eh->e_ident[2] == 'L' && eh->e_ident[3] == 'F')) - goto fail; - - if (IS_ELF64(*eh) != (sizeof(uintptr_t) == 8)) - goto fail; - - uintptr_t min_vaddr = -1, max_vaddr = 0; - size_t phdr_size = eh->e_phnum * sizeof(Elf_Ehdr); - Elf_Phdr* ph = blob + eh->e_phoff; - if (eh->e_phoff + phdr_size > size) - goto fail; - first_free_paddr = ROUNDUP(first_free_paddr, MEGAPAGE_SIZE); - for (int i = 0; i < eh->e_phnum; i++) - if (ph[i].p_type == PT_LOAD && ph[i].p_memsz && ph[i].p_vaddr < min_vaddr) - min_vaddr = ph[i].p_vaddr; - min_vaddr = ROUNDDOWN(min_vaddr, MEGAPAGE_SIZE); - uintptr_t bias = first_free_paddr - min_vaddr; - for (int i = eh->e_phnum - 1; i >= 0; i--) { - if(ph[i].p_type == PT_LOAD && ph[i].p_memsz) { - uintptr_t prepad = ph[i].p_vaddr % RISCV_PGSIZE; - uintptr_t vaddr = ph[i].p_vaddr + bias; - if (vaddr + ph[i].p_memsz > max_vaddr) - max_vaddr = vaddr + ph[i].p_memsz; - if (ph[i].p_offset + ph[i].p_filesz > size) - goto fail; - memcpy((void*)vaddr, blob + ph[i].p_offset, ph[i].p_filesz); - memset((void*)vaddr - prepad, 0, prepad); - memset((void*)vaddr + ph[i].p_filesz, 0, ph[i].p_memsz - ph[i].p_filesz); - } - } - - return eh->e_entry + bias; - -fail: - die("failed to load payload"); -} diff --git a/bbl/payload.S b/bbl/payload.S index 7ff1e58..6a175aa 100644 --- a/bbl/payload.S +++ b/bbl/payload.S @@ -1,7 +1,9 @@ -.section ".payload","a",@progbits -.align 3 +#include "encoding.h" -.globl _payload_start, _payload_end + .section ".payload","a",@progbits + .align RISCV_PGSHIFT + RISCV_PGLEVEL_BITS + + .globl _payload_start, _payload_end _payload_start: -.incbin BBL_PAYLOAD + .incbin BBL_PAYLOAD _payload_end: @@ -603,6 +603,8 @@ INSTALL_PROGRAM STOW_PREFIX STOW_ROOT enable_stow +OBJCOPY +READELF RANLIB AR ac_ct_CXX @@ -642,6 +644,7 @@ infodir docdir oldincludedir includedir +runstatedir localstatedir sharedstatedir sysconfdir @@ -725,6 +728,7 @@ datadir='${datarootdir}' sysconfdir='${prefix}/etc' sharedstatedir='${prefix}/com' localstatedir='${prefix}/var' +runstatedir='${localstatedir}/run' includedir='${prefix}/include' oldincludedir='/usr/include' docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' @@ -977,6 +981,15 @@ do | -silent | --silent | --silen | --sile | --sil) silent=yes ;; + -runstatedir | --runstatedir | --runstatedi | --runstated \ + | --runstate | --runstat | --runsta | --runst | --runs \ + | --run | --ru | --r) + ac_prev=runstatedir ;; + -runstatedir=* | --runstatedir=* | --runstatedi=* | --runstated=* \ + | --runstate=* | --runstat=* | --runsta=* | --runst=* | --runs=* \ + | --run=* | --ru=* | --r=*) + runstatedir=$ac_optarg ;; + -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) ac_prev=sbindir ;; -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ @@ -1114,7 +1127,7 @@ fi for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ datadir sysconfdir sharedstatedir localstatedir includedir \ oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir + libdir localedir mandir runstatedir do eval ac_val=\$$ac_var # Remove trailing slashes. @@ -1267,6 +1280,7 @@ Fine tuning of the installation directories: --sysconfdir=DIR read-only single-machine data [PREFIX/etc] --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] --localstatedir=DIR modifiable single-machine data [PREFIX/var] + --runstatedir=DIR modifiable per-process data [LOCALSTATEDIR/run] --libdir=DIR object code libraries [EPREFIX/lib] --includedir=DIR C header files [PREFIX/include] --oldincludedir=DIR C header files for non-gcc [/usr/include] @@ -1305,7 +1319,7 @@ Optional Features: --enable-optional-subprojects Enable all optional subprojects --disable-vm Disable virtual memory - --disable-logo Disable boot logo + --enable-logo Enable boot logo --disable-fp-emulation Disable floating-point emulation Optional Packages: @@ -3250,6 +3264,190 @@ else RANLIB="$ac_cv_prog_RANLIB" fi +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}readelf", so it can be a program name with args. +set dummy ${ac_tool_prefix}readelf; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_READELF+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$READELF"; then + ac_cv_prog_READELF="$READELF" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_READELF="${ac_tool_prefix}readelf" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +READELF=$ac_cv_prog_READELF +if test -n "$READELF"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $READELF" >&5 +$as_echo "$READELF" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_READELF"; then + ac_ct_READELF=$READELF + # Extract the first word of "readelf", so it can be a program name with args. +set dummy readelf; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_READELF+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_READELF"; then + ac_cv_prog_ac_ct_READELF="$ac_ct_READELF" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_READELF="readelf" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_READELF=$ac_cv_prog_ac_ct_READELF +if test -n "$ac_ct_READELF"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_READELF" >&5 +$as_echo "$ac_ct_READELF" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_READELF" = x; then + READELF="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + READELF=$ac_ct_READELF + fi +else + READELF="$ac_cv_prog_READELF" +fi + +if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}objcopy", so it can be a program name with args. +set dummy ${ac_tool_prefix}objcopy; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_OBJCOPY+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$OBJCOPY"; then + ac_cv_prog_OBJCOPY="$OBJCOPY" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_OBJCOPY="${ac_tool_prefix}objcopy" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +OBJCOPY=$ac_cv_prog_OBJCOPY +if test -n "$OBJCOPY"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJCOPY" >&5 +$as_echo "$OBJCOPY" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_OBJCOPY"; then + ac_ct_OBJCOPY=$OBJCOPY + # Extract the first word of "objcopy", so it can be a program name with args. +set dummy objcopy; ac_word=$2 +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +$as_echo_n "checking for $ac_word... " >&6; } +if ${ac_cv_prog_ac_ct_OBJCOPY+:} false; then : + $as_echo_n "(cached) " >&6 +else + if test -n "$ac_ct_OBJCOPY"; then + ac_cv_prog_ac_ct_OBJCOPY="$ac_ct_OBJCOPY" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + test -z "$as_dir" && as_dir=. + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_OBJCOPY="objcopy" + $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_OBJCOPY=$ac_cv_prog_ac_ct_OBJCOPY +if test -n "$ac_ct_OBJCOPY"; then + { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJCOPY" >&5 +$as_echo "$ac_ct_OBJCOPY" >&6; } +else + { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 +$as_echo "no" >&6; } +fi + + if test "x$ac_ct_OBJCOPY" = x; then + OBJCOPY="" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + OBJCOPY=$ac_ct_OBJCOPY + fi +else + OBJCOPY="$ac_cv_prog_OBJCOPY" +fi + #------------------------------------------------------------------------- # MCPPBS specific program checks @@ -4020,7 +4218,7 @@ if test "${enable_logo+set}" = set; then : enableval=$enable_logo; fi -if test "x$enable_logo" != "xno"; then : +if test "x$enable_logo" == "xyes"; then : $as_echo "#define PK_ENABLE_LOGO /**/" >>confdefs.h diff --git a/configure.ac b/configure.ac index 1bf0326..b4a58fd 100644 --- a/configure.ac +++ b/configure.ac @@ -50,6 +50,8 @@ AC_PROG_CC AC_PROG_CXX AC_CHECK_TOOL([AR],[ar]) AC_CHECK_TOOL([RANLIB],[ranlib]) +AC_CHECK_TOOL([READELF],[readelf]) +AC_CHECK_TOOL([OBJCOPY],[objcopy]) #------------------------------------------------------------------------- # MCPPBS specific program checks diff --git a/machine/htif.c b/machine/htif.c index 8b8d69b..fa3db53 100644 --- a/machine/htif.c +++ b/machine/htif.c @@ -2,47 +2,56 @@ #include "atomic.h" #include "mtrap.h" -volatile uint64_t tohost __attribute__((section("htif"))); -volatile uint64_t fromhost __attribute__((section("htif"))); +volatile uint64_t tohost __attribute__((section(".htif"))); +volatile uint64_t fromhost __attribute__((section(".htif"))); volatile int htif_console_buf; static spinlock_t htif_lock = SPINLOCK_INIT; -static void request_htif_keyboard_interrupt() -{ - assert(tohost == 0); - tohost = TOHOST_CMD(1, 0, 0); -} - static void __check_fromhost() { - // we should only be interrupted by keypresses uint64_t fh = fromhost; if (!fh) return; - assert(FROMHOST_DEV(fh) == 1 && FROMHOST_CMD(fh) == 0); - htif_console_buf = 1 + (uint8_t)FROMHOST_DATA(fh); fromhost = 0; + + // this should be from the console + assert(FROMHOST_DEV(fh) == 1); + switch (FROMHOST_CMD(fh)) { + case 0: + htif_console_buf = 1 + (uint8_t)FROMHOST_DATA(fh); + break; + case 1: + break; + default: + assert(0); + } +} + +static void __set_tohost(uintptr_t dev, uintptr_t cmd, uintptr_t data) +{ + while (tohost) + __check_fromhost(); + tohost = TOHOST_CMD(dev, cmd, data); } int htif_console_getchar() { - if (spinlock_trylock(&htif_lock) == 0) { + spinlock_lock(&htif_lock); __check_fromhost(); - spinlock_unlock(&htif_lock); - } + int ch = htif_console_buf; + if (ch >= 0) { + htif_console_buf = -1; + __set_tohost(1, 0, 0); + } + spinlock_unlock(&htif_lock); - int ch = atomic_swap(&htif_console_buf, -1); - if (ch >= 0) - request_htif_keyboard_interrupt(); return ch - 1; } static void do_tohost_fromhost(uintptr_t dev, uintptr_t cmd, uintptr_t data) { spinlock_lock(&htif_lock); - while (tohost) - __check_fromhost(); - tohost = TOHOST_CMD(dev, cmd, data); + __set_tohost(dev, cmd, data); while (1) { uint64_t fh = fromhost; @@ -53,7 +62,6 @@ static void do_tohost_fromhost(uintptr_t dev, uintptr_t cmd, uintptr_t data) } __check_fromhost(); } - wfi(); } spinlock_unlock(&htif_lock); } @@ -65,7 +73,9 @@ void htif_syscall(uintptr_t arg) void htif_console_putchar(uint8_t ch) { - do_tohost_fromhost(1, 1, ch); + spinlock_lock(&htif_lock); + __set_tohost(1, 1, ch); + spinlock_unlock(&htif_lock); } void htif_poweroff() diff --git a/machine/mentry.S b/machine/mentry.S index 5ff5c68..01db536 100644 --- a/machine/mentry.S +++ b/machine/mentry.S @@ -247,11 +247,7 @@ do_reset: csrr t1, mtvec 1:bne t0, t1, 1b - # sp <- end of first full page after the end of the binary - la sp, _end + 2*RISCV_PGSIZE - 1 - li t0, -RISCV_PGSIZE - and sp, sp, t0 - addi sp, sp, -MENTRY_FRAME_SIZE + la sp, stacks + RISCV_PGSIZE - MENTRY_FRAME_SIZE csrr a0, mhartid slli a1, a0, RISCV_PGSHIFT @@ -278,3 +274,8 @@ do_reset: #endif wfi j .LmultiHart + + .bss + .align RISCV_PGSHIFT +stacks: + .skip RISCV_PGSIZE * MAX_HARTS diff --git a/machine/minit.c b/machine/minit.c index 0c95ea4..e84f6d9 100644 --- a/machine/minit.c +++ b/machine/minit.c @@ -6,7 +6,6 @@ #include <limits.h> pte_t* root_page_table; -uintptr_t first_free_paddr; uintptr_t mem_size; uintptr_t num_harts; volatile uint64_t* mtime; @@ -67,16 +66,9 @@ hls_t* hls_init(uintptr_t id) return hls; } -static uintptr_t sbi_top_paddr() -{ - extern char _end; - return ROUNDUP((uintptr_t)&_end, RISCV_PGSIZE); -} - static void memory_init() { mem_size = mem_size / MEGAPAGE_SIZE * MEGAPAGE_SIZE; - first_free_paddr = sbi_top_paddr() + num_harts * RISCV_PGSIZE; } static void hart_init() diff --git a/machine/mtrap.h b/machine/mtrap.h index 3700a6d..2f0fc69 100644 --- a/machine/mtrap.h +++ b/machine/mtrap.h @@ -28,7 +28,6 @@ static inline int xlen() return read_const_csr(misa) < 0 ? 64 : 32; } -extern uintptr_t first_free_paddr; extern uintptr_t mem_size; extern uintptr_t num_harts; extern volatile uint64_t* mtime; @@ -20,6 +20,7 @@ typedef struct { static spinlock_t vm_lock = SPINLOCK_INIT; static vmr_t* vmrs; +uintptr_t first_free_paddr; static uintptr_t first_free_page; static size_t next_free_page; static size_t free_pages; @@ -385,15 +386,14 @@ void populate_mapping(const void* start, size_t size, int prot) uintptr_t pk_vm_init() { -#if __riscv_xlen == 32 - // We can't support more than 2 GiB of memory in RV32 + // HTIF address signedness and va2pa macro both cap memory size to 2 GiB mem_size = MIN(mem_size, 1U << 31); -#endif - size_t mem_pages = mem_size >> RISCV_PGSHIFT; free_pages = MAX(8, mem_pages >> (RISCV_PGLEVEL_BITS-1)); - first_free_page = first_free_paddr; - first_free_paddr += free_pages * RISCV_PGSIZE; + + extern char _end; + first_free_page = ROUNDUP((uintptr_t)&_end, RISCV_PGSIZE); + first_free_paddr = first_free_page + free_pages * RISCV_PGSIZE; root_page_table = (void*)__page_alloc(); __map_kernel_range(DRAM_BASE, DRAM_BASE, first_free_paddr - DRAM_BASE, PROT_READ|PROT_WRITE|PROT_EXEC); @@ -33,6 +33,7 @@ uintptr_t do_mprotect(uintptr_t addr, size_t length, int prot); uintptr_t do_brk(uintptr_t addr); #define va2pa(va) ({ uintptr_t __va = (uintptr_t)(va); \ + extern uintptr_t first_free_paddr; \ __va >= DRAM_BASE ? __va : __va + first_free_paddr; }) #endif @@ -44,9 +44,9 @@ SECTIONS /* HTIF, isolated onto separate page */ /*--------------------------------------------------------------------*/ . = ALIGN(0x1000); - htif : + .htif : { - *(htif) + *(.htif) } . = ALIGN(0x1000); |