direct-io.hg

changeset 13642: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>
author kaf24@localhost.localdomain
date Fri Jan 26 16:30:48 2007 +0000 (2007-01-26)
parents b97780b7080d
children c07326324f8d
files tools/firmware/Makefile tools/firmware/hvmloader/32bitbios_support.c tools/firmware/hvmloader/Makefile tools/firmware/hvmloader/config.h tools/firmware/hvmloader/hvmloader.c tools/firmware/hvmloader/mp_tables.c tools/firmware/hvmloader/util.c tools/firmware/hvmloader/util.h tools/firmware/rombios/32bit/32bitbios.c tools/firmware/rombios/32bit/Makefile tools/firmware/rombios/32bit/jumptable.h tools/firmware/rombios/32bit/mkhex tools/firmware/rombios/32bit/rombios_compat.h tools/firmware/rombios/32bitgateway.c tools/firmware/rombios/32bitgateway.h tools/firmware/rombios/32bitprotos.h tools/firmware/rombios/Makefile tools/firmware/rombios/rombios.c
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