Add support for the Andes SBI vendor extension (EXT_ID 0x0900031E)
with function IDs for PMA (Physical Memory Attribute) operations:
probe, set, and free.

These SBI calls allow S-mode software to configure memory attributes
through OpenSBI, which is needed for setting up noncached memory
regions on Andes RISC-V platforms.

Signed-off-by: Leo Yu-Chi Liang <[email protected]>
---
 arch/riscv/include/asm/sbi.h | 22 ++++++++++++++++
 arch/riscv/lib/sbi.c         | 51 ++++++++++++++++++++++++++++++++++++
 2 files changed, 73 insertions(+)

diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h
index 47124dbaac8..8642954d272 100644
--- a/arch/riscv/include/asm/sbi.h
+++ b/arch/riscv/include/asm/sbi.h
@@ -37,6 +37,7 @@ enum sbi_ext_id {
        SBI_EXT_FWFT = 0x46574654,
        SBI_EXT_DBTR = 0x44425452,
        SBI_EXT_MPXY = 0x4D505859,
+       SBI_EXT_ANDES = 0x0900031E,
 };
 
 enum sbi_ext_base_fid {
@@ -98,6 +99,23 @@ enum sbi_srst_reset_reason {
        SBI_SRST_RESET_REASON_SYS_FAILURE,
 };
 
+enum sbi_ext_andes_fid {
+       SBI_EXT_ANDES_FID0 = 0,
+       SBI_EXT_ANDES_IOCP_SW_WORKAROUND,
+       SBI_EXT_ANDES_PMA_PROBE,
+       SBI_EXT_ANDES_PMA_SET,
+       SBI_EXT_ANDES_PMA_FREE,
+};
+
+/* Andes PMA configuration flags */
+#define ANDES_PMACFG_ETYP_OFFSET       0
+#define ANDES_PMACFG_ETYP_NAPOT        (3 << ANDES_PMACFG_ETYP_OFFSET)
+#define ANDES_PMACFG_ETYP_OFF          (0 << ANDES_PMACFG_ETYP_OFFSET)
+#define ANDES_PMACFG_ETYP_MASK         (3 << ANDES_PMACFG_ETYP_OFFSET)
+#define ANDES_PMACFG_MTYP_OFFSET               2
+#define ANDES_PMACFG_MTYP_MEM_NON_CACHE_BUF    (3 << ANDES_PMACFG_MTYP_OFFSET)
+#define ANDES_PMACFG_MTYP_DEV_NOBUF            (0 << ANDES_PMACFG_MTYP_OFFSET)
+
 enum sbi_ext_dbcn_fid {
        SBI_EXT_DBCN_CONSOLE_WRITE = 0,
        SBI_EXT_DBCN_CONSOLE_READ,
@@ -176,4 +194,8 @@ int sbi_get_mimpid(long *mimpid);
 void sbi_srst_reset(unsigned long type, unsigned long reason);
 int sbi_dbcn_write_byte(unsigned char ch);
 
+int sbi_pma_probe(void);
+int sbi_pma_set(unsigned long pa, unsigned long size, unsigned long flags);
+int sbi_pma_free(unsigned long pa);
+
 #endif
diff --git a/arch/riscv/lib/sbi.c b/arch/riscv/lib/sbi.c
index 35a7d3b12f5..f8a2da5c271 100644
--- a/arch/riscv/lib/sbi.c
+++ b/arch/riscv/lib/sbi.c
@@ -220,6 +220,57 @@ int sbi_dbcn_write_byte(unsigned char ch)
        return ret.error;
 }
 
+/**
+ * sbi_pma_probe() - Probe for Andes PMA support
+ *
+ * Return: Number of PMA entries on success, SBI error on failure
+ */
+int sbi_pma_probe(void)
+{
+       struct sbiret ret;
+
+       ret = sbi_ecall(SBI_EXT_ANDES, SBI_EXT_ANDES_PMA_PROBE,
+                       0, 0, 0, 0, 0, 0);
+       if (ret.error)
+               return ret.error;
+
+       return ret.value;
+}
+
+/**
+ * sbi_pma_set() - Set a PMA region
+ * @pa:                Physical address of the region
+ * @size:      Size of the region
+ * @flags:     PMA configuration flags
+ *
+ * Return: 0 on success, SBI error on failure
+ */
+int sbi_pma_set(unsigned long pa, unsigned long size, unsigned long flags)
+{
+       struct sbiret ret;
+
+       ret = sbi_ecall(SBI_EXT_ANDES, SBI_EXT_ANDES_PMA_SET,
+                       pa, size, flags, 0, 0, 0);
+
+       return ret.error;
+}
+
+/**
+ * sbi_pma_free() - Free a PMA region
+ * @pa:                Physical address of the region to free
+ *
+ * Return: 0 on success, SBI error on failure
+ */
+int sbi_pma_free(unsigned long pa)
+{
+       struct sbiret ret;
+
+       ret = sbi_ecall(SBI_EXT_ANDES, SBI_EXT_ANDES_PMA_FREE,
+                       pa, 0, 0, 0, 0, 0);
+
+       return ret.error;
+}
+
 #ifdef CONFIG_SBI_V01
 
 /**
-- 
2.34.1


Reply via email to