svn commit: r365548 - head/sys/powerpc/powernv

Brandon Bergren bdragon at FreeBSD.org
Thu Sep 10 01:49:54 UTC 2020


Author: bdragon
Date: Thu Sep 10 01:49:53 2020
New Revision: 365548
URL: https://svnweb.freebsd.org/changeset/base/365548

Log:
  [PowerPC] Fix setting of time in OPAL
  
  There were multiple bugs in the OPAL RTC code which had never been
  discovered, as the default configuration of OPAL machines is to
  have the BMC / FSP control the RTC.
  
  * Fix calling convention for setting the time -- the variables are passed
  directly in CPU registers, not via memory.
  
  * Fix bug in the bcd encoding routines. (from jhibbits)
  
  Tested on POWER9 Talos II (BE) and POWER9 Blackbird (LE).
  
  Reviewed by:	jhibbits (in irc)
  Sponsored by:	Tag1 Consulting, Inc.

Modified:
  head/sys/powerpc/powernv/opal_dev.c

Modified: head/sys/powerpc/powernv/opal_dev.c
==============================================================================
--- head/sys/powerpc/powernv/opal_dev.c	Thu Sep 10 00:50:18 2020	(r365547)
+++ head/sys/powerpc/powernv/opal_dev.c	Thu Sep 10 01:49:53 2020	(r365548)
@@ -256,15 +256,15 @@ bin2bcd32(int bin)
 	int tmp;
 
 	tmp = bin % 100;
-	out += bin2bcd(tmp) * 1;
+	out += bin2bcd(tmp) * 0x1;
 	bin = bin / 100;
 
 	tmp = bin % 100;
-	out += bin2bcd(tmp) * 100;
+	out += bin2bcd(tmp) * 0x100;
 	bin = bin / 100;
 
 	tmp = bin % 100;
-	out += bin2bcd(tmp) * 10000;
+	out += bin2bcd(tmp) * 0x10000;
 
 	return (out);
 }
@@ -297,7 +297,7 @@ opal_gettime(device_t dev, struct timespec *ts)
 
 	ct.day	= bcd2bin((ymd & 0x000000ff) >> 0);
 	ct.mon	= bcd2bin((ymd & 0x0000ff00) >> 8);
-	ct.year	= bcd2bin32((ymd & 0xffff0000) >> 16);
+	ct.year = bcd2bin32((ymd & 0xffff0000) >> 16);
 
 	return (clock_ct_to_ts(&ct, ts));
 }
@@ -321,11 +321,12 @@ opal_settime(device_t dev, struct timespec *ts)
 	hmsm |= ((uint64_t)bin2bcd(ct.min) << 48);
 	hmsm |= ((uint64_t)bin2bcd(ct.hour) << 56);
 
-	hmsm = htobe64(hmsm);
-	ymd = htobe32(ymd);
-
+	/*
+	 * We do NOT swap endian here, because the values are being sent
+	 * via registers instead of indirect via memory.
+	 */
 	do {
-		rv = opal_call(OPAL_RTC_WRITE, vtophys(&ymd), vtophys(&hmsm));
+		rv = opal_call(OPAL_RTC_WRITE, ymd, hmsm);
 		if (rv == OPAL_BUSY_EVENT) {
 			rv = opal_call(OPAL_POLL_EVENTS, 0);
 			pause("opalrtc", 1);


More information about the svn-src-head mailing list