diff mbox series

[RFC,v5,08/16] xscoms: read/write xscoms using ucall

Message ID 20200227204023.22125-9-grimm@linux.ibm.com
State New
Headers show
Series Ultravisor support in skiboot | expand

Checks

Context Check Description
snowpatch_ozlabs/snowpatch_job_snowpatch-skiboot-dco success Signed-off-by present
snowpatch_ozlabs/snowpatch_job_snowpatch-skiboot success Test snowpatch/job/snowpatch-skiboot on branch master
snowpatch_ozlabs/apply_patch success Successfully applied on branch master (82aed17a5468aff6b600ee1694a10a60f942c018)

Commit Message

Ryan Grimm Feb. 27, 2020, 8:40 p.m. UTC
From: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>

xscom registers are in the secure memory area when secure mode is
enabled. These registers cannot be accessed directly and need to use
ultravisor services using ultracall.

Signed-off-by: Madhavan Srinivasan <maddy@linux.vnet.ibm.com>
Signed-off-by: Santosh Sivaraj <santosh@fossix.org>
[ linuxram: Set uv_present just after starting UV ]
Signed-off-by: Ram Pai <linuxram@us.ibm.com>
[ grimm: Don't check MSR in xscom read/write ]
Signed-off-by: Ryan Grimm <grimm@linux.ibm.com>
---
 hw/ultravisor.c      |  3 +++
 include/ultravisor.h | 23 +++++++++++++++++++++++
 include/xscom.h      |  5 +++++
 3 files changed, 31 insertions(+)
diff mbox series

Patch

diff --git a/hw/ultravisor.c b/hw/ultravisor.c
index 78281b41..ea14d8bd 100644
--- a/hw/ultravisor.c
+++ b/hw/ultravisor.c
@@ -13,6 +13,7 @@ 
 
 static struct dt_node *uv_fw_node;
 static uint64_t uv_base_addr;
+bool uv_present = false;
 
 struct memcons uv_memcons __section(".data.memcons") = {
 	.magic		= MEMCONS_MAGIC,
@@ -58,6 +59,8 @@  int start_ultravisor(void *fdt)
 
 	cpu_start_ultravisor(fdt);
 
+	uv_present = true;
+
 	while (i > 0)
 		cpu_wait_job(jobs[--i], true);
 
diff --git a/include/ultravisor.h b/include/ultravisor.h
index 148041a0..0d4d4939 100644
--- a/include/ultravisor.h
+++ b/include/ultravisor.h
@@ -6,13 +6,36 @@ 
 
 #include <stdint.h>
 #include <types.h>
+#include <processor.h>
 
 #define UV_LOAD_MAX_SIZE        0x200000
 
+#define UCALL_BUFSIZE 4
+#define UV_READ_SCOM  0xF114
+#define UV_WRITE_SCOM 0xF118
+
 extern long ucall(unsigned long opcode, unsigned long *retbuf, ...);
 extern int start_uv(uint64_t entry, void *fdt);
+extern bool uv_present;
 
 int start_ultravisor(void *fdt);
 void init_uv(void);
 
+static inline int uv_xscom_read(u64 partid, u64 pcb_addr, u64 *val)
+{
+	unsigned long retbuf[UCALL_BUFSIZE];
+	long rc;
+
+	rc = ucall(UV_READ_SCOM, retbuf, partid, pcb_addr);
+	*val = retbuf[0];
+	return rc;
+}
+
+static inline int uv_xscom_write(u64 partid, u64 pcb_addr, u64 val)
+{
+	unsigned long retbuf[UCALL_BUFSIZE];
+
+	return ucall(UV_WRITE_SCOM, retbuf, partid, pcb_addr, val);
+}
+
 #endif /* __ULTRAVISOR_H */
diff --git a/include/xscom.h b/include/xscom.h
index 8a466d56..2346db64 100644
--- a/include/xscom.h
+++ b/include/xscom.h
@@ -7,6 +7,7 @@ 
 #include <stdint.h>
 #include <processor.h>
 #include <cpu.h>
+#include <ultravisor.h>
 
 /*
  * SCOM "partID" definitions:
@@ -174,9 +175,13 @@  extern void _xscom_unlock(void);
 /* Targeted SCOM access */
 static inline int xscom_read(uint32_t partid, uint64_t pcb_addr, uint64_t *val)
 {
+	if (uv_present)
+		return uv_xscom_read(partid, pcb_addr, val);
 	return _xscom_read(partid, pcb_addr, val, true);
 }
 static inline int xscom_write(uint32_t partid, uint64_t pcb_addr, uint64_t val) {
+	if (uv_present)
+		return uv_xscom_write(partid, pcb_addr, val);
 	return _xscom_write(partid, pcb_addr, val, true);
 }
 extern int xscom_write_mask(uint32_t partid, uint64_t pcb_addr, uint64_t val, uint64_t mask);