Add initial version of calling VGA POST from vga_resume. This is the

equivalent to "vbetool post" using x86emu in the kernel.
This commit is contained in:
joerg 2007-12-25 14:22:25 +00:00
parent 891d658a22
commit 9a98cd19ff
6 changed files with 253 additions and 7 deletions

View File

@ -1,4 +1,4 @@
# $NetBSD: ALL,v 1.148 2007/12/21 15:20:13 jmcneill Exp $
# $NetBSD: ALL,v 1.149 2007/12/25 14:22:26 joerg Exp $
# From NetBSD: GENERIC,v 1.787 2006/10/01 18:37:54 bouyer Exp
#
# ALL machine description file
@ -17,7 +17,7 @@ include "arch/i386/conf/std.i386"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
#ident "ALL-$Revision: 1.148 $"
#ident "ALL-$Revision: 1.149 $"
maxusers 32 # estimated number of users
@ -287,6 +287,8 @@ options PCDISPLAY_SOFTCURSOR
options VGA_CONSOLE_SCREENTYPE="\"80x24\""
# work around a hardware bug that loaded fonts don't work; found on ATI cards
options VGA_CONSOLE_ATI_BROKEN_FONTSEL
# issue VGA BIOS POST on resume
options VGA_POST
# console scrolling support.
options WSDISPLAY_SCROLLSUPPORT
# enable VGA raster mode capable of displaying multilingual text on console

View File

@ -1,4 +1,4 @@
# $NetBSD: files.x86,v 1.37 2007/12/18 07:17:16 joerg Exp $
# $NetBSD: files.x86,v 1.38 2007/12/25 14:22:26 joerg Exp $
# options for MP configuration through the MP spec
defflag opt_mpbios.h MPBIOS MPVERBOSE MPDEBUG MPBIOS_SCANPCI
@ -96,3 +96,5 @@ file arch/x86/x86/coretemp.c intel_coretemp
device ipmi: sysmon_envsys, sysmon_wdog
attach ipmi at ipmibus
file arch/x86/x86/ipmi.c ipmi needs-flag
file arch/x86/x86/vga_post.c vga_post

View File

@ -0,0 +1,40 @@
/*-
* Copyright (c) 2007 Joerg Sonnenberger <joerg@NetBSD.org>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#ifndef _X86_VGA_POST_H_
#define _X86_VGA_POST_H_
#ifdef _KERNEL
struct vga_post;
struct vga_post *vga_post_init(int, int, int);
void vga_post_free(struct vga_post *);
void vga_post_call(struct vga_post *);
#endif
#endif

182
sys/arch/x86/x86/vga_post.c Normal file
View File

@ -0,0 +1,182 @@
/*-
* Copyright (c) 2007 Joerg Sonnenberger <joerg@NetBSD.org>.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in
* the documentation and/or other materials provided with the
* distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
* COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/param.h>
#include <sys/device.h>
#include <sys/kmem.h>
#include <uvm/uvm_extern.h>
#include <uvm/uvm_page.h>
#include <machine/pio.h>
#include <x86/vga_post.h>
#include <x86emu/x86emu.h>
#include <x86emu/x86emu_i8254.h>
#include <x86emu/x86emu_regs.h>
struct vga_post {
struct X86EMU emu;
vaddr_t sys_image;
uint32_t initial_eax;
struct x86emu_i8254 i8254;
};
static uint8_t
vm86_emu_inb(struct X86EMU *emu, uint16_t port)
{
struct vga_post *sc = emu->sys_private;
if (port == 0xb2) /* APM scratch register */
return 0;
if (port >= 0x80 && port < 0x88) /* POST status register */
return 0;
if (x86emu_i8254_claim_port(&sc->i8254, port) && 0) {
return x86emu_i8254_inb(&sc->i8254, port);
} else
return inb(port);
}
static uint16_t
vm86_emu_inw(struct X86EMU *emu, uint16_t port)
{
if (port >= 0x80 && port < 0x88) /* POST status register */
return 0;
return inw(port);
}
static uint32_t
vm86_emu_inl(struct X86EMU *emu, uint16_t port)
{
if (port >= 0x80 && port < 0x88) /* POST status register */
return 0;
return inl(port);
}
static void
vm86_emu_outb(struct X86EMU *emu, uint16_t port, uint8_t val)
{
struct vga_post *sc = emu->sys_private;
if (port == 0xb2) /* APM scratch register */
return;
if (port >= 0x80 && port < 0x88) /* POST status register */
return;
if (x86emu_i8254_claim_port(&sc->i8254, port) && 0) {
x86emu_i8254_outb(&sc->i8254, port, val);
} else
outb(port, val);
}
static void
vm86_emu_outw(struct X86EMU *emu, uint16_t port, uint16_t val)
{
if (port >= 0x80 && port < 0x88) /* POST status register */
return;
outw(port, val);
}
static void
vm86_emu_outl(struct X86EMU *emu, uint16_t port, uint32_t val)
{
if (port >= 0x80 && port < 0x88) /* POST status register */
return;
outl(port, val);
}
struct vga_post *
vga_post_init(int bus, int device, int function)
{
struct vga_post *sc;
vaddr_t rom;
vaddr_t sys_image;
sys_image = uvm_km_alloc(kernel_map, 1024 * 1024, 0, UVM_KMF_VAONLY);
if (sys_image == 0)
return NULL;
sc = kmem_alloc(sizeof(*sc), KM_SLEEP);
sc->sys_image = sys_image;
sc->emu.sys_private = sc;
pmap_kenter_pa(sc->sys_image, 0, VM_PROT_READ | VM_PROT_WRITE);
for (rom = 640 * 1024; rom < 1024 * 1024; rom += 4096)
pmap_kenter_pa(sc->sys_image + rom, rom, VM_PROT_READ | VM_PROT_WRITE);
pmap_update(pmap_kernel());
memset(&sc->emu, 0, sizeof(sc->emu));
X86EMU_init_default(&sc->emu);
sc->emu.emu_inb = vm86_emu_inb;
sc->emu.emu_inw = vm86_emu_inw;
sc->emu.emu_inl = vm86_emu_inl;
sc->emu.emu_outb = vm86_emu_outb;
sc->emu.emu_outw = vm86_emu_outw;
sc->emu.emu_outl = vm86_emu_outl;
sc->emu.mem_base = (char *)sc->sys_image;
sc->emu.mem_size = 1024 * 1024;
sc->initial_eax = bus * 256 + device * 8 + function;
return sc;
}
void
vga_post_call(struct vga_post *sc)
{
sc->emu.x86.R_EAX = sc->initial_eax;
sc->emu.x86.R_EDX = 0x00000080;
sc->emu.x86.R_DS = 0x0040;
sc->emu.x86.register_flags = 0x3200;
/* stack is at the end of the first 4KB */
sc->emu.x86.R_SS = 0;
sc->emu.x86.R_ESP = 4096;
x86emu_i8254_init(&sc->i8254, nanotime);
/* Jump straight into the VGA BIOS POST code */
X86EMU_exec_call(&sc->emu, 0xc000, 0x0003);
}
void
vga_post_free(struct vga_post *sc)
{
pmap_kremove(sc->sys_image, 1024 * 1024);
pmap_update(pmap_kernel());
kmem_free(sc, sizeof(*sc));
}

View File

@ -1,4 +1,4 @@
# $NetBSD: files.pci,v 1.299 2007/12/15 05:46:21 dyoung Exp $
# $NetBSD: files.pci,v 1.300 2007/12/25 14:22:25 joerg Exp $
#
# Config file and device description for machine-independent PCI code.
# Included by ports that need it. Requires that the SCSI files be
@ -391,6 +391,7 @@ attach esh at pci with esh_pci
file dev/pci/if_esh_pci.c esh_pci
# generic PCI VGA
defflag opt_vga.h VGA_POST
attach vga at pci with vga_pci
file dev/pci/vga_pci.c vga_pci needs-flag

View File

@ -1,4 +1,4 @@
/* $NetBSD: vga_pci.c,v 1.37 2007/12/09 20:28:13 jmcneill Exp $ */
/* $NetBSD: vga_pci.c,v 1.38 2007/12/25 14:22:26 joerg Exp $ */
/*
* Copyright (c) 1995, 1996 Carnegie-Mellon University.
@ -28,7 +28,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: vga_pci.c,v 1.37 2007/12/09 20:28:13 jmcneill Exp $");
__KERNEL_RCSID(0, "$NetBSD: vga_pci.c,v 1.38 2007/12/25 14:22:26 joerg Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@ -52,6 +52,12 @@ __KERNEL_RCSID(0, "$NetBSD: vga_pci.c,v 1.37 2007/12/09 20:28:13 jmcneill Exp $"
#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wsdisplayvar.h>
#include "opt_vga.h"
#ifdef VGA_POST
#include <x86/vga_post.h>
#endif
#define NBARS 6 /* number of PCI BARs */
struct vga_bar {
@ -70,7 +76,9 @@ struct vga_pci_softc {
struct vga_bar sc_bars[NBARS];
struct vga_bar sc_rom;
struct pci_conf_state sc_pciconf;
#ifdef VGA_POST
struct vga_post *sc_posth;
#endif
};
static int vga_pci_match(struct device *, struct cfdata *, void *);
@ -221,6 +229,12 @@ vga_pci_attach(struct device *parent, struct device *self, void *aux)
vga_common_attach(sc, pa->pa_iot, pa->pa_memt, WSDISPLAY_TYPE_PCIVGA,
vga_pci_lookup_quirks(pa), &vga_pci_funcs);
#ifdef VGA_POST
psc->sc_posth = vga_post_init(pa->pa_bus, pa->pa_device, pa->pa_function);
if (psc->sc_posth == NULL)
aprint_error_dev(self, "WARNING: could not prepare POST handler\n");
#endif
/*
* XXX Do not use the generic PCI framework for now as
* XXX it would power down the device when the console
@ -238,6 +252,11 @@ vga_pci_resume(device_t dv)
vga_resume(&sc->sc_vga);
#ifdef VGA_POST
if (sc->sc_posth != NULL)
vga_post_call(sc->sc_posth);
#endif
return true;
}