1 /*
2 * Copyright (C) 2022 Huawei Technologies Co., Ltd.
3 * Licensed under the Mulan PSL v2.
4 * You can use this software according to the terms and conditions of the Mulan PSL v2.
5 * You may obtain a copy of Mulan PSL v2 at:
6 * http://license.coscl.org.cn/MulanPSL2
7 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR
8 * IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR
9 * PURPOSE.
10 * See the Mulan PSL v2 for more details.
11 */
12
13 #include <set_teeos_cfg.h>
14
15 #include <securec.h>
16
17 #include <teeos_uuid.h>
18 #include <tlv_sharedmem.h>
19
20 #define TEEOS_TEXT_OFFSET (0x8000)
21 #define ALIGN_SIZE_2M (0x200000)
22
23 struct platform_info {
24 uint64_t plat_cfg_size;
25 uint64_t phys_region_size;
26 uint64_t phys_region_start;
27 uint64_t uart_addr;
28 uint64_t uart_type;
29 p_region_t protected_regions[MAX_PROTECTED_REGIONS];
30 uint64_t reserved;
31 uint64_t shmem_size;
32 uint32_t random_seed;
33 struct gic_config_t gic_config;
34 uint32_t spi_num_for_notify;
35 uint64_t plat_features;
36 struct extend_datas_t {
37 uint64_t extend_length;
38 char extend_paras[0];
39 } extend_datas;
40 };
41
42 static struct platform_info g_teeos_cfg;
43
44 static uintptr_t g_teeos_base_addr = 0;
45
set_teeos_mem(uintptr_t teeos_base_addr,uint64_t size)46 int32_t set_teeos_mem(uintptr_t teeos_base_addr, uint64_t size)
47 {
48 g_teeos_base_addr = teeos_base_addr;
49 g_teeos_cfg.phys_region_size = size;
50 if ((uint64_t)teeos_base_addr % ALIGN_SIZE_2M != 0)
51 return -1;
52
53 g_teeos_cfg.phys_region_start = (uint64_t)teeos_base_addr;
54
55 return 0;
56 }
57
set_teeos_uart(uint64_t uart_addr,uint64_t uart_type)58 void set_teeos_uart(uint64_t uart_addr, uint64_t uart_type)
59 {
60 g_teeos_cfg.uart_addr = uart_addr;
61 g_teeos_cfg.uart_type = uart_type;
62 }
63
set_protected_regions(p_region_t * protected_regions,uint32_t regions_num)64 bool set_protected_regions(p_region_t *protected_regions, uint32_t regions_num)
65 {
66 if (regions_num > MAX_PROTECTED_REGIONS)
67 return false;
68
69 if (protected_regions == NULL)
70 return false;
71
72 if (memcpy_s(g_teeos_cfg.protected_regions, sizeof(p_region_t) * regions_num,
73 protected_regions, sizeof(p_region_t) * regions_num) != EOK)
74 return false;
75
76 return true;
77 }
78
set_sharedmem_size(uint64_t shmem_size)79 void set_sharedmem_size(uint64_t shmem_size)
80 {
81 g_teeos_cfg.shmem_size = shmem_size;
82 }
83
set_random(uint64_t random_data)84 bool set_random(uint64_t random_data)
85 {
86 if (random_data == 0)
87 return false;
88
89 g_teeos_cfg.random_seed = random_data;
90
91 return true;
92 }
93
set_gic(struct gic_config_t gic_config)94 void set_gic(struct gic_config_t gic_config)
95 {
96 g_teeos_cfg.gic_config = gic_config;
97 }
98
set_spi_num(uint32_t spi_num)99 void set_spi_num(uint32_t spi_num)
100 {
101 g_teeos_cfg.spi_num_for_notify = spi_num;
102 }
103
set_plat_features(uint64_t plat_features)104 void set_plat_features(uint64_t plat_features)
105 {
106 g_teeos_cfg.plat_features = plat_features;
107 }
108
copy_extend_datas(void * extend_datas,uint64_t extend_length)109 bool copy_extend_datas(void *extend_datas, uint64_t extend_length)
110 {
111 if (extend_datas == NULL)
112 return false;
113
114 if (sizeof(struct platform_info) + extend_length > MAX_CONFIG_LENGTH)
115 return false;
116
117 g_teeos_cfg.extend_datas.extend_length = extend_length;
118 char *dst = (char *)(uintptr_t)(g_teeos_cfg.phys_region_start + sizeof(g_teeos_cfg));
119
120 if (memcpy_s(dst, MAX_CONFIG_LENGTH - sizeof(g_teeos_cfg),
121 extend_datas, extend_length) != EOK)
122 return false;
123
124 return true;
125 }
126
copy_teeos_cfg(void)127 bool copy_teeos_cfg(void)
128 {
129 if (g_teeos_cfg.phys_region_start == 0)
130 return false;
131
132 g_teeos_cfg.plat_cfg_size = sizeof(struct platform_info) + g_teeos_cfg.extend_datas.extend_length;
133 char *dst = (void *)(uintptr_t)g_teeos_cfg.phys_region_start;
134
135 if (memcpy_s(dst, sizeof(g_teeos_cfg),
136 (char *)&g_teeos_cfg, g_teeos_cfg.plat_cfg_size - sizeof(uint64_t)) != EOK)
137 return false;
138
139 return true;
140 }
141
get_teeos_start(void)142 uint64_t get_teeos_start(void)
143 {
144 return g_teeos_cfg.phys_region_start;
145 }
146
get_teeos_code_start(void)147 uint64_t get_teeos_code_start(void)
148 {
149 return g_teeos_cfg.phys_region_start + TEEOS_TEXT_OFFSET;
150 }
151
get_teeos_size(void)152 uint64_t get_teeos_size(void)
153 {
154 return g_teeos_cfg.phys_region_size;
155 }
156
get_sharedmem_start(void)157 uint64_t get_sharedmem_start(void)
158 {
159 return g_teeos_cfg.phys_region_start + g_teeos_cfg.phys_region_size - g_teeos_cfg.shmem_size;
160 }
161
get_sharedmem_size(void)162 uint64_t get_sharedmem_size(void)
163 {
164 return g_teeos_cfg.shmem_size;
165 }
166
167 #define CHIP_TYPE_TAG "chip_type"
168 #define CHIP_TYPE_LEN_MAX 32
set_chip_type_info(char * chip_type,uint32_t size)169 int32_t set_chip_type_info(char *chip_type, uint32_t size)
170 {
171 TEE_UUID all_service = TEE_SERVICE_ALL;
172 struct tlv_item_data tlv_item_data;
173 char chip_type_tmp[CHIP_TYPE_LEN_MAX] = {0};
174
175 if (memcpy_s(chip_type_tmp, CHIP_TYPE_LEN_MAX,
176 chip_type, (size > CHIP_TYPE_LEN_MAX) ? CHIP_TYPE_LEN_MAX : size) != EOK) {
177 teelog("copy to chip_type_tmp failed\n");
178 return -1;
179 }
180
181 tlv_item_data.type = CHIP_TYPE_TAG;
182 tlv_item_data.type_size = strlen(CHIP_TYPE_TAG);
183 tlv_item_data.owner_list = (void *)&all_service;
184 tlv_item_data.owner_len = sizeof(TEE_UUID);
185 tlv_item_data.value = chip_type;
186 tlv_item_data.value_len = size;
187
188 if (put_tlv_shared_mem(tlv_item_data) != 0) {
189 teelog("put chip_type info failed\n");
190 return -1;
191 }
192
193 return 0;
194 }
195