summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2019-08-12 19:17:36 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2019-08-12 19:17:36 +0000
commit01e91e0ad7efeaac318809a368d16ff0d66bb0f9 (patch)
tree97f8d19220d2690f163596150db83ab97cc748cb
parent915ce8c0716d0d53d590ca8fb9fe7f3a196ae07d (diff)
Make it possible to switch to framebuffer "glass" console in case it
isn't the default already. ok patrick@
-rw-r--r--sys/arch/arm64/stand/efiboot/Makefile4
-rw-r--r--sys/arch/arm64/stand/efiboot/conf.c5
-rw-r--r--sys/arch/arm64/stand/efiboot/efiboot.c100
-rw-r--r--sys/arch/arm64/stand/efiboot/efiboot.h6
4 files changed, 105 insertions, 10 deletions
diff --git a/sys/arch/arm64/stand/efiboot/Makefile b/sys/arch/arm64/stand/efiboot/Makefile
index 09b2e05928c..a7b00e48e18 100644
--- a/sys/arch/arm64/stand/efiboot/Makefile
+++ b/sys/arch/arm64/stand/efiboot/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.8 2019/08/03 15:22:20 deraadt Exp $
+# $OpenBSD: Makefile,v 1.9 2019/08/12 19:17:35 kettenis Exp $
NOMAN= #
@@ -36,7 +36,7 @@ SRCS+= aes_xts.c bcrypt_pbkdf.c blowfish.c explicit_bzero.c hmac_sha1.c \
pkcs5_pbkdf2.c rijndael.c sha1.c sha2.c softraid.c
.PATH: ${S}/lib/libkern/arch/arm64 ${S}/lib/libkern
-SRCS+= divdi3.c moddi3.c qdivrem.c strlcpy.c strlen.c
+SRCS+= divdi3.c moddi3.c qdivrem.c strlcat.c strlcpy.c strlen.c
.PATH: ${S}/lib/libz
SRCS+= adler32.c crc32.c inflate.c inftrees.c
diff --git a/sys/arch/arm64/stand/efiboot/conf.c b/sys/arch/arm64/stand/efiboot/conf.c
index 9962b7fb8ea..3cba4d95faa 100644
--- a/sys/arch/arm64/stand/efiboot/conf.c
+++ b/sys/arch/arm64/stand/efiboot/conf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.c,v 1.21 2019/08/04 13:45:14 deraadt Exp $ */
+/* $OpenBSD: conf.c,v 1.22 2019/08/12 19:17:35 kettenis Exp $ */
/*
* Copyright (c) 1996 Michael Shalayeff
@@ -45,7 +45,7 @@
#include "efipxe.h"
#include "softraid_arm64.h"
-const char version[] = "0.17";
+const char version[] = "0.18";
int debug = 0;
struct fs_ops file_system[] = {
@@ -67,6 +67,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/arm64/stand/efiboot/efiboot.c b/sys/arch/arm64/stand/efiboot/efiboot.c
index 4457ab9e287..4a7be9dacec 100644
--- a/sys/arch/arm64/stand/efiboot/efiboot.c
+++ b/sys/arch/arm64/stand/efiboot/efiboot.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: efiboot.c,v 1.24 2019/08/10 13:08:21 kettenis Exp $ */
+/* $OpenBSD: efiboot.c,v 1.25 2019/08/12 19:17:35 kettenis Exp $ */
/*
* Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
@@ -104,11 +104,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
@@ -169,6 +177,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)
{
@@ -310,6 +344,7 @@ efi_framebuffer(void)
uint32_t reg[4];
uint32_t width, height, stride;
char *format;
+ char *prop;
/*
* Don't create a "simple-framebuffer" node if we already have
@@ -319,13 +354,19 @@ efi_framebuffer(void)
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"))
+ 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"))
+ if (!fdt_node_is_compatible(child, "simple-framebuffer"))
+ continue;
+ if (fdt_node_property(child, "status", &prop) &&
+ strcmp(prop, "okay") == 0)
return;
}
@@ -387,6 +428,36 @@ efi_framebuffer(void)
"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);
+}
+
int acpi = 0;
void *fdt = NULL;
char *bootmac = NULL;
@@ -463,6 +534,7 @@ efi_makebootargs(char *bootargs)
fdt_node_add_property(node, "openbsd,uefi-mmap-desc-ver", zero, 4);
efi_framebuffer();
+ efi_console();
fdt_finalize();
@@ -648,21 +720,39 @@ devboot(dev_t dev, char *p)
p[2] = '0' + sd_boot_vol;
}
+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/arm64/stand/efiboot/efiboot.h b/sys/arch/arm64/stand/efiboot/efiboot.h
index 43888bc4908..47da16cdc1c 100644
--- a/sys/arch/arm64/stand/efiboot/efiboot.h
+++ b/sys/arch/arm64/stand/efiboot/efiboot.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: efiboot.h,v 1.3 2018/06/25 22:39:14 kettenis Exp $ */
+/* $OpenBSD: efiboot.h,v 1.4 2019/08/12 19:17:35 kettenis Exp $ */
/*
* Copyright (c) 2015 YASUOKA Masahiko <yasuoka@yasuoka.net>
@@ -25,3 +25,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);