mirror of
https://github.com/riscv-software-src/opensbi.git
synced 2025-08-24 15:31:22 +01:00

This patch adds unspecified permission flags for the PLICSW region and updates the permission of the PLMT region. With this update, both regions will become M-mode only read/write regions in the root domain. Domain0 Region00: 0x00000000f0300000-0x00000000f0300fff M: (I,R,W) S/U: (R,W) Domain0 Region01: 0x0000000000040000-0x000000000005ffff M: (R,W) S/U: () Domain0 Region02: 0x0000000000000000-0x000000000003ffff M: (R,X) S/U: () > Domain0 Region03: 0x00000000e6000000-0x00000000e60fffff M: (I,R,W) S/U: () > Domain0 Region04: 0x00000000e6400000-0x00000000e67fffff M: (I,R,W) S/U: () Domain0 Region05: 0x0000000000000000-0xffffffffffffffff M: () S/U: (R,W,X) The PMP rules of AE350-AX65 (single-core) w/ Smepmp: p/x $pmpcfg0 $1 = {0x1f9b9b9d9b1e00, pmp0cfg = {0x0}, L--AAXWR pmp1cfg = {0x1e} (00011110), pmpaddr1: 0xf0300000 ~ 0xf0300fff (UART1) pmp2cfg = {0x9b} (10011011), pmpaddr2: 0x40000 ~ 0x5ffff pmp3cfg = {0x9d} (10011101), pmpaddr3: 0x0 ~ 0x3ffff pmp4cfg = {0x9b} (10011011), pmpaddr4: 0xe6000000 ~ 0xe60fffff (PLMT) pmp5cfg = {0x9b} (10011011), pmpaddr5: 0xe6400000 ~ 0xe67fffff (PLICSW) pmp6cfg = {0x1f} (00011111), pmpaddr6: 0x0 ~ 0xffffffffff pmp7cfg = {0x0 }} The PMP rules of AE350-AX45MP (qual-core) w/o Smepmp: p/x $pmpcfg0 $1 = {0x1f181818181b, L--AAXWR pmp0cfg = {0x1b}, (00011011), pmpaddr0: 0xf0300000 ~ 0xf0300fff (UART1) pmp1cfg = {0x18}, (00011000), pmpaddr1: 0x40000 ~ 0x5ffff pmp2cfg = {0x18}, (00011000), pmpaddr2: 0x0 ~ 0x3ffff pmp3cfg = {0x18}, (00011000), pmpaddr3: 0xe6000000 ~ 0xe60fffff (PLMT) pmp4cfg = {0x18}, (00011000), pmpaddr4: 0xe6400000 ~ 0xe67fffff (PLICSW) pmp5cfg = {0x1f}, (00011111), pmpaddr5: 0x0 ~ 0x1ffffffff pmp6cfg = {0x0 }} Note that starting from this patch, we restrict the S/U-mode read permission to the PLMT region, since we should read the TIME CSR in a lower privilege mode. Signed-off-by: Yu Chien Peter Lin <peterlin@andestech.com> Reviewed-by: Anup Patel <anup@brainfault.org>
108 lines
2.2 KiB
C
108 lines
2.2 KiB
C
/*
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
|
*
|
|
* Copyright (c) 2022 Andes Technology Corporation
|
|
*
|
|
* Authors:
|
|
* Yu Chien Peter Lin <peterlin@andestech.com>
|
|
*/
|
|
|
|
#include <sbi/riscv_asm.h>
|
|
#include <sbi/riscv_io.h>
|
|
#include <sbi/sbi_domain.h>
|
|
#include <sbi/sbi_error.h>
|
|
#include <sbi/sbi_timer.h>
|
|
#include <sbi_utils/timer/andes_plmt.h>
|
|
|
|
struct plmt_data plmt;
|
|
|
|
static u64 plmt_timer_value(void)
|
|
{
|
|
#if __riscv_xlen == 64
|
|
return readq_relaxed(plmt.time_val);
|
|
#else
|
|
u32 lo, hi;
|
|
|
|
do {
|
|
hi = readl_relaxed((void *)plmt.time_val + 0x04);
|
|
lo = readl_relaxed(plmt.time_val);
|
|
} while (hi != readl_relaxed((void *)plmt.time_val + 0x04));
|
|
|
|
return ((u64)hi << 32) | (u64)lo;
|
|
#endif
|
|
}
|
|
|
|
static void plmt_timer_event_stop(void)
|
|
{
|
|
u32 target_hart = current_hartid();
|
|
|
|
if (plmt.hart_count <= target_hart)
|
|
ebreak();
|
|
|
|
/* Clear PLMT Time Compare */
|
|
#if __riscv_xlen == 64
|
|
writeq_relaxed(-1ULL, &plmt.time_cmp[target_hart]);
|
|
#else
|
|
writel_relaxed(-1UL, &plmt.time_cmp[target_hart]);
|
|
writel_relaxed(-1UL, (void *)(&plmt.time_cmp[target_hart]) + 0x04);
|
|
#endif
|
|
}
|
|
|
|
static void plmt_timer_event_start(u64 next_event)
|
|
{
|
|
u32 target_hart = current_hartid();
|
|
|
|
if (plmt.hart_count <= target_hart)
|
|
ebreak();
|
|
|
|
/* Program PLMT Time Compare */
|
|
#if __riscv_xlen == 64
|
|
writeq_relaxed(next_event, &plmt.time_cmp[target_hart]);
|
|
#else
|
|
u32 mask = -1UL;
|
|
|
|
writel_relaxed(next_event & mask, &plmt.time_cmp[target_hart]);
|
|
writel_relaxed(next_event >> 32,
|
|
(void *)(&plmt.time_cmp[target_hart]) + 0x04);
|
|
#endif
|
|
}
|
|
|
|
static struct sbi_timer_device plmt_timer = {
|
|
.name = "andes_plmt",
|
|
.timer_freq = DEFAULT_AE350_PLMT_FREQ,
|
|
.timer_value = plmt_timer_value,
|
|
.timer_event_start = plmt_timer_event_start,
|
|
.timer_event_stop = plmt_timer_event_stop
|
|
};
|
|
|
|
int plmt_cold_timer_init(struct plmt_data *plmt)
|
|
{
|
|
int rc;
|
|
|
|
/* Add PLMT region to the root domain */
|
|
rc = sbi_domain_root_add_memrange(
|
|
(unsigned long)plmt->time_val, plmt->size,
|
|
PLMT_REGION_ALIGN,
|
|
SBI_DOMAIN_MEMREGION_MMIO |
|
|
SBI_DOMAIN_MEMREGION_M_READABLE |
|
|
SBI_DOMAIN_MEMREGION_M_WRITABLE);
|
|
if (rc)
|
|
return rc;
|
|
|
|
plmt_timer.timer_freq = plmt->timer_freq;
|
|
|
|
sbi_timer_set_device(&plmt_timer);
|
|
|
|
return 0;
|
|
}
|
|
|
|
int plmt_warm_timer_init(void)
|
|
{
|
|
if (!plmt.time_val)
|
|
return SBI_ENODEV;
|
|
|
|
plmt_timer_event_stop();
|
|
|
|
return 0;
|
|
}
|