1 /*
2 * Hypercall helpers
3 *
4 * broken_sc1 probing/patching inspired by SLOF, see
5 * SLOF:lib/libhvcall/brokensc1.c
6 *
7 * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com>
8 *
9 * This work is licensed under the terms of the GNU LGPL, version 2.
10 */
11 #include <asm/hcall.h>
12 #include <libcflat.h>
13 #include "io.h"
14
hcall_have_broken_sc1(void)15 int hcall_have_broken_sc1(void)
16 {
17 register unsigned long r3 asm("r3") = H_SET_DABR;
18 register unsigned long r4 asm("r4") = 0;
19
20 asm volatile("sc 1"
21 : "=r" (r3)
22 : "r" (r3), "r" (r4)
23 : "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12");
24
25 return r3 == (unsigned long)H_PRIVILEGE;
26 }
27
papr_putchar(int c)28 void papr_putchar(int c)
29 {
30 unsigned long vty = 0; /* 0 == default */
31 unsigned long nr_chars = 1;
32 unsigned long chars = (unsigned long)c << 56;
33
34 hcall(H_PUT_TERM_CHAR, vty, nr_chars, chars);
35 }
36
__papr_getchar(void)37 int __papr_getchar(void)
38 {
39 register unsigned long r3 asm("r3") = H_GET_TERM_CHAR;
40 register unsigned long r4 asm("r4") = 0; /* 0 == default vty */
41 register unsigned long r5 asm("r5");
42
43 asm volatile (" sc 1 " : "+r"(r3), "+r"(r4), "=r"(r5)
44 : "r"(r3), "r"(r4));
45
46 return r3 == H_SUCCESS && r4 > 0 ? r5 >> 56 : -1;
47 }
48