[Skiboot] [PATCH v2] fsp/rtc: ignore TOD_RESET status

Cédric Le Goater clg at fr.ibm.com
Fri Oct 16 00:36:17 AEDT 2015

When the timeofday is considered INVALID by the FSP :

	System time is INVALID: 2015/10/14 20:13:53.305261

it will return a FSP_STATUS_TOD_RESET (0xA9) to any TOD read
request done by OPAL. This status stays invalid until a write
request is done.

This is a problem for the kernel as the OPAL_RTC_READ calls
are done in loops. The consequence is that the skiroot kernel
hangs quite early in the boot looping on : 

	[9163642153,3] RTC TOD in invalid state
	[9186642687,3] RTC TOD in invalid state
	[9204379669,3] RTC TOD in invalid state
	[9226043775,3] RTC TOD in invalid state
	[9240944791,3] RTC TOD in invalid state

with other unpleasant consequences following. The system is
left unusable and it is difficult for the user to know what
is happening.

This patch modifies the behavior of the read request when an
invalid status is received. It simply ignores it and considers
the read as successful. 

This breaks the loops done in the kernel on OPAL_RTC_READ calls
and lets the boot complete. The status is expected to become
valid after the first TOD write request. 

Signed-off-by: Cédric Le Goater <clg at fr.ibm.com>

 Tested on failing system with skiboot-5.1.7

 Changes since v1:

 - simply log the status and ignore it instead of keeping a permanent
   error on the TOD

 hw/fsp/fsp-rtc.c |   18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

Index: skiboot.git/hw/fsp/fsp-rtc.c
--- skiboot.git.orig/hw/fsp/fsp-rtc.c
+++ skiboot.git/hw/fsp/fsp-rtc.c
@@ -169,13 +169,6 @@ static void fsp_rtc_process_read(struct
 	assert(rtc_read_request_state == RTC_READ_PENDING_REQUEST);
 	switch (val) {
-		log_simple_error(&e_info(OPAL_RC_RTC_TOD),
-				"RTC TOD in invalid state\n");
-		rtc_tod_state = RTC_TOD_INVALID;
-		rtc_read_request_state = RTC_READ_NO_REQUEST;
-		break;
 			"RTC TOD in permanent error state\n");
@@ -183,6 +176,17 @@ static void fsp_rtc_process_read(struct
 		rtc_read_request_state = RTC_READ_NO_REQUEST;
+		prerror("RTC TOD in invalid state\n");
+		/*
+		 * The RESET status indicates that the TOD was
+		 * powered up with an invalid state, which will be
+		 * cleared by the first write request.
+		 *
+		 * As this is a rare scenario, let's pretend the read
+		 * request is a success and let the first write
+		 * request clear the status.
+		 */
 		/* Save the read RTC value in our cache */
 		rtc_read_request_state = RTC_READ_REQUEST_AVAILABLE;

More information about the Skiboot mailing list