blob: 88dcfec988d8611b3356097fbeb86eca941582f0 [file] [log] [blame]
/*
* 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;
}