@@ -316,3 +316,30 @@ exit_uv_mode:
mflr %r4
mtspr SPR_USRR0,%r4
urfid
+
+.global ucall
+ucall:
+ mflr %r0
+ stdu %r1,-STACK_FRAMESIZE(%r1)
+ std %r0,STACK_LR(%r1)
+ mfcr %r0
+ stw %r0,STACK_CR(%r1)
+ std %r4,STACK_GPR4(%r1) /* Save ret buffer */
+ mr %r4,%r5
+ mr %r5,%r6
+ mr %r6,%r7
+ mr %r7,%r8
+ mr %r8,%r9
+ mr %r9,%r10
+ sc 2 /* invoke the ultravisor */
+ ld %r12,STACK_GPR4(%r1)
+ std %r4, 0(%r12)
+ std %r5, 8(%r12)
+ std %r6, 16(%r12)
+ std %r7, 24(%r12)
+ lwz %r0,STACK_CR(%r1)
+ mtcrf 0xff,%r0
+ ld %r0,STACK_LR(%r1)
+ mtlr %r0
+ addi %r1,%r1,STACK_FRAMESIZE
+ blr /* return r3 = status */
@@ -9,6 +9,7 @@
#define UV_LOAD_MAX_SIZE 0x200000
+extern long ucall(unsigned long opcode, unsigned long *retbuf, ...);
extern int start_uv(uint64_t entry, void *fdt);
int start_ultravisor(void *fdt);