wm_sasc.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include "wm_sasc.h"
  4. extern void dumpBuffer(char *name, char* buffer, int len);
  5. #define TEST_DEBUG_EN 1
  6. #if TEST_DEBUG_EN
  7. #define TEST_DEBUG(fmt, ...) printf("%s: "fmt, __func__, ##__VA_ARGS__)
  8. #else
  9. #define TEST_DEBUG(fmt, ...)
  10. #endif
  11. static void switch_to_ree(void)
  12. {
  13. csi_vic_disable_irq(SYS_TICK_IRQn);
  14. __asm__ volatile(
  15. "mtcr r14, cr<6, 3> \n"
  16. "mfcr a3, psr\n"
  17. "bclri a3, 30 \n" //Clear PSR.T
  18. "mtcr a3, psr \n"
  19. "psrset ee, ie \n" //Set EE & IE
  20. "mfcr a3, psr\n"
  21. "bseti a3, 9 \n" //Set MM
  22. "mtcr a3, psr \n"
  23. );
  24. __asm__ volatile("mtcr %0, vbr" : : "r"(& (__Vectors)));
  25. TEST_DEBUG("switched to ree\n");
  26. }
  27. static SASC_Type* get_block_from_addr(uint32_t base_addr)
  28. {
  29. if(base_addr >= 0x8000000 && base_addr < 0x10000000)
  30. {
  31. return SASC_FLASH;
  32. }
  33. else if(base_addr < 0x20028000 && base_addr >= 0x20000000)
  34. {
  35. return SASC_B1;
  36. }
  37. else if(base_addr < 0x20048000 && base_addr >= 0x20028000)
  38. {
  39. return SASC_B2;
  40. }
  41. return NULL;
  42. }
  43. static void wm_sasc_config_region(SASC_Type *block, uint32_t idx, uint32_t base_addr, sasc_region_size_e size,
  44. sasc_region_attr_t *attr, uint32_t enable)
  45. {
  46. base_addr &= 0x03FFFFFC;
  47. block->REGION[idx] = size | (base_addr << 6);
  48. //printf("region %d: 0x%x\n", idx, size | (base_addr << 6));
  49. block->CAR = _R2_Pos(attr->car, idx) | (block->CAR & ~(_R2_Msk(idx)));
  50. switch(attr->car)
  51. {
  52. case SASC_UN_SE_USER:
  53. block->AP0 = _R2_Pos(attr->ap, idx) | (block->AP0 & ~(_R2_Msk(idx)));
  54. block->CD0 = _R2_Pos(attr->cd, idx) | (block->CD0 & ~(_R2_Msk(idx)));
  55. break;
  56. case SASC_UN_SE_SUPER:
  57. block->AP1 = _R2_Pos(attr->ap, idx) | (block->AP1 & ~(_R2_Msk(idx)));
  58. block->CD1 = _R2_Pos(attr->cd, idx) | (block->CD1 & ~(_R2_Msk(idx)));
  59. break;
  60. case SASC_SE_USER:
  61. block->AP2 = _R2_Pos(attr->ap, idx) | (block->AP2 & ~(_R2_Msk(idx)));
  62. block->CD2 = _R2_Pos(attr->cd, idx) | (block->CD2 & ~(_R2_Msk(idx)));
  63. break;
  64. default:
  65. break;
  66. }
  67. block->CR = _R1_Pos(enable, idx) | (block->CR & ~(_R1_Msk(idx)));
  68. }
  69. void wm_sasc_enable_region(SASC_Type *block, uint32_t idx)
  70. {
  71. block->CR = _R1_Pos(1, idx) | (block->CR & ~(_R1_Msk(idx)));
  72. }
  73. void wm_sasc_disable_region(SASC_Type *block, uint32_t idx)
  74. {
  75. block->CR = (block->CR & ~(_R1_Msk(idx)));
  76. }
  77. void set_region_protect(uint32_t base_addr, uint32_t idx, sasc_region_size_e size, sasc_region_attr_t *attr)
  78. {
  79. SASC_Type* block = get_block_from_addr(base_addr);
  80. TEST_DEBUG("base_addr %x idx %d size 0x%x ap %d cd %d car %d\n", base_addr, idx, size, attr->ap, attr->cd, attr->car);
  81. if(base_addr >= 0x8000000 && base_addr < 0x10000000)
  82. {
  83. base_addr &= 0x1FFFFFF;
  84. }
  85. else if(base_addr < 0x20028000 && base_addr >= 0x20000000)
  86. {
  87. base_addr &= 0x3FFFF;
  88. }
  89. else if(base_addr < 0x20048000 && base_addr >= 0x20028000)
  90. {
  91. base_addr &= 0x7FFFF;
  92. }
  93. wm_sasc_config_region(block, idx, base_addr, size, attr, 1);
  94. }
  95. /**
  96. *******************************************************
  97. * TEST CODE IS BELOW
  98. *******************************************************
  99. */
  100. void access_region(uint32_t base_addr, sasc_region_size_e size, sasc_region_attr_t *attr, int pos)
  101. {
  102. char dest[4] = {0xa5, 0xa5, 0xa5, 0xa5};
  103. uint32_t s = 1 << (size - 3);
  104. TEST_DEBUG("base_addr %x size 0x%x\n", base_addr, s);
  105. switch(pos)
  106. {
  107. case 0:
  108. memcpy(dest, (char*)(base_addr + s), sizeof(dest));
  109. TEST_DEBUG("Behind addr %x size 0x%x can read\n", base_addr + s, sizeof(dest));
  110. TEST_DEBUG("start to read addr %x size 0x%x\n", base_addr + s - sizeof(dest), sizeof(dest));
  111. memcpy(dest, (char*)(base_addr + s - sizeof(dest)), sizeof(dest));
  112. TEST_DEBUG("addr %x size 0x%x can read\n", base_addr + s - sizeof(dest), sizeof(dest));
  113. break;
  114. case 1:
  115. memcpy(dest, (char*)(base_addr - sizeof(dest)), sizeof(dest));
  116. TEST_DEBUG("Front addr %x size 0x%x can read\n", base_addr - sizeof(dest), sizeof(dest));
  117. TEST_DEBUG("start to read addr %x size 0x%x\n", base_addr, sizeof(dest));
  118. memcpy(dest, (char*)base_addr, sizeof(dest));
  119. TEST_DEBUG("base_addr %x size 0x%x can read\n", base_addr, sizeof(dest));
  120. break;
  121. case 2:
  122. memcpy((char*)(base_addr - sizeof(dest)), dest, sizeof(dest));
  123. TEST_DEBUG("Front addr %x size 0x%x can write\n", base_addr - sizeof(dest), sizeof(dest));
  124. TEST_DEBUG("start to write addr %x size 0x%x\n", base_addr, sizeof(dest));
  125. memcpy((char*)base_addr, dest, sizeof(dest));
  126. TEST_DEBUG("base_addr %x size 0x%x can write\n", base_addr, sizeof(dest));
  127. break;
  128. default:
  129. memcpy((char*)(base_addr + s), dest, sizeof(dest));
  130. TEST_DEBUG("Behind addr %x size 0x%x can write\n", base_addr + s, sizeof(dest));
  131. TEST_DEBUG("start to write addr %x size 0x%x\n", base_addr + s - sizeof(dest), sizeof(dest));
  132. memcpy((char*)(base_addr + s - sizeof(dest)), dest, sizeof(dest));
  133. TEST_DEBUG("addr %x size 0x%x can write\n", base_addr + s - sizeof(dest), sizeof(dest));
  134. break;
  135. }
  136. dumpBuffer("dest", dest, sizeof(dest));
  137. }
  138. int sasc_region_security_test(int num)
  139. {
  140. sasc_region_attr_t attr;
  141. attr.ap = SASC_AP_DENYALL;
  142. attr.cd = SASC_CD_DA_OF;
  143. attr.car = SASC_SE_SUPER;
  144. set_region_protect(0x08010000, 0, SASC_REGION_SIZE_64KB, &attr);
  145. set_region_protect(0x20010000, 1, SASC_REGION_SIZE_16KB, &attr);
  146. set_region_protect(0x20030000, 2, SASC_REGION_SIZE_32KB, &attr);
  147. // SASC_B2->REGION[0] = SASC_REGION_SIZE_32KB | (0x8000 << 6);
  148. switch_to_ree();
  149. switch(num)
  150. {
  151. case 0:
  152. access_region(0x20010000, SASC_REGION_SIZE_16KB, &attr, 0);
  153. break;
  154. case 1:
  155. access_region(0x20010000, SASC_REGION_SIZE_16KB, &attr, 1);
  156. break;
  157. case 2:
  158. access_region(0x20010000, SASC_REGION_SIZE_16KB, &attr, 2);
  159. break;
  160. case 3:
  161. access_region(0x20010000, SASC_REGION_SIZE_16KB, &attr, 3);
  162. break;
  163. case 4:
  164. access_region(0x20030000, SASC_REGION_SIZE_32KB, &attr, 0);
  165. break;
  166. case 5:
  167. access_region(0x20030000, SASC_REGION_SIZE_32KB, &attr, 1);
  168. break;
  169. case 6:
  170. access_region(0x20030000, SASC_REGION_SIZE_32KB, &attr, 2);
  171. break;
  172. case 7:
  173. access_region(0x20030000, SASC_REGION_SIZE_32KB, &attr, 3);
  174. break;
  175. case 8:
  176. access_region(0x08010000, SASC_REGION_SIZE_64KB, &attr, 0);
  177. break;
  178. case 9:
  179. access_region(0x08010000, SASC_REGION_SIZE_64KB, &attr, 1);
  180. break;
  181. }
  182. return -1;
  183. }