1cab0b5b0SSoby Mathew /* 2cab0b5b0SSoby Mathew * Copyright (c) 2018, ARM Limited and Contributors. All rights reserved. 3cab0b5b0SSoby Mathew * 4cab0b5b0SSoby Mathew * SPDX-License-Identifier: BSD-3-Clause 5cab0b5b0SSoby Mathew */ 6cab0b5b0SSoby Mathew 735a3eeb6SRoberto Vargas #include <arm_dyn_cfg_helpers.h> 8cab0b5b0SSoby Mathew #include <assert.h> 9cab0b5b0SSoby Mathew #include <desc_image_load.h> 10cab0b5b0SSoby Mathew #include <fdt_wrappers.h> 11cab0b5b0SSoby Mathew #include <libfdt.h> 12da5f2745SSoby Mathew #include <plat_arm.h> 13cab0b5b0SSoby Mathew 14cab0b5b0SSoby Mathew /******************************************************************************* 15cab0b5b0SSoby Mathew * Helper to read the `hw_config` property in config DTB. This function 16cab0b5b0SSoby Mathew * expects the following properties to be present in the config DTB. 17cab0b5b0SSoby Mathew * name : hw_config_addr size : 2 cells 18cab0b5b0SSoby Mathew * name : hw_config_max_size size : 1 cell 19cab0b5b0SSoby Mathew * 20cab0b5b0SSoby Mathew * Arguments: 21cab0b5b0SSoby Mathew * void *dtb - pointer to the TB_FW_CONFIG in memory 22cab0b5b0SSoby Mathew * int node - The node offset to appropriate node in the 23cab0b5b0SSoby Mathew * DTB. 24cab0b5b0SSoby Mathew * uint64_t *hw_config_addr - Returns the `hw_config` load address if read 25cab0b5b0SSoby Mathew * is successful. 26cab0b5b0SSoby Mathew * uint32_t *hw_config_size - Returns the `hw_config` size if read is 27cab0b5b0SSoby Mathew * successful. 28cab0b5b0SSoby Mathew * 29cab0b5b0SSoby Mathew * Returns 0 on success and -1 on error. 30cab0b5b0SSoby Mathew ******************************************************************************/ 31cab0b5b0SSoby Mathew int arm_dyn_get_hwconfig_info(void *dtb, int node, 32cab0b5b0SSoby Mathew uint64_t *hw_config_addr, uint32_t *hw_config_size) 33cab0b5b0SSoby Mathew { 34cab0b5b0SSoby Mathew int err; 35cab0b5b0SSoby Mathew 36da5f2745SSoby Mathew assert(dtb != NULL); 37da5f2745SSoby Mathew assert(hw_config_addr != NULL); 38da5f2745SSoby Mathew assert(hw_config_size != NULL); 39cab0b5b0SSoby Mathew 40cab0b5b0SSoby Mathew /* Check if the pointer to DT is correct */ 41cab0b5b0SSoby Mathew assert(fdt_check_header(dtb) == 0); 42cab0b5b0SSoby Mathew 43cab0b5b0SSoby Mathew /* Assert the node offset point to "arm,tb_fw" compatible property */ 44cab0b5b0SSoby Mathew assert(node == fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw")); 45cab0b5b0SSoby Mathew 46cab0b5b0SSoby Mathew err = fdtw_read_cells(dtb, node, "hw_config_addr", 2, 47cab0b5b0SSoby Mathew (void *) hw_config_addr); 48cab0b5b0SSoby Mathew if (err < 0) { 49cab0b5b0SSoby Mathew WARN("Read cell failed for hw_config_addr\n"); 50cab0b5b0SSoby Mathew return -1; 51cab0b5b0SSoby Mathew } 52cab0b5b0SSoby Mathew 53cab0b5b0SSoby Mathew err = fdtw_read_cells(dtb, node, "hw_config_max_size", 1, 54cab0b5b0SSoby Mathew (void *) hw_config_size); 55cab0b5b0SSoby Mathew if (err < 0) { 56cab0b5b0SSoby Mathew WARN("Read cell failed for hw_config_max_size\n"); 57cab0b5b0SSoby Mathew return -1; 58cab0b5b0SSoby Mathew } 59cab0b5b0SSoby Mathew 60cab0b5b0SSoby Mathew VERBOSE("Dyn cfg: Read hw_config address from TB_FW_CONFIG 0x%p %p\n", 61cab0b5b0SSoby Mathew hw_config_addr, hw_config_size); 62cab0b5b0SSoby Mathew 63cab0b5b0SSoby Mathew return 0; 64cab0b5b0SSoby Mathew } 65cab0b5b0SSoby Mathew 66cab0b5b0SSoby Mathew /******************************************************************************* 67*6e79f9fdSSoby Mathew * Helper to read the `disable_auth` property in config DTB. This function 68*6e79f9fdSSoby Mathew * expects the following properties to be present in the config DTB. 69*6e79f9fdSSoby Mathew * name : disable_auth size : 1 cell 70*6e79f9fdSSoby Mathew * 71*6e79f9fdSSoby Mathew * Arguments: 72*6e79f9fdSSoby Mathew * void *dtb - pointer to the TB_FW_CONFIG in memory 73*6e79f9fdSSoby Mathew * int node - The node offset to appropriate node in the 74*6e79f9fdSSoby Mathew * DTB. 75*6e79f9fdSSoby Mathew * uint64_t *disable_auth - The value of `disable_auth` property on 76*6e79f9fdSSoby Mathew * successful read. Must be 0 or 1. 77*6e79f9fdSSoby Mathew * 78*6e79f9fdSSoby Mathew * Returns 0 on success and -1 on error. 79*6e79f9fdSSoby Mathew ******************************************************************************/ 80*6e79f9fdSSoby Mathew int arm_dyn_get_disable_auth(void *dtb, int node, uint32_t *disable_auth) 81*6e79f9fdSSoby Mathew { 82*6e79f9fdSSoby Mathew int err; 83*6e79f9fdSSoby Mathew 84*6e79f9fdSSoby Mathew assert(dtb != NULL); 85*6e79f9fdSSoby Mathew assert(disable_auth != NULL); 86*6e79f9fdSSoby Mathew 87*6e79f9fdSSoby Mathew /* Check if the pointer to DT is correct */ 88*6e79f9fdSSoby Mathew assert(fdt_check_header(dtb) == 0); 89*6e79f9fdSSoby Mathew 90*6e79f9fdSSoby Mathew /* Assert the node offset point to "arm,tb_fw" compatible property */ 91*6e79f9fdSSoby Mathew assert(node == fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw")); 92*6e79f9fdSSoby Mathew 93*6e79f9fdSSoby Mathew /* Locate the disable_auth cell and read the value */ 94*6e79f9fdSSoby Mathew err = fdtw_read_cells(dtb, node, "disable_auth", 1, disable_auth); 95*6e79f9fdSSoby Mathew if (err < 0) { 96*6e79f9fdSSoby Mathew WARN("Read cell failed for `disable_auth`\n"); 97*6e79f9fdSSoby Mathew return -1; 98*6e79f9fdSSoby Mathew } 99*6e79f9fdSSoby Mathew 100*6e79f9fdSSoby Mathew /* Check if the value is boolean */ 101*6e79f9fdSSoby Mathew if (*disable_auth != 0 && *disable_auth != 1) { 102*6e79f9fdSSoby Mathew WARN("Invalid value for `disable_auth` cell %d\n", *disable_auth); 103*6e79f9fdSSoby Mathew return -1; 104*6e79f9fdSSoby Mathew } 105*6e79f9fdSSoby Mathew 106*6e79f9fdSSoby Mathew VERBOSE("Dyn cfg: `disable_auth` cell found with value = %d\n", 107*6e79f9fdSSoby Mathew *disable_auth); 108*6e79f9fdSSoby Mathew return 0; 109*6e79f9fdSSoby Mathew } 110*6e79f9fdSSoby Mathew 111*6e79f9fdSSoby Mathew /******************************************************************************* 112cab0b5b0SSoby Mathew * Validate the tb_fw_config is a valid DTB file and returns the node offset 113cab0b5b0SSoby Mathew * to "arm,tb_fw" property. 114cab0b5b0SSoby Mathew * Arguments: 115cab0b5b0SSoby Mathew * void *dtb - pointer to the TB_FW_CONFIG in memory 116cab0b5b0SSoby Mathew * int *node - Returns the node offset to "arm,tb_fw" property if found. 117cab0b5b0SSoby Mathew * 118cab0b5b0SSoby Mathew * Returns 0 on success and -1 on error. 119cab0b5b0SSoby Mathew ******************************************************************************/ 120cab0b5b0SSoby Mathew int arm_dyn_tb_fw_cfg_init(void *dtb, int *node) 121cab0b5b0SSoby Mathew { 122da5f2745SSoby Mathew assert(dtb != NULL); 123da5f2745SSoby Mathew assert(node != NULL); 124cab0b5b0SSoby Mathew 125cab0b5b0SSoby Mathew /* Check if the pointer to DT is correct */ 126cab0b5b0SSoby Mathew if (fdt_check_header(dtb) != 0) { 127cab0b5b0SSoby Mathew WARN("Invalid DTB file passed as TB_FW_CONFIG\n"); 128cab0b5b0SSoby Mathew return -1; 129cab0b5b0SSoby Mathew } 130cab0b5b0SSoby Mathew 131cab0b5b0SSoby Mathew /* Assert the node offset point to "arm,tb_fw" compatible property */ 132cab0b5b0SSoby Mathew *node = fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw"); 133cab0b5b0SSoby Mathew if (*node < 0) { 134cab0b5b0SSoby Mathew WARN("The compatible property `arm,tb_fw` not found in the config\n"); 135cab0b5b0SSoby Mathew return -1; 136cab0b5b0SSoby Mathew } 137cab0b5b0SSoby Mathew 138cab0b5b0SSoby Mathew VERBOSE("Dyn cfg: Found \"arm,tb_fw\" in the config\n"); 139cab0b5b0SSoby Mathew return 0; 140cab0b5b0SSoby Mathew } 141