blob: b2b3e9ee3845e2c5af121d8793bd1383cc68334a [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001/*
2 * Copyright (c) 2016 MediaTek Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files
6 * (the "Software"), to deal in the Software without restriction,
7 * including without limitation the rights to use, copy, modify, merge,
8 * publish, distribute, sublicense, and/or sell copies of the Software,
9 * and to permit persons to whom the Software is furnished to do so,
10 * subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
18 * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
19 * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
20 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
21 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 */
23
24#include <dev/udc.h>
25#include <lib/bio.h>
26#include <lib/dl_commands.h>
27#include <lib/fastboot.h>
28#include <lib/fastboot_oem_cmd.h>
29#include <lib/mempool.h>
30#include <platform/mtk_serial_key.h>
31#include <platform/mtk_wdt.h>
32#include <reg.h>
33#include <stdio.h>
34#include <string.h>
35#include <target/cust_usb.h>
36
37#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
38#ifndef SN_BUF_LEN
39#define SN_BUF_LEN 19 /* fastboot use 13 bytes as default, max is 19 */
40#endif
41#define DEFAULT_SERIAL_NUM "0123456789ABCDEF"
42char sn_buf[SN_BUF_LEN+1] = DEFAULT_SERIAL_NUM;
43
44static struct udc_device surf_udc_device = {
45 .vendor_id = USB_VENDORID,
46 .product_id = USB_PRODUCTID,
47 .version_id = USB_VERSIONID,
48 .manufacturer = USB_MANUFACTURER,
49 .product = USB_PRODUCT_NAME,
50};
51
52static void register_commands(void)
53{
54 fastboot_register("getvar:", cmd_getvar);
55 fastboot_register("download:", cmd_download);
56 fastboot_register("flash:", cmd_flash);
57 fastboot_register("erase:", cmd_erase);
58 fastboot_register("reboot", cmd_reboot);
59 fastboot_register("reboot-bootloader", cmd_reboot_bootloader);
60 fastboot_register("reboot-fastboot", cmd_reboot_fastbootd);
61 fastboot_register("oem reboot-recovery", cmd_reboot_recovery);
62 fastboot_register("oem continue", cmd_continue_boot);
63#ifdef AVB_ENABLE_DEVICE_STATE_CHANGE
64 fastboot_register("flashing", cmd_flashing);
65#endif
66}
67
68static void register_oem_fastboot_cmds(void)
69{
70 extern const struct fastboot_oem_cmd_descriptor __fb_oem_cmd_start[];
71 extern const struct fastboot_oem_cmd_descriptor __fb_oem_cmd_end[];
72
73 const struct fastboot_oem_cmd_descriptor *cmd;
74
75 for (cmd = __fb_oem_cmd_start; cmd != __fb_oem_cmd_end; cmd++) {
76 if (cmd->cmd_handler)
77 fastboot_register(cmd->cmd_str, cmd->cmd_handler);
78 }
79}
80
81static void publish_attributes(void)
82{
83 char buffer_size[11];
84 sprintf(buffer_size, "0x%x", SCRATCH_SIZE);
85 fastboot_publish("version", "0.5");
86 fastboot_publish("max-download-size", buffer_size);
87 fastboot_publish("is-userspace", "no");
88}
89
90static void storage_init(void)
91{
92 /* init storage that only use in fastboot, currently none */
93 bio_dump_devices();
94}
95
96static char udc_chr[32] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZ456789"};
97static int get_serial(u64 hwkey, u32 chipid, char *ser)
98{
99 u16 hashkey[4];
100 u32 idx, ser_idx;
101
102 /* split to 4 key with 16-bit width each */
103 for (idx = 0; idx < ARRAY_SIZE(hashkey); idx++) {
104 hashkey[idx] = (u16)(hwkey & 0xffff);
105 hwkey >>= 16;
106 }
107
108 /* hash the key with chip id */
109 for (idx = 0; idx < ARRAY_SIZE(hashkey); idx++) {
110 u32 digit = (chipid % 10);
111 hashkey[idx] = (hashkey[idx] >> digit) | (hashkey[idx] << (16-digit));
112 chipid = (chipid / 10);
113 }
114
115 /* generate serail using hashkey */
116 ser_idx = 0;
117 for (idx = 0; idx < ARRAY_SIZE(hashkey); idx++) {
118 ser[ser_idx++] = (hashkey[idx] & 0x001f);
119 ser[ser_idx++] = (hashkey[idx] & 0x00f8) >> 3;
120 ser[ser_idx++] = (hashkey[idx] & 0x1f00) >> 8;
121 ser[ser_idx++] = (hashkey[idx] & 0xf800) >> 11;
122 }
123
124 for (idx = 0; idx < ser_idx; idx++)
125 ser[idx] = udc_chr[(int)ser[idx]];
126
127 ser[ser_idx] = 0x00;
128
129 return 0;
130}
131
132void ext_boot(void)
133{
134 void *scratch_buf;
135
136 u64 key = ((u64)readl(SERIAL_KEY_HI) << 32) | readl(SERIAL_KEY_LO);
137 if (key != 0)
138 get_serial(key, MACH_TYPE, sn_buf);
139
140 surf_udc_device.serialno = sn_buf;
141 udc_init(&surf_udc_device);
142
143 storage_init();
144 mtk_wdt_disable();
145 register_commands();
146 register_oem_fastboot_cmds();
147 publish_attributes();
148
149 scratch_buf = mempool_alloc(SCRATCH_SIZE, MEMPOOL_ANY);
150
151 if (!scratch_buf)
152 return;
153
154 fastboot_init(scratch_buf, (unsigned long long)SCRATCH_SIZE);
155 mempool_free(scratch_buf);
156}