aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.clang-tidy67
-rw-r--r--.gitignore1
-rw-r--r--README.md2
-rw-r--r--arch/arm/arm/faults.c9
-rw-r--r--arch/arm/rules.mk10
-rw-r--r--arch/arm/toolchain.mk20
-rw-r--r--arch/riscv/arch.c5
-rw-r--r--arch/riscv/feature.c222
-rw-r--r--arch/riscv/include/arch/riscv.h3
-rw-r--r--arch/riscv/include/arch/riscv/feature.h62
-rw-r--r--arch/riscv/mmu.cpp4
-rw-r--r--arch/riscv/rules.mk4
-rw-r--r--arch/riscv/time.c13
-rw-r--r--dev/interrupt/arm_gic/arm_gic.c103
-rw-r--r--lib/fdtwalk/fdtwalk.cpp33
-rw-r--r--lib/fdtwalk/helpers.cpp47
-rw-r--r--lib/fdtwalk/include/lib/fdtwalk.h4
-rw-r--r--lk.code-workspace14
-rw-r--r--project/virtual/fs.mk3
-rwxr-xr-xscripts/do-qemuriscv21
20 files changed, 554 insertions, 93 deletions
diff --git a/.clang-tidy b/.clang-tidy
new file mode 100644
index 00000000..66e9452a
--- /dev/null
+++ b/.clang-tidy
@@ -0,0 +1,67 @@
+---
+Checks: >
+ -*,
+ bugprone-*,
+ -bugprone-easily-swappable-parameters,
+
+ clang-diagnostic-*,
+ -clang-diagnostic-unused-command-line-argument,
+
+ google-*,
+ -google-runtime-references,
+ -google-readability-todo,
+ -google-readability-braces-around-statements,
+
+ misc-*,
+ -misc-noexcept*,
+ -misc-unused-parameters,
+ -misc-const-correctness,
+ -misc-include-cleaner,
+
+ modernize-*,
+ -modernize-avoid-c-arrays,
+ -modernize-deprecated-headers,
+ -modernize-raw-string-literal,
+ -modernize-return-braced-init-list,
+ -modernize-use-auto,
+ -modernize-use-equals-delete,
+ -modernize-use-nodiscard,
+ -modernize-use-trailing-return-type,
+
+ performance-*,
+ readability-*,
+ -readability-else-after-return,
+ -readability-function-cognitive-complexity,
+ -readability-identifier-length,
+ -readability-identifier-length,
+ -readability-implicit-bool-conversion,
+ -readability-isolate-declaration,
+ -readability-magic-numbers,
+ -readability-named-parameter,
+ -readability-qualified-auto,
+ -readability-uppercase-literal-suffix,
+
+WarningsAsErrors: false
+FormatStyle: file
+CheckOptions:
+ - key: misc-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic
+ value: '1'
+ - key: modernize-loop-convert.MaxCopySize
+ value: '16'
+ - key: modernize-loop-convert.MinConfidence
+ value: reasonable
+ - key: modernize-loop-convert.NamingStyle
+ value: CamelCase
+ - key: modernize-pass-by-value.IncludeStyle
+ value: llvm
+ - key: modernize-replace-auto-ptr.IncludeStyle
+ value: llvm
+ - key: modernize-use-default-member-init.UseAssignment
+ value: '1'
+ - key: modernize-use-emplace.IgnoreImplicitConstructors
+ value: '1'
+ - key: modernize-use-nullptr.NullMacros
+ value: 'NULL'
+ - key: readability-braces-around-statements.ShortStatementLines
+ value: '2'
+...
diff --git a/.gitignore b/.gitignore
index 8b5e280c..2ef05724 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,3 +14,4 @@ blk.bin
scripts/toolpaths.local
.clangd
.vscode
+.cache
diff --git a/README.md b/README.md
index 51b2d1bb..1e9861f9 100644
--- a/README.md
+++ b/README.md
@@ -42,4 +42,4 @@ arm machine 'virt' emulation. type 'help' for commands.
Note: for ubuntu x86-64:
sudo apt-get install gcc-arm-none-eabi
or fetch a prebuilt toolchain from
-https://newos.org/toolchains/x86_64-elf-13.2.0-Linux-x86_64.tar.xz
+https://newos.org/toolchains/x86_64-elf-14.1.0-Linux-x86_64.tar.xz
diff --git a/arch/arm/arm/faults.c b/arch/arm/arm/faults.c
index 0409ba8e..a1d17446 100644
--- a/arch/arm/arm/faults.c
+++ b/arch/arm/arm/faults.c
@@ -10,6 +10,7 @@
#include <arch/arm.h>
#include <kernel/thread.h>
#include <platform.h>
+#include <stdlib.h>
struct fault_handler_table_entry {
uint32_t pc;
@@ -54,8 +55,12 @@ static void dump_mode_regs(uint32_t spsr, uint32_t svc_r13, uint32_t svc_r14) {
}
if (stack != 0) {
- dprintf(CRITICAL, "bottom of stack at 0x%08x:\n", (unsigned int)stack);
- hexdump((void *)stack, 128);
+ dprintf(CRITICAL, "stack pointer at 0x%08x:\n", (unsigned int)stack);
+
+ /* Avoid crossing page-boundary in case near stack base */
+ const size_t used_stack = PAGE_SIZE - ((unsigned int)stack % PAGE_SIZE);
+
+ hexdump((void *)stack, MIN(used_stack, 128));
}
}
diff --git a/arch/arm/rules.mk b/arch/arm/rules.mk
index 1f4b2b16..53b48cb6 100644
--- a/arch/arm/rules.mk
+++ b/arch/arm/rules.mk
@@ -244,12 +244,14 @@ MODULE_SRCS += \
$(LOCAL_DIR)/arm/cache.c \
$(LOCAL_DIR)/arm/debug.c \
$(LOCAL_DIR)/arm/ops.S \
- $(LOCAL_DIR)/arm/exceptions.S \
$(LOCAL_DIR)/arm/faults.c \
- $(LOCAL_DIR)/arm/fpu.c \
$(LOCAL_DIR)/arm/mmu.c \
$(LOCAL_DIR)/arm/thread.c
+MODULE_FLOAT_SRCS += \
+ $(LOCAL_DIR)/arm/exceptions.S \
+ $(LOCAL_DIR)/arm/fpu.c \
+
MODULE_ARM_OVERRIDE_SRCS := \
$(LOCAL_DIR)/arm/arch.c
@@ -333,8 +335,8 @@ TOOLCHAIN_PREFIX := $(ARCH_$(ARCH)_TOOLCHAIN_PREFIX)
$(info TOOLCHAIN_PREFIX = $(TOOLCHAIN_PREFIX))
ARCH_COMPILEFLAGS += $(ARCH_$(ARCH)_COMPILEFLAGS)
-ARCH_COMPILEFLAGS_NOFLOAT := -mgeneral-regs-only
-ARCH_COMPILEFLAGS_FLOAT :=
+ARCH_COMPILEFLAGS_NOFLOAT :=
+ARCH_COMPILEFLAGS_FLOAT := $(ARCH_$(ARCH)_COMPILEFLAGS_FLOAT)
GLOBAL_COMPILEFLAGS += $(THUMBINTERWORK)
diff --git a/arch/arm/toolchain.mk b/arch/arm/toolchain.mk
index 07f48719..f1e1a458 100644
--- a/arch/arm/toolchain.mk
+++ b/arch/arm/toolchain.mk
@@ -75,33 +75,31 @@ ARCH_arm_COMPILEFLAGS += -mcpu=cortex-m4
endif
ifeq ($(ARM_CPU),cortex-m7-fpu-sp-d16)
# use cortex-m4 for now until better general toolchain support
-ARCH_arm_COMPILEFLAGS += -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp
+ARCH_arm_COMPILEFLAGS += -mcpu=cortex-m4
+ARCH_arm_COMPILEFLAGS_FLOAT += -mfpu=fpv4-sp-d16 -mfloat-abi=softfp
endif
ifeq ($(ARM_CPU),cortex-m4f)
-ARCH_arm_COMPILEFLAGS += -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=softfp
+ARCH_arm_COMPILEFLAGS += -mcpu=cortex-m4
+ARCH_arm_COMPILEFLAGS_FLOAT += -mfpu=fpv4-sp-d16 -mfloat-abi=softfp
endif
ifeq ($(ARM_CPU),cortex-a7)
ARCH_arm_COMPILEFLAGS += -mcpu=$(ARM_CPU)
-ARCH_arm_COMPILEFLAGS += -mfpu=vfpv3 -mfloat-abi=softfp
+ARCH_arm_COMPILEFLAGS_FLOAT += -mfpu=vfpv3 -mfloat-abi=softfp
endif
ifeq ($(ARM_CPU),cortex-a8)
ARCH_arm_COMPILEFLAGS += -mcpu=$(ARM_CPU)
-ARCH_arm_COMPILEFLAGS += -mfpu=neon -mfloat-abi=softfp
+ARCH_arm_COMPILEFLAGS_FLOAT += -mfpu=neon -mfloat-abi=softfp
endif
ifeq ($(ARM_CPU),cortex-a9)
ARCH_arm_COMPILEFLAGS += -mcpu=$(ARM_CPU)
endif
ifeq ($(ARM_CPU),cortex-a9-neon)
ARCH_arm_COMPILEFLAGS += -mcpu=cortex-a9
-# XXX cannot enable neon right now because compiler generates
-# neon code for 64bit integer ops
-ARCH_arm_COMPILEFLAGS += -mfpu=vfpv3 -mfloat-abi=softfp
+ARCH_arm_COMPILEFLAGS_FLOAT += -mfpu=neon -mfloat-abi=softfp
endif
ifeq ($(ARM_CPU),cortex-a15)
ARCH_arm_COMPILEFLAGS += -mcpu=$(ARM_CPU)
-ifneq ($(ARM_WITHOUT_VFP_NEON),true)
-ARCH_arm_COMPILEFLAGS += -mfpu=vfpv3 -mfloat-abi=softfp
-endif
+ARCH_arm_COMPILEFLAGS_FLOAT += -mfpu=neon -mfloat-abi=softfp
endif
ifeq ($(ARM_CPU),arm1136j-s)
ARCH_arm_COMPILEFLAGS += -mcpu=$(ARM_CPU)
@@ -113,7 +111,7 @@ ifeq ($(ARM_CPU),cortex-r4f)
ARCH_arm_COMPILEFLAGS += -march=armv7-r
ARCH_arm_COMPILEFLAGS += -mcpu=$(ARM_CPU)
ARCH_arm_COMPILEFLAGS += -mbig-endian
-ARCH_arm_COMPILEFLAGS += -mfpu=vfpv3-d16 -mfloat-abi=hard
+ARCH_arm_COMPILEFLAGS_FLOAT += -mfpu=vfpv3-d16 -mfloat-abi=hard
GLOBAL_MODULE_LDFLAGS += -EB
endif
ifeq ($(ARM_CPU),armemu)
diff --git a/arch/riscv/arch.c b/arch/riscv/arch.c
index 83d4e224..e1a2bcc1 100644
--- a/arch/riscv/arch.c
+++ b/arch/riscv/arch.c
@@ -18,6 +18,7 @@
#include <platform.h>
#include <arch.h>
+#include "arch/riscv/feature.h"
#include "riscv_priv.h"
#define LOCAL_TRACE 0
@@ -71,6 +72,8 @@ void riscv_early_init_percpu(void) {
void arch_early_init(void) {
riscv_early_init_percpu();
+ riscv_feature_early_init();
+
#if RISCV_S_MODE
sbi_early_init();
#endif
@@ -110,6 +113,8 @@ void arch_init(void) {
riscv_get_mvendorid(), riscv_get_marchid(),
riscv_get_mimpid(), riscv_current_hart());
+ riscv_feature_init();
+
#if RISCV_M_MODE
dprintf(INFO, "RISCV: misa %#lx\n", riscv_csr_read(RISCV_CSR_MISA));
#elif RISCV_S_MODE
diff --git a/arch/riscv/feature.c b/arch/riscv/feature.c
new file mode 100644
index 00000000..e516318d
--- /dev/null
+++ b/arch/riscv/feature.c
@@ -0,0 +1,222 @@
+/*
+ * Copyright (c) 2024 Travis Geiselbrecht
+ *
+ * Use of this source code is governed by a MIT-style
+ * license that can be found in the LICENSE file or at
+ * https://opensource.org/licenses/MIT
+ */
+#include "arch/riscv/feature.h"
+
+#include <lk/trace.h>
+#include <lk/debug.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+
+#define LOCAL_TRACE 0
+
+// Make feature bitmap
+uint32_t riscv_feature_bitmap[ROUNDUP(RISCV_FEAT_COUNT, 32) / 32];
+
+static void set_feature(enum riscv_feature feature) {
+ riscv_feature_bitmap[feature / 32] |= (1U << feature % 32);
+}
+
+// match a one word feature from a known list
+static void match_feature(const char *str, size_t start, size_t end) {
+ const struct {
+ const char *str;
+ enum riscv_feature feat;
+ } oneword[] = {
+ { "zba", RISCV_FEAT_ZBA },
+ { "zbb", RISCV_FEAT_ZBB },
+ { "zbc", RISCV_FEAT_ZBC },
+ { "zbs", RISCV_FEAT_ZBS },
+ { "zicbom", RISCV_FEAT_ZICBOM },
+ { "zicbop", RISCV_FEAT_ZICBOP },
+ { "zicboz", RISCV_FEAT_ZICBOZ },
+ { "sstc", RISCV_FEAT_SSTC },
+ { "svadu", RISCV_FEAT_SVADU },
+ { "zicsr", RISCV_FEAT_ZICSR },
+ { "zifencei", RISCV_FEAT_ZIFENCEI },
+ };
+
+ if (LOCAL_TRACE) {
+ char feat[128];
+ strlcpy(feat, &str[start], end - start + 1);
+ printf("feature '%s'\n", feat);
+ }
+
+ for (size_t i = 0; i < countof(oneword); i++) {
+ if (strlen(oneword[i].str) != end - start)
+ continue;
+
+ if (strncasecmp(oneword[i].str, &str[start], end - start) == 0) {
+ dprintf(INFO, "riscv: found feature '%s'\n", oneword[i].str);
+ set_feature(oneword[i].feat);
+ }
+ }
+}
+
+void riscv_set_isa_string(const char *str) {
+ LTRACEF("%s\n", str);
+
+ const size_t slen = strlen(str);
+
+ // Handle simple features first.
+ // Feature string must start with either 'rv64' or 'rv32' followed by
+ // one or more one character features until _ or null.
+ if (slen < 4 || str[0] != 'r' || str[1] != 'v') {
+ return;
+ }
+
+ // We're going to continue, so wipe out the existing default feature list
+ memset(riscv_feature_bitmap, 0, 4 * countof(riscv_feature_bitmap));
+
+ size_t pos = 4;
+ while (str[pos] != 0 && str[pos] != '_') {
+ bool found = true;
+ switch (tolower(str[pos])) {
+ // TODO: make sure this is the complete list
+ case 'i': set_feature(RISCV_FEAT_I); break;
+ case 'm': set_feature(RISCV_FEAT_M); break;
+ case 'a': set_feature(RISCV_FEAT_A); break;
+ case 'q': set_feature(RISCV_FEAT_Q);
+ // fallthrough
+ case 'd':
+feat_d:
+ set_feature(RISCV_FEAT_D);
+ // fallthrough
+ case 'f': set_feature(RISCV_FEAT_F); break;
+ case 'c': set_feature(RISCV_FEAT_C); break;
+ case 'b': set_feature(RISCV_FEAT_B); break;
+ case 'p': set_feature(RISCV_FEAT_P); break;
+ case 'h': set_feature(RISCV_FEAT_H); break;
+ case 'v':
+ set_feature(RISCV_FEAT_V);
+ goto feat_d;
+ case 'g':
+ // 'g' is a special case that implies IMAFDZisr_Zifenci
+ set_feature(RISCV_FEAT_I);
+ set_feature(RISCV_FEAT_M);
+ set_feature(RISCV_FEAT_A);
+ set_feature(RISCV_FEAT_ZICSR);
+ set_feature(RISCV_FEAT_ZIFENCEI);
+ goto feat_d;
+ default:
+ found = false;
+ }
+ if (found) {
+ dprintf(INFO, "riscv: found feature '%c'\n", tolower(str[pos]));
+ }
+
+ pos++;
+ }
+
+ // walk the one-word features
+ bool in_word = false;
+ size_t start;
+ for (; pos <= slen; pos++) {
+ if (!in_word) {
+ if (str[pos] == '_') {
+ continue;
+ } else if (str[pos] == 0) {
+ break;
+ }
+ start = pos;
+ in_word = true;
+ } else {
+ // we're in a word
+ if (str[pos] == '_' || str[pos] == 0) {
+ // end of word
+ in_word = false;
+
+ // process the feature word, between str[start...pos]
+ match_feature(str, start, pos);
+ }
+ }
+ }
+}
+
+void riscv_feature_early_init(void) {
+ // set the default features based on the compiler switches
+#if __riscv_i
+ set_feature(RISCV_FEAT_I);
+#endif
+#if __riscv_m
+ set_feature(RISCV_FEAT_M);
+#endif
+#if __riscv_a
+ set_feature(RISCV_FEAT_A);
+#endif
+#if __riscv_f
+ set_feature(RISCV_FEAT_F);
+#endif
+#if __riscv_d
+ set_feature(RISCV_FEAT_D);
+#endif
+#if __riscv_q
+ set_feature(RISCV_FEAT_Q);
+#endif
+#if __riscv_c
+ set_feature(RISCV_FEAT_C);
+#endif
+#if __riscv_zba
+ set_feature(RISCV_FEAT_ZBA);
+#endif
+#if __riscv_zbb
+ set_feature(RISCV_FEAT_ZBB);
+#endif
+#if __riscv_zba
+ set_feature(RISCV_FEAT_ZBA);
+#endif
+#if __riscv_zbc
+ set_feature(RISCV_FEAT_ZBC);
+#endif
+#if __riscv_zbs
+ set_feature(RISCV_FEAT_ZBS);
+#endif
+}
+
+const char *riscv_feature_to_string(enum riscv_feature feature) {
+ switch (feature) {
+ case RISCV_FEAT_I: return "i";
+ case RISCV_FEAT_M: return "m";
+ case RISCV_FEAT_A: return "a";
+ case RISCV_FEAT_F: return "f";
+ case RISCV_FEAT_D: return "d";
+ case RISCV_FEAT_Q: return "q";
+ case RISCV_FEAT_C: return "c";
+ case RISCV_FEAT_B: return "b";
+ case RISCV_FEAT_P: return "p";
+ case RISCV_FEAT_V: return "v";
+ case RISCV_FEAT_H: return "h";
+ case RISCV_FEAT_ZBA: return "zba";
+ case RISCV_FEAT_ZBB: return "zbb";
+ case RISCV_FEAT_ZBC: return "zbc";
+ case RISCV_FEAT_ZBS: return "zbs";
+ case RISCV_FEAT_ZICBOM: return "zicbom";
+ case RISCV_FEAT_ZICBOP: return "zicbop";
+ case RISCV_FEAT_ZICBOZ: return "zicboz";
+ case RISCV_FEAT_ZICSR: return "zicsr";
+ case RISCV_FEAT_ZIFENCEI: return "zifencei";
+ case RISCV_FEAT_SSTC: return "sstc";
+ case RISCV_FEAT_SVADU: return "svadu";
+
+ // keep this in so the compiler warns if something is missing
+ case RISCV_FEAT_COUNT: return "";
+ }
+ return "";
+}
+
+void riscv_feature_init(void) {
+ dprintf(INFO, "RISCV: detected features");
+ for (size_t i = 0; i < countof(riscv_feature_bitmap); i++) {
+ for (size_t j = 0; j < sizeof(riscv_feature_bitmap[i]) * 8; j++) {
+ if (riscv_feature_bitmap[i] & (1U << j)) {
+ dprintf(INFO, " %s", riscv_feature_to_string(i * 32 + j));
+ }
+ }
+ }
+ dprintf(INFO, "\n");
+} \ No newline at end of file
diff --git a/arch/riscv/include/arch/riscv.h b/arch/riscv/include/arch/riscv.h
index 48875575..21c05dec 100644
--- a/arch/riscv/include/arch/riscv.h
+++ b/arch/riscv/include/arch/riscv.h
@@ -58,6 +58,9 @@
#if RISCV_S_MODE // Supervisor-mode only CSRs
#define RISCV_CSR_SATP satp
+// sstc feature
+#define RISCV_CSR_STIMECMP stimecmp
+#define RISCV_CSR_STIMECMPH stimecmph
#endif
#define RISCV_CSR_XSTATUS_IE (1ul << (RISCV_XMODE_OFFSET + 0))
diff --git a/arch/riscv/include/arch/riscv/feature.h b/arch/riscv/include/arch/riscv/feature.h
new file mode 100644
index 00000000..8cf08660
--- /dev/null
+++ b/arch/riscv/include/arch/riscv/feature.h
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2024 Travis Geiselbrecht
+ *
+ * Use of this source code is governed by a MIT-style
+ * license that can be found in the LICENSE file or at
+ * https://opensource.org/licenses/MIT
+ */
+#pragma once
+
+#include <lk/compiler.h>
+#include <stdbool.h>
+#include <stdlib.h>
+
+__BEGIN_CDECLS
+
+// Given a list of features in foo_bar_baz form, break out known features.
+// Does not keep a pointer to the string.
+void riscv_set_isa_string(const char *string);
+
+enum riscv_feature {
+ // Basic one character features
+ RISCV_FEAT_I,
+ RISCV_FEAT_M,
+ RISCV_FEAT_A,
+ RISCV_FEAT_F,
+ RISCV_FEAT_D,
+ RISCV_FEAT_Q,
+ RISCV_FEAT_C,
+ RISCV_FEAT_B,
+ RISCV_FEAT_P,
+ RISCV_FEAT_V,
+ RISCV_FEAT_H,
+
+ // multichar features
+ RISCV_FEAT_ZBA,
+ RISCV_FEAT_ZBB,
+ RISCV_FEAT_ZBC,
+ RISCV_FEAT_ZBS,
+ RISCV_FEAT_ZICSR,
+ RISCV_FEAT_ZIFENCEI,
+ RISCV_FEAT_ZICBOM,
+ RISCV_FEAT_ZICBOP,
+ RISCV_FEAT_ZICBOZ,
+ RISCV_FEAT_SSTC,
+ RISCV_FEAT_SVADU,
+
+ RISCV_FEAT_COUNT
+};
+
+extern uint32_t riscv_feature_bitmap[];
+
+// Test if a particular feature is present
+static inline bool riscv_feature_test(enum riscv_feature feature) {
+ return riscv_feature_bitmap[feature / 32] & (1U << feature % 32);
+}
+
+const char *riscv_feature_to_string(enum riscv_feature feature);
+
+void riscv_feature_early_init(void);
+void riscv_feature_init(void);
+
+__END_CDECLS
diff --git a/arch/riscv/mmu.cpp b/arch/riscv/mmu.cpp
index a7603d23..c82239ac 100644
--- a/arch/riscv/mmu.cpp
+++ b/arch/riscv/mmu.cpp
@@ -25,8 +25,6 @@
#define LOCAL_TRACE 0
-#include <kernel/vm.h>
-
#if __riscv_xlen == 32
#error "32 bit mmu not supported yet"
#endif
@@ -640,7 +638,7 @@ void riscv_early_mmu_init() {
// called a bit later once on the boot cpu
extern "C"
void riscv_mmu_init() {
- printf("RISCV: MMU ASID mask %#lx\n", riscv_asid_mask);
+ dprintf(INFO, "RISCV: MMU ASID mask %#lx\n", riscv_asid_mask);
}
#endif
diff --git a/arch/riscv/rules.mk b/arch/riscv/rules.mk
index 7f61687b..44fb993f 100644
--- a/arch/riscv/rules.mk
+++ b/arch/riscv/rules.mk
@@ -3,15 +3,17 @@ LOCAL_DIR := $(GET_LOCAL_DIR)
MODULE := $(LOCAL_DIR)
MODULE_SRCS += $(LOCAL_DIR)/start.S
+
MODULE_SRCS += $(LOCAL_DIR)/arch.c
MODULE_SRCS += $(LOCAL_DIR)/asm.S
MODULE_SRCS += $(LOCAL_DIR)/exceptions.c
+MODULE_SRCS += $(LOCAL_DIR)/feature.c
MODULE_SRCS += $(LOCAL_DIR)/fpu_asm.S
-MODULE_SRCS += $(LOCAL_DIR)/thread.c
MODULE_SRCS += $(LOCAL_DIR)/mmu.cpp
MODULE_SRCS += $(LOCAL_DIR)/mp.c
MODULE_SRCS += $(LOCAL_DIR)/sbi.c
MODULE_SRCS += $(LOCAL_DIR)/spinlock.c
+MODULE_SRCS += $(LOCAL_DIR)/thread.c
MODULE_SRCS += $(LOCAL_DIR)/time.c
MODULE_DEPS += lib/libcpp
diff --git a/arch/riscv/time.c b/arch/riscv/time.c
index ed5f8067..f2352cf3 100644
--- a/arch/riscv/time.c
+++ b/arch/riscv/time.c
@@ -11,6 +11,8 @@
#include <lk/err.h>
#include <lk/trace.h>
+#include <arch/riscv/feature.h>
+
#include <arch/riscv.h>
#include <arch/ops.h>
@@ -39,7 +41,16 @@ status_t platform_set_oneshot_timer (platform_timer_callback callback, void *arg
#if RISCV_M_MODE
clint_set_timer(ticks);
#elif RISCV_S_MODE
- sbi_set_timer(ticks);
+ if (riscv_feature_test(RISCV_FEAT_SSTC)) {
+#if __riscv_xlen == 64
+ riscv_csr_write(RISCV_CSR_STIMECMP, ticks);
+#else
+ riscv_csr_write(RISCV_CSR_STIMECMPH, ticks >> 32);
+ riscv_csr_write(RISCV_CSR_STIMECMP, ticks);
+#endif
+ } else {
+ sbi_set_timer(ticks);
+ }
#endif
return NO_ERROR;
diff --git a/dev/interrupt/arm_gic/arm_gic.c b/dev/interrupt/arm_gic/arm_gic.c
index de08bb83..7072f614 100644
--- a/dev/interrupt/arm_gic/arm_gic.c
+++ b/dev/interrupt/arm_gic/arm_gic.c
@@ -50,17 +50,17 @@ static spin_lock_t gicd_lock;
#if WITH_LIB_SM
static bool arm_gic_non_secure_interrupts_frozen;
-static bool arm_gic_interrupt_change_allowed(int irq) {
+static bool arm_gic_interrupt_change_allowed(uint irq) {
if (!arm_gic_non_secure_interrupts_frozen)
return true;
- TRACEF("change to interrupt %d ignored after booting ns\n", irq);
+ TRACEF("change to interrupt %u ignored after booting ns\n", irq);
return false;
}
static void suspend_resume_fiq(bool resume_gicc, bool resume_gicd);
#else
-static bool arm_gic_interrupt_change_allowed(int irq) {
+static bool arm_gic_interrupt_change_allowed(uint irq) {
return true;
}
@@ -78,10 +78,11 @@ static struct int_handler_struct int_handler_table_per_cpu[GIC_MAX_PER_CPU_INT][
static struct int_handler_struct int_handler_table_shared[MAX_INT-GIC_MAX_PER_CPU_INT];
static struct int_handler_struct *get_int_handler(unsigned int vector, uint cpu) {
- if (vector < GIC_MAX_PER_CPU_INT)
+ if (vector < GIC_MAX_PER_CPU_INT) {
return &int_handler_table_per_cpu[vector][cpu];
- else
+ } else {
return &int_handler_table_shared[vector - GIC_MAX_PER_CPU_INT];
+ }
}
void register_int_handler(unsigned int vector, int_handler handler, void *arg) {
@@ -111,8 +112,6 @@ void register_int_handler_msi(unsigned int vector, int_handler handler, void *ar
register_int_handler(vector, handler, arg);
}
-#define GICREG(gic, reg) (*REG32(GICBASE(gic) + (reg)))
-
/* main cpu regs */
#define GICC_CTLR (GICC_OFFSET + 0x0000)
#define GICC_PMR (GICC_OFFSET + 0x0004)
@@ -153,7 +152,7 @@ void register_int_handler_msi(unsigned int vector, int_handler handler, void *ar
#define GIC_REG_COUNT(bit_per_reg) DIV_ROUND_UP(MAX_INT, (bit_per_reg))
#define DEFINE_GIC_SHADOW_REG(name, bit_per_reg, init_val, init_from) \
uint32_t (name)[GIC_REG_COUNT(bit_per_reg)] = { \
- [(init_from / bit_per_reg) ... \
+ [((init_from) / (bit_per_reg)) ... \
(GIC_REG_COUNT(bit_per_reg) - 1)] = (init_val) \
}
@@ -162,24 +161,34 @@ static DEFINE_GIC_SHADOW_REG(gicd_igroupr, 32, ~0U, 0);
#endif
static DEFINE_GIC_SHADOW_REG(gicd_itargetsr, 4, 0x01010101, 32);
+// accessor routines for GIC registers that go through the mmio interface
+static inline uint32_t gicreg_read32(uint32_t gic, uint32_t register_offset) {
+ return mmio_read32((volatile uint32_t *)(GICBASE(gic) + register_offset));
+}
+
+static inline void gicreg_write32(uint32_t gic, uint32_t register_offset, uint32_t value) {
+ mmio_write32((volatile uint32_t *)(GICBASE(gic) + register_offset), value);
+}
+
static void gic_set_enable(uint vector, bool enable) {
- int reg = vector / 32;
+ uint reg = vector / 32;
uint32_t mask = 1ULL << (vector % 32);
- if (enable)
- GICREG(0, GICD_ISENABLER(reg)) = mask;
- else
- GICREG(0, GICD_ICENABLER(reg)) = mask;
+ if (enable) {
+ gicreg_write32(0, GICD_ISENABLER(reg), mask);
+ } else {
+ gicreg_write32(0, GICD_ICENABLER(reg), mask);
+ }
}
static void arm_gic_init_percpu(uint level) {
#if WITH_LIB_SM
- GICREG(0, GICC_CTLR) = 0xb; // enable GIC0 and select fiq mode for secure
- GICREG(0, GICD_IGROUPR(0)) = ~0U; /* GICD_IGROUPR0 is banked */
+ gicreg_write32(0, GICC_CTLR, 0xb); // enable GIC0 and select fiq mode for secure
+ gicreg_write32(0, GICD_IGROUPR(0), ~0U); /* GICD_IGROUPR0 is banked */
#else
- GICREG(0, GICC_CTLR) = 1; // enable GIC0
+ gicreg_write32(0, GICC_CTLR, 1); // enable GIC0
#endif
- GICREG(0, GICC_PMR) = 0xFF; // unmask interrupts at all priority levels
+ gicreg_write32(0, GICC_PMR, 0xFF); // unmask interrupts at all priority levels
}
LK_INIT_HOOK_FLAGS(arm_gic_init_percpu,
@@ -198,7 +207,7 @@ static void arm_gic_resume_cpu(uint level) {
bool resume_gicd = false;
spin_lock_save(&gicd_lock, &state, GICD_LOCK_FLAGS);
- if (!(GICREG(0, GICD_CTLR) & 1)) {
+ if (!(gicreg_read32(0, GICD_CTLR) & 1)) {
dprintf(SPEW, "%s: distibutor is off, calling arm_gic_init instead\n", __func__);
arm_gic_init();
resume_gicd = true;
@@ -212,8 +221,8 @@ static void arm_gic_resume_cpu(uint level) {
LK_INIT_HOOK_FLAGS(arm_gic_resume_cpu, arm_gic_resume_cpu,
LK_INIT_LEVEL_PLATFORM, LK_INIT_FLAG_CPU_RESUME);
-static int arm_gic_max_cpu(void) {
- return (GICREG(0, GICD_TYPER) >> 5) & 0x7;
+static uint arm_gic_max_cpu(void) {
+ return (gicreg_read32(0, GICD_TYPER) >> 5) & 0x7;
}
static status_t gic_configure_interrupt(unsigned int vector,
@@ -233,13 +242,13 @@ static status_t gic_configure_interrupt(unsigned int vector,
// 16 irqs encoded per ICFGR register
uint32_t reg_ndx = vector >> 4;
uint32_t bit_shift = ((vector & 0xf) << 1) + 1;
- uint32_t reg_val = GICREG(0, GICD_ICFGR(reg_ndx));
+ uint32_t reg_val = gicreg_read32(0, GICD_ICFGR(reg_ndx));
if (tm == IRQ_TRIGGER_MODE_EDGE) {
reg_val |= (1 << bit_shift);
} else {
reg_val &= ~(1 << bit_shift);
}
- GICREG(0, GICD_ICFGR(reg_ndx)) = reg_val;
+ gicreg_write32(0, GICD_ICFGR(reg_ndx), reg_val);
return NO_ERROR;
}
@@ -248,14 +257,14 @@ void arm_gic_init(void) {
int i;
for (i = 0; i < MAX_INT; i+= 32) {
- GICREG(0, GICD_ICENABLER(i / 32)) = ~0;
- GICREG(0, GICD_ICPENDR(i / 32)) = ~0;
+ gicreg_write32(0, GICD_ICENABLER(i / 32), ~0);
+ gicreg_write32(0, GICD_ICPENDR(i / 32), ~0);
}
if (arm_gic_max_cpu() > 0) {
/* Set external interrupts to target cpu 0 */
for (i = 32; i < MAX_INT; i += 4) {
- GICREG(0, GICD_ITARGETSR(i / 4)) = gicd_itargetsr[i / 4];
+ gicreg_write32(0, GICD_ITARGETSR(i / 4), gicd_itargetsr[i / 4]);
}
}
@@ -265,9 +274,9 @@ void arm_gic_init(void) {
}
- GICREG(0, GICD_CTLR) = 1; // enable GIC0
+ gicreg_write32(0, GICD_CTLR, 1); // enable GIC0
#if WITH_LIB_SM
- GICREG(0, GICD_CTLR) = 3; // enable GIC0 ns interrupts
+ gicreg_write32(0, GICD_CTLR, 3); // enable GIC0 ns interrupts
/*
* Iterate through all IRQs and set them to non-secure
* mode. This will allow the non-secure side to handle
@@ -275,7 +284,7 @@ void arm_gic_init(void) {
*/
for (i = 32; i < MAX_INT; i += 32) {
u_int reg = i / 32;
- GICREG(0, GICD_IGROUPR(reg)) = gicd_igroupr[reg];
+ gicreg_write32(0, GICD_IGROUPR(reg), gicd_igroupr[reg]);
}
#endif
arm_gic_init_percpu(0);
@@ -290,11 +299,11 @@ static status_t arm_gic_set_secure_locked(u_int irq, bool secure) {
return ERR_INVALID_ARGS;
if (secure)
- GICREG(0, GICD_IGROUPR(reg)) = (gicd_igroupr[reg] &= ~mask);
+ gicreg_write32(0, GICD_IGROUPR(reg), (gicd_igroupr[reg] &= ~mask));
else
- GICREG(0, GICD_IGROUPR(reg)) = (gicd_igroupr[reg] |= mask);
+ gicreg_write32(0, GICD_IGROUPR(reg), (gicd_igroupr[reg] |= mask));
LTRACEF("irq %d, secure %d, GICD_IGROUP%d = %x\n",
- irq, secure, reg, GICREG(0, GICD_IGROUPR(reg)));
+ irq, secure, reg, gicreg_read32(0, GICD_IGROUPR(reg)));
#endif
return NO_ERROR;
}
@@ -308,19 +317,19 @@ static status_t arm_gic_set_target_locked(u_int irq, u_int cpu_mask, u_int enabl
cpu_mask = (cpu_mask & 0xff) << shift;
enable_mask = (enable_mask << shift) & cpu_mask;
- old_val = GICREG(0, GICD_ITARGETSR(reg));
+ old_val = gicreg_read32(0, GICD_ITARGETSR(reg));
new_val = (gicd_itargetsr[reg] & ~cpu_mask) | enable_mask;
- GICREG(0, GICD_ITARGETSR(reg)) = gicd_itargetsr[reg] = new_val;
+ gicreg_write32(0, GICD_ITARGETSR(reg), (gicd_itargetsr[reg] = new_val));
LTRACEF("irq %i, GICD_ITARGETSR%d %x => %x (got %x)\n",
- irq, reg, old_val, new_val, GICREG(0, GICD_ITARGETSR(reg)));
+ irq, reg, old_val, new_val, gicreg_read32(0, GICD_ITARGETSR(reg)));
return NO_ERROR;
}
-static status_t arm_gic_get_priority(u_int irq) {
+static uint8_t arm_gic_get_priority(u_int irq) {
u_int reg = irq / 4;
u_int shift = 8 * (irq % 4);
- return (GICREG(0, GICD_IPRIORITYR(reg)) >> shift) & 0xff;
+ return (gicreg_read32(0, GICD_IPRIORITYR(reg)) >> shift) & 0xff;
}
static status_t arm_gic_set_priority_locked(u_int irq, uint8_t priority) {
@@ -329,12 +338,12 @@ static status_t arm_gic_set_priority_locked(u_int irq, uint8_t priority) {
u_int mask = 0xff << shift;
uint32_t regval;
- regval = GICREG(0, GICD_IPRIORITYR(reg));
+ regval = gicreg_read32(0, GICD_IPRIORITYR(reg));
LTRACEF("irq %i, old GICD_IPRIORITYR%d = %x\n", irq, reg, regval);
regval = (regval & ~mask) | ((uint32_t)priority << shift);
- GICREG(0, GICD_IPRIORITYR(reg)) = regval;
+ gicreg_write32(0, GICD_IPRIORITYR(reg), regval);
LTRACEF("irq %i, new GICD_IPRIORITYR%d = %x, req %x\n",
- irq, reg, GICREG(0, GICD_IPRIORITYR(reg)), regval);
+ irq, reg, gicreg_read32(0, GICD_IPRIORITYR(reg)), regval);
return 0;
}
@@ -351,7 +360,7 @@ status_t arm_gic_sgi(u_int irq, u_int flags, u_int cpu_mask) {
LTRACEF("GICD_SGIR: %x\n", val);
- GICREG(0, GICD_SGIR) = val;
+ gicreg_write32(0, GICD_SGIR, val);
return NO_ERROR;
}
@@ -379,7 +388,7 @@ status_t unmask_interrupt(unsigned int vector) {
static
enum handler_return __platform_irq(struct iframe *frame) {
// get the current vector
- uint32_t iar = GICREG(0, GICC_IAR);
+ uint32_t iar = gicreg_read32(0, GICC_IAR);
unsigned int vector = iar & 0x3ff;
if (vector >= 0x3fe) {
@@ -403,7 +412,7 @@ enum handler_return __platform_irq(struct iframe *frame) {
if (handler->handler)
ret = handler->handler(handler->arg);
- GICREG(0, GICC_EOIR) = iar;
+ gicreg_write32(0, GICC_EOIR, iar);
LTRACEF_LEVEL(2, "cpu %u exit %d\n", cpu, ret);
@@ -415,7 +424,7 @@ enum handler_return __platform_irq(struct iframe *frame) {
enum handler_return platform_irq(struct iframe *frame);
enum handler_return platform_irq(struct iframe *frame) {
#if WITH_LIB_SM
- uint32_t ahppir = GICREG(0, GICC_AHPPIR);
+ uint32_t ahppir = gicreg_read32(0, GICC_AHPPIR);
uint32_t pending_irq = ahppir & 0x3ff;
struct int_handler_struct *h;
uint cpu = arch_curr_cpu_num();
@@ -436,7 +445,7 @@ enum handler_return platform_irq(struct iframe *frame) {
old_priority = arm_gic_get_priority(pending_irq);
arm_gic_set_priority_locked(pending_irq, 0);
DSB;
- irq = GICREG(0, GICC_AIAR) & 0x3ff;
+ irq = gicreg_read32(0, GICC_AIAR) & 0x3ff;
arm_gic_set_priority_locked(pending_irq, old_priority);
spin_unlock_restore(&gicd_lock, state, GICD_LOCK_FLAGS);
@@ -446,7 +455,7 @@ enum handler_return platform_irq(struct iframe *frame) {
ret = h->handler(h->arg);
else
TRACEF("unexpected irq %d != %d may get lost\n", irq, pending_irq);
- GICREG(0, GICC_AEOIR) = irq;
+ gicreg_write32(0, GICC_AEOIR, irq);
return ret;
}
return sm_handle_irq();
@@ -569,7 +578,7 @@ static void suspend_resume_fiq(bool resume_gicc, bool resume_gicd) {
status_t sm_intc_fiq_enter(void) {
u_int cpu = arch_curr_cpu_num();
- u_int irq = GICREG(0, GICC_IAR) & 0x3ff;
+ u_int irq = gicreg_read32(0, GICC_IAR) & 0x3ff;
bool fiq_enabled;
ASSERT(cpu < 8);
@@ -582,7 +591,7 @@ status_t sm_intc_fiq_enter(void) {
}
fiq_enabled = update_fiq_targets(cpu, false, irq, false);
- GICREG(0, GICC_EOIR) = irq;
+ gicreg_write32(0, GICC_EOIR, irq);
if (current_fiq[cpu] != 0x3ff) {
dprintf(INFO, "more than one fiq active: cpu %d, old %d, new %d\n", cpu, current_fiq[cpu], irq);
diff --git a/lib/fdtwalk/fdtwalk.cpp b/lib/fdtwalk/fdtwalk.cpp
index 17c8a515..b28775e4 100644
--- a/lib/fdtwalk/fdtwalk.cpp
+++ b/lib/fdtwalk/fdtwalk.cpp
@@ -84,18 +84,35 @@ status_t read_base_len_pair(const uint8_t *prop_ptr, size_t prop_len,
// returns true or false if a particular property is a particular value
bool check_prop_is_val_string(const void *fdt, int offset, const char *prop, const char *val) {
int lenp;
- const uint8_t *prop_ptr = (const uint8_t *)fdt_getprop(fdt, offset, prop, &lenp);
+ const uint8_t *prop_ptr = static_cast<const uint8_t *>(fdt_getprop(fdt, offset, prop, &lenp));
if (!prop_ptr || lenp <= 0) {
return false;
}
- if (strncmp(val, (const char *)prop_ptr, strlen(val)) == 0) {
+ if (strncmp(val, reinterpret_cast<const char *>(prop_ptr), strlen(val)) == 0) {
return true;
}
return false;
}
+const char *get_prop_string(const void *fdt, int offset, const char *prop) {
+ int lenp;
+ const uint8_t *prop_ptr = static_cast<const uint8_t *>(fdt_getprop(fdt, offset, prop, &lenp));
+ if (!prop_ptr || lenp <= 0) {
+ return nullptr;
+ }
+
+ // check to see that it appears to be null terminated
+ auto str = reinterpret_cast<const char *>(prop_ptr);
+ if (str[lenp-1] != '\0') {
+ return nullptr;
+ }
+
+ // seems safe
+ return str;
+}
+
struct fdt_walk_state {
const void *fdt;
int offset;
@@ -210,6 +227,18 @@ status_t fdt_walk_find_cpus(const void *fdt, struct fdt_walk_cpu_info *cpu, size
cpu[*cpu_count].id = id;
(*cpu_count)++;
}
+#if ARCH_RISCV
+ // look for riscv,isa and riscv,isa-extensions
+ auto isa_string = get_prop_string(state.fdt, state.offset, "riscv,isa");
+ if (isa_string) {
+ cpu->isa_string = isa_string;
+ }
+
+ auto isa_extensions_string = get_prop_string(state.fdt, state.offset, "riscv,isa-extensions");
+ if (isa_extensions_string) {
+ cpu->isa_extensions_string = isa_extensions_string;
+ }
+#endif
}
}
};
diff --git a/lib/fdtwalk/helpers.cpp b/lib/fdtwalk/helpers.cpp
index 9254103c..b978bb98 100644
--- a/lib/fdtwalk/helpers.cpp
+++ b/lib/fdtwalk/helpers.cpp
@@ -22,6 +22,7 @@
#endif
#if ARCH_RISCV
#include <arch/riscv.h>
+#include <arch/riscv/feature.h>
#endif
#if ARCH_ARM || ARCH_ARM64
#include <dev/power/psci.h>
@@ -42,13 +43,13 @@ status_t fdtwalk_reserve_fdt_memory(const void *fdt, paddr_t fdt_phys) {
return ERR_NOT_FOUND;
}
- unsigned long length = fdt_totalsize(fdt);
+ uint32_t length = fdt_totalsize(fdt);
paddr_t base = fdt_phys;
base = PAGE_ALIGN(base);
length = ROUNDUP(length, PAGE_SIZE);
- printf("FDT: reserving physical range for FDT: [%#lx, %#lx]\n", base, base + length - 1);
+ dprintf(INFO, "FDT: reserving physical range for FDT: [%#lx, %#lx]\n", base, base + length - 1);
#if WITH_KERNEL_VM
struct list_node list = LIST_INITIAL_VALUE(list);
@@ -74,7 +75,7 @@ status_t fdtwalk_setup_memory(const void *fdt, paddr_t fdt_phys, paddr_t default
status_t err = fdt_walk_find_memory(fdt, mem, &mem_count, reserved_mem, &reserved_mem_count);
if (err < NO_ERROR || mem_count == 0) {
/* add a default memory region if we didn't find it in the FDT */
- printf("FDT: could not find memory, using default base %#lx size %#zx\n", default_mem_base, default_mem_size);
+ dprintf(INFO, "FDT: could not find memory, using default base %#lx size %#zx\n", default_mem_base, default_mem_size);
#if WITH_KERNEL_VM
mem[0].base = default_mem_base;
mem[0].len = default_mem_size;
@@ -84,20 +85,20 @@ status_t fdtwalk_setup_memory(const void *fdt, paddr_t fdt_phys, paddr_t default
for (size_t i = 0; i < mem_count; i++) {
LTRACEF("base %#llx len %#llx\n", mem[i].base, mem[i].len);
- printf("FDT: found memory bank range [%#llx, %#llx] (length %#llx)\n", mem[i].base, mem[i].base + mem[i].len - 1, mem[i].len);
+ dprintf(INFO, "FDT: found memory bank range [%#llx, %#llx] (length %#llx)\n", mem[i].base, mem[i].base + mem[i].len - 1, mem[i].len);
/* trim size on certain platforms */
-#if ARCH_ARM
+#if ARCH_ARM || (ARCH_RISCV && __riscv_xlen == 32)
/* only use the first 1GB on ARM32 */
const auto GB = 1024*1024*1024UL;
if (mem[i].base - MEMBASE > GB) {
- printf("trimming memory to 1GB\n");
+ dprintf(INFO, "trimming memory to 1GB\n");
continue;
}
if (mem[i].base - MEMBASE + mem[i].len > GB) {
- printf("trimming memory to 1GB\n");
+ dprintf(INFO, "trimming memory to 1GB\n");
mem[i].len = MEMBASE + GB - mem[i].base;
- printf("range is now [%#llx, %#llx]\n", mem[i].base, mem[i].base + mem[i].len - 1);
+ dprintf(INFO, "range is now [%#llx, %#llx]\n", mem[i].base, mem[i].base + mem[i].len - 1);
}
#endif
@@ -120,7 +121,7 @@ status_t fdtwalk_setup_memory(const void *fdt, paddr_t fdt_phys, paddr_t default
/* reserve memory described by the FDT */
for (size_t i = 0; i < reserved_mem_count; i++) {
- printf("FDT: reserving memory range [%#llx, %#llx]\n",
+ dprintf(INFO, "FDT: reserving memory range [%#llx, %#llx]\n",
reserved_mem[i].base, reserved_mem[i].base + reserved_mem[i].len - 1);
#if WITH_KERNEL_VM
@@ -150,9 +151,10 @@ status_t fdtwalk_setup_cpus_riscv(const void *fdt) {
status_t err = fdt_walk_find_cpus(fdt, cpus, &cpu_count);
if (err >= NO_ERROR) {
+ const char *isa_string = {};
if (cpu_count > 0) {
- printf("FDT: found %zu cpu%c\n", cpu_count, cpu_count == 1 ? ' ' : 's');
+ dprintf(INFO, "FDT: found %zu cpu%c\n", cpu_count, cpu_count == 1 ? ' ' : 's');
uint harts[SMP_MAX_CPUS - 1];
// copy from the detected cpu list to an array of harts, excluding the boot hart
@@ -166,12 +168,29 @@ status_t fdtwalk_setup_cpus_riscv(const void *fdt) {
if (hart_index >= SMP_MAX_CPUS - 1) {
break;
}
+
+ if (cpus[i].isa_string) {
+ if (!isa_string) {
+ // save the first isa string we found
+ isa_string = cpus[i].isa_string;
+ } else {
+ if (!strcmp(cpus[i].isa_string, isa_string)) {
+ printf("FDT Warning: isa_strings do not match between cpus, using first found\n");
+ }
+ }
+ }
+
}
// tell the riscv layer how many cores we have to start
if (hart_index > 0) {
riscv_set_secondary_harts_to_start(harts, hart_index);
}
+
+ if (isa_string) {
+ dprintf(INFO, "FDT: isa string '%s'\n", isa_string);
+ riscv_set_isa_string(isa_string);
+ }
}
}
#endif
@@ -189,11 +208,11 @@ status_t fdtwalk_setup_cpus_arm(const void *fdt) {
status_t err = fdt_walk_find_cpus(fdt, cpus, &cpu_count);
if (err >= NO_ERROR) {
if (cpu_count > 0) {
- printf("FDT: found %zu cpu%c\n", cpu_count, cpu_count == 1 ? ' ' : 's');
+ dprintf(INFO, "FDT: found %zu cpu%c\n", cpu_count, cpu_count == 1 ? ' ' : 's');
if (cpu_count > SMP_MAX_CPUS) {
cpu_count = MIN(cpu_count, SMP_MAX_CPUS);
- printf("FDT: clamping max cpus to %zu\n", cpu_count);
+ dprintf(INFO, "FDT: clamping max cpus to %zu\n", cpu_count);
}
LTRACEF("booting %zu cpus\n", cpu_count);
@@ -201,7 +220,7 @@ status_t fdtwalk_setup_cpus_arm(const void *fdt) {
/* boot the secondary cpus using the Power State Coordintion Interface */
for (size_t i = 1; i < cpu_count; i++) {
/* note: assumes cpuids are numbered like MPIDR 0:0:0:N */
- printf("ARM: starting cpu %#x\n", cpus[i].id);
+ dprintf(INFO, "ARM: starting cpu %#x\n", cpus[i].id);
int ret = psci_cpu_on(cpus[i].id, MEMBASE + KERNEL_LOAD_OFFSET);
if (ret != 0) {
printf("ERROR: psci CPU_ON returns %d\n", ret);
@@ -235,7 +254,7 @@ status_t fdtwalk_setup_pci(const void *fdt) {
}
if (pcie_info[i].ecam_len > 0) {
- printf("PCIE: initializing pcie with ecam at %#" PRIx64 " found in FDT\n", pcie_info[i].ecam_base);
+ dprintf(INFO, "PCIE: initializing pcie with ecam at %#" PRIx64 " found in FDT\n", pcie_info[i].ecam_base);
err = pci_init_ecam(pcie_info[i].ecam_base, pcie_info[i].ecam_len, pcie_info[i].bus_start, pcie_info[i].bus_end);
if (err == NO_ERROR) {
// add some additional resources to the pci bus manager in case it needs to configure
diff --git a/lib/fdtwalk/include/lib/fdtwalk.h b/lib/fdtwalk/include/lib/fdtwalk.h
index b0f2d644..c80c740c 100644
--- a/lib/fdtwalk/include/lib/fdtwalk.h
+++ b/lib/fdtwalk/include/lib/fdtwalk.h
@@ -41,6 +41,10 @@ struct fdt_walk_memory_region {
struct fdt_walk_cpu_info {
uint32_t id;
+#if ARCH_RISCV
+ const char *isa_string; // pointer to riscv,isa inside device tree
+ const char *isa_extensions_string; // pointer to riscv,isa-etensions inside device tree
+#endif
};
status_t fdt_walk_dump(const void *fdt);
diff --git a/lk.code-workspace b/lk.code-workspace
new file mode 100644
index 00000000..81617e81
--- /dev/null
+++ b/lk.code-workspace
@@ -0,0 +1,14 @@
+{
+ "folders": [
+ {
+ "path": "."
+ }
+ ],
+ "settings": {
+ "editor.tabSize": 4,
+ "files.exclude": {
+ "**/.cache": true,
+ "**/.clangd": true
+ }
+ }
+} \ No newline at end of file
diff --git a/project/virtual/fs.mk b/project/virtual/fs.mk
index d9de1026..0e7fb8a5 100644
--- a/project/virtual/fs.mk
+++ b/project/virtual/fs.mk
@@ -5,5 +5,6 @@ MODULES += \
lib/fs/ext2 \
lib/fs/fat \
lib/fs/spifs \
- lib/fs/memfs
+ lib/fs/memfs \
+ lib/partition
diff --git a/scripts/do-qemuriscv b/scripts/do-qemuriscv
index 88d4ffec..ea341f9f 100755
--- a/scripts/do-qemuriscv
+++ b/scripts/do-qemuriscv
@@ -37,7 +37,7 @@ DO_CMPCTMALLOC=0
DO_MINIHEAP=0
DO_SUPERVISOR=0
SMP=1
-MEMSIZE=512
+MEMSIZE=0
SUDO=""
PROJECT=""
@@ -75,19 +75,18 @@ if (( $DO_UNLEASHED == 1 )); then
if (( $SMP == 1 )); then
SMP=2
fi
- if (( $MEMSIZE == 512 )); then
- MEMSIZE=8192
- fi
+ _MEMSIZE=8192
elif (( $DO_EMBEDDED == 1 )); then
QEMU="qemu-system-riscv32"
MACHINE="sifive_e"
_PROJECT="sifive-e-test"
- MEMSIZE=0
+ _MEMSIZE=0
SMP=0
elif (( $DO_64BIT )); then
QEMU="qemu-system-riscv64"
CPU="rv64"
MACHINE="virt"
+ _MEMSIZE=512
if (( $DO_SUPERVISOR )); then
_PROJECT="qemu-virt-riscv64-supervisor-test"
BIOS="default"
@@ -99,12 +98,22 @@ else
QEMU="qemu-system-riscv32"
CPU="rv32"
MACHINE="virt"
- _PROJECT="qemu-virt-riscv32-test"
BIOS="none"
+ _MEMSIZE=512
+ if (( $DO_SUPERVISOR )); then
+ _PROJECT="qemu-virt-riscv32-supervisor-test"
+ BIOS="default"
+ else
+ _PROJECT="qemu-virt-riscv32-test"
+ BIOS="none"
+ fi
fi
if [[ -z "$PROJECT" ]]; then
PROJECT=$_PROJECT
fi
+if [[ -z "$MEMSIZE" ]]; then
+ PROJECT=$_MEMSIZE
+fi
# construct a list of args based on previous variables
ARGS=" -machine $MACHINE"