From 46bbedff23f449fa836e664c55925a78d804094e Mon Sep 17 00:00:00 2001 From: Amneesh Singh Date: Mon, 23 Sep 2024 12:23:05 +0530 Subject: [PATCH 1/4] drivers: xen: init - Add basic xen hypercall mechanism - Add helper functions to print to xen console - Add helper functions to print to xen PV console - Add --xen-enable flag to the build system - Enable Xen for AM62 and AM62P - AM62: Edit addresses in a53 linker template for xen Signed-off-by: Amneesh Singh --- .project/cgt/cgt_gcc-aarch64.js | 3 + .project/common.js | 15 ++ .project/device/project_am62px.js | 3 + .project/device/project_am62x.js | 3 + .project/genExampleFiles.js | 1 + .project/project.js | 5 + .../templates/am62x/common/linker_a53.cmd.xdt | 13 +- .../templates/am62x/nortos/main_nortos.c.xdt | 4 + makefile | 2 +- source/drivers/xen/.project/project.js | 55 ++++++ .../xen/makefile.am62ax.a53.gcc-aarch64 | 115 +++++++++++ .../xen/makefile.am62dx.a53.gcc-aarch64 | 115 +++++++++++ .../xen/makefile.am62px.a53.gcc-aarch64 | 115 +++++++++++ .../xen/makefile.am62x.a53.gcc-aarch64 | 115 +++++++++++ source/drivers/xen/xen_console.c | 182 ++++++++++++++++++ source/drivers/xen/xen_console.h | 14 ++ source/drivers/xen/xen_events.c | 87 +++++++++ source/drivers/xen/xen_events.h | 48 +++++ source/drivers/xen/xen_hvm.c | 22 +++ source/drivers/xen/xen_hvm.h | 21 ++ source/drivers/xen/xen_hypercall.S | 18 ++ source/drivers/xen/xen_hypercall.h | 21 ++ source/drivers/xen/xen_os.h | 81 ++++++++ 23 files changed, 1055 insertions(+), 3 deletions(-) create mode 100755 source/drivers/xen/.project/project.js create mode 100644 source/drivers/xen/makefile.am62ax.a53.gcc-aarch64 create mode 100644 source/drivers/xen/makefile.am62dx.a53.gcc-aarch64 create mode 100644 source/drivers/xen/makefile.am62px.a53.gcc-aarch64 create mode 100644 source/drivers/xen/makefile.am62x.a53.gcc-aarch64 create mode 100644 source/drivers/xen/xen_console.c create mode 100644 source/drivers/xen/xen_console.h create mode 100644 source/drivers/xen/xen_events.c create mode 100644 source/drivers/xen/xen_events.h create mode 100644 source/drivers/xen/xen_hvm.c create mode 100644 source/drivers/xen/xen_hvm.h create mode 100644 source/drivers/xen/xen_hypercall.S create mode 100644 source/drivers/xen/xen_hypercall.h create mode 100644 source/drivers/xen/xen_os.h diff --git a/.project/cgt/cgt_gcc-aarch64.js b/.project/cgt/cgt_gcc-aarch64.js index 65a8ca4b5d..2d02bd9a2e 100644 --- a/.project/cgt/cgt_gcc-aarch64.js +++ b/.project/cgt/cgt_gcc-aarch64.js @@ -10,6 +10,9 @@ const cgt_a53 ={ "-mstrict-align", "-mfix-cortex-a53-835769", "-mfix-cortex-a53-843419", + ... common.isXenEnabled() ? [ + "-DXEN_ENABLED" + ] : [] ], }, } diff --git a/.project/common.js b/.project/common.js index 64f9308066..d2b0b7dda2 100755 --- a/.project/common.js +++ b/.project/common.js @@ -184,12 +184,27 @@ function setInstrumentationMode(mode) genInstrumentationMode = mode; } +/* xen is disabled by default */ +let xenEnabled = false; + +function isXenEnabled() +{ + return xenEnabled; +} + +function setXenEnabled(enabled) +{ + xenEnabled = enabled; +} + module.exports = { genBuildfiles, isDevelopmentMode, setGenBuildFilesMode, isInstrumentationMode, setInstrumentationMode, + isXenEnabled, + setXenEnabled, cleanBuildfiles, mergeCgtOptions, convertTemplateToFile, diff --git a/.project/device/project_am62px.js b/.project/device/project_am62px.js index 57f8f47423..7a6e99cd55 100644 --- a/.project/device/project_am62px.js +++ b/.project/device/project_am62px.js @@ -28,6 +28,9 @@ const component_file_list = [ "source/safety_checkers/.project/project.js", "docs_src/docs/api_guide/doxy_samples/.project/project.js", "test/unity/.project/project.js", + ... common.isXenEnabled() ? [ + "source/drivers/xen/.project/project.js", + ] : [] ]; // List of components where makefile is not generated. diff --git a/.project/device/project_am62x.js b/.project/device/project_am62x.js index 6957f9a89c..f7596040d1 100644 --- a/.project/device/project_am62x.js +++ b/.project/device/project_am62x.js @@ -18,6 +18,9 @@ const component_file_list = [ "source/safety_checkers/.project/project.js", "test/unity/.project/project.js", "docs_src/docs/api_guide/doxy_samples/.project/project.js", + ... common.isXenEnabled() ? [ + "source/drivers/xen/.project/project.js", + ] : [] ]; // List of components where makefile is not generated. diff --git a/.project/genExampleFiles.js b/.project/genExampleFiles.js index 5b8f62ceb0..a7a97b1f5c 100755 --- a/.project/genExampleFiles.js +++ b/.project/genExampleFiles.js @@ -38,6 +38,7 @@ function genExampleFilesDevice(device) { project: project, options: template.options, isInstrumentation: isInstrumentation, + isXenEnabled: common.isXenEnabled, }; common.convertTemplateToFile( diff --git a/.project/project.js b/.project/project.js index f4f62c27d1..46e124e485 100755 --- a/.project/project.js +++ b/.project/project.js @@ -27,6 +27,10 @@ const argv = yargs default: "disable", array: false }) + .option('enable-xen', { + description: 'L1 Hypervisor', + type: 'boolean', + }) .help() .alias('help', 'h') .argv; @@ -41,6 +45,7 @@ if(argv.target == "clean") { else { common.setGenBuildFilesMode(argv.target); common.setInstrumentationMode(argv.instrumentation); + common.setXenEnabled(!!argv.enableXen); for(device of argv.device) { console.log(`Generating build files for ${device} in ${argv.target} mode ...`); common.genBuildfiles(device); diff --git a/.project/templates/am62x/common/linker_a53.cmd.xdt b/.project/templates/am62x/common/linker_a53.cmd.xdt index 4aeb344fae..6cb5298a12 100644 --- a/.project/templates/am62x/common/linker_a53.cmd.xdt +++ b/.project/templates/am62x/common/linker_a53.cmd.xdt @@ -41,6 +41,15 @@ let addrBaseDdr = 0x80000000; let codeDataSizeDdr = 0x1000000; + let shmOrigin = 0x82000000; + let scratchBufOrigin = 0x82000080; + + if(args.isXenEnabled()) { + addrBaseDdr = 0x40000000; + shmOrigin = 0x42000000; + scratchBufOrigin = 0x42000080; + } + /* if no options given use defaults */ if(options && options.stackSize) stackSize = options.stackSize; @@ -90,7 +99,7 @@ MEMORY { /* On A53, * - make sure there is a MMU entry which maps below regions as non-cache */ - USER_SHM_MEM : ORIGIN = 0x82000000, LENGTH = 0x80 + USER_SHM_MEM : ORIGIN = 0x`(shmOrigin).toString(16).toUpperCase()`, LENGTH = 0x80 % if(args.project.isLogSHM === true){ LOG_SHM_MEM : ORIGIN = 0xA1000000, LENGTH = 0x40000 %} @@ -99,7 +108,7 @@ MEMORY { %} % if(globalScratchBuf == "true") { /* global scratch buffer region in DDR (32 MB) */ - GLOBAL_SCRATCH_BUFF (RWIX): ORIGIN = 0x82000080 LENGTH = 0x02000000 + GLOBAL_SCRATCH_BUFF (RWIX): ORIGIN = 0x`(scratchBufOrigin).toString(16).toUpperCase()` LENGTH = 0x02000000 % } } diff --git a/.project/templates/am62x/nortos/main_nortos.c.xdt b/.project/templates/am62x/nortos/main_nortos.c.xdt index 4890b3e5c0..0d54afe1de 100755 --- a/.project/templates/am62x/nortos/main_nortos.c.xdt +++ b/.project/templates/am62x/nortos/main_nortos.c.xdt @@ -50,7 +50,9 @@ int main() { int32_t status = SystemP_SUCCESS; + % if(!args.isXenEnabled()) { System_init(); + % } Board_init(); /* Open drivers */ @@ -67,7 +69,9 @@ int main() Drivers_close(); Board_deinit(); + % if(!args.isXenEnabled()) { System_deinit(); + % } return 0; } diff --git a/makefile b/makefile index b46a04cb5d..3fcd264bce 100755 --- a/makefile +++ b/makefile @@ -143,7 +143,7 @@ docs-clean: $(MAKE) -C docs_src/docs/api_guide clean DEVICE=$(DEVICE) DOC_COMBO=$(DOC_COMBO) gen-buildfiles: - $(NODE) ./.project/project.js --device $(DEVICE) --target $(GEN_BUILDFILES_TARGET) --instrumentation $(INSTRUMENTATION_MODE) + $(NODE) ./.project/project.js --device $(DEVICE) --target $(GEN_BUILDFILES_TARGET) --instrumentation $(INSTRUMENTATION_MODE) $(if $(ENABLE_XEN),--enable-xen) gen-buildfiles-clean: $(NODE) ./.project/project.js --device $(DEVICE) --target clean diff --git a/source/drivers/xen/.project/project.js b/source/drivers/xen/.project/project.js new file mode 100755 index 0000000000..a4398f7e4a --- /dev/null +++ b/source/drivers/xen/.project/project.js @@ -0,0 +1,55 @@ +let path = require('path'); + +const files = { + common: [ + "xen_console.c", + "xen_events.c", + "xen_hvm.c", + ], +}; + +const asmfiles = { + common: [ + "xen_hypercall.S", + ], +}; + +const filedirs = { + common: [ + ".", + ], +}; + + +function getComponentProperty(device) { + const buildOptionCombos = [ + { device: device, cpu: "a53", cgt: "gcc-aarch64", os: "nortos" }, + { device: device, cpu: "a53", cgt: "gcc-aarch64", os: "freertos" }, + ]; + let property = {}; + + property.dirPath = path.resolve(__dirname, ".."); + property.type = "library"; + property.name = "xen"; + property.isInternal = false; + property.buildOptionCombos = buildOptionCombos; + + return property; +} + +function getComponentBuildProperty(buildOption) { + let build_property = {}; + + if(buildOption.cpu.match(/a53*/)){ + build_property.files = files; + build_property.asmfiles = asmfiles; + build_property.filedirs = filedirs; + } + + return build_property; +} + +module.exports = { + getComponentProperty, + getComponentBuildProperty, +}; diff --git a/source/drivers/xen/makefile.am62ax.a53.gcc-aarch64 b/source/drivers/xen/makefile.am62ax.a53.gcc-aarch64 new file mode 100644 index 0000000000..a3bdf3b4ae --- /dev/null +++ b/source/drivers/xen/makefile.am62ax.a53.gcc-aarch64 @@ -0,0 +1,115 @@ +# +# Auto generated makefile +# + +export MCU_PLUS_SDK_PATH?=$(abspath ../../..) +include $(MCU_PLUS_SDK_PATH)/imports.mak + +CG_TOOL_ROOT=$(CGT_GCC_AARCH64_PATH) + +CC=$(CGT_GCC_AARCH64_PATH)/bin/aarch64-none-elf-gcc +AR=$(CGT_GCC_AARCH64_PATH)/bin/aarch64-none-elf-gcc-ar + +PROFILE?=release +ConfigName:=$(PROFILE) + +LIBNAME:=xen.am62ax.a53.gcc-aarch64.$(PROFILE).lib + +FILES_common := \ + xen_console.c \ + xen_events.c \ + xen_hvm.c \ + +ASMFILES_common := \ + xen_hypercall.S \ + +FILES_PATH_common = \ + . \ + +INCLUDES_common := \ + -I${MCU_PLUS_SDK_PATH}/source \ + +DEFINES_common := \ + -DSOC_AM62X \ + +CFLAGS_common := \ + -mcpu=cortex-a53+fp+simd \ + -mabi=lp64 \ + -mcmodel=large \ + -mstrict-align \ + -mfix-cortex-a53-835769 \ + -mfix-cortex-a53-843419 \ + -DXEN_ENABLED \ + -Wall \ + -Werror \ + -g \ + -Wno-int-to-pointer-cast \ + -Wno-pointer-to-int-cast \ + -Wno-unused-but-set-variable \ + -fdata-sections \ + -ffunction-sections \ + +CFLAGS_debug := \ + -D_DEBUG_=1 \ + +CFLAGS_release := \ + -O2 \ + +ARFLAGS_common := \ + cr \ + +FILES := $(FILES_common) $(FILES_$(PROFILE)) +ASMFILES := $(ASMFILES_common) $(ASMFILES_$(PROFILE)) +FILES_PATH := $(FILES_PATH_common) $(FILES_PATH_$(PROFILE)) +CFLAGS := $(CFLAGS_common) $(CFLAGS_$(PROFILE)) +ASMFLAGS := $(CFLAGS_common) $(CFLAGS_$(PROFILE)) +ifeq ($(CPLUSPLUS_BUILD), yes) +CFLAGS += $(CFLAGS_cpp_common) +endif +DEFINES := $(DEFINES_common) $(DEFINES_$(PROFILE)) +INCLUDES := $(INCLUDES_common) $(INCLUDE_$(PROFILE)) +ARFLAGS := $(ARFLAGS_common) $(ARFLAGS_$(PROFILE)) + +LIBDIR := lib +OBJDIR := obj/am62ax/gcc-aarch64/$(PROFILE)/a53/xen/ +OBJS := $(FILES:%.c=%.obj) +OBJS += $(ASMFILES:%.S=%.obj) +DEPS := $(FILES:%.c=%.d) + +vpath %.obj $(OBJDIR) +vpath %.c $(FILES_PATH) +vpath %.S $(FILES_PATH) + +$(OBJDIR)/%.obj %.obj: %.c + @echo Compiling: $(LIBNAME): $< + $(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) -MMD -MT $@ -o $(OBJDIR)/$@ $< + +$(OBJDIR)/%.obj %.obj: %.S + @echo Compiling: $(LIBNAME): $< + $(CC) -c -x assembler-with-cpp $(CFLAGS) $(INCLUDES) $(DEFINES) -o $(OBJDIR)$@ $< + +all: $(LIBDIR)/$(LIBNAME) + +$(LIBDIR)/$(LIBNAME): $(OBJS) | $(LIBDIR) + @echo . + @echo Archiving: $(LIBNAME) to $@ ... + $(AR) $(ARFLAGS) $@ $(addprefix $(OBJDIR), $(OBJS)) + @echo Archiving: $(LIBNAME) Done !!! + @echo . + +clean: + @echo Cleaning: $(LIBNAME) ... + $(RMDIR) $(OBJDIR) + $(RM) $(LIBDIR)/$(LIBNAME) + +scrub: + @echo Scrubing: $(LIBNAME) ... + -$(RMDIR) obj/ + -$(RMDIR) lib/ + +$(OBJS): | $(OBJDIR) + +$(LIBDIR) $(OBJDIR): + $(MKDIR) $@ + +-include $(addprefix $(OBJDIR)/, $(DEPS)) diff --git a/source/drivers/xen/makefile.am62dx.a53.gcc-aarch64 b/source/drivers/xen/makefile.am62dx.a53.gcc-aarch64 new file mode 100644 index 0000000000..ec97fb15b1 --- /dev/null +++ b/source/drivers/xen/makefile.am62dx.a53.gcc-aarch64 @@ -0,0 +1,115 @@ +# +# Auto generated makefile +# + +export MCU_PLUS_SDK_PATH?=$(abspath ../../..) +include $(MCU_PLUS_SDK_PATH)/imports.mak + +CG_TOOL_ROOT=$(CGT_GCC_AARCH64_PATH) + +CC=$(CGT_GCC_AARCH64_PATH)/bin/aarch64-none-elf-gcc +AR=$(CGT_GCC_AARCH64_PATH)/bin/aarch64-none-elf-gcc-ar + +PROFILE?=release +ConfigName:=$(PROFILE) + +LIBNAME:=xen.am62dx.a53.gcc-aarch64.$(PROFILE).lib + +FILES_common := \ + xen_console.c \ + xen_events.c \ + xen_hvm.c \ + +ASMFILES_common := \ + xen_hypercall.S \ + +FILES_PATH_common = \ + . \ + +INCLUDES_common := \ + -I${MCU_PLUS_SDK_PATH}/source \ + +DEFINES_common := \ + -DSOC_AM62X \ + +CFLAGS_common := \ + -mcpu=cortex-a53+fp+simd \ + -mabi=lp64 \ + -mcmodel=large \ + -mstrict-align \ + -mfix-cortex-a53-835769 \ + -mfix-cortex-a53-843419 \ + -DXEN_ENABLED \ + -Wall \ + -Werror \ + -g \ + -Wno-int-to-pointer-cast \ + -Wno-pointer-to-int-cast \ + -Wno-unused-but-set-variable \ + -fdata-sections \ + -ffunction-sections \ + +CFLAGS_debug := \ + -D_DEBUG_=1 \ + +CFLAGS_release := \ + -O2 \ + +ARFLAGS_common := \ + cr \ + +FILES := $(FILES_common) $(FILES_$(PROFILE)) +ASMFILES := $(ASMFILES_common) $(ASMFILES_$(PROFILE)) +FILES_PATH := $(FILES_PATH_common) $(FILES_PATH_$(PROFILE)) +CFLAGS := $(CFLAGS_common) $(CFLAGS_$(PROFILE)) +ASMFLAGS := $(CFLAGS_common) $(CFLAGS_$(PROFILE)) +ifeq ($(CPLUSPLUS_BUILD), yes) +CFLAGS += $(CFLAGS_cpp_common) +endif +DEFINES := $(DEFINES_common) $(DEFINES_$(PROFILE)) +INCLUDES := $(INCLUDES_common) $(INCLUDE_$(PROFILE)) +ARFLAGS := $(ARFLAGS_common) $(ARFLAGS_$(PROFILE)) + +LIBDIR := lib +OBJDIR := obj/am62dx/gcc-aarch64/$(PROFILE)/a53/xen/ +OBJS := $(FILES:%.c=%.obj) +OBJS += $(ASMFILES:%.S=%.obj) +DEPS := $(FILES:%.c=%.d) + +vpath %.obj $(OBJDIR) +vpath %.c $(FILES_PATH) +vpath %.S $(FILES_PATH) + +$(OBJDIR)/%.obj %.obj: %.c + @echo Compiling: $(LIBNAME): $< + $(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) -MMD -MT $@ -o $(OBJDIR)/$@ $< + +$(OBJDIR)/%.obj %.obj: %.S + @echo Compiling: $(LIBNAME): $< + $(CC) -c -x assembler-with-cpp $(CFLAGS) $(INCLUDES) $(DEFINES) -o $(OBJDIR)$@ $< + +all: $(LIBDIR)/$(LIBNAME) + +$(LIBDIR)/$(LIBNAME): $(OBJS) | $(LIBDIR) + @echo . + @echo Archiving: $(LIBNAME) to $@ ... + $(AR) $(ARFLAGS) $@ $(addprefix $(OBJDIR), $(OBJS)) + @echo Archiving: $(LIBNAME) Done !!! + @echo . + +clean: + @echo Cleaning: $(LIBNAME) ... + $(RMDIR) $(OBJDIR) + $(RM) $(LIBDIR)/$(LIBNAME) + +scrub: + @echo Scrubing: $(LIBNAME) ... + -$(RMDIR) obj/ + -$(RMDIR) lib/ + +$(OBJS): | $(OBJDIR) + +$(LIBDIR) $(OBJDIR): + $(MKDIR) $@ + +-include $(addprefix $(OBJDIR)/, $(DEPS)) diff --git a/source/drivers/xen/makefile.am62px.a53.gcc-aarch64 b/source/drivers/xen/makefile.am62px.a53.gcc-aarch64 new file mode 100644 index 0000000000..1a94638385 --- /dev/null +++ b/source/drivers/xen/makefile.am62px.a53.gcc-aarch64 @@ -0,0 +1,115 @@ +# +# Auto generated makefile +# + +export MCU_PLUS_SDK_PATH?=$(abspath ../../..) +include $(MCU_PLUS_SDK_PATH)/imports.mak + +CG_TOOL_ROOT=$(CGT_GCC_AARCH64_PATH) + +CC=$(CGT_GCC_AARCH64_PATH)/bin/aarch64-none-elf-gcc +AR=$(CGT_GCC_AARCH64_PATH)/bin/aarch64-none-elf-gcc-ar + +PROFILE?=release +ConfigName:=$(PROFILE) + +LIBNAME:=xen.am62px.a53.gcc-aarch64.$(PROFILE).lib + +FILES_common := \ + xen_console.c \ + xen_events.c \ + xen_hvm.c \ + +ASMFILES_common := \ + xen_hypercall.S \ + +FILES_PATH_common = \ + . \ + +INCLUDES_common := \ + -I${MCU_PLUS_SDK_PATH}/source \ + +DEFINES_common := \ + -DSOC_AM62X \ + +CFLAGS_common := \ + -mcpu=cortex-a53+fp+simd \ + -mabi=lp64 \ + -mcmodel=large \ + -mstrict-align \ + -mfix-cortex-a53-835769 \ + -mfix-cortex-a53-843419 \ + -DXEN_ENABLED \ + -Wall \ + -Werror \ + -g \ + -Wno-int-to-pointer-cast \ + -Wno-pointer-to-int-cast \ + -Wno-unused-but-set-variable \ + -fdata-sections \ + -ffunction-sections \ + +CFLAGS_debug := \ + -D_DEBUG_=1 \ + +CFLAGS_release := \ + -O2 \ + +ARFLAGS_common := \ + cr \ + +FILES := $(FILES_common) $(FILES_$(PROFILE)) +ASMFILES := $(ASMFILES_common) $(ASMFILES_$(PROFILE)) +FILES_PATH := $(FILES_PATH_common) $(FILES_PATH_$(PROFILE)) +CFLAGS := $(CFLAGS_common) $(CFLAGS_$(PROFILE)) +ASMFLAGS := $(CFLAGS_common) $(CFLAGS_$(PROFILE)) +ifeq ($(CPLUSPLUS_BUILD), yes) +CFLAGS += $(CFLAGS_cpp_common) +endif +DEFINES := $(DEFINES_common) $(DEFINES_$(PROFILE)) +INCLUDES := $(INCLUDES_common) $(INCLUDE_$(PROFILE)) +ARFLAGS := $(ARFLAGS_common) $(ARFLAGS_$(PROFILE)) + +LIBDIR := lib +OBJDIR := obj/am62px/gcc-aarch64/$(PROFILE)/a53/xen/ +OBJS := $(FILES:%.c=%.obj) +OBJS += $(ASMFILES:%.S=%.obj) +DEPS := $(FILES:%.c=%.d) + +vpath %.obj $(OBJDIR) +vpath %.c $(FILES_PATH) +vpath %.S $(FILES_PATH) + +$(OBJDIR)/%.obj %.obj: %.c + @echo Compiling: $(LIBNAME): $< + $(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) -MMD -MT $@ -o $(OBJDIR)/$@ $< + +$(OBJDIR)/%.obj %.obj: %.S + @echo Compiling: $(LIBNAME): $< + $(CC) -c -x assembler-with-cpp $(CFLAGS) $(INCLUDES) $(DEFINES) -o $(OBJDIR)$@ $< + +all: $(LIBDIR)/$(LIBNAME) + +$(LIBDIR)/$(LIBNAME): $(OBJS) | $(LIBDIR) + @echo . + @echo Archiving: $(LIBNAME) to $@ ... + $(AR) $(ARFLAGS) $@ $(addprefix $(OBJDIR), $(OBJS)) + @echo Archiving: $(LIBNAME) Done !!! + @echo . + +clean: + @echo Cleaning: $(LIBNAME) ... + $(RMDIR) $(OBJDIR) + $(RM) $(LIBDIR)/$(LIBNAME) + +scrub: + @echo Scrubing: $(LIBNAME) ... + -$(RMDIR) obj/ + -$(RMDIR) lib/ + +$(OBJS): | $(OBJDIR) + +$(LIBDIR) $(OBJDIR): + $(MKDIR) $@ + +-include $(addprefix $(OBJDIR)/, $(DEPS)) diff --git a/source/drivers/xen/makefile.am62x.a53.gcc-aarch64 b/source/drivers/xen/makefile.am62x.a53.gcc-aarch64 new file mode 100644 index 0000000000..4b278d019f --- /dev/null +++ b/source/drivers/xen/makefile.am62x.a53.gcc-aarch64 @@ -0,0 +1,115 @@ +# +# Auto generated makefile +# + +export MCU_PLUS_SDK_PATH?=$(abspath ../../..) +include $(MCU_PLUS_SDK_PATH)/imports.mak + +CG_TOOL_ROOT=$(CGT_GCC_AARCH64_PATH) + +CC=$(CGT_GCC_AARCH64_PATH)/bin/aarch64-none-elf-gcc +AR=$(CGT_GCC_AARCH64_PATH)/bin/aarch64-none-elf-gcc-ar + +PROFILE?=release +ConfigName:=$(PROFILE) + +LIBNAME:=xen.am62x.a53.gcc-aarch64.$(PROFILE).lib + +FILES_common := \ + xen_console.c \ + xen_events.c \ + xen_hvm.c \ + +ASMFILES_common := \ + xen_hypercall.S \ + +FILES_PATH_common = \ + . \ + +INCLUDES_common := \ + -I${MCU_PLUS_SDK_PATH}/source \ + +DEFINES_common := \ + -DSOC_AM62X \ + +CFLAGS_common := \ + -mcpu=cortex-a53+fp+simd \ + -mabi=lp64 \ + -mcmodel=large \ + -mstrict-align \ + -mfix-cortex-a53-835769 \ + -mfix-cortex-a53-843419 \ + -DXEN_ENABLED \ + -Wall \ + -Werror \ + -g \ + -Wno-int-to-pointer-cast \ + -Wno-pointer-to-int-cast \ + -Wno-unused-but-set-variable \ + -fdata-sections \ + -ffunction-sections \ + +CFLAGS_debug := \ + -D_DEBUG_=1 \ + +CFLAGS_release := \ + -O2 \ + +ARFLAGS_common := \ + cr \ + +FILES := $(FILES_common) $(FILES_$(PROFILE)) +ASMFILES := $(ASMFILES_common) $(ASMFILES_$(PROFILE)) +FILES_PATH := $(FILES_PATH_common) $(FILES_PATH_$(PROFILE)) +CFLAGS := $(CFLAGS_common) $(CFLAGS_$(PROFILE)) +ASMFLAGS := $(CFLAGS_common) $(CFLAGS_$(PROFILE)) +ifeq ($(CPLUSPLUS_BUILD), yes) +CFLAGS += $(CFLAGS_cpp_common) +endif +DEFINES := $(DEFINES_common) $(DEFINES_$(PROFILE)) +INCLUDES := $(INCLUDES_common) $(INCLUDE_$(PROFILE)) +ARFLAGS := $(ARFLAGS_common) $(ARFLAGS_$(PROFILE)) + +LIBDIR := lib +OBJDIR := obj/am62x/gcc-aarch64/$(PROFILE)/a53/xen/ +OBJS := $(FILES:%.c=%.obj) +OBJS += $(ASMFILES:%.S=%.obj) +DEPS := $(FILES:%.c=%.d) + +vpath %.obj $(OBJDIR) +vpath %.c $(FILES_PATH) +vpath %.S $(FILES_PATH) + +$(OBJDIR)/%.obj %.obj: %.c + @echo Compiling: $(LIBNAME): $< + $(CC) -c $(CFLAGS) $(INCLUDES) $(DEFINES) -MMD -MT $@ -o $(OBJDIR)/$@ $< + +$(OBJDIR)/%.obj %.obj: %.S + @echo Compiling: $(LIBNAME): $< + $(CC) -c -x assembler-with-cpp $(CFLAGS) $(INCLUDES) $(DEFINES) -o $(OBJDIR)$@ $< + +all: $(LIBDIR)/$(LIBNAME) + +$(LIBDIR)/$(LIBNAME): $(OBJS) | $(LIBDIR) + @echo . + @echo Archiving: $(LIBNAME) to $@ ... + $(AR) $(ARFLAGS) $@ $(addprefix $(OBJDIR), $(OBJS)) + @echo Archiving: $(LIBNAME) Done !!! + @echo . + +clean: + @echo Cleaning: $(LIBNAME) ... + $(RMDIR) $(OBJDIR) + $(RM) $(LIBDIR)/$(LIBNAME) + +scrub: + @echo Scrubing: $(LIBNAME) ... + -$(RMDIR) obj/ + -$(RMDIR) lib/ + +$(OBJS): | $(OBJDIR) + +$(LIBDIR) $(OBJDIR): + $(MKDIR) $@ + +-include $(addprefix $(OBJDIR)/, $(DEPS)) diff --git a/source/drivers/xen/xen_console.c b/source/drivers/xen/xen_console.c new file mode 100644 index 0000000000..c5c4c1d63f --- /dev/null +++ b/source/drivers/xen/xen_console.c @@ -0,0 +1,182 @@ +/* + **************************************************************************** + * (C) 2006 - Grzegorz Milos - Cambridge University + **************************************************************************** + * + * File: console.h + * Author: Grzegorz Milos + * Changes: + * + * Date: Mar 2006 + * + * Environment: Xen Minimal OS + * Description: Console interface. + * + * Handles console I/O. Defines printk. + * + **************************************************************************** + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +/* Copies all print output to the Xen emergency console apart + of standard dom0 handled console */ +#include "xen_console.h" +#include "xen_events.h" +#include "xen_hvm.h" +#include "xen_hypercall.h" +#include "xen_os.h" +#include +#include +#include +#include + +#define MASK_uint32_t(idx, ring) ((idx) & (sizeof(ring) - 1)) + +struct xencons_interface { + uint8_t in[1024]; + uint8_t out[2048]; + uint32_t in_cons, in_prod; + uint32_t out_cons, out_prod; +}; + +struct { + struct xencons_interface *interface; + uint32_t evtchn_port; +} console = {.interface = NULL, .evtchn_port = 0}; + +static int xencons_ring_send_no_notify(const char *data, unsigned len) +{ + int sent = 0; + struct xencons_interface *intf = console.interface; + uint32_t cons, prod; + + cons = intf->out_cons; + prod = intf->out_prod; + mb(); + + XEN_ASSERT((prod - cons) <= sizeof(intf->out)); + + while ((sent < len) && ((prod - cons) < sizeof(intf->out))) + intf->out[MASK_uint32_t(prod++, intf->out)] = data[sent++]; + + wmb(); + intf->out_prod = prod; + + return sent; +} + +static int xencons_ring_send(const char *data, unsigned len) +{ + int sent; + + sent = xencons_ring_send_no_notify(data, len); + notify_evtch(console.evtchn_port); + + return sent; +} + +static void console_print(char *data, int length) +{ + char *curr_char, saved_char; + char copied_str[length + 1]; + char *copied_ptr; + int part_len; + int (*ring_send_fn)(const char *data, unsigned length); + + if (!console.interface) + ring_send_fn = xencons_ring_send_no_notify; + else + ring_send_fn = xencons_ring_send; + + copied_ptr = copied_str; + memcpy(copied_ptr, data, length); + for (curr_char = copied_ptr; curr_char < copied_ptr + length - 1; + curr_char++) + { + if (*curr_char == '\n') + { + *curr_char = '\r'; + saved_char = *(curr_char + 1); + *(curr_char + 1) = '\n'; + part_len = curr_char - copied_ptr + 2; + ring_send_fn(copied_ptr, part_len); + *(curr_char + 1) = saved_char; + copied_ptr = curr_char + 1; + length -= part_len - 1; + } + } + + if (copied_ptr[length - 1] == '\n') + { + copied_ptr[length - 1] = '\r'; + copied_ptr[length] = '\n'; + length++; + } + + ring_send_fn(copied_ptr, length); +} + +void Xen_printkXen(char *str, unsigned length) +{ + HYPERVISOR_console_io(CONSOLEIO_write, length, str); +} + +void Xen_printk(const char *fmt, ...) +{ + static char str[512]; + va_list args; + + va_start(args, fmt); + vsnprintf(str, sizeof(str), fmt, args); + va_end(args); + + if (console.interface) + console_print(str, strlen(str)); + else + Xen_printkXen(str, strlen(str)); +} + +int Xen_consoleInit() +{ + uintptr_t console_pfn; + + if (map_shared_info() < 0) + { + DebugP_logError("Could not map xen internal shared info\n"); + return -1; + } + + if (hvm_get_parameter(HVM_PARAM_CONSOLE_EVTCHN, + (uint64_t *)&console.evtchn_port) < 0) + { + DebugP_logError("Could not get the event channel for xen PV console\n"); + return -1; + } + + if (hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, (uint64_t *)&console_pfn) < 0) + { + DebugP_logError("Could not get the memory ring for xen PV console\n"); + return -1; + } + + console.interface = (struct xencons_interface *)pfn_to_addr(console_pfn); + unmask_evtchn(console.evtchn_port); + + return 0; +} diff --git a/source/drivers/xen/xen_console.h b/source/drivers/xen/xen_console.h new file mode 100644 index 0000000000..daf0e4893b --- /dev/null +++ b/source/drivers/xen/xen_console.h @@ -0,0 +1,14 @@ +#ifndef XEN_CONSOLE_H_ +#define XEN_CONSOLE_H_ + +/* + * Commands to HYPERVISOR_console_io(). + */ +#define CONSOLEIO_write 0 +#define CONSOLEIO_read 1 + +void Xen_printkXen(char *str, unsigned length); +void Xen_printk(const char *str, ...); +int Xen_consoleInit(); + +#endif /* XEN_CONSOLE_H_ */ diff --git a/source/drivers/xen/xen_events.c b/source/drivers/xen/xen_events.c new file mode 100644 index 0000000000..d4f3740a5a --- /dev/null +++ b/source/drivers/xen/xen_events.c @@ -0,0 +1,87 @@ +/****************************************************************************** + * hypervisor.c + * + * Communication to/from hypervisor. + * + * Copyright (c) 2002-2003, K A Fraser + * Copyright (c) 2005, Grzegorz Milos, gm281@cam.ac.uk,Intel Research Cambridge + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to + * deal in the Software without restriction, including without limitation the + * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include "xen_events.h" +#include "xen_hypercall.h" +#include "xen_os.h" + +typedef struct vcpu_info { + uint8_t evtchn_upcall_pending; + uint8_t pad0; + uint64_t evtchn_pending_sel; + uint8_t pad[30]; +} vcpu_info_t; /* 64 bytes (x86) */ + +typedef struct shared_info { + vcpu_info_t vcpu_info[1]; + uint64_t evtchn_pending[sizeof(uint64_t) * 8]; + uint64_t evtchn_mask[sizeof(uint64_t) * 8]; +} shared_info_t; +static __attribute__((aligned(1 << PAGE_SHIFT))) shared_info_t sharedInfo; + +// This function is used by the guest to notify Xen that an event has occurred +void notify_evtch(uint32_t evtch_id) +{ + uint32_t op = (uint32_t)evtch_id; + HYPERVISOR_event_channel_op(EVTCHNOP_send, &op); +} + +void unmask_evtchn(uint32_t port) +{ + /* TODO: is it okay to use 0th vcpu? */ + vcpu_info_t *vcpu_info = &sharedInfo.vcpu_info[0]; + + synch_clear_bit(port, &sharedInfo.evtchn_mask[0]); + + /* + * The following is basically the equivalent of 'hw_resend_irq'. Just like + * a real IO-APIC we 'lose the interrupt edge' if the channel is masked. + */ + if (synch_test_bit(port, &sharedInfo.evtchn_pending[0]) && + !synch_test_and_set_bit(port / (sizeof(unsigned long) * 8), + &vcpu_info->evtchn_pending_sel)) + { + vcpu_info->evtchn_upcall_pending = 1; +#ifdef XEN_HAVE_PV_UPCALL_MASK + if (!vcpu_info->evtchn_upcall_mask) +#endif + } +} + +int map_shared_info() +{ + xen_add_to_physmap_t xatp; + + xatp.domid = DOMID_SELF; + xatp.idx = 0; + xatp.space = XENMAPSPACE_shared_info; + xatp.gpfn = addr_to_pfn((uintptr_t)&sharedInfo); + if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp) < 0) + return -1; + + return 0; +} diff --git a/source/drivers/xen/xen_events.h b/source/drivers/xen/xen_events.h new file mode 100644 index 0000000000..e2d7d3e723 --- /dev/null +++ b/source/drivers/xen/xen_events.h @@ -0,0 +1,48 @@ +#ifndef XEN_EVENTS_H_ +#define XEN_EVENTS_H_ + +#include + +/* + * Sets the GPFN at which a particular page appears in the specified guest's + * physical address space (translated guests only). + * arg == addr of xen_add_to_physmap_t. + */ +#define XENMEM_add_to_physmap 7 +#define XENMAPSPACE_shared_info 0 /* shared info page */ + +/* ` enum event_channel_op { // EVTCHNOP_* => struct evtchn_* */ +#define EVTCHNOP_bind_interdomain 0 +#define EVTCHNOP_bind_virq 1 +#define EVTCHNOP_bind_pirq 2 +#define EVTCHNOP_close 3 +#define EVTCHNOP_send 4 +#define EVTCHNOP_status 5 +#define EVTCHNOP_alloc_unbound 6 +#define EVTCHNOP_bind_ipi 7 +#define EVTCHNOP_bind_vcpu 8 +#define EVTCHNOP_unmask 9 +#define EVTCHNOP_reset 10 +#define EVTCHNOP_init_control 11 +#define EVTCHNOP_expand_array 12 +#define EVTCHNOP_set_priority 13 +#ifdef __XEN__ +#define EVTCHNOP_reset_cont 14 +#endif +/* ` } */ + +void notify_evtch(uint32_t evtch_id); +void unmask_evtchn(uint32_t port); + +typedef struct xen_add_to_physmap { + uint16_t domid; /* Which domain to change the mapping for. */ + uint16_t size; /* Number of pages to go through for gmfn_range */ + unsigned int space; /* => enum phys_map_space */ + unsigned long idx; /* Index into space being mapped. */ + unsigned long gpfn; + /* GPFN in domid where the source mapping page should appear. */ +} xen_add_to_physmap_t; + +int map_shared_info(); + +#endif /* XEN_EVENTS_H_ */ diff --git a/source/drivers/xen/xen_hvm.c b/source/drivers/xen/xen_hvm.c new file mode 100644 index 0000000000..b8686efc4c --- /dev/null +++ b/source/drivers/xen/xen_hvm.c @@ -0,0 +1,22 @@ +#include "xen_hvm.h" +#include "xen_hypercall.h" +#include "xen_os.h" +#include + +int hvm_get_parameter(int idx, uint64_t *value) +{ + Xen_Hvm_Param xhv; + int ret; + + xhv.domid = DOMID_SELF; + xhv.index = idx; + ret = HYPERVISOR_hvm_op(HVMOP_get_param, &xhv); + if (ret < 0) + { + DebugP_logError("failed to get xen HVM parameter: %d\n", idx); + return ret; + } + + *value = xhv.value; + return 0; +} diff --git a/source/drivers/xen/xen_hvm.h b/source/drivers/xen/xen_hvm.h new file mode 100644 index 0000000000..5088c5f4e6 --- /dev/null +++ b/source/drivers/xen/xen_hvm.h @@ -0,0 +1,21 @@ +#ifndef XEN_HVM_H_ +#define XEN_HVM_H_ + +#include + +/* Get/set subcommands: extra argument == pointer to xen_hvm_param struct. */ +#define HVMOP_set_param 0 +#define HVMOP_get_param 1 + +/* Console debug shared memory ring and event channel */ +#define HVM_PARAM_CONSOLE_PFN 17 +#define HVM_PARAM_CONSOLE_EVTCHN 18 +typedef struct Xen_Hvm_Param_s { + uint16_t domid; /* IN */ + uint16_t pad; + uint32_t index; /* IN */ + uint64_t value; /* IN/OUT */ +} Xen_Hvm_Param; +int hvm_get_parameter(int idx, uint64_t *value); + +#endif /* XEN_HVM_H_ */ diff --git a/source/drivers/xen/xen_hypercall.S b/source/drivers/xen/xen_hypercall.S new file mode 100644 index 0000000000..b0bcffe78b --- /dev/null +++ b/source/drivers/xen/xen_hypercall.S @@ -0,0 +1,18 @@ +#define __ASSEMBLY__ +#include "xen_hypercall.h" +#undef __ASSEMBLY__ + +#define XEN_IMM 0xEA1 + +#define HYPERCALL(hypercall) \ +.globl HYPERVISOR_##hypercall; \ +.align 4; \ +HYPERVISOR_##hypercall: \ + mov x16, #__HYPERVISOR_##hypercall; \ + hvc XEN_IMM; \ + ret + +HYPERCALL(memory_op); +HYPERCALL(event_channel_op); +HYPERCALL(console_io); +HYPERCALL(hvm_op); diff --git a/source/drivers/xen/xen_hypercall.h b/source/drivers/xen/xen_hypercall.h new file mode 100644 index 0000000000..d71a5730e3 --- /dev/null +++ b/source/drivers/xen/xen_hypercall.h @@ -0,0 +1,21 @@ +#ifndef XEN_HYPERCALL_H_ +#define XEN_HYPERCALL_H_ + +/* + * HYPERCALLS + */ +#define __HYPERVISOR_memory_op 12 +#define __HYPERVISOR_console_io 18 +#define __HYPERVISOR_event_channel_op 32 +#define __HYPERVISOR_hvm_op 34 + +#ifndef __ASSEMBLY__ + +int HYPERVISOR_memory_op(int cmd, void *arg); +int HYPERVISOR_console_io(int cmd, int count, char *str); +int HYPERVISOR_event_channel_op(int cmd, void *op); +int HYPERVISOR_hvm_op(int cmd, void *arg); + +#endif /* __ASSEMBLY__ */ + +#endif /* XEN_HYPERCALL_H_ */ diff --git a/source/drivers/xen/xen_os.h b/source/drivers/xen/xen_os.h new file mode 100644 index 0000000000..2cb73faa6f --- /dev/null +++ b/source/drivers/xen/xen_os.h @@ -0,0 +1,81 @@ +#ifndef XEN_OS_H_ +#define XEN_OS_H_ + +#include + +/* DOMID_SELF is used in certain contexts to refer to oneself. */ +#define DOMID_SELF (0x7FF0U) + +#define PAGE_SHIFT 12 +static inline uintptr_t addr_to_pfn(uintptr_t va) { return va >> PAGE_SHIFT; } +static inline uintptr_t pfn_to_addr(uintptr_t va) { return va << PAGE_SHIFT; } + +#define XEN_ASSERT(x) \ + do \ + { \ + if (!(x)) \ + { \ + char buf[128]; \ + snprintf(buf, sizeof(buf), "ASSERTION FAILED: %s at %s:%d.\n", #x, \ + __FILE__, __LINE__); \ + Xen_printkXen(buf, strlen(buf)); \ + } \ + } while (0) + +#define ADDR (*(volatile long *)addr) + +/* We probably only need "dmb" here, but we'll start by being paranoid. */ +#define mb() __asm__("dsb sy" ::: "memory"); +#define rmb() __asm__("dsb ld" ::: "memory"); +#define wmb() __asm__("dsb st" ::: "memory"); + +#define barrier() __asm__ __volatile__("" : : : "memory") + +/** + * Test whether a bit is set. */ +static __inline__ int test_bit(int nr, const volatile unsigned long *addr) +{ + const uint8_t *ptr = (const uint8_t *)addr; + return ((1 << (nr & 7)) & (ptr[nr >> 3])) != 0; +} + +/* As test_and_clear_bit, but using __ATOMIC_SEQ_CST */ +static __inline__ int synch_test_and_clear_bit(int nr, volatile void *addr) +{ + uint8_t *byte = ((uint8_t *)addr) + (nr >> 3); + uint8_t bit = 1 << (nr & 7); + uint8_t orig; + + orig = __atomic_fetch_and(byte, ~bit, __ATOMIC_SEQ_CST); + + return (orig & bit) != 0; +} + +/* As test_and_set_bit, but using __ATOMIC_SEQ_CST */ +static __inline__ int synch_test_and_set_bit(int nr, volatile void *base) +{ + uint8_t *byte = ((uint8_t *)base) + (nr >> 3); + uint8_t bit = 1 << (nr & 7); + uint8_t orig; + + orig = __atomic_fetch_or(byte, bit, __ATOMIC_SEQ_CST); + + return (orig & bit) != 0; +} + +/* As clear_bit, but using __ATOMIC_SEQ_CST */ +static __inline__ void synch_clear_bit(int nr, volatile void *addr) +{ + synch_test_and_clear_bit(nr, addr); +} + +/* As test_bit, but with a following memory barrier. */ +static __inline__ int synch_test_bit(int nr, volatile void *addr) +{ + int result; + result = test_bit(nr, addr); + barrier(); + return result; +} + +#endif /* XEN_OS_H_ */ From 77581d9deb99d9444b329cbb84d1d5d88b2caa47 Mon Sep 17 00:00:00 2001 From: Amneesh Singh Date: Mon, 23 Sep 2024 12:28:22 +0530 Subject: [PATCH 2/4] kernel: rtos: add support for Xen - dpl/a53: add linux zImage kernel header for Xen - dpl/common: print to Xen/PV console when Xen is enabled Signed-off-by: Amneesh Singh --- .../dpl/a53/HwiP_armv8_vectors_nortos_asm.S | 23 +++++++++++++++++-- source/kernel/nortos/dpl/a53/boot_armv8_asm.S | 2 ++ .../kernel/nortos/dpl/common/DebugP_nortos.c | 12 ++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/source/kernel/nortos/dpl/a53/HwiP_armv8_vectors_nortos_asm.S b/source/kernel/nortos/dpl/a53/HwiP_armv8_vectors_nortos_asm.S index 7fedcf915b..9e541f7584 100644 --- a/source/kernel/nortos/dpl/a53/HwiP_armv8_vectors_nortos_asm.S +++ b/source/kernel/nortos/dpl/a53/HwiP_armv8_vectors_nortos_asm.S @@ -30,10 +30,10 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ - .global HwiP_defaultExcHandler .global HwiP_dispatchIRQ .global HwiP_abortHandler + .global gnu_targets_arm_rtsv8A_startupAsm .macro PUSH_ALL_CPU_REGS stackPtr stp x0, x1, [\stackPtr, #-16]! @@ -102,6 +102,25 @@ .align 11 HwiP_gicv3Vectors: +#ifdef XEN_ENABLED + /* Xen requires the 64 bit linux kernel header */ + + ldr x16, =gnu_targets_arm_rtsv8A_startupAsm /* Executable code */ + br x16 /* Executable code */ + + .dword 0 /* Image load offset, little endian */ + .dword 0 /* Effective Image size, little endian */ + .dword 8 /* kernel flags, little endian */ + + .dword 0 /* reserved */ + .dword 0 /* resrerved */ + .dword 0 /* reserved */ + + .dword 0x644d5241 /* Magic number, little endian, "ARM\x64" */ + .dword 0 /* reserved (used for PE COFF offset) */ + +#endif + /* ************************************************************************* * Exception from currentEL, using SP0 @@ -230,4 +249,4 @@ VECTOR_ENTRY el0FiqAarch32 VECTOR_ENTRY el0SErrorAarch32 b el0SErrorAarch32 - .end \ No newline at end of file + .end diff --git a/source/kernel/nortos/dpl/a53/boot_armv8_asm.S b/source/kernel/nortos/dpl/a53/boot_armv8_asm.S index 6c87214aaa..97622b0a19 100644 --- a/source/kernel/nortos/dpl/a53/boot_armv8_asm.S +++ b/source/kernel/nortos/dpl/a53/boot_armv8_asm.S @@ -31,6 +31,8 @@ */ //************************** Global symbols ************************************ + + .global gnu_targets_arm_rtsv8A_startupAsm .global _c_int00 .global _stack .global _bss_start diff --git a/source/kernel/nortos/dpl/common/DebugP_nortos.c b/source/kernel/nortos/dpl/common/DebugP_nortos.c index 8bf8d3fb2e..b5f4bd24c6 100755 --- a/source/kernel/nortos/dpl/common/DebugP_nortos.c +++ b/source/kernel/nortos/dpl/common/DebugP_nortos.c @@ -34,6 +34,10 @@ #include #include +#ifdef XEN_ENABLED +#include +#endif + extern uint32_t gDebugLogZone; int32_t _DebugP_log(char *format, ...); @@ -47,7 +51,11 @@ void _DebugP_logZone(uint32_t logZone, char *format, ...) { va_list va; va_start(va, format); +#ifdef XEN_ENABLED + Xen_printk(format, va); +#else vprintf_(format, va); +#endif /* XEN_ENABLED */ va_end(va); } } @@ -61,7 +69,11 @@ int _DebugP_log(char *format, ...) { va_list va; va_start(va, format); +#ifdef XEN_ENABLED + Xen_printk(format, va); +#else vprintf_(format, va); +#endif /* XEN_ENABLED */ va_end(va); } } From eb9eda393f6416d97b1107e1fb34a535f31f8ce9 Mon Sep 17 00:00:00 2001 From: Amneesh Singh Date: Mon, 23 Sep 2024 12:31:54 +0530 Subject: [PATCH 3/4] kernel/freertos: add support for Xen - portable/portASM.s: add linux zImage kernel header for Xen - dpl/common: print to Xen/PV console when Xen is enabled Signed-off-by: Amneesh Singh --- .../freertos/dpl/common/DebugP_freertos.c | 11 ++++++++++ .../freertos/portable/GCC/ARM_CA53/portASM.S | 21 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/source/kernel/freertos/dpl/common/DebugP_freertos.c b/source/kernel/freertos/dpl/common/DebugP_freertos.c index b51674eeab..02d2223e8c 100755 --- a/source/kernel/freertos/dpl/common/DebugP_freertos.c +++ b/source/kernel/freertos/dpl/common/DebugP_freertos.c @@ -34,6 +34,9 @@ #include #include #include +#ifdef XEN_ENABLED +#include +#endif int32_t _DebugP_log(char *format, ...); extern uint32_t gDebugLogZone; @@ -62,7 +65,11 @@ void _DebugP_logZone(uint32_t logZone, char *format, ...) SemaphoreP_pend(&gDebugLogLockObj, SystemP_WAIT_FOREVER); va_start(va, format); +#ifdef XEN_ENABLED + Xen_printk(format, va); +#else vprintf_(format, va); +#endif va_end(va); SemaphoreP_post(&gDebugLogLockObj); } @@ -89,7 +96,11 @@ int32_t _DebugP_log(char *format, ...) SemaphoreP_pend(&gDebugLogLockObj, SystemP_WAIT_FOREVER); va_start(va, format); +#ifdef XEN_ENABLED + Xen_printk(format, va); +#else vprintf_(format, va); +#endif va_end(va); SemaphoreP_post(&gDebugLogLockObj); } diff --git a/source/kernel/freertos/portable/GCC/ARM_CA53/portASM.S b/source/kernel/freertos/portable/GCC/ARM_CA53/portASM.S index fddd7a6ae7..a5cbdd0c82 100644 --- a/source/kernel/freertos/portable/GCC/ARM_CA53/portASM.S +++ b/source/kernel/freertos/portable/GCC/ARM_CA53/portASM.S @@ -68,6 +68,8 @@ .extern ullCriticalNesting .extern ullPortYieldRequired + .global gnu_targets_arm_rtsv8A_startupAsm + .global HwiP_IRQ_Handler .global HwiP_SVC_Handler .global vPortRestoreTaskContext @@ -281,6 +283,25 @@ .align 11 HwiP_gicv3Vectors: +#ifdef XEN_ENABLED + /* Xen requires the 64 bit linux kernel header */ + + ldr x16, =gnu_targets_arm_rtsv8A_startupAsm /* Executable code */ + br x16 /* Executable code */ + + .dword 0 /* Image load offset, little endian */ + .dword 0 /* Effective Image size, little endian */ + .dword 8 /* kernel flags, little endian */ + + .dword 0 /* reserved */ + .dword 0 /* resrerved */ + .dword 0 /* reserved */ + + .dword 0x644d5241 /* Magic number, little endian, "ARM\x64" */ + .dword 0 /* reserved (used for PE COFF offset) */ + +#endif + /* ************************************************************************* * Exception from currentEL, using SP0 From b2c00d9c52cc44428b3474ce6e923da52e09eaf1 Mon Sep 17 00:00:00 2001 From: Amneesh Singh Date: Fri, 27 Sep 2024 13:21:28 +0530 Subject: [PATCH 4/4] kernel/nortos/dpl/a53: fix gic for xen - Change GIC address as the vGIC in Xen is at 0x30010000 - Remove SGI_PPI stuff as Xen does not support it Signed-off-by: Amneesh Singh --- source/drivers/.meta/system/system_config.c.xdt | 3 +++ source/kernel/.meta/dpl/dpl_config.c.xdt | 4 ++++ source/kernel/nortos/dpl/a53/HwiP_armv8_gic.c | 16 ++++++++++++++++ source/kernel/nortos/dpl/a53/HwiP_armv8_gic.h | 4 ++++ source/kernel/nortos/dpl/a53/boot_armv8_asm.S | 4 ++++ 5 files changed, 31 insertions(+) diff --git a/source/drivers/.meta/system/system_config.c.xdt b/source/drivers/.meta/system/system_config.c.xdt index 01b0c8ee0a..e2b5b5be78 100755 --- a/source/drivers/.meta/system/system_config.c.xdt +++ b/source/drivers/.meta/system/system_config.c.xdt @@ -79,12 +79,15 @@ void System_init(void) `system.getTemplate(sciclientInitTemplate)()` % } +#ifndef XEN_ENABLED `system.getTemplate("/kernel/dpl/pmu_init.c.xdt")()` PowerClock_init(); /* Now we can do pinmux */ Pinmux_init(); /* finally we initialize all peripheral drivers */ +#endif + % let driverOrder = system.getScript('/common').getDriverOpenOrder(); % let orderedTemplates = []; % let otherTemplates = []; diff --git a/source/kernel/.meta/dpl/dpl_config.c.xdt b/source/kernel/.meta/dpl/dpl_config.c.xdt index 35571674ad..a94d8662ae 100755 --- a/source/kernel/.meta/dpl/dpl_config.c.xdt +++ b/source/kernel/.meta/dpl/dpl_config.c.xdt @@ -72,7 +72,9 @@ void Dpl_init(void) % } % for(let subTemplate of args) { % if (subTemplate.dpl_init && !subTemplate.dpl_init.match(/mpu_armv7*/) && !subTemplate.dpl_init.match(/cache*/) && !subTemplate.dpl_init.match(/addr_translate*/) && !subTemplate.dpl_init.match(/debug_log*/) && !subTemplate.dpl_init.match(/mmu_armv8*/)) { +#ifndef XEN_ENABLED `system.getTemplate(subTemplate.dpl_init)()` +#endif % } % } /* Enable interrupt handling */ @@ -83,7 +85,9 @@ void Dpl_deinit(void) { % for(let subTemplate of args) { % if (subTemplate.dpl_deinit) { +#ifndef XEN_ENABLED `system.getTemplate(subTemplate.dpl_deinit)()` +#endif % } % } /* Disable interrupt handling */ diff --git a/source/kernel/nortos/dpl/a53/HwiP_armv8_gic.c b/source/kernel/nortos/dpl/a53/HwiP_armv8_gic.c index 790386c756..97b93bd9b4 100644 --- a/source/kernel/nortos/dpl/a53/HwiP_armv8_gic.c +++ b/source/kernel/nortos/dpl/a53/HwiP_armv8_gic.c @@ -337,11 +337,15 @@ void HwiP_init() /* Initialize the GIC V3 */ CSL_gic500_gicdRegs *gicdRegs = (CSL_gic500_gicdRegs *)(HWIP_GIC_BASE_ADDR); CSL_gic500_gicrRegs_core_control *gicrRegs; +#ifndef XEN_ENABLED CSL_gic500_gicrRegs_core_sgi_ppi *gicsRegs; +#endif /* update the redistributor and sgi_ppi address */ gicrRegs = (CSL_gic500_gicrRegs_core_control *) (HWIP_GIC_BASE_ADDR + CSL_GIC500_GICR_CORE_CONTROL_CTLR(coreId)); +#ifndef XEN_ENABLED gicsRegs = (CSL_gic500_gicrRegs_core_sgi_ppi *) ((uintptr_t)gicrRegs + (uintptr_t) 0x10000U); +#endif /* Initialize the Interrupt controller */ { @@ -363,7 +367,9 @@ void HwiP_init() /* * Disable all interrupts at startup */ +#ifndef XEN_ENABLED gicsRegs->ICENABLER0 = 0xFFFFFFFF; +#endif if(0 == coreId) { @@ -384,7 +390,9 @@ void HwiP_init() } /* Search for any previously active interrupts and acknowledge them */ +#ifndef XEN_ENABLED intrActiveReg = gicsRegs->ICACTIVER0; +#endif if (intrActiveReg) { for (j = 0; j < HWIP_GICD_SGI_PPI_INTR_ID_MAX; j++) @@ -420,7 +428,9 @@ void HwiP_init() /* * Clear any currently pending enabled interrupts */ +#ifndef XEN_ENABLED gicsRegs->ICPENDR0 = 0xFFFFFFFF; +#endif if(0 == coreId) { for (i = 0; i < HWIP_GICD_SPI_INTR_COUNT_MAX/32; i++) @@ -432,7 +442,9 @@ void HwiP_init() /* * Clear all interrupt active status registers */ +#ifndef XEN_ENABLED gicsRegs->ICACTIVER0 = 0xFFFFFFFF; +#endif if(0 == coreId) { for (i = 0; i < HWIP_GICD_SPI_INTR_COUNT_MAX/32; i++) @@ -467,7 +479,9 @@ void HwiP_init() */ for (i = 0; i < HWIP_GICD_SGI_PPI_INTR_ID_MAX/4; i++) { +#ifndef XEN_ENABLED gicsRegs->IPRIORITYR[i]=0x20202020; +#endif } if(0 == coreId) { @@ -499,7 +513,9 @@ void HwiP_init() * b00 Interrupt is active-High level-sensitive * b10 Interrupt is rising edge-sensitive */ +#ifndef XEN_ENABLED gicsRegs->ICFGR1 = 0; +#endif if(0 == coreId) { for (i = 0; i < HWIP_GICD_SPI_INTR_COUNT_MAX/16; i++) diff --git a/source/kernel/nortos/dpl/a53/HwiP_armv8_gic.h b/source/kernel/nortos/dpl/a53/HwiP_armv8_gic.h index 66f9b91c58..fb593f3fad 100644 --- a/source/kernel/nortos/dpl/a53/HwiP_armv8_gic.h +++ b/source/kernel/nortos/dpl/a53/HwiP_armv8_gic.h @@ -53,7 +53,11 @@ extern "C" #define HWIP_GICD_SPI_INTR_COUNT_MAX (960U) #define HwiP_MAX_INTERRUPTS (1024u) +#ifndef XEN_ENABLED #define HWIP_GIC_BASE_ADDR (0x1800000UL) +#else +#define HWIP_GIC_BASE_ADDR (0x3001000UL) +#endif #define HWIP_GIC_DEFAULT_PRIORITY ((uint32_t) 0x9U) diff --git a/source/kernel/nortos/dpl/a53/boot_armv8_asm.S b/source/kernel/nortos/dpl/a53/boot_armv8_asm.S index 97622b0a19..8408606f5e 100644 --- a/source/kernel/nortos/dpl/a53/boot_armv8_asm.S +++ b/source/kernel/nortos/dpl/a53/boot_armv8_asm.S @@ -43,7 +43,11 @@ .global CacheP_disableEL3 .global HwiP_armv8GetGicxAddr +#ifndef XEN_ENABLED #define HWIP_GIC_BASE_ADDR (0x1800000U) +#else +#define HWIP_GIC_BASE_ADDR (0x3001000U) +#endif #ifdef SOC_AM62AX #include