1de6ed120SBrad Bishop#!/usr/bin/env python 240a360c2SBrad Bishop 340a360c2SBrad Bishopimport gobject 440a360c2SBrad Bishopimport dbus 540a360c2SBrad Bishopimport dbus.service 640a360c2SBrad Bishopimport dbus.mainloop.glib 740a360c2SBrad Bishopimport os 840a360c2SBrad Bishopimport obmc.dbuslib.propertycacher as PropertyCacher 940a360c2SBrad Bishopfrom obmc.dbuslib.bindings import DbusProperties, DbusObjectManager, get_dbus 1040a360c2SBrad Bishopimport obmc.enums 110b380f7bSBrad Bishopimport obmc_system_config as System 126173a896SBrad Bishopimport obmc.mapper.utils 137e5ec46dSBrad Bishopimport obmc.inventory 14a7ac805bSBrad Bishopimport obmc.system 1540a360c2SBrad Bishop 1640a360c2SBrad BishopDBUS_NAME = 'org.openbmc.managers.System' 1740a360c2SBrad BishopOBJ_NAME = '/org/openbmc/managers/System' 1840a360c2SBrad BishopINTF_SENSOR = 'org.openbmc.SensorValue' 1940a360c2SBrad BishopINTF_ITEM = 'org.openbmc.InventoryItem' 2040a360c2SBrad Bishop 21520f8b05SRatan GuptaSYS_STATE_FILE = '/var/lib/obmc/last-system-state' 22520f8b05SRatan GuptaPOWER_OFF = "0" 23520f8b05SRatan Gupta 2440a360c2SBrad Bishop 2540a360c2SBrad Bishopclass SystemManager(DbusProperties, DbusObjectManager): 2640a360c2SBrad Bishop def __init__(self, bus, obj_name): 27f47f5faaSBrad Bishop super(SystemManager, self).__init__( 28f47f5faaSBrad Bishop conn=bus, 29f47f5faaSBrad Bishop object_path=obj_name) 30fa736499SBrad Bishop self.bus = bus 3140a360c2SBrad Bishop 32fa736499SBrad Bishop bus.add_signal_receiver( 33416539dfSBrad Bishop self.NewObjectHandler, 3440a360c2SBrad Bishop signal_name="InterfacesAdded", sender_keyword='bus_name') 35416539dfSBrad Bishop bus.add_signal_receiver( 36416539dfSBrad Bishop self.SystemStateHandler, signal_name="GotoSystemState") 3740a360c2SBrad Bishop 38520f8b05SRatan Gupta bus.add_signal_receiver( 39520f8b05SRatan Gupta self.chassisPowerStateHandler, 40520f8b05SRatan Gupta dbus_interface="org.freedesktop.DBus.Properties", 41520f8b05SRatan Gupta signal_name="PropertiesChanged", 42520f8b05SRatan Gupta path="/org/openbmc/control/power0") 4340a360c2SBrad Bishop 44520f8b05SRatan Gupta self.Set(DBUS_NAME, "current_state", "") 45520f8b05SRatan Gupta self.Set(DBUS_NAME, "system_last_state", POWER_OFF) 46520f8b05SRatan Gupta self.import_system_state_from_disk() 47520f8b05SRatan Gupta # replace symbolic path in ID_LOOKUP 4840a360c2SBrad Bishop for category in System.ID_LOOKUP: 4940a360c2SBrad Bishop for key in System.ID_LOOKUP[category]: 5040a360c2SBrad Bishop val = System.ID_LOOKUP[category][key] 51416539dfSBrad Bishop new_val = val.replace( 527e5ec46dSBrad Bishop "<inventory_root>", obmc.inventory.INVENTORY_ROOT) 5340a360c2SBrad Bishop System.ID_LOOKUP[category][key] = new_val 5440a360c2SBrad Bishop 5540a360c2SBrad Bishop self.SystemStateHandler(System.SYSTEM_STATES[0]) 5640a360c2SBrad Bishop 5740a360c2SBrad Bishop print "SystemManager Init Done" 5840a360c2SBrad Bishop 59520f8b05SRatan Gupta def chassisPowerStateHandler(self, interface_name, changed_properties, 60520f8b05SRatan Gupta invalidated_properties): 61520f8b05SRatan Gupta value = changed_properties.get('state') 62520f8b05SRatan Gupta if value is not None: 63520f8b05SRatan Gupta self.write_to_disk_and_update(str(value)) 64520f8b05SRatan Gupta 6540a360c2SBrad Bishop def SystemStateHandler(self, state_name): 6640a360c2SBrad Bishop print "Running System State: "+state_name 6740a360c2SBrad Bishop 6840a360c2SBrad Bishop self.Set(DBUS_NAME, "current_state", state_name) 6940a360c2SBrad Bishop 706173a896SBrad Bishop waitlist = System.EXIT_STATE_DEPEND.get(state_name, {}).keys() 716173a896SBrad Bishop if waitlist: 726173a896SBrad Bishop self.waiter = obmc.mapper.utils.Wait( 736173a896SBrad Bishop self.bus, waitlist, 746173a896SBrad Bishop callback=self.gotoNextState) 756173a896SBrad Bishop 7640a360c2SBrad Bishop def gotoNextState(self): 7740a360c2SBrad Bishop s = 0 7840a360c2SBrad Bishop current_state = self.Get(DBUS_NAME, "current_state") 7940a360c2SBrad Bishop for i in range(len(System.SYSTEM_STATES)): 8040a360c2SBrad Bishop if (System.SYSTEM_STATES[i] == current_state): 8140a360c2SBrad Bishop s = i+1 8240a360c2SBrad Bishop 8340a360c2SBrad Bishop if (s == len(System.SYSTEM_STATES)): 8440a360c2SBrad Bishop print "ERROR SystemManager: No more system states" 8540a360c2SBrad Bishop else: 8640a360c2SBrad Bishop new_state_name = System.SYSTEM_STATES[s] 8740a360c2SBrad Bishop print "SystemManager Goto System State: "+new_state_name 8840a360c2SBrad Bishop self.SystemStateHandler(new_state_name) 8940a360c2SBrad Bishop 90520f8b05SRatan Gupta def import_system_state_from_disk(self): 91520f8b05SRatan Gupta state = str(POWER_OFF) 92520f8b05SRatan Gupta try: 93520f8b05SRatan Gupta with open(SYS_STATE_FILE, 'r+') as f: 94520f8b05SRatan Gupta state = f.readline().rstrip('\n') 95520f8b05SRatan Gupta except IOError: 96520f8b05SRatan Gupta pass 97520f8b05SRatan Gupta self.Set(DBUS_NAME, "system_last_state", state) 98520f8b05SRatan Gupta return state 99520f8b05SRatan Gupta 100520f8b05SRatan Gupta def write_to_disk_and_update(self, state): 101520f8b05SRatan Gupta try: 102520f8b05SRatan Gupta with open(SYS_STATE_FILE, 'w+') as f: 103520f8b05SRatan Gupta f.write(str(state)) 104520f8b05SRatan Gupta self.Set(DBUS_NAME, "system_last_state", state) 105520f8b05SRatan Gupta except IOError: 106520f8b05SRatan Gupta pass 107520f8b05SRatan Gupta 108416539dfSBrad Bishop @dbus.service.method(DBUS_NAME, in_signature='', out_signature='s') 10940a360c2SBrad Bishop def getSystemState(self): 11040a360c2SBrad Bishop return self.Get(DBUS_NAME, "current_state") 11140a360c2SBrad Bishop 11240a360c2SBrad Bishop def doObjectLookup(self, category, key): 11340a360c2SBrad Bishop obj_path = "" 11440a360c2SBrad Bishop intf_name = INTF_ITEM 11540a360c2SBrad Bishop try: 11640a360c2SBrad Bishop obj_path = System.ID_LOOKUP[category][key] 11740a360c2SBrad Bishop parts = obj_path.split('/') 11840a360c2SBrad Bishop if (parts[3] == 'sensors'): 11940a360c2SBrad Bishop intf_name = INTF_SENSOR 12040a360c2SBrad Bishop except Exception as e: 12140a360c2SBrad Bishop print "ERROR SystemManager: "+str(e)+" not found in lookup" 12240a360c2SBrad Bishop 123fc38a575SBrad Bishop return [obj_path, intf_name] 12440a360c2SBrad Bishop 125fc38a575SBrad Bishop @dbus.service.method(DBUS_NAME, in_signature='ss', out_signature='(ss)') 12640a360c2SBrad Bishop def getObjectFromId(self, category, key): 12740a360c2SBrad Bishop return self.doObjectLookup(category, key) 12840a360c2SBrad Bishop 129fc38a575SBrad Bishop @dbus.service.method(DBUS_NAME, in_signature='sy', out_signature='(ss)') 13040a360c2SBrad Bishop def getObjectFromByteId(self, category, key): 13140a360c2SBrad Bishop byte = int(key) 13240a360c2SBrad Bishop return self.doObjectLookup(category, byte) 13340a360c2SBrad Bishop 13440a360c2SBrad Bishop # Get the FRU area names defined in ID_LOOKUP table given a fru_id. 13540a360c2SBrad Bishop # If serval areas are defined for a fru_id, the areas are returned 13640a360c2SBrad Bishop # together as a string with each area name seperated with ','. 13740a360c2SBrad Bishop # If no fru area defined in ID_LOOKUP, an empty string will be returned. 138416539dfSBrad Bishop @dbus.service.method(DBUS_NAME, in_signature='y', out_signature='s') 13940a360c2SBrad Bishop def getFRUArea(self, fru_id): 14040a360c2SBrad Bishop ret_str = '' 14140a360c2SBrad Bishop fru_id = '_' + str(fru_id) 142416539dfSBrad Bishop area_list = [ 143416539dfSBrad Bishop area for area in System.ID_LOOKUP['FRU_STR'].keys() 14440a360c2SBrad Bishop if area.endswith(fru_id)] 14540a360c2SBrad Bishop for area in area_list: 14640a360c2SBrad Bishop ret_str = area + ',' + ret_str 14740a360c2SBrad Bishop # remove the last ',' 14840a360c2SBrad Bishop return ret_str[:-1] 14940a360c2SBrad Bishop 15040a360c2SBrad Bishop def NewObjectHandler(self, obj_path, iprops, bus_name=None): 15140a360c2SBrad Bishop current_state = self.Get(DBUS_NAME, "current_state") 1524de42643SBrad Bishop if current_state not in System.EXIT_STATE_DEPEND: 1534de42643SBrad Bishop return 15440a360c2SBrad Bishop 1554de42643SBrad Bishop if obj_path in System.EXIT_STATE_DEPEND[current_state]: 1564de42643SBrad Bishop print "New object: "+obj_path+" ("+bus_name+")" 15740a360c2SBrad Bishop 158416539dfSBrad Bishop @dbus.service.method(DBUS_NAME, in_signature='s', out_signature='sis') 15940a360c2SBrad Bishop def gpioInit(self, name): 16040a360c2SBrad Bishop gpio_path = '' 16140a360c2SBrad Bishop gpio_num = -1 16240a360c2SBrad Bishop r = ['', gpio_num, ''] 163416539dfSBrad Bishop if name not in System.GPIO_CONFIG: 164605620d2SXo Wang # TODO: Better error handling 165605620d2SXo Wang msg = "ERROR: "+name+" not found in GPIO config table" 166605620d2SXo Wang print msg 167605620d2SXo Wang raise Exception(msg) 16840a360c2SBrad Bishop else: 16940a360c2SBrad Bishop 17040a360c2SBrad Bishop gpio_num = -1 17140a360c2SBrad Bishop gpio = System.GPIO_CONFIG[name] 172416539dfSBrad Bishop if 'gpio_num' in System.GPIO_CONFIG[name]: 17340a360c2SBrad Bishop gpio_num = gpio['gpio_num'] 17440a360c2SBrad Bishop else: 175416539dfSBrad Bishop if 'gpio_pin' in System.GPIO_CONFIG[name]: 176a7ac805bSBrad Bishop gpio_num = obmc.system.convertGpio(gpio['gpio_pin']) 17740a360c2SBrad Bishop else: 178605620d2SXo Wang msg = "ERROR: SystemManager - GPIO lookup failed for "+name 179605620d2SXo Wang print msg 180605620d2SXo Wang raise Exception(msg) 18140a360c2SBrad Bishop 18240a360c2SBrad Bishop if (gpio_num != -1): 18340a360c2SBrad Bishop r = [obmc.enums.GPIO_DEV, gpio_num, gpio['direction']] 18440a360c2SBrad Bishop return r 18540a360c2SBrad Bishop 1863f87de8bSXo Wang @dbus.service.method(DBUS_NAME, in_signature='', 187*75a18a23SLei YU out_signature='ssa(sb)a(sb)a(sbb)ssssa(sb)') 188*75a18a23SLei YU def getGpioConfiguration(self): 189*75a18a23SLei YU power_config = System.GPIO_CONFIGS.get('power_config', {}) 190*75a18a23SLei YU power_good_in = power_config.get('power_good_in', '') 191*75a18a23SLei YU latch_out = power_config.get('latch_out', '') 192*75a18a23SLei YU power_up_outs = power_config.get('power_up_outs', []) 193*75a18a23SLei YU reset_outs = power_config.get('reset_outs', []) 194*75a18a23SLei YU pci_reset_outs = System.GPIO_CONFIGS.get('pci_reset_outs', []) 195*75a18a23SLei YU hostctl_config = System.GPIO_CONFIGS.get('hostctl_config', {}) 196*75a18a23SLei YU fsi_data = hostctl_config.get('fsi_data', '') 197*75a18a23SLei YU fsi_clk = hostctl_config.get('fsi_clk', '') 198*75a18a23SLei YU fsi_enable = hostctl_config.get('fsi_enable', '') 199*75a18a23SLei YU cronus_sel = hostctl_config.get('cronus_sel', '') 200*75a18a23SLei YU optionals = hostctl_config.get('optionals', []) 201*75a18a23SLei YU r = [power_good_in, latch_out, power_up_outs, reset_outs, pci_reset_outs,\ 202*75a18a23SLei YU fsi_data, fsi_clk, fsi_enable, cronus_sel, optionals] 2033f87de8bSXo Wang print "Power GPIO config: " + str(r) 2043f87de8bSXo Wang return r 2053f87de8bSXo Wang 20640a360c2SBrad Bishop 20740a360c2SBrad Bishopif __name__ == '__main__': 20840a360c2SBrad Bishop dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) 20940a360c2SBrad Bishop bus = get_dbus() 21040a360c2SBrad Bishop obj = SystemManager(bus, OBJ_NAME) 21140a360c2SBrad Bishop mainloop = gobject.MainLoop() 212f0f3efe1SBrad Bishop obj.unmask_signals() 21370852a38SBrad Bishop name = dbus.service.BusName(DBUS_NAME, bus) 21440a360c2SBrad Bishop 21540a360c2SBrad Bishop print "Running SystemManager" 21640a360c2SBrad Bishop mainloop.run() 21753066750SBrad Bishop 21853066750SBrad Bishop# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4 219