summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaptor Engineering Development Team <support@raptorengineering.com>2019-04-24 05:28:43 +0000
committerRaptor Engineering Development Team <support@raptorengineering.com>2019-04-24 05:28:43 +0000
commitb480da65b9476ae363c488faaf30c196b9291462 (patch)
treee7190cd47ad6eb5c27b2440da2ab5457bdc6b2d2
parent697da84f55c2bb080eee647bcab3255a6fd818e2 (diff)
downloadtalos-skeleton-b480da65b9476ae363c488faaf30c196b9291462.tar.gz
talos-skeleton-b480da65b9476ae363c488faaf30c196b9291462.zip
Update IPL status observer to use new port 81h/82h status codes
-rwxr-xr-xpyiplobserver/ipl_status_observer.py184
1 files changed, 68 insertions, 116 deletions
diff --git a/pyiplobserver/ipl_status_observer.py b/pyiplobserver/ipl_status_observer.py
index b3bafa7..5fdfd8e 100755
--- a/pyiplobserver/ipl_status_observer.py
+++ b/pyiplobserver/ipl_status_observer.py
@@ -1,6 +1,6 @@
#!/usr/bin/env python
#
-# Copyright 2018 Raptor Engineering, LLC
+# Copyright 2018-2019 Raptor Engineering, LLC
# Released under the terms of the GPL v3
#
# Get current istep with
@@ -18,6 +18,7 @@ import subprocess
import time
import subprocess
import traceback
+from binascii import hexlify
from fcntl import fcntl, F_GETFL, F_SETFL
from os import O_NONBLOCK, read
import obmc.dbuslib.propertycacher as PropertyCacher
@@ -26,7 +27,6 @@ import obmc.enums
import obmc_system_config as System
import obmc.mapper.utils
import obmc.inventory
-import obmc.system
DBUS_NAME = 'org.openbmc.status.IPL'
OBJ_NAME = u'/org/openbmc/status/IPL'
@@ -34,6 +34,9 @@ OBJ_NAME = u'/org/openbmc/status/IPL'
IPL_FLAG_DIR = '/run/openbmc/'
IPL_FLAG_FILE = 'host@0-ipl-complete'
+PORT81_SNOOP_FIFO = '/dev/aspeed-lpc-snoop0'
+PORT82_SNOOP_FIFO = '/dev/aspeed-lpc-snoop1'
+
HOST_STATUS_RUNNING = "xyz.openbmc_project.State.Host.HostState.Running"
IPL_SBE_START_ISTEP_MAJOR = 0
@@ -48,14 +51,14 @@ IPL_HOSTBOOT_START_ISTEP_MINOR = 0
IPL_COMPLETE_ISTEP_MAJOR = 21
IPL_COMPLETE_ISTEP_MINOR = 3
-SKIBOOT_RUNNING_ISTEP_MAJOR = 22
-SKIBOOT_RUNNING_ISTEP_MINOR = 0
+SKIBOOT_RUNNING_ISTEP_MAJOR = 192
+SKIBOOT_RUNNING_ISTEP_MINOR = 12
-KERNEL_RUNNING_ISTEP_MAJOR = 23
-KERNEL_RUNNING_ISTEP_MINOR = 0
+KERNEL_RUNNING_ISTEP_MAJOR = 240
+KERNEL_RUNNING_ISTEP_MINOR = 16
-KERNEL_COMPLETE_ISTEP_MAJOR = 23
-KERNEL_COMPLETE_ISTEP_MINOR = 1
+KERNEL_COMPLETE_ISTEP_MAJOR = 254
+KERNEL_COMPLETE_ISTEP_MINOR = 254
class IPLStatus(DbusProperties, DbusObjectManager):
def __init__(self, bus, obj_name):
@@ -70,8 +73,8 @@ class IPLStatus(DbusProperties, DbusObjectManager):
self.last_istep = ""
self.current_istep_major = 0
self.current_istep_minor = 0
- self.consoleProcess = None
- self.consoleReadBuffer = ""
+ self.port_81_fifo = None
+ self.port_82_fifo = None
if not os.path.exists(IPL_FLAG_DIR):
os.makedirs(IPL_FLAG_DIR)
@@ -81,16 +84,18 @@ class IPLStatus(DbusProperties, DbusObjectManager):
host_state_value = host_state_iface.Get("xyz.openbmc_project.State.Host", "CurrentHostState")
if host_state_value is not None:
power_ctrl_flag = self.getChassisPowerRequestFlag()
- skiboot_flags = self.getSkibootBootFlags()
- if ((skiboot_flags != 0) and (skiboot_flags != 1)) or ((power_ctrl_flag == 1) and (skiboot_flags == 0)):
+ # FIXME
+ # If this service is restarted after the host has completed IPL, we have no way
+ # of knowing this. If the host has not completed IPL, then running the following
+ # commands will probably cause a system fault requiring manual intervention to clear
+ # (i.e. pflash -P GUARD -c once the second CPU faults out)
+ if power_ctrl_flag == 1:
self.current_istep_major = KERNEL_COMPLETE_ISTEP_MAJOR
self.current_istep_minor = KERNEL_COMPLETE_ISTEP_MAJOR
- if (skiboot_flags != 0) or (power_ctrl_flag == 1):
self.activateMonitoringPrev = True
self.activateMonitoring = True
if (host_state_value != HOST_STATUS_RUNNING) and (self.activateMonitoring == True):
host_state_iface.Set("xyz.openbmc_project.State.Host", "CurrentHostState", HOST_STATUS_RUNNING)
- self.setSkibootBootFlags(2)
self.Set(DBUS_NAME, "current_istep", "")
self.Set(DBUS_NAME, "current_status", "UNKNOWN")
@@ -115,32 +120,6 @@ class IPLStatus(DbusProperties, DbusObjectManager):
return result
- # BMC bits OEM1, OEM2, and OEM3 are the signalling flags
- # OEM1 is unconditionally set at skiboot completion and is only cleared by the BMC IPL monitor
- # OEM2 is used as a persistent state indicator, and is only set and cleared by the BMC IPL monitor
- # OEM3 is unconditionally set at kernel boot completion and is only cleared by the BMC IPL monitor
- def getSkibootBootFlags(self):
- result = 0
- try:
- proc = subprocess.Popen(["devmem", "0x1e789060", "16"], stdout=subprocess.PIPE, stderr=open(os.devnull, 'wb'), shell=False)
- (out, err) = proc.communicate()
- result = (int(out, 16) & 28) >> 2
- except:
- pass
-
- return result
-
- def setSkibootBootFlags(self, value):
- try:
- proc = subprocess.Popen(["devmem", "0x1e789060", "16"], stdout=subprocess.PIPE, stderr=open(os.devnull, 'wb'), shell=False)
- (out, err) = proc.communicate()
- reg_data = (int(out, 16) & (~28)) | ((value & 7) << 2)
- proc = subprocess.Popen(["devmem", "0x1e789060", "16", str(reg_data)], stdout=subprocess.PIPE, stderr=open(os.devnull, 'wb'), shell=False)
- (out, err) = proc.communicate()
- except:
- print "IPLStatus unable to reset skiboot / kernel flags!"
- pass
-
def readIPLStatus(self):
try:
# Set up defaults
@@ -155,22 +134,30 @@ class IPLStatus(DbusProperties, DbusObjectManager):
self.Set(DBUS_NAME, "current_status", current_status)
self.IPLStatusChanged(current_status)
self.last_status = current_status
- self.setSkibootBootFlags(0)
if (self.last_istep != current_istep):
self.Set(DBUS_NAME, "current_istep", current_istep)
self.IPLStepChanged(current_istep)
self.last_istep = current_istep
- self.setSkibootBootFlags(0)
self.activateMonitoringPrev = self.activateMonitoring
return True;
if (self.activateMonitoring == True) and (self.activateMonitoringPrev == False):
- if (self.consoleProcess is None):
- self.consoleProcess = subprocess.Popen(["/usr/bin/obmc-console-client"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False)
- # set the O_NONBLOCK flag of self.consoleProcess.stdout file descriptor:
- stdout_flags = fcntl(self.consoleProcess.stdout, F_GETFL) # get current p.stdout flags
- fcntl(self.consoleProcess.stdout, F_SETFL, stdout_flags | O_NONBLOCK)
+ if (self.port_81_fifo is None):
+ self.port_81_fifo = os.open(PORT81_SNOOP_FIFO, os.O_RDONLY | os.O_NONBLOCK, 0);
+ if (self.port_82_fifo is None):
+ self.port_82_fifo = os.open(PORT82_SNOOP_FIFO, os.O_RDONLY | os.O_NONBLOCK, 0);
+ # Drain FIFOs
+ while True:
+ try:
+ os.read(self.port_81_fifo, 1)
+ except:
+ break
+ while True:
+ try:
+ os.read(self.port_82_fifo, 1)
+ except:
+ break
current_status = "IPL_RUNNING"
self.current_istep_major = IPL_SBE_START_ISTEP_MAJOR
self.current_istep_minor = IPL_SBE_START_ISTEP_MINOR
@@ -179,50 +166,40 @@ class IPLStatus(DbusProperties, DbusObjectManager):
self.IPLStepChanged(current_istep)
self.last_istep = current_istep
elif (self.activateMonitoring == False) and (self.activateMonitoringPrev == True):
- if (self.consoleProcess is not None):
- self.consoleProcess.kill()
- self.consoleProcess = None
- self.consoleReadBuffer = ""
- self.current_istep_major = 0
- self.current_istep_minor = 0
+ # Close FIFOs if still open
+ if (self.port_81_fifo is not None):
+ os.close(self.port_81_fifo);
+ self.port_81_fifo = None;
+ if (self.port_82_fifo is not None):
+ os.close(self.port_82_fifo);
+ self.port_82_fifo = None;
+ self.current_istep_major = 0
+ self.current_istep_minor = 0
# Check for output
- if (self.consoleProcess is not None):
+ if (self.port_82_fifo is not None):
all_lines_processed = False
while all_lines_processed == False:
- candidate_character = ''
+ istep_major = None
+ istep_minor = None
try:
- while True:
- candidate_character = self.consoleProcess.stdout.read(1)
- self.consoleReadBuffer += candidate_character
- if (candidate_character == '\n'):
- break;
+ value = os.read(self.port_82_fifo, 1)
+ istep_minor = int(hexlify(value), 16)
except:
- # ENODATA is expected
all_lines_processed = True
- break;
-
- self.consoleReadBuffer += candidate_character
- if (candidate_character != '\n'):
- return True
-
- candidate_line = self.consoleReadBuffer.decode('utf-8', 'ignore').rstrip().lstrip()
- self.consoleReadBuffer = ""
- if ("|ISTEP " in candidate_line):
- candidate_line = candidate_line.replace(" ", "")
+ if not all_lines_processed:
try:
- (timestamp_seconds, timestamp_fraction, istep_major, istep_minor, istep_name) = [t(s) for t, s in zip((int, int, int, int, str), re.search('^(\d+).(\d+)\|ISTEP(\d+).(\d+)-(\S+)$', candidate_line).groups())]
+ value = os.read(self.port_81_fifo, 1)
+ istep_major = int(hexlify(value), 16)
except:
- self.activateMonitoringPrev = self.activateMonitoring
- return True
- else:
- self.activateMonitoringPrev = self.activateMonitoring
- return True
+ all_lines_processed = True
- # Figure out system status
- self.current_istep_major = istep_major
- self.current_istep_minor = istep_minor
+ if not all_lines_processed:
+ if (istep_major != None) and (istep_minor != None):
+ # Figure out system status
+ self.current_istep_major = istep_major
+ self.current_istep_minor = istep_minor
# Assemble status strings
current_istep = str(self.current_istep_major) + "," + str(self.current_istep_minor)
@@ -230,36 +207,13 @@ class IPLStatus(DbusProperties, DbusObjectManager):
if ((self.current_istep_major > 0) or (self.current_istep_minor > 0 )):
current_status = "IPL_RUNNING"
if (self.current_istep_major >= IPL_COMPLETE_ISTEP_MAJOR):
- # Disconnect console if still active
- if (self.consoleProcess is not None):
- self.consoleProcess.kill()
- self.consoleProcess = None
- self.consoleReadBuffer = ""
-
- # Monitor remainder of IPL via status flags
- skiboot_flags = self.getSkibootBootFlags()
- if (skiboot_flags == 0):
- current_status = "IPL_RUNNING"
- self.current_istep_major = SKIBOOT_RUNNING_ISTEP_MAJOR
- self.current_istep_minor = SKIBOOT_RUNNING_ISTEP_MINOR
- current_istep = str(self.current_istep_major) + "," + str(self.current_istep_minor)
- elif (skiboot_flags == 1):
- current_status = "IPL_RUNNING"
- self.current_istep_major = KERNEL_RUNNING_ISTEP_MAJOR
- self.current_istep_minor = KERNEL_RUNNING_ISTEP_MINOR
- current_istep = str(self.current_istep_major) + "," + str(self.current_istep_minor)
- else:
+ # Monitor remainder of IPL for completion
+ if (self.current_istep_major == KERNEL_COMPLETE_ISTEP_MAJOR) and (self.current_istep_minor == KERNEL_COMPLETE_ISTEP_MINOR):
current_status = "IPL_COMPLETE"
- self.current_istep_major = KERNEL_COMPLETE_ISTEP_MAJOR
- self.current_istep_minor = KERNEL_COMPLETE_ISTEP_MINOR
- current_istep = str(self.current_istep_major) + "," + str(self.current_istep_minor)
# Check for status changes
if (self.last_status != current_status):
if (current_status == "IPL_COMPLETE"):
- # Set skiboot completion flag
- self.setSkibootBootFlags(2)
-
# Signal systemd that IPL is complete
try:
with open(IPL_FLAG_DIR + IPL_FLAG_FILE, 'a'):
@@ -276,9 +230,6 @@ class IPLStatus(DbusProperties, DbusObjectManager):
os.remove(IPL_FLAG_DIR + IPL_FLAG_FILE)
except:
pass
- if (current_status == "IPL_RUNNING"):
- if (self.current_istep_major < IPL_COMPLETE_ISTEP_MAJOR):
- self.setSkibootBootFlags(0)
# Publish status
if (self.last_status != current_status):
@@ -305,13 +256,15 @@ class IPLStatus(DbusProperties, DbusObjectManager):
if (value == HOST_STATUS_RUNNING):
self.activateMonitoring = True
else:
- # Disconnect console if still active
- if (self.consoleProcess is not None):
- self.consoleProcess.kill()
- self.consoleProcess = None
- self.consoleReadBuffer = ""
- self.current_istep_major = 0
- self.current_istep_minor = 0
+ # Close FIFOs if still open
+ if (self.port_81_fifo is not None):
+ os.close(self.port_81_fifo);
+ self.port_81_fifo = None;
+ if (self.port_82_fifo is not None):
+ os.close(self.port_82_fifo);
+ self.port_82_fifo = None;
+ self.current_istep_major = 0
+ self.current_istep_minor = 0
# Remove IPL complete flag if present
try:
@@ -319,7 +272,6 @@ class IPLStatus(DbusProperties, DbusObjectManager):
except:
pass
- self.setSkibootBootFlags(0)
self.activateMonitoring = False
@dbus.service.method(DBUS_NAME, in_signature='', out_signature='s')
OpenPOWER on IntegriCloud