[FOSS_TLK]kernel: dynamically decide to use cmdline/boot_args
[3rdparty/ote_partner/tlk.git] / kernel / boot.c
1 /*
2  * Copyright (c) 2012-2015, NVIDIA CORPORATION. All rights reserved
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 <string.h>
25 #include <stdlib.h>
26 #include <assert.h>
27 #include <debug.h>
28 #include <err.h>
29 #include <kernel/boot_params.h>
30 #include <platform/platform_p.h>
31 #include <common/ote_nv_uuid.h>
32
33 unsigned int coldboot_normal_os;
34 unsigned int normal_os_coldboot_fn;
35 extern uint32_t debug_uart_id;
36 unsigned int tf_key_addr;
37 unsigned int tf_key_size;
38 uint32_t device_uid[DEVICE_UID_SIZE_WORDS];
39 paddr_t tsec_carveout_size, tsec_carveout_base;
40 paddr_t dtb_addr;
41
42 extern unsigned int __bootarg_addr;
43
44 struct cmdline_member {
45         char name[PARAM_NAME_LEN];
46         unsigned int *container;
47 };
48
49 static int getoffsetof(char *source, char c)
50 {
51         int offset = 0;
52         int len;
53
54         if (!source)
55                 return 0;
56
57         len = strlen(source);
58
59         while (*source++ != c && len-- > 0)
60                 offset++;
61
62         return offset;
63 }
64
65 static int parse_cmdline(void)
66 {
67         boot_params *boot_params_ptr = (boot_params*)__bootarg_addr;
68         char *str;
69         int cmdline_len, i;
70         struct cmdline_member members[] = {
71                 {CMDLINE_OS_BOOT_ADDR, &normal_os_coldboot_fn},
72                 {CMDLINE_DEVICE_UID0, &device_uid[0]},
73                 {CMDLINE_DEVICE_UID1, &device_uid[1]},
74                 {CMDLINE_DEVICE_UID2, &device_uid[2]},
75                 {CMDLINE_DEVICE_UID3, &device_uid[3]},
76                 {CMDLINE_DEBUG_UART_ID, &debug_uart_id},
77                 {CMDLINE_TFKEY_ADDR, &tf_key_addr},
78                 {CMDLINE_TFKEY_SIZE, &tf_key_size},
79                 {CMDLINE_DTB_ADDR, &dtb_addr}
80         };
81
82         if (!boot_params_ptr ||
83             !boot_params_ptr->param_string[0])
84                 return ERR_INVALID_ARGS;
85
86         /* Check whether parameters are passed as cmdline or structure */
87         cmdline_len = boot_params_ptr->param_string_sz;
88         if (cmdline_len == 0)
89                 return ERR_NOT_SUPPORTED;
90
91         str = boot_params_ptr->param_string;
92         for (i = 0; i < cmdline_len; i++) {
93                 if (*(str + i) == '\n') {
94                         *(str + i) = '\0';
95                         cmdline_len--;
96                 }
97         }
98
99         str = boot_params_ptr->param_string;
100         while (cmdline_len > 0) {
101                 if (*str == '[')
102                         goto done;
103
104                 unsigned int offset = getoffsetof(str, ':');
105
106                 if (strlen(str) < offset)
107                         goto done;
108
109                 *(str + offset) = '\0';
110                 cmdline_len -= (strlen(str) + 1);
111
112                 for (i = 0; i < ARRAY_SIZE(members); i++) {
113                         if (!strncmp(str, (const char *)&members[i].name, strlen(members[i].name))) {
114                                 str += strlen(str) + 2;
115                                 *members[i].container = atoi(str);
116                                 cmdline_len--;
117                                 break;
118                         } else if (!strncmp(str, CMDLINE_DRAM_RANGE, strlen(CMDLINE_DRAM_RANGE))) {
119                                 paddr_t base, size;
120
121                                 /* format is "mem: <size>M@<base>M" in MBbytes */
122                                 str += strlen(str) + 2;
123                                 size = (paddr_t) atoui(str);
124                                 base = (paddr_t) atoui(strchr(str, '@') + 1);
125                                 cmdline_len--;
126
127                                 tz_add_dram_range(base << 20, size << 20);
128                                 break;
129                         } else if (!strncmp(str, CMDLINE_TSEC_CARVEOUT, strlen(CMDLINE_TSEC_CARVEOUT))) {
130
131                                 /* format is "tsec: <size>M@<base>M" in MBbytes */
132                                 str += strlen(str) + 2;
133                                 tsec_carveout_size = (paddr_t) atoui(str);
134                                 tsec_carveout_base = (paddr_t) atoui(strchr(str, '@') + 1);
135                                 tsec_carveout_size <<= 20;
136                                 tsec_carveout_base <<= 20;
137                                 cmdline_len--;
138                                 break;
139                         }
140                 }
141
142                 if (i == ARRAY_SIZE(members)) {
143                         str += strlen(str) + 2;
144                         cmdline_len--;
145                 }
146
147 done:
148                 cmdline_len -= strlen(str);
149                 str += strlen(str) + 1;
150         }
151         return NO_ERROR;
152 }
153
154 static int parse_bootargs(void)
155 {
156         boot_params_t *boot_params_ptr = (boot_params*)__bootarg_addr;
157         uint64_t base, size;
158
159         if (!boot_params_ptr || boot_params_ptr->version != 0)
160                 return ERR_INVALID_ARGS;
161
162         device_uid[0] = boot_params_ptr->chip_uid[0];
163         device_uid[1] = boot_params_ptr->chip_uid[1];
164         device_uid[2] = boot_params_ptr->chip_uid[2];
165         device_uid[3] = boot_params_ptr->chip_uid[3];
166
167         debug_uart_id = boot_params_ptr->uart_id;
168
169         /* Get DRAM range from the structure passed */
170         base = boot_params_ptr->pmem;
171         size = boot_params_ptr->pmem_size;
172         tz_add_dram_range(base << 20, size << 20);
173
174         if (boot_params_ptr->emem_size != 0) {
175                 base = boot_params_ptr->emem;
176                 size = boot_params_ptr->emem_size;
177                 tz_add_dram_range(base << 20, size << 20);
178         }
179
180         dtb_addr = boot_params_ptr->dtb_load_addr;
181
182         /* Get TSEC range from the structure passed */
183         tsec_carveout_base = boot_params_ptr->tsec_carveout;
184         tsec_carveout_size = boot_params_ptr->tsec_size;
185         tsec_carveout_size <<= 20;
186         tsec_carveout_base <<= 20;
187
188         return NO_ERROR;
189 }
190
191 void get_boot_params(void)
192 {
193         int32_t err = NO_ERROR;
194
195         err = parse_cmdline();
196         if (err)
197                 err = parse_bootargs();
198 }
199
200 int get_boot_args(task_t *task, uint32_t *argv)
201 {
202         int i = 0;
203         te_service_id_t hdcp_uuid = SERVICE_SECURE_HDCP_UUID;
204
205         /* pass input params to hdcp service via argv */
206         if (!memcmp(&hdcp_uuid, &task->props.uuid, sizeof(te_service_id_t))) {
207                 argv[i++] = 0x0;                /* argv[0] = progname (NULL) */
208                 argv[i++] = tsec_carveout_base; /* argv[1] */
209                 argv[i++] = tsec_carveout_size; /* argv[2] */
210         }
211
212         return i;
213 }