1/* 2 * Copyright (C) 2012 ARM Ltd. 3 * Author: Marc Zyngier <marc.zyngier@arm.com> 4 * 5 * Adapted for ARM and earlycon: 6 * Copyright (C) 2014 Linaro Ltd. 7 * Author: Rob Herring <robh@kernel.org> 8 * 9 * This program is free software: you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License version 2 as 11 * published by the Free Software Foundation. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program. If not, see <http://www.gnu.org/licenses/>. 20 */ 21#include <linux/kernel.h> 22#include <linux/console.h> 23#include <linux/init.h> 24#include <linux/serial_core.h> 25 26#ifdef CONFIG_THUMB2_KERNEL 27#define SEMIHOST_SWI "0xab" 28#else 29#define SEMIHOST_SWI "0x123456" 30#endif 31 32/* 33 * Semihosting-based debug console 34 */ 35static void smh_putc(struct uart_port *port, int c) 36{ 37#ifdef CONFIG_ARM64 38 asm volatile("mov x1, %0\n" 39 "mov x0, #3\n" 40 "hlt 0xf000\n" 41 : : "r" (&c) : "x0", "x1", "memory"); 42#else 43 asm volatile("mov r1, %0\n" 44 "mov r0, #3\n" 45 "svc " SEMIHOST_SWI "\n" 46 : : "r" (&c) : "r0", "r1", "memory"); 47#endif 48} 49 50static void smh_write(struct console *con, const char *s, unsigned n) 51{ 52 struct earlycon_device *dev = con->data; 53 uart_console_write(&dev->port, s, n, smh_putc); 54} 55 56int __init early_smh_setup(struct earlycon_device *device, const char *opt) 57{ 58 device->con->write = smh_write; 59 return 0; 60} 61EARLYCON_DECLARE(smh, early_smh_setup); 62