11e95c7ccSAndrew Jones /* 21e95c7ccSAndrew Jones * Each architecture must implement puts() and exit(). 31e95c7ccSAndrew Jones * 41e95c7ccSAndrew Jones * Copyright (C) 2016, Red Hat Inc, Andrew Jones <drjones@redhat.com> 51e95c7ccSAndrew Jones * 61e95c7ccSAndrew Jones * This work is licensed under the terms of the GNU LGPL, version 2. 71e95c7ccSAndrew Jones */ 81e95c7ccSAndrew Jones #include <libcflat.h> 9e65bcc62SAndrew Jones #include <asm/spinlock.h> 102f9ce69eSAndrew Jones #include <asm/rtas.h> 114ff26ec5SThomas Huth #include <asm/setup.h> 12*610c5a9cSNicholas Piggin #include <asm/processor.h> 134ff26ec5SThomas Huth #include "io.h" 14e65bcc62SAndrew Jones 15e65bcc62SAndrew Jones static struct spinlock print_lock; 161e95c7ccSAndrew Jones 17*610c5a9cSNicholas Piggin void putchar(int c) 18*610c5a9cSNicholas Piggin { 19*610c5a9cSNicholas Piggin if (machine_is_powernv()) 20*610c5a9cSNicholas Piggin opal_putchar(c); 21*610c5a9cSNicholas Piggin else 22*610c5a9cSNicholas Piggin papr_putchar(c); 23*610c5a9cSNicholas Piggin } 24*610c5a9cSNicholas Piggin 25*610c5a9cSNicholas Piggin int __getchar(void) 26*610c5a9cSNicholas Piggin { 27*610c5a9cSNicholas Piggin if (machine_is_powernv()) 28*610c5a9cSNicholas Piggin return __opal_getchar(); 29*610c5a9cSNicholas Piggin else 30*610c5a9cSNicholas Piggin return __papr_getchar(); 31*610c5a9cSNicholas Piggin } 32*610c5a9cSNicholas Piggin 331e95c7ccSAndrew Jones void io_init(void) 341e95c7ccSAndrew Jones { 35*610c5a9cSNicholas Piggin if (machine_is_powernv()) 36*610c5a9cSNicholas Piggin assert(!opal_init()); 37*610c5a9cSNicholas Piggin else 382f9ce69eSAndrew Jones rtas_init(); 391e95c7ccSAndrew Jones } 401e95c7ccSAndrew Jones 41e65bcc62SAndrew Jones void puts(const char *s) 421e95c7ccSAndrew Jones { 43e65bcc62SAndrew Jones spin_lock(&print_lock); 44e65bcc62SAndrew Jones while (*s) 45e65bcc62SAndrew Jones putchar(*s++); 46e65bcc62SAndrew Jones spin_unlock(&print_lock); 471e95c7ccSAndrew Jones } 481e95c7ccSAndrew Jones 49764aa0b8SAndrew Jones /* 50764aa0b8SAndrew Jones * Defining halt to take 'code' as an argument guarantees that it will 51764aa0b8SAndrew Jones * be in r3 when we halt. That gives us a final chance to see the exit 52764aa0b8SAndrew Jones * status while inspecting the halted unit test state. 53764aa0b8SAndrew Jones */ 54764aa0b8SAndrew Jones extern void halt(int code); 55764aa0b8SAndrew Jones 56e65bcc62SAndrew Jones void exit(int code) 571e95c7ccSAndrew Jones { 58f5a87330SAndrew Jones // FIXME: change this print-exit/rtas-poweroff to chr_testdev_exit(), 59f5a87330SAndrew Jones // maybe by plugging chr-testdev into a spapr-vty. 60f5a87330SAndrew Jones printf("\nEXIT: STATUS=%d\n", ((code) << 1) | 1); 61*610c5a9cSNicholas Piggin if (machine_is_powernv()) 62*610c5a9cSNicholas Piggin opal_power_off(); 63*610c5a9cSNicholas Piggin else 64f5a87330SAndrew Jones rtas_power_off(); 65e65bcc62SAndrew Jones halt(code); 6696d79976SAndre Przywara __builtin_unreachable(); 671e95c7ccSAndrew Jones } 68