diff --git a/README.md b/README.md index 407a0df..1457694 100644 --- a/README.md +++ b/README.md @@ -4,9 +4,28 @@ applications are developing on top of [Zephyr BSP](https://github.com/AspeedTech # Building ASPEED-PFR firmware + ``` -west init -m https://github.com/AspeedTech-BMC/aspeed-zephyr-sdk --mr aspeed-master workspace +west init -m https://github.com/AspeedTech-BMC/aspeed-zephyr-project --mr aspeed-master workspace cd workspace west update -west build -b ast1060_evb -p auto aspeed-zephyr-sdk/apps/aspeed-pfr ``` + +## AST2600 L board + +``` +west build -b ast1060_evb -p auto aspeed-zephyr-project/apps/aspeed-pfr +``` + +## AST2600 DCSCM board + +``` +west build -b ast1060_dcscm -p auto aspeed-zephyr-project/apps/aspeed-pfr +``` + +## AST2600 Dual Flash + +``` +west build -b ast1060_dual_flash -p auto aspeed-zephyr-project/apps/aspeed-pfr +``` + diff --git a/apps/aspeed-pfr/Kconfig b/apps/aspeed-pfr/Kconfig new file mode 100644 index 0000000..5d9a2c9 --- /dev/null +++ b/apps/aspeed-pfr/Kconfig @@ -0,0 +1,58 @@ +# Copyright (c) 2022 ASPEED Technology Inc. +# # SPDX-License-Identifier: MIT + +config ASPEED_DC_SCM + default n + bool "ASPEED DC-SCM board" + help + Enable ASPEED DC-SCM board basic settings. + +config BMC_DUAL_FLASH + default n + bool "Enable dual flash support" + help + Enable if BMC has dual flash + +config SPI_MUX_INVERSE + default n + bool "Invert SPI MUX" + help + Enable if SPI MUX connected to BMC/ROT is inverted + +config CHECKPOINT_RECOVERY + default n + bool "Checkpoint timeout recovery function" + help + Enable if BMC/PCH supports mailbox checkpoint + +config PLATFORM_STATE_LED + default n + bool "Display platfrom state in 8 bits LED" + help + Enable if the system has PlatformState LEDs + +config BMC_STAGING_SIZE + default 0x03DE0000 + hex "BMC staging region size in BMC flash" + help + The max size of BMC staging area for putting signed BMC capsule. + +config BMC_PCH_STAGING_SIZE + default 0x1000000 + hex "PCH staging region size in BMC flash" + help + The max size of PCH staging area for putting signed PCH capsule. + +config BMC_PFR_STAGING_SIZE + default 0x500000 + hex "PFR staging region size in BMC flash" + help + The max size of PFR staging area for putting signed ROT capsule. + +config PCH_STAGING_SIZE + default 0x1000000 + hex "PCH staging region size in PCH flash" + help + The max size of PCH staging area for putting signed PCH capsule. + +source "Kconfig.zephyr" diff --git a/apps/aspeed-pfr/boards/ast1060_dcscm.conf b/apps/aspeed-pfr/boards/ast1060_dcscm.conf new file mode 100644 index 0000000..61bac48 --- /dev/null +++ b/apps/aspeed-pfr/boards/ast1060_dcscm.conf @@ -0,0 +1,23 @@ +CONFIG_GPIO_ASPEED_SGPIOM=y +CONFIG_GPIO_ASPEED=y +CONFIG_SPI_ASPEED=y +CONFIG_SPI_MONITOR_ASPEED=y +CONFIG_SPI_MONITOR_SHELL_ASPEED=y +CONFIG_SPI_NOR_ADDR_MODE_FALLBACK_DISABLED=y +CONFIG_PFR_SHELL_ASPEED=y +CONFIG_I2C_ASPEED=y +CONFIG_I2C_PFR=y +CONFIG_I2C_PFR_INIT_PRIORITY=60 +CONFIG_I2C_PFR_FILTER=y +CONFIG_SHELL_ARGC_MAX=70 +CONFIG_WATCHDOG=y +CONFIG_WDT_ASPEED=y +CONFIG_UART_ASPEED=y +CONFIG_ASPEED_DC_SCM=y +CONFIG_PFR_SW_MAILBOX=y +CONFIG_I2C_SWMBX_SLAVE=y +CONFIG_PLATFORM_STATE_LED=y +CONFIG_BMC_STAGING_SIZE=0x3de0000 +CONFIG_BMC_PCH_STAGING_SIZE=0x1000000 +CONFIG_BMC_PFR_STAGING_SIZE=0x500000 +CONFIG_PCH_STAGING_SIZE=0x1000000 diff --git a/apps/aspeed-pfr/boards/ast1060_dcscm.overlay b/apps/aspeed-pfr/boards/ast1060_dcscm.overlay new file mode 100644 index 0000000..227ccd4 --- /dev/null +++ b/apps/aspeed-pfr/boards/ast1060_dcscm.overlay @@ -0,0 +1,364 @@ +/ { + /* For v01.00.06 */ + resources { + compatible = "demo,gpio_basic_api"; + bmc-srst-ctrl-out-gpios = <&gpio0_m_p 5 0>; /* GPIO_M5 */ + bmc-extrst-ctrl-out-gpios = <&gpio0_e_h 26 0>; /* GPIO_H2 */ + bmc-rst-ind-in-gpios = <&gpio0_m_p 19 0>; /* GPIO_O3 */ + bmc-cpu1-mux-sel-out-gpios = <&gpio0_a_d 26 0>; /* GPIO_D2 */ + bic-rst-ind-in-gpios = <&gpio0_a_d 16 0>; /* GPIO_C0 */ + pch-rst-ctrl-out-gpios = <&gpio0_m_p 2 0>; /* GPIO_M2 */ + cpu0-rst-ind-in-gpios = <&gpio0_q_t 26 0>; /* GPIO_T2 */ + cpu1-rst-ind-in-gpios = <&gpio0_q_t 28 0>; /* GPIO_T4 */ + cpu0-flash-pwr-out-gpios = <&gpio0_i_l 26 0>; /* GPIO_L2 */ + cpu1-flash-pwr-out-gpios = <&gpio0_i_l 27 0>; /* GPIO_L3 */ + + platform-state-out-gpios = + <&sgpiom_a_d 0 0>, <&sgpiom_a_d 1 0>, + <&sgpiom_a_d 2 0>, <&sgpiom_a_d 3 0>, + <&sgpiom_a_d 4 0>, <&sgpiom_a_d 5 0>, + <&sgpiom_a_d 6 0>, <&sgpiom_a_d 7 0>; + }; +}; + +&i2cfilter { + pinctrl-0 = <&pinctrl_smbflt_default>; + status = "okay"; +}; + +&mbxctrl { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + pinctrl-0 = <&pinctrl_i2c0_default>; + + swmbx0: swmbx0@38 { + compatible = "aspeed,swmbx-dev"; + reg = <0x38>; + label = "SWMBX_SLAVE_BMC"; + size = <256>; + port = <0>; + status = "okay"; + }; +}; + +&i2c1 { + pinctrl-0 = <&pinctrl_i2c1_default>; + status = "okay"; +}; + +&i2c2 { + pinctrl-0 = <&pinctrl_i2c2_default>; + status = "okay"; + + swmbx1: swmbx1@62 { + compatible = "aspeed,swmbx-dev"; + reg = <0x62>; + label = "SWMBX_SLAVE_CPU"; + size = <256>; + port = <1>; + status = "okay"; + }; +}; + +&i2c4 { + pinctrl-0 = <&pinctrl_i2c4_default>; + status = "okay"; +}; + +&i2c5 { + pinctrl-0 = <&pinctrl_i2c5_default>; + status = "okay"; +}; + +&i2c6 { + pinctrl-0 = <&pinctrl_i2c6_default>; + status = "okay"; +}; + +&i2c7 { + pinctrl-0 = <&pinctrl_i2c7_default>; + status = "okay"; +}; + +// for i2c filter testing +&i2c8 { + pinctrl-0 = <&pinctrl_i2c8_default>; + status = "okay"; +}; + +&wdt0 { + status = "okay"; +}; + +&wdt1 { + status = "okay"; +}; + +&wdt2 { + status = "okay"; +}; + +&wdt3 { + status = "okay"; +}; + +&wdt4 { + status = "okay"; +}; + +&fmc { + status = "okay"; +}; + +&fmc_cs0 { + /delete-property/ broken-sfdp; + /delete-property/ write-block-size; + status = "okay"; + spi-max-buswidth = <4>; + spi-max-frequency = <50000000>; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + active_partition: partition@0 { + label = "active"; + reg = <0x0 0x60000>; + }; + + recovery_partition: partition@1 { + label = "recovery"; + reg = <0x60000 0x60000>; + }; + + state_partition: partition@2 { + label = "state"; + reg = <0xC0000 0x10000>; + }; + + intel_state_partition: partition@3 { + label = "intel_state"; + reg = <0xD0000 0x10000>; + }; + + key_partition: partition@4 { + label = "key"; + reg = <0xE0000 0x10000>; + }; + + log_partition: partition@5 { + label = "log"; + reg = <0xF0000 0x20000>; + }; + }; +}; + +&fmc_cs1 { + status = "okay"; + spi-max-buswidth = <4>; + spi-max-frequency = <50000000>; +}; + +&spi1 { + num-cs = <1>; + status = "okay"; +}; + +/* "SPI1_CS0" used to access flash connected to SPI_Monitor_1, + * "SPI2_CS0" used to access flash connected to SPI_Monitor_3, + * "SPI2_CS1" is used to access flash connected to SPI_Monitor_4, + */ + +&spi1_cs0 { + spi-max-buswidth = <4>; + spi-max-frequency = <50000000>; + status = "okay"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* 896KB */ + bmc_uboot_partition: partition@0 { + label = "bmc-uboot"; + reg = <0x00000000 0x000e0000>; + }; + + /* 128KB */ + bmc_pfm_partition: partition@e0000{ + reg = <0x000e0000 0x00020000>; + label = "bmc-pfm"; + }; + + /* 128KB */ + bmc_ub_env_partition: partition@100000{ + reg = <0x00100000 0x00020000>; + label = "bmc-ub-env"; + }; + + /* 2048KB */ + bmc_sofs_partition: partition@120000{ + reg = <0x00120000 0x00200000>; + label = "bmc-sofs"; + }; + + /* 18432KB */ + bmc_rwfs_partition: partition@320000{ + label = "bmc-rwfs"; + reg = <0x00320000 0x01200000>; + }; + + /* 46080KB */ + bmc_fitimg_partition: partition@1520000{ + label = "bmc-fitimg"; + reg = <0x01520000 0x02d00000>; + }; + + /* 63360KB */ + bmc_rc_image_partition: partition@4220000{ + label = "bmc-rc-image"; + reg = <0x04220000 0x03de0000>; + }; + + /* 63360KB */ + bmc_stg_partition: partition@8000000{ + label = "bmc-stg"; + reg = <0x08000000 0x03de0000>; + }; + + /* 16384KB */ + bmc_pch_stg_partition: partition@bde0000{ + label = "bmc-pch-stg"; + reg = <0x0bde0000 0x01000000>; + }; + + /* 5120KB */ + bmc_pfr_stg_partition: partition@cde0000{ + label = "bmc-pfr-stg"; + reg = <0x0cde0000 0x00500000>; + }; + + /* 128KB */ + afm_act_partition: partition@d2e0000 { + label = "afm-act"; + reg = <0x0d2e0000 0x00020000>; + }; + + /* 128KB */ + afm_rc_partition: partition@d300000 { + label = "afm-rc"; + reg = <0x0d300000 0x00020000>; + }; + + /* 45952KB */ + reserved_partition: partition@d320000 { + reg = <0x0d320000 0x02ce0000>; + label = "reserved"; + }; + }; +}; + +&spi2_cs0 { + spi-max-buswidth = <4>; + spi-max-frequency = <50000000>; + status = "okay"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* 8MB */ + pch_active_partition: partition@0 { + label = "pch-act"; + reg = <0x00000000 0x00800000>; + }; + + /* 8MB compressed pch recovery image */ + pch_recovery_partition: partition@800000 { + label = "pch-rc"; + reg = <0x00800000 0x00800000>; + }; + + /* 8MB compressed pch staging image */ + pch_staging_partition: partition@1000000 { + label = "pch-stg"; + reg = <0x01000000 0x00800000>; + }; + + /* 4MB */ + pch_pfm_partition: partition@1800000 { + label = "pch-pfm"; + reg = <0x01800000 0x00400000>; + }; + }; +}; + +&spi2_cs1 { + spi-max-buswidth = <4>; + spi-max-frequency = <50000000>; + status = "okay"; +}; + +&spi2 { + internal-mux-master = <2>; + spi-monitor-output-base = <3>; + spi-monitor-common-ctrl = <&spim0>; + pinctrl-0 = <>; + + num-cs = <2>; + status = "okay"; +}; + +&spim0 { + status = "okay"; +}; + +&spim1 { + allow-cmds = [03 13 0b 0c 6b 6c 01 05 35 06 04 20 21 9f 5a b7 e9 32 34 d8 dc 02 12 3b 3c 70 bb bc]; + log-ram-size = <0x200>; + pinctrl-0 = <&pinctrl_spim1_cs &pinctrl_spim1_in_default &pinctrl_spim1_qspi_in_default + &pinctrl_spim1_rst_out &pinctrl_spim1_muxsel>; + + flash-device = <&spi1_cs0>; + ext-mux-sel = <1>; + status = "okay"; + + write-forbidden-regions = < + 0x00000000 0x10000000 + >; +}; + +&spim3 { + allow-cmds = [03 13 0b 0c 6b 6c 01 05 35 06 04 20 21 9f 5a b7 e9 32 34 d8 dc 02 12 3b 3c 70 bb bc]; + log-ram-size = <0x200>; + pinctrl-0 = <&pinctrl_spim3_cs &pinctrl_spim3_in_default &pinctrl_spim3_out_default + &pinctrl_spim3_qspi_in_default &pinctrl_spim3_qspi_out_default + &pinctrl_spim3_muxsel &pinctrl_spim3_rst_out>; + + flash-device = <&spi2_cs0>; + ext-mux-sel = <1>; + status = "okay"; + write-forbidden-regions = < + 0x00000000 0x08000000 + >; +}; + +&spim4 { + allow-cmds = [03 13 0b 0c 6b 6c 01 05 35 06 04 20 21 9f 5a b7 e9 32 34 d8 dc 02 12 3b 3c 70 bb bc]; + log-ram-size = <0x200>; + pinctrl-0 = <&pinctrl_spim4_cs &pinctrl_spim4_in_default &pinctrl_spim4_out_default + &pinctrl_spim4_qspi_in_default &pinctrl_spim4_qspi_out_default + &pinctrl_spim4_muxsel &pinctrl_spim4_rst_out>; + + flash-device = <&spi2_cs1>; + ext-mux-sel = <1>; + status = "okay"; +}; + +&sgpiom { + status = "okay"; +}; diff --git a/apps/aspeed-pfr/boards/ast1060_dual_flash.conf b/apps/aspeed-pfr/boards/ast1060_dual_flash.conf new file mode 100644 index 0000000..d798c48 --- /dev/null +++ b/apps/aspeed-pfr/boards/ast1060_dual_flash.conf @@ -0,0 +1,24 @@ +CONFIG_GPIO_ASPEED_SGPIOM=y +CONFIG_GPIO_ASPEED=y +CONFIG_SPI_ASPEED=y +CONFIG_SPI_MONITOR_ASPEED=y +CONFIG_SPI_MONITOR_SHELL_ASPEED=y +CONFIG_SPI_NOR_ADDR_MODE_FALLBACK_DISABLED=y +CONFIG_PFR_SHELL_ASPEED=y +CONFIG_I2C_ASPEED=y +CONFIG_I2C_PFR=y +CONFIG_I2C_PFR_INIT_PRIORITY=60 +CONFIG_I2C_PFR_FILTER=y +CONFIG_SHELL_ARGC_MAX=70 +CONFIG_WATCHDOG=y +CONFIG_WDT_ASPEED=y +CONFIG_UART_ASPEED=y +CONFIG_PFR_SW_MAILBOX=y +CONFIG_I2C_SWMBX_SLAVE=y +CONFIG_ASPEED_DC_SCM=y +CONFIG_BMC_DUAL_FLASH=y +CONFIG_CHECKPOINT_RECOVERY=n +CONFIG_BMC_STAGING_SIZE=0x3de0000 +CONFIG_BMC_PCH_STAGING_SIZE=0x1000000 +CONFIG_BMC_PFR_STAGING_SIZE=0x500000 +CONFIG_PCH_STAGING_SIZE=0x1000000 diff --git a/apps/aspeed-pfr/boards/ast1060_dual_flash.overlay b/apps/aspeed-pfr/boards/ast1060_dual_flash.overlay new file mode 100644 index 0000000..e412806 --- /dev/null +++ b/apps/aspeed-pfr/boards/ast1060_dual_flash.overlay @@ -0,0 +1,277 @@ +/ { + /* For v01.00.06 */ + resources { + compatible = "demo,gpio_basic_api"; + bmc-srst-ctrl-out-gpios = <&gpio0_m_p 5 0>; /* GPIO_M5 */ + bmc-extrst-ctrl-out-gpios = <&gpio0_e_h 26 0>; /* GPIO_H2 */ + bmc-rst-ind-in-gpios = <&gpio0_m_p 19 0>; /* GPIO_O3 */ + bmc-cpu1-mux-sel-out-gpios = <&gpio0_a_d 26 0>; /* GPIO_D2 */ + bic-rst-ind-in-gpios = <&gpio0_a_d 16 0>; /* GPIO_C0 */ + pch-rst-ctrl-out-gpios = <&gpio0_m_p 2 0>; /* GPIO_M2 */ + cpu0-rst-ind-in-gpios = <&gpio0_q_t 26 0>; /* GPIO_T2 */ + cpu1-rst-ind-in-gpios = <&gpio0_q_t 28 0>; /* GPIO_T4 */ + cpu0-flash-pwr-out-gpios = <&gpio0_i_l 26 0>; /* GPIO_L2 */ + cpu1-flash-pwr-out-gpios = <&gpio0_i_l 27 0>; /* GPIO_L3 */ + + platform-state-out-gpios = + <&sgpiom_a_d 0 0>, <&sgpiom_a_d 1 0>, + <&sgpiom_a_d 2 0>, <&sgpiom_a_d 3 0>, + <&sgpiom_a_d 4 0>, <&sgpiom_a_d 5 0>, + <&sgpiom_a_d 6 0>, <&sgpiom_a_d 7 0>; + }; +}; + +&i2cfilter { + pinctrl-0 = <&pinctrl_smbflt_default>; + status = "okay"; +}; + +&mbxctrl { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + pinctrl-0 = <&pinctrl_i2c0_default>; + + swmbx0: swmbx0@38 { + compatible = "aspeed,swmbx-dev"; + reg = <0x38>; + label = "SWMBX_SLAVE_BMC"; + size = <256>; + port = <0>; + status = "okay"; + }; +}; + +&i2c1 { + pinctrl-0 = <&pinctrl_i2c1_default>; + status = "okay"; +}; + +&i2c2 { + pinctrl-0 = <&pinctrl_i2c2_default>; + status = "okay"; + + swmbx1: swmbx1@62 { + compatible = "aspeed,swmbx-dev"; + reg = <0x62>; + label = "SWMBX_SLAVE_CPU"; + size = <256>; + port = <1>; + status = "okay"; + }; +}; + +&i2c3 { + pinctrl-0 = <&pinctrl_i2c3_default>; + status = "okay"; +}; + +&i2c4 { + pinctrl-0 = <&pinctrl_i2c4_default>; + status = "okay"; +}; + +&i2c5 { + pinctrl-0 = <&pinctrl_i2c5_default>; + status = "okay"; +}; + +&i2c6 { + pinctrl-0 = <&pinctrl_i2c6_default>; + status = "okay"; +}; + +&i2c7 { + pinctrl-0 = <&pinctrl_i2c7_default>; + status = "okay"; +}; + +// for i2c filter testing +&i2c8 { + pinctrl-0 = <&pinctrl_i2c8_default>; + status = "okay"; +}; + +&wdt0 { + status = "okay"; +}; + +&wdt1 { + status = "okay"; +}; + +&wdt2 { + status = "okay"; +}; + +&wdt3 { + status = "okay"; +}; + +&wdt4 { + status = "okay"; +}; + +&fmc { + status = "okay"; +}; + +&fmc_cs0 { + /delete-property/ broken-sfdp; + /delete-property/ write-block-size; + status = "okay"; + spi-max-buswidth = <4>; + spi-max-frequency = <50000000>; + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + active_partition: partition@0 { + label = "active"; + reg = <0x0 0x60000>; + }; + + recovery_partition: partition@1 { + label = "recovery"; + reg = <0x60000 0x60000>; + }; + + state_partition: partition@2 { + label = "state"; + reg = <0xC0000 0x10000>; + }; + + intel_state_partition: partition@3 { + label = "intel_state"; + reg = <0xD0000 0x10000>; + }; + + key_partition: partition@4 { + label = "key"; + reg = <0xE0000 0x10000>; + }; + + log_partition: partition@5 { + label = "log"; + reg = <0xF0000 0x20000>; + }; + }; +}; + +&fmc_cs1 { + status = "okay"; + spi-max-buswidth = <4>; + spi-max-frequency = <50000000>; +}; + +&spi1 { + num-cs = <2>; + status = "okay"; +}; + +/* "SPI1_CS0" is used to access flash connected to SPI_Monitor_1, + * "SPI1_CS1" is used to access flash connected to SPI_Monitor_2, + * "SPI2_CS0" is used to access flash connected to SPI_Monitor_3, + * "SPI2_CS1" is used to access flash connected to SPI_Monitor_4, + */ + +&spi1_cs0 { + spi-max-buswidth = <4>; + spi-max-frequency = <50000000>; + status = "okay"; +}; + +&spi1_cs1 { + spi-max-buswidth = <4>; + spi-max-frequency = <50000000>; + status = "okay"; +}; + +&spi2_cs0 { + spi-max-buswidth = <4>; + spi-max-frequency = <50000000>; + status = "okay"; +}; + +&spi2_cs1 { + spi-max-buswidth = <4>; + spi-max-frequency = <50000000>; + status = "okay"; +}; + +&spi2 { + internal-mux-master = <2>; + spi-monitor-output-base = <3>; + spi-monitor-common-ctrl = <&spim0>; + pinctrl-0 = <>; + + num-cs = <2>; + status = "okay"; +}; + +&spim0 { + status = "okay"; +}; + +&spim1 { + allow-cmds = [03 13 0b 0c 6b 6c 01 05 35 06 04 20 21 9f 5a b7 e9 32 34 d8 dc 02 12 3b 3c 70 bb bc]; + log-ram-size = <0x200>; + pinctrl-0 = <&pinctrl_spim1_cs &pinctrl_spim1_in_default &pinctrl_spim1_qspi_in_default + &pinctrl_spim1_rst_out &pinctrl_spim1_muxsel>; + + flash-device = <&spi1_cs0>; + ext-mux-sel = <1>; + status = "okay"; + + write-forbidden-regions = < + 0x00000000 0x08000000 + >; +}; + +&spim2 { + allow-cmds = [03 13 0b 0c 6b 6c 01 05 35 06 04 20 21 9f 5a b7 e9 32 34 d8 dc 02 12 3b 3c 70 bb bc]; + log-ram-size = <0x200>; + pinctrl-0 = <&pinctrl_spim2_cs &pinctrl_spim2_in_default &pinctrl_spim2_qspi_in_default + &pinctrl_spim2_rst_out &pinctrl_spim2_muxsel>; + + flash-device = <&spi1_cs1>; + ext-mux-sel = <1>; + status = "okay"; + + write-forbidden-regions = < + 0x00000000 0x08000000 + >; +}; + +&spim3 { + allow-cmds = [03 13 0b 0c 6b 6c 01 05 35 06 04 20 21 9f 5a b7 e9 32 34 d8 dc 02 12 3b 3c 70 bb bc]; + log-ram-size = <0x200>; + pinctrl-0 = <&pinctrl_spim3_cs &pinctrl_spim3_in_default &pinctrl_spim3_out_default + &pinctrl_spim3_qspi_in_default &pinctrl_spim3_qspi_out_default + &pinctrl_spim3_muxsel &pinctrl_spim3_rst_out>; + + flash-device = <&spi2_cs0>; + ext-mux-sel = <1>; + status = "okay"; + write-forbidden-regions = < + 0x00000000 0x08000000 + >; +}; + +&spim4 { + allow-cmds = [03 13 0b 0c 6b 6c 01 05 35 06 04 20 21 9f 5a b7 e9 32 34 d8 dc 02 12 3b 3c 70 bb bc]; + log-ram-size = <0x200>; + pinctrl-0 = <&pinctrl_spim4_cs &pinctrl_spim4_in_default &pinctrl_spim4_out_default + &pinctrl_spim4_qspi_in_default &pinctrl_spim4_qspi_out_default + &pinctrl_spim4_muxsel &pinctrl_spim4_rst_out>; + + flash-device = <&spi2_cs1>; + ext-mux-sel = <1>; + status = "okay"; +}; + +&sgpiom { + status = "okay"; +}; diff --git a/apps/aspeed-pfr/boards/ast1060_evb.conf b/apps/aspeed-pfr/boards/ast1060_evb.conf index 5620c38..82d2012 100644 --- a/apps/aspeed-pfr/boards/ast1060_evb.conf +++ b/apps/aspeed-pfr/boards/ast1060_evb.conf @@ -12,3 +12,11 @@ CONFIG_I2C_PFR_FILTER=y CONFIG_SHELL_ARGC_MAX=70 CONFIG_WATCHDOG=y CONFIG_WDT_ASPEED=y +CONFIG_UART_ASPEED=y +CONFIG_PFR_SW_MAILBOX=y +CONFIG_I2C_SWMBX_SLAVE=y +CONFIG_SPI_MUX_INVERSE=y +CONFIG_BMC_STAGING_SIZE=0x2000000 +CONFIG_BMC_PCH_STAGING_SIZE=0x1000000 +CONFIG_BMC_PFR_STAGING_SIZE=0x500000 +CONFIG_PCH_STAGING_SIZE=0x1000000 diff --git a/apps/aspeed-pfr/boards/ast1060_evb.overlay b/apps/aspeed-pfr/boards/ast1060_evb.overlay index 480b3ae..d62be88 100644 --- a/apps/aspeed-pfr/boards/ast1060_evb.overlay +++ b/apps/aspeed-pfr/boards/ast1060_evb.overlay @@ -1,5 +1,5 @@ / { -#if 0 +#if 1 /* For v01.00.06 */ resources { compatible = "demo,gpio_basic_api"; @@ -13,6 +13,12 @@ cpu1-rst-ind-in-gpios = <&gpio0_q_t 28 0>; /* GPIO_T4 */ cpu0-flash-pwr-out-gpios = <&gpio0_i_l 26 0>; /* GPIO_L2 */ cpu1-flash-pwr-out-gpios = <&gpio0_i_l 27 0>; /* GPIO_L3 */ + + platform-state-out-gpios = + <&sgpiom_a_d 0 0>, <&sgpiom_a_d 1 0>, + <&sgpiom_a_d 2 0>, <&sgpiom_a_d 3 0>, + <&sgpiom_a_d 4 0>, <&sgpiom_a_d 5 0>, + <&sgpiom_a_d 6 0>, <&sgpiom_a_d 7 0>; }; #else /* For v01.00.05 */ @@ -24,25 +30,44 @@ #endif }; +&sram0 { + reg = <0 DT_SIZE_K(640)>, <0xa0000 DT_SIZE_K(128)>; +}; + &i2cfilter { pinctrl-0 = <&pinctrl_smbflt_default>; status = "okay"; }; +&mbxctrl { + status = "okay"; +}; + &i2c0 { status = "okay"; pinctrl-0 = <&pinctrl_i2c0_default>; + + swmbx0: swmbx0@62 { + compatible = "aspeed,swmbx-dev"; + reg = <0x62>; + label = "SWMBX_SLAVE_CPU"; + size = <256>; + port = <1>; + status = "okay"; + }; }; &i2c1 { pinctrl-0 = <&pinctrl_i2c1_default>; status = "okay"; - bmcmbx_0: bmcmbx_0@38 { - compatible = "bmcmbx"; + swmbx1: swmbx1@38 { + compatible = "aspeed,swmbx-dev"; reg = <0x38>; + label = "SWMBX_SLAVE_BMC"; + size = <256>; + port = <0>; status = "okay"; - label = "BMCMBX_0"; }; }; @@ -71,7 +96,7 @@ &i2c8 { pinctrl-0 = <&pinctrl_i2c8_default>; status = "okay"; - }; +}; &wdt0 { status = "okay"; @@ -98,6 +123,8 @@ }; &fmc_cs0 { + /delete-property/ broken-sfdp; + /delete-property/ write-block-size; status = "okay"; spi-max-buswidth = <4>; spi-max-frequency = <50000000>; @@ -152,6 +179,90 @@ spi-max-buswidth = <4>; spi-max-frequency = <50000000>; status = "okay"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* 896KB */ + bmc_uboot_partition: partition@0 { + label = "bmc-uboot"; + reg = <0x00000000 0x000e0000>; + }; + + /* 128KB */ + bmc_pfm_partition: partition@e0000{ + reg = <0x000e0000 0x00020000>; + label = "bmc-pfm"; + }; + + /* 128KB */ + bmc_ub_env_partition: partition@100000{ + reg = <0x00100000 0x00020000>; + label = "bmc-ub-env"; + }; + + /* 2048KB */ + bmc_sofs_partition: partition@120000{ + reg = <0x00120000 0x00200000>; + label = "bmc-sofs"; + }; + + /* 8064KB */ + bmc_rwfs_partition: partition@320000{ + label = "bmc-rwfs"; + reg = <0x00320000 0x007e0000>; + }; + + /* 31744KB */ + bmc_fitimg_partition: partition@b00000{ + label = "bmc-fitimg"; + reg = <0x00b00000 0x01f00000>; + }; + + /* 32768KB */ + bmc_rc_image_partition: partition@2a00000{ + label = "bmc-rc-image"; + reg = <0x02a00000 0x02000000>; + }; + + /* 32768KB */ + bmc_stg_partition: partition@4a00000{ + label = "bmc-stg"; + reg = <0x04a00000 0x02000000>; + }; + + /* 16384KB */ + bmc_pch_stg_partition: partition@6a00000{ + label = "bmc-pch-stg"; + reg = <0x06a00000 0x01000000>; + }; + + /* 5120KB */ + bmc_pfr_stg_partition: partition@7a00000{ + label = "bmc-pfr-stg"; + reg = <0x07a00000 0x00500000>; + }; + + /* 128KB */ + afm_act_partition: partition@7f00000 { + label = "afm-act"; + reg = <0x07f00000 0x00020000>; + }; + + /* 128KB */ + afm_rc_partition: partition@7f20000 { + label = "afm-rc"; + reg = <0x07f20000 0x00020000>; + }; + + /* 768KB */ + reserved_partition: partition@7f40000 { + reg = <0x07f40000 0x000c0000>; + label = "reserved"; + }; + }; }; /* Use AST1060 SPI2 as the internal SPI master to @@ -167,6 +278,36 @@ spi-max-frequency = <50000000>; reg = <0>; status = "okay"; + + partitions { + compatible = "fixed-partitions"; + #address-cells = <1>; + #size-cells = <1>; + + /* 8MB */ + pch_active_partition: partition@0 { + label = "pch-act"; + reg = <0x00000000 0x00800000>; + }; + + /* 8MB compressed pch recovery image */ + pch_recovery_partition: partition@800000 { + label = "pch-rc"; + reg = <0x00800000 0x00800000>; + }; + + /* 8MB compressed pch staging image */ + pch_staging_partition: partition@1000000 { + label = "pch-stg"; + reg = <0x01000000 0x00800000>; + }; + + /* 4MB */ + pch_pfm_partition: partition@1800000 { + label = "pch-pfm"; + reg = <0x01800000 0x00400000>; + }; + }; }; &spi2_cs1 { @@ -208,7 +349,7 @@ flash-device = <&spi1_cs0>; status = "okay"; write-forbidden-regions = < - 0x00000000 0x08000000 + 0x00000000 0x08000000 >; }; @@ -222,7 +363,7 @@ flash-device = <&spi2_cs0>; status = "okay"; write-forbidden-regions = < - 0x00000000 0x08000000 + 0x00000000 0x08000000 >; }; @@ -262,3 +403,7 @@ flash-device = <&spi2_cs2>; status = "okay"; }; + +&sgpiom { + status = "okay"; +}; diff --git a/apps/aspeed-pfr/dts/bindings/demo,gpio_basic_api.yaml b/apps/aspeed-pfr/dts/bindings/demo,gpio_basic_api.yaml index 0d13757..e2538a5 100644 --- a/apps/aspeed-pfr/dts/bindings/demo,gpio_basic_api.yaml +++ b/apps/aspeed-pfr/dts/bindings/demo,gpio_basic_api.yaml @@ -23,3 +23,61 @@ properties: Identity of a GPIO that will be configured as an input. This must be on the same device as out-gpios,and physically connected to out-gpios. + bmc-srst-ctrl-out-gpios: + type: phandle-array + required: false + description: Control BMC SRST# signal. + + bmc-extrst-ctrl-out-gpios: + type: phandle-array + required: false + description: Control BMC EXTRST# signal. + + bmc-rst-ind-in-gpios: + type: phandle-array + required: false + description: Detect or monitor BMC reset indicator. + + bmc-cpu1-mux-sel-out-gpios: + type: phandle-array + required: false + description: | + Control the MUX selection pin which determains + SPI flash signal from BMC or CPU1. + 0: CPU1 + 1: BMC or BIC + + bic-rst-ind-in-gpios: + type: phandle-array + required: false + description: Detect or monitor BIC reset indicator. + + pch-rst-ctrl-out-gpios: + type: phandle-array + required: false + description: Control PCH reset signal. + + cpu0-rst-ind-in-gpios: + type: phandle-array + required: false + description: Detect CPU0 reset indicator. + + cpu1-rst-ind-in-gpios: + type: phandle-array + required: false + description: Detect CPU1 reset indicator. + + cpu0-flash-pwr-out-gpios: + type: phandle-array + required: false + description: PCH CPU0 SPI flash power control. + + cpu1-flash-pwr-out-gpios: + type: phandle-array + required: false + description: PCH CPU1 SPI flash power control. + + platform-state-out-gpios: + type: phandle-array + required: false + description: 8 bit leds for displaying platform state diff --git a/apps/aspeed-pfr/prj.conf b/apps/aspeed-pfr/prj.conf index de43a9d..d8e3ad9 100644 --- a/apps/aspeed-pfr/prj.conf +++ b/apps/aspeed-pfr/prj.conf @@ -7,6 +7,7 @@ CONFIG_I2C_SLAVE=y CONFIG_I2C_EEPROM_SLAVE=y CONFIG_FLASH=y CONFIG_SPI_NOR_MULTI_DEV=y +CONFIG_SPI_DMA_SUPPORT_ASPEED=y CONFIG_FLASH_SHELL=y CONFIG_HEAP_MEM_POOL_SIZE=16384 CONFIG_MINIMAL_LIBC_MALLOC_ARENA_SIZE=147456 @@ -14,9 +15,8 @@ CONFIG_REBOOT=y CONFIG_POSIX_CLOCK=y CONFIG_STACK_SENTINEL=y CONFIG_LOG=y -CONFIG_LOG_BACKEND_UART=y +CONFIG_LOG_BUFFER_SIZE=8192 CONFIG_SHELL=y -CONFIG_SHELL_BACKEND_SERIAL_INIT_PRIORITY=99 CONFIG_PFR_FLOW_CTRL_AST1060=y CONFIG_CRYPTO=y CONFIG_CRYPTO_ASPEED=y @@ -33,7 +33,14 @@ CONFIG_MBEDTLS_ECP_DP_SECP384R1_ENABLED=y CONFIG_MBEDTLS_ECP_DP_SECP256R1_ENABLED=y CONFIG_MBEDTLS_ENABLE_HEAP=y CONFIG_MBEDTLS_HEAP_SIZE=16384 +CONFIG_MBEDTLS_ECP_NIST_OPTIM=y CONFIG_SHELL_STACK_SIZE=4096 +CONFIG_SHELL_BACKEND_SERIAL_INIT_PRIORITY=99 +CONFIG_SHELL_BACKEND_SERIAL_LOG_MESSAGE_QUEUE_TIMEOUT=-1 +CONFIG_SHELL_BACKEND_SERIAL_LOG_MESSAGE_QUEUE_SIZE=100 CONFIG_CERBERUS=y CONFIG_HROT_HAL=y +CONFIG_I2C_LOG_LEVEL_ERR=y +CONFIG_ABR_FLOW_CTRL_ASPEED=y +CONFIG_CHECKPOINT_RECOVERY=y diff --git a/apps/aspeed-pfr/src/AspeedStateMachine/AspeedStateMachine.c b/apps/aspeed-pfr/src/AspeedStateMachine/AspeedStateMachine.c new file mode 100644 index 0000000..d6c3463 --- /dev/null +++ b/apps/aspeed-pfr/src/AspeedStateMachine/AspeedStateMachine.c @@ -0,0 +1,933 @@ +/* + * Copyright (c) 2022 ASPEED Technology Inc. + * + * SPDX-License-Identifier: MIT + */ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "AspeedStateMachine.h" +#include "include/SmbusMailBoxCom.h" +#include "intel_pfr/intel_pfr_definitions.h" +#include "Smbus_mailbox/Smbus_mailbox.h" +#include "pfr/pfr_util.h" +#include "gpio/gpio_aspeed.h" +#include "platform_monitor/platform_monitor.h" +#include "platform_monitor/spim_monitor.h" +#include "engineManager/engine_manager.h" +#include "spi_filter/spi_filter_wrapper.h" +#include "flash/flash_aspeed.h" +#include "flash/flash_wrapper.h" + +LOG_MODULE_REGISTER(aspeed_state_machine, LOG_LEVEL_DBG); +K_FIFO_DEFINE(aspeed_sm_fifo); +struct smf_context s_obj; +static const struct smf_state state_table[]; + +enum aspeed_pfr_event event_log[128] = {START_STATE_MACHINE}; +size_t event_log_idx = 0; + +void GenerateStateMachineEvent(enum aspeed_pfr_event evt, void *data) +{ + struct event_context *event = (struct event_context *)k_malloc(sizeof(struct event_context)); + LOG_INF("Send event:%d data:%p to state machine", evt, data); + event_log[event_log_idx % 128] = evt; + event_log_idx++; + event->event = evt; + event->data.ptr = data; + + k_fifo_put(&aspeed_sm_fifo, event); +} + + +void do_init(void *o) +{ + struct smf_context *state = (struct smf_context *)o; + LOG_DBG("Start"); + + initializeEngines(); + initializeManifestProcessor(); + debug_log_init();// State Machine log saving + spim_irq_init(); + + // DEBUG_HALT(); + pfr_bmc_srst_enable_ctrl(true); + BMCBootHold(); + PCHBootHold(); + + state->bmc_active_object.type = BMC_EVENT; + state->bmc_active_object.ActiveImageStatus = Failure; + state->bmc_active_object.RecoveryImageStatus = Failure; + state->bmc_active_object.RestrictActiveUpdate = 0; + + state->pch_active_object.type = PCH_EVENT; + state->pch_active_object.ActiveImageStatus = Failure; + state->pch_active_object.RecoveryImageStatus = Failure; + state->pch_active_object.RestrictActiveUpdate = 0; + + // I2c_slave_dev_debug+> + // struct i2c_slave_interface *I2CSlaveEngine = getI2CSlaveEngineInstance(); + // struct I2CSlave_engine_wrapper *I2cSlaveEngineWrapper; + + // I2C_Slave_wrapper_init(getI2CSlaveEngineInstance()); + + enum boot_indicator rot_boot_from = get_boot_indicator(); + + disable_abr_wdt(); + if (rot_boot_from == BOOT_FROM_ALTERNATE_PART) { + /* ABR secondary booted, copy recovery image to active image */ + LOG_ERR("ROT boot from secondary image, need to recovery ROT active region"); + GenerateStateMachineEvent(INIT_ROT_SECONDARY_BOOTED, NULL); + } else { + /* ABR primary booted */ +#if SMBUS_MAILBOX_SUPPORT + InitializeSmbusMailbox(); + SetPlatformState(CPLD_NIOS_II_PROCESSOR_STARTED); +#endif + + // TODO: Wait for Power Sequence signal to leave INIT state + // Populate INIT_DONE event will enter FIRMWARE_VERIFY state + GenerateStateMachineEvent(INIT_DONE, NULL); + } + LOG_DBG("End"); +} + +void enter_tmin1(void *o) +{ + ARG_UNUSED(o); + LOG_DBG("Start"); + SetPlatformState(ENTER_T_MINUS_1); + /* TODO: BMC only reset */ + BMCBootHold(); + PCHBootHold(); + LOG_DBG("End"); +} + +void handle_image_verification(void *o) +{ + struct smf_context *state = (struct smf_context*)o; + struct event_context *evt_ctx = ((struct smf_context *)o)->event_ctx; + int ret; + + + byte provision_state = GetUfmStatusValue(); + + if (!(provision_state & UFM_PROVISIONED)) { + // Unprovisioned, populate INIT_UNPROVISIONED event will enter UNPROVISIONED state + GenerateStateMachineEvent(VERIFY_UNPROVISIONED, NULL); + } else { + /* BMC Verification */ + { + SetPlatformState(BMC_FLASH_AUTH); + { + EVENT_CONTEXT evt_wrap; + evt_wrap.image = BMC_EVENT; + evt_wrap.operation = VERIFY_BACKUP; + evt_wrap.flash = SECONDARY_FLASH_REGION; + ret = authentication_image(NULL, &evt_wrap); + LOG_INF("authentication_image bmc backup return %d", ret); + if (ret == 0) { + state->bmc_active_object.RecoveryImageStatus = Success; + } else { + state->bmc_active_object.RecoveryImageStatus = Failure; + } + } + + { + EVENT_CONTEXT evt_wrap; + evt_wrap.image = BMC_EVENT; + evt_wrap.operation = VERIFY_ACTIVE; + ret = authentication_image(NULL, &evt_wrap); + LOG_INF("authentication_image bmc active return %d", ret); + if (ret == 0) { + state->bmc_active_object.ActiveImageStatus = Success; + } else { + state->bmc_active_object.ActiveImageStatus = Failure; + } + } + } + + /* PCH Verification */ + { + SetPlatformState(PCH_FLASH_AUTH); + { + EVENT_CONTEXT evt_wrap; + evt_wrap.image = PCH_EVENT; + evt_wrap.operation = VERIFY_BACKUP; + evt_wrap.flash = SECONDARY_FLASH_REGION; + ret = authentication_image(NULL, &evt_wrap); + LOG_INF("authentication_image host backup return %d", ret); + if (ret == 0) { + state->pch_active_object.RecoveryImageStatus = Success; + } else { + state->pch_active_object.RecoveryImageStatus = Failure; + } + } + + { + EVENT_CONTEXT evt_wrap; + evt_wrap.image = PCH_EVENT; + evt_wrap.operation = VERIFY_ACTIVE; + evt_wrap.flash = PRIMARY_FLASH_REGION; + ret = authentication_image(NULL, &evt_wrap); + LOG_INF("authentication_image host active return %d", ret); + if (ret == 0) { + state->pch_active_object.ActiveImageStatus = Success; + } else { + state->pch_active_object.ActiveImageStatus = Failure; + } + } + } + + /* Success = 0, Failure = 1 */ + LOG_INF("BMC image verification recovery=%s active=%s", + state->bmc_active_object.RecoveryImageStatus ? "Bad" : "Good", + state->bmc_active_object.ActiveImageStatus ? "Bad" : "Good"); + LOG_INF("PCH image verification recovery=%s active=%s", + state->pch_active_object.RecoveryImageStatus ? "Bad" : "Good", + state->pch_active_object.ActiveImageStatus ? "Bad" : "Good"); + + /* Handling platform recovery matrix, the detail logic will be handled in recover_image() */ + if ((state->pch_active_object.ActiveImageStatus == Success && state->pch_active_object.RecoveryImageStatus == Success) + && (state->bmc_active_object.ActiveImageStatus == Success && state->bmc_active_object.RecoveryImageStatus == Success)) { + /* All good, we're good to go. */ + GenerateStateMachineEvent(VERIFY_DONE, NULL); + } else if ((state->pch_active_object.ActiveImageStatus == Failure && state->pch_active_object.RecoveryImageStatus == Success) + || (state->bmc_active_object.ActiveImageStatus == Failure && state->bmc_active_object.RecoveryImageStatus == Success)) { + /* Active currupted but recovery good, recovery -> active */ + GenerateStateMachineEvent(VERIFY_ACT_FAILED, NULL); + } else if ((state->pch_active_object.ActiveImageStatus == Success && state->pch_active_object.RecoveryImageStatus == Failure) + || (state->bmc_active_object.ActiveImageStatus == Success && state->bmc_active_object.RecoveryImageStatus == Failure)) { + /* Active good but recovery bad, staging -> recovery if possible */ + GenerateStateMachineEvent(VERIFY_RCV_FAILED, NULL); + } else if (evt_ctx->event == RECOVERY_DONE + && state->bmc_active_object.ActiveImageStatus == Success && state->bmc_active_object.RecoveryImageStatus == Success) { + /* BMC is (Good, Good) but PCH is (Bad, Bad), boot BMC but lockdown PCH */ + GenerateStateMachineEvent(VERIFY_DONE, NULL); + } else { + /* BMC is (Bad, Bad), stg->rcv->act */ + GenerateStateMachineEvent(VERIFY_RCV_FAILED, NULL); + } + } +} + +void do_verify(void *o) +{ + LOG_DBG("Start"); + handle_image_verification(o); + LOG_DBG("End"); +} + +void handle_recovery(void *o) +{ + struct smf_context *state = (struct smf_context *)o; + struct event_context *evt_ctx = state->event_ctx; + + /* Check Staging Image */ + bool recovery_done = 0; + int ret; + int verify_staging = -1; + EVENT_CONTEXT evt_wrap; + + recovery_initialize(); + + /* TODO: Verify Staging? */ + SetPlatformState(T_MINUS_1_FW_RECOVERY); + switch (evt_ctx->event) { +#if defined(CONFIG_CHECKPOINT_RECOVERY) + case WDT_TIMEOUT: + // WDT Checkpoint Timeout + SetPlatformState(WDT_TIMEOUT_RECOVERY); + state->bmc_active_object.ActiveImageStatus = Failure; + __attribute__ ((fallthrough)); +#endif + case VERIFY_ACT_FAILED: + case VERIFY_RCV_FAILED: + // Recovery matrix can be handled in recover_image + if (state->bmc_active_object.ActiveImageStatus == Failure || state->bmc_active_object.RecoveryImageStatus == Failure) { + evt_wrap.image = BMC_EVENT; + ret = recover_image(&state->bmc_active_object, &evt_wrap); + LOG_INF("BMC Recovery return=%d", ret); + if (ret == Success || ret == VerifyActive || ret == VerifyRecovery) { + recovery_done = 1; + } + } + + if (state->pch_active_object.ActiveImageStatus == Failure || state->pch_active_object.RecoveryImageStatus == Failure) { + evt_wrap.image = PCH_EVENT; + ret = recover_image(&state->pch_active_object, &evt_wrap); + LOG_INF("PCH Recovery return=%d", ret); + if (ret == Success || ret == VerifyActive || ret == VerifyRecovery) { + recovery_done = 1; + } + } + break; + default: + break; + } + + if (recovery_done) { + GenerateStateMachineEvent(RECOVERY_DONE, NULL); + } else { + GenerateStateMachineEvent(RECOVERY_FAILED, NULL); + } +} + +void do_recovery(void *o) +{ + LOG_DBG("Start"); + handle_recovery(o); + LOG_DBG("End"); +} + +static uint8_t recovery_buffer[1024] __aligned(16); + +void do_rot_recovery(void *o) +{ + ARG_UNUSED(o); + LOG_DBG("Start"); + uint8_t status; + size_t offset = 0; + struct spi_engine_wrapper *spi_flash = getSpiEngineWrapper(); + uint32_t region_size = pfr_spi_get_device_size(ROT_INTERNAL_RECOVERY); + + clear_abr_indicator(); + + LOG_INF("Erase PFR Active region size=%08x", region_size); + if (pfr_spi_erase_region(ROT_INTERNAL_ACTIVE, true, 0, region_size)){ + LOG_ERR("Erase PFR active region failed, SYSTEM LOCKDOWN"); + GenerateStateMachineEvent(RECOVERY_FAILED, NULL); + } + + LOG_INF("Copy PFR Recovery region to Active region"); + status = pfr_spi_region_read_write_between_spi(ROT_INTERNAL_RECOVERY, 0, + ROT_INTERNAL_ACTIVE, 0, region_size); + + if (!status) { + LOG_INF("Copy PFR Recovery region to Active region done"); + GenerateStateMachineEvent(RECOVERY_DONE, NULL); + } else { + LOG_ERR("Recover PFR active region failed, SYSTEM LOCKDOWN"); + GenerateStateMachineEvent(RECOVERY_FAILED, NULL); + } + LOG_DBG("End"); +} + +void enter_tzero(void *o) +{ + LOG_DBG("Start"); + SetPlatformState(ENTER_T0); + + struct smf_context *state = (struct smf_context*)o; + /* Arm reset monitor */ + platform_monitor_init(); +#if defined(CONFIG_ASPEED_DC_SCM) + pfr_bmc_srst_enable_ctrl(false); +#endif + if (state->ctx.current == &state_table[RUNTIME]) { + /* Provisioned */ + /* Arm SPI/I2C Filter */ + apply_pfm_protection(BMC_SPI); + /* Releasing System Reset */ + if (state->bmc_active_object.ActiveImageStatus == Success) { + BMCBootRelease(); + } else { + /* Should not enter here, redirect to LOCKDOWN */ + LOG_ERR("BMC firmware is invalid, lockdown the platform"); + } + + if (state->pch_active_object.ActiveImageStatus == Success) { + PCHBootRelease(); + } else { + LOG_ERR("Host firmware is invalid, host won't boot"); + } + } else { + /* Unprovisioned - Releasing System Reset */ + Set_SPI_Filter_RW_Region("spi_m1", SPI_FILTER_READ_PRIV, SPI_FILTER_PRIV_ENABLE, 0, 0x10000000); + Set_SPI_Filter_RW_Region("spi_m1", SPI_FILTER_WRITE_PRIV, SPI_FILTER_PRIV_ENABLE, 0, 0x10000000); + BMCBootRelease(); + PCHBootRelease(); + } + + LOG_DBG("End"); +} + +void exit_tzero(void *o) +{ + ARG_UNUSED(o); + LOG_DBG("Start"); + /* Disarm reset monitor */ + platform_monitor_remove(); + LOG_DBG("End"); +} + +extern struct device *gSwMbxDev; +extern uint8_t gUfmFifoData[64]; +extern uint8_t gReadFifoData[64]; +extern uint8_t gFifoData; + +void handle_provision_event(void *o) +{ + struct event_context *evt_ctx = ((struct smf_context *)o)->event_ctx; + + if (evt_ctx->data.bit8[1] & EXECUTE_UFM_COMMAND) { + LOG_DBG("UFM Trigger Execute"); + ClearUfmStatusValue(UFM_CLEAR_ON_NEW_COMMAND); + SetUfmStatusValue(COMMAND_BUSY); + process_provision_command(); + SetUfmStatusValue(COMMAND_DONE); + } else if (evt_ctx->data.bit8[1] & FLUSH_WRITE_FIFO) { + memset(&gUfmFifoData, 0, sizeof(gUfmFifoData)); + swmbx_flush_fifo(gSwMbxDev, UfmWriteFIFO); + gFifoData = 0; + } else if (evt_ctx->data.bit8[1] & FLUSH_READ_FIFO) { + memset(&gReadFifoData, 0, sizeof(gReadFifoData)); + swmbx_flush_fifo(gSwMbxDev, UfmReadFIFO); + gFifoData = 0; + } +} + +void handle_checkpoint(void *o) +{ + struct event_context *evt_ctx = ((struct smf_context *)o)->event_ctx; + + switch (evt_ctx->data.bit8[0]) { + case BmcCheckpoint: + if (evt_ctx->data.bit8[1] == 0x09) + SetPlatformState(T0_BMC_BOOTED); + UpdateBmcCheckpoint(evt_ctx->data.bit8[1]); + break; + case AcmCheckpoint: + if (evt_ctx->data.bit8[1] == 0x09) + SetPlatformState(T0_ACM_BOOTED); + //UpdateAcmCheckpoint(evt_ctx->data.bit8[1]); + break; + case BiosCheckpoint: + if (evt_ctx->data.bit8[1] == 0x09) + SetPlatformState(T0_BIOS_BOOTED); + UpdateBiosCheckpoint(evt_ctx->data.bit8[1]); + break; + default: + break; + } +} + +void handle_update_requested(void *o) +{ + struct smf_context *state = (struct smf_context *)o; + struct event_context *evt_ctx = state->event_ctx; + AO_DATA *ao_data_wrap = NULL; + EVENT_CONTEXT evt_ctx_wrap; + int ret; + uint8_t update_region = evt_ctx->data.bit8[1] & 0x3f; + bool update_dynamic = evt_ctx->data.bit8[1] & DymanicUpdate; + bool update_reset = evt_ctx->data.bit8[1] & UpdateAtReset; + CPLD_STATUS cpld_update_status; + + LOG_DBG("FIRMWARE_UPDATE Event Data %02x %02x", evt_ctx->data.bit8[0], evt_ctx->data.bit8[1]); + + switch(evt_ctx->data.bit8[0]) { + case PchUpdateIntent: + /* CPU/PCH only has access to bit[7:6] and bit[1:0] */ + update_region &= UpdateAtReset | DymanicUpdate | PchRecoveryUpdate | PchActiveUpdate; + break; + case BmcUpdateIntent: + /* BMC has full access */ + if ((update_region & PchActiveUpdate) || (update_region & PchRecoveryUpdate)) { + ufm_read(UPDATE_STATUS_UFM, UPDATE_STATUS_ADDRESS, &cpld_update_status, sizeof(CPLD_STATUS)); + cpld_update_status.BmcToPchStatus = 1; + ufm_write(UPDATE_STATUS_UFM, UPDATE_STATUS_ADDRESS, &cpld_update_status, sizeof(CPLD_STATUS)); + } + break; + default: + break; + } + + if (!update_reset) { + uint32_t handled_region = 0; + while(update_region) { + uint32_t image_type = 0xFFFFFFFF; + do { + /* BMC Active */ + if (update_region & BmcActiveUpdate) { + SetPlatformState(BMC_FW_UPDATE); + LOG_INF("BMC Active Firmware Update"); + image_type = BMC_TYPE; + evt_ctx_wrap.flash = PRIMARY_FLASH_REGION; + update_region &= ~BmcActiveUpdate; + handled_region |= BmcActiveUpdate; + ao_data_wrap = &state->bmc_active_object; + break; + } + + /* BMC Recovery */ + if (update_region & BmcRecoveryUpdate) { + SetPlatformState(BMC_FW_UPDATE); + LOG_INF("BMC Recovery Firmware Update"); + image_type = BMC_TYPE; + evt_ctx_wrap.flash = SECONDARY_FLASH_REGION; + update_region &= ~BmcRecoveryUpdate; + handled_region |= BmcRecoveryUpdate; + ao_data_wrap = &state->bmc_active_object; + break; + } + + /* PCH Active */ + if (update_region & PchActiveUpdate) { + SetPlatformState(PCH_FW_UPDATE); + LOG_INF("PCH Active Firmware Update"); + image_type = PCH_TYPE; + evt_ctx_wrap.flash = PRIMARY_FLASH_REGION; + update_region &= ~PchActiveUpdate; + handled_region |= PchActiveUpdate; + ao_data_wrap = &state->pch_active_object; + break; + } + + /* PCH Recovery */ + if (update_region & PchRecoveryUpdate) { + SetPlatformState(PCH_FW_UPDATE); + LOG_INF("PCH Recovery Firmware Update"); + image_type = PCH_TYPE; + evt_ctx_wrap.flash = SECONDARY_FLASH_REGION; + update_region &= ~PchRecoveryUpdate; + handled_region |= PchRecoveryUpdate; + ao_data_wrap = &state->pch_active_object; + break; + } + + /* ROT Active */ + if (update_region & HROTActiveUpdate) { + SetPlatformState(CPLD_FW_UPDATE); + LOG_INF("ROT Active Firmware Update"); + image_type = ROT_TYPE; + update_region &= ~HROTActiveUpdate; + handled_region |= HROTActiveUpdate; + break; + } + + /* ROT Recovery */ + if (update_region & HROTRecoveryUpdate) { + SetPlatformState(CPLD_FW_UPDATE); + LOG_INF("ROT Recovery Firmware Update"); + image_type = ROT_TYPE; + update_region &= ~HROTRecoveryUpdate; + handled_region |= HROTRecoveryUpdate; + break; + } + + } while (0); + + if (image_type != 0xFFFFFFFF) { + ret = update_firmware_image(image_type, ao_data_wrap, &evt_ctx_wrap); + } + + if (ret != Success) { + /* TODO: Log failed reason and handle it properly */ + GenerateStateMachineEvent(UPDATE_FAILED, (void *)handled_region); + break; + } + } + + if (update_region == 0 && ret == Success) { + GenerateStateMachineEvent(UPDATE_DONE, (void *)handled_region); + } + } +} + +void do_unprovisioned(void *o) +{ + LOG_DBG("Start"); + struct event_context *evt_ctx = ((struct smf_context *)o)->event_ctx; + switch (evt_ctx->event) { + case PROVISION_CMD: + handle_provision_event(o); + break; + default: + break; + } + + LOG_DBG("End"); +} + +void enter_runtime(void *o) +{ + ARG_UNUSED(o); + LOG_DBG("Start"); + AspeedPFR_EnableTimer(BMC_EVENT); + //AspeedPFR_EnableTimer(PCH_EVENT); + LOG_DBG("End"); +} + +void do_runtime(void *o) +{ + LOG_DBG("Start"); + struct event_context *evt_ctx = ((struct smf_context *)o)->event_ctx; + switch (evt_ctx->event) { + case PROVISION_CMD: + handle_provision_event(o); + break; + case WDT_CHECKPOINT: + handle_checkpoint(o); + break; + default: + break; + } + LOG_DBG("End"); +} + +void do_update(void *o) +{ + LOG_DBG("Start"); + handle_update_requested(o); + LOG_DBG("End"); +} + +void enter_lockdown(void *o) +{ + ARG_UNUSED(o); + LOG_DBG("Start"); + pfr_bmc_srst_enable_ctrl(false); + BMCBootHold(); + PCHBootHold(); + SetPlatformState(LOCKDOWN_ON_AUTH_FAIL); + LOG_DBG("End"); +} + +void do_lockdown(void *o) +{ + ARG_UNUSED(o); + LOG_DBG("Start"); + LOG_DBG("End"); +} + +void do_reboot(void *o) +{ + ARG_UNUSED(o); + LOG_DBG("Start"); + LOG_PANIC(); + pfr_cpld_update_reboot(); + /* Should never reach here? */ + LOG_DBG("End"); +} + +static const struct smf_state state_table[] = { + [BOOT] = SMF_CREATE_STATE(NULL, NULL, NULL, NULL), + [INIT] = SMF_CREATE_STATE(NULL, do_init, NULL, NULL), + [ROT_RECOVERY] = SMF_CREATE_STATE(NULL, do_rot_recovery, NULL, NULL), + [TMIN1] = SMF_CREATE_STATE(enter_tmin1, NULL, NULL, NULL), + [FIRMWARE_VERIFY] = SMF_CREATE_STATE(NULL, do_verify, NULL, &state_table[TMIN1]), + [FIRMWARE_RECOVERY] = SMF_CREATE_STATE(NULL, do_recovery, NULL, &state_table[TMIN1]), + [FIRMWARE_UPDATE] = SMF_CREATE_STATE(NULL, do_update, NULL, &state_table[TMIN1]), + [TZERO] = SMF_CREATE_STATE(enter_tzero, NULL, exit_tzero, NULL), + [UNPROVISIONED] = SMF_CREATE_STATE(NULL, do_unprovisioned, NULL, &state_table[TZERO]), + [RUNTIME] = SMF_CREATE_STATE(enter_runtime, do_runtime, NULL, &state_table[TZERO]), + // [SEAMLESS_UPDATE] = SMF_CREATE_STATE(NULL, do_seamless, NULL, NULL, &state_table[TZERO]), + [SYSTEM_LOCKDOWN] = SMF_CREATE_STATE(NULL, do_lockdown, NULL, NULL), + [SYSTEM_REBOOT] = SMF_CREATE_STATE(NULL, do_reboot, NULL, NULL), +}; + + +void AspeedStateMachine() +{ + smf_set_initial(SMF_CTX(&s_obj), &state_table[BOOT]); + GenerateStateMachineEvent(START_STATE_MACHINE, NULL); + + while (1) { + struct event_context *fifo_in = (struct event_context *)k_fifo_get(&aspeed_sm_fifo, K_FOREVER); + if (fifo_in == NULL) { + continue; + } + s_obj.event_ctx = fifo_in; + + LOG_INF("EVENT IN [%p] EVT=%d DATA=%p", fifo_in, fifo_in->event, fifo_in->data.ptr); + const struct smf_state *current_state = SMF_CTX(&s_obj)->current; + const struct smf_state *next_state = NULL; + bool run_state = false; + + if (current_state == &state_table[BOOT]) { + switch (fifo_in->event) { + case START_STATE_MACHINE: + next_state = &state_table[INIT]; + break; + default: + break; + } + } else if (current_state == &state_table[INIT]) { + switch (fifo_in->event) { + case INIT_DONE: + next_state = &state_table[FIRMWARE_VERIFY]; + break; + case INIT_ROT_SECONDARY_BOOTED: + next_state = &state_table[ROT_RECOVERY]; + break; + default: + /* Discard anyother event */ + break; + } + } else if (current_state == &state_table[ROT_RECOVERY]) { + switch (fifo_in->event) { + case RECOVERY_DONE: + next_state = &state_table[SYSTEM_REBOOT]; + break; + case RECOVERY_FAILED: + next_state = &state_table[SYSTEM_LOCKDOWN]; + break; + default: + break; + } + } else if (current_state == &state_table[FIRMWARE_VERIFY]) { + switch (fifo_in->event) { + case VERIFY_UNPROVISIONED: + next_state = &state_table[UNPROVISIONED]; + break; + case VERIFY_STG_FAILED: + case VERIFY_RCV_FAILED: + case VERIFY_ACT_FAILED: + next_state = &state_table[FIRMWARE_RECOVERY]; + break; + case VERIFY_DONE: + // Firmware is authenticated -> RUNTIME + // Non provisioned -> UNPROVISIONED + next_state = &state_table[RUNTIME]; + break; + default: + break; + } + } else if (current_state == &state_table[FIRMWARE_RECOVERY]) { + switch (fifo_in->event) { + case RECOVERY_DONE: + next_state = &state_table[FIRMWARE_VERIFY]; + break; + case RECOVERY_FAILED: + next_state = &state_table[SYSTEM_LOCKDOWN]; + break; + default: + break; + } + } else if (current_state == &state_table[FIRMWARE_UPDATE]) { + switch (fifo_in->event) { + case UPDATE_DONE: + if (fifo_in->data.bit32 & HROTActiveUpdate) { + /* Update PFR requires reboot platform */ + next_state = &state_table[SYSTEM_REBOOT]; + } else { + /* Verify the image then boot */ + next_state = &state_table[FIRMWARE_VERIFY]; + } + break; + case UPDATE_FAILED: + next_state = &state_table[FIRMWARE_VERIFY]; + break; + default: + break; + } + } else if (current_state == &state_table[RUNTIME]) { + switch (fifo_in->event) { + case RESET_DETECTED: + next_state = &state_table[FIRMWARE_VERIFY]; + break; + case UPDATE_REQUESTED: + // Check update intent, seamless or tmin1 update + next_state = &state_table[FIRMWARE_UPDATE]; + break; + case PROVISION_CMD: + case WDT_CHECKPOINT: + // Just run provision handling + run_state = true; + break; +#if defined(CONFIG_CHECKPOINT_RECOVERY) + case WDT_TIMEOUT: + next_state = &state_table[FIRMWARE_RECOVERY]; + break; +#endif + default: + break; + } + } else if (current_state == &state_table[UNPROVISIONED]) { + switch (fifo_in->event) { + case PROVISION_CMD: + // Just run provision handling + run_state = true; + break; + case RESET_DETECTED: + next_state = &state_table[FIRMWARE_VERIFY]; + break; + default: + break; + } + } + + if (next_state) { + smf_set_state(SMF_CTX(&s_obj), next_state); + } + + if (run_state || next_state) { + smf_run_state(SMF_CTX(&s_obj)); + } + + s_obj.event_ctx = NULL; + k_free(fifo_in); + } +} + +#ifdef CONFIG_SHELL +static int cmd_asm_event(const struct shell *shell, + size_t argc, char **argv, void *data) +{ + ARG_UNUSED(argc); + ARG_UNUSED(argv); + + shell_print(shell, "Sending event[%d]\n", data); + GenerateStateMachineEvent((enum aspeed_pfr_event)data, NULL); + + return 0; +} + +static int cmd_asm_show(const struct shell *shell, size_t argc, + char **argv) +{ + ARG_UNUSED(argc); + ARG_UNUSED(argv); + shell_print(shell, "State List:"); + for (int i=0; i < ARRAY_SIZE(state_table); ++i) { + shell_print(shell, "[%d] %p", i, &state_table[i]); + } + shell_print(shell, "Current state: %p", SMF_CTX(&s_obj)->current); + return 0; +} + +static int cmd_asm_log(const struct shell *shell, size_t argc, + char **argv) +{ + ARG_UNUSED(argc); + ARG_UNUSED(argv); + shell_print(shell, "Event Count = %d\n", event_log_idx); + shell_hexdump(shell, event_log, sizeof(event_log)); + return 0; +} + +static int cmd_asm_abr(const struct shell *shell, size_t argc, + char **argv) +{ + bool control = false; + + if (argc > 1 && !strncmp(argv[1], "enable", 6)) { + shell_print(shell, "Enable ABR FMCWDT2"); +#define ABR_CTRL_REG 0x7e620064 + uint32_t reg_val; + reg_val = sys_read32(ABR_CTRL_REG); + reg_val |= BIT(0); + sys_write32(reg_val, ABR_CTRL_REG); + } else { + shell_print(shell, "Disable ABR FMCWDT2"); + disable_abr_wdt(); + } + + return 0; +} + +static int cmd_asm_flash_cmp(const struct shell *shell, size_t argc, + char **argv) +{ + if (argc < 4) { + shell_print(shell, "asm flash_cmp DEVICE OFFSET_A OFFSET_B LENGTH"); + return 0; + } + char *dev_name = argv[1]; + size_t offset_a = strtol(argv[2], NULL, 16); + size_t offset_b = strtol(argv[3], NULL, 16); + size_t length = strtol(argv[4], NULL, 16); + + shell_print(shell, "Hash Dev:%s Offset_A:%p Offset_B:%p Length:%p", dev_name, offset_a, offset_b, length); + + struct device *dev = device_get_binding(dev_name); + if (dev == NULL) { + shell_print(shell, "Failed to bind device:%s", dev_name); + return 0; + } + + char buffer_a[128] = {0}; + char buffer_b[128] = {0}; + size_t byte_read = 0; + + while (byte_read <= length) { + size_t len = MIN(128, length - byte_read); + if (len == 0) + break; + flash_read(dev, offset_a + byte_read, buffer_a, len); + flash_read(dev, offset_b + byte_read, buffer_b, len); + if (memcmp(buffer_a, buffer_b, len) != 0) { + LOG_ERR("Offset_A=%08x Offset_B=%08x Different", offset_a + byte_read, offset_b + byte_read); + LOG_HEXDUMP_ERR(buffer_a, len, "Buffer A"); + LOG_HEXDUMP_ERR(buffer_b, len, "Buffer B"); + } + byte_read += len; + } + + return 0; +} + +static int cmd_asm_rot_recovery(const struct shell *shell, size_t argc, + char **argv) +{ + uint8_t status; + size_t offset = 0; + struct spi_engine_wrapper *spi_flash = getSpiEngineWrapper(); + uint32_t region_size = pfr_spi_get_device_size(ROT_INTERNAL_RECOVERY); + + LOG_INF("Erase PFR Active region size=%08x", region_size); + if (pfr_spi_erase_region(ROT_INTERNAL_ACTIVE, true, 0, region_size)){ + LOG_ERR("Erase PFR active region failed"); + return 0; + } + + LOG_INF("Copy PFR Recovery region to Active region"); + status = pfr_spi_region_read_write_between_spi(ROT_INTERNAL_RECOVERY, 0, + ROT_INTERNAL_ACTIVE, 0, region_size); + + if (!status) { + LOG_INF("Copy PFR Recovery region to Active region done"); + } else { + LOG_ERR("Recover PFR active region failed"); + } + + return 0; +} + +SHELL_STATIC_SUBCMD_SET_CREATE(sub_asm, + SHELL_CMD(show, NULL, "Show current state machine state", cmd_asm_show), + SHELL_CMD(log, NULL, "Show state machine event log", cmd_asm_log), + SHELL_CMD(abr, NULL, "Control FMCWDT2 timer manually: enable or disable", cmd_asm_abr), + SHELL_CMD(cmp, NULL, "Flash content compairson", cmd_asm_flash_cmp), + SHELL_CMD(rot_rc, NULL, "ROT firmware recoery", cmd_asm_rot_recovery), + SHELL_SUBCMD_SET_END +); + +SHELL_CMD_REGISTER(asm, &sub_asm, "Aspeed PFR State Machine Commands", NULL); + +SHELL_SUBCMD_DICT_SET_CREATE(sub_event, cmd_asm_event, + (INIT_DONE, INIT_DONE), + (VERIFY_UNPROVISIONED, VERIFY_UNPROVISIONED), + (VERIFY_STG_FAILED, VERIFY_STG_FAILED), + (VERIFY_RCV_FAILED, VERIFY_RCV_FAILED), + (VERIFY_ACT_FAILED, VERIFY_ACT_FAILED), + (VERIFY_DONE, VERIFY_DONE), + (RECOVERY_DONE, RECOVERY_DONE), + (RECOVERY_FAILED, RECOVERY_FAILED), + (RESET_DETECTED, RESET_DETECTED), + (UPDATE_REQUESTED, UPDATE_REQUESTED), + (UPDATE_DONE, UPDATE_DONE), + (UPDATE_FAILED, UPDATE_FAILED), + (PROVISION_CMD, PROVISION_CMD), + (WDT_TIMEOUT, WDT_TIMEOUT) +); + +SHELL_CMD_REGISTER(event, &sub_event, "State Machine Events", NULL); +#endif diff --git a/apps/aspeed-pfr/src/AspeedStateMachine/AspeedStateMachine.h b/apps/aspeed-pfr/src/AspeedStateMachine/AspeedStateMachine.h new file mode 100644 index 0000000..c3dff19 --- /dev/null +++ b/apps/aspeed-pfr/src/AspeedStateMachine/AspeedStateMachine.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2022 ASPEED Technology Inc. + * + * SPDX-License-Identifier: MIT + */ +#pragma once +#include +#include + +enum aspeed_pfr_state { + BOOT, + INIT, + UNPROVISIONED, + ROT_RECOVERY, + TMIN1, + TZERO, + FIRMWARE_VERIFY, + FIRMWARE_RECOVERY, + FIRMWARE_UPDATE, + RUNTIME, + SYSTEM_LOCKDOWN, + SYSTEM_REBOOT, +}; + +enum aspeed_pfr_event { + START_STATE_MACHINE, + INIT_DONE, + INIT_ROT_SECONDARY_BOOTED, + VERIFY_UNPROVISIONED, + VERIFY_STG_FAILED, + VERIFY_RCV_FAILED, + VERIFY_ACT_FAILED, + VERIFY_DONE, + RECOVERY_FAILED, + RECOVERY_DONE, + RESET_DETECTED, + UPDATE_REQUESTED, + WDT_CHECKPOINT, + WDT_TIMEOUT, + UPDATE_DONE, + UPDATE_FAILED, + PROVISION_CMD, +}; + +union aspeed_event_data { + /* Data in-place */ + uint32_t bit32; + uint8_t bit8[4]; + + /* Data somewhere else */ + uint8_t *ptr_u8; + uint32_t *ptr_u32; + void *ptr; +}; + +struct event_context { + /* Reserved for FIFO */ + void *fifo_reserved; + + /* User Defined Event */ + enum aspeed_pfr_event event; + union aspeed_event_data data; +}; + +struct smf_context { + /* Context data for smf */ + struct smf_ctx ctx; + + /* User Define State Data */ + + /* Input event, malloc by generator, release by state machine */ + struct event_context *event_ctx; + + /* Firmware state */ + AO_DATA bmc_active_object; + AO_DATA pch_active_object; +}; + +extern struct k_fifo aspeed_sm_fifo; + +void GenerateStateMachineEvent(enum aspeed_pfr_event evt, void *data); +void AspeedStateMachine(); diff --git a/apps/aspeed-pfr/src/I2c_Handler/BmcI2C_handler.h b/apps/aspeed-pfr/src/I2c_Handler/BmcI2C_handler.h index a4af1d2..905477e 100644 --- a/apps/aspeed-pfr/src/I2c_Handler/BmcI2C_handler.h +++ b/apps/aspeed-pfr/src/I2c_Handler/BmcI2C_handler.h @@ -3,3 +3,5 @@ * * SPDX-License-Identifier: MIT */ + +#pragma once diff --git a/apps/aspeed-pfr/src/I2c_Handler/PchI2c_handler.h b/apps/aspeed-pfr/src/I2c_Handler/PchI2c_handler.h index a4af1d2..cef9a9e 100644 --- a/apps/aspeed-pfr/src/I2c_Handler/PchI2c_handler.h +++ b/apps/aspeed-pfr/src/I2c_Handler/PchI2c_handler.h @@ -3,3 +3,6 @@ * * SPDX-License-Identifier: MIT */ + +#pragma once + diff --git a/apps/aspeed-pfr/src/Smbus_mailbox/Smbus_mailbox.c b/apps/aspeed-pfr/src/Smbus_mailbox/Smbus_mailbox.c index 6bebaf1..f082186 100644 --- a/apps/aspeed-pfr/src/Smbus_mailbox/Smbus_mailbox.c +++ b/apps/aspeed-pfr/src/Smbus_mailbox/Smbus_mailbox.c @@ -4,14 +4,22 @@ * SPDX-License-Identifier: MIT */ +#include +#include #include "Smbus_mailbox.h" #include "common/common.h" #include "intel_pfr/intel_pfr_pfm_manifest.h" #include "intel_pfr/intel_pfr_definitions.h" #include "intel_pfr/intel_pfr_provision.h" +#include +#include + +#include "AspeedStateMachine/AspeedStateMachine.h" + +LOG_MODULE_REGISTER(mailbox, CONFIG_LOG_DEFAULT_LEVEL); #if SMBUS_MAILBOX_DEBUG -#define DEBUG_PRINTF printk +#define DEBUG_PRINTF LOG_INF #else #define DEBUG_PRINTF(...) #endif @@ -22,6 +30,7 @@ #define PRIMARY_FLASH_REGION 1 #define SECONDARY_FLASH_REGION 2 +struct device *gSwMbxDev = NULL; uint8_t gReadOnlyRfAddress[READ_ONLY_RF_COUNT] = { 0x1, 0x2, 0x3, 0x04, 0x05, 0x06, 0x07, 0x0A, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F }; uint8_t gReadAndWriteRfAddress[READ_WRITE_RF_COUNT] = { 0x08, 0x09, 0x0B, 0x0C, 0x0D, 0x0E }; @@ -30,7 +39,7 @@ EVENT_CONTEXT DataContext; uint8_t gUfmFifoData[64]; uint8_t gReadFifoData[64]; -uint8_t gRootKeyHash[32]; +uint8_t gRootKeyHash[SHA384_DIGEST_LENGTH]; uint8_t gPchOffsets[12]; uint8_t gBmcOffsets[12]; uint8_t gUfmFifoLength; @@ -62,8 +71,8 @@ AO_DATA UpdateActiveObject; void ResetMailBox(void) { memset(&gSmbusMailboxData, 0, sizeof(gSmbusMailboxData)); - set_provision_status(COMMAND_DONE); // reset ufm status - set_provision_commandTrigger(0x00); + SetUfmStatusValue(COMMAND_DONE); // reset ufm status + SetUfmCmdTriggerValue(0x00); } /** * Function to Erase th UFM @@ -137,31 +146,229 @@ void get_image_svn(uint8_t image_id, uint32_t address, uint8_t *SVN, uint8_t *Ma *MinorVersion = Buffer.MinorVersion; } +#define SWMBX_NOTIFYEE_STACK_SIZE 1024 +struct k_thread swmbx_notifyee_thread; +K_THREAD_STACK_DEFINE(swmbx_notifyee_stack, SWMBX_NOTIFYEE_STACK_SIZE); +K_SEM_DEFINE(ufm_write_fifo_state_sem, 0, 1); +K_SEM_DEFINE(ufm_write_fifo_data_sem, 0, 1); +K_SEM_DEFINE(ufm_read_fifo_state_sem, 0, 1); +K_SEM_DEFINE(ufm_provision_trigger_sem, 0, 1); +K_SEM_DEFINE(bmc_update_intent_sem, 0, 1); +K_SEM_DEFINE(pch_update_intent_sem, 0, 1); +K_SEM_DEFINE(bmc_checkpoint_sem, 0, 1); +K_SEM_DEFINE(acm_checkpoint_sem, 0, 1); +K_SEM_DEFINE(bios_checkpoint_sem, 0, 1); + +void swmbx_notifyee_main(void *a, void *b, void *c) +{ + struct k_poll_event events[8]; + AO_DATA aodata[8]; + EVENT_CONTEXT evt_ctx[8]; + uint8_t buffer[8][2] = { { 0 } }; + + k_poll_event_init(&events[0], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, &ufm_write_fifo_data_sem); + k_poll_event_init(&events[1], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, &ufm_read_fifo_state_sem); + k_poll_event_init(&events[2], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, &ufm_provision_trigger_sem); + k_poll_event_init(&events[3], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, &bmc_update_intent_sem); + k_poll_event_init(&events[4], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, &pch_update_intent_sem); + k_poll_event_init(&events[5], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, &bmc_checkpoint_sem); + k_poll_event_init(&events[6], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, &acm_checkpoint_sem); + k_poll_event_init(&events[7], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, &bios_checkpoint_sem); + + int ret; + + while (1) { + ret = k_poll(events, 8, K_FOREVER); + + union aspeed_event_data data = {0}; + if (ret < 0) { + DEBUG_PRINTF("k_poll error ret=%d", ret); + continue; + } + + if (events[0].state == K_POLL_STATE_SEM_AVAILABLE) { + /* UFM Write FIFO from BMC/PCH */ + k_sem_take(events[0].sem, K_NO_WAIT); + // TODO: race condition + do { + uint8_t c; + + ret = swmbx_read(gSwMbxDev, true, UfmWriteFIFO, &c); + if (!ret) { + gUfmFifoData[gFifoData++] = c; + } + } while (!ret); + } else if (events[1].state == K_POLL_STATE_SEM_AVAILABLE) { + /* UFM Read FIFO empty prepare next data */ + k_sem_take(events[1].sem, K_NO_WAIT); + } else if (events[2].state == K_POLL_STATE_SEM_AVAILABLE) { + + /* UFM Provision Trigger */ + k_sem_take(events[2].sem, K_NO_WAIT); + aodata[2].ProcessNewCommand = 1; + aodata[2].type = I2C_EVENT; + evt_ctx[2].operation = I2C_HANDLE; + evt_ctx[2].i2c_data = buffer[2]; + data.bit8[0] = UfmCmdTriggerValue; + swmbx_get_msg(0, UfmCmdTriggerValue, &data.bit8[1]); + + GenerateStateMachineEvent(PROVISION_CMD, data.ptr); + } else if (events[3].state == K_POLL_STATE_SEM_AVAILABLE) { + /* BMC Update Intent */ + k_sem_take(events[3].sem, K_NO_WAIT); + aodata[3].ProcessNewCommand = 1; + aodata[3].type = I2C_EVENT; + evt_ctx[3].operation = I2C_HANDLE; + evt_ctx[3].i2c_data = buffer[3]; + data.bit8[0] = BmcUpdateIntent; + swmbx_get_msg(0, BmcUpdateIntent, &data.bit8[1]); + + GenerateStateMachineEvent(UPDATE_REQUESTED, data.ptr); + } else if (events[4].state == K_POLL_STATE_SEM_AVAILABLE) { + /* PCH Update Intent */ + k_sem_take(events[4].sem, K_NO_WAIT); + } else if (events[5].state == K_POLL_STATE_SEM_AVAILABLE) { + /* BMC Checkpoint */ + k_sem_take(events[5].sem, K_NO_WAIT); + aodata[5].ProcessNewCommand = 1; + aodata[5].type = I2C_EVENT; + evt_ctx[5].operation = I2C_HANDLE; + evt_ctx[5].i2c_data = buffer[5]; + data.bit8[0] = BmcCheckpoint; + swmbx_get_msg(0, BmcCheckpoint, &data.bit8[1]); + + GenerateStateMachineEvent(WDT_CHECKPOINT, data.ptr); + } else if (events[6].state == K_POLL_STATE_SEM_AVAILABLE) { + /* ACM Checkpoint */ + k_sem_take(events[6].sem, K_NO_WAIT); + GenerateStateMachineEvent(WDT_CHECKPOINT, NULL); + } else if (events[7].state == K_POLL_STATE_SEM_AVAILABLE) { + /* BIOS Checkpoint */ + k_sem_take(events[7].sem, K_NO_WAIT); + GenerateStateMachineEvent(WDT_CHECKPOINT, NULL); + } + + for (size_t i = 0; i < 8; ++i) + events[i].state = K_POLL_STATE_NOT_READY; + } +} + +void InitializeSoftwareMailbox(void) +{ + /* Top level mailbox device driver */ + const struct device *swmbx_dev = NULL; + int result; + + swmbx_dev = device_get_binding("SWMBX"); + if (swmbx_dev == NULL) { + DEBUG_PRINTF("%s: fail to bind %s", "SWMBX"); + return; + } + gSwMbxDev = swmbx_dev; + + /* Enable mailbox read/write notifiaction and FIFO */ + swmbx_enable_behavior(swmbx_dev, SWMBX_PROTECT | SWMBX_NOTIFY | SWMBX_FIFO, 1); + + /* Register mailbox notification semphore */ + swmbx_update_fifo(swmbx_dev, &ufm_write_fifo_state_sem, 0, UfmWriteFIFO, 0x40, SWMBX_FIFO_NOTIFY_STOP, true); + swmbx_update_fifo(swmbx_dev, &ufm_read_fifo_state_sem, 1, UfmReadFIFO, 0x40, SWMBX_FIFO_NOTIFY_STOP, true); + + /* swmbx_update_notify(dev, port, sem, addr, enable) */ + swmbx_update_notify(swmbx_dev, 0x0, &ufm_write_fifo_data_sem, UfmWriteFIFO, true); + swmbx_update_notify(swmbx_dev, 0x0, &ufm_provision_trigger_sem, UfmCmdTriggerValue, true); + swmbx_update_notify(swmbx_dev, 0x0, &bmc_update_intent_sem, BmcUpdateIntent, true); + swmbx_update_notify(swmbx_dev, 0x0, &pch_update_intent_sem, PchPfmActiveSvn, true); + swmbx_update_notify(swmbx_dev, 0x0, &bmc_checkpoint_sem, BmcCheckpoint, true); + swmbx_update_notify(swmbx_dev, 0x0, &acm_checkpoint_sem, AcmCheckpoint, true); + swmbx_update_notify(swmbx_dev, 0x0, &bios_checkpoint_sem, BiosCheckpoint, true); + + /* Protect bit: + * 0 means readable/writable + * 1 means read-only + * + * Port and access_control[]: + * 0 for BMC + * 1 for PCH + */ + uint32_t access_control[2][8] = { + /* BMC */ + { + 0xfff704ff, // 1fh ~ 00h + 0xffffffff, // 3fh ~ 20h CPLD RoT Hash + 0xffffffff, // 5fh ~ 40h CPLD RoT Hash + 0xfffffffa, // 7fh ~ 60h + 0xffffffff, // 9fh ~ 80h ACM/BIOS Scrachpad + 0xffffffff, // bfh ~ a0h ACM/BIOS Scrachpad + 0x00000000, // dfh ~ c0h BMC scrachpad + 0x00000000, // ffh ~ e0h BMC scrachpad + }, + /* PCH */ + { + 0xfff884ff, // 1fh ~ 00h + 0xffffffff, // 3fh ~ 20h CPLD RoT Hash + 0xffffffff, // 5fh ~ 40h CPLD RoT Hash + 0xfffffff5, // 7fh ~ 60h + 0x00000000, // 9fh ~ 80h ACM/BIOS Scrachpad + 0x00000000, // bfh ~ a0h ACM/BIOS Scrachpad + 0xffffffff, // dfh ~ c0h BMC scrachpad + 0xffffffff, // ffh ~ e0h BMC scrachpad + }, + }; + result = swmbx_apply_protect(swmbx_dev, 0, access_control[0], 0, 8); + LOG_INF("Mailbox protection apply result=%d", result); + result = swmbx_apply_protect(swmbx_dev, 1, access_control[1], 0, 8); + LOG_INF("Mailbox protection apply result=%d", result); + + /* Register slave device to bus device */ + const struct device *dev = NULL; + + dev = device_get_binding("SWMBX_SLAVE_BMC"); + if (dev) + i2c_slave_driver_register(dev); + + /* TODO: CPU0 */ + dev = device_get_binding("SWMBX_SLAVE_CPU"); + if (dev) + i2c_slave_driver_register(dev); + + k_tid_t swmbx_tid = k_thread_create( + &swmbx_notifyee_thread, + swmbx_notifyee_stack, + SWMBX_NOTIFYEE_STACK_SIZE, + swmbx_notifyee_main, + NULL, NULL, NULL, + 5, 0, K_NO_WAIT); + k_thread_name_set(swmbx_tid, "Software Mailbox Handler"); + +} + void InitializeSmbusMailbox(void) { + uint32_t UfmStatus; + + InitializeSoftwareMailbox(); ResetMailBox(); + SetCpldIdentifier(0xDE); SetCpldReleaseVersion(CPLD_RELEASE_VERSION); uint8_t CurrentSvn = 0; // get root key hash - get_provision_data_in_flash(ROOT_KEY_HASH, gRootKeyHash, SHA256_DIGEST_LENGTH); + get_provision_data_in_flash(ROOT_KEY_HASH, gRootKeyHash, SHA384_DIGEST_LENGTH); get_provision_data_in_flash(PCH_ACTIVE_PFM_OFFSET, gPchOffsets, sizeof(gPchOffsets)); get_provision_data_in_flash(BMC_ACTIVE_PFM_OFFSET, gBmcOffsets, sizeof(gBmcOffsets)); + get_provision_data_in_flash(UFM_STATUS, (uint8_t *)&UfmStatus, sizeof(UfmStatus)); - uint32_t UfmStatus; - - get_provision_data_in_flash(UFM_STATUS, &UfmStatus, sizeof(uint32_t) / sizeof(uint8_t)); - - uint8_t bmc_provision_flag = 1 << BMC_OFFSET_PROVISION_FLAG; - uint8_t pch_provision_flag = 1 << PCH_OFFSET_PROVISION_FLAG; - uint8_t root_key_provision_flag = 1 << ROOT_KEY_HASH_PROVISION_FLAG; - uint8_t provision_flag = root_key_provision_flag | bmc_provision_flag | pch_provision_flag; + if (CheckUfmStatus(UfmStatus, UFM_STATUS_PROVISIONED_ROOT_KEY_HASH_BIT_MASK | + UFM_STATUS_PROVISIONED_PCH_OFFSETS_BIT_MASK | + UFM_STATUS_PROVISIONED_BMC_OFFSETS_BIT_MASK)) { + SetUfmStatusValue(UFM_PROVISIONED); + } - if (memcmp(UfmStatus & provision_flag, 0) == 0) - set_provision_status(UFM_PROVISIONED); + if (CheckUfmStatus(UfmStatus, UFM_STATUS_LOCK_BIT_MASK)) + SetUfmStatusValue(UFM_LOCKED); - if (memcmp(UfmStatus & pch_provision_flag, 0) == 0) { + if (CheckUfmStatus(UfmStatus, UFM_STATUS_PROVISIONED_PCH_OFFSETS_BIT_MASK)) { uint8_t PCHActiveMajorVersion, PCHActiveMinorVersion; uint8_t PCHActiveSVN; uint32_t pch_pfm_address; @@ -185,7 +392,7 @@ void InitializeSmbusMailbox(void) SetPchPfmRecoverMinorVersion(PCHRecoveryMinorVersion); } // f1 - if (memcmp(UfmStatus & bmc_provision_flag, 0) == 0) { + if (CheckUfmStatus(UfmStatus, UFM_STATUS_PROVISIONED_BMC_OFFSETS_BIT_MASK)) { uint8_t BMCActiveMajorVersion, BMCActiveMinorVersion; uint8_t BMCActiveSVN; uint32_t bmc_pfm_address; @@ -216,114 +423,117 @@ void InitializeSmbusMailbox(void) SetCpldRotSvn(current_svn); } -void SetCpldIdentifier(byte Data) -{ - gSmbusMailboxData.CpldIdentifier = Data; - ////UpdateMailboxRegisterFile(CpldIdentifier,(uint8_t)gSmbusMailboxData.CpldIdentifier); -} -byte GetCpldIdentifier(void) -{ - return gSmbusMailboxData.CpldIdentifier; -} - -void SetCpldReleaseVersion(byte Data) -{ - gSmbusMailboxData.CpldReleaseVersion = Data; - ////UpdateMailboxRegisterFile(CpldReleaseVersion,(uint8_t)gSmbusMailboxData.CpldReleaseVersion); -} -byte GetCpldReleaseVersion(void) -{ - return gSmbusMailboxData.CpldReleaseVersion; -} +#define MBX_REG_SETTER(REG) \ + void Set##REG(byte Data) \ + { \ + swmbx_write(gSwMbxDev, false, REG, &Data); \ + } + +#define MBX_REG_INC(REG) \ + void Inc##REG() \ + { \ + byte data; \ + swmbx_read(gSwMbxDev, false, REG, &data); \ + ++data; \ + swmbx_write(gSwMbxDev, false, REG, &data); \ + } + +#define MBX_REG_GETTER(REG) \ + byte Get##REG(void) \ + { \ + byte data; \ + swmbx_read(gSwMbxDev, false, REG, &data); \ + return data; \ + } -void SetCpldRotSvn(byte Data) -{ - gSmbusMailboxData.CpldRoTSVN = Data; - ////UpdateMailboxRegisterFile(CpldRoTSVN,(uint8_t)gSmbusMailboxData.CpldRoTSVN); -} -byte GetCpldRotSvn(void) -{ - return gSmbusMailboxData.CpldRoTSVN; -} - -byte GetPlatformState(void) -{ - return gSmbusMailboxData.PlatformState; -} +#define MBX_REG_SETTER_GETTER(REG) \ + MBX_REG_SETTER(REG) \ + MBX_REG_GETTER(REG) + +#define MBX_REG_INC_GETTER(REG) \ + MBX_REG_INC(REG) \ + MBX_REG_GETTER(REG) + +MBX_REG_SETTER_GETTER(CpldIdentifier); +MBX_REG_SETTER_GETTER(CpldReleaseVersion); +MBX_REG_SETTER_GETTER(CpldRotSvn); +MBX_REG_GETTER(PlatformState); +MBX_REG_INC_GETTER(RecoveryCount); +MBX_REG_SETTER_GETTER(LastRecoveryReason); +MBX_REG_INC_GETTER(PanicEventCount); +MBX_REG_SETTER_GETTER(LastPanicReason); +MBX_REG_SETTER_GETTER(MajorErrorCode); +MBX_REG_SETTER_GETTER(MinorErrorCode); +MBX_REG_GETTER(UfmStatusValue); +MBX_REG_GETTER(UfmCommand); +MBX_REG_SETTER_GETTER(UfmCmdTriggerValue); +MBX_REG_SETTER_GETTER(BmcCheckpoint); +MBX_REG_SETTER_GETTER(AcmCheckpoint); +MBX_REG_SETTER_GETTER(BiosCheckpoint); +MBX_REG_SETTER_GETTER(BmcUpdateIntent); +MBX_REG_SETTER_GETTER(PchPfmActiveSvn); +MBX_REG_SETTER_GETTER(PchPfmActiveMajorVersion); +MBX_REG_SETTER_GETTER(PchPfmActiveMinorVersion); +MBX_REG_SETTER_GETTER(BmcPfmActiveSvn); +MBX_REG_SETTER_GETTER(BmcPfmActiveMajorVersion); +MBX_REG_SETTER_GETTER(BmcPfmActiveMinorVersion); +MBX_REG_SETTER_GETTER(PchPfmRecoverSvn); +MBX_REG_SETTER_GETTER(PchPfmRecoverMajorVersion); +MBX_REG_SETTER_GETTER(PchPfmRecoverMinorVersion); +MBX_REG_SETTER_GETTER(BmcPfmRecoverSvn); +MBX_REG_SETTER_GETTER(BmcPfmRecoverMajorVersion); +MBX_REG_SETTER_GETTER(BmcPfmRecoverMinorVersion); void SetPlatformState(byte PlatformStateData) { - gSmbusMailboxData.PlatformState = PlatformStateData; - ////UpdateMailboxRegisterFile(PlatformState, (uint8_t)gSmbusMailboxData.PlatformState); -} - -byte GetRecoveryCount(void) -{ - return gSmbusMailboxData.Recoverycount; -} - -void IncRecoveryCount(void) -{ - gSmbusMailboxData.Recoverycount++; - ////UpdateMailboxRegisterFile(Recoverycount, (uint8_t)gSmbusMailboxData.Recoverycount); -} - -byte GetLastRecoveryReason(void) -{ - return gSmbusMailboxData.LastRecoveryReason; -} - -void SetLastRecoveryReason(LAST_RECOVERY_REASON_VALUE LastRecoveryReasonValue) -{ - gSmbusMailboxData.LastRecoveryReason = LastRecoveryReasonValue; - ////UpdateMailboxRegisterFile(LastRecoveryReason, (uint8_t)gSmbusMailboxData.LastRecoveryReason); -} - -byte GetPanicEventCount(void) -{ - return gSmbusMailboxData.PanicEventCount; -} - -void IncPanicEventCount(void) -{ - gSmbusMailboxData.PanicEventCount++; - // UpdateMailboxRegisterFile(PanicEventCount, (uint8_t)gSmbusMailboxData.PanicEventCount); +#if defined(CONFIG_PLATFORM_STATE_LED) + uint8_t bit; + static const struct gpio_dt_spec leds[] = { + GPIO_DT_SPEC_GET_BY_IDX(DT_INST(0, demo_gpio_basic_api), platform_state_out_gpios, 0), + GPIO_DT_SPEC_GET_BY_IDX(DT_INST(0, demo_gpio_basic_api), platform_state_out_gpios, 1), + GPIO_DT_SPEC_GET_BY_IDX(DT_INST(0, demo_gpio_basic_api), platform_state_out_gpios, 2), + GPIO_DT_SPEC_GET_BY_IDX(DT_INST(0, demo_gpio_basic_api), platform_state_out_gpios, 3), + GPIO_DT_SPEC_GET_BY_IDX(DT_INST(0, demo_gpio_basic_api), platform_state_out_gpios, 4), + GPIO_DT_SPEC_GET_BY_IDX(DT_INST(0, demo_gpio_basic_api), platform_state_out_gpios, 5), + GPIO_DT_SPEC_GET_BY_IDX(DT_INST(0, demo_gpio_basic_api), platform_state_out_gpios, 6), + GPIO_DT_SPEC_GET_BY_IDX(DT_INST(0, demo_gpio_basic_api), platform_state_out_gpios, 7)}; + + for(uint8_t bit = 0; bit < 8; ++bit) { + gpio_pin_configure_dt(&leds[bit], GPIO_OUTPUT); + gpio_pin_set(leds[bit].port, leds[bit].pin, !(PlatformStateData & BIT(bit))); + } +#endif + swmbx_write(gSwMbxDev, false, PlatformState, &PlatformStateData); } -byte GetLastPanicReason(void) +// UFM Status +void SetUfmStatusValue(uint8_t UfmStatusBitMask) { - return gSmbusMailboxData.LastPanicReason; -} + uint8_t status = GetUfmStatusValue(); -void SetLastPanicReason(LAST_PANIC_REASON_VALUE LastPanicReasonValue) -{ - gSmbusMailboxData.LastPanicReason = LastPanicReasonValue; - // UpdateMailboxRegisterFile(LastPanicReason, (uint8_t)gSmbusMailboxData.LastPanicReason); + status |= UfmStatusBitMask; + swmbx_write(gSwMbxDev, false, UfmStatusValue, &status); } -byte GetMajorErrorCode(void) +void ClearUfmStatusValue(uint8_t UfmStatusBitMask) { - return gSmbusMailboxData.MajorErrorCode; -} + uint8_t status = GetUfmStatusValue(); -void SetMajorErrorCode(MAJOR_ERROR_CODE_VALUE MajorErrorCodeValue) -{ - gSmbusMailboxData.MajorErrorCode = MajorErrorCodeValue; - // UpdateMailboxRegisterFile(MajorErrorCode, (uint8_t)gSmbusMailboxData.MajorErrorCode); + status &= ~UfmStatusBitMask; + swmbx_write(gSwMbxDev, false, UfmStatusValue, &status); } -byte GetMinorErrorCode(void) +void SetUfmFlashStatus(uint32_t UfmStatus, uint32_t UfmStatusBitMask) { - return gSmbusMailboxData.MinorErrorCode; + UfmStatus &= ~UfmStatusBitMask; + set_provision_data_in_flash(UFM_STATUS, &UfmStatus, 4); } -void SetMinorErrorCode(MINOR_ERROR_CODE_VALUE MinorErrorCodeValue) +int CheckUfmStatus(uint32_t UfmStatus, uint32_t UfmStatusBitMask) { - gSmbusMailboxData.MinorErrorCode = MinorErrorCodeValue; - // UpdateMailboxRegisterFile(MinorErrorCode,(uint8_t)gSmbusMailboxData.MinorErrorCode); + return ((~UfmStatus & UfmStatusBitMask) == UfmStatusBitMask); } -// UFM Status bool IsUfmStatusCommandBusy(void) { return gSmbusMailboxData.CommandBusy ? true : false; @@ -359,75 +569,6 @@ bool IsUfmStatusPITL2CompleteSuccess(void) return gSmbusMailboxData.PITL2CompleteSuccess ? true : false; } -byte get_provision_status(void) -{ - uint8_t UfmStatus = 0; - - UfmStatus = gSmbusMailboxData.UfmStatusValue; - if (gProvisionCount == 3) - gProvisinDoneFlag = TRUE; - - return UfmStatus; -} - -void set_provision_status(byte UfmStatus) -{ - gSmbusMailboxData.UfmStatusValue = UfmStatus; - // UpdateMailboxRegisterFile(UfmStatusValue, (uint8_t)gSmbusMailboxData.UfmStatusValue); -} - -byte get_provision_command(void) -{ - uint8_t UfmCommandData = 0; - - if (gBmcFlag) - UfmCommandData = gSmbusMailboxData.UfmCommand; - - return UfmCommandData; -} - -void set_provision_command(byte UfmCommandValue) -{ - gSmbusMailboxData.UfmCommand = UfmCommandValue; - // UpdateMailboxRegisterFile(UfmCommand, (uint8_t)gSmbusMailboxData.UfmCommand); -} - -void set_provision_commandTrigger(byte UfmCommandTrigger) -{ - gSmbusMailboxData.UfmCmdTriggerValue = UfmCommandTrigger; - // UpdateMailboxRegisterFile(UfmCmdTriggerValue, (uint8_t)gSmbusMailboxData.UfmCmdTriggerValue); -} - -byte get_provision_commandTrigger(void) -{ - return gSmbusMailboxData.UfmCmdTriggerValue; -} - -byte GetBmcCheckPoint(void) -{ - return gSmbusMailboxData.BmcCheckpoint; -} - -void SetBmcCheckPoint(byte BmcCheckpointData) -{ - // TODO Allow for updating from BMC Reset to Boot Complete - gSmbusMailboxData.BmcCheckpoint = BmcCheckpointData; - // UpdateMailboxRegisterFile(BmcCheckpoint, (uint8_t)gSmbusMailboxData.BmcCheckpoint); -} - -byte GetBiosCheckPoint(void) -{ - return gSmbusMailboxData.BiosCheckpoint; -} - -void SetBiosCheckPoint(byte BiosCheckpointData) -{ - - gSmbusMailboxData.BiosCheckpoint = BiosCheckpointData; - // UpdateMailboxRegisterFile(BiosCheckpoint, (uint8_t)gSmbusMailboxData.BiosCheckpoint); - -} - // PCH UpdateIntent bool IsPchUpdateIntentPCHActive(void) { @@ -522,154 +663,12 @@ bool IsBmcUpdateIntentUpdateAtReset(void) return gSmbusMailboxData.BmcUpdateIntentUpdateAtReset ? true : false; } -byte GetBmcUpdateIntent(void) -{ - return gSmbusMailboxData.BmcUpdateIntentValue; -} - -void SetBmcUpdateIntent(byte BmcUpdateIntent) -{ - gSmbusMailboxData.BmcUpdateIntentValue = BmcUpdateIntent; - // UpdateMailboxRegisterFile(BmcUpdateIntentValue, (uint8_t)gSmbusMailboxData.BmcUpdateIntentValue); -} - -byte GetPchPfmActiveSvn(void) -{ - return gSmbusMailboxData.PchPFMActiveSVN; -} - -void SetPchPfmActiveSvn(byte ActiveSVN) -{ - gSmbusMailboxData.PchPFMActiveSVN = ActiveSVN; - // UpdateMailboxRegisterFile(PchPFMActiveSVN, (uint8_t)gSmbusMailboxData.PchPFMActiveSVN); -} - -byte GetPchPfmActiveMajorVersion(void) -{ - return gSmbusMailboxData.PchPFMActiveMajorVersion; -} - -void SetPchPfmActiveMajorVersion(byte ActiveMajorVersion) -{ - gSmbusMailboxData.PchPFMActiveMajorVersion = ActiveMajorVersion; - // UpdateMailboxRegisterFile(PchPFMActiveMajorVersion, (uint8_t)gSmbusMailboxData.PchPFMActiveMajorVersion); -} - -byte GetPchPfmActiveMinorVersion(void) -{ - return gSmbusMailboxData.PchPFMActiveMinorVersion; -} - -void SetPchPfmActiveMinorVersion(byte ActiveMinorVersion) -{ - gSmbusMailboxData.PchPFMActiveMinorVersion = ActiveMinorVersion; - // UpdateMailboxRegisterFile(PchPFMActiveMinorVersion, (uint8_t)gSmbusMailboxData.PchPFMActiveMinorVersion); -} - -byte GetBmcPfmActiveSvn(void) -{ - return gSmbusMailboxData.BmcPFMActiveSVN; -} - -void SetBmcPfmActiveSvn(byte ActiveSVN) -{ - gSmbusMailboxData.BmcPFMActiveSVN = ActiveSVN; - // UpdateMailboxRegisterFile(BmcPFMActiveSVN, (uint8_t)gSmbusMailboxData.BmcPFMActiveSVN); -} - -byte GetBmcPfmActiveMajorVersion(void) -{ - return gSmbusMailboxData.BmcPFMActiveMajorVersion; -} - -void SetBmcPfmActiveMajorVersion(byte ActiveMajorVersion) -{ - gSmbusMailboxData.BmcPFMActiveMajorVersion = ActiveMajorVersion; - // UpdateMailboxRegisterFile(BmcPFMActiveMajorVersion, (uint8_t)gSmbusMailboxData.BmcPFMActiveMajorVersion); -} - -byte GetBmcPfmActiveMinorVersion(void) -{ - return gSmbusMailboxData.BmcPFMActiveMinorVersion; -} - -void SetBmcPfmActiveMinorVersion(byte ActiveMinorVersion) -{ - gSmbusMailboxData.BmcPFMActiveMinorVersion = ActiveMinorVersion; - // UpdateMailboxRegisterFile(BmcPFMActiveMinorVersion, (uint8_t)gSmbusMailboxData.BmcPFMActiveMinorVersion); -} - -byte GetPchPfmRecoverSvn(void) -{ - return gSmbusMailboxData.PchPFMRecoverSVN; -} - -void SetPchPfmRecoverSvn(byte RecoverSVN) -{ - gSmbusMailboxData.PchPFMRecoverSVN = RecoverSVN; - // UpdateMailboxRegisterFile(PchPFMRecoverSVN, (uint8_t)gSmbusMailboxData.PchPFMRecoverSVN); -} - -byte GetPchPfmRecoverMajorVersion(void) -{ - return gSmbusMailboxData.PchPFMRecoverMajorVersion; -} - -void SetPchPfmRecoverMajorVersion(byte RecoverMajorVersion) -{ - gSmbusMailboxData.PchPFMRecoverMajorVersion = RecoverMajorVersion; - // UpdateMailboxRegisterFile(PchPFMRecoverMajorVersion, (uint8_t)gSmbusMailboxData.PchPFMRecoverMajorVersion); -} - -byte GetPchPfmRecoverMinorVersion(void) -{ - return gSmbusMailboxData.PchPFMRecoverMinorVersion; -} - -void SetPchPfmRecoverMinorVersion(byte RecoverMinorVersion) -{ - gSmbusMailboxData.PchPFMRecoverMinorVersion = RecoverMinorVersion; - // UpdateMailboxRegisterFile(PchPFMRecoverMinorVersion, (uint8_t)gSmbusMailboxData.PchPFMRecoverMinorVersion); -} - -byte GetBmcPfmRecoverSvn(void) -{ - return gSmbusMailboxData.BmcPFMRecoverSVN; -} - -void SetBmcPfmRecoverSvn(byte RecoverSVN) -{ - gSmbusMailboxData.BmcPFMRecoverSVN = RecoverSVN; - // UpdateMailboxRegisterFile(BmcPFMRecoverSVN, (uint8_t)gSmbusMailboxData.BmcPFMRecoverSVN); -} - -byte GetBmcPfmRecoverMajorVersion(void) -{ - return gSmbusMailboxData.BmcPFMRecoverMajorVersion; -} - -void SetBmcPfmRecoverMajorVersion(byte RecoverMajorVersion) -{ - gSmbusMailboxData.BmcPFMRecoverMajorVersion = RecoverMajorVersion; - // UpdateMailboxRegisterFile(BmcPFMRecoverMajorVersion, (uint8_t)gSmbusMailboxData.BmcPFMRecoverMajorVersion); -} - -byte GetBmcPfmRecoverMinorVersion(void) -{ - return gSmbusMailboxData.BmcPFMRecoverMinorVersion; -} - -void SetBmcPfmRecoverMinorVersion(byte RecoverMinorVersion) -{ - gSmbusMailboxData.BmcPFMRecoverMinorVersion = RecoverMinorVersion; - // UpdateMailboxRegisterFile(BmcPFMRecoverMinorVersion, (uint8_t)gSmbusMailboxData.BmcPFMRecoverMinorVersion); -} byte *GetCpldFpgaRotHash(void) { - uint8_t HashData[SHA256_DIGEST_LENGTH] = { 0 }; + uint8_t HashData[SHA384_DIGEST_LENGTH] = { 0 }; - memcpy(HashData, gSmbusMailboxData.CpldFPGARoTHash, SHA256_DIGEST_LENGTH); + memcpy(HashData, gSmbusMailboxData.CpldFPGARoTHash, SHA384_DIGEST_LENGTH); // add obb read code for bmc return gSmbusMailboxData.CpldFPGARoTHash; } @@ -695,22 +694,22 @@ unsigned char ProvisionRootKeyHash(void) uint8_t Status; uint32_t UfmStatus; - get_provision_data_in_flash(UFM_STATUS, &UfmStatus, sizeof(uint32_t) / sizeof(uint8_t)); - if (gRootKeyHash == NULL) - return Failure; - if (((UfmStatus & 1)) && ((UfmStatus & 2))) { - Status = set_provision_data_in_flash(ROOT_KEY_HASH, gRootKeyHash, SHA256_DIGEST_LENGTH); + get_provision_data_in_flash(UFM_STATUS, (uint8_t *)&UfmStatus, sizeof(UfmStatus)); + if (!CheckUfmStatus(UfmStatus, UFM_STATUS_LOCK_BIT_MASK) && !CheckUfmStatus(UfmStatus, UFM_STATUS_PROVISIONED_ROOT_KEY_HASH_BIT_MASK)) { + Status = set_provision_data_in_flash(ROOT_KEY_HASH, gRootKeyHash, SHA384_DIGEST_LENGTH); if (Status == Success) { - UfmStatus &= 0xFD; - Status = set_provision_data_in_flash(UFM_STATUS, (uint8_t *)&UfmStatus, sizeof(uint32_t) / sizeof(uint8_t)); + DEBUG_PRINTF("Root key provisioned"); + SetUfmFlashStatus(UfmStatus, UFM_STATUS_PROVISIONED_ROOT_KEY_HASH_BIT_MASK); return Success; - } else { - return Failure; } - } else { - printk("Unsupported error\n"); - return UnSupported; + + DEBUG_PRINTF("Root key provision failed..."); + erase_provision_flash(); + return Failure; } + + DEBUG_PRINTF("%s, Provisioned or UFM Locked", __func__); + return UnSupported; } unsigned char ProvisionPchOffsets(void) @@ -719,23 +718,21 @@ unsigned char ProvisionPchOffsets(void) uint32_t UfmStatus; get_provision_data_in_flash(UFM_STATUS, (uint8_t *)&UfmStatus, sizeof(UfmStatus)); - - if (((UfmStatus & 1)) && ((UfmStatus & 4))) { - + if (!CheckUfmStatus(UfmStatus, UFM_STATUS_LOCK_BIT_MASK) && !CheckUfmStatus(UfmStatus, UFM_STATUS_PROVISIONED_PCH_OFFSETS_BIT_MASK)) { Status = set_provision_data_in_flash(PCH_ACTIVE_PFM_OFFSET, gPchOffsets, sizeof(gPchOffsets)); if (Status == Success) { - DEBUG_PRINTF("Ps\r\n"); - UfmStatus &= 0xFB; - Status = set_provision_data_in_flash(UFM_STATUS, (uint8_t *)&UfmStatus, sizeof(uint32_t) / sizeof(uint8_t)); - } else { - DEBUG_PRINTF("PCH Offsets Provision failed...\r\n"); - erase_provision_flash(); - set_provision_status(COMMAND_ERROR); + DEBUG_PRINTF("PCH offsets provisioned"); + SetUfmFlashStatus(UfmStatus, UFM_STATUS_PROVISIONED_PCH_OFFSETS_BIT_MASK); + return Success; } - return Success; - } else { - return UnSupported; + + DEBUG_PRINTF("PCH offsets provision failed..."); + erase_provision_flash(); + return Failure; } + + DEBUG_PRINTF("%s, Provisioned or UFM Locked", __func__); + return UnSupported; } unsigned char ProvisionBmcOffsets(void) @@ -745,49 +742,53 @@ unsigned char ProvisionBmcOffsets(void) get_provision_data_in_flash(UFM_STATUS, (uint8_t *)&UfmStatus, sizeof(UfmStatus)); - if (((UfmStatus & 1)) && ((UfmStatus & 8))) { - + if (!CheckUfmStatus(UfmStatus, UFM_STATUS_LOCK_BIT_MASK) && !CheckUfmStatus(UfmStatus, UFM_STATUS_PROVISIONED_BMC_OFFSETS_BIT_MASK)) { Status = set_provision_data_in_flash(BMC_ACTIVE_PFM_OFFSET, gBmcOffsets, sizeof(gBmcOffsets)); if (Status == Success) { - UfmStatus &= 0xF7; - Status = set_provision_data_in_flash(UFM_STATUS, (uint8_t *)&UfmStatus, sizeof(UfmStatus)); - DEBUG_PRINTF("Bs\r\n"); - - } else { - DEBUG_PRINTF("BMC Offsets Provision failed...\r\n"); - erase_provision_flash(); - set_provision_status(COMMAND_ERROR); + SetUfmFlashStatus(UfmStatus, UFM_STATUS_PROVISIONED_BMC_OFFSETS_BIT_MASK); + DEBUG_PRINTF("BMC offsets provisioned"); + return Success; } - return Success; - } else { - return UnSupported; + + DEBUG_PRINTF("BMC offsets provision failed..."); + erase_provision_flash(); + return Failure; } + + DEBUG_PRINTF("%s, Provisioned or UFM Locked", __func__); + return UnSupported; } void lock_provision_flash(void) { - uint8_t Status; uint32_t UfmStatus; get_provision_data_in_flash(UFM_STATUS, (uint8_t *)&UfmStatus, sizeof(UfmStatus)); - UfmStatus |= 1; - - set_provision_data_in_flash(UFM_STATUS, (uint8_t *)&UfmStatus, sizeof(UfmStatus)); + SetUfmFlashStatus(UfmStatus, UFM_STATUS_LOCK_BIT_MASK); } void ReadRootKey(void) { - memcpy(gReadFifoData, gRootKeyHash, SHA256_DIGEST_LENGTH); + get_provision_data_in_flash(ROOT_KEY_HASH, gRootKeyHash, SHA384_DIGEST_LENGTH); + memcpy(gReadFifoData, gRootKeyHash, SHA384_DIGEST_LENGTH); + for (size_t i = 0; i < SHA384_DIGEST_LENGTH; ++i) + swmbx_write(gSwMbxDev, true, UfmReadFIFO, gRootKeyHash + i); } void ReadPchOfsets(void) { + get_provision_data_in_flash(PCH_ACTIVE_PFM_OFFSET, gPchOffsets, sizeof(gPchOffsets)); memcpy(gReadFifoData, gPchOffsets, sizeof(gPchOffsets)); + for (size_t i = 0; i < sizeof(gPchOffsets); ++i) + swmbx_write(gSwMbxDev, true, UfmReadFIFO, gPchOffsets + i); } void ReadBmcOffets(void) { + get_provision_data_in_flash(BMC_ACTIVE_PFM_OFFSET, gBmcOffsets, sizeof(gBmcOffsets)); memcpy(gReadFifoData, gBmcOffsets, sizeof(gBmcOffsets)); + for (size_t i = 0; i < sizeof(gBmcOffsets); ++i) + swmbx_write(gSwMbxDev, true, UfmReadFIFO, gBmcOffsets + i); } /** @@ -797,110 +798,98 @@ void ReadBmcOffets(void) **/ void process_provision_command(void) { + uint32_t UfmFlashStatus; byte UfmCommandData; - byte UfmStatus; byte Status = 0; - UfmStatus = get_provision_status(); + UfmCommandData = GetUfmCommand(); + get_provision_data_in_flash(UFM_STATUS, (uint8_t *)&UfmFlashStatus, sizeof(UfmFlashStatus)); - if (UfmStatus & UFM_LOCKED) { - // Ufm locked - DEBUG_PRINTF("UFM LOCKED\n\r"); - return; + if (CheckUfmStatus(UfmFlashStatus, UFM_STATUS_LOCK_BIT_MASK)) { + if ((UfmCommandData < READ_ROOT_KEY) || (UfmCommandData > READ_BMC_OFFSET)) { + // Ufm locked + DEBUG_PRINTF("UFM Locked and Dropped Write Command: 0x%x", UfmCommandData); + return; + } } - UfmCommandData = get_provision_command(); switch (UfmCommandData) { case ERASE_CURRENT: - set_provision_status(COMMAND_BUSY); Status = erase_provision_flash(); if (Status == Success) { gProvisionCount = 0; - set_provision_status(COMMAND_DONE); - } else { - set_provision_status(COMMAND_ERROR); + ClearUfmStatusValue(UFM_CLEAR_ON_ERASE_COMMAND); + } else { + SetUfmStatusValue(COMMAND_ERROR); } break; case PROVISION_ROOT_KEY: - set_provision_status(COMMAND_BUSY); - memcpy(gRootKeyHash, gUfmFifoData, SHA256_DIGEST_LENGTH); - gProvisionCount++; + memcpy(gRootKeyHash, gUfmFifoData, SHA384_DIGEST_LENGTH); + gProvisionCount |= 1 << 0; gProvisionData = 1; - set_provision_status(COMMAND_DONE); - break; case PROVISION_PIT_KEY: // Update password to provsioned UFM - DEBUG_PRINTF("PIT IS NOT SUPPORTED\n\r"); + DEBUG_PRINTF("PIT IS NOT SUPPORTED"); break; case PROVISION_PCH_OFFSET: - set_provision_status(COMMAND_BUSY); memcpy(gPchOffsets, gUfmFifoData, sizeof(gPchOffsets)); - gProvisionCount++; + gProvisionCount |= 1 << 1; gProvisionData = 1; - set_provision_status(COMMAND_DONE); - break; case PROVISION_BMC_OFFSET: - set_provision_status(COMMAND_BUSY); - memcpy(gBmcOffsets, gUfmFifoData, sizeof(gPchOffsets)); - gProvisionCount++; + memcpy(gBmcOffsets, gUfmFifoData, sizeof(gBmcOffsets)); + gProvisionCount |= 1 << 2; gProvisionData = 1; - set_provision_status(COMMAND_DONE); - break; case LOCK_UFM: // lock ufm lock_provision_flash(); - set_provision_status(COMMAND_DONE | UFM_LOCKED); + SetUfmStatusValue(UFM_LOCKED); break; case READ_ROOT_KEY: ReadRootKey(); - set_provision_status(COMMAND_DONE); break; case READ_PCH_OFFSET: ReadPchOfsets(); - set_provision_status(COMMAND_DONE); break; case READ_BMC_OFFSET: ReadBmcOffets(); - set_provision_status(COMMAND_DONE | UFM_PROVISIONED); - // set_provision_status(COMMAND_DONE); break; - case ENABLE_PIT_LEVEL_1_PROTECTION: // EnablePitLevel1(); - DEBUG_PRINTF("PIT IS NOT SUPPORTED\n\r"); + DEBUG_PRINTF("PIT IS NOT SUPPORTED"); break; case ENABLE_PIT_LEVEL_2_PROTECTION: // EnablePitLevel2(); - DEBUG_PRINTF("PIT IS NOT SUPPORTED\n\r"); + DEBUG_PRINTF("PIT IS NOT SUPPORTED"); break; } - if ((gProvisionCount == 3) && (gProvisionData == 1)) { - set_provision_status(COMMAND_BUSY); - // printk("Calling provisioing process..\n"); + + if ((gProvisionCount == 0x07) && (gProvisionData == 1)) { + DEBUG_PRINTF("Calling provisioing process.."); gProvisionData = 0; + gProvisionCount = 0; Status = ProvisionRootKeyHash(); if (Status != Success) { - set_provision_status(COMMAND_ERROR); + SetUfmStatusValue(COMMAND_ERROR); return; } Status = ProvisionPchOffsets(); if (Status != Success) { - set_provision_status(COMMAND_ERROR); + SetUfmStatusValue(COMMAND_ERROR); return; } Status = ProvisionBmcOffsets(); if (Status != Success) { - printk("Status: %x\n", Status); - set_provision_status(COMMAND_ERROR); + DEBUG_PRINTF("Status: %x", Status); + SetUfmStatusValue(COMMAND_ERROR); return; } - set_provision_status(COMMAND_DONE | UFM_PROVISIONED); + SetUfmStatusValue(UFM_PROVISIONED); CPLD_STATUS cpld_status; @@ -923,12 +912,12 @@ void UpdateBmcCheckpoint(byte Data) // Start WDT for BMC boot gBmcBootDone = START; gBMCWatchDogTimer = 0; - SetBmcCheckPoint(Data); + SetBmcCheckpoint(Data); } else - DEBUG_PRINTF("BMC boot completed. Checkpoint update not allowed\r\n"); + DEBUG_PRINTF("BMC boot completed. Checkpoint update not allowed"); if (Data == PausingExecutionBlock) { - printk("Enter PausingExecutionBlock Disable Timer\n"); + DEBUG_PRINTF("Enter PausingExecution: Block Disable Timer"); AspeedPFR_DisableTimer(BMC_EVENT); } if (Data == ResumedExecutionBlock) @@ -937,7 +926,7 @@ void UpdateBmcCheckpoint(byte Data) // BMC boot completed if (Data == CompletingexecutionBlock || Data == ReadToBootOS) { // If execution completed disable timer - printk("Enter CompletingexecutionBlock Disable Timer\n"); + DEBUG_PRINTF("Enter Completingexecution: Block Disable Timer"); AspeedPFR_DisableTimer(BMC_EVENT); gBmcBootDone = TRUE; gBMCWatchDogTimer = -1; @@ -979,7 +968,7 @@ void UpdateBiosCheckpoint(byte Data) gBootCheckpointReceived = true; gPCHWatchDogTimer = -1; SetPlatformState(T0_BIOS_BOOTED); - DEBUG_PRINTF("BIOS boot completed. Checkpoint update not allowed\r\n"); + DEBUG_PRINTF("BIOS boot completed. Checkpoint update not allowed"); } if (Data == AUTHENTICATION_FAILED) { gBiosBootDone = FALSE; @@ -989,7 +978,7 @@ void UpdateBiosCheckpoint(byte Data) } if (gBmcBootDone == TRUE && gBiosBootDone == TRUE) SetPlatformState(T0_BOOT_COMPLETED); - SetBiosCheckPoint(Data); + SetBiosCheckpoint(Data); } void PublishUpdateEvent(uint8_t ImageType, uint8_t FlashRegion) @@ -1003,7 +992,7 @@ void PublishUpdateEvent(uint8_t ImageType, uint8_t FlashRegion) UpdateEventData.image = ImageType; if (post_smc_action(UPDATE, &UpdateActiveObject, &UpdateEventData)) { - DEBUG_PRINTF("%s : event queue not available !\n", __func__); + DEBUG_PRINTF("%s : event queue not available !", __func__); return; } } @@ -1014,7 +1003,7 @@ void UpdateIntentHandle(byte Data, uint32_t Source) uint8_t PchActiveStatus; uint8_t BmcActiveStatus; - DEBUG_PRINTF("\r\n Update Intent = 0x%x\r\n", Data); + DEBUG_PRINTF(" Update Intent = 0x%x", Data); if (Data & UpdateAtReset) { // Getting cpld status from UFM @@ -1042,12 +1031,12 @@ void UpdateIntentHandle(byte Data, uint32_t Source) cpld_update_status.Region[1].Recoveryregion = 1; } if (Data & HROTRecoveryUpdate) - DEBUG_PRINTF("HROTRecoveryUpdate not supported\r\n"); + DEBUG_PRINTF("HROTRecoveryUpdate not supported"); if (Data & DymanicUpdate) - DEBUG_PRINTF("DymanicUpdate not supported\r\n"); + DEBUG_PRINTF("DymanicUpdate not supported"); // Setting updated cpld status to ufm ufm_write(UPDATE_STATUS_UFM, UPDATE_STATUS_ADDRESS, &cpld_update_status, sizeof(CPLD_STATUS)); - } else { + } else { if (Data & PchActiveUpdate) { if ((Data & PchActiveUpdate) && (Data & PchRecoveryUpdate)) { ufm_read(UPDATE_STATUS_UFM, UPDATE_STATUS_ADDRESS, &cpld_update_status, sizeof(CPLD_STATUS)); @@ -1058,7 +1047,7 @@ void UpdateIntentHandle(byte Data, uint32_t Source) PublishUpdateEvent(PCH_EVENT, PRIMARY_FLASH_REGION); return; } - if (Source == BmcUpdateIntentValue) { + if (Source == BmcUpdateIntent) { ufm_read(UPDATE_STATUS_UFM, UPDATE_STATUS_ADDRESS, &cpld_update_status, sizeof(CPLD_STATUS)); cpld_update_status.BmcToPchStatus = 1; ufm_write(UPDATE_STATUS_UFM, UPDATE_STATUS_ADDRESS, &cpld_update_status, sizeof(CPLD_STATUS)); @@ -1068,7 +1057,7 @@ void UpdateIntentHandle(byte Data, uint32_t Source) } if (Data & PchRecoveryUpdate) { - if (Source == BmcUpdateIntentValue) { + if (Source == BmcUpdateIntent) { ufm_read(UPDATE_STATUS_UFM, UPDATE_STATUS_ADDRESS, &cpld_update_status, sizeof(CPLD_STATUS)); cpld_update_status.BmcToPchStatus = 1; ufm_write(UPDATE_STATUS_UFM, UPDATE_STATUS_ADDRESS, &cpld_update_status, sizeof(CPLD_STATUS)); @@ -1079,20 +1068,18 @@ void UpdateIntentHandle(byte Data, uint32_t Source) PublishUpdateEvent(ROT_TYPE, PRIMARY_FLASH_REGION); if (Data & BmcActiveUpdate) { - if ((Data & BmcActiveUpdate) && (Data & BmcRecoveryUpdate)) { PublishUpdateEvent(BMC_EVENT, PRIMARY_FLASH_REGION); return; } - PublishUpdateEvent(BMC_EVENT, PRIMARY_FLASH_REGION); } if (Data & BmcRecoveryUpdate) PublishUpdateEvent(BMC_EVENT, SECONDARY_FLASH_REGION); if (Data & HROTRecoveryUpdate) - DEBUG_PRINTF("HROTRecoveryUpdate not supported\r\n"); + DEBUG_PRINTF("HROTRecoveryUpdate not supported"); if (Data & DymanicUpdate) - DEBUG_PRINTF("DymanicUpdate not supported\r\n"); + DEBUG_PRINTF("DymanicUpdate not supported"); } } @@ -1103,7 +1090,7 @@ void UpdateIntentHandle(byte Data, uint32_t Source) */ bool WatchDogTimer(int ImageType) { - DEBUG_PRINTF("WDT Update Tiggers\r\n"); + DEBUG_PRINTF("WDT Update Tiggers"); if (ImageType == PCH_EVENT) { gPCHWatchDogTimer = 0; gBiosBootDone = FALSE; @@ -1126,72 +1113,29 @@ uint8_t PchBmcCommands(unsigned char *CipherText, uint8_t ReadFlag) byte DataToSend = 0; uint8_t i = 0; + DEBUG_PRINTF("%s CipherText: %02x %02x", __func__, CipherText[0], CipherText[1]); + switch (CipherText[0]) { - case CpldIdentifier: - DataToSend = GetCpldIdentifier(); - break; - case CpldReleaseVersion: - DataToSend = GetCpldReleaseVersion(); - break; - case CpldRoTSVN: - DataToSend = GetCpldRotSvn(); - break; - case PlatformState: - DataToSend = GetPlatformState(); - break; - case Recoverycount: - DataToSend = GetRecoveryCount(); - break; - case LastRecoveryReason: - DataToSend = GetLastRecoveryReason(); - break; - case PanicEventCount: - DataToSend = GetPanicEventCount(); - break; - case LastPanicReason: - DataToSend = GetLastPanicReason(); - break; - case MajorErrorCode: - DataToSend = GetMajorErrorCode(); - break; - case MinorErrorCode: - DataToSend = GetMinorErrorCode(); - break; - case UfmStatusValue: - DataToSend = get_provision_status(); - break; - case UfmCommand: - if (ReadFlag == TRUE) - DataToSend = get_provision_command(); - else - set_provision_command(CipherText[1]); - break; case UfmCmdTriggerValue: - if (ReadFlag == TRUE) { - DataToSend = get_provision_commandTrigger(); - } else { - if (CipherText[1] & EXECUTE_UFM_COMMAND) { // If bit 0 set - // Execute command specified at UFM/Provisioning Command register - process_provision_command(); - } else if (CipherText[1] & FLUSH_WRITE_FIFO) { // Flush Write FIFO - // Need to read UFM Write FIFO offest - memset(&gUfmFifoData, 0, sizeof(gUfmFifoData)); - gFifoData = 0; - } else if (CipherText[1] & FLUSH_READ_FIFO) { // flush Read FIFO - // Need to read UFM Read FIFO offest - memset(&gReadFifoData, 0, sizeof(gReadFifoData)); - gFifoData = 0; - mailBox_index = 0; - } + if (CipherText[1] & EXECUTE_UFM_COMMAND) { // If bit 0 set + // Execute command specified at UFM/Provisioning Command register + ClearUfmStatusValue(UFM_CLEAR_ON_NEW_COMMAND); + SetUfmStatusValue(COMMAND_BUSY); + process_provision_command(); + ClearUfmStatusValue(COMMAND_BUSY); + SetUfmStatusValue(COMMAND_DONE); + } else if (CipherText[1] & FLUSH_WRITE_FIFO) { // Flush Write FIFO + // Need to read UFM Write FIFO offest + memset(&gUfmFifoData, 0, sizeof(gUfmFifoData)); + swmbx_flush_fifo(gSwMbxDev, UfmWriteFIFO); + gFifoData = 0; + } else if (CipherText[1] & FLUSH_READ_FIFO) { // flush Read FIFO + // Need to read UFM Read FIFO offest + memset(&gReadFifoData, 0, sizeof(gReadFifoData)); + swmbx_flush_fifo(gSwMbxDev, UfmReadFIFO); + gFifoData = 0; + mailBox_index = 0; } - - break; - case UfmWriteFIFO: - gUfmFifoData[gFifoData++] = CipherText[1]; - break; - case UfmReadFIFO: - DataToSend = gReadFifoData[mailBox_index]; - mailBox_index++; break; case BmcCheckpoint: UpdateBmcCheckpoint(CipherText[1]); @@ -1202,62 +1146,16 @@ uint8_t PchBmcCommands(unsigned char *CipherText, uint8_t ReadFlag) case BiosCheckpoint: UpdateBiosCheckpoint(CipherText[1]); break; - case PchUpdateIntentValue: - if (!ReadFlag) { - SetPchUpdateIntent(CipherText[1]); - UpdateIntentHandle(CipherText[1], PchUpdateIntentValue); - } - break; - case BmcUpdateIntentValue: - if (!ReadFlag) { - SetBmcUpdateIntent(CipherText[1]); - UpdateIntentHandle(CipherText[1], BmcUpdateIntentValue); - } - break; - case PchPFMActiveSVN: - DataToSend = GetPchPfmActiveSvn(); - break; - case PchPFMActiveMajorVersion: - DataToSend = GetPchPfmActiveMajorVersion(); - break; - case PchPFMActiveMinorVersion: - DataToSend = GetPchPfmActiveMinorVersion(); - break; - case BmcPFMActiveSVN: - DataToSend = GetBmcPfmActiveSvn(); - break; - case BmcPFMActiveMajorVersion: - DataToSend = GetBmcPfmActiveMajorVersion(); - break; - case BmcPFMActiveMinorVersion: - DataToSend = GetBmcPfmActiveMinorVersion(); - break; - case PchPFMRecoverSVN: - DataToSend = GetPchPfmRecoverSvn(); - break; - case PchPFMRecoverMajorVersion: - DataToSend = GetPchPfmRecoverMajorVersion(); - break; - case PchPFMRecoverMinorVersion: - DataToSend = GetPchPfmRecoverMinorVersion(); - break; - case BmcPFMRecoverSVN: - DataToSend = GetBmcPfmRecoverSvn(); - break; - case BmcPFMRecoverMajorVersion: - DataToSend = GetBmcPfmRecoverMajorVersion(); - break; - case BmcPFMRecoverMinorVersion: - DataToSend = GetBmcPfmRecoverMinorVersion(); - break; - case CpldFPGARoTHash: - break; - case AcmBiosScratchPad: + case PchUpdateIntent: + SetPchUpdateIntent(CipherText[1]); + UpdateIntentHandle(CipherText[1], PchUpdateIntent); break; - case BmcScratchPad: + case BmcUpdateIntent: + SetBmcUpdateIntent(CipherText[1]); + UpdateIntentHandle(CipherText[1], BmcUpdateIntent); break; default: - DEBUG_PRINTF("Mailbox command not found\r\n"); + DEBUG_PRINTF("Mailbox command not found"); break; } diff --git a/apps/aspeed-pfr/src/Smbus_mailbox/Smbus_mailbox.h b/apps/aspeed-pfr/src/Smbus_mailbox/Smbus_mailbox.h index 1091911..67bd553 100644 --- a/apps/aspeed-pfr/src/Smbus_mailbox/Smbus_mailbox.h +++ b/apps/aspeed-pfr/src/Smbus_mailbox/Smbus_mailbox.h @@ -3,8 +3,9 @@ * * SPDX-License-Identifier: MIT */ -#ifndef PFR_SMBUS_MAILBOX_H_ -#define PFR_SMBUS_MAILBOX_H_ + +#pragma once + #include #include // #include @@ -120,39 +121,39 @@ typedef struct _SMBUS_MAIL_BOX_ { } SMBUS_MAIL_BOX; typedef enum _SMBUS_MAILBOX_RF_ADDRESS_READONLY { - CpldIdentifier, - CpldReleaseVersion, - CpldRoTSVN, - PlatformState, - Recoverycount, - LastRecoveryReason, - PanicEventCount, - LastPanicReason, - MajorErrorCode, - MinorErrorCode, - UfmStatusValue, - UfmCommand, - UfmCmdTriggerValue, - UfmWriteFIFO, - UfmReadFIFO, - BmcCheckpoint, - AcmCheckpoint, - BiosCheckpoint, - PchUpdateIntentValue, - BmcUpdateIntentValue, - PchPFMActiveSVN, - PchPFMActiveMajorVersion, - PchPFMActiveMinorVersion, - BmcPFMActiveSVN, - BmcPFMActiveMajorVersion, - BmcPFMActiveMinorVersion, - PchPFMRecoverSVN, - PchPFMRecoverMajorVersion, - PchPFMRecoverMinorVersion, - BmcPFMRecoverSVN, - BmcPFMRecoverMajorVersion, - BmcPFMRecoverMinorVersion, - CpldFPGARoTHash, + CpldIdentifier = 0x00, + CpldReleaseVersion = 0x01, + CpldRotSvn = 0x02, + PlatformState = 0x03, + RecoveryCount = 0x04, + LastRecoveryReason = 0x05, + PanicEventCount = 0x06, + LastPanicReason = 0x07, + MajorErrorCode = 0x08, + MinorErrorCode = 0x09, + UfmStatusValue = 0x0a, + UfmCommand = 0x0b, + UfmCmdTriggerValue = 0x0c, + UfmWriteFIFO = 0x0d, + UfmReadFIFO = 0x0e, + BmcCheckpoint = 0x0f, + AcmCheckpoint = 0x10, + BiosCheckpoint = 0x11, + PchUpdateIntent = 0x12, + BmcUpdateIntent = 0x13, + PchPfmActiveSvn = 0x14, + PchPfmActiveMajorVersion = 0x15, + PchPfmActiveMinorVersion = 0x16, + BmcPfmActiveSvn = 0x17, + BmcPfmActiveMajorVersion = 0x18, + BmcPfmActiveMinorVersion = 0x19, + PchPfmRecoverSvn = 0x1a, + PchPfmRecoverMajorVersion = 0x1b, + PchPfmRecoverMinorVersion = 0x1c, + BmcPfmRecoverSvn = 0x1d, + BmcPfmRecoverMajorVersion = 0x1e, + BmcPfmRecoverMinorVersion = 0x1f, + CpldFPGARoTHash = 0x20, /* 0x20 - 0x5f */ Reserved = 0x63, AcmBiosScratchPad = 0x80, BmcScratchPad = 0xc0, @@ -207,6 +208,8 @@ typedef struct _PFM_STRUCTURE { uint32_t Length; } PFM_STRUCTURE; +#pragma pack() + static SMBUS_MAIL_BOX gSmbusMailboxData = { 0 }; unsigned char set_provision_data_in_flash(uint8_t addr, uint8_t *DataBuffer, uint8_t DataSize); @@ -229,15 +232,21 @@ void SetPlatformState(byte PlatformStateData); byte GetRecoveryCount(void); void IncRecoveryCount(void); byte GetLastRecoveryReason(void); -void SetLastRecoveryReason(LAST_RECOVERY_REASON_VALUE LastRecoveryReasonValue); + +// void SetLastRecoveryReason(LAST_RECOVERY_REASON_VALUE LastRecoveryReasonValue); +void SetLastRecoveryReason(byte LastRecoveryReasonValue); + byte GetPanicEventCount(void); void IncPanicEventCount(void); byte GetLastPanicReason(void); -void SetLastPanicReason(LAST_PANIC_REASON_VALUE LastPanicReasonValue); +// void SetLastPanicReason(LAST_PANIC_REASON_VALUE LastPanicReasonValue); +void SetLastPanicReason(byte LastPanicReasonValue); byte GetMajorErrorCode(void); -void SetMajorErrorCode(MAJOR_ERROR_CODE_VALUE MajorErrorCodeValue); +// void SetMajorErrorCode(MAJOR_ERROR_CODE_VALUE MajorErrorCodeValue); +void SetMajorErrorCode(byte MajorErrorCodeValue); byte GetMinorErrorCode(void); -void SetMinorErrorCode(MINOR_ERROR_CODE_VALUE MinorErrorCodeValue); +// void SetMinorErrorCode(MINOR_ERROR_CODE_VALUE MinorErrorCodeValue); +void SetMinorErrorCode(byte MinorErrorCodeValue); bool IsUfmStatusCommandBusy(void); bool IsUfmStatusCommandDone(void); bool IsUfmStatusCommandError(void); @@ -245,8 +254,9 @@ bool IsUfmStatusLocked(void); bool IsUfmStatusUfmProvisioned(void); bool IsUfmStatusPitLevel1Enforced(void); bool IsUfmStatusPITL2CompleteSuccess(void); -byte get_provision_status(void); -void set_provision_status(byte UfmStatus); +byte GetUfmStatusValue(void); +void SetUfmStatusValue(uint8_t UfmStatusBitMask); +void ClearUfmStatusValue(uint8_t UfmStatusBitMask); byte get_provision_command(void); void set_provision_command(byte UfmCommandValue); void set_provision_commandTrigger(byte UfmCommandTrigger); @@ -314,11 +324,16 @@ bool WatchDogTimer(int ImageType); uint8_t PchBmcCommands(unsigned char *CipherText, uint8_t ReadFlag); void get_image_svn(uint8_t image_id, uint32_t address, uint8_t *SVN, uint8_t *MajorVersion, uint8_t *MinorVersion); -#define ROOT_KEY_HASH_PROVISION_FLAG 1 -#define PCH_OFFSET_PROVISION_FLAG 2 -#define BMC_OFFSET_PROVISION_FLAG 3 +#define UFM_STATUS_LOCK_BIT_MASK 0b1 +#define UFM_STATUS_PROVISIONED_ROOT_KEY_HASH_BIT_MASK 0b10 +#define UFM_STATUS_PROVISIONED_PCH_OFFSETS_BIT_MASK 0b100 +#define UFM_STATUS_PROVISIONED_BMC_OFFSETS_BIT_MASK 0b1000 +#define UFM_STATUS_PROVISIONED_PIT_ID_BIT_MASK 0b10000 +#define UFM_STATUS_PIT_L1_ENABLE_BIT_MASK 0b100000 +#define UFM_STATUS_PIT_L2_ENABLE_BIT_MASK 0b1000000 +#define UFM_STATUS_PIT_HASH_STORED_BIT_MASK 0b10000000 +#define UFM_STATUS_PIT_L2_PASSED_BIT_MASK 0b100000000 extern uint8_t gBiosBootDone; extern uint8_t gBmcBootDone; -#endif /* PFR_SMBUS_MAILBOX_H_ */ diff --git a/apps/aspeed-pfr/src/StateMachineAction/StateMachineActions.c b/apps/aspeed-pfr/src/StateMachineAction/StateMachineActions.c index 111cc70..1d7b32f 100644 --- a/apps/aspeed-pfr/src/StateMachineAction/StateMachineActions.c +++ b/apps/aspeed-pfr/src/StateMachineAction/StateMachineActions.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: MIT */ +#include #include "StateMachineActions.h" #include "state_machine/common_smc.h" #include "include/SmbusMailBoxCom.h" @@ -18,6 +19,9 @@ #include "intel_pfr/intel_pfr_definitions.h" #include "spi_filter/spi_filter_wrapper.h" #include "logging/debug_log.h"// State Machine log saving +#include "AspeedStateMachine/AspeedStateMachine.h" + +LOG_MODULE_DECLARE(state_machine, CONFIG_LOG_DEFAULT_LEVEL); #define RELEASE_PLATFORM 1 @@ -26,7 +30,7 @@ #define SMBUS_WRITE 0x45 #if PF_STATUS_DEBUG -#define DEBUG_PRINTF printk +#define DEBUG_PRINTF LOG_INF #else #define DEBUG_PRINTF(...) #endif @@ -37,47 +41,49 @@ AO_DATA BmcActiveObjectData, PchActiveObjectData; static void wdt_callback_bmc_timeout(void) { - printk("enter %s\n", __func__); + DEBUG_PRINTF("enter %s", __func__); SetLastPanicReason(BMC_WDT_EXPIRE); + GenerateStateMachineEvent(WDT_TIMEOUT, NULL); } static void wdt_callback_pch_timeout(void) { - printk("enter %s\n", __func__); + DEBUG_PRINTF("enter %s", __func__); SetLastPanicReason(ACM_WDT_EXPIRE); + GenerateStateMachineEvent(WDT_TIMEOUT, NULL); } void AspeedPFR_EnableTimer(int type) { - struct watchdog_config *wdt_config; + struct watchdog_config wdt_config; const struct device *wdt_dev; int ret = 0; uint32_t count = 0; - wdt_config->wdt_cfg.window.min = 0; - wdt_config->reset_option = WDT_FLAG_RESET_NONE; + wdt_config.wdt_cfg.window.min = 0; + wdt_config.reset_option = WDT_FLAG_RESET_NONE; if (type == BMC_EVENT) { - DEBUG_PRINTF("---------------------------------------\r\n"); - DEBUG_PRINTF(" Start BMC Timer\r\n"); - DEBUG_PRINTF("---------------------------------------\r\n"); - wdt_config->wdt_cfg.window.max = BMC_MAXTIMEOUT; - wdt_config->wdt_cfg.callback = wdt_callback_bmc_timeout; + DEBUG_PRINTF("---------------------------------------"); + DEBUG_PRINTF(" Start BMC Timer"); + DEBUG_PRINTF("---------------------------------------"); + wdt_config.wdt_cfg.window.max = BMC_MAXTIMEOUT; + wdt_config.wdt_cfg.callback = wdt_callback_bmc_timeout; wdt_dev = device_get_binding(WDT_Devices_List[0]); } else if (type == PCH_EVENT) { - DEBUG_PRINTF("---------------------------------------\r\n"); - DEBUG_PRINTF(" Start PCH Timer\r\n"); - DEBUG_PRINTF("---------------------------------------\r\n"); - wdt_config->wdt_cfg.window.max = BIOS_MAXTIMEOUT; - wdt_config->wdt_cfg.callback = wdt_callback_pch_timeout; + DEBUG_PRINTF("---------------------------------------"); + DEBUG_PRINTF(" Start PCH Timer"); + DEBUG_PRINTF("---------------------------------------"); + wdt_config.wdt_cfg.window.max = BIOS_MAXTIMEOUT; + wdt_config.wdt_cfg.callback = wdt_callback_pch_timeout; wdt_dev = device_get_binding(WDT_Devices_List[1]); } if (!wdt_dev) { - printk("wdt_timer_err: cannot find wdt device.\n"); + DEBUG_PRINTF("wdt_timer_err: cannot find wdt device."); return; } - ret = watchdog_init(wdt_dev, wdt_config); + ret = watchdog_init(wdt_dev, &wdt_config); watchdog_feed(wdt_dev, 0); } @@ -87,15 +93,15 @@ void AspeedPFR_DisableTimer(int type) const struct device *wdt_dev; if (type == BMC_EVENT) { - DEBUG_PRINTF("---------------------------------------\r\n"); - DEBUG_PRINTF(" Disable BMC Timer\r\n"); - DEBUG_PRINTF("---------------------------------------\r\n"); + DEBUG_PRINTF("---------------------------------------"); + DEBUG_PRINTF(" Disable BMC Timer"); + DEBUG_PRINTF("---------------------------------------"); wdt_dev = device_get_binding(WDT_Devices_List[0]); } else if (type == PCH_EVENT) { - DEBUG_PRINTF("---------------------------------------\r\n"); - DEBUG_PRINTF(" Disable PCH Timer\r\n"); - DEBUG_PRINTF("---------------------------------------\r\n"); + DEBUG_PRINTF("---------------------------------------"); + DEBUG_PRINTF(" Disable PCH Timer"); + DEBUG_PRINTF("---------------------------------------"); wdt_dev = device_get_binding(WDT_Devices_List[1]); } @@ -177,9 +183,9 @@ void PublishPchEvents(void) void PublishInitialEvents(void) { - byte provision_state = get_provision_status(); + byte provision_state = GetUfmStatusValue(); - if (provision_state == UFM_PROVISIONED) { + if (provision_state & UFM_PROVISIONED) { check_staging_area(); #if BMC_SUPPORT PublishBmcEvents(); @@ -232,17 +238,17 @@ void CheckAndReleasePlatform(void *AoData, void *EventContext) if (EventData->image == BMC_EVENT) { release_bmc = 1; - DEBUG_PRINTF("---------------------------------------\r\n"); - DEBUG_PRINTF(" BMC authentication success\r\n"); - DEBUG_PRINTF("---------------------------------------\r\n"); + DEBUG_PRINTF("---------------------------------------"); + DEBUG_PRINTF(" BMC authentication success"); + DEBUG_PRINTF("---------------------------------------"); PublishPchEvents(); } if (EventData->image == PCH_EVENT) { release_pch = 1; release_bmc = 1; - DEBUG_PRINTF("---------------------------------------\r\n"); - DEBUG_PRINTF(" PCH authentication success\r\n"); - DEBUG_PRINTF("---------------------------------------\r\n"); + DEBUG_PRINTF("---------------------------------------"); + DEBUG_PRINTF(" PCH authentication success"); + DEBUG_PRINTF("---------------------------------------"); T0Transition(release_bmc, release_pch); } @@ -627,7 +633,6 @@ void handlePostUpdateSuccess(void *AoData) if (ActiveObjectData->type == ROT_TYPE) pfr_cpld_update_reboot(); - } void handlePostUpdateFailure(void *AoData) @@ -643,15 +648,19 @@ void T0Transition(int releaseBmc, int releasePCH) int provision_status; SetPlatformState(ENTER_T0); - provision_status = get_provision_status(); - if (provision_status == UFM_PROVISIONED) { + provision_status = GetUfmStatusValue(); + if (provision_status & UFM_PROVISIONED) { // enable spi filtering if (releaseBmc) { - init_SPI_RW_Region(0); + init_SPI_RW_Region(BMC_SPI); AspeedPFR_EnableTimer(BMC_EVENT); } if (releasePCH) { +#if defined(CONFIG_ASPEED_DC_SCM) || defined(CONFIG_BMC_DUAL_FLASH) + init_SPI_RW_Region(PCH_SPI); +#else init_SPI_RW_Region(1); +#endif AspeedPFR_EnableTimer(PCH_EVENT); } } @@ -675,15 +684,15 @@ void LockDownPlatform(void *AoData) int image_type = ao_data->type; if (image_type == BMC_EVENT) { - DEBUG_PRINTF("---------------------------------------\r\n"); - DEBUG_PRINTF(" BMC authentication failed\r\n"); - DEBUG_PRINTF("---------------------------------------\r\n"); + DEBUG_PRINTF("---------------------------------------"); + DEBUG_PRINTF(" BMC authentication failed"); + DEBUG_PRINTF("---------------------------------------"); execute_next_smc_action(LOCKDOWN, AoData, NULL); } else if (image_type == PCH_EVENT) { - DEBUG_PRINTF("---------------------------------------\r\n"); - DEBUG_PRINTF(" PCH authentication failed\r\n"); - DEBUG_PRINTF("---------------------------------------\r\n"); - DEBUG_PRINTF("ao_data->InLockdown: %d\r\n", ao_data->InLockdown); + DEBUG_PRINTF("---------------------------------------"); + DEBUG_PRINTF(" PCH authentication failed"); + DEBUG_PRINTF("---------------------------------------"); + DEBUG_PRINTF("ao_data->InLockdown: %d", ao_data->InLockdown); if (ao_data->InLockdown == 1) { uint8_t ReleasePch = 0, ReleaseBmc = RELEASE_PLATFORM; @@ -699,7 +708,7 @@ int process_i2c_command(void *static_data, void *event_context) EVENT_CONTEXT *I2CData = (EVENT_CONTEXT *) event_context; if (I2CActiveObjectData->ProcessNewCommand) { - // printk("I2CData->i2c_data[0]: %x, I2CData->i2c_data[1]: %x\n", I2CData->i2c_data[0], I2CData->i2c_data[1]); + // LOG_INF("I2CData->i2c_data[0]: %x, I2CData->i2c_data[1]: %x", I2CData->i2c_data[0], I2CData->i2c_data[1]); PchBmcCommands(I2CData->i2c_data, 0); I2CActiveObjectData->ProcessNewCommand = 0; } diff --git a/apps/aspeed-pfr/src/StateMachineAction/StateMachineActions.h b/apps/aspeed-pfr/src/StateMachineAction/StateMachineActions.h index 0943403..7634fee 100644 --- a/apps/aspeed-pfr/src/StateMachineAction/StateMachineActions.h +++ b/apps/aspeed-pfr/src/StateMachineAction/StateMachineActions.h @@ -4,8 +4,7 @@ * SPDX-License-Identifier: MIT */ -#ifndef SMC_ACTIONS_H_ -#define SMC_ACTIONS_H_ +#pragma once #include "state_machine.h" #include "common_smc.h" @@ -106,4 +105,4 @@ int StartBmcAOWithEvent(void); int StartPchAOWithEvent(void); int process_i2c_command(void *static_data, void *event_context); void T0Transition(int releaseBmc, int releasePCH); -#endif /* FALZARGOSMC_ACTIONS_H_ */ + diff --git a/apps/aspeed-pfr/src/common/common.h b/apps/aspeed-pfr/src/common/common.h index 5311dd6..88044db 100644 --- a/apps/aspeed-pfr/src/common/common.h +++ b/apps/aspeed-pfr/src/common/common.h @@ -4,8 +4,8 @@ * SPDX-License-Identifier: MIT */ -#ifndef ZEPHYR_ASPEED_PFR_SRC_COMMON_COMMON_H_ -#define ZEPHYR_ASPEED_PFR_SRC_COMMON_COMMON_H_ +#pragma once + /* Cerberus Includes*/ #include @@ -38,6 +38,7 @@ #include #define hashStorageLength 256 +#define MAX_BIOS_BOOT_TIME 300 struct flash *getFlashDeviceInstance(void); struct flash_master *getFlashMasterInstance(void); @@ -49,7 +50,5 @@ struct spi_flash *getSpiFlashInstance(void); struct rsa_engine_wrapper *getRsaEngineInstance(void); struct I2CSlave_engine_wrapper *getI2CSlaveEngineInstance(void); struct spi_filter_engine_wrapper *getSpiFilterEngineWrapper(void); +struct spi_engine_wrapper *getSpiEngineWrapper(void); -#endif /* ZEPHYR_ASPEED_PFR_SRC_COMMON_COMMON_H_ */ - -#define MAX_BIOS_BOOT_TIME 300 diff --git a/apps/aspeed-pfr/src/common/pfm_headers.h b/apps/aspeed-pfr/src/common/pfm_headers.h index 8abf546..4d6d39b 100644 --- a/apps/aspeed-pfr/src/common/pfm_headers.h +++ b/apps/aspeed-pfr/src/common/pfm_headers.h @@ -4,8 +4,7 @@ * SPDX-License-Identifier: MIT */ -#ifndef ZEPHYR_ASPEED_PFR_SRC_COMMON_PFM_HEADER_H_ -#define ZEPHYR_ASPEED_PFR_SRC_COMMON_PFM_HEADER_H_ +#pragma once #include @@ -77,4 +76,3 @@ struct recovery_image { uint8_t image_length[4]; }; -#endif /* ZEPHYR_ASPEED_PFR_SRC_COMMON_PFM_HEADER_H_ */ diff --git a/apps/aspeed-pfr/src/context_manager/context_manager.h b/apps/aspeed-pfr/src/context_manager/context_manager.h index 1deb3a7..341707b 100644 --- a/apps/aspeed-pfr/src/context_manager/context_manager.h +++ b/apps/aspeed-pfr/src/context_manager/context_manager.h @@ -4,8 +4,7 @@ * SPDX-License-Identifier: MIT */ -#ifndef CONTEXT_MANAGER_H_ -#define CONTEXT_MANAGER_H_ +#pragma once #include #include @@ -31,4 +30,4 @@ struct Context_Manager { int app_context_init(struct app_context *context); struct app_context *getappcontextInstance(void); static int save_cpld_context(struct app_context *context); -#endif // #ifndef CONTEXT_MANAGER_H_ + diff --git a/apps/aspeed-pfr/src/engineManager/engine_manager.c b/apps/aspeed-pfr/src/engineManager/engine_manager.c index ad09b90..15b14d7 100644 --- a/apps/aspeed-pfr/src/engineManager/engine_manager.c +++ b/apps/aspeed-pfr/src/engineManager/engine_manager.c @@ -5,7 +5,10 @@ */ #include +#include +#include +#include #include "engine_manager.h" #include "include/definitions.h" #include "common/common.h" @@ -13,9 +16,13 @@ #include "intel_pfr/intel_pfr_verification.h" #include "intel_pfr/intel_pfr_provision.h" +LOG_MODULE_REGISTER(engine, CONFIG_LOG_DEFAULT_LEVEL); + uint8_t signature[RSA_MAX_KEY_LENGTH]; /**< Buffer for the manifest signature. */ uint8_t platform_id[256]; /**< Cache for the platform ID. */ +#define SPIM_NUM 4 + static int initialize_I2cSlave(/*struct engine_instances *engineInstances*/) { int status = I2C_Slave_wrapper_init(getI2CSlaveEngineInstance()); @@ -38,9 +45,7 @@ static int initialize_crypto(/*struct engine_instances *engineInstances*/) static int initialize_flash(void) { - int status = 0; - - status = flash_master_wrapper_init(getFlashMasterInstance()); + int status = flash_master_wrapper_init(getFlashEngineWrapper()); if (status) return status; @@ -66,11 +71,15 @@ int initializeEngines(void) assert(status == 0); status = initialize_crypto(); assert(status == 0); +#ifdef CONFIG_CERBERUS_PFR status = signature_verification_init(getSignatureVerificationInstance()); assert(status == 0); +#endif status = initialize_I2cSlave(); assert(status == 0); +#ifdef CONFIG_CERBERUS_PFR status = initialize_pfm_flash(); +#endif return status; } @@ -80,13 +89,183 @@ void uninitializeEngines(void) pfm_flash_release(getPfmFlashInstance()); } -void init_SPI_RW_Region(int spi_device_id) +void apply_pfm_protection(int spi_device_id) { int status = 0; - static char *spim_devs[4] = { + static char *spim_devs[SPIM_NUM] = { + "spi_m1", + "spi_m2", + "spi_m3", + "spi_m4" + }; + + status = spi_filter_wrapper_init(getSpiFilterEngineWrapper()); + struct spi_filter_engine_wrapper *spi_filter = getSpiFilterEngineWrapper(); + + spi_filter->dev_id = spi_device_id; // 0: BMC , 1: PCH + + // read PFR_Manifest + status = initializeEngines(); + status = initializeManifestProcessor(); + + struct spi_engine_wrapper *spi_flash = getSpiEngineWrapper(); + uint8_t *data; + uint8_t pfm_length[4]; + uint32_t pfm_read_address; + + if (spi_device_id == BMC_SPI) + get_provision_data_in_flash(BMC_ACTIVE_PFM_OFFSET, &pfm_read_address, sizeof(pfm_read_address)); + else if (spi_device_id == PCH_SPI) + get_provision_data_in_flash(PCH_ACTIVE_PFM_OFFSET, &pfm_read_address, sizeof(pfm_read_address)); + + // Block 0 + Block 1 = 1024 (0x400); PFM data(PFM Body = 0x20) + uint32_t pfm_region_Start = pfm_read_address + 0x400 + 0x20; + int default_region_length = 40; + uint32_t region_start_address; + uint32_t region_end_address; + // Table 2-14 get Length + uint32_t addr_size_of_pfm = pfm_read_address + 0x400 + 0x1c; + int region_length; + // cerberus define region_id start from 1 + int region_id = 1; + uint8_t region_record[40]; + int flash_size; + + // assign the flash device id, 0:spi1_cs0, 1:spi2_cs0 , 2:spi2_cs1, 3:spi2_cs2, 4:fmc_cs0, 5:fmc_cs1 + spi_flash->spi.device_id[0] = spi_device_id; + spi_flash->spi.base.read(&spi_flash->spi, addr_size_of_pfm, pfm_length, 4); + + int pfm_record_length = (pfm_length[0] & 0xff) | (pfm_length[1] << 8 & 0xff00) | (pfm_length[2] << 16 & 0xff0000) | (pfm_length[3] << 24 & 0xff000000); + + bool done = false; + // TODO: Clear all setting before apply new setting + + while (!done) { + /* Read PFM Record */ + spi_flash->spi.base.read(&spi_flash->spi, pfm_region_Start, region_record, default_region_length); + switch(region_record[0]) { + case 0x01: + /* SPI Region: 0x01 */ + /* Region protect level mask: + * 0b00000001: Protect: Read allowed + * 0b00000010: Protect: Write allowed + * 0b00000100: Recover: recover on first recovery + * 0b00001000: Recover: recover on second recovery + * 0b00010000: Recover: Recover on third recovery + * 0b11100000: Reserved + */ + + region_start_address = (region_record[8] & 0xff) | (region_record[9] << 8 & 0xff00) | + (region_record[10] << 16 & 0xff0000) | (region_record[11] << 24 & 0xff000000); + region_end_address = (region_record[12] & 0xff) | (region_record[13] << 8 & 0xff00) | + (region_record[14] << 16 & 0xff0000) | (region_record[15] << 24 & 0xff000000); + +#if defined(CONFIG_BMC_DUAL_FLASH) + spi_flash->spi.base.get_device_size((struct flash *)&spi_flash->spi, &flash_size); + if (region_start_address >= flash_size && region_end_address >= flash_size) { + region_start_address -= flash_size; + region_end_address -= flash_size; + spi_device_id = BMC_SPI_2; + } +#endif + region_length = region_end_address - region_start_address; + if (region_record[1] & 0x02) { + /* Write allowed region */ + spi_filter->base.set_filter_rw_region(&spi_filter->base, + region_id, region_start_address, region_end_address); + region_id++; + } else { + /* Write not allowed region */ + // Cerberus did not support write not allowed setting + Set_SPI_Filter_RW_Region(spim_devs[spi_device_id], + SPI_FILTER_WRITE_PRIV, SPI_FILTER_PRIV_DISABLE, + region_start_address, region_length); + } + + if (region_record[1] & 0x01) { + /* Read allowed region */ + // Cerberus did not support read disabled + Set_SPI_Filter_RW_Region(spim_devs[spi_device_id], + SPI_FILTER_READ_PRIV, SPI_FILTER_PRIV_ENABLE, + region_start_address, region_length); + } else { + /* Read not allowed region */ + // Cerberus did not support read disabled + Set_SPI_Filter_RW_Region(spim_devs[spi_device_id], + SPI_FILTER_READ_PRIV, SPI_FILTER_PRIV_DISABLE, + region_start_address, region_length); + } + + /* Hash Algorhtm 2 bytes: + * 0b00000001: SHA256 present + * 0b00000010: SHA384 present + * 0b00000100: SHA512 present + * Otherwise: Reserved + */ + if ((region_record[2] & 0x01) == 0x01) + pfm_region_Start = pfm_region_Start + 48; + else + pfm_region_Start = pfm_region_Start + 16; + break; + case 0x02: + /* SMBus Rule Definition: 0x02 */ + LOG_INF("SMBus Rule Bus[%d] RuleId[%d] DeviceAddr[%x]", + region_record[5], region_record[6], region_record[7]); + LOG_HEXDUMP_INF(®ion_record[8], 32, "Whitelist: "); + + if (region_record[5] > 0 && region_record[5] < 6 && region_record[6] > 0 && region_record[6] < 17) { + // Valid Bus ID should be 1~5 and reflect to I2C_FILTER_0 ~ I2C_FILTER_4 + // Valid Rule ID should be 1~16 and refect to I2C Filter Driver Rule 0~15 + + char bus_dev_name[] = "I2C_FILTER_x"; + bus_dev_name[11] = (region_record[5] - 1) + '0'; + struct device *flt_dev = device_get_binding(bus_dev_name); + if (flt_dev) { + status = ast_i2c_filter_en( + flt_dev, + true, + true, + 0, + 0); + LOG_DBG("ast_i2c_filter_en ret=%d", status); + status = ast_i2c_filter_update( + flt_dev, + region_record[6] - 1, // Rule ID + region_record[7], // Device Address + ®ion_record[8] // cmd_whitelist + ); + LOG_DBG("ast_i2c_filter_update ret=%d", status); + } else { + LOG_ERR("%s device not found", bus_dev_name); + } + } else { + LOG_HEXDUMP_ERR(region_record, 40, "Invalid Bus ID or Rule ID"); + } + + pfm_region_Start += 40; + break; + default: + done = true; + break; + } + if (pfm_region_Start >= pfm_read_address + 0x400 + pfm_record_length) + break; + } + + spi_filter->base.enable_filter(spi_filter, true); +} + +void init_SPI_RW_Region(int spi_device_id) +{ + printk("DEPRECATED init_SPI_RW_Region\n"); +#if 0 + int status = 0; + static char *spim_devs[SPIM_NUM] = { "spi_m1", +#if !defined(CONFIG_ASPEED_DC_SCM) "spi_m2", +#endif "spi_m3", "spi_m4" }; @@ -156,4 +335,5 @@ void init_SPI_RW_Region(int spi_device_id) } spi_filter->base.enable_filter(spi_filter, true); +#endif } diff --git a/apps/aspeed-pfr/src/engineManager/engine_manager.h b/apps/aspeed-pfr/src/engineManager/engine_manager.h index 8848d67..def968e 100644 --- a/apps/aspeed-pfr/src/engineManager/engine_manager.h +++ b/apps/aspeed-pfr/src/engineManager/engine_manager.h @@ -4,8 +4,7 @@ * SPDX-License-Identifier: MIT */ -#ifndef ZEPHYR_ASPEED_PFR_SRC_INCLUDE_ENGINES_H_ -#define ZEPHYR_ASPEED_PFR_SRC_INCLUDE_ENGINES_H_ +#pragma once #include @@ -30,5 +29,4 @@ struct engine_instances { }; int initializeEngines(void); - -#endif /* ZEPHYR_ASPEED_PFR_SRC_INCLUDE_ENGINES_H_ */ +void apply_pfm_protection(int spi_device_id); diff --git a/apps/aspeed-pfr/src/imageRecovery/image_recovery.c b/apps/aspeed-pfr/src/imageRecovery/image_recovery.c index 520ff5a..2805149 100644 --- a/apps/aspeed-pfr/src/imageRecovery/image_recovery.c +++ b/apps/aspeed-pfr/src/imageRecovery/image_recovery.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: MIT */ +#include #include #include "include/definitions.h" @@ -11,6 +12,8 @@ #include "firmware/app_image.h" #include "common/common.h" +LOG_MODULE_REGISTER(recovery, CONFIG_LOG_DEFAULT_LEVEL); + uint8_t recovery_image_magic_num[4] = { 0x8A, 0x14, 0x7C, 0x29 }; void recovery_initialize(void) @@ -30,7 +33,7 @@ int recovery_header_magic_num_check(uint8_t *magic_num) if (memcmp(magic_num, recovery_image_magic_num, sizeof(recovery_image_magic_num))) return 0; - printk("Recovery Header Magic Number not Match.\r\n"); + LOG_INF("Recovery Header Magic Number not Match."); return 1; } @@ -93,14 +96,14 @@ int recovery_action(struct flash *flash, uint8_t *recovery_address) image_offset += sizeof(recovery_info); // image data start if (!memcmp(recovery_address, recovery_info.address, sizeof(recovery_info.address))) { - printk("Start Recovery\n"); + LOG_INF("Start Recovery"); match_flag = 1; // do recovery here; recovery_read_offset = image_offset; active_write_offset = *((uint32_t *)recovery_address); - printk("recovery offset:%x\n", active_write_offset); + LOG_INF("recovery offset:%x", active_write_offset); page_count = *((uint32_t *)recovery_info.image_length) / sizeof(buf); block_count = *((uint32_t *)recovery_info.image_length) / 1024 / 64; @@ -115,7 +118,7 @@ int recovery_action(struct flash *flash, uint8_t *recovery_address) flash->read(flash, recovery_read_offset + page * sizeof(buf), buf, sizeof(buf)); flash->write(flash, active_write_offset + page * sizeof(buf), buf, sizeof(buf)); } - printk("recovery offset:%x recovery successful\n", active_write_offset); + LOG_INF("recovery offset:%x recovery successful", active_write_offset); break; } image_offset += *((uint32_t *)recovery_info.image_length);// image data end @@ -140,7 +143,7 @@ int performImageRecovery(void) if (status) return status; - printk("Recovery Verification\n"); + LOG_INF("Recovery Verification"); recovery_verify_result = recovery_verification(manifest_flash->flash, get_hash_engine_instance(), getRsaEngineInstance(), @@ -150,11 +153,11 @@ int performImageRecovery(void) recovery_verify_flag++; if (recovery_verify_result) { - printk("Recovery Verification Fail\n"); + LOG_INF("Recovery Verification Fail"); return recovery_verify_result; } - printk("Recovery Verification Successful\n"); + LOG_INF("Recovery Verification Successful"); } return recovery_action(manifest_flash->flash, firmware_info.start_address); diff --git a/apps/aspeed-pfr/src/imageVerification/image_verify.c b/apps/aspeed-pfr/src/imageVerification/image_verify.c index 977cd0a..87b6dd4 100644 --- a/apps/aspeed-pfr/src/imageVerification/image_verify.c +++ b/apps/aspeed-pfr/src/imageVerification/image_verify.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: MIT */ +#include #include #include @@ -11,6 +12,8 @@ #include "common/common.h" #include "common/pfm_headers.h" +LOG_MODULE_REGISTER(verification, CONFIG_LOG_DEFAULT_LEVEL); + void verify_initialize(void) { initializeEngines(); @@ -161,11 +164,11 @@ int perform_image_verification(void) ); if (status) { - printk("Active Verification Fail\n"); - printk("start_address:%x\n", *((uint32_t *) firmware_info.start_address)); - printk("end_address:%x\n", *((uint32_t *) firmware_info.end_address)); + LOG_INF("Active Verification Fail"); + LOG_INF("start_address:%x", *((uint32_t *) firmware_info.start_address)); + LOG_INF("end_address:%x", *((uint32_t *) firmware_info.end_address)); } else { - printk("Active Region offset %x verify successful\n", *((uint32_t *) firmware_info.start_address)); + LOG_INF("Active Region offset %x verify successful", *((uint32_t *) firmware_info.start_address)); } firmware_offset += sizeof(firmware_info); } diff --git a/apps/aspeed-pfr/src/imageVerification/image_verify.h b/apps/aspeed-pfr/src/imageVerification/image_verify.h index d69b6de..f902d80 100644 --- a/apps/aspeed-pfr/src/imageVerification/image_verify.h +++ b/apps/aspeed-pfr/src/imageVerification/image_verify.h @@ -4,8 +4,7 @@ * SPDX-License-Identifier: MIT */ -#ifndef ZEPHYR_ASPEED_PFR_SRC_IMAGEVERIFICATION_IMAGE_VERIFY_H_ -#define ZEPHYR_ASPEED_PFR_SRC_IMAGEVERIFICATION_IMAGE_VERIFY_H_ +#pragma once #include #include @@ -17,4 +16,4 @@ void handleVerifyExitState(/* TBD */); int perform_image_verification(void); int signature_verification_init(struct signature_verification *verification); int read_rsa_public_key(struct rsa_public_key *public_key); -#endif /* ZEPHYR_ASPEED_PFR_SRC_IMAGEVERIFICATION_IMAGE_VERIFY_H_ */ + diff --git a/apps/aspeed-pfr/src/include/SmbusMailBoxCom.h b/apps/aspeed-pfr/src/include/SmbusMailBoxCom.h index 72f3f2c..676a68a 100644 --- a/apps/aspeed-pfr/src/include/SmbusMailBoxCom.h +++ b/apps/aspeed-pfr/src/include/SmbusMailBoxCom.h @@ -4,8 +4,7 @@ * SPDX-License-Identifier: MIT */ -#ifndef PFR_SMBUS_MAILBOX_COMM_H_ -#define PFR_SMBUS_MAILBOX_COMM_H_ +#pragma once typedef char byte; @@ -110,7 +109,9 @@ typedef enum _UFM_PROVISONING_STATUS_VALUE { UFM_LOCKED = 0X10, UFM_PROVISIONED = 0X20, PIT_LEVEL_1_ENFORCED = 0X40, - PIT_L2_COMPLETE_SUCCESSFUL = 0X80 + PIT_L2_COMPLETE_SUCCESSFUL = 0X80, + UFM_CLEAR_ON_NEW_COMMAND = COMMAND_BUSY | COMMAND_DONE | COMMAND_ERROR, + UFM_CLEAR_ON_ERASE_COMMAND = UFM_PROVISIONED | PIT_LEVEL_1_ENFORCED | PIT_L2_COMPLETE_SUCCESSFUL, } UFM_PROVISONING_STATUS_VALUE; typedef enum _UFM_PROVISIONING_COMMAND_VALUE { @@ -175,4 +176,3 @@ typedef enum _BMC_PCH_UPDATE_INTENT_VALUE { UPDATE_AT_RESET = 0X80 } BMC_PCH_UPDATE_INTENT_VALUE; -#endif /* PFR_SMBUS_MAILBOX_COMM_H_ */ diff --git a/apps/aspeed-pfr/src/include/definitions.h b/apps/aspeed-pfr/src/include/definitions.h index 8bbd032..c981e59 100644 --- a/apps/aspeed-pfr/src/include/definitions.h +++ b/apps/aspeed-pfr/src/include/definitions.h @@ -4,8 +4,7 @@ * SPDX-License-Identifier: MIT */ -#ifndef ZEPHYR_ASPEED_PFR_SRC_INCLUDE_DEFINITIONS_H_ -#define ZEPHYR_ASPEED_PFR_SRC_INCLUDE_DEFINITIONS_H_ +#pragma once #include @@ -47,4 +46,3 @@ struct pfmInfo { uint8_t platform_id[256]; /**< Cache for the platform ID. */ }; -#endif /* ZEPHYR_ASPEED_PFR_SRC_INCLUDE_DEFINITIONS_H_ */ diff --git a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_authentication.c b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_authentication.c index ebefd4b..01e9a98 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_authentication.c +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_authentication.c @@ -4,43 +4,46 @@ * SPDX-License-Identifier: MIT */ +#include #include "pfr/pfr_common.h" #include "intel_pfr_definitions.h" #include "intel_pfr_verification.h" #include "Smbus_mailbox/Smbus_mailbox.h" #include "intel_pfr_provision.h" +#include "intel_pfr_pfm_manifest.h" +#include "pfr/pfr_ufm.h" -#if PF_STATUS_DEBUG -#define DEBUG_PRINTF printk -#else -#define DEBUG_PRINTF(...) -#endif - +LOG_MODULE_DECLARE(pfr, CONFIG_LOG_DEFAULT_LEVEL); int pfr_recovery_verify(struct pfr_manifest *manifest) { int status = 0; uint32_t read_address; - DEBUG_PRINTF("Verify recovery\r\n"); + LOG_INF("Verify recovery"); // Recovery region verification if (manifest->image_type == BMC_TYPE) { - ufm_read(PROVISION_UFM, BMC_RECOVERY_REGION_OFFSET, &read_address, sizeof(read_address)); + LOG_INF("Image Type: BMC"); + ufm_read(PROVISION_UFM, BMC_RECOVERY_REGION_OFFSET, (uint8_t *)&read_address, sizeof(read_address)); manifest->pc_type = PFR_BMC_UPDATE_CAPSULE; } else if (manifest->image_type == PCH_TYPE) { - ufm_read(PROVISION_UFM, PCH_RECOVERY_REGION_OFFSET, &read_address, sizeof(read_address)); + LOG_INF("Image Type: PCH"); + ufm_read(PROVISION_UFM, PCH_RECOVERY_REGION_OFFSET, (uint8_t *)&read_address, sizeof(read_address)); manifest->pc_type = PFR_PCH_UPDATE_CAPSULE; } + manifest->address = read_address; // Block0-Block1 verifcation - status = manifest->base->verify(manifest, manifest->hash, manifest->verification->base, manifest->pfr_hash->hash_out, manifest->pfr_hash->length); + status = manifest->base->verify((struct manifest *)manifest, manifest->hash, manifest->verification->base, manifest->pfr_hash->hash_out, manifest->pfr_hash->length); if (status != Success) { - DEBUG_PRINTF("Verify recovery failed\r\n"); + LOG_ERR("Verify update capsule failed"); return Failure; } + LOG_INF("Verify recovery capsule success"); + if (manifest->image_type == BMC_TYPE) manifest->pc_type = PFR_BMC_PFM; else if (manifest->image_type == PCH_TYPE) @@ -50,17 +53,19 @@ int pfr_recovery_verify(struct pfr_manifest *manifest) manifest->address += PFM_SIG_BLOCK_SIZE; // manifest verifcation - status = manifest->base->verify(manifest, manifest->hash, manifest->verification->base, manifest->pfr_hash->hash_out, manifest->pfr_hash->length); + status = manifest->base->verify((struct manifest *)manifest, manifest->hash, manifest->verification->base, manifest->pfr_hash->hash_out, manifest->pfr_hash->length); if (status != Success) { - DEBUG_PRINTF("Verify recovery pfm failed\r\n"); + LOG_ERR("Verify recovery PFM failed"); return Failure; } + LOG_INF("Verify recovery PFM success"); + status = get_recover_pfm_version_details(manifest, read_address); if (status != Success) return Failure; - DEBUG_PRINTF("Recovery Region verification success\r\n"); + LOG_INF("Recovery region verification success"); return Success; } @@ -71,36 +76,43 @@ int pfr_active_verify(struct pfr_manifest *manifest) uint32_t read_address; if (manifest->image_type == BMC_TYPE) { - get_provision_data_in_flash(BMC_ACTIVE_PFM_OFFSET, &read_address, sizeof(read_address)); + LOG_INF("Image Type: BMC"); + get_provision_data_in_flash(BMC_ACTIVE_PFM_OFFSET, (uint8_t *)&read_address, sizeof(read_address)); manifest->pc_type = PFR_BMC_PFM; } else if (manifest->image_type == PCH_TYPE) { - get_provision_data_in_flash(PCH_ACTIVE_PFM_OFFSET, &read_address, sizeof(read_address)); + LOG_INF("Image Type: PCH"); + get_provision_data_in_flash(PCH_ACTIVE_PFM_OFFSET, (uint8_t *)&read_address, sizeof(read_address)); manifest->pc_type = PFR_PCH_PFM; } manifest->address = read_address; - DEBUG_PRINTF("PFM Verification\r\n"); - - status = manifest->base->verify(manifest, manifest->hash, manifest->verification->base, manifest->pfr_hash->hash_out, manifest->pfr_hash->length); + LOG_INF("PFM Verification"); + LOG_INF("manifest->address=%x manifest->recovery_address=%x", manifest->address, manifest->recovery_address); + status = manifest->base->verify((struct manifest *)manifest, manifest->hash, manifest->verification->base, manifest->pfr_hash->hash_out, manifest->pfr_hash->length); if (status != Success) { - DEBUG_PRINTF("Verify active pfm failed\r\n"); + LOG_ERR("Verify active PFM failed"); SetMajorErrorCode(manifest->image_type == BMC_TYPE ? BMC_AUTH_FAIL : PCH_AUTH_FAIL); return Failure; } + LOG_INF("Verify active PFM success"); + read_address = read_address + PFM_SIG_BLOCK_SIZE; status = pfm_version_set(manifest, read_address); - if (status != Success) + if (status != Success) { + LOG_ERR("PFM version set failed"); return Failure; + } status = pfm_spi_region_verification(manifest); if (status != Success) { SetMajorErrorCode(manifest->image_type == BMC_TYPE ? BMC_AUTH_FAIL : PCH_AUTH_FAIL); - DEBUG_PRINTF("Verify active spi failed\r\n"); + LOG_ERR("Verify active SPI region failed"); return Failure; } + LOG_INF("Verify active SPI region success"); return Success; } diff --git a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_authentication.h b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_authentication.h index 5f45187..ae84780 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_authentication.h +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_authentication.h @@ -4,10 +4,10 @@ * SPDX-License-Identifier: MIT */ -#ifndef INTEL_PFR_AUTHENTICATION_H_ -#define INTEL_PFR_AUTHENTICATION_H_ +#pragma once -int pfr_active_verify(struct pfr_manifest *manifest); +#include "pfr/pfr_common.h" -#endif /*INTEL_PFR_AUTHENTICATION_H_*/ +int pfr_active_verify(struct pfr_manifest *manifest); +int pfr_recovery_verify(struct pfr_manifest *manifest); diff --git a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_definitions.h b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_definitions.h index c529444..e2fb243 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_definitions.h +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_definitions.h @@ -4,19 +4,18 @@ * SPDX-License-Identifier: MIT */ -#ifndef INTEL_PFR_DEFINITIONS_H_ -#define INTEL_PFR_DEFINITIONS_H_ +#pragma once #define BMC_FLASH_ID 0 #define PCH_FLASH_ID 1 #define BMC_TYPE 0 -#define PCH_TYPE 1 +#define PCH_TYPE 2 #define UFM0 4 #define UFM0_SIZE 256 -#define UFM1 3 +#define UFM1 3 #define FALSE 0 #define TRUE 1 @@ -29,83 +28,73 @@ #define UPDATE_STATUS_ADDRESS 0x00 // Debug configuration token -#define PF_STATUS_DEBUG 1 -#define PF_VERIFY_DEBUG 1 -#define PF_UPDATE_DEBUG 1 -#define PFR_AUTHENTICATION_DEBUG 1 -#define HROT_STATE_DEBUG 1 -#define SMBUS_MAILBOX_DEBUG 1 -#define INTEL_MANIFEST_DEBUG 1 -#define EVERY_BOOT_SVN_VALIDATION 1 - -#define BMC_SUPPORT 1 -#define EMULATION_SUPPORT 1 -#define LOG_DEBUG 1 -#define LOG_ENABLE 1 -#define SMBUS_MAILBOX_SUPPORT 1 -#define PFR_AUTO_PROVISION 1 -#define UART_ENABLE 1 - -#define CPLD_RELEASE_VERSION 1 +#define PF_STATUS_DEBUG 1 +#define PF_UPDATE_DEBUG 1 +#define SMBUS_MAILBOX_DEBUG 1 +#define INTEL_MANIFEST_DEBUG 1 + +#define BMC_SUPPORT 1 +#define EMULATION_SUPPORT 1 +#define LOG_DEBUG 1 +#define LOG_ENABLE 1 +#define SMBUS_MAILBOX_SUPPORT 1 +#define PFR_AUTO_PROVISION 1 +#define UART_ENABLE 1 + +#define CPLD_RELEASE_VERSION 1 #define CPLD_RoT_SVN 1 // BIOS/BMC SPI Region information +#define PCH_ACTIVE_FW_UPDATE_ADDRESS 0x00000000 #define PCH_CAPSULE_STAGING_ADDRESS 0x007F0000 -#define PCH_PFM_ADDRESS 0x02FF0000 -#define PCH_FVM_ADDRESS 0x02FF1000 +#define PCH_PFM_ADDRESS 0x02FF0000 +#define PCH_FVM_ADDRESS 0x02FF1000 #define PCH_RECOVERY_AREA_ADDRESS 0x01BF0000 -#define PCH_STAGING_SIZE 0x01400000 -#define BMC_STAGING_SIZE 0x02000000 -#define BMC_CAPSULE_STAGING_ADDRESS 0x04A00000 -#define BMC_CPLD_STAGING_ADDRESS 0x07A00000 -#define BMC_CPLD_RECOVERY_ADDRESS 0x07F00000 -#define BMC_PFM_ADDRESS 0x029C0000 -#define BMC_RECOVERY_AREA_ADDRESS 0x02A00000 -#define BMC_FLASH_SIZE 0x08000000 -#define PCH_FLASH_SIZE 0x04000000 -#define BMC_CPLD_RECOVERY_SIZE 0x100000 - -#define BMC_CAPSULE_PCH_STAGING_ADDRESS 0x06A00000 -#define BMC_PCH_STAGING_SIZE 0x01000000 - -#define COMPRESSION_TAG 0x5F504243 -#define BLOCK0TAG 0xB6EAFD19 + +#define PBC_COMPRESSION_TAG 0x5F504243 +#define PBC_VERSION 2 +#define PBC_PAGE_SIZE 0x1000 +#define PBC_PATTERN_SIZE 0x0001 +#define PBC_PATTERN 0xFF + + +#define BLOCK0TAG 0xB6EAFD19 #define BLOCK0_RSA_TAG 0x35C6B783 -#define BLOCK1TAG 0xF27F28D7 +#define BLOCK1TAG 0xF27F28D7 #define BLOCK1_RSA_TAG 0xD1550984 -#define BLOCK1_ROOTENTRY_TAG 0xA757A046 +#define BLOCK1_ROOTENTRY_TAG 0xA757A046 #define BLOCK1_ROOTENTRY_RSA_TAG 0x6CCDCAD7 -#define BLOCK1CSKTAG 0x14711C2F -#define BLOCK1_BLOCK0ENTRYTAG 0x15364367 -#define SIGNATURE_SECP256_TAG 0xDE64437D -#define SIGNATURE_SECP384_TAG 0xEA2A50E9 +#define BLOCK1CSKTAG 0x14711C2F +#define BLOCK1_BLOCK0ENTRYTAG 0x15364367 +#define SIGNATURE_SECP256_TAG 0xDE64437D +#define SIGNATURE_SECP384_TAG 0xEA2A50E9 #define SIGNATURE_RSA2K_256_TAG 0xee728a05 #define SIGNATURE_RSA3K_384_TAG 0x9432a93e #define SIGNATURE_RSA4K_384_TAG 0xF61B70F3 #define SIGNATURE_RSA4K_512_TAG 0x383c5144 -#define PUBLIC_SECP256_TAG 0xC7B88C74 -#define PUBLIC_SECP384_TAG 0x08F07B47 -#define PUBLIC_RSA2K_TAG 0x7FAD5E14 -#define PUBLIC_RSA3K_TAG 0x684694E6 -#define PUBLIC_RSA4K_TAG 0xB73AA717 -#define PEM_TAG 0x02B3CE1D -#define PFM_SIG_BLOCK_SIZE 1024 -#define PFM_SIG_BLOCK_SIZE_3K 3072 -#define PFMTAG 0x02B3CE1D -#define FVMTAG 0xA8E7C2D4 -#define PFMTYPE 0x01 -#define UPDATE_CAPSULE 1 -#define ACTIVE_PFM 2 -#define ROT_TYPE 3 -#define LENGTH 256 +#define PUBLIC_SECP256_TAG 0xC7B88C74 +#define PUBLIC_SECP384_TAG 0x08F07B47 +#define PUBLIC_RSA2K_TAG 0x7FAD5E14 +#define PUBLIC_RSA3K_TAG 0x684694E6 +#define PUBLIC_RSA4K_TAG 0xB73AA717 +#define PEM_TAG 0x02B3CE1D +#define PFM_SIG_BLOCK_SIZE 1024 +#define PFM_SIG_BLOCK_SIZE_3K 3072 +#define PFMTAG 0x02B3CE1D +#define FVMTAG 0xA8E7C2D4 +#define PFMTYPE 0x01 +#define UPDATE_CAPSULE 1 +#define ACTIVE_PFM 2 +#define ROT_TYPE 3 +#define LENGTH 256 #define DECOMMISSION_PC_SIZE 128 -#define SIGN_PCH_PFM_BIT0 0x00000001 -#define SIGN_PCH_UPDATE_BIT1 0x00000002 -#define SIGN_BMC_PFM_BIT2 0x00000004 -#define SIGN_BMC_UPDATE_BIT3 0x00000008 -#define SIGN_CPLD_UPDATE_BIT4 0x00000010 -#define SIGN_CPLD_UPDATE_BIT9 0x00000200 +#define SIGN_PCH_PFM_BIT0 0x00000001 +#define SIGN_PCH_UPDATE_BIT1 0x00000002 +#define SIGN_BMC_PFM_BIT2 0x00000004 +#define SIGN_BMC_UPDATE_BIT3 0x00000008 +#define SIGN_CPLD_UPDATE_BIT4 0x00000010 +#define SIGN_CPLD_UPDATE_BIT9 0x00000200 #define SHA384_SIZE 48 #define SHA256_SIZE 32 @@ -114,12 +103,12 @@ #define SHA384_DIGEST_LENGTH 48 #define SHA512_DIGEST_LENGTH 64 #define FOUR_BYTE_ADDR_MODE 1 -#define SVN_MAX 63 +#define SVN_MAX 63 #define MAX_READ_SIZE 0x1000 #define MAX_WRITE_SIZE 0x1000 -#define PAGE_SIZE 0x1000 +#define PAGE_SIZE 0x1000 +#define BLOCK_SIZE 0x10000 #define UFM_PAGE_SIZE 16 -#define CSK_KEY_SIZE 16 #define ROOT_KEY_SIZE 64 #define ROOT_KEY_X_Y_SIZE_256 32 #define ROOT_KEY_X_Y_SIZE_384 48 @@ -127,10 +116,10 @@ #define BLOCK_SUPPORT_1KB 1 #define BLOCK_SUPPORT_3KB 0 -#define SMBUS_FILTER_IRQ_ENABLE 0x20 -#define SMBUS_FILTER_IRQ_DISABLE 0x00 -#define SMBUS_FILTER_ENCRYPTED_DATA_SIZE 64 -#define NOACK_FLAG 0x3 +#define SMBUS_FILTER_IRQ_ENABLE 0x20 +#define SMBUS_FILTER_IRQ_DISABLE 0x00 +#define SMBUS_FILTER_ENCRYPTED_DATA_SIZE 64 +#define NOACK_FLAG 0x3 #define ACTIVE_UFM PROVISION_UFM #define ACTIVE_UFM_SIZE PROVISION_UFM_SIZE @@ -145,21 +134,18 @@ #define BIT7_SET 0x00000080 // Smbus filter disable/enable Reuest key permission #define BIT8_SET 0x00000100 // Debug Request key permission -#define CSK_KEY \ - { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, \ - 0xFF, 0xFF, 0xFF, 0xFF } - -#define ROOTKEYHASH \ - { 0x6b, 0xa4, 0xa6, 0x98, 0x53, 0x63, 0xf0, 0xe7, \ - 0xe9, 0x98, 0x76, 0x62, 0x7d, 0xe7, 0x12, 0x41, \ - 0xda, 0xab, 0x4b, 0x96, 0xbd, 0x67, 0x99, 0x82, \ - 0x81, 0x40, 0x27, 0x87, 0xa5, 0x10, 0x6e, 0x73 } - enum Ecc_Curve { secp384r1 = 1, secp256r1, }; +typedef enum +{ + DECOMPRESSION_STATIC_REGIONS_MASK = 0b1, + DECOMPRESSION_DYNAMIC_REGIONS_MASK = 0b10, + DECOMPRESSION_STATIC_AND_DYNAMIC_REGIONS_MASK = 0b11, +} DECOMPRESSION_TYPE_MASK_ENUM; + typedef struct { uint8_t ActiveRegion; uint8_t Recoveryregion; @@ -176,4 +162,3 @@ typedef struct { uint8_t Reserved[4]; } CPLD_STATUS; -#endif diff --git a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_key_cancellation.c b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_key_cancellation.c index 4be29d5..36f4db3 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_key_cancellation.c +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_key_cancellation.c @@ -4,29 +4,22 @@ * SPDX-License-Identifier: MIT */ -#include +#include +#include + +#include "pfr/pfr_common.h" +#include "pfr/pfr_util.h" +#include "pfr/pfr_ufm.h" #include "intel_pfr_provision.h" #include "intel_pfr_definitions.h" -#include "intel_pfr_verification.h" -#include "flash/flash_wrapper.h" +#include "intel_pfr_key_cancellation.h" #include "state_machine/common_smc.h" -#include "flash/flash_aspeed.h" -#include "pfr/pfr_common.h" -#include "pfr/pfr_util.h" -#include -#include -#include - -#undef DEBUG_PRINTF -#if PFR_AUTHENTICATION_DEBUG -#define DEBUG_PRINTF printk -#else -#define DEBUG_PRINTF(...) -#endif + +LOG_MODULE_DECLARE(pfr, CONFIG_LOG_DEFAULT_LEVEL); int get_cancellation_policy_offset(uint32_t pc_type) { - if ((pc_type == CPLD_CAPSULE_CANCELLATION) || (pc_type == PFR_CPLD_UPDATE_CAPSULE)) + if ((pc_type == CPLD_CAPSULE_CANCELLATION) || (pc_type == PFR_CPLD_UPDATE_CAPSULE) || (pc_type == DECOMMISSION_CAPSULE)) return KEY_CANCELLATION_POLICY_FOR_SIGNING_CPLD_UPDATE_CAPSULE; else if ((pc_type == PCH_PFM_CANCELLATION) || (pc_type == PFR_PCH_PFM)) return KEY_CANCELLATION_POLICY_FOR_SIGNING_PCH_PFM; @@ -34,7 +27,7 @@ int get_cancellation_policy_offset(uint32_t pc_type) return KEY_CANCELLATION_POLICY_FOR_SIGNING_PCH_UPDATE_CAPSULE; else if ((pc_type == BMC_PFM_CANCELLATION) || (pc_type == PFR_BMC_PFM)) return KEY_CANCELLATION_POLICY_FOR_SIGNING_BMC_PFM; - else if ((pc_type == BMC_CAPSULE_CANCELLATION) || (pc_type == PFR_BMC_UPDATE_CAPSULE) || (pc_type == DECOMMISSION_CAPSULE)) + else if ((pc_type == BMC_CAPSULE_CANCELLATION) || (pc_type == PFR_BMC_UPDATE_CAPSULE)) return KEY_CANCELLATION_POLICY_FOR_SIGNING_BMC_UPDATE_CAPSULE; return 0; @@ -42,19 +35,20 @@ int get_cancellation_policy_offset(uint32_t pc_type) int validate_key_cancellation_flag(struct pfr_manifest *manifest) { - + uint32_t block1_address = manifest->address + sizeof(PFR_AUTHENTICATION_BLOCK0); uint32_t status = 0; uint32_t key_id = 0; - uint32_t block1_address = manifest->address + sizeof(PFR_AUTHENTICATION_BLOCK0); if ((manifest->pc_type == CPLD_CAPSULE_CANCELLATION) || (manifest->pc_type == PCH_PFM_CANCELLATION) || (manifest->pc_type == PCH_CAPSULE_CANCELLATION) || (manifest->pc_type == BMC_PFM_CANCELLATION) || (manifest->pc_type == BMC_CAPSULE_CANCELLATION)) { manifest->kc_flag = TRUE; } else { // Read Csk key ID - status = pfr_spi_read(manifest->image_type, block1_address + CSK_KEY_ID_ADDRESS, sizeof(key_id), &key_id); - if (status != Success) + status = pfr_spi_read(manifest->image_type, block1_address + CSK_KEY_ID_ADDRESS, sizeof(key_id), (uint8_t *)&key_id); + if (status != Success) { + LOG_ERR("Flash read block1 CSK key Id failed"); return Failure; + } status = manifest->keystore->kc_flag->verify_kc_flag(manifest, key_id); if (status != Success) @@ -63,81 +57,152 @@ int validate_key_cancellation_flag(struct pfr_manifest *manifest) manifest->kc_flag = FALSE; } - DEBUG_PRINTF("KeyCancellationFlag : %x \r\n", manifest->kc_flag); + LOG_INF("KeyCancellationFlag: %x", manifest->kc_flag); return Success; } int verify_csk_key_id(struct pfr_manifest *manifest, uint32_t key_id) { - - int status = 0; uint32_t ufm_offset = get_cancellation_policy_offset(manifest->pc_type); + uint32_t policy_data; + uint32_t bit_offset; + int status = 0; - uint8_t old_key_id[CSK_KEY_SIZE] = { 0 }; - uint8_t new_key_id = 1; + if (!ufm_offset) { + LOG_ERR("%s: Invalid provisioned UFM offset for key cancellation", __func__); + return Failure; + } if (manifest->pc_type == PFR_PCH_CPU_Seamless_Update_Capsule) return Success; - if (!ufm_offset) + // key id must be within 0-127 + if (key_id > KEY_CANCELLATION_MAX_KEY_ID) { + LOG_ERR("%s: Invalid key Id: %d", __func__, key_id); return Failure; + } - status = ufm_read(PROVISION_UFM, ufm_offset, old_key_id, sizeof(old_key_id)); - if (status != Success) - return Failure; + ufm_offset += (key_id / 32) * 4; + // bit little endian + bit_offset = 31 - (key_id % 32); - new_key_id = new_key_id << (key_id % 8); - if ((key_id / 8) > (CSK_KEY_SIZE - 1)) { - DEBUG_PRINTF("Invalid Key Id\r\n"); + status = ufm_read(PROVISION_UFM, ufm_offset, (uint8_t *)&policy_data, sizeof(policy_data)); + if (status != Success) { + LOG_ERR("%s: Read cancellation policy status from UFM failed", __func__); return Failure; } - if (!(new_key_id & old_key_id[key_id / 8])) { - DEBUG_PRINTF("This PFR CSK Key Was cancelled..!Can't Proceed with verify with this key Id: %d\r\n", key_id); + if (!(policy_data & (0x01 << bit_offset))) { + LOG_ERR("This CSK key was cancelled..! Can't Proceed with verify with this key Id: %d", key_id); return Failure; } return Success; - } int cancel_csk_key_id(struct pfr_manifest *manifest, uint32_t key_id) { uint32_t ufm_offset = get_cancellation_policy_offset(manifest->pc_type); - uint8_t cancellation_byte_old[16] = { 0 }; - uint8_t cancellation_byte_new = 1; - uint8_t byte_no = 0; - uint8_t bit_no = 0; - + uint32_t policy_data; + uint32_t bit_offset; int status = 0; - uint8_t policy_data = 0; - if (!ufm_offset) { - DEBUG_PRINTF("Invalid provisioned UFM offset for key cancellation\r\n"); + LOG_ERR("%s: Invalid provisioned UFM offset for key cancellation", __func__); + return Failure; + } + + // key id must be within 0-127 + if (key_id > KEY_CANCELLATION_MAX_KEY_ID) { + LOG_ERR("%s: Invalid key Id: %d", __func__, key_id); return Failure; } - byte_no = key_id / 8; - bit_no = key_id % 8; - ufm_offset = ufm_offset + byte_no; + ufm_offset += (key_id / 32) * 4; + // bit little endian + bit_offset = 31 - (key_id % 32); // store policy data from flash part - status = ufm_read(PROVISION_UFM, ufm_offset, &policy_data, 1); + status = ufm_read(PROVISION_UFM, ufm_offset, (uint8_t *)&policy_data, sizeof(policy_data)); if (status != Success) { - DEBUG_PRINTF("ReadCancellationPolicyStatus load cancellation policy fail\r\n"); + LOG_ERR("%s: Read cancellation policy status from UFM failed", __func__); return Failure; } - policy_data = policy_data & ~(0x01 << bit_no); + policy_data &= ~(0x01 << bit_offset); - status = ufm_write(PROVISION_UFM, ufm_offset, &policy_data, 1); + status = ufm_write(PROVISION_UFM, ufm_offset, (uint8_t *)&policy_data, sizeof(policy_data)); if (status != Success) { - DEBUG_PRINTF("ReadCancellationPolicyStatus write cancellation policy fail"); + LOG_ERR("Write cancellation policy status to UFM failed, offset = %x, data = %x", ufm_offset, policy_data); return Failure; } return Success; +} +#ifdef CONFIG_SHELL +static int cmd_cancel_csk_key_id(const struct shell *shell, size_t argc, char **argv) +{ + struct pfr_manifest test_manifest; + uint32_t key_id; + + test_manifest.pc_type = strtoul(argv[1], NULL, 16); + key_id = strtoul(argv[2], NULL, 10); + + cancel_csk_key_id(&test_manifest, key_id); + + ARG_UNUSED(shell); + ARG_UNUSED(argc); + return 0; +} + +static int cmd_verify_csk_key_id(const struct shell *shell, size_t argc, char **argv) +{ + struct pfr_manifest test_manifest; + uint32_t key_id; + + test_manifest.pc_type = strtoul(argv[1], NULL, 16); + key_id = strtoul(argv[2], NULL, 10); + + if (!verify_csk_key_id(&test_manifest, key_id)) + LOG_INF("This CSK key is not cancelled.., PC type = 0x%x, Key Id = %d", test_manifest.pc_type, key_id); + + ARG_UNUSED(shell); + ARG_UNUSED(argc); + return 0; +} + +static int cmd_dump_key_cancellation_policy(const struct shell *shell, size_t argc, char **argv) +{ + uint32_t buffer[4] = { 0 }; + uint32_t offset = 0; + uint32_t pc_type; + + pc_type = strtoul(argv[1], NULL, 16); + offset = get_cancellation_policy_offset(pc_type); + + if (!offset) { + LOG_ERR("%s: Invalid provisioned UFM offset for key cancellation", __func__); + return Failure; + } + + LOG_INF("UFM Offeset = %x", offset); + ufm_read(PROVISION_UFM, offset, (uint8_t *)buffer, sizeof(buffer)); + LOG_HEXDUMP_INF(buffer, sizeof(buffer), "Key Cancellation Policy"); + + ARG_UNUSED(shell); + ARG_UNUSED(argc); + return 0; } + +SHELL_STATIC_SUBCMD_SET_CREATE(sub_kc_cmds, + SHELL_CMD_ARG(verify, NULL, " ", cmd_verify_csk_key_id, 3, 0), + SHELL_CMD_ARG(cancel, NULL, " ", cmd_cancel_csk_key_id, 3, 0), + SHELL_CMD_ARG(dump, NULL, "", cmd_dump_key_cancellation_policy, 2, 0), + SHELL_SUBCMD_SET_END +); + +SHELL_CMD_REGISTER(kc, &sub_kc_cmds, "Key Cancellation Commands", NULL); + +#endif diff --git a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_key_cancellation.h b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_key_cancellation.h index 940d1c3..87f2593 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_key_cancellation.h +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_key_cancellation.h @@ -4,12 +4,11 @@ * SPDX-License-Identifier: MIT */ -#ifndef INTEL_PFR_KEY_CANCELLATION_H_ -#define INTEL_PFR_KEY_CANCELLATION_H_ +#pragma once +#define KEY_CANCELLATION_MAX_KEY_ID 127 int validate_key_cancellation_flag(struct pfr_manifest *manifest); int verify_csk_key_id(struct pfr_manifest *manifest, uint32_t key_id); int cancel_csk_key_id(struct pfr_manifest *manifest, uint32_t key_id); -#endif /*INTEL_PFR_KEY_CANCELLATION_H_*/ diff --git a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_pbc.c b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_pbc.c index dd06676..e8847d0 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_pbc.c +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_pbc.c @@ -4,139 +4,280 @@ * SPDX-License-Identifier: MIT */ +#include #include +#include #include "state_machine/common_smc.h" +#include "pfr/pfr_common.h" +#include "pfr/pfr_util.h" +#include "flash/flash_wrapper.h" #include "intel_pfr_definitions.h" +#include "intel_pfr_pfm_manifest.h" +#include "common/common.h" +LOG_MODULE_DECLARE(pfr, CONFIG_LOG_DEFAULT_LEVEL); #if PF_UPDATE_DEBUG -#define DEBUG_PRINTF printk +#define DEBUG_PRINTF LOG_INF #else #define DEBUG_PRINTF(...) #endif -int is_compression_tag_matched(uint32_t image_type, uint32_t *compression_tag, uint32_t read_address, uint32_t AreaSize) +typedef struct { - uint32_t tag = 0; + uint32_t tag; + uint32_t version; + uint32_t page_size; + uint32_t pattern_size; + uint32_t pattern; + uint32_t bitmap_nbit; + uint32_t payload_len; + uint32_t _reserved[25]; +} PBC_HEADER; - *compression_tag = *compression_tag + PFM_SIG_BLOCK_SIZE + PFM_SIG_BLOCK_SIZE;// Adding PFR Size +int update_active_pfm(struct pfr_manifest *manifest) +{ + struct spi_engine_wrapper *spi_flash = getSpiEngineWrapper(); + int status = 0; + uint32_t capsule_offset; - // Loop To verify the Tag. - while ((*compression_tag <= (read_address + AreaSize) - 4)) { - if (pfr_spi_read(image_type, *compression_tag, sizeof(tag), (uint8_t *)&tag)) - return Failure; + if (manifest->state == RECOVERY) + capsule_offset = manifest->recovery_address; + else + capsule_offset = manifest->staging_address; - if (tag == COMPRESSION_TAG) { - DEBUG_PRINTF("Tag Found\r\n"); - return Success; - } - *compression_tag += 1; - } + // Adjusting capsule offset size to PFM Signing chain + capsule_offset += PFM_SIG_BLOCK_SIZE; + + spi_flash->spi.device_id[0] = manifest->image_type; + + // Updating PFM from capsule to active region + status = flash_copy_and_verify(&spi_flash->spi, manifest->active_pfm_addr, + capsule_offset, PAGE_SIZE); + if (status != Success) + return Failure; + + DEBUG_PRINTF("Active PFM Updated!!"); - return Failure; + return Success; } -int decompression_erasing(uint32_t image_type, uint32_t N, uint32_t active_map_address) +int decompression_erase(uint32_t image_type, uint32_t start_addr, uint32_t end_addr, + uint32_t active_bitmap) { - int status = 0; - uint32_t index0 = 0; - int8_t index1 = 0; - uint8_t bit_map_data = 0; - uint32_t erase_offset = 0; - - // Loop To Erase the data in destination chip based on the Active Buffer data - DEBUG_PRINTF("Erasing...\r\n"); - for (index0 = 0; index0 < N / 8; index0++) { - status = pfr_spi_read(image_type, active_map_address, sizeof(uint8_t), (uint8_t *)&bit_map_data); - if (status != Success) { - DEBUG_PRINTF("Decompression Erase failed\r\n"); - return Failure; - } + uint32_t region_start_bit = start_addr / PAGE_SIZE; + uint32_t region_end_bit = end_addr / PAGE_SIZE; + int sector_sz = pfr_spi_get_block_size(image_type); + uint8_t active_bitmap_byte[PAGE_SIZE]; + uint32_t erase_start_bit = 0xffffffff; + bool support_block_erase = false; + uint32_t bit_in_bitmap; + uint32_t erase_bits; + + if (pfr_spi_read(image_type, active_bitmap, sizeof(active_bitmap_byte), + active_bitmap_byte)) { + DEBUG_PRINTF("Faild to get bitmap infromation"); + return Failure; + } - active_map_address += 1; - for (index1 = 7; index1 >= 0; index1--) { - if ((bit_map_data >> index1) & 1) { - status = pfr_spi_erase_4k(image_type, erase_offset); - if (status != Success) { - DEBUG_PRINTF("Decompression Erase failed\r\n"); - return Failure; + if (sector_sz == BLOCK_SIZE) + support_block_erase = true; + + for (bit_in_bitmap = region_start_bit; bit_in_bitmap < region_end_bit; bit_in_bitmap++) { + if (active_bitmap_byte[bit_in_bitmap >> 3] & (1 << (7 - (bit_in_bitmap % 8)))) { + if (erase_start_bit == 0xffffffff) + erase_start_bit = bit_in_bitmap; + } else { + if (erase_start_bit != 0xffffffff) { + erase_bits = bit_in_bitmap - erase_start_bit; + if (erase_bits) { + pfr_spi_erase_region(image_type, + support_block_erase, + erase_start_bit * PAGE_SIZE, + erase_bits * PAGE_SIZE); + erase_start_bit = 0xffffffff; } } - erase_offset += PAGE_SIZE; } } - DEBUG_PRINTF("Erase Successful\r\n"); + if (erase_start_bit != 0xffffffff) { + start_addr = erase_start_bit * PAGE_SIZE; + pfr_spi_erase_region(image_type, support_block_erase, + start_addr, end_addr - start_addr); + } + return Success; } -int decompression_write(uint32_t image_type, uint32_t N, uint32_t compression_tag, uint32_t compression_map_address) +int decompression_write(uint32_t image_type, + uint32_t decomp_src_addr, + uint32_t start_addr, + uint32_t end_addr, + uint32_t comp_bitmap) { - int status = 0; - uint8_t bit_map_data = 0; - uint32_t index0 = 0; - int8_t index1 = 0; - uint32_t erase_offset = 0; - - // Loop to Write the Data in destination Chip Based on the Compression Buffer data - DEBUG_PRINTF("Writing...\r\n"); - for (index0 = 0; index0 < N / 8; index0++) { - status = pfr_spi_read(image_type, compression_map_address, sizeof(uint8_t), (uint8_t *)&bit_map_data); - if (status != Success) - return Failure; - - compression_map_address += 1; - for (index1 = 7; index1 >= 0; index1--) { - if ((bit_map_data >> index1) & 1) { - status = pfr_spi_page_read_write(image_type, &compression_tag, &erase_offset); - if (status != Success) - return Failure; - } else { - erase_offset += PAGE_SIZE; + uint32_t region_start_bit = start_addr / PAGE_SIZE; + uint32_t region_end_bit = end_addr / PAGE_SIZE; + uint8_t comp_bitmap_byte[PAGE_SIZE]; + uint32_t dest_addr = start_addr; + uint32_t bitmap_byte_idx = 0; + uint32_t copy_this_page; + uint32_t cur_bit = 0; + uint16_t bit_mask; + + if (pfr_spi_read(image_type, comp_bitmap, sizeof(comp_bitmap_byte), comp_bitmap_byte)) { + DEBUG_PRINTF("Faild to get bitmap infromation"); + return Failure; + } + + while (cur_bit < region_end_bit) { + for (bit_mask = 0x80; bit_mask > 0; bit_mask >>= 1) { + copy_this_page = comp_bitmap_byte[bitmap_byte_idx] & bit_mask; + + if ((region_start_bit <= cur_bit) && (cur_bit < region_end_bit)) { + if (copy_this_page) { + if (pfr_spi_page_read_write(image_type, + decomp_src_addr, dest_addr)) + return Failure; + } + dest_addr += PAGE_SIZE; } + + if (copy_this_page) + decomp_src_addr += PAGE_SIZE; + + cur_bit++; } + bitmap_byte_idx++; } + return Success; } -int capsule_decompression(uint32_t image_type, uint32_t read_address, uint32_t area_size) +int decompress_spi_region(struct pfr_manifest *manifest, PBC_HEADER *pbc, + uint32_t start_addr, uint32_t end_addr) { - int status = 0; - uint32_t compression_tag = read_address; - uint32_t N = 0; - uint32_t bit_map_address = 0; + uint32_t image_type = manifest->image_type; + uint32_t read_address = (manifest->state == UPDATE) ? + manifest->staging_address : manifest->recovery_address; + uint32_t cap_pfm_offset = read_address + PFM_SIG_BLOCK_SIZE * 2; + uint32_t pbc_offset = cap_pfm_offset + manifest->pc_length; + uint32_t decomp_src_addr; + uint32_t active_bitmap; + uint32_t comp_bitmap; + uint32_t bitmap_size; + int status; + + bitmap_size = pbc->bitmap_nbit / 8; - if (is_compression_tag_matched(image_type, &compression_tag, read_address, area_size)) { - DEBUG_PRINTF("Tag Not Found\r\n"); + if (bitmap_size > PAGE_SIZE) { + DEBUG_PRINTF("bitmap size is too big"); return Failure; } - // Collecting the Active and Compression Buffer Values. - compression_tag += 20; - status = pfr_spi_read(image_type, compression_tag, sizeof(uint32_t), (uint8_t *)&N); - if (status != Success) { - DEBUG_PRINTF("Decompression failed\r\n"); + active_bitmap = pbc_offset + sizeof(PBC_HEADER); + comp_bitmap = active_bitmap + bitmap_size; + decomp_src_addr = comp_bitmap + bitmap_size; + if (decompression_erase(image_type, start_addr, end_addr, active_bitmap)) return Failure; + + status = decompression_write(image_type, decomp_src_addr, start_addr, end_addr, + comp_bitmap); + + return status; +} + +bool is_spi_region_static(PFM_SPI_DEFINITION *spi_region_def) +{ + return (spi_region_def->ProtectLevelMask.ReadAllowed && + spi_region_def->ProtectLevelMask.WriteAllowed == 0); +} + +bool is_spi_region_dynamic(PFM_SPI_DEFINITION *spi_region_def) +{ + return (spi_region_def->ProtectLevelMask.ReadAllowed && + spi_region_def->ProtectLevelMask.WriteAllowed); +} + +bool is_pbc_valid(PBC_HEADER *pbc) +{ + if (pbc->tag != PBC_COMPRESSION_TAG) { + DEBUG_PRINTF("PBC compression tag is invalid"); + return false; } - compression_tag += 108; - bit_map_address = compression_tag; + if (pbc->version != PBC_VERSION) { + DEBUG_PRINTF("PBC version is invalid"); + return false; + } - status = decompression_erasing(image_type, N, bit_map_address); - if (status != Success) - return Failure; + if (pbc->page_size != PBC_PAGE_SIZE) { + DEBUG_PRINTF("PBC page size is invalid"); + return false; + } + + if (pbc->bitmap_nbit % 8){ + DEBUG_PRINTF("PBC bitmap size is invalid"); + return false; + } + + return true; +} + +int decompress_capsule(struct pfr_manifest *manifest, DECOMPRESSION_TYPE_MASK_ENUM decomp_type) +{ + uint32_t image_type = manifest->image_type; + uint32_t read_address = (manifest->state == UPDATE) ? + manifest->staging_address : manifest->recovery_address; + uint32_t cap_pfm_offset = read_address + PFM_SIG_BLOCK_SIZE * 2; + uint32_t pbc_offset = cap_pfm_offset + manifest->pc_length; + uint32_t cap_pfm_body_offset = cap_pfm_offset + sizeof(PFM_STRUCTURE_1); + PFM_SPI_DEFINITION spi_def; + PBC_HEADER pbc; - compression_tag += N / 8; - bit_map_address = compression_tag; - compression_tag += N / 8; + if(pfr_spi_read(image_type, pbc_offset, sizeof(PBC_HEADER), (uint8_t *)&pbc)) + return Failure; - status = decompression_write(image_type, N, compression_tag, bit_map_address); - if (status != Success) { - DEBUG_PRINTF("Decompression write failed\r\n"); + if (!is_pbc_valid(&pbc)) return Failure; + + DEBUG_PRINTF("Decompressing %s capsule...", (manifest->state == UPDATE) ? + "staging" : "recovery"); + + while (1) { + pfr_spi_read(image_type, cap_pfm_body_offset, sizeof(PFM_SPI_DEFINITION), (uint8_t *)&spi_def); + if (spi_def.PFMDefinitionType == SMBUS_RULE) { + cap_pfm_body_offset += sizeof(PFM_SMBUS_RULE); + } else if (spi_def.PFMDefinitionType == SPI_REGION) { + if (is_spi_region_static(&spi_def)) { + if (decomp_type & DECOMPRESSION_STATIC_REGIONS_MASK) + decompress_spi_region(manifest, &pbc, + spi_def.RegionStartAddress, + spi_def.RegionEndAddress); + } else if (is_spi_region_dynamic(&spi_def) && + spi_def.RegionStartAddress != manifest->staging_address) { + if (decomp_type & DECOMPRESSION_DYNAMIC_REGIONS_MASK) + decompress_spi_region(manifest, &pbc, + spi_def.RegionStartAddress, + spi_def.RegionEndAddress); + + } + + if (spi_def.HashAlgorithmInfo.SHA256HashPresent || + spi_def.HashAlgorithmInfo.SHA384HashPresent) { + cap_pfm_body_offset += sizeof(PFM_SPI_DEFINITION); + cap_pfm_body_offset += (manifest->hash_curve == secp384r1) ? + SHA384_SIZE : SHA256_SIZE; + } else { + cap_pfm_body_offset += SPI_REGION_DEF_MIN_SIZE; + } + } else { + break; + } } - DEBUG_PRINTF("Decompression completed\r\n"); - return Success; -} + if (decomp_type & DECOMPRESSION_STATIC_REGIONS_MASK) + update_active_pfm(manifest); + return Success; +} diff --git a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_pbc.h b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_pbc.h index 9a8c0de..8f56152 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_pbc.h +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_pbc.h @@ -4,9 +4,8 @@ * SPDX-License-Identifier: MIT */ -#ifndef INTEL_PFR_PBC_H_ -#define INTEL_PFR_PBC_H_ +#pragma once -int capsule_decompression(int image_type, uint32_t read_address, uint32_t area_size); +#include "intel_pfr_definitions.h" -#endif /*INTEL_PFR_PBC_H_*/ +int decompress_capsule(struct pfr_manifest *manifest, DECOMPRESSION_TYPE_MASK_ENUM decomp_type); diff --git a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_pfm_manifest.c b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_pfm_manifest.c index 1fe6aa1..7e47b92 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_pfm_manifest.c +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_pfm_manifest.c @@ -4,15 +4,22 @@ * SPDX-License-Identifier: MIT */ +#include #include "intel_pfr_pfm_manifest.h" #include "intel_pfr_definitions.h" #include "state_machine/common_smc.h" #include "intel_pfr_provision.h" +#include "intel_pfr_update.h" #include "pfr/pfr_common.h" +#include "pfr/pfr_util.h" +#include "Smbus_mailbox/Smbus_mailbox.h" + + +LOG_MODULE_REGISTER(pfr, CONFIG_LOG_DEFAULT_LEVEL); #undef DEBUG_PRINTF #if INTEL_MANIFEST_DEBUG -#define DEBUG_PRINTF printk +#define DEBUG_PRINTF LOG_INF #else #define DEBUG_PRINTF(...) #endif @@ -38,14 +45,14 @@ int pfm_version_set(struct pfr_manifest *manifest, uint32_t read_address) status = pfr_spi_read(manifest->image_type, read_address, sizeof(PFM_STRUCTURE_1), buffer); if (status != Success) { - DEBUG_PRINTF("Pfm Version Set failed...\r\n"); + DEBUG_PRINTF("Pfm Version Set failed..."); return Failure; } if (((PFM_STRUCTURE_1 *)buffer)->PfmTag == PFMTAG) { - DEBUG_PRINTF("PfmTag verification success...\r\n"); + DEBUG_PRINTF("PfmTag verification success..."); } else { - DEBUG_PRINTF("PfmTag verification failed...\r\n"); + DEBUG_PRINTF("PfmTag verification failed..."); return Failure; } @@ -92,7 +99,7 @@ int get_recover_pfm_version_details(struct pfr_manifest *manifest, uint32_t addr status = pfr_spi_read(manifest->image_type, pfm_data_address, sizeof(PFM_STRUCTURE_1), buffer); if (status != Success) { - DEBUG_PRINTF("Get Recover Pfm Version Details failed...\r\n"); + DEBUG_PRINTF("Get Recover Pfm Version Details failed..."); return Failure; } @@ -136,7 +143,7 @@ int read_statging_area_pfm(struct pfr_manifest *manifest, uint8_t *svn_version) status = pfr_spi_read(manifest->image_type, pfm_start_address, sizeof(PFM_STRUCTURE_1), buffer); if (status != Success) { - DEBUG_PRINTF("Invalid Staging Area Pfm \r\n"); + DEBUG_PRINTF("Invalid Staging Area Pfm "); return Failure; } @@ -151,14 +158,15 @@ int spi_region_hash_verification(struct pfr_manifest *pfr_manifest, PFM_SPI_DEFI int status = 0; uint32_t region_length; - DEBUG_PRINTF("RegionStartAddress: %x,RegionEndAddress: %x\r\n", + DEBUG_PRINTF("RegionStartAddress: %x, RegionEndAddress: %x", PfmSpiDefinition->RegionStartAddress, PfmSpiDefinition->RegionEndAddress); region_length = (PfmSpiDefinition->RegionEndAddress) - (PfmSpiDefinition->RegionStartAddress); if ((PfmSpiDefinition->HashAlgorithmInfo.SHA256HashPresent == 1) || (PfmSpiDefinition->HashAlgorithmInfo.SHA384HashPresent == 1)) { + DEBUG_PRINTF("Digest verification start"); - uint8_t sha256_buffer[SHA384_DIGEST_LENGTH] = { 0 }; + uint8_t sha_buffer[SHA384_DIGEST_LENGTH] = { 0 }; uint32_t hash_length = 0; pfr_manifest->pfr_hash->start_address = PfmSpiDefinition->RegionStartAddress; @@ -174,18 +182,21 @@ int spi_region_hash_verification(struct pfr_manifest *pfr_manifest, PFM_SPI_DEFI return Failure; } - pfr_manifest->base->get_hash(pfr_manifest, pfr_manifest->hash, sha256_buffer, SHA256_DIGEST_LENGTH); + pfr_manifest->base->get_hash((struct manifest *)pfr_manifest, pfr_manifest->hash, sha_buffer, hash_length); - status = compare_buffer(pfm_spi_Hash, sha256_buffer, SHA256_DIGEST_LENGTH); - if (status != Success) + status = compare_buffer(pfm_spi_Hash, sha_buffer, hash_length); + if (status != Success) { + DEBUG_PRINTF("Digest verification failed"); return Failure; + } + DEBUG_PRINTF("Digest verification succeeded"); } - DEBUG_PRINTF("Digest verification success\r\n"); return Success; } +#if 0 int get_fvm_start_address(struct pfr_manifest *manifest, uint32_t *fvm_address) { @@ -237,7 +248,7 @@ int get_fvm_address(struct pfr_manifest *manifest, uint16_t fv_type) return 0; } - +#endif int get_spi_region_hash(struct pfr_manifest *manifest, uint32_t address, PFM_SPI_DEFINITION *p_spi_definition, uint8_t *pfm_spi_hash, uint8_t pfm_definition) { int status = 0; @@ -258,7 +269,6 @@ int get_spi_region_hash(struct pfr_manifest *manifest, uint32_t address, PFM_SPI void set_protect_level_mask_count(struct pfr_manifest *manifest, PFM_SPI_DEFINITION *spi_definition) { - int status = 0; uint8_t local_count = 0; if (manifest->image_type == PCH_TYPE) { @@ -322,7 +332,7 @@ Manifest_Status get_pfm_manifest_data(struct pfr_manifest *manifest, uint32_t *p if (status != Success) return manifest_failure; - // DEBUG_PRINTF("PFMDefinitionType %d\r\n", pfm_definition_type); + // DEBUG_PRINTF("PFMDefinitionType %d", pfm_definition_type); if (pfm_definition_type == ACTIVE_PFM_SMBUS_RULE) { if (pfm_definition_type == pfm_definition) { @@ -333,7 +343,7 @@ Manifest_Status get_pfm_manifest_data(struct pfr_manifest *manifest, uint32_t *p *position += sizeof(PFM_SMBUS_RULE); } else if (pfm_definition_type == PCH_PFM_SPI_REGION) { - DEBUG_PRINTF("PFM Spi Region Detected\n"); + DEBUG_PRINTF("PFM Spi Region Detected"); status = pfr_spi_read(manifest->image_type, (manifest_start_address + *position), sizeof(PFM_SPI_DEFINITION), (uint8_t *) spi_definition); if (status != Success) @@ -342,7 +352,7 @@ Manifest_Status get_pfm_manifest_data(struct pfr_manifest *manifest, uint32_t *p *position += sizeof(PFM_SPI_DEFINITION); *position += get_spi_region_hash(manifest, (uint32_t)(manifest_start_address + *position), (PFM_SPI_DEFINITION *)spi_definition, pfm_spi_hash, pfm_definition); - set_protect_level_mask_count(manifest->image_type, spi_definition); + set_protect_level_mask_count(manifest, spi_definition); } else if (pfm_definition_type == PCH_PFM_FVM_ADDRESS_DEFINITION) { if (pfm_definition_type == pfm_definition) { @@ -371,14 +381,13 @@ int pfm_spi_region_verification(struct pfr_manifest *manifest) PFM_SPI_DEFINITION pfm_spi_definition = { 0 }; uint8_t pfm_definition_type = PCH_PFM_SPI_REGION; uint8_t pfm_spi_hash[SHA384_SIZE] = { 0 }; - uint8_t fvm_region_count = 0; region_count = 0; for (position = 0; position <= g_pfm_manifest_length - 1; region_count++) { verify_status = get_pfm_manifest_data(manifest, &position, (void *)&pfm_spi_definition, (uint8_t *)&pfm_spi_hash, pfm_definition_type); if (verify_status == manifest_failure) { - DEBUG_PRINTF("Invalid Manifest Data..System Halted !!\r\n"); + DEBUG_PRINTF("Invalid Manifest Data..System Halted !!"); return Failure; } @@ -391,7 +400,7 @@ int pfm_spi_region_verification(struct pfr_manifest *manifest) if (pfm_definition_type == PCH_PFM_SPI_REGION) { status = spi_region_hash_verification(manifest, &pfm_spi_definition, pfm_spi_hash); if (status != Success) { - DEBUG_PRINTF("SPI region hash verification fail...\r\n"); + DEBUG_PRINTF("SPI region hash verification fail..."); return Failure; } @@ -425,9 +434,9 @@ Manifest_Status get_fvm_manifest_data(struct pfr_manifest *manifest, uint32_t *p return manifest_failure; if (fvm_data.FvmTag == FVMTAG) { - DEBUG_PRINTF("FvmTag verification success...\r\n"); + DEBUG_PRINTF("FvmTag verification success..."); } else { - DEBUG_PRINTF("FvmTag verification failed...\r\n"); + DEBUG_PRINTF("FvmTag verification failed..."); return manifest_failure; } diff --git a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_pfm_manifest.h b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_pfm_manifest.h index 2369751..b4fc5e6 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_pfm_manifest.h +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_pfm_manifest.h @@ -4,11 +4,10 @@ * SPDX-License-Identifier: MIT */ -#ifndef INTEL_PFR_PFM_VERIFICATION_H_ -#define INTEL_PFR_PFM_VERIFICATION_H_ +#pragma once #include - +#include "pfr/pfr_common.h" #pragma pack(1) #define NUM_WHITESPACE 8 @@ -120,6 +119,7 @@ typedef struct _FVM_CAPABILITIES { #define PCH_PFM_SPI_REGION 0x01 #define ACTIVE_PFM_SMBUS_RULE 0x02 #define PCH_PFM_FVM_ADDRESS_DEFINITION 0x03 +#define SPI_REGION_DEF_MIN_SIZE 16 #define PCH_FVM_SPI_REGION 0x01 #define PCH_FVM_Capabilities 0x04 @@ -138,10 +138,10 @@ extern uint32_t g_fvm_manifest_length; extern ProtectLevelMask pch_protect_level_mask_count; extern ProtectLevelMask bmc_protect_level_mask_count; -// int pfm_spi_region_verification(struct pfr_manifest *manifest); -// Manifest_Status get_pfm_manifest_data(struct pfr_manifest *manifest, uint32_t *position,void *spi_definition, uint8_t *pfm_spi_hash, uint8_t pfm_definition); - #pragma pack() +int read_statging_area_pfm(struct pfr_manifest *manifest, uint8_t *svn_version); +int get_recover_pfm_version_details(struct pfr_manifest *manifest, uint32_t address); +int pfm_version_set(struct pfr_manifest *manifest, uint32_t read_address); +int pfm_spi_region_verification(struct pfr_manifest *manifest); -#endif /*INTEL_PFR_PFM_VERIFICATION_H_*/ diff --git a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_provision.c b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_provision.c index 5a3233e..0232bc3 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_provision.c +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_provision.c @@ -4,125 +4,102 @@ * SPDX-License-Identifier: MIT */ +#include #include #include "state_machine/common_smc.h" #include "pfr/pfr_common.h" +#include "pfr/pfr_ufm.h" #include "intel_pfr_definitions.h" #include "pfr/pfr_util.h" #include "intel_pfr_provision.h" #include "intel_pfr_verification.h" -#undef DEBUG_PRINTF -#if PFR_AUTHENTICATION_DEBUG -#define DEBUG_PRINTF printk -#else -#define DEBUG_PRINTF(...) -#endif +LOG_MODULE_DECLARE(pfr, CONFIG_LOG_DEFAULT_LEVEL); -int g_provision_data; -// Verify Root Key hash -int verify_root_key_hash(struct pfr_manifest *manifest, uint8_t *root_public_key) +int verify_root_key_hash(struct pfr_manifest *manifest, uint8_t *pubkey_x, uint8_t *pubkey_y) { - int status = 0; - uint8_t hash_length = 0; - uint8_t sha_buffer[SHA384_DIGEST_LENGTH] = { 0 }; + uint8_t root_public_key[SHA384_DIGEST_LENGTH * 2] = { 0 }; uint8_t ufm_sha_data[SHA384_DIGEST_LENGTH] = { 0 }; + uint8_t sha_buffer[SHA384_DIGEST_LENGTH] = { 0 }; + uint8_t digest_length = 0; + uint8_t i = 0; + int status; if (manifest->hash_curve == secp256r1) - hash_length = (2 * SHA256_HASH_LENGTH); + digest_length = SHA256_DIGEST_LENGTH; else if (manifest->hash_curve == secp384r1) - hash_length = (2 * SHA384_HASH_LENGTH); - else - return Failure; - - status = get_buffer_hash(manifest, root_public_key, hash_length, sha_buffer); - if (status != Success) + digest_length = SHA384_DIGEST_LENGTH; + else { + LOG_ERR("Block1 Root Entry: Unsupported hash curve, %x", manifest->hash_curve); return Failure; + } - // Read hash from provisoned UFM 0 - status = ufm_read(PROVISION_UFM, ROOT_KEY_HASH, ufm_sha_data, (hash_length / 2)); - if (status != Success) - return status; + // Changing little endianess + for (i = 0; i < digest_length; i++) { + root_public_key[i] = pubkey_x[digest_length - 1 - i]; + root_public_key[i + digest_length] = pubkey_y[digest_length - 1 - i]; + } - status = compare_buffer(sha_buffer, ufm_sha_data, (hash_length / 2)); + status = get_buffer_hash(manifest, root_public_key, digest_length * 2, sha_buffer); if (status != Success) { - DEBUG_PRINTF("Root Key hash not matched\r\n"); + LOG_ERR("Block1 Root Entry: Get buffer hash failed"); return Failure; } - return Success; -} - -// Verify Root Key -int verify_root_key_data(struct pfr_manifest *manifest, uint8_t *pubkey_x, uint8_t *pubkey_y) -{ - int status; - uint8_t root_public_key[2 * SHA384_DIGEST_LENGTH] = { 0 }; - uint8_t i = 0; - uint8_t temp = 0; - uint8_t digest_length = 0; - - if (manifest->hash_curve == secp256r1) - digest_length = SHA256_DIGEST_LENGTH; - else if (manifest->hash_curve == secp384r1) - digest_length = SHA384_DIGEST_LENGTH; - else - return Failure; - - // Root Public Key update - memcpy(&root_public_key[0], pubkey_x, digest_length); - memcpy(&root_public_key[digest_length], pubkey_y, digest_length); - - // Changing Endianess - for (i = digest_length; i > digest_length / 2; i--) { - temp = root_public_key[i - 1]; - root_public_key[i - 1] = root_public_key[digest_length - i]; - root_public_key[digest_length - i] = temp; - temp = root_public_key[digest_length + i - 1]; - root_public_key[digest_length + i - 1] = root_public_key[(digest_length - i) + digest_length]; - root_public_key[(digest_length - i) + digest_length] = temp; + // Read hash from provisoned UFM 0 + status = ufm_read(PROVISION_UFM, ROOT_KEY_HASH, ufm_sha_data, digest_length); + if (status != Success) { + LOG_ERR("Block1 Root Entry: Read hash from UFM failed"); + return status; } - status = verify_root_key_hash(manifest, root_public_key); - if (status != Success) + status = compare_buffer(sha_buffer, ufm_sha_data, digest_length); + if (status != Success) { + LOG_ERR("Block1 Root Entry: hash not matched"); + LOG_HEXDUMP_INF(root_public_key, digest_length*2, "Public key:"); + LOG_HEXDUMP_INF(sha_buffer, digest_length, "Calculated hash:"); + LOG_HEXDUMP_INF(ufm_sha_data, digest_length, "Expected hash:"); return Failure; + } return Success; } -// Root Entry Key +// Block1 Root Entry int verify_root_key_entry(struct pfr_manifest *manifest, PFR_AUTHENTICATION_BLOCK1 *block1_buffer) { + uint32_t root_key_permission = 0xFFFFFFFF; // -1; int status; - int root_key_permission = 0xFFFFFFFF; // -1; - uint8_t i = 0; - uint8_t temp = 0; if (block1_buffer->RootEntry.Tag != BLOCK1_ROOTENTRY_TAG) { - DEBUG_PRINTF("Root Magic/Tag not matched \r\n"); + LOG_ERR("Block1 Root Entry: Magic/Tag not matched, %x", block1_buffer->RootEntry.Tag); return Failure; } - // Update CSK curve type to validate Block 0 entry + // Update root key entry curve type to validate csk/b0 entry if (block1_buffer->RootEntry.PubCurveMagic == PUBLIC_SECP256_TAG) manifest->hash_curve = secp256r1; else if (block1_buffer->RootEntry.PubCurveMagic == PUBLIC_SECP384_TAG) manifest->hash_curve = secp384r1; + else { + LOG_ERR("Block1 Root Entry: curve magic not support, %x", block1_buffer->RootEntry.PubCurveMagic); + return Failure; + } // Key permission if (block1_buffer->RootEntry.KeyPermission != root_key_permission) { - DEBUG_PRINTF("Root key permission not matched \r\n"); + LOG_ERR("Block1 Root Entry: key permission not matched, %x", block1_buffer->RootEntry.KeyPermission); return Failure; } // Key Cancellation if (block1_buffer->RootEntry.KeyId != root_key_permission) { - DEBUG_PRINTF("Root key permission not matched \r\n"); + LOG_ERR("Block1 Root Entry: key id not matched, %x", block1_buffer->RootEntry.KeyId); return Failure; } - status = verify_root_key_data(manifest, block1_buffer->RootEntry.PubKeyX, block1_buffer->RootEntry.PubKeyY); + status = verify_root_key_hash(manifest, block1_buffer->RootEntry.PubKeyX, block1_buffer->RootEntry.PubKeyY); if (status != Success) return Failure; diff --git a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_provision.h b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_provision.h index 38cf227..fc70ce3 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_provision.h +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_provision.h @@ -4,41 +4,38 @@ * SPDX-License-Identifier: MIT */ -#ifndef INTEL_PFR_PROVISION_H_ -#define INTEL_PFR_PROVISION_H_ +#pragma once #include -// #include "intel_pfr_verification.h" -// #include "pfr/pfr_common.h" - -extern int g_provision_data; +#include "intel_pfr_verification.h" +/* + * revise provisioned data structure in UFM + * increase the length of root key hash item to 48 bytes to support both sha256 and sha384 + * change the offset to increase 16 bytes after root key hash items + * + */ enum { UFM_STATUS, ROOT_KEY_HASH = 0x004, - PCH_ACTIVE_PFM_OFFSET = 0x024, - PCH_RECOVERY_REGION_OFFSET = 0x028, - PCH_STAGING_REGION_OFFSET = 0x02c, - BMC_ACTIVE_PFM_OFFSET = 0x030, - BMC_RECOVERY_REGION_OFFSET = 0x034, - BMC_STAGING_REGION_OFFSET = 0x038, - PIT_PASSWORD = 0x03c, - PIT_PCH_FW_HASH = 0x044, - PIT_BMC_FW_HASH = 0x064, - SVN_POLICY_FOR_CPLD_UPDATE = 0x084, - SVN_POLICY_FOR_PCH_FW_UPDATE = 0x08c, - SVN_POLICY_FOR_BMC_FW_UPDATE = 0x094, - KEY_CANCELLATION_POLICY_FOR_SIGNING_PCH_PFM = 0x09c, - KEY_CANCELLATION_POLICY_FOR_SIGNING_PCH_UPDATE_CAPSULE = 0x0ac, - KEY_CANCELLATION_POLICY_FOR_SIGNING_BMC_PFM = 0x0bc, - KEY_CANCELLATION_POLICY_FOR_SIGNING_BMC_UPDATE_CAPSULE = 0x0cc, - KEY_CANCELLATION_POLICY_FOR_SIGNING_CPLD_UPDATE_CAPSULE = 0x0dc + PCH_ACTIVE_PFM_OFFSET = 0x034, + PCH_RECOVERY_REGION_OFFSET = 0x038, + PCH_STAGING_REGION_OFFSET = 0x03c, + BMC_ACTIVE_PFM_OFFSET = 0x040, + BMC_RECOVERY_REGION_OFFSET = 0x044, + BMC_STAGING_REGION_OFFSET = 0x048, + PIT_PASSWORD = 0x04c, + PIT_PCH_FW_HASH = 0x054, + PIT_BMC_FW_HASH = 0x074, + SVN_POLICY_FOR_CPLD_UPDATE = 0x094, + SVN_POLICY_FOR_PCH_FW_UPDATE = 0x09c, + SVN_POLICY_FOR_BMC_FW_UPDATE = 0x0a4, + KEY_CANCELLATION_POLICY_FOR_SIGNING_PCH_PFM = 0x0ac, + KEY_CANCELLATION_POLICY_FOR_SIGNING_PCH_UPDATE_CAPSULE = 0x0bc, + KEY_CANCELLATION_POLICY_FOR_SIGNING_BMC_PFM = 0x0cc, + KEY_CANCELLATION_POLICY_FOR_SIGNING_BMC_UPDATE_CAPSULE = 0x0dc, + KEY_CANCELLATION_POLICY_FOR_SIGNING_CPLD_UPDATE_CAPSULE = 0x0ec }; -// int verify_root_key_hash(struct pfr_manifest *manifest, uint8_t *root_public_key); -// int verify_root_key_data(struct pfr_manifest *manifest, uint8_t *pubkey_x, uint8_t *pubkey_y); -// int verify_root_key_entry(struct pfr_manifest *manifest, PFR_AUTHENTICATION_BLOCK1 *block1_buffer); - - -#endif /*INTEL_PFR_PROVISION_H*/ +int verify_root_key_entry(struct pfr_manifest *manifest, PFR_AUTHENTICATION_BLOCK1 *block1_buffer); diff --git a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_recovery.c b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_recovery.c index e252ab6..cb36c5b 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_recovery.c +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_recovery.c @@ -4,18 +4,29 @@ * SPDX-License-Identifier: MIT */ +#include +#include +#include "common/common.h" +#include "pfr/pfr_ufm.h" #include "pfr/pfr_common.h" +#include "pfr/pfr_util.h" #include "state_machine/common_smc.h" -#include "intel_pfr_recovery.h" #include "manifest/pfm/pfm_manager.h" +#include "intel_pfr_recovery.h" +#include "intel_pfr_pfm_manifest.h" +#include "intel_pfr_pbc.h" #include "intel_pfr_definitions.h" #include "intel_pfr_provision.h" #include "intel_pfr_verification.h" +#include "intel_pfr_authentication.h" #include "flash/flash_wrapper.h" #include "flash/flash_util.h" +#include "Smbus_mailbox/Smbus_mailbox.h" + +LOG_MODULE_DECLARE(pfr, CONFIG_LOG_DEFAULT_LEVEL); #if PF_UPDATE_DEBUG -#define DEBUG_PRINTF printk +#define DEBUG_PRINTF LOG_INF #else #define DEBUG_PRINTF(...) #endif @@ -30,7 +41,6 @@ int intel_pfr_recovery_verify(struct recovery_image *image, struct hash_engine * ARG_UNUSED(hash_length); ARG_UNUSED(pfm); - int status = 0; struct pfr_manifest *pfr_manifest = (struct pfr_manifest *) image; return pfr_recovery_verify(pfr_manifest); @@ -52,7 +62,7 @@ int pfr_active_recovery_svn_validation(struct pfr_manifest *manifest) active_svn = GetPchPfmActiveSvn(); if (active_svn != staging_svn) { - DEBUG_PRINTF("SVN error\r\n"); + DEBUG_PRINTF("SVN error"); return Failure; } @@ -62,118 +72,101 @@ int pfr_active_recovery_svn_validation(struct pfr_manifest *manifest) int pfr_recover_recovery_region(int image_type, uint32_t source_address, uint32_t target_address) { int status = 0; - uint32_t area_size = 0; struct spi_engine_wrapper *spi_flash = getSpiEngineWrapper(); + int sector_sz = pfr_spi_get_block_size(image_type); + bool support_block_erase = (sector_sz == BLOCK_SIZE); + size_t area_size; if (image_type == BMC_TYPE) - area_size = BMC_STAGING_SIZE; + area_size = CONFIG_BMC_STAGING_SIZE; else if (image_type == PCH_TYPE) - area_size = PCH_STAGING_SIZE; + area_size = CONFIG_PCH_STAGING_SIZE; spi_flash->spi.device_id[0] = image_type; // assign the flash device id, 0:spi1_cs0, 1:spi2_cs0 , 2:spi2_cs1, 3:spi2_cs2, 4:fmc_cs0, 5:fmc_cs1 DEBUG_PRINTF("Recovering..."); + if (pfr_spi_erase_region(image_type, support_block_erase, target_address, area_size)) { - status = flash_copy_and_verify(&spi_flash->spi, target_address, source_address, area_size); - if (status != Success) { - DEBUG_PRINTF("Recovery region update failed\r\n"); + DEBUG_PRINTF("Recovery region erase failed"); return Failure; } - DEBUG_PRINTF("Recovery region update completed\r\n"); - - return Success; -} - -int pfr_recover_active_region(struct pfr_manifest *manifest) -{ - - int status = 0; - uint32_t pfm_length; - uint32_t read_address = 0; - uint32_t area_size; - - DEBUG_PRINTF("Active Data Corrupted\r\n"); - if (manifest->image_type == BMC_TYPE) { - status = ufm_read(PROVISION_UFM, BMC_RECOVERY_REGION_OFFSET, (uint8_t *)&read_address, sizeof(read_address)); - if (status != Success) - return status; - - area_size = BMC_STAGING_SIZE; - } else if (manifest->image_type == PCH_TYPE) { - status = ufm_read(PROVISION_UFM, PCH_RECOVERY_REGION_OFFSET, (uint8_t *)&read_address, sizeof(read_address)); - if (status != Success) - return Failure; - area_size = PCH_STAGING_SIZE; - } else { - return Failure; - } - - status = capsule_decompression(manifest->image_type, read_address, area_size); - if (status != Success) { - DEBUG_PRINTF("Repair Failed\r\n"); - return Failure; - } - - status = active_region_pfm_update(manifest); - if (status != Success) { - DEBUG_PRINTF("Active Region PFM Update failed!!\r\n"); + // use read_write_between spi for supporting dual flash + if (pfr_spi_region_read_write_between_spi(image_type, source_address, image_type, + target_address, area_size)) { + DEBUG_PRINTF("Recovery region update failed"); return Failure; } - DEBUG_PRINTF("Repair success\r\n"); + DEBUG_PRINTF("Recovery region update completed"); - return Success; + return status; } -int active_region_pfm_update(struct pfr_manifest *manifest) +int pfr_recover_active_region(struct pfr_manifest *manifest) { + uint32_t read_address; + uint32_t staging_address; + uint32_t act_pfm_offset; + PFR_AUTHENTICATION_BLOCK0 *block0_buffer; + uint8_t buffer[sizeof(PFR_AUTHENTICATION_BLOCK0)] = { 0 }; - int status = 0; - uint32_t active_offset = 0, capsule_offset = 0; + DEBUG_PRINTF("Active Data Corrupted"); + if (manifest->image_type == BMC_TYPE) { + if (ufm_read(PROVISION_UFM, BMC_RECOVERY_REGION_OFFSET, (uint8_t *)&read_address, + sizeof(read_address))) + return Failure; - // Getting offsets based on ImageType - if (manifest->image_type == PCH_TYPE) { - status = ufm_read(PROVISION_UFM, PCH_ACTIVE_PFM_OFFSET, (uint8_t *) &active_offset, sizeof(active_offset)); - if (status != Success) + if (ufm_read(PROVISION_UFM, BMC_STAGING_REGION_OFFSET, + (uint8_t *)&staging_address, sizeof(staging_address))) return Failure; - if (manifest->state == RECOVERY) - status = ufm_read(PROVISION_UFM, PCH_RECOVERY_REGION_OFFSET, (uint8_t *) &capsule_offset, sizeof(capsule_offset)); - else - status = ufm_read(PROVISION_UFM, PCH_STAGING_REGION_OFFSET, (uint8_t *) &capsule_offset, sizeof(capsule_offset)); + if (ufm_read(PROVISION_UFM, BMC_ACTIVE_PFM_OFFSET, (uint8_t *) &act_pfm_offset, + sizeof(act_pfm_offset))) + return Failure; + } else if (manifest->image_type == PCH_TYPE) { + if (ufm_read(PROVISION_UFM, PCH_RECOVERY_REGION_OFFSET, (uint8_t *)&read_address, + sizeof(read_address))) + return Failure; - if (status != Success) + if (ufm_read(PROVISION_UFM, PCH_STAGING_REGION_OFFSET, (uint8_t *)&staging_address, + sizeof(staging_address))) return Failure; - } else if (manifest->image_type == BMC_TYPE) { - status = ufm_read(PROVISION_UFM, BMC_ACTIVE_PFM_OFFSET, (uint8_t *) &active_offset, sizeof(active_offset)); - if (status != Success) - return status; + if(ufm_read(PROVISION_UFM, PCH_ACTIVE_PFM_OFFSET, (uint8_t *) &act_pfm_offset, + sizeof(act_pfm_offset))) + return Failure; + } else { + return Failure; + } - if (manifest->state == RECOVERY) - status = ufm_read(PROVISION_UFM, BMC_RECOVERY_REGION_OFFSET, (uint8_t *) &capsule_offset, sizeof(capsule_offset)); - else - status = ufm_read(PROVISION_UFM, BMC_STAGING_REGION_OFFSET, (uint8_t *) &capsule_offset, sizeof(capsule_offset)); + manifest->recovery_address = read_address; + manifest->staging_address = staging_address; + manifest->active_pfm_addr = act_pfm_offset; + manifest->address = read_address; + manifest->address += PFM_SIG_BLOCK_SIZE; - if (status != Success) - return status; - } else { + if (pfr_spi_read(manifest->image_type, manifest->address, + sizeof(PFR_AUTHENTICATION_BLOCK0), buffer)) { + LOG_ERR("Block0: Flash read data failed"); return Failure; } - // Adjusting capsule offset size to PFM Signing chain - capsule_offset += PFM_SIG_BLOCK_SIZE; - - struct spi_engine_wrapper *spi_flash = getSpiEngineWrapper(); + block0_buffer = (PFR_AUTHENTICATION_BLOCK0 *)buffer; + manifest->pc_length = block0_buffer->PcLength; - spi_flash->spi.device_id[0] = manifest->image_type; // assign the flash device id, 0:spi1_cs0, 1:spi2_cs0 , 2:spi2_cs1, 3:spi2_cs2, 4:fmc_cs0, 5:fmc_cs1 + uint32_t time_start, time_end; + time_start = k_uptime_get_32(); - // Updating PFM from capsule to active region - status = flash_copy_and_verify(&spi_flash->spi, active_offset, capsule_offset, PAGE_SIZE); - if (status != Success) + if (decompress_capsule(manifest, DECOMPRESSION_STATIC_AND_DYNAMIC_REGIONS_MASK)) { + DEBUG_PRINTF("Repair Failed"); return Failure; + } - DEBUG_PRINTF("PFM Updated!!\r\n"); + time_end = k_uptime_get_32(); + DEBUG_PRINTF("Firmware recovery completed, elapsed time = %u milliseconds", + (time_end - time_start)); + + DEBUG_PRINTF("Repair success"); return Success; } @@ -181,14 +174,11 @@ int active_region_pfm_update(struct pfr_manifest *manifest) int pfr_staging_pch_staging(struct pfr_manifest *manifest) { - int status = 0; + int status; - uint32_t source_address = 0; // BMC_CAPSULE_PCH_STAGING_ADDRESS; - uint32_t target_address = 0; // PCH_CAPSULE_STAGING_ADDRESS; - uint32_t area_size = BMC_PCH_STAGING_SIZE; - uint32_t PfmLength, PcLength; - - uint8_t active_svn = 0; + uint32_t source_address; + uint32_t target_address; + uint32_t image_type = manifest->image_type; status = ufm_read(PROVISION_UFM, BMC_STAGING_REGION_OFFSET, (uint8_t *)&source_address, sizeof(source_address)); if (status != Success) @@ -198,21 +188,17 @@ int pfr_staging_pch_staging(struct pfr_manifest *manifest) if (status != Success) return Failure; - - source_address += BMC_STAGING_SIZE; // PFR Staging - PCH Staging offset is 32MB after BMC staging offset - - uint32_t image_type = manifest->image_type; + source_address += CONFIG_BMC_STAGING_SIZE; manifest->image_type = BMC_TYPE; - manifest->address = source_address; manifest->pc_type = PFR_PCH_UPDATE_CAPSULE; - DEBUG_PRINTF("BMC(PCH) Staging Area verfication\r\n"); + DEBUG_PRINTF("BMC(PCH) Staging Area verfication"); // manifest verifcation - status = manifest->base->verify(manifest, manifest->hash, manifest->verification->base, manifest->pfr_hash->hash_out, manifest->pfr_hash->length); + status = manifest->base->verify((struct manifest *)manifest, manifest->hash, manifest->verification->base, manifest->pfr_hash->hash_out, manifest->pfr_hash->length); if (status != Success) { - DEBUG_PRINTF("verify failed\r\n"); + DEBUG_PRINTF("verify failed"); return Failure; } @@ -220,43 +206,39 @@ int pfr_staging_pch_staging(struct pfr_manifest *manifest) manifest->address += PFM_SIG_BLOCK_SIZE; manifest->pc_type = PFR_PCH_PFM; // manifest verifcation - status = manifest->base->verify(manifest, manifest->hash, manifest->verification->base, manifest->pfr_hash->hash_out, manifest->pfr_hash->length); + status = manifest->base->verify((struct manifest *)manifest, manifest->hash, manifest->verification->base, manifest->pfr_hash->hash_out, manifest->pfr_hash->length); if (status != Success) return Failure; - printk("BMC PCH Staging verification successful\r\n"); + DEBUG_PRINTF("BMC PCH Staging verification successful"); manifest->address = target_address; manifest->image_type = image_type; - uint32_t erase_address = target_address; - - for (int i = 0; i < (area_size / PAGE_SIZE); i++) { - - status = pfr_spi_erase_4k(manifest->image_type, erase_address); - if (status != Success) - return Failure; + int sector_sz = pfr_spi_get_block_size(image_type); + bool support_block_erase = (sector_sz == BLOCK_SIZE); - erase_address += PAGE_SIZE; - } + if (pfr_spi_erase_region(manifest->image_type, support_block_erase, target_address, + CONFIG_BMC_PCH_STAGING_SIZE)) + return Failure; - for (int i = 0; i < (area_size / PAGE_SIZE); i++) { - status = pfr_spi_page_read_write_between_spi(BMC_TYPE, &source_address, PCH_TYPE, &target_address); - if (status != Success) - return Failure; - } + if (pfr_spi_region_read_write_between_spi(BMC_TYPE, source_address, PCH_TYPE, + target_address, CONFIG_BMC_PCH_STAGING_SIZE)) + return Failure; if (manifest->state == RECOVERY) { - DEBUG_PRINTF("PCH staging region verification\r\n"); - status = manifest->update_fw->base->verify(manifest, NULL, NULL); + DEBUG_PRINTF("PCH staging region verification"); + status = manifest->update_fw->base->verify((struct firmware_image *)manifest, NULL, NULL); if (status != Success) return Failure; } - DEBUG_PRINTF("BMC PCH Recovery region Update completed\r\n"); + DEBUG_PRINTF("BMC PCH %s region Update completed", + (manifest->state == RECOVERY) ? "Recovery" : "Staging"); return Success; } int intel_pfr_recover_update_action(struct pfr_manifest *manifest) { + ARG_UNUSED(manifest); return Success; } diff --git a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_recovery.h b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_recovery.h index a9a5495..95ef355 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_recovery.h +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_recovery.h @@ -4,8 +4,7 @@ * SPDX-License-Identifier: MIT */ -#ifndef INTEL_PFR_RECOVERY_H_ -#define INTEL_PFR_RECOVERY_H_ +#pragma once #include #include "manifest/pfm/pfm_manager.h" @@ -13,5 +12,6 @@ int intel_pfr_recovery_verify(struct recovery_image *image, struct hash_engine *hash, struct signature_verification *verification, uint8_t *hash_out, size_t hash_length, struct pfm_manager *pfm); +int pfr_recover_recovery_region(int image_type, uint32_t source_address, uint32_t target_address); +int pfr_staging_pch_staging(struct pfr_manifest *manifest); -#endif diff --git a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_update.c b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_update.c index a2f8948..1eb2335 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_update.c +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_update.c @@ -4,7 +4,11 @@ * SPDX-License-Identifier: MIT */ +#include +#include #include "pfr/pfr_update.h" +#include "pfr/pfr_ufm.h" +#include "pfr/pfr_util.h" #include "StateMachineAction/StateMachineActions.h" #include "state_machine/common_smc.h" #include "pfr/pfr_common.h" @@ -13,12 +17,17 @@ #include "intel_pfr_verification.h" #include "intel_pfr_provision.h" #include "intel_pfr_definitions.h" +#include "intel_pfr_pbc.h" +#include "intel_pfr_recovery.h" #include "StateMachineAction/StateMachineActions.h" #include "intel_pfr_pfm_manifest.h" #include "flash/flash_aspeed.h" +#include "Smbus_mailbox/Smbus_mailbox.h" + +LOG_MODULE_DECLARE(pfr, CONFIG_LOG_DEFAULT_LEVEL); #if PF_UPDATE_DEBUG -#define DEBUG_PRINTF printk +#define DEBUG_PRINTF LOG_INF #else #define DEBUG_PRINTF(...) #endif @@ -33,7 +42,7 @@ int pfr_staging_verify(struct pfr_manifest *manifest) uint32_t target_address = 0; if (manifest->image_type == BMC_TYPE) { - DEBUG_PRINTF("BMC Recovery\r\n"); + DEBUG_PRINTF("BMC Staging Region Verification"); status = ufm_read(PROVISION_UFM, BMC_STAGING_REGION_OFFSET, (uint8_t *)&read_address, sizeof(read_address)); if (status != Success) return status; @@ -45,7 +54,7 @@ int pfr_staging_verify(struct pfr_manifest *manifest) manifest->pc_type = PFR_BMC_UPDATE_CAPSULE; } else if (manifest->image_type == PCH_TYPE) { - DEBUG_PRINTF("PCH Recovery...\r\n"); + DEBUG_PRINTF("PCH Staging Region Verification"); status = ufm_read(PROVISION_UFM, PCH_STAGING_REGION_OFFSET, (uint8_t *)&read_address, sizeof(read_address)); if (status != Success) return Failure; @@ -62,10 +71,11 @@ int pfr_staging_verify(struct pfr_manifest *manifest) manifest->address = read_address; manifest->recovery_address = target_address; + DEBUG_PRINTF("manifest->address=0x%08x manifest->recovery_address=0x%08x", manifest->address, manifest->recovery_address); // manifest verification - status = manifest->base->verify(manifest, manifest->hash, manifest->verification->base, manifest->pfr_hash->hash_out, manifest->pfr_hash->length); + status = manifest->base->verify((struct manifest *)manifest, manifest->hash, manifest->verification->base, manifest->pfr_hash->hash_out, manifest->pfr_hash->length); if (status != Success) { - DEBUG_PRINTF("staging verify failed\r\n"); + DEBUG_PRINTF("Staging manifest verification failed"); return Failure; } @@ -79,17 +89,19 @@ int pfr_staging_verify(struct pfr_manifest *manifest) // Recovery region PFM verification manifest->address += PFM_SIG_BLOCK_SIZE; + DEBUG_PRINTF("manifest->address=0x%08x manifest->recovery_address=0x%08x", manifest->address, manifest->recovery_address); // manifest verification - status = manifest->base->verify(manifest, manifest->hash, manifest->verification->base, manifest->pfr_hash->hash_out, manifest->pfr_hash->length); + status = manifest->base->verify((struct manifest *)manifest, manifest->hash, manifest->verification->base, manifest->pfr_hash->hash_out, manifest->pfr_hash->length); if (status != Success) { - DEBUG_PRINTF("staging verify failed\r\n"); + DEBUG_PRINTF("Recovery manifest verification failed"); return Failure; } manifest->update_fw->pfm_length = manifest->pc_length; manifest->address = read_address; + manifest->staging_address = read_address; - DEBUG_PRINTF("Stagig area verification successful\r\n"); + DEBUG_PRINTF("Staging area verification successful"); return Success; } @@ -100,7 +112,6 @@ int intel_pfr_update_verify(struct firmware_image *fw, struct hash_engine *hash, ARG_UNUSED(hash); ARG_UNUSED(rsa); - int status = 0; struct pfr_manifest *pfr_manifest = (struct pfr_manifest *) fw; return pfr_staging_verify(pfr_manifest); @@ -108,6 +119,7 @@ int intel_pfr_update_verify(struct firmware_image *fw, struct hash_engine *hash, int set_ufm_svn(struct pfr_manifest *manifest, uint8_t ufm_location, uint8_t svn_number) { + ARG_UNUSED(manifest); int status = 0; uint8_t svn_buffer[8]; @@ -130,6 +142,7 @@ int set_ufm_svn(struct pfr_manifest *manifest, uint8_t ufm_location, uint8_t svn int get_ufm_svn(struct pfr_manifest *manifest, uint8_t offset) { + ARG_UNUSED(manifest); uint8_t svn_size = 8; // we have (0- 63) SVN Number in 64 bits uint8_t svn_buffer[8]; @@ -155,7 +168,7 @@ int check_rot_capsule_type(struct pfr_manifest *manifest) status = pfr_spi_read(manifest->image_type, manifest->address + (2 * sizeof(pc_type)), sizeof(pc_type), (uint8_t *)&pc_type); if (pc_type == DECOMMISSION_CAPSULE) { - DEBUG_PRINTF("Decommission Certificate found\r\n"); + LOG_INF("Decommission Certificate found"); return DECOMMISSION_CAPSULE; } else if ((pc_type == CPLD_CAPSULE_CANCELLATION) || (pc_type == PCH_PFM_CANCELLATION) || (pc_type == PCH_CAPSULE_CANCELLATION) || (pc_type == BMC_PFM_CANCELLATION) || (pc_type == BMC_CAPSULE_CANCELLATION)) { @@ -171,65 +184,83 @@ int check_rot_capsule_type(struct pfr_manifest *manifest) int pfr_decommission(struct pfr_manifest *manifest) { - int status = 0; - uint8_t decom_buffer[DECOMMISSION_PC_SIZE] = { 0 }; uint8_t read_buffer[DECOMMISSION_PC_SIZE] = { 0 }; - CPLD_STATUS cpld_update_status; + int status = 0; + int i; status = pfr_spi_read(manifest->image_type, manifest->address, manifest->pc_length, read_buffer); if (status != Success) { - DEBUG_PRINTF("PfrDecommission failed\r\n"); + LOG_ERR("Flash read decommission capsule data failed"); return Failure; } - status = compare_buffer(read_buffer, decom_buffer, sizeof(read_buffer)); - if (status != Success) { - DEBUG_PRINTF("Invalid decommission capsule data\r\n"); - return Failure; + for (i = 0; i < DECOMMISSION_PC_SIZE; i++) { + if (read_buffer[i] != 0) { + LOG_ERR("Invalid decommission capsule data"); + return Failure; + } } // Erasing provisioned data - DEBUG_PRINTF("Decommission Success.Erasing the provisioned UFM data\r\n"); - status = ufm_erase(PROVISION_UFM); - if (status != Success) + if (status != Success) { + LOG_ERR("Erase the provisioned UFM data failed"); return Failure; + } - memset(&cpld_update_status, 0, sizeof(cpld_update_status)); + LOG_INF("Decommission Success"); + memset(&cpld_update_status, 0, sizeof(cpld_update_status)); cpld_update_status.DecommissionFlag = 1; status = ufm_write(UPDATE_STATUS_UFM, UPDATE_STATUS_ADDRESS, (uint8_t *)&cpld_update_status, sizeof(CPLD_STATUS)); - if (status != Success) + if (status != Success) { + LOG_ERR("Update ROT status in UPDATE_STATUS_UFM failed"); return Failure; - - // DEBUG_PRINTF("Flash the CPLD Update Capsule to do UFM Provision\r\n"); + } return Success; } int update_rot_fw(uint32_t address, uint32_t length) { - int status = 0; + uint32_t region_size = pfr_spi_get_device_size(ROT_INTERNAL_ACTIVE); uint32_t source_address = address; - uint32_t target_address = 0; - uint32_t rot_recovery_address = 0; uint32_t rot_active_address = 0; - uint32_t active_length = 0x60000; + uint32_t length_page_align; - for (int i = 0; i < (active_length / PAGE_SIZE); i++) { - pfr_spi_erase_4k(ROT_INTERNAL_RECOVERY, rot_recovery_address); - status = pfr_spi_page_read_write_between_spi(ROT_INTERNAL_ACTIVE, &rot_active_address, ROT_INTERNAL_RECOVERY, &rot_recovery_address); - if (status != Success) - return Failure; + length_page_align = (length % PAGE_SIZE) ? (length + (PAGE_SIZE - (length % PAGE_SIZE))) : length; + + if (length_page_align > region_size) { + LOG_ERR("length(%x) exceed region size(%x)", length_page_align, region_size); + return Failure; } - for (int i = 0; i <= (length / PAGE_SIZE); i++) { - pfr_spi_erase_4k(ROT_INTERNAL_ACTIVE, target_address); - status = pfr_spi_page_read_write_between_spi(BMC_SPI, &source_address, ROT_INTERNAL_ACTIVE, &target_address); - if (status != Success) - return Failure; + if (pfr_spi_erase_region(ROT_INTERNAL_RECOVERY, true, rot_recovery_address, + region_size)) { + LOG_ERR("Erase PFR Recovery region failed, address = %x, length = %x", rot_recovery_address, region_size); + return Failure; + } + + if (pfr_spi_region_read_write_between_spi(ROT_INTERNAL_ACTIVE, rot_active_address, + ROT_INTERNAL_RECOVERY, rot_recovery_address, region_size)) { + LOG_ERR("read(ROT_INTERNAL_ACTIVE) address =%x, write(ROT_INTERNAL_RECOVERY) address = %x, length = %x", + rot_active_address, rot_recovery_address, region_size); + return Failure; + } + + if (pfr_spi_erase_region(ROT_INTERNAL_ACTIVE, true, rot_active_address, + region_size)) { + LOG_ERR("Erase PFR Active region failed, address = %x, length = %x", rot_active_address, region_size); + return Failure; + } + + if (pfr_spi_region_read_write_between_spi(BMC_SPI, source_address, + ROT_INTERNAL_ACTIVE, rot_active_address, length_page_align)) { + LOG_ERR("read(BMC_SPI) address =%x, write(ROT_INTERNAL_ACTIVE) address = %x, length = %x", + source_address, rot_active_address, length_page_align); + return Failure; } return Success; @@ -242,10 +273,11 @@ int rot_svn_policy_verify(struct pfr_manifest *manifest, uint32_t hrot_svn) current_svn = get_ufm_svn(manifest, SVN_POLICY_FOR_CPLD_UPDATE); if (hrot_svn > SVN_MAX) { - DEBUG_PRINTF("Invalid Staging area SVN Number\r\n"); + LOG_ERR("Invalid Staging area SVN Number, %02x", hrot_svn); return Failure; - } else if (hrot_svn <= current_svn) { - DEBUG_PRINTF("Can't update with older version of SVN\r\n"); + } else if (hrot_svn < current_svn) { + LOG_ERR("Can't update with older version of SVN current=%02x staging=%02x", + current_svn, hrot_svn); return Failure; } set_ufm_svn(manifest, SVN_POLICY_FOR_CPLD_UPDATE, hrot_svn); @@ -256,26 +288,32 @@ int rot_svn_policy_verify(struct pfr_manifest *manifest, uint32_t hrot_svn) int ast1060_update(struct pfr_manifest *manifest) { - int status = 0; - uint8_t buffer; - uint32_t pc_length = 0, pc_type, pc_type_status; + uint32_t cancelled_id = 0; uint32_t payload_address; + uint32_t pc_type_status; + uint32_t pc_length = 0; + uint32_t hrot_svn = 0; + uint32_t pc_type; + int status = 0; // Checking the PC type status = pfr_spi_read(manifest->image_type, manifest->address + (2 * sizeof(pc_type)), sizeof(pc_type), (uint8_t *)&pc_type); if (status != Success) { - DEBUG_PRINTF("HROT update failed\r\n"); + LOG_ERR("Flash read PC type failed"); return Failure; } manifest->pc_type = pc_type; - status = manifest->base->verify(manifest, manifest->hash, manifest->verification->base, manifest->pfr_hash->hash_out, manifest->pfr_hash->length); + + LOG_INF("manifest->address=%x", manifest->address); + status = manifest->base->verify((struct manifest *)manifest, manifest->hash, manifest->verification->base, manifest->pfr_hash->hash_out, manifest->pfr_hash->length); if (status != Success) { - DEBUG_PRINTF("HROT update capsule verification failed\r\n"); + LOG_ERR("ROT update capsule verification failed"); SetMinorErrorCode(CPLD_UPD_CAPSULE_AUTH_FAIL); return Failure; } + LOG_INF("ROT update capsule verification success"); pc_type_status = check_rot_capsule_type(manifest); payload_address = manifest->address + PFM_SIG_BLOCK_SIZE; @@ -285,42 +323,40 @@ int ast1060_update(struct pfr_manifest *manifest) status = pfr_decommission(manifest); return status; } else if (pc_type_status == KEY_CANCELLATION_CAPSULE) { - uint32_t cancelled_id = 0; - status = pfr_spi_read(manifest->image_type, payload_address, sizeof(uint32_t), (uint8_t *)&cancelled_id); if (status != Success) { - DEBUG_PRINTF("HROT update failed\r\n"); + LOG_ERR("Flash read key cancellation Id failed"); return Failure; } status = manifest->keystore->kc_flag->cancel_kc_flag(manifest, cancelled_id); if (status == Success) - DEBUG_PRINTF("Key cancellation success. Key Id :%d was cancelled\r\n", cancelled_id); + LOG_INF("Key cancellation success. Key Id :%d was cancelled", cancelled_id); return status; } else if (pc_type_status == PFR_CPLD_UPDATE_CAPSULE) { - - uint32_t hrot_svn = 0; - - status = pfr_spi_read(manifest->image_type, payload_address, sizeof(uint32_t), &hrot_svn); - if (status != Success) + LOG_INF("ROT update start"); + status = pfr_spi_read(manifest->image_type, payload_address, sizeof(uint32_t), (uint8_t *)&hrot_svn); + if (status != Success) { + LOG_ERR("ROT flash read svn failed"); return Failure; + } status = rot_svn_policy_verify(manifest, hrot_svn); if (status != Success) { + LOG_ERR("ROT verify svn failed"); SetMinorErrorCode(CPLD_INVALID_SVN); return Failure; } - - pc_length = manifest->pc_length; - pc_length = pc_length - (sizeof(uint32_t) + HROT_UPDATE_RESERVED); - payload_address = payload_address + sizeof(uint32_t) + HROT_UPDATE_RESERVED; + pc_length = manifest->pc_length - sizeof(uint32_t); + payload_address = payload_address + sizeof(uint32_t); status = update_rot_fw(payload_address, pc_length); if (status != Success) { - DEBUG_PRINTF("Cpld update failed.\r\n"); + LOG_ERR("ROT update failed"); return Failure; } + LOG_INF("ROT update end"); } return Success; @@ -340,10 +376,11 @@ int check_svn_number(struct pfr_manifest *manifest, uint32_t read_address, uint8 staging_svn_number = ((PFM_STRUCTURE_1 *)buffer)->SVN; if (staging_svn_number > SVN_MAX) { - DEBUG_PRINTF("Invalid Staging area SVN Number\r\n"); + DEBUG_PRINTF("Invalid Staging area SVN Number"); return Failure; } else if (staging_svn_number < current_svn_number) { - DEBUG_PRINTF("Can't update with older version of SVN\r\n"); + DEBUG_PRINTF("Can't update with older version of SVN current=%02x staging=%02x", + current_svn_number, staging_svn_number); return Failure; } @@ -363,15 +400,15 @@ int update_recovery_region(int image_type, uint32_t source_address, uint32_t tar int update_firmware_image(uint32_t image_type, void *AoData, void *EventContext) { int status = 0; - uint32_t source_address, target_address, pfm_length, area_size, pc_length; + uint32_t source_address, target_address, area_size; + uint32_t act_pfm_offset; uint32_t address = 0; uint32_t pc_type_status = 0; - uint8_t active_update_needed = 0; uint8_t active_svn_number = 0; CPLD_STATUS cpld_update_status; AO_DATA *ActiveObjectData = (AO_DATA *) AoData; - EVENT_CONTEXT *EventData = (EVENT_CONTEXT *) EventContext; + DECOMPRESSION_TYPE_MASK_ENUM decomp_event = DECOMPRESSION_STATIC_REGIONS_MASK; uint32_t flash_select = ((EVENT_CONTEXT *)EventContext)->flash; @@ -383,24 +420,36 @@ int update_firmware_image(uint32_t image_type, void *AoData, void *EventContext) if (pfr_manifest->image_type == ROT_TYPE) { pfr_manifest->image_type = BMC_TYPE; - pfr_manifest->address = BMC_CPLD_STAGING_ADDRESS; + if (ufm_read(PROVISION_UFM, BMC_STAGING_REGION_OFFSET, (uint8_t *)&source_address, sizeof(source_address))) { + LOG_ERR("Read BMC staging region offset failed from UFM"); + return Failure; + } + + source_address += CONFIG_BMC_STAGING_SIZE; + source_address += CONFIG_BMC_PCH_STAGING_SIZE; + pfr_manifest->address = source_address; return ast1060_update(pfr_manifest); } if (pfr_manifest->image_type == BMC_TYPE) { - DEBUG_PRINTF("BMC Update in Progress\r\n"); - status = ufm_read(PROVISION_UFM, BMC_STAGING_REGION_OFFSET, (uint8_t *)&source_address, sizeof(source_address)); - if (status != Success) + DEBUG_PRINTF("BMC Update in Progress"); + if (ufm_read(PROVISION_UFM, BMC_STAGING_REGION_OFFSET, (uint8_t *)&source_address, sizeof(source_address))) + return Failure; + if (ufm_read(PROVISION_UFM, BMC_ACTIVE_PFM_OFFSET, (uint8_t *) &act_pfm_offset, sizeof(act_pfm_offset))) return Failure; - } else if (pfr_manifest->image_type == PCH_TYPE) { - DEBUG_PRINTF("PCH Update in Progress\r\n"); - status = ufm_read(PROVISION_UFM, PCH_STAGING_REGION_OFFSET, (uint8_t *)&source_address, sizeof(source_address)); - if (status != Success) - return status; + DEBUG_PRINTF("PCH Update in Progress"); + if (ufm_read(PROVISION_UFM, PCH_STAGING_REGION_OFFSET, (uint8_t *)&source_address, sizeof(source_address))) + return Failure; + if (ufm_read(PROVISION_UFM, PCH_ACTIVE_PFM_OFFSET, (uint8_t *) &act_pfm_offset, sizeof(act_pfm_offset))) + return Failure; } + pfr_manifest->staging_address = source_address; + pfr_manifest->active_pfm_addr = act_pfm_offset; + status = ufm_read(UPDATE_STATUS_UFM, UPDATE_STATUS_ADDRESS, (uint8_t *)&cpld_update_status, sizeof(CPLD_STATUS)); + LOG_HEXDUMP_INF(&cpld_update_status, sizeof(cpld_update_status), "CPLD Status"); if (status != Success) return status; @@ -415,11 +464,14 @@ int update_firmware_image(uint32_t image_type, void *AoData, void *EventContext) if (status != Success) return Failure; - address += BMC_STAGING_SIZE; // PFR Staging - PCH Staging offset is 32MB after BMC staging offset + // PFR Staging - PCH Staging offset after BMC staging offset + address += CONFIG_BMC_STAGING_SIZE; pfr_manifest->address = address; // Checking for key cancellation + pfr_manifest->image_type = BMC_TYPE; pc_type_status = check_rot_capsule_type(pfr_manifest); + pfr_manifest->image_type = image_type; status = pfr_staging_pch_staging(pfr_manifest); if (status != Success) @@ -433,16 +485,15 @@ int update_firmware_image(uint32_t image_type, void *AoData, void *EventContext) return ast1060_update(pfr_manifest); // Staging area verification - DEBUG_PRINTF("Staging Area verfication \r\n"); - // status = pfr_staging_verify(pfr_manifest); - status = pfr_manifest->update_fw->base->verify(pfr_manifest, NULL, NULL); + DEBUG_PRINTF("Staging Area verfication"); + status = pfr_manifest->update_fw->base->verify((struct firmware_image *)pfr_manifest, NULL, NULL); if (status != Success) { - DEBUG_PRINTF("Staging Area verfication failed\r\n"); + DEBUG_PRINTF("Staging Area verfication failed"); SetMinorErrorCode(FW_UPD_CAPSULE_AUTH_FAIL); return Failure; } - DEBUG_PRINTF("Staging Area verfication success \r\n"); + DEBUG_PRINTF("Staging Area verfication success"); // After staging manifest, Compression header will start area_size = pfr_manifest->update_fw->pc_length - (PFM_SIG_BLOCK_SIZE + pfr_manifest->update_fw->pfm_length); @@ -456,35 +507,35 @@ int update_firmware_image(uint32_t image_type, void *AoData, void *EventContext) status = check_svn_number(pfr_manifest, source_address, active_svn_number); if (status != Success) { SetMinorErrorCode(PCH_BMC_FW_INVALID_SVN); - DEBUG_PRINTF("Anti rollback\r\n"); + DEBUG_PRINTF("Anti rollback"); return Failure; } if (flash_select == PRIMARY_FLASH_REGION) { // Active Update - DEBUG_PRINTF("Active Region Update\r\n"); + DEBUG_PRINTF("Active Region Update"); if (ActiveObjectData->RestrictActiveUpdate == 1) { - DEBUG_PRINTF("Restrict Active Update\r\n"); + DEBUG_PRINTF("Restrict Active Update"); SetMinorErrorCode(UPD_NOT_ALLOWED); return Failure; } - status = capsule_decompression(pfr_manifest->image_type, source_address /* + PFM_SIG_BLOCK_SIZE + PFM_SIG_BLOCK_SIZE + PfmLength*/, area_size); - if (status != Success) - return Failure; + uint32_t time_start, time_end; + time_start = k_uptime_get_32(); - status = active_region_pfm_update(pfr_manifest); - if (status != Success) { - DEBUG_PRINTF("Active Region PFM Update failed!!\r\n"); + if (decompress_capsule(pfr_manifest, decomp_event)) return Failure; - } + + time_end = k_uptime_get_32(); + DEBUG_PRINTF("Firmware update completed, elapsed time = %u milliseconds", + (time_end - time_start)); } else { if (pfr_manifest->image_type == BMC_TYPE) { - DEBUG_PRINTF("BMC Recovery Region Update\r\n"); + DEBUG_PRINTF("BMC Recovery Region Update"); status = ufm_read(PROVISION_UFM, BMC_RECOVERY_REGION_OFFSET, (uint8_t *)&target_address, sizeof(target_address)); } else if (pfr_manifest->image_type == PCH_TYPE) { - DEBUG_PRINTF("PCH Recovery Region Update\r\n"); + DEBUG_PRINTF("PCH Recovery Region Update"); status = ufm_read(PROVISION_UFM, PCH_RECOVERY_REGION_OFFSET, (uint8_t *)&target_address, sizeof(target_address)); } @@ -493,7 +544,7 @@ int update_firmware_image(uint32_t image_type, void *AoData, void *EventContext) status = update_recovery_region(pfr_manifest->image_type, source_address, target_address); if (status != Success) { - DEBUG_PRINTF("Recovery capsule update failed\r\n"); + DEBUG_PRINTF("Recovery capsule update failed"); return Failure; } } @@ -533,25 +584,23 @@ void get_region_type(CPLD_STATUS region, void *AoData) void watchdog_timer(uint32_t image_type) { + ARG_UNUSED(image_type); #if 0 if (image_type == BMC_TYPE) { - printk("Watchdog timer BMC TYPE\r\n"); + DEBUG_PRINTF("Watchdog timer BMC TYPE"); } else { - printk("Watchdog timer PCH TYPE\r\n"); + DEBUG_PRINTF("Watchdog timer PCH TYPE"); } #endif } int check_staging_area(void) { - int status = 0; - uint32_t pc_length, read_address, pc_type; - uint8_t active_svn_number = 0; int flash_id; void *AoData = NULL; - DEBUG_PRINTF("Check Staging Area\r\n"); + DEBUG_PRINTF("Check Staging Area"); CPLD_STATUS cpld_update_status; status = ufm_read(UPDATE_STATUS_UFM, UPDATE_STATUS_ADDRESS, (uint8_t *)&cpld_update_status, sizeof(CPLD_STATUS)); @@ -559,7 +608,7 @@ int check_staging_area(void) return Failure; if (cpld_update_status.CpldStatus == 1) { - DEBUG_PRINTF("CPLD Check\r\n"); + DEBUG_PRINTF("CPLD Check"); get_region_type(cpld_update_status, AoData); DataContext.image = ROT_TYPE; flash_id = BMC_TYPE; @@ -567,7 +616,7 @@ int check_staging_area(void) // Checking CPLD staging area status = handle_update_image_action(ROT_TYPE, NULL, &DataContext); if (status == Success) { - DEBUG_PRINTF("SuccessFully updated cpld\r\n"); + DEBUG_PRINTF("SuccessFully updated cpld"); cpld_update_status.CpldStatus = 0; cpld_update_status.Region[0].ActiveRegion = 0; ufm_write(UPDATE_STATUS_UFM, UPDATE_STATUS_ADDRESS, (uint8_t *)&cpld_update_status, sizeof(CPLD_STATUS)); @@ -575,7 +624,7 @@ int check_staging_area(void) } if (cpld_update_status.BmcStatus == 1) { - DEBUG_PRINTF("BMC check\r\n"); + DEBUG_PRINTF("BMC check"); get_region_type(cpld_update_status, AoData); flash_id = BMC_TYPE; DataContext.image = flash_id; @@ -600,7 +649,7 @@ int check_staging_area(void) } if (cpld_update_status.PchStatus == 1) { - DEBUG_PRINTF("PCH check\r\n"); + DEBUG_PRINTF("PCH check"); // Checking PCH staging area flash_id = PCH_TYPE; diff --git a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_update.h b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_update.h index 099e244..b537e83 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_update.h +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_update.h @@ -4,11 +4,11 @@ * SPDX-License-Identifier: MIT */ -#ifndef INTEL_PFR_UPDATE_H_ -#define INTEL_PFR_UPDATE_H_ +#pragma once #include int intel_pfr_update_verify(struct firmware_image *fw, struct hash_engine *hash, struct rsa_engine *rsa); +int get_ufm_svn(struct pfr_manifest *manifest, uint8_t offset); +int set_ufm_svn(struct pfr_manifest *manifest, uint8_t ufm_location, uint8_t svn_number); -#endif /*INTEL_PFR_UPDATE_H_*/ diff --git a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_verification.c b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_verification.c index f50d850..5c23906 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_verification.c +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_verification.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: MIT */ +#include #include #include "state_machine/common_smc.h" #include "pfr/pfr_common.h" @@ -12,36 +13,38 @@ #include "intel_pfr_provision.h" #include "intel_pfr_key_cancellation.h" #include "intel_pfr_verification.h" +#include "Smbus_mailbox/Smbus_mailbox.h" -#undef DEBUG_PRINTF -#if PFR_AUTHENTICATION_DEBUG -#define DEBUG_PRINTF printk -#else -#define DEBUG_PRINTF(...) -#endif +LOG_MODULE_DECLARE(pfr, CONFIG_LOG_DEFAULT_LEVEL); int intel_pfr_manifest_verify(struct manifest *manifest, struct hash_engine *hash, struct signature_verification *verification, uint8_t *hash_out, uint32_t hash_length) { - - int status = 0; + struct pfr_manifest *pfr_manifest = (struct pfr_manifest *) manifest; uint32_t pc_type = 0; + int status = 0; - struct pfr_manifest *pfr_manifest = (struct pfr_manifest *) manifest; + ARG_UNUSED(hash); + ARG_UNUSED(verification); + ARG_UNUSED(hash_out); + ARG_UNUSED(hash_length); + ARG_UNUSED(verification); init_pfr_authentication(pfr_manifest->pfr_authentication); - status = pfr_spi_read(pfr_manifest->image_type, pfr_manifest->address + BLOCK0_PCTYPE_ADDRESS, sizeof(pc_type), &pc_type); - if (status != Success) + status = pfr_spi_read(pfr_manifest->image_type, pfr_manifest->address + BLOCK0_PCTYPE_ADDRESS, sizeof(pc_type), (uint8_t *)&pc_type); + if (status != Success) { + LOG_ERR("Flash read PC type failed"); return Failure; + } // Validate PC type - status = pfr_manifest->pfr_authentication->validate_pctye(pfr_manifest, pc_type); + status = pfr_manifest->pfr_authentication->validate_pctye(pfr_manifest, pc_type); if (status != Success) return Failure; // Validate Key cancellation - status = pfr_manifest->pfr_authentication->validate_kc(pfr_manifest); + status = pfr_manifest->pfr_authentication->validate_kc(pfr_manifest); if (status != Success) return Failure; @@ -60,123 +63,151 @@ int intel_pfr_manifest_verify(struct manifest *manifest, struct hash_engine *has int validate_pc_type(struct pfr_manifest *manifest, uint32_t pc_type) { - - if (pc_type != manifest->pc_type && manifest->pc_type != PFR_PCH_CPU_Seamless_Update_Capsule) + if (pc_type != manifest->pc_type && manifest->pc_type != PFR_PCH_CPU_Seamless_Update_Capsule) { + LOG_ERR("Validation PC Type failed, block0_read_pc_type = %x, manifest_pc_type = %x", pc_type, manifest->pc_type); return Failure; + } return Success; } -// Block 1 _ Block 0 Entry +// Block 1 Block 0 Entry int intel_block1_block0_entry_verify(struct pfr_manifest *manifest) { - int status = 0; + uint8_t buffer[sizeof(BLOCK0ENTRY)] = { 0 }; + uint8_t block0_signature_curve_magic = 0; uint32_t block0_entry_address = 0; BLOCK0ENTRY *block1_buffer; - uint8_t block0_signature_curve_magic = 0; - uint8_t verify_status = 0; - uint8_t buffer[sizeof(BLOCK0ENTRY)] = { 0 }; + uint32_t hash_length = 0; + int status = 0; - // Adjusting BlockAddress in case of KeyCancellation + // Adjusting Block Address in case of KeyCancellation if (manifest->kc_flag == 0) block0_entry_address = manifest->address + sizeof(PFR_AUTHENTICATION_BLOCK0) + CSK_START_ADDRESS + sizeof(CSKENTRY); else block0_entry_address = manifest->address + sizeof(PFR_AUTHENTICATION_BLOCK0) + CSK_START_ADDRESS; status = pfr_spi_read(manifest->image_type, block0_entry_address, sizeof(BLOCK0ENTRY), buffer); - if (status != Success) + if (status != Success) { + LOG_ERR("Block1 Block0 Entry: Flash read data failed"); return Failure; + } block1_buffer = (BLOCK0ENTRY *)&buffer; if (block1_buffer->TagBlock0Entry != BLOCK1_BLOCK0ENTRYTAG) { - DEBUG_PRINTF("Block 0 entry Magic/Tag not matched \r\n"); + LOG_ERR("Block1 Block0 Entry: Magic/Tag not matched, %x", block1_buffer->TagBlock0Entry); return Failure; } - if (block1_buffer->Block0SignatureMagic == SIGNATURE_SECP256_TAG) + if (block1_buffer->Block0SignatureMagic == SIGNATURE_SECP256_TAG) { block0_signature_curve_magic = secp256r1; - else if (block1_buffer->Block0SignatureMagic == SIGNATURE_SECP384_TAG) + manifest->pfr_hash->type = HASH_TYPE_SHA256; + hash_length = SHA256_HASH_LENGTH; + } else if (block1_buffer->Block0SignatureMagic == SIGNATURE_SECP384_TAG) { block0_signature_curve_magic = secp384r1; + manifest->pfr_hash->type = HASH_TYPE_SHA384; + hash_length = SHA384_HASH_LENGTH; + } else { + LOG_ERR("Block1 Block0 Entry: Unsupported signature magic, %x", block1_buffer->Block0SignatureMagic); + return Failure; + } // Key curve and Block 0 signature curve type should match if (block0_signature_curve_magic != manifest->hash_curve) { - DEBUG_PRINTF("Key curve magic and Block0 signature curve magic not matched \r\n"); + LOG_ERR("Block1 Block0 Entry: key curve magic and Block0 signature curve magic not matched, key_curve = %x, sig_curve = %x", + manifest->hash_curve, block0_signature_curve_magic); return Failure; } - uint8_t signature[2 * SHA384_DIGEST_LENGTH] = { 0 }; - uint32_t hash_length = 0; - manifest->pfr_hash->start_address = manifest->address; manifest->pfr_hash->length = sizeof(PFR_AUTHENTICATION_BLOCK0); - if (manifest->hash_curve == secp256r1) { - manifest->pfr_hash->type = HASH_TYPE_SHA256; - hash_length = SHA256_HASH_LENGTH; - } else if (manifest->hash_curve == secp384r1) { - manifest->pfr_hash->type = HASH_TYPE_SHA384; - hash_length = SHA384_HASH_LENGTH; - } else { + status = manifest->base->get_hash((struct manifest *)manifest, manifest->hash, manifest->pfr_hash->hash_out, hash_length); + if (status != Success) { + LOG_ERR("Block1 Block0 Entry: Get hash failed"); return Failure; } - status = manifest->base->get_hash(manifest, manifest->hash, manifest->pfr_hash->hash_out, hash_length); - if (status != Success) - return Failure; - memcpy(manifest->verification->pubkey->signature_r, block1_buffer->Block0SignatureR, hash_length); memcpy(manifest->verification->pubkey->signature_s, block1_buffer->Block0SignatureS, hash_length); - status = manifest->verification->base->verify_signature(manifest, manifest->pfr_hash->hash_out, hash_length, signature, (2 * hash_length)); - if (status != Success) + status = manifest->verification->base->verify_signature((struct signature_verification *)manifest, manifest->pfr_hash->hash_out, hash_length, NULL, (2 * hash_length)); + if (status != Success) { + LOG_ERR("Block1 Block0 Entry: Verify signature failed"); + LOG_HEXDUMP_INF(manifest->verification->pubkey->x, hash_length, "ECDSA X:"); + LOG_HEXDUMP_INF(manifest->verification->pubkey->y, hash_length, "ECDSA Y:"); + LOG_HEXDUMP_INF(manifest->verification->pubkey->signature_r, hash_length, "ECDSA R:"); + LOG_HEXDUMP_INF(manifest->verification->pubkey->signature_s, hash_length, "ECDSA S:"); + LOG_INF("Hash Info: address = %x, length = %x", manifest->pfr_hash->start_address, manifest->pfr_hash->length); + LOG_HEXDUMP_INF(manifest->pfr_hash->hash_out, hash_length, "Calculated D:"); return Failure; - - DEBUG_PRINTF("Block 0 entry Verification status: %d\r\n", status); + } return Success; } -// Block 1 CSK +// Block 1 CSK Entry int intel_block1_csk_block0_entry_verify(struct pfr_manifest *manifest) { - int status = 0; - uint32_t sign_bit_verify = 0; uint32_t block1_address = manifest->address + sizeof(PFR_AUTHENTICATION_BLOCK0); - CSKENTRY *block1_buffer; - uint8_t csk_sign_curve_magic = 0; uint8_t buffer[sizeof(CSKENTRY)] = { 0 }; + uint8_t csk_sign_curve_magic = 0; uint8_t csk_key_curve_type = 0; - uint8_t verify_status = 0; + uint32_t sign_bit_verify = 0; + CSKENTRY *block1_buffer; + uint32_t hash_length = 0; + int status = 0; + int i; status = pfr_spi_read(manifest->image_type, block1_address + CSK_START_ADDRESS, sizeof(CSKENTRY), buffer); - if (status != Success) + if (status != Success) { + LOG_ERR("Block1 CSK Entry: Flash read data failed"); return Failure; + } block1_buffer = (CSKENTRY *)&buffer; // validate CSK entry magic tag if (block1_buffer->CskEntryInitial.Tag != BLOCK1CSKTAG) { - DEBUG_PRINTF("CSK Magic/Tag not matched \r\n"); + LOG_ERR("Block1 CSK Entry: Magic/Tag not matched, %x", block1_buffer->CskEntryInitial.Tag); return Failure; } - if (block1_buffer->CskSignatureMagic == SIGNATURE_SECP256_TAG) + if (block1_buffer->CskEntryInitial.PubCurveMagic == PUBLIC_SECP256_TAG) { + csk_key_curve_type = secp256r1; + } else if (block1_buffer->CskEntryInitial.PubCurveMagic == PUBLIC_SECP384_TAG) { + csk_key_curve_type = secp384r1; + } else { + LOG_ERR("Block1 CSK Entry: Unsupported curve magic, %x", block1_buffer->CskEntryInitial.PubCurveMagic); + return Failure; + } + + // Root key curve and CSK curve should match + if (csk_key_curve_type != manifest->hash_curve) { + LOG_ERR("Block1 CSK Entry: Root key curve magic and CSK curve magic not matched, root_curve = %x, csk_curve = %x", + manifest->hash_curve, csk_key_curve_type); + return Failure; + } + + if (block1_buffer->CskSignatureMagic == SIGNATURE_SECP256_TAG) { csk_sign_curve_magic = secp256r1; - else if (block1_buffer->CskSignatureMagic == SIGNATURE_SECP384_TAG) + manifest->pfr_hash->type = HASH_TYPE_SHA256; + hash_length = SHA256_DIGEST_LENGTH; + } else if (block1_buffer->CskSignatureMagic == SIGNATURE_SECP384_TAG) { csk_sign_curve_magic = secp384r1; - - // Root key curve and CSK signature curve type should match - if (csk_sign_curve_magic != manifest->hash_curve) { - DEBUG_PRINTF("Root Key curve magic and CSK key signature curve magic not matched \r\n"); + manifest->pfr_hash->type = HASH_TYPE_SHA384; + hash_length = SHA384_DIGEST_LENGTH; + } else { + LOG_ERR("Block1 CSK Entry: Unsupported signature magic, %x", block1_buffer->CskSignatureMagic); return Failure; } - // Update CSK curve type to validate Block 0 entry - if (block1_buffer->CskEntryInitial.PubCurveMagic == PUBLIC_SECP256_TAG) - csk_key_curve_type = secp256r1; - else if (block1_buffer->CskEntryInitial.PubCurveMagic == PUBLIC_SECP384_TAG) - csk_key_curve_type = secp384r1; + if (csk_key_curve_type != csk_sign_curve_magic) { + LOG_ERR("Block1 CSK Entry: curve magic type and signature magic type not matched, key_curve = %x, sig_curve = %x", + csk_key_curve_type, csk_sign_curve_magic); + return Failure; + } // Key permission if (manifest->pc_type == PFR_BMC_UPDATE_CAPSULE) {// Bmc update @@ -189,51 +220,55 @@ int intel_block1_csk_block0_entry_verify(struct pfr_manifest *manifest) sign_bit_verify = SIGN_PCH_PFM_BIT0; } else if (manifest->pc_type == PFR_CPLD_UPDATE_CAPSULE || manifest->pc_type == PFR_CPLD_UPDATE_CAPSULE_DECOMMISSON) { - // HROT update + // ROT update sign_bit_verify = SIGN_CPLD_UPDATE_BIT4; } if (!(block1_buffer->CskEntryInitial.KeyPermission & sign_bit_verify)) { - DEBUG_PRINTF("CSK key permission denied..\r\n"); + LOG_ERR("Block1 CSK Entry: CSK key permission denied..., %x", block1_buffer->CskEntryInitial.KeyPermission); return Failure; } - uint8_t signature[2 * SHA384_DIGEST_LENGTH] = { 0 }; - uint32_t hash_length = 0; + // Check for the 0s in the reserved field + for (i = 0; i < BLOCK1_CSK_ENTRY_RESERVED_SIZE; i++) { + if (block1_buffer->CskEntryInitial.Reserved[i] != 0) { + LOG_ERR("Block1 CSK Entry: reserved data failed"); + return Failure; + } + } manifest->pfr_hash->start_address = block1_address + CSK_START_ADDRESS + sizeof(block1_buffer->CskEntryInitial.Tag); manifest->pfr_hash->length = CSK_ENTRY_PC_SIZE; - if (csk_key_curve_type == secp256r1) { - manifest->pfr_hash->type = HASH_TYPE_SHA256; - hash_length = SHA256_DIGEST_LENGTH; - } else if (csk_key_curve_type == secp384r1) { - manifest->pfr_hash->type = HASH_TYPE_SHA384; - hash_length = SHA384_DIGEST_LENGTH; - } else { + status = manifest->base->get_hash((struct manifest *)manifest, manifest->hash, manifest->pfr_hash->hash_out, hash_length); + if (status != Success) { + LOG_ERR("Block1 CSK Entry: Get hash failed"); return Failure; } - status = manifest->base->get_hash(manifest, manifest->hash, manifest->pfr_hash->hash_out, hash_length); - if (status != Success) - return Failure; - memcpy(manifest->verification->pubkey->signature_r, block1_buffer->CskSignatureR, hash_length); memcpy(manifest->verification->pubkey->signature_s, block1_buffer->CskSignatureS, hash_length); - // memcpy(&signature[0],&block1_buffer->CskSignatureR[0],hash_length); - // memcpy(&signature[hash_length],&block1_buffer->CskSignatureS[0],hash_length); - - status = manifest->verification->base->verify_signature(manifest, manifest->pfr_hash->hash_out, hash_length, signature, (2 * hash_length)); - if (status != Success) + status = manifest->verification->base->verify_signature((struct signature_verification *)manifest, manifest->pfr_hash->hash_out, hash_length, NULL, (2 * hash_length)); + if (status != Success) { + LOG_ERR("Block1 CSK Entry: Verify signature failed"); + LOG_HEXDUMP_INF(manifest->verification->pubkey->x, hash_length, "ECDSA X:"); + LOG_HEXDUMP_INF(manifest->verification->pubkey->y, hash_length, "ECDSA Y:"); + LOG_HEXDUMP_INF(manifest->verification->pubkey->signature_r, hash_length, "ECDSA R:"); + LOG_HEXDUMP_INF(manifest->verification->pubkey->signature_s, hash_length, "ECDSA S:"); + LOG_INF("Hash Info: address = %x, length = %x", manifest->pfr_hash->start_address, manifest->pfr_hash->length); + LOG_HEXDUMP_INF(manifest->pfr_hash->hash_out, hash_length, "Calculated D:"); return Failure; + } + + // Update csk key to validate b0 entry + memcpy(manifest->verification->pubkey->x, block1_buffer->CskEntryInitial.PubKeyX, hash_length); + memcpy(manifest->verification->pubkey->y, block1_buffer->CskEntryInitial.PubKeyY, hash_length); status = manifest->pfr_authentication->block1_block0_entry_verify(manifest); if (status != Success) return Failure; - DEBUG_PRINTF("Block0 Entry validation success\r\n"); - return Success; } @@ -246,107 +281,84 @@ int intel_block1_verify(struct pfr_manifest *manifest) status = pfr_spi_read(manifest->image_type, manifest->address + sizeof(PFR_AUTHENTICATION_BLOCK0), sizeof(block1_buffer->TagBlock1) + sizeof(block1_buffer->ReservedBlock1) + sizeof(block1_buffer->RootEntry), buffer); if (status != Success) { - DEBUG_PRINTF("Block1 Verification failed\r\n"); + LOG_ERR("Block1: Flash read data failed"); return Failure; } block1_buffer = (PFR_AUTHENTICATION_BLOCK1 *)buffer; if (block1_buffer->TagBlock1 != BLOCK1TAG) { - DEBUG_PRINTF("Block1 Tag Not Found\r\n"); + LOG_ERR("Block1: Tag Not Found, %x", block1_buffer->TagBlock1); return Failure; } status = verify_root_key_entry(manifest, block1_buffer); if (status != Success) { - DEBUG_PRINTF("Root Entry validation failed\r\n"); + LOG_ERR("Block1 Root Entry: Validation failed"); return Failure; } - DEBUG_PRINTF("Root Entry validation success\r\n"); + LOG_INF("Block1 Root Entry: Validation success"); + + // Update root key to validate csk entry if csk entry exist or b0 entry if csk entry does not exist memcpy(manifest->verification->pubkey->x, block1_buffer->RootEntry.PubKeyX, sizeof(block1_buffer->RootEntry.PubKeyX)); memcpy(manifest->verification->pubkey->y, block1_buffer->RootEntry.PubKeyY, sizeof(block1_buffer->RootEntry.PubKeyY)); - if (block1_buffer->RootEntry.PubCurveMagic == PUBLIC_SECP256_TAG) - manifest->verification->pubkey->length = SHA256_DIGEST_LENGTH; - else if (block1_buffer->RootEntry.PubCurveMagic == PUBLIC_SECP384_TAG) - manifest->verification->pubkey->length = SHA384_DIGEST_LENGTH; - if (manifest->kc_flag == 0) { // CSK and Block 0 entry verification status = manifest->pfr_authentication->block1_csk_block0_entry_verify(manifest); if (status != Success) { - DEBUG_PRINTF("CSK and Block0 Entry validation failed\r\n"); + LOG_ERR("Block1 CSK and Block0 Entry: Validation failed"); return Failure; } + LOG_INF("Block1 CSK and Block0 Entry: Validation success"); } else { status = manifest->pfr_authentication->block1_block0_entry_verify(manifest); if (status != Success) { - DEBUG_PRINTF("Block0 Entry validation failed\r\n"); + LOG_ERR("Block1 Block0 Entry: Validation failed"); return Failure; } + LOG_INF("Block1 Block0 Entry: Validation success"); } return Success; } // BLOCK 0 -uint8_t intel_block0_verify(struct pfr_manifest *manifest) +int intel_block0_verify(struct pfr_manifest *manifest) { - int status = 0; - uint32_t pc_type_status = 0; - PFR_AUTHENTICATION_BLOCK0 *block0_buffer; - - uint8_t block0_hash_match = 0; uint8_t buffer[sizeof(PFR_AUTHENTICATION_BLOCK0)] = { 0 }; uint8_t sha_buffer[SHA384_DIGEST_LENGTH] = { 0 }; + PFR_AUTHENTICATION_BLOCK0 *block0_buffer; + uint32_t hash_length = 0; + uint8_t *ptr_sha; + int status = 0; status = pfr_spi_read(manifest->image_type, manifest->address, sizeof(PFR_AUTHENTICATION_BLOCK0), buffer); if (status != Success) { - DEBUG_PRINTF("Block0 Verification failed\r\n"); - return Failure; - } - - status = pfr_spi_read(manifest->image_type, manifest->address + (2 * sizeof(pc_type_status)), sizeof(pc_type_status), (uint8_t *)&pc_type_status); - if (status != Success) { - DEBUG_PRINTF("Block0 Verification failed\r\n"); + LOG_ERR("Block0: Flash read data failed"); return Failure; } block0_buffer = (PFR_AUTHENTICATION_BLOCK0 *)buffer; - // Block0 Hash verify - status = get_buffer_hash(manifest, buffer, sizeof(PFR_AUTHENTICATION_BLOCK0), sha_buffer); - if (status != Success) - return Success; - - if (manifest->hash_curve == secp256r1) - status = compare_buffer(manifest->pfr_hash->hash_out, sha_buffer, SHA256_DIGEST_LENGTH); - else if (manifest->hash_curve == secp384r1) - status = compare_buffer(manifest->pfr_hash->hash_out, sha_buffer, SHA384_DIGEST_LENGTH); - else - return Failure; - - if (status != Success) { - DEBUG_PRINTF("Block0 Hash Not Matched..\r\n"); + if (block0_buffer->Block0Tag != BLOCK0TAG) { + LOG_ERR("Block0: Tag Not Found, %x", block0_buffer->Block0Tag); return Failure; } - if (block0_buffer->Block0Tag != BLOCK0TAG) { - DEBUG_PRINTF("Block0 tag not found\r\n"); + if ((block0_buffer->PcLength < 128) || (block0_buffer->PcLength % 128 != 0)) { + LOG_ERR("Block0: PC length failed, %x", block0_buffer->PcLength); return Failure; } - if (pc_type_status == DECOMMISSION_CAPSULE) { - manifest->pc_length = block0_buffer->PcLength; - return Success; + if (block0_buffer->PcType == DECOMMISSION_CAPSULE) { + if (block0_buffer->PcLength != DECOMMISSION_PC_SIZE) { + LOG_ERR("Block0: Decommission capsule PC length failed, %x", block0_buffer->PcLength); + return Failure; + } } - uint32_t hash_length = 0; - uint8_t *ptr_sha; - - memset(sha_buffer, 0x00, sizeof(sha_buffer)); - // Protected content length manifest->pc_length = block0_buffer->PcLength; manifest->pfr_hash->start_address = manifest->address + PFM_SIG_BLOCK_SIZE; @@ -361,23 +373,29 @@ uint8_t intel_block0_verify(struct pfr_manifest *manifest) hash_length = SHA384_DIGEST_LENGTH; ptr_sha = block0_buffer->Sha384Pc; } else { + LOG_ERR("Block0: Unsupported hash curve, %x", manifest->hash_curve); return Failure; } - status = manifest->base->get_hash(manifest, manifest->hash, sha_buffer, hash_length); - if (status != Success) + status = manifest->base->get_hash((struct manifest *)manifest, manifest->hash, sha_buffer, hash_length); + if (status != Success) { + LOG_ERR("Block0: Get hash failed"); return Failure; + } + LOG_INF("Block0: Verification PC, address = %x, length = %x", manifest->pfr_hash->start_address, manifest->pfr_hash->length); status = compare_buffer(ptr_sha, sha_buffer, hash_length); if (status != Success) { - DEBUG_PRINTF(" Block0 Verification failed..\r\n"); + LOG_ERR("Block0: Verification PC failed"); + LOG_HEXDUMP_INF(sha_buffer, hash_length, "Calculated hash:"); + LOG_HEXDUMP_INF(ptr_sha, hash_length, "Expected hash:"); return Failure; } - if (pc_type_status == PFR_CPLD_UPDATE_CAPSULE) + if (block0_buffer->PcType == PFR_CPLD_UPDATE_CAPSULE) SetCpldFpgaRotHash(&sha_buffer[0]); - DEBUG_PRINTF("Block0 Hash Matched..\r\n"); + LOG_INF("Block0: Hash Matched"); return Success; } diff --git a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_verification.h b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_verification.h index d51b626..3e168fd 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_verification.h +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_verification.h @@ -4,15 +4,15 @@ * SPDX-License-Identifier: MIT */ -#ifndef INTEL_PFR_VERIFICATION_H_ -#define INTEL_PFR_VERIFICATION_H_ +#pragma once #include +#include "pfr/pfr_common.h" #define INTEL_PFR_BLOCK_0_TAG 0xB6EAFD19 #define DECOMMISSION_CAPSULE 0x200 -#define KEY_CANCELLATION_CAPSULE 0x300 +#define KEY_CANCELLATION_CAPSULE 0x100 #define FALSE 0 #define TRUE 1 @@ -27,13 +27,12 @@ #define HROT_UPDATE_RESERVED 32 #define MAX_BIOS_BOOT_TIME 300 #define MAX_ERASE_SIZE 0x1000 -#define MAX_READ_SIZE 0x100 -#define MAX_WRITE_SIZE 0x100 #define RANDOM_KEY_MAGIC_TAG 0x52414E44 #define RANDOM_KEY_ADDRESS_IN_UFM ((PROVISION_UFM_SIZE * 16) - (2 * SHA384_SIZE)) #define ROOT_PUB_KEY_LOC_IN_UFM (RANDOM_KEY_ADDRESS_IN_UFM - (2 * SHA384_SIZE)) #define MAGIC_TAG_SIZE 4 +#define BLOCK1_CSK_ENTRY_RESERVED_SIZE 20 #pragma pack(1) @@ -215,11 +214,11 @@ struct pfr_authentication { int (*block1_csk_block0_entry_verify)(struct pfr_manifest *manifest); int (*block1_verify)(struct pfr_manifest *manifest); int (*block0_verify)(struct pfr_manifest *manifest); - int (*validate_root_key); }; +#pragma pack() int intel_pfr_manifest_verify(struct manifest *manifest, struct hash_engine *hash, struct signature_verification *verification, uint8_t *hash_out, uint32_t hash_length); -#endif /*INTEL_PFR_VERIFICATION_H*/ +void init_pfr_authentication(struct pfr_authentication *pfr_authentication); diff --git a/apps/aspeed-pfr/src/main.c b/apps/aspeed-pfr/src/main.c index 3e9cca0..98c8a3a 100644 --- a/apps/aspeed-pfr/src/main.c +++ b/apps/aspeed-pfr/src/main.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: MIT */ +#include #include #include "state_machine.h" @@ -17,6 +18,9 @@ #include "intel_pfr/intel_pfr_definitions.h" #include "intel_pfr/intel_pfr_pfm_manifest.h" #include +#include "AspeedStateMachine/AspeedStateMachine.h" + +LOG_MODULE_REGISTER(main, CONFIG_LOG_DEFAULT_LEVEL); #define DEBUG_HALT() { \ volatile int halt = 1; \ @@ -29,30 +33,9 @@ void main(void) { int status = 0; - printk("\r\n *** ASPEED_PFR version 0.0.1 ***\r\n"); - - status = initializeEngines(); - status = initializeManifestProcessor(); - debug_log_init();// State Machine log saving - - // DEBUG_HALT(); - BMCBootHold(); - PCHBootHold(); - - // I2c_slave_dev_debug+> - struct i2c_slave_interface *I2CSlaveEngine = getI2CSlaveEngineInstance(); - struct I2CSlave_engine_wrapper *I2cSlaveEngineWrapper; - - status = I2C_Slave_wrapper_init(getI2CSlaveEngineInstance()); - //I2CSlaveEngine->InitSlaveDev(I2CSlaveEngine,"I2C_2",0x38); - - /* TODO: Discard slave address */ - I2CSlaveEngine->InitSlaveDev(I2CSlaveEngine,"BMCMBX_0", 0x38); + LOG_INF("*** ASPEED_PFR version 01.01 Board:%s ***", CONFIG_BOARD); -#if SMBUS_MAILBOX_SUPPORT - InitializeSmbusMailbox(); - SetPlatformState(ENTER_T_MINUS_1); -#endif + aspeed_print_sysrst_info(); - StartHrotStateMachine(); + AspeedStateMachine(); } diff --git a/apps/aspeed-pfr/src/manifestProcessor/manifestProcessor.c b/apps/aspeed-pfr/src/manifestProcessor/manifestProcessor.c index 13d7572..81a31c5 100644 --- a/apps/aspeed-pfr/src/manifestProcessor/manifestProcessor.c +++ b/apps/aspeed-pfr/src/manifestProcessor/manifestProcessor.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: MIT */ +#include #include #include "include/definitions.h" @@ -11,13 +12,17 @@ #include "common/common.h" #include "firmware/app_image.h" +LOG_MODULE_REGISTER(manifest, CONFIG_LOG_DEFAULT_LEVEL); + int initializeManifestProcessor(void) { int status = 0; +#ifdef CONFIG_CERBERUS_PFR status = manifest_flash_init(getManifestFlashInstance(), getFlashDeviceInstance(), PFM_FLASH_MANIFEST_ADDRESS, PFM_V2_MAGIC_NUM); if (status) return status; +#endif init_pfr_manifest(); // status = pfm_manager_flash_init(getPfmManagerFlashInstance(), getPfmFlashInstance(), getPfmFlashInstance(), @@ -37,12 +42,12 @@ int processPfmFlashManifest(void) uint8_t *hashStorage = getNewHashStorage(); struct manifest_flash *manifest_flash = getManifestFlashInstance(); - // printk("Manifest Verification\n"); + LOG_INF("Manifest Verification\n"); status = manifest_flash_verify(manifest_flash, get_hash_engine_instance(), getSignatureVerificationInstance(), hashStorage, hashStorageLength); if (true == manifest_flash->manifest_valid) { - printk("Manifest Verificaation Successful\n"); + LOG_INF("Manifest Verificaation Successful\n"); status = perform_image_verification(); } diff --git a/apps/aspeed-pfr/src/manifestProcessor/manifestProcessor.h b/apps/aspeed-pfr/src/manifestProcessor/manifestProcessor.h index 88ecc2c..272091d 100644 --- a/apps/aspeed-pfr/src/manifestProcessor/manifestProcessor.h +++ b/apps/aspeed-pfr/src/manifestProcessor/manifestProcessor.h @@ -4,12 +4,10 @@ * SPDX-License-Identifier: MIT */ -#ifndef ZEPHYR_ASPEED_PFR_SRC_MANIFESTPROCESSOR_MANIFESTPROCESSOR_H_ -#define ZEPHYR_ASPEED_PFR_SRC_MANIFESTPROCESSOR_MANIFESTPROCESSOR_H_ +#pragma once #include int initializeManifestProcessor(void); int processPfmFlashManifest(void); -#endif /* ZEPHYR_ASPEED_PFR_SRC_MANIFESTPROCESSOR_MANIFESTPROCESSOR_H_ */ diff --git a/apps/aspeed-pfr/src/pfr/pfr_common.h b/apps/aspeed-pfr/src/pfr/pfr_common.h index 5e7b658..6c8ddd0 100644 --- a/apps/aspeed-pfr/src/pfr/pfr_common.h +++ b/apps/aspeed-pfr/src/pfr/pfr_common.h @@ -4,8 +4,7 @@ * SPDX-License-Identifier: MIT */ -#ifndef PFR_COMMON_H_ -#define PFR_COMMON_H_ +#pragma once #include "manifest/manifest_flash.h" #include "manifest/manifest.h" @@ -37,6 +36,7 @@ struct pfr_manifest { uint32_t address; // START ADDRESS uint32_t recovery_address; // Recovery address uint32_t staging_address; // Staging Address + uint32_t active_pfm_addr; // Active PFM address uint32_t pc_length; // Protected Content Size uint32_t pc_type; // manifest protected content type uint32_t kc_flag; // Key Cancellation flag @@ -90,4 +90,3 @@ struct pfr_keystore { void init_pfr_manifest(void); struct pfr_manifest *get_pfr_manifest(void); -#endif /* PFR_COMMON_H_ */ diff --git a/apps/aspeed-pfr/src/pfr/pfr_recovery.c b/apps/aspeed-pfr/src/pfr/pfr_recovery.c index 54b4260..25bffb1 100644 --- a/apps/aspeed-pfr/src/pfr/pfr_recovery.c +++ b/apps/aspeed-pfr/src/pfr/pfr_recovery.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: MIT */ +#include #include "pfr_recovery.h" #include "StateMachineAction/StateMachineActions.h" #include "state_machine/common_smc.h" @@ -11,9 +12,11 @@ #include "intel_pfr/intel_pfr_definitions.h" #include "include/SmbusMailBoxCom.h" +LOG_MODULE_DECLARE(pfr, CONFIG_LOG_DEFAULT_LEVEL); + #undef DEBUG_PRINTF #if PF_UPDATE_DEBUG -#define DEBUG_PRINTF printk +#define DEBUG_PRINTF LOG_INF #else #define DEBUG_PRINTF(...) #endif @@ -32,12 +35,12 @@ int recover_image(void *AoData, void *EventContext) if (EventData->image == BMC_EVENT) { // BMC SPI - DEBUG_PRINTF("Image Type: BMC \r\n"); + DEBUG_PRINTF("Image Type: BMC "); pfr_manifest->image_type = BMC_TYPE; } else { // PCH SPI - DEBUG_PRINTF("Image Type: PCH \r\n"); + DEBUG_PRINTF("Image Type: PCH "); pfr_manifest->image_type = PCH_TYPE; } @@ -45,7 +48,7 @@ int recover_image(void *AoData, void *EventContext) // status = pfr_staging_verify(pfr_manifest); status = status = pfr_manifest->update_fw->base->verify(pfr_manifest, NULL, NULL); if (status != Success) { - DEBUG_PRINTF("PFR Staging Area Corrupted\r\n"); + DEBUG_PRINTF("PFR Staging Area Corrupted"); if (ActiveObjectData->ActiveImageStatus != Success) { SetMajorErrorCode(pfr_manifest->image_type == BMC_TYPE ? BMC_AUTH_FAIL : PCH_AUTH_FAIL); SetMinorErrorCode(ACTIVE_RECOVERY_STAGING_AUTH_FAIL); diff --git a/apps/aspeed-pfr/src/pfr/pfr_recovery.h b/apps/aspeed-pfr/src/pfr/pfr_recovery.h index 0e836a7..905477e 100644 --- a/apps/aspeed-pfr/src/pfr/pfr_recovery.h +++ b/apps/aspeed-pfr/src/pfr/pfr_recovery.h @@ -4,8 +4,4 @@ * SPDX-License-Identifier: MIT */ -#ifndef PFR_RECOVERY_H_ -#define PFR_RECOVERY_H_ - - -#endif /*PFR_RECOVERY_H_*/ +#pragma once diff --git a/apps/aspeed-pfr/src/pfr/pfr_ufm.c b/apps/aspeed-pfr/src/pfr/pfr_ufm.c index 4d9d42c..5b4b656 100644 --- a/apps/aspeed-pfr/src/pfr/pfr_ufm.c +++ b/apps/aspeed-pfr/src/pfr/pfr_ufm.c @@ -11,7 +11,6 @@ int get_cpld_status(uint8_t *data, uint32_t data_length) { - int status; struct spi_engine_wrapper *spi_flash = getSpiEngineWrapper(); diff --git a/apps/aspeed-pfr/src/pfr/pfr_ufm.h b/apps/aspeed-pfr/src/pfr/pfr_ufm.h index 0860eba..e5bcb97 100644 --- a/apps/aspeed-pfr/src/pfr/pfr_ufm.h +++ b/apps/aspeed-pfr/src/pfr/pfr_ufm.h @@ -4,10 +4,8 @@ * SPDX-License-Identifier: MIT */ -#ifndef PFR_UFM_H -#define PFR_UFM_H +#pragma once int ufm_read(uint32_t ufm_id, uint32_t offset, uint8_t *data, uint32_t data_length); int ufm_write(uint32_t ufm_id, uint32_t offset, uint8_t *data, uint32_t data_length); - -#endif /*PFR_UFM_H*/ +int ufm_erase(uint32_t ufm_id); diff --git a/apps/aspeed-pfr/src/pfr/pfr_update.c b/apps/aspeed-pfr/src/pfr/pfr_update.c index 43cba4c..e5debd1 100644 --- a/apps/aspeed-pfr/src/pfr/pfr_update.c +++ b/apps/aspeed-pfr/src/pfr/pfr_update.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: MIT */ +#include #include #include "pfr_ufm.h" #include "state_machine/common_smc.h" @@ -15,10 +16,11 @@ #include "pfr_common.h" #include +LOG_MODULE_DECLARE(pfr, CONFIG_LOG_DEFAULT_LEVEL); #undef DEBUG_PRINTF #if PF_UPDATE_DEBUG -#define DEBUG_PRINTF printk +#define DEBUG_PRINTF LOG_INF #else #define DEBUG_PRINTF(...) #endif diff --git a/apps/aspeed-pfr/src/pfr/pfr_update.h b/apps/aspeed-pfr/src/pfr/pfr_update.h index 6dc0ac4..6bfae9c 100644 --- a/apps/aspeed-pfr/src/pfr/pfr_update.h +++ b/apps/aspeed-pfr/src/pfr/pfr_update.h @@ -4,9 +4,7 @@ * SPDX-License-Identifier: MIT */ -#ifndef PFR_UPDATE_H_ -#define PFR_UPDATE_H_ +#pragma once extern int pfr_update_image(int image_type, void *AoData, void *EventContext); -#endif /*PFR_UPDATE_H_*/ diff --git a/apps/aspeed-pfr/src/pfr/pfr_util.c b/apps/aspeed-pfr/src/pfr/pfr_util.c index c6e6f22..738b94f 100644 --- a/apps/aspeed-pfr/src/pfr/pfr_util.c +++ b/apps/aspeed-pfr/src/pfr/pfr_util.c @@ -4,102 +4,145 @@ * SPDX-License-Identifier: MIT */ -#if !defined(MBEDTLS_CONFIG_FILE) +/* + * mbedtls library for ECDSA. + * + */ +#if defined(CONFIG_MBEDTLS) +#if !defined(CONFIG_MBEDTLS_CFG_FILE) #include "mbedtls/config.h" #else -#include MBEDTLS_CONFIG_FILE +#include CONFIG_MBEDTLS_CFG_FILE #endif +#include "mbedtls/ecdsa.h" +#endif + +#include -// #include "pfr_util.h" +#include "common/common.h" #include "flash/flash_wrapper.h" #include "flash/flash_util.h" #include "state_machine/common_smc.h" #include "pfr_common.h" #include "intel_pfr/intel_pfr_definitions.h" +#include "crypto/ecdsa_aspeed.h" #include -#include -#include -#include "mbedtls/ecdsa.h" #include #include #include +#include -#undef DEBUG_PRINTF -#if 1 -#define DEBUG_PRINTF printk -#else -#define DEBUG_PRINTF(...) -#endif +LOG_MODULE_DECLARE(pfr, CONFIG_LOG_DEFAULT_LEVEL); +uint8_t buffer[PAGE_SIZE] __aligned(16); -int pfr_spi_read(unsigned int device_id, unsigned int address, unsigned int data_length, unsigned char *data) +int pfr_spi_read(uint8_t device_id, uint32_t address, uint32_t data_length, uint8_t *data) { int status = 0; struct spi_engine_wrapper *spi_flash = getSpiEngineWrapper(); spi_flash->spi.device_id[0] = device_id; // assign the flash device id, 0:spi1_cs0, 1:spi2_cs0 , 2:spi2_cs1, 3:spi2_cs2, 4:fmc_cs0, 5:fmc_cs1 - spi_flash->spi.base.read(&spi_flash->spi, address, data, data_length); - return Success; + status = spi_flash->spi.base.read((struct flash *)&spi_flash->spi, address, data, data_length); + return status; } -int pfr_spi_write(unsigned int device_id, unsigned int address, unsigned int data_length, unsigned char *data) +int pfr_spi_write(uint8_t device_id, uint32_t address, uint32_t data_length, uint8_t *data) { int status = 0; struct spi_engine_wrapper *spi_flash = getSpiEngineWrapper(); spi_flash->spi.device_id[0] = device_id; // assign the flash device id, 0:spi1_cs0, 1:spi2_cs0 , 2:spi2_cs1, 3:spi2_cs2, 4:fmc_cs0, 5:fmc_cs1 - spi_flash->spi.base.write(&spi_flash->spi, address, data, data_length); - return Success; + spi_flash->spi.base.write((struct flash *)&spi_flash->spi, address, data, data_length); + return status; } -int pfr_spi_erase_4k(unsigned int device_id, unsigned int address) +int pfr_spi_erase_4k(uint8_t device_id, uint32_t address) { - int status = 0; + int status; struct spi_engine_wrapper *spi_flash = getSpiEngineWrapper(); spi_flash->spi.device_id[0] = device_id; // assign the flash device id, 0:spi1_cs0, 1:spi2_cs0 , 2:spi2_cs1, 3:spi2_cs2, 4:fmc_cs0, 5:fmc_cs1 - spi_flash->spi.base.sector_erase(&spi_flash->spi, address); + status = spi_flash->spi.base.sector_erase((struct flash *)&spi_flash->spi, address); + return status; +} + +int pfr_spi_erase_block(uint8_t device_id, uint32_t address) +{ + int status; + struct spi_engine_wrapper *spi_flash = getSpiEngineWrapper(); + + spi_flash->spi.device_id[0] = device_id; // assign the flash device id, 0:spi1_cs0, 1:spi2_cs0 , 2:spi2_cs1, 3:spi2_cs2, 4:fmc_cs0, 5:fmc_cs1 + status = spi_flash->spi.base.block_erase((struct flash *)&spi_flash->spi, address); + return status; +} + +int pfr_spi_erase_region(uint8_t device_id, + bool support_block_erase, uint32_t start_addr, uint32_t nbytes) +{ + uint32_t erase_addr = start_addr; + uint32_t end_addr = start_addr + nbytes; + + while (erase_addr < end_addr) { + if (support_block_erase && ((end_addr - erase_addr) >= BLOCK_SIZE) && + !(erase_addr & 0xffff)) { + if (pfr_spi_erase_block(device_id, erase_addr)) + return Failure; + erase_addr += BLOCK_SIZE; + } else { + if (pfr_spi_erase_4k(device_id, erase_addr)) + return Failure; + erase_addr += PAGE_SIZE; + } + } + return Success; } -int pfr_spi_page_read_write(unsigned int device_id, uint32_t *source_address, uint32_t *target_address) +uint32_t pfr_spi_get_device_size(uint8_t device_id) { - int status = 0; - int index1, index2; - uint8_t buffer[MAX_READ_SIZE] = { 0 }; + struct spi_engine_wrapper *spi_flash = getSpiEngineWrapper(); + uint32_t size; + spi_flash->spi.device_id[0] = device_id; // assign the flash device id, 0:spi1_cs0, 1:spi2_cs0 , 2:spi2_cs1, 3:spi2_cs2, 4:fmc_cs0, 5:fmc_cs1 + spi_flash->spi.base.get_device_size((struct flash *)&spi_flash->spi, &size); + return size; +} + +int pfr_spi_get_block_size(uint8_t device_id) +{ struct spi_engine_wrapper *spi_flash = getSpiEngineWrapper(); + int block_sz; spi_flash->spi.device_id[0] = device_id; // assign the flash device id, 0:spi1_cs0, 1:spi2_cs0 , 2:spi2_cs1, 3:spi2_cs2, 4:fmc_cs0, 5:fmc_cs1 + spi_flash->spi.base.get_block_size((struct flash *)&spi_flash->spi, &block_sz); + return block_sz; +} - for (index1 = 0; index1 < (PAGE_SIZE / MAX_READ_SIZE); index1++) { - spi_flash->spi.base.read(&spi_flash->spi, *source_address, buffer, MAX_READ_SIZE); - for (index2 = 0; index2 < (MAX_READ_SIZE / MAX_WRITE_SIZE); index2++) { - spi_flash->spi.base.write(&spi_flash->spi, *target_address, &buffer[index2 * MAX_WRITE_SIZE], MAX_WRITE_SIZE); - *target_address += MAX_WRITE_SIZE; - } +int pfr_spi_page_read_write(uint8_t device_id, uint32_t source_address, uint32_t target_address) +{ + struct spi_engine_wrapper *spi_flash = getSpiEngineWrapper(); - *source_address += MAX_READ_SIZE; - } + spi_flash->spi.device_id[0] = device_id; // assign the flash device id, 0:spi1_cs0, 1:spi2_cs0 , 2:spi2_cs1, 3:spi2_cs2, 4:fmc_cs0, 5:fmc_cs1 + if (spi_flash->spi.base.read((struct flash *)&spi_flash->spi, source_address, buffer, PAGE_SIZE)) + return Failure; + spi_flash->spi.base.write((struct flash *)&spi_flash->spi, target_address, buffer, PAGE_SIZE); return Success; } -int pfr_spi_page_read_write_between_spi(int source_flash, uint32_t *source_address, int target_flash, uint32_t *target_address) +int pfr_spi_page_read_write_between_spi(uint8_t source_flash, uint32_t *source_address, uint8_t target_flash, uint32_t *target_address) { - int status = 0; uint32_t index1, index2; - uint8_t buffer[MAX_READ_SIZE]; struct spi_engine_wrapper *spi_flash = getSpiEngineWrapper(); for (index1 = 0; index1 < (PAGE_SIZE / MAX_READ_SIZE); index1++) { spi_flash->spi.device_id[0] = source_flash; // assign the flash device id, 0:spi1_cs0, 1:spi2_cs0 , 2:spi2_cs1, 3:spi2_cs2, 4:fmc_cs0, 5:fmc_cs1 - spi_flash->spi.base.read(&spi_flash->spi, *source_address, buffer, MAX_READ_SIZE); + spi_flash->spi.base.read((struct flash *)&spi_flash->spi, *source_address, buffer, MAX_READ_SIZE); for (index2 = 0; index2 < (MAX_READ_SIZE / MAX_WRITE_SIZE); index2++) { spi_flash->spi.device_id[0] = target_flash; - spi_flash->spi.base.write(&spi_flash->spi, *target_address, &buffer[index2 * MAX_WRITE_SIZE], MAX_WRITE_SIZE); + spi_flash->spi.base.write((struct flash *)&spi_flash->spi, *target_address, &buffer[index2 * MAX_WRITE_SIZE], MAX_WRITE_SIZE); *target_address += MAX_WRITE_SIZE; } @@ -110,16 +153,33 @@ int pfr_spi_page_read_write_between_spi(int source_flash, uint32_t *source_addre return Success; } -// calculates sha for dataBuffer -int get_buffer_hash(struct pfr_manifest *manifest, uint8_t *data_buffer, uint8_t length, unsigned char *hash_out) +int pfr_spi_region_read_write_between_spi(uint8_t src_dev, uint32_t src_addr, + uint8_t dest_dev, uint32_t dest_addr, size_t length) { - + int i; struct spi_engine_wrapper *spi_flash = getSpiEngineWrapper(); + for (i = 0; i < length / PAGE_SIZE; i++) { + spi_flash->spi.device_id[0] = src_dev; + spi_flash->spi.base.read((struct flash *)&spi_flash->spi, src_addr, buffer, PAGE_SIZE); + spi_flash->spi.device_id[0] = dest_dev; + spi_flash->spi.base.write((struct flash *)&spi_flash->spi, dest_addr, buffer, PAGE_SIZE); + src_addr += PAGE_SIZE; + dest_addr += PAGE_SIZE; + } + + return Success; +} + +// calculates sha for dataBuffer +int get_buffer_hash(struct pfr_manifest *manifest, uint8_t *data_buffer, uint8_t length, uint8_t *hash_out) +{ if (manifest->hash_curve == secp256r1) { manifest->hash->start_sha256(manifest->hash); manifest->hash->calculate_sha256(manifest->hash, data_buffer, length, hash_out, SHA256_HASH_LENGTH); } else if (manifest->hash_curve == secp384r1) { + manifest->hash->start_sha384(manifest->hash); + manifest->hash->calculate_sha384(manifest->hash, data_buffer, length, hash_out, SHA384_HASH_LENGTH); } else { return Failure; } @@ -127,19 +187,9 @@ int get_buffer_hash(struct pfr_manifest *manifest, uint8_t *data_buffer, uint8_t return Success; } -int esb_ecdsa_verify(struct pfr_manifest *manifest, unsigned int digest[], unsigned char pub_key[], - unsigned char signature[], unsigned char *auth_pass) -{ - *auth_pass = true; - - return Success; -} - // Calculate hash digest int get_hash(struct manifest *manifest, struct hash_engine *hash_engine, uint8_t *hash_out, size_t hash_length) { - int status = 0; - struct pfr_manifest *pfr_manifest = (struct pfr_manifest *)manifest; if (pfr_manifest == NULL || hash_engine == NULL || @@ -147,88 +197,47 @@ int get_hash(struct manifest *manifest, struct hash_engine *hash_engine, uint8_t (hash_length > SHA256_HASH_LENGTH && hash_length < SHA384_HASH_LENGTH)) { return Failure; } - flash_hash_contents(pfr_manifest->flash, pfr_manifest->pfr_hash->start_address, pfr_manifest->pfr_hash->length, pfr_manifest->hash, pfr_manifest->pfr_hash->type, hash_out, hash_length); - return Success; -} - -// print buffer -void print_buffer(uint8_t *string, uint8_t *buffer, uint32_t length) -{ - - DEBUG_PRINTF("\r\n%s ", string); - - for (int i = 0; i < length; i++) - DEBUG_PRINTF(" %x", buffer[i]); - - DEBUG_PRINTF("\r\n"); + return flash_hash_contents((struct flash *)pfr_manifest->flash, pfr_manifest->pfr_hash->start_address, pfr_manifest->pfr_hash->length, pfr_manifest->hash, pfr_manifest->pfr_hash->type, hash_out, hash_length); } // compare buffer int compare_buffer(uint8_t *buffer1, uint8_t *buffer2, uint32_t length) { - int status = Success; - - for (int i = 0; i < length; i++) { - if ((buffer1[i] != buffer2[i]) && (status != Failure)) - status = Failure; - } - return status; -} - -// reverse byte array -void reverse_byte_array(uint8_t *data_buffer, uint32_t length) -{ - uint8_t temp = 0; - - for (int i = 0, j = length; i < length / 2; i++, j--) { - temp = data_buffer[i]; - data_buffer[i] = data_buffer[j]; - data_buffer[j] = temp; - } + return memcmp(buffer1, buffer2, length); } static int mbedtls_ecdsa_verify_middlelayer(struct pfr_pubkey *pubkey, - const uint8_t *digest, uint8_t *signature_r, + const uint8_t *digest, size_t length, uint8_t *signature_r, uint8_t *signature_s) { mbedtls_ecdsa_context ctx_verify; - mbedtls_mpi r, s; - unsigned char hash[SHA256_HASH_LENGTH]; + mbedtls_mpi r; + mbedtls_mpi s; + uint8_t z = 1; int ret = 0; - char z = 1; mbedtls_ecdsa_init(&ctx_verify); mbedtls_mpi_init(&r); mbedtls_mpi_init(&s); - - // print_buffer("ECDSA X: ", pubkey->x, pubkey->length); - // print_buffer("ECDSA Y: ", pubkey->y, pubkey->length); - // print_buffer("ECDSA R: ", signature_r, pubkey->length); - // print_buffer("ECDSA S: ", signature_s, pubkey->length); - // print_buffer("ECDSA D: ", digest, pubkey->length); - - mbedtls_mpi_read_binary(&ctx_verify.Q.X, pubkey->x, pubkey->length /*SHA256_HASH_LENGTH*/); - - mbedtls_mpi_read_binary(&ctx_verify.Q.Y, pubkey->y, pubkey->length /*SHA256_HASH_LENGTH*/); - + mbedtls_mpi_read_binary(&ctx_verify.Q.X, pubkey->x, length); + mbedtls_mpi_read_binary(&ctx_verify.Q.Y, pubkey->y, length); mbedtls_mpi_read_binary(&ctx_verify.Q.Z, &z, 1); + mbedtls_mpi_read_binary(&r, signature_r, length); + mbedtls_mpi_read_binary(&s, signature_s, length); - mbedtls_mpi_read_binary(&r, signature_r, pubkey->length /*SHA256_HASH_LENGTH*/); + if (length == SHA256_HASH_LENGTH) + mbedtls_ecp_group_load(&ctx_verify.grp, MBEDTLS_ECP_DP_SECP256R1); + else if (length == SHA384_HASH_LENGTH) + mbedtls_ecp_group_load(&ctx_verify.grp, MBEDTLS_ECP_DP_SECP384R1); + else + LOG_ERR("Unsupported ECDSA curve length, %d", length); - mbedtls_mpi_read_binary(&s, signature_s, pubkey->length /*SHA256_HASH_LENGTH*/); - - mbedtls_ecp_group_load(&ctx_verify.grp, MBEDTLS_ECP_DP_SECP256R1); - memcpy(hash, digest, pubkey->length /*SHA256_HASH_LENGTH*/); - ret = mbedtls_ecdsa_verify(&ctx_verify.grp, hash, SHA256_HASH_LENGTH, + ret = mbedtls_ecdsa_verify(&ctx_verify.grp, digest, length, &ctx_verify.Q, &r, &s); - mbedtls_ecdsa_free(&ctx_verify); mbedtls_mpi_free(&r); mbedtls_mpi_free(&s); - - // printk("ECDSA:%d\r\n", ret); - return ret; } @@ -247,26 +256,38 @@ static int mbedtls_ecdsa_verify_middlelayer(struct pfr_pubkey *pubkey, int verify_signature(struct signature_verification *verification, const uint8_t *digest, size_t length, const uint8_t *signature, size_t sig_length) { - int status = Success; - struct pfr_manifest *manifest = (struct pfr_manifest *)verification; - // uint8_t signature_r[SHA256_HASH_LENGTH]; - // uint8_t signature_s[SHA256_HASH_LENGTH]; - // memcpy(&signature_r[0],&signature[0],length); - // memcpy(&signature_s[0],&signature[length],length); + int status = Success; - int ecdsa_result = mbedtls_ecdsa_verify_middlelayer(manifest->verification->pubkey, - digest, - manifest->verification->pubkey->signature_r, - manifest->verification->pubkey->signature_s); + ARG_UNUSED(signature); + ARG_UNUSED(sig_length); + + if (length == SHA256_HASH_LENGTH) { + LOG_DBG("MBEDTLS ECDSA Start"); + status = mbedtls_ecdsa_verify_middlelayer(manifest->verification->pubkey, + digest, + length, + manifest->verification->pubkey->signature_r, + manifest->verification->pubkey->signature_s); + LOG_DBG("MBEDTLS ECDSA End, status = %d", status); + } else if (length == SHA384_HASH_LENGTH) { + LOG_DBG("ASPEED ECDSA Start"); + status = aspeed_ecdsa_verify_middlelayer(manifest->verification->pubkey->x, + manifest->verification->pubkey->y, + digest, + length, + manifest->verification->pubkey->signature_r, + manifest->verification->pubkey->signature_s); + LOG_DBG("ASPEED ECDSA End, status = %d", status); + } else + LOG_ERR("Unsupported digest length, %d", length); return status; } - int pfr_cpld_update_reboot(void) { - DEBUG_PRINTF("system going reboot ...\n"); + LOG_INF("system going reboot ..."); #if (CONFIG_KERNEL_SHELL_REBOOT_DELAY > 0) k_sleep(K_MSEC(CONFIG_KERNEL_SHELL_REBOOT_DELAY)); diff --git a/apps/aspeed-pfr/src/pfr/pfr_util.h b/apps/aspeed-pfr/src/pfr/pfr_util.h index 04c89cd..7b6f9d7 100644 --- a/apps/aspeed-pfr/src/pfr/pfr_util.h +++ b/apps/aspeed-pfr/src/pfr/pfr_util.h @@ -4,38 +4,41 @@ * SPDX-License-Identifier: MIT */ -#ifndef PFR_UTIL_H -#define PFR_UTIL_H +#pragma once -#include +#include "pfr_common.h" -int pfr_spi_read(unsigned int device_id, unsigned int address, - unsigned int data_length, unsigned char *data); +int pfr_spi_read(uint8_t device_id, uint32_t address, + uint32_t data_length, uint8_t *data); -int pfr_spi_write(unsigned int device_id, unsigned int address, - unsigned int data_length, unsigned char *data); +int pfr_spi_write(uint8_t device_id, uint32_t address, + uint32_t data_length, uint8_t *data); -int pfr_spi_page_read_write(unsigned int device_id, uint32_t *source_address, uint32_t *target_address); +int pfr_spi_page_read_write(uint8_t device_id, uint32_t source_address, uint32_t target_address); -int pfr_spi_erase_4k(unsigned int device_id, unsigned int address); +int pfr_spi_erase_4k(uint8_t device_id, uint32_t address); -int esb_ecdsa_verify(struct pfr_manifest *manifest, unsigned int digest[], unsigned char pub_key[], - unsigned char signature[], unsigned char *auth_pass); +int pfr_spi_erase_block(uint8_t device_id, uint32_t address); -int get_buffer_hash(struct pfr_manifest *manifest, uint8_t *data_buffer, uint8_t length, unsigned char *hash_out); +int pfr_spi_erase_region(uint8_t device_id, + bool support_block_erase, uint32_t start_addr, uint32_t nbytes); + +int pfr_spi_region_read_write_between_spi(uint8_t src_dev, uint32_t src_addr, + uint8_t dest_dev, uint32_t dest_addr, size_t length); + +uint32_t pfr_spi_get_device_size(uint8_t device_id); + +int pfr_spi_get_block_size(uint8_t device_id); + +int get_buffer_hash(struct pfr_manifest *manifest, uint8_t *data_buffer, uint8_t length, uint8_t *hash_out); int get_hash(struct manifest *manifest, struct hash_engine *hash_engine, uint8_t *hash_out, size_t hash_length); -void print_buffer(uint8_t *string, uint8_t *buffer, uint32_t length); - int compare_buffer(uint8_t *buffer1, uint8_t *buffer2, uint32_t length); -void reverse_byte_array(uint8_t *data_buffer, uint32_t length); - int verify_signature(struct signature_verification *verification, const uint8_t *digest, size_t length, const uint8_t *signature, size_t sig_length); int pfr_cpld_update_reboot(void); -#endif /*PFR_UTIL_H*/ diff --git a/apps/aspeed-pfr/src/pfr/pfr_verification.c b/apps/aspeed-pfr/src/pfr/pfr_verification.c index 7095e79..f5b7040 100644 --- a/apps/aspeed-pfr/src/pfr/pfr_verification.c +++ b/apps/aspeed-pfr/src/pfr/pfr_verification.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: MIT */ +#include #include "intel_pfr/intel_pfr_authentication.h" #include "StateMachineAction/StateMachineActions.h" #include "state_machine/common_smc.h" @@ -13,16 +14,17 @@ #include "intel_pfr/intel_pfr_definitions.h" #include "pfr_util.h" +LOG_MODULE_DECLARE(pfr, CONFIG_LOG_DEFAULT_LEVEL); + #undef DEBUG_PRINTF #if PFR_AUTHENTICATION_DEBUG -#define DEBUG_PRINTF printk +#define DEBUG_PRINTF LOG_INF #else #define DEBUG_PRINTF(...) #endif int authentication_image(void *AoData, void *EventContext) { - int status = 0; AO_DATA *ActiveObjectData = (AO_DATA *) AoData; EVENT_CONTEXT *EventData = (EVENT_CONTEXT *) EventContext; @@ -34,12 +36,12 @@ int authentication_image(void *AoData, void *EventContext) if (EventData->image == BMC_EVENT) { // BMC SPI - DEBUG_PRINTF("Image Type: BMC \r\n"); + DEBUG_PRINTF("Image Type: BMC "); pfr_manifest->image_type = BMC_TYPE; } else { // PCH SPI - DEBUG_PRINTF("Image Type: PCH \r\n"); + DEBUG_PRINTF("Image Type: PCH "); pfr_manifest->image_type = PCH_TYPE; } @@ -70,7 +72,6 @@ int authentication_image(void *AoData, void *EventContext) int manifest_verify(struct manifest *manifest, struct hash_engine *hash, struct signature_verification *verification, uint8_t *hash_out, size_t hash_length) { - return intel_pfr_manifest_verify(manifest, hash, verification, hash_out, hash_length); } @@ -84,7 +85,6 @@ int manifest_verify(struct manifest *manifest, struct hash_engine *hash, */ int manifest_get_id(struct manifest *manifest, uint32_t *id) { - ARG_UNUSED(manifest); ARG_UNUSED(id); @@ -107,7 +107,6 @@ int manifest_get_id(struct manifest *manifest, uint32_t *id) */ int manifest_get_platform_id(struct manifest *manifest, char **id, size_t length) { - ARG_UNUSED(manifest); ARG_UNUSED(id); ARG_UNUSED(length); @@ -124,7 +123,6 @@ int manifest_get_platform_id(struct manifest *manifest, char **id, size_t length */ void manifest_free_platform_id(struct manifest *manifest, char *id) { - ARG_UNUSED(manifest); ARG_UNUSED(id); @@ -146,7 +144,6 @@ void manifest_free_platform_id(struct manifest *manifest, char *id) int manifest_get_hash(struct manifest *manifest, struct hash_engine *hash, uint8_t *hash_out, size_t hash_length) { - return get_hash(manifest, hash, hash_out, hash_length); } @@ -162,7 +159,6 @@ int manifest_get_hash(struct manifest *manifest, struct hash_engine *hash, uint8 */ int manifest_get_signature(struct manifest *manifest, uint8_t *signature, size_t length) { - ARG_UNUSED(manifest); ARG_UNUSED(signature); ARG_UNUSED(length); diff --git a/apps/aspeed-pfr/src/pfr/pfr_verification.h b/apps/aspeed-pfr/src/pfr/pfr_verification.h index bc2a03e..acf3fc7 100644 --- a/apps/aspeed-pfr/src/pfr/pfr_verification.h +++ b/apps/aspeed-pfr/src/pfr/pfr_verification.h @@ -4,8 +4,7 @@ * SPDX-License-Identifier: MIT */ -#ifndef PFR_VERIFICATION_H -#define PFR_VERIFICATION_H +#pragma once int authentication_image(void *AoData, void *EventContext); @@ -17,4 +16,3 @@ int PfmSpiRegionVerification(unsigned int ImageId, unsigned int FlashSelect); // -- Recovery Region int RecoveryRegionVerification(int ImageType); -#endif /* PFR_VERIFICATION_H */ diff --git a/apps/aspeed-pfr/src/platform_monitor/platform_monitor.c b/apps/aspeed-pfr/src/platform_monitor/platform_monitor.c new file mode 100644 index 0000000..a487ac3 --- /dev/null +++ b/apps/aspeed-pfr/src/platform_monitor/platform_monitor.c @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2022 ASPEED Technology Inc. + * + * SPDX-License-Identifier: MIT + */ +#include +#include +#include +#include "state_machine/state_machine.h" +#include "StateMachineAction/StateMachineActions.h" +#include "AspeedStateMachine/AspeedStateMachine.h" + +LOG_MODULE_REGISTER(monitor, CONFIG_LOG_DEFAULT_LEVEL); + +AO_DATA BmcAOData; +static EVENT_CONTEXT BmcData[2]; +static struct gpio_callback bmc_rstind_cb_data; +void bmc_rstind_handler(const struct device *dev, struct gpio_callback *cb, uint32_t pins) +{ + uint8_t gpio_pin = 31 - __builtin_clz(pins); + int ret = gpio_pin_get(dev, gpio_pin); + LOG_INF("[BMC->PFR] RSTIND[%s %d] = %d", dev->name, gpio_pin, ret); + + GenerateStateMachineEvent(RESET_DETECTED, NULL); +} + +/* Monitor BMC Reset Status */ +void platform_monitor_init() +{ + int ret; + struct gpio_dt_spec bmc_rstind = + GPIO_DT_SPEC_GET_BY_IDX(DT_INST(0, demo_gpio_basic_api), bmc_rst_ind_in_gpios, 0); + ret = gpio_pin_configure_dt(&bmc_rstind, GPIO_INPUT); + LOG_INF("BMC: gpio_pin_configure_dt[%s %d] = %d", bmc_rstind.port->name, bmc_rstind.pin, ret); + ret = gpio_pin_interrupt_configure_dt(&bmc_rstind, GPIO_INT_EDGE_FALLING); + LOG_INF("BMC: gpio_pin_interrupt_configure_dt = %d", ret); + gpio_init_callback(&bmc_rstind_cb_data, bmc_rstind_handler, BIT(bmc_rstind.pin)); + ret = gpio_add_callback(bmc_rstind.port, &bmc_rstind_cb_data); + LOG_INF("BMC: gpio_add_callback = %d", ret); +} + +void platform_monitor_remove() +{ + struct gpio_dt_spec bmc_rstind = + GPIO_DT_SPEC_GET_BY_IDX(DT_INST(0, demo_gpio_basic_api), bmc_rst_ind_in_gpios, 0); + gpio_pin_interrupt_configure_dt(&bmc_rstind, GPIO_INT_DISABLE); + gpio_remove_callback(bmc_rstind.port, &bmc_rstind_cb_data); +} diff --git a/apps/aspeed-pfr/src/platform_monitor/platform_monitor.h b/apps/aspeed-pfr/src/platform_monitor/platform_monitor.h new file mode 100644 index 0000000..005b0fe --- /dev/null +++ b/apps/aspeed-pfr/src/platform_monitor/platform_monitor.h @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2022 ASPEED Technology Inc. + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +void platform_monitor_init(); +void platform_monitor_remove(); diff --git a/apps/aspeed-pfr/src/platform_monitor/spim_monitor.c b/apps/aspeed-pfr/src/platform_monitor/spim_monitor.c new file mode 100644 index 0000000..d8d1dd2 --- /dev/null +++ b/apps/aspeed-pfr/src/platform_monitor/spim_monitor.c @@ -0,0 +1,121 @@ +/* + * Copyright (c) 2021 Aspeed Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + * + * This work is ported from Aspeed Zephyr SDK sample code. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +LOG_MODULE_REGISTER(spim, CONFIG_LOG_DEFAULT_LEVEL); + +struct demo_spim_log_ctrl { + struct k_work log_work; + struct spim_log_info info; + const struct device *dev; + uint32_t cur_off; + uint32_t pre_off; +}; + +struct k_sem sem_demo_log_op; +struct demo_spim_log_ctrl log_ctrls[4]; +const struct device *spim_devs[4]; + +static void spim_log_parser(const struct device *dev, uint32_t idx, uint32_t log_val) +{ + switch ((log_val & 0x000c0000) >> 18) { + case 0x0: + /* block command */ + LOG_ERR("[%s][b][%03d][cmd] %02xh", + dev->name, idx, log_val & 0xFF); + break; + case 0x1: + /* block write command */ + LOG_ERR("[%s][b][%03d][w_addr] 0x%08x", + dev->name, idx, (log_val & 0x3FFFF) << 14); + break; + case 0x2: + /* block read command */ + LOG_ERR("[%s][b][%03d][r_addr] 0x%08x", + dev->name, idx, (log_val & 0x3FFFF) << 14); + break; + default: + LOG_ERR("[%s][%03d]invalid ctx: 0x%08x", dev->name, idx, log_val); + } +} + +void demo_rst_log_ptr(const struct device *dev) +{ + uint32_t ctrl_idx = spim_get_ctrl_idx(dev); + if (IS_ENABLED(CONFIG_MULTITHREADING)) + k_sem_take(&sem_demo_log_op, K_FOREVER); + log_ctrls[ctrl_idx - 1].pre_off = 0; + if (IS_ENABLED(CONFIG_MULTITHREADING)) + k_sem_give(&sem_demo_log_op); +} + +static void demo_spim_log_work(struct k_work *item) +{ + uint32_t i; + struct demo_spim_log_ctrl *log_ctrl = + CONTAINER_OF(item, struct demo_spim_log_ctrl, log_work); + if (IS_ENABLED(CONFIG_MULTITHREADING)) + k_sem_take(&sem_demo_log_op, K_FOREVER); + spim_get_log_info(log_ctrl->dev, &log_ctrl->info); + log_ctrl->cur_off = log_ctrl->info.log_idx_reg; + if (log_ctrl->cur_off < log_ctrl->pre_off) { + for (i = log_ctrl->pre_off; i < log_ctrl->info.log_max_sz / 4; i++) { + spim_log_parser(log_ctrl->dev, i, + sys_read32(log_ctrl->info.log_ram_addr + i * 4)); + } + log_ctrl->pre_off = 0; + } + for (i = log_ctrl->pre_off; i < log_ctrl->cur_off; i++) { + spim_log_parser(log_ctrl->dev, i, + sys_read32(log_ctrl->info.log_ram_addr + i * 4)); + } + log_ctrl->pre_off = log_ctrl->cur_off; + if (IS_ENABLED(CONFIG_MULTITHREADING)) + k_sem_give(&sem_demo_log_op); +} + +static void demo_spim_isr_callback(const struct device *dev) +{ + uint32_t ctrl_idx = spim_get_ctrl_idx(dev); + /* notice: the ctrl_idx is from 1 to 4 */ + k_work_submit(&log_ctrls[ctrl_idx - 1].log_work); +} + +void spim_irq_init(void) +{ + uint32_t i; + static char *spim_dev_names[4] = { + "spi_m1", + "spi_m2", + "spi_m3", + "spi_m4" + }; + if (IS_ENABLED(CONFIG_MULTITHREADING)) + k_sem_init(&sem_demo_log_op, 1, 1); + memset(log_ctrls, 0x0, sizeof(struct demo_spim_log_ctrl)); + for (i = 0; i < 3; i++) { + spim_devs[i] = device_get_binding(spim_dev_names[i]); + if (!spim_devs[i]) { + LOG_ERR("demo_err: cannot get device, %s.\n", spim_dev_names[i]); + continue; + } + log_ctrls[i].dev = spim_devs[i]; + spim_isr_callback_install(spim_devs[i], demo_spim_isr_callback); + k_work_init(&log_ctrls[i].log_work, demo_spim_log_work); + } +} diff --git a/apps/aspeed-pfr/src/platform_monitor/spim_monitor.h b/apps/aspeed-pfr/src/platform_monitor/spim_monitor.h new file mode 100644 index 0000000..8470553 --- /dev/null +++ b/apps/aspeed-pfr/src/platform_monitor/spim_monitor.h @@ -0,0 +1,8 @@ +/* + * Copyright (c) 2022 ASPEED Technology Inc. + * + * SPDX-License-Identifier: MIT + */ +#pragma once + +void spim_irq_init(void); diff --git a/apps/aspeed-pfr/src/state_machine/common_smc.h b/apps/aspeed-pfr/src/state_machine/common_smc.h index da7a944..072528c 100644 --- a/apps/aspeed-pfr/src/state_machine/common_smc.h +++ b/apps/aspeed-pfr/src/state_machine/common_smc.h @@ -4,8 +4,8 @@ * SPDX-License-Identifier: MIT */ -#ifndef COMMON_SMC_H -#define COMMON_SMC_H +#pragma once + /* List of HRoT states */ enum HRoT_state { IDLE, INITIALIZE, I2C, VERIFY, RECOVERY, UPDATE, LOCKDOWN }; @@ -27,4 +27,3 @@ enum _hrot_event { I2C_EVENT }; -#endif // #ifndef COMMON_SMC_H diff --git a/apps/aspeed-pfr/src/state_machine/state_machine.c b/apps/aspeed-pfr/src/state_machine/state_machine.c index 15627ed..094dbc7 100644 --- a/apps/aspeed-pfr/src/state_machine/state_machine.c +++ b/apps/aspeed-pfr/src/state_machine/state_machine.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: MIT */ +#include #include #include @@ -13,6 +14,8 @@ #include "Smbus_mailbox/Smbus_mailbox.h" #include "logging/debug_log.h"// State Machine log saving +LOG_MODULE_REGISTER(state_machine, CONFIG_LOG_DEFAULT_LEVEL); + K_FIFO_DEFINE(evt_q); /* Forward declaration of HRoT state table */ @@ -36,7 +39,6 @@ int StartHrotStateMachine(void) /* Run the state machine */ do { - /* State machine terminates if a non-zero value is returned */ ret = smf_run_state(SMF_CTX(&context)); if (ret) { @@ -54,7 +56,7 @@ int StartHrotStateMachine(void) static void run_idle(void *context) { - // printk("Executing run_idle\r\n"); + LOG_DBG("Executing run_idle\r\n"); if (!k_fifo_is_empty(&evt_q)) { int new_state = 0; @@ -95,13 +97,13 @@ static void run_idle(void *context) /* I2C State Handlers */ static void i2c_entry(void *context) { - // printk("Executing i2c_entry\r\n"); - // printk("Leaving i2c_entry\r\n"); + LOG_DBG("Executing i2c_entry\r\n"); + LOG_DBG("Leaving i2c_entry\r\n"); } static void run_i2c(void *context) { - // printk("Executing run_i2c\r\n"); + LOG_DBG("Executing run_i2c\r\n"); struct hrot_smc_context *sm_context = (struct hrot_smc_context *)context; void *sm_static_data = sm_context->sm_static_data; void *event_ctx = sm_context->event_ctx; @@ -110,15 +112,13 @@ static void run_i2c(void *context) // Event process_i2c_command(sm_static_data, event_ctx); // PchBmcCommands(event_ctx, 0); - - - // printk("Leaving run_i2c\r\n"); + LOG_DBG("Leaving run_i2c\r\n"); } static void i2c_exit(void *context) { - // printk("Executing i2c_exit\r\n"); - // printk("Leaving i2c_exit\r\n"); + LOG_DBG("Executing i2c_exit\r\n"); + LOG_DBG("Leaving i2c_exit\r\n"); } /* verify State Handlers */ @@ -144,10 +144,10 @@ static void run_verify(void *context) debug_log_create_entry(DEBUG_LOG_SEVERITY_INFO, DEBUG_LOG_COMPONENT_VERIFY, VERIFY_LOG_COMPONENT_RUN_START, 0, 0); debug_log_flush();// State Machine log saving to SPI - // printk("Executing run_verify\r\n"); + LOG_DBG("Executing run_verify\r\n"); status = handleImageVerification(sm_static_data, event_ctx); - // printk("Leaving run_verify\r\n"); + LOG_DBG("Leaving run_verify\r\n"); } static void verify_exit(void *context) @@ -155,9 +155,9 @@ static void verify_exit(void *context) struct hrot_smc_context *sm_context = (struct hrot_smc_context *)context; void *sm_static_data = sm_context->sm_static_data; - // printk("Executing verify_exit\r\n"); + LOG_DBG("Executing verify_exit\r\n"); handleVerifyExitState(sm_static_data); - // printk("Leaving verify_exit\r\n"); + LOG_DBG("Leaving verify_exit\r\n"); } /* recovery State Handlers */ @@ -169,10 +169,10 @@ static void recovery_entry(void *context) debug_log_create_entry(DEBUG_LOG_SEVERITY_INFO, DEBUG_LOG_COMPONENT_RECOVERY, RECOVERY_LOG_COMPONENT_ENTRY_START, 0, 0); debug_log_flush();// State Machine log saving to SPI - // printk("Executing recovery_entry\r\n"); + LOG_DBG("Executing recovery_entry\r\n"); handleRecoveryEntryState(sm_static_data); handleRecoveryInitState(sm_static_data); - // printk("Leaving recovery_entry\r\n"); + LOG_DBG("Leaving recovery_entry\r\n"); } static void run_recovery(void *context) @@ -186,7 +186,7 @@ static void run_recovery(void *context) debug_log_create_entry(DEBUG_LOG_SEVERITY_INFO, DEBUG_LOG_COMPONENT_RECOVERY, RECOVERY_LOG_COMPONENT_RUN_START, 0, 0); debug_log_flush();// State Machine log saving to SPI - // printk("Executing run_recovery\r\n"); + LOG_DBG("Executing run_recovery\r\n"); status = handleRecoveryAction(sm_static_data, event_ctx); AO_DATA *ActiveObjectData = (AO_DATA *)sm_static_data; @@ -206,7 +206,7 @@ static void run_recovery(void *context) handlePostRecoveryFailure(sm_static_data, event_ctx); } - // printk("Leaving run_recovery\r\n"); + LOG_DBG("Leaving run_recovery\r\n"); } static void recovery_exit(void *context) @@ -214,9 +214,9 @@ static void recovery_exit(void *context) struct hrot_smc_context *sm_context = (struct hrot_smc_context *)context; void *sm_static_data = sm_context->sm_static_data; - // printk("Executing recovery_exit\r\n"); + LOG_DBG("Executing recovery_exit\r\n"); handleRecoveryExitState(sm_static_data); - // printk("Leaving recovery_exit\r\n"); + LOG_DBG("Leaving recovery_exit\r\n"); } /* update State Handlers */ @@ -230,10 +230,10 @@ static void update_entry(void *context) debug_log_create_entry(DEBUG_LOG_SEVERITY_INFO, DEBUG_LOG_COMPONENT_UPDATE, UPDATE_LOG_COMPONENT_ENTRY_START, 0, 0); debug_log_flush();// State Machine log saving to SPI - // printk("Executing update_entry\r\n"); + LOG_DBG("Executing update_entry\r\n"); handleUpdateEntryState((int)type, sm_static_data); handleUpdateInitState((int)type, sm_static_data); - // printk("Leaving update_entry\r\n"); + LOG_DBG("Leaving update_entry\r\n"); } static void run_update(void *context) @@ -247,7 +247,7 @@ static void run_update(void *context) debug_log_create_entry(DEBUG_LOG_SEVERITY_INFO, DEBUG_LOG_COMPONENT_UPDATE, UPDATE_LOG_COMPONENT_RUN_START, 0, 0); debug_log_flush();// State Machine log saving to SPI - // printk("Executing run_update\r\n"); + LOG_DBG("Executing run_update\r\n"); status = handleUpdateImageAction(sm_static_data, event_ctx); if (status == Success) { debug_log_create_entry(DEBUG_LOG_SEVERITY_INFO, DEBUG_LOG_COMPONENT_UPDATE, UPDATE_LOG_COMPONENT_UPDATE_SUCCESS, 0, 0); @@ -260,7 +260,7 @@ static void run_update(void *context) handlePostUpdateFailure(sm_static_data); } - // printk("Leaving run_update\r\n"); + LOG_DBG("Leaving run_update\r\n"); } static void update_exit(void *context) @@ -270,9 +270,9 @@ static void update_exit(void *context) void *event_ctx = sm_context->event_ctx; unsigned int type = ((EVENT_CONTEXT *)event_ctx)->image; - // printk("Executing update_exit\r\n"); + LOG_DBG("Executing update_exit\r\n"); handleUpdateExitState((int)type, sm_static_data); - // printk("Leaving update_exit\r\n"); + LOG_DBG("Leaving update_exit\r\n"); } /* Lockdown State Handlers */ @@ -281,9 +281,9 @@ static void run_lockdown(void *context) struct hrot_smc_context *sm_context = (struct hrot_smc_context *)context; void *sm_static_data = sm_context->sm_static_data; - // printk("Executing run_lockdown\r\n"); + LOG_DBG("Executing run_lockdown\r\n"); handleLockDownState(sm_static_data); - // printk("Leaving run_lockdown\r\n"); + LOG_DBG("Leaving run_lockdown\r\n"); } int post_smc_action(int new_state, void *static_data, void *event) diff --git a/apps/aspeed-pfr/src/state_machine/state_machine.h b/apps/aspeed-pfr/src/state_machine/state_machine.h index 19b9b04..06c4eb9 100644 --- a/apps/aspeed-pfr/src/state_machine/state_machine.h +++ b/apps/aspeed-pfr/src/state_machine/state_machine.h @@ -4,8 +4,7 @@ * SPDX-License-Identifier: MIT */ -#ifndef ZEPHYR_STATE_MACHINE_H -#define ZEPHYR_STATE_MACHINE_H +#pragma once #include #include "common_smc.h" @@ -29,4 +28,3 @@ int post_smc_action(int new_state, void *static_data, void *event); int execute_next_smc_action(int new_state, void *static_data, void *event_ctx); void PublishInitialEvents(void); -#endif // #ifndef ZEPHYR_STATE_MACHINE_H diff --git a/apps/aspeed-pfr/tools/README.md b/apps/aspeed-pfr/tools/README.md new file mode 100644 index 0000000..f0797dd --- /dev/null +++ b/apps/aspeed-pfr/tools/README.md @@ -0,0 +1,149 @@ +# Required Packages +- [intel-pfr-signing-utility](https://github.com/Intel-BMC/intel-pfr-signing-utility) + +It is required to use this tool to sign unsigned capsule. + +# Keys +## secp256r1 (ECDSA 256) +- root private key: `rk_prv.pem` +- root public key: `rk_pub.pem` +- csk private key: `csk_prv.pem` +- csk public key: `csk_pub.pem` + +# XML config file +## rot_update_capsule.xml +- svn: `1` +- pc_type: `0` +- csk_id: `0` + +It is used for ROT update capsule creation. + +## rot_dcc_capsule.xml +- pc_type: `512` +- csk_id: `0` + +It is used for ROT decommission capsule creation. + +## kcc_capsule.xml +- without `cskey` element in `block1` +- `pc_type`: `0` key cancellation for ROT update capsule + +``` +0 ROT Update Capsule (0x100 + 0 = 0x100) +1 PCH PFM (0x100 + 1 = 0x101) +2 PCH Update Capsule (0x100 + 2 = 0x102) +3 BMC PFM (0x100 + 3 = 0x103) +4 BMC Update Capsule (0x100 + 4 = 0x104) +``` + +According to the Intel PFR spec, pc_type should be 0x100 to 0x104. However, if `cskkey` element does not exist in XML config file, the `intel-pfr-signing-utility` sign tool will automatically add `0x100`. Therefore, the sign tool will add `0x100` in signature if `pc_tpye` is `0` in XML configure file. + +It is used for key cancellation capsule creation. + +# Create ROT update capsule +This python script, `rot_update_capsule.py`, creates ROT unsigned capsule and sign it with XML configure file. + +## Usage +python3 rot_update_capsule.py -h + +``` +usage: rot_update_capsule.py [-h] [-t [input sign tool]] [-c [input xml]] + [-i [input image]] [-o [output image]] + +sign ROT update capsule + +optional arguments: + -h, --help show this help message and exit + -t [input sign tool], --input_sign_tool [input sign tool] + sign tool + -c [input xml], --input_xml [input xml] + xml configure file, default is rot_update_capsule.xml + -i [input image], --input_img [input image] + raw image to be signed + -o [output image], --out_img [output image] + output image, default is rot_update_capsule_signed.bin +``` + +## Run +- raw image: `zephyr.bin` +- pfr sign tool: `intel-pfr-signing-utility` +- XML config file: `rot_update_capsule.xml` + +The following example places above files in this directory. + +``` +python3 ./rot_update_capsule.py -t ./intel-pfr-signing-utility -i ./zephyr.bin +``` + +The ROT update capsule will be created in `update-output/rot_update_capsule_signed.bin` + +# Create ROT decommission capsule +This python script, `rot_dcc_capsule.py`, creates ROT unsigned payload and sign it with XML configure file. The payload consists of 128 bytes of 0s. + +## Usage +python3 rot_dcc_capsule.py -h + +``` +usage: rot_dcc_capsule.py [-h] [-t [input sign tool]] [-c [input xml]] + [-o [output image]] + +create ROT dcc capsule + +optional arguments: + -h, --help show this help message and exit + -t [input sign tool], --input_sign_tool [input sign tool] + sign tool + -c [input xml], --input_xml [input xml] + xml configure file, default is rot_dcc_capsule.xml + -o [output image], --out_img [output image] + output image, default is rot_dcc_capsule_signed.bin +``` + +## Run +- pfr sign tool: `intel-pfr-signing-utility` +- XML config file: `rot_dcc_capsule.xml` + +The following example places above files in this directory. + +``` +python3 ./rot_dcc_capsule.py -t ./intel-pfr-signing-utility +``` + +The ROT decommission capsule will be created in `dss-output/rot_dcc_capsule_signed.bin` + +# Create key cancellation capsule +This python script, `kcc_capsule.py`, creates unsigned payload and sign it with XML configure file. The payload consists of key cancellation ID(4 bytes) and 124 bytes of 0s. + +## Usage +python3 kcc_capsule.py -h + +``` +usage: kcc_capsule.py [-h] -t [input sign tool] [-c [input xml]] + [-o [output image]] [-k [csk id]] + +create kcc capsule + +optional arguments: + -h, --help show this help message and exit + -t [input sign tool], --input_sign_tool [input sign tool] + sign tool + -c [input xml], --input_xml [input xml] + xml configure file, default is kcc_capsule.xml + -o [output image], --out_img [output image] + output image, default is kcc_csk(id)_cap_signed.bin + -k [csk id], --csk_id [csk id] + key cancellation CSK id (0-127), default is 0 +``` + +## Run +- pfr sign tool: `intel-pfr-signing-utility` +- XML config file: `kcc_capsule.xml` +- Key cancellation Id: `0` + +The following example places above files in this directory. + +``` +python3 ./kcc_capsule.py -t ./intel-pfr-signing-utility -k 0 +``` + +The key cancellation capsule will be created in `kcc-output/kcc_csk1_cap_signed.bin` for CSK ID `1`. diff --git a/apps/aspeed-pfr/tools/csk_prv.pem b/apps/aspeed-pfr/tools/csk_prv.pem new file mode 100644 index 0000000..a46fa2a --- /dev/null +++ b/apps/aspeed-pfr/tools/csk_prv.pem @@ -0,0 +1,8 @@ +-----BEGIN EC PARAMETERS----- +BggqhkjOPQMBBw== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIFjPqxcb6tfFWyFVaQCVjeN9MtcISpYIbNlkQoODrHTUoAoGCCqGSM49 +AwEHoUQDQgAERGJveRnhIp7I5cvmjO74MJLbUJjTfvTDKlzK0hJB0WRBEFScpb9d +xWLrwj9TNcO+EexnNcjEkF1RYNs6lHavRQ== +-----END EC PRIVATE KEY----- diff --git a/apps/aspeed-pfr/tools/csk_pub.pem b/apps/aspeed-pfr/tools/csk_pub.pem new file mode 100644 index 0000000..cc70d6e --- /dev/null +++ b/apps/aspeed-pfr/tools/csk_pub.pem @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAERGJveRnhIp7I5cvmjO74MJLbUJjT +fvTDKlzK0hJB0WRBEFScpb9dxWLrwj9TNcO+EexnNcjEkF1RYNs6lHavRQ== +-----END PUBLIC KEY----- diff --git a/apps/aspeed-pfr/tools/kcc_capsule.py b/apps/aspeed-pfr/tools/kcc_capsule.py new file mode 100644 index 0000000..46cde98 --- /dev/null +++ b/apps/aspeed-pfr/tools/kcc_capsule.py @@ -0,0 +1,98 @@ +#!/usr/bin/python3 +# script to create key cancellation capsule + +import sys +import os +import argparse +import logging +import subprocess +import shutil +import pathlib +import struct + +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + + +def main(args): + """ main program + :param -t input_sign_tool + :param -c xml configure file, default is kcc_capsule.xml + :param -o output image, default is kcc_csk(id)_cap_signed.bin + """ + parser = argparse.ArgumentParser(description='create kcc capsule') + parser.add_argument('-t', + '--input_sign_tool', + required=True, + metavar="[input sign tool]", + dest='input_sign_tool', + default=None, + help='sign tool') + parser.add_argument('-c', + '--input_xml', + metavar="[input xml]", + dest='input_xml', + default='kcc_capsule.xml', + help='xml configure file,\ + default is kcc_capsule.xml') + parser.add_argument('-o', + '--out_img', + metavar="[output image]", + dest='out_img', + default=None, + help='output image,\ + default is kcc_csk(id)_cap_signed.bin') + parser.add_argument('-k', + '--csk_id', + metavar="[csk id]", + dest='csk_id', + default='0', + type=int, + choices=range(0, 128), + help='key cancellation CSK id (0-127),\ + default is 0') + args = parser.parse_args(args) + logger.info(args) + + logger.info("create key cancellation payload") + payload = 'kcc_csk{}_payload.bin'.format(args.csk_id) + outimg = args.out_img + + if outimg is None: + outimg = 'kcc_csk{}_cap_signed.bin'.format(args.csk_id) + + with open(payload, 'wb') as fd: + fd.write(struct.pack('I', args.csk_id)) + fd.write(b'\x00'*124) + + logger.info("sign %s", payload) + cmd = "{} -c {} -o {} {}".format(args.input_sign_tool, + args.input_xml, + outimg, + payload) + logger.info("issue: %s", cmd) + p = subprocess.Popen(cmd, + shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + out, err = p.communicate() + + if (p.returncode): + logger.error(err) + logger.error("create key cancellation capsule failed") + exit(1) + + work_path = pathlib.Path(__file__).parent.absolute() + output_path = os.path.join(work_path, 'kcc-output') + logger.info('work_path: %s', work_path) + if os.path.exists(output_path): + shutil.rmtree(output_path) + pathlib.Path(output_path).mkdir(parents=True, exist_ok=True) + shutil.move(outimg, output_path) + shutil.move(payload, output_path) + shutil.move(payload + "_aligned", output_path) + logger.info('key cancellation capsule in: %s', output_path) + + +if __name__ == '__main__': + main(sys.argv[1:]) diff --git a/apps/aspeed-pfr/tools/kcc_capsule.xml b/apps/aspeed-pfr/tools/kcc_capsule.xml new file mode 100644 index 0000000..f5265a4 --- /dev/null +++ b/apps/aspeed-pfr/tools/kcc_capsule.xml @@ -0,0 +1,37 @@ + + + + 1 + + 0xB6EAFD19 + + + + + + + 0 + + + 0xF27F28D7 + + 0xA757A046 + 0xC7B88C74 + -1 + -1 + rk_pub.pem + + + 0x15364367 + 0xDE64437D + sha256 + rk_prv.pem + + + + + 1024 + + 128 + + diff --git a/apps/aspeed-pfr/tools/rk_prv.pem b/apps/aspeed-pfr/tools/rk_prv.pem new file mode 100644 index 0000000..9e86167 --- /dev/null +++ b/apps/aspeed-pfr/tools/rk_prv.pem @@ -0,0 +1,8 @@ +-----BEGIN EC PARAMETERS----- +BggqhkjOPQMBBw== +-----END EC PARAMETERS----- +-----BEGIN EC PRIVATE KEY----- +MHcCAQEEIHVbq5CmT4Vr4Jb0eJK0+KhUxDOWy1kh9QYAClV5MH1GoAoGCCqGSM49 +AwEHoUQDQgAEZUL6ZcF0YN590Pq/bKPYjfa3F4E44XiKcqvS6+l2GfSdCLRhXWHw +iV803vFkTsZ1CfpzFdZGwfbwg7nvG5UpSQ== +-----END EC PRIVATE KEY----- diff --git a/apps/aspeed-pfr/tools/rk_pub.pem b/apps/aspeed-pfr/tools/rk_pub.pem new file mode 100644 index 0000000..117e08b --- /dev/null +++ b/apps/aspeed-pfr/tools/rk_pub.pem @@ -0,0 +1,4 @@ +-----BEGIN PUBLIC KEY----- +MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEZUL6ZcF0YN590Pq/bKPYjfa3F4E4 +4XiKcqvS6+l2GfSdCLRhXWHwiV803vFkTsZ1CfpzFdZGwfbwg7nvG5UpSQ== +-----END PUBLIC KEY----- diff --git a/apps/aspeed-pfr/tools/rot_dcc_capsule.py b/apps/aspeed-pfr/tools/rot_dcc_capsule.py new file mode 100644 index 0000000..3d6e85a --- /dev/null +++ b/apps/aspeed-pfr/tools/rot_dcc_capsule.py @@ -0,0 +1,83 @@ +#!/usr/bin/python3 +# script to create ROT Decommission Capsule + +import sys +import os +import argparse +import logging +import subprocess +import shutil +import pathlib + +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + + +def main(args): + """ main program + :param -t input_sign_tool + :param -c xml configure file, default is rot_dcc_capsule.xml + :param -o output image, default is rot_dcc_capsule_signed.bin + """ + parser = argparse.ArgumentParser(description='create ROT dcc capsule') + parser.add_argument('-t', + '--input_sign_tool', + required=True, + metavar="[input sign tool]", + dest='input_sign_tool', + default=None, + help='sign tool') + parser.add_argument('-c', + '--input_xml', + metavar="[input xml]", + dest='input_xml', + default='rot_dcc_capsule.xml', + help='xml configure file,\ + default is rot_dcc_capsule.xml') + parser.add_argument('-o', + '--out_img', + metavar="[output image]", + dest='out_img', + default='rot_dcc_capsule_signed.bin', + help='output image,\ + default is rot_dcc_capsule_signed.bin') + args = parser.parse_args(args) + logger.info(args) + + logger.info("create decommission payload") + payload = 'dcc_payload.bin' + + with open(payload, 'wb') as fd: + fd.write(b'\x00'*128) + + logger.info("sign decommission payload") + cmd = "{} -c {} -o {} {}".format(args.input_sign_tool, + args.input_xml, + args.out_img, + payload) + logger.info("issue: %s", cmd) + p = subprocess.Popen(cmd, + shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + out, err = p.communicate() + + if (p.returncode): + logger.error(err) + logger.error("create ROT decommission capsule failed") + exit(1) + + work_path = pathlib.Path(__file__).parent.absolute() + output_path = os.path.join(work_path, 'dss-output') + logger.info('work_path: %s', work_path) + if os.path.exists(output_path): + shutil.rmtree(output_path) + pathlib.Path(output_path).mkdir(parents=True, exist_ok=True) + shutil.move(args.out_img, output_path) + shutil.move(payload, output_path) + shutil.move(payload + "_aligned", output_path) + logger.info('ROT decommission capsule in: %s', output_path) + + +if __name__ == '__main__': + main(sys.argv[1:]) diff --git a/apps/aspeed-pfr/tools/rot_dcc_capsule.xml b/apps/aspeed-pfr/tools/rot_dcc_capsule.xml new file mode 100644 index 0000000..e9311d6 --- /dev/null +++ b/apps/aspeed-pfr/tools/rot_dcc_capsule.xml @@ -0,0 +1,41 @@ + + + + 1 + + 0xB6EAFD19 + 512 + + + 0xF27F28D7 + + 0xA757A046 + 0xC7B88C74 + -1 + -1 + rk_pub.pem + + + 0x14711C2F + 0xC7B88C74 + 16 + 0 + csk_pub.pem + 0xDE64437D + sha256 + rk_prv.pem + + + 0x15364367 + 0xDE64437D + sha256 + csk_prv.pem + + + + + 1024 + + 128 + + diff --git a/apps/aspeed-pfr/tools/rot_update_capsule.py b/apps/aspeed-pfr/tools/rot_update_capsule.py new file mode 100644 index 0000000..af38418 --- /dev/null +++ b/apps/aspeed-pfr/tools/rot_update_capsule.py @@ -0,0 +1,85 @@ +#!/usr/bin/python3 +# python script to update ROT unsigned capsule +# and sign it with XML configure file + +import sys +import os +import argparse +import logging +import subprocess +import shutil +import pathlib + +logger = logging.getLogger(__name__) +logging.basicConfig(level=logging.INFO) + + +def main(args): + """ main program + :param -t input sign tool + :param -c input xml configure file, default is rot_update_capsule.xml + :param -i input image + :param -o output image, default is rot_update_capsule_signed.bin + """ + parser = argparse.ArgumentParser(description='sign ROT update capsule') + parser.add_argument('-t', + '--input_sign_tool', + required=True, + metavar="[input sign tool]", + dest='input_sign_tool', + default=None, + help='sign tool') + parser.add_argument('-c', + '--input_xml', + metavar="[input xml]", + dest='input_xml', + default='rot_update_capsule.xml', + help='xml configure file,\ + default is rot_update_capsule.xml') + parser.add_argument('-i', + '--input_img', + required=True, + metavar="[input image]", + dest='input_img', + default=None, + help='raw image to be signed') + parser.add_argument('-o', + '--out_img', + metavar="[output image]", + dest='out_img', + default='rot_update_capsule_signed.bin', + help='output image,\ + default is rot_update_capsule_signed.bin') + args = parser.parse_args(args) + logger.info(args) + + logger.info("sign ROT update capsule") + cmd = "{} -c {} -o {} {}".format(args.input_sign_tool, + args.input_xml, + args.out_img, + args.input_img) + logger.info("issue: %s", cmd) + p = subprocess.Popen(cmd, + shell=True, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + out, err = p.communicate() + + if (p.returncode): + logger.error(err) + logger.error("create ROT update capsule failed") + exit(1) + + work_path = pathlib.Path(__file__).parent.absolute() + output_path = os.path.join(work_path, 'update-output') + logger.info('work_path: %s', work_path) + if os.path.exists(output_path): + shutil.rmtree(output_path) + pathlib.Path(output_path).mkdir(parents=True, exist_ok=True) + shutil.move(args.out_img, output_path) + shutil.move(args.input_img + "_aligned", output_path) + logger.info('ROT update capsule in: %s', output_path) + + +if __name__ == '__main__': + main(sys.argv[1:]) diff --git a/apps/aspeed-pfr/tools/rot_update_capsule.xml b/apps/aspeed-pfr/tools/rot_update_capsule.xml new file mode 100644 index 0000000..c7d6428 --- /dev/null +++ b/apps/aspeed-pfr/tools/rot_update_capsule.xml @@ -0,0 +1,50 @@ + + + + 1 + + + 0xB6EAFD19 + 0 + + + + 0xF27F28D7 + + + 0xA757A046 + 0xC7B88C74 + -1 + -1 + rk_pub.pem + + + + 0x14711C2F + 0xC7B88C74 + 16 + 0 + csk_pub.pem + 0xDE64437D + sha256 + rk_prv.pem + + + + 0x15364367 + 0xDE64437D + sha256 + csk_prv.pem + + + + + 1 + + + + 1024 + + 128 + + diff --git a/boards/arm/ast1060_dcscm/CMakeLists.txt b/boards/arm/ast1060_dcscm/CMakeLists.txt new file mode 100644 index 0000000..fcc0e1e --- /dev/null +++ b/boards/arm/ast1060_dcscm/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) 2021 Aspeed +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_PINMUX_ASPEED) + zephyr_include_directories(.) +endif() diff --git a/boards/arm/ast1060_dcscm/Kconfig.board b/boards/arm/ast1060_dcscm/Kconfig.board new file mode 100644 index 0000000..3f30f5c --- /dev/null +++ b/boards/arm/ast1060_dcscm/Kconfig.board @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Aspeed BIC AST1060 board configuration +# +# Copyright (c) 2021 ASPEED Technology Inc. + +config BOARD_AST1060_DCSCM + bool "ASPEED AST1060 DCSCM Evaluation Board" + depends on SOC_AST1060 + diff --git a/boards/arm/ast1060_dcscm/Kconfig.defconfig b/boards/arm/ast1060_dcscm/Kconfig.defconfig new file mode 100644 index 0000000..67fb3ea --- /dev/null +++ b/boards/arm/ast1060_dcscm/Kconfig.defconfig @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Aspeed BIC AST1060 board configuration +# +# Copyright (c) 2021 ASPEED Technology Inc. + +if BOARD_AST1060_DCSCM +config BOARD + default "ast1060_dcscm" +endif # BOARD_AST1060_DCSCM + diff --git a/boards/arm/ast1060_dcscm/ast1060_dcscm.dts b/boards/arm/ast1060_dcscm/ast1060_dcscm.dts new file mode 100644 index 0000000..6bb9ebe --- /dev/null +++ b/boards/arm/ast1060_dcscm/ast1060_dcscm.dts @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 ASPEED Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include + +/ { + model = "Aspeed AST1060 DCSCM Evaluation board"; + compatible = "aspeed,bic-ast1030", "aspeed,ast1030"; + + chosen { + zephyr,console = &uart5; + zephyr,shell-uart = &uart5; + zephyr,sram = &sram0; + }; +}; + +&sram0 { + reg = <0 DT_SIZE_K(640)>, <0xa0000 DT_SIZE_K(128)>; +}; + +&uart5 { + clock-frequency = <1846153>; + current-speed = <115200>; + status = "okay"; +}; + diff --git a/boards/arm/ast1060_dcscm/ast1060_dcscm.yaml b/boards/arm/ast1060_dcscm/ast1060_dcscm.yaml new file mode 100644 index 0000000..529d98b --- /dev/null +++ b/boards/arm/ast1060_dcscm/ast1060_dcscm.yaml @@ -0,0 +1,13 @@ +identifier: ast1060_dcscm +name: AST1060-DCSCM +type: mcu +arch: arm +toolchain: + - zephyr +supported: + - i2c + - spi +testing: + default: true +ram: 768 +flash: 512 diff --git a/boards/arm/ast1060_dcscm/ast1060_dcscm_defconfig b/boards/arm/ast1060_dcscm/ast1060_dcscm_defconfig new file mode 100644 index 0000000..9451659 --- /dev/null +++ b/boards/arm/ast1060_dcscm/ast1060_dcscm_defconfig @@ -0,0 +1,30 @@ +CONFIG_SOC_SERIES_AST10X0=y +CONFIG_SOC_AST1060=y +CONFIG_BOARD_AST1060_DCSCM=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=200000000 +CONFIG_CACHE_ASPEED=y +CONFIG_MAIN_STACK_SIZE=4096 +CONFIG_BOOTLOADER_SRAM_SIZE=0 +CONFIG_FLASH_SIZE=0 +CONFIG_FLASH_BASE_ADDRESS=0x0 +CONFIG_XIP=n +CONFIG_CLOCK_CONTROL=y +CONFIG_CLOCK_CONTROL_AST10X0=y +CONFIG_RESET_CONTROL=y +CONFIG_RESET_CONTROL_ASPEED=y +CONFIG_PINMUX=y +CONFIG_PINMUX_ASPEED=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_NS16550=y +CONFIG_HEAP_MEM_POOL_SIZE=50000 +CONFIG_ASSERT=y +# For CMSIS +CONFIG_POLL=y +CONFIG_THREAD_NAME=y +CONFIG_THREAD_STACK_INFO=y +CONFIG_THREAD_MONITOR=y +CONFIG_INIT_STACKS=y +CONFIG_NUM_PREEMPT_PRIORITIES=56 +CONFIG_CMSIS_RTOS_V2=y diff --git a/boards/arm/ast1060_dcscm/board.cmake b/boards/arm/ast1060_dcscm/board.cmake new file mode 100644 index 0000000..e8ed7ad --- /dev/null +++ b/boards/arm/ast1060_dcscm/board.cmake @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "-f") + +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/ast1060_dcscm/fun_def_list.h b/boards/arm/ast1060_dcscm/fun_def_list.h new file mode 100644 index 0000000..386796d --- /dev/null +++ b/boards/arm/ast1060_dcscm/fun_def_list.h @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2020-2021 Aspeed Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +#ifdef CONFIG_ARM_ICE +FUN_DEFINE(DT_NODELABEL(pinctrl_arm_ice_default), ARM_TRST, ARM_TCK, ARM_TDI, ARM_TDO, ARM_TMS) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc0), okay) && CONFIG_ADC_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_adc0_default), ADC0) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc1_default), ADC1) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc2_default), ADC2) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc3_default), ADC3) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc4_default), ADC4) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc5_default), ADC5) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc6_default), ADC6) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc7_default), ADC7) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc1), okay) && CONFIG_ADC_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_adc8_default), ADC8) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc9_default), ADC9) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc10_default), ADC10) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc11_default), ADC11) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc12_default), ADC12) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc13_default), ADC13) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc14_default), ADC14) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc15_default), ADC15) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm), okay) && CONFIG_PWM_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm0_default), PWM0) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm1_default), PWM1) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm2_default), PWM2) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm3_default), PWM3) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm4_default), PWM4) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm5_default), PWM5) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm6_default), PWM6) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm7_default), PWM7) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm8_default), PWM8) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm9_default), PWM9) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm10_default), PWM10) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm11_default), PWM11) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm12_default), PWM12) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm13_default), PWM13) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm14_default), PWM14) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm15_default), PWM15) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(sgpiom), okay) && CONFIG_GPIO_ASPEED_SGPIOM +FUN_DEFINE(DT_NODELABEL(pinctrl_sgpiom_default), SGPMCLK, SGPMLD, SGPMO, SGPMI) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(tach), okay) && CONFIG_TACH_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_tach0_default), TACH0) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach1_default), TACH1) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach2_default), TACH2) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach3_default), TACH3) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach4_default), TACH4) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach5_default), TACH5) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach6_default), TACH6) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach7_default), TACH7) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach8_default), TACH8) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach9_default), TACH9) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach10_default), TACH10) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach11_default), TACH11) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach12_default), TACH12) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach13_default), TACH13) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach14_default), TACH14) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach15_default), TACH15) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(jtag0), okay) && CONFIG_JTAG_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_jtagm0_default), MTRSTN1, MTDI1, MTCK1, MTMS1, MTDO1) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(jtag1), okay) && CONFIG_JTAG_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_jtagm1_default), MTRSTN2, MTDI2, MTCK2, MTMS2, MTDO2) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2cfilter), okay) && CONFIG_I2C_PFR_FILTER +FUN_DEFINE(DT_NODELABEL(pinctrl_smbflt_default), SMBF1SCLIN, SMBF1SDAIN, SMBF1SCLOUT, SMBF1SDAOUT, +SMBF2SCLIN, SMBF2SDAIN, SMBF2SCLOUT, SMBF2SDAOUT, SMBF3SCLIN, SMBF3SDAIN, SMBF3SCLOUT, SMBF3SDAOUT, +SMBF4SCLIN, SMBF4SDAIN, SMBF4SCLOUT, SMBF4SDAOUT) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c0), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c0_default), SCL1, SDA1) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c1_default), SCL2, SDA2) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c2_default), SCL3, SDA3) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c3), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c3_default), SCL4, SDA4) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c4), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c4_default), SCL5, SDA5) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c5), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c5_default), SCL6, SDA6) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c6), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c6_default), SCL7, SDA7) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c7), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c7_default), SCL8, SDA8) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c8), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c8_default), SCL9, SDA9) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c9), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c9_default), SCL10, SDA10) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c10), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c10_default), SCL11, SDA11) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c11), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c11_default), SCL12, SDA12) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c12), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c12_default), SCL13, SDA13) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c13), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c13_default), SCL14, SDA14) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart1), okay) && (CONFIG_UART_ASPEED || CONFIG_UART_NS16550) +FUN_DEFINE(DT_NODELABEL(pinctrl_uart1_default), TXD1, RXD1) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart2), okay) && (CONFIG_UART_ASPEED || CONFIG_UART_NS16550) +FUN_DEFINE(DT_NODELABEL(pinctrl_uart2_default), TXD2, RXD2) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart3), okay) && (CONFIG_UART_ASPEED || CONFIG_UART_NS16550) +FUN_DEFINE(DT_NODELABEL(pinctrl_uart3_default), TXD3, RXD3) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart4), okay) && (CONFIG_UART_ASPEED || CONFIG_UART_NS16550) +FUN_DEFINE(DT_NODELABEL(pinctrl_uart4_default), TXD4, RXD4) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart6), okay) && (CONFIG_UART_ASPEED || CONFIG_UART_NS16550) +FUN_DEFINE(DT_NODELABEL(pinctrl_uart6_default), TXD6, RXD6) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart7), okay) && (CONFIG_UART_ASPEED || CONFIG_UART_NS16550) +FUN_DEFINE(DT_NODELABEL(pinctrl_uart7_default), TXD7, RXD7) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart8), okay) && (CONFIG_UART_ASPEED || CONFIG_UART_NS16550) +FUN_DEFINE(DT_NODELABEL(pinctrl_uart8_default), TXD8, RXD8) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart9), okay) && (CONFIG_UART_ASPEED || CONFIG_UART_NS16550) +FUN_DEFINE(DT_NODELABEL(pinctrl_uart9_default), TXD9, RXD9) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart10), okay) && (CONFIG_UART_ASPEED || CONFIG_UART_NS16550) +FUN_DEFINE(DT_NODELABEL(pinctrl_uart10_default), TXD10, RXD10) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart11), okay) && (CONFIG_UART_ASPEED || CONFIG_UART_NS16550) +FUN_DEFINE(DT_NODELABEL(pinctrl_uart11_default), TXD11, RXD11) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart12), okay) && (CONFIG_UART_ASPEED || CONFIG_UART_NS16550) +FUN_DEFINE(DT_NODELABEL(pinctrl_uart12_default), TXD12, RXD12) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart13), okay) && (CONFIG_UART_ASPEED || CONFIG_UART_NS16550) +FUN_DEFINE(DT_NODELABEL(pinctrl_uart13_default), TXD13, RXD13) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart14), okay) && (CONFIG_UART_ASPEED || CONFIG_UART_NS16550) +FUN_DEFINE(DT_NODELABEL(pinctrl_uart14_default), TXD14, RXD14) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i3c0), okay) && CONFIG_I3C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i3c0_default), I3C1SCL, I3C1SDA) +FUN_DEFINE(DT_NODELABEL(pinctrl_hvi3c0_default), HVI3C1SCL, HVI3C1SDA) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i3c1), okay) && CONFIG_I3C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i3c1_default), I3C2SCL, I3C2SDA) +FUN_DEFINE(DT_NODELABEL(pinctrl_hvi3c1_default), HVI3C2SCL, HVI3C2SDA) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i3c2), okay) && CONFIG_I3C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i3c2_default), I3C3SCL, I3C3SDA) +FUN_DEFINE(DT_NODELABEL(pinctrl_hvi3c2_default), HVI3C3SCL, HVI3C3SDA) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i3c3), okay) && CONFIG_I3C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i3c3_default), I3C4SCL, I3C4SDA) +FUN_DEFINE(DT_NODELABEL(pinctrl_hvi3c3_default), HVI3C4SCL, HVI3C4SDA) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(fmc), okay) && CONFIG_SPI_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_fmc_quad), FWSPIDQ2, FWSPIDQ3) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_spi1_quad), SPI1DQ2, SPI1DQ3) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_spi2_default), SPI2CS0, SPI2CK, SPI2DQ0, SPI2DQ1) +FUN_DEFINE(DT_NODELABEL(pinctrl_spi2_cs1), SPI2CS1) +FUN_DEFINE(DT_NODELABEL(pinctrl_spi2_quad), SPI2DQ2, SPI2DQ3) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(spim1), okay) && CONFIG_SPI_MONITOR_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_spim1_cs), SPIM1CSIN, SPIM1CSOUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim1_in_default), SPIM1CLKIN, SPIM1MOSIIN, SPIM1MISOIN) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim1_out_default), SPIM1CLKOUT, SPIM1MOSIOUT, SPIM1MISOOUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim1_qspi_in_default), SPIM1IO2IN, SPIM1IO3IN) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim1_qspi_out_default), SPIM1IO2OUT, SPIM1IO3OUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim1_rst_in), SPIM1SPIRSTIN) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim1_rst_out), SPIM1SPIRSTOUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim1_muxsel), SPIM1MUXSEL) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(spim2), okay) && CONFIG_SPI_MONITOR_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_spim2_cs), SPIM2CSIN, SPIM2CSOUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim2_in_default), SPIM2CLKIN, SPIM2MOSIIN, SPIM2MISOIN) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim2_out_default), SPIM2CLKOUT, SPIM2MOSIOUT, SPIM2MISOOUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim2_qspi_in_default), SPIM2IO2IN, SPIM2IO3IN) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim2_qspi_out_default), SPIM2IO2OUT, SPIM2IO3OUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim2_rst_in), SPIM2SPIRSTIN) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim2_rst_out), SPIM2SPIRSTOUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim2_muxsel), SPIM2MUXSEL) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(spim3), okay) && CONFIG_SPI_MONITOR_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_spim3_cs), SPIM3CSIN, SPIM3CSOUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim3_in_default), SPIM3CLKIN, SPIM3MOSIIN, SPIM3MISOIN) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim3_out_default), SPIM3CLKOUT, SPIM3MOSIOUT, SPIM3MISOOUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim3_qspi_in_default), SPIM3IO2IN, SPIM3IO3IN) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim3_qspi_out_default), SPIM3IO2OUT, SPIM3IO3OUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim3_rst_in), SPIM3SPIRSTIN) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim3_rst_out), SPIM3SPIRSTOUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim3_muxsel), SPIM3MUXSEL) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(spim4), okay) && CONFIG_SPI_MONITOR_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_spim4_cs), SPIM4CSIN, SPIM4CSOUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim4_in_default), SPIM4CLKIN, SPIM4MOSIIN, SPIM4MISOIN) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim4_out_default), SPIM4CLKOUT, SPIM4MOSIOUT, SPIM4MISOOUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim4_qspi_in_default), SPIM4IO2IN, SPIM4IO3IN) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim4_qspi_out_default), SPIM4IO2OUT, SPIM4IO3OUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim4_rst_in), SPIM4SPIRSTIN) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim4_rst_out), SPIM4SPIRSTOUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim4_muxsel), SPIM4MUXSEL) +#endif + diff --git a/boards/arm/ast1060_dcscm/fun_id.h b/boards/arm/ast1060_dcscm/fun_id.h new file mode 100644 index 0000000..1a98fbe --- /dev/null +++ b/boards/arm/ast1060_dcscm/fun_id.h @@ -0,0 +1,13 @@ +#ifndef __FUN_ID_H__ +#define __FUN_ID_H__ + +/* Function ID */ +enum aspeed_fun_id_e { + FUN_NONE = -1, +#define FUN_DEFINE(fun, ...) fun, + #include "fun_def_list.h" +#undef FUN_DEFINE + MAX_FUN_ID, +}; + +#endif /* #ifndef __FUN_ID_H__ */ diff --git a/boards/arm/ast1060_dual_flash/CMakeLists.txt b/boards/arm/ast1060_dual_flash/CMakeLists.txt new file mode 100644 index 0000000..fcc0e1e --- /dev/null +++ b/boards/arm/ast1060_dual_flash/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) 2021 Aspeed +# SPDX-License-Identifier: Apache-2.0 + +if(CONFIG_PINMUX_ASPEED) + zephyr_include_directories(.) +endif() diff --git a/boards/arm/ast1060_dual_flash/Kconfig.board b/boards/arm/ast1060_dual_flash/Kconfig.board new file mode 100644 index 0000000..ed13212 --- /dev/null +++ b/boards/arm/ast1060_dual_flash/Kconfig.board @@ -0,0 +1,10 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Aspeed BIC AST1060 board configuration +# +# Copyright (c) 2021 ASPEED Technology Inc. + +config BOARD_AST1060_DUAL_FLASH + bool "ASPEED AST1060 Dual Flash Platform" + depends on SOC_AST1060 + diff --git a/boards/arm/ast1060_dual_flash/Kconfig.defconfig b/boards/arm/ast1060_dual_flash/Kconfig.defconfig new file mode 100644 index 0000000..de128d4 --- /dev/null +++ b/boards/arm/ast1060_dual_flash/Kconfig.defconfig @@ -0,0 +1,11 @@ +# SPDX-License-Identifier: Apache-2.0 +# +# Aspeed BIC AST1060 board configuration +# +# Copyright (c) 2021 ASPEED Technology Inc. + +if BOARD_AST1060_DUAL_FLASH +config BOARD + default "ast1060_dual_flash" +endif # BOARD_AST1060_DUAL_FLASH + diff --git a/boards/arm/ast1060_dual_flash/ast1060_dual_flash.dts b/boards/arm/ast1060_dual_flash/ast1060_dual_flash.dts new file mode 100644 index 0000000..0eb53ba --- /dev/null +++ b/boards/arm/ast1060_dual_flash/ast1060_dual_flash.dts @@ -0,0 +1,30 @@ +/* + * Copyright (c) 2021 ASPEED Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/dts-v1/; +#include + +/ { + model = "Aspeed AST1060 dual flash platform"; + compatible = "aspeed,bic-ast1030", "aspeed,ast1030"; + + chosen { + zephyr,console = &uart5; + zephyr,shell-uart = &uart5; + zephyr,sram = &sram0; + }; +}; + +&sram0 { + reg = <0 DT_SIZE_K(640)>, <0xa0000 DT_SIZE_K(128)>; +}; + +&uart5 { + clock-frequency = <1846153>; + current-speed = <115200>; + status = "okay"; +}; + diff --git a/boards/arm/ast1060_dual_flash/ast1060_dual_flash.yaml b/boards/arm/ast1060_dual_flash/ast1060_dual_flash.yaml new file mode 100644 index 0000000..b50424c --- /dev/null +++ b/boards/arm/ast1060_dual_flash/ast1060_dual_flash.yaml @@ -0,0 +1,13 @@ +identifier: ast1060_dual_flash +name: AST1060-DUAL-FLASH +type: mcu +arch: arm +toolchain: + - zephyr +supported: + - i2c + - spi +testing: + default: true +ram: 768 +flash: 512 diff --git a/boards/arm/ast1060_dual_flash/ast1060_dual_flash_defconfig b/boards/arm/ast1060_dual_flash/ast1060_dual_flash_defconfig new file mode 100644 index 0000000..b4cd273 --- /dev/null +++ b/boards/arm/ast1060_dual_flash/ast1060_dual_flash_defconfig @@ -0,0 +1,30 @@ +CONFIG_SOC_SERIES_AST10X0=y +CONFIG_SOC_AST1060=y +CONFIG_BOARD_AST1060_DUAL_FLASH=y +CONFIG_SYS_CLOCK_HW_CYCLES_PER_SEC=200000000 +CONFIG_CACHE_ASPEED=y +CONFIG_MAIN_STACK_SIZE=4096 +CONFIG_BOOTLOADER_SRAM_SIZE=0 +CONFIG_FLASH_SIZE=0 +CONFIG_FLASH_BASE_ADDRESS=0x0 +CONFIG_XIP=n +CONFIG_CLOCK_CONTROL=y +CONFIG_CLOCK_CONTROL_AST10X0=y +CONFIG_RESET_CONTROL=y +CONFIG_RESET_CONTROL_ASPEED=y +CONFIG_PINMUX=y +CONFIG_PINMUX_ASPEED=y +CONFIG_CONSOLE=y +CONFIG_UART_CONSOLE=y +CONFIG_SERIAL=y +CONFIG_UART_NS16550=y +CONFIG_HEAP_MEM_POOL_SIZE=50000 +CONFIG_ASSERT=y +# For CMSIS +CONFIG_POLL=y +CONFIG_THREAD_NAME=y +CONFIG_THREAD_STACK_INFO=y +CONFIG_THREAD_MONITOR=y +CONFIG_INIT_STACKS=y +CONFIG_NUM_PREEMPT_PRIORITIES=56 +CONFIG_CMSIS_RTOS_V2=y diff --git a/boards/arm/ast1060_dual_flash/board.cmake b/boards/arm/ast1060_dual_flash/board.cmake new file mode 100644 index 0000000..e8ed7ad --- /dev/null +++ b/boards/arm/ast1060_dual_flash/board.cmake @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: Apache-2.0 + +board_runner_args(jlink "-f") + +include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) diff --git a/boards/arm/ast1060_dual_flash/fun_def_list.h b/boards/arm/ast1060_dual_flash/fun_def_list.h new file mode 100644 index 0000000..386796d --- /dev/null +++ b/boards/arm/ast1060_dual_flash/fun_def_list.h @@ -0,0 +1,275 @@ +/* + * Copyright (c) 2020-2021 Aspeed Technology Inc. + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include + +#ifdef CONFIG_ARM_ICE +FUN_DEFINE(DT_NODELABEL(pinctrl_arm_ice_default), ARM_TRST, ARM_TCK, ARM_TDI, ARM_TDO, ARM_TMS) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc0), okay) && CONFIG_ADC_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_adc0_default), ADC0) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc1_default), ADC1) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc2_default), ADC2) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc3_default), ADC3) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc4_default), ADC4) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc5_default), ADC5) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc6_default), ADC6) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc7_default), ADC7) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(adc1), okay) && CONFIG_ADC_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_adc8_default), ADC8) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc9_default), ADC9) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc10_default), ADC10) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc11_default), ADC11) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc12_default), ADC12) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc13_default), ADC13) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc14_default), ADC14) +FUN_DEFINE(DT_NODELABEL(pinctrl_adc15_default), ADC15) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(pwm), okay) && CONFIG_PWM_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm0_default), PWM0) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm1_default), PWM1) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm2_default), PWM2) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm3_default), PWM3) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm4_default), PWM4) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm5_default), PWM5) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm6_default), PWM6) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm7_default), PWM7) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm8_default), PWM8) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm9_default), PWM9) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm10_default), PWM10) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm11_default), PWM11) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm12_default), PWM12) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm13_default), PWM13) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm14_default), PWM14) +FUN_DEFINE(DT_NODELABEL(pinctrl_pwm15_default), PWM15) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(sgpiom), okay) && CONFIG_GPIO_ASPEED_SGPIOM +FUN_DEFINE(DT_NODELABEL(pinctrl_sgpiom_default), SGPMCLK, SGPMLD, SGPMO, SGPMI) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(tach), okay) && CONFIG_TACH_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_tach0_default), TACH0) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach1_default), TACH1) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach2_default), TACH2) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach3_default), TACH3) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach4_default), TACH4) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach5_default), TACH5) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach6_default), TACH6) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach7_default), TACH7) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach8_default), TACH8) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach9_default), TACH9) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach10_default), TACH10) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach11_default), TACH11) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach12_default), TACH12) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach13_default), TACH13) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach14_default), TACH14) +FUN_DEFINE(DT_NODELABEL(pinctrl_tach15_default), TACH15) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(jtag0), okay) && CONFIG_JTAG_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_jtagm0_default), MTRSTN1, MTDI1, MTCK1, MTMS1, MTDO1) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(jtag1), okay) && CONFIG_JTAG_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_jtagm1_default), MTRSTN2, MTDI2, MTCK2, MTMS2, MTDO2) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2cfilter), okay) && CONFIG_I2C_PFR_FILTER +FUN_DEFINE(DT_NODELABEL(pinctrl_smbflt_default), SMBF1SCLIN, SMBF1SDAIN, SMBF1SCLOUT, SMBF1SDAOUT, +SMBF2SCLIN, SMBF2SDAIN, SMBF2SCLOUT, SMBF2SDAOUT, SMBF3SCLIN, SMBF3SDAIN, SMBF3SCLOUT, SMBF3SDAOUT, +SMBF4SCLIN, SMBF4SDAIN, SMBF4SCLOUT, SMBF4SDAOUT) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c0), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c0_default), SCL1, SDA1) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c1), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c1_default), SCL2, SDA2) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c2), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c2_default), SCL3, SDA3) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c3), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c3_default), SCL4, SDA4) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c4), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c4_default), SCL5, SDA5) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c5), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c5_default), SCL6, SDA6) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c6), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c6_default), SCL7, SDA7) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c7), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c7_default), SCL8, SDA8) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c8), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c8_default), SCL9, SDA9) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c9), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c9_default), SCL10, SDA10) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c10), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c10_default), SCL11, SDA11) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c11), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c11_default), SCL12, SDA12) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c12), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c12_default), SCL13, SDA13) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i2c13), okay) && CONFIG_I2C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i2c13_default), SCL14, SDA14) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart1), okay) && (CONFIG_UART_ASPEED || CONFIG_UART_NS16550) +FUN_DEFINE(DT_NODELABEL(pinctrl_uart1_default), TXD1, RXD1) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart2), okay) && (CONFIG_UART_ASPEED || CONFIG_UART_NS16550) +FUN_DEFINE(DT_NODELABEL(pinctrl_uart2_default), TXD2, RXD2) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart3), okay) && (CONFIG_UART_ASPEED || CONFIG_UART_NS16550) +FUN_DEFINE(DT_NODELABEL(pinctrl_uart3_default), TXD3, RXD3) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart4), okay) && (CONFIG_UART_ASPEED || CONFIG_UART_NS16550) +FUN_DEFINE(DT_NODELABEL(pinctrl_uart4_default), TXD4, RXD4) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart6), okay) && (CONFIG_UART_ASPEED || CONFIG_UART_NS16550) +FUN_DEFINE(DT_NODELABEL(pinctrl_uart6_default), TXD6, RXD6) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart7), okay) && (CONFIG_UART_ASPEED || CONFIG_UART_NS16550) +FUN_DEFINE(DT_NODELABEL(pinctrl_uart7_default), TXD7, RXD7) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart8), okay) && (CONFIG_UART_ASPEED || CONFIG_UART_NS16550) +FUN_DEFINE(DT_NODELABEL(pinctrl_uart8_default), TXD8, RXD8) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart9), okay) && (CONFIG_UART_ASPEED || CONFIG_UART_NS16550) +FUN_DEFINE(DT_NODELABEL(pinctrl_uart9_default), TXD9, RXD9) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart10), okay) && (CONFIG_UART_ASPEED || CONFIG_UART_NS16550) +FUN_DEFINE(DT_NODELABEL(pinctrl_uart10_default), TXD10, RXD10) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart11), okay) && (CONFIG_UART_ASPEED || CONFIG_UART_NS16550) +FUN_DEFINE(DT_NODELABEL(pinctrl_uart11_default), TXD11, RXD11) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart12), okay) && (CONFIG_UART_ASPEED || CONFIG_UART_NS16550) +FUN_DEFINE(DT_NODELABEL(pinctrl_uart12_default), TXD12, RXD12) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart13), okay) && (CONFIG_UART_ASPEED || CONFIG_UART_NS16550) +FUN_DEFINE(DT_NODELABEL(pinctrl_uart13_default), TXD13, RXD13) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(uart14), okay) && (CONFIG_UART_ASPEED || CONFIG_UART_NS16550) +FUN_DEFINE(DT_NODELABEL(pinctrl_uart14_default), TXD14, RXD14) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i3c0), okay) && CONFIG_I3C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i3c0_default), I3C1SCL, I3C1SDA) +FUN_DEFINE(DT_NODELABEL(pinctrl_hvi3c0_default), HVI3C1SCL, HVI3C1SDA) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i3c1), okay) && CONFIG_I3C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i3c1_default), I3C2SCL, I3C2SDA) +FUN_DEFINE(DT_NODELABEL(pinctrl_hvi3c1_default), HVI3C2SCL, HVI3C2SDA) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i3c2), okay) && CONFIG_I3C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i3c2_default), I3C3SCL, I3C3SDA) +FUN_DEFINE(DT_NODELABEL(pinctrl_hvi3c2_default), HVI3C3SCL, HVI3C3SDA) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(i3c3), okay) && CONFIG_I3C_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_i3c3_default), I3C4SCL, I3C4SDA) +FUN_DEFINE(DT_NODELABEL(pinctrl_hvi3c3_default), HVI3C4SCL, HVI3C4SDA) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(fmc), okay) && CONFIG_SPI_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_fmc_quad), FWSPIDQ2, FWSPIDQ3) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi1), okay) && CONFIG_SPI_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_spi1_quad), SPI1DQ2, SPI1DQ3) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(spi2), okay) && CONFIG_SPI_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_spi2_default), SPI2CS0, SPI2CK, SPI2DQ0, SPI2DQ1) +FUN_DEFINE(DT_NODELABEL(pinctrl_spi2_cs1), SPI2CS1) +FUN_DEFINE(DT_NODELABEL(pinctrl_spi2_quad), SPI2DQ2, SPI2DQ3) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(spim1), okay) && CONFIG_SPI_MONITOR_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_spim1_cs), SPIM1CSIN, SPIM1CSOUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim1_in_default), SPIM1CLKIN, SPIM1MOSIIN, SPIM1MISOIN) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim1_out_default), SPIM1CLKOUT, SPIM1MOSIOUT, SPIM1MISOOUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim1_qspi_in_default), SPIM1IO2IN, SPIM1IO3IN) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim1_qspi_out_default), SPIM1IO2OUT, SPIM1IO3OUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim1_rst_in), SPIM1SPIRSTIN) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim1_rst_out), SPIM1SPIRSTOUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim1_muxsel), SPIM1MUXSEL) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(spim2), okay) && CONFIG_SPI_MONITOR_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_spim2_cs), SPIM2CSIN, SPIM2CSOUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim2_in_default), SPIM2CLKIN, SPIM2MOSIIN, SPIM2MISOIN) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim2_out_default), SPIM2CLKOUT, SPIM2MOSIOUT, SPIM2MISOOUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim2_qspi_in_default), SPIM2IO2IN, SPIM2IO3IN) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim2_qspi_out_default), SPIM2IO2OUT, SPIM2IO3OUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim2_rst_in), SPIM2SPIRSTIN) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim2_rst_out), SPIM2SPIRSTOUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim2_muxsel), SPIM2MUXSEL) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(spim3), okay) && CONFIG_SPI_MONITOR_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_spim3_cs), SPIM3CSIN, SPIM3CSOUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim3_in_default), SPIM3CLKIN, SPIM3MOSIIN, SPIM3MISOIN) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim3_out_default), SPIM3CLKOUT, SPIM3MOSIOUT, SPIM3MISOOUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim3_qspi_in_default), SPIM3IO2IN, SPIM3IO3IN) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim3_qspi_out_default), SPIM3IO2OUT, SPIM3IO3OUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim3_rst_in), SPIM3SPIRSTIN) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim3_rst_out), SPIM3SPIRSTOUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim3_muxsel), SPIM3MUXSEL) +#endif + +#if DT_NODE_HAS_STATUS(DT_NODELABEL(spim4), okay) && CONFIG_SPI_MONITOR_ASPEED +FUN_DEFINE(DT_NODELABEL(pinctrl_spim4_cs), SPIM4CSIN, SPIM4CSOUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim4_in_default), SPIM4CLKIN, SPIM4MOSIIN, SPIM4MISOIN) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim4_out_default), SPIM4CLKOUT, SPIM4MOSIOUT, SPIM4MISOOUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim4_qspi_in_default), SPIM4IO2IN, SPIM4IO3IN) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim4_qspi_out_default), SPIM4IO2OUT, SPIM4IO3OUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim4_rst_in), SPIM4SPIRSTIN) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim4_rst_out), SPIM4SPIRSTOUT) +FUN_DEFINE(DT_NODELABEL(pinctrl_spim4_muxsel), SPIM4MUXSEL) +#endif + diff --git a/boards/arm/ast1060_dual_flash/fun_id.h b/boards/arm/ast1060_dual_flash/fun_id.h new file mode 100644 index 0000000..1a98fbe --- /dev/null +++ b/boards/arm/ast1060_dual_flash/fun_id.h @@ -0,0 +1,13 @@ +#ifndef __FUN_ID_H__ +#define __FUN_ID_H__ + +/* Function ID */ +enum aspeed_fun_id_e { + FUN_NONE = -1, +#define FUN_DEFINE(fun, ...) fun, + #include "fun_def_list.h" +#undef FUN_DEFINE + MAX_FUN_ID, +}; + +#endif /* #ifndef __FUN_ID_H__ */ diff --git a/lib/hrot_hal/Kconfig b/lib/hrot_hal/Kconfig index 83b1abe..5b15d45 100644 --- a/lib/hrot_hal/Kconfig +++ b/lib/hrot_hal/Kconfig @@ -4,3 +4,12 @@ config HROT_HAL bool "Hardware root of trust hardware abstraction layer" +config SPI_DMA_SUPPORT_ASPEED + depends on SPI_ASPEED + bool "Enable ASPEED SPI DMA" + default n + help + Enable ASPEED SPI DMA. Notice, both + flash start addrss and ram start address + MUST be 4-byte aligned. + diff --git a/lib/hrot_hal/abr/abr_aspeed.h b/lib/hrot_hal/abr/abr_aspeed.h index 25fd242..f5f646d 100644 --- a/lib/hrot_hal/abr/abr_aspeed.h +++ b/lib/hrot_hal/abr/abr_aspeed.h @@ -4,11 +4,9 @@ * SPDX-License-Identifier: MIT */ -#ifndef ABR_ASPEED_H_ -#define ABR_ASPEED_H_ +#pragma once #define HW_STRAP1_SCU500 0x7e6e2500 #define HW_STRAP2_SCU510 0x7e6e2510 #define ASPEED_FMC_WDT2_CTRL 0x7e620064 -#endif diff --git a/lib/hrot_hal/crypto/ecdsa_aspeed.c b/lib/hrot_hal/crypto/ecdsa_aspeed.c index 90c0fe6..976054e 100644 --- a/lib/hrot_hal/crypto/ecdsa_aspeed.c +++ b/lib/hrot_hal/crypto/ecdsa_aspeed.c @@ -4,44 +4,69 @@ * SPDX-License-Identifier: MIT */ -#ifdef CONFIG_ECDSA_ASPEED - #define ECDSA_DRV_NAME DT_LABEL(DT_INST(0, aspeed_ecdsa)) -#endif - -#include -#include -#include #include #include -#include +#include +LOG_MODULE_REGISTER(ecdsa_middle_aspeed, CONFIG_LOG_DEFAULT_LEVEL); +#ifdef CONFIG_ECDSA_ASPEED +#define ECDSA_DRV_NAME DT_LABEL(DT_INST(0, aspeed_ecdsa)) +#endif + +/** + * This function verifies the expected SHA384 hash and EC signature (for secp384) for a given data. + * + * The function calculate_sha is called initially to obtain the hash output of the data + * and this hash data will be transfered to the ecdsa block to be used for signature + * verification. + * + * @param public_key_x : Q(x) public key + * @param public_key_y : Q(y) public key + * @param digest : hash data + * @param length : digest length + * @param signature_r : signature r + * @param signature_s : signature s + * + * @return 0 if the digest matches the signature or an error code. + * + */ int aspeed_ecdsa_verify_middlelayer(uint8_t *public_key_x, uint8_t *public_key_y, - const uint8_t *digest, uint8_t *signature_r, uint8_t *signature_s) + const uint8_t *digest, size_t length, uint8_t *signature_r, uint8_t *signature_s) { - int status = 0; const struct device *dev = device_get_binding(ECDSA_DRV_NAME); struct ecdsa_ctx ini; struct ecdsa_pkt pkt; struct ecdsa_key ek; + int status = 1; + + if (dev == NULL) { + LOG_ERR("device not found"); + return status; + } + + if (length != 48) { + LOG_ERR("digest length not support, %d", length); + return status; + } - ek.curve_id = ECC_CURVE_NIST_P256; + ek.curve_id = ECC_CURVE_NIST_P384; ek.qx = public_key_x; ek.qy = public_key_y; - pkt.m = digest; + pkt.m = (uint8_t *) digest; pkt.r = signature_r; pkt.s = signature_s; - pkt.m_len = 32; - pkt.r_len = 32; - pkt.s_len = 32; + pkt.m_len = length; + pkt.r_len = length; + pkt.s_len = length; + status = ecdsa_begin_session(dev, &ini, &ek); - if (status) - printk("ecdsa_begin_session fail: %d\r\n", status); + if (status) { + LOG_ERR("begin session failed: %d", status); + return status; + } + status = ecdsa_verify(&ini, &pkt); - if (status) - printk("Fail\r\n"); - else - printk("Success\r\n"); ecdsa_free_session(dev, &ini); - return status; } + diff --git a/lib/hrot_hal/crypto/ecdsa_aspeed.h b/lib/hrot_hal/crypto/ecdsa_aspeed.h index 68cbe32..248a82f 100644 --- a/lib/hrot_hal/crypto/ecdsa_aspeed.h +++ b/lib/hrot_hal/crypto/ecdsa_aspeed.h @@ -4,12 +4,7 @@ * SPDX-License-Identifier: MIT */ -#include -#include -#include -#include -#include -#include +#pragma once int aspeed_ecdsa_verify_middlelayer(uint8_t *public_key_x, uint8_t *public_key_y, - const uint8_t *digest, uint8_t *signature_r, uint8_t *signature_s); + const uint8_t *digest, size_t length, uint8_t *signature_r, uint8_t *signature_s); diff --git a/lib/hrot_hal/crypto/hash_aspeed.h b/lib/hrot_hal/crypto/hash_aspeed.h index 01c25d3..d1c8b51 100644 --- a/lib/hrot_hal/crypto/hash_aspeed.h +++ b/lib/hrot_hal/crypto/hash_aspeed.h @@ -4,8 +4,7 @@ * SPDX-License-Identifier: MIT */ -#ifndef ZEPHYR_INCLUDE_HASH_API_MIDLEYER_H_ -#define ZEPHYR_INCLUDE_HASH_API_MIDLEYER_H_ +#pragma once #include @@ -55,4 +54,3 @@ int hash_engine_update(const uint8_t *data, size_t length); int hash_engine_finish(uint8_t *hash, size_t hash_length); void hash_engine_cancel(void); -#endif /* ZEPHYR_INCLUDE_HASH_API_MIDLEYER_H_ */ diff --git a/lib/hrot_hal/crypto/rsa_aspeed.h b/lib/hrot_hal/crypto/rsa_aspeed.h index 42828e1..0516644 100644 --- a/lib/hrot_hal/crypto/rsa_aspeed.h +++ b/lib/hrot_hal/crypto/rsa_aspeed.h @@ -4,8 +4,7 @@ * SPDX-License-Identifier: MIT */ -#ifndef ZEPHYR_INCLUDE_RSA_API_MIDLEYER_H_ -#define ZEPHYR_INCLUDE_RSA_API_MIDLEYER_H_ +#pragma once #include @@ -24,4 +23,4 @@ void rsa_engine_function_test(void); // rsa functions testing int decrypt_aspeed(const struct rsa_key *key, const uint8_t *encrypted, size_t in_length, uint8_t *decrypted, size_t out_length); int sig_verify_aspeed(const struct rsa_key *key, const uint8_t *signature, int sig_length, const uint8_t *match, size_t match_length); int rsa_sig_verify_test(void); -#endif /* ZEPHYR_INCLUDE_RSA_API_MIDLEYER_H_ */ + diff --git a/lib/hrot_hal/flash/flash_aspeed.c b/lib/hrot_hal/flash/flash_aspeed.c index 82af81a..2ec2952 100644 --- a/lib/hrot_hal/flash/flash_aspeed.c +++ b/lib/hrot_hal/flash/flash_aspeed.c @@ -13,23 +13,26 @@ #include #include #include -//#include -//#include "flash/spi_flash.h" +#include #define LOG_MODULE_NAME spi_api #include -LOG_MODULE_REGISTER(LOG_MODULE_NAME); +LOG_MODULE_REGISTER(LOG_MODULE_NAME, LOG_LEVEL_DBG); static char *Flash_Devices_List[6] = { "spi1_cs0", + "spi1_cs1", "spi2_cs0", "spi2_cs1", - "spi2_cs2", "fmc_cs0", "fmc_cs1" }; +#if defined(CONFIG_SPI_DMA_SUPPORT_ASPEED) +static uint8_t flash_rw_buf[16384] NON_CACHED_BSS_ALIGN16; +#endif + static void Data_dump_buf(uint8_t *buf, uint32_t len) { uint32_t i; @@ -46,22 +49,33 @@ int BMC_PCH_SPI_Command(struct pspi_flash *flash, struct pflash_xfer *xfer) { struct device *flash_device; uint8_t DeviceId = flash->device_id[0]; - int AdrOffset = 0; - int Datalen = 0; + int AdrOffset = xfer->address; + int Datalen = xfer->length; uint32_t FlashSize = 0; int ret = 0; - char buf[4096]; - uint32_t page_sz = 0; - uint32_t sector_sz = 0; + int page_sz = 0; + int sector_sz = 0; flash_device = device_get_binding(Flash_Devices_List[DeviceId]); - AdrOffset = xfer->address; - Datalen = xfer->length; + if (!flash_device) { + + LOG_DBG("%s doesn't exist.\n", Flash_Devices_List[DeviceId]); + return -1; + } + +#if defined(CONFIG_BMC_DUAL_FLASH) + FlashSize = flash_get_flash_size(flash_device); + if (AdrOffset >= FlashSize) { + DeviceId += 1; + AdrOffset -= FlashSize; + flash_device = device_get_binding(Flash_Devices_List[DeviceId]); + } +#endif switch (xfer->cmd) { case SPI_APP_CMD_GET_FLASH_SIZE: - FlashSize = flash_get_flash_size(flash_device); - //printk("FlashSize:%x\n",FlashSize); + if (!FlashSize) + FlashSize = flash_get_flash_size(flash_device); return FlashSize; break; #if 0 @@ -75,27 +89,33 @@ int BMC_PCH_SPI_Command(struct pspi_flash *flash, struct pflash_xfer *xfer) break; #endif case SPI_APP_CMD_GET_FLASH_BLOCK_SIZE: - page_sz = (flash_get_write_block_size(flash_device) << 4); + page_sz = spi_nor_get_erase_sz(flash_device, MIDLEY_FLASH_CMD_BLOCK_ERASE); return page_sz; break; case MIDLEY_FLASH_CMD_READ: - ret = flash_read(flash_device, AdrOffset, buf, Datalen); +#if defined(CONFIG_SPI_DMA_SUPPORT_ASPEED) + ret = flash_read(flash_device, AdrOffset, flash_rw_buf, Datalen); + memcpy(xfer->data, flash_rw_buf, Datalen); +#else + ret = flash_read(flash_device, AdrOffset, xfer->data, Datalen); +#endif //Data_dump_buf(buf,Datalen); - if (xfer->data != NULL) - memcpy(xfer->data, buf, Datalen); break; case MIDLEY_FLASH_CMD_PP://Flash Write - memset(buf, 0xff, Datalen); - memcpy(buf, xfer->data, Datalen); - ret = flash_write(flash_device, AdrOffset, buf, Datalen); +#if defined(CONFIG_SPI_DMA_SUPPORT_ASPEED) + memcpy(flash_rw_buf, xfer->data, Datalen); + ret = flash_write(flash_device, AdrOffset, flash_rw_buf, Datalen); +#else + ret = flash_write(flash_device, AdrOffset, xfer->data, Datalen); +#endif break; case MIDLEY_FLASH_CMD_4K_ERASE: - sector_sz = flash_get_write_block_size(flash_device); - ret = flash_erase(flash_device, AdrOffset, sector_sz); + ret = spi_nor_erase_by_cmd(flash_device, AdrOffset, SECTOR_SIZE, + MIDLEY_FLASH_CMD_4K_ERASE); break; - case MIDLEY_FLASH_CMD_64K_ERASE: - sector_sz = (flash_get_write_block_size(flash_device) << 4); - ret = flash_erase(flash_device, AdrOffset, sector_sz); + case MIDLEY_FLASH_CMD_BLOCK_ERASE: + ret = spi_nor_erase_by_cmd(flash_device, AdrOffset, BLOCK_SIZE, + MIDLEY_FLASH_CMD_BLOCK_ERASE); break; case MIDLEY_FLASH_CMD_CE: FlashSize = flash_get_flash_size(flash_device); @@ -107,7 +127,7 @@ int BMC_PCH_SPI_Command(struct pspi_flash *flash, struct pflash_xfer *xfer) ret = 0; break; default: - printk("%d Command is not supported", xfer->cmd); + LOG_DBG("%d Command is not supported\n", xfer->cmd); break; } @@ -123,7 +143,6 @@ int FMC_SPI_Command(struct pspi_flash *flash, struct pflash_xfer *xfer) uint32_t sector_sz = 0; int AdrOffset = 0; int Datalen = 0; - char buf[4096]; int err, ret = 0; flash_device = device_get_binding(Flash_Devices_List[ROT_SPI]); @@ -154,25 +173,32 @@ int FMC_SPI_Command(struct pspi_flash *flash, struct pflash_xfer *xfer) ret = 0; // bypass as write enabled break; case MIDLEY_FLASH_CMD_READ: - ret = flash_area_read(partition_device, AdrOffset, buf, Datalen); - if (xfer->data != NULL) - memcpy(xfer->data, buf, Datalen); +#if defined(CONFIG_SPI_DMA_SUPPORT_ASPEED) + ret = flash_area_read(partition_device, AdrOffset, flash_rw_buf, Datalen); + memcpy(xfer->data, flash_rw_buf, Datalen); + +#else + ret = flash_area_read(partition_device, AdrOffset, xfer->data, Datalen); +#endif break; case MIDLEY_FLASH_CMD_PP://Flash Write - memset(buf, 0xff, Datalen); - memcpy(buf, xfer->data, Datalen); - ret = flash_area_write(partition_device, AdrOffset, buf, Datalen); +#if defined(CONFIG_SPI_DMA_SUPPORT_ASPEED) + memcpy(flash_rw_buf, xfer->data, Datalen); + ret = flash_area_write(partition_device, AdrOffset, flash_rw_buf, Datalen); +#else + ret = flash_area_write(partition_device, AdrOffset, xfer->data, Datalen); +#endif break; case MIDLEY_FLASH_CMD_4K_ERASE: - sector_sz = flash_get_write_block_size(flash_device); - ret = flash_area_erase(partition_device, AdrOffset, sector_sz); + ret = spi_nor_erase_by_cmd(flash_device, partition_device->fa_off + AdrOffset, + SECTOR_SIZE, MIDLEY_FLASH_CMD_4K_ERASE); break; - case MIDLEY_FLASH_CMD_64K_ERASE: - printk("%d Command is not supported", xfer->cmd); - ret = 0; + case MIDLEY_FLASH_CMD_BLOCK_ERASE: + ret = spi_nor_erase_by_cmd(flash_device, partition_device->fa_off + AdrOffset, + BLOCK_SIZE, MIDLEY_FLASH_CMD_BLOCK_ERASE); break; case MIDLEY_FLASH_CMD_CE: - printk("%d Command is not supported", xfer->cmd); + LOG_DBG("%d Command is not supported\n", xfer->cmd); ret = 0; break; case MIDLEY_FLASH_CMD_RDSR: @@ -181,7 +207,7 @@ int FMC_SPI_Command(struct pspi_flash *flash, struct pflash_xfer *xfer) ret = 0; break; default: - printk("%d Command is not supported", xfer->cmd); + LOG_DBG("%d Command is not supported\n", xfer->cmd); break; } @@ -198,12 +224,11 @@ int SPI_Command_Xfer(struct pspi_flash *flash, struct pflash_xfer *xfer) uint32_t page_sz = 0; int ret = 0; int i = 0; - char buf[4096]; int AdrOffset = 0; int Datalen = 0; struct device *dev; - if (DeviceId == BMC_SPI || DeviceId == PCH_SPI) + if (DeviceId <= PCH_SPI) ret = BMC_PCH_SPI_Command(flash, xfer); else ret = FMC_SPI_Command(flash, xfer); diff --git a/lib/hrot_hal/flash/flash_aspeed.h b/lib/hrot_hal/flash/flash_aspeed.h index 23d55ef..daf695e 100644 --- a/lib/hrot_hal/flash/flash_aspeed.h +++ b/lib/hrot_hal/flash/flash_aspeed.h @@ -4,13 +4,15 @@ * SPDX-License-Identifier: MIT */ -#ifndef ZEPHYR_INCLUDE_SPI_API_MIDLEYER_H_ -#define ZEPHYR_INCLUDE_SPI_API_MIDLEYER_H_ +#pragma once #include #include #include +#define SECTOR_SIZE 0x1000 +#define BLOCK_SIZE 0x10000 + enum { SPI_APP_CMD_NOOP = 0x00, /**< No-op */ SPI_APP_CMD_READ = 0x01, @@ -26,6 +28,7 @@ enum { enum { BMC_SPI = 0, + BMC_SPI_2, PCH_SPI, ROT_INTERNAL_ACTIVE = 4, ROT_INTERNAL_RECOVERY, @@ -74,7 +77,7 @@ enum { //MIDLEY_FLASH_CMD_DIO_READ = 0xbb, /**< Dual I/O read */ //MIDLEY_FLASH_CMD_4BYTE_DIO_READ = 0xbc, /**< Dual I/O read with 4 byte address */ MIDLEY_FLASH_CMD_CE = 0xc7, /**< Chip erase */ - MIDLEY_FLASH_CMD_64K_ERASE = 0xd8, /**< Block erase 64kB */ + MIDLEY_FLASH_CMD_BLOCK_ERASE = 0xd8, /**< Block erase 64kB */ //MIDLEY_FLASH_CMD_4BYTE_64K_ERASE = 0xdc, /**< Block erase 64kB with 4 byte address */ //MIDLEY_FLASH_CMD_EX4B = 0xe9, /**< Exit 4-byte mode */ //MIDLEY_FLASH_CMD_QIO_READ = 0xeb, /**< Quad I/O read */ @@ -301,4 +304,3 @@ struct pspi_flash { int SPI_Command_Xfer(struct pspi_flash *flash, struct pflash_xfer *xfer); -#endif diff --git a/lib/hrot_hal/gpio/gpio_aspeed.c b/lib/hrot_hal/gpio/gpio_aspeed.c index 65f8ab1..598c320 100644 --- a/lib/hrot_hal/gpio/gpio_aspeed.c +++ b/lib/hrot_hal/gpio/gpio_aspeed.c @@ -4,6 +4,7 @@ * SPDX-License-Identifier: MIT */ +#include #include #include #include @@ -17,156 +18,75 @@ #define LOG_MODULE_NAME gpio_api -#include LOG_MODULE_REGISTER(LOG_MODULE_NAME); -static char *GPIO_Devices_List[6] = { - "GPIO0_A_D", - "GPIO0_E_H", - "GPIO0_I_L", - "GPIO0_M_P", - "GPIO0_Q_T", - "GPIO0_U_V", -}; - -static void GPIO_dump_buf(uint8_t *buf, uint32_t len) -{ - uint32_t i; - - for (i = 0; i < len; i++) { - printk("%02x ", buf[i]); - if (i % 16 == 15) - printk("\n"); - } - printk("\n"); -} - int BMCBootHold(void) { - const struct device *gpio_dev = NULL; const struct device *dev_m = NULL; + /* Hold BMC Reset */ + pfr_bmc_extrst_enable_ctrl(true); +#if !defined(CONFIG_ASPEED_DC_SCM) + pfr_bmc_srst_enable_ctrl(true); +#endif dev_m = device_get_binding(BMC_SPI_MONITOR); - spim_rst_flash(dev_m, 1000); + spim_rst_flash(dev_m, 10); spim_passthrough_config(dev_m, 0, false); -#if 0 - spim_ext_mux_config(dev_m, SPIM_EXT_MUX_SEL_1); -#else - spim_ext_mux_config(dev_m, SPIM_MASTER_MODE); -#endif - /* GPIOM5 */ - gpio_dev = device_get_binding("GPIO0_M_P"); - - if (gpio_dev == NULL) { - printk("[%d]Fail to get GPIO0_M_P", __LINE__); - return -1; - } - - gpio_pin_configure(gpio_dev, BMC_SRST, GPIO_OUTPUT); - - k_busy_wait(10000); /* 10ms */ - - gpio_pin_set(gpio_dev, BMC_SRST, 0); - - k_busy_wait(10000); /* 10ms */ + /* config spi monitor as master mode */ + spim_ext_mux_config(dev_m, SPIM_EXT_MUX_ROT); return 0; } int PCHBootHold(void) { - const struct device *gpio_dev = NULL; const struct device *dev_m = NULL; + /* Hold PCH Reset */ + pfr_pch_rst_enable_ctrl(true); + dev_m = device_get_binding(PCH_SPI_MONITOR); - spim_rst_flash(dev_m, 1000); + spim_rst_flash(dev_m, 10); spim_passthrough_config(dev_m, 0, false); -#if 0 - spim_ext_mux_config(dev_m, SPIM_EXT_MUX_SEL_1); -#else - spim_ext_mux_config(dev_m, SPIM_MASTER_MODE); -#endif - /* GPIOM5 */ - gpio_dev = device_get_binding("GPIO0_M_P"); - - if (gpio_dev == NULL) { - printk("[%d]Fail to get GPIO0_M_P", __LINE__); - return -1; - } - - gpio_pin_configure(gpio_dev, CPU0_RST, GPIO_OUTPUT); - - k_busy_wait(10000); /* 10ms */ - - gpio_pin_set(gpio_dev, CPU0_RST, 0); - - k_busy_wait(10000); /* 10ms */ + /* config spi monitor as master mode */ + spim_ext_mux_config(dev_m, SPIM_EXT_MUX_ROT); return 0; } int BMCBootRelease(void) { - const struct device *gpio_dev = NULL; const struct device *dev_m = NULL; dev_m = device_get_binding(BMC_SPI_MONITOR); - spim_rst_flash(dev_m, 1000); + spim_rst_flash(dev_m, 10); spim_passthrough_config(dev_m, 0, false); -#if 0 aspeed_spi_monitor_sw_rst(dev_m); - spim_ext_mux_config(dev_m, SPIM_EXT_MUX_SEL_0); -#else - spim_ext_mux_config(dev_m, SPIM_MONITOR_MODE); -#endif - /* GPIOM5 */ - gpio_dev = device_get_binding("GPIO0_M_P"); - - if (gpio_dev == NULL) { - printk("[%d]Fail to get GPIO0_M_P", __LINE__); - return -1; - } - - gpio_pin_configure(gpio_dev, BMC_SRST, GPIO_OUTPUT); - - k_busy_wait(20000); /* 10ms */ - - gpio_pin_set(gpio_dev, BMC_SRST, 1); + /* config spi monitor as monitor mode */ + spim_ext_mux_config(dev_m, SPIM_EXT_MUX_BMC_PCH); - k_busy_wait(20000); /* 10ms */ +#if !defined(CONFIG_ASPEED_DC_SCM) + pfr_bmc_srst_enable_ctrl(false); +#endif + pfr_bmc_extrst_enable_ctrl(false); + LOG_INF("release BMC"); return 0; } int PCHBootRelease(void) { - const struct device *gpio_dev = NULL; const struct device *dev_m = NULL; dev_m = device_get_binding(PCH_SPI_MONITOR); - spim_rst_flash(dev_m, 1000); + spim_rst_flash(dev_m, 10); spim_passthrough_config(dev_m, 0, false); -#if 0 - spim_ext_mux_config(dev_m, SPIM_EXT_MUX_SEL_0); -#else - spim_ext_mux_config(dev_m, SPIM_MONITOR_MODE); -#endif - /* GPIOM5 */ - gpio_dev = device_get_binding("GPIO0_M_P"); - - if (gpio_dev == NULL) { - printk("[%d]Fail to get GPIO0_M_P", __LINE__); - return -1; - } - - gpio_pin_configure(gpio_dev, CPU0_RST, GPIO_OUTPUT); - - k_busy_wait(10000); /* 10ms */ - - gpio_pin_set(gpio_dev, CPU0_RST, 1); - - k_busy_wait(10000); /* 10ms */ + aspeed_spi_monitor_sw_rst(dev_m); + /* config spi monitor as monitor mode */ + spim_ext_mux_config(dev_m, SPIM_EXT_MUX_BMC_PCH); + pfr_pch_rst_enable_ctrl(false); + LOG_INF("release PCH"); return 0; } diff --git a/lib/hrot_hal/gpio/gpio_aspeed.h b/lib/hrot_hal/gpio/gpio_aspeed.h index 73be409..caff3c9 100644 --- a/lib/hrot_hal/gpio/gpio_aspeed.h +++ b/lib/hrot_hal/gpio/gpio_aspeed.h @@ -4,11 +4,19 @@ * SPDX-License-Identifier: MIT */ -#ifndef ZEPHYR_INCLUDE_GPIO_API_MIDLEYER_H_ -#define ZEPHYR_INCLUDE_GPIO_API_MIDLEYER_H_ +#pragma once + +#if defined(CONFIG_SPI_MUX_INVERSE) +#define SPIM_EXT_MUX_BMC_PCH SPIM_EXT_MUX_SEL_1 +#define SPIM_EXT_MUX_ROT SPIM_EXT_MUX_SEL_0 +#else +#define SPIM_EXT_MUX_BMC_PCH SPIM_EXT_MUX_SEL_0 +#define SPIM_EXT_MUX_ROT SPIM_EXT_MUX_SEL_1 +#endif + #define BMC_SPI_MONITOR "spi_m1" -#define PCH_SPI_MONITOR "spi_m2" +#define PCH_SPI_MONITOR "spi_m3" #define CPU0_RST 1 //refer to ASPEED Datasheet V0.8 p.41 #define BMC_SRST 5 @@ -20,4 +28,7 @@ enum { GPIO_APP_CMD_NOOP = 0x00, /**< No-op */ }; -#endif +int BMCBootHold(void); +int PCHBootHold(void); +int BMCBootRelease(void); +int PCHBootRelease(void); diff --git a/lib/hrot_hal/i2c/I2C_Slave_aspeed.h b/lib/hrot_hal/i2c/I2C_Slave_aspeed.h index 7f4775e..49f5051 100644 --- a/lib/hrot_hal/i2c/I2C_Slave_aspeed.h +++ b/lib/hrot_hal/i2c/I2C_Slave_aspeed.h @@ -4,8 +4,8 @@ * SPDX-License-Identifier: MIT */ -#ifndef ZEPHYR_INCLUDE_I2C_SLAVE_DEVICE_API_MIDLEYER_H_ -#define ZEPHYR_INCLUDE_I2C_SLAVE_DEVICE_API_MIDLEYER_H_ +#pragma once + #include #include #include @@ -169,4 +169,4 @@ int ast_i2c_slave_dev_init(const struct device *dev, uint8_t slave_addr); #define SLAVE_BUF_BUFF_MODE 1 #define SLAVE_BUF_BYTE_MODE 2 #define SLAVE_BUF_B_size 0x80 -#endif + diff --git a/lib/hrot_hal/i2c/i2c_filter_aspeed.h b/lib/hrot_hal/i2c/i2c_filter_aspeed.h index bc202ba..ccb0567 100644 --- a/lib/hrot_hal/i2c/i2c_filter_aspeed.h +++ b/lib/hrot_hal/i2c/i2c_filter_aspeed.h @@ -4,8 +4,7 @@ * SPDX-License-Identifier: MIT */ -#ifndef ZEPHYR_INCLUDE_I2C_FILTER_ASPEED_API_MIDLEYER_H_ -#define ZEPHYR_INCLUDE_I2C_FILTER_ASPEED_API_MIDLEYER_H_ +#pragma once #define I2C_FILTER_MIDDLEWARE_PREFIX "I2C_FILTER_" #define I2C_FILTER_MIDDLEWARE_STRING_SIZE sizeof("xxx") @@ -15,5 +14,3 @@ int i2c_filter_middleware_set_whitelist(uint8_t filter_sel, uint8_t whitelist_tb int i2c_filter_middleware_en(uint8_t filter_sel, bool en); int i2c_filter_middleware_init(uint8_t filter_sel); -#endif // ZEPHYR_INCLUDE_I2C_FILTER_ASPEED_API_MIDLEYER_H_ - diff --git a/lib/hrot_hal/otp/otp_aspeed.h b/lib/hrot_hal/otp/otp_aspeed.h index da77374..23706da 100644 --- a/lib/hrot_hal/otp/otp_aspeed.h +++ b/lib/hrot_hal/otp/otp_aspeed.h @@ -4,6 +4,8 @@ * SPDX-License-Identifier: MIT */ +#pragma once + #include #define OTP_REG_RESERVED -1 diff --git a/lib/hrot_hal/spi_filter/spi_filter_aspeed.c b/lib/hrot_hal/spi_filter/spi_filter_aspeed.c index 1bdba5a..c81fb8d 100644 --- a/lib/hrot_hal/spi_filter/spi_filter_aspeed.c +++ b/lib/hrot_hal/spi_filter/spi_filter_aspeed.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -18,15 +19,14 @@ void SPI_Monitor_Enable(char *dev_name, bool enabled) const struct device *dev_m = NULL; dev_m = device_get_binding(dev_name); - spim_rst_flash(dev_m, 1000); + if (dev_m == NULL) { + printk("%s: unable to bind %s\n", __FUNCTION__, dev_name); + return ; + } + spim_rst_flash(dev_m, 10); spim_passthrough_config(dev_m, 0, false); -#if 0 + spim_ext_mux_config(dev_m, SPIM_EXT_MUX_ROT); aspeed_spi_monitor_sw_rst(dev_m); - spim_ext_mux_config(dev_m, SPIM_EXT_MUX_SEL_1); -#else - - spim_ext_mux_config(dev_m, SPIM_MONITOR_MODE); -#endif spim_monitor_enable(dev_m, enabled); } @@ -36,6 +36,10 @@ int Set_SPI_Filter_RW_Region(char *dev_name, enum addr_priv_rw_select rw_select, const struct device *dev_m = NULL; dev_m = device_get_binding(dev_name); + if (dev_m == NULL) { + printk("%s: unable to bind %s\n", __FUNCTION__, dev_name); + return -1; + } ret = spim_address_privilege_config(dev_m, rw_select, op, addr, len); return ret; diff --git a/lib/hrot_hal/spi_filter/spi_filter_aspeed.h b/lib/hrot_hal/spi_filter/spi_filter_aspeed.h index e309730..acb84d7 100644 --- a/lib/hrot_hal/spi_filter/spi_filter_aspeed.h +++ b/lib/hrot_hal/spi_filter/spi_filter_aspeed.h @@ -4,8 +4,7 @@ * SPDX-License-Identifier: MIT */ -#ifndef ZEPHYR_INCLUDE_SPI_FILTER_API_MIDLEYER_H_ -#define ZEPHYR_INCLUDE_SPI_FILTER_API_MIDLEYER_H_ +#pragma once #include #include @@ -15,4 +14,3 @@ void SPI_Monitor_Enable(char *dev_name, bool enabled); int Set_SPI_Filter_RW_Region(char *dev_name, enum addr_priv_rw_select rw_select, enum addr_priv_op op, mm_reg_t addr, uint32_t len); -#endif diff --git a/lib/hrot_hal/watchdog/watchdog_aspeed.h b/lib/hrot_hal/watchdog/watchdog_aspeed.h index b0c8007..b6d76a5 100644 --- a/lib/hrot_hal/watchdog/watchdog_aspeed.h +++ b/lib/hrot_hal/watchdog/watchdog_aspeed.h @@ -4,8 +4,7 @@ * SPDX-License-Identifier: MIT */ -#ifndef ZEPHYR_INCLUDE_WATCHDOG_API_MIDLETER_H_ -#define ZEPHYR_INCLUDE_WATCHDOG_API_MIDLETER_H_ +#pragma once #include #include @@ -56,4 +55,3 @@ int watchdog_feed(const struct device *dev, int channel_id); */ int watchdog_disable(const struct device *dev); -#endif diff --git a/west.yml b/west.yml index 19501a0..a019aa1 100644 --- a/west.yml +++ b/west.yml @@ -3,7 +3,7 @@ manifest: self: - path: aspeed-zephyr-sdk + path: aspeed-zephyr-project remotes: - name: github @@ -12,7 +12,7 @@ manifest: projects: - name: zephyr remote: github - revision: db3dbcc9c52e67a47180890ac938ed380b33f91c + revision: d014527731033db477f806f5bff2e1ca5d4b2ba7 import: name-whitelist: - mcumgr