[DELL] S6100 Support PowerCycle in Last Reboot Reason (#3403)
* [DELL] S6100 Support PowerCycle in Last Reboot Reason * handle first time boot properly * S6000 Last Reboot Reason Fix
This commit is contained in:
parent
124b26d72f
commit
3c0b56a709
@ -235,6 +235,9 @@ if [ -f $FIRST_BOOT_FILE ]; then
|
|||||||
touch /tmp/pending_config_initialization
|
touch /tmp/pending_config_initialization
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# Notify firstboot to Platform, to use it for reboot-cause
|
||||||
|
touch /tmp/notify_firstboot_to_platform
|
||||||
|
|
||||||
if [ -d /host/image-$SONIC_VERSION/platform/$platform ]; then
|
if [ -d /host/image-$SONIC_VERSION/platform/$platform ]; then
|
||||||
dpkg -i /host/image-$SONIC_VERSION/platform/$platform/*.deb
|
dpkg -i /host/image-$SONIC_VERSION/platform/$platform/*.deb
|
||||||
fi
|
fi
|
||||||
|
@ -21,6 +21,7 @@ SYSLOG_IDENTIFIER = "process-reboot-cause"
|
|||||||
REBOOT_CAUSE_DIR = "/host/reboot-cause/"
|
REBOOT_CAUSE_DIR = "/host/reboot-cause/"
|
||||||
REBOOT_CAUSE_FILE = REBOOT_CAUSE_DIR + "reboot-cause.txt"
|
REBOOT_CAUSE_FILE = REBOOT_CAUSE_DIR + "reboot-cause.txt"
|
||||||
PREVIOUS_REBOOT_CAUSE_FILE = REBOOT_CAUSE_DIR + "previous-reboot-cause.txt"
|
PREVIOUS_REBOOT_CAUSE_FILE = REBOOT_CAUSE_DIR + "previous-reboot-cause.txt"
|
||||||
|
FIRST_BOOT_PLATFORM_FILE = "/tmp/notify_firstboot_to_platform"
|
||||||
|
|
||||||
UNKNOWN_REBOOT_CAUSE = "Unknown"
|
UNKNOWN_REBOOT_CAUSE = "Unknown"
|
||||||
|
|
||||||
@ -86,6 +87,13 @@ def main():
|
|||||||
cause_file = open(REBOOT_CAUSE_FILE, "r")
|
cause_file = open(REBOOT_CAUSE_FILE, "r")
|
||||||
previous_reboot_cause = cause_file.readline().rstrip('\n')
|
previous_reboot_cause = cause_file.readline().rstrip('\n')
|
||||||
cause_file.close()
|
cause_file.close()
|
||||||
|
# If it is FirstTime Boot and previous_reboot_cause is unknown
|
||||||
|
# and hardware_reboot cause is non_hardware then
|
||||||
|
# Update the reboot cause as required
|
||||||
|
if os.path.isfile(FIRST_BOOT_PLATFORM_FILE):
|
||||||
|
if (previous_reboot_cause == UNKNOWN_REBOOT_CAUSE):
|
||||||
|
previous_reboot_cause = UNKNOWN_REBOOT_CAUSE
|
||||||
|
os.remove(FIRST_BOOT_PLATFORM_FILE)
|
||||||
elif hardware_reboot_cause == chassis.REBOOT_CAUSE_HARDWARE_OTHER:
|
elif hardware_reboot_cause == chassis.REBOOT_CAUSE_HARDWARE_OTHER:
|
||||||
previous_reboot_cause = "{} ({})".format(hardware_reboot_cause, optional_details)
|
previous_reboot_cause = "{} ({})".format(hardware_reboot_cause, optional_details)
|
||||||
else:
|
else:
|
||||||
@ -100,6 +108,12 @@ def main():
|
|||||||
previous_reboot_cause = cause_file.readline().rstrip('\n')
|
previous_reboot_cause = cause_file.readline().rstrip('\n')
|
||||||
cause_file.close()
|
cause_file.close()
|
||||||
|
|
||||||
|
# If it is FirstTime Boot and previous_reboot_cause is unknown
|
||||||
|
# Update the reboot cause as required
|
||||||
|
if os.path.isfile(FIRST_BOOT_PLATFORM_FILE):
|
||||||
|
if (previous_reboot_cause == UNKNOWN_REBOOT_CAUSE):
|
||||||
|
previous_reboot_cause = UNKNOWN_REBOOT_CAUSE
|
||||||
|
os.remove(FIRST_BOOT_PLATFORM_FILE)
|
||||||
# Write the previous reboot cause to PREVIOUS_REBOOT_CAUSE_FILE
|
# Write the previous reboot cause to PREVIOUS_REBOOT_CAUSE_FILE
|
||||||
prev_cause_file = open(PREVIOUS_REBOOT_CAUSE_FILE, "w")
|
prev_cause_file = open(PREVIOUS_REBOOT_CAUSE_FILE, "w")
|
||||||
prev_cause_file.write(previous_reboot_cause)
|
prev_cause_file.write(previous_reboot_cause)
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
#define IOREGION_LENGTH 0x4
|
#define IOREGION_LENGTH 0x4
|
||||||
#define SMF_ADDR_REG_OFFSET 0
|
#define SMF_ADDR_REG_OFFSET 0
|
||||||
#define SMF_READ_DATA_REG_OFFSET 2
|
#define SMF_READ_DATA_REG_OFFSET 2
|
||||||
|
#define SMF_WRITE_DATA_REG_OFFSET 3
|
||||||
#define SMF_REG_ADDR 0x200
|
#define SMF_REG_ADDR 0x200
|
||||||
#define SMF_POR_SRC_REG 0x209
|
#define SMF_POR_SRC_REG 0x209
|
||||||
#define SMF_RST_SRC_REG 0x20A
|
#define SMF_RST_SRC_REG 0x20A
|
||||||
@ -170,6 +171,8 @@
|
|||||||
#define EEPROM_LABEL_REV_SIZE 3
|
#define EEPROM_LABEL_REV_SIZE 3
|
||||||
#define EEPROM_PPID_SIZE 28
|
#define EEPROM_PPID_SIZE 28
|
||||||
|
|
||||||
|
/* Mailbox PowerOn Reason */
|
||||||
|
#define TRACK_POWERON_REASON 0x05FF
|
||||||
|
|
||||||
|
|
||||||
unsigned long *mmio;
|
unsigned long *mmio;
|
||||||
@ -461,6 +464,18 @@ struct smf_sio_data {
|
|||||||
enum kinds kind;
|
enum kinds kind;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int smf_write_reg(struct smf_data *data, u16 reg, u16 dev_data)
|
||||||
|
{
|
||||||
|
int res = 0;
|
||||||
|
|
||||||
|
mutex_lock(&data->lock);
|
||||||
|
outb_p(reg>> 8, data->addr + SMF_ADDR_REG_OFFSET);
|
||||||
|
outb_p(reg & 0xff, data->addr + SMF_ADDR_REG_OFFSET + 1);
|
||||||
|
outb_p(dev_data & 0xff, data->addr + SMF_WRITE_DATA_REG_OFFSET);
|
||||||
|
mutex_unlock(&data->lock);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
static int smf_read_reg(struct smf_data *data, u16 reg)
|
static int smf_read_reg(struct smf_data *data, u16 reg)
|
||||||
{
|
{
|
||||||
@ -552,6 +567,40 @@ static ssize_t show_power_on_reason(struct device *dev,
|
|||||||
return sprintf(buf, "%x\n", ret);
|
return sprintf(buf, "%x\n", ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* SMF Mailbox Power ON Reason */
|
||||||
|
static ssize_t set_mb_poweron_reason(struct device *dev,
|
||||||
|
struct device_attribute *devattr, const char *buf, size_t count)
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
unsigned int dev_data = 0;
|
||||||
|
struct smf_data *data = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
err = kstrtouint(buf, 16, &dev_data);
|
||||||
|
if (err)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
err = smf_write_reg(data, TRACK_POWERON_REASON, dev_data);
|
||||||
|
|
||||||
|
if(err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
static ssize_t show_mb_poweron_reason(struct device *dev,
|
||||||
|
struct device_attribute *devattr, char *buf)
|
||||||
|
{
|
||||||
|
unsigned int ret = 0;
|
||||||
|
struct smf_data *data = dev_get_drvdata(dev);
|
||||||
|
|
||||||
|
ret = smf_read_reg(data, TRACK_POWERON_REASON);
|
||||||
|
|
||||||
|
if(ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return sprintf(buf, "0x%x\n", ret);
|
||||||
|
}
|
||||||
|
|
||||||
/* FANIN ATTR */
|
/* FANIN ATTR */
|
||||||
static ssize_t
|
static ssize_t
|
||||||
show_fan_label(struct device *dev, struct device_attribute *attr, char *buf)
|
show_fan_label(struct device *dev, struct device_attribute *attr, char *buf)
|
||||||
@ -1981,11 +2030,16 @@ static SENSOR_DEVICE_ATTR(smf_reset_reason, S_IRUGO, show_reset_reason, NULL, 1)
|
|||||||
static SENSOR_DEVICE_ATTR(smf_poweron_reason, S_IRUGO,
|
static SENSOR_DEVICE_ATTR(smf_poweron_reason, S_IRUGO,
|
||||||
show_power_on_reason, NULL, 1);
|
show_power_on_reason, NULL, 1);
|
||||||
|
|
||||||
|
/* Mailbox Power tracking Reason */
|
||||||
|
static SENSOR_DEVICE_ATTR(mb_poweron_reason, S_IRUGO|S_IWUSR,
|
||||||
|
show_mb_poweron_reason, set_mb_poweron_reason, 0);
|
||||||
|
|
||||||
static struct attribute *smf_dell_attrs[] = {
|
static struct attribute *smf_dell_attrs[] = {
|
||||||
&sensor_dev_attr_smf_version.dev_attr.attr,
|
&sensor_dev_attr_smf_version.dev_attr.attr,
|
||||||
&sensor_dev_attr_smf_firmware_ver.dev_attr.attr,
|
&sensor_dev_attr_smf_firmware_ver.dev_attr.attr,
|
||||||
&sensor_dev_attr_smf_reset_reason.dev_attr.attr,
|
&sensor_dev_attr_smf_reset_reason.dev_attr.attr,
|
||||||
&sensor_dev_attr_smf_poweron_reason.dev_attr.attr,
|
&sensor_dev_attr_smf_poweron_reason.dev_attr.attr,
|
||||||
|
&sensor_dev_attr_mb_poweron_reason.dev_attr.attr,
|
||||||
&sensor_dev_attr_fan_tray_presence.dev_attr.attr,
|
&sensor_dev_attr_fan_tray_presence.dev_attr.attr,
|
||||||
&sensor_dev_attr_fan1_airflow.dev_attr.attr,
|
&sensor_dev_attr_fan1_airflow.dev_attr.attr,
|
||||||
&sensor_dev_attr_fan3_airflow.dev_attr.attr,
|
&sensor_dev_attr_fan3_airflow.dev_attr.attr,
|
||||||
|
@ -175,16 +175,18 @@ class Chassis(ChassisBase):
|
|||||||
"""
|
"""
|
||||||
Retrieves the cause of the previous reboot
|
Retrieves the cause of the previous reboot
|
||||||
"""
|
"""
|
||||||
reset_reason = int(self._get_cpld_register('last_reboot_reason'),
|
|
||||||
base=16)
|
|
||||||
|
|
||||||
# In S6000, We track the reboot reason by writing the reason in
|
# In S6000, We track the reboot reason by writing the reason in
|
||||||
# NVRAM. Only Warmboot and Coldboot reason are supported here.
|
# NVRAM. Only Warmboot and Coldboot reason are supported here.
|
||||||
|
# Since it does not support any hardware reason, we return
|
||||||
|
# non_hardware as default
|
||||||
|
|
||||||
if (reset_reason in self.reset_reason_dict):
|
lrr = self._get_cpld_register('last_reboot_reason')
|
||||||
return (self.reset_reason_dict[reset_reason], None)
|
if (lrr != 'ERR'):
|
||||||
|
reset_reason = int(lrr, base=16)
|
||||||
|
if (reset_reason in self.reset_reason_dict):
|
||||||
|
return (self.reset_reason_dict[reset_reason], None)
|
||||||
|
|
||||||
return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason")
|
return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None)
|
||||||
|
|
||||||
def _get_command_result(self, cmdline):
|
def _get_command_result(self, cmdline):
|
||||||
try:
|
try:
|
||||||
|
@ -217,6 +217,24 @@ reset_muxes() {
|
|||||||
io_rd_wr.py --set --val 0xff --offset 0x20b
|
io_rd_wr.py --set --val 0xff --offset 0x20b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
track_reboot_reason() {
|
||||||
|
if [[ -d /sys/devices/platform/SMF.512/hwmon/ ]]; then
|
||||||
|
rv=$(cd /sys/devices/platform/SMF.512/hwmon/*; cat mb_poweron_reason)
|
||||||
|
reason=$(echo $rv | cut -d 'x' -f2)
|
||||||
|
if [ $reason == "ff" ]; then
|
||||||
|
cd /sys/devices/platform/SMF.512/hwmon/*
|
||||||
|
if [[ -e /tmp/notify_firstboot_to_platform ]]; then
|
||||||
|
echo 0x01 > mb_poweron_reason
|
||||||
|
else
|
||||||
|
echo 0xbb > mb_poweron_reason
|
||||||
|
fi
|
||||||
|
elif [ $reason == "bb" ] || [ $reason == "1" ]; then
|
||||||
|
cd /sys/devices/platform/SMF.512/hwmon/*
|
||||||
|
echo 0xaa > mb_poweron_reason
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
install_python_api_package() {
|
install_python_api_package() {
|
||||||
device="/usr/share/sonic/device"
|
device="/usr/share/sonic/device"
|
||||||
platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform)
|
platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform)
|
||||||
@ -239,6 +257,7 @@ if [[ "$1" == "init" ]]; then
|
|||||||
modprobe dell_ich
|
modprobe dell_ich
|
||||||
modprobe dell_s6100_iom_cpld
|
modprobe dell_s6100_iom_cpld
|
||||||
modprobe dell_s6100_lpc
|
modprobe dell_s6100_lpc
|
||||||
|
track_reboot_reason
|
||||||
|
|
||||||
# Disable Watchdog Timer
|
# Disable Watchdog Timer
|
||||||
if [[ -e /usr/local/bin/platform_watchdog_disable.sh ]]; then
|
if [[ -e /usr/local/bin/platform_watchdog_disable.sh ]]; then
|
||||||
|
@ -85,6 +85,13 @@ class Chassis(ChassisBase):
|
|||||||
self._component_name_list.append(SWITCH_CPLD)
|
self._component_name_list.append(SWITCH_CPLD)
|
||||||
self._component_name_list.append(SMF_FPGA)
|
self._component_name_list.append(SMF_FPGA)
|
||||||
|
|
||||||
|
def _get_reboot_reason_smf_register(self):
|
||||||
|
# Returns 0xAA on software reload
|
||||||
|
# Returns 0xFF on power-cycle
|
||||||
|
# Returns 0x01 on first-boot
|
||||||
|
smf_mb_reg_reason = self._get_pmc_register('mb_poweron_reason')
|
||||||
|
return int(smf_mb_reg_reason, 16)
|
||||||
|
|
||||||
def _get_pmc_register(self, reg_name):
|
def _get_pmc_register(self, reg_name):
|
||||||
# On successful read, returns the value read from given
|
# On successful read, returns the value read from given
|
||||||
# reg_name and on failure returns 'ERR'
|
# reg_name and on failure returns 'ERR'
|
||||||
@ -201,6 +208,10 @@ class Chassis(ChassisBase):
|
|||||||
|
|
||||||
reset_reason = int(self._get_pmc_register('smf_reset_reason'))
|
reset_reason = int(self._get_pmc_register('smf_reset_reason'))
|
||||||
power_reason = int(self._get_pmc_register('smf_poweron_reason'))
|
power_reason = int(self._get_pmc_register('smf_poweron_reason'))
|
||||||
|
smf_mb_reg_reason = self._get_reboot_reason_smf_register()
|
||||||
|
|
||||||
|
if ((smf_mb_reg_reason == 0x01) and (power_reason == 0x11)):
|
||||||
|
return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None)
|
||||||
|
|
||||||
# Reset_Reason = 11 ==> PowerLoss
|
# Reset_Reason = 11 ==> PowerLoss
|
||||||
# So return the reboot reason from Last Power_Reason Dictionary
|
# So return the reboot reason from Last Power_Reason Dictionary
|
||||||
@ -209,10 +220,16 @@ class Chassis(ChassisBase):
|
|||||||
# checking key presence in dictionary else return
|
# checking key presence in dictionary else return
|
||||||
# REBOOT_CAUSE_HARDWARE_OTHER as the Power_Reason and Reset_Reason
|
# REBOOT_CAUSE_HARDWARE_OTHER as the Power_Reason and Reset_Reason
|
||||||
# registers returned invalid data
|
# registers returned invalid data
|
||||||
|
|
||||||
|
# In S6100, if Reset_Reason is not 11 and smf_mb_reg_reason
|
||||||
|
# is ff or bb, then it is PowerLoss
|
||||||
if (reset_reason == 11):
|
if (reset_reason == 11):
|
||||||
if (power_reason in self.power_reason_dict):
|
if (power_reason in self.power_reason_dict):
|
||||||
return (self.power_reason_dict[power_reason], None)
|
return (self.power_reason_dict[power_reason], None)
|
||||||
else:
|
else:
|
||||||
|
if ((smf_mb_reg_reason == 0xbb) or (smf_mb_reg_reason == 0xff)):
|
||||||
|
return (ChassisBase.REBOOT_CAUSE_POWER_LOSS, None)
|
||||||
|
|
||||||
if (reset_reason in self.reset_reason_dict):
|
if (reset_reason in self.reset_reason_dict):
|
||||||
return (self.reset_reason_dict[reset_reason], None)
|
return (self.reset_reason_dict[reset_reason], None)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user