Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/bouyer-socketcan]: src/sys/arch/i386/stand/efiboot 1673576
details: https://anonhg.NetBSD.org/src/rev/2581a9215833
branches: bouyer-socketcan
changeset: 820853:2581a9215833
user: nonaka <nonaka%NetBSD.org@localhost>
date: Fri Mar 24 01:25:37 2017 +0000
description:
1673576
diffstat:
sys/arch/i386/stand/efiboot/eficons.c | 563 ++++++++++++++++++++++++++++++++++
1 files changed, 563 insertions(+), 0 deletions(-)
diffs (truncated from 567 to 300 lines):
diff -r 3bde1026fddc -r 2581a9215833 sys/arch/i386/stand/efiboot/eficons.c
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/arch/i386/stand/efiboot/eficons.c Fri Mar 24 01:25:37 2017 +0000
@@ -0,0 +1,563 @@
+/* $NetBSD: eficons.c,v 1.3.4.2 2017/03/24 01:25:37 nonaka Exp $ */
+
+/*-
+ * Copyright (c) 2016 Kimihiro Nonaka <nonaka%netbsd.org@localhost>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/bitops.h>
+#include <sys/stdint.h>
+
+#include "efiboot.h"
+
+#include "bootinfo.h"
+#include "vbe.h"
+
+struct btinfo_console btinfo_console;
+
+static EFI_GRAPHICS_OUTPUT_PROTOCOL *efi_gop;
+static int efi_gop_mode = -1;
+
+static CHAR16 keybuf[16];
+static int keybuf_read = 0;
+static int keybuf_write = 0;
+
+static void eficons_init_video(void);
+static void efi_switch_video_to_text_mode(void);
+
+int
+cninit(void)
+{
+
+ efi_switch_video_to_text_mode();
+ eficons_init_video();
+
+ /* XXX serial console */
+ btinfo_console.devname[0] = 'p';
+ btinfo_console.devname[1] = 'c';
+ btinfo_console.devname[2] = 0;
+
+ return 0;
+}
+
+int
+getchar(void)
+{
+ EFI_STATUS status;
+ EFI_INPUT_KEY key;
+ int c;
+
+ if (keybuf_read != keybuf_write) {
+ c = keybuf[keybuf_read];
+ keybuf_read = (keybuf_read + 1) % __arraycount(keybuf);
+ return c;
+ }
+
+ status = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn,
+ &key);
+ while (status == EFI_NOT_READY) {
+ WaitForSingleEvent(ST->ConIn->WaitForKey, 0);
+ status = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2,
+ ST->ConIn, &key);
+ }
+ return key.UnicodeChar;
+}
+
+void
+putchar(int c)
+{
+ CHAR16 buf[2];
+
+ buf[1] = 0;
+ if (c == '\n') {
+ buf[0] = '\r';
+ Output(buf);
+ }
+ buf[0] = c;
+ Output(buf);
+}
+
+/*ARGSUSED*/
+int
+iskey(int intr)
+{
+ EFI_STATUS status;
+ EFI_INPUT_KEY key;
+
+ if (keybuf_read != keybuf_write)
+ return 1;
+
+ status = uefi_call_wrapper(ST->ConIn->ReadKeyStroke, 2, ST->ConIn,
+ &key);
+ if (EFI_ERROR(status))
+ return 0;
+
+ keybuf[keybuf_write] = key.UnicodeChar;
+ keybuf_write = (keybuf_write + 1) % __arraycount(keybuf);
+ return 1;
+}
+
+char
+awaitkey(int timeout, int tell)
+{
+ char c = 0;
+
+ for (;;) {
+ if (tell) {
+ char numbuf[32];
+ int len;
+
+ len = snprintf(numbuf, sizeof(numbuf), "%d seconds. ",
+ timeout);
+ if (len > 0 && len < sizeof(numbuf)) {
+ char *p = numbuf;
+
+ printf("%s", numbuf);
+ while (*p)
+ *p++ = '\b';
+ printf("%s", numbuf);
+ }
+ }
+ if (iskey(1)) {
+ /* flush input buffer */
+ while (iskey(0))
+ c = getchar();
+ if (c == 0)
+ c = -1;
+ goto out;
+ }
+ if (timeout--)
+ WaitForSingleEvent(ST->ConIn->WaitForKey, 10000000);
+ else
+ break;
+ }
+
+out:
+ if (tell)
+ printf("0 seconds. \n");
+
+ return c;
+}
+
+void
+clear_pc_screen(void)
+{
+
+ uefi_call_wrapper(ST->ConOut->ClearScreen, 1, ST->ConOut);
+}
+
+static uint8_t
+getdepth(const EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info)
+{
+
+ switch (info->PixelFormat) {
+ case PixelBlueGreenRedReserved8BitPerColor:
+ case PixelRedGreenBlueReserved8BitPerColor:
+ return 32;
+
+ case PixelBitMask:
+ return fls32(info->PixelInformation.RedMask
+ | info->PixelInformation.GreenMask
+ | info->PixelInformation.BlueMask
+ | info->PixelInformation.ReservedMask);
+
+ case PixelBltOnly:
+ case PixelFormatMax:
+ return 0;
+ }
+ return 0;
+}
+
+static void
+setpixelformat(UINT32 mask, uint8_t *num, uint8_t *pos)
+{
+ uint8_t n, p;
+
+ n = popcount32(mask);
+ p = ffs32(mask);
+ if (p > 0)
+ p--;
+
+ *num = n;
+ *pos = p;
+}
+
+static void
+bi_framebuffer(void)
+{
+ EFI_STATUS status;
+ EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *info;
+ struct btinfo_framebuffer fb;
+ INT32 bestmode = -1;
+
+ if (efi_gop == NULL) {
+ framebuffer_configure(NULL);
+ return;
+ }
+
+ if (efi_gop_mode >= 0) {
+ bestmode = efi_gop_mode;
+ } else {
+#if 0
+ UINT64 res, bestres = 0;
+ UINTN sz;
+ UINT32 i;
+
+ /* XXX EDID? EFI_EDID_DISCOVERED_PROTOCOL */
+ for (i = 0; i < efi_gop->Mode->MaxMode; i++) {
+ status = uefi_call_wrapper(efi_gop->QueryMode, 4,
+ efi_gop, i, &sz, &info);
+ if (EFI_ERROR(status))
+ continue;
+
+ res = (UINT64)info->HorizontalResolution *
+ (UINT64)info->VerticalResolution *
+ (UINT64)getdepth(info);
+ if (res > bestres) {
+ bestmode = i;
+ bestres = res;
+ }
+ }
+#endif
+ }
+ if (bestmode >= 0) {
+ status = uefi_call_wrapper(efi_gop->SetMode, 2, efi_gop,
+ bestmode);
+ if (EFI_ERROR(status) || efi_gop->Mode->Mode != bestmode)
+ Print(L"GOP setmode failed: %r\n", status);
+ }
+
+ info = efi_gop->Mode->Info;
+ memset(&fb, 0, sizeof(fb));
+ fb.physaddr = efi_gop->Mode->FrameBufferBase;
+ fb.flags = 0;
+ fb.width = info->HorizontalResolution;
+ fb.height = info->VerticalResolution;
+ fb.depth = getdepth(info);
+ fb.stride = info->PixelsPerScanLine * ((fb.depth + 7) / 8);
+ fb.vbemode = 0; /* XXX */
+
+ switch (info->PixelFormat) {
+ case PixelBlueGreenRedReserved8BitPerColor:
+ fb.rnum = 8;
+ fb.gnum = 8;
+ fb.bnum = 8;
+ fb.rpos = 16;
+ fb.gpos = 8;
+ fb.bpos = 0;
+ break;
+
+ case PixelRedGreenBlueReserved8BitPerColor:
+ fb.rnum = 8;
+ fb.gnum = 8;
+ fb.bnum = 8;
+ fb.rpos = 0;
+ fb.gpos = 8;
+ fb.bpos = 16;
+ break;
+
+ case PixelBitMask:
+ setpixelformat(info->PixelInformation.RedMask,
+ &fb.rnum, &fb.rpos);
+ setpixelformat(info->PixelInformation.GreenMask,
+ &fb.gnum, &fb.gpos);
+ setpixelformat(info->PixelInformation.BlueMask,
+ &fb.bnum, &fb.bpos);
+ break;
+
+ case PixelBltOnly:
+ case PixelFormatMax:
+ Panic(L"Error: invalid pixel format (%d)", info->PixelFormat);
+ break;
+ }
+
+ framebuffer_configure(&fb);
+}
Home |
Main Index |
Thread Index |
Old Index