diff --git a/apps/aspeed-pfr/CMakeLists.txt b/apps/aspeed-pfr/CMakeLists.txt index c77b475..0d6f90f 100644 --- a/apps/aspeed-pfr/CMakeLists.txt +++ b/apps/aspeed-pfr/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.13.1) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(aspeed-pfr VERSION 02.01 LANGUAGES C) +project(aspeed-pfr VERSION 02.02 LANGUAGES C) set(PROJECT_VERSION_MAJOR ${CMAKE_PROJECT_VERSION_MAJOR}) set(PROJECT_VERSION_MINOR ${CMAKE_PROJECT_VERSION_MINOR}) @@ -19,7 +19,11 @@ set(CERBERUS_ROOT $ENV{ZEPHYR_BASE}/../middlewares/cerberus) zephyr_link_libraries(hrot_hal) zephyr_link_libraries(hrot_wrapper) zephyr_link_libraries(smf) -zephyr_link_libraries(lms) + +if (MBEDTLS_LMS_C) + zephyr_link_libraries(lms) +endif() + zephyr_link_libraries(cerberus) zephyr_link_libraries(mbedTLS) zephyr_include_directories(mbedTLS) diff --git a/apps/aspeed-pfr/Kconfig.spdm b/apps/aspeed-pfr/Kconfig.spdm index 0230a42..a61fb41 100644 --- a/apps/aspeed-pfr/Kconfig.spdm +++ b/apps/aspeed-pfr/Kconfig.spdm @@ -21,6 +21,13 @@ config PFR_MCTP_I3C help Enable MCTP over I3C support +config PFR_MCTP_I3C_5_0 + depends on PFR_MCTP_I3C + default n + bool "PFR 5.0 MCTP over I3C support" + help + Enable MCTP over I3C support for PFR 5.0 + config PFR_SPDM_RESPONDER depends on PFR_MCTP default n @@ -60,13 +67,25 @@ config PFR_SPDM_I3C_BUS default 2 int "I3C bus for attestation" +config PFR_SPDM_CPU_I3C_BUS + default 0 + int "CPU I3C bus for attestation" + config PFR_SPDM_I3C_BMC_DEV_PID default 0x7ec05031000 hex "I3C device pid for BMC" -config PFR_SPDM_I3C_CPU_DEV_PID - default 0x7ec05032000 - hex "I3C device pid for CPU" +config PFR_SPDM_I3C_HUB_DEV_PID + default 0x4cd7515a106 + hex "I3C device pid for i3c hub" + +config PFR_SPDM_I3C_CPU0_DEV_PID + default 0x20a0000000f + hex "I3C device pid for CPU0" + +config PFR_SPDM_I3C_CPU1_DEV_PID + default 0x20a0000100f + hex "I3C device pid for CPU1" config AFM_SPEC_VERSION range 3 4 diff --git a/apps/aspeed-pfr/boards/ast1060_dcscm.conf b/apps/aspeed-pfr/boards/ast1060_dcscm.conf index 2fa98a5..ea41c4d 100644 --- a/apps/aspeed-pfr/boards/ast1060_dcscm.conf +++ b/apps/aspeed-pfr/boards/ast1060_dcscm.conf @@ -48,4 +48,9 @@ CONFIG_PROVISION_SHELL=y # AFM version settings CONFIG_AFM_SPEC_VERSION=4 CONFIG_PFR_SPDM_ATTESTATION_DEVICE_OFFSET=0x2000 -CONFIG_PFR_SPDM_ATTESTATION_MAX_DEVICES=33 \ No newline at end of file +CONFIG_PFR_SPDM_ATTESTATION_MAX_DEVICES=33 + +# Intel PFR 5.0 +CONFIG_PFR_MCTP_I3C_5_0=n +CONFIG_I3C_TARGET=n +CONFIG_I3C_TARGET_MQUEUE=n diff --git a/apps/aspeed-pfr/boards/ast1060_dcscm.overlay b/apps/aspeed-pfr/boards/ast1060_dcscm.overlay index 3836124..32cf3b9 100644 --- a/apps/aspeed-pfr/boards/ast1060_dcscm.overlay +++ b/apps/aspeed-pfr/boards/ast1060_dcscm.overlay @@ -56,6 +56,36 @@ status = "okay"; }; +#if 1 +&i3c0 { + status = "okay"; + sda-tx-hold-ns = <20>; + i3c-pp-scl-hi-period-ns = <380>; + i3c-pp-scl-lo-period-ns = <620>; + pinctrl-0 = ; + + // i3chub + i3cdev@4cd7515a106 { + compatible = "i3c-dummy-device"; + reg = <0x0 0x4cd 0x7515a106>; + status = "okay"; + }; + + // cpu0 + i3cdev@20a0000000f { + compatible = "i3c-dummy-device"; + reg = <0x0 0x20a 0x0000000f>; + status = "okay"; + }; + + // cpu1 + i3cdev@20a0000100f { + compatible = "i3c-dummy-device"; + reg = <0x0 0x20a 0x0000100f>; + status = "okay"; + }; +}; + // For mctp over i3c // AST2600 i3c-1 -> AST1060 i3c-2 &i3c2 { @@ -72,6 +102,46 @@ status = "okay"; }; }; +#else +// For testing PFR 5.0 it requires following modification on dcscm card: +// - TP313 connected to R187 +// - TP314 connected to R188 +// AST1060 i3c0 -> AST2600 i3c0 (LV) +// AST1060 i3c2 -> AST2600 i3c1 (LV) +&i3c0 { + status = "okay"; + dcr = <0xcc>; + secondary; + + pinctrl-0 = < pinctrl_i3c0_default >; + + i3c0_tmq:i3c-tmq@7eca0030000 { + compatible = "i3c-target-mqueue"; + reg = <0x0 0x7ec 0xa0030000>; + msg-size = <256>; + num-of-msgs = <4>; + mandatory-data-byte = <0xae>; + status = "okay"; + }; +}; + +&i3c2 { + status = "okay"; + dcr = <0xcc>; + secondary; + + pinctrl-0 = < pinctrl_i3c2_default >; + + i3c2_tmq:i3c-tmq@7eca0032000 { + compatible = "i3c-target-mqueue"; + reg = <0x0 0x7ec 0xa0032000>; + msg-size = <256>; + num-of-msgs = <4>; + mandatory-data-byte = <0xae>; + status = "okay"; + }; +}; +#endif &wdt0 { status = "okay"; @@ -203,18 +273,21 @@ &spi1_cs0 { spi-max-buswidth = <4>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim1>; status = "okay"; }; &spi2_cs0 { spi-max-buswidth = <1>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim3>; status = "okay"; }; &spi2_cs1 { spi-max-buswidth = <1>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim4>; status = "okay"; }; @@ -239,7 +312,6 @@ log-ram-size = <0x200>; pinctrl-0 = ; pinctrl-names = "default"; - flash-device = <&spi1_cs0>; ext-mux-sel = <1>; status = "okay"; @@ -256,7 +328,6 @@ &pin_spim3misoout &pin_spim3mosiout &pin_spim3io2out &pin_spim3io3out &pin_spim3muxsel>; pinctrl-names = "default"; - flash-device = <&spi2_cs0>; ext-mux-sel = <1>; status = "okay"; write-forbidden-regions = < @@ -272,7 +343,6 @@ &pin_spim4misoout &pin_spim4mosiout &pin_spim4io2out &pin_spim4io3out &pin_spim4muxsel>; pinctrl-names = "default"; - flash-device = <&spi2_cs1>; ext-mux-sel = <1>; status = "okay"; write-forbidden-regions = < diff --git a/apps/aspeed-pfr/boards/ast1060_dcscm_amd.overlay b/apps/aspeed-pfr/boards/ast1060_dcscm_amd.overlay index d5afc64..21773aa 100644 --- a/apps/aspeed-pfr/boards/ast1060_dcscm_amd.overlay +++ b/apps/aspeed-pfr/boards/ast1060_dcscm_amd.overlay @@ -137,18 +137,21 @@ &spi1_cs0 { spi-max-buswidth = <4>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim1>; status = "okay"; }; &spi2_cs0 { spi-max-buswidth = <1>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim3>; status = "okay"; }; &spi2_cs1 { spi-max-buswidth = <1>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim4>; status = "okay"; }; @@ -173,7 +176,6 @@ log-ram-size = <0x200>; pinctrl-0 = ; pinctrl-names = "default"; - flash-device = <&spi1_cs0>; ext-mux-sel = <1>; status = "okay"; @@ -190,7 +192,6 @@ &pin_spim3misoout &pin_spim3mosiout &pin_spim3io2out &pin_spim3io3out &pin_spim3muxsel>; pinctrl-names = "default"; - flash-device = <&spi2_cs0>; ext-mux-sel = <1>; status = "okay"; write-forbidden-regions = < @@ -206,7 +207,6 @@ &pin_spim4misoout &pin_spim4mosiout &pin_spim4io2out &pin_spim4io3out &pin_spim4muxsel>; pinctrl-names = "default"; - flash-device = <&spi2_cs1>; ext-mux-sel = <1>; status = "okay"; write-forbidden-regions = < diff --git a/apps/aspeed-pfr/boards/ast1060_dcscm_dice.overlay b/apps/aspeed-pfr/boards/ast1060_dcscm_dice.overlay index 76b1840..0266454 100644 --- a/apps/aspeed-pfr/boards/ast1060_dcscm_dice.overlay +++ b/apps/aspeed-pfr/boards/ast1060_dcscm_dice.overlay @@ -199,18 +199,21 @@ &spi1_cs0 { spi-max-buswidth = <4>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim1>; status = "okay"; }; &spi2_cs0 { spi-max-buswidth = <1>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim3>; status = "okay"; }; &spi2_cs1 { spi-max-buswidth = <1>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim4>; status = "okay"; }; @@ -235,7 +238,6 @@ log-ram-size = <0x200>; pinctrl-0 = ; pinctrl-names = "default"; - flash-device = <&spi1_cs0>; ext-mux-sel = <1>; status = "okay"; @@ -252,7 +254,6 @@ &pin_spim3misoout &pin_spim3mosiout &pin_spim3io2out &pin_spim3io3out &pin_spim3muxsel>; pinctrl-names = "default"; - flash-device = <&spi2_cs0>; ext-mux-sel = <1>; status = "okay"; write-forbidden-regions = < @@ -268,7 +269,6 @@ &pin_spim4misoout &pin_spim4mosiout &pin_spim4io2out &pin_spim4io3out &pin_spim4muxsel>; pinctrl-names = "default"; - flash-device = <&spi2_cs1>; ext-mux-sel = <1>; status = "okay"; write-forbidden-regions = < diff --git a/apps/aspeed-pfr/boards/ast1060_dual_flash.overlay b/apps/aspeed-pfr/boards/ast1060_dual_flash.overlay index 47f99bb..fb784c2 100644 --- a/apps/aspeed-pfr/boards/ast1060_dual_flash.overlay +++ b/apps/aspeed-pfr/boards/ast1060_dual_flash.overlay @@ -143,24 +143,28 @@ &spi1_cs0 { spi-max-buswidth = <4>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim1>; status = "okay"; }; &spi1_cs1 { spi-max-buswidth = <4>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim2>; status = "okay"; }; &spi2_cs0 { spi-max-buswidth = <1>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim3>; status = "okay"; }; &spi2_cs1 { spi-max-buswidth = <1>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim4>; status = "okay"; }; @@ -185,7 +189,6 @@ log-ram-size = <0x200>; pinctrl-0 = ; pinctrl-names = "default"; - flash-device = <&spi1_cs0>; ext-mux-sel = <1>; status = "okay"; @@ -199,7 +202,6 @@ log-ram-size = <0x200>; pinctrl-0 = ; pinctrl-names = "default"; - flash-device = <&spi1_cs1>; ext-mux-sel = <1>; status = "okay"; @@ -216,7 +218,6 @@ &pin_spim3misoout &pin_spim3mosiout &pin_spim3io2out &pin_spim3io3out &pin_spim3muxsel>; pinctrl-names = "default"; - flash-device = <&spi2_cs0>; ext-mux-sel = <1>; status = "okay"; write-forbidden-regions = < @@ -232,7 +233,6 @@ &pin_spim4misoout &pin_spim4mosiout &pin_spim4io2out &pin_spim4io3out &pin_spim4muxsel>; pinctrl-names = "default"; - flash-device = <&spi2_cs1>; ext-mux-sel = <1>; status = "okay"; write-forbidden-regions = < diff --git a/apps/aspeed-pfr/boards/ast1060_dual_flash_amd.overlay b/apps/aspeed-pfr/boards/ast1060_dual_flash_amd.overlay index 344e890..a79f5ea 100644 --- a/apps/aspeed-pfr/boards/ast1060_dual_flash_amd.overlay +++ b/apps/aspeed-pfr/boards/ast1060_dual_flash_amd.overlay @@ -142,24 +142,28 @@ &spi1_cs0 { spi-max-buswidth = <4>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim1>; status = "okay"; }; &spi1_cs1 { spi-max-buswidth = <4>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim2>; status = "okay"; }; &spi2_cs0 { spi-max-buswidth = <1>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim3>; status = "okay"; }; &spi2_cs1 { spi-max-buswidth = <1>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim4>; status = "okay"; }; @@ -184,7 +188,6 @@ log-ram-size = <0x200>; pinctrl-0 = ; pinctrl-names = "default"; - flash-device = <&spi1_cs0>; ext-mux-sel = <1>; status = "okay"; @@ -198,7 +201,6 @@ log-ram-size = <0x200>; pinctrl-0 = ; pinctrl-names = "default"; - flash-device = <&spi1_cs1>; ext-mux-sel = <1>; status = "okay"; @@ -215,7 +217,6 @@ &pin_spim3misoout &pin_spim3mosiout &pin_spim3io2out &pin_spim3io3out &pin_spim3muxsel>; pinctrl-names = "default"; - flash-device = <&spi2_cs0>; ext-mux-sel = <1>; status = "okay"; write-forbidden-regions = < @@ -231,7 +232,6 @@ &pin_spim4misoout &pin_spim4mosiout &pin_spim4io2out &pin_spim4io3out &pin_spim4muxsel>; pinctrl-names = "default"; - flash-device = <&spi2_cs1>; ext-mux-sel = <1>; status = "okay"; write-forbidden-regions = < diff --git a/apps/aspeed-pfr/boards/ast1060_dual_flash_dice.overlay b/apps/aspeed-pfr/boards/ast1060_dual_flash_dice.overlay index a001818..66a9fd8 100644 --- a/apps/aspeed-pfr/boards/ast1060_dual_flash_dice.overlay +++ b/apps/aspeed-pfr/boards/ast1060_dual_flash_dice.overlay @@ -154,24 +154,28 @@ &spi1_cs0 { spi-max-buswidth = <4>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim1>; status = "okay"; }; &spi1_cs1 { spi-max-buswidth = <4>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim2>; status = "okay"; }; &spi2_cs0 { spi-max-buswidth = <1>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim3>; status = "okay"; }; &spi2_cs1 { spi-max-buswidth = <1>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim4>; status = "okay"; }; @@ -196,7 +200,6 @@ log-ram-size = <0x200>; pinctrl-0 = ; pinctrl-names = "default"; - flash-device = <&spi1_cs0>; ext-mux-sel = <1>; status = "okay"; @@ -211,7 +214,6 @@ pinctrl-0 = ; pinctrl-names = "default"; - flash-device = <&spi1_cs1>; ext-mux-sel = <1>; status = "okay"; @@ -228,7 +230,6 @@ &pin_spim3misoout &pin_spim3mosiout &pin_spim3io2out &pin_spim3io3out &pin_spim3muxsel>; pinctrl-names = "default"; - flash-device = <&spi2_cs0>; ext-mux-sel = <1>; status = "okay"; write-forbidden-regions = < @@ -244,7 +245,6 @@ &pin_spim4misoout &pin_spim4mosiout &pin_spim4io2out &pin_spim4io3out &pin_spim4muxsel>; pinctrl-names = "default"; - flash-device = <&spi2_cs1>; ext-mux-sel = <1>; status = "okay"; write-forbidden-regions = < diff --git a/apps/aspeed-pfr/boards/ast1060_evb.overlay b/apps/aspeed-pfr/boards/ast1060_evb.overlay index b067c30..d645d4a 100644 --- a/apps/aspeed-pfr/boards/ast1060_evb.overlay +++ b/apps/aspeed-pfr/boards/ast1060_evb.overlay @@ -138,6 +138,7 @@ &spi1_cs0 { spi-max-buswidth = <4>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim1>; status = "okay"; }; @@ -153,6 +154,7 @@ spi-max-buswidth = <4>; spi-max-frequency = <50000000>; reg = <0>; + spi-monitor-ctrl = <&spim3>; status = "okay"; }; @@ -160,6 +162,7 @@ spi-max-buswidth = <4>; spi-max-frequency = <50000000>; reg = <1>; + spi-monitor-ctrl = <&spim4>; status = "okay"; }; @@ -190,7 +193,6 @@ pinctrl-0 = ; pinctrl-names = "default"; - flash-device = <&spi1_cs0>; status = "okay"; write-forbidden-regions = < 0x00000000 0x08000000 @@ -203,7 +205,6 @@ pinctrl-0 = ; pinctrl-names = "default"; - flash-device = <&spi2_cs0>; status = "okay"; write-forbidden-regions = < 0x00000000 0x08000000 @@ -219,7 +220,6 @@ &pin_spim3muxsel>; pinctrl-names = "default"; - flash-device = <&spi2_cs1>; status = "okay"; }; @@ -247,7 +247,6 @@ &pin_spim4muxsel>; pinctrl-names = "default"; - flash-device = <&spi2_cs2>; status = "okay"; }; diff --git a/apps/aspeed-pfr/boards/ast1060_prot.overlay b/apps/aspeed-pfr/boards/ast1060_prot.overlay index 1598d05..84810af 100644 --- a/apps/aspeed-pfr/boards/ast1060_prot.overlay +++ b/apps/aspeed-pfr/boards/ast1060_prot.overlay @@ -188,24 +188,28 @@ &spi1_cs0 { spi-max-buswidth = <4>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim1>; status = "okay"; }; &spi1_cs1 { spi-max-buswidth = <4>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim2>; status = "okay"; }; &spi2_cs0 { spi-max-buswidth = <4>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim3>; status = "okay"; }; &spi2_cs1 { spi-max-buswidth = <4>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim4>; status = "okay"; }; @@ -232,7 +236,6 @@ &pin_spim1csout &pin_spim1io2in &pin_spim1io3in>; pinctrl-names = "default"; - flash-device = <&spi1_cs0>; ext-mux-sel = <1>; ext-mux-sel-gpios = <&gpio0_a_d 12 0>, <&sgpiom_a_d 0 0>; /* SGPIO OUT #1 */ ext-mux-sel-delay-us = <1000>; @@ -250,7 +253,6 @@ &pin_spim2csout &pin_spim2io2in &pin_spim2io3in>; pinctrl-names = "default"; - flash-device = <&spi1_cs1>; ext-mux-sel = <1>; ext-mux-sel-gpios = <&gpio0_a_d 12 0>, <&sgpiom_a_d 0 0>; /* SGPIO OUT #1 */ ext-mux-sel-delay-us = <1000>; @@ -270,7 +272,6 @@ &pin_spim3misoout &pin_spim3mosiout &pin_spim3io2out &pin_spim3io3out>; pinctrl-names = "default"; - flash-device = <&spi2_cs0>; ext-mux-sel = <1>; ext-mux-sel-gpios = <&gpio0_e_h 8 0>, <&sgpiom_a_d 2 0>; /* SGPIO OUT #3 */ ext-mux-sel-delay-us = <1000>; @@ -289,7 +290,6 @@ &pin_spim4misoout &pin_spim4mosiout &pin_spim4io2out &pin_spim4io3out>; pinctrl-names = "default"; - flash-device = <&spi2_cs1>; ext-mux-sel = <1>; ext-mux-sel-gpios = <&gpio0_e_h 8 0>, <&sgpiom_a_d 2 0>; /* SGPIO OUT #3 */ ext-mux-sel-delay-us = <1000>; diff --git a/apps/aspeed-pfr/boards/ast2700_dcscm.overlay b/apps/aspeed-pfr/boards/ast2700_dcscm.overlay index 7341e28..10f3628 100644 --- a/apps/aspeed-pfr/boards/ast2700_dcscm.overlay +++ b/apps/aspeed-pfr/boards/ast2700_dcscm.overlay @@ -55,6 +55,36 @@ }; // For mctp over i3c +// CPU0 and CPU1 -> i3chub -> AST1060 i3c-2 +&i3c0 { + status = "okay"; + sda-tx-hold-ns = <20>; + i3c-pp-scl-hi-period-ns = <380>; + i3c-pp-scl-lo-period-ns = <620>; + pinctrl-0 = ; + + // i3chub + i3cdev@4cd7515a106 { + compatible = "i3c-dummy-device"; + reg = <0x0 0x4cd 0x7515a106>; + status = "okay"; + }; + + // cpu0 + i3cdev@20a0000000f { + compatible = "i3c-dummy-device"; + reg = <0x0 0x20a 0x0000000f>; + status = "okay"; + }; + + // cpu1 + i3cdev@20a0000100f { + compatible = "i3c-dummy-device"; + reg = <0x0 0x20a 0x0000100f>; + status = "okay"; + }; +}; + // AST2700 i3c-0 -> AST1060 i3c-2 &i3c2 { status = "okay"; @@ -192,18 +222,21 @@ &spi1_cs0 { spi-max-buswidth = <4>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim1>; status = "okay"; }; &spi2_cs0 { spi-max-buswidth = <1>; spi-max-frequency = <25000000>; + spi-monitor-ctrl = <&spim3>; status = "okay"; }; &spi2_cs1 { spi-max-buswidth = <1>; spi-max-frequency = <25000000>; + spi-monitor-ctrl = <&spim4>; status = "okay"; }; @@ -228,7 +261,6 @@ log-ram-size = <0x200>; pinctrl-0 = ; pinctrl-names = "default"; - flash-device = <&spi1_cs0>; ext-mux-sel = <1>; status = "okay"; @@ -245,7 +277,6 @@ &pin_spim3misoout &pin_spim3mosiout &pin_spim3io2out &pin_spim3io3out &pin_spim3muxsel>; pinctrl-names = "default"; - flash-device = <&spi2_cs0>; ext-mux-sel = <1>; status = "okay"; write-forbidden-regions = < @@ -261,7 +292,6 @@ &pin_spim4misoout &pin_spim4mosiout &pin_spim4io2out &pin_spim4io3out &pin_spim4muxsel>; pinctrl-names = "default"; - flash-device = <&spi2_cs1>; ext-mux-sel = <1>; status = "okay"; write-forbidden-regions = < diff --git a/apps/aspeed-pfr/prj.conf b/apps/aspeed-pfr/prj.conf index 908cb13..d47d499 100644 --- a/apps/aspeed-pfr/prj.conf +++ b/apps/aspeed-pfr/prj.conf @@ -1,3 +1,4 @@ +CONFIG_EVENTS=y CONFIG_GPIO=y CONFIG_SPI=y CONFIG_I2C=y diff --git a/apps/aspeed-pfr/src/AspeedStateMachine/AspeedStateMachine.c b/apps/aspeed-pfr/src/AspeedStateMachine/AspeedStateMachine.c index 1ab0beb..f3829d0 100644 --- a/apps/aspeed-pfr/src/AspeedStateMachine/AspeedStateMachine.c +++ b/apps/aspeed-pfr/src/AspeedStateMachine/AspeedStateMachine.c @@ -48,14 +48,17 @@ #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 "spi_filter/spim_util.h" #include "pfr/pfr_ufm.h" #include "flash/flash_aspeed.h" #include "flash/flash_wrapper.h" #include "watchdog_timer/wdt_utils.h" +#include "i2c/i2c_util.h" +#include "i3c/i3c_util.h" #if defined(CONFIG_PFR_MCTP) #include "mctp/mctp.h" +#include "mctp/mctp_i3c.h" #endif #if defined(CONFIG_PFR_SPDM_ATTESTATION) @@ -107,6 +110,7 @@ static uint8_t last_cpld_recovery_verify_status = Failure; static bool reset_from_unprovision_state = false; size_t event_log_idx = 0; +K_EVENT_DEFINE(pfr_system_event); extern enum boot_indicator get_boot_indicator(void); void clear_pending_recovery_update(CPLD_STATUS *cpld_update_status) @@ -203,6 +207,22 @@ int is_pltrst_sync(void) return pltrst_sync; } +void init_i2c_filters(void) +{ + char bus_dev_name[] = "i2cfilterx"; + const struct device *flt_dev = NULL; + + for (int i = 0; i < 4; i++) { + bus_dev_name[9] = i + '0'; + flt_dev = device_get_binding(bus_dev_name); + if (flt_dev) { + ast_i2c_filter_init(flt_dev); + ast_i2c_filter_en(flt_dev, true, false, true, true); + ast_i2c_filter_default(flt_dev, 0); + } + } +} + void do_init(void *o) { struct smf_context *state = (struct smf_context *)o; @@ -275,6 +295,8 @@ void do_init(void *o) #if defined(CONFIG_PFR_SW_MAILBOX) InitializeSmbusMailbox(); #endif + util_init_I2C(); + util_init_I3C(); #if defined(CONFIG_PFR_MCTP) init_pfr_mctp(); #if defined(CONFIG_PFR_SPDM_ATTESTATION) @@ -331,16 +353,21 @@ void enter_tmin1(void *o) } if (bmc_reset_only) { + init_i2c_filters(); BMCBootHold(); evt_ctx->data.bit8[2] |= BmcOnlyReset; gWdtBootStatus &= ~WDT_BMC_BOOT_DONE_MASK; SetBmcCheckpoint(0); #if defined(CONFIG_PFR_MCTP_I3C) - if (mctp_i3c_detach_slave_dev(CONFIG_PFR_SPDM_I3C_BUS, - CONFIG_PFR_SPDM_I3C_BMC_DEV_PID)) - LOG_WRN("Failed to dettach i3c slave device"); - else - LOG_INF("I3C slave device detached"); +#if defined(CONFIG_PFR_MCTP_I3C_5_0) + mctp_i3c_target_mctp_stop(); +#else + if (mctp_i3c_detach_slave_dev(CONFIG_PFR_SPDM_I3C_BUS, + CONFIG_PFR_SPDM_I3C_BMC_DEV_PID)) + LOG_WRN("Failed to detach BMC's i3c target device"); + else + LOG_INF("BMC's I3C target device detached"); +#endif #endif } else if (pch_reset_only) { PCHBootHold(); @@ -351,6 +378,7 @@ void enter_tmin1(void *o) #endif SetBiosCheckpoint(0); } else { + init_i2c_filters(); evt_ctx->data.bit8[2] &= ~(BmcOnlyReset | PchOnlyReset); BMCBootHold(); PCHBootHold(); @@ -364,11 +392,29 @@ void enter_tmin1(void *o) SetBmcCheckpoint(0); SetBiosCheckpoint(0); #if defined(CONFIG_PFR_MCTP_I3C) - if (mctp_i3c_detach_slave_dev(CONFIG_PFR_SPDM_I3C_BUS, - CONFIG_PFR_SPDM_I3C_BMC_DEV_PID)) - LOG_WRN("Failed to dettach i3c slave device"); - else - LOG_INF("I3C slave device detached"); +#if defined(CONFIG_PFR_MCTP_I3C_5_0) + mctp_i3c_target_mctp_stop(); +#else + if (mctp_i3c_detach_slave_dev(CONFIG_PFR_SPDM_I3C_BUS, + CONFIG_PFR_SPDM_I3C_BMC_DEV_PID)) + LOG_WRN("Failed to detach BMC's i3c target device"); + else + LOG_INF("BMC's I3C target device detached"); + + if (get_i3c_mng_owner() == I3C_MNG_OWNER_ROT) { + if (mctp_i3c_detach_slave_dev(CONFIG_PFR_SPDM_CPU_I3C_BUS, + CONFIG_PFR_SPDM_I3C_CPU0_DEV_PID)) + LOG_WRN("Failed to detach CPU0 i3c target device"); + else + LOG_INF("CPU0's I3C target device detached"); + + if (mctp_i3c_detach_slave_dev(CONFIG_PFR_SPDM_CPU_I3C_BUS, + CONFIG_PFR_SPDM_I3C_CPU1_DEV_PID)) + LOG_WRN("Failed to detach CPU1 i3c target device"); + else + LOG_INF("CPU1's I3C target device detached"); + } +#endif #endif } @@ -635,7 +681,7 @@ void handle_image_verification(void *o) /* Success = 0, Failure = 1 */ if (state->bmc_active_object.ActiveImageStatus) { if (state->bmc_active_object.RecoveryImageStatus) - LogErrorCodes(BMC_AUTH_FAIL, ACTIVE_RECOVERY_AUTH_FAIL); + LogErrorCodes(BMC_AUTH_FAIL, ACTIVE_RECOVERY_STAGING_AUTH_FAIL); else LogErrorCodes(BMC_AUTH_FAIL, ACTIVE_AUTH_FAIL); } else if (state->bmc_active_object.RecoveryImageStatus) { @@ -644,12 +690,22 @@ void handle_image_verification(void *o) if (state->pch_active_object.ActiveImageStatus) { if (state->pch_active_object.RecoveryImageStatus) - LogErrorCodes(PCH_AUTH_FAIL, ACTIVE_RECOVERY_AUTH_FAIL); + LogErrorCodes(PCH_AUTH_FAIL, ACTIVE_RECOVERY_STAGING_AUTH_FAIL); else LogErrorCodes(PCH_AUTH_FAIL, ACTIVE_AUTH_FAIL); } else if (state->pch_active_object.RecoveryImageStatus) { LogErrorCodes(PCH_AUTH_FAIL, RECOVERY_AUTH_FAIL); } +#if defined(CONFIG_PFR_SPDM_ATTESTATION) + if (state->afm_active_object.ActiveImageStatus) { + if (state->afm_active_object.RecoveryImageStatus) + LogErrorCodes(BMC_AUTH_FAIL, AFM_ACTIVE_RECOVERY_STAGING_AUTH_FAIL); + else + LogErrorCodes(BMC_AUTH_FAIL, AFM_ACTIVE_AUTH_FAIL); + } else if (state->afm_active_object.RecoveryImageStatus) { + LogErrorCodes(BMC_AUTH_FAIL, AFM_RECOVERY_AUTH_FAIL); + } +#endif if (state->bmc_active_object.ActiveImageStatus || !state->bmc_active_object.RecoveryImageStatus) state->bmc_active_object.RestrictActiveUpdate = 0; @@ -938,6 +994,9 @@ void enter_tzero(void *o) { LOG_DBG("Start"); SetPlatformState(ENTER_T0); +#if defined(CONFIG_PFR_MCTP_I3C) + switch_i3c_mng_owner(I3C_MNG_OWNER_BMC); +#endif struct smf_context *state = (struct smf_context *)o; struct event_context *evt_ctx = ((struct smf_context *)o)->event_ctx; @@ -955,9 +1014,6 @@ void enter_tzero(void *o) goto enter_tzero_end; } else if (evt_ctx->data.bit8[2] & PchOnlyReset) { apply_pfm_protection(PCH_SPI); -#if defined(CONFIG_CERBERUS_PFR) - apply_pfm_smbus_protection(PCH_SPI); -#endif PCHBootRelease(); goto enter_tzero_end; } @@ -979,11 +1035,8 @@ void enter_tzero(void *o) } if (state->pch_active_object.ActiveImageStatus == Success) { - /* Arm SPI/I2C Filter */ + /* Arm SPI Filter */ apply_pfm_protection(PCH_SPI); -#if defined(CONFIG_CERBERUS_PFR) - apply_pfm_smbus_protection(PCH_SPI); -#endif PCHBootRelease(); } else LOG_ERR("Host firmware is invalid, host won't boot"); @@ -1130,6 +1183,7 @@ void handle_provision_image(void *o) EVENT_CONTEXT evt_ctx_wrap; uint32_t image_type = ROT_TYPE; int ret; + struct event_context *evt_ctx = ((struct smf_context *)o)->event_ctx; ufm_read(UPDATE_STATUS_UFM, UPDATE_STATUS_ADDRESS, (uint8_t *)&cached_status, sizeof(CPLD_STATUS)); @@ -1141,7 +1195,7 @@ void handle_provision_image(void *o) dev_m = device_get_binding(BMC_SPI_MONITOR_2); spim_ext_mux_config(dev_m, SPIM_EXT_MUX_ROT); #endif - ret = update_firmware_image(image_type, ao_data_wrap, &evt_ctx_wrap, &cpld_update_status); + ret = update_firmware_image(image_type, ao_data_wrap, &evt_ctx_wrap, &cpld_update_status, evt_ctx); if (memcmp(&cached_status, &cpld_update_status, sizeof(CPLD_STATUS))) { ufm_write(UPDATE_STATUS_UFM, UPDATE_STATUS_ADDRESS, (uint8_t *)&cpld_update_status, sizeof(CPLD_STATUS)); @@ -1158,6 +1212,23 @@ void handle_provision_image(void *o) } #endif +void handle_unprovisioned_checkpoint(void *o) +{ + struct smf_context *state = (struct smf_context *)o; + struct event_context *evt_ctx = state->event_ctx; + + switch(evt_ctx->data.bit8[0]) { + case BmcCheckpoint: + if (evt_ctx->data.bit8[1] == CompletingExecutionBlock) { + LOG_INF("BMC Boot complete UNPROVISIONED"); + k_event_post(&pfr_system_event, PFR_SYSTEM_BMC_BOOTED); + } + break; + default: + break; + } +} + void handle_checkpoint(void *o) { struct smf_context *state = (struct smf_context *)o; @@ -1167,14 +1238,21 @@ void handle_checkpoint(void *o) case BmcCheckpoint: UpdateBmcCheckpoint(evt_ctx->data.bit8[1]); if (evt_ctx->data.bit8[1] == CompletingExecutionBlock) { + LOG_INF("BMC Boot complete RUNTIME"); + k_event_post(&pfr_system_event, PFR_SYSTEM_BMC_BOOTED); #if defined(CONFIG_PFR_SPDM_ATTESTATION) if (state->afm_active_object.ActiveImageStatus == Success) { spdm_run_attester(); } #endif #if defined(CONFIG_PFR_MCTP_I3C) - mctp_i3c_attach_target_dev(CONFIG_PFR_SPDM_I3C_BUS, - CONFIG_PFR_SPDM_I3C_BMC_DEV_PID); +#if defined(CONFIG_PFR_MCTP_I3C_5_0) + mctp_i3c_target_intf_init(); +#else + mctp_i3c_attach_target_dev(CONFIG_PFR_SPDM_I3C_BUS, + CONFIG_PFR_SPDM_I3C_BMC_DEV_PID); + mctp_i3c_configure_cpu_i3c_devs(); +#endif #endif } break; @@ -1200,7 +1278,7 @@ void handle_checkpoint(void *o) int handle_recovery_requested(CPLD_STATUS *cpld_status, EVENT_CONTEXT *evt_ctx_wrap, - AO_DATA *ao_data_wrap, + AO_DATA **ao_data_wrap, struct smf_context *state, struct event_context *evt_ctx, uint32_t *image_type, @@ -1269,7 +1347,7 @@ int handle_recovery_requested(CPLD_STATUS *cpld_status, #endif evt_ctx_wrap->flag = evt_ctx->data.bit8[1] & UPDATE_DYNAMIC; evt_ctx_wrap->flash = SECONDARY_FLASH_REGION; - ao_data_wrap = &state->bmc_active_object; + *ao_data_wrap = &state->bmc_active_object; } else { *image_type = 0xFFFFFFFF; LOG_ERR("Staging region is tampered, recovery update won't be performed"); @@ -1354,43 +1432,56 @@ void handle_update_requested(void *o) { struct smf_context *state = (struct smf_context *)o; struct event_context *evt_ctx = state->event_ctx; + struct pfr_manifest *pfr_manifest = get_pfr_manifest(); AO_DATA *ao_data_wrap = NULL; EVENT_CONTEXT evt_ctx_wrap; int ret = Success; - uint8_t update_region = evt_ctx->data.bit8[1] & PchBmcHROTActiveAndRecoveryUpdate; + uint8_t update_region = 0; CPLD_STATUS cpld_update_status, cached_status; LOG_DBG("FIRMWARE_UPDATE Event Data %02x %02x", evt_ctx->data.bit8[0], evt_ctx->data.bit8[1]); + pfr_manifest->update_intent1 = 0; + pfr_manifest->update_intent2 = 0; + update_region = evt_ctx->data.bit8[1] & PchBmcHROTActiveAndRecoveryUpdate; ufm_read(UPDATE_STATUS_UFM, UPDATE_STATUS_ADDRESS, (uint8_t *)&cached_status, sizeof(CPLD_STATUS)); memcpy(&cpld_update_status, &cached_status, sizeof(CPLD_STATUS)); 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; if (!update_region) LogUpdateFailure(INVALID_UPD_INTENT, 0); + else { + evt_ctx->data.bit8[1] &= (UpdateAtReset | DymanicUpdate | PchRecoveryUpdate | PchActiveUpdate); + pfr_manifest->update_intent1 = evt_ctx->data.bit8[1]; + } + break; case BmcUpdateIntent: /* BMC has full access */ if ((update_region & PchActiveUpdate) || (update_region & PchRecoveryUpdate)) { cpld_update_status.BmcToPchStatus = 1; } + pfr_manifest->update_intent1 = evt_ctx->data.bit8[1]; break; case BmcUpdateIntent2: #if defined(CONFIG_PFR_SPDM_ATTESTATION) - if (evt_ctx->data.bit8[1] & AfmActiveAndRecoveryUpdate) { - update_region &= AfmActiveAndRecoveryUpdate; + if (evt_ctx->data.bit8[1] & AfmActiveUpdate) { + update_region |= AfmActiveUpdate; + } + if (evt_ctx->data.bit8[1] & AfmRecoveryUpdate) { + update_region |= AfmRecoveryUpdate; } break; #endif #if defined(CONFIG_INTEL_PFR_CPLD_UPDATE) if (evt_ctx->data.bit8[1] & CPLDUpdate) { - update_region &= CPLDUpdate; + update_region |= CPLDUpdate; } break; #endif + pfr_manifest->update_intent2 = evt_ctx->data.bit8[1]; default: break; } @@ -1410,7 +1501,7 @@ void handle_update_requested(void *o) if (update_region & BmcRecoveryUpdate) { if (handle_recovery_requested(&cpld_update_status, &evt_ctx_wrap, - ao_data_wrap, + &ao_data_wrap, state, evt_ctx, &image_type, @@ -1434,7 +1525,7 @@ void handle_update_requested(void *o) if (update_region & PchRecoveryUpdate) { if (handle_recovery_requested(&cpld_update_status, &evt_ctx_wrap, - ao_data_wrap, + &ao_data_wrap, state, evt_ctx, &image_type, @@ -1457,7 +1548,7 @@ void handle_update_requested(void *o) if (update_region & HROTRecoveryUpdate) { if (handle_recovery_requested(&cpld_update_status, &evt_ctx_wrap, - ao_data_wrap, + &ao_data_wrap, state, evt_ctx, &image_type, @@ -1489,7 +1580,7 @@ void handle_update_requested(void *o) if (update_region & AfmRecoveryUpdate) { if (handle_recovery_requested(&cpld_update_status, &evt_ctx_wrap, - ao_data_wrap, + &ao_data_wrap, state, evt_ctx, &image_type, @@ -1525,15 +1616,13 @@ void handle_update_requested(void *o) if (image_type != 0xFFFFFFFF) ret = update_firmware_image(image_type, ao_data_wrap, &evt_ctx_wrap, - &cpld_update_status); + &cpld_update_status, evt_ctx); evt_ctx->data.bit8[3] = handled_region; if (ret != Success) { - /* TODO: Log failed reason and handle it properly */ clear_pending_recovery_update(&cpld_update_status); GenerateStateMachineEvent(UPDATE_FAILED, evt_ctx->data.ptr); - break; } } @@ -1568,18 +1657,23 @@ void handle_seamless_update_requested(void *o) int ret; uint8_t update_region = evt_ctx->data.bit8[1] & 0x3f; CPLD_STATUS cpld_update_status; + struct pfr_manifest *pfr_manifest = get_pfr_manifest(); evt_ctx_wrap.operation = NONE; LOG_DBG("SEAMLESS_UPDATE Event Data %02x %02x", evt_ctx->data.bit8[0], evt_ctx->data.bit8[1]); + pfr_manifest->update_intent2 = 0; switch (evt_ctx->data.bit8[0]) { case PchUpdateIntent2: - if (evt_ctx->data.bit8[1] & BIT(0)) + if (evt_ctx->data.bit8[1] & BIT(0)) { update_region &= SeamlessUpdate; + pfr_manifest->update_intent2 = evt_ctx->data.bit8[1] & BIT(0); + } break; case BmcUpdateIntent2: if (evt_ctx->data.bit8[1] & BIT(0)) { update_region &= SeamlessUpdate; + pfr_manifest->update_intent2 = evt_ctx->data.bit8[1] & BIT(0); ufm_read(UPDATE_STATUS_UFM, UPDATE_STATUS_ADDRESS, (uint8_t *)&cpld_update_status, sizeof(CPLD_STATUS)); cpld_update_status.BmcToPchStatus = 1; ufm_write(UPDATE_STATUS_UFM, UPDATE_STATUS_ADDRESS, (uint8_t *)&cpld_update_status, sizeof(CPLD_STATUS)); @@ -1662,11 +1756,16 @@ void handle_seamless_update_verification(void *o) } #endif +extern bool i3c_hub_configured; void do_unprovisioned(void *o) { LOG_DBG("Start"); struct event_context *evt_ctx = ((struct smf_context *)o)->event_ctx; +#if defined(CONFIG_PFR_MCTP_I3C) + switch_i3c_mng_owner(I3C_MNG_OWNER_BMC); +#endif + switch (evt_ctx->event) { #if defined(CONFIG_CERBERUS_PFR) case UPDATE_REQUESTED: @@ -1680,11 +1779,22 @@ void do_unprovisioned(void *o) #endif break; case WDT_CHECKPOINT: + handle_unprovisioned_checkpoint(o); #if defined(CONFIG_PFR_MCTP_I3C) - if (evt_ctx->data.bit8[1] == CompletingExecutionBlock) { - mctp_i3c_attach_target_dev(CONFIG_PFR_SPDM_I3C_BUS, - CONFIG_PFR_SPDM_I3C_BMC_DEV_PID); - } + if (evt_ctx->data.bit8[1] == PausingExecutionBlock) { +#if !defined(CONFIG_PFR_MCTP_I3C_5_0) + switch_i3c_mng_owner(I3C_MNG_OWNER_ROT); + mctp_i3c_configure_cpu_i3c_devs(); +#endif + } else if (evt_ctx->data.bit8[1] == CompletingExecutionBlock) { +#if defined(CONFIG_PFR_MCTP_I3C_5_0) + mctp_i3c_target_intf_init(); +#else + mctp_i3c_attach_target_dev(CONFIG_PFR_SPDM_I3C_BUS, + CONFIG_PFR_SPDM_I3C_BMC_DEV_PID); + mctp_i3c_configure_cpu_i3c_devs(); +#endif + } #endif break; default: @@ -1955,7 +2065,7 @@ void AspeedStateMachine(void) next_state = &state_table[ROT_RECOVERY]; break; default: - /* Discard anyother event */ + /* Discard another event */ break; } } else if (current_state == &state_table[ROT_RECOVERY]) { diff --git a/apps/aspeed-pfr/src/AspeedStateMachine/AspeedStateMachine.h b/apps/aspeed-pfr/src/AspeedStateMachine/AspeedStateMachine.h index 80ae721..634811f 100644 --- a/apps/aspeed-pfr/src/AspeedStateMachine/AspeedStateMachine.h +++ b/apps/aspeed-pfr/src/AspeedStateMachine/AspeedStateMachine.h @@ -157,6 +157,9 @@ struct smf_context { extern struct k_fifo aspeed_sm_fifo; extern enum aspeed_pfr_event event_log[128]; extern size_t event_log_idx; +extern struct k_event pfr_system_event; + +#define PFR_SYSTEM_BMC_BOOTED BIT(0) void GenerateStateMachineEvent(enum aspeed_pfr_event evt, void *data); void AspeedStateMachine(void); diff --git a/apps/aspeed-pfr/src/AspeedStateMachine/TestShell.c b/apps/aspeed-pfr/src/AspeedStateMachine/TestShell.c index e578013..d900ab9 100644 --- a/apps/aspeed-pfr/src/AspeedStateMachine/TestShell.c +++ b/apps/aspeed-pfr/src/AspeedStateMachine/TestShell.c @@ -103,7 +103,7 @@ static int cmd_asm_flash_cmp(const struct shell *shell, size_t argc, 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); + shell_print(shell, "Hash Dev:%s Offset_A:%08x Offset_B:%08x Length:%08x", dev_name, offset_a, offset_b, length); const struct device *dev = device_get_binding(dev_name); @@ -148,7 +148,7 @@ static int cmd_asm_flash_copy(const struct shell *shell, size_t argc, size_t offset_b = strtol(argv[4], NULL, 16); size_t length = strtol(argv[5], NULL, 16); - shell_print(shell, "Hash Dev_src:%s Offset_src:%p Dev_dest:%s Offset_dest:%p Length:%p", + shell_print(shell, "Hash Dev_src:%s Offset_src:%08x Dev_dest:%s Offset_dest:%08x Length:%08x", dev_name_a, offset_a, dev_name_b, offset_b, length); const struct device *dev_a = device_get_binding(dev_name_a); @@ -377,6 +377,7 @@ SHELL_SUBCMD_DICT_SET_CREATE(sub_event, cmd_asm_event, (UPDATE_DONE, UPDATE_DONE, "UPDATE_DONE"), (UPDATE_FAILED, UPDATE_FAILED, "UPDATE_FAILED"), (PROVISION_CMD, PROVISION_CMD, "PROVISION_CMD"), + (BMC_CHECKPOINT_COMPLETE, ( WDT_CHECKPOINT | (BmcCheckpoint << 8) | (CompletingExecutionBlock << 16)), "BMC boot complete"), (WDT_TIMEOUT_BMC, (WDT_TIMEOUT | BMC_EVENT << 8), "WDT_TIMEOUT_BMC"), (WDT_TIMEOUT_PCH, (WDT_TIMEOUT | PCH_EVENT << 8), "WDT_TIMEOUT_PCH"), diff --git a/apps/aspeed-pfr/src/CMakeLists.txt b/apps/aspeed-pfr/src/CMakeLists.txt index 6ba52bc..ee564d4 100644 --- a/apps/aspeed-pfr/src/CMakeLists.txt +++ b/apps/aspeed-pfr/src/CMakeLists.txt @@ -11,8 +11,11 @@ add_subdirectory(manifestProcessor) add_subdirectory(pfr) add_subdirectory(platform_monitor) add_subdirectory(Smbus_mailbox) +add_subdirectory(spi_filter) add_subdirectory(watchdog_timer) add_subdirectory(otp) +add_subdirectory(i2c) +add_subdirectory(i3c) # Vendor specific layer add_subdirectory_ifdef(CONFIG_INTEL_PFR intel_pfr) diff --git a/apps/aspeed-pfr/src/SPDM/ResponseCmd/SPDMChallengeAuth.c b/apps/aspeed-pfr/src/SPDM/ResponseCmd/SPDMChallengeAuth.c index ce7825c..3740685 100644 --- a/apps/aspeed-pfr/src/SPDM/ResponseCmd/SPDMChallengeAuth.c +++ b/apps/aspeed-pfr/src/SPDM/ResponseCmd/SPDMChallengeAuth.c @@ -62,7 +62,7 @@ int spdm_handle_challenge(void *ctx, void *req, void *rsp) rsp_msg->header.param2 = context->local.certificate.slot_mask; // SlotMask // Calculate Certificate Chain hash - uint8_t hash[48]; + uint8_t hash[MBEDTLS_MD_MAX_SIZE]; mbedtls_sha512(context->local.certificate.certs[slot_id].data, context->local.certificate.certs[slot_id].size, hash, 1); diff --git a/apps/aspeed-pfr/src/SPDM/ResponseCmd/SPDMMeasurements.c b/apps/aspeed-pfr/src/SPDM/ResponseCmd/SPDMMeasurements.c index 8c245ce..79abe01 100644 --- a/apps/aspeed-pfr/src/SPDM/ResponseCmd/SPDMMeasurements.c +++ b/apps/aspeed-pfr/src/SPDM/ResponseCmd/SPDMMeasurements.c @@ -117,7 +117,7 @@ int spdm_handle_get_measurements(void *ctx, void *req, void *rsp) * Entire first GET_MEASUREMENTS request message under consideration, where the Requester has * requested a signature on that specific GET_MEASUREMENTS request. */ - uint8_t hash[48]; + uint8_t hash[MBEDTLS_MD_MAX_SIZE]; mbedtls_sha512_finish(&context->l1l2_context, hash); LOG_HEXDUMP_DBG(hash, 48, "L1L2 Hash"); diff --git a/apps/aspeed-pfr/src/SPDM/SPDMBuffer.c b/apps/aspeed-pfr/src/SPDM/SPDMBuffer.c index 14de12d..0630518 100644 --- a/apps/aspeed-pfr/src/SPDM/SPDMBuffer.c +++ b/apps/aspeed-pfr/src/SPDM/SPDMBuffer.c @@ -119,7 +119,10 @@ int spdm_buffer_append_reserved(struct spdm_buffer *buffer, size_t size) int spdm_buffer_get_array(struct spdm_buffer *buffer, void *data, size_t size) { - if (buffer == NULL || buffer->read_ptr + size > buffer->size) { + if (buffer == NULL) { + LOG_ERR("spdm_buffer_get_array buffer=NULL data=%p size=%d", data, size); + return -1; + } else if (buffer->read_ptr + size > buffer->size) { LOG_ERR("spdm_buffer_get_array buffer=%p data=%p read_ptr=%d size=%d buf->size=%d", buffer, data, buffer->read_ptr, size, buffer->size); return -1; diff --git a/apps/aspeed-pfr/src/SPDM/SPDMCrypto.c b/apps/aspeed-pfr/src/SPDM/SPDMCrypto.c index 319bf81..232e7a8 100644 --- a/apps/aspeed-pfr/src/SPDM/SPDMCrypto.c +++ b/apps/aspeed-pfr/src/SPDM/SPDMCrypto.c @@ -93,7 +93,7 @@ int spdm_crypto_verify(void *ctx, uint8_t slot_id, uint8_t *input, size_t input_ bool sig_context_hash, uint8_t *sig_context, size_t sig_context_len) { struct spdm_context *context = (struct spdm_context *)ctx; - int ret; + int ret = -1; /* Get Public Key for verification */ mbedtls_x509_crt *cur = &context->remote.certificate.certs[slot_id].chain; diff --git a/apps/aspeed-pfr/src/SPDM/SPDMMctpBinding.c b/apps/aspeed-pfr/src/SPDM/SPDMMctpBinding.c index e303699..9ab7770 100644 --- a/apps/aspeed-pfr/src/SPDM/SPDMMctpBinding.c +++ b/apps/aspeed-pfr/src/SPDM/SPDMMctpBinding.c @@ -72,7 +72,7 @@ extern mctp *mctp_i3c_bmc_inst; bool spdm_mctp_init_req(void *ctx, SPDM_MEDIUM medium, uint8_t bus, uint8_t dst_sa, uint8_t dst_eid) { struct spdm_context *context = (struct spdm_context *)ctx; - struct spdm_mctp_connection_data *conn = malloc(sizeof(struct spdm_mctp_connection_data)); + struct spdm_mctp_connection_data *conn; mctp *mctp_inst = NULL; switch (medium) { @@ -90,6 +90,11 @@ bool spdm_mctp_init_req(void *ctx, SPDM_MEDIUM medium, uint8_t bus, uint8_t dst_ } if (mctp_inst != NULL) { + conn = malloc(sizeof(struct spdm_mctp_connection_data)); + if (conn == NULL) { + LOG_ERR("can't allocate for connection data (%d)", sizeof(struct spdm_mctp_connection_data)); + return false; + } conn->mctp_inst = mctp_inst; conn->dst_addr = dst_sa; conn->dst_eid = dst_eid; diff --git a/apps/aspeed-pfr/src/SPDM/SPDMMctpBinding.h b/apps/aspeed-pfr/src/SPDM/SPDMMctpBinding.h index e974ce9..eb98d6d 100644 --- a/apps/aspeed-pfr/src/SPDM/SPDMMctpBinding.h +++ b/apps/aspeed-pfr/src/SPDM/SPDMMctpBinding.h @@ -5,7 +5,7 @@ */ #pragma once #include "mctp/mctp_interface.h" -#include "mctp/mctp_utils.h" +#include "mctp/mctp.h" #include "mctp/plat_mctp.h" struct spdm_mctp_connection_data { diff --git a/apps/aspeed-pfr/src/SPDM/SPDMRequester.c b/apps/aspeed-pfr/src/SPDM/SPDMRequester.c index 20f2a80..7f12779 100644 --- a/apps/aspeed-pfr/src/SPDM/SPDMRequester.c +++ b/apps/aspeed-pfr/src/SPDM/SPDMRequester.c @@ -155,7 +155,6 @@ int read_afm_dev_info(uint8_t dev_idx, uint8_t *buffer) /* To verify the data content if the data is stored in external flash */ if (dev_idx > afm_dev_idx_bmc) { manifest->image_type = flash_id; - manifest->pc_type = PFR_AFM_PER_DEV; manifest->address = afm_list[dev_idx] - offset; manifest->flash->state->device_id[0] = flash_id; ret = manifest->base->verify((struct manifest *)manifest, manifest->hash, @@ -420,13 +419,13 @@ void spdm_attester_main(void *a, void *b, void *c) AFM_DEVICE_STRUCTURE_v40_p3 afm_meas_info; char uuid_buf[36]; - afm_device_v4.dev = afm_device; afm_device_v4.pubkey = &afm_pubkey_info; afm_device_v4.measurements = &afm_meas_info; /* if data validation is failed, to ignore this item */ if (read_afm_dev_info(device, buffer)) continue; afm_device = (AFM_DEVICE_STRUCTURE_v40_p1 *)buffer; + afm_device_v4.dev = afm_device; snprintf(uuid_buf, sizeof(uuid_buf), "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", afm_device->UUID[0], afm_device->UUID[1], afm_device->UUID[2], afm_device->UUID[3], afm_device->UUID[4], afm_device->UUID[5], afm_device->UUID[6], afm_device->UUID[7], diff --git a/apps/aspeed-pfr/src/Smbus_mailbox/Smbus_mailbox.c b/apps/aspeed-pfr/src/Smbus_mailbox/Smbus_mailbox.c index cb18cdf..efc0dfc 100644 --- a/apps/aspeed-pfr/src/Smbus_mailbox/Smbus_mailbox.c +++ b/apps/aspeed-pfr/src/Smbus_mailbox/Smbus_mailbox.c @@ -364,6 +364,20 @@ void swmbx_notifyee_main(void *a, void *b, void *c) k_sem_take(events[8].sem, K_NO_WAIT); data.bit8[0] = BmcUpdateIntent2; swmbx_get_msg(0, BmcUpdateIntent2, &data.bit8[1]); + // BMC sends 0b10000001 (seamless update value) to 0x62 (mailbox register offset). + // CPLD cleared Bit#0 of the seamless update intent after receiving the intent. + // CPLD finish the seamless update and check the most significant bit of the update intent. + // CPLD wait up to ‘x’ ( Eg: 30sec) seconds for this significant bit to be cleared, + // if not cleared, CPLD issue BMC reset. + uint8_t update_intent = data.bit8[1]; + + if (update_intent & SeamlessUpdateAck) { + update_intent &= ~SeamlessUpdate; + SetBmcUpdateIntent2(update_intent); + } else { + if (pfr_timer_remaining_get(BMC_TIMER)) + pfr_stop_timer(BMC_TIMER); + } GenerateStateMachineEvent(UPDATE_INTENT_2_REQUESTED, data.ptr); } else if (events[9].state == K_POLL_STATE_SEM_AVAILABLE) { @@ -579,6 +593,7 @@ MBX_REG_SETTER_GETTER(BmcCheckpoint); MBX_REG_SETTER_GETTER(AcmCheckpoint); MBX_REG_SETTER_GETTER(BiosCheckpoint); MBX_REG_SETTER_GETTER(BmcUpdateIntent); +MBX_REG_SETTER_GETTER(BmcUpdateIntent2); MBX_REG_SETTER_GETTER(PchPfmActiveSvn); MBX_REG_SETTER_GETTER(PchPfmActiveMajorVersion); MBX_REG_SETTER_GETTER(PchPfmActiveMinorVersion); @@ -605,6 +620,8 @@ MBX_REG_SETTER_GETTER(IntelCpldActiveSvn); MBX_REG_SETTER_GETTER(IntelCpldActiveMajorVersion); MBX_REG_SETTER_GETTER(IntelCpldActiveMinorVersion); #endif +MBX_REG_SETTER_GETTER(PfrActivityInfo1); +MBX_REG_SETTER_GETTER(PfrActivityInfo2); #if defined(CONFIG_FRONT_PANEL_LED) #include diff --git a/apps/aspeed-pfr/src/Smbus_mailbox/Smbus_mailbox.h b/apps/aspeed-pfr/src/Smbus_mailbox/Smbus_mailbox.h index 4662ce3..42fce98 100644 --- a/apps/aspeed-pfr/src/Smbus_mailbox/Smbus_mailbox.h +++ b/apps/aspeed-pfr/src/Smbus_mailbox/Smbus_mailbox.h @@ -71,6 +71,8 @@ typedef enum _SMBUS_MAILBOX_RF_ADDRESS_READONLY { IntelCpldActiveMajorVersion = 0x7c, IntelCpldActiveMinorVersion = 0x7d, #endif + PfrActivityInfo1 = 0x7e, + PfrActivityInfo2 = 0x7f, AcmBiosScratchPad = 0x80, BmcScratchPad = 0xc0, } SMBUS_MAILBOX_RF_ADDRESS; @@ -120,7 +122,9 @@ typedef enum _UPDATE_INTENT_2 { AfmActiveUpdate = 0x02, AfmRecoveryUpdate = 0x04, AfmActiveAndRecoveryUpdate = 0x06, + AfmActiveAddToUpdate = 0x08, CPLDUpdate = 0x10, + SeamlessUpdateAck = 0x80, } UPDATE_INTENT_2; // EVT_DATA_0 : Update Intent(e.g. PchUpdateIntent) @@ -211,6 +215,8 @@ byte GetBmcPfmRecoverMajorVersion(void); void SetBmcPfmRecoverMajorVersion(byte RecoverMajorVersion); byte GetBmcPfmRecoverMinorVersion(void); void SetBmcPfmRecoverMinorVersion(byte RecoverMinorVersion); +byte GetBmcUpdateIntent2(void); +void SetBmcUpdateIntent2(byte UpdateIntent); #if defined(CONFIG_PFR_SPDM_ATTESTATION) byte GetAfmActiveSvn(void); void SetAfmActiveSvn(byte ActiveSVN); @@ -235,6 +241,10 @@ void SetIntelCpldActiveMajorVersion(byte ActiveMajorVersion); byte GetIntelCpldActiveMinorVersion(void); void SetIntelCpldActiveMinorVersion(byte ActiveMinorVersion); #endif +void SetPfrActivityInfo1(byte activity); +byte GetPfrActivityInfo1(void); +void SetPfrActivityInfo2(byte activity); +byte GetPfrActivityInfo2(void); void process_provision_command(void); void UpdateBiosCheckpoint(byte Data); void UpdateBmcCheckpoint(byte Data); diff --git a/apps/aspeed-pfr/src/cerberus_pfr/cerberus_pfr_recovery.c b/apps/aspeed-pfr/src/cerberus_pfr/cerberus_pfr_recovery.c index daefd61..67424c4 100644 --- a/apps/aspeed-pfr/src/cerberus_pfr/cerberus_pfr_recovery.c +++ b/apps/aspeed-pfr/src/cerberus_pfr/cerberus_pfr_recovery.c @@ -388,9 +388,3 @@ int recovery_verify(struct recovery_image *image, struct hash_engine *hash, return Success; } -int recovery_apply_to_flash(struct recovery_image *image, struct spi_flash *flash) -{ - // TODO - return Success; -} - diff --git a/apps/aspeed-pfr/src/cerberus_pfr/cerberus_pfr_recovery.h b/apps/aspeed-pfr/src/cerberus_pfr/cerberus_pfr_recovery.h index fc2292f..d2b4f38 100644 --- a/apps/aspeed-pfr/src/cerberus_pfr/cerberus_pfr_recovery.h +++ b/apps/aspeed-pfr/src/cerberus_pfr/cerberus_pfr_recovery.h @@ -39,7 +39,6 @@ int cerberus_pfr_recovery_verify(struct recovery_image *image, struct hash_engin int 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 recovery_apply_to_flash(struct recovery_image *image, struct spi_flash *flash); int pfr_staging_pch_staging(struct pfr_manifest *manifest); int pfr_recover_active_region(struct pfr_manifest *manifest); diff --git a/apps/aspeed-pfr/src/cerberus_pfr/cerberus_pfr_smbus_filtering.c b/apps/aspeed-pfr/src/cerberus_pfr/cerberus_pfr_smbus_filtering.c index 7067931..4c0fc71 100644 --- a/apps/aspeed-pfr/src/cerberus_pfr/cerberus_pfr_smbus_filtering.c +++ b/apps/aspeed-pfr/src/cerberus_pfr/cerberus_pfr_smbus_filtering.c @@ -40,16 +40,6 @@ void apply_pfm_smbus_protection(uint8_t spi_dev) if ((i2c_rule.magic_number != I2C_FILTER_SECTION_MAGIC) || (i2c_rule.filter_count == 0)) return; - for (int i = 0; i < 4; i++) { - bus_dev_name[9] = i + '0'; - flt_dev = device_get_binding(bus_dev_name); - if (flt_dev) { - ast_i2c_filter_init(flt_dev); - ast_i2c_filter_en(flt_dev, true, false, true, true); - ast_i2c_filter_default(flt_dev, 0); - } - } - i2c_filter_addr += sizeof(struct SMBUS_FILTER_RULE); for (uint8_t fid = 0; fid < i2c_rule.filter_count; fid++) { diff --git a/apps/aspeed-pfr/src/cerberus_pfr/cerberus_pfr_spi_filtering.c b/apps/aspeed-pfr/src/cerberus_pfr/cerberus_pfr_spi_filtering.c index dda2ff1..280cf62 100644 --- a/apps/aspeed-pfr/src/cerberus_pfr/cerberus_pfr_spi_filtering.c +++ b/apps/aspeed-pfr/src/cerberus_pfr/cerberus_pfr_spi_filtering.c @@ -13,6 +13,7 @@ #include "flash/flash_aspeed.h" #include "pfr/pfr_util.h" #include "Smbus_mailbox/Smbus_mailbox.h" +#include "spi_filter/spim_util.h" #define SPIM_NUM 4 diff --git a/apps/aspeed-pfr/src/cerberus_pfr/cerberus_pfr_update.c b/apps/aspeed-pfr/src/cerberus_pfr/cerberus_pfr_update.c index 11e3a2e..058a7ef 100644 --- a/apps/aspeed-pfr/src/cerberus_pfr/cerberus_pfr_update.c +++ b/apps/aspeed-pfr/src/cerberus_pfr/cerberus_pfr_update.c @@ -568,10 +568,9 @@ int update_firmware_image(uint32_t image_type, void *AoData, void *EventContext, * * @return 0 if the firmware image is valid or an error code. */ -int firmware_image_verify(struct firmware_image *fw, struct hash_engine *hash, struct rsa_engine *rsa) +int firmware_image_verify(const struct firmware_image *fw, struct hash_engine *hash) { ARG_UNUSED(hash); - ARG_UNUSED(rsa); struct pfr_manifest *manifest = (struct pfr_manifest *) fw; struct recovery_header image_header; uint32_t dest_pfm_addr; diff --git a/apps/aspeed-pfr/src/cerberus_pfr/cerberus_pfr_update.h b/apps/aspeed-pfr/src/cerberus_pfr/cerberus_pfr_update.h index 996d7b5..cfe028a 100644 --- a/apps/aspeed-pfr/src/cerberus_pfr/cerberus_pfr_update.h +++ b/apps/aspeed-pfr/src/cerberus_pfr/cerberus_pfr_update.h @@ -13,6 +13,6 @@ int cerberus_pfr_update_verify(struct firmware_image *fw, struct hash_engine *hash, struct rsa_engine *rsa); -int firmware_image_verify(struct firmware_image *fw, struct hash_engine *hash, struct rsa_engine *rsa); -int update_firmware_image(uint32_t image_type, void *AoData, void *EventContext, CPLD_STATUS *cpld_update_status); +int firmware_image_verify(const struct firmware_image *fw, struct hash_engine *hash); +int update_firmware_image(uint32_t image_type, void *AoData, void *EventContext, CPLD_STATUS *cpld_update_status, struct event_context *evt_ctx); diff --git a/apps/aspeed-pfr/src/common/common.c b/apps/aspeed-pfr/src/common/common.c index 28a5639..c6d9489 100644 --- a/apps/aspeed-pfr/src/common/common.c +++ b/apps/aspeed-pfr/src/common/common.c @@ -6,21 +6,15 @@ #include #include "common.h" -struct flash_master flashMaster; /**< Flash master for the PFM flash. */ struct hash_engine hashEngine; /**< Hashing engine for validation. */ -struct host_state_manager hostStateManager; struct manifest_flash manifestFlash; -struct pfm_flash pfmFlash; /**< PFM instance under test. */ -struct pfm_manager_flash pfmManagerFlash; struct signature_verification signatureVerification; /**< PFM signature verification. */ -struct spi_flash spiFlash; /**< Flash where the PFM is stored. */ struct rsa_engine_wrapper rsaEngineWrapper; // Zephyr Ported structures struct spi_engine_wrapper spiEngineWrapper; struct spi_engine_state_wrapper spiEngineStateWrapper; struct flash_master_wrapper flashEngineWrapper; -struct spi_filter_engine_wrapper spiFilterEngineWrapper; static uint8_t hashStorage[RSA_MAX_KEY_LENGTH] __aligned(16); @@ -29,46 +23,21 @@ struct flash *getFlashDeviceInstance(void) return &spiEngineWrapper.spi.base; } -struct flash_master *getFlashMasterInstance(void) -{ - return &flashMaster; -} - struct hash_engine *get_hash_engine_instance(void) { return &hashEngine; } -struct host_state_manager *getHostStateManagerInstance(void) -{ - return &hostStateManager; -} - struct manifest_flash *getManifestFlashInstance(void) { return &manifestFlash; } -struct pfm_flash *getPfmFlashInstance(void) -{ - return &pfmFlash; -} - -struct pfm_manager_flash *getPfmManagerFlashInstance(void) -{ - return &pfmManagerFlash; -} - struct signature_verification *getSignatureVerificationInstance(void) { return &signatureVerification; } -struct spi_flash *getSpiFlashInstance(void) -{ - return &spiFlash; -} - struct rsa_engine_wrapper *getRsaEngineInstance(void) { return &rsaEngineWrapper; @@ -96,7 +65,3 @@ uint8_t *getNewHashStorage(void) return hashStorage; } -struct spi_filter_engine_wrapper *getSpiFilterEngineWrapper(void) -{ - return &spiFilterEngineWrapper; -} diff --git a/apps/aspeed-pfr/src/common/common.h b/apps/aspeed-pfr/src/common/common.h index 098eb56..7ecc76c 100644 --- a/apps/aspeed-pfr/src/common/common.h +++ b/apps/aspeed-pfr/src/common/common.h @@ -19,15 +19,12 @@ #include #include -#include #include #include #include #include -#include - #include @@ -46,7 +43,6 @@ struct pfm_flash *getPfmFlashInstance(void); struct signature_verification *getSignatureVerificationInstance(void); struct spi_flash *getSpiFlashInstance(void); struct rsa_engine_wrapper *getRsaEngineInstance(void); -struct spi_filter_engine_wrapper *getSpiFilterEngineWrapper(void); struct spi_engine_wrapper *getSpiEngineWrapper(void); struct spi_engine_state_wrapper *getSpiEngineStateWrapper(void); uint8_t *getNewHashStorage(void); diff --git a/apps/aspeed-pfr/src/engineManager/engine_manager.c b/apps/aspeed-pfr/src/engineManager/engine_manager.c index 367bd7a..dcb43ce 100644 --- a/apps/aspeed-pfr/src/engineManager/engine_manager.c +++ b/apps/aspeed-pfr/src/engineManager/engine_manager.c @@ -40,8 +40,9 @@ static int initialize_crypto(/*struct engine_instances *engineInstances*/) status = hash_wrapper_init(get_hash_engine_instance()); if (status) return status; - +#if defined(CONFIG_CERBERUS_PFR) status = rsa_wrapper_init(getRsaEngineInstance()); +#endif return status; } @@ -69,94 +70,3 @@ int initializeEngines(void) return status; } -#if defined(CONFIG_SEAMLESS_UPDATE) -void apply_fvm_spi_protection(uint32_t fvm_addr, int offset) -{ - uint32_t fvm_offset = fvm_addr + offset; - uint32_t fvm_body_offset = fvm_offset + sizeof(FVM_STRUCTURE); - FVM_STRUCTURE fvm; - PFM_SPI_DEFINITION spi_def; - uint32_t fvm_body_end_addr; - uint32_t region_start_address; - uint32_t region_end_address; - int region_length; -#if defined(CONFIG_CPU_DUAL_FLASH) - int flash_size; -#endif - int spi_id = 0; - char *pch_spim_devs[2] = { - "spi_m3", - "spi_m4" - }; - - pfr_spi_read(PCH_SPI, fvm_offset, sizeof(FVM_STRUCTURE), (uint8_t *)&fvm); - fvm_body_end_addr = fvm_offset + fvm.Length; - - while (fvm_body_offset < fvm_body_end_addr) { - pfr_spi_read(PCH_SPI, fvm_body_offset, sizeof(PFM_SPI_DEFINITION), - (uint8_t *)&spi_def); - if (spi_def.PFMDefinitionType == SPI_REGION) { - region_start_address = spi_def.RegionStartAddress; - region_end_address = spi_def.RegionEndAddress; - region_length = region_end_address - region_start_address; -#if defined(CONFIG_CPU_DUAL_FLASH) - flash_size = pfr_spi_get_device_size(PCH_SPI); - if (region_start_address >= flash_size && (region_end_address - 1) >= flash_size) { - region_start_address -= flash_size; - region_end_address -= flash_size; - spi_id = 1; - } else if (region_start_address < flash_size && (region_end_address - 1) >= flash_size) { - LOG_ERR("ERROR: region start and end address should be in the same flash"); - return; - } else { - spi_id = 0; - } -#endif - if (spi_def.ProtectLevelMask.ReadAllowed) { - Set_SPI_Filter_RW_Region(pch_spim_devs[spi_id], SPI_FILTER_READ_PRIV, - SPI_FILTER_PRIV_ENABLE, region_start_address, - region_length); - LOG_INF("SPI_ID[2] fvm read enable 0x%08x to 0x%08x", - region_start_address, - region_end_address); - } else { - Set_SPI_Filter_RW_Region(pch_spim_devs[spi_id], SPI_FILTER_READ_PRIV, - SPI_FILTER_PRIV_DISABLE, region_start_address, - region_length); - LOG_INF("SPI_ID[2] fvm read disable 0x%08x to 0x%08x", - region_start_address, - region_end_address); - } - - if (spi_def.ProtectLevelMask.WriteAllowed) { - Set_SPI_Filter_RW_Region(pch_spim_devs[spi_id], SPI_FILTER_WRITE_PRIV, - SPI_FILTER_PRIV_ENABLE, region_start_address, - region_length); - LOG_INF("SPI_ID[2] fvm write enable 0x%08x to 0x%08x", - region_start_address, - region_end_address); - } else { - Set_SPI_Filter_RW_Region(pch_spim_devs[spi_id], SPI_FILTER_WRITE_PRIV, - SPI_FILTER_PRIV_DISABLE, region_start_address, - region_length); - LOG_INF("SPI_ID[2] fvm write disable 0x%08x to 0x%08x", - region_start_address, - region_end_address); - } - - if (spi_def.HashAlgorithmInfo.SHA256HashPresent) { - fvm_body_offset += sizeof(PFM_SPI_DEFINITION) + SHA256_SIZE; - } else if (spi_def.HashAlgorithmInfo.SHA384HashPresent) { - fvm_body_offset += sizeof(PFM_SPI_DEFINITION) + SHA384_SIZE; - } else { - fvm_body_offset += SPI_REGION_DEF_MIN_SIZE; - } - } else if (spi_def.PFMDefinitionType == FVM_CAP) { - fvm_body_offset += sizeof(FVM_CAPABLITIES); - } else { - break; - } - } -} -#endif - diff --git a/apps/aspeed-pfr/src/engineManager/engine_manager.h b/apps/aspeed-pfr/src/engineManager/engine_manager.h index 8553cd8..a5aaf72 100644 --- a/apps/aspeed-pfr/src/engineManager/engine_manager.h +++ b/apps/aspeed-pfr/src/engineManager/engine_manager.h @@ -7,27 +7,5 @@ #pragma once #include -#include "flash/flash_wrapper.h" - - -struct engine_instances { - struct aes_engine *aesEngine; - struct base64_engine *base64Engine; - struct ecc_engine *eccEngine; - struct flash *flashDevice; - struct flash_master *flashMaster; /**< Flash master for the PFM flash. */ - struct flash_engine_wrapper *flashEngineWrapper; - struct hash_engine *hashEngine; - struct keystore *keyStore; - struct manifest *manifestHandler; - struct pfm_flash *pfmFlash; - struct rng_engine *rngEngine; - struct rsa_engine *rsaEngine; - struct signature_verification *verification; /**< PFM signature verification. */ - struct spi_flash *spiFlash; /**< Flash where the PFM is stored. */ - struct spi_flash_wrapper *spiEngineWrapper; - struct x509_engine *x509Engine; -}; int initializeEngines(void); -void apply_fvm_spi_protection(uint32_t fvm_addr, int offset); diff --git a/apps/aspeed-pfr/src/i2c/CMakeLists.txt b/apps/aspeed-pfr/src/i2c/CMakeLists.txt new file mode 100644 index 0000000..b58e546 --- /dev/null +++ b/apps/aspeed-pfr/src/i2c/CMakeLists.txt @@ -0,0 +1,6 @@ +# Copyright (c) 2024 ASPEED Technology Inc. +# SPDX-License-Identifier: MIT +target_sources(app PRIVATE + i2c_util.c + ) + diff --git a/lib/hrot_hal/i2c/hal_i2c.c b/apps/aspeed-pfr/src/i2c/i2c_util.c similarity index 95% rename from lib/hrot_hal/i2c/hal_i2c.c rename to apps/aspeed-pfr/src/i2c/i2c_util.c index 8153f79..ab99998 100644 --- a/lib/hrot_hal/i2c/hal_i2c.c +++ b/apps/aspeed-pfr/src/i2c/i2c_util.c @@ -19,9 +19,9 @@ #include #include #include -#include "hal_i2c.h" +#include "i2c/i2c_util.h" -LOG_MODULE_REGISTER(hal_i2c, CONFIG_LOG_DEFAULT_LEVEL); +LOG_MODULE_REGISTER(i2c_util, CONFIG_LOG_DEFAULT_LEVEL); const struct device *dev_i2c[I2C_BUS_MAX_NUM]; @@ -62,11 +62,6 @@ int i2c_master_read(I2C_MSG *msg, uint8_t retry) return -EMSGSIZE; } - if (msg->tx_len > I2C_BUFF_SIZE) { - LOG_ERR("tx_len %d is over limit %d", msg->tx_len, I2C_BUFF_SIZE); - return -1; - } - int status; status = k_mutex_lock(&i2c_mutex[msg->bus], K_MSEC(1000)); @@ -139,11 +134,6 @@ int i2c_master_write(I2C_MSG *msg, uint8_t retry) return -1; } - if (msg->tx_len > I2C_BUFF_SIZE) { - LOG_ERR("tx_len %d is over limit %d", msg->tx_len, I2C_BUFF_SIZE); - return -1; - } - int status; status = k_mutex_lock(&i2c_mutex[msg->bus], K_MSEC(1000)); diff --git a/lib/hrot_hal/i2c/hal_i2c.h b/apps/aspeed-pfr/src/i2c/i2c_util.h similarity index 100% rename from lib/hrot_hal/i2c/hal_i2c.h rename to apps/aspeed-pfr/src/i2c/i2c_util.h diff --git a/apps/aspeed-pfr/src/i3c/CMakeLists.txt b/apps/aspeed-pfr/src/i3c/CMakeLists.txt new file mode 100644 index 0000000..30d83e3 --- /dev/null +++ b/apps/aspeed-pfr/src/i3c/CMakeLists.txt @@ -0,0 +1,7 @@ +# Copyright (c) 2024 ASPEED Technology Inc. +# SPDX-License-Identifier: MIT + +target_sources(app PRIVATE + i3c_util.c + ) + diff --git a/apps/aspeed-pfr/src/i3c/i3c_util.c b/apps/aspeed-pfr/src/i3c/i3c_util.c new file mode 100644 index 0000000..a7ca1c5 --- /dev/null +++ b/apps/aspeed-pfr/src/i3c/i3c_util.c @@ -0,0 +1,117 @@ +/* + * Copyright (c) 2024 ASPEED Technology Inc. + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include "i3c_util.h" +#include "gpio/gpio_aspeed.h" +#if defined(CONFIG_PFR_MCTP_I3C) +#include "mctp/mctp_i3c.h" +#endif + +LOG_MODULE_REGISTER(util_i3c); +static const struct device *dev_i3c_tmq[I3C_MAX_NUM]; +K_SEM_DEFINE(pltrst_sem, 0, 1); + +struct k_thread cpu_i3c_setup_thread; +#define CPU_I3C_SETUP_STACK_SIZE 1024 +K_THREAD_STACK_DEFINE(cpu_i3c_setup_stack, CPU_I3C_SETUP_STACK_SIZE); + +struct i3c_target_mqueue_data { + struct i3c_target_config target_config; + const struct i3c_target_mqueue_config *config; + struct mq_msg *msg_curr; + struct mq_msg *msg_queue; + int in; + int out; + int wr_index; +}; + +#if defined(CONFIG_PFR_MCTP_I3C) +void i3c_util_cpu_i3c_setup(void *a, void *b, void *c) +{ + while (1) + { + k_sem_take(&pltrst_sem, K_FOREVER); + mctp_i3c_configure_cpu_i3c_devs(); + } +} +#endif + +void util_init_I3C(void) +{ + const struct i3c_target_driver_api *api; +#ifdef DEV_I3C_TMQ_0 + dev_i3c_tmq[0] = device_get_binding("i3c-tmq@7eca0030000"); + api = dev_i3c_tmq[0]->api; + api->driver_register(dev_i3c_tmq[0]); +#endif +#ifdef DEV_I3C_TMQ_1 + dev_i3c_tmq[1] = device_get_binding("i3c-tmq@7eca0031000"); + api = dev_i3c_tmq[1]->api; + api->driver_register(dev_i3c_tmq[1]); +#endif +#ifdef DEV_I3C_TMQ_2 + dev_i3c_tmq[2] = device_get_binding("i3c-tmq@7eca0032000"); + api = dev_i3c_tmq[2]->api; + api->driver_register(dev_i3c_tmq[2]); +#endif +#ifdef DEV_I3C_TMQ_3 + dev_i3c_tmq[3] = device_get_binding("i3c-tmq@7eca0033000"); + api = dev_i3c_tmq[3]->api; + api->driver_register(dev_i3c_tmq[3]); +#endif +#if defined(CONFIG_PFR_MCTP_I3C) + k_tid_t swmbx_tid = k_thread_create( + &cpu_i3c_setup_thread, + cpu_i3c_setup_stack, + CPU_I3C_SETUP_STACK_SIZE, + i3c_util_cpu_i3c_setup, + NULL, NULL, NULL, + 5, 0, K_NO_WAIT); + k_thread_name_set(swmbx_tid, "CPU I3C Configuration Handler"); +#endif + +} + +int i3c_get_assigned_addr(uint8_t bus, uint8_t *address) +{ + const struct i3c_target_mqueue_data *tmq_data; + if (!dev_i3c_tmq[bus]) + return -ENODEV; + + + tmq_data = dev_i3c_tmq[bus]->data; + *address = tmq_data->target_config.address; + + return 0; +} + +int i3c_tmq_read(I3C_MSG *msg) +{ + if (!dev_i3c_tmq[msg->bus]) + return -ENODEV; + + msg->rx_len = + i3c_target_mqueue_read(dev_i3c_tmq[msg->bus], &msg->data[0], I3C_MAX_DATA_SIZE); + if (msg->rx_len == 0) { + return -ENODATA; + } + + return msg->rx_len; +} + +int i3c_tmq_write(I3C_MSG *msg) +{ + int ret; + if (!dev_i3c_tmq[msg->bus]) + return -ENODEV; + + ret = i3c_target_mqueue_write(dev_i3c_tmq[msg->bus], &msg->data[0], msg->tx_len); + return ret; +} + diff --git a/apps/aspeed-pfr/src/i3c/i3c_util.h b/apps/aspeed-pfr/src/i3c/i3c_util.h new file mode 100644 index 0000000..29dccd5 --- /dev/null +++ b/apps/aspeed-pfr/src/i3c/i3c_util.h @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2024 ASPEED Technology Inc. + * + * SPDX-License-Identifier: MIT + */ + +#include +#include + +#if DT_NODE_EXISTS(DT_NODELABEL(i3c0_tmq)) +#define DEV_I3C_TMQ_0 +#endif + +#if DT_NODE_EXISTS(DT_NODELABEL(i3c1_tmq)) +#define DEV_I3C_TMQ_1 +#endif + +#if DT_NODE_EXISTS(DT_NODELABEL(i3c2_tmq)) +#define DEV_I3C_TMQ_2 +#endif + +#if DT_NODE_EXISTS(DT_NODELABEL(i3c3_tmq)) +#define DEV_I3C_TMQ_3 +#endif + +#define I3C_MAX_NUM 4 +#define I3C_MAX_DATA_SIZE 256 + +typedef struct _I3C_MSG_ { + uint8_t bus; + uint8_t tx_len; + uint8_t rx_len; + uint8_t data[I3C_MAX_DATA_SIZE]; +} I3C_MSG; + +void util_init_I3C(void); +int i3c_get_assigned_addr(uint8_t bus, uint8_t *address); +int i3c_tmq_read(I3C_MSG *msg); +int i3c_tmq_write(I3C_MSG *msg); + diff --git a/apps/aspeed-pfr/src/include/SmbusMailBoxCom.h b/apps/aspeed-pfr/src/include/SmbusMailBoxCom.h index 5db4e4f..52afafb 100644 --- a/apps/aspeed-pfr/src/include/SmbusMailBoxCom.h +++ b/apps/aspeed-pfr/src/include/SmbusMailBoxCom.h @@ -214,3 +214,19 @@ typedef enum _BMC_PCH_UPDATE_INTENT_VALUE { UPDATE_AT_RESET = 0X80 } BMC_PCH_UPDATE_INTENT_VALUE; +typedef enum _PFR_ACTIVITY_STATUS_1_VALUE { + PFR_ACT1_DAA_I3C_BMC = 0b1, + PFR_ACT1_SET_EID_I3C_BMC = 0b10, + PFR_ACT1_EID_REGISTRATION_I3C_BMC = 0b100, + PFR_ACT1_I3C_MUX_TAKEOVER = 0b1000, + PFR_ACT1_DAA_I3C_CPU = 0b10000, + PFR_ACT1_SET_EID_I3C_CPU = 0b100000, + PFR_ACT1_EID_REGISTRATION_I3C_CPU = 0b1000000, +} PFR_ACTIVITY_STATUS_1_VALUE; + +typedef enum _PFR_ACTIVITY_STATUS_2_VALUE { + PFR_ACT2_BMC_BOOT_DONE = 0b1, + PFR_ACT2_IBB_BOOT_DONE = 0b10, + PFR_ACT2_OBB_BOOT_DONE = 0b100, +} PFR_ACTIVITY_STATUS_2_VALUE; + 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 ab6d83e..493cea8 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_authentication.c +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_authentication.c @@ -32,30 +32,25 @@ int pfr_recovery_verify(struct pfr_manifest *manifest) if (manifest->image_type == BMC_TYPE) { 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, (uint8_t *)&read_address, sizeof(read_address)); - manifest->pc_type = PFR_PCH_UPDATE_CAPSULE; } #if defined(CONFIG_PFR_SPDM_ATTESTATION) #if (CONFIG_AFM_SPEC_VERSION == 4) else if (manifest->image_type == ROT_EXT_AFM_RC_1) { read_address = 0; - manifest->pc_type = PFR_AFM; //manifest->image_type = ROT_EXT_AFM_RC_1; verify_afm = true; } else if (manifest->image_type == ROT_EXT_AFM_RC_2) { read_address = 0; - manifest->pc_type = PFR_AFM; //manifest->image_type = ROT_EXT_AFM_RC_2; verify_afm = true; } #elif (CONFIG_AFM_SPEC_VERSION == 3) else if (manifest->image_type == AFM_TYPE) { read_address = CONFIG_BMC_AFM_RECOVERY_OFFSET; - manifest->pc_type = PFR_AFM; manifest->image_type = BMC_TYPE; verify_afm = true; } @@ -65,7 +60,6 @@ int pfr_recovery_verify(struct pfr_manifest *manifest) else if (manifest->image_type == CPLD_TYPE) { manifest->image_type = ROT_EXT_CPLD_RC; read_address = 0; - manifest->pc_type = PFR_INTEL_CPLD_UPDATE_CAPSULE; } #endif else { @@ -84,19 +78,6 @@ int pfr_recovery_verify(struct pfr_manifest *manifest) LOG_ERR("Verify recovery capsule failed"); return Failure; } -#if defined(CONFIG_PFR_SPDM_ATTESTATION) - if (verify_afm) - manifest->pc_type = PFR_AFM; - else if (manifest->image_type == BMC_TYPE) - manifest->pc_type = PFR_BMC_PFM; - else if (manifest->image_type == PCH_TYPE) - manifest->pc_type = PFR_PCH_PFM; -#else - if (manifest->image_type == BMC_TYPE) - manifest->pc_type = PFR_BMC_PFM; - else if (manifest->image_type == PCH_TYPE) - manifest->pc_type = PFR_PCH_PFM; -#endif // Recovery region PFM verification if (manifest->hash_curve == hash_sign_algo384 || manifest->hash_curve == hash_sign_algo256) @@ -131,29 +112,24 @@ int pfr_active_verify(struct pfr_manifest *manifest) if (manifest->image_type == BMC_TYPE) { 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, (uint8_t *)&read_address, sizeof(read_address)); - manifest->pc_type = PFR_PCH_PFM; } #if defined(CONFIG_PFR_SPDM_ATTESTATION) #if (CONFIG_AFM_SPEC_VERSION == 4) else if (manifest->image_type == ROT_EXT_AFM_ACT_1) { /* Fixed partition so starts from zero */ read_address = 0; - manifest->pc_type = PFR_AFM; } else if (manifest->image_type == ROT_EXT_AFM_ACT_2) { /* Fixed partition so starts from zero */ read_address = 0; - manifest->pc_type = PFR_AFM; } #elif (CONFIG_AFM_SPEC_VERSION == 3) else if (manifest->image_type == ROT_INTERNAL_AFM) { /* Fixed partition so starts from zero */ read_address = 0; - manifest->pc_type = PFR_AFM; } #endif #endif @@ -161,7 +137,6 @@ int pfr_active_verify(struct pfr_manifest *manifest) else if (manifest->image_type == CPLD_TYPE) { manifest->image_type = ROT_EXT_CPLD_ACT; read_address = 0; - manifest->pc_type = PFR_INTEL_CPLD_UPDATE_CAPSULE; manifest->address = read_address; LOG_INF("Verifying capsule signature, address=0x%08x", manifest->address); if (manifest->pfr_authentication->online_update_cap_verify(manifest)) { diff --git a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_cpld_utils.c b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_cpld_utils.c index 4eb1e0c..7756b9a 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_cpld_utils.c +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_cpld_utils.c @@ -17,7 +17,7 @@ #include "intel_pfr_cpld_utils.h" #include "gpio/gpio_aspeed.h" #include "pfr/pfr_util.h" -#include "i2c/hal_i2c.h" +#include "i2c/i2c_util.h" LOG_MODULE_DECLARE(pfr, CONFIG_LOG_DEFAULT_LEVEL); @@ -91,6 +91,9 @@ int intel_rsu_read_ctrl_reg(uint8_t rsu_type, uint8_t reg, uint16_t *val) if (get_rsu_dev(rsu_type, &dev, &slave_addr)) return -1; + if (!dev) + return -1; + reg_addr[0] = RSU_CTRL_REG; reg_addr[1] = reg; 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 8f30a20..4b703d0 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_definitions.h +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_definitions.h @@ -10,16 +10,6 @@ #define BMC_FLASH_ID 0 #define PCH_FLASH_ID 1 -#define BMC_TYPE 0 -#define PCH_TYPE 2 - -/* For Intel-PFR 3.0 */ -#define AFM_TYPE 4 -/* For Intel-PFR 4.0 */ -#define AFM_TYPE2 5 - -#define CPLD_TYPE 6 - #define UFM0 4 #define UFM0_SIZE 512 @@ -87,10 +77,10 @@ #define PFM_SIG_BLOCK_SIZE_3K 3072 #define PFMTAG 0x02B3CE1D #define FVMTAG 0xA8E7C2D4 +#define CFMTAG 0xA8E7C2D6 #define PFMTYPE 0x01 #define UPDATE_CAPSULE 1 #define ACTIVE_PFM 2 -#define ROT_TYPE 3 #define SIGN_PCH_PFM_BIT0 0x00000001 #define SIGN_PCH_UPDATE_BIT1 0x00000002 @@ -127,6 +117,16 @@ #define MEASUREMENT_PAYLOAD_SIZE 4 #endif +typedef enum { + BMC_TYPE = 0, + PCH_TYPE = 2, + ROT_TYPE, + AFM_TYPE, + AFM_TYPE2, + CPLD_TYPE, + MAX_SUPPORTED_FW_TYPE, +} FW_TYPE; + /* Each AFM device data is 8 Kbytes In ROT_INTERNAL_AFM, its size is 64 Kbytes and it stores 3 AFM device data (CPU0, CPU1, BMC). 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 fb4bcb9..c7dc1f1 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 @@ -133,6 +133,70 @@ int verify_csk_key_id(struct pfr_manifest *manifest, uint8_t key_id) return Success; } +bool verify_key_unused(uint32_t ufm_offset, uint8_t key_id) +{ + uint32_t block1_address; + uint32_t image_type; + uint32_t base_addr; + uint32_t csk_id = 0; + + if (ufm_read(PROVISION_UFM, ufm_offset, (uint8_t *)&base_addr, sizeof(base_addr))) { + LOG_ERR("Failed to read UFM"); + return false; + } + switch (ufm_offset) { + case BMC_RECOVERY_REGION_OFFSET: + base_addr += PFM_SIG_BLOCK_SIZE; + case BMC_ACTIVE_PFM_OFFSET: + image_type = BMC_TYPE; + break; + case PCH_RECOVERY_REGION_OFFSET: + base_addr += PFM_SIG_BLOCK_SIZE; + case PCH_ACTIVE_PFM_OFFSET: + image_type = PCH_TYPE; + break; + default: + return false; + } + + block1_address = base_addr + sizeof(PFR_AUTHENTICATION_BLOCK0); + if (pfr_spi_read(image_type, block1_address + CSK_KEY_ID_ADDRESS, + sizeof(csk_id), (uint8_t *)&csk_id)) { + LOG_ERR("Flash read block1 CSK key Id failed"); + return false; + } + + if ((uint8_t)csk_id == key_id) { + LOG_ERR("Key Id: %d is not unused", key_id); + return false; + } + return true; +} + +bool is_csk_unused(uint8_t key_id, uint32_t pc_type) +{ + if (pc_type == PCH_PFM_CANCELLATION) { + LOG_INF("Verifying key is not used by PCH Active Region"); + if (!verify_key_unused(PCH_ACTIVE_PFM_OFFSET, key_id)) + return false; + + LOG_INF("Verifying key is not used by PCH Recovery Region"); + if (!verify_key_unused(PCH_RECOVERY_REGION_OFFSET, key_id)) + return false; + } else if (pc_type == BMC_PFM_CANCELLATION) { + LOG_INF("Verifying key is not used by BMC Active Region"); + if (!verify_key_unused(BMC_ACTIVE_PFM_OFFSET, key_id)) + return false; + + LOG_INF("Verifying key is not used by BMC Recovery Region"); + if (!verify_key_unused(BMC_RECOVERY_REGION_OFFSET, key_id)) + return false; + } + + LOG_INF("Key verification succeeded, Key Id: %d is not used by system", key_id); + return true; +} + int cancel_csk_key_id(struct pfr_manifest *manifest, uint8_t key_id) { uint32_t ufm_offset = get_cancellation_policy_offset(manifest->pc_type); @@ -151,6 +215,9 @@ int cancel_csk_key_id(struct pfr_manifest *manifest, uint8_t key_id) return Failure; } + if (!is_csk_unused(key_id, manifest->pc_type)) + return Failure; + ufm_offset += (key_id / 32) * 4; // bit little endian bit_offset = 31 - (key_id % 32); 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 eb4d175..ebb910d 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_pbc.c +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_pbc.c @@ -261,7 +261,7 @@ bool is_pbc_valid(PBC_HEADER *pbc) #if defined(CONFIG_SEAMLESS_UPDATE) || (CONFIG_AFM_SPEC_VERSION == 4) int get_total_pfm_size(struct pfr_manifest *manifest, uint32_t signed_pfm_offset, - uint32_t cap_pfm_body_start_addr, uint32_t cap_pfm_body_end_addr) + uint32_t cap_pfm_body_start_addr, uint32_t cap_pfm_body_end_addr, uint32_t *last_fvm_addr) { PFM_SPI_DEFINITION spi_def; uint8_t def_map = 0; @@ -271,6 +271,7 @@ int get_total_pfm_size(struct pfr_manifest *manifest, uint32_t signed_pfm_offset #endif #if (CONFIG_AFM_SPEC_VERSION == 4) uint32_t afm_start_addr = 0; + uint32_t afm_data_length = 0; #endif uint32_t image_type = manifest->image_type; uint32_t cap_pfm_body_offset = cap_pfm_body_start_addr; @@ -310,6 +311,7 @@ int get_total_pfm_size(struct pfr_manifest *manifest, uint32_t signed_pfm_offset (uint8_t *)&afm_def); cap_pfm_body_offset += sizeof(AFM_ADDRESS_DEFINITION_v40); afm_start_addr = afm_def.AfmAddress; + afm_data_length = afm_def.length; def_map |= (1 << AFM_ADDR_DEF); LOG_INF("Get an AFM defintion, afm_start_addr = %x", afm_start_addr); #endif @@ -319,20 +321,7 @@ int get_total_pfm_size(struct pfr_manifest *manifest, uint32_t signed_pfm_offset } uint32_t total_pfm_size = manifest->pc_length; -#if (CONFIG_AFM_SPEC_VERSION == 4) - if (def_map & (1 << AFM_ADDR_DEF)) { - PFR_AUTHENTICATION_BLOCK0 signed_afm; - uint32_t afm_start_addr_in_pfm = - afm_start_addr - manifest->active_pfm_addr; - uint32_t signed_afm_offset = signed_pfm_offset + afm_start_addr_in_pfm; - - pfr_spi_read(image_type, signed_afm_offset, sizeof(PFR_AUTHENTICATION_BLOCK0), - (uint8_t *)&signed_afm); - total_pfm_size = afm_start_addr_in_pfm + signed_afm.PcLength + AFM_BODY_SIZE; - /* the AFM device info should be the last part of the PFM, we don't need to calculate the FVM size if AFM is presented */ - return total_pfm_size; - } -#endif + *last_fvm_addr = manifest->pc_length; #if defined(CONFIG_SEAMLESS_UPDATE) // Get length from the header of the last fvm. if (def_map & (1 << FVM_ADDR_DEF)) { @@ -344,6 +333,24 @@ int get_total_pfm_size(struct pfr_manifest *manifest, uint32_t signed_pfm_offset pfr_spi_read(image_type, last_signed_fvm_offset, sizeof(PFR_AUTHENTICATION_BLOCK0), (uint8_t *)&signed_fvm); total_pfm_size = last_fvm_start_addr_in_pfm + signed_fvm.PcLength; + *last_fvm_addr = total_pfm_size; + } +#endif +#if (CONFIG_AFM_SPEC_VERSION == 4) + if (def_map & (1 << AFM_ADDR_DEF)) { + PFR_AUTHENTICATION_BLOCK0 signed_afm; + uint32_t afm_start_addr_in_pfm = + afm_start_addr - manifest->active_pfm_addr; + uint32_t signed_afm_offset = signed_pfm_offset + afm_start_addr_in_pfm + afm_data_length; + + pfr_spi_read(image_type, signed_afm_offset, sizeof(PFR_AUTHENTICATION_BLOCK0), + (uint8_t *)&signed_afm); + total_pfm_size = afm_start_addr_in_pfm + afm_data_length - PFM_SIG_BLOCK_SIZE; + if (signed_afm.Block0Tag == BLOCK0TAG) { + LOG_INF("has AFM device data"); + /* has AFM device data */ + total_pfm_size += AFM_BODY_SIZE; + } } #endif return total_pfm_size; @@ -468,51 +475,71 @@ int decompress_fv_capsule(struct pfr_manifest *manifest) int decompress_afm_capsule(struct pfr_manifest *pfr_manifest, AFM_ADDRESS_DEFINITION_v40 *afm_def) { int status; - uint32_t staging_address; + uint32_t reaad_address; uint32_t afm_start_addr = afm_def->AfmAddress; uint32_t afm_start_addr_in_pfm = afm_start_addr - pfr_manifest->active_pfm_addr; uint32_t org_address; + PFR_AUTHENTICATION_BLOCK0 block0; + uint32_t offset = PFM_SIG_BLOCK_SIZE; - if (pfr_manifest->image_type == BMC_TYPE) { - status = ufm_read(PROVISION_UFM, BMC_STAGING_REGION_OFFSET, - (uint8_t *)&staging_address, sizeof(staging_address)); - } else if (pfr_manifest->image_type == PCH_TYPE) { - status = ufm_read(PROVISION_UFM, PCH_STAGING_REGION_OFFSET, - (uint8_t *)&staging_address, sizeof(staging_address)); - } else { - LOG_ERR("AFM is not existed in image %d", pfr_manifest->image_type); - return -1; + if (pfr_manifest->hash_curve == hash_sign_algo384 || + pfr_manifest->hash_curve == hash_sign_algo256) { + offset = LMS_PFM_SIG_BLOCK_SIZE; } - if (status != Success) - return status; - afm_start_addr_in_pfm += staging_address ; - afm_start_addr_in_pfm += AFM_BODY_SIZE; + if (pfr_manifest->state == FIRMWARE_RECOVERY) + reaad_address = pfr_manifest->recovery_address + offset; + else + reaad_address = pfr_manifest->staging_address + offset;; + + afm_start_addr_in_pfm += reaad_address; + pfr_spi_read(pfr_manifest->image_type, afm_start_addr_in_pfm, sizeof(PFR_AUTHENTICATION_BLOCK0), + (uint8_t *)&block0); + + if (block0.Block0Tag == BLOCK0TAG) { + /* AFM address definition is found, to find AFM device info is presented or not */ + pfr_spi_read(pfr_manifest->image_type, afm_start_addr_in_pfm + block0.PcLength + offset, sizeof(PFR_AUTHENTICATION_BLOCK0), + (uint8_t *)&block0); + if (block0.Block0Tag != BLOCK0TAG) { + LOG_WRN("%s : afm device info, Tag = %x, len = %x", __FUNCTION__, block0.Block0Tag, block0.PcLength); + LOG_WRN("there is no AFM device info, to ignore AFM device decompression"); + return Success; + } + // move to afm device offset + afm_start_addr_in_pfm += (block0.PcLength + offset); + } + else { + /* the image should carry AFM address defintion because afm_def is presented */ + LOG_ERR("%s : image(%d), afm_start_addr_in_pfm = %x, afm_start_addr = %x, Tag = %x, len = %x", + __FUNCTION__, pfr_manifest->image_type, afm_start_addr_in_pfm, afm_start_addr, block0.Block0Tag, block0.PcLength); + return Failure; + } org_address = pfr_manifest->address; pfr_manifest->address = afm_start_addr_in_pfm; - // Staging area verification - LOG_INF("Staging Area verification, %x", afm_start_addr_in_pfm); - status = pfr_manifest->update_fw->base->verify((struct firmware_image *)pfr_manifest, - NULL); + status = pfr_manifest->base->verify((struct manifest *)pfr_manifest, pfr_manifest->hash, + pfr_manifest->verification->base, pfr_manifest->pfr_hash->hash_out, + pfr_manifest->pfr_hash->length); + pfr_manifest->address = org_address; if (status != Success) { LOG_ERR("Staging Area verification failed, status = %x", status); return -1; } - pfr_spi_erase_region(pfr_manifest->image_type, true, afm_start_addr + AFM_BODY_SIZE, AFM_BODY_SIZE); + LOG_INF("to copy AFM device data from image (%d,%x) to image (%d, %x)", pfr_manifest->image_type, + afm_start_addr_in_pfm, pfr_manifest->image_type, afm_start_addr); + pfr_spi_erase_region(pfr_manifest->image_type, true, afm_start_addr, AFM_BODY_SIZE); if (pfr_spi_region_read_write_between_spi(pfr_manifest->image_type, afm_start_addr_in_pfm, - pfr_manifest->image_type, afm_start_addr + AFM_BODY_SIZE, AFM_BODY_SIZE)) { - LOG_ERR("AFM body update failed"); + pfr_manifest->image_type, afm_start_addr, AFM_BODY_SIZE)) { + LOG_ERR("AFM device data update failed"); return Failure; } return 0; } - #endif int decompress_capsule(struct pfr_manifest *manifest, DECOMPRESSION_TYPE_MASK_ENUM decomp_type) @@ -526,7 +553,7 @@ int decompress_capsule(struct pfr_manifest *manifest, DECOMPRESSION_TYPE_MASK_EN uint32_t cap_pfm_body_start_addr = cap_pfm_body_offset; uint32_t cap_pfm_body_end_addr; uint32_t pbc_offset; - uint32_t pfm_size; + uint32_t pfm_total_size, pfm_size; PFM_STRUCTURE pfm_header; PFM_SPI_DEFINITION spi_def; PBC_HEADER pbc; @@ -544,13 +571,15 @@ int decompress_capsule(struct pfr_manifest *manifest, DECOMPRESSION_TYPE_MASK_EN cap_pfm_body_end_addr = cap_pfm_body_offset + pfm_header.Length - sizeof(PFM_STRUCTURE); #if defined(CONFIG_SEAMLESS_UPDATE) || (CONFIG_AFM_SPEC_VERSION == 4) - pfm_size = get_total_pfm_size(manifest, signed_pfm_offset, - cap_pfm_body_start_addr, cap_pfm_body_end_addr); + pfm_total_size = get_total_pfm_size(manifest, signed_pfm_offset, + cap_pfm_body_start_addr, cap_pfm_body_end_addr, &pfm_size); #else + pfm_total_size = manifest->pc_length; pfm_size = manifest->pc_length; #endif - pbc_offset = cap_pfm_offset + pfm_size; + pbc_offset = cap_pfm_offset + pfm_total_size; + LOG_INF("pbc_offset = %x, pfm_total_size = %x, pfm_size = %x", pbc_offset, pfm_total_size, pfm_size); if (pfr_spi_read(image_type, pbc_offset, sizeof(PBC_HEADER), (uint8_t *)&pbc)) return Failure; 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 7de8c21..1452722 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 @@ -35,6 +35,7 @@ int update_afm_body(uint32_t type, uint32_t address) int hash_length = SHA384_DIGEST_LENGTH; uint32_t org_type, afm_addr; off_t *afmlist = spdm_get_afm_list(); + PFR_AUTHENTICATION_BLOCK0 block0; struct pfr_manifest *pfr_manifest = get_pfr_manifest(); org_type = pfr_manifest->image_type; @@ -47,8 +48,21 @@ int update_afm_body(uint32_t type, uint32_t address) afm_body_offset = PCH1_AFM_BODY_OFFSET; } - /* ignore the AFM address definition part */ - afm_addr = address + AFM_BODY_SIZE; + afm_addr = address; + pfr_spi_read(flash_type, afm_addr, sizeof(PFR_AUTHENTICATION_BLOCK0), (uint8_t *)&block0); + if (block0.PcType == PFR_AFM) { + /* if AFM data is an address defintion data, to find AFM device data */ + pfr_spi_read(flash_type, afm_addr + AFM_BODY_SIZE, sizeof(PFR_AUTHENTICATION_BLOCK0), (uint8_t *)&block0); + if (block0.Block0Tag == BLOCK0TAG) + afm_addr += AFM_BODY_SIZE; + else { + LOG_WRN("there is no AFM device (%x, %x, %x)", block0.Block0Tag, block0.PcType, block0.PcLength); + return Success; + } + } else if (block0.PcType != PFR_AFM_PER_DEV) { + LOG_WRN("Invalid AFM type (%x, %x, %x)", block0.Block0Tag, block0.PcType, block0.PcLength); + return Failure; + } pfr_manifest->image_type = flash_type; pfr_manifest->pfr_hash->start_address = afm_addr; 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 71db554..2e2b32e 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_recovery.c +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_recovery.c @@ -340,6 +340,7 @@ int pfr_staging_pch_staging(struct pfr_manifest *manifest) uint32_t source_address; uint32_t target_address; + uint32_t pc_type; uint32_t image_type = manifest->image_type; status = ufm_read(PROVISION_UFM, BMC_STAGING_REGION_OFFSET, (uint8_t *)&source_address, @@ -355,18 +356,16 @@ int pfr_staging_pch_staging(struct pfr_manifest *manifest) manifest->image_type = BMC_TYPE; manifest->address = source_address; -#if defined(CONFIG_SEAMLESS_UPDATE) - if (manifest->state == SEAMLESS_UPDATE) { - manifest->pc_type = PFR_PCH_SEAMLESS_UPDATE_CAPSULE; - } else -#endif - { - manifest->pc_type = PFR_PCH_UPDATE_CAPSULE; - } - LOG_INF("BMC's PCH Staging Area verification"); LOG_INF("Veriifying capsule signature, address=0x%08x", manifest->address); // manifest verification + status = pfr_spi_read(manifest->image_type, manifest->address + (2 * sizeof(pc_type)), + sizeof(pc_type), (uint8_t *)&pc_type); + if (pc_type != PFR_PCH_UPDATE_CAPSULE && pc_type != PFR_PCH_SEAMLESS_UPDATE_CAPSULE) { + LOG_ERR("Invalid pc_type : %x", pc_type); + return Failure; + } + status = manifest->base->verify((struct manifest *)manifest, manifest->hash, manifest->verification->base, manifest->pfr_hash->hash_out, manifest->pfr_hash->length); @@ -375,20 +374,6 @@ int pfr_staging_pch_staging(struct pfr_manifest *manifest) return Failure; } - // Recovery region PFM verification - if (manifest->hash_curve == hash_sign_algo384 || manifest->hash_curve == hash_sign_algo256) - manifest->address += LMS_PFM_SIG_BLOCK_SIZE; - else - manifest->address += PFM_SIG_BLOCK_SIZE; - - manifest->pc_type = PFR_PCH_PFM; - LOG_INF("Verifying PFM signature, address=0x%08x", manifest->address); - // manifest verification - 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; LOG_INF("BMC's PCH Staging verification successful"); manifest->address = target_address; manifest->image_type = image_type; @@ -447,19 +432,3 @@ int recovery_verify(struct recovery_image *image, struct hash_engine *hash, return intel_pfr_recovery_verify(image, hash, verification, hash_out, hash_length, pfm); } -/** - * Apply the recovery image to host flash. It is assumed that the host flash region is already - * blank. - * - * @param image The recovery image to query. - * @param flash The flash device to write the recovery image to. - * - * @return 0 if applying the recovery image to host flash was successful or an error code. - */ -int recovery_apply_to_flash(struct recovery_image *image, struct spi_flash *flash) -{ - struct pfr_manifest *pfr_manifest = (struct pfr_manifest *) image; - - return intel_pfr_recover_update_action(pfr_manifest); -} - 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 4f69939..b12b4be 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_recovery.h +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_recovery.h @@ -19,5 +19,3 @@ int pfr_recover_active_region(struct pfr_manifest *manifest); int 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 recovery_apply_to_flash(struct recovery_image *image, struct spi_flash *flash); - diff --git a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_spi_filtering.c b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_spi_filtering.c index c4b2b2c..e8c71a5 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_spi_filtering.c +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_spi_filtering.c @@ -12,36 +12,21 @@ #include "engineManager/engine_manager.h" #include "manifestProcessor/manifestProcessor.h" #include "Smbus_mailbox/Smbus_mailbox.h" +#include "spi_filter/spim_util.h" #include "intel_pfr/intel_pfr_provision.h" #include "intel_pfr/intel_pfr_pfm_manifest.h" #include "intel_pfr/intel_pfr_definitions.h" +#include "intel_pfr/intel_pfr_spi_filtering.h" #include "pfr/pfr_util.h" #define SPIM_NUM 4 LOG_MODULE_DECLARE(pfr, CONFIG_LOG_DEFAULT_LEVEL); -void init_i2c_filters(void) -{ - char bus_dev_name[] = "i2cfilterx"; - const struct device *flt_dev = NULL; - - for (int i = 0; i < 4; i++) { - bus_dev_name[9] = i + '0'; - flt_dev = device_get_binding(bus_dev_name); - if (flt_dev) { - ast_i2c_filter_init(flt_dev); - ast_i2c_filter_en(flt_dev, true, false, true, true); - ast_i2c_filter_default(flt_dev, 0); - } - } -} - void apply_pfm_protection(int spi_device_id) { int status = 0; - bool i2c_flt_init = false; int spi_id = spi_device_id; const char *spim_devs[SPIM_NUM] = { "spim@1", @@ -50,8 +35,6 @@ void apply_pfm_protection(int spi_device_id) "spim@4" }; - status = spi_filter_wrapper_init(getSpiFilterEngineWrapper()); - struct spi_filter_engine_wrapper *spi_filter = getSpiFilterEngineWrapper(); char bus_dev_name[] = "i2cfilterx"; const struct device *flt_dev = NULL; @@ -84,8 +67,6 @@ void apply_pfm_protection(int spi_device_id) // Table 2-14 get Length uint32_t addr_size_of_pfm = pfm_read_address + offset + 0x1c; int region_length; - // cerberus define region_id start from 1 - int region_id = 1; uint8_t region_record[40]; #if defined(CONFIG_SEAMLESS_UPDATE) PFM_FVM_ADDRESS_DEFINITION *fvm_def; @@ -155,13 +136,12 @@ void apply_pfm_protection(int spi_device_id) } #endif - spi_filter->dev_id = spi_id; 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++; + Set_SPI_Filter_RW_Region((char *)spim_devs[spi_id], + SPI_FILTER_WRITE_PRIV, SPI_FILTER_PRIV_ENABLE, + region_start_address, region_length); LOG_INF("SPI_ID[%d] write enable 0x%08x to 0x%08x", spi_id, region_start_address, region_end_address); } else { @@ -208,9 +188,10 @@ void apply_pfm_protection(int spi_device_id) pfm_region_Start = pfm_region_Start + 16; break; case SMBUS_RULE: - if (!i2c_flt_init) { - init_i2c_filters(); - i2c_flt_init = true; + // Ignore all smbus rules in pch flash. + if (spi_device_id >= PCH_SPI) { + LOG_WRN("Found SMBUS Rules in PCH SPI, ignoring the rule."); + break; } /* SMBus Rule Definition: 0x02 */ LOG_INF("SMBus Rule Bus[%d] RuleId[%d] DeviceAddr[%x]", @@ -265,6 +246,99 @@ void apply_pfm_protection(int spi_device_id) break; } - spi_filter->base.enable_filter((struct spi_filter_interface *)spi_filter, true); + SPI_Monitor_Enable(spim_devs[spi_id], true); } +#if defined(CONFIG_SEAMLESS_UPDATE) +void apply_fvm_spi_protection(uint32_t fvm_addr, int offset) +{ + uint32_t fvm_offset = fvm_addr + offset; + uint32_t fvm_body_offset = fvm_offset + sizeof(FVM_STRUCTURE); + FVM_STRUCTURE fvm; + PFM_SPI_DEFINITION spi_def; + uint32_t fvm_body_end_addr; + uint32_t region_start_address; + uint32_t region_end_address; + int region_length; +#if defined(CONFIG_CPU_DUAL_FLASH) + int flash_size; +#endif + int spi_id = 0; + char *pch_spim_devs[2] = { + "spim@3", + "spim@4" + }; + + pfr_spi_read(PCH_SPI, fvm_offset, sizeof(FVM_STRUCTURE), (uint8_t *)&fvm); + fvm_body_end_addr = fvm_offset + fvm.Length; + + while (fvm_body_offset < fvm_body_end_addr) { + pfr_spi_read(PCH_SPI, fvm_body_offset, sizeof(PFM_SPI_DEFINITION), + (uint8_t *)&spi_def); + if (spi_def.PFMDefinitionType == SPI_REGION) { + region_start_address = spi_def.RegionStartAddress; + region_end_address = spi_def.RegionEndAddress; + region_length = region_end_address - region_start_address; +#if defined(CONFIG_CPU_DUAL_FLASH) + flash_size = pfr_spi_get_device_size(PCH_SPI); + if (region_start_address >= flash_size && (region_end_address - 1) >= flash_size) { + region_start_address -= flash_size; + region_end_address -= flash_size; + spi_id = 1; + } else if (region_start_address < flash_size && (region_end_address - 1) >= flash_size) { + LOG_ERR("ERROR: region start and end address should be in the same flash"); + return; + } else { + spi_id = 0; + } +#endif + if (spi_def.ProtectLevelMask.ReadAllowed) { + Set_SPI_Filter_RW_Region(pch_spim_devs[spi_id], SPI_FILTER_READ_PRIV, + SPI_FILTER_PRIV_ENABLE, region_start_address, + region_length); + LOG_INF("SPI_ID[2] fvm read enable 0x%08x to 0x%08x", + region_start_address, + region_end_address); + } else { + Set_SPI_Filter_RW_Region(pch_spim_devs[spi_id], SPI_FILTER_READ_PRIV, + SPI_FILTER_PRIV_DISABLE, region_start_address, + region_length); + LOG_INF("SPI_ID[2] fvm read disable 0x%08x to 0x%08x", + region_start_address, + region_end_address); + } + + if (spi_def.ProtectLevelMask.WriteAllowed) { + Set_SPI_Filter_RW_Region(pch_spim_devs[spi_id], SPI_FILTER_WRITE_PRIV, + SPI_FILTER_PRIV_ENABLE, region_start_address, + region_length); + LOG_INF("SPI_ID[2] fvm write enable 0x%08x to 0x%08x", + region_start_address, + region_end_address); + } else { + Set_SPI_Filter_RW_Region(pch_spim_devs[spi_id], SPI_FILTER_WRITE_PRIV, + SPI_FILTER_PRIV_DISABLE, region_start_address, + region_length); + LOG_INF("SPI_ID[2] fvm write disable 0x%08x to 0x%08x", + region_start_address, + region_end_address); + } + + if (spi_def.HashAlgorithmInfo.SHA256HashPresent) { + fvm_body_offset += sizeof(PFM_SPI_DEFINITION) + SHA256_SIZE; + } else if (spi_def.HashAlgorithmInfo.SHA384HashPresent) { + fvm_body_offset += sizeof(PFM_SPI_DEFINITION) + SHA384_SIZE; + } else { + fvm_body_offset += SPI_REGION_DEF_MIN_SIZE; + } + } else if (spi_def.PFMDefinitionType == FVM_CAP) { + fvm_body_offset += sizeof(FVM_CAPABLITIES); + } else { + break; + } + } + + SPI_Monitor_Enable(pch_spim_devs[spi_id], true); +} +#endif + diff --git a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_spi_filtering.h b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_spi_filtering.h index bdb06ea..3223e99 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_spi_filtering.h +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_spi_filtering.h @@ -5,6 +5,8 @@ */ #pragma once +#include void apply_pfm_protection(int spi_device_id); +void apply_fvm_spi_protection(uint32_t fvm_addr, int offset); 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 1b79911..64733c1 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_update.c +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_update.c @@ -27,6 +27,7 @@ #include "flash/flash_aspeed.h" #include "Smbus_mailbox/Smbus_mailbox.h" #include "gpio/gpio_aspeed.h" +#include "watchdog_timer/wdt_utils.h" #if defined(CONFIG_INTEL_PFR_CPLD_UPDATE) #include "intel_pfr_cpld_utils.h" #endif @@ -55,9 +56,6 @@ int pfr_staging_verify(struct pfr_manifest *manifest) (uint8_t *)&target_address, sizeof(target_address)); if (status != Success) return status; - - manifest->pc_type = PFR_BMC_UPDATE_CAPSULE; - } else if (manifest->image_type == PCH_TYPE) { LOG_INF("PCH Staging Region Verification"); status = ufm_read(PROVISION_UFM, PCH_STAGING_REGION_OFFSET, @@ -69,15 +67,6 @@ int pfr_staging_verify(struct pfr_manifest *manifest) (uint8_t *)&target_address, sizeof(target_address)); if (status != Success) return Failure; - -#if defined(CONFIG_SEAMLESS_UPDATE) - if (manifest->state == SEAMLESS_UPDATE) { - manifest->pc_type = PFR_PCH_SEAMLESS_UPDATE_CAPSULE; - } else -#endif - { - manifest->pc_type = PFR_PCH_UPDATE_CAPSULE; - } } #if defined(CONFIG_PFR_SPDM_ATTESTATION) #if (CONFIG_AFM_SPEC_VERSION == 4) @@ -86,7 +75,6 @@ int pfr_staging_verify(struct pfr_manifest *manifest) manifest->image_type = BMC_TYPE; read_address = CONFIG_BMC_AFM_STAGING_OFFSET; target_address = 0; - manifest->pc_type = PFR_AFM; afm_update = true; } #elif (CONFIG_AFM_SPEC_VERSION == 3) @@ -95,7 +83,6 @@ int pfr_staging_verify(struct pfr_manifest *manifest) manifest->image_type = BMC_TYPE; read_address = CONFIG_BMC_AFM_STAGING_OFFSET; target_address = CONFIG_BMC_AFM_RECOVERY_OFFSET; - manifest->pc_type = PFR_AFM; afm_update = true; } #endif @@ -105,7 +92,6 @@ int pfr_staging_verify(struct pfr_manifest *manifest) LOG_INF("Intel CPLD Staging Region Verification"); manifest->image_type = BMC_TYPE; read_address = CONFIG_BMC_INTEL_CPLD_STAGING_OFFSET; - manifest->pc_type = PFR_INTEL_CPLD_UPDATE_CAPSULE; cpld_update = true; } #endif @@ -113,11 +99,27 @@ int pfr_staging_verify(struct pfr_manifest *manifest) return Failure; } + status = pfr_spi_read(manifest->image_type, manifest->address + (2 * sizeof(uint32_t)), + sizeof(uint32_t), (uint8_t *)&manifest->pc_type); + if (status != Success) { + LOG_ERR("Flash read PC type failed"); + return Failure; + } + manifest->address = read_address; manifest->recovery_address = target_address; LOG_INF("Verifying capsule signature, address=0x%08x", manifest->address); // manifest verification + if (manifest->state != FIRMWARE_RECOVERY) { + status = manifest->pfr_authentication->validate_pctye(manifest); + if (status != Success) { + LOG_ERR("Validation PC Type failed, image = %d, pc_type = %x, update intent (%x, %x)", + manifest->image_type, manifest->pc_type, manifest->update_intent1, manifest->update_intent2); + return Failure; + } + } + status = manifest->base->verify((struct manifest *)manifest, manifest->hash, manifest->verification->base, manifest->pfr_hash->hash_out, manifest->pfr_hash->length); @@ -128,15 +130,6 @@ int pfr_staging_verify(struct pfr_manifest *manifest) manifest->update_fw->pc_length = manifest->pc_length; - if (afm_update == true) - manifest->pc_type = PFR_AFM; - else if (cpld_update == true) - manifest->pc_type = PFR_INTEL_CPLD_UPDATE_CAPSULE; - else if (manifest->image_type == BMC_TYPE) - manifest->pc_type = PFR_BMC_PFM; - else if (manifest->image_type == PCH_TYPE) - manifest->pc_type = PFR_PCH_PFM; - if (manifest->hash_curve == hash_sign_algo384 || manifest->hash_curve == hash_sign_algo256) manifest->address += LMS_PFM_SIG_BLOCK_SIZE; else @@ -164,7 +157,8 @@ int pfr_staging_verify(struct pfr_manifest *manifest) status = manifest->pfr_authentication->fvms_verify(manifest); } #endif - LOG_INF("Staging area verification successful"); + if (status == Success) + LOG_INF("Staging area verification successful"); if (afm_update) manifest->image_type = AFM_TYPE; @@ -174,24 +168,25 @@ int pfr_staging_verify(struct pfr_manifest *manifest) return status; } -int intel_pfr_update_verify(struct firmware_image *fw, struct hash_engine *hash, struct rsa_engine *rsa) +int intel_pfr_update_verify(const struct firmware_image *fw, struct hash_engine *hash) { ARG_UNUSED(hash); - ARG_UNUSED(rsa); struct pfr_manifest *pfr_manifest = (struct pfr_manifest *) fw; return pfr_staging_verify(pfr_manifest); } -int check_rot_capsule_type(struct pfr_manifest *manifest) +int check_rot_capsule_type(struct pfr_manifest *manifest) { int status = 0; uint32_t pc_type; status = pfr_spi_read(manifest->image_type, manifest->address + (2 * sizeof(pc_type)), sizeof(pc_type), (uint8_t *)&pc_type); + manifest->pc_type = pc_type; + if (pc_type == PFR_CPLD_UPDATE_CAPSULE_DECOMMISSON) { LOG_INF("Decommission Certificate found"); return PFR_CPLD_UPDATE_CAPSULE_DECOMMISSON; @@ -343,6 +338,7 @@ int update_afm_v40(enum AFM_PARTITION_TYPE part, uint32_t address, size_t length uint32_t source_address = address; uint32_t length_page_align; uint8_t flash_type, source_flash_type; + struct pfr_manifest *manifest = get_pfr_manifest(); length_page_align = (length % PAGE_SIZE) ? (length + (PAGE_SIZE - (length % PAGE_SIZE))) : length; @@ -352,8 +348,15 @@ int update_afm_v40(enum AFM_PARTITION_TYPE part, uint32_t address, size_t length } if (part == AFM_PART_ACT_1) { - flash_type = ROT_EXT_AFM_ACT_1; - source_flash_type = ROT_EXT_AFM_RC_1; + if (manifest->state == FIRMWARE_RECOVERY) { + flash_type = ROT_EXT_AFM_ACT_1; + source_flash_type = ROT_EXT_AFM_RC_1; + LOG_INF("to recover active region"); + } else { + flash_type = ROT_EXT_AFM_ACT_1; + source_flash_type = BMC_SPI; + LOG_INF("to update active region"); + } } else if (part == AFM_PART_RCV_1) { flash_type = ROT_EXT_AFM_RC_1; source_flash_type = BMC_SPI; @@ -392,19 +395,8 @@ int update_afm_image(struct pfr_manifest *manifest, uint32_t flash_select, void uint32_t payload_address; 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) { - LOG_ERR("Flash read PC type failed"); - return Failure; - } - - manifest->pc_type = pc_type; - LOG_INF("manifest->address=%08x", manifest->address); status = manifest->base->verify((struct manifest *)manifest, manifest->hash, manifest->verification->base, manifest->pfr_hash->hash_out, @@ -546,8 +538,6 @@ int verify_and_update_cpld_images(struct pfr_manifest *manifest, uint32_t flash_ uint32_t read_addr = manifest->address; uint32_t region_size; - manifest->pc_type = PFR_INTEL_CPLD_UPDATE_CAPSULE; - if (manifest->pfr_authentication->online_update_cap_verify(manifest)) { LOG_ERR("Verify BMC's CPLD staging region failed"); return Failure; @@ -595,26 +585,14 @@ int verify_and_update_cpld_images(struct pfr_manifest *manifest, uint32_t flash_ } #endif -int ast1060_update(struct pfr_manifest *manifest, uint32_t flash_select) +int ast1060_update(struct pfr_manifest *manifest, uint32_t flash_select, uint32_t 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) { - LOG_ERR("Flash read PC type failed"); - return Failure; - } - - manifest->pc_type = pc_type; - LOG_INF("manifest->address=%x", manifest->address); status = manifest->base->verify((struct manifest *)manifest, manifest->hash, manifest->verification->base, manifest->pfr_hash->hash_out, @@ -626,7 +604,6 @@ int ast1060_update(struct pfr_manifest *manifest, uint32_t flash_select) } LOG_INF("ROT update capsule verification success"); - pc_type_status = check_rot_capsule_type(manifest); if (manifest->hash_curve == hash_sign_algo384 || manifest->hash_curve == hash_sign_algo256) payload_address = manifest->address + LMS_PFM_SIG_BLOCK_SIZE; else @@ -645,9 +622,9 @@ int ast1060_update(struct pfr_manifest *manifest, uint32_t flash_select) return Failure; } - status = manifest->keystore->kc_flag->cancel_kc_flag(manifest, cancelled_id); + status = manifest->keystore->kc_flag->cancel_kc_flag(manifest, (uint8_t)cancelled_id); if (status == Success) - LOG_INF("Key cancellation success. Key Id :%d was cancelled", cancelled_id); + LOG_INF("Key cancellation success. Key Id :%d was cancelled", (uint8_t)cancelled_id); return status; } else if (pc_type_status == PFR_CPLD_UPDATE_CAPSULE) { @@ -688,13 +665,13 @@ 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, - CPLD_STATUS *cpld_update_status) + CPLD_STATUS *cpld_update_status, struct event_context *evt_ctx) { int status = 0; uint32_t source_address, target_address, area_size; - uint32_t act_pfm_offset; - uint32_t address = 0; + uint32_t act_pfm_offset = 0; uint32_t pc_type_status = 0; + uint32_t update_type; uint8_t staging_svn = 0; AO_DATA *ActiveObjectData = (AO_DATA *) AoData; DECOMPRESSION_TYPE_MASK_ENUM decomp_event; @@ -712,14 +689,13 @@ int update_firmware_image(uint32_t image_type, void *AoData, void *EventContext, pfr_manifest->flash_id = flash_select; if (pfr_manifest->image_type == ROT_TYPE) { + update_type = ROT_TYPE; pfr_manifest->image_type = BMC_TYPE; - pfr_manifest->address = CONFIG_BMC_PFR_STAGING_OFFSET; - if (cpld_update_status->Region[ROT_REGION].Recoveryregion == RECOVERY_PENDING_REQUEST_HANDLED) - cpld_update_status->Region[ROT_REGION].Recoveryregion = 0; - return ast1060_update(pfr_manifest, flash_select); + source_address = CONFIG_BMC_PFR_STAGING_OFFSET; } else if (pfr_manifest->image_type == BMC_TYPE) { LOG_INF("BMC Update in progress"); + update_type = BMC_TYPE; if (ufm_read(PROVISION_UFM, BMC_STAGING_REGION_OFFSET, (uint8_t *)&source_address, sizeof(source_address))) return Failure; @@ -728,9 +704,17 @@ int update_firmware_image(uint32_t image_type, void *AoData, void *EventContext, return Failure; } else if (pfr_manifest->image_type == PCH_TYPE) { LOG_INF("PCH Update in progress"); - if (ufm_read(PROVISION_UFM, PCH_STAGING_REGION_OFFSET, (uint8_t *)&source_address, - sizeof(source_address))) - return Failure; + update_type = PCH_TYPE; + if (cpld_update_status->BmcToPchStatus == 1) { + pfr_manifest->image_type = BMC_TYPE; + if (ufm_read(PROVISION_UFM, BMC_STAGING_REGION_OFFSET, (uint8_t *)&source_address, + sizeof(source_address))) + return Failure; + } else { + 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; @@ -738,19 +722,17 @@ int update_firmware_image(uint32_t image_type, void *AoData, void *EventContext, #if defined(CONFIG_PFR_SPDM_ATTESTATION) else if (pfr_manifest->image_type == AFM_TYPE) { LOG_INF("AFM Update in progress"); + update_type = AFM_TYPE; pfr_manifest->image_type = BMC_TYPE; - pfr_manifest->address = CONFIG_BMC_AFM_STAGING_OFFSET; - if (cpld_update_status->Region[AFM_REGION].Recoveryregion == RECOVERY_PENDING_REQUEST_HANDLED) - cpld_update_status->Region[AFM_REGION].Recoveryregion = 0; - return update_afm_image(pfr_manifest, flash_select, ActiveObjectData); + source_address = CONFIG_BMC_AFM_STAGING_OFFSET; } #endif #if defined(CONFIG_INTEL_PFR_CPLD_UPDATE) else if (pfr_manifest->image_type == CPLD_TYPE) { LOG_INF("SCM/CPU/Debug CPLD Update in progress"); + update_type = CPLD_TYPE; pfr_manifest->image_type = BMC_TYPE; - pfr_manifest->address = CONFIG_BMC_INTEL_CPLD_STAGING_OFFSET; - return verify_and_update_cpld_images(pfr_manifest, flash_select, ActiveObjectData); + source_address = CONFIG_BMC_INTEL_CPLD_STAGING_OFFSET; } #endif else { @@ -758,38 +740,80 @@ int update_firmware_image(uint32_t image_type, void *AoData, void *EventContext, return Failure; } + pfr_manifest->address = source_address; pfr_manifest->staging_address = source_address; pfr_manifest->active_pfm_addr = act_pfm_offset; + pc_type_status = check_rot_capsule_type(pfr_manifest); - if (image_type == PCH_TYPE && cpld_update_status->BmcToPchStatus == 1) { + // Checking for key cancellation + if (pc_type_status == KEY_CANCELLATION_CAPSULE) { + // Key cancellation is allowed in any update intent. + // If users issue recovery intent with key cancellation capsule, + // the pending recovery flag should be cleared. + if (pfr_manifest->update_intent1 & PchRecoveryUpdate) { + if (cpld_update_status->BmcToPchStatus == 1) + cpld_update_status->BmcToPchStatus = 0; + cpld_update_status->Region[PCH_REGION].Recoveryregion = 0; + } else if (pfr_manifest->update_intent1 & BmcRecoveryUpdate) { + cpld_update_status->Region[BMC_REGION].Recoveryregion = 0; + } else if (pfr_manifest->update_intent2 & AfmRecoveryUpdate) { + cpld_update_status->Region[AFM_REGION].Recoveryregion = 0; + } + if (pfr_manifest->pc_type == PCH_PFM_CANCELLATION) { + LOG_INF("execute PCH PFM key cancellation, to hold PCH"); + PCHBootHold(); + // to remove BmcOnlyReset bit for booting BMC and PCH + if (evt_ctx->data.bit8[2] == BmcOnlyReset) + evt_ctx->data.bit8[2] &= ~BmcOnlyReset; + } + update_type = ROT_TYPE; + } + + /* ROT_TYPE doesn't use AoData pointer, to ignore the NULL pointer checking */ + if ((update_type != ROT_TYPE) && (AoData == NULL)) { + LOG_ERR("Active Object is NULL"); + return Failure; + } + + if (update_type == ROT_TYPE) { + if (cpld_update_status->Region[ROT_REGION].Recoveryregion == RECOVERY_PENDING_REQUEST_HANDLED) + cpld_update_status->Region[ROT_REGION].Recoveryregion = 0; + return ast1060_update(pfr_manifest, flash_select, pc_type_status); + } +#if defined(CONFIG_PFR_SPDM_ATTESTATION) + else if (update_type == AFM_TYPE) { + if (cpld_update_status->Region[AFM_REGION].Recoveryregion == RECOVERY_PENDING_REQUEST_HANDLED) + cpld_update_status->Region[AFM_REGION].Recoveryregion = 0; + return update_afm_image(pfr_manifest, flash_select, ActiveObjectData); + } +#endif +#if defined(CONFIG_INTEL_PFR_CPLD_UPDATE) + else if (update_type == CPLD_TYPE) { + return verify_and_update_cpld_images(pfr_manifest, flash_select, ActiveObjectData); + } +#endif + else if (update_type >= MAX_SUPPORTED_FW_TYPE) { + return Failure; + } + + if (update_type == PCH_TYPE && cpld_update_status->BmcToPchStatus == 1) { cpld_update_status->BmcToPchStatus = 0; + if (ufm_read(PROVISION_UFM, PCH_STAGING_REGION_OFFSET, (uint8_t *)&source_address, + sizeof(source_address))) { + LOG_ERR("Failed to get PCH staging offset"); + return Failure; + } + pfr_manifest->image_type = update_type; + pfr_manifest->address = source_address; // It is not necessary to copy image from bmc's staging to pch's staging again // for handling the pending recovery update. if (cpld_update_status->Region[PCH_REGION].Recoveryregion != RECOVERY_PENDING_REQUEST_HANDLED) { - status = ufm_read(PROVISION_UFM, BMC_STAGING_REGION_OFFSET, - (uint8_t *)&address, sizeof(address)); - if (status != Success) - return Failure; - - 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) return Failure; } } - pfr_manifest->address = source_address; - // Checking for key cancellation - pc_type_status = check_rot_capsule_type(pfr_manifest); - if (pc_type_status == KEY_CANCELLATION_CAPSULE) - return ast1060_update(pfr_manifest, PRIMARY_FLASH_REGION); - // Staging area verification LOG_INF("Staging Area verification"); status = pfr_manifest->update_fw->base->verify((struct firmware_image *)pfr_manifest, @@ -916,7 +940,8 @@ int perform_seamless_update(uint32_t image_type, void *AoData, void *EventContex CPLD_STATUS cpld_update_status; const struct device *dev_m = NULL; #if defined(CONFIG_BMC_DUAL_FLASH) - uint32_t flash_size = flash_get_flash_size("spi1_cs0"); + const struct device *flash_dev = device_get_binding("spi1@0"); + uint32_t flash_size = flash_get_flash_size(flash_dev); uint32_t staging_start_addr; #endif @@ -982,24 +1007,35 @@ int perform_seamless_update(uint32_t image_type, void *AoData, void *EventContex #endif spim_ext_mux_config(dev_m, SPIM_EXT_MUX_ROT); - pfr_manifest->address = address; - - // Checking for key cancellation pfr_manifest->image_type = BMC_TYPE; + pfr_manifest->address = address; 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) - goto release_both_muxes; + if (pc_type_status == KEY_CANCELLATION_CAPSULE) { + // Key cancellation is allowed in any update intent. + status = ast1060_update(pfr_manifest, PRIMARY_FLASH_REGION, pc_type_status); + goto release_both_muxes; + } else { + pfr_manifest->image_type = image_type; + pfr_manifest->address = address; + status = pfr_staging_pch_staging(pfr_manifest); + if (status != Success) + goto release_both_muxes; + } // Release BMC SPI after copying capsule to PCH's flash. // PCH SPI will be release after firmware update completed. LOG_INF("Switch BMC SPI MUX to BMC"); spim_ext_mux_config(dev_m, SPIM_EXT_MUX_BMC_PCH); + } else { + pc_type_status = check_rot_capsule_type(pfr_manifest); + // Checking for key cancellation + if (pc_type_status == KEY_CANCELLATION_CAPSULE) { + // Key cancellation is allowed in any update intent. + status = ast1060_update(pfr_manifest, PRIMARY_FLASH_REGION, pc_type_status); + goto release_pch_mux; + } } - pfr_manifest->address = source_address; // Staging area verification LOG_INF("Staging Area verification"); @@ -1010,10 +1046,18 @@ int perform_seamless_update(uint32_t image_type, void *AoData, void *EventContex goto release_pch_mux; } + LOG_INF("Decompressing seamless capsule"); status = decompress_fv_capsule(pfr_manifest); if (status != Success) LOG_ERR("Failed to decompress seamless capsule"); + // ROT finish the seamless update and check the most significant bit of the update intent. + // ROT wait up to ‘x’ ( Eg: 30sec) seconds for this significant bit to be cleared, + // if not cleared, ROT issue BMC reset. + if (GetBmcUpdateIntent2() & SeamlessUpdateAck) + pfr_start_timer(BMC_TIMER, 30000); + + LOG_INF("Seamless update completed"); goto release_pch_mux; release_both_muxes: @@ -1046,12 +1090,11 @@ int perform_seamless_update(uint32_t image_type, void *AoData, void *EventContex * * @param fw The firmware image to validate. * @param hash The hash engine to use for validation. - * @param rsa The RSA engine to use for signature checking. * * @return 0 if the firmware image is valid or an error code. */ -int firmware_image_verify(struct firmware_image *fw, struct hash_engine *hash, struct rsa_engine *rsa) +int firmware_image_verify(const struct firmware_image *fw, struct hash_engine *hash) { - return intel_pfr_update_verify(fw, hash, rsa); + return intel_pfr_update_verify(fw, hash); } 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 7e0716f..bc6b434 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_update.h +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_update.h @@ -24,12 +24,12 @@ int update_afm(enum AFM_PARTITION_TYPE part, uint32_t address, size_t length); int update_cpld_image(struct pfr_manifest *manifest); #endif -int intel_pfr_update_verify(struct firmware_image *fw, struct hash_engine *hash, struct rsa_engine *rsa); -int update_firmware_image(uint32_t image_type, void *AoData, void *EventContext, CPLD_STATUS *cpld_update_status); +int intel_pfr_update_verify(const struct firmware_image *fw, struct hash_engine *hash); +int update_firmware_image(uint32_t image_type, void *AoData, void *EventContext, CPLD_STATUS *cpld_update_status, struct event_context *evt_ctx); #if defined(CONFIG_SEAMLESS_UPDATE) int perform_seamless_update(uint32_t image_type, void *AoData, void *EventContext); #endif -int firmware_image_verify(struct firmware_image *fw, struct hash_engine *hash, struct rsa_engine *rsa); +int firmware_image_verify(const struct firmware_image *fw, struct hash_engine *hash); 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 577189b..10c78da 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_verification.c +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_verification.c @@ -176,8 +176,6 @@ int intel_pfr_manifest_verify(struct manifest *manifest, struct hash_engine *has ARG_UNUSED(hash_out); ARG_UNUSED(hash_length); - init_pfr_authentication(pfr_manifest->pfr_authentication); - 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_INF("pfr_manifest->image_type=%d address=0x%08x", pfr_manifest->image_type, pfr_manifest->address + BLOCK0_PCTYPE_ADDRESS); @@ -185,13 +183,9 @@ int intel_pfr_manifest_verify(struct manifest *manifest, struct hash_engine *has return Failure; } + pfr_manifest->pc_type = pc_type; LOG_INF("pfr_manifest->image_type=%d address=0x%08x pc_type=%x", pfr_manifest->image_type, pfr_manifest->address + BLOCK0_PCTYPE_ADDRESS, pc_type); - // Validate 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); if (status != Success) @@ -210,19 +204,62 @@ int intel_pfr_manifest_verify(struct manifest *manifest, struct hash_engine *has return status; } -int validate_pc_type(struct pfr_manifest *manifest, uint32_t pc_type) +int validate_pc_type(struct pfr_manifest *manifest) { - if (pc_type != manifest->pc_type && manifest->pc_type != PFR_PCH_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; + int ret = Failure; + + if (manifest->pc_type == CPLD_CAPSULE_CANCELLATION) + return Success; + else if (manifest->pc_type == PFR_CPLD_UPDATE_CAPSULE_DECOMMISSON || + (manifest->pc_type & PFR_CPLD_UPDATE_CAPSULE)) + return (manifest->update_intent1 & HROTActiveAndRecoveryUpdate) ? Success : Failure; + else if (manifest->pc_type == PFR_BMC_UPDATE_CAPSULE) { + if (manifest->update_intent1 & BmcActiveAndRecoveryUpdate && + (manifest->image_type == BMC_TYPE)) { + ret = Success; + } + return ret; } + else if (manifest->pc_type == PFR_PCH_UPDATE_CAPSULE) { + if (manifest->update_intent1 & PchActiveAndRecoveryUpdate && + (manifest->image_type == PCH_TYPE)) { + ret = Success; + } + return ret; + } + else if (manifest->pc_type == PFR_CPLD_UPDATE_CAPSULE) + return (manifest->update_intent1 & HROTActiveAndRecoveryUpdate) ? Success : Failure; +#if defined(CONFIG_SEAMLESS_UPDATE) + else if (manifest->pc_type == PFR_PCH_SEAMLESS_UPDATE_CAPSULE) + return (manifest->update_intent2 & SeamlessUpdate) ? Success : Failure; +#endif +#if defined(CONFIG_INTEL_PFR_CPLD_UPDATE) + else if (manifest->pc_type == PFR_INTEL_CPLD_UPDATE_CAPSULE) + return (manifest->update_intent2 & CPLDUpdate) ? Success : Failure; +#endif +#if defined(CONFIG_PFR_SPDM_ATTESTATION) +#if (CONFIG_AFM_SPEC_VERSION == 4) + else if (manifest->pc_type == PFR_AFM) + return (manifest->update_intent2 & AfmActiveUpdate) ? Success : Failure; + else if (manifest->pc_type == PFR_AFM_PER_DEV) + return (manifest->update_intent2 & AfmRecoveryUpdate) ? Success : Failure; + else if (manifest->pc_type == PFR_AFM_ADD_TO_UPDATE) + return (manifest->update_intent2 & AfmActiveAddToUpdate) ? Success : Failure; +#elif (CONFIG_AFM_SPEC_VERSION == 3) + else if (manifest->pc_type == PFR_AFM) + return (manifest->update_intent2 & AfmActiveAndRecoveryUpdate) ? Success : Failure; +#endif +#endif - return Success; + return Failure; } + +#if defined(CONFIG_MBEDTLS_LMS_C) #include "mbedtls/lms.h" #include "lmots.h" +#endif + int intel_block1_block0_entry_verify_lms(struct pfr_manifest *manifest, void *input, int hash_length) { #if defined(CONFIG_MBEDTLS_LMS_C) @@ -489,6 +526,12 @@ int intel_block1_csk_block0_entry_verify(struct pfr_manifest *manifest) return Failure; } + status = pfr_spi_read(manifest->image_type, manifest->address + (2 * sizeof(uint32_t)), + sizeof(uint32_t), (uint8_t *)&manifest->pc_type); + if (status != Success) { + LOG_ERR("Flash read PC type failed"); + return Failure; + } // Key permission if (manifest->pc_type == PFR_BMC_UPDATE_CAPSULE) {// Bmc update sign_bit_verify = SIGN_BMC_UPDATE_BIT3; @@ -1015,6 +1058,11 @@ int intel_cfms_verify(struct pfr_manifest *manifest) cfm_offset += offset; pfr_spi_read(image_type, cfm_offset, sizeof(CFM_STRUCTURE), (uint8_t *)&cfm_header); + if (cfm_header.CfmTag != CFMTAG) { + LOG_ERR("CFMTag verification failed...\n expected: %x\n actual: %x", + CFMTAG, cfm_header.CfmTag); + return Failure; + } if (cpld_addr_def.FwType != cfm_header.FwType) { LOG_ERR("Incorrect capsule format"); return Failure; 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 f9685c2..e428840 100644 --- a/apps/aspeed-pfr/src/intel_pfr/intel_pfr_verification.h +++ b/apps/aspeed-pfr/src/intel_pfr/intel_pfr_verification.h @@ -214,6 +214,7 @@ enum { PFR_AFM, PFR_INTEL_CPLD_UPDATE_CAPSULE, PFR_AFM_PER_DEV, + PFR_AFM_ADD_TO_UPDATE = 0x0A, PFR_CPLD_UPDATE_CAPSULE_DECOMMISSON = 0x200 }; @@ -237,7 +238,7 @@ enum { }; struct pfr_authentication { - int (*validate_pctye)(struct pfr_manifest *manifest, uint32_t pc_type); + int (*validate_pctye)(struct pfr_manifest *manifest); int (*validate_kc)(struct pfr_manifest *manifest); int (*block1_block0_entry_verify)(struct pfr_manifest *manifest); int (*block1_csk_block0_entry_verify)(struct pfr_manifest *manifest); diff --git a/apps/aspeed-pfr/src/mctp/CMakeLists.txt b/apps/aspeed-pfr/src/mctp/CMakeLists.txt index 990e6be..42572bc 100644 --- a/apps/aspeed-pfr/src/mctp/CMakeLists.txt +++ b/apps/aspeed-pfr/src/mctp/CMakeLists.txt @@ -9,6 +9,7 @@ target_sources(app PRIVATE ) target_sources_ifdef(CONFIG_PFR_MCTP_I3C app PRIVATE mctp_i3c.c) +target_sources_ifdef(CONFIG_PFR_MCTP_I3C_5_0 app PRIVATE mctp_i3c_target.c) if(CONFIG_SHELL) target_sources(app PRIVATE test_mctp_shell.c) diff --git a/apps/aspeed-pfr/src/mctp/cmd_channel_mctp.c b/apps/aspeed-pfr/src/mctp/cmd_channel_mctp.c index 2573f3b..4e53efd 100644 --- a/apps/aspeed-pfr/src/mctp/cmd_channel_mctp.c +++ b/apps/aspeed-pfr/src/mctp/cmd_channel_mctp.c @@ -9,7 +9,7 @@ #include #include "cmd_interface/cmd_channel.h" #include "cmd_channel_mctp.h" -#include "mctp_utils.h" +#include "mctp.h" LOG_MODULE_REGISTER(cmd_channel_mctp, CONFIG_LOG_DEFAULT_LEVEL); diff --git a/apps/aspeed-pfr/src/mctp/mctp.c b/apps/aspeed-pfr/src/mctp/mctp.c index 83e84d0..9c383d3 100644 --- a/apps/aspeed-pfr/src/mctp/mctp.c +++ b/apps/aspeed-pfr/src/mctp/mctp.c @@ -6,14 +6,12 @@ #include #include -#include "i2c/hal_i2c.h" #include "plat_mctp.h" LOG_MODULE_REGISTER(mctp, CONFIG_LOG_DEFAULT_LEVEL); void init_pfr_mctp(void) { - util_init_I2C(); plat_mctp_init(); } diff --git a/apps/aspeed-pfr/src/mctp/mctp.h b/apps/aspeed-pfr/src/mctp/mctp.h index a680b32..199272e 100644 --- a/apps/aspeed-pfr/src/mctp/mctp.h +++ b/apps/aspeed-pfr/src/mctp/mctp.h @@ -5,13 +5,134 @@ */ #pragma once -#include -#include "cmd_interface/device_manager.h" +#include +#include +#include +#include "mctp/mctp_interface_wrapper.h" +#include "cmd_interface/cmd_channel.h" -void set_prev_mctp_i3c_state(int state); -int mctp_i3c_detach_slave_dev(uint8_t bus, uint64_t pid); -int mctp_i3c_attach_target_dev(uint8_t bus, uint64_t pid); -void mctp_i3c_stop_discovery_notify(struct device_manager *mgr); +#define MCTP_SUCCESS 0 +#define MCTP_ERROR 1 +#define MCTP_TX_QUEUE_SIZE 16 +#define MCTP_RX_TASK_STACK_SIZE 2048 +#define MCTP_TX_TASK_STACK_SIZE 2048 +#define MCTP_TASK_NAME_LEN 32 + +#define MCTP_I3C_STATE_HANDLER_STACK_SIZE 4096 + +typedef enum { + MCTP_MEDIUM_TYPE_UNKNOWN = 0, + MCTP_MEDIUM_TYPE_SMBUS, + MCTP_MEDIUM_TYPE_I3C, + MCTP_MEDIUM_TYPE_I3C_TARGET, + MCTP_MEDIUM_TYPE_MAX +} MCTP_MEDIUM_TYPE; + +/* smbus extra medium data of endpoint */ +typedef struct _mctp_smbus_ext_params { + uint8_t addr; /* 7 bit address */ +} mctp_smbus_ext_params; + +/* mctp extra parameters prototype */ +typedef struct _mctp_ext_params { + /* medium parameters */ + MCTP_MEDIUM_TYPE type; + union { + mctp_smbus_ext_params smbus_ext_params; + }; +} mctp_ext_params; + +/* medium write/read function prototype */ +typedef uint16_t (*medium_tx)(void *mctp_p, void *msg_p); +typedef uint16_t (*medium_rx)(void *mctp_p, void *msg_p); + +/* i3c config for mctp medium_conf */ +typedef struct _mctp_i3c_conf { + uint8_t bus; + uint8_t addr; + uint8_t dummy; +} mctp_i3c_conf; + +/* smbus config for mctp medium_conf */ +typedef struct _mctp_smbus_conf { + uint8_t bus; + uint8_t rot_addr; + uint8_t mbx_port; +} mctp_smbus_conf; + +/* mctp medium conf */ +typedef union { + mctp_smbus_conf smbus_conf; + mctp_i3c_conf i3c_conf; +} mctp_medium_conf; + +/* mctp tx message struct */ +typedef struct _mctp_tx_msg { + uint8_t *buf; + size_t len; + mctp_ext_params ext_params; +} mctp_tx_msg; + +/* mctp main struct */ +typedef struct _mctp { + uint8_t is_servcie_start; + MCTP_MEDIUM_TYPE medium_type; + + /* medium related */ + mctp_medium_conf medium_conf; + medium_rx read_data; + medium_tx write_data; + + /* read/write task */ + k_tid_t mctp_rx_task_tid; + k_tid_t mctp_tx_task_tid; + struct k_thread rx_task_thread_data; + struct k_thread tx_task_thread_data; + + K_KERNEL_STACK_MEMBER(rx_task_stack_area, MCTP_RX_TASK_STACK_SIZE); + K_KERNEL_STACK_MEMBER(tx_task_stack_area, MCTP_TX_TASK_STACK_SIZE); + uint8_t mctp_rx_task_name[MCTP_TASK_NAME_LEN]; + uint8_t mctp_tx_task_name[MCTP_TASK_NAME_LEN]; + + /* queue */ + struct k_msgq mctp_tx_queue; + + /* interface */ + struct mctp_interface_wrapper mctp_wrapper; + + /* command channel */ + struct cmd_channel mctp_cmd_channel; + + /* semaphore */ + struct k_sem rx_fifo_in_data_sem; + + /* sw mailbox device */ + const struct device *sw_mbx_dev; +} mctp; + +/* public function */ void init_pfr_mctp(void); +mctp *mctp_init(void); +uint8_t mctp_deinit(mctp *mctp_inst); +uint8_t mctp_set_medium_configure(mctp *mctp_inst, MCTP_MEDIUM_TYPE medium_type, + mctp_medium_conf medium_conf); + +/* medium_conf should be freed by application */ +uint8_t mctp_get_medium_configure(mctp *mctp_inst, MCTP_MEDIUM_TYPE *medium_type, + mctp_medium_conf *medium_conf); +/* mctp service start */ +uint8_t mctp_start(mctp *mctp_inst); + +/* mctp service stop */ +uint8_t mctp_stop(mctp *mctp_inst); + +/* send/receive message to destination endpoint */ +uint8_t mctp_send_msg(mctp *mctp_inst, struct cmd_packet *packet); +uint8_t mctp_recv_msg(mctp *mctp_inst, struct cmd_packet *packet); + +/* medium init/deinit */ +uint8_t mctp_smbus_init(mctp *mctp_inst, mctp_medium_conf medium_conf); +uint8_t mctp_smbus_deinit(mctp *mctp_inst); + diff --git a/apps/aspeed-pfr/src/mctp/mctp_i3c.c b/apps/aspeed-pfr/src/mctp/mctp_i3c.c index 46a12b5..2a1bfb5 100644 --- a/apps/aspeed-pfr/src/mctp/mctp_i3c.c +++ b/apps/aspeed-pfr/src/mctp/mctp_i3c.c @@ -22,11 +22,15 @@ #include #include #include -#include "mctp_utils.h" +#include +#include +#include "mctp.h" +#include "mctp_i3c.h" #include "gpio/gpio_aspeed.h" #include "Smbus_mailbox/Smbus_mailbox.h" #include "AspeedStateMachine/AspeedStateMachine.h" #include "SPDM/SPDMRequester.h" +#include "i3c/i3c_util.h" #include "mctp/mctp_base_protocol.h" #include "cmd_channel_mctp.h" @@ -38,31 +42,74 @@ LOG_MODULE_REGISTER(mctp_i3c); #define I3C_2 DEVICE_DT_NAME(DT_NODELABEL(i3c2)) #define I3C_3 DEVICE_DT_NAME(DT_NODELABEL(i3c3)) -#define MCTP_DISCOVERY_NOTIFY_STACK_SIZE 4096 -#define MCTP_I3C_MSG_RETRY_INTERVAL 12 - +#define MCTP_I3C_CPU0_EID 0x1D +#define MCTP_I3C_CPU1_EID 0x9D #define MCTP_I3C_REGISTRATION_EID 0x1D #define MCTP_DOE_REGISTRATION_CMD 0x4 - static uint8_t i3c_data_in[256]; static uint8_t mctp_msg_buf[MCTP_BASE_PROTOCOL_MAX_MESSAGE_LEN]; -// const struct device *mctp_i3c_dev; -struct i3c_device_desc *mctp_i3c_bmc_desc = NULL; -struct i3c_device_desc *mctp_i3c_cpu_desc = NULL; -mctp *mctp_i3c_bmc_inst = NULL; -mctp *mctp_i3c_cpu_inst = NULL; -struct k_thread mctp_i3c_discovery_notify_thread; -K_THREAD_STACK_DEFINE(mctp_i3c_discovery_notify_stack, MCTP_DISCOVERY_NOTIFY_STACK_SIZE); +mctp_i3c mctp_i3c_bmc_inst = {0}; +mctp_i3c mctp_i3c_cpu0_inst = {0}; +mctp_i3c mctp_i3c_cpu1_inst = {0}; +bool i3c_hub_configured = false; static void mctp_i3c_req_timeout_callback(struct k_timer *tmr); K_TIMER_DEFINE(mctp_i3c_req_timer, mctp_i3c_req_timeout_callback, NULL); K_SEM_DEFINE(ibi_complete, 0, 1); +K_SEM_DEFINE(cpu0_ibi_complete, 0, 1); +K_SEM_DEFINE(cpu1_ibi_complete, 0, 1); +K_SEM_DEFINE(hub_ibi_complete, 0, 1); K_SEM_DEFINE(mctp_i3c_sem, 0, 1); -bool i3c_bmc_dev_attached = false; -static const struct device *get_mctp_i3c_dev(uint8_t bus_num) +static int mctp_i3c_sem_give(struct i3c_device_desc *target) +{ + switch(target->pid) { + case CONFIG_PFR_SPDM_I3C_BMC_DEV_PID: + k_sem_give(&ibi_complete); + break; + case CONFIG_PFR_SPDM_I3C_CPU0_DEV_PID: + k_sem_give(&cpu0_ibi_complete); + break; + case CONFIG_PFR_SPDM_I3C_CPU1_DEV_PID: + k_sem_give(&cpu1_ibi_complete); + break; + case CONFIG_PFR_SPDM_I3C_HUB_DEV_PID: + k_sem_give(&hub_ibi_complete); + break; + default: + LOG_ERR("Unknown pid"); + break; + } + + return 0; +} + +static int mctp_i3c_sem_take(struct i3c_device_desc *target) +{ + switch(target->pid) { + case CONFIG_PFR_SPDM_I3C_BMC_DEV_PID: + k_sem_take(&ibi_complete, K_FOREVER); + break; + case CONFIG_PFR_SPDM_I3C_CPU0_DEV_PID: + k_sem_take(&cpu0_ibi_complete, K_FOREVER); + break; + case CONFIG_PFR_SPDM_I3C_CPU1_DEV_PID: + k_sem_take(&cpu1_ibi_complete, K_FOREVER); + break; + case CONFIG_PFR_SPDM_I3C_HUB_DEV_PID: + k_sem_take(&hub_ibi_complete, K_FOREVER); + break; + default: + LOG_ERR("Unknown pid"); + break; + } + + return 0; +} + +const struct device *get_mctp_i3c_dev(uint8_t bus_num) { switch(bus_num) { case 0: @@ -163,8 +210,8 @@ int mctp_i3c_send_discovery_notify(mctp *mctp_instance, int *duration) uint8_t req_buf[3] = {MCTP_BASE_PROTOCOL_MSG_TYPE_CONTROL_MSG, 0x81, 0x0d}; mctp_interface_issue_request(mctp_interface, &mctp_instance->mctp_cmd_channel, - mctp_i3c_bmc_desc->dynamic_addr, 0, req_buf, sizeof(req_buf), mctp_msg_buf, - sizeof(mctp_msg_buf), 1); + mctp_instance->medium_conf.i3c_conf.addr, 0, req_buf, sizeof(req_buf), + mctp_msg_buf, sizeof(mctp_msg_buf), 1); *duration = MCTP_I3C_MSG_RETRY_INTERVAL; @@ -173,7 +220,9 @@ int mctp_i3c_send_discovery_notify(mctp *mctp_instance, int *duration) int mctp_i3c_send_eid_announcement(mctp *mctp_instance, int *duration) { - int status; + int status = -1; + uint8_t dest_eid; + struct mctp_interface_wrapper *mctp_wrapper = &mctp_instance->mctp_wrapper; struct mctp_interface *mctp_interface = &mctp_wrapper->mctp_interface; struct device_manager *device_mgr = mctp_interface->device_manager; @@ -182,18 +231,20 @@ int mctp_i3c_send_eid_announcement(mctp *mctp_instance, int *duration) uint8_t req_buf[14] = {MCTP_BASE_PROTOCOL_MSG_TYPE_VENDOR_DEF, 0x80, 0x86, 0x80, 0x0a, 0x00, 0x00, 0x00, 0x00, MCTP_DOE_REGISTRATION_CMD, 0x00, 0x00, 0x01, src_eid}; - if (get_i3c_mng_owner() == I3C_MNG_OWNER_BMC) { - status = mctp_interface_issue_request(mctp_interface, &mctp_instance->mctp_cmd_channel, - mctp_i3c_bmc_desc->dynamic_addr, MCTP_I3C_REGISTRATION_EID, req_buf, - sizeof(req_buf), mctp_msg_buf, sizeof(mctp_msg_buf), 12000); + if (mctp_instance == mctp_i3c_bmc_inst.mctp_inst) { + dest_eid = MCTP_I3C_REGISTRATION_EID; + } else if (mctp_instance == mctp_i3c_cpu0_inst.mctp_inst) { + dest_eid = MCTP_I3C_CPU0_EID; + } else if (mctp_instance == mctp_i3c_cpu1_inst.mctp_inst) { + dest_eid = MCTP_I3C_CPU1_EID; } else { - uint8_t dest_eid = device_manager_get_device_eid(device_mgr, - DEVICE_MANAGER_MCTP_BRIDGE_DEVICE_NUM); - status = mctp_interface_issue_request(mctp_interface, &mctp_instance->mctp_cmd_channel, - mctp_i3c_cpu_desc->dynamic_addr, dest_eid, req_buf, - sizeof(req_buf), mctp_msg_buf, sizeof(mctp_msg_buf), 12000); + return status; } + status = mctp_interface_issue_request(mctp_interface, &mctp_instance->mctp_cmd_channel, + mctp_instance->medium_conf.i3c_conf.addr, dest_eid, req_buf, + sizeof(req_buf), mctp_msg_buf, sizeof(mctp_msg_buf), 12000); + if (status == 0) { device_manager_update_device_state(device_mgr, DEVICE_MANAGER_SELF_DEVICE_NUM, @@ -207,25 +258,38 @@ int mctp_i3c_send_eid_announcement(mctp *mctp_instance, int *duration) void mctp_i3c_state_handler(void *a, void *b, void *c) { - mctp *mctp_instance = mctp_i3c_bmc_inst; + mctp_i3c *mctp_i3c_instance = a; + mctp *mctp_instance = mctp_i3c_instance->mctp_inst; struct mctp_interface_wrapper *mctp_wrapper = &mctp_instance->mctp_wrapper; struct device_manager *device_mgr = mctp_wrapper->mctp_interface.device_manager; int dev_state; int duration = MCTP_I3C_MSG_RETRY_INTERVAL; + int owner; + uint8_t stat; while (1) { - k_sem_take(&mctp_i3c_sem, K_FOREVER); + k_sem_take(&mctp_i3c_instance->i3c_state_sem, K_FOREVER); + owner = get_i3c_mng_owner(); dev_state = device_manager_get_device_state(device_mgr, DEVICE_MANAGER_SELF_DEVICE_NUM); if (dev_state == DEVICE_MANAGER_SEND_DISCOVERY_NOTIFY) { LOG_DBG("Send discovery notify"); - mctp_i3c_send_discovery_notify( mctp_instance, &duration); + stat = (I3C_MNG_OWNER_BMC == owner) ? + PFR_ACT1_DAA_I3C_BMC : PFR_ACT1_DAA_I3C_CPU; + SetPfrActivityInfo1(stat); + mctp_i3c_send_discovery_notify(mctp_instance, &duration); } else if (dev_state == DEVICE_MANAGER_EID_ANNOUNCEMENT) { LOG_DBG("Announce EID"); + stat = (I3C_MNG_OWNER_BMC == owner) ? + PFR_ACT1_SET_EID_I3C_BMC : PFR_ACT1_SET_EID_I3C_CPU; + SetPfrActivityInfo1(stat); mctp_i3c_send_eid_announcement(mctp_instance, &duration); } #if defined(CONFIG_PFR_SPDM_ATTESTATION) else if (dev_state == DEVICE_MANAGER_PRE_ATTESTATION) { + stat = (I3C_MNG_OWNER_BMC == owner) ? + PFR_ACT1_EID_REGISTRATION_I3C_BMC : PFR_ACT1_EID_REGISTRATION_I3C_CPU; + SetPfrActivityInfo1(stat); mctp_i3c_pre_attestation(device_mgr, &duration); } else if (dev_state == DEVICE_MANAGER_ATTESTATION) { /* Start S3M attestation then release PLTRST_CPU0_N */ @@ -240,8 +304,8 @@ void mctp_i3c_state_handler(void *a, void *b, void *c) duration = 0; } - if (duration > 0 && i3c_bmc_dev_attached) { - k_timer_start(&mctp_i3c_req_timer, K_SECONDS(duration), K_NO_WAIT); + if (duration > 0 && mctp_i3c_instance->state == MCTP_I3C_TARGET_ATTACHED) { + k_timer_start(&mctp_i3c_instance->i3c_state_timer, K_SECONDS(duration), K_NO_WAIT); } } } @@ -256,12 +320,9 @@ static uint16_t mctp_i3c_read(void *mctp_p, void *msg_p) struct i3c_device_desc* desc; // read request from slave device. - k_sem_take(&ibi_complete, K_FOREVER); - memset(i3c_data_in, 0, sizeof(i3c_data_in)); - dev = get_mctp_i3c_dev(mctp_inst->medium_conf.i3c_conf.bus); if (dev == NULL) { - LOG_ERR("Faile to get i3c dev"); + LOG_ERR("Failed to get i3c dev"); return MCTP_ERROR; } data = (struct i3c_driver_data *)dev->data; @@ -271,6 +332,9 @@ static uint16_t mctp_i3c_read(void *mctp_p, void *msg_p) return MCTP_ERROR; } + mctp_i3c_sem_take(desc); + memset(i3c_data_in, 0, sizeof(i3c_data_in)); + xfer.flags = I3C_MSG_READ | I3C_MSG_STOP; xfer.buf = i3c_data_in; xfer.len = sizeof(i3c_data_in); @@ -283,6 +347,12 @@ static uint16_t mctp_i3c_read(void *mctp_p, void *msg_p) packet->timeout_valid = 0; packet->pkt_timeout = 0; packet->state = CMD_VALID_PACKET; + + if (xfer.len > CMD_MAX_PACKET_SIZE) { + LOG_WRN("Buffer is smaller than received data"); + xfer.len = CMD_MAX_PACKET_SIZE; + } + memcpy(packet->data, xfer.buf, xfer.len); return 0; @@ -314,7 +384,7 @@ static uint16_t mctp_i3c_write(void *mctp_p, void *msg_p) return MCTP_ERROR; } - xfer.flags = I3C_MSG_WRITE; + xfer.flags = I3C_MSG_WRITE | I3C_MSG_STOP; xfer.buf = tx_msg->buf; xfer.len = tx_msg->len; LOG_DBG("write len : %d", xfer.len); @@ -329,15 +399,13 @@ int mctp_i3c_detach_slave_dev(uint8_t bus, uint64_t pid) const struct device *dev; struct i3c_device_desc *desc; const struct i3c_device_id i3c_id = I3C_DEVICE_ID(pid); + mctp_i3c *mctp_i3c_inst; mctp *mctp_inst; struct mctp_interface_wrapper *mctp_wrapper; struct device_manager *device_mgr; - if (pid == CONFIG_PFR_SPDM_I3C_BMC_DEV_PID && !i3c_bmc_dev_attached) - return 0; - - if (pid != CONFIG_PFR_SPDM_I3C_BMC_DEV_PID && - pid != CONFIG_PFR_SPDM_I3C_CPU_DEV_PID) { + if (pid != CONFIG_PFR_SPDM_I3C_BMC_DEV_PID && pid != CONFIG_PFR_SPDM_I3C_CPU0_DEV_PID && + pid != CONFIG_PFR_SPDM_I3C_CPU1_DEV_PID) { LOG_ERR("Invalid i3c pid"); goto error; } @@ -355,20 +423,27 @@ int mctp_i3c_detach_slave_dev(uint8_t bus, uint64_t pid) } if (pid == CONFIG_PFR_SPDM_I3C_BMC_DEV_PID) { - mctp_inst = mctp_i3c_bmc_inst; - i3c_bmc_dev_attached = false; - k_timer_stop(&mctp_i3c_req_timer); - } else if (pid == CONFIG_PFR_SPDM_I3C_CPU_DEV_PID) { - mctp_inst = mctp_i3c_cpu_inst; + mctp_i3c_inst = &mctp_i3c_bmc_inst; + } else if (pid == CONFIG_PFR_SPDM_I3C_CPU0_DEV_PID) { + mctp_i3c_inst = &mctp_i3c_cpu0_inst; + } else if (pid == CONFIG_PFR_SPDM_I3C_CPU1_DEV_PID) { + mctp_i3c_inst = &mctp_i3c_cpu1_inst; } else { goto error; } + if (mctp_i3c_inst->state != MCTP_I3C_TARGET_ATTACHED) { + LOG_WRN("Device is not attached"); + goto error; + } + k_timer_stop(&mctp_i3c_inst->i3c_state_timer); + mctp_inst = mctp_i3c_inst->mctp_inst; mctp_wrapper = &mctp_inst->mctp_wrapper; device_mgr = mctp_wrapper->mctp_interface.device_manager; device_manager_update_device_state(device_mgr, DEVICE_MANAGER_SELF_DEVICE_NUM, DEVICE_MANAGER_SEND_DISCOVERY_NOTIFY); + mctp_i3c_inst->state = MCTP_I3C_TARGET_INITIALIZED_DETACHED; return 0; error: @@ -382,15 +457,14 @@ static void mctp_i3c_req_timeout_callback(struct k_timer *tmr) #define IBI_MDB_GROUP GENMASK(7, 5) #define IBI_MDB_GROUP_PENDING_READ_NOTI 5 - -static int mctp_i3c_ibi_cb(struct i3c_device_desc *target, struct i3c_ibi_payload *payload) +int mctp_i3c_ibi_cb(struct i3c_device_desc *target, struct i3c_ibi_payload *payload) { if (payload->payload_len) { LOG_HEXDUMP_DBG(payload->payload, payload->payload_len, "IBI payload:"); if (FIELD_GET(IBI_MDB_GROUP, payload->payload[0]) == IBI_MDB_GROUP_PENDING_READ_NOTI) { - k_sem_give(&ibi_complete); + mctp_i3c_sem_give(target); } } @@ -406,17 +480,32 @@ uint8_t mctp_i3c_init(mctp *mctp_instance, mctp_medium_conf medium_conf) mctp_instance->read_data = mctp_i3c_read; mctp_instance->write_data = mctp_i3c_write; - if (mctp_instance->is_servcie_start) - return MCTP_SUCCESS; + return MCTP_SUCCESS; +} + +uint8_t mctp_i3c_eid_assignment_thread_create(mctp_i3c *mctp_i3c_inst) +{ - k_tid_t mctp_i3c_state_tid = k_thread_create(&mctp_i3c_discovery_notify_thread, - mctp_i3c_discovery_notify_stack, - MCTP_DISCOVERY_NOTIFY_STACK_SIZE, + mctp_i3c_inst->i3c_state_tid = k_thread_create(&mctp_i3c_inst->i3c_state_thread, + mctp_i3c_inst->i3c_state_handler_stack, + MCTP_I3C_STATE_HANDLER_STACK_SIZE, mctp_i3c_state_handler, - NULL, NULL, NULL, 5, 0, K_NO_WAIT); - k_thread_name_set(mctp_i3c_state_tid, "MCTP I3C State Handler"); + mctp_i3c_inst, NULL, NULL, 5, 0, K_NO_WAIT); - return MCTP_SUCCESS; + snprintf(mctp_i3c_inst->i3c_state_task_name, sizeof(mctp_i3c_inst->i3c_state_task_name), + "MCTP I3C State Handler B%02xA%02x", + mctp_i3c_inst->mctp_inst->medium_conf.i3c_conf.bus, + mctp_i3c_inst->mctp_inst->medium_conf.i3c_conf.addr); + k_thread_name_set(mctp_i3c_inst->i3c_state_tid, mctp_i3c_inst->i3c_state_task_name); + + return 0; +} + +void mctp_i3c_state_expiry_fn(struct k_timer *tmr) +{ + struct k_sem *state_sem; + state_sem = (struct k_sem *)k_timer_user_data_get(tmr); + k_sem_give(state_sem); } uint8_t mctp_i3c_deinit(mctp *mctp_instance) @@ -433,14 +522,17 @@ uint8_t mctp_i3c_deinit(mctp *mctp_instance) int mctp_i3c_attach_target_dev(uint8_t bus, uint64_t pid) { struct i3c_device_desc *desc; + struct i3c_ccc_mrl mrl; const struct device *dev; const struct i3c_device_id i3c_id = I3C_DEVICE_ID(pid); + mctp_i3c *mctp_i3c_inst; mctp *mctp_inst; int mctp_channel_id; int rc; if (pid != CONFIG_PFR_SPDM_I3C_BMC_DEV_PID && - pid != CONFIG_PFR_SPDM_I3C_CPU_DEV_PID) { + pid != CONFIG_PFR_SPDM_I3C_CPU0_DEV_PID && + pid != CONFIG_PFR_SPDM_I3C_CPU1_DEV_PID) { LOG_ERR("Invalid i3c pid"); goto error; } @@ -457,26 +549,49 @@ int mctp_i3c_attach_target_dev(uint8_t bus, uint64_t pid) goto error; } + if (pid == CONFIG_PFR_SPDM_I3C_BMC_DEV_PID) { + if (mctp_i3c_bmc_inst.mctp_inst == NULL) { + mctp_i3c_bmc_inst.state = MCTP_I3C_TARGET_DETACHED; + mctp_i3c_bmc_inst.mctp_inst = mctp_init(); + } + mctp_i3c_inst = &mctp_i3c_bmc_inst; + } else if (pid == CONFIG_PFR_SPDM_I3C_CPU0_DEV_PID) { + if (mctp_i3c_cpu0_inst.mctp_inst == NULL) { + mctp_i3c_cpu0_inst.state = MCTP_I3C_TARGET_DETACHED; + mctp_i3c_cpu0_inst.mctp_inst = mctp_init(); + } + mctp_i3c_inst = &mctp_i3c_cpu0_inst; + mrl.len = 0x45; + mrl.ibi_len = 2; + i3c_ccc_do_setmrl(desc, &mrl); + } else if (pid == CONFIG_PFR_SPDM_I3C_CPU1_DEV_PID) { + if (mctp_i3c_cpu1_inst.mctp_inst == NULL) { + mctp_i3c_cpu1_inst.state = MCTP_I3C_TARGET_DETACHED; + mctp_i3c_cpu1_inst.mctp_inst = mctp_init(); + } + mctp_i3c_inst = &mctp_i3c_cpu1_inst; + mrl.len = 0x45; + mrl.ibi_len = 2; + i3c_ccc_do_setmrl(desc, &mrl); + } else { + goto error; + } + desc->ibi_cb = mctp_i3c_ibi_cb; if (i3c_ibi_enable(desc)) { LOG_ERR("Failed to enable ibi"); goto error; } - if (pid == CONFIG_PFR_SPDM_I3C_BMC_DEV_PID) { - mctp_i3c_bmc_desc = desc; - if (mctp_i3c_bmc_inst == NULL) - mctp_i3c_bmc_inst = mctp_init(); - mctp_inst = mctp_i3c_bmc_inst; - } else if (pid == CONFIG_PFR_SPDM_I3C_CPU_DEV_PID) { - mctp_i3c_cpu_desc = desc; - if (mctp_i3c_cpu_inst == NULL) - mctp_i3c_cpu_inst = mctp_init(); - mctp_inst = mctp_i3c_cpu_inst; - } else { - goto error; + mrl.len = 0x45; + mrl.ibi_len = 2; + int ret = ret = i3c_ccc_do_setmrl(desc, &mrl); + if (mctp_i3c_inst->state == MCTP_I3C_TARGET_ATTACHED) { + LOG_WRN("I3C device is attached"); + return 0; } + mctp_inst = mctp_i3c_inst->mctp_inst; if (mctp_inst == NULL) goto error; @@ -500,25 +615,282 @@ int mctp_i3c_attach_target_dev(uint8_t bus, uint64_t pid) mctp_interface_set_channel_id(&mctp_inst->mctp_wrapper.mctp_interface, mctp_channel_id); mctp_start(mctp_inst); - - if (pid == CONFIG_PFR_SPDM_I3C_BMC_DEV_PID) { - i3c_bmc_dev_attached = true; - k_timer_start(&mctp_i3c_req_timer, K_SECONDS(12), K_NO_WAIT); - LOG_INF("BMC's MCTP over I3C initialization succeeded"); + if (mctp_i3c_inst->state == MCTP_I3C_TARGET_INITIALIZED_DETACHED) { + k_sem_give(&mctp_i3c_inst->i3c_state_sem); + } else { + k_sem_init(&mctp_i3c_inst->i3c_state_sem, 1, 1); + k_timer_init(&mctp_i3c_inst->i3c_state_timer, mctp_i3c_state_expiry_fn, + NULL); + k_timer_user_data_set(&mctp_i3c_inst->i3c_state_timer, + &mctp_i3c_inst->i3c_state_sem); + mctp_i3c_eid_assignment_thread_create(mctp_i3c_inst); } + mctp_i3c_inst->state = MCTP_I3C_TARGET_ATTACHED; + k_timer_start(&mctp_i3c_inst->i3c_state_timer, K_SECONDS(12), K_NO_WAIT); + return 0; error: if (pid == CONFIG_PFR_SPDM_I3C_BMC_DEV_PID) { - mctp_i3c_bmc_desc = NULL; - if (mctp_i3c_bmc_inst) - free(mctp_i3c_bmc_inst); - } else if (pid == CONFIG_PFR_SPDM_I3C_CPU_DEV_PID) { - mctp_i3c_cpu_desc = NULL; - if (mctp_i3c_cpu_inst) - free(mctp_i3c_cpu_inst); + if (mctp_i3c_bmc_inst.mctp_inst) + free(mctp_i3c_bmc_inst.mctp_inst); + } else if (pid == CONFIG_PFR_SPDM_I3C_CPU0_DEV_PID) { + if (mctp_i3c_cpu0_inst.mctp_inst) + free(mctp_i3c_cpu0_inst.mctp_inst); + } else if (pid == CONFIG_PFR_SPDM_I3C_CPU1_DEV_PID) { + if (mctp_i3c_cpu1_inst.mctp_inst) + free(mctp_i3c_cpu1_inst.mctp_inst); } return -1; } +void mctp_i3c_send_entdaa(uint8_t bus) +{ + const struct device *dev; + + dev = get_mctp_i3c_dev(bus); + if (dev == NULL) { + LOG_ERR("Failed to get i3c dev"); + return; + } + + i3c_do_daa(dev); +} + +void mctp_i3c_send_rstdaa(uint8_t bus) +{ + const struct device *dev; + struct i3c_driver_data *data; + sys_snode_t *node; + + dev = get_mctp_i3c_dev(bus); + if (dev == NULL) { + LOG_ERR("Failed to get i3c dev"); + return; + } + + data = dev->data; + i3c_ccc_do_rstdaa_all(dev); + + /* reset all devices DA */ + if (!sys_slist_is_empty(&data->attached_dev.devices.i3c)) { + SYS_SLIST_FOR_EACH_NODE(&data->attached_dev.devices.i3c, node) { + struct i3c_device_desc *desc = + CONTAINER_OF(node, struct i3c_device_desc, node); + desc->dynamic_addr = 0; + LOG_INF("Reset dynamic address for device %s", desc->dev->name); + } + } +} + +// The function is used to configure RG3MxxB12 i3c hub +int mctp_i3c_hub_configuration(void) +{ + const struct device *dev; + struct i3c_device_desc* desc; + struct i3c_msg xfer; + uint8_t i3c_conf_buf[2] = {0x10, 0x69}; + uint8_t read_back[1] = {0}; + uint64_t pid = CONFIG_PFR_SPDM_I3C_HUB_DEV_PID; + const struct i3c_device_id i3c_id = I3C_DEVICE_ID(pid); + + LOG_INF("Configuring I3C hub"); + dev = get_mctp_i3c_dev(CONFIG_PFR_SPDM_CPU_I3C_BUS); + desc = i3c_device_find(dev, &i3c_id); + if (desc == NULL) { + LOG_ERR("I3C Hub not found"); + goto end; + } + + desc->ibi_cb = mctp_i3c_ibi_cb; + xfer.flags = I3C_MSG_WRITE | I3C_MSG_STOP; + xfer.buf = i3c_conf_buf; + xfer.len = sizeof(i3c_conf_buf); + + // 79 c7 + i3c_conf_buf[0] = 0x79; + i3c_write_read(desc, i3c_conf_buf, 1, read_back, 1); + LOG_INF("Hub power good status : %x", read_back[0]); + + // 10 69 + i3c_conf_buf[0] = 0x10; + i3c_conf_buf[1] = 0x69; + if (i3c_transfer(desc, &xfer, 1)) { + LOG_ERR("Failed to unlock register protection"); + goto end; + } + + //read PID reg 2 ~ 7 + // uint8_t pid_reg[1] = {2}; + // for (int i = 2; i < 8; i++) { + // pid_reg[0] = i; + // i3c_write_read(desc, pid_reg, 1, read_back, 1); + // LOG_INF("pid = %x", read_back[0]); + // } + + // 16 00 + i3c_conf_buf[0] = 0x16; + i3c_write_read(desc, i3c_conf_buf, 1, read_back, 1); + + // 19 50 + i3c_conf_buf[0] = 0x19; + i3c_write_read(desc, i3c_conf_buf, 1, read_back, 1); + + // 16 00 + i3c_conf_buf[0] = 0x16; + i3c_write_read(desc, i3c_conf_buf, 1, read_back, 1); + + // 19 50 + i3c_conf_buf[0] = 0x19; + i3c_write_read(desc, i3c_conf_buf, 1, read_back, 1); + + // 14 00 + i3c_conf_buf[0] = 0x14; + i3c_write_read(desc, i3c_conf_buf, 1, read_back, 1); + + // 14 00 + i3c_conf_buf[0] = 0x14; + i3c_write_read(desc, i3c_conf_buf, 1, read_back, 1); + if (read_back[0] != 0xf) { + // 14 0f + i3c_conf_buf[0] = 0x14; + i3c_conf_buf[1] = 0x0f; + if (i3c_transfer(desc, &xfer, 1)) { + LOG_ERR("Failed to setup io drive strength"); + goto end; + } + } + + // 19 50 + i3c_conf_buf[0] = 0x19; + i3c_write_read(desc, i3c_conf_buf, 1, read_back, 1); + if (read_back[0] != 0xf0) { + // 19 f0 + i3c_conf_buf[0] = 0x19; + i3c_conf_buf[1] = 0xf0; + if (i3c_transfer(desc, &xfer, 1)) { + LOG_ERR("Failed to disable LDO"); + goto end; + } + } + + // 17 ff + i3c_conf_buf[0] = 0x17; + i3c_write_read(desc, i3c_conf_buf, 1, read_back, 1); + if (read_back[0] != 0x0) { + // 17 00 + xfer.len = sizeof(i3c_conf_buf); + i3c_conf_buf[0] = 0x17; + i3c_conf_buf[1] = 0x00; + if (i3c_transfer(desc, &xfer, 1)) { + LOG_ERR("Failed to enable compatible mode"); + goto end; + } + } + + // 53 ff + i3c_conf_buf[0] = 0x53; + i3c_write_read(desc, i3c_conf_buf, 1, read_back, 1); + if (read_back[0] != 0xff) { + i3c_conf_buf[0] = 0x53; + i3c_conf_buf[1] = 0xff; + if (i3c_transfer(desc, &xfer, 1)) { + LOG_ERR("Failed to setup pull up resistor connection"); + goto end; + } + } + + // 18 00 + i3c_conf_buf[0] = 0x18; + i3c_write_read(desc, i3c_conf_buf, 1, read_back, 1); + if (read_back[0] != 0) { + i3c_conf_buf[0] = 0x18; + i3c_conf_buf[1] = 0x00; + if (i3c_transfer(desc, &xfer, 1)) { + LOG_ERR("Failed to disable SMBus agent"); + goto end; + } + } + + // 1e 00 + i3c_conf_buf[0] = 0x1e; + i3c_write_read(desc, i3c_conf_buf, 1, read_back, 1); + if (read_back[0] != 0) { + i3c_conf_buf[0] = 0x1e; + i3c_conf_buf[1] = 0x00; + if (i3c_transfer(desc, &xfer, 1)) { + LOG_ERR("Failed to disable GPIO mode"); + goto end; + } + } + + // 38 01 + i3c_conf_buf[0] = 0x38; + i3c_conf_buf[1] = 0x01; + if (i3c_transfer(desc, &xfer, 1)) { + LOG_ERR("Failed to request HUB control"); + goto end; + } + + // 12 00 + i3c_conf_buf[0] = 0x12; + i3c_write_read(desc, i3c_conf_buf, 1, read_back, 1); + if (read_back[0] != 5) { + // 12 05 + i3c_conf_buf[0] = 0x12; + i3c_conf_buf[1] = 0x05; + if (i3c_transfer(desc, &xfer, 1)) { + LOG_ERR("Failed to enable ports"); + goto end; + } + } + + // 51 00 + i3c_conf_buf[0] = 0x51; + i3c_write_read(desc, i3c_conf_buf, 1, read_back, 1); + if (read_back[0] != 5) { + // 51 05 + if (i3c_transfer(desc, &xfer, 1)) { + LOG_ERR("Failed to setup slave port connection"); + goto end; + } + } + + // 10 00 + i3c_conf_buf[0] = 0x10; + i3c_conf_buf[1] = 0x00; + if (i3c_transfer(desc, &xfer, 1)) { + LOG_ERR("Failed to lock register protection"); + goto end; + } + + LOG_INF("I3C hub initialization succeed"); + return 0; +end: + LOG_ERR("Failed to configure i3c hub"); + return -1; +} + +void mctp_i3c_configure_cpu_i3c_devs(void) +{ + if (!is_pltrst_sync()) + return; + if (get_i3c_mng_owner() == I3C_MNG_OWNER_ROT) { + LOG_INF("Enable CPU i3c"); + if (!i3c_hub_configured) { + mctp_i3c_send_rstdaa(CONFIG_PFR_SPDM_CPU_I3C_BUS); + mctp_i3c_send_entdaa(CONFIG_PFR_SPDM_CPU_I3C_BUS); + if (mctp_i3c_hub_configuration()) + return; + i3c_hub_configured = true; + } + mctp_i3c_send_rstdaa(CONFIG_PFR_SPDM_CPU_I3C_BUS); + mctp_i3c_send_entdaa(CONFIG_PFR_SPDM_CPU_I3C_BUS); + + mctp_i3c_attach_target_dev(CONFIG_PFR_SPDM_CPU_I3C_BUS, + CONFIG_PFR_SPDM_I3C_CPU0_DEV_PID); + mctp_i3c_attach_target_dev(CONFIG_PFR_SPDM_CPU_I3C_BUS, + CONFIG_PFR_SPDM_I3C_CPU1_DEV_PID); + } +} diff --git a/apps/aspeed-pfr/src/mctp/mctp_i3c.h b/apps/aspeed-pfr/src/mctp/mctp_i3c.h new file mode 100644 index 0000000..1effed6 --- /dev/null +++ b/apps/aspeed-pfr/src/mctp/mctp_i3c.h @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2022 ASPEED Technology Inc. + * + * SPDX-License-Identifier: MIT + */ + +#pragma once +#include +#include +#include "mctp.h" +#include "cmd_interface/device_manager.h" + +#define MCTP_I3C_MSG_RETRY_INTERVAL 12 + +enum { + MCTP_I3C_TARGET_DETACHED, + MCTP_I3C_TARGET_INITIALIZED_DETACHED, + MCTP_I3C_TARGET_ATTACHED, +}; + +typedef struct _mctp_i3c { + mctp *mctp_inst; + uint8_t state; + uint8_t i3c_state_task_name[MCTP_TASK_NAME_LEN]; + struct k_sem i3c_state_sem; + struct k_timer i3c_state_timer; + k_tid_t i3c_state_tid; + struct k_thread i3c_state_thread; + K_KERNEL_STACK_MEMBER(i3c_state_handler_stack, MCTP_I3C_STATE_HANDLER_STACK_SIZE); +} mctp_i3c; + +uint8_t mctp_i3c_init(mctp *mctp_instance, mctp_medium_conf medium_conf); +uint8_t mctp_i3c_target_init(mctp *mctp_instance, mctp_medium_conf medium_conf); +uint8_t mctp_i3c_deinit(mctp *mctp_instance); + +void set_prev_mctp_i3c_state(int state); +int mctp_i3c_detach_slave_dev(uint8_t bus, uint64_t pid); +int mctp_i3c_attach_target_dev(uint8_t bus, uint64_t pid); +void mctp_i3c_stop_discovery_notify(struct device_manager *mgr); +int mctp_i3c_hub_configuration(void); +const struct device *get_mctp_i3c_dev(uint8_t bus_num); +int mctp_i3c_ibi_cb(struct i3c_device_desc *target, struct i3c_ibi_payload *payload); + +uint8_t mctp_i3c_eid_assignment_thread_create(mctp_i3c *mctp_i3c_inst); +void mctp_i3c_state_expiry_fn(struct k_timer *tmr); +void mctp_i3c_pre_attestation(struct device_manager *mgr, int *duration); +void mctp_i3c_attestation(struct device_manager *mgr, int *duration); +int mctp_i3c_send_discovery_notify(mctp *mctp_instance, int *duration); +int mctp_i3c_send_eid_announcement(mctp *mctp_instance, int *duration); + +void mctp_i3c_send_rstdaa(uint8_t bus); +void mctp_i3c_send_entdaa(uint8_t bus); +void mctp_i3c_configure_cpu_i3c_devs(void); +#if defined(CONFIG_PFR_MCTP_I3C_5_0) +void mctp_i3c_target_intf_init(void); +uint8_t mctp_i3c_target_mctp_stop(void); +#endif diff --git a/apps/aspeed-pfr/src/mctp/mctp_i3c_target.c b/apps/aspeed-pfr/src/mctp/mctp_i3c_target.c new file mode 100644 index 0000000..9c443e7 --- /dev/null +++ b/apps/aspeed-pfr/src/mctp/mctp_i3c_target.c @@ -0,0 +1,241 @@ +/* + * Copyright (c) 2024 ASPEED Technology Inc. + * + * SPDX-License-Identifier: MIT + */ + +#include +#include +#include +#include "i3c/i3c_util.h" +#include "mctp.h" +#include "mctp_i3c.h" +#include "cmd_channel_mctp.h" +#include "gpio/gpio_aspeed.h" +#include "Smbus_mailbox/Smbus_mailbox.h" + +LOG_MODULE_REGISTER(mctp_i3c_target); + +extern const struct device dev_i3c_tmq[I3C_MAX_NUM]; + +#define I3C_BUS_CPU 0x00 +#define I3C_BUS_BMC 0x02 + +typedef struct _mctp_i3c_dev { + mctp_i3c mctp_i3c_inst; + mctp_i3c_conf i3c_conf; +} mctp_i3c_dev; + +mctp_i3c_dev i3c_devs[] = { + { + // For BMC to brige CPU's mctp msg to PFR + .i3c_conf.bus = I3C_BUS_CPU, + .i3c_conf.addr = 0, // will be assigned by BMC + }, + { + // For BMC to send mctp msg to PFR + .i3c_conf.bus = I3C_BUS_BMC, + .i3c_conf.addr = 0, // will be assigned by BMC + }, +}; + +static uint16_t mctp_i3c_tmq_read(void *mctp_p, void *msg_p) +{ + // Add sleep here for preventing cpu stuck in while loop. + // i3c target only supports polling mode. + k_msleep(1); + + struct cmd_packet *packet = (struct cmd_packet *)msg_p; + uint8_t max_idx = ARRAY_SIZE(packet->data); + int ret = 0; + I3C_MSG i3c_msg; + mctp *mctp_inst = (mctp *)mctp_p; + + if (mctp_p == NULL || msg_p == NULL) + return MCTP_ERROR; + + i3c_msg.bus = mctp_inst->medium_conf.i3c_conf.bus; + ret = i3c_tmq_read(&i3c_msg); + + /** mctp rx keep polling, return length 0 directly if no data or invalid data **/ + if (ret <= 0) { + memset(packet, 0, sizeof(struct cmd_packet)); + return 0; + } + + packet->dest_addr = mctp_inst->medium_conf.i3c_conf.addr; + packet->pkt_size = ret; + packet->timeout_valid = 0; + packet->pkt_timeout = 0; + packet->state = CMD_VALID_PACKET; + + i3c_msg.rx_len = ret; + if (ret > max_idx) { + packet->state = CMD_OVERFLOW_PACKET; + return MCTP_ERROR; + } + + LOG_HEXDUMP_INF(&i3c_msg.data[0], i3c_msg.rx_len, "mctp_i3c_read_smq msg dump"); + + memcpy(packet->data, &i3c_msg.data[0], i3c_msg.rx_len); + return MCTP_SUCCESS; +} + +static uint16_t mctp_i3c_tmq_write(void *mctp_p, void *msg_p) +{ + int ret; + mctp *mctp_instance = (mctp *)mctp_p; + mctp_tx_msg *tx_msg = (mctp_tx_msg *)msg_p; + uint32_t len = tx_msg->len; + I3C_MSG i3c_msg; + + if (mctp_p == NULL || msg_p == NULL) + return MCTP_ERROR; + + if (!tx_msg->buf) + return MCTP_ERROR; + + if (!tx_msg->len) + return MCTP_ERROR; + + i3c_msg.bus = mctp_instance->medium_conf.i3c_conf.bus; + /** mctp package **/ + memcpy(&i3c_msg.data[0], tx_msg->buf, len); + i3c_msg.tx_len = len; + + LOG_HEXDUMP_INF(&i3c_msg.data[0], i3c_msg.tx_len, "mctp_i3c_write_tmq msg dump"); + + ret = i3c_tmq_write(&i3c_msg); + if (ret) { + LOG_ERR("mctp_i3c_write_tmq write failed, ret = %d", ret); + return MCTP_ERROR; + } + + return MCTP_SUCCESS; +} + +uint8_t mctp_i3c_target_init(mctp *mctp_instance, mctp_medium_conf medium_conf) +{ + if (mctp_instance == NULL) + return MCTP_ERROR; + + mctp_instance->medium_conf = medium_conf; + mctp_instance->read_data = mctp_i3c_tmq_read; + mctp_instance->write_data = mctp_i3c_tmq_write; + + if (mctp_instance->is_servcie_start) + return MCTP_SUCCESS; + + return MCTP_SUCCESS; +} + +uint8_t mctp_i3c_target_mctp_stop(void) +{ + int i; + mctp_i3c_dev *i3c_dev_p; + mctp_i3c *mctp_i3c_inst; + mctp *mctp_inst; + struct mctp_interface_wrapper *mctp_wrapper; + struct device_manager *device_mgr; + + for (i = 0; i < ARRAY_SIZE(i3c_devs); i++) { + i3c_dev_p = &i3c_devs[i]; + mctp_i3c_inst = &i3c_dev_p->mctp_i3c_inst; + if (mctp_i3c_inst->state != MCTP_I3C_TARGET_ATTACHED) + return 0; + + mctp_i3c_inst->state = MCTP_I3C_TARGET_INITIALIZED_DETACHED; + k_timer_stop(&mctp_i3c_inst->i3c_state_timer); + + mctp_inst = mctp_i3c_inst->mctp_inst; + mctp_wrapper = &mctp_inst->mctp_wrapper; + device_mgr = mctp_wrapper->mctp_interface.device_manager; + device_manager_update_device_state(device_mgr, + DEVICE_MANAGER_SELF_DEVICE_NUM, DEVICE_MANAGER_SEND_DISCOVERY_NOTIFY); + } + return 0; +} + +void mctp_i3c_target_intf_init(void) +{ + int i; + int rc; + mctp_i3c_dev *i3c_dev_p; + mctp_i3c *mctp_i3c_instance; + mctp *mctp_instance; + + int mctp_channel_id; + + LOG_INF("mctp_i3c_target_intf_init"); + + for (i = 0; i < ARRAY_SIZE(i3c_devs); i++) { + i3c_dev_p = &i3c_devs[i]; + mctp_i3c_instance = &i3c_dev_p->mctp_i3c_inst; + if (mctp_i3c_instance->mctp_inst != NULL) + if (!mctp_i3c_instance->mctp_inst->is_servcie_start) + free(mctp_i3c_instance->mctp_inst); + + if (mctp_i3c_instance->mctp_inst == NULL) { + mctp_i3c_instance->mctp_inst = mctp_init(); + mctp_i3c_instance->state = MCTP_I3C_TARGET_DETACHED; + } + + mctp_instance = mctp_i3c_instance->mctp_inst; + if (!mctp_instance) { + LOG_ERR("Failed to allocate mctp instance for i3c"); + return; + } + mctp_set_medium_configure(mctp_instance, MCTP_MEDIUM_TYPE_I3C_TARGET, + mctp_instance->medium_conf); + + if (i3c_get_assigned_addr(i3c_dev_p->i3c_conf.bus, &i3c_dev_p->i3c_conf.addr)) { + LOG_ERR("Failed to get assigned i3c device address"); + goto error; + } + mctp_instance->medium_conf.i3c_conf.bus = i3c_dev_p->i3c_conf.bus; + mctp_instance->medium_conf.i3c_conf.addr = i3c_dev_p->i3c_conf.addr; + mctp_channel_id = CMD_CHANNEL_I3C_BASE | CMD_CHANNEL_I3C_TARGET | + mctp_instance->medium_conf.i3c_conf.bus; + rc = cmd_channel_mctp_init(&mctp_instance->mctp_cmd_channel, + mctp_channel_id); + if (rc != MCTP_SUCCESS) { + LOG_ERR("i3c mctp cmd channel init failed"); + goto error; + } + + rc = mctp_i3c_wrapper_init(&mctp_instance->mctp_wrapper, + mctp_instance->medium_conf.i3c_conf.addr); + if (rc != MCTP_SUCCESS) { + LOG_ERR("i3c mctp interface wrapper init failed!!"); + goto error; + } + + mctp_interface_set_channel_id(&mctp_instance->mctp_wrapper.mctp_interface, + mctp_channel_id); + + mctp_start(mctp_instance); + if (mctp_i3c_instance->state == MCTP_I3C_TARGET_INITIALIZED_DETACHED) { + if (mctp_i3c_instance->i3c_state_sem.count <= 0) + k_sem_give(&mctp_i3c_instance->i3c_state_sem); + } else { + k_sem_init(&mctp_i3c_instance->i3c_state_sem, 1, 1); + k_timer_init(&mctp_i3c_instance->i3c_state_timer, mctp_i3c_state_expiry_fn, + NULL); + k_timer_user_data_set(&mctp_i3c_instance->i3c_state_timer, + &mctp_i3c_instance->i3c_state_sem); + mctp_i3c_eid_assignment_thread_create(&i3c_dev_p->mctp_i3c_inst); + } + + mctp_i3c_instance->state = MCTP_I3C_TARGET_ATTACHED; + LOG_INF("MCTP over I3C for bus %02x start", i3c_dev_p->i3c_conf.bus); + } + + return; +error: + for (i = 0; i < ARRAY_SIZE(i3c_devs); i++) { + i3c_dev_p = &i3c_devs[i]; + mctp_i3c_instance = &i3c_dev_p->mctp_i3c_inst; + if (mctp_i3c_instance->mctp_inst != NULL) + free(mctp_i3c_instance->mctp_inst); + } +} diff --git a/apps/aspeed-pfr/src/mctp/mctp_smbus.c b/apps/aspeed-pfr/src/mctp/mctp_smbus.c index c20e355..ed20f29 100644 --- a/apps/aspeed-pfr/src/mctp/mctp_smbus.c +++ b/apps/aspeed-pfr/src/mctp/mctp_smbus.c @@ -10,8 +10,8 @@ #include #include "Smbus_mailbox/Smbus_mailbox.h" #include "cmd_interface/cmd_channel.h" -#include "i2c/hal_i2c.h" -#include "mctp_utils.h" +#include "i2c/i2c_util.h" +#include "mctp.h" LOG_MODULE_DECLARE(mctp, CONFIG_LOG_DEFAULT_LEVEL); diff --git a/apps/aspeed-pfr/src/mctp/mctp_task.c b/apps/aspeed-pfr/src/mctp/mctp_task.c index 8b6be34..0c90715 100644 --- a/apps/aspeed-pfr/src/mctp/mctp_task.c +++ b/apps/aspeed-pfr/src/mctp/mctp_task.c @@ -8,13 +8,15 @@ #include #include #include -#include "mctp_utils.h" +#include "mctp.h" +#include "mctp_i3c.h" LOG_MODULE_DECLARE(mctp, CONFIG_LOG_DEFAULT_LEVEL); /* set thread name */ static uint8_t set_thread_name(mctp *mctp_inst) { + int status; if (!mctp_inst) return MCTP_ERROR; @@ -29,23 +31,40 @@ static uint8_t set_thread_name(mctp *mctp_inst) LOG_INF("medium_type: smbus"); mctp_smbus_conf *smbus_conf = (mctp_smbus_conf *)&mctp_inst->medium_conf; - snprintf(mctp_inst->mctp_rx_task_name, sizeof(mctp_inst->mctp_rx_task_name), + status = snprintf(mctp_inst->mctp_rx_task_name, sizeof(mctp_inst->mctp_rx_task_name), "mctprx_%02x_%02x_%02x", mctp_inst->medium_type, smbus_conf->bus, smbus_conf->rot_addr); - snprintf(mctp_inst->mctp_tx_task_name, sizeof(mctp_inst->mctp_tx_task_name), + if (status < 0) { + LOG_WRN("Failed to set smbus mctprx thread name for %02x:%02x:%02x", + mctp_inst->medium_type, smbus_conf->bus, smbus_conf->rot_addr); + } + status = snprintf(mctp_inst->mctp_tx_task_name, sizeof(mctp_inst->mctp_tx_task_name), "mctptx_%02x_%02x", mctp_inst->medium_type, smbus_conf->bus); + if (status < 0) { + LOG_WRN("Failed to set smbus mctptx thread name for %02x:%02x", + mctp_inst->medium_type, smbus_conf->bus); + } ret = MCTP_SUCCESS; break; #if defined(CONFIG_PFR_MCTP_I3C) && defined(CONFIG_I3C_ASPEED) case MCTP_MEDIUM_TYPE_I3C: + case MCTP_MEDIUM_TYPE_I3C_TARGET: LOG_INF("medium_type: i3c"); mctp_i3c_conf *i3c_conf = (mctp_i3c_conf *)&mctp_inst->medium_conf; - snprintf(mctp_inst->mctp_rx_task_name, sizeof(mctp_inst->mctp_rx_task_name), + status = snprintf(mctp_inst->mctp_rx_task_name, sizeof(mctp_inst->mctp_rx_task_name), "mctprx_%02x_%02x_%02x", mctp_inst->medium_type, i3c_conf->bus, i3c_conf->addr); - snprintf(mctp_inst->mctp_tx_task_name, sizeof(mctp_inst->mctp_tx_task_name), + if (status < 0) { + LOG_WRN("Failed to set i3c mctprx thread name for %02x:%02x:%02x", + mctp_inst->medium_type, i3c_conf->bus, i3c_conf->addr); + } + status = snprintf(mctp_inst->mctp_tx_task_name, sizeof(mctp_inst->mctp_tx_task_name), "mctptx_%02x_%02x_%02x", mctp_inst->medium_type, i3c_conf->bus, i3c_conf->addr); + if (status < 0) { + LOG_WRN("Failed to set i3c mctptx thread name for %02x:%02x:%02x", + mctp_inst->medium_type, i3c_conf->bus, i3c_conf->addr); + } ret = MCTP_SUCCESS; break; #endif @@ -72,6 +91,11 @@ static uint8_t mctp_medium_init(mctp *mctp_inst, mctp_medium_conf medium_conf) case MCTP_MEDIUM_TYPE_I3C: ret = mctp_i3c_init(mctp_inst, medium_conf); break; +#if defined(CONFIG_PFR_MCTP_I3C_5_0) + case MCTP_MEDIUM_TYPE_I3C_TARGET: + ret = mctp_i3c_target_init(mctp_inst, medium_conf); + break; +#endif #endif default: break; @@ -91,6 +115,7 @@ static uint8_t mctp_medium_deinit(mctp *mctp_inst) break; #if defined(CONFIG_PFR_MCTP_I3C) && defined(CONFIG_I3C_ASPEED) case MCTP_MEDIUM_TYPE_I3C: + case MCTP_MEDIUM_TYPE_I3C_TARGET: mctp_i3c_deinit(mctp_inst); break; #endif diff --git a/apps/aspeed-pfr/src/mctp/mctp_utils.h b/apps/aspeed-pfr/src/mctp/mctp_utils.h deleted file mode 100644 index d97b4a9..0000000 --- a/apps/aspeed-pfr/src/mctp/mctp_utils.h +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (c) 2022 ASPEED Technology Inc. - * - * SPDX-License-Identifier: MIT - */ - -#pragma once - -#include -#include -#include -#include "mctp/mctp_interface_wrapper.h" -#include "cmd_interface/cmd_channel.h" - -#define MCTP_SUCCESS 0 -#define MCTP_ERROR 1 - -#define MCTP_TX_QUEUE_SIZE 16 -#define MCTP_RX_TASK_STACK_SIZE 2048 -#define MCTP_TX_TASK_STACK_SIZE 2048 -#define MCTP_TASK_NAME_LEN 32 - -typedef enum { - MCTP_MEDIUM_TYPE_UNKNOWN = 0, - MCTP_MEDIUM_TYPE_SMBUS, - MCTP_MEDIUM_TYPE_I3C, - MCTP_MEDIUM_TYPE_MAX -} MCTP_MEDIUM_TYPE; - -/* smbus extra medium data of endpoint */ -typedef struct _mctp_smbus_ext_params { - uint8_t addr; /* 7 bit address */ -} mctp_smbus_ext_params; - -/* mctp extra parameters prototype */ -typedef struct _mctp_ext_params { - /* medium parameters */ - MCTP_MEDIUM_TYPE type; - union { - mctp_smbus_ext_params smbus_ext_params; - }; -} mctp_ext_params; - -/* medium write/read function prototype */ -typedef uint16_t (*medium_tx)(void *mctp_p, void *msg_p); -typedef uint16_t (*medium_rx)(void *mctp_p, void *msg_p); - -/* i3c config for mctp medium_conf */ -typedef struct _mctp_i3c_conf { - uint8_t bus; - uint8_t addr; - uint32_t dummy; -} mctp_i3c_conf; - -/* smbus config for mctp medium_conf */ -typedef struct _mctp_smbus_conf { - uint8_t bus; - uint8_t rot_addr; - uint8_t mbx_port; -} mctp_smbus_conf; - -/* mctp medium conf */ -typedef union { - mctp_smbus_conf smbus_conf; - mctp_i3c_conf i3c_conf; -} mctp_medium_conf; - -/* mctp tx message struct */ -typedef struct _mctp_tx_msg { - uint8_t *buf; - size_t len; - mctp_ext_params ext_params; -} mctp_tx_msg; - -/* mctp main struct */ -typedef struct _mctp { - uint8_t is_servcie_start; - MCTP_MEDIUM_TYPE medium_type; - - /* medium related */ - mctp_medium_conf medium_conf; - medium_rx read_data; - medium_tx write_data; - - /* read/write task */ - k_tid_t mctp_rx_task_tid; - k_tid_t mctp_tx_task_tid; - struct k_thread rx_task_thread_data; - struct k_thread tx_task_thread_data; - - K_KERNEL_STACK_MEMBER(rx_task_stack_area, MCTP_RX_TASK_STACK_SIZE); - K_KERNEL_STACK_MEMBER(tx_task_stack_area, MCTP_TX_TASK_STACK_SIZE); - uint8_t mctp_rx_task_name[MCTP_TASK_NAME_LEN]; - uint8_t mctp_tx_task_name[MCTP_TASK_NAME_LEN]; - - /* queue */ - struct k_msgq mctp_tx_queue; - - /* interface */ - struct mctp_interface_wrapper mctp_wrapper; - - /* command channel */ - struct cmd_channel mctp_cmd_channel; - - /* semaphore */ - struct k_sem rx_fifo_in_data_sem; - - /* sw mailbox device */ - const struct device *sw_mbx_dev; -} mctp; - -/* public function */ -mctp *mctp_init(void); -uint8_t mctp_deinit(mctp *mctp_inst); -uint8_t mctp_set_medium_configure(mctp *mctp_inst, MCTP_MEDIUM_TYPE medium_type, - mctp_medium_conf medium_conf); - -/* medium_conf should be freed by application */ -uint8_t mctp_get_medium_configure(mctp *mctp_inst, MCTP_MEDIUM_TYPE *medium_type, - mctp_medium_conf *medium_conf); -/* mctp service start */ -uint8_t mctp_start(mctp *mctp_inst); - -/* mctp service stop */ -uint8_t mctp_stop(mctp *mctp_inst); - -/* send/receive message to destination endpoint */ -uint8_t mctp_send_msg(mctp *mctp_inst, struct cmd_packet *packet); -uint8_t mctp_recv_msg(mctp *mctp_inst, struct cmd_packet *packet); - -/* medium init/deinit */ -uint8_t mctp_smbus_init(mctp *mctp_inst, mctp_medium_conf medium_conf); -uint8_t mctp_smbus_deinit(mctp *mctp_inst); - -uint8_t mctp_i3c_init(mctp *mctp_instance, mctp_medium_conf medium_conf); -uint8_t mctp_i3c_deinit(mctp *mctp_instance); diff --git a/apps/aspeed-pfr/src/mctp/plat_mctp.c b/apps/aspeed-pfr/src/mctp/plat_mctp.c index 4783385..082285c 100644 --- a/apps/aspeed-pfr/src/mctp/plat_mctp.c +++ b/apps/aspeed-pfr/src/mctp/plat_mctp.c @@ -8,11 +8,14 @@ #include #include #include +#include +#include #include "Smbus_mailbox/Smbus_mailbox.h" #include "mctp/mctp_interface_wrapper.h" -#include "mctp_utils.h" +#include "mctp.h" #include "plat_mctp.h" #include "cmd_channel_mctp.h" +#include "i3c/i3c_util.h" LOG_MODULE_REGISTER(plat_mctp, CONFIG_LOG_DEFAULT_LEVEL); @@ -62,7 +65,8 @@ mctp *find_mctp_by_smbus(uint8_t bus) void plat_mctp_init(void) { LOG_INF("plat_mctp_init"); - uint8_t i, rc; + uint8_t i; + int rc; if (gSwMbxDev == NULL) { LOG_ERR("without SWMBX device"); diff --git a/apps/aspeed-pfr/src/mctp/plat_mctp.h b/apps/aspeed-pfr/src/mctp/plat_mctp.h index 4e3fa6d..3348d54 100644 --- a/apps/aspeed-pfr/src/mctp/plat_mctp.h +++ b/apps/aspeed-pfr/src/mctp/plat_mctp.h @@ -6,7 +6,7 @@ #pragma once -#include "mctp_utils.h" +#include "mctp.h" typedef struct _mctp_smbus_port { mctp *mctp_inst; diff --git a/apps/aspeed-pfr/src/mctp/test_mctp_shell.c b/apps/aspeed-pfr/src/mctp/test_mctp_shell.c index 8145caa..4858d17 100644 --- a/apps/aspeed-pfr/src/mctp/test_mctp_shell.c +++ b/apps/aspeed-pfr/src/mctp/test_mctp_shell.c @@ -8,11 +8,10 @@ #include #include #include "mctp/mctp_interface.h" -#include "mctp_utils.h" +#include "mctp.h" #include "plat_mctp.h" #include "cmd_interface/device_manager.h" #include "logging/logging_wrapper.h" -#include "mctp.h" // #define MCTP_TEST_DEBUG static uint8_t request_buf[MCTP_BASE_PROTOCOL_MAX_MESSAGE_BODY] = {0}; diff --git a/apps/aspeed-pfr/src/pfr/pfr_common.c b/apps/aspeed-pfr/src/pfr/pfr_common.c index b1f5e64..6ee9066 100644 --- a/apps/aspeed-pfr/src/pfr/pfr_common.c +++ b/apps/aspeed-pfr/src/pfr/pfr_common.c @@ -239,4 +239,7 @@ void init_pfr_bases(void) get_recovery_pfm(), get_update_fw_base(), get_active_image()); +#if defined(CONFIG_INTEL_PFR) + init_pfr_authentication(get_pfr_manifest()->pfr_authentication); +#endif } diff --git a/apps/aspeed-pfr/src/pfr/pfr_common.h b/apps/aspeed-pfr/src/pfr/pfr_common.h index ee9044f..0344974 100644 --- a/apps/aspeed-pfr/src/pfr/pfr_common.h +++ b/apps/aspeed-pfr/src/pfr/pfr_common.h @@ -51,6 +51,8 @@ struct pfr_manifest { uint32_t intel_cpld_addr[3]; // CPU/SCM/Debug CPLD firmware addr uint32_t intel_cpld_img_size[3]; // CPU/SCM/Debug CPLD image size #endif + uint8_t update_intent1; + uint8_t update_intent2; }; struct active_image { diff --git a/apps/aspeed-pfr/src/pfr/pfr_recovery.c b/apps/aspeed-pfr/src/pfr/pfr_recovery.c index 71db98e..e7a4e65 100644 --- a/apps/aspeed-pfr/src/pfr/pfr_recovery.c +++ b/apps/aspeed-pfr/src/pfr/pfr_recovery.c @@ -18,11 +18,13 @@ #if defined(CONFIG_INTEL_PFR) #include "intel_pfr/intel_pfr_definitions.h" #include "intel_pfr/intel_pfr_recovery.h" +#include "intel_pfr/intel_pfr_provision.h" #endif #if defined(CONFIG_CERBERUS_PFR) #include "cerberus_pfr/cerberus_pfr_definitions.h" #include "cerberus_pfr/cerberus_pfr_recovery.h" #include "cerberus_pfr/cerberus_pfr_svn.h" +#include "cerberus_pfr/cerberus_pfr_provision.h" #endif #include "include/SmbusMailBoxCom.h" @@ -35,6 +37,7 @@ int recover_image(void *AoData, void *EventContext) int status = 0; AO_DATA *ActiveObjectData = (AO_DATA *) AoData; EVENT_CONTEXT *EventData = (EVENT_CONTEXT *) EventContext; + uint32_t act_pfm_addr; struct pfr_manifest *pfr_manifest = get_pfr_manifest(); @@ -43,9 +46,21 @@ int recover_image(void *AoData, void *EventContext) if (EventData->image == BMC_EVENT) { LOG_INF("Image Type: BMC"); pfr_manifest->image_type = BMC_TYPE; + if (get_provision_data_in_flash(PCH_ACTIVE_PFM_OFFSET, (uint8_t *)&act_pfm_addr, + sizeof(act_pfm_addr))) { + LOG_ERR("Failed to get PCH active PFM address"); + return Failure; + } + pfr_manifest->active_pfm_addr = act_pfm_addr; } else if (EventData->image == PCH_EVENT) { LOG_INF("Image Type: PCH"); pfr_manifest->image_type = PCH_TYPE; + if (get_provision_data_in_flash(PCH_ACTIVE_PFM_OFFSET, (uint8_t *)&act_pfm_addr, + sizeof(act_pfm_addr))) { + LOG_ERR("Failed to get PCH active PFM address"); + return Failure; + } + pfr_manifest->active_pfm_addr = act_pfm_addr; } #if defined(CONFIG_PFR_SPDM_ATTESTATION) #if (CONFIG_AFM_SPEC_VERSION == 4) @@ -80,15 +95,19 @@ int recover_image(void *AoData, void *EventContext) if (ActiveObjectData->RecoveryImageStatus != Success) { status = pfr_manifest->update_fw->base->verify((struct firmware_image *)pfr_manifest, NULL); if (status != Success) { - LOG_INF("PFR Staging Area Corrupted"); + LOG_ERR("PFR Staging Area Corrupted"); if (ActiveObjectData->ActiveImageStatus != Success) { /* Scenarios * Active | Recovery | Staging * 0 | 0 | 0 */ + uint8_t minor_err = ACTIVE_RECOVERY_STAGING_AUTH_FAIL; +#if defined(CONFIG_PFR_SPDM_ATTESTATION) + if (EventData->image == AFM_EVENT) + minor_err = AFM_ACTIVE_RECOVERY_STAGING_AUTH_FAIL; +#endif LogErrorCodes((pfr_manifest->image_type == BMC_TYPE ? - BMC_AUTH_FAIL : PCH_AUTH_FAIL), - ACTIVE_RECOVERY_STAGING_AUTH_FAIL); + BMC_AUTH_FAIL : PCH_AUTH_FAIL), minor_err); if (pfr_manifest->image_type == PCH_TYPE) { status = pfr_staging_pch_staging(pfr_manifest); if (status != Success) @@ -150,54 +169,9 @@ int recover_image(void *AoData, void *EventContext) return Success; } -/** - * Get the SHA-256 hash of the recovery image data, not including the signature. - * - * @param image The recovery image to query. - * @param hash The hash engine to use for generating the hash. - * @param hash_out Output buffer for the manifest hash. - * @param hash_length Length of the hash output buffer. - * - * @return 0 if the hash was calculated successfully or an error code. - */ -int recovery_get_hash(struct recovery_image *image, struct hash_engine *hash, uint8_t *hash_out, - size_t hash_length) -{ - - ARG_UNUSED(image); - ARG_UNUSED(hash); - ARG_UNUSED(hash_out); - ARG_UNUSED(hash_length); - - return Success; -} - -/** - * Get the version of the recovery image. - * - * @param image The recovery image to query. - * @param version The buffer to hold the version ID. - * @param len The output buffer length. - * - * @return 0 if the ID was successfully retrieved or an error code. - */ -int recovery_get_version(struct recovery_image *image, char *version, size_t len) -{ - - ARG_UNUSED(image); - ARG_UNUSED(version); - ARG_UNUSED(len); - - return Success; -} - void init_recovery_manifest(struct recovery_image *image) { image->verify = recovery_verify; - image->get_hash = recovery_get_hash; - image->get_version = recovery_get_version; - image->apply_to_flash = recovery_apply_to_flash; - } int pfr_recover_recovery_region(int image_type, uint32_t source_address, uint32_t target_address) diff --git a/apps/aspeed-pfr/src/pfr/pfr_update.c b/apps/aspeed-pfr/src/pfr/pfr_update.c index 689d301..ce401a5 100644 --- a/apps/aspeed-pfr/src/pfr/pfr_update.c +++ b/apps/aspeed-pfr/src/pfr/pfr_update.c @@ -5,97 +5,20 @@ */ #include -#include #include #include +#include "pfr_common.h" -#include "pfr_ufm.h" -#include "AspeedStateMachine/common_smc.h" #if defined(CONFIG_INTEL_PFR) -#include "intel_pfr/intel_pfr_definitions.h" -#include "intel_pfr/intel_pfr_provision.h" -#include "intel_pfr/intel_pfr_verification.h" #include "intel_pfr/intel_pfr_update.h" #endif #if defined(CONFIG_CERBERUS_PFR) -#include "cerberus_pfr/cerberus_pfr_definitions.h" -#include "cerberus_pfr/cerberus_pfr_provision.h" -#include "cerberus_pfr/cerberus_pfr_verification.h" #include "cerberus_pfr/cerberus_pfr_update.h" #endif -#include "gpio/gpio_aspeed.h" -#include "Smbus_mailbox/Smbus_mailbox.h" -#include "include/SmbusMailBoxCom.h" -#include "pfr_common.h" LOG_MODULE_DECLARE(pfr, CONFIG_LOG_DEFAULT_LEVEL); -/** - * Update the image referenced by an instance. - * - * @param fw The firmware image instance to update. - * @param flash The flash device that contains the firmware image. - * @param base_addr The starting address of the new firmware image. - * - * @return 0 if the image reference was updated successfully or an error code. Load-time - * validation errors will generate one of the following errors: - * - FIRMWARE_IMAGE_INVALID_FORMAT - * - FIRMWARE_IMAGE_BAD_CHECKSUM - * - KEY_MANIFEST_INVALID_FORMAT - * - FIRMWARE_HEADER validation errors - */ -int firmware_image_load(struct firmware_image *fw, struct flash *flash, uint32_t base_addr) -{ - return Success; -} - -/** - * Get the total size of the firmware image. - * - * @param fw The firmware image to query. - * - * @return The size of the firmware image or an error code. Use ROT_IS_ERROR to check the - * return value. - */ -int firmware_image_get_image_size(struct firmware_image *fw) -{ - ARG_UNUSED(fw); - return Success; -} - -/** - * Get the key manifest for the current firmware image. - * - * @param fw The firmware image to query. - * - * @return The image key manifest or null if there is an error. The memory for the key - * manifest is managed by the firmware image instance and is only guaranteed to be valid until - * the next call to 'load'. - */ -struct key_manifest *firmware_imag_eget_key_manifest(struct firmware_image *fw) -{ - ARG_UNUSED(fw); - return NULL; -} - -/** - * Get the main image header for the current firmware image. - * - * @param fw The firmware image to query. - * - * @return The image firmware header or null if there is an error. The memory for the header - * is managed by the firmware image instance and is only guaranteed to be valid until the next - * call to 'load'. - */ -struct firmware_header *firmware_image_get_firmware_header(struct firmware_image *fw) -{ - ARG_UNUSED(fw); - return NULL; -} - void init_update_fw_manifest(struct firmware_image *fw) { - // fw->load = firmware_image_load; fw->verify = firmware_image_verify; - // fw->get_image_size = firmware_image_get_image_size; } diff --git a/apps/aspeed-pfr/src/pfr/pfr_util.c b/apps/aspeed-pfr/src/pfr/pfr_util.c index ac8667e..3843a0e 100644 --- a/apps/aspeed-pfr/src/pfr/pfr_util.c +++ b/apps/aspeed-pfr/src/pfr/pfr_util.c @@ -136,8 +136,16 @@ uint32_t pfr_spi_get_device_size(uint8_t device_id) int pfr_spi_get_block_size(uint8_t device_id) { uint32_t block_size; + uint8_t flash_id; - block_size = get_block_erase_size(device_id); + if (device_id >= ROT_INTERNAL_ACTIVE && device_id < ROT_EXT_AFM_ACT_1) + flash_id = ROT_SPI; + else if (device_id >= ROT_EXT_AFM_ACT_1) + flash_id = ROT_EXT_SPI; + else + flash_id = device_id; + + block_size = get_block_erase_size(flash_id); return block_size; } diff --git a/apps/aspeed-pfr/src/platform_monitor/platform_monitor.c b/apps/aspeed-pfr/src/platform_monitor/platform_monitor.c index cba2967..d5ab008 100644 --- a/apps/aspeed-pfr/src/platform_monitor/platform_monitor.c +++ b/apps/aspeed-pfr/src/platform_monitor/platform_monitor.c @@ -11,11 +11,18 @@ #include "watchdog_timer/wdt_utils.h" #include "watchdog_timer/wdt_handler.h" #include "platform_monitor.h" +#include "gpio/gpio_aspeed.h" +#if defined(CONFIG_PFR_MCTP) #include "mctp/mctp.h" +#if defined(CONFIG_PFR_MCTP_I3C) +#include "mctp/mctp_i3c.h" +#endif +#endif LOG_MODULE_REGISTER(monitor, CONFIG_LOG_DEFAULT_LEVEL); extern struct k_work log_bmc_rst_work; +extern struct k_sem pltrst_sem; extern uint8_t gWdtBootStatus; static struct gpio_callback bmc_rstind_cb_data; static void platform_reset_monitor_remove(void); @@ -55,6 +62,7 @@ void bmc_reset_monitor_remove(void) #ifdef SUPPORT_PLTRST static struct gpio_callback rst_pltrst_cb_data; +extern bool i3c_hub_configured; /** * Arm the ACM watchdog timer when ROT firmware detects a platform reset @@ -67,9 +75,18 @@ static void platform_reset_handler(const struct device *dev, struct gpio_callbac int ret = gpio_pin_get(dev, gpio_pin); LOG_INF("[CPU->PFR] PLTRST_SYNC[%s %d] = %d", dev->name, gpio_pin, ret); - platform_reset_monitor_remove(); - extern bool pltrst_sync; - pltrst_sync = true; + // platform_reset_monitor_remove(); + if (ret == 0) { + RSTPlatformReset(true); + } else { + RSTPlatformReset(false); + // platform_reset_monitor_remove(); + extern bool pltrst_sync; + pltrst_sync = true; +#if defined(CONFIG_PFR_MCTP_I3C) + k_sem_give(&pltrst_sem); +#endif + } #endif #ifdef INTEL_EGS @@ -103,7 +120,7 @@ static void platform_reset_monitor_init(void) ret = gpio_pin_configure_dt(&rst_pltrst, GPIO_INPUT); LOG_INF("Platform: gpio_pin_configure_dt[%s %d] = %d", rst_pltrst.port->name, rst_pltrst.pin, ret); - ret = gpio_pin_interrupt_configure_dt(&rst_pltrst, GPIO_INT_EDGE_RISING); + ret = gpio_pin_interrupt_configure_dt(&rst_pltrst, GPIO_INT_EDGE_BOTH); LOG_INF("Platform: gpio_pin_interrupt_configure_dt = %d", ret); gpio_init_callback(&rst_pltrst_cb_data, platform_reset_handler, BIT(rst_pltrst.pin)); ret = gpio_add_callback(rst_pltrst.port, &rst_pltrst_cb_data); diff --git a/apps/aspeed-pfr/src/spi_filter/CMakeLists.txt b/apps/aspeed-pfr/src/spi_filter/CMakeLists.txt new file mode 100644 index 0000000..5c71966 --- /dev/null +++ b/apps/aspeed-pfr/src/spi_filter/CMakeLists.txt @@ -0,0 +1,3 @@ +# Copyright (c) 2024 ASPEED Technology Inc. +# SPDX-License-Identifier: MIT +target_sources(app PRIVATE spim_util.c) diff --git a/lib/hrot_hal/spi_filter/spi_filter_aspeed.c b/apps/aspeed-pfr/src/spi_filter/spim_util.c similarity index 73% rename from lib/hrot_hal/spi_filter/spi_filter_aspeed.c rename to apps/aspeed-pfr/src/spi_filter/spim_util.c index 41443c5..948bd68 100644 --- a/lib/hrot_hal/spi_filter/spi_filter_aspeed.c +++ b/apps/aspeed-pfr/src/spi_filter/spim_util.c @@ -1,12 +1,12 @@ /* - * Copyright (c) 2022 ASPEED Technology Inc. + * Copyright (c) 2024 ASPEED Technology Inc. * * SPDX-License-Identifier: MIT */ #include #include -#include +#include #include #include #include @@ -14,7 +14,7 @@ #include #include -void SPI_Monitor_Enable(char *dev_name, bool enabled) +void SPI_Monitor_Enable(const char *dev_name, bool enabled) { const struct device *dev_m = NULL; @@ -26,7 +26,7 @@ void SPI_Monitor_Enable(char *dev_name, bool enabled) spim_monitor_enable(dev_m, 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) +int Set_SPI_Filter_RW_Region(const char *dev_name, enum addr_priv_rw_select rw_select, enum addr_priv_op op, mm_reg_t addr, uint32_t len) { int ret = 0; const struct device *dev_m = NULL; diff --git a/apps/aspeed-pfr/src/spi_filter/spim_util.h b/apps/aspeed-pfr/src/spi_filter/spim_util.h new file mode 100644 index 0000000..1da5071 --- /dev/null +++ b/apps/aspeed-pfr/src/spi_filter/spim_util.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2024 ASPEED Technology Inc. + * + * SPDX-License-Identifier: MIT + */ + +#pragma once + +#include +#include +#include +#include + +#define SPI_FILTER_READ_PRIV 0 +#define SPI_FILTER_WRITE_PRIV 1 + +#define SPI_FILTER_PRIV_ENABLE 0 +#define SPI_FILTER_PRIV_DISABLE 1 + +void SPI_Monitor_Enable(const char *dev_name, bool enabled); +int Set_SPI_Filter_RW_Region(const char *dev_name, enum addr_priv_rw_select rw_select, enum addr_priv_op op, mm_reg_t addr, uint32_t len); + diff --git a/apps/aspeed-pfr/src/watchdog_timer/wdt_handler.c b/apps/aspeed-pfr/src/watchdog_timer/wdt_handler.c index 8bc87e0..aa1377c 100644 --- a/apps/aspeed-pfr/src/watchdog_timer/wdt_handler.c +++ b/apps/aspeed-pfr/src/watchdog_timer/wdt_handler.c @@ -40,6 +40,7 @@ void bmc_wdt_handler(uint8_t cmd) // BMC stays in uboot or in FFUJ(Force Firmware Update Jumper (FFUJ)) mode // Take over i3c MNG #if defined(CONFIG_PFR_MCTP_I3C) + SetPfrActivityInfo1(PFR_ACT1_I3C_MUX_TAKEOVER); switch_i3c_mng_owner(I3C_MNG_OWNER_ROT); #endif } else if (cmd == ResumedExecutionBlock) { @@ -56,6 +57,7 @@ void bmc_wdt_handler(uint8_t cmd) // Clear the fw recovery level upon successful boot reset_recovery_level(BMC_SPI); #endif + SetPfrActivityInfo2(PFR_ACT2_BMC_BOOT_DONE); log_t0_timed_boot_complete_if_ready(T0_BMC_BOOTED); } } @@ -171,6 +173,7 @@ void bios_wdt_handler(uint8_t cmd) reset_recovery_level(PCH_SPI); #endif // Log boot progress + SetPfrActivityInfo2(PFR_ACT2_OBB_BOOT_DONE); log_t0_timed_boot_complete_if_ready(T0_BIOS_BOOTED); } else if (cmd == AUTHENTICATION_FAILED) { LOG_ERR("OBB authentication failed"); @@ -196,6 +199,7 @@ void bios_wdt_handler(uint8_t cmd) gWdtBootStatus |= WDT_IBB_BOOT_DONE_MASK; // Start the BIOS OBB timer. pfr_start_timer(type, ms_timeout); + SetPfrActivityInfo2(PFR_ACT2_IBB_BOOT_DONE); } else if (cmd == AUTHENTICATION_FAILED) { LOG_ERR("IBB authentication failed"); pfr_stop_timer(type); diff --git a/apps/aspeed-pfr/src/watchdog_timer/wdt_utils.c b/apps/aspeed-pfr/src/watchdog_timer/wdt_utils.c index 2701e1f..c495704 100644 --- a/apps/aspeed-pfr/src/watchdog_timer/wdt_utils.c +++ b/apps/aspeed-pfr/src/watchdog_timer/wdt_utils.c @@ -19,11 +19,19 @@ uint8_t gWdtBootStatus = 0; static void wdt_callback_bmc_timeout(struct k_timer *tmr) { union aspeed_event_data data = {0}; + byte update_intent = GetBmcUpdateIntent2(); data.bit8[0] = BMC_EVENT; LOG_ERR("BMC Boot WDT Timeout"); - LogWatchdogRecovery(BMC_LAUNCH_FAIL, BMC_WDT_EXPIRE); - GenerateStateMachineEvent(WDT_TIMEOUT, data.ptr); + if (update_intent & SeamlessUpdateAck) { + LOG_ERR("BMC doesn't clear seamless update ACK"); + update_intent &= ~SeamlessUpdateAck; + SetBmcUpdateIntent2(update_intent); + GenerateStateMachineEvent(RESET_DETECTED, NULL); + } else { + LogWatchdogRecovery(BMC_LAUNCH_FAIL, BMC_WDT_EXPIRE); + GenerateStateMachineEvent(WDT_TIMEOUT, data.ptr); + } ARG_UNUSED(tmr); } #if defined(CONFIG_INTEL_PFR) @@ -148,3 +156,24 @@ void pfr_stop_timer(int type) } } +uint32_t pfr_timer_remaining_get(int type) +{ + uint32_t remaining = 0; + + if (type == BMC_TIMER) + remaining = k_timer_remaining_get(&pfr_bmc_timer); +#if defined(CONFIG_INTEL_PFR) + else if (type == ACM_TIMER) + remaining = k_timer_remaining_get(&pfr_acm_timer); +#ifdef SUPPORT_ME + else if (type == ME_TIMER) + remaining = k_timer_remaining_get(&pfr_me_timer); + +#endif +#endif + else if (type == BIOS_TIMER) + remaining = k_timer_remaining_get(&pfr_bios_timer); + + return remaining; +} + diff --git a/apps/aspeed-pfr/src/watchdog_timer/wdt_utils.h b/apps/aspeed-pfr/src/watchdog_timer/wdt_utils.h index 74b8633..c7490f9 100644 --- a/apps/aspeed-pfr/src/watchdog_timer/wdt_utils.h +++ b/apps/aspeed-pfr/src/watchdog_timer/wdt_utils.h @@ -49,4 +49,5 @@ enum _pfr_timer { uint8_t is_timed_boot_done(void); void pfr_start_timer(int type, uint32_t ms_timeout); void pfr_stop_timer(int type); +uint32_t pfr_timer_remaining_get(int type); diff --git a/apps/aspeed-pfr/tools/intel/README.md b/apps/aspeed-pfr/tools/intel/README.md index 8c70ca9..8bef97a 100644 --- a/apps/aspeed-pfr/tools/intel/README.md +++ b/apps/aspeed-pfr/tools/intel/README.md @@ -1,9 +1,33 @@ # Required Packages - [intel-pfr-signing-utility](https://github.com/Intel-BMC/intel-pfr-signing-utility) -Download intel pfr signing utility and compile. +This is the Intel(R) Platform Firmware Resilience Signing Utility. ASPEED created some [pull requests](https://github.com/Intel-BMC/intel-pfr-signing-utility/pulls) to fix this tool issues. However, these pull requests does not be reviewed, yet. Please apply the following patches before complie it. + +Users can download these patches from [AspeedTech-BMC/openbmc](https://github.com/AspeedTech-BMC/openbmc/tree/aspeed-master/meta-aspeed-sdk/meta-aspeed-pfr/recipes-intel/pfr/intel-pfr-signing-utility) +``` +0001-support-openssl-3.0.patch +0002-fix-verify-error-if-block1-b0sig-hashalg-set-to-sha384.patch +0003-Fix-signature-RS-extration-error.patch +``` # Keys +## Generating Root Keys and Code Signing Keys +- ECDSA 256 +``` +openssl ecparam -name secp256r1 -genkey -out rk_prv.pem +openssl ec -in rk_prv.pem -pubout -out rk_pub.pem +openssl ecparam -name secp256r1 -genkey -out csk_prv.pem +openssl ec -in csk_prv.pem -pubout -out csk_pub.pem +``` + +- ECDSA 384 +``` +openssl ecparam -name secp384r1 -genkey -out rk384_prv.pem +openssl ec -in rk384_prv.pem -pubout -out rk384_pub.pem +openssl ecparam -name secp384r1 -genkey -out csk384_prv.pem +openssl ec -in csk384_prv.pem -pubout -out csk384_pub.pem +``` + ## secp256r1 (ECDSA 256) - root private key: `rk_prv.pem` - root public key: `rk_pub.pem` diff --git a/apps/aspeed-pfr/tools/intel/bhs_afm_manifest_pfm.json b/apps/aspeed-pfr/tools/intel/bhs_afm_manifest_pfm.json index d1df724..7abed55 100644 --- a/apps/aspeed-pfr/tools/intel/bhs_afm_manifest_pfm.json +++ b/apps/aspeed-pfr/tools/intel/bhs_afm_manifest_pfm.json @@ -15,7 +15,7 @@ "device_platform_model" : "0x0011223344556677", "device_platform_version" : "0x9a9a", "afm_length" : "0x2000", - "afm_addr" : "0x4000800" + "afm_addr" : "0x4001000" } }, "afm_data" : { "device0" : { diff --git a/apps/aspeed-pfr/tools/intel/platforms/example-a/create_bios_pfr_image.sh b/apps/aspeed-pfr/tools/intel/platforms/example-a/create_bios_pfr_image.sh new file mode 100755 index 0000000..bbbf575 --- /dev/null +++ b/apps/aspeed-pfr/tools/intel/platforms/example-a/create_bios_pfr_image.sh @@ -0,0 +1,148 @@ +#!/bin/bash + +# Input setting +PLATFORM_NAME="plta" +BIOS_ACTIVE_IMAGE="$1" +if ! test -f "${BIOS_ACTIVE_IMAGE}"; then + echo "Invalid BIOS active image: $1" + exit 1 +fi + +# 1 = SHA256 +# 2 = SHA384 +PFR_SHA="$2" +if test "x${PFR_SHA}" = "x1"; then + echo "SHA256..." + PFM_CONFIG_XML="${PLATFORM_NAME}_bios_pfm_config_secp256r1.xml" + BIOS_CONFIG_XML="${PLATFORM_NAME}_bios_config_secp256r1.xml" +elif test "x${PFR_SHA}" = "x2"; then + echo "SHA384..." + PFM_CONFIG_XML="${PLATFORM_NAME}_bios_pfm_config_secp384r1.xml" + BIOS_CONFIG_XML="${PLATFORM_NAME}_bios_config_secp384r1.xml" +else + echo "Invalid hash algorithm:${PFR_SHA}" + echo "Only support 1:sha256 and 2:sha384" + exit 1 +fi + +# PFM setting +PFR_SVN="1" +PFR_BKC_VER="1" +PFR_BUILD_VER_MAJ="1" +PFR_BUILD_VER_MIN="0" +PFR_BUILD_NUM="787788" +PFM_JSON_FILE="${PLATFORM_NAME}_bios_pfm.json" +PFM_UNSIGNED_BIN="${PLATFORM_NAME}-pfm.bin" +PFM_SIGNED_BIN="${PFM_UNSIGNED_BIN}.signed" + +# Image setting +BIOS_IMAGE_TEMP="image-bios-temp" +BIOS_PFR_IMAGE="image-bios-pfr" +# Size unit kb +PFR_IMAGE_SIZE="65536" +PFR_RECOVERY_OFFSET="44992" +PFR_PFM_OFFSET="65472" + +# Update capsule setting +BIOS_UPDATE_CAPSULE="${PLATFORM_NAME}-bios_cap.bin" +BIOS_PBC_BIN="${PLATFORM_NAME}-pbc.bin" +BIOS_COMPRESSED_BIN="${PLATFORM_NAME}-bios_compressed.bin" +BIOS_SIGNED_UPDATE_CAPSULE="${BIOS_UPDATE_CAPSULE}.signed" +BIOS_SIGNED_UPDATE_CAPSULE_LINK="bios_signed_cap.bin" + +mk_empty_image() { + image_dst="$1" + image_size_kb=$2 + dd if=/dev/zero bs=1k count=$image_size_kb \ + | tr '\000' '\377' > $image_dst +} + +rm -rf ${BIOS_IMAGE_TEMP} +rm -rf ${BIOS_PFR_IMAGE} +rm -rf *.bin +rm -rf *.bin* + +# Generate the unsigned PFM from the BIOS active image +echo "Generate the unsigned PFM from the ${BIOS_ACTIVE_IMAGE} image..." + +# Assemble the flash image +mk_empty_image ${BIOS_IMAGE_TEMP} ${PFR_IMAGE_SIZE} +dd bs=1k conv=notrunc seek=0 \ + if=${BIOS_ACTIVE_IMAGE}\ + of=${BIOS_IMAGE_TEMP} + +python3 pfr_image.py \ + -m ${PFM_JSON_FILE} \ + -p ${PLATFORM_NAME} \ + -i ${BIOS_IMAGE_TEMP} \ + -j ${PFR_BUILD_VER_MAJ} \ + -n ${PFR_BUILD_VER_MIN} \ + -b ${PFR_BUILD_NUM} \ + -v ${PFR_BKC_VER} \ + -s ${PFR_SVN} \ + -a ${PFR_SHA} \ + -o ${BIOS_PFR_IMAGE} + +if [ $? -ne 0 ]; then + echo "!!!Generate the unsigned PFM failed.!!!" + exit 1 +fi + +mv ${PLATFORM_NAME}-bmc_compressed.bin ${PLATFORM_NAME}-bios_compressed.bin + +# Sign the PFM +echo "Sign the PFM..." +./intel-pfr-signing-utility -c ${PFM_CONFIG_XML} -o ${PFM_SIGNED_BIN} ${PFM_UNSIGNED_BIN} -v +if [ $? -ne 0 ]; then + echo "!!!Sign the PFM failed.!!!" + exit 1 +fi + +# Verify the PFM +echo "Verify the PFM.." +./intel-pfr-signing-utility -p ${PFM_SIGNED_BIN} -c ${PFM_CONFIG_XML} +if [ $(./intel-pfr-signing-utility -p ${PFM_SIGNED_BIN} -c ${PFM_CONFIG_XML} 2>&1 | grep "ERR" | wc -c) -gt 0 ]; then + echo "!!!Verify the PFM failed.!!!" + exit 1 +fi + +# Add the signed PFM to the BIOS full ROM image at the PFM offset +echo "Add the signed PFM to the BIOS full ROM image at the offset: ${PFR_PFM_OFFSET}kb" +dd bs=1k conv=notrunc seek=${PFR_PFM_OFFSET} \ + if=${PFM_SIGNED_BIN} \ + of=${BIOS_PFR_IMAGE} + +# Create the unsigned BIOS image update capsule +# append with 1. pfm_signed, 2. pbc, 3. bios compressed +echo "Create the unsigned BIOS image update capsule..." +echo "append with 1:${PFM_SIGNED_BIN}, 2:${BIOS_PBC_BIN}, 3:${BIOS_COMPRESSED_BIN}" +dd if=${PFM_SIGNED_BIN} bs=1k >> ${BIOS_UPDATE_CAPSULE} +dd if=${BIOS_PBC_BIN} bs=1k >> ${BIOS_UPDATE_CAPSULE} +dd if=${BIOS_COMPRESSED_BIN} bs=1k >> ${BIOS_UPDATE_CAPSULE} + +# Sign the BIOS update capsule +echo "Sign the BIOS update capsule..." +./intel-pfr-signing-utility -c ${BIOS_CONFIG_XML} -o ${BIOS_SIGNED_UPDATE_CAPSULE} ${BIOS_UPDATE_CAPSULE} -v +if [ $? -ne 0 ]; then + echo "!!!Sign the BIOS update capsule failed.!!!" + exit 1 +fi + +# Verify the update capsule +echo "Verify the update capsule.." +./intel-pfr-signing-utility -p ${BIOS_SIGNED_UPDATE_CAPSULE} -c ${BIOS_CONFIG_XML} +if [ $(./intel-pfr-signing-utility -p ${BIOS_SIGNED_UPDATE_CAPSULE} -c ${BIOS_CONFIG_XML} 2>&1 | grep "ERR" | wc -c) -gt 0 ]; then + echo "!!!Verify the update capsule failed.!!!" + exit 1 +fi + +ln -sf ${BIOS_SIGNED_UPDATE_CAPSULE} ${BIOS_SIGNED_UPDATE_CAPSULE_LINK} + +# Add the signed BIOS update capsule to the BIOS full ROM image at the Recovery offset +echo "Add the signed BIOS update capsule to the BIOS full ROM image at the Recovery offset: ${PFR_RECOVERY_OFFSET}kb" +dd bs=1k conv=notrunc seek=${PFR_RECOVERY_OFFSET} \ + if=${BIOS_SIGNED_UPDATE_CAPSULE} \ + of=${BIOS_PFR_IMAGE} + +echo "Successfully create a BIOS PFR image: ${BIOS_PFR_IMAGE}" + diff --git a/apps/aspeed-pfr/tools/intel/platforms/example-a/generate_bios_pfr_image.md b/apps/aspeed-pfr/tools/intel/platforms/example-a/generate_bios_pfr_image.md new file mode 100644 index 0000000..d314a47 --- /dev/null +++ b/apps/aspeed-pfr/tools/intel/platforms/example-a/generate_bios_pfr_image.md @@ -0,0 +1,238 @@ +# Introduction +This documentation briefly introduce users how to use Intel Platform Firmware Resilience(Intel PFR) tools create Platform Firmware Manifest(PFM) and BIOS update capsule from the BIOS active image, sign the PFM and BIOS update capsule using the `intel-pfr-signing-utility`. Add the signed PFM and signed BIOS update capsule to the BIOS full ROM image compatible Intel PFR. + +# Required Tools +- [intel-pfr-signing-utility](https://github.com/Intel-BMC/intel-pfr-signing-utility) + Please see [tools/README.md](../../README.md) for detail. +- [pfr_image.py](https://github.com/AspeedTech-BMC/openbmc/blob/aspeed-master/meta-aspeed-sdk/meta-aspeed-pfr/recipes-intel/pfr/files/pfr_image.py) + This is the python script for Platform Firmware Manifest(PFM) and update capsule creation. ASPEED copy this python script, [pfr_image.py](https://github.com/Intel-BMC/openbmc/blob/1-release/meta-openbmc-mods/meta-common/recipes-intel/intel-pfr/files/pfr_image.py) from [Intel-BMC/openbmc](https://github.com/Intel-BMC/openbmc) to [AspeedTech-BMC/openbmc](https://github.com/AspeedTech-BMC/openbmc). Execute this scripts with Python 3.6 or later. + +# Flash layout +In this example, the size of BIOS active image is 16MB and the BIOS full ROM image size is 64MB, the partition layout is below: + +|Contents |Start Address|End Address(-1) |Size(KB)| Type | +|--------------------------- |-------------|------------------|--------|---------| +|Reserved-1 |0x0000_0000 |0x0002_0000 |128 |Static | +|Embedded Firmware Signature |0x0002_0000 |0x0002_4000 |16 |Static | +|NVRAM |0x0002_4000 |0x0004_4000 |128 |Dynamic | +|NVRAM Backup |0x0004_4000 |0x0006_4000 |128 |Dynamic | +|PSP Data |0x0006_4000 |0x007D_4000 |7616 |Static | +|OEM NCB |0x007D_4000 |0x007E_4000 |64 |Dyanmic | +|GPNV |0x007E_4000 |0x007F_4000 |64 |Dynamic | +|WHEA |0x007F_4000 |0x0080_4000 |64 |Dynamic | +|FV_MAIN |0x0080_4000 |0x00CA_0000 |4720 |Static | +|FV_BB |0x00CA_0000 |0x0100_0000 |3456 |Static | +|Reserved-2 |0x0100_0000 |0x017F_0000 |8128 |Static | +|Staging |0x017F_0000 |0x02BF_0000 |20480 |Dynamic | +|Recovery |0x02BF_0000 |0x03FF_0000 |20480 |Static | +|PFM |0x03FF_0000 |0x0400_0000 |64 |Static | + +# Create BIOS full ROM image +- Input: + - BIOS active image whose size is **16MB** + - Key pair generated with OpenSSL. Please see [tools/README.md](../../README.md) for detail. + - A JSON file defines the firmware manifestation including SPI image layout. + - XML files for the PFM and update capsule file signing with the `intel-pfr-signing-utility` +- Output: + - BISO full ROM image whose size is **64MB**. It includes BIOS active image, signed PFM and signed BIOS update capsule. + +## Generate the unsigned PFM from the BIOS active image +- input + - BIOS active image whose size is 16MB. + - JSON file: plta_bios_pfm.json +- output + - the unsigned PFM: plta-pfm.bin + - the pbc: plta-pbc.bin + - the compressed binary: plta-bios_compressed.bin + - the BIOS full ROM image: image-bios-pfr. It includes BIOS active image at offset 0 in this step. + + Both plta-pbc.bin and plta-bios_compressed.bin are used for unsigned BIOS update capsule generation. + +- Script: + - Generate a temporary full `64MB` image and places BIOS active imagae at the offest `0`. + - It set BKC version `1`. So far, PFR firmware only supports this version. + - It set SVN `1`, major version `1`, minor version `0` and build number `787788` by default. + - Execute `pfr_image.py` to generate the unsigned PFM, pbc and compressed binary. + +``` +PFR_SHA="$2" +if test "x${PFR_SHA}" = "x1"; then + echo "SHA256..." + PFM_CONFIG_XML="${PLATFORM_NAME}_bios_pfm_config_secp256r1.xml" + BIOS_CONFIG_XML="${PLATFORM_NAME}_bios_config_secp256r1.xml" +elif test "x${PFR_SHA}" = "x2"; then + echo "SHA384..." + PFM_CONFIG_XML="${PLATFORM_NAME}_bios_pfm_config_secp384r1.xml" + BIOS_CONFIG_XML="${PLATFORM_NAME}_bios_config_secp384r1.xml" +else + echo "Invalid hash algorithm:${PFR_SHA}" + echo "Only support 1:sha256 and 2:sha384" + exit 1 +fi + +PFR_SVN="1" +PFR_BKC_VER="1" +PFR_BUILD_VER_MAJ="1" +PFR_BUILD_VER_MIN="0" +PFR_BUILD_NUM="787788" +PFM_JSON_FILE="plta_bios_pfm.json" + +# Image setting +BIOS_IMAGE_TEMP="image-bios-temp" +BIOS_PFR_IMAGE="image-bios-pfr" +# Size unit KB +PFR_IMAGE_SIZE="65536" + +mk_empty_image ${BIOS_IMAGE_TEMP} ${PFR_IMAGE_SIZE} +dd bs=1k conv=notrunc seek=0 \ + if=${BIOS_ACTIVE_IMAGE}\ + of=${BIOS_IMAGE_TEMP} + +python3 pfr_image.py \ + -m ${PFM_JSON_FILE} \ + -p ${PLATFORM_NAME} \ + -i ${BIOS_IMAGE_TEMP} \ + -j ${PFR_BUILD_VER_MAJ} \ + -n ${PFR_BUILD_VER_MIN} \ + -b ${PFR_BUILD_NUM} \ + -v ${PFR_BKC_VER} \ + -s ${PFR_SVN} \ + -a ${PFR_SHA} \ + -o ${BIOS_PFR_IMAGE} +``` + +## Sign the PFM +- input + - the unsigned PFM: plta-pfm.bin + - algorithm: ecdsa 384 + - the XML config: plta_bios_pfm_config_secp384r1.xml. + - root keys: rk384_prv.pem and rk384_pub.pem + - csk keys: csk384_prv.pem and csk384_pub.pem + - algotithm: ecdsa 256 + - the XML config: plta_bios_pfm_config_secp256r1.xml. + - root keys: rk_prv.pem and rk_pub.pem + - csk keys: csk_prv.pem and csk_pub.pem +- output + - the signed PFM: plta-pfm.bin.signed +- script + - Sign the PFM using intel-pfr-signing-utility + +``` +# PFM setting +PFM_UNSIGNED_BIN="${PLATFORM_NAME}-pfm.bin" +PFM_SIGNED_BIN="${PFM_UNSIGNED_BIN}.signed" + +# Sign the PFM +./intel-pfr-signing-utility -c ${PFM_CONFIG_XML} -o ${PFM_SIGNED_BIN} ${PFM_UNSIGNED_BIN} -v +``` + +## Add the signed PFM to the BIOS full ROM image at the PFM offset 0x03FF_0000 +- input + - the signed PFM: plta-pfm.bin.signed +- output + - the BIOS full ROM image: image-bios-pfr. It includes signed PFM at offset 0x03FF_0000 in this step. +- script: + - The 0x03FF_0000 is equal 65472kb +``` +PFR_PFM_OFFSET="65472" + +dd bs=1k conv=notrunc seek=${PFR_PFM_OFFSET} \ + if=${PFM_SIGNED_BIN} \ + of=${BIOS_PFR_IMAGE} +``` + +## Create the unsigned BIOS image update capsule +- input + - the signed PFM: plta-pfm.bin.signed + - the pbc: plta-pbc.bin + - the compressed binary: plta-bios_compressed.bin +- output + - the unsigned BIOS update capsule: plta-bios_cap.bin +- script + - append with 1. signed PFM, 2. pbc, 3. BIOS compressed + +``` +# Update capsule setting +BIOS_UPDATE_CAPSULE="${PLATFORM_NAME}-bios_cap.bin" +BIOS_PBC_BIN="${PLATFORM_NAME}-pbc.bin" +BIOS_COMPRESSED_BIN="${PLATFORM_NAME}-bios_compressed.bin" + +dd if=${PFM_SIGNED_BIN} bs=1k >> ${BIOS_UPDATE_CAPSULE} +dd if=${BIOS_PBC_BIN} bs=1k >> ${BIOS_UPDATE_CAPSULE} +dd if=${BIOS_COMPRESSED_BIN} bs=1k >> ${BIOS_UPDATE_CAPSULE} +``` + +## Sign the BIOS update capsule +- input + - the unsigned BIOS update capsule: plta-bios_cap.bin + - algorithm ecdsa 384 + - the XML config: plta_bios_config_secp384r1.xml. + - root keys: rk384_prv.pem and rk384_pub.pem + - csk keys: csk384_prv.pem and csk384_pub.pem + - algotithm ecdsa 256 + - the XML config: plta_bios_config_secp256r1.xml. + - root keys: rk_prv.pem and rk_pub.pem + - csk keys: csk_prv.pem and csk_pub.pem +- output + - the signed BIOS update capsule: `plta-bios_cap.bin.signed` and `bios_signed_cap.bin` which is a softlink. +- script + - Sign the BIOS update capsule using intel-pfr-signing-utility + +``` +# Update capsule setting +BIOS_UPDATE_CAPSULE="${PLATFORM_NAME}-bios_cap.bin" +BIOS_SIGNED_UPDATE_CAPSULE="${BIOS_UPDATE_CAPSULE}.signed" +BIOS_SIGNED_UPDATE_CAPSULE_LINK="bios_signed_cap.bin" + +# Sign the BIOS update capsule +echo "Sign the BIOS update capsule..." +./intel-pfr-signing-utility -c ${BIOS_CONFIG_XML} -o ${BIOS_SIGNED_UPDATE_CAPSULE} ${BIOS_UPDATE_CAPSULE} -v + +ln -sf ${BIOS_SIGNED_UPDATE_CAPSULE} ${BIOS_SIGNED_UPDATE_CAPSULE_LINK} +``` + +## Add the signed BIOS update capsule to the BIOS full ROM image at the Recovery offset 0x02BF_0000 +- input + - the signed BIOS update capsule: plta-bios_cap.bin.signed +- output + - the BIOS full ROM image: image-bios-pfr. It includes signed BIOS update capsule at offset 0x02BF_0000 in this step. +- script: + - The 0x02BF_0000 is equal 44992kb +``` +PFR_RECOVERY_OFFSET="44992" + +dd bs=1k conv=notrunc seek=${PFR_RECOVERY_OFFSET} \ + if=${BIOS_SIGNED_UPDATE_CAPSULE} \ + of=${BIOS_PFR_IMAGE} +``` + +# Run create_bios_pfr_image.sh to generate BIOS PFR image +According to the design of Intel PFR spec, if users want to create a signature with `ECDSA 384` algorithm, it is required to use `sha384` hash algorithm. If users want to create a signature with `ECDSA 256`, it is required to use `sha256` hash algorithm. + +The name of users BIOS active image: `bios_active_image` +ASPEED PFR Keys: copy keys from `apps/aspeed-pfr/tools/intel/` to this directory. + +- sha384 with ecdsa384 +``` +./create_bios_pfr_image.sh bios_active_image 2 +``` + +- sha256 with ecdsa256 +``` +./create_bios_pfr_image.sh bios_active_image 1 +``` + +# Notice +- Please ensuer provisioning the correct offsets of BIOS active, recovery and staging regions. + + |Region |offset | + |----------|------------| + |Active |0x03FF_0000 | + |Recovery |0x02BF_0000 | + |Staging |0x017F_0000 | + +- The size of BIOS staging region is `20MB`. Please ensure to set the correct size in users configs. + +``` +CONFIG_PCH_STAGING_SIZE=0x1400000 +``` diff --git a/apps/aspeed-pfr/tools/intel/platforms/example-a/plta_bios_config_secp256r1.xml b/apps/aspeed-pfr/tools/intel/platforms/example-a/plta_bios_config_secp256r1.xml new file mode 100644 index 0000000..f2cab71 --- /dev/null +++ b/apps/aspeed-pfr/tools/intel/platforms/example-a/plta_bios_config_secp256r1.xml @@ -0,0 +1,48 @@ + + + + 1 + + + 0xB6EAFD19 + 2 + + + + 0xF27F28D7 + + + 0xA757A046 + 0xC7B88C74 + -1 + -1 + rk_pub.pem + + + + 0x14711C2F + 0xC7B88C74 + 2 + 1 + csk_pub.pem + 0xDE64437D + sha256 + rk_prv.pem + + + + + 0x15364367 + 0xDE64437D + sha256 + csk_prv.pem + + + + + + 1024 + + 128 + + diff --git a/apps/aspeed-pfr/tools/intel/platforms/example-a/plta_bios_config_secp384r1.xml b/apps/aspeed-pfr/tools/intel/platforms/example-a/plta_bios_config_secp384r1.xml new file mode 100644 index 0000000..6d2d0b9 --- /dev/null +++ b/apps/aspeed-pfr/tools/intel/platforms/example-a/plta_bios_config_secp384r1.xml @@ -0,0 +1,48 @@ + + + + 1 + + + 0xB6EAFD19 + 2 + + + + 0xF27F28D7 + + + 0xA757A046 + 0x08F07B47 + -1 + -1 + rk384_pub.pem + + + + 0x14711C2F + 0x08F07B47 + 2 + 1 + csk384_pub.pem + 0xEA2A50E9 + sha384 + rk384_prv.pem + + + + + 0x15364367 + 0xEA2A50E9 + sha384 + csk384_prv.pem + + + + + + 1024 + + 128 + + diff --git a/apps/aspeed-pfr/tools/intel/platforms/example-a/plta_bios_pfm.json b/apps/aspeed-pfr/tools/intel/platforms/example-a/plta_bios_pfm.json new file mode 100644 index 0000000..1948d56 --- /dev/null +++ b/apps/aspeed-pfr/tools/intel/platforms/example-a/plta_bios_pfm.json @@ -0,0 +1,136 @@ +{ + "exclude-pages":[[11248, 16367], [16368, 16383]], + "image-parts": [ + { + "name": "Reserved-1", + "index": 0, + "offset": "0x0", + "size": "0x20000", + "prot_mask": 29, + "pfm": 1, + "hash": 1, + "compress": 1 + }, + { + "name": "Embedded-Firmware-Signature", + "index": 1, + "offset": "0x20000", + "size": "0x4000", + "prot_mask": 29, + "pfm": 1, + "hash": 1, + "compress": 1 + }, + { + "name": "NVRAM", + "index": 2, + "offset": "0x24000", + "size": "0x20000", + "prot_mask": 31, + "pfm": 1, + "hash": 0, + "compress": 1 + }, + { + "name": "NVRAM-Backup", + "index": 3, + "offset": "0x44000", + "size": "0x20000", + "prot_mask": 31, + "pfm": 1, + "hash": 0, + "compress": 1 + }, + { + "name": "PSP-Data", + "index": 4, + "offset": "0x64000", + "size": "0x770000", + "prot_mask": 29, + "pfm": 1, + "hash": 1, + "compress": 1 + }, + { + "name": "OEM-NCB", + "index": 5, + "offset": "0x7d4000", + "size": "0x10000", + "prot_mask": 31, + "pfm": 1, + "hash": 0, + "compress": 1 + }, + { + "name": "GPNV", + "index": 6, + "offset": "0x7e4000", + "size": "0x10000", + "prot_mask": 31, + "pfm": 1, + "hash": 0, + "compress": 1 + }, + { + "name": "WHEA", + "index": 7, + "offset": "0x7f4000", + "size": "0x10000", + "prot_mask": 31, + "pfm": 1, + "hash": 0, + "compress": 1 + }, + { + "name": "FV_MAIN", + "index": 8, + "offset": "0x804000", + "size": "0x49c000", + "prot_mask": 29, + "pfm": 1, + "hash": 1, + "compress": 1 + }, + { + "name": "FV_BB", + "index": 9, + "offset": "0xca0000", + "size": "0x360000", + "prot_mask": 29, + "pfm": 1, + "hash": 1, + "compress": 1 + }, + { + "name": "Staging", + "index": 10, + "offset": "0x17f0000", + "size": "0x1400000", + "prot_mask": 3, + "pfm": 1, + "hash": 0, + "compress": 0 + }, + { + "name": "Recovery", + "index": 11, + "offset": "0x2bf0000", + "size": "0x1400000", + "prot_mask": 0, + "pfm": 1, + "hash": 0, + "compress": 0 + }, + { + "name": "PFM", + "index": 12, + "offset": "0x3ff0000", + "size": "0x10000", + "prot_mask": 0, + "pfm": 1, + "hash": 0, + "compress": 0 + } + ], + "i2c-rules":[] +} diff --git a/apps/aspeed-pfr/tools/intel/platforms/example-a/plta_bios_pfm_config_secp256r1.xml b/apps/aspeed-pfr/tools/intel/platforms/example-a/plta_bios_pfm_config_secp256r1.xml new file mode 100644 index 0000000..186a254 --- /dev/null +++ b/apps/aspeed-pfr/tools/intel/platforms/example-a/plta_bios_pfm_config_secp256r1.xml @@ -0,0 +1,48 @@ + + + + 1 + + + 0xB6EAFD19 + 1 + + + + 0xF27F28D7 + + + 0xA757A046 + 0xC7B88C74 + -1 + -1 + rk_pub.pem + + + + 0x14711C2F + 0xC7B88C74 + 1 + 1 + csk_pub.pem + 0xDE64437D + sha256 + rk_prv.pem + + + + + 0x15364367 + 0xDE64437D + sha256 + csk_prv.pem + + + + + + 1024 + + 128 + + diff --git a/apps/aspeed-pfr/tools/intel/platforms/example-a/plta_bios_pfm_config_secp384r1.xml b/apps/aspeed-pfr/tools/intel/platforms/example-a/plta_bios_pfm_config_secp384r1.xml new file mode 100644 index 0000000..a641c69 --- /dev/null +++ b/apps/aspeed-pfr/tools/intel/platforms/example-a/plta_bios_pfm_config_secp384r1.xml @@ -0,0 +1,48 @@ + + + + 1 + + + 0xB6EAFD19 + 1 + + + + 0xF27F28D7 + + + 0xA757A046 + 0x08F07B47 + -1 + -1 + rk384_pub.pem + + + + 0x14711C2F + 0x08F07B47 + 1 + 1 + csk384_pub.pem + 0xEA2A50E9 + sha384 + rk384_prv.pem + + + + + 0x15364367 + 0xEA2A50E9 + sha384 + csk384_prv.pem + + + + + + 1024 + + 128 + + diff --git a/apps/preload-fw/CMakeLists.txt b/apps/preload-fw/CMakeLists.txt index 5e3bd45..6d4d503 100644 --- a/apps/preload-fw/CMakeLists.txt +++ b/apps/preload-fw/CMakeLists.txt @@ -4,7 +4,7 @@ cmake_minimum_required(VERSION 3.13.1) find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) -project(preload-fw VERSION 02.01 LANGUAGES C) +project(preload-fw VERSION 02.02 LANGUAGES C) set(PROJECT_VERSION_MAJOR ${CMAKE_PROJECT_VERSION_MAJOR}) set(PROJECT_VERSION_MINOR ${CMAKE_PROJECT_VERSION_MINOR}) diff --git a/apps/preload-fw/Kconfig b/apps/preload-fw/Kconfig index c0285a1..5a4dce7 100644 --- a/apps/preload-fw/Kconfig +++ b/apps/preload-fw/Kconfig @@ -40,12 +40,6 @@ config OTP_SIM_SHELL help Enable OTP commands for read otp data from flash -config ODM_ROT_REPLACEMENT - default y - bool "ODM ROT replacement" - help - Replace ROT firmware by mcuboot recovery mechanism after devid provisioned - config AST10X0_PROGRAMMER_MP depends on BOARD_AST10X0_MP default n diff --git a/apps/preload-fw/boards/ast1060_dcscm.overlay b/apps/preload-fw/boards/ast1060_dcscm.overlay index 4d493e8..10f704a 100644 --- a/apps/preload-fw/boards/ast1060_dcscm.overlay +++ b/apps/preload-fw/boards/ast1060_dcscm.overlay @@ -144,6 +144,7 @@ &spi1_cs0 { spi-max-buswidth = <4>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim1>; status = "okay"; }; @@ -151,6 +152,7 @@ &spi1_cs1 { spi-max-buswidth = <4>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim2>; status = "okay"; }; #endif @@ -158,12 +160,14 @@ &spi2_cs0 { spi-max-buswidth = <1>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim3>; status = "okay"; }; &spi2_cs1 { spi-max-buswidth = <1>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim4>; status = "okay"; }; @@ -188,7 +192,6 @@ log-ram-size = <0x200>; pinctrl-0 = ; pinctrl-names = "default"; - flash-device = <&spi1_cs0>; ext-mux-sel = <1>; status = "okay"; }; @@ -199,7 +202,6 @@ log-ram-size = <0x200>; pinctrl-0 = ; pinctrl-names = "default"; - flash-device = <&spi1_cs1>; ext-mux-sel = <1>; status = "okay"; }; @@ -213,7 +215,6 @@ &pin_spim3misoout &pin_spim3mosiout &pin_spim3io2out &pin_spim3io3out &pin_spim3muxsel>; pinctrl-names = "default"; - flash-device = <&spi2_cs0>; ext-mux-sel = <1>; status = "okay"; }; @@ -226,7 +227,6 @@ &pin_spim4misoout &pin_spim4mosiout &pin_spim4io2out &pin_spim4io3out &pin_spim4muxsel>; pinctrl-names = "default"; - flash-device = <&spi2_cs1>; ext-mux-sel = <1>; status = "okay"; }; diff --git a/apps/preload-fw/boards/ast1060_dcscm_dice.conf b/apps/preload-fw/boards/ast1060_dcscm_dice.conf index 8449def..98854ed 100644 --- a/apps/preload-fw/boards/ast1060_dcscm_dice.conf +++ b/apps/preload-fw/boards/ast1060_dcscm_dice.conf @@ -16,4 +16,3 @@ CONFIG_PFR_SW_MAILBOX=y CONFIG_I2C_SWMBX_TARGET=y CONFIG_MBEDTLS_MAC_SHA384_ENABLED=y CONFIG_CPU_DUAL_FLASH=y -CONFIG_ODM_ROT_REPLACEMENT=y diff --git a/apps/preload-fw/boards/ast1060_dcscm_dice.overlay b/apps/preload-fw/boards/ast1060_dcscm_dice.overlay index f098d66..2eba5f4 100644 --- a/apps/preload-fw/boards/ast1060_dcscm_dice.overlay +++ b/apps/preload-fw/boards/ast1060_dcscm_dice.overlay @@ -15,7 +15,6 @@ swmbx0: swmbx0@38 { compatible = "aspeed,swmbx-dev"; reg = <0x38>; - label = "SWMBX_SLAVE_BMC"; size = <256>; port = <0>; status = "okay"; @@ -32,7 +31,6 @@ swmbx1: swmbx1@70 { compatible = "aspeed,swmbx-dev"; reg = <0x70>; - label = "SWMBX_SLAVE_CPU"; size = <256>; port = <1>; status = "okay"; @@ -141,18 +139,21 @@ &spi1_cs0 { spi-max-buswidth = <4>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim1>; status = "okay"; }; &spi2_cs0 { spi-max-buswidth = <1>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim3>; status = "okay"; }; &spi2_cs1 { spi-max-buswidth = <1>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim4>; status = "okay"; }; @@ -177,7 +178,6 @@ log-ram-size = <0x200>; pinctrl-0 = ; pinctrl-names = "default"; - flash-device = <&spi1_cs0>; ext-mux-sel = <1>; status = "okay"; }; @@ -190,7 +190,6 @@ &pin_spim3misoout &pin_spim3mosiout &pin_spim3io2out &pin_spim3io3out &pin_spim3muxsel>; pinctrl-names = "default"; - flash-device = <&spi2_cs0>; ext-mux-sel = <1>; status = "okay"; }; @@ -203,7 +202,6 @@ &pin_spim4misoout &pin_spim4mosiout &pin_spim4io2out &pin_spim4io3out &pin_spim4muxsel>; pinctrl-names = "default"; - flash-device = <&spi2_cs1>; ext-mux-sel = <1>; status = "okay"; }; diff --git a/apps/preload-fw/boards/ast1060_dual_flash_dice.overlay b/apps/preload-fw/boards/ast1060_dual_flash_dice.overlay index 4397e84..e394da5 100644 --- a/apps/preload-fw/boards/ast1060_dual_flash_dice.overlay +++ b/apps/preload-fw/boards/ast1060_dual_flash_dice.overlay @@ -142,24 +142,28 @@ &spi1_cs0 { spi-max-buswidth = <4>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim1>; status = "okay"; }; &spi1_cs1 { spi-max-buswidth = <4>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim2>; status = "okay"; }; &spi2_cs0 { spi-max-buswidth = <1>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim3>; status = "okay"; }; &spi2_cs1 { spi-max-buswidth = <1>; spi-max-frequency = <50000000>; + spi-monitor-ctrl = <&spim4>; status = "okay"; }; @@ -185,7 +189,6 @@ pinctrl-0 = ; pinctrl-names = "default"; - flash-device = <&spi1_cs0>; ext-mux-sel = <1>; status = "okay"; }; @@ -196,7 +199,6 @@ pinctrl-0 = ; pinctrl-names = "default"; - flash-device = <&spi1_cs1>; ext-mux-sel = <1>; status = "okay"; }; @@ -210,7 +212,6 @@ &pin_spim3muxsel>; pinctrl-names = "default"; - flash-device = <&spi2_cs0>; ext-mux-sel = <1>; status = "okay"; }; @@ -224,7 +225,6 @@ &pin_spim4muxsel>; pinctrl-names = "default"; - flash-device = <&spi2_cs1>; ext-mux-sel = <1>; status = "okay"; }; diff --git a/apps/preload-fw/src/CMakeLists.txt b/apps/preload-fw/src/CMakeLists.txt index fcfb9ed..aebce3f 100644 --- a/apps/preload-fw/src/CMakeLists.txt +++ b/apps/preload-fw/src/CMakeLists.txt @@ -8,6 +8,4 @@ add_subdirectory(otp) add_subdirectory_ifdef(CONFIG_AST10X0_PROGRAMMER_MP mp) -add_subdirectory_ifdef(CONFIG_BOARD_AST1060_DCSCM_DICE fw_update) -add_subdirectory_ifdef(CONFIG_BOARD_AST1060_DCSCM_DICE sw_mailbox) add_subdirectory_ifdef(CONFIG_BOARD_AST1060_DCSCM_DICE certificate) diff --git a/apps/preload-fw/src/certificate/cert_prov.c b/apps/preload-fw/src/certificate/cert_prov.c index 82cede8..3506762 100644 --- a/apps/preload-fw/src/certificate/cert_prov.c +++ b/apps/preload-fw/src/certificate/cert_prov.c @@ -14,7 +14,6 @@ #include "cert_prov.h" #include "gpio/gpio_ctrl.h" #include "otp/otp_utils.h" -#include "sw_mailbox/sw_mailbox.h" LOG_MODULE_REGISTER(prov, CONFIG_LOG_DEFAULT_LEVEL); PFR_DEVID_CERT_INFO devid_cert_info NON_CACHED_BSS_ALIGN16; @@ -42,7 +41,6 @@ PROV_STATUS cert_provision(void) } LOG_INF("Certificate verified successfully"); -#if defined(CONFIG_ODM_ROT_REPLACEMENT) // 2nd bootup // Erase the 1st slot firmware, the 1st slot firmware will be replaced by // the 2nd slot firmeware(customer's firmware) by mcuboot's recovery mechanism @@ -70,29 +68,6 @@ PROV_STATUS cert_provision(void) LOG_INF("Preload fw is erased"); set_mp_status(1, 1); return PROV_DONE; -#else - if (IS_CSR(devid_cert_info)) { - // 2nd bootup, CSR is generated and waiting for signing by HSM - LOG_WRN("Certificate is not signed"); - } else { - // 3rd bootup, certificate chain is generated and waiting for - // firmware replacement - LOG_INF("Verify certificate chain..."); - if (verify_certificate(devid_cert_info.cert.data, - devid_cert_info.cert.length)) { - LOG_ERR("Invalid certificate chain"); - cleanup_cert_info(); - goto out; - } - - cleanup_cert_info(); -#if defined(CONFIG_PFR_SW_MAILBOX) - init_sw_mailbox(); -#endif - LOG_INF("Ready for ROT firmware replacement"); - return PROV_ROT_UPDATE; - } -#endif } else { // 1st bootup: // Secure Boot is not enabled diff --git a/apps/preload-fw/src/certificate/cert_verify.c b/apps/preload-fw/src/certificate/cert_verify.c index b07c2eb..27950c4 100644 --- a/apps/preload-fw/src/certificate/cert_verify.c +++ b/apps/preload-fw/src/certificate/cert_verify.c @@ -11,7 +11,6 @@ #include #include #include "cert_verify.h" -#include "fw_update/fw_update.h" #include "mbedtls/x509.h" #include "mbedtls/x509_crt.h" @@ -65,121 +64,3 @@ int get_certificate_info(PFR_DEVID_CERT_INFO *devid_cert_info, uint32_t cert_siz return -1; } -// Test function -#if 1 -// read certificate chain from BMC's SPI 0xd320000 -// certificate chain size = 1645 bytes -#define CERT_CHAIN_LENGTH 1645 - -uint8_t get_certificate_chain(uint8_t *cert_chain, uint32_t *cert_chain_len) -{ - const struct device *dev = get_flash_dev(BMC_FLASH_ID); - uint32_t cert_addr = 0xd320000; - *cert_chain_len = CERT_CHAIN_LENGTH; - flash_read(dev, cert_addr, cert_chain, *cert_chain_len); - - return 0; -} -#endif - -void generate_cert_info(PFR_CERT_INFO *cert_info, uint8_t *cert_chain, uint32_t cert_chain_len) -{ - cert_info->magic = CERT_INFO_MAGIC_NUM; - cert_info->length = cert_chain_len; - memset(cert_info->data, 0, sizeof(cert_info->data)); - memcpy(cert_info->data, cert_chain, cert_chain_len); - mbedtls_sha256(cert_info->data, cert_info->length, cert_info->hash, 0); -} - -int write_cert_chain(uint8_t *cert_chain, uint32_t cert_chain_len) -{ - const struct flash_area *fa = NULL; - PFR_DEVID_CERT_INFO devid_cert_info = {0}; - devid_cert_info.cert_type = CERT_TYPE; - memcpy(devid_cert_info.pubkey, devid_pub_key, sizeof(devid_cert_info.pubkey)); - generate_cert_info(&devid_cert_info.cert, cert_chain, cert_chain_len); - - if (flash_area_open(FIXED_PARTITION_ID(certificate_partition), &fa)) { - LOG_ERR("Failed to open certificate region"); - return -1; - } - - flash_area_erase(fa, DEVID_CERT_AREA_OFFSET, CERT_AREA_SIZE); - flash_area_write(fa, DEVID_CERT_AREA_OFFSET, &devid_cert_info, sizeof(devid_cert_info)); - flash_area_close(fa); - - return 0; -} - -int verify_certificate(uint8_t *cert_chain, uint32_t cert_chain_len) -{ - uint32_t asn1_len; - uint32_t current_cert_len; - uint32_t flags; - uint8_t current_index = 0; - const uint8_t *current_cert = cert_chain; - const uint8_t *tmp_ptr; - int ret; - - mbedtls_x509_crt_init(&root_cert); - mbedtls_x509_crt_init(&leaf_cert); - - /* Verify the certificate */ - while (true) { - tmp_ptr = current_cert; - ret = mbedtls_asn1_get_tag( - (uint8_t **)&tmp_ptr, cert_chain + cert_chain_len, &asn1_len, - MBEDTLS_ASN1_CONSTRUCTED | MBEDTLS_ASN1_SEQUENCE); - if (ret != 0) { - break; - } - - current_cert_len = asn1_len + (tmp_ptr - current_cert); - - // Certificate Chain = Root CA + Intermediate Cert + Leaf Cert - if (current_index < 2) { - ret = mbedtls_x509_crt_parse_der_nocopy( - &root_cert, current_cert, current_cert_len); - if (ret < 0) { - // Parse Certificate Chain DER failed - ret = -1; - LOG_ERR("Failed to parse root ca"); - goto cleanup; - } - } else { - ret = mbedtls_x509_crt_parse_der_nocopy( - &leaf_cert, current_cert, current_cert_len); - if (ret < 0) { - // Parse Certificate Chain DER failed - ret = -1; - LOG_ERR("Failed to parse leaf certificate"); - goto cleanup; - } - } - - current_cert = current_cert + current_cert_len; - current_index++; - } - - ret = mbedtls_x509_crt_verify(&leaf_cert, &root_cert, NULL, NULL, &flags, NULL, NULL); - if (ret < 0 || flags != 0) { - // Verify Failed - LOG_ERR("Certificate chain verification failed"); - ret = -1; - goto cleanup; - } - - LOG_INF("Certificate chain verify successful"); - ret = 0; - -cleanup: - mbedtls_x509_crt_free(&root_cert); - mbedtls_x509_crt_free(&leaf_cert); - return ret; -} - -void cleanup_cert_info(void) -{ - memset(devid_pub_key, 0, sizeof(devid_pub_key)); -} - diff --git a/apps/preload-fw/src/certificate/cert_verify.h b/apps/preload-fw/src/certificate/cert_verify.h index 1c78a4a..5d10d4d 100644 --- a/apps/preload-fw/src/certificate/cert_verify.h +++ b/apps/preload-fw/src/certificate/cert_verify.h @@ -38,7 +38,3 @@ typedef struct { } PFR_DEVID_CERT_INFO; int get_certificate_info(PFR_DEVID_CERT_INFO *devid_cert_info, uint32_t cert_size); -uint8_t get_certificate_chain(uint8_t *cert_chain, uint32_t *cert_chain_len); -int verify_certificate(uint8_t *cert_chain, uint32_t cert_chain_len); -int write_cert_chain(uint8_t *cert_chain, uint32_t cert_chain_len); -void cleanup_cert_info(void); diff --git a/apps/preload-fw/src/fw_update/CMakeLists.txt b/apps/preload-fw/src/fw_update/CMakeLists.txt deleted file mode 100644 index 64a8f51..0000000 --- a/apps/preload-fw/src/fw_update/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) 2023 ASPEED Technology Inc. -# SPDX-License-Identifier: MIT -target_sources(app PRIVATE fw_update.c) diff --git a/apps/preload-fw/src/fw_update/fw_update.c b/apps/preload-fw/src/fw_update/fw_update.c deleted file mode 100644 index 26b77f0..0000000 --- a/apps/preload-fw/src/fw_update/fw_update.c +++ /dev/null @@ -1,223 +0,0 @@ -/* - * Copyright (c) 2022 ASPEED Technology Inc. - * - * SPDX-License-Identifier: MIT - */ - -#include -#include -#include -#include -#include -#include -#include "fw_update.h" -#include "gpio/gpio_ctrl.h" - -LOG_MODULE_REGISTER(fwupdate); - -char *flash_devices[6] = { - "spi1@0", - "spi1@1", - "spi2@0", - "spi2@1", - "fmc@0", - "fmc@1" -}; - -static uint32_t rot_fw_staging_addr = 0; -static uint32_t rot_fw_checksum = 0; -static uint32_t rot_fw_size = 0; - -static uint8_t staging_src_flash_id = BMC_FLASH_ID; -static uint8_t ext_mux_level = 0; - -uint8_t flash_buf[PAGE_SIZE] NON_CACHED_BSS_ALIGN16; - -void configure_staging_source(union aspeed_event_data *data) -{ - if (data->bit8[1] & ROT_SETTING_FMC_SPI) { - staging_src_flash_id = ROT_FMC_CS1; - } else { - staging_src_flash_id = ((data->bit8[1] & ROT_SETTING_SPI_SRC) << 1) | - ((data->bit8[1] & ROT_SETTING_CS_SRC) >> 1); - } - - LOG_INF("flash id = %d\n",staging_src_flash_id); - ext_mux_level = (data->bit8[1] & ROT_SETTING_MUX_INV) ? 1 : 0; -} - -void set_fw_staging_source(union aspeed_event_data *data) -{ - switch(data->bit8[0]) { - case RotCmdStagingOffset0: - rot_fw_staging_addr &= 0xffffff00; - rot_fw_staging_addr |= data->bit8[1]; - break; - case RotCmdStagingOffset1: - rot_fw_staging_addr &= 0xffff00ff; - rot_fw_staging_addr |= (data->bit8[1] << 8); - break; - case RotCmdStagingOffset2: - rot_fw_staging_addr &= 0xff00ffff; - rot_fw_staging_addr |= (data->bit8[1] << 16); - break; - case RotCmdStagingOffset3: - rot_fw_staging_addr &= 0x00ffffff; - rot_fw_staging_addr |= (data->bit8[1] << 24); - break; - } - LOG_INF("rot_fw_staging_addr : %x", rot_fw_staging_addr); -} - -void set_fw_image_size(union aspeed_event_data *data) -{ - switch(data->bit8[0]) { - case RotCmdImgSize0: - rot_fw_size &= 0xffffff00; - rot_fw_size |= data->bit8[1]; - break; - case RotCmdImgSize1: - rot_fw_size &= 0xffff00ff; - rot_fw_size |= (data->bit8[1] << 8); - break; - case RotCmdImgSize2: - rot_fw_size &= 0xff00ffff; - rot_fw_size |= (data->bit8[1] << 16); - break; - case RotCmdImgSize3: - rot_fw_size &= 0x00ffffff; - rot_fw_size |= (data->bit8[1] << 24); - break; - } - LOG_INF("rot_fw_size : %x", rot_fw_size); -} - -void set_fw_image_checksum(union aspeed_event_data *data) -{ - switch(data->bit8[0]) { - case RotCmdChecksum0: - rot_fw_checksum &= 0xffffff00; - rot_fw_checksum |= data->bit8[1]; - break; - case RotCmdChecksum1: - rot_fw_checksum &= 0xffff00ff; - rot_fw_checksum |= (data->bit8[1] << 8); - break; - case RotCmdChecksum2: - rot_fw_checksum &= 0xff00ffff; - rot_fw_checksum |= (data->bit8[1] << 16); - break; - case RotCmdChecksum3: - rot_fw_checksum &= 0x00ffffff; - rot_fw_checksum |= (data->bit8[1] << 24); - break; - } - LOG_INF("rot_fw_checksum : %x", rot_fw_checksum); -} - -uint32_t cal_checksum(const struct device *dev, uint32_t addr, uint32_t size) -{ - uint32_t read_addr = addr; - uint32_t read_size; - uint32_t remaining = size; - uint32_t crc = 0; - - while (remaining) { - read_size = (remaining >= PAGE_SIZE) ? PAGE_SIZE : remaining; - flash_read(dev, read_addr, flash_buf, read_size); - crc = crc32_ieee_update(crc, flash_buf, read_size); - read_addr += read_size; - remaining -= read_size; - } - - return crc; -} - -const struct device *get_flash_dev(uint8_t flash_id) -{ - const struct device *flash_dev; - flash_dev = device_get_binding(flash_devices[flash_id]); - - return flash_dev; -} - -int rot_fw_update(void) -{ - const struct flash_area *fa; - const struct device *stg_flash_dev; - const struct device *rot_flash_dev; - uint32_t flash_sz; - uint32_t checksum = 0; - uint8_t fw_update_status = 0; - - fw_update_status = ROT_FW_UPDATE_INPROGRESS; - SetRotCmdStatus(fw_update_status); - - LOG_INF("ROT FW Start Addr: 0x%08x", rot_fw_staging_addr); - if (rot_fw_staging_addr == 0) { - LOG_ERR("Invalid staging address"); - goto fwu_error; - } - - if (flash_area_open(FIXED_PARTITION_ID(active_partition), &fa)) { - LOG_ERR("Unknown partition"); - goto fwu_error; - } - - BMCSPIHold(ext_mux_level); - LOG_INF("flash dev : %s", flash_devices[staging_src_flash_id]); - stg_flash_dev = device_get_binding(flash_devices[staging_src_flash_id]); - if (stg_flash_dev == NULL) { - LOG_ERR("Failed to get BMC flash device"); - goto fwu_error; - } - - flash_sz = flash_get_flash_size(stg_flash_dev); - - if (rot_fw_size > fa->fa_size) { - LOG_ERR("Firmware size > active partition size"); - goto fwu_error; - } - - if (rot_fw_staging_addr > flash_sz || - flash_sz - rot_fw_staging_addr < rot_fw_size) { - LOG_ERR("Invalid address"); - goto fwu_error; - } - - checksum = cal_checksum(stg_flash_dev, rot_fw_staging_addr, rot_fw_size); - if (checksum != rot_fw_checksum) { - LOG_ERR("Invalid checksum, expected : %x, actual : %x", rot_fw_checksum, checksum); - fw_update_status = ROT_FW_CHECKSUM_FAIl; - SetRotCmdStatus(fw_update_status); - BMCSPIRelease(ext_mux_level); - return -1; - } - - flash_area_erase(fa, 0, fa->fa_size); - uint32_t read_addr = rot_fw_staging_addr; - uint32_t write_addr = fa->fa_off; - uint32_t remaining = rot_fw_size; - uint32_t read_size; - - rot_flash_dev = device_get_binding(flash_devices[ROT_FLASH_ID]); - - while(remaining) { - read_size = (remaining >= PAGE_SIZE) ? PAGE_SIZE : remaining; - flash_read(stg_flash_dev, read_addr, flash_buf, PAGE_SIZE); - flash_write(rot_flash_dev, write_addr, flash_buf, PAGE_SIZE); - read_addr += read_size; - write_addr += read_size; - remaining -= read_size; - } - - SetRotCmdStatus(ROT_FW_UPDATE_DONE); - BMCSPIRelease(ext_mux_level); - LOG_INF("ROT firmware update successful"); - - return 0; -fwu_error: - SetRotCmdStatus(ROT_FW_UPDATE_FAIl); - BMCSPIRelease(ext_mux_level); - return -1; -} diff --git a/apps/preload-fw/src/fw_update/fw_update.h b/apps/preload-fw/src/fw_update/fw_update.h deleted file mode 100644 index df8eae0..0000000 --- a/apps/preload-fw/src/fw_update/fw_update.h +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2022 ASPEED Technology Inc. - * - * SPDX-License-Identifier: MIT - */ - -#pragma once - -#include -#include "sw_mailbox/sw_mailbox.h" - -#define PAGE_SIZE 4096 - -enum { - BMC_FLASH_ID = 0, - BMC_FLASH_ID_2 = 1, - PCH_FLASH_ID = 2, - PCH_FLASH_ID_2 = 3, - ROT_FLASH_ID = 4, - ROT_FMC_CS1 = 5, -}; - -void configure_staging_source(union aspeed_event_data *data); -void set_fw_staging_source(union aspeed_event_data *data); -void set_fw_image_size(union aspeed_event_data *data); -void set_fw_image_checksum(union aspeed_event_data *data); -const struct device *get_flash_dev(uint8_t flash_id); -int rot_fw_update(void); - diff --git a/apps/preload-fw/src/gpio/gpio_ctrl.c b/apps/preload-fw/src/gpio/gpio_ctrl.c index 64ab630..6152b15 100644 --- a/apps/preload-fw/src/gpio/gpio_ctrl.c +++ b/apps/preload-fw/src/gpio/gpio_ctrl.c @@ -10,7 +10,6 @@ #include #include "gpio_ctrl.h" -#include "sw_mailbox/sw_mailbox.h" #if !DT_NODE_HAS_STATUS(DT_INST(0, aspeed_pfr_gpio_common), okay) #error "no correct pfr gpio device" diff --git a/apps/preload-fw/src/sw_mailbox/CMakeLists.txt b/apps/preload-fw/src/sw_mailbox/CMakeLists.txt deleted file mode 100644 index 7dc0566..0000000 --- a/apps/preload-fw/src/sw_mailbox/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -# Copyright (c) 2023 ASPEED Technology Inc. -# SPDX-License-Identifier: MIT -target_sources(app PRIVATE sw_mailbox.c) diff --git a/apps/preload-fw/src/sw_mailbox/sw_mailbox.c b/apps/preload-fw/src/sw_mailbox/sw_mailbox.c deleted file mode 100644 index 4361cb6..0000000 --- a/apps/preload-fw/src/sw_mailbox/sw_mailbox.c +++ /dev/null @@ -1,262 +0,0 @@ -/* - * Copyright (c) 2022 ASPEED Technology Inc. - * - * SPDX-License-Identifier: MIT - */ - -#include -#include -#include -#include -#include -#include -#include "sw_mailbox.h" -#include "fw_update/fw_update.h" - -LOG_MODULE_REGISTER(mailbox, CONFIG_LOG_DEFAULT_LEVEL); - -#define TOTAL_MBOX_EVENT 14 -#define SWMBX_NOTIFYEE_STACK_SIZE 1024 - -const struct device *swmbx_dev = NULL; - -#define SWMBX_SLAVE_BMC DEVICE_DT_NAME(DT_NODELABEL(swmbx1)) -#define SWMBX_SLAVE_CPU DEVICE_DT_NAME(DT_NODELABEL(swmbx0)) - -#define MBX_REG_SETTER(REG) \ - void Set##REG(uint8_t Data) \ - { \ - swmbx_write(swmbx_dev, false, REG, &Data); \ - } - -#define MBX_REG_GETTER(REG) \ - uint8_t Get##REG(void) \ - { \ - uint8_t data; \ - swmbx_read(swmbx_dev, false, REG, &data); \ - return data; \ - } - -#define MBX_REG_SETTER_GETTER(REG) \ - MBX_REG_SETTER(REG) \ - MBX_REG_GETTER(REG) - -MBX_REG_SETTER_GETTER(RotCmdPreloadImgId); -MBX_REG_SETTER_GETTER(RotCmdSetting); -MBX_REG_SETTER_GETTER(RotCmdCommand); -MBX_REG_SETTER_GETTER(RotCmdStatus); -MBX_REG_SETTER_GETTER(RotCmdStagingOffset0); -MBX_REG_SETTER_GETTER(RotCmdStagingOffset1); -MBX_REG_SETTER_GETTER(RotCmdStagingOffset2); -MBX_REG_SETTER_GETTER(RotCmdStagingOffset3); -MBX_REG_SETTER_GETTER(RotCmdImgSize0); -MBX_REG_SETTER_GETTER(RotCmdImgSize1); -MBX_REG_SETTER_GETTER(RotCmdImgSize2); -MBX_REG_SETTER_GETTER(RotCmdImgSize3); -MBX_REG_SETTER_GETTER(RotCmdChecksum0); -MBX_REG_SETTER_GETTER(RotCmdChecksum1); -MBX_REG_SETTER_GETTER(RotCmdChecksum2); -MBX_REG_SETTER_GETTER(RotCmdChecksum3); - -struct k_thread swmbx_notifyee_thread; - -K_THREAD_STACK_DEFINE(swmbx_notifyee_stack, SWMBX_NOTIFYEE_STACK_SIZE); -K_SEM_DEFINE(rot_setting_sem, 0, 1); -K_SEM_DEFINE(rot_command_sem, 0, 1); -K_SEM_DEFINE(rot_staging_offset0_sem, 0, 1); -K_SEM_DEFINE(rot_staging_offset1_sem, 0, 1); -K_SEM_DEFINE(rot_staging_offset2_sem, 0, 1); -K_SEM_DEFINE(rot_staging_offset3_sem, 0, 1); -K_SEM_DEFINE(rot_image_size0_sem, 0, 1); -K_SEM_DEFINE(rot_image_size1_sem, 0, 1); -K_SEM_DEFINE(rot_image_size2_sem, 0, 1); -K_SEM_DEFINE(rot_image_size3_sem, 0, 1); -K_SEM_DEFINE(rot_checksum0_sem, 0, 1); -K_SEM_DEFINE(rot_checksum1_sem, 0, 1); -K_SEM_DEFINE(rot_checksum2_sem, 0, 1); -K_SEM_DEFINE(rot_checksum3_sem, 0, 1); - -void swmbx_notifyee_main(void *a, void *b, void *c) -{ - int ret; - union aspeed_event_data data = {0}; - - struct k_poll_event events[TOTAL_MBOX_EVENT]; - k_poll_event_init(&events[0], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, - &rot_setting_sem); - k_poll_event_init(&events[1], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, - &rot_command_sem); - k_poll_event_init(&events[2], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, - &rot_staging_offset0_sem); - k_poll_event_init(&events[3], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, - &rot_staging_offset1_sem); - k_poll_event_init(&events[4], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, - &rot_staging_offset2_sem); - k_poll_event_init(&events[5], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, - &rot_staging_offset3_sem); - k_poll_event_init(&events[6], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, - &rot_image_size0_sem); - k_poll_event_init(&events[7], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, - &rot_image_size1_sem); - k_poll_event_init(&events[8], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, - &rot_image_size2_sem); - k_poll_event_init(&events[9], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, - &rot_image_size3_sem); - k_poll_event_init(&events[10], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, - &rot_checksum0_sem); - k_poll_event_init(&events[11], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, - &rot_checksum1_sem); - k_poll_event_init(&events[12], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, - &rot_checksum2_sem); - k_poll_event_init(&events[13], K_POLL_TYPE_SEM_AVAILABLE, K_POLL_MODE_NOTIFY_ONLY, - &rot_checksum3_sem); - - while (1) { - ret = k_poll(events, TOTAL_MBOX_EVENT, K_FOREVER); - - if (ret < 0) { - LOG_ERR("k_poll error ret=%d", ret); - continue; - } - - if (events[0].state == K_POLL_STATE_SEM_AVAILABLE) { - k_sem_take(events[0].sem, K_NO_WAIT); - data.bit8[0] = RotCmdSetting; - swmbx_get_msg(0, RotCmdSetting, &data.bit8[1]); - configure_staging_source(&data); - } else if (events[1].state == K_POLL_STATE_SEM_AVAILABLE) { - k_sem_take(events[1].sem, K_NO_WAIT); - data.bit8[0] = RotCmdCommand; - swmbx_get_msg(0, RotCmdCommand, &data.bit8[1]); - if (data.bit8[1] == 1){ - if (rot_fw_update()) { - LOG_ERR("Failed to update ROT firmware"); - } - } - } else if (events[2].state == K_POLL_STATE_SEM_AVAILABLE) { - k_sem_take(events[2].sem, K_NO_WAIT); - data.bit8[0] = RotCmdStagingOffset0; - swmbx_get_msg(0, RotCmdStagingOffset0, &data.bit8[1]); - set_fw_staging_source(&data); - } else if (events[3].state == K_POLL_STATE_SEM_AVAILABLE) { - k_sem_take(events[3].sem, K_NO_WAIT); - data.bit8[0] = RotCmdStagingOffset1; - swmbx_get_msg(0, RotCmdStagingOffset1, &data.bit8[1]); - set_fw_staging_source(&data); - } else if (events[4].state == K_POLL_STATE_SEM_AVAILABLE) { - k_sem_take(events[4].sem, K_NO_WAIT); - data.bit8[0] = RotCmdStagingOffset2; - swmbx_get_msg(0, RotCmdStagingOffset2, &data.bit8[1]); - set_fw_staging_source(&data); - } else if (events[5].state == K_POLL_STATE_SEM_AVAILABLE) { - k_sem_take(events[5].sem, K_NO_WAIT); - data.bit8[0] = RotCmdStagingOffset3; - swmbx_get_msg(0, RotCmdStagingOffset3, &data.bit8[1]); - set_fw_staging_source(&data); - } else if (events[6].state == K_POLL_STATE_SEM_AVAILABLE) { - k_sem_take(events[6].sem, K_NO_WAIT); - data.bit8[0] = RotCmdImgSize0; - swmbx_get_msg(0, RotCmdImgSize0, &data.bit8[1]); - set_fw_image_size(&data); - } else if (events[7].state == K_POLL_STATE_SEM_AVAILABLE) { - k_sem_take(events[7].sem, K_NO_WAIT); - data.bit8[0] = RotCmdImgSize1; - swmbx_get_msg(0, RotCmdImgSize1, &data.bit8[1]); - set_fw_image_size(&data); - } else if (events[8].state == K_POLL_STATE_SEM_AVAILABLE) { - k_sem_take(events[8].sem, K_NO_WAIT); - data.bit8[0] = RotCmdImgSize2; - swmbx_get_msg(0, RotCmdImgSize2, &data.bit8[1]); - set_fw_image_size(&data); - } else if (events[9].state == K_POLL_STATE_SEM_AVAILABLE) { - k_sem_take(events[9].sem, K_NO_WAIT); - data.bit8[0] = RotCmdImgSize3; - swmbx_get_msg(0, RotCmdImgSize3, &data.bit8[1]); - set_fw_image_size(&data); - } else if (events[10].state == K_POLL_STATE_SEM_AVAILABLE) { - k_sem_take(events[10].sem, K_NO_WAIT); - data.bit8[0] = RotCmdChecksum0; - swmbx_get_msg(0, RotCmdChecksum0, &data.bit8[1]); - set_fw_image_checksum(&data); - } else if (events[11].state == K_POLL_STATE_SEM_AVAILABLE) { - k_sem_take(events[11].sem, K_NO_WAIT); - data.bit8[0] = RotCmdChecksum1; - swmbx_get_msg(0, RotCmdChecksum1, &data.bit8[1]); - set_fw_image_checksum(&data); - } else if (events[12].state == K_POLL_STATE_SEM_AVAILABLE) { - k_sem_take(events[12].sem, K_NO_WAIT); - data.bit8[0] = RotCmdChecksum2; - swmbx_get_msg(0, RotCmdChecksum2, &data.bit8[1]); - set_fw_image_checksum(&data); - } else if (events[13].state == K_POLL_STATE_SEM_AVAILABLE) { - k_sem_take(events[13].sem, K_NO_WAIT); - data.bit8[0] = RotCmdChecksum3; - swmbx_get_msg(0, RotCmdChecksum3, &data.bit8[1]); - set_fw_image_checksum(&data); - } - - for (size_t i = 0; i < TOTAL_MBOX_EVENT; ++i) - events[i].state = K_POLL_STATE_NOT_READY; - } -} - -void init_sw_mailbox(void) -{ - swmbx_dev = device_get_binding("swmbx-ctrl"); - if (swmbx_dev == NULL) { - LOG_ERR("%s: fail to bind %s", __func__, "SWMBX"); - return; - } - SetRotCmdPreloadImgId(0xa3); - /* Enable mailbox read/write notifiaction and FIFO */ - swmbx_enable_behavior(swmbx_dev, SWMBX_PROTECT | SWMBX_NOTIFY | SWMBX_FIFO, 1); - - /* swmbx_update_notify(dev, port, sem, addr, enable) */ - /* From BMC */ - swmbx_update_notify(swmbx_dev, 0x0, &rot_setting_sem, RotCmdSetting, true); - swmbx_update_notify(swmbx_dev, 0x0, &rot_command_sem, RotCmdCommand, true); - swmbx_update_notify(swmbx_dev, 0x0, &rot_staging_offset0_sem, RotCmdStagingOffset0, true); - swmbx_update_notify(swmbx_dev, 0x0, &rot_staging_offset1_sem, RotCmdStagingOffset1, true); - swmbx_update_notify(swmbx_dev, 0x0, &rot_staging_offset2_sem, RotCmdStagingOffset2, true); - swmbx_update_notify(swmbx_dev, 0x0, &rot_staging_offset3_sem, RotCmdStagingOffset3, true); - swmbx_update_notify(swmbx_dev, 0x0, &rot_image_size0_sem, RotCmdImgSize0, true); - swmbx_update_notify(swmbx_dev, 0x0, &rot_image_size1_sem, RotCmdImgSize1, true); - swmbx_update_notify(swmbx_dev, 0x0, &rot_image_size2_sem, RotCmdImgSize2, true); - swmbx_update_notify(swmbx_dev, 0x0, &rot_image_size3_sem, RotCmdImgSize3, true); - swmbx_update_notify(swmbx_dev, 0x0, &rot_checksum0_sem, RotCmdChecksum0, true); - swmbx_update_notify(swmbx_dev, 0x0, &rot_checksum1_sem, RotCmdChecksum1, true); - swmbx_update_notify(swmbx_dev, 0x0, &rot_checksum2_sem, RotCmdChecksum2, true); - swmbx_update_notify(swmbx_dev, 0x0, &rot_checksum3_sem, RotCmdChecksum3, true); - - /* Protect bit: - * 0 means readable/writable - * 1 means read-only - */ - uint32_t access_control[8] = { - 0xffff0009, // 1fh ~ 00h - 0xffffffff, - 0xffffffff, - 0xffffffff, - 0xffffffff, - 0xffffffff, - 0xffffffff, - 0xffffffff, - }; - swmbx_apply_protect(swmbx_dev, 0, access_control, 0, 8); - - /* Register slave device to bus device */ - const struct device *dev = NULL; - - dev = device_get_binding(SWMBX_SLAVE_BMC); - if (dev) - i2c_target_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"); -} diff --git a/apps/preload-fw/src/sw_mailbox/sw_mailbox.h b/apps/preload-fw/src/sw_mailbox/sw_mailbox.h deleted file mode 100644 index 65b193a..0000000 --- a/apps/preload-fw/src/sw_mailbox/sw_mailbox.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2022 ASPEED Technology Inc. - * - * SPDX-License-Identifier: MIT - */ - -#pragma once - -#define ROT_PRELOAD_IMAGE_ID 0xa3 - -// 01h ROT Settings -#define ROT_SETTING_SPI_SRC BIT(0) -#define ROT_SETTING_CS_SRC BIT(1) -#define ROT_SETTING_FMC_SPI BIT(2) -#define ROT_SETTING_MUX_INV BIT(3) - -// 03h ROT Status -#define ROT_FW_UPDATE_INPROGRESS BIT(0) -#define ROT_FW_UPDATE_FAIl BIT(1) -#define ROT_FW_CHECKSUM_FAIl BIT(2) -#define ROT_FW_UPDATE_DONE BIT(3) - -typedef enum _SW_MAILBOX_RF_ADDRESS { - RotWriteFifo = 0x7e, - RotFwUpdateTrigger = 0x7f, -} SW_MAILBOX_ADDRESS; - -typedef enum _ROT_CMD { - RotCmdPreloadImgId = 0, - RotCmdSetting, - RotCmdCommand, - RotCmdStatus, - RotCmdStagingOffset0, - RotCmdStagingOffset1, - RotCmdStagingOffset2, - RotCmdStagingOffset3, - RotCmdImgSize0, - RotCmdImgSize1, - RotCmdImgSize2, - RotCmdImgSize3, - RotCmdChecksum0, - RotCmdChecksum1, - RotCmdChecksum2, - RotCmdChecksum3, -} ROT_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; -}; - -void SetRotCmdPreloadImgId(uint8_t preload_id); -void SetRotCmdStatus(uint8_t status); - -void init_sw_mailbox(void); diff --git a/boards/arm/ast1060_dcscm/board.c b/boards/arm/ast1060_dcscm/board.c index 8fd695c..e5c71f6 100644 --- a/boards/arm/ast1060_dcscm/board.c +++ b/boards/arm/ast1060_dcscm/board.c @@ -26,19 +26,6 @@ static int ast1060_dcscm_init(void) dev = device_get_binding("gpio0_e_h"); gpio_pin_configure(dev, 27, GPIO_OUTPUT_ACTIVE); #endif - // Workaround: - // Will be removed if zephyr sdk supports changing pin function to GPI Tx when ADC engine - // is disabled. -#define ADC_ENGINE_CTRL 0x7e6e9000 -#define SCU_PIN_CTRL5 0x7e6e2430 - - uint32_t pinctrl_val = sys_read32(SCU_PIN_CTRL5); - uint32_t adc_engine_en = sys_read32(ADC_ENGINE_CTRL); - if (!(adc_engine_en & 1)) { - // Enable GPI T0 - T7 - pinctrl_val |= 0xff000000; - sys_write32(pinctrl_val, SCU_PIN_CTRL5); - } return 0; } diff --git a/boards/arm/ast1060_dcscm_amd/board.c b/boards/arm/ast1060_dcscm_amd/board.c index af6d9d3..fd407be 100644 --- a/boards/arm/ast1060_dcscm_amd/board.c +++ b/boards/arm/ast1060_dcscm_amd/board.c @@ -21,20 +21,6 @@ static int ast1060_dcscm_post_init(const struct device *arg) static int ast1060_dcscm_init(const struct device *arg) { - // Workaround: - // Will be removed if zephyr sdk supports changing pin function to GPI Tx when ADC engine - // is disabled. -#define ADC_ENGINE_CTRL 0x7e6e9000 -#define SCU_PIN_CTRL5 0x7e6e2430 - - uint32_t pinctrl_val = sys_read32(SCU_PIN_CTRL5); - uint32_t adc_engine_en = sys_read32(ADC_ENGINE_CTRL); - if (!(adc_engine_en & 1)) { - // Enable GPI T0 - T7 - pinctrl_val |= 0xff000000; - sys_write32(pinctrl_val, SCU_PIN_CTRL5); - } - return 0; } diff --git a/boards/arm/ast1060_dcscm_dice/board.c b/boards/arm/ast1060_dcscm_dice/board.c index 70eb035..62d0d9e 100644 --- a/boards/arm/ast1060_dcscm_dice/board.c +++ b/boards/arm/ast1060_dcscm_dice/board.c @@ -26,19 +26,6 @@ static int ast1060_dcscm_init(const struct device *arg) dev = device_get_binding("gpio0_e_h"); gpio_pin_configure(dev, 27, GPIO_OUTPUT_ACTIVE); #endif - // Workaround: - // Will be removed if zephyr sdk supports changing pin function to GPI Tx when ADC engine - // is disabled. -#define ADC_ENGINE_CTRL 0x7e6e9000 -#define SCU_PIN_CTRL5 0x7e6e2430 - - uint32_t pinctrl_val = sys_read32(SCU_PIN_CTRL5); - uint32_t adc_engine_en = sys_read32(ADC_ENGINE_CTRL); - if (!(adc_engine_en & 1)) { - // Enable GPI T0 - T7 - pinctrl_val |= 0xff000000; - sys_write32(pinctrl_val, SCU_PIN_CTRL5); - } return 0; } diff --git a/boards/arm/ast1060_dual_flash/board.c b/boards/arm/ast1060_dual_flash/board.c index 70eb035..62d0d9e 100644 --- a/boards/arm/ast1060_dual_flash/board.c +++ b/boards/arm/ast1060_dual_flash/board.c @@ -26,19 +26,6 @@ static int ast1060_dcscm_init(const struct device *arg) dev = device_get_binding("gpio0_e_h"); gpio_pin_configure(dev, 27, GPIO_OUTPUT_ACTIVE); #endif - // Workaround: - // Will be removed if zephyr sdk supports changing pin function to GPI Tx when ADC engine - // is disabled. -#define ADC_ENGINE_CTRL 0x7e6e9000 -#define SCU_PIN_CTRL5 0x7e6e2430 - - uint32_t pinctrl_val = sys_read32(SCU_PIN_CTRL5); - uint32_t adc_engine_en = sys_read32(ADC_ENGINE_CTRL); - if (!(adc_engine_en & 1)) { - // Enable GPI T0 - T7 - pinctrl_val |= 0xff000000; - sys_write32(pinctrl_val, SCU_PIN_CTRL5); - } return 0; } diff --git a/boards/arm/ast1060_dual_flash_amd/board.c b/boards/arm/ast1060_dual_flash_amd/board.c index af6d9d3..fd407be 100644 --- a/boards/arm/ast1060_dual_flash_amd/board.c +++ b/boards/arm/ast1060_dual_flash_amd/board.c @@ -21,20 +21,6 @@ static int ast1060_dcscm_post_init(const struct device *arg) static int ast1060_dcscm_init(const struct device *arg) { - // Workaround: - // Will be removed if zephyr sdk supports changing pin function to GPI Tx when ADC engine - // is disabled. -#define ADC_ENGINE_CTRL 0x7e6e9000 -#define SCU_PIN_CTRL5 0x7e6e2430 - - uint32_t pinctrl_val = sys_read32(SCU_PIN_CTRL5); - uint32_t adc_engine_en = sys_read32(ADC_ENGINE_CTRL); - if (!(adc_engine_en & 1)) { - // Enable GPI T0 - T7 - pinctrl_val |= 0xff000000; - sys_write32(pinctrl_val, SCU_PIN_CTRL5); - } - return 0; } diff --git a/boards/arm/ast1060_dual_flash_dice/board.c b/boards/arm/ast1060_dual_flash_dice/board.c index 70eb035..62d0d9e 100644 --- a/boards/arm/ast1060_dual_flash_dice/board.c +++ b/boards/arm/ast1060_dual_flash_dice/board.c @@ -26,19 +26,6 @@ static int ast1060_dcscm_init(const struct device *arg) dev = device_get_binding("gpio0_e_h"); gpio_pin_configure(dev, 27, GPIO_OUTPUT_ACTIVE); #endif - // Workaround: - // Will be removed if zephyr sdk supports changing pin function to GPI Tx when ADC engine - // is disabled. -#define ADC_ENGINE_CTRL 0x7e6e9000 -#define SCU_PIN_CTRL5 0x7e6e2430 - - uint32_t pinctrl_val = sys_read32(SCU_PIN_CTRL5); - uint32_t adc_engine_en = sys_read32(ADC_ENGINE_CTRL); - if (!(adc_engine_en & 1)) { - // Enable GPI T0 - T7 - pinctrl_val |= 0xff000000; - sys_write32(pinctrl_val, SCU_PIN_CTRL5); - } return 0; } diff --git a/boards/arm/ast1060_prot/board.c b/boards/arm/ast1060_prot/board.c index 9d94258..344448d 100644 --- a/boards/arm/ast1060_prot/board.c +++ b/boards/arm/ast1060_prot/board.c @@ -113,20 +113,6 @@ static int ast1060_prot_gpio_post_init(void) static int ast1060_prot_init(const struct device *arg) { - // Workaround: - // Will be removed if zephyr sdk supports changing pin function to GPI Tx when ADC engine - // is disabled. -#define ADC_ENGINE_CTRL 0x7e6e9000 -#define SCU_PIN_CTRL5 0x7e6e2430 - - uint32_t pinctrl_val = sys_read32(SCU_PIN_CTRL5); - uint32_t adc_engine_en = sys_read32(ADC_ENGINE_CTRL); - if (!(adc_engine_en & 1)) { - // Enable GPI T0 - T7 - pinctrl_val |= 0xff000000; - sys_write32(pinctrl_val, SCU_PIN_CTRL5); - } - return 0; } diff --git a/boards/arm/ast2700_dcscm/board.c b/boards/arm/ast2700_dcscm/board.c index 90032e5..a425976 100644 --- a/boards/arm/ast2700_dcscm/board.c +++ b/boards/arm/ast2700_dcscm/board.c @@ -31,57 +31,94 @@ static int ast2700_dcscm_init(void) dev = device_get_binding("gpio0_e_h"); gpio_pin_configure(dev, 27, GPIO_OUTPUT_ACTIVE); #endif - // Workaround: - // Will be removed if zephyr sdk supports changing pin function to GPI Tx when ADC engine - // is disabled. -#define ADC_ENGINE_CTRL 0x7e6e9000 -#define SCU_PIN_CTRL5 0x7e6e2430 - - uint32_t pinctrl_val = sys_read32(SCU_PIN_CTRL5); - uint32_t adc_engine_en = sys_read32(ADC_ENGINE_CTRL); - if (!(adc_engine_en & 1)) { - // Enable GPI T0 - T7 - pinctrl_val |= 0xff000000; - sys_write32(pinctrl_val, SCU_PIN_CTRL5); + const struct device *dev; + dev = device_get_binding("sgpiom_a_d"); + if (dev) { + LOG_INF("SGPIOM_A_D PIN[3,4,5,18,19,20(RTC_CPU0),23(RTC_CPU1),24] to 1"); + gpio_pin_set_raw(dev, 3, 1); + gpio_pin_set_raw(dev, 4, 1); + gpio_pin_set_raw(dev, 5, 1); + gpio_pin_set_raw(dev, 18, 1); + gpio_pin_set_raw(dev, 19, 1); + gpio_pin_set_raw(dev, 20, 1); // RTCRST CPU0 + gpio_pin_set_raw(dev, 24, 1); + gpio_pin_set_raw(dev, 23, 1); // RTCRST CPU1 + } + + dev = device_get_binding("sgpiom_e_h"); + if (dev) { + LOG_INF("SGPIOM_E_H PIN[16,17,18,19,20] to 1"); + gpio_pin_set_raw(dev, 16, 1); + gpio_pin_set_raw(dev, 17, 1); + gpio_pin_set_raw(dev, 18, 1); + gpio_pin_set_raw(dev, 19, 1); + gpio_pin_set_raw(dev, 20, 1); + } + + dev = device_get_binding("sgpiom_i_l"); + if (dev) { + LOG_INF("SGPIOM_I_L PIN[2,6,7] to 1"); + gpio_pin_set_raw(dev, 2, 1); + gpio_pin_set_raw(dev, 6, 1); + gpio_pin_set_raw(dev, 7, 1); } return 0; } -static void sgpio_passthrough_workaround(struct k_timer *timer_id) { +static void sgpio_passthrough_workaround(struct k_timer *timer_id) +{ const struct device *dev = NULL; - uint32_t mask = 0; + extern struct k_event pfr_system_event; + static bool printed = false; - /* Bit 31:0 */ - dev = device_get_binding("sgpiom_a_d"); - mask = 0x00000000; - if (dev && mask) { - LOG_DBG("PASSTHROUGH [%s %08x]", dev->name, mask); - sgpio_passthrough(dev, mask); - } + if (k_event_wait(&pfr_system_event, BIT(0), false, K_NO_WAIT)) { + LOG_DBG("SGPIO Passthrough"); + uint32_t mask = 0; - /* Bit 63:32 */ - dev = device_get_binding("sgpiom_e_h"); - mask = 0xFFFF0000; - if (dev && mask) { - LOG_DBG("PASSTHROUGH [%s %08x]", dev->name, mask); - sgpio_passthrough(dev, mask); - } + /* Bit 31:0 */ + dev = device_get_binding("sgpiom_a_d"); + mask = 0x00000000; + if (dev && mask) { + if (printed == false) + LOG_WRN("PASSTHROUGH [%s %08x]", dev->name, mask); + sgpio_passthrough(dev, mask); + } - /* Bit 95:64 */ - dev = device_get_binding("sgpiom_i_l"); - mask = 0xFFFFFFFF; - if (dev && mask) { - LOG_DBG("PASSTHROUGH [%s %08x]", dev->name, mask); - sgpio_passthrough(dev, mask); - } + /* Bit 63:32 */ + dev = device_get_binding("sgpiom_e_h"); + mask = 0xFFFFFF00; + if (dev && mask) { + if (printed == false) + LOG_WRN("PASSTHROUGH [%s %08x]", dev->name, mask); + sgpio_passthrough(dev, mask); + } - /* Bit 127:96 */ - dev = device_get_binding("sgpiom_m_p"); - mask = 0xFFFFFFFF; - if (dev && mask) { - LOG_DBG("PASSTHROUGH [%s %08x]", dev->name, mask); - sgpio_passthrough(dev, mask); + /* Bit 95:64 */ + dev = device_get_binding("sgpiom_i_l"); + mask = 0xFFFFFFFF; + if (dev && mask) { + if (printed == false) + LOG_WRN("PASSTHROUGH [%s %08x]", dev->name, mask); + sgpio_passthrough(dev, mask); + } + + /* Bit 127:96 */ + dev = device_get_binding("sgpiom_m_p"); + mask = 0xFFFFFFFF; + if (dev && mask) { + if (printed == false) + LOG_WRN("PASSTHROUGH [%s %08x]", dev->name, mask); + sgpio_passthrough(dev, mask); + } + if (printed == false) + printed = true; + } else { + static uint32_t count = 0; + if ((++count & 0xFF) == 0) { + /* Do not flood the console log */ + LOG_WRN("SGPIO Passthrough wait for BMC Boot complete flag"); + } } } @@ -91,6 +128,17 @@ K_TIMER_DEFINE(dcscm_sgpio_passthrough_workaround, static int ast2700_sgpio_workaround_init(void) { +#define SCU_PIN_CTRL4 0x7e6e241c + uint32_t pinctrl_val = sys_read32(SCU_PIN_CTRL4); + pinctrl_val &= ~BIT(12); + sys_write32(pinctrl_val, SCU_PIN_CTRL4); + + const struct device *dev = device_get_binding("gpio0_m_p"); + if (dev) { + int ret = gpio_pin_configure(dev, 12, GPIO_OUTPUT); + ret = gpio_pin_set_raw(dev, 12, 1); + } + // I don't have a good value here, so let's starts the workaround // after 200ms and runs every 50ms period LOG_WRN("AST2700-A0 SGPIO Passthrough Workaround"); diff --git a/lib/hrot_hal/CMakeLists.txt b/lib/hrot_hal/CMakeLists.txt index 6f6799c..53f6fc9 100644 --- a/lib/hrot_hal/CMakeLists.txt +++ b/lib/hrot_hal/CMakeLists.txt @@ -17,15 +17,11 @@ if (CONFIG_HROT_HAL) ${HROT_MIDDLEWARE_ROOT}/flash/flash_aspeed.c ${HROT_MIDDLEWARE_ROOT}/gpio/gpio_aspeed.c ${HROT_MIDDLEWARE_ROOT}/crypto/hash_aspeed.c - ${HROT_MIDDLEWARE_ROOT}/crypto/rsa_aspeed.c ${HROT_MIDDLEWARE_ROOT}/crypto/ecdsa_aspeed.c - ${HROT_MIDDLEWARE_ROOT}/i2c/hal_i2c.c - ${HROT_MIDDLEWARE_ROOT}/watchdog/watchdog_aspeed.c - # ${HROT_MIDDLEWARE_ROOT}/otp/otp_aspeed.c - ${HROT_MIDDLEWARE_ROOT}/abr/abr_aspeed.c - ${HROT_MIDDLEWARE_ROOT}/spi_filter/spi_filter_aspeed.c ) + zephyr_library_sources_ifdef(CONFIG_CERBERUS_PFR ${HROT_MIDDLEWARE_ROOT}/crypto/rsa_aspeed.c) + zephyr_library_include_directories( . $ENV{ZEPHYR_BASE}/build/zephyr/include/generated/ diff --git a/lib/hrot_hal/abr/abr_aspeed.c b/lib/hrot_hal/abr/abr_aspeed.c deleted file mode 100644 index cec6ed8..0000000 --- a/lib/hrot_hal/abr/abr_aspeed.c +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2022 ASPEED Technology Inc. - * - * SPDX-License-Identifier: MIT - */ - -#include "abr_aspeed.h" -#include -#include - -void print_abr_wdt_info(void) -{ - /* ABR enable */ - if (sys_read32(HW_STRAP2_SCU510) & BIT(11)) // OTPSTRAP[43] - printk("\r\n The boot SPI ABR is enabled"); - else - printk("\r\n The boot SPI ABR is disabled"); - - if (sys_read32(HW_STRAP2_SCU510) & BIT(12)) // OTPSTRAP[44] - printk(", Single flash"); - else - printk(", Dual flashes"); - // OTPSTRAP[3] - printk(", Source: %s (%s)", - (sys_read32(ASPEED_FMC_WDT2_CTRL) & BIT(4)) ? "Alternate" : "Primary", // Boot flash source select indicator - (sys_read32(HW_STRAP1_SCU500) & BIT(3)) ? "1/3 flash layout" : "1/2 flash layout"); - - if (sys_read32(HW_STRAP2_SCU510) & GENMASK(15, 13)) { // OTPSTRAP[47:45] - printk(", Boot SPI flash size: %ldMB.", - BIT((sys_read32(HW_STRAP2_SCU510) >> 13) & 0x7) / 2); - } else - printk(", no define size."); - - printk("\n"); - - if (sys_read32(ASPEED_FMC_WDT2_CTRL) & BIT(0)) - printk("\r\n WDT status: enabled.\n"); - else - printk("\r\n WDT status: disabled.\n"); -} - -void clear_source_select_indicator(void) -{ - uint32_t reg_val; - uint8_t bitmask; - - bitmask = 0xea; - reg_val = sys_read32(ASPEED_FMC_WDT2_CTRL); - reg_val |= bitmask << 16; - sys_write32(reg_val, ASPEED_FMC_WDT2_CTRL); - printk("\r\n The indicator is cleared.\n"); -} - -void disable_watchdog(void) -{ - uint32_t reg_val; - uint8_t bitmask; - - bitmask = BIT(0); - reg_val = sys_read32(ASPEED_FMC_WDT2_CTRL); - reg_val &= ~bitmask; - sys_write32(reg_val, ASPEED_FMC_WDT2_CTRL); - printk("\r\n The WDT is disabled.\n"); -} diff --git a/lib/hrot_hal/abr/abr_aspeed.h b/lib/hrot_hal/abr/abr_aspeed.h deleted file mode 100644 index f5f646d..0000000 --- a/lib/hrot_hal/abr/abr_aspeed.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (c) 2022 ASPEED Technology Inc. - * - * SPDX-License-Identifier: MIT - */ - -#pragma once - -#define HW_STRAP1_SCU500 0x7e6e2500 -#define HW_STRAP2_SCU510 0x7e6e2510 -#define ASPEED_FMC_WDT2_CTRL 0x7e620064 - diff --git a/lib/hrot_hal/flash/flash_aspeed.c b/lib/hrot_hal/flash/flash_aspeed.c index 7bd7c5c..2988bb1 100644 --- a/lib/hrot_hal/flash/flash_aspeed.c +++ b/lib/hrot_hal/flash/flash_aspeed.c @@ -54,7 +54,7 @@ int BMC_PCH_SPI_Command(struct pspi_flash *flash, struct pflash_xfer *xfer) uint8_t DeviceId = flash->state->device_id[0]; int AdrOffset = xfer->address; int Datalen = xfer->length; - uint32_t FlashSize = 0; + int FlashSize = 0; int ret = 0; switch (xfer->cmd) { @@ -68,9 +68,13 @@ int BMC_PCH_SPI_Command(struct pspi_flash *flash, struct pflash_xfer *xfer) return get_block_erase_size(DeviceId); break; case MIDLEY_FLASH_CMD_READ: + if (xfer->data == NULL) + return -1; ret = bmc_pch_flash_read(DeviceId, AdrOffset, Datalen, xfer->data); break; case MIDLEY_FLASH_CMD_PP://Flash Write + if (xfer->data == NULL) + return -1; ret = bmc_pch_flash_write(DeviceId, AdrOffset, Datalen, xfer->data); break; case MIDLEY_FLASH_CMD_4K_ERASE: @@ -81,15 +85,22 @@ int BMC_PCH_SPI_Command(struct pspi_flash *flash, struct pflash_xfer *xfer) break; case MIDLEY_FLASH_CMD_CE: FlashSize = bmc_pch_get_flash_size(DeviceId); - ret = bmc_pch_flash_erase(DeviceId, AdrOffset, FlashSize, false); + if (FlashSize > 0) { + ret = bmc_pch_flash_erase(DeviceId, AdrOffset, FlashSize, false); + } else { + LOG_ERR("Failed to get flash size device_id=%x", DeviceId); + ret = -1; + } break; case MIDLEY_FLASH_CMD_RDSR: + if (xfer->data == NULL) + return -1; // bypass as flash status are write enabled and not busy *xfer->data = 0x02; ret = 0; break; default: - LOG_DBG("%d Command is not supported\n", xfer->cmd); + LOG_DBG("%d Command is not supported", xfer->cmd); break; } @@ -111,9 +122,13 @@ int FMC_SPI_Command(struct pspi_flash *flash, struct pflash_xfer *xfer) ret = 0; // bypass as write enabled break; case MIDLEY_FLASH_CMD_READ: + if (xfer->data == NULL) + return -1; ret = rot_flash_read(DeviceId, AdrOffset, Datalen, xfer->data); break; case MIDLEY_FLASH_CMD_PP://Flash Write + if (xfer->data == NULL) + return -1; ret = rot_flash_write(DeviceId, AdrOffset, Datalen, xfer->data); break; case MIDLEY_FLASH_CMD_4K_ERASE: @@ -123,16 +138,18 @@ int FMC_SPI_Command(struct pspi_flash *flash, struct pflash_xfer *xfer) ret = rot_flash_erase(DeviceId, AdrOffset, BLOCK_SIZE, false); break; case MIDLEY_FLASH_CMD_CE: - LOG_DBG("%d Command is not supported\n", xfer->cmd); + LOG_DBG("%d Command is not supported", xfer->cmd); ret = 0; break; case MIDLEY_FLASH_CMD_RDSR: + if (xfer->data == NULL) + return -1; // bypass as flash status are write enabled and not busy *xfer->data = 0x02; ret = 0; break; default: - LOG_ERR("%d Command is not supported\n", xfer->cmd); + LOG_ERR("%d Command is not supported", xfer->cmd); break; } @@ -426,6 +443,10 @@ int rot_get_region_size(uint8_t device_id) int get_block_erase_size(uint8_t device_id) { int block_erase_sz = 0; + + if (device_id >= ARRAY_SIZE(Flash_Devices_List)) + return SECTOR_SIZE; + const struct device *flash_device = device_get_binding(Flash_Devices_List[device_id]); block_erase_sz = spi_nor_get_erase_sz(flash_device, MIDLEY_FLASH_CMD_BLOCK_ERASE); diff --git a/lib/hrot_hal/gpio/gpio_aspeed.c b/lib/hrot_hal/gpio/gpio_aspeed.c index 1ecadb9..1d43e98 100644 --- a/lib/hrot_hal/gpio/gpio_aspeed.c +++ b/lib/hrot_hal/gpio/gpio_aspeed.c @@ -137,7 +137,7 @@ int PCHBootHold(void) RSTPlatformReset(true); /* Hold low AUX PWRGD */ - RTCRSTControl(true); + // RTCRSTControl(true); AUXPowerGoodControl(false); /* Hold PCH Reset */ #ifndef INTEL_BHS @@ -236,7 +236,7 @@ int PCHBootRelease(void) spim_ext_mux_config(dev_m, SPIM_EXT_MUX_BMC_PCH); #endif - RTCRSTControl(false); + // RTCRSTControl(false); AUXPowerGoodControl(true); // pch_rst_enable_ctrl(false); diff --git a/lib/hrot_hal/otp/otp_aspeed.c b/lib/hrot_hal/otp/otp_aspeed.c deleted file mode 100644 index 6114611..0000000 --- a/lib/hrot_hal/otp/otp_aspeed.c +++ /dev/null @@ -1,652 +0,0 @@ -/* - * Copyright (c) 2022 ASPEED Technology Inc. - * - * SPDX-License-Identifier: MIT - */ - -#include "otp_aspeed.h" -#include -#include -#include -#include -#include - -#define OTP_PASSWD 0x349fe38a - -#define OTP_BASE 0x7e6f2000 -#define OTP_PROTECT_KEY OTP_BASE -#define OTP_COMMAND (OTP_BASE + 0x4) -#define OTP_TIMING (OTP_BASE + 0x8) -#define OTP_ADDR (OTP_BASE + 0x10) -#define OTP_STATUS (OTP_BASE + 0x14) -#define OTP_COMPARE_1 (OTP_BASE + 0x20) -#define OTP_COMPARE_2 (OTP_BASE + 0x24) -#define OTP_COMPARE_3 (OTP_BASE + 0x28) -#define OTP_COMPARE_4 (OTP_BASE + 0x2c) -#define SW_REV_ID0 (OTP_BASE + 0x68) -#define SW_REV_ID1 (OTP_BASE + 0x6c) -#define SEC_KEY_NUM (OTP_BASE + 0x78) - -#define ASPEED_REVISION_ID0 0x7e6e2004 -#define ASPEED_REVISION_ID1 0x7e6e2014 - -#define ID0_AST1030A0 0x80000000 -#define ID1_AST1030A0 0x80000000 -#define ID0_AST1030A1 0x80010000 -#define ID1_AST1030A1 0x80010000 -#define ID0_AST1060A1 0xA0010000 -#define ID1_AST1060A1 0xA0010000 - -#define OTP_AST1030A0 1 -#define OTP_AST1030A1 2 -#define OTP_AST1060A1 3 - -#define OTP_USAGE -1 -#define OTP_FAILURE -2 -#define OTP_SUCCESS 0 - -#define OTP_KEY_TYPE_RSA_PUB 1 -#define OTP_KEY_TYPE_RSA_PRIV 2 -#define OTP_KEY_TYPE_AES 3 -#define OTP_KEY_TYPE_VAULT 4 -#define OTP_KEY_TYPE_HMAC 5 -#define OTP_KEY_ECDSA384 6 -#define OTP_KEY_ECDSA384P 7 - -struct otp_pro_sts { - char mem_lock; - char pro_key_ret; - char pro_strap; - char pro_conf; - char pro_data; - char pro_sec; - uint32_t sec_size; -}; - -struct otpkey_type { - int value; - int key_type; - int need_id; - char information[110]; -}; - - -struct otp_info_cb { - int version; - char ver_name[10]; - const struct otpstrap_info *strap_info; - int strap_info_len; - const struct otpconf_info *conf_info; - int conf_info_len; - const struct otpkey_type *key_info; - int key_info_len; - const struct scu_info *scu_info; - int scu_info_len; - struct otp_pro_sts pro_sts; -}; - -static const struct otpkey_type ast10xxa0_key_type[] = { - { - 1, OTP_KEY_TYPE_VAULT, 0, - "AES-256 as secret vault key" - }, - { - 2, OTP_KEY_TYPE_AES, 1, - "AES-256 as OEM platform key for image encryption/decryption in Mode 2 or AES-256 as OEM DSS keys for Mode GCM" - }, - { - 8, OTP_KEY_TYPE_RSA_PUB, 1, - "RSA-public as OEM DSS public keys in Mode 2" - }, - { - 10, OTP_KEY_TYPE_RSA_PUB, 0, - "RSA-public as AES key decryption key" - }, - { - 14, OTP_KEY_TYPE_RSA_PRIV, 0, - "RSA-private as AES key decryption key" - }, -}; - -static struct otp_info_cb info_cb; -//static struct otpstrap_status strap_status[64]; - -static uint32_t chip_version(void) -{ - uint32_t revid0, revid1; - - revid0 = sys_read32(ASPEED_REVISION_ID0); - revid1 = sys_read32(ASPEED_REVISION_ID1); - - if (revid0 == ID0_AST1030A0 && revid1 == ID1_AST1030A0) { - /* AST1030-A0 */ - return OTP_AST1030A0; - } else if (revid0 == ID0_AST1030A1 && revid1 == ID1_AST1030A1) { - /* AST1030-A1 */ - return OTP_AST1030A1; - } else if (revid0 == ID0_AST1060A1 && revid1 == ID1_AST1060A1) { - /* AST1060-A1 */ - return OTP_AST1060A1; - } - return OTP_FAILURE; -} - -static const struct otpkey_type ast10xxa1_key_type[] = { - { - 1, OTP_KEY_TYPE_VAULT, 0, - "AES-256 as secret vault key" - }, - { - 2, OTP_KEY_TYPE_AES, 1, - "AES-256 as OEM platform key for image encryption/decryption in Mode 2 or AES-256 as OEM DSS keys for Mode GCM" - }, - { - 8, OTP_KEY_TYPE_RSA_PUB, 1, - "RSA-public as OEM DSS public keys in Mode 2" - }, - { - 9, OTP_KEY_TYPE_RSA_PUB, 1, - "RSA-public as OEM DSS public keys in Mode 2(big endian)" - }, - { - 10, OTP_KEY_TYPE_RSA_PUB, 0, - "RSA-public as AES key decryption key" - }, - { - 11, OTP_KEY_TYPE_RSA_PUB, 0, - "RSA-public as AES key decryption key(big endian)" - }, - { - 12, OTP_KEY_TYPE_RSA_PRIV, 0, - "RSA-private as AES key decryption key" - }, - { - 13, OTP_KEY_TYPE_RSA_PRIV, 0, - "RSA-private as AES key decryption key(big endian)" - }, - { - 5, OTP_KEY_ECDSA384P, 0, - "ECDSA384 cure parameter" - }, - { - 7, OTP_KEY_ECDSA384, 0, - "ECDSA-public as OEM DSS public keys" - } -}; - -static void wait_complete(void) -{ - int reg; - - k_usleep(100); - do { - reg = sys_read32(OTP_STATUS); - } while ((reg & 0x6) != 0x6); -} - -static void otp_read_conf(uint32_t offset, uint32_t *data) -{ - int config_offset; - - config_offset = 0x800; - config_offset |= (offset / 8) * 0x200; - config_offset |= (offset % 8) * 0x2; - - sys_write32(config_offset, OTP_ADDR); /* Read address */ - sys_write32(0x23b1e361, OTP_COMMAND); /* trigger read */ - wait_complete(); - data[0] = sys_read32(OTP_COMPARE_1); -} - -static int ast_otp_init(void) -{ - struct otp_pro_sts *pro_sts; - uint32_t ver; - uint32_t otp_conf0; - - ver = chip_version(); - switch (ver) { - case OTP_AST1030A0: - info_cb.version = OTP_AST1030A0; - info_cb.conf_info = ast1030a0_conf_info; - info_cb.conf_info_len = ARRAY_SIZE(ast1030a0_conf_info); - info_cb.strap_info = ast1030a0_strap_info; - info_cb.strap_info_len = ARRAY_SIZE(ast1030a0_strap_info); - info_cb.key_info = ast10xxa0_key_type; - info_cb.key_info_len = ARRAY_SIZE(ast10xxa0_key_type); - sprintf(info_cb.ver_name, "AST1030A0"); - //printk("\r\n OTP init: the SOC version is AST1030A0\r\n"); - break; - case OTP_AST1030A1: - info_cb.version = OTP_AST1030A1; - info_cb.conf_info = ast1030a1_conf_info; - info_cb.conf_info_len = ARRAY_SIZE(ast1030a1_conf_info); - info_cb.strap_info = ast1030a0_strap_info; - info_cb.strap_info_len = ARRAY_SIZE(ast1030a0_strap_info); - info_cb.key_info = ast10xxa1_key_type; - info_cb.key_info_len = ARRAY_SIZE(ast10xxa1_key_type); - sprintf(info_cb.ver_name, "AST1030A1"); - //printk("\r\n OTP init: the SOC version is AST1030A1\r\n"); - break; - case OTP_AST1060A1: - info_cb.version = OTP_AST1060A1; - info_cb.conf_info = ast1030a1_conf_info; - info_cb.conf_info_len = ARRAY_SIZE(ast1030a1_conf_info); - info_cb.strap_info = ast1030a0_strap_info; - info_cb.strap_info_len = ARRAY_SIZE(ast1030a0_strap_info); - info_cb.key_info = ast10xxa1_key_type; - info_cb.key_info_len = ARRAY_SIZE(ast10xxa1_key_type); - sprintf(info_cb.ver_name, "AST1060A1"); - //printk("\r\n OTP init: the SOC version is AST1060A1\r\n"); - break; - default: - printk("SOC is not supported\n"); - return -EINVAL; - } - - sys_write32(OTP_PASSWD, OTP_PROTECT_KEY); /* password */ - otp_read_conf(0, &otp_conf0); - pro_sts = &info_cb.pro_sts; - - pro_sts->mem_lock = (otp_conf0 >> 31) & 0x1; - pro_sts->pro_key_ret = (otp_conf0 >> 29) & 0x1; - pro_sts->pro_strap = (otp_conf0 >> 25) & 0x1; - pro_sts->pro_conf = (otp_conf0 >> 24) & 0x1; - pro_sts->pro_data = (otp_conf0 >> 23) & 0x1; - pro_sts->pro_sec = (otp_conf0 >> 22) & 0x1; - pro_sts->sec_size = ((otp_conf0 >> 16) & 0x3f) << 5; - - return 0; -} - -static void ast_otp_finish(void) -{ - sys_write32(1, OTP_PROTECT_KEY); /* protect otp controller */ -} - -static void otp_write(uint32_t otp_addr, uint32_t data) -{ - sys_write32(otp_addr, OTP_ADDR); /* write address */ - sys_write32(data, OTP_COMPARE_1); /* write data */ - sys_write32(0x23b1e362, OTP_COMMAND); /* write command */ - wait_complete(); -} - -static void otp_soak(int soak) -{ - switch (soak) { - case 0: /* default */ - otp_write(0x3000, 0x0); /* Write MRA */ - otp_write(0x5000, 0x0); /* Write MRB */ - otp_write(0x1000, 0x0); /* Write MR */ - break; - case 1: /* normal program */ - otp_write(0x3000, 0x1320); /* Write MRA */ - otp_write(0x5000, 0x1008); /* Write MRB */ - otp_write(0x1000, 0x0024); /* Write MR */ - sys_write32(0x04191388, OTP_TIMING); /* 200us */ - break; - case 2: /* soak program */ - otp_write(0x3000, 0x1320); /* Write MRA */ - otp_write(0x5000, 0x0007); /* Write MRB */ - otp_write(0x1000, 0x0100); /* Write MR */ - sys_write32(0x04193a98, OTP_TIMING); /* 600us */ - break; - } - wait_complete(); -} - -static void otp_read_data(uint32_t offset, uint32_t *data) -{ - sys_write32(offset, OTP_ADDR); /* Read address */ - sys_write32(0x23b1e361, OTP_COMMAND); /* trigger read */ - wait_complete(); - data[0] = sys_read32(OTP_COMPARE_1); - data[1] = sys_read32(OTP_COMPARE_2); -} - -static void otp_strap_status(struct otpstrap_status *os) -{ - uint32_t OTPSTRAP_RAW[2]; - int strap_end; - int i, j; - - for (j = 0; j < 64; j++) { - os[j].value = 0; - os[j].remain_times = 6; - os[j].writeable_option = -1; - os[j].protected = 0; - } - strap_end = 28; - - otp_soak(0); - for (i = 16; i < strap_end; i += 2) { - int option = (i - 16) / 2; - - otp_read_conf(i, &OTPSTRAP_RAW[0]); - otp_read_conf(i + 1, &OTPSTRAP_RAW[1]); - for (j = 0; j < 32; j++) { - char bit_value = ((OTPSTRAP_RAW[0] >> j) & 0x1); - - if (bit_value == 0 && os[j].writeable_option == -1) - os[j].writeable_option = option; - if (bit_value == 1) - os[j].remain_times--; - os[j].value ^= bit_value; - os[j].option_array[option] = bit_value; - } - for (j = 32; j < 64; j++) { - char bit_value = ((OTPSTRAP_RAW[1] >> (j - 32)) & 0x1); - - if (bit_value == 0 && os[j].writeable_option == -1) - os[j].writeable_option = option; - if (bit_value == 1) - os[j].remain_times--; - os[j].value ^= bit_value; - os[j].option_array[option] = bit_value; - } - } - - otp_read_conf(30, &OTPSTRAP_RAW[0]); - otp_read_conf(31, &OTPSTRAP_RAW[1]); - for (j = 0; j < 32; j++) { - if (((OTPSTRAP_RAW[0] >> j) & 0x1) == 1) - os[j].protected = 1; - } - for (j = 32; j < 64; j++) { - if (((OTPSTRAP_RAW[1] >> (j - 32)) & 0x1) == 1) - os[j].protected = 1; - } -} - -static int otp_print_strap(int start, int count, struct otpstrap_status *strap_status) -{ - int i, j; - int remains = 6; - - if (start < 0 || start > 64) - return OTP_USAGE; - - if ((start + count) < 0 || (start + count) > 64) - return OTP_USAGE; - - otp_strap_status(strap_status); -/* - printk("BIT(hex) Value Option Status\n"); - printk("______________________________________________________________________________\n"); - - for (i = start; i < start + count; i++) { - printk("0x%-8X", i); - printk("%-7d", strap_status[i].value); - for (j = 0; j < remains; j++) - printk("%d ", strap_status[i].option_array[j]); - printk(" "); - if (strap_status[i].protected == 1) { - printk("protected and not writable"); - } else { - printk("not protected "); - if (strap_status[i].remain_times == 0) - printk("and no remaining times to write."); - else - printk("and still can write %d times", strap_status[i].remain_times); - } - printk("\n"); - } -*/ - return OTP_SUCCESS; -} - -static int otp_print_conf(uint32_t offset, uint32_t dw_count, uint32_t *buf) -{ - int i; - uint32_t ret[1]; - - if (offset + dw_count > 32) - return OTP_USAGE; - otp_soak(0); - for (i = offset; i < offset + dw_count; i++) { - otp_read_conf(i, ret); - //printk("OTPCFG0x%X: 0x%08X\n", i, ret[0]); - buf[i-offset] = ret[0]; - } - return OTP_SUCCESS; -} - -int do_otpread_conf(uint32_t offset, uint32_t count, uint32_t *buf) -{ - int ret; - - ret = ast_otp_init(); - if (ret) - goto end; - - ret = otp_print_conf(offset, count, buf); -end: - ast_otp_finish(); - return ret; -} - -static int otp_print_data(uint32_t offset, uint32_t dw_count, uint32_t *buf) -{ - int i; - uint32_t ret[2]; - - if (offset + dw_count > 2048 || offset % 4 != 0) - return OTP_USAGE; - otp_soak(0); - for (i = offset; i < offset + dw_count; i += 2) { - //printk(i); - otp_read_data(i, ret); - /* - if (i % 4 == 0) - printk("%03X: %08X %08X ", i * 4, ret[0], ret[1]); - else - printk("%08X %08X\n", ret[0], ret[1]); - */ - buf[i-offset] = ret[0]; - buf[i-offset+1] = ret[1]; - } - return OTP_SUCCESS; -} - -int do_otpread_data(uint32_t offset, uint32_t count, uint32_t *buf) -{ - int ret; - - ret = ast_otp_init(); - if (ret) - goto end; - - ret = otp_print_data(offset, count, buf); -end: - ast_otp_finish(); - return ret; -} - -int do_otpread_strap(uint32_t offset, uint32_t count, struct otpstrap_status *strap_status) -{ - int ret; - - ret = ast_otp_init(); - if (ret) - goto end; - - ret = otp_print_strap(offset, count, strap_status); -end: - ast_otp_finish(); - return ret; -} - -static int otp_print_conf_info(int input_offset) -{ - const struct otpconf_info *conf_info = info_cb.conf_info; - uint32_t OTPCFG[16]; - uint32_t mask; - uint32_t dw_offset; - uint32_t bit_offset; - uint32_t otp_value; - char valid_bit[20]; - int i; - int j; - - otp_soak(0); - for (i = 0; i < 16; i++) - otp_read_conf(i, &OTPCFG[i]); - - printk("DW BIT Value Description\n"); - printk("__________________________________________________________________________\n"); - for (i = 0; i < info_cb.conf_info_len; i++) { - if (input_offset != -1 && input_offset != conf_info[i].dw_offset) - continue; - dw_offset = conf_info[i].dw_offset; - bit_offset = conf_info[i].bit_offset; - mask = BIT(conf_info[i].length) - 1; - otp_value = (OTPCFG[dw_offset] >> bit_offset) & mask; - - if (otp_value != conf_info[i].value && - conf_info[i].value != OTP_REG_RESERVED && - conf_info[i].value != OTP_REG_VALUE && - conf_info[i].value != OTP_REG_VALID_BIT) - continue; - printk("0x%-4X", dw_offset); - - if (conf_info[i].length == 1) { - printk("0x%-9X", conf_info[i].bit_offset); - } else { - printk("0x%-2X:0x%-4X", - conf_info[i].bit_offset + conf_info[i].length - 1, - conf_info[i].bit_offset); - } - printk("0x%-10x", otp_value); - - if (conf_info[i].value == OTP_REG_RESERVED) { - printk("Reserved\n"); - } else if (conf_info[i].value == OTP_REG_VALUE) { - printk(conf_info[i].information, otp_value); - printk("\n"); - } else if (conf_info[i].value == OTP_REG_VALID_BIT) { - if (otp_value != 0) { - for (j = 0; j < 7; j++) { - if (otp_value & (1 << j)) - valid_bit[j * 2] = '1'; - else - valid_bit[j * 2] = '0'; - valid_bit[j * 2 + 1] = ' '; - } - valid_bit[15] = 0; - } else { - strcpy(valid_bit, "0 0 0 0 0 0 0 0\0"); - } - printk(conf_info[i].information, valid_bit); - printk("\n"); - } else { - printk("%s\n", conf_info[i].information); - } - } - return OTP_SUCCESS; -} - -static int do_otpinfo_conf(void) -{ - int ret; - - ret = ast_otp_init(); - if (ret) - goto end; - - otp_print_conf_info(-1); - -end: - ast_otp_finish(); - return ret; -} -/* -static int otp_print_strap_info(int view) -{ - const struct otpstrap_info *strap_info = info_cb.strap_info; - int i, j; - int fail = 0; - uint32_t bit_offset; - uint32_t length; - uint32_t otp_value; - uint32_t otp_protect; - - otp_strap_status(strap_status); - - if (view) { - printk("BIT(hex) Value Remains Protect Description\n"); - printk("___________________________________________________________________________________________________\n"); - } else { - printk("BIT(hex) Value Description\n"); - printk("________________________________________________________________________________\n"); - } - for (i = 0; i < info_cb.strap_info_len; i++) { - otp_value = 0; - bit_offset = strap_info[i].bit_offset; - length = strap_info[i].length; - for (j = 0; j < length; j++) { - otp_value |= strap_status[bit_offset + j].value << j; - otp_protect |= strap_status[bit_offset + j].protected << j; - } - if (otp_value != strap_info[i].value && - strap_info[i].value != OTP_REG_RESERVED) - continue; - if (view) { - for (j = 0; j < length; j++) { - printk("0x%-7X", strap_info[i].bit_offset + j); - printk("0x%-5X", strap_status[bit_offset + j].value); - printk("%-9d", strap_status[bit_offset + j].remain_times); - printk("0x%-7X", strap_status[bit_offset + j].protected); - if (strap_info[i].value == OTP_REG_RESERVED) { - printk("Reserved\n"); - continue; - } - if (length == 1) { - printk("%s\n", strap_info[i].information); - continue; - } - - if (j == 0) - printk("/%s\n", strap_info[i].information); - else if (j == length - 1) - printk("\\ \"\n"); - else - printk("| \"\n"); - } - } else { - if (length == 1) { - printk("0x%-9X", strap_info[i].bit_offset); - } else { - printk("0x%-2X:0x%-4X", - bit_offset + length - 1, bit_offset); - } - - printk("0x%-10X", otp_value); - - if (strap_info[i].value != OTP_REG_RESERVED) - printk("%s\n", strap_info[i].information); - else - printk("Reserved\n"); - } - } - - if (fail) - return OTP_FAILURE; - - return OTP_SUCCESS; -} -*/ -static int do_otpinfo_strap(void) -{ - int ret; - - ret = ast_otp_init(); - if (ret) - goto end; - - otp_print_strap_info(1); - -end: - ast_otp_finish(); - return ret; -} diff --git a/lib/hrot_hal/otp/otp_aspeed.h b/lib/hrot_hal/otp/otp_aspeed.h deleted file mode 100644 index 23706da..0000000 --- a/lib/hrot_hal/otp/otp_aspeed.h +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright (c) 2022 ASPEED Technology Inc. - * - * SPDX-License-Identifier: MIT - */ - -#pragma once - -#include - -#define OTP_REG_RESERVED -1 -#define OTP_REG_VALUE -2 -#define OTP_REG_VALID_BIT -3 - -struct otpconf_info { - signed char dw_offset; - signed char bit_offset; - signed char length; - signed char value; - const char *information; -}; - -struct otpstrap_info { - signed char bit_offset; - signed char length; - signed char value; - const char *information; -}; - -struct otpstrap_status { - int value; - int option_array[7]; - int remain_times; - int writeable_option; - int protected; -}; - -static const struct otpstrap_info ast1030a0_strap_info[] = { - { 0, 1, 0, "Disable Secure Boot" }, - { 0, 1, 1, "Enable Secure Boot" }, - { 1, 1, 0, "Disable boot from eMMC" }, - { 1, 1, 1, "Enable boot from eMMC" }, - { 2, 1, 0, "Disable Boot from debug SPI" }, - { 2, 1, 1, "Enable Boot from debug SPI" }, - { 3, 1, 0, "Enable ARM CM3" }, - { 3, 1, 1, "Disable ARM CM3" }, - { 4, 1, 0, "No VGA BIOS ROM, VGA BIOS is merged in the system BIOS" }, - { 4, 1, 1, "Enable dedicated VGA BIOS ROM" }, - { 5, 1, 0, "MAC 1 : RMII/NCSI" }, - { 5, 1, 1, "MAC 1 : RGMII" }, - { 6, 1, 0, "MAC 2 : RMII/NCSI" }, - { 6, 1, 1, "MAC 2 : RGMII" }, - { 7, 3, 0, "CPU Frequency : 1.2GHz" }, - { 7, 3, 1, "CPU Frequency : 1.6GHz" }, - { 7, 3, 2, "CPU Frequency : 1.2GHz" }, - { 7, 3, 3, "CPU Frequency : 1.6GHz" }, - { 7, 3, 4, "CPU Frequency : 800MHz" }, - { 7, 3, 5, "CPU Frequency : 800MHz" }, - { 7, 3, 6, "CPU Frequency : 800MHz" }, - { 7, 3, 7, "CPU Frequency : 800MHz" }, - { 10, 2, 0, "HCLK ratio AXI:AHB = default" }, - { 10, 2, 1, "HCLK ratio AXI:AHB = 2:1" }, - { 10, 2, 2, "HCLK ratio AXI:AHB = 3:1" }, - { 10, 2, 3, "HCLK ratio AXI:AHB = 4:1" }, - { 12, 2, 0, "VGA memory size : 8MB" }, - { 12, 2, 1, "VGA memory size : 16MB" }, - { 12, 2, 2, "VGA memory size : 32MB" }, - { 12, 2, 3, "VGA memory size : 64MB" }, - { 15, 1, 0, "CPU/AXI clock ratio : 2:1" }, - { 15, 1, 1, "CPU/AXI clock ratio : 1:1" }, - { 16, 1, 0, "Enable ARM JTAG debug" }, - { 16, 1, 1, "Disable ARM JTAG debug" }, - { 17, 1, 0, "VGA class code : vga_device" }, - { 17, 1, 1, "VGA class code : video_device" }, - { 18, 1, 0, "Enable debug interfaces 0" }, - { 18, 1, 1, "Disable debug interfaces 0" }, - { 19, 1, 0, "Boot from eMMC speed mode : normal" }, - { 19, 1, 1, "Boot from eMMC speed mode : high" }, - { 20, 1, 0, "Disable Pcie EHCI device" }, - { 20, 1, 1, "Enable Pcie EHCI device" }, - { 21, 1, 0, "Enable ARM JTAG trust world debug" }, - { 21, 1, 1, "Disable ARM JTAG trust world debug" }, - { 22, 1, 0, "Normal BMC mode" }, - { 22, 1, 1, "Disable dedicated BMC functions for non-BMC application" }, - { 23, 1, 0, "SSPRST# pin is for secondary processor dedicated reset pin" }, - { 23, 1, 1, "SSPRST# pin is for PCIE root complex dedicated reset pin" }, - { 24, 1, 0, "Enable watchdog to reset full chip" }, - { 24, 1, 1, "Disable watchdog to reset full chip" }, - { 25, 2, 0, "Internal bridge speed selection : 1x" }, - { 25, 2, 1, "Internal bridge speed selection : 1/2x" }, - { 25, 2, 2, "Internal bridge speed selection : 1/4x" }, - { 25, 2, 3, "Internal bridge speed selection : 1/8x" }, - { 29, 1, 0, "Enable RVAS function" }, - { 29, 1, 1, "Disable RVAS function" }, - { 32, 1, 0, "MAC 3 : RMII/NCSI" }, - { 32, 1, 1, "MAC 3 : RGMII" }, - { 33, 1, 0, "MAC 4 : RMII/NCSI" }, - { 33, 1, 1, "MAC 4 : RGMII" }, - { 34, 1, 0, "SuperIO configuration address : 0x2e" }, - { 34, 1, 1, "SuperIO configuration address : 0x4e" }, - { 35, 1, 0, "Enable LPC to decode SuperIO" }, - { 35, 1, 1, "Disable LPC to decode SuperIO" }, - { 36, 1, 0, "Enable debug interfaces 1" }, - { 36, 1, 1, "Disable debug interfaces 1" }, - { 37, 1, 0, "Disable ACPI function" }, - { 37, 1, 1, "Enable ACPI function" }, - { 38, 1, 0, "Select LPC/eSPI : eSPI" }, - { 38, 1, 1, "Select LPC/eSPI : LPC" }, - { 39, 1, 0, "Disable SAFS mode" }, - { 39, 1, 1, "Enable SAFS mode" }, - { 40, 1, 0, "Disable boot from uart5" }, - { 40, 1, 1, "Enable boot from uart5" }, - { 41, 1, 0, "Disable boot SPI 3B address mode auto-clear" }, - { 41, 1, 1, "Enable boot SPI 3B address mode auto-clear" }, - { 42, 1, 0, "Disable boot SPI 3B/4B address mode auto detection" }, - { 42, 1, 1, "Enable boot SPI 3B/4B address mode auto detection" }, - { 43, 1, 0, "Disable boot SPI or eMMC ABR" }, - { 43, 1, 1, "Enable boot SPI or eMMC ABR" }, - { 44, 1, 0, "Boot SPI ABR Mode : dual" }, - { 44, 1, 1, "Boot SPI ABR Mode : single" }, - { 45, 3, 0, "Boot SPI flash size : 0MB" }, - { 45, 3, 1, "Boot SPI flash size : 2MB" }, - { 45, 3, 2, "Boot SPI flash size : 4MB" }, - { 45, 3, 3, "Boot SPI flash size : 8MB" }, - { 45, 3, 4, "Boot SPI flash size : 16MB" }, - { 45, 3, 5, "Boot SPI flash size : 32MB" }, - { 45, 3, 6, "Boot SPI flash size : 64MB" }, - { 45, 3, 7, "Boot SPI flash size : 128MB" }, - { 48, 1, 0, "Disable host SPI ABR" }, - { 48, 1, 1, "Enable host SPI ABR" }, - { 49, 1, 0, "Disable host SPI ABR mode select pin" }, - { 49, 1, 1, "Enable host SPI ABR mode select pin" }, - { 50, 1, 0, "Host SPI ABR mode : dual" }, - { 50, 1, 1, "Host SPI ABR mode : single" }, - { 51, 3, 0, "Host SPI flash size : 0MB" }, - { 51, 3, 1, "Host SPI flash size : 2MB" }, - { 51, 3, 2, "Host SPI flash size : 4MB" }, - { 51, 3, 3, "Host SPI flash size : 8MB" }, - { 51, 3, 4, "Host SPI flash size : 16MB" }, - { 51, 3, 5, "Host SPI flash size : 32MB" }, - { 51, 3, 6, "Host SPI flash size : 64MB" }, - { 51, 3, 7, "Host SPI flash size : 128MB" }, - { 54, 1, 0, "Disable boot SPI auxiliary control pins" }, - { 54, 1, 1, "Enable boot SPI auxiliary control pins" }, - { 55, 2, 0, "Boot SPI CRTM size : 0KB" }, - { 55, 2, 1, "Boot SPI CRTM size : 256KB" }, - { 55, 2, 2, "Boot SPI CRTM size : 512KB" }, - { 55, 2, 3, "Boot SPI CRTM size : 1024KB" }, - { 57, 2, 0, "Host SPI CRTM size : 0KB" }, - { 57, 2, 1, "Host SPI CRTM size : 1024KB" }, - { 57, 2, 2, "Host SPI CRTM size : 2048KB" }, - { 57, 2, 3, "Host SPI CRTM size : 4096KB" }, - { 59, 1, 0, "Disable host SPI auxiliary control pins" }, - { 59, 1, 1, "Enable host SPI auxiliary control pins" }, - { 60, 1, 0, "Disable GPIO pass through" }, - { 60, 1, 1, "Enable GPIO pass through" }, - { 62, 1, 0, "Disable dedicate GPIO strap pins" }, - { 62, 1, 1, "Enable dedicate GPIO strap pins" } -}; - -static const struct otpconf_info ast1030a0_conf_info[] = { - { 0, 1, 1, 0, "Disable Secure Boot" }, - { 0, 1, 1, 1, "Enable Secure Boot" }, - { 0, 3, 1, 0, "User region ECC disable" }, - { 0, 3, 1, 1, "User region ECC enable" }, - { 0, 4, 1, 0, "Secure Region ECC disable" }, - { 0, 4, 1, 1, "Secure Region ECC enable" }, - { 0, 5, 1, 0, "Enable low security key" }, - { 0, 5, 1, 1, "Disable low security key" }, - { 0, 6, 1, 0, "Do not ignore Secure Boot hardware strap" }, - { 0, 6, 1, 1, "Ignore Secure Boot hardware strap" }, - { 0, 7, 1, 0, "Secure Boot Mode: Mode_2" }, - { 0, 7, 1, 1, "Secure Boot Mode: Mode_PFR" }, - { 0, 10, 2, 0, "RSA mode : RSA1024" }, - { 0, 10, 2, 1, "RSA mode : RSA2048" }, - { 0, 10, 2, 2, "RSA mode : RSA3072" }, - { 0, 10, 2, 3, "RSA mode : RSA4096" }, - { 0, 12, 2, 0, "SHA mode : SHA224" }, - { 0, 12, 2, 1, "SHA mode : SHA256" }, - { 0, 12, 2, 2, "SHA mode : SHA384" }, - { 0, 12, 2, 3, "SHA mode : SHA512" }, - { 0, 14, 1, 0, "Enable patch code" }, - { 0, 14, 1, 1, "Disable patch code" }, - { 0, 15, 1, 0, "Enable Boot from Uart" }, - { 0, 15, 1, 1, "Disable Boot from Uart" }, - { 0, 16, 6, OTP_REG_VALUE, "Secure Region size (DW): 0x%x" }, - { 0, 22, 1, 0, "Secure Region : Writable" }, - { 0, 22, 1, 1, "Secure Region : Write Protect" }, - { 0, 23, 1, 0, "User Region : Writable" }, - { 0, 23, 1, 1, "User Region : Write Protect" }, - { 0, 24, 1, 0, "Configure Region : Writable" }, - { 0, 24, 1, 1, "Configure Region : Write Protect" }, - { 0, 25, 1, 0, "OTP strap Region : Writable" }, - { 0, 25, 1, 1, "OTP strap Region : Write Protect" }, - { 0, 26, 1, 0, "Copy Boot Image to Internal SRAM" }, - { 0, 26, 1, 1, "Disable Copy Boot Image to Internal SRAM" }, - { 0, 27, 1, 0, "Disable image encryption" }, - { 0, 27, 1, 1, "Enable image encryption" }, - { 0, 29, 1, 0, "OTP key retire Region : Writable" }, - { 0, 29, 1, 1, "OTP key retire Region : Write Protect" }, - { 0, 31, 1, 0, "OTP memory lock disable" }, - { 0, 31, 1, 1, "OTP memory lock enable" }, - { 2, 0, 16, OTP_REG_VALUE, "Vender ID : 0x%x" }, - { 2, 16, 16, OTP_REG_VALUE, "Key Revision : 0x%x" }, - { 3, 0, 16, OTP_REG_VALUE, "Secure boot header offset : 0x%x" }, - { 4, 0, 8, OTP_REG_VALID_BIT, "Keys retire : %s" }, - { 5, 0, 32, OTP_REG_VALUE, "User define data, random number low : 0x%x" }, - { 6, 0, 32, OTP_REG_VALUE, "User define data, random number high : 0x%x" }, - { 14, 0, 11, OTP_REG_VALUE, "Patch code location (DW): 0x%x" }, - { 14, 11, 6, OTP_REG_VALUE, "Patch code size (DW): 0x%x" } -}; - -static const struct otpconf_info ast1030a1_conf_info[] = { - { 0, 1, 1, 0, "Disable Secure Boot" }, - { 0, 1, 1, 1, "Enable Secure Boot" }, - { 0, 3, 1, 0, "User region ECC disable" }, - { 0, 3, 1, 1, "User region ECC enable" }, - { 0, 4, 1, 0, "Secure Region ECC disable" }, - { 0, 4, 1, 1, "Secure Region ECC enable" }, - { 0, 5, 1, 0, "Enable low security key" }, - { 0, 5, 1, 1, "Disable low security key" }, - { 0, 6, 1, 0, "Do not ignore Secure Boot hardware strap" }, - { 0, 6, 1, 1, "Ignore Secure Boot hardware strap" }, - { 0, 7, 1, 0, "Secure Boot Mode: Normal" }, - { 0, 7, 1, 1, "Secure Boot Mode: Mode_PFR" }, - { 0, 10, 4, 0, "Signature Scheme : ECDSA384" }, - { 0, 10, 4, 1, "Signature Scheme : ECDSA384_RSA2048" }, - { 0, 10, 4, 2, "Signature Scheme : ECDSA384_RSA3072" }, - { 0, 10, 4, 3, "Signature Scheme : ECDSA384_RSA4096" }, - { 0, 10, 4, 4, "Signature Scheme : RSAPSS_2048_SHA256" }, - { 0, 10, 4, 8, "Signature Scheme : RSAPSS_3072_SHA384" }, - { 0, 10, 4, 12, "Signature Scheme : RSAPSS_4096_SHA512" }, - { 0, 10, 4, 5, "Signature Scheme : RSAPKCS1_2048_SHA256" }, - { 0, 10, 4, 10, "Signature Scheme : RSAPKCS1_3072_SHA384" }, - { 0, 10, 4, 15, "Signature Scheme : RSAPKCS1_4096_SHA512" }, - { 0, 14, 1, 0, "Enable patch code" }, - { 0, 14, 1, 1, "Disable patch code" }, - { 0, 15, 1, 0, "Enable Boot from Uart" }, - { 0, 15, 1, 1, "Disable Boot from Uart" }, - { 0, 16, 6, OTP_REG_VALUE, "Secure Region size (DW): 0x%x" }, - { 0, 22, 1, 0, "Secure Region : Writable" }, - { 0, 22, 1, 1, "Secure Region : Write Protect" }, - { 0, 23, 1, 0, "User Region : Writable" }, - { 0, 23, 1, 1, "User Region : Write Protect" }, - { 0, 24, 1, 0, "Configure Region : Writable" }, - { 0, 24, 1, 1, "Configure Region : Write Protect" }, - { 0, 25, 1, 0, "OTP strap Region : Writable" }, - { 0, 25, 1, 1, "OTP strap Region : Write Protect" }, - { 0, 26, 1, 0, "Copy Boot Image to Internal SRAM" }, - { 0, 26, 1, 1, "Disable Copy Boot Image to Internal SRAM" }, - { 0, 27, 1, 0, "Disable image encryption" }, - { 0, 27, 1, 1, "Enable image encryption" }, - { 0, 29, 1, 0, "OTP key retire Region : Writable" }, - { 0, 29, 1, 1, "OTP key retire Region : Write Protect" }, - { 0, 31, 1, 0, "OTP memory lock disable" }, - { 0, 31, 1, 1, "OTP memory lock enable" }, - { 2, 0, 16, OTP_REG_VALUE, "Vender ID : 0x%x" }, - { 2, 16, 16, OTP_REG_VALUE, "Key Revision : 0x%x" }, - { 3, 0, 16, OTP_REG_VALUE, "Secure boot header offset : 0x%x" }, - { 4, 0, 8, OTP_REG_VALID_BIT, "Keys retire : %s" }, - { 5, 0, 32, OTP_REG_VALUE, "User define data, random number low : 0x%x" }, - { 6, 0, 32, OTP_REG_VALUE, "User define data, random number high : 0x%x" }, - { 14, 0, 11, OTP_REG_VALUE, "Patch code location (DW): 0x%x" }, - { 14, 11, 6, OTP_REG_VALUE, "Patch code size (DW): 0x%x" } -}; - diff --git a/lib/hrot_hal/spi_filter/spi_filter_aspeed.h b/lib/hrot_hal/spi_filter/spi_filter_aspeed.h deleted file mode 100644 index 099bec3..0000000 --- a/lib/hrot_hal/spi_filter/spi_filter_aspeed.h +++ /dev/null @@ -1,16 +0,0 @@ -/* - * Copyright (c) 2022 ASPEED Technology Inc. - * - * SPDX-License-Identifier: MIT - */ - -#pragma once - -#include -#include -#include -#include - -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); - diff --git a/lib/hrot_hal/watchdog/watchdog_aspeed.c b/lib/hrot_hal/watchdog/watchdog_aspeed.c deleted file mode 100644 index 636c21e..0000000 --- a/lib/hrot_hal/watchdog/watchdog_aspeed.c +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (c) 2022 ASPEED Technology Inc. - * - * SPDX-License-Identifier: MIT - */ - -#include -#include -#include -#include -#include "watchdog_aspeed.h" - -LOG_MODULE_REGISTER(hal_watchdog, CONFIG_LOG_DEFAULT_LEVEL); - -/** - * Initial watchdog timer and configure timeout configuration. - * - * @param dev Pointer to the device structure for the driver instance, the possible value is wdt1/wdt2/wdt3/wdt4 . - * @param wdt_cfg Watchdog timeout configuration struct , refer to drivers/watchdog.h . - * @param reset_option Configuration options , the possible value is WDT_FLAG_RESET_NONE/WDT_FLAG_RESET_CPU_CORE/WDT_FLAG_RESET_SOC, refer to drivers/watchdog.h . - * - * - * @retval 0 if successfully or an error code. - * - */ -int watchdog_init(const struct device *dev, struct watchdog_config *wdt_config) -{ - int ret = 0; - struct wdt_timeout_cfg init_wdt_cfg; - - init_wdt_cfg.window.min = wdt_config->wdt_cfg.window.min; - init_wdt_cfg.window.max = wdt_config->wdt_cfg.window.max; - init_wdt_cfg.callback = wdt_config->wdt_cfg.callback; - ret = wdt_install_timeout(dev, &init_wdt_cfg); - if (ret != 0) { - LOG_ERR("%s error: fail to install dev timeout", __func__); - return ret; - } - - ret = wdt_setup(dev, wdt_config->reset_option); - if (ret != 0) { - LOG_ERR("%s error: fail to setup dev timeout", __func__); - return ret; - } - - return ret; -} - -/** - * Feed specified watchdog timeout. - * - * @param dev Pointer to the device structure for the driver instance. the possible value is wdt1/wdt2/wdt3/wdt4 . - * @param channel_id Index of the fed channel. - * - * @retval 0 If successful or an error code. - */ -int watchdog_feed(const struct device *dev, int channel_id) -{ - int ret = 0; - - ret = wdt_feed(dev, channel_id); - return ret; -} - -/** - * Disable watchdog instance. - * - * - * @param dev Pointer to the device structure for the driver instance, the possible value is wdt1/wdt2/wdt3/wdt4 . - * - * @retval 0 If successful or an error code. - * - */ -int watchdog_disable(const struct device *dev) -{ - int ret = 0; - - ret = wdt_disable(dev); - return ret; -} - diff --git a/lib/hrot_hal/watchdog/watchdog_aspeed.h b/lib/hrot_hal/watchdog/watchdog_aspeed.h deleted file mode 100644 index e6dc5c4..0000000 --- a/lib/hrot_hal/watchdog/watchdog_aspeed.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (c) 2022 ASPEED Technology Inc. - * - * SPDX-License-Identifier: MIT - */ - -#pragma once - -#include -#include -#include - -struct watchdog_config { - struct wdt_timeout_cfg wdt_cfg; - uint8_t reset_option; // WDT_FLAG_RESET_NONE , WDT_FLAG_RESET_CPU_CORE , WDT_FLAG_RESET_SOC -}; - -/** - * Initial watchdog timer and configure timeout configuration. - * - * @param dev Pointer to the device structure for the driver instance, the possible value is wdt1/wdt2/wdt3/wdt4 . - * @param wdt_cfg Watchdog timeout configuration struct , refer to drivers/watchdog.h . - * @param reset_option Configuration options, the possible value is WDT_FLAG_RESET_NONE/WDT_FLAG_RESET_CPU_CORE/WDT_FLAG_RESET_SOC, refer to drivers/watchdog.h . - * - * @retval 0 if successfully or an error code. - * - */ -int watchdog_init(const struct device *dev, struct watchdog_config *wdt_cfg); - -/** - * Feed specified watchdog timeout. - * - * @param dev Pointer to the device structure for the driver instance. the possible value is wdt1/wdt2/wdt3/wdt4 . - * @param channel_id Index of the fed channel. - * - * @retval 0 If successful or an error code. - */ -int watchdog_feed(const struct device *dev, int channel_id); - -/** - * Disable watchdog instance. - * - * @param dev Pointer to the device structure for the driver instance, the possible value is wdt1/wdt2/wdt3/wdt4 . - * - * @retval 0 If successful or an error code. - * - */ -int watchdog_disable(const struct device *dev); - diff --git a/lib/hrot_wrapper/crypto/signature_verification_rsa_wrapper.c b/lib/hrot_wrapper/crypto/signature_verification_rsa_wrapper.c deleted file mode 100644 index 0402c13..0000000 --- a/lib/hrot_wrapper/crypto/signature_verification_rsa_wrapper.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2022 ASPEED Technology Inc. - * - * SPDX-License-Identifier: MIT - */ - -#include -#include -#include -#include "signature_verification_rsa_wrapper.h" - - -static int signature_verification_rsa_verify_signature(struct signature_verification *verification, - const uint8_t *digest, size_t length, const uint8_t *signature, size_t sig_length) -{ - struct signature_verification_rsa_wrapper *rsa = (struct signature_verification_rsa_wrapper *) verification; - - if (rsa == NULL) { - return SIG_VERIFICATION_INVALID_ARGUMENT; - } - - return rsa->rsa->sig_verify(rsa->rsa, rsa->key, signature, sig_length, HASH_TYPE_SHA256, digest, length); -} - -/** - * Initialize signature verification with an RSA public key. - * - * @param verification The verification instance to initialize. - * @param rsa The RSA engine to use for verification. - * @param key The RSA public key for the signatures to verify. - * - * @return 0 if the verification instance was successfully initialized or an error code. - */ -int signature_verification_rsa_wrapper_init(struct signature_verification_rsa_wrapper *verification, - struct rsa_engine *rsa, const struct rsa_public_key *key) -{ - if ((verification == NULL) || (rsa == NULL) || (key == NULL)) { - return SIG_VERIFICATION_INVALID_ARGUMENT; - } - memset(verification, 0, sizeof(struct signature_verification)); - - verification->rsa = rsa; - verification->key = key; - - verification->base.verify_signature = signature_verification_rsa_verify_signature; - - return 0; -} - -/** - * Release the resources used for RSA signature verification. - * - * @param verification The verification instance to release. - */ -void signature_verification_rsa_wrapper_release(struct signature_verification_rsa_wrapper *verification) -{ - -} diff --git a/lib/hrot_wrapper/crypto/signature_verification_rsa_wrapper.h b/lib/hrot_wrapper/crypto/signature_verification_rsa_wrapper.h deleted file mode 100644 index ef05ed5..0000000 --- a/lib/hrot_wrapper/crypto/signature_verification_rsa_wrapper.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (c) 2022 ASPEED Technology Inc. - * - * SPDX-License-Identifier: MIT - */ - -#pragma once - -#include "crypto/signature_verification.h" -#include "crypto/rsa.h" - - -/** - * Verification implementation to verify RSA signatures. - */ -struct signature_verification_rsa_wrapper { - struct signature_verification base; /**< Base verification instance. */ - struct rsa_engine *rsa; /**< RSA engine to use for verification. */ - const struct rsa_public_key *key; /**< Public key for signature verification. */ -}; - - -int signature_verification_rsa_wrapper_init(struct signature_verification_rsa_wrapper *verification, - struct rsa_engine *rsa, const struct rsa_public_key *key); -void signature_verification_rsa_wrapper_release(struct signature_verification_rsa_wrapper *verification); - diff --git a/lib/hrot_wrapper/flash/flash_wrapper.c b/lib/hrot_wrapper/flash/flash_wrapper.c index b974996..39c0d7c 100644 --- a/lib/hrot_wrapper/flash/flash_wrapper.c +++ b/lib/hrot_wrapper/flash/flash_wrapper.c @@ -28,7 +28,7 @@ */ int Wrapper_spi_flash_get_device_size(struct spi_flash *flash, uint32_t *bytes) { - struct flash_xfer xfer; + struct flash_xfer xfer = {0}; if ((flash == NULL) || (bytes == NULL)) { return SPI_FLASH_INVALID_ARGUMENT; @@ -206,7 +206,7 @@ int Wrapper_spi_flash_write(struct spi_flash *flash, uint32_t address, const uin */ int Wrapper_spi_flash_get_sector_size(struct spi_flash *flash, uint32_t *bytes) { - struct flash_xfer xfer; + struct flash_xfer xfer = {0}; if ((flash == NULL) || (bytes == NULL)) { return SPI_FLASH_INVALID_ARGUMENT; @@ -231,13 +231,15 @@ int Wrapper_spi_flash_get_sector_size(struct spi_flash *flash, uint32_t *bytes) */ int Wrapper_spi_flash_sector_erase(struct spi_flash *flash, uint32_t sector_addr) { - struct flash_xfer xfer; + struct flash_xfer xfer = {0}; int status = 0; if (flash == NULL) { return SPI_FLASH_INVALID_ARGUMENT; } xfer.cmd = MIDLEY_FLASH_CMD_4K_ERASE; + xfer.address = sector_addr; + xfer.length = SECTOR_SIZE; status = SPI_Command_Xfer(flash, &xfer); @@ -254,7 +256,7 @@ int Wrapper_spi_flash_sector_erase(struct spi_flash *flash, uint32_t sector_addr */ int Wrapper_spi_flash_get_block_size(struct spi_flash *flash, uint32_t *bytes) { - struct flash_xfer xfer; + struct flash_xfer xfer = {0}; if ((flash == NULL) || (bytes == NULL)) { return SPI_FLASH_INVALID_ARGUMENT; @@ -277,13 +279,15 @@ int Wrapper_spi_flash_get_block_size(struct spi_flash *flash, uint32_t *bytes) */ int Wrapper_spi_flash_block_erase(struct spi_flash *flash, uint32_t block_addr) { - struct flash_xfer xfer; + struct flash_xfer xfer = {0}; int status = 0; if (flash == NULL) { return SPI_FLASH_INVALID_ARGUMENT; } xfer.cmd = MIDLEY_FLASH_CMD_BLOCK_ERASE; + xfer.address = block_addr; + xfer.length = BLOCK_SIZE; status = SPI_Command_Xfer(flash, &xfer); @@ -300,15 +304,17 @@ int Wrapper_spi_flash_block_erase(struct spi_flash *flash, uint32_t block_addr) */ int Wrapper_spi_flash_chip_erase(struct spi_flash *flash) { - struct flash_xfer xfer; + struct flash_xfer xfer = {0}; int status = 0; - xfer.cmd = MIDLEY_FLASH_CMD_READ; + if (flash == NULL) { + return SPI_FLASH_INVALID_ARGUMENT; + } + xfer.cmd = MIDLEY_FLASH_CMD_CE; status = SPI_Command_Xfer(flash, &xfer); return status; - } int flash_wrapper_init(struct spi_engine_wrapper *flash, struct flash_master_wrapper *spi, struct spi_engine_state_wrapper *flash_state) diff --git a/lib/hrot_wrapper/logging/logging_wrapper.c b/lib/hrot_wrapper/logging/logging_wrapper.c index 2a9246f..6398cba 100644 --- a/lib/hrot_wrapper/logging/logging_wrapper.c +++ b/lib/hrot_wrapper/logging/logging_wrapper.c @@ -18,7 +18,7 @@ static int logging_memory_wrapper_init(struct logging_memory_wrapper *logging_wr debug_log = &logging_wrapper->logging.base; logging_wrapper->logging.state = &logging_wrapper->state; - status = logging_memory_init((struct logging_memory *)debug_log, &logging_wrapper->state, + status = logging_memory_init(&logging_wrapper->logging, &logging_wrapper->state, LOGGING_ENTRY_COUNT, LOGGING_ENTRY_LENGTH); if (status != 0) { LOG_ERR("logging memory init failed(%x)", status); diff --git a/lib/hrot_wrapper/spi_filter/spi_filter_wrapper.c b/lib/hrot_wrapper/spi_filter/spi_filter_wrapper.c deleted file mode 100644 index 35652cc..0000000 --- a/lib/hrot_wrapper/spi_filter/spi_filter_wrapper.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2022 ASPEED Technology Inc. - * - * SPDX-License-Identifier: MIT - */ - -#include -#include - -#define SPIM_NUM 4 - -static char *spim_devs[SPIM_NUM] = { - "spim@1", - "spim@2", - "spim@3", - "spim@4" -}; - -int Wrapper_spi_filter_enable(struct spi_filter_interface *spi_filter, bool enable) -{ - struct spi_filter_engine_wrapper *spi_filter_wrapper = - (struct spi_filter_engine_wrapper*) spi_filter; - - SPI_Monitor_Enable(spim_devs[spi_filter_wrapper->dev_id], enable); - - return 0; -} - -int Wrapper_spi_filter_rw_region(struct spi_filter_interface *spi_filter, uint8_t region, uint32_t start_addr, uint32_t end_addr) -{ - int ret = 0; - struct spi_filter_engine_wrapper *spi_filter_wrapper = (struct spi_filter_engine_wrapper *) spi_filter; - - uint32_t length = end_addr - start_addr; - - ret = Set_SPI_Filter_RW_Region(spim_devs[spi_filter_wrapper->dev_id], SPI_FILTER_WRITE_PRIV, SPI_FILTER_PRIV_ENABLE, start_addr, length); - - return ret; -} - - -int spi_filter_wrapper_init(struct spi_filter_engine_wrapper *spi_filter) -{ - if (spi_filter == NULL) { - return SPI_FILTER_INVALID_ARGUMENT; - } - - memset(spi_filter, 0, sizeof(struct spi_filter_engine_wrapper)); - - spi_filter->base.enable_filter = (int (*)(struct spi_filter_interface *, bool))Wrapper_spi_filter_enable; - spi_filter->base.set_filter_rw_region = (int (*)(struct spi_filter_interface *, uint8_t, uint32_t, uint32_t))Wrapper_spi_filter_rw_region; - - return 0; -} diff --git a/lib/hrot_wrapper/spi_filter/spi_filter_wrapper.h b/lib/hrot_wrapper/spi_filter/spi_filter_wrapper.h deleted file mode 100644 index 8405e6b..0000000 --- a/lib/hrot_wrapper/spi_filter/spi_filter_wrapper.h +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2022 ASPEED Technology Inc. - * - * SPDX-License-Identifier: MIT - */ - -#pragma once - -#include "spi_filter/spi_filter_interface.h" -#include "spi_filter/spi_filter_aspeed.h" - -#define SPI_FILTER_READ_PRIV 0 -#define SPI_FILTER_WRITE_PRIV 1 - -#define SPI_FILTER_PRIV_ENABLE 0 -#define SPI_FILTER_PRIV_DISABLE 1 - -struct spi_filter_engine_wrapper{ - struct spi_filter_interface base; - int dev_id; -}; - -int spi_filter_wrapper_init (struct spi_filter_engine_wrapper *spi_filter); diff --git a/lib/lms/CMakeLists.txt b/lib/lms/CMakeLists.txt index 8bc4698..70930fb 100644 --- a/lib/lms/CMakeLists.txt +++ b/lib/lms/CMakeLists.txt @@ -1,13 +1,15 @@ # SPDX-License-Identifier: Apache-2.0 -zephyr_interface_library_named(lms) +if (MBEDTLS_LMS_C) + zephyr_interface_library_named(lms) -target_include_directories(lms INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) + target_include_directories(lms INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}) -target_include_directories(lms INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/../../modules/crypto/mbedtls/include/) + target_include_directories(lms INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}/../../modules/crypto/mbedtls/include/) -zephyr_library(lms) + zephyr_library(lms) -zephyr_library_sources(lmots.c lms.c psa_util.c lms_shell.c) + zephyr_library_sources(lmots.c lms.c psa_util.c lms_shell.c) -zephyr_library_link_libraries(lms) + zephyr_library_link_libraries(lms) +endif() diff --git a/west.yml b/west.yml index b35de9b..bdc4af3 100644 --- a/west.yml +++ b/west.yml @@ -12,7 +12,7 @@ manifest: projects: - name: zephyr remote: github - revision: 1e4df2976ce294ca07ebcb48f9a0e34c9c7fb85a + revision: f947f6980189946957c03961d58bfa5049737cee import: name-whitelist: - mcumgr @@ -21,9 +21,9 @@ manifest: - mbedtls - name: cerberus remote: github - revision: 51e55fa2c73f91a81629cefd081e049b5518d2f1 + revision: 2da20db7d1887db023fe3188bd69dcb8e807af12 path: middlewares/cerberus - name: mcuboot remote: github - revision: a844bb3089999c37f2f89873a6c493b1b0dfbd7a + revision: ce9bdf834557ee71b3ba87c32a16990f306ee8ee path: bootloader/mcuboot