diff mbox

[v3,2/4] Move P8 timer code to separate file

Message ID 1489467718-10273-2-git-send-email-hegdevasant@linux.vnet.ibm.com
State Superseded
Headers show

Commit Message

Vasant Hegde March 14, 2017, 5:01 a.m. UTC
Lets move P8 timer support code from slw.c to sbe_p8.c (as suggested
by Ben). There is a difference between timer support in P8 and P9.
Hence I think it makes sense to name it as sbe_p8.c

Note that this is pure code movement and renaming functions/variables.
No functionality changes.

Suggested-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Signed-off-by: Vasant Hegde <hegdevasant@linux.vnet.ibm.com>
---
 core/interrupts.c |   3 +-
 core/timer.c      |   7 +-
 hw/Makefile.inc   |   2 +-
 hw/sbe_p8.c       | 203 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 hw/slw.c          | 185 +------------------------------------------------
 include/sbe_p8.h  |  29 ++++++++
 include/skiboot.h |   6 --
 7 files changed, 241 insertions(+), 194 deletions(-)
 create mode 100644 hw/sbe_p8.c
 create mode 100644 include/sbe_p8.h

Comments

Vasant Hegde March 14, 2017, 5:08 a.m. UTC | #1
On 03/14/2017 10:31 AM, Vasant Hegde wrote:
> Lets move P8 timer support code from slw.c to sbe_p8.c (as suggested
> by Ben). There is a difference between timer support in P8 and P9.
> Hence I think it makes sense to name it as sbe_p8.c
>
> Note that this is pure code movement and renaming functions/variables.
> No functionality changes.

@Ben,
   As you suggested, I moved P8 timer code to separate file. But now I'm 
thinking it may be good to have single file (sbe.c) and add all SBE related code 
their (both P8 timer code and new P9 code).

In P8, we have used direct SCOMs for SBE timer. But from P9 onwards we are 
getting MBOX messages for SBE operations. So we can have something like below


void sbe_timer_init(void)
{
	if (proc_gen == proc_gen_p8)
		p8_sbe_timer();
	else
		sbe_timer();
}

Let me know which one is better.

-Vasant
Benjamin Herrenschmidt March 14, 2017, 6:03 a.m. UTC | #2
On Tue, 2017-03-14 at 10:38 +0530, Vasant Hegde wrote:
> @Ben,
>    As you suggested, I moved P8 timer code to separate file. But now I'm 
> thinking it may be good to have single file (sbe.c) and add all SBE related code 
> their (both P8 timer code and new P9 code).
> 
> In P8, we have used direct SCOMs for SBE timer. But from P9 onwards we are 
> getting MBOX messages for SBE operations. So we can have something like below
> 
> 
> void sbe_timer_init(void)
> {
>         if (proc_gen == proc_gen_p8)
>                 p8_sbe_timer();
>         else
>                 sbe_timer();
> }
> 
> Let me know which one is better.

What would you win by having a single file other than more clutter ?

I prefer keeping them separate as they have strictly nothing in common.

Cheers,
Ben.
Vasant Hegde March 14, 2017, 6:16 a.m. UTC | #3
On 03/14/2017 11:33 AM, Benjamin Herrenschmidt wrote:
> On Tue, 2017-03-14 at 10:38 +0530, Vasant Hegde wrote:
>> @Ben,
>>     As you suggested, I moved P8 timer code to separate file. But now I'm
>> thinking it may be good to have single file (sbe.c) and add all SBE related code
>> their (both P8 timer code and new P9 code).
>>
>> In P8, we have used direct SCOMs for SBE timer. But from P9 onwards we are
>> getting MBOX messages for SBE operations. So we can have something like below
>>
>>
>> void sbe_timer_init(void)
>> {
>>          if (proc_gen == proc_gen_p8)
>>                  p8_sbe_timer();
>>          else
>>                  sbe_timer();
>> }
>>
>> Let me know which one is better.
>
> What would you win by having a single file other than more clutter ?

Nothing much except number of files ;-)

>
> I prefer keeping them separate as they have strictly nothing in common.

Agree. There is no common code. I will keep it as separate and changes p9 
function to something like

p9_sbe_*()

Thanks!

-Vasant
diff mbox

Patch

diff --git a/core/interrupts.c b/core/interrupts.c
index 006d555..3567e2c 100644
--- a/core/interrupts.c
+++ b/core/interrupts.c
@@ -25,6 +25,7 @@ 
 #include <device.h>
 #include <ccan/str/str.h>
 #include <timer.h>
+#include <sbe_p8.h>
 
 /* ICP registers */
 #define ICP_XIRR		0x4	/* 32-bit access */
@@ -457,7 +458,7 @@  static int64_t opal_handle_interrupt(uint32_t isn, __be64 *outstanding_event_mas
 	is->ops->interrupt(is, isn);
 
 	/* Check timers if SLW timer isn't working */
-	if (!slw_timer_ok())
+	if (!p8_sbe_timer_ok())
 		check_timers(true);
 
 	/* Update output events */
diff --git a/core/timer.c b/core/timer.c
index 7548996..84d4aa8 100644
--- a/core/timer.c
+++ b/core/timer.c
@@ -4,6 +4,7 @@ 
 #include <fsp.h>
 #include <device.h>
 #include <opal.h>
+#include <sbe_p8.h>
 
 #ifdef __TEST__
 #define this_cpu()	((void *)-1)
@@ -106,7 +107,7 @@  static void __schedule_timer_at(struct timer *t, uint64_t when)
 	/* Pick up the next timer and upddate the SBE HW timer */
 	lt = list_top(&timer_list, struct timer, link);
 	if (lt)
-		slw_update_timer_expiry(lt->target);
+		p8_sbe_update_timer_expiry(lt->target);
 }
 
 void schedule_timer_at(struct timer *t, uint64_t when)
@@ -163,7 +164,7 @@  static void __check_poll_timers(uint64_t now)
 		 * arbitrarily 1us.
 		 */
 		if (t->running) {
-			slw_update_timer_expiry(now + usecs_to_tb(1));
+			p8_sbe_update_timer_expiry(now + usecs_to_tb(1));
 			break;
 		}
 
@@ -261,7 +262,7 @@  void late_init_timers(void)
 	 */
 	if (platform.heartbeat_time) {
 		heartbeat = platform.heartbeat_time();
-	} else if (slw_timer_ok() || fsp_present()) {
+	} else if (p8_sbe_timer_ok() || fsp_present()) {
 		heartbeat = HEARTBEAT_DEFAULT_MS * 10;
 	}
 
diff --git a/hw/Makefile.inc b/hw/Makefile.inc
index d87f85e..96a99e1 100644
--- a/hw/Makefile.inc
+++ b/hw/Makefile.inc
@@ -6,7 +6,7 @@  HW_OBJS += nx.o nx-rng.o nx-crypto.o nx-842.o
 HW_OBJS += p7ioc.o p7ioc-inits.o p7ioc-phb.o
 HW_OBJS += phb3.o sfc-ctrl.o fake-rtc.o bt.o p8-i2c.o prd.o
 HW_OBJS += dts.o lpc-rtc.o npu.o npu-hw-procedures.o xive.o phb4.o
-HW_OBJS += fake-nvram.o lpc-mbox.o
+HW_OBJS += fake-nvram.o lpc-mbox.o sbe_p8.o
 HW=hw/built-in.o
 
 # FIXME hack this for now
diff --git a/hw/sbe_p8.c b/hw/sbe_p8.c
new file mode 100644
index 0000000..b32872d
--- /dev/null
+++ b/hw/sbe_p8.c
@@ -0,0 +1,203 @@ 
+/* Copyright 2013-2017 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *	http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <device.h>
+#include <sbe_p8.h>
+#include <skiboot.h>
+#include <timebase.h>
+#include <xscom.h>
+
+/* SLW timer related stuff */
+static bool sbe_has_timer;
+static uint64_t sbe_timer_inc;
+static uint64_t sbe_timer_target;
+static uint32_t sbe_timer_chip;
+static uint64_t sbe_last_gen;
+static uint64_t sbe_last_gen_stamp;
+
+static void p8_sbe_dump_timer_ffdc(void)
+{
+	uint64_t i, val;
+	int64_t rc;
+
+	static const uint32_t dump_regs[] = {
+		0xe0000, 0xe0001, 0xe0002, 0xe0003,
+		0xe0004, 0xe0005, 0xe0006, 0xe0007,
+		0xe0008, 0xe0009, 0xe000a, 0xe000b,
+		0xe000c, 0xe000d, 0xe000e, 0xe000f,
+		0xe0010, 0xe0011, 0xe0012, 0xe0013,
+		0xe0014, 0xe0015, 0xe0016, 0xe0017,
+		0xe0018, 0xe0019,
+		0x5001c,
+		0x50038, 0x50039, 0x5003a, 0x5003b
+	};
+
+	/**
+	 * @fwts-label SLWRegisterDump
+	 * @fwts-advice An error condition occurred in sleep/winkle
+	 * engines timer state machine. Dumping debug information to
+	 * root-cause. OPAL/skiboot may be stuck on some operation that
+	 * requires SLW timer state machine (e.g. core powersaving)
+	 */
+	prlog(PR_DEBUG, "SLW: Register state:\n");
+
+	for (i = 0; i < ARRAY_SIZE(dump_regs); i++) {
+		uint32_t reg = dump_regs[i];
+		rc = xscom_read(sbe_timer_chip, reg, &val);
+		if (rc) {
+			prlog(PR_DEBUG, "SLW: XSCOM error %lld reading"
+			      " reg 0x%x\n", rc, reg);
+			break;
+		}
+		prlog(PR_DEBUG, "SLW:  %5x = %016llx\n", reg, val);
+	}
+}
+
+/* This is called with the timer lock held, so there is no
+ * issue with re-entrancy or concurrence
+ */
+void p8_sbe_update_timer_expiry(uint64_t new_target)
+{
+	uint64_t count, gen, gen2, req, now = mftb();
+	int64_t rc;
+
+	if (!sbe_has_timer || new_target == sbe_timer_target)
+		return;
+
+	sbe_timer_target = new_target;
+
+	/* Calculate how many increments from now, rounded up */
+	if (now < new_target)
+		count = (new_target - now + sbe_timer_inc - 1) / sbe_timer_inc;
+	else
+		count = 1;
+
+	/* Max counter is 24-bit */
+	if (count > 0xffffff)
+		count = 0xffffff;
+	/* Fabricate update request */
+	req = (1ull << 63) | (count << 32);
+
+	prlog(PR_TRACE, "SLW: TMR expiry: 0x%llx, req: %016llx\n", count, req);
+
+	do {
+		/* Grab generation and spin if odd */
+		_xscom_lock();
+		for (;;) {
+			rc = _xscom_read(sbe_timer_chip, 0xE0006, &gen, false);
+			if (rc) {
+				prerror("SLW: Error %lld reading tmr gen "
+					" count\n", rc);
+				_xscom_unlock();
+				return;
+			}
+			if (!(gen & 1))
+				break;
+			if (tb_compare(now + msecs_to_tb(1), mftb()) == TB_ABEFOREB) {
+				/**
+				 * @fwts-label SLWTimerStuck
+				 * @fwts-advice The SLeep/Winkle Engine (SLW)
+				 * failed to increment the generation number
+				 * within our timeout period (it *should* have
+				 * done so within ~10us, not >1ms. OPAL uses
+				 * the SLW timer to schedule some operations,
+				 * but can fall back to the (much less frequent
+				 * OPAL poller, which although does not affect
+				 * functionality, runs *much* less frequently.
+				 * This could have the effect of slow I2C
+				 * operations (for example). It may also mean
+				 * that you *had* an increase in jitter, due
+				 * to slow interactions with SLW.
+				 * This error may also occur if the machine
+				 * is connected to via soft FSI.
+				 */
+				prerror("SLW: timer stuck, falling back to OPAL pollers. You will likely have slower I2C and may have experienced increased jitter.\n");
+				prlog(PR_DEBUG, "SLW: Stuck with odd generation !\n");
+				_xscom_unlock();
+				sbe_has_timer = false;
+				p8_sbe_dump_timer_ffdc();
+				return;
+			}
+		}
+
+		rc = _xscom_write(sbe_timer_chip, 0x5003A, req, false);
+		if (rc) {
+			prerror("SLW: Error %lld writing tmr request\n", rc);
+			_xscom_unlock();
+			return;
+		}
+
+		/* Re-check gen count */
+		rc = _xscom_read(sbe_timer_chip, 0xE0006, &gen2, false);
+		if (rc) {
+			prerror("SLW: Error %lld re-reading tmr gen "
+				" count\n", rc);
+			_xscom_unlock();
+			return;
+		}
+		_xscom_unlock();
+	} while(gen != gen2);
+
+	/* Check if the timer is working. If at least 1ms has elapsed
+	 * since the last call to this function, check that the gen
+	 * count has changed
+	 */
+	if (tb_compare(sbe_last_gen_stamp + msecs_to_tb(1), now)
+	    == TB_ABEFOREB) {
+		if (sbe_last_gen == gen) {
+			prlog(PR_ERR,
+			      "SLW: Timer appears to not be running !\n");
+			sbe_has_timer = false;
+			p8_sbe_dump_timer_ffdc();
+		}
+		sbe_last_gen = gen;
+		sbe_last_gen_stamp = mftb();
+	}
+
+	prlog(PR_TRACE, "SLW: gen: %llx\n", gen);
+}
+
+bool p8_sbe_timer_ok(void)
+{
+	return sbe_has_timer;
+}
+
+void p8_sbe_init_timer(void)
+{
+	struct dt_node *np;
+	int64_t rc;
+	uint32_t tick_us;
+
+	np = dt_find_compatible_node(dt_root, NULL, "ibm,power8-sbe-timer");
+	if (!np)
+		return;
+
+	sbe_timer_chip = dt_get_chip_id(np);
+	tick_us = dt_prop_get_u32(np, "tick-time-us");
+	sbe_timer_inc = usecs_to_tb(tick_us);
+	sbe_timer_target = ~0ull;
+
+	rc = xscom_read(sbe_timer_chip, 0xE0006, &sbe_last_gen);
+	if (rc) {
+		prerror("SLW: Error %lld reading tmr gen count\n", rc);
+		return;
+	}
+	sbe_last_gen_stamp = mftb();
+
+	prlog(PR_INFO, "SLW: Timer facility on chip %d, resolution %dus\n",
+	      sbe_timer_chip, tick_us);
+	sbe_has_timer = true;
+}
diff --git a/hw/slw.c b/hw/slw.c
index bea1028..5f47b1b 100644
--- a/hw/slw.c
+++ b/hw/slw.c
@@ -29,6 +29,7 @@ 
 #include <errorlog.h>
 #include <libfdt/libfdt.h>
 #include <opal-api.h>
+#include <sbe_p8.h>
 
 #ifdef __HAVE_LIBPORE__
 #include <p8_pore_table_gen_api.H>
@@ -41,14 +42,6 @@  static uint32_t slw_saved_reset[MAX_RESET_PATCH_SIZE];
 static bool slw_current_le = false;
 #endif /* __HAVE_LIBPORE__ */
 
-/* SLW timer related stuff */
-static bool slw_has_timer;
-static uint64_t slw_timer_inc;
-static uint64_t slw_timer_target;
-static uint32_t slw_timer_chip;
-static uint64_t slw_last_gen;
-static uint64_t slw_last_gen_stamp;
-
 DEFINE_LOG_ENTRY(OPAL_RC_SLW_INIT, OPAL_PLATFORM_ERR_EVT, OPAL_SLW,
 		 OPAL_PLATFORM_FIRMWARE, OPAL_PREDICTIVE_ERR_GENERAL,
 		 OPAL_NA);
@@ -1262,180 +1255,6 @@  int64_t opal_slw_set_reg(uint64_t cpu_pir, uint64_t sprn, uint64_t val)
 opal_call(OPAL_SLW_SET_REG, opal_slw_set_reg, 3);
 #endif /* __HAVE_LIBPORE__ */
 
-static void slw_dump_timer_ffdc(void)
-{
-	uint64_t i, val;
-	int64_t rc;
-
-	static const uint32_t dump_regs[] = {
-		0xe0000, 0xe0001, 0xe0002, 0xe0003,
-		0xe0004, 0xe0005, 0xe0006, 0xe0007,
-		0xe0008, 0xe0009, 0xe000a, 0xe000b,
-		0xe000c, 0xe000d, 0xe000e, 0xe000f,
-		0xe0010, 0xe0011, 0xe0012, 0xe0013,
-		0xe0014, 0xe0015, 0xe0016, 0xe0017,
-		0xe0018, 0xe0019,
-		0x5001c,
-		0x50038, 0x50039, 0x5003a, 0x5003b
-	};
-
-	/**
-	 * @fwts-label SLWRegisterDump
-	 * @fwts-advice An error condition occurred in sleep/winkle
-	 * engines timer state machine. Dumping debug information to
-	 * root-cause. OPAL/skiboot may be stuck on some operation that
-	 * requires SLW timer state machine (e.g. core powersaving)
-	 */
-	prlog(PR_DEBUG, "SLW: Register state:\n");
-
-	for (i = 0; i < ARRAY_SIZE(dump_regs); i++) {
-		uint32_t reg = dump_regs[i];
-		rc = xscom_read(slw_timer_chip, reg, &val);
-		if (rc) {
-			prlog(PR_DEBUG, "SLW: XSCOM error %lld reading"
-			      " reg 0x%x\n", rc, reg);
-			break;
-		}
-		prlog(PR_DEBUG, "SLW:  %5x = %016llx\n", reg, val);
-	}
-}
-
-/* This is called with the timer lock held, so there is no
- * issue with re-entrancy or concurrence
- */
-void slw_update_timer_expiry(uint64_t new_target)
-{
-	uint64_t count, gen, gen2, req, now = mftb();
-	int64_t rc;
-
-	if (!slw_has_timer || new_target == slw_timer_target)
-		return;
-
-	slw_timer_target = new_target;
-
-	/* Calculate how many increments from now, rounded up */
-	if (now < new_target)
-		count = (new_target - now + slw_timer_inc - 1) / slw_timer_inc;
-	else
-		count = 1;
-
-	/* Max counter is 24-bit */
-	if (count > 0xffffff)
-		count = 0xffffff;
-	/* Fabricate update request */
-	req = (1ull << 63) | (count << 32);
-
-	prlog(PR_TRACE, "SLW: TMR expiry: 0x%llx, req: %016llx\n", count, req);
-
-	do {
-		/* Grab generation and spin if odd */
-		_xscom_lock();
-		for (;;) {
-			rc = _xscom_read(slw_timer_chip, 0xE0006, &gen, false);
-			if (rc) {
-				prerror("SLW: Error %lld reading tmr gen "
-					" count\n", rc);
-				_xscom_unlock();
-				return;
-			}
-			if (!(gen & 1))
-				break;
-			if (tb_compare(now + msecs_to_tb(1), mftb()) == TB_ABEFOREB) {
-				/**
-				 * @fwts-label SLWTimerStuck
-				 * @fwts-advice The SLeep/Winkle Engine (SLW)
-				 * failed to increment the generation number
-				 * within our timeout period (it *should* have
-				 * done so within ~10us, not >1ms. OPAL uses
-				 * the SLW timer to schedule some operations,
-				 * but can fall back to the (much less frequent
-				 * OPAL poller, which although does not affect
-				 * functionality, runs *much* less frequently.
-				 * This could have the effect of slow I2C
-				 * operations (for example). It may also mean
-				 * that you *had* an increase in jitter, due
-				 * to slow interactions with SLW.
-				 * This error may also occur if the machine
-				 * is connected to via soft FSI.
-				 */
-				prerror("SLW: timer stuck, falling back to OPAL pollers. You will likely have slower I2C and may have experienced increased jitter.\n");
-				prlog(PR_DEBUG, "SLW: Stuck with odd generation !\n");
-				_xscom_unlock();
-				slw_has_timer = false;
-				slw_dump_timer_ffdc();
-				return;
-			}
-		}
-
-		rc = _xscom_write(slw_timer_chip, 0x5003A, req, false);
-		if (rc) {
-			prerror("SLW: Error %lld writing tmr request\n", rc);
-			_xscom_unlock();
-			return;
-		}
-
-		/* Re-check gen count */
-		rc = _xscom_read(slw_timer_chip, 0xE0006, &gen2, false);
-		if (rc) {
-			prerror("SLW: Error %lld re-reading tmr gen "
-				" count\n", rc);
-			_xscom_unlock();
-			return;
-		}
-		_xscom_unlock();
-	} while(gen != gen2);
-
-	/* Check if the timer is working. If at least 1ms has elapsed
-	 * since the last call to this function, check that the gen
-	 * count has changed
-	 */
-	if (tb_compare(slw_last_gen_stamp + msecs_to_tb(1), now)
-	    == TB_ABEFOREB) {
-		if (slw_last_gen == gen) {
-			prlog(PR_ERR,
-			      "SLW: Timer appears to not be running !\n");
-			slw_has_timer = false;
-			slw_dump_timer_ffdc();
-		}
-		slw_last_gen = gen;
-		slw_last_gen_stamp = mftb();
-	}
-
-	prlog(PR_TRACE, "SLW: gen: %llx\n", gen);
-}
-
-bool slw_timer_ok(void)
-{
-	return slw_has_timer;
-}
-
-static void slw_init_timer(void)
-{
-	struct dt_node *np;
-	int64_t rc;
-	uint32_t tick_us;
-
-	np = dt_find_compatible_node(dt_root, NULL, "ibm,power8-sbe-timer");
-	if (!np)
-		return;
-
-	slw_timer_chip = dt_get_chip_id(np);
-	tick_us = dt_prop_get_u32(np, "tick-time-us");
-	slw_timer_inc = usecs_to_tb(tick_us);
-	slw_timer_target = ~0ull;
-
-	rc = xscom_read(slw_timer_chip, 0xE0006, &slw_last_gen);
-	if (rc) {
-		prerror("SLW: Error %lld reading tmr gen count\n", rc);
-		return;
-	}
-	slw_last_gen_stamp = mftb();
-
-	prlog(PR_INFO, "SLW: Timer facility on chip %d, resolution %dus\n",
-	      slw_timer_chip, tick_us);
-	slw_has_timer = true;
-}
-
 void slw_init(void)
 {
 	struct proc_chip *chip;
@@ -1446,5 +1265,5 @@  void slw_init(void)
 	for_each_chip(chip)
 		slw_init_chip(chip);
 
-	slw_init_timer();
+	p8_sbe_init_timer();
 }
diff --git a/include/sbe_p8.h b/include/sbe_p8.h
new file mode 100644
index 0000000..87c4aeb
--- /dev/null
+++ b/include/sbe_p8.h
@@ -0,0 +1,29 @@ 
+/* Copyright 2013-2017 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *	http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __SBE_P8_H
+#define __SBE_P8_H
+
+/* P8 SBE update timer function */
+extern void p8_sbe_update_timer_expiry(uint64_t new_target);
+
+/* Is SBE timer available ? */
+extern bool p8_sbe_timer_ok(void);
+
+/* Initialize SBE timer */
+extern void p8_sbe_init_timer(void);
+
+#endif /* __SBE_P8_H */
diff --git a/include/skiboot.h b/include/skiboot.h
index bb0a7b5..b1422e3 100644
--- a/include/skiboot.h
+++ b/include/skiboot.h
@@ -278,12 +278,6 @@  extern void *create_dtb(const struct dt_node *root, bool exclusive);
 /* SLW reinit function for switching core settings */
 extern int64_t slw_reinit(uint64_t flags);
 
-/* SLW update timer function */
-extern void slw_update_timer_expiry(uint64_t new_target);
-
-/* Is SLW timer available ? */
-extern bool slw_timer_ok(void);
-
 /* Patch SPR in SLW image */
 extern int64_t opal_slw_set_reg(uint64_t cpu_pir, uint64_t sprn, uint64_t val);