• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Winner Microelectronics Co., Ltd. All rights reserved.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <stdio.h>
17 #include <string.h>
18 #include "wm_sasc.h"
19 
20 extern void dumpBuffer(char *name, char* buffer, int len);
21 
22 #define TEST_DEBUG_EN           1
23 #if TEST_DEBUG_EN
24 #define TEST_DEBUG(fmt, ...)    printf("%s: "fmt, __func__, ##__VA_ARGS__)
25 #else
26 #define TEST_DEBUG(fmt, ...)
27 #endif
28 
switch_to_ree(void)29 static void switch_to_ree(void)
30 {
31     csi_vic_disable_irq(SYS_TICK_IRQn);
32     __asm__ volatile(
33         "mtcr r14, cr<6, 3> \n"
34         "mfcr     a3, psr\n"
35         "bclri    a3, 30 \n" // Clear PSR.T
36         "mtcr     a3, psr \n"
37         "psrset   ee, ie \n" // Set EE & IE
38         "mfcr     a3, psr\n"
39         "bseti    a3, 9 \n" // Set MM
40         "mtcr     a3, psr \n"
41     );
42     __asm__ volatile("mtcr %0, vbr" : : "r"(& (__Vectors)));
43     TEST_DEBUG("switched to ree\n");
44 }
45 
get_block_from_addr(uint32_t base_addr)46 static SASC_Type* get_block_from_addr(uint32_t base_addr)
47 {
48     if (base_addr >= 0x8000000 && base_addr < 0x10000000) {
49         return SASC_FLASH;
50     } else if (base_addr < 0x20028000 && base_addr >= 0x20000000) {
51         return SASC_B1;
52     } else if (base_addr < 0x20048000 && base_addr >= 0x20028000) {
53         return SASC_B2;
54     }
55     return NULL;
56 }
57 
wm_sasc_config_region(SASC_Type * block,uint32_t idx,uint32_t base_addr,sasc_region_size_e size,sasc_region_attr_t * attr,uint32_t enable)58 static void wm_sasc_config_region(SASC_Type *block, uint32_t idx, uint32_t base_addr, sasc_region_size_e size,
59     sasc_region_attr_t *attr, uint32_t enable)
60 {
61     base_addr &= 0x03FFFFFC;
62     block->REGION[idx] = size | (base_addr << 6);
63     // printf("region %d: 0x%x\n", idx, size | (base_addr << 6));
64     block->CAR = _R2_Pos(attr->car, idx) | (block->CAR & ~(_R2_Msk(idx)));
65     switch (attr->car) {
66         case SASC_UN_SE_USER:
67             block->AP0 = _R2_Pos(attr->ap, idx) | (block->AP0 & ~(_R2_Msk(idx)));
68             block->CD0 = _R2_Pos(attr->cd, idx) | (block->CD0 & ~(_R2_Msk(idx)));
69             break;
70         case SASC_UN_SE_SUPER:
71             block->AP1 = _R2_Pos(attr->ap, idx) | (block->AP1 & ~(_R2_Msk(idx)));
72             block->CD1 = _R2_Pos(attr->cd, idx) | (block->CD1 & ~(_R2_Msk(idx)));
73             break;
74         case SASC_SE_USER:
75             block->AP2 = _R2_Pos(attr->ap, idx) | (block->AP2 & ~(_R2_Msk(idx)));
76             block->CD2 = _R2_Pos(attr->cd, idx) | (block->CD2 & ~(_R2_Msk(idx)));
77             break;
78         default:
79             break;
80     }
81     block->CR = _R1_Pos(enable, idx) | (block->CR & ~(_R1_Msk(idx)));
82 }
83 
wm_sasc_enable_region(SASC_Type * block,uint32_t idx)84 void wm_sasc_enable_region(SASC_Type *block, uint32_t idx)
85 {
86     block->CR = _R1_Pos(1, idx) | (block->CR & ~(_R1_Msk(idx)));
87 }
88 
wm_sasc_disable_region(SASC_Type * block,uint32_t idx)89 void wm_sasc_disable_region(SASC_Type *block, uint32_t idx)
90 {
91     block->CR = (block->CR & ~(_R1_Msk(idx)));
92 }
93 
set_region_protect(uint32_t base_addr,uint32_t idx,sasc_region_size_e size,sasc_region_attr_t * attr)94 void set_region_protect(uint32_t base_addr, uint32_t idx, sasc_region_size_e size, sasc_region_attr_t *attr)
95 {
96     SASC_Type* block = get_block_from_addr(base_addr);
97 
98     TEST_DEBUG("base_addr %x idx %u size 0x%x ap %d cd %d car %d\n", \
99                 base_addr, idx, size, attr->ap, attr->cd, attr->car);
100     if (base_addr >= 0x8000000 && base_addr < 0x10000000) {
101         base_addr &= 0x1FFFFFF;
102     } else if (base_addr < 0x20028000 && base_addr >= 0x20000000) {
103         base_addr &= 0x3FFFF;
104     } else if (base_addr < 0x20048000 && base_addr >= 0x20028000) {
105         base_addr &= 0x7FFFF;
106     }
107     wm_sasc_config_region(block, idx, base_addr, size, attr, 1);
108 }
109 
110 /**
111   *******************************************************
112   *               TEST CODE IS BELOW
113   *******************************************************
114   */
115 
access_region(uint32_t base_addr,sasc_region_size_e size,sasc_region_attr_t * attr,int pos)116 void access_region(uint32_t base_addr, sasc_region_size_e size, sasc_region_attr_t *attr, int pos)
117 {
118     char dest[4] = {0xa5, 0xa5, 0xa5, 0xa5};
119     uint32_t s = 1 << (size - 3);
120     TEST_DEBUG("base_addr %x size 0x%x\n", base_addr, s);
121 
122     switch (pos) {
123         case 0:
124             memcpy_s(dest, sizeof(dest), (char*)(base_addr + s), sizeof(dest));
125             TEST_DEBUG("Behind addr %x size 0x%lx can read\n", base_addr + s, (unsigned long)sizeof(dest));
126             TEST_DEBUG("start to read addr %x size 0x%lx\n", \
127                         base_addr + s - (uint32_t)sizeof(dest), (unsigned long)sizeof(dest));
128             memcpy_s(dest, sizeof(dest), (char*)(base_addr + s - sizeof(dest)), sizeof(dest));
129             TEST_DEBUG("addr %x size 0x%lx can read\n", \
130                         base_addr + s - (uint32_t)sizeof(dest), (unsigned long)sizeof(dest));
131             break;
132         case 1:
133             memcpy_s(dest, sizeof(dest), (char*)(base_addr - sizeof(dest)), sizeof(dest));
134             TEST_DEBUG("Front addr %x size 0x%lx can read\n", \
135                        base_addr - (uint32_t)sizeof(dest), (unsigned long)sizeof(dest));
136             TEST_DEBUG("start to read addr %x size 0x%lx\n", base_addr, (unsigned long)sizeof(dest));
137             memcpy_s(dest, sizeof(dest), (char*)base_addr, sizeof(dest));
138             TEST_DEBUG("base_addr %x size 0x%lx can read\n", base_addr, (unsigned long)sizeof(dest));
139             break;
140         case 2:
141             memcpy_s((char*)(base_addr - sizeof(dest)), sizeof(base_addr -sizeof(dest)), dest, sizeof(dest));
142             TEST_DEBUG("Front addr %x size 0x%lx can write\n", \
143                        base_addr - (uint32_t)sizeof(dest), (unsigned long)sizeof(dest));
144             TEST_DEBUG("start to write addr %x size 0x%lx\n", base_addr, (unsigned long)sizeof(dest));
145             memcpy_s((char*)base_addr, sizeof(base_addr), dest, sizeof(dest));
146             TEST_DEBUG("base_addr %x size 0x%lx can write\n", base_addr, (unsigned long)sizeof(dest));
147             break;
148         default:
149             memcpy_s((char*)(base_addr + s), sizeof(base_addr + s), dest, sizeof(dest));
150             TEST_DEBUG("Behind addr %x size 0x%lx can write\n", base_addr + s, (unsigned long)sizeof(dest));
151             TEST_DEBUG("start to write addr %x size 0x%lx\n", \
152                        base_addr + s - (uint32_t)sizeof(dest), (unsigned long)sizeof(dest));
153             memcpy_s((char*)(base_addr + s - sizeof(dest)), sizeof(base_addr + s - sizeof(dest)), dest, sizeof(dest));
154             TEST_DEBUG("addr %x size 0x%lx can write\n", \
155                        base_addr + s - (uint32_t)sizeof(dest), (unsigned long)sizeof(dest));
156             break;
157     }
158     dumpBuffer("dest", dest, sizeof(dest));
159 }
160 
sasc_region_security_test(int num)161 int sasc_region_security_test(int num)
162 {
163     sasc_region_attr_t attr;
164     attr.ap = SASC_AP_DENYALL;
165     attr.cd = SASC_CD_DA_OF;
166     attr.car = SASC_SE_SUPER;
167     set_region_protect(0x08010000, 0, SASC_REGION_SIZE_64KB, &attr);
168     set_region_protect(0x20010000, 1, SASC_REGION_SIZE_16KB, &attr);
169     set_region_protect(0x20030000, 2, SASC_REGION_SIZE_32KB, &attr);
170 
171 //   SASC_B2->REGION[0] = SASC_REGION_SIZE_32KB | (0x8000 << 6);
172 
173     switch_to_ree();
174 
175     switch (num) {
176         case 0:
177             access_region(0x20010000, SASC_REGION_SIZE_16KB, &attr, 0);
178             break;
179         case 1:
180             access_region(0x20010000, SASC_REGION_SIZE_16KB, &attr, 1);
181             break;
182         case 2:
183             access_region(0x20010000, SASC_REGION_SIZE_16KB, &attr, 2);
184             break;
185         case 3:
186             access_region(0x20010000, SASC_REGION_SIZE_16KB, &attr, 3);
187             break;
188         case 4:
189             access_region(0x20030000, SASC_REGION_SIZE_32KB, &attr, 0);
190             break;
191         case 5:
192             access_region(0x20030000, SASC_REGION_SIZE_32KB, &attr, 1);
193             break;
194         case 6:
195             access_region(0x20030000, SASC_REGION_SIZE_32KB, &attr, 2);
196             break;
197         case 7:
198             access_region(0x20030000, SASC_REGION_SIZE_32KB, &attr, 3);
199             break;
200         case 8:
201             access_region(0x08010000, SASC_REGION_SIZE_64KB, &attr, 0);
202             break;
203         case 9:
204             access_region(0x08010000, SASC_REGION_SIZE_64KB, &attr, 1);
205             break;
206         default:
207             break;
208     }
209     return -1;
210 }
211 
212