1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  * Copyright 2016-2017 Texas Instruments, Inc.
4  */
5 
6 #include <common.h>
7 #include <linux/libfdt.h>
8 #include <fdt_support.h>
9 
10 #include <asm/omap_common.h>
11 #include <asm/omap_sec_common.h>
12 
13 #ifdef CONFIG_TI_SECURE_DEVICE
14 
15 /* Give zero values if not already defined */
16 #ifndef TI_OMAP5_SECURE_BOOT_RESV_SRAM_SZ
17 #define TI_OMAP5_SECURE_BOOT_RESV_SRAM_SZ (0)
18 #endif
19 #ifndef CONFIG_SECURE_RUNTIME_RESV_SRAM_SZ
20 #define CONFIG_SECURE_RUNTIME_RESV_SRAM_SZ (0)
21 #endif
22 
23 int ft_hs_disable_rng(void *fdt, bd_t *bd)
24 {
25 	const char *path;
26 	int offs;
27 	int ret;
28 
29 	/* Make HW RNG reserved for secure world use */
30 	path = "/ocp/rng";
31 	offs = fdt_path_offset(fdt, path);
32 	if (offs < 0) {
33 		debug("Node %s not found.\n", path);
34 		return 0;
35 	}
36 	ret = fdt_setprop_string(fdt, offs,
37 				 "status", "disabled");
38 	if (ret < 0) {
39 		printf("Could not add status property to node %s: %s\n",
40 		       path, fdt_strerror(ret));
41 		return ret;
42 	}
43 	return 0;
44 }
45 
46 #if (CONFIG_TI_SECURE_EMIF_TOTAL_REGION_SIZE != 0)
47 /*
48  * fdt_pack_reg - pack address and size array into the "reg"-suitable stream
49  */
50 static int fdt_pack_reg(const void *fdt, void *buf, u64 address, u64 size)
51 {
52 	int address_cells = fdt_address_cells(fdt, 0);
53 	int size_cells = fdt_size_cells(fdt, 0);
54 	char *p = buf;
55 
56 	if (address_cells == 2)
57 		*(fdt64_t *)p = cpu_to_fdt64(address);
58 	else
59 		*(fdt32_t *)p = cpu_to_fdt32(address);
60 	p += 4 * address_cells;
61 
62 	if (size_cells == 2)
63 		*(fdt64_t *)p = cpu_to_fdt64(size);
64 	else
65 		*(fdt32_t *)p = cpu_to_fdt32(size);
66 	p += 4 * size_cells;
67 
68 	return p - (char *)buf;
69 }
70 
71 int ft_hs_fixup_dram(void *fdt, bd_t *bd)
72 {
73 	const char *path, *subpath;
74 	int offs, len;
75 	u32 sec_mem_start = get_sec_mem_start();
76 	u32 sec_mem_size = CONFIG_TI_SECURE_EMIF_TOTAL_REGION_SIZE;
77 	fdt32_t address_cells = cpu_to_fdt32(fdt_address_cells(fdt, 0));
78 	fdt32_t size_cells = cpu_to_fdt32(fdt_size_cells(fdt, 0));
79 	u8 temp[16]; /* Up to 64-bit address + 64-bit size */
80 
81 	/* Delete any original secure_reserved node */
82 	path = "/reserved-memory/secure_reserved";
83 	offs = fdt_path_offset(fdt, path);
84 	if (offs >= 0)
85 		fdt_del_node(fdt, offs);
86 
87 	/* Add new secure_reserved node */
88 	path = "/reserved-memory";
89 	offs = fdt_path_offset(fdt, path);
90 	if (offs < 0) {
91 		debug("Node %s not found\n", path);
92 		path = "/";
93 		subpath = "reserved-memory";
94 		offs = fdt_path_offset(fdt, path);
95 		offs = fdt_add_subnode(fdt, offs, subpath);
96 		if (offs < 0) {
97 			printf("Could not create %s%s node.\n", path, subpath);
98 			return 1;
99 		}
100 		path = "/reserved-memory";
101 		offs = fdt_path_offset(fdt, path);
102 
103 		fdt_setprop(fdt, offs, "#address-cells", &address_cells, sizeof(address_cells));
104 		fdt_setprop(fdt, offs, "#size-cells", &size_cells, sizeof(size_cells));
105 		fdt_setprop(fdt, offs, "ranges", NULL, 0);
106 	}
107 
108 	subpath = "secure_reserved";
109 	offs = fdt_add_subnode(fdt, offs, subpath);
110 	if (offs < 0) {
111 		printf("Could not create %s%s node.\n", path, subpath);
112 		return 1;
113 	}
114 
115 	fdt_setprop_string(fdt, offs, "compatible", "ti,secure-memory");
116 	fdt_setprop_string(fdt, offs, "status", "okay");
117 	fdt_setprop(fdt, offs, "no-map", NULL, 0);
118 	len = fdt_pack_reg(fdt, temp, sec_mem_start, sec_mem_size);
119 	fdt_setprop(fdt, offs, "reg", temp, len);
120 
121 	return 0;
122 }
123 #else
124 int ft_hs_fixup_dram(void *fdt, bd_t *bd) { return 0; }
125 #endif
126 
127 int ft_hs_add_tee(void *fdt, bd_t *bd)
128 {
129 	const char *path, *subpath;
130 	int offs;
131 
132 	extern int tee_loaded;
133 	if (!tee_loaded)
134 		return 0;
135 
136 	path = "/firmware";
137 	offs = fdt_path_offset(fdt, path);
138 	if (offs < 0) {
139 		path = "/";
140 		offs = fdt_path_offset(fdt, path);
141 		if (offs < 0) {
142 			printf("Could not find root node.\n");
143 			return 1;
144 		}
145 
146 		subpath = "firmware";
147 		offs = fdt_add_subnode(fdt, offs, subpath);
148 		if (offs < 0) {
149 			printf("Could not create %s node.\n", subpath);
150 			return 1;
151 		}
152 	}
153 
154 	subpath = "optee";
155 	offs = fdt_add_subnode(fdt, offs, subpath);
156 	if (offs < 0) {
157 		printf("Could not create %s node.\n", subpath);
158 		return 1;
159 	}
160 
161 	fdt_setprop_string(fdt, offs, "compatible", "linaro,optee-tz");
162 	fdt_setprop_string(fdt, offs, "method", "smc");
163 
164 	return 0;
165 }
166 
167 #endif
168