1*275854baSSimon Glass /* 2*275854baSSimon Glass * Copyright (c) 2015 Google, Inc 3*275854baSSimon Glass * Written by Simon Glass <sjg@chromium.org> 4*275854baSSimon Glass * 5*275854baSSimon Glass * SPDX-License-Identifier: GPL-2.0+ 6*275854baSSimon Glass */ 7*275854baSSimon Glass 8*275854baSSimon Glass #include <common.h> 9*275854baSSimon Glass #include <debug_uart.h> 10*275854baSSimon Glass #include <dm.h> 11*275854baSSimon Glass #include <efi.h> 12*275854baSSimon Glass #include <efi_api.h> 13*275854baSSimon Glass #include <errno.h> 14*275854baSSimon Glass #include <fdtdec.h> 15*275854baSSimon Glass #include <linux/compiler.h> 16*275854baSSimon Glass #include <asm/io.h> 17*275854baSSimon Glass #include <serial.h> 18*275854baSSimon Glass 19*275854baSSimon Glass /* Information about the efi console */ 20*275854baSSimon Glass struct serial_efi_priv { 21*275854baSSimon Glass struct efi_simple_input_interface *con_in; 22*275854baSSimon Glass struct efi_simple_text_output_protocol *con_out; 23*275854baSSimon Glass struct efi_input_key key; 24*275854baSSimon Glass bool have_key; 25*275854baSSimon Glass }; 26*275854baSSimon Glass 27*275854baSSimon Glass int serial_efi_setbrg(struct udevice *dev, int baudrate) 28*275854baSSimon Glass { 29*275854baSSimon Glass return 0; 30*275854baSSimon Glass } 31*275854baSSimon Glass 32*275854baSSimon Glass static int serial_efi_get_key(struct serial_efi_priv *priv) 33*275854baSSimon Glass { 34*275854baSSimon Glass int ret; 35*275854baSSimon Glass 36*275854baSSimon Glass if (priv->have_key) 37*275854baSSimon Glass return 0; 38*275854baSSimon Glass ret = priv->con_in->read_key_stroke(priv->con_in, &priv->key); 39*275854baSSimon Glass if (ret == EFI_NOT_READY) 40*275854baSSimon Glass return -EAGAIN; 41*275854baSSimon Glass else if (ret != EFI_SUCCESS) 42*275854baSSimon Glass return -EIO; 43*275854baSSimon Glass 44*275854baSSimon Glass priv->have_key = true; 45*275854baSSimon Glass 46*275854baSSimon Glass return 0; 47*275854baSSimon Glass } 48*275854baSSimon Glass 49*275854baSSimon Glass static int serial_efi_getc(struct udevice *dev) 50*275854baSSimon Glass { 51*275854baSSimon Glass struct serial_efi_priv *priv = dev_get_priv(dev); 52*275854baSSimon Glass int ret, ch; 53*275854baSSimon Glass 54*275854baSSimon Glass ret = serial_efi_get_key(priv); 55*275854baSSimon Glass if (ret) 56*275854baSSimon Glass return ret; 57*275854baSSimon Glass 58*275854baSSimon Glass priv->have_key = false; 59*275854baSSimon Glass ch = priv->key.unicode_char; 60*275854baSSimon Glass 61*275854baSSimon Glass /* 62*275854baSSimon Glass * Unicode char 8 (for backspace) is never returned. Instead we get a 63*275854baSSimon Glass * key scan code of 8. Handle this so that backspace works correctly 64*275854baSSimon Glass * in the U-Boot command line. 65*275854baSSimon Glass */ 66*275854baSSimon Glass if (!ch && priv->key.scan_code == 8) 67*275854baSSimon Glass ch = 8; 68*275854baSSimon Glass debug(" [%x %x %x] ", ch, priv->key.unicode_char, priv->key.scan_code); 69*275854baSSimon Glass 70*275854baSSimon Glass return ch; 71*275854baSSimon Glass } 72*275854baSSimon Glass 73*275854baSSimon Glass static int serial_efi_putc(struct udevice *dev, const char ch) 74*275854baSSimon Glass { 75*275854baSSimon Glass struct serial_efi_priv *priv = dev_get_priv(dev); 76*275854baSSimon Glass uint16_t ucode[2]; 77*275854baSSimon Glass int ret; 78*275854baSSimon Glass 79*275854baSSimon Glass ucode[0] = ch; 80*275854baSSimon Glass ucode[1] = '\0'; 81*275854baSSimon Glass ret = priv->con_out->output_string(priv->con_out, ucode); 82*275854baSSimon Glass if (ret) 83*275854baSSimon Glass return -EIO; 84*275854baSSimon Glass 85*275854baSSimon Glass return 0; 86*275854baSSimon Glass } 87*275854baSSimon Glass 88*275854baSSimon Glass static int serial_efi_pending(struct udevice *dev, bool input) 89*275854baSSimon Glass { 90*275854baSSimon Glass struct serial_efi_priv *priv = dev_get_priv(dev); 91*275854baSSimon Glass int ret; 92*275854baSSimon Glass 93*275854baSSimon Glass /* We assume that EFI will stall if its output buffer fills up */ 94*275854baSSimon Glass if (!input) 95*275854baSSimon Glass return 0; 96*275854baSSimon Glass 97*275854baSSimon Glass ret = serial_efi_get_key(priv); 98*275854baSSimon Glass if (ret == -EAGAIN) 99*275854baSSimon Glass return 0; 100*275854baSSimon Glass else if (ret) 101*275854baSSimon Glass return ret; 102*275854baSSimon Glass 103*275854baSSimon Glass return 1; 104*275854baSSimon Glass } 105*275854baSSimon Glass 106*275854baSSimon Glass /* 107*275854baSSimon Glass * There is nothing to init here since the EFI console is already running by 108*275854baSSimon Glass * the time we enter U-Boot. 109*275854baSSimon Glass */ 110*275854baSSimon Glass void debug_uart_init(void) 111*275854baSSimon Glass { 112*275854baSSimon Glass } 113*275854baSSimon Glass 114*275854baSSimon Glass static inline void _debug_uart_putc(int ch) 115*275854baSSimon Glass { 116*275854baSSimon Glass struct efi_system_table *sys_table = efi_get_sys_table(); 117*275854baSSimon Glass uint16_t ucode[2]; 118*275854baSSimon Glass 119*275854baSSimon Glass ucode[0] = ch; 120*275854baSSimon Glass ucode[1] = '\0'; 121*275854baSSimon Glass sys_table->con_out->output_string(sys_table->con_out, ucode); 122*275854baSSimon Glass } 123*275854baSSimon Glass 124*275854baSSimon Glass DEBUG_UART_FUNCS 125*275854baSSimon Glass 126*275854baSSimon Glass static int serial_efi_probe(struct udevice *dev) 127*275854baSSimon Glass { 128*275854baSSimon Glass struct efi_system_table *table = efi_get_sys_table(); 129*275854baSSimon Glass struct serial_efi_priv *priv = dev_get_priv(dev); 130*275854baSSimon Glass 131*275854baSSimon Glass priv->con_in = table->con_in; 132*275854baSSimon Glass priv->con_out = table->con_out; 133*275854baSSimon Glass 134*275854baSSimon Glass return 0; 135*275854baSSimon Glass } 136*275854baSSimon Glass 137*275854baSSimon Glass static const struct dm_serial_ops serial_efi_ops = { 138*275854baSSimon Glass .putc = serial_efi_putc, 139*275854baSSimon Glass .getc = serial_efi_getc, 140*275854baSSimon Glass .pending = serial_efi_pending, 141*275854baSSimon Glass .setbrg = serial_efi_setbrg, 142*275854baSSimon Glass }; 143*275854baSSimon Glass 144*275854baSSimon Glass static const struct udevice_id serial_efi_ids[] = { 145*275854baSSimon Glass { .compatible = "efi,uart" }, 146*275854baSSimon Glass { } 147*275854baSSimon Glass }; 148*275854baSSimon Glass 149*275854baSSimon Glass U_BOOT_DRIVER(serial_efi) = { 150*275854baSSimon Glass .name = "serial_efi", 151*275854baSSimon Glass .id = UCLASS_SERIAL, 152*275854baSSimon Glass .of_match = serial_efi_ids, 153*275854baSSimon Glass .priv_auto_alloc_size = sizeof(struct serial_efi_priv), 154*275854baSSimon Glass .probe = serial_efi_probe, 155*275854baSSimon Glass .ops = &serial_efi_ops, 156*275854baSSimon Glass .flags = DM_FLAG_PRE_RELOC, 157*275854baSSimon Glass }; 158