1 /*
2 * Copyright (c) 2023 Institute of Parallel And Distributed Systems (IPADS), Shanghai Jiao Tong University (SJTU)
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 #include <arch/trustzone/tlogger.h>
13 #include <arch/mm/page_table.h>
14 #include <arch/mmu.h>
15 #include <arch/sync.h>
16 #include <mm/mm.h>
17 #include <mm/uaccess.h>
18 #include <common/util.h>
19 #include <object/thread.h>
20 #include <common/lock.h>
21
22 #define LOGGER_BASE 0xFFFFFD0000000000
23 #define TMP_LOGGER_SIZE (PAGE_SIZE << 6)
24
25 #define LOG_ITEM_MAGIC 0x5A5A
26 #define LOG_ITEM_LEN_ALIGN 64
27
28 #define LOG_ITEM_SIZE 384
29
30 const char *user_prefix = " [ChCore-User]";
31 const char *kernel_prefix = " [ChCore-Kernel]";
32
33 struct lock tlogger_lock;
34 volatile bool using_tlogger = false;
35 static struct log_buffer *logger = NULL;
36 extern unsigned long boot_ttbr1_l0[];
37
enable_tlogger(void)38 void enable_tlogger(void)
39 {
40 using_tlogger = true;
41 }
42
is_tlogger_on(void)43 bool is_tlogger_on(void)
44 {
45 return using_tlogger;
46 }
47
append_rdr_log(const void * buf,size_t len)48 int append_rdr_log(const void *buf, size_t len)
49 {
50 int ret = 0;
51
52 lock(&tlogger_lock);
53 if (!using_tlogger || !logger) {
54 goto out_unlock;
55 }
56
57 if (logger->flag.last_pos + len >= logger->flag.max_len) {
58 logger->flag.last_pos = 0;
59 logger->flag.write_loops++;
60 }
61 memcpy(logger->buffer_start + logger->flag.last_pos, buf, len);
62 logger->flag.last_pos += len;
63
64 out_unlock:
65 unlock(&tlogger_lock);
66 return ret;
67 }
68
append_chcore_log(const char * str,size_t len,bool is_kernel)69 int append_chcore_log(const char *str, size_t len, bool is_kernel)
70 {
71 int ret, count;
72 struct log_item *item;
73 size_t item_size;
74 char *ptr;
75 char log_item_buf[LOG_ITEM_SIZE];
76 const char *prefix;
77
78 if (is_kernel) {
79 prefix = kernel_prefix;
80 } else {
81 prefix = user_prefix;
82 }
83
84 item_size = sizeof(struct log_item) + strlen(prefix) + len + 2;
85 if (current_thread && current_cap_group) {
86 item_size += 1 + strlen(current_cap_group->cap_group_name) + 1;
87 }
88
89 if (item_size >= LOG_ITEM_SIZE) {
90 return -E2BIG;
91 }
92 memset(log_item_buf, 0, sizeof(log_item_buf));
93 item = (struct log_item *)log_item_buf;
94
95 ptr = (char *)item->log_buffer;
96 if (current_thread && current_cap_group) {
97 count = simple_sprintf(
98 ptr, "%s[%s]", prefix, current_cap_group->cap_group_name);
99 } else {
100 count = simple_sprintf(ptr, "%s", prefix);
101 }
102 ptr += count;
103 memcpy(ptr, str, len);
104 while (ptr[len - 1] == ' ') {
105 ptr[--len] = 0;
106 }
107 if (ptr[len - 1] != '\n') {
108 ptr[len++] = '\n';
109 }
110
111 item->magic = LOG_ITEM_MAGIC;
112 item->real_len = count + len;
113 item->buffer_len = (item->real_len + LOG_ITEM_LEN_ALIGN - 1)
114 / LOG_ITEM_LEN_ALIGN * LOG_ITEM_LEN_ALIGN;
115 item->log_level = 2;
116
117 ret = append_rdr_log(item, sizeof(struct log_item) + item->buffer_len);
118
119 return ret;
120 }
121
tmp_tlogger_init(void)122 int tmp_tlogger_init(void)
123 {
124 logger = kmalloc(TMP_LOGGER_SIZE);
125 if (logger == NULL) {
126 return -ENOMEM;
127 }
128 logger->flag.last_pos = 0;
129 logger->flag.write_loops = 0;
130 logger->flag.max_len = TMP_LOGGER_SIZE - sizeof(struct log_buffer);
131 lock_init(&tlogger_lock);
132 return 0;
133 }
134
sys_tee_push_rdr_update_addr(paddr_t addr,size_t size,bool is_cache_mem,char * chip_type_buff,size_t buff_len)135 int sys_tee_push_rdr_update_addr(paddr_t addr, size_t size, bool is_cache_mem,
136 char *chip_type_buff, size_t buff_len)
137 {
138 int ret;
139 struct log_buffer *tmp_logger;
140 size_t copy_len;
141
142 size = ROUND_UP(size, PAGE_SIZE);
143 ret = map_range_in_pgtbl_kernel(
144 (void *)((unsigned long)boot_ttbr1_l0 + KBASE),
145 LOGGER_BASE,
146 addr,
147 size,
148 VMR_READ | VMR_WRITE | VMR_TZ_NS);
149 flush_tlb_all();
150 if (ret) {
151 goto out;
152 }
153 tmp_logger = logger;
154 logger = (void *)LOGGER_BASE;
155 logger->flag.last_pos = tmp_logger->flag.last_pos;
156 logger->flag.write_loops = tmp_logger->flag.write_loops;
157 logger->flag.max_len = size - sizeof(struct log_buffer);
158 copy_len = MIN(tmp_logger->flag.max_len, logger->flag.max_len);
159 memcpy(logger->buffer_start, tmp_logger->buffer_start, copy_len);
160 kfree(tmp_logger);
161
162 out:
163 return ret;
164 }
165
sys_debug_rdr_logitem(char * str,size_t str_len)166 int sys_debug_rdr_logitem(char *str, size_t str_len)
167 {
168 int ret = 0;
169 char *kbuf;
170 if (check_user_addr_range((vaddr_t)str, str_len)) {
171 return -EINVAL;
172 }
173 kbuf = kmalloc(str_len);
174 if (kbuf == NULL) {
175 return -ENOMEM;
176 }
177 ret = copy_from_user(kbuf, str, str_len);
178 if (ret) {
179 goto out;
180 }
181
182 ret = append_rdr_log(kbuf, str_len);
183
184 out:
185 kfree(kbuf);
186 return ret;
187 }
188