summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorkettenis <kettenis@openbsd.org>2019-10-25 10:06:40 +0000
committerkettenis <kettenis@openbsd.org>2019-10-25 10:06:40 +0000
commit48816fc0f01af5080cf6fe852b1d10c6abe8a211 (patch)
tree69282c31f297372b1b1c5de2e7ae960685fbfe9f
parentifname in opentap() is not optional (diff)
downloadwireguard-openbsd-48816fc0f01af5080cf6fe852b1d10c6abe8a211.tar.xz
wireguard-openbsd-48816fc0f01af5080cf6fe852b1d10c6abe8a211.zip
Make it possible to switch to framebuffer "glass" console in case it
isn't the default already. Same change as we made on arm64 two months ago. ok patrick@
-rw-r--r--sys/arch/armv7/stand/efiboot/Makefile4
-rw-r--r--sys/arch/armv7/stand/efiboot/conf.c5
-rw-r--r--sys/arch/armv7/stand/efiboot/efiboot.c186
-rw-r--r--sys/arch/armv7/stand/efiboot/efiboot.h6
-rw-r--r--sys/arch/armv7/stand/efiboot/fdt.c71
-rw-r--r--sys/arch/armv7/stand/efiboot/fdt.h5
6 files changed, 266 insertions, 11 deletions
diff --git a/sys/arch/armv7/stand/efiboot/Makefile b/sys/arch/armv7/stand/efiboot/Makefile
index 9b054df13a8..43f78b723ec 100644
--- a/sys/arch/armv7/stand/efiboot/Makefile
+++ b/sys/arch/armv7/stand/efiboot/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.12 2019/08/03 15:22:20 deraadt Exp $
+# $OpenBSD: Makefile,v 1.13 2019/10/25 10:06:40 kettenis Exp $
NOMAN= #
@@ -34,7 +34,7 @@ SRCS+= ufs.c
SRCS+= arp.c ether.c globals.c in_cksum.c net.c netif.c netudp.c tftp.c
.PATH: ${S}/lib/libkern/arch/arm ${S}/lib/libkern
-SRCS+= divsi3.S divdi3.c moddi3.c qdivrem.c strlcpy.c strlen.c
+SRCS+= divsi3.S divdi3.c moddi3.c qdivrem.c strlcat.c strlcpy.c strlen.c
SRCS+= __aeabi_ldivmod.S
.PATH: ${S}/lib/libz
diff --git a/sys/arch/armv7/stand/efiboot/conf.c b/sys/arch/armv7/stand/efiboot/conf.c
index e0615de7a3a..b107e4009ca 100644
--- a/sys/arch/armv7/stand/efiboot/conf.c
+++ b/sys/arch/armv7/stand/efiboot/conf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.c,v 1.19 2019/08/13 09:00:20 patrick Exp $ */
+/* $OpenBSD: conf.c,v 1.20 2019/10/25 10:06:40 kettenis Exp $ */
/*
* Copyright (c) 1996 Michael Shalayeff
@@ -36,7 +36,7 @@
#include "efidev.h"
#include "efipxe.h"
-const char version[] = "1.6";
+const char version[] = "1.7";
int debug = 0;
struct fs_ops file_system[] = {
@@ -57,6 +57,7 @@ int ndevs = nitems(devsw);
struct consdev constab[] = {
{ efi_cons_probe, efi_cons_init, efi_cons_getc, efi_cons_putc },
+ { efi_fb_probe, efi_fb_init, efi_cons_getc, efi_cons_putc },
{ NULL }
};
struct consdev *cn_tab;
diff --git a/sys/arch/armv7/stand/efiboot/efiboot.c b/sys/arch/armv7/stand/efiboot/efiboot.c
index f6ccb141b87..b26734ca581 100644
--- a/sys/arch/armv7/stand/efiboot/efiboot.c
+++ b/sys/arch/armv7/stand/efiboot/efiboot.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: efiboot.c,v 1.24 2019/04/25 20:19:30 naddy Exp $ */
+/* $OpenBSD: efiboot.c,v 1.25 2019/10/25 10:06:40 kettenis Exp $ */
/*
* Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
@@ -52,6 +52,7 @@ UINT32 mmap_version;
static EFI_GUID imgp_guid = LOADED_IMAGE_PROTOCOL;
static EFI_GUID blkio_guid = BLOCK_IO_PROTOCOL;
static EFI_GUID devp_guid = DEVICE_PATH_PROTOCOL;
+static EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID;
int efi_device_path_depth(EFI_DEVICE_PATH *dp, int);
int efi_device_path_ncmp(EFI_DEVICE_PATH *, EFI_DEVICE_PATH *, int);
@@ -94,11 +95,19 @@ efi_main(EFI_HANDLE image, EFI_SYSTEM_TABLE *systab)
static SIMPLE_TEXT_OUTPUT_INTERFACE *conout;
static SIMPLE_INPUT_INTERFACE *conin;
+/*
+ * The device majors for these don't match the ones used by the
+ * kernel. That's fine. They're just used as an index into the cdevs
+ * array and never passed on to the kernel.
+ */
+static dev_t serial = makedev(0, 0);
+static dev_t framebuffer = makedev(1, 0);
+
void
efi_cons_probe(struct consdev *cn)
{
cn->cn_pri = CN_MIDPRI;
- cn->cn_dev = makedev(12, 0);
+ cn->cn_dev = serial;
}
void
@@ -159,6 +168,32 @@ efi_cons_putc(dev_t dev, int c)
conout->OutputString(conout, buf);
}
+void
+efi_fb_probe(struct consdev *cn)
+{
+ cn->cn_pri = CN_LOWPRI;
+ cn->cn_dev = framebuffer;
+}
+
+void
+efi_fb_init(struct consdev *cn)
+{
+ conin = ST->ConIn;
+ conout = ST->ConOut;
+}
+
+int
+efi_fb_getc(dev_t dev)
+{
+ return efi_cons_getc(dev);
+}
+
+void
+efi_fb_putc(dev_t dev, int c)
+{
+ efi_cons_putc(dev, c);
+}
+
static void
efi_heap_init(void)
{
@@ -285,6 +320,130 @@ struct board_id board_id_table[] = {
{ "ti,omap4-panda", 2791 },
};
+void
+efi_framebuffer(void)
+{
+ EFI_GRAPHICS_OUTPUT *gop;
+ EFI_STATUS status;
+ void *node, *child;
+ uint32_t acells, scells;
+ uint64_t base, size;
+ uint32_t reg[4];
+ uint32_t width, height, stride;
+ char *format;
+ char *prop;
+
+ /*
+ * Don't create a "simple-framebuffer" node if we already have
+ * one. Besides "/chosen", we also check under "/" since that
+ * is where the Raspberry Pi firmware puts it.
+ */
+ node = fdt_find_node("/chosen");
+ for (child = fdt_child_node(node); child;
+ child = fdt_next_node(child)) {
+ if (!fdt_node_is_compatible(child, "simple-framebuffer"))
+ continue;
+ if (fdt_node_property(child, "status", &prop) &&
+ strcmp(prop, "okay") == 0)
+ return;
+ }
+ node = fdt_find_node("/");
+ for (child = fdt_child_node(node); child;
+ child = fdt_next_node(child)) {
+ if (!fdt_node_is_compatible(child, "simple-framebuffer"))
+ continue;
+ if (fdt_node_property(child, "status", &prop) &&
+ strcmp(prop, "okay") == 0)
+ return;
+ }
+
+ status = EFI_CALL(BS->LocateProtocol, &gop_guid, NULL, (void **)&gop);
+ if (status != EFI_SUCCESS)
+ return;
+
+ /* Paranoia! */
+ if (gop == NULL || gop->Mode == NULL || gop->Mode->Info == NULL)
+ return;
+
+ /* We only support 32-bit pixel modes for now. */
+ switch (gop->Mode->Info->PixelFormat) {
+ case PixelRedGreenBlueReserved8BitPerColor:
+ format = "x8b8g8r8";
+ break;
+ case PixelBlueGreenRedReserved8BitPerColor:
+ format = "x8r8g8b8";
+ break;
+ default:
+ return;
+ }
+
+ base = gop->Mode->FrameBufferBase;
+ size = gop->Mode->FrameBufferSize;
+ width = htobe32(gop->Mode->Info->HorizontalResolution);
+ height = htobe32(gop->Mode->Info->VerticalResolution);
+ stride = htobe32(gop->Mode->Info->PixelsPerScanLine * 4);
+
+ node = fdt_find_node("/");
+ if (fdt_node_property_int(node, "#address-cells", &acells) != 1)
+ acells = 1;
+ if (fdt_node_property_int(node, "#size-cells", &scells) != 1)
+ scells = 1;
+ if (acells > 2 || scells > 2)
+ return;
+ if (acells >= 1)
+ reg[0] = htobe32(base);
+ if (acells == 2) {
+ reg[1] = reg[0];
+ reg[0] = htobe32(base >> 32);
+ }
+ if (scells >= 1)
+ reg[acells] = htobe32(size);
+ if (scells == 2) {
+ reg[acells + 1] = reg[acells];
+ reg[acells] = htobe32(size >> 32);
+ }
+
+ node = fdt_find_node("/chosen");
+ fdt_node_add_node(node, "framebuffer", &child);
+ fdt_node_add_property(child, "status", "okay", strlen("okay") + 1);
+ fdt_node_add_property(child, "format", format, strlen(format) + 1);
+ fdt_node_add_property(child, "stride", &stride, 4);
+ fdt_node_add_property(child, "height", &height, 4);
+ fdt_node_add_property(child, "width", &width, 4);
+ fdt_node_add_property(child, "reg", reg, (acells + scells) * 4);
+ fdt_node_add_property(child, "compatible",
+ "simple-framebuffer", strlen("simple-framebuffer") + 1);
+}
+
+void
+efi_console(void)
+{
+ char path[128];
+ void *node, *child;
+ char *prop;
+
+ if (cn_tab->cn_dev != framebuffer)
+ return;
+
+ /* Find the desired framebuffer node. */
+ node = fdt_find_node("/chosen");
+ for (child = fdt_child_node(node); child;
+ child = fdt_next_node(child)) {
+ if (!fdt_node_is_compatible(child, "simple-framebuffer"))
+ continue;
+ if (fdt_node_property(child, "status", &prop) &&
+ strcmp(prop, "okay") == 0)
+ break;
+ }
+ if (child == NULL)
+ return;
+
+ /* Point stdout-path at the framebuffer node. */
+ strlcpy(path, "/chosen/", sizeof(path));
+ strlcat(path, fdt_node_name(child), sizeof(path));
+ fdt_node_add_property(node, "stdout-path", path, strlen(path) + 1);
+}
+
char *bootmac = NULL;
static EFI_GUID fdt_guid = FDT_TABLE_GUID;
@@ -338,6 +497,9 @@ efi_makebootargs(char *bootargs, uint32_t *board_id)
fdt_node_add_property(node, "openbsd,uefi-mmap-desc-size", zero, 4);
fdt_node_add_property(node, "openbsd,uefi-mmap-desc-ver", zero, 4);
+ efi_framebuffer();
+ efi_console();
+
fdt_finalize();
node = fdt_find_node("/");
@@ -506,21 +668,39 @@ devboot(dev_t dev, char *p)
strlcpy(p, "tftp0a", 7);
}
+const char cdevs[][4] = { "com", "fb" };
+const int ncdevs = nitems(cdevs);
+
int
cnspeed(dev_t dev, int sp)
{
return 115200;
}
+char ttyname_buf[8];
+
char *
ttyname(int fd)
{
- return "com0";
+ snprintf(ttyname_buf, sizeof ttyname_buf, "%s%d",
+ cdevs[major(cn_tab->cn_dev)], minor(cn_tab->cn_dev));
+
+ return ttyname_buf;
}
dev_t
ttydev(char *name)
{
+ int i, unit = -1;
+ char *no = name + strlen(name) - 1;
+
+ while (no >= name && *no >= '0' && *no <= '9')
+ unit = (unit < 0 ? 0 : (unit * 10)) + *no-- - '0';
+ if (no < name || unit < 0)
+ return NODEV;
+ for (i = 0; i < ncdevs; i++)
+ if (strncmp(name, cdevs[i], no - name + 1) == 0)
+ return makedev(i, unit);
return NODEV;
}
diff --git a/sys/arch/armv7/stand/efiboot/efiboot.h b/sys/arch/armv7/stand/efiboot/efiboot.h
index 166be1c0526..b478d15c602 100644
--- a/sys/arch/armv7/stand/efiboot/efiboot.h
+++ b/sys/arch/armv7/stand/efiboot/efiboot.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: efiboot.h,v 1.4 2018/03/31 18:19:12 patrick Exp $ */
+/* $OpenBSD: efiboot.h,v 1.5 2019/10/25 10:06:40 kettenis Exp $ */
/*
* Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
@@ -24,3 +24,7 @@ void efi_cons_probe(struct consdev *);
void efi_cons_init(struct consdev *);
int efi_cons_getc(dev_t);
void efi_cons_putc(dev_t, int);
+void efi_fb_probe(struct consdev *);
+void efi_fb_init(struct consdev *);
+int efi_fb_getc(dev_t);
+void efi_fb_putc(dev_t, int);
diff --git a/sys/arch/armv7/stand/efiboot/fdt.c b/sys/arch/armv7/stand/efiboot/fdt.c
index 7c1ba49f249..df353f696a3 100644
--- a/sys/arch/armv7/stand/efiboot/fdt.c
+++ b/sys/arch/armv7/stand/efiboot/fdt.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: fdt.c,v 1.5 2017/05/07 11:25:58 kettenis Exp $ */
+/* $OpenBSD: fdt.c,v 1.6 2019/10/25 10:06:40 kettenis Exp $ */
/*
* Copyright (c) 2009 Dariusz Swiderski <sfires@sfires.net>
@@ -148,7 +148,8 @@ fdt_add_str(char *name)
if (tree.memory > tree.strings)
tree.memory += len;
tree.end += len;
- memcpy(end, name, len);
+ memset(end, 0, len);
+ memcpy(end, name, strlen(name));
return (end - tree.strings);
}
@@ -293,6 +294,43 @@ fdt_node_add_property(void *node, char *name, void *data, int len)
return fdt_node_set_property(node, name, data, len);
}
+int
+fdt_node_add_node(void *node, char *name, void **child)
+{
+ size_t len = roundup(strlen(name) + 1, sizeof(uint32_t)) + 8;
+ uint32_t *ptr = (uint32_t *)node;
+
+ if (!tree_inited)
+ return 0;
+
+ if (betoh32(*ptr) != FDT_NODE_BEGIN)
+ return 0;
+
+ ptr = skip_node_name(ptr + 1);
+ ptr = skip_props(ptr);
+
+ /* skip children */
+ while (betoh32(*ptr) == FDT_NODE_BEGIN)
+ ptr = skip_node(ptr);
+
+ memmove((char *)ptr + len, ptr, tree.end - (char *)ptr);
+ tree.struct_size += len;
+ if (tree.strings > tree.tree)
+ tree.strings += len;
+ if (tree.memory > tree.tree)
+ tree.memory += len;
+ tree.end += len;
+
+ *child = ptr;
+ *ptr++ = htobe32(FDT_NODE_BEGIN);
+ memset(ptr, 0, len - 8);
+ memcpy(ptr, name, strlen(name));
+ ptr += (len - 8) / sizeof(uint32_t);
+ *ptr++ = htobe32(FDT_NODE_END);
+
+ return 1;
+}
+
/*
* Retrieves next node, skipping all the children nodes of the pointed node,
* returns pointer to next node, no matter if it exists or not.
@@ -356,6 +394,35 @@ fdt_next_node(void *node)
}
/*
+ * Retrieves node property as integers and puts them in the given
+ * integer array.
+ */
+int
+fdt_node_property_ints(void *node, char *name, int *out, int outlen)
+{
+ int *data;
+ int i, inlen;
+
+ inlen = fdt_node_property(node, name, (char **)&data) / sizeof(int);
+ if (inlen <= 0)
+ return -1;
+
+ for (i = 0; i < inlen && i < outlen; i++)
+ out[i] = betoh32(data[i]);
+
+ return i;
+}
+
+/*
+ * Retrieves node property as an integer.
+ */
+int
+fdt_node_property_int(void *node, char *name, int *out)
+{
+ return fdt_node_property_ints(node, name, out, 1);
+}
+
+/*
* Retrieves next node, skipping all the children nodes of the pointed node
*/
void *
diff --git a/sys/arch/armv7/stand/efiboot/fdt.h b/sys/arch/armv7/stand/efiboot/fdt.h
index 747cf7c29ed..8e9f7eccd2c 100644
--- a/sys/arch/armv7/stand/efiboot/fdt.h
+++ b/sys/arch/armv7/stand/efiboot/fdt.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: fdt.h,v 1.3 2017/05/07 11:25:58 kettenis Exp $ */
+/* $OpenBSD: fdt.h,v 1.4 2019/10/25 10:06:40 kettenis Exp $ */
/*
* Copyright (c) 2009 Dariusz Swiderski <sfires@sfires.net>
@@ -57,8 +57,11 @@ void *fdt_child_node(void *);
char *fdt_node_name(void *);
void *fdt_find_node(char *);
int fdt_node_property(void *, char *, char **);
+int fdt_node_property_int(void *, char *, int *);
+int fdt_node_property_ints(void *, char *, int *, int);
int fdt_node_set_property(void *, char *, void *, int);
int fdt_node_add_property(void *, char *, void *, int);
+int fdt_node_add_node(void *, char *, void **);
void *fdt_parent_node(void *);
int fdt_node_is_compatible(void *, const char *);
#ifdef DEBUG