From owner-svn-src-head@freebsd.org Sat Sep 5 03:27:24 2015 Return-Path: Delivered-To: svn-src-head@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 063AB9C9996; Sat, 5 Sep 2015 03:27:24 +0000 (UTC) (envelope-from marcel@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id EB99D264; Sat, 5 Sep 2015 03:27:23 +0000 (UTC) (envelope-from marcel@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id t853RNiQ014329; Sat, 5 Sep 2015 03:27:23 GMT (envelope-from marcel@FreeBSD.org) Received: (from marcel@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t853RNKK014328; Sat, 5 Sep 2015 03:27:23 GMT (envelope-from marcel@FreeBSD.org) Message-Id: <201509050327.t853RNKK014328@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: marcel set sender to marcel@FreeBSD.org using -f From: Marcel Moolenaar Date: Sat, 5 Sep 2015 03:27:23 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r287475 - head/sys/boot/efi/loader/arch/amd64 X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 05 Sep 2015 03:27:24 -0000 Author: marcel Date: Sat Sep 5 03:27:23 2015 New Revision: 287475 URL: https://svnweb.freebsd.org/changeset/base/287475 Log: My MacBook has UGA only, but we fail to detect any changes in the frame buffer when we flip pixels. Allow the detection to be bypassed by setting the uga_framebuffer and uga_stride variables. The kernel console works fine even when we can't detect pixel changes in the frame buffer, which indicates that the problem could be with reading from the frame buffer and not writing to it. Modified: head/sys/boot/efi/loader/arch/amd64/framebuffer.c Modified: head/sys/boot/efi/loader/arch/amd64/framebuffer.c ============================================================================== --- head/sys/boot/efi/loader/arch/amd64/framebuffer.c Sat Sep 5 01:00:02 2015 (r287474) +++ head/sys/boot/efi/loader/arch/amd64/framebuffer.c Sat Sep 5 03:27:23 2015 (r287475) @@ -183,29 +183,24 @@ efifb_uga_find_pixel(EFI_UGA_DRAW_PROTOC return (-1); } -static EFI_STATUS -efifb_uga_detect_framebuffer(EFI_UGA_DRAW_PROTOCOL *uga, - EFI_PCI_IO_PROTOCOL **pciiop, uint64_t *addrp, uint64_t *sizep) +static EFI_PCI_IO_PROTOCOL * +efifb_uga_get_pciio(void) { EFI_PCI_IO_PROTOCOL *pciio; EFI_HANDLE *buf, *hp; - uint8_t *resattr; - uint64_t a, addr, s, size; - ssize_t ofs; EFI_STATUS status; UINTN bufsz; - u_int bar; /* Get all handles that support the UGA protocol. */ bufsz = 0; status = BS->LocateHandle(ByProtocol, &uga_guid, NULL, &bufsz, NULL); if (status != EFI_BUFFER_TOO_SMALL) - return (status); + return (NULL); buf = malloc(bufsz); status = BS->LocateHandle(ByProtocol, &uga_guid, NULL, &bufsz, buf); if (status != EFI_SUCCESS) { free(buf); - return (status); + return (NULL); } bufsz /= sizeof(EFI_HANDLE); @@ -213,12 +208,24 @@ efifb_uga_detect_framebuffer(EFI_UGA_DRA pciio = NULL; for (hp = buf; hp < buf + bufsz; hp++) { status = BS->HandleProtocol(*hp, &pciio_guid, (void **)&pciio); - if (status == EFI_SUCCESS) - break; + if (status == EFI_SUCCESS) { + free(buf); + return (pciio); + } } free(buf); - if (status != EFI_SUCCESS || pciio == NULL) - return (EFI_NOT_FOUND); + return (NULL); +} + +static EFI_STATUS +efifb_uga_detect_framebuffer(EFI_UGA_DRAW_PROTOCOL *uga, + EFI_PCI_IO_PROTOCOL *pciio, uint64_t *addrp, uint64_t *sizep) +{ + uint8_t *resattr; + uint64_t a, addr, s, size; + ssize_t ofs; + EFI_STATUS status; + u_int bar; /* Attempt to get the frame buffer address (imprecise). */ addr = 0; @@ -265,7 +272,6 @@ efifb_uga_detect_framebuffer(EFI_UGA_DRA addr += ofs; size -= ofs; - *pciiop = pciio; *addrp = addr; *sizep = size; return (0); @@ -275,6 +281,7 @@ static int efifb_from_uga(struct efi_fb *efifb, EFI_UGA_DRAW_PROTOCOL *uga) { EFI_PCI_IO_PROTOCOL *pciio; + char *ev, *p; EFI_STATUS status; ssize_t ofs; uint32_t horiz, vert, depth, refresh; @@ -287,18 +294,37 @@ efifb_from_uga(struct efi_fb *efifb, EFI efifb_mask_from_pixfmt(efifb, PixelBlueGreenRedReserved8BitPerColor, NULL); - /* Try and find the frame buffer. */ - status = efifb_uga_detect_framebuffer(uga, &pciio, &efifb->fb_addr, - &efifb->fb_size); - if (EFI_ERROR(status)) + pciio = efifb_uga_get_pciio(); + if (pciio == NULL) return (1); - /* Try and detect the stride. */ - ofs = efifb_uga_find_pixel(uga, 1, pciio, efifb->fb_addr, - efifb->fb_size); - if (ofs == -1) - return (1); - efifb->fb_stride = ofs >> 2; + ev = getenv("uga_framebuffer"); + if (ev == NULL) { + /* Try to find the frame buffer. */ + status = efifb_uga_detect_framebuffer(uga, pciio, + &efifb->fb_addr, &efifb->fb_size); + if (EFI_ERROR(status)) + return (1); + } else { + efifb->fb_size = horiz * vert * 4; + efifb->fb_addr = strtoul(ev, &p, 0); + if (*p != '\0') + return (1); + } + + ev = getenv("uga_stride"); + if (ev == NULL) { + /* Try to detect the stride. */ + ofs = efifb_uga_find_pixel(uga, 1, pciio, efifb->fb_addr, + efifb->fb_size); + if (ofs == -1) + return (1); + efifb->fb_stride = ofs >> 2; + } else { + efifb->fb_stride = strtoul(ev, &p, 0); + if (*p != '\0') + return (1); + } return (0); }