Redo testbios utility to use all of YABEL
Drop buggy duplicate implementation of intXX handlers and provide enough glue to use all of YABEL. Change-Id: I2db77a56a2a991cb84876456dcbb3a843a0d9754 Signed-off-by: Stefan Reinauer <stefan.reinauer@coreboot.org> Reviewed-on: https://review.coreboot.org/12117 Reviewed-by: Ronald G. Minnich <rminnich@gmail.com> Tested-by: build bot (Jenkins)
This commit is contained in:
parent
eb960f1af9
commit
05082737a9
|
@ -1,3 +1,18 @@
|
|||
##
|
||||
## This file is part of the coreboot project.
|
||||
##
|
||||
## Copyright (C) 2016 Google Inc.
|
||||
##
|
||||
## This program is free software; you can redistribute it and/or modify
|
||||
## it under the terms of the GNU General Public License as published by
|
||||
## the Free Software Foundation; version 2 of the License.
|
||||
##
|
||||
## This program is distributed in the hope that it will be useful,
|
||||
## but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
## GNU General Public License for more details.
|
||||
##
|
||||
|
||||
#
|
||||
# NOTE: You need to add your libpci.a version to CFLAGS below if
|
||||
# pci-userspace.c does not build.
|
||||
|
@ -7,33 +22,55 @@
|
|||
#
|
||||
|
||||
TOP ?= ../..
|
||||
OUT ?= build
|
||||
|
||||
CC ?= gcc
|
||||
CFLAGS ?= -O2 -g -fomit-frame-pointer
|
||||
|
||||
CFLAGS += -Wall -Wundef -Wstrict-prototypes -Wmissing-prototypes
|
||||
CFLAGS += -Wwrite-strings -Wredundant-decls -Wstrict-aliasing -Wshadow -Wextra
|
||||
CFLAGS += -Wno-unused-but-set-variable
|
||||
|
||||
# TODO check host architecture
|
||||
CBCFLAGS = -DCONFIG_ARCH_X86=1 -Wno-sign-compare -Wno-unused-but-set-variable -Wno-unused-parameter
|
||||
CBCFLAGS = -Wno-sign-compare -Wno-unused-parameter -Wno-format
|
||||
|
||||
INCLUDES = -Iinclude -I$(TOP)/src/device/oprom/include/
|
||||
CBINCLUDES = -I$(TOP)/src --include include/stdtypes.h
|
||||
CBINCLUDES += --include $(TOP)/src/commonlib/include/commonlib/loglevel.h
|
||||
CBINCLUDES += -include stdio.h
|
||||
INCLUDES = -Iinclude -I$(OUT)/include
|
||||
INCLUDES += -I$(TOP)/src/device/oprom/include/
|
||||
INCLUDES += -I$(TOP)/src/device/oprom/yabel
|
||||
INCLUDES += -include $(TOP)/src/commonlib/include/commonlib/loglevel.h
|
||||
INCLUDES += -include stdtypes.h -include pci-userspace.h
|
||||
INCLUDES += -include $(TOP)/src/include/kconfig.h
|
||||
|
||||
SOURCE = int10.c int15.c int16.c int1a.c inte6.c testbios.c
|
||||
SOURCE += helper_exec.c helper_mem.c pci-userspace.c
|
||||
CBINCLUDES = -I$(TOP)/src -include include/stdtypes.h -include $(TOP)/src/include/endian.h
|
||||
CBINCLUDES += -include stdio.h -include sys/io.h
|
||||
|
||||
X86EMU = sys.c decode.c ops.c ops2.c prim_ops.c fpu.c debug.c
|
||||
X86EMU_DIR = $(TOP)/src/device/oprom/x86emu
|
||||
SOURCE = testbios.c
|
||||
SOURCE += pci-userspace.c
|
||||
SOURCE += device.c
|
||||
|
||||
X86EMU = x86emu/sys.c x86emu/decode.c x86emu/ops.c x86emu/ops2.c
|
||||
X86EMU += x86emu/prim_ops.c x86emu/fpu.c x86emu/debug.c
|
||||
|
||||
X86EMU += yabel/interrupt.c
|
||||
X86EMU += yabel/mem.c
|
||||
X86EMU += yabel/io.c
|
||||
X86EMU += yabel/pmm.c
|
||||
X86EMU += yabel/biosemu.c
|
||||
X86EMU += yabel/debug.c
|
||||
#X86EMU += yabel/device.c # For now we need a local copy :-(
|
||||
|
||||
|
||||
|
||||
X86EMU_DIR = $(TOP)/src/device/oprom
|
||||
X86EMU_SOURCE = $(addprefix $(X86EMU_DIR)/, $(X86EMU))
|
||||
OBJECTS:=$(SOURCE:.c=.o) $(X86EMU:.c=.o)
|
||||
OBJECTS:=$(addprefix $(OUT)/,$(SOURCE:.c=.o)) $(addprefix $(OUT)/, $(X86EMU:.c=.o))
|
||||
|
||||
LIBS=-lpci
|
||||
|
||||
all: dep testbios
|
||||
|
||||
$(OBJECTS): includes
|
||||
|
||||
testbios: $(OBJECTS)
|
||||
printf " LINK $(notdir $@)\n"
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
|
||||
|
@ -42,21 +79,37 @@ dep: $(SOURCE) $(X86EMU_SOURCE) Makefile
|
|||
$(CC) $(CFLAGS) $(INCLUDES) -MM $(SOURCE) > .dependencies
|
||||
$(CC) $(CFLAGS) $(INCLUDES) $(CBCFLAGS) $(CBINCLUDES) -MM $(X86EMU_SOURCE) >> .dependencies
|
||||
|
||||
# Make all the dummy include files (that are in reality
|
||||
# covered by all the -include statements above)
|
||||
includes:
|
||||
mkdir -p $(OUT)/include/device
|
||||
mkdir -p $(OUT)/include/arch
|
||||
touch $(OUT)/include/device/device.h
|
||||
touch $(OUT)/include/device/pci.h
|
||||
touch $(OUT)/include/device/pci_ops.h
|
||||
touch $(OUT)/include/device/resource.h
|
||||
touch $(OUT)/include/arch/io.h
|
||||
touch $(OUT)/include/timer.h
|
||||
touch $(OUT)/include/types.h
|
||||
|
||||
clean:
|
||||
rm -f *.o *~ testbios
|
||||
rm -f $(OBJECTS) *~ testbios
|
||||
rm -rf $(OUT)
|
||||
|
||||
distclean: clean
|
||||
rm -f .dependencies
|
||||
|
||||
%.o: $(X86EMU_DIR)/%.c
|
||||
$(OUT)/%.o: $(X86EMU_DIR)/%.c
|
||||
printf " CC (x86emu) $(notdir $<)\n"
|
||||
mkdir -p $(dir $@)
|
||||
$(CC) $(CFLAGS) $(CBCFLAGS) $(INCLUDES) $(CBINCLUDES) -c -o $@ $<
|
||||
|
||||
%.o: %.c
|
||||
$(OUT)/%.o: %.c
|
||||
printf " CC $(notdir $<)\n"
|
||||
mkdir -p $(dir $@)
|
||||
$(CC) $(CFLAGS) $(INCLUDES) -c -o $@ $<
|
||||
|
||||
.PHONY: all clean distclean
|
||||
.PHONY: all includes clean distclean
|
||||
.SILENT:
|
||||
|
||||
-include .dependencies
|
||||
|
|
|
@ -0,0 +1,482 @@
|
|||
/******************************************************************************
|
||||
* Copyright (c) 2004, 2008 IBM Corporation
|
||||
* Copyright (c) 2008, 2009 Pattrick Hueper <phueper@hueper.net>
|
||||
* All rights reserved.
|
||||
* This program and the accompanying materials
|
||||
* are made available under the terms of the BSD License
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.opensource.org/licenses/bsd-license.php
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial implementation
|
||||
*****************************************************************************/
|
||||
|
||||
|
||||
#include <stdtypes.h>
|
||||
|
||||
#include <arch/byteorder.h>
|
||||
#include "device.h"
|
||||
#include "compat/rtas.h"
|
||||
#include <string.h>
|
||||
#include "debug.h"
|
||||
|
||||
#include <device/device.h>
|
||||
#include <device/pci.h>
|
||||
#include <device/pci_ops.h>
|
||||
#include <device/resource.h>
|
||||
|
||||
/* the device we are working with... */
|
||||
biosemu_device_t bios_device;
|
||||
//max. 6 BARs and 1 Exp.ROM plus CfgSpace and 3 legacy ranges, plus 2 "special" memory ranges
|
||||
translate_address_t translate_address_array[13];
|
||||
u8 taa_last_entry;
|
||||
|
||||
typedef struct {
|
||||
u8 info;
|
||||
u8 bus;
|
||||
u8 devfn;
|
||||
u8 cfg_space_offset;
|
||||
u64 address;
|
||||
u64 size;
|
||||
} __attribute__ ((__packed__)) assigned_address_t;
|
||||
|
||||
#if CONFIG_PCI_OPTION_ROM_RUN_YABEL
|
||||
/* coreboot version */
|
||||
|
||||
static void
|
||||
biosemu_dev_get_addr_info(void)
|
||||
{
|
||||
#if 0
|
||||
int taa_index = 0;
|
||||
struct resource *r;
|
||||
u8 bus = bios_device.dev->bus->secondary;
|
||||
u16 devfn = bios_device.dev->path.pci.devfn;
|
||||
|
||||
bios_device.bus = bus;
|
||||
bios_device.devfn = devfn;
|
||||
|
||||
DEBUG_PRINTF("bus: %x, devfn: %x\n", bus, devfn);
|
||||
for (r = bios_device.dev->resource_list; r; r = r->next) {
|
||||
translate_address_array[taa_index].info = r->flags;
|
||||
translate_address_array[taa_index].bus = bus;
|
||||
translate_address_array[taa_index].devfn = devfn;
|
||||
translate_address_array[taa_index].cfg_space_offset =
|
||||
r->index;
|
||||
translate_address_array[taa_index].address = r->base;
|
||||
translate_address_array[taa_index].size = r->size;
|
||||
/* don't translate addresses... all addresses are 1:1 */
|
||||
translate_address_array[taa_index].address_offset = 0;
|
||||
taa_index++;
|
||||
}
|
||||
/* Expansion ROM */
|
||||
translate_address_array[taa_index].info = IORESOURCE_MEM | IORESOURCE_READONLY;
|
||||
translate_address_array[taa_index].bus = bus;
|
||||
translate_address_array[taa_index].devfn = devfn;
|
||||
translate_address_array[taa_index].cfg_space_offset = 0x30;
|
||||
translate_address_array[taa_index].address = bios_device.img_addr;
|
||||
translate_address_array[taa_index].size = 0; /* TODO: do we need the size? */
|
||||
/* don't translate addresses... all addresses are 1:1 */
|
||||
translate_address_array[taa_index].address_offset = 0;
|
||||
taa_index++;
|
||||
/* legacy ranges if its a VGA card... */
|
||||
if ((bios_device.dev->class & 0xFF0000) == 0x030000) {
|
||||
DEBUG_PRINTF("%s: VGA device found, adding legacy resources... \n", __func__);
|
||||
/* I/O 0x3B0-0x3BB */
|
||||
translate_address_array[taa_index].info = IORESOURCE_FIXED | IORESOURCE_IO;
|
||||
translate_address_array[taa_index].bus = bus;
|
||||
translate_address_array[taa_index].devfn = devfn;
|
||||
translate_address_array[taa_index].cfg_space_offset = 0;
|
||||
translate_address_array[taa_index].address = 0x3b0;
|
||||
translate_address_array[taa_index].size = 0xc;
|
||||
/* don't translate addresses... all addresses are 1:1 */
|
||||
translate_address_array[taa_index].address_offset = 0;
|
||||
taa_index++;
|
||||
/* I/O 0x3C0-0x3DF */
|
||||
translate_address_array[taa_index].info = IORESOURCE_FIXED | IORESOURCE_IO;
|
||||
translate_address_array[taa_index].bus = bus;
|
||||
translate_address_array[taa_index].devfn = devfn;
|
||||
translate_address_array[taa_index].cfg_space_offset = 0;
|
||||
translate_address_array[taa_index].address = 0x3c0;
|
||||
translate_address_array[taa_index].size = 0x20;
|
||||
/* don't translate addresses... all addresses are 1:1 */
|
||||
translate_address_array[taa_index].address_offset = 0;
|
||||
taa_index++;
|
||||
/* Mem 0xA0000-0xBFFFF */
|
||||
translate_address_array[taa_index].info = IORESOURCE_FIXED | IORESOURCE_MEM;
|
||||
translate_address_array[taa_index].bus = bus;
|
||||
translate_address_array[taa_index].devfn = devfn;
|
||||
translate_address_array[taa_index].cfg_space_offset = 0;
|
||||
translate_address_array[taa_index].address = 0xa0000;
|
||||
translate_address_array[taa_index].size = 0x20000;
|
||||
/* don't translate addresses... all addresses are 1:1 */
|
||||
translate_address_array[taa_index].address_offset = 0;
|
||||
taa_index++;
|
||||
}
|
||||
// store last entry index of translate_address_array
|
||||
taa_last_entry = taa_index - 1;
|
||||
#if CONFIG_X86EMU_DEBUG
|
||||
//dump translate_address_array
|
||||
printf("translate_address_array: \n");
|
||||
translate_address_t ta;
|
||||
int i;
|
||||
for (i = 0; i <= taa_last_entry; i++) {
|
||||
ta = translate_address_array[i];
|
||||
printf
|
||||
("%d: info: %08lx bus: %02x devfn: %02x cfg_space_offset: %02x\n\taddr: %016llx\n\toffs: %016llx\n\tsize: %016llx\n",
|
||||
i, ta.info, ta.bus, ta.devfn, ta.cfg_space_offset,
|
||||
ta.address, ta.address_offset, ta.size);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
// use translate_address_dev and get_puid from net-snk's net_support.c
|
||||
void translate_address_dev(u64 *, phandle_t);
|
||||
u64 get_puid(phandle_t node);
|
||||
|
||||
|
||||
// scan all addresses assigned to the device ("assigned-addresses" and "reg")
|
||||
// store in translate_address_array for faster translation using dev_translate_address
|
||||
void
|
||||
biosemu_dev_get_addr_info(void)
|
||||
{
|
||||
// get bus/dev/fn from assigned-addresses
|
||||
int32_t len;
|
||||
//max. 6 BARs and 1 Exp.ROM plus CfgSpace and 3 legacy ranges
|
||||
assigned_address_t buf[11];
|
||||
len =
|
||||
of_getprop(bios_device.phandle, "assigned-addresses", buf,
|
||||
sizeof(buf));
|
||||
bios_device.bus = buf[0].bus;
|
||||
bios_device.devfn = buf[0].devfn;
|
||||
DEBUG_PRINTF("bus: %x, devfn: %x\n", bios_device.bus,
|
||||
bios_device.devfn);
|
||||
//store address translations for all assigned-addresses and regs in
|
||||
//translate_address_array for faster translation later on...
|
||||
int i = 0;
|
||||
// index to insert data into translate_address_array
|
||||
int taa_index = 0;
|
||||
u64 address_offset;
|
||||
for (i = 0; i < (len / sizeof(assigned_address_t)); i++, taa_index++) {
|
||||
//copy all info stored in assigned-addresses
|
||||
translate_address_array[taa_index].info = buf[i].info;
|
||||
translate_address_array[taa_index].bus = buf[i].bus;
|
||||
translate_address_array[taa_index].devfn = buf[i].devfn;
|
||||
translate_address_array[taa_index].cfg_space_offset =
|
||||
buf[i].cfg_space_offset;
|
||||
translate_address_array[taa_index].address = buf[i].address;
|
||||
translate_address_array[taa_index].size = buf[i].size;
|
||||
// translate first address and store it as address_offset
|
||||
address_offset = buf[i].address;
|
||||
translate_address_dev(&address_offset, bios_device.phandle);
|
||||
translate_address_array[taa_index].address_offset =
|
||||
address_offset - buf[i].address;
|
||||
}
|
||||
//get "reg" property
|
||||
len = of_getprop(bios_device.phandle, "reg", buf, sizeof(buf));
|
||||
for (i = 0; i < (len / sizeof(assigned_address_t)); i++) {
|
||||
if ((buf[i].size == 0) || (buf[i].cfg_space_offset != 0)) {
|
||||
// we don't care for ranges with size 0 and
|
||||
// BARs and Expansion ROM must be in assigned-addresses... so in reg
|
||||
// we only look for those without config space offset set...
|
||||
// i.e. the legacy ranges
|
||||
continue;
|
||||
}
|
||||
//copy all info stored in assigned-addresses
|
||||
translate_address_array[taa_index].info = buf[i].info;
|
||||
translate_address_array[taa_index].bus = buf[i].bus;
|
||||
translate_address_array[taa_index].devfn = buf[i].devfn;
|
||||
translate_address_array[taa_index].cfg_space_offset =
|
||||
buf[i].cfg_space_offset;
|
||||
translate_address_array[taa_index].address = buf[i].address;
|
||||
translate_address_array[taa_index].size = buf[i].size;
|
||||
// translate first address and store it as address_offset
|
||||
address_offset = buf[i].address;
|
||||
translate_address_dev(&address_offset, bios_device.phandle);
|
||||
translate_address_array[taa_index].address_offset =
|
||||
address_offset - buf[i].address;
|
||||
taa_index++;
|
||||
}
|
||||
// store last entry index of translate_address_array
|
||||
taa_last_entry = taa_index - 1;
|
||||
#if CONFIG_X86EMU_DEBUG
|
||||
//dump translate_address_array
|
||||
printf("translate_address_array: \n");
|
||||
translate_address_t ta;
|
||||
for (i = 0; i <= taa_last_entry; i++) {
|
||||
ta = translate_address_array[i];
|
||||
printf
|
||||
("%d: %02x%02x%02x%02x\n\taddr: %016llx\n\toffs: %016llx\n\tsize: %016llx\n",
|
||||
i, ta.info, ta.bus, ta.devfn, ta.cfg_space_offset,
|
||||
ta.address, ta.address_offset, ta.size);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
// "special memory" is a hack to make some parts of memory fall through to real memory
|
||||
// (ie. no translation). Necessary if option ROMs attempt DMA there, map registers or
|
||||
// do similarly crazy things.
|
||||
void
|
||||
biosemu_add_special_memory(u32 start, u32 size)
|
||||
{
|
||||
#if 0
|
||||
int taa_index = ++taa_last_entry;
|
||||
translate_address_array[taa_index].info = IORESOURCE_FIXED | IORESOURCE_MEM;
|
||||
translate_address_array[taa_index].bus = 0;
|
||||
translate_address_array[taa_index].devfn = 0;
|
||||
translate_address_array[taa_index].cfg_space_offset = 0;
|
||||
translate_address_array[taa_index].address = start;
|
||||
translate_address_array[taa_index].size = size;
|
||||
/* don't translate addresses... all addresses are 1:1 */
|
||||
translate_address_array[taa_index].address_offset = 0;
|
||||
#endif
|
||||
printf("TODO: Add special memory handler for %x[%x]\n", start, size);
|
||||
}
|
||||
|
||||
#if !CONFIG_PCI_OPTION_ROM_RUN_YABEL
|
||||
// to simulate accesses to legacy VGA Memory (0xA0000-0xBFFFF)
|
||||
// we look for the first prefetchable memory BAR, if no prefetchable BAR found,
|
||||
// we use the first memory BAR
|
||||
// dev_translate_addr will translate accesses to the legacy VGA Memory into the found vmem BAR
|
||||
static void
|
||||
biosemu_dev_find_vmem_addr(void)
|
||||
{
|
||||
int i = 0;
|
||||
translate_address_t ta;
|
||||
s8 tai_np = -1, tai_p = -1; // translate_address_array index for non-prefetchable and prefetchable memory
|
||||
//search backwards to find first entry
|
||||
for (i = taa_last_entry; i >= 0; i--) {
|
||||
ta = translate_address_array[i];
|
||||
if ((ta.cfg_space_offset >= 0x10)
|
||||
&& (ta.cfg_space_offset <= 0x24)) {
|
||||
//only BARs
|
||||
if ((ta.info & 0x03) >= 0x02) {
|
||||
//32/64bit memory
|
||||
tai_np = i;
|
||||
if ((ta.info & 0x40) != 0) {
|
||||
// prefetchable
|
||||
tai_p = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (tai_p != -1) {
|
||||
ta = translate_address_array[tai_p];
|
||||
bios_device.vmem_addr = ta.address;
|
||||
bios_device.vmem_size = ta.size;
|
||||
DEBUG_PRINTF
|
||||
("%s: Found prefetchable Virtual Legacy Memory BAR: %llx, size: %llx\n",
|
||||
__func__, bios_device.vmem_addr,
|
||||
bios_device.vmem_size);
|
||||
} else if (tai_np != -1) {
|
||||
ta = translate_address_array[tai_np];
|
||||
bios_device.vmem_addr = ta.address;
|
||||
bios_device.vmem_size = ta.size;
|
||||
DEBUG_PRINTF
|
||||
("%s: Found non-prefetchable Virtual Legacy Memory BAR: %llx, size: %llx",
|
||||
__func__, bios_device.vmem_addr,
|
||||
bios_device.vmem_size);
|
||||
}
|
||||
// disable vmem
|
||||
//bios_device.vmem_size = 0;
|
||||
}
|
||||
|
||||
void
|
||||
biosemu_dev_get_puid(void)
|
||||
{
|
||||
// get puid
|
||||
bios_device.puid = get_puid(bios_device.phandle);
|
||||
DEBUG_PRINTF("puid: 0x%llx\n", bios_device.puid);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
biosemu_dev_get_device_vendor_id(void)
|
||||
{
|
||||
|
||||
u32 pci_config_0;
|
||||
#if CONFIG_PCI_OPTION_ROM_RUN_YABEL
|
||||
pci_config_0 = pci_read_config32(bios_device.dev, 0x0);
|
||||
#else
|
||||
pci_config_0 =
|
||||
rtas_pci_config_read(bios_device.puid, 4, bios_device.bus,
|
||||
bios_device.devfn, 0x0);
|
||||
#endif
|
||||
bios_device.pci_device_id =
|
||||
(u16) ((pci_config_0 & 0xFFFF0000) >> 16);
|
||||
bios_device.pci_vendor_id = (u16) (pci_config_0 & 0x0000FFFF);
|
||||
DEBUG_PRINTF("PCI Device ID: %04x, PCI Vendor ID: %x\n",
|
||||
bios_device.pci_device_id, bios_device.pci_vendor_id);
|
||||
}
|
||||
|
||||
/* Check whether the device has a valid Expansion ROM and search the PCI Data
|
||||
* Structure and any Expansion ROM Header (using dev_scan_exp_header()) for
|
||||
* needed information. If the rom_addr parameter is != 0, it is the address of
|
||||
* the Expansion ROM image and will be used, if it is == 0, the Expansion ROM
|
||||
* BAR address will be used.
|
||||
*/
|
||||
u8
|
||||
biosemu_dev_check_exprom(unsigned long rom_base_addr)
|
||||
{
|
||||
#if 0
|
||||
int i = 0;
|
||||
translate_address_t ta;
|
||||
u16 pci_ds_offset;
|
||||
pci_data_struct_t pci_ds;
|
||||
if (rom_base_addr == 0) {
|
||||
// check for ExpROM Address (Offset 30) in taa
|
||||
for (i = 0; i <= taa_last_entry; i++) {
|
||||
ta = translate_address_array[i];
|
||||
if (ta.cfg_space_offset == 0x30) {
|
||||
//translated address
|
||||
rom_base_addr = ta.address + ta.address_offset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* In the ROM there could be multiple Expansion ROM Images... start
|
||||
* searching them for an x86 image.
|
||||
*/
|
||||
do {
|
||||
if (rom_base_addr == 0) {
|
||||
printf("Error: no Expansion ROM address found!\n");
|
||||
return -1;
|
||||
}
|
||||
set_ci();
|
||||
u16 rom_signature = in16le((void *) rom_base_addr);
|
||||
clr_ci();
|
||||
if (rom_signature != 0xaa55) {
|
||||
printf
|
||||
("Error: invalid Expansion ROM signature: %02x!\n",
|
||||
*((u16 *) rom_base_addr));
|
||||
return -1;
|
||||
}
|
||||
set_ci();
|
||||
// at offset 0x18 is the (16bit little-endian) pointer to the PCI Data Structure
|
||||
pci_ds_offset = in16le((void *) (rom_base_addr + 0x18));
|
||||
//copy the PCI Data Structure
|
||||
memcpy(&pci_ds, (void *) (rom_base_addr + pci_ds_offset),
|
||||
sizeof(pci_ds));
|
||||
clr_ci();
|
||||
#if CONFIG_X86EMU_DEBUG
|
||||
DEBUG_PRINTF("PCI Data Structure @%lx:\n",
|
||||
rom_base_addr + pci_ds_offset);
|
||||
dump((void *) &pci_ds, sizeof(pci_ds));
|
||||
#endif
|
||||
if (strncmp((const char *) pci_ds.signature, "PCIR", 4) != 0) {
|
||||
printf("Invalid PCI Data Structure found!\n");
|
||||
break;
|
||||
}
|
||||
//little-endian conversion
|
||||
pci_ds.vendor_id = in16le(&pci_ds.vendor_id);
|
||||
pci_ds.device_id = in16le(&pci_ds.device_id);
|
||||
pci_ds.img_length = in16le(&pci_ds.img_length);
|
||||
pci_ds.pci_ds_length = in16le(&pci_ds.pci_ds_length);
|
||||
#ifdef DO_THIS_TEST_TWICE
|
||||
if (pci_ds.vendor_id != bios_device.pci_vendor_id) {
|
||||
printf
|
||||
("Image has invalid Vendor ID: %04x, expected: %04x\n",
|
||||
pci_ds.vendor_id, bios_device.pci_vendor_id);
|
||||
break;
|
||||
}
|
||||
if (pci_ds.device_id != bios_device.pci_device_id) {
|
||||
printf
|
||||
("Image has invalid Device ID: %04x, expected: %04x\n",
|
||||
pci_ds.device_id, bios_device.pci_device_id);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
DEBUG_PRINTF("Image Length: %d\n", pci_ds.img_length * 512);
|
||||
DEBUG_PRINTF("Image Code Type: %d\n", pci_ds.code_type);
|
||||
if (pci_ds.code_type == 0) {
|
||||
//x86 image
|
||||
//store image address and image length in bios_device struct
|
||||
bios_device.img_addr = rom_base_addr;
|
||||
bios_device.img_size = pci_ds.img_length * 512;
|
||||
// we found the image, exit the loop
|
||||
break;
|
||||
} else {
|
||||
// no x86 image, check next image (if any)
|
||||
rom_base_addr += pci_ds.img_length * 512;
|
||||
}
|
||||
if ((pci_ds.indicator & 0x80) == 0x80) {
|
||||
//last image found, exit the loop
|
||||
DEBUG_PRINTF("Last PCI Expansion ROM Image found.\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
while (bios_device.img_addr == 0);
|
||||
// in case we did not find a valid x86 Expansion ROM Image
|
||||
if (bios_device.img_addr == 0) {
|
||||
printf("Error: no valid x86 Expansion ROM Image found!\n");
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
u8
|
||||
biosemu_dev_init(struct device * device)
|
||||
{
|
||||
u8 rval = 0;
|
||||
//init bios_device struct
|
||||
DEBUG_PRINTF("%s\n", __func__);
|
||||
memset(&bios_device, 0, sizeof(bios_device));
|
||||
|
||||
#if !CONFIG_PCI_OPTION_ROM_RUN_YABEL
|
||||
bios_device.ihandle = of_open(device_name);
|
||||
if (bios_device.ihandle == 0) {
|
||||
DEBUG_PRINTF("%s is no valid device!\n", device_name);
|
||||
return -1;
|
||||
}
|
||||
bios_device.phandle = of_finddevice(device_name);
|
||||
#else
|
||||
bios_device.dev = device;
|
||||
#endif
|
||||
biosemu_dev_get_addr_info();
|
||||
#if !CONFIG_PCI_OPTION_ROM_RUN_YABEL
|
||||
biosemu_dev_find_vmem_addr();
|
||||
biosemu_dev_get_puid();
|
||||
#endif
|
||||
biosemu_dev_get_device_vendor_id();
|
||||
return rval;
|
||||
}
|
||||
|
||||
// translate address function using translate_address_array assembled
|
||||
// by dev_get_addr_info... MUCH faster than calling translate_address_dev
|
||||
// and accessing client interface for every translation...
|
||||
// returns: 0 if addr not found in translate_address_array, 1 if found.
|
||||
u8
|
||||
biosemu_dev_translate_address(int type, unsigned long * addr)
|
||||
{
|
||||
int i = 0;
|
||||
translate_address_t ta;
|
||||
#if !CONFIG_PCI_OPTION_ROM_RUN_YABEL
|
||||
/* we don't need this hack for coreboot... we can access legacy areas */
|
||||
//check if it is an access to legacy VGA Mem... if it is, map the address
|
||||
//to the vmem BAR and then translate it...
|
||||
// (translation info provided by Ben Herrenschmidt)
|
||||
// NOTE: the translation seems to only work for NVIDIA cards... but it is needed
|
||||
// to make some NVIDIA cards work at all...
|
||||
if ((bios_device.vmem_size > 0)
|
||||
&& ((*addr >= 0xA0000) && (*addr < 0xB8000))) {
|
||||
*addr = (*addr - 0xA0000) * 4 + 2 + bios_device.vmem_addr;
|
||||
}
|
||||
if ((bios_device.vmem_size > 0)
|
||||
&& ((*addr >= 0xB8000) && (*addr < 0xC0000))) {
|
||||
u8 shift = *addr & 1;
|
||||
*addr &= 0xfffffffe;
|
||||
*addr = (*addr - 0xB8000) * 4 + shift + bios_device.vmem_addr;
|
||||
}
|
||||
#endif
|
||||
for (i = 0; i <= taa_last_entry; i++) {
|
||||
ta = translate_address_array[i];
|
||||
if ((*addr >= ta.address) && (*addr <= (ta.address + ta.size)) && (ta.info & type)) {
|
||||
*addr += ta.address_offset;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
|
@ -1,269 +0,0 @@
|
|||
/* $XFree86: xc/programs/Xserver/hw/xfree86/int10/helper_exec.c,v 1.16 2001/04/30 14:34:57 tsi Exp $ */
|
||||
/*
|
||||
* XFree86 int10 module
|
||||
* execute BIOS int 10h calls in x86 real mode environment
|
||||
* Copyright 1999 Egbert Eich
|
||||
*
|
||||
* Part of this is based on code taken from DOSEMU
|
||||
* (C) Copyright 1992, ..., 1999 the "DOSEMU-Development-Team"
|
||||
*/
|
||||
|
||||
/*
|
||||
* To debug port accesses define PRINT_PORT.
|
||||
* Note! You also have to comment out ioperm()
|
||||
* in xf86EnableIO(). Otherwise we won't trap
|
||||
* on PIO.
|
||||
*/
|
||||
#include <sys/io.h>
|
||||
#include <sys/time.h>
|
||||
#include <stdio.h>
|
||||
#include <stdtypes.h>
|
||||
#include <x86emu/x86emu.h>
|
||||
#include "helper_exec.h"
|
||||
#include "testbios.h"
|
||||
|
||||
/* general software interrupt handler */
|
||||
u32 getIntVect(int num)
|
||||
{
|
||||
return MEM_RW(num << 2) + (MEM_RW((num << 2) + 2) << 4);
|
||||
}
|
||||
|
||||
void pushw(u16 val)
|
||||
{
|
||||
X86_ESP -= 2;
|
||||
MEM_WW(((u32) X86_SS << 4) + X86_SP, val);
|
||||
}
|
||||
|
||||
int run_bios_int(int num)
|
||||
{
|
||||
u32 eflags;
|
||||
|
||||
eflags = X86_EFLAGS;
|
||||
pushw(eflags);
|
||||
pushw(X86_CS);
|
||||
pushw(X86_IP);
|
||||
X86_CS = MEM_RW((num << 2) + 2);
|
||||
X86_IP = MEM_RW(num << 2);
|
||||
|
||||
printf("%s: INT %x CS:IP = %x:%x\n", __FUNCTION__,
|
||||
num, MEM_RW((num << 2) + 2), MEM_RW(num << 2));
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
|
||||
int port_rep_inb(u16 port, u32 base, int d_f, u32 count)
|
||||
{
|
||||
register int inc = d_f ? -1 : 1;
|
||||
u32 dst = base;
|
||||
while (count--) {
|
||||
MEM_WB(dst, x_inb(port));
|
||||
dst += inc;
|
||||
}
|
||||
return dst - base;
|
||||
}
|
||||
|
||||
int port_rep_inw(u16 port, u32 base, int d_f, u32 count)
|
||||
{
|
||||
register int inc = d_f ? -2 : 2;
|
||||
u32 dst = base;
|
||||
while (count--) {
|
||||
MEM_WW(dst, x_inw(port));
|
||||
dst += inc;
|
||||
}
|
||||
return dst - base;
|
||||
}
|
||||
|
||||
int port_rep_inl(u16 port, u32 base, int d_f, u32 count)
|
||||
{
|
||||
register int inc = d_f ? -4 : 4;
|
||||
u32 dst = base;
|
||||
while (count--) {
|
||||
MEM_WL(dst, x_inl(port));
|
||||
dst += inc;
|
||||
}
|
||||
return dst - base;
|
||||
}
|
||||
|
||||
int port_rep_outb(u16 port, u32 base, int d_f, u32 count)
|
||||
{
|
||||
register int inc = d_f ? -1 : 1;
|
||||
u32 dst = base;
|
||||
while (count--) {
|
||||
x_outb(port, MEM_RB(dst));
|
||||
dst += inc;
|
||||
}
|
||||
return dst - base;
|
||||
}
|
||||
|
||||
int port_rep_outw(u16 port, u32 base, int d_f, u32 count)
|
||||
{
|
||||
register int inc = d_f ? -2 : 2;
|
||||
u32 dst = base;
|
||||
while (count--) {
|
||||
x_outw(port, MEM_RW(dst));
|
||||
dst += inc;
|
||||
}
|
||||
return dst - base;
|
||||
}
|
||||
|
||||
int port_rep_outl(u16 port, u32 base, int d_f, u32 count)
|
||||
{
|
||||
register int inc = d_f ? -4 : 4;
|
||||
u32 dst = base;
|
||||
while (count--) {
|
||||
x_outl(port, MEM_RL(dst));
|
||||
dst += inc;
|
||||
}
|
||||
return dst - base;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
u8 x_inb(u16 port)
|
||||
{
|
||||
u8 val;
|
||||
|
||||
val = inb(port);
|
||||
|
||||
printf("inb(0x%04x) = 0x%02x\n", port, val);
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
u16 x_inw(u16 port)
|
||||
{
|
||||
u16 val;
|
||||
|
||||
val = inw(port);
|
||||
|
||||
printf("inw(0x%04x) = 0x%04x\n", port, val);
|
||||
return val;
|
||||
}
|
||||
|
||||
u32 x_inl(u16 port)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = inl(port);
|
||||
|
||||
printf("inl(0x%04x) = 0x%08x\n", port, val);
|
||||
return val;
|
||||
}
|
||||
|
||||
void x_outb(u16 port, u8 val)
|
||||
{
|
||||
printf("outb(0x%02x, 0x%04x)\n",
|
||||
val, port);
|
||||
outb(val, port);
|
||||
}
|
||||
|
||||
void x_outw(u16 port, u16 val)
|
||||
{
|
||||
printf("outw(0x%04x, 0x%04x)\n", val, port);
|
||||
outw(val, port);
|
||||
}
|
||||
|
||||
void x_outl(u16 port, u32 val)
|
||||
{
|
||||
printf("outl(0x%08x, 0x%04x)\n", val, port);
|
||||
outl(val, port);
|
||||
}
|
||||
|
||||
#if 0
|
||||
u8 Mem_rb(int addr)
|
||||
{
|
||||
return (*current->mem->rb) (current, addr);
|
||||
}
|
||||
|
||||
u16 Mem_rw(int addr)
|
||||
{
|
||||
return (*current->mem->rw) (current, addr);
|
||||
}
|
||||
|
||||
u32 Mem_rl(int addr)
|
||||
{
|
||||
return (*current->mem->rl) (current, addr);
|
||||
}
|
||||
|
||||
void Mem_wb(int addr, u8 val)
|
||||
{
|
||||
(*current->mem->wb) (current, addr, val);
|
||||
}
|
||||
|
||||
void Mem_ww(int addr, u16 val)
|
||||
{
|
||||
(*current->mem->ww) (current, addr, val);
|
||||
}
|
||||
|
||||
void Mem_wl(int addr, u32 val)
|
||||
{
|
||||
(*current->mem->wl) (current, addr, val);
|
||||
}
|
||||
#endif
|
||||
|
||||
void getsecs(unsigned long *sec, unsigned long *usec)
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, 0);
|
||||
*sec = tv.tv_sec;
|
||||
*usec = tv.tv_usec;
|
||||
}
|
||||
|
||||
#define TAG(Cfg1Addr) (Cfg1Addr & 0xffff00)
|
||||
#define OFFSET(Cfg1Addr) (Cfg1Addr & 0xff)
|
||||
|
||||
u8 bios_checksum(u8 * start, int size)
|
||||
{
|
||||
u8 sum = 0;
|
||||
|
||||
while (size-- > 0)
|
||||
sum += *start++;
|
||||
return sum;
|
||||
}
|
||||
|
||||
/*
|
||||
* Lock/Unlock legacy VGA. Some Bioses try to be very clever and make
|
||||
* an attempt to detect a legacy ISA card. If they find one they might
|
||||
* act very strange: for example they might configure the card as a
|
||||
* monochrome card. This might cause some drivers to choke.
|
||||
* To avoid this we attempt legacy VGA by writing to all know VGA
|
||||
* disable registers before we call the BIOS initialization and
|
||||
* restore the original values afterwards. In beween we hold our
|
||||
* breath. To get to a (possibly exising) ISA card need to disable
|
||||
* our current PCI card.
|
||||
*/
|
||||
/*
|
||||
* This is just for booting: we just want to catch pure
|
||||
* legacy vga therefore we don't worry about mmio etc.
|
||||
* This stuff should really go into vgaHW.c. However then
|
||||
* the driver would have to load the vga-module prior to
|
||||
* doing int10.
|
||||
*/
|
||||
/*void
|
||||
LockLegacyVGA(int screenIndex,legacyVGAPtr vga)
|
||||
{
|
||||
xf86SetCurrentAccess(FALSE, xf86Screens[screenIndex]);
|
||||
vga->save_msr = inb(0x3CC);
|
||||
vga->save_vse = inb(0x3C3);
|
||||
vga->save_46e8 = inb(0x46e8);
|
||||
vga->save_pos102 = inb(0x102);
|
||||
outb(0x3C2, ~(u8)0x03 & vga->save_msr);
|
||||
outb(0x3C3, ~(u8)0x01 & vga->save_vse);
|
||||
outb(0x46e8, ~(u8)0x08 & vga->save_46e8);
|
||||
outb(0x102, ~(u8)0x01 & vga->save_pos102);
|
||||
xf86SetCurrentAccess(TRUE, xf86Screens[screenIndex]);
|
||||
}
|
||||
|
||||
void
|
||||
UnlockLegacyVGA(int screenIndex, legacyVGAPtr vga)
|
||||
{
|
||||
xf86SetCurrentAccess(FALSE, xf86Screens[screenIndex]);
|
||||
outb(0x102, vga->save_pos102);
|
||||
outb(0x46e8, vga->save_46e8);
|
||||
outb(0x3C3, vga->save_vse);
|
||||
outb(0x3C2, vga->save_msr);
|
||||
xf86SetCurrentAccess(TRUE, xf86Screens[screenIndex]);
|
||||
}
|
||||
*/
|
|
@ -1,32 +0,0 @@
|
|||
#ifndef __HELPER_EXEC_H__
|
||||
#define __HELPER_EXEC_H__
|
||||
|
||||
u32 getIntVect(int num);
|
||||
int run_bios_int(int num);
|
||||
void pushw(u16 val);
|
||||
|
||||
int port_rep_inb(u16 port, u32 base, int d_f, u32 count);
|
||||
int port_rep_inw(u16 port, u32 base, int d_f, u32 count);
|
||||
int port_rep_inl(u16 port, u32 base, int d_f, u32 count);
|
||||
int port_rep_outb(u16 port, u32 base, int d_f, u32 count);
|
||||
int port_rep_outw(u16 port, u32 base, int d_f, u32 count);
|
||||
int port_rep_outl(u16 port, u32 base, int d_f, u32 count);
|
||||
|
||||
u8 x_inb(u16 port);
|
||||
u16 x_inw(u16 port);
|
||||
void x_outb(u16 port, u8 val);
|
||||
void x_outw(u16 port, u16 val);
|
||||
u32 x_inl(u16 port);
|
||||
void x_outl(u16 port, u32 val);
|
||||
|
||||
u8 Mem_rb(int addr);
|
||||
u16 Mem_rw(int addr);
|
||||
u32 Mem_rl(int addr);
|
||||
|
||||
void Mem_wb(int addr, u8 val);
|
||||
void Mem_ww(int addr, u16 val);
|
||||
void Mem_wl(int addr, u32 val);
|
||||
void getsecs(unsigned long *sec, unsigned long *usec);
|
||||
u8 bios_checksum(u8 * start, int size);
|
||||
|
||||
#endif
|
|
@ -1,313 +0,0 @@
|
|||
/* $XFree86: xc/programs/Xserver/hw/xfree86/int10/helper_mem.c,v 1.21 2001/05/22 16:24:37 tsi Exp $ */
|
||||
/*
|
||||
* XFree86 int10 module
|
||||
* execute BIOS int 10h calls in x86 real mode environment
|
||||
* Copyright 1999 Egbert Eich
|
||||
*/
|
||||
#include <stdio.h>
|
||||
|
||||
#define _INT10_PRIVATE
|
||||
|
||||
#define REG pInt
|
||||
#if 0
|
||||
typedef enum {
|
||||
OPT_NOINT10,
|
||||
OPT_INIT_PRIMARY,
|
||||
OPT_BIOS_LOCATION
|
||||
} INT10Opts;
|
||||
|
||||
static const OptionInfoRec INT10Options[] = {
|
||||
{OPT_NOINT10, "NoINT10", OPTV_BOOLEAN, {0}, FALSE},
|
||||
{OPT_INIT_PRIMARY, "InitPrimary", OPTV_BOOLEAN, {0}, FALSE},
|
||||
{OPT_BIOS_LOCATION, "BiosLocation", OPTV_STRING, {0}, FALSE},
|
||||
{-1, NULL, OPTV_NONE, {0}, FALSE},
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
void dprint(unsigned long start, unsigned long size)
|
||||
{
|
||||
int i, j;
|
||||
char *c = (char *) start;
|
||||
|
||||
for (j = 0; j < (size >> 4); j++) {
|
||||
char *d = c;
|
||||
printf("\n0x%lx: ", (unsigned long) c);
|
||||
for (i = 0; i < 16; i++)
|
||||
printf("%2.2x ", (unsigned char) (*(c++)));
|
||||
c = d;
|
||||
for (i = 0; i < 16; i++) {
|
||||
printf("%c", ((((unsigned char) (*c)) > 32) && (((unsigned char) (*c)) < 128)) ?
|
||||
(unsigned char) (*(c)) : '.');
|
||||
c++;
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
#endif /* DEBUG */
|
||||
|
||||
#if 0
|
||||
#ifndef _PC
|
||||
/*
|
||||
* here we are really paranoid about faking a "real"
|
||||
* BIOS. Most of this information was pulled from
|
||||
* dosemu.
|
||||
*/
|
||||
void setup_int_vect(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* let the int vects point to the SYS_BIOS seg */
|
||||
for (i = 0; i < 0x80; i++) {
|
||||
MEM_WW(i << 2, 0);
|
||||
MEM_WW((i << 2) + 2, SYS_BIOS >> 4);
|
||||
}
|
||||
|
||||
reset_int_vect(current);
|
||||
/* font tables default location (int 1F) */
|
||||
MEM_WW(0x1f << 2, 0xfa6e);
|
||||
|
||||
/* int 11 default location (Get Equipment Configuration) */
|
||||
MEM_WW(0x11 << 2, 0xf84d);
|
||||
/* int 12 default location (Get Conventional Memory Size) */
|
||||
MEM_WW(0x12 << 2, 0xf841);
|
||||
/* int 15 default location (I/O System Extensions) */
|
||||
MEM_WW(0x15 << 2, 0xf859);
|
||||
/* int 1A default location (RTC, PCI and others) */
|
||||
MEM_WW(0x1a << 2, 0xff6e);
|
||||
/* int 05 default location (Bound Exceeded) */
|
||||
MEM_WW(0x05 << 2, 0xff54);
|
||||
/* int 08 default location (Double Fault) */
|
||||
MEM_WW(0x08 << 2, 0xfea5);
|
||||
/* int 13 default location (Disk) */
|
||||
MEM_WW(0x13 << 2, 0xec59);
|
||||
/* int 0E default location (Page Fault) */
|
||||
MEM_WW(0x0e << 2, 0xef57);
|
||||
/* int 17 default location (Parallel Port) */
|
||||
MEM_WW(0x17 << 2, 0xefd2);
|
||||
/* fdd table default location (int 1e) */
|
||||
MEM_WW(0x1e << 2, 0xefc7);
|
||||
|
||||
/* Set Equipment flag to VGA */
|
||||
i = MEM_RB(0x0410) & 0xCF;
|
||||
MEM_WB(0x0410, i);
|
||||
/* XXX Perhaps setup more of the BDA here. See also int42(0x00). */
|
||||
}
|
||||
#endif
|
||||
|
||||
int setup_system_bios(void *base_addr)
|
||||
{
|
||||
char *base = (char *) base_addr;
|
||||
|
||||
/*
|
||||
* we trap the "industry standard entry points" to the BIOS
|
||||
* and all other locations by filling them with "hlt"
|
||||
* TODO: implement hlt-handler for these
|
||||
*/
|
||||
memset(base, 0xf4, 0x10000);
|
||||
|
||||
/* set bios date */
|
||||
strcpy(base + 0x0FFF5, "06/11/99");
|
||||
/* set up eisa ident string */
|
||||
strcpy(base + 0x0FFD9, "PCI_ISA");
|
||||
/* write system model id for IBM-AT */
|
||||
*((unsigned char *) (base + 0x0FFFE)) = 0xfc;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void reset_int_vect(void)
|
||||
{
|
||||
/*
|
||||
* This table is normally located at 0xF000:0xF0A4. However, int 0x42,
|
||||
* function 0 (Mode Set) expects it (or a copy) somewhere in the bottom
|
||||
* 64kB. Note that because this data doesn't survive POST, int 0x42 should
|
||||
* only be used during EGA/VGA BIOS initialisation.
|
||||
*/
|
||||
static const unsigned char VideoParms[] = {
|
||||
/* Timing for modes 0x00 & 0x01 */
|
||||
0x38, 0x28, 0x2d, 0x0a, 0x1f, 0x06, 0x19, 0x1c,
|
||||
0x02, 0x07, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
|
||||
/* Timing for modes 0x02 & 0x03 */
|
||||
0x71, 0x50, 0x5a, 0x0a, 0x1f, 0x06, 0x19, 0x1c,
|
||||
0x02, 0x07, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
|
||||
/* Timing for modes 0x04, 0x05 & 0x06 */
|
||||
0x38, 0x28, 0x2d, 0x0a, 0x7f, 0x06, 0x64, 0x70,
|
||||
0x02, 0x01, 0x06, 0x07, 0x00, 0x00, 0x00, 0x00,
|
||||
/* Timing for mode 0x07 */
|
||||
0x61, 0x50, 0x52, 0x0f, 0x19, 0x06, 0x19, 0x19,
|
||||
0x02, 0x0d, 0x0b, 0x0c, 0x00, 0x00, 0x00, 0x00,
|
||||
/* Display page lengths in little endian order */
|
||||
0x00, 0x08, /* Modes 0x00 and 0x01 */
|
||||
0x00, 0x10, /* Modes 0x02 and 0x03 */
|
||||
0x00, 0x40, /* Modes 0x04 and 0x05 */
|
||||
0x00, 0x40, /* Modes 0x06 and 0x07 */
|
||||
/* Number of columns for each mode */
|
||||
40, 40, 80, 80, 40, 40, 80, 80,
|
||||
/* CGA Mode register value for each mode */
|
||||
0x2c, 0x28, 0x2d, 0x29, 0x2a, 0x2e, 0x1e, 0x29,
|
||||
/* Padding */
|
||||
0x00, 0x00, 0x00, 0x00
|
||||
};
|
||||
int i;
|
||||
|
||||
for (i = 0; i < sizeof(VideoParms); i++)
|
||||
MEM_WB(i + (0x1000 - sizeof(VideoParms)), VideoParms[i]);
|
||||
MEM_WW(0x1d << 2, 0x1000 - sizeof(VideoParms));
|
||||
MEM_WW((0x1d << 2) + 2, 0);
|
||||
|
||||
printf("SETUP INT\n");
|
||||
MEM_WW(0x10 << 2, 0xf065);
|
||||
MEM_WW((0x10 << 2) + 2, SYS_BIOS >> 4);
|
||||
MEM_WW(0x42 << 2, 0xf065);
|
||||
MEM_WW((0x42 << 2) + 2, SYS_BIOS >> 4);
|
||||
MEM_WW(0x6D << 2, 0xf065);
|
||||
MEM_WW((0x6D << 2) + 2, SYS_BIOS >> 4);
|
||||
}
|
||||
|
||||
void set_return_trap(void)
|
||||
{
|
||||
/*
|
||||
* Here we set the exit condition: We return when we encounter
|
||||
* 'hlt' (=0xf4), which we locate at address 0x600 in x86 memory.
|
||||
*/
|
||||
MEM_WB(0x0600, 0xf4);
|
||||
|
||||
/*
|
||||
* Allocate a segment for the stack
|
||||
*/
|
||||
xf86Int10AllocPages(1, current->stackseg);
|
||||
}
|
||||
|
||||
void *xf86HandleInt10Options(ScrnInfoPtr pScrn, int entityIndex)
|
||||
{
|
||||
EntityInfoPtr pEnt = xf86GetEntityInfo(entityIndex);
|
||||
OptionInfoPtr options = NULL;
|
||||
|
||||
if (pEnt->device) {
|
||||
pointer configOptions = NULL;
|
||||
|
||||
/* Check if xf86CollectOptions() has already been called */
|
||||
if (((pEnt->index < 0) ||
|
||||
!xf86Screens[pEnt->index] ||
|
||||
!(configOptions = xf86Screens[pEnt->index]->options)) &&
|
||||
pEnt->device)
|
||||
configOptions = pEnt->device->options;
|
||||
|
||||
if (configOptions) {
|
||||
if (!(options = (OptionInfoPtr) xalloc(sizeof(INT10Options))))
|
||||
return NULL;
|
||||
|
||||
(void) memcpy(options, INT10Options, sizeof(INT10Options));
|
||||
xf86ProcessOptions(pScrn->scrnIndex, configOptions, options);
|
||||
}
|
||||
}
|
||||
xfree(pEnt);
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
Bool int10skip(void *options)
|
||||
{
|
||||
Bool noint10 = FALSE;
|
||||
|
||||
if (!options)
|
||||
return FALSE;
|
||||
|
||||
xf86GetOptValBool(options, OPT_NOINT10, &noint10);
|
||||
return noint10;
|
||||
}
|
||||
|
||||
Bool int10_check_bios(int scrnIndex, int codeSeg, unsigned char *vbiosMem)
|
||||
{
|
||||
int size;
|
||||
|
||||
if ((codeSeg & 0x1f) || /* Not 512-byte aligned otherwise */
|
||||
((codeSeg << 4) < V_BIOS) || ((codeSeg << 4) >= SYS_SIZE))
|
||||
return FALSE;
|
||||
|
||||
if (xf86IsPc98())
|
||||
return FALSE;
|
||||
|
||||
if ((*vbiosMem != 0x55) || (*(vbiosMem + 1) != 0xAA) || !*(vbiosMem + 2))
|
||||
return FALSE;
|
||||
|
||||
size = *(vbiosMem + 2) * 512;
|
||||
|
||||
if ((size + (codeSeg << 4)) > SYS_SIZE)
|
||||
return FALSE;
|
||||
|
||||
if (bios_checksum(vbiosMem, size))
|
||||
xf86DrvMsg(scrnIndex, X_WARNING, "Bad V_BIOS checksum\n");
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Bool initPrimary(void *options)
|
||||
{
|
||||
Bool initPrimary = FALSE;
|
||||
|
||||
if (!options)
|
||||
return FALSE;
|
||||
|
||||
xf86GetOptValBool(options, OPT_INIT_PRIMARY, &initPrimary);
|
||||
return initPrimary;
|
||||
}
|
||||
|
||||
void xf86int10ParseBiosLocation(void *options, xf86int10BiosLocationPtr bios)
|
||||
{
|
||||
char *s;
|
||||
char *p;
|
||||
char *str = NULL;
|
||||
|
||||
if (options)
|
||||
str = xf86GetOptValString(options, OPT_BIOS_LOCATION);
|
||||
|
||||
bios->bus = BUS_NONE;
|
||||
if (!str)
|
||||
return;
|
||||
|
||||
s = xstrdup(str);
|
||||
p = strtok(s, ":");
|
||||
if (xf86NameCmp(p, "pci"))
|
||||
bios->bus = BUS_PCI;
|
||||
else if (xf86NameCmp(p, "primary"))
|
||||
bios->bus = BUS_ISA;
|
||||
|
||||
xfree(s);
|
||||
|
||||
if (bios->bus == BUS_NONE)
|
||||
return;
|
||||
|
||||
s = xstrdup(str);
|
||||
p = strchr(s, ':');
|
||||
|
||||
switch (bios->bus) {
|
||||
case BUS_ISA:
|
||||
if (p)
|
||||
bios->location.legacy = atoi(++p);
|
||||
else
|
||||
bios->location.legacy = 0;
|
||||
break;
|
||||
case BUS_PCI:
|
||||
if (p) {
|
||||
bios->location.pci.bus = atoi(++p);
|
||||
if ((p = strchr(p, ':'))) {
|
||||
bios->location.pci.dev = atoi(++p);
|
||||
if ((p = strchr(p, ':'))) {
|
||||
bios->location.pci.func = atoi(++p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* fall through */
|
||||
bios->bus = BUS_NONE;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
xfree(s);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -0,0 +1,24 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2016 Google Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _BYTEORDER_H
|
||||
#define _BYTEORDER_H
|
||||
|
||||
#define __LITTLE_ENDIAN 1234
|
||||
|
||||
#define cpu_to_le16(x) ((uint16_t)(x))
|
||||
#define cpu_to_le32(x) ((uint32_t)(x))
|
||||
|
||||
#endif /* _BYTEORDER_H */
|
|
@ -1,4 +0,0 @@
|
|||
#ifndef _ASM_IO_H
|
||||
#define _ASM_IO_H
|
||||
#include <sys/io.h>
|
||||
#endif
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2016 Google Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#define CONFIG_PCI_OPTION_ROM_RUN_YABEL 1
|
||||
#define CONFIG_YABEL_PCI_ACCESS_OTHER_DEVICES 0
|
||||
#define CONFIG_YABEL_DIRECTHW 1
|
||||
|
||||
#define CONFIG_X86EMU_DEBUG 1
|
||||
#define CONFIG_X86EMU_DEBUG_TIMINGS 0
|
||||
#define CONFIG_X86EMU_DEBUG_JMP 0
|
||||
#define CONFIG_X86EMU_DEBUG_TRACE 0
|
||||
#define CONFIG_X86EMU_DEBUG_PNP 0
|
||||
#define CONFIG_X86EMU_DEBUG_DISK 0
|
||||
#define CONFIG_X86EMU_DEBUG_PMM 0
|
||||
#define CONFIG_X86EMU_DEBUG_VBE 0
|
||||
#define CONFIG_X86EMU_DEBUG_INT10 0
|
||||
#define CONFIG_X86EMU_DEBUG_INTERRUPTS 0
|
||||
#define CONFIG_X86EMU_DEBUG_CHECK_VMEM_ACCESS 0
|
||||
#define CONFIG_X86EMU_DEBUG_MEM 0
|
||||
#define CONFIG_X86EMU_DEBUG_IO 0
|
||||
|
||||
#define CONFIG_ARCH_X86 1
|
||||
#define CONFIG_ARCH_ARM 0
|
|
@ -1,6 +1,21 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2016 Google Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _CONSOLE_CONSOLE_H
|
||||
#define _CONSOLE_CONSOLE_H
|
||||
#define CONFIG_X86EMU_DEBUG 1
|
||||
|
||||
int printk(int msg_level, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2016 Google Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _STDTYPES_H
|
||||
#define _STDTYPES_H
|
||||
|
||||
|
|
|
@ -0,0 +1,57 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef _SWAB_H
|
||||
#define _SWAB_H
|
||||
|
||||
/*
|
||||
* linux/byteorder/swab.h
|
||||
* Byte-swapping, independently from CPU endianness
|
||||
* swabXX[ps]?(foo)
|
||||
*
|
||||
* Francois-Rene Rideau <fare@tunes.org> 19971205
|
||||
* separated swab functions from cpu_to_XX,
|
||||
* to clean up support for bizarre-endian architectures.
|
||||
*
|
||||
* See asm-i386/byteorder.h and such for examples of how to provide
|
||||
* architecture-dependent optimized versions
|
||||
*
|
||||
*/
|
||||
|
||||
/* casts are necessary for constants, because we never know how for sure
|
||||
* how U/UL/ULL map to __u16, __u32, __u64. At least not in a portable way.
|
||||
*/
|
||||
#define swab16(x) \
|
||||
((unsigned short)( \
|
||||
(((unsigned short)(x) & (unsigned short)0x00ffU) << 8) | \
|
||||
(((unsigned short)(x) & (unsigned short)0xff00U) >> 8) ))
|
||||
|
||||
#define swab32(x) \
|
||||
((unsigned int)( \
|
||||
(((unsigned int)(x) & (unsigned int)0x000000ffUL) << 24) | \
|
||||
(((unsigned int)(x) & (unsigned int)0x0000ff00UL) << 8) | \
|
||||
(((unsigned int)(x) & (unsigned int)0x00ff0000UL) >> 8) | \
|
||||
(((unsigned int)(x) & (unsigned int)0xff000000UL) >> 24) ))
|
||||
|
||||
#define swab64(x) \
|
||||
((uint64_t)( \
|
||||
(((uint64_t)(x) & (uint64_t)0x00000000000000ffULL) << 56) | \
|
||||
(((uint64_t)(x) & (uint64_t)0x000000000000ff00ULL) << 40) | \
|
||||
(((uint64_t)(x) & (uint64_t)0x0000000000ff0000ULL) << 24) | \
|
||||
(((uint64_t)(x) & (uint64_t)0x00000000ff000000ULL) << 8) | \
|
||||
(((uint64_t)(x) & (uint64_t)0x000000ff00000000ULL) >> 8) | \
|
||||
(((uint64_t)(x) & (uint64_t)0x0000ff0000000000ULL) >> 24) | \
|
||||
(((uint64_t)(x) & (uint64_t)0x00ff000000000000ULL) >> 40) | \
|
||||
(((uint64_t)(x) & (uint64_t)0xff00000000000000ULL) >> 56) ))
|
||||
|
||||
#endif /* _SWAB_H */
|
|
@ -1,476 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdtypes.h>
|
||||
#include "testbios.h"
|
||||
|
||||
extern int verbose;
|
||||
|
||||
|
||||
#ifndef _PC
|
||||
/*
|
||||
* This is derived from a number of PC system BIOS'es. The intent here is to
|
||||
* provide very primitive video support, before an EGA/VGA BIOS installs its
|
||||
* own interrupt vector. Here, "Ignored" calls should remain so. "Not
|
||||
* Implemented" denotes functionality that can be implemented should the need
|
||||
* arise. What are "Not Implemented" throughout are video memory accesses.
|
||||
* Also, very little input validity checking is done here.
|
||||
*/
|
||||
int int42_handler(void)
|
||||
{
|
||||
#if 0
|
||||
if (verbose && X86_AH != 0x0e) {
|
||||
printf("int%x\n", current->num);
|
||||
x86emu_dump_xregs();
|
||||
}
|
||||
|
||||
switch (X86_AH) {
|
||||
case 0x00:
|
||||
/* Set Video Mode */
|
||||
/* Enter: AL = video mode number */
|
||||
/* Leave: Nothing */
|
||||
/* Implemented (except for clearing the screen) */
|
||||
{ /* Localise */
|
||||
int i;
|
||||
u16 ioport, int1d, regvals, tmp;
|
||||
u8 mode, cgamode, cgacolour;
|
||||
|
||||
/*
|
||||
* Ignore all mode numbers but 0x00-0x13. Some systems also ignore
|
||||
* 0x0B and 0x0C, but don't do that here.
|
||||
*/
|
||||
if (X86_AL > 0x13)
|
||||
break;
|
||||
|
||||
/*
|
||||
* You didn't think that was really the mode set, did you? There
|
||||
* are only so many slots in the video parameter table...
|
||||
*/
|
||||
mode = X86_AL;
|
||||
ioport = 0x03D4;
|
||||
switch (MEM_RB(0x0410) & 0x30) {
|
||||
case 0x30: /* MDA */
|
||||
mode = 0x07; /* Force mode to 0x07 */
|
||||
ioport = 0x03B4;
|
||||
break;
|
||||
case 0x10: /* CGA 40x25 */
|
||||
if (mode >= 0x07)
|
||||
mode = 0x01;
|
||||
break;
|
||||
case 0x20: /* CGA 80x25 (MCGA?) */
|
||||
if (mode >= 0x07)
|
||||
mode = 0x03;
|
||||
break;
|
||||
case 0x00: /* EGA/VGA */
|
||||
if (mode >= 0x07) /* Don't try MDA timings */
|
||||
mode = 0x01; /* !?!?! */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Locate data in video parameter table */
|
||||
int1d = MEM_RW(0x1d << 2);
|
||||
regvals = ((mode >> 1) << 4) + int1d;
|
||||
cgacolour = 0x30;
|
||||
if (mode == 0x06) {
|
||||
regvals -= 0x10;
|
||||
cgacolour = 0x3F;
|
||||
}
|
||||
|
||||
/** Update BIOS Data Area **/
|
||||
|
||||
/* Video mode */
|
||||
MEM_WB(0x0449, mode);
|
||||
|
||||
/* Columns */
|
||||
tmp = MEM_RB(mode + int1d + 0x48);
|
||||
MEM_WW(0x044A, tmp);
|
||||
|
||||
/* Page length */
|
||||
tmp = MEM_RW((mode & 0x06) + int1d + 0x40);
|
||||
MEM_WW(0x044C, tmp);
|
||||
|
||||
/* Start Address */
|
||||
MEM_WW(0x044E, 0);
|
||||
|
||||
/* Cursor positions, one for each display page */
|
||||
for (i = 0x0450; i < 0x0460; i += 2)
|
||||
MEM_WW(i, 0);
|
||||
|
||||
/* Cursor start & end scanlines */
|
||||
tmp = MEM_RB(regvals + 0x0B);
|
||||
MEM_WB(0x0460, tmp);
|
||||
tmp = MEM_RB(regvals + 0x0A);
|
||||
MEM_WB(0x0461, tmp);
|
||||
|
||||
/* Current display page number */
|
||||
MEM_WB(0x0462, 0);
|
||||
|
||||
/* CRTC I/O address */
|
||||
MEM_WW(0x0463, ioport);
|
||||
|
||||
/* CGA Mode register value */
|
||||
cgamode = MEM_RB(mode + int1d + 0x50);
|
||||
MEM_WB(0x0465, cgamode);
|
||||
|
||||
/* CGA Colour register value */
|
||||
MEM_WB(0x0466, cgacolour);
|
||||
|
||||
/* Rows */
|
||||
MEM_WB(0x0484, (25 - 1));
|
||||
|
||||
/* Programme the mode */
|
||||
outb(ioport + 4, cgamode & 0x37); /* Turn off screen */
|
||||
for (i = 0; i < 0x10; i++) {
|
||||
tmp = MEM_RB(regvals + i);
|
||||
outb(ioport, i);
|
||||
outb(ioport + 1, tmp);
|
||||
}
|
||||
outb(ioport + 5, cgacolour); /* Select colour mode */
|
||||
outb(ioport + 4, cgamode); /* Turn on screen */
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x01:
|
||||
/* Set Cursor Type */
|
||||
/* Enter: CH = starting line for cursor */
|
||||
/* CL = ending line for cursor */
|
||||
/* Leave: Nothing */
|
||||
/* Implemented */
|
||||
{ /* Localise */
|
||||
u16 ioport = MEM_RW(0x0463);
|
||||
|
||||
MEM_WB(0x0460, X86_CL);
|
||||
MEM_WB(0x0461, X86_CH);
|
||||
|
||||
outb(ioport, 0x0A);
|
||||
outb(ioport + 1, X86_CH);
|
||||
outb(ioport, 0x0B);
|
||||
outb(ioport + 1, X86_CL);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x02:
|
||||
/* Set Cursor Position */
|
||||
/* Enter: BH = display page number */
|
||||
/* DH = row */
|
||||
/* DL = column */
|
||||
/* Leave: Nothing */
|
||||
/* Implemented */
|
||||
{ /* Localise */
|
||||
u16 offset, ioport;
|
||||
|
||||
MEM_WB((X86_BH << 1) + 0x0450, X86_DL);
|
||||
MEM_WB((X86_BH << 1) + 0x0451, X86_DH);
|
||||
|
||||
if (X86_BH != MEM_RB(0x0462))
|
||||
break;
|
||||
|
||||
offset = (X86_DH * MEM_RW(0x044A)) + X86_DL;
|
||||
offset += MEM_RW(0x044E) << 1;
|
||||
|
||||
ioport = MEM_RW(0x0463);
|
||||
outb(ioport, 0x0E);
|
||||
outb(ioport + 1, offset >> 8);
|
||||
outb(ioport, 0x0F);
|
||||
outb(ioport + 1, offset & 0xFF);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
/* Get Cursor Position */
|
||||
/* Enter: BH = display page number */
|
||||
/* Leave: CH = starting line for cursor */
|
||||
/* CL = ending line for cursor */
|
||||
/* DH = row */
|
||||
/* DL = column */
|
||||
/* Implemented */
|
||||
{ /* Localise */
|
||||
X86_CL = MEM_RB(0x0460);
|
||||
X86_CH = MEM_RB(0x0461);
|
||||
X86_DL = MEM_RB((X86_BH << 1) + 0x0450);
|
||||
X86_DH = MEM_RB((X86_BH << 1) + 0x0451);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x04:
|
||||
/* Get Light Pen Position */
|
||||
/* Enter: Nothing */
|
||||
/* Leave: AH = 0x01 (down/triggered) or 0x00 (not) */
|
||||
/* BX = pixel column */
|
||||
/* CX = pixel row */
|
||||
/* DH = character row */
|
||||
/* DL = character column */
|
||||
/* Not Implemented */
|
||||
{ /* Localise */
|
||||
printf("int%x - Get Light Pen Position. "
|
||||
"Function not implemented.\n", current->num);
|
||||
x86emu_dump_xregs();
|
||||
X86_AH = X86_BX = X86_CX = X86_DX = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x05:
|
||||
/* Set Display Page */
|
||||
/* Enter: AL = display page number */
|
||||
/* Leave: Nothing */
|
||||
/* Implemented */
|
||||
{ /* Localise */
|
||||
u16 start, ioport = MEM_RW(0x0463);
|
||||
u8 x, y;
|
||||
|
||||
/* Calculate new start address */
|
||||
MEM_WB(0x0462, X86_AL);
|
||||
start = X86_AL * MEM_RW(0x044C);
|
||||
MEM_WW(0x044E, start);
|
||||
start <<= 1;
|
||||
|
||||
/* Update start address */
|
||||
outb(ioport, 0x0C);
|
||||
outb(ioport + 1, start >> 8);
|
||||
outb(ioport, 0x0D);
|
||||
outb(ioport + 1, start & 0xFF);
|
||||
|
||||
/* Switch cursor position */
|
||||
y = MEM_RB((X86_AL << 1) + 0x0450);
|
||||
x = MEM_RB((X86_AL << 1) + 0x0451);
|
||||
start += (y * MEM_RW(0x044A)) + x;
|
||||
|
||||
/* Update cursor position */
|
||||
outb(ioport, 0x0E);
|
||||
outb(ioport + 1, start >> 8);
|
||||
outb(ioport, 0x0F);
|
||||
outb(ioport + 1, start & 0xFF);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x06:
|
||||
/* Initialise or Scroll Window Up */
|
||||
/* Enter: AL = lines to scroll up */
|
||||
/* BH = attribute for blank */
|
||||
/* CH = upper y of window */
|
||||
/* CL = left x of window */
|
||||
/* DH = lower y of window */
|
||||
/* DL = right x of window */
|
||||
/* Leave: Nothing */
|
||||
/* Not Implemented */
|
||||
{ /* Localise */
|
||||
printf("int%x: Initialise or Scroll Window Up - "
|
||||
"Function not implemented.\n", current->num);
|
||||
x86emu_dump_xregs();
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x07:
|
||||
/* Initialise or Scroll Window Down */
|
||||
/* Enter: AL = lines to scroll down */
|
||||
/* BH = attribute for blank */
|
||||
/* CH = upper y of window */
|
||||
/* CL = left x of window */
|
||||
/* DH = lower y of window */
|
||||
/* DL = right x of window */
|
||||
/* Leave: Nothing */
|
||||
/* Not Implemented */
|
||||
{ /* Localise */
|
||||
printf("int%x: Initialise or Scroll Window Down - "
|
||||
"Function not implemented.\n", current->num);
|
||||
x86emu_dump_xregs();
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x08:
|
||||
/* Read Character and Attribute at Cursor */
|
||||
/* Enter: BH = display page number */
|
||||
/* Leave: AH = attribute */
|
||||
/* AL = character */
|
||||
/* Not Implemented */
|
||||
{ /* Localise */
|
||||
printf
|
||||
("int%x: Read Character and Attribute at Cursor - "
|
||||
"Function not implemented.\n", current->num);
|
||||
x86emu_dump_xregs();
|
||||
|
||||
X86_AX = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x09:
|
||||
/* Write Character and Attribute at Cursor */
|
||||
/* Enter: AL = character */
|
||||
/* BH = display page number */
|
||||
/* BL = attribute (text) or colour (graphics) */
|
||||
/* CX = replication count */
|
||||
/* Leave: Nothing */
|
||||
/* Not Implemented */
|
||||
{ /* Localise */
|
||||
printf
|
||||
("int%x: Write Character and Attribute at Cursor - "
|
||||
"Function not implemented.\n", current->num);
|
||||
x86emu_dump_xregs();
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0a:
|
||||
/* Write Character at Cursor */
|
||||
/* Enter: AL = character */
|
||||
/* BH = display page number */
|
||||
/* BL = colour */
|
||||
/* CX = replication count */
|
||||
/* Leave: Nothing */
|
||||
/* Not Implemented */
|
||||
{ /* Localise */
|
||||
printf("int%x: Write Character at Cursor - "
|
||||
"Function not implemented.\n", current->num);
|
||||
x86emu_dump_xregs();
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0b:
|
||||
/* Set Palette, Background or Border */
|
||||
/* Enter: BH = 0x00 or 0x01 */
|
||||
/* BL = colour or palette (respectively) */
|
||||
/* Leave: Nothing */
|
||||
/* Implemented */
|
||||
{ /* Localise */
|
||||
u16 ioport = MEM_RW(0x0463) + 5;
|
||||
u8 cgacolour = MEM_RB(0x0466);
|
||||
|
||||
if (X86_BH) {
|
||||
cgacolour &= 0xDF;
|
||||
cgacolour |= (X86_BL & 0x01) << 5;
|
||||
} else {
|
||||
cgacolour &= 0xE0;
|
||||
cgacolour |= X86_BL & 0x1F;
|
||||
}
|
||||
|
||||
MEM_WB(0x0466, cgacolour);
|
||||
outb(ioport, cgacolour);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0c:
|
||||
/* Write Graphics Pixel */
|
||||
/* Enter: AL = pixel value */
|
||||
/* BH = display page number */
|
||||
/* CX = column */
|
||||
/* DX = row */
|
||||
/* Leave: Nothing */
|
||||
/* Not Implemented */
|
||||
{ /* Localise */
|
||||
printf("int%x: Write Graphics Pixel - "
|
||||
"Function not implemented.\n", current->num);
|
||||
x86emu_dump_xregs();
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0d:
|
||||
/* Read Graphics Pixel */
|
||||
/* Enter: BH = display page number */
|
||||
/* CX = column */
|
||||
/* DX = row */
|
||||
/* Leave: AL = pixel value */
|
||||
/* Not Implemented */
|
||||
{ /* Localise */
|
||||
printf("int%x: Write Graphics Pixel - "
|
||||
"Function not implemented.\n", current->num);
|
||||
x86emu_dump_xregs();
|
||||
|
||||
X86_AL = 0;
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0e:
|
||||
/* Write Character in Teletype Mode */
|
||||
/* Enter: AL = character */
|
||||
/* BH = display page number */
|
||||
/* BL = foreground colour */
|
||||
/* Leave: Nothing */
|
||||
/* Not Implemented */
|
||||
/* WARNING: Emulation of BEL characters will require */
|
||||
/* emulation of RTC and PC speaker I/O. */
|
||||
/* Also, this recurses through int 0x10 */
|
||||
/* which might or might not have been */
|
||||
/* installed yet. */
|
||||
{ /* Localise */
|
||||
#ifdef PARANOID
|
||||
printf("int%x: Write Character in Teletype Mode - "
|
||||
"Function not implemented.\n", current->num);
|
||||
x86emu_dump_xregs();
|
||||
#endif
|
||||
printf("%c", X86_AL);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x0f:
|
||||
/* Get Video Mode */
|
||||
/* Enter: Nothing */
|
||||
/* Leave: AH = number of columns */
|
||||
/* AL = video mode number */
|
||||
/* BH = display page number */
|
||||
/* Implemented */
|
||||
{ /* Localise */
|
||||
X86_AH = MEM_RW(0x044A);
|
||||
X86_AL = MEM_RB(0x0449);
|
||||
X86_BH = MEM_RB(0x0462);
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x10:
|
||||
/* Colour Control (subfunction in AL) */
|
||||
/* Enter: Various */
|
||||
/* Leave: Various */
|
||||
/* Ignored */
|
||||
break;
|
||||
|
||||
case 0x11:
|
||||
/* Font Control (subfunction in AL) */
|
||||
/* Enter: Various */
|
||||
/* Leave: Various */
|
||||
/* Ignored */
|
||||
break;
|
||||
|
||||
case 0x12:
|
||||
/* Miscellaneous (subfunction in BL) */
|
||||
/* Enter: Various */
|
||||
/* Leave: Various */
|
||||
/* Ignored. Previous code here optionally allowed */
|
||||
/* the enabling and disabling of VGA, but no system */
|
||||
/* BIOS I've come across actually implements it. */
|
||||
break;
|
||||
|
||||
case 0x13:
|
||||
/* Write String in Teletype Mode */
|
||||
/* Enter: AL = write mode */
|
||||
/* BL = attribute (if (AL & 0x02) == 0) */
|
||||
/* CX = string length */
|
||||
/* DH = row */
|
||||
/* DL = column */
|
||||
/* ES:BP = string segment:offset */
|
||||
/* Leave: Nothing */
|
||||
/* Not Implemented */
|
||||
/* WARNING: Emulation of BEL characters will require */
|
||||
/* emulation of RTC and PC speaker I/O. */
|
||||
/* Also, this recurses through int 0x10 */
|
||||
/* which might or might not have been */
|
||||
/* installed yet. */
|
||||
{ /* Localise */
|
||||
printf("int%x: Write String in Teletype Mode - "
|
||||
"Function not implemented.\n", current->num);
|
||||
x86emu_dump_xregs();
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
/* Various extensions */
|
||||
/* Enter: Various */
|
||||
/* Leave: Various */
|
||||
/* Ignored */
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
#endif
|
|
@ -1,11 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdtypes.h>
|
||||
#include "testbios.h"
|
||||
|
||||
int int15_handler(void)
|
||||
{
|
||||
printf("\nint15 encountered.\n");
|
||||
x86emu_dump_xregs();
|
||||
X86_EAX = 0;
|
||||
return 1;
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include "testbios.h"
|
||||
|
||||
int int16_handler(void)
|
||||
{
|
||||
printf("\nint16: keyboard not supported right now.\n");
|
||||
x86emu_dump_xregs();
|
||||
return 1;
|
||||
}
|
|
@ -1,171 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include <stdtypes.h>
|
||||
#include "testbios.h"
|
||||
#include "pci-userspace.h"
|
||||
|
||||
#define DEBUG_INT1A
|
||||
|
||||
#define SUCCESSFUL 0x00
|
||||
#define DEVICE_NOT_FOUND 0x86
|
||||
#define BAD_REGISTER_NUMBER 0x87
|
||||
|
||||
extern int verbose;
|
||||
|
||||
int int1A_handler(void)
|
||||
{
|
||||
PCITAG tag = NULL;
|
||||
pciVideoPtr pvp = NULL;
|
||||
|
||||
if (verbose) {
|
||||
printf("\nint1a encountered.\n");
|
||||
//x86emu_dump_xregs();
|
||||
}
|
||||
|
||||
switch (X86_AX) {
|
||||
case 0xb101:
|
||||
X86_EAX = 0x00; /* no config space/special cycle support */
|
||||
X86_AL = 0x01; /* config mechanism 1 */
|
||||
X86_EDX = 0x20494350; /* " ICP" */
|
||||
X86_EBX = 0x0210; /* Version 2.10 */
|
||||
X86_ECX &= 0xFF00;
|
||||
X86_ECX |= (pciNumBuses & 0xFF); /* Max bus number in system */
|
||||
X86_EFLAGS &= ~((unsigned long) 0x01); /* clear carry flag */
|
||||
#ifdef DEBUG_INT1A
|
||||
if (verbose)
|
||||
printf("PCI bios present.\n");
|
||||
#endif
|
||||
return 1;
|
||||
case 0xb102:
|
||||
if (X86_DX == pvp->vendor_id && X86_CX == pvp->device_id && X86_ESI == 0) {
|
||||
X86_EAX = X86_AL | (SUCCESSFUL << 8);
|
||||
X86_EFLAGS &= ~((unsigned long) 0x01); /* clear carry flag */
|
||||
X86_EBX = pciSlotBX(tag); // XXX used to be pvp, but both are NULL
|
||||
}
|
||||
#ifdef SHOW_ALL_DEVICES
|
||||
else if ((pvp = xf86FindPciDeviceVendor(X86_EDX, X86_ECX, X86_ESI, pvp))) {
|
||||
X86_EAX = X86_AL | (SUCCESSFUL << 8);
|
||||
X86_EFLAGS &= ~((unsigned long) 0x01); /* clear carry flag */
|
||||
X86_EBX = pciSlotBX(pvp);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
X86_EAX = X86_AL | (DEVICE_NOT_FOUND << 8);
|
||||
X86_EFLAGS |= ((unsigned long) 0x01); /* set carry flag */
|
||||
}
|
||||
#ifdef DEBUG_INT1A
|
||||
printf("eax=0x%x ebx=0x%x eflags=0x%x\n", X86_EAX, X86_EBX, X86_EFLAGS);
|
||||
#endif
|
||||
return 1;
|
||||
case 0xb103:
|
||||
#if 0
|
||||
if (X86_CL == pvp->interface &&
|
||||
X86_CH == pvp->subclass &&
|
||||
((X86_ECX & 0xFFFF0000) >> 16) == pvp->class) {
|
||||
X86_EAX = X86_AL | (SUCCESSFUL << 8);
|
||||
X86_EBX = pciSlotBX(pvp);
|
||||
X86_EFLAGS &= ~((unsigned long) 0x01); /* clear carry flag */
|
||||
}
|
||||
#else
|
||||
/* FIXME: dirty hack */
|
||||
if (0);
|
||||
#endif
|
||||
#ifdef SHOW_ALL_DEVICES
|
||||
else if ((pvp = FindPciClass(X86_CL, X86_CH,
|
||||
(X86_ECX & 0xffff0000) >> 16,
|
||||
X86_ESI, pvp))) {
|
||||
X86_EAX = X86_AL | (SUCCESSFUL << 8);
|
||||
X86_EFLAGS &= ~((unsigned long) 0x01); /* clear carry flag */
|
||||
X86_EBX = pciSlotBX(pvp);
|
||||
}
|
||||
#endif
|
||||
else {
|
||||
X86_EAX = X86_AL | (DEVICE_NOT_FOUND << 8);
|
||||
X86_EFLAGS |= ((unsigned long) 0x01); /* set carry flag */
|
||||
}
|
||||
#ifdef DEBUG_INT1A
|
||||
printf("eax=0x%x eflags=0x%x\n", X86_EAX, X86_EFLAGS);
|
||||
#endif
|
||||
return 1;
|
||||
case 0xb108:
|
||||
if ((tag = findPci(X86_EBX))) {
|
||||
X86_CL = pciReadByte(tag, X86_EDI);
|
||||
X86_EAX = X86_AL | (SUCCESSFUL << 8);
|
||||
X86_EFLAGS &= ~((unsigned long) 0x01); /* clear carry flag */
|
||||
} else {
|
||||
X86_EAX = X86_AL | (BAD_REGISTER_NUMBER << 8);
|
||||
X86_EFLAGS |= ((unsigned long) 0x01); /* set carry flag */
|
||||
}
|
||||
#ifdef DEBUG_INT1A
|
||||
printf("eax=0x%x ecx=0x%x eflags=0x%x\n", X86_EAX, X86_ECX, X86_EFLAGS);
|
||||
#endif
|
||||
return 1;
|
||||
case 0xb109:
|
||||
if ((tag = findPci(X86_EBX))) {
|
||||
X86_CX = pciReadWord(tag, X86_EDI);
|
||||
X86_EAX = X86_AL | (SUCCESSFUL << 8);
|
||||
X86_EFLAGS &= ~((unsigned long) 0x01); /* clear carry flag */
|
||||
} else {
|
||||
X86_EAX = X86_AL | (BAD_REGISTER_NUMBER << 8);
|
||||
X86_EFLAGS |= ((unsigned long) 0x01); /* set carry flag */
|
||||
}
|
||||
#ifdef DEBUG_INT1A
|
||||
printf("eax=0x%x ecx=0x%x eflags=0x%x\n", X86_EAX, X86_ECX, X86_EFLAGS);
|
||||
#endif
|
||||
return 1;
|
||||
case 0xb10a:
|
||||
if ((tag = findPci(X86_EBX))) {
|
||||
X86_ECX = pciReadLong(tag, X86_EDI);
|
||||
X86_EAX = X86_AL | (SUCCESSFUL << 8);
|
||||
X86_EFLAGS &= ~((unsigned long) 0x01); /* clear carry flag */
|
||||
} else {
|
||||
X86_EAX = X86_AL | (BAD_REGISTER_NUMBER << 8);
|
||||
X86_EFLAGS |= ((unsigned long) 0x01); /* set carry flag */
|
||||
}
|
||||
#ifdef DEBUG_INT1A
|
||||
printf("eax=0x%x ecx=0x%x eflags=0x%x\n", X86_EAX, X86_ECX, X86_EFLAGS);
|
||||
#endif
|
||||
return 1;
|
||||
case 0xb10b:
|
||||
if ((tag = findPci(X86_EBX))) {
|
||||
pciWriteByte(tag, X86_EDI, X86_CL);
|
||||
X86_EAX = X86_AL | (SUCCESSFUL << 8);
|
||||
X86_EFLAGS &= ~((unsigned long) 0x01); /* clear carry flag */
|
||||
} else {
|
||||
X86_EAX = X86_AL | (BAD_REGISTER_NUMBER << 8);
|
||||
X86_EFLAGS |= ((unsigned long) 0x01); /* set carry flag */
|
||||
}
|
||||
#ifdef DEBUG_INT1A
|
||||
printf("eax=0x%x eflags=0x%x\n", X86_EAX, X86_EFLAGS);
|
||||
#endif
|
||||
return 1;
|
||||
case 0xb10c:
|
||||
if ((tag = findPci(X86_EBX))) {
|
||||
pciWriteWord(tag, X86_EDI, X86_CX);
|
||||
X86_EAX = X86_AL | (SUCCESSFUL << 8);
|
||||
X86_EFLAGS &= ~((unsigned long) 0x01); /* clear carry flag */
|
||||
} else {
|
||||
X86_EAX = X86_AL | (BAD_REGISTER_NUMBER << 8);
|
||||
X86_EFLAGS |= ((unsigned long) 0x01); /* set carry flag */
|
||||
}
|
||||
#ifdef DEBUG_INT1A
|
||||
printf("eax=0x%x eflags=0x%x\n", X86_EAX, X86_EFLAGS);
|
||||
#endif
|
||||
return 1;
|
||||
case 0xb10d:
|
||||
if ((tag = findPci(X86_EBX))) {
|
||||
pciWriteLong(tag, X86_EDI, X86_ECX);
|
||||
X86_EAX = X86_AL | (SUCCESSFUL << 8);
|
||||
X86_EFLAGS &= ~((unsigned long) 0x01); /* clear carry flag */
|
||||
} else {
|
||||
X86_EAX = X86_AL | (BAD_REGISTER_NUMBER << 8);
|
||||
X86_EFLAGS |= ((unsigned long) 0x01); /* set carry flag */
|
||||
}
|
||||
#ifdef DEBUG_INT1A
|
||||
printf("eax=0x%x eflags=0x%x\n", X86_EAX, X86_EFLAGS);
|
||||
#endif
|
||||
return 1;
|
||||
default:
|
||||
printf("int1a: subfunction not implemented.\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
#include <stdio.h>
|
||||
#include "testbios.h"
|
||||
|
||||
int intE6_handler(void)
|
||||
{
|
||||
#if 0
|
||||
pciVideoPtr pvp;
|
||||
|
||||
if ((pvp = xf86GetPciInfoForEntity(pInt->entityIndex)))
|
||||
X86_AX = (pvp->bus << 8) | (pvp->device << 3) | (pvp->func & 0x7);
|
||||
pushw(X86_CS);
|
||||
pushw(X86_IP);
|
||||
X86_CS = pInt->BIOSseg;
|
||||
X86_EIP = 0x0003;
|
||||
X86_ES = 0; /* standard pc es */
|
||||
#endif
|
||||
printf("intE6 not supported right now.\n");
|
||||
x86emu_dump_xregs();
|
||||
return 1;
|
||||
}
|
|
@ -1,31 +1,30 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2016 Google Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <pci/pci.h>
|
||||
#include "pci-userspace.h"
|
||||
|
||||
#ifdef PCI_LIB_VERSION
|
||||
#define LIBPCI_CHECK_VERSION(major,minor,micro) \
|
||||
((((major) << 16) | ((minor) << 8) | (micro)) <= PCI_LIB_VERSION)
|
||||
#else
|
||||
#define LIBPCI_CHECK_VERSION(major,minor,micro) \
|
||||
( (LIBPCI_MAJOR_VERSION > (major)) || \
|
||||
(LIBPCI_MAJOR_VERSION == (major) && LIBPCI_MINOR_VERSION > (minor)) || \
|
||||
(LIBPCI_MAJOR_VERSION == (major) && LIBPCI_MINOR_VERSION == (minor)) && \
|
||||
LIBPCI_MICRO_VERSION >= (micro) )
|
||||
#endif
|
||||
|
||||
#define PCITAG struct pci_filter *
|
||||
|
||||
#define DEBUG_PCI 1
|
||||
|
||||
struct pci_access *pacc;
|
||||
static struct pci_access *pacc;
|
||||
|
||||
int pci_initialize(void)
|
||||
{
|
||||
struct pci_dev *dev;
|
||||
|
||||
struct pci_filter ltag;
|
||||
|
||||
|
||||
int pciNumBuses = 0;
|
||||
|
||||
int pciInit(void)
|
||||
{
|
||||
pacc = pci_alloc();
|
||||
|
||||
pci_init(pacc);
|
||||
|
@ -36,133 +35,80 @@ int pciInit(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int pciExit(void)
|
||||
int pci_exit(void)
|
||||
{
|
||||
pci_cleanup(pacc);
|
||||
return 0;
|
||||
}
|
||||
|
||||
PCITAG findPci(unsigned short bx)
|
||||
{
|
||||
PCITAG tag = <ag;
|
||||
|
||||
int bus = (bx >> 8) & 0xFF;
|
||||
int slot = (bx >> 3) & 0x1F;
|
||||
int func = bx & 0x7;
|
||||
|
||||
tag->bus = bus;
|
||||
tag->slot = slot;
|
||||
tag->func = func;
|
||||
|
||||
#if LIBPCI_CHECK_VERSION(2,1,99)
|
||||
if (pci_get_dev(pacc, 0, bus, slot, func))
|
||||
#else
|
||||
if (pci_get_dev(pacc, bus, slot, func))
|
||||
#endif
|
||||
return tag;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
u32 pciSlotBX(PCITAG tag)
|
||||
{
|
||||
return (tag->bus << 8) | (tag->slot << 3) | (tag->func);
|
||||
}
|
||||
|
||||
u8 pciReadByte(PCITAG tag, u32 idx)
|
||||
u8 pci_read_config8(struct device *dev, unsigned int where)
|
||||
{
|
||||
struct pci_dev *d;
|
||||
#if LIBPCI_CHECK_VERSION(2,1,99)
|
||||
if ((d = pci_get_dev(pacc, 0, tag->bus, tag->slot, tag->func)))
|
||||
#else
|
||||
if ((d = pci_get_dev(pacc, tag->bus, tag->slot, tag->func)))
|
||||
#endif
|
||||
return pci_read_byte(d, idx);
|
||||
if ((d = pci_get_dev(pacc, 0, dev->busno, dev->slot, dev->func)))
|
||||
return pci_read_byte(d, where);
|
||||
#ifdef DEBUG_PCI
|
||||
printf("PCI: device not found while read byte (%x:%x.%x)\n",
|
||||
tag->bus, tag->slot, tag->func);
|
||||
dev->busno, dev->slot, dev->func);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
u16 pciReadWord(PCITAG tag, u32 idx)
|
||||
u16 pci_read_config16(struct device *dev, unsigned int where)
|
||||
{
|
||||
struct pci_dev *d;
|
||||
#if LIBPCI_CHECK_VERSION(2,1,99)
|
||||
if ((d = pci_get_dev(pacc, 0, tag->bus, tag->slot, tag->func)))
|
||||
#else
|
||||
if ((d = pci_get_dev(pacc, tag->bus, tag->slot, tag->func)))
|
||||
#endif
|
||||
return pci_read_word(d, idx);
|
||||
if ((d = pci_get_dev(pacc, 0, dev->busno, dev->slot, dev->func)))
|
||||
return pci_read_word(d, where);
|
||||
#ifdef DEBUG_PCI
|
||||
printf("PCI: device not found while read word (%x:%x.%x)\n",
|
||||
tag->bus, tag->slot, tag->func);
|
||||
dev->busno, dev->slot, dev->func);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 pciReadLong(PCITAG tag, u32 idx)
|
||||
u32 pci_read_config32(struct device *dev, unsigned int where)
|
||||
{
|
||||
struct pci_dev *d;
|
||||
#if LIBPCI_CHECK_VERSION(2,1,99)
|
||||
if ((d = pci_get_dev(pacc, 0, tag->bus, tag->slot, tag->func)))
|
||||
#else
|
||||
if ((d = pci_get_dev(pacc, tag->bus, tag->slot, tag->func)))
|
||||
#endif
|
||||
return pci_read_long(d, idx);
|
||||
if ((d = pci_get_dev(pacc, 0, dev->busno, dev->slot, dev->func)))
|
||||
return pci_read_long(d, where);
|
||||
#ifdef DEBUG_PCI
|
||||
printf("PCI: device not found while read long (%x:%x.%x)\n",
|
||||
tag->bus, tag->slot, tag->func);
|
||||
printf("PCI: device not found while read dword (%x:%x.%x)\n",
|
||||
dev->busno, dev->slot, dev->func);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void pciWriteLong(PCITAG tag, u32 idx, u32 data)
|
||||
void pci_write_config8(struct device *dev, unsigned int where, u8 val)
|
||||
{
|
||||
struct pci_dev *d;
|
||||
#if LIBPCI_CHECK_VERSION(2,1,99)
|
||||
if ((d = pci_get_dev(pacc, 0, tag->bus, tag->slot, tag->func)))
|
||||
#else
|
||||
if ((d = pci_get_dev(pacc, tag->bus, tag->slot, tag->func)))
|
||||
#endif
|
||||
pci_write_long(d, idx, data);
|
||||
if ((d = pci_get_dev(pacc, 0, dev->busno, dev->slot, dev->func)))
|
||||
pci_write_byte(d, where, val);
|
||||
#ifdef DEBUG_PCI
|
||||
else
|
||||
printf("PCI: device not found while write long (%x:%x.%x)\n",
|
||||
tag->bus, tag->slot, tag->func);
|
||||
printf("PCI: device not found while write byte (%x:%x.%x)\n",
|
||||
dev->busno, dev->slot, dev->func);
|
||||
#endif
|
||||
}
|
||||
|
||||
void pciWriteWord(PCITAG tag, u32 idx, u16 data)
|
||||
void pci_write_config16(struct device *dev, unsigned int where, u16 val)
|
||||
{
|
||||
struct pci_dev *d;
|
||||
#if LIBPCI_CHECK_VERSION(2,1,99)
|
||||
if ((d = pci_get_dev(pacc, 0, tag->bus, tag->slot, tag->func)))
|
||||
#else
|
||||
if ((d = pci_get_dev(pacc, tag->bus, tag->slot, tag->func)))
|
||||
#endif
|
||||
pci_write_word(d, idx, data);
|
||||
if ((d = pci_get_dev(pacc, 0, dev->busno, dev->slot, dev->func)))
|
||||
pci_write_word(d, where, val);
|
||||
#ifdef DEBUG_PCI
|
||||
else
|
||||
printf("PCI: device not found while write word (%x:%x.%x)\n",
|
||||
tag->bus, tag->slot, tag->func);
|
||||
dev->busno, dev->slot, dev->func);
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
void pciWriteByte(PCITAG tag, u32 idx, u8 data)
|
||||
void pci_write_config32(struct device *dev, unsigned int where, u32 val)
|
||||
{
|
||||
struct pci_dev *d;
|
||||
#if LIBPCI_CHECK_VERSION(2,1,99)
|
||||
if ((d = pci_get_dev(pacc, 0, tag->bus, tag->slot, tag->func)))
|
||||
#else
|
||||
if ((d = pci_get_dev(pacc, tag->bus, tag->slot, tag->func)))
|
||||
#endif
|
||||
pci_write_long(d, idx, data);
|
||||
if ((d = pci_get_dev(pacc, 0, dev->busno, dev->slot, dev->func)))
|
||||
pci_write_long(d, where, val);
|
||||
#ifdef DEBUG_PCI
|
||||
else
|
||||
printf("PCI: device not found while write long (%x:%x.%x)\n",
|
||||
tag->bus, tag->slot, tag->func);
|
||||
printf("PCI: device not found while write dword (%x:%x.%x)\n",
|
||||
dev->busno, dev->slot, dev->func);
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -1,62 +1,35 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2016 Google Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __PCI_USERSPACE_H__
|
||||
#define __PCI_USERSPACE_H__
|
||||
|
||||
#include <pci/pci.h>
|
||||
|
||||
typedef unsigned long pciaddr_t;
|
||||
typedef u8 byte;
|
||||
typedef u16 word;
|
||||
|
||||
#if 0
|
||||
struct pci_dev {
|
||||
struct pci_dev *next; /* Next device in the chain */
|
||||
word bus; /* Higher byte can select host bridges */
|
||||
byte dev, func; /* Device and function */
|
||||
|
||||
/* These fields are set by pci_fill_info() */
|
||||
int known_fields; /* Set of info fields already known */
|
||||
word vendor_id, device_id; /* Identity of the device */
|
||||
int irq; /* IRQ number */
|
||||
pciaddr_t base_addr[6]; /* Base addresses */
|
||||
pciaddr_t size[6]; /* Region sizes */
|
||||
pciaddr_t rom_base_addr; /* Expansion ROM base address */
|
||||
pciaddr_t rom_size; /* Expansion ROM size */
|
||||
|
||||
/* Fields used internally: */
|
||||
void *access;
|
||||
void *methods;
|
||||
byte *cache; /* Cached information */
|
||||
int cache_len;
|
||||
int hdrtype; /* Direct methods: header type */
|
||||
void *aux; /* Auxillary data */
|
||||
struct device {
|
||||
int busno;
|
||||
int slot;
|
||||
int func;
|
||||
};
|
||||
|
||||
int pci_initialize(void);
|
||||
int pci_exit(void);
|
||||
|
||||
struct pci_filter {
|
||||
int bus, slot, func; /* -1 = ANY */
|
||||
int vendor, device;
|
||||
};
|
||||
#endif
|
||||
|
||||
#define PCITAG struct pci_filter *
|
||||
#define pciVideoPtr struct pci_dev *
|
||||
|
||||
extern int pciNumBuses;
|
||||
|
||||
int pciInit(void);
|
||||
int pciExit(void);
|
||||
|
||||
|
||||
PCITAG findPci(unsigned short bx);
|
||||
//u32 pciSlotBX(pciVideoPtr pvp);
|
||||
u32 pciSlotBX(PCITAG tag);
|
||||
|
||||
void pciWriteLong(PCITAG tag, u32 idx, u32 data);
|
||||
void pciWriteWord(PCITAG tag, u32 idx, u16 data);
|
||||
void pciWriteByte(PCITAG tag, u32 idx, u8 data);
|
||||
|
||||
u32 pciReadLong(PCITAG tag, u32 idx);
|
||||
u16 pciReadWord(PCITAG tag, u32 idx);
|
||||
u8 pciReadByte(PCITAG tag, u32 idx);
|
||||
u8 pci_read_config8(struct device *dev, unsigned int where);
|
||||
u16 pci_read_config16(struct device *dev, unsigned int where);
|
||||
u32 pci_read_config32(struct device *dev, unsigned int where);
|
||||
void pci_write_config8(struct device *dev, unsigned int where, u8 val);
|
||||
void pci_write_config16(struct device *dev, unsigned int where, u16 val);
|
||||
void pci_write_config32(struct device *dev, unsigned int where, u32 val);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,3 +1,18 @@
|
|||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright (C) 2016 Google Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
|
@ -7,75 +22,28 @@
|
|||
#include <getopt.h>
|
||||
#include <string.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#include <stdtypes.h>
|
||||
#define die(x) { perror(x); exit(1); }
|
||||
#define warn(x) { perror(x); }
|
||||
|
||||
#include <x86emu/x86emu.h>
|
||||
#include <console/console.h>
|
||||
#include "helper_exec.h"
|
||||
#include <arch/byteorder.h>
|
||||
#include "device.h"
|
||||
|
||||
#include "testbios.h"
|
||||
#include "pci-userspace.h"
|
||||
int X86EMU_set_debug(int debug);
|
||||
unsigned short get_device(char *arg_val);
|
||||
|
||||
biosemu_device_t bios_device;
|
||||
|
||||
extern int teststart, testend;
|
||||
|
||||
_ptr p;
|
||||
ptr current = 0;
|
||||
unsigned char biosmem[1024 * 1024];
|
||||
#define BIOSMEM_SIZE (1024 * 1024)
|
||||
unsigned char biosmem[BIOSMEM_SIZE];
|
||||
|
||||
int verbose = 0;
|
||||
|
||||
|
||||
/* Interrupt multiplexer */
|
||||
|
||||
static void do_int(int num)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
printf("int%x vector at %x\n", num, getIntVect(num));
|
||||
|
||||
/* This is a pInt leftover */
|
||||
current->num = num;
|
||||
|
||||
switch (num) {
|
||||
#ifndef _PC
|
||||
case 0x10:
|
||||
case 0x42:
|
||||
case 0x6D:
|
||||
|
||||
if (getIntVect(num) == 0xFF065) {
|
||||
ret = int42_handler();
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case 0x15:
|
||||
ret = int15_handler();
|
||||
break;
|
||||
case 0x16:
|
||||
ret = int16_handler();
|
||||
break;
|
||||
case 0x1A:
|
||||
ret = int1A_handler();
|
||||
break;
|
||||
case 0xe6:
|
||||
ret = intE6_handler();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (!ret)
|
||||
ret = run_bios_int(num);
|
||||
|
||||
if (!ret) {
|
||||
printf("\nint%x: not implemented\n", num);
|
||||
//x86emu_dump_xregs();
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned char *mapitin(char *file, off_t where, size_t size)
|
||||
{
|
||||
void *z;
|
||||
|
@ -90,14 +58,57 @@ static unsigned char *mapitin(char *file, off_t where, size_t size)
|
|||
close(fd);
|
||||
|
||||
return z;
|
||||
|
||||
}
|
||||
|
||||
X86EMU_pioFuncs myfuncs = {
|
||||
x_inb, x_inw, x_inl,
|
||||
x_outb, x_outw, x_outl
|
||||
};
|
||||
static unsigned short get_device(char *arg_val)
|
||||
{
|
||||
unsigned short devfn=0;
|
||||
long bus=0,dev=0,fn=0,need_pack=0;
|
||||
char *tok;
|
||||
|
||||
tok = strsep(&arg_val,":");
|
||||
if (arg_val != NULL) {
|
||||
bus = strtol(tok,0,16);
|
||||
need_pack = 1;
|
||||
}
|
||||
else {
|
||||
arg_val = tok;
|
||||
}
|
||||
|
||||
tok = strsep(&arg_val,".");
|
||||
if (arg_val != NULL) {
|
||||
dev = strtol(tok,0,16);
|
||||
fn = strtol(arg_val,0,16);
|
||||
need_pack = 1;
|
||||
}
|
||||
else {
|
||||
if (need_pack ==1 && (strlen(tok))) {
|
||||
dev = strtol(tok,0,16);
|
||||
}
|
||||
}
|
||||
|
||||
if ( need_pack == 1) {
|
||||
devfn = bus<<8 | (dev<<3) | fn;
|
||||
}
|
||||
else {
|
||||
devfn = strtol(tok, 0, 0);
|
||||
}
|
||||
|
||||
return devfn;
|
||||
}
|
||||
|
||||
int printk(int msg_level, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int i;
|
||||
|
||||
printf ("<%d> ", msg_level);
|
||||
va_start(args, fmt);
|
||||
i = vprintf(fmt, args);
|
||||
va_end(args);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static void usage(char *name)
|
||||
{
|
||||
|
@ -106,11 +117,24 @@ static void usage(char *name)
|
|||
name);
|
||||
}
|
||||
|
||||
/* main entry into YABEL biosemu, arguments are:
|
||||
* *biosmem = pointer to virtual memory
|
||||
* biosmem_size = size of the virtual memory
|
||||
* *dev = pointer to the device to be initialised
|
||||
* rom_addr = address of the OptionROM to be executed, if this is = 0, YABEL
|
||||
* will look for an ExpansionROM BAR and use the code from there.
|
||||
*/
|
||||
u32
|
||||
biosemu(u8 *biosmem, u32 biosmem_size, struct device * dev, unsigned long
|
||||
rom_addr);
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int ret;
|
||||
char *absegname = 0;
|
||||
void *abseg = 0;
|
||||
int i, c, trace = 0;
|
||||
int c, trace = 0;
|
||||
unsigned char *cp;
|
||||
char *filename;
|
||||
ssize_t size = 0;
|
||||
|
@ -118,12 +142,14 @@ int main(int argc, char **argv)
|
|||
int have_size = 0, have_base = 0, have_ip = 0, have_cs = 0;
|
||||
int have_devfn = 0;
|
||||
int parse_rom = 0;
|
||||
char *fsegname = 0;
|
||||
unsigned char *fsegptr;
|
||||
//char *fsegname = 0;
|
||||
//unsigned char *fsegptr;
|
||||
unsigned short initialip = 0, initialcs = 0, devfn = 0;
|
||||
X86EMU_intrFuncs intFuncs[256];
|
||||
//X86EMU_intrFuncs intFuncs[256];
|
||||
int debugflag = 0;
|
||||
struct device *dev;
|
||||
|
||||
//const char *optstring = "vh?b:i:c:s:tpd:";
|
||||
const char *optstring = "vh?b:i:c:s:tpd:";
|
||||
while (1) {
|
||||
int option_index = 0;
|
||||
|
@ -132,7 +158,7 @@ int main(int argc, char **argv)
|
|||
{"help", 0, 0, 'h'},
|
||||
{"trace", 0, 0, 't'},
|
||||
{"base", 1, 0, 'b'},
|
||||
{"fseg", 1, 0, 'f'},
|
||||
//{"fseg", 1, 0, 'f'},
|
||||
{"instructionpointer", 1, 0, 'i'},
|
||||
{"codesegment", 1, 0, 'c'},
|
||||
{"absegment", 1, 0, 'a'},
|
||||
|
@ -156,10 +182,10 @@ int main(int argc, char **argv)
|
|||
case 't':
|
||||
trace = 1;
|
||||
break;
|
||||
case 'b':
|
||||
base = strtol(optarg, 0, 0);
|
||||
have_base = 1;
|
||||
break;
|
||||
//case 'b':
|
||||
// base = strtol(optarg, 0, 0);
|
||||
// have_base = 1;
|
||||
// break;
|
||||
case 'i':
|
||||
initialip = strtol(optarg, 0, 0);
|
||||
have_ip = 1;
|
||||
|
@ -175,9 +201,9 @@ int main(int argc, char **argv)
|
|||
case 'p':
|
||||
parse_rom = 1;
|
||||
break;
|
||||
case 'f':
|
||||
fsegname = optarg;
|
||||
break;
|
||||
// case 'f':
|
||||
// fsegname = optarg;
|
||||
// break;
|
||||
case 'a':
|
||||
absegname = optarg;
|
||||
break;
|
||||
|
@ -220,10 +246,10 @@ int main(int argc, char **argv)
|
|||
printf("No base specified. defaulting to 0xc0000\n");
|
||||
base = 0xc0000;
|
||||
}
|
||||
if (!have_cs) {
|
||||
printf("No initial code segment specified. defaulting to 0xc000\n");
|
||||
initialcs = 0xc000;
|
||||
}
|
||||
//if (!have_cs) {
|
||||
// printf("No initial code segment specified. defaulting to 0xc000\n");
|
||||
// initialcs = 0xc000;
|
||||
//}
|
||||
if (!have_ip) {
|
||||
printf
|
||||
("No initial instruction pointer specified. defaulting to 0x0003\n");
|
||||
|
@ -234,7 +260,7 @@ int main(int argc, char **argv)
|
|||
printf("Parsing rom images not implemented.\n");
|
||||
|
||||
//printf("Point 1 int%x vector at %x\n", 0x42, getIntVect(0x42));
|
||||
|
||||
#if 0
|
||||
if (initialip == 0x0003) {
|
||||
if ((devfn == 0) || (have_devfn == 0)) {
|
||||
printf("WARNING! It appears you are trying to run an option ROM.\n");
|
||||
|
@ -250,6 +276,7 @@ int main(int argc, char **argv)
|
|||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (absegname) {
|
||||
abseg = mapitin(absegname, (off_t) 0xa0000, 0x20000);
|
||||
|
@ -257,10 +284,6 @@ int main(int argc, char **argv)
|
|||
die(absegname);
|
||||
}
|
||||
|
||||
current = &p;
|
||||
X86EMU_setMemBase(biosmem, sizeof(biosmem));
|
||||
M.abseg = (unsigned long)abseg;
|
||||
X86EMU_setupPioFuncs(&myfuncs);
|
||||
ioperm(0, 0x400, 1);
|
||||
|
||||
if (iopl(3) < 0) {
|
||||
|
@ -275,17 +298,20 @@ int main(int argc, char **argv)
|
|||
* basically this means initializing PCI and
|
||||
* intXX handlers.
|
||||
*/
|
||||
pciInit();
|
||||
pci_initialize();
|
||||
|
||||
#if 0
|
||||
for (i = 0; i < 256; i++)
|
||||
intFuncs[i] = do_int;
|
||||
X86EMU_setupIntrFuncs(intFuncs);
|
||||
#endif
|
||||
cp = mapitin(filename, (off_t) 0, size);
|
||||
|
||||
if (devfn) {
|
||||
printf("Loading ax with BusDevFn = %x\n",devfn);
|
||||
}
|
||||
|
||||
#if 0
|
||||
current->ax = devfn ? devfn : 0xff;
|
||||
current->dx = 0x80;
|
||||
// current->ip = 0;
|
||||
|
@ -322,68 +348,33 @@ int main(int argc, char **argv)
|
|||
pushw(X86_SP + 2);
|
||||
|
||||
X86_ES = 0x0000;
|
||||
#endif
|
||||
|
||||
if (trace) {
|
||||
printf("Switching to single step mode.\n");
|
||||
//X86EMU_trace_on();
|
||||
}
|
||||
if (debugflag) {
|
||||
printf("Enable Debug = %x.\n",debugflag);
|
||||
//X86EMU_set_debug(debugflag);
|
||||
}
|
||||
#if 0
|
||||
X86EMU_exec();
|
||||
#endif
|
||||
|
||||
ret = biosemu(biosmem, BIOSMEM_SIZE, dev, base);
|
||||
|
||||
#if 0
|
||||
current = &p;
|
||||
X86EMU_setMemBase(biosmem, sizeof(biosmem));
|
||||
M.abseg = (unsigned long)abseg;
|
||||
X86EMU_setupPioFuncs(&myfuncs);
|
||||
#endif
|
||||
|
||||
/* Cleaning up */
|
||||
pciExit();
|
||||
pci_exit();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned short get_device(char *arg_val)
|
||||
{
|
||||
unsigned short devfn=0;
|
||||
long bus=0,dev=0,fn=0,need_pack=0;
|
||||
char *tok;
|
||||
|
||||
tok = strsep(&arg_val,":");
|
||||
if (arg_val != NULL) {
|
||||
bus = strtol(tok,0,16);
|
||||
need_pack = 1;
|
||||
}
|
||||
else {
|
||||
arg_val = tok;
|
||||
}
|
||||
|
||||
tok = strsep(&arg_val,".");
|
||||
if (arg_val != NULL) {
|
||||
dev = strtol(tok,0,16);
|
||||
fn = strtol(arg_val,0,16);
|
||||
need_pack = 1;
|
||||
}
|
||||
else {
|
||||
if (need_pack ==1 && (strlen(tok))) {
|
||||
dev = strtol(tok,0,16);
|
||||
}
|
||||
}
|
||||
|
||||
if ( need_pack == 1) {
|
||||
devfn = bus<<8 | (dev<<3) | fn;
|
||||
}
|
||||
else {
|
||||
devfn = strtol(tok, 0, 0);
|
||||
}
|
||||
|
||||
|
||||
return devfn;
|
||||
}
|
||||
|
||||
int printk(int msg_level, const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
int i;
|
||||
|
||||
printf ("<%d> ", msg_level);
|
||||
va_start(args, fmt);
|
||||
i = vprintf(fmt, args);
|
||||
va_end(args);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
|
|
@ -1,19 +1,21 @@
|
|||
/* Derived from:
|
||||
* XFree86 int10 module
|
||||
* execute BIOS int 10h calls in x86 real mode environment
|
||||
/*
|
||||
* This file is part of the coreboot project.
|
||||
*
|
||||
* Copyright 1999 Egbert Eich
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; version 2 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#ifndef __TESTBIOS_H__
|
||||
#define __TESTBIOS_H__
|
||||
|
||||
void x86emu_dump_xregs(void);
|
||||
int int15_handler(void);
|
||||
int int16_handler(void);
|
||||
int int1A_handler(void);
|
||||
int int42_handler(void);
|
||||
int intE6_handler(void);
|
||||
|
||||
#include <stdtypes.h>
|
||||
#include <x86emu/x86emu.h>
|
||||
|
||||
|
@ -57,42 +59,4 @@ int intE6_handler(void);
|
|||
#define X86_CH M.x86.R_CH
|
||||
#define X86_DH M.x86.R_DH
|
||||
|
||||
|
||||
/* int10 info structure */
|
||||
typedef struct {
|
||||
u16 BIOSseg;
|
||||
u16 inb40time;
|
||||
struct _mem *mem;
|
||||
int num;
|
||||
int ax;
|
||||
int bx;
|
||||
int cx;
|
||||
int dx;
|
||||
int si;
|
||||
int di;
|
||||
int es;
|
||||
int bp;
|
||||
int flags;
|
||||
int stackseg;
|
||||
} _ptr, *ptr;
|
||||
|
||||
typedef struct _mem {
|
||||
u8(*rb) (ptr, int);
|
||||
u16(*rw) (ptr, int);
|
||||
u32(*rl) (ptr, int);
|
||||
void (*wb) (ptr, int, u8);
|
||||
void (*ww) (ptr, int, u16);
|
||||
void (*wl) (ptr, int, u32);
|
||||
} mem;
|
||||
|
||||
#define MEM_WB(where, what) wrb(where,what)
|
||||
#define MEM_WW(where, what) wrw(where, what)
|
||||
#define MEM_WL(where, what) wrl(where, what)
|
||||
|
||||
#define MEM_RB(where) rdb(where)
|
||||
#define MEM_RW(where) rdw(where)
|
||||
#define MEM_RL(where) rdl(where)
|
||||
|
||||
extern ptr current;
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue