diff --git a/repos/base-hw/lib/mk/base-hw-common.mk b/repos/base-hw/lib/mk/base-hw-common.mk
index 76b64b739c..58506fd577 100644
--- a/repos/base-hw/lib/mk/base-hw-common.mk
+++ b/repos/base-hw/lib/mk/base-hw-common.mk
@@ -10,3 +10,8 @@ include $(BASE_DIR)/lib/mk/base-common.inc
SRC_CC += rpc_dispatch_loop.cc
SRC_CC += thread.cc thread_myself.cc thread_bootstrap.cc
SRC_CC += signal_transmitter.cc
+
+# filter out log.cc from the generic base library
+# in core and hw kernel we have to implement it differently
+SRC_CC_WITH_LOG_CC := $(SRC_CC)
+SRC_CC = $(filter-out log.cc,$(SRC_CC_WITH_LOG_CC))
diff --git a/repos/base-hw/lib/mk/base-hw.mk b/repos/base-hw/lib/mk/base-hw.mk
index 8aaf077421..ed1b684450 100644
--- a/repos/base-hw/lib/mk/base-hw.mk
+++ b/repos/base-hw/lib/mk/base-hw.mk
@@ -1,5 +1,6 @@
include $(BASE_DIR)/lib/mk/base.inc
+SRC_CC += log.cc
SRC_CC += thread_start.cc
SRC_CC += capability.cc
SRC_CC += cache.cc
diff --git a/repos/base-hw/src/core/core_log_out.cc b/repos/base-hw/src/core/core_log_out.cc
index 2d555f12c1..70148f275a 100644
--- a/repos/base-hw/src/core/core_log_out.cc
+++ b/repos/base-hw/src/core/core_log_out.cc
@@ -12,15 +12,22 @@
* under the terms of the GNU Affero General Public License version 3.
*/
+/* Genode includes */
+#include
+#include
+
/* base-internal includes */
#include
#include
#include
+#include
#include
+using namespace Genode;
-void Genode::Core_log::out(char const c) { Kernel::log(c); }
+
+void Core_log::out(char const c) { Kernel::log(c); }
void Genode::raw_write_string(char const *str)
@@ -28,3 +35,75 @@ void Genode::raw_write_string(char const *str)
while (char c = *str++)
Kernel::log(c);
}
+
+
+/************************************************************
+ ** Utility to check whether kernel or core code is active **
+ ************************************************************/
+
+extern void const * const kernel_stack;
+
+static inline bool running_in_kernel()
+{
+ addr_t const stack_base = reinterpret_cast(&kernel_stack);
+ static constexpr size_t stack_size =
+ NR_OF_CPUS * Kernel::Cpu::KERNEL_STACK_SIZE;
+
+ /* check stack variable against kernel stack area */
+ return ((addr_t)&stack_base) >= stack_base &&
+ ((addr_t)&stack_base) < (stack_base + stack_size);
+}
+
+
+/*******************************************
+ ** Implementation of src/lib/base/log.cc **
+ *******************************************/
+
+void Log::_acquire(Type type)
+{
+ if (!running_in_kernel()) _mutex.acquire();
+
+ /*
+ * Mark warnings and errors via distinct colors.
+ */
+ switch (type) {
+ case LOG: break;
+ case WARNING: _output.out_string("\033[34mWarning: "); break;
+ case ERROR: _output.out_string("\033[31mError: "); break;
+ };
+}
+
+
+void Log::_release()
+{
+ /*
+ * Reset color and add newline
+ */
+ _output.out_string("\033[0m\n");
+
+ if (!running_in_kernel()) _mutex.release();
+}
+
+
+void Raw::_acquire()
+{
+ /*
+ * Mark raw output with distinct color
+ */
+ _output().out_string("\033[32mKernel: ");
+}
+
+
+void Raw::_release()
+{
+ /*
+ * Reset color and add newline
+ */
+ _output().out_string("\033[0m\n");
+}
+
+
+void Trace_output::Write_trace_fn::operator () (char const *s)
+{
+ Thread::trace(s);
+}