* [PATCH 0/2] add support of efi Serial IO and Graphics Output Protocol @ 2017-03-06 5:02 Jean-Christophe PLAGNIOL-VILLARD 2017-03-06 5:04 ` [PATCH 1/2] video: add EFI Graphics Output Protocol support Jean-Christophe PLAGNIOL-VILLARD 2017-03-06 8:18 ` [PATCH 0/2] add support of efi Serial IO and Graphics Output Protocol Sascha Hauer 0 siblings, 2 replies; 10+ messages in thread From: Jean-Christophe PLAGNIOL-VILLARD @ 2017-03-06 5:02 UTC (permalink / raw) To: barebox Hi, The following changes since commit d92ed454107b4d6f0d30fa0271da191ae5911d18: Merge branch 'for-next/video' into next (2017-02-27 08:51:08 +0100) are available in the git repository at: git://git.jcrosoft.org/barebox.git delivery/serial-gop for you to fetch changes up to 6ecbe33539f20076bbc781b9e20a5a54d504fdf3: efi: add serial driver support (2017-03-01 22:11:37 +0800) ---------------------------------------------------------------- Jean-Christophe PLAGNIOL-VILLARD (2): video: add EFI Graphics Output Protocol support efi: add serial driver support drivers/serial/Kconfig | 4 +++ drivers/serial/Makefile | 1 + drivers/serial/serial_efi.c | 241 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ drivers/video/Kconfig | 4 +++ drivers/video/Makefile | 2 ++ drivers/video/efi_gop.c | 267 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 6 files changed, 519 insertions(+) create mode 100644 drivers/serial/serial_efi.c create mode 100644 drivers/video/efi_gop.c Best Regards, J. _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/2] video: add EFI Graphics Output Protocol support 2017-03-06 5:02 [PATCH 0/2] add support of efi Serial IO and Graphics Output Protocol Jean-Christophe PLAGNIOL-VILLARD @ 2017-03-06 5:04 ` Jean-Christophe PLAGNIOL-VILLARD 2017-03-06 5:04 ` [PATCH 2/2] efi: add serial driver support Jean-Christophe PLAGNIOL-VILLARD 2017-03-09 8:46 ` [PATCH 1/2] video: add EFI Graphics Output Protocol support Michael Olbrich 2017-03-06 8:18 ` [PATCH 0/2] add support of efi Serial IO and Graphics Output Protocol Sascha Hauer 1 sibling, 2 replies; 10+ messages in thread From: Jean-Christophe PLAGNIOL-VILLARD @ 2017-03-06 5:04 UTC (permalink / raw) To: barebox Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> --- drivers/video/Kconfig | 4 + drivers/video/Makefile | 2 + drivers/video/efi_gop.c | 267 ++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 273 insertions(+) create mode 100644 drivers/video/efi_gop.c diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 8f31f5af7..8d50db6f6 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -24,6 +24,10 @@ config DRIVER_VIDEO_ATMEL_HLCD bool "Atmel HLCDC framebuffer driver" depends on ARCH_AT91 +config DRIVER_VIDEO_EFI_GOP + bool "EFI Graphics Output Protocol (GOP)" + depends on EFI_BOOTUP + config DRIVER_VIDEO_IMX bool "i.MX framebuffer driver" depends on ARCH_IMX1 || ARCH_IMX21 || ARCH_IMX25 || ARCH_IMX27 diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 1bf2e1f3c..97712182e 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -21,3 +21,5 @@ obj-$(CONFIG_DRIVER_VIDEO_OMAP) += omap.o obj-$(CONFIG_DRIVER_VIDEO_BCM283X) += bcm2835.o obj-$(CONFIG_DRIVER_VIDEO_SIMPLEFB) += simplefb.o obj-$(CONFIG_DRIVER_VIDEO_IMX_IPUV3) += imx-ipu-v3/ + +obj-$(CONFIG_DRIVER_VIDEO_EFI_GOP) += efi_gop.o diff --git a/drivers/video/efi_gop.c b/drivers/video/efi_gop.c new file mode 100644 index 000000000..ccb4af3d9 --- /dev/null +++ b/drivers/video/efi_gop.c @@ -0,0 +1,267 @@ +/* + * Copyright 2011 Intel Corporation; author Matt Fleming + * Copyright (c) 2017 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * GPL v2 + */ + +#include <common.h> +#include <driver.h> +#include <init.h> +#include <malloc.h> +#include <fb.h> +#include <errno.h> +#include <gui/graphic_utils.h> +#include <efi.h> +#include <efi/efi.h> +#include <efi/efi-device.h> + +#define PIXEL_RGB_RESERVED_8BIT_PER_COLOR 0 +#define PIXEL_BGR_RESERVED_8BIT_PER_COLOR 1 +#define PIXEL_BIT_MASK 2 +#define PIXEL_BLT_ONLY 3 +#define PIXEL_FORMAT_MAX 4 + +struct efi_pixel_bitmask { + u32 red_mask; + u32 green_mask; + u32 blue_mask; + u32 reserved_mask; +}; + +struct efi_graphics_output_mode_info { + u32 version; + u32 horizontal_resolution; + u32 vertical_resolution; + int pixel_format; + struct efi_pixel_bitmask pixel_information; + u32 pixels_per_scan_line; +}; + +struct efi_graphics_output_protocol_mode { + uint32_t max_mode; + uint32_t mode; + struct efi_graphics_output_mode_info *info; + unsigned long size_of_info; + void *frame_buffer_base; + unsigned long frame_buffer_size; +}; + +struct efi_graphics_output_protocol { + efi_status_t (EFIAPI *query_mode) (struct efi_graphics_output_protocol *This, + uint32_t mode_number, unsigned long *size_of_info, + struct efi_graphics_output_mode_info **info); + efi_status_t (EFIAPI *set_mode) (struct efi_graphics_output_protocol *This, + uint32_t mode_number); + efi_status_t (EFIAPI *blt)(struct efi_graphics_output_protocol *This, + void *buffer, + unsigned long operation, + unsigned long sourcex, unsigned long sourcey, + unsigned long destinationx, unsigned long destinationy, + unsigned long width, unsigned long height, unsigned + long delta); + struct efi_graphics_output_protocol_mode *mode; +}; + +struct efi_gop_priv { + struct device_d *dev; + struct fb_info fb; + + uint32_t mode; + struct efi_graphics_output_protocol *gop; +}; + +static void find_bits(unsigned long mask, u32 *pos, u32 *size) +{ + u8 first, len; + + first = 0; + len = 0; + + if (mask) { + while (!(mask & 0x1)) { + mask = mask >> 1; + first++; + } + + while (mask & 0x1) { + mask = mask >> 1; + len++; + } + } + + *pos = first; + *size = len; +} + +static void setup_pixel_info(struct fb_info *fb, u32 pixels_per_scan_line, + struct efi_pixel_bitmask pixel_info, int pixel_format) +{ + if (pixel_format == PIXEL_RGB_RESERVED_8BIT_PER_COLOR) { + fb->bits_per_pixel = 32; + fb->line_length = pixels_per_scan_line * 4; + fb->red.length = 8; + fb->red.offset = 0; + fb->green.length = 8; + fb->green.offset = 8; + fb->blue.length = 8; + fb->blue.offset = 16; + fb->transp.length = 8; + fb->transp.offset = 24; + } else if (pixel_format == PIXEL_BGR_RESERVED_8BIT_PER_COLOR) { + fb->bits_per_pixel = 32; + fb->line_length = pixels_per_scan_line * 4; + fb->red.length = 8; + fb->red.offset = 16; + fb->green.length = 8; + fb->green.offset = 8; + fb->blue.length = 8; + fb->blue.offset = 0; + fb->transp.length = 8; + fb->transp.offset = 24; + } else if (pixel_format == PIXEL_BIT_MASK) { + find_bits(pixel_info.red_mask, &fb->red.offset, &fb->red.length); + find_bits(pixel_info.green_mask, &fb->green.offset, + &fb->green.length); + find_bits(pixel_info.blue_mask, &fb->blue.offset, &fb->blue.length); + find_bits(pixel_info.reserved_mask, &fb->transp.offset, + &fb->transp.length); + fb->bits_per_pixel = fb->red.length + fb->green.length + + fb->blue.length + fb->transp.length; + fb->line_length = (pixels_per_scan_line * fb->bits_per_pixel) / 8; + } else { + fb->bits_per_pixel = 4; + fb->line_length = fb->xres / 2; + fb->red.length = 0; + fb->red.offset = 0; + fb->green.length = 0; + fb->green.offset = 0; + fb->blue.length = 0; + fb->blue.offset = 0; + fb->transp.length = 0; + fb->transp.offset = 0; + } +} + +static int efi_gop_query(struct efi_gop_priv *priv) +{ + struct efi_graphics_output_protocol_mode *mode; + struct efi_graphics_output_mode_info *info; + efi_status_t efiret; + unsigned long size = 0; + int i; + struct fb_videomode *vmode; + + mode = priv->gop->mode; + vmode = xzalloc(sizeof(*vmode) * mode->max_mode); + + priv->fb.modes.num_modes = mode->max_mode; + priv->fb.modes.modes = vmode; + + for (i = 0; i < mode->max_mode; i++, vmode++) { + efiret = priv->gop->query_mode(priv->gop, i, &size, &info); + if (EFI_ERROR(efiret)) + continue; + + vmode->name = basprintf("%d", i); + vmode->xres = info->horizontal_resolution; + vmode->yres = info->vertical_resolution; + } + + priv->fb.screen_base = mode->frame_buffer_base; + priv->mode = mode->mode; + priv->fb.xres = priv->fb.mode->xres; + priv->fb.yres = priv->fb.mode->yres; + + return 0; +} + +static int efi_gop_fb_activate_var(struct fb_info *fb_info) +{ + struct efi_gop_priv *priv = fb_info->priv; + struct efi_graphics_output_mode_info *info; + int num; + unsigned long size = 0; + efi_status_t efiret; + + num = simple_strtoul(fb_info->mode->name, NULL, 0); + + if (priv->mode != num) { + efiret = priv->gop->set_mode(priv->gop, num); + if (EFI_ERROR(efiret)) + return -efi_errno(efiret); + priv->mode = num; + } + + efiret = priv->gop->query_mode(priv->gop, num, &size, &info); + if (EFI_ERROR(efiret)) + return -efi_errno(efiret); + + setup_pixel_info(&priv->fb, info->pixels_per_scan_line, + info->pixel_information, info->pixel_format); + + return 0; +} + +static struct fb_ops efi_gop_ops = { + .fb_activate_var = efi_gop_fb_activate_var, +}; + +static int efi_gop_probe(struct efi_device *efidev) +{ + struct efi_gop_priv *priv; + int ret = 0; + efi_status_t efiret; + efi_guid_t got_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; + void *protocol; + + efiret = BS->handle_protocol(efidev->handle, &got_guid, &protocol); + if (EFI_ERROR(efiret)) + return -efi_errno(efiret); + + priv = xzalloc(sizeof(struct efi_gop_priv)); + priv->gop = protocol; + priv->dev = &efidev->dev; + + if (!priv->gop) { + ret = -EINVAL; + goto err; + } + + ret = efi_gop_query(priv); + if (ret) + goto err; + + priv->fb.priv = priv; + priv->fb.dev.parent = priv->dev; + priv->fb.fbops = &efi_gop_ops; + priv->fb.p_enable = 1; + priv->fb.current_mode = priv->mode; + + ret = register_framebuffer(&priv->fb); + if (!ret) { + priv->dev->priv = &priv->fb; + return 0; + } + + if (priv->fb.modes.modes) { + int i; + + for (i = 0; i < priv->fb.modes.num_modes; i++) + free((void*)priv->fb.modes.modes[i].name); + + free((void*)priv->fb.modes.modes); + } +err: + free(priv); + return ret; +} + +static struct efi_driver efi_gop_driver = { + .driver = { + .name = "efi-gop", + }, + .probe = efi_gop_probe, + .guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID, +}; +device_efi_driver(efi_gop_driver); -- 2.11.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/2] efi: add serial driver support 2017-03-06 5:04 ` [PATCH 1/2] video: add EFI Graphics Output Protocol support Jean-Christophe PLAGNIOL-VILLARD @ 2017-03-06 5:04 ` Jean-Christophe PLAGNIOL-VILLARD 2017-03-06 9:34 ` [PATCH 2/2 v2] " Jean-Christophe PLAGNIOL-VILLARD 2017-03-09 8:46 ` [PATCH 1/2] video: add EFI Graphics Output Protocol support Michael Olbrich 1 sibling, 1 reply; 10+ messages in thread From: Jean-Christophe PLAGNIOL-VILLARD @ 2017-03-06 5:04 UTC (permalink / raw) To: barebox So now we can stop to use the efi-stdio as this driver print on the Framebuffer and the serial at the same time. This is specially usefull if we want to use the framebuffer via efi-gop for something else. Do not forget to disable the efi-stdio device before enabling the console otherwise you will get double printing. Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> --- drivers/serial/Kconfig | 4 + drivers/serial/Makefile | 1 + drivers/serial/serial_efi.c | 241 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 246 insertions(+) create mode 100644 drivers/serial/serial_efi.c diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index ced30530a..cfddc2ee9 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -21,6 +21,10 @@ config DRIVER_SERIAL_AR933X If you have an Atheros AR933X SOC based board and want to use the built-in UART of the SoC, say Y to this option. +config DRIVER_SERIAL_EFI + bool "EFI serial" + depends on EFI_BOOTUP + config DRIVER_SERIAL_IMX depends on ARCH_IMX default y diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 7d1bae195..3d9f735ed 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -1,6 +1,7 @@ obj-$(CONFIG_DRIVER_SERIAL_ARM_DCC) += arm_dcc.o obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o obj-$(CONFIG_DRIVER_SERIAL_AR933X) += serial_ar933x.o +obj-$(CONFIG_DRIVER_SERIAL_EFI) += serial_efi.o obj-$(CONFIG_DRIVER_SERIAL_IMX) += serial_imx.o obj-$(CONFIG_DRIVER_SERIAL_STM378X) += stm-serial.o obj-$(CONFIG_DRIVER_SERIAL_ATMEL) += atmel.o diff --git a/drivers/serial/serial_efi.c b/drivers/serial/serial_efi.c new file mode 100644 index 000000000..35387bfd5 --- /dev/null +++ b/drivers/serial/serial_efi.c @@ -0,0 +1,241 @@ +/* + * (C) Copyright 2000 + * Rob Taylor, Flying Pig Systems. robt@flyingpig.com. + * + * (C) Copyright 2004 + * ARM Ltd. + * Philippe Robin, <philippe.robin@arm.com> + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +/* Simple U-Boot driver for the PrimeCell PL010/PL011 UARTs */ + +#include <common.h> +#include <driver.h> +#include <init.h> +#include <malloc.h> +#include <efi.h> +#include <efi/efi.h> +#include <efi/efi-device.h> + +// +// define for Control bits, grouped by read only, write only, and read write +// +// +// Read Only +// +#define EFI_SERIAL_CLEAR_TO_SEND 0x00000010 +#define EFI_SERIAL_DATA_SET_READY 0x00000020 +#define EFI_SERIAL_RING_INDICATE 0x00000040 +#define EFI_SERIAL_CARRIER_DETECT 0x00000080 +#define EFI_SERIAL_INPUT_BUFFER_EMPTY 0x00000100 +#define EFI_SERIAL_OUTPUT_BUFFER_EMPTY 0x00000200 + +// +// Write Only +// +#define EFI_SERIAL_REQUEST_TO_SEND 0x00000002 +#define EFI_SERIAL_DATA_TERMINAL_READY 0x00000001 + +// +// Read Write +// +#define EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE 0x00001000 +#define EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE 0x00002000 +#define EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE 0x00004000 + +typedef enum { + DefaultParity, + NoParity, + EvenParity, + OddParity, + MarkParity, + SpaceParity +} efi_parity_type; + +typedef enum { + DefaultStopBits, + OneStopBit, + OneFiveStopBits, + TwoStopBits +} efi_stop_bits_type; + +struct efi_serial_io_mode { + uint32_t controlmask; + uint32_t timeout; + uint64_t baudrate; + uint32_t receivefifodepth; + uint32_t databits; + uint32_t parity; + uint32_t stopbits; +}; + +struct efi_serial_io_protocol { + uint32_t revision; + + efi_status_t (EFIAPI *reset) (struct efi_serial_io_protocol *This); + efi_status_t (EFIAPI *set_attributes) (struct efi_serial_io_protocol *This, + uint64_t baudrate, uint32_t receivefifodepth, + uint32_t timeout, efi_parity_type parity, + uint8_t databits, efi_stop_bits_type stopbits); + efi_status_t (EFIAPI *setcontrol) (struct efi_serial_io_protocol *This, + uint32_t control); + efi_status_t (EFIAPI *getcontrol) (struct efi_serial_io_protocol *This, + uint32_t *control); + efi_status_t (EFIAPI *write) (struct efi_serial_io_protocol *This, + unsigned long *buffersize, void *buffer); + efi_status_t (EFIAPI *read) (struct efi_serial_io_protocol *This, + unsigned long *buffersize, void *buffer); + + struct efi_serial_io_mode *mode; +}; + +/* + * We wrap our port structure around the generic console_device. + */ +struct efi_serial_port { + struct efi_serial_io_protocol *serial; + struct console_device uart; /* uart */ + struct efi_device *efidev; +}; + +static inline struct efi_serial_port * +to_efi_serial_port(struct console_device *uart) +{ + return container_of(uart, struct efi_serial_port, uart); +} + +static int efi_serial_setbaudrate(struct console_device *cdev, int baudrate) +{ + struct efi_serial_port *uart = to_efi_serial_port(cdev); + struct efi_serial_io_protocol *serial = uart->serial; + efi_status_t efiret; + + efiret = serial->set_attributes(serial, baudrate, 0, 0, NoParity, 8, + OneStopBit); + if (EFI_ERROR(efiret)) + return -efi_errno(efiret); + + return 0; +} + +static void efi_serial_putc(struct console_device *cdev, char c) +{ + struct efi_serial_port *uart = to_efi_serial_port(cdev); + struct efi_serial_io_protocol *serial = uart->serial; + uint32_t control; + efi_status_t efiret; + unsigned long buffersize = sizeof(char); + + do { + efiret = serial->getcontrol(serial, &control); + if (EFI_ERROR(efiret)) + return; + + } while(!(control & EFI_SERIAL_CLEAR_TO_SEND)); + + serial->write(serial, &buffersize, &c); +} + +static int efi_serial_puts(struct console_device *cdev, const char *s) +{ + struct efi_serial_port *uart = to_efi_serial_port(cdev); + struct efi_serial_io_protocol *serial = uart->serial; + uint32_t control; + efi_status_t efiret; + unsigned long buffersize = strlen(s) * sizeof(char); + + do { + efiret = serial->getcontrol(serial, &control); + if (EFI_ERROR(efiret)) + return 0; + + } while(!(control & EFI_SERIAL_CLEAR_TO_SEND)); + + serial->write(serial, &buffersize, (void*)s); + + return strlen(s); +} + +static int efi_serial_getc(struct console_device *cdev) +{ + struct efi_serial_port *uart = to_efi_serial_port(cdev); + struct efi_serial_io_protocol *serial = uart->serial; + uint32_t control; + efi_status_t efiret; + unsigned long buffersize = sizeof(char); + char c; + + do { + efiret = serial->getcontrol(serial, &control); + if (EFI_ERROR(efiret)) + return (int)-1; + + } while(!(control & EFI_SERIAL_DATA_SET_READY)); + + serial->read(serial, &buffersize, &c); + + return (int)c; +} + +static int efi_serial_tstc(struct console_device *cdev) +{ + struct efi_serial_port *uart = to_efi_serial_port(cdev); + struct efi_serial_io_protocol *serial = uart->serial; + uint32_t control; + efi_status_t efiret; + + efiret = serial->getcontrol(serial, &control); + if (EFI_ERROR(efiret)) + return 0; + + return !(control & EFI_SERIAL_INPUT_BUFFER_EMPTY); +} + +static int efi_serial_probe(struct efi_device *efidev) +{ + struct efi_serial_port *uart; + struct console_device *cdev; + + uart = xzalloc(sizeof(struct efi_serial_port)); + + cdev = &uart->uart; + cdev->dev = &efidev->dev; + cdev->tstc = efi_serial_tstc; + cdev->putc = efi_serial_putc; + cdev->puts = efi_serial_puts; + cdev->getc = efi_serial_getc; + cdev->setbrg = efi_serial_setbaudrate; + + uart->serial = efidev->protocol; + + uart->serial->reset(uart->serial); + + /* Enable UART */ + + console_register(cdev); + + return 0; +} + +static struct efi_driver efi_serial_driver = { + .driver = { + .name = "efi-serial", + }, + .probe = efi_serial_probe, + .guid = EFI_SERIAL_IO_PROTOCOL_GUID, +}; +device_efi_driver(efi_serial_driver); -- 2.11.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 2/2 v2] efi: add serial driver support 2017-03-06 5:04 ` [PATCH 2/2] efi: add serial driver support Jean-Christophe PLAGNIOL-VILLARD @ 2017-03-06 9:34 ` Jean-Christophe PLAGNIOL-VILLARD 2017-03-07 7:01 ` Sascha Hauer 2017-03-11 16:23 ` Michael Olbrich 0 siblings, 2 replies; 10+ messages in thread From: Jean-Christophe PLAGNIOL-VILLARD @ 2017-03-06 9:34 UTC (permalink / raw) To: barebox So now we can stop to use the efi-stdio as this driver print on the Framebuffer and the serial at the same time. This is specially usefull if we want to use the framebuffer via efi-gop for something else. Do not forget to disable the efi-stdio device before enabling the console otherwise you will get double printing. Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> --- Fix copyright drivers/serial/Kconfig | 4 + drivers/serial/Makefile | 1 + drivers/serial/serial_efi.c | 221 ++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 226 insertions(+) create mode 100644 drivers/serial/serial_efi.c diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index ced30530a..cfddc2ee9 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -21,6 +21,10 @@ config DRIVER_SERIAL_AR933X If you have an Atheros AR933X SOC based board and want to use the built-in UART of the SoC, say Y to this option. +config DRIVER_SERIAL_EFI + bool "EFI serial" + depends on EFI_BOOTUP + config DRIVER_SERIAL_IMX depends on ARCH_IMX default y diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile index 7d1bae195..3d9f735ed 100644 --- a/drivers/serial/Makefile +++ b/drivers/serial/Makefile @@ -1,6 +1,7 @@ obj-$(CONFIG_DRIVER_SERIAL_ARM_DCC) += arm_dcc.o obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o obj-$(CONFIG_DRIVER_SERIAL_AR933X) += serial_ar933x.o +obj-$(CONFIG_DRIVER_SERIAL_EFI) += serial_efi.o obj-$(CONFIG_DRIVER_SERIAL_IMX) += serial_imx.o obj-$(CONFIG_DRIVER_SERIAL_STM378X) += stm-serial.o obj-$(CONFIG_DRIVER_SERIAL_ATMEL) += atmel.o diff --git a/drivers/serial/serial_efi.c b/drivers/serial/serial_efi.c new file mode 100644 index 000000000..f0a2b22c2 --- /dev/null +++ b/drivers/serial/serial_efi.c @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2017 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> + * + * Under GPLv2 Only + */ + +#include <common.h> +#include <driver.h> +#include <init.h> +#include <malloc.h> +#include <efi.h> +#include <efi/efi.h> +#include <efi/efi-device.h> + +/* + * define for Control bits, grouped by read only, write only, and read write + * + * Read Only + */ +#define EFI_SERIAL_CLEAR_TO_SEND 0x00000010 +#define EFI_SERIAL_DATA_SET_READY 0x00000020 +#define EFI_SERIAL_RING_INDICATE 0x00000040 +#define EFI_SERIAL_CARRIER_DETECT 0x00000080 +#define EFI_SERIAL_INPUT_BUFFER_EMPTY 0x00000100 +#define EFI_SERIAL_OUTPUT_BUFFER_EMPTY 0x00000200 + +/* + * Write Only + */ +#define EFI_SERIAL_REQUEST_TO_SEND 0x00000002 +#define EFI_SERIAL_DATA_TERMINAL_READY 0x00000001 + +/* + * Read Write + */ +#define EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE 0x00001000 +#define EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE 0x00002000 +#define EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE 0x00004000 + +typedef enum { + DefaultParity, + NoParity, + EvenParity, + OddParity, + MarkParity, + SpaceParity +} efi_parity_type; + +typedef enum { + DefaultStopBits, + OneStopBit, + OneFiveStopBits, + TwoStopBits +} efi_stop_bits_type; + +struct efi_serial_io_mode { + uint32_t controlmask; + uint32_t timeout; + uint64_t baudrate; + uint32_t receivefifodepth; + uint32_t databits; + uint32_t parity; + uint32_t stopbits; +}; + +struct efi_serial_io_protocol { + uint32_t revision; + + efi_status_t (EFIAPI *reset) (struct efi_serial_io_protocol *This); + efi_status_t (EFIAPI *set_attributes) (struct efi_serial_io_protocol *This, + uint64_t baudrate, uint32_t receivefifodepth, + uint32_t timeout, efi_parity_type parity, + uint8_t databits, efi_stop_bits_type stopbits); + efi_status_t (EFIAPI *setcontrol) (struct efi_serial_io_protocol *This, + uint32_t control); + efi_status_t (EFIAPI *getcontrol) (struct efi_serial_io_protocol *This, + uint32_t *control); + efi_status_t (EFIAPI *write) (struct efi_serial_io_protocol *This, + unsigned long *buffersize, void *buffer); + efi_status_t (EFIAPI *read) (struct efi_serial_io_protocol *This, + unsigned long *buffersize, void *buffer); + + struct efi_serial_io_mode *mode; +}; + +/* + * We wrap our port structure around the generic console_device. + */ +struct efi_serial_port { + struct efi_serial_io_protocol *serial; + struct console_device uart; /* uart */ + struct efi_device *efidev; +}; + +static inline struct efi_serial_port * +to_efi_serial_port(struct console_device *uart) +{ + return container_of(uart, struct efi_serial_port, uart); +} + +static int efi_serial_setbaudrate(struct console_device *cdev, int baudrate) +{ + struct efi_serial_port *uart = to_efi_serial_port(cdev); + struct efi_serial_io_protocol *serial = uart->serial; + efi_status_t efiret; + + efiret = serial->set_attributes(serial, baudrate, 0, 0, NoParity, 8, + OneStopBit); + if (EFI_ERROR(efiret)) + return -efi_errno(efiret); + + return 0; +} + +static void efi_serial_putc(struct console_device *cdev, char c) +{ + struct efi_serial_port *uart = to_efi_serial_port(cdev); + struct efi_serial_io_protocol *serial = uart->serial; + uint32_t control; + efi_status_t efiret; + unsigned long buffersize = sizeof(char); + + do { + efiret = serial->getcontrol(serial, &control); + if (EFI_ERROR(efiret)) + return; + + } while(!(control & EFI_SERIAL_CLEAR_TO_SEND)); + + serial->write(serial, &buffersize, &c); +} + +static int efi_serial_puts(struct console_device *cdev, const char *s) +{ + struct efi_serial_port *uart = to_efi_serial_port(cdev); + struct efi_serial_io_protocol *serial = uart->serial; + uint32_t control; + efi_status_t efiret; + unsigned long buffersize = strlen(s) * sizeof(char); + + do { + efiret = serial->getcontrol(serial, &control); + if (EFI_ERROR(efiret)) + return 0; + + } while(!(control & EFI_SERIAL_CLEAR_TO_SEND)); + + serial->write(serial, &buffersize, (void*)s); + + return strlen(s); +} + +static int efi_serial_getc(struct console_device *cdev) +{ + struct efi_serial_port *uart = to_efi_serial_port(cdev); + struct efi_serial_io_protocol *serial = uart->serial; + uint32_t control; + efi_status_t efiret; + unsigned long buffersize = sizeof(char); + char c; + + do { + efiret = serial->getcontrol(serial, &control); + if (EFI_ERROR(efiret)) + return (int)-1; + + } while(!(control & EFI_SERIAL_DATA_SET_READY)); + + serial->read(serial, &buffersize, &c); + + return (int)c; +} + +static int efi_serial_tstc(struct console_device *cdev) +{ + struct efi_serial_port *uart = to_efi_serial_port(cdev); + struct efi_serial_io_protocol *serial = uart->serial; + uint32_t control; + efi_status_t efiret; + + efiret = serial->getcontrol(serial, &control); + if (EFI_ERROR(efiret)) + return 0; + + return !(control & EFI_SERIAL_INPUT_BUFFER_EMPTY); +} + +static int efi_serial_probe(struct efi_device *efidev) +{ + struct efi_serial_port *uart; + struct console_device *cdev; + + uart = xzalloc(sizeof(struct efi_serial_port)); + + cdev = &uart->uart; + cdev->dev = &efidev->dev; + cdev->tstc = efi_serial_tstc; + cdev->putc = efi_serial_putc; + cdev->puts = efi_serial_puts; + cdev->getc = efi_serial_getc; + cdev->setbrg = efi_serial_setbaudrate; + + uart->serial = efidev->protocol; + + uart->serial->reset(uart->serial); + + /* Enable UART */ + + console_register(cdev); + + return 0; +} + +static struct efi_driver efi_serial_driver = { + .driver = { + .name = "efi-serial", + }, + .probe = efi_serial_probe, + .guid = EFI_SERIAL_IO_PROTOCOL_GUID, +}; +device_efi_driver(efi_serial_driver); -- 2.11.0 _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2 v2] efi: add serial driver support 2017-03-06 9:34 ` [PATCH 2/2 v2] " Jean-Christophe PLAGNIOL-VILLARD @ 2017-03-07 7:01 ` Sascha Hauer 2017-03-11 16:23 ` Michael Olbrich 1 sibling, 0 replies; 10+ messages in thread From: Sascha Hauer @ 2017-03-07 7:01 UTC (permalink / raw) To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox On Mon, Mar 06, 2017 at 10:34:47AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote: > So now we can stop to use the efi-stdio as this driver > print on the Framebuffer and the serial at the same time. > > This is specially usefull if we want to use the framebuffer via efi-gop for > something else. > > Do not forget to disable the efi-stdio device before enabling the console > otherwise you will get double printing. > > Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> > --- > Fix copyright Replaced with this version. Sascha > > drivers/serial/Kconfig | 4 + > drivers/serial/Makefile | 1 + > drivers/serial/serial_efi.c | 221 ++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 226 insertions(+) > create mode 100644 drivers/serial/serial_efi.c > > diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig > index ced30530a..cfddc2ee9 100644 > --- a/drivers/serial/Kconfig > +++ b/drivers/serial/Kconfig > @@ -21,6 +21,10 @@ config DRIVER_SERIAL_AR933X > If you have an Atheros AR933X SOC based board and want to use the > built-in UART of the SoC, say Y to this option. > > +config DRIVER_SERIAL_EFI > + bool "EFI serial" > + depends on EFI_BOOTUP > + > config DRIVER_SERIAL_IMX > depends on ARCH_IMX > default y > diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile > index 7d1bae195..3d9f735ed 100644 > --- a/drivers/serial/Makefile > +++ b/drivers/serial/Makefile > @@ -1,6 +1,7 @@ > obj-$(CONFIG_DRIVER_SERIAL_ARM_DCC) += arm_dcc.o > obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o > obj-$(CONFIG_DRIVER_SERIAL_AR933X) += serial_ar933x.o > +obj-$(CONFIG_DRIVER_SERIAL_EFI) += serial_efi.o > obj-$(CONFIG_DRIVER_SERIAL_IMX) += serial_imx.o > obj-$(CONFIG_DRIVER_SERIAL_STM378X) += stm-serial.o > obj-$(CONFIG_DRIVER_SERIAL_ATMEL) += atmel.o > diff --git a/drivers/serial/serial_efi.c b/drivers/serial/serial_efi.c > new file mode 100644 > index 000000000..f0a2b22c2 > --- /dev/null > +++ b/drivers/serial/serial_efi.c > @@ -0,0 +1,221 @@ > +/* > + * Copyright (C) 2017 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> > + * > + * Under GPLv2 Only > + */ > + > +#include <common.h> > +#include <driver.h> > +#include <init.h> > +#include <malloc.h> > +#include <efi.h> > +#include <efi/efi.h> > +#include <efi/efi-device.h> > + > +/* > + * define for Control bits, grouped by read only, write only, and read write > + * > + * Read Only > + */ > +#define EFI_SERIAL_CLEAR_TO_SEND 0x00000010 > +#define EFI_SERIAL_DATA_SET_READY 0x00000020 > +#define EFI_SERIAL_RING_INDICATE 0x00000040 > +#define EFI_SERIAL_CARRIER_DETECT 0x00000080 > +#define EFI_SERIAL_INPUT_BUFFER_EMPTY 0x00000100 > +#define EFI_SERIAL_OUTPUT_BUFFER_EMPTY 0x00000200 > + > +/* > + * Write Only > + */ > +#define EFI_SERIAL_REQUEST_TO_SEND 0x00000002 > +#define EFI_SERIAL_DATA_TERMINAL_READY 0x00000001 > + > +/* > + * Read Write > + */ > +#define EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE 0x00001000 > +#define EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE 0x00002000 > +#define EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE 0x00004000 > + > +typedef enum { > + DefaultParity, > + NoParity, > + EvenParity, > + OddParity, > + MarkParity, > + SpaceParity > +} efi_parity_type; > + > +typedef enum { > + DefaultStopBits, > + OneStopBit, > + OneFiveStopBits, > + TwoStopBits > +} efi_stop_bits_type; > + > +struct efi_serial_io_mode { > + uint32_t controlmask; > + uint32_t timeout; > + uint64_t baudrate; > + uint32_t receivefifodepth; > + uint32_t databits; > + uint32_t parity; > + uint32_t stopbits; > +}; > + > +struct efi_serial_io_protocol { > + uint32_t revision; > + > + efi_status_t (EFIAPI *reset) (struct efi_serial_io_protocol *This); > + efi_status_t (EFIAPI *set_attributes) (struct efi_serial_io_protocol *This, > + uint64_t baudrate, uint32_t receivefifodepth, > + uint32_t timeout, efi_parity_type parity, > + uint8_t databits, efi_stop_bits_type stopbits); > + efi_status_t (EFIAPI *setcontrol) (struct efi_serial_io_protocol *This, > + uint32_t control); > + efi_status_t (EFIAPI *getcontrol) (struct efi_serial_io_protocol *This, > + uint32_t *control); > + efi_status_t (EFIAPI *write) (struct efi_serial_io_protocol *This, > + unsigned long *buffersize, void *buffer); > + efi_status_t (EFIAPI *read) (struct efi_serial_io_protocol *This, > + unsigned long *buffersize, void *buffer); > + > + struct efi_serial_io_mode *mode; > +}; > + > +/* > + * We wrap our port structure around the generic console_device. > + */ > +struct efi_serial_port { > + struct efi_serial_io_protocol *serial; > + struct console_device uart; /* uart */ > + struct efi_device *efidev; > +}; > + > +static inline struct efi_serial_port * > +to_efi_serial_port(struct console_device *uart) > +{ > + return container_of(uart, struct efi_serial_port, uart); > +} > + > +static int efi_serial_setbaudrate(struct console_device *cdev, int baudrate) > +{ > + struct efi_serial_port *uart = to_efi_serial_port(cdev); > + struct efi_serial_io_protocol *serial = uart->serial; > + efi_status_t efiret; > + > + efiret = serial->set_attributes(serial, baudrate, 0, 0, NoParity, 8, > + OneStopBit); > + if (EFI_ERROR(efiret)) > + return -efi_errno(efiret); > + > + return 0; > +} > + > +static void efi_serial_putc(struct console_device *cdev, char c) > +{ > + struct efi_serial_port *uart = to_efi_serial_port(cdev); > + struct efi_serial_io_protocol *serial = uart->serial; > + uint32_t control; > + efi_status_t efiret; > + unsigned long buffersize = sizeof(char); > + > + do { > + efiret = serial->getcontrol(serial, &control); > + if (EFI_ERROR(efiret)) > + return; > + > + } while(!(control & EFI_SERIAL_CLEAR_TO_SEND)); > + > + serial->write(serial, &buffersize, &c); > +} > + > +static int efi_serial_puts(struct console_device *cdev, const char *s) > +{ > + struct efi_serial_port *uart = to_efi_serial_port(cdev); > + struct efi_serial_io_protocol *serial = uart->serial; > + uint32_t control; > + efi_status_t efiret; > + unsigned long buffersize = strlen(s) * sizeof(char); > + > + do { > + efiret = serial->getcontrol(serial, &control); > + if (EFI_ERROR(efiret)) > + return 0; > + > + } while(!(control & EFI_SERIAL_CLEAR_TO_SEND)); > + > + serial->write(serial, &buffersize, (void*)s); > + > + return strlen(s); > +} > + > +static int efi_serial_getc(struct console_device *cdev) > +{ > + struct efi_serial_port *uart = to_efi_serial_port(cdev); > + struct efi_serial_io_protocol *serial = uart->serial; > + uint32_t control; > + efi_status_t efiret; > + unsigned long buffersize = sizeof(char); > + char c; > + > + do { > + efiret = serial->getcontrol(serial, &control); > + if (EFI_ERROR(efiret)) > + return (int)-1; > + > + } while(!(control & EFI_SERIAL_DATA_SET_READY)); > + > + serial->read(serial, &buffersize, &c); > + > + return (int)c; > +} > + > +static int efi_serial_tstc(struct console_device *cdev) > +{ > + struct efi_serial_port *uart = to_efi_serial_port(cdev); > + struct efi_serial_io_protocol *serial = uart->serial; > + uint32_t control; > + efi_status_t efiret; > + > + efiret = serial->getcontrol(serial, &control); > + if (EFI_ERROR(efiret)) > + return 0; > + > + return !(control & EFI_SERIAL_INPUT_BUFFER_EMPTY); > +} > + > +static int efi_serial_probe(struct efi_device *efidev) > +{ > + struct efi_serial_port *uart; > + struct console_device *cdev; > + > + uart = xzalloc(sizeof(struct efi_serial_port)); > + > + cdev = &uart->uart; > + cdev->dev = &efidev->dev; > + cdev->tstc = efi_serial_tstc; > + cdev->putc = efi_serial_putc; > + cdev->puts = efi_serial_puts; > + cdev->getc = efi_serial_getc; > + cdev->setbrg = efi_serial_setbaudrate; > + > + uart->serial = efidev->protocol; > + > + uart->serial->reset(uart->serial); > + > + /* Enable UART */ > + > + console_register(cdev); > + > + return 0; > +} > + > +static struct efi_driver efi_serial_driver = { > + .driver = { > + .name = "efi-serial", > + }, > + .probe = efi_serial_probe, > + .guid = EFI_SERIAL_IO_PROTOCOL_GUID, > +}; > +device_efi_driver(efi_serial_driver); > -- > 2.11.0 > > > _______________________________________________ > barebox mailing list > barebox@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/barebox > -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2 v2] efi: add serial driver support 2017-03-06 9:34 ` [PATCH 2/2 v2] " Jean-Christophe PLAGNIOL-VILLARD 2017-03-07 7:01 ` Sascha Hauer @ 2017-03-11 16:23 ` Michael Olbrich 2017-03-12 12:07 ` Jean-Christophe PLAGNIOL-VILLARD 1 sibling, 1 reply; 10+ messages in thread From: Michael Olbrich @ 2017-03-11 16:23 UTC (permalink / raw) To: barebox On Mon, Mar 06, 2017 at 10:34:47AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote: > So now we can stop to use the efi-stdio as this driver > print on the Framebuffer and the serial at the same time. > > This is specially usefull if we want to use the framebuffer via efi-gop for > something else. > > Do not forget to disable the efi-stdio device before enabling the console > otherwise you will get double printing. Works nicely here (with a unrelated fix). However, it might be better to implement this as a console_platform_driver. The efi drivers are loaded rather late during startup and this makes early debugging impossible. Michael > Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> > --- > Fix copyright > > drivers/serial/Kconfig | 4 + > drivers/serial/Makefile | 1 + > drivers/serial/serial_efi.c | 221 ++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 226 insertions(+) > create mode 100644 drivers/serial/serial_efi.c > > diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig > index ced30530a..cfddc2ee9 100644 > --- a/drivers/serial/Kconfig > +++ b/drivers/serial/Kconfig > @@ -21,6 +21,10 @@ config DRIVER_SERIAL_AR933X > If you have an Atheros AR933X SOC based board and want to use the > built-in UART of the SoC, say Y to this option. > > +config DRIVER_SERIAL_EFI > + bool "EFI serial" > + depends on EFI_BOOTUP > + > config DRIVER_SERIAL_IMX > depends on ARCH_IMX > default y > diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile > index 7d1bae195..3d9f735ed 100644 > --- a/drivers/serial/Makefile > +++ b/drivers/serial/Makefile > @@ -1,6 +1,7 @@ > obj-$(CONFIG_DRIVER_SERIAL_ARM_DCC) += arm_dcc.o > obj-$(CONFIG_SERIAL_AMBA_PL011) += amba-pl011.o > obj-$(CONFIG_DRIVER_SERIAL_AR933X) += serial_ar933x.o > +obj-$(CONFIG_DRIVER_SERIAL_EFI) += serial_efi.o > obj-$(CONFIG_DRIVER_SERIAL_IMX) += serial_imx.o > obj-$(CONFIG_DRIVER_SERIAL_STM378X) += stm-serial.o > obj-$(CONFIG_DRIVER_SERIAL_ATMEL) += atmel.o > diff --git a/drivers/serial/serial_efi.c b/drivers/serial/serial_efi.c > new file mode 100644 > index 000000000..f0a2b22c2 > --- /dev/null > +++ b/drivers/serial/serial_efi.c > @@ -0,0 +1,221 @@ > +/* > + * Copyright (C) 2017 Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> > + * > + * Under GPLv2 Only > + */ > + > +#include <common.h> > +#include <driver.h> > +#include <init.h> > +#include <malloc.h> > +#include <efi.h> > +#include <efi/efi.h> > +#include <efi/efi-device.h> > + > +/* > + * define for Control bits, grouped by read only, write only, and read write > + * > + * Read Only > + */ > +#define EFI_SERIAL_CLEAR_TO_SEND 0x00000010 > +#define EFI_SERIAL_DATA_SET_READY 0x00000020 > +#define EFI_SERIAL_RING_INDICATE 0x00000040 > +#define EFI_SERIAL_CARRIER_DETECT 0x00000080 > +#define EFI_SERIAL_INPUT_BUFFER_EMPTY 0x00000100 > +#define EFI_SERIAL_OUTPUT_BUFFER_EMPTY 0x00000200 > + > +/* > + * Write Only > + */ > +#define EFI_SERIAL_REQUEST_TO_SEND 0x00000002 > +#define EFI_SERIAL_DATA_TERMINAL_READY 0x00000001 > + > +/* > + * Read Write > + */ > +#define EFI_SERIAL_HARDWARE_LOOPBACK_ENABLE 0x00001000 > +#define EFI_SERIAL_SOFTWARE_LOOPBACK_ENABLE 0x00002000 > +#define EFI_SERIAL_HARDWARE_FLOW_CONTROL_ENABLE 0x00004000 > + > +typedef enum { > + DefaultParity, > + NoParity, > + EvenParity, > + OddParity, > + MarkParity, > + SpaceParity > +} efi_parity_type; > + > +typedef enum { > + DefaultStopBits, > + OneStopBit, > + OneFiveStopBits, > + TwoStopBits > +} efi_stop_bits_type; > + > +struct efi_serial_io_mode { > + uint32_t controlmask; > + uint32_t timeout; > + uint64_t baudrate; > + uint32_t receivefifodepth; > + uint32_t databits; > + uint32_t parity; > + uint32_t stopbits; > +}; > + > +struct efi_serial_io_protocol { > + uint32_t revision; > + > + efi_status_t (EFIAPI *reset) (struct efi_serial_io_protocol *This); > + efi_status_t (EFIAPI *set_attributes) (struct efi_serial_io_protocol *This, > + uint64_t baudrate, uint32_t receivefifodepth, > + uint32_t timeout, efi_parity_type parity, > + uint8_t databits, efi_stop_bits_type stopbits); > + efi_status_t (EFIAPI *setcontrol) (struct efi_serial_io_protocol *This, > + uint32_t control); > + efi_status_t (EFIAPI *getcontrol) (struct efi_serial_io_protocol *This, > + uint32_t *control); > + efi_status_t (EFIAPI *write) (struct efi_serial_io_protocol *This, > + unsigned long *buffersize, void *buffer); > + efi_status_t (EFIAPI *read) (struct efi_serial_io_protocol *This, > + unsigned long *buffersize, void *buffer); > + > + struct efi_serial_io_mode *mode; > +}; > + > +/* > + * We wrap our port structure around the generic console_device. > + */ > +struct efi_serial_port { > + struct efi_serial_io_protocol *serial; > + struct console_device uart; /* uart */ > + struct efi_device *efidev; > +}; > + > +static inline struct efi_serial_port * > +to_efi_serial_port(struct console_device *uart) > +{ > + return container_of(uart, struct efi_serial_port, uart); > +} > + > +static int efi_serial_setbaudrate(struct console_device *cdev, int baudrate) > +{ > + struct efi_serial_port *uart = to_efi_serial_port(cdev); > + struct efi_serial_io_protocol *serial = uart->serial; > + efi_status_t efiret; > + > + efiret = serial->set_attributes(serial, baudrate, 0, 0, NoParity, 8, > + OneStopBit); > + if (EFI_ERROR(efiret)) > + return -efi_errno(efiret); > + > + return 0; > +} > + > +static void efi_serial_putc(struct console_device *cdev, char c) > +{ > + struct efi_serial_port *uart = to_efi_serial_port(cdev); > + struct efi_serial_io_protocol *serial = uart->serial; > + uint32_t control; > + efi_status_t efiret; > + unsigned long buffersize = sizeof(char); > + > + do { > + efiret = serial->getcontrol(serial, &control); > + if (EFI_ERROR(efiret)) > + return; > + > + } while(!(control & EFI_SERIAL_CLEAR_TO_SEND)); > + > + serial->write(serial, &buffersize, &c); > +} > + > +static int efi_serial_puts(struct console_device *cdev, const char *s) > +{ > + struct efi_serial_port *uart = to_efi_serial_port(cdev); > + struct efi_serial_io_protocol *serial = uart->serial; > + uint32_t control; > + efi_status_t efiret; > + unsigned long buffersize = strlen(s) * sizeof(char); > + > + do { > + efiret = serial->getcontrol(serial, &control); > + if (EFI_ERROR(efiret)) > + return 0; > + > + } while(!(control & EFI_SERIAL_CLEAR_TO_SEND)); > + > + serial->write(serial, &buffersize, (void*)s); > + > + return strlen(s); > +} > + > +static int efi_serial_getc(struct console_device *cdev) > +{ > + struct efi_serial_port *uart = to_efi_serial_port(cdev); > + struct efi_serial_io_protocol *serial = uart->serial; > + uint32_t control; > + efi_status_t efiret; > + unsigned long buffersize = sizeof(char); > + char c; > + > + do { > + efiret = serial->getcontrol(serial, &control); > + if (EFI_ERROR(efiret)) > + return (int)-1; > + > + } while(!(control & EFI_SERIAL_DATA_SET_READY)); > + > + serial->read(serial, &buffersize, &c); > + > + return (int)c; > +} > + > +static int efi_serial_tstc(struct console_device *cdev) > +{ > + struct efi_serial_port *uart = to_efi_serial_port(cdev); > + struct efi_serial_io_protocol *serial = uart->serial; > + uint32_t control; > + efi_status_t efiret; > + > + efiret = serial->getcontrol(serial, &control); > + if (EFI_ERROR(efiret)) > + return 0; > + > + return !(control & EFI_SERIAL_INPUT_BUFFER_EMPTY); > +} > + > +static int efi_serial_probe(struct efi_device *efidev) > +{ > + struct efi_serial_port *uart; > + struct console_device *cdev; > + > + uart = xzalloc(sizeof(struct efi_serial_port)); > + > + cdev = &uart->uart; > + cdev->dev = &efidev->dev; > + cdev->tstc = efi_serial_tstc; > + cdev->putc = efi_serial_putc; > + cdev->puts = efi_serial_puts; > + cdev->getc = efi_serial_getc; > + cdev->setbrg = efi_serial_setbaudrate; > + > + uart->serial = efidev->protocol; > + > + uart->serial->reset(uart->serial); > + > + /* Enable UART */ > + > + console_register(cdev); > + > + return 0; > +} > + > +static struct efi_driver efi_serial_driver = { > + .driver = { > + .name = "efi-serial", > + }, > + .probe = efi_serial_probe, > + .guid = EFI_SERIAL_IO_PROTOCOL_GUID, > +}; > +device_efi_driver(efi_serial_driver); > -- > 2.11.0 > > > _______________________________________________ > barebox mailing list > barebox@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/barebox > -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 2/2 v2] efi: add serial driver support 2017-03-11 16:23 ` Michael Olbrich @ 2017-03-12 12:07 ` Jean-Christophe PLAGNIOL-VILLARD 0 siblings, 0 replies; 10+ messages in thread From: Jean-Christophe PLAGNIOL-VILLARD @ 2017-03-12 12:07 UTC (permalink / raw) To: barebox On 17:23 Sat 11 Mar , Michael Olbrich wrote: > On Mon, Mar 06, 2017 at 10:34:47AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote: > > So now we can stop to use the efi-stdio as this driver > > print on the Framebuffer and the serial at the same time. > > > > This is specially usefull if we want to use the framebuffer via efi-gop for > > something else. > > > > Do not forget to disable the efi-stdio device before enabling the console > > otherwise you will get double printing. > > Works nicely here (with a unrelated fix). However, it might be better to > implement this as a console_platform_driver. The efi drivers are loaded > rather late during startup and this makes early debugging impossible. I did not did it as you can use efi-stdio as early as possible but we can take a look to probe it earlier Best Regards, J. _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] video: add EFI Graphics Output Protocol support 2017-03-06 5:04 ` [PATCH 1/2] video: add EFI Graphics Output Protocol support Jean-Christophe PLAGNIOL-VILLARD 2017-03-06 5:04 ` [PATCH 2/2] efi: add serial driver support Jean-Christophe PLAGNIOL-VILLARD @ 2017-03-09 8:46 ` Michael Olbrich 2017-03-09 8:49 ` Jean-Christophe PLAGNIOL-VILLARD 1 sibling, 1 reply; 10+ messages in thread From: Michael Olbrich @ 2017-03-09 8:46 UTC (permalink / raw) To: barebox On Mon, Mar 06, 2017 at 06:04:10AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote: > Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> > --- > drivers/video/Kconfig | 4 + > drivers/video/Makefile | 2 + > drivers/video/efi_gop.c | 267 ++++++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 273 insertions(+) > create mode 100644 drivers/video/efi_gop.c > [...] > diff --git a/drivers/video/efi_gop.c b/drivers/video/efi_gop.c > new file mode 100644 > index 000000000..ccb4af3d9 [...] > +static struct fb_ops efi_gop_ops = { > + .fb_activate_var = efi_gop_fb_activate_var, > +}; This is missing the fb_enable/fb_disable callbacks. Both are not optional. The framebuffer console is broken without this. Michael -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 1/2] video: add EFI Graphics Output Protocol support 2017-03-09 8:46 ` [PATCH 1/2] video: add EFI Graphics Output Protocol support Michael Olbrich @ 2017-03-09 8:49 ` Jean-Christophe PLAGNIOL-VILLARD 0 siblings, 0 replies; 10+ messages in thread From: Jean-Christophe PLAGNIOL-VILLARD @ 2017-03-09 8:49 UTC (permalink / raw) To: Michael Olbrich; +Cc: barebox > On Mar 9, 2017, at 4:46 PM, Michael Olbrich <m.olbrich@pengutronix.de> wrote: > > On Mon, Mar 06, 2017 at 06:04:10AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote: >> Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com> >> --- >> drivers/video/Kconfig | 4 + >> drivers/video/Makefile | 2 + >> drivers/video/efi_gop.c | 267 ++++++++++++++++++++++++++++++++++++++++++++++++ >> 3 files changed, 273 insertions(+) >> create mode 100644 drivers/video/efi_gop.c >> > [...] >> diff --git a/drivers/video/efi_gop.c b/drivers/video/efi_gop.c >> new file mode 100644 >> index 000000000..ccb4af3d9 > [...] >> +static struct fb_ops efi_gop_ops = { >> + .fb_activate_var = efi_gop_fb_activate_var, >> +}; > > This is missing the fb_enable/fb_disable callbacks. Both are not optional. > The framebuffer console is broken without this. you can not enable or disable them so this need to be fix at framework level not driver Best Regards, J. > > Michael > > > -- > Pengutronix e.K. | | > Industrial Linux Solutions | http://www.pengutronix.de/ | > Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | > Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | > > _______________________________________________ > barebox mailing list > barebox@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/barebox _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 0/2] add support of efi Serial IO and Graphics Output Protocol 2017-03-06 5:02 [PATCH 0/2] add support of efi Serial IO and Graphics Output Protocol Jean-Christophe PLAGNIOL-VILLARD 2017-03-06 5:04 ` [PATCH 1/2] video: add EFI Graphics Output Protocol support Jean-Christophe PLAGNIOL-VILLARD @ 2017-03-06 8:18 ` Sascha Hauer 1 sibling, 0 replies; 10+ messages in thread From: Sascha Hauer @ 2017-03-06 8:18 UTC (permalink / raw) To: Jean-Christophe PLAGNIOL-VILLARD; +Cc: barebox On Mon, Mar 06, 2017 at 06:02:11AM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote: > Hi, > > The following changes since commit d92ed454107b4d6f0d30fa0271da191ae5911d18: > > Merge branch 'for-next/video' into next (2017-02-27 08:51:08 +0100) > > are available in the git repository at: > > git://git.jcrosoft.org/barebox.git delivery/serial-gop > > for you to fetch changes up to 6ecbe33539f20076bbc781b9e20a5a54d504fdf3: > > efi: add serial driver support (2017-03-01 22:11:37 +0800) Applied, thanks Sascha > > ---------------------------------------------------------------- > Jean-Christophe PLAGNIOL-VILLARD (2): > video: add EFI Graphics Output Protocol support > efi: add serial driver support > > drivers/serial/Kconfig | 4 +++ > drivers/serial/Makefile | 1 + > drivers/serial/serial_efi.c | 241 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > drivers/video/Kconfig | 4 +++ > drivers/video/Makefile | 2 ++ > drivers/video/efi_gop.c | 267 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > 6 files changed, 519 insertions(+) > create mode 100644 drivers/serial/serial_efi.c > create mode 100644 drivers/video/efi_gop.c > > Best Regards, > J. > > _______________________________________________ > barebox mailing list > barebox@lists.infradead.org > http://lists.infradead.org/mailman/listinfo/barebox > -- Pengutronix e.K. | | Industrial Linux Solutions | http://www.pengutronix.de/ | Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0 | Amtsgericht Hildesheim, HRA 2686 | Fax: +49-5121-206917-5555 | _______________________________________________ barebox mailing list barebox@lists.infradead.org http://lists.infradead.org/mailman/listinfo/barebox ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2017-03-12 12:02 UTC | newest] Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2017-03-06 5:02 [PATCH 0/2] add support of efi Serial IO and Graphics Output Protocol Jean-Christophe PLAGNIOL-VILLARD 2017-03-06 5:04 ` [PATCH 1/2] video: add EFI Graphics Output Protocol support Jean-Christophe PLAGNIOL-VILLARD 2017-03-06 5:04 ` [PATCH 2/2] efi: add serial driver support Jean-Christophe PLAGNIOL-VILLARD 2017-03-06 9:34 ` [PATCH 2/2 v2] " Jean-Christophe PLAGNIOL-VILLARD 2017-03-07 7:01 ` Sascha Hauer 2017-03-11 16:23 ` Michael Olbrich 2017-03-12 12:07 ` Jean-Christophe PLAGNIOL-VILLARD 2017-03-09 8:46 ` [PATCH 1/2] video: add EFI Graphics Output Protocol support Michael Olbrich 2017-03-09 8:49 ` Jean-Christophe PLAGNIOL-VILLARD 2017-03-06 8:18 ` [PATCH 0/2] add support of efi Serial IO and Graphics Output Protocol Sascha Hauer
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox