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