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 7*35a3eeb6SRoberto 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 /******************************************************************************* 67cab0b5b0SSoby Mathew * Validate the tb_fw_config is a valid DTB file and returns the node offset 68cab0b5b0SSoby Mathew * to "arm,tb_fw" property. 69cab0b5b0SSoby Mathew * Arguments: 70cab0b5b0SSoby Mathew * void *dtb - pointer to the TB_FW_CONFIG in memory 71cab0b5b0SSoby Mathew * int *node - Returns the node offset to "arm,tb_fw" property if found. 72cab0b5b0SSoby Mathew * 73cab0b5b0SSoby Mathew * Returns 0 on success and -1 on error. 74cab0b5b0SSoby Mathew ******************************************************************************/ 75cab0b5b0SSoby Mathew int arm_dyn_tb_fw_cfg_init(void *dtb, int *node) 76cab0b5b0SSoby Mathew { 77da5f2745SSoby Mathew assert(dtb != NULL); 78da5f2745SSoby Mathew assert(node != NULL); 79cab0b5b0SSoby Mathew 80cab0b5b0SSoby Mathew /* Check if the pointer to DT is correct */ 81cab0b5b0SSoby Mathew if (fdt_check_header(dtb) != 0) { 82cab0b5b0SSoby Mathew WARN("Invalid DTB file passed as TB_FW_CONFIG\n"); 83cab0b5b0SSoby Mathew return -1; 84cab0b5b0SSoby Mathew } 85cab0b5b0SSoby Mathew 86cab0b5b0SSoby Mathew /* Assert the node offset point to "arm,tb_fw" compatible property */ 87cab0b5b0SSoby Mathew *node = fdt_node_offset_by_compatible(dtb, -1, "arm,tb_fw"); 88cab0b5b0SSoby Mathew if (*node < 0) { 89cab0b5b0SSoby Mathew WARN("The compatible property `arm,tb_fw` not found in the config\n"); 90cab0b5b0SSoby Mathew return -1; 91cab0b5b0SSoby Mathew } 92cab0b5b0SSoby Mathew 93cab0b5b0SSoby Mathew VERBOSE("Dyn cfg: Found \"arm,tb_fw\" in the config\n"); 94cab0b5b0SSoby Mathew return 0; 95cab0b5b0SSoby Mathew } 96