| /* |
| * Copyright (c) 2012-2015, NVIDIA CORPORATION. All rights reserved |
| * |
| * Permission is hereby granted, free of charge, to any person obtaining |
| * a copy of this software and associated documentation files |
| * (the "Software"), to deal in the Software without restriction, |
| * including without limitation the rights to use, copy, modify, merge, |
| * publish, distribute, sublicense, and/or sell copies of the Software, |
| * and to permit persons to whom the Software is furnished to do so, |
| * subject to the following conditions: |
| * |
| * The above copyright notice and this permission notice shall be |
| * included in all copies or substantial portions of the Software. |
| * |
| * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
| * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
| * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
| * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
| * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
| * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
| * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
| */ |
| |
| #include <string.h> |
| #include <stdlib.h> |
| #include <assert.h> |
| #include <debug.h> |
| #include <err.h> |
| #include <kernel/boot_params.h> |
| #include <platform/platform_p.h> |
| #include <common/ote_nv_uuid.h> |
| |
| unsigned int coldboot_normal_os; |
| unsigned int normal_os_coldboot_fn; |
| extern uint32_t debug_uart_id; |
| unsigned int tf_key_addr; |
| unsigned int tf_key_size; |
| uint32_t device_uid[DEVICE_UID_SIZE_WORDS]; |
| paddr_t tsec_carveout_size, tsec_carveout_base; |
| paddr_t dtb_addr; |
| |
| extern unsigned int __bootarg_addr; |
| |
| struct cmdline_member { |
| char name[PARAM_NAME_LEN]; |
| unsigned int *container; |
| }; |
| |
| static int getoffsetof(char *source, char c) |
| { |
| int offset = 0; |
| int len; |
| |
| if (!source) |
| return 0; |
| |
| len = strlen(source); |
| |
| while (*source++ != c && len-- > 0) |
| offset++; |
| |
| return offset; |
| } |
| |
| static int parse_cmdline(void) |
| { |
| boot_params *boot_params_ptr = (boot_params*)__bootarg_addr; |
| char *str; |
| int cmdline_len, i; |
| struct cmdline_member members[] = { |
| {CMDLINE_OS_BOOT_ADDR, &normal_os_coldboot_fn}, |
| {CMDLINE_DEVICE_UID0, &device_uid[0]}, |
| {CMDLINE_DEVICE_UID1, &device_uid[1]}, |
| {CMDLINE_DEVICE_UID2, &device_uid[2]}, |
| {CMDLINE_DEVICE_UID3, &device_uid[3]}, |
| {CMDLINE_DEBUG_UART_ID, &debug_uart_id}, |
| {CMDLINE_TFKEY_ADDR, &tf_key_addr}, |
| {CMDLINE_TFKEY_SIZE, &tf_key_size}, |
| {CMDLINE_DTB_ADDR, &dtb_addr} |
| }; |
| |
| if (!boot_params_ptr || |
| !boot_params_ptr->param_string[0]) |
| return ERR_INVALID_ARGS; |
| |
| /* Check whether parameters are passed as cmdline or structure */ |
| cmdline_len = boot_params_ptr->param_string_sz; |
| if (cmdline_len == 0) |
| return ERR_NOT_SUPPORTED; |
| |
| str = boot_params_ptr->param_string; |
| for (i = 0; i < cmdline_len; i++) { |
| if (*(str + i) == '\n') { |
| *(str + i) = '\0'; |
| cmdline_len--; |
| } |
| } |
| |
| str = boot_params_ptr->param_string; |
| while (cmdline_len > 0) { |
| if (*str == '[') |
| goto done; |
| |
| unsigned int offset = getoffsetof(str, ':'); |
| |
| if (strlen(str) < offset) |
| goto done; |
| |
| *(str + offset) = '\0'; |
| cmdline_len -= (strlen(str) + 1); |
| |
| for (i = 0; i < ARRAY_SIZE(members); i++) { |
| if (!strncmp(str, (const char *)&members[i].name, strlen(members[i].name))) { |
| str += strlen(str) + 2; |
| *members[i].container = atoi(str); |
| cmdline_len--; |
| break; |
| } else if (!strncmp(str, CMDLINE_DRAM_RANGE, strlen(CMDLINE_DRAM_RANGE))) { |
| paddr_t base, size; |
| |
| /* format is "mem: <size>M@<base>M" in MBbytes */ |
| str += strlen(str) + 2; |
| size = (paddr_t) atoui(str); |
| base = (paddr_t) atoui(strchr(str, '@') + 1); |
| cmdline_len--; |
| |
| tz_add_dram_range(base << 20, size << 20); |
| break; |
| } else if (!strncmp(str, CMDLINE_TSEC_CARVEOUT, strlen(CMDLINE_TSEC_CARVEOUT))) { |
| |
| /* format is "tsec: <size>M@<base>M" in MBbytes */ |
| str += strlen(str) + 2; |
| tsec_carveout_size = (paddr_t) atoui(str); |
| tsec_carveout_base = (paddr_t) atoui(strchr(str, '@') + 1); |
| tsec_carveout_size <<= 20; |
| tsec_carveout_base <<= 20; |
| cmdline_len--; |
| break; |
| } |
| } |
| |
| if (i == ARRAY_SIZE(members)) { |
| str += strlen(str) + 2; |
| cmdline_len--; |
| } |
| |
| done: |
| cmdline_len -= strlen(str); |
| str += strlen(str) + 1; |
| } |
| return NO_ERROR; |
| } |
| |
| static int parse_bootargs(void) |
| { |
| boot_params_t *boot_params_ptr = (boot_params*)__bootarg_addr; |
| uint64_t base, size; |
| |
| if (!boot_params_ptr || boot_params_ptr->version != 0) |
| return ERR_INVALID_ARGS; |
| |
| device_uid[0] = boot_params_ptr->chip_uid[0]; |
| device_uid[1] = boot_params_ptr->chip_uid[1]; |
| device_uid[2] = boot_params_ptr->chip_uid[2]; |
| device_uid[3] = boot_params_ptr->chip_uid[3]; |
| |
| debug_uart_id = boot_params_ptr->uart_id; |
| |
| /* Get DRAM range from the structure passed */ |
| base = boot_params_ptr->pmem; |
| size = boot_params_ptr->pmem_size; |
| tz_add_dram_range(base << 20, size << 20); |
| |
| if (boot_params_ptr->emem_size != 0) { |
| base = boot_params_ptr->emem; |
| size = boot_params_ptr->emem_size; |
| tz_add_dram_range(base << 20, size << 20); |
| } |
| |
| dtb_addr = boot_params_ptr->dtb_load_addr; |
| |
| /* Get TSEC range from the structure passed */ |
| tsec_carveout_base = boot_params_ptr->tsec_carveout; |
| tsec_carveout_size = boot_params_ptr->tsec_size; |
| tsec_carveout_size <<= 20; |
| tsec_carveout_base <<= 20; |
| |
| return NO_ERROR; |
| } |
| |
| void get_boot_params(void) |
| { |
| int32_t err = NO_ERROR; |
| |
| err = parse_cmdline(); |
| if (err) |
| err = parse_bootargs(); |
| } |
| |
| int get_boot_args(task_t *task, uint32_t *argv) |
| { |
| int i = 0; |
| te_service_id_t hdcp_uuid = SERVICE_SECURE_HDCP_UUID; |
| |
| /* pass input params to hdcp service via argv */ |
| if (!memcmp(&hdcp_uuid, &task->props.uuid, sizeof(te_service_id_t))) { |
| argv[i++] = 0x0; /* argv[0] = progname (NULL) */ |
| argv[i++] = tsec_carveout_base; /* argv[1] */ |
| argv[i++] = tsec_carveout_size; /* argv[2] */ |
| } |
| |
| return i; |
| } |