1 /* 2 * Each architecture must implement puts() and exit() with the I/O 3 * devices exposed from QEMU, e.g. pl011 and chr-testdev. That's 4 * what's done here, along with initialization functions for those 5 * devices. 6 * 7 * Copyright (C) 2014, 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 <libcflat.h> 12 #include <devicetree.h> 13 #include <chr-testdev.h> 14 #include <config.h> 15 #include <asm/psci.h> 16 #include <asm/spinlock.h> 17 #include <asm/io.h> 18 19 #include "io.h" 20 21 static struct spinlock uart_lock; 22 /* 23 * Use this guess for the uart base in order to make an attempt at 24 * having earlier printf support. We'll overwrite it with the real 25 * base address that we read from the device tree later. This is 26 * the address we expect the virtual machine manager to put in 27 * its generated device tree. 28 */ 29 #define UART_EARLY_BASE (u8 *)(unsigned long)CONFIG_UART_EARLY_BASE 30 static volatile u8 *uart0_base = UART_EARLY_BASE; 31 32 static void uart0_init_fdt(void) 33 { 34 /* 35 * kvm-unit-tests uses the uart only for output. Both uart models have 36 * the TX register at offset 0 from the base address, so there is no 37 * need to treat them separately. 38 */ 39 const char *compatible[] = {"arm,pl011", "ns16550a"}; 40 struct dt_pbus_reg base; 41 int i, ret; 42 43 ret = dt_get_default_console_node(); 44 assert(ret >= 0 || ret == -FDT_ERR_NOTFOUND); 45 46 if (ret == -FDT_ERR_NOTFOUND) { 47 48 for (i = 0; i < ARRAY_SIZE(compatible); i++) { 49 ret = dt_pbus_get_base_compatible(compatible[i], &base); 50 assert(ret == 0 || ret == -FDT_ERR_NOTFOUND); 51 52 if (ret == 0) 53 break; 54 } 55 56 if (ret) { 57 printf("%s: Compatible uart not found in the device tree, " 58 "aborting...\n", __func__); 59 abort(); 60 } 61 62 } else { 63 ret = dt_pbus_translate_node(ret, 0, &base); 64 assert(ret == 0); 65 } 66 67 uart0_base = ioremap(base.addr, base.size); 68 } 69 70 #ifdef CONFIG_EFI 71 72 #include <acpi.h> 73 74 static void uart0_init_acpi(void) 75 { 76 struct spcr_descriptor *spcr = find_acpi_table_addr(SPCR_SIGNATURE); 77 78 assert_msg(spcr, "Unable to find ACPI SPCR"); 79 uart0_base = ioremap(spcr->serial_port.address, spcr->serial_port.bit_width); 80 } 81 #else 82 83 static void uart0_init_acpi(void) 84 { 85 assert_msg(false, "ACPI not available"); 86 } 87 88 #endif 89 90 void io_init(void) 91 { 92 if (dt_available()) 93 uart0_init_fdt(); 94 else 95 uart0_init_acpi(); 96 97 if (uart0_base != UART_EARLY_BASE) { 98 printf("WARNING: early print support may not work. " 99 "Found uart at %p, but early base is %p.\n", 100 uart0_base, UART_EARLY_BASE); 101 } 102 103 chr_testdev_init(); 104 } 105 106 void puts(const char *s) 107 { 108 spin_lock(&uart_lock); 109 while (*s) 110 writeb(*s++, uart0_base); 111 spin_unlock(&uart_lock); 112 } 113 114 static int do_getchar(void) 115 { 116 int c; 117 118 spin_lock(&uart_lock); 119 c = readb(uart0_base); 120 spin_unlock(&uart_lock); 121 122 return c ?: -1; 123 } 124 125 /* 126 * Minimalist implementation for migration completion detection. 127 * Without FIFOs enabled on the QEMU UART device we just read 128 * the data register: we cannot read more than 16 characters. 129 */ 130 int __getchar(void) 131 { 132 int c = do_getchar(); 133 static int count; 134 135 if (c != -1) 136 ++count; 137 138 assert(count < 16); 139 140 return c; 141 } 142 143 /* 144 * Defining halt to take 'code' as an argument guarantees that it will 145 * be in x0/r0 when we halt. That gives us a final chance to see the exit 146 * status while inspecting the halted unit test state. 147 */ 148 extern void halt(int code); 149 150 void exit(int code) 151 { 152 /* 153 * Print the test return code in the following format which is 154 * consistent with powerpc and s390x. The runner can pick it 155 * up when chr-testdev is not present. 156 */ 157 printf("\nEXIT: STATUS=%d\n", ((code) << 1) | 1); 158 159 chr_testdev_exit(code); 160 psci_system_off(); 161 halt(code); 162 __builtin_unreachable(); 163 } 164