diff options
Diffstat (limited to 'meta-yadro')
53 files changed, 2320 insertions, 438 deletions
diff --git a/meta-yadro/MAINTAINERS b/meta-yadro/MAINTAINERS index 276d9ea4a..6b1b60261 100644 --- a/meta-yadro/MAINTAINERS +++ b/meta-yadro/MAINTAINERS @@ -45,3 +45,4 @@ START OF MAINTAINERS LIST M: Alexander Filippov <a.filippov@yadro.com> <nest1ing!> M: Alexander Amelkin <a.amelkin@yadro.com> <AAmelkin_YADRO!> R: Artem Senichev <artemsen@gmail.com> <artemsen!> +R: Andrei Kartashev <a.kartashev@yadro.com> <alatar!> diff --git a/meta-yadro/conf/layer.conf b/meta-yadro/conf/layer.conf index 0a5f6f2f3..502a8fdc9 100644 --- a/meta-yadro/conf/layer.conf +++ b/meta-yadro/conf/layer.conf @@ -9,4 +9,4 @@ BBFILE_COLLECTIONS += "yadro-layer" BBFILE_PATTERN_yadro-layer = "^${LAYERDIR}/" BBFILE_PATTERN_IGNORE_EMPTY_yadro-layer = "1" -LAYERSERIES_COMPAT_yadro-layer = "warrior zeus dunfell" +LAYERSERIES_COMPAT_yadro-layer = "dunfell gatesgarth" diff --git a/meta-yadro/meta-nicole/recipes-bsp/u-boot/files/0001-Add-system-reset-status-support.patch b/meta-yadro/meta-nicole/recipes-bsp/u-boot/files/0001-Add-system-reset-status-support.patch index 4daa354d6..d1cc9d9a6 100644 --- a/meta-yadro/meta-nicole/recipes-bsp/u-boot/files/0001-Add-system-reset-status-support.patch +++ b/meta-yadro/meta-nicole/recipes-bsp/u-boot/files/0001-Add-system-reset-status-support.patch @@ -1,4 +1,4 @@ -From cf39fde2c1cfb55aa756bfb551c4087ba2fd4b6c Mon Sep 17 00:00:00 2001 +From 1c5b450a068583f2407767451ef636d0661071da Mon Sep 17 00:00:00 2001 From: Alexander Filippov <a.filippov@yadro.com> Date: Tue, 7 Apr 2020 16:45:41 +0300 Subject: [PATCH] Add system reset status support @@ -11,27 +11,17 @@ and save the reset reasons into kernel command line, for applications to query. Signed-off-by: Alexander Filippov <a.filippov@yadro.com> - --- - arch/arm/include/asm/arch-aspeed/ast_g5_platform.h | 1 + - arch/arm/include/asm/arch-aspeed/ast_scu.h | 2 +- - arch/arm/mach-aspeed/ast-scu.c | 6 +- - board/aspeed/ast-g5/ast-g5.c | 98 ++++++++++++++++++++++ - 4 files changed, 105 insertions(+), 2 deletions(-) + arch/arm/include/asm/arch-aspeed/ast_scu.h | 2 +- + arch/arm/include/asm/arch-aspeed/platform.h | 2 + + arch/arm/mach-aspeed/Makefile | 1 + + arch/arm/mach-aspeed/ast-late-init.c | 114 ++++++++++++++++++++ + arch/arm/mach-aspeed/ast-scu.c | 6 +- + 5 files changed, 123 insertions(+), 2 deletions(-) + create mode 100644 arch/arm/mach-aspeed/ast-late-init.c -diff --git a/arch/arm/include/asm/arch-aspeed/ast_g5_platform.h b/arch/arm/include/asm/arch-aspeed/ast_g5_platform.h -index 4210873..d2a4268cd 100644 ---- a/arch/arm/include/asm/arch-aspeed/ast_g5_platform.h -+++ b/arch/arm/include/asm/arch-aspeed/ast_g5_platform.h -@@ -188,5 +188,6 @@ - #define AST_FORMATTER_MEM_SIZE 0xC00000 /* 12MB */ - #define AST_FORMATTER_MEM_BASE (AST_H264_MEM_BASE + AST_H264_MEM_SIZE) - -+#define CONFIG_BOARD_LATE_INIT 1 /* Call board_late_init */ - - #endif diff --git a/arch/arm/include/asm/arch-aspeed/ast_scu.h b/arch/arm/include/asm/arch-aspeed/ast_scu.h -index dcbc673..b428f38 100644 +index dcbc6730d4..b428f386d6 100644 --- a/arch/arm/include/asm/arch-aspeed/ast_scu.h +++ b/arch/arm/include/asm/arch-aspeed/ast_scu.h @@ -29,7 +29,7 @@ @@ -43,48 +33,43 @@ index dcbc673..b428f38 100644 extern void ast_scu_security_info(void); extern u32 ast_scu_revision_id(void); extern u32 ast_scu_get_vga_memsize(void); -diff --git a/arch/arm/mach-aspeed/ast-scu.c b/arch/arm/mach-aspeed/ast-scu.c -index 12de9b8..5afd379 100644 ---- a/arch/arm/mach-aspeed/ast-scu.c -+++ b/arch/arm/mach-aspeed/ast-scu.c -@@ -482,22 +482,26 @@ void ast_scu_security_info(void) - } - } - --void ast_scu_sys_rest_info(void) -+u32 ast_scu_sys_rest_info(void) - { - u32 rest = ast_scu_read(AST_SCU_SYS_CTRL); - - if (rest & SCU_SYS_EXT_RESET_FLAG) { - printf("RST : External\n"); - ast_scu_write(SCU_SYS_EXT_RESET_FLAG, AST_SCU_SYS_CTRL); -+ rest = SCU_SYS_EXT_RESET_FLAG; - } else if (rest & SCU_SYS_WDT_RESET_FLAG) { - printf("RST : Watchdog\n"); - ast_scu_write(SCU_SYS_WDT_RESET_FLAG, AST_SCU_SYS_CTRL); -+ rest = SCU_SYS_WDT_RESET_FLAG; - } else if (rest & SCU_SYS_PWR_RESET_FLAG) { - printf("RST : Power On\n"); - ast_scu_write(SCU_SYS_PWR_RESET_FLAG, AST_SCU_SYS_CTRL); -+ rest = SCU_SYS_PWR_RESET_FLAG; - } else { - printf("RST : CLK en\n"); - } -+ return rest; - } +diff --git a/arch/arm/include/asm/arch-aspeed/platform.h b/arch/arm/include/asm/arch-aspeed/platform.h +index 1c02914fcb..b9207c492f 100644 +--- a/arch/arm/include/asm/arch-aspeed/platform.h ++++ b/arch/arm/include/asm/arch-aspeed/platform.h +@@ -31,4 +31,6 @@ + #err "No define for platform.h" + #endif - u32 ast_scu_get_vga_memsize(void) -diff --git a/board/aspeed/ast-g5/ast-g5.c b/board/aspeed/ast-g5/ast-g5.c -index 12496ce..42d7496 100644 ---- a/board/aspeed/ast-g5/ast-g5.c -+++ b/board/aspeed/ast-g5/ast-g5.c -@@ -105,3 +105,104 @@ void hw_watchdog_reset(void) - writel(0x4755, AST_WDT2_BASE + 0x08); - } - #endif /* CONFIG_WATCHDOG */ ++#define CONFIG_BOARD_LATE_INIT 1 /* Call board_late_init */ ++ + #endif +diff --git a/arch/arm/mach-aspeed/Makefile b/arch/arm/mach-aspeed/Makefile +index 7d8930beb9..4af2a7c96a 100644 +--- a/arch/arm/mach-aspeed/Makefile ++++ b/arch/arm/mach-aspeed/Makefile +@@ -15,3 +15,4 @@ obj-y += timer.o reset.o cpuinfo.o ast-scu.o ast-ahbc.o ast-sdmc.o + obj-$(CONFIG_AST_SPI_NOR) += flash.o + obj-$(CONFIG_ARCH_AST2500) += platform_g5.o + obj-$(CONFIG_ARCH_AST2400) += platform_g4.o ++obj-$(CONFIG_BOARD_LATE_INIT) += ast-late-init.o +diff --git a/arch/arm/mach-aspeed/ast-late-init.c b/arch/arm/mach-aspeed/ast-late-init.c +new file mode 100644 +index 0000000000..5646c0e882 +--- /dev/null ++++ b/arch/arm/mach-aspeed/ast-late-init.c +@@ -0,0 +1,114 @@ ++/* ++ * SPDX-License-Identifier: Apache-2.0 ++ * Copyright (C) 2020 YADRO. ++ */ ++ ++#include <common.h> ++ ++#include <asm/arch/ast_scu.h> ++#include <asm/arch/regs-scu.h> ++#include <malloc.h> + -+#ifdef CONFIG_BOARD_LATE_INIT +static void update_bootargs_cmd(const char *key, const char *value) +{ + int buf_len; @@ -158,7 +143,7 @@ index 12496ce..42d7496 100644 + free(buf); +} + -+int board_late_init(void) ++static void set_reset_reason(void) +{ + u32 reset_reason = ast_scu_sys_rest_info(); + @@ -180,7 +165,46 @@ index 12496ce..42d7496 100644 + snprintf(value, sizeof(value) - 1, "0x%x", reset_reason); + update_bootargs_cmd("resetreason", value); + } ++} ++ ++int board_late_init(void) ++{ ++ set_reset_reason(); + + return 0; +} -+#endif /* CONFIG_BOARD_LATE_INIT */ +diff --git a/arch/arm/mach-aspeed/ast-scu.c b/arch/arm/mach-aspeed/ast-scu.c +index 12de9b8036..5afd3793e3 100644 +--- a/arch/arm/mach-aspeed/ast-scu.c ++++ b/arch/arm/mach-aspeed/ast-scu.c +@@ -482,22 +482,26 @@ void ast_scu_security_info(void) + } + } + +-void ast_scu_sys_rest_info(void) ++u32 ast_scu_sys_rest_info(void) + { + u32 rest = ast_scu_read(AST_SCU_SYS_CTRL); + + if (rest & SCU_SYS_EXT_RESET_FLAG) { + printf("RST : External\n"); + ast_scu_write(SCU_SYS_EXT_RESET_FLAG, AST_SCU_SYS_CTRL); ++ rest = SCU_SYS_EXT_RESET_FLAG; + } else if (rest & SCU_SYS_WDT_RESET_FLAG) { + printf("RST : Watchdog\n"); + ast_scu_write(SCU_SYS_WDT_RESET_FLAG, AST_SCU_SYS_CTRL); ++ rest = SCU_SYS_WDT_RESET_FLAG; + } else if (rest & SCU_SYS_PWR_RESET_FLAG) { + printf("RST : Power On\n"); + ast_scu_write(SCU_SYS_PWR_RESET_FLAG, AST_SCU_SYS_CTRL); ++ rest = SCU_SYS_PWR_RESET_FLAG; + } else { + printf("RST : CLK en\n"); + } ++ return rest; + } + + u32 ast_scu_get_vga_memsize(void) +-- +2.25.4 + diff --git a/meta-yadro/meta-nicole/recipes-bsp/u-boot/files/0003-aspeed-add-gpio-support.patch b/meta-yadro/meta-nicole/recipes-bsp/u-boot/files/0003-aspeed-add-gpio-support.patch new file mode 100644 index 000000000..2e825c8cd --- /dev/null +++ b/meta-yadro/meta-nicole/recipes-bsp/u-boot/files/0003-aspeed-add-gpio-support.patch @@ -0,0 +1,512 @@ +From 9bb68d8820480519e8b331f7a8b866b8718ad7fd Mon Sep 17 00:00:00 2001 +From: Alexander Filippov <a.filippov@yadro.com> +Date: Tue, 19 May 2020 18:55:41 +0300 +Subject: [PATCH] aspeed: add gpio support + +This is an initial support for the parallel GPIO pins directly connected +to the AHB on the Aspeed 2400/2500. + +This brings the functions and a shell command to manipulate the GPIO +state. The GPIO value reading and writing work in non interrupt mode +only. + +Signed-off-by: Alexander Filippov <a.filippov@yadro.com> +--- + arch/arm/include/asm/arch-aspeed/gpio.h | 65 ++++ + arch/arm/include/asm/arch-aspeed/platform.h | 1 + + drivers/gpio/Makefile | 2 + + drivers/gpio/aspeed_gpio.c | 386 ++++++++++++++++++++ + 4 files changed, 454 insertions(+) + create mode 100644 arch/arm/include/asm/arch-aspeed/gpio.h + create mode 100644 drivers/gpio/aspeed_gpio.c + +diff --git a/arch/arm/include/asm/arch-aspeed/gpio.h b/arch/arm/include/asm/arch-aspeed/gpio.h +new file mode 100644 +index 0000000000..c63987e917 +--- /dev/null ++++ b/arch/arm/include/asm/arch-aspeed/gpio.h +@@ -0,0 +1,65 @@ ++/* ++ * SPDX-License-Identifier: GPL-2.0+ ++ * Copyright (C) 2020 YADRO. ++ */ ++#ifndef _ASPEED_GPIO_H ++#define _ASPEED_GPIO_H ++ ++#define ASPEED_GPIO_PORT_A 0 ++#define ASPEED_GPIO_PORT_B 1 ++#define ASPEED_GPIO_PORT_C 2 ++#define ASPEED_GPIO_PORT_D 3 ++#define ASPEED_GPIO_PORT_E 4 ++#define ASPEED_GPIO_PORT_F 5 ++#define ASPEED_GPIO_PORT_G 6 ++#define ASPEED_GPIO_PORT_H 7 ++#define ASPEED_GPIO_PORT_I 8 ++#define ASPEED_GPIO_PORT_J 9 ++#define ASPEED_GPIO_PORT_K 10 ++#define ASPEED_GPIO_PORT_L 11 ++#define ASPEED_GPIO_PORT_M 12 ++#define ASPEED_GPIO_PORT_N 13 ++#define ASPEED_GPIO_PORT_O 14 ++#define ASPEED_GPIO_PORT_P 15 ++#define ASPEED_GPIO_PORT_Q 16 ++#define ASPEED_GPIO_PORT_R 17 ++#define ASPEED_GPIO_PORT_S 18 ++#define ASPEED_GPIO_PORT_T 19 ++#define ASPEED_GPIO_PORT_U 20 ++#define ASPEED_GPIO_PORT_V 21 ++#define ASPEED_GPIO_PORT_W 22 ++#define ASPEED_GPIO_PORT_X 23 ++#define ASPEED_GPIO_PORT_Y 24 ++#define ASPEED_GPIO_PORT_Z 25 ++#define ASPEED_GPIO_PORT_AA 26 ++#define ASPEED_GPIO_PORT_AB 27 ++#define ASPEED_GPIO_PORT_AC 28 ++ ++#define ASPEED_GPIO_PORT_SHIFT 3 ++#define ASPEED_GPIO_PIN_MASK 0x7 ++#define ASPEED_GPIO(port, pin) \ ++ ((ASPEED_GPIO_PORT_##port << ASPEED_GPIO_PORT_SHIFT) | \ ++ (pin & ASPEED_GPIO_PIN_MASK)) ++ ++/* Direction values */ ++#define ASPEED_GPIO_INPUT 0 ++#define ASPEED_GPIO_OUTPUT 1 ++ ++/* Trigger values */ ++#define ASPEED_GPIO_FALLING_EDGE 0 ++#define ASPEED_GPIO_RISING_EDGE 1 ++#define ASPEED_GPIO_LOW_LEVEL 2 ++#define ASPEED_GPIO_HIGH_LEVEL 3 ++#define ASPEED_GPIO_DUAL_EDGE 4 ++ ++/* Debounce values */ ++#define ASPEED_GPIO_DEBOUNCE_NONE 0 ++#define ASPEED_GPIO_DEBOUNCE_1 1 ++#define ASPEED_GPIO_DEBOUNCE_2 2 ++#define ASPEED_GPIO_DEBOUNCE_3 3 ++ ++#define gpio_status() gpio_info() ++ ++extern void gpio_info(void); ++ ++#endif /* #ifndef _ASPEED_GPIO_H */ +diff --git a/arch/arm/include/asm/arch-aspeed/platform.h b/arch/arm/include/asm/arch-aspeed/platform.h +index b9207c492f..0a05a7a7a0 100644 +--- a/arch/arm/include/asm/arch-aspeed/platform.h ++++ b/arch/arm/include/asm/arch-aspeed/platform.h +@@ -32,5 +32,6 @@ + #endif + + #define CONFIG_BOARD_LATE_INIT 1 /* Call board_late_init */ ++#define CONFIG_CMD_GPIO 1 /* Enable gpio command in shell */ + + #endif +diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile +index 792d19186a..5f043e07ce 100644 +--- a/drivers/gpio/Makefile ++++ b/drivers/gpio/Makefile +@@ -14,6 +14,8 @@ obj-$(CONFIG_DM_GPIO) += gpio-uclass.o + obj-$(CONFIG_DM_PCA953X) += pca953x_gpio.o + obj-$(CONFIG_DM_74X164) += 74x164_gpio.o + ++obj-$(CONFIG_ARCH_AST2400) += aspeed_gpio.o ++obj-$(CONFIG_ARCH_AST2500) += aspeed_gpio.o + obj-$(CONFIG_AT91_GPIO) += at91_gpio.o + obj-$(CONFIG_ATMEL_PIO4) += atmel_pio4.o + obj-$(CONFIG_INTEL_ICH6_GPIO) += intel_ich6_gpio.o +diff --git a/drivers/gpio/aspeed_gpio.c b/drivers/gpio/aspeed_gpio.c +new file mode 100644 +index 0000000000..dc07f5a520 +--- /dev/null ++++ b/drivers/gpio/aspeed_gpio.c +@@ -0,0 +1,386 @@ ++/* ++ * SPDX-License-Identifier: GPL-2.0+ ++ * Copyright (C) 2020 YADRO. ++ */ ++ ++#include <common.h> ++ ++#include <asm/arch/gpio.h> ++#include <asm/arch/platform.h> ++#include <asm/io.h> ++#include <linux/ctype.h> ++ ++typedef struct _ast_gpio_regs ++{ ++ uint32_t base; /* data and direction registers */ ++ uint32_t intcfg; /* interrupt config */ ++ uint32_t debounce; /* debounce config */ ++ uint32_t cmdsrc; /* command source config */ ++ uint32_t data; /* data read register */ ++} ast_gpio_regs_t; ++ ++static ast_gpio_regs_t ast_gpio_regs[] = { ++ /* A/B/C/D */ ++ {AST_GPIO_BASE + 0x0000, AST_GPIO_BASE + 0x0008, AST_GPIO_BASE + 0x0040, ++ AST_GPIO_BASE + 0x0060, AST_GPIO_BASE + 0x00C0}, ++ /* E/F/G/H */ ++ {AST_GPIO_BASE + 0x0020, AST_GPIO_BASE + 0x0028, AST_GPIO_BASE + 0x0048, ++ AST_GPIO_BASE + 0x0068, AST_GPIO_BASE + 0x00C4}, ++ /* I/J/K/L */ ++ {AST_GPIO_BASE + 0x0070, AST_GPIO_BASE + 0x0098, AST_GPIO_BASE + 0x00B0, ++ AST_GPIO_BASE + 0x0090, AST_GPIO_BASE + 0x00C8}, ++ /* M/N/O/P */ ++ {AST_GPIO_BASE + 0x0078, AST_GPIO_BASE + 0x00E8, AST_GPIO_BASE + 0x0100, ++ AST_GPIO_BASE + 0x00E0, AST_GPIO_BASE + 0x00CC}, ++ /* Q/R/S/T */ ++ {AST_GPIO_BASE + 0x0080, AST_GPIO_BASE + 0x0118, AST_GPIO_BASE + 0x0130, ++ AST_GPIO_BASE + 0x0110, AST_GPIO_BASE + 0x00D0}, ++ /* U/V/W/X */ ++ {AST_GPIO_BASE + 0x0088, AST_GPIO_BASE + 0x0148, AST_GPIO_BASE + 0x0160, ++ AST_GPIO_BASE + 0x0140, AST_GPIO_BASE + 0x00D4}, ++ /* Y/Z/AA/AB */ ++ {AST_GPIO_BASE + 0x01E0, AST_GPIO_BASE + 0x0178, AST_GPIO_BASE + 0x0190, ++ AST_GPIO_BASE + 0x0170, AST_GPIO_BASE + 0x00D8}, ++ /* AC */ ++ {AST_GPIO_BASE + 0x01E8, AST_GPIO_BASE + 0x01A8, AST_GPIO_BASE + 0x01C0, ++ AST_GPIO_BASE + 0x01A0, AST_GPIO_BASE + 0x00DC}, ++}; ++ ++#define AST_GPIO_PINS_PER_PORT 8 ++#define AST_GPIO_PORTS_PER_REGISTER 4 ++ ++#define AST_GPIO_PORT(gpio) (gpio >> ASPEED_GPIO_PORT_SHIFT) ++#define AST_GPIO_PIN(gpio) (gpio & ASPEED_GPIO_PIN_MASK) ++#define AST_GPIO_SHIFT(gpio) \ ++ ((AST_GPIO_PORT(gpio) % AST_GPIO_PORTS_PER_REGISTER) * \ ++ AST_GPIO_PINS_PER_PORT + \ ++ AST_GPIO_PIN(gpio)) ++ ++#define AST_GPIO_REG_INDEX(gpio) \ ++ (AST_GPIO_PORT(gpio) / AST_GPIO_PORTS_PER_REGISTER) ++ ++/** ++ * @return Pointer to corresponding item from ast_gpio_regs table. ++ */ ++#define AST_GPIO_REGS(gpio) \ ++ ((AST_GPIO_REG_INDEX(gpio) < ARRAY_SIZE(ast_gpio_regs)) \ ++ ? (ast_gpio_regs + AST_GPIO_REG_INDEX(gpio)) \ ++ : NULL) ++ ++/** ++ * @brief Set a corresponding bit in specified register. ++ * ++ * @param val - Required bit value ++ * @param base - Register address ++ * @param shift - Bit index. ++ */ ++#define AST_GPIO_WRITE(val, base, shift) \ ++ writel(((val) ? readl(base) | (1 << (shift)) \ ++ : readl(base) & ~(1 << (shift))), \ ++ base) ++ ++/** ++ * @brief Get value of corresponging bit from specified register. ++ * ++ * @param base - Register address ++ * @param shift - Bit index ++ * ++ * @return Bit value ++ */ ++#define AST_GPIO_READ(base, shift) ((readl(base) >> (shift)) & 1) ++ ++#define IS_VALID_GPIO(gpio) \ ++ ((gpio) >= ASPEED_GPIO(A, 0) && (gpio) <= ASPEED_GPIO(AC, 7)) ++ ++#define AST_GPIO_DIRECTION 0x04 ++#define AST_GPIO_INT_SENS0 0x04 ++#define AST_GPIO_INT_SENS1 0x08 ++#define AST_GPIO_INT_SENS2 0x0C ++#define AST_GPIO_INT_STATUS 0x10 ++#define AST_GPIO_DEBOUNCE0 0x00 ++#define AST_GPIO_DEBOUNCE1 0x04 ++#define AST_GPIO_CMD_SRC0 0x00 ++#define AST_GPIO_CMD_SRC1 0x04 ++ ++/** ++ * @brief Set a GPIO direction ++ * ++ * @param gpio GPIO line ++ * @param direction GPIO direction (0 for input or 1 for output) ++ * ++ * @return 0 if ok, -1 on error ++ */ ++static int ast_gpio_set_direction(unsigned gpio, unsigned direction) ++{ ++ ast_gpio_regs_t *regs = AST_GPIO_REGS(gpio); ++ if (!regs) ++ { ++ printf("%s: Invalid GPIO!\n", __func__); ++ return -1; ++ } ++ ++ AST_GPIO_WRITE(direction, regs->base + AST_GPIO_DIRECTION, ++ AST_GPIO_SHIFT(gpio)); ++ return 0; ++} ++ ++/** ++ * The 6 following functions are generic u-boot gpio implementation. ++ * They are declared in `include/asm-generic/gpio.h` ++ */ ++ ++int gpio_request(unsigned gpio, const char *label) ++{ ++ return (IS_VALID_GPIO(gpio) ? 0 : -1); ++} ++ ++int gpio_free(unsigned gpio) ++{ ++ return (IS_VALID_GPIO(gpio) ? 0 : -1); ++} ++ ++int gpio_get_value(unsigned gpio) ++{ ++ ast_gpio_regs_t *regs = AST_GPIO_REGS(gpio); ++ if (!regs) ++ { ++ printf("%s: Invalid GPIO!\n", __func__); ++ return -1; ++ } ++ ++ return AST_GPIO_READ(regs->base, AST_GPIO_SHIFT(gpio)); ++} ++ ++int gpio_set_value(unsigned gpio, int value) ++{ ++ ast_gpio_regs_t *regs = AST_GPIO_REGS(gpio); ++ if (!regs) ++ { ++ printf("%s: Invalid GPIO!\n", __func__); ++ return -1; ++ } ++ ++ AST_GPIO_WRITE(value, regs->base, AST_GPIO_SHIFT(gpio)); ++ return 0; ++} ++ ++int gpio_direction_input(unsigned gpio) ++{ ++ return ast_gpio_set_direction(gpio, ASPEED_GPIO_INPUT); ++} ++ ++int gpio_direction_output(unsigned gpio, int value) ++{ ++ int rc = ast_gpio_set_direction(gpio, ASPEED_GPIO_OUTPUT); ++ return (rc == 0 ? gpio_set_value(gpio, value) : rc); ++} ++ ++/** ++ * @brief Convert a string to GPIO line. Used by `do_gpio()` from `cmd/gpio.c` ++ * ++ * @param str a GPIO name or line number ++ * ++ * @return GPIO line if ok, -1 on error ++ */ ++int name_to_gpio(const char *str) ++{ ++ int gpio = -1; ++ ++ if (str) ++ { ++ if (isalpha(*str)) ++ { ++ gpio = (toupper(*str) - 'A') << ASPEED_GPIO_PORT_SHIFT; ++ ++ if (toupper(*str) == 'A' && toupper(*(str + 1)) >= 'A' && ++ toupper(*(str + 1)) <= 'C') ++ { ++ str++; ++ gpio = (ASPEED_GPIO_PORT_AA + toupper(*str) - 'A') ++ << ASPEED_GPIO_PORT_SHIFT; ++ } ++ ++ str++; ++ if (*str >= '0' && *str <= '7' && !*(str + 1)) ++ { ++ gpio += *str - '0'; ++ } ++ else ++ { ++ gpio = -1; ++ } ++ } ++ else if (isdigit(*str)) ++ { ++ gpio = simple_strtoul(str, NULL, 0); ++ } ++ } ++ ++ return gpio; ++} ++ ++/** ++ * @return A GPIO direction in human readable format. ++ */ ++static const char *ast_gpio_direction(unsigned gpio) ++{ ++ ast_gpio_regs_t *regs = AST_GPIO_REGS(gpio); ++ if (regs) ++ { ++ int direction = AST_GPIO_READ(regs->base + AST_GPIO_DIRECTION, ++ AST_GPIO_SHIFT(gpio)); ++ switch (direction) ++ { ++ case ASPEED_GPIO_INPUT: ++ return "input"; ++ case ASPEED_GPIO_OUTPUT: ++ return "output"; ++ default: ++ break; ++ } ++ } ++ return "error"; ++} ++ ++/** ++ * @return An interrupt trigger settings in human readable format. ++ */ ++static const char *ast_gpio_trigger(unsigned gpio) ++{ ++ ast_gpio_regs_t *regs = AST_GPIO_REGS(gpio); ++ if (regs) ++ { ++ unsigned shift = AST_GPIO_SHIFT(gpio); ++ unsigned trigger = ++ (AST_GPIO_READ(regs->intcfg + AST_GPIO_INT_SENS0, shift) << 0) | ++ (AST_GPIO_READ(regs->intcfg + AST_GPIO_INT_SENS1, shift) << 1) | ++ (AST_GPIO_READ(regs->intcfg + AST_GPIO_INT_SENS2, shift) << 2); ++ ++ switch (trigger) ++ { ++ case ASPEED_GPIO_FALLING_EDGE: ++ return "fall"; ++ case ASPEED_GPIO_RISING_EDGE: ++ return "rise"; ++ case ASPEED_GPIO_LOW_LEVEL: ++ return "low "; ++ case ASPEED_GPIO_HIGH_LEVEL: ++ return "high"; ++ default: ++ return "both"; ++ } ++ } ++ return "error"; ++} ++ ++/** ++ * @return An interrupt status in human readable format. ++ */ ++static const char *ast_gpio_int_status(unsigned gpio) ++{ ++ ast_gpio_regs_t *regs = AST_GPIO_REGS(gpio); ++ if (regs) ++ { ++ unsigned shift = AST_GPIO_SHIFT(gpio); ++ if (AST_GPIO_READ(regs->intcfg, shift)) ++ { ++ return AST_GPIO_READ(regs->intcfg + AST_GPIO_INT_STATUS, shift) ++ ? "pending" ++ : "cleaned"; ++ } ++ return "disabled"; ++ } ++ ++ return "error"; ++} ++ ++/** ++ * @return A debounce value in human readable format. ++ */ ++static const char *ast_gpio_debounce(unsigned gpio) ++{ ++ ast_gpio_regs_t *regs = AST_GPIO_REGS(gpio); ++ if (regs) ++ { ++ unsigned shift = AST_GPIO_SHIFT(gpio); ++ unsigned debounce = ++ (AST_GPIO_READ(regs->debounce + AST_GPIO_DEBOUNCE0, shift) << 0) | ++ (AST_GPIO_READ(regs->debounce + AST_GPIO_DEBOUNCE1, shift) << 1); ++ switch (debounce) ++ { ++ case ASPEED_GPIO_DEBOUNCE_NONE: ++ return "none"; ++ case ASPEED_GPIO_DEBOUNCE_1: ++ return "timer1"; ++ case ASPEED_GPIO_DEBOUNCE_2: ++ return "timer2"; ++ case ASPEED_GPIO_DEBOUNCE_3: ++ return "timer3"; ++ default: ++ break; ++ } ++ } ++ ++ return "error"; ++} ++ ++/** ++ * @return A command source value in human readable format. ++ */ ++static const char *ast_gpio_command_source(unsigned gpio) ++{ ++ ast_gpio_regs_t *regs = AST_GPIO_REGS(gpio); ++ if (regs) ++ { ++ /* Used one bit per gpio port */ ++ unsigned shift = AST_GPIO_SHIFT(gpio) - AST_GPIO_PIN(gpio); ++ unsigned cmdsrc = ++ (AST_GPIO_READ(regs->cmdsrc + AST_GPIO_CMD_SRC0, shift) << 0) | ++ (AST_GPIO_READ(regs->cmdsrc + AST_GPIO_CMD_SRC1, shift) << 1); ++ ++ switch (cmdsrc) ++ { ++ /* The single place where these values are used is here. */ ++ case 0x0: ++ return "ARM"; ++ case 0x1: ++ return "LPC"; ++ case 0x2: ++ return "CoCPU"; ++ default: ++ return "Unknown"; ++ } ++ } ++ ++ return "error"; ++} ++ ++/** ++ * @brief Show all GPIO pins statuses. Used by `do_gpio()` in `cmd/gpio.c` ++ */ ++void gpio_info(void) ++{ ++ unsigned first = ASPEED_GPIO(A, 0); ++ unsigned last = ASPEED_GPIO(AC, 7); ++ for (unsigned gpio = first; gpio <= last; gpio++) ++ { ++ unsigned port = AST_GPIO_PORT(gpio); ++ unsigned pin = AST_GPIO_PIN(gpio); ++ unsigned shift = AST_GPIO_SHIFT(gpio); ++ ast_gpio_regs_t *regs = AST_GPIO_REGS(gpio); ++ if (!regs) ++ { ++ printf("gpio %u is invalid!\n", gpio); ++ continue; ++ } ++ ++ printf("gpio %c%c%c line %3d: %s, int: %s, %s, deb: %s, src: %s, " ++ "val: %d/%d\n", ++ (port >= ASPEED_GPIO_PORT_AA ? 'A' : ' '), ++ ('A' + port % ASPEED_GPIO_PORT_AA), ('0' + pin), gpio, ++ ast_gpio_direction(gpio), ast_gpio_trigger(gpio), ++ ast_gpio_int_status(gpio), ast_gpio_debounce(gpio), ++ ast_gpio_command_source(gpio), gpio_get_value(gpio), ++ AST_GPIO_READ(regs->data, shift)); ++ } ++} +-- +2.25.4 + diff --git a/meta-yadro/meta-nicole/recipes-bsp/u-boot/files/0004-aspeed-add-bmc-position-support.patch b/meta-yadro/meta-nicole/recipes-bsp/u-boot/files/0004-aspeed-add-bmc-position-support.patch new file mode 100644 index 000000000..423092b5f --- /dev/null +++ b/meta-yadro/meta-nicole/recipes-bsp/u-boot/files/0004-aspeed-add-bmc-position-support.patch @@ -0,0 +1,61 @@ +From 8098310be5887bd5e80830f105b63ed59dc10421 Mon Sep 17 00:00:00 2001 +From: Alexander Filippov <a.filippov@yadro.com> +Date: Fri, 22 May 2020 11:45:31 +0300 +Subject: [PATCH] aspeed: add bmc position support + +There are two Nicoles in one chassis in the Tatlin hardware. +The position is encoded by a pin, read by an MCU, and then translated +to the BMC via GPIO pin GPIOE1. + +This reads the GPIO pin state and put is as a bootargs item. + +Signed-off-by: Alexander Filippov <a.filippov@yadro.com> +--- + arch/arm/mach-aspeed/ast-late-init.c | 21 +++++++++++++++++++++ + 1 file changed, 21 insertions(+) + +diff --git a/arch/arm/mach-aspeed/ast-late-init.c b/arch/arm/mach-aspeed/ast-late-init.c +index 5646c0e882..7d36dc0d8a 100644 +--- a/arch/arm/mach-aspeed/ast-late-init.c ++++ b/arch/arm/mach-aspeed/ast-late-init.c +@@ -7,6 +7,7 @@ + + #include <asm/arch/ast_scu.h> + #include <asm/arch/regs-scu.h> ++#include <asm/gpio.h> + #include <malloc.h> + + static void update_bootargs_cmd(const char *key, const char *value) +@@ -106,9 +107,29 @@ static void set_reset_reason(void) + } + } + ++static void set_bmc_position(void) ++{ ++ unsigned gpio = ASPEED_GPIO(E, 1); ++ ++ /* Init GPIO */ ++ if (gpio_request(gpio, "bmcposition") == 0 && ++ gpio_direction_input(gpio) == 0) ++ { ++ int position = gpio_get_value(gpio); ++ if (position >= 0) ++ { ++ printf("BMC Position: %d\n", position); ++ update_bootargs_cmd("bmcposition", position ? "1" : "0"); ++ } ++ } ++ ++ gpio_free(gpio); ++} ++ + int board_late_init(void) + { + set_reset_reason(); ++ set_bmc_position(); + + return 0; + } +-- +2.25.4 + diff --git a/meta-yadro/meta-nicole/recipes-bsp/u-boot/u-boot-aspeed_%.bbappend b/meta-yadro/meta-nicole/recipes-bsp/u-boot/u-boot-aspeed_%.bbappend index bf7802a68..1390922e1 100644 --- a/meta-yadro/meta-nicole/recipes-bsp/u-boot/u-boot-aspeed_%.bbappend +++ b/meta-yadro/meta-nicole/recipes-bsp/u-boot/u-boot-aspeed_%.bbappend @@ -3,4 +3,6 @@ FILESEXTRAPATHS_append := "${THISDIR}/files:" SRC_URI_append = " \ file://0001-Add-system-reset-status-support.patch \ file://0002-config-ast-common-set-fieldmode-to-true.patch \ + file://0003-aspeed-add-gpio-support.patch \ + file://0004-aspeed-add-bmc-position-support.patch \ " diff --git a/meta-yadro/meta-nicole/recipes-core/dropbear/dropbear/dropbear.default b/meta-yadro/meta-nicole/recipes-core/dropbear/dropbear/dropbear.default new file mode 100644 index 000000000..e5f778145 --- /dev/null +++ b/meta-yadro/meta-nicole/recipes-core/dropbear/dropbear/dropbear.default @@ -0,0 +1 @@ +DROPBEAR_EXTRA_ARGS="" diff --git a/meta-yadro/meta-nicole/recipes-core/dropbear/dropbear_%.bbappend b/meta-yadro/meta-nicole/recipes-core/dropbear/dropbear_%.bbappend new file mode 100644 index 000000000..72d991c7e --- /dev/null +++ b/meta-yadro/meta-nicole/recipes-core/dropbear/dropbear_%.bbappend @@ -0,0 +1 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" diff --git a/meta-yadro/meta-nicole/recipes-core/systemd/systemd-conf/00-bmc-eth0.0.network b/meta-yadro/meta-nicole/recipes-core/systemd/systemd-conf/00-bmc-eth0.0.network new file mode 100644 index 000000000..64a1436cb --- /dev/null +++ b/meta-yadro/meta-nicole/recipes-core/systemd/systemd-conf/00-bmc-eth0.0.network @@ -0,0 +1,11 @@ +[Match] +Name=eth0 +KernelCommandLine=bmcposition=0 +[Network] +VLAN=eth0.4004 +DHCP=true +LinkLocalAddressing=yes +IPv6AcceptRA=false +Address=10.9.0.1/24 +[DHCP] +ClientIdentifier=mac diff --git a/meta-yadro/meta-nicole/recipes-core/systemd/systemd-conf/00-bmc-eth0.1.network b/meta-yadro/meta-nicole/recipes-core/systemd/systemd-conf/00-bmc-eth0.1.network new file mode 100644 index 000000000..aaaa520dd --- /dev/null +++ b/meta-yadro/meta-nicole/recipes-core/systemd/systemd-conf/00-bmc-eth0.1.network @@ -0,0 +1,11 @@ +[Match] +Name=eth0 +KernelCommandLine=bmcposition=1 +[Network] +VLAN=eth0.4004 +DHCP=true +LinkLocalAddressing=yes +IPv6AcceptRA=false +Address=10.9.0.2/24 +[DHCP] +ClientIdentifier=mac diff --git a/meta-yadro/meta-nicole/recipes-core/systemd/systemd-conf/00-bmc-eth0.4004.0.network b/meta-yadro/meta-nicole/recipes-core/systemd/systemd-conf/00-bmc-eth0.4004.0.network new file mode 100644 index 000000000..534cbe9b1 --- /dev/null +++ b/meta-yadro/meta-nicole/recipes-core/systemd/systemd-conf/00-bmc-eth0.4004.0.network @@ -0,0 +1,8 @@ +[Match] +Name=eth0.4004 +KernelCommandLine=bmcposition=0 +[Network] +LinkLocalAddressing=yes +IPv6AcceptRA=true +DHCP=no +Address=fd59:4144:524f:5441:544c:494e:3:1/122 diff --git a/meta-yadro/meta-nicole/recipes-core/systemd/systemd-conf/00-bmc-eth0.4004.1.network b/meta-yadro/meta-nicole/recipes-core/systemd/systemd-conf/00-bmc-eth0.4004.1.network new file mode 100644 index 000000000..83a48eee7 --- /dev/null +++ b/meta-yadro/meta-nicole/recipes-core/systemd/systemd-conf/00-bmc-eth0.4004.1.network @@ -0,0 +1,8 @@ +[Match] +Name=eth0.4004 +KernelCommandLine=bmcposition=1 +[Network] +LinkLocalAddressing=yes +IPv6AcceptRA=true +DHCP=no +Address=fd59:4144:524f:5441:544c:494e:3:2/122 diff --git a/meta-yadro/meta-nicole/recipes-core/systemd/systemd-conf/eth0.4004.netdev b/meta-yadro/meta-nicole/recipes-core/systemd/systemd-conf/eth0.4004.netdev new file mode 100644 index 000000000..e315f5e8a --- /dev/null +++ b/meta-yadro/meta-nicole/recipes-core/systemd/systemd-conf/eth0.4004.netdev @@ -0,0 +1,5 @@ +[NetDev] +Name=eth0.4004 +Kind=vlan +[VLAN] +Id=4004 diff --git a/meta-yadro/meta-nicole/recipes-core/systemd/systemd-conf_%.bbappend b/meta-yadro/meta-nicole/recipes-core/systemd/systemd-conf_%.bbappend new file mode 100644 index 000000000..48d4a4a4c --- /dev/null +++ b/meta-yadro/meta-nicole/recipes-core/systemd/systemd-conf_%.bbappend @@ -0,0 +1,27 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" + +SRC_URI_append = " \ + file://00-bmc-eth0.4004.0.network \ + file://00-bmc-eth0.4004.1.network \ + file://00-bmc-eth0.0.network \ + file://00-bmc-eth0.1.network \ + file://eth0.4004.netdev \ +" + +do_install_append() { + install -m 0644 \ + ${WORKDIR}/00-bmc-eth0.4004.0.network \ + ${WORKDIR}/00-bmc-eth0.4004.1.network \ + ${WORKDIR}/00-bmc-eth0.0.network \ + ${WORKDIR}/00-bmc-eth0.1.network \ + ${WORKDIR}/eth0.4004.netdev \ + -D -t ${D}${sysconfdir}/systemd/network +} + +FILES_${PN}_append = " \ + ${sysconfdir}/systemd/network/00-bmc-eth0.4004.0.network \ + ${sysconfdir}/systemd/network/00-bmc-eth0.4004.1.network \ + ${sysconfdir}/systemd/network/00-bmc-eth0.0.network \ + ${sysconfdir}/systemd/network/00-bmc-eth0.1.network \ + ${sysconfdir}/systemd/network/eth0.4004.netdev \ +" diff --git a/meta-yadro/meta-nicole/recipes-kernel/linux/linux-aspeed/arch/arm/boot/dts/aspeed-bmc-opp-nicole.dts b/meta-yadro/meta-nicole/recipes-kernel/linux/linux-aspeed/arch/arm/boot/dts/aspeed-bmc-opp-nicole.dts deleted file mode 100644 index 91dced7e7..000000000 --- a/meta-yadro/meta-nicole/recipes-kernel/linux/linux-aspeed/arch/arm/boot/dts/aspeed-bmc-opp-nicole.dts +++ /dev/null @@ -1,326 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -// Copyright 2019 YADRO -/dts-v1/; -#include "aspeed-g5.dtsi" -#include <dt-bindings/gpio/aspeed-gpio.h> - -/ { - model = "Nicole BMC"; - compatible = "yadro,nicole-bmc", "aspeed,ast2500"; - - chosen { - stdout-path = &uart5; - bootargs = "console=ttyS4,115200 earlyprintk"; - }; - - memory@80000000 { - reg = <0x80000000 0x20000000>; - }; - - reserved-memory { - #address-cells = <1>; - #size-cells = <1>; - ranges; - - vga_memory: framebuffer@9f000000 { - no-map; - reg = <0x9f000000 0x01000000>; /* 16M */ - }; - - flash_memory: region@98000000 { - no-map; - reg = <0x98000000 0x04000000>; /* 64M */ - }; - - coldfire_memory: codefire_memory@9ef00000 { - reg = <0x9ef00000 0x00100000>; - no-map; - }; - - gfx_memory: framebuffer { - size = <0x01000000>; - alignment = <0x01000000>; - compatible = "shared-dma-pool"; - reusable; - }; - - video_engine_memory: jpegbuffer { - size = <0x02000000>; /* 32M */ - alignment = <0x01000000>; - compatible = "shared-dma-pool"; - reusable; - }; - }; - - leds { - compatible = "gpio-leds"; - - power { - label = "platform:green:power"; - gpios = <&gpio ASPEED_GPIO(AA, 4) GPIO_ACTIVE_HIGH>; - }; - - identify { - label = "platform:blue:indicator"; - gpios = <&gpio ASPEED_GPIO(AA, 7) GPIO_ACTIVE_HIGH>; - }; - - fault { - label = "platform:red:fault"; - gpios = <&gpio ASPEED_GPIO(AA, 3) GPIO_ACTIVE_HIGH>; - }; - - attention { - label = "platform:yellow:alarm"; - gpios = <&gpio ASPEED_GPIO(AA, 1) GPIO_ACTIVE_HIGH>; - }; - }; - - fsi: gpio-fsi { - compatible = "aspeed,ast2500-cf-fsi-master", "fsi-master"; - #address-cells = <2>; - #size-cells = <0>; - no-gpio-delays; - - memory-region = <&coldfire_memory>; - aspeed,sram = <&sram>; - aspeed,cvic = <&cvic>; - - clock-gpios = <&gpio ASPEED_GPIO(AA, 0) GPIO_ACTIVE_HIGH>; - data-gpios = <&gpio ASPEED_GPIO(AA, 2) GPIO_ACTIVE_HIGH>; - mux-gpios = <&gpio ASPEED_GPIO(A, 6) GPIO_ACTIVE_HIGH>; - enable-gpios = <&gpio ASPEED_GPIO(D, 0) GPIO_ACTIVE_HIGH>; - trans-gpios = <&gpio ASPEED_GPIO(P, 1) GPIO_ACTIVE_HIGH>; - }; - - gpio-keys { - compatible = "gpio-keys"; - - checkstop { - label = "checkstop"; - gpios = <&gpio ASPEED_GPIO(J, 2) GPIO_ACTIVE_LOW>; - linux,code = <ASPEED_GPIO(J, 2)>; - }; - }; - - iio-hwmon-battery { - compatible = "iio-hwmon"; - io-channels = <&adc 12>; - }; -}; - -&fmc { - status = "okay"; - flash@0 { - status = "okay"; - m25p,fast-read; - label = "bmc"; - spi-max-frequency = <50000000>; -#include "openbmc-flash-layout.dtsi" - }; -}; - -&spi1 { - status = "okay"; - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_spi1_default>; - - flash@0 { - status = "okay"; - m25p,fast-read; - label = "pnor"; - spi-max-frequency = <100000000>; - }; -}; - -&lpc_ctrl { - status = "okay"; - memory-region = <&flash_memory>; - flash = <&spi1>; -}; - -&uart1 { - /* Rear RS-232 connector */ - status = "okay"; - - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_txd1_default - &pinctrl_rxd1_default - &pinctrl_nrts1_default - &pinctrl_ndtr1_default - &pinctrl_ndsr1_default - &pinctrl_ncts1_default - &pinctrl_ndcd1_default - &pinctrl_nri1_default>; -}; - -&uart5 { - status = "okay"; -}; - -&mac0 { - status = "okay"; - - use-ncsi; - - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_rmii1_default>; - clocks = <&syscon ASPEED_CLK_GATE_MAC1CLK>, - <&syscon ASPEED_CLK_MAC1RCLK>; - clock-names = "MACCLK", "RCLK"; -}; - -&i2c0 { - status = "okay"; - - eeprom@50 { - compatible = "atmel,24c256"; - reg = <0x50>; - pagesize = <64>; - }; -}; - -&i2c2 { - status = "okay"; - /* CPU0 characterization connector */ -}; - -&i2c3 { - status = "okay"; - /* CLK GEN SI5338 */ -}; - -&i2c4 { - status = "okay"; - /* Voltage regulators for CPU0 */ -}; - -&i2c5 { - status = "okay"; - /* Voltage regulators for CPU1 */ -}; - -&i2c6 { - status = "okay"; - - rtc@32 { - compatible = "epson,rx8900"; - reg = <0x32>; - }; -}; - -&i2c7 { - status = "okay"; - /* CPLD */ -}; - -&gpio { - gpio-line-names = - /*A0-A7*/ "","cfam-reset","","","","","fsi-mux","", - /*B0-B7*/ "","","","","","","","", - /*C0-C7*/ "","","","","","","","", - /*D0-D7*/ "fsi-enable","bmc_power_up","sys_pwrok_buf", - "func_mode0","func_mode1","func_mode2","","", - /*E0-E7*/ "","ncsi_cfg","","","","","","", - /*F0-F7*/ "","","","","","","","", - /*G0-G7*/ "","","","","","","","", - /*H0-H7*/ "","","","","","","","", - /*I0-I7*/ "","","","","","","","", - /*J0-J7*/ "","","checkstop","","","","","", - /*K0-K7*/ "","","","","","","","", - /*L0-L7*/ "","","","","","","","", - /*M0-M7*/ "","","","","","","","", - /*N0-N7*/ "","","","","","","","", - /*O0-O7*/ "","","power-button","","","","","", - /*P0-P7*/ "","fsi-trans","pm_rtc_adc_en","","","","","", - /*Q0-Q7*/ "","","","","","","","id-button", - /*R0-R7*/ "","software_pwrgood","","","","","","", - /*S0-S7*/ "","","","","","","","seq_cont", - /*T0-T7*/ "","","","","","","","", - /*U0-U7*/ "","","","","","","","", - /*V0-V7*/ "","","","","","","","", - /*W0-W7*/ "","","","","","","","", - /*X0-X7*/ "","","","","","","","", - /*Y0-Y7*/ "","","","","","","","", - /*Z0-Z7*/ "","","","","","","","", - /*AA0-AA7*/ "fsi-clock","led-attention","fsi-data","led-fault", - "led-power","","","led-identify", - /*AB0-AB7*/ "","","","","","","","", - /*AC0-AC7*/ "","","","","","","",""; - - func_mode0 { - gpio-hog; - gpios = <ASPEED_GPIO(D, 3) GPIO_ACTIVE_HIGH>; - output-low; - }; - func_mode1 { - gpio-hog; - gpios = <ASPEED_GPIO(D, 4) GPIO_ACTIVE_HIGH>; - output-low; - }; - func_mode2 { - gpio-hog; - gpios = <ASPEED_GPIO(D, 5) GPIO_ACTIVE_HIGH>; - output-low; - }; - seq_cont { - gpio-hog; - gpios = <ASPEED_GPIO(S, 7) GPIO_ACTIVE_HIGH>; - output-low; - }; - ncsi_cfg { - gpio-hog; - input; - gpios = <ASPEED_GPIO(E, 1) GPIO_ACTIVE_HIGH>; - }; -}; - -&vuart { - status = "okay"; -}; - -&gfx { - status = "okay"; - memory-region = <&gfx_memory>; -}; - -&pinctrl { - aspeed,external-nodes = <&gfx &lhc>; -}; - -&ibt { - status = "okay"; -}; - -&vhub { - status = "okay"; -}; - -&adc { - status = "okay"; - - pinctrl-names = "default"; - pinctrl-0 = <&pinctrl_adc0_default - &pinctrl_adc1_default - &pinctrl_adc2_default - &pinctrl_adc3_default - &pinctrl_adc4_default - &pinctrl_adc5_default - &pinctrl_adc6_default - &pinctrl_adc7_default - &pinctrl_adc8_default - &pinctrl_adc9_default - &pinctrl_adc10_default - &pinctrl_adc11_default - &pinctrl_adc12_default - &pinctrl_adc13_default - &pinctrl_adc14_default - &pinctrl_adc15_default>; -}; - -&video { - status = "okay"; - memory-region = <&video_engine_memory>; -}; - -#include "ibm-power9-dual.dtsi" diff --git a/meta-yadro/meta-nicole/recipes-kernel/linux/linux-aspeed_%.bbappend b/meta-yadro/meta-nicole/recipes-kernel/linux/linux-aspeed_%.bbappend index bf06fe23f..c34909d04 100644 --- a/meta-yadro/meta-nicole/recipes-kernel/linux/linux-aspeed_%.bbappend +++ b/meta-yadro/meta-nicole/recipes-kernel/linux/linux-aspeed_%.bbappend @@ -1,13 +1,4 @@ FILESEXTRAPATHS_prepend_nicole := "${THISDIR}/${PN}:" SRC_URI += "file://nicole.cfg \ - file://arch \ file://0001-Add-NCSI-channel-selector.patch \ " - -# Merge source tree by original project with our layer of additional files -do_add_vesnin_files () { - cp -r "${WORKDIR}/arch" \ - "${STAGING_KERNEL_DIR}" -} -addtask do_add_vesnin_files after do_kernel_checkout before do_patch - diff --git a/meta-yadro/meta-nicole/recipes-phosphor/cli/obmc-yadro-cli_%.bbappend b/meta-yadro/meta-nicole/recipes-phosphor/cli/obmc-yadro-cli_%.bbappend new file mode 100644 index 000000000..760a12aa9 --- /dev/null +++ b/meta-yadro/meta-nicole/recipes-phosphor/cli/obmc-yadro-cli_%.bbappend @@ -0,0 +1,10 @@ +RDEPENDS_${PN}_append = " \ + obmc-yadro-backup \ + obmc-yadro-lsinventory \ + op-proc-control \ + openpower-esel-parser \ + phosphor-debug-collector \ + phosphor-led-manager-ledmanager \ + phosphor-mapper \ + phosphor-state-manager \ +" diff --git a/meta-yadro/meta-nicole/recipes-phosphor/configuration/nicole-yaml-config/nicole-ipmi-sensors.yaml b/meta-yadro/meta-nicole/recipes-phosphor/configuration/nicole-yaml-config/nicole-ipmi-sensors.yaml index 2c056f9a1..20b3a4ea2 100644 --- a/meta-yadro/meta-nicole/recipes-phosphor/configuration/nicole-yaml-config/nicole-ipmi-sensors.yaml +++ b/meta-yadro/meta-nicole/recipes-phosphor/configuration/nicole-yaml-config/nicole-ipmi-sensors.yaml @@ -189,14 +189,14 @@ Value: Offsets: 255: - type: int64_t + type: double multiplierM: 5 mutability: Mutability::Write|Mutability::Read offsetB: 0 path: /xyz/openbmc_project/sensors/temperature/dimm0_temp rExp: -1 readingType: readingData - scale: -3 + scale: 0 sensorNamePattern: nameLeaf sensorReadingType: 1 sensorType: 1 @@ -490,14 +490,14 @@ Value: Offsets: 255: - type: int64_t + type: double multiplierM: 5 mutability: Mutability::Write|Mutability::Read offsetB: 0 path: /xyz/openbmc_project/sensors/temperature/p0_core0_temp rExp: -1 readingType: readingData - scale: -3 + scale: 0 sensorNamePattern: nameLeaf sensorReadingType: 1 sensorType: 1 diff --git a/meta-yadro/meta-nicole/recipes-phosphor/host/op-proc-control/0001-Stop-and-send-SRESET-for-one-thread-only.patch b/meta-yadro/meta-nicole/recipes-phosphor/host/op-proc-control/0001-Stop-and-send-SRESET-for-one-thread-only.patch new file mode 100644 index 000000000..c763e67de --- /dev/null +++ b/meta-yadro/meta-nicole/recipes-phosphor/host/op-proc-control/0001-Stop-and-send-SRESET-for-one-thread-only.patch @@ -0,0 +1,60 @@ +From 53241d7be35fba23079504468090d770d4116831 Mon Sep 17 00:00:00 2001 +From: Artem Senichev <a.senichev@yadro.com> +Date: Tue, 28 Jul 2020 17:38:17 +0300 +Subject: [PATCH] Stop and send SRESET for one thread only + +Fixes bugs preventing the host from creating a crash dump. + +Stopping all threads leads to errors in skiboot: +[ 163.237293219,3] Could not stop thread 0:0:1: Thread is quiesced already. +If the kernel has xmon support, exiting the debugger causes the kernel +to hang: +[ 235.694220] watchdog: CPU 97 TB:187362511366, last heartbeat TB:159120095297 (55160ms ago) +[ 235.694276] watchdog: CPU 101 Hard LOCKUP + +Sending SRESET to all threads causes kernel panic: +[ 50.495727] Kernel panic - not syncing: Unrecoverable nested System Reset + +Signed-off-by: Artem Senichev <a.senichev@yadro.com> +--- + nmi_interface.cpp | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff --git a/nmi_interface.cpp b/nmi_interface.cpp +index fcce451..d022d7e 100644 +--- a/nmi_interface.cpp ++++ b/nmi_interface.cpp +@@ -38,7 +38,7 @@ void NMI::nMI() + using InternalFailure = + sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure; + +- struct pdbg_target* target; ++ struct pdbg_target* target = nullptr; + + pdbg_for_each_class_target("thread", target) + { +@@ -51,11 +51,19 @@ void NMI::nMI() + report<InternalFailure>(); + return; + } ++ break; + } + +- if (thread_sreset_all() < 0) ++ if (!target) + { +- log<level::ERR>("Failed to sreset all threads"); ++ log<level::ERR>("Thread not found"); ++ report<InternalFailure>(); ++ return; ++ } ++ ++ if (thread_sreset(target) < 0) ++ { ++ log<level::ERR>("Failed to sreset thread"); + report<InternalFailure>(); + } + } +-- +2.27.0 + diff --git a/meta-yadro/meta-nicole/recipes-phosphor/host/op-proc-control_%.bbappend b/meta-yadro/meta-nicole/recipes-phosphor/host/op-proc-control_%.bbappend new file mode 100644 index 000000000..ed1cec767 --- /dev/null +++ b/meta-yadro/meta-nicole/recipes-phosphor/host/op-proc-control_%.bbappend @@ -0,0 +1,2 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" +SRC_URI += "file://0001-Stop-and-send-SRESET-for-one-thread-only.patch" diff --git a/meta-yadro/meta-nicole/recipes-phosphor/images/obmc-phosphor-image.bbappend b/meta-yadro/meta-nicole/recipes-phosphor/images/obmc-phosphor-image.bbappend index 8f69024d1..75dc1399a 100644 --- a/meta-yadro/meta-nicole/recipes-phosphor/images/obmc-phosphor-image.bbappend +++ b/meta-yadro/meta-nicole/recipes-phosphor/images/obmc-phosphor-image.bbappend @@ -1,8 +1,8 @@ OBMC_IMAGE_EXTRA_INSTALL_append = " \ admin-account \ first-boot-set-hostname \ - first-boot-set-mac \ mboxd \ obmc-yadro-cli \ openpower-fru-vpd \ " +IMAGE_FEATURES_remove_nicole = "obmc-user-mgmt-ldap" diff --git a/meta-yadro/meta-nicole/recipes-phosphor/interfaces/bmcweb_%.bbappend b/meta-yadro/meta-nicole/recipes-phosphor/interfaces/bmcweb_%.bbappend new file mode 100644 index 000000000..0f663ddc0 --- /dev/null +++ b/meta-yadro/meta-nicole/recipes-phosphor/interfaces/bmcweb_%.bbappend @@ -0,0 +1,3 @@ +EXTRA_OECMAKE_append = " \ + -DBMCWEB_ENABLE_MUTUAL_TLS_AUTHENTICATION=OFF \ +" diff --git a/meta-yadro/meta-nicole/recipes-phosphor/ipmi/phosphor-ipmi-config.bbappend b/meta-yadro/meta-nicole/recipes-phosphor/ipmi/phosphor-ipmi-config.bbappend new file mode 100644 index 000000000..466f42f0b --- /dev/null +++ b/meta-yadro/meta-nicole/recipes-phosphor/ipmi/phosphor-ipmi-config.bbappend @@ -0,0 +1,21 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" + +inherit systemd + +RDEPENDS_${PN} = "${VIRTUAL-RUNTIME_base-utils}" +SYSTEMD_SERVICE_${PN} = "${BPN}.service" +SRC_URI_append = " \ + file://${BPN}-set-device-id.sh \ + file://${BPN}.service \ +" + +S = "${WORKDIR}" +do_install_append() { + install -d ${D}${bindir} ${D}${systemd_system_unitdir} + install ${BPN}-set-device-id.sh ${D}${bindir}/ + install -m 0644 ${BPN}.service ${D}${systemd_system_unitdir}/ +} + +FILES_${PN}_append = " \ + ${bindir}/${BPN}-set-device-id.sh \ +" diff --git a/meta-yadro/meta-nicole/recipes-phosphor/ipmi/phosphor-ipmi-config/channel_config.json b/meta-yadro/meta-nicole/recipes-phosphor/ipmi/phosphor-ipmi-config/channel_config.json new file mode 100644 index 000000000..63e1fa7e3 --- /dev/null +++ b/meta-yadro/meta-nicole/recipes-phosphor/ipmi/phosphor-ipmi-config/channel_config.json @@ -0,0 +1,178 @@ +{ + "0" : { + "name" : "IPMB", + "is_valid" : true, + "active_sessions" : 0, + "channel_info" : { + "medium_type" : "ipmb", + "protocol_type" : "ipmb-1.0", + "session_supported" : "session-less", + "is_ipmi" : true + } + }, + "1" : { + "name" : "eth0", + "is_valid" : true, + "active_sessions" : 0, + "channel_info" : { + "medium_type" : "lan-802.3", + "protocol_type" : "ipmb-1.0", + "session_supported" : "multi-session", + "is_ipmi" : true + } + }, + "2" : { + "name" : "RESERVED", + "is_valid" : false, + "active_sessions" : 0, + "channel_info" : { + "medium_type" : "lan-802.3", + "protocol_type" : "ipmb-1.0", + "session_supported" : "multi-session", + "is_ipmi" : true + } + }, + "3" : { + "name" : "RESERVED", + "is_valid" : false, + "active_sessions" : 0, + "channel_info" : { + "medium_type" : "reserved", + "protocol_type" : "na", + "session_supported" : "session-less", + "is_ipmi" : true + } + }, + "4" : { + "name" : "RESERVED", + "is_valid" : false, + "active_sessions" : 0, + "channel_info" : { + "medium_type" : "reserved", + "protocol_type" : "na", + "session_supported" : "session-less", + "is_ipmi" : true + } + }, + "5" : { + "name" : "RESERVED", + "is_valid" : false, + "active_sessions" : 0, + "channel_info" : { + "medium_type" : "reserved", + "protocol_type" : "na", + "session_supported" : "session-less", + "is_ipmi" : true + } + }, + "6" : { + "name" : "RESERVED", + "is_valid" : false, + "active_sessions" : 0, + "channel_info" : { + "medium_type" : "reserved", + "protocol_type" : "na", + "session_supported" : "session-less", + "is_ipmi" : true + } + }, + "7" : { + "name" : "RESERVED", + "is_valid" : false, + "active_sessions" : 0, + "channel_info" : { + "medium_type" : "reserved", + "protocol_type" : "na", + "session_supported" : "session-less", + "is_ipmi" : true + } + }, + "8" : { + "name" : "RESERVED", + "is_valid" : false, + "active_sessions" : 0, + "channel_info" : { + "medium_type" : "oem", + "protocol_type" : "oem", + "session_supported" : "session-less", + "is_ipmi" : true + } + }, + "9" : { + "name" : "RESERVED", + "is_valid" : false, + "active_sessions" : 0, + "channel_info" : { + "medium_type" : "reserved", + "protocol_type" : "na", + "session_supported" : "session-less", + "is_ipmi" : true + } + }, + "10" : { + "name" : "RESERVED", + "is_valid" : false, + "active_sessions" : 0, + "channel_info" : { + "medium_type" : "reserved", + "protocol_type" : "na", + "session_supported" : "session-less", + "is_ipmi" : true + } + }, + "11" : { + "name" : "RESERVED", + "is_valid" : false, + "active_sessions" : 0, + "channel_info" : { + "medium_type" : "reserved", + "protocol_type" : "na", + "session_supported" : "session-less", + "is_ipmi" : true + } + }, + "12" : { + "name" : "RESERVED", + "is_valid" : false, + "active_sessions" : 0, + "channel_info" : { + "medium_type" : "reserved", + "protocol_type" : "na", + "session_supported" : "session-less", + "is_ipmi" : true + } + }, + "13" : { + "name" : "RESERVED", + "is_valid" : false, + "active_sessions" : 0, + "channel_info" : { + "medium_type" : "reserved", + "protocol_type" : "na", + "session_supported" : "session-less", + "is_ipmi" : true + } + }, + "14" : { + "name" : "SELF", + "is_valid" : true, + "active_sessions" : 0, + "channel_info" : { + "medium_type" : "ipmb", + "protocol_type" : "ipmb-1.0", + "session_supported" : "session-less", + "is_ipmi" : true + } + }, + "15" : { + "name" : "SMS", + "is_valid" : true, + "active_sessions" : 0, + "channel_info" : { + "medium_type" : "system-interface", + "protocol_type" : "kcs", + "session_supported" : "session-less", + "is_ipmi" : true + } + } +} diff --git a/meta-yadro/meta-nicole/recipes-phosphor/ipmi/phosphor-ipmi-config/dev_id.json b/meta-yadro/meta-nicole/recipes-phosphor/ipmi/phosphor-ipmi-config/dev_id.json new file mode 100644 index 000000000..9cad55573 --- /dev/null +++ b/meta-yadro/meta-nicole/recipes-phosphor/ipmi/phosphor-ipmi-config/dev_id.json @@ -0,0 +1,7 @@ +{ + "id": 0, + "revision": 1, + "addn_dev_support": 0, + "manuf_id": 49769, + "prod_id": 11 +} diff --git a/meta-yadro/meta-nicole/recipes-phosphor/ipmi/phosphor-ipmi-config/phosphor-ipmi-config-set-device-id.sh b/meta-yadro/meta-nicole/recipes-phosphor/ipmi/phosphor-ipmi-config/phosphor-ipmi-config-set-device-id.sh new file mode 100755 index 000000000..6600ced4a --- /dev/null +++ b/meta-yadro/meta-nicole/recipes-phosphor/ipmi/phosphor-ipmi-config/phosphor-ipmi-config-set-device-id.sh @@ -0,0 +1,5 @@ +#!/bin/sh -eu + +BMCPOS=$(awk -v RS=" " '/^bmcposition=/{print substr($0,13)}' /proc/cmdline) +sed -r "s/\"id\"\s*:\s*[0-9]+\s*,/\"id\": ${BMCPOS:-0},/" -i \ + /usr/share/ipmi-providers/dev_id.json diff --git a/meta-yadro/meta-nicole/recipes-phosphor/ipmi/phosphor-ipmi-config/phosphor-ipmi-config.service b/meta-yadro/meta-nicole/recipes-phosphor/ipmi/phosphor-ipmi-config/phosphor-ipmi-config.service new file mode 100644 index 000000000..647138054 --- /dev/null +++ b/meta-yadro/meta-nicole/recipes-phosphor/ipmi/phosphor-ipmi-config/phosphor-ipmi-config.service @@ -0,0 +1,12 @@ +[Unit] +Description=Set DeviceID for ipmi-host +Before=phosphor-ipmi-host.service + +[Service] +Type=oneshot +TimeoutSec=0 +RemainAfterExit=yes +ExecStart=/usr/bin/env phosphor-ipmi-config-set-device-id.sh + +[Install] +RequiredBy=phosphor-ipmi-host.service diff --git a/meta-yadro/meta-nicole/recipes-phosphor/network/first-boot-set-mac_%.bbappend b/meta-yadro/meta-nicole/recipes-phosphor/network/first-boot-set-mac_%.bbappend deleted file mode 100644 index 29d23c8c4..000000000 --- a/meta-yadro/meta-nicole/recipes-phosphor/network/first-boot-set-mac_%.bbappend +++ /dev/null @@ -1 +0,0 @@ -SYSTEMD_SERVICE_${PN} += "first-boot-set-mac@eth0.service" diff --git a/meta-yadro/meta-nicole/recipes-phosphor/network/phosphor-network/config.json b/meta-yadro/meta-nicole/recipes-phosphor/network/phosphor-network/config.json new file mode 100644 index 000000000..52280a4e6 --- /dev/null +++ b/meta-yadro/meta-nicole/recipes-phosphor/network/phosphor-network/config.json @@ -0,0 +1,3 @@ +{ + "eth0":"ethernet" +} diff --git a/meta-yadro/meta-nicole/recipes-phosphor/network/phosphor-network_%.bbappend b/meta-yadro/meta-nicole/recipes-phosphor/network/phosphor-network_%.bbappend new file mode 100644 index 000000000..e71ba71a3 --- /dev/null +++ b/meta-yadro/meta-nicole/recipes-phosphor/network/phosphor-network_%.bbappend @@ -0,0 +1,10 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" + +EXTRA_OECONF_append = " --enable-sync-mac " +SRC_URI_append = " file://config.json " +FILES_${PN} += "${datadir}/network/*.json" + +do_install_append() { + install -d ${D}${datadir}/network/ + install -m 0644 ${WORKDIR}/config.json ${D}${datadir}/network/ +} diff --git a/meta-yadro/meta-nicole/recipes-phosphor/packagegroups/packagegroup-obmc-apps.bbappend b/meta-yadro/meta-nicole/recipes-phosphor/packagegroups/packagegroup-obmc-apps.bbappend index 26e64be50..61bf12e06 100644 --- a/meta-yadro/meta-nicole/recipes-phosphor/packagegroups/packagegroup-obmc-apps.bbappend +++ b/meta-yadro/meta-nicole/recipes-phosphor/packagegroups/packagegroup-obmc-apps.bbappend @@ -1,10 +1,7 @@ RDEPENDS_${PN}-inventory_append = " openpower-occ-control" RDEPENDS_${PN}-extras_append = " \ phosphor-hostlogger \ - openpower-esel-parser \ - obmc-yadro-lssensors \ " RDEPENDS_${PN}-software_append = " \ obmc-yadro-fwupdate \ - phosphor-image-signing \ " diff --git a/meta-yadro/meta-nicole/recipes-phosphor/sensors/phosphor-hwmon/obmc/hwmon/iio-hwmon-battery.conf b/meta-yadro/meta-nicole/recipes-phosphor/sensors/phosphor-hwmon/obmc/hwmon/iio-hwmon-battery.conf index 290a72252..a6065805c 100644 --- a/meta-yadro/meta-nicole/recipes-phosphor/sensors/phosphor-hwmon/obmc/hwmon/iio-hwmon-battery.conf +++ b/meta-yadro/meta-nicole/recipes-phosphor/sensors/phosphor-hwmon/obmc/hwmon/iio-hwmon-battery.conf @@ -1,5 +1,5 @@ LABEL_in1=vbat -GAIN_in1=2.25 +GAIN_in1=0.00225 # GPIOP2 needs to be pulled high for battery voltage reading GPIOCHIP_in1=0 diff --git a/meta-yadro/meta-nicole/recipes-phosphor/settings/phosphor-settings-manager/bootmailbox.override.yml b/meta-yadro/meta-nicole/recipes-phosphor/settings/phosphor-settings-manager/bootmailbox.override.yml new file mode 100644 index 000000000..e4e5745f4 --- /dev/null +++ b/meta-yadro/meta-nicole/recipes-phosphor/settings/phosphor-settings-manager/bootmailbox.override.yml @@ -0,0 +1,16 @@ +--- +/xyz/openbmc_project/control/host0/boot/mailbox: + - Interface: xyz.openbmc_project.Control.Boot.Mailbox + Properties: + Supported: + Default: 'true' + IANAEnterpriseNumber: + # This is IBM's IANA Enterprise number expected by petitboot + Default: 2 + Data: + # The mailbox must be no smaller that 5 blocks. That is 80 bytes. + # This array does NOT include the 3-byte IANA enterprise number. + # So the minimum is 77 bytes. 512 bytes look enough to accomodate + # all boot settings, yet not too big to waste space. + # 512 - 3 = 509 + Default: 'std::vector<uint8_t>(509)' diff --git a/meta-yadro/meta-nicole/recipes-phosphor/settings/phosphor-settings-manager/time-sync-method.override.yml b/meta-yadro/meta-nicole/recipes-phosphor/settings/phosphor-settings-manager/time-sync-method.override.yml new file mode 100644 index 000000000..696919e9e --- /dev/null +++ b/meta-yadro/meta-nicole/recipes-phosphor/settings/phosphor-settings-manager/time-sync-method.override.yml @@ -0,0 +1,5 @@ +/xyz/openbmc_project/time/sync_method: + - Interface: xyz.openbmc_project.Time.Synchronization + Properties: + TimeSyncMethod: + Default: Synchronization::Method::Manual diff --git a/meta-yadro/meta-nicole/recipes-phosphor/settings/phosphor-settings-manager_%.bbappend b/meta-yadro/meta-nicole/recipes-phosphor/settings/phosphor-settings-manager_%.bbappend new file mode 100644 index 000000000..848bf4e5b --- /dev/null +++ b/meta-yadro/meta-nicole/recipes-phosphor/settings/phosphor-settings-manager_%.bbappend @@ -0,0 +1,5 @@ +FILESEXTRAPATHS_prepend_nicole := "${THISDIR}/${PN}:" +SRC_URI_append_nicole = " \ + file://bootmailbox.override.yml \ + file://time-sync-method.override.yml \ +" diff --git a/meta-yadro/meta-nicole/recipes-phosphor/users/admin-account.bb b/meta-yadro/meta-nicole/recipes-phosphor/users/admin-account.bb index d94952e1f..c6be7e067 100644 --- a/meta-yadro/meta-nicole/recipes-phosphor/users/admin-account.bb +++ b/meta-yadro/meta-nicole/recipes-phosphor/users/admin-account.bb @@ -18,14 +18,12 @@ GROUP_ADMIN = "priv-admin" GROUP_OPERATOR = "priv-operator" GROUP_USER = "priv-user" GROUP_IPMI = "ipmi" -GROUP_SUDO = "sudo" # Default administrative account (login: admin, password: admin) ADMIN_LOGIN = "admin" ADMIN_PASSW = "\$1\$Fze0kFe8\$sylEANC01t.osF8OewyB/1" USERADD_PACKAGES = "${PN}" -USERADD_PARAM_${PN} = "--gid ${GROUP_ADMIN} \ - --groups ${GROUP_ADMIN},${GROUP_OPERATOR},${GROUP_USER},${GROUP_IPMI},${GROUP_SUDO} \ +USERADD_PARAM_${PN} = "--groups ${GROUP_ADMIN},${GROUP_IPMI} \ --password '${ADMIN_PASSW}' \ ${ADMIN_LOGIN}" diff --git a/meta-yadro/recipes-core/base-files/base-files%.bbappend b/meta-yadro/recipes-core/base-files/base-files%.bbappend new file mode 100644 index 000000000..48c80e96d --- /dev/null +++ b/meta-yadro/recipes-core/base-files/base-files%.bbappend @@ -0,0 +1,7 @@ +do_install_basefilesissue () { + if [ "${hostname}" ]; then + echo ${hostname} > ${D}${sysconfdir}/hostname + fi + + # Issue files are provided by os-release recipe instead +} diff --git a/meta-yadro/recipes-core/os-release/os-release.bbappend b/meta-yadro/recipes-core/os-release/os-release.bbappend new file mode 100644 index 000000000..ae1e95552 --- /dev/null +++ b/meta-yadro/recipes-core/os-release/os-release.bbappend @@ -0,0 +1,129 @@ +# This recipe append assumes that all YADRO branches follow the +# <type>/<product>/<description> convention, or are either +# "merge/upstream" or "master" e.g.: +# +# release/nicole/v1 +# feature/vesnin/some-feature +# merge/upstream +# master +# +# Release branches (release/<machine>/vX) are expected to be forked off +# the master branch and may contain tags in the form +# <machine>-vX.Y[-rcZ|-dev*]. All release branches without machine tags, +# as well as any non-release branches produce 'Unofficial' builds. +# So do the release branches with -rc or -dev suffix in the latest tag. + +python do_compile_prepend() { + print ("Preparing YADRO-specific version information") + version_id = d.getVar('VERSION_ID') + + print ('Original VERSION_ID = %s' % version_id) + + versionList = version_id.split('-') + + branch_info = run_git(d, 'rev-parse --abbrev-ref HEAD').split('/') + branch_type = branch_info[0] + + if len(branch_info) > 1: + branch_product = branch_info[1] + else: + branch_product = d.getVar('MACHINE', True).split('-')[0] + + if len(branch_info) > 2: + # This is for <type>/<product>/<description> branches + # and <type>/<product>/<any>/<level>/<of>/<hierarchy> branches alike + branch_name = '-'.join(branch_info[2::]) + else: + # This is for "merge/upstream", "master" and any arbitrary branches + branch_name = '-'.join(branch_info) + + print ('Branch type = %s' % branch_type) + print ('Branch product = %s' % branch_product) + print ('Branch name = %s' % branch_name) + + # For <product>-vX.Y tags, simply strip off the '<product>-' part, + # then pretend it is a normal version tag + product_tagged = False + if branch_product == versionList[0]: + product_tagged = True + versionList.pop(0) + + version = versionList[0] if len(versionList) > 0 else '' + if versionList[1][:2] == 'rc' or versionList[1] == 'dev': # Remove the '-rcX' and '-dev' parts + rcdev = versionList[1] + versionList.pop(1) + patch_level = versionList[1] if len(versionList) > 1 else 0 + git_hash = versionList[2] if len(versionList) > 2 else 'nongit' + dirty = ('dirty' == versionList[3]) if len(versionList) > 3 else 0 + + # For release branches: + if 'release' == branch_type: + flag = '' + if not product_tagged: + # If there is no tag, take branch name for the major version + # and assume the minor version to be 0, patch level will + # represent the number of commits since branch creation + # (assuming that it branched off the master branch) + patch_level = run_git(d, 'rev-list --count origin/master..%s' + % '/'.join(branch_info)) + # Prevent zero patch level. Zero patch level is an official release. + patch_level = str(int(patch_level) + 1) + version = branch_name.split('-')[0] + version += '.0' + # Any build from a release/<product>/* branch without a <product>-* tag + # is not an official release + release = 'Unofficial ' + branch_name + flag = '-unofficial' + else: + # If there is a product tag, then it is used as the normal tag to + # designate the major and minor version, patch level is as usual + # the number of commits since the tag. + release = version + if (rcdev): + flag = '-' + rcdev + release += flag + # Official releases happen only exactly on tags, without extra + # commits. Release candidates and development releases are also + # not considered 'official' + if int(patch_level) or rcdev: + release = 'Unofficial ' + release + flag += '-unofficial' + + version_id = version + version_id += 'r' + git_hash[1:7] + version_id += ('p' + patch_level) if int(patch_level) else '' + version_id += flag + version_id += '-dirty' if dirty else '' + name = 'YADRO %s BMC Firmware' + else: + version_id += ("-" + branch_name) if (branch_name) else '' + release = version_id + name = 'YADRO %s BMC Development Firmware' + + u_product = branch_product.upper() + + d.setVar('VERSION_ID', version_id) + d.setVar('VERSION', version) + d.setVar('RELEASE', release) + d.setVar('PATCH_LEVEL', patch_level) + d.setVar('NAME', '%s' % (name % u_product)) + d.setVar('PRETTY_NAME', '%s %s' % (name % u_product, release)) + + print ('%s VERSION_ID = %s' % (u_product, version_id)) + print ('%s RELEASE = %s' % (u_product, release)) + print ('%s PATCH_LEVEL = %s' % (u_product, patch_level)) +} + +python do_compile_append () { + with open(d.expand('${B}/issue'), 'w') as f: + f.write('%s %s @ \\l\n' % (name % u_product, release)) +} + +do_install_append () { + install -m 0644 issue ${D}${sysconfdir}/issue + install -m 0644 issue ${D}${sysconfdir}/issue.net +} + +CONFFILES_${PN} += " ${sysconfdir}/issue ${sysconfdir}/issue.net" +OS_RELEASE_FIELDS_append = " RELEASE PATCH_LEVEL" +BB_DONT_CACHE = "1" diff --git a/meta-yadro/recipes-phosphor/cli/obmc-yadro-backup_git.bb b/meta-yadro/recipes-phosphor/cli/obmc-yadro-backup_git.bb new file mode 100644 index 000000000..c101d837c --- /dev/null +++ b/meta-yadro/recipes-phosphor/cli/obmc-yadro-backup_git.bb @@ -0,0 +1,16 @@ +SUMMARY = "Command line tool for backup configuration" +DESCRIPTION = "YADRO OpenBMC command line tool for backup and restore configuration" +HOMEPAGE = "https://github.com/YADRO-KNS/obmc-yadro-backup" +PR = "r1" +PV = "1.0+git${SRCPV}" + +inherit meson + +# License info +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=86d3f3a95c324c9479bd8986968f4327" + +# Source code repository +S = "${WORKDIR}/git" +SRC_URI = "git://github.com/YADRO-KNS/obmc-yadro-backup.git" +SRCREV = "dd29c8bdc222de004284faba37d278f8c443b531" diff --git a/meta-yadro/meta-nicole/recipes-phosphor/cli/obmc-yadro-cli_git.bb b/meta-yadro/recipes-phosphor/cli/obmc-yadro-cli_git.bb index 0f1bc3aad..1cdecb07c 100644 --- a/meta-yadro/meta-nicole/recipes-phosphor/cli/obmc-yadro-cli_git.bb +++ b/meta-yadro/recipes-phosphor/cli/obmc-yadro-cli_git.bb @@ -10,16 +10,28 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=86d3f3a95c324c9479bd8986968f4327" # Dependencies DEPENDS = "phosphor-user-manager" -RDEPENDS_${PN} = "sudo bash" +RDEPENDS_${PN} = " \ + ${VIRTUAL-RUNTIME_base-utils} \ + bash \ + obmc-console \ + obmc-yadro-fwupdate \ + obmc-yadro-lssensors \ + obmc-yadro-netconfig \ + sudo \ + systemd \ +" +# Some platforms also require some additional packages like +# ipmitool, obmc-yadro-lsinventory, obmc-yadro-backup ... +# They should be appended by bbappend file in their layers -# Besides executable file we also have shared help -FILES_${PN} += "${datadir}/cli.help" +# Directory with command handlers +FILES_${PN} += "${datadir}/cli" # Custom installation procedure do_install() { ${B}/install.sh \ --dir ${D} \ - --machine ${MACHINE} \ + --machine ${@'${MACHINE}'.split('-')[0]} \ --admin priv-admin \ --operator priv-operator \ --user priv-user @@ -28,4 +40,4 @@ do_install() { # Source code repository S = "${WORKDIR}/git" SRC_URI = "git://github.com/YADRO-KNS/obmc-yadro-cli" -SRCREV = "406688be909c702cbaecdf06147dc3b832c37f99" +SRCREV = "9457a085c86722214d6c450397ccecd6db4a1071" diff --git a/meta-yadro/recipes-phosphor/cli/obmc-yadro-fwupdate_git.bb b/meta-yadro/recipes-phosphor/cli/obmc-yadro-fwupdate_git.bb new file mode 100644 index 000000000..90f377bbe --- /dev/null +++ b/meta-yadro/recipes-phosphor/cli/obmc-yadro-fwupdate_git.bb @@ -0,0 +1,27 @@ +SUMMARY = "YADRO Firmware update tool" +DESCRIPTION = "Command line tool for update firmware" +HOMEPAGE = "https://github.com/YADRO-KNS/obmc-yadro-fwupdate" +PR = "r1" +PV = "1.0+git${SRCPV}" +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e" + +inherit meson +inherit pkgconfig + +DEPENDS += " \ + sdbusplus \ + openssl \ +" + +PACKAGECONFIG[obmc-phosphor-image] = "-Dbmc-image-type=obmc-phosphor-image,,,,,intel-platforms" +PACKAGECONFIG[intel-platforms] = "-Dbmc-image-type=intel-platforms,,,,,obmc-phosphor-image" +PACKAGECONFIG[reboot-guard-support] = "-Dreboot-guard-support=true,-Dreboot-guard-support=false" +PACKAGECONFIG[openpower-support] = "-Dopenpower-support=true,-Dopenpower-support=false" + +PACKAGECONFIG ??= " obmc-phosphor-image reboot-guard-support " +PACKAGECONFIG_append_df-openpower = "openpower-support" + +SRC_URI = "git://github.com/YADRO-KNS/obmc-yadro-fwupdate" +SRCREV = "f141bdf92f92971caa4e8e5eb0727821241416e8" +S = "${WORKDIR}/git" diff --git a/meta-yadro/recipes-phosphor/cli/obmc-yadro-lsinventory_git.bb b/meta-yadro/recipes-phosphor/cli/obmc-yadro-lsinventory_git.bb new file mode 100644 index 000000000..89ceb1ee1 --- /dev/null +++ b/meta-yadro/recipes-phosphor/cli/obmc-yadro-lsinventory_git.bb @@ -0,0 +1,22 @@ +SUMMARY = "Command line tool for printing inventory" +DESCRIPTION = "YADRO OpenBMC command line tool for printing inventory list" +HOMEPAGE = "https://github.com/YADRO-KNS/obmc-yadro-lsinventory" +PR = "r1" +PV = "1.0+git${SRCPV}" + +inherit meson + +# License info +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=86d3f3a95c324c9479bd8986968f4327" + +# Dependencies +DEPENDS += " \ + json-c \ + sdbusplus \ + " + +# Source code repository +S = "${WORKDIR}/git" +SRC_URI = "git://github.com/YADRO-KNS/obmc-yadro-lsinventory.git" +SRCREV = "d0bdf0ddd192b9d41c5c5d4af9385122b08c7608" diff --git a/meta-yadro/recipes-phosphor/sensors/obmc-yadro-lssensors_git.bb b/meta-yadro/recipes-phosphor/cli/obmc-yadro-lssensors_git.bb index 55d549500..234d3cdad 100644 --- a/meta-yadro/recipes-phosphor/sensors/obmc-yadro-lssensors_git.bb +++ b/meta-yadro/recipes-phosphor/cli/obmc-yadro-lssensors_git.bb @@ -13,4 +13,4 @@ DEPENDS += "sdbusplus" S = "${WORKDIR}/git" SRC_URI = "git://github.com/YADRO-KNS/obmc-yadro-lssensors.git" -SRCREV = "4f55f0e21c5000d7a9e9c49cc2ad16bc6ba6463e" +SRCREV = "f76bf429d212d803cff7e4f1e3ca21097c65f18f" diff --git a/meta-yadro/recipes-phosphor/cli/obmc-yadro-netconfig_git.bb b/meta-yadro/recipes-phosphor/cli/obmc-yadro-netconfig_git.bb new file mode 100644 index 000000000..e868bbfb4 --- /dev/null +++ b/meta-yadro/recipes-phosphor/cli/obmc-yadro-netconfig_git.bb @@ -0,0 +1,19 @@ +SUMMARY = "Command line tool for configuring network" +DESCRIPTION = "YADRO OpenBMC command line tool for configuring network" +HOMEPAGE = "https://github.com/YADRO-KNS/obmc-yadro-netconfig" +PR = "r1" +PV = "1.0+git${SRCPV}" + +inherit meson + +# License info +LICENSE = "Apache-2.0" +LIC_FILES_CHKSUM = "file://LICENSE;md5=86d3f3a95c324c9479bd8986968f4327" + +# Dependencies +DEPENDS = "sdbusplus" + +# Source code repository +S = "${WORKDIR}/git" +SRC_URI = "git://github.com/YADRO-KNS/obmc-yadro-netconfig.git" +SRCREV = "b300465732616c6d456bdc2df2cce9d1246636a8" diff --git a/meta-yadro/recipes-phosphor/dbus/phosphor-dbus-interfaces/0001-Add-boot-initiator-mailbox-interface.patch b/meta-yadro/recipes-phosphor/dbus/phosphor-dbus-interfaces/0001-Add-boot-initiator-mailbox-interface.patch new file mode 100644 index 000000000..e3da4378a --- /dev/null +++ b/meta-yadro/recipes-phosphor/dbus/phosphor-dbus-interfaces/0001-Add-boot-initiator-mailbox-interface.patch @@ -0,0 +1,138 @@ +From 104027fff5db49d60d2ff7256580b8efb6429a27 Mon Sep 17 00:00:00 2001 +From: Alexander Amelkin <a.amelkin@yadro.com> +Date: Wed, 20 Mar 2019 19:33:00 +0300 +Subject: [PATCH] Add boot initiator mailbox interface + +Add the xyz.openbmc_project.Control.Boot.Mailbox interface to allow +for provision of the boot initiator (such as Petitboot or UEFI) with +its specific parameters. This is based on IPMI 2.0 Table 28-14 'Boot +Option Parameters' parameter 7 'Boot initiator mailbox'. + +Partially resolves openbmc/openbmc#3391 + +Change-Id: If2a7dce6fae812fc3f1f325cd07c77f31900cf42 +Signed-off-by: Alexander Amelkin <a.amelkin@yadro.com> +--- + .../Control/Boot/Mailbox/meson.build | 14 +++++ + .../openbmc_project/Control/Boot/meson.build | 15 +++++ + .../Control/Boot/Mailbox.interface.yaml | 63 +++++++++++++++++++ + 3 files changed, 92 insertions(+) + create mode 100644 gen/xyz/openbmc_project/Control/Boot/Mailbox/meson.build + create mode 100644 xyz/openbmc_project/Control/Boot/Mailbox.interface.yaml + +diff --git a/gen/xyz/openbmc_project/Control/Boot/Mailbox/meson.build b/gen/xyz/openbmc_project/Control/Boot/Mailbox/meson.build +new file mode 100644 +index 0000000..149e68a +--- /dev/null ++++ b/gen/xyz/openbmc_project/Control/Boot/Mailbox/meson.build +@@ -0,0 +1,14 @@ ++# Generated file; do not modify. ++generated_sources += custom_target( ++ 'xyz/openbmc_project/Control/Boot/Mailbox__cpp'.underscorify(), ++ input: [ meson.source_root() / 'xyz/openbmc_project/Control/Boot/Mailbox.interface.yaml', ], ++ output: [ 'server.cpp', 'server.hpp', 'client.hpp', ], ++ command: [ ++ sdbuspp_gen_meson_prog, '--command', 'cpp', ++ '--output', meson.current_build_dir(), ++ '--tool', sdbusplusplus_prog, ++ '--directory', meson.source_root(), ++ 'xyz/openbmc_project/Control/Boot/Mailbox', ++ ], ++) ++ +diff --git a/gen/xyz/openbmc_project/Control/Boot/meson.build b/gen/xyz/openbmc_project/Control/Boot/meson.build +index ba8a19f..6901fc0 100644 +--- a/gen/xyz/openbmc_project/Control/Boot/meson.build ++++ b/gen/xyz/openbmc_project/Control/Boot/meson.build +@@ -1,4 +1,19 @@ + # Generated file; do not modify. ++subdir('Mailbox') ++generated_others += custom_target( ++ 'xyz/openbmc_project/Control/Boot/Mailbox__markdown'.underscorify(), ++ input: [ meson.source_root() / 'xyz/openbmc_project/Control/Boot/Mailbox.interface.yaml', ], ++ output: [ 'Mailbox.md' ], ++ command: [ ++ sdbuspp_gen_meson_prog, '--command', 'markdown', ++ '--output', meson.current_build_dir(), ++ '--tool', sdbusplusplus_prog, ++ '--directory', meson.source_root(), ++ 'xyz/openbmc_project/Control/Boot/Mailbox', ++ ], ++ build_by_default: true, ++) ++ + subdir('Mode') + generated_others += custom_target( + 'xyz/openbmc_project/Control/Boot/Mode__markdown'.underscorify(), +diff --git a/xyz/openbmc_project/Control/Boot/Mailbox.interface.yaml b/xyz/openbmc_project/Control/Boot/Mailbox.interface.yaml +new file mode 100644 +index 0000000..839e8be +--- /dev/null ++++ b/xyz/openbmc_project/Control/Boot/Mailbox.interface.yaml +@@ -0,0 +1,63 @@ ++description: > ++ Implement to provide the boot initiator (such as Petitboot or UEFI) ++ with its specific parameters. This is based on IPMI 2.0 Table 28-14 ++ 'Boot Option Parameters' parameter 7 'Boot initiator mailbox'. ++ ++properties: ++ - name: Supported ++ type: boolean ++ flags: ++ - const ++ default: false ++ description: > ++ Specifies whether or not the mailbox is supported by the ++ boot initiator on this machine. ++ ++ The property is constant and is only set by the implementation ++ on startup. ++ ++ - name: IANAEnterpriseNumber ++ type: uint32 ++ flags: ++ - const ++ default: 0 ++ description: > ++ The 24-bit IANA Private Enterprise Number for the company or organization ++ that has specified the boot initiator. This is a machine-specific ++ constant. The implementing application is responsible for setting ++ this to the proper machine-specific value (0x000000..0xFFFFFF) ++ according to https://www.iana.org/assignments/enterprise-numbers/enterprise-numbers. ++ ++ The property is constant and is only set by the implementation ++ on startup. ++ ++ - name: Data ++ type: array[byte] ++ description: > ++ The array of data bytes for the boot initiator to treat ++ in its specific way. This interface doesn't impose any ++ limitiations on the format or make any assumptions regarding ++ it. The boot initiator is responsible for parsing this array. ++ ++ The size of the array is a constant depending on the requirements ++ set by the boot initiator used for a particular architecture or ++ a machine. The implementing application is responsible for setting ++ the size of this array to the proper value. ++ ++ For conformance to the IPMI 2.0 specification, the size of the array ++ plus 3 (the size of IPMI 2.0 representation of IANA Enterprise Number) ++ must be a multiple of 16 with the minimum allowed size being 77 ++ (5 x 16-byte blocks, minus 3) if mailbox is at all Supported. ++ ++ For IPMI 2.0 this array is supposed to be split into 16-byte ++ blocks by the implementing service (block 0 being made of IANA PEN ++ plus first 13 bytes of this array). Please pay special attention ++ that this array does NOT include the IANA PEN needed for IPMI 2.0. ++ Only the actual PEN-specific data is stored here. ++ ++ When partially written to, the remaining parts of this array ++ must not be automatically cleared. This is per IPMI 2.0 ++ specification. ++ ++ Other interfaces to the boot initiator (such as MCTP) may process ++ this array differently. +-- +2.26.2 + diff --git a/meta-yadro/recipes-phosphor/dbus/phosphor-dbus-interfaces_%.bbappend b/meta-yadro/recipes-phosphor/dbus/phosphor-dbus-interfaces_%.bbappend new file mode 100644 index 000000000..8a5b4c363 --- /dev/null +++ b/meta-yadro/recipes-phosphor/dbus/phosphor-dbus-interfaces_%.bbappend @@ -0,0 +1,5 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" + +SRC_URI_append = "\ + file://0001-Add-boot-initiator-mailbox-interface.patch \ +" diff --git a/meta-yadro/recipes-phosphor/flash/obmc-yadro-fwupdate_git.bb b/meta-yadro/recipes-phosphor/flash/obmc-yadro-fwupdate_git.bb deleted file mode 100644 index ae2f7c97a..000000000 --- a/meta-yadro/recipes-phosphor/flash/obmc-yadro-fwupdate_git.bb +++ /dev/null @@ -1,22 +0,0 @@ -SUMMARY = "YADRO Firmware update tool" -DESCRIPTION = "Command line tool for update firmware" -HOMEPAGE = "https://github.com/YADRO-KNS/obmc-yadro-fwupdate" -PR = "r1" -PV = "1.0+git${SRCPV}" -LICENSE = "Apache-2.0" -LIC_FILES_CHKSUM = "file://LICENSE;md5=e3fc50a88d0a364313df4b21ef20c29e" - -inherit meson - -DEPENDS += " \ - sdbusplus \ - openssl \ -" - -EXTRA_OEMESON_df-openpower = " \ - -Dopenpower-support=true \ -" - -SRC_URI = "git://github.com/YADRO-KNS/obmc-yadro-fwupdate" -SRCREV = "b922eb474447b76fb72cc615c025e3845b7c4b7e" -S = "${WORKDIR}/git" diff --git a/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-config.bbappend b/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-config.bbappend new file mode 100644 index 000000000..72d991c7e --- /dev/null +++ b/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-config.bbappend @@ -0,0 +1 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" diff --git a/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-config/cipher_list.json b/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-config/cipher_list.json new file mode 100644 index 000000000..767fc708c --- /dev/null +++ b/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-config/cipher_list.json @@ -0,0 +1,14 @@ +{ + "a":{ + "cipher":3, + "authentication":1, + "integrity":1, + "confidentiality":1 + }, + "b":{ + "cipher":17, + "authentication":3, + "integrity":4, + "confidentiality":1 + } +} diff --git a/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-host/0001-Add-support-for-persistent-only-settings.patch b/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-host/0001-Add-support-for-persistent-only-settings.patch new file mode 100644 index 000000000..f1e2c4ae4 --- /dev/null +++ b/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-host/0001-Add-support-for-persistent-only-settings.patch @@ -0,0 +1,92 @@ +From aaf8a4a5b82baff679f557ed83b25af6ff2919cf Mon Sep 17 00:00:00 2001 +From: Alexander Amelkin <a.amelkin@yadro.com> +Date: Thu, 23 May 2019 20:39:57 +0300 +Subject: [PATCH] Add support for persistent-only settings + +Some settings such as Boot Initiator Mailbox do not support +one-time setting mode (as per IPMI 2.0 specification). + +This commit adds support for such persistent-only settings. + +Partially resolves openbmc/openbmc#3391 + +Change-Id: Iec8e2f5bddbc50d270916567effe334f10db2987 +Signed-off-by: Alexander Amelkin <a.amelkin@yadro.com> +Signed-off-by: Ivan Mikhaylov <i.mikhaylov@yadro.com> +--- + settings.cpp | 35 +++++++++++++++++++++++++++++++---- + 1 file changed, 31 insertions(+), 4 deletions(-) + +diff --git a/settings.cpp b/settings.cpp +index 2fa2511..6002365 100644 +--- a/settings.cpp ++++ b/settings.cpp +@@ -95,19 +95,44 @@ namespace boot + std::tuple<Path, OneTimeEnabled> setting(const Objects& objects, + const Interface& iface) + { +- constexpr auto bootObjCount = 2; ++ constexpr auto ambiguousOperationCount = 2; + constexpr auto oneTime = "one_time"; + constexpr auto enabledIntf = "xyz.openbmc_project.Object.Enable"; ++ bool oneTimeEnabled = false; + + const std::vector<Path>& paths = objects.map.at(iface); + auto count = paths.size(); +- if (count != bootObjCount) ++ if (!count) + { +- log<level::ERR>("Exactly two objects expected", ++ // If there are no objects implementing the requested interface, ++ // that must be an error. ++ log<level::ERR>("Interface objects not found", ++ entry("INTERFACE=%s", iface.c_str())); ++ elog<InternalFailure>(); ++ } ++ else if (count < ambiguousOperationCount) ++ { ++ // On the contrary, if there is just one object, that may mean ++ // that this particular interface doesn't support one-time ++ // setting mode (e.g. Boot Initiator Mailbox). ++ // That is not an error, just return the regular setting. ++ // If there's just one object, that's the only kind of setting ++ // mode this interface supports, so just return that setting path. ++ const Path& regularSetting = paths[0]; ++ return std::make_tuple(regularSetting, oneTimeEnabled); ++ } ++ else if (count > ambiguousOperationCount) ++ { ++ // Something must be wrong if there are more objects than expected ++ log<level::ERR>("Exactly 1 or 2 interface objects are required", + entry("INTERFACE=%s", iface.c_str()), + entry("COUNT=%d", count)); + elog<InternalFailure>(); + } ++ ++ // We are here because there were exactly two objects implementing the ++ // same interface. Take those two and find out which of them is the ++ // one-time setting, consider the other the persistent setting. + size_t index = 0; + if (std::string::npos == paths[0].rfind(oneTime)) + { +@@ -116,6 +141,8 @@ std::tuple<Path, OneTimeEnabled> setting(const Objects& objects, + const Path& oneTimeSetting = paths[index]; + const Path& regularSetting = paths[!index]; + ++ // Now see if the one-time setting is enabled and return the path for it ++ // if so. Otherwise return the path for the persistent setting. + auto method = objects.bus.new_method_call( + objects.service(oneTimeSetting, iface).c_str(), oneTimeSetting.c_str(), + ipmi::PROP_INTF, "Get"); +@@ -131,7 +158,7 @@ std::tuple<Path, OneTimeEnabled> setting(const Objects& objects, + + std::variant<bool> enabled; + reply.read(enabled); +- auto oneTimeEnabled = std::get<bool>(enabled); ++ oneTimeEnabled = std::get<bool>(enabled); + const Path& setting = oneTimeEnabled ? oneTimeSetting : regularSetting; + return std::make_tuple(setting, oneTimeEnabled); + } +-- +2.21.1 + diff --git a/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-host/0002-Add-support-for-boot-initiator-mailbox.patch b/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-host/0002-Add-support-for-boot-initiator-mailbox.patch new file mode 100644 index 000000000..dd7610975 --- /dev/null +++ b/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-host/0002-Add-support-for-boot-initiator-mailbox.patch @@ -0,0 +1,418 @@ +From ec6765e9aa35871f8d02cb0b5b47d96be18f4804 Mon Sep 17 00:00:00 2001 +From: Alexander Amelkin <a.amelkin@yadro.com> +Date: Mon, 8 Apr 2019 17:58:42 +0300 +Subject: [PATCH] Add support for boot initiator mailbox + +Add handlers to process the chassis system option 7 +(boot initiator mailbox). The format of mailbox is +specific to the machine/bootloader. This commit only +adds generic handlers to process getting and setting +of the mailbox data regardless of the content. + +Only the IANA Enterprise number is checked in the data +block 0. Also checked are the data boundaries. + +It is expected that a machine-specific override for +phosphor-settingsd sets the supported state and +the IANA number according to the used bootloader. + +Resolves openbmc/openbmc#3391 + +Change-Id: Iccbf74c0775f20c70e8deaa7b0a8bd995ebbffea +Signed-off-by: Alexander Amelkin <a.amelkin@yadro.com> +Signed-off-by: Ivan Mikhaylov <i.mikhaylov@yadro.com> +--- + chassishandler.cpp | 328 ++++++++++++++++++++++++++++++++++++++++++++- + chassishandler.hpp | 1 + + 2 files changed, 325 insertions(+), 4 deletions(-) + +diff --git a/chassishandler.cpp b/chassishandler.cpp +index 3250b2c..48cda21 100644 +--- a/chassishandler.cpp ++++ b/chassishandler.cpp +@@ -136,6 +136,7 @@ namespace internal + { + + constexpr auto bootModeIntf = "xyz.openbmc_project.Control.Boot.Mode"; ++constexpr auto bootMboxIntf = "xyz.openbmc_project.Control.Boot.Mailbox"; + constexpr auto bootSourceIntf = "xyz.openbmc_project.Control.Boot.Source"; + constexpr auto powerRestoreIntf = + "xyz.openbmc_project.Control.Power.RestorePolicy"; +@@ -151,8 +152,8 @@ settings::Objects& getObjects() + if (objectsPtr == nullptr) + { + objectsPtr = std::make_unique<settings::Objects>( +- dbus, std::vector<std::string>{bootModeIntf, bootSourceIntf, +- powerRestoreIntf}); ++ dbus, std::vector<std::string>{bootMboxIntf, bootModeIntf, ++ bootSourceIntf, powerRestoreIntf}); + } + return *objectsPtr; + } +@@ -1670,6 +1671,127 @@ static ipmi::Cc setBootMode(const Mode::Modes& mode) + return ipmi::ccSuccess; + } + ++using MboxVec = std::vector<uint8_t>; ++ ++// Check if Boot Mailbox is supported. ++static std::optional<bool> isBootMboxSupported() ++{ ++ using namespace chassis::internal; ++ using namespace chassis::internal::cache; ++ ++ try ++ { ++ settings::Objects& objects = getObjects(); ++ auto bootMbox = settings::boot::setting(objects, bootMboxIntf); ++ const auto& bootMboxSetting = std::get<settings::Path>(bootMbox); ++ auto method = dbus.new_method_call( ++ objects.service(bootMboxSetting, bootMboxIntf).c_str(), ++ bootMboxSetting.c_str(), ipmi::PROP_INTF, "Get"); ++ ++ method.append(bootMboxIntf, "Supported"); ++ auto reply = dbus.call(method); ++ std::variant<bool> result; ++ reply.read(result); ++ return std::get<bool>(result); ++ } ++ catch (const std::exception& e) ++ { ++ log<level::ERR>("Error getting Boot/Mailbox/Supported", ++ entry("ERROR=%s", e.what())); ++ report<InternalFailure>(); ++ return std::nullopt; ++ } ++} ++ ++static std::optional<uint24_t> getBootMboxIANA() ++{ ++ using namespace chassis::internal; ++ using namespace chassis::internal::cache; ++ ++ try ++ { ++ settings::Objects& objects = getObjects(); ++ auto bootMbox = settings::boot::setting(objects, bootMboxIntf); ++ const auto& bootMboxSetting = std::get<settings::Path>(bootMbox); ++ auto method = dbus.new_method_call( ++ objects.service(bootMboxSetting, bootMboxIntf).c_str(), ++ bootMboxSetting.c_str(), ipmi::PROP_INTF, "Get"); ++ ++ method.append(bootMboxIntf, "IANAEnterpriseNumber"); ++ auto reply = dbus.call(method); ++ std::variant<uint32_t> result; ++ reply.read(result); ++ return std::get<uint32_t>(result); ++ } ++ catch (const std::exception& e) ++ { ++ log<level::ERR>("Error getting Boot/Mailbox/IANAEnterpriseNumber", ++ entry("ERROR=%s", e.what())); ++ report<InternalFailure>(); ++ return std::nullopt; ++ } ++} ++ ++static std::optional<MboxVec> getBootMbox() ++{ ++ using namespace chassis::internal; ++ using namespace chassis::internal::cache; ++ ++ try ++ { ++ settings::Objects& objects = getObjects(); ++ auto bootMbox = settings::boot::setting(objects, bootMboxIntf); ++ const auto& bootMboxSetting = std::get<settings::Path>(bootMbox); ++ auto method = dbus.new_method_call( ++ objects.service(bootMboxSetting, bootMboxIntf).c_str(), ++ bootMboxSetting.c_str(), ipmi::PROP_INTF, "Get"); ++ ++ method.append(bootMboxIntf, "Data"); ++ auto reply = dbus.call(method); ++ std::variant<MboxVec> result; ++ reply.read(result); ++ return std::get<MboxVec>(result); ++ } ++ catch (const std::exception& e) ++ { ++ log<level::ERR>("Error getting Boot/Mailbox/Data", ++ entry("ERROR=%s", e.what())); ++ report<InternalFailure>(); ++ return std::nullopt; ++ } ++} ++ ++static bool setBootMbox(MboxVec data) ++{ ++ using namespace chassis::internal; ++ using namespace chassis::internal::cache; ++ ++ try ++ { ++ settings::Objects& objects = getObjects(); ++ std::variant<MboxVec> property(data); ++ auto bootMbox = settings::boot::setting(objects, bootMboxIntf); ++ const auto& bootMboxSetting = std::get<settings::Path>(bootMbox); ++ auto method = dbus.new_method_call( ++ objects.service(bootMboxSetting, bootMboxIntf).c_str(), ++ bootMboxSetting.c_str(), ipmi::PROP_INTF, "Set"); ++ ++ method.append(bootMboxIntf, "Data", property); ++ dbus.call(method); ++ return true; ++ } ++ catch (const std::exception& e) ++ { ++ log<level::ERR>("Error setting Boot/Mailbox/Data", ++ entry("ERROR=%s", e.what())); ++ report<InternalFailure>(); ++ return false; ++ } ++} ++ ++static constexpr size_t normalBlockSize = 16; ++static constexpr size_t IANAEnterpriseLength = 3; ++ + /** @brief implements the Get Chassis system boot option + * @param bootOptionParameter - boot option parameter selector + * @param reserved1 - reserved bit +@@ -1783,6 +1905,87 @@ ipmi::RspType<ipmi::message::Payload> + return ipmi::responseUnspecifiedError(); + } + } ++ else if (static_cast<uint8_t>(bootOptionParameter) == ++ static_cast<uint8_t>(BootOptionParameter::bootInitiatorMbox)) ++ { ++ // Only allow reading the boot initiator mailbox if Mailbox is supported ++ // ++ // Algorithm: ++ // 1. Get 'Supported' property from the Control.Boot.Mailbox interface ++ // 2. If {1} is 'false', report Parameter not supported (0x80) ++ // 3. Get Block Selector from request ++ // 4. Get 'Data' vector from Control.Boot.Mailbox ++ // 5. If requested block {3} exceeds total vector size {4}, ++ // report Out of space (0xC4) ++ // 6. Return the selected block (16 bytes) from the vector ++ try ++ { ++ // Check whether this option is supported ++ std::optional<bool> isSupported = isBootMboxSupported(); ++ if (!isSupported) ++ { ++ return ipmi::responseUnspecifiedError(); ++ } ++ ++ if (!*isSupported) ++ { ++ log<level::INFO>("Attempt to read unsupported Boot/Mailbox"); ++ return ipmi::responseParmNotSupported(); ++ } ++ ++ // Initially assume it's block 1+ ++ std::optional<uint24_t> IANAEnterprise; ++ size_t blockDataSize = normalBlockSize; ++ size_t dataVecStartOffset = ++ setSelector * normalBlockSize - IANAEnterpriseLength; ++ ++ response.pack(bootOptionParameter, reserved1, setSelector); ++ ++ // Adjust pointers and sizes for block 0, and fill in the IANA PEN ++ if (0 == setSelector) ++ { ++ IANAEnterprise = getBootMboxIANA(); ++ if (!IANAEnterprise) ++ { ++ return ipmi::responseInvalidCommand(); ++ } ++ ++ blockDataSize = normalBlockSize - IANAEnterpriseLength; ++ dataVecStartOffset = 0; ++ ++ response.pack(*IANAEnterprise); ++ } ++ ++ // Get the total data size ++ std::optional<MboxVec> dataVec = getBootMbox(); ++ if (!dataVec) ++ { ++ return ipmi::responseInvalidCommand(); ++ } ++ ++ if ((*dataVec).size() < dataVecStartOffset + blockDataSize) ++ { ++ size_t totalSize = (*dataVec).size() + IANAEnterpriseLength; ++ log<level::ERR>( ++ "Attempt to read unsupported block", ++ entry("REQUESTED_BLOCK=%d", setSelector), ++ entry("MAX_BLOCK=%d", totalSize / normalBlockSize)); ++ return ipmi::responseParmOutOfRange(); ++ } ++ ++ // Copy the data to response from specified offset in d-bus vector ++ response.append((*dataVec).data() + dataVecStartOffset, ++ (*dataVec).data() + dataVecStartOffset + ++ blockDataSize); ++ ++ return ipmi::responseSuccess(std::move(response)); ++ } ++ catch (InternalFailure& e) ++ { ++ report<InternalFailure>(); ++ return ipmi::responseUnspecifiedError(); ++ } ++ } + else + { + if ((bootOptionParameter >= oemParmStart) && +@@ -1825,9 +2028,8 @@ ipmi::RspType<> ipmiChassisSetSysBootOptions(ipmi::Context::ptr ctx, + using namespace boot_options; + ipmi::Cc rc; + +- /* 000101 ++ /* + * Parameter #5 means boot flags. Please refer to 28.13 of ipmi doc. +- * This is the only parameter used by petitboot. + */ + + if (parameterSelector == +@@ -1954,6 +2156,124 @@ ipmi::RspType<> ipmiChassisSetSysBootOptions(ipmi::Context::ptr ctx, + return ipmi::responseUnspecifiedError(); + } + } ++ else if (parameterSelector == ++ static_cast<uint7_t>(BootOptionParameter::bootInitiatorMbox)) ++ { ++ // Only allow writing to boot initiator mailbox if: ++ // 1. Mailbox is supported ++ // 2. IANA PEN matches. ++ // ++ // Algorithm: ++ // 1. Get 'Supported' property from Control.Boot.Mailbox interface ++ // 2. If {1} is 'false', report Parameter not supported (0x80) ++ // 3. Get Block Selector from request ++ // 4. Get 'Data' array from Control.Boot.Mailbox ++ // 5. If requested block {3} exceeds total vector size {4}, ++ // report Out of range (0xC9) ++ // 6. If requsted block {3} is 0: ++ // 4.1. Get IANA PEN from request ++ // 4.2. Get 'IANAEnterpriseNumber' property from Control.Boot.Mailbox ++ // 4.3. If {4.1} doesn't match {4.2}, report 0xCC error (Invalid ++ // data field in request) ++ // 7. Overwrite the 16 bytes at offset {3}*16 with the data from request ++ // 8. Update the 'Data' array in Control.Boot.Mailbox ++ ++ try ++ { ++ std::optional<bool> isSupported = isBootMboxSupported(); ++ if (!isSupported) ++ { ++ return ipmi::responseUnspecifiedError(); ++ } ++ ++ if (!*isSupported) ++ { ++ log<level::INFO>("Attempt to read unsupported Boot/Mailbox"); ++ return ipmi::responseParmNotSupported(); ++ } ++ ++ // Requested block ++ uint8_t reqBlock; ++ if (data.unpack(reqBlock) != 0) ++ { ++ return ipmi::responseReqDataLenInvalid(); ++ } ++ ++ // Initially assume it's blcok 1+ ++ uint24_t reqIANAEnterprise; ++ std::vector<uint8_t> blockData(normalBlockSize); ++ size_t dataVecStartOffset = ++ reqBlock * normalBlockSize - IANAEnterpriseLength; ++ ++ // Adjust pointers and sizes for block 0, and fill in the IANA PEN ++ if (0 == reqBlock) ++ { ++ if (data.unpack(reqIANAEnterprise) != 0) ++ { ++ return ipmi::responseReqDataLenInvalid(); ++ } ++ ++ std::optional<uint24_t> IANAEnterprise = getBootMboxIANA(); ++ if (!IANAEnterprise) ++ { ++ return ipmi::responseInvalidCommand(); ++ } ++ ++ if (*IANAEnterprise != reqIANAEnterprise) ++ { ++ log<level::ERR>( ++ "Unsupported IANA Enterprise number", ++ entry("REQUESTED_IANA=%d", ++ static_cast<uint32_t>(reqIANAEnterprise)), ++ entry("SUPPORTED_IANA=%d", ++ static_cast<uint32_t>(*IANAEnterprise))); ++ return ipmi::responseInvalidFieldRequest(); ++ } ++ ++ // For block 0 operate on data after IANA PEN ++ blockData.resize(normalBlockSize - IANAEnterpriseLength); ++ dataVecStartOffset = 0; ++ } ++ ++ // Get the data vector from d-bus ++ std::optional<MboxVec> dataVec = getBootMbox(); ++ if (!dataVec) ++ { ++ return ipmi::responseInvalidCommand(); ++ } ++ ++ // Does the requested block exist? ++ if ((*dataVec).size() < dataVecStartOffset + blockData.size()) ++ { ++ size_t totalSize = (*dataVec).size() + IANAEnterpriseLength; ++ log<level::ERR>( ++ "Attempt to read unsupported block", ++ entry("REQUESTED_BLOCK=%d", reqBlock), ++ entry("MAX_BLOCK=%d", totalSize / normalBlockSize)); ++ return ipmi::responseParmOutOfRange(); ++ } ++ ++ if (data.unpack(blockData) != 0 || !data.fullyUnpacked()) ++ { ++ return ipmi::responseReqDataLenInvalid(); ++ } ++ ++ // Copy the data from request to specified offset in d-bus vector ++ for (size_t i = 0; i < blockData.size(); ++i) ++ { ++ (*dataVec)[dataVecStartOffset + i] = blockData[i]; ++ } ++ if (!setBootMbox(*dataVec)) ++ { ++ return ipmi::responseUnspecifiedError(); ++ } ++ } ++ catch (InternalFailure& e) ++ { ++ report<InternalFailure>(); ++ return ipmi::responseUnspecifiedError(); ++ } ++ } + else if (parameterSelector == + static_cast<uint7_t>(BootOptionParameter::bootInfo)) + { +diff --git a/chassishandler.hpp b/chassishandler.hpp +index 93de2c0..33ad25f 100644 +--- a/chassishandler.hpp ++++ b/chassishandler.hpp +@@ -48,6 +48,7 @@ enum class BootOptionParameter : size_t + { + bootInfo = 0x4, + bootFlags = 0x5, ++ bootInitiatorMbox = 0x07, + opalNetworkSettings = 0x61 + }; + +-- +2.26.2 + diff --git a/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-host/0003-Fix-version-parsing-update-AUX-revision-info.patch b/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-host/0003-Fix-version-parsing-update-AUX-revision-info.patch new file mode 100644 index 000000000..695b16c69 --- /dev/null +++ b/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-host/0003-Fix-version-parsing-update-AUX-revision-info.patch @@ -0,0 +1,329 @@ +From 605210dca3d6803839a8bcea4b5b83866c01f2da Mon Sep 17 00:00:00 2001 +From: Alexander Amelkin <alexander@amelkin.msk.ru> +Date: Wed, 11 Jul 2018 13:16:01 +0300 +Subject: [PATCH] Fix version parsing, update AUX revision info + +AUX Revision info was always taken from the dev_id.json +file if it exists, overriding the value calculated from the +active firmware version string. Also, when AUX info was +calculated, it only properly parsed the dirtyness of the +build. + +With this commit the AUX info calculation will properly parse +the git hash part and will include it as higher 3 bytes of +the AUX info. For officially released versions the lower byte +will be zero. + +For development versions, bits [7:1] of the fourth byte will +all be 1 as an indicator of non-release branch. For unofficial +builds from release branches those bits will contain a number +from 1 to 126 indicating a patch level since the release tag. + +In any case the bit 0 of byte 4 is a dirtyness indicator. +If the sources used to build the firmware were modified compared +to the git hash, this bit will be 1. + +WARNING: For the AUX decoding from version string to work + properly, the dev_id.json file must NOT contain + the `aux` property. + +Resolves SRV-775 +End-user-impact: Version info is properly represented in the + AUX Revision Info fields in response to the + IPMI Get Device ID command (ipmitool mc info) +Signed-off-by: Alexander Amelkin <a.filippov@yadro.com> + +--- + apphandler.cpp | 228 +++++++++++++++++++++++++++++++++++-------------- + 1 file changed, 165 insertions(+), 63 deletions(-) + +diff --git a/apphandler.cpp b/apphandler.cpp +index 90818a9..93e3b6c 100644 +--- a/apphandler.cpp ++++ b/apphandler.cpp +@@ -1,4 +1,5 @@ + #include <arpa/inet.h> ++#include <endian.h> + #include <fcntl.h> + #include <limits.h> + #include <linux/i2c-dev.h> +@@ -459,33 +460,112 @@ ipmi::RspType<uint8_t, // acpiSystemPowerState + return ipmi::responseSuccess(sysAcpiState, devAcpiState); + } + ++static ++std::vector<std::string> ++tokenize(std::string const& str, ++ char const token[]) ++{ ++ std::vector<std::string> results; ++ std::string::size_type j = 0; ++ while (j < str.length()) ++ { ++ std::string::size_type k = str.find_first_of(token, j); ++ if (k == std::string::npos) ++ k = str.length(); ++ results.push_back(str.substr(j, k-j)); ++ j = k + 1; ++ } ++ return results; ++} ++ + typedef struct + { +- char major; +- char minor; +- uint16_t d[2]; ++ uint8_t major; ++ uint8_t minor; ++ union { ++ uint8_t aux[4]; // Individual bytes in IPMI big-endian order ++ uint32_t aux32; // use htobe32() on writes to aux32 ++ }; + } Revision; + +-/* Currently supports the vx.x-x-[-x] and v1.x.x-x-[-x] format. It will */ +-/* return -1 if not in those formats, this routine knows how to parse */ ++/* Currently supports the following formats. It will return -1 if not in */ ++/* those formats: */ ++/* */ ++/* Format 1: */ + /* version = v0.6-19-gf363f61-dirty */ +-/* ^ ^ ^^ ^ */ +-/* | | |----------|-- additional details */ +-/* | |---------------- Minor */ +-/* |------------------ Major */ +-/* and version = v1.99.10-113-g65edf7d-r3-0-g9e4f715 */ +-/* ^ ^ ^^ ^ */ +-/* | | |--|---------- additional details */ +-/* | |---------------- Minor */ +-/* |------------------ Major */ +-/* Additional details : If the option group exists it will force Auxiliary */ +-/* Firmware Revision Information 4th byte to 1 indicating the build was */ +-/* derived with additional edits */ ++/* ^ ^ ^^^^^^ ^^^^^ */ ++/* | | | | */ ++/* | | | `-- AUX dirty flag */ ++/* | | `---------- AUX commit hash */ ++/* | `---------------- Minor */ ++/* `------------------ Major */ ++/* */ ++/* Format 2: */ ++/* version = v1.99.10-113-g65edf7d-r3-0-g9e4f715-dirty */ ++/* ^ ^^ ^^^^^^ ^^^^^ */ ++/* | | | .-----------------' */ ++/* | | | `- AUX dirty flag */ ++/* | | `----- AUX commit hash */ ++/* | `---------------- Minor */ ++/* `------------------ Major */ ++/* */ ++/* version = v2.09-dev-794-g196400c89-some-branch-name-dirty */ ++/* ^ ^^ ^^^^^^ ^^^^^ */ ++/* | | | .-----------------------' */ ++/* | | | `- AUX dirty flag */ ++/* | | `---- AUX commit hash */ ++/* | `---------------- Minor */ ++/* `------------------ Major */ ++/* */ ++/* Format 3 (YADRO Releases): */ ++/* version = v1.0rcf2817p7-rc2-unofficial-dirty */ ++/* ^ ^ ^^^^^^ ^^ .----------^^^^^ */ ++/* | | | | `- AUX dirty flag */ ++/* | | | `------- AUX patch level (1-126), optional */ ++/* | | `-------------- AUX release number */ ++/* | `---------------- Minor */ ++/* `------------------ Major */ ++/* */ ++static + int convertVersion(std::string s, Revision& rev) + { +- std::string token; +- uint16_t commits; ++ std::vector<std::string> tokens; ++ bool has_release = false; // version string is of "release" format 3 ++ bool dirty = false; + ++ constexpr int TOKEN_MAJOR = 0; ++ constexpr int TOKEN_MINOR = 1; ++ // These are for "release" format 3 ++ constexpr int TOKEN_MINOR_HASH = 1; ++ constexpr int TOKEN_MINOR_PATCH = 2; ++ // For non-release formats 1 and 2 ++ constexpr int TOKEN_HASH = 3; // Search for git hash starting from this ++ ++ // Hash info is in the higher 24 bits of AUX F/W Revision Info ++ constexpr int AUX_HASH_SHIFT = 8; ++ constexpr int AUX_HASH_LEN = 6; ++ ++ // Non-release indicator is byte 3 (bits 7..1 of AUX F/W Revision Info) ++ constexpr int AUX_NON_REL_BYTE = 3; ++ constexpr int AUX_NON_REL_SHIFT = 1; ++ constexpr uint8_t AUX_NON_REL_VALUE = UINT8_MAX >> AUX_NON_REL_SHIFT; ++ ++ // Release patch level occupies the same bits as the non-release indicator ++ constexpr int AUX_PATCH_BYTE = AUX_NON_REL_BYTE; ++ constexpr int AUX_PATCH_SHIFT = AUX_NON_REL_SHIFT; ++ constexpr int AUX_MAX_PATCH = AUX_NON_REL_VALUE - 1; ++ ++ // The least significant bit of byte 3 is the dirty flag ++ constexpr int AUX_DIRTY_BYTE = 3; ++ constexpr int AUX_DIRTY_SHIFT = 0; ++ ++ // Use base-16 to convert decimals to BCD ++ constexpr int BCD_BASE = 16; ++ ++ // First of all clear the revision ++ rev = {0}; ++ ++ // Cut off the optional 'v' at the beginning + auto location = s.find_first_of('v'); + if (location != std::string::npos) + { +@@ -494,64 +576,77 @@ int convertVersion(std::string s, Revision& rev) + + if (!s.empty()) + { +- location = s.find_first_of("."); +- if (location != std::string::npos) ++ int hash = 0; ++ ++ if (s.find("dirty") != std::string::npos) + { +- rev.major = +- static_cast<char>(std::stoi(s.substr(0, location), 0, 16)); +- token = s.substr(location + 1); ++ dirty = true; + } + +- if (!token.empty()) ++ tokens = tokenize(s, ".-"); ++ ++ if (!tokens.empty()) + { +- location = token.find_first_of(".-"); +- if (location != std::string::npos) ++ rev.major = std::stoi(tokens[TOKEN_MAJOR], 0, BCD_BASE); ++ } ++ ++ if (tokens.size() > TOKEN_MINOR) ++ { ++ rev.minor = std::stoi(tokens[TOKEN_MINOR], 0, BCD_BASE); ++ ++ // Minor version token may also contain release/patchlevel info ++ std::vector<std::string> minortok; ++ ++ minortok = tokenize(tokens[TOKEN_MINOR], "rp"); ++ ++ if (minortok.size() > TOKEN_MINOR_HASH) + { +- rev.minor = static_cast<char>( +- std::stoi(token.substr(0, location), 0, 16)); +- token = token.substr(location + 1); ++ // hash is plain hex ++ hash= std::stoi(minortok[TOKEN_MINOR_HASH], 0, 16); ++ has_release = true; ++ } ++ ++ if (minortok.size() > TOKEN_MINOR_PATCH) ++ { ++ // Patch level is encoded as binary, not BCD. ++ // That is to allow for a wider range. ++ int pl = std::stoi(minortok[TOKEN_MINOR_PATCH], 0, 10); ++ uint8_t patchlevel = (pl > AUX_MAX_PATCH) ++ ? AUX_MAX_PATCH ++ : pl; ++ rev.aux[AUX_PATCH_BYTE] = patchlevel << AUX_PATCH_SHIFT; + } + } + +- // Capture the number of commits on top of the minor tag. +- // I'm using BE format like the ipmi spec asked for +- location = token.find_first_of(".-"); +- if (!token.empty()) ++ // If it's not a "release" format 3, then search for ++ // letter 'g' indicating the position of a git hash ++ // in the version string ++ if (!has_release && tokens.size() > TOKEN_HASH) + { +- commits = std::stoi(token.substr(0, location), 0, 16); +- rev.d[0] = (commits >> 8) | (commits << 8); +- +- // commit number we skip +- location = token.find_first_of(".-"); +- if (location != std::string::npos) ++ std::string hashstr; ++ for (size_t i = TOKEN_HASH; i < tokens.size(); ++i) + { +- token = token.substr(location + 1); ++ // Find the first token that looks like a git hash. ++ // We think here that anything starting with a 'g' is a match. ++ if ('g' == tokens[i][0]) ++ { ++ // Cut off the 'g', take only the first AUX_HASH_LEN digits ++ hashstr = tokens[i].substr(1, AUX_HASH_LEN); ++ break; ++ } + } +- } +- else +- { +- rev.d[0] = 0; +- } + +- if (location != std::string::npos) +- { +- token = token.substr(location + 1); ++ // Hash is plain hex ++ hash = std::stoi(hashstr, 0, 16); ++ rev.aux[AUX_NON_REL_BYTE] |= AUX_NON_REL_VALUE << AUX_NON_REL_SHIFT; + } ++ rev.aux32 |= htobe32(hash << AUX_HASH_SHIFT); ++ rev.aux[AUX_DIRTY_BYTE] |= dirty << AUX_DIRTY_SHIFT; + +- // Any value of the optional parameter forces it to 1 +- location = token.find_first_of(".-"); +- if (location != std::string::npos) +- { +- token = token.substr(location + 1); +- } +- commits = (!token.empty()) ? 1 : 0; +- +- // We do this operation to get this displayed in least significant bytes +- // of ipmitool device id command. +- rev.d[1] = (commits >> 8) | (commits << 8); ++ return 0; + } + +- return 0; ++ return -1; + } + + /* @brief: Implement the Get Device ID IPMI command per the IPMI spec +@@ -623,7 +718,7 @@ ipmi::RspType<uint8_t, // Device ID + + rev.minor = (rev.minor > 99 ? 99 : rev.minor); + devId.fw[1] = rev.minor % 10 + (rev.minor / 10) * 16; +- std::memcpy(&devId.aux, rev.d, 4); ++ std::memcpy(&devId.aux, rev.aux, 4); + } + + // IPMI Spec version 2.0 +@@ -640,7 +735,14 @@ ipmi::RspType<uint8_t, // Device ID + devId.addnDevSupport = data.value("addn_dev_support", 0); + devId.manufId = data.value("manuf_id", 0); + devId.prodId = data.value("prod_id", 0); +- devId.aux = data.value("aux", 0); ++ ++ // Use the AUX data from the file only for overriding ++ // the data obtained from version string. ++ if (data.contains("aux")) ++ { ++ // AUX F/W Revision Info is MSB first (big-endian) ++ devId.aux = htobe32(data.value("aux", 0)); ++ } + + // Set the availablitity of the BMC. + defaultActivationSetting = data.value("availability", true); +-- +2.28.0 + diff --git a/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-host_%.bbappend b/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-host_%.bbappend new file mode 100644 index 000000000..b4b1a2f1e --- /dev/null +++ b/meta-yadro/recipes-phosphor/ipmi/phosphor-ipmi-host_%.bbappend @@ -0,0 +1,7 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/${PN}:" + +SRC_URI += "\ + file://0001-Add-support-for-persistent-only-settings.patch \ + file://0002-Add-support-for-boot-initiator-mailbox.patch \ + file://0003-Fix-version-parsing-update-AUX-revision-info.patch \ +" |