Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DELL] S6100 Support PowerCycle in Last Reboot Reason #3399

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions files/image_config/platform/rc.local
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,9 @@ if [ -f $FIRST_BOOT_FILE ]; then
touch /tmp/pending_config_initialization
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
dpkg -i /host/image-$SONIC_VERSION/platform/$platform/*.deb
fi
Expand Down
14 changes: 14 additions & 0 deletions files/image_config/process-reboot-cause/process-reboot-cause
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ SYSLOG_IDENTIFIER = "process-reboot-cause"
REBOOT_CAUSE_DIR = "/host/reboot-cause/"
REBOOT_CAUSE_FILE = REBOOT_CAUSE_DIR + "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"

Expand Down Expand Up @@ -86,6 +87,13 @@ def main():
cause_file = open(REBOOT_CAUSE_FILE, "r")
previous_reboot_cause = cause_file.readline().rstrip('\n')
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:
previous_reboot_cause = "{} ({})".format(hardware_reboot_cause, optional_details)
else:
Expand All @@ -100,6 +108,12 @@ def main():
previous_reboot_cause = cause_file.readline().rstrip('\n')
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
prev_cause_file = open(PREVIOUS_REBOOT_CAUSE_FILE, "w")
prev_cause_file.write(previous_reboot_cause)
Expand Down
55 changes: 55 additions & 0 deletions platform/broadcom/sonic-platform-modules-dell/common/dell_pmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#define IOREGION_LENGTH 0x4
#define SMF_ADDR_REG_OFFSET 0
#define SMF_READ_DATA_REG_OFFSET 2
#define SMF_WRITE_DATA_REG_OFFSET 3
#define SMF_REG_ADDR 0x200
#define SMF_POR_SRC_REG 0x209
#define SMF_RST_SRC_REG 0x20A
Expand Down Expand Up @@ -157,6 +158,9 @@
#define CPU_7_MONITOR_STATUS 0x02E8
#define CPU_8_MONITOR_STATUS 0x02E9

/* Mailbox PowerOn Reason */
#define TRACK_POWERON_REASON 0x05FF

/* EEPROM PPID */
/* FAN and PSU EEPROM PPID format is:
COUNTRY_CODE-PART_NO-MFG_ID-MFG_DATE_CODE-SERIAL_NO-LABEL_REV */
Expand Down Expand Up @@ -461,6 +465,18 @@ struct smf_sio_data {
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)
{
Expand Down Expand Up @@ -552,6 +568,40 @@ static ssize_t show_power_on_reason(struct device *dev,
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 */
static ssize_t
show_fan_label(struct device *dev, struct device_attribute *attr, char *buf)
Expand Down Expand Up @@ -1981,11 +2031,16 @@ static SENSOR_DEVICE_ATTR(smf_reset_reason, S_IRUGO, show_reset_reason, NULL, 1)
static SENSOR_DEVICE_ATTR(smf_poweron_reason, S_IRUGO,
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[] = {
&sensor_dev_attr_smf_version.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_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_fan1_airflow.dev_attr.attr,
&sensor_dev_attr_fan3_airflow.dev_attr.attr,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,11 @@ def get_reboot_cause(self):

# In S6000, We track the reboot reason by writing the reason in
# 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):
return (self.reset_reason_dict[reset_reason], None)

return (ChassisBase.REBOOT_CAUSE_HARDWARE_OTHER, "Invalid Reason")
return (ChassisBase.REBOOT_CAUSE_NON_HARDWARE, None)

Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,25 @@ reset_muxes() {
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 == "01"]; then
cd /sys/devices/platform/SMF.512/hwmon/*
echo 0xaa > mb_poweron_reason
fi
fi
}

install_python_api_package() {
device="/usr/share/sonic/device"
platform=$(/usr/local/bin/sonic-cfggen -H -v DEVICE_METADATA.localhost.platform)
Expand All @@ -239,6 +258,7 @@ if [[ "$1" == "init" ]]; then
modprobe dell_ich
modprobe dell_s6100_iom_cpld
modprobe dell_s6100_lpc
track_reboot_reason

# Disable Watchdog Timer
if [[ -e /usr/local/bin/platform_watchdog_disable.sh ]]; then
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,13 @@ def _get_pmc_register(self, reg_name):
rv = rv.lstrip(" ")
return rv

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)

# Run bash command and print output to stdout
def run_command(self, command):
click.echo(click.style("Command: ", fg='cyan') +
Expand Down Expand Up @@ -236,6 +243,10 @@ def get_reboot_cause(self):

reset_reason = int(self._get_pmc_register('smf_reset_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
# So return the reboot reason from Last Power_Reason Dictionary
Expand All @@ -244,10 +255,16 @@ def get_reboot_cause(self):
# checking key presence in dictionary else return
# REBOOT_CAUSE_HARDWARE_OTHER as the Power_Reason and Reset_Reason
# 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 (power_reason in self.power_reason_dict):
return (self.power_reason_dict[power_reason], None)
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):
return (self.reset_reason_dict[reset_reason], None)

Expand Down