debuggers.hg
changeset 13680:480436ef6255
This patch adds a 32bit gateway to the Bochs BIOS. The 32 bit code is
compiled with gcc and linked into the hvmloader as a byte-array.
Hvmloader allocates memory (rounded up to next 64kb) from the e820
table
below 4GB, copies and relocates the 32bit code in the allocated area
and
copies a jumptable (located in a section '.biosjumptable') pointing to
the 'exported' functions into the Bochs BIOS's memory area to link the
two code sections. The memory area has been reserved and can be
identified with the signature '___JMPT'.
In the Bochs BIOS only stub functions are provided. These load the
index
of a particular function in the jump table, switch to protected mode
and
call the function in the high memory area. The stack is prepared such
that functions compiled by gcc can just pick the parameters from the
stack as usual - this means that the 16bit real-mode return address is
taken off the stack. The stub functions should have the same signature
as those in 32bit space. For ABI compatibility reasons parameters
inside
the Bochs BIOS stubs should all be 32bit wide.
This patch includes a test function that calls three gcc-compiled
functions in the high memory area and displays their success status.
Simple tests are done doing multiplication and addition of 32-bit
numbers and reading and modification of a static variable. These
functions test the interface and the relocation code. The test code is
removed in patch part 3.
Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
compiled with gcc and linked into the hvmloader as a byte-array.
Hvmloader allocates memory (rounded up to next 64kb) from the e820
table
below 4GB, copies and relocates the 32bit code in the allocated area
and
copies a jumptable (located in a section '.biosjumptable') pointing to
the 'exported' functions into the Bochs BIOS's memory area to link the
two code sections. The memory area has been reserved and can be
identified with the signature '___JMPT'.
In the Bochs BIOS only stub functions are provided. These load the
index
of a particular function in the jump table, switch to protected mode
and
call the function in the high memory area. The stack is prepared such
that functions compiled by gcc can just pick the parameters from the
stack as usual - this means that the 16bit real-mode return address is
taken off the stack. The stub functions should have the same signature
as those in 32bit space. For ABI compatibility reasons parameters
inside
the Bochs BIOS stubs should all be 32bit wide.
This patch includes a test function that calls three gcc-compiled
functions in the high memory area and displays their success status.
Simple tests are done doing multiplication and addition of 32-bit
numbers and reading and modification of a static variable. These
functions test the interface and the relocation code. The test code is
removed in patch part 3.
Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
line diff
1.1 --- a/tools/firmware/Makefile Fri Jan 26 15:45:51 2007 +0000 1.2 +++ b/tools/firmware/Makefile Fri Jan 26 16:30:48 2007 +0000 1.3 @@ -7,7 +7,7 @@ TARGET := hvmloader/hvmloader 1.4 INST_DIR := $(DESTDIR)/usr/lib/xen/boot 1.5 1.6 SUBDIRS := 1.7 -SUBDIRS += rombios 1.8 +SUBDIRS += rombios rombios/32bit 1.9 SUBDIRS += vgabios 1.10 SUBDIRS += vmxassist 1.11 SUBDIRS += hvmloader
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 2.2 +++ b/tools/firmware/hvmloader/32bitbios_support.c Fri Jan 26 16:30:48 2007 +0000 2.3 @@ -0,0 +1,169 @@ 2.4 +/* 2.5 + * 32bitbios_support.c - relocation of 32bit BIOS implementation 2.6 + * 2.7 + * Stefan Berger, stefanb@us.ibm.com 2.8 + * Copyright (c) 2006, International Business Machines Corporation. 2.9 + * 2.10 + * This program is free software; you can redistribute it and/or modify it 2.11 + * under the terms and conditions of the GNU General Public License, 2.12 + * version 2, as published by the Free Software Foundation. 2.13 + * 2.14 + * This program is distributed in the hope it will be useful, but WITHOUT 2.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 2.17 + * more details. 2.18 + * 2.19 + * You should have received a copy of the GNU General Public License along with 2.20 + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple 2.21 + * Place - Suite 330, Boston, MA 02111-1307 USA. 2.22 + */ 2.23 +#include <elf.h> 2.24 +#include <xen/hvm/e820.h> 2.25 +#include "util.h" 2.26 +#include "config.h" 2.27 + 2.28 +#include "../rombios/32bit/32bitbios_flat.h" 2.29 +#include "../rombios/32bit/jumptable.h" 2.30 + 2.31 + 2.32 +/* 2.33 + * relocate ELF file of type ET_REL 2.34 + */ 2.35 +static int relocate_elf(unsigned char *elfarray) { 2.36 + Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfarray; 2.37 + Elf32_Shdr *shdr = (Elf32_Shdr *)&elfarray[ehdr->e_shoff]; 2.38 + int i; 2.39 + 2.40 + if (ehdr->e_type != ET_REL) { 2.41 + printf("Not a relocatabel BIOS object file. Has type %d, need %d\n", 2.42 + ehdr->e_type, ET_REL); 2.43 + return -1; 2.44 + } 2.45 + 2.46 + for (i = 0; i < ehdr->e_shnum; i++) { 2.47 + if (!(shdr[i]).sh_flags & SHF_ALLOC) { 2.48 + shdr[i].sh_addr = 0; 2.49 + continue; 2.50 + } 2.51 + shdr[i].sh_addr = (Elf32_Addr)&elfarray[shdr[i].sh_offset]; 2.52 + } 2.53 + 2.54 + for (i = 0; i < ehdr->e_shnum; i++) { 2.55 + if (shdr[i].sh_type == SHT_REL && shdr[i].sh_addr != 0) { 2.56 + Elf32_Shdr *targetsec = (Elf32_Shdr *)&(shdr[shdr[i].sh_info]); 2.57 + Elf32_Shdr *symtabsec = (Elf32_Shdr *)&(shdr[shdr[i].sh_link]); 2.58 + Elf32_Sym *syms = (Elf32_Sym *)symtabsec->sh_addr; 2.59 + Elf32_Rel *rels = (Elf32_Rel *)shdr[i].sh_addr; 2.60 + unsigned char *code = (unsigned char *)targetsec->sh_addr; 2.61 + int j; 2.62 + 2.63 + for (j = 0; j < shdr[i].sh_size / sizeof(Elf32_Rel); j++) { 2.64 + int idx = ELF32_R_SYM(rels[j].r_info); 2.65 + Elf32_Sym *symbol = &syms[idx]; 2.66 + uint32_t *loc = (uint32_t *)&code[rels[j].r_offset]; 2.67 + uint32_t fix = shdr[symbol->st_shndx].sh_addr + 2.68 + symbol->st_value; 2.69 + 2.70 + switch (ELF32_R_TYPE(rels[j].r_info)) { 2.71 + case R_386_PC32: 2.72 + *loc += (fix - (uint32_t)loc); 2.73 + break; 2.74 + 2.75 + case R_386_32: 2.76 + *loc += fix; 2.77 + break; 2.78 + } 2.79 + } 2.80 + } else if (shdr[i].sh_type == SHT_RELA) { 2.81 + return -2; 2.82 + } 2.83 + } 2.84 + return 0; 2.85 +} 2.86 + 2.87 +/* scan the rombios for the destination of the jumptable */ 2.88 +static char* get_jump_table_start(void) 2.89 +{ 2.90 + char *bios_mem; 2.91 + 2.92 + for ( bios_mem = (char *)ROMBIOS_BEGIN; 2.93 + bios_mem != (char *)ROMBIOS_END; 2.94 + bios_mem++ ) { 2.95 + if (strncmp(bios_mem, "___JMPT", 7) == 0) 2.96 + return bios_mem; 2.97 + } 2.98 + 2.99 + return NULL; 2.100 +} 2.101 + 2.102 +/* copy relocated jumptable into the rombios */ 2.103 +static int copy_jumptable(unsigned char *elfarray) 2.104 +{ 2.105 + int rc = 0; 2.106 + Elf32_Ehdr *ehdr = (Elf32_Ehdr *)elfarray; 2.107 + Elf32_Shdr *shdr = (Elf32_Shdr *)&elfarray[ehdr->e_shoff]; 2.108 + Elf32_Shdr *shdr_strings = (Elf32_Shdr *)&shdr[ehdr->e_shstrndx]; 2.109 + char *secstrings = (char *)&elfarray[shdr_strings->sh_offset]; 2.110 + uint32_t *rombiosjumptable = (uint32_t *)get_jump_table_start(); 2.111 + uint32_t *biosjumptable = NULL; 2.112 + int i; 2.113 + 2.114 + if (rombiosjumptable == NULL) { 2.115 + return -3; 2.116 + } 2.117 + 2.118 + /* find the section with the jump table and copy to lower BIOS memory */ 2.119 + for (i = 0; i < ehdr->e_shnum; i++) { 2.120 + if (!strcmp(JUMPTABLE_SECTION_NAME, secstrings + shdr[i].sh_name)) { 2.121 + uint32_t biosjumptableentries; 2.122 + biosjumptable = (uint32_t *)shdr[i].sh_addr; 2.123 + biosjumptableentries = shdr[i].sh_size / 4; 2.124 + for (int j = 0; j < biosjumptableentries; j++) { 2.125 + rombiosjumptable[j] = biosjumptable[j]; 2.126 + if (biosjumptable[j] == 0 && 2.127 + j < (biosjumptableentries - 1)) { 2.128 + printf("WARNING: jumptable entry %d is NULL!\n",j); 2.129 + } 2.130 + } 2.131 + break; 2.132 + } 2.133 + } 2.134 + 2.135 + if (biosjumptable == NULL) { 2.136 + printf("Could not find " JUMPTABLE_SECTION_NAME " section in file.\n"); 2.137 + rc = -4; 2.138 + } 2.139 + 2.140 + return 0; 2.141 +} 2.142 + 2.143 +static int relocate_32bitbios(unsigned char *elfarray, uint32_t elfarraysize) 2.144 +{ 2.145 + int rc = 0; 2.146 + uint32_t mask = (64 * 1024) - 1; 2.147 + uint32_t to_malloc = (elfarraysize + mask) & ~mask; /* round to 64kb */ 2.148 + unsigned char *highbiosarea; 2.149 + 2.150 + highbiosarea = (unsigned char *)(long) 2.151 + e820_malloc((uint64_t)to_malloc, 2.152 + E820_RESERVED, 2.153 + (uint64_t)0xffffffff); 2.154 + 2.155 + if (highbiosarea != 0) { 2.156 + memcpy(highbiosarea, elfarray, elfarraysize); 2.157 + rc = relocate_elf(highbiosarea); 2.158 + if (rc == 0) { 2.159 + rc = copy_jumptable(highbiosarea); 2.160 + } 2.161 + } else { 2.162 + rc = -5; 2.163 + } 2.164 + 2.165 + return rc; 2.166 +} 2.167 + 2.168 +int highbios_setup(void) 2.169 +{ 2.170 + return relocate_32bitbios((unsigned char *)highbios_array, 2.171 + sizeof(highbios_array)); 2.172 +}
3.1 --- a/tools/firmware/hvmloader/Makefile Fri Jan 26 15:45:51 2007 +0000 3.2 +++ b/tools/firmware/hvmloader/Makefile Fri Jan 26 16:30:48 2007 +0000 3.3 @@ -35,7 +35,7 @@ OBJCOPY = objcopy 3.4 CFLAGS += -fno-builtin -O2 -msoft-float 3.5 LDFLAGS = -nostdlib -Wl,-N -Wl,-Ttext -Wl,$(LOADADDR) 3.6 3.7 -SRCS = hvmloader.c mp_tables.c util.c smbios.c 3.8 +SRCS = hvmloader.c mp_tables.c util.c smbios.c 32bitbios_support.c 3.9 OBJS = $(patsubst %.c,%.o,$(SRCS)) 3.10 3.11 .PHONY: all
4.1 --- a/tools/firmware/hvmloader/config.h Fri Jan 26 15:45:51 2007 +0000 4.2 +++ b/tools/firmware/hvmloader/config.h Fri Jan 26 16:30:48 2007 +0000 4.3 @@ -11,4 +11,11 @@ 4.4 #define PCI_ISA_DEVFN 0x08 /* dev 1, fn 0 */ 4.5 #define PCI_ISA_IRQ_MASK 0x0c60U /* ISA IRQs 5,6,10,11 are PCI connected */ 4.6 4.7 +#define ROMBIOS_SEG 0xF000 4.8 +#define ROMBIOS_BEGIN 0x000F0000 4.9 +#define ROMBIOS_SIZE 0x00010000 4.10 +#define ROMBIOS_MAXOFFSET 0x0000FFFF 4.11 +#define ROMBIOS_END (ROMBIOS_BEGIN + ROMBIOS_SIZE) 4.12 + 4.13 + 4.14 #endif /* __HVMLOADER_CONFIG_H__ */
5.1 --- a/tools/firmware/hvmloader/hvmloader.c Fri Jan 26 15:45:51 2007 +0000 5.2 +++ b/tools/firmware/hvmloader/hvmloader.c Fri Jan 26 16:30:48 2007 +0000 5.3 @@ -314,6 +314,7 @@ int main(void) 5.4 5.5 printf("Loading ROMBIOS ...\n"); 5.6 memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, sizeof(rombios)); 5.7 + highbios_setup(); 5.8 5.9 apic_setup(); 5.10 pci_setup();
6.1 --- a/tools/firmware/hvmloader/mp_tables.c Fri Jan 26 15:45:51 2007 +0000 6.2 +++ b/tools/firmware/hvmloader/mp_tables.c Fri Jan 26 16:30:48 2007 +0000 6.3 @@ -45,12 +45,6 @@ typedef unsigned long uint64_t; 6.4 typedef signed long int64_t; 6.5 #endif 6.6 6.7 -#define ROMBIOS_SEG 0xF000 6.8 -#define ROMBIOS_BEGIN 0x000F0000 6.9 -#define ROMBIOS_SIZE 0x00010000 6.10 -#define ROMBIOS_MAXOFFSET 0x0000FFFF 6.11 -#define ROMBIOS_END (ROMBIOS_BEGIN + ROMBIOS_SIZE) 6.12 - 6.13 /* number of non-processor MP table entries */ 6.14 #define NR_NONPROC_ENTRIES 18 6.15 6.16 @@ -311,10 +305,7 @@ void* get_mp_table_start(void) 6.17 bios_mem != (char *)ROMBIOS_END; 6.18 bios_mem++ ) 6.19 { 6.20 - if ( bios_mem[0] == '_' && bios_mem[1] == '_' && 6.21 - bios_mem[2] == '_' && bios_mem[3] == 'H' && 6.22 - bios_mem[4] == 'V' && bios_mem[5] == 'M' && 6.23 - bios_mem[6] == 'M' && bios_mem[7] == 'P' ) 6.24 + if ( strncmp(bios_mem, "___HVMMP", 8) == 0) 6.25 return bios_mem; 6.26 } 6.27
7.1 --- a/tools/firmware/hvmloader/util.c Fri Jan 26 15:45:51 2007 +0000 7.2 +++ b/tools/firmware/hvmloader/util.c Fri Jan 26 16:30:48 2007 +0000 7.3 @@ -91,6 +91,15 @@ int strcmp(const char *cs, const char *c 7.4 return res; 7.5 } 7.6 7.7 +int strncmp(const char *s1, const char *s2, uint32_t n) 7.8 +{ 7.9 + uint32_t ctr; 7.10 + for (ctr = 0; ctr < n; ctr++) 7.11 + if (s1[ctr] != s2[ctr]) 7.12 + return (int)(s1[ctr] - s2[ctr]); 7.13 + return 0; 7.14 +} 7.15 + 7.16 void *memcpy(void *dest, const void *src, unsigned n) 7.17 { 7.18 int t0, t1, t2;
8.1 --- a/tools/firmware/hvmloader/util.h Fri Jan 26 15:45:51 2007 +0000 8.2 +++ b/tools/firmware/hvmloader/util.h Fri Jan 26 16:30:48 2007 +0000 8.3 @@ -53,6 +53,7 @@ int get_apic_mode(void); 8.4 8.5 /* String and memory functions */ 8.6 int strcmp(const char *cs, const char *ct); 8.7 +int strncmp(const char *s1, const char *s2, uint32_t n); 8.8 char *strcpy(char *dest, const char *src); 8.9 char *strncpy(char *dest, const char *src, unsigned n); 8.10 unsigned strlen(const char *s); 8.11 @@ -77,6 +78,10 @@ int vprintf(const char *fmt, va_list ap) 8.12 /* Allocate region of specified type in the e820 table. */ 8.13 uint64_t e820_malloc(uint64_t size, uint32_t type, uint64_t mask); 8.14 8.15 +/* Prepare the 32bit BIOS */ 8.16 +int highbios_setup(void); 8.17 + 8.18 + 8.19 #define isdigit(c) ((c) >= '0' && (c) <= '9') 8.20 8.21 #endif /* __HVMLOADER_UTIL_H__ */
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/tools/firmware/rombios/32bit/32bitbios.c Fri Jan 26 16:30:48 2007 +0000 9.3 @@ -0,0 +1,60 @@ 9.4 +/* 9.5 + * 32bitbios - jumptable for those function reachable from 16bit area 9.6 + * 9.7 + * This library is free software; you can redistribute it and/or 9.8 + * modify it under the terms of the GNU Lesser General Public 9.9 + * License as published by the Free Software Foundation; either 9.10 + * version 2 of the License, or (at your option) any later version. 9.11 + * 9.12 + * This library is distributed in the hope that it will be useful, 9.13 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 9.14 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9.15 + * Lesser General Public License for more details. 9.16 + * 9.17 + * You should have received a copy of the GNU Lesser General Public 9.18 + * License along with this library; if not, write to the Free Software 9.19 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 9.20 + * 9.21 + * Copyright (C) IBM Corporation, 2006 9.22 + * 9.23 + * Author: Stefan Berger <stefanb@us.ibm.com> 9.24 + */ 9.25 +#include "rombios_compat.h" 9.26 +#include "jumptable.h" 9.27 +#include "32bitprotos.h" 9.28 + 9.29 +/* same prototypes as in the 16bit BIOS */ 9.30 +Bit32u multiply(Bit32u a, Bit32u b) 9.31 +{ 9.32 + return a*b; 9.33 +} 9.34 + 9.35 +Bit32u add(Bit32u a, Bit32u b) 9.36 +{ 9.37 + return a+b; 9.38 +} 9.39 + 9.40 +static Bit32u stat_a = 0x1; 9.41 +Bit32u set_static(Bit32u a) 9.42 +{ 9.43 + Bit32u _a = stat_a; 9.44 + stat_a = a; 9.45 + return _a; 9.46 +} 9.47 + 9.48 + 9.49 +/* 9.50 + the jumptable that will be copied into the rombios in the 0xf000 segment 9.51 + for every function that is to be called from the lower BIOS, make an entry 9.52 + here. 9.53 + */ 9.54 +#define TABLE_ENTRY(idx, func) [idx] = (uint32_t)func 9.55 +uint32_t jumptable[IDX_LAST+1] __attribute__((section (JUMPTABLE_SECTION_NAME))) = 9.56 +{ 9.57 + TABLE_ENTRY(IDX_MULTIPLY , multiply), 9.58 + TABLE_ENTRY(IDX_ADD , add), 9.59 + TABLE_ENTRY(IDX_SET_STATIC , set_static), 9.60 + 9.61 + 9.62 + TABLE_ENTRY(IDX_LAST , 0) /* keep last */ 9.63 +};
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/tools/firmware/rombios/32bit/Makefile Fri Jan 26 16:30:48 2007 +0000 10.3 @@ -0,0 +1,31 @@ 10.4 + 10.5 +override XEN_TARGET_ARCH = x86_32 10.6 +XEN_ROOT = ../../../.. 10.7 +CFLAGS := 10.8 +include $(XEN_ROOT)/tools/Rules.mk 10.9 + 10.10 +TARGET = 32bitbios_flat.h 10.11 + 10.12 +CFLAGS += -fno-builtin -O2 -msoft-float 10.13 +CFLAGS += -I../ 10.14 + 10.15 +MODULES = 32bitbios.o 10.16 + 10.17 +.PHONY: all 10.18 + 10.19 +all : $(TARGET) 10.20 + 10.21 +clean :: 10.22 + rm -rf *.o $(TARGET) 10.23 + 10.24 +$(TARGET) : 32bitbios_all.o $(SOURCES) 10.25 + unref=`nm -u 32bitbios_all.o` 10.26 + @if [ "$$unref" != "" ]; then \ 10.27 + echo "There are unresolved symbols in the BIOS."; \ 10.28 + echo $$unref ; \ 10.29 + else \ 10.30 + bash mkhex highbios_array 32bitbios_all.o > $(TARGET); \ 10.31 + fi 10.32 + 10.33 +32bitbios_all.o : 32bitbios.o $(MODULES) 10.34 + ld $(LDFLAGS_DIRECT) -r $(MODULES) -o 32bitbios_all.o
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 11.2 +++ b/tools/firmware/rombios/32bit/jumptable.h Fri Jan 26 16:30:48 2007 +0000 11.3 @@ -0,0 +1,11 @@ 11.4 +#ifndef JUMPTABLE_H 11.5 +#define JUMPTABLE_H 11.6 + 11.7 +/* 11.8 + name of the section the 32bit BIOS must have and where the array of 11.9 + function poiners is built; hvmloader looks for this section and copies 11.10 + it into the lower BIOS in the 0xf000 segment 11.11 + */ 11.12 +#define JUMPTABLE_SECTION_NAME ".biosjumptable" 11.13 + 11.14 +#endif
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 12.2 +++ b/tools/firmware/rombios/32bit/mkhex Fri Jan 26 16:30:48 2007 +0000 12.3 @@ -0,0 +1,26 @@ 12.4 +#!/bin/sh 12.5 + 12.6 +# 12.7 +# mkhex: Generate C embeddable hexdumps 12.8 +# 12.9 +# Leendert van Doorn, leendert@watson.ibm.com 12.10 +# Copyright (c) 2005, International Business Machines Corporation. 12.11 +# 12.12 +# This program is free software; you can redistribute it and/or modify it 12.13 +# under the terms and conditions of the GNU General Public License, 12.14 +# version 2, as published by the Free Software Foundation. 12.15 +# 12.16 +# This program is distributed in the hope it will be useful, but WITHOUT 12.17 +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12.18 +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12.19 +# more details. 12.20 +# 12.21 +# You should have received a copy of the GNU General Public License along with 12.22 +# this program; if not, write to the Free Software Foundation, Inc., 59 Temple 12.23 +# Place - Suite 330, Boston, MA 02111-1307 USA. 12.24 +# 12.25 + 12.26 +echo "unsigned $1[] = {" 12.27 +od -v -t x $2 | sed 's/^[0-9]* /0x/' | sed 's/ /, 0x/g' | sed 's/$/,/' 12.28 +echo "};" 12.29 +
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/tools/firmware/rombios/32bit/rombios_compat.h Fri Jan 26 16:30:48 2007 +0000 13.3 @@ -0,0 +1,92 @@ 13.4 +#ifndef ROMBIOS_COMPAT 13.5 +#define ROMBIOS_COMPAT 13.6 + 13.7 +/* 13.8 + * Compatibility functions and structures for transitioning between 13.9 + * 16 bit Bochs BIOS and 32 bit BIOS code. 13.10 + */ 13.11 +#include <stdint.h> 13.12 + 13.13 +#define ADDR_FROM_SEG_OFF(seg, off) (void *)((((uint32_t)(seg)) << 4) + (off)) 13.14 + 13.15 +typedef uint8_t Bit8u; 13.16 +typedef uint16_t Bit16u; 13.17 +typedef uint32_t Bit32u; 13.18 + 13.19 +#define SetCF(x) (x)->u.r8.flagsl |= 0x01 13.20 +#define SetZF(x) (x)->u.r8.flagsl |= 0x40 13.21 +#define ClearCF(x) (x)->u.r8.flagsl &= 0xfe 13.22 +#define ClearZF(x) (x)->u.r8.flagsl &= 0xbf 13.23 +#define GetCF(x) ((x)->u.r8.flagsl & 0x01) 13.24 + 13.25 +#define SET_CF() *FLAGS |= 0x0001 13.26 +#define CLEAR_CF() *FLAGS &= 0xfffe 13.27 +#define GET_CF() (*FLAGS & 0x0001) 13.28 + 13.29 +#define SET_ZF() *FLAGS |= 0x0040 13.30 +#define CLEAR_ZF() *FLAGS &= 0xffbf 13.31 + 13.32 + 13.33 +typedef struct { 13.34 + union { 13.35 + struct { 13.36 + Bit32u edi, esi, ebp, esp; 13.37 + Bit32u ebx, edx, ecx, eax; 13.38 + } r32; 13.39 + struct { 13.40 + Bit16u di, filler1, si, filler2, bp, filler3, sp, filler4; 13.41 + Bit16u bx, filler5, dx, filler6, cx, filler7, ax, filler8; 13.42 + } r16; 13.43 + struct { 13.44 + Bit32u filler[4]; 13.45 + Bit8u bl, bh; 13.46 + Bit16u filler1; 13.47 + Bit8u dl, dh; 13.48 + Bit16u filler2; 13.49 + Bit8u cl, ch; 13.50 + Bit16u filler3; 13.51 + Bit8u al, ah; 13.52 + Bit16u filler4; 13.53 + } r8; 13.54 + } u; 13.55 +} __attribute__((packed)) pushad_regs_t; 13.56 + 13.57 + 13.58 + 13.59 +static inline Bit32u read_dword(Bit16u seg, Bit16u off) 13.60 +{ 13.61 + uint32_t *addr = (uint32_t *)ADDR_FROM_SEG_OFF(seg,off); 13.62 + return *addr; 13.63 +} 13.64 + 13.65 +static inline Bit16u read_word(Bit16u seg, Bit16u off) 13.66 +{ 13.67 + uint16_t *addr = (uint16_t *)ADDR_FROM_SEG_OFF(seg,off); 13.68 + return *addr; 13.69 +} 13.70 + 13.71 +static inline Bit8u read_byte(Bit16u seg, Bit16u off) 13.72 +{ 13.73 + uint8_t *addr = (uint8_t *)ADDR_FROM_SEG_OFF(seg,off); 13.74 + return *addr; 13.75 +} 13.76 + 13.77 +static inline void write_dword(Bit16u seg, Bit16u off, Bit32u val) 13.78 +{ 13.79 + uint32_t *addr = (uint32_t *)ADDR_FROM_SEG_OFF(seg,off); 13.80 + *addr = val; 13.81 +} 13.82 + 13.83 +static inline void write_word(Bit16u seg, Bit16u off, Bit16u val) 13.84 +{ 13.85 + uint16_t *addr = (uint16_t *)ADDR_FROM_SEG_OFF(seg,off); 13.86 + *addr = val; 13.87 +} 13.88 + 13.89 +static inline void write_byte(Bit16u seg, Bit16u off, Bit8u val) 13.90 +{ 13.91 + uint8_t *addr = (uint8_t *)ADDR_FROM_SEG_OFF(seg,off); 13.92 + *addr = val; 13.93 +} 13.94 + 13.95 +#endif
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/tools/firmware/rombios/32bitgateway.c Fri Jan 26 16:30:48 2007 +0000 14.3 @@ -0,0 +1,486 @@ 14.4 +/* 14.5 + * Implementation of a gateway into 32bit space. Stub functions 14.6 + * can be called from Bochs BIOS which call functions with a compatible 14.7 + * signature in 32bit space. All interrupts are disabled while in 14.8 + * 32 bit mode. 14.9 + * 14.10 + * This library is free software; you can redistribute it and/or 14.11 + * modify it under the terms of the GNU Lesser General Public 14.12 + * License as published by the Free Software Foundation; either 14.13 + * version 2 of the License, or (at your option) any later version. 14.14 + * 14.15 + * This library is distributed in the hope that it will be useful, 14.16 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 14.17 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14.18 + * Lesser General Public License for more details. 14.19 + * 14.20 + * You should have received a copy of the GNU Lesser General Public 14.21 + * License along with this library; if not, write to the Free Software 14.22 + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 14.23 + * 14.24 + * Copyright (C) IBM Corporation, 2006 14.25 + * 14.26 + * Author: Stefan Berger <stefanb@us.ibm.com> 14.27 + */ 14.28 + 14.29 +/* 14.30 + * Note: 14.31 + * BCC's ABI does not require to preserve any 16bit registers ax, bx, cs, dx 14.32 + * by a called function. So these registers need not be preserved while 14.33 + * calling a function in 32bit space, either. 14.34 + * 14.35 + * When bcc calls a function with 16bit parameters it pushes 2 bytes onto 14.36 + * the stack for such a parameter. GCC, however, expects 32bit parameters 14.37 + * (4 bytes) even for uint16_t, so casting to 32bit from bcc is a good idea. 14.38 + */ 14.39 + 14.40 +#define SEGMENT_OFFSET 0xf0000 14.41 +#define REAL_MODE_CODE_SEGMENT 0xf000 14.42 + 14.43 +#define START_PM_CODE USE32 14.44 +#define END_PM_CODE USE16 14.45 + 14.46 +/* definition of used code/data segment descriptors */ 14.47 +#define PM_NORMAL_CS (gdt_entry_pm_cs - gdt_base) 14.48 +#define PM_16BIT_CS (gdt_entry_pm_16bit_cs - gdt_base) 14.49 +#define PM_32BIT_DS (gdt_entry_pm_32bit_ds - gdt_base) 14.50 + 14.51 + ASM_START 14.52 + 14.53 + ; Switch into protected mode to allow access to 32 bit addresses. 14.54 + ; This function allows switching into protected mode. 14.55 + ; (the specs says big real mode, but that will not work) 14.56 + ; 14.57 + ; preserves all registers and prepares cs, ds, es, ss for usage 14.58 + ; in protected mode; while in prot.mode interrupts remain disabled 14.59 +switch_to_protmode: 14.60 + cli 14.61 + 14.62 + ; have to fix the stack for proper return address in 32 bit mode 14.63 + push WORD #(REAL_MODE_CODE_SEGMENT>>12) ;extended return address 14.64 + push bp ;pop@A1 14.65 + mov bp, sp 14.66 + push eax ;pop@A2 14.67 + mov eax, 2[bp] ; fix return address 14.68 + rol eax, #16 14.69 + mov 2[bp], eax 14.70 + 14.71 + mov eax, esp 14.72 + ror eax, #16 ; hi(esp) 14.73 + 14.74 + push bx ; preserve before function call 14.75 + push cx 14.76 + push dx 14.77 + 14.78 + push ax ; prepare stack for 14.79 + push es ; call 14.80 + push ds 14.81 + push cs 14.82 + push ss 14.83 + call _store_segment_registers 14.84 + add sp, #10 ; pop ax,es-ss 14.85 + 14.86 + pop dx ; restore after function call 14.87 + pop cx 14.88 + pop bx 14.89 + 14.90 + ; calculate protected-mode esp from ss:sp 14.91 + and esp, #0xffff 14.92 + xor eax, eax 14.93 + mov ax, ss 14.94 + rol eax, #4 14.95 + add eax, esp 14.96 + mov esp, eax 14.97 + 14.98 + seg cs 14.99 + lgdt my_gdtdesc ; switch to own table 14.100 + 14.101 + mov eax, cr0 14.102 + or al, #0x1 ; protected mode 'on' 14.103 + mov cr0, eax 14.104 + 14.105 + jmpf DWORD (SEGMENT_OFFSET | switch_to_protmode_goon_1), #PM_NORMAL_CS 14.106 + 14.107 + START_PM_CODE 14.108 + 14.109 +switch_to_protmode_goon_1: 14.110 + mov ax, #PM_32BIT_DS ; 32 bit segment that allows 14.111 + mov ds, ax ; to reach all 32 bit 14.112 + mov es, ax ; addresses 14.113 + mov ss, ax 14.114 + 14.115 + pop eax ;@A2 14.116 + pop bp ;@A1 14.117 + ret 14.118 + 14.119 + END_PM_CODE 14.120 + 14.121 + 14.122 + 14.123 + .align 16 14.124 +gdt_base: 14.125 + ; see Intel SW Dev. Manuals section 3.4.5, Volume 3 for meaning of bits 14.126 + .word 0,0 14.127 + .byte 0,0,0,0 14.128 + 14.129 +gdt_entry_pm_cs: 14.130 + ; 32 bit code segment for protected mode 14.131 + .word 0xffff, 0x0000 14.132 + .byte 0x00, 0x9a, 0xcf, 0x00 14.133 + 14.134 +gdt_entry_pm_16bit_cs: 14.135 + ; temp. 16 bit code segment used while in protected mode 14.136 + .word 0xffff, 0x0000 14.137 + .byte SEGMENT_OFFSET >> 16, 0x9a, 0x0, 0x0 14.138 + 14.139 +gdt_entry_pm_32bit_ds: 14.140 + ; (32 bit) data segment (r/w) reaching all possible areas in 32bit memory 14.141 + ; 4kb granularity 14.142 + .word 0xffff, 0x0000 14.143 + .byte 0x0, 0x92, 0xcf, 0x0 14.144 +gdt_entry_end: 14.145 + 14.146 +my_gdtdesc: 14.147 + .word (gdt_entry_end - gdt_base) - 1 14.148 + .long gdt_base | SEGMENT_OFFSET 14.149 + 14.150 + 14.151 +realmode_gdtdesc: ;to be used in real mode 14.152 + .word 0xffff 14.153 + .long 0x0 14.154 + 14.155 + 14.156 + 14.157 +switch_to_realmode: 14.158 + ; Implementation of switching from protected mode to real mode 14.159 + ; restores all registers and prepares cs, es, ds, ss to be used 14.160 + ; in real mode 14.161 + START_PM_CODE 14.162 + 14.163 + ; need to fix up the stack to return in 16 bit mode 14.164 + ; currently the 32 bit return address is on the stack 14.165 + push bp ;pop@A1 14.166 + mov bp, sp 14.167 + push eax ;pop@X 14.168 + 14.169 + mov eax, [bp] ; return address low 16bits 14.170 + ; and 'bp' are being moved 14.171 + mov 2[bp], eax 14.172 + 14.173 + pop eax ;@X 14.174 + add sp, #2 ; adjust stack for 'lost' bytes 14.175 + 14.176 + push eax ;pop@1 14.177 + push bx ;pop@2 14.178 + push si ;pop@3 14.179 + 14.180 + call _ebda_ss_offset32 ; get the offset of the ss 14.181 + mov bx, ax ; entry within the ebda. 14.182 + 14.183 + jmpf switch_to_realmode_goon_1, #PM_16BIT_CS 14.184 + 14.185 + END_PM_CODE 14.186 + 14.187 +switch_to_realmode_goon_1: 14.188 + mov eax, cr0 14.189 + and al, #0xfe ; protected mode 'off' 14.190 + mov cr0, eax 14.191 + 14.192 + jmpf switch_to_realmode_goon_2, #REAL_MODE_CODE_SEGMENT 14.193 + 14.194 +switch_to_realmode_goon_2: 14.195 + 14.196 + ; get orig. 'ss' without using the stack (no 'call'!) 14.197 + xor eax, eax ; clear upper 16 bits (and lower) 14.198 + mov ax, #0x40 ; where is the ebda located? 14.199 + mov ds, ax 14.200 + mov si, #0xe 14.201 + seg ds 14.202 + mov ax, [si] ; ax = segment of ebda 14.203 + 14.204 + mov ds, ax ; segment of ebda 14.205 + seg ds 14.206 + mov ax, [bx] ; stack segment - bx has been set above 14.207 + mov ss, ax 14.208 + 14.209 + ; from esp and ss calculate real-mode sp 14.210 + rol eax, #4 14.211 + sub esp, eax 14.212 + 14.213 + push dx ;preserve before call(s) 14.214 + push cx 14.215 + push bx 14.216 + 14.217 + call _get_register_ds ; get orig. 'ds' 14.218 + mov ds, ax 14.219 + call _get_register_es ; get orig. 'es' 14.220 + mov es, ax 14.221 + call _get_register_esp_hi ; fix the upper 16 bits of esp 14.222 + ror esp, #16 14.223 + mov sp, ax 14.224 + rol esp, #16 14.225 + 14.226 + pop bx 14.227 + pop cx 14.228 + pop dx 14.229 + 14.230 + seg cs 14.231 + lgdt realmode_gdtdesc 14.232 + 14.233 + sti ; allow interrupts 14.234 + 14.235 + pop si ;@3 14.236 + pop bx ;@2 14.237 + pop eax ;@1 14.238 + pop bp ;@A1 14.239 + 14.240 + ret 14.241 + 14.242 + ASM_END 14.243 + 14.244 +/* 14.245 + * Helper function to get the offset of the reg_ss within the ebda struct 14.246 + * Only 'C' can tell the offset. 14.247 + */ 14.248 +Bit16u 14.249 +ebda_ss_offset32() 14.250 +{ 14.251 + ASM_START 14.252 + START_PM_CODE // need to have this 14.253 + ASM_END // compiled for protected mode 14.254 + return &EbdaData->upcall.reg_ss; // 'C' knows the offset! 14.255 + ASM_START 14.256 + END_PM_CODE 14.257 + ASM_END 14.258 +} 14.259 + 14.260 +/* 14.261 + * Two often-used functions 14.262 + */ 14.263 +Bit16u 14.264 +read_word_from_ebda(offset) 14.265 + Bit16u offset; 14.266 +{ 14.267 + Bit16u ebda_seg = read_word(0x0040, 0x000E); 14.268 + return read_word(ebda_seg, offset); 14.269 +} 14.270 + 14.271 +Bit32u 14.272 +read_dword_from_ebda(offset) 14.273 + Bit16u offset; 14.274 +{ 14.275 + Bit16u ebda_seg = read_word(0x0040, 0x000E); 14.276 + return read_dword(ebda_seg, offset); 14.277 +} 14.278 + 14.279 +/* 14.280 + * Store registers in the EBDA; used to keep the registers' 14.281 + * content in a well-defined place during protected mode execution 14.282 + */ 14.283 + void 14.284 +store_segment_registers(ss, cs, ds, es, esp_hi) 14.285 + Bit16u ss, cs, ds, es, esp_hi; 14.286 +{ 14.287 + Bit16u ebda_seg = read_word(0x0040, 0x000E); 14.288 + write_word(ebda_seg, &EbdaData->upcall.reg_ss, ss); 14.289 + write_word(ebda_seg, &EbdaData->upcall.reg_cs, cs); 14.290 + write_word(ebda_seg, &EbdaData->upcall.reg_ds, ds); 14.291 + write_word(ebda_seg, &EbdaData->upcall.reg_es, es); 14.292 + write_word(ebda_seg, &EbdaData->upcall.esp_hi, esp_hi); 14.293 +} 14.294 + 14.295 + 14.296 + void 14.297 +store_returnaddress(retaddr) 14.298 + Bit16u retaddr; 14.299 +{ 14.300 + Bit16u ebda_seg = read_word(0x0040, 0x000E); 14.301 + write_word(ebda_seg, &EbdaData->upcall.retaddr, retaddr); 14.302 +} 14.303 + 14.304 +Bit16u 14.305 +get_returnaddress() 14.306 +{ 14.307 + return read_word_from_ebda(&EbdaData->upcall.retaddr); 14.308 +} 14.309 + 14.310 +/* 14.311 + * get the segment register 'cs' value from the EBDA 14.312 + */ 14.313 +Bit16u 14.314 +get_register_cs() 14.315 +{ 14.316 + return read_word_from_ebda(&EbdaData->upcall.reg_cs); 14.317 +} 14.318 + 14.319 +/* 14.320 + * get the segment register 'ds' value from the EBDA 14.321 + */ 14.322 +Bit16u 14.323 +get_register_ds() 14.324 +{ 14.325 + return read_word_from_ebda(&EbdaData->upcall.reg_ds); 14.326 +} 14.327 + 14.328 +/* 14.329 + * get the segment register 'es' value from the EBDA 14.330 + */ 14.331 +Bit16u 14.332 +get_register_es() 14.333 +{ 14.334 + return read_word_from_ebda(&EbdaData->upcall.reg_es); 14.335 +} 14.336 + 14.337 +/* 14.338 + * get the upper 16 bits of the esp from the EBDA 14.339 + */ 14.340 +Bit16u 14.341 +get_register_esp_hi() 14.342 +{ 14.343 + return read_word_from_ebda(&EbdaData->upcall.esp_hi); 14.344 +} 14.345 + 14.346 + 14.347 + 14.348 +/********************************************************/ 14.349 + 14.350 + 14.351 +ASM_START 14.352 + 14.353 +Upcall: 14.354 + ; do the upcall into 32 bit space 14.355 + ; clear the stack frame so that 32 bit space sees all the parameters 14.356 + ; on the stack as if they were prepared for it 14.357 + ; ---> take the 16 bit return address off the stack and remember it 14.358 + ; 14.359 + ; Input: 14.360 + ; bx: index of function to call 14.361 + ; Ouput: 14.362 + ; dx, ax: 32 bit result of call (even if 'void' is expected) 14.363 + 14.364 + push bp ;pop @1 14.365 + mov bp, sp 14.366 + push si ;pop @2 14.367 + 14.368 + mov ax, 2[bp] ; 16 bit return address 14.369 + push ax 14.370 + call _store_returnaddress ; store away 14.371 + pop ax 14.372 + 14.373 + rol bx, #2 14.374 + mov si, #jmptable 14.375 + seg cs 14.376 + mov eax, dword ptr [si+bx] ; address to call from table 14.377 + 14.378 + pop si ;@2 14.379 + pop bp ;@1 14.380 + 14.381 + add sp, #2 ; remove 16bit return address from stack 14.382 + 14.383 + call switch_to_protmode 14.384 + START_PM_CODE 14.385 + 14.386 + call eax ; call 32bit function 14.387 + push eax ; preserve result 14.388 + 14.389 + call switch_to_realmode ; back to realmode 14.390 + END_PM_CODE 14.391 + 14.392 + pop eax ; get result 14.393 + 14.394 + push word 0x0000 ; placeholder for 16 bit return address 14.395 + push bp 14.396 + mov bp,sp 14.397 + push eax ; preserve work register 14.398 + 14.399 + call _get_returnaddress 14.400 + mov 2[bp], ax ; 16bit return address onto stack 14.401 + 14.402 + pop eax 14.403 + pop bp 14.404 + 14.405 + ror eax, #16 ; result into dx/ax 14.406 + mov dx, ax ; hi(res) -> dx 14.407 + ror eax, #16 14.408 + 14.409 + ret 14.410 + 14.411 + 14.412 +/* macro for functions to declare their call into 32bit space */ 14.413 +MACRO DoUpcall 14.414 + mov bx, #?1 14.415 + jmp Upcall 14.416 +MEND 14.417 + 14.418 + 14.419 +ASM_END 14.420 + 14.421 +#include "32bitprotos.h" 14.422 +#include "32bitgateway.h" 14.423 + 14.424 +/******************************************************************** 14.425 + Collection of stub functions for functions executed in 32bit space 14.426 + *******************************************************************/ 14.427 + 14.428 +Bit32u multiply(a, b) /* for testing */ 14.429 + Bit32u a; 14.430 + Bit32u b; 14.431 +{ 14.432 + ASM_START 14.433 + DoUpcall IDX_MULTIPLY 14.434 + ASM_END 14.435 +} 14.436 + 14.437 +Bit32u add(a, b) /* for testing */ 14.438 + Bit32u a; 14.439 + Bit32u b; 14.440 +{ 14.441 + ASM_START 14.442 + DoUpcall IDX_ADD 14.443 + ASM_END 14.444 +} 14.445 + 14.446 +Bit32u set_static(a, b) /* for testing */ 14.447 + Bit32u a; 14.448 + Bit32u b; 14.449 +{ 14.450 + ASM_START 14.451 + DoUpcall IDX_SET_STATIC 14.452 + ASM_END 14.453 +} 14.454 + 14.455 +/* a function to test the gateway */ 14.456 +void 14.457 +test_gateway() 14.458 +{ 14.459 + Bit32u res; 14.460 + Bit16u err = 0; 14.461 + 14.462 + printf("32bit gateway "); 14.463 + res = multiply(11111L,222L); 14.464 + if (err = 0 && res != 11111L * 222L) { 14.465 + printf("not working correctly: multiply\n"); 14.466 + err = 1; 14.467 + } 14.468 + 14.469 + res = add(111111L, 222222L); 14.470 + if (err = 0 && res != 111111L + 222222L) { 14.471 + printf("not working correctly: add\n"); 14.472 + err = 1; 14.473 + } 14.474 + 14.475 + res = set_static(0x12345678L); 14.476 + if (err = 0 && res != 0x1L) { 14.477 + printf("not working correctly: set_static (1)\n"); 14.478 + err = 1; 14.479 + } 14.480 + res = set_static(0x11111111L); 14.481 + if (err = 0 && res != 0x12345678L) { 14.482 + printf("not working correctly: set_static (2)\n"); 14.483 + err = 1; 14.484 + } 14.485 + 14.486 + if (err == 0) { 14.487 + printf("working correctly\n"); 14.488 + } 14.489 +}
15.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 15.2 +++ b/tools/firmware/rombios/32bitgateway.h Fri Jan 26 16:30:48 2007 +0000 15.3 @@ -0,0 +1,18 @@ 15.4 +#ifndef GATEWAY 15.5 +#define GATEWAY 15.6 + 15.7 +#include "32bitprotos.h" 15.8 + 15.9 +void test_gateway(); 15.10 + 15.11 +/* extension for the EBDA */ 15.12 +typedef struct { 15.13 + Bit16u reg_ss; 15.14 + Bit16u reg_cs; 15.15 + Bit16u reg_ds; 15.16 + Bit16u reg_es; 15.17 + Bit16u esp_hi; 15.18 + Bit16u retaddr; 15.19 +} upcall_t; 15.20 + 15.21 +#endif
16.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 16.2 +++ b/tools/firmware/rombios/32bitprotos.h Fri Jan 26 16:30:48 2007 +0000 16.3 @@ -0,0 +1,22 @@ 16.4 +#ifndef PROTOS_HIGHBIOS 16.5 +#define PROTOS_HIGHBIOS 16.6 + 16.7 +/* bcc does not like 'enum' */ 16.8 +#define IDX_MULTIPLY 0 16.9 +#define IDX_ADD 1 16.10 +#define IDX_SET_STATIC 2 16.11 +#define IDX_LAST 3 /* keep last! */ 16.12 + 16.13 + 16.14 +#ifdef GCC_PROTOS 16.15 + #define PARMS(x...) x 16.16 +#else 16.17 + /* bcc doesn't want any parameter types in prototypes */ 16.18 + #define PARMS(x...) 16.19 +#endif 16.20 + 16.21 +Bit32u multiply( PARMS(Bit32u a, Bit32u b) ); 16.22 +Bit32u add( PARMS(Bit32u a, Bit32u b) ); 16.23 +Bit32u set_static( PARMS(Bit32u) ); 16.24 + 16.25 +#endif
17.1 --- a/tools/firmware/rombios/Makefile Fri Jan 26 15:45:51 2007 +0000 17.2 +++ b/tools/firmware/rombios/Makefile Fri Jan 26 16:30:48 2007 +0000 17.3 @@ -12,7 +12,7 @@ clean: 17.4 rm -f rombios*.txt rombios*.sym usage biossums 17.5 rm -f BIOS-bochs-* 17.6 17.7 -BIOS-bochs-latest: rombios.c biossums 17.8 +BIOS-bochs-latest: rombios.c biossums 32bitgateway.c 17.9 gcc -DBX_SMP_PROCESSORS=1 -E -P $< > _rombios_.c 17.10 bcc -o rombios.s -C-c -D__i86__ -0 -S _rombios_.c 17.11 sed -e 's/^\.text//' -e 's/^\.data//' rombios.s > _rombios_.s
18.1 --- a/tools/firmware/rombios/rombios.c Fri Jan 26 15:45:51 2007 +0000 18.2 +++ b/tools/firmware/rombios/rombios.c Fri Jan 26 16:30:48 2007 +0000 18.3 @@ -722,6 +722,8 @@ typedef struct { 18.4 } cdemu_t; 18.5 #endif // BX_ELTORITO_BOOT 18.6 18.7 +#include "32bitgateway.h" 18.8 + 18.9 // for access to EBDA area 18.10 // The EBDA structure should conform to 18.11 // http://www.cybertrails.com/~fys/rombios.htm document 18.12 @@ -745,6 +747,7 @@ typedef struct { 18.13 cdemu_t cdemu; 18.14 #endif // BX_ELTORITO_BOOT 18.15 18.16 + upcall_t upcall; 18.17 } ebda_data_t; 18.18 18.19 #define EbdaData ((ebda_data_t *) 0) 18.20 @@ -1852,6 +1855,7 @@ print_bios_banner() 18.21 printf(BX_APPNAME" BIOS, %d cpu%s, ", BX_SMP_PROCESSORS, BX_SMP_PROCESSORS>1?"s":""); 18.22 printf("%s %s\n", bios_cvs_version_string, bios_date_string); 18.23 printf("\n"); 18.24 + test_gateway(); 18.25 } 18.26 18.27 18.28 @@ -8853,6 +8857,10 @@ use16 386 18.29 18.30 #endif 18.31 18.32 +ASM_END 18.33 +#include "32bitgateway.c" 18.34 +ASM_START 18.35 + 18.36 ;-------------------- 18.37 #if BX_PCIBIOS 18.38 use32 386 18.39 @@ -10691,13 +10699,23 @@ static Bit8u vgafont8[128*8]= 18.40 }; 18.41 18.42 #ifdef HVMASSIST 18.43 +ASM_START 18.44 + 18.45 +// space for addresses in 32bit BIOS area; currently 256/4 entries 18.46 +// are allocated 18.47 +.org 0xcb00 18.48 +jmptable: 18.49 +db 0x5F, 0x5F, 0x5F, 0x4A, 0x4D, 0x50, 0x54 ;; ___JMPT 18.50 +dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 64 bytes 18.51 +dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 128 bytes 18.52 +dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 192 bytes 18.53 + 18.54 // 18.55 // MP Tables 18.56 // just carve out some blank space for HVMLOADER to write the MP tables to 18.57 // 18.58 // NOTE: There should be enough space for a 32 processor entry MP table 18.59 // 18.60 -ASM_START 18.61 .org 0xcc00 18.62 db 0x5F, 0x5F, 0x5F, 0x48, 0x56, 0x4D, 0x4D, 0x50 ;; ___HVMMP 18.63 dw 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ;; 64 bytes