Add muen scheduling info as timer source
This is a very low precision clock. We just take the start of the cur-
rent scheduling minor frame as the minimum, yet elapsed moment and the
end of the frame as the maximum, yet reached moment in time. As a
result, every timer based delay will wait at least for the next minor
frame.
For the build, `musinfo.ads` and `muschedinfo.ads` from the Muen
project are required. One should point the `muen-common-path` variable
to the `common` subdir of the Muen source distribution.
Change-Id: Ib139749214bf8d2ca293e31327b156de5198b65d
Signed-off-by: Nico Huber <nico.huber@secunet.com>
Reviewed-on: https://review.coreboot.org/18357
Tested-by: Nico Huber <nico.h@gmx.de>
Reviewed-by: Adrian-Ken Rueegsegger <ken@codelabs.ch>
diff --git a/ada/Makefile.inc b/ada/Makefile.inc
index e09f1a5..2233094 100644
--- a/ada/Makefile.inc
+++ b/ada/Makefile.inc
@@ -1,3 +1,7 @@
hw-$(CONFIG_HWBASE_STATIC_MMIO) += static_mmio/hw-mmio_range.adb
hw-$(CONFIG_HWBASE_DYNAMIC_MMIO) += dynamic_mmio/hw-mmio_range.adb
hw-$(CONFIG_HWBASE_TIMER_CLOCK_GETTIME) += clock_gettime/hw-time-timer.adb
+
+hw-$(CONFIG_HWBASE_TIMER_MUTIME) += $(muen-common-path)/musinfo/musinfo.ads
+hw-$(CONFIG_HWBASE_TIMER_MUTIME) += $(muen-common-path)/muschedinfo/muschedinfo.ads
+hw-$(CONFIG_HWBASE_TIMER_MUTIME) += mutime/hw-time-timer.adb
diff --git a/ada/mutime/hw-time-timer.adb b/ada/mutime/hw-time-timer.adb
new file mode 100644
index 0000000..272289c
--- /dev/null
+++ b/ada/mutime/hw-time-timer.adb
@@ -0,0 +1,59 @@
+--
+-- Copyright (C) 2015-2016 secunet Security Networks AG
+--
+-- This program is free software; you can redistribute it and/or modify
+-- it under the terms of the GNU General Public License as published by
+-- the Free Software Foundation; version 2 of the License.
+--
+-- This program is distributed in the hope that it will be useful,
+-- but WITHOUT ANY WARRANTY; without even the implied warranty of
+-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+-- GNU General Public License for more details.
+--
+
+with System;
+
+with Musinfo;
+with Muschedinfo;
+
+package body HW.Time.Timer
+ with Refined_State => (Timer_State => null,
+ Abstract_Time => (Sinfo, Sched_Info))
+is
+ Sinfo_Base_Address : constant := 16#000e_0000_0000#;
+ Sinfo_Page_Size : constant
+ := ((Musinfo.Subject_Info_Type_Size + (16#1000# - 1))
+ / 16#1000#) * 16#1000#;
+
+ Sinfo : Musinfo.Subject_Info_Type
+ with
+ Address => System'To_Address (Sinfo_Base_Address);
+
+ Sched_Info : Muschedinfo.Scheduling_Info_Type
+ with
+ Volatile,
+ Async_Writers,
+ Address => System'To_Address (Sinfo_Base_Address + Sinfo_Page_Size);
+
+ function Raw_Value_Min return T
+ is
+ TSC_Schedule_Start : constant Interfaces.Unsigned_64
+ := Sched_Info.TSC_Schedule_Start;
+ begin
+ return T (TSC_Schedule_Start);
+ end Raw_Value_Min;
+
+ function Raw_Value_Max return T
+ is
+ TSC_Schedule_End : constant Interfaces.Unsigned_64
+ := Sched_Info.TSC_Schedule_End;
+ begin
+ return T (TSC_Schedule_End);
+ end Raw_Value_Max;
+
+ function Hz return T is
+ begin
+ return T (Sinfo.TSC_Khz) * 1000;
+ end Hz;
+
+end HW.Time.Timer;
diff --git a/configs/defconfig b/configs/defconfig
index 17bb699..eb8cafb 100644
--- a/configs/defconfig
+++ b/configs/defconfig
@@ -3,3 +3,4 @@
CONFIG_HWBASE_STATIC_MMIO = y
CONFIG_HWBASE_DYNAMIC_MMIO =
CONFIG_HWBASE_TIMER_CLOCK_GETTIME = y
+CONFIG_HWBASE_TIMER_MUTIME =