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