[Skiboot] [PATCH 12/33] Timebase quirk for slow simulators like AWAN and SIMICS

Benjamin Herrenschmidt benh at kernel.crashing.org
Sat Jun 25 08:47:35 AEST 2016


This will internally pretend the timebase is running 1000 times
slower, which reduces some otherwise really terrible delays in
some simulators.

Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
---
 core/chip.c              | 13 ++++++++++++-
 core/test/run-timebase.c |  2 ++
 core/test/run-timer.c    |  2 ++
 core/timebase.c          |  8 +++++++-
 hdata/test/hdata_to_dt.c |  2 ++
 hw/xscom.c               |  3 ++-
 include/chip.h           |  1 +
 include/timebase.h       |  2 +-
 8 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/core/chip.c b/core/chip.c
index b9297e1..2651ad4 100644
--- a/core/chip.c
+++ b/core/chip.c
@@ -18,6 +18,7 @@
 #include <skiboot.h>
 #include <chip.h>
 #include <device.h>
+#include <timebase.h>
 
 static struct proc_chip *chips[MAX_CHIPS];
 enum proc_chip_quirks proc_chip_quirks;
@@ -81,11 +82,21 @@ void init_chips(void)
 			| QUIRK_NO_F000F | QUIRK_NO_PBA | QUIRK_NO_OCC_IRQ;
 		prlog(PR_NOTICE, "CHIP: Detected Mambo simulator\n");
 	}
+	/* Detect simics */
 	if (dt_find_by_path(dt_root, "/simics")) {
 		proc_chip_quirks |= QUIRK_SIMICS | QUIRK_NO_CHIPTOD
-			| QUIRK_NO_PBA | QUIRK_NO_OCC_IRQ;
+			| QUIRK_NO_PBA | QUIRK_NO_OCC_IRQ | QUIRK_SLOW_SIM;
+		tb_hz = 512000;
 		prlog(PR_NOTICE, "CHIP: Detected Simics simulator\n");
 	}
+	/* Detect Awan emulator */
+	if (dt_find_by_path(dt_root, "/awan")) {
+		proc_chip_quirks |= QUIRK_NO_CHIPTOD | QUIRK_NO_F000F
+			| QUIRK_NO_PBA | QUIRK_NO_OCC_IRQ | QUIRK_SLOW_SIM;
+		tb_hz = 512000;
+		prlog(PR_NOTICE, "CHIP: Detected Awan emulator\n");
+	}
+	/* Detect Qemu */
 	if (dt_node_is_compatible(dt_root, "qemu,powernv")) {
 		proc_chip_quirks |= QUIRK_NO_CHIPTOD | QUIRK_NO_PBA;
 		prlog(PR_NOTICE, "CHIP: Detected Qemu simulator\n");
diff --git a/core/test/run-timebase.c b/core/test/run-timebase.c
index 2d4c83d..38c41fd 100644
--- a/core/test/run-timebase.c
+++ b/core/test/run-timebase.c
@@ -22,6 +22,8 @@
 #define __TEST__
 #include <timebase.h>
 
+unsigned long tb_hz = 512000000;
+
 int main(void)
 {
 	/* This is a fairly solid assumption that the math we're doing
diff --git a/core/test/run-timer.c b/core/test/run-timer.c
index e1a7cef..75c40fe 100644
--- a/core/test/run-timer.c
+++ b/core/test/run-timer.c
@@ -13,6 +13,8 @@ struct lock;
 static inline void lock(struct lock *l) { (void)l; }
 static inline void unlock(struct lock *l) { (void)l; }
 
+unsigned long tb_hz = 512000000;
+
 #include "../timer.c"
 
 #define NUM_TIMERS	100
diff --git a/core/timebase.c b/core/timebase.c
index 4fcfae5..0714f25 100644
--- a/core/timebase.c
+++ b/core/timebase.c
@@ -18,6 +18,9 @@
 #include <timebase.h>
 #include <opal.h>
 #include <cpu.h>
+#include <chip.h>
+
+unsigned long tb_hz = 512000000;
 
 static void time_wait_poll(unsigned long duration)
 {
@@ -108,7 +111,10 @@ unsigned long timespec_to_tb(const struct timespec *ts)
 	 * at the expense of capacity or do 128 bit math which
 	 * I'm not eager to do :-)
 	 */
-	return (ns * (tb_hz >> 24)) / (1000000000ul >> 24);
+	if (chip_quirk(QUIRK_SLOW_SIM))
+		return (ns * (tb_hz >> 16)) / (1000000000ul >> 16);
+	else
+		return (ns * (tb_hz >> 24)) / (1000000000ul >> 24);
 }
 
 int nanosleep(const struct timespec *req, struct timespec *rem)
diff --git a/hdata/test/hdata_to_dt.c b/hdata/test/hdata_to_dt.c
index 2ed683e..86fdf5c 100644
--- a/hdata/test/hdata_to_dt.c
+++ b/hdata/test/hdata_to_dt.c
@@ -46,6 +46,8 @@ static void *ntuple_addr(const struct spira_ntuple *n);
 #define __this_cpu ((struct cpu_thread *)NULL)
 #define zalloc(expr) calloc(1, (expr))
 
+unsigned long tb_hz = 512000000;
+
 /* Don't include processor-specific stuff. */
 #define __PROCESSOR_H
 #define PVR_TYPE(_pvr)	_pvr
diff --git a/hw/xscom.c b/hw/xscom.c
index f8a6402..cb5a4a7 100644
--- a/hw/xscom.c
+++ b/hw/xscom.c
@@ -442,9 +442,10 @@ int64_t xscom_read_cfam_chipid(uint32_t partid, uint32_t *chip_id)
 	 * something up
 	 */
 	if (chip_quirk(QUIRK_NO_F000F)) {
-		val = 0x221EF04980000000UL; /* P8 Murano DD2.1 */
 		if (proc_gen == proc_gen_p9)
 			val = 0x100D104980000000UL; /* P9 Nimbus DD1.0 */
+		else
+			val = 0x221EF04980000000UL; /* P8 Murano DD2.1 */
 	} else
 		rc = xscom_read(partid, 0xf000f, &val);
 
diff --git a/include/chip.h b/include/chip.h
index 0038814..4541368 100644
--- a/include/chip.h
+++ b/include/chip.h
@@ -127,6 +127,7 @@ enum proc_chip_quirks {
 	QUIRK_NO_PBA		= 0x00000008,
 	QUIRK_NO_OCC_IRQ       	= 0x00000010,
 	QUIRK_SIMICS		= 0x00000020,
+	QUIRK_SLOW_SIM		= 0x00000040,
 } proc_chip_quirks;
 
 static inline bool chip_quirk(unsigned int q)
diff --git a/include/timebase.h b/include/timebase.h
index 7f5afe1..7fc4748 100644
--- a/include/timebase.h
+++ b/include/timebase.h
@@ -52,7 +52,7 @@ static inline enum tb_cmpval tb_compare(unsigned long a,
 }
 
 /* Architected timebase */
-static const unsigned long tb_hz = 512000000;
+extern unsigned long tb_hz;
 
 static inline unsigned long secs_to_tb(unsigned long secs)
 {
-- 
2.7.4



More information about the Skiboot mailing list