1 /* SPDX-License-Identifier: BSD-2-Clause */ 2 /* 3 * Copyright (c) 2016, Linaro Limited 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright notice, 10 * this list of conditions and the following disclaimer. 11 * 12 * 2. Redistributions in binary form must reproduce the above copyright notice, 13 * this list of conditions and the following disclaimer in the documentation 14 * and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #ifndef KERNEL_DT_H 30 #define KERNEL_DT_H 31 32 #include <compiler.h> 33 #include <stdint.h> 34 #include <types_ext.h> 35 #include <util.h> 36 37 /* 38 * Bitfield to reflect status and secure-status values ("okay", "disabled" 39 * or not present) 40 */ 41 #define DT_STATUS_DISABLED 0 42 #define DT_STATUS_OK_NSEC BIT(0) 43 #define DT_STATUS_OK_SEC BIT(1) 44 45 #if defined(CFG_DT) 46 47 /* 48 * DT-aware drivers 49 */ 50 51 struct dt_device_match { 52 const char *compatible; 53 }; 54 55 struct dt_driver { 56 const char *name; 57 const struct dt_device_match *match_table; /* null-terminated */ 58 const void *driver; 59 }; 60 61 #define __dt_driver __section(".rodata.dtdrv") 62 63 /* 64 * Find a driver that is suitable for the given DT node, that is, with 65 * a matching "compatible" property. 66 * 67 * @fdt: pointer to the device tree 68 * @offs: node offset 69 */ 70 const struct dt_driver *dt_find_compatible_driver(const void *fdt, int offs); 71 72 const struct dt_driver *__dt_driver_start(void); 73 74 const struct dt_driver *__dt_driver_end(void); 75 76 /* 77 * Map a device into secure or non-secure memory and return the base VA and 78 * the mapping size. The mapping is done with type MEM_AREA_IO_SEC or 79 * MEM_AREA_IO_NSEC, depending on the device status. 80 * If the mapping already exists, the function simply returns the @vbase and 81 * @size information. 82 * 83 * @offs is the offset of the node that describes the device in @fdt. 84 * @base receives the base virtual address corresponding to the base physical 85 * address of the "reg" property 86 * @size receives the size of the mapping 87 * 88 * Returns 0 on success or -1 in case of error. 89 */ 90 int dt_map_dev(const void *fdt, int offs, vaddr_t *base, size_t *size); 91 92 /* 93 * Check whether the node at @offs contains the property with propname or not. 94 * 95 * @offs is the offset of the node that describes the device in @fdt. 96 * @propname is the property that need to check 97 * 98 * Returns true on success or false if no propname. 99 */ 100 bool dt_have_prop(const void *fdt, int offs, const char *propname); 101 102 /* 103 * FDT manipulation functions, not provided by <libfdt.h> 104 */ 105 106 /* 107 * Return the base address for the "reg" property of the specified node or 108 * (paddr_t)-1 in case of error 109 */ 110 paddr_t _fdt_reg_base_address(const void *fdt, int offs); 111 112 /* 113 * Return the reg size for the reg property of the specified node or -1 in case 114 * of error 115 */ 116 ssize_t _fdt_reg_size(const void *fdt, int offs); 117 118 /* 119 * Read the status and secure-status properties into a bitfield. 120 * @status is set to DT_STATUS_DISABLED or a combination of DT_STATUS_OK_NSEC 121 * and DT_STATUS_OK_SEC 122 * Returns 0 on success or -1 in case of error. 123 */ 124 int _fdt_get_status(const void *fdt, int offs); 125 126 #else /* !CFG_DT */ 127 128 static inline const struct dt_driver *__dt_driver_start(void) 129 { 130 return NULL; 131 } 132 133 static inline const struct dt_driver *__dt_driver_end(void) 134 { 135 return NULL; 136 } 137 138 static inline const struct dt_driver *dt_find_compatible_driver( 139 const void *fdt __unused, 140 int offs __unused) 141 { 142 return NULL; 143 } 144 145 static inline int dt_map_dev(const void *fdt __unused, int offs __unused, 146 vaddr_t *vbase __unused, size_t *size __unused) 147 { 148 return -1; 149 } 150 151 static inline paddr_t _fdt_reg_base_address(const void *fdt __unused, 152 int offs __unused) 153 { 154 return (paddr_t)-1; 155 } 156 157 static inline ssize_t _fdt_reg_size(const void *fdt __unused, 158 int offs __unused) 159 { 160 return -1; 161 } 162 163 static inline int _fdt_get_status(const void *fdt __unused, int offs __unused) 164 { 165 return -1; 166 } 167 168 #endif /* !CFG_DT */ 169 170 #define for_each_dt_driver(drv) \ 171 for (drv = __dt_driver_start(); drv < __dt_driver_end(); drv++) 172 173 #endif /* KERNEL_DT_H */ 174