xref: /kvm-unit-tests/lib/powerpc/io.c (revision 67bdbcff6116e4f02fef693d87be296e549c207e)
1 /*
2  * Each architecture must implement puts() and exit().
3  *
4  * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com>
5  *
6  * This work is licensed under the terms of the GNU LGPL, version 2.
7  */
8 #include <libcflat.h>
9 #include <asm/spinlock.h>
10 #include <asm/rtas.h>
11 #include <asm/setup.h>
12 #include <asm/processor.h>
13 #include "io.h"
14 
15 static struct spinlock print_lock;
16 
17 void putchar(int c)
18 {
19 	if (machine_is_powernv())
20 		opal_putchar(c);
21 	else
22 		papr_putchar(c);
23 }
24 
25 int __getchar(void)
26 {
27 	if (machine_is_powernv())
28 		return __opal_getchar();
29 	else
30 		return __papr_getchar();
31 }
32 
33 void io_init(void)
34 {
35 	if (machine_is_powernv())
36 		assert(!opal_init());
37 	else
38 		rtas_init();
39 }
40 
41 void puts(const char *s)
42 {
43 	spin_lock(&print_lock);
44 	while (*s)
45 		putchar(*s++);
46 	spin_unlock(&print_lock);
47 }
48 
49 /*
50  * Defining halt to take 'code' as an argument guarantees that it will
51  * be in r3 when we halt. That gives us a final chance to see the exit
52  * status while inspecting the halted unit test state.
53  */
54 extern void halt(int code);
55 
56 void exit(int code)
57 {
58 // FIXME: change this print-exit/rtas-poweroff to chr_testdev_exit(),
59 //        maybe by plugging chr-testdev into a spapr-vty.
60 	printf("\nEXIT: STATUS=%d\n", ((code) << 1) | 1);
61 	if (machine_is_powernv())
62 		opal_power_off();
63 	else
64 		rtas_power_off();
65 	halt(code);
66 	__builtin_unreachable();
67 }
68