[Skiboot] [RFC PATCH v7 06/12] xscoms: read/write xscoms using ucall
Ryan Grimm
grimm at linux.ibm.com
Tue Jul 7 02:14:33 AEST 2020
From: Madhavan Srinivasan <maddy at 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 at linux.vnet.ibm.com>
Signed-off-by: Santosh Sivaraj <santosh at fossix.org>
[ linuxram: Set uv_present just after starting UV ]
Signed-off-by: Ram Pai <linuxram at us.ibm.com>
[ grimm: Don't check MSR in xscom read/write ]
Signed-off-by: Ryan Grimm <grimm at linux.ibm.com>
---
include/ultravisor.h | 21 +++++++++++++++++++++
include/xscom.h | 5 +++++
2 files changed, 26 insertions(+)
diff --git a/include/ultravisor.h b/include/ultravisor.h
index 623b81d4..84217d66 100644
--- a/include/ultravisor.h
+++ b/include/ultravisor.h
@@ -7,6 +7,7 @@
#include <stdbool.h>
#include <stdint.h>
#include <types.h>
+#include <processor.h>
/*
* enter_uv: Each thread enters ultravisor and exits with S=0
@@ -43,4 +44,24 @@ void init_uv(void);
#define UCALL_BUFSIZE 4
extern long ucall(unsigned long opcode, unsigned long *retbuf, ...);
+#define UV_READ_SCOM 0xF114
+#define UV_WRITE_SCOM 0xF118
+
+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 bd8bb89a..67a845fd 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);
--
2.21.0
More information about the Skiboot
mailing list