From owner-svn-src-head@FreeBSD.ORG Mon Aug 26 18:27:51 2013 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 6CFB1CBF; Mon, 26 Aug 2013 18:27:51 +0000 (UTC) (envelope-from jhb@freebsd.org) Received: from bigwig.baldwin.cx (bigwig.baldwin.cx [IPv6:2001:470:1f11:75::1]) (using TLSv1 with cipher ADH-CAMELLIA256-SHA (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 06D4F263E; Mon, 26 Aug 2013 18:27:51 +0000 (UTC) Received: from jhbbsd.localnet (unknown [38.105.238.108]) by bigwig.baldwin.cx (Postfix) with ESMTPSA id BF0DFB962; Mon, 26 Aug 2013 14:27:49 -0400 (EDT) From: John Baldwin To: "Jean-Sebastien Pedron" Subject: Re: svn commit: r254882 - head/sys/dev/pci Date: Mon, 26 Aug 2013 10:55:17 -0400 User-Agent: KMail/1.13.5 (FreeBSD/8.2-CBSD-20110714-p28; KDE/4.5.5; amd64; ; ) References: <201308251809.r7PI9CsE052978@svn.freebsd.org> In-Reply-To: <201308251809.r7PI9CsE052978@svn.freebsd.org> MIME-Version: 1.0 Message-Id: <201308261055.17964.jhb@freebsd.org> Content-Type: Text/Plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Greylist: Sender succeeded SMTP AUTH, not delayed by milter-greylist-4.2.7 (bigwig.baldwin.cx); Mon, 26 Aug 2013 14:27:49 -0400 (EDT) Cc: svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.14 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: Mon, 26 Aug 2013 18:27:51 -0000 On Sunday, August 25, 2013 2:09:12 pm Jean-Sebastien Pedron wrote: > Author: dumbbell > Date: Sun Aug 25 18:09:11 2013 > New Revision: 254882 > URL: http://svnweb.freebsd.org/changeset/base/254882 > > Log: > vga_pci: Add API to map the Video BIOS > > Here are two new functions to map and unmap the Video BIOS: > void * vga_pci_map_bios(device_t dev, size_t *size); > void vga_pci_unmap_bios(device_t dev, void *bios); > > The BIOS is either taken from the shadow copy made by the System BIOS at > boot time if the given device was used for the default display (i386, > amd64 and ia64 only), or from the PCI expansion ROM. > > Additionally, one can determine if a given device was the default > display at boot time using the following new function: > void vga_pci_unmap_bios(device_t dev, void *bios); > > Modified: > head/sys/dev/pci/pcivar.h > head/sys/dev/pci/vga_pci.c > > Modified: head/sys/dev/pci/pcivar.h > ============================================================================== > --- head/sys/dev/pci/pcivar.h Sun Aug 25 17:26:05 2013 (r254881) > +++ head/sys/dev/pci/pcivar.h Sun Aug 25 18:09:11 2013 (r254882) > @@ -517,4 +517,11 @@ extern uint32_t pci_generation; > struct pci_map *pci_find_bar(device_t dev, int reg); > int pci_bar_enabled(device_t dev, struct pci_map *pm); > > +#define VGA_PCI_BIOS_SHADOW_ADDR 0xC0000 > +#define VGA_PCI_BIOS_SHADOW_SIZE 131072 > + > +int vga_pci_is_boot_display(device_t dev); > +void * vga_pci_map_bios(device_t dev, size_t *size); > +void vga_pci_unmap_bios(device_t dev, void *bios); > + > #endif /* _PCIVAR_H_ */ > > Modified: head/sys/dev/pci/vga_pci.c > ============================================================================== > --- head/sys/dev/pci/vga_pci.c Sun Aug 25 17:26:05 2013 (r254881) > +++ head/sys/dev/pci/vga_pci.c Sun Aug 25 18:09:11 2013 (r254882) > @@ -46,6 +46,11 @@ __FBSDID("$FreeBSD$"); > #include > #include > > +#if defined(__amd64__) || defined(__i386__) || defined(__ia64__) > +#include > +#include > +#endif > + > #include > #include > > @@ -67,6 +72,99 @@ TUNABLE_INT("hw.pci.default_vgapci_unit" > SYSCTL_INT(_hw_pci, OID_AUTO, default_vgapci_unit, CTLFLAG_RDTUN, > &vga_pci_default_unit, -1, "Default VGA-compatible display"); > > +int > +vga_pci_is_boot_display(device_t dev) > +{ > + > + /* > + * Return true if the given device is the default display used > + * at boot time. > + */ > + > + return ( > + (pci_get_class(dev) == PCIC_DISPLAY || > + (pci_get_class(dev) == PCIC_OLD && > + pci_get_subclass(dev) == PCIS_OLD_VGA)) && > + device_get_unit(dev) == vga_pci_default_unit); > +} > + > +void * > +vga_pci_map_bios(device_t dev, size_t *size) > +{ > + int rid; > + struct resource *res; > + > +#if defined(__amd64__) || defined(__i386__) || defined(__ia64__) > + if (vga_pci_is_boot_display(dev)) { > + /* > + * On x86, the System BIOS copy the default display > + * device's Video BIOS at a fixed location in system > + * memory (0xC0000, 128 kBytes long) at boot time. > + * > + * We use this copy for the default boot device, because > + * the original ROM may not be valid after boot. > + */ > + > + printf("%s: Mapping BIOS shadow\n", __func__); > + *size = VGA_PCI_BIOS_SHADOW_SIZE; > + return (pmap_mapbios(VGA_PCI_BIOS_SHADOW_ADDR, *size)); > + } > +#endif > + > + printf("%s: Mapping PCI expansion ROM\n", __func__); > + rid = PCIR_BIOS; > + res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); > + if (res == NULL) { > + return (NULL); > + } > + > + *size = rman_get_size(res); > + return (rman_get_virtual(res)); > +} > + > +void > +vga_pci_unmap_bios(device_t dev, void *bios) > +{ > + int rid; > + struct resource *res; > + > + if (bios == NULL) { > + return; > + } > + > +#if defined(__amd64__) || defined(__i386__) || defined(__ia64__) > + if (vga_pci_is_boot_display(dev)) { > + /* We mapped the BIOS shadow copy located at 0xC0000. */ > + printf("%s: Unmapping BIOS shadow\n", __func__); > + pmap_unmapdev((vm_offset_t)bios, VGA_PCI_BIOS_SHADOW_SIZE); > + > + return; > + } > +#endif > + > + /* > + * FIXME: We returned only the virtual address of the resource > + * to the caller. Now, to get the resource struct back, we > + * allocate it again: the struct exists once in memory in > + * device softc. Therefore, we release twice now to release the > + * reference we just obtained to get the structure back and the > + * caller's reference. > + */ This won't actually work (the PCI bus will panic when you do the duplicate alloc). Why not put this in the softc of the vga_pci device? In fact, it is already there. You just need to bump the vr_refs on the vga_bios resource similar to what vga_pci_alloc_resource() does. Also, returning a void * for this API seems rather hacky. Have you considered returning a struct resource * instead (and requiring the caller to use bus_space_* on it)? That would be more consistent with new-bus. I can help with getting the right bus_alloc_resource() incantation to alloc a struct resource * for the shadow copy if so. -- John Baldwin