aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.in6
-rw-r--r--bbl/bbl.ac4
-rw-r--r--bbl/bbl.c17
-rw-r--r--bbl/bbl.h1
-rw-r--r--bbl/bbl.lds4
-rw-r--r--bbl/bbl.mk.in6
-rw-r--r--bbl/kernel_elf.c50
-rw-r--r--bbl/payload.S10
-rwxr-xr-xconfigure204
-rw-r--r--configure.ac2
-rw-r--r--machine/htif.c54
-rw-r--r--machine/mentry.S11
-rw-r--r--machine/minit.c8
-rw-r--r--machine/mtrap.h1
-rw-r--r--pk/mmap.c12
-rw-r--r--pk/mmap.h1
-rw-r--r--pk/pk.lds4
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
diff --git a/bbl/bbl.ac b/bbl/bbl.ac
index 51dcf01..4b6a9f3 100644
--- a/bbl/bbl.ac
+++ b/bbl/bbl.ac
@@ -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])
])
diff --git a/bbl/bbl.c b/bbl/bbl.c
index bdd56ad..9553ddb 100644
--- a/bbl/bbl.c
+++ b/bbl/bbl.c
@@ -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();
}
diff --git a/bbl/bbl.h b/bbl/bbl.h
index 67997b9..c9a02e1 100644
--- a/bbl/bbl.h
+++ b/bbl/bbl.h
@@ -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:
diff --git a/configure b/configure
index 2ca6316..c1b2b73 100755
--- a/configure
+++ b/configure
@@ -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;
diff --git a/pk/mmap.c b/pk/mmap.c
index 9e9be57..33c3da2 100644
--- a/pk/mmap.c
+++ b/pk/mmap.c
@@ -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);
diff --git a/pk/mmap.h b/pk/mmap.h
index f4f39f5..efc7c1e 100644
--- a/pk/mmap.h
+++ b/pk/mmap.h
@@ -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
diff --git a/pk/pk.lds b/pk/pk.lds
index 1bc9adf..5348635 100644
--- a/pk/pk.lds
+++ b/pk/pk.lds
@@ -44,9 +44,9 @@ SECTIONS
/* HTIF, isolated onto separate page */
/*--------------------------------------------------------------------*/
. = ALIGN(0x1000);
- htif :
+ .htif :
{
- *(htif)
+ *(.htif)
}
. = ALIGN(0x1000);