123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- /*
- * Copyright (c) 2019 Actions Semiconductor Co., Ltd
- *
- * SPDX-License-Identifier: Apache-2.0
- */
- /**
- * @file arm mpu
- */
- #include <kernel.h>
- #include <string.h>
- #include <arch/arm/aarch32/cortex_m/cmsis.h>
- #include <act_arm_mpu.h>
- #include <linker/linker-defs.h>
- #include <soc.h>
- /* Global MAIR configurations */
- #define MPU_MAIR_INDEX_NC 0
- #define MPU_RBAR_AP_Pos 1U
- /* Privileged Read Write, Unprivileged Read Write */
- #define P_RW_U_RW 0x1
- #define P_RW_U_RW_Msk (P_RW_U_RW << MPU_RBAR_AP_Pos)
- /* Privileged Read Only, Unprivileged Read Only */
- #define P_RO_U_RO 0x3
- #define P_RO_U_RO_Msk (P_RO_U_RO << MPU_RBAR_AP_Pos)
- #define MPU_RBAR_SH_Pos 3U
- #define INNER_SHAREABLE 0x3
- #define INNER_SHAREABLE_Msk (INNER_SHAREABLE << MPU_RBAR_SH_Pos)
- /* Attribute flag for not-allowing execution (eXecute Never) */
- #define NOT_EXEC 0x01
- static const char *mpu_attr_str[3] = { "NO", "RW", "RO"};
- /*MPU set, mem_base= must align to size , n >= 5 (32-2GB),*/
- void act_mpu_set(uint32_t chan, uint32_t mem_base, uint32_t size, uint32_t attr)
- {
- uint32_t mpu_base, mpu_end, mpu_attr;
- uint32_t num_region ;
- num_region = (MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos;
- if(chan >= num_region){
- printk("mpu set over max region:%d >= %d\n", chan, num_region);
- return;
- }
-
- if(!(MPU->CTRL & MPU_CTRL_ENABLE_Msk)){
- // Memory Attribute Indirection Register 0
- MPU->MAIR0 = ((0x44 & MPU_MAIR0_Attr0_Msk) | // Normal memory, Inner Non-cacheable, Outer Non-cacheable
- (0x44 << MPU_MAIR0_Attr1_Pos) | // Normal memory, Inner Non-cacheable, Outer Non-cacheable
- (0x44 << MPU_MAIR0_Attr2_Pos) | // Normal memory, Inner Non-cacheable, Outer Non-cacheable
- (0x44 << MPU_MAIR0_Attr3_Pos)); // Normal memory, Inner Non-cacheable, Outer Non-cacheable
- MPU->CTRL = MPU_CTRL_ENABLE_Msk | MPU_CTRL_PRIVDEFENA_Msk;
- }
- mpu_base = (mem_base+0x1f) & (~0x1f); // 32B align
- mpu_end = ((mem_base+size) & (~0x1f))-1;
- if(attr == MPU_ATTR_NO){
- mpu_attr = P_RO_U_RO_Msk | INNER_SHAREABLE_Msk | NOT_EXEC; //no exe, ro
- }else if(attr == MPU_ATTR_RW){
- mpu_attr = P_RW_U_RW_Msk | INNER_SHAREABLE_Msk ; // exe, rw
- } else {
- mpu_attr = P_RO_U_RO_Msk | INNER_SHAREABLE_Msk ; // exe, ro
- }
- printk("mpu %d(%d): 0x%x-0x%x, set=0x%x-0x%x,attr=%s\n", chan , num_region, mpu_base, mpu_end,
- mem_base, mem_base+size, mpu_attr_str[attr]);
- MPU->RNR = chan;
- // Base address
- MPU->RBAR = (mpu_base | mpu_attr);
- // Limit register
- MPU->RLAR = ((mpu_end & MPU_RLAR_LIMIT_Msk) | // Size
- (MPU_MAIR_INDEX_NC << MPU_RLAR_AttrIndx_Pos) | // AttrIndex - 0
- (0x1 << MPU_RLAR_EN_Pos)); // Enable - On
- }
- void act_mpu_unset(uint32_t chan)
- {
- uint32_t num_region ;
- num_region = (MPU->TYPE & MPU_TYPE_DREGION_Msk) >> MPU_TYPE_DREGION_Pos;
- if(chan >= num_region){
- printk("mpu unset over max region:%d >= %d\n", chan, num_region);
- return;
- }
- MPU->RNR = chan;
- MPU->RBAR = 0;
- MPU->RLAR = 0;
- printk("mpu %d unset\n", chan);
- }
- void arm_mpu_protect_init(void)
- {
- /* protect rom section */
- act_mpu_set(MPU_CHAN_ROM, 0x0, 0x10000, MPU_ATTR_RO);
- /* protect flash cache all address section */
- act_mpu_set(MPU_CHAN_CODE, (CONFIG_FLASH_BASE_ADDRESS + CONFIG_FLASH_LOAD_OFFSET), 0x1000000, MPU_ATTR_RO);
- #if defined(CONFIG_ARCH_HAS_RAMFUNC_SUPPORT)
- act_mpu_set(MPU_CHAN_RAMFUC, (uint32_t)&__ramfunc_start, (uint32_t)&__ramfunc_size, MPU_ATTR_RO);
- #endif /* CONFIG_ARCH_HAS_RAMFUNC_SUPPORT */
- }
- #define CPU_TRACE_RAM_ADDR 0x31000000
- #define CPU_TRACE_RAM_MAXLEN 1024
- static void trace_dump_str(unsigned int *buf, unsigned int len)
- {
- int i;
- for(i = 0; i < len/4; i++) {
- if((i&0x7)==0){
- printk("%08x:",CPU_TRACE_RAM_ADDR+i*4);
- }
- printk("%08x ", buf[i]);
- if( (i&0x7)==7 )
- printk("\n");
- }
- printk("\n");
- }
- void cpu_trace_enable(int enable)
- {
- if(enable){
- sys_write32(0 , 0xe0043004);
- memset((void*)CPU_TRACE_RAM_ADDR, 0, CPU_TRACE_RAM_MAXLEN);
- sys_write32(0 , 0xe0043000);
- sys_write32((1<<31)|0xf , 0xe0043004);
- }else{
- sys_write32(0 , 0xe0043004);
- }
- }
- static int act_mpu_init(const struct device *arg)
- {
- //unsigned int val = 0;
- ARG_UNUSED(arg);
- printk("arm mpu init\n");
- arm_mpu_protect_init();
- //soc_pstore_get(SOC_PSTORE_TAG_SYS_PANIC,&val);
- //if(val){
- printk("arm trace dump:\n");
- trace_dump_str((unsigned int *)CPU_TRACE_RAM_ADDR, CPU_TRACE_RAM_MAXLEN);
- //}
- cpu_trace_enable(1);
- return 0;
- }
- SYS_INIT(act_mpu_init, APPLICATION, 20);
|