From 19c354eaab9359cce9230138938cf1185b5f197f Mon Sep 17 00:00:00 2001 From: wangguokun Date: Mon, 28 Oct 2024 16:47:37 +0800 Subject: [PATCH] plat/d9: provide adaptive SemiDrive D9 board Signed-off-by: wangguokun --- .clang-format | 197 +++++++++++++++++++++++++++++++++++++++++++ Config.uk | 28 ++++++ Linker.uk | 79 +++++++++++++++++ Makefile.uk | 68 +++++++++++++++ README.en.md | 36 -------- README.md | 92 ++++++++++++++------ console.c | 12 +++ d9_bpt64.S | 115 +++++++++++++++++++++++++ include/d9/console.h | 9 ++ include/d9/sysregs.h | 27 ++++++ io.c | 16 ++++ lcpu.c | 56 ++++++++++++ memory.c | 8 ++ mmu.S | 84 ++++++++++++++++++ setup.c | 124 +++++++++++++++++++++++++++ shutdown.c | 29 +++++++ start.S | 95 +++++++++++++++++++++ 17 files changed, 1014 insertions(+), 61 deletions(-) create mode 100644 .clang-format create mode 100644 Config.uk create mode 100644 Linker.uk create mode 100644 Makefile.uk delete mode 100644 README.en.md create mode 100644 console.c create mode 100644 d9_bpt64.S create mode 100644 include/d9/console.h create mode 100644 include/d9/sysregs.h create mode 100644 io.c create mode 100644 lcpu.c create mode 100644 memory.c create mode 100644 mmu.S create mode 100644 setup.c create mode 100644 shutdown.c create mode 100644 start.S diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..33105f1 --- /dev/null +++ b/.clang-format @@ -0,0 +1,197 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# clang-format version is 20.0.0 +# +# For more information, see: +# https://clang.llvm.org/docs/ClangFormatStyleOptions.html +# +--- +# 应用于c、c++文件。目前的配置前都是针对C语言的 +Language: Cpp +AccessModifierOffset: -4 +AlignAfterOpenBracket: Align +# 连续赋值时对齐等号 +AlignConsecutiveAssignments: true +# 连续声明时对齐变量名 +AlignConsecutiveDeclarations: true +# 行尾'\'符左对齐 +AlignEscapedNewlines: Left +# 换行时操作数垂直对齐 +AlignOperands: true +# 多行连续代码存在行尾注释时(//),注释对齐 +AlignTrailingComments: + Kind: Always + OverEmptyLines: 2 +# 函数参数列表过长时,不允许从第一个参数开始换行 +AllowAllParametersOfDeclarationOnNextLine: false +AllowShortBlocksOnASingleLine: false +# 'case xxx:'条件后必须换行 +AllowShortCaseLabelsOnASingleLine: false +# 除了空函数外,函数名、函数体不允许写在同一行 +AllowShortFunctionsOnASingleLine: Empty +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakBeforeMultilineStrings: false +# 如果设成false,调用函数时如果参数列表需要换行,必须一行一个 +BinPackArguments: true +# 函数定义、声明时,允许参数列表换行,不需要一行一个 +BinPackParameters: BinPack +# 采用BraceWrapping定义的括号换行方式 +BreakBeforeBraces: Custom +BraceWrapping: + # 条件分支(if-else、do-while、switch-case、for,花括号不换行) + AfterControlStatement: Never + # 定义枚举类型,花括号不换行 + AfterEnum: false + # 定义函数,花括号换行 + AfterFunction: true + # 定义结构体,花括号不换行 + AfterStruct: false + # 定义Union类型,花括号不换行 + AfterUnion: false + # extern "C"之后花括号不换行 + AfterExternBlock: false + # else分支花括号不换行 + BeforeElse: false + # 花括号换行后不增加缩进 + IndentBraces: false + # 空函数体的花括号不用换行 + SplitEmptyFunction: false + # 空的结构体、Union等定义,花括号不用换行 + SplitEmptyRecord: false +# 根据PenaltyReturnTypeOnItsOwnLine决定函数声明返回类型后是否换行 +BreakAfterReturnType: Automatic +# 语句超过一行时,在操作符之后换行。即操作符保留在上一行 +BreakBeforeBinaryOperators: None +# 使用三目操作符的语句换行时,在三目操作符之后换行(?和:后) +BreakBeforeTernaryOperators: false +# 字符串常量不能拆分,例如,下边这种是不允许的: +# const char* x = "veryVeryVeryVeryVeryVe" +# "ryVeryVeryVeryVeryVery" +# "VeryLongString"; +BreakStringLiterals: false +# 每行不超过80字符 +ColumnLimit: 80 +# 正则匹配到的注释不能换行断开。 +# iwyu是一个include依赖管理工具,后续可能引入,暂时保留配置 +# https://github.com/include-what-you-use/include-what-you-use/blob/master/README.md +CommentPragmas: '^ IWYU pragma:' +ContinuationIndentWidth: 4 +# 花括号包围的字段列表,与花括号之前插一个空格,比如:new int[3]{ 1, 2, 3 }; +Cpp11BracedListStyle: false +# 用PointerAlignment决定指针怎么对齐 +DerivePointerAlignment: false +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +# Taken from: +# git grep -h -E '^#define [^[:space:]]*for(_)?each[^[:space:]]*\(' include/ arch/ drivers/ lib/ plat/ \ +# | sed "s,^#define \([^[:space:]]*for\(_\)\?each[^[:space:]]*\)(.*$, - '\1'," \ +# | LC_ALL=C sort -u +ForEachMacros: + - '_runq_foreach_safe' + - '_waitq_foreach_safe' + - 'fdt_for_each_property_offset' + - 'fdt_for_each_subnode' + - 'for_each_fs' + - 'lcpu_lcpuid_list_foreach' + - 'nf_excpttab_foreach' + - 'tn_entrytab_foreach' + - 'uk_alloc_foreach' + - 'uk_alloc_foreach_libstats' + - 'uk_ctortab_foreach' + - 'uk_event_handler_foreach' + - 'uk_for_each_set_bit' + - 'uk_inittab_foreach' + - 'uk_inittab_foreach_reverse' + - 'uk_inittab_foreach_reverse2' + - 'uk_libinfo_hdr_foreach' + - 'uk_libinfo_rec_foreach' + - 'uk_list_for_each_entry' + - 'uk_list_for_each_entry_safe' + - 'uk_posix_clonetab_foreach' + - 'uk_posix_clonetab_foreach_reverse' + - 'uk_posix_clonetab_foreach_reverse2' + - 'uk_sched_foreach_thread' + - 'uk_sched_foreach_thread_safe' + - 'uk_test_assert_foreach' + - 'uk_testsuite_case_foreach' + - 'uk_thread_inittab_foreach' + - 'uk_thread_inittab_foreach_reverse' + - 'uk_thread_inittab_foreach_reverse2' + - 'ukplat_memregion_foreach' +# include自动排序,配合IncludeCategories使用,保证<>形式和""形式的头文件分别排序,两部分用空行隔开。 +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '<[[:alnum:]_]+\.h>' + Priority: 1 + SortPriority: 1 + - Regex: '<(uk|tn)/[[:alnum:]_/]+\.h>' + Priority: 2 + SortPriority: 2 + - Regex: '"[[:alnum:]_]+\.h"' + Priority: 3 + SortPriority: 3 +# case语句不缩进 +IndentCaseLabels: false +# goto语句不缩进 +IndentGotoLabels: false +# 预编译指令不缩进。如果缩进的话,会导致预处理后的文件缩进奇怪,比如下边的例子: +# #if FOO +# #if BAR +# #include +# #endif +# #endif +IndentPPDirectives: None +# 缩进字符数 +IndentWidth: 4 +# 函数声明、定义在return type后换行,函数名不缩进 +IndentWrappedFunctionNames: false +# 文件结尾追加空行 +KeepEmptyLines: + AtEndOfFile: true + AtStartOfBlock: false + AtStartOfFile: false +LineEnding: LF +MacroBlockBegin: '' +MacroBlockEnd: '' +# 不允许连续空行,最多一行 +MaxEmptyLinesToKeep: 1 +# Taken from git's rules +PenaltyBreakAssignment: 10 +PenaltyBreakBeforeFirstCallParameter: 30 +PenaltyBreakComment: 10 +PenaltyBreakFirstLessLess: 0 +PenaltyBreakString: 10 +PenaltyExcessCharacter: 100 +# 超过60字符后在函数声明return type之后换行 +PenaltyReturnTypeOnItsOwnLine: 60 +# 指针的*挨着变量名 +PointerAlignment: Right +# 暂时配成注释自动换行,如果对API注释等影响较大,改回false +ReflowComments: true +# 删除多余不必要的花括号 +RemoveBracesLLVM: true +# include排序时不区分大小写 +SortIncludes: CaseInsensitive +# 类型强转时,类型和变量名之间不加空格 +SpaceAfterCStyleCast: false +# =、+=等赋值符前边加空格 +SpaceBeforeAssignmentOperators: true +# 除了ForEachMacros外,其他场景需要在括号前加空格。也就是说把foreach宏当成函数调用,不加空格 +# 而if等逻辑判断,keyword和括号之间加空格 +SpaceBeforeParens: ControlStatementsExceptForEachMacros +SpacesInParens: Custom +# 括号里不加空格 +SpacesInParensOptions: + InEmptyParentheses: false + InCStyleCasts: false + InConditionalStatements: false + Other: false +# 行尾注释//后加1个空格 +SpacesBeforeTrailingComments: 1 +# 方括号里不加空格 +SpacesInSquareBrackets: false +TabWidth: 4 +# 用tab缩进,需要对齐时补空格 +UseTab: Always +... diff --git a/Config.uk b/Config.uk new file mode 100644 index 0000000..daa1682 --- /dev/null +++ b/Config.uk @@ -0,0 +1,28 @@ +menuconfig PLAT_D9 + bool "D9" + default n + depends on ARCH_ARM_64 + select HAVE_FDT + select LIBFDT + select LIBUKOFW + select LIBTNTTY_NS8250 + select HAVE_INTCTLR + select LIBUKINTCTLR_GICV2 + select ARM_GENERIC_TIMER + help + Create a kernel image that runs on D9 + +if (PLAT_D9) + +config RAM_BASE_ADDR + hex + default 0x5B200000 + +config BOOT_PROTO_LXBOOT + bool "Lxboot" + default y + help + Linux 64-bit Boot Protocol + +endif + diff --git a/Linker.uk b/Linker.uk new file mode 100644 index 0000000..f2afd45 --- /dev/null +++ b/Linker.uk @@ -0,0 +1,79 @@ +ifeq (arm64,$(CONFIG_UK_ARCH)) +D9_LDFLAGS-y += -Wl,--entry=_start +D9_LDFLAGS-y += -Wl,-m,aarch64elf +D9_LINK_LIBGCC_FLAG := -lgcc +endif + +## +## Link image +## +D9_IMAGE := $(BUILD_DIR)/$(CONFIG_UK_NAME)_d9-$(CONFIG_UK_ARCH) +D9_DEBUG_IMAGE := $(D9_IMAGE).dbg + +D9_LD_SCRIPT_FLAGS := $(addprefix -Wl$(comma)-dT$(comma),\ + $(UK_PLAT_D9_DEF_LDS)) +D9_LD_SCRIPT_FLAGS += $(addprefix -Wl$(comma)-T$(comma),\ + $(D9_LD_SCRIPT-y) $(EXTRA_LD_SCRIPT-y)) + +$(D9_DEBUG_IMAGE): $(D9_ALIBS) $(D9_ALIBS-y) $(D9_OLIBS) $(D9_OLIBS-y) \ + $(UK_ALIBS) $(UK_ALIBS-y) $(UK_OLIBS) $(UK_OLIBS-y) \ + $(D9_LD_SCRIPT-y) $(EXTRA_LD_SCRIPT-y) \ + $(UK_PLAT_D9_DEF_LDS) $(UK_LDEPS) + $(call build_cmd,LD,,$@,\ + $(LD) \ + $(D9_LDFLAGS) $(D9_LDFLAGS-y) \ + $(D9_OLIBS) $(D9_OLIBS-y) \ + $(UK_OLIBS) $(UK_OLIBS-y) \ + -Wl$(comma)--start-group \ + $(D9_ALIBS) $(D9_ALIBS-y) \ + $(UK_ALIBS) $(UK_ALIBS-y) \ + $(D9_LINK_LIBGCC_FLAG) \ + -Wl$(comma)--end-group \ + $(LDFLAGS) $(LDFLAGS-y) \ + $(D9_LD_SCRIPT_FLAGS) \ + -o $@) +ifeq ($(CONFIG_OPTIMIZE_PIE),y) + $(call build_uk_reloc,$@) +endif + + +$(D9_IMAGE): $(D9_IMAGE).dbg + $(call build_cmd,SCSTRIP,,$@,\ + $(STRIP) -s \ + $(SECT_STRIP_FLAGS) $(SECT_STRIP_FLAGS-y) \ + $(D9_STRIPFLAGS) \ + $< -o $@ 2>&1 | \ + { $(GREP) -Ev \ + "Empty loadable segment detected|section.*lma.*adjusted to.*" || \ + true; }) + $(call build_bootinfo,$@) + + $(call build_cmd,OBJCOPY,,$(D9_IMAGE).img,\ + $(OBJCOPY) -O binary $(D9_IMAGE) $(BUILD_DIR)/kernel.img) + +ifeq ($(CONFIG_BOOT_PROTO_LXBOOT),y) +$(D9_IMAGE).lxboot: $(D9_IMAGE) + $(call build_cmd,MKLINUX,,$(D9_IMAGE).img, $(SCRIPTS_DIR)/mklinux.py \ + $(BUILD_DIR)/kernel.img $(D9_IMAGE).dbg) +endif + +$(D9_IMAGE).sym: $(D9_DEBUG_IMAGE) + $(call build_cmd,NM,,$@, $(NM) -n $< > $@) + +$(D9_IMAGE).gz: $(D9_IMAGE) + $(call build_cmd,GZ,,$@, $(GZIP) -f -9 -c $< >$@) + +# register images to the build +ifeq ($(CONFIG_PLAT_D9),y) +UK_DEBUG_IMAGES-y += $(D9_DEBUG_IMAGE) +UK_IMAGES-y += $(D9_IMAGE) +ifeq ($(CONFIG_BOOT_PROTO_LXBOOT),y) +UK_IMAGES-y += $(D9_IMAGE).lxboot +endif +UK_IMAGES-$(CONFIG_OPTIMIZE_SYMFILE) += $(D9_IMAGE).sym +UK_IMAGES-$(CONFIG_OPTIMIZE_COMPRESS) += $(D9_IMAGE).gz +endif + +# ...for cleaning: +LIBD9PLAT_CLEAN += $(call build_clean,$(D9_DEBUG_IMAGE).bootinfo) +LIBD9PLAT_CLEAN += $(call build_clean,$(BUILD_DIR)/kernel.img) \ No newline at end of file diff --git a/Makefile.uk b/Makefile.uk new file mode 100644 index 0000000..5308477 --- /dev/null +++ b/Makefile.uk @@ -0,0 +1,68 @@ +## +## D9 platform registration +## +$(eval $(call addplat_s,d9,$(CONFIG_PLAT_D9))) + +## +## D9 platform library registration +## +$(eval $(call addplatlib,d9,libd9plat)) + +## +## Platform library definitions +## +LIBD9PLAT_ASINCLUDES-y += -I$(LIBD9PLAT_BASE)/include +LIBD9PLAT_ASINCLUDES-y += -I$(UK_PLAT_COMMON_BASE)/include +LIBD9PLAT_CINCLUDES-y += -I$(LIBD9PLAT_BASE)/include +LIBD9PLAT_CINCLUDES-y += -I$(UK_PLAT_COMMON_BASE)/include +LIBD9PLAT_CINCLUDES-y += -I$(UK_PLAT_DRIVERS_BASE)/include + +LIBD9PLAT_ASFLAGS += -DD9PLAT -DUK_USE_SECTION_SEGMENTS +LIBD9PLAT_CFLAGS += -DD9PLAT -DUK_USE_SECTION_SEGMENTS +LIBD9PLAT_CXXFLAGS += -DD9PLAT -DUK_USE_SECTION_SEGMENTS + +## +## Default Linker script +UK_PLAT_D9_DEF_LDS := $(UK_PLAT_COMMON_BASE)/arm/link64.lds.S + +## +## Architecture library definitions +## +LIBD9PLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(UK_PLAT_COMMON_BASE)/arm/cpu_native.c|common +LIBD9PLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(UK_PLAT_COMMON_BASE)/arm/cache64.S|common +ifneq ($(CONFIG_HAVE_SYSTICK),y) +LIBD9PLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(UK_PLAT_COMMON_BASE)/arm/generic_timer.c|common +LIBD9PLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(UK_PLAT_COMMON_BASE)/arm/time.c|common +endif +LIBD9PLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(UK_PLAT_COMMON_BASE)/arm/lcpu.c|arm64_common +LIBD9PLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(UK_PLAT_COMMON_BASE)/arm/traps_arm64.c|isr +LIBD9PLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(UK_PLAT_COMMON_BASE)/arm/smccc.c|common +LIBD9PLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(UK_PLAT_COMMON_BASE)/arm/psci.c|common +LIBD9PLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(UK_PLAT_COMMON_BASE)/arm/smccc_invoke.S|common +LIBD9PLAT_SRCS-y += $(UK_PLAT_COMMON_BASE)/lcpu.c|common +LIBD9PLAT_SRCS-y += $(UK_PLAT_COMMON_BASE)/memory.c|common +LIBD9PLAT_SRCS-y += $(UK_PLAT_COMMON_BASE)/tls.c|common +ifeq ($(CONFIG_ENFORCE_W_XOR_X),y) +LIBD9PLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(UK_PLAT_COMMON_BASE)/w_xor_x.c|common +endif +LIBD9PLAT_SRCS-$(CONFIG_FPSIMD) += $(UK_PLAT_COMMON_BASE)/arm/fp_arm64.c|isr +ifeq ($(CONFIG_PAGING),y) +LIBD9PLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(UK_PLAT_COMMON_BASE)/paging.c|isr +endif +LIBD9PLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(UK_PLAT_COMMON_BASE)/arm/lcpu_start.S +LIBD9PLAT_SRCS-y += $(UK_PLAT_COMMON_BASE)/bootinfo.c|common +LIBD9PLAT_SRCS-$(CONFIG_LIBFDT) += $(UK_PLAT_COMMON_BASE)/bootinfo_fdt.c|common +LIBD9PLAT_SRCS-y += $(UK_PLAT_COMMON_BASE)/bootinfo.lds.S|common +LIBD9PLAT_SRCS-y += $(UK_PLAT_COMMON_BASE)/arm/exceptions64.S|arm64_common + +LIBD9PLAT_SRCS-y += $(LIBD9PLAT_BASE)/start.S|isr +LIBD9PLAT_SRCS-y += $(LIBD9PLAT_BASE)/console.c +LIBD9PLAT_SRCS-y += $(LIBD9PLAT_BASE)/lcpu.c +LIBD9PLAT_SRCS-y += $(LIBD9PLAT_BASE)/io.c +LIBD9PLAT_SRCS-y += $(LIBD9PLAT_BASE)/memory.c +LIBD9PLAT_SRCS-y += $(LIBD9PLAT_BASE)/setup.c +LIBD9PLAT_SRCS-y += $(LIBD9PLAT_BASE)/shutdown.c +LIBD9PLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(LIBD9PLAT_BASE)/mmu.S|isr +LIBD9PLAT_SRCS-$(CONFIG_ARCH_ARM_64) += $(LIBD9PLAT_BASE)/d9_bpt64.S|arm +LIBD9PLAT_SRCS-y += $(UK_PLAT_D9_DEF_LDS) + diff --git a/README.en.md b/README.en.md deleted file mode 100644 index 0066828..0000000 --- a/README.en.md +++ /dev/null @@ -1,36 +0,0 @@ -# plat - -#### Description -Tenon芯驰D9平台 - -#### Software Architecture -Software architecture description - -#### Installation - -1. xxxx -2. xxxx -3. xxxx - -#### Instructions - -1. xxxx -2. xxxx -3. xxxx - -#### Contribution - -1. Fork the repository -2. Create Feat_xxx branch -3. Commit your code -4. Create Pull Request - - -#### Gitee Feature - -1. You can use Readme\_XXX.md to support different languages, such as Readme\_en.md, Readme\_zh.md -2. Gitee blog [blog.gitee.com](https://blog.gitee.com) -3. Explore open source project [https://gitee.com/explore](https://gitee.com/explore) -4. The most valuable open source project [GVP](https://gitee.com/gvp) -5. The manual of Gitee [https://gitee.com/help](https://gitee.com/help) -6. The most popular members [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) diff --git a/README.md b/README.md index 283bbbb..7cbb73e 100644 --- a/README.md +++ b/README.md @@ -1,37 +1,79 @@ -# plat +# SemiDrive D9 -#### 介绍 -Tenon芯驰D9平台 +本仓库用于移植Tenon OS到SemiDrive D9系列嵌入式板卡。 -#### 软件架构 -软件架构说明 +## 编译 +以米尔电子MYD-JD9340开发板为例,介绍TenonOS使用本仓库的编译流程: -#### 安装教程 +### 清除配置项 -1. xxxx -2. xxxx -3. xxxx +清除配置项,如有需要请保存原有的.config文件,该文件位于TenonOS源码目录下: -#### 使用说明 +```shell +make distclean +``` -1. xxxx -2. xxxx -3. xxxx +### 配置内核选项 -#### 参与贡献 +配置内核编译选项: -1. Fork 本仓库 -2. 新建 Feat_xxx 分支 -3. 提交代码 -4. 新建 Pull Request +```shell +make menuconfig P=/home/username/workdir/plats/ L=/home/username/workdir/libs +``` +* P:传递给TenonOS的平台微库地址 +* L:传递给TenonOS的功能微库地址地址 -#### 特技 +工作空间目录结构以如下为例: -1. 使用 Readme\_XXX.md 来支持不同的语言,例如 Readme\_en.md, Readme\_zh.md -2. Gitee 官方博客 [blog.gitee.com](https://blog.gitee.com) -3. 你可以 [https://gitee.com/explore](https://gitee.com/explore) 这个地址来了解 Gitee 上的优秀开源项目 -4. [GVP](https://gitee.com/gvp) 全称是 Gitee 最有价值开源项目,是综合评定出的优秀开源项目 -5. Gitee 官方提供的使用手册 [https://gitee.com/help](https://gitee.com/help) -6. Gitee 封面人物是一档用来展示 Gitee 会员风采的栏目 [https://gitee.com/gitee-stars/](https://gitee.com/gitee-stars/) +```shell +. workdir +├── board-support-package /* TenonOS的板级支持包 */ +├── drivers /* 存放驱动微库 */ +├── libs /* 存放各类功能微库 */ +│ ├── lib-musl +│ └── lib-tlsf +├── plats /* 存放适各类开发板的平台微库 */ +│ ├── plat-d9 +│ ├── plat-raspi +│ └── plat-rk3568 +├── tenon /* 基于libos架构的操作系统框架和核心微库 */ +``` + +#### 配置CPU + +```shell +Architecture Selection --> Target Processor --> select: Generic Armv8 Cortex A55 +Architecture Selection --> deselect: Workaround for Cortex-A73 erratum +``` + +#### 配置架构 + +```shell +Architecture Selection --> Architecture --> select: Arrmv8 compatible (64 bits) +``` + +#### 配置平台 + +```shell +Platform Configuration --> select: D9 +``` + +#### 配置串口 + +```shell +Device Drivers --> Serial console --> NS8250 --> Description of serial --> write: serial0 +``` + +#### 配置堆栈 + +如果需要开启LIBUKVMEM,则需要设置heap基地址为: + +```shell +Library Configuration --> ukboot --> Heap base address --> write: 0x800000000 +``` + +如需使用更多功能,请使用Tenon BSP仓库构建[board-support-package][bsp] + +[bsp]: diff --git a/console.c b/console.c new file mode 100644 index 0000000..564e714 --- /dev/null +++ b/console.c @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2024 The TenonOS Authors + */ + +#include +#include + +void _libd9plat_init_console(void *dtb) +{ + ns8250_console_init(dtb); +} + diff --git a/d9_bpt64.S b/d9_bpt64.S new file mode 100644 index 0000000..ed49b92 --- /dev/null +++ b/d9_bpt64.S @@ -0,0 +1,115 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2024 The TenonOS Authors + */ + +#include + +#include +#include + +/* ------------------------- Memory Map of myd-jd9x ----------------------- + * + * 0x0000,0000,0000 - 0x0000,3FFF,FFFF Device: attr:device + * 0x0000,4000,0000 - 0x0000,FFFF,FFFF Normal Mem: 1-4GB attr:normal + * 0x0001,0000,0000 - 0x0004,3FFF,FFFF Normal Mem: 4GB-17GB attr:normal + * 0x0005,0000,0000 - 0x0006,FFFF,FFFF PCIe_MAPPED_IO attr:device + * Notice: The page tables below use the Unikraft indexing convention. + */ + +.section .data +.align 4 +.global bpt_unmap_mrd +bpt_unmap_mrd: + .quad 0x0000000040000000 /* 1GB */ + .quad 0x0000000040000000 /* 1GB */ + /* Used for struct ukplat_memregion_desc + * Unmapping starts at 1GB and ends at 4GB + */ + .quad 0x00000000c0000000 + .short 0x0000000000000000 + .short 0x0000000000000010 /* UKPLAT_MEMRF_UNMAP */ + .space 36 + +.global arm64_bpt_l3_pt0 + +/* L3: 0 - 256TiB (512Gib / entry) + * + * 0x0000 0000 0000 0000 - 0x0000 007f ffff ffff Table descriptor to l2_pt0 + * 0x0000 0080 0000 0000 - 0x0000 00ff ffff ffff Hole + * 0x0000 ff80 0000 0000 - 0x0000 ffff ffff ffff Table descriptor to l2_pt511 + */ +.align 12 +arm64_bpt_l3_pt0: + ur_pte arm64_bpt_l2_pt0, PTE_TYPE_TABLE + pte_zero ,510 +#if CONFIG_PAGING + ur_pte arm64_bpt_l2_pt511, PTE_TYPE_TABLE +#else /* !CONFIG_PAGING */ + pte_zero ,1 +#endif /* !CONFIG_PAGING */ + +/* L2: 0 - 512Gib (1GiB / entry) + * 0x0000 0000 0000 0000 - 0x0000 0000 3FFF FFFF Table descriptor to l1_pt0 + * 0x0000 0000 4000 0000 - 0x0000 0000 7FFF FFFF Table descriptor to l1_pt1 + * 0x0000 0000 8000 0000 - 0x0000 0000 BFFF FFFF NORMAL RAM + * 0x0000 0000 C000 0000 - 0x0000 0000 FFFF FFFF Hole + * 0x0000 0001 0000 0000 - 0x0000 0004 3FFF FFFF DEVICE DDR_MEM_AP_ONLY + * 0x0000 0004 4000 0000 - 0x0000 0004 FFFF FFFF Hole + * 0x0000 0005 0000 0000 - 0x0000 0006 FFFF FFFF DEVICE PCIE_MAPPED_IO + * 0x0000 0007 0000 0000 - 0x0000 0080 0000 0000 Hole + */ +.align 12 +arm64_bpt_l2_pt0: + ur_pte arm64_bpt_l1_pt0, PTE_TYPE_TABLE + ur_pte arm64_bpt_l1_pt1, PTE_TYPE_TABLE + pte_fill 0x80000000, 1, 2, PTE_BLOCK_NORMAL_RWX + pte_zero ,1 + pte_fill 0x100000000, 13, 2, PTE_BLOCK_DEVICE_nGnRnE + pte_zero ,3 + pte_fill 0x500000000, 8, 2, PTE_BLOCK_DEVICE_nGnRnE + pte_zero ,484 + +/* L1: 0 - 1GiB (2MiB / entry) + * 0x0000 0000 0000 0000 - 0x0000 0000 3FFF FFFF DEVICE + */ +.align 12 +arm64_bpt_l1_pt0: + pte_fill 0x00000000, 512, 1, PTE_BLOCK_DEVICE_nGnRnE + +/* L1: 1GiB - 2Gib (2MiB / entry) + * 0x0000 0000 4000 0000 - 0x0000 0000 40A0 0000 Hole + * 0x0000 0000 40A0 0000 - 0x0000 0000 40BF FFFF Table descriptor to l0_pt5 + * 0x0000 0000 40C0 0000 - 0x0000 0000 459F FFFF NORMAL RAM + * 0x0000 0000 45A0 0000 - 0x0000 0000 571F FFFF Hole + * 0x0000 0000 5720 0000 - 0x0000 0000 771F FFFF NORMAL RAM + * 0x0000 0000 7720 0000 - 0x0000 0000 7c5F FFFF Hole + * 0x0000 0000 7C60 0000 - 0x0000 0000 7FFF FFFF NORMAL RAM + */ +.align 12 +arm64_bpt_l1_pt1: + pte_zero ,5 + ur_pte arm64_bpt_l0_pt5, PTE_TYPE_TABLE + pte_fill 0x40c00000, 40, 1, PTE_BLOCK_NORMAL_RWX + pte_zero ,139 + pte_fill 0x57200000, 256, 1, PTE_BLOCK_NORMAL_RWX + pte_zero ,42 + pte_fill 0x7C600000, 29, 1, PTE_BLOCK_NORMAL_RWX + +/* L0: (2MiB / entry) + * 0x0000 0000 40A0 0000 - 0x0000 0000 40A0 3FFF Hole + * 0x0000 0000 40A0 4000 - 0x0000 0000 40C0 0000 NORMAL RAM + */ +.align 12 +arm64_bpt_l0_pt5: + pte_zero ,4 + pte_fill 0x40a04000, 508, 0, PTE_PAGE_NORMAL_RWX + +#if CONFIG_PAGING +/* L2: 255.5 TiB - 256TiB (1GiB / entry) + * + * 0x0000ff8000000000 - 0x0000ffffffffffff Direct-mapped + */ +.align 12 +arm64_bpt_l2_pt511: + pte_fill 0x0000000000000000, 512, 2, PTE_BLOCK_NORMAL_RW +#endif /* CONFIG_PAGING */ diff --git a/include/d9/console.h b/include/d9/console.h new file mode 100644 index 0000000..80ec165 --- /dev/null +++ b/include/d9/console.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2024 The TenonOS Authors + */ + +#ifndef __D9_CONSOLE_H__ +#define __D9_CONSOLE_H__ + +void _libd9plat_init_console(void *dtb); +#endif /* __D9_CONSOLE_H__ */ diff --git a/include/d9/sysregs.h b/include/d9/sysregs.h new file mode 100644 index 0000000..177960c --- /dev/null +++ b/include/d9/sysregs.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2024 The TenonOS Authors + */ + +#ifndef __D9_SYSREGS_H__ +#define __D9_SYSREGS_H__ + +#include +#include + +// *************************************** +// HCR_EL2, Hypervisor Configuration Register (EL2), +// Page 351 of Cortex-A55 Core Techinical-Reference-Manual. +// *************************************** + +#define HCR_EL2_VALUE (HCR_EL2_RW) +#define SCTLR_EL2_VALUE (0) + +// *************************************** +// CPACR_EL1, Architectural Feature Access Control Register. +// *************************************** + +#define CPACR_EL1_VALUE (CPACR_EL1_FPEN_TRAP_NONE) + +#define SPSR_EL2_VALUE (SPSR_MASK_ALL | SPSR_ELxh) + +#endif /* __D9_SYSREGS_H__ */ \ No newline at end of file diff --git a/io.c b/io.c new file mode 100644 index 0000000..ec54113 --- /dev/null +++ b/io.c @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2024 The TenonOS Authors + */ + +#include + +/** + * TODO: + * For d9 platform, the guest virtual address = guest physical address. + * We may have to reconsider this implementation when condition changes. + */ + +__paddr_t ukplat_virt_to_phys(const __volatile__ void *address) +{ + return (__paddr_t)address; +} diff --git a/lcpu.c b/lcpu.c new file mode 100644 index 0000000..22d363e --- /dev/null +++ b/lcpu.c @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2024 The TenonOS Authors + */ + +#include + +#include + +#include +#include + +void ukplat_lcpu_enable_irq(void) +{ + local_irq_enable(); +} + +void ukplat_lcpu_disable_irq(void) +{ + local_irq_disable(); +} + +void ukplat_lcpu_halt_irq(void) +{ + UK_ASSERT(ukplat_lcpu_irqs_disabled()); + + halt(); +} + +unsigned long ukplat_lcpu_save_irqf(void) +{ + unsigned long flags; + + local_irq_save(flags); + + return flags; +} + +void ukplat_lcpu_restore_irqf(unsigned long flags) +{ + local_irq_restore(flags); +} + +int ukplat_lcpu_irqs_disabled(void) +{ + return irqs_disabled(); +} + +void ukplat_lcpu_irqs_handle_pending(void) +{ + // TODO +} + +unsigned int tnplat_lcpu_physical_index(__lcpuid_p cpuid) +{ + return (cpuid & MPIDR_AFF1_MASK) >> MPIDR_AFF1_SHIFT; +} \ No newline at end of file diff --git a/memory.c b/memory.c new file mode 100644 index 0000000..e5a4f0c --- /dev/null +++ b/memory.c @@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2024 The TenonOS Authors + */ + +int _ukplat_mem_mappings_init(void) +{ + return 0; +} diff --git a/mmu.S b/mmu.S new file mode 100644 index 0000000..a77112a --- /dev/null +++ b/mmu.S @@ -0,0 +1,84 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2024 The TenonOS Authors + */ + + +#include +#include +#include +#include + +ENTRY(start_mmu) + /* Load ttbr0, pagetable starts from _end */ + ur_ldr x27, arm64_bpt_l3_pt0 + msr ttbr0_el1, x27 + isb + + /* Clear the Monitor Debug System control register */ + msr mdscr_el1, xzr + + /* Invalidate the TLB to avoid stale one */ + tlbi vmalle1 + dsb nsh + + ldr x2, =MAIR_INIT_ATTR + msr mair_el1, x2 + +#ifdef CONFIG_PAGING + /* Set up TCR_EL1. The platform must provide a + * configuration compatible with the paging API. + */ + ldr x2, =TCR_INIT_FLAGS + msr tcr_el1, x2 +#else /* CONFIG_PAGING */ + /* Get VIRT_BITS from id_aa64mmfr0_el1.PARange */ + mrs x3, id_aa64mmfr0_el1 + ur_ldr x5, tcr_ips_bits + ubfx x4, x3, #0, #4 + ldrb w4, [x5, x4] + cmp x4, #52 + b.lt setup_tcr_el1 + /* + * We currently do not provide 5-level page tables used in + * implementing 52-bit virtual addresing with 4K granularity, so we + * enforce the max VA to 48-bit for PARange >= 52. + */ + mov x4, #48 +setup_tcr_el1: + /* Setup TCR_EL1_TxSZ(64 - VIRT_BITS) for TCR_INIT_FLAGS */ + mov x5, #64 + sub x5, x5, x4 + mov x4, x5 + lsl x5, x5, #TCR_EL1_T1SZ_SHIFT + orr x5, x4, x5 + ldr x2, =TCR_INIT_FLAGS + orr x2, x5, x2 + bfi x2, x3, #32, #3 + msr tcr_el1, x2 +#endif /* CONFIG_PAGING */ + + /* Setup SCTLR */ + ldr x2, =SCTLR_SET_BITS + ldr x3, =SCTLR_CLEAR_BITS + mrs x1, sctlr_el1 + bic x1, x1, x3 /* Clear the required bits */ + orr x1, x1, x2 /* Set the required bits */ + msr sctlr_el1, x1 + isb + + ret +END(start_mmu) + +ENTRY(clear_bss) +clear_bss_start: + // Clear bss + ldr x1, =__bss_start + ldr w2, =__bss_size +clear_bss_loop: + cbz w2, clear_bss_done + str xzr, [x1], #8 + sub w2, w2, #1 + cbnz w2, clear_bss_loop +clear_bss_done: + ret +END(clear_bss) diff --git a/setup.c b/setup.c new file mode 100644 index 0000000..48c3c96 --- /dev/null +++ b/setup.c @@ -0,0 +1,124 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2024 The TenonOS Authors + */ + +#include +#include + +#include +#include +#include +#include +#include +#include +#if CONFIG_ENFORCE_W_XOR_X && CONFIG_PAGING +#include +#endif /* CONFIG_ENFORCE_W_XOR_X && CONFIG_PAGING */ + +static char *cmdline; +static __sz cmdline_len; + +static inline int cmdline_init(struct ukplat_bootinfo *bi) +{ + char *cmdl; + + if (bi->cmdline_len) { + cmdl = (char *)bi->cmdline; + cmdline_len = bi->cmdline_len; + } else { + cmdl = CONFIG_UK_NAME; + cmdline_len = sizeof(CONFIG_UK_NAME) - 1; + } + + /* TODO: Only extract what we need before passing to application. */ + + /* This is not the original command-line, but one that will be thrashed + * by `ukplat_entry_argp` to obtain argc/argv. So mark it as a kernel + * resource instead. + */ + cmdline = ukplat_memregion_alloc(cmdline_len + 1, UKPLAT_MEMRT_KERNEL, + UKPLAT_MEMRF_READ | UKPLAT_MEMRF_WRITE | + UKPLAT_MEMRF_MAP); + if (unlikely(!cmdline)) + return -ENOMEM; + + memcpy(cmdline, cmdl, cmdline_len); + cmdline[cmdline_len] = 0; + + return 0; +} + +static void __noreturn _ukplat_entry2(void) +{ + ukplat_entry_argp(NULL, cmdline, cmdline_len); + + ukplat_lcpu_halt(); +} + +void _libd9plat_entry(void *fdtp) +{ + int rc; + void *bstack; + struct ukplat_bootinfo *bi; + + ukplat_bootinfo_fdt_setup(fdtp); + + _libd9plat_init_console(fdtp); + + bi = ukplat_bootinfo_get(); + + if (unlikely(!bi)) + UK_CRASH("Invalid bootinfo"); + + rc = cmdline_init(bi); + if (unlikely(rc < 0)) + UK_CRASH("Failed to initialize command-line\n"); + + /* Allocate boot stack */ + bstack = ukplat_memregion_alloc(__STACK_SIZE, UKPLAT_MEMRT_STACK, + UKPLAT_MEMRF_READ | UKPLAT_MEMRF_WRITE | + UKPLAT_MEMRF_MAP); + if (unlikely(!bstack)) + UK_CRASH("Boot stack alloc failed\n"); + bstack = (void *)((__uptr)bstack + __STACK_SIZE); + + /* Initialize paging */ + rc = ukplat_mem_init(); + if (unlikely(rc)) + UK_CRASH("Could not initialize paging (%d)\n", rc); + +#if defined(CONFIG_ENFORCE_W_XOR_X) && defined(CONFIG_PAGING) + /* Print boot information */ + ukplat_bootinfo_print(); + enforce_w_xor_x(); +#endif /* CONFIG_ENFORCE_W_XOR_X && CONFIG_PAGING */ + + /* Initialize logical boot CPU */ + rc = lcpu_init(lcpu_alloc(get_bootstrap_cpu_physical_id())); + if (unlikely(rc)) + UK_CRASH("Failed to initialize bootstrapping CPU: %d\n", rc); + + /* Initialize interrupt controller */ + rc = uk_intctlr_probe(); + if (unlikely(rc)) + UK_CRASH("Could not initialize the IRQ controller: %d\n", rc); + + /* Initialize PSCI */ + rc = get_psci_method(bi); + if (unlikely(rc < 0)) + UK_CRASH("Failed to get PSCI method: %d.\n", rc); + + /* + * Switch away from the bootstrap stack as early as possible. + */ + uk_pr_info("Switch from bootstrap stack to stack @%p\n", bstack); + + /* Print boot information */ + uk_pr_info("Print bootinfo before jump to entry:\n"); + ukplat_bootinfo_print(); + + /* + * Enter Unikraft with new allocated stack. + */ + lcpu_arch_jump_to(bstack, _ukplat_entry2); +} diff --git a/shutdown.c b/shutdown.c new file mode 100644 index 0000000..3492cc4 --- /dev/null +++ b/shutdown.c @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2024 The TenonOS Authors + */ + +#include + +#include +#include +#include + +static void cpu_halt(void) __noreturn; + +void ukplat_terminate(enum ukplat_gstate request) +{ + /* Try to make system off */ + system_off(request); + + cpu_halt(); +} + +static void cpu_halt(void) +{ + __CPU_HALT(); +} + +int ukplat_suspend(void) +{ + return -EBUSY; +} diff --git a/start.S b/start.S new file mode 100644 index 0000000..2dfd816 --- /dev/null +++ b/start.S @@ -0,0 +1,95 @@ +/* SPDX-License-Identifier: Apache-2.0 + * Copyright 2024 The TenonOS Authors + */ + +#include +#include +#include +#include +#include +#include + +#define BOOTSTACK_SIZE 4096 + +.section .bss +.align 16 +.space BOOTSTACK_SIZE +lcpu_bootstack: + +.section ".text.boot" +ENTRY(_start) + /* preserve dtb addr */ + mov x25, x0 + + /* detect EL level */ + switch_el x0, el2_entry, el1_entry + +el2_entry: + ldr x0, =SCTLR_EL2_VALUE + msr sctlr_el2, x0 + isb + + // define register width, el1: aarch64, el0: by code. other bits are 0. + ldr x0, =HCR_EL2_VALUE + msr hcr_el2, x0 + + // Set the SPSR state to restore when returning from EL2 to EL1 + ldr x0, =SPSR_EL2_VALUE + msr spsr_el2, x0 + + // set return address when returning from EL2 to EL1 + adr x0, el1_entry + msr elr_el2, x0 + + eret + +el1_entry: + // disable mmu and cache + mrs x2, sctlr_el1 + mov x3, #SCTLR_EL1_M_BIT|SCTLR_EL1_C_BIT + bic x2, x2, x3 + msr sctlr_el1, x2 + + // Disable coprocessor traps + ldr x0, =CPACR_EL1_VALUE + msr cpacr_el1, x0 + + /* + * We will disable MMU and cache before the pagetables are ready. + * This means we will change memory with cache disabled, so we need to + * invalidate the cache to ensure there is no stale data in it. + * But it would be expensive to invalidate the whole cache. + * In this case, just need to invalidate what we are going to use: + * DTB, TEXT, DATA, BSS, and bootstack. + */ + ldr x0, =_start_ram_addr + ldr x1, =_end + sub x1, x1, x0 + bl clean_and_invalidate_dcache_range + + /* Enable the mmu */ + bl start_mmu + + bl clear_bss + + ldr x0, =lcpu_bootstack + and x0, x0, ~(__STACK_ALIGN_SIZE - 1) + mov sp, x0 + + /* Set exception vector table*/ + ldr x0, =vectors_el1 + msr vbar_el1, x0 + + /* Set the context id */ + msr contextidr_el1, xzr + + bl set_bootstrap_cpu + + ldr x0, =lcpus + msr tpidr_el1, x0 + + /* Load dtb address to x0 as a parameter */ + mov x0, x25 + + bl _libd9plat_entry +END(_start) -- Gitee