xref: /rk3399_rockchip-uboot/drivers/usb/gadget/f_fastboot.c (revision 028a3c087958354767360c818b7df81ef657708a)
1 /*
2  * (C) Copyright 2008 - 2009
3  * Windriver, <www.windriver.com>
4  * Tom Rix <Tom.Rix@windriver.com>
5  *
6  * Copyright 2011 Sebastian Andrzej Siewior <bigeasy@linutronix.de>
7  *
8  * Copyright 2014 Linaro, Ltd.
9  * Rob Herring <robh@kernel.org>
10  *
11  * SPDX-License-Identifier:	GPL-2.0+
12  */
13 #include <config.h>
14 #include <common.h>
15 #include <console.h>
16 #include <android_bootloader.h>
17 #include <errno.h>
18 #include <fastboot.h>
19 #include <malloc.h>
20 #include <linux/usb/ch9.h>
21 #include <linux/usb/gadget.h>
22 #include <linux/usb/composite.h>
23 #include <linux/compiler.h>
24 #include <u-boot/sha256.h>
25 #include <version.h>
26 #include <g_dnl.h>
27 #include <fs.h>
28 #include <android_avb/avb_ops_user.h>
29 #include <android_avb/rk_avb_ops_user.h>
30 #include <dm/uclass.h>
31 #include <power/fuel_gauge.h>
32 #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
33 #include <fb_mmc.h>
34 #endif
35 #ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
36 #include <fb_nand.h>
37 #endif
38 #ifdef CONFIG_OPTEE_CLIENT
39 #include <optee_include/OpteeClientInterface.h>
40 #endif
41 #include <boot_rkimg.h>
42 #include <optee_include/tee_client_api.h>
43 #ifdef CONFIG_FASTBOOT_OEM_UNLOCK
44 #include <keymaster.h>
45 #endif
46 
47 #define FASTBOOT_VERSION		"0.4"
48 
49 #define FASTBOOT_INTERFACE_CLASS	0xff
50 #define FASTBOOT_INTERFACE_SUB_CLASS	0x42
51 #define FASTBOOT_INTERFACE_PROTOCOL	0x03
52 
53 #define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_2_0  (0x0200)
54 #define RX_ENDPOINT_MAXIMUM_PACKET_SIZE_1_1  (0x0040)
55 #define TX_ENDPOINT_MAXIMUM_PACKET_SIZE      (0x0040)
56 
57 #define EP_BUFFER_SIZE			4096
58 #define SLEEP_COUNT 20000
59 #define MAX_PART_NUM_STR_SIZE 4
60 #define PARTITION_TYPE_STRINGS "partition-type"
61 
62 /*
63  * EP_BUFFER_SIZE must always be an integral multiple of maxpacket size
64  * (64 or 512 or 1024), else we break on certain controllers like DWC3
65  * that expect bulk OUT requests to be divisible by maxpacket size.
66  */
67 
68 struct f_fastboot {
69 	struct usb_function usb_function;
70 
71 	/* IN/OUT EP's and corresponding requests */
72 	struct usb_ep *in_ep, *out_ep;
73 	struct usb_request *in_req, *out_req;
74 };
75 
76 static inline struct f_fastboot *func_to_fastboot(struct usb_function *f)
77 {
78 	return container_of(f, struct f_fastboot, usb_function);
79 }
80 
81 static struct f_fastboot *fastboot_func;
82 static unsigned int download_size;
83 static unsigned int download_bytes;
84 static unsigned int upload_size;
85 static unsigned int upload_bytes;
86 static bool start_upload;
87 static unsigned intthread_wakeup_needed;
88 
89 static struct usb_endpoint_descriptor fs_ep_in = {
90 	.bLength            = USB_DT_ENDPOINT_SIZE,
91 	.bDescriptorType    = USB_DT_ENDPOINT,
92 	.bEndpointAddress   = USB_DIR_IN,
93 	.bmAttributes       = USB_ENDPOINT_XFER_BULK,
94 	.wMaxPacketSize     = cpu_to_le16(64),
95 };
96 
97 static struct usb_endpoint_descriptor fs_ep_out = {
98 	.bLength		= USB_DT_ENDPOINT_SIZE,
99 	.bDescriptorType	= USB_DT_ENDPOINT,
100 	.bEndpointAddress	= USB_DIR_OUT,
101 	.bmAttributes		= USB_ENDPOINT_XFER_BULK,
102 	.wMaxPacketSize		= cpu_to_le16(64),
103 };
104 
105 static struct usb_endpoint_descriptor hs_ep_in = {
106 	.bLength		= USB_DT_ENDPOINT_SIZE,
107 	.bDescriptorType	= USB_DT_ENDPOINT,
108 	.bEndpointAddress	= USB_DIR_IN,
109 	.bmAttributes		= USB_ENDPOINT_XFER_BULK,
110 	.wMaxPacketSize		= cpu_to_le16(512),
111 };
112 
113 static struct usb_endpoint_descriptor hs_ep_out = {
114 	.bLength		= USB_DT_ENDPOINT_SIZE,
115 	.bDescriptorType	= USB_DT_ENDPOINT,
116 	.bEndpointAddress	= USB_DIR_OUT,
117 	.bmAttributes		= USB_ENDPOINT_XFER_BULK,
118 	.wMaxPacketSize		= cpu_to_le16(512),
119 };
120 
121 static struct usb_endpoint_descriptor ss_ep_in = {
122 	.bLength		= USB_DT_ENDPOINT_SIZE,
123 	.bDescriptorType	= USB_DT_ENDPOINT,
124 	.bEndpointAddress	= USB_DIR_IN,
125 	.bmAttributes		= USB_ENDPOINT_XFER_BULK,
126 	.wMaxPacketSize		= cpu_to_le16(1024),
127 };
128 
129 static struct usb_ss_ep_comp_descriptor ss_ep_in_comp_desc = {
130 	.bLength		= sizeof(ss_ep_in_comp_desc),
131 	.bDescriptorType	= USB_DT_SS_ENDPOINT_COMP,
132 	/* .bMaxBurst		= DYNAMIC, */
133 };
134 
135 static struct usb_endpoint_descriptor ss_ep_out = {
136 	.bLength		= USB_DT_ENDPOINT_SIZE,
137 	.bDescriptorType	= USB_DT_ENDPOINT,
138 	.bEndpointAddress	= USB_DIR_OUT,
139 	.bmAttributes		= USB_ENDPOINT_XFER_BULK,
140 	.wMaxPacketSize		= cpu_to_le16(1024),
141 };
142 
143 static struct usb_ss_ep_comp_descriptor ss_ep_out_comp_desc = {
144 	.bLength		= sizeof(ss_ep_out_comp_desc),
145 	.bDescriptorType	= USB_DT_SS_ENDPOINT_COMP,
146 	/* .bMaxBurst		= DYNAMIC, */
147 };
148 
149 static struct usb_interface_descriptor interface_desc = {
150 	.bLength		= USB_DT_INTERFACE_SIZE,
151 	.bDescriptorType	= USB_DT_INTERFACE,
152 	.bInterfaceNumber	= 0x00,
153 	.bAlternateSetting	= 0x00,
154 	.bNumEndpoints		= 0x02,
155 	.bInterfaceClass	= FASTBOOT_INTERFACE_CLASS,
156 	.bInterfaceSubClass	= FASTBOOT_INTERFACE_SUB_CLASS,
157 	.bInterfaceProtocol	= FASTBOOT_INTERFACE_PROTOCOL,
158 };
159 
160 static struct usb_descriptor_header *fb_fs_function[] = {
161 	(struct usb_descriptor_header *)&interface_desc,
162 	(struct usb_descriptor_header *)&fs_ep_in,
163 	(struct usb_descriptor_header *)&fs_ep_out,
164 };
165 
166 static struct usb_descriptor_header *fb_hs_function[] = {
167 	(struct usb_descriptor_header *)&interface_desc,
168 	(struct usb_descriptor_header *)&hs_ep_in,
169 	(struct usb_descriptor_header *)&hs_ep_out,
170 	NULL,
171 };
172 
173 static struct usb_descriptor_header *fb_ss_function[] = {
174 	(struct usb_descriptor_header *)&interface_desc,
175 	(struct usb_descriptor_header *)&ss_ep_in,
176 	(struct usb_descriptor_header *)&ss_ep_in_comp_desc,
177 	(struct usb_descriptor_header *)&ss_ep_out,
178 	(struct usb_descriptor_header *)&ss_ep_out_comp_desc,
179 	NULL,
180 };
181 
182 static struct usb_endpoint_descriptor *
183 fb_ep_desc(struct usb_gadget *g, struct usb_endpoint_descriptor *fs,
184 	   struct usb_endpoint_descriptor *hs,
185 	   struct usb_endpoint_descriptor *ss,
186 	   struct usb_ss_ep_comp_descriptor *comp_desc,
187 	   struct usb_ep *ep)
188 {
189 	struct usb_endpoint_descriptor *speed_desc = NULL;
190 
191 	/* select desired speed */
192 	switch (g->speed) {
193 	case USB_SPEED_SUPER:
194 		if (gadget_is_superspeed(g)) {
195 			speed_desc = ss;
196 			ep->comp_desc = comp_desc;
197 			break;
198 		}
199 		/* else: Fall trough */
200 	case USB_SPEED_HIGH:
201 		if (gadget_is_dualspeed(g)) {
202 			speed_desc = hs;
203 			break;
204 		}
205 		/* else: fall through */
206 	default:
207 		speed_desc = fs;
208 	}
209 
210 	return speed_desc;
211 }
212 
213 /*
214  * static strings, in UTF-8
215  */
216 static const char fastboot_name[] = "Android Fastboot";
217 
218 static struct usb_string fastboot_string_defs[] = {
219 	[0].s = fastboot_name,
220 	{  }			/* end of list */
221 };
222 
223 static struct usb_gadget_strings stringtab_fastboot = {
224 	.language	= 0x0409,	/* en-us */
225 	.strings	= fastboot_string_defs,
226 };
227 
228 static struct usb_gadget_strings *fastboot_strings[] = {
229 	&stringtab_fastboot,
230 	NULL,
231 };
232 
233 static void rx_handler_command(struct usb_ep *ep, struct usb_request *req);
234 static int strcmp_l1(const char *s1, const char *s2);
235 static void wakeup_thread(void)
236 {
237 	intthread_wakeup_needed = false;
238 }
239 
240 static void busy_indicator(void)
241 {
242 	static int state;
243 
244 	switch (state) {
245 	case 0:
246 		puts("\r|"); break;
247 	case 1:
248 		puts("\r/"); break;
249 	case 2:
250 		puts("\r-"); break;
251 	case 3:
252 		puts("\r\\"); break;
253 	case 4:
254 		puts("\r|"); break;
255 	case 5:
256 		puts("\r/"); break;
257 	case 6:
258 		puts("\r-"); break;
259 	case 7:
260 		puts("\r\\"); break;
261 	default:
262 		state = 0;
263 	}
264 	if (state++ == 8)
265 		state = 0;
266 }
267 
268 static int fb_get_fstype(const char *ifname, const int part_num,
269 			 const char **fs_type)
270 {
271 	char part_num_str[MAX_PART_NUM_STR_SIZE] = {0};
272 
273 	snprintf(part_num_str, ARRAY_SIZE(part_num_str), ":%x", part_num);
274 
275 	if (fs_set_blk_dev(ifname, part_num_str, FS_TYPE_ANY))
276 		return -1;
277 
278 	if (fs_get_fstype(fs_type))
279 		return -1;
280 
281 	return 0;
282 }
283 
284 static int sleep_thread(void)
285 {
286 	int rc = 0;
287 	int i = 0, k = 0;
288 
289 	/* Wait until a signal arrives or we are woken up */
290 	for (;;) {
291 		if (!intthread_wakeup_needed)
292 			break;
293 
294 		if (++i == SLEEP_COUNT) {
295 			busy_indicator();
296 			i = 0;
297 			k++;
298 		}
299 
300 		if (k == 10) {
301 			/* Handle CTRL+C */
302 			if (ctrlc())
303 				return -EPIPE;
304 
305 			/* Check cable connection */
306 			if (!g_dnl_board_usb_cable_connected())
307 				return -EIO;
308 
309 			k = 0;
310 		}
311 
312 		usb_gadget_handle_interrupts(0);
313 	}
314 	intthread_wakeup_needed = true;
315 	return rc;
316 }
317 
318 static void fastboot_complete(struct usb_ep *ep, struct usb_request *req)
319 {
320 	int status = req->status;
321 
322 	wakeup_thread();
323 	if (!status)
324 		return;
325 	printf("status: %d ep '%s' trans: %d\n", status, ep->name, req->actual);
326 }
327 
328 static int fastboot_bind(struct usb_configuration *c, struct usb_function *f)
329 {
330 	int id;
331 	struct usb_gadget *gadget = c->cdev->gadget;
332 	struct f_fastboot *f_fb = func_to_fastboot(f);
333 	const char *s;
334 
335 	/* DYNAMIC interface numbers assignments */
336 	id = usb_interface_id(c, f);
337 	if (id < 0)
338 		return id;
339 	interface_desc.bInterfaceNumber = id;
340 
341 	id = usb_string_id(c->cdev);
342 	if (id < 0)
343 		return id;
344 	fastboot_string_defs[0].id = id;
345 	interface_desc.iInterface = id;
346 
347 	f_fb->in_ep = usb_ep_autoconfig(gadget, &fs_ep_in);
348 	if (!f_fb->in_ep)
349 		return -ENODEV;
350 	f_fb->in_ep->driver_data = c->cdev;
351 
352 	f_fb->out_ep = usb_ep_autoconfig(gadget, &fs_ep_out);
353 	if (!f_fb->out_ep)
354 		return -ENODEV;
355 	f_fb->out_ep->driver_data = c->cdev;
356 
357 	f->descriptors = fb_fs_function;
358 
359 	if (gadget_is_dualspeed(gadget)) {
360 		/* Assume endpoint addresses are the same for both speeds */
361 		hs_ep_in.bEndpointAddress = fs_ep_in.bEndpointAddress;
362 		hs_ep_out.bEndpointAddress = fs_ep_out.bEndpointAddress;
363 		/* copy HS descriptors */
364 		f->hs_descriptors = fb_hs_function;
365 	}
366 
367 	if (gadget_is_superspeed(gadget)) {
368 		/* Assume endpoint addresses are the same as full speed */
369 		ss_ep_in.bEndpointAddress = fs_ep_in.bEndpointAddress;
370 		ss_ep_out.bEndpointAddress = fs_ep_out.bEndpointAddress;
371 		/* copy SS descriptors */
372 		f->ss_descriptors = fb_ss_function;
373 	}
374 
375 	s = env_get("serial#");
376 	if (s)
377 		g_dnl_set_serialnumber((char *)s);
378 
379 	return 0;
380 }
381 
382 static void fastboot_unbind(struct usb_configuration *c, struct usb_function *f)
383 {
384 	memset(fastboot_func, 0, sizeof(*fastboot_func));
385 }
386 
387 static void fastboot_disable(struct usb_function *f)
388 {
389 	struct f_fastboot *f_fb = func_to_fastboot(f);
390 
391 	usb_ep_disable(f_fb->out_ep);
392 	usb_ep_disable(f_fb->in_ep);
393 
394 	if (f_fb->out_req) {
395 		free(f_fb->out_req->buf);
396 		usb_ep_free_request(f_fb->out_ep, f_fb->out_req);
397 		f_fb->out_req = NULL;
398 	}
399 	if (f_fb->in_req) {
400 		free(f_fb->in_req->buf);
401 		usb_ep_free_request(f_fb->in_ep, f_fb->in_req);
402 		f_fb->in_req = NULL;
403 	}
404 }
405 
406 static struct usb_request *fastboot_start_ep(struct usb_ep *ep)
407 {
408 	struct usb_request *req;
409 
410 	req = usb_ep_alloc_request(ep, 0);
411 	if (!req)
412 		return NULL;
413 
414 	req->length = EP_BUFFER_SIZE;
415 	req->buf = memalign(CONFIG_SYS_CACHELINE_SIZE, EP_BUFFER_SIZE);
416 	if (!req->buf) {
417 		usb_ep_free_request(ep, req);
418 		return NULL;
419 	}
420 
421 	memset(req->buf, 0, req->length);
422 	return req;
423 }
424 
425 static int fastboot_set_alt(struct usb_function *f,
426 			    unsigned interface, unsigned alt)
427 {
428 	int ret;
429 	struct usb_composite_dev *cdev = f->config->cdev;
430 	struct usb_gadget *gadget = cdev->gadget;
431 	struct f_fastboot *f_fb = func_to_fastboot(f);
432 	const struct usb_endpoint_descriptor *d;
433 
434 	debug("%s: func: %s intf: %d alt: %d\n",
435 	      __func__, f->name, interface, alt);
436 
437 	d = fb_ep_desc(gadget, &fs_ep_out, &hs_ep_out, &ss_ep_out,
438 		       &ss_ep_out_comp_desc, f_fb->out_ep);
439 	ret = usb_ep_enable(f_fb->out_ep, d);
440 	if (ret) {
441 		puts("failed to enable out ep\n");
442 		return ret;
443 	}
444 
445 	f_fb->out_req = fastboot_start_ep(f_fb->out_ep);
446 	if (!f_fb->out_req) {
447 		puts("failed to alloc out req\n");
448 		ret = -EINVAL;
449 		goto err;
450 	}
451 	f_fb->out_req->complete = rx_handler_command;
452 
453 	d = fb_ep_desc(gadget, &fs_ep_in, &hs_ep_in, &ss_ep_in,
454 		       &ss_ep_in_comp_desc, f_fb->in_ep);
455 	ret = usb_ep_enable(f_fb->in_ep, d);
456 	if (ret) {
457 		puts("failed to enable in ep\n");
458 		goto err;
459 	}
460 
461 	f_fb->in_req = fastboot_start_ep(f_fb->in_ep);
462 	if (!f_fb->in_req) {
463 		puts("failed alloc req in\n");
464 		ret = -EINVAL;
465 		goto err;
466 	}
467 	f_fb->in_req->complete = fastboot_complete;
468 
469 	ret = usb_ep_queue(f_fb->out_ep, f_fb->out_req, 0);
470 	if (ret)
471 		goto err;
472 
473 	return 0;
474 err:
475 	fastboot_disable(f);
476 	return ret;
477 }
478 
479 static int fastboot_add(struct usb_configuration *c)
480 {
481 	struct f_fastboot *f_fb = fastboot_func;
482 	int status;
483 
484 	debug("%s: cdev: 0x%p\n", __func__, c->cdev);
485 
486 	if (!f_fb) {
487 		f_fb = memalign(CONFIG_SYS_CACHELINE_SIZE, sizeof(*f_fb));
488 		if (!f_fb)
489 			return -ENOMEM;
490 
491 		fastboot_func = f_fb;
492 		memset(f_fb, 0, sizeof(*f_fb));
493 	}
494 
495 	f_fb->usb_function.name = "f_fastboot";
496 	f_fb->usb_function.bind = fastboot_bind;
497 	f_fb->usb_function.unbind = fastboot_unbind;
498 	f_fb->usb_function.set_alt = fastboot_set_alt;
499 	f_fb->usb_function.disable = fastboot_disable;
500 	f_fb->usb_function.strings = fastboot_strings;
501 
502 	status = usb_add_function(c, &f_fb->usb_function);
503 	if (status) {
504 		free(f_fb);
505 		fastboot_func = f_fb;
506 	}
507 
508 	return status;
509 }
510 DECLARE_GADGET_BIND_CALLBACK(usb_dnl_fastboot, fastboot_add);
511 
512 static int fastboot_tx_write(const char *buffer, unsigned int buffer_size)
513 {
514 	struct usb_request *in_req = fastboot_func->in_req;
515 	int ret;
516 
517 	memcpy(in_req->buf, buffer, buffer_size);
518 	in_req->length = buffer_size;
519 
520 	usb_ep_dequeue(fastboot_func->in_ep, in_req);
521 
522 	ret = usb_ep_queue(fastboot_func->in_ep, in_req, 0);
523 	if (ret)
524 		printf("Error %d on queue\n", ret);
525 	return 0;
526 }
527 
528 static int fastboot_tx_write_str(const char *buffer)
529 {
530 	int ret;
531 
532 	ret = sleep_thread();
533 	if (ret < 0)
534 		printf("warning: 0x%x, usb transmission is abnormal!\n", ret);
535 
536 	return fastboot_tx_write(buffer, strlen(buffer));
537 }
538 
539 static void compl_do_reset(struct usb_ep *ep, struct usb_request *req)
540 {
541 	do_reset(NULL, 0, 0, NULL);
542 }
543 
544 int __weak fb_set_reboot_flag(void)
545 {
546 	return -ENOSYS;
547 }
548 
549 static void cb_reboot(struct usb_ep *ep, struct usb_request *req)
550 {
551 	char *cmd = req->buf;
552 
553 	if (!strcmp_l1("reboot-bootloader", cmd)) {
554 		if (fb_set_reboot_flag()) {
555 			fastboot_tx_write_str("FAILCannot set reboot flag");
556 			return;
557 		}
558 	}
559 #ifdef CONFIG_ANDROID_BOOTLOADER
560 	if (!strcmp_l1("reboot-fastboot", cmd)) {
561 		if (android_bcb_write("boot-fastboot")) {
562 			fastboot_tx_write_str("FAILCannot set boot-fastboot");
563 			return;
564 		}
565 	}
566 
567 	if (!strcmp_l1("reboot-recovery", cmd)) {
568 		if (android_bcb_write("boot-recovery")) {
569 			fastboot_tx_write_str("FAILCannot set boot-recovery");
570 			return;
571 		}
572 	}
573 #endif
574 	fastboot_func->in_req->complete = compl_do_reset;
575 	fastboot_tx_write_str("OKAY");
576 }
577 
578 static int strcmp_l1(const char *s1, const char *s2)
579 {
580 	if (!s1 || !s2)
581 		return -1;
582 	return strncmp(s1, s2, strlen(s1));
583 }
584 
585 struct name_string {
586 	const char *str;
587 	int expects_args;
588 	char delim;
589 };
590 
591 #define NAME_NO_ARGS(s)	{.str = s, .expects_args = 0}
592 #define NAME_ARGS(s, d)	{.str = s, .expects_args = 1, .delim = d}
593 
594 static size_t name_check_match(const char *str, size_t len,
595 			       const struct name_string *name)
596 {
597 	size_t str_len = strlen(name->str);
598 
599 	/* If name len is greater than input, return 0. */
600 	if (str_len > len)
601 		return 0;
602 
603 	/* If name str does not match input string, return 0. */
604 	if (memcmp(name->str, str, str_len))
605 		return 0;
606 
607 	if (name->expects_args) {
608 		/* string should have space for delim */
609 		if (len == str_len)
610 			return 0;
611 
612 		/* Check delim match */
613 		if (name->delim != str[str_len])
614 			return 0;
615 	} else {
616 		/* Name str len should match input len */
617 		if (str_len != len)
618 			return 0;
619 	}
620 
621 	return str_len + name->expects_args;
622 }
623 
624 static void fb_add_string(char *dst, size_t chars_left,
625 			  const char *str, const char *args)
626 {
627 	if (!str)
628 		return;
629 
630 	int ret = snprintf(dst, chars_left, str, args);
631 
632 	if (ret < 0)
633 		pr_err("snprintf is error!");
634 }
635 
636 static void fb_add_number(char *dst, size_t chars_left,
637 			  const char *format, size_t num)
638 {
639 	if (!format)
640 		return;
641 
642 	int ret = snprintf(dst, chars_left, format, num);
643 
644 	if (ret > chars_left)
645 		pr_err("snprintf is error!");
646 }
647 
648 static int fb_read_var(char *cmd, char *response,
649 		       fb_getvar_t var, size_t chars_left)
650 {
651 	const char *s;
652 	int ret = 0;
653 
654 	switch (var) {
655 	case FB_VERSION:
656 		fb_add_string(response, chars_left, FASTBOOT_VERSION, NULL);
657 		break;
658 	case FB_BOOTLOADER_VERSION:
659 		fb_add_string(response, chars_left, U_BOOT_VERSION, NULL);
660 		break;
661 	case FB_BASEBAND_VERSION:
662 		fb_add_string(response, chars_left, "N/A", NULL);
663 		break;
664 	case FB_PRODUCT:
665 		fb_add_string(response, chars_left, CONFIG_SYS_BOARD, NULL);
666 		break;
667 	case FB_SERIAL_NO:
668 		s = env_get("serial#");
669 		if (s)
670 			fb_add_string(response, chars_left, s, NULL);
671 		else
672 			ret = -1;
673 		break;
674 	case FB_SECURE:
675 		fb_add_string(response, chars_left, "yes", NULL);
676 		break;
677 	case FB_VARIANT:
678 		fb_add_string(response, chars_left, "userdebug", NULL);
679 		break;
680 	case FB_DWNLD_SIZE:
681 		fb_add_number(response, chars_left, "0x%08x",
682 			      CONFIG_FASTBOOT_BUF_SIZE);
683 		break;
684 	case FB_PART_SIZE:
685 	case FB_PART_TYPE: {
686 		char *part_name = cmd;
687 
688 		cmd = strsep(&part_name, ":");
689 		if (!cmd || !part_name) {
690 			fb_add_string(response, chars_left,
691 				      "argument Invalid!", NULL);
692 			ret = -1;
693 			break;
694 		}
695 
696 #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
697 		disk_partition_t part_info;
698 		struct blk_desc *dev_desc;
699 		int part_num = -1;
700 		const char *fs_type = NULL;
701 
702 #ifdef CONFIG_RKIMG_BOOTLOADER
703 		dev_desc = rockchip_get_bootdev();
704 #else
705 		dev_desc = NULL;
706 #endif
707 		if (!dev_desc) {
708 			fb_add_string(response, chars_left,
709 				      "block device not found", NULL);
710 			ret = -1;
711 			break;
712 		}
713 
714 		part_num = part_get_info_by_name(dev_desc, part_name,
715 						 &part_info);
716 		if (part_num < 0) {
717 			fb_add_string(response, chars_left,
718 				      "partition not found", NULL);
719 			ret = -1;
720 		} else if (!strncmp(PARTITION_TYPE_STRINGS, cmd,
721 					strlen(PARTITION_TYPE_STRINGS))) {
722 			if (fb_get_fstype("mmc", part_num, &fs_type)) {
723 				fb_add_string(response, chars_left,
724 					      (char *)part_info.type, NULL);
725 			} else {
726 				fb_add_string(response, chars_left,
727 					      fs_type, NULL);
728 			}
729 		} else if (!strncmp("partition-size", cmd, 14)) {
730 			u64 part_size;
731 
732 			part_size = (uint64_t)part_info.size;
733 			snprintf(response, chars_left, "0x%llx",
734 				 part_size * dev_desc->blksz);
735 		}
736 #else
737 		fb_add_string(response, chars_left, "not implemented", NULL);
738 		ret = -1;
739 #endif
740 		break;
741 	}
742 	case FB_BLK_SIZE: {
743 #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
744 		struct blk_desc *dev_desc;
745 
746 #ifdef CONFIG_RKIMG_BOOTLOADER
747 		dev_desc = rockchip_get_bootdev();
748 #else
749 		dev_desc = NULL;
750 #endif
751 		if (!dev_desc) {
752 			fb_add_string(response, chars_left,
753 				      "block device not found", NULL);
754 			ret = -1;
755 		} else {
756 			fb_add_number(response, chars_left,
757 				      "0x%lx", dev_desc->blksz);
758 		}
759 #else
760 		fb_add_string(response, chars_left, "not implemented", NULL);
761 		ret = -1;
762 #endif
763 		break;
764 	}
765 	case FB_ERASE_SIZE: {
766 #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
767 		lbaint_t erase_grp_size;
768 
769 		erase_grp_size = fb_mmc_get_erase_grp_size();
770 		if (erase_grp_size < 0) {
771 			fb_add_string(response, chars_left,
772 				      "block device not found", NULL);
773 			ret = -1;
774 		} else {
775 			fb_add_number(response, chars_left, "0x"LBAF"",
776 				      erase_grp_size);
777 		}
778 #else
779 		fb_add_string(response, chars_left, "not implemented", NULL);
780 		ret = -1;
781 #endif
782 		break;
783 	}
784 	case FB_UNLOCKED: {
785 #ifdef CONFIG_RK_AVB_LIBAVB_USER
786 		uint8_t flash_lock_state = 0;
787 
788 		if (rk_avb_read_flash_lock_state(&flash_lock_state))
789 			fb_add_string(response, chars_left, "yes", NULL);
790 		else
791 			fb_add_string(response, chars_left, "no", NULL);
792 #else
793 		fb_add_string(response, chars_left, "not implemented", NULL);
794 		ret = -1;
795 #endif
796 		break;
797 	}
798 	case  FB_OFF_MODE_CHARGE: {
799 		fb_add_string(response, chars_left, "not implemented", NULL);
800 		break;
801 	}
802 	case FB_BATT_VOLTAGE: {
803 		fb_add_string(response, chars_left, "not implemented", NULL);
804 		break;
805 	}
806 	case FB_BATT_SOC_OK: {
807 		fb_add_string(response, chars_left, "no", NULL);
808 		break;
809 	}
810 	case FB_IS_USERSPACE: {
811 		fb_add_string(response, chars_left, "no", NULL);
812 		break;
813 	}
814 #ifdef CONFIG_RK_AVB_LIBAVB_USER
815 	case FB_HAS_COUNT: {
816 		char slot_count[2];
817 		char temp;
818 
819 		slot_count[1] = '\0';
820 		if (rk_avb_read_slot_count(&temp) < 0) {
821 			fb_add_number(response, chars_left, "%d", 0);
822 			ret = -1;
823 			break;
824 		}
825 		slot_count[0] = temp + 0x30;
826 		fb_add_string(response, chars_left, slot_count, NULL);
827 		break;
828 	}
829 	case FB_HAS_SLOT: {
830 		char *part_name = cmd;
831 		int has_slot = -1;
832 
833 		cmd = strsep(&part_name, ":");
834 		if (!cmd || !part_name) {
835 			fb_add_string(response, chars_left,
836 				      "argument Invalid!", NULL);
837 			ret = -1;
838 			break;
839 		}
840 
841 		has_slot = rk_avb_get_part_has_slot_info(part_name);
842 		if (has_slot < 0)
843 			fb_add_string(response, chars_left, "no", NULL);
844 		else
845 			fb_add_string(response, chars_left, "yes", NULL);
846 		break;
847 	}
848 	case FB_CURR_SLOT: {
849 		char slot_surrent[8] = {0};
850 
851 		if (!rk_avb_get_current_slot(slot_surrent)) {
852 			fb_add_string(response, chars_left,
853 				      slot_surrent + 1, NULL);
854 		} else {
855 			fb_add_string(response, chars_left, "get error", NULL);
856 			ret = -1;
857 		}
858 		break;
859 	}
860 	case FB_SLOT_SUFFIXES: {
861 		char slot_suffixes_temp[4] = {0};
862 		char slot_suffixes[9] = {0};
863 		int slot_cnt = 0;
864 
865 		rk_avb_read_slot_suffixes(slot_suffixes_temp);
866 		while (slot_suffixes_temp[slot_cnt] != '\0') {
867 			slot_suffixes[slot_cnt * 2]
868 				= slot_suffixes_temp[slot_cnt];
869 			slot_suffixes[slot_cnt * 2 + 1] = ',';
870 			slot_cnt++;
871 		}
872 
873 		slot_suffixes[(slot_cnt - 1) * 2 + 1] = '\0';
874 		fb_add_string(response, chars_left, slot_suffixes, NULL);
875 		break;
876 	}
877 	case FB_SLOT_SUCCESSFUL:{
878 		char *slot_name = cmd;
879 		AvbABData ab_info;
880 
881 		cmd = strsep(&slot_name, ":");
882 		if (!cmd || !slot_name) {
883 			fb_add_string(response, chars_left,
884 				      "argument Invalid!", NULL);
885 			ret = -1;
886 			break;
887 		}
888 
889 		if (rk_avb_get_ab_info(&ab_info) < 0) {
890 			fb_add_string(response, chars_left,
891 				      "get ab info failed!", NULL);
892 			ret = -1;
893 			break;
894 		}
895 
896 		if (!strcmp(slot_name, "a")) {
897 			if (ab_info.slots[0].successful_boot)
898 				fb_add_string(response, chars_left,
899 					      "yes", NULL);
900 			else
901 				fb_add_string(response, chars_left,
902 					      "no", NULL);
903 		} else if (!strcmp(slot_name, "b")) {
904 			if (ab_info.slots[1].successful_boot)
905 				fb_add_string(response, chars_left,
906 					      "yes", NULL);
907 			else
908 				fb_add_string(response, chars_left,
909 					      "no", NULL);
910 		} else {
911 			fb_add_string(response, chars_left, "no", NULL);
912 		}
913 		break;
914 	}
915 	case FB_SLOT_UNBOOTABLE: {
916 		char *slot_name = cmd;
917 		AvbABData ab_info;
918 
919 		cmd = strsep(&slot_name, ":");
920 
921 		if (!cmd || !slot_name) {
922 			fb_add_string(response, chars_left,
923 				      "argument Invalid!", NULL);
924 			ret = -1;
925 			break;
926 		}
927 
928 		if (rk_avb_get_ab_info(&ab_info) < 0) {
929 			fb_add_string(response, chars_left,
930 				      "get ab info failed!", NULL);
931 			ret = -1;
932 			break;
933 		}
934 
935 		if (!strcmp(slot_name, "a")) {
936 			if (!ab_info.slots[0].successful_boot &&
937 			    !ab_info.slots[0].tries_remaining &&
938 			    !ab_info.slots[0].priority)
939 				fb_add_string(response, chars_left,
940 					      "yes", NULL);
941 			else
942 				fb_add_string(response, chars_left, "no", NULL);
943 		} else if (!strcmp(slot_name, "b")) {
944 			if (!ab_info.slots[1].successful_boot &&
945 			    !ab_info.slots[1].tries_remaining &&
946 			    !ab_info.slots[1].priority)
947 				fb_add_string(response, chars_left,
948 					      "yes", NULL);
949 			else
950 				fb_add_string(response, chars_left, "no", NULL);
951 		} else {
952 			fb_add_string(response, chars_left, "no", NULL);
953 		}
954 		break;
955 	}
956 	case FB_SLOT_RETRY_COUNT: {
957 		char *slot_name = cmd;
958 		AvbABData ab_info;
959 
960 		cmd = strsep(&slot_name, ":");
961 		if (!cmd || !slot_name) {
962 			fb_add_string(response, chars_left,
963 				      "argument Invalid!", NULL);
964 			ret = -1;
965 			break;
966 		}
967 
968 		if (rk_avb_get_ab_info(&ab_info) < 0) {
969 			fb_add_string(response, chars_left,
970 				      "get ab info failed!", NULL);
971 			ret = -1;
972 			break;
973 		}
974 
975 		if (!strcmp(slot_name, "a")) {
976 			fb_add_number(response, chars_left,
977 				      "%d", ab_info.slots[0].tries_remaining);
978 		} else if (!strcmp(slot_name, "b")) {
979 			fb_add_number(response, chars_left, "%d",
980 				      ab_info.slots[1].tries_remaining);
981 
982 		} else {
983 			strcpy(response, "FAILno");
984 		}
985 		break;
986 	}
987 	case FB_AT_VBST: {
988 		char vbst[VBOOT_STATE_SIZE] = {0};
989 		char *p_vbst;
990 
991 		strcpy(response, "INFO");
992 		rk_avb_get_at_vboot_state(vbst);
993 		p_vbst = vbst;
994 		do {
995 			cmd = strsep(&p_vbst, "\n");
996 			if (strlen(cmd) > 0) {
997 				memcpy(&response[4], cmd, chars_left);
998 				fastboot_tx_write_str(response);
999 			}
1000 		} while (strlen(cmd));
1001 		break;
1002 	}
1003 #endif
1004 #ifdef CONFIG_OPTEE_CLIENT
1005 	case FB_AT_DH: {
1006 		char dhbuf[ATTEST_DH_SIZE];
1007 		uint32_t dh_len = ATTEST_DH_SIZE;
1008 		uint32_t res = trusty_attest_dh((uint8_t *)dhbuf, &dh_len);
1009 
1010 		if (res) {
1011 			fb_add_string(response, chars_left, "dh not set", NULL);
1012 			ret = -1;
1013 		} else {
1014 			fb_add_string(response, chars_left, dhbuf, NULL);
1015 		}
1016 		break;
1017 	}
1018 	case FB_AT_UUID: {
1019 		char uuid[ATTEST_UUID_SIZE] = {0};
1020 		uint32_t uuid_len = ATTEST_UUID_SIZE;
1021 		uint32_t res = trusty_attest_uuid((uint8_t *)uuid, &uuid_len);
1022 
1023 		uuid[ATTEST_UUID_SIZE - 1] = 0;
1024 		if (res) {
1025 			fb_add_string(response, chars_left, "dh not set", NULL);
1026 			ret = -1;
1027 		} else {
1028 			fb_add_string(response, chars_left, uuid, NULL);
1029 		}
1030 		break;
1031 	}
1032 #endif
1033 	default: {
1034 			char *envstr;
1035 
1036 			envstr = malloc(strlen("fastboot.") + strlen(cmd) + 1);
1037 			if (!envstr) {
1038 				fb_add_string(response, chars_left,
1039 					      "malloc error", NULL);
1040 				ret = -1;
1041 				break;
1042 			}
1043 
1044 			sprintf(envstr, "fastboot.%s", cmd);
1045 			s = env_get(envstr);
1046 			if (s) {
1047 				strncat(response, s, chars_left);
1048 			} else {
1049 				printf("WARNING: unknown variable: %s\n", cmd);
1050 				fb_add_string(response, chars_left,
1051 					      "not implemented", NULL);
1052 			}
1053 
1054 			free(envstr);
1055 			break;
1056 		}
1057 	}
1058 
1059 	return ret;
1060 }
1061 
1062 static const struct {
1063 	/*
1064 	 *any changes to this array require an update to the corresponding
1065 	 *enum in fastboot.h
1066 	 */
1067 	struct name_string name;
1068 	fb_getvar_t var;
1069 } getvar_table[] = {
1070 	{ NAME_NO_ARGS("version"), FB_VERSION},
1071 	{ NAME_NO_ARGS("version-bootloader"), FB_BOOTLOADER_VERSION},
1072 	{ NAME_NO_ARGS("version-baseband"), FB_BASEBAND_VERSION},
1073 	{ NAME_NO_ARGS("product"), FB_PRODUCT},
1074 	{ NAME_NO_ARGS("serialno"), FB_SERIAL_NO},
1075 	{ NAME_NO_ARGS("secure"), FB_SECURE},
1076 	{ NAME_NO_ARGS("max-download-size"), FB_DWNLD_SIZE},
1077 	{ NAME_NO_ARGS("logical-block-size"), FB_BLK_SIZE},
1078 	{ NAME_NO_ARGS("erase-block-size"), FB_ERASE_SIZE},
1079 	{ NAME_ARGS("partition-type", ':'), FB_PART_TYPE},
1080 	{ NAME_ARGS("partition-size", ':'), FB_PART_SIZE},
1081 	{ NAME_NO_ARGS("unlocked"), FB_UNLOCKED},
1082 	{ NAME_NO_ARGS("off-mode-charge"), FB_OFF_MODE_CHARGE},
1083 	{ NAME_NO_ARGS("battery-voltage"), FB_BATT_VOLTAGE},
1084 	{ NAME_NO_ARGS("variant"), FB_VARIANT},
1085 	{ NAME_NO_ARGS("battery-soc-ok"), FB_BATT_SOC_OK},
1086 	{ NAME_NO_ARGS("is-userspace"), FB_IS_USERSPACE},
1087 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1088 	/* Slots related */
1089 	{ NAME_NO_ARGS("slot-count"), FB_HAS_COUNT},
1090 	{ NAME_ARGS("has-slot", ':'), FB_HAS_SLOT},
1091 	{ NAME_NO_ARGS("current-slot"), FB_CURR_SLOT},
1092 	{ NAME_NO_ARGS("slot-suffixes"), FB_SLOT_SUFFIXES},
1093 	{ NAME_ARGS("slot-successful", ':'), FB_SLOT_SUCCESSFUL},
1094 	{ NAME_ARGS("slot-unbootable", ':'), FB_SLOT_UNBOOTABLE},
1095 	{ NAME_ARGS("slot-retry-count", ':'), FB_SLOT_RETRY_COUNT},
1096 	{ NAME_NO_ARGS("at-vboot-state"), FB_AT_VBST},
1097 #endif
1098 	/*
1099 	 * OEM specific :
1100 	 * Spec says names starting with lowercase letter are reserved.
1101 	 */
1102 #ifdef CONFIG_OPTEE_CLIENT
1103 	{ NAME_NO_ARGS("at-attest-dh"), FB_AT_DH},
1104 	{ NAME_NO_ARGS("at-attest-uuid"), FB_AT_UUID},
1105 #endif
1106 };
1107 
1108 static int fb_getvar_single(char *cmd, char *response, size_t chars_left)
1109 {
1110 	int i;
1111 	size_t match_len = 0;
1112 	size_t len = strlen(cmd);
1113 
1114 	for (i = 0; i < ARRAY_SIZE(getvar_table); i++) {
1115 		match_len = name_check_match(cmd, len, &getvar_table[i].name);
1116 		if (match_len)
1117 			break;
1118 	}
1119 
1120 	if (match_len == 0) {
1121 		fb_add_string(response, chars_left, "unknown variable", NULL);
1122 		return -1;
1123 	}
1124 
1125 	if (fb_read_var(cmd, response, getvar_table[i].var, chars_left) < 0)
1126 		return -1;
1127 
1128 	return 0;
1129 }
1130 
1131 static void fb_getvar_all(void)
1132 {
1133 	char response[FASTBOOT_RESPONSE_LEN] = {0};
1134 	char resp_tmp[FASTBOOT_RESPONSE_LEN] = {0};
1135 	char *actual_resp;
1136 	size_t chars_left;
1137 	int i, p;
1138 	disk_partition_t part_info;
1139 	struct blk_desc *dev_desc;
1140 
1141 	strcpy(response, "INFO");
1142 	chars_left = sizeof(response) - strlen(response) - 1;
1143 	actual_resp = response + strlen(response);
1144 
1145 	for (i = 0; i < ARRAY_SIZE(getvar_table); i++) {
1146 		fb_getvar_t var = getvar_table[i].var;
1147 
1148 		switch (var) {
1149 		case FB_PART_TYPE:
1150 		case FB_PART_SIZE: {
1151 			const char *fs_type = NULL;
1152 #ifdef CONFIG_RKIMG_BOOTLOADER
1153 			dev_desc = rockchip_get_bootdev();
1154 #else
1155 			dev_desc = NULL;
1156 #endif
1157 			if (!dev_desc) {
1158 				fb_add_string(actual_resp, chars_left,
1159 					      "%s:block device not found",
1160 					      getvar_table[i].name.str);
1161 				fastboot_tx_write_str(response);
1162 				break;
1163 			}
1164 
1165 			for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) {
1166 				if (part_get_info(dev_desc, p,
1167 						  &part_info) < 0) {
1168 					break;
1169 				}
1170 
1171 				if (var == FB_PART_TYPE) {
1172 					fs_type = NULL;
1173 					if (fb_get_fstype("mmc", p,
1174 							  &fs_type)) {
1175 						fb_add_string(
1176 							resp_tmp,
1177 							FASTBOOT_RESPONSE_LEN,
1178 							(char *)part_info.type,
1179 							NULL);
1180 					} else {
1181 						fb_add_string(
1182 							resp_tmp,
1183 							FASTBOOT_RESPONSE_LEN,
1184 							fs_type,
1185 							NULL);
1186 					}
1187 
1188 					snprintf(actual_resp,
1189 						 chars_left,
1190 						 "%s:%s:%s",
1191 						 getvar_table[i].name.str,
1192 						 part_info.name,
1193 						 resp_tmp);
1194 				} else {
1195 					uint64_t part_size;
1196 
1197 					part_size = (uint64_t)part_info.size;
1198 					snprintf(actual_resp,
1199 						 chars_left,
1200 						 "%s:%s:0x%llx",
1201 						 getvar_table[i].name.str,
1202 						 part_info.name,
1203 						 part_size * dev_desc->blksz);
1204 				}
1205 				fastboot_tx_write_str(response);
1206 			}
1207 			break;
1208 		}
1209 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1210 		case FB_HAS_SLOT: {
1211 			uchar *ptr_name_tmp;
1212 			char c = '_';
1213 			int has_slot = -1;
1214 
1215 #ifdef CONFIG_RKIMG_BOOTLOADER
1216 			dev_desc = rockchip_get_bootdev();
1217 #else
1218 			dev_desc = NULL;
1219 #endif
1220 			if (!dev_desc) {
1221 				fb_add_string(actual_resp, chars_left,
1222 					      "%s:block device not found",
1223 					      getvar_table[i].name.str);
1224 				fastboot_tx_write_str(response);
1225 				break;
1226 			}
1227 
1228 			for (p = 1; p <= MAX_SEARCH_PARTITIONS; p++) {
1229 				if (part_get_info(dev_desc, p,
1230 						  &part_info) < 0) {
1231 					break;
1232 				} else {
1233 					ptr_name_tmp = (uchar *)strrchr(
1234 						(char *)part_info.name, c);
1235 					if (ptr_name_tmp &&
1236 					    part_info.name[ptr_name_tmp -
1237 						part_info.name + 2] == '\0')
1238 						fb_add_string(
1239 							resp_tmp,
1240 							ptr_name_tmp -
1241 							part_info.name + 1,
1242 							(char *)part_info.name,
1243 							NULL);
1244 					else
1245 						strcpy(resp_tmp,
1246 						       (char *)part_info.name);
1247 
1248 					has_slot = rk_avb_get_part_has_slot_info(
1249 						resp_tmp);
1250 					if (has_slot < 0) {
1251 						snprintf(actual_resp,
1252 							 chars_left,
1253 							 "%s:%s:no",
1254 							 getvar_table[i].name.str,
1255 							 resp_tmp);
1256 					} else {
1257 						snprintf(actual_resp,
1258 							 chars_left,
1259 							 "%s:%s:yes",
1260 							 getvar_table[i].name.str,
1261 							 resp_tmp);
1262 						p++;
1263 					}
1264 
1265 					fastboot_tx_write_str(response);
1266 				}
1267 			}
1268 			break;
1269 		}
1270 
1271 		case FB_SLOT_SUCCESSFUL: {
1272 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1273 			AvbABData ab_info;
1274 
1275 			if (rk_avb_get_ab_info(&ab_info) < 0) {
1276 				fb_add_string(actual_resp,
1277 					      chars_left,
1278 					      "%s:get ab info failed!",
1279 					      getvar_table[i].name.str);
1280 				fastboot_tx_write_str(response);
1281 				break;
1282 			}
1283 
1284 			if (ab_info.slots[0].successful_boot)
1285 				fb_add_string(actual_resp, chars_left,
1286 					      "%s:a:yes",
1287 					      getvar_table[i].name.str);
1288 			else
1289 				fb_add_string(actual_resp, chars_left,
1290 					      "%s:a:no",
1291 					      getvar_table[i].name.str);
1292 			fastboot_tx_write_str(response);
1293 
1294 			if (ab_info.slots[1].successful_boot)
1295 				fb_add_string(actual_resp, chars_left,
1296 					      "%s:b:yes",
1297 					      getvar_table[i].name.str);
1298 			else
1299 				fb_add_string(actual_resp, chars_left,
1300 					      "%s:b:no",
1301 					      getvar_table[i].name.str);
1302 			fastboot_tx_write_str(response);
1303 #else
1304 			fb_add_string(actual_resp, chars_left,
1305 				      "%s:not find ab info!",
1306 				      getvar_table[i].name.str);
1307 			fastboot_tx_write_str(response);
1308 #endif
1309 			break;
1310 		}
1311 
1312 		case FB_SLOT_UNBOOTABLE: {
1313 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1314 			AvbABData ab_info;
1315 
1316 			if (rk_avb_get_ab_info(&ab_info) < 0) {
1317 				fb_add_string(actual_resp, chars_left,
1318 					      "%s:not find ab info!",
1319 					      getvar_table[i].name.str);
1320 				fastboot_tx_write_str(response);
1321 				break;
1322 			}
1323 
1324 			if (!ab_info.slots[0].successful_boot &&
1325 			    !ab_info.slots[0].tries_remaining &&
1326 			    !ab_info.slots[0].priority)
1327 				fb_add_string(actual_resp, chars_left,
1328 					      "%s:a:yes",
1329 					      getvar_table[i].name.str);
1330 			else
1331 				fb_add_string(actual_resp, chars_left,
1332 					      "%s:a:no",
1333 					      getvar_table[i].name.str);
1334 			fastboot_tx_write_str(response);
1335 
1336 			if (!ab_info.slots[1].successful_boot &&
1337 			    !ab_info.slots[1].tries_remaining &&
1338 			    !ab_info.slots[1].priority)
1339 				fb_add_string(actual_resp, chars_left,
1340 					      "%s:b:yes",
1341 					      getvar_table[i].name.str);
1342 			else
1343 				fb_add_string(actual_resp, chars_left,
1344 					      "%s:b:no",
1345 					      getvar_table[i].name.str);
1346 
1347 			fastboot_tx_write_str(response);
1348 #else
1349 			fb_add_string(actual_resp, chars_left,
1350 				      "%s:not find ab info!",
1351 				      getvar_table[i].name.str);
1352 			fastboot_tx_write_str(response);
1353 #endif
1354 			break;
1355 		}
1356 
1357 		case FB_SLOT_RETRY_COUNT: {
1358 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1359 			AvbABData ab_info;
1360 
1361 			if (rk_avb_get_ab_info(&ab_info) < 0) {
1362 				fb_add_string(actual_resp, chars_left,
1363 					      "%s:not find ab info!",
1364 					      getvar_table[i].name.str);
1365 				fastboot_tx_write_str(response);
1366 				break;
1367 			}
1368 
1369 			snprintf(actual_resp, chars_left, "%s:a:%d",
1370 				 getvar_table[i].name.str,
1371 				 ab_info.slots[1].tries_remaining);
1372 			fastboot_tx_write_str(response);
1373 			snprintf(actual_resp, chars_left, "%s:b:%d",
1374 				 getvar_table[i].name.str,
1375 				 ab_info.slots[1].tries_remaining);
1376 			fastboot_tx_write_str(response);
1377 #else
1378 			fb_add_string(actual_resp, chars_left,
1379 				      "%s:not find ab info!",
1380 				      getvar_table[i].name.str);
1381 			fastboot_tx_write_str(response);
1382 #endif
1383 			break;
1384 		}
1385 #endif
1386 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1387 		case FB_AT_VBST:
1388 			break;
1389 #endif
1390 		default:
1391 			fb_getvar_single((char *)getvar_table[i].name.str,
1392 					 resp_tmp, FASTBOOT_RESPONSE_LEN);
1393 			snprintf(actual_resp, chars_left, "%s:%s",
1394 				 getvar_table[i].name.str, resp_tmp);
1395 			fastboot_tx_write_str(response);
1396 		}
1397 	}
1398 }
1399 
1400 static void cb_getvar(struct usb_ep *ep, struct usb_request *req)
1401 {
1402 	char *cmd = req->buf;
1403 	char response[FASTBOOT_RESPONSE_LEN] = {0};
1404 	const char *str_read_all = "all";
1405 	size_t len = 0;
1406 	size_t chars_left;
1407 
1408 	strsep(&cmd, ":");
1409 	if (!cmd) {
1410 		pr_err("missing variable");
1411 		fastboot_tx_write_str("FAILmissing var");
1412 		return;
1413 	}
1414 
1415 	len = strlen(cmd);
1416 	if (len == strlen(str_read_all) &&
1417 	    (strncmp(cmd, str_read_all, len) == 0)) {
1418 		fb_getvar_all();
1419 		fastboot_tx_write_str("OKAYDone!");
1420 	} else {
1421 		strcpy(response, "OKAY");
1422 		chars_left = sizeof(response) - strlen(response) - 1;
1423 
1424 		if (fb_getvar_single(cmd, &response[strlen(response)],
1425 				     chars_left) < 0) {
1426 			strcpy(cmd, "FAILunknown variable");
1427 			strncat(cmd, &response[strlen(response)], chars_left);
1428 			fastboot_tx_write_str(cmd);
1429 			return;
1430 		}
1431 		fastboot_tx_write_str(response);
1432 	}
1433 
1434 	return;
1435 }
1436 
1437 static unsigned int rx_bytes_expected(struct usb_ep *ep)
1438 {
1439 	int rx_remain = download_size - download_bytes;
1440 	unsigned int rem;
1441 	unsigned int maxpacket = ep->maxpacket;
1442 
1443 	if (rx_remain <= 0)
1444 		return 0;
1445 	else if (rx_remain > EP_BUFFER_SIZE)
1446 		return EP_BUFFER_SIZE;
1447 
1448 	/*
1449 	 * Some controllers e.g. DWC3 don't like OUT transfers to be
1450 	 * not ending in maxpacket boundary. So just make them happy by
1451 	 * always requesting for integral multiple of maxpackets.
1452 	 * This shouldn't bother controllers that don't care about it.
1453 	 */
1454 	rem = rx_remain % maxpacket;
1455 	if (rem > 0)
1456 		rx_remain = rx_remain + (maxpacket - rem);
1457 
1458 	return rx_remain;
1459 }
1460 
1461 #define BYTES_PER_DOT	0x20000
1462 static void rx_handler_dl_image(struct usb_ep *ep, struct usb_request *req)
1463 {
1464 	char response[FASTBOOT_RESPONSE_LEN];
1465 	unsigned int transfer_size = download_size - download_bytes;
1466 	const unsigned char *buffer = req->buf;
1467 	unsigned int buffer_size = req->actual;
1468 	unsigned int pre_dot_num, now_dot_num;
1469 
1470 	if (req->status != 0) {
1471 		printf("Bad status: %d\n", req->status);
1472 		return;
1473 	}
1474 
1475 	if (buffer_size < transfer_size)
1476 		transfer_size = buffer_size;
1477 
1478 	memcpy((void *)CONFIG_FASTBOOT_BUF_ADDR + download_bytes,
1479 	       buffer, transfer_size);
1480 
1481 	pre_dot_num = download_bytes / BYTES_PER_DOT;
1482 	download_bytes += transfer_size;
1483 	now_dot_num = download_bytes / BYTES_PER_DOT;
1484 
1485 	if (pre_dot_num != now_dot_num) {
1486 		putc('.');
1487 		if (!(now_dot_num % 74))
1488 			putc('\n');
1489 	}
1490 
1491 	/* Check if transfer is done */
1492 	if (download_bytes >= download_size) {
1493 		/*
1494 		 * Reset global transfer variable, keep download_bytes because
1495 		 * it will be used in the next possible flashing command
1496 		 */
1497 		download_size = 0;
1498 		req->complete = rx_handler_command;
1499 		req->length = EP_BUFFER_SIZE;
1500 
1501 		strcpy(response, "OKAY");
1502 		fastboot_tx_write_str(response);
1503 
1504 		printf("\ndownloading of %d bytes finished\n", download_bytes);
1505 	} else {
1506 		req->length = rx_bytes_expected(ep);
1507 	}
1508 
1509 	req->actual = 0;
1510 	usb_ep_queue(ep, req, 0);
1511 }
1512 
1513 static void cb_download(struct usb_ep *ep, struct usb_request *req)
1514 {
1515 	char *cmd = req->buf;
1516 	char response[FASTBOOT_RESPONSE_LEN];
1517 
1518 	strsep(&cmd, ":");
1519 	download_size = simple_strtoul(cmd, NULL, 16);
1520 	download_bytes = 0;
1521 
1522 	printf("Starting download of %d bytes\n", download_size);
1523 
1524 	if (0 == download_size) {
1525 		strcpy(response, "FAILdata invalid size");
1526 	} else if (download_size > CONFIG_FASTBOOT_BUF_SIZE) {
1527 		download_size = 0;
1528 		strcpy(response, "FAILdata too large");
1529 	} else {
1530 		sprintf(response, "DATA%08x", download_size);
1531 		req->complete = rx_handler_dl_image;
1532 		req->length = rx_bytes_expected(ep);
1533 	}
1534 
1535 	fastboot_tx_write_str(response);
1536 }
1537 
1538 static void tx_handler_ul(struct usb_ep *ep, struct usb_request *req)
1539 {
1540 	unsigned int xfer_size = 0;
1541 	unsigned int pre_dot_num, now_dot_num;
1542 	unsigned int remain_size = 0;
1543 	unsigned int transferred_size = req->actual;
1544 
1545 	if (req->status != 0) {
1546 		printf("Bad status: %d\n", req->status);
1547 		return;
1548 	}
1549 
1550 	if (start_upload) {
1551 		pre_dot_num = upload_bytes / BYTES_PER_DOT;
1552 		upload_bytes += transferred_size;
1553 		now_dot_num = upload_bytes / BYTES_PER_DOT;
1554 
1555 		if (pre_dot_num != now_dot_num) {
1556 			putc('.');
1557 			if (!(now_dot_num % 74))
1558 				putc('\n');
1559 		}
1560 	}
1561 
1562 	remain_size = upload_size - upload_bytes;
1563 	xfer_size = (remain_size > EP_BUFFER_SIZE) ?
1564 		    EP_BUFFER_SIZE : remain_size;
1565 
1566 	debug("%s: remain_size=%d, transferred_size=%d",
1567 	      __func__, remain_size, transferred_size);
1568 	debug("xfer_size=%d, upload_bytes=%d, upload_size=%d!\n",
1569 	      xfer_size, upload_bytes, upload_size);
1570 
1571 	if (remain_size <= 0) {
1572 		fastboot_func->in_req->complete = fastboot_complete;
1573 		wakeup_thread();
1574 		fastboot_tx_write_str("OKAY");
1575 		printf("\nuploading of %d bytes finished\n", upload_bytes);
1576 		upload_bytes = 0;
1577 		upload_size = 0;
1578 		start_upload = false;
1579 		return;
1580 	}
1581 
1582 	/* Remove the transfer callback which response the upload */
1583 	/* request from host */
1584 	if (!upload_bytes)
1585 		start_upload = true;
1586 
1587 	fastboot_tx_write((char *)((phys_addr_t)CONFIG_FASTBOOT_BUF_ADDR + \
1588 			  upload_bytes),
1589 			  xfer_size);
1590 }
1591 
1592 static void cb_upload(struct usb_ep *ep, struct usb_request *req)
1593 {
1594 	char response[FASTBOOT_RESPONSE_LEN];
1595 
1596 	printf("Starting upload of %d bytes\n", upload_size);
1597 
1598 	if (0 == upload_size) {
1599 		strcpy(response, "FAILdata invalid size");
1600 	} else {
1601 		start_upload = false;
1602 		sprintf(response, "DATA%08x", upload_size);
1603 		fastboot_func->in_req->complete = tx_handler_ul;
1604 	}
1605 
1606 	fastboot_tx_write_str(response);
1607 }
1608 
1609 static void do_bootm_on_complete(struct usb_ep *ep, struct usb_request *req)
1610 {
1611 	char boot_addr_start[12];
1612 	char *bootm_args[] = { "bootm", boot_addr_start, NULL };
1613 
1614 	puts("Booting kernel..\n");
1615 
1616 	sprintf(boot_addr_start, "0x%lx", (long)CONFIG_FASTBOOT_BUF_ADDR);
1617 	do_bootm(NULL, 0, 2, bootm_args);
1618 
1619 	/* This only happens if image is somehow faulty so we start over */
1620 	do_reset(NULL, 0, 0, NULL);
1621 }
1622 
1623 static void cb_boot(struct usb_ep *ep, struct usb_request *req)
1624 {
1625 	fastboot_func->in_req->complete = do_bootm_on_complete;
1626 	fastboot_tx_write_str("OKAY");
1627 }
1628 
1629 static void do_exit_on_complete(struct usb_ep *ep, struct usb_request *req)
1630 {
1631 	g_dnl_trigger_detach();
1632 }
1633 
1634 static void cb_continue(struct usb_ep *ep, struct usb_request *req)
1635 {
1636 	fastboot_func->in_req->complete = do_exit_on_complete;
1637 	fastboot_tx_write_str("OKAY");
1638 }
1639 
1640 static void cb_set_active(struct usb_ep *ep, struct usb_request *req)
1641 {
1642 	char *cmd = req->buf;
1643 
1644 	debug("%s: %s\n", __func__, cmd);
1645 
1646 	strsep(&cmd, ":");
1647 	if (!cmd) {
1648 		pr_err("missing slot name");
1649 		fastboot_tx_write_str("FAILmissing slot name");
1650 		return;
1651 	}
1652 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1653 	unsigned int slot_number;
1654 	if (strncmp("a", cmd, 1) == 0) {
1655 		slot_number = 0;
1656 		rk_avb_set_slot_active(&slot_number);
1657 	} else if (strncmp("b", cmd, 1) == 0) {
1658 		slot_number = 1;
1659 		rk_avb_set_slot_active(&slot_number);
1660 	} else {
1661 		fastboot_tx_write_str("FAILunkown slot name");
1662 		return;
1663 	}
1664 
1665 	fastboot_tx_write_str("OKAY");
1666 	return;
1667 #else
1668 	fastboot_tx_write_str("FAILnot implemented");
1669 	return;
1670 #endif
1671 }
1672 
1673 #ifdef CONFIG_FASTBOOT_FLASH
1674 static void cb_flash(struct usb_ep *ep, struct usb_request *req)
1675 {
1676 	char *cmd = req->buf;
1677 	char response[FASTBOOT_RESPONSE_LEN] = {0};
1678 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1679 	uint8_t flash_lock_state;
1680 
1681 	if (rk_avb_read_flash_lock_state(&flash_lock_state)) {
1682 		/* write the device flashing unlock when first read */
1683 		if (rk_avb_write_flash_lock_state(1)) {
1684 			fastboot_tx_write_str("FAILflash lock state write failure");
1685 			return;
1686 		}
1687 		if (rk_avb_read_flash_lock_state(&flash_lock_state)) {
1688 			fastboot_tx_write_str("FAILflash lock state read failure");
1689 			return;
1690 		}
1691 	}
1692 
1693 	if (flash_lock_state == 0) {
1694 		fastboot_tx_write_str("FAILThe device is locked, can not flash!");
1695 		printf("The device is locked, can not flash!\n");
1696 		return;
1697 	}
1698 #endif
1699 	strsep(&cmd, ":");
1700 	if (!cmd) {
1701 		pr_err("missing partition name");
1702 		fastboot_tx_write_str("FAILmissing partition name");
1703 		return;
1704 	}
1705 
1706 	fastboot_fail("no flash device defined", response);
1707 #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
1708 	fb_mmc_flash_write(cmd, (void *)CONFIG_FASTBOOT_BUF_ADDR,
1709 				download_bytes, response);
1710 #endif
1711 #ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
1712 	fb_nand_flash_write(cmd, (void *)CONFIG_FASTBOOT_BUF_ADDR,
1713 				download_bytes, response);
1714 #endif
1715 	fastboot_tx_write_str(response);
1716 }
1717 
1718 static void cb_flashing(struct usb_ep *ep, struct usb_request *req)
1719 {
1720 	char *cmd = req->buf;
1721 
1722 	if (strncmp("lock", cmd + 9, 4) == 0) {
1723 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1724 		uint8_t flash_lock_state;
1725 		flash_lock_state = 0;
1726 		if (rk_avb_write_flash_lock_state(flash_lock_state))
1727 			fastboot_tx_write_str("FAILflash lock state"
1728 					      " write failure");
1729 		else
1730 			fastboot_tx_write_str("OKAY");
1731 #else
1732 		fastboot_tx_write_str("FAILnot implemented");
1733 #endif
1734 	} else if (strncmp("unlock", cmd + 9, 6) == 0) {
1735 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1736 		uint8_t flash_lock_state;
1737 		flash_lock_state = 1;
1738 		if (rk_avb_write_flash_lock_state(flash_lock_state))
1739 			fastboot_tx_write_str("FAILflash lock state"
1740 					      " write failure");
1741 		else
1742 			fastboot_tx_write_str("OKAY");
1743 #else
1744 		fastboot_tx_write_str("FAILnot implemented");
1745 #endif
1746 	} else if (strncmp("lock_critical", cmd + 9, 12) == 0) {
1747 		fastboot_tx_write_str("FAILnot implemented");
1748 	} else if (strncmp("unlock_critical", cmd + 9, 14) == 0) {
1749 		fastboot_tx_write_str("FAILnot implemented");
1750 	} else if (strncmp("get_unlock_ability", cmd + 9, 17) == 0) {
1751 		fastboot_tx_write_str("FAILnot implemented");
1752 	} else if (strncmp("get_unlock_bootloader_nonce", cmd + 4, 27) == 0) {
1753 		fastboot_tx_write_str("FAILnot implemented");
1754 	} else if (strncmp("unlock_bootloader", cmd + 9, 17) == 0) {
1755 		fastboot_tx_write_str("FAILnot implemented");
1756 	} else if (strncmp("lock_bootloader", cmd + 9, 15) == 0) {
1757 		fastboot_tx_write_str("FAILnot implemented");
1758 	} else {
1759 		fastboot_tx_write_str("FAILunknown flashing command");
1760 	}
1761 }
1762 #endif
1763 
1764 static void cb_oem_perm_attr(void)
1765 {
1766 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1767 #ifndef CONFIG_ROCKCHIP_PRELOADER_PUB_KEY
1768 	sha256_context ctx;
1769 	uint8_t digest[SHA256_SUM_LEN] = {0};
1770 	uint8_t digest_temp[SHA256_SUM_LEN] = {0};
1771 	uint8_t perm_attr_temp[PERM_ATTR_TOTAL_SIZE] = {0};
1772 	uint8_t flag = 0;
1773 #endif
1774 	if (PERM_ATTR_TOTAL_SIZE != download_bytes) {
1775 		printf("Permanent attribute size is not equal!\n");
1776 		fastboot_tx_write_str("FAILincorrect perm attribute size");
1777 		return;
1778 	}
1779 #ifndef CONFIG_ROCKCHIP_PRELOADER_PUB_KEY
1780 	if (rk_avb_read_perm_attr_flag(&flag)) {
1781 		printf("rk_avb_read_perm_attr_flag error!\n");
1782 		fastboot_tx_write_str("FAILperm attr read failed");
1783 		return;
1784 	}
1785 
1786 	if (flag == PERM_ATTR_SUCCESS_FLAG) {
1787 		if (rk_avb_read_attribute_hash(digest_temp,
1788 					       SHA256_SUM_LEN)) {
1789 			printf("The efuse IO can not be used!\n");
1790 			fastboot_tx_write_str("FAILefuse IO can not be used");
1791 			return;
1792 		}
1793 
1794 		if (memcmp(digest, digest_temp, SHA256_SUM_LEN) != 0) {
1795 			if (rk_avb_read_permanent_attributes(perm_attr_temp,
1796 							     PERM_ATTR_TOTAL_SIZE)) {
1797 				printf("rk_avb_write_permanent_attributes error!\n");
1798 				fastboot_tx_write_str("FAILread perm attr error");
1799 				return;
1800 			}
1801 
1802 			sha256_starts(&ctx);
1803 			sha256_update(&ctx,
1804 				      (const uint8_t *)perm_attr_temp,
1805 				      PERM_ATTR_TOTAL_SIZE);
1806 			sha256_finish(&ctx, digest);
1807 			if (memcmp(digest, digest_temp, SHA256_SUM_LEN) == 0) {
1808 				printf("The hash has been written!\n");
1809 				fastboot_tx_write_str("OKAY");
1810 				return;
1811 			}
1812 		}
1813 
1814 		if (rk_avb_write_perm_attr_flag(0)) {
1815 			fastboot_tx_write_str("FAILperm attr flag write failure");
1816 			return;
1817 		}
1818 	}
1819 #endif
1820 	if (rk_avb_write_permanent_attributes((uint8_t *)
1821 					      CONFIG_FASTBOOT_BUF_ADDR,
1822 					      download_bytes)) {
1823 		if (rk_avb_write_perm_attr_flag(0)) {
1824 			fastboot_tx_write_str("FAILperm attr flag write failure");
1825 			return;
1826 		}
1827 		fastboot_tx_write_str("FAILperm attr write failed");
1828 		return;
1829 	}
1830 #ifndef CONFIG_ROCKCHIP_PRELOADER_PUB_KEY
1831 	memset(digest, 0, SHA256_SUM_LEN);
1832 	sha256_starts(&ctx);
1833 	sha256_update(&ctx, (const uint8_t *)CONFIG_FASTBOOT_BUF_ADDR,
1834 		      PERM_ATTR_TOTAL_SIZE);
1835 	sha256_finish(&ctx, digest);
1836 
1837 	if (rk_avb_write_attribute_hash((uint8_t *)digest,
1838 					SHA256_SUM_LEN)) {
1839 		if (rk_avb_read_attribute_hash(digest_temp,
1840 						SHA256_SUM_LEN)) {
1841 			printf("The efuse IO can not be used!\n");
1842 			fastboot_tx_write_str("FAILefuse IO can not be used");
1843 			return;
1844 		}
1845 		if (memcmp(digest, digest_temp, SHA256_SUM_LEN) != 0) {
1846 			if (rk_avb_write_perm_attr_flag(0)) {
1847 				fastboot_tx_write_str("FAILperm attr flag write failure");
1848 				return;
1849 			}
1850 			printf("The hash has been written, but is different!\n");
1851 			fastboot_tx_write_str("FAILhash comparison failure");
1852 			return;
1853 		}
1854 	}
1855 #endif
1856 	if (rk_avb_write_perm_attr_flag(PERM_ATTR_SUCCESS_FLAG)) {
1857 		fastboot_tx_write_str("FAILperm attr flag write failure");
1858 		return;
1859 	}
1860 
1861 	fastboot_tx_write_str("OKAY");
1862 #else
1863 	fastboot_tx_write_str("FAILnot implemented");
1864 #endif
1865 }
1866 
1867 static void cb_oem_perm_attr_rsa_cer(void)
1868 {
1869 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1870 	if (download_bytes != 256) {
1871 		printf("Permanent attribute rsahash size is not equal!\n");
1872 		fastboot_tx_write_str("FAILperm attribute rsahash size error");
1873 		return;
1874 	}
1875 
1876 	if (rk_avb_set_perm_attr_cer((uint8_t *)CONFIG_FASTBOOT_BUF_ADDR,
1877 				     download_bytes)) {
1878 		fastboot_tx_write_str("FAILSet perm attr cer fail!");
1879 		return;
1880 	}
1881 
1882 	fastboot_tx_write_str("OKAY");
1883 #else
1884 	fastboot_tx_write_str("FAILnot implemented");
1885 #endif
1886 }
1887 
1888 static void cb_oem(struct usb_ep *ep, struct usb_request *req)
1889 {
1890 	char *cmd = req->buf;
1891 
1892 #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
1893 	if (strncmp("format", cmd + 4, 6) == 0) {
1894 		char cmdbuf[32];
1895 		sprintf(cmdbuf, "gpt write mmc %x $partitions",
1896 			CONFIG_FASTBOOT_FLASH_MMC_DEV);
1897 		if (run_command(cmdbuf, 0))
1898 			fastboot_tx_write_str("FAILmmc write failure");
1899 		else
1900 			fastboot_tx_write_str("OKAY");
1901 	} else
1902 #endif
1903 	if (strncmp("unlock", cmd + 4, 8) == 0) {
1904 #ifdef CONFIG_FASTBOOT_OEM_UNLOCK
1905 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1906 		fastboot_tx_write_str("FAILnot implemented");
1907 		return;
1908 #else
1909 		uint8_t unlock = 0;
1910 		TEEC_Result result;
1911 		debug("oem unlock\n");
1912 		result = trusty_read_oem_unlock(&unlock);
1913 		if (result) {
1914 			printf("read oem unlock status with error : 0x%x\n", result);
1915 			fastboot_tx_write_str("FAILRead oem unlock status failed");
1916 			return;
1917 		}
1918 		if (unlock) {
1919 			printf("oem unlock ignored, device already unlocked\n");
1920 			fastboot_tx_write_str("FAILalready unlocked");
1921 			return;
1922 		}
1923 		printf("oem unlock requested:\n");
1924 		printf("\tUnlocking forces a factory reset and could\n");
1925 		printf("\topen your device up to a world of hurt.  If you\n");
1926 		printf("\tare sure you know what you're doing, then accept\n");
1927 		printf("\tvia 'fastboot oem unlock_accept'.\n");
1928 		env_set("unlock", "unlock");
1929 		fastboot_tx_write_str("OKAY");
1930 #endif
1931 #else
1932 		fastboot_tx_write_str("FAILnot implemented");
1933 		return;
1934 #endif
1935 	} else if (strncmp("unlock_accept", cmd + 4, 13) == 0) {
1936 #ifdef CONFIG_FASTBOOT_OEM_UNLOCK
1937 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1938 		fastboot_tx_write_str("FAILnot implemented");
1939 		return;
1940 #else
1941 		char *unlock = env_get("unlock");
1942 		TEEC_Result result;
1943 		debug("oem unlock_accept\n");
1944 		if (unlock == NULL || strncmp("unlock", unlock, 6) != 0) {
1945 			printf("oem unlock_accept ignored, not pending\n");
1946 			fastboot_tx_write_str("FAILoem unlock not requested");
1947 			return;
1948 		}
1949 		env_set("unlock", "");
1950 		printf("Erasing userdata partition\n");
1951 		struct blk_desc *dev_desc;
1952 		disk_partition_t part_info;
1953 		dev_desc = rockchip_get_bootdev();
1954 		if (!dev_desc) {
1955 			printf("%s: dev_desc is NULL!\n", __func__);
1956 			return;
1957 		}
1958 		int ret = part_get_info_by_name(dev_desc, "userdata",
1959 				&part_info);
1960 		if (ret < 0) {
1961 			printf("not found userdata partition");
1962 			printf("Erase failed with error %d\n", ret);
1963 			fastboot_tx_write_str("FAILErasing userdata failed");
1964 			return;
1965 		}
1966 		ret = blk_derase(dev_desc, part_info.start, part_info.size);
1967 		if (ret != part_info.size) {
1968 			printf("Erase failed with error %d\n", ret);
1969 			fastboot_tx_write_str("FAILErasing userdata failed");
1970 			return;
1971 		}
1972 		printf("Erasing succeeded\n");
1973 
1974 		result = trusty_write_oem_unlock(1);
1975 		if (result) {
1976 			printf("write oem unlock status with error : 0x%x\n", result);
1977 			fastboot_tx_write_str("FAILWrite oem unlock status failed");
1978 			return;
1979 		}
1980 		fastboot_tx_write_str("OKAY");
1981 
1982 		/*
1983 		 * now reboot into recovery to do a format of the
1984 		 * userdata partition so it's ready to use on next boot
1985 		 */
1986 		board_run_recovery_wipe_data();
1987 #endif
1988 #else
1989 		fastboot_tx_write_str("FAILnot implemented");
1990 		return;
1991 #endif
1992 	} else if (strncmp("lock", cmd + 4, 8) == 0) {
1993 #ifdef CONFIG_FASTBOOT_OEM_UNLOCK
1994 #ifdef CONFIG_RK_AVB_LIBAVB_USER
1995 		fastboot_tx_write_str("FAILnot implemented");
1996 		return;
1997 #else
1998 		TEEC_Result result;
1999 		uint8_t unlock = 0;
2000 		trusty_read_oem_unlock(&unlock);
2001 		if (!unlock) {
2002 			printf("oem lock ignored, already locked\n");
2003 			fastboot_tx_write_str("FAILalready locked");
2004 			return;
2005 		}
2006 
2007 		result = trusty_write_oem_unlock(0);
2008 		if (result) {
2009 			printf("write oem unlock status with error : 0x%x\n", result);
2010 			fastboot_tx_write_str("FAILWrite oem unlock status failed");
2011 			return;
2012 		}
2013 		fastboot_tx_write_str("OKAY");
2014 #endif
2015 #else
2016 		fastboot_tx_write_str("FAILnot implemented");
2017 		return;
2018 #endif
2019 	} else if (strncmp("at-get-ca-request", cmd + 4, 17) == 0) {
2020 #ifdef CONFIG_OPTEE_CLIENT
2021 		uint8_t out[ATTEST_CA_OUT_SIZE];
2022 		uint32_t operation_size = download_bytes;
2023 		uint32_t out_len = ATTEST_CA_OUT_SIZE;
2024 		uint32_t res = 0;
2025 
2026 		res = trusty_attest_get_ca((uint8_t *)CONFIG_FASTBOOT_BUF_ADDR,
2027 					   &operation_size, out, &out_len);
2028 		if (res) {
2029 			fastboot_tx_write_str("FAILtrusty_attest_get_ca failed");
2030 			return;
2031 		}
2032 		upload_size = out_len;
2033 		memcpy((void *)CONFIG_FASTBOOT_BUF_ADDR, out, out_len);
2034 		fastboot_tx_write_str("OKAY");
2035 #else
2036 		fastboot_tx_write_str("FAILnot implemented");
2037 		return;
2038 #endif
2039 	} else if (strncmp("at-set-ca-response", cmd + 4, 18) == 0) {
2040 #ifdef CONFIG_OPTEE_CLIENT
2041 		uint32_t ca_response_size = download_bytes;
2042 		uint32_t res = 0;
2043 
2044 		res = trusty_attest_set_ca((uint8_t *)CONFIG_FASTBOOT_BUF_ADDR,
2045 					   &ca_response_size);
2046 		if (res)
2047 			fastboot_tx_write_str("FAILtrusty_attest_set_ca failed");
2048 		else
2049 			fastboot_tx_write_str("OKAY");
2050 #else
2051 		fastboot_tx_write_str("FAILnot implemented");
2052 		return;
2053 #endif
2054 	} else if (strncmp("at-get-vboot-unlock-challenge", cmd + 4, 29) == 0) {
2055 #ifdef CONFIG_RK_AVB_LIBAVB_USER
2056 		uint32_t challenge_len = 0;
2057 		int ret = 0;
2058 
2059 		ret = rk_generate_unlock_challenge((void *)CONFIG_FASTBOOT_BUF_ADDR, &challenge_len);
2060 		if (ret == 0) {
2061 			upload_size = challenge_len;
2062 			fastboot_tx_write_str("OKAY");
2063 		} else {
2064 			fastboot_tx_write_str("FAILgenerate unlock challenge fail!");
2065 		}
2066 #else
2067 		fastboot_tx_write_str("FAILnot implemented");
2068 		return;
2069 #endif
2070 	} else if (strncmp("at-lock-vboot", cmd + 4, 13) == 0) {
2071 #ifdef CONFIG_RK_AVB_LIBAVB_USER
2072 		uint8_t lock_state;
2073 		lock_state = 0;
2074 		if (rk_avb_write_lock_state(lock_state))
2075 			fastboot_tx_write_str("FAILwrite lock state failed");
2076 		else
2077 			fastboot_tx_write_str("OKAY");
2078 #else
2079 		fastboot_tx_write_str("FAILnot implemented");
2080 #endif
2081 	} else if (strncmp("at-unlock-vboot", cmd + 4, 15) == 0) {
2082 #ifdef CONFIG_RK_AVB_LIBAVB_USER
2083 		uint8_t lock_state;
2084 		char out_is_trusted = true;
2085 
2086 		if (rk_avb_read_lock_state(&lock_state))
2087 			fastboot_tx_write_str("FAILlock sate read failure");
2088 		if (lock_state >> 1 == 1) {
2089 			fastboot_tx_write_str("FAILThe vboot is disable!");
2090 		} else {
2091 			lock_state = 1;
2092 #ifdef CONFIG_RK_AVB_LIBAVB_ENABLE_ATH_UNLOCK
2093 			if (rk_auth_unlock((void *)CONFIG_FASTBOOT_BUF_ADDR,
2094 					   &out_is_trusted)) {
2095 				printf("rk_auth_unlock ops error!\n");
2096 				fastboot_tx_write_str("FAILrk_auth_unlock ops error!");
2097 				return;
2098 			}
2099 #endif
2100 			if (out_is_trusted == true) {
2101 				if (rk_avb_write_lock_state(lock_state))
2102 					fastboot_tx_write_str("FAILwrite lock state failed");
2103 				else
2104 					fastboot_tx_write_str("OKAY");
2105 			} else {
2106 				fastboot_tx_write_str("FAILauthenticated unlock fail");
2107 			}
2108 		}
2109 #else
2110 		fastboot_tx_write_str("FAILnot implemented");
2111 #endif
2112 	} else if (strncmp("fuse at-perm-attr", cmd + 4, 16) == 0) {
2113 		cb_oem_perm_attr();
2114 	} else if (strncmp("fuse at-rsa-perm-attr", cmd + 4, 25) == 0) {
2115 		cb_oem_perm_attr_rsa_cer();
2116 	} else if (strncmp("fuse at-bootloader-vboot-key", cmd + 4, 27) == 0) {
2117 #ifdef CONFIG_RK_AVB_LIBAVB_USER
2118 		sha256_context ctx;
2119 		uint8_t digest[SHA256_SUM_LEN];
2120 
2121 		if (download_bytes != VBOOT_KEY_HASH_SIZE) {
2122 			fastboot_tx_write_str("FAILinvalid vboot key length");
2123 			printf("The vboot key size error!\n");
2124 			return;
2125 		}
2126 
2127 		sha256_starts(&ctx);
2128 		sha256_update(&ctx, (const uint8_t *)CONFIG_FASTBOOT_BUF_ADDR,
2129 			      VBOOT_KEY_SIZE);
2130 		sha256_finish(&ctx, digest);
2131 
2132 		if (rk_avb_write_vbootkey_hash((uint8_t *)digest,
2133 					       SHA256_SUM_LEN)) {
2134 			fastboot_tx_write_str("FAILvbootkey hash write failure");
2135 			return;
2136 		}
2137 		fastboot_tx_write_str("OKAY");
2138 #else
2139 		fastboot_tx_write_str("FAILnot implemented");
2140 #endif
2141 	} else if (strncmp("init-ab-metadata", cmd + 4, 16) == 0) {
2142 #ifdef CONFIG_RK_AVB_LIBAVB_USER
2143 		if (rk_avb_init_ab_metadata()) {
2144 			fastboot_tx_write_str("FAILinit ab data fail!");
2145 			return;
2146 		}
2147 		fastboot_tx_write_str("OKAY");
2148 #else
2149 		fastboot_tx_write_str("FAILnot implemented");
2150 #endif
2151 	} else {
2152 		fastboot_tx_write_str("FAILunknown oem command");
2153 	}
2154 }
2155 
2156 #ifdef CONFIG_FASTBOOT_FLASH
2157 static void cb_erase(struct usb_ep *ep, struct usb_request *req)
2158 {
2159 	char *cmd = req->buf;
2160 	char response[FASTBOOT_RESPONSE_LEN];
2161 
2162 	strsep(&cmd, ":");
2163 	if (!cmd) {
2164 		pr_err("missing partition name");
2165 		fastboot_tx_write_str("FAILmissing partition name");
2166 		return;
2167 	}
2168 
2169 	fastboot_fail("no flash device defined", response);
2170 #ifdef CONFIG_FASTBOOT_FLASH_MMC_DEV
2171 	fb_mmc_erase(cmd, response);
2172 #endif
2173 #ifdef CONFIG_FASTBOOT_FLASH_NAND_DEV
2174 	fb_nand_erase(cmd, response);
2175 #endif
2176 	fastboot_tx_write_str(response);
2177 }
2178 #endif
2179 
2180 struct cmd_dispatch_info {
2181 	char *cmd;
2182 	void (*cb)(struct usb_ep *ep, struct usb_request *req);
2183 };
2184 
2185 static const struct cmd_dispatch_info cmd_dispatch_info[] = {
2186 	{
2187 		.cmd = "reboot",
2188 		.cb = cb_reboot,
2189 	}, {
2190 		.cmd = "getvar:",
2191 		.cb = cb_getvar,
2192 	}, {
2193 		.cmd = "download:",
2194 		.cb = cb_download,
2195 	}, {
2196 		.cmd = "upload",
2197 		.cb = cb_upload,
2198 	}, {
2199 		.cmd = "boot",
2200 		.cb = cb_boot,
2201 	}, {
2202 		.cmd = "continue",
2203 		.cb = cb_continue,
2204 	}, {
2205 		.cmd = "set_active",
2206 		.cb = cb_set_active,
2207 	},
2208 #ifdef CONFIG_FASTBOOT_FLASH
2209 	{
2210 		.cmd = "flashing",
2211 		.cb = cb_flashing,
2212 	},
2213 	{
2214 		.cmd = "flash",
2215 		.cb = cb_flash,
2216 	}, {
2217 		.cmd = "erase",
2218 		.cb = cb_erase,
2219 	},
2220 #endif
2221 	{
2222 		.cmd = "oem",
2223 		.cb = cb_oem,
2224 	},
2225 };
2226 
2227 static void rx_handler_command(struct usb_ep *ep, struct usb_request *req)
2228 {
2229 	char *cmdbuf = req->buf;
2230 	void (*func_cb)(struct usb_ep *ep, struct usb_request *req) = NULL;
2231 	int i;
2232 
2233 	if (req->status != 0 || req->length == 0)
2234 		return;
2235 
2236 	for (i = 0; i < ARRAY_SIZE(cmd_dispatch_info); i++) {
2237 		if (!strcmp_l1(cmd_dispatch_info[i].cmd, cmdbuf)) {
2238 			func_cb = cmd_dispatch_info[i].cb;
2239 			break;
2240 		}
2241 	}
2242 
2243 	if (!func_cb) {
2244 		pr_err("unknown command: %.*s", req->actual, cmdbuf);
2245 		fastboot_tx_write_str("FAILunknown command");
2246 	} else {
2247 		if (req->actual < req->length) {
2248 			u8 *buf = (u8 *)req->buf;
2249 			buf[req->actual] = 0;
2250 			func_cb(ep, req);
2251 		} else {
2252 			pr_err("buffer overflow");
2253 			fastboot_tx_write_str("FAILbuffer overflow");
2254 		}
2255 	}
2256 
2257 	*cmdbuf = '\0';
2258 	req->actual = 0;
2259 	usb_ep_queue(ep, req, 0);
2260 }
2261