diff options
author | Ed Tanous <ed.tanous@intel.com> | 2019-08-19 21:16:19 +0300 |
---|---|---|
committer | Ed Tanous <ed@tanous.net> | 2019-08-20 18:56:17 +0300 |
commit | 35e295e2a161fcf146ea031de53431b2888521fa (patch) | |
tree | a0c78943fef5c085f371aaa840d46edecc1f2e95 /meta-openbmc-mods/meta-common | |
parent | 9856ac69064742544fafad307d3ee4544385ffa2 (diff) | |
download | openbmc-35e295e2a161fcf146ea031de53431b2888521fa.tar.xz |
Sync to internal 8-19-2019
Signed-off-by: Ed Tanous <ed.tanous@intel.com>
Diffstat (limited to 'meta-openbmc-mods/meta-common')
69 files changed, 2718 insertions, 1120 deletions
diff --git a/meta-openbmc-mods/meta-common/classes/image_types_intel_pfr.bbclass b/meta-openbmc-mods/meta-common/classes/image_types_intel_pfr.bbclass index 834c09229..9962e7df6 100644 --- a/meta-openbmc-mods/meta-common/classes/image_types_intel_pfr.bbclass +++ b/meta-openbmc-mods/meta-common/classes/image_types_intel_pfr.bbclass @@ -1,6 +1,7 @@ inherit obmc-phosphor-full-fitimage
+DEPENDS += "obmc-intel-pfr-image-native"
require recipes-core/os-release/version-vars.inc
@@ -38,7 +39,7 @@ do_image_pfr () { cd "${PFR_IMAGES_DIR}"
# python script that does the creating PFM, BMC compressed and unsigned images from BMC 128MB raw binary file.
- python ${PFR_STAGING_DIR}/pfr_image.py ${PFR_STAGING_DIR}/pfr_image-manifest.json ${DEPLOY_DIR_IMAGE}/image-mtd ${build_version} ${build_number} ${build_hash}
+ python ${PFR_STAGING_DIR}/pfr_image.py ${PFR_STAGING_DIR}/pfr_manifest.json ${DEPLOY_DIR_IMAGE}/image-mtd ${build_version} ${build_number} ${build_hash}
# sign the PFM region
${PFR_STAGING_DIR}/blocksign -c ${PFR_STAGING_DIR}/pfm_config.xml -o ${PFR_IMAGES_DIR}/pfm_signed.bin ${PFR_IMAGES_DIR}/pfm.bin
diff --git a/meta-openbmc-mods/meta-common/classes/obmc-phosphor-image-common.bbclass b/meta-openbmc-mods/meta-common/classes/obmc-phosphor-image-common.bbclass index a495b76fa..6a3ad73d7 100644 --- a/meta-openbmc-mods/meta-common/classes/obmc-phosphor-image-common.bbclass +++ b/meta-openbmc-mods/meta-common/classes/obmc-phosphor-image-common.bbclass @@ -1,4 +1,5 @@ inherit obmc-phosphor-image +inherit systemd-watchdog IMAGE_INSTALL_append = " \ bmcweb \ @@ -33,6 +34,7 @@ IMAGE_INSTALL_append = " \ phosphor-u-boot-mgr \ prov-mode-mgr \ ac-boot-check \ + beepcode-mgr \ " # this package was flagged as a security risk diff --git a/meta-openbmc-mods/meta-common/classes/systemd-watchdog.bbclass b/meta-openbmc-mods/meta-common/classes/systemd-watchdog.bbclass new file mode 100644 index 000000000..4cc3845c6 --- /dev/null +++ b/meta-openbmc-mods/meta-common/classes/systemd-watchdog.bbclass @@ -0,0 +1,27 @@ +add_watchdog_confs() { + + interval=10 # minutes + count=5 # allowed reboots + + for service in $(ls $D/lib/systemd/system | grep -o ".*service"); do + if [[ $service == *"mapper-wait"* ]]; then + continue + fi + + if cat $D/lib/systemd/system/${service} | grep oneshot > /dev/null; then + continue + fi + + folder="$D/etc/systemd/system/${service}.d" + mkdir -p "${folder}" + fname="${folder}/watchdog.conf" + echo "[Unit]" > ${fname} + echo "OnFailure=watchdog-reset.service" >> ${fname} + echo "[Service]" >> "${fname}" + echo "StartLimitInterval=${interval}min" >> "${fname}" + echo "StartLimitBurst=${count}" >> "${fname}" + done + +} + +ROOTFS_POSTINSTALL_COMMAND += "add_watchdog_confs" diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0025-Manufacturing-mode-physical-presence-detection.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0025-Manufacturing-mode-physical-presence-detection.patch index 7e75acb02..2d63314af 100644 --- a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0025-Manufacturing-mode-physical-presence-detection.patch +++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0025-Manufacturing-mode-physical-presence-detection.patch @@ -1,17 +1,23 @@ -From 0e83d58efe5bd34430c953713285293cd0756b69 Mon Sep 17 00:00:00 2001 +From 4c87d6074fb36d423f135392983d225785abf43a Mon Sep 17 00:00:00 2001 From: AppaRao Puli <apparao.puli@linux.intel.com> Date: Thu, 20 Jun 2019 18:11:43 +0530 Subject: [PATCH] Manufacturing mode physical presence detection Support for physical presence of manufacturing mode added. -Front panel power button press for 8 seconds will be detected -and marked as special mode for manufacturing request +Front panel power button press for 15 seconds will be detected +and marked as special mode for manufacturing request. +There will be 10 second Status LED blink for 10 seconds to +do the physical indication to the user. This indicates the +user that he has pressed power button long enough for +manufacturing mode detection. Tested: 1. Verified by holding the power button when u-boot boots for -8 seconds, and confirmed that bootargs passed to linux has -special=mfg string -2. Verified in normal condition special=mfg string is not passed. +15 seconds, and confirmed that bootargs passed to linux has +special=mfg string and status led blink physical indication +has been provided +2. Verified in normal condition special=mfg string is not passed +and no physical indication has been provided Change-Id: Id7e7c7e7860c7ef3ae8e3a7a7cfda7ff506c0f2b Signed-off-by: Richard Marian Thomaiyar <richard.marian.thomaiyar@linux.intel.com> @@ -19,8 +25,8 @@ Signed-off-by: AppaRao Puli <apparao.puli@linux.intel.com> --- board/aspeed/ast-g5/ast-g5-gpio.h | 2 +- - board/aspeed/ast-g5/ast-g5-intel.c | 31 +++++++++++++++++++++++++++++++ - 2 files changed, 32 insertions(+), 1 deletion(-) + board/aspeed/ast-g5/ast-g5-intel.c | 35 +++++++++++++++++++++++++++++++++++ + 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/board/aspeed/ast-g5/ast-g5-gpio.h b/board/aspeed/ast-g5/ast-g5-gpio.h index a820c0f..ed2499f 100644 @@ -36,7 +42,7 @@ index a820c0f..ed2499f 100644 // GPIO Configuration Register bits #define GPCFG_EVENT_TO_SMI (1 << 7) // 1 == enabled diff --git a/board/aspeed/ast-g5/ast-g5-intel.c b/board/aspeed/ast-g5/ast-g5-intel.c -index 55afa09..812e3ef 100644 +index 55afa09..452cb5c 100644 --- a/board/aspeed/ast-g5/ast-g5-intel.c +++ b/board/aspeed/ast-g5/ast-g5-intel.c @@ -24,6 +24,7 @@ enum gpio_names { @@ -58,7 +64,7 @@ index 55afa09..812e3ef 100644 }; #define LPC_SNOOP_ADDR 0x80 -@@ -373,6 +378,26 @@ static void update_bootargs_cmd(const char *key, const char *value) +@@ -373,6 +378,30 @@ static void update_bootargs_cmd(const char *key, const char *value) free(buf); } @@ -66,11 +72,12 @@ index 55afa09..812e3ef 100644 +{ + /* + * Assume mfg mode physical request is made, if power button -+ * is pressed continously for 8 seconds, indicate the ++ * is pressed continously for 15 seconds, indicate the + * same in bootargs + */ + const uint32_t delay_in_ms = 100; -+ const uint32_t read_count = ((8 * 1000) / delay_in_ms); ++ const uint32_t read_count = ((15 * 1000) / delay_in_ms); ++ const uint32_t delay_for_indication = 10 * 1000; + for (uint32_t count = 0; count < read_count; ++count) { + if (!gpio_get_value(GPIO_FP_PWR_BTN)) + return false; @@ -78,6 +85,9 @@ index 55afa09..812e3ef 100644 + mdelay(delay_in_ms); + } + debug("is_mfg_mode_phy_req : detected mfg mode request\n"); ++ id_led_control(GPIO_GREEN_LED, EIDLED_Blink_3HZ); ++ /* Delay the boot to do physical indication for mfg mode */ ++ mdelay(delay_for_indication); + + return true; +} @@ -85,7 +95,7 @@ index 55afa09..812e3ef 100644 void ast_g5_intel_late_init(void) { char value[32]; -@@ -420,6 +445,12 @@ void ast_g5_intel_late_init(void) +@@ -420,6 +449,12 @@ void ast_g5_intel_late_init(void) ast_scu_write(0, AST_SCU_SYS_CTRL); update_bootargs_cmd("resetreason", value); @@ -98,3 +108,6 @@ index 55afa09..812e3ef 100644 } static void pwm_init(void) +-- +2.7.4 + diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0032-Adding-PFR-boot-flow-checkpoint-in-u-boot.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0032-Adding-PFR-boot-flow-checkpoint-in-u-boot.patch deleted file mode 100644 index b76a3dba0..000000000 --- a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0032-Adding-PFR-boot-flow-checkpoint-in-u-boot.patch +++ /dev/null @@ -1,102 +0,0 @@ -From dda24946edd0a4ec54e3ecaa8bd493cce9bdfa15 Mon Sep 17 00:00:00 2001 -From: AppaRao Puli <apparao.puli@linux.intel.com> -Date: Mon, 22 Jul 2019 08:26:15 +0530 -Subject: [PATCH] Adding PFR boot flow checkpoint in u-boot - -Added two PFR boot flow check points in u-boot -1) Set the booting starts checkpoint(0x01) -2) Set FFUJ checkpoint(0x07) when jumper on. - -Tested: -Loaded the image, dumped all cpld registers and -cross verified the check-points properly set or not. - -Change-Id: I3c725b0e15c1fea5bdb7b085826bdabad19bda80 -Signed-off-by: AppaRao Puli <apparao.puli@linux.intel.com> ---- - board/aspeed/ast-g5/ast-g5-intel.c | 46 ++++++++++++++++++++++++++++++++++++++ - 1 file changed, 46 insertions(+) - -diff --git a/board/aspeed/ast-g5/ast-g5-intel.c b/board/aspeed/ast-g5/ast-g5-intel.c -index e68ab85..9f0a64d 100644 ---- a/board/aspeed/ast-g5/ast-g5-intel.c -+++ b/board/aspeed/ast-g5/ast-g5-intel.c -@@ -12,11 +12,21 @@ - #include <asm/arch/regs-scu.h> - #include <asm/arch/ast_scu.h> - #include <asm/arch/aspeed.h> -+#include <i2c.h> - - #include "ast-g5.h" - #include "ast-g5-gpio.h" - #include "ast-g5-timer.h" - -+/* PFR Specific defines */ -+#define PFR_CPLD_I2C_BUSNO 4 -+#define PFR_CPLD_SLAVE_ADDR 0xE0 -+#define PFR_CPLD_BOOT_CHECKPOINT_REG 0x13 -+ -+#define PFR_CPLD_CHKPOINT_START 0x01 -+#define PFR_CPLD_CHKPOINT_FFUJ 0x07 -+#define PFR_CPLD_CHKPOINT_FINISHED 0x09 -+ - /* Names to match the GPIOs */ - enum gpio_names { - GPIO_ID_LED = 0, -@@ -537,10 +547,42 @@ static void pwm_init(void) - writel(val, PWM_BASE_ADDR + PWM_CONTROL); - } - -+static void set_boot_checkpoint(u8 chk_point) -+{ -+ int ret = 0; -+ int chip = (PFR_CPLD_SLAVE_ADDR >> 1); -+ u32 reg_addr = PFR_CPLD_BOOT_CHECKPOINT_REG; -+ -+ /* Get current I2C bus number to restore later. */ -+ int current_bus_no = i2c_get_bus_num(); -+ -+ /* Set I2C bus number to PFR CPLD I2C bus. */ -+ ret = i2c_set_bus_num(PFR_CPLD_I2C_BUSNO); -+ if (ret) { -+ printf("Failed to change I2C bus number (%d)\n", ret); -+ goto done; -+ } -+ -+ ret = i2c_write(chip, reg_addr, 1, &chk_point, 1); -+ if (ret) { -+ printf("Error writing the chip: %d\n", ret); -+ goto done; -+ } -+ -+done: -+ /* Restore I2C bus number */ -+ if (i2c_set_bus_num(current_bus_no)) -+ printf("Failed to restore I2C bus number.\n"); -+} -+ - extern void espi_init(void); - extern void kcs_init(void); - void ast_g5_intel(void) - { -+ /* To notify the CPLD about the start of bootloader -+ * and hardware initialization */ -+ set_boot_checkpoint(PFR_CPLD_CHKPOINT_START); -+ - uart_init(); - pwm_init(); - gpio_init(gpio_table, ARRAY_SIZE(gpio_table)); -@@ -551,6 +593,10 @@ void ast_g5_intel(void) - if (intel_force_firmware_jumper_enabled()) { - id_led_control(GPIO_AMBER_LED, EIDLED_On); - kcs_init(); -+ /* Notify CPLD about FFUJ jumper set and pause -+ * of booting for indefinitely time. It will be -+ * resumed once reset is done. */ -+ set_boot_checkpoint(PFR_CPLD_CHKPOINT_FFUJ); - /* TODO: need to stop the booting here. */ - } else { - id_led_control(GPIO_GREEN_LED, EIDLED_On); --- -2.7.4 - diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0033-PFR-firmware-update-support-in-u-boot.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0032-PFR-FW-update-and-checkpoint-support-in-u-boot.patch index 80a949a87..7700e067f 100644 --- a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0033-PFR-firmware-update-support-in-u-boot.patch +++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0032-PFR-FW-update-and-checkpoint-support-in-u-boot.patch @@ -1,28 +1,36 @@ -From d9287ee5f3b797fd492ec78617c174ad20e85bc4 Mon Sep 17 00:00:00 2001 +From 0c975e64ca8bd5fdaf12f15b4dbc9ceaa942c36c Mon Sep 17 00:00:00 2001 From: AppaRao Puli <apparao.puli@linux.intel.com> Date: Wed, 24 Jul 2019 20:11:30 +0530 -Subject: [PATCH] PFR firmware update support in u-boot +Subject: [PATCH] PFR FW update and checkpoint support in u-boot -Added firmware update ipmi commands support +1) Added firmware update ipmi commands support for PFR images. This enables PFR based firmware updates for components BMC, BIOS and CPLD during FFUJ mode. +2) Added two PFR boot flow checkpoint in u-boot + - Set the booting starts checkpoint(0x01) + - Set FFUJ checkpoint(0x07) when jumper on. + +Tested: + Tested: -Using debug fwpiaupd.efi utility, validated the PFR -BMC image update. +1) Using debug fwpiaupd.efi utility, validated the PFR +BMC image update via KCS ( In FFUJ mode). +2) Loaded the image, dumped all cpld registers and +cross verified the check-points properly set or not. -Change-Id: Ic2b550c42208f52ec865da463e6518bf8c503c15 Signed-off-by: AppaRao Puli <apparao.puli@linux.intel.com> --- - board/aspeed/ast-g5/Makefile | 1 + - board/aspeed/ast-g5/fw-update.c | 112 ++++++++++++++++++++------------------- - board/aspeed/ast-g5/fw-update.h | 7 +++ - board/aspeed/ast-g5/ipmi-fwupd.c | 37 +++++++++++++ - board/aspeed/ast-g5/ipmi-fwupd.h | 6 --- - board/aspeed/ast-g5/pfr-mgr.c | 73 +++++++++++++++++++++++++ - board/aspeed/ast-g5/pfr-mgr.h | 67 +++++++++++++++++++++++ - 7 files changed, 242 insertions(+), 61 deletions(-) + board/aspeed/ast-g5/Makefile | 1 + + board/aspeed/ast-g5/ast-g5-intel.c | 10 ++++ + board/aspeed/ast-g5/fw-update.c | 112 +++++++++++++++++++------------------ + board/aspeed/ast-g5/fw-update.h | 7 +++ + board/aspeed/ast-g5/ipmi-fwupd.c | 37 ++++++++++++ + board/aspeed/ast-g5/ipmi-fwupd.h | 6 -- + board/aspeed/ast-g5/pfr-mgr.c | 73 ++++++++++++++++++++++++ + board/aspeed/ast-g5/pfr-mgr.h | 73 ++++++++++++++++++++++++ + 8 files changed, 258 insertions(+), 61 deletions(-) create mode 100644 board/aspeed/ast-g5/pfr-mgr.c create mode 100644 board/aspeed/ast-g5/pfr-mgr.h @@ -35,6 +43,41 @@ index 0b2d936..9021d7f 100644 obj-y += ipmi-fwupd.o obj-y += fw-update.o +obj-y += pfr-mgr.o +diff --git a/board/aspeed/ast-g5/ast-g5-intel.c b/board/aspeed/ast-g5/ast-g5-intel.c +index e68ab85..cd359ce 100644 +--- a/board/aspeed/ast-g5/ast-g5-intel.c ++++ b/board/aspeed/ast-g5/ast-g5-intel.c +@@ -16,6 +16,7 @@ + #include "ast-g5.h" + #include "ast-g5-gpio.h" + #include "ast-g5-timer.h" ++#include "pfr-mgr.h" + + /* Names to match the GPIOs */ + enum gpio_names { +@@ -541,6 +542,10 @@ extern void espi_init(void); + extern void kcs_init(void); + void ast_g5_intel(void) + { ++ /* To notify the CPLD about the start of bootloader ++ * and hardware initialization */ ++ set_cpld_reg(PFR_CPLD_BOOT_CHECKPOINT_REG, PFR_CPLD_CHKPOINT_START); ++ + uart_init(); + pwm_init(); + gpio_init(gpio_table, ARRAY_SIZE(gpio_table)); +@@ -551,6 +556,11 @@ void ast_g5_intel(void) + if (intel_force_firmware_jumper_enabled()) { + id_led_control(GPIO_AMBER_LED, EIDLED_On); + kcs_init(); ++ /* Notify CPLD about FFUJ jumper set and pause ++ * of booting for indefinitely time. It will be ++ * resumed once reset is done. */ ++ set_cpld_reg(PFR_CPLD_BOOT_CHECKPOINT_REG, ++ PFR_CPLD_CHKPOINT_FFUJ); + /* TODO: need to stop the booting here. */ + } else { + id_led_control(GPIO_GREEN_LED, EIDLED_On); diff --git a/board/aspeed/ast-g5/fw-update.c b/board/aspeed/ast-g5/fw-update.c index 9923993..89fe5fd 100644 --- a/board/aspeed/ast-g5/fw-update.c @@ -404,10 +447,10 @@ index 0000000..7713168 + diff --git a/board/aspeed/ast-g5/pfr-mgr.h b/board/aspeed/ast-g5/pfr-mgr.h new file mode 100644 -index 0000000..b2368e1 +index 0000000..6cf8c6d --- /dev/null +++ b/board/aspeed/ast-g5/pfr-mgr.h -@@ -0,0 +1,67 @@ +@@ -0,0 +1,73 @@ +// SPDX-License-Identifier: GPL-2.0+ +// Copyright (c) 2018-2019 Intel Corporation + @@ -418,8 +461,14 @@ index 0000000..b2368e1 +#define PFR_CPLD_SLAVE_ADDR 0xE0 + +/* CPLD registers */ ++#define PFR_CPLD_BOOT_CHECKPOINT_REG 0x0F +#define PFR_CPLD_BMC_UPDATE_INTENT_REG 0x13 + ++/* PFR checkpoints */ ++#define PFR_CPLD_CHKPOINT_START 0x01 ++#define PFR_CPLD_CHKPOINT_FFUJ 0x07 ++#define PFR_CPLD_CHKPOINT_FINISHED 0x09 ++ +#define PFR_BLOCK0_MAGIC_NUM 0xB6EAFD19 +#define PFR_AUTH_DATA_STRUCT_LEN 1024 /* Block0 & Block1 */ + diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0033-Reboot-into-UBOOT-on-Watchdog-Failures.patch b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0033-Reboot-into-UBOOT-on-Watchdog-Failures.patch new file mode 100644 index 000000000..e673da7ee --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/files/0033-Reboot-into-UBOOT-on-Watchdog-Failures.patch @@ -0,0 +1,110 @@ +From c82bf9de515cbbdb4ea1a350be83fb89f4a83631 Mon Sep 17 00:00:00 2001 +From: James Feist <james.feist@linux.intel.com> +Date: Wed, 31 Jul 2019 16:01:49 -0700 +Subject: [PATCH 1/1] Reboot into UBOOT on Watchdog Failures + +We use watchdog1 to reboot when there is a watchdog +error. Reboot into u-boot as we are using that as +safe mode. + +Tested: watchdog -T 0 -F /dev/watchdog1 reboots into +uboot after 3 times + +Signed-off-by: James Feist <james.feist@linux.intel.com> +--- + .../include/asm/arch-aspeed/ast-g5-intel.h | 1 + + board/aspeed/ast-g5/ast-g5-intel.c | 31 +++++++++++++++++++ + common/autoboot.c | 2 ++ + 3 files changed, 34 insertions(+) + +diff --git a/arch/arm/include/asm/arch-aspeed/ast-g5-intel.h b/arch/arm/include/asm/arch-aspeed/ast-g5-intel.h +index a88521a1b3..64f4ed17bf 100644 +--- a/arch/arm/include/asm/arch-aspeed/ast-g5-intel.h ++++ b/arch/arm/include/asm/arch-aspeed/ast-g5-intel.h +@@ -14,6 +14,7 @@ + + #ifndef __ASSEMBLY__ + int intel_force_firmware_jumper_enabled(void); ++int intel_failed_boot(void); + void start_fw_update_loop(void); + #endif + +diff --git a/board/aspeed/ast-g5/ast-g5-intel.c b/board/aspeed/ast-g5/ast-g5-intel.c +index e68ab8546a..c003d9a7bc 100644 +--- a/board/aspeed/ast-g5/ast-g5-intel.c ++++ b/board/aspeed/ast-g5/ast-g5-intel.c +@@ -111,6 +111,24 @@ static const GPIOValue gpio_table[] = { + #define HOST_SERIAL_A_HIGH_SPEED (1 << 0) + #define HOST_SERIAL_B_HIGH_SPEED (1 << 1) + ++#define WATCHDOG_RESET_BIT 0x8 ++#define BOOT_FAILURE_LIMIT 0x3 ++ ++static int get_boot_failures(void) ++{ ++ return getenv_ulong("bootfailures", 10, 0); ++} ++ ++static void set_boot_failures(u32 count) ++{ ++ if (count > BOOT_FAILURE_LIMIT) ++ return; ++ ++ setenv_ulong("bootfailures", count); ++ saveenv(); ++} ++ ++ + static void sgpio_init(void) + { + uint32_t value; +@@ -270,6 +288,11 @@ int intel_force_firmware_jumper_enabled(void) + return gpio_get_value(GPIO_FF_UPD_JUMPER); + } + ++int intel_failed_boot(void) ++{ ++ return get_boot_failures() >= BOOT_FAILURE_LIMIT; ++} ++ + void arch_preboot_os(void) + { + // last second before booting... set the LEDs +@@ -402,6 +425,7 @@ void ast_g5_intel_late_init(void) + { + char value[32]; + u32 reset_reason = 0; ++ u32 boot_failures = 0; + + /* By default host serail A and B use normal speed */ + uint32_t host_serial_cfg = 0; +@@ -446,6 +470,13 @@ void ast_g5_intel_late_init(void) + + update_bootargs_cmd("resetreason", value); + ++ boot_failures = get_boot_failures(); ++ ++ if (reset_reason & WATCHDOG_RESET_BIT) ++ set_boot_failures(boot_failures + 1); ++ else ++ set_boot_failures(0); ++ + /* Update the special mode in bootargs */ + if (is_mfg_mode_phy_req()) + update_bootargs_cmd("special", "mfg"); +diff --git a/common/autoboot.c b/common/autoboot.c +index 45a600e663..03fd164501 100644 +--- a/common/autoboot.c ++++ b/common/autoboot.c +@@ -263,6 +263,8 @@ static int abortboot(int bootdelay) + # ifdef AST_G5_INTEL + if (intel_force_firmware_jumper_enabled()) + return 1; ++ if (intel_failed_boot()) ++ return 1; + # endif + + if (bootdelay >= 0) +-- +2.17.1 + diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/u-boot-aspeed_%.bbappend b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/u-boot-aspeed_%.bbappend index 5d8c10a76..09544cfb2 100644 --- a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/u-boot-aspeed_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/u-boot-aspeed_%.bbappend @@ -33,11 +33,11 @@ SRC_URI_append_intel-ast2500 = " \ file://0029-FFUJ-FW-IPMI-commands-and-flash-support-in-u-boot.patch \ file://0030-Support-Get-Set-Security-mode-command.patch \ file://0031-Make-it-so-TFTP-port-can-be-modified.patch \ + file://0033-Reboot-into-UBOOT-on-Watchdog-Failures.patch \ " PFR_SRC_URI = " \ file://0022-u-boot-env-change-for-PFR-image.patch \ - file://0032-Adding-PFR-boot-flow-checkpoint-in-u-boot.patch \ - file://0033-PFR-firmware-update-support-in-u-boot.patch \ + file://0032-PFR-FW-update-and-checkpoint-support-in-u-boot.patch \ " SRC_URI_append_intel-ast2500 += "${@bb.utils.contains('IMAGE_FSTYPES', 'intel-pfr', PFR_SRC_URI, '', d)}" diff --git a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/u-boot-fw-utils-aspeed_%.bbappend b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/u-boot-fw-utils-aspeed_%.bbappend index 5d8c10a76..09544cfb2 100644 --- a/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/u-boot-fw-utils-aspeed_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-bsp/u-boot/u-boot-fw-utils-aspeed_%.bbappend @@ -33,11 +33,11 @@ SRC_URI_append_intel-ast2500 = " \ file://0029-FFUJ-FW-IPMI-commands-and-flash-support-in-u-boot.patch \ file://0030-Support-Get-Set-Security-mode-command.patch \ file://0031-Make-it-so-TFTP-port-can-be-modified.patch \ + file://0033-Reboot-into-UBOOT-on-Watchdog-Failures.patch \ " PFR_SRC_URI = " \ file://0022-u-boot-env-change-for-PFR-image.patch \ - file://0032-Adding-PFR-boot-flow-checkpoint-in-u-boot.patch \ - file://0033-PFR-firmware-update-support-in-u-boot.patch \ + file://0032-PFR-FW-update-and-checkpoint-support-in-u-boot.patch \ " SRC_URI_append_intel-ast2500 += "${@bb.utils.contains('IMAGE_FSTYPES', 'intel-pfr', PFR_SRC_URI, '', d)}" diff --git a/meta-openbmc-mods/meta-common/recipes-core/at-scale-debug/at-scale-debug.bb b/meta-openbmc-mods/meta-common/recipes-core/at-scale-debug/at-scale-debug_git.bb index 5576c84c7..170f41a94 100644 --- a/meta-openbmc-mods/meta-common/recipes-core/at-scale-debug/at-scale-debug.bb +++ b/meta-openbmc-mods/meta-common/recipes-core/at-scale-debug/at-scale-debug_git.bb @@ -12,9 +12,9 @@ DEPENDS = "sdbusplus openssl libpam" do_configure[depends] += "virtual/kernel:do_shared_workdir" -SRC_URI = "git://git@github.com/Intel-BMC/at-scale-debug;protocol=ssh" +SRC_URI = "git://git@github.com/Intel-BMC/asd;protocol=ssh;nobranch=1" +SRCREV = "73d4cc11b859ba91f313a7bb85f2dbb26e36d0ee" -SRCREV = "bf2736cb1c8959164f989f59c4337a0ff108b13f" S = "${WORKDIR}/git" SYSTEMD_SERVICE_${PN} += "com.intel.AtScaleDebug.service" diff --git a/meta-openbmc-mods/meta-common/recipes-core/crashdump/crashdump_git.bb b/meta-openbmc-mods/meta-common/recipes-core/crashdump/crashdump_git.bb index 63f65e03d..68a548b02 100644 --- a/meta-openbmc-mods/meta-common/recipes-core/crashdump/crashdump_git.bb +++ b/meta-openbmc-mods/meta-common/recipes-core/crashdump/crashdump_git.bb @@ -4,16 +4,18 @@ inherit obmc-phosphor-systemd SUMMARY = "CPU Crashdump" DESCRIPTION = "CPU utilities for dumping CPU Crashdump and registers over PECI" -DEPENDS = "boost cjson sdbusplus safec " +DEPENDS = "boost cjson sdbusplus safec gtest " inherit cmake -LICENSE = "CLOSED" -LIC_FILES_CHKSUM = "" +EXTRA_OECMAKE = "-DCRASHDUMP_BUILD_UT=ON" -SRC_URI = "git://git@github.com/Intel-BMC/at-scale-debug;protocol=ssh" -SRCREV = "bf2736cb1c8959164f989f59c4337a0ff108b13f" +LICENSE = "Proprietary" +LIC_FILES_CHKSUM = "file://LICENSE;md5=26bb6d0733830e7bab774914a8f8f20a" -S = "${WORKDIR}/git/crashdump" +SRC_URI = "git://git@github.com/Intel-BMC/crashdump;protocol=ssh;nobranch=1" +SRCREV = "c99e4fb7727545501fe65b90a8a97e84d469d45e" + +S = "${WORKDIR}/git" PACKAGES += "libpeci" SYSTEMD_SERVICE_${PN} += "com.intel.crashdump.service" diff --git a/meta-openbmc-mods/meta-common/recipes-core/host-error-monitor/host-error-monitor_git.bb b/meta-openbmc-mods/meta-common/recipes-core/host-error-monitor/host-error-monitor_git.bb index 1733ac428..483a9bf12 100644 --- a/meta-openbmc-mods/meta-common/recipes-core/host-error-monitor/host-error-monitor_git.bb +++ b/meta-openbmc-mods/meta-common/recipes-core/host-error-monitor/host-error-monitor_git.bb @@ -7,7 +7,7 @@ SRC_URI = "git://git@github.com/Intel-BMC/at-scale-debug;protocol=ssh" DEPENDS = "boost sdbusplus libgpiod" PV = "0.1+git${SRCPV}" -SRCREV = "bf2736cb1c8959164f989f59c4337a0ff108b13f" +SRCREV = "6ed87657134c7379da1febcccd5d87617c702347" S = "${WORKDIR}/git/host_error_monitor" diff --git a/meta-openbmc-mods/meta-common/recipes-core/ipmi/intel-ipmi-oem_%.bbappend b/meta-openbmc-mods/meta-common/recipes-core/ipmi/intel-ipmi-oem_%.bbappend index e79a42fcd..53fc218c6 100644 --- a/meta-openbmc-mods/meta-common/recipes-core/ipmi/intel-ipmi-oem_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-core/ipmi/intel-ipmi-oem_%.bbappend @@ -1,2 +1,2 @@ SRC_URI = "git://github.com/openbmc/intel-ipmi-oem.git" -SRCREV = "6ae0818f82bcfc6c5568dd2107d0656da5410f61" +SRCREV = "773703a58db91f69f2ecb32d3c69d9984fba504e" diff --git a/meta-openbmc-mods/meta-common/recipes-core/peci-pcie/peci-pcie_git.bb b/meta-openbmc-mods/meta-common/recipes-core/peci-pcie/peci-pcie_git.bb index 01ef73964..e19e5fc93 100644 --- a/meta-openbmc-mods/meta-common/recipes-core/peci-pcie/peci-pcie_git.bb +++ b/meta-openbmc-mods/meta-common/recipes-core/peci-pcie/peci-pcie_git.bb @@ -10,7 +10,7 @@ SRC_URI = "git://git@github.com/Intel-BMC/at-scale-debug;protocol=ssh" DEPENDS = "boost sdbusplus crashdump" PV = "0.1+git${SRCPV}" -SRCREV = "bf2736cb1c8959164f989f59c4337a0ff108b13f" +SRCREV = "6ed87657134c7379da1febcccd5d87617c702347" S = "${WORKDIR}/git/peci_pcie" diff --git a/meta-openbmc-mods/meta-common/recipes-graphics/obmc-ikvm/obmc-ikvm_%.bbappend b/meta-openbmc-mods/meta-common/recipes-graphics/obmc-ikvm/obmc-ikvm_%.bbappend index 577a78601..cc18a9b43 100644 --- a/meta-openbmc-mods/meta-common/recipes-graphics/obmc-ikvm/obmc-ikvm_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-graphics/obmc-ikvm/obmc-ikvm_%.bbappend @@ -1,6 +1,6 @@ FILESEXTRAPATHS_append := ":${THISDIR}/${PN}" #SRC_URI = "git://github.com/openbmc/obmc-ikvm" -SRCREV = "133bfa2d5b1b3af0b8e819b4cd210a0e1ac0445c" +SRCREV = "95a3b35bf30f730d2bc512bd42aea45746c625e6" SRC_URI += "file://0001-Add-flow-control-to-prevent-buffer-over-run.patch" diff --git a/meta-openbmc-mods/meta-common/recipes-intel/chassis/intel-chassis-control.bb b/meta-openbmc-mods/meta-common/recipes-intel/chassis/intel-chassis-control.bb index ea7579cb3..f727b4536 100644 --- a/meta-openbmc-mods/meta-common/recipes-intel/chassis/intel-chassis-control.bb +++ b/meta-openbmc-mods/meta-common/recipes-intel/chassis/intel-chassis-control.bb @@ -2,7 +2,7 @@ SUMMARY = "Chassis Power Control service for Intel based platform" DESCRIPTION = "Chassis Power Control service for Intel based platfrom" SRC_URI = "git://git@github.com/Intel-BMC/intel-chassis-control.git;protocol=ssh" -SRCREV = "8d7026c078d79d5e60e7938e4e5f08bb7966ebbd" +SRCREV = "b9e1b13e42359baf21592480874a176548071cf2" S = "${WORKDIR}/git/services/chassis/" diff --git a/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/files/blocksign b/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/files/blocksign Binary files differdeleted file mode 100755 index 69d51d2ba..000000000 --- a/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/files/blocksign +++ /dev/null diff --git a/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/files/bmc_config.xml b/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/files/bmc_config.xml index 89c3d30ca..9e7d3f82d 100644 --- a/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/files/bmc_config.xml +++ b/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/files/bmc_config.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?>
<!-- XML file for Block Sign Tool -->
<blocksign>
+ <version>1</version>
<!-- Block 0 -->
<block0>
<magic>0xB6EAFD19</magic>
diff --git a/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/files/pfm_config.xml b/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/files/pfm_config.xml index 215fe8783..78c816191 100644 --- a/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/files/pfm_config.xml +++ b/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/files/pfm_config.xml @@ -1,6 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?>
<!-- XML file for Block Sign Tool -->
<blocksign>
+ <version>1</version>
<!-- Block 0 -->
<block0>
<magic>0xB6EAFD19</magic>
diff --git a/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/files/pfr_image-manifest.json b/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/files/pfr_image-manifest.json deleted file mode 100644 index 7890aa700..000000000 --- a/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/files/pfr_image-manifest.json +++ /dev/null @@ -1,63 +0,0 @@ -{
- "image-parts": [{
- "name": "u-boot",
- "index": 0,
- "offset": "0",
- "size": "0x80000",
- "prot_mask": 31,
- "pfm": 1,
- "hash": 1,
- "compress": 1
- },
- {
- "name": "pfm",
- "index": 1,
- "offset": "0x80000",
- "size": "0x20000",
- "prot_mask": 31,
- "pfm": 1,
- "hash": 0,
- "compress": 0
- },
- {
- "name": "u-boot-env",
- "index": 2,
- "offset": "0xa0000",
- "size": "0x20000",
- "prot_mask": 29,
- "pfm": 1,
- "hash": 0,
- "compress": 0
- },
- {
- "name": "sofs",
- "index": 3,
- "offset": "0xc0000",
- "size": "0x200000",
- "prot_mask": 29,
- "pfm": 1,
- "hash": 0,
- "compress": 0
- },
- {
- "name": "rwfs",
- "index": 4,
- "offset": "0x2c0000",
- "size": "0x840000",
- "prot_mask": 29,
- "pfm": 1,
- "hash": 0,
- "compress": 0
- },
- {
- "name": "fit-image-a",
- "index": 5,
- "offset": "0xb00000",
- "size": "0x1f00000",
- "prot_mask": 31,
- "pfm": 1,
- "hash": 1,
- "compress": 1
- }
- ]
-}
\ No newline at end of file diff --git a/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/files/pfr_image.py b/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/files/pfr_image.py index e1a23c172..5cda38b79 100755 --- a/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/files/pfr_image.py +++ b/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/files/pfr_image.py @@ -14,11 +14,9 @@ # TODO: figure out if active and recovery actually have different sigs # TODO: build hashmap from payload manifest # TODO: figure out exact struct layout for PFR metadata - import os, hashlib, struct, json, sys, subprocess, mmap, io, array, binascii, copy, shutil, re from array import array from binascii import unhexlify -from six import b, print_, binary_type from hashlib import sha1, sha256, sha512 from shutil import copyfile # Flash Map @@ -38,18 +36,20 @@ from shutil import copyfile # TODO: The below defines should go to manifest files. # Keeping it here hard coded for now. # The pages to be skipped for HASH and PBC -# Pages: 0x80 to 0xaff - starting PFM region until fit-image +# Pages: 0x80 to 0x9f - starting PFM region until end of pfm # Pages: 0x2a00 to 0x7FFF - starting RC-image until end of flash -EXCLUDE_PAGES =[[0x80, 0xaff],[0x2a00,0x7fff]] +EXCLUDE_PAGES =[[0x80, 0x9f],[0x2a00,0x7fff]] # SPI PFM globals PFM_OFFSET = 0x80000 PFM_SPI = 0x1 +PFM_I2C = 0x2 SHA256 = 0x1 SHA256_SIZE = 32 PFM_DEF_SIZE = 16 PFM_SPI_SIZE_DEF = 16 # 16 bytes of SPI PFM PFM_SPI_SIZE_HASH = 32 # 32 bytes of SPI region HASH +PFM_I2C_SIZE = 40 # 40 bytes of i2c rules region in PFM PAGE_SIZE = 0x1000 # 4KB size of page @@ -62,23 +62,32 @@ def load_manifest(fname): class pfm_spi(object): def __init__(self, prot_mask, start_addr, end_addr, hash, hash_pres): - self.pfm = PFM_SPI - self.prot_mask = prot_mask - self.hash_pres = hash_pres + self.spi_pfm = PFM_SPI + self.spi_prot_mask = prot_mask + self.spi_hash_pres = hash_pres if hash_pres == 1: self.spi_hash = hash - self.pfm_rsvd = 0xffffffff #b'\xff'*4 - self.start_addr = start_addr - self.end_addr = end_addr + self.spi_pfm_rsvd = 0xffffffff # b'\xff'*4 + self.spi_start_addr = start_addr + self.spi_end_addr = end_addr + +class pfm_i2c(object): + def __init__(self, bus_id, rule_id, address, cmd_map): + self.i2c_pfm = PFM_I2C + self.i2c_pfm_rsvd = 0xffffffff # b'\xff'*4 + self.i2c_bus_id = bus_id + self.i2c_rule_id = rule_id + self.i2c_address = address + self.i2c_cmd_whitelist = cmd_map class pfr_bmc_image(object): -# json_file, update_file - def __init__(self, manifest, update_file, build_ver, build_num, build_hash): +# json_file, firmware_file + def __init__(self, manifest, firmware_file, build_ver, build_num, build_hash): self.manifest = load_manifest(manifest) - self.update_file = update_file + self.firmware_file = firmware_file self.build_version = build_ver self.build_number = build_num self.build_hash = build_hash @@ -111,6 +120,26 @@ class pfr_bmc_image(object): # fill in the calculated data self.hash_and_map() + self.i2c_rules = [] + for i in self.manifest['i2c-rules']: + # the json should have in the order- bus-id, rule-id, address, size and cmd-whitelist + self.i2c_rules.append((i['bus-id'], i['rule-id'], i['address'], i['cmd-whitelist'])) + print(self.i2c_rules) + + # I2C rules PFM array + self.pfm_i2c_rules = [] + + # Generate the i2c rules + self.build_i2c_rules() + + # Generate PFM region binary - pfm.bin + self.build_pfm() + print("PFM build done") + + # Generate PBC region - pbc.bin + self.pbc_hdr() + print("PBC build done") + def hash_compress_regions(self, p, upd): # JSON format as below @@ -134,41 +163,44 @@ class pfr_bmc_image(object): # 1 page is 4KB page = start_addr >> 12 - if hash_flag == 1: - with open(self.update_file, "rb") as f: - f.seek(start_addr) - skip = False - # HASH for the region + with open(self.firmware_file, "rb") as f: + f.seek(start_addr) + skip = False + + if hash_flag == 1: hash_dgst = hashlib.sha256() - for chunk in iter(lambda: f.read(self.page_size), b''): - chunk_len = len(chunk) - if chunk_len != self.page_size: - chunk = b''.join([chunk, b'\xff' * (self.page_size - chunk_len)]) - - for p in EXCLUDE_PAGES: - if (page >= p[0]) and (page <= p[1]): - print("Exclude page={}".format(page)) - skip = True - break - - if not skip: - # add to the hash + + for chunk in iter(lambda: f.read(self.page_size), b''): + chunk_len = len(chunk) + if chunk_len != self.page_size: + chunk = b''.join([chunk, b'\xff' * (self.page_size - chunk_len)]) + + for p in EXCLUDE_PAGES: + if (page >= p[0]) and (page <= p[1]): + #print("Exclude page={}".format(page)) + skip = True + break + + if not skip: + # add to the hash + if hash_flag == 1: + # HASH for the region self.act_dgst.update(chunk) hash_dgst.update(chunk) - self.pbc_erase_bitmap[page >> 3] |= 1 << (7- (page % 8)) # Big endian bit map - if compress == 1: - # add to the pbc map - if chunk != self.empty: - print("compressed page ={}".format(page)) - upd.write(chunk) - self.pbc_comp_bitmap[page >> 3] |= 1 << (7- (page % 8)) # Big Endian bit map - self.pbc_comp_payload += chunk_len # compressed payload bytes + if compress == 1: + self.pbc_erase_bitmap[page >> 3] |= 1 << (7- (page % 8)) # Big endian bit map + # add to the pbc map + if chunk != self.empty: + #print("compressed page ={}".format(page)) + upd.write(chunk) + self.pbc_comp_bitmap[page >> 3] |= 1 << (7- (page % 8)) # Big Endian bit map + self.pbc_comp_payload += chunk_len # compressed payload bytes - page += 1 + page += 1 - if (page * self.page_size) >= (size + start_addr): - break + if (page * self.page_size) >= (size + start_addr): + break if pfm_flag == 1: self.pfm_bytes += PFM_SPI_SIZE_DEF @@ -185,24 +217,43 @@ class pfr_bmc_image(object): # append to SPI regions in PFM self.pfm_spi_regions.append(pfm_spi(pfm_prot_mask, start_addr, (start_addr+size), hash, hash_pres)) + def add_i2c_rules(self, i): + bus_id = i[0] # I2C Bus number + rule_id = i[1] # I2C rule number + addr = i[2] # I2C device address + cmds = i[3] # I2C white listed commands for which i2c write to be allowed + whitelist_map = bytearray(32) + + self.pfm_bytes += PFM_I2C_SIZE # add upto PFM size + + for c in cmds: + if c == "all": + for i in range(32): + whitelist_map[i] = 0xff + break + else: + idx = int(c,16) / 8 # index in the 32 bytes of white list i2c cmds + bit = int(c,16) % 8 # bit position to set + whitelist_map[idx] |= (1 << bit) + + # append to I2C rules in PFM + self.pfm_i2c_rules.append(pfm_i2c(bus_id, rule_id, addr, whitelist_map)) + + def build_i2c_rules(self): + for i in self.i2c_rules: + print(i[0], i[1], i[2], i[3]) + self.add_i2c_rules(i) + def hash_and_map(self): # have copy of the update file for appending with PFR meta and compression - copyfile(self.update_file, self.pfr_rom_file) + copyfile(self.firmware_file, self.pfr_rom_file) with open("bmc_compressed.bin", "wb+") as upd: for p in self.image_parts: #filename, index, offset, size, protection. print(p[0], p[1], p[2], p[3], p[4]) self.hash_compress_regions(p, upd) - # Generate PFM region binary - pfm.bin - self.build_pfm() - print("PFM build done") - - # Generate PBC region - pbc.bin - self.pbc_hdr() - print("PBC build done") - def pbc_hdr(self): ''' typedef struct { @@ -244,30 +295,34 @@ class pfr_bmc_image(object): ''' typedef struct { uint32_t tag; /* PFM_HDR_TAG above, no terminating null */ - uint8_t sec_revision; /* SVN- security revision of associated image data */ + uint8_t SVN; /* SVN- security revision of associated image data */ + uint8_t bkc; /* bkc */ uint8_t pfm_ver_major; /* PFM revision */ uint8_t pfm_ver_minor; + uint8_t reserved0[4]; uint8_t build_num; uint8_t build_hash[3]; - uint8_t reserved0; /* reserved */ + uint8_t reserved1[12]; /* reserved */ uint32_t pfm_length; /* PFM size in bytes */ pfm_spi pfm_spi[2]; /* PFM SPI regions - u-boot & fit-image */ pfm_smbus pfm_smbus[4]; /* defined smbus rules for PSUs and HSBP */ } __attribute__((packed)) pfm_hdr; ''' names = [ - 'tag', 'sec_rev', 'pfm_ver_major', 'pfm_ver_minor', 'build_num', 'build_hash1', 'build_hash2', 'build_hash3', 'resvd0', 'pfm_len', + 'tag', 'sec_rev', 'bkc', 'pfm_ver_major', 'pfm_ver_minor', 'resvd0', 'build_num', 'build_hash1', 'build_hash2', 'build_hash3', 'resvd1', 'pfm_len', ] parts = { 'tag': struct.pack("<I", 0x02b3ce1d), 'sec_rev': struct.pack('<B', self.sec_rev), + 'bkc': struct.pack('<B', 0x01), 'pfm_ver_major': struct.pack('<B', ((int(self.build_version) >> 8) & 0xff)), 'pfm_ver_minor': struct.pack('<B', (int(self.build_version) & 0x00ff)), + 'resvd0': b'\xff'* 4, 'build_num': struct.pack('<B', int(self.build_number,16)), - 'build_hash1': struct.pack('<B', int(self.build_hash) & 0xff), - 'build_hash2': struct.pack('<B', (int(self.build_hash) >> 8) & 0xff), - 'build_hash3': struct.pack('<B', (int(self.build_hash) >> 16) & 0xff), - 'resvd0': b'\xff'* 1, + 'build_hash1': struct.pack('<B', (int(self.build_hash) & 0xff)), + 'build_hash2': struct.pack('<B', ((int(self.build_hash) >> 8) & 0xff)), + 'build_hash3': struct.pack('<B', ((int(self.build_hash) >> 16) & 0xff)), + 'resvd1': b'\xff'* 12, 'pfm_len': '' } @@ -280,32 +335,40 @@ class pfr_bmc_image(object): with open("pfm.bin", "wb+") as f: f.write(b''.join([parts[n] for n in names])) for i in self.pfm_spi_regions: - f.write(struct.pack('b', int(i.pfm))) - f.write(struct.pack('b', int(i.prot_mask))) - f.write(struct.pack('h', int(i.hash_pres))) - f.write(struct.pack('<I', int(i.pfm_rsvd))) - f.write(struct.pack('<I', int(i.start_addr))) - f.write(struct.pack('<I', int(i.end_addr))) - - if i.hash_pres == 1: + f.write(struct.pack('<B', int(i.spi_pfm))) + f.write(struct.pack('<B', int(i.spi_prot_mask))) + f.write(struct.pack('<h', int(i.spi_hash_pres))) + f.write(struct.pack('<I', int(i.spi_pfm_rsvd))) + f.write(struct.pack('<I', int(i.spi_start_addr))) + f.write(struct.pack('<I', int(i.spi_end_addr))) + + if i.spi_hash_pres == 1: f.write(i.spi_hash.decode('hex')) + for r in self.pfm_i2c_rules: + f.write(struct.pack('<B', int(r.i2c_pfm))) + f.write(struct.pack('<I', int(r.i2c_pfm_rsvd))) + f.write(struct.pack('<B', int(r.i2c_bus_id))) + f.write(struct.pack('<B', int(r.i2c_rule_id))) + f.write(struct.pack('<B', int(r.i2c_address, 16))) + f.write(r.i2c_cmd_whitelist) + # write the padding bytes at the end f.write(b'\xff' * padding_bytes) def main(): if len(sys.argv) != 6: #< pfr_image.py manifest.json> <update.bin> <build_version> <build_number> <build_hash> - print('usage: {} <manifest.json> <update.bin> <build_version> <build_number> <build_hash>'.format(sys.argv[0])) + print('usage: {} <manifest.json> <firmware.bin> <build_version> <build_number> <build_hash>'.format(sys.argv[0])) return json_file = sys.argv[1] - update_file = sys.argv[2] + firmware_file = sys.argv[2] build_ver = sys.argv[3] build_num = sys.argv[4] build_hash = sys.argv[5] # function to generate BMC PFM, PBC header and BMC compressed image - pfr_bmc_image(json_file, update_file, build_ver, build_num, build_hash) + pfr_bmc_image(json_file, firmware_file, build_ver, build_num, build_hash) if __name__ == '__main__': main() diff --git a/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/files/pfr_manifest.json b/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/files/pfr_manifest.json new file mode 100644 index 000000000..adea41eab --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/files/pfr_manifest.json @@ -0,0 +1,120 @@ +{ + "image-parts": [{ + "name": "u-boot", + "index": 0, + "offset": "0", + "size": "0x80000", + "prot_mask": 29, + "pfm": 1, + "hash": 1, + "compress": 1 + }, + { + "name": "pfm", + "index": 1, + "offset": "0x80000", + "size": "0x20000", + "prot_mask": 0, + "pfm": 1, + "hash": 0, + "compress": 0 + }, + { + "name": "u-boot-env", + "index": 2, + "offset": "0xa0000", + "size": "0x20000", + "prot_mask": 31, + "pfm": 1, + "hash": 0, + "compress": 1 + }, + { + "name": "sofs", + "index": 3, + "offset": "0xc0000", + "size": "0x200000", + "prot_mask": 31, + "pfm": 1, + "hash": 0, + "compress": 1 + }, + { + "name": "rwfs", + "index": 4, + "offset": "0x2c0000", + "size": "0x840000", + "prot_mask": 31, + "pfm": 1, + "hash": 0, + "compress": 1 + }, + { + "name": "fit-image-a", + "index": 5, + "offset": "0xb00000", + "size": "0x1f00000", + "prot_mask": 29, + "pfm": 1, + "hash": 1, + "compress": 1 + }, + { + "name": "rc-image", + "index": 6, + "offset": "0x2a00000", + "size": "0x2000000", + "prot_mask": 0, + "pfm": 1, + "hash": 0, + "compress": 0 + }, + { + "name": "image-stg", + "index": 7, + "offset": "0x4a00000", + "size": "0x3600000", + "prot_mask": 3, + "pfm": 1, + "hash": 0, + "compress": 0 + } + ], + "i2c-rules": [{ + "bus-id": 5, + "rule-id": 1, + "address": "0xD0", + "cmd-whitelist": ["0x00", "0x01", "0x02", "0x03", "0x04", "0x09", "0x0A", "0x0B", "0x0C", "0x0D", "0x0E", "0x0F", + "0x10", "0x13", "0x17", "0x1B", "0x1C", "0x1D", "0x02", "0x021", "0x22", "0x23", "0x25", "0x30", + "0x31", "0x32", "0x33", "0x035", "0x36", "0x37", "0x38", "0x39", "0x3A", "0x3B", "0x3C", "0x3D"] + }, + { + "bus-id": 5, + "rule-id": 2, + "address": "0xD6", + "cmd-whitelist": ["0x00", "0x01", "0x02", "0x03", "0x04", "0x09", "0x0A", "0x0B", "0x0C", "0x0D", "0x0E", "0x0F", + "0x10", "0x13", "0x17", "0x1B", "0x1C", "0x1D", "0x02", "0x021", "0x22", "0x23", "0x25", "0x30", + "0x31", "0x32", "0x33", "0x035", "0x36", "0x37", "0x38", "0x39", "0x3A", "0x3B", "0x3C", "0x3D"] + }, + { + "bus-id": 8, + "rule-id": 3, + "address": "0xB0", + "cmd-whitelist": ["0x03", "0x05", "0x06", "0x19", "0x1A", "0x30", "0x3A", "0x3B", "0x3C", "0x3D", "0x3E", "0x3F", + "0x79", "0x7A", "0x7B", "0x7C", "0x7D", "0x7E", "0x7F", "0x81", "0x82", "0x86", "0x87", "0x88", + "0x89", "0x8C", "0x8D", "0x8E", "0x8F", "0x90", "0x91", "0x92", "0x93", "0x94", "0x95", "0x96", + "0x97", "0x98", "0x9A", "0xA6", "0xA7", "0xD0", "0xD3", "0xD4", "0xD5", "0xD6", "0xD7", "0xD8", + "0xD9", "0xDC", "0xDD", "0xDE", "0xDE"] + }, + { + "bus-id": 8, + "rule-id": 4, + "address": "0xB2", + "cmd-whitelist": ["0x03", "0x05", "0x06", "0x19", "0x1A", "0x30", "0x3A", "0x3B", "0x3C", "0x3D", "0x3E", "0x3F", + "0x79", "0x7A", "0x7B", "0x7C", "0x7D", "0x7E", "0x7F", "0x81", "0x82", "0x86", "0x87", "0x88", + "0x89", "0x8C", "0x8D", "0x8E", "0x8F", "0x90", "0x91", "0x92", "0x93", "0x94", "0x95", "0x96", + "0x97", "0x98", "0x9A", "0xA6", "0xA7", "0xD0", "0xD3", "0xD4", "0xD5", "0xD6", "0xD7", "0xD8", + "0xD9", "0xDC", "0xDD", "0xDE", "0xDE"] + } + ] +} diff --git a/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/intel-blocksign-native.bb b/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/intel-blocksign-native.bb new file mode 100644 index 000000000..12394dd91 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/intel-blocksign-native.bb @@ -0,0 +1,20 @@ +SUMMARY = "Intel Blocksign tool for PFR image"
+DESCRIPTION = "Image signing tool for BMC PFR image"
+
+inherit native cmake
+
+LICENSE = "Apache-2.0"
+LIC_FILES_CHKSUM = "file://${INTELBASE}/COPYING.apache-2.0;md5=34400b68072d710fecd0a2940a0d1658"
+
+DEPENDS = "openssl-native libxml2-native "
+
+SRC_URI = "git://git@github.com/Intel-BMC/blocksign;protocol=ssh"
+
+SRCREV = "60d76db038a0d85851098b13451246abb0d876ed"
+
+S = "${WORKDIR}/git/"
+
+do_install_append() {
+ install -d ${STAGING_DIR}/intel-pfr-files
+ install -m 775 ${B}/blocksign ${STAGING_DIR}/intel-pfr-files
+}
diff --git a/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/intel-pfr-manager_git.bb b/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/intel-pfr-manager_git.bb index ebebe43bb..96bfec0a8 100644 --- a/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/intel-pfr-manager_git.bb +++ b/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/intel-pfr-manager_git.bb @@ -9,7 +9,7 @@ LICENSE = "Apache-2.0" LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e" SRC_URI = "git://git@github.com/Intel-BMC/provingground.git;protocol=ssh" -SRCREV = "4611d8dcba0c0dc92156bbafdb50607aaff122ab" +SRCREV = "226ca2842e0a14ad56b4ebeedfd82ac2ea7e145e" inherit cmake systemd SYSTEMD_SERVICE_${PN} = "xyz.openbmc_project.Intel.PFR.Manager.service" diff --git a/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/obmc-intel-pfr-image-native.bb b/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/obmc-intel-pfr-image-native.bb index ee2cc3934..307fe1829 100644 --- a/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/obmc-intel-pfr-image-native.bb +++ b/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/obmc-intel-pfr-image-native.bb @@ -9,11 +9,11 @@ inherit native PFR_KEY_NAME ?= "pfr-dev-key"
PFR_SIGN_UTIL ?= "blocksign"
+DEPENDS += " intel-blocksign-native"
SRC_URI = " \
- file://pfr_image-manifest.json \
+ file://pfr_manifest.json \
file://pfr_image.py \
- file://blocksign \
file://pfm_config.xml \
file://bmc_config.xml \
file://csk_prv.pem \
@@ -26,13 +26,12 @@ do_install() { bbplain "Copying the intel pfr image generation scripts and image signing keys"
install -d ${STAGING_DIR}/intel-pfr-files
- install -m 400 ${WORKDIR}/pfr_image-manifest.json ${STAGING_DIR}/intel-pfr-files
- install -m 775 ${WORKDIR}/blocksign ${STAGING_DIR}/intel-pfr-files
+ install -m 400 ${WORKDIR}/pfr_manifest.json ${STAGING_DIR}/intel-pfr-files
install -m 400 ${WORKDIR}/pfm_config.xml ${STAGING_DIR}/intel-pfr-files
install -m 400 ${WORKDIR}/bmc_config.xml ${STAGING_DIR}/intel-pfr-files
install -m 775 ${WORKDIR}/pfr_image.py ${STAGING_DIR}/intel-pfr-files
- install -m 400 ${WORKDIR}/csk_prv.pem ${STAGING_DIR}/intel-pfr-files/
- install -m 400 ${WORKDIR}/csk_pub.pem ${STAGING_DIR}/intel-pfr-files/
- install -m 400 ${WORKDIR}/rk_pub.pem ${STAGING_DIR}/intel-pfr-files/
- install -m 400 ${WORKDIR}/rk_prv.pem ${STAGING_DIR}/intel-pfr-files/
+ install -m 400 ${WORKDIR}/csk_prv.pem ${STAGING_DIR}/intel-pfr-files
+ install -m 400 ${WORKDIR}/csk_pub.pem ${STAGING_DIR}/intel-pfr-files
+ install -m 400 ${WORKDIR}/rk_pub.pem ${STAGING_DIR}/intel-pfr-files
+ install -m 400 ${WORKDIR}/rk_prv.pem ${STAGING_DIR}/intel-pfr-files
}
diff --git a/meta-openbmc-mods/meta-common/recipes-intel/smbios/smbios-mdrv1.bb b/meta-openbmc-mods/meta-common/recipes-intel/smbios/smbios-mdrv1.bb index 84d5a9831..0f6893ed6 100644 --- a/meta-openbmc-mods/meta-common/recipes-intel/smbios/smbios-mdrv1.bb +++ b/meta-openbmc-mods/meta-common/recipes-intel/smbios/smbios-mdrv1.bb @@ -2,7 +2,7 @@ SUMMARY = "SMBIOS MDR version 1 service for Intel based platform" DESCRIPTION = "SMBIOS MDR version 1 service for Intel based platfrom" SRC_URI = "git://git@github.com/Intel-BMC/provingground.git;protocol=ssh" -SRCREV = "4611d8dcba0c0dc92156bbafdb50607aaff122ab" +SRCREV = "226ca2842e0a14ad56b4ebeedfd82ac2ea7e145e" S = "${WORKDIR}/git/services/smbios/" diff --git a/meta-openbmc-mods/meta-common/recipes-intel/smbios/smbios-mdrv2.bb b/meta-openbmc-mods/meta-common/recipes-intel/smbios/smbios-mdrv2.bb index bc0538b04..71ac31348 100644 --- a/meta-openbmc-mods/meta-common/recipes-intel/smbios/smbios-mdrv2.bb +++ b/meta-openbmc-mods/meta-common/recipes-intel/smbios/smbios-mdrv2.bb @@ -2,7 +2,7 @@ SUMMARY = "SMBIOS MDR version 2 service for Intel based platform" DESCRIPTION = "SMBIOS MDR version 2 service for Intel based platfrom" SRC_URI = "git://git@github.com/Intel-BMC/provingground.git;protocol=ssh" -SRCREV = "4611d8dcba0c0dc92156bbafdb50607aaff122ab" +SRCREV = "226ca2842e0a14ad56b4ebeedfd82ac2ea7e145e" S = "${WORKDIR}/git/services/smbios-mdrv2/" diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0008-Add-ASPEED-SGPIO-driver.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0008-Add-ASPEED-SGPIO-driver.patch index 08be45ff7..146a725dd 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0008-Add-ASPEED-SGPIO-driver.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0008-Add-ASPEED-SGPIO-driver.patch @@ -1,18 +1,17 @@ -From 323066b26f02f043e694463a8e0cd4ada465984b Mon Sep 17 00:00:00 2001 +From e6923abbc90b5b00bc9ea401fbb2a28971d19cbe Mon Sep 17 00:00:00 2001 From: "Feist, James" <james.feist@intel.com> -Date: Mon, 5 Jun 2017 11:13:52 -0700 -Subject: [PATCH] Add ASPEED SGPIO driver. +Date: Tue, 4 Jun 2019 14:00:39 -0700 +Subject: [PATCH] gpio: aspeed: add ASPEED SGPIO driver -Port aspeed sgpio driver to OBMC Kernel and -enable it on Purley config. Based off AST sdk 4.0. +Add SGPIO driver support for Aspeed SoCs. Signed-off-by: James Feist <james.feist@linux.intel.com> Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com> --- drivers/gpio/Kconfig | 8 + drivers/gpio/Makefile | 1 + - drivers/gpio/sgpio-aspeed.c | 416 ++++++++++++++++++++++++++++++++++++++++++++ - 3 files changed, 425 insertions(+) + drivers/gpio/sgpio-aspeed.c | 708 ++++++++++++++++++++++++++++++++++++++++++++ + 3 files changed, 717 insertions(+) create mode 100644 drivers/gpio/sgpio-aspeed.c diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig @@ -48,425 +47,717 @@ index 6700eee860b7..77c6ec0ee98f 100644 obj-$(CONFIG_GPIO_BD9571MWV) += gpio-bd9571mwv.o diff --git a/drivers/gpio/sgpio-aspeed.c b/drivers/gpio/sgpio-aspeed.c new file mode 100644 -index 000000000000..9c4add74602a +index 000000000000..6fb402a3f74d --- /dev/null +++ b/drivers/gpio/sgpio-aspeed.c -@@ -0,0 +1,416 @@ -+// SPDX-License-Identifier: GPL-2.0 -+// Copyright (C) 2012-2017 ASPEED Technology Inc. -+// Copyright (c) 2018 Intel Corporation +@@ -0,0 +1,708 @@ ++// SPDX-License-Identifier: GPL-2.0+ ++// Copyright (c) 2019 Intel Corporation + -+#include <asm/mach/irq.h> +#include <linux/bitfield.h> ++#include <linux/clk.h> +#include <linux/gpio/driver.h> -+#include <linux/init.h> -+#include <linux/io.h> +#include <linux/module.h> -+#include <linux/of_gpio.h> ++#include <linux/of.h> +#include <linux/platform_device.h> ++#include <linux/spinlock.h> ++ ++#define ASPEED_SGPIO_CTRL 0x54 ++#define ASPEED_SGPIO_CLK_DIV_MASK GENMASK(31, 16) ++#define ASPEED_SGPIO_CLK_DIV_MIN 1 ++#define ASPEED_SGPIO_CLK_DIV_MAX 65535 ++#define ASPEED_SGPIO_PINBYTES_MASK GENMASK(9, 6) ++#define ASPEED_SGPIO_PINBYTES_MIN 1 ++#define ASPEED_SGPIO_PINBYTES_MAX 10 ++#define ASPEED_SGPIO_ENABLE BIT(0) ++ ++#define ASPEED_SGPIO_BUS_FREQ_DEFAULT 1000000 ++ ++struct aspeed_bank_props { ++ unsigned int bank; ++ u32 input; ++ u32 output; ++}; + -+#ifdef ARCH_NR_GPIOS -+#undef ARCH_NR_GPIOS -+#endif ++struct aspeed_sgpio_config { ++ unsigned int nr_pgpios; ++ unsigned int nr_gpios; ++ const struct aspeed_bank_props *props; ++}; + -+// TODO: move this to aspeed_sgpio_of_table -+#if defined(CONFIG_MACH_ASPEED_G5) -+#define GPIO_PORT_NUM 29 -+#elif defined(CONFIG_MACH_ASPEED_G4) -+#define GPIO_PORT_NUM 28 -+#endif ++struct aspeed_sgpio { ++ struct gpio_chip chip; ++ spinlock_t lock; ++ void __iomem *base; ++ int irq; ++ const struct aspeed_sgpio_config *config; + -+// TODO: fix defines -+#define GPIOS_PER_PORT 8 -+#define ARCH_NR_GPIOS (GPIOS_PER_PORT * GPIO_PORT_NUM) -+#define ASPEED_SGPIO_CTRL 0x54 -+#define SGPIO_CHAIN_CHIP_BASE ARCH_NR_GPIOS -+#define SGPIO_GROUP_NUMS 10 ++ u32 *dcache; ++}; + -+#define ASPEED_VIC_NUMS 64 -+#define ASPEED_FIQ_NUMS 64 -+#define ARCH_NR_I2C 14 ++struct aspeed_sgpio_bank { ++ uint16_t val_reg; ++ uint16_t rdata_reg; ++ uint16_t tolerance_reg; ++ uint16_t irq_regs; ++ bool support_irq; ++ const char names[4][3]; ++}; + -+#define IRQ_I2C_CHAIN_START (ASPEED_VIC_NUMS + ASPEED_FIQ_NUMS) -+#define IRQ_GPIO_CHAIN_START (IRQ_I2C_CHAIN_START + ARCH_NR_I2C) -+#define IRQ_SGPIO_CHAIN_START (IRQ_GPIO_CHAIN_START + ARCH_NR_GPIOS) ++/* ++ * Note: The "val" register returns the input value sampled on the line. ++ * Or, it can be used for writing a value on the line. ++ * ++ * The "rdata" register returns the content of the write latch and thus ++ * can be used to read back what was last written reliably. ++ */ + -+#define ASPEED_SGPIO_PINS_MASK GENMASK(9, 6) -+#define ASPEED_SGPIO_CLK_DIV_MASK GENMASK(31, 16) -+#define ASPEED_SGPIO_ENABLE BIT(0) ++static const struct aspeed_sgpio_bank aspeed_sgpio_banks[] = { ++ { ++ .val_reg = 0x0000, ++ .rdata_reg = 0x0070, ++ .tolerance_reg = 0x0018, ++ .irq_regs = 0x0004, ++ .support_irq = false, ++ .names = { "OA", "OB", "OC", "OD" }, ++ }, ++ { ++ .val_reg = 0x001C, ++ .rdata_reg = 0x0074, ++ .tolerance_reg = 0x0034, ++ .irq_regs = 0x0020, ++ .support_irq = false, ++ .names = { "OE", "OF", "OG", "OH" }, ++ }, ++ { ++ .val_reg = 0x0038, ++ .rdata_reg = 0x0078, ++ .tolerance_reg = 0x0050, ++ .irq_regs = 0x003C, ++ .support_irq = false, ++ .names = { "OI", "OJ" }, ++ }, ++ { ++ .val_reg = 0x0000, ++ .rdata_reg = 0x0070, ++ .tolerance_reg = 0x0018, ++ .irq_regs = 0x0004, ++ .support_irq = true, ++ .names = { "IA", "IB", "IC", "ID" }, ++ }, ++ { ++ .val_reg = 0x001C, ++ .rdata_reg = 0x0074, ++ .tolerance_reg = 0x0034, ++ .irq_regs = 0x0020, ++ .support_irq = true, ++ .names = { "IE", "IF", "IG", "IH" }, ++ }, ++ { ++ .val_reg = 0x0038, ++ .rdata_reg = 0x0078, ++ .tolerance_reg = 0x0050, ++ .irq_regs = 0x003C, ++ .support_irq = true, ++ .names = { "II", "IJ" }, ++ }, ++}; + -+struct aspeed_sgpio { -+ struct device *dev; -+ int mirq; /* master irq */ -+ void __iomem *base; -+// TODO: make below members as a struct member -+ uint index; -+ uint data_offset; -+ uint data_read_offset; -+ uint int_en_offset; -+ uint int_type_offset; -+ uint int_sts_offset; -+ uint rst_tol_offset; -+ struct gpio_chip chip; ++enum aspeed_sgpio_reg { ++ reg_val, ++ reg_rdata, ++ reg_irq_enable, ++ reg_irq_type0, ++ reg_irq_type1, ++ reg_irq_type2, ++ reg_irq_status, ++ reg_tolerance, +}; + -+uint aspeed_sgpio_to_irq(uint gpio) ++#define GPIO_IRQ_ENABLE 0x00 ++#define GPIO_IRQ_TYPE0 0x04 ++#define GPIO_IRQ_TYPE1 0x08 ++#define GPIO_IRQ_TYPE2 0x0c ++#define GPIO_IRQ_STATUS 0x10 ++ ++/* This will be resolved at compile time */ ++static inline void __iomem *bank_reg(struct aspeed_sgpio *gpio, ++ const struct aspeed_sgpio_bank *bank, ++ const enum aspeed_sgpio_reg reg) +{ -+ return (gpio + IRQ_SGPIO_CHAIN_START); ++ switch (reg) { ++ case reg_val: ++ return gpio->base + bank->val_reg; ++ case reg_rdata: ++ return gpio->base + bank->rdata_reg; ++ case reg_irq_enable: ++ return gpio->base + bank->irq_regs + GPIO_IRQ_ENABLE; ++ case reg_irq_type0: ++ return gpio->base + bank->irq_regs + GPIO_IRQ_TYPE0; ++ case reg_irq_type1: ++ return gpio->base + bank->irq_regs + GPIO_IRQ_TYPE1; ++ case reg_irq_type2: ++ return gpio->base + bank->irq_regs + GPIO_IRQ_TYPE2; ++ case reg_irq_status: ++ return gpio->base + bank->irq_regs + GPIO_IRQ_STATUS; ++ case reg_tolerance: ++ return gpio->base + bank->tolerance_reg; ++ default: ++ WARN_ON(1); ++ } ++ ++ return NULL; +} -+EXPORT_SYMBOL(aspeed_sgpio_to_irq); + -+uint aspeed_irq_to_sgpio(uint irq) ++#define GPIO_BANK(x) ((x) >> 5) ++#define GPIO_OFFSET(x) ((x) & 0x1f) ++#define GPIO_BIT(x) BIT(GPIO_OFFSET(x)) ++ ++static const struct aspeed_sgpio_bank *to_bank(unsigned int offset) +{ -+ return (irq - IRQ_SGPIO_CHAIN_START); ++ unsigned int bank = GPIO_BANK(offset); ++ ++ WARN_ON(bank >= ARRAY_SIZE(aspeed_sgpio_banks)); ++ return &aspeed_sgpio_banks[bank]; +} -+EXPORT_SYMBOL(aspeed_irq_to_sgpio); + -+static int aspeed_sgpio_get(struct gpio_chip *chip, unsigned offset) ++static inline bool is_bank_props_sentinel(const struct aspeed_bank_props *props) +{ -+ struct aspeed_sgpio *priv = gpiochip_get_data(chip); -+ uint bit_nr = priv->index * GPIOS_PER_PORT + offset; -+ unsigned long flags; -+ u32 v; ++ return !(props->input || props->output); ++} + -+ local_irq_save(flags); ++static inline const struct aspeed_bank_props *find_bank_props( ++ struct aspeed_sgpio *gpio, unsigned int offset) ++{ ++ const struct aspeed_bank_props *props = gpio->config->props; + -+ v = readl(priv->base + priv->data_offset); -+ v &= BIT(bit_nr); ++ while (!is_bank_props_sentinel(props)) { ++ if (props->bank == GPIO_BANK(offset)) ++ return props; ++ props++; ++ } + -+ if (v) -+ v = 1; -+ else -+ v = 0; ++ return NULL; ++} + -+ local_irq_restore(flags); ++static inline bool have_input(struct aspeed_sgpio *gpio, unsigned int offset) ++{ ++ const struct aspeed_bank_props *props = find_bank_props(gpio, offset); + -+ dev_dbg(priv->dev, "%s, %s[%d]: %d\n", __func__, chip->label, -+ offset, v); ++ return !props || (props->input & GPIO_BIT(offset)); ++} + -+ return v; ++static inline bool have_output(struct aspeed_sgpio *gpio, unsigned int offset) ++{ ++ const struct aspeed_bank_props *props = find_bank_props(gpio, offset); ++ ++ return !props || (props->output & GPIO_BIT(offset)); +} + -+static void aspeed_sgpio_set(struct gpio_chip *chip, unsigned offset, int val) ++static int aspeed_sgpio_get(struct gpio_chip *gc, unsigned int offset) +{ -+ struct aspeed_sgpio *priv = gpiochip_get_data(chip); -+ uint bit_nr = priv->index * GPIOS_PER_PORT + offset; ++ struct aspeed_sgpio *gpio = gpiochip_get_data(gc); ++ const struct aspeed_sgpio_bank *bank = to_bank(offset); ++ enum aspeed_sgpio_reg reg; ++ ++ if (have_output(gpio, offset)) ++ reg = reg_rdata; ++ else ++ reg = reg_val; ++ ++ return !!(ioread32(bank_reg(gpio, bank, reg)) & GPIO_BIT(offset)); ++} ++ ++static void aspeed_sgpio_set(struct gpio_chip *gc, unsigned int offset, int val) ++{ ++ const struct aspeed_sgpio_bank *bank = to_bank(offset); ++ struct aspeed_sgpio *gpio = gpiochip_get_data(gc); + unsigned long flags; -+ u32 v; ++ u32 reg; + -+ local_irq_save(flags); ++ if (!have_output(gpio, offset)) ++ return; + -+ v = readl(priv->base + priv->data_read_offset); ++ spin_lock_irqsave(&gpio->lock, flags); ++ ++ reg = ioread32(bank_reg(gpio, bank, reg_rdata)); + + if (val) -+ v |= BIT(bit_nr); ++ reg |= GPIO_BIT(offset); + else -+ v &= ~BIT(bit_nr); -+ -+ writel(v, priv->base + priv->data_offset); ++ reg &= ~GPIO_BIT(offset); + -+ dev_dbg(priv->dev, "%s, %s[%d]: %d\n", __func__, chip->label, -+ offset, val); ++ iowrite32(reg, bank_reg(gpio, bank, reg_val)); + -+ local_irq_restore(flags); ++ spin_unlock_irqrestore(&gpio->lock, flags); +} + -+#define SGPIO_BANK(name, index_no, data, read_data, int_en, int_type, \ -+ int_sts, rst_tol, chip_base_idx) { \ -+ .index = index_no, \ -+ .data_offset = data, \ -+ .data_read_offset = read_data, \ -+ .int_en_offset = int_en, \ -+ .int_type_offset = int_type, \ -+ .int_sts_offset = int_sts, \ -+ .rst_tol_offset = rst_tol, \ -+ .chip = { \ -+ .label = name, \ -+ .get = aspeed_sgpio_get, \ -+ .set = aspeed_sgpio_set, \ -+ .base = SGPIO_CHAIN_CHIP_BASE + chip_base_idx * 8, \ -+ .ngpio = GPIOS_PER_PORT, \ -+ }, \ -+} ++static int aspeed_sgpio_dir_in(struct gpio_chip *gc, unsigned int offset) ++{ ++ struct aspeed_sgpio *gpio = gpiochip_get_data(gc); + -+// TODO: use a single priv after changing it as an array member of the priv -+static struct aspeed_sgpio aspeed_sgpio_gp[] = { -+ SGPIO_BANK("SGPIOA", 0, 0x000, 0x070, 0x004, 0x008, 0x014, 0x018, 0), -+ SGPIO_BANK("SGPIOB", 1, 0x000, 0x070, 0x004, 0x008, 0x014, 0x018, 1), -+ SGPIO_BANK("SGPIOC", 2, 0x000, 0x070, 0x004, 0x008, 0x014, 0x018, 2), -+ SGPIO_BANK("SGPIOD", 3, 0x000, 0x070, 0x004, 0x008, 0x014, 0x018, 3), -+ SGPIO_BANK("SGPIOE", 0, 0x01C, 0x074, 0x020, 0x024, 0x030, 0x034, 4), -+ SGPIO_BANK("SGPIOF", 1, 0x01C, 0x074, 0x020, 0x024, 0x030, 0x034, 5), -+ SGPIO_BANK("SGPIOG", 2, 0x01C, 0x074, 0x020, 0x024, 0x030, 0x034, 6), -+ SGPIO_BANK("SGPIOH", 3, 0x01C, 0x074, 0x020, 0x024, 0x030, 0x034, 7), -+ SGPIO_BANK("SGPIOI", 0, 0x038, 0x078, 0x03C, 0x040, 0x04C, 0x050, 8), -+ SGPIO_BANK("SGPIOJ", 1, 0x038, 0x078, 0x03C, 0x040, 0x04C, 0x050, 9), -+}; ++ if (!have_input(gpio, offset)) ++ return -ENOTSUPP; + -+/** -+ * We need to unmask the GPIO bank interrupt as soon as possible to avoid -+ * missing GPIO interrupts for other lines in the bank. Then we need to -+ * mask-read-clear-unmask the triggered GPIO lines in the bank to avoid missing -+ * nested interrupts for a GPIO line. If we wait to unmask individual GPIO lines -+ * in the bank after the line's interrupt handler has been run, we may miss some -+ * nested interrupts. -+ */ -+static void aspeed_sgpio_irq_handler(struct irq_desc *desc) ++ return 0; ++} ++ ++static int aspeed_sgpio_dir_out(struct gpio_chip *gc, unsigned int offset, ++ int val) +{ -+ struct irq_chip *chip = irq_desc_get_chip(desc); -+ struct aspeed_sgpio *priv = irq_desc_get_chip_data(desc); -+ u32 isr; -+ int i; ++ struct aspeed_sgpio *gpio = gpiochip_get_data(gc); + -+ chained_irq_enter(chip, desc); ++ if (!have_output(gpio, offset)) ++ return -ENOTSUPP; + -+ isr = readl(priv->base + priv->int_sts_offset); -+ isr = (isr >> (GPIOS_PER_PORT * priv->index)) & 0xff; ++ return 0; ++} + -+ dev_dbg(priv->dev, "[%s] isr %x \n", priv->chip.label, isr); ++static int aspeed_sgpio_get_direction(struct gpio_chip *gc, unsigned int offset) ++{ ++ struct aspeed_sgpio *gpio = gpiochip_get_data(gc); + -+ if (isr != 0) { -+ for (i = 0; i < GPIOS_PER_PORT; i++) { -+ if (BIT(i) & isr) -+ generic_handle_irq(i * GPIOS_PER_PORT + -+ i + IRQ_SGPIO_CHAIN_START); -+ } -+ } ++ if (have_output(gpio, offset)) ++ return 0; ++ else if (have_input(gpio, offset)) ++ return 1; + -+ chained_irq_exit(chip, desc); ++ return -ENOTSUPP; +} + -+static void aspeed_sgpio_ack_irq(struct irq_data *d) ++static inline int ++irqd_to_aspeed_sgpio_data(struct irq_data *d, struct aspeed_sgpio **gpio, ++ const struct aspeed_sgpio_bank **bank, ++ u32 *bit, int *offset) +{ -+ struct aspeed_sgpio *priv = irq_get_chip_data(d->irq); -+ uint sgpio_irq = (d->irq - IRQ_SGPIO_CHAIN_START) % GPIOS_PER_PORT; -+ uint bit_nr = priv->index * GPIOS_PER_PORT + sgpio_irq; ++ struct aspeed_sgpio *internal; ++ ++ *offset = irqd_to_hwirq(d); ++ ++ internal = irq_data_get_irq_chip_data(d); + -+ dev_dbg(priv->dev, "irq %d: %s [%s] pin %d\n", d->irq, __func__, -+ priv->chip.label, sgpio_irq); ++ *gpio = internal; ++ *bank = to_bank(*offset); ++ *bit = GPIO_BIT(*offset); + -+ writel(BIT(bit_nr), priv->base + priv->int_sts_offset); ++ return 0; +} + -+static void aspeed_sgpio_mask_irq(struct irq_data *d) ++static void aspeed_sgpio_irq_ack(struct irq_data *d) +{ -+ struct aspeed_sgpio *priv = irq_get_chip_data(d->irq); -+ uint sgpio_irq = (d->irq - IRQ_SGPIO_CHAIN_START) % GPIOS_PER_PORT; -+ uint bit_nr = priv->index * GPIOS_PER_PORT + sgpio_irq; ++ const struct aspeed_sgpio_bank *bank; ++ struct aspeed_sgpio *gpio; ++ void __iomem *status_addr; ++ unsigned long flags; ++ int rc, offset; ++ u32 bit; ++ ++ rc = irqd_to_aspeed_sgpio_data(d, &gpio, &bank, &bit, &offset); ++ if (rc) ++ return; ++ ++ status_addr = bank_reg(gpio, bank, reg_irq_status); ++ ++ spin_lock_irqsave(&gpio->lock, flags); + -+ /* Disable IRQ */ -+ writel(readl(priv->base + priv->int_en_offset) & ~BIT(bit_nr), -+ priv->base + priv->int_en_offset); ++ iowrite32(bit, status_addr); + -+ dev_dbg(priv->dev, "irq %d: %s [%s] pin %d\n ", d->irq, __func__, -+ priv->chip.label, sgpio_irq); ++ spin_unlock_irqrestore(&gpio->lock, flags); +} + -+static void aspeed_sgpio_unmask_irq(struct irq_data *d) ++static void aspeed_sgpio_irq_set_mask(struct irq_data *d, bool set) +{ -+ struct aspeed_sgpio *priv = irq_data_get_irq_chip_data(d); -+ u32 sgpio_irq = (d->irq - IRQ_SGPIO_CHAIN_START) % GPIOS_PER_PORT; -+ uint bit_nr = priv->index * GPIOS_PER_PORT + sgpio_irq; ++ const struct aspeed_sgpio_bank *bank; ++ struct aspeed_sgpio *gpio; ++ unsigned long flags; ++ u32 reg, bit; ++ void __iomem *addr; ++ int rc, offset; ++ ++ rc = irqd_to_aspeed_sgpio_data(d, &gpio, &bank, &bit, &offset); ++ if (rc) ++ return; ++ ++ if (!bank->support_irq) ++ return; ++ ++ addr = bank_reg(gpio, bank, reg_irq_enable); ++ ++ spin_lock_irqsave(&gpio->lock, flags); + -+ /* Enable IRQ */ -+ writel(BIT(bit_nr), priv->base + priv->int_sts_offset); -+ writel(readl(priv->base + priv->int_en_offset) | BIT(bit_nr), -+ priv->base + priv->int_en_offset); ++ reg = ioread32(addr); ++ if (set) ++ reg |= bit; ++ else ++ reg &= ~bit; ++ ++ iowrite32(reg, addr); + -+ dev_dbg(priv->dev, "irq %d: %s [%s] pin %d\n", d->irq, __func__, -+ priv->chip.label, sgpio_irq); ++ spin_unlock_irqrestore(&gpio->lock, flags); +} + -+static int aspeed_sgpio_irq_type(struct irq_data *d, unsigned int type) ++static void aspeed_sgpio_irq_mask(struct irq_data *d) +{ -+ unsigned int irq = d->irq; -+ struct aspeed_sgpio *priv = irq_get_chip_data(irq); -+ u32 sgpio_irq = (irq - IRQ_SGPIO_CHAIN_START) % GPIOS_PER_PORT; -+ u32 type0, type1, type2; ++ aspeed_sgpio_irq_set_mask(d, false); ++} + -+ dev_dbg(priv->dev, "irq: %d, sgpio_irq: %d , irq_type: 0x%x\n", -+ irq, sgpio_irq, type); ++static void aspeed_sgpio_irq_unmask(struct irq_data *d) ++{ ++ aspeed_sgpio_irq_set_mask(d, true); ++} + -+ if (type & ~IRQ_TYPE_SENSE_MASK) ++static int aspeed_sgpio_set_type(struct irq_data *d, unsigned int type) ++{ ++ u32 type0 = 0; ++ u32 type1 = 0; ++ u32 type2 = 0; ++ u32 bit, reg; ++ const struct aspeed_sgpio_bank *bank; ++ irq_flow_handler_t handler; ++ struct aspeed_sgpio *gpio; ++ unsigned long flags; ++ void __iomem *addr; ++ int rc, offset; ++ ++ rc = irqd_to_aspeed_sgpio_data(d, &gpio, &bank, &bit, &offset); ++ if (rc) + return -EINVAL; + -+ type0 = readl(priv->base + priv->int_type_offset); -+ type1 = readl(priv->base + priv->int_type_offset + 0x04); -+ type2 = readl(priv->base + priv->int_type_offset + 0x08); ++ if (!bank->support_irq) ++ return -ENOTSUPP; + -+ switch (type) { -+ /* Edge rising type */ ++ switch (type & IRQ_TYPE_SENSE_MASK) { ++ case IRQ_TYPE_EDGE_BOTH: ++ type2 |= bit; ++ /* fall through */ + case IRQ_TYPE_EDGE_RISING: -+ type0 |= BIT(sgpio_irq); -+ type1 &= ~BIT(sgpio_irq); -+ type2 &= ~BIT(sgpio_irq); -+ break; -+ /* Edge falling type */ ++ type0 |= bit; ++ /* fall through */ + case IRQ_TYPE_EDGE_FALLING: -+ type2 |= BIT(sgpio_irq); -+ break; -+ case IRQ_TYPE_EDGE_BOTH: -+ type0 &= ~BIT(sgpio_irq); -+ type1 |= BIT(sgpio_irq); -+ type2 &= ~BIT(sgpio_irq); ++ handler = handle_edge_irq; + break; + case IRQ_TYPE_LEVEL_HIGH: -+ type0 |= BIT(sgpio_irq); -+ type1 |= BIT(sgpio_irq); -+ type2 &= ~BIT(sgpio_irq); -+ break; ++ type0 |= bit; ++ /* fall through */ + case IRQ_TYPE_LEVEL_LOW: -+ type0 &= ~BIT(sgpio_irq); -+ type1 |= BIT(sgpio_irq); -+ type2 &= ~BIT(sgpio_irq); ++ type1 |= bit; ++ handler = handle_level_irq; + break; + default: -+ dev_dbg(priv->dev, "not supported trigger type: %d", type); + return -EINVAL; -+ break; + } + -+ writel(type0, priv->base + priv->int_type_offset); -+ writel(type1, priv->base + priv->int_type_offset + 0x04); -+ writel(type2, priv->base + priv->int_type_offset + 0x08); ++ spin_lock_irqsave(&gpio->lock, flags); ++ ++ addr = bank_reg(gpio, bank, reg_irq_type0); ++ reg = ioread32(addr); ++ reg = (reg & ~bit) | type0; ++ iowrite32(reg, addr); ++ ++ addr = bank_reg(gpio, bank, reg_irq_type1); ++ reg = ioread32(addr); ++ reg = (reg & ~bit) | type1; ++ iowrite32(reg, addr); ++ ++ addr = bank_reg(gpio, bank, reg_irq_type2); ++ reg = ioread32(addr); ++ reg = (reg & ~bit) | type2; ++ iowrite32(reg, addr); ++ ++ spin_unlock_irqrestore(&gpio->lock, flags); ++ ++ irq_set_handler_locked(d, handler); + + return 0; +} + -+static struct irq_chip aspeed_sgpio_irq_chip = { -+ .name = "aspeed-sgpio", -+ .irq_ack = aspeed_sgpio_ack_irq, -+ .irq_mask = aspeed_sgpio_mask_irq, -+ .irq_unmask = aspeed_sgpio_unmask_irq, -+ .irq_set_type = aspeed_sgpio_irq_type, ++static void aspeed_sgpio_irq_handler(struct irq_desc *desc) ++{ ++ struct gpio_chip *gc = irq_desc_get_handler_data(desc); ++ struct aspeed_sgpio *data = gpiochip_get_data(gc); ++ struct irq_chip *ic = irq_desc_get_chip(desc); ++ unsigned int i, p, girq; ++ unsigned long reg; ++ ++ chained_irq_enter(ic, desc); ++ ++ for (i = 0; i < ARRAY_SIZE(aspeed_sgpio_banks); i++) { ++ const struct aspeed_sgpio_bank *bank = &aspeed_sgpio_banks[i]; ++ ++ if (!bank->support_irq) ++ continue; ++ ++ reg = ioread32(bank_reg(data, bank, reg_irq_status)); ++ ++ for_each_set_bit(p, ®, 32) { ++ girq = irq_find_mapping(gc->irq.domain, i * 32 + p); ++ generic_handle_irq(girq); ++ } ++ } ++ ++ chained_irq_exit(ic, desc); ++} ++ ++static struct irq_chip aspeed_sgpio_irqchip = { ++ .name = "aspeed-sgpio", ++ .irq_ack = aspeed_sgpio_irq_ack, ++ .irq_mask = aspeed_sgpio_irq_mask, ++ .irq_unmask = aspeed_sgpio_irq_unmask, ++ .irq_set_type = aspeed_sgpio_set_type, +}; + -+static int aspeed_sgpio_config(struct aspeed_sgpio *priv) ++static void set_irq_valid_mask(struct aspeed_sgpio *gpio) +{ -+ /** -+ * There is a limitation that SGPIO clock division has to be larger or -+ * equal to 1. And the value of clock division read back is left shift -+ * 1 bit from actual value. -+ * -+ * GPIO254[31:16] - Serial GPIO clock division -+ * Serial GPIO clock period = period of PCLK * 2 * (GPIO254[31:16] + 1) -+ * -+ * SGPIO master controller updates every data input when SGPMLD is low. -+ * For example, SGPIO clock is 1MHz and number of SGPIO is 80 then each -+ * SGPIO will be updated in every 80us. -+ */ -+ writel(FIELD_PREP(ASPEED_SGPIO_CLK_DIV_MASK, 10) | -+ FIELD_PREP(ASPEED_SGPIO_PINS_MASK, SGPIO_GROUP_NUMS) | -+ ASPEED_SGPIO_ENABLE, -+ priv->base + ASPEED_SGPIO_CTRL); -+ dev_dbg(priv->dev, "sgpio config reg: 0x%08X\n", -+ readl(priv->base + ASPEED_SGPIO_CTRL)); ++ const struct aspeed_bank_props *props = gpio->config->props; + -+ return 0; ++ while (!is_bank_props_sentinel(props)) { ++ unsigned int offset; ++ const unsigned long int input = props->input; ++ ++ /* Pretty crummy approach, but similar to GPIO core */ ++ for_each_clear_bit(offset, &input, 32) { ++ unsigned int i = props->bank * 32 + offset; ++ ++ if (i >= gpio->config->nr_gpios) ++ break; ++ ++ clear_bit(i, gpio->chip.irq.valid_mask); ++ } ++ ++ props++; ++ } +} + -+static int aspeed_sgpio_probe(struct platform_device *pdev) ++static int aspeed_sgpio_setup_irqs(struct aspeed_sgpio *gpio, ++ struct platform_device *pdev) +{ -+ int i, j; -+ uint irq; -+ struct resource *res; -+ struct aspeed_sgpio *priv; -+ void __iomem *base; -+ int mirq; -+ -+ // aspeed_scu_multi_func_sgpio(); done via pinctl -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ -+ base = devm_ioremap_resource(&pdev->dev, res); -+ if (IS_ERR(base)) -+ return PTR_ERR(base); -+ -+ mirq = platform_get_irq(pdev, 0); -+ if (!mirq) -+ return -ENODEV; -+ -+ for (i = 0; i < ARRAY_SIZE(aspeed_sgpio_gp); i++) { -+ // TODO: use heap allocation and use a single priv -+ priv = &aspeed_sgpio_gp[i]; -+ priv->dev = &pdev->dev; -+ priv->base = base; -+ priv->mirq = mirq; -+ dev_set_drvdata(&pdev->dev, priv); -+ -+ dev_dbg(priv->dev, "add gpio_chip [%s]: %d\n", priv->chip.label, -+ i); -+ -+ devm_gpiochip_add_data(&pdev->dev, &priv->chip, priv); -+ -+ /* Disable Interrupt & Clear Status & Set Level-High Trigger */ -+ writel(0x00000000, priv->base + priv->int_en_offset); -+ writel(0xffffffff, priv->base + priv->int_sts_offset); -+ writel(0xffffffff, priv->base + priv->int_type_offset); -+ writel(0xffffffff, priv->base + priv->int_type_offset + 0x04); -+ writel(0x00000000, priv->base + priv->int_type_offset + 0x08); -+ -+ // TODO: no this many chip registration is needed. fix it. -+ for (j = 0; j < GPIOS_PER_PORT; j++) { -+ irq = i * GPIOS_PER_PORT + j + IRQ_SGPIO_CHAIN_START; -+ dev_dbg(priv->dev, "inst chip data %d\n", irq); -+ irq_set_chip_data(irq, priv); -+ irq_set_chip_and_handler(irq, &aspeed_sgpio_irq_chip, -+ handle_level_irq); -+ irq_clear_status_flags(irq, IRQ_NOREQUEST); -+ } ++ const struct aspeed_sgpio_bank *bank; ++ int rc, i; ++ ++ /* Initialize IRQ and tolerant settings */ ++ for (i = 0; i < ARRAY_SIZE(aspeed_sgpio_banks); i++) { ++ bank = &aspeed_sgpio_banks[i]; ++ ++ /* Value will be reset by WDT reset */ ++ iowrite32(0x00000000, bank_reg(gpio, bank, reg_tolerance)); ++ ++ if (!bank->support_irq) ++ continue; ++ ++ /* disable irq enable bits */ ++ iowrite32(0x00000000, bank_reg(gpio, bank, reg_irq_enable)); ++ /* clear status bits */ ++ iowrite32(0xffffffff, bank_reg(gpio, bank, reg_irq_status)); ++ /* set rising or level-high irq */ ++ iowrite32(0xffffffff, bank_reg(gpio, bank, reg_irq_type0)); ++ /* trigger type is level */ ++ iowrite32(0xffffffff, bank_reg(gpio, bank, reg_irq_type1)); ++ /* single trigger mode */ ++ iowrite32(0x00000000, bank_reg(gpio, bank, reg_irq_type2)); + } + -+ irq_set_chained_handler(priv->mirq, aspeed_sgpio_irq_handler); ++ rc = platform_get_irq(pdev, 0); ++ if (rc < 0) ++ return rc; ++ ++ gpio->irq = rc; + -+ aspeed_sgpio_config(priv); ++ set_irq_valid_mask(gpio); + -+ dev_info(&pdev->dev, "sgpio controller registered, irq %d\n", -+ priv->mirq); ++ rc = gpiochip_irqchip_add(&gpio->chip, &aspeed_sgpio_irqchip, ++ 0, handle_bad_irq, IRQ_TYPE_NONE); ++ if (rc) { ++ dev_info(&pdev->dev, "Could not add irqchip\n"); ++ return rc; ++ } ++ ++ gpiochip_set_chained_irqchip(&gpio->chip, &aspeed_sgpio_irqchip, ++ gpio->irq, aspeed_sgpio_irq_handler); + + return 0; +} + -+static int aspeed_sgpio_remove(struct platform_device *pdev) ++static int aspeed_sgpio_reset_tolerance(struct gpio_chip *chip, ++ unsigned int offset, bool enable) +{ -+ struct aspeed_sgpio *priv = -+ &aspeed_sgpio_gp[ARRAY_SIZE(aspeed_sgpio_gp) - 1]; ++ struct aspeed_sgpio *gpio = gpiochip_get_data(chip); ++ unsigned long flags; ++ void __iomem *treg; ++ u32 val; + -+ irq_set_chained_handler(priv->mirq, NULL); ++ treg = bank_reg(gpio, to_bank(offset), reg_tolerance); ++ ++ spin_lock_irqsave(&gpio->lock, flags); ++ ++ val = readl(treg); ++ ++ if (enable) ++ val |= GPIO_BIT(offset); ++ else ++ val &= ~GPIO_BIT(offset); ++ ++ writel(val, treg); ++ ++ spin_unlock_irqrestore(&gpio->lock, flags); + + return 0; +} + ++static int aspeed_sgpio_set_config(struct gpio_chip *chip, unsigned int offset, ++ unsigned long config) ++{ ++ unsigned long param = pinconf_to_config_param(config); ++ u32 arg = pinconf_to_config_argument(config); ++ ++ if (param == PIN_CONFIG_PERSIST_STATE) ++ return aspeed_sgpio_reset_tolerance(chip, offset, arg); ++ ++ return -ENOTSUPP; ++} ++ ++/* ++ * Any banks not specified in a struct aspeed_bank_props array are assumed to ++ * have the properties: ++ * ++ * { .input = 0xffffffff, .output = 0xffffffff } ++ */ ++ ++static const struct aspeed_bank_props ast_sgpio_bank_props[] = { ++ /* input output */ ++ { 0, 0x00000000, 0xffffffff }, /* OA/OB/OC/OD */ ++ { 1, 0x00000000, 0xffffffff }, /* OE/OF/OG/OH */ ++ { 2, 0x00000000, 0x0000ffff }, /* OI/OJ */ ++ { 3, 0xffffffff, 0x00000000 }, /* IA/IB/IC/ID */ ++ { 4, 0xffffffff, 0x00000000 }, /* IE/IF/IG/IH */ ++ { 5, 0x0000ffff, 0x00000000 }, /* II/IJ */ ++ { } ++}; ++ ++/* ++ * This H/W has 80 bidirectional lines so this driver provides total 160 lines ++ * for 80 outputs and 80 inputs. To simplify bank register manipulation, it ++ * uses 96 lines per each input and output set so total 192 lines it has. ++ */ ++static const struct aspeed_sgpio_config ast2400_config = ++ { .nr_pgpios = 224, .nr_gpios = 192, .props = ast_sgpio_bank_props }; ++ ++static const struct aspeed_sgpio_config ast2500_config = ++ { .nr_pgpios = 232, .nr_gpios = 192, .props = ast_sgpio_bank_props }; ++ +static const struct of_device_id aspeed_sgpio_of_table[] = { -+ { .compatible = "aspeed,ast2400-sgpio", }, -+ { .compatible = "aspeed,ast2500-sgpio", }, -+ { }, ++ { .compatible = "aspeed,ast2400-sgpio", .data = &ast2400_config }, ++ { .compatible = "aspeed,ast2500-sgpio", .data = &ast2500_config }, ++ { } +}; +MODULE_DEVICE_TABLE(of, aspeed_sgpio_of_table); + ++static int __init aspeed_sgpio_probe(struct platform_device *pdev) ++{ ++ const struct of_device_id *gpio_id; ++ u32 sgpio_freq, clk_div, nb_gpios; ++ struct aspeed_sgpio *gpio; ++ unsigned long src_freq; ++ struct clk *clk; ++ int rc, banks; ++ ++ gpio = devm_kzalloc(&pdev->dev, sizeof(*gpio), GFP_KERNEL); ++ if (!gpio) ++ return -ENOMEM; ++ ++ gpio->base = devm_platform_ioremap_resource(pdev, 0); ++ if (IS_ERR(gpio->base)) ++ return PTR_ERR(gpio->base); ++ ++ spin_lock_init(&gpio->lock); ++ ++ gpio_id = of_match_node(aspeed_sgpio_of_table, pdev->dev.of_node); ++ if (!gpio_id) ++ return -EINVAL; ++ ++ gpio->config = gpio_id->data; ++ ++ rc = device_property_read_u32(&pdev->dev, "bus-frequency", &sgpio_freq); ++ if (rc < 0) { ++ dev_warn(&pdev->dev, "Could not read bus-frequency property. Use default.\n"); ++ sgpio_freq = ASPEED_SGPIO_BUS_FREQ_DEFAULT; ++ } ++ ++ clk = devm_clk_get(&pdev->dev, NULL); ++ if (IS_ERR(clk)) { ++ dev_err(&pdev->dev, "Failed to get clk source.\n"); ++ return PTR_ERR(clk); ++ } ++ ++ /* ++ * There is a limitation that SGPIO clock division has to be larger or ++ * equal to 1. And a read back value of clock division is 1-bit left ++ * shifted from the actual value. ++ * ++ * GPIO254[31:16] - Serial GPIO clock division: ++ * Serial GPIO clock period = period of PCLK * 2 * (GPIO254[31:16] + 1) ++ * ++ * SGPIO master controller updates every data input when SGPMLD is low. ++ * For an example, SGPIO clock is 1MHz and number of SGPIO is 80. Each ++ * SGPIO will be updated every 80us. ++ */ ++ src_freq = clk_get_rate(clk); ++ clk_div = src_freq / (2 * sgpio_freq) - 1; ++ if (clk_div < ASPEED_SGPIO_CLK_DIV_MIN) ++ clk_div = ASPEED_SGPIO_CLK_DIV_MIN; ++ else if (clk_div > ASPEED_SGPIO_CLK_DIV_MAX) ++ clk_div = ASPEED_SGPIO_CLK_DIV_MAX; ++ ++ nb_gpios = gpio->config->nr_gpios / 16; ++ if (nb_gpios < ASPEED_SGPIO_PINBYTES_MIN) ++ nb_gpios = ASPEED_SGPIO_PINBYTES_MIN; ++ else if (nb_gpios > ASPEED_SGPIO_PINBYTES_MAX) ++ nb_gpios = ASPEED_SGPIO_PINBYTES_MAX; ++ ++ iowrite32(FIELD_PREP(ASPEED_SGPIO_CLK_DIV_MASK, clk_div) | ++ FIELD_PREP(ASPEED_SGPIO_PINBYTES_MASK, nb_gpios) | ++ ASPEED_SGPIO_ENABLE, ++ gpio->base + ASPEED_SGPIO_CTRL); ++ ++ gpio->chip.parent = &pdev->dev; ++ gpio->chip.ngpio = gpio->config->nr_gpios; ++ ++ gpio->chip.direction_input = aspeed_sgpio_dir_in; ++ gpio->chip.direction_output = aspeed_sgpio_dir_out; ++ gpio->chip.get_direction = aspeed_sgpio_get_direction; ++ gpio->chip.get = aspeed_sgpio_get; ++ gpio->chip.set = aspeed_sgpio_set; ++ gpio->chip.set_config = aspeed_sgpio_set_config; ++ gpio->chip.label = dev_name(&pdev->dev); ++ gpio->chip.base = -1; ++ gpio->chip.irq.need_valid_mask = true; ++ ++ /* Allocate a cache of the output registers */ ++ banks = gpio->config->nr_gpios >> 5; ++ ++ gpio->dcache = devm_kcalloc(&pdev->dev, ++ banks, sizeof(u32), GFP_KERNEL); ++ ++ if (!gpio->dcache) ++ return -ENOMEM; ++ ++ rc = devm_gpiochip_add_data(&pdev->dev, &gpio->chip, gpio); ++ if (rc < 0) ++ return rc; ++ ++ return aspeed_sgpio_setup_irqs(gpio, pdev); ++} ++ +static struct platform_driver aspeed_sgpio_driver = { -+ .probe = aspeed_sgpio_probe, -+ .remove = aspeed_sgpio_remove, + .driver = { -+ .name = "sgpio-aspeed", -+ .of_match_table = of_match_ptr(aspeed_sgpio_of_table), ++ .name = KBUILD_MODNAME, ++ .of_match_table = aspeed_sgpio_of_table, + }, +}; + -+static int __init aspeed_sgpio_init(void) -+{ -+ return platform_driver_register(&aspeed_sgpio_driver); -+} -+subsys_initcall(aspeed_sgpio_init); -+ -+static void __exit aspeed_sgpio_exit(void) -+{ -+ platform_driver_unregister(&aspeed_sgpio_driver); -+} -+module_exit(aspeed_sgpio_exit); ++module_platform_driver_probe(aspeed_sgpio_driver, aspeed_sgpio_probe); + -+MODULE_AUTHOR("Ryan Chen <ryan_chen@aspeedtech.com>"); +MODULE_AUTHOR("Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com>"); -+MODULE_DESCRIPTION("ASPEED SGPIO driver"); ++MODULE_DESCRIPTION("Aspeed SGPIO Master Driver"); +MODULE_LICENSE("GPL v2"); -- 2.7.4 diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0009-SGPIO-DT-and-pinctrl-fixup.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0009-SGPIO-DT-and-pinctrl-fixup.patch index 8083ead0b..4210d9f67 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0009-SGPIO-DT-and-pinctrl-fixup.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0009-SGPIO-DT-and-pinctrl-fixup.patch @@ -1,4 +1,4 @@ -From 1059e64f4fc5af65f2afdc209761342fe44e3498 Mon Sep 17 00:00:00 2001 +From 0f63ecc25766fdf66610d08441e59147a4cbde78 Mon Sep 17 00:00:00 2001 From: Vernon Mauery <vernon.mauery@intel.com> Date: Wed, 16 May 2018 10:03:14 -0700 Subject: [PATCH] SGPIO DT and pinctrl fixup @@ -8,17 +8,17 @@ This commit fixes DT and pinctrl for SGPIO use. Signed-off-by: Vernon Mauery <vernon.mauery@intel.com> Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com> --- - arch/arm/boot/dts/aspeed-g4.dtsi | 54 ++++++++++-------------------- - arch/arm/boot/dts/aspeed-g5.dtsi | 8 +++++ - drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c | 48 +++++++++++++------------- + arch/arm/boot/dts/aspeed-g4.dtsi | 56 +++++++++++------------------- + arch/arm/boot/dts/aspeed-g5.dtsi | 10 ++++++ + drivers/pinctrl/aspeed/pinctrl-aspeed-g4.c | 48 ++++++++++++------------- drivers/pinctrl/aspeed/pinctrl-aspeed-g5.c | 4 +++ - 4 files changed, 54 insertions(+), 60 deletions(-) + 4 files changed, 58 insertions(+), 60 deletions(-) diff --git a/arch/arm/boot/dts/aspeed-g4.dtsi b/arch/arm/boot/dts/aspeed-g4.dtsi -index fd857be397bf..00848693f455 100644 +index fd857be397bf..58306a8232c9 100644 --- a/arch/arm/boot/dts/aspeed-g4.dtsi +++ b/arch/arm/boot/dts/aspeed-g4.dtsi -@@ -207,6 +207,18 @@ +@@ -207,6 +207,20 @@ #interrupt-cells = <2>; }; @@ -29,6 +29,8 @@ index fd857be397bf..00848693f455 100644 + reg = <0x1e780200 0x0100>; + interrupts = <40>; + interrupt-controller; ++ clocks = <&syscon ASPEED_CLK_APB>; ++ bus-frequency = <1000000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sgpm_default>; + status = "disabled"; @@ -37,7 +39,7 @@ index fd857be397bf..00848693f455 100644 timer: timer@1e782000 { /* This timer is a Faraday FTTMR010 derivative */ compatible = "aspeed,ast2400-timer"; -@@ -1180,44 +1192,14 @@ +@@ -1180,44 +1194,14 @@ groups = "SD2"; }; @@ -89,20 +91,22 @@ index fd857be397bf..00848693f455 100644 pinctrl_sioonctrl_default: sioonctrl_default { diff --git a/arch/arm/boot/dts/aspeed-g5.dtsi b/arch/arm/boot/dts/aspeed-g5.dtsi -index db82f47339aa..8406da6f62a5 100644 +index db82f47339aa..425a542690de 100644 --- a/arch/arm/boot/dts/aspeed-g5.dtsi +++ b/arch/arm/boot/dts/aspeed-g5.dtsi -@@ -298,6 +298,9 @@ +@@ -298,6 +298,11 @@ reg = <0x1e780200 0x0100>; interrupts = <40>; interrupt-controller; ++ clocks = <&syscon ASPEED_CLK_APB>; ++ bus-frequency = <1000000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sgpm_default>; + status = "disabled"; }; rtc: rtc@1e781000 { -@@ -1403,6 +1406,11 @@ +@@ -1403,6 +1408,11 @@ groups = "SDA2"; }; diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0010-Update-PECI-drivers-to-sync-with-linux-upstreaming-v.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0010-Update-PECI-drivers-to-sync-with-linux-upstreaming-v.patch index 86dd2e68c..329a92cd6 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0010-Update-PECI-drivers-to-sync-with-linux-upstreaming-v.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0010-Update-PECI-drivers-to-sync-with-linux-upstreaming-v.patch @@ -1,4 +1,4 @@ -From 2dec2c142e48a35e6c7de00c6a35e963de7447e0 Mon Sep 17 00:00:00 2001 +From 691b8580a1592eddb919e8dd295e6c1f136a4c00 Mon Sep 17 00:00:00 2001 From: Jae Hyun Yoo <jae.hyun.yoo@intel.com> Date: Mon, 7 Jan 2019 09:56:10 -0800 Subject: [PATCH] Update PECI drivers to sync with linux upstreaming version @@ -10,25 +10,25 @@ Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com> --- Documentation/hwmon/peci-cputemp | 34 +- drivers/hwmon/Kconfig | 4 +- - drivers/hwmon/peci-cputemp.c | 162 ++++-- - drivers/hwmon/peci-dimmtemp.c | 69 +-- + drivers/hwmon/peci-cputemp.c | 171 ++++--- + drivers/hwmon/peci-dimmtemp.c | 184 +++++-- drivers/hwmon/peci-hwmon.h | 9 +- drivers/mfd/Kconfig | 5 +- - drivers/mfd/intel-peci-client.c | 49 +- + drivers/mfd/intel-peci-client.c | 51 +- drivers/peci/Kconfig | 46 +- drivers/peci/Makefile | 7 +- drivers/peci/busses/Kconfig | 32 ++ drivers/peci/busses/Makefile | 7 + - drivers/peci/busses/peci-aspeed.c | 494 +++++++++++++++++++ + drivers/peci/busses/peci-aspeed.c | 492 ++++++++++++++++++ drivers/peci/busses/peci-npcm.c | 410 +++++++++++++++ drivers/peci/peci-aspeed.c | 505 ------------------- - drivers/peci/peci-core.c | 905 +++++++++++++++++++--------------- + drivers/peci/peci-core.c | 914 ++++++++++++++++++---------------- drivers/peci/peci-dev.c | 346 +++++++++++++ drivers/peci/peci-npcm.c | 410 --------------- - include/linux/mfd/intel-peci-client.h | 32 +- + include/linux/mfd/intel-peci-client.h | 31 +- include/linux/peci.h | 30 +- include/uapi/linux/peci-ioctl.h | 416 +++++++++------- - 20 files changed, 2296 insertions(+), 1676 deletions(-) + 20 files changed, 2402 insertions(+), 1702 deletions(-) create mode 100644 drivers/peci/busses/Kconfig create mode 100644 drivers/peci/busses/Makefile create mode 100644 drivers/peci/busses/peci-aspeed.c @@ -115,7 +115,7 @@ index c0623fa5ba41..7399c3cef30c 100644 source "drivers/hwmon/pmbus/Kconfig" diff --git a/drivers/hwmon/peci-cputemp.c b/drivers/hwmon/peci-cputemp.c -index 11880c86a854..3cb2db2fdf0a 100644 +index 11880c86a854..d0d68e88889f 100644 --- a/drivers/hwmon/peci-cputemp.c +++ b/drivers/hwmon/peci-cputemp.c @@ -1,5 +1,5 @@ @@ -125,7 +125,7 @@ index 11880c86a854..3cb2db2fdf0a 100644 #include <linux/hwmon.h> #include <linux/jiffies.h> -@@ -9,7 +9,7 @@ +@@ -9,18 +9,13 @@ #include <linux/platform_device.h> #include "peci-hwmon.h" @@ -134,15 +134,19 @@ index 11880c86a854..3cb2db2fdf0a 100644 #define CORETEMP_CHANNEL_NUMS CORE_NUMS_MAX #define CPUTEMP_CHANNEL_NUMS (DEFAULT_CHANNEL_NUMS + CORETEMP_CHANNEL_NUMS) -@@ -21,6 +21,7 @@ - +-/* The RESOLVED_CORES register in PCU of a client CPU */ +-#define REG_RESOLVED_CORES_BUS 1 +-#define REG_RESOLVED_CORES_DEVICE 30 +-#define REG_RESOLVED_CORES_FUNCTION 3 +-#define REG_RESOLVED_CORES_OFFSET 0xB4 +- struct temp_group { struct temp_data die; + struct temp_data dts; struct temp_data tcontrol; struct temp_data tthrottle; struct temp_data tjmax; -@@ -43,6 +44,7 @@ struct peci_cputemp { +@@ -43,6 +38,7 @@ struct peci_cputemp { enum cputemp_channels { channel_die, @@ -150,7 +154,7 @@ index 11880c86a854..3cb2db2fdf0a 100644 channel_tcontrol, channel_tthrottle, channel_tjmax, -@@ -54,6 +56,10 @@ static const u32 config_table[DEFAULT_CHANNEL_NUMS + 1] = { +@@ -54,6 +50,10 @@ static const u32 config_table[DEFAULT_CHANNEL_NUMS + 1] = { HWMON_T_LABEL | HWMON_T_INPUT | HWMON_T_MAX | HWMON_T_CRIT | HWMON_T_CRIT_HYST, @@ -161,7 +165,7 @@ index 11880c86a854..3cb2db2fdf0a 100644 /* Tcontrol temperature */ HWMON_T_LABEL | HWMON_T_INPUT | HWMON_T_CRIT, -@@ -70,6 +76,7 @@ static const u32 config_table[DEFAULT_CHANNEL_NUMS + 1] = { +@@ -70,6 +70,7 @@ static const u32 config_table[DEFAULT_CHANNEL_NUMS + 1] = { static const char *cputemp_label[CPUTEMP_CHANNEL_NUMS] = { "Die", @@ -169,7 +173,7 @@ index 11880c86a854..3cb2db2fdf0a 100644 "Tcontrol", "Tthrottle", "Tjmax", -@@ -92,19 +99,20 @@ static int get_temp_targets(struct peci_cputemp *priv) +@@ -92,19 +93,20 @@ static int get_temp_targets(struct peci_cputemp *priv) s32 tthrottle_offset; s32 tcontrol_margin; u8 pkg_cfg[4]; @@ -196,7 +200,7 @@ index 11880c86a854..3cb2db2fdf0a 100644 priv->temp.tjmax.value = pkg_cfg[2] * 1000; -@@ -123,17 +131,16 @@ static int get_temp_targets(struct peci_cputemp *priv) +@@ -123,17 +125,16 @@ static int get_temp_targets(struct peci_cputemp *priv) static int get_die_temp(struct peci_cputemp *priv) { struct peci_get_temp_msg msg; @@ -218,33 +222,27 @@ index 11880c86a854..3cb2db2fdf0a 100644 /* Note that the tjmax should be available before calling it */ priv->temp.die.value = priv->temp.tjmax.value + -@@ -144,24 +151,70 @@ static int get_die_temp(struct peci_cputemp *priv) +@@ -144,24 +145,64 @@ static int get_die_temp(struct peci_cputemp *priv) return 0; } +static int get_dts(struct peci_cputemp *priv) +{ -+ struct peci_rd_pkg_cfg_msg msg; + s32 dts_margin; ++ u8 pkg_cfg[4]; + int ret; + + if (!peci_temp_need_update(&priv->temp.dts)) + return 0; + -+ msg.addr = priv->mgr->client->addr; -+ msg.index = PECI_MBX_INDEX_DTS_MARGIN; -+ msg.param = 0; -+ msg.rx_len = 4; ++ ret = peci_client_read_package_config(priv->mgr, ++ PECI_MBX_INDEX_DTS_MARGIN, 0, ++ pkg_cfg); + -+ ret = peci_command(priv->mgr->client->adapter, PECI_CMD_RD_PKG_CFG, -+ &msg); + if (ret) + return ret; + -+ if (msg.cc != PECI_DEV_CC_SUCCESS) -+ return -EAGAIN; -+ -+ dts_margin = (msg.pkg_config[1] << 8) | msg.pkg_config[0]; ++ dts_margin = (pkg_cfg[1] << 8) | pkg_cfg[0]; + + /** + * Processors return a value of DTS reading in 10.6 format @@ -296,7 +294,7 @@ index 11880c86a854..3cb2db2fdf0a 100644 * Processors return a value of the core DTS reading in 10.6 format * (10 bits signed decimal, 6 bits fractional). * Error codes: -@@ -192,6 +245,7 @@ static int cputemp_read_string(struct device *dev, +@@ -192,6 +233,7 @@ static int cputemp_read_string(struct device *dev, return -EOPNOTSUPP; *str = cputemp_label[channel]; @@ -304,7 +302,7 @@ index 11880c86a854..3cb2db2fdf0a 100644 return 0; } -@@ -200,26 +254,33 @@ static int cputemp_read(struct device *dev, +@@ -200,26 +242,33 @@ static int cputemp_read(struct device *dev, u32 attr, int channel, long *val) { struct peci_cputemp *priv = dev_get_drvdata(dev); @@ -344,7 +342,7 @@ index 11880c86a854..3cb2db2fdf0a 100644 case channel_tcontrol: *val = priv->temp.tcontrol.value; break; -@@ -231,8 +292,8 @@ static int cputemp_read(struct device *dev, +@@ -231,8 +280,8 @@ static int cputemp_read(struct device *dev, break; default: core_index = channel - DEFAULT_CHANNEL_NUMS; @@ -355,7 +353,7 @@ index 11880c86a854..3cb2db2fdf0a 100644 break; *val = priv->temp.core[core_index].value; -@@ -249,11 +310,11 @@ static int cputemp_read(struct device *dev, +@@ -249,11 +298,11 @@ static int cputemp_read(struct device *dev, *val = priv->temp.tjmax.value - priv->temp.tcontrol.value; break; default: @@ -369,7 +367,7 @@ index 11880c86a854..3cb2db2fdf0a 100644 } static umode_t cputemp_is_visible(const void *data, -@@ -262,11 +323,11 @@ static umode_t cputemp_is_visible(const void *data, +@@ -262,11 +311,11 @@ static umode_t cputemp_is_visible(const void *data, { const struct peci_cputemp *priv = data; @@ -386,7 +384,7 @@ index 11880c86a854..3cb2db2fdf0a 100644 return 0; } -@@ -280,7 +341,7 @@ static const struct hwmon_ops cputemp_ops = { +@@ -280,40 +329,43 @@ static const struct hwmon_ops cputemp_ops = { static int check_resolved_cores(struct peci_cputemp *priv) { struct peci_rd_pci_cfg_local_msg msg; @@ -395,8 +393,14 @@ index 11880c86a854..3cb2db2fdf0a 100644 /* Get the RESOLVED_CORES register value */ msg.addr = priv->mgr->client->addr; -@@ -290,30 +351,34 @@ static int check_resolved_cores(struct peci_cputemp *priv) - msg.reg = REG_RESOLVED_CORES_OFFSET; +- msg.bus = REG_RESOLVED_CORES_BUS; +- msg.device = REG_RESOLVED_CORES_DEVICE; +- msg.function = REG_RESOLVED_CORES_FUNCTION; +- msg.reg = REG_RESOLVED_CORES_OFFSET; ++ msg.bus = 1; ++ msg.device = 30; ++ msg.function = 3; ++ msg.reg = 0xb4; msg.rx_len = 4; - rc = peci_command(priv->mgr->client->adapter, @@ -405,11 +409,10 @@ index 11880c86a854..3cb2db2fdf0a 100644 - return rc; + ret = peci_command(priv->mgr->client->adapter, + PECI_CMD_RD_PCI_CFG_LOCAL, &msg); ++ if (msg.cc != PECI_DEV_CC_SUCCESS) ++ ret = -EAGAIN; + if (ret) + return ret; -+ -+ if (msg.cc != PECI_DEV_CC_SUCCESS) -+ return -EAGAIN; priv->core_mask = le32_to_cpup((__le32 *)msg.pci_config); if (!priv->core_mask) @@ -439,7 +442,7 @@ index 11880c86a854..3cb2db2fdf0a 100644 priv->temp_config[priv->config_idx++] = config_table[channel_core]; -@@ -326,7 +391,7 @@ static int peci_cputemp_probe(struct platform_device *pdev) +@@ -326,7 +378,7 @@ static int peci_cputemp_probe(struct platform_device *pdev) struct device *dev = &pdev->dev; struct peci_cputemp *priv; struct device *hwmon_dev; @@ -448,7 +451,7 @@ index 11880c86a854..3cb2db2fdf0a 100644 if ((mgr->client->adapter->cmd_mask & (BIT(PECI_CMD_GET_TEMP) | BIT(PECI_CMD_RD_PKG_CFG))) != -@@ -346,12 +411,13 @@ static int peci_cputemp_probe(struct platform_device *pdev) +@@ -346,12 +398,13 @@ static int peci_cputemp_probe(struct platform_device *pdev) mgr->client->addr - PECI_BASE_ADDR); priv->temp_config[priv->config_idx++] = config_table[channel_die]; @@ -464,8 +467,17 @@ index 11880c86a854..3cb2db2fdf0a 100644 dev_dbg(dev, "Skipped creating core temp info\n"); priv->chip.ops = &cputemp_ops; +@@ -385,7 +438,7 @@ MODULE_DEVICE_TABLE(platform, peci_cputemp_ids); + static struct platform_driver peci_cputemp_driver = { + .probe = peci_cputemp_probe, + .id_table = peci_cputemp_ids, +- .driver = { .name = "peci-cputemp", }, ++ .driver = { .name = KBUILD_MODNAME, }, + }; + module_platform_driver(peci_cputemp_driver); + diff --git a/drivers/hwmon/peci-dimmtemp.c b/drivers/hwmon/peci-dimmtemp.c -index 86a45a90805b..e088366fd138 100644 +index 86a45a90805b..a404b6ea4ba3 100644 --- a/drivers/hwmon/peci-dimmtemp.c +++ b/drivers/hwmon/peci-dimmtemp.c @@ -1,5 +1,5 @@ @@ -475,9 +487,20 @@ index 86a45a90805b..e088366fd138 100644 #include <linux/hwmon.h> #include <linux/jiffies.h> -@@ -45,16 +45,16 @@ static int get_dimm_temp(struct peci_dimmtemp *priv, int dimm_no) +@@ -21,6 +21,8 @@ struct peci_dimmtemp { + struct workqueue_struct *work_queue; + struct delayed_work work_handler; + struct temp_data temp[DIMM_NUMS_MAX]; ++ long temp_max[DIMM_NUMS_MAX]; ++ long temp_crit[DIMM_NUMS_MAX]; + u32 dimm_mask; + int retry_count; + u32 temp_config[DIMM_NUMS_MAX + 1]; +@@ -44,20 +46,106 @@ static int get_dimm_temp(struct peci_dimmtemp *priv, int dimm_no) + { int dimm_order = dimm_no % priv->gen_info->dimm_idx_max; int chan_rank = dimm_no / priv->gen_info->dimm_idx_max; ++ struct peci_rd_pci_cfg_local_msg rp_msg; u8 cfg_data[4]; - int rc; + int ret; @@ -498,7 +521,95 @@ index 86a45a90805b..e088366fd138 100644 priv->temp[dimm_no].value = cfg_data[dimm_order] * 1000; -@@ -77,6 +77,7 @@ static int dimmtemp_read_string(struct device *dev, ++ switch (priv->gen_info->model) { ++ case INTEL_FAM6_SKYLAKE_X: ++ rp_msg.addr = priv->mgr->client->addr; ++ rp_msg.bus = 2; ++ /* ++ * Device 10, Function 2: IMC 0 channel 0 -> rank 0 ++ * Device 10, Function 6: IMC 0 channel 1 -> rank 1 ++ * Device 11, Function 2: IMC 0 channel 2 -> rank 2 ++ * Device 12, Function 2: IMC 1 channel 0 -> rank 3 ++ * Device 12, Function 6: IMC 1 channel 1 -> rank 4 ++ * Device 13, Function 2: IMC 1 channel 2 -> rank 5 ++ */ ++ rp_msg.device = 10 + chan_rank / 3 * 2 + ++ (chan_rank % 3 == 2 ? 1 : 0); ++ rp_msg.function = chan_rank % 3 == 1 ? 6 : 2; ++ rp_msg.reg = 0x120 + dimm_order * 4; ++ rp_msg.rx_len = 4; ++ ++ ret = peci_command(priv->mgr->client->adapter, ++ PECI_CMD_RD_PCI_CFG_LOCAL, &rp_msg); ++ if (rp_msg.cc != PECI_DEV_CC_SUCCESS) ++ ret = -EAGAIN; ++ if (ret) ++ return ret; ++ ++ priv->temp_max[dimm_no] = rp_msg.pci_config[1] * 1000; ++ priv->temp_crit[dimm_no] = rp_msg.pci_config[2] * 1000; ++ break; ++ case INTEL_FAM6_SKYLAKE_XD: ++ rp_msg.addr = priv->mgr->client->addr; ++ rp_msg.bus = 2; ++ /* ++ * Device 10, Function 2: IMC 0 channel 0 -> rank 0 ++ * Device 10, Function 6: IMC 0 channel 1 -> rank 1 ++ * Device 12, Function 2: IMC 1 channel 0 -> rank 2 ++ * Device 12, Function 6: IMC 1 channel 1 -> rank 3 ++ */ ++ rp_msg.device = 10 + chan_rank / 2 * 2; ++ rp_msg.function = chan_rank % 2 ? 6 : 2; ++ rp_msg.reg = 0x120 + dimm_order * 4; ++ rp_msg.rx_len = 4; ++ ++ ret = peci_command(priv->mgr->client->adapter, ++ PECI_CMD_RD_PCI_CFG_LOCAL, &rp_msg); ++ if (rp_msg.cc != PECI_DEV_CC_SUCCESS) ++ ret = -EAGAIN; ++ if (ret) ++ return ret; ++ ++ priv->temp_max[dimm_no] = rp_msg.pci_config[1] * 1000; ++ priv->temp_crit[dimm_no] = rp_msg.pci_config[2] * 1000; ++ break; ++ case INTEL_FAM6_HASWELL_X: ++ case INTEL_FAM6_BROADWELL_X: ++ rp_msg.addr = priv->mgr->client->addr; ++ rp_msg.bus = 1; ++ /* ++ * Device 20, Function 0: IMC 0 channel 0 -> rank 0 ++ * Device 20, Function 1: IMC 0 channel 1 -> rank 1 ++ * Device 21, Function 0: IMC 0 channel 2 -> rank 2 ++ * Device 21, Function 1: IMC 0 channel 3 -> rank 3 ++ * Device 23, Function 0: IMC 1 channel 0 -> rank 4 ++ * Device 23, Function 1: IMC 1 channel 1 -> rank 5 ++ * Device 24, Function 0: IMC 1 channel 2 -> rank 6 ++ * Device 24, Function 1: IMC 1 channel 3 -> rank 7 ++ */ ++ rp_msg.device = 20 + chan_rank / 2 + chan_rank / 4; ++ rp_msg.function = chan_rank % 2; ++ rp_msg.reg = 0x120 + dimm_order * 4; ++ rp_msg.rx_len = 4; ++ ++ ret = peci_command(priv->mgr->client->adapter, ++ PECI_CMD_RD_PCI_CFG_LOCAL, &rp_msg); ++ if (rp_msg.cc != PECI_DEV_CC_SUCCESS) ++ ret = -EAGAIN; ++ if (ret) ++ return ret; ++ ++ priv->temp_max[dimm_no] = rp_msg.pci_config[1] * 1000; ++ priv->temp_crit[dimm_no] = rp_msg.pci_config[2] * 1000; ++ break; ++ default: ++ return -EOPNOTSUPP; ++ } ++ + peci_temp_mark_updated(&priv->temp[dimm_no]); + + return 0; +@@ -77,6 +165,7 @@ static int dimmtemp_read_string(struct device *dev, chan_rank = channel / dimm_idx_max; dimm_idx = channel % dimm_idx_max; *str = dimmtemp_label[chan_rank][dimm_idx]; @@ -506,29 +617,46 @@ index 86a45a90805b..e088366fd138 100644 return 0; } -@@ -84,16 +85,17 @@ static int dimmtemp_read(struct device *dev, enum hwmon_sensor_types type, +@@ -84,17 +173,28 @@ static int dimmtemp_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, long *val) { struct peci_dimmtemp *priv = dev_get_drvdata(dev); - int rc; -+ int ret; - - if (attr != hwmon_temp_input) - return -EOPNOTSUPP; - +- +- if (attr != hwmon_temp_input) +- return -EOPNOTSUPP; +- - rc = get_dimm_temp(priv, channel); - if (rc) - return rc; ++ int ret; ++ + ret = get_dimm_temp(priv, channel); + if (ret) + return ret; - - *val = priv->temp[channel].value; + - return 0; ++ switch (attr) { ++ case hwmon_temp_input: ++ *val = priv->temp[channel].value; ++ break; ++ case hwmon_temp_max: ++ *val = priv->temp_max[channel]; ++ break; ++ case hwmon_temp_crit: ++ *val = priv->temp_crit[channel]; ++ break; ++ default: ++ ret = -EOPNOTSUPP; ++ break; ++ } + +- *val = priv->temp[channel].value; +- return 0; ++ return ret; } -@@ -120,16 +122,16 @@ static int check_populated_dimms(struct peci_dimmtemp *priv) + static umode_t dimmtemp_is_visible(const void *data, +@@ -120,16 +220,16 @@ static int check_populated_dimms(struct peci_dimmtemp *priv) { u32 chan_rank_max = priv->gen_info->chan_rank_max; u32 dimm_idx_max = priv->gen_info->dimm_idx_max; @@ -551,7 +679,7 @@ index 86a45a90805b..e088366fd138 100644 } for (dimm_idx = 0; dimm_idx < dimm_idx_max; dimm_idx++) -@@ -143,17 +145,18 @@ static int check_populated_dimms(struct peci_dimmtemp *priv) +@@ -143,17 +243,18 @@ static int check_populated_dimms(struct peci_dimmtemp *priv) return -EAGAIN; dev_dbg(priv->dev, "Scanned populated DIMMs: 0x%x\n", priv->dimm_mask); @@ -574,7 +702,7 @@ index 86a45a90805b..e088366fd138 100644 if (priv->retry_count < DIMM_MASK_CHECK_RETRY_MAX) { queue_delayed_work(priv->work_queue, &priv->work_handler, -@@ -164,11 +167,11 @@ static int create_dimm_temp_info(struct peci_dimmtemp *priv) +@@ -164,11 +265,11 @@ static int create_dimm_temp_info(struct peci_dimmtemp *priv) } else { dev_err(priv->dev, "Timeout DIMM temp info creation\n"); @@ -588,7 +716,17 @@ index 86a45a90805b..e088366fd138 100644 } channels = priv->gen_info->chan_rank_max * -@@ -192,12 +195,12 @@ static int create_dimm_temp_info(struct peci_dimmtemp *priv) +@@ -177,7 +278,8 @@ static int create_dimm_temp_info(struct peci_dimmtemp *priv) + if (priv->dimm_mask & BIT(i)) + while (i >= config_idx) + priv->temp_config[config_idx++] = +- HWMON_T_LABEL | HWMON_T_INPUT; ++ HWMON_T_LABEL | HWMON_T_INPUT | ++ HWMON_T_MAX | HWMON_T_CRIT; + + priv->chip.ops = &dimmtemp_ops; + priv->chip.info = priv->info; +@@ -192,12 +294,12 @@ static int create_dimm_temp_info(struct peci_dimmtemp *priv) priv, &priv->chip, NULL); @@ -604,7 +742,7 @@ index 86a45a90805b..e088366fd138 100644 } static void create_dimm_temp_info_delayed(struct work_struct *work) -@@ -205,10 +208,10 @@ static void create_dimm_temp_info_delayed(struct work_struct *work) +@@ -205,10 +307,10 @@ static void create_dimm_temp_info_delayed(struct work_struct *work) struct delayed_work *dwork = to_delayed_work(work); struct peci_dimmtemp *priv = container_of(dwork, struct peci_dimmtemp, work_handler); @@ -618,7 +756,7 @@ index 86a45a90805b..e088366fd138 100644 dev_dbg(priv->dev, "Failed to create DIMM temp info\n"); } -@@ -217,7 +220,7 @@ static int peci_dimmtemp_probe(struct platform_device *pdev) +@@ -217,7 +319,7 @@ static int peci_dimmtemp_probe(struct platform_device *pdev) struct peci_client_manager *mgr = dev_get_drvdata(pdev->dev.parent); struct device *dev = &pdev->dev; struct peci_dimmtemp *priv; @@ -627,7 +765,7 @@ index 86a45a90805b..e088366fd138 100644 if ((mgr->client->adapter->cmd_mask & (BIT(PECI_CMD_GET_TEMP) | BIT(PECI_CMD_RD_PKG_CFG))) != -@@ -242,8 +245,8 @@ static int peci_dimmtemp_probe(struct platform_device *pdev) +@@ -242,8 +344,8 @@ static int peci_dimmtemp_probe(struct platform_device *pdev) INIT_DELAYED_WORK(&priv->work_handler, create_dimm_temp_info_delayed); @@ -638,7 +776,7 @@ index 86a45a90805b..e088366fd138 100644 dev_err(dev, "Failed to create DIMM temp info\n"); goto err_free_wq; } -@@ -252,7 +255,7 @@ static int peci_dimmtemp_probe(struct platform_device *pdev) +@@ -252,7 +354,7 @@ static int peci_dimmtemp_probe(struct platform_device *pdev) err_free_wq: destroy_workqueue(priv->work_queue); @@ -647,6 +785,15 @@ index 86a45a90805b..e088366fd138 100644 } static int peci_dimmtemp_remove(struct platform_device *pdev) +@@ -275,7 +377,7 @@ static struct platform_driver peci_dimmtemp_driver = { + .probe = peci_dimmtemp_probe, + .remove = peci_dimmtemp_remove, + .id_table = peci_dimmtemp_ids, +- .driver = { .name = "peci-dimmtemp", }, ++ .driver = { .name = KBUILD_MODNAME, }, + }; + module_platform_driver(peci_dimmtemp_driver); + diff --git a/drivers/hwmon/peci-hwmon.h b/drivers/hwmon/peci-hwmon.h index 6ca1855a86bb..ce6b470eae63 100644 --- a/drivers/hwmon/peci-hwmon.h @@ -696,7 +843,7 @@ index 75dbcc7da87c..6f7ee4dd08f6 100644 bool "Atmel Micro ASIC (iPAQ h3100/h3600/h3700) Support" depends on SA1100_H3100 || SA1100_H3600 diff --git a/drivers/mfd/intel-peci-client.c b/drivers/mfd/intel-peci-client.c -index d53e4f1078ac..466085fd43b9 100644 +index d53e4f1078ac..18bf0af0e09e 100644 --- a/drivers/mfd/intel-peci-client.c +++ b/drivers/mfd/intel-peci-client.c @@ -1,12 +1,12 @@ @@ -727,7 +874,7 @@ index d53e4f1078ac..466085fd43b9 100644 static struct mfd_cell peci_functions[] = { { .name = "peci-cputemp", }, { .name = "peci-dimmtemp", }, -@@ -31,19 +25,25 @@ static struct mfd_cell peci_functions[] = { +@@ -31,38 +25,45 @@ static struct mfd_cell peci_functions[] = { }; static const struct cpu_gen_info cpu_gen_info_table[] = { @@ -746,17 +893,19 @@ index d53e4f1078ac..466085fd43b9 100644 .chan_rank_max = CHAN_RANK_MAX_ON_BDX, .dimm_idx_max = DIMM_IDX_MAX_ON_BDX }, - [CPU_GEN_SKX] = { -+ { /* Broadwell Xeon D */ -+ .family = 6, /* Family code */ -+ .model = INTEL_FAM6_BROADWELL_XEON_D, -+ .core_max = CORE_MAX_ON_XD, -+ .chan_rank_max = CHAN_RANK_MAX_ON_XD, -+ .dimm_idx_max = DIMM_IDX_MAX_ON_XD }, + { /* Skylake Xeon */ .family = 6, /* Family code */ .model = INTEL_FAM6_SKYLAKE_X, .core_max = CORE_MAX_ON_SKX, -@@ -53,16 +53,17 @@ static const struct cpu_gen_info cpu_gen_info_table[] = { + .chan_rank_max = CHAN_RANK_MAX_ON_SKX, + .dimm_idx_max = DIMM_IDX_MAX_ON_SKX }, ++ { /* Skylake Xeon D */ ++ .family = 6, /* Family code */ ++ .model = INTEL_FAM6_SKYLAKE_XD, ++ .core_max = CORE_MAX_ON_SKXD, ++ .chan_rank_max = CHAN_RANK_MAX_ON_SKXD, ++ .dimm_idx_max = DIMM_IDX_MAX_ON_SKXD }, + }; static int peci_client_get_cpu_gen_info(struct peci_client_manager *priv) { @@ -830,6 +979,15 @@ index d53e4f1078ac..466085fd43b9 100644 static const struct peci_device_id peci_client_ids[] = { { .name = "peci-client" }, +@@ -139,7 +138,7 @@ static struct peci_driver peci_client_driver = { + .probe = peci_client_probe, + .id_table = peci_client_ids, + .driver = { +- .name = "peci-client", ++ .name = KBUILD_MODNAME, + .of_match_table = of_match_ptr(peci_client_of_table), + }, + }; diff --git a/drivers/peci/Kconfig b/drivers/peci/Kconfig index 7293108fb543..9752feee2454 100644 --- a/drivers/peci/Kconfig @@ -972,10 +1130,10 @@ index 000000000000..aa8ce3ae5947 +obj-$(CONFIG_PECI_NPCM) += peci-npcm.o diff --git a/drivers/peci/busses/peci-aspeed.c b/drivers/peci/busses/peci-aspeed.c new file mode 100644 -index 000000000000..8a0dd40730cc +index 000000000000..851b71e32eac --- /dev/null +++ b/drivers/peci/busses/peci-aspeed.c -@@ -0,0 +1,494 @@ +@@ -0,0 +1,492 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright (C) 2012-2017 ASPEED Technology Inc. +// Copyright (c) 2018-2019 Intel Corporation @@ -1371,7 +1529,6 @@ index 000000000000..8a0dd40730cc +{ + struct peci_adapter *adapter; + struct aspeed_peci *priv; -+ struct resource *res; + int ret; + + adapter = peci_alloc_adapter(&pdev->dev, sizeof(*priv)); @@ -1383,8 +1540,7 @@ index 000000000000..8a0dd40730cc + priv->dev = &pdev->dev; + dev_set_drvdata(&pdev->dev, priv); + -+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ priv->base = devm_ioremap_resource(&pdev->dev, res); ++ priv->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->base)) { + ret = PTR_ERR(priv->base); + goto err_put_adapter_dev; @@ -1413,7 +1569,7 @@ index 000000000000..8a0dd40730cc + priv->rst = devm_reset_control_get(&pdev->dev, NULL); + if (IS_ERR(priv->rst)) { + dev_err(&pdev->dev, -+ "missing or invalid reset controller entry"); ++ "missing or invalid reset controller entry\n"); + ret = PTR_ERR(priv->rst); + goto err_put_adapter_dev; + } @@ -1460,7 +1616,7 @@ index 000000000000..8a0dd40730cc + .probe = aspeed_peci_probe, + .remove = aspeed_peci_remove, + .driver = { -+ .name = "peci-aspeed", ++ .name = KBUILD_MODNAME, + .of_match_table = of_match_ptr(aspeed_peci_of_table), + }, +}; @@ -2398,7 +2554,7 @@ index 51cb2563ceb6..000000000000 -MODULE_DESCRIPTION("ASPEED PECI driver"); -MODULE_LICENSE("GPL v2"); diff --git a/drivers/peci/peci-core.c b/drivers/peci/peci-core.c -index 6f241469ec7e..d1f0df8b139a 100644 +index 6f241469ec7e..48f29de09311 100644 --- a/drivers/peci/peci-core.c +++ b/drivers/peci/peci-core.c @@ -1,38 +1,31 @@ @@ -3400,7 +3556,7 @@ index 6f241469ec7e..d1f0df8b139a 100644 static int peci_check_addr_validity(u8 addr) { -@@ -814,18 +907,23 @@ static int peci_check_client_busy(struct device *dev, void *client_new_p) +@@ -814,18 +907,22 @@ static int peci_check_client_busy(struct device *dev, void *client_new_p) int peci_get_cpu_id(struct peci_adapter *adapter, u8 addr, u32 *cpu_id) { struct peci_rd_pkg_cfg_msg msg; @@ -3418,12 +3574,11 @@ index 6f241469ec7e..d1f0df8b139a 100644 - if (!rc) - *cpu_id = le32_to_cpup((__le32 *)msg.pkg_config); + ret = peci_command(adapter, PECI_CMD_RD_PKG_CFG, &msg); ++ if (msg.cc != PECI_DEV_CC_SUCCESS) ++ ret = -EAGAIN; + if (ret) + return ret; + -+ if (msg.cc != PECI_DEV_CC_SUCCESS) -+ return -EAGAIN; -+ + *cpu_id = le32_to_cpup((__le32 *)msg.pkg_config); - return rc; @@ -3431,7 +3586,7 @@ index 6f241469ec7e..d1f0df8b139a 100644 } EXPORT_SYMBOL_GPL(peci_get_cpu_id); -@@ -833,7 +931,7 @@ static struct peci_client *peci_new_device(struct peci_adapter *adapter, +@@ -833,7 +930,7 @@ static struct peci_client *peci_new_device(struct peci_adapter *adapter, struct peci_board_info const *info) { struct peci_client *client; @@ -3440,7 +3595,7 @@ index 6f241469ec7e..d1f0df8b139a 100644 /* Increase reference count for the adapter assigned */ if (!peci_get_adapter(adapter->nr)) -@@ -847,46 +945,49 @@ static struct peci_client *peci_new_device(struct peci_adapter *adapter, +@@ -847,46 +944,49 @@ static struct peci_client *peci_new_device(struct peci_adapter *adapter, client->addr = info->addr; strlcpy(client->name, info->type, sizeof(client->name)); @@ -3502,7 +3657,7 @@ index 6f241469ec7e..d1f0df8b139a 100644 return NULL; } -@@ -895,8 +996,10 @@ static void peci_unregister_device(struct peci_client *client) +@@ -895,8 +995,10 @@ static void peci_unregister_device(struct peci_client *client) if (!client) return; @@ -3514,7 +3669,7 @@ index 6f241469ec7e..d1f0df8b139a 100644 device_unregister(&client->dev); } -@@ -916,7 +1019,7 @@ static void peci_adapter_dev_release(struct device *dev) +@@ -916,7 +1018,7 @@ static void peci_adapter_dev_release(struct device *dev) dev_dbg(dev, "%s: %s\n", __func__, adapter->name); mutex_destroy(&adapter->userspace_clients_lock); @@ -3523,7 +3678,7 @@ index 6f241469ec7e..d1f0df8b139a 100644 kfree(adapter); } -@@ -928,7 +1031,8 @@ static ssize_t peci_sysfs_new_device(struct device *dev, +@@ -928,7 +1030,8 @@ static ssize_t peci_sysfs_new_device(struct device *dev, struct peci_board_info info = {}; struct peci_client *client; char *blank, end; @@ -3533,7 +3688,7 @@ index 6f241469ec7e..d1f0df8b139a 100644 /* Parse device type */ blank = strchr(buf, ' '); -@@ -943,16 +1047,17 @@ static ssize_t peci_sysfs_new_device(struct device *dev, +@@ -943,16 +1046,17 @@ static ssize_t peci_sysfs_new_device(struct device *dev, memcpy(info.type, buf, blank - buf); /* Parse remaining parameters, reject extra parameters */ @@ -3554,7 +3709,7 @@ index 6f241469ec7e..d1f0df8b139a 100644 client = peci_new_device(adapter, &info); if (!client) return -EINVAL; -@@ -961,8 +1066,8 @@ static ssize_t peci_sysfs_new_device(struct device *dev, +@@ -961,8 +1065,8 @@ static ssize_t peci_sysfs_new_device(struct device *dev, mutex_lock(&adapter->userspace_clients_lock); list_add_tail(&client->detected, &adapter->userspace_clients); mutex_unlock(&adapter->userspace_clients_lock); @@ -3565,7 +3720,7 @@ index 6f241469ec7e..d1f0df8b139a 100644 return count; } -@@ -975,9 +1080,9 @@ static ssize_t peci_sysfs_delete_device(struct device *dev, +@@ -975,9 +1079,9 @@ static ssize_t peci_sysfs_delete_device(struct device *dev, struct peci_adapter *adapter = to_peci_adapter(dev); struct peci_client *client, *next; struct peci_board_info info = {}; @@ -3577,7 +3732,7 @@ index 6f241469ec7e..d1f0df8b139a 100644 /* Parse device type */ blank = strchr(buf, ' '); -@@ -992,41 +1097,41 @@ static ssize_t peci_sysfs_delete_device(struct device *dev, +@@ -992,41 +1096,41 @@ static ssize_t peci_sysfs_delete_device(struct device *dev, memcpy(info.type, buf, blank - buf); /* Parse remaining parameters, reject extra parameters */ @@ -3631,7 +3786,7 @@ index 6f241469ec7e..d1f0df8b139a 100644 } static DEVICE_ATTR_IGNORE_LOCKDEP(delete_device, 0200, NULL, peci_sysfs_delete_device); -@@ -1039,10 +1144,11 @@ static struct attribute *peci_adapter_attrs[] = { +@@ -1039,10 +1143,11 @@ static struct attribute *peci_adapter_attrs[] = { }; ATTRIBUTE_GROUPS(peci_adapter); @@ -3644,7 +3799,7 @@ index 6f241469ec7e..d1f0df8b139a 100644 /** * peci_verify_adapter - return parameter as peci_adapter, or NULL -@@ -1063,32 +1169,26 @@ static struct peci_client *peci_of_register_device(struct peci_adapter *adapter, +@@ -1063,32 +1168,26 @@ static struct peci_client *peci_of_register_device(struct peci_adapter *adapter, struct device_node *node) { struct peci_board_info info = {}; @@ -3689,7 +3844,7 @@ index 6f241469ec7e..d1f0df8b139a 100644 } static void peci_of_register_devices(struct peci_adapter *adapter) -@@ -1119,7 +1219,7 @@ static void peci_of_register_devices(struct peci_adapter *adapter) +@@ -1119,7 +1218,7 @@ static void peci_of_register_devices(struct peci_adapter *adapter) of_node_put(bus); } @@ -3698,7 +3853,7 @@ index 6f241469ec7e..d1f0df8b139a 100644 static void peci_of_register_devices(struct peci_adapter *adapter) { } #endif /* CONFIG_OF */ -@@ -1163,9 +1263,7 @@ static struct peci_adapter *peci_of_find_adapter(struct device_node *node) +@@ -1163,9 +1262,7 @@ static struct peci_adapter *peci_of_find_adapter(struct device_node *node) return adapter; } @@ -3709,7 +3864,7 @@ index 6f241469ec7e..d1f0df8b139a 100644 { struct of_reconfig_data *rd = arg; struct peci_adapter *adapter; -@@ -1216,7 +1314,7 @@ static int peci_of_notify(struct notifier_block *nb, +@@ -1216,7 +1313,7 @@ static int peci_of_notify(struct notifier_block *nb, static struct notifier_block peci_of_notifier = { .notifier_call = peci_of_notify, }; @@ -3718,7 +3873,7 @@ index 6f241469ec7e..d1f0df8b139a 100644 extern struct notifier_block peci_of_notifier; #endif /* CONFIG_OF_DYNAMIC */ -@@ -1240,7 +1338,7 @@ extern struct notifier_block peci_of_notifier; +@@ -1240,7 +1337,7 @@ extern struct notifier_block peci_of_notifier; * * Return: the peci_adapter structure on success, else NULL. */ @@ -3727,7 +3882,7 @@ index 6f241469ec7e..d1f0df8b139a 100644 { struct peci_adapter *adapter; -@@ -1263,7 +1361,7 @@ EXPORT_SYMBOL_GPL(peci_alloc_adapter); +@@ -1263,7 +1360,7 @@ EXPORT_SYMBOL_GPL(peci_alloc_adapter); static int peci_register_adapter(struct peci_adapter *adapter) { @@ -3736,7 +3891,7 @@ index 6f241469ec7e..d1f0df8b139a 100644 /* Can't register until after driver model init */ if (WARN_ON(!is_registered)) -@@ -1275,27 +1373,17 @@ static int peci_register_adapter(struct peci_adapter *adapter) +@@ -1275,27 +1372,17 @@ static int peci_register_adapter(struct peci_adapter *adapter) if (WARN(!adapter->xfer, "peci adapter has no xfer function\n")) goto err_free_idr; @@ -3769,7 +3924,7 @@ index 6f241469ec7e..d1f0df8b139a 100644 } dev_dbg(&adapter->dev, "adapter [%s] registered\n", adapter->name); -@@ -1309,13 +1397,11 @@ static int peci_register_adapter(struct peci_adapter *adapter) +@@ -1309,13 +1396,11 @@ static int peci_register_adapter(struct peci_adapter *adapter) return 0; @@ -3784,7 +3939,24 @@ index 6f241469ec7e..d1f0df8b139a 100644 } static int peci_add_numbered_adapter(struct peci_adapter *adapter) -@@ -1411,7 +1497,7 @@ void peci_del_adapter(struct peci_adapter *adapter) +@@ -1354,12 +1439,10 @@ int peci_add_adapter(struct peci_adapter *adapter) + struct device *dev = &adapter->dev; + int id; + +- if (dev->of_node) { +- id = of_alias_get_id(dev->of_node, "peci"); +- if (id >= 0) { +- adapter->nr = id; +- return peci_add_numbered_adapter(adapter); +- } ++ id = of_alias_get_id(dev->of_node, "peci"); ++ if (id >= 0) { ++ adapter->nr = id; ++ return peci_add_numbered_adapter(adapter); + } + + mutex_lock(&core_lock); +@@ -1411,7 +1494,7 @@ void peci_del_adapter(struct peci_adapter *adapter) } mutex_unlock(&adapter->userspace_clients_lock); @@ -3793,7 +3965,7 @@ index 6f241469ec7e..d1f0df8b139a 100644 * Detach any active clients. This can't fail, thus we do not * check the returned value. */ -@@ -1420,13 +1506,8 @@ void peci_del_adapter(struct peci_adapter *adapter) +@@ -1420,13 +1503,8 @@ void peci_del_adapter(struct peci_adapter *adapter) /* device name is gone after device_unregister */ dev_dbg(&adapter->dev, "adapter [%s] unregistered\n", adapter->name); @@ -3807,7 +3979,7 @@ index 6f241469ec7e..d1f0df8b139a 100644 device_unregister(&adapter->dev); /* free bus id */ -@@ -1436,6 +1517,18 @@ void peci_del_adapter(struct peci_adapter *adapter) +@@ -1436,6 +1514,18 @@ void peci_del_adapter(struct peci_adapter *adapter) } EXPORT_SYMBOL_GPL(peci_del_adapter); @@ -3826,7 +3998,7 @@ index 6f241469ec7e..d1f0df8b139a 100644 /** * peci_register_driver - register a PECI driver * @owner: owner module of the driver being registered -@@ -1446,7 +1539,7 @@ EXPORT_SYMBOL_GPL(peci_del_adapter); +@@ -1446,7 +1536,7 @@ EXPORT_SYMBOL_GPL(peci_del_adapter); */ int peci_register_driver(struct module *owner, struct peci_driver *driver) { @@ -3835,7 +4007,7 @@ index 6f241469ec7e..d1f0df8b139a 100644 /* Can't register until after driver model init */ if (WARN_ON(!is_registered)) -@@ -1456,13 +1549,13 @@ int peci_register_driver(struct module *owner, struct peci_driver *driver) +@@ -1456,13 +1546,13 @@ int peci_register_driver(struct module *owner, struct peci_driver *driver) driver->driver.owner = owner; driver->driver.bus = &peci_bus_type; @@ -3853,7 +4025,7 @@ index 6f241469ec7e..d1f0df8b139a 100644 pr_debug("driver [%s] registered\n", driver->driver.name); -@@ -1492,13 +1585,6 @@ static int __init peci_init(void) +@@ -1492,13 +1582,6 @@ static int __init peci_init(void) return ret; } @@ -3867,7 +4039,7 @@ index 6f241469ec7e..d1f0df8b139a 100644 crc8_populate_msb(peci_crc8_table, PECI_CRC8_POLYNOMIAL); if (IS_ENABLED(CONFIG_OF_DYNAMIC)) -@@ -1514,11 +1600,10 @@ static void __exit peci_exit(void) +@@ -1514,11 +1597,10 @@ static void __exit peci_exit(void) if (IS_ENABLED(CONFIG_OF_DYNAMIC)) WARN_ON(of_reconfig_notifier_unregister(&peci_of_notifier)); @@ -4649,7 +4821,7 @@ index f632365b1416..000000000000 -MODULE_DESCRIPTION("NPCM Platform Environment Control Interface (PECI) driver"); -MODULE_LICENSE("GPL v2"); diff --git a/include/linux/mfd/intel-peci-client.h b/include/linux/mfd/intel-peci-client.h -index 8f6d823a59cd..7b62a02e46ee 100644 +index 8f6d823a59cd..9854303bbc26 100644 --- a/include/linux/mfd/intel-peci-client.h +++ b/include/linux/mfd/intel-peci-client.h @@ -1,5 +1,5 @@ @@ -4674,22 +4846,22 @@ index 8f6d823a59cd..7b62a02e46ee 100644 -#define INTEL_FAM6_SKYLAKE_X 0x55 +#define INTEL_FAM6_HASWELL_X 0x3F +#define INTEL_FAM6_BROADWELL_X 0x4F -+#define INTEL_FAM6_BROADWELL_XEON_D 0x56 +#define INTEL_FAM6_SKYLAKE_X 0x55 ++#define INTEL_FAM6_SKYLAKE_XD 0x56 #endif #define CORE_MAX_ON_HSX 18 /* Max number of cores on Haswell */ -@@ -27,6 +28,10 @@ - #define CHAN_RANK_MAX_ON_BDX 4 /* Max number of channel ranks on Broadwell */ - #define DIMM_IDX_MAX_ON_BDX 3 /* Max DIMM index per channel on Broadwell */ - -+#define CORE_MAX_ON_XD 16 /* Max number of cores on Xeon D */ -+#define CHAN_RANK_MAX_ON_XD 2 /* Max number of channel ranks on Xeon D */ -+#define DIMM_IDX_MAX_ON_XD 2 /* Max DIMM index per channel on Xeon D */ -+ - #define CORE_MAX_ON_SKX 28 /* Max number of cores on Skylake */ +@@ -31,6 +32,10 @@ #define CHAN_RANK_MAX_ON_SKX 6 /* Max number of channel ranks on Skylake */ #define DIMM_IDX_MAX_ON_SKX 2 /* Max DIMM index per channel on Skylake */ + ++#define CORE_MAX_ON_SKXD 16 /* Max number of cores on Skylake D */ ++#define CHAN_RANK_MAX_ON_SKXD 2 /* Max number of channel ranks on Skylake D */ ++#define DIMM_IDX_MAX_ON_SKXD 2 /* Max DIMM index per channel on Skylake D */ ++ + #define CORE_NUMS_MAX CORE_MAX_ON_SKX + #define CHAN_RANK_MAX CHAN_RANK_MAX_ON_HSX + #define DIMM_IDX_MAX DIMM_IDX_MAX_ON_HSX @@ -58,7 +63,6 @@ struct cpu_gen_info { /** * struct peci_client_manager - PECI client manager information @@ -4706,7 +4878,7 @@ index 8f6d823a59cd..7b62a02e46ee 100644 char name[PECI_NAME_SIZE]; const struct cpu_gen_info *gen_info; }; -@@ -93,18 +96,23 @@ peci_client_read_package_config(struct peci_client_manager *priv, +@@ -93,18 +96,22 @@ peci_client_read_package_config(struct peci_client_manager *priv, u8 index, u16 param, u8 *data) { struct peci_rd_pkg_cfg_msg msg; @@ -4722,12 +4894,11 @@ index 8f6d823a59cd..7b62a02e46ee 100644 - if (!rc) - memcpy(data, msg.pkg_config, 4); + ret = peci_command(priv->client->adapter, PECI_CMD_RD_PKG_CFG, &msg); ++ if (msg.cc != PECI_DEV_CC_SUCCESS) ++ ret = -EAGAIN; + if (ret) + return ret; + -+ if (msg.cc != PECI_DEV_CC_SUCCESS) -+ return -EAGAIN; -+ + memcpy(data, msg.pkg_config, 4); - return rc; diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0026-Add-support-for-new-PECI-commands.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0026-Add-support-for-new-PECI-commands.patch index 0e11e1c3e..53060daf7 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0026-Add-support-for-new-PECI-commands.patch +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0026-Add-support-for-new-PECI-commands.patch @@ -588,7 +588,7 @@ index 253fb42e38b7..405cd8edbcbf 100644 + struct peci_rd_end_pt_cfg_msg) + +#define PECI_IOC_WR_END_PT_CFG \ -+ _IOWR(PECI_IOC_BASE, PECI_IOC_WR_END_PT_CFG, \ ++ _IOWR(PECI_IOC_BASE, PECI_CMD_WR_END_PT_CFG, \ + struct peci_wr_end_pt_cfg_msg) + +#define PECI_IOC_CRASHDUMP_DISC \ diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0069-i2c-aspeed-add-SLAVE_ADDR_RECEIVED_PENDING-interrupt.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0069-i2c-aspeed-add-SLAVE_ADDR_RECEIVED_PENDING-interrupt.patch new file mode 100644 index 000000000..dc38c81f3 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0069-i2c-aspeed-add-SLAVE_ADDR_RECEIVED_PENDING-interrupt.patch @@ -0,0 +1,50 @@ +From 085bde1e91d85435c44a752bd59d38cf31465518 Mon Sep 17 00:00:00 2001 +From: Jae Hyun Yoo <jae.hyun.yoo@intel.com> +Date: Thu, 11 Jul 2019 14:04:39 -0700 +Subject: [PATCH] i2c: aspeed: add SLAVE_ADDR_RECEIVED_PENDING interrupt + handling + +If a peer master sends messages too quickly before it processes +previous slave DMA data handling, this indicator will be set. It's +just a indicator and driver can't recover this case so just ignore +it. + +Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com> +--- + drivers/i2c/busses/i2c-aspeed.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/drivers/i2c/busses/i2c-aspeed.c b/drivers/i2c/busses/i2c-aspeed.c +index d41f377de9dc..46de9a01a0eb 100644 +--- a/drivers/i2c/busses/i2c-aspeed.c ++++ b/drivers/i2c/busses/i2c-aspeed.c +@@ -86,6 +86,7 @@ + * These share bit definitions, so use the same values for the enable & + * status bits. + */ ++#define ASPEED_I2CD_INTR_SLAVE_ADDR_RECEIVED_PENDING BIT(30) + #define ASPEED_I2CD_INTR_SLAVE_INACTIVE_TIMEOUT BIT(15) + #define ASPEED_I2CD_INTR_SDA_DL_TIMEOUT BIT(14) + #define ASPEED_I2CD_INTR_BUS_RECOVER_DONE BIT(13) +@@ -353,6 +354,18 @@ static u32 aspeed_i2c_slave_irq(struct aspeed_i2c_bus *bus, u32 irq_status) + dev_dbg(bus->dev, "slave irq status 0x%08x, cmd 0x%08x\n", + irq_status, command); + ++ /* ++ * If a peer master sends messages too quickly before it processes ++ * previous slave DMA data handling, this indicator will be set. It's ++ * just a indicator and driver can't recover this case so just ignore ++ * it. ++ */ ++ if (unlikely(irq_status & ++ ASPEED_I2CD_INTR_SLAVE_ADDR_RECEIVED_PENDING)) { ++ dev_dbg(bus->dev, "A slave addr match interrupt is pending.\n"); ++ irq_handled |= ASPEED_I2CD_INTR_SLAVE_ADDR_RECEIVED_PENDING; ++ } ++ + /* Slave was sent something. */ + if (irq_status & ASPEED_I2CD_INTR_RX_DONE) { + if (bus->dma_buf && +-- +2.7.4 + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0070-gpio-aspeed-temporary-fix-for-gpiochip-range-setting.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0070-gpio-aspeed-temporary-fix-for-gpiochip-range-setting.patch new file mode 100644 index 000000000..4af5be95d --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0070-gpio-aspeed-temporary-fix-for-gpiochip-range-setting.patch @@ -0,0 +1,44 @@ +From 9195eef3fec7022ca52ac9791c19de2362ed042e Mon Sep 17 00:00:00 2001 +From: Jae Hyun Yoo <jae.hyun.yoo@intel.com> +Date: Fri, 19 Jul 2019 12:54:38 -0700 +Subject: [PATCH] gpio: aspeed: temporary fix for gpiochip range setting + +Since we are still using fixed indices for gpio line numbers for sysfs +interface, this commit set the gpiochip range as fixed temporariliy +til we replace all index based gpio uses with name based uses. + +Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com> +--- + drivers/gpio/gpio-aspeed.c | 2 +- + drivers/gpio/sgpio-aspeed.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c +index e426452a28f7..d4aaf7fa8e4b 100644 +--- a/drivers/gpio/gpio-aspeed.c ++++ b/drivers/gpio/gpio-aspeed.c +@@ -1189,7 +1189,7 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev) + gpio->chip.set = aspeed_gpio_set; + gpio->chip.set_config = aspeed_gpio_set_config; + gpio->chip.label = dev_name(&pdev->dev); +- gpio->chip.base = -1; ++ gpio->chip.base = 0; + gpio->chip.irq.need_valid_mask = true; + + /* Allocate a cache of the output registers */ +diff --git a/drivers/gpio/sgpio-aspeed.c b/drivers/gpio/sgpio-aspeed.c +index 6fb402a3f74d..2f4c0aab0bf2 100644 +--- a/drivers/gpio/sgpio-aspeed.c ++++ b/drivers/gpio/sgpio-aspeed.c +@@ -675,7 +675,7 @@ static int __init aspeed_sgpio_probe(struct platform_device *pdev) + gpio->chip.set = aspeed_sgpio_set; + gpio->chip.set_config = aspeed_sgpio_set_config; + gpio->chip.label = dev_name(&pdev->dev); +- gpio->chip.base = -1; ++ gpio->chip.base = gpio->config->nr_pgpios; + gpio->chip.irq.need_valid_mask = true; + + /* Allocate a cache of the output registers */ +-- +2.7.4 + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0071-peci-add-a-temporary-workaround.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0071-peci-add-a-temporary-workaround.patch new file mode 100644 index 000000000..e32ec54ac --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0071-peci-add-a-temporary-workaround.patch @@ -0,0 +1,101 @@ +From 3394fabbd17ad7263feeb0f4ae593056237f0647 Mon Sep 17 00:00:00 2001 +From: Jae Hyun Yoo <jae.hyun.yoo@intel.com> +Date: Tue, 30 Jul 2019 13:01:58 -0700 +Subject: [PATCH] peci: add a temporary workaround + +To cover a PECI issue, this commit makes PECI driver block all PECI +commands when PLTRST_N signal is 0. + +Also, it adds 'use_wa' module parameter for platforms that don't have +the PLTRST_N gpio input so that the WA can be disabled through the +module parameter. + +This is a temporary workaround. + +Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com> +--- + drivers/peci/busses/peci-aspeed.c | 11 +++++++++++ + drivers/peci/peci-core.c | 11 +++++++++++ + include/linux/peci.h | 1 + + 3 files changed, 23 insertions(+) + +diff --git a/drivers/peci/busses/peci-aspeed.c b/drivers/peci/busses/peci-aspeed.c +index 8a0dd40730cc..76394ab32854 100644 +--- a/drivers/peci/busses/peci-aspeed.c ++++ b/drivers/peci/busses/peci-aspeed.c +@@ -10,6 +10,7 @@ + #include <linux/jiffies.h> + #include <linux/module.h> + #include <linux/of.h> ++#include <linux/of_gpio.h> + #include <linux/peci.h> + #include <linux/platform_device.h> + #include <linux/reset.h> +@@ -445,6 +446,16 @@ static int aspeed_peci_probe(struct platform_device *pdev) + if (ret) + goto err_put_adapter_dev; + ++ priv->adapter->pltrst_pin = of_get_gpio(pdev->dev.of_node, 0); ++ if (gpio_is_valid(priv->adapter->pltrst_pin)) { ++ ret = devm_gpio_request(&pdev->dev, priv->adapter->pltrst_pin, ++ "peci-aspeed"); ++ if (ret < 0) { ++ priv->adapter->pltrst_pin = -1; ++ dev_err(&pdev->dev, "error requesting pltrst gpio\n"); ++ } ++ } ++ + ret = peci_add_adapter(priv->adapter); + if (ret) + goto err_put_adapter_dev; +diff --git a/drivers/peci/peci-core.c b/drivers/peci/peci-core.c +index b99ba788a032..2e3b9a0c83e9 100644 +--- a/drivers/peci/peci-core.c ++++ b/drivers/peci/peci-core.c +@@ -5,6 +5,7 @@ + #include <linux/crc8.h> + #include <linux/delay.h> + #include <linux/mm.h> ++#include <linux/gpio.h> + #include <linux/module.h> + #include <linux/of_device.h> + #include <linux/peci.h> +@@ -190,6 +191,11 @@ static int peci_aw_fcs(struct peci_xfer_msg *msg, int len, u8 *aw_fcs) + return 0; + } + ++/* Temporary WA */ ++static bool use_wa __read_mostly = true; ++module_param_named(use_wa, use_wa, bool, 0644); ++MODULE_PARM_DESC(use_wa, "flag for enabling of WA"); ++ + static int __peci_xfer(struct peci_adapter *adapter, struct peci_xfer_msg *msg, + bool do_retry, bool has_aw_fcs) + { +@@ -197,6 +203,11 @@ static int __peci_xfer(struct peci_adapter *adapter, struct peci_xfer_msg *msg, + u8 aw_fcs; + int ret; + ++ /* Temporary WA */ ++ if (use_wa && gpio_is_valid(adapter->pltrst_pin) && ++ gpio_get_value(adapter->pltrst_pin) == 0) ++ return -EAGAIN; ++ + /* + * In case if adapter uses DMA, check at here whether tx and rx buffers + * are DMA capable or not. +diff --git a/include/linux/peci.h b/include/linux/peci.h +index 6fc424dc2a73..e589cb258a2a 100644 +--- a/include/linux/peci.h ++++ b/include/linux/peci.h +@@ -44,6 +44,7 @@ struct peci_adapter { + struct peci_xfer_msg *msg); + u32 cmd_mask; + bool use_dma; ++ int pltrst_pin; + }; + + static inline struct peci_adapter *to_peci_adapter(void *d) +-- +2.7.4 + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0072-pmbus-add-fault-and-beep-attributes.patch b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0072-pmbus-add-fault-and-beep-attributes.patch new file mode 100644 index 000000000..40a9272e0 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed/0072-pmbus-add-fault-and-beep-attributes.patch @@ -0,0 +1,88 @@ +From e360a6c2a3f15bfc8900c7262c56f9bcd5e0f16e Mon Sep 17 00:00:00 2001 +From: Jae Hyun Yoo <jae.hyun.yoo@intel.com> +Date: Thu, 8 Aug 2019 10:38:00 -0700 +Subject: [PATCH] pmbus: add 'fault' and 'beep' attributes + +This commit adds two more attirbutes to reflect MFR_SPECIFIC bit in +the STATUS_WORD and 'Unit Off For Insufficient Input Voltage' bit in +the STATUS_INPUT into 'fault' and 'beep' attributes respectively. + +The attributes will be enumerated as 'inX_fault' and 'inX_beep' in +a 'vin' group. + +Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@intel.com> +--- + drivers/hwmon/pmbus/pmbus.h | 1 + + drivers/hwmon/pmbus/pmbus_core.c | 30 ++++++++++++++++++++++++++++++ + 2 files changed, 31 insertions(+) + +diff --git a/drivers/hwmon/pmbus/pmbus.h b/drivers/hwmon/pmbus/pmbus.h +index d198af3a92b6..09e6fe01c304 100644 +--- a/drivers/hwmon/pmbus/pmbus.h ++++ b/drivers/hwmon/pmbus/pmbus.h +@@ -303,6 +303,7 @@ enum pmbus_fan_mode { percent = 0, rpm }; + #define PB_PIN_OP_WARNING BIT(0) + #define PB_IIN_OC_WARNING BIT(1) + #define PB_IIN_OC_FAULT BIT(2) ++#define PB_UNIT_OFF_FOR_INSUF_VIN BIT(3) + + /* + * STATUS_TEMPERATURE +diff --git a/drivers/hwmon/pmbus/pmbus_core.c b/drivers/hwmon/pmbus/pmbus_core.c +index 898d7378f4f8..85295a45c3ba 100644 +--- a/drivers/hwmon/pmbus/pmbus_core.c ++++ b/drivers/hwmon/pmbus/pmbus_core.c +@@ -1163,6 +1163,8 @@ struct pmbus_limit_attr { + struct pmbus_sensor_attr { + u16 reg; /* sensor register */ + u16 gbit; /* generic status bit */ ++ u16 gfbit; /* generic fault status bit */ ++ u16 sbbit; /* beep status bit */ + u8 nlimit; /* # of limit registers */ + enum pmbus_sensor_classes class;/* sensor class */ + const char *label; /* sensor label */ +@@ -1264,6 +1266,32 @@ static int pmbus_add_sensor_attrs_one(struct i2c_client *client, + return ret; + } + } ++ /* ++ * Add fault attribute if there is a generic fault bit, and if ++ * the generic status register (word or byte, depending on which global ++ * bit is set) for this page is accessible. ++ */ ++ if (attr->gfbit) { ++ upper = !!(attr->gfbit & 0xff00); /* need to check STATUS_WORD */ ++ if ((!upper || (upper && data->has_status_word)) && ++ pmbus_check_status_register(client, page)) { ++ ret = pmbus_add_boolean(data, name, "fault", index, ++ NULL, NULL, ++ PB_STATUS_BASE + page, ++ attr->gfbit); ++ if (ret) ++ return ret; ++ } ++ } ++ /* Add beep attribute if there is a beep status bit. */ ++ if (attr->sbbit) { ++ ret = pmbus_add_boolean(data, name, "beep", index, ++ NULL, NULL, ++ attr->sbase + page, ++ attr->sbbit); ++ if (ret) ++ return ret; ++ } + return 0; + } + +@@ -1435,6 +1463,8 @@ static const struct pmbus_sensor_attr voltage_attributes[] = { + .gbit = PB_STATUS_VIN_UV, + .limit = vin_limit_attrs, + .nlimit = ARRAY_SIZE(vin_limit_attrs), ++ .gfbit = PB_STATUS_WORD_MFR, ++ .sbbit = PB_UNIT_OFF_FOR_INSUF_VIN, + }, { + .reg = PMBUS_VIRT_READ_VMON, + .class = PSC_VOLTAGE_IN, +-- +2.7.4 + diff --git a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed_%.bbappend b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed_%.bbappend index 999c8d17c..8ff89685b 100644 --- a/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-kernel/linux/linux-aspeed_%.bbappend @@ -44,4 +44,8 @@ SRC_URI += " \ file://0067-i2c-aspeed-add-DMA-mode-transfer-support.patch \ file://0001-set-idle-disconnect-to-true-in-all-cases.patch \ file://0068-i2c-aspeed-add-H-W-timeout-support.patch \ + file://0069-i2c-aspeed-add-SLAVE_ADDR_RECEIVED_PENDING-interrupt.patch \ + file://0070-gpio-aspeed-temporary-fix-for-gpiochip-range-setting.patch \ + file://0071-peci-add-a-temporary-workaround.patch \ + file://0072-pmbus-add-fault-and-beep-attributes.patch \ " diff --git a/meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network/0002-IPv6-Network-changes-to-configuration-file.patch b/meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network/0002-IPv6-Network-changes-to-configuration-file.patch deleted file mode 100644 index b46702902..000000000 --- a/meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network/0002-IPv6-Network-changes-to-configuration-file.patch +++ /dev/null @@ -1,208 +0,0 @@ -From 53dbefc9f31dcfca06d7c7705ea3dcfc5e93ae72 Mon Sep 17 00:00:00 2001 -From: David Cobbley <david.j.cobbley@linux.intel.com> -Date: Wed, 6 Jun 2018 11:11:43 -0700 -Subject: [PATCH 1/2] IPv6 Network changes to configuration file - -Allow Additional parameters to be set for IPv6 - -Change-Id: If662f1ce2d265bc525073890c49231bf6f2b8a30 ---- - ethernet_interface.cpp | 109 +++++++++++++++++++++++++++++++++++++++-- - ethernet_interface.hpp | 17 +++++++ - util.cpp | 3 +- - 3 files changed, 123 insertions(+), 6 deletions(-) - -diff --git a/ethernet_interface.cpp b/ethernet_interface.cpp -index 154efcb..aa1c895 100644 ---- a/ethernet_interface.cpp -+++ b/ethernet_interface.cpp -@@ -46,6 +46,8 @@ EthernetInterface::EthernetInterface(sdbusplus::bus::bus& bus, - std::replace(intfName.begin(), intfName.end(), '_', '.'); - interfaceName(intfName); - EthernetInterfaceIntf::dHCPEnabled(dhcpEnabled); -+ EthernetInterfaceIntf::iPAddressEnables(getIPAddressEnablesFromConf()); -+ EthernetInterfaceIntf::iPv6AcceptRA(getIPv6AcceptRAFromConf()); - MacAddressIntf::mACAddress(getMACAddress(intfName)); - EthernetInterfaceIntf::nTPServers(getNTPServersFromConf()); - EthernetInterfaceIntf::nameservers(getNameServerFromConf()); -@@ -329,7 +331,16 @@ std::string EthernetInterface::generateObjectPath( - objectPath /= generateId(ipaddress, prefixLength, gateway); - return objectPath.string(); - } -- -+bool EthernetInterface::iPv6AcceptRA(bool value) -+{ -+ if (value == EthernetInterfaceIntf::iPv6AcceptRA()) -+ { -+ return value; -+ } -+ EthernetInterfaceIntf::iPv6AcceptRA(value); -+ manager.writeToConfigurationFile(); -+ return value; -+} - bool EthernetInterface::dHCPEnabled(bool value) - { - if (value == EthernetInterfaceIntf::dHCPEnabled()) -@@ -442,7 +453,80 @@ ObjectPath EthernetInterface::createVLAN(VlanId id) - - return path; - } -+bool EthernetInterface::getIPv6AcceptRAFromConf() -+{ -+ fs::path confPath = manager.getConfDir(); -+ -+ std::string fileName = systemd::config::networkFilePrefix + -+ interfaceName() + systemd::config::networkFileSuffix; -+ confPath /= fileName; -+ config::ValueList values; -+ config::Parser parser(confPath.string()); -+ auto rc = config::ReturnCode::SUCCESS; -+ std::tie(rc, values) = parser.getValues("Network", "IPv6AcceptRA"); -+ if (rc != config::ReturnCode::SUCCESS) -+ { -+ log<level::DEBUG>("Unable to get the value for Network[IPv6AcceptRA]", -+ entry("rc=%d", rc)); -+ return false; -+ } -+ if (values[0] == "true") -+ { -+ return true; -+ } -+ -+ return false; -+} -+EthernetInterface::IPAllowed EthernetInterface::getIPAddressEnablesFromConf() -+{ -+ fs::path confPath = manager.getConfDir(); -+ -+ std::string fileName = systemd::config::networkFilePrefix + -+ interfaceName() + systemd::config::networkFileSuffix; -+ confPath /= fileName; -+ config::ValueList values; -+ config::Parser parser(confPath.string()); -+ auto rc = config::ReturnCode::SUCCESS; -+ std::tie(rc, values) = parser.getValues("Network", "DHCP"); -+ if (rc != config::ReturnCode::SUCCESS) -+ { -+ log<level::DEBUG>("Unable to get the value for Network[DHCP]", -+ entry("rc=%d", rc)); -+ return EthernetInterface::IPAllowed::IPv4AndIPv6; -+ } -+ // true, false, ipv4, ipv6 -+ if (values[0] == "ipv6") -+ { -+ return EthernetInterface::IPAllowed::IPv6Only; -+ } -+ else if (values[0] == "ipv4") -+ { -+ return EthernetInterface::IPAllowed::IPv4Only; -+ } -+ else if (values[0] == "off") -+ { -+ // This function should not get called if DHCP == off -+ log<level::DEBUG>("Function not available in static mode"); -+ return EthernetInterface::IPAllowed::IPv4AndIPv6; -+ } -+ else -+ { -+ return EthernetInterface::IPAllowed::IPv4AndIPv6; -+ } -+} -+EthernetInterface::IPAllowed -+ EthernetInterface::iPAddressEnables(EthernetInterface::IPAllowed iPAllowed) -+{ -+ if (iPAllowed == EthernetInterfaceIntf::iPAddressEnables()) -+ { -+ return iPAllowed; -+ } -+ -+ EthernetInterfaceIntf::iPAddressEnables(iPAllowed); -+ writeConfigurationFile(); - -+ return iPAllowed; -+} - ServerList EthernetInterface::getNTPServersFromConf() - { - fs::path confPath = manager.getConfDir(); -@@ -524,7 +608,8 @@ void EthernetInterface::writeConfigurationFile() - #else - stream << "LinkLocalAddressing=no\n"; - #endif -- stream << "IPv6AcceptRA=false\n"; -+ stream << std::boolalpha -+ << "IPv6AcceptRA=" << EthernetInterfaceIntf::iPv6AcceptRA() << "\n"; - - // Add the VLAN entry - for (const auto& intf : vlanInterfaces) -@@ -533,8 +618,24 @@ void EthernetInterface::writeConfigurationFile() - << "\n"; - } - // Add the DHCP entry -- auto value = dHCPEnabled() ? "true"s : "false"s; -- stream << "DHCP="s + value + "\n"; -+ std::string dhcpValue = "false"; -+ if (dHCPEnabled()) -+ { -+ IPAllowed ipAllowed = EthernetInterfaceIntf::iPAddressEnables(); -+ if (ipAllowed == IPAllowed::IPv4AndIPv6) -+ { -+ dhcpValue = "true"; -+ } -+ else if (ipAllowed == IPAllowed::IPv4Only) -+ { -+ dhcpValue = "ipv4"; -+ } -+ else if (ipAllowed == IPAllowed::IPv6Only) -+ { -+ dhcpValue = "ipv6"; -+ } -+ } -+ stream << "DHCP=" << dhcpValue << "\n"; - - // When the interface configured as dhcp, we don't need below given entries - // in config file. -diff --git a/ethernet_interface.hpp b/ethernet_interface.hpp -index c65726a..55fd7d9 100644 ---- a/ethernet_interface.hpp -+++ b/ethernet_interface.hpp -@@ -207,6 +207,23 @@ class EthernetInterface : public Ifaces - /** @brief write the dhcp section **/ - void writeDHCPSection(std::fstream& stream); - -+ /** @brief get the IPv6AcceptRA flag from the network configuration file -+ * -+ */ -+ bool getIPv6AcceptRAFromConf(); -+ -+ /** @brief check conf file for Router Advertisements -+ * -+ */ -+ bool iPv6AcceptRA(bool value) override; -+ -+ /** @brief get the allowed network modes. Similar to DHCP enabled, but -+ * more specific -+ */ -+ IPAllowed getIPAddressEnablesFromConf(); -+ -+ IPAllowed iPAddressEnables(IPAllowed) override; -+ - /** @brief get the NTP server list from the network conf - * - */ -diff --git a/util.cpp b/util.cpp -index 6bc1497..6c60d54 100644 ---- a/util.cpp -+++ b/util.cpp -@@ -461,8 +461,7 @@ bool getDHCPValue(const std::string& confDir, const std::string& intf) - entry("RC=%d", rc)); - return dhcp; - } -- // There will be only single value for DHCP key. -- if (values[0] == "true") -+ if (values[0] != "false") - { - dhcp = true; - } --- -2.17.1 - diff --git a/meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network_%.bbappend b/meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network_%.bbappend index afec5d41f..ee0d78d57 100644 --- a/meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-network/network/phosphor-network_%.bbappend @@ -2,8 +2,7 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" DEPENDS += "nlohmann-json" -SRC_URI += "file://0002-IPv6-Network-changes-to-configuration-file.patch \ - file://0003-Adding-channel-specific-privilege-to-network.patch \ +SRC_URI += "file://0003-Adding-channel-specific-privilege-to-network.patch \ " SRCREV = "f273d2b5629d2a7d96802dc7a7ddb92e303ac8de" diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/beepcode-mgr/beepcode-mgr.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/beepcode-mgr/beepcode-mgr.bb new file mode 100644 index 000000000..347ba7cdd --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/beepcode-mgr/beepcode-mgr.bb @@ -0,0 +1,25 @@ + +SUMMARY = "Beep code manager service" +DESCRIPTION = "The beep code manager service will provide a method for beep code" + +SRC_URI = "\ + file://CMakeLists.txt \ + file://beepcode_mgr.cpp \ + " +PV = "0.1" + +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://${PHOSPHORBASE}/LICENSE;md5=19407077e42b1ba3d653da313f1f5b4e" + +S = "${WORKDIR}" + +SYSTEMD_SERVICE_${PN} = "beepcode-mgr.service" + +inherit cmake +inherit obmc-phosphor-systemd + +DEPENDS += " \ + sdbusplus \ + phosphor-logging \ + boost \ + " diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/beepcode-mgr/files/.clang-format b/meta-openbmc-mods/meta-common/recipes-phosphor/beepcode-mgr/files/.clang-format new file mode 100644 index 000000000..dd2770837 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/beepcode-mgr/files/.clang-format @@ -0,0 +1,98 @@ +--- +Language: Cpp +# BasedOnStyle: LLVM +AccessModifierOffset: -2 +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlinesLeft: false +AlignOperands: true +AlignTrailingComments: true +AllowAllParametersOfDeclarationOnNextLine: true +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: false +AllowShortLoopsOnASingleLine: false +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakBeforeMultilineStrings: false +AlwaysBreakTemplateDeclarations: false +BinPackArguments: true +BinPackParameters: true +BraceWrapping: + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: true + BeforeCatch: true + BeforeElse: true + IndentBraces: false +BreakBeforeBinaryOperators: None +BreakBeforeBraces: Custom +BreakBeforeTernaryOperators: true +BreakConstructorInitializers: AfterColon +ColumnLimit: 80 +CommentPragmas: '^ IWYU pragma:' +ConstructorInitializerAllOnOneLineOrOnePerLine: false +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +Cpp11BracedListStyle: true +DerivePointerAlignment: true +PointerAlignment: Left +DisableFormat: false +ExperimentalAutoDetectBinPacking: false +FixNamespaceComments: true +ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ] +IncludeBlocks: Regroup +IncludeCategories: + - Regex: '^[<"](gtest|gmock)' + Priority: 5 + - Regex: '^"config.h"' + Priority: -1 + - Regex: '^".*\.hpp"' + Priority: 1 + - Regex: '^<.*\.h>' + Priority: 2 + - Regex: '^<.*' + Priority: 3 + - Regex: '.*' + Priority: 4 +IndentCaseLabels: true +IndentWidth: 4 +IndentWrappedFunctionNames: true +KeepEmptyLinesAtTheStartOfBlocks: true +MacroBlockBegin: '' +MacroBlockEnd: '' +MaxEmptyLinesToKeep: 1 +NamespaceIndentation: None +ObjCBlockIndentWidth: 2 +ObjCSpaceAfterProperty: false +ObjCSpaceBeforeProtocolList: true +PenaltyBreakBeforeFirstCallParameter: 19 +PenaltyBreakComment: 300 +PenaltyBreakFirstLessLess: 120 +PenaltyBreakString: 1000 +PenaltyExcessCharacter: 1000000 +PenaltyReturnTypeOnItsOwnLine: 60 +PointerAlignment: Right +ReflowComments: true +SortIncludes: true +SpaceAfterCStyleCast: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 1 +SpacesInAngles: false +SpacesInContainerLiterals: true +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false +Standard: Cpp11 +TabWidth: 4 +UseTab: Never +... diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/beepcode-mgr/files/CMakeLists.txt b/meta-openbmc-mods/meta-common/recipes-phosphor/beepcode-mgr/files/CMakeLists.txt new file mode 100644 index 000000000..472257279 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/beepcode-mgr/files/CMakeLists.txt @@ -0,0 +1,39 @@ +cmake_minimum_required (VERSION 3.5 FATAL_ERROR) +project (beepcode-mgr CXX) +set (CMAKE_CXX_STANDARD 17) +set (CMAKE_CXX_STANDARD_REQUIRED ON) +set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti") +set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-rtti") + +include_directories (${CMAKE_CURRENT_SOURCE_DIR}) + +# boost support +find_package (Boost REQUIRED) +# pkg_check_modules(Boost boost REQUIRED) +include_directories (${Boost_INCLUDE_DIRS}) +add_definitions (-DBOOST_ERROR_CODE_HEADER_ONLY) +add_definitions (-DBOOST_SYSTEM_NO_DEPRECATED) +add_definitions (-DBOOST_ALL_NO_LIB) +add_definitions (-DBOOST_NO_RTTI) +add_definitions (-DBOOST_NO_TYPEID) +add_definitions (-DBOOST_ASIO_DISABLE_THREADS) + +# import sdbusplus +find_package (PkgConfig REQUIRED) +pkg_check_modules (SDBUSPLUSPLUS sdbusplus REQUIRED) +include_directories (${SDBUSPLUSPLUS_INCLUDE_DIRS}) +link_directories (${SDBUSPLUSPLUS_LIBRARY_DIRS}) + +# import phosphor-logging +find_package (PkgConfig REQUIRED) +pkg_check_modules (LOGGING phosphor-logging REQUIRED) +include_directories (${LOGGING_INCLUDE_DIRS}) +link_directories (${LOGGING_LIBRARY_DIRS}) + +add_executable (beepcode-mgr beepcode_mgr.cpp) + +target_link_libraries (${PROJECT_NAME} ${Boost_LIBRARIES}) +target_link_libraries (${PROJECT_NAME} ${SDBUSPLUSPLUS_LIBRARIES} + phosphor_logging) + +install (TARGETS beepcode-mgr DESTINATION bin) diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/beepcode-mgr/files/beepcode-mgr.service b/meta-openbmc-mods/meta-common/recipes-phosphor/beepcode-mgr/files/beepcode-mgr.service new file mode 100644 index 000000000..8099e2541 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/beepcode-mgr/files/beepcode-mgr.service @@ -0,0 +1,12 @@ +[Unit] +Description=Beep code manager + +[Service] +Restart=always +RestartSec=2 +ExecStart=/usr/bin/beepcode-mgr +StartLimitInterval=0 +Type=simple + +[Install] +WantedBy=multi-user.target diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/beepcode-mgr/files/beepcode_mgr.cpp b/meta-openbmc-mods/meta-common/recipes-phosphor/beepcode-mgr/files/beepcode_mgr.cpp new file mode 100644 index 000000000..2940610da --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/beepcode-mgr/files/beepcode_mgr.cpp @@ -0,0 +1,325 @@ +/* Copyright 2019 Intel + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include <fcntl.h> +#include <linux/input.h> + +#include <boost/date_time/posix_time/posix_time.hpp> +#include <chrono> +#include <iostream> +#include <phosphor-logging/log.hpp> +#include <sdbusplus/asio/object_server.hpp> + +static constexpr uint32_t defaultBeepFrequence = 2000; +static constexpr uint32_t defaultBeepDurationMs = 300; +// Duration between two beeps +static constexpr uint32_t defaultInterBeepDurationMs = 300; +// Duration between two 4-bit digitals +static constexpr uint32_t defaultInterDigitBeepDurationMs = 800; +// Duration between two patterns +static constexpr uint32_t defaultPostBeepDurationMs = 1000; + +static constexpr uint8_t offBeepState = 0; +static constexpr uint8_t onBeepState = 1; +// finish 1 bit beep +static constexpr uint8_t interBeepState = 2; +// finish 4 bits beep +static constexpr uint8_t interDigitBeepState = 3; +// finish all bits beep +static constexpr uint8_t postBeepState = 4; + +static const std::vector<uint32_t> beepDelayTable = { + 0, defaultBeepDurationMs, defaultInterBeepDurationMs, + defaultInterDigitBeepDurationMs, defaultPostBeepDurationMs}; + +static constexpr uint32_t bpBitCount = 4; +static constexpr uint32_t bpShiftCount = 32; +static constexpr uint32_t bpMask = 0xf0000000; + +// beep code priority +static constexpr uint8_t beepOff = 0; +static constexpr uint8_t beepVRWatchdogTimeout = 1; +static constexpr uint8_t beepPSUFailure = 2; +static constexpr uint8_t beepCPUMIssing = 3; +static constexpr uint8_t beepCPUCatError = 4; +static constexpr uint8_t beepCPUErr2 = 5; +static constexpr uint8_t beepVoltageMismatch = 6; +static constexpr uint8_t beepCPUConfigError = 7; +static constexpr uint8_t beepPowerFail = 8; +static constexpr uint8_t beepPowerGoodTimeOut = 9; +static constexpr uint8_t beepMax = 10; + +// priority, abbrev name map +static const std::map<uint8_t, std::string> beepCodeNameList = { + {beepVRWatchdogTimeout, "VRWatchdogTimeout"}, + {beepPSUFailure, "PSUFailure"}, + {beepCPUMIssing, "CPUMissing"}, + {beepCPUCatError, "CPUCatError"}, + {beepCPUErr2, "CPUErr2"}, + {beepVoltageMismatch, "VoltageMismatch"}, + {beepCPUConfigError, "CPUConfigError"}, + {beepPowerFail, "PowerFail"}, + {beepPowerGoodTimeOut, "PowerGoodTimeOut"}, +}; + +// priority, code pattern map +static const std::map<uint8_t, std::string> beepCodePatternList = { + {beepVRWatchdogTimeout, "1-5-1-2"}, {beepPSUFailure, "1-5-1-4"}, + {beepCPUMIssing, "1-5-2-1"}, {beepCPUCatError, "1-5-2-2"}, + {beepCPUErr2, "1-5-2-3"}, {beepVoltageMismatch, "1-5-2-4"}, + {beepCPUConfigError, "1-5-2-5"}, {beepPowerFail, "1-5-4-2"}, + {beepPowerGoodTimeOut, "1-5-4-4"}, +}; + +static const std::vector<uint32_t> beepCodeTable = { + 0, 0x1512, 0x1514, 0x1521, 0x1522, 0x1523, 0x1524, 0x1525, 0x1542, 0x1544}; + +static constexpr char bpDevName[] = "/dev/input/event0"; +static constexpr char bpBusName[] = "xyz.openbmc_project.BeepCode"; +static constexpr char bpObjName[] = "/xyz/openbmc_project/BeepCode"; +static constexpr char bpIntfName[] = "xyz.openbmc_project.BeepCode"; +static constexpr char bpMethodName[] = "Beep"; + +static std::shared_ptr<sdbusplus::asio::dbus_interface> bpIface; +static boost::asio::io_service io; +static auto conn = std::make_shared<sdbusplus::asio::connection>(io); + +class Beeper +{ + public: + Beeper(boost::asio::io_service& io) + { + timer = std::make_unique<boost::asio::steady_timer>(io); + fdBeepDev = -1; + currentCount = 0; + currentBeepCode = 0; + currentMask = bpMask; + currentShift = bpShiftCount; + currentState = offBeepState; + timerRunning = false; + } + + ~Beeper() + { + } + + void beep(const uint8_t& beepPriority) + { + if (timerRunning) + { + pendingList.push_back(beepPriority); + pendingList.sort(std::greater<uint8_t>()); + return; + } + + performBeep(beepPriority); + } + + private: + void performBeep(const uint8_t& beepPriority) + { + currentBeepCode = beepCodeTable[beepPriority]; + currentCount = 0; + currentMask = bpMask; + currentShift = bpShiftCount; + getCurrentCount(); + startBeep(defaultBeepFrequence); + currentState = onBeepState; + currentCount--; + timerRunning = true; + startBeepTimer(); + } + + void startBeepTimer() + { + timer->expires_after( + std::chrono::milliseconds(beepDelayTable[currentState])); + timer->async_wait([this](const boost::system::error_code& ec) { + // timer timeout + switch (currentState) + { + case onBeepState: + stopBeep(); + if (currentCount == 0) + { + // finished the current 4-bit + if (currentBeepCode == 0) + { + // finished all bits + currentState = postBeepState; + } + else + { + // start next 4-bit + currentState = interDigitBeepState; + getCurrentCount(); + currentCount--; + } + } + else + { + // still in 4-bit processing + currentCount--; + currentState = interBeepState; + } + startBeepTimer(); + break; + + case interBeepState: + case interDigitBeepState: + startBeep(defaultBeepFrequence); + currentState = onBeepState; + startBeepTimer(); + break; + case postBeepState: + if (pendingList.size() != 0) + { + // continue the next new beepcode + uint8_t beepPriority = pendingList.front(); + pendingList.pop_front(); + performBeep(beepPriority); + } + else + { + timerRunning = false; + } + break; + + default: + std::cerr << "Incorrect beepState: " + << static_cast<unsigned int>(currentState) + << std::endl; + break; + } + }); + } + + void startBeep(uint32_t freq) + { + if (fdBeepDev != -1) + { + std::cerr << "beep device is opening already!" << std::endl; + ::close(fdBeepDev); + fdBeepDev = -1; + } + + if ((fdBeepDev = ::open(bpDevName, O_RDWR | O_CLOEXEC)) < 0) + { + phosphor::logging::log<phosphor::logging::level::ERR>( + "Failed to open input device"); + return; + } + + struct input_event event; + event.type = EV_SND; + event.code = SND_TONE; + event.value = freq; + + if (::write(fdBeepDev, &event, sizeof(struct input_event)) != + sizeof(struct input_event)) + { + phosphor::logging::log<phosphor::logging::level::ERR>( + "Failed to write a tone sound event"); + ::close(fdBeepDev); + fdBeepDev = -1; + return; + } + return; + } + + void stopBeep() + { + if (fdBeepDev == -1) + { + std::cerr << "beep device is closed!" << std::endl; + return; + } + + ::close(fdBeepDev); + fdBeepDev = -1; + } + + // Split the beep code based on bpBitCount, for example 0x1544, + // currentCount=1, 5, 4, 4 + void getCurrentCount() + { + while (currentCount == 0) + { + currentCount = currentMask & currentBeepCode; + currentShift -= bpBitCount; + currentCount >>= currentShift; + currentBeepCode = currentBeepCode & ~currentMask; + currentMask >>= bpBitCount; + if (currentMask == 0) + { + break; + } + } + } + + int fdBeepDev; + bool timerRunning; + uint32_t currentCount; + uint32_t currentBeepCode; + uint32_t currentMask; + uint32_t currentShift; + uint8_t currentState; + std::unique_ptr<boost::asio::steady_timer> timer; + std::list<uint8_t> pendingList; +}; + +static Beeper beeper(io); + +// dbus method +static void beep(const uint8_t& beepPriority) +{ + if ((beepPriority >= beepMax) || (beepPriority == beepOff)) + { + std::cerr << "Incorrect input: " + << static_cast<unsigned int>(beepPriority) << std::endl; + return; + } + + // Log into redfish event log + sd_journal_send("MESSAGE=BeepCode: Priority=%d", beepPriority, + "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s", + "OpenBMC.0.1.BeepCode", "REDFISH_MESSAGE_ARGS=%d", + beepPriority, NULL); + + beeper.beep(beepPriority); + + return; +} + +int main(int argc, char** argv) +{ + phosphor::logging::log<phosphor::logging::level::INFO>( + "Starting BeepCode service"); + + conn->request_name(bpBusName); + sdbusplus::asio::object_server server = + sdbusplus::asio::object_server(conn); + bpIface = server.add_interface(bpObjName, bpIntfName); + + bpIface->register_property("BeepCodeNameList", beepCodeNameList, + sdbusplus::asio::PropertyPermission::readOnly); + bpIface->register_property("BeepCodePatternList", beepCodePatternList, + sdbusplus::asio::PropertyPermission::readOnly); + bpIface->register_method(bpMethodName, beep); + bpIface->initialize(); + + io.run(); + return 0; +} diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/beepcode-mgr/files/cmake-format.json b/meta-openbmc-mods/meta-common/recipes-phosphor/beepcode-mgr/files/cmake-format.json new file mode 100644 index 000000000..583c255a3 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/beepcode-mgr/files/cmake-format.json @@ -0,0 +1,12 @@ +{ + "enum_char": ".", + "line_ending": "unix", + "bullet_char": "*", + "max_subargs_per_line": 99, + "command_case": "lower", + "tab_size": 4, + "line_width": 80, + "separate_fn_name_with_space": true, + "dangle_parens": true, + "separate_ctrl_name_with_space": true +}
\ No newline at end of file diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/configuration/entity-manager_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/configuration/entity-manager_%.bbappend index d4b50df88..080ae9f58 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/configuration/entity-manager_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/configuration/entity-manager_%.bbappend @@ -1,6 +1,6 @@ # this is here just to bump faster than upstream SRC_URI = "git://github.com/openbmc/entity-manager.git" -SRCREV = "441c7a86749b2331863b115e141033e735bd6ffc" +SRCREV = "fff050a355041d2848b8a126a19a6cb81daebe6b" FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0002-Modify-Dbus-for-IPv6.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0002-Modify-Dbus-for-IPv6.patch deleted file mode 100644 index fc09da3bd..000000000 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces/0002-Modify-Dbus-for-IPv6.patch +++ /dev/null @@ -1,59 +0,0 @@ -From 62240a7ef12bb2ed3730a625ad7a809a9a6d0512 Mon Sep 17 00:00:00 2001 -From: David Cobbley <david.j.cobbley@linux.intel.com> -Date: Wed, 6 Jun 2018 10:11:58 -0700 -Subject: [PATCH 1/1] Modify Dbus for IPv6. - -Add additional interfaces for IPv6 use. - -Signed-off-by: James Feist <james.feist@linux.intel.com> ---- - .../Network/EthernetInterface.interface.yaml | 13 ++++++++++++- - xyz/openbmc_project/Network/IP.interface.yaml | 4 ++++ - 2 files changed, 16 insertions(+), 1 deletion(-) - -diff --git a/xyz/openbmc_project/Network/EthernetInterface.interface.yaml b/xyz/openbmc_project/Network/EthernetInterface.interface.yaml -index 6fa1d0b..6b7cd9a 100644 ---- a/xyz/openbmc_project/Network/EthernetInterface.interface.yaml -+++ b/xyz/openbmc_project/Network/EthernetInterface.interface.yaml -@@ -46,6 +46,10 @@ properties: - type: boolean - description: > - Boolean for accepting router advertisements in IPv6 -+ - name: IPAddressEnables -+ type: enum[self.IPAllowed] -+ description: > -+ The type of IP connection is allowed on this channel - - enumerations: - - name: LinkLocalConf -@@ -56,4 +60,11 @@ enumerations: - - name: v4 - - name: v6 - - name: none -- -+ - name: IPAllowed -+ description: > -+ Determines whether the system allows both IPv6 & IPv4, or disables on -+ or the other -+ values: -+ - name: IPv4AndIPv6 -+ - name: IPv4Only -+ - name: IPv6Only -diff --git a/xyz/openbmc_project/Network/IP.interface.yaml b/xyz/openbmc_project/Network/IP.interface.yaml -index 5091ac9..b2442a5 100644 ---- a/xyz/openbmc_project/Network/IP.interface.yaml -+++ b/xyz/openbmc_project/Network/IP.interface.yaml -@@ -34,6 +34,10 @@ properties: - errors: - - xyz::openbmc_project.Common.Error.NotAllowed - -+ - name: BackupGateway -+ type: string -+ description: > -+ This is the IP address of the backup gateway. - - name: Type - type: enum[self.Protocol] - description: > --- -2.17.1 - diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces_%.bbappend index 40b00e70f..79a67ee79 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/dbus/phosphor-dbus-interfaces_%.bbappend @@ -3,8 +3,7 @@ SRCREV = "ddc9e9f9d6ed0282ec6c1421a706b45f3c09ebcc" FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" -SRC_URI += "file://0002-Modify-Dbus-for-IPv6.patch \ - file://0005-Add-DBUS-interface-of-CPU-and-Memory-s-properties.patch \ +SRC_URI += "file://0005-Add-DBUS-interface-of-CPU-and-Memory-s-properties.patch \ file://0007-ipmi-set-BIOS-id.patch \ file://0010-Increase-the-default-watchdog-timeout-value.patch \ file://0012-Add-RestoreDelay-interface-for-power-restore-delay.patch \ diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend index 8d13272bb..53cd944c6 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/interfaces/bmcweb_%.bbappend @@ -1,5 +1,5 @@ SRC_URI = "git://github.com/openbmc/bmcweb.git" -SRCREV = "2c0feb0085ac3cc11c6fd77df7a8c7701f38fea5" +SRCREV = "b76f9ca126d5c1abcd8b833a511d784531dbb3a1" FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0066-Valid-VLANID-should-be-1-4095-as-in-802.1VLAN-spec.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0066-Valid-VLANID-should-be-1-4095-as-in-802.1VLAN-spec.patch new file mode 100644 index 000000000..f8f71338a --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host/0066-Valid-VLANID-should-be-1-4095-as-in-802.1VLAN-spec.patch @@ -0,0 +1,44 @@ +From 07caf4cc516601c93d12bbe89b4afb0284201dff Mon Sep 17 00:00:00 2001 +From: Suryakanth Sekar <suryakanth.sekar@linux.intel.com> +Date: Fri, 2 Aug 2019 14:18:31 +0530 +Subject: [PATCH] Valid VLANID should be 1-4095 as in 802.1VLAN spec + +Added the VLAN ID checking condition in Set LAN configuration + +Unit test: +Verified VLAN ID 1-4095 is allowed and CC returns for 0 & > 4095 + +Change-Id: I1737986ed7adb727758dedb84b851ba2c208cea3 +Signed-off-by: Suryakanth Sekar <suryakanth.sekar@linux.intel.com> +--- + transporthandler.cpp | 4 ++++ + transporthandler.hpp | 1 + + 2 files changed, 5 insertions(+) + +diff --git a/transporthandler.cpp b/transporthandler.cpp +index 44ddcef..ede6472 100644 +--- a/transporthandler.cpp ++++ b/transporthandler.cpp +@@ -536,6 +536,10 @@ ipmi_ret_t ipmi_transport_set_lan(ipmi_netfn_t netfn, ipmi_cmd_t cmd, + // We assume that ipmitool always send enable + // bit as 1. + vlan = le16toh(vlan); ++ if (vlan == 0 || vlan > maxValidVLANIDValue) ++ { ++ return IPMI_CC_INVALID_FIELD_REQUEST; ++ } + channelConf->vlanID = vlan; + } + break; +diff --git a/transporthandler.hpp b/transporthandler.hpp +index 1237658..d8805e1 100644 +--- a/transporthandler.hpp ++++ b/transporthandler.hpp +@@ -219,3 +219,4 @@ enum class Privilege : uint8_t + + constexpr uint8_t progressMask = 0x03; + constexpr uint8_t enableMask = 0x01; ++constexpr uint16_t maxValidVLANIDValue = 4095; +-- +2.7.4 + diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host_%.bbappend index d8f9203c9..16bd9f757 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-host_%.bbappend @@ -3,7 +3,7 @@ FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" # TODO: This should be removed, once up-stream bump up # issue is resolved #SRC_URI = "git://github.com/openbmc/phosphor-host-ipmid" -SRCREV = "894d022017215acceafc9e3f21379534f5396d21" +SRCREV = "9da3a75091e0bf0849e2555447e64a70f1dc3bfb" SRC_URI += "file://phosphor-ipmi-host.service \ file://host-ipmid-whitelist.conf \ @@ -21,6 +21,7 @@ SRC_URI += "file://phosphor-ipmi-host.service \ file://0063-Save-the-pre-timeout-interrupt-in-dbus-property.patch \ file://0064-Enable-watchdog-to-save-useflag-after-host-power-off.patch \ file://0064-Update-provisioning-mode-filter-logic.patch \ + file://0066-Valid-VLANID-should-be-1-4095-as-in-802.1VLAN-spec.patch \ " # remove the softpoweroff service since we do not need it diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net_%.bbappend index 05f10d980..24037a4cb 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/ipmi/phosphor-ipmi-net_%.bbappend @@ -3,7 +3,7 @@ inherit useradd # TODO: This should be removed, once up-stream bump up # issue is resolved SRC_URI += "git://github.com/openbmc/phosphor-net-ipmid" -SRCREV = "0a269046d0d9fcd690ccbb129ae58a3c1450b04e" +SRCREV = "35ca150beb7d5faf2fe0ca44c87bc7b0ade0aee7" USERADD_PACKAGES = "${PN}" # add a group called ipmi diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/logging/phosphor-logging_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/logging/phosphor-logging_%.bbappend deleted file mode 100644 index b1f4c1ce5..000000000 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/logging/phosphor-logging_%.bbappend +++ /dev/null @@ -1,2 +0,0 @@ -SRCREV = "30047bf9647215951ba5dfe21ceb3e58a1b405a4" - diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/phosphor-u-boot-mgr/phosphor-u-boot-mgr_git.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/phosphor-u-boot-mgr/phosphor-u-boot-mgr_git.bb index c35289a57..d20da7b35 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/phosphor-u-boot-mgr/phosphor-u-boot-mgr_git.bb +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/phosphor-u-boot-mgr/phosphor-u-boot-mgr_git.bb @@ -10,7 +10,7 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e" SRC_URI = "git://git@github.com/Intel-BMC/provingground.git;protocol=ssh" -SRCREV = "4611d8dcba0c0dc92156bbafdb50607aaff122ab" +SRCREV = "226ca2842e0a14ad56b4ebeedfd82ac2ea7e145e" inherit cmake systemd SYSTEMD_SERVICE_${PN} = "xyz.openbmc_project.U_Boot.Environment.Manager.service" diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/prov-mode-mgr/prov-mode-mgr_git.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/prov-mode-mgr/prov-mode-mgr_git.bb index a37d3ec9c..53f42dbdf 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/prov-mode-mgr/prov-mode-mgr_git.bb +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/prov-mode-mgr/prov-mode-mgr_git.bb @@ -10,7 +10,7 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e" SRC_URI = "git://git@github.com/Intel-BMC/provingground.git;protocol=ssh" -SRCREV = "4611d8dcba0c0dc92156bbafdb50607aaff122ab" +SRCREV = "226ca2842e0a14ad56b4ebeedfd82ac2ea7e145e" inherit cmake systemd SYSTEMD_SERVICE_${PN} = "xyz.openbmc_project.RestrictionMode.Manager.service" diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0001-Add-WA-enable-disable-control-code-into-cpusensor.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0001-Add-WA-enable-disable-control-code-into-cpusensor.patch new file mode 100644 index 000000000..1e1fc9625 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors/0001-Add-WA-enable-disable-control-code-into-cpusensor.patch @@ -0,0 +1,50 @@ +From f9b4545af42fc673f81d043a8512db8ebfe58660 Mon Sep 17 00:00:00 2001 +From: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com> +Date: Fri, 2 Aug 2019 12:02:58 -0700 +Subject: [PATCH] Add WA enable/disable control code into cpusensor + +This commit adds a PECI WA enable/disable control code. If 'UseWA' +isn't in CPU configuration or the setting is 0, the WA will be +disabled by writing 'N' on the peci_core module parameter. + +This is a temporary WA. + +Change-Id: I73ae9ac49c9382f3ebdc800c360e078418b124e9 +Signed-off-by: Jae Hyun Yoo <jae.hyun.yoo@linux.intel.com> +--- + src/CPUSensorMain.cpp | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +diff --git a/src/CPUSensorMain.cpp b/src/CPUSensorMain.cpp +index 2a3ff16f8294..b4085fd1038d 100644 +--- a/src/CPUSensorMain.cpp ++++ b/src/CPUSensorMain.cpp +@@ -629,6 +629,25 @@ bool getCpuConfig( + std::cout << "type: " << type << "\n"; + } + ++ // Temporary WA ++ uint64_t useWA = 0; ++ auto findUseWA = config.second.find("UseWA"); ++ if (findUseWA != config.second.end()) ++ { ++ useWA = std::visit(VariantToUnsignedIntVisitor(), ++ findUseWA->second); ++ } ++ if (useWA == 0) ++ { ++ std::ofstream deviceFile( ++ "/sys/module/peci_core/parameters/use_wa"); ++ if (deviceFile.good()) ++ { ++ deviceFile << 'N'; ++ } ++ deviceFile.close(); ++ } ++ + cpuConfigs.emplace(bus, addr, name, State::OFF); + } + } +-- +2.7.4 + diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors_%.bbappend index 3e3282f6f..082c87055 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/sensors/dbus-sensors_%.bbappend @@ -1,7 +1,10 @@ -SRCREV = "1cbd1c6da17a85ec7213744cf2d1e56fcba3e34e" +SRCREV = "7fa475d3f27ec6c37503ff7ec0496acc2215da29" SRC_URI = "git://github.com/openbmc/dbus-sensors.git" DEPENDS_append = " libgpiod" +FILESEXTRAPATHS_append := ":${THISDIR}/${PN}" +SRC_URI += "file://0001-Add-WA-enable-disable-control-code-into-cpusensor.patch" + #todo(cheng) remove this when synced upstream SYSTEMD_SERVICE_${PN} += " xyz.openbmc_project.mcutempsensor.service" diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/settings/settings_git.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/settings/settings_git.bb index 50f644f37..1a34e2478 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/settings/settings_git.bb +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/settings/settings_git.bb @@ -1,7 +1,7 @@ SUMMARY = "Settings" SRC_URI = "git://git@github.com/Intel-BMC/provingground.git;protocol=ssh" -SRCREV = "4611d8dcba0c0dc92156bbafdb50607aaff122ab" +SRCREV = "226ca2842e0a14ad56b4ebeedfd82ac2ea7e145e" PV = "0.1+git${SRCPV}" LICENSE = "Apache-2.0" diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/special-mode-mgr/special-mode-mgr_git.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/special-mode-mgr/special-mode-mgr_git.bb index 736277dce..d6d9d2d20 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/special-mode-mgr/special-mode-mgr_git.bb +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/special-mode-mgr/special-mode-mgr_git.bb @@ -9,7 +9,7 @@ LICENSE = "Apache-2.0" LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e" SRC_URI = "git://git@github.com/Intel-BMC/provingground.git;protocol=ssh" -SRCREV = "4611d8dcba0c0dc92156bbafdb50607aaff122ab" +SRCREV = "226ca2842e0a14ad56b4ebeedfd82ac2ea7e145e" inherit cmake systemd SYSTEMD_SERVICE_${PN} = "specialmodemgr.service" diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/srvcfg-manager/srvcfg-manager_git.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/srvcfg-manager/srvcfg-manager_git.bb index 30d92ea38..12fd75226 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/srvcfg-manager/srvcfg-manager_git.bb +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/srvcfg-manager/srvcfg-manager_git.bb @@ -9,7 +9,7 @@ LICENSE = "Apache-2.0" LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e" SRC_URI = "git://git@github.com/Intel-BMC/provingground.git;protocol=ssh" -SRCREV = "4611d8dcba0c0dc92156bbafdb50607aaff122ab" +SRCREV = "226ca2842e0a14ad56b4ebeedfd82ac2ea7e145e" inherit cmake systemd SYSTEMD_SERVICE_${PN} = "srvcfg-manager.service" diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/system/callback-manager.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/system/callback-manager.bb index e863b14e7..921352a5b 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/system/callback-manager.bb +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/system/callback-manager.bb @@ -7,7 +7,7 @@ inherit cmake systemd DEPENDS = "boost sdbusplus" PV = "0.1+git${SRCPV}" -SRCREV = "4611d8dcba0c0dc92156bbafdb50607aaff122ab" +SRCREV = "226ca2842e0a14ad56b4ebeedfd82ac2ea7e145e" S = "${WORKDIR}/git/callback-manager" diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0003-Set-PreTimeoutInterruptOccurFlag-in-DBUS.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0003-Set-PreTimeoutInterruptOccurFlag-in-DBUS.patch new file mode 100644 index 000000000..60b605418 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0003-Set-PreTimeoutInterruptOccurFlag-in-DBUS.patch @@ -0,0 +1,45 @@ +From 41f71ecfa2b8339281a33c260d78102453d4ac97 Mon Sep 17 00:00:00 2001 +From: Ren Yu <yux.ren@intel.com> +Date: Tue, 30 Jul 2019 15:31:09 +0800 +Subject: [PATCH] Set PreTimeoutInterruptOccurFlag in DBUS + +Set preTimeoutInterruptOccurFlag in DBUS as 'true' when +watchdog pre-timeout interrupt occurred. +This property is use for recording PreTimeoutInterruptOccurFlag. +In command get message flag, need verify whether pre-timeout +interrupt occurred by it. + +Tested: +Set watchdog timer +(Pre-timeout interrupt is Messaging, Initial Countdown is 2 second). +ipmitool raw 0x06 0x24 0x5 0x30 0x1 0x3e 0x14 0x00 +Start watchdog timer. +ipmitool mc watchdog reset +Wait watchdog timer expired, log into below: +http://BMC-IP:3000/ +xyz.openbmc_project.Watchdog +/xyz/openbmc_project/watchdog/host0 +xyz.openbmc_project.State.Watchdog +check whether the value of PreTimeoutInterruptOccurFlag is true. + +Signed-off-by: Ren Yu <yux.ren@intel.com> +--- + watchdog.cpp | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/watchdog.cpp b/watchdog.cpp +index fa58ef4..bdf65da 100644 +--- a/watchdog.cpp ++++ b/watchdog.cpp +@@ -198,6 +198,8 @@ void Watchdog::timeOutHandler() + + if (preInterruptNoAction != convertForMessage(preTimeoutInterruptAction)) + { ++ preTimeoutInterruptOccurFlag(true); ++ + sd_journal_send("MESSAGE=IPMIWatchdog: Pre Timed out Interrupt=%s", + convertForMessage(preTimeoutInterruptAction).c_str(), + "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s", +-- +2.7.4 + diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0004-Standardize-watchdog-redfish-format-according-to-EPS.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0004-Standardize-watchdog-redfish-format-according-to-EPS.patch new file mode 100644 index 000000000..578fa1257 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog/0004-Standardize-watchdog-redfish-format-according-to-EPS.patch @@ -0,0 +1,211 @@ +From 3bead6316f653f14773e65b2f6b8facb08f200e7 Mon Sep 17 00:00:00 2001 +From: Ren Yu <yux.ren@intel.com> +Date: Fri, 9 Aug 2019 14:54:13 +0800 +Subject: [PATCH] Standardize watchdog redfish format according to EPS + +According to EPS and test requirement, change the messageArgs +in redfish about watchdog action and pre-interrupt action and +add timer user display. + +Tested: +Set a watchdog (Timer action and pre-interrupt action both are none). + ipmitool raw 0x06 0x24 0x05 0x00 0x00 0x00 0x30 0x00 +Get the watchdog. + ipmitool mc watchdog get +Start the watchdog. + ipmitool mc watchdog reset +When timer expired, check messageArgs in Redfish with below url: +https://IP/redfish/v1/Systems/system/LogServices/EventLog/Entries. + + "Message": "Host Watchdog Event: Power Cycle - System power cycle due to Watchdog timeout. timer use: SMS/OS", + "MessageArgs": [ + "Power Cycle - System power cycle due to Watchdog timeout. timer use: SMS/OS" + ], + + "Message": "Host Watchdog Event: Timer interrupt - Messaging Interrupt due to Watchdog timeout. timer use: OEM", + "MessageArgs": [ + "Timer interrupt - Messaging Interrupt due to Watchdog timeout. timer use: OEM" + ], + +Signed-off-by: Ren Yu <yux.ren@intel.com> +--- + watchdog.cpp | 127 +++++++++++++++++++++++++++++++++++++++++------------------ + 1 file changed, 89 insertions(+), 38 deletions(-) + +diff --git a/watchdog.cpp b/watchdog.cpp +index bdf65da..7cfcc75 100644 +--- a/watchdog.cpp ++++ b/watchdog.cpp +@@ -25,25 +25,28 @@ const static constexpr char* currentPowerState = "CurrentPowerState"; + const static constexpr char* powerStatusOff = + "xyz.openbmc_project.State.Chassis.PowerState.Off"; + +-const static constexpr char* powerActionHardReset = +- "xyz.openbmc_project.State.Watchdog.Action.HardReset"; +-const static constexpr char* powerActionOff = +- "xyz.openbmc_project.State.Watchdog.Action.PowerOff"; +-const static constexpr char* powerActionPowerCycle = +- "xyz.openbmc_project.State.Watchdog.Action.PowerCycle"; +-const static constexpr char* powerActionNone = +- "xyz.openbmc_project.State.Watchdog.Action.None"; +-const static constexpr char* preInterruptNoAction = +- "xyz.openbmc_project.State.Watchdog.PreTimeoutInterruptAction.None"; +- +-const static constexpr char* hardResteDescription = +- "Hard Reset - System reset due to Watchdog timeout"; ++const static constexpr char* actionDescription = " due to Watchdog timeout"; ++const static constexpr char* hardResetDescription = "Hard Reset - System reset"; + const static constexpr char* powerOffDescription = +- "Power Down - System power down due to Watchdog timeout"; ++ "Power Down - System power down"; + const static constexpr char* powerCycleDescription = +- "Power Cycle - System power cycle due to Watchdog timeout"; ++ "Power Cycle - System power cycle"; + const static constexpr char* timerExpiredDescription = "Timer expired"; +-const static constexpr char* preInterruptDescription = "Timer interrupt"; ++ ++const static constexpr char* preInterruptActionNone = ++ "xyz.openbmc_project.State.Watchdog.PreTimeoutInterruptAction.None"; ++ ++const static constexpr char* preInterruptDescriptionSMI = "SMI"; ++const static constexpr char* preInterruptDescriptionNMI = "NMI"; ++const static constexpr char* preInterruptDescriptionMI = "Messaging Interrupt"; ++ ++const static constexpr char* reservedDescription = "Reserved"; ++ ++const static constexpr char* timerUseDescriptionBIOSFRB2 = "BIOS FRB2"; ++const static constexpr char* timerUseDescriptionBIOSPOST = "BIOS/POST"; ++const static constexpr char* timerUseDescriptionOSLoad = "OSLoad"; ++const static constexpr char* timerUseDescriptionSMSOS = "SMS/OS"; ++const static constexpr char* timerUseDescriptionOEM = "OEM"; + + namespace restart + { +@@ -161,54 +164,102 @@ uint64_t Watchdog::interval(uint64_t value) + void Watchdog::timeOutHandler() + { + PreTimeoutInterruptAction preTimeoutInterruptAction = preTimeoutInterrupt(); ++ std::string preInterruptActionMessageArgs{}; ++ + Action action = expireAction(); + std::string actionMessageArgs{}; + ++ expiredTimerUse(currentTimerUse()); ++ ++ TimerUse timeUser = expiredTimerUse(); ++ std::string timeUserMessage{}; ++ + if (!this->enabled()) + { + action = fallback->action; + } + +- if (convertForMessage(action) == powerActionHardReset) +- { +- actionMessageArgs = hardResteDescription; +- } +- else if (convertForMessage(action) == powerActionOff) +- { +- actionMessageArgs = powerOffDescription; +- } +- else if (convertForMessage(action) == powerActionPowerCycle) ++ switch (timeUser) + { +- actionMessageArgs = powerCycleDescription; ++ case Watchdog::TimerUse::BIOSFRB2: ++ timeUserMessage = timerUseDescriptionBIOSFRB2; ++ break; ++ case Watchdog::TimerUse::BIOSPOST: ++ timeUserMessage = timerUseDescriptionBIOSPOST; ++ break; ++ case Watchdog::TimerUse::OSLoad: ++ timeUserMessage = timerUseDescriptionOSLoad; ++ break; ++ case Watchdog::TimerUse::SMSOS: ++ timeUserMessage = timerUseDescriptionSMSOS; ++ break; ++ case Watchdog::TimerUse::OEM: ++ timeUserMessage = timerUseDescriptionOEM; ++ break; ++ default: ++ timeUserMessage = reservedDescription; ++ break; + } +- else if (convertForMessage(action) == powerActionNone) +- { +- actionMessageArgs = timerExpiredDescription; +- } +- else ++ ++ switch (action) + { +- actionMessageArgs = "Reserved"; ++ case Watchdog::Action::HardReset: ++ actionMessageArgs = std::string(hardResetDescription) + ++ std::string(actionDescription); ++ break; ++ case Watchdog::Action::PowerOff: ++ actionMessageArgs = std::string(powerOffDescription) + ++ std::string(actionDescription); ++ break; ++ case Watchdog::Action::PowerCycle: ++ actionMessageArgs = std::string(powerCycleDescription) + ++ std::string(actionDescription); ++ break; ++ case Watchdog::Action::None: ++ actionMessageArgs = timerExpiredDescription; ++ break; ++ default: ++ actionMessageArgs = reservedDescription; ++ break; + } + + // Log into redfish event log + sd_journal_send("MESSAGE=IPMIWatchdog: Timed out ACTION=%s", + convertForMessage(action).c_str(), "PRIORITY=%i", LOG_INFO, + "REDFISH_MESSAGE_ID=%s", "OpenBMC.0.1.IPMIWatchdog", +- "REDFISH_MESSAGE_ARGS=%s", actionMessageArgs.c_str(), NULL); ++ "REDFISH_MESSAGE_ARGS=%s. timer use: %s", ++ actionMessageArgs.c_str(), timeUserMessage.c_str(), NULL); ++ ++ switch (preTimeoutInterruptAction) ++ { ++ case Watchdog::PreTimeoutInterruptAction::SMI: ++ preInterruptActionMessageArgs = preInterruptDescriptionSMI; ++ break; ++ case Watchdog::PreTimeoutInterruptAction::NMI: ++ preInterruptActionMessageArgs = preInterruptDescriptionNMI; ++ break; ++ case Watchdog::PreTimeoutInterruptAction::MI: ++ preInterruptActionMessageArgs = preInterruptDescriptionMI; ++ break; ++ default: ++ preInterruptActionMessageArgs = reservedDescription; ++ break; ++ } + +- if (preInterruptNoAction != convertForMessage(preTimeoutInterruptAction)) ++ if (preInterruptActionNone != convertForMessage(preTimeoutInterruptAction)) + { + preTimeoutInterruptOccurFlag(true); + + sd_journal_send("MESSAGE=IPMIWatchdog: Pre Timed out Interrupt=%s", + convertForMessage(preTimeoutInterruptAction).c_str(), + "PRIORITY=%i", LOG_INFO, "REDFISH_MESSAGE_ID=%s", +- "OpenBMC.0.1.IPMIWatchdog", "REDFISH_MESSAGE_ARGS=%s", +- preInterruptDescription, NULL); ++ "OpenBMC.0.1.IPMIWatchdog", ++ "REDFISH_MESSAGE_ARGS=Timer interrupt - %s due to " ++ "Watchdog timeout. timer use: %s", ++ preInterruptActionMessageArgs.c_str(), ++ timeUserMessage.c_str(), NULL); + } + +- expiredTimerUse(currentTimerUse()); +- + auto target = actionTargetMap.find(action); + if (target == actionTargetMap.end()) + { +-- +2.7.4 + diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog_%.bbappend index caaca2670..0e221a6b5 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/phosphor-watchdog_%.bbappend @@ -3,6 +3,8 @@ FILESEXTRAPATHS_append := ":${THISDIR}/${PN}" SRCREV = "c35135d32f9cb84b62de7b72eee3a2e87b4b3d4d" SRC_URI += "file://0001-Move-Phosphor-Watchdog-to-Not-Use-Service-Files.patch \ file://0002-Stop-the-watchdog-when-the-host-is-going-to-off.patch \ + file://0003-Set-PreTimeoutInterruptOccurFlag-in-DBUS.patch \ + file://0004-Standardize-watchdog-redfish-format-according-to-EPS.patch \ " # Remove the override to keep service running after DC cycle diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog.bb b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog.bb index 5da053f1d..2ed120659 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog.bb +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog.bb @@ -11,3 +11,6 @@ LIC_FILES_CHKSUM = "file://${INTELBASE}/COPYING.apache-2.0;md5=34400b68072d710fe SYSTEMD_SERVICE_${PN} += "system-watchdog.service" SYSTEMD_ENVIRONMENT_FILE_${PN} += "obmc/system-watchdog/system-watchdog.conf" +SYSTEMD_SERVICE_${PN} += "watchdog-reset.service" +SYSTEMD_SERVICE_${PN} += "watchdog-clear-failures.service" +SYSTEMD_SERVICE_${PN} += "watchdog-clear-failures.timer" diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-clear-failures.service b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-clear-failures.service new file mode 100644 index 000000000..801f4ed27 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-clear-failures.service @@ -0,0 +1,10 @@ +[Unit] +Description=Reset BMC Hardware Watchdog Failure Count + +[Service] +ExecStart=busctl call xyz.openbmc_project.U_Boot.Environment.Manager \ + /xyz/openbmc_project/u_boot/environment/mgr \ + xyz.openbmc_project.U_Boot.Environment.Manager \ + Write ss bootfailures 0 +Type=oneshot + diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-clear-failures.timer b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-clear-failures.timer new file mode 100644 index 000000000..1abac4326 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-clear-failures.timer @@ -0,0 +1,8 @@ +[Unit] +Description=Starts the clear watchdog serivce after 30 minutes + +[Timer] +OnBootSec=30min + +[Install] +WantedBy=timers.target diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-reset.service b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-reset.service new file mode 100644 index 000000000..6f33b36d7 --- /dev/null +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/watchdog/system-watchdog/watchdog-reset.service @@ -0,0 +1,8 @@ +[Unit] +Description=Reset BMC Using Hardware Watchdog +Conflicts=system-watchdog.service + +[Service] +ExecStart=/sbin/watchdog -T 0 -F /dev/watchdog1 +Type=oneshot + diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/webui/phosphor-webui/0004-Implement-force-boot-to-bios-in-server-power-control.patch b/meta-openbmc-mods/meta-common/recipes-phosphor/webui/phosphor-webui/0004-Implement-force-boot-to-bios-in-server-power-control.patch index 0e2d400a3..3885318de 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/webui/phosphor-webui/0004-Implement-force-boot-to-bios-in-server-power-control.patch +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/webui/phosphor-webui/0004-Implement-force-boot-to-bios-in-server-power-control.patch @@ -1,105 +1,70 @@ -From a4f948f98e9bfd8b019699b4e23281448f7b7313 Mon Sep 17 00:00:00 2001 +From 5a6e97bdca6db517eabb94a926623e2f662b1315 Mon Sep 17 00:00:00 2001 From: Kuiying Wang <kuiying.wang@intel.com> -Date: Wed, 27 Mar 2019 19:35:12 +0800 -Subject: [PATCH] Implement force to BIOS +Date: Thu, 1 Aug 2019 17:37:17 +0800 +Subject: [PATCH] force to bios fix bump fail -UI page review use below link: -https://projects.invisionapp.com/share/UER87D98GPM#/screens - -Tested: - Switch on "Boot To BIOS", could enter BIOS setup page directly - when power on system. - -Change-Id: Ib46dc5d84df51d31cc5ff8635fa0c0f52de0e194 Signed-off-by: Kuiying Wang <kuiying.wang@intel.com> --- - app/common/services/api-utils.js | 49 +++++++++++++++++++ - app/common/services/constants.js | 4 ++ - app/common/services/dataService.js | 1 + - .../power-operations-controller.html | 12 +++++ - .../power-operations-controller.js | 32 ++++++++++++ - 5 files changed, 98 insertions(+) + app/common/services/api-utils.js | 30 ++++++++++++++++++ + app/common/services/constants.js | 4 +++ + app/common/services/dataService.js | 1 + + .../controllers/power-operations-controller.html | 11 +++++++ + .../controllers/power-operations-controller.js | 36 ++++++++++++++++++++-- + 5 files changed, 80 insertions(+), 2 deletions(-) diff --git a/app/common/services/api-utils.js b/app/common/services/api-utils.js -index 840db8e..193c172 100644 +index d485016..3d64406 100644 --- a/app/common/services/api-utils.js +++ b/app/common/services/api-utils.js -@@ -31,6 +31,7 @@ window.angular && (function(angular) { - HOST_STATE: Constants.HOST_STATE, +@@ -29,12 +29,42 @@ window.angular && (function(angular) { + HOST_STATE_TEXT: Constants.HOST_STATE, LED_STATE: Constants.LED_STATE, LED_STATE_TEXT: Constants.LED_STATE_TEXT, + FORCE_TO_BIOS_STATE_TEXT: Constants.FORCE_TO_BIOS_STATE_TEXT, HOST_SESSION_STORAGE_KEY: Constants.API_CREDENTIALS.host_storage_key, - getChassisState: function() { - var deferred = $q.defer(); -@@ -451,6 +452,32 @@ window.angular && (function(angular) { - }); - return deferred.promise; + validIPV4IP: function(ip) { + // Checks for [0-255].[0-255].[0-255].[0-255] + return ip.match( + /\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/); }, ++ setForceToBIOSState: function(state) { ++ console.log(state); ++ var data = JSON.stringify({'Boot': ++ { ++ 'BootSourceOverrideTarget': state ++ } ++ }); ++ return $http({ ++ method: 'PATCH', ++ url: DataService.getHost() + '/redfish/v1/Systems/system', ++ withCredentials: true, ++ data: data ++ }); ++ }, + getForceToBIOSState: function() { -+ var deferred = $q.defer(); + -+ if (DataService.configJson.redfishSupportEnabled == true) { -+ $http({ -+ method: 'GET', -+ url: -+ DataService.getHost() + '/redfish/v1/Systems/system', -+ withCredentials: true -+ }).then( -+ function(response) { -+ var json = JSON.stringify(response.data); -+ var content = JSON.parse(json); -+ deferred.resolve(content.Boot.BootSourceOverrideTarget); -+ }, -+ function(error) { -+ console.log(error); -+ deferred.reject(error); -+ }); -+ } else { -+ var err = "Redfish is not enabled!"; -+ console.log(err); -+ deferred.reject(err); -+ } -+ return deferred.promise; -+ }, - login: function(username, password, callback) { - $http({ - method: 'POST', -@@ -872,6 +899,28 @@ window.angular && (function(angular) { - } - }); - }, -+ setForceToBIOSState: function(state) { -+ if (DataService.configJson.redfishSupportEnabled == true) { -+ var data = JSON.stringify({'Boot': -+ { -+ 'BootSourceOverrideTarget': state -+ } -+ }); -+ return $http({ -+ method: 'PATCH', -+ url: -+ DataService.getHost() + '/redfish/v1/Systems/system', -+ withCredentials: true, -+ data: data -+ }); -+ } else { -+ var deferred = $q.defer(); -+ var err = "Redfish is not enabled!"; -+ console.log(err); -+ deferred.reject(err); -+ return deferred.promise; -+ } ++ return $http({ ++ method: 'GET', ++ url: DataService.getHost() + '/redfish/v1/Systems/system', ++ withCredentials: true ++ }).then( ++ function(response) { ++ console.log(JSON.stringify(response.data.Boot.BootSourceOverrideTarget)); ++ return response.data.Boot.BootSourceOverrideTarget; ++ }, ++ function(error) { ++ console.log(error); ++ }); + }, - getLastRebootTime: function() { + getRedfishSysName: function() { return $http({ method: 'GET', diff --git a/app/common/services/constants.js b/app/common/services/constants.js -index 9931f01..8da0b12 100644 +index ae82e76..e594570 100644 --- a/app/common/services/constants.js +++ b/app/common/services/constants.js -@@ -38,6 +38,10 @@ window.angular && (function(angular) { - HOST_STATE: {on: 1, off: -1, error: 0, unreachable: -2}, +@@ -42,6 +42,10 @@ window.angular && (function(angular) { + }, LED_STATE: {on: true, off: false}, LED_STATE_TEXT: {on: 'on', off: 'off'}, + FORCE_TO_BIOS_STATE_TEXT: { @@ -110,22 +75,22 @@ index 9931f01..8da0b12 100644 Emergency: 'High', Alert: 'High', diff --git a/app/common/services/dataService.js b/app/common/services/dataService.js -index 76ab381..bcd7142 100644 +index 87fddba..cc9c0b3 100644 --- a/app/common/services/dataService.js +++ b/app/common/services/dataService.js -@@ -18,6 +18,7 @@ window.angular && (function(angular) { - this.server_status = -2; - this.chassis_state = 'On'; +@@ -16,6 +16,7 @@ window.angular && (function(angular) { + this.server_health = Constants.SERVER_HEALTH.unknown; + this.server_state = 'Unreachable'; this.LED_state = Constants.LED_STATE_TEXT.off; + this.ForceToBIOS_state = Constants.FORCE_TO_BIOS_STATE_TEXT.off; this.last_updated = new Date(); this.loading = false; diff --git a/app/server-control/controllers/power-operations-controller.html b/app/server-control/controllers/power-operations-controller.html -index 3dc69d2..1f00f4a 100644 +index ddf8bda..ea46e00 100644 --- a/app/server-control/controllers/power-operations-controller.html +++ b/app/server-control/controllers/power-operations-controller.html -@@ -10,6 +10,18 @@ +@@ -10,6 +10,17 @@ <div class="row column"> <div id="power-indicator-bar" class="power__indicator-bar" ng-class="{'power__state-on': dataService.server_state == 'Running', 'power__state-off': dataService.server_state == 'Off', 'power__state-indet': dataService.server_state == 'Standby', 'power__state-error': dataService.server_state == 'Quiesced'}"> <p class="inline">{{dataService.hostname}} - {{dataService.server_id}}</p> @@ -140,18 +105,30 @@ index 3dc69d2..1f00f4a 100644 + <label for="toggle__switch-round" tabindex="0"> </label> + <h3 class="inline">Boot to BIOS</h3> + </div> -+ <h3 class="power__state inline no-margin h3"><span>{{dataService.server_state | quiescedToError}}</span></h3> </div> </div> diff --git a/app/server-control/controllers/power-operations-controller.js b/app/server-control/controllers/power-operations-controller.js -index 1a1f355..9a832e8 100644 +index 986ac3b..2c29093 100644 --- a/app/server-control/controllers/power-operations-controller.js +++ b/app/server-control/controllers/power-operations-controller.js -@@ -26,6 +26,17 @@ window.angular && (function(angular) { +@@ -10,10 +10,10 @@ window.angular && (function(angular) { + 'use strict'; - var pollChassisStatusTimer = undefined; - var pollStartTime = null; + angular.module('app.serverControl').controller('powerOperationsController', [ +- '$scope', 'APIUtils', 'dataService', 'Constants', '$interval', '$q', ++ '$route', '$scope', 'APIUtils', 'dataService', 'Constants', '$interval', '$q', + 'toastService', + function( +- $scope, APIUtils, dataService, Constants, $interval, $q, toastService) { ++ $route, $scope, APIUtils, dataService, Constants, $interval, $q, toastService) { + $scope.dataService = dataService; + // Is a || of the other 4 "confirm" variables to ensure only + // one confirm is shown at a time. +@@ -57,6 +57,17 @@ window.angular && (function(angular) { + }, Constants.POLL_INTERVALS.POWER_OP); + return deferred.promise; + }; + APIUtils.getForceToBIOSState().then( + function(data) { + if (data == APIUtils.FORCE_TO_BIOS_STATE_TEXT.on) { @@ -164,11 +141,11 @@ index 1a1f355..9a832e8 100644 + console.log(JSON.stringify(error)); + }); - //@TODO: call api and get proper state - -@@ -50,6 +61,27 @@ window.angular && (function(angular) { - (dataService.server_state == 'Running') ? 'Off' : 'Running'; - }; + APIUtils.getLastPowerTime() + .then( +@@ -74,6 +85,27 @@ window.angular && (function(angular) { + $scope.loading = false; + }); + $scope.toggleForceToBIOS = function() { + var toggleState = @@ -191,9 +168,9 @@ index 1a1f355..9a832e8 100644 + }) + }; + - $scope.powerOn = function() { - $scope.loading = true; - dataService.setUnreachableState(); + $scope.toggleState = function() { + dataService.server_state = + (dataService.server_state == 'Running') ? 'Off' : 'Running'; -- -2.19.1 +2.7.4 diff --git a/meta-openbmc-mods/meta-common/recipes-phosphor/webui/phosphor-webui_%.bbappend b/meta-openbmc-mods/meta-common/recipes-phosphor/webui/phosphor-webui_%.bbappend index 97270e982..5f18206c8 100644 --- a/meta-openbmc-mods/meta-common/recipes-phosphor/webui/phosphor-webui_%.bbappend +++ b/meta-openbmc-mods/meta-common/recipes-phosphor/webui/phosphor-webui_%.bbappend @@ -1,6 +1,6 @@ FILESEXTRAPATHS_append := ":${THISDIR}/${PN}" #SRC_URI = "git://github.com/openbmc/phosphor-webui.git" -SRCREV = "ae0353989abe7d9194dba47ca26d803fe11f46b6" +SRCREV = "30d7c6377f70382088436c7a4830663eb522d588" SRC_URI += "file://0004-Implement-force-boot-to-bios-in-server-power-control.patch" |