diff options
| author | Dan McDonald <danmcd@joyent.com> | 2021-02-12 16:42:37 -0500 |
|---|---|---|
| committer | Dan McDonald <danmcd@joyent.com> | 2021-02-12 16:42:39 -0500 |
| commit | 3b5a24cbde3c794c2a4b77cc402302b0c2fefc1d (patch) | |
| tree | 160bd5d1dd9e24baf306c57ade7e84bc5fd3a943 /usr/src/boot | |
| parent | a4b5adf38c4d13d8a0bb4c581f0001585cc2ad4e (diff) | |
| parent | d12ea28fc42fd800e7bac951f1fd7607dc8e3afd (diff) | |
| download | illumos-joyent-3b5a24cbde3c794c2a4b77cc402302b0c2fefc1d.tar.gz | |
[illumos-gate merge]
commit d12ea28fc42fd800e7bac951f1fd7607dc8e3afd
13499 System paging parameters no longer calculated at boot after 13097
commit 44e8cbb5864d29abbabb68852e1d183c9c6e534d
13495 klmmod: multiply-defined symbols
commit aab20b47bd0a2879ccd534e4b5516c6af3f5a1d2
13494 nfs: multiply-defined symbols
commit 592b68f9130dc6c5b980b90fbb93d13a5a4c3265
13433 After cxgbe transceiver is reseated, link does not return to up state
commit 99d0d3f582c9145a267ddfd9fef778459d415339
13476 zfs: multiply-defined symbols
commit 379728489ed47862c4927c75771e767b9476c9c4
13496 libnsl: symbol '_null_auth' is multiply-defined
commit 7449d3727c8ac1ccfb0a4c4de0a9ccf79c1d8cfd
13454 loader: create local copy of mode list provided by vbeinfoblock
commit 168091e5da87ff8dbec35e48d0cebe8b5221365d
13506 smbfs panic on failed open for append
commit 72973a2ec5f92e2ddf35c4a344567980fae70ec1
13453 loader.efi: handle multiple gop instances
commit a8e6450ff6a17b0dab01ca8f09ba123395cf94fa
13485 ratz, some ast tools not necessary
Conflicts:
usr/src/uts/common/os/vm_pageout.c
Diffstat (limited to 'usr/src/boot')
| -rw-r--r-- | usr/src/boot/Makefile.version | 2 | ||||
| -rw-r--r-- | usr/src/boot/sys/boot/efi/loader/framebuffer.c | 38 | ||||
| -rw-r--r-- | usr/src/boot/sys/boot/i386/libi386/vbe.c | 103 |
3 files changed, 104 insertions, 39 deletions
diff --git a/usr/src/boot/Makefile.version b/usr/src/boot/Makefile.version index 6f851b7eef..d4b95e1bef 100644 --- a/usr/src/boot/Makefile.version +++ b/usr/src/boot/Makefile.version @@ -34,4 +34,4 @@ LOADER_VERSION = 1.1 # Use date like formatting here, YYYY.MM.DD.XX, without leading zeroes. # The version is processed from left to right, the version number can only # be increased. -BOOT_VERSION = $(LOADER_VERSION)-2020.12.11.1 +BOOT_VERSION = $(LOADER_VERSION)-2021.01.17.2 diff --git a/usr/src/boot/sys/boot/efi/loader/framebuffer.c b/usr/src/boot/sys/boot/efi/loader/framebuffer.c index 534e00cf9c..1100f2e4e1 100644 --- a/usr/src/boot/sys/boot/efi/loader/framebuffer.c +++ b/usr/src/boot/sys/boot/efi/loader/framebuffer.c @@ -46,6 +46,7 @@ #include "gfx_fb.h" #include "framebuffer.h" +EFI_GUID conout_guid = EFI_CONSOLE_OUT_DEVICE_GUID; EFI_GUID gop_guid = EFI_GRAPHICS_OUTPUT_PROTOCOL_GUID; static EFI_GUID pciio_guid = EFI_PCI_IO_PROTOCOL_GUID; EFI_GUID uga_guid = EFI_UGA_DRAW_PROTOCOL_GUID; @@ -506,6 +507,8 @@ efifb_get_edid(edid_res_list_t *res) int efi_find_framebuffer(struct efi_fb *efifb) { + EFI_HANDLE h, *hlist; + UINTN nhandles, i, hsize; extern EFI_GRAPHICS_OUTPUT *gop; extern EFI_UGA_DRAW_PROTOCOL *uga; EFI_STATUS status; @@ -514,7 +517,40 @@ efi_find_framebuffer(struct efi_fb *efifb) if (gop != NULL) return (efifb_from_gop(efifb, gop->Mode, gop->Mode->Info)); - status = BS->LocateProtocol(&gop_guid, NULL, (void **)&gop); + hsize = 0; + hlist = NULL; + status = BS->LocateHandle(ByProtocol, &gop_guid, NULL, &hsize, hlist); + if (status == EFI_BUFFER_TOO_SMALL) { + hlist = malloc(hsize); + if (hlist == NULL) + return (ENOMEM); + status = BS->LocateHandle(ByProtocol, &gop_guid, NULL, &hsize, + hlist); + if (EFI_ERROR(status)) + free(hlist); + } + if (EFI_ERROR(status)) + return (efi_status_to_errno(status)); + + nhandles = hsize / sizeof (*hlist); + + /* + * Search for ConOut protocol, if not found, use first handle. + */ + h = *hlist; + for (i = 0; i < nhandles; i++) { + void *dummy = NULL; + + status = OpenProtocolByHandle(hlist[i], &conout_guid, &dummy); + if (status == EFI_SUCCESS) { + h = hlist[i]; + break; + } + } + + status = OpenProtocolByHandle(h, &gop_guid, (void **)&gop); + free(hlist); + if (status == EFI_SUCCESS) { /* Save default mode. */ if (default_mode == UINT32_MAX) { diff --git a/usr/src/boot/sys/boot/i386/libi386/vbe.c b/usr/src/boot/sys/boot/i386/libi386/vbe.c index 4f98cdf747..c48427f5f4 100644 --- a/usr/src/boot/sys/boot/i386/libi386/vbe.c +++ b/usr/src/boot/sys/boot/i386/libi386/vbe.c @@ -47,13 +47,14 @@ static struct vbeinfoblock *vbe = (struct vbeinfoblock *)&vbestate.vbe_control_info; static struct modeinfoblock *vbe_mode = (struct modeinfoblock *)&vbestate.vbe_mode_info; +static uint16_t *vbe_mode_list; +static size_t vbe_mode_list_size; multiboot_color_t *cmap; /* The default VGA color palette format is 6 bits per primary color. */ int palette_format = 6; -#define VESA_MODE_BASE 0x100 -#define VESA_MODE_MAX 0x1ff -#define VESA_MODE_COUNT (VESA_MODE_MAX - VESA_MODE_BASE + 1) +#define VESA_MODE_BASE 0x100 +#define VESA_END_OF_MODE_LIST 0xffff /* Actually assuming mode 3. */ void @@ -278,9 +279,25 @@ vbe_check(void) return (1); } +/* + * Translate selector:offset style address to linear adress. + * selector = farptr >> 16; + * offset = farptr & 0xffff; + * linear = (selector * 4) + offset. + * By using mask 0xffff0000, we wil get the optimised line below. + * As a final step, translate physical address to loader virtual address. + */ +static void * +vbe_farptr(uint32_t farptr) +{ + return (PTOV((((farptr & 0xffff0000) >> 12) + (farptr & 0xffff)))); +} + void vbe_init(void) { + uint16_t *p, *ml; + /* First set FB for text mode. */ gfx_fb.framebuffer_common.mb_type = MULTIBOOT_TAG_TYPE_FRAMEBUFFER; gfx_fb.framebuffer_common.framebuffer_type = @@ -301,9 +318,37 @@ vbe_init(void) if (memcmp(vbe->VbeSignature, "VESA", 4) != 0) return; + /* + * Copy mode list array. We must do this because some systems do + * place this array to scratch memory, which will be reused by + * subsequent VBE calls. (vbox 6.1 is one example). + */ + p = ml = vbe_farptr(vbe->VideoModePtr); + while (*p++ != VESA_END_OF_MODE_LIST) + ; + + vbe_mode_list_size = (uintptr_t)p - (uintptr_t)ml; + + /* + * Since vbe_init() is used only once at very start of the loader, + * we assume malloc will not fail there. But in case it does, + * we point vbe_mode_list to memory pointed by VideoModePtr. + * If the VideoModePtr memory area is not valid, we will fail to + * pick usable VBE mode and fall back to use text mode. + */ + vbe_mode_list = malloc(vbe_mode_list_size); + if (vbe_mode_list == NULL) + vbe_mode_list = ml; + else + bcopy(ml, vbe_mode_list, vbe_mode_list_size); + + /* reset VideoModePtr, to make sure, we only do use vbe_mode_list. */ + vbe->VideoModePtr = 0; + vbestate.mb_type = MULTIBOOT_TAG_TYPE_VBE; vbestate.mb_size = sizeof (vbestate); vbestate.vbe_mode = 0; + /* vbe_set_mode() will set up the rest. */ } @@ -446,12 +491,6 @@ vbe_set_mode(int modenum) return (0); } -static void * -vbe_farptr(uint32_t farptr) -{ - return (PTOV((((farptr & 0xffff0000) >> 12) + (farptr & 0xffff)))); -} - /* * Verify existance of mode number or find mode by * dimensions. If depth is not given, walk values 32, 24, 16, 8. @@ -460,9 +499,9 @@ static int vbe_find_mode_xydm(int x, int y, int depth, int m) { struct modeinfoblock mi; - uint32_t farptr; uint16_t mode; - int safety, i; + size_t idx, nentries; + int i; memset(vbe, 0, sizeof (vbe)); memcpy(vbe->VbeSignature, "VBE2", 4); @@ -470,8 +509,6 @@ vbe_find_mode_xydm(int x, int y, int depth, int m) return (0); if (memcmp(vbe->VbeSignature, "VESA", 4) != 0) return (0); - if (vbe->VideoModePtr == 0) - return (0); if (m != -1) i = 8; @@ -480,17 +517,16 @@ vbe_find_mode_xydm(int x, int y, int depth, int m) else i = depth; + nentries = vbe_mode_list_size / sizeof (*vbe_mode_list); while (i > 0) { - farptr = vbe->VideoModePtr; - safety = 0; - while ((mode = *(uint16_t *)vbe_farptr(farptr)) != 0xffff) { - safety++; - farptr += 2; - if (safety == VESA_MODE_COUNT) - return (0); - if (biosvbe_get_mode_info(mode, &mi) != VBE_SUCCESS) { + for (idx = 0; idx < nentries; idx++) { + mode = vbe_mode_list[idx]; + if (mode == VESA_END_OF_MODE_LIST) + break; + + if (biosvbe_get_mode_info(mode, &mi) != VBE_SUCCESS) continue; - } + /* we only care about linear modes here */ if (vbe_mode_is_supported(&mi) == 0) continue; @@ -624,9 +660,8 @@ void vbe_modelist(int depth) { struct modeinfoblock mi; - uint32_t farptr; uint16_t mode; - int nmodes = 0, safety = 0; + int nmodes, idx, nentries; int ddc_caps; uint_t width, height; bool edid = false; @@ -662,6 +697,7 @@ vbe_modelist(int depth) if (vbe_get_flatpanel(&width, &height)) printf(": Panel %dx%d\n", width, height); + nmodes = 0; memset(vbe, 0, sizeof (vbe)); memcpy(vbe->VbeSignature, "VBE2", 4); if (biosvbe_info(vbe) != VBE_SUCCESS) @@ -672,26 +708,19 @@ vbe_modelist(int depth) vbe_print_vbe_info(vbe); printf("Modes: "); - farptr = vbe->VideoModePtr; - if (farptr == 0) - goto done; - - while ((mode = *(uint16_t *)vbe_farptr(farptr)) != 0xffff) { - safety++; - farptr += 2; - if (safety == VESA_MODE_COUNT) { - printf("[?] "); + nentries = vbe_mode_list_size / sizeof (*vbe_mode_list); + for (idx = 0; idx < nentries; idx++) { + mode = vbe_mode_list[idx]; + if (mode == VESA_END_OF_MODE_LIST) break; - } + if (biosvbe_get_mode_info(mode, &mi) != VBE_SUCCESS) continue; + /* we only care about linear modes here */ if (vbe_mode_is_supported(&mi) == 0) continue; - /* we found some mode so reset safety counter */ - safety = 0; - /* apply requested filter */ if (depth != -1 && mi.BitsPerPixel != depth) continue; |
