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