Commit e0343ea466a651ee574e5ceeb5c522fdcb6116ab

Authored by Ji Luo
1 parent 40f95bfc01

MA-14318-1 Support dual bootloader for xen

Trusty is not supported for xen so we don't need to check
the keyslot package or rollback index in spl. Reassign the
dram address for spl and u-boot to avoid conflicts.

Support serial init functions to enable debug console
in spl when xen is running.

Test: Boot and A/B slot switch on imx8qm_mek.

Change-Id: If6829252f1ec2e32255f951715c8747181951fd0
Signed-off-by: Ji Luo <ji.luo@nxp.com>
Reviewed-by: Peng Fan <peng.fan@nxp.com>

Showing 4 changed files with 65 additions and 3 deletions Inline Diff

drivers/serial/serial.c
1 /* 1 /*
2 * (C) Copyright 2004 2 * (C) Copyright 2004
3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de. 3 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
4 * 4 *
5 * SPDX-License-Identifier: GPL-2.0+ 5 * SPDX-License-Identifier: GPL-2.0+
6 */ 6 */
7 7
8 #include <common.h> 8 #include <common.h>
9 #include <environment.h> 9 #include <environment.h>
10 #include <serial.h> 10 #include <serial.h>
11 #include <stdio_dev.h> 11 #include <stdio_dev.h>
12 #include <post.h> 12 #include <post.h>
13 #include <linux/compiler.h> 13 #include <linux/compiler.h>
14 #include <errno.h> 14 #include <errno.h>
15 15
16 DECLARE_GLOBAL_DATA_PTR; 16 DECLARE_GLOBAL_DATA_PTR;
17 17
18 static struct serial_device *serial_devices; 18 static struct serial_device *serial_devices;
19 static struct serial_device *serial_current; 19 static struct serial_device *serial_current;
20 /* 20 /*
21 * Table with supported baudrates (defined in config_xyz.h) 21 * Table with supported baudrates (defined in config_xyz.h)
22 */ 22 */
23 static const unsigned long baudrate_table[] = CONFIG_SYS_BAUDRATE_TABLE; 23 static const unsigned long baudrate_table[] = CONFIG_SYS_BAUDRATE_TABLE;
24 24
25 /** 25 /**
26 * serial_null() - Void registration routine of a serial driver 26 * serial_null() - Void registration routine of a serial driver
27 * 27 *
28 * This routine implements a void registration routine of a serial 28 * This routine implements a void registration routine of a serial
29 * driver. The registration routine of a particular driver is aliased 29 * driver. The registration routine of a particular driver is aliased
30 * to this empty function in case the driver is not compiled into 30 * to this empty function in case the driver is not compiled into
31 * U-Boot. 31 * U-Boot.
32 */ 32 */
33 static void serial_null(void) 33 static void serial_null(void)
34 { 34 {
35 } 35 }
36 36
37 /** 37 /**
38 * on_baudrate() - Update the actual baudrate when the env var changes 38 * on_baudrate() - Update the actual baudrate when the env var changes
39 * 39 *
40 * This will check for a valid baudrate and only apply it if valid. 40 * This will check for a valid baudrate and only apply it if valid.
41 */ 41 */
42 static int on_baudrate(const char *name, const char *value, enum env_op op, 42 static int on_baudrate(const char *name, const char *value, enum env_op op,
43 int flags) 43 int flags)
44 { 44 {
45 int i; 45 int i;
46 int baudrate; 46 int baudrate;
47 47
48 switch (op) { 48 switch (op) {
49 case env_op_create: 49 case env_op_create:
50 case env_op_overwrite: 50 case env_op_overwrite:
51 /* 51 /*
52 * Switch to new baudrate if new baudrate is supported 52 * Switch to new baudrate if new baudrate is supported
53 */ 53 */
54 baudrate = simple_strtoul(value, NULL, 10); 54 baudrate = simple_strtoul(value, NULL, 10);
55 55
56 /* Not actually changing */ 56 /* Not actually changing */
57 if (gd->baudrate == baudrate) 57 if (gd->baudrate == baudrate)
58 return 0; 58 return 0;
59 59
60 for (i = 0; i < ARRAY_SIZE(baudrate_table); ++i) { 60 for (i = 0; i < ARRAY_SIZE(baudrate_table); ++i) {
61 if (baudrate == baudrate_table[i]) 61 if (baudrate == baudrate_table[i])
62 break; 62 break;
63 } 63 }
64 if (i == ARRAY_SIZE(baudrate_table)) { 64 if (i == ARRAY_SIZE(baudrate_table)) {
65 if ((flags & H_FORCE) == 0) 65 if ((flags & H_FORCE) == 0)
66 printf("## Baudrate %d bps not supported\n", 66 printf("## Baudrate %d bps not supported\n",
67 baudrate); 67 baudrate);
68 return 1; 68 return 1;
69 } 69 }
70 if ((flags & H_INTERACTIVE) != 0) { 70 if ((flags & H_INTERACTIVE) != 0) {
71 printf("## Switch baudrate to %d" 71 printf("## Switch baudrate to %d"
72 " bps and press ENTER ...\n", baudrate); 72 " bps and press ENTER ...\n", baudrate);
73 udelay(50000); 73 udelay(50000);
74 } 74 }
75 75
76 gd->baudrate = baudrate; 76 gd->baudrate = baudrate;
77 77
78 serial_setbrg(); 78 serial_setbrg();
79 79
80 udelay(50000); 80 udelay(50000);
81 81
82 if ((flags & H_INTERACTIVE) != 0) 82 if ((flags & H_INTERACTIVE) != 0)
83 while (1) { 83 while (1) {
84 if (getc() == '\r') 84 if (getc() == '\r')
85 break; 85 break;
86 } 86 }
87 87
88 return 0; 88 return 0;
89 case env_op_delete: 89 case env_op_delete:
90 printf("## Baudrate may not be deleted\n"); 90 printf("## Baudrate may not be deleted\n");
91 return 1; 91 return 1;
92 default: 92 default:
93 return 0; 93 return 0;
94 } 94 }
95 } 95 }
96 U_BOOT_ENV_CALLBACK(baudrate, on_baudrate); 96 U_BOOT_ENV_CALLBACK(baudrate, on_baudrate);
97 97
98 /** 98 /**
99 * serial_initfunc() - Forward declare of driver registration routine 99 * serial_initfunc() - Forward declare of driver registration routine
100 * @name: Name of the real driver registration routine. 100 * @name: Name of the real driver registration routine.
101 * 101 *
102 * This macro expands onto forward declaration of a driver registration 102 * This macro expands onto forward declaration of a driver registration
103 * routine, which is then used below in serial_initialize() function. 103 * routine, which is then used below in serial_initialize() function.
104 * The declaration is made weak and aliases to serial_null() so in case 104 * The declaration is made weak and aliases to serial_null() so in case
105 * the driver is not compiled in, the function is still declared and can 105 * the driver is not compiled in, the function is still declared and can
106 * be used, but aliases to serial_null() and thus is optimized away. 106 * be used, but aliases to serial_null() and thus is optimized away.
107 */ 107 */
108 #define serial_initfunc(name) \ 108 #define serial_initfunc(name) \
109 void name(void) \ 109 void name(void) \
110 __attribute__((weak, alias("serial_null"))); 110 __attribute__((weak, alias("serial_null")));
111 111
112 serial_initfunc(amirix_serial_initialize); 112 serial_initfunc(amirix_serial_initialize);
113 serial_initfunc(arc_serial_initialize); 113 serial_initfunc(arc_serial_initialize);
114 serial_initfunc(arm_dcc_initialize); 114 serial_initfunc(arm_dcc_initialize);
115 serial_initfunc(asc_serial_initialize); 115 serial_initfunc(asc_serial_initialize);
116 serial_initfunc(atmel_serial_initialize); 116 serial_initfunc(atmel_serial_initialize);
117 serial_initfunc(au1x00_serial_initialize); 117 serial_initfunc(au1x00_serial_initialize);
118 serial_initfunc(bfin_jtag_initialize); 118 serial_initfunc(bfin_jtag_initialize);
119 serial_initfunc(bfin_serial_initialize); 119 serial_initfunc(bfin_serial_initialize);
120 serial_initfunc(bmw_serial_initialize); 120 serial_initfunc(bmw_serial_initialize);
121 serial_initfunc(clps7111_serial_initialize); 121 serial_initfunc(clps7111_serial_initialize);
122 serial_initfunc(cogent_serial_initialize); 122 serial_initfunc(cogent_serial_initialize);
123 serial_initfunc(cpci750_serial_initialize); 123 serial_initfunc(cpci750_serial_initialize);
124 serial_initfunc(evb64260_serial_initialize); 124 serial_initfunc(evb64260_serial_initialize);
125 serial_initfunc(imx_serial_initialize); 125 serial_initfunc(imx_serial_initialize);
126 serial_initfunc(iop480_serial_initialize); 126 serial_initfunc(iop480_serial_initialize);
127 serial_initfunc(jz_serial_initialize); 127 serial_initfunc(jz_serial_initialize);
128 serial_initfunc(leon2_serial_initialize); 128 serial_initfunc(leon2_serial_initialize);
129 serial_initfunc(leon3_serial_initialize); 129 serial_initfunc(leon3_serial_initialize);
130 serial_initfunc(lh7a40x_serial_initialize); 130 serial_initfunc(lh7a40x_serial_initialize);
131 serial_initfunc(lpc32xx_serial_initialize); 131 serial_initfunc(lpc32xx_serial_initialize);
132 serial_initfunc(marvell_serial_initialize); 132 serial_initfunc(marvell_serial_initialize);
133 serial_initfunc(max3100_serial_initialize); 133 serial_initfunc(max3100_serial_initialize);
134 serial_initfunc(mcf_serial_initialize); 134 serial_initfunc(mcf_serial_initialize);
135 serial_initfunc(ml2_serial_initialize); 135 serial_initfunc(ml2_serial_initialize);
136 serial_initfunc(mpc85xx_serial_initialize); 136 serial_initfunc(mpc85xx_serial_initialize);
137 serial_initfunc(mpc8xx_serial_initialize); 137 serial_initfunc(mpc8xx_serial_initialize);
138 serial_initfunc(mxc_serial_initialize); 138 serial_initfunc(mxc_serial_initialize);
139 serial_initfunc(xen_serial_initialize);
139 serial_initfunc(serial_lpuart_initialize); 140 serial_initfunc(serial_lpuart_initialize);
140 serial_initfunc(mxs_auart_initialize); 141 serial_initfunc(mxs_auart_initialize);
141 serial_initfunc(ns16550_serial_initialize); 142 serial_initfunc(ns16550_serial_initialize);
142 serial_initfunc(oc_serial_initialize); 143 serial_initfunc(oc_serial_initialize);
143 serial_initfunc(p3mx_serial_initialize); 144 serial_initfunc(p3mx_serial_initialize);
144 serial_initfunc(pl01x_serial_initialize); 145 serial_initfunc(pl01x_serial_initialize);
145 serial_initfunc(pxa_serial_initialize); 146 serial_initfunc(pxa_serial_initialize);
146 serial_initfunc(s3c24xx_serial_initialize); 147 serial_initfunc(s3c24xx_serial_initialize);
147 serial_initfunc(s5p_serial_initialize); 148 serial_initfunc(s5p_serial_initialize);
148 serial_initfunc(sa1100_serial_initialize); 149 serial_initfunc(sa1100_serial_initialize);
149 serial_initfunc(sandbox_serial_initialize); 150 serial_initfunc(sandbox_serial_initialize);
150 serial_initfunc(sconsole_serial_initialize); 151 serial_initfunc(sconsole_serial_initialize);
151 serial_initfunc(sh_serial_initialize); 152 serial_initfunc(sh_serial_initialize);
152 serial_initfunc(stm32_serial_initialize); 153 serial_initfunc(stm32_serial_initialize);
153 serial_initfunc(uartlite_serial_initialize); 154 serial_initfunc(uartlite_serial_initialize);
154 serial_initfunc(xen_debug_serial_initialize); 155 serial_initfunc(xen_debug_serial_initialize);
155 serial_initfunc(zynq_serial_initialize); 156 serial_initfunc(zynq_serial_initialize);
156 157
157 /** 158 /**
158 * serial_register() - Register serial driver with serial driver core 159 * serial_register() - Register serial driver with serial driver core
159 * @dev: Pointer to the serial driver structure 160 * @dev: Pointer to the serial driver structure
160 * 161 *
161 * This function registers the serial driver supplied via @dev with 162 * This function registers the serial driver supplied via @dev with
162 * serial driver core, thus making U-Boot aware of it and making it 163 * serial driver core, thus making U-Boot aware of it and making it
163 * available for U-Boot to use. On platforms that still require manual 164 * available for U-Boot to use. On platforms that still require manual
164 * relocation of constant variables, relocation of the supplied structure 165 * relocation of constant variables, relocation of the supplied structure
165 * is performed. 166 * is performed.
166 */ 167 */
167 void serial_register(struct serial_device *dev) 168 void serial_register(struct serial_device *dev)
168 { 169 {
169 #ifdef CONFIG_NEEDS_MANUAL_RELOC 170 #ifdef CONFIG_NEEDS_MANUAL_RELOC
170 if (dev->start) 171 if (dev->start)
171 dev->start += gd->reloc_off; 172 dev->start += gd->reloc_off;
172 if (dev->stop) 173 if (dev->stop)
173 dev->stop += gd->reloc_off; 174 dev->stop += gd->reloc_off;
174 if (dev->setbrg) 175 if (dev->setbrg)
175 dev->setbrg += gd->reloc_off; 176 dev->setbrg += gd->reloc_off;
176 if (dev->getc) 177 if (dev->getc)
177 dev->getc += gd->reloc_off; 178 dev->getc += gd->reloc_off;
178 if (dev->tstc) 179 if (dev->tstc)
179 dev->tstc += gd->reloc_off; 180 dev->tstc += gd->reloc_off;
180 if (dev->putc) 181 if (dev->putc)
181 dev->putc += gd->reloc_off; 182 dev->putc += gd->reloc_off;
182 if (dev->puts) 183 if (dev->puts)
183 dev->puts += gd->reloc_off; 184 dev->puts += gd->reloc_off;
184 #endif 185 #endif
185 186
186 dev->next = serial_devices; 187 dev->next = serial_devices;
187 serial_devices = dev; 188 serial_devices = dev;
188 } 189 }
189 190
190 /** 191 /**
191 * serial_initialize() - Register all compiled-in serial port drivers 192 * serial_initialize() - Register all compiled-in serial port drivers
192 * 193 *
193 * This function registers all serial port drivers that are compiled 194 * This function registers all serial port drivers that are compiled
194 * into the U-Boot binary with the serial core, thus making them 195 * into the U-Boot binary with the serial core, thus making them
195 * available to U-Boot to use. Lastly, this function assigns a default 196 * available to U-Boot to use. Lastly, this function assigns a default
196 * serial port to the serial core. That serial port is then used as a 197 * serial port to the serial core. That serial port is then used as a
197 * default output. 198 * default output.
198 */ 199 */
199 void serial_initialize(void) 200 void serial_initialize(void)
200 { 201 {
201 amirix_serial_initialize(); 202 amirix_serial_initialize();
202 arc_serial_initialize(); 203 arc_serial_initialize();
203 arm_dcc_initialize(); 204 arm_dcc_initialize();
204 asc_serial_initialize(); 205 asc_serial_initialize();
205 atmel_serial_initialize(); 206 atmel_serial_initialize();
206 au1x00_serial_initialize(); 207 au1x00_serial_initialize();
207 bfin_jtag_initialize(); 208 bfin_jtag_initialize();
208 bfin_serial_initialize(); 209 bfin_serial_initialize();
209 bmw_serial_initialize(); 210 bmw_serial_initialize();
210 clps7111_serial_initialize(); 211 clps7111_serial_initialize();
211 cogent_serial_initialize(); 212 cogent_serial_initialize();
212 cpci750_serial_initialize(); 213 cpci750_serial_initialize();
213 evb64260_serial_initialize(); 214 evb64260_serial_initialize();
214 imx_serial_initialize(); 215 imx_serial_initialize();
215 iop480_serial_initialize(); 216 iop480_serial_initialize();
216 jz_serial_initialize(); 217 jz_serial_initialize();
217 leon2_serial_initialize(); 218 leon2_serial_initialize();
218 leon3_serial_initialize(); 219 leon3_serial_initialize();
219 lh7a40x_serial_initialize(); 220 lh7a40x_serial_initialize();
220 lpc32xx_serial_initialize(); 221 lpc32xx_serial_initialize();
221 marvell_serial_initialize(); 222 marvell_serial_initialize();
222 max3100_serial_initialize(); 223 max3100_serial_initialize();
223 mcf_serial_initialize(); 224 mcf_serial_initialize();
224 ml2_serial_initialize(); 225 ml2_serial_initialize();
225 mpc85xx_serial_initialize(); 226 mpc85xx_serial_initialize();
226 mpc8xx_serial_initialize(); 227 mpc8xx_serial_initialize();
227 mxc_serial_initialize(); 228 mxc_serial_initialize();
229 xen_serial_initialize();
228 serial_lpuart_initialize(); 230 serial_lpuart_initialize();
229 mxs_auart_initialize(); 231 mxs_auart_initialize();
230 ns16550_serial_initialize(); 232 ns16550_serial_initialize();
231 oc_serial_initialize(); 233 oc_serial_initialize();
232 p3mx_serial_initialize(); 234 p3mx_serial_initialize();
233 pl01x_serial_initialize(); 235 pl01x_serial_initialize();
234 pxa_serial_initialize(); 236 pxa_serial_initialize();
235 s3c24xx_serial_initialize(); 237 s3c24xx_serial_initialize();
236 s5p_serial_initialize(); 238 s5p_serial_initialize();
237 sa1100_serial_initialize(); 239 sa1100_serial_initialize();
238 sandbox_serial_initialize(); 240 sandbox_serial_initialize();
239 sconsole_serial_initialize(); 241 sconsole_serial_initialize();
240 sh_serial_initialize(); 242 sh_serial_initialize();
241 stm32_serial_initialize(); 243 stm32_serial_initialize();
242 uartlite_serial_initialize(); 244 uartlite_serial_initialize();
243 xen_debug_serial_initialize(); 245 xen_debug_serial_initialize();
244 zynq_serial_initialize(); 246 zynq_serial_initialize();
245 247
246 serial_assign(default_serial_console()->name); 248 serial_assign(default_serial_console()->name);
247 } 249 }
248 250
249 static int serial_stub_start(struct stdio_dev *sdev) 251 static int serial_stub_start(struct stdio_dev *sdev)
250 { 252 {
251 struct serial_device *dev = sdev->priv; 253 struct serial_device *dev = sdev->priv;
252 254
253 return dev->start(); 255 return dev->start();
254 } 256 }
255 257
256 static int serial_stub_stop(struct stdio_dev *sdev) 258 static int serial_stub_stop(struct stdio_dev *sdev)
257 { 259 {
258 struct serial_device *dev = sdev->priv; 260 struct serial_device *dev = sdev->priv;
259 261
260 return dev->stop(); 262 return dev->stop();
261 } 263 }
262 264
263 static void serial_stub_putc(struct stdio_dev *sdev, const char ch) 265 static void serial_stub_putc(struct stdio_dev *sdev, const char ch)
264 { 266 {
265 struct serial_device *dev = sdev->priv; 267 struct serial_device *dev = sdev->priv;
266 268
267 dev->putc(ch); 269 dev->putc(ch);
268 } 270 }
269 271
270 static void serial_stub_puts(struct stdio_dev *sdev, const char *str) 272 static void serial_stub_puts(struct stdio_dev *sdev, const char *str)
271 { 273 {
272 struct serial_device *dev = sdev->priv; 274 struct serial_device *dev = sdev->priv;
273 275
274 dev->puts(str); 276 dev->puts(str);
275 } 277 }
276 278
277 static int serial_stub_getc(struct stdio_dev *sdev) 279 static int serial_stub_getc(struct stdio_dev *sdev)
278 { 280 {
279 struct serial_device *dev = sdev->priv; 281 struct serial_device *dev = sdev->priv;
280 282
281 return dev->getc(); 283 return dev->getc();
282 } 284 }
283 285
284 static int serial_stub_tstc(struct stdio_dev *sdev) 286 static int serial_stub_tstc(struct stdio_dev *sdev)
285 { 287 {
286 struct serial_device *dev = sdev->priv; 288 struct serial_device *dev = sdev->priv;
287 289
288 return dev->tstc(); 290 return dev->tstc();
289 } 291 }
290 292
291 /** 293 /**
292 * serial_stdio_init() - Register serial ports with STDIO core 294 * serial_stdio_init() - Register serial ports with STDIO core
293 * 295 *
294 * This function generates a proxy driver for each serial port driver. 296 * This function generates a proxy driver for each serial port driver.
295 * These proxy drivers then register with the STDIO core, making the 297 * These proxy drivers then register with the STDIO core, making the
296 * serial drivers available as STDIO devices. 298 * serial drivers available as STDIO devices.
297 */ 299 */
298 void serial_stdio_init(void) 300 void serial_stdio_init(void)
299 { 301 {
300 struct stdio_dev dev; 302 struct stdio_dev dev;
301 struct serial_device *s = serial_devices; 303 struct serial_device *s = serial_devices;
302 304
303 while (s) { 305 while (s) {
304 memset(&dev, 0, sizeof(dev)); 306 memset(&dev, 0, sizeof(dev));
305 307
306 strcpy(dev.name, s->name); 308 strcpy(dev.name, s->name);
307 dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT; 309 dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT;
308 310
309 dev.start = serial_stub_start; 311 dev.start = serial_stub_start;
310 dev.stop = serial_stub_stop; 312 dev.stop = serial_stub_stop;
311 dev.putc = serial_stub_putc; 313 dev.putc = serial_stub_putc;
312 dev.puts = serial_stub_puts; 314 dev.puts = serial_stub_puts;
313 dev.getc = serial_stub_getc; 315 dev.getc = serial_stub_getc;
314 dev.tstc = serial_stub_tstc; 316 dev.tstc = serial_stub_tstc;
315 dev.priv = s; 317 dev.priv = s;
316 318
317 stdio_register(&dev); 319 stdio_register(&dev);
318 320
319 s = s->next; 321 s = s->next;
320 } 322 }
321 } 323 }
322 324
323 /** 325 /**
324 * serial_assign() - Select the serial output device by name 326 * serial_assign() - Select the serial output device by name
325 * @name: Name of the serial driver to be used as default output 327 * @name: Name of the serial driver to be used as default output
326 * 328 *
327 * This function configures the serial output multiplexing by 329 * This function configures the serial output multiplexing by
328 * selecting which serial device will be used as default. In case 330 * selecting which serial device will be used as default. In case
329 * the STDIO "serial" device is selected as stdin/stdout/stderr, 331 * the STDIO "serial" device is selected as stdin/stdout/stderr,
330 * the serial device previously configured by this function will be 332 * the serial device previously configured by this function will be
331 * used for the particular operation. 333 * used for the particular operation.
332 * 334 *
333 * Returns 0 on success, negative on error. 335 * Returns 0 on success, negative on error.
334 */ 336 */
335 int serial_assign(const char *name) 337 int serial_assign(const char *name)
336 { 338 {
337 struct serial_device *s; 339 struct serial_device *s;
338 340
339 for (s = serial_devices; s; s = s->next) { 341 for (s = serial_devices; s; s = s->next) {
340 if (strcmp(s->name, name)) 342 if (strcmp(s->name, name))
341 continue; 343 continue;
342 serial_current = s; 344 serial_current = s;
343 return 0; 345 return 0;
344 } 346 }
345 347
346 return -EINVAL; 348 return -EINVAL;
347 } 349 }
348 350
349 /** 351 /**
350 * serial_reinit_all() - Reinitialize all compiled-in serial ports 352 * serial_reinit_all() - Reinitialize all compiled-in serial ports
351 * 353 *
352 * This function reinitializes all serial ports that are compiled 354 * This function reinitializes all serial ports that are compiled
353 * into U-Boot by calling their serial_start() functions. 355 * into U-Boot by calling their serial_start() functions.
354 */ 356 */
355 void serial_reinit_all(void) 357 void serial_reinit_all(void)
356 { 358 {
357 struct serial_device *s; 359 struct serial_device *s;
358 360
359 for (s = serial_devices; s; s = s->next) 361 for (s = serial_devices; s; s = s->next)
360 s->start(); 362 s->start();
361 } 363 }
362 364
363 /** 365 /**
364 * get_current() - Return pointer to currently selected serial port 366 * get_current() - Return pointer to currently selected serial port
365 * 367 *
366 * This function returns a pointer to currently selected serial port. 368 * This function returns a pointer to currently selected serial port.
367 * The currently selected serial port is altered by serial_assign() 369 * The currently selected serial port is altered by serial_assign()
368 * function. 370 * function.
369 * 371 *
370 * In case this function is called before relocation or before any serial 372 * In case this function is called before relocation or before any serial
371 * port is configured, this function calls default_serial_console() to 373 * port is configured, this function calls default_serial_console() to
372 * determine the serial port. Otherwise, the configured serial port is 374 * determine the serial port. Otherwise, the configured serial port is
373 * returned. 375 * returned.
374 * 376 *
375 * Returns pointer to the currently selected serial port on success, 377 * Returns pointer to the currently selected serial port on success,
376 * NULL on error. 378 * NULL on error.
377 */ 379 */
378 static struct serial_device *get_current(void) 380 static struct serial_device *get_current(void)
379 { 381 {
380 struct serial_device *dev; 382 struct serial_device *dev;
381 383
382 if (!(gd->flags & GD_FLG_RELOC)) 384 if (!(gd->flags & GD_FLG_RELOC))
383 dev = default_serial_console(); 385 dev = default_serial_console();
384 else if (!serial_current) 386 else if (!serial_current)
385 dev = default_serial_console(); 387 dev = default_serial_console();
386 else 388 else
387 dev = serial_current; 389 dev = serial_current;
388 390
389 /* We must have a console device */ 391 /* We must have a console device */
390 if (!dev) { 392 if (!dev) {
391 #ifdef CONFIG_SPL_BUILD 393 #ifdef CONFIG_SPL_BUILD
392 puts("Cannot find console\n"); 394 puts("Cannot find console\n");
393 hang(); 395 hang();
394 #else 396 #else
395 panic("Cannot find console\n"); 397 panic("Cannot find console\n");
396 #endif 398 #endif
397 } 399 }
398 400
399 return dev; 401 return dev;
400 } 402 }
401 403
402 /** 404 /**
403 * serial_init() - Initialize currently selected serial port 405 * serial_init() - Initialize currently selected serial port
404 * 406 *
405 * This function initializes the currently selected serial port. This 407 * This function initializes the currently selected serial port. This
406 * usually involves setting up the registers of that particular port, 408 * usually involves setting up the registers of that particular port,
407 * enabling clock and such. This function uses the get_current() call 409 * enabling clock and such. This function uses the get_current() call
408 * to determine which port is selected. 410 * to determine which port is selected.
409 * 411 *
410 * Returns 0 on success, negative on error. 412 * Returns 0 on success, negative on error.
411 */ 413 */
412 int serial_init(void) 414 int serial_init(void)
413 { 415 {
414 gd->flags |= GD_FLG_SERIAL_READY; 416 gd->flags |= GD_FLG_SERIAL_READY;
415 return get_current()->start(); 417 return get_current()->start();
416 } 418 }
417 419
418 /** 420 /**
419 * serial_setbrg() - Configure baud-rate of currently selected serial port 421 * serial_setbrg() - Configure baud-rate of currently selected serial port
420 * 422 *
421 * This function configures the baud-rate of the currently selected 423 * This function configures the baud-rate of the currently selected
422 * serial port. The baud-rate is retrieved from global data within 424 * serial port. The baud-rate is retrieved from global data within
423 * the serial port driver. This function uses the get_current() call 425 * the serial port driver. This function uses the get_current() call
424 * to determine which port is selected. 426 * to determine which port is selected.
425 * 427 *
426 * Returns 0 on success, negative on error. 428 * Returns 0 on success, negative on error.
427 */ 429 */
428 void serial_setbrg(void) 430 void serial_setbrg(void)
429 { 431 {
430 get_current()->setbrg(); 432 get_current()->setbrg();
431 } 433 }
432 434
433 /** 435 /**
434 * serial_getc() - Read character from currently selected serial port 436 * serial_getc() - Read character from currently selected serial port
435 * 437 *
436 * This function retrieves a character from currently selected serial 438 * This function retrieves a character from currently selected serial
437 * port. In case there is no character waiting on the serial port, 439 * port. In case there is no character waiting on the serial port,
438 * this function will block and wait for the character to appear. This 440 * this function will block and wait for the character to appear. This
439 * function uses the get_current() call to determine which port is 441 * function uses the get_current() call to determine which port is
440 * selected. 442 * selected.
441 * 443 *
442 * Returns the character on success, negative on error. 444 * Returns the character on success, negative on error.
443 */ 445 */
444 int serial_getc(void) 446 int serial_getc(void)
445 { 447 {
446 return get_current()->getc(); 448 return get_current()->getc();
447 } 449 }
448 450
449 /** 451 /**
450 * serial_tstc() - Test if data is available on currently selected serial port 452 * serial_tstc() - Test if data is available on currently selected serial port
451 * 453 *
452 * This function tests if one or more characters are available on 454 * This function tests if one or more characters are available on
453 * currently selected serial port. This function never blocks. This 455 * currently selected serial port. This function never blocks. This
454 * function uses the get_current() call to determine which port is 456 * function uses the get_current() call to determine which port is
455 * selected. 457 * selected.
456 * 458 *
457 * Returns positive if character is available, zero otherwise. 459 * Returns positive if character is available, zero otherwise.
458 */ 460 */
459 int serial_tstc(void) 461 int serial_tstc(void)
460 { 462 {
461 return get_current()->tstc(); 463 return get_current()->tstc();
462 } 464 }
463 465
464 /** 466 /**
465 * serial_putc() - Output character via currently selected serial port 467 * serial_putc() - Output character via currently selected serial port
466 * @c: Single character to be output from the serial port. 468 * @c: Single character to be output from the serial port.
467 * 469 *
468 * This function outputs a character via currently selected serial 470 * This function outputs a character via currently selected serial
469 * port. This character is passed to the serial port driver responsible 471 * port. This character is passed to the serial port driver responsible
470 * for controlling the hardware. The hardware may still be in process 472 * for controlling the hardware. The hardware may still be in process
471 * of transmitting another character, therefore this function may block 473 * of transmitting another character, therefore this function may block
472 * for a short amount of time. This function uses the get_current() 474 * for a short amount of time. This function uses the get_current()
473 * call to determine which port is selected. 475 * call to determine which port is selected.
474 */ 476 */
475 void serial_putc(const char c) 477 void serial_putc(const char c)
476 { 478 {
477 get_current()->putc(c); 479 get_current()->putc(c);
478 } 480 }
479 481
480 /** 482 /**
481 * serial_puts() - Output string via currently selected serial port 483 * serial_puts() - Output string via currently selected serial port
482 * @s: Zero-terminated string to be output from the serial port. 484 * @s: Zero-terminated string to be output from the serial port.
483 * 485 *
484 * This function outputs a zero-terminated string via currently 486 * This function outputs a zero-terminated string via currently
485 * selected serial port. This function behaves as an accelerator 487 * selected serial port. This function behaves as an accelerator
486 * in case the hardware can queue multiple characters for transfer. 488 * in case the hardware can queue multiple characters for transfer.
487 * The whole string that is to be output is available to the function 489 * The whole string that is to be output is available to the function
488 * implementing the hardware manipulation. Transmitting the whole 490 * implementing the hardware manipulation. Transmitting the whole
489 * string may take some time, thus this function may block for some 491 * string may take some time, thus this function may block for some
490 * amount of time. This function uses the get_current() call to 492 * amount of time. This function uses the get_current() call to
491 * determine which port is selected. 493 * determine which port is selected.
492 */ 494 */
493 void serial_puts(const char *s) 495 void serial_puts(const char *s)
494 { 496 {
495 get_current()->puts(s); 497 get_current()->puts(s);
496 } 498 }
497 499
498 /** 500 /**
499 * default_serial_puts() - Output string by calling serial_putc() in loop 501 * default_serial_puts() - Output string by calling serial_putc() in loop
500 * @s: Zero-terminated string to be output from the serial port. 502 * @s: Zero-terminated string to be output from the serial port.
501 * 503 *
502 * This function outputs a zero-terminated string by calling serial_putc() 504 * This function outputs a zero-terminated string by calling serial_putc()
503 * in a loop. Most drivers do not support queueing more than one byte for 505 * in a loop. Most drivers do not support queueing more than one byte for
504 * transfer, thus this function precisely implements their serial_puts(). 506 * transfer, thus this function precisely implements their serial_puts().
505 * 507 *
506 * To optimize the number of get_current() calls, this function only 508 * To optimize the number of get_current() calls, this function only
507 * calls get_current() once and then directly accesses the putc() call 509 * calls get_current() once and then directly accesses the putc() call
508 * of the &struct serial_device . 510 * of the &struct serial_device .
509 */ 511 */
510 void default_serial_puts(const char *s) 512 void default_serial_puts(const char *s)
511 { 513 {
512 struct serial_device *dev = get_current(); 514 struct serial_device *dev = get_current();
513 while (*s) 515 while (*s)
514 dev->putc(*s++); 516 dev->putc(*s++);
515 } 517 }
516 518
517 #if CONFIG_POST & CONFIG_SYS_POST_UART 519 #if CONFIG_POST & CONFIG_SYS_POST_UART
518 static const int bauds[] = CONFIG_SYS_BAUDRATE_TABLE; 520 static const int bauds[] = CONFIG_SYS_BAUDRATE_TABLE;
519 521
520 /** 522 /**
521 * uart_post_test() - Test the currently selected serial port using POST 523 * uart_post_test() - Test the currently selected serial port using POST
522 * @flags: POST framework flags 524 * @flags: POST framework flags
523 * 525 *
524 * Do a loopback test of the currently selected serial port. This 526 * Do a loopback test of the currently selected serial port. This
525 * function is only useful in the context of the POST testing framwork. 527 * function is only useful in the context of the POST testing framwork.
526 * The serial port is first configured into loopback mode and then 528 * The serial port is first configured into loopback mode and then
527 * characters are sent through it. 529 * characters are sent through it.
528 * 530 *
529 * Returns 0 on success, value otherwise. 531 * Returns 0 on success, value otherwise.
530 */ 532 */
531 /* Mark weak until post/cpu/.../uart.c migrate over */ 533 /* Mark weak until post/cpu/.../uart.c migrate over */
532 __weak 534 __weak
533 int uart_post_test(int flags) 535 int uart_post_test(int flags)
534 { 536 {
535 unsigned char c; 537 unsigned char c;
536 int ret, saved_baud, b; 538 int ret, saved_baud, b;
537 struct serial_device *saved_dev, *s; 539 struct serial_device *saved_dev, *s;
538 540
539 /* Save current serial state */ 541 /* Save current serial state */
540 ret = 0; 542 ret = 0;
541 saved_dev = serial_current; 543 saved_dev = serial_current;
542 saved_baud = gd->baudrate; 544 saved_baud = gd->baudrate;
543 545
544 for (s = serial_devices; s; s = s->next) { 546 for (s = serial_devices; s; s = s->next) {
545 /* If this driver doesn't support loop back, skip it */ 547 /* If this driver doesn't support loop back, skip it */
546 if (!s->loop) 548 if (!s->loop)
547 continue; 549 continue;
548 550
549 /* Test the next device */ 551 /* Test the next device */
550 serial_current = s; 552 serial_current = s;
551 553
552 ret = serial_init(); 554 ret = serial_init();
553 if (ret) 555 if (ret)
554 goto done; 556 goto done;
555 557
556 /* Consume anything that happens to be queued */ 558 /* Consume anything that happens to be queued */
557 while (serial_tstc()) 559 while (serial_tstc())
558 serial_getc(); 560 serial_getc();
559 561
560 /* Enable loop back */ 562 /* Enable loop back */
561 s->loop(1); 563 s->loop(1);
562 564
563 /* Test every available baud rate */ 565 /* Test every available baud rate */
564 for (b = 0; b < ARRAY_SIZE(bauds); ++b) { 566 for (b = 0; b < ARRAY_SIZE(bauds); ++b) {
565 gd->baudrate = bauds[b]; 567 gd->baudrate = bauds[b];
566 serial_setbrg(); 568 serial_setbrg();
567 569
568 /* 570 /*
569 * Stick to printable chars to avoid issues: 571 * Stick to printable chars to avoid issues:
570 * - terminal corruption 572 * - terminal corruption
571 * - serial program reacting to sequences and sending 573 * - serial program reacting to sequences and sending
572 * back random extra data 574 * back random extra data
573 * - most serial drivers add in extra chars (like \r\n) 575 * - most serial drivers add in extra chars (like \r\n)
574 */ 576 */
575 for (c = 0x20; c < 0x7f; ++c) { 577 for (c = 0x20; c < 0x7f; ++c) {
576 /* Send it out */ 578 /* Send it out */
577 serial_putc(c); 579 serial_putc(c);
578 580
579 /* Make sure it's the same one */ 581 /* Make sure it's the same one */
580 ret = (c != serial_getc()); 582 ret = (c != serial_getc());
581 if (ret) { 583 if (ret) {
582 s->loop(0); 584 s->loop(0);
583 goto done; 585 goto done;
584 } 586 }
585 587
586 /* Clean up the output in case it was sent */ 588 /* Clean up the output in case it was sent */
587 serial_putc('\b'); 589 serial_putc('\b');
588 ret = ('\b' != serial_getc()); 590 ret = ('\b' != serial_getc());
589 if (ret) { 591 if (ret) {
590 s->loop(0); 592 s->loop(0);
591 goto done; 593 goto done;
592 } 594 }
593 } 595 }
594 } 596 }
595 597
596 /* Disable loop back */ 598 /* Disable loop back */
597 s->loop(0); 599 s->loop(0);
598 600
599 /* XXX: There is no serial_stop() !? */ 601 /* XXX: There is no serial_stop() !? */
600 if (s->stop) 602 if (s->stop)
601 s->stop(); 603 s->stop();
602 } 604 }
603 605
604 done: 606 done:
605 /* Restore previous serial state */ 607 /* Restore previous serial state */
606 serial_current = saved_dev; 608 serial_current = saved_dev;
607 gd->baudrate = saved_baud; 609 gd->baudrate = saved_baud;
608 serial_reinit_all(); 610 serial_reinit_all();
609 serial_setbrg(); 611 serial_setbrg();
610 612
611 return ret; 613 return ret;
612 } 614 }
613 #endif 615 #endif
614 616
drivers/serial/serial_xen.c
1 /* 1 /*
2 * Copyright 2018 NXP 2 * Copyright 2018 NXP
3 * 3 *
4 * SPDX-License-Identifier: GPL-2.0+ 4 * SPDX-License-Identifier: GPL-2.0+
5 */ 5 */
6 6
7 #include <common.h> 7 #include <common.h>
8 #include <debug_uart.h> 8 #include <debug_uart.h>
9 #include <dm.h> 9 #include <dm.h>
10 #include <errno.h> 10 #include <errno.h>
11 #include <fdtdec.h> 11 #include <fdtdec.h>
12 #include <linux/compiler.h> 12 #include <linux/compiler.h>
13 #include <serial.h> 13 #include <serial.h>
14 14
15 #include <xen/events.h> 15 #include <xen/events.h>
16 #include <xen/hvm.h> 16 #include <xen/hvm.h>
17 #include <xen/interface/sched.h> 17 #include <xen/interface/sched.h>
18 #include <xen/interface/hvm/hvm_op.h> 18 #include <xen/interface/hvm/hvm_op.h>
19 #include <xen/interface/hvm/params.h> 19 #include <xen/interface/hvm/params.h>
20 #include <xen/interface/io/console.h> 20 #include <xen/interface/io/console.h>
21 #include <xen/interface/io/ring.h> 21 #include <xen/interface/io/ring.h>
22 22
23 DECLARE_GLOBAL_DATA_PTR; 23 DECLARE_GLOBAL_DATA_PTR;
24 24
25 #ifdef CONFIG_DM_SERIAL 25 #ifdef CONFIG_DM_SERIAL
26 struct xen_uart_priv { 26 struct xen_uart_priv {
27 struct xencons_interface *intf; 27 struct xencons_interface *intf;
28 u32 evtchn; 28 u32 evtchn;
29 int vtermno; 29 int vtermno;
30 struct hvc_struct *hvc; 30 struct hvc_struct *hvc;
31 grant_ref_t gntref; 31 grant_ref_t gntref;
32 }; 32 };
33 33
34 int xen_serial_setbrg(struct udevice *dev, int baudrate) 34 int xen_serial_setbrg(struct udevice *dev, int baudrate)
35 { 35 {
36 return 0; 36 return 0;
37 } 37 }
38 38
39 static int xen_serial_probe(struct udevice *dev) 39 static int xen_serial_probe(struct udevice *dev)
40 { 40 {
41 struct xen_uart_priv *priv = dev_get_priv(dev); 41 struct xen_uart_priv *priv = dev_get_priv(dev);
42 u64 v = 0; 42 u64 v = 0;
43 unsigned long gfn; 43 unsigned long gfn;
44 int r; 44 int r;
45 45
46 r = hvm_get_parameter(HVM_PARAM_CONSOLE_EVTCHN, &v); 46 r = hvm_get_parameter(HVM_PARAM_CONSOLE_EVTCHN, &v);
47 if (r < 0 || v == 0) 47 if (r < 0 || v == 0)
48 return r; 48 return r;
49 49
50 priv->evtchn = v; 50 priv->evtchn = v;
51 51
52 r = hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, &v); 52 r = hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, &v);
53 if (r < 0 || v == 0) 53 if (r < 0 || v == 0)
54 return -ENODEV; 54 return -ENODEV;
55 55
56 gfn = v; 56 gfn = v;
57 57
58 priv->intf = (struct xencons_interface *)(gfn << XEN_PAGE_SHIFT); 58 priv->intf = (struct xencons_interface *)(gfn << XEN_PAGE_SHIFT);
59 if (!priv->intf) 59 if (!priv->intf)
60 return -EINVAL; 60 return -EINVAL;
61 61
62 return 0; 62 return 0;
63 } 63 }
64 64
65 static int xen_serial_pending(struct udevice *dev, bool input) 65 static int xen_serial_pending(struct udevice *dev, bool input)
66 { 66 {
67 struct xen_uart_priv *priv = dev_get_priv(dev); 67 struct xen_uart_priv *priv = dev_get_priv(dev);
68 struct xencons_interface *intf = priv->intf; 68 struct xencons_interface *intf = priv->intf;
69 69
70 if (!input || intf->in_cons == intf->in_prod) 70 if (!input || intf->in_cons == intf->in_prod)
71 return 0; 71 return 0;
72 72
73 return 1; 73 return 1;
74 } 74 }
75 75
76 static int xen_serial_getc(struct udevice *dev) 76 static int xen_serial_getc(struct udevice *dev)
77 { 77 {
78 struct xen_uart_priv *priv = dev_get_priv(dev); 78 struct xen_uart_priv *priv = dev_get_priv(dev);
79 struct xencons_interface *intf = priv->intf; 79 struct xencons_interface *intf = priv->intf;
80 XENCONS_RING_IDX cons; 80 XENCONS_RING_IDX cons;
81 char c; 81 char c;
82 82
83 while (intf->in_cons == intf->in_prod) { 83 while (intf->in_cons == intf->in_prod) {
84 mb(); /* wait */ 84 mb(); /* wait */
85 } 85 }
86 86
87 cons = intf->in_cons; 87 cons = intf->in_cons;
88 mb(); /* get pointers before reading ring */ 88 mb(); /* get pointers before reading ring */
89 89
90 c = intf->in[MASK_XENCONS_IDX(cons++, intf->in)]; 90 c = intf->in[MASK_XENCONS_IDX(cons++, intf->in)];
91 91
92 mb(); /* read ring before consuming */ 92 mb(); /* read ring before consuming */
93 intf->in_cons = cons; 93 intf->in_cons = cons;
94 94
95 notify_remote_via_evtchn(priv->evtchn); 95 notify_remote_via_evtchn(priv->evtchn);
96 96
97 return c; 97 return c;
98 } 98 }
99 99
100 static int __write_console(struct udevice *dev, const char *data, int len) 100 static int __write_console(struct udevice *dev, const char *data, int len)
101 { 101 {
102 struct xen_uart_priv *priv = dev_get_priv(dev); 102 struct xen_uart_priv *priv = dev_get_priv(dev);
103 struct xencons_interface *intf = priv->intf; 103 struct xencons_interface *intf = priv->intf;
104 XENCONS_RING_IDX cons, prod; 104 XENCONS_RING_IDX cons, prod;
105 int sent = 0; 105 int sent = 0;
106 106
107 cons = intf->out_cons; 107 cons = intf->out_cons;
108 prod = intf->out_prod; 108 prod = intf->out_prod;
109 mb(); /* Update pointer */ 109 mb(); /* Update pointer */
110 110
111 WARN_ON((prod - cons) > sizeof(intf->out)); 111 WARN_ON((prod - cons) > sizeof(intf->out));
112 112
113 while ((sent < len) && ((prod - cons) < sizeof(intf->out))) 113 while ((sent < len) && ((prod - cons) < sizeof(intf->out)))
114 intf->out[MASK_XENCONS_IDX(prod++, intf->out)] = data[sent++]; 114 intf->out[MASK_XENCONS_IDX(prod++, intf->out)] = data[sent++];
115 115
116 mb(); /* Update data before pointer */ 116 mb(); /* Update data before pointer */
117 intf->out_prod = prod; 117 intf->out_prod = prod;
118 118
119 if (sent) 119 if (sent)
120 notify_remote_via_evtchn(priv->evtchn); 120 notify_remote_via_evtchn(priv->evtchn);
121 121
122 if (data[sent - 1] == '\n') 122 if (data[sent - 1] == '\n')
123 serial_puts("\r"); 123 serial_puts("\r");
124 124
125 return sent; 125 return sent;
126 } 126 }
127 127
128 static int write_console(struct udevice *dev, const char *data, int len) 128 static int write_console(struct udevice *dev, const char *data, int len)
129 { 129 {
130 /* 130 /*
131 * Make sure the whole buffer is emitted, polling if 131 * Make sure the whole buffer is emitted, polling if
132 * necessary. We don't ever want to rely on the hvc daemon 132 * necessary. We don't ever want to rely on the hvc daemon
133 * because the most interesting console output is when the 133 * because the most interesting console output is when the
134 * kernel is crippled. 134 * kernel is crippled.
135 */ 135 */
136 while (len) { 136 while (len) {
137 int sent = __write_console(dev, data, len); 137 int sent = __write_console(dev, data, len);
138 138
139 data += sent; 139 data += sent;
140 len -= sent; 140 len -= sent;
141 141
142 if (unlikely(len)) 142 if (unlikely(len))
143 HYPERVISOR_sched_op(SCHEDOP_yield, NULL); 143 HYPERVISOR_sched_op(SCHEDOP_yield, NULL);
144 } 144 }
145 145
146 return 0; 146 return 0;
147 } 147 }
148 148
149 static int xen_serial_puts(struct udevice *dev, const char *str) 149 static int xen_serial_puts(struct udevice *dev, const char *str)
150 { 150 {
151 write_console(dev, str, strlen(str)); 151 write_console(dev, str, strlen(str));
152 152
153 return 0; 153 return 0;
154 } 154 }
155 155
156 static int xen_serial_putc(struct udevice *dev, const char ch) 156 static int xen_serial_putc(struct udevice *dev, const char ch)
157 { 157 {
158 write_console(dev, &ch, 1); 158 write_console(dev, &ch, 1);
159 159
160 return 0; 160 return 0;
161 } 161 }
162 162
163 static const struct dm_serial_ops xen_serial_ops = { 163 static const struct dm_serial_ops xen_serial_ops = {
164 .puts = xen_serial_puts, 164 .puts = xen_serial_puts,
165 .putc = xen_serial_putc, 165 .putc = xen_serial_putc,
166 .getc = xen_serial_getc, 166 .getc = xen_serial_getc,
167 .pending = xen_serial_pending, 167 .pending = xen_serial_pending,
168 }; 168 };
169 169
170 static const struct udevice_id xen_serial_ids[] = { 170 static const struct udevice_id xen_serial_ids[] = {
171 { .compatible = "xen,xen" }, 171 { .compatible = "xen,xen" },
172 { } 172 { }
173 }; 173 };
174 174
175 U_BOOT_DRIVER(serial_xen) = { 175 U_BOOT_DRIVER(serial_xen) = {
176 .name = "serial_xen", 176 .name = "serial_xen",
177 .id = UCLASS_SERIAL, 177 .id = UCLASS_SERIAL,
178 .of_match = xen_serial_ids, 178 .of_match = xen_serial_ids,
179 .priv_auto_alloc_size = sizeof(struct xen_uart_priv), 179 .priv_auto_alloc_size = sizeof(struct xen_uart_priv),
180 .probe = xen_serial_probe, 180 .probe = xen_serial_probe,
181 .ops = &xen_serial_ops, 181 .ops = &xen_serial_ops,
182 .flags = DM_FLAG_PRE_RELOC, 182 .flags = DM_FLAG_PRE_RELOC,
183 }; 183 };
184 #else 184 #else
185 static void xen_serial_putc(const char c)
186 {
187 (void)HYPERVISOR_console_io(CONSOLEIO_write, 1, &c);
188 }
189
190 static void xen_serial_puts(const char *str)
191 {
192 (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(str), str);
193 }
194
195 static int xen_serial_tstc(void)
196 {
197 return 0;
198 }
199
200 static int xen_serial_init(void)
201 {
202 }
203
204 static void xen_serial_setbrg(void)
205 {
206 }
207
208 static struct serial_device xen_serial_drv = {
209 .name = "xen_serial",
210 .start = xen_serial_init,
211 .stop = NULL,
212 .setbrg = xen_serial_setbrg,
213 .getc = NULL,
214 .putc = xen_serial_putc,
215 .puts = xen_serial_puts,
216 .tstc = xen_serial_tstc,
217 };
218
185 __weak struct serial_device *default_serial_console(void) 219 __weak struct serial_device *default_serial_console(void)
186 { 220 {
187 return NULL; 221 return &xen_serial_drv;
188 } 222 }
189 223
190 #endif 224 #endif
191 225
192 #ifdef CONFIG_DEBUG_UART_XEN 226 #ifdef CONFIG_DEBUG_UART_XEN
193 void _debug_uart_init(void) 227 void _debug_uart_init(void)
194 { 228 {
195 } 229 }
196 230
197 void _debug_uart_putc(int ch) 231 void _debug_uart_putc(int ch)
198 { 232 {
199 /* If \n, also do \r */ 233 /* If \n, also do \r */
200 if (ch == '\n') 234 if (ch == '\n')
201 serial_putc('\r'); 235 serial_putc('\r');
202 236
203 (void)HYPERVISOR_console_io(CONSOLEIO_write, 1, &ch); 237 (void)HYPERVISOR_console_io(CONSOLEIO_write, 1, &ch);
204 238
205 return; 239 return;
206 } 240 }
207 241
208 DEBUG_UART_FUNCS 242 DEBUG_UART_FUNCS
209 243
210 #endif 244 #endif
211 245
include/configs/imx8qm_mek_android_auto_xen.h
1 /* 1 /*
2 * Copyright 2018 NXP 2 * Copyright 2018 NXP
3 * 3 *
4 * SPDX-License-Identifier: GPL-2.0+ 4 * SPDX-License-Identifier: GPL-2.0+
5 */ 5 */
6 6
7 #ifndef IMX8QM_MEK_ANDROID_AUTO_XEN_H 7 #ifndef IMX8QM_MEK_ANDROID_AUTO_XEN_H
8 #define IMX8QM_MEK_ANDROID_AUTO_XEN_H 8 #define IMX8QM_MEK_ANDROID_AUTO_XEN_H
9 9
10 #undef CONFIG_SYS_SDRAM_BASE 10 #undef CONFIG_SYS_SDRAM_BASE
11 #undef CONFIG_NR_DRAM_BANKS 11 #undef CONFIG_NR_DRAM_BANKS
12 #undef PHYS_SDRAM_1 12 #undef PHYS_SDRAM_1
13 #undef PHYS_SDRAM_2 13 #undef PHYS_SDRAM_2
14 #undef PHYS_SDRAM_1_SIZE 14 #undef PHYS_SDRAM_1_SIZE
15 #undef PHYS_SDRAM_2_SIZE 15 #undef PHYS_SDRAM_2_SIZE
16 16
17 #define CONFIG_SYS_SDRAM_BASE 0x80000000 17 #define CONFIG_SYS_SDRAM_BASE 0x80000000
18 #define CONFIG_NR_DRAM_BANKS 2 18 #define CONFIG_NR_DRAM_BANKS 2
19 #define PHYS_SDRAM_1 0x80000000 19 #define PHYS_SDRAM_1 0x80000000
20 #define PHYS_SDRAM_2 0x200000000 20 #define PHYS_SDRAM_2 0x200000000
21 #define PHYS_SDRAM_1_SIZE 0x80000000 /* 2 GB */ 21 #define PHYS_SDRAM_1_SIZE 0x80000000 /* 2 GB */
22 #define PHYS_SDRAM_2_SIZE 0x50000000 /* 1280 MB */ 22 #define PHYS_SDRAM_2_SIZE 0x50000000 /* 1280 MB */
23 23
24 #undef CONFIG_LOADADDR 24 #undef CONFIG_LOADADDR
25 #define CONFIG_LOADADDR 0x80080000 25 #define CONFIG_LOADADDR 0x80080000
26 #undef CONFIG_SYS_INIT_SP_ADDR 26 #undef CONFIG_SYS_INIT_SP_ADDR
27 #define CONFIG_SYS_INIT_SP_ADDR 0x80200000 27 #define CONFIG_SYS_INIT_SP_ADDR 0x81200000
28 28
29 #undef CONFIG_REQUIRE_SERIAL_CONSOLE 29 #undef CONFIG_REQUIRE_SERIAL_CONSOLE
30 #undef CONFIG_IMX_SMMU 30 #undef CONFIG_IMX_SMMU
31 31
32 #undef CONFIG_FASTBOOT_USB_DEV 32 #undef CONFIG_FASTBOOT_USB_DEV
33 #define CONFIG_FASTBOOT_USB_DEV 0 /* Use OTG port, not typec port */ 33 #define CONFIG_FASTBOOT_USB_DEV 0 /* Use OTG port, not typec port */
34 34
35 /* This needs to be stay same in iomem in domu.cfg */ 35 /* This needs to be stay same in iomem in domu.cfg */
36 #ifdef SC_IPC_CH 36 #ifdef SC_IPC_CH
37 #undef SC_IPC_CH 37 #undef SC_IPC_CH
38 #endif 38 #endif
39 #define SC_IPC_CH 0x5d1d0000 39 #define SC_IPC_CH 0x5d1d0000
40
41 #ifdef CONFIG_SPL_BUILD
42 #undef CONFIG_SPL_BSS_START_ADDR
43 #undef CONFIG_SYS_SPL_MALLOC_START
44 #undef CONFIG_MALLOC_F_ADDR
45 #undef CONFIG_SPL_TEXT_BASE
46 #undef CONFIG_SPL_STACK
47
48 #define CONFIG_SPL_TEXT_BASE 0x80080000
49 #define CONFIG_MALLOC_F_ADDR 0x80100000
50 #define CONFIG_SYS_SPL_MALLOC_START 0x80200000
51 #define CONFIG_SPL_BSS_START_ADDR 0x80300000
52 #define CONFIG_SPL_STACK 0x80400000
53
54 #define CONFIG_SYS_SPL_PTE_RAM_BASE 0x80500000
55 #endif
40 56
41 #define AVB_AB_I_UNDERSTAND_LIBAVB_AB_IS_DEPRECATED 57 #define AVB_AB_I_UNDERSTAND_LIBAVB_AB_IS_DEPRECATED
42 58
43 #endif /* IMX8QM_MEK_ANDROID_AUTO_XEN_H */ 59 #endif /* IMX8QM_MEK_ANDROID_AUTO_XEN_H */
44 60
lib/avb/fsl/fsl_avb_ab_flow.c
1 /* 1 /*
2 * Copyright 2018 NXP 2 * Copyright 2018 NXP
3 */ 3 */
4 4
5 #include <common.h> 5 #include <common.h>
6 #include <fsl_avb.h> 6 #include <fsl_avb.h>
7 #include <mmc.h> 7 #include <mmc.h>
8 #include <spl.h> 8 #include <spl.h>
9 #include <part.h> 9 #include <part.h>
10 #include <image.h> 10 #include <image.h>
11 #include "utils.h" 11 #include "utils.h"
12 #include "fsl_caam.h" 12 #include "fsl_caam.h"
13 #include "fsl_avbkey.h" 13 #include "fsl_avbkey.h"
14 14
15 #if defined(CONFIG_DUAL_BOOTLOADER) || !defined(CONFIG_SPL_BUILD) 15 #if defined(CONFIG_DUAL_BOOTLOADER) || !defined(CONFIG_SPL_BUILD)
16 static const char* slot_suffixes[2] = {"_a", "_b"}; 16 static const char* slot_suffixes[2] = {"_a", "_b"};
17 17
18 /* This is a copy of slot_set_unbootable() form 18 /* This is a copy of slot_set_unbootable() form
19 * external/avb/libavb_ab/avb_ab_flow.c. 19 * external/avb/libavb_ab/avb_ab_flow.c.
20 */ 20 */
21 void fsl_slot_set_unbootable(AvbABSlotData* slot) { 21 void fsl_slot_set_unbootable(AvbABSlotData* slot) {
22 slot->priority = 0; 22 slot->priority = 0;
23 slot->tries_remaining = 0; 23 slot->tries_remaining = 0;
24 slot->successful_boot = 0; 24 slot->successful_boot = 0;
25 } 25 }
26 26
27 /* Ensure all unbootable and/or illegal states are marked as the 27 /* Ensure all unbootable and/or illegal states are marked as the
28 * canonical 'unbootable' state, e.g. priority=0, tries_remaining=0, 28 * canonical 'unbootable' state, e.g. priority=0, tries_remaining=0,
29 * and successful_boot=0. This is a copy of slot_normalize from 29 * and successful_boot=0. This is a copy of slot_normalize from
30 * external/avb/libavb_ab/avb_ab_flow.c. 30 * external/avb/libavb_ab/avb_ab_flow.c.
31 */ 31 */
32 void fsl_slot_normalize(AvbABSlotData* slot) { 32 void fsl_slot_normalize(AvbABSlotData* slot) {
33 if (slot->priority > 0) { 33 if (slot->priority > 0) {
34 #if defined(CONFIG_DUAL_BOOTLOADER) && !defined(CONFIG_SPL_BUILD) 34 #if defined(CONFIG_DUAL_BOOTLOADER) && !defined(CONFIG_SPL_BUILD)
35 if ((slot->tries_remaining == 0) 35 if ((slot->tries_remaining == 0)
36 && (!slot->successful_boot) && (slot->bootloader_verified != 1)) { 36 && (!slot->successful_boot) && (slot->bootloader_verified != 1)) {
37 /* We've exhausted all tries -> unbootable. */ 37 /* We've exhausted all tries -> unbootable. */
38 fsl_slot_set_unbootable(slot); 38 fsl_slot_set_unbootable(slot);
39 } 39 }
40 #else 40 #else
41 if ((slot->tries_remaining == 0) && (!slot->successful_boot)) { 41 if ((slot->tries_remaining == 0) && (!slot->successful_boot)) {
42 /* We've exhausted all tries -> unbootable. */ 42 /* We've exhausted all tries -> unbootable. */
43 fsl_slot_set_unbootable(slot); 43 fsl_slot_set_unbootable(slot);
44 } 44 }
45 #endif 45 #endif
46 if ((slot->tries_remaining > 0) && (slot->successful_boot)) { 46 if ((slot->tries_remaining > 0) && (slot->successful_boot)) {
47 /* Illegal state - avb_ab_mark_slot_successful() will clear 47 /* Illegal state - avb_ab_mark_slot_successful() will clear
48 * tries_remaining when setting successful_boot. 48 * tries_remaining when setting successful_boot.
49 */ 49 */
50 fsl_slot_set_unbootable(slot); 50 fsl_slot_set_unbootable(slot);
51 } 51 }
52 } else { 52 } else {
53 fsl_slot_set_unbootable(slot); 53 fsl_slot_set_unbootable(slot);
54 } 54 }
55 } 55 }
56 56
57 /* This is a copy of slot_is_bootable() from 57 /* This is a copy of slot_is_bootable() from
58 * externel/avb/libavb_ab/avb_ab_flow.c. 58 * externel/avb/libavb_ab/avb_ab_flow.c.
59 */ 59 */
60 bool fsl_slot_is_bootable(AvbABSlotData* slot) { 60 bool fsl_slot_is_bootable(AvbABSlotData* slot) {
61 return (slot->priority > 0) && 61 return (slot->priority > 0) &&
62 (slot->successful_boot || (slot->tries_remaining > 0)); 62 (slot->successful_boot || (slot->tries_remaining > 0));
63 } 63 }
64 #endif /* CONFIG_DUAL_BOOTLOADER || !CONFIG_SPL_BUILD */ 64 #endif /* CONFIG_DUAL_BOOTLOADER || !CONFIG_SPL_BUILD */
65 65
66 #if defined(CONFIG_DUAL_BOOTLOADER) && defined(CONFIG_SPL_BUILD) 66 #if defined(CONFIG_DUAL_BOOTLOADER) && defined(CONFIG_SPL_BUILD)
67 67
68 #define FSL_AB_METADATA_MISC_PARTITION_OFFSET 2048 68 #define FSL_AB_METADATA_MISC_PARTITION_OFFSET 2048
69 #define PARTITION_NAME_LEN 13 69 #define PARTITION_NAME_LEN 13
70 #define PARTITION_MISC "misc" 70 #define PARTITION_MISC "misc"
71 #define PARTITION_BOOTLOADER "bootloader" 71 #define PARTITION_BOOTLOADER "bootloader"
72 72
73 extern int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value); 73 extern int mmc_switch(struct mmc *mmc, u8 set, u8 index, u8 value);
74 extern int mmc_load_image_parse_container(struct spl_image_info *spl_image, 74 extern int mmc_load_image_parse_container(struct spl_image_info *spl_image,
75 struct mmc *mmc, unsigned long sector); 75 struct mmc *mmc, unsigned long sector);
76 76
77 /* Pre-declaration of h_spl_load_read(), see detail implementation in 77 /* Pre-declaration of h_spl_load_read(), see detail implementation in
78 * common/spl/spl_mmc.c. 78 * common/spl/spl_mmc.c.
79 */ 79 */
80 ulong h_spl_load_read(struct spl_load_info *load, ulong sector, 80 ulong h_spl_load_read(struct spl_load_info *load, ulong sector,
81 ulong count, void *buf); 81 ulong count, void *buf);
82 82
83 void fsl_avb_ab_data_update_crc_and_byteswap(const AvbABData* src, 83 void fsl_avb_ab_data_update_crc_and_byteswap(const AvbABData* src,
84 AvbABData* dest) { 84 AvbABData* dest) {
85 memcpy(dest, src, sizeof(AvbABData)); 85 memcpy(dest, src, sizeof(AvbABData));
86 dest->crc32 = cpu_to_be32( 86 dest->crc32 = cpu_to_be32(
87 avb_crc32((const uint8_t*)dest, 87 avb_crc32((const uint8_t*)dest,
88 sizeof(AvbABData) - sizeof(uint32_t))); 88 sizeof(AvbABData) - sizeof(uint32_t)));
89 } 89 }
90 90
91 void fsl_avb_ab_data_init(AvbABData* data) { 91 void fsl_avb_ab_data_init(AvbABData* data) {
92 memset(data, '\0', sizeof(AvbABData)); 92 memset(data, '\0', sizeof(AvbABData));
93 memcpy(data->magic, AVB_AB_MAGIC, AVB_AB_MAGIC_LEN); 93 memcpy(data->magic, AVB_AB_MAGIC, AVB_AB_MAGIC_LEN);
94 data->version_major = AVB_AB_MAJOR_VERSION; 94 data->version_major = AVB_AB_MAJOR_VERSION;
95 data->version_minor = AVB_AB_MINOR_VERSION; 95 data->version_minor = AVB_AB_MINOR_VERSION;
96 data->slots[0].priority = AVB_AB_MAX_PRIORITY; 96 data->slots[0].priority = AVB_AB_MAX_PRIORITY;
97 data->slots[0].tries_remaining = AVB_AB_MAX_TRIES_REMAINING; 97 data->slots[0].tries_remaining = AVB_AB_MAX_TRIES_REMAINING;
98 data->slots[0].successful_boot = 0; 98 data->slots[0].successful_boot = 0;
99 data->slots[0].bootloader_verified = 0; 99 data->slots[0].bootloader_verified = 0;
100 data->slots[1].priority = AVB_AB_MAX_PRIORITY - 1; 100 data->slots[1].priority = AVB_AB_MAX_PRIORITY - 1;
101 data->slots[1].tries_remaining = AVB_AB_MAX_TRIES_REMAINING; 101 data->slots[1].tries_remaining = AVB_AB_MAX_TRIES_REMAINING;
102 data->slots[1].successful_boot = 0; 102 data->slots[1].successful_boot = 0;
103 data->slots[1].bootloader_verified = 0; 103 data->slots[1].bootloader_verified = 0;
104 } 104 }
105 105
106 bool fsl_avb_ab_data_verify_and_byteswap(const AvbABData* src, 106 bool fsl_avb_ab_data_verify_and_byteswap(const AvbABData* src,
107 AvbABData* dest) { 107 AvbABData* dest) {
108 /* Ensure magic is correct. */ 108 /* Ensure magic is correct. */
109 if (memcmp(src->magic, AVB_AB_MAGIC, AVB_AB_MAGIC_LEN) != 0) { 109 if (memcmp(src->magic, AVB_AB_MAGIC, AVB_AB_MAGIC_LEN) != 0) {
110 printf("Magic is incorrect.\n"); 110 printf("Magic is incorrect.\n");
111 return false; 111 return false;
112 } 112 }
113 113
114 memcpy(dest, src, sizeof(AvbABData)); 114 memcpy(dest, src, sizeof(AvbABData));
115 dest->crc32 = be32_to_cpu(dest->crc32); 115 dest->crc32 = be32_to_cpu(dest->crc32);
116 116
117 /* Ensure we don't attempt to access any fields if the major version 117 /* Ensure we don't attempt to access any fields if the major version
118 * is not supported. 118 * is not supported.
119 */ 119 */
120 if (dest->version_major > AVB_AB_MAJOR_VERSION) { 120 if (dest->version_major > AVB_AB_MAJOR_VERSION) {
121 printf("No support for given major version.\n"); 121 printf("No support for given major version.\n");
122 return false; 122 return false;
123 } 123 }
124 124
125 /* Fail if CRC32 doesn't match. */ 125 /* Fail if CRC32 doesn't match. */
126 if (dest->crc32 != 126 if (dest->crc32 !=
127 avb_crc32((const uint8_t*)dest, sizeof(AvbABData) - sizeof(uint32_t))) { 127 avb_crc32((const uint8_t*)dest, sizeof(AvbABData) - sizeof(uint32_t))) {
128 printf("CRC32 does not match.\n"); 128 printf("CRC32 does not match.\n");
129 return false; 129 return false;
130 } 130 }
131 131
132 return true; 132 return true;
133 } 133 }
134 134
135 /* Writes A/B metadata to disk only if it has changed. 135 /* Writes A/B metadata to disk only if it has changed.
136 */ 136 */
137 int fsl_save_metadata_if_changed_dual_uboot(struct blk_desc *dev_desc, 137 int fsl_save_metadata_if_changed_dual_uboot(struct blk_desc *dev_desc,
138 AvbABData* ab_data, 138 AvbABData* ab_data,
139 AvbABData* ab_data_orig) { 139 AvbABData* ab_data_orig) {
140 AvbABData serialized; 140 AvbABData serialized;
141 size_t num_bytes; 141 size_t num_bytes;
142 disk_partition_t info; 142 disk_partition_t info;
143 143
144 /* Save metadata if changed. */ 144 /* Save metadata if changed. */
145 if (memcmp(ab_data, ab_data_orig, sizeof(AvbABData)) != 0) { 145 if (memcmp(ab_data, ab_data_orig, sizeof(AvbABData)) != 0) {
146 /* Get misc partition info */ 146 /* Get misc partition info */
147 if (part_get_info_by_name(dev_desc, PARTITION_MISC, &info) == -1) { 147 if (part_get_info_by_name(dev_desc, PARTITION_MISC, &info) == -1) {
148 printf("Can't get partition info of partition: misc\n"); 148 printf("Can't get partition info of partition: misc\n");
149 return -1; 149 return -1;
150 } 150 }
151 151
152 /* Writing A/B metadata to disk. */ 152 /* Writing A/B metadata to disk. */
153 fsl_avb_ab_data_update_crc_and_byteswap(ab_data, &serialized); 153 fsl_avb_ab_data_update_crc_and_byteswap(ab_data, &serialized);
154 if (write_to_partition_in_bytes(dev_desc, &info, 154 if (write_to_partition_in_bytes(dev_desc, &info,
155 FSL_AB_METADATA_MISC_PARTITION_OFFSET, 155 FSL_AB_METADATA_MISC_PARTITION_OFFSET,
156 sizeof(AvbABData), 156 sizeof(AvbABData),
157 (void *)&serialized, &num_bytes) || 157 (void *)&serialized, &num_bytes) ||
158 (num_bytes != sizeof(AvbABData))) { 158 (num_bytes != sizeof(AvbABData))) {
159 printf("Error--write metadata fail!\n"); 159 printf("Error--write metadata fail!\n");
160 return -1; 160 return -1;
161 } 161 }
162 } 162 }
163 return 0; 163 return 0;
164 } 164 }
165 165
166 /* Load metadate from misc partition. 166 /* Load metadate from misc partition.
167 */ 167 */
168 int fsl_load_metadata_dual_uboot(struct blk_desc *dev_desc, 168 int fsl_load_metadata_dual_uboot(struct blk_desc *dev_desc,
169 AvbABData* ab_data, 169 AvbABData* ab_data,
170 AvbABData* ab_data_orig) { 170 AvbABData* ab_data_orig) {
171 disk_partition_t info; 171 disk_partition_t info;
172 AvbABData serialized; 172 AvbABData serialized;
173 size_t num_bytes; 173 size_t num_bytes;
174 174
175 if (part_get_info_by_name(dev_desc, PARTITION_MISC, &info) == -1) { 175 if (part_get_info_by_name(dev_desc, PARTITION_MISC, &info) == -1) {
176 printf("Can't get partition info of partition: misc\n"); 176 printf("Can't get partition info of partition: misc\n");
177 return -1; 177 return -1;
178 } else { 178 } else {
179 read_from_partition_in_bytes(dev_desc, &info, 179 read_from_partition_in_bytes(dev_desc, &info,
180 FSL_AB_METADATA_MISC_PARTITION_OFFSET, 180 FSL_AB_METADATA_MISC_PARTITION_OFFSET,
181 sizeof(AvbABData), 181 sizeof(AvbABData),
182 (void *)ab_data, &num_bytes ); 182 (void *)ab_data, &num_bytes );
183 if (num_bytes != sizeof(AvbABData)) { 183 if (num_bytes != sizeof(AvbABData)) {
184 printf("Error--read metadata fail!\n"); 184 printf("Error--read metadata fail!\n");
185 return -1; 185 return -1;
186 } else { 186 } else {
187 if (!fsl_avb_ab_data_verify_and_byteswap(ab_data, &serialized)) { 187 if (!fsl_avb_ab_data_verify_and_byteswap(ab_data, &serialized)) {
188 printf("Error validating A/B metadata from disk.\n"); 188 printf("Error validating A/B metadata from disk.\n");
189 printf("Resetting and writing new A/B metadata to disk.\n"); 189 printf("Resetting and writing new A/B metadata to disk.\n");
190 fsl_avb_ab_data_init(ab_data); 190 fsl_avb_ab_data_init(ab_data);
191 fsl_avb_ab_data_update_crc_and_byteswap(ab_data, &serialized); 191 fsl_avb_ab_data_update_crc_and_byteswap(ab_data, &serialized);
192 num_bytes = 0; 192 num_bytes = 0;
193 if (write_to_partition_in_bytes( 193 if (write_to_partition_in_bytes(
194 dev_desc, &info, 194 dev_desc, &info,
195 FSL_AB_METADATA_MISC_PARTITION_OFFSET, 195 FSL_AB_METADATA_MISC_PARTITION_OFFSET,
196 sizeof(AvbABData), 196 sizeof(AvbABData),
197 (void *)&serialized, &num_bytes) || 197 (void *)&serialized, &num_bytes) ||
198 (num_bytes != sizeof(AvbABData))) { 198 (num_bytes != sizeof(AvbABData))) {
199 printf("Error--write metadata fail!\n"); 199 printf("Error--write metadata fail!\n");
200 return -1; 200 return -1;
201 } else 201 } else
202 return 0; 202 return 0;
203 } else { 203 } else {
204 memcpy(ab_data_orig, ab_data, sizeof(AvbABData)); 204 memcpy(ab_data_orig, ab_data, sizeof(AvbABData));
205 /* Ensure data is normalized, e.g. illegal states will be marked as 205 /* Ensure data is normalized, e.g. illegal states will be marked as
206 * unbootable and all unbootable states are represented with 206 * unbootable and all unbootable states are represented with
207 * (priority=0, tries_remaining=0, successful_boot=0). 207 * (priority=0, tries_remaining=0, successful_boot=0).
208 */ 208 */
209 fsl_slot_normalize(&ab_data->slots[0]); 209 fsl_slot_normalize(&ab_data->slots[0]);
210 fsl_slot_normalize(&ab_data->slots[1]); 210 fsl_slot_normalize(&ab_data->slots[1]);
211 return 0; 211 return 0;
212 } 212 }
213 } 213 }
214 } 214 }
215 } 215 }
216 216
217 #ifndef CONFIG_XEN
217 static int spl_verify_rbidx(struct mmc *mmc, AvbABSlotData *slot, 218 static int spl_verify_rbidx(struct mmc *mmc, AvbABSlotData *slot,
218 struct spl_image_info *spl_image) 219 struct spl_image_info *spl_image)
219 { 220 {
220 kblb_hdr_t hdr; 221 kblb_hdr_t hdr;
221 kblb_tag_t *rbk; 222 kblb_tag_t *rbk;
222 uint64_t extract_idx; 223 uint64_t extract_idx;
223 #ifdef CONFIG_AVB_ATX 224 #ifdef CONFIG_AVB_ATX
224 struct bl_rbindex_package *bl_rbindex; 225 struct bl_rbindex_package *bl_rbindex;
225 #endif 226 #endif
226 227
227 /* Make sure rollback index has been initialized before verify */ 228 /* Make sure rollback index has been initialized before verify */
228 if (rpmb_init()) { 229 if (rpmb_init()) {
229 printf("RPMB init failed!\n"); 230 printf("RPMB init failed!\n");
230 return -1; 231 return -1;
231 } 232 }
232 233
233 /* Read bootloader rollback index header first. */ 234 /* Read bootloader rollback index header first. */
234 if (rpmb_read(mmc, (uint8_t *)&hdr, sizeof(hdr), 235 if (rpmb_read(mmc, (uint8_t *)&hdr, sizeof(hdr),
235 BOOTLOADER_RBIDX_OFFSET) != 0) { 236 BOOTLOADER_RBIDX_OFFSET) != 0) {
236 printf("Read RPMB error!\n"); 237 printf("Read RPMB error!\n");
237 return -1; 238 return -1;
238 } 239 }
239 240
240 /* Read bootloader rollback index. */ 241 /* Read bootloader rollback index. */
241 rbk = &(hdr.bootloader_rbk_tags); 242 rbk = &(hdr.bootloader_rbk_tags);
242 if (rpmb_read(mmc, (uint8_t *)&extract_idx, rbk->len, rbk->offset) != 0) { 243 if (rpmb_read(mmc, (uint8_t *)&extract_idx, rbk->len, rbk->offset) != 0) {
243 printf("Read rollback index error!\n"); 244 printf("Read rollback index error!\n");
244 return -1; 245 return -1;
245 } 246 }
246 247
247 /* Verify bootloader rollback index. */ 248 /* Verify bootloader rollback index. */
248 if (spl_image->rbindex >= extract_idx) { 249 if (spl_image->rbindex >= extract_idx) {
249 /* Rollback index verify pass, update it only when current slot 250 /* Rollback index verify pass, update it only when current slot
250 * has been marked as successful. 251 * has been marked as successful.
251 */ 252 */
252 if ((slot->successful_boot != 0) && (spl_image->rbindex != extract_idx) && 253 if ((slot->successful_boot != 0) && (spl_image->rbindex != extract_idx) &&
253 rpmb_write(mmc, (uint8_t *)(&(spl_image->rbindex)), 254 rpmb_write(mmc, (uint8_t *)(&(spl_image->rbindex)),
254 rbk->len, rbk->offset)) { 255 rbk->len, rbk->offset)) {
255 printf("Update bootloader rollback index failed!\n"); 256 printf("Update bootloader rollback index failed!\n");
256 return -1; 257 return -1;
257 } 258 }
258 259
259 #ifdef CONFIG_AVB_ATX 260 #ifdef CONFIG_AVB_ATX
260 /* Pass bootloader rbindex to u-boot here. */ 261 /* Pass bootloader rbindex to u-boot here. */
261 bl_rbindex = (struct bl_rbindex_package *)BL_RBINDEX_LOAD_ADDR; 262 bl_rbindex = (struct bl_rbindex_package *)BL_RBINDEX_LOAD_ADDR;
262 memcpy(bl_rbindex->magic, BL_RBINDEX_MAGIC, BL_RBINDEX_MAGIC_LEN); 263 memcpy(bl_rbindex->magic, BL_RBINDEX_MAGIC, BL_RBINDEX_MAGIC_LEN);
263 if (slot->successful_boot != 0) 264 if (slot->successful_boot != 0)
264 bl_rbindex->rbindex = spl_image->rbindex; 265 bl_rbindex->rbindex = spl_image->rbindex;
265 else 266 else
266 bl_rbindex->rbindex = extract_idx; 267 bl_rbindex->rbindex = extract_idx;
267 #endif 268 #endif
268 269
269 return 0; 270 return 0;
270 } else { 271 } else {
271 printf("Rollback index verify rejected!\n"); 272 printf("Rollback index verify rejected!\n");
272 return -1; 273 return -1;
273 } 274 }
274 275
275 } 276 }
277 #endif /* CONFIG_XEN */
276 278
277 #ifdef CONFIG_PARSE_CONTAINER 279 #ifdef CONFIG_PARSE_CONTAINER
278 int mmc_load_image_parse_container_dual_uboot( 280 int mmc_load_image_parse_container_dual_uboot(
279 struct spl_image_info *spl_image, struct mmc *mmc) 281 struct spl_image_info *spl_image, struct mmc *mmc)
280 { 282 {
281 disk_partition_t info; 283 disk_partition_t info;
282 int ret = 0, n = 0; 284 int ret = 0, n = 0;
283 char partition_name[PARTITION_NAME_LEN]; 285 char partition_name[PARTITION_NAME_LEN];
284 struct blk_desc *dev_desc; 286 struct blk_desc *dev_desc;
285 AvbABData ab_data, ab_data_orig; 287 AvbABData ab_data, ab_data_orig;
286 size_t slot_index_to_boot, target_slot; 288 size_t slot_index_to_boot, target_slot;
289 #ifndef CONFIG_XEN
287 struct keyslot_package kp; 290 struct keyslot_package kp;
291 #endif
288 292
289 /* Check if gpt is valid */ 293 /* Check if gpt is valid */
290 dev_desc = mmc_get_blk_desc(mmc); 294 dev_desc = mmc_get_blk_desc(mmc);
291 if (dev_desc) { 295 if (dev_desc) {
292 if (part_get_info(dev_desc, 1, &info)) { 296 if (part_get_info(dev_desc, 1, &info)) {
293 printf("GPT is invalid, please flash correct GPT!\n"); 297 printf("GPT is invalid, please flash correct GPT!\n");
294 return -1; 298 return -1;
295 } 299 }
296 } else { 300 } else {
297 printf("Get block desc fail!\n"); 301 printf("Get block desc fail!\n");
298 return -1; 302 return -1;
299 } 303 }
300 304
301 /* Read RPMB keyslot package */ 305 #ifndef CONFIG_XEN
306 /* Read RPMB keyslot package, xen won't check this. */
302 read_keyslot_package(&kp); 307 read_keyslot_package(&kp);
303 if (strcmp(kp.magic, KEYPACK_MAGIC)) { 308 if (strcmp(kp.magic, KEYPACK_MAGIC)) {
304 if (rpmbkey_is_set()) { 309 if (rpmbkey_is_set()) {
305 printf("\nFATAL - RPMB key was destroyed!\n"); 310 printf("\nFATAL - RPMB key was destroyed!\n");
306 hang(); 311 hang();
307 } else 312 } else
308 printf("keyslot package magic error, do nothing here!\n"); 313 printf("keyslot package magic error, do nothing here!\n");
309 } else { 314 } else {
310 /* Set power-on write protection to boot1 partition. */ 315 /* Set power-on write protection to boot1 partition. */
311 if (mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP, BOOT1_PWR_WP)) { 316 if (mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP, BOOT1_PWR_WP)) {
312 printf("Unable to set power-on write protection to boot1!\n"); 317 printf("Unable to set power-on write protection to boot1!\n");
313 return -1; 318 return -1;
314 } 319 }
315 } 320 }
321 #endif
322
316 /* Load AB metadata from misc partition */ 323 /* Load AB metadata from misc partition */
317 if (fsl_load_metadata_dual_uboot(dev_desc, &ab_data, 324 if (fsl_load_metadata_dual_uboot(dev_desc, &ab_data,
318 &ab_data_orig)) { 325 &ab_data_orig)) {
319 return -1; 326 return -1;
320 } 327 }
321 328
322 slot_index_to_boot = 2; // Means not 0 or 1 329 slot_index_to_boot = 2; // Means not 0 or 1
323 target_slot = 330 target_slot =
324 (ab_data.slots[1].priority > ab_data.slots[0].priority) ? 1 : 0; 331 (ab_data.slots[1].priority > ab_data.slots[0].priority) ? 1 : 0;
325 332
326 for (n = 0; n < 2; n++) { 333 for (n = 0; n < 2; n++) {
327 if (!fsl_slot_is_bootable(&ab_data.slots[target_slot])) { 334 if (!fsl_slot_is_bootable(&ab_data.slots[target_slot])) {
328 target_slot = (target_slot == 1 ? 0 : 1); 335 target_slot = (target_slot == 1 ? 0 : 1);
329 continue; 336 continue;
330 } 337 }
331 /* Choose slot to load. */ 338 /* Choose slot to load. */
332 snprintf(partition_name, PARTITION_NAME_LEN, 339 snprintf(partition_name, PARTITION_NAME_LEN,
333 PARTITION_BOOTLOADER"%s", 340 PARTITION_BOOTLOADER"%s",
334 slot_suffixes[target_slot]); 341 slot_suffixes[target_slot]);
335 342
336 /* Read part info from gpt */ 343 /* Read part info from gpt */
337 if (part_get_info_by_name(dev_desc, partition_name, &info) == -1) { 344 if (part_get_info_by_name(dev_desc, partition_name, &info) == -1) {
338 printf("Can't get partition info of partition bootloader%s\n", 345 printf("Can't get partition info of partition bootloader%s\n",
339 slot_suffixes[target_slot]); 346 slot_suffixes[target_slot]);
340 ret = -1; 347 ret = -1;
341 goto end; 348 goto end;
342 } else { 349 } else {
343 ret = mmc_load_image_parse_container(spl_image, mmc, info.start); 350 ret = mmc_load_image_parse_container(spl_image, mmc, info.start);
344 351
352 /* Don't need to check rollback index for xen. */
353 #ifndef CONFIG_XEN
345 /* Image loaded successfully, go to verify rollback index */ 354 /* Image loaded successfully, go to verify rollback index */
346 if (!ret && rpmbkey_is_set()) 355 if (!ret && rpmbkey_is_set())
347 ret = spl_verify_rbidx(mmc, &ab_data.slots[target_slot], spl_image); 356 ret = spl_verify_rbidx(mmc, &ab_data.slots[target_slot], spl_image);
348 357
349 /* Copy rpmb keyslot to secure memory. */ 358 /* Copy rpmb keyslot to secure memory. */
350 if (!ret) 359 if (!ret)
351 fill_secure_keyslot_package(&kp); 360 fill_secure_keyslot_package(&kp);
361 #endif
352 } 362 }
353 363
354 /* Set current slot to unbootable if load/verify fail. */ 364 /* Set current slot to unbootable if load/verify fail. */
355 if (ret != 0) { 365 if (ret != 0) {
356 printf("Load or verify bootloader%s fail, setting unbootable..\n", 366 printf("Load or verify bootloader%s fail, setting unbootable..\n",
357 slot_suffixes[target_slot]); 367 slot_suffixes[target_slot]);
358 fsl_slot_set_unbootable(&ab_data.slots[target_slot]); 368 fsl_slot_set_unbootable(&ab_data.slots[target_slot]);
359 /* Switch to another slot. */ 369 /* Switch to another slot. */
360 target_slot = (target_slot == 1 ? 0 : 1); 370 target_slot = (target_slot == 1 ? 0 : 1);
361 } else { 371 } else {
362 slot_index_to_boot = target_slot; 372 slot_index_to_boot = target_slot;
363 n = 2; 373 n = 2;
364 } 374 }
365 } 375 }
366 376
367 if (slot_index_to_boot == 2) { 377 if (slot_index_to_boot == 2) {
368 /* No bootable slots! */ 378 /* No bootable slots! */
369 printf("No bootable slots found.\n"); 379 printf("No bootable slots found.\n");
370 ret = -1; 380 ret = -1;
371 goto end; 381 goto end;
372 } else if (!ab_data.slots[slot_index_to_boot].successful_boot && 382 } else if (!ab_data.slots[slot_index_to_boot].successful_boot &&
373 (ab_data.slots[slot_index_to_boot].tries_remaining > 0)) { 383 (ab_data.slots[slot_index_to_boot].tries_remaining > 0)) {
374 /* Set the bootloader_verified flag if current slot only has one chance. */ 384 /* Set the bootloader_verified flag if current slot only has one chance. */
375 if (ab_data.slots[slot_index_to_boot].tries_remaining == 1) 385 if (ab_data.slots[slot_index_to_boot].tries_remaining == 1)
376 ab_data.slots[slot_index_to_boot].bootloader_verified = 1; 386 ab_data.slots[slot_index_to_boot].bootloader_verified = 1;
377 ab_data.slots[slot_index_to_boot].tries_remaining -= 1; 387 ab_data.slots[slot_index_to_boot].tries_remaining -= 1;
378 } 388 }
379 printf("Booting from bootloader%s...\n", slot_suffixes[slot_index_to_boot]); 389 printf("Booting from bootloader%s...\n", slot_suffixes[slot_index_to_boot]);
380 390
381 end: 391 end:
382 /* Save metadata if changed. */ 392 /* Save metadata if changed. */
383 if (fsl_save_metadata_if_changed_dual_uboot(dev_desc, &ab_data, &ab_data_orig)) { 393 if (fsl_save_metadata_if_changed_dual_uboot(dev_desc, &ab_data, &ab_data_orig)) {
384 ret = -1; 394 ret = -1;
385 } 395 }
386 396
387 if (ret) 397 if (ret)
388 return -1; 398 return -1;
389 else 399 else
390 return 0; 400 return 0;
391 } 401 }
392 #else /* CONFIG_PARSE_CONTAINER */ 402 #else /* CONFIG_PARSE_CONTAINER */
393 int mmc_load_image_raw_sector_dual_uboot( 403 int mmc_load_image_raw_sector_dual_uboot(
394 struct spl_image_info *spl_image, struct mmc *mmc) 404 struct spl_image_info *spl_image, struct mmc *mmc)
395 { 405 {
396 unsigned long count; 406 unsigned long count;
397 disk_partition_t info; 407 disk_partition_t info;
398 int ret = 0, n = 0; 408 int ret = 0, n = 0;
399 char partition_name[PARTITION_NAME_LEN]; 409 char partition_name[PARTITION_NAME_LEN];
400 struct blk_desc *dev_desc; 410 struct blk_desc *dev_desc;
401 struct image_header *header; 411 struct image_header *header;
402 AvbABData ab_data, ab_data_orig; 412 AvbABData ab_data, ab_data_orig;
403 size_t slot_index_to_boot, target_slot; 413 size_t slot_index_to_boot, target_slot;
404 struct keyslot_package kp; 414 struct keyslot_package kp;
405 415
406 /* Check if gpt is valid */ 416 /* Check if gpt is valid */
407 dev_desc = mmc_get_blk_desc(mmc); 417 dev_desc = mmc_get_blk_desc(mmc);
408 if (dev_desc) { 418 if (dev_desc) {
409 if (part_get_info(dev_desc, 1, &info)) { 419 if (part_get_info(dev_desc, 1, &info)) {
410 printf("GPT is invalid, please flash correct GPT!\n"); 420 printf("GPT is invalid, please flash correct GPT!\n");
411 return -1; 421 return -1;
412 } 422 }
413 } else { 423 } else {
414 printf("Get block desc fail!\n"); 424 printf("Get block desc fail!\n");
415 return -1; 425 return -1;
416 } 426 }
417 427
418 /* Init RPMB keyslot package if not initialized before. */ 428 /* Init RPMB keyslot package if not initialized before. */
419 read_keyslot_package(&kp); 429 read_keyslot_package(&kp);
420 if (strcmp(kp.magic, KEYPACK_MAGIC)) { 430 if (strcmp(kp.magic, KEYPACK_MAGIC)) {
421 printf("keyslot package magic error. Will generate new one\n"); 431 printf("keyslot package magic error. Will generate new one\n");
422 if (gen_rpmb_key(&kp)) { 432 if (gen_rpmb_key(&kp)) {
423 printf("Generate keyslot package fail!\n"); 433 printf("Generate keyslot package fail!\n");
424 return -1; 434 return -1;
425 } 435 }
426 } 436 }
427 /* Set power-on write protection to boot1 partition. */ 437 /* Set power-on write protection to boot1 partition. */
428 if (mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP, BOOT1_PWR_WP)) { 438 if (mmc_switch(mmc, EXT_CSD_CMD_SET_NORMAL, EXT_CSD_BOOT_WP, BOOT1_PWR_WP)) {
429 printf("Unable to set power-on write protection to boot1!\n"); 439 printf("Unable to set power-on write protection to boot1!\n");
430 return -1; 440 return -1;
431 } 441 }
432 442
433 /* Load AB metadata from misc partition */ 443 /* Load AB metadata from misc partition */
434 if (fsl_load_metadata_dual_uboot(dev_desc, &ab_data, 444 if (fsl_load_metadata_dual_uboot(dev_desc, &ab_data,
435 &ab_data_orig)) { 445 &ab_data_orig)) {
436 return -1; 446 return -1;
437 } 447 }
438 448
439 slot_index_to_boot = 2; // Means not 0 or 1 449 slot_index_to_boot = 2; // Means not 0 or 1
440 target_slot = 450 target_slot =
441 (ab_data.slots[1].priority > ab_data.slots[0].priority) ? 1 : 0; 451 (ab_data.slots[1].priority > ab_data.slots[0].priority) ? 1 : 0;
442 452
443 for (n = 0; n < 2; n++) { 453 for (n = 0; n < 2; n++) {
444 if (!fsl_slot_is_bootable(&ab_data.slots[target_slot])) { 454 if (!fsl_slot_is_bootable(&ab_data.slots[target_slot])) {
445 target_slot = (target_slot == 1 ? 0 : 1); 455 target_slot = (target_slot == 1 ? 0 : 1);
446 continue; 456 continue;
447 } 457 }
448 /* Choose slot to load. */ 458 /* Choose slot to load. */
449 snprintf(partition_name, PARTITION_NAME_LEN, 459 snprintf(partition_name, PARTITION_NAME_LEN,
450 PARTITION_BOOTLOADER"%s", 460 PARTITION_BOOTLOADER"%s",
451 slot_suffixes[target_slot]); 461 slot_suffixes[target_slot]);
452 462
453 /* Read part info from gpt */ 463 /* Read part info from gpt */
454 if (part_get_info_by_name(dev_desc, partition_name, &info) == -1) { 464 if (part_get_info_by_name(dev_desc, partition_name, &info) == -1) {
455 printf("Can't get partition info of partition bootloader%s\n", 465 printf("Can't get partition info of partition bootloader%s\n",
456 slot_suffixes[target_slot]); 466 slot_suffixes[target_slot]);
457 ret = -1; 467 ret = -1;
458 goto end; 468 goto end;
459 } else { 469 } else {
460 header = (struct image_header *)(CONFIG_SYS_TEXT_BASE - 470 header = (struct image_header *)(CONFIG_SYS_TEXT_BASE -
461 sizeof(struct image_header)); 471 sizeof(struct image_header));
462 472
463 /* read image header to find the image size & load address */ 473 /* read image header to find the image size & load address */
464 count = blk_dread(dev_desc, info.start, 1, header); 474 count = blk_dread(dev_desc, info.start, 1, header);
465 if (count == 0) { 475 if (count == 0) {
466 ret = -1; 476 ret = -1;
467 goto end; 477 goto end;
468 } 478 }
469 479
470 /* Load fit and check HAB */ 480 /* Load fit and check HAB */
471 if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) && 481 if (IS_ENABLED(CONFIG_SPL_LOAD_FIT) &&
472 image_get_magic(header) == FDT_MAGIC) { 482 image_get_magic(header) == FDT_MAGIC) {
473 struct spl_load_info load; 483 struct spl_load_info load;
474 484
475 debug("Found FIT\n"); 485 debug("Found FIT\n");
476 load.dev = mmc; 486 load.dev = mmc;
477 load.priv = NULL; 487 load.priv = NULL;
478 load.filename = NULL; 488 load.filename = NULL;
479 load.bl_len = mmc->read_bl_len; 489 load.bl_len = mmc->read_bl_len;
480 load.read = h_spl_load_read; 490 load.read = h_spl_load_read;
481 ret = spl_load_simple_fit(spl_image, &load, 491 ret = spl_load_simple_fit(spl_image, &load,
482 info.start, header); 492 info.start, header);
483 } else { 493 } else {
484 ret = -1; 494 ret = -1;
485 } 495 }
486 496
487 /* Fit image loaded successfully, go to verify rollback index */ 497 /* Fit image loaded successfully, go to verify rollback index */
488 if (!ret) 498 if (!ret)
489 ret = spl_verify_rbidx(mmc, &ab_data.slots[target_slot], spl_image); 499 ret = spl_verify_rbidx(mmc, &ab_data.slots[target_slot], spl_image);
490 500
491 /* Copy rpmb keyslot to secure memory. */ 501 /* Copy rpmb keyslot to secure memory. */
492 if (!ret) 502 if (!ret)
493 fill_secure_keyslot_package(&kp); 503 fill_secure_keyslot_package(&kp);
494 } 504 }
495 505
496 /* Set current slot to unbootable if load/verify fail. */ 506 /* Set current slot to unbootable if load/verify fail. */
497 if (ret != 0) { 507 if (ret != 0) {
498 printf("Load or verify bootloader%s fail, setting unbootable..\n", 508 printf("Load or verify bootloader%s fail, setting unbootable..\n",
499 slot_suffixes[target_slot]); 509 slot_suffixes[target_slot]);
500 fsl_slot_set_unbootable(&ab_data.slots[target_slot]); 510 fsl_slot_set_unbootable(&ab_data.slots[target_slot]);
501 /* Switch to another slot. */ 511 /* Switch to another slot. */
502 target_slot = (target_slot == 1 ? 0 : 1); 512 target_slot = (target_slot == 1 ? 0 : 1);
503 } else { 513 } else {
504 slot_index_to_boot = target_slot; 514 slot_index_to_boot = target_slot;
505 n = 2; 515 n = 2;
506 } 516 }
507 } 517 }
508 518
509 if (slot_index_to_boot == 2) { 519 if (slot_index_to_boot == 2) {
510 /* No bootable slots! */ 520 /* No bootable slots! */
511 printf("No bootable slots found.\n"); 521 printf("No bootable slots found.\n");
512 ret = -1; 522 ret = -1;
513 goto end; 523 goto end;
514 } else if (!ab_data.slots[slot_index_to_boot].successful_boot && 524 } else if (!ab_data.slots[slot_index_to_boot].successful_boot &&
515 (ab_data.slots[slot_index_to_boot].tries_remaining > 0)) { 525 (ab_data.slots[slot_index_to_boot].tries_remaining > 0)) {
516 /* Set the bootloader_verified flag as if current slot only has one chance. */ 526 /* Set the bootloader_verified flag as if current slot only has one chance. */
517 if (ab_data.slots[slot_index_to_boot].tries_remaining == 1) 527 if (ab_data.slots[slot_index_to_boot].tries_remaining == 1)
518 ab_data.slots[slot_index_to_boot].bootloader_verified = 1; 528 ab_data.slots[slot_index_to_boot].bootloader_verified = 1;
519 ab_data.slots[slot_index_to_boot].tries_remaining -= 1; 529 ab_data.slots[slot_index_to_boot].tries_remaining -= 1;
520 } 530 }
521 printf("Booting from bootloader%s...\n", slot_suffixes[slot_index_to_boot]); 531 printf("Booting from bootloader%s...\n", slot_suffixes[slot_index_to_boot]);
522 532
523 end: 533 end:
524 /* Save metadata if changed. */ 534 /* Save metadata if changed. */
525 if (fsl_save_metadata_if_changed_dual_uboot(dev_desc, &ab_data, &ab_data_orig)) { 535 if (fsl_save_metadata_if_changed_dual_uboot(dev_desc, &ab_data, &ab_data_orig)) {
526 ret = -1; 536 ret = -1;
527 } 537 }
528 538
529 if (ret) 539 if (ret)
530 return -1; 540 return -1;
531 else 541 else
532 return 0; 542 return 0;
533 } 543 }
534 544
535 /* 545 /*
536 * spl_fit_get_rbindex(): Get rollback index of the bootloader. 546 * spl_fit_get_rbindex(): Get rollback index of the bootloader.
537 * @fit: Pointer to the FDT blob. 547 * @fit: Pointer to the FDT blob.
538 * @images: Offset of the /images subnode. 548 * @images: Offset of the /images subnode.
539 * 549 *
540 * Return: the rollback index value of bootloader or a negative 550 * Return: the rollback index value of bootloader or a negative
541 * error number. 551 * error number.
542 */ 552 */
543 int spl_fit_get_rbindex(const void *fit, int images) 553 int spl_fit_get_rbindex(const void *fit, int images)
544 { 554 {
545 const char *str; 555 const char *str;
546 uint64_t index; 556 uint64_t index;
547 int conf_node; 557 int conf_node;
548 int len; 558 int len;
549 559
550 conf_node = fit_find_config_node(fit); 560 conf_node = fit_find_config_node(fit);
551 if (conf_node < 0) { 561 if (conf_node < 0) {
552 return conf_node; 562 return conf_node;
553 } 563 }
554 564
555 str = fdt_getprop(fit, conf_node, "rbindex", &len); 565 str = fdt_getprop(fit, conf_node, "rbindex", &len);
556 if (!str) { 566 if (!str) {
557 debug("cannot find property 'rbindex'\n"); 567 debug("cannot find property 'rbindex'\n");
558 return -EINVAL; 568 return -EINVAL;
559 } 569 }
560 570
561 index = simple_strtoul(str, NULL, 10); 571 index = simple_strtoul(str, NULL, 10);
562 572
563 return index; 573 return index;
564 } 574 }
565 #endif /* CONFIG_PARSE_CONTAINER */ 575 #endif /* CONFIG_PARSE_CONTAINER */
566 576
567 /* For normal build */ 577 /* For normal build */
568 #elif !defined(CONFIG_SPL_BUILD) 578 #elif !defined(CONFIG_SPL_BUILD)
569 579
570 /* Writes A/B metadata to disk only if it has been changed. 580 /* Writes A/B metadata to disk only if it has been changed.
571 */ 581 */
572 static AvbIOResult fsl_save_metadata_if_changed(AvbABOps* ab_ops, 582 static AvbIOResult fsl_save_metadata_if_changed(AvbABOps* ab_ops,
573 AvbABData* ab_data, 583 AvbABData* ab_data,
574 AvbABData* ab_data_orig) { 584 AvbABData* ab_data_orig) {
575 if (avb_safe_memcmp(ab_data, ab_data_orig, sizeof(AvbABData)) != 0) { 585 if (avb_safe_memcmp(ab_data, ab_data_orig, sizeof(AvbABData)) != 0) {
576 avb_debug("Writing A/B metadata to disk.\n"); 586 avb_debug("Writing A/B metadata to disk.\n");
577 return ab_ops->write_ab_metadata(ab_ops, ab_data); 587 return ab_ops->write_ab_metadata(ab_ops, ab_data);
578 } 588 }
579 return AVB_IO_RESULT_OK; 589 return AVB_IO_RESULT_OK;
580 } 590 }
581 591
582 /* Helper function to load metadata - returns AVB_IO_RESULT_OK on 592 /* Helper function to load metadata - returns AVB_IO_RESULT_OK on
583 * success, error code otherwise. This is a copy of load_metadata() 593 * success, error code otherwise. This is a copy of load_metadata()
584 * from /lib/avb/libavb_ab/avb_ab_flow.c. 594 * from /lib/avb/libavb_ab/avb_ab_flow.c.
585 */ 595 */
586 static AvbIOResult fsl_load_metadata(AvbABOps* ab_ops, 596 static AvbIOResult fsl_load_metadata(AvbABOps* ab_ops,
587 AvbABData* ab_data, 597 AvbABData* ab_data,
588 AvbABData* ab_data_orig) { 598 AvbABData* ab_data_orig) {
589 AvbIOResult io_ret; 599 AvbIOResult io_ret;
590 600
591 io_ret = ab_ops->read_ab_metadata(ab_ops, ab_data); 601 io_ret = ab_ops->read_ab_metadata(ab_ops, ab_data);
592 if (io_ret != AVB_IO_RESULT_OK) { 602 if (io_ret != AVB_IO_RESULT_OK) {
593 avb_error("I/O error while loading A/B metadata.\n"); 603 avb_error("I/O error while loading A/B metadata.\n");
594 return io_ret; 604 return io_ret;
595 } 605 }
596 *ab_data_orig = *ab_data; 606 *ab_data_orig = *ab_data;
597 607
598 /* Ensure data is normalized, e.g. illegal states will be marked as 608 /* Ensure data is normalized, e.g. illegal states will be marked as
599 * unbootable and all unbootable states are represented with 609 * unbootable and all unbootable states are represented with
600 * (priority=0, tries_remaining=0, successful_boot=0). 610 * (priority=0, tries_remaining=0, successful_boot=0).
601 */ 611 */
602 fsl_slot_normalize(&ab_data->slots[0]); 612 fsl_slot_normalize(&ab_data->slots[0]);
603 fsl_slot_normalize(&ab_data->slots[1]); 613 fsl_slot_normalize(&ab_data->slots[1]);
604 return AVB_IO_RESULT_OK; 614 return AVB_IO_RESULT_OK;
605 } 615 }
606 616
607 #ifdef CONFIG_DUAL_BOOTLOADER 617 #ifdef CONFIG_DUAL_BOOTLOADER
608 AvbABFlowResult avb_flow_dual_uboot(AvbABOps* ab_ops, 618 AvbABFlowResult avb_flow_dual_uboot(AvbABOps* ab_ops,
609 const char* const* requested_partitions, 619 const char* const* requested_partitions,
610 AvbSlotVerifyFlags flags, 620 AvbSlotVerifyFlags flags,
611 AvbHashtreeErrorMode hashtree_error_mode, 621 AvbHashtreeErrorMode hashtree_error_mode,
612 AvbSlotVerifyData** out_data) { 622 AvbSlotVerifyData** out_data) {
613 AvbOps* ops = ab_ops->ops; 623 AvbOps* ops = ab_ops->ops;
614 AvbSlotVerifyData* slot_data = NULL; 624 AvbSlotVerifyData* slot_data = NULL;
615 AvbSlotVerifyData* data = NULL; 625 AvbSlotVerifyData* data = NULL;
616 AvbABFlowResult ret; 626 AvbABFlowResult ret;
617 AvbABData ab_data, ab_data_orig; 627 AvbABData ab_data, ab_data_orig;
618 AvbIOResult io_ret; 628 AvbIOResult io_ret;
619 bool saw_and_allowed_verification_error = false; 629 bool saw_and_allowed_verification_error = false;
620 AvbSlotVerifyResult verify_result; 630 AvbSlotVerifyResult verify_result;
621 bool set_slot_unbootable = false; 631 bool set_slot_unbootable = false;
622 int target_slot, n; 632 int target_slot, n;
623 uint64_t rollback_index_value = 0; 633 uint64_t rollback_index_value = 0;
624 uint64_t current_rollback_index_value = 0; 634 uint64_t current_rollback_index_value = 0;
625 635
626 io_ret = fsl_load_metadata(ab_ops, &ab_data, &ab_data_orig); 636 io_ret = fsl_load_metadata(ab_ops, &ab_data, &ab_data_orig);
627 if (io_ret == AVB_IO_RESULT_ERROR_OOM) { 637 if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
628 ret = AVB_AB_FLOW_RESULT_ERROR_OOM; 638 ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
629 goto out; 639 goto out;
630 } else if (io_ret != AVB_IO_RESULT_OK) { 640 } else if (io_ret != AVB_IO_RESULT_OK) {
631 ret = AVB_AB_FLOW_RESULT_ERROR_IO; 641 ret = AVB_AB_FLOW_RESULT_ERROR_IO;
632 goto out; 642 goto out;
633 } 643 }
634 644
635 /* Choose the target slot, it should be the same with the one in SPL. */ 645 /* Choose the target slot, it should be the same with the one in SPL. */
636 target_slot = get_curr_slot(&ab_data); 646 target_slot = get_curr_slot(&ab_data);
637 if (target_slot == -1) { 647 if (target_slot == -1) {
638 ret = AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS; 648 ret = AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS;
639 printf("No bootable slot found!\n"); 649 printf("No bootable slot found!\n");
640 goto out; 650 goto out;
641 } 651 }
642 /* Clear the bootloader_verified flag. */ 652 /* Clear the bootloader_verified flag. */
643 ab_data.slots[target_slot].bootloader_verified = 0; 653 ab_data.slots[target_slot].bootloader_verified = 0;
644 654
645 printf("Verifying slot %s ...\n", slot_suffixes[target_slot]); 655 printf("Verifying slot %s ...\n", slot_suffixes[target_slot]);
646 verify_result = avb_slot_verify(ops, 656 verify_result = avb_slot_verify(ops,
647 requested_partitions, 657 requested_partitions,
648 slot_suffixes[target_slot], 658 slot_suffixes[target_slot],
649 flags, 659 flags,
650 hashtree_error_mode, 660 hashtree_error_mode,
651 &slot_data); 661 &slot_data);
652 662
653 switch (verify_result) { 663 switch (verify_result) {
654 case AVB_SLOT_VERIFY_RESULT_ERROR_OOM: 664 case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
655 ret = AVB_AB_FLOW_RESULT_ERROR_OOM; 665 ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
656 goto out; 666 goto out;
657 667
658 case AVB_SLOT_VERIFY_RESULT_ERROR_IO: 668 case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
659 ret = AVB_AB_FLOW_RESULT_ERROR_IO; 669 ret = AVB_AB_FLOW_RESULT_ERROR_IO;
660 goto out; 670 goto out;
661 671
662 case AVB_SLOT_VERIFY_RESULT_OK: 672 case AVB_SLOT_VERIFY_RESULT_OK:
663 ret = AVB_AB_FLOW_RESULT_OK; 673 ret = AVB_AB_FLOW_RESULT_OK;
664 break; 674 break;
665 675
666 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA: 676 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
667 case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION: 677 case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
668 /* Even with AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR 678 /* Even with AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR
669 * these mean game over. 679 * these mean game over.
670 */ 680 */
671 set_slot_unbootable = true; 681 set_slot_unbootable = true;
672 break; 682 break;
673 683
674 case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION: 684 case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
675 case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX: 685 case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
676 case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED: 686 case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
677 if (flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR) { 687 if (flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR) {
678 /* Do nothing since we allow this. */ 688 /* Do nothing since we allow this. */
679 avb_debugv("Allowing slot ", 689 avb_debugv("Allowing slot ",
680 slot_suffixes[target_slot], 690 slot_suffixes[target_slot],
681 " which verified " 691 " which verified "
682 "with result ", 692 "with result ",
683 avb_slot_verify_result_to_string(verify_result), 693 avb_slot_verify_result_to_string(verify_result),
684 " because " 694 " because "
685 "AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR " 695 "AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR "
686 "is set.\n", 696 "is set.\n",
687 NULL); 697 NULL);
688 saw_and_allowed_verification_error = 698 saw_and_allowed_verification_error =
689 true; 699 true;
690 } else { 700 } else {
691 set_slot_unbootable = true; 701 set_slot_unbootable = true;
692 } 702 }
693 break; 703 break;
694 704
695 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT: 705 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
696 ret = AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT; 706 ret = AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT;
697 goto out; 707 goto out;
698 /* Do not add a 'default:' case here because 708 /* Do not add a 'default:' case here because
699 * of -Wswitch. 709 * of -Wswitch.
700 */ 710 */
701 } 711 }
702 712
703 if (set_slot_unbootable) { 713 if (set_slot_unbootable) {
704 avb_errorv("Error verifying slot ", 714 avb_errorv("Error verifying slot ",
705 slot_suffixes[target_slot], 715 slot_suffixes[target_slot],
706 " with result ", 716 " with result ",
707 avb_slot_verify_result_to_string(verify_result), 717 avb_slot_verify_result_to_string(verify_result),
708 " - setting unbootable.\n", 718 " - setting unbootable.\n",
709 NULL); 719 NULL);
710 fsl_slot_set_unbootable(&ab_data.slots[target_slot]); 720 fsl_slot_set_unbootable(&ab_data.slots[target_slot]);
711 721
712 /* Only the slot chosen by SPL will be verified here so we 722 /* Only the slot chosen by SPL will be verified here so we
713 * return AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS if the 723 * return AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS if the
714 * slot should be set unbootable. 724 * slot should be set unbootable.
715 */ 725 */
716 ret = AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS; 726 ret = AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS;
717 goto out; 727 goto out;
718 } 728 }
719 729
720 /* Update stored rollback index only when the slot has been marked 730 /* Update stored rollback index only when the slot has been marked
721 * as successful. Do this for every rollback index location. 731 * as successful. Do this for every rollback index location.
722 */ 732 */
723 if (ab_data.slots[target_slot].successful_boot != 0) { 733 if (ab_data.slots[target_slot].successful_boot != 0) {
724 for (n = 0; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) { 734 for (n = 0; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
725 735
726 rollback_index_value = slot_data->rollback_indexes[n]; 736 rollback_index_value = slot_data->rollback_indexes[n];
727 737
728 if (rollback_index_value != 0) { 738 if (rollback_index_value != 0) {
729 io_ret = ops->read_rollback_index( 739 io_ret = ops->read_rollback_index(
730 ops, n, &current_rollback_index_value); 740 ops, n, &current_rollback_index_value);
731 if (io_ret == AVB_IO_RESULT_ERROR_OOM) { 741 if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
732 ret = AVB_AB_FLOW_RESULT_ERROR_OOM; 742 ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
733 goto out; 743 goto out;
734 } else if (io_ret != AVB_IO_RESULT_OK) { 744 } else if (io_ret != AVB_IO_RESULT_OK) {
735 avb_error("Error getting rollback index for slot.\n"); 745 avb_error("Error getting rollback index for slot.\n");
736 ret = AVB_AB_FLOW_RESULT_ERROR_IO; 746 ret = AVB_AB_FLOW_RESULT_ERROR_IO;
737 goto out; 747 goto out;
738 } 748 }
739 if (current_rollback_index_value != rollback_index_value) { 749 if (current_rollback_index_value != rollback_index_value) {
740 io_ret = ops->write_rollback_index( 750 io_ret = ops->write_rollback_index(
741 ops, n, rollback_index_value); 751 ops, n, rollback_index_value);
742 if (io_ret == AVB_IO_RESULT_ERROR_OOM) { 752 if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
743 ret = AVB_AB_FLOW_RESULT_ERROR_OOM; 753 ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
744 goto out; 754 goto out;
745 } else if (io_ret != AVB_IO_RESULT_OK) { 755 } else if (io_ret != AVB_IO_RESULT_OK) {
746 avb_error("Error setting stored rollback index.\n"); 756 avb_error("Error setting stored rollback index.\n");
747 ret = AVB_AB_FLOW_RESULT_ERROR_IO; 757 ret = AVB_AB_FLOW_RESULT_ERROR_IO;
748 goto out; 758 goto out;
749 } 759 }
750 } 760 }
751 } 761 }
752 } 762 }
753 } 763 }
754 764
755 /* Finally, select this slot. */ 765 /* Finally, select this slot. */
756 avb_assert(slot_data != NULL); 766 avb_assert(slot_data != NULL);
757 data = slot_data; 767 data = slot_data;
758 slot_data = NULL; 768 slot_data = NULL;
759 if (saw_and_allowed_verification_error) { 769 if (saw_and_allowed_verification_error) {
760 avb_assert( 770 avb_assert(
761 flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR); 771 flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR);
762 ret = AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR; 772 ret = AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR;
763 } else { 773 } else {
764 ret = AVB_AB_FLOW_RESULT_OK; 774 ret = AVB_AB_FLOW_RESULT_OK;
765 } 775 }
766 776
767 out: 777 out:
768 io_ret = fsl_save_metadata_if_changed(ab_ops, &ab_data, &ab_data_orig); 778 io_ret = fsl_save_metadata_if_changed(ab_ops, &ab_data, &ab_data_orig);
769 if (io_ret != AVB_IO_RESULT_OK) { 779 if (io_ret != AVB_IO_RESULT_OK) {
770 if (io_ret == AVB_IO_RESULT_ERROR_OOM) { 780 if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
771 ret = AVB_AB_FLOW_RESULT_ERROR_OOM; 781 ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
772 } else { 782 } else {
773 ret = AVB_AB_FLOW_RESULT_ERROR_IO; 783 ret = AVB_AB_FLOW_RESULT_ERROR_IO;
774 } 784 }
775 if (data != NULL) { 785 if (data != NULL) {
776 avb_slot_verify_data_free(data); 786 avb_slot_verify_data_free(data);
777 data = NULL; 787 data = NULL;
778 } 788 }
779 } 789 }
780 790
781 if (slot_data != NULL) 791 if (slot_data != NULL)
782 avb_slot_verify_data_free(slot_data); 792 avb_slot_verify_data_free(slot_data);
783 793
784 if (out_data != NULL) { 794 if (out_data != NULL) {
785 *out_data = data; 795 *out_data = data;
786 } else { 796 } else {
787 if (data != NULL) { 797 if (data != NULL) {
788 avb_slot_verify_data_free(data); 798 avb_slot_verify_data_free(data);
789 } 799 }
790 } 800 }
791 801
792 return ret; 802 return ret;
793 } 803 }
794 #else /* CONFIG_DUAL_BOOTLOADER */ 804 #else /* CONFIG_DUAL_BOOTLOADER */
795 /* For legacy i.mx6/7, we won't enable A/B due to the limitation of 805 /* For legacy i.mx6/7, we won't enable A/B due to the limitation of
796 * storage capacity, but we still want to verify boot/recovery with 806 * storage capacity, but we still want to verify boot/recovery with
797 * AVB. */ 807 * AVB. */
798 AvbABFlowResult avb_single_flow(AvbABOps* ab_ops, 808 AvbABFlowResult avb_single_flow(AvbABOps* ab_ops,
799 const char* const* requested_partitions, 809 const char* const* requested_partitions,
800 AvbSlotVerifyFlags flags, 810 AvbSlotVerifyFlags flags,
801 AvbHashtreeErrorMode hashtree_error_mode, 811 AvbHashtreeErrorMode hashtree_error_mode,
802 AvbSlotVerifyData** out_data) { 812 AvbSlotVerifyData** out_data) {
803 AvbOps* ops = ab_ops->ops; 813 AvbOps* ops = ab_ops->ops;
804 AvbSlotVerifyData* slot_data = NULL; 814 AvbSlotVerifyData* slot_data = NULL;
805 AvbSlotVerifyData* data = NULL; 815 AvbSlotVerifyData* data = NULL;
806 AvbABFlowResult ret; 816 AvbABFlowResult ret;
807 bool saw_and_allowed_verification_error = false; 817 bool saw_and_allowed_verification_error = false;
808 818
809 /* Validate boot/recovery. */ 819 /* Validate boot/recovery. */
810 AvbSlotVerifyResult verify_result; 820 AvbSlotVerifyResult verify_result;
811 821
812 verify_result = avb_slot_verify(ops, 822 verify_result = avb_slot_verify(ops,
813 requested_partitions, 823 requested_partitions,
814 "", 824 "",
815 flags, 825 flags,
816 hashtree_error_mode, 826 hashtree_error_mode,
817 &slot_data); 827 &slot_data);
818 switch (verify_result) { 828 switch (verify_result) {
819 case AVB_SLOT_VERIFY_RESULT_ERROR_OOM: 829 case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
820 ret = AVB_AB_FLOW_RESULT_ERROR_OOM; 830 ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
821 goto out; 831 goto out;
822 832
823 case AVB_SLOT_VERIFY_RESULT_ERROR_IO: 833 case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
824 ret = AVB_AB_FLOW_RESULT_ERROR_IO; 834 ret = AVB_AB_FLOW_RESULT_ERROR_IO;
825 goto out; 835 goto out;
826 836
827 case AVB_SLOT_VERIFY_RESULT_OK: 837 case AVB_SLOT_VERIFY_RESULT_OK:
828 break; 838 break;
829 839
830 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA: 840 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
831 case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION: 841 case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
832 /* Even with AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR 842 /* Even with AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR
833 * these mean game over. 843 * these mean game over.
834 */ 844 */
835 ret = AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS; 845 ret = AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS;
836 goto out; 846 goto out;
837 847
838 /* explicit fallthrough. */ 848 /* explicit fallthrough. */
839 case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION: 849 case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
840 case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX: 850 case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
841 case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED: 851 case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
842 if (flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR) { 852 if (flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR) {
843 /* Do nothing since we allow this. */ 853 /* Do nothing since we allow this. */
844 avb_debugv("Allowing slot ", 854 avb_debugv("Allowing slot ",
845 slot_suffixes[n], 855 slot_suffixes[n],
846 " which verified " 856 " which verified "
847 "with result ", 857 "with result ",
848 avb_slot_verify_result_to_string(verify_result), 858 avb_slot_verify_result_to_string(verify_result),
849 " because " 859 " because "
850 "AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR " 860 "AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR "
851 "is set.\n", 861 "is set.\n",
852 NULL); 862 NULL);
853 saw_and_allowed_verification_error = true; 863 saw_and_allowed_verification_error = true;
854 } else { 864 } else {
855 ret = AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS; 865 ret = AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS;
856 goto out; 866 goto out;
857 } 867 }
858 break; 868 break;
859 869
860 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT: 870 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
861 ret = AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT; 871 ret = AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT;
862 goto out; 872 goto out;
863 /* Do not add a 'default:' case here because of -Wswitch. */ 873 /* Do not add a 'default:' case here because of -Wswitch. */
864 } 874 }
865 875
866 avb_assert(slot_data != NULL); 876 avb_assert(slot_data != NULL);
867 data = slot_data; 877 data = slot_data;
868 slot_data = NULL; 878 slot_data = NULL;
869 if (saw_and_allowed_verification_error) { 879 if (saw_and_allowed_verification_error) {
870 avb_assert(flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR); 880 avb_assert(flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR);
871 ret = AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR; 881 ret = AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR;
872 } else { 882 } else {
873 ret = AVB_AB_FLOW_RESULT_OK; 883 ret = AVB_AB_FLOW_RESULT_OK;
874 } 884 }
875 885
876 out: 886 out:
877 if (slot_data != NULL) { 887 if (slot_data != NULL) {
878 avb_slot_verify_data_free(slot_data); 888 avb_slot_verify_data_free(slot_data);
879 } 889 }
880 890
881 if (out_data != NULL) { 891 if (out_data != NULL) {
882 *out_data = data; 892 *out_data = data;
883 } else { 893 } else {
884 if (data != NULL) { 894 if (data != NULL) {
885 avb_slot_verify_data_free(data); 895 avb_slot_verify_data_free(data);
886 } 896 }
887 } 897 }
888 898
889 return ret; 899 return ret;
890 } 900 }
891 901
892 AvbABFlowResult avb_ab_flow_fast(AvbABOps* ab_ops, 902 AvbABFlowResult avb_ab_flow_fast(AvbABOps* ab_ops,
893 const char* const* requested_partitions, 903 const char* const* requested_partitions,
894 AvbSlotVerifyFlags flags, 904 AvbSlotVerifyFlags flags,
895 AvbHashtreeErrorMode hashtree_error_mode, 905 AvbHashtreeErrorMode hashtree_error_mode,
896 AvbSlotVerifyData** out_data) { 906 AvbSlotVerifyData** out_data) {
897 AvbOps* ops = ab_ops->ops; 907 AvbOps* ops = ab_ops->ops;
898 AvbSlotVerifyData* slot_data[2] = {NULL, NULL}; 908 AvbSlotVerifyData* slot_data[2] = {NULL, NULL};
899 AvbSlotVerifyData* data = NULL; 909 AvbSlotVerifyData* data = NULL;
900 AvbABFlowResult ret; 910 AvbABFlowResult ret;
901 AvbABData ab_data, ab_data_orig; 911 AvbABData ab_data, ab_data_orig;
902 size_t slot_index_to_boot, n; 912 size_t slot_index_to_boot, n;
903 AvbIOResult io_ret; 913 AvbIOResult io_ret;
904 bool saw_and_allowed_verification_error = false; 914 bool saw_and_allowed_verification_error = false;
905 size_t target_slot; 915 size_t target_slot;
906 AvbSlotVerifyResult verify_result; 916 AvbSlotVerifyResult verify_result;
907 bool set_slot_unbootable = false; 917 bool set_slot_unbootable = false;
908 uint64_t rollback_index_value = 0; 918 uint64_t rollback_index_value = 0;
909 uint64_t current_rollback_index_value = 0; 919 uint64_t current_rollback_index_value = 0;
910 920
911 io_ret = fsl_load_metadata(ab_ops, &ab_data, &ab_data_orig); 921 io_ret = fsl_load_metadata(ab_ops, &ab_data, &ab_data_orig);
912 if (io_ret == AVB_IO_RESULT_ERROR_OOM) { 922 if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
913 ret = AVB_AB_FLOW_RESULT_ERROR_OOM; 923 ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
914 goto out; 924 goto out;
915 } else if (io_ret != AVB_IO_RESULT_OK) { 925 } else if (io_ret != AVB_IO_RESULT_OK) {
916 ret = AVB_AB_FLOW_RESULT_ERROR_IO; 926 ret = AVB_AB_FLOW_RESULT_ERROR_IO;
917 goto out; 927 goto out;
918 } 928 }
919 929
920 slot_index_to_boot = 2; // Means not 0 or 1 930 slot_index_to_boot = 2; // Means not 0 or 1
921 target_slot = 931 target_slot =
922 (ab_data.slots[1].priority > ab_data.slots[0].priority) ? 1 : 0; 932 (ab_data.slots[1].priority > ab_data.slots[0].priority) ? 1 : 0;
923 933
924 for (n = 0; n < 2; n++) { 934 for (n = 0; n < 2; n++) {
925 if (!fsl_slot_is_bootable(&ab_data.slots[target_slot])) { 935 if (!fsl_slot_is_bootable(&ab_data.slots[target_slot])) {
926 target_slot = (target_slot == 1 ? 0 : 1); 936 target_slot = (target_slot == 1 ? 0 : 1);
927 continue; 937 continue;
928 } 938 }
929 verify_result = avb_slot_verify(ops, 939 verify_result = avb_slot_verify(ops,
930 requested_partitions, 940 requested_partitions,
931 slot_suffixes[target_slot], 941 slot_suffixes[target_slot],
932 flags, 942 flags,
933 hashtree_error_mode, 943 hashtree_error_mode,
934 &slot_data[target_slot]); 944 &slot_data[target_slot]);
935 switch (verify_result) { 945 switch (verify_result) {
936 case AVB_SLOT_VERIFY_RESULT_ERROR_OOM: 946 case AVB_SLOT_VERIFY_RESULT_ERROR_OOM:
937 ret = AVB_AB_FLOW_RESULT_ERROR_OOM; 947 ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
938 goto out; 948 goto out;
939 949
940 case AVB_SLOT_VERIFY_RESULT_ERROR_IO: 950 case AVB_SLOT_VERIFY_RESULT_ERROR_IO:
941 ret = AVB_AB_FLOW_RESULT_ERROR_IO; 951 ret = AVB_AB_FLOW_RESULT_ERROR_IO;
942 goto out; 952 goto out;
943 953
944 case AVB_SLOT_VERIFY_RESULT_OK: 954 case AVB_SLOT_VERIFY_RESULT_OK:
945 slot_index_to_boot = target_slot; 955 slot_index_to_boot = target_slot;
946 n = 2; 956 n = 2;
947 break; 957 break;
948 958
949 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA: 959 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_METADATA:
950 case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION: 960 case AVB_SLOT_VERIFY_RESULT_ERROR_UNSUPPORTED_VERSION:
951 /* Even with AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR 961 /* Even with AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR
952 * these mean game over. 962 * these mean game over.
953 */ 963 */
954 set_slot_unbootable = true; 964 set_slot_unbootable = true;
955 break; 965 break;
956 966
957 /* explicit fallthrough. */ 967 /* explicit fallthrough. */
958 case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION: 968 case AVB_SLOT_VERIFY_RESULT_ERROR_VERIFICATION:
959 case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX: 969 case AVB_SLOT_VERIFY_RESULT_ERROR_ROLLBACK_INDEX:
960 case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED: 970 case AVB_SLOT_VERIFY_RESULT_ERROR_PUBLIC_KEY_REJECTED:
961 if (flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR) { 971 if (flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR) {
962 /* Do nothing since we allow this. */ 972 /* Do nothing since we allow this. */
963 avb_debugv("Allowing slot ", 973 avb_debugv("Allowing slot ",
964 slot_suffixes[target_slot], 974 slot_suffixes[target_slot],
965 " which verified " 975 " which verified "
966 "with result ", 976 "with result ",
967 avb_slot_verify_result_to_string(verify_result), 977 avb_slot_verify_result_to_string(verify_result),
968 " because " 978 " because "
969 "AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR " 979 "AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR "
970 "is set.\n", 980 "is set.\n",
971 NULL); 981 NULL);
972 saw_and_allowed_verification_error = 982 saw_and_allowed_verification_error =
973 true; 983 true;
974 slot_index_to_boot = target_slot; 984 slot_index_to_boot = target_slot;
975 n = 2; 985 n = 2;
976 } else { 986 } else {
977 set_slot_unbootable = true; 987 set_slot_unbootable = true;
978 } 988 }
979 break; 989 break;
980 990
981 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT: 991 case AVB_SLOT_VERIFY_RESULT_ERROR_INVALID_ARGUMENT:
982 ret = AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT; 992 ret = AVB_AB_FLOW_RESULT_ERROR_INVALID_ARGUMENT;
983 goto out; 993 goto out;
984 /* Do not add a 'default:' case here because 994 /* Do not add a 'default:' case here because
985 * of -Wswitch. 995 * of -Wswitch.
986 */ 996 */
987 } 997 }
988 998
989 if (set_slot_unbootable) { 999 if (set_slot_unbootable) {
990 avb_errorv("Error verifying slot ", 1000 avb_errorv("Error verifying slot ",
991 slot_suffixes[target_slot], 1001 slot_suffixes[target_slot],
992 " with result ", 1002 " with result ",
993 avb_slot_verify_result_to_string(verify_result), 1003 avb_slot_verify_result_to_string(verify_result),
994 " - setting unbootable.\n", 1004 " - setting unbootable.\n",
995 NULL); 1005 NULL);
996 fsl_slot_set_unbootable(&ab_data.slots[target_slot]); 1006 fsl_slot_set_unbootable(&ab_data.slots[target_slot]);
997 set_slot_unbootable = false; 1007 set_slot_unbootable = false;
998 } 1008 }
999 /* switch to another slot */ 1009 /* switch to another slot */
1000 target_slot = (target_slot == 1 ? 0 : 1); 1010 target_slot = (target_slot == 1 ? 0 : 1);
1001 } 1011 }
1002 1012
1003 if (slot_index_to_boot == 2) { 1013 if (slot_index_to_boot == 2) {
1004 /* No bootable slots! */ 1014 /* No bootable slots! */
1005 avb_error("No bootable slots found.\n"); 1015 avb_error("No bootable slots found.\n");
1006 ret = AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS; 1016 ret = AVB_AB_FLOW_RESULT_ERROR_NO_BOOTABLE_SLOTS;
1007 goto out; 1017 goto out;
1008 } 1018 }
1009 1019
1010 /* Update stored rollback index only when the slot has been marked 1020 /* Update stored rollback index only when the slot has been marked
1011 * as successful. Do this for every rollback index location. 1021 * as successful. Do this for every rollback index location.
1012 */ 1022 */
1013 if (ab_data.slots[slot_index_to_boot].successful_boot != 0) { 1023 if (ab_data.slots[slot_index_to_boot].successful_boot != 0) {
1014 for (n = 0; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) { 1024 for (n = 0; n < AVB_MAX_NUMBER_OF_ROLLBACK_INDEX_LOCATIONS; n++) {
1015 1025
1016 rollback_index_value = slot_data[slot_index_to_boot]->rollback_indexes[n]; 1026 rollback_index_value = slot_data[slot_index_to_boot]->rollback_indexes[n];
1017 1027
1018 if (rollback_index_value != 0) { 1028 if (rollback_index_value != 0) {
1019 io_ret = ops->read_rollback_index( 1029 io_ret = ops->read_rollback_index(
1020 ops, n, &current_rollback_index_value); 1030 ops, n, &current_rollback_index_value);
1021 if (io_ret == AVB_IO_RESULT_ERROR_OOM) { 1031 if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
1022 ret = AVB_AB_FLOW_RESULT_ERROR_OOM; 1032 ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
1023 goto out; 1033 goto out;
1024 } else if (io_ret != AVB_IO_RESULT_OK) { 1034 } else if (io_ret != AVB_IO_RESULT_OK) {
1025 avb_error("Error getting rollback index for slot.\n"); 1035 avb_error("Error getting rollback index for slot.\n");
1026 ret = AVB_AB_FLOW_RESULT_ERROR_IO; 1036 ret = AVB_AB_FLOW_RESULT_ERROR_IO;
1027 goto out; 1037 goto out;
1028 } 1038 }
1029 if (current_rollback_index_value != rollback_index_value) { 1039 if (current_rollback_index_value != rollback_index_value) {
1030 io_ret = ops->write_rollback_index( 1040 io_ret = ops->write_rollback_index(
1031 ops, n, rollback_index_value); 1041 ops, n, rollback_index_value);
1032 if (io_ret == AVB_IO_RESULT_ERROR_OOM) { 1042 if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
1033 ret = AVB_AB_FLOW_RESULT_ERROR_OOM; 1043 ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
1034 goto out; 1044 goto out;
1035 } else if (io_ret != AVB_IO_RESULT_OK) { 1045 } else if (io_ret != AVB_IO_RESULT_OK) {
1036 avb_error("Error setting stored rollback index.\n"); 1046 avb_error("Error setting stored rollback index.\n");
1037 ret = AVB_AB_FLOW_RESULT_ERROR_IO; 1047 ret = AVB_AB_FLOW_RESULT_ERROR_IO;
1038 goto out; 1048 goto out;
1039 } 1049 }
1040 } 1050 }
1041 } 1051 }
1042 } 1052 }
1043 } 1053 }
1044 1054
1045 /* Finally, select this slot. */ 1055 /* Finally, select this slot. */
1046 avb_assert(slot_data[slot_index_to_boot] != NULL); 1056 avb_assert(slot_data[slot_index_to_boot] != NULL);
1047 data = slot_data[slot_index_to_boot]; 1057 data = slot_data[slot_index_to_boot];
1048 slot_data[slot_index_to_boot] = NULL; 1058 slot_data[slot_index_to_boot] = NULL;
1049 if (saw_and_allowed_verification_error) { 1059 if (saw_and_allowed_verification_error) {
1050 avb_assert( 1060 avb_assert(
1051 flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR); 1061 flags & AVB_SLOT_VERIFY_FLAGS_ALLOW_VERIFICATION_ERROR);
1052 ret = AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR; 1062 ret = AVB_AB_FLOW_RESULT_OK_WITH_VERIFICATION_ERROR;
1053 } else { 1063 } else {
1054 ret = AVB_AB_FLOW_RESULT_OK; 1064 ret = AVB_AB_FLOW_RESULT_OK;
1055 } 1065 }
1056 1066
1057 /* ... and decrement tries remaining, if applicable. */ 1067 /* ... and decrement tries remaining, if applicable. */
1058 if (!ab_data.slots[slot_index_to_boot].successful_boot && 1068 if (!ab_data.slots[slot_index_to_boot].successful_boot &&
1059 (ab_data.slots[slot_index_to_boot].tries_remaining > 0)) { 1069 (ab_data.slots[slot_index_to_boot].tries_remaining > 0)) {
1060 ab_data.slots[slot_index_to_boot].tries_remaining -= 1; 1070 ab_data.slots[slot_index_to_boot].tries_remaining -= 1;
1061 } 1071 }
1062 1072
1063 out: 1073 out:
1064 io_ret = fsl_save_metadata_if_changed(ab_ops, &ab_data, &ab_data_orig); 1074 io_ret = fsl_save_metadata_if_changed(ab_ops, &ab_data, &ab_data_orig);
1065 if (io_ret != AVB_IO_RESULT_OK) { 1075 if (io_ret != AVB_IO_RESULT_OK) {
1066 if (io_ret == AVB_IO_RESULT_ERROR_OOM) { 1076 if (io_ret == AVB_IO_RESULT_ERROR_OOM) {
1067 ret = AVB_AB_FLOW_RESULT_ERROR_OOM; 1077 ret = AVB_AB_FLOW_RESULT_ERROR_OOM;
1068 } else { 1078 } else {
1069 ret = AVB_AB_FLOW_RESULT_ERROR_IO; 1079 ret = AVB_AB_FLOW_RESULT_ERROR_IO;
1070 } 1080 }
1071 if (data != NULL) { 1081 if (data != NULL) {
1072 avb_slot_verify_data_free(data); 1082 avb_slot_verify_data_free(data);
1073 data = NULL; 1083 data = NULL;
1074 } 1084 }
1075 } 1085 }
1076 1086
1077 for (n = 0; n < 2; n++) { 1087 for (n = 0; n < 2; n++) {
1078 if (slot_data[n] != NULL) { 1088 if (slot_data[n] != NULL) {
1079 avb_slot_verify_data_free(slot_data[n]); 1089 avb_slot_verify_data_free(slot_data[n]);
1080 } 1090 }
1081 } 1091 }
1082 1092
1083 if (out_data != NULL) { 1093 if (out_data != NULL) {
1084 *out_data = data; 1094 *out_data = data;
1085 } else { 1095 } else {
1086 if (data != NULL) { 1096 if (data != NULL) {
1087 avb_slot_verify_data_free(data); 1097 avb_slot_verify_data_free(data);
1088 } 1098 }
1089 } 1099 }
1090 1100
1091 return ret; 1101 return ret;
1092 } 1102 }
1093 #endif /* CONFIG_DUAL_BOOTLOADER */ 1103 #endif /* CONFIG_DUAL_BOOTLOADER */
1094 1104
1095 #endif /* CONFIG_DUAL_BOOTLOADER && CONFIG_SPL_BUILD */ 1105 #endif /* CONFIG_DUAL_BOOTLOADER && CONFIG_SPL_BUILD */
1096 1106