diff --git a/repos/base-hw/lib/mk/bootstrap-hw-muen.mk b/repos/base-hw/lib/mk/bootstrap-hw-muen.mk new file mode 100644 index 000000000..d4f5568c8 --- /dev/null +++ b/repos/base-hw/lib/mk/bootstrap-hw-muen.mk @@ -0,0 +1,2 @@ +REQUIRES = x86_64 +LIBS = bootstrap-hw-muen_off diff --git a/repos/base-hw/lib/mk/bootstrap-hw-trustzone.mk b/repos/base-hw/lib/mk/bootstrap-hw-trustzone.mk new file mode 100644 index 000000000..1bd2e907e --- /dev/null +++ b/repos/base-hw/lib/mk/bootstrap-hw-trustzone.mk @@ -0,0 +1,4 @@ +REQUIRES = imx53 + +# add library dependencies +LIBS += bootstrap-hw-trustzone_off diff --git a/repos/base-hw/lib/mk/bootstrap-hw.inc b/repos/base-hw/lib/mk/bootstrap-hw.inc new file mode 100644 index 000000000..d67c6f8b9 --- /dev/null +++ b/repos/base-hw/lib/mk/bootstrap-hw.inc @@ -0,0 +1,44 @@ +HW_DIR = $(BASE_DIR)/../base-hw + +LIBS = cxx + +SRC_CC += bootstrap/env.cc +SRC_CC += bootstrap/init.cc +SRC_CC += bootstrap/lock.cc +SRC_CC += bootstrap/platform.cc +SRC_CC += bootstrap/thread.cc +SRC_CC += core/capability.cc +SRC_CC += core/core_log.cc +SRC_CC += core/default_log.cc +SRC_CC += core/dump_alloc.cc +SRC_CC += core/kernel_log.cc +SRC_CC += lib/base/allocator_avl.cc +SRC_CC += lib/base/avl_tree.cc +SRC_CC += lib/base/console.cc +SRC_CC += lib/base/elf_binary.cc +SRC_CC += lib/base/heap.cc +SRC_CC += lib/base/log.cc +SRC_CC += lib/base/output.cc +SRC_CC += lib/base/slab.cc +SRC_CC += lib/base/sleep.cc +SRC_CC += lib/base/sliced_heap.cc +SRC_CC += lib/startup/_main.cc + +INC_DIR += $(HW_DIR)/src/bootstrap/include +INC_DIR += $(HW_DIR)/src/core/include +INC_DIR += $(BASE_DIR)/src/core/include +INC_DIR += $(HW_DIR)/src/include +INC_DIR += $(BASE_DIR)/src/include + +# configure multiprocessor mode +NR_OF_CPUS ?= 1 +CC_OPT += -Wa,--defsym -Wa,NR_OF_CPUS=$(NR_OF_CPUS) -DNR_OF_CPUS=$(NR_OF_CPUS) + +vpath lib/base/% $(HW_DIR)/src +vpath lib/muen/% $(HW_DIR)/src +vpath lib/base/% $(BASE_DIR)/src +vpath lib/startup/% $(BASE_DIR)/src +vpath base/% $(HW_DIR)/src +vpath core/% $(HW_DIR)/src +vpath core/% $(BASE_DIR)/src +vpath bootstrap/% $(HW_DIR)/src diff --git a/repos/base-hw/lib/mk/core-hw-trustzone.inc b/repos/base-hw/lib/mk/core-hw-trustzone.inc deleted file mode 100644 index a4682878e..000000000 --- a/repos/base-hw/lib/mk/core-hw-trustzone.inc +++ /dev/null @@ -1,14 +0,0 @@ -# -# \brief Build config for parts of core that depend on Trustzone status -# \author Stefan Kalkowski -# \author Martin Stein -# \date 2012-10-24 -# - -# add include paths -INC_DIR += $(REP_DIR)/src/core/include -INC_DIR += $(BASE_DIR)/src/core/include - -# declare source paths -vpath % $(REP_DIR)/src/core -vpath % $(BASE_DIR)/src/core diff --git a/repos/base-hw/lib/mk/core-hw-trustzone.mk b/repos/base-hw/lib/mk/core-hw-trustzone.mk index 472e0b21e..148090d87 100644 --- a/repos/base-hw/lib/mk/core-hw-trustzone.mk +++ b/repos/base-hw/lib/mk/core-hw-trustzone.mk @@ -5,5 +5,7 @@ # \date 2012-10-24 # +REQUIRES = imx53 + # add library dependencies LIBS += core-hw-trustzone_off diff --git a/repos/base-hw/lib/mk/core-hw-trustzone_off.mk b/repos/base-hw/lib/mk/core-hw-trustzone_off.mk deleted file mode 100644 index 212350935..000000000 --- a/repos/base-hw/lib/mk/core-hw-trustzone_off.mk +++ /dev/null @@ -1,5 +0,0 @@ -# -# \brief Build config for parts of core that depend on Trustzone status -# \author Martin Stein -# \date 2014-07-23 -# diff --git a/repos/base-hw/lib/mk/core-hw.inc b/repos/base-hw/lib/mk/core-hw.inc index 340ebd028..7de46e3e2 100644 --- a/repos/base-hw/lib/mk/core-hw.inc +++ b/repos/base-hw/lib/mk/core-hw.inc @@ -23,6 +23,7 @@ SRC_CC += core_rpc_cap_alloc.cc SRC_CC += dataspace_component.cc SRC_CC += default_log.cc SRC_CC += dump_alloc.cc +SRC_CC += kernel_log.cc SRC_CC += io_mem_session_component.cc SRC_CC += io_mem_session_support.cc SRC_CC += irq_session_component.cc @@ -62,6 +63,7 @@ SRC_CC += capability.cc include $(BASE_DIR)/src/core/version.inc # configure multiprocessor mode +NR_OF_CPUS ?= 1 CC_OPT += -Wa,--defsym -Wa,NR_OF_CPUS=$(NR_OF_CPUS) -DNR_OF_CPUS=$(NR_OF_CPUS) # declare source locations diff --git a/repos/base-hw/lib/mk/spec/arm/bootstrap-hw.inc b/repos/base-hw/lib/mk/spec/arm/bootstrap-hw.inc new file mode 100644 index 000000000..beb9dccca --- /dev/null +++ b/repos/base-hw/lib/mk/spec/arm/bootstrap-hw.inc @@ -0,0 +1,4 @@ +INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/arm +SRC_S += bootstrap/spec/arm/crt0.s + +include $(BASE_DIR)/../base-hw/lib/mk/bootstrap-hw.inc diff --git a/repos/base-hw/lib/mk/spec/arm_v7/bootstrap-hw.inc b/repos/base-hw/lib/mk/spec/arm_v7/bootstrap-hw.inc new file mode 100644 index 000000000..159730220 --- /dev/null +++ b/repos/base-hw/lib/mk/spec/arm_v7/bootstrap-hw.inc @@ -0,0 +1,4 @@ +INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/arm_v7 +SRC_CC += core/spec/arm_v7/cpu.cc + +include $(BASE_DIR)/../base-hw/lib/mk/spec/arm/bootstrap-hw.inc diff --git a/repos/base-hw/lib/mk/spec/arndale/bootstrap-hw.mk b/repos/base-hw/lib/mk/spec/arndale/bootstrap-hw.mk new file mode 100644 index 000000000..5fb0ea0df --- /dev/null +++ b/repos/base-hw/lib/mk/spec/arndale/bootstrap-hw.mk @@ -0,0 +1,6 @@ +SRC_CC += bootstrap/spec/arndale/cpu.cc +SRC_CC += core/spec/arndale/pic.cc + +NR_OF_CPUS = 2 + +include $(REP_DIR)/lib/mk/spec/exynos5/bootstrap-hw.inc diff --git a/repos/base-hw/lib/mk/spec/arndale/core-hw.mk b/repos/base-hw/lib/mk/spec/arndale/core-hw.mk index a5e83eb8b..b604fd5b5 100644 --- a/repos/base-hw/lib/mk/spec/arndale/core-hw.mk +++ b/repos/base-hw/lib/mk/spec/arndale/core-hw.mk @@ -8,7 +8,6 @@ INC_DIR += $(REP_DIR)/src/core/include/spec/arm_v7/virtualization # add C++ sources -SRC_CC += spec/arndale/cpu.cc SRC_CC += spec/arndale/pic.cc SRC_CC += spec/arndale/platform_services.cc SRC_CC += kernel/vm_thread_on.cc diff --git a/repos/base-hw/lib/mk/spec/cortex_a15/bootstrap-hw.inc b/repos/base-hw/lib/mk/spec/cortex_a15/bootstrap-hw.inc new file mode 100644 index 000000000..fe2916eea --- /dev/null +++ b/repos/base-hw/lib/mk/spec/cortex_a15/bootstrap-hw.inc @@ -0,0 +1,4 @@ +INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/cortex_a15 +INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/arm_gic + +include $(BASE_DIR)/../base-hw/lib/mk/spec/arm_v7/bootstrap-hw.inc diff --git a/repos/base-hw/lib/mk/spec/cortex_a15/core-hw.inc b/repos/base-hw/lib/mk/spec/cortex_a15/core-hw.inc index a28a5416f..d44af57e2 100644 --- a/repos/base-hw/lib/mk/spec/cortex_a15/core-hw.inc +++ b/repos/base-hw/lib/mk/spec/cortex_a15/core-hw.inc @@ -9,14 +9,10 @@ INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/cortex_a15 INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/arm_gic # add C++ sources -SRC_CC += spec/cortex_a15/cpu.cc SRC_CC += spec/cortex_a15/kernel/cpu.cc SRC_CC += spec/arm/smp/kernel/thread_update_pd.cc SRC_CC += spec/arm/smp/kernel/cpu.cc -# add assembler sources -SRC_S += spec/arm/smp/kernel/crt0.s - # include less specific configuration include $(BASE_DIR)/../base-hw/lib/mk/spec/smp/core-hw.inc include $(BASE_DIR)/../base-hw/lib/mk/spec/arm_v7/core-hw.inc diff --git a/repos/base-hw/lib/mk/spec/cortex_a9/bootstrap-hw.inc b/repos/base-hw/lib/mk/spec/cortex_a9/bootstrap-hw.inc new file mode 100644 index 000000000..92df72006 --- /dev/null +++ b/repos/base-hw/lib/mk/spec/cortex_a9/bootstrap-hw.inc @@ -0,0 +1,9 @@ +INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/smp +INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/arm_gic +INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/cortex_a9 + +SRC_CC += core/spec/arm_gic/pic.cc +SRC_CC += core/spec/cortex_a9/board.cc +SRC_CC += bootstrap/spec/cortex_a9/platform.cc + +include $(BASE_DIR)/../base-hw/lib/mk/spec/arm_v7/bootstrap-hw.inc diff --git a/repos/base-hw/lib/mk/spec/cortex_a9/core-hw.inc b/repos/base-hw/lib/mk/spec/cortex_a9/core-hw.inc index e4a6391f9..5db2a02e5 100644 --- a/repos/base-hw/lib/mk/spec/cortex_a9/core-hw.inc +++ b/repos/base-hw/lib/mk/spec/cortex_a9/core-hw.inc @@ -10,17 +10,15 @@ INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/arm_gic # add C++ sources SRC_CC += spec/cortex_a9/kernel/cpu.cc -SRC_CC += spec/cortex_a9/cpu.cc SRC_CC += spec/cortex_a9/fpu.cc +SRC_CC += spec/cortex_a9/board.cc +SRC_CC += spec/cortex_a9/timer.cc SRC_CC += spec/arm/smp/kernel/thread_update_pd.cc SRC_CC += spec/arm/smp/kernel/cpu.cc SRC_CC += spec/arm/kernel/cpu_context.cc SRC_CC += spec/arm_gic/pic.cc SRC_CC += kernel/vm_thread_off.cc -# add Assembler sources -SRC_S += spec/arm/smp/kernel/crt0.s - # include less specific configuration include $(BASE_DIR)/../base-hw/lib/mk/spec/smp/core-hw.inc include $(BASE_DIR)/../base-hw/lib/mk/spec/arm_v7/core-hw.inc diff --git a/repos/base-hw/lib/mk/spec/exynos5/bootstrap-hw.inc b/repos/base-hw/lib/mk/spec/exynos5/bootstrap-hw.inc new file mode 100644 index 000000000..de2807a27 --- /dev/null +++ b/repos/base-hw/lib/mk/spec/exynos5/bootstrap-hw.inc @@ -0,0 +1,5 @@ +INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/exynos5 +SRC_CC += bootstrap/spec/exynos5/platform.cc + +include $(BASE_DIR)/../base-hw/lib/mk/spec/cortex_a15/bootstrap-hw.inc + diff --git a/repos/base-hw/lib/mk/spec/exynos5/core-hw.inc b/repos/base-hw/lib/mk/spec/exynos5/core-hw.inc index 2b3d53167..342c8cb77 100644 --- a/repos/base-hw/lib/mk/spec/exynos5/core-hw.inc +++ b/repos/base-hw/lib/mk/spec/exynos5/core-hw.inc @@ -8,7 +8,6 @@ INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/exynos5 # add C++ sources -SRC_CC += spec/exynos5/platform_support.cc SRC_CC += spec/exynos5/cpu.cc # include less specific configuration diff --git a/repos/base-hw/lib/mk/spec/imx53/bootstrap-hw-trustzone_off.mk b/repos/base-hw/lib/mk/spec/imx53/bootstrap-hw-trustzone_off.mk new file mode 100644 index 000000000..d6ab75d2b --- /dev/null +++ b/repos/base-hw/lib/mk/spec/imx53/bootstrap-hw-trustzone_off.mk @@ -0,0 +1,3 @@ +SRC_CC += bootstrap/spec/imx53/board.cc + +include $(BASE_DIR)/../base-hw/lib/mk/spec/imx53/bootstrap-hw.inc diff --git a/repos/base-hw/lib/mk/spec/imx53/bootstrap-hw-trustzone_on.mk b/repos/base-hw/lib/mk/spec/imx53/bootstrap-hw-trustzone_on.mk new file mode 100644 index 000000000..ae770b488 --- /dev/null +++ b/repos/base-hw/lib/mk/spec/imx53/bootstrap-hw-trustzone_on.mk @@ -0,0 +1,3 @@ +SRC_CC += bootstrap/spec/imx53/board_trustzone.cc + +include $(BASE_DIR)/../base-hw/lib/mk/spec/imx53/bootstrap-hw.inc diff --git a/repos/base-hw/lib/mk/spec/imx53/bootstrap-hw.inc b/repos/base-hw/lib/mk/spec/imx53/bootstrap-hw.inc new file mode 100644 index 000000000..d86cd10cc --- /dev/null +++ b/repos/base-hw/lib/mk/spec/imx53/bootstrap-hw.inc @@ -0,0 +1,8 @@ +INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/cortex_a8 +INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/imx53 +INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/imx + +SRC_CC += core/spec/imx53/pic.cc +SRC_CC += bootstrap/spec/imx53/platform.cc + +include $(BASE_DIR)/../base-hw/lib/mk/spec/arm_v7/bootstrap-hw.inc diff --git a/repos/base-hw/lib/mk/spec/imx53/bootstrap-hw.mk b/repos/base-hw/lib/mk/spec/imx53/bootstrap-hw.mk new file mode 100644 index 000000000..eb8c6c5ef --- /dev/null +++ b/repos/base-hw/lib/mk/spec/imx53/bootstrap-hw.mk @@ -0,0 +1 @@ +LIBS += bootstrap-hw-trustzone diff --git a/repos/base-hw/lib/mk/spec/imx53/core-hw-trustzone_off.mk b/repos/base-hw/lib/mk/spec/imx53/core-hw-trustzone_off.mk index ea4f1ee17..843f65eb8 100644 --- a/repos/base-hw/lib/mk/spec/imx53/core-hw-trustzone_off.mk +++ b/repos/base-hw/lib/mk/spec/imx53/core-hw-trustzone_off.mk @@ -12,5 +12,4 @@ SRC_CC += spec/imx53/pic.cc SRC_CC += platform_services.cc # include less specific configuration -include $(REP_DIR)/lib/mk/spec/imx53/core-hw-trustzone.inc -include $(REP_DIR)/lib/mk/core-hw-trustzone.inc +include $(REP_DIR)/lib/mk/spec/imx53/core-hw.inc diff --git a/repos/base-hw/lib/mk/spec/imx53/core-hw-trustzone_on.inc b/repos/base-hw/lib/mk/spec/imx53/core-hw-trustzone_on.inc index 03fcd6f61..e533574f5 100644 --- a/repos/base-hw/lib/mk/spec/imx53/core-hw-trustzone_on.inc +++ b/repos/base-hw/lib/mk/spec/imx53/core-hw-trustzone_on.inc @@ -22,5 +22,4 @@ SRC_CC += spec/arm_v7/trustzone/vm_session_component.cc SRC_S += spec/arm_v7/trustzone/mode_transition.s # include less specific configuration -include $(REP_DIR)/lib/mk/spec/imx53/core-hw-trustzone.inc -include $(REP_DIR)/lib/mk/core-hw-trustzone.inc +include $(REP_DIR)/lib/mk/spec/imx53/core-hw.inc diff --git a/repos/base-hw/lib/mk/spec/imx53/core-hw-trustzone.inc b/repos/base-hw/lib/mk/spec/imx53/core-hw.inc similarity index 100% rename from repos/base-hw/lib/mk/spec/imx53/core-hw-trustzone.inc rename to repos/base-hw/lib/mk/spec/imx53/core-hw.inc diff --git a/repos/base-hw/lib/mk/spec/imx6/bootstrap-hw.mk b/repos/base-hw/lib/mk/spec/imx6/bootstrap-hw.mk new file mode 100644 index 000000000..8418e15be --- /dev/null +++ b/repos/base-hw/lib/mk/spec/imx6/bootstrap-hw.mk @@ -0,0 +1,8 @@ +INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/imx6 +INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/imx + +SRC_CC += bootstrap/spec/imx6/platform.cc + +NR_OF_CPUS = 4 + +include $(BASE_DIR)/../base-hw/lib/mk/spec/cortex_a9/bootstrap-hw.inc diff --git a/repos/base-hw/lib/mk/spec/muen/bootstrap-hw-muen.mk b/repos/base-hw/lib/mk/spec/muen/bootstrap-hw-muen.mk new file mode 100644 index 000000000..177f7c5de --- /dev/null +++ b/repos/base-hw/lib/mk/spec/muen/bootstrap-hw-muen.mk @@ -0,0 +1 @@ +LIBS += bootstrap-hw-muen_on diff --git a/repos/base-hw/lib/mk/spec/odroid_xu/bootstrap-hw.mk b/repos/base-hw/lib/mk/spec/odroid_xu/bootstrap-hw.mk new file mode 100644 index 000000000..2163e99f2 --- /dev/null +++ b/repos/base-hw/lib/mk/spec/odroid_xu/bootstrap-hw.mk @@ -0,0 +1,4 @@ +SRC_CC += bootstrap/spec/odroid_xu/cpu.cc +SRC_CC += core/spec/arm_gic/pic.cc + +include $(REP_DIR)/lib/mk/spec/exynos5/bootstrap-hw.inc diff --git a/repos/base-hw/lib/mk/spec/odroid_xu/core-hw.mk b/repos/base-hw/lib/mk/spec/odroid_xu/core-hw.mk index 300ddc4df..8a62feed1 100644 --- a/repos/base-hw/lib/mk/spec/odroid_xu/core-hw.mk +++ b/repos/base-hw/lib/mk/spec/odroid_xu/core-hw.mk @@ -5,13 +5,10 @@ # # add C++ sources -SRC_CC += spec/cortex_a15/cpu_init.cc SRC_CC += spec/arm/kernel/cpu_context.cc SRC_CC += spec/arm_gic/pic.cc SRC_CC += kernel/vm_thread_off.cc SRC_CC += platform_services.cc -NR_OF_CPUS = 1 - # include less specific configuration include $(REP_DIR)/lib/mk/spec/exynos5/core-hw.inc diff --git a/repos/base-hw/lib/mk/spec/panda/bootstrap-hw.mk b/repos/base-hw/lib/mk/spec/panda/bootstrap-hw.mk new file mode 100644 index 000000000..339d72e14 --- /dev/null +++ b/repos/base-hw/lib/mk/spec/panda/bootstrap-hw.mk @@ -0,0 +1,8 @@ +INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/panda +INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/tl16c750 + +SRC_CC += bootstrap/spec/panda/platform.cc + +NR_OF_CPUS = 2 + +include $(BASE_DIR)/../base-hw/lib/mk/spec/cortex_a9/bootstrap-hw.inc diff --git a/repos/base-hw/lib/mk/spec/pbxa9/bootstrap-hw.mk b/repos/base-hw/lib/mk/spec/pbxa9/bootstrap-hw.mk new file mode 100644 index 000000000..c01bc7973 --- /dev/null +++ b/repos/base-hw/lib/mk/spec/pbxa9/bootstrap-hw.mk @@ -0,0 +1,6 @@ +INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/pbxa9 +INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/pl011 + +SRC_CC += bootstrap/spec/pbxa9/platform.cc + +include $(BASE_DIR)/../base-hw/lib/mk/spec/cortex_a9/bootstrap-hw.inc diff --git a/repos/base-hw/lib/mk/spec/riscv/bootstrap-hw.mk b/repos/base-hw/lib/mk/spec/riscv/bootstrap-hw.mk new file mode 100644 index 000000000..e8d1ab5f6 --- /dev/null +++ b/repos/base-hw/lib/mk/spec/riscv/bootstrap-hw.mk @@ -0,0 +1,11 @@ +INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/riscv + +SRC_CC += bootstrap/spec/riscv/cpu.cc +SRC_CC += bootstrap/spec/riscv/exception_vector.cc +SRC_CC += bootstrap/spec/riscv/platform.cc +SRC_CC += lib/base/riscv/kernel/interface.cc +SRC_S += bootstrap/spec/riscv/crt0.s +SRC_S += core/spec/riscv/mode_transition.s + +include $(BASE_DIR)/../base-hw/lib/mk/bootstrap-hw.inc + diff --git a/repos/base-hw/lib/mk/spec/riscv/core-hw.mk b/repos/base-hw/lib/mk/spec/riscv/core-hw.mk index e7a91118e..9746c28f4 100644 --- a/repos/base-hw/lib/mk/spec/riscv/core-hw.mk +++ b/repos/base-hw/lib/mk/spec/riscv/core-hw.mk @@ -9,7 +9,6 @@ SRC_CC += spec/riscv/kernel/cpu_context.cc SRC_CC += spec/riscv/kernel/thread.cc SRC_CC += spec/riscv/kernel/pd.cc SRC_CC += spec/riscv/kernel/cpu.cc -SRC_CC += spec/riscv/kernel/exception_vector.cc SRC_CC += spec/riscv/platform_support.cc SRC_CC += spec/riscv/cpu.cc @@ -18,7 +17,5 @@ SRC_S += spec/riscv/mode_transition.s SRC_S += spec/riscv/kernel/crt0.s SRC_S += spec/riscv/crt0.s -NR_OF_CPUS = 1 - # include less specific configuration include $(REP_DIR)/lib/mk/core-hw.inc diff --git a/repos/base-hw/lib/mk/spec/rpi/bootstrap-hw.mk b/repos/base-hw/lib/mk/spec/rpi/bootstrap-hw.mk new file mode 100644 index 000000000..aca694531 --- /dev/null +++ b/repos/base-hw/lib/mk/spec/rpi/bootstrap-hw.mk @@ -0,0 +1,10 @@ +INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/rpi +INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/arm_v6 +INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/pl011 + +SRC_CC += bootstrap/spec/arm_v6/cpu.cc +SRC_CC += bootstrap/spec/rpi/platform.cc +SRC_CC += core/spec/rpi/pic.cc + +include $(BASE_DIR)/../base-hw/lib/mk/spec/arm/bootstrap-hw.inc + diff --git a/repos/base-hw/lib/mk/spec/rpi/core-hw.mk b/repos/base-hw/lib/mk/spec/rpi/core-hw.mk index 704aa2693..decd8abe7 100644 --- a/repos/base-hw/lib/mk/spec/rpi/core-hw.mk +++ b/repos/base-hw/lib/mk/spec/rpi/core-hw.mk @@ -11,8 +11,8 @@ INC_DIR += $(REP_DIR)/src/core/include/spec/pl011 # add C++ sources SRC_CC += platform_services.cc SRC_CC += spec/rpi/platform_support.cc - -NR_OF_CPUS = 1 +SRC_CC += spec/rpi/timer.cc +SRC_CC += spec/rpi/pic.cc # include less specific configuration include $(REP_DIR)/lib/mk/spec/arm_v6/core-hw.inc diff --git a/repos/base-hw/lib/mk/spec/trustzone/bootstrap-hw-trustzone.mk b/repos/base-hw/lib/mk/spec/trustzone/bootstrap-hw-trustzone.mk new file mode 100644 index 000000000..e09ee0083 --- /dev/null +++ b/repos/base-hw/lib/mk/spec/trustzone/bootstrap-hw-trustzone.mk @@ -0,0 +1 @@ +LIBS += bootstrap-hw-trustzone_on diff --git a/repos/base-hw/lib/mk/spec/usb_armory/bootstrap-hw.mk b/repos/base-hw/lib/mk/spec/usb_armory/bootstrap-hw.mk new file mode 100644 index 000000000..fbdc97cef --- /dev/null +++ b/repos/base-hw/lib/mk/spec/usb_armory/bootstrap-hw.mk @@ -0,0 +1,9 @@ +INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/cortex_a8 +INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/imx53 +INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/imx + +SRC_CC += core/spec/imx53/pic.cc +SRC_CC += bootstrap/spec/imx53/platform.cc +SRC_CC += bootstrap/spec/imx53/board_trustzone.cc + +include $(BASE_DIR)/../base-hw/lib/mk/spec/arm_v7/bootstrap-hw.inc diff --git a/repos/base-hw/lib/mk/spec/x86_64/bootstrap-hw-muen_off.mk b/repos/base-hw/lib/mk/spec/x86_64/bootstrap-hw-muen_off.mk new file mode 100644 index 000000000..c311fffb7 --- /dev/null +++ b/repos/base-hw/lib/mk/spec/x86_64/bootstrap-hw-muen_off.mk @@ -0,0 +1,5 @@ +SRC_CC += core/spec/x86_64/pic.cc +SRC_CC += bootstrap/spec/x86_64/platform.cc +SRC_S += bootstrap/spec/x86_64/crt0_translation_table.s + +include $(BASE_DIR)/../base-hw/lib/mk/spec/x86_64/bootstrap-hw.inc diff --git a/repos/base-hw/lib/mk/spec/x86_64/bootstrap-hw-muen_on.mk b/repos/base-hw/lib/mk/spec/x86_64/bootstrap-hw-muen_on.mk new file mode 100644 index 000000000..7e60275a2 --- /dev/null +++ b/repos/base-hw/lib/mk/spec/x86_64/bootstrap-hw-muen_on.mk @@ -0,0 +1,9 @@ +REQUIRES = muen + +INC_DIR += $(REP_DIR)/src/core/include/spec/x86_64/muen + +SRC_CC += lib/muen/sinfo.cc +SRC_CC += bootstrap/spec/x86_64/platform_muen.cc +SRC_S += bootstrap/spec/x86_64/crt0_translation_table_muen.s + +include $(BASE_DIR)/../base-hw/lib/mk/spec/x86_64/bootstrap-hw.inc diff --git a/repos/base-hw/lib/mk/spec/x86_64/bootstrap-hw.inc b/repos/base-hw/lib/mk/spec/x86_64/bootstrap-hw.inc new file mode 100644 index 000000000..611b678bb --- /dev/null +++ b/repos/base-hw/lib/mk/spec/x86_64/bootstrap-hw.inc @@ -0,0 +1,5 @@ +INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/x86_64 + +SRC_S += bootstrap/spec/x86_64/crt0.s + +include $(BASE_DIR)/../base-hw/lib/mk/bootstrap-hw.inc diff --git a/repos/base-hw/lib/mk/spec/x86_64/bootstrap-hw.mk b/repos/base-hw/lib/mk/spec/x86_64/bootstrap-hw.mk new file mode 100644 index 000000000..b96705494 --- /dev/null +++ b/repos/base-hw/lib/mk/spec/x86_64/bootstrap-hw.mk @@ -0,0 +1 @@ +LIBS = bootstrap-hw-muen diff --git a/repos/base-hw/lib/mk/spec/x86_64/core-hw-muen_off.mk b/repos/base-hw/lib/mk/spec/x86_64/core-hw-muen_off.mk index ec2d80a0e..25be436d4 100644 --- a/repos/base-hw/lib/mk/spec/x86_64/core-hw-muen_off.mk +++ b/repos/base-hw/lib/mk/spec/x86_64/core-hw-muen_off.mk @@ -4,12 +4,10 @@ # \date 2015-06-02 # -# add assembly sources -SRC_S += spec/x86_64/kernel/crt0_translation_table.s - # add C++ sources SRC_CC += kernel/vm_thread_off.cc SRC_CC += spec/x86_64/pic.cc +SRC_CC += spec/x86_64/timer.cc SRC_CC += spec/x86_64/kernel/cpu_exception.cc SRC_CC += spec/x86_64/kernel/thread_exception.cc SRC_CC += spec/x86_64/platform_support.cc diff --git a/repos/base-hw/lib/mk/spec/x86_64/core-hw-muen_on.mk b/repos/base-hw/lib/mk/spec/x86_64/core-hw-muen_on.mk index ffd560128..f7038bcf9 100644 --- a/repos/base-hw/lib/mk/spec/x86_64/core-hw-muen_on.mk +++ b/repos/base-hw/lib/mk/spec/x86_64/core-hw-muen_on.mk @@ -9,9 +9,6 @@ REQUIRES = muen # add include paths INC_DIR += $(REP_DIR)/src/core/include/spec/x86_64/muen -# add assembly sources -SRC_S += spec/x86_64/muen/kernel/crt0_translation_table.s - # add C++ sources SRC_CC += spec/x86_64/muen/kernel/cpu_exception.cc SRC_CC += spec/x86_64/muen/kernel/thread_exception.cc diff --git a/repos/base-hw/lib/mk/spec/x86_64/core-hw.inc b/repos/base-hw/lib/mk/spec/x86_64/core-hw.inc index 4813f2df0..06e70d79a 100644 --- a/repos/base-hw/lib/mk/spec/x86_64/core-hw.inc +++ b/repos/base-hw/lib/mk/spec/x86_64/core-hw.inc @@ -27,7 +27,5 @@ SRC_CC += spec/x86_64/kernel/thread.cc SRC_CC += spec/x86_64/kernel/thread.cc SRC_CC += spec/x86_64/platform_support_common.cc -NR_OF_CPUS = 1 - # include less specific configuration include $(BASE_DIR)/../base-hw/lib/mk/core-hw.inc diff --git a/repos/base-hw/lib/mk/spec/zynq/bootstrap-hw.inc b/repos/base-hw/lib/mk/spec/zynq/bootstrap-hw.inc new file mode 100644 index 000000000..cd4cbd256 --- /dev/null +++ b/repos/base-hw/lib/mk/spec/zynq/bootstrap-hw.inc @@ -0,0 +1,5 @@ +INC_DIR += $(BASE_DIR)/../base-hw/src/core/include/spec/zynq + +SRC_CC += bootstrap/spec/zynq/platform.cc + +include $(BASE_DIR)/../base-hw/lib/mk/spec/cortex_a9/bootstrap-hw.inc diff --git a/repos/base-hw/lib/mk/spec/zynq_qemu/bootstrap-hw.mk b/repos/base-hw/lib/mk/spec/zynq_qemu/bootstrap-hw.mk new file mode 100644 index 000000000..ec85ee3cc --- /dev/null +++ b/repos/base-hw/lib/mk/spec/zynq_qemu/bootstrap-hw.mk @@ -0,0 +1,4 @@ +INC_DIR += $(REP_DIR)/src/core/include/spec/xilinx_uartps_0 +INC_DIR += $(REP_DIR)/src/core/include/spec/zynq_qemu + +include $(BASE_DIR)/../base-hw/lib/mk/spec/zynq/bootstrap-hw.inc diff --git a/repos/base-hw/src/bootstrap/env.cc b/repos/base-hw/src/bootstrap/env.cc new file mode 100644 index 000000000..95f8ac85c --- /dev/null +++ b/repos/base-hw/src/bootstrap/env.cc @@ -0,0 +1,24 @@ +/* + * \brief Environment dummy implementation needed by cxx library + * \author Stefan Kalkowski + * \date 2016-09-23 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +/* base includes */ +#include + +/* core includes */ +#include + +Genode::Env_deprecated * Genode::env_deprecated() +{ + assert(false); + return nullptr; +} diff --git a/repos/base-hw/src/bootstrap/hw/target.mk b/repos/base-hw/src/bootstrap/hw/target.mk new file mode 100644 index 000000000..06c3d050c --- /dev/null +++ b/repos/base-hw/src/bootstrap/hw/target.mk @@ -0,0 +1,13 @@ +TARGET = bootstrap +LIBS = bootstrap-hw +BOOTSTRAP_OBJ = bootstrap.o + +$(TARGET): $(BOOTSTRAP_OBJ) + $(VERBOSE)true + +.PHONY: $(BOOTSTRAP_OBJ) +$(BOOTSTRAP_OBJ): + $(VERBOSE)$(LD) $(LD_MARCH) -u _start --whole-archive -r $(LINK_ITEMS) $(LIBCXX_GCC) -o $@ + +clean cleanall: + $(VERBOSE)rm -f $(BOOTSTRAP_OBJ) diff --git a/repos/base-hw/src/bootstrap/include/platform.h b/repos/base-hw/src/bootstrap/include/platform.h new file mode 100644 index 000000000..a27158cdb --- /dev/null +++ b/repos/base-hw/src/bootstrap/include/platform.h @@ -0,0 +1,142 @@ +/* + * \brief Platform interface + * \author Stefan Kalkowski + * \date 2016-10-19 + */ + +/* + * Copyright (C) 2016-2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _PLATFORM_H_ +#define _PLATFORM_H_ + +/* Genode includes */ +#include +#include +#include + +/* core includes */ +#include +#include +#include +#include +#include + +using Genode::addr_t; +using Genode::size_t; +using Genode::Bootinfo; +using Genode::Core_mmio; +using Genode::Mapping; +using Genode::Memory_region; +using Genode::Memory_region_array; +using Genode::Rom_module; + + +class Platform +{ + private: + + struct Board : Genode::Board + { + Memory_region_array early_ram_regions; + Memory_region_array late_ram_regions; + Core_mmio const core_mmio; + + Board(); + }; + + + class Ram_allocator : public Genode::Allocator_avl_base + { + private: + + using Base = Genode::Allocator_avl_base; + + enum { BSZ = Genode::Allocator_avl::slab_block_size() }; + + Genode::Tslab _slab; + Genode::uint8_t _first_slab[BSZ]; + + public: + + Ram_allocator() + : Genode::Allocator_avl_base(&_slab, sizeof(Base::Block)), + _slab(this, (Genode::Slab_block*)&_first_slab) {} + + void * alloc_aligned(size_t size, unsigned align); + bool alloc(size_t size, void **out_addr) override; + void * alloc(size_t size) { return Allocator::alloc(size); } + + void add(Memory_region const &); + void remove(Memory_region const &); + + template + void for_each_free_region(FUNC functor) + { + _block_tree().for_each([&] (Block const & b) + { + if (!b.used()) + functor(Genode::Memory_region(b.addr(), b.size())); + }); + } + }; + + + struct Pd + { + void * const table_base; + void * const allocator_base; + Bootinfo::Table & table; + Bootinfo::Table_allocator & allocator; + Bootinfo::Mapping_pool mappings; + + Pd(Ram_allocator & alloc); + + void map(Mapping m); + void map_insert(Mapping m); + }; + + + struct Elf : Genode::Elf_binary + { + Elf(addr_t const addr) : Genode::Elf_binary(addr) { } + + template void for_each_segment(T functor) + { + Genode::Elf_segment segment; + for (unsigned i = 0; (segment = get_segment(i)).valid(); i++) { + if (segment.flags().skip) continue; + if (segment.mem_size() == 0) continue; + functor(segment); + } + } + }; + + Board board; + Genode::Cpu cpu; + Genode::Pic pic; + Ram_allocator ram_alloc; + Memory_region const bootstrap_region; + Genode::Constructible core_pd; + addr_t core_elf_addr; + Elf core_elf; + + addr_t _load_elf(); + + public: + + Platform(); + + static addr_t mmio_to_virt(addr_t mmio) { return mmio; } + + void enable_mmu(); + void start_core() __attribute__((noreturn)); +}; + +extern Platform & platform(); + +#endif /* _PLATFORM_H_ */ diff --git a/repos/base-hw/src/bootstrap/init.cc b/repos/base-hw/src/bootstrap/init.cc new file mode 100644 index 000000000..4da9e2a0a --- /dev/null +++ b/repos/base-hw/src/bootstrap/init.cc @@ -0,0 +1,30 @@ +/* + * \brief Initialization code for bootstrap + * \author Stefan Kalkowski + * \date 2016-09-22 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +/* local */ +#include + +/* base includes */ +#include +#include + +Platform & platform() { return *unmanaged_singleton(); } + +extern "C" void init() __attribute__ ((noreturn)); + +extern "C" void init() +{ + Genode::init_log(); + platform().enable_mmu(); + platform().start_core(); +} diff --git a/repos/base-hw/src/bootstrap/lock.cc b/repos/base-hw/src/bootstrap/lock.cc new file mode 100644 index 000000000..db8d4e454 --- /dev/null +++ b/repos/base-hw/src/bootstrap/lock.cc @@ -0,0 +1,32 @@ +/* + * \brief Lock dummy implementation + * \author Stefan Kalkowski + * \date 2016-09-23 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#include +#include + +Genode::Cancelable_lock::Cancelable_lock(Genode::Cancelable_lock::State state) +: _state(state), _owner(nullptr) { } + + +void Genode::Cancelable_lock::unlock() +{ + assert(_state == LOCKED); + _state = UNLOCKED; +} + + +void Genode::Cancelable_lock::lock() +{ + assert(_state == UNLOCKED); + _state = LOCKED; +} diff --git a/repos/base-hw/src/bootstrap/platform.cc b/repos/base-hw/src/bootstrap/platform.cc new file mode 100644 index 000000000..c31930318 --- /dev/null +++ b/repos/base-hw/src/bootstrap/platform.cc @@ -0,0 +1,191 @@ +/* + * \brief Platform implementation + * \author Stefan Kalkowski + * \date 2016-10-19 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +/* base-internal includes */ +#include + +/* core includes */ +#include +#include +#include + + +/***************************** + ** Platform::Ram_allocator ** + *****************************/ + +void * Platform::Ram_allocator::alloc_aligned(size_t size, unsigned align) +{ + using namespace Genode; + + void * ret; + assert(Base::alloc_aligned(round_page(size), &ret, + max(align, get_page_size_log2())).ok()); + return ret; +} + + +bool Platform::Ram_allocator::alloc(size_t size, void **out_addr) +{ + *out_addr = alloc_aligned(size, 0); + return true; +} + + +void Platform::Ram_allocator::add(Memory_region const & region) { + add_range(region.base, region.size); } + + +void Platform::Ram_allocator::remove(Memory_region const & region) { + remove_range(region.base, region.size); } + + +/****************** + ** Platform::Pd ** + ******************/ + +Platform::Pd::Pd(Platform::Ram_allocator & alloc) +: table_base(alloc.alloc_aligned(sizeof(Bootinfo::Table), + Bootinfo::Table::ALIGNM_LOG2)), + allocator_base(alloc.alloc_aligned(sizeof(Bootinfo::Table_allocator), + Bootinfo::Table::ALIGNM_LOG2)), + table(*Genode::construct_at(table_base)), + allocator(*Genode::construct_at(allocator_base)) +{ + using namespace Genode; + map_insert(Mapping((addr_t)table_base, (addr_t)table_base, + sizeof(Bootinfo::Table), PAGE_FLAGS_KERN_DATA)); + map_insert(Mapping((addr_t)allocator_base, (addr_t)allocator_base, + sizeof(Bootinfo::Table_allocator), PAGE_FLAGS_KERN_DATA)); +} + + +void Platform::Pd::map(Mapping m) +{ + try { + table.insert_translation(m.virt(), m.phys(), m.size(), m.flags(), + allocator.alloc()); + } catch(Genode::Allocator::Out_of_memory) { + Genode::error("translation table needs to much RAM"); + } catch (...) { + Genode::error("invalid mapping ", m); + } +} + + +void Platform::Pd::map_insert(Mapping m) +{ + mappings.add(m); + map(m); +} + + +/************** + ** Platform ** + **************/ + +addr_t Platform::_load_elf() +{ + using namespace Genode; + + addr_t start = ~0UL; + addr_t end = 0; + auto lambda = [&] (Genode::Elf_segment & segment) { + void * phys = (void*)(core_elf_addr + segment.file_offset()); + start = min(start, (addr_t) phys); + size_t const size = round_page(segment.mem_size()); + + if (segment.flags().w) { + unsigned align_log2; + for (align_log2 = 0; align_log2 < 8*sizeof(addr_t); align_log2++) + if ((addr_t)(1 << align_log2) & (addr_t)phys) break; + + void * const dst = ram_alloc.alloc_aligned(segment.mem_size(), + align_log2); + memcpy(dst, phys, segment.file_size()); + + if (size > segment.file_size()) + memset((void *)((addr_t)dst + segment.file_size()), + 0, size - segment.file_size()); + + phys = dst; + } + + //FIXME: set read-only, privileged and global accordingly + Page_flags flags{RW, segment.flags().x ? EXEC : NO_EXEC, + USER, NO_GLOBAL, RAM, CACHED}; + Mapping m((addr_t)phys, (addr_t)segment.start(), size, flags); + core_pd->map_insert(m); + end = max(end, (addr_t)segment.start() + size); + }; + core_elf.for_each_segment(lambda); + return end; +} + + +void Platform::start_core() +{ + typedef void (* Entry)(); + Entry __attribute__((noreturn)) const entry + = reinterpret_cast(core_elf.entry()); + entry(); +} + + +static constexpr Genode::Boot_modules_header & header() { + return *((Genode::Boot_modules_header*) &_boot_modules_headers_begin); } + + +Platform::Platform() +: bootstrap_region((addr_t)&_prog_img_beg, + ((addr_t)&_prog_img_end - (addr_t)&_prog_img_beg)), + core_pd(ram_alloc), + core_elf_addr(header().base), + core_elf(core_elf_addr) +{ + using namespace Genode; + + /* prepare the ram allocator */ + board.early_ram_regions.for_each([this] (Memory_region const & region) { + ram_alloc.add(region); }); + ram_alloc.remove(bootstrap_region); + + /* now we can use the ram allocator for core's pd */ + core_pd.construct(ram_alloc); + + /* temporarily map all bootstrap memory 1:1 for transition to core */ + // FIXME do not insert as mapping for core + core_pd->map_insert(Mapping(bootstrap_region.base, bootstrap_region.base, + bootstrap_region.size, PAGE_FLAGS_KERN_TEXT)); + + /* map memory-mapped I/O for core */ + board.core_mmio.for_each_mapping([&] (Mapping const & m) { + core_pd->map_insert(m); }); + + /* load ELF */ + addr_t const elf_end = _load_elf(); + + /* setup boot info page */ + void * bi_base = ram_alloc.alloc(sizeof(Bootinfo)); + core_pd->map_insert(Mapping((addr_t)bi_base, elf_end, sizeof(Bootinfo), + PAGE_FLAGS_KERN_TEXT)); + Bootinfo & bootinfo = + *construct_at(bi_base, &core_pd->table, &core_pd->allocator, + core_pd->mappings, board.core_mmio); + + /* add all left RAM to bootinfo */ + ram_alloc.for_each_free_region([&] (Memory_region const & r) { + bootinfo.ram_regions.add(r); }); + board.late_ram_regions.for_each([&] (Memory_region const & r) { + bootinfo.ram_regions.add(r); }); +} diff --git a/repos/base-hw/src/bootstrap/spec/arm/crt0.s b/repos/base-hw/src/bootstrap/spec/arm/crt0.s new file mode 100644 index 000000000..e7eb6aef9 --- /dev/null +++ b/repos/base-hw/src/bootstrap/spec/arm/crt0.s @@ -0,0 +1,60 @@ +/* + * \brief Startup code for bootstrap + * \author Stefan Kalkowski + * \date 2016-09-22 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +.include "macros.s" + +.set STACK_SIZE, 4 * 16 * 1024 + +.section ".text.crt0" + + .global _start + _start: + + /* zero-fill BSS segment */ + adr r0, _bss_local_start + adr r1, _bss_local_end + ldr r0, [r0] + ldr r1, [r1] + mov r2, #0 + 1: + cmp r1, r0 + ble 2f + str r2, [r0] + add r0, r0, #4 + b 1b + 2: + + .global _start_setup_stack + _start_setup_stack: + + /* setup multiprocessor-aware kernel stack-pointer */ + adr r0, _start_stack + adr r1, _start_stack_size + ldr r1, [r1] + _init_kernel_sp r0, r1 + b init + + _bss_local_start: + .long _bss_start + + _bss_local_end: + .long _bss_end + + _start_stack_size: + .long STACK_SIZE + + .align 3 + _start_stack: + .rept NR_OF_CPUS + .space STACK_SIZE + .endr diff --git a/repos/base-hw/src/bootstrap/spec/arm_v6/cpu.cc b/repos/base-hw/src/bootstrap/spec/arm_v6/cpu.cc new file mode 100644 index 000000000..2844eaa81 --- /dev/null +++ b/repos/base-hw/src/bootstrap/spec/arm_v6/cpu.cc @@ -0,0 +1,23 @@ +/* + * \brief CPU driver for core + * \author Norman Feske + * \author Martin stein + * \author Stefan Kalkowski + * \date 2012-08-30 + */ + +/* + * Copyright (C) 2012-2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#include + +void Genode::Arm::clean_invalidate_data_cache() { + asm volatile ("mcr p15, 0, %[rd], c7, c14, 0" :: [rd]"r"(0) : ); } + + +void Genode::Cpu::translation_added(Genode::addr_t const addr, + Genode::size_t const size) { } diff --git a/repos/base-hw/src/core/spec/arndale/cpu.cc b/repos/base-hw/src/bootstrap/spec/arndale/cpu.cc similarity index 77% rename from repos/base-hw/src/core/spec/arndale/cpu.cc rename to repos/base-hw/src/bootstrap/spec/arndale/cpu.cc index 191f883d1..6ca9effd7 100644 --- a/repos/base-hw/src/core/spec/arndale/cpu.cc +++ b/repos/base-hw/src/bootstrap/spec/arndale/cpu.cc @@ -13,8 +13,7 @@ /* core includes */ #include - -namespace Kernel { void prepare_hypervisor(void); } +#include static unsigned char hyp_mode_stack[1024]; @@ -61,6 +60,25 @@ static inline void prepare_nonsecure_world() } +static inline void prepare_hypervisor(Genode::Translation_table & table) +{ + using Genode::Cpu; + + /* set hypervisor exception vector */ + Cpu::hyp_exception_entry_at((void*)0xfff00000); /* FIXME */ + + /* set hypervisor's translation table */ + Cpu::Httbr::translation_table((Genode::addr_t)&table); + + /* prepare MMU usage by hypervisor code */ + Cpu::Htcr::write(Cpu::Ttbcr::init_virt_kernel()); + Cpu::Hcptr::write(Cpu::Hcptr::init()); + Cpu::Hmair0::write(Cpu::Mair0::init_virt_kernel()); + Cpu::Vtcr::write(Cpu::Vtcr::init()); + Cpu::Hsctlr::write(Cpu::Sctlr::init_value()); +} + + static inline void switch_to_supervisor_mode() { using Psr = Genode::Cpu::Psr; @@ -82,9 +100,9 @@ static inline void switch_to_supervisor_mode() } -void Genode::Cpu::init() +void Genode::Cpu::init(Genode::Translation_table & table) { prepare_nonsecure_world(); - Kernel::prepare_hypervisor(); + prepare_hypervisor(table); switch_to_supervisor_mode(); } diff --git a/repos/base-hw/src/bootstrap/spec/cortex_a9/platform.cc b/repos/base-hw/src/bootstrap/spec/cortex_a9/platform.cc new file mode 100644 index 000000000..a33860a9b --- /dev/null +++ b/repos/base-hw/src/bootstrap/spec/cortex_a9/platform.cc @@ -0,0 +1,169 @@ +/* + * \brief Cpu class implementation specific to Cortex A9 SMP + * \author Stefan Kalkowski + * \date 2015-12-09 + */ + +/* + * Copyright (C) 2015-2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#include + +/* core includes */ +#include +#include + +//using namespace Kernel; + +/* entrypoint for non-boot CPUs */ +extern "C" void * _start_setup_stack; + + +/** + * SMP-safe simple counter + */ +class Cpu_counter +{ + private: + + Kernel::Lock _lock; + volatile int _value = 0; + + public: + + void inc() + { + Kernel::Lock::Guard guard(_lock); + Genode::memory_barrier(); + _value++; + } + + void wait_for(int const v) { + while (_value < v) ; } +}; + + +struct Scu : Genode::Mmio +{ + struct Cr : Register<0x0, 32> + { + struct Enable : Bitfield<0, 1> { }; + }; + + struct Dcr : Register<0x30, 32> + { + struct Bit_0 : Bitfield<0, 1> { }; + }; + + struct Iassr : Register<0xc, 32> + { + struct Cpu0_way : Bitfield<0, 4> { }; + struct Cpu1_way : Bitfield<4, 4> { }; + struct Cpu2_way : Bitfield<8, 4> { }; + struct Cpu3_way : Bitfield<12, 4> { }; + }; + + Scu(Genode::addr_t mmio) : Genode::Mmio(mmio) { } + + void invalidate() + { + Iassr::access_t iassr = 0; + for (Iassr::access_t way = 0; way <= Iassr::Cpu0_way::mask(); + way++) { + Iassr::Cpu0_way::set(iassr, way); + Iassr::Cpu1_way::set(iassr, way); + Iassr::Cpu2_way::set(iassr, way); + Iassr::Cpu3_way::set(iassr, way); + write(iassr); + } + } + + void enable(bool err_arm_764369) + { + if (err_arm_764369) write(1); + write(1); + } +}; + + +/* + * The initialization of Cortex A9 multicore systems implies a sophisticated + * algorithm in early revisions of this cpu. + * + * See ARM's Cortex-A9 MPCore TRM r2p0 in section 5.3.5 for more details + */ +void Platform::enable_mmu() +{ + using Genode::Cpu; + static volatile bool primary_cpu = true; + static Cpu_counter data_cache_invalidated; + static Cpu_counter data_cache_enabled; + static Cpu_counter smp_coherency_enabled; + + bool primary = primary_cpu; + if (primary) primary_cpu = false; + + Cpu::Sctlr::init(); + Cpu::Psr::write(Cpu::Psr::init_kernel()); + + /* locally initialize interrupt controller */ + pic.init_cpu_local(); + + cpu.invalidate_inner_data_cache(); + data_cache_invalidated.inc(); + + /* primary cpu wakes up all others */ + if (primary && NR_OF_CPUS > 1) { + board.wake_up_all_cpus(&_start_setup_stack); + + /* send an IPI to all other cpus */ + pic.send_ipi(); + } + + /* wait for other cores' data cache invalidation */ + data_cache_invalidated.wait_for(NR_OF_CPUS); + + if (primary) { + Scu scu(Board::SCU_MMIO_BASE); + scu.invalidate(); + Board::L2_cache l2_cache(Board::PL310_MMIO_BASE); + l2_cache.disable(); + l2_cache.invalidate(); + scu.enable(board.errata(Platform::Board::ARM_764369)); + } + + /* secondary cpus wait for the primary's cache activation */ + if (!primary) data_cache_enabled.wait_for(1); + + cpu.enable_mmu_and_caches((Genode::addr_t)core_pd->table_base); + + data_cache_enabled.inc(); + cpu.clean_invalidate_inner_data_cache(); + + /* wait for other cores' data cache activation */ + data_cache_enabled.wait_for(NR_OF_CPUS); + + if (primary) { + Board::L2_cache l2_cache(board.core_mmio.virt_addr(Board::PL310_MMIO_BASE)); + l2_cache.enable(); + } + + /* secondary cpus wait for the primary's coherency activation */ + if (!primary) smp_coherency_enabled.wait_for(1); + + Cpu::Actlr::enable_smp(board); + smp_coherency_enabled.inc(); + + /* + * strangely, some older versions (imx6) seem to not work cache coherent + * until SMP bit is set, so write back the variable here. + */ + cpu.clean_invalidate_inner_data_cache(); + + /* wait for other cores' coherency activation */ + smp_coherency_enabled.wait_for(NR_OF_CPUS); +} diff --git a/repos/base-hw/src/bootstrap/spec/exynos5/platform.cc b/repos/base-hw/src/bootstrap/spec/exynos5/platform.cc new file mode 100644 index 000000000..2f3b751ed --- /dev/null +++ b/repos/base-hw/src/bootstrap/spec/exynos5/platform.cc @@ -0,0 +1,48 @@ +/* + * \brief Parts of platform that are specific to Arndale + * \author Martin Stein + * \date 2012-04-27 + */ + +/* + * Copyright (C) 2012 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#include + +/* entrypoint for non-boot CPUs */ +extern "C" void * _start_setup_stack; + +Platform::Board::Board() +: early_ram_regions(Memory_region { RAM_0_BASE, RAM_0_SIZE }), + core_mmio(Memory_region { IRQ_CONTROLLER_BASE, IRQ_CONTROLLER_SIZE }, + Memory_region { IRQ_CONTROLLER_VT_CTRL_BASE, IRQ_CONTROLLER_VT_CTRL_SIZE }, + Memory_region { MCT_MMIO_BASE, MCT_MMIO_SIZE }, + Memory_region { UART_2_MMIO_BASE, UART_2_MMIO_SIZE }) { } + + +void Platform::enable_mmu() +{ + using Genode::Cpu; + + static volatile bool primary_cpu = true; + pic.init_cpu_local(); + + cpu.init(*reinterpret_cast(core_pd->table_base)); + + Cpu::Sctlr::init(); + Cpu::Psr::write(Cpu::Psr::init_kernel()); + + cpu.invalidate_inner_data_cache(); + + /* primary cpu wakes up all others */ + if (primary_cpu && NR_OF_CPUS > 1) { + primary_cpu = false; + board.wake_up_all_cpus(&_start_setup_stack); + } + + cpu.enable_mmu_and_caches((Genode::addr_t)core_pd->table_base); +} diff --git a/repos/base-hw/src/bootstrap/spec/imx53/board.cc b/repos/base-hw/src/bootstrap/spec/imx53/board.cc new file mode 100644 index 000000000..e48b27672 --- /dev/null +++ b/repos/base-hw/src/bootstrap/spec/imx53/board.cc @@ -0,0 +1,25 @@ +/* + * \brief Specific bootstrap implementations + * \author Stefan Kalkowski + * \date 2017-01-27 + */ + +/* + * Copyright (C) 2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#include +#include + +using Genode::Memory_region; + +Platform::Board::Board() +: early_ram_regions(Memory_region { RAM0_BASE, RAM0_SIZE }, + Memory_region { RAM1_BASE, RAM1_SIZE }), + core_mmio(Memory_region { UART_1_MMIO_BASE, UART_1_MMIO_SIZE }, + Memory_region { EPIT_1_MMIO_BASE, EPIT_1_MMIO_SIZE }, + Memory_region { IRQ_CONTROLLER_BASE, IRQ_CONTROLLER_SIZE }) { + init(); } diff --git a/repos/base-hw/src/bootstrap/spec/imx53/board_trustzone.cc b/repos/base-hw/src/bootstrap/spec/imx53/board_trustzone.cc new file mode 100644 index 000000000..ae05e82d1 --- /dev/null +++ b/repos/base-hw/src/bootstrap/spec/imx53/board_trustzone.cc @@ -0,0 +1,27 @@ +/* + * \brief Specific core implementations + * \author Stefan Kalkowski + * \date 2017-01-27 + */ + +/* + * Copyright (C) 2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +/* core includes */ +#include +#include + +using Genode::Memory_region; + +Platform::Board::Board() +: early_ram_regions(Memory_region { Trustzone::SECURE_RAM_BASE, + Trustzone::SECURE_RAM_SIZE }), + core_mmio(Memory_region { UART_1_MMIO_BASE, UART_1_MMIO_SIZE }, + Memory_region { EPIT_1_MMIO_BASE, EPIT_1_MMIO_SIZE }, + Memory_region { IRQ_CONTROLLER_BASE, IRQ_CONTROLLER_SIZE }, + Memory_region { CSU_BASE, CSU_SIZE }) { + init(); } diff --git a/repos/base-hw/src/bootstrap/spec/imx53/platform.cc b/repos/base-hw/src/bootstrap/spec/imx53/platform.cc new file mode 100644 index 000000000..39d07b9c1 --- /dev/null +++ b/repos/base-hw/src/bootstrap/spec/imx53/platform.cc @@ -0,0 +1,28 @@ +/* + * \brief Specific i.MX53 bootstrap implementations + * \author Stefan Kalkowski + * \date 2012-10-24 + */ + +/* + * Copyright (C) 2012-2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +/* core includes */ +#include +#include + + +void Platform::enable_mmu() +{ + Genode::Cpu::Sctlr::init(); + + cpu.enable_mmu_and_caches((addr_t)core_pd->table_base); +} + + +void Genode::Cpu::translation_added(Genode::addr_t const addr, + Genode::size_t const size) { } diff --git a/repos/base-hw/src/bootstrap/spec/imx6/platform.cc b/repos/base-hw/src/bootstrap/spec/imx6/platform.cc new file mode 100644 index 000000000..552da464e --- /dev/null +++ b/repos/base-hw/src/bootstrap/spec/imx6/platform.cc @@ -0,0 +1,44 @@ +/* + * \brief Specific bootstrap implementations + * \author Stefan Kalkowski + * \author Josef Soentgen + * \author Martin Stein + * \date 2014-02-25 + */ + +/* + * Copyright (C) 2014-2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +/* core includes */ +#include +#include + +using namespace Genode; + +Platform::Board::Board() +: early_ram_regions(Memory_region { RAM0_BASE, RAM0_SIZE }), + core_mmio(Memory_region { UART_1_MMIO_BASE, + UART_1_MMIO_SIZE }, + Memory_region { CORTEX_A9_PRIVATE_MEM_BASE, + CORTEX_A9_PRIVATE_MEM_SIZE }, + Memory_region { PL310_MMIO_BASE, + PL310_MMIO_SIZE }) { init(); } + + +bool Cortex_a9::Board::errata(Cortex_a9::Board::Errata err) +{ + switch (err) { + case Cortex_a9::Board::ARM_754322: + case Cortex_a9::Board::ARM_764369: + case Cortex_a9::Board::ARM_775420: + case Cortex_a9::Board::PL310_588369: + case Cortex_a9::Board::PL310_727915: + case Cortex_a9::Board::PL310_769419: + return true; + }; + return false; +} diff --git a/repos/base-hw/src/core/spec/cortex_a15/cpu_init.cc b/repos/base-hw/src/bootstrap/spec/odroid_xu/cpu.cc similarity index 84% rename from repos/base-hw/src/core/spec/cortex_a15/cpu_init.cc rename to repos/base-hw/src/bootstrap/spec/odroid_xu/cpu.cc index 389af2f79..8e65896df 100644 --- a/repos/base-hw/src/core/spec/cortex_a15/cpu_init.cc +++ b/repos/base-hw/src/bootstrap/spec/odroid_xu/cpu.cc @@ -13,4 +13,4 @@ #include -void Genode::Cpu::init() {} +void Genode::Cpu::init(Genode::Translation_table&) {} diff --git a/repos/base-hw/src/bootstrap/spec/panda/platform.cc b/repos/base-hw/src/bootstrap/spec/panda/platform.cc new file mode 100644 index 000000000..ea0ac794c --- /dev/null +++ b/repos/base-hw/src/bootstrap/spec/panda/platform.cc @@ -0,0 +1,51 @@ +/* + * \brief Parts of platform that are specific to Pandaboard + * \author Stefan Kalkowski + * \date 2017-01-30 + */ + +/* + * Copyright (C) 2017 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#include +#include + +Platform::Board::Board() +: early_ram_regions(Memory_region { RAM_0_BASE, RAM_0_SIZE }), + core_mmio(Memory_region { CORTEX_A9_PRIVATE_MEM_BASE, + CORTEX_A9_PRIVATE_MEM_SIZE }, + Memory_region { TL16C750_3_MMIO_BASE, + TL16C750_MMIO_SIZE }, + Memory_region { PL310_MMIO_BASE, + PL310_MMIO_SIZE }) { } + + +void Cortex_a9::Board::wake_up_all_cpus(void * const ip) +{ + Genode::Cortex_a9_wugen wugen; + wugen.init_cpu_1(ip); + asm volatile("dsb\n" + "sev\n"); +} + + +bool Cortex_a9::Board::errata(Cortex_a9::Board::Errata err) +{ + switch (err) { + case Cortex_a9::Board::PL310_588369: + case Cortex_a9::Board::PL310_727915: return true; + default: ; + }; + return false; +} + + +void Genode::Cpu::Actlr::enable_smp(Genode::Board & board) +{ + Board::Secure_monitor monitor; + monitor.call(Board::Secure_monitor::CPU_ACTLR_SMP_BIT_RAISE, 0); +} diff --git a/repos/base-hw/src/bootstrap/spec/pbxa9/platform.cc b/repos/base-hw/src/bootstrap/spec/pbxa9/platform.cc new file mode 100644 index 000000000..4a045e1ea --- /dev/null +++ b/repos/base-hw/src/bootstrap/spec/pbxa9/platform.cc @@ -0,0 +1,52 @@ +/* + * \brief Pbxa9 specific platform implementation + * \author Stefan Kalkowski + * \date 2016-10-20 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +/* bootstrap includes */ +#include + +Platform::Board::Board() +: early_ram_regions(Memory_region { RAM_0_BASE, RAM_0_SIZE }, + Memory_region { RAM_1_BASE, RAM_1_SIZE }), + core_mmio(Memory_region { Board::CORTEX_A9_PRIVATE_MEM_BASE, + Board::CORTEX_A9_PRIVATE_MEM_SIZE }, + Memory_region { Board::PL011_0_MMIO_BASE, + Board::PL011_0_MMIO_SIZE }, + Memory_region { Board::PL310_MMIO_BASE, + Board::PL310_MMIO_SIZE }) { } + + +bool Cortex_a9::Board::errata(Cortex_a9::Board::Errata err) { + return false; } + + +void Cortex_a9::Board::wake_up_all_cpus(void * const ip) +{ + /** + * set the entrypoint for the other CPUs via the flags register + * of the system control registers. ARMs boot monitor code will + * read out this register and jump to it after the cpu received + * an interrupt + */ + struct System_control : Genode::Mmio + { + struct Flagsset : Register<0x30, 32> { }; + struct Flagsclr : Register<0x34, 32> { }; + + System_control(void * const ip) + : Mmio(SYSTEM_CONTROL_MMIO_BASE) + { + write(~0UL); + write(reinterpret_cast(ip)); + } + } sc(ip); +} diff --git a/repos/base-hw/src/bootstrap/spec/riscv/cpu.cc b/repos/base-hw/src/bootstrap/spec/riscv/cpu.cc new file mode 100644 index 000000000..f3c54c962 --- /dev/null +++ b/repos/base-hw/src/bootstrap/spec/riscv/cpu.cc @@ -0,0 +1,19 @@ +/* + * \brief CPU core implementation + * \author Sebastian Sumpf + * \author Stefan Kalkowski + * \date 2016-02-10 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +/* core includes */ +#include + +void Genode::Cpu::translation_added(addr_t const addr, size_t const size) { + Genode::Cpu::sfence(); } diff --git a/repos/base-hw/src/bootstrap/spec/riscv/crt0.s b/repos/base-hw/src/bootstrap/spec/riscv/crt0.s new file mode 100644 index 000000000..67dcbe6d0 --- /dev/null +++ b/repos/base-hw/src/bootstrap/spec/riscv/crt0.s @@ -0,0 +1,51 @@ +/** + * \brief Kernel startup code + * \author Sebastian Sumpf + * \author Stefan Kalkowski + * \date 2015-06-010 + */ + +/* + * Copyright (C) 2015-2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +.set STACK_SIZE, 64 * 1024 + +.section ".text.crt0" + +.global _start +_start: +j _start_next_page + +/* leave first page empty for mode-transition page located at 0x100 */ +.space 4096 + +_start_next_page: + + /* clear the bss segment */ +la a0, _bss_start +la a1, _bss_end +1: +sd x0, (a0) +addi a0, a0, 8 +bne a0, a1, 1b + +la sp, _stack_area_start +la a0, STACK_SIZE +ld a0, (a0) +add sp, sp, a0 + +/* save kernel stack pointer in mscratch */ +csrw mscratch, sp + +jal setup_riscv_exception_vector +jal init + +1: j 1b + +.align 3 +_stack_area_start: +.space STACK_SIZE diff --git a/repos/base-hw/src/core/spec/riscv/kernel/exception_vector.cc b/repos/base-hw/src/bootstrap/spec/riscv/exception_vector.cc similarity index 100% rename from repos/base-hw/src/core/spec/riscv/kernel/exception_vector.cc rename to repos/base-hw/src/bootstrap/spec/riscv/exception_vector.cc diff --git a/repos/base-hw/src/bootstrap/spec/riscv/platform.cc b/repos/base-hw/src/bootstrap/spec/riscv/platform.cc new file mode 100644 index 000000000..053b0ed0f --- /dev/null +++ b/repos/base-hw/src/bootstrap/spec/riscv/platform.cc @@ -0,0 +1,59 @@ +/* + * \brief Platform implementations specific for RISC-V + * \author Stefan Kalkowski + * \author Sebastian Sumpf + * \date 2016-11-23 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#include + +Platform::Board::Board() +: early_ram_regions(Genode::Memory_region { 0, 128 * 1024 * 1024 } ) {} + + +struct Mstatus : Genode::Register<64> +{ + enum { + USER = 0, + SUPERVISOR = 1, + Sv39 = 9, + }; + struct Ie : Bitfield<0, 1> { }; + struct Priv : Bitfield<1, 2> { }; + struct Ie1 : Bitfield<3, 1> { }; + struct Priv1 : Bitfield<4, 2> { }; + struct Fs : Bitfield<12, 2> { enum { INITIAL = 1 }; }; + struct Vm : Bitfield<17, 5> { }; +}; + + +void Platform::enable_mmu() +{ + using Genode::Cpu; + + /* read status register */ + Mstatus::access_t mstatus = 0; + + Mstatus::Vm::set(mstatus, Mstatus::Sv39); /* enable Sv39 paging */ + Mstatus::Fs::set(mstatus, Mstatus::Fs::INITIAL); /* enable FPU */ + Mstatus::Ie1::set(mstatus, 1); /* user mode interrupt */ + Mstatus::Priv1::set(mstatus, Mstatus::USER); /* set user mode */ + Mstatus::Ie::set(mstatus, 0); /* disable interrupts */ + Mstatus::Priv::set(mstatus, Mstatus::SUPERVISOR); /* set supervisor mode */ + + asm volatile ("csrw sasid, %0\n" /* address space id */ + "csrw sptbr, %1\n" /* set page table */ + "csrw mstatus, %2\n" /* change mode */ + : + : "r" (0/*core_pd.asid*/), + "r" (core_pd->table_base), + "r" (mstatus) + : "memory"); +} diff --git a/repos/base-hw/src/bootstrap/spec/rpi/platform.cc b/repos/base-hw/src/bootstrap/spec/rpi/platform.cc new file mode 100644 index 000000000..e02d9df3e --- /dev/null +++ b/repos/base-hw/src/bootstrap/spec/rpi/platform.cc @@ -0,0 +1,46 @@ +/* + * \brief Platform implementations specific for base-hw and Raspberry Pi + * \author Norman Feske + * \author Stefan Kalkowski + * \date 2013-04-05 + */ + +/* + * Copyright (C) 2013-2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#include + +using Genode::Memory_region; + +/** + * Leave out the first page (being 0x0) from bootstraps RAM allocator, + * some code does not feel happy with addresses being zero + */ +Platform::Board::Board() +: early_ram_regions(Memory_region { RAM_0_BASE + 0x1000, + RAM_0_SIZE - 0x1000 }), + late_ram_regions(Memory_region { RAM_0_BASE, 0x1000 }), + core_mmio(Memory_region { PL011_0_MMIO_BASE, + PL011_0_MMIO_SIZE }, + Memory_region { SYSTEM_TIMER_MMIO_BASE, + SYSTEM_TIMER_MMIO_SIZE }, + Memory_region { IRQ_CONTROLLER_BASE, + IRQ_CONTROLLER_SIZE }, + Memory_region { USB_DWC_OTG_BASE, + USB_DWC_OTG_SIZE }) {} + + +void Platform::enable_mmu() +{ + Genode::Cpu::Sctlr::init(); + Genode::Cpu::Psr::write(Genode::Cpu::Psr::init_kernel()); + + /* check for mapping restrictions */ + assert(!Genode::Cpu::restricted_page_mappings()); + + cpu.enable_mmu_and_caches((addr_t)core_pd->table_base); +} diff --git a/repos/base-hw/src/bootstrap/spec/x86_64/crt0.s b/repos/base-hw/src/bootstrap/spec/x86_64/crt0.s new file mode 100644 index 000000000..d471201e1 --- /dev/null +++ b/repos/base-hw/src/bootstrap/spec/x86_64/crt0.s @@ -0,0 +1,118 @@ +/* + * \brief Startup code for kernel + * \author Adrian-Ken Rueegsegger + * \author Martin Stein + * \author Reto Buerki + * \author Stefan Kalkowski + * \date 2015-02-06 + */ + +/* + * Copyright (C) 2011-2015 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +.include "macros.s" + +.section ".text.crt0" + + /* magic multi-boot header to make GRUB happy */ + .long 0x1badb002 + .long 0x0 + .long 0xe4524ffe + + /********************************** + ** Startup code for primary CPU ** + **********************************/ + +.code32 + .global _start + _start: + + /** + * zero-fill BSS segment + */ + leal _bss_start, %edi + leal _bss_end, %ecx + sub %edi, %ecx + shr $2, %ecx + xor %eax, %eax + rep stosl + + /* Enable PAE (prerequisite for IA-32e mode) */ + movl %cr4, %eax + btsl $5, %eax + movl %eax, %cr4 + + /* Load initial pagetables */ + leal _kernel_pml4, %eax + mov %eax, %cr3 + + /* Enable IA-32e mode and execute-disable */ + movl $0xc0000080, %ecx + rdmsr + btsl $8, %eax + btsl $11, %eax + wrmsr + + /* Enable paging, write protection and caching */ + movl %cr0, %eax + btsl $16, %eax + btrl $29, %eax + btrl $30, %eax + btsl $31, %eax + movl %eax, %cr0 + + /* Set up GDT */ + lgdt _mt_gdt_ptr + + /* Indirect long jump to 64-bit code */ + ljmp $8, $_start64 + +.code64 + _start64: + + /* + * Set up kernel segment selectors + */ + mov $0x10, %eax + mov %eax, %ss + mov %eax, %ds + mov %eax, %es + mov %eax, %fs + mov %eax, %gs + + /* + * Install initial temporary environment that is replaced later by the + * environment that init_main_thread creates. + */ + leaq _stack_high@GOTPCREL(%rip),%rax + movq (%rax), %rsp + + movq __initial_bx@GOTPCREL(%rip),%rax + movq %rbx, (%rax) + + /* kernel-initialization */ + call init + + /* catch erroneous return of the kernel initialization */ + 1: jmp 1b + + _define_gdt 0 + + +/********************************* + ** .bss (non-initialized data) ** + *********************************/ + +.bss + + /* stack of the temporary initial environment */ + .p2align 8 + .space 32 * 1024 + _stack_high: + .globl __initial_bx + __initial_bx: + .space 8 diff --git a/repos/base-hw/src/core/spec/x86_64/kernel/crt0_translation_table.s b/repos/base-hw/src/bootstrap/spec/x86_64/crt0_translation_table.s similarity index 80% rename from repos/base-hw/src/core/spec/x86_64/kernel/crt0_translation_table.s rename to repos/base-hw/src/bootstrap/spec/x86_64/crt0_translation_table.s index 2cf503e77..bb2bbbf82 100644 --- a/repos/base-hw/src/core/spec/x86_64/kernel/crt0_translation_table.s +++ b/repos/base-hw/src/bootstrap/spec/x86_64/crt0_translation_table.s @@ -2,11 +2,12 @@ * \brief Initial pagetables for x86_64 * \author Adrian-Ken Rueegsegger * \author Reto Buerki + * \author Stefan Kalkowski * \date 2015-04-22 */ /* - * Copyright (C) 2015 Genode Labs GmbH + * Copyright (C) 2015-2016 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -17,10 +18,10 @@ .data /******************************************** - ** Identity mapping from 2MiB to 1GiB ** + ** Identity mapping from 4KiB to 1GiB ** ** plus mappings for LAPIC, I/O APIC MMIO ** ** Page 0 containing the Bios Data Area ** - ** gets mapped to 2MB - 4K readonly. ** + ** gets mapped to 2MiB - 4KiB readonly. ** ********************************************/ /* PML4 */ @@ -57,5 +58,10 @@ .p2align MIN_PAGE_SIZE_LOG2 _kernel_pt_bda: - .fill 511, 8, 0x0 + .fill 1, 8, 0x0 + .set entry, 0x118f + .rept 510 + .quad entry + .set entry, entry + 0x1000 + .endr .quad 0x000001 diff --git a/repos/base-hw/src/core/spec/x86_64/muen/kernel/crt0_translation_table.s b/repos/base-hw/src/bootstrap/spec/x86_64/crt0_translation_table_muen.s similarity index 100% rename from repos/base-hw/src/core/spec/x86_64/muen/kernel/crt0_translation_table.s rename to repos/base-hw/src/bootstrap/spec/x86_64/crt0_translation_table_muen.s diff --git a/repos/base-hw/src/bootstrap/spec/x86_64/platform.cc b/repos/base-hw/src/bootstrap/spec/x86_64/platform.cc new file mode 100644 index 000000000..abc08777d --- /dev/null +++ b/repos/base-hw/src/bootstrap/spec/x86_64/platform.cc @@ -0,0 +1,75 @@ +/* + * \brief Platform implementations specific for x86_64 + * \author Reto Buerki + * \author Stefan Kalkowski + * \date 2015-05-04 + */ + +/* + * Copyright (C) 2015-2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +/* core includes */ +#include +#include +#include +#include + +using namespace Genode; + +/* contains physical pointer to multiboot */ +extern "C" Genode::addr_t __initial_bx; + +Platform::Board::Board() +: core_mmio(Memory_region { 0, 0x1000 }, + Memory_region { Board::MMIO_LAPIC_BASE, + Board::MMIO_LAPIC_SIZE }, + Memory_region { Board::MMIO_IOAPIC_BASE, + Board::MMIO_IOAPIC_SIZE }, + Memory_region { __initial_bx & ~0xFFFUL, + get_page_size() }) +{ + using Mmap = Multiboot_info::Mmap; + static constexpr size_t initial_map_max = 1024 * 1024 * 1024; + + for (unsigned i = 0; true; i++) { + Mmap v = Multiboot_info(__initial_bx).phys_ram(i); + if (!v.base) break; + + Mmap::Addr::access_t base = v.read(); + Mmap::Length::access_t size = v.read(); + + /* + * Exclude first physical page, so that it will become part of the + * MMIO allocator. The framebuffer requests this page as MMIO. + */ + if (base == 0 && size >= get_page_size()) { + base = get_page_size(); + size -= get_page_size(); + } + + if (base >= initial_map_max) { + late_ram_regions.add(Memory_region { base, size }); + continue; + } + + if (base + size <= initial_map_max) { + early_ram_regions.add(Memory_region { base, size }); + continue; + } + + size_t low_size = initial_map_max - base; + early_ram_regions.add(Memory_region { base, low_size }); + late_ram_regions.add(Memory_region { initial_map_max, size - low_size }); + } +} + + +void Platform::enable_mmu() { + Cpu::Cr3::write(Cpu::Cr3::init((addr_t)core_pd->table_base)); } + + +addr_t Bios_data_area::_mmio_base_virt() { return 0x1ff000; } diff --git a/repos/base-hw/src/bootstrap/spec/x86_64/platform_muen.cc b/repos/base-hw/src/bootstrap/spec/x86_64/platform_muen.cc new file mode 100644 index 000000000..d3eb0f597 --- /dev/null +++ b/repos/base-hw/src/bootstrap/spec/x86_64/platform_muen.cc @@ -0,0 +1,39 @@ +/* + * \brief Platform implementations specific for x86_64 + * \author Reto Buerki + * \author Stefan Kalkowski + * \date 2015-05-04 + */ + +/* + * Copyright (C) 2015-2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +/* core includes */ +#include +#include +#include + +using namespace Genode; + + +Platform::Board::Board() +: core_mmio(Memory_region { Sinfo::PHYSICAL_BASE_ADDR, Sinfo::SIZE }, + Memory_region { TIMER_BASE_ADDR, TIMER_SIZE }, + Memory_region { TIMER_PREEMPT_BASE_ADDR, TIMER_PREEMPT_SIZE }) +{ + struct Sinfo::Memregion_info region; + + Sinfo sinfo(Sinfo::PHYSICAL_BASE_ADDR); + if (!sinfo.get_memregion_info("ram", ®ion)) + error("Unable to retrieve base-hw ram region"); + else + early_ram_regions.add(Memory_region { region.address, region.size }); +} + + +void Platform::enable_mmu() { + Cpu::Cr3::write(Cpu::Cr3::init((addr_t)core_pd->table_base)); } diff --git a/repos/base-hw/src/bootstrap/spec/zynq/platform.cc b/repos/base-hw/src/bootstrap/spec/zynq/platform.cc new file mode 100644 index 000000000..82dac0d73 --- /dev/null +++ b/repos/base-hw/src/bootstrap/spec/zynq/platform.cc @@ -0,0 +1,32 @@ +/* + * \brief Platform implementations specific for base-hw and Zynq + * \author Johannes Schlatow + * \author Stefan Kalkowski + * \date 2014-12-15 + */ + +/* + * Copyright (C) 2014-2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +/* core includes */ +#include + + +Platform::Board::Board() +: early_ram_regions(Memory_region { RAM_0_BASE + 0x1000, + RAM_0_SIZE - 0x1000 }), + late_ram_regions(Memory_region { RAM_0_BASE, 0x1000 }), + core_mmio(Memory_region { CORTEX_A9_PRIVATE_MEM_BASE, + CORTEX_A9_PRIVATE_MEM_SIZE }, + Memory_region { KERNEL_UART_BASE, + KERNEL_UART_SIZE }, + Memory_region { PL310_MMIO_BASE, + PL310_MMIO_SIZE }) { } + + +bool Cortex_a9::Board::errata(Cortex_a9::Board::Errata err) { + return false; } diff --git a/repos/base-hw/src/bootstrap/thread.cc b/repos/base-hw/src/bootstrap/thread.cc new file mode 100644 index 000000000..4608fcb5c --- /dev/null +++ b/repos/base-hw/src/bootstrap/thread.cc @@ -0,0 +1,28 @@ +/* + * \brief Thread implementation needed by cxx library + * \author Stefan Kalkowski + * \date 2016-10-19 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +/* base includes */ +#include + +/* local includes */ +#include + + +Genode::Thread * Genode::Thread::myself() +{ + assert(false); + return nullptr; +} + + +Genode::Thread::Name Genode::Thread::name() const { return "bootstrap"; } diff --git a/repos/base-hw/src/core/core_log.cc b/repos/base-hw/src/core/core_log.cc index b42becce2..ee8794998 100644 --- a/repos/base-hw/src/core/core_log.cc +++ b/repos/base-hw/src/core/core_log.cc @@ -12,40 +12,16 @@ * under the terms of the GNU General Public License version 2. */ -/* Genode includes */ -#include - /* base-internal includes */ #include #include -#include #include -#include #include -static void out_char(char const c) -{ - using Genode::Serial; - - enum { - ASCII_LINE_FEED = 10, - ASCII_CARRIAGE_RETURN = 13, - BAUD_RATE = 115200 - }; - - Serial & serial = *unmanaged_singleton(BAUD_RATE); - if (c == ASCII_LINE_FEED) serial.put_char(ASCII_CARRIAGE_RETURN); - serial.put_char(c); -} - - -void Genode::Core_log::out(char const c) { out_char(c); } - - -void Kernel::log(char const c) { out_char(c); } +void Genode::Core_log::out(char const c) { Kernel::log(c); } void Genode::raw_write_string(char const *str) { - while (char c = *str++) out_char(c); } + while (char c = *str++) Kernel::log(c); } diff --git a/repos/base-hw/src/core/core_region_map.cc b/repos/base-hw/src/core/core_region_map.cc index dee1c9e00..30e8b38da 100644 --- a/repos/base-hw/src/core/core_region_map.cc +++ b/repos/base-hw/src/core/core_region_map.cc @@ -59,9 +59,9 @@ Core_region_map::attach(Dataspace_capability ds_cap, size_t size, /* map the dataspace's physical pages to corresponding virtual addresses */ unsigned num_pages = page_rounded_size >> get_page_size_log2(); - Page_flags const flags = Page_flags::apply_mapping(ds->writable(), - ds->cacheability(), - ds->io_mem()); + Page_flags const flags { ds->writable() ? RW : RO, NO_EXEC, USER, + NO_GLOBAL, ds->io_mem() ? DEVICE : RAM, + ds->cacheability() }; if (!map_local(ds->phys_addr(), (addr_t)virt_addr, num_pages, flags)) return nullptr; diff --git a/repos/base-hw/src/core/include/bootinfo.h b/repos/base-hw/src/core/include/bootinfo.h new file mode 100644 index 000000000..c9fb8ca19 --- /dev/null +++ b/repos/base-hw/src/core/include/bootinfo.h @@ -0,0 +1,44 @@ +/* + * \brief Boot information + * \author Stefan Kalkowski + * \date 2016-10-26 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _BOOTINFO_H_ +#define _BOOTINFO_H_ + +#include +#include +#include + +namespace Genode { struct Bootinfo; } + +struct Genode::Bootinfo +{ + using Table = Translation_table; + static constexpr size_t COUNT = Table::CORE_TRANS_TABLE_COUNT; + using Table_allocator = Translation_table_allocator_tpl; + using Mapping_pool = Array; + + Table * const table; + Table_allocator * const table_allocator; + Mapping_pool const elf_mappings; + Core_mmio const core_mmio; + Memory_region_array ram_regions; + + Bootinfo(Table * const table, + Table_allocator * const table_alloc, + Mapping_pool const elf_mappings, + Core_mmio const core_mmio) + : table(table), table_allocator(table_alloc), + elf_mappings(elf_mappings), core_mmio(core_mmio) {} +}; + +#endif /* _BOOTINFO_H_ */ diff --git a/repos/base-hw/src/core/include/core_mmio.h b/repos/base-hw/src/core/include/core_mmio.h new file mode 100644 index 000000000..3f7464dba --- /dev/null +++ b/repos/base-hw/src/core/include/core_mmio.h @@ -0,0 +1,57 @@ +/* + * \brief Representation of core's MMIO space + * \author Stefan Kalkowski + * \date 2016-11-24 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#ifndef _CORE_MMIO_H_ +#define _CORE_MMIO_H_ + +#include +#include +#include + +namespace Genode { struct Core_mmio; } + +struct Genode::Core_mmio : Genode::Memory_region_array +{ + using Memory_region_array::Memory_region_array; + + struct Not_found {}; + + template + void for_each_mapping(FUNC f) const + { + addr_t virt_base = 0xf0000000UL; /* FIXME */ + auto lambda = [&] (Memory_region const & r) { + f(Mapping { r.base, virt_base, r.size, PAGE_FLAGS_KERN_IO }); + virt_base += r.size + get_page_size(); + }; + for_each(lambda); + } + + addr_t virt_addr(addr_t phys_addr) const + { + /* + * Sadly this method is used quite early in the kernel + * where no exceptions can be used + */ + addr_t ret = 0; + for_each_mapping([&] (Mapping const & m) + { + if (phys_addr >= m.phys() && phys_addr < (m.phys()+m.size())) + ret = m.virt() + (phys_addr-m.phys()); + }); + + return ret; + } +}; + +#endif /* _CORE_MMIO_H_ */ diff --git a/repos/base-hw/src/core/include/kernel/cpu.h b/repos/base-hw/src/core/include/kernel/cpu.h index 4964335c2..c47b7ae31 100644 --- a/repos/base-hw/src/core/include/kernel/cpu.h +++ b/repos/base-hw/src/core/include/kernel/cpu.h @@ -61,7 +61,7 @@ namespace Kernel Cpu_pool * cpu_pool(); } -class Kernel::Cpu_context : Genode::Cpu::Context +class Kernel::Cpu_context : public Genode::Cpu::Context { private: @@ -292,7 +292,7 @@ class Kernel::Cpu : public Genode::Cpu, public Irq::Pool, private Timeout * \param core_pd core's pd object * \param board object encapsulating board specifics */ - void init(Pic &pic, Kernel::Pd &core_pd, Genode::Board & board); + void init(Pic &pic/*, Kernel::Pd &core_pd, Genode::Board & board*/); /** * Raise the IPI of the CPU diff --git a/repos/base-hw/src/core/include/kernel/pd.h b/repos/base-hw/src/core/include/kernel/pd.h index 6ba2bb6cd..f38188515 100644 --- a/repos/base-hw/src/core/include/kernel/pd.h +++ b/repos/base-hw/src/core/include/kernel/pd.h @@ -36,7 +36,7 @@ namespace Kernel * control provides a simple interface to access the code from within * the kernel. */ - class Mode_transition_control; + struct Mode_transition_control; /** * Return the system wide mode-transition control @@ -49,86 +49,40 @@ namespace Kernel class Pd; } -class Kernel::Mode_transition_control + +struct Kernel::Mode_transition_control { - friend class Pd; + /** + * Map the mode transition page to a virtual address space + * + * \param tt translation buffer of the address space + * \param alloc translation table allocator used for the mapping + */ + void map(Genode::Translation_table * tt, + Genode::Translation_table_allocator * alloc); - private: + /** + * Continue execution of client context + * + * \param context targeted CPU context + * \param cpu kernel name of targeted CPU + * \param entry_raw raw pointer to assembly entry-code + * \param context_ptr_base base address of client-context pointer region + */ + void switch_to(Cpu::Context * const context, + unsigned const cpu, + addr_t const entry_raw, + addr_t const context_ptr_base); - /* - * set the table allocator to the current minimum of bits-of-one-mword - * this is a limitation of the Bit_allocator used within this allocator. - * actually only one page-mapping is needed by the MTC allocator - */ - typedef Genode::Translation_table_allocator_tpl<64> Allocator; - typedef Genode::Translation_table Table; - - Allocator _alloc; - Table _table; - Cpu_context _master; - - /** - * Return size of the mode transition - */ - static size_t _size(); - - /** - * Return size of master-context space in the mode transition - */ - static size_t _master_context_size(); - - /** - * Return virtual address of the user entry-code - */ - static addr_t _virt_user_entry(); - - public: - - enum { - SIZE = Cpu::mtc_size, - VIRT_BASE = Cpu::exception_entry, - ALIGN_LOG2 = Genode::Translation_table::ALIGNM_LOG2, - ALIGN = 1 << ALIGN_LOG2, - }; - - /** - * Constructor - * - * \param c CPU context for kernel mode entry - */ - Mode_transition_control(); - - /** - * Map the mode transition page to a virtual address space - * - * \param tt translation buffer of the address space - * \param alloc translation table allocator used for the mapping - */ - void map(Genode::Translation_table * tt, - Genode::Translation_table_allocator * alloc); - - /** - * Continue execution of client context - * - * \param context targeted CPU context - * \param cpu kernel name of targeted CPU - * \param entry_raw raw pointer to assembly entry-code - * \param context_ptr_base base address of client-context pointer region - */ - void switch_to(Cpu::Context * const context, - unsigned const cpu, - addr_t const entry_raw, - addr_t const context_ptr_base); - - /** - * Continue execution of user context - * - * \param context targeted CPU context - * \param cpu kernel name of targeted CPU - */ - void switch_to_user(Cpu::Context * const context, - unsigned const cpu); -} __attribute__((aligned(Mode_transition_control::ALIGN))); + /** + * Continue execution of user context + * + * \param context targeted CPU context + * \param cpu kernel name of targeted CPU + */ + void switch_to_user(Cpu::Context * const context, + unsigned const cpu); +}; class Kernel::Pd : public Cpu::Pd, diff --git a/repos/base-hw/src/core/include/map_local.h b/repos/base-hw/src/core/include/map_local.h index 32b087b01..047b5be5c 100644 --- a/repos/base-hw/src/core/include/map_local.h +++ b/repos/base-hw/src/core/include/map_local.h @@ -30,8 +30,7 @@ namespace Genode { * \return true on success */ bool map_local(addr_t from_phys, addr_t to_virt, size_t num_pages, - Page_flags flags = { true, true, false, false, - false, CACHED }); + Page_flags flags = PAGE_FLAGS_KERN_DATA); /** * Unmap pages from core's address space diff --git a/repos/base-hw/src/core/include/mapping.h b/repos/base-hw/src/core/include/mapping.h index bb4d483de..87e12191c 100644 --- a/repos/base-hw/src/core/include/mapping.h +++ b/repos/base-hw/src/core/include/mapping.h @@ -14,39 +14,50 @@ #ifndef _MAPPING_H_ #define _MAPPING_H_ -#include +#include #include -namespace Genode { struct Mapping; } +namespace Genode { class Mapping; } -struct Genode::Mapping +class Genode::Mapping { - addr_t phys = 0; - addr_t virt = 0; - size_t size = 0; - Page_flags flags; + private: - Mapping() {} + Memory_region _phys { 0, 0 }; + addr_t _virt = 0; + Page_flags _flags { RO, NO_EXEC, KERN, NO_GLOBAL, RAM, CACHED }; - Mapping(addr_t virt, addr_t phys, Cache_attribute cacheable, - bool io, unsigned size_log2, bool writeable) - : phys(phys), virt(virt), size(1 << size_log2), - flags{ writeable, true, false, false, io, cacheable } {} + public: - Mapping(addr_t phys, addr_t virt, size_t size, Page_flags flags) - : phys(phys), virt(virt), size(size), flags(flags) {} + Mapping() {} - void print(Output & out) const - { - Genode::print(out, "phys=", (void*)phys, " => virt=", (void*) virt, - " (size=", Hex(size, Hex::PREFIX, Hex::PAD), - " page-flags: ", flags, ")"); - } + Mapping(addr_t phys, addr_t virt, size_t size, Page_flags flags) + : _phys(phys, size), _virt(virt), _flags(flags) {} - /** - * Dummy implementation used by generic region_map code - */ - void prepare_map_operation() {} + void print(Output & out) const + { + Genode::print(out, "physical region(", _phys, + ") => virtual address=", (void*) _virt, + " with page-flags: ", _flags, ")"); + } + + addr_t phys() const { return _phys.base; } + addr_t virt() const { return _virt; } + size_t size() const { return _phys.size; } + Page_flags flags() const { return _flags; } + + + /*********************************************** + ** Interface used by generic region_map code ** + ***********************************************/ + + Mapping(addr_t virt, addr_t phys, Cache_attribute cacheable, + bool io, unsigned size_log2, bool writeable) + : _phys(phys, 1 << size_log2), _virt(virt), + _flags { writeable ? RW : RO, EXEC, USER, NO_GLOBAL, + io ? DEVICE : RAM, cacheable } {} + + void prepare_map_operation() const {} }; #endif /* _MAPPING_H_ */ diff --git a/repos/base-hw/src/core/include/page_flags.h b/repos/base-hw/src/core/include/page_flags.h index a83377657..1eb154429 100644 --- a/repos/base-hw/src/core/include/page_flags.h +++ b/repos/base-hw/src/core/include/page_flags.h @@ -5,7 +5,7 @@ */ /* - * Copyright (C) 2014 Genode Labs GmbH + * Copyright (C) 2014-2016 Genode Labs GmbH * * This file is part of the Genode OS framework, which is distributed * under the terms of the GNU General Public License version 2. @@ -17,48 +17,55 @@ #include #include -namespace Genode { struct Page_flags; } +namespace Genode { + + enum Writeable { RO, RW }; + enum Executeable { NO_EXEC, EXEC }; + enum Privileged { USER, KERN }; + enum Global { NO_GLOBAL, GLOBAL }; + enum Type { RAM, DEVICE }; + + struct Page_flags; +} struct Genode::Page_flags { - bool writeable; - bool executable; - bool privileged; - bool global; - bool device; + Writeable writeable; + Executeable executable; + Privileged privileged; + Global global; + Type type; Cache_attribute cacheable; - /** - * Create flag POD for Genode pagers - */ - static const Page_flags - apply_mapping(bool const writeable, - Cache_attribute const cacheable, - bool const io_mem) { - return Page_flags { writeable, true, false, false, - io_mem, cacheable }; } - - /** - * Create flag POD for the mode transition region - */ - static const Page_flags mode_transition() { - return Page_flags { true, true, true, true, false, CACHED }; } - void print(Output & out) const { using Genode::print; - print(out, writeable ? "writeable, " : "readonly, ", - executable ? "exec, " : "noexec, "); - if (privileged) print(out, "privileged, "); - if (global) print(out, "global, "); - if (device) print(out, "iomem, "); + print(out, (writeable == RW) ? "writeable, " : "readonly, ", + (executable ==EXEC) ? "exec, " : "noexec, "); + if (privileged == KERN) print(out, "privileged, "); + if (global == GLOBAL) print(out, "global, "); + if (type == DEVICE) print(out, "iomem, "); switch (cacheable) { - case UNCACHED: print(out, "uncached"); break; - case CACHED: print(out, "cached"); break; - case WRITE_COMBINED: print(out, "write-combined"); break; + case UNCACHED: print(out, "uncached"); break; + case CACHED: print(out, "cached"); break; + case WRITE_COMBINED: print(out, "write-combined"); break; }; } }; + +namespace Genode { + static constexpr Page_flags PAGE_FLAGS_KERN_IO + { RW, NO_EXEC, USER, NO_GLOBAL, DEVICE, UNCACHED }; + static constexpr Page_flags PAGE_FLAGS_KERN_DATA + { RW, EXEC, USER, NO_GLOBAL, RAM, CACHED }; + static constexpr Page_flags PAGE_FLAGS_KERN_TEXT + { RW, EXEC, USER, NO_GLOBAL, RAM, CACHED }; + static constexpr Page_flags PAGE_FLAGS_KERN_EXCEP + { RW, EXEC, USER, GLOBAL, RAM, CACHED }; + static constexpr Page_flags PAGE_FLAGS_UTCB + { RW, NO_EXEC, USER, NO_GLOBAL, RAM, CACHED }; +} + #endif /* _CORE__INCLUDE__PAGE_FLAGS_H_ */ diff --git a/repos/base-hw/src/core/include/platform.h b/repos/base-hw/src/core/include/platform.h index 907242358..041eab876 100644 --- a/repos/base-hw/src/core/include/platform.h +++ b/repos/base-hw/src/core/include/platform.h @@ -25,6 +25,7 @@ #include /* core includes */ +#include #include #include #include @@ -46,6 +47,9 @@ namespace Genode { Phys_allocator _irq_alloc; /* IRQ allocator */ Rom_fs _rom_fs; /* ROM file system */ + static Genode::Bootinfo const & _bootinfo(); + static Genode::Memory_region_array const & _core_virt_regions(); + /** * Initialize I/O port allocator */ @@ -68,9 +72,10 @@ namespace Genode { public: - Platform(); + static addr_t mmio_to_virt(addr_t mmio); + /** * Return platform IRQ-number for user IRQ-number 'user_irq' */ @@ -99,23 +104,12 @@ namespace Genode { static bool get_msi_params(const addr_t mmconf, addr_t &address, addr_t &data, unsigned &irq_number); - /** - * Return address of cores translation table allocator - */ - static addr_t core_translation_tables(); - /** - * Return size of cores translation table allocator - */ - static constexpr size_t core_translation_tables_size() - { - return round_page(sizeof(Translation_table_allocator_tpl< - Translation_table::CORE_TRANS_TABLE_COUNT>)); - } + static addr_t core_phys_addr(addr_t virt); - static Genode::Memory_region_array & ram_regions(); - static Memory_region_array & core_ram_regions(); - static Genode::Memory_region_array & core_mmio_regions(); + static Translation_table * core_translation_table(); + + static Translation_table_allocator * core_translation_table_allocator(); /******************************** diff --git a/repos/base-hw/src/core/include/platform_pd.h b/repos/base-hw/src/core/include/platform_pd.h index 9ad85500d..d1770a1a2 100644 --- a/repos/base-hw/src/core/include/platform_pd.h +++ b/repos/base-hw/src/core/include/platform_pd.h @@ -211,29 +211,9 @@ class Genode::Platform_pd : public Hw::Address_space, }; -class Genode::Core_platform_pd : public Genode::Platform_pd +struct Genode::Core_platform_pd : Genode::Platform_pd { - private: - - static inline Translation_table * const _table(); - static inline Translation_table_allocator * const _table_alloc(); - - /** - * Establish initial one-to-one mappings for core/kernel. - * This function avoids to take the core-pd's translation table - * lock in contrast to normal translation insertions to - * circumvent strex/ldrex problems in early bootstrap code - * on some ARM SoCs. - * - * \param start physical/virtual start address of area - * \param size size of area - * \param io_mem true if it should be marked as device memory - */ - void _map(addr_t start, size_t size, bool io_mem); - - public: - - Core_platform_pd(); + Core_platform_pd(); }; #endif /* _CORE__INCLUDE__PLATFORM_PD_H_ */ diff --git a/repos/base-hw/src/core/include/spec/arm/cpu_support.h b/repos/base-hw/src/core/include/spec/arm/cpu_support.h index 971a838e4..9946d5501 100644 --- a/repos/base-hw/src/core/include/spec/arm/cpu_support.h +++ b/repos/base-hw/src/core/include/spec/arm/cpu_support.h @@ -169,8 +169,8 @@ class Genode::Arm { access_t v = Ba::masked((addr_t)table); Rgn::set(v, CACHEABLE); - S::set(v, Kernel::board().is_smp() ? 1 : 0); - if (Kernel::board().is_smp()) Irgn::set(v, CACHEABLE); + S::set(v, Board::SMP ? 1 : 0); + if (Board::SMP) Irgn::set(v, CACHEABLE); else C::set(v, 1); return v; } @@ -488,12 +488,27 @@ class Genode::Arm */ void clean_invalidate_data_cache(); + /** + * Invalidate all branch predictions + */ + static void invalidate_branch_predicts() { + asm volatile ("mcr p15, 0, r0, c7, c5, 6" ::: "r0"); }; + /** * Switch on MMU and caches * - * \param pd kernel's pd object + * \param table page tables physical address */ - void enable_mmu_and_caches(Kernel::Pd & pd); + void enable_mmu_and_caches(Genode::addr_t table) + { + invalidate_tlb(); + Cidr::write(0); + Dacr::write(Dacr::init_virt_kernel()); + Ttbr0::write(Ttbr0::init(table)); + Ttbcr::write(0); + Sctlr::enable_mmu_and_caches(); + invalidate_branch_predicts(); + } /** * Invalidate all TLB entries of the address space named 'pid' @@ -504,7 +519,7 @@ class Genode::Arm /** * Invalidate all TLB entries */ - void invalidate_tlb() { + static void invalidate_tlb() { asm volatile ("mcr p15, 0, %0, c8, c7, 0" :: "r" (0) : ); } static constexpr addr_t line_size = 1 << Board::CACHE_LINE_SIZE_LOG2; diff --git a/repos/base-hw/src/core/include/spec/arm/pl310.h b/repos/base-hw/src/core/include/spec/arm/pl310.h index 384180e09..23452c0c0 100644 --- a/repos/base-hw/src/core/include/spec/arm/pl310.h +++ b/repos/base-hw/src/core/include/spec/arm/pl310.h @@ -19,10 +19,7 @@ /* Genode includes */ #include -namespace Arm -{ - struct Pl310; -} +namespace Arm { struct Pl310; } /** @@ -68,7 +65,8 @@ class Arm::Pl310 : public Genode::Mmio Pl310(Genode::addr_t const base) : Mmio(base) { } - void enable() {} + void enable() {} + void disable() {} void clean_invalidate() { diff --git a/repos/base-hw/src/core/include/spec/arm/short_translation_table.h b/repos/base-hw/src/core/include/spec/arm/short_translation_table.h index 9d223e140..9c3d6e252 100644 --- a/repos/base-hw/src/core/include/spec/arm/short_translation_table.h +++ b/repos/base-hw/src/core/include/spec/arm/short_translation_table.h @@ -61,15 +61,18 @@ class Genode::Translation _create(Page_flags const & f, addr_t const pa) { typename T::access_t v = T::Pa::masked(pa); - T::S::set(v, Kernel::board().is_smp()); + T::S::set(v, Board::SMP); T::Ng::set(v, !f.global); T::Xn::set(v, !f.executable); - if (f.device) { T::Tex::set(v, _device_tex()); } - else { - switch (f.cacheable) { - case CACHED: T::Tex::set(v, 5); - case WRITE_COMBINED: T::B::set(v, 1); break; - case UNCACHED: T::Tex::set(v, 1); break; } } + if (f.type == DEVICE) { + T::Tex::set(v, _device_tex()); + } else { + switch (f.cacheable) { + case CACHED: T::Tex::set(v, 5); + case WRITE_COMBINED: T::B::set(v, 1); break; + case UNCACHED: T::Tex::set(v, 1); break; + } + } if (f.writeable) if (f.privileged) T::Ap::set(v, 1); else T::Ap::set(v, 3); else if (f.privileged) T::Ap::set(v, 5); diff --git a/repos/base-hw/src/core/include/spec/arm_gic/pic.h b/repos/base-hw/src/core/include/spec/arm_gic/pic.h index 60e90dfef..de585ff87 100644 --- a/repos/base-hw/src/core/include/spec/arm_gic/pic.h +++ b/repos/base-hw/src/core/include/spec/arm_gic/pic.h @@ -210,17 +210,7 @@ class Genode::Pic enum { NR_OF_IRQ = Distr::nr_of_irq }; - /** - * Constructor - */ - Pic() - : _distr(Board::IRQ_CONTROLLER_DISTR_BASE), - _cpui (Board::IRQ_CONTROLLER_CPU_BASE), - _last_iar(Cpui::Iar::Irq_id::bits(spurious_id)), - _max_irq(_distr.max_irq()) - { - _init(); - } + Pic(); /** * Initialize CPU local interface of the controller diff --git a/repos/base-hw/src/core/include/spec/arm_v7/cpu_support.h b/repos/base-hw/src/core/include/spec/arm_v7/cpu_support.h index 1fae98bb9..6256ca59c 100644 --- a/repos/base-hw/src/core/include/spec/arm_v7/cpu_support.h +++ b/repos/base-hw/src/core/include/spec/arm_v7/cpu_support.h @@ -119,20 +119,6 @@ class Genode::Arm_v7 : public Arm asm volatile ("mcr p15, 0, %[v], c10, c2, 0" :: [v]"r"(v) : ); } }; - /** - * Invalidate all branch predictions - */ - static void invalidate_branch_predicts() { - asm volatile ("mcr p15, 0, r0, c7, c5, 6" ::: "r0"); }; - - /** - * Switch on MMU and caches - * - * \param pd kernel's pd object - */ - void enable_mmu_and_caches(Kernel::Pd& pd); - - /** * Finish all previous data transfers */ diff --git a/repos/base-hw/src/core/include/spec/arm_v7/long_translation_table.h b/repos/base-hw/src/core/include/spec/arm_v7/long_translation_table.h index 3cb6b3143..1c6f59dd8 100644 --- a/repos/base-hw/src/core/include/spec/arm_v7/long_translation_table.h +++ b/repos/base-hw/src/core/include/spec/arm_v7/long_translation_table.h @@ -203,7 +203,9 @@ class Genode::Long_translation_table static typename Descriptor::access_t create(Page_flags const &f) { - if (f.device) { return Attribute_index::bits(DEVICE); } + if (f.type == Genode::DEVICE) + return Attribute_index::bits(DEVICE); + switch (f.cacheable) { case CACHED: return Attribute_index::bits(CACHED); case WRITE_COMBINED: diff --git a/repos/base-hw/src/core/include/spec/cortex_a15/cpu.h b/repos/base-hw/src/core/include/spec/cortex_a15/cpu.h index 4168f7b56..d274be1a1 100644 --- a/repos/base-hw/src/core/include/spec/cortex_a15/cpu.h +++ b/repos/base-hw/src/core/include/spec/cortex_a15/cpu.h @@ -16,6 +16,7 @@ #define _CORE__INCLUDE__SPEC__CORTEX_A15__CPU_H_ /* core includes */ +#include #include namespace Genode { class Cpu; } @@ -431,7 +432,22 @@ class Genode::Cpu : public Arm_v7 * Hook function called at the very beginning * of the local cpu initialization */ - void init(); + void init(Genode::Translation_table&); + + /** + * Switch on MMU and caches + * + * \param table physical page table address + */ + void enable_mmu_and_caches(Genode::addr_t table) + { + Cpu::Mair0::write(Cpu::Mair0::init_virt_kernel()); + Cpu::Dacr::write(Cpu::Dacr::init_virt_kernel()); + Cpu::Ttbr0::write(Cpu::Ttbr0::init(table, 0)); + Cpu::Ttbcr::write(Cpu::Ttbcr::init_virt_kernel()); + Cpu::Sctlr::enable_mmu_and_caches(); + invalidate_branch_predicts(); + } /************* diff --git a/repos/base-hw/src/core/include/spec/cortex_a9/board_support.h b/repos/base-hw/src/core/include/spec/cortex_a9/board_support.h index 6718cbe24..8ecd353fc 100644 --- a/repos/base-hw/src/core/include/spec/cortex_a9/board_support.h +++ b/repos/base-hw/src/core/include/spec/cortex_a9/board_support.h @@ -18,23 +18,15 @@ #include #include -namespace Cortex_a9 -{ - /** - * Board driver - */ - class Board; -} +namespace Cortex_a9 { class Board; } class Cortex_a9::Board : public Genode::Board_base { - protected: + public: using L2_cache = Arm::Pl310; - L2_cache _l2_cache; - - public: + static constexpr bool SMP = true; enum Errata { ARM_754322, @@ -61,14 +53,17 @@ class Cortex_a9::Board : public Genode::Board_base PRIVATE_TIMER_IRQ = 29, }; - Board() : _l2_cache(Genode::Board_base::PL310_MMIO_BASE) {} + Board(); L2_cache & l2_cache() { return _l2_cache; } void init() { } void wake_up_all_cpus(void * const ip); - bool is_smp() { return true; } bool errata(Errata); + + protected: + + L2_cache _l2_cache; }; #endif /* _CORE__INCLUDE__SPEC__CORTEX_A9__BOARD_SUPPORT_H_ */ diff --git a/repos/base-hw/src/core/include/spec/cortex_a9/cpu_support.h b/repos/base-hw/src/core/include/spec/cortex_a9/cpu_support.h index 2ff8d6913..6a1d6b5b4 100644 --- a/repos/base-hw/src/core/include/spec/cortex_a9/cpu_support.h +++ b/repos/base-hw/src/core/include/spec/cortex_a9/cpu_support.h @@ -74,7 +74,7 @@ class Genode::Cortex_a9 : public Arm_v7 static void write(access_t const v) { asm volatile ("mcr p15, 0, %0, c1, c0, 1" :: "r" (v) : ); } - static void enable_smp() + static void enable_smp(Board&) { access_t v = read(); Smp::set(v, 1); diff --git a/repos/base-hw/src/core/include/spec/cortex_a9/scu.h b/repos/base-hw/src/core/include/spec/cortex_a9/scu.h index 13d9cc3e8..f64b6822e 100644 --- a/repos/base-hw/src/core/include/spec/cortex_a9/scu.h +++ b/repos/base-hw/src/core/include/spec/cortex_a9/scu.h @@ -18,54 +18,47 @@ /* local includes */ #include -namespace Genode { - class Scu; -} +namespace Genode { struct Scu; } -class Genode::Scu : Genode::Mmio + +struct Genode::Scu : Genode::Mmio { - private: + struct Cr : Register<0x0, 32> + { + struct Enable : Bitfield<0, 1> { }; + }; - struct Cr : Register<0x0, 32> - { - struct Enable : Bitfield<0, 1> { }; - }; + struct Dcr : Register<0x30, 32> + { + struct Bit_0 : Bitfield<0, 1> { }; + }; - struct Dcr : Register<0x30, 32> - { - struct Bit_0 : Bitfield<0, 1> { }; - }; + struct Iassr : Register<0xc, 32> + { + struct Cpu0_way : Bitfield<0, 4> { }; + struct Cpu1_way : Bitfield<4, 4> { }; + struct Cpu2_way : Bitfield<8, 4> { }; + struct Cpu3_way : Bitfield<12, 4> { }; + }; - struct Iassr : Register<0xc, 32> - { - struct Cpu0_way : Bitfield<0, 4> { }; - struct Cpu1_way : Bitfield<4, 4> { }; - struct Cpu2_way : Bitfield<8, 4> { }; - struct Cpu3_way : Bitfield<12, 4> { }; - }; + Scu() : Mmio(Board::SCU_MMIO_BASE) { } - Board &_board; - - public: - - Scu(Board & board) : Mmio(Board::SCU_MMIO_BASE), _board(board) { } - - void invalidate() - { - Iassr::access_t iassr = 0; - for (Iassr::access_t way = 0; way <= Iassr::Cpu0_way::mask(); - way++) { - Iassr::Cpu0_way::set(iassr, way); - Iassr::Cpu1_way::set(iassr, way); - Iassr::Cpu2_way::set(iassr, way); - Iassr::Cpu3_way::set(iassr, way); - write(iassr); - } + void invalidate() + { + Iassr::access_t iassr = 0; + for (Iassr::access_t way = 0; way <= Iassr::Cpu0_way::mask(); + way++) { + Iassr::Cpu0_way::set(iassr, way); + Iassr::Cpu1_way::set(iassr, way); + Iassr::Cpu2_way::set(iassr, way); + Iassr::Cpu3_way::set(iassr, way); + write(iassr); } + } - void enable() - { - if (_board.errata(Board::ARM_764369)) write(1); - write(1); - } + void enable(Board & board) + { + if (board.errata(Board::ARM_764369)) write(1); + write(1); + } }; diff --git a/repos/base-hw/src/core/include/spec/cortex_a9/timer.h b/repos/base-hw/src/core/include/spec/cortex_a9/timer.h index b217978fe..da7e3f30f 100644 --- a/repos/base-hw/src/core/include/spec/cortex_a9/timer.h +++ b/repos/base-hw/src/core/include/spec/cortex_a9/timer.h @@ -70,13 +70,7 @@ class Genode::Timer : public Mmio public: - /** - * Constructor - */ - Timer() : Mmio(Board::PRIVATE_TIMER_MMIO_BASE) - { - write(0); - } + Timer(); /** * Return kernel name of timer interrupt @@ -89,21 +83,7 @@ class Genode::Timer : public Mmio * * \param tics delay of timer interrupt */ - void start_one_shot(time_t const tics, unsigned const) - { - enum { PRESCALER = Board::CORTEX_A9_PRIVATE_TIMER_DIV - 1 }; - - /* reset timer */ - write(1); - Control::access_t control = 0; - Control::Irq_enable::set(control, 1); - Control::Prescaler::set(control, PRESCALER); - write(control); - - /* load timer and start decrementing */ - write(tics); - write(1); - } + void start_one_shot(time_t const tics, unsigned const); time_t tics_to_us(time_t const tics) const { return (tics / TICS_PER_MS) * 1000; } @@ -119,6 +99,6 @@ class Genode::Timer : public Mmio time_t max_value() { return (Load::access_t)~0; } }; -namespace Kernel { class Timer : public Genode::Timer { }; } +namespace Kernel { using Genode::Timer; } #endif /* _CORE__INCLUDE__SPEC__CORTEX_A9__TIMER_H_ */ diff --git a/repos/base-hw/src/core/include/spec/exynos5/board.h b/repos/base-hw/src/core/include/spec/exynos5/board.h index 0b34428b7..d4a9df79e 100644 --- a/repos/base-hw/src/core/include/spec/exynos5/board.h +++ b/repos/base-hw/src/core/include/spec/exynos5/board.h @@ -36,7 +36,7 @@ namespace Genode "sev\n"); } - static bool is_smp() { return true; } + static constexpr bool SMP = true; }; } diff --git a/repos/base-hw/src/core/include/spec/exynos5/serial.h b/repos/base-hw/src/core/include/spec/exynos5/serial.h index c66047904..ba1e1fe3f 100644 --- a/repos/base-hw/src/core/include/spec/exynos5/serial.h +++ b/repos/base-hw/src/core/include/spec/exynos5/serial.h @@ -17,6 +17,7 @@ /* core includes */ #include +#include /* Genode includes */ #include @@ -37,7 +38,7 @@ namespace Genode */ Serial(unsigned const baud_rate) : - Exynos_uart_base(Board::UART_2_MMIO_BASE, + Exynos_uart_base(Platform::mmio_to_virt(Board::UART_2_MMIO_BASE), Board::UART_2_CLOCK, baud_rate) { } }; diff --git a/repos/base-hw/src/core/include/spec/exynos5/timer.h b/repos/base-hw/src/core/include/spec/exynos5/timer.h index 7527989d0..f0de347c6 100644 --- a/repos/base-hw/src/core/include/spec/exynos5/timer.h +++ b/repos/base-hw/src/core/include/spec/exynos5/timer.h @@ -19,6 +19,7 @@ /* core include */ #include +#include /* Genode includes */ #include @@ -207,7 +208,7 @@ class Genode::Timer : public Mmio */ Timer() : - Mmio(Board::MCT_MMIO_BASE), + Mmio(Platform::mmio_to_virt(Board::MCT_MMIO_BASE)), _tics_per_ms(_calc_tics_per_ms(Board::MCT_CLOCK)) { Mct_cfg::access_t mct_cfg = 0; diff --git a/repos/base-hw/src/core/include/spec/imx/serial.h b/repos/base-hw/src/core/include/spec/imx/serial.h index c3efc7f5b..69de63393 100644 --- a/repos/base-hw/src/core/include/spec/imx/serial.h +++ b/repos/base-hw/src/core/include/spec/imx/serial.h @@ -16,6 +16,7 @@ /* core includes */ #include +#include /* Genode includes */ #include @@ -34,7 +35,8 @@ namespace Genode * * XXX: The 'baud_rate' argument is ignored for now. */ - Serial(unsigned) : Imx_uart_base(Board::UART_1_MMIO_BASE) { } + Serial(unsigned) + : Imx_uart_base(Platform::mmio_to_virt(Board::UART_1_MMIO_BASE)) { } }; } diff --git a/repos/base-hw/src/core/include/spec/imx53/board.h b/repos/base-hw/src/core/include/spec/imx53/board.h index 3bd5b5cdc..60f843167 100644 --- a/repos/base-hw/src/core/include/spec/imx53/board.h +++ b/repos/base-hw/src/core/include/spec/imx53/board.h @@ -18,17 +18,8 @@ /* core includes */ #include -namespace Genode -{ - /** - * Board driver - */ - class Board : public Imx::Board - { - public: +namespace Genode { struct Board; } - bool is_smp() { return false; } - }; -} +struct Genode::Board : Imx::Board { static constexpr bool SMP = false; }; #endif /* _CORE__INCLUDE__SPEC__IMX53__BOARD_H_ */ diff --git a/repos/base-hw/src/core/include/spec/imx53/pic.h b/repos/base-hw/src/core/include/spec/imx53/pic.h index c2c60a90c..38c48d90e 100644 --- a/repos/base-hw/src/core/include/spec/imx53/pic.h +++ b/repos/base-hw/src/core/include/spec/imx53/pic.h @@ -20,13 +20,8 @@ /* core includes */ #include -namespace Genode -{ - /** - * Programmable interrupt controller for core - */ - class Pic; -} +namespace Genode { class Pic; } + class Genode::Pic : public Mmio { @@ -101,10 +96,9 @@ class Genode::Pic : public Mmio public: - /** - * Constructor - */ - Pic() : Mmio(Board::IRQ_CONTROLLER_BASE) + Pic(); + + void init_cpu_local() { for (unsigned i = 0; i < NR_OF_IRQ; i++) { write(1, i); @@ -172,10 +166,9 @@ class Genode::Pic : public Mmio *************/ void trigger_ip_interrupt(unsigned) { } - void init_cpu_local() { } void finish_request() { } }; -namespace Kernel { class Pic : public Genode::Pic { }; } +namespace Kernel { using Pic = Genode::Pic; } #endif /* _CORE__INCLUDE__SPEC__IMX53__PIC_H_ */ diff --git a/repos/base-hw/src/core/include/spec/imx53/timer.h b/repos/base-hw/src/core/include/spec/imx53/timer.h index d30663fca..3a8885e70 100644 --- a/repos/base-hw/src/core/include/spec/imx53/timer.h +++ b/repos/base-hw/src/core/include/spec/imx53/timer.h @@ -22,6 +22,7 @@ /* core includes */ #include +#include namespace Genode { class Timer; } @@ -135,10 +136,7 @@ class Genode::Timer : public Mmio return Board::EPIT_1_IRQ; } - /** - * Constructor - */ - Timer() : Mmio(Board::EPIT_1_MMIO_BASE) { } + Timer() : Mmio(Platform::mmio_to_virt(Board::EPIT_1_MMIO_BASE)) { } /** * Start single timeout run @@ -174,6 +172,6 @@ class Genode::Timer : public Mmio return read() ? 0 : read(); } }; -namespace Kernel { class Timer : public Genode::Timer { }; } +namespace Kernel { using Timer = Genode::Timer; } #endif /* _CORE__INCLUDE__SPEC__IMX53__TIMER_H_ */ diff --git a/repos/base-hw/src/core/include/spec/imx53/trustzone/csu.h b/repos/base-hw/src/core/include/spec/imx53/trustzone/csu.h index 62c6340b2..4c8f12dfd 100644 --- a/repos/base-hw/src/core/include/spec/imx53/trustzone/csu.h +++ b/repos/base-hw/src/core/include/spec/imx53/trustzone/csu.h @@ -101,7 +101,7 @@ namespace Genode { typedef Csl<0x78> Csl30; typedef Csl<0x7c> Csl31; - Csu(addr_t const base) : Mmio(base) + Csu(addr_t const base) : Mmio(Platform::mmio_to_virt(base)) { /* Power (CCM, SRC, DPLLIP1-4, GPC and OWIRE) */ write(Csl00::UNSECURE); diff --git a/repos/base-hw/src/core/include/spec/panda/board.h b/repos/base-hw/src/core/include/spec/panda/board.h index 11bf43002..62abe11e0 100644 --- a/repos/base-hw/src/core/include/spec/panda/board.h +++ b/repos/base-hw/src/core/include/spec/panda/board.h @@ -19,15 +19,9 @@ #include #include -namespace Genode -{ - class Board; -} +namespace Genode { class Board; } -/** - * Board driver for core - */ class Genode::Board : public Cortex_a9::Board { public: @@ -35,7 +29,7 @@ class Genode::Board : public Cortex_a9::Board using Base = Cortex_a9::Board; /** - * Frontend to monitor firmware running in the secure world + * Frontend to firmware running in the secure world */ struct Secure_monitor { @@ -63,7 +57,7 @@ class Genode::Board : public Cortex_a9::Board { private: - Secure_monitor & _monitor; + Secure_monitor _monitor; unsigned long _init_value() { @@ -90,9 +84,7 @@ class Genode::Board : public Cortex_a9::Board public: - L2_cache(Secure_monitor & monitor) - : Base::L2_cache(Genode::Board_base::PL310_MMIO_BASE), - _monitor(monitor) + L2_cache(Genode::addr_t mmio) : Base::L2_cache(mmio) { _monitor.call(Secure_monitor::L2_CACHE_AUX_REG, _init_value()); @@ -118,17 +110,11 @@ class Genode::Board : public Cortex_a9::Board _monitor.call(Secure_monitor::L2_CACHE_ENABLE_REG, 0); } }; + L2_cache & l2_cache() { return _l2_cache; } + private: - Secure_monitor _monitor; - L2_cache _l2_cache; - - public: - - Board() : _l2_cache(_monitor) { _l2_cache.disable(); } - - L2_cache & l2_cache() { return _l2_cache; } - Secure_monitor & monitor() { return _monitor; } + L2_cache _l2_cache { Base::l2_cache().base }; }; #endif /* _CORE__INCLUDE__SPEC__PANDA__BOARD_H_ */ diff --git a/repos/base-hw/src/core/include/spec/panda/cpu.h b/repos/base-hw/src/core/include/spec/panda/cpu.h index 91003f7d6..89675ae0b 100644 --- a/repos/base-hw/src/core/include/spec/panda/cpu.h +++ b/repos/base-hw/src/core/include/spec/panda/cpu.h @@ -17,11 +17,7 @@ /* core includes */ #include -namespace Genode -{ - class Cpu; -} - +namespace Genode { class Cpu; } /** * Override the Cortex A9 Cpu driver, because some registers can be accessed @@ -33,7 +29,7 @@ class Genode::Cpu : public Genode::Cortex_a9 struct Actlr : Cortex_a9::Actlr { - static void enable_smp(); + static void enable_smp(Board&); }; }; diff --git a/repos/base-hw/src/core/include/spec/pl011/serial.h b/repos/base-hw/src/core/include/spec/pl011/serial.h index b35e56422..05af7f661 100644 --- a/repos/base-hw/src/core/include/spec/pl011/serial.h +++ b/repos/base-hw/src/core/include/spec/pl011/serial.h @@ -16,30 +16,28 @@ /* core includes */ #include +#include /* Genode includes */ #include -namespace Genode -{ - /** - * Serial output driver for core - */ - class Serial : public Pl011_base - { - public: +namespace Genode { class Serial; } - /** - * Constructor - * - * \param baud_rate targeted transfer baud-rate - */ - Serial(unsigned const baud_rate) - : - Pl011_base(Board::PL011_0_MMIO_BASE, - Board::PL011_0_CLOCK, baud_rate) - { } - }; -} + +class Genode::Serial : public Pl011_base +{ + public: + + /** + * Constructor + * + * \param baud_rate targeted transfer baud-rate + */ + Serial(unsigned const baud_rate) + : + Pl011_base(Platform::mmio_to_virt(Board::PL011_0_MMIO_BASE), + Board::PL011_0_CLOCK, baud_rate) + { } +}; #endif /* _CORE__INCLUDE__SPEC__PL011__SERIAL_H_ */ diff --git a/repos/base-hw/src/core/include/spec/rpi/board.h b/repos/base-hw/src/core/include/spec/rpi/board.h index e47c0d84d..3085f7255 100644 --- a/repos/base-hw/src/core/include/spec/rpi/board.h +++ b/repos/base-hw/src/core/include/spec/rpi/board.h @@ -18,16 +18,13 @@ /* core includes */ #include -namespace Genode +namespace Genode { struct Board; } + +struct Genode::Board : Board_base { - class Board : public Board_base - { - public: + void init() { } - void init() { } - - static bool is_smp() { return false; } - }; -} + static constexpr bool SMP = false; +}; #endif /* _CORE__INCLUDE__BOARD_H_ */ diff --git a/repos/base-hw/src/core/include/spec/rpi/pic.h b/repos/base-hw/src/core/include/spec/rpi/pic.h index b094297c6..a58bc2134 100644 --- a/repos/base-hw/src/core/include/spec/rpi/pic.h +++ b/repos/base-hw/src/core/include/spec/rpi/pic.h @@ -15,7 +15,6 @@ #define _CORE__INCLUDE__SPEC__RPI__PIC_H_ /* Genode includes */ -#include #include /* core includes */ @@ -67,55 +66,13 @@ class Genode::Usb_dwc_otg : Mmio } static bool _need_trigger_sof(uint32_t host_frame, - uint32_t scheduled_frame) - { - uint32_t const max_frame = 0x3fff; - - if (host_frame < scheduled_frame) { - if (scheduled_frame - host_frame < max_frame / 2) - return false; /* scheduled frame not reached yet */ - else - return true; /* scheduled frame passed, host frame wrapped */ - } else { - if (host_frame - scheduled_frame < max_frame / 2) - return true; /* scheduled frame passed */ - else - return false; /* scheduled frame wrapped, not reached */ - } - } + uint32_t scheduled_frame); public: - Usb_dwc_otg() : Mmio(Board::USB_DWC_OTG_BASE) - { - write(0); - write(false); - write(false); - } + Usb_dwc_otg(); - bool handle_sof() - { - if (!_is_sof()) - return false; - - static int cnt = 0; - - if (++cnt == 8*20) { - cnt = 0; - return false; - } - - if (!read() || read()) - return false; - - if (_need_trigger_sof(read(), - read())) - return false; - - write(1); - - return true; - } + bool handle_sof(); }; @@ -162,76 +119,16 @@ class Genode::Pic : Mmio public: - /** - * Constructor - */ - Pic() : Mmio(Board::IRQ_CONTROLLER_BASE) { mask(); } + Pic(); void init_cpu_local() { } - - bool take_request(unsigned &irq) - { - /* read basic IRQ status mask */ - uint32_t const p = read(); - - - /* read GPU IRQ status mask */ - uint32_t const p1 = read(), - p2 = read(); - - if (Irq_pending_basic::Timer::get(p)) { - irq = Irq_pending_basic::Timer::SHIFT; - return true; - } - - /* search for lowest set bit in pending masks */ - for (unsigned i = 0; i < NR_OF_IRQ; i++) { - if (!_is_pending(i, p1, p2)) - continue; - - irq = Board_base::GPU_IRQ_BASE + i; - - /* handle SOF interrupts locally, filter from the user land */ - if (irq == Board_base::DWC_IRQ) - if (_usb.handle_sof()) - return false; - - return true; - } - - return false; - } - + bool take_request(unsigned &irq); void finish_request() { } - - void mask() - { - write(~0); - write(~0); - write(~0); - } - - void unmask(unsigned const i, unsigned) - { - if (i < 8) - write(1 << i); - else if (i < 32 + 8) - write(1 << (i - 8)); - else - write(1 << (i - 8 - 32)); - } - - void mask(unsigned const i) - { - if (i < 8) - write(1 << i); - else if (i < 32 + 8) - write(1 << (i - 8)); - else - write(1 << (i - 8 - 32)); - } + void mask(); + void unmask(unsigned const i, unsigned); + void mask(unsigned const i); }; -namespace Kernel { class Pic : public Genode::Pic { }; } +namespace Kernel { using Genode::Pic; } #endif /* _CORE__INCLUDE__SPEC__RPI__PIC_H_ */ diff --git a/repos/base-hw/src/core/include/spec/rpi/timer.h b/repos/base-hw/src/core/include/spec/rpi/timer.h index 68cfc42e5..0c1a7f495 100644 --- a/repos/base-hw/src/core/include/spec/rpi/timer.h +++ b/repos/base-hw/src/core/include/spec/rpi/timer.h @@ -44,35 +44,18 @@ class Genode::Timer : public Mmio public: - Timer() : Mmio(Board::SYSTEM_TIMER_MMIO_BASE) { } + Timer(); static unsigned interrupt_id(unsigned const) { return Board::SYSTEM_TIMER_IRQ; } - void start_one_shot(time_t const tics, unsigned const) - { - write(1); - read(); - write(0); - write(read() + tics); - } - - time_t tics_to_us(time_t const tics) const { - return (tics / TICS_PER_MS) * 1000; } - - time_t us_to_tics(time_t const us) const { - return (us / 1000) * TICS_PER_MS; } - - time_t max_value() { return (Clo::access_t)~0; } - - time_t value(unsigned const) - { - Cmp::access_t const cmp = read(); - Clo::access_t const clo = read(); - return cmp > clo ? cmp - clo : 0; - } + void start_one_shot(time_t const tics, unsigned const); + time_t tics_to_us(time_t const tics) const; + time_t us_to_tics(time_t const us) const; + time_t max_value(); + time_t value(unsigned const); }; -namespace Kernel { class Timer : public Genode::Timer { }; } +namespace Kernel { using Genode::Timer; } #endif /* _CORE__INCLUDE__SPEC__RPI__TIMER_H_ */ diff --git a/repos/base-hw/src/core/include/spec/tl16c750/serial.h b/repos/base-hw/src/core/include/spec/tl16c750/serial.h index ecc572ff8..27eba959a 100644 --- a/repos/base-hw/src/core/include/spec/tl16c750/serial.h +++ b/repos/base-hw/src/core/include/spec/tl16c750/serial.h @@ -16,6 +16,7 @@ /* core includes */ #include +#include /* Genode includes */ #include @@ -36,7 +37,7 @@ namespace Genode */ Serial(unsigned const baud_rate) : - Tl16c750_base(Board::TL16C750_3_MMIO_BASE, + Tl16c750_base(Platform::mmio_to_virt(Board::TL16C750_3_MMIO_BASE), Board::TL16C750_CLOCK, baud_rate) { } }; diff --git a/repos/base-hw/src/core/include/spec/x86_64/cpu.h b/repos/base-hw/src/core/include/spec/x86_64/cpu.h index e1490fe47..7e2c71300 100644 --- a/repos/base-hw/src/core/include/spec/x86_64/cpu.h +++ b/repos/base-hw/src/core/include/spec/x86_64/cpu.h @@ -27,7 +27,6 @@ /* core includes */ #include -#include namespace Genode { class Cpu; diff --git a/repos/base-hw/src/core/include/spec/x86_64/macros.s b/repos/base-hw/src/core/include/spec/x86_64/macros.s index 88adf1ab0..4e220204c 100644 --- a/repos/base-hw/src/core/include/spec/x86_64/macros.s +++ b/repos/base-hw/src/core/include/spec/x86_64/macros.s @@ -1,6 +1,7 @@ /* * \brief Macros that are used by multiple assembly files * \author Martin Stein + * \author Stefan Kalkowski * \date 2014-01-13 */ @@ -19,3 +20,51 @@ /* alignment constraints */ .set MIN_PAGE_SIZE_LOG2, 12 .set DATA_ACCESS_ALIGNM_LOG2, 2 + + +/****************************************** + ** Global Descriptor Table (GDT) ** + ** See Intel SDM Vol. 3A, section 3.5.1 ** + ******************************************/ + +.macro _define_gdt tss_address + .align 4 + .space 2 + .global _mt_gdt_ptr + .global _mt_gdt_start + _mt_gdt_ptr: + .word _mt_gdt_end - _mt_gdt_start - 1 /* limit */ + .long _mt_gdt_start /* base address */ + + .set TSS_LIMIT, 0x68 + .set TSS_TYPE, 0x8900 + + .align 8 + _mt_gdt_start: + /* Null descriptor */ + .quad 0 + /* 64-bit code segment descriptor */ + .long 0 + /* GDTE_LONG | GDTE_PRESENT | GDTE_CODE | GDTE_NON_SYSTEM */ + .long 0x209800 + /* 64-bit data segment descriptor */ + .long 0 + /* GDTE_LONG | GDTE_PRESENT | GDTE_TYPE_DATA_A | GDTE_TYPE_DATA_W | GDTE_NON_SYSTEM */ + .long 0x209300 + /* 64-bit user code segment descriptor */ + .long 0 + /* GDTE_LONG | GDTE_PRESENT | GDTE_CODE | GDTE_NON_SYSTEM */ + .long 0x20f800 + /* 64-bit user data segment descriptor */ + .long 0 + /* GDTE_LONG | GDTE_PRESENT | GDTE_TYPE_DATA_A | GDTE_TYPE_DATA_W | GDTE_NON_SYSTEM */ + .long 0x20f300 + /* Task segment descriptor */ + .long (\tss_address & 0xffff) << 16 | TSS_LIMIT + /* GDTE_PRESENT | GDTE_SYS_TSS */ + .long ((\tss_address >> 24) & 0xff) << 24 | ((\tss_address >> 16) & 0xff) | TSS_TYPE + .long \tss_address >> 32 + .long 0 + .global _mt_gdt_end + _mt_gdt_end: +.endm diff --git a/repos/base-hw/src/core/include/spec/x86_64/muen/sinfo_instance.h b/repos/base-hw/src/core/include/spec/x86_64/muen/sinfo_instance.h index 359409318..79302205c 100644 --- a/repos/base-hw/src/core/include/spec/x86_64/muen/sinfo_instance.h +++ b/repos/base-hw/src/core/include/spec/x86_64/muen/sinfo_instance.h @@ -16,6 +16,7 @@ /* base includes */ #include +#include namespace Genode { @@ -23,7 +24,7 @@ namespace Genode * Return sinfo singleton */ static Sinfo * sinfo() { - static Sinfo singleton(Sinfo::PHYSICAL_BASE_ADDR); + static Sinfo singleton(Platform::mmio_to_virt(Sinfo::PHYSICAL_BASE_ADDR)); return &singleton; } } diff --git a/repos/base-hw/src/core/include/spec/x86_64/muen/timer.h b/repos/base-hw/src/core/include/spec/x86_64/muen/timer.h index bf38e967a..08f3a742b 100644 --- a/repos/base-hw/src/core/include/spec/x86_64/muen/timer.h +++ b/repos/base-hw/src/core/include/spec/x86_64/muen/timer.h @@ -74,7 +74,7 @@ class Genode::Timer throw Invalid_region(); } - _event_page = (Subject_timed_event *)region.address; + _event_page = (Subject_timed_event *)Platform::mmio_to_virt(region.address); _event_page->event_nr = Board::TIMER_EVENT_KERNEL; log("muen-timer: Page @", Hex(region.address), ", " "frequency ", _tics_per_ms, " kHz, " @@ -83,7 +83,7 @@ class Genode::Timer if (sinfo()->get_memregion_info("monitor_timed_event", ®ion)) { log("muen-timer: Found guest timed event page @", Hex(region.address), " -> enabling preemption"); - _guest_event_page = (Subject_timed_event *)region.address; + _guest_event_page = (Subject_timed_event *)Platform::mmio_to_virt(region.address); _guest_event_page->event_nr = Board::TIMER_EVENT_PREEMPT; } } diff --git a/repos/base-hw/src/core/include/spec/x86_64/pic.h b/repos/base-hw/src/core/include/spec/x86_64/pic.h index 0e991ce39..6a7eb8529 100644 --- a/repos/base-hw/src/core/include/spec/x86_64/pic.h +++ b/repos/base-hw/src/core/include/spec/x86_64/pic.h @@ -96,59 +96,16 @@ class Genode::Ioapic : public Mmio * 32 bits so only the necessary half of the IRT entry is * updated. */ - void _update_irt_entry(unsigned irq) - { - Irte::access_t irte; - - write(IOREDTBL + 2 * irq); - irte = read(); - - Irte::Pol::set(irte, _irq_mode[irq].polarity); - Irte::Trg::set(irte, _irq_mode[irq].trigger_mode); - - write(IOREDTBL + 2 * irq); - write(irte); - } + void _update_irt_entry(unsigned irq); /** * Create redirection table entry for given IRQ */ - Irte::access_t _create_irt_entry(unsigned const irq) - { - Irte::access_t irte = REMAP_BASE + irq; - Irte::Mask::set(irte, 1); - - Irte::Pol::set(irte, _irq_mode[irq].polarity); - Irte::Trg::set(irte, _irq_mode[irq].trigger_mode); - - return irte; - } + Irte::access_t _create_irt_entry(unsigned const irq); public: - Ioapic() : Mmio(Board::MMIO_IOAPIC_BASE) - { - for (unsigned i = 0; i < IRQ_COUNT; i++) - { - /* set legacy/ISA IRQs to edge, high */ - if (i <= Board::ISA_IRQ_END) { - _irq_mode[i].trigger_mode = TRIGGER_EDGE; - _irq_mode[i].polarity = POLARITY_HIGH; - } else { - _irq_mode[i].trigger_mode = TRIGGER_LEVEL; - _irq_mode[i].polarity = POLARITY_LOW; - } - - /* remap all IRQs managed by I/O APIC */ - if (i < IRTE_COUNT) { - Irte::access_t irte = _create_irt_entry(i); - write(IOREDTBL + 2 * i + 1); - write(irte >> Iowin::ACCESS_WIDTH); - write(IOREDTBL + 2 * i); - write(irte); - } - } - }; + Ioapic(); /** * Set/unset mask bit of IRTE for given vector @@ -156,32 +113,7 @@ class Genode::Ioapic : public Mmio * \param vector targeted vector * \param set whether to set or to unset the mask bit */ - void toggle_mask(unsigned const vector, bool const set) - { - /* - * Ignore toggle requests for vectors not handled by the I/O APIC. - */ - if (vector < REMAP_BASE || vector >= REMAP_BASE + IRTE_COUNT) { - return; - } - - const unsigned irq = vector - REMAP_BASE; - - /* - * Only mask existing RTEs and do *not* mask edge-triggered - * interrupts to avoid losing them while masked, see Intel - * 82093AA I/O Advanced Programmable Interrupt Controller - * (IOAPIC) specification, section 3.4.2, "Interrupt Mask" - * flag and edge-triggered interrupts or: - * http://yarchive.net/comp/linux/edge_triggered_interrupts.html - */ - if (_edge_triggered(irq) && set) { return; } - - write(IOREDTBL + (2 * irq)); - Irte::access_t irte = read(); - Irte::Mask::set(irte, set); - write(irte); - } + void toggle_mask(unsigned const vector, bool const set); /** * Setup mode of an IRQ to specified trigger mode and polarity @@ -228,19 +160,7 @@ class Genode::Pic : public Mmio * \return index of first ISR bit set starting at index one, zero if no * bit is set. */ - inline unsigned get_lowest_bit(void) - { - unsigned bit, vec_base = 0; - - for (unsigned i = 0; i < 8 * 4; i += 4) { - bit = __builtin_ffs(read(i)); - if (bit) { - return vec_base + bit; - } - vec_base += 32; - } - return 0; - } + inline unsigned get_lowest_bit(void); public: @@ -277,6 +197,6 @@ class Genode::Pic : public Mmio void trigger_ip_interrupt(unsigned) { } }; -namespace Kernel { class Pic : public Genode::Pic { }; } +namespace Kernel { using Genode::Pic; } #endif /* _CORE__INCLUDE__SPEC__X86_64__PIC_H_ */ diff --git a/repos/base-hw/src/core/include/spec/x86_64/timer.h b/repos/base-hw/src/core/include/spec/x86_64/timer.h index 3a35c79a2..f8426fa76 100644 --- a/repos/base-hw/src/core/include/spec/x86_64/timer.h +++ b/repos/base-hw/src/core/include/spec/x86_64/timer.h @@ -73,77 +73,28 @@ class Genode::Timer : public Mmio uint32_t _tics_per_ms = 0; /* Measure LAPIC timer frequency using PIT channel 2 */ - uint32_t _pit_calc_timer_freq(void) - { - uint32_t t_start, t_end; - - /* Set channel gate high and disable speaker */ - outb(PIT_CH2_GATE, (inb(0x61) & ~0x02) | 0x01); - - /* Set timer counter (mode 0, binary count) */ - outb(PIT_MODE, 0xb0); - outb(PIT_CH2_DATA, PIT_SLEEP_TICS & 0xff); - outb(PIT_CH2_DATA, PIT_SLEEP_TICS >> 8); - - write(~0U); - - t_start = read(); - while ((inb(PIT_CH2_GATE) & 0x20) == 0) - { - asm volatile("pause" : : : "memory"); - } - t_end = read(); - - write(0); - - return (t_start - t_end) / PIT_SLEEP_MS; - } + uint32_t _pit_calc_timer_freq(void); public: - Timer() : Mmio(Board::MMIO_LAPIC_BASE) - { - write( - Divide_configuration::Divide_value::MAX); - - /* Enable LAPIC timer in one-shot mode */ - write(Board::TIMER_VECTOR_KERNEL); - write(0); - write(0); - write(0); - - /* Calculate timer frequency */ - _tics_per_ms = _pit_calc_timer_freq(); - } + Timer(); /** * Disable PIT timer channel. This is necessary since BIOS sets up * channel 0 to fire periodically. */ - static void disable_pit() - { - outb(PIT_MODE, 0x30); - outb(PIT_CH0_DATA, 0); - outb(PIT_CH0_DATA, 0); - } + static void disable_pit(); static unsigned interrupt_id(unsigned const) { return Board::TIMER_VECTOR_KERNEL; } - void start_one_shot(time_t const tics, unsigned const) { - write(tics); } - - time_t tics_to_us(time_t const tics) const { - return (tics / _tics_per_ms) * 1000; } - - time_t us_to_tics(time_t const us) const { - return (us / 1000) * _tics_per_ms; } - - time_t max_value() { return (Tmr_initial::access_t)~0; } - - time_t value(unsigned const) { return read(); } + void start_one_shot(time_t const tics, unsigned const); + time_t tics_to_us(time_t const tics) const; + time_t us_to_tics(time_t const us) const; + time_t max_value(); + time_t value(unsigned const); }; -namespace Kernel { class Timer : public Genode::Timer { }; } +namespace Kernel { using Genode::Timer; } #endif /* _CORE__INCLUDE__SPEC__X86_64__TIMER_H_ */ diff --git a/repos/base-hw/src/core/include/spec/xilinx_uartps_0/serial.h b/repos/base-hw/src/core/include/spec/xilinx_uartps_0/serial.h index 9172c5d62..524d1d7e6 100644 --- a/repos/base-hw/src/core/include/spec/xilinx_uartps_0/serial.h +++ b/repos/base-hw/src/core/include/spec/xilinx_uartps_0/serial.h @@ -16,6 +16,7 @@ /* core includes */ #include +#include /* Genode includes */ #include @@ -36,7 +37,7 @@ class Genode::Serial : public Xilinx_uartps_base */ Serial(unsigned const baud_rate) : - Xilinx_uartps_base(Board::UART_0_MMIO_BASE, + Xilinx_uartps_base(Platform::mmio_to_virt(Board::UART_0_MMIO_BASE), Board::UART_CLOCK, baud_rate) { } }; diff --git a/repos/base-hw/src/core/kernel/cpu.cc b/repos/base-hw/src/core/kernel/cpu.cc index 7d5873de4..9f158052f 100644 --- a/repos/base-hw/src/core/kernel/cpu.cc +++ b/repos/base-hw/src/core/kernel/cpu.cc @@ -243,6 +243,7 @@ Cpu_domain_update::Cpu_domain_update() { *****************/ /** + * FIXME THIS IS ONLY USED BY IDLE THREAD * Enable kernel-entry assembly to get an exclusive stack for every CPU * * The stack alignment is determined as follows: @@ -264,7 +265,6 @@ Cpu_context::Cpu_context(Genode::Translation_table * const table) { sp = (addr_t)kernel_stack; ip = (addr_t)kernel; - core_pd()->admit(this); /* * platform specific initialization, has to be done after diff --git a/repos/base-hw/src/core/kernel/init.cc b/repos/base-hw/src/core/kernel/init.cc index 3dec3d2b5..c829fe68f 100644 --- a/repos/base-hw/src/core/kernel/init.cc +++ b/repos/base-hw/src/core/kernel/init.cc @@ -43,24 +43,22 @@ Genode::Board & Kernel::board() { */ extern "C" void init_kernel() { - /* - * As atomic operations are broken in physical mode on some platforms - * we must avoid the use of 'cmpxchg' by now (includes not using any - * local static objects. - */ - - board().init(); + static volatile bool initialized = false; + if (Cpu::executing_id()) while (!initialized) ; /* initialize cpu pool */ cpu_pool(); /* initialize current cpu */ - cpu_pool()->cpu(Cpu::executing_id())->init(*pic(), *core_pd(), board()); + cpu_pool()->cpu(Cpu::executing_id())->init(*pic()/*, *core_pd(), board()*/); Core_thread::singleton(); - Genode::log(""); - Genode::log("kernel initialized"); + if (!Cpu::executing_id()) { + initialized = true; + Genode::log(""); + Genode::log("kernel initialized"); + } kernel(); } diff --git a/repos/base-hw/src/core/kernel/pd.cc b/repos/base-hw/src/core/kernel/pd.cc index fbeb7fa08..4a91f23f1 100644 --- a/repos/base-hw/src/core/kernel/pd.cc +++ b/repos/base-hw/src/core/kernel/pd.cc @@ -14,54 +14,37 @@ /* core includes */ #include -#include #include - -/* Genode includes */ #include #include +#include + +#include +#include /* base-internal includes */ +#include #include using namespace Kernel; +using Genode::Translation_table; +using Genode::Platform; /* structure of the mode transition */ -extern int _mt_begin; -extern int _mt_end; -extern int _mt_user_entry_pic; -extern Genode::addr_t _mt_client_context_ptr; -extern Genode::addr_t _mt_master_context_begin; -extern Genode::addr_t _mt_master_context_end; - - -size_t Mode_transition_control::_size() { - return (addr_t)&_mt_end - (addr_t)&_mt_begin; } - - -size_t Mode_transition_control::_master_context_size() -{ - addr_t const begin = (addr_t)&_mt_master_context_begin; - addr_t const end = (addr_t)&_mt_master_context_end; - return end - begin; -} - - -addr_t Mode_transition_control::_virt_user_entry() -{ - addr_t const phys = (addr_t)&_mt_user_entry_pic; - addr_t const phys_base = (addr_t)&_mt_begin; - return VIRT_BASE + (phys - phys_base); -} +extern int _mt_begin; +extern int _mt_user_entry_pic; +extern int _mt_client_context_ptr; void Mode_transition_control::map(Genode::Translation_table * tt, Genode::Translation_table_allocator * alloc) { + static addr_t const phys_base = + Platform::core_phys_addr((addr_t)&_mt_begin); + try { - addr_t const phys_base = (addr_t)&_mt_begin; - tt->insert_translation(Genode::trunc_page(VIRT_BASE), phys_base, SIZE, - Genode::Page_flags::mode_transition(), alloc); + tt->insert_translation(Cpu::exception_entry, phys_base, Cpu::mtc_size, + Genode::PAGE_FLAGS_KERN_EXCEP, alloc); } catch(...) { Genode::error("inserting exception vector in page table failed!"); } } @@ -87,23 +70,12 @@ void Mode_transition_control::switch_to(Cpu::Context * const context, void Mode_transition_control::switch_to_user(Cpu::Context * const context, unsigned const cpu) { - switch_to(context, cpu, _virt_user_entry(), - (addr_t)&_mt_client_context_ptr); + static addr_t entry = (addr_t)Cpu::exception_entry + + ((addr_t)&_mt_user_entry_pic + - (addr_t)&_mt_begin); + switch_to(context, cpu, entry, (addr_t)&_mt_client_context_ptr); } -Mode_transition_control::Mode_transition_control() : _master(&_table) -{ - assert(Genode::aligned(this, ALIGN_LOG2)); - assert(sizeof(_master) <= _master_context_size()); - assert(_size() <= SIZE); - map(&_table, _alloc.alloc()); - Genode::memcpy(&_mt_master_context_begin, &_master, sizeof(_master)); -} - - -Mode_transition_control * Kernel::mtc() -{ - typedef Mode_transition_control Control; - return unmanaged_singleton(); -} +Mode_transition_control * Kernel::mtc() { + return unmanaged_singleton(); } diff --git a/repos/base-hw/src/core/kernel/thread.cc b/repos/base-hw/src/core/kernel/thread.cc index 2cf0dce54..91c287522 100644 --- a/repos/base-hw/src/core/kernel/thread.cc +++ b/repos/base-hw/src/core/kernel/thread.cc @@ -20,6 +20,7 @@ /* base-internal includes */ #include #include +#include /* core includes */ #include @@ -647,14 +648,15 @@ Genode::uint8_t __initial_stack_base[DEFAULT_STACK_SIZE]; Core_thread::Core_thread() : Core_object(Cpu_priority::MAX, 0, "core") { - using Genode::Native_utcb; + using namespace Genode; static Native_utcb * const utcb = - unmanaged_singleton(); + unmanaged_singleton(); + static addr_t const utcb_phys = Platform::core_phys_addr((addr_t)utcb); /* map UTCB */ - Genode::map_local((addr_t)utcb, (addr_t)Genode::utcb_main_thread(), - sizeof(Native_utcb) / Genode::get_page_size()); + Genode::map_local(utcb_phys, (addr_t)utcb_main_thread(), + sizeof(Native_utcb) / get_page_size()); utcb->cap_add(core_capid()); utcb->cap_add(cap_id_invalid()); diff --git a/repos/base-hw/src/core/kernel_log.cc b/repos/base-hw/src/core/kernel_log.cc new file mode 100644 index 000000000..1b03f29db --- /dev/null +++ b/repos/base-hw/src/core/kernel_log.cc @@ -0,0 +1,35 @@ +/* + * \brief Access to the core's log facility + * \author Norman Feske + * \author Stefan Kalkowski + * \date 2016-05-03 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +/* base-internal includes */ +#include + +#include +#include + + +void Kernel::log(char const c) +{ + using Genode::Serial; + + enum { + ASCII_LINE_FEED = 10, + ASCII_CARRIAGE_RETURN = 13, + BAUD_RATE = 115200 + }; + + Serial & serial = *unmanaged_singleton(BAUD_RATE); + if (c == ASCII_LINE_FEED) serial.put_char(ASCII_CARRIAGE_RETURN); + serial.put_char(c); +} diff --git a/repos/base-hw/src/core/platform.cc b/repos/base-hw/src/core/platform.cc index c53791b6c..5649a2aa7 100644 --- a/repos/base-hw/src/core/platform.cc +++ b/repos/base-hw/src/core/platform.cc @@ -42,38 +42,46 @@ void __attribute__((weak)) Kernel::init_trustzone(Pic & pic) { } ** Platform ** **************/ -addr_t Platform::core_translation_tables() -{ - size_t sz = max((size_t)Translation_table::TABLE_LEVEL_X_SIZE_LOG2, - get_page_size_log2()); - return align_addr((addr_t)&_boot_modules_binaries_end, sz); -} +Bootinfo const & Platform::_bootinfo() { + return *reinterpret_cast(round_page((addr_t)&_prog_img_end)); } +addr_t Platform::mmio_to_virt(addr_t mmio) { + return _bootinfo().core_mmio.virt_addr(mmio); } -Genode::Memory_region_array & Platform::core_ram_regions() -{ - return *unmanaged_singleton( - Memory_region { (addr_t)&_prog_img_beg, - (size_t)((addr_t)&_prog_img_end - - (addr_t)&_prog_img_beg) }, - Memory_region { core_translation_tables(), - core_translation_tables_size() }); -} +Translation_table * Platform::core_translation_table() { + return _bootinfo().table; } +Translation_table_allocator * Platform::core_translation_table_allocator() { + return _bootinfo().table_allocator->alloc(); } void Platform::_init_io_mem_alloc() { /* add entire adress space minus the RAM memory regions */ _io_mem_alloc.add_range(0, ~0x0UL); - Platform::ram_regions().for_each([this] (Memory_region const &r) { + _bootinfo().ram_regions.for_each([this] (Memory_region const &r) { _io_mem_alloc.remove_range(r.base, r.size); }); - - /* remove IOMEM of core from its virtual address space allocator */ - Platform::core_mmio_regions().for_each([this] (Memory_region const &r) { - _core_mem_alloc.virt_alloc()->remove_range(r.base, r.size);}); }; +Memory_region_array const & Platform::_core_virt_regions() +{ + return *unmanaged_singleton( + Memory_region(stack_area_virtual_base(), stack_area_virtual_size())); +} + + +addr_t Platform::core_phys_addr(addr_t virt) +{ + addr_t ret = 0; + _bootinfo().elf_mappings.for_each([&] (Mapping const & m) + { + if (virt >= m.virt() && virt < (m.virt() + m.size())) + ret = (virt - m.virt()) + m.phys(); + }); + return ret; +} + + Platform::Platform() : _io_mem_alloc(core_mem_alloc()), @@ -82,15 +90,13 @@ Platform::Platform() { _core_mem_alloc.virt_alloc()->add_range(VIRT_ADDR_SPACE_START, VIRT_ADDR_SPACE_SIZE); - _core_mem_alloc.virt_alloc()->remove_range(stack_area_virtual_base(), - stack_area_virtual_size()); - - Platform::ram_regions().for_each([this] (Memory_region const & region) { + _core_virt_regions().for_each([this] (Memory_region const & r) { + _core_mem_alloc.virt_alloc()->remove_range(r.base, r.size); }); + _bootinfo().elf_mappings.for_each([this] (Mapping const & m) { + _core_mem_alloc.virt_alloc()->remove_range(m.virt(), m.size()); }); + _bootinfo().ram_regions.for_each([this] (Memory_region const & region) { _core_mem_alloc.phys_alloc()->add_range(region.base, region.size); }); - core_ram_regions().for_each([this] (Memory_region const & region) { - _core_mem_alloc.phys_alloc()->remove_range(region.base, region.size); }); - _init_io_port_alloc(); /* make all non-kernel interrupts available to the interrupt allocator */ @@ -106,7 +112,8 @@ Platform::Platform() Boot_modules_header * header = &_boot_modules_headers_begin; for (; header < &_boot_modules_headers_end; header++) { Rom_module * rom_module = new (core_mem_alloc()) - Rom_module(header->base, header->size, (const char*)header->name); + Rom_module(Platform::core_phys_addr(header->base), header->size, + (const char*)header->name); _rom_fs.insert(rom_module); } diff --git a/repos/base-hw/src/core/platform_pd.cc b/repos/base-hw/src/core/platform_pd.cc index 9b0258604..53aaffa0a 100644 --- a/repos/base-hw/src/core/platform_pd.cc +++ b/repos/base-hw/src/core/platform_pd.cc @@ -17,12 +17,10 @@ #include /* core includes */ +#include #include #include -extern int _prog_img_beg; -extern int _prog_img_end; - using namespace Genode; @@ -69,7 +67,8 @@ void Hw::Address_space::flush(addr_t virt, size_t size) Lock::Guard guard(_lock); try { - if (_tt) _tt->remove_translation(virt, size, _tt_alloc); + assert(_tt); + _tt->remove_translation(virt, size, _tt_alloc); /* update translation caches */ Kernel::update_pd(_kernel_pd); @@ -81,7 +80,8 @@ void Hw::Address_space::flush(addr_t virt, size_t size) Hw::Address_space::Address_space(Kernel::Pd* pd, Translation_table * tt, Translation_table_allocator * tt_alloc) -: _tt(tt), _tt_phys(tt), _tt_alloc(tt_alloc), _kernel_pd(pd) { } +: _tt(tt), _tt_phys(tt), _tt_alloc(tt_alloc), _kernel_pd(pd) { + Kernel::mtc()->map(_tt, _tt_alloc); } Hw::Address_space::Address_space(Kernel::Pd * pd) @@ -180,55 +180,12 @@ Platform_pd::~Platform_pd() ** Core_platform_pd implementation ** *************************************/ -Translation_table * const Core_platform_pd::_table() -{ - return unmanaged_singleton(); -} - - -Translation_table_allocator * const Core_platform_pd::_table_alloc() -{ - constexpr size_t count = Genode::Translation_table::CORE_TRANS_TABLE_COUNT; - using Allocator = Translation_table_allocator_tpl; - - static Allocator * alloc = nullptr; - if (!alloc) { - void * base = (void*) Platform::core_translation_tables(); - alloc = construct_at(base); - } - return alloc->alloc(); -} - - -void Core_platform_pd::_map(addr_t start, size_t size, bool io_mem) -{ - const Page_flags flags = - Page_flags::apply_mapping(true, io_mem ? UNCACHED : CACHED, io_mem); - - if (start < VIRT_ADDR_SPACE_START) error("mapping outside of core's vm"); - - try { - _table()->insert_translation(start, start, size, flags, _table_alloc()); - } catch(Allocator::Out_of_memory) { - error("translation table needs to much RAM"); - } catch(...) { - error("invalid mapping ", Hex(start), " size=", size); - } -} - +extern int _mt_master_context_begin; Core_platform_pd::Core_platform_pd() -: Platform_pd(_table(), _table_alloc()) +: Platform_pd(Platform::core_translation_table(), + Platform::core_translation_table_allocator()) { - /* map exception vector for core */ - Kernel::mtc()->map(_table(), _table_alloc()); - - /* map core's ram regions */ - Platform::core_ram_regions().for_each([this] (Memory_region const &r) { - _map(r.base, r.size, false); }); - - /* map core's mmio regions */ - Platform::core_mmio_regions().for_each([this] (Memory_region const &r) { - _map(r.base, r.size, true); }); + Genode::construct_at(&_mt_master_context_begin, + translation_table_phys()); } diff --git a/repos/base-hw/src/core/platform_thread.cc b/repos/base-hw/src/core/platform_thread.cc index 92600c63e..67a20c82e 100644 --- a/repos/base-hw/src/core/platform_thread.cc +++ b/repos/base-hw/src/core/platform_thread.cc @@ -142,11 +142,10 @@ int Platform_thread::start(void * const ip, void * const sp) error("invalid RM client"); return -1; }; - Page_flags const flags = Page_flags::apply_mapping(true, CACHED, false); _utcb_pd_addr = utcb_main_thread(); Hw::Address_space * as = static_cast(&*locked_ptr); if (!as->insert_translation((addr_t)_utcb_pd_addr, dsc->phys_addr(), - sizeof(Native_utcb), flags)) { + sizeof(Native_utcb), PAGE_FLAGS_UTCB)) { error("failed to attach UTCB"); return -1; } diff --git a/repos/base-hw/src/core/region_map_support.cc b/repos/base-hw/src/core/region_map_support.cc index 75badc1ae..716437c69 100644 --- a/repos/base-hw/src/core/region_map_support.cc +++ b/repos/base-hw/src/core/region_map_support.cc @@ -81,8 +81,8 @@ void Pager_entrypoint::entry() if (!locked_ptr.valid()) return; Hw::Address_space * as = static_cast(&*locked_ptr); - as->insert_translation(_mapping.virt, _mapping.phys, - _mapping.size, _mapping.flags); + as->insert_translation(_mapping.virt(), _mapping.phys(), + _mapping.size(), _mapping.flags()); } /* let pager object go back to no-fault state */ diff --git a/repos/base-hw/src/core/spec/arm/kernel/cpu.cc b/repos/base-hw/src/core/spec/arm/kernel/cpu.cc index ea030ee9e..1dd66c4fd 100644 --- a/repos/base-hw/src/core/spec/arm/kernel/cpu.cc +++ b/repos/base-hw/src/core/spec/arm/kernel/cpu.cc @@ -19,27 +19,17 @@ #include #include -void Kernel::Cpu::init(Kernel::Pic &pic, Kernel::Pd & core_pd, - Genode::Board & board) +void Kernel::Cpu::init(Kernel::Pic &pic) { - Sctlr::init(); - - /* switch to core address space */ - Cpu::enable_mmu_and_caches(core_pd); - - /* - * TrustZone initialization code - */ - init_trustzone(pic); - - /* - * Enable performance counter - */ - perf_counter()->enable(); - /* locally initialize interrupt controller */ pic.init_cpu_local(); + /* TrustZone initialization code */ + init_trustzone(pic); + + /* enable performance counter */ + perf_counter()->enable(); + /* enable timer interrupt */ pic.unmask(Timer::interrupt_id(id()), id()); } diff --git a/repos/base-hw/src/core/spec/arm/kernel/cpu_context.cc b/repos/base-hw/src/core/spec/arm/kernel/cpu_context.cc index b2f24df76..97883585c 100644 --- a/repos/base-hw/src/core/spec/arm/kernel/cpu_context.cc +++ b/repos/base-hw/src/core/spec/arm/kernel/cpu_context.cc @@ -13,9 +13,12 @@ /* core includes */ #include +#include void Kernel::Cpu_context::_init(size_t const stack_size, addr_t const table) { - r12 = stack_size; + r12 = stack_size; cpu_exception = Genode::Cpu::Ttbr0::init(table); + protection_domain(0); + translation_table(table); } diff --git a/repos/base-hw/src/core/spec/arm/kernel/crt0.s b/repos/base-hw/src/core/spec/arm/kernel/crt0.s index 52889d30b..bde39b213 100644 --- a/repos/base-hw/src/core/spec/arm/kernel/crt0.s +++ b/repos/base-hw/src/core/spec/arm/kernel/crt0.s @@ -19,7 +19,6 @@ /* core includes */ .include "macros.s" - .section ".text.crt0" /********************************** @@ -29,31 +28,9 @@ .global _start _start: - /* idle a little initially because U-Boot likes it this way */ - mov r8, r8 - mov r8, r8 - mov r8, r8 - mov r8, r8 - mov r8, r8 - mov r8, r8 - mov r8, r8 - mov r8, r8 - - /* zero-fill BSS segment */ - ldr r0, =_bss_start - ldr r1, =_bss_end - mov r2, #0 - 1: - cmp r1, r0 - ble 2f - str r2, [r0] - add r0, r0, #4 - b 1b - 2: - /* setup temporary stack pointer */ - _get_constraints_of_kernel_stacks r0, r1 - add sp, r0, r1 + _get_constraints_of_kernel_stacks r2, r3 + _init_kernel_sp r2, r3 /* kernel-initialization */ bl init_kernel diff --git a/repos/base-hw/src/core/spec/arm/smp/kernel/cpu.cc b/repos/base-hw/src/core/spec/arm/smp/kernel/cpu.cc index 702e6f8fe..32a52521a 100644 --- a/repos/base-hw/src/core/spec/arm/smp/kernel/cpu.cc +++ b/repos/base-hw/src/core/spec/arm/smp/kernel/cpu.cc @@ -25,18 +25,5 @@ Kernel::Lock & Kernel::data_lock() { return *unmanaged_singleton(); } -/** - * Setup non-boot CPUs - */ -extern "C" void init_kernel_mp() -{ - using namespace Kernel; - - cpu_pool()->cpu(Genode::Cpu::executing_id())->init(*pic(), *core_pd(), board()); - - kernel(); -} - - void Kernel::Cpu_domain_update::_domain_update() { cpu_pool()->cpu(Cpu::executing_id())->invalidate_tlb_by_pid(_domain_id); } diff --git a/repos/base-hw/src/core/spec/arm/smp/kernel/crt0.s b/repos/base-hw/src/core/spec/arm/smp/kernel/crt0.s deleted file mode 100644 index eba4f282a..000000000 --- a/repos/base-hw/src/core/spec/arm/smp/kernel/crt0.s +++ /dev/null @@ -1,39 +0,0 @@ -/* - * \brief Startup code for SMP kernel - * \author Martin Stein - * \author Stefan Kalkowski - * \date 2015-12-08 - */ - -/* - * Copyright (C) 2015 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -/************ - ** Macros ** - ************/ - -/* core includes */ -.include "macros.s" - -.section ".text.crt0" - -/********************************************* - ** Startup code that is common to all CPUs ** - *********************************************/ - -.global _start_secondary_cpus -_start_secondary_cpus: - -/* setup multiprocessor-aware kernel stack-pointer */ -_get_constraints_of_kernel_stacks r0, r1 -_init_kernel_sp r0, r1 - -/* do multiprocessor kernel-initialization */ -bl init_kernel_mp - -/* catch erroneous return of the kernel main-routine */ -1: b 1b diff --git a/repos/base-hw/src/core/spec/arm_gic/pic.cc b/repos/base-hw/src/core/spec/arm_gic/pic.cc index 28033fff0..22011fe04 100644 --- a/repos/base-hw/src/core/spec/arm_gic/pic.cc +++ b/repos/base-hw/src/core/spec/arm_gic/pic.cc @@ -13,6 +13,7 @@ /* core includes */ #include +#include using namespace Genode; @@ -43,3 +44,13 @@ void Pic::init_cpu_local() /* enable device */ _cpui.write(1); } + + +Pic::Pic() +: _distr(Platform::mmio_to_virt(Board::IRQ_CONTROLLER_DISTR_BASE)), + _cpui (Platform::mmio_to_virt(Board::IRQ_CONTROLLER_CPU_BASE)), + _last_iar(Cpui::Iar::Irq_id::bits(spurious_id)), + _max_irq(_distr.max_irq()) +{ + _init(); +} diff --git a/repos/base-hw/src/core/spec/arm_v6/cpu.cc b/repos/base-hw/src/core/spec/arm_v6/cpu.cc index 7a76cb5ee..d0e76e158 100644 --- a/repos/base-hw/src/core/spec/arm_v6/cpu.cc +++ b/repos/base-hw/src/core/spec/arm_v6/cpu.cc @@ -21,20 +21,6 @@ void Genode::Arm::clean_invalidate_data_cache() { asm volatile ("mcr p15, 0, %[rd], c7, c14, 0" :: [rd]"r"(0) : ); } -void Genode::Arm::enable_mmu_and_caches(Kernel::Pd& pd) -{ - /* check for mapping restrictions */ - assert(!Cpu::restricted_page_mappings()); - - invalidate_tlb(); - Cidr::write(pd.asid); - Dacr::write(Dacr::init_virt_kernel()); - Ttbr0::write(Ttbr0::init((Genode::addr_t)pd.translation_table())); - Ttbcr::write(0); - Sctlr::enable_mmu_and_caches(); -} - - void Genode::Cpu::translation_added(Genode::addr_t const addr, Genode::size_t const size) { diff --git a/repos/base-hw/src/core/spec/arm_v7/cpu.cc b/repos/base-hw/src/core/spec/arm_v7/cpu.cc index 84e876f78..ed4eaa135 100644 --- a/repos/base-hw/src/core/spec/arm_v7/cpu.cc +++ b/repos/base-hw/src/core/spec/arm_v7/cpu.cc @@ -13,7 +13,6 @@ */ #include -#include /** * Helpers that increase readability of MCR and MRC commands diff --git a/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/cpu_context.cc b/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/cpu_context.cc index aae9bc11d..dccab33a8 100644 --- a/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/cpu_context.cc +++ b/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/cpu_context.cc @@ -16,8 +16,10 @@ void Kernel::Cpu_context::_init(size_t const stack_size, addr_t const table) { - r12 = stack_size; + r12 = stack_size; cpu_exception = Genode::Cpu::Ttbr0::init(table); + protection_domain(0); + translation_table(table); sctlr = Cpu::Sctlr::init_value(); ttbrc = Cpu::Ttbcr::init_virt_kernel(); mair0 = Cpu::Mair0::init_virt_kernel(); diff --git a/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/vm.cc b/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/vm.cc index e3998e188..91d1938c5 100644 --- a/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/vm.cc +++ b/repos/base-hw/src/core/spec/arm_v7/virtualization/kernel/vm.cc @@ -32,11 +32,6 @@ namespace Kernel * Kernel private virtualization interrupts, delivered to VM/VMMs */ struct Vm_irq; - - /** - * Cpu-specific initialization for virtualization support - */ - void prepare_hypervisor(void); } using namespace Kernel; @@ -44,8 +39,6 @@ using namespace Kernel; extern void * _vt_vm_entry; extern void * _vt_host_entry; extern Genode::addr_t _vt_vm_context_ptr; -extern Genode::addr_t _vt_host_context_ptr; -extern Genode::addr_t _mt_master_context_begin; struct Kernel::Vm_irq : Kernel::Irq @@ -82,7 +75,7 @@ struct Kernel::Virtual_pic : Genode::Mmio Vm_irq irq = Genode::Board::VT_MAINTAINANCE_IRQ; Virtual_pic() - : Genode::Mmio(Genode::Board::IRQ_CONTROLLER_VT_CTRL_BASE) { } + : Genode::Mmio(Genode::Platform::mmio_to_virt(Genode::Board::IRQ_CONTROLLER_VT_CTRL_BASE)) { } static Virtual_pic& pic() { @@ -179,28 +172,6 @@ struct Kernel::Virtual_timer }; -void Kernel::prepare_hypervisor() -{ - /* set hypervisor exception vector */ - Cpu::hyp_exception_entry_at(&_vt_host_entry); - - /* set hypervisor's translation table */ - Genode::Translation_table * table = - core_pd()->platform_pd()->translation_table_phys(); - Cpu::Httbr::translation_table((addr_t)table); - - /* prepare MMU usage by hypervisor code */ - Cpu::Htcr::write(Cpu::Ttbcr::init_virt_kernel()); - Cpu::Hcptr::write(Cpu::Hcptr::init()); - Cpu::Hmair0::write(Cpu::Mair0::init_virt_kernel()); - Cpu::Vtcr::write(Cpu::Vtcr::init()); - Cpu::Hsctlr::write(Cpu::Sctlr::init_value()); - - /* initialize host context used in virtualization world switch */ - *((void**)&_vt_host_context_ptr) = &_mt_master_context_begin; -} - - using Vmid_allocator = Genode::Bit_allocator<256>; static Vmid_allocator &alloc() diff --git a/repos/base-hw/src/core/spec/arm_v7/virtualization/mode_transition.s b/repos/base-hw/src/core/spec/arm_v7/virtualization/mode_transition.s index 699b54f73..50dd59153 100644 --- a/repos/base-hw/src/core/spec/arm_v7/virtualization/mode_transition.s +++ b/repos/base-hw/src/core/spec/arm_v7/virtualization/mode_transition.s @@ -28,6 +28,30 @@ .section .text +/* + * On virtualization exceptions the CPU has to jump to one of the following + * 7 entry vectors to switch to a kernel context. + */ +.p2align 12 +.global _vt_host_entry +_vt_host_entry: + b _vt_rst_entry + b _vt_und_entry /* undefined instruction */ + b _vt_svc_entry /* hypervisor call */ + b _vt_pab_entry /* prefetch abort */ + b _vt_dab_entry /* data abort */ + b _vt_trp_entry /* hypervisor trap */ + b _vt_irq_entry /* interrupt request */ + _vm_exit 7 /* fast interrupt request */ + +_vt_rst_entry: _vm_exit 1 +_vt_und_entry: _vm_exit 2 +_vt_svc_entry: _vm_exit 3 +_vt_pab_entry: _vm_exit 4 +_vt_dab_entry: _vm_exit 5 +_vt_irq_entry: _vm_exit 6 +_vt_trp_entry: _vm_exit 8 + /* space for a copy of the host context */ .p2align 2 .global _vt_host_context_ptr @@ -148,28 +172,3 @@ _vt_vm_entry: cps #SVC_MODE ldm r0!, {r5 - r12} hvc #0 - -/* - * On virtualization exceptions the CPU has to jump to one of the following - * 7 entry vectors to switch to a kernel context. - */ -.p2align 5 -.global _vt_host_entry -_vt_host_entry: - b _vt_rst_entry - b _vt_und_entry /* undefined instruction */ - b _vt_svc_entry /* hypervisor call */ - b _vt_pab_entry /* prefetch abort */ - b _vt_dab_entry /* data abort */ - b _vt_trp_entry /* hypervisor trap */ - b _vt_irq_entry /* interrupt request */ - _vm_exit 7 /* fast interrupt request */ - -_vt_rst_entry: _vm_exit 1 -_vt_und_entry: _vm_exit 2 -_vt_svc_entry: _vm_exit 3 -_vt_pab_entry: _vm_exit 4 -_vt_dab_entry: _vm_exit 5 -_vt_irq_entry: _vm_exit 6 -_vt_trp_entry: _vm_exit 8 - diff --git a/repos/base-hw/src/core/spec/arm_v7/virtualization/vm_session_component.cc b/repos/base-hw/src/core/spec/arm_v7/virtualization/vm_session_component.cc index 7cac81dac..dee50c4e3 100644 --- a/repos/base-hw/src/core/spec/arm_v7/virtualization/vm_session_component.cc +++ b/repos/base-hw/src/core/spec/arm_v7/virtualization/vm_session_component.cc @@ -36,7 +36,7 @@ void Vm_session_component::exception_handler(Signal_context_capability handler) void Vm_session_component::_attach(addr_t phys_addr, addr_t vm_addr, size_t size) { - Page_flags pflags = Page_flags::apply_mapping(true, CACHED, false); + Page_flags pflags { RW, NO_EXEC, USER, NO_GLOBAL, RAM, CACHED }; try { _table->insert_translation(vm_addr, phys_addr, size, pflags, _tt_alloc); diff --git a/repos/base-hw/src/core/spec/arndale/pic.cc b/repos/base-hw/src/core/spec/arndale/pic.cc index 9cc73c695..a05973c74 100644 --- a/repos/base-hw/src/core/spec/arndale/pic.cc +++ b/repos/base-hw/src/core/spec/arndale/pic.cc @@ -13,6 +13,7 @@ /* core includes */ #include +#include using namespace Genode; @@ -58,3 +59,13 @@ void Pic::init_cpu_local() Cpui::Ctlr::Fiq_en::set(v, 1); _cpui.write(v); } + + +Pic::Pic() +: _distr(Platform::mmio_to_virt(Board::IRQ_CONTROLLER_DISTR_BASE)), + _cpui (Platform::mmio_to_virt(Board::IRQ_CONTROLLER_CPU_BASE)), + _last_iar(Cpui::Iar::Irq_id::bits(spurious_id)), + _max_irq(_distr.max_irq()) +{ + _init(); +} diff --git a/repos/base-hw/src/core/spec/arndale/platform_services.cc b/repos/base-hw/src/core/spec/arndale/platform_services.cc index 94a9959a5..a9ab70df4 100644 --- a/repos/base-hw/src/core/spec/arndale/platform_services.cc +++ b/repos/base-hw/src/core/spec/arndale/platform_services.cc @@ -18,8 +18,12 @@ /* core includes */ #include #include /* for 'Core_service' type */ +#include #include +extern Genode::addr_t _vt_host_context_ptr; +extern Genode::addr_t _vt_host_entry; +extern Genode::addr_t _mt_master_context_begin; /* * Add ARM virtualization specific vm service @@ -30,6 +34,11 @@ void Genode::platform_add_local_services(Rpc_entrypoint *ep, { using namespace Genode; + /* initialize host context used in virtualization world switch */ + *((void**)&_vt_host_context_ptr) = &_mt_master_context_begin; + + map_local(Platform::core_phys_addr((addr_t)&_vt_host_entry), 0xfff00000, 1, PAGE_FLAGS_KERN_TEXT); + static Vm_root vm_root(ep, sh); static Core_service vm_service(*services, vm_root); } diff --git a/repos/base-hw/src/core/spec/cortex_a15/cpu.cc b/repos/base-hw/src/core/spec/cortex_a15/cpu.cc deleted file mode 100644 index dd2c9e395..000000000 --- a/repos/base-hw/src/core/spec/cortex_a15/cpu.cc +++ /dev/null @@ -1,26 +0,0 @@ -/* - * \brief Cpu driver implementations specific to ARM Cortex A15 - * \author Stefan Kalkowski - * \date 2016-01-07 - */ - -/* - * Copyright (C) 2016 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -/* core includes */ -#include -#include - -void Genode::Arm_v7::enable_mmu_and_caches(Kernel::Pd & pd) -{ - Cpu::Mair0::write(Cpu::Mair0::init_virt_kernel()); - Cpu::Dacr::write(Cpu::Dacr::init_virt_kernel()); - Cpu::Ttbr0::write(Cpu::Ttbr0::init((Genode::addr_t)pd.translation_table(), pd.asid)); - Cpu::Ttbcr::write(Cpu::Ttbcr::init_virt_kernel()); - Cpu::Sctlr::enable_mmu_and_caches(); - invalidate_branch_predicts(); -} diff --git a/repos/base-hw/src/core/spec/cortex_a15/kernel/cpu.cc b/repos/base-hw/src/core/spec/cortex_a15/kernel/cpu.cc index aacc8f62c..594a5385b 100644 --- a/repos/base-hw/src/core/spec/cortex_a15/kernel/cpu.cc +++ b/repos/base-hw/src/core/spec/cortex_a15/kernel/cpu.cc @@ -29,30 +29,8 @@ extern "C" void * _start_secondary_cpus; static volatile bool primary_cpu = true; -void Kernel::Cpu::init(Kernel::Pic &pic, Kernel::Pd & core_pd, Genode::Board & board) +void Kernel::Cpu::init(Kernel::Pic &pic/*, Kernel::Pd & core_pd, Genode::Board & board*/) { - /* - * local interrupt controller interface needs to be initialized that early, - * because it potentially sets the SGI interrupts to be non-secure before - * entering the normal world in Genode::Cpu::init() - */ - pic.init_cpu_local(); - - Genode::Cpu::init(); - - Sctlr::init(); - Psr::write(Psr::init_kernel()); - - invalidate_inner_data_cache(); - - /* primary cpu wakes up all others */ - if (primary_cpu && NR_OF_CPUS > 1) { - primary_cpu = false; - board.wake_up_all_cpus(&_start_secondary_cpus); - } - - enable_mmu_and_caches(core_pd); - { Lock::Guard guard(data_lock()); diff --git a/repos/base-hw/src/core/spec/cortex_a8/cpu.cc b/repos/base-hw/src/core/spec/cortex_a8/cpu.cc index b30bec366..0cc6954f8 100644 --- a/repos/base-hw/src/core/spec/cortex_a8/cpu.cc +++ b/repos/base-hw/src/core/spec/cortex_a8/cpu.cc @@ -15,7 +15,6 @@ #include #include #include -#include void Genode::Cpu::translation_table_insertions() { @@ -42,15 +41,3 @@ void Genode::Cpu::translation_added(Genode::addr_t const addr, cpu->clean_invalidate_data_cache(); } } - - -void Genode::Arm_v7::enable_mmu_and_caches(Kernel::Pd & pd) -{ - invalidate_tlb(); - Cpu::Cidr::write(pd.asid); - Cpu::Dacr::write(Dacr::init_virt_kernel()); - Cpu::Ttbr0::write(Ttbr0::init((Genode::addr_t)pd.translation_table())); - Cpu::Ttbcr::write(0); - Cpu::Sctlr::enable_mmu_and_caches(); - invalidate_branch_predicts(); -} diff --git a/repos/base-hw/src/core/spec/cortex_a9/board.cc b/repos/base-hw/src/core/spec/cortex_a9/board.cc new file mode 100644 index 000000000..cca9e6f4a --- /dev/null +++ b/repos/base-hw/src/core/spec/cortex_a9/board.cc @@ -0,0 +1,20 @@ +/* + * \brief Board implementation specific to Cortex A9 + * \author Stefan Kalkowski + * \date 2016-01-07 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#include +#include + +using namespace Genode; + +Cortex_a9::Board::Board() +: _l2_cache(Platform::mmio_to_virt(Board_base::PL310_MMIO_BASE)) {} diff --git a/repos/base-hw/src/core/spec/cortex_a9/cpu.cc b/repos/base-hw/src/core/spec/cortex_a9/cpu.cc deleted file mode 100644 index 1b8be0426..000000000 --- a/repos/base-hw/src/core/spec/cortex_a9/cpu.cc +++ /dev/null @@ -1,27 +0,0 @@ -/* - * \brief CPU driver for core - * \author Martin stein - * \author Stefan Kalkowski - * \date 2011-11-03 - */ - -/* - * Copyright (C) 2011-2016 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -#include -#include - -void Genode::Arm_v7::enable_mmu_and_caches(Kernel::Pd & pd) -{ - invalidate_tlb(); - Cpu::Cidr::write(pd.asid); - Cpu::Dacr::write(Dacr::init_virt_kernel()); - Cpu::Ttbr0::write(Ttbr0::init((Genode::addr_t)pd.translation_table())); - Cpu::Ttbcr::write(0); - Cpu::Sctlr::enable_mmu_and_caches(); - invalidate_branch_predicts(); -} diff --git a/repos/base-hw/src/core/spec/cortex_a9/kernel/cpu.cc b/repos/base-hw/src/core/spec/cortex_a9/kernel/cpu.cc index 74a08bd1a..efdc0a604 100644 --- a/repos/base-hw/src/core/spec/cortex_a9/kernel/cpu.cc +++ b/repos/base-hw/src/core/spec/cortex_a9/kernel/cpu.cc @@ -12,114 +12,23 @@ */ /* core includes */ +#include #include #include #include -#include -#include +#include -/* base-hw includes */ -#include - -using namespace Kernel; - -/* entrypoint for non-boot CPUs */ -extern "C" void * _start_secondary_cpus; +extern int _mt_begin; +extern int _mt_master_context_begin; -/** - * SMP-safe simple counter - */ -class Counter +void Kernel::Cpu::init(Kernel::Pic &pic) { - private: - - Kernel::Lock _lock; - volatile int _value = 0; - - public: - - void inc() - { - Kernel::Lock::Guard guard(_lock); - Genode::memory_barrier(); - _value++; - } - - void wait_for(int const v) { - while (_value < v) ; } -}; - -static volatile bool primary_cpu = true; /* indicates boot cpu status */ -static Counter data_cache_invalidated; /* counts cpus that invalidated - their data cache */ -static Counter data_cache_enabled; /* counts cpus that enabled - their data cache */ -static Counter smp_coherency_enabled; /* counts cpus that enabled - their SCU */ - - -/* - * The initialization of Cortex A9 multicore systems implies a sophisticated - * algorithm in early revisions of this cpu. - * - * See ARM's Cortex-A9 MPCore TRM r2p0 in section 5.3.5 for more details - */ -void Kernel::Cpu::init(Kernel::Pic &pic, Kernel::Pd & core_pd, Genode::Board & board) -{ - bool primary = primary_cpu; - if (primary) primary_cpu = false; - - Sctlr::init(); - Psr::write(Psr::init_kernel()); - - /* locally initialize interrupt controller */ pic.init_cpu_local(); - invalidate_inner_data_cache(); - data_cache_invalidated.inc(); - - /* primary cpu wakes up all others */ - if (primary && NR_OF_CPUS > 1) - board.wake_up_all_cpus(&_start_secondary_cpus); - - /* wait for other cores' data cache invalidation */ - data_cache_invalidated.wait_for(NR_OF_CPUS); - - if (primary) { - Genode::Scu scu(board); - scu.invalidate(); - board.l2_cache().invalidate(); - scu.enable(); - } - - /* secondary cpus wait for the primary's cache activation */ - if (!primary) data_cache_enabled.wait_for(1); - - enable_mmu_and_caches(core_pd); - data_cache_enabled.inc(); - clean_invalidate_inner_data_cache(); - - /* wait for other cores' data cache activation */ - data_cache_enabled.wait_for(NR_OF_CPUS); - - if (primary) board.l2_cache().enable(); - - /* secondary cpus wait for the primary's coherency activation */ - if (!primary) smp_coherency_enabled.wait_for(1); - - Actlr::enable_smp(); - smp_coherency_enabled.inc(); - - /* - * strangely, some older versions (imx6) seem to not work cache coherent - * until SMP bit is set, so write back the variable here. - */ - clean_invalidate_inner_data_cache(); - - /* wait for other cores' coherency activation */ - smp_coherency_enabled.wait_for(NR_OF_CPUS); - + static Hw::Address_space invalid_space(nullptr); + Cpu_context * c = (Cpu_context*) (Cpu::exception_entry + ((addr_t)&_mt_master_context_begin - (addr_t)&_mt_begin)); + c->cpu_exception = Genode::Cpu::Ttbr0::init((addr_t)invalid_space.translation_table_phys()); _fpu.init(); { diff --git a/repos/base-hw/src/core/spec/cortex_a9/timer.cc b/repos/base-hw/src/core/spec/cortex_a9/timer.cc new file mode 100644 index 000000000..ee77d4a4c --- /dev/null +++ b/repos/base-hw/src/core/spec/cortex_a9/timer.cc @@ -0,0 +1,38 @@ +/* + * \brief Timer implementation specific to Cortex A9 + * \author Stefan Kalkowski + * \date 2016-01-07 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#include +#include + +Genode::Timer::Timer() +: Genode::Mmio(Genode::Platform::mmio_to_virt(Board::PRIVATE_TIMER_MMIO_BASE)) +{ + write(0); +} + + +void Genode::Timer::start_one_shot(time_t const tics, unsigned const) +{ + enum { PRESCALER = Board::CORTEX_A9_PRIVATE_TIMER_DIV - 1 }; + + /* reset timer */ + write(1); + Control::access_t control = 0; + Control::Irq_enable::set(control, 1); + Control::Prescaler::set(control, PRESCALER); + write(control); + + /* load timer and start decrementing */ + write(tics); + write(1); +} diff --git a/repos/base-hw/src/core/spec/exynos5/platform_support.cc b/repos/base-hw/src/core/spec/exynos5/platform_support.cc deleted file mode 100644 index a93395efd..000000000 --- a/repos/base-hw/src/core/spec/exynos5/platform_support.cc +++ /dev/null @@ -1,36 +0,0 @@ -/* - * \brief Parts of platform that are specific to Arndale - * \author Martin Stein - * \date 2012-04-27 - */ - -/* - * Copyright (C) 2012 Genode Labs GmbH - * - * This file is part of the Genode OS framework, which is distributed - * under the terms of the GNU General Public License version 2. - */ - -/* core includes */ -#include -#include - -#include - -using namespace Genode; - - -Memory_region_array & Platform::ram_regions() -{ - return *unmanaged_singleton( - Memory_region { Board::RAM_0_BASE, Board::RAM_0_SIZE } ); -} - - -Memory_region_array & Platform::core_mmio_regions() -{ - return *unmanaged_singleton( - Memory_region { Board::IRQ_CONTROLLER_BASE, Board::IRQ_CONTROLLER_SIZE }, - Memory_region { Board::MCT_MMIO_BASE, Board::MCT_MMIO_SIZE }, - Memory_region { Board::UART_2_MMIO_BASE, 0x1000 }); -} diff --git a/repos/base-hw/src/core/spec/imx53/pic.cc b/repos/base-hw/src/core/spec/imx53/pic.cc index 20dafdbc1..91b100056 100644 --- a/repos/base-hw/src/core/spec/imx53/pic.cc +++ b/repos/base-hw/src/core/spec/imx53/pic.cc @@ -13,9 +13,12 @@ /* core includes */ #include +#include using namespace Genode; +Pic::Pic() : Mmio(Platform::mmio_to_virt(Board::IRQ_CONTROLLER_BASE)) { } + void Pic::_init_security_ext() { } void Pic::unsecure(unsigned) { } diff --git a/repos/base-hw/src/core/spec/imx53/platform_support.cc b/repos/base-hw/src/core/spec/imx53/platform_support.cc index 1ae18f138..504291dc7 100644 --- a/repos/base-hw/src/core/spec/imx53/platform_support.cc +++ b/repos/base-hw/src/core/spec/imx53/platform_support.cc @@ -12,32 +12,6 @@ */ /* core includes */ -#include -#include #include -#include - -using namespace Genode; - -Memory_region_array & Platform::ram_regions() -{ - return *unmanaged_singleton( - Memory_region { Board::RAM0_BASE, Board::RAM0_SIZE }, - Memory_region { Board::RAM1_BASE, Board::RAM1_SIZE }); -} - - -Memory_region_array & Platform::core_mmio_regions() -{ - return *unmanaged_singleton( - Memory_region { Board::UART_1_MMIO_BASE, /* UART */ - Board::UART_1_MMIO_SIZE }, - Memory_region { Board::EPIT_1_MMIO_BASE, /* timer */ - Board::EPIT_1_MMIO_SIZE }, - Memory_region { Board::IRQ_CONTROLLER_BASE, /* irq controller */ - Board::IRQ_CONTROLLER_SIZE }); -} - - -Cpu::User_context::User_context() { cpsr = Psr::init_user(); } +Genode::Cpu::User_context::User_context() { cpsr = Psr::init_user(); } diff --git a/repos/base-hw/src/core/spec/imx53/trustzone/pic.cc b/repos/base-hw/src/core/spec/imx53/trustzone/pic.cc index aaca757eb..420461acf 100644 --- a/repos/base-hw/src/core/spec/imx53/trustzone/pic.cc +++ b/repos/base-hw/src/core/spec/imx53/trustzone/pic.cc @@ -13,9 +13,13 @@ /* core includes */ #include +#include using namespace Genode; +Pic::Pic() : Mmio(Platform::mmio_to_virt(Board::IRQ_CONTROLLER_BASE)) { } + + void Pic::_init_security_ext() { for (unsigned i = 0; i < NR_OF_IRQ; i++) { secure(i); } diff --git a/repos/base-hw/src/core/spec/imx53/trustzone/platform_support.cc b/repos/base-hw/src/core/spec/imx53/trustzone/platform_support.cc index edfda3e0c..fcea6b38d 100644 --- a/repos/base-hw/src/core/spec/imx53/trustzone/platform_support.cc +++ b/repos/base-hw/src/core/spec/imx53/trustzone/platform_support.cc @@ -64,26 +64,4 @@ void Kernel::init_trustzone(Pic & pic) } -Memory_region_array & Platform::ram_regions() -{ - return *unmanaged_singleton( - Memory_region { Trustzone::SECURE_RAM_BASE, - Trustzone::SECURE_RAM_SIZE }); -} - - -Memory_region_array & Platform::core_mmio_regions() -{ - return *unmanaged_singleton( - Memory_region { Board::UART_1_MMIO_BASE, /* UART */ - Board::UART_1_MMIO_SIZE }, - Memory_region { Board::EPIT_1_MMIO_BASE, /* timer */ - Board::EPIT_1_MMIO_SIZE }, - Memory_region { Board::IRQ_CONTROLLER_BASE, /* irq controller */ - Board::IRQ_CONTROLLER_SIZE }, - Memory_region { Board::CSU_BASE, /* central security unit */ - Board::CSU_SIZE }); -} - - Cpu::User_context::User_context() { cpsr = Psr::init_user_with_trustzone(); } diff --git a/repos/base-hw/src/core/spec/imx6/platform_support.cc b/repos/base-hw/src/core/spec/imx6/platform_support.cc index 93e01cdda..ff15b1698 100644 --- a/repos/base-hw/src/core/spec/imx6/platform_support.cc +++ b/repos/base-hw/src/core/spec/imx6/platform_support.cc @@ -14,45 +14,6 @@ */ /* core includes */ -#include #include -#include - -using namespace Genode; - -Memory_region_array & Platform::ram_regions() -{ - return *unmanaged_singleton( - Memory_region { Board::RAM0_BASE, Board::RAM0_SIZE }); -} - - -Memory_region_array & Platform::core_mmio_regions() -{ - return *unmanaged_singleton( - Memory_region { Board::UART_1_MMIO_BASE, /* UART */ - Board::UART_1_MMIO_SIZE }, - Memory_region { Board::CORTEX_A9_PRIVATE_MEM_BASE, /* irq controller */ - Board::CORTEX_A9_PRIVATE_MEM_SIZE }, /* and timer */ - Memory_region { Board::PL310_MMIO_BASE, /* l2 cache controller */ - Board::PL310_MMIO_SIZE }); -} - - Genode::Arm::User_context::User_context() { cpsr = Psr::init_user(); } - - -bool Cortex_a9::Board::errata(Cortex_a9::Board::Errata err) -{ - switch (err) { - case Cortex_a9::Board::ARM_754322: - case Cortex_a9::Board::ARM_764369: - case Cortex_a9::Board::ARM_775420: - case Cortex_a9::Board::PL310_588369: - case Cortex_a9::Board::PL310_727915: - case Cortex_a9::Board::PL310_769419: - return true; - }; - return false; -} diff --git a/repos/base-hw/src/core/spec/panda/platform_support.cc b/repos/base-hw/src/core/spec/panda/platform_support.cc index 2affe4ba7..5005b8704 100644 --- a/repos/base-hw/src/core/spec/panda/platform_support.cc +++ b/repos/base-hw/src/core/spec/panda/platform_support.cc @@ -12,57 +12,6 @@ */ /* core includes */ -#include -#include #include -#include -#include - -/* base-internal includes */ -#include - -using namespace Genode; - -Memory_region_array & Platform::ram_regions() -{ - return *unmanaged_singleton( - Memory_region { Board::RAM_0_BASE, Board::RAM_0_SIZE }); -} - - -Memory_region_array & Platform::core_mmio_regions() -{ - return *unmanaged_singleton( - Memory_region { Board::CORTEX_A9_PRIVATE_MEM_BASE, /* timer and PIC */ - Board::CORTEX_A9_PRIVATE_MEM_SIZE }, - Memory_region { Board::TL16C750_3_MMIO_BASE, /* UART */ - Board::TL16C750_MMIO_SIZE }, - Memory_region { Board::PL310_MMIO_BASE, /* l2 cache controller */ - Board::PL310_MMIO_SIZE }); -} - - -void Cortex_a9::Board::wake_up_all_cpus(void * const ip) -{ - Cortex_a9_wugen wugen; - wugen.init_cpu_1(ip); - asm volatile("dsb\n" - "sev\n"); -} Genode::Arm::User_context::User_context() { cpsr = Psr::init_user(); } - - -void Cpu::Actlr::enable_smp() { - Kernel::board().monitor().call(Board::Secure_monitor::CPU_ACTLR_SMP_BIT_RAISE, 0); } - - -bool Cortex_a9::Board::errata(Cortex_a9::Board::Errata err) -{ - switch (err) { - case Cortex_a9::Board::PL310_588369: - case Cortex_a9::Board::PL310_727915: return true; - default: ; - }; - return false; -} diff --git a/repos/base-hw/src/core/spec/pbxa9/platform_support.cc b/repos/base-hw/src/core/spec/pbxa9/platform_support.cc index eef62913d..c95ac2d74 100644 --- a/repos/base-hw/src/core/spec/pbxa9/platform_support.cc +++ b/repos/base-hw/src/core/spec/pbxa9/platform_support.cc @@ -23,28 +23,4 @@ using namespace Genode; -Memory_region_array & Platform::ram_regions() -{ - return *unmanaged_singleton( - Memory_region { Board::RAM_0_BASE, Board::RAM_0_SIZE }, - Memory_region { Board::RAM_1_BASE, Board::RAM_1_SIZE }); -} - - -Memory_region_array & Platform::core_mmio_regions() -{ - return *unmanaged_singleton( - /* core timer and PIC */ - Memory_region { Board::CORTEX_A9_PRIVATE_MEM_BASE, - Board::CORTEX_A9_PRIVATE_MEM_SIZE }, - - /* core UART */ - Memory_region { Board::PL011_0_MMIO_BASE, Board::PL011_0_MMIO_SIZE }, - - /* L2 Cache Controller */ - Memory_region { Board::PL310_MMIO_BASE, Board::PL310_MMIO_SIZE } - ); -} - - Genode::Arm::User_context::User_context() { cpsr = Psr::init_user(); } diff --git a/repos/base-hw/src/core/spec/riscv/kernel/cpu.cc b/repos/base-hw/src/core/spec/riscv/kernel/cpu.cc index e1221b49c..911304a8f 100644 --- a/repos/base-hw/src/core/spec/riscv/kernel/cpu.cc +++ b/repos/base-hw/src/core/spec/riscv/kernel/cpu.cc @@ -20,49 +20,15 @@ using namespace Kernel; extern Genode::addr_t _mt_client_context_ptr; -struct Mstatus : Genode::Register<64> +void Kernel::Cpu::init(Kernel::Pic &pic/*, Kernel::Pd & core_pd, + Genode::Board & board*/) { - enum { - USER = 0, - SUPERVISOR = 1, - MACHINE = 3, - Sv39 = 9, - }; - struct Ie : Bitfield<0, 1> { }; - struct Priv : Bitfield<1, 2> { }; - struct Ie1 : Bitfield<3, 1> { }; - struct Priv1 : Bitfield<4, 2> { }; - struct Fs : Bitfield<12, 2> { enum { INITIAL = 1 }; }; - struct Vm : Bitfield<17, 5> { }; - struct Mprv : Bitfield<16, 1> { }; -}; - - -void Kernel::Cpu::init(Kernel::Pic &pic, Kernel::Pd & core_pd, - Genode::Board & board) -{ - /* read status register */ - Mstatus::access_t mstatus = 0; - - Mstatus::Vm::set(mstatus, Mstatus::Sv39); /* enable Sv39 paging */ - Mstatus::Fs::set(mstatus, Mstatus::Fs::INITIAL); /* enable FPU */ - Mstatus::Ie1::set(mstatus, 1); /* user mode interrupt */ - Mstatus::Priv1::set(mstatus, Mstatus::USER); /* set user mode */ - Mstatus::Ie::set(mstatus, 0); /* disable interrupts */ - Mstatus::Priv::set(mstatus, Mstatus::SUPERVISOR); /* set supervisor mode */ - addr_t client_context_ptr_off = (addr_t)&_mt_client_context_ptr & 0xfff; addr_t client_context_ptr = exception_entry | client_context_ptr_off; - asm volatile ("csrw sasid, %0\n" /* address space id */ - "csrw sptbr, %1\n" /* set page table */ - "csrw mstatus, %2\n" /* change mode */ - "csrw stvec, %3\n" /* exception vector */ - "csrw sscratch,%4\n" /* master conext ptr */ + asm volatile ("csrw stvec, %0\n" /* exception vector */ + "csrw sscratch,%1\n" /* master conext ptr */ : - : "r" (core_pd.asid), - "r" (core_pd.translation_table()), - "r" (mstatus), - "r" (exception_entry), + : "r" (exception_entry), "r" (client_context_ptr) : "memory"); } diff --git a/repos/base-hw/src/core/spec/riscv/kernel/cpu_context.cc b/repos/base-hw/src/core/spec/riscv/kernel/cpu_context.cc index f60c6146f..5696c10ba 100644 --- a/repos/base-hw/src/core/spec/riscv/kernel/cpu_context.cc +++ b/repos/base-hw/src/core/spec/riscv/kernel/cpu_context.cc @@ -23,4 +23,6 @@ void Kernel::Cpu_context::_init(size_t const stack_size, addr_t const table) * stack, i.e. increasing sp by the size of one stack. */ sp = sp + stack_size; + translation_table(table); + protection_domain(0); } diff --git a/repos/base-hw/src/core/spec/riscv/kernel/crt0.s b/repos/base-hw/src/core/spec/riscv/kernel/crt0.s index 18fc325d4..8558b9e3f 100644 --- a/repos/base-hw/src/core/spec/riscv/kernel/crt0.s +++ b/repos/base-hw/src/core/spec/riscv/kernel/crt0.s @@ -15,30 +15,10 @@ .global _start _start: -j _start_next_page - -/* leave first page empty for mode-transition page located at 0x100 */ -.space 4096 - -_start_next_page: - - /* clear the bss segment */ -la a0, _bss_start -la a1, _bss_end -1: -sd x0, (a0) -addi a0, a0, 8 -bne a0, a1, 1b la sp, kernel_stack la a0, kernel_stack_size ld a0, (a0) add sp, sp, a0 -/* save kernel stack pointer in mscratch */ -csrw mscratch, sp - -jal setup_riscv_exception_vector jal init_kernel - -1: j 1b diff --git a/repos/base-hw/src/core/spec/riscv/platform_support.cc b/repos/base-hw/src/core/spec/riscv/platform_support.cc index 9006e4093..1b5b4c64f 100644 --- a/repos/base-hw/src/core/spec/riscv/platform_support.cc +++ b/repos/base-hw/src/core/spec/riscv/platform_support.cc @@ -21,22 +21,10 @@ using namespace Genode; -Memory_region_array & Platform::ram_regions() -{ - return *unmanaged_singleton( - Memory_region { 0, 128 * 1024 * 1024 } ); -} - - Cpu::User_context::User_context() { } -Memory_region_array & Platform::core_mmio_regions() { - return *unmanaged_singleton(); } - void Platform::_init_io_port_alloc() { } -void Platform::_init_io_mem_alloc() { } - void Platform::_init_additional() { } void Platform::setup_irq_mode(unsigned, unsigned, unsigned) { } @@ -44,7 +32,5 @@ void Platform::setup_irq_mode(unsigned, unsigned, unsigned) { } long Platform::irq(long const user_irq) { return 0; } bool Platform::get_msi_params(const addr_t mmconf, addr_t &address, - addr_t &data, unsigned &irq_number) -{ - return false; -} + addr_t &data, unsigned &irq_number) { + return false; } diff --git a/repos/base-hw/src/core/spec/rpi/pic.cc b/repos/base-hw/src/core/spec/rpi/pic.cc new file mode 100644 index 000000000..a50487454 --- /dev/null +++ b/repos/base-hw/src/core/spec/rpi/pic.cc @@ -0,0 +1,136 @@ +/* + * \brief Pic implementation specific to Rpi + * \author Norman Feske + * \author Stefan Kalkowski + * \date 2016-01-07 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#include +#include + + +bool Genode::Usb_dwc_otg::_need_trigger_sof(uint32_t host_frame, + uint32_t scheduled_frame) +{ + uint32_t const max_frame = 0x3fff; + + if (host_frame < scheduled_frame) { + if (scheduled_frame - host_frame < max_frame / 2) + return false; /* scheduled frame not reached yet */ + else + return true; /* scheduled frame passed, host frame wrapped */ + } else { + if (host_frame - scheduled_frame < max_frame / 2) + return true; /* scheduled frame passed */ + else + return false; /* scheduled frame wrapped, not reached */ + } +} + + +Genode::Usb_dwc_otg::Usb_dwc_otg() : Mmio(Platform::mmio_to_virt(Board::USB_DWC_OTG_BASE)) +{ + write(0); + write(false); + write(false); +} + + +bool Genode::Usb_dwc_otg::handle_sof() +{ + if (!_is_sof()) + return false; + + static int cnt = 0; + + if (++cnt == 8*20) { + cnt = 0; + return false; + } + + if (!read() || read()) + return false; + + if (_need_trigger_sof(read(), + read())) + return false; + + write(1); + + return true; +} + + +Genode::Pic::Pic() +: Mmio(Platform::mmio_to_virt(Board::IRQ_CONTROLLER_BASE)) { mask(); } + + +bool Genode::Pic::take_request(unsigned &irq) +{ + /* read basic IRQ status mask */ + uint32_t const p = read(); + + + /* read GPU IRQ status mask */ + uint32_t const p1 = read(), + p2 = read(); + + if (Irq_pending_basic::Timer::get(p)) { + irq = Irq_pending_basic::Timer::SHIFT; + return true; + } + + /* search for lowest set bit in pending masks */ + for (unsigned i = 0; i < NR_OF_IRQ; i++) { + if (!_is_pending(i, p1, p2)) + continue; + + irq = Board_base::GPU_IRQ_BASE + i; + + /* handle SOF interrupts locally, filter from the user land */ + if (irq == Board_base::DWC_IRQ) + if (_usb.handle_sof()) + return false; + + return true; + } + + return false; +} + + +void Genode::Pic::mask() +{ + write(~0); + write(~0); + write(~0); +} + + +void Genode::Pic::unmask(unsigned const i, unsigned) +{ + if (i < 8) + write(1 << i); + else if (i < 32 + 8) + write(1 << (i - 8)); + else + write(1 << (i - 8 - 32)); +} + + +void Genode::Pic::mask(unsigned const i) +{ + if (i < 8) + write(1 << i); + else if (i < 32 + 8) + write(1 << (i - 8)); + else + write(1 << (i - 8 - 32)); +} diff --git a/repos/base-hw/src/core/spec/rpi/platform_support.cc b/repos/base-hw/src/core/spec/rpi/platform_support.cc index 50d56a3bc..bb3dbbf40 100644 --- a/repos/base-hw/src/core/spec/rpi/platform_support.cc +++ b/repos/base-hw/src/core/spec/rpi/platform_support.cc @@ -12,34 +12,8 @@ */ /* core includes */ -#include -#include #include -#include - using namespace Genode; -Memory_region_array & Platform::ram_regions() -{ - return *unmanaged_singleton( - Memory_region { Board::RAM_0_BASE, Board::RAM_0_SIZE }); -} - - -Memory_region_array & Platform::core_mmio_regions() -{ - return *unmanaged_singleton( - Memory_region { Board::PL011_0_MMIO_BASE, /* UART */ - Board::PL011_0_MMIO_SIZE }, - Memory_region { Board::SYSTEM_TIMER_MMIO_BASE, /* system timer */ - Board::SYSTEM_TIMER_MMIO_SIZE }, - Memory_region { Board::IRQ_CONTROLLER_BASE, /* IRQ controller */ - Board::IRQ_CONTROLLER_SIZE }, - Memory_region { Board::USB_DWC_OTG_BASE, /* DWC OTG USB */ - Board::USB_DWC_OTG_SIZE } /* controller */ - ); -} - - Cpu::User_context::User_context() { cpsr = Psr::init_user(); } diff --git a/repos/base-hw/src/core/spec/rpi/timer.cc b/repos/base-hw/src/core/spec/rpi/timer.cc new file mode 100644 index 000000000..94635517d --- /dev/null +++ b/repos/base-hw/src/core/spec/rpi/timer.cc @@ -0,0 +1,51 @@ +/* + * \brief Timer implementation specific to Rpi + * \author Norman Feske + * \author Stefan Kalkowski + * \date 2016-01-07 + */ + +/* + * Copyright (C) 2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +#include +#include + +using namespace Genode; +using Kernel::time_t; + + +Timer::Timer() +: Mmio(Platform::mmio_to_virt(Board::SYSTEM_TIMER_MMIO_BASE)) { } + + +void Timer::start_one_shot(time_t const tics, unsigned const) +{ + write(1); + read(); + write(0); + write(read() + tics); +} + + +time_t Timer::tics_to_us(time_t const tics) const { + return (tics / TICS_PER_MS) * 1000; } + + +time_t Timer::us_to_tics(time_t const us) const { + return (us / 1000) * TICS_PER_MS; } + + +time_t Timer::max_value() { return (Clo::access_t)~0; } + + +time_t Timer::value(unsigned const) +{ + Cmp::access_t const cmp = read(); + Clo::access_t const clo = read(); + return cmp > clo ? cmp - clo : 0; +} diff --git a/repos/base-hw/src/core/spec/x86_64/bios_data_area.cc b/repos/base-hw/src/core/spec/x86_64/bios_data_area.cc index 036f6673d..a883c55b4 100644 --- a/repos/base-hw/src/core/spec/x86_64/bios_data_area.cc +++ b/repos/base-hw/src/core/spec/x86_64/bios_data_area.cc @@ -13,7 +13,8 @@ /* core includes */ #include +#include using namespace Genode; -addr_t Bios_data_area::_mmio_base_virt() { return 0x1ff000; } +addr_t Bios_data_area::_mmio_base_virt() { return Platform::mmio_to_virt(0); } diff --git a/repos/base-hw/src/core/spec/x86_64/cpu.cc b/repos/base-hw/src/core/spec/x86_64/cpu.cc index ddba61b20..e6d839954 100644 --- a/repos/base-hw/src/core/spec/x86_64/cpu.cc +++ b/repos/base-hw/src/core/spec/x86_64/cpu.cc @@ -43,7 +43,6 @@ void Genode::Cpu::Context::init(addr_t const table, bool core) */ eflags = EFLAGS_IF_SET; if (core) eflags |= EFLAGS_IOPL_3; - else Gdt::init(); } diff --git a/repos/base-hw/src/core/spec/x86_64/kernel/cpu.cc b/repos/base-hw/src/core/spec/x86_64/kernel/cpu.cc index e7432180f..c91907994 100644 --- a/repos/base-hw/src/core/spec/x86_64/kernel/cpu.cc +++ b/repos/base-hw/src/core/spec/x86_64/kernel/cpu.cc @@ -25,6 +25,7 @@ using namespace Kernel; Cpu_idle::Cpu_idle(Cpu * const cpu) : Cpu_job(Cpu_priority::MIN, 0) { + Cpu::Gdt::init(); Cpu_job::cpu(cpu); ip = (addr_t)&_main; sp = (addr_t)&_stack[stack_size]; @@ -32,7 +33,7 @@ Cpu_idle::Cpu_idle(Cpu * const cpu) : Cpu_job(Cpu_priority::MIN, 0) } -void Kernel::Cpu::init(Pic &pic, Kernel::Pd &core_pd, Genode::Board&) +void Kernel::Cpu::init(Pic &pic) { Idt::init(); Tss::init(); @@ -41,16 +42,6 @@ void Kernel::Cpu::init(Pic &pic, Kernel::Pd &core_pd, Genode::Board&) fpu().init(); - /* - * Please do not remove the log(), because the serial constructor requires - * access to the Bios Data Area, which is available in the initial - * translation table set, but not in the final tables used after - * Cr3::write(). - */ - Genode::log("Switch to core's final translation table"); - - Cr3::write(Cr3::init((addr_t)core_pd.translation_table())); - /* enable timer interrupt */ unsigned const cpu = Cpu::executing_id(); pic.unmask(Timer::interrupt_id(cpu), cpu); diff --git a/repos/base-hw/src/core/spec/x86_64/kernel/cpu_context.cc b/repos/base-hw/src/core/spec/x86_64/kernel/cpu_context.cc index 6737bf9d3..ae3fafe56 100644 --- a/repos/base-hw/src/core/spec/x86_64/kernel/cpu_context.cc +++ b/repos/base-hw/src/core/spec/x86_64/kernel/cpu_context.cc @@ -13,6 +13,7 @@ /* core includes */ #include +#include void Kernel::Cpu_context::_init(size_t const stack_size, addr_t const table) { @@ -21,5 +22,6 @@ void Kernel::Cpu_context::_init(size_t const stack_size, addr_t const table) * of all CPU's kernel stacks, on this uni-processor platform * it is sufficient to increase it by the stack's size */ - sp = sp + stack_size; + sp = sp + stack_size; + cr3 = Genode::Cpu::Cr3::init(table); } diff --git a/repos/base-hw/src/core/spec/x86_64/kernel/crt0.s b/repos/base-hw/src/core/spec/x86_64/kernel/crt0.s index 178c4f266..8bad86387 100644 --- a/repos/base-hw/src/core/spec/x86_64/kernel/crt0.s +++ b/repos/base-hw/src/core/spec/x86_64/kernel/crt0.s @@ -18,72 +18,8 @@ .section ".text.crt0" - /* magic multi-boot header to make GRUB happy */ - .long 0x1badb002 - .long 0x0 - .long 0xe4524ffe - - /********************************** - ** Startup code for primary CPU ** - **********************************/ - -.code32 - .global _start - _start: - - /** - * zero-fill BSS segment - */ - leal _bss_start, %edi - leal _bss_end, %ecx - sub %edi, %ecx - shr $2, %ecx - xor %eax, %eax - rep stosl - - /* Enable PAE (prerequisite for IA-32e mode) */ - movl %cr4, %eax - btsl $5, %eax - movl %eax, %cr4 - - /* Load initial pagetables */ - leal _kernel_pml4, %eax - mov %eax, %cr3 - - /* Enable IA-32e mode and execute-disable */ - movl $0xc0000080, %ecx - rdmsr - btsl $8, %eax - btsl $11, %eax - wrmsr - - /* Enable paging, write protection and caching */ - movl %cr0, %eax - btsl $16, %eax - btrl $29, %eax - btrl $30, %eax - btsl $31, %eax - movl %eax, %cr0 - - /* Set up GDT */ - lgdt _mt_gdt_ptr - - /* Indirect long jump to 64-bit code */ - ljmp $8, $_start64 - -.code64 - _start64: .p2align MIN_PAGE_SIZE_LOG2 - - /* - * Set up kernel segment selectors - */ - mov $0x10, %eax - mov %eax, %ss - mov %eax, %ds - mov %eax, %es - mov %eax, %fs - mov %eax, %gs - +.global _start +_start: /* * Install initial temporary environment that is replaced later by the * environment that init_main_thread creates. diff --git a/repos/base-hw/src/core/spec/x86_64/mode_transition.s b/repos/base-hw/src/core/spec/x86_64/mode_transition.s index dc1d8e6a7..dc5c4b3f3 100644 --- a/repos/base-hw/src/core/spec/x86_64/mode_transition.s +++ b/repos/base-hw/src/core/spec/x86_64/mode_transition.s @@ -307,48 +307,7 @@ .quad MT_IRQ_STACK .space 76 - /****************************************** - ** Global Descriptor Table (GDT) ** - ** See Intel SDM Vol. 3A, section 3.5.1 ** - ******************************************/ - - .align 4 - .space 2 - - .global _mt_gdt_ptr - .global _mt_gdt_start - _mt_gdt_ptr: - .word _mt_gdt_end - _mt_gdt_start - 1 /* limit */ - .long _mt_gdt_start /* base address */ - - .align 8 - _mt_gdt_start: - /* Null descriptor */ - .quad 0 - /* 64-bit code segment descriptor */ - .long 0 - /* GDTE_LONG | GDTE_PRESENT | GDTE_CODE | GDTE_NON_SYSTEM */ - .long 0x209800 - /* 64-bit data segment descriptor */ - .long 0 - /* GDTE_LONG | GDTE_PRESENT | GDTE_TYPE_DATA_A | GDTE_TYPE_DATA_W | GDTE_NON_SYSTEM */ - .long 0x209300 - /* 64-bit user code segment descriptor */ - .long 0 - /* GDTE_LONG | GDTE_PRESENT | GDTE_CODE | GDTE_NON_SYSTEM */ - .long 0x20f800 - /* 64-bit user data segment descriptor */ - .long 0 - /* GDTE_LONG | GDTE_PRESENT | GDTE_TYPE_DATA_A | GDTE_TYPE_DATA_W | GDTE_NON_SYSTEM */ - .long 0x20f300 - /* Task segment descriptor */ - .long (MT_TSS & 0xffff) << 16 | TSS_LIMIT - /* GDTE_PRESENT | GDTE_SYS_TSS */ - .long ((MT_TSS >> 24) & 0xff) << 24 | ((MT_TSS >> 16) & 0xff) | TSS_TYPE - .long MT_TSS >> 32 - .long 0 - .global _mt_gdt_end - _mt_gdt_end: + _define_gdt MT_TSS /************************************************ ** Temporary interrupt stack ** diff --git a/repos/base-hw/src/core/spec/x86_64/muen/platform_support.cc b/repos/base-hw/src/core/spec/x86_64/muen/platform_support.cc index 0a9f9ee2b..6fff07d3e 100644 --- a/repos/base-hw/src/core/spec/x86_64/muen/platform_support.cc +++ b/repos/base-hw/src/core/spec/x86_64/muen/platform_support.cc @@ -59,18 +59,6 @@ struct Msi_address : Register<32> }; -Memory_region_array & Platform::core_mmio_regions() -{ - return *unmanaged_singleton( - Memory_region { Sinfo::PHYSICAL_BASE_ADDR, /* Sinfo pages */ - Sinfo::SIZE }, - Memory_region { Board::TIMER_BASE_ADDR, /* Timer page */ - Board::TIMER_SIZE }, - Memory_region { Board::TIMER_PREEMPT_BASE_ADDR, /* Timed event page */ - Board::TIMER_PREEMPT_SIZE }); /* for preemption */ -} - - void Platform::setup_irq_mode(unsigned, unsigned, unsigned) { } @@ -99,21 +87,6 @@ bool Platform::get_msi_params(const addr_t mmconf, addr_t &address, } -Memory_region_array & Platform::ram_regions() -{ - static Memory_region_array ram; - - if (ram.count() == 0) { - struct Sinfo::Memregion_info region; - if (!sinfo()->get_memregion_info("ram", ®ion)) - error("Unable to retrieve base-hw ram region"); - else - ram.add(Memory_region { region.address, region.size }); - } - return ram; -} - - void Platform::_init_additional() { /* export subject info page as ROM module */ diff --git a/repos/base-hw/src/core/spec/x86_64/pic.cc b/repos/base-hw/src/core/spec/x86_64/pic.cc index 79dedac3c..bf69f912d 100644 --- a/repos/base-hw/src/core/spec/x86_64/pic.cc +++ b/repos/base-hw/src/core/spec/x86_64/pic.cc @@ -17,7 +17,8 @@ /* core includes */ #include -#include "pic.h" +#include +#include using namespace Genode; @@ -28,7 +29,7 @@ enum { PIC_DATA_SLAVE = 0xa1, }; -Pic::Pic() : Mmio(Board::MMIO_LAPIC_BASE) +Pic::Pic() : Mmio(Platform::mmio_to_virt(Board::MMIO_LAPIC_BASE)) { /* Start initialization sequence in cascade mode */ outb(PIC_CMD_MASTER, 0x11); @@ -83,6 +84,20 @@ void Pic::mask(unsigned const i) ioapic.toggle_mask(i, true); } +inline unsigned Pic::get_lowest_bit(void) +{ + unsigned bit, vec_base = 0; + + for (unsigned i = 0; i < 8 * 4; i += 4) { + bit = __builtin_ffs(read(i)); + if (bit) { + return vec_base + bit; + } + vec_base += 32; + } + return 0; +} + Ioapic::Irq_mode Ioapic::_irq_mode[IRQ_COUNT]; void Ioapic::setup_irq_mode(unsigned irq_number, unsigned trigger, @@ -123,3 +138,83 @@ void Ioapic::setup_irq_mode(unsigned irq_number, unsigned trigger, if (needs_sync) _update_irt_entry(irq_nr); } + + +void Ioapic::_update_irt_entry(unsigned irq) +{ + Irte::access_t irte; + + write(IOREDTBL + 2 * irq); + irte = read(); + + Irte::Pol::set(irte, _irq_mode[irq].polarity); + Irte::Trg::set(irte, _irq_mode[irq].trigger_mode); + + write(IOREDTBL + 2 * irq); + write(irte); +} + + +Irte::access_t Ioapic::_create_irt_entry(unsigned const irq) +{ + Irte::access_t irte = REMAP_BASE + irq; + Irte::Mask::set(irte, 1); + + Irte::Pol::set(irte, _irq_mode[irq].polarity); + Irte::Trg::set(irte, _irq_mode[irq].trigger_mode); + + return irte; +} + + +Ioapic::Ioapic() : Mmio(Platform::mmio_to_virt(Board::MMIO_IOAPIC_BASE)) +{ + for (unsigned i = 0; i < IRQ_COUNT; i++) + { + /* set legacy/ISA IRQs to edge, high */ + if (i <= Board::ISA_IRQ_END) { + _irq_mode[i].trigger_mode = TRIGGER_EDGE; + _irq_mode[i].polarity = POLARITY_HIGH; + } else { + _irq_mode[i].trigger_mode = TRIGGER_LEVEL; + _irq_mode[i].polarity = POLARITY_LOW; + } + + /* remap all IRQs managed by I/O APIC */ + if (i < IRTE_COUNT) { + Irte::access_t irte = _create_irt_entry(i); + write(IOREDTBL + 2 * i + 1); + write(irte >> Iowin::ACCESS_WIDTH); + write(IOREDTBL + 2 * i); + write(irte); + } + } +}; + + +void Ioapic::toggle_mask(unsigned const vector, bool const set) +{ + /* + * Ignore toggle requests for vectors not handled by the I/O APIC. + */ + if (vector < REMAP_BASE || vector >= REMAP_BASE + IRTE_COUNT) { + return; + } + + const unsigned irq = vector - REMAP_BASE; + + /* + * Only mask existing RTEs and do *not* mask edge-triggered + * interrupts to avoid losing them while masked, see Intel + * 82093AA I/O Advanced Programmable Interrupt Controller + * (IOAPIC) specification, section 3.4.2, "Interrupt Mask" + * flag and edge-triggered interrupts or: + * http://yarchive.net/comp/linux/edge_triggered_interrupts.html + */ + if (_edge_triggered(irq) && set) { return; } + + write(IOREDTBL + (2 * irq)); + Irte::access_t irte = read(); + Irte::Mask::set(irte, set); + write(irte); +} diff --git a/repos/base-hw/src/core/spec/x86_64/platform_support.cc b/repos/base-hw/src/core/spec/x86_64/platform_support.cc index 87def75b6..3d7bf7c2d 100644 --- a/repos/base-hw/src/core/spec/x86_64/platform_support.cc +++ b/repos/base-hw/src/core/spec/x86_64/platform_support.cc @@ -13,69 +13,19 @@ /* core includes */ #include -#include -#include #include -#include - -#include using namespace Genode; -/* contains physical pointer to multiboot */ -extern "C" Genode::addr_t __initial_bx; void Platform::_init_additional() { }; -Memory_region_array & Platform::core_mmio_regions() -{ - return *unmanaged_singleton( - Memory_region { Board::MMIO_LAPIC_BASE, Board::MMIO_LAPIC_SIZE }, - Memory_region { Board::MMIO_IOAPIC_BASE, Board::MMIO_IOAPIC_SIZE }, - Memory_region { __initial_bx & ~0xFFFUL, get_page_size() }); -} - void Platform::setup_irq_mode(unsigned irq_number, unsigned trigger, - unsigned polarity) -{ - Kernel::pic()->ioapic.setup_irq_mode(irq_number, trigger, polarity); -} + unsigned polarity) { + Kernel::pic()->ioapic.setup_irq_mode(irq_number, trigger, polarity); } bool Platform::get_msi_params(const addr_t mmconf, addr_t &address, - addr_t &data, unsigned &irq_number) -{ - return false; -} - - -Memory_region_array & Platform::ram_regions() -{ - static Memory_region_array ram; - - /* initialize memory pool */ - if (ram.count() == 0) { - using Mmap = Multiboot_info::Mmap; - - for (unsigned i = 0; true; i++) { - Mmap v = Multiboot_info(__initial_bx).phys_ram(i); - if (!v.base) break; - - Mmap::Addr::access_t base = v.read(); - Mmap::Length::access_t size = v.read(); - - /* - * Exclude first physical page, so that it will become part of the - * MMIO allocator. The framebuffer requests this page as MMIO. - */ - if (base == 0 && size >= get_page_size()) { - base = get_page_size(); - size -= get_page_size(); - } - ram.add(Memory_region { base, size }); - } - } - - return ram; -} + addr_t &data, unsigned &irq_number) { + return false; } diff --git a/repos/base-hw/src/core/spec/x86_64/timer.cc b/repos/base-hw/src/core/spec/x86_64/timer.cc new file mode 100644 index 000000000..c07e4dfa8 --- /dev/null +++ b/repos/base-hw/src/core/spec/x86_64/timer.cc @@ -0,0 +1,88 @@ +/* + * \brief Timer driver for core + * \author Adrian-Ken Rueegsegger + * \author Reto Buerki + * \date 2015-02-06 + */ + +/* + * Copyright (C) 2015-2016 Genode Labs GmbH + * + * This file is part of the Genode OS framework, which is distributed + * under the terms of the GNU General Public License version 2. + */ + +/* core includes */ +#include +#include + +using namespace Genode; +using Kernel::time_t; + +uint32_t Timer::_pit_calc_timer_freq(void) +{ + uint32_t t_start, t_end; + + /* Set channel gate high and disable speaker */ + outb(PIT_CH2_GATE, (inb(0x61) & ~0x02) | 0x01); + + /* Set timer counter (mode 0, binary count) */ + outb(PIT_MODE, 0xb0); + outb(PIT_CH2_DATA, PIT_SLEEP_TICS & 0xff); + outb(PIT_CH2_DATA, PIT_SLEEP_TICS >> 8); + + write(~0U); + + t_start = read(); + while ((inb(PIT_CH2_GATE) & 0x20) == 0) + { + asm volatile("pause" : : : "memory"); + } + t_end = read(); + + write(0); + + return (t_start - t_end) / PIT_SLEEP_MS; +} + + +Timer::Timer() : Mmio(Platform::mmio_to_virt(Board::MMIO_LAPIC_BASE)) +{ + write( + Divide_configuration::Divide_value::MAX); + + /* Enable LAPIC timer in one-shot mode */ + write(Board::TIMER_VECTOR_KERNEL); + write(0); + write(0); + write(0); + + /* Calculate timer frequency */ + _tics_per_ms = _pit_calc_timer_freq(); +} + + +void Timer::disable_pit() +{ + outb(PIT_MODE, 0x30); + outb(PIT_CH0_DATA, 0); + outb(PIT_CH0_DATA, 0); +} + + +void Timer::start_one_shot(time_t const tics, unsigned const) { + write(tics); } + + +time_t Timer::tics_to_us(time_t const tics) const { + return (tics / _tics_per_ms) * 1000; } + + +time_t Timer::us_to_tics(time_t const us) const { + return (us / 1000) * _tics_per_ms; } + + +time_t Timer::max_value() { return (Tmr_initial::access_t)~0; } + + +time_t Timer::value(unsigned const) { return read(); } diff --git a/repos/base-hw/src/core/spec/zynq/platform_support.cc b/repos/base-hw/src/core/spec/zynq/platform_support.cc index 2134b8657..e54b30c8b 100644 --- a/repos/base-hw/src/core/spec/zynq/platform_support.cc +++ b/repos/base-hw/src/core/spec/zynq/platform_support.cc @@ -13,37 +13,6 @@ */ /* core includes */ -#include -#include #include -#include - -/* base-internal includes */ -#include - -using namespace Genode; - -Memory_region_array & Platform::ram_regions() -{ - return *unmanaged_singleton( - Memory_region { Board::RAM_0_BASE, Board::RAM_0_SIZE }); -} - - -Memory_region_array & Platform::core_mmio_regions() -{ - return *unmanaged_singleton( - Memory_region { Board::CORTEX_A9_PRIVATE_MEM_BASE, /* timer and PIC */ - Board::CORTEX_A9_PRIVATE_MEM_SIZE }, - Memory_region { Board::KERNEL_UART_BASE, /* UART */ - Board::KERNEL_UART_SIZE }, - Memory_region { Board::PL310_MMIO_BASE, /* L2 cache controller */ - Board::PL310_MMIO_SIZE }); -} - Genode::Arm::User_context::User_context() { cpsr = Psr::init_user(); } - - -bool Cortex_a9::Board::errata(Cortex_a9::Board::Errata err) { - return false; } diff --git a/repos/base-hw/src/core/thread_start.cc b/repos/base-hw/src/core/thread_start.cc index 20b8b5242..734b37136 100644 --- a/repos/base-hw/src/core/thread_start.cc +++ b/repos/base-hw/src/core/thread_start.cc @@ -64,7 +64,7 @@ void Thread::_init_platform_thread(size_t, Type type) } /* remap initial main-thread UTCB according to stack-area spec */ - Genode::map_local((addr_t)Kernel::Core_thread::singleton().utcb(), + Genode::map_local(Platform::core_phys_addr((addr_t)Kernel::Core_thread::singleton().utcb()), (addr_t)&_stack->utcb(), max(sizeof(Native_utcb) / get_page_size(), (size_t)1)); diff --git a/repos/base/include/spec/exynos5/board_base.h b/repos/base/include/spec/exynos5/board_base.h index 7ac2927f7..5f55f5dac 100644 --- a/repos/base/include/spec/exynos5/board_base.h +++ b/repos/base/include/spec/exynos5/board_base.h @@ -35,6 +35,7 @@ struct Genode::Exynos5 IRQ_CONTROLLER_BASE = 0x10480000, IRQ_CONTROLLER_SIZE = 0x00010000, IRQ_CONTROLLER_VT_CTRL_BASE = 0x10484000, + IRQ_CONTROLLER_VT_CTRL_SIZE = 0x1000, IRQ_CONTROLLER_VT_CPU_BASE = 0x10486000, IRQ_CONTROLLER_VT_CPU_SIZE = 0x1000, @@ -44,6 +45,7 @@ struct Genode::Exynos5 /* UART */ UART_2_MMIO_BASE = 0x12C20000, + UART_2_MMIO_SIZE = 0x1000, UART_2_IRQ = 85, /* pulse-width-modulation timer */ diff --git a/tool/run/boot_dir/hw b/tool/run/boot_dir/hw index 3b6c54858..6db3251d7 100644 --- a/tool/run/boot_dir/hw +++ b/tool/run/boot_dir/hw @@ -6,8 +6,7 @@ proc binary_name_gpio_drv { } { return "hw_gpio_drv" } proc run_boot_string { } { return "\nkernel initialized" } - -proc core_link_address { } { +proc bootstrap_link_address { } { if {[have_spec "odroid_xu"]} { return "0x80000000" } if {[have_spec "pbxa9"]} { return "0x70000000" } if {[have_spec "usb_armory"]} { return "0x72000000" } @@ -24,6 +23,12 @@ proc core_link_address { } { exit -1 } +proc core_link_address { } { + if {[have_spec "riscv"]} { return "0x1000000" } + scan [bootstrap_link_address] 0x%x link_address + return [format 0x%08x [expr {$link_address + 0x10000000}]] +} + ## # Populate boot directory with binaries on hw @@ -37,9 +42,31 @@ proc run_boot_dir {binaries} { close $fh } - build { lib/ld/hw } + build { lib/ld/hw bootstrap } - build_core_image $binaries + # boot module list without core + set idx [lsearch $binaries "core"] + set modules [lreplace $binaries $idx $idx] + + # strip binaries + copy_and_strip_genode_binaries_to_run_dir $modules + lappend modules "config" + + puts "core link address is [core_link_address]" + + set core_obj core/hw/core.o + set bootstrap_obj bootstrap/hw/bootstrap.o + + # create core and bootstrap binary without modules for debugging + build_core $core_obj {} [run_dir].core [core_link_address] + build_core $bootstrap_obj {} [run_dir].bootstrap [bootstrap_link_address] + + # create core binary containing the boot modules + build_core $core_obj $modules [run_dir]/genode/core.elf [core_link_address] + exec [cross_dev_prefix]strip [run_dir]/genode/core.elf + build_core $bootstrap_obj { core.elf } [run_dir]/image.elf [bootstrap_link_address] + exec rm -f [run_dir]/genode/core.elf + exec [cross_dev_prefix]strip [run_dir]/image.elf if {[have_include "image/iso"] || [have_include "image/disk"]} { #