xref: /optee_os/core/kernel/dt.c (revision 1bb929836182ecb96d2d9d268daa807c67596396)
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 #include <assert.h>
30 #include <kernel/dt.h>
31 #include <kernel/linker.h>
32 #include <libfdt.h>
33 #include <mm/core_memprot.h>
34 #include <mm/core_mmu.h>
35 #include <string.h>
36 #include <trace.h>
37 
38 const struct dt_driver *dt_find_compatible_driver(const void *fdt, int offs)
39 {
40 	const struct dt_device_match *dm;
41 	const struct dt_driver *drv;
42 
43 	for_each_dt_driver(drv)
44 		for (dm = drv->match_table; dm; dm++)
45 			if (!fdt_node_check_compatible(fdt, offs,
46 						       dm->compatible))
47 				return drv;
48 
49 	return NULL;
50 }
51 
52 const struct dt_driver *__dt_driver_start(void)
53 {
54 	return &__rodata_dtdrv_start;
55 }
56 
57 const struct dt_driver *__dt_driver_end(void)
58 {
59 	return &__rodata_dtdrv_end;
60 }
61 
62 bool dt_have_prop(const void *fdt, int offs, const char *propname)
63 {
64 	const void *prop;
65 
66 	prop = fdt_getprop(fdt, offs, propname, NULL);
67 
68 	return prop;
69 }
70 
71 int dt_map_dev(const void *fdt, int offs, vaddr_t *base, size_t *size)
72 {
73 	enum teecore_memtypes mtype;
74 	paddr_t pbase;
75 	vaddr_t vbase;
76 	ssize_t sz;
77 	int st;
78 
79 	assert(cpu_mmu_enabled());
80 
81 	st = _fdt_get_status(fdt, offs);
82 	if (st == DT_STATUS_DISABLED)
83 		return -1;
84 
85 	pbase = _fdt_reg_base_address(fdt, offs);
86 	if (pbase == (paddr_t)-1)
87 		return -1;
88 	sz = _fdt_reg_size(fdt, offs);
89 	if (sz < 0)
90 		return -1;
91 
92 	if ((st & DT_STATUS_OK_SEC) && !(st & DT_STATUS_OK_NSEC))
93 		mtype = MEM_AREA_IO_SEC;
94 	else
95 		mtype = MEM_AREA_IO_NSEC;
96 
97 	/* Check if we have a mapping, create one if needed */
98 	if (!core_mmu_add_mapping(mtype, pbase, sz)) {
99 		EMSG("Failed to map %zu bytes at PA 0x%"PRIxPA,
100 		     (size_t)sz, pbase);
101 		return -1;
102 	}
103 	vbase = (vaddr_t)phys_to_virt(pbase, mtype);
104 	if (!vbase) {
105 		EMSG("Failed to get VA for PA 0x%"PRIxPA, pbase);
106 		return -1;
107 	}
108 
109 	*base = vbase;
110 	*size = sz;
111 	return 0;
112 }
113 
114 /* Read a physical address (n=1 or 2 cells) */
115 static paddr_t _fdt_read_paddr(const uint32_t *cell, int n)
116 {
117 	paddr_t addr;
118 
119 	if (n < 1 || n > 2)
120 		goto bad;
121 
122 	addr = fdt32_to_cpu(*cell);
123 	cell++;
124 	if (n == 2) {
125 #ifdef ARM32
126 		if (addr) {
127 			/* High order 32 bits can't be nonzero */
128 			goto bad;
129 		}
130 		addr = fdt32_to_cpu(*cell);
131 #else
132 		addr = (addr << 32) | fdt32_to_cpu(*cell);
133 #endif
134 	}
135 
136 	if (!addr)
137 		goto bad;
138 
139 	return addr;
140 bad:
141 	return (paddr_t)-1;
142 
143 }
144 
145 paddr_t _fdt_reg_base_address(const void *fdt, int offs)
146 {
147 	const void *reg;
148 	int ncells;
149 	int len;
150 	int parent;
151 
152 	parent = fdt_parent_offset(fdt, offs);
153 	if (parent < 0)
154 		return (paddr_t)-1;
155 
156 	reg = fdt_getprop(fdt, offs, "reg", &len);
157 	if (!reg)
158 		return (paddr_t)-1;
159 
160 	ncells = fdt_address_cells(fdt, parent);
161 	if (ncells < 0)
162 		return (paddr_t)-1;
163 
164 	return _fdt_read_paddr(reg, ncells);
165 }
166 
167 ssize_t _fdt_reg_size(const void *fdt, int offs)
168 {
169 	const uint32_t *reg;
170 	uint32_t sz;
171 	int n;
172 	int len;
173 	int parent;
174 
175 	parent = fdt_parent_offset(fdt, offs);
176 	if (parent < 0)
177 		return (paddr_t)-1;
178 
179 	reg = (const uint32_t *)fdt_getprop(fdt, offs, "reg", &len);
180 	if (!reg)
181 		return -1;
182 
183 	n = fdt_address_cells(fdt, parent);
184 	if (n < 1 || n > 2)
185 		return -1;
186 
187 	reg += n;
188 
189 	n = fdt_size_cells(fdt, parent);
190 	if (n < 1 || n > 2)
191 		return -1;
192 
193 	sz = fdt32_to_cpu(*reg);
194 	if (n == 2) {
195 		if (sz)
196 			return -1;
197 		reg++;
198 		sz = fdt32_to_cpu(*reg);
199 	}
200 
201 	return sz;
202 }
203 
204 static bool is_okay(const char *st, int len)
205 {
206 	return !strncmp(st, "ok", len) || !strncmp(st, "okay", len);
207 }
208 
209 int _fdt_get_status(const void *fdt, int offs)
210 {
211 	const char *prop;
212 	int st = 0;
213 	int len;
214 
215 	prop = fdt_getprop(fdt, offs, "status", &len);
216 	if (!prop || is_okay(prop, len)) {
217 		/* If status is not specified, it defaults to "okay" */
218 		st |= DT_STATUS_OK_NSEC;
219 	}
220 
221 	prop = fdt_getprop(fdt, offs, "secure-status", &len);
222 	if (!prop) {
223 		/*
224 		 * When secure-status is not specified it defaults to the same
225 		 * value as status
226 		 */
227 		if (st & DT_STATUS_OK_NSEC)
228 			st |= DT_STATUS_OK_SEC;
229 	} else {
230 		if (is_okay(prop, len))
231 			st |= DT_STATUS_OK_SEC;
232 	}
233 
234 	return st;
235 }
236