Commit 0d6d8807793e74402e23772062469aeb4808dd48
1 parent
87a19df5e4
Exists in
smarc_8mm-imx_v2018.03_4.14.98_2.0.0_ga
and in
4 other branches
MA-14629 fix build warnings for varialbe initialization and type cast
initialize potential uninitialized variable with the type of"char*" to be NULL in AVB. That "hashtree_error_mode" in code is manually specified with a known value, the cases listed cover all potential value of "hashtree_error_mode" explicitly do a type cast for memcpy parameters. Change-Id: Ie5d234422a273d6dab75585bd0d8eb81583707ca Signed-off-by: faqiang.zhu <faqiang.zhu@nxp.com>
Showing 2 changed files with 3 additions and 3 deletions Inline Diff
board/freescale/imx8qm_mek/imx8qm_mek.c
1 | /* | 1 | /* |
2 | * Copyright 2017-2018 NXP | 2 | * Copyright 2017-2018 NXP |
3 | * | 3 | * |
4 | * SPDX-License-Identifier: GPL-2.0+ | 4 | * SPDX-License-Identifier: GPL-2.0+ |
5 | */ | 5 | */ |
6 | #include <common.h> | 6 | #include <common.h> |
7 | #include <malloc.h> | 7 | #include <malloc.h> |
8 | #include <errno.h> | 8 | #include <errno.h> |
9 | #include <netdev.h> | 9 | #include <netdev.h> |
10 | #include <fsl_ifc.h> | 10 | #include <fsl_ifc.h> |
11 | #include <fdt_support.h> | 11 | #include <fdt_support.h> |
12 | #include <linux/libfdt.h> | 12 | #include <linux/libfdt.h> |
13 | #include <environment.h> | 13 | #include <environment.h> |
14 | #include <fsl_esdhc.h> | 14 | #include <fsl_esdhc.h> |
15 | #include <i2c.h> | 15 | #include <i2c.h> |
16 | 16 | ||
17 | #include <asm/io.h> | 17 | #include <asm/io.h> |
18 | #include <asm/gpio.h> | 18 | #include <asm/gpio.h> |
19 | #include <asm/arch/clock.h> | 19 | #include <asm/arch/clock.h> |
20 | #include <asm/mach-imx/sci/sci.h> | 20 | #include <asm/mach-imx/sci/sci.h> |
21 | #include <asm/arch/imx8-pins.h> | 21 | #include <asm/arch/imx8-pins.h> |
22 | #include <dm.h> | 22 | #include <dm.h> |
23 | #include <imx8_hsio.h> | 23 | #include <imx8_hsio.h> |
24 | #include <usb.h> | 24 | #include <usb.h> |
25 | #include <asm/arch/iomux.h> | 25 | #include <asm/arch/iomux.h> |
26 | #include <asm/arch/sys_proto.h> | 26 | #include <asm/arch/sys_proto.h> |
27 | #include <asm/mach-imx/video.h> | 27 | #include <asm/mach-imx/video.h> |
28 | #include <asm/arch/video_common.h> | 28 | #include <asm/arch/video_common.h> |
29 | #include <power-domain.h> | 29 | #include <power-domain.h> |
30 | #include "../common/tcpc.h" | 30 | #include "../common/tcpc.h" |
31 | #include <cdns3-uboot.h> | 31 | #include <cdns3-uboot.h> |
32 | #include <asm/arch/lpcg.h> | 32 | #include <asm/arch/lpcg.h> |
33 | 33 | ||
34 | DECLARE_GLOBAL_DATA_PTR; | 34 | DECLARE_GLOBAL_DATA_PTR; |
35 | 35 | ||
36 | #define ENET_INPUT_PAD_CTRL ((SC_PAD_CONFIG_OD_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 36 | #define ENET_INPUT_PAD_CTRL ((SC_PAD_CONFIG_OD_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
37 | | (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 37 | | (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
38 | 38 | ||
39 | #define ENET_NORMAL_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 39 | #define ENET_NORMAL_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
40 | | (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 40 | | (SC_PAD_28FDSOI_DSE_18V_10MA << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
41 | 41 | ||
42 | #define FSPI_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 42 | #define FSPI_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
43 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 43 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
44 | 44 | ||
45 | #define GPIO_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 45 | #define GPIO_PAD_CTRL ((SC_PAD_CONFIG_NORMAL << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
46 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 46 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
47 | 47 | ||
48 | #define I2C_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 48 | #define I2C_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
49 | | (SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 49 | | (SC_PAD_28FDSOI_DSE_DV_LOW << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
50 | 50 | ||
51 | #define UART_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ | 51 | #define UART_PAD_CTRL ((SC_PAD_CONFIG_OUT_IN << PADRING_CONFIG_SHIFT) | (SC_PAD_ISO_OFF << PADRING_LPCONFIG_SHIFT) \ |
52 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) | 52 | | (SC_PAD_28FDSOI_DSE_DV_HIGH << PADRING_DSE_SHIFT) | (SC_PAD_28FDSOI_PS_PU << PADRING_PULL_SHIFT)) |
53 | 53 | ||
54 | static iomux_cfg_t uart0_pads[] = { | 54 | static iomux_cfg_t uart0_pads[] = { |
55 | SC_P_UART0_RX | MUX_PAD_CTRL(UART_PAD_CTRL), | 55 | SC_P_UART0_RX | MUX_PAD_CTRL(UART_PAD_CTRL), |
56 | SC_P_UART0_TX | MUX_PAD_CTRL(UART_PAD_CTRL), | 56 | SC_P_UART0_TX | MUX_PAD_CTRL(UART_PAD_CTRL), |
57 | }; | 57 | }; |
58 | 58 | ||
59 | static void setup_iomux_uart(void) | 59 | static void setup_iomux_uart(void) |
60 | { | 60 | { |
61 | imx8_iomux_setup_multiple_pads(uart0_pads, ARRAY_SIZE(uart0_pads)); | 61 | imx8_iomux_setup_multiple_pads(uart0_pads, ARRAY_SIZE(uart0_pads)); |
62 | } | 62 | } |
63 | 63 | ||
64 | int board_early_init_f(void) | 64 | int board_early_init_f(void) |
65 | { | 65 | { |
66 | sc_ipc_t ipcHndl = 0; | 66 | sc_ipc_t ipcHndl = 0; |
67 | sc_err_t sciErr = 0; | 67 | sc_err_t sciErr = 0; |
68 | 68 | ||
69 | /* When start u-boot in XEN VM, directly return */ | 69 | /* When start u-boot in XEN VM, directly return */ |
70 | if (IS_ENABLED(CONFIG_XEN)) { | 70 | if (IS_ENABLED(CONFIG_XEN)) { |
71 | writel(0xF53535F5, (void __iomem *)0x80000000); | 71 | writel(0xF53535F5, (void __iomem *)0x80000000); |
72 | return 0; | 72 | return 0; |
73 | } | 73 | } |
74 | 74 | ||
75 | ipcHndl = gd->arch.ipc_channel_handle; | 75 | ipcHndl = gd->arch.ipc_channel_handle; |
76 | 76 | ||
77 | /* Power up UART0, this is very early while power domain is not working */ | 77 | /* Power up UART0, this is very early while power domain is not working */ |
78 | sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_UART_0, SC_PM_PW_MODE_ON); | 78 | sciErr = sc_pm_set_resource_power_mode(ipcHndl, SC_R_UART_0, SC_PM_PW_MODE_ON); |
79 | if (sciErr != SC_ERR_NONE) | 79 | if (sciErr != SC_ERR_NONE) |
80 | return 0; | 80 | return 0; |
81 | 81 | ||
82 | /* Set UART0 clock root to 80 MHz */ | 82 | /* Set UART0 clock root to 80 MHz */ |
83 | sc_pm_clock_rate_t rate = 80000000; | 83 | sc_pm_clock_rate_t rate = 80000000; |
84 | sciErr = sc_pm_set_clock_rate(ipcHndl, SC_R_UART_0, 2, &rate); | 84 | sciErr = sc_pm_set_clock_rate(ipcHndl, SC_R_UART_0, 2, &rate); |
85 | if (sciErr != SC_ERR_NONE) | 85 | if (sciErr != SC_ERR_NONE) |
86 | return 0; | 86 | return 0; |
87 | 87 | ||
88 | /* Enable UART0 clock root */ | 88 | /* Enable UART0 clock root */ |
89 | sciErr = sc_pm_clock_enable(ipcHndl, SC_R_UART_0, 2, true, false); | 89 | sciErr = sc_pm_clock_enable(ipcHndl, SC_R_UART_0, 2, true, false); |
90 | if (sciErr != SC_ERR_NONE) | 90 | if (sciErr != SC_ERR_NONE) |
91 | return 0; | 91 | return 0; |
92 | 92 | ||
93 | LPCG_AllClockOn(LPUART_0_LPCG); | 93 | LPCG_AllClockOn(LPUART_0_LPCG); |
94 | 94 | ||
95 | setup_iomux_uart(); | 95 | setup_iomux_uart(); |
96 | 96 | ||
97 | return 0; | 97 | return 0; |
98 | } | 98 | } |
99 | 99 | ||
100 | #ifdef CONFIG_FEC_MXC | 100 | #ifdef CONFIG_FEC_MXC |
101 | #include <miiphy.h> | 101 | #include <miiphy.h> |
102 | 102 | ||
103 | static iomux_cfg_t pad_enet1[] = { | 103 | static iomux_cfg_t pad_enet1[] = { |
104 | SC_P_ENET1_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 104 | SC_P_ENET1_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
105 | SC_P_ENET1_RGMII_RXD0 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 105 | SC_P_ENET1_RGMII_RXD0 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
106 | SC_P_ENET1_RGMII_RXD1 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 106 | SC_P_ENET1_RGMII_RXD1 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
107 | SC_P_ENET1_RGMII_RXD2 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 107 | SC_P_ENET1_RGMII_RXD2 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
108 | SC_P_ENET1_RGMII_RXD3 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 108 | SC_P_ENET1_RGMII_RXD3 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
109 | SC_P_ENET1_RGMII_RXC | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 109 | SC_P_ENET1_RGMII_RXC | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
110 | SC_P_ENET1_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 110 | SC_P_ENET1_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
111 | SC_P_ENET1_RGMII_TXD0 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 111 | SC_P_ENET1_RGMII_TXD0 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
112 | SC_P_ENET1_RGMII_TXD1 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 112 | SC_P_ENET1_RGMII_TXD1 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
113 | SC_P_ENET1_RGMII_TXD2 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 113 | SC_P_ENET1_RGMII_TXD2 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
114 | SC_P_ENET1_RGMII_TXD3 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 114 | SC_P_ENET1_RGMII_TXD3 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
115 | SC_P_ENET1_RGMII_TXC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 115 | SC_P_ENET1_RGMII_TXC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
116 | 116 | ||
117 | /* Shared MDIO */ | 117 | /* Shared MDIO */ |
118 | SC_P_ENET0_MDC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 118 | SC_P_ENET0_MDC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
119 | SC_P_ENET0_MDIO | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 119 | SC_P_ENET0_MDIO | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
120 | }; | 120 | }; |
121 | 121 | ||
122 | static iomux_cfg_t pad_enet0[] = { | 122 | static iomux_cfg_t pad_enet0[] = { |
123 | SC_P_ENET0_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 123 | SC_P_ENET0_RGMII_RX_CTL | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
124 | SC_P_ENET0_RGMII_RXD0 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 124 | SC_P_ENET0_RGMII_RXD0 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
125 | SC_P_ENET0_RGMII_RXD1 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 125 | SC_P_ENET0_RGMII_RXD1 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
126 | SC_P_ENET0_RGMII_RXD2 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 126 | SC_P_ENET0_RGMII_RXD2 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
127 | SC_P_ENET0_RGMII_RXD3 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 127 | SC_P_ENET0_RGMII_RXD3 | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
128 | SC_P_ENET0_RGMII_RXC | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), | 128 | SC_P_ENET0_RGMII_RXC | MUX_PAD_CTRL(ENET_INPUT_PAD_CTRL), |
129 | SC_P_ENET0_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 129 | SC_P_ENET0_RGMII_TX_CTL | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
130 | SC_P_ENET0_RGMII_TXD0 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 130 | SC_P_ENET0_RGMII_TXD0 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
131 | SC_P_ENET0_RGMII_TXD1 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 131 | SC_P_ENET0_RGMII_TXD1 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
132 | SC_P_ENET0_RGMII_TXD2 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 132 | SC_P_ENET0_RGMII_TXD2 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
133 | SC_P_ENET0_RGMII_TXD3 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 133 | SC_P_ENET0_RGMII_TXD3 | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
134 | SC_P_ENET0_RGMII_TXC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 134 | SC_P_ENET0_RGMII_TXC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
135 | 135 | ||
136 | /* Shared MDIO */ | 136 | /* Shared MDIO */ |
137 | SC_P_ENET0_MDC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 137 | SC_P_ENET0_MDC | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
138 | SC_P_ENET0_MDIO | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), | 138 | SC_P_ENET0_MDIO | MUX_PAD_CTRL(ENET_NORMAL_PAD_CTRL), |
139 | }; | 139 | }; |
140 | 140 | ||
141 | static void setup_iomux_fec(void) | 141 | static void setup_iomux_fec(void) |
142 | { | 142 | { |
143 | if (0 == CONFIG_FEC_ENET_DEV) | 143 | if (0 == CONFIG_FEC_ENET_DEV) |
144 | imx8_iomux_setup_multiple_pads(pad_enet0, ARRAY_SIZE(pad_enet0)); | 144 | imx8_iomux_setup_multiple_pads(pad_enet0, ARRAY_SIZE(pad_enet0)); |
145 | else | 145 | else |
146 | imx8_iomux_setup_multiple_pads(pad_enet1, ARRAY_SIZE(pad_enet1)); | 146 | imx8_iomux_setup_multiple_pads(pad_enet1, ARRAY_SIZE(pad_enet1)); |
147 | } | 147 | } |
148 | 148 | ||
149 | int board_eth_init(bd_t *bis) | 149 | int board_eth_init(bd_t *bis) |
150 | { | 150 | { |
151 | int ret; | 151 | int ret; |
152 | struct power_domain pd; | 152 | struct power_domain pd; |
153 | 153 | ||
154 | printf("[%s] %d\n", __func__, __LINE__); | 154 | printf("[%s] %d\n", __func__, __LINE__); |
155 | 155 | ||
156 | if (CONFIG_FEC_ENET_DEV) { | 156 | if (CONFIG_FEC_ENET_DEV) { |
157 | if (!power_domain_lookup_name("conn_enet1", &pd)) | 157 | if (!power_domain_lookup_name("conn_enet1", &pd)) |
158 | power_domain_on(&pd); | 158 | power_domain_on(&pd); |
159 | } else { | 159 | } else { |
160 | if (!power_domain_lookup_name("conn_enet0", &pd)) | 160 | if (!power_domain_lookup_name("conn_enet0", &pd)) |
161 | power_domain_on(&pd); | 161 | power_domain_on(&pd); |
162 | } | 162 | } |
163 | 163 | ||
164 | setup_iomux_fec(); | 164 | setup_iomux_fec(); |
165 | 165 | ||
166 | ret = fecmxc_initialize_multi(bis, CONFIG_FEC_ENET_DEV, | 166 | ret = fecmxc_initialize_multi(bis, CONFIG_FEC_ENET_DEV, |
167 | CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE); | 167 | CONFIG_FEC_MXC_PHYADDR, IMX_FEC_BASE); |
168 | if (ret) | 168 | if (ret) |
169 | printf("FEC1 MXC: %s:failed\n", __func__); | 169 | printf("FEC1 MXC: %s:failed\n", __func__); |
170 | 170 | ||
171 | return ret; | 171 | return ret; |
172 | } | 172 | } |
173 | 173 | ||
174 | int board_phy_config(struct phy_device *phydev) | 174 | int board_phy_config(struct phy_device *phydev) |
175 | { | 175 | { |
176 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f); | 176 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x1f); |
177 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8); | 177 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x8); |
178 | 178 | ||
179 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x00); | 179 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x00); |
180 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x82ee); | 180 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x82ee); |
181 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05); | 181 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1d, 0x05); |
182 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); | 182 | phy_write(phydev, MDIO_DEVAD_NONE, 0x1e, 0x100); |
183 | 183 | ||
184 | if (phydev->drv->config) | 184 | if (phydev->drv->config) |
185 | phydev->drv->config(phydev); | 185 | phydev->drv->config(phydev); |
186 | 186 | ||
187 | return 0; | 187 | return 0; |
188 | } | 188 | } |
189 | #endif | 189 | #endif |
190 | 190 | ||
191 | #ifdef CONFIG_MXC_GPIO | 191 | #ifdef CONFIG_MXC_GPIO |
192 | 192 | ||
193 | #define LVDS_ENABLE IMX_GPIO_NR(1, 6) | 193 | #define LVDS_ENABLE IMX_GPIO_NR(1, 6) |
194 | #define MIPI_ENABLE IMX_GPIO_NR(1, 7) | 194 | #define MIPI_ENABLE IMX_GPIO_NR(1, 7) |
195 | 195 | ||
196 | #define BB_GPIO_3V3_1 IMX_GPIO_NR(4, 20) | 196 | #define BB_GPIO_3V3_1 IMX_GPIO_NR(4, 20) |
197 | #define BB_GPIO_3V3_2 IMX_GPIO_NR(4, 24) | 197 | #define BB_GPIO_3V3_2 IMX_GPIO_NR(4, 24) |
198 | #define BB_GPIO_3V3_3 IMX_GPIO_NR(4, 23) | 198 | #define BB_GPIO_3V3_3 IMX_GPIO_NR(4, 23) |
199 | 199 | ||
200 | static void board_gpio_init(void) | 200 | static void board_gpio_init(void) |
201 | { | 201 | { |
202 | /* Enable BB 3V3 */ | 202 | /* Enable BB 3V3 */ |
203 | gpio_request(BB_GPIO_3V3_1, "bb_3v3_1"); | 203 | gpio_request(BB_GPIO_3V3_1, "bb_3v3_1"); |
204 | gpio_direction_output(BB_GPIO_3V3_1, 1); | 204 | gpio_direction_output(BB_GPIO_3V3_1, 1); |
205 | gpio_request(BB_GPIO_3V3_2, "bb_3v3_2"); | 205 | gpio_request(BB_GPIO_3V3_2, "bb_3v3_2"); |
206 | gpio_direction_output(BB_GPIO_3V3_2, 1); | 206 | gpio_direction_output(BB_GPIO_3V3_2, 1); |
207 | gpio_request(BB_GPIO_3V3_3, "bb_3v3_3"); | 207 | gpio_request(BB_GPIO_3V3_3, "bb_3v3_3"); |
208 | gpio_direction_output(BB_GPIO_3V3_3, 1); | 208 | gpio_direction_output(BB_GPIO_3V3_3, 1); |
209 | 209 | ||
210 | /* enable LVDS SAS boards */ | 210 | /* enable LVDS SAS boards */ |
211 | gpio_request(LVDS_ENABLE, "lvds_enable"); | 211 | gpio_request(LVDS_ENABLE, "lvds_enable"); |
212 | gpio_direction_output(LVDS_ENABLE, 1); | 212 | gpio_direction_output(LVDS_ENABLE, 1); |
213 | 213 | ||
214 | /* enable MIPI SAS boards */ | 214 | /* enable MIPI SAS boards */ |
215 | gpio_request(MIPI_ENABLE, "mipi_enable"); | 215 | gpio_request(MIPI_ENABLE, "mipi_enable"); |
216 | gpio_direction_output(MIPI_ENABLE, 1); | 216 | gpio_direction_output(MIPI_ENABLE, 1); |
217 | } | 217 | } |
218 | #endif | 218 | #endif |
219 | 219 | ||
220 | int checkboard(void) | 220 | int checkboard(void) |
221 | { | 221 | { |
222 | puts("Board: iMX8QM MEK\n"); | 222 | puts("Board: iMX8QM MEK\n"); |
223 | 223 | ||
224 | print_bootinfo(); | 224 | print_bootinfo(); |
225 | 225 | ||
226 | /* Note: After reloc, ipcHndl will no longer be valid. If handle | 226 | /* Note: After reloc, ipcHndl will no longer be valid. If handle |
227 | * returned by sc_ipc_open matches SC_IPC_CH, use this | 227 | * returned by sc_ipc_open matches SC_IPC_CH, use this |
228 | * macro (valid after reloc) for subsequent SCI calls. | 228 | * macro (valid after reloc) for subsequent SCI calls. |
229 | */ | 229 | */ |
230 | if (gd->arch.ipc_channel_handle != SC_IPC_CH) { | 230 | if (gd->arch.ipc_channel_handle != SC_IPC_CH) { |
231 | printf("\nSCI error! Invalid handle\n"); | 231 | printf("\nSCI error! Invalid handle\n"); |
232 | } | 232 | } |
233 | 233 | ||
234 | return 0; | 234 | return 0; |
235 | } | 235 | } |
236 | 236 | ||
237 | #ifdef CONFIG_FSL_HSIO | 237 | #ifdef CONFIG_FSL_HSIO |
238 | 238 | ||
239 | #define PCIE_PAD_CTRL ((SC_PAD_CONFIG_OD_IN << PADRING_CONFIG_SHIFT)) | 239 | #define PCIE_PAD_CTRL ((SC_PAD_CONFIG_OD_IN << PADRING_CONFIG_SHIFT)) |
240 | static iomux_cfg_t board_pcie_pins[] = { | 240 | static iomux_cfg_t board_pcie_pins[] = { |
241 | SC_P_PCIE_CTRL0_CLKREQ_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), | 241 | SC_P_PCIE_CTRL0_CLKREQ_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), |
242 | SC_P_PCIE_CTRL0_WAKE_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), | 242 | SC_P_PCIE_CTRL0_WAKE_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), |
243 | SC_P_PCIE_CTRL0_PERST_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), | 243 | SC_P_PCIE_CTRL0_PERST_B | MUX_MODE_ALT(0) | MUX_PAD_CTRL(PCIE_PAD_CTRL), |
244 | }; | 244 | }; |
245 | 245 | ||
246 | static void imx8qm_hsio_initialize(void) | 246 | static void imx8qm_hsio_initialize(void) |
247 | { | 247 | { |
248 | struct power_domain pd; | 248 | struct power_domain pd; |
249 | int ret; | 249 | int ret; |
250 | 250 | ||
251 | if (!power_domain_lookup_name("hsio_sata0", &pd)) { | 251 | if (!power_domain_lookup_name("hsio_sata0", &pd)) { |
252 | ret = power_domain_on(&pd); | 252 | ret = power_domain_on(&pd); |
253 | if (ret) | 253 | if (ret) |
254 | printf("hsio_sata0 Power up failed! (error = %d)\n", ret); | 254 | printf("hsio_sata0 Power up failed! (error = %d)\n", ret); |
255 | } | 255 | } |
256 | 256 | ||
257 | if (!power_domain_lookup_name("hsio_pcie0", &pd)) { | 257 | if (!power_domain_lookup_name("hsio_pcie0", &pd)) { |
258 | ret = power_domain_on(&pd); | 258 | ret = power_domain_on(&pd); |
259 | if (ret) | 259 | if (ret) |
260 | printf("hsio_pcie0 Power up failed! (error = %d)\n", ret); | 260 | printf("hsio_pcie0 Power up failed! (error = %d)\n", ret); |
261 | } | 261 | } |
262 | 262 | ||
263 | if (!power_domain_lookup_name("hsio_pcie1", &pd)) { | 263 | if (!power_domain_lookup_name("hsio_pcie1", &pd)) { |
264 | ret = power_domain_on(&pd); | 264 | ret = power_domain_on(&pd); |
265 | if (ret) | 265 | if (ret) |
266 | printf("hsio_pcie1 Power up failed! (error = %d)\n", ret); | 266 | printf("hsio_pcie1 Power up failed! (error = %d)\n", ret); |
267 | } | 267 | } |
268 | 268 | ||
269 | if (!power_domain_lookup_name("hsio_gpio", &pd)) { | 269 | if (!power_domain_lookup_name("hsio_gpio", &pd)) { |
270 | ret = power_domain_on(&pd); | 270 | ret = power_domain_on(&pd); |
271 | if (ret) | 271 | if (ret) |
272 | printf("hsio_gpio Power up failed! (error = %d)\n", ret); | 272 | printf("hsio_gpio Power up failed! (error = %d)\n", ret); |
273 | } | 273 | } |
274 | 274 | ||
275 | LPCG_AllClockOn(HSIO_PCIE_X2_LPCG); | 275 | LPCG_AllClockOn(HSIO_PCIE_X2_LPCG); |
276 | LPCG_AllClockOn(HSIO_PCIE_X1_LPCG); | 276 | LPCG_AllClockOn(HSIO_PCIE_X1_LPCG); |
277 | LPCG_AllClockOn(HSIO_SATA_LPCG); | 277 | LPCG_AllClockOn(HSIO_SATA_LPCG); |
278 | LPCG_AllClockOn(HSIO_PHY_X2_LPCG); | 278 | LPCG_AllClockOn(HSIO_PHY_X2_LPCG); |
279 | LPCG_AllClockOn(HSIO_PHY_X1_LPCG); | 279 | LPCG_AllClockOn(HSIO_PHY_X1_LPCG); |
280 | LPCG_AllClockOn(HSIO_PHY_X2_CRR0_LPCG); | 280 | LPCG_AllClockOn(HSIO_PHY_X2_CRR0_LPCG); |
281 | LPCG_AllClockOn(HSIO_PHY_X1_CRR1_LPCG); | 281 | LPCG_AllClockOn(HSIO_PHY_X1_CRR1_LPCG); |
282 | LPCG_AllClockOn(HSIO_PCIE_X2_CRR2_LPCG); | 282 | LPCG_AllClockOn(HSIO_PCIE_X2_CRR2_LPCG); |
283 | LPCG_AllClockOn(HSIO_PCIE_X1_CRR3_LPCG); | 283 | LPCG_AllClockOn(HSIO_PCIE_X1_CRR3_LPCG); |
284 | LPCG_AllClockOn(HSIO_SATA_CRR4_LPCG); | 284 | LPCG_AllClockOn(HSIO_SATA_CRR4_LPCG); |
285 | LPCG_AllClockOn(HSIO_MISC_LPCG); | 285 | LPCG_AllClockOn(HSIO_MISC_LPCG); |
286 | LPCG_AllClockOn(HSIO_GPIO_LPCG); | 286 | LPCG_AllClockOn(HSIO_GPIO_LPCG); |
287 | 287 | ||
288 | imx8_iomux_setup_multiple_pads(board_pcie_pins, ARRAY_SIZE(board_pcie_pins)); | 288 | imx8_iomux_setup_multiple_pads(board_pcie_pins, ARRAY_SIZE(board_pcie_pins)); |
289 | } | 289 | } |
290 | 290 | ||
291 | void pci_init_board(void) | 291 | void pci_init_board(void) |
292 | { | 292 | { |
293 | /* test the 1 lane mode of the PCIe A controller */ | 293 | /* test the 1 lane mode of the PCIe A controller */ |
294 | mx8qm_pcie_init(); | 294 | mx8qm_pcie_init(); |
295 | } | 295 | } |
296 | #endif | 296 | #endif |
297 | 297 | ||
298 | #ifdef CONFIG_USB | 298 | #ifdef CONFIG_USB |
299 | 299 | ||
300 | #ifdef CONFIG_USB_TCPC | 300 | #ifdef CONFIG_USB_TCPC |
301 | #define USB_TYPEC_SEL IMX_GPIO_NR(4, 6) | 301 | #define USB_TYPEC_SEL IMX_GPIO_NR(4, 6) |
302 | #define USB_TYPEC_EN IMX_GPIO_NR(4, 19) | 302 | #define USB_TYPEC_EN IMX_GPIO_NR(4, 19) |
303 | 303 | ||
304 | static iomux_cfg_t ss_mux_gpio[] = { | 304 | static iomux_cfg_t ss_mux_gpio[] = { |
305 | SC_P_USB_SS3_TC3 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPIO_PAD_CTRL), | 305 | SC_P_USB_SS3_TC3 | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPIO_PAD_CTRL), |
306 | SC_P_QSPI1A_SS0_B | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPIO_PAD_CTRL), | 306 | SC_P_QSPI1A_SS0_B | MUX_MODE_ALT(3) | MUX_PAD_CTRL(GPIO_PAD_CTRL), |
307 | }; | 307 | }; |
308 | 308 | ||
309 | struct tcpc_port port; | 309 | struct tcpc_port port; |
310 | struct tcpc_port_config port_config = { | 310 | struct tcpc_port_config port_config = { |
311 | .i2c_bus = 0, | 311 | .i2c_bus = 0, |
312 | .addr = 0x51, | 312 | .addr = 0x51, |
313 | .port_type = TYPEC_PORT_DFP, | 313 | .port_type = TYPEC_PORT_DFP, |
314 | }; | 314 | }; |
315 | 315 | ||
316 | void ss_mux_select(enum typec_cc_polarity pol) | 316 | void ss_mux_select(enum typec_cc_polarity pol) |
317 | { | 317 | { |
318 | if (pol == TYPEC_POLARITY_CC1) | 318 | if (pol == TYPEC_POLARITY_CC1) |
319 | gpio_direction_output(USB_TYPEC_SEL, 0); | 319 | gpio_direction_output(USB_TYPEC_SEL, 0); |
320 | else | 320 | else |
321 | gpio_direction_output(USB_TYPEC_SEL, 1); | 321 | gpio_direction_output(USB_TYPEC_SEL, 1); |
322 | } | 322 | } |
323 | 323 | ||
324 | static void setup_typec(void) | 324 | static void setup_typec(void) |
325 | { | 325 | { |
326 | imx8_iomux_setup_multiple_pads(ss_mux_gpio, ARRAY_SIZE(ss_mux_gpio)); | 326 | imx8_iomux_setup_multiple_pads(ss_mux_gpio, ARRAY_SIZE(ss_mux_gpio)); |
327 | gpio_request(USB_TYPEC_SEL, "typec_sel"); | 327 | gpio_request(USB_TYPEC_SEL, "typec_sel"); |
328 | gpio_request(USB_TYPEC_EN, "typec_en"); | 328 | gpio_request(USB_TYPEC_EN, "typec_en"); |
329 | 329 | ||
330 | gpio_direction_output(USB_TYPEC_EN, 1); | 330 | gpio_direction_output(USB_TYPEC_EN, 1); |
331 | 331 | ||
332 | tcpc_init(&port, port_config, &ss_mux_select); | 332 | tcpc_init(&port, port_config, &ss_mux_select); |
333 | } | 333 | } |
334 | #endif | 334 | #endif |
335 | 335 | ||
336 | #ifdef CONFIG_USB_CDNS3_GADGET | 336 | #ifdef CONFIG_USB_CDNS3_GADGET |
337 | static struct cdns3_device cdns3_device_data = { | 337 | static struct cdns3_device cdns3_device_data = { |
338 | .none_core_base = 0x5B110000, | 338 | .none_core_base = 0x5B110000, |
339 | .xhci_base = 0x5B130000, | 339 | .xhci_base = 0x5B130000, |
340 | .dev_base = 0x5B140000, | 340 | .dev_base = 0x5B140000, |
341 | .phy_base = 0x5B160000, | 341 | .phy_base = 0x5B160000, |
342 | .otg_base = 0x5B120000, | 342 | .otg_base = 0x5B120000, |
343 | .dr_mode = USB_DR_MODE_PERIPHERAL, | 343 | .dr_mode = USB_DR_MODE_PERIPHERAL, |
344 | .index = 1, | 344 | .index = 1, |
345 | }; | 345 | }; |
346 | 346 | ||
347 | int usb_gadget_handle_interrupts(int index) | 347 | int usb_gadget_handle_interrupts(int index) |
348 | { | 348 | { |
349 | cdns3_uboot_handle_interrupt(index); | 349 | cdns3_uboot_handle_interrupt(index); |
350 | return 0; | 350 | return 0; |
351 | } | 351 | } |
352 | #endif | 352 | #endif |
353 | 353 | ||
354 | int board_usb_init(int index, enum usb_init_type init) | 354 | int board_usb_init(int index, enum usb_init_type init) |
355 | { | 355 | { |
356 | int ret = 0; | 356 | int ret = 0; |
357 | 357 | ||
358 | if (index == 1) { | 358 | if (index == 1) { |
359 | if (init == USB_INIT_HOST) { | 359 | if (init == USB_INIT_HOST) { |
360 | #ifdef CONFIG_USB_TCPC | 360 | #ifdef CONFIG_USB_TCPC |
361 | ret = tcpc_setup_dfp_mode(&port); | 361 | ret = tcpc_setup_dfp_mode(&port); |
362 | #endif | 362 | #endif |
363 | #ifdef CONFIG_USB_CDNS3_GADGET | 363 | #ifdef CONFIG_USB_CDNS3_GADGET |
364 | } else { | 364 | } else { |
365 | #ifdef CONFIG_SPL_BUILD | 365 | #ifdef CONFIG_SPL_BUILD |
366 | sc_ipc_t ipcHndl = 0; | 366 | sc_ipc_t ipcHndl = 0; |
367 | 367 | ||
368 | ipcHndl = gd->arch.ipc_channel_handle; | 368 | ipcHndl = gd->arch.ipc_channel_handle; |
369 | 369 | ||
370 | ret = sc_pm_set_resource_power_mode(ipcHndl, SC_R_USB_2, SC_PM_PW_MODE_ON); | 370 | ret = sc_pm_set_resource_power_mode(ipcHndl, SC_R_USB_2, SC_PM_PW_MODE_ON); |
371 | if (ret != SC_ERR_NONE) | 371 | if (ret != SC_ERR_NONE) |
372 | printf("conn_usb2 Power up failed! (error = %d)\n", ret); | 372 | printf("conn_usb2 Power up failed! (error = %d)\n", ret); |
373 | 373 | ||
374 | ret = sc_pm_set_resource_power_mode(ipcHndl, SC_R_USB_2_PHY, SC_PM_PW_MODE_ON); | 374 | ret = sc_pm_set_resource_power_mode(ipcHndl, SC_R_USB_2_PHY, SC_PM_PW_MODE_ON); |
375 | if (ret != SC_ERR_NONE) | 375 | if (ret != SC_ERR_NONE) |
376 | printf("conn_usb2_phy Power up failed! (error = %d)\n", ret); | 376 | printf("conn_usb2_phy Power up failed! (error = %d)\n", ret); |
377 | #else | 377 | #else |
378 | struct power_domain pd; | 378 | struct power_domain pd; |
379 | int ret; | 379 | int ret; |
380 | 380 | ||
381 | /* Power on usb */ | 381 | /* Power on usb */ |
382 | if (!power_domain_lookup_name("conn_usb2", &pd)) { | 382 | if (!power_domain_lookup_name("conn_usb2", &pd)) { |
383 | ret = power_domain_on(&pd); | 383 | ret = power_domain_on(&pd); |
384 | if (ret) | 384 | if (ret) |
385 | printf("conn_usb2 Power up failed! (error = %d)\n", ret); | 385 | printf("conn_usb2 Power up failed! (error = %d)\n", ret); |
386 | } | 386 | } |
387 | 387 | ||
388 | if (!power_domain_lookup_name("conn_usb2_phy", &pd)) { | 388 | if (!power_domain_lookup_name("conn_usb2_phy", &pd)) { |
389 | ret = power_domain_on(&pd); | 389 | ret = power_domain_on(&pd); |
390 | if (ret) | 390 | if (ret) |
391 | printf("conn_usb2_phy Power up failed! (error = %d)\n", ret); | 391 | printf("conn_usb2_phy Power up failed! (error = %d)\n", ret); |
392 | } | 392 | } |
393 | #endif | 393 | #endif |
394 | 394 | ||
395 | #ifdef CONFIG_USB_TCPC | 395 | #ifdef CONFIG_USB_TCPC |
396 | ret = tcpc_setup_ufp_mode(&port); | 396 | ret = tcpc_setup_ufp_mode(&port); |
397 | printf("%d setufp mode %d\n", index, ret); | 397 | printf("%d setufp mode %d\n", index, ret); |
398 | #endif | 398 | #endif |
399 | 399 | ||
400 | ret = cdns3_uboot_init(&cdns3_device_data); | 400 | ret = cdns3_uboot_init(&cdns3_device_data); |
401 | printf("%d cdns3_uboot_initmode %d\n", index, ret); | 401 | printf("%d cdns3_uboot_initmode %d\n", index, ret); |
402 | #endif | 402 | #endif |
403 | } | 403 | } |
404 | } | 404 | } |
405 | return ret; | 405 | return ret; |
406 | } | 406 | } |
407 | 407 | ||
408 | int board_usb_cleanup(int index, enum usb_init_type init) | 408 | int board_usb_cleanup(int index, enum usb_init_type init) |
409 | { | 409 | { |
410 | int ret = 0; | 410 | int ret = 0; |
411 | 411 | ||
412 | if (index == 1) { | 412 | if (index == 1) { |
413 | if (init == USB_INIT_HOST) { | 413 | if (init == USB_INIT_HOST) { |
414 | #ifdef CONFIG_USB_TCPC | 414 | #ifdef CONFIG_USB_TCPC |
415 | ret = tcpc_disable_src_vbus(&port); | 415 | ret = tcpc_disable_src_vbus(&port); |
416 | #endif | 416 | #endif |
417 | #ifdef CONFIG_USB_CDNS3_GADGET | 417 | #ifdef CONFIG_USB_CDNS3_GADGET |
418 | } else { | 418 | } else { |
419 | cdns3_uboot_exit(1); | 419 | cdns3_uboot_exit(1); |
420 | 420 | ||
421 | #ifdef CONFIG_SPL_BUILD | 421 | #ifdef CONFIG_SPL_BUILD |
422 | sc_ipc_t ipcHndl = 0; | 422 | sc_ipc_t ipcHndl = 0; |
423 | 423 | ||
424 | ipcHndl = gd->arch.ipc_channel_handle; | 424 | ipcHndl = gd->arch.ipc_channel_handle; |
425 | 425 | ||
426 | ret = sc_pm_set_resource_power_mode(ipcHndl, SC_R_USB_2, SC_PM_PW_MODE_OFF); | 426 | ret = sc_pm_set_resource_power_mode(ipcHndl, SC_R_USB_2, SC_PM_PW_MODE_OFF); |
427 | if (ret != SC_ERR_NONE) | 427 | if (ret != SC_ERR_NONE) |
428 | printf("conn_usb2 Power down failed! (error = %d)\n", ret); | 428 | printf("conn_usb2 Power down failed! (error = %d)\n", ret); |
429 | 429 | ||
430 | ret = sc_pm_set_resource_power_mode(ipcHndl, SC_R_USB_2_PHY, SC_PM_PW_MODE_OFF); | 430 | ret = sc_pm_set_resource_power_mode(ipcHndl, SC_R_USB_2_PHY, SC_PM_PW_MODE_OFF); |
431 | if (ret != SC_ERR_NONE) | 431 | if (ret != SC_ERR_NONE) |
432 | printf("conn_usb2_phy Power down failed! (error = %d)\n", ret); | 432 | printf("conn_usb2_phy Power down failed! (error = %d)\n", ret); |
433 | #else | 433 | #else |
434 | struct power_domain pd; | 434 | struct power_domain pd; |
435 | int ret; | 435 | int ret; |
436 | 436 | ||
437 | /* Power off usb */ | 437 | /* Power off usb */ |
438 | if (!power_domain_lookup_name("conn_usb2", &pd)) { | 438 | if (!power_domain_lookup_name("conn_usb2", &pd)) { |
439 | ret = power_domain_off(&pd); | 439 | ret = power_domain_off(&pd); |
440 | if (ret) | 440 | if (ret) |
441 | printf("conn_usb2 Power down failed! (error = %d)\n", ret); | 441 | printf("conn_usb2 Power down failed! (error = %d)\n", ret); |
442 | } | 442 | } |
443 | 443 | ||
444 | if (!power_domain_lookup_name("conn_usb2_phy", &pd)) { | 444 | if (!power_domain_lookup_name("conn_usb2_phy", &pd)) { |
445 | ret = power_domain_off(&pd); | 445 | ret = power_domain_off(&pd); |
446 | if (ret) | 446 | if (ret) |
447 | printf("conn_usb2_phy Power down failed! (error = %d)\n", ret); | 447 | printf("conn_usb2_phy Power down failed! (error = %d)\n", ret); |
448 | } | 448 | } |
449 | #endif | 449 | #endif |
450 | #endif | 450 | #endif |
451 | } | 451 | } |
452 | } | 452 | } |
453 | return ret; | 453 | return ret; |
454 | } | 454 | } |
455 | #endif | 455 | #endif |
456 | 456 | ||
457 | int board_init(void) | 457 | int board_init(void) |
458 | { | 458 | { |
459 | if (IS_ENABLED(CONFIG_XEN)) | 459 | if (IS_ENABLED(CONFIG_XEN)) |
460 | return 0; | 460 | return 0; |
461 | 461 | ||
462 | #ifdef CONFIG_MXC_GPIO | 462 | #ifdef CONFIG_MXC_GPIO |
463 | board_gpio_init(); | 463 | board_gpio_init(); |
464 | #endif | 464 | #endif |
465 | 465 | ||
466 | #ifdef CONFIG_FSL_HSIO | 466 | #ifdef CONFIG_FSL_HSIO |
467 | imx8qm_hsio_initialize(); | 467 | imx8qm_hsio_initialize(); |
468 | #ifdef CONFIG_SCSI_AHCI_PLAT | 468 | #ifdef CONFIG_SCSI_AHCI_PLAT |
469 | sata_init(); | 469 | sata_init(); |
470 | #endif | 470 | #endif |
471 | #endif | 471 | #endif |
472 | 472 | ||
473 | #if defined(CONFIG_USB_XHCI_IMX8) && defined(CONFIG_USB_TCPC) | 473 | #if defined(CONFIG_USB_XHCI_IMX8) && defined(CONFIG_USB_TCPC) |
474 | setup_typec(); | 474 | setup_typec(); |
475 | #endif | 475 | #endif |
476 | 476 | ||
477 | return 0; | 477 | return 0; |
478 | } | 478 | } |
479 | 479 | ||
480 | void board_quiesce_devices(void) | 480 | void board_quiesce_devices(void) |
481 | { | 481 | { |
482 | const char *power_on_devices[] = { | 482 | const char *power_on_devices[] = { |
483 | "dma_lpuart0", | 483 | "dma_lpuart0", |
484 | }; | 484 | }; |
485 | 485 | ||
486 | if (IS_ENABLED(CONFIG_XEN)) { | 486 | if (IS_ENABLED(CONFIG_XEN)) { |
487 | /* Clear magic number to let xen know uboot is over */ | 487 | /* Clear magic number to let xen know uboot is over */ |
488 | writel(0x0, (void __iomem *)0x80000000); | 488 | writel(0x0, (void __iomem *)0x80000000); |
489 | return; | 489 | return; |
490 | } | 490 | } |
491 | 491 | ||
492 | power_off_pd_devices(power_on_devices, ARRAY_SIZE(power_on_devices)); | 492 | power_off_pd_devices(power_on_devices, ARRAY_SIZE(power_on_devices)); |
493 | } | 493 | } |
494 | 494 | ||
495 | void detail_board_ddr_info(void) | 495 | void detail_board_ddr_info(void) |
496 | { | 496 | { |
497 | puts("\nDDR "); | 497 | puts("\nDDR "); |
498 | } | 498 | } |
499 | 499 | ||
500 | /* | 500 | /* |
501 | * Board specific reset that is system reset. | 501 | * Board specific reset that is system reset. |
502 | */ | 502 | */ |
503 | void reset_cpu(ulong addr) | 503 | void reset_cpu(ulong addr) |
504 | { | 504 | { |
505 | puts("SCI reboot request"); | 505 | puts("SCI reboot request"); |
506 | sc_pm_reboot(SC_IPC_CH, SC_PM_RESET_TYPE_COLD); | 506 | sc_pm_reboot(SC_IPC_CH, SC_PM_RESET_TYPE_COLD); |
507 | while (1) | 507 | while (1) |
508 | putc('.'); | 508 | putc('.'); |
509 | } | 509 | } |
510 | 510 | ||
511 | #ifdef CONFIG_OF_BOARD_SETUP | 511 | #ifdef CONFIG_OF_BOARD_SETUP |
512 | int ft_board_setup(void *blob, bd_t *bd) | 512 | int ft_board_setup(void *blob, bd_t *bd) |
513 | { | 513 | { |
514 | return 0; | 514 | return 0; |
515 | } | 515 | } |
516 | #endif | 516 | #endif |
517 | 517 | ||
518 | int board_mmc_get_env_dev(int devno) | 518 | int board_mmc_get_env_dev(int devno) |
519 | { | 519 | { |
520 | /* Use EMMC */ | 520 | /* Use EMMC */ |
521 | if (IS_ENABLED(CONFIG_XEN)) | 521 | if (IS_ENABLED(CONFIG_XEN)) |
522 | return 0; | 522 | return 0; |
523 | 523 | ||
524 | return devno; | 524 | return devno; |
525 | } | 525 | } |
526 | 526 | ||
527 | int mmc_map_to_kernel_blk(int dev_no) | 527 | int mmc_map_to_kernel_blk(int dev_no) |
528 | { | 528 | { |
529 | /* Use EMMC */ | 529 | /* Use EMMC */ |
530 | if (IS_ENABLED(CONFIG_XEN)) | 530 | if (IS_ENABLED(CONFIG_XEN)) |
531 | return 0; | 531 | return 0; |
532 | 532 | ||
533 | return dev_no; | 533 | return dev_no; |
534 | } | 534 | } |
535 | 535 | ||
536 | extern uint32_t _end_ofs; | 536 | extern uint32_t _end_ofs; |
537 | int board_late_init(void) | 537 | int board_late_init(void) |
538 | { | 538 | { |
539 | char *fdt_file; | 539 | char *fdt_file; |
540 | bool m4_boot; | 540 | bool m4_boot; |
541 | 541 | ||
542 | #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG | 542 | #ifdef CONFIG_ENV_VARS_UBOOT_RUNTIME_CONFIG |
543 | env_set("board_name", "MEK"); | 543 | env_set("board_name", "MEK"); |
544 | env_set("board_rev", "iMX8QM"); | 544 | env_set("board_rev", "iMX8QM"); |
545 | #endif | 545 | #endif |
546 | 546 | ||
547 | env_set("sec_boot", "no"); | 547 | env_set("sec_boot", "no"); |
548 | #ifdef CONFIG_AHAB_BOOT | 548 | #ifdef CONFIG_AHAB_BOOT |
549 | env_set("sec_boot", "yes"); | 549 | env_set("sec_boot", "yes"); |
550 | #endif | 550 | #endif |
551 | 551 | ||
552 | fdt_file = env_get("fdt_file"); | 552 | fdt_file = env_get("fdt_file"); |
553 | m4_boot = check_m4_parts_boot(); | 553 | m4_boot = check_m4_parts_boot(); |
554 | 554 | ||
555 | if (fdt_file && !strcmp(fdt_file, "undefined")) { | 555 | if (fdt_file && !strcmp(fdt_file, "undefined")) { |
556 | if (m4_boot) | 556 | if (m4_boot) |
557 | env_set("fdt_file", "fsl-imx8qm-mek-rpmsg.dtb"); | 557 | env_set("fdt_file", "fsl-imx8qm-mek-rpmsg.dtb"); |
558 | else | 558 | else |
559 | env_set("fdt_file", "fsl-imx8qm-mek.dtb"); | 559 | env_set("fdt_file", "fsl-imx8qm-mek.dtb"); |
560 | } | 560 | } |
561 | 561 | ||
562 | #ifdef CONFIG_ENV_IS_IN_MMC | 562 | #ifdef CONFIG_ENV_IS_IN_MMC |
563 | board_late_mmc_env_init(); | 563 | board_late_mmc_env_init(); |
564 | #endif | 564 | #endif |
565 | 565 | ||
566 | #ifdef IMX_LOAD_HDMI_FIMRWARE | 566 | #ifdef IMX_LOAD_HDMI_FIMRWARE |
567 | char *end_of_uboot; | 567 | char *end_of_uboot; |
568 | char command[256]; | 568 | char command[256]; |
569 | end_of_uboot = (char *)(ulong)(CONFIG_SYS_TEXT_BASE + _end_ofs + fdt_totalsize(gd->fdt_blob)); | 569 | end_of_uboot = (char *)(ulong)(CONFIG_SYS_TEXT_BASE + _end_ofs + fdt_totalsize(gd->fdt_blob)); |
570 | end_of_uboot += 9; | 570 | end_of_uboot += 9; |
571 | 571 | ||
572 | /* load hdmitxfw.bin and hdmirxfw.bin*/ | 572 | /* load hdmitxfw.bin and hdmirxfw.bin*/ |
573 | memcpy(IMX_HDMI_FIRMWARE_LOAD_ADDR, end_of_uboot, | 573 | memcpy((void *)IMX_HDMI_FIRMWARE_LOAD_ADDR, end_of_uboot, |
574 | IMX_HDMITX_FIRMWARE_SIZE + IMX_HDMIRX_FIRMWARE_SIZE); | 574 | IMX_HDMITX_FIRMWARE_SIZE + IMX_HDMIRX_FIRMWARE_SIZE); |
575 | 575 | ||
576 | sprintf(command, "hdp load 0x%x", IMX_HDMI_FIRMWARE_LOAD_ADDR); | 576 | sprintf(command, "hdp load 0x%x", IMX_HDMI_FIRMWARE_LOAD_ADDR); |
577 | run_command(command, 0); | 577 | run_command(command, 0); |
578 | 578 | ||
579 | sprintf(command, "hdprx load 0x%x", | 579 | sprintf(command, "hdprx load 0x%x", |
580 | IMX_HDMI_FIRMWARE_LOAD_ADDR + IMX_HDMITX_FIRMWARE_SIZE); | 580 | IMX_HDMI_FIRMWARE_LOAD_ADDR + IMX_HDMITX_FIRMWARE_SIZE); |
581 | run_command(command, 0); | 581 | run_command(command, 0); |
582 | #endif | 582 | #endif |
583 | 583 | ||
584 | return 0; | 584 | return 0; |
585 | } | 585 | } |
586 | 586 | ||
587 | #ifdef CONFIG_FSL_FASTBOOT | 587 | #ifdef CONFIG_FSL_FASTBOOT |
588 | #ifdef CONFIG_ANDROID_RECOVERY | 588 | #ifdef CONFIG_ANDROID_RECOVERY |
589 | int is_recovery_key_pressing(void) | 589 | int is_recovery_key_pressing(void) |
590 | { | 590 | { |
591 | return 0; /*TODO*/ | 591 | return 0; /*TODO*/ |
592 | } | 592 | } |
593 | #endif /*CONFIG_ANDROID_RECOVERY*/ | 593 | #endif /*CONFIG_ANDROID_RECOVERY*/ |
594 | #endif /*CONFIG_FSL_FASTBOOT*/ | 594 | #endif /*CONFIG_FSL_FASTBOOT*/ |
595 | 595 | ||
596 | #if defined(CONFIG_VIDEO_IMXDPUV1) | 596 | #if defined(CONFIG_VIDEO_IMXDPUV1) |
597 | static void enable_lvds(struct display_info_t const *dev) | 597 | static void enable_lvds(struct display_info_t const *dev) |
598 | { | 598 | { |
599 | display_controller_setup((PS2KHZ(dev->mode.pixclock) * 1000)); | 599 | display_controller_setup((PS2KHZ(dev->mode.pixclock) * 1000)); |
600 | lvds_soc_setup(dev->bus, (PS2KHZ(dev->mode.pixclock) * 1000)); | 600 | lvds_soc_setup(dev->bus, (PS2KHZ(dev->mode.pixclock) * 1000)); |
601 | lvds_configure(dev->bus); | 601 | lvds_configure(dev->bus); |
602 | lvds2hdmi_setup(6); | 602 | lvds2hdmi_setup(6); |
603 | } | 603 | } |
604 | 604 | ||
605 | struct display_info_t const displays[] = {{ | 605 | struct display_info_t const displays[] = {{ |
606 | .bus = 0, /* LVDS0 */ | 606 | .bus = 0, /* LVDS0 */ |
607 | .addr = 0, /* Unused */ | 607 | .addr = 0, /* Unused */ |
608 | .pixfmt = IMXDPUV1_PIX_FMT_BGRA32, | 608 | .pixfmt = IMXDPUV1_PIX_FMT_BGRA32, |
609 | .detect = NULL, | 609 | .detect = NULL, |
610 | .enable = enable_lvds, | 610 | .enable = enable_lvds, |
611 | .mode = { | 611 | .mode = { |
612 | .name = "IT6263", /* 720P60 */ | 612 | .name = "IT6263", /* 720P60 */ |
613 | .refresh = 60, | 613 | .refresh = 60, |
614 | .xres = 1280, | 614 | .xres = 1280, |
615 | .yres = 720, | 615 | .yres = 720, |
616 | .pixclock = 13468, /* 74250000 */ | 616 | .pixclock = 13468, /* 74250000 */ |
617 | .left_margin = 110, | 617 | .left_margin = 110, |
618 | .right_margin = 220, | 618 | .right_margin = 220, |
619 | .upper_margin = 5, | 619 | .upper_margin = 5, |
620 | .lower_margin = 20, | 620 | .lower_margin = 20, |
621 | .hsync_len = 40, | 621 | .hsync_len = 40, |
622 | .vsync_len = 5, | 622 | .vsync_len = 5, |
623 | .sync = FB_SYNC_EXT, | 623 | .sync = FB_SYNC_EXT, |
624 | .vmode = FB_VMODE_NONINTERLACED | 624 | .vmode = FB_VMODE_NONINTERLACED |
625 | } } }; | 625 | } } }; |
626 | size_t display_count = ARRAY_SIZE(displays); | 626 | size_t display_count = ARRAY_SIZE(displays); |
627 | 627 | ||
628 | #endif /* CONFIG_VIDEO_IMXDPUV1 */ | 628 | #endif /* CONFIG_VIDEO_IMXDPUV1 */ |
629 | 629 |
lib/avb/libavb/avb_cmdline.c
1 | /* | 1 | /* |
2 | * Copyright (C) 2016 The Android Open Source Project | 2 | * Copyright (C) 2016 The Android Open Source Project |
3 | * | 3 | * |
4 | * Permission is hereby granted, free of charge, to any person | 4 | * Permission is hereby granted, free of charge, to any person |
5 | * obtaining a copy of this software and associated documentation | 5 | * obtaining a copy of this software and associated documentation |
6 | * files (the "Software"), to deal in the Software without | 6 | * files (the "Software"), to deal in the Software without |
7 | * restriction, including without limitation the rights to use, copy, | 7 | * restriction, including without limitation the rights to use, copy, |
8 | * modify, merge, publish, distribute, sublicense, and/or sell copies | 8 | * modify, merge, publish, distribute, sublicense, and/or sell copies |
9 | * of the Software, and to permit persons to whom the Software is | 9 | * of the Software, and to permit persons to whom the Software is |
10 | * furnished to do so, subject to the following conditions: | 10 | * furnished to do so, subject to the following conditions: |
11 | * | 11 | * |
12 | * The above copyright notice and this permission notice shall be | 12 | * The above copyright notice and this permission notice shall be |
13 | * included in all copies or substantial portions of the Software. | 13 | * included in all copies or substantial portions of the Software. |
14 | * | 14 | * |
15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | 15 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF | 16 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | 17 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS | 18 | * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
19 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN | 19 | * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
20 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN | 20 | * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | 21 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
22 | * SOFTWARE. | 22 | * SOFTWARE. |
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "avb_cmdline.h" | 25 | #include "avb_cmdline.h" |
26 | #include "avb_sha.h" | 26 | #include "avb_sha.h" |
27 | #include "avb_util.h" | 27 | #include "avb_util.h" |
28 | #include "avb_version.h" | 28 | #include "avb_version.h" |
29 | 29 | ||
30 | #define NUM_GUIDS 3 | 30 | #define NUM_GUIDS 3 |
31 | 31 | ||
32 | /* Substitutes all variables (e.g. $(ANDROID_SYSTEM_PARTUUID)) with | 32 | /* Substitutes all variables (e.g. $(ANDROID_SYSTEM_PARTUUID)) with |
33 | * values. Returns NULL on OOM, otherwise the cmdline with values | 33 | * values. Returns NULL on OOM, otherwise the cmdline with values |
34 | * replaced. | 34 | * replaced. |
35 | */ | 35 | */ |
36 | char* avb_sub_cmdline(AvbOps* ops, | 36 | char* avb_sub_cmdline(AvbOps* ops, |
37 | const char* cmdline, | 37 | const char* cmdline, |
38 | const char* ab_suffix, | 38 | const char* ab_suffix, |
39 | bool using_boot_for_vbmeta, | 39 | bool using_boot_for_vbmeta, |
40 | const AvbCmdlineSubstList* additional_substitutions) { | 40 | const AvbCmdlineSubstList* additional_substitutions) { |
41 | const char* part_name_str[NUM_GUIDS] = {"system", "boot", "vbmeta"}; | 41 | const char* part_name_str[NUM_GUIDS] = {"system", "boot", "vbmeta"}; |
42 | const char* replace_str[NUM_GUIDS] = {"$(ANDROID_SYSTEM_PARTUUID)", | 42 | const char* replace_str[NUM_GUIDS] = {"$(ANDROID_SYSTEM_PARTUUID)", |
43 | "$(ANDROID_BOOT_PARTUUID)", | 43 | "$(ANDROID_BOOT_PARTUUID)", |
44 | "$(ANDROID_VBMETA_PARTUUID)"}; | 44 | "$(ANDROID_VBMETA_PARTUUID)"}; |
45 | char* ret = NULL; | 45 | char* ret = NULL; |
46 | AvbIOResult io_ret; | 46 | AvbIOResult io_ret; |
47 | size_t n; | 47 | size_t n; |
48 | 48 | ||
49 | /* Special-case for when the top-level vbmeta struct is in the boot | 49 | /* Special-case for when the top-level vbmeta struct is in the boot |
50 | * partition. | 50 | * partition. |
51 | */ | 51 | */ |
52 | if (using_boot_for_vbmeta) { | 52 | if (using_boot_for_vbmeta) { |
53 | part_name_str[2] = "boot"; | 53 | part_name_str[2] = "boot"; |
54 | } | 54 | } |
55 | 55 | ||
56 | /* Replace unique partition GUIDs */ | 56 | /* Replace unique partition GUIDs */ |
57 | for (n = 0; n < NUM_GUIDS; n++) { | 57 | for (n = 0; n < NUM_GUIDS; n++) { |
58 | char part_name[AVB_PART_NAME_MAX_SIZE]; | 58 | char part_name[AVB_PART_NAME_MAX_SIZE]; |
59 | char guid_buf[37]; | 59 | char guid_buf[37]; |
60 | 60 | ||
61 | if (!avb_str_concat(part_name, | 61 | if (!avb_str_concat(part_name, |
62 | sizeof part_name, | 62 | sizeof part_name, |
63 | part_name_str[n], | 63 | part_name_str[n], |
64 | avb_strlen(part_name_str[n]), | 64 | avb_strlen(part_name_str[n]), |
65 | ab_suffix, | 65 | ab_suffix, |
66 | avb_strlen(ab_suffix))) { | 66 | avb_strlen(ab_suffix))) { |
67 | avb_error("Partition name and suffix does not fit.\n"); | 67 | avb_error("Partition name and suffix does not fit.\n"); |
68 | goto fail; | 68 | goto fail; |
69 | } | 69 | } |
70 | 70 | ||
71 | io_ret = ops->get_unique_guid_for_partition( | 71 | io_ret = ops->get_unique_guid_for_partition( |
72 | ops, part_name, guid_buf, sizeof guid_buf); | 72 | ops, part_name, guid_buf, sizeof guid_buf); |
73 | if (io_ret == AVB_IO_RESULT_ERROR_OOM) { | 73 | if (io_ret == AVB_IO_RESULT_ERROR_OOM) { |
74 | goto fail; | 74 | goto fail; |
75 | } else if (io_ret != AVB_IO_RESULT_OK) { | 75 | } else if (io_ret != AVB_IO_RESULT_OK) { |
76 | avb_error("Error getting unique GUID for partition.\n"); | 76 | avb_error("Error getting unique GUID for partition.\n"); |
77 | goto fail; | 77 | goto fail; |
78 | } | 78 | } |
79 | 79 | ||
80 | if (ret == NULL) { | 80 | if (ret == NULL) { |
81 | ret = avb_replace(cmdline, replace_str[n], guid_buf); | 81 | ret = avb_replace(cmdline, replace_str[n], guid_buf); |
82 | } else { | 82 | } else { |
83 | char* new_ret = avb_replace(ret, replace_str[n], guid_buf); | 83 | char* new_ret = avb_replace(ret, replace_str[n], guid_buf); |
84 | avb_free(ret); | 84 | avb_free(ret); |
85 | ret = new_ret; | 85 | ret = new_ret; |
86 | } | 86 | } |
87 | if (ret == NULL) { | 87 | if (ret == NULL) { |
88 | goto fail; | 88 | goto fail; |
89 | } | 89 | } |
90 | } | 90 | } |
91 | 91 | ||
92 | avb_assert(ret != NULL); | 92 | avb_assert(ret != NULL); |
93 | 93 | ||
94 | /* Replace any additional substitutions. */ | 94 | /* Replace any additional substitutions. */ |
95 | if (additional_substitutions != NULL) { | 95 | if (additional_substitutions != NULL) { |
96 | for (n = 0; n < additional_substitutions->size; ++n) { | 96 | for (n = 0; n < additional_substitutions->size; ++n) { |
97 | char* new_ret = avb_replace(ret, | 97 | char* new_ret = avb_replace(ret, |
98 | additional_substitutions->tokens[n], | 98 | additional_substitutions->tokens[n], |
99 | additional_substitutions->values[n]); | 99 | additional_substitutions->values[n]); |
100 | avb_free(ret); | 100 | avb_free(ret); |
101 | ret = new_ret; | 101 | ret = new_ret; |
102 | if (ret == NULL) { | 102 | if (ret == NULL) { |
103 | goto fail; | 103 | goto fail; |
104 | } | 104 | } |
105 | } | 105 | } |
106 | } | 106 | } |
107 | 107 | ||
108 | return ret; | 108 | return ret; |
109 | 109 | ||
110 | fail: | 110 | fail: |
111 | if (ret != NULL) { | 111 | if (ret != NULL) { |
112 | avb_free(ret); | 112 | avb_free(ret); |
113 | } | 113 | } |
114 | return NULL; | 114 | return NULL; |
115 | } | 115 | } |
116 | 116 | ||
117 | static int cmdline_append_option(AvbSlotVerifyData* slot_data, | 117 | static int cmdline_append_option(AvbSlotVerifyData* slot_data, |
118 | const char* key, | 118 | const char* key, |
119 | const char* value) { | 119 | const char* value) { |
120 | size_t offset, key_len, value_len; | 120 | size_t offset, key_len, value_len; |
121 | char* new_cmdline; | 121 | char* new_cmdline; |
122 | 122 | ||
123 | key_len = avb_strlen(key); | 123 | key_len = avb_strlen(key); |
124 | value_len = avb_strlen(value); | 124 | value_len = avb_strlen(value); |
125 | 125 | ||
126 | offset = 0; | 126 | offset = 0; |
127 | if (slot_data->cmdline != NULL) { | 127 | if (slot_data->cmdline != NULL) { |
128 | offset = avb_strlen(slot_data->cmdline); | 128 | offset = avb_strlen(slot_data->cmdline); |
129 | if (offset > 0) { | 129 | if (offset > 0) { |
130 | offset += 1; | 130 | offset += 1; |
131 | } | 131 | } |
132 | } | 132 | } |
133 | 133 | ||
134 | new_cmdline = avb_calloc(offset + key_len + value_len + 2); | 134 | new_cmdline = avb_calloc(offset + key_len + value_len + 2); |
135 | if (new_cmdline == NULL) { | 135 | if (new_cmdline == NULL) { |
136 | return 0; | 136 | return 0; |
137 | } | 137 | } |
138 | if (offset > 0) { | 138 | if (offset > 0) { |
139 | avb_memcpy(new_cmdline, slot_data->cmdline, offset - 1); | 139 | avb_memcpy(new_cmdline, slot_data->cmdline, offset - 1); |
140 | new_cmdline[offset - 1] = ' '; | 140 | new_cmdline[offset - 1] = ' '; |
141 | } | 141 | } |
142 | avb_memcpy(new_cmdline + offset, key, key_len); | 142 | avb_memcpy(new_cmdline + offset, key, key_len); |
143 | new_cmdline[offset + key_len] = '='; | 143 | new_cmdline[offset + key_len] = '='; |
144 | avb_memcpy(new_cmdline + offset + key_len + 1, value, value_len); | 144 | avb_memcpy(new_cmdline + offset + key_len + 1, value, value_len); |
145 | if (slot_data->cmdline != NULL) { | 145 | if (slot_data->cmdline != NULL) { |
146 | avb_free(slot_data->cmdline); | 146 | avb_free(slot_data->cmdline); |
147 | } | 147 | } |
148 | slot_data->cmdline = new_cmdline; | 148 | slot_data->cmdline = new_cmdline; |
149 | 149 | ||
150 | return 1; | 150 | return 1; |
151 | } | 151 | } |
152 | 152 | ||
153 | #define AVB_MAX_DIGITS_UINT64 32 | 153 | #define AVB_MAX_DIGITS_UINT64 32 |
154 | 154 | ||
155 | /* Writes |value| to |digits| in base 10 followed by a NUL byte. | 155 | /* Writes |value| to |digits| in base 10 followed by a NUL byte. |
156 | * Returns number of characters written excluding the NUL byte. | 156 | * Returns number of characters written excluding the NUL byte. |
157 | */ | 157 | */ |
158 | static size_t uint64_to_base10(uint64_t value, | 158 | static size_t uint64_to_base10(uint64_t value, |
159 | char digits[AVB_MAX_DIGITS_UINT64]) { | 159 | char digits[AVB_MAX_DIGITS_UINT64]) { |
160 | char rev_digits[AVB_MAX_DIGITS_UINT64]; | 160 | char rev_digits[AVB_MAX_DIGITS_UINT64]; |
161 | size_t n, num_digits; | 161 | size_t n, num_digits; |
162 | 162 | ||
163 | for (num_digits = 0; num_digits < AVB_MAX_DIGITS_UINT64 - 1;) { | 163 | for (num_digits = 0; num_digits < AVB_MAX_DIGITS_UINT64 - 1;) { |
164 | rev_digits[num_digits++] = avb_div_by_10(&value) + '0'; | 164 | rev_digits[num_digits++] = avb_div_by_10(&value) + '0'; |
165 | if (value == 0) { | 165 | if (value == 0) { |
166 | break; | 166 | break; |
167 | } | 167 | } |
168 | } | 168 | } |
169 | 169 | ||
170 | for (n = 0; n < num_digits; n++) { | 170 | for (n = 0; n < num_digits; n++) { |
171 | digits[n] = rev_digits[num_digits - 1 - n]; | 171 | digits[n] = rev_digits[num_digits - 1 - n]; |
172 | } | 172 | } |
173 | digits[n] = '\0'; | 173 | digits[n] = '\0'; |
174 | return n; | 174 | return n; |
175 | } | 175 | } |
176 | 176 | ||
177 | static int cmdline_append_version(AvbSlotVerifyData* slot_data, | 177 | static int cmdline_append_version(AvbSlotVerifyData* slot_data, |
178 | const char* key, | 178 | const char* key, |
179 | uint64_t major_version, | 179 | uint64_t major_version, |
180 | uint64_t minor_version) { | 180 | uint64_t minor_version) { |
181 | char major_digits[AVB_MAX_DIGITS_UINT64]; | 181 | char major_digits[AVB_MAX_DIGITS_UINT64]; |
182 | char minor_digits[AVB_MAX_DIGITS_UINT64]; | 182 | char minor_digits[AVB_MAX_DIGITS_UINT64]; |
183 | char combined[AVB_MAX_DIGITS_UINT64 * 2 + 1]; | 183 | char combined[AVB_MAX_DIGITS_UINT64 * 2 + 1]; |
184 | size_t num_major_digits, num_minor_digits; | 184 | size_t num_major_digits, num_minor_digits; |
185 | 185 | ||
186 | num_major_digits = uint64_to_base10(major_version, major_digits); | 186 | num_major_digits = uint64_to_base10(major_version, major_digits); |
187 | num_minor_digits = uint64_to_base10(minor_version, minor_digits); | 187 | num_minor_digits = uint64_to_base10(minor_version, minor_digits); |
188 | avb_memcpy(combined, major_digits, num_major_digits); | 188 | avb_memcpy(combined, major_digits, num_major_digits); |
189 | combined[num_major_digits] = '.'; | 189 | combined[num_major_digits] = '.'; |
190 | avb_memcpy(combined + num_major_digits + 1, minor_digits, num_minor_digits); | 190 | avb_memcpy(combined + num_major_digits + 1, minor_digits, num_minor_digits); |
191 | combined[num_major_digits + 1 + num_minor_digits] = '\0'; | 191 | combined[num_major_digits + 1 + num_minor_digits] = '\0'; |
192 | 192 | ||
193 | return cmdline_append_option(slot_data, key, combined); | 193 | return cmdline_append_option(slot_data, key, combined); |
194 | } | 194 | } |
195 | 195 | ||
196 | static int cmdline_append_uint64_base10(AvbSlotVerifyData* slot_data, | 196 | static int cmdline_append_uint64_base10(AvbSlotVerifyData* slot_data, |
197 | const char* key, | 197 | const char* key, |
198 | uint64_t value) { | 198 | uint64_t value) { |
199 | char digits[AVB_MAX_DIGITS_UINT64]; | 199 | char digits[AVB_MAX_DIGITS_UINT64]; |
200 | uint64_to_base10(value, digits); | 200 | uint64_to_base10(value, digits); |
201 | return cmdline_append_option(slot_data, key, digits); | 201 | return cmdline_append_option(slot_data, key, digits); |
202 | } | 202 | } |
203 | 203 | ||
204 | static int cmdline_append_hex(AvbSlotVerifyData* slot_data, | 204 | static int cmdline_append_hex(AvbSlotVerifyData* slot_data, |
205 | const char* key, | 205 | const char* key, |
206 | const uint8_t* data, | 206 | const uint8_t* data, |
207 | size_t data_len) { | 207 | size_t data_len) { |
208 | int ret; | 208 | int ret; |
209 | char* hex_data = avb_bin2hex(data, data_len); | 209 | char* hex_data = avb_bin2hex(data, data_len); |
210 | if (hex_data == NULL) { | 210 | if (hex_data == NULL) { |
211 | return 0; | 211 | return 0; |
212 | } | 212 | } |
213 | ret = cmdline_append_option(slot_data, key, hex_data); | 213 | ret = cmdline_append_option(slot_data, key, hex_data); |
214 | avb_free(hex_data); | 214 | avb_free(hex_data); |
215 | return ret; | 215 | return ret; |
216 | } | 216 | } |
217 | 217 | ||
218 | AvbSlotVerifyResult avb_append_options( | 218 | AvbSlotVerifyResult avb_append_options( |
219 | AvbOps* ops, | 219 | AvbOps* ops, |
220 | AvbSlotVerifyData* slot_data, | 220 | AvbSlotVerifyData* slot_data, |
221 | AvbVBMetaImageHeader* toplevel_vbmeta, | 221 | AvbVBMetaImageHeader* toplevel_vbmeta, |
222 | AvbAlgorithmType algorithm_type, | 222 | AvbAlgorithmType algorithm_type, |
223 | AvbHashtreeErrorMode hashtree_error_mode) { | 223 | AvbHashtreeErrorMode hashtree_error_mode) { |
224 | AvbSlotVerifyResult ret; | 224 | AvbSlotVerifyResult ret; |
225 | const char* verity_mode; | 225 | const char* verity_mode = NULL; |
226 | bool is_device_unlocked; | 226 | bool is_device_unlocked; |
227 | AvbIOResult io_ret; | 227 | AvbIOResult io_ret; |
228 | 228 | ||
229 | /* Add androidboot.vbmeta.device option. */ | 229 | /* Add androidboot.vbmeta.device option. */ |
230 | if (!cmdline_append_option(slot_data, | 230 | if (!cmdline_append_option(slot_data, |
231 | "androidboot.vbmeta.device", | 231 | "androidboot.vbmeta.device", |
232 | "PARTUUID=$(ANDROID_VBMETA_PARTUUID)")) { | 232 | "PARTUUID=$(ANDROID_VBMETA_PARTUUID)")) { |
233 | ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; | 233 | ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; |
234 | goto out; | 234 | goto out; |
235 | } | 235 | } |
236 | 236 | ||
237 | /* Add androidboot.vbmeta.avb_version option. */ | 237 | /* Add androidboot.vbmeta.avb_version option. */ |
238 | if (!cmdline_append_version(slot_data, | 238 | if (!cmdline_append_version(slot_data, |
239 | "androidboot.vbmeta.avb_version", | 239 | "androidboot.vbmeta.avb_version", |
240 | AVB_VERSION_MAJOR, | 240 | AVB_VERSION_MAJOR, |
241 | AVB_VERSION_MINOR)) { | 241 | AVB_VERSION_MINOR)) { |
242 | ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; | 242 | ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; |
243 | goto out; | 243 | goto out; |
244 | } | 244 | } |
245 | 245 | ||
246 | /* Set androidboot.avb.device_state to "locked" or "unlocked". */ | 246 | /* Set androidboot.avb.device_state to "locked" or "unlocked". */ |
247 | io_ret = ops->read_is_device_unlocked(ops, &is_device_unlocked); | 247 | io_ret = ops->read_is_device_unlocked(ops, &is_device_unlocked); |
248 | if (io_ret == AVB_IO_RESULT_ERROR_OOM) { | 248 | if (io_ret == AVB_IO_RESULT_ERROR_OOM) { |
249 | ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; | 249 | ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; |
250 | goto out; | 250 | goto out; |
251 | } else if (io_ret != AVB_IO_RESULT_OK) { | 251 | } else if (io_ret != AVB_IO_RESULT_OK) { |
252 | avb_error("Error getting device state.\n"); | 252 | avb_error("Error getting device state.\n"); |
253 | ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO; | 253 | ret = AVB_SLOT_VERIFY_RESULT_ERROR_IO; |
254 | goto out; | 254 | goto out; |
255 | } | 255 | } |
256 | if (!cmdline_append_option(slot_data, | 256 | if (!cmdline_append_option(slot_data, |
257 | "androidboot.vbmeta.device_state", | 257 | "androidboot.vbmeta.device_state", |
258 | is_device_unlocked ? "unlocked" : "locked")) { | 258 | is_device_unlocked ? "unlocked" : "locked")) { |
259 | ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; | 259 | ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; |
260 | goto out; | 260 | goto out; |
261 | } | 261 | } |
262 | 262 | ||
263 | /* Set androidboot.vbmeta.{hash_alg, size, digest} - use same hash | 263 | /* Set androidboot.vbmeta.{hash_alg, size, digest} - use same hash |
264 | * function as is used to sign vbmeta. | 264 | * function as is used to sign vbmeta. |
265 | */ | 265 | */ |
266 | switch (algorithm_type) { | 266 | switch (algorithm_type) { |
267 | /* Explicit fallthrough. */ | 267 | /* Explicit fallthrough. */ |
268 | case AVB_ALGORITHM_TYPE_NONE: | 268 | case AVB_ALGORITHM_TYPE_NONE: |
269 | case AVB_ALGORITHM_TYPE_SHA256_RSA2048: | 269 | case AVB_ALGORITHM_TYPE_SHA256_RSA2048: |
270 | case AVB_ALGORITHM_TYPE_SHA256_RSA4096: | 270 | case AVB_ALGORITHM_TYPE_SHA256_RSA4096: |
271 | case AVB_ALGORITHM_TYPE_SHA256_RSA8192: { | 271 | case AVB_ALGORITHM_TYPE_SHA256_RSA8192: { |
272 | size_t n, total_size = 0; | 272 | size_t n, total_size = 0; |
273 | uint8_t vbmeta_digest[AVB_SHA256_DIGEST_SIZE]; | 273 | uint8_t vbmeta_digest[AVB_SHA256_DIGEST_SIZE]; |
274 | avb_slot_verify_data_calculate_vbmeta_digest( | 274 | avb_slot_verify_data_calculate_vbmeta_digest( |
275 | slot_data, AVB_DIGEST_TYPE_SHA256, vbmeta_digest); | 275 | slot_data, AVB_DIGEST_TYPE_SHA256, vbmeta_digest); |
276 | for (n = 0; n < slot_data->num_vbmeta_images; n++) { | 276 | for (n = 0; n < slot_data->num_vbmeta_images; n++) { |
277 | total_size += slot_data->vbmeta_images[n].vbmeta_size; | 277 | total_size += slot_data->vbmeta_images[n].vbmeta_size; |
278 | } | 278 | } |
279 | if (!cmdline_append_option( | 279 | if (!cmdline_append_option( |
280 | slot_data, "androidboot.vbmeta.hash_alg", "sha256") || | 280 | slot_data, "androidboot.vbmeta.hash_alg", "sha256") || |
281 | !cmdline_append_uint64_base10( | 281 | !cmdline_append_uint64_base10( |
282 | slot_data, "androidboot.vbmeta.size", total_size) || | 282 | slot_data, "androidboot.vbmeta.size", total_size) || |
283 | !cmdline_append_hex(slot_data, | 283 | !cmdline_append_hex(slot_data, |
284 | "androidboot.vbmeta.digest", | 284 | "androidboot.vbmeta.digest", |
285 | vbmeta_digest, | 285 | vbmeta_digest, |
286 | AVB_SHA256_DIGEST_SIZE)) { | 286 | AVB_SHA256_DIGEST_SIZE)) { |
287 | ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; | 287 | ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; |
288 | goto out; | 288 | goto out; |
289 | } | 289 | } |
290 | } break; | 290 | } break; |
291 | /* Explicit fallthrough. */ | 291 | /* Explicit fallthrough. */ |
292 | case AVB_ALGORITHM_TYPE_SHA512_RSA2048: | 292 | case AVB_ALGORITHM_TYPE_SHA512_RSA2048: |
293 | case AVB_ALGORITHM_TYPE_SHA512_RSA4096: | 293 | case AVB_ALGORITHM_TYPE_SHA512_RSA4096: |
294 | case AVB_ALGORITHM_TYPE_SHA512_RSA8192: { | 294 | case AVB_ALGORITHM_TYPE_SHA512_RSA8192: { |
295 | size_t n, total_size = 0; | 295 | size_t n, total_size = 0; |
296 | uint8_t vbmeta_digest[AVB_SHA512_DIGEST_SIZE]; | 296 | uint8_t vbmeta_digest[AVB_SHA512_DIGEST_SIZE]; |
297 | avb_slot_verify_data_calculate_vbmeta_digest( | 297 | avb_slot_verify_data_calculate_vbmeta_digest( |
298 | slot_data, AVB_DIGEST_TYPE_SHA512, vbmeta_digest); | 298 | slot_data, AVB_DIGEST_TYPE_SHA512, vbmeta_digest); |
299 | for (n = 0; n < slot_data->num_vbmeta_images; n++) { | 299 | for (n = 0; n < slot_data->num_vbmeta_images; n++) { |
300 | total_size += slot_data->vbmeta_images[n].vbmeta_size; | 300 | total_size += slot_data->vbmeta_images[n].vbmeta_size; |
301 | } | 301 | } |
302 | if (!cmdline_append_option( | 302 | if (!cmdline_append_option( |
303 | slot_data, "androidboot.vbmeta.hash_alg", "sha512") || | 303 | slot_data, "androidboot.vbmeta.hash_alg", "sha512") || |
304 | !cmdline_append_uint64_base10( | 304 | !cmdline_append_uint64_base10( |
305 | slot_data, "androidboot.vbmeta.size", total_size) || | 305 | slot_data, "androidboot.vbmeta.size", total_size) || |
306 | !cmdline_append_hex(slot_data, | 306 | !cmdline_append_hex(slot_data, |
307 | "androidboot.vbmeta.digest", | 307 | "androidboot.vbmeta.digest", |
308 | vbmeta_digest, | 308 | vbmeta_digest, |
309 | AVB_SHA512_DIGEST_SIZE)) { | 309 | AVB_SHA512_DIGEST_SIZE)) { |
310 | ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; | 310 | ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; |
311 | goto out; | 311 | goto out; |
312 | } | 312 | } |
313 | } break; | 313 | } break; |
314 | case _AVB_ALGORITHM_NUM_TYPES: | 314 | case _AVB_ALGORITHM_NUM_TYPES: |
315 | avb_assert_not_reached(); | 315 | avb_assert_not_reached(); |
316 | break; | 316 | break; |
317 | } | 317 | } |
318 | 318 | ||
319 | /* Set androidboot.veritymode and androidboot.vbmeta.invalidate_on_error */ | 319 | /* Set androidboot.veritymode and androidboot.vbmeta.invalidate_on_error */ |
320 | if (toplevel_vbmeta->flags & AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED) { | 320 | if (toplevel_vbmeta->flags & AVB_VBMETA_IMAGE_FLAGS_HASHTREE_DISABLED) { |
321 | verity_mode = "disabled"; | 321 | verity_mode = "disabled"; |
322 | } else { | 322 | } else { |
323 | const char* dm_verity_mode; | 323 | const char* dm_verity_mode = NULL; |
324 | char* new_ret; | 324 | char* new_ret; |
325 | 325 | ||
326 | switch (hashtree_error_mode) { | 326 | switch (hashtree_error_mode) { |
327 | case AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE: | 327 | case AVB_HASHTREE_ERROR_MODE_RESTART_AND_INVALIDATE: |
328 | if (!cmdline_append_option( | 328 | if (!cmdline_append_option( |
329 | slot_data, "androidboot.vbmeta.invalidate_on_error", "yes")) { | 329 | slot_data, "androidboot.vbmeta.invalidate_on_error", "yes")) { |
330 | ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; | 330 | ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; |
331 | goto out; | 331 | goto out; |
332 | } | 332 | } |
333 | verity_mode = "enforcing"; | 333 | verity_mode = "enforcing"; |
334 | dm_verity_mode = "restart_on_corruption"; | 334 | dm_verity_mode = "restart_on_corruption"; |
335 | break; | 335 | break; |
336 | case AVB_HASHTREE_ERROR_MODE_RESTART: | 336 | case AVB_HASHTREE_ERROR_MODE_RESTART: |
337 | verity_mode = "enforcing"; | 337 | verity_mode = "enforcing"; |
338 | dm_verity_mode = "restart_on_corruption"; | 338 | dm_verity_mode = "restart_on_corruption"; |
339 | break; | 339 | break; |
340 | case AVB_HASHTREE_ERROR_MODE_EIO: | 340 | case AVB_HASHTREE_ERROR_MODE_EIO: |
341 | verity_mode = "eio"; | 341 | verity_mode = "eio"; |
342 | /* For now there's no option to specify the EIO mode. So | 342 | /* For now there's no option to specify the EIO mode. So |
343 | * just use 'ignore_zero_blocks' since that's already set | 343 | * just use 'ignore_zero_blocks' since that's already set |
344 | * and dm-verity-target.c supports specifying this multiple | 344 | * and dm-verity-target.c supports specifying this multiple |
345 | * times. | 345 | * times. |
346 | */ | 346 | */ |
347 | dm_verity_mode = "ignore_zero_blocks"; | 347 | dm_verity_mode = "ignore_zero_blocks"; |
348 | break; | 348 | break; |
349 | case AVB_HASHTREE_ERROR_MODE_LOGGING: | 349 | case AVB_HASHTREE_ERROR_MODE_LOGGING: |
350 | verity_mode = "logging"; | 350 | verity_mode = "logging"; |
351 | dm_verity_mode = "ignore_corruption"; | 351 | dm_verity_mode = "ignore_corruption"; |
352 | break; | 352 | break; |
353 | } | 353 | } |
354 | new_ret = avb_replace( | 354 | new_ret = avb_replace( |
355 | slot_data->cmdline, "$(ANDROID_VERITY_MODE)", dm_verity_mode); | 355 | slot_data->cmdline, "$(ANDROID_VERITY_MODE)", dm_verity_mode); |
356 | avb_free(slot_data->cmdline); | 356 | avb_free(slot_data->cmdline); |
357 | slot_data->cmdline = new_ret; | 357 | slot_data->cmdline = new_ret; |
358 | if (slot_data->cmdline == NULL) { | 358 | if (slot_data->cmdline == NULL) { |
359 | ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; | 359 | ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; |
360 | goto out; | 360 | goto out; |
361 | } | 361 | } |
362 | } | 362 | } |
363 | if (!cmdline_append_option( | 363 | if (!cmdline_append_option( |
364 | slot_data, "androidboot.veritymode", verity_mode)) { | 364 | slot_data, "androidboot.veritymode", verity_mode)) { |
365 | ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; | 365 | ret = AVB_SLOT_VERIFY_RESULT_ERROR_OOM; |
366 | goto out; | 366 | goto out; |
367 | } | 367 | } |
368 | 368 | ||
369 | ret = AVB_SLOT_VERIFY_RESULT_OK; | 369 | ret = AVB_SLOT_VERIFY_RESULT_OK; |
370 | 370 | ||
371 | out: | 371 | out: |
372 | 372 | ||
373 | return ret; | 373 | return ret; |
374 | } | 374 | } |
375 | 375 | ||
376 | AvbCmdlineSubstList* avb_new_cmdline_subst_list() { | 376 | AvbCmdlineSubstList* avb_new_cmdline_subst_list() { |
377 | return (AvbCmdlineSubstList*)avb_calloc(sizeof(AvbCmdlineSubstList)); | 377 | return (AvbCmdlineSubstList*)avb_calloc(sizeof(AvbCmdlineSubstList)); |
378 | } | 378 | } |
379 | 379 | ||
380 | void avb_free_cmdline_subst_list(AvbCmdlineSubstList* cmdline_subst) { | 380 | void avb_free_cmdline_subst_list(AvbCmdlineSubstList* cmdline_subst) { |
381 | size_t i; | 381 | size_t i; |
382 | for (i = 0; i < cmdline_subst->size; ++i) { | 382 | for (i = 0; i < cmdline_subst->size; ++i) { |
383 | avb_free(cmdline_subst->tokens[i]); | 383 | avb_free(cmdline_subst->tokens[i]); |
384 | avb_free(cmdline_subst->values[i]); | 384 | avb_free(cmdline_subst->values[i]); |
385 | } | 385 | } |
386 | cmdline_subst->size = 0; | 386 | cmdline_subst->size = 0; |
387 | avb_free(cmdline_subst); | 387 | avb_free(cmdline_subst); |
388 | } | 388 | } |
389 | 389 | ||
390 | AvbSlotVerifyResult avb_add_root_digest_substitution( | 390 | AvbSlotVerifyResult avb_add_root_digest_substitution( |
391 | const char* part_name, | 391 | const char* part_name, |
392 | const uint8_t* digest, | 392 | const uint8_t* digest, |
393 | size_t digest_size, | 393 | size_t digest_size, |
394 | AvbCmdlineSubstList* out_cmdline_subst) { | 394 | AvbCmdlineSubstList* out_cmdline_subst) { |
395 | const char* kDigestSubPrefix = "$(AVB_"; | 395 | const char* kDigestSubPrefix = "$(AVB_"; |
396 | const char* kDigestSubSuffix = "_ROOT_DIGEST)"; | 396 | const char* kDigestSubSuffix = "_ROOT_DIGEST)"; |
397 | size_t part_name_len = avb_strlen(part_name); | 397 | size_t part_name_len = avb_strlen(part_name); |
398 | size_t list_index = out_cmdline_subst->size; | 398 | size_t list_index = out_cmdline_subst->size; |
399 | 399 | ||
400 | avb_assert(part_name_len < AVB_PART_NAME_MAX_SIZE); | 400 | avb_assert(part_name_len < AVB_PART_NAME_MAX_SIZE); |
401 | avb_assert(digest_size <= AVB_SHA512_DIGEST_SIZE); | 401 | avb_assert(digest_size <= AVB_SHA512_DIGEST_SIZE); |
402 | if (part_name_len >= AVB_PART_NAME_MAX_SIZE || | 402 | if (part_name_len >= AVB_PART_NAME_MAX_SIZE || |
403 | digest_size > AVB_SHA512_DIGEST_SIZE) { | 403 | digest_size > AVB_SHA512_DIGEST_SIZE) { |
404 | return AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; | 404 | return AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; |
405 | } | 405 | } |
406 | 406 | ||
407 | if (out_cmdline_subst->size >= AVB_MAX_NUM_CMDLINE_SUBST) { | 407 | if (out_cmdline_subst->size >= AVB_MAX_NUM_CMDLINE_SUBST) { |
408 | /* The list is full. Currently dynamic growth of this list is not supported. | 408 | /* The list is full. Currently dynamic growth of this list is not supported. |
409 | */ | 409 | */ |
410 | return AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; | 410 | return AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA; |
411 | } | 411 | } |
412 | 412 | ||
413 | /* Construct the token to replace in the command line based on the partition | 413 | /* Construct the token to replace in the command line based on the partition |
414 | * name. For partition 'foo', this will be '$(AVB_FOO_ROOT_DIGEST)'. | 414 | * name. For partition 'foo', this will be '$(AVB_FOO_ROOT_DIGEST)'. |
415 | */ | 415 | */ |
416 | out_cmdline_subst->tokens[list_index] = | 416 | out_cmdline_subst->tokens[list_index] = |
417 | avb_strdupv(kDigestSubPrefix, part_name, kDigestSubSuffix, NULL); | 417 | avb_strdupv(kDigestSubPrefix, part_name, kDigestSubSuffix, NULL); |
418 | if (out_cmdline_subst->tokens[list_index] == NULL) { | 418 | if (out_cmdline_subst->tokens[list_index] == NULL) { |
419 | goto fail; | 419 | goto fail; |
420 | } | 420 | } |
421 | avb_uppercase(out_cmdline_subst->tokens[list_index]); | 421 | avb_uppercase(out_cmdline_subst->tokens[list_index]); |
422 | 422 | ||
423 | /* The digest value is hex encoded when inserted in the command line. */ | 423 | /* The digest value is hex encoded when inserted in the command line. */ |
424 | out_cmdline_subst->values[list_index] = avb_bin2hex(digest, digest_size); | 424 | out_cmdline_subst->values[list_index] = avb_bin2hex(digest, digest_size); |
425 | if (out_cmdline_subst->values[list_index] == NULL) { | 425 | if (out_cmdline_subst->values[list_index] == NULL) { |
426 | goto fail; | 426 | goto fail; |
427 | } | 427 | } |
428 | 428 | ||
429 | out_cmdline_subst->size++; | 429 | out_cmdline_subst->size++; |
430 | return AVB_SLOT_VERIFY_RESULT_OK; | 430 | return AVB_SLOT_VERIFY_RESULT_OK; |
431 | 431 | ||
432 | fail: | 432 | fail: |
433 | if (out_cmdline_subst->tokens[list_index]) { | 433 | if (out_cmdline_subst->tokens[list_index]) { |
434 | avb_free(out_cmdline_subst->tokens[list_index]); | 434 | avb_free(out_cmdline_subst->tokens[list_index]); |
435 | } | 435 | } |
436 | if (out_cmdline_subst->values[list_index]) { | 436 | if (out_cmdline_subst->values[list_index]) { |
437 | avb_free(out_cmdline_subst->values[list_index]); | 437 | avb_free(out_cmdline_subst->values[list_index]); |
438 | } | 438 | } |
439 | return AVB_SLOT_VERIFY_RESULT_ERROR_OOM; | 439 | return AVB_SLOT_VERIFY_RESULT_ERROR_OOM; |
440 | } | 440 | } |
441 | 441 |