1// Copyright 2017 The Fuchsia Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "osboot.h" 6 7#include <stdio.h> 8#include <string.h> 9#include <xefi.h> 10 11#include <zircon/pixelformat.h> 12 13static efi_guid AcpiTableGUID = ACPI_TABLE_GUID; 14static efi_guid Acpi2TableGUID = ACPI_20_TABLE_GUID; 15static efi_guid SmbiosTableGUID = SMBIOS_TABLE_GUID; 16static efi_guid Smbios3TableGUID = SMBIOS3_TABLE_GUID; 17static uint8_t ACPI_RSD_PTR[8] = "RSD PTR "; 18static uint8_t SmbiosAnchor[4] = "_SM_"; 19static uint8_t Smbios3Anchor[5] = "_SM3_"; 20 21uint64_t find_acpi_root(efi_handle img, efi_system_table* sys) { 22 efi_configuration_table* cfgtab = sys->ConfigurationTable; 23 int i; 24 25 for (i = 0; i < sys->NumberOfTableEntries; i++) { 26 if (xefi_cmp_guid(&cfgtab[i].VendorGuid, &AcpiTableGUID) && 27 xefi_cmp_guid(&cfgtab[i].VendorGuid, &Acpi2TableGUID)) { 28 // not an ACPI table 29 continue; 30 } 31 if (memcmp(cfgtab[i].VendorTable, ACPI_RSD_PTR, 8)) { 32 // not the Root Description Pointer 33 continue; 34 } 35 return (uint64_t)cfgtab[i].VendorTable; 36 } 37 return 0; 38} 39 40uint64_t find_smbios(efi_handle img, efi_system_table* sys) { 41 efi_configuration_table* cfgtab = sys->ConfigurationTable; 42 int i; 43 44 for (i = 0; i < sys->NumberOfTableEntries; i++) { 45 if (!xefi_cmp_guid(&cfgtab[i].VendorGuid, &SmbiosTableGUID)) { 46 if (!memcmp(cfgtab[i].VendorTable, SmbiosAnchor, sizeof(SmbiosAnchor))) { 47 return (uint64_t)cfgtab[i].VendorTable; 48 } 49 } else if (!xefi_cmp_guid(&cfgtab[i].VendorGuid, &Smbios3TableGUID)) { 50 if (!memcmp(cfgtab[i].VendorTable, Smbios3Anchor, sizeof(Smbios3Anchor))) { 51 return (uint64_t)cfgtab[i].VendorTable; 52 } 53 } 54 } 55 return 0; 56} 57 58static void get_bit_range(uint32_t mask, int* high, int* low) { 59 *high = -1; 60 *low = -1; 61 int idx = 0; 62 while (mask) { 63 if (*low < 0 && (mask & 1)) *low = idx; 64 idx++; 65 mask >>= 1; 66 } 67 *high = idx - 1; 68} 69 70static int get_zx_pixel_format_from_bitmask(efi_pixel_bitmask bitmask) { 71 int r_hi = -1, r_lo = -1, g_hi = -1, g_lo = -1, b_hi = -1, b_lo = -1; 72 73 get_bit_range(bitmask.RedMask, &r_hi, &r_lo); 74 get_bit_range(bitmask.GreenMask, &g_hi, &g_lo); 75 get_bit_range(bitmask.BlueMask, &b_hi, &b_lo); 76 77 if (r_lo < 0 || g_lo < 0 || b_lo < 0) { 78 goto unsupported; 79 } 80 81 if ((r_hi == 23 && r_lo == 16) && 82 (g_hi == 15 && g_lo == 8) && 83 (b_hi == 7 && b_lo == 0)) { 84 return ZX_PIXEL_FORMAT_RGB_x888; 85 } 86 87 if ((r_hi == 7 && r_lo == 5) && 88 (g_hi == 4 && g_lo == 2) && 89 (b_hi == 1 && b_lo == 0)) { 90 return ZX_PIXEL_FORMAT_RGB_332; 91 } 92 93 if ((r_hi == 15 && r_lo == 11) && 94 (g_hi == 10 && g_lo == 5) && 95 (b_hi == 4 && b_lo == 0)) { 96 return ZX_PIXEL_FORMAT_RGB_565; 97 } 98 99 if ((r_hi == 7 && r_lo == 6) && 100 (g_hi == 5 && g_lo == 4) && 101 (b_hi == 3 && b_lo == 2)) { 102 return ZX_PIXEL_FORMAT_RGB_2220; 103 } 104 105unsupported: 106 printf("unsupported pixel format bitmask: r %08x / g %08x / b %08x\n", 107 bitmask.RedMask, bitmask.GreenMask, bitmask.BlueMask); 108 return ZX_PIXEL_FORMAT_NONE; 109} 110 111uint32_t get_zx_pixel_format(efi_graphics_output_protocol* gop) { 112 efi_graphics_pixel_format efi_fmt = gop->Mode->Info->PixelFormat; 113 switch (efi_fmt) { 114 case PixelBlueGreenRedReserved8BitPerColor: 115 return ZX_PIXEL_FORMAT_RGB_x888; 116 case PixelBitMask: 117 return get_zx_pixel_format_from_bitmask(gop->Mode->Info->PixelInformation); 118 default: 119 printf("unsupported pixel format %d!\n", efi_fmt); 120 return ZX_PIXEL_FORMAT_NONE; 121 } 122} 123