From owner-svn-src-all@freebsd.org Mon Sep 7 19:38:58 2015 Return-Path: Delivered-To: svn-src-all@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 84DF89CD3C1; Mon, 7 Sep 2015 19:38:58 +0000 (UTC) (envelope-from adrian.chadd@gmail.com) Received: from mail-ig0-x22f.google.com (mail-ig0-x22f.google.com [IPv6:2607:f8b0:4001:c05::22f]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 51ACA1982; Mon, 7 Sep 2015 19:38:58 +0000 (UTC) (envelope-from adrian.chadd@gmail.com) Received: by igbni9 with SMTP id ni9so62889945igb.0; Mon, 07 Sep 2015 12:38:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=acW0H07HmMOZ8XMsQOC5Bn5daaJcKIF2Sc2ZOyT8hXg=; b=alAzOl4oMtfaeEE+mcfkXhNRRUtIP6JYKbREoKcRpgUPODlNAaxv21VORULyL9nWjI bL0bRmin9hjRbKp7v1TjtmI3shhEA4pknQsrqd0easQ3dwSgwlwg+qBA/+08eRo/XCkV HEKOfTzCxhGZsyUSdA38m9cxxqo6Zkp2iINsPvd255O73+LKWC/uEsH7q0KEl5dbyv4k vEL09+sZRMlGt6g3qdieNPg37yL/bA8XyqTJvE4PQpMM96/NJv1hqaBqUBUb/IV+8y3H 2P3V+kw8KaBvUfEKVcyEw3DhZt/d3+ri/KFroUTwi0zAQ+o89RyfnCzfgCgfPLr1ohLA TtRQ== MIME-Version: 1.0 X-Received: by 10.50.61.243 with SMTP id t19mr30772378igr.22.1441654737534; Mon, 07 Sep 2015 12:38:57 -0700 (PDT) Received: by 10.36.28.208 with HTTP; Mon, 7 Sep 2015 12:38:57 -0700 (PDT) In-Reply-To: <201509071756.t87HuoRu079196@repo.freebsd.org> References: <201509071756.t87HuoRu079196@repo.freebsd.org> Date: Mon, 7 Sep 2015 12:38:57 -0700 Message-ID: Subject: Re: svn commit: r287538 - head/sys/boot/efi/loader/arch/amd64 From: Adrian Chadd To: Marcel Moolenaar Cc: "src-committers@freebsd.org" , "svn-src-all@freebsd.org" , "svn-src-head@freebsd.org" Content-Type: text/plain; charset=UTF-8 X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 07 Sep 2015 19:38:58 -0000 Hi, every time I see efi framebuffer changes I get a little queasy. There's quite a lot of variance in well, what I once thought would be better than just dealing with a VESA framebuffer. So I'd really appreciate it (and I'm sure others would too!) if you listed all of the things you tested out changes on successfully when you do make changes. That way I and others can have a hope of actually reproducing what's going on and also testing on setups that you don't have. Thanks, -adrian (I'm really surprised this stuff is more complicated than VESA 2.0..) On 7 September 2015 at 10:56, Marcel Moolenaar wrote: > Author: marcel > Date: Mon Sep 7 17:56:49 2015 > New Revision: 287538 > URL: https://svnweb.freebsd.org/changeset/base/287538 > > Log: > As expected, things aren't as simple as hoped. Consequently, we have > no option but to use the smbios information to fill in the blanks. > It's a good thing UGA is a protocol of the past and GOP has all the > info we need. > > Anyway, the logic has been tweaked a little to get the easier bits > of information up front. This includes the resolution and the frame > buffer address. Then we look at the smbios information and define > expected values as well as the missing bits (frame buffer offset and > stride). If the values obtained match the expect values, we fill in > the blanks and return. Otherwise we use the existing detection logic > to figure it out. > > Rename the environment variables from uga_framebuffer abd uga_stride > to hw.efifb.address and hw.efifb.stride. The latter names are more > in line with other variable names. > > We currently have hardcoded settings for: > 1. Mid-2007 iMac (iMac7,1) > 2. Late-2007 MacBook (MacBook3,1) > > 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 Mon Sep 7 16:44:28 2015 (r287537) > +++ head/sys/boot/efi/loader/arch/amd64/framebuffer.c Mon Sep 7 17:56:49 2015 (r287538) > @@ -269,8 +269,10 @@ efifb_from_uga(struct efi_fb *efifb, EFI > EFI_PCI_IO_PROTOCOL *pciio; > char *ev, *p; > EFI_STATUS status; > - ssize_t ofs; > - uint32_t np, horiz, vert, depth, refresh; > + ssize_t offset; > + uint64_t fbaddr, fbsize; > + uint32_t horiz, vert, stride; > + uint32_t np, depth, refresh; > > status = uga->GetMode(uga, &horiz, &vert, &depth, &refresh); > if (EFI_ERROR(status)) > @@ -285,6 +287,63 @@ efifb_from_uga(struct efi_fb *efifb, EFI > efifb_mask_from_pixfmt(efifb, PixelBlueGreenRedReserved8BitPerColor, > NULL); > > + /* pciio can be NULL on return! */ > + pciio = efifb_uga_get_pciio(); > + > + /* Try to find the frame buffer. */ > + status = efifb_uga_locate_framebuffer(pciio, &efifb->fb_addr, > + &efifb->fb_size); > + if (EFI_ERROR(status)) { > + efifb->fb_addr = 0; > + efifb->fb_size = 0; > + } > + > + /* > + * There's no reliable way to detect the frame buffer or the > + * offset within the frame buffer of the visible region, nor > + * the stride. Our only option is to look at the system and > + * fill in the blanks based on that. Luckily, UGA was mostly > + * only used on Apple hardware. > + */ > + offset = -1; > + ev = getenv("smbios.system.maker"); > + if (ev != NULL && !strcmp(ev, "Apple Inc.")) { > + ev = getenv("smbios.system.product"); > + if (ev != NULL && !strcmp(ev, "iMac7,1")) { > + /* These are the expected values we should have. */ > + horiz = 1680; > + vert = 1050; > + fbaddr = 0xc0000000; > + /* These are the missing bits. */ > + offset = 0x10000; > + stride = 1728; > + } else if (ev != NULL && !strcmp(ev, "MacBook3,1")) { > + /* These are the expected values we should have. */ > + horiz = 1280; > + vert = 800; > + fbaddr = 0xc0000000; > + /* These are the missing bits. */ > + offset = 0x0; > + stride = 2048; > + } > + } > + > + /* > + * If this is hardware we know, make sure that it looks familiar > + * before we accept our hardcoded values. > + */ > + if (offset >= 0 && efifb->fb_width == horiz && > + efifb->fb_height == vert && efifb->fb_addr == fbaddr) { > + efifb->fb_addr += offset; > + efifb->fb_size -= offset; > + efifb->fb_stride = stride; > + return (0); > + } else if (offset >= 0) { > + printf("Hardware make/model known, but graphics not " > + "as expected.\n"); > + printf("Console may not work!\n"); > + } > + > /* > * The stride is equal or larger to the width. Often it's the > * next larger power of two. We'll start with that... > @@ -298,16 +357,11 @@ efifb_from_uga(struct efi_fb *efifb, EFI > } > } while (np); > > - /* pciio can be NULL on return! */ > - pciio = efifb_uga_get_pciio(); > - > - ev = getenv("uga_framebuffer"); > + ev = getenv("hw.efifb.address"); > if (ev == NULL) { > - /* Try to find the frame buffer. */ > - status = efifb_uga_locate_framebuffer(pciio, &efifb->fb_addr, > - &efifb->fb_size); > - if (EFI_ERROR(status)) { > - printf("Please set uga_framebuffer!\n"); > + if (efifb->fb_addr == 0) { > + printf("Please set hw.efifb.address and " > + "hw.efifb.stride.\n"); > return (1); > } > > @@ -328,30 +382,30 @@ efifb_from_uga(struct efi_fb *efifb, EFI > * to not appear to hang when we can't read from the > * frame buffer. > */ > - ofs = efifb_uga_find_pixel(uga, 0, pciio, efifb->fb_addr, > + offset = efifb_uga_find_pixel(uga, 0, pciio, efifb->fb_addr, > efifb->fb_size >> 8); > - if (ofs == -1) { > + if (offset == -1) { > printf("Unable to reliably detect frame buffer.\n"); > - } else if (ofs > 0) { > - efifb->fb_addr += ofs; > - efifb->fb_size -= ofs; > + } else if (offset > 0) { > + efifb->fb_addr += offset; > + efifb->fb_size -= offset; > } > } else { > - ofs = 0; > + offset = 0; > efifb->fb_size = efifb->fb_height * efifb->fb_stride * 4; > efifb->fb_addr = strtoul(ev, &p, 0); > if (*p != '\0') > return (1); > } > > - ev = getenv("uga_stride"); > + ev = getenv("hw.efifb.stride"); > if (ev == NULL) { > - if (pciio != NULL && ofs != -1) { > + if (pciio != NULL && offset != -1) { > /* Determine the stride. */ > - ofs = efifb_uga_find_pixel(uga, 1, pciio, > + offset = efifb_uga_find_pixel(uga, 1, pciio, > efifb->fb_addr, horiz * 8); > - if (ofs != -1) > - efifb->fb_stride = ofs >> 2; > + if (offset != -1) > + efifb->fb_stride = offset >> 2; > } else { > printf("Unable to reliably detect the stride.\n"); > } >