/* * Copyright (c) Hisilicon Technologies Co., Ltd. 2021-2021. All rights reserved. * Description: Entries for drviers and applications * Author: Hisilicon * Create: 2021-04-26 */ #include "soc_osal.h" #include "td_type.h" #include "arch/pmp.h" #include "board.h" #include "drv_dmcu_sys.h" #include "drv_log.h" #include "dmcu_pmp.h" #include "dmcu_dbg.h" #include "dmcu_hal.h" static PMP_ENTRY_INFO g_dmcu_pmp_entry[] = { { /* LiteOS Code READ/EXEC/NON-WRITE NOMMU SEC CACHEABLE (part 1) */ .ucNumber = DMCU_REGION_LOS_CODE_START, .bLocked = TRUE, .accPermission.readAcc = E_MEM_RD_ACC_RD, .accPermission.writeAcc = E_MEM_WR_ACC_NON_WR, .accPermission.excuteAcc = E_MEM_EX_ACC_EX, .ucAddressMatch = PMP_RGN_ADDR_MATCH_OFF, .uwBaseAddress = 0, .uwRegionSize = 0, .memAttr = MEM_ATTR_WB_RW_ALLOC, .seCtl = SEC_CONTRLO_SECURE_NOMMU, }, { /* LiteOS Code READ/EXEC/NON-WRITE NOMMU SEC CACHEABLE (part 2) */ .ucNumber = DMCU_REGION_LOS_CODE_END, .bLocked = TRUE, .accPermission.readAcc = E_MEM_RD_ACC_RD, .accPermission.writeAcc = E_MEM_WR_ACC_NON_WR, .accPermission.excuteAcc = E_MEM_EX_ACC_EX, .ucAddressMatch = PMP_RGN_ADDR_MATCH_TOR, .uwBaseAddress = 0, .uwRegionSize = 0, .memAttr = MEM_ATTR_WB_RW_ALLOC, .seCtl = SEC_CONTRLO_SECURE_NOMMU, }, { /* LiteOS Data READ/EXEC/WRITE NOMMU SEC CACHEABLE */ .ucNumber = DMCU_REGION_LOS_DATA_END, .bLocked = TRUE, .accPermission.readAcc = E_MEM_RD_ACC_RD, .accPermission.writeAcc = E_MEM_WR_ACC_WR, .accPermission.excuteAcc = E_MEM_EX_ACC_NON_EX, .ucAddressMatch = PMP_RGN_ADDR_MATCH_TOR, .uwBaseAddress = 0, .uwRegionSize = 0, .memAttr = MEM_ATTR_WB_RW_ALLOC, .seCtl = SEC_CONTRLO_SECURE_NOMMU, }, { /* NONSEC PAGE TABLE READ/EXEC/WRITE NOMMU NONSEC NONCACHEABLE */ .ucNumber = DMCU_REGION_IOMMU_PT_NS, .bLocked = TRUE, .accPermission.readAcc = E_MEM_RD_ACC_RD, .accPermission.writeAcc = E_MEM_WR_ACC_WR, .accPermission.excuteAcc = E_MEM_EX_ACC_NON_EX, .ucAddressMatch = PMP_RGN_ADDR_MATCH_NAPOT, .uwBaseAddress = (td_u32)DMCU_NS_PT_BASEADDR, .uwRegionSize = 1 << 22, /* 1 << 22 is PMP_REGION_SIZE_4MB */ .memAttr = MEM_ATTR_NORM_NON_CA_BUF, .seCtl = SEC_CONTRLO_NOSECURE_NOMMU, }, { /* ITCM READ/EXEC/WRITE NOMMU SEC NONCACHEABLE */ .ucNumber = DMCU_REGION_ITCM, .bLocked = FALSE, /* for resume copy itcm */ .accPermission.readAcc = E_MEM_RD_ACC_RD, .accPermission.writeAcc = E_MEM_WR_ACC_NON_WR, .accPermission.excuteAcc = E_MEM_EX_ACC_EX, .ucAddressMatch = PMP_RGN_ADDR_MATCH_NAPOT, .uwBaseAddress = (td_u32)DMCU_ITCM_BASE_ADDR, .uwRegionSize = 1 << 15, /* 1 << 15 is PMP_REGION_SIZE_32KB */ .memAttr = MEM_ATTR_NORM_NON_CA_BUF, .seCtl = SEC_CONTRLO_SECURE_NOMMU, }, { /* DMCU_LOG NOMMU NONCACHEABLE */ .ucNumber = DMCU_REGION_LOG, .bLocked = TRUE, .accPermission.readAcc = E_MEM_RD_ACC_RD, .accPermission.writeAcc = E_MEM_WR_ACC_WR, .accPermission.excuteAcc = E_MEM_EX_ACC_EX, .ucAddressMatch = PMP_RGN_ADDR_MATCH_NAPOT, .uwBaseAddress = (td_u32)DMCU_PROC_START_ADDR, .uwRegionSize = 1 << 20, /* 1 << 20 is PMP_REGION_SIZE_1MB */ .memAttr = MEM_ATTR_NORM_NON_CA_BUF, .seCtl = SEC_CONTRLO_NOSECURE_NOMMU, }, { /* DMCU_IPCM NOMMU NONCACHEABLE */ .ucNumber = DMCU_REGION_IPCM, .bLocked = TRUE, .accPermission.readAcc = E_MEM_RD_ACC_RD, .accPermission.writeAcc = E_MEM_WR_ACC_WR, .accPermission.excuteAcc = E_MEM_EX_ACC_EX, .ucAddressMatch = PMP_RGN_ADDR_MATCH_NAPOT, .uwBaseAddress = (td_u32)DMCU_IPCM_NOSEC_ADDR, .uwRegionSize = 1 << 20, /* 1 << 20 is PMP_REGION_SIZE_1MB */ .memAttr = MEM_ATTR_NORM_NON_CA_BUF, .seCtl = SEC_CONTRLO_NOSECURE_NOMMU, }, }; void dmcu_pmp_region_init(void) { PMP_ENTRY_INFO *pmp_entry; pmp_entry = &g_dmcu_pmp_entry[DMCU_REGION_LOS_CODE_START]; pmp_entry->uwBaseAddress = DMCU_LOS_CODE_START; pmp_entry->uwRegionSize = 0; pmp_entry = &g_dmcu_pmp_entry[DMCU_REGION_LOS_CODE_END]; pmp_entry->uwBaseAddress = DMCU_LOS_CODE_START + DMCU_LOS_CODE_SIZE; pmp_entry->uwRegionSize = 0; pmp_entry = &g_dmcu_pmp_entry[DMCU_REGION_LOS_DATA_END]; pmp_entry->uwBaseAddress = DMCU_LOS_DATA_START + DMCU_LOS_DATA_SIZE; pmp_entry->uwRegionSize = 0; return; } td_s32 dmcu_pmp_region_config(void) { td_s32 i; td_u32 ret; bool error_occur = TD_FALSE; PMP_ENTRY_INFO *pmp_entry = NULL; for (i = 0; i < sizeof(g_dmcu_pmp_entry) / sizeof(g_dmcu_pmp_entry[0]); i++) { pmp_entry = &g_dmcu_pmp_entry[i]; printf("pmp[%d]: uwBaseAddress:0x%x, uwRegionSize:0x%x\n", i, pmp_entry->uwBaseAddress, pmp_entry->uwRegionSize); ret = ArchProtectionRegionSet(pmp_entry); if (ret != TD_SUCCESS) { error_occur = TRUE; printf("set region failed 0x%x num %d\n", ret, pmp_entry->ucNumber); } } return (error_occur) ? TD_FAILURE : TD_SUCCESS; } td_void dmcu_itcm_resume(td_void) { td_u32 ret; PMP_ENTRY_INFO *pmp = TD_NULL; osal_printk("%s start\n", __func__); pmp = &g_dmcu_pmp_entry[DMCU_REGION_ITCM]; pmp->accPermission.writeAcc = E_MEM_WR_ACC_WR; ret = ArchProtectionRegionSet(pmp); if (ret != LOS_OK) { osal_printk("%s set wr err\n", __func__); return; } if (memcpy_s((td_void *)(&__itcm_text_start), ITCM_CODE_LEN, (const td_void *)(&__itcm_text_load_start), (td_uintptr_t)(&__itcm_size)) != EOK) { osal_printk("%s memcpy err\n", __func__); return; } pmp = &g_dmcu_pmp_entry[DMCU_REGION_ITCM]; pmp->accPermission.writeAcc = E_MEM_WR_ACC_NON_WR; ret = ArchProtectionRegionSet(pmp); if (ret != LOS_OK) { osal_printk("%s set non wr err\n", __func__); return; } osal_printk("%s end\n", __func__); return; } void dmcu_pmp_init(void) { mcu_dmcu_status *mcu_status = get_mcu_status(); mcu_status->u32 = 0; ArchProtectionUnitInit(DMCU_MIN_PMP_ADDR, DMCU_MAX_PMP_ADDR); dmcu_pmp_region_init(); dmcu_pmp_region_config(); mdc_log_init(); dmcu_hal_set_uart_pinmux(); mcu_status->bit.pmp_init = 1; return; }