379 lines
11 KiB
C
Raw Normal View History

2025-02-27 17:59:18 +08:00
/*
* Copyright (c) 2012-2021 Andes Technology Corporation
* All rights reserved.
*/
#if 0
#include <stdio.h>
#include "platform.h"
#include "pmp.h"
#include <os/os.h>
#define SYS_DELAY_TIME_10US (170UL)
/* bk7256 */
#define MEM_MAPPING_MAX 0xFFFFFFF0
#define ADDR_MAPPING_MAX 0x80000000
#define DTCM_END 0x20008000
#define SRAM_END 0x38080000
#define FLASH_END 0x00400000
/* PMP entry 0 : 0 ~ (_start), lock, TOR range, excutable, no writable, readable */
extern char _start;
/* PMP entry 1(code/RO data section) : (_start) ~ (_data_lmastart), lock, TOR range, excutable, no writable, readable */
extern char _data_lmastart;
/* PMP entry 2(FLASH) : (_data_lmastart) ~ (FLASH_END), lock, TOR range, no excutable, writable, readable */
/* PMP entry 3(null section) : (FLASH_END) ~ (_itcm_ema_start), lock, TOR range, no excutable, no writable, no readable */
extern char _itcm_ema_start;
/* PMP entry 4(itcm section) : (_itcm_ema_start) ~ (_dtcm_ema_start), lock, TOR range, excutable, no writable, readable */
extern char _dtcm_ema_start;
/* PMP entry 5(dtcm/sram section) : (_dtcm_ema_start) ~ (SRAM_END), lock, TOR range, no excutable, writable, readable */
/* PMP entry 6(max address section) : (SRAM_END) ~ (ADDR_MAPPING_MAX), lock, TOR range, no excutable, writable, readable */
#if (CONFIG_SYS_CPU0)
const pmp_config_t pmp_tor_config_table[] = {\
{ENTRY_PMPADDR0, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_ON, PMP_W_OFF, PMP_R_ON), (void*)(&_start + 4)}, \
{ENTRY_PMPADDR1, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_ON, PMP_W_OFF, PMP_R_ON), (void*)(&_data_lmastart + 4) }, \
{ENTRY_PMPADDR2, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_OFF, PMP_W_ON, PMP_R_ON), (void*)(FLASH_END + 4) }, \
{ENTRY_PMPADDR3, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_OFF, PMP_W_OFF, PMP_R_OFF), (void*)(&_itcm_ema_start + 4) }, \
{ENTRY_PMPADDR4, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_ON, PMP_W_OFF, PMP_R_ON), (void*)(&_dtcm_ema_start + 4) }, \
{ENTRY_PMPADDR5, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_OFF, PMP_W_ON, PMP_R_ON), (void*)(SRAM_END +4) }, \
{ENTRY_PMPADDR6, PMPCFG_ALXWR(PMP_A_TOR, PMP_L_ON, PMP_X_OFF, PMP_W_ON, PMP_R_ON), (void*)(ADDR_MAPPING_MAX+4) } \
};
#else
const pmp_config_t pmp_tor_config_table[] = {\
};
#endif //#if (CONFIG_SYS_CPU0)
extern void sys_delay_sync(uint32_t time_count );
void pmp_tor_config(char entry, void* address, char pmp_cfg)
{
long pmpcfg = pmp_cfg & 0xFF;
void * va = (void *)((((uint32)(address)+3)/4) * 4);
os_printf("pmp_tor_config[%d]: addr(0x%08x),TOR(0x%08x) cfg(0x%02x).\n", entry, va, TOR(va), pmpcfg);
switch (entry) {
case ENTRY_PMPADDR0:
write_csr(NDS_PMPADDR0, TOR(va));
break;
case ENTRY_PMPADDR1:
write_csr(NDS_PMPADDR1, TOR(va));
break;
case ENTRY_PMPADDR2:
write_csr(NDS_PMPADDR2, TOR(va));
break;
case ENTRY_PMPADDR3:
write_csr(NDS_PMPADDR3, TOR(va));
break;
case ENTRY_PMPADDR4:
write_csr(NDS_PMPADDR4, TOR(va));
break;
case ENTRY_PMPADDR5:
write_csr(NDS_PMPADDR5, TOR(va));
break;
case ENTRY_PMPADDR6:
write_csr(NDS_PMPADDR6, TOR(va));
break;
case ENTRY_PMPADDR7:
write_csr(NDS_PMPADDR7, TOR(va));
break;
case ENTRY_PMPADDR8:
write_csr(NDS_PMPADDR8, TOR(va));
break;
case ENTRY_PMPADDR9:
write_csr(NDS_PMPADDR9, TOR(va));
break;
case ENTRY_PMPADDR10:
write_csr(NDS_PMPADDR10, TOR(va));
break;
case ENTRY_PMPADDR11:
write_csr(NDS_PMPADDR11, TOR(va));
break;
case ENTRY_PMPADDR12:
write_csr(NDS_PMPADDR12, TOR(va));
break;
case ENTRY_PMPADDR13:
write_csr(NDS_PMPADDR13, TOR(va));
break;
case ENTRY_PMPADDR14:
write_csr(NDS_PMPADDR14, TOR(va));
break;
case ENTRY_PMPADDR15:
write_csr(NDS_PMPADDR15, TOR(va));
break;
}
#if __riscv_xlen == 64
switch (entry >> 3){
case ENTRY_PMPCFG0:
write_csr(NDS_PMPCFG0, ((read_csr(NDS_PMPCFG0) & (~(0xFFLL << ((long)(entry%8) << 3)))) | (((long)pmpcfg) << ((long)(entry%8) << 3))));
break;
case ENTRY_PMPCFG1:
write_csr(NDS_PMPCFG2, ((read_csr(NDS_PMPCFG2) & (~(0xFFLL << ((long)(entry%8) << 3)))) | (((long)pmpcfg) << ((long)(entry%8) << 3))));
break;
}
#else
switch (entry >> 2) {
case ENTRY_PMPCFG0:
write_csr(NDS_PMPCFG0, ((read_csr(NDS_PMPCFG0) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3))));
break;
case ENTRY_PMPCFG1:
write_csr(NDS_PMPCFG1, ((read_csr(NDS_PMPCFG1) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3))));
break;
case ENTRY_PMPCFG2:
write_csr(NDS_PMPCFG2, ((read_csr(NDS_PMPCFG2) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3))));
break;
case ENTRY_PMPCFG3:
write_csr(NDS_PMPCFG3, ((read_csr(NDS_PMPCFG3) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3))));
break;
}
#endif
}
void pmp_napot_config(char entry, void* va, unsigned long size, char pmpcfg)
{
switch (entry) {
case ENTRY_PMPADDR0:
write_csr(NDS_PMPADDR0, NAPOT(va, size));
break;
case ENTRY_PMPADDR1:
write_csr(NDS_PMPADDR1, NAPOT(va, size));
break;
case ENTRY_PMPADDR2:
write_csr(NDS_PMPADDR2, NAPOT(va, size));
break;
case ENTRY_PMPADDR3:
write_csr(NDS_PMPADDR3, NAPOT(va, size));
break;
case ENTRY_PMPADDR4:
write_csr(NDS_PMPADDR4, NAPOT(va, size));
break;
case ENTRY_PMPADDR5:
write_csr(NDS_PMPADDR5, NAPOT(va, size));
break;
case ENTRY_PMPADDR6:
write_csr(NDS_PMPADDR6, NAPOT(va, size));
break;
case ENTRY_PMPADDR7:
write_csr(NDS_PMPADDR7, NAPOT(va, size));
break;
case ENTRY_PMPADDR8:
write_csr(NDS_PMPADDR8, NAPOT(va, size));
break;
case ENTRY_PMPADDR9:
write_csr(NDS_PMPADDR9, NAPOT(va, size));
break;
case ENTRY_PMPADDR10:
write_csr(NDS_PMPADDR10, NAPOT(va, size));
break;
case ENTRY_PMPADDR11:
write_csr(NDS_PMPADDR11, NAPOT(va, size));
break;
case ENTRY_PMPADDR12:
write_csr(NDS_PMPADDR12, NAPOT(va, size));
break;
case ENTRY_PMPADDR13:
write_csr(NDS_PMPADDR13, NAPOT(va, size));
break;
case ENTRY_PMPADDR14:
write_csr(NDS_PMPADDR14, NAPOT(va, size));
break;
case ENTRY_PMPADDR15:
write_csr(NDS_PMPADDR15, NAPOT(va, size));
break;
}
#if __riscv_xlen == 64
switch (entry >> 3){
case ENTRY_PMPCFG0:
write_csr(NDS_PMPCFG0, ((read_csr(NDS_PMPCFG0) & (~(0xFFLL << ((long)(entry%8) << 3)))) | (((long)pmpcfg) << ((long)(entry%8) << 3))));
break;
case ENTRY_PMPCFG1:
write_csr(NDS_PMPCFG2, ((read_csr(NDS_PMPCFG2) & (~(0xFFLL << ((long)(entry%8) << 3)))) | (((long)pmpcfg) << ((long)(entry%8) << 3))));
break;
}
#else
switch (entry >> 2) {
case ENTRY_PMPCFG0:
write_csr(NDS_PMPCFG0, ((read_csr(NDS_PMPCFG0) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3))));
break;
case ENTRY_PMPCFG1:
write_csr(NDS_PMPCFG1, ((read_csr(NDS_PMPCFG1) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3))));
break;
case ENTRY_PMPCFG2:
write_csr(NDS_PMPCFG2, ((read_csr(NDS_PMPCFG2) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3))));
break;
case ENTRY_PMPCFG3:
write_csr(NDS_PMPCFG3, ((read_csr(NDS_PMPCFG3) & (~((0xFF) << ((entry%4) << 3)))) | (((long)pmpcfg) << ((entry%4) << 3))));
break;
}
#endif
}
void init_pmp_config()
{
int i = 0;
int config_count = 0;
/*
* Check whether the CPU configured with PMP feature.
* Write 0x3 to the pmpcfg0 register, and read it back
* to check the number of PMP entries.
*/
write_csr(NDS_PMPCFG0, 0x3);
if (!read_csr(NDS_PMPCFG0)) {
os_printf("PMP entries is 0, CPU does NOT support PMP.\n");
while(1);
}
/* Disable global interrupt but allow exception */
clear_csr(NDS_MSTATUS, MSTATUS_MIE);
#if USE_NAPOT
os_printf("PMP uses NAPOT scheme!.\n");
#else /* USE_TOR */
os_printf("PMP uses TOR scheme!.\n");
config_count = sizeof(pmp_tor_config_table)/sizeof(pmp_config_t);
os_printf("PMP config count(%d).\n", config_count);
for (i = 0; i < config_count; i++)
{
pmp_tor_config(pmp_tor_config_table[i].pmp_entry,
pmp_tor_config_table[i].pmp_addr,
pmp_tor_config_table[i].pmp_config);
//sys_delay_sync(SYS_DELAY_TIME_10US);
}
#endif
}
void show_pmp_config()
{
os_printf("==========PMP config info===============\r\n");
int i = 0;
int config_count = 0;
long pmp_config0 = read_csr(NDS_PMPCFG0);
if (!pmp_config0) {
os_printf("PMP entries is 0, CPU does NOT support PMP.\n");
}
#if USE_NAPOT
os_printf("PMP uses NAPOT scheme!.\n");
#else /* USE_TOR */
os_printf("PMP uses TOR scheme!.\n");
config_count = sizeof(pmp_tor_config_table)/sizeof(pmp_config_t);
os_printf("PMP user config count(%d).\n", config_count);
for (i = 0; i < config_count; i++)
{
os_printf("PMP config[%d], 0x%08x, 0x%0x.\r\n", i,
(void *)pmp_tor_config_table[i].pmp_addr,
pmp_tor_config_table[i].pmp_config);
}
#endif
os_printf("==========PMP actural config:\r\n");
os_printf("==========NDS_PMPCFG0: 0x%08x.\r\n", pmp_config0);
os_printf("==========NDS_PMPCFG1: 0x%08x.\r\n", read_csr(NDS_PMPCFG1));
os_printf("==========NDS_PMPADDR0: 0x%08x.\r\n", read_csr(NDS_PMPADDR0));
os_printf("==========NDS_PMPADDR1: 0x%08x.\r\n", read_csr(NDS_PMPADDR1));
os_printf("==========NDS_PMPADDR2: 0x%08x.\r\n", read_csr(NDS_PMPADDR2));
os_printf("==========NDS_PMPADDR3: 0x%08x.\r\n", read_csr(NDS_PMPADDR3));
os_printf("==========NDS_PMPADDR4: 0x%08x.\r\n", read_csr(NDS_PMPADDR4));
os_printf("==========NDS_PMPADDR5: 0x%08x.\r\n", read_csr(NDS_PMPADDR5));
os_printf("==========NDS_PMPADDR6: 0x%08x.\r\n", read_csr(NDS_PMPADDR6));
os_printf("==========NDS_PMPADDR7: 0x%08x.\r\n", read_csr(NDS_PMPADDR7));
}
#else
void show_pmp_config()
{
}
#include "sdkconfig.h"
#include "mon_call.h"
extern char _sram_start;
extern char _sram_end;
extern char _swap_start;
void init_u_mode_pmp_config()
{
#define SRAM_START_ADDR 0x30000000
#define SRAM_END_ADDR 0X38080000
#if CONFIG_DUAL_CORE // #if config_multi_core
// #if CONFIG_MAILBOX // #if config_multi_core
u8 free_cfg = 0;
mon_get_free_pmp_cfg(&free_cfg);
if(free_cfg == 0)
return;
/* there codes are designed for simple configuration case as illustrated below */
/* for more complex cases, these codes should be modified to suite the config. */
/****************************************************/
/* SRAM */
/* |--------------------|--------------|----------| */
/* |------- CPU0 -------|----- CPU1 ---|-- SWAP --| */
/* |------- CPU1 -------|----- CPU0 ---|-- SWAP --| */
/****************************************************/
u32 start_addr, size, tmp;
u8 attr = PMP_R_ON;
#if CONFIG_SYS_CPU0
attr = PMP_R_ON; // used for CPU0 dump.
#else
attr = 0;
#endif
start_addr = (u32)&_sram_start;
tmp = start_addr & (~0x08000000);
if(tmp > SRAM_START_ADDR)
{
size = start_addr - SRAM_START_ADDR;
mon_pmp_cfg(SRAM_START_ADDR, size, attr);
}
else if(tmp == SRAM_START_ADDR)
{
start_addr = (u32)&_sram_end; // _sram_end is aligned with 16 bytes set in SAG file.
size = (u32)&_swap_start - start_addr;
mon_pmp_cfg(start_addr, size, attr);
}
#endif
}
#endif