@@ -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);
@@ -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 */
@@ -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);