/**************************************************************************** * * Copyright(c) 2019 by Aerospace C.Power (Chongqing) Microelectronics. ALL RIGHTS RESERVED. * * This Information is proprietary to Aerospace C.Power (Chongqing) Microelectronics and MAY NOT * be copied by any method or incorporated into another program without * the express written consent of Aerospace C.Power. This Information or any portion * thereof remains the property of Aerospace C.Power. The Information contained herein * is believed to be accurate and Aerospace C.Power assumes no responsibility or * liability for its use in any way and conveys no license or title under * any patent or copyright and makes no representation or warranty that this * Information is free from patent or copyright infringement. * * ****************************************************************************/ #include "os_types.h" void IRAM_ATTR mmon_reset(uint32_t region) { uint32_t cfgmask = 0xffff << ((region % 2) * 16); if (0 == region || 1 == region) { asm volatile ("csrc pmpcfg0, %[mask]" ::[mask]"r"(cfgmask)); } else if (2 == region || 3 == region) { asm volatile ("csrc pmpcfg1, %[mask]" ::[mask]"r"(cfgmask)); } else if (4 == region || 5 == region) { asm volatile ("csrc pmpcfg2, %[mask]" ::[mask]"r"(cfgmask)); } else if (6 == region || 7 == region) { asm volatile ("csrc pmpcfg3, %[mask]" ::[mask]"r"(cfgmask)); } } /* attention: privilege, read=0 && write=1 is reserved */ void IRAM_ATTR mmon_set(uint32_t region, uint32_t start, uint32_t size, uint8_t privilege) { uint32_t protected_addr_start = start >> 2; uint32_t protected_addr_end = protected_addr_start + (size >> 2); /* x:[2] w:[1] R:[0] */ uint32_t cfg = (0x88 | (privilege & 0x7)) << 8; cfg <<= ((region % 2) * 16); uint32_t cfg_mask = 0xffff << ((region % 2) * 16); if (0 == region) { asm volatile ("csrw pmpaddr0, %[addr]" ::[addr] "r"(protected_addr_start)); asm volatile ("csrw pmpaddr1, %[addr]" ::[addr] "r"(protected_addr_end)); asm volatile ("csrc pmpcfg0, %[addr]" ::[addr] "r"(cfg_mask)); asm volatile ("csrs pmpcfg0, %[addr]" ::[addr] "r"(cfg)); } else if (1 == region) { asm volatile ("csrw pmpaddr2, %[addr]" ::[addr] "r"(protected_addr_start)); asm volatile ("csrw pmpaddr3, %[addr]" ::[addr] "r"(protected_addr_end)); asm volatile ("csrc pmpcfg0, %[addr]" ::[addr] "r"(cfg_mask)); asm volatile ("csrs pmpcfg0, %[addr]" ::[addr] "r"(cfg)); } else if (2 == region) { asm volatile ("csrw pmpaddr4, %[addr]" ::[addr] "r"(protected_addr_start)); asm volatile ("csrw pmpaddr5, %[addr]" ::[addr] "r"(protected_addr_end)); asm volatile ("csrc pmpcfg1, %[addr]" ::[addr] "r"(cfg_mask)); asm volatile ("csrs pmpcfg1, %[addr]" ::[addr] "r"(cfg)); } else if (3 == region) { asm volatile ("csrw pmpaddr6, %[addr]" ::[addr] "r"(protected_addr_start)); asm volatile ("csrw pmpaddr7, %[addr]" ::[addr] "r"(protected_addr_end)); asm volatile ("csrc pmpcfg1, %[addr]" ::[addr] "r"(cfg_mask)); asm volatile ("csrs pmpcfg1, %[addr]" ::[addr] "r"(cfg)); } else if (4 == region) { asm volatile ("csrw pmpaddr8, %[addr]" ::[addr] "r"(protected_addr_start)); asm volatile ("csrw pmpaddr9, %[addr]" ::[addr] "r"(protected_addr_end)); asm volatile ("csrc pmpcfg2, %[addr]" ::[addr] "r"(cfg_mask)); asm volatile ("csrs pmpcfg2, %[addr]" ::[addr] "r"(cfg)); } else if (5 == region) { asm volatile ("csrw pmpaddr10, %[addr]" ::[addr] "r"(protected_addr_start)); asm volatile ("csrw pmpaddr11, %[addr]" ::[addr] "r"(protected_addr_end)); asm volatile ("csrc pmpcfg2, %[addr]" ::[addr] "r"(cfg_mask)); asm volatile ("csrs pmpcfg2, %[addr]" ::[addr] "r"(cfg)); } else if (6 == region) { asm volatile ("csrw pmpaddr12, %[addr]" ::[addr] "r"(protected_addr_start)); asm volatile ("csrw pmpaddr13, %[addr]" ::[addr] "r"(protected_addr_end)); asm volatile ("csrc pmpcfg3, %[addr]" ::[addr] "r"(cfg_mask)); asm volatile ("csrs pmpcfg3, %[addr]" ::[addr] "r"(cfg)); } else if (7 == region) { asm volatile ("csrw pmpaddr14, %[addr]" ::[addr] "r"(protected_addr_start)); asm volatile ("csrw pmpaddr15, %[addr]" ::[addr] "r"(protected_addr_end)); asm volatile ("csrc pmpcfg3, %[addr]" ::[addr] "r"(cfg_mask)); asm volatile ("csrs pmpcfg3, %[addr]" ::[addr] "r"(cfg)); } } void IRAM_ATTR mmon_read(uint32_t region, uint32_t *cfg, uint32_t* addr) { uint32_t pmpaddr = 0, pmpcfg = 0; if (0 == region) { asm volatile ("csrr %0, pmpaddr0" : "=r"(pmpaddr)); asm volatile ("csrr %0, pmpcfg0" : "=r"(pmpcfg)); } else if (1 == region) { asm volatile ("csrr %0, pmpaddr1" : "=r"(pmpaddr)); asm volatile ("csrr %0, pmpcfg0" : "=r"(pmpcfg)); } else if (2 == region) { asm volatile ("csrr %0, pmpaddr2" : "=r"(pmpaddr)); asm volatile ("csrr %0, pmpcfg0" : "=r"(pmpcfg)); } else if (3 == region) { asm volatile ("csrr %0, pmpaddr3" : "=r"(pmpaddr)); asm volatile ("csrr %0, pmpcfg0" : "=r"(pmpcfg)); } else if (4 == region) { asm volatile ("csrr %0, pmpaddr4" : "=r"(pmpaddr)); asm volatile ("csrr %0, pmpcfg1" : "=r"(pmpcfg)); } else if (5 == region) { asm volatile ("csrr %0, pmpaddr5" : "=r"(pmpaddr)); asm volatile ("csrr %0, pmpcfg1" : "=r"(pmpcfg)); } else if (6 == region) { asm volatile ("csrr %0, pmpaddr6" : "=r"(pmpaddr)); asm volatile ("csrr %0, pmpcfg1" : "=r"(pmpcfg)); } else if (7 == region) { asm volatile ("csrr %0, pmpaddr7" : "=r"(pmpaddr)); asm volatile ("csrr %0, pmpcfg1" : "=r"(pmpcfg)); } else if (8 == region) { asm volatile ("csrr %0, pmpaddr8" : "=r"(pmpaddr)); asm volatile ("csrr %0, pmpcfg2" : "=r"(pmpcfg)); } else if (9 == region) { asm volatile ("csrr %0, pmpaddr9" : "=r"(pmpaddr)); asm volatile ("csrr %0, pmpcfg2" : "=r"(pmpcfg)); } else if (10 == region) { asm volatile ("csrr %0, pmpaddr10" : "=r"(pmpaddr)); asm volatile ("csrr %0, pmpcfg2" : "=r"(pmpcfg)); } else if (11 == region) { asm volatile ("csrr %0, pmpaddr11" : "=r"(pmpaddr)); asm volatile ("csrr %0, pmpcfg2" : "=r"(pmpcfg)); } else if (12 == region) { asm volatile ("csrr %0, pmpaddr12" : "=r"(pmpaddr)); asm volatile ("csrr %0, pmpcfg3" : "=r"(pmpcfg)); } else if (13 == region) { asm volatile ("csrr %0, pmpaddr13" : "=r"(pmpaddr)); asm volatile ("csrr %0, pmpcfg3" : "=r"(pmpcfg)); } else if (14 == region) { asm volatile ("csrr %0, pmpaddr14" : "=r"(pmpaddr)); asm volatile ("csrr %0, pmpcfg3" : "=r"(pmpcfg)); } else if (15 == region) { asm volatile ("csrr %0, pmpaddr15" : "=r"(pmpaddr)); asm volatile ("csrr %0, pmpcfg3" : "=r"(pmpcfg)); } *cfg = pmpcfg; *addr = pmpaddr; }