From 3e4bb4cee4f77eb34e5e4fbb8d98224f432683a7 Mon Sep 17 00:00:00 2001 From: thead_admin Date: Sun, 24 Dec 2023 02:32:36 +0000 Subject: [PATCH] Linux_SDK_V1.4.2 Signed-off-by: thead_admin --- include/sbi/sbi_platform.h | 4 ++ platform/generic/platform.c | 112 +++++++++++++++++++++++++++++++++++- 2 files changed, 115 insertions(+), 1 deletion(-) diff --git a/include/sbi/sbi_platform.h b/include/sbi/sbi_platform.h index f8074d2..fb0f7f2 100644 --- a/include/sbi/sbi_platform.h +++ b/include/sbi/sbi_platform.h @@ -45,6 +45,10 @@ #include #include +#define SBI_EXT_VENDOR_SMC (SBI_EXT_VENDOR_START + 0) +#define SBI_EXT_VENDOR_PMU (SBI_EXT_VENDOR_START + 1) +#define SBI_EXT_VENDOR_PMP (SBI_EXT_VENDOR_START + 2) + struct sbi_domain_memregion; struct sbi_trap_info; struct sbi_trap_regs; diff --git a/platform/generic/platform.c b/platform/generic/platform.c index 60b72a3..eb94c72 100644 --- a/platform/generic/platform.c +++ b/platform/generic/platform.c @@ -21,6 +21,21 @@ #include #include #include +#include +#include + +#define PMP_BASE_ADDR 0xffdc020000UL +#define PMP_SIZE_PER_CORE 0x4000UL +#define TCM0_START_ADDR 0xffe0180000UL +#define TCM0_END_ADDR 0xffe01c0000UL +#define TCM1_START_ADDR 0xffe01c0000UL +#define TCM1_END_ADDR 0xffe0200000UL +#define RESERVED_START_ADDR 0xffe0200000UL +#define RESERVED_END_ADDR 0xffe1000000UL +#define PMP_ENTRY_BASE_ADDR 0x100UL +#define PMP_ENTRY_START_ADDR(n) (PMP_BASE_ADDR + PMP_ENTRY_BASE_ADDR + (n * 8)) +#define PMP_ENTRY_END_ADDR(n) (PMP_ENTRY_START_ADDR(n) + 4) +#define PMP_ENTRY_CFG_ADDR(n) (PMP_BASE_ADDR + ((n / 4) * 4)) extern const struct platform_override sifive_fu540; extern const struct platform_override light; @@ -330,14 +345,109 @@ static void sbi_thead_pmu_set(unsigned long type, unsigned long idx, unsigned lo } } +static void sbi_thead_reserved_pmp_set(void) +{ + unsigned int num, reg_val; + + for (num = 0; num < 4; num++) { + /* pmp entry 28 for reserved memory */ + writel(RESERVED_START_ADDR >> 12, (void *)(PMP_ENTRY_START_ADDR(28) + num*PMP_SIZE_PER_CORE)); + writel(RESERVED_END_ADDR >> 12, (void *)(PMP_ENTRY_END_ADDR(28) + num*PMP_SIZE_PER_CORE)); + + /* pmp entry 28 config */ + reg_val = readl((void *)(PMP_ENTRY_CFG_ADDR(28) + num*PMP_SIZE_PER_CORE)); + reg_val = (reg_val & 0xffffff00) | 0x040; + writel(reg_val, (void *)((PMP_ENTRY_CFG_ADDR(28) + num*PMP_SIZE_PER_CORE))); + } + + sync_is(); +} + +static void sbi_thead_tcm0_pmp_set(unsigned long auth) +{ + sbi_printf("%s: auth:%lx \n", __func__, auth); + unsigned int num, reg_val; + + reg_val = readl((void *)PMP_ENTRY_START_ADDR(26)); + + if (reg_val != TCM0_START_ADDR >> 12) + for(num = 0; num < 4; num++) { + /* pmp entry 26 for dsp tcm0 */ + writel(TCM0_START_ADDR >> 12, (void *)(PMP_ENTRY_START_ADDR(26) + num*PMP_SIZE_PER_CORE)); + writel(TCM0_END_ADDR >> 12, (void *)(PMP_ENTRY_END_ADDR(26) + num*PMP_SIZE_PER_CORE)); + } + + for(num = 0; num < 4; num++) { + /* pmp entry 26 config */ + reg_val = readl((void *)(PMP_ENTRY_CFG_ADDR(26) + num*PMP_SIZE_PER_CORE)); + reg_val = (reg_val & 0xff00ffff) | (auth << 16); + writel(reg_val, (void *)(PMP_ENTRY_CFG_ADDR(26) + num*PMP_SIZE_PER_CORE)); + } + + sync_is(); +} + +static void sbi_thead_tcm1_pmp_set(unsigned long auth) +{ + sbi_printf("%s: auth:%lx \n", __func__, auth); + unsigned int num, reg_val; + + reg_val = readl((void *)PMP_ENTRY_START_ADDR(27)); + if (reg_val != TCM1_START_ADDR >> 12) + for (num = 0; num < 4; num++) { + /* pmp entry 27 for dsp tcm1 */ + writel(TCM1_START_ADDR >> 12, (void *)(PMP_ENTRY_START_ADDR(27) + num*PMP_SIZE_PER_CORE)); + writel(TCM1_END_ADDR >> 12, (void *)(PMP_ENTRY_END_ADDR(27) + num*PMP_SIZE_PER_CORE)); + } + + for (num = 0; num < 4; num++) { + /* pmp entry 27 config */ + reg_val = readl((void *)(PMP_ENTRY_CFG_ADDR(27) + num*PMP_SIZE_PER_CORE)); + reg_val = (reg_val & 0x00ffffff) | (auth << 24); + writel(reg_val, (void *)(PMP_ENTRY_CFG_ADDR(27) + num*PMP_SIZE_PER_CORE)); + } + + sync_is(); +} + +static void sbi_thead_pmp_set(unsigned long idx, unsigned long auth) +{ + unsigned int reg_val; + + if (idx !=0 && idx != 1) + return; + + /* read pmp entry 28 */ + reg_val = readl((void *)PMP_ENTRY_START_ADDR(28)); + + if (reg_val != RESERVED_START_ADDR >> 12) + sbi_thead_reserved_pmp_set(); + + switch (idx) { + case 0: + sbi_thead_tcm0_pmp_set(auth); + break; + case 1: + sbi_thead_tcm1_pmp_set(auth); + break; + default: + break; + } +} + static int thead_vendor_ext_provider(long extid, long funcid, const struct sbi_trap_regs *regs, unsigned long *out_value, struct sbi_trap_info *out_trap) { + sbi_printf("%s: extid:%lx funcid:%lx \n", __func__, + extid, funcid); switch (extid) { - case 0x09000001: + case SBI_EXT_VENDOR_PMU: sbi_thead_pmu_set(regs->a0, regs->a1, regs->a2); break; + case SBI_EXT_VENDOR_PMP: + sbi_thead_pmp_set(funcid, regs->a0); + break; default: while(1); }