Changeset 5135


Ignore:
Timestamp:
Feb 22, 2010, 5:33:13 AM (5 years ago)
Author:
stepan
Message:

YABEL update

  • drop x86emu + old biosemu in favor of YABEL
  • Add YABEL_DIRECTHW to get the old biosemu behavior
  • add support for vesa console using YABEL
  • add coreboot table entry with console information
  • add bootsplash support (reads /bootsplash.jpg from CBFS)

Signed-off-by: Stefan Reinauer <stepan@…>
Acked-by: Pattrick Hueper <phueper@…>

Location:
trunk
Files:
2 added
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/arch/i386/boot/coreboot_table.c

    r5065 r5135  
    146146#if CONFIG_USBDEBUG_DIRECT
    147147        add_console(header, LB_TAG_CONSOLE_EHCI);
     148#endif
     149}
     150
     151static void lb_framebuffer(struct lb_header *header)
     152{
     153#if defined(CONFIG_BOOTSPLASH) && CONFIG_BOOTSPLASH && CONFIG_COREBOOT_KEEP_FRAMEBUFFER
     154        void fill_lb_framebuffer(struct lb_framebuffer *framebuffer);
     155
     156        struct lb_framebuffer *framebuffer;
     157        framebuffer = (struct lb_framebuffer *)lb_new_record(header);
     158        framebuffer->tag = LB_TAG_FRAMEBUFFER;
     159        framebuffer->size = sizeof(*framebuffer);
     160        fill_lb_framebuffer(framebuffer);
    148161#endif
    149162}
     
    566579        /* Record our various random string information */
    567580        lb_strings(head);
     581        /* Record our framebuffer */
     582        lb_framebuffer(head);
    568583
    569584        /* Remember where my valid memory ranges are */
  • trunk/src/arch/i386/include/arch/byteorder.h

    r1411 r5135  
    1515#define be16_to_cpu(x) swab16((x))
    1616
     17#define ntohl(x) be32_to_cpu(x)
     18#define htonl(x) cpu_to_be32(x)
     19
    1720#endif /* _BYTEORDER_H */
  • trunk/src/devices/Kconfig

    r5127 r5135  
    22## This file is part of the coreboot project.
    33##
    4 ## Copyright (C) 2007 coresystems GmbH
     4## Copyright (C) 2007-2010 coresystems GmbH
    55## (Written by Stefan Reinauer <stepan@coresystems.de> for coresystems GmbH)
    66##
     
    5050
    5151config PCI_OPTION_ROM_RUN_REALMODE
    52         prompt "Real mode"
     52        prompt "Native mode"
    5353        bool
    5454        depends on ARCH_X86
     
    5959          (only works on x86/x64 systems)
    6060
    61 config PCI_OPTION_ROM_RUN_X86EMU
    62         prompt "x86emu"
     61config PCI_OPTION_ROM_RUN_YABEL
     62        prompt "Secure Mode"
    6363        bool
    6464        help
    6565          If you select this option, the x86emu CPU emulator will be used to
    66           execute PCI option ROMs.
     66          execute PCI option ROMs.
     67          This option prevents option ROMs from doing dirty tricks with the
     68          system (such as installing SMM modules or hypervisors), but it is also
     69          significantly slower than the native option ROM initialization method.
     70          This is the default choice for non-x86 systems.
     71endchoice
     72
     73# TODO: Describe better, and/or make a "choice" selection for this.
     74config YABEL_DEBUG_FLAGS
     75        prompt "Hex value for YABEL debug flags"
     76        hex
     77        default 0x0
     78        depends on PCI_OPTION_ROM_RUN_YABEL
     79        help
     80          Set CONFIG_YABEL_DEBUG_FLAGS is a binary switch that allows you
     81          to select the following items to debug. 1=on 0=off. After you
     82          decide what you want to debug create the binary value, convert to hex
     83          and set the Option (Ex. CONFIG_YABEL_DEBUG_FLAGS = 0x31FF //Debug All).
     84
     85          |-DEBUG_JMP - print info about JMP and RETF opcodes from x86emu
     86          ||-DEBUG_TRACE_X86EMU - print _all_ opcodes that are executed by x86emu (WARNING: this will produce a LOT of output)
     87          |||-Currently unused
     88          ||||-Currently unused
     89          |||||-Currently unused
     90          ||||||-DEBUG_PNP - Print Plug And Play access made by option rom
     91          |||||||-DEBUG_DISK - Print Disk I/O related messages, currently unused
     92          ||||||||-DEBUG_PMM - Print messages related to POST Memory Manager (PMM)
     93          |||||||||-DEBUG_VBE - Print messages related to VESA BIOS Extension (VBE) functions
     94          ||||||||||-DEBUG_PRINT_INT10 - let INT10 (i.e. character output) calls print messages to Debug output
     95          |||||||||||-DEBUG_INTR - Print messages related to interrupt handling
     96          ||||||||||||-DEBUG_CHECK_VMEM_ACCESS - Print messages related to accesse to certain areas of the virtual Memory (e.g. BDA (BIOS Data Area) or Interrupt Vectors)
     97          |||||||||||||-DEBUG_MEM - Print memory access made by option rom (NOTE: this also includes accesses to fetch instructions)
     98          ||||||||||||||-DEBUG_IO - Print I/O access made by option rom
     99          11000111111111 - Max Binary Value, Debug All (WARNING: - This could run for hours)
     100       
     101          DEBUG_IO                0x0001
     102          DEBUG_MEM               0x0002
     103          DEBUG_CHECK_VMEM_ACCESS 0x0004
     104          DEBUG_INTR              0x0008
     105          DEBUG_PRINT_INT10       0x0010
     106          DEBUG_VBE               0x0020
     107          DEBUG_PMM               0x0040
     108          DEBUG_DISK              0x0080
     109          DEBUG_PNP               0x0100
     110          DEBUG_TRACE_X86EMU      0x1000
     111          DEBUG_JMP               0x2000
     112
     113          See debug.h for values 0 is no debug output, 0x31ff is _verbose_.
     114
     115config YABEL_PCI_ACCESS_OTHER_DEVICES
     116        prompt "Allow option roms to acces other devices"
     117        bool
     118        depends on PCI_OPTION_ROM_RUN_YABEL
     119        help
     120          Per default, YABEL only allows option roms to access the PCI device
     121          that they are associated with. However, this causes trouble for some
     122          onboard graphics chips whose option rom needs to reconfigure the
     123          north bridge.
     124
     125config YABEL_VIRTMEM_LOCATION
     126        prompt "Location of YABEL's virtual memory"
     127        hex
     128        depends on PCI_OPTION_ROM_RUN_YABEL && EXPERT
     129        default 0x1000000
     130        help
     131          YABEL requires 1MB memory for its CPU emulation. This memory is
     132          normally located at 16MB.
     133
     134config YABEL_DIRECTHW
     135        prompt "Direct Hardware Access"
     136        bool
     137        depends on PCI_OPTION_ROM_RUN_YABEL
     138        help
     139          YABEL consists of two parts: It uses x86emu for the CPU emulation and
     140          additionally provides a PC system emulation that filters bad device and
     141          memory access (such as PCI config space access to other devices than the
     142          initialized one).
    67143          When choosing this option, x86emu will pass through all hardware
    68144          accesses to memory and IO devices to the underlying memory and IO
     
    70146          tricks with the CPU (such as installing SMM modules or hypervisors),
    71147          they can still access all devices in the system.
    72           Choosing x86emu, option ROM execution is slower than native execution
    73           in real mode, but faster than the full system emulation YABEL
    74           This is the default choice for non-x86 systems.
    75 
    76 config PCI_OPTION_ROM_RUN_YABEL
    77         prompt "YABEL"
    78         bool
    79         help
    80           If you select this option, the YABEL system emulator will be used to
    81           execute PCI option ROMs.
    82           YABEL consists of two parts: It uses x86emu for the CPU emulation and
    83           additionally provides a PC system emulation that filters bad device and
    84           memory access (such as PCI config space access to other devices than the
    85           initialized one).
    86           This option best prevents option ROMs from doing dirty tricks with the
    87           system (such as installing SMM modules or hypervisors), but it is also
    88           significantly slower than the other option ROM initialization methods.
    89 
    90 endchoice
    91 
    92 config YABEL_PCI_ACCESS_OTHER_DEVICES
    93         prompt "Allow option roms to acces other devices"
    94         bool
    95         depends on PCI_OPTION_ROM_RUN_YABEL
    96         help
    97           Per default, YABEL only allows option roms to access the PCI device
    98           that they are associated with. However, this causes trouble for some
    99           onboard graphics chips whose option rom needs to reconfigure the
    100           north bridge.
    101 
    102 config YABEL_VIRTMEM_LOCATION
    103         prompt "Location of YABEL's virtual memory"
     148          Enable this option for a good compromise between security and speed.
     149
     150config BOOTSPLASH
     151        prompt "Show graphical bootsplash"
     152        bool
     153        depends on PCI_OPTION_ROM_RUN_YABEL
     154        help
     155          This option shows a graphical bootsplash screen. The grapics are
     156          loaded from the CBFS file bootsplash.jpg
     157
     158config FRAMEBUFFER_VESA_MODE
     159        prompt "VESA framebuffer video mode"
    104160        hex
    105         depends on EXPERT
    106         default 0x1000000
    107         help
    108           YABEL requires 1MB memory for its CPU emulation. This memory is
    109           normally located at 16MB.
    110 
    111 # TODO: Describe better, and/or make a "choice" selection for this.
    112 config YABEL_DEBUG_FLAGS
    113         prompt "Hex value for YABEL debug flags"
    114         hex
    115         default 0x0
    116         depends on PCI_OPTION_ROM_RUN_YABEL
    117         help
    118           See debug.h for values 0 is no debug output, 0x31ff is _verbose_.
     161        default 0x117
     162        depends on BOOTSPLASH
     163        help
     164          This option sets the resolution used for the coreboot framebuffer and
     165          bootsplash screen. Set to 0x117 for 1024x768x16. A diligent soul will
     166          some day make this a "choice".
     167
     168config COREBOOT_KEEP_FRAMEBUFFER
     169        prompt "Keep VESA framebuffer"
     170        bool
     171        depends on BOOTSPLASH
     172        help
     173          This option keeps the framebuffer mode set after coreboot finishes
     174          execution. If this option is enabled, coreboot will pass a framebuffer
     175          entry in its coreboot table and the payload will need a framebuffer
     176          driver. If this option is disabled, coreboot will switch back to
     177          text mode before handing control to a payload.
    119178
    120179config CONSOLE_VGA_MULTI
  • trunk/src/include/boot/coreboot_tables.h

    r4453 r5135  
    160160};
    161161
    162 #define LB_TAG_FORWARD          0x0011
    163 struct lb_forward {
    164         uint32_t tag;
    165         uint32_t size;
    166         uint64_t forward;
    167 };
    168 
    169162#define LB_TAG_CONSOLE_SERIAL8250       0
    170163#define LB_TAG_CONSOLE_VGA              1
     
    173166#define LB_TAG_CONSOLE_SROM             4
    174167#define LB_TAG_CONSOLE_EHCI             5
     168
     169#define LB_TAG_FORWARD          0x0011
     170struct lb_forward {
     171        uint32_t tag;
     172        uint32_t size;
     173        uint64_t forward;
     174};
     175
     176#define LB_TAG_FRAMEBUFFER      0x0012
     177struct lb_framebuffer {
     178        uint32_t tag;
     179        uint32_t size;
     180
     181        uint64_t physical_address;
     182        uint32_t x_resolution;
     183        uint32_t y_resolution;
     184        uint32_t bytes_per_line;
     185        uint8_t bits_per_pixel;
     186        uint8_t red_mask_pos;
     187        uint8_t red_mask_size;
     188        uint8_t green_mask_pos;
     189        uint8_t green_mask_size;
     190        uint8_t blue_mask_pos;
     191        uint8_t blue_mask_size;
     192        uint8_t reserved_mask_pos;
     193        uint8_t reserved_mask_size;
     194};
    175195
    176196/* The following structures are for the cmos definitions table */
  • trunk/src/lib/Makefile.inc

    r4860 r5135  
    2727obj-$(CONFIG_COMPRESSED_PAYLOAD_LZMA) += lzma.o
    2828
     29obj-$(CONFIG_BOOTSPLASH) += jpeg.o
     30
    2931ifdef POST_EVALUATION
    3032$(obj)/lib/version.o :: $(obj)/build.h
  • trunk/src/lib/cbfs.c

    r4933 r5135  
    2323#include <cbfs.h>
    2424#include <lib.h>
    25 
    26 #ifndef CONFIG_BIG_ENDIAN
    27 #define ntohl(x) ( ((x&0xff)<<24) | ((x&0xff00)<<8) | \
    28                 ((x&0xff0000) >> 8) | ((x&0xff000000) >> 24) )
    29 #else
    30 #define ntohl(x) (x)
    31 #endif
     25#include <arch/byteorder.h>
    3226
    3327int cbfs_decompress(int algo, void *src, void *dst, int len)
     
    214208void * cbfs_get_file(const char *name)
    215209{
    216         return cbfs_find(name);
     210        return (void *) cbfs_find(name);
    217211}
    218212
  • trunk/src/lib/fallback_boot.c

    r4381 r5135  
    3131void boot_successful(void)
    3232{
     33#if defined(CONFIG_BOOTSPLASH) && CONFIG_BOOTSPLASH && !CONFIG_COREBOOT_KEEP_FRAMEBUFFER
     34        void vbe_textmode_console(void);
     35
     36        vbe_textmode_console();
     37#endif
    3338        /* Remember this was a successful boot */
    3439        set_boot_successful();
  • trunk/util/x86emu/Makefile

    r4915 r5135  
    1 ##
    2 ## This file is part of the coreboot project.
    3 ##
    4 ## Copyright (C) 2007 coresystems GmbH
    5 ##
    6 ## This program is free software; you can redistribute it and/or modify
    7 ## it under the terms of the GNU General Public License as published by
    8 ## the Free Software Foundation; either version 2 of the License, or
    9 ## (at your option) any later version.
    10 ##
    11 ## This program is distributed in the hope that it will be useful,
    12 ## but WITHOUT ANY WARRANTY; without even the implied warranty of
    13 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14 ## GNU General Public License for more details.
    15 ##
    16 ## You should have received a copy of the GNU General Public License
    17 ## along with this program; if not, write to the Free Software
    18 ## Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
    19 ##
    20 
    21 #X86EMU_INCLUDE = -I $(src)/util/x86emu/include 
    22 
    23 X86EMU_SRC  = debug.c decode.c fpu.c ops.c ops2.c prim_ops.c sys.c
    24 ifeq ($(CONFIG_PCI_OPTION_ROM_RUN_X86EMU),y)
    25 BIOSEMU_SRC = biosemu.c
    26 endif
    27 
    28 ifeq ($(CONFIG_PCI_OPTION_ROM_RUN_YABEL),y)
    29 BIOSEMU_SRC  = biosemu.c debug.c device.c mem.c io.c interrupt.c
    30 #TODO: add vbe.c, currently not needed...
    31 #BIOSEMU_SRC +=vbe.c
    32 BIOSEMU_SRC +=pmm.c
    33 #PH: TODO: remove the compat files??
    34 BIOSEMU_SRC  += compat/functions.c
    35 X86EMU_INCLUDE += -I $(src)/util/x86emu/yabel
    36 X86EMU_INCLUDE += -I $(src)/util/x86emu
    37 #TODO: remove these, these are .h files from slof, to make the merge easier...
    38 X86EMU_INCLUDE += -I $(src)/util/x86emu/yabel/compat
    39 endif
    40 REALMODE_SRC    = x86.c x86_asm.S
    41 
    42 ifeq ($(CONFIG_PCI_OPTION_ROM_RUN_X86EMU),y)
    43 LIBX86EMU_SRC=$(patsubst %,x86emu/%,$(X86EMU_SRC)) $(BIOSEMU_SRC)
    44 endif
    45 
    46 ifeq ($(CONFIG_PCI_OPTION_ROM_RUN_YABEL),y)
    47 LIBX86EMU_SRC=$(patsubst %,x86emu/%,$(X86EMU_SRC)) $(patsubst %,yabel/%,$(BIOSEMU_SRC))
    48 endif
    49 
    50 ifeq ($(CONFIG_PCI_OPTION_ROM_RUN_REALMODE),y)
    51 LIBX86EMU_SRC=$(REALMODE_SRC)
    52 endif
    53 
    54 LIBX86EMU_OBJS = $(patsubst %.c,$(obj)/util/x86emu/%.o,$(LIBX86EMU_SRC))
    55 # needed for kscope
    56 PCIROM_SRC += $(patsubst %,$(src)/util/x86emu/%,$(LIBX86EMU_SRC))
    57 
    58 
    59 $(obj)/util/x86emu/libx86emu.a: $(LIBX86EMU_OBJS) $(src)/.config
    60         @printf "  AR      $(subst $(shell pwd)/,,$(@))\n"
    61         $(Q)rm -f $@ # otherwise we always add to the archive
    62         $(Q)$(AR) qcs $@ $(LIBX86EMU_OBJS)
    63 
    64 #
    65 # This rule is also valid for all subdirectories
    66 #
    67 
    68 $(obj)/util/x86emu/%.o: $(src)/util/x86emu/%.c
    69         @printf "  CC      $(subst $(shell pwd)/,,$(@))\n"
    70         $(Q)mkdir -p $(dir $@)
    71         $(Q)$(CC) -Werror $(INITCFLAGS) $(X86EMU_INCLUDE) -I$(src)/util/x86emu/include -c $< -o $@
    72 
  • trunk/util/x86emu/Makefile.inc

    r4915 r5135  
    22## This file is part of the coreboot project.
    33##
    4 ## Copyright (C) 2007 coresystems GmbH
     4## Copyright (C) 2007-2010 coresystems GmbH
    55##
    66## This program is free software; you can redistribute it and/or modify
    77## it under the terms of the GNU General Public License as published by
    8 ## the Free Software Foundation; either version 2 of the License, or
    9 ## (at your option) any later version.
     8## the Free Software Foundation; version 2 of the License.
    109##
    1110## This program is distributed in the hope that it will be useful,
     
    1918##
    2019
    21 subdirs-$(CONFIG_PCI_OPTION_ROM_RUN_X86EMU) += x86emu
    22 obj-$(CONFIG_PCI_OPTION_ROM_RUN_X86EMU) += biosemu.o
    23 
    2420obj-$(CONFIG_PCI_OPTION_ROM_RUN_REALMODE) += x86.o
    2521obj-$(CONFIG_PCI_OPTION_ROM_RUN_REALMODE) += x86_asm.o
  • trunk/util/x86emu/biosemu.c

    r5131 r5135  
    1 /*
    2  * This software and ancillary information (herein called SOFTWARE )
    3  * called LinuxBIOS          is made available under the terms described
    4  * here.  The SOFTWARE has been approved for release with associated
    5  * LA-CC Number 00-34   .  Unless otherwise indicated, this SOFTWARE has
    6  * been authored by an employee or employees of the University of
    7  * California, operator of the Los Alamos National Laboratory under
    8  * Contract No. W-7405-ENG-36 with the U.S. Department of Energy.  The
    9  * U.S. Government has rights to use, reproduce, and distribute this
    10  * SOFTWARE.  The public may copy, distribute, prepare derivative works
    11  * and publicly display this SOFTWARE without charge, provided that this
    12  * Notice and any statement of authorship are reproduced on all copies.
    13  * Neither the Government nor the University makes any warranty, express
    14  * or implied, or assumes any liability or responsibility for the use of
    15  * this SOFTWARE.  If SOFTWARE is modified to produce derivative works,
    16  * such modified SOFTWARE should be clearly marked, so as not to confuse
    17  * it with the version available from LANL.
    18  */
    19  /*
    20  * This file is part of the coreboot project.
    21  *
    22  *  (c) Copyright 2000, Ron Minnich, Advanced Computing Lab, LANL
    23  *  Copyright (C) 2009 coresystems GmbH
    24  *
    25  * This program is free software; you can redistribute it and/or modify
    26  * it under the terms of the GNU General Public License as published by
    27  * the Free Software Foundation; either version 2 of the License, or
    28  * (at your option) any later version.
    29  *
    30  * This program is distributed in the hope that it will be useful,
    31  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    32  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    33  * GNU General Public License for more details.
    34  *
    35  * You should have received a copy of the GNU General Public License
    36  * along with this program; if not, write to the Free Software
    37  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
    38  */
    39 #include <string.h>
    40 #include <arch/io.h>
    41 #include <console/console.h>
    42 #include <device/device.h>
    43 #include <device/pci.h>
    44 #include <device/pci_ids.h>
    45 #include <device/pci_ops.h>
    46 #include <x86emu/x86emu.h>
    47 #include "x86emu/prim_ops.h"
    48 
    49 #define DATA_SEGMENT 0x2000
    50 #define STACK_SEGMENT 0x1000    //1000:xxxx
    51 #define STACK_START_OFFSET 0xfffe
    52 #define INITIAL_EBDA_SEGMENT 0xF600     // segment of the Extended BIOS Data Area
    53 #define INITIAL_EBDA_SIZE 0x400 // size of the EBDA (at least 1KB!! since size is stored in KB!)
    54 
    55 enum {
    56         PCI_BIOS_PRESENT        = 0xB101,
    57         FIND_PCI_DEVICE         = 0xB102,
    58         FIND_PCI_CLASS_CODE     = 0xB103,
    59         GENERATE_SPECIAL_CYCLE  = 0xB106,
    60         READ_CONFIG_BYTE        = 0xB108,
    61         READ_CONFIG_WORD        = 0xB109,
    62         READ_CONFIG_DWORD       = 0xB10A,
    63         WRITE_CONFIG_BYTE       = 0xB10B,
    64         WRITE_CONFIG_WORD       = 0xB10C,
    65         WRITE_CONFIG_DWORD      = 0xB10D,
    66         GET_IRQ_ROUTING_OPTIONS = 0xB10E,
    67         SET_PCI_IRQ             = 0xB10F
    68 };
    69 
    70 enum {
    71         SUCCESSFUL              = 0x00,
    72         FUNC_NOT_SUPPORTED      = 0x81,
    73         BAD_VENDOR_ID           = 0x83,
    74         DEVICE_NOT_FOUND        = 0x86,
    75         BAD_REGISTER_NUMBER     = 0x87,
    76         SET_FAILED              = 0x88,
    77         BUFFER_TOO_SMALL        = 0x89
    78 };
    79 
    80 #define MEM_WB(where, what) wrb(where, what)
    81 #define MEM_WW(where, what) wrw(where, what)
    82 #define MEM_WL(where, what) wrl(where, what)
    83 
    84 #define MEM_RB(where) rdb(where)
    85 #define MEM_RW(where) rdw(where)
    86 #define MEM_RL(where) rdl(where)
    87 
    88 static u8 biosemu_inb(u16 port)
    89 {
    90         u8 val;
    91 
    92         val = inb(port);
    93 #ifdef DEBUG
    94         if (port != 0x40)
    95             printk("inb(0x%04x) = 0x%02x\n", port, val);
    96 #endif
    97 
    98         return val;
    99 }
    100 
    101 static u16 biosemu_inw(u16 port)
    102 {
    103         u16 val;
    104 
    105         val = inw(port);
    106 
    107 #ifdef DEBUG
    108         printk("inw(0x%04x) = 0x%04x\n", port, val);
    109 #endif
    110         return val;
    111 }
    112 
    113 static u32 biosemu_inl(u16 port)
    114 {
    115         u32 val;
    116 
    117         val = inl(port);
    118 
    119 #ifdef DEBUG
    120         printk("inl(0x%04x) = 0x%08x\n", port, val);
    121 #endif
    122         return val;
    123 }
    124 
    125 static void biosemu_outb(u16 port, u8 val)
    126 {
    127 #ifdef DEBUG
    128         if (port != 0x43)
    129                 printk("outb(0x%02x, 0x%04x)\n", val, port);
    130 #endif
    131         outb(val, port);
    132 }
    133 
    134 static void biosemu_outw(u16 port, u16 val)
    135 {
    136 #ifdef DEBUG
    137         printk("outw(0x%04x, 0x%04x)\n", val, port);
    138 #endif
    139         outw(val, port);
    140 }
    141 
    142 static void biosemu_outl(u16 port, u32 val)
    143 {
    144 #ifdef DEBUG
    145         printk("outl(0x%08x, 0x%04x)\n", val, port);
    146 #endif
    147         outl(val, port);
    148 }
    149 
    150 static X86EMU_pioFuncs biosemu_piofuncs = {
    151         biosemu_inb,  biosemu_inw,  biosemu_inl,
    152         biosemu_outb, biosemu_outw, biosemu_outl
    153 };
    154 
    155 /* Interrupt Handlers */
    156 
    157 static int int15_handler(void)
    158 {
    159         /* This int15 handler is VIA Tech. and Intel specific. Other chipsets need other
    160          * handlers. The right way to do this is to move this handler code into
    161          * the mainboard or northbridge code.
    162          */
    163         switch (X86_AX) {
    164         case 0x5f19:
    165                 X86_EFLAGS |= FB_CF;    /* set carry flag */
    166                 break;
    167         case 0x5f18:
    168                 X86_EAX = 0x5f;
    169                 // MCLK = 133, 32M frame buffer, 256 M main memory
    170                 X86_EBX = 0x545;
    171                 X86_ECX = 0x060;
    172                 X86_EFLAGS &= ~FB_CF;
    173                 break;
    174         case 0x5f00:
    175                 X86_EAX = 0x8600;
    176                 X86_EFLAGS |= FB_CF;    /* set carry flag */
    177                 break;
    178         case 0x5f01:
    179                 X86_EAX = 0x5f;
    180                 X86_ECX = (X86_ECX & 0xffffff00 ) | 2; // panel type =  2 = 1024 * 768
    181                 X86_EFLAGS &= ~FB_CF;
    182                 break;
    183         case 0x5f02:
    184                 X86_EAX = 0x5f;
    185                 X86_EBX = (X86_EBX & 0xffff0000) | 2;
    186                 X86_ECX = (X86_ECX & 0xffff0000) | 0x401;  // PAL + crt only
    187                 X86_EDX = (X86_EDX & 0xffff0000) | 0;  // TV Layout - default
    188                 X86_EFLAGS &= ~FB_CF;
    189                 break;
    190         case 0x5f0f:
    191                 X86_EAX = 0x860f;
    192                 X86_EFLAGS |= FB_CF;    /* set carry flag */
    193                 break;
    194         /* And now Intel IGD code */
    195 #define BOOT_DISPLAY_DEFAULT    0
    196 #define BOOT_DISPLAY_CRT        (1 << 0)
    197 #define BOOT_DISPLAY_TV         (1 << 1)
    198 #define BOOT_DISPLAY_EFP        (1 << 2)
    199 #define BOOT_DISPLAY_LCD        (1 << 3)
    200 #define BOOT_DISPLAY_CRT2       (1 << 4)
    201 #define BOOT_DISPLAY_TV2        (1 << 5)
    202 #define BOOT_DISPLAY_EFP2       (1 << 6)
    203 #define BOOT_DISPLAY_LCD2       (1 << 7)
    204 
    205         case 0x5f35:
    206                 X86_EAX = 0x5f;
    207                 X86_ECX = BOOT_DISPLAY_DEFAULT;
    208                 X86_EFLAGS &= ~FB_CF;
    209                 break;
    210         case 0x5f40:
    211                 X86_EAX = 0x5f;
    212                 X86_ECX = 3; // This is mainboard specific
    213                 printk("DISPLAY=%x\n", X86_ECX);
    214                 X86_EFLAGS &= ~FB_CF;
    215                 break;
    216         default:
    217                 printk("Unknown INT15 function %04x!\n", X86_AX);
    218                 X86_EFLAGS |= FB_CF;    /* set carry flag */
    219         }
    220 
    221         return 1;
    222 }
    223 
    224 static int int1a_handler(void)
    225 {
    226         int ret = 0;
    227         struct device *dev = 0;
    228 
    229         switch (X86_AX) {
    230         case PCI_BIOS_PRESENT:
    231                 X86_AH  = 0x00;         /* no config space/special cycle support */
    232                 X86_AL  = 0x01;         /* config mechanism 1 */
    233                 X86_EDX = 'P' | 'C' << 8 | 'I' << 16 | ' ' << 24;
    234                 X86_EBX = 0x0210;       /* Version 2.10 */
    235                 X86_ECX = 0xFF00;       /* FIXME: Max bus number */
    236                 X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
    237                 ret = 1;
    238                 break;
    239         case FIND_PCI_DEVICE:
    240                 /* FIXME: support SI != 0 */
    241                 dev = dev_find_device(X86_DX, X86_CX, dev);
    242                 if (dev != 0) {
    243                         X86_BH = dev->bus->secondary;
    244                         X86_BL = dev->path.pci.devfn;
    245                         X86_AH = SUCCESSFUL;
    246                         X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
    247                         ret = 1;
    248                 } else {
    249                         X86_AH = DEVICE_NOT_FOUND;
    250                         X86_EFLAGS |= FB_CF;    /* set carry flag */
    251                         ret = 0;
    252                 }
    253                 break;
    254         case FIND_PCI_CLASS_CODE:
    255                 /* FixME: support SI != 0 */
    256                 dev = dev_find_class(X86_ECX, dev);
    257                 if (dev != 0) {
    258                         X86_BH = dev->bus->secondary;
    259                         X86_BL = dev->path.pci.devfn;
    260                         X86_AH = SUCCESSFUL;
    261                         X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
    262                         ret = 1;
    263                 } else {
    264                         X86_AH = DEVICE_NOT_FOUND;
    265                         X86_EFLAGS |= FB_CF;    /* set carry flag */
    266                         ret = 0;
    267                 }
    268                 break;
    269         case READ_CONFIG_BYTE:
    270                 dev = dev_find_slot(X86_BH, X86_BL);
    271                 if (dev != 0) {
    272                         X86_CL = pci_read_config8(dev, X86_DI);
    273                         X86_AH = SUCCESSFUL;
    274                         X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
    275                         ret = 1;
    276                 } else {
    277                         X86_AH = DEVICE_NOT_FOUND;
    278                         X86_EFLAGS |= FB_CF;    /* set carry flag */   
    279                         ret = 0;
    280                 }
    281                 break;
    282         case READ_CONFIG_WORD:
    283                 dev = dev_find_slot(X86_BH, X86_BL);
    284                 if (dev != 0) {
    285                         X86_CX = pci_read_config16(dev, X86_DI);
    286                         X86_AH = SUCCESSFUL;
    287                         X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
    288                         ret = 1;
    289                 } else {
    290                         X86_AH = DEVICE_NOT_FOUND;
    291                         X86_EFLAGS |= FB_CF;    /* set carry flag */   
    292                         ret = 0;
    293                 }
    294                 break;
    295         case READ_CONFIG_DWORD:
    296                 dev = dev_find_slot(X86_BH, X86_BL);
    297                 if (dev != 0) {
    298                         X86_ECX = pci_read_config32(dev, X86_DI);
    299                         X86_AH = SUCCESSFUL;
    300                         X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
    301                         ret = 1;
    302                 } else {
    303                         X86_AH = DEVICE_NOT_FOUND;
    304                         X86_EFLAGS |= FB_CF;    /* set carry flag */   
    305                         ret = 0;
    306                 }
    307                 break;
    308         case WRITE_CONFIG_BYTE:
    309                 dev = dev_find_slot(X86_BH, X86_BL);
    310                 if (dev != 0) {
    311                         pci_write_config8(dev, X86_DI, X86_CL);
    312                         X86_AH = SUCCESSFUL;
    313                         X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
    314                         ret = 1;
    315                 } else {
    316                         X86_AH = DEVICE_NOT_FOUND;
    317                         X86_EFLAGS |= FB_CF;    /* set carry flag */   
    318                         ret = 0;
    319                 }
    320                 break;
    321         case WRITE_CONFIG_WORD:
    322                 dev = dev_find_slot(X86_BH, X86_BL);
    323                 if (dev != 0) {
    324                         pci_write_config16(dev, X86_DI, X86_CX);
    325                         X86_AH = SUCCESSFUL;
    326                         X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
    327                         ret = 1;
    328                 } else {
    329                         X86_AH = DEVICE_NOT_FOUND;
    330                         X86_EFLAGS |= FB_CF;    /* set carry flag */   
    331                         ret = 0;
    332                 }
    333                 break;
    334         case WRITE_CONFIG_DWORD:
    335                 dev = dev_find_slot(X86_BH, X86_BL);
    336                 if (dev != 0) {
    337                         pci_write_config16(dev, X86_DI, X86_ECX);
    338                         X86_AH = SUCCESSFUL;
    339                         X86_EFLAGS &= ~FB_CF;   /* clear carry flag */
    340                         ret = 1;
    341                 } else {
    342                         X86_AH = DEVICE_NOT_FOUND;
    343                         X86_EFLAGS |= FB_CF;    /* set carry flag */   
    344                         ret = 0;
    345                 }
    346                 break;
    347         default:
    348                 X86_AH = FUNC_NOT_SUPPORTED;
    349                 X86_EFLAGS |= FB_CF;
    350                 break;
    351         }
    352 
    353         return ret;
    354 }
    355 
    356 /* Interrupt multiplexer */
    357 
    358 /* Find base address of interrupt handler */
    359 static u32 getIntVect(int num)
    360 {
    361         return MEM_RW(num << 2) + (MEM_RW((num << 2) + 2) << 4);
    362 }
    363 
    364 static int run_bios_int(int num)
    365 {
    366         u32 eflags;
    367 
    368         eflags = X86_EFLAGS;
    369         push_word(eflags);
    370         push_word(X86_CS);
    371         push_word(X86_IP);
    372         X86_CS = MEM_RW((num << 2) + 2);
    373         X86_IP = MEM_RW(num << 2);
    374 
    375         return 1;
    376 }
    377 
    378 static void do_int(int num)
    379 {
    380         int ret = 0;
    381 
    382         printk("int%x (AX=%04x) vector at %x\n", num, X86_AX, getIntVect(num));
    383 
    384         switch (num) {
    385         case 0x10:
    386         case 0x42:
    387         case 0x6D:
    388                 if (getIntVect(num) == 0x0000) {
    389                         printk("uninitialized interrupt vector\n");
    390                         ret = 1;
    391                 }
    392                 if (getIntVect(num) == 0xFF065) {
    393                         //ret = int42_handler();
    394                         ret = 1;
    395                 }
    396                 break;
    397         case 0x15:
    398                 ret = int15_handler();
    399                 ret = 1;
    400                 break;
    401         case 0x16:
    402                 //ret = int16_handler();
    403                 ret = 0;
    404                 break;
    405         case 0x1A:
    406                 ret = int1a_handler();
    407                 ret = 1;
    408                 break;
    409         case 0xe6:
    410                 //ret = intE6_handler();
    411                 ret = 0;
    412                 break;
    413         default:
    414                 break;
    415         }
    416 
    417         if (!ret)
    418                 ret = run_bios_int(num);
    419 
    420 }
    421 
    422 /*
    423  * here we are really paranoid about faking a "real"
    424  * BIOS. Most of this information was pulled from
    425  * dosemu.
    426  */
    427 static void setup_system_bios(void)
    428 {
    429         int i;
    430 
    431         /* Set up Interrupt Vectors. The IVT starts at 0x0000:0x0000
    432          * Additionally, we put some stub code into the F segment for
    433          * those pesky little buggers that jmp to the hard coded addresses
    434          * instead of calling int XX. This stub code looks like this
    435          *
    436          *  CD XX       int 0xXX
    437          *  C3          ret
    438          *  F4          hlt
    439          */
    440 
    441         /* int 05 default location (Bound Exceeded) */
    442         MEM_WL(0x05 << 2, 0xf000ff54);
    443         MEM_WL(0xfff54, 0xf4c305cd);
    444         /* int 08 default location (Double Fault) */
    445         MEM_WL(0x08 << 2, 0xf000fea5);
    446         MEM_WL(0xffea5, 0xf4c308cd);
    447         /* int 0E default location (Page Fault) */
    448         MEM_WL(0x0e << 2, 0xf000ef57);
    449         MEM_WL(0xfef57, 0xf4c30ecd);
    450         /* int 10 default location */
    451         MEM_WL(0x10 << 2, 0xf000f065);
    452         MEM_WL(0xff065, 0xf4c310cd);
    453         /* int 11 default location (Get Equipment Configuration) */
    454         MEM_WL(0x11 << 2, 0xf000f84d);
    455         MEM_WL(0xff84d, 0xf4c311cd);
    456         /* int 12 default location (Get Conventional Memory Size) */
    457         MEM_WL(0x12 << 2, 0xf000f841);
    458         MEM_WL(0xff841, 0xf4c312cd);
    459         /* int 13 default location (Disk) */
    460         MEM_WL(0x13 << 2, 0xf000ec59);
    461         MEM_WL(0xfec59, 0xf4c313cd);
    462         /* int 14 default location (Disk) */
    463         MEM_WL(0x14 << 2, 0xf000e739);
    464         MEM_WL(0xfe739, 0xf4c314cd);
    465         /* int 15 default location (I/O System Extensions) */
    466         MEM_WL(0x15 << 2, 0xf000f859);
    467         MEM_WL(0xf859, 0xf4c315cd);
    468         /* int 16 default location */
    469         MEM_WL(0x16 << 2, 0xf000e82e);
    470         MEM_WL(0xfe82e, 0xf4c316cd);
    471         /* int 17 default location (Parallel Port) */
    472         MEM_WL(0x17 << 2, 0xf000efd2);
    473         MEM_WL(0xfefd2, 0xf4c317cd);
    474         /* int 1A default location (RTC, PCI and others) */
    475         MEM_WL(0x1a << 2, 0xf000fe6e);
    476         MEM_WL(0xffe6e, 0xf4c31acd);
    477         /* int 1E default location (FDD table) */
    478         MEM_WL(0x1e << 2, 0xf000efc7);
    479         MEM_WL(0xfefc7, 0xf4c31ecd);
    480         /* font tables default location (int 1F) */
    481         MEM_WL(0x1f << 2, 0xf000fa6e);
    482         MEM_WL(0xffa6e, 0xf4c31fcd);
    483         /* int 42 default location */
    484         MEM_WL(0x42 << 2, 0xf000f065);
    485         /* int 6D default location */
    486         MEM_WL(0x6D << 2, 0xf000f065);
    487 
    488         /* Clear EBDA */
    489         for (i=(INITIAL_EBDA_SEGMENT << 4);
    490                 i<(INITIAL_EBDA_SEGMENT << 4) + INITIAL_EBDA_SIZE; i++)
    491                 MEM_WB(i, 0);
    492         /* at offset 0h in EBDA is the size of the EBDA in KB */
    493         MEM_WW((INITIAL_EBDA_SEGMENT << 4) + 0x0, INITIAL_EBDA_SIZE / 1024);
    494 
    495         /* Clear BDA */
    496         for (i=0x400; i<0x500; i+=4)
    497                 MEM_WL(i, 0);
    498 
    499         /* Set up EBDA */
    500         MEM_WW(0x40e, INITIAL_EBDA_SEGMENT);
    501 
    502         /* Set RAM size to 16MB (fake) */
    503         MEM_WW(0x413, 16384);
    504 
    505         // TODO Set up more of BDA here
    506 
    507         /* setup original ROM BIOS Area (F000:xxxx) */
    508         const char *date = "06/23/99";
    509         for (i = 0; date[i]; i++)
    510                 MEM_WB(0xffff5 + i, date[i]);
    511         /* set up eisa ident string */
    512         const char *ident = "PCI_ISA";
    513         for (i = 0; ident[i]; i++)
    514                 MEM_WB(0xfffd9 + i, ident[i]);
    515 
    516         // write system model id for IBM-AT
    517         // according to "Ralf Browns Interrupt List" Int15 AH=C0 Table 515,
    518         // model FC is the original AT and also used in all DOSEMU Versions.
    519         MEM_WB(0xFFFFE, 0xfc);
    520 }
    521 
    522 #define BIOSEMU_MEM_BASE 0x00000000
    523 #define BIOSEMU_MEM_SIZE 0x00100000
    524 void run_bios(struct device * dev, unsigned long addr)
    525 {
    526         int i;
    527         u16 initialcs = (addr & 0xF0000) >> 4;
    528         u16 initialip = (addr + 3) & 0xFFFF;
    529         u16 devfn = (dev->bus->secondary << 8) | dev->path.pci.devfn;
    530         X86EMU_intrFuncs intFuncs[256];
    531 
    532         X86EMU_setMemBase(BIOSEMU_MEM_BASE, BIOSEMU_MEM_SIZE);
    533         X86EMU_setupPioFuncs(&biosemu_piofuncs);
    534         for (i = 0; i < 256; i++)
    535                 intFuncs[i] = do_int;
    536         X86EMU_setupIntrFuncs(intFuncs);
    537 
    538         setup_system_bios();
    539 
    540         /* cpu setup */
    541         X86_AX = devfn ? devfn : 0xff;
    542         X86_DX = 0x80;
    543         X86_EIP = initialip;
    544         X86_CS = initialcs;
    545 
    546         /* Initialize stack and data segment */
    547         X86_SS = STACK_SEGMENT;
    548         X86_SP = STACK_START_OFFSET;;
    549         X86_DS = DATA_SEGMENT;
    550 
    551         /* We need a sane way to return from bios
    552          * execution. A hlt instruction and a pointer
    553          * to it, both kept on the stack, will do.
    554          */
    555         push_word(0xf4f4);              /* hlt; hlt */
    556         push_word(X86_SS);
    557         push_word(X86_SP + 2);
    558 
    559 #ifdef DEBUG
    560         //X86EMU_trace_on();
    561 #endif
    562 
    563         printk("Executing Initialization Vector...\n");
    564         X86EMU_exec();
    565         printk("Option ROM Exit Status: %04x\n", X86_AX);
    566 
    567         /* Check whether the stack is "clean" i.e. containing the HLT
    568          * instruction we pushed before executing and pointing to the original
    569          * stack address... indicating that the initialization probably was
    570          * successful
    571          */
    572         if ((pop_word() == 0xf4f4) && (X86_SS == STACK_SEGMENT)
    573             && (X86_SP == STACK_START_OFFSET)) {
    574                 printk("Stack is clean, initialization successfull!\n");
    575         } else {
    576                 printk("Stack unclean, initialization probably NOT COMPLETE!!\n");
    577                 printk("SS:SP = %04x:%04x, expected: %04x:%04x\n",
    578                         X86_SS, X86_SP, STACK_SEGMENT, STACK_START_OFFSET);
    579         }
    580 }
  • trunk/util/x86emu/yabel/Makefile.inc

    r4609 r5135  
    66obj-y += mem.o
    77obj-y += pmm.o
     8obj-y += vbe.o
    89subdirs-y += compat
  • trunk/util/x86emu/yabel/biosemu.c

    r5131 r5135  
    8787        // in case we jump somewhere unexpected, or execution is finished,
    8888        // fill the biosmem with hlt instructions (0xf4)
    89         memset(biosmem, 0xf4, biosmem_size);
    90 
    91         M.mem_base = (long) biosmem;
    92         M.mem_size = biosmem_size;
     89        // But we have to be careful: If biosmem is 0x00000000 we're running
     90        // in the lower 1MB and we must not wipe memory like that.
     91        if (biosmem) {
     92                DEBUG_PRINTF("Clearing biosmem\n");
     93                memset(biosmem, 0xf4, biosmem_size);
     94        }
     95
     96        X86EMU_setMemBase(biosmem, biosmem_size);
     97
    9398        DEBUG_PRINTF("membase set: %08x, size: %08x\n", (int) M.mem_base,
    9499                     (int) M.mem_size);
  • trunk/util/x86emu/yabel/compat/functions.c

    r5040 r5135  
    1717#include <string.h>
    1818#include <device/device.h>
     19#include "../debug.h"
    1920
    20 #define VMEM_SIZE 1024 *1024 /* 1 MB */
     21#define VMEM_SIZE (1024 * 1024) /* 1 MB */
    2122
     23#if !defined(CONFIG_YABEL_DIRECTHW) || (!CONFIG_YABEL_DIRECTHW)
    2224#ifdef CONFIG_YABEL_VIRTMEM_LOCATION
    2325u8* vmem = (u8 *) CONFIG_YABEL_VIRTMEM_LOCATION;
     
    2527u8* vmem = (u8 *) (16*1024*1024); /* default to 16MB */
    2628#endif
     29#else
     30u8* vmem = NULL;
     31#endif
    2732
    2833u32 biosemu(u8 *biosmem, u32 biosmem_size, struct device *dev,
    2934            unsigned long rom_addr);
     35#if CONFIG_BOOTSPLASH
     36void vbe_set_graphics(void);
     37#endif
    3038
    3139void run_bios(struct device * dev, unsigned long addr)
    3240{
     41
    3342        biosemu(vmem, VMEM_SIZE, dev, addr);
    34         memcpy(0x0, vmem + 0x0, 0x400);
    35         memcpy(0x400, vmem + 0x400, 0x100);
    36         memcpy(0xc0000, vmem + 0xc0000, 0x10000);
     43
     44#if CONFIG_BOOTSPLASH
     45        vbe_set_graphics();
     46#endif
     47
     48        if (vmem != NULL) {
     49                printf("Copying legacy memory from 0x%08x to the lower 1MB\n", vmem);
     50                memcpy(0x00000, vmem + 0x00000, 0x400);         // IVT
     51                memcpy(0x00400, vmem + 0x00400, 0x100);         // BDA
     52                memcpy(0xc0000, vmem + 0xc0000, 0x10000);       // VGA OPROM
     53        }
    3754}
    3855
  • trunk/util/x86emu/yabel/io.c

    r5040 r5135  
    8181}
    8282#endif
     83
     84#if defined(CONFIG_YABEL_DIRECTHW) && (CONFIG_YABEL_DIRECTHW == 1)
     85u8 my_inb(X86EMU_pioAddr addr)
     86{
     87        u8 val;
     88
     89        val = inb(addr);
     90#ifdef CONFIG_DEBUG
     91        if ((debug_flags & DEBUG_IO) && (addr != 0x40))
     92            printk("inb(0x%04x) = 0x%02x\n", addr, val);
     93#endif
     94
     95        return val;
     96}
     97
     98u16 my_inw(X86EMU_pioAddr addr)
     99{
     100        u16 val;
     101
     102        val = inw(addr);
     103
     104#ifdef CONFIG_DEBUG
     105        if (debug_flags & DEBUG_IO)
     106                printk("inw(0x%04x) = 0x%04x\n", addr, val);
     107#endif
     108        return val;
     109}
     110
     111u32 my_inl(X86EMU_pioAddr addr)
     112{
     113        u32 val;
     114
     115        val = inl(addr);
     116
     117#ifdef CONFIG_DEBUG
     118        if (debug_flags & DEBUG_IO)
     119                printk("inl(0x%04x) = 0x%08x\n", addr, val);
     120#endif
     121        return val;
     122}
     123
     124void my_outb(X86EMU_pioAddr addr, u8 val)
     125{
     126#ifdef CONFIG_DEBUG
     127        if ((debug_flags & DEBUG_IO) && (addr != 0x43))
     128                printk("outb(0x%02x, 0x%04x)\n", val, addr);
     129#endif
     130        outb(val, addr);
     131}
     132
     133void my_outw(X86EMU_pioAddr addr, u16 val)
     134{
     135#ifdef CONFIG_DEBUG
     136        if (debug_flags & DEBUG_IO)
     137                printk("outw(0x%04x, 0x%04x)\n", val, addr);
     138#endif
     139        outw(val, addr);
     140}
     141
     142void my_outl(X86EMU_pioAddr addr, u32 val)
     143{
     144#ifdef CONFIG_DEBUG
     145        if (debug_flags & DEBUG_IO)
     146                printk("outl(0x%08x, 0x%04x)\n", val, addr);
     147#endif
     148        outl(val, addr);
     149}
     150
     151#else
     152
    83153u32 pci_cfg_read(X86EMU_pioAddr addr, u8 size);
    84154void pci_cfg_write(X86EMU_pioAddr addr, u32 val, u8 size);
     
    480550        return *((u8 *) (bios_device.io_buffer + 0x61));
    481551}
     552#endif
  • trunk/util/x86emu/yabel/mem.c

    r5131 r5135  
    169169void update_time(u32);
    170170
     171#if !defined(CONFIG_YABEL_DIRECTHW) || (!CONFIG_YABEL_DIRECTHW)
    171172// read byte from memory
    172173u8
     
    437438        }
    438439}
     440#else
     441u8
     442my_rdb(u32 addr)
     443{
     444        return rdb(addr);
     445}
     446
     447u16
     448my_rdw(u32 addr)
     449{
     450        return rdw(addr);
     451}
     452
     453u32
     454my_rdl(u32 addr)
     455{
     456        return rdl(addr);
     457}
     458
     459void
     460my_wrb(u32 addr, u8 val)
     461{
     462        wrb(addr, val);
     463}
     464
     465void
     466my_wrw(u32 addr, u16 val)
     467{
     468        wrw(addr, val);
     469}
     470
     471void
     472my_wrl(u32 addr, u32 val)
     473{
     474        wrl(addr, val);
     475}
     476#endif
    439477
    440478//update time in BIOS Data Area
  • trunk/util/x86emu/yabel/vbe.c

    r5040 r5135  
    1414#include <string.h>
    1515#include <types.h>
     16#if CONFIG_BOOTSPLASH
     17#include <boot/coreboot_tables.h>
     18#endif
     19
     20#include <arch/byteorder.h>
     21#define ntohl(x) be32_to_cpu(x)
    1622
    1723#include "debug.h"
     
    2733#include "device.h"
    2834
    29 static X86EMU_memFuncs my_mem_funcs = {
    30         my_rdb, my_rdw, my_rdl,
    31         my_wrb, my_wrw, my_wrl
    32 };
    33 
    34 static X86EMU_pioFuncs my_pio_funcs = {
    35         my_inb, my_inw, my_inl,
    36         my_outb, my_outw, my_outl
    37 };
     35#include <cbfs.h>
     36
     37#include <delay.h>
     38#include "../../src/lib/jpeg.h"
    3839
    3940// pointer to VBEInfoBuffer, set by vbe_prepare
    4041u8 *vbe_info_buffer = 0;
     42
    4143// virtual BIOS Memory
    4244u8 *biosmem;
     
    7476
    7577typedef struct {
     78        u16 mode_attributes; // 00
     79        u8 win_a_attributes; // 02
     80        u8 win_b_attributes; // 03
     81        u16 win_granularity; // 04
     82        u16 win_size;        // 06
     83        u16 win_a_segment;   // 08
     84        u16 win_b_segment;   // 0a
     85        u32 win_func_ptr;    // 0c
     86        u16 bytes_per_scanline; // 10
     87        u16 x_resolution;    // 12
     88        u16 y_resolution;    // 14
     89        u8 x_charsize;       // 16
     90        u8 y_charsize;       // 17
     91        u8 number_of_planes; // 18
     92        u8 bits_per_pixel;   // 19
     93        u8 number_of_banks;  // 20
     94        u8 memory_model;     // 21
     95        u8 bank_size;        // 22
     96        u8 number_of_image_pages; // 23
     97        u8 reserved_page;
     98        u8 red_mask_size;
     99        u8 red_mask_pos;
     100        u8 green_mask_size;
     101        u8 green_mask_pos;
     102        u8 blue_mask_size;
     103        u8 blue_mask_pos;
     104        u8 reserved_mask_size;
     105        u8 reserved_mask_pos;
     106        u8 direct_color_mode_info;
     107        u32 phys_base_ptr;
     108        u32 offscreen_mem_offset;
     109        u16 offscreen_mem_size;
     110        u8 reserved[206];
     111} __attribute__ ((__packed__)) vesa_mode_info_t;
     112
     113typedef struct {
    76114        u16 video_mode;
    77         u8 mode_info_block[256];
    78         u16 attributes;
    79         u16 linebytes;
    80         u16 x_resolution;
    81         u16 y_resolution;
    82         u8 x_charsize;
    83         u8 y_charsize;
    84         u8 bits_per_pixel;
    85         u8 memory_model;
    86         u32 framebuffer_address;
     115        union {
     116                vesa_mode_info_t vesa;
     117                u8 mode_info_block[256];
     118        };
     119        // our crap
     120        //u16 attributes;
     121        //u16 linebytes;
     122        //u16 x_resolution;
     123        //u16 y_resolution;
     124        //u8 x_charsize;
     125        //u8 y_charsize;
     126        //u8 bits_per_pixel;
     127        //u8 memory_model;
     128        //u32 framebuffer_address;
    87129} vbe_mode_info_t;
    88130
     
    95137
    96138static inline u8
    97 vbe_prepare()
     139vbe_prepare(void)
    98140{
    99141        vbe_info_buffer = biosmem + (VBE_SEGMENT << 4); // segment:offset off VBE Data Area
     
    210252                return M.x86.R_AH;
    211253        }
     254
    212255        //pointer to mode_info_block is in ES:DI
    213256        memcpy(mode_info->mode_info_block,
     
    217260        //printf("Mode Info Dump:");
    218261        //dump(mode_info_block, 64);
    219 
    220         // offset 0: 16bit le mode attributes
    221         mode_info->attributes = in16le(mode_info->mode_info_block);
    222 
    223         // offset 16: 16bit le bytes per scan line
    224         mode_info->linebytes = in16le(mode_info->mode_info_block + 16);
    225 
    226         // offset 18: 16bit le x resolution
    227         mode_info->x_resolution = in16le(mode_info->mode_info_block + 18);
    228 
    229         // offset 20: 16bit le y resolution
    230         mode_info->y_resolution = in16le(mode_info->mode_info_block + 20);
    231 
    232         // offset 22: 8bit le x charsize
    233         mode_info->x_charsize = *(mode_info->mode_info_block + 22);
    234 
    235         // offset 23: 8bit le y charsize
    236         mode_info->y_charsize = *(mode_info->mode_info_block + 23);
    237 
    238         // offset 25: 8bit le bits per pixel
    239         mode_info->bits_per_pixel = *(mode_info->mode_info_block + 25);
    240 
    241         // offset 27: 8bit le memory model
    242         mode_info->memory_model = *(mode_info->mode_info_block + 27);
    243 
    244         // offset 40: 32bit le containg offset of frame buffer memory ptr
    245         mode_info->framebuffer_address =
    246             in32le(mode_info->mode_info_block + 40);
    247262
    248263        return 0;
     
    483498
    484499u32
    485 vbe_get_info(u8 argc, char ** argv)
     500vbe_get_info(void)
    486501{
    487502        u8 rval;
    488         u32 i;
    489         if (argc < 4) {
    490                 printf
    491                     ("Usage %s <vmem_base> <device_path> <address of screen_info_t>\n",
    492                      argv[0]);
    493                 int i = 0;
    494                 for (i = 0; i < argc; i++) {
    495                         printf("argv[%d]: %s\n", i, argv[i]);
    496                 }
    497                 return -1;
    498         }
     503        int i;
     504
     505        // XXX FIXME these need to be filled with sane values
     506
    499507        // get a copy of input struct...
    500         screen_info_input_t input =
    501             *((screen_info_input_t *) strtoul((char *) argv[4], 0, 16));
     508        screen_info_input_t input;
    502509        // output is pointer to the address passed as argv[4]
    503         screen_info_t *output =
    504             (screen_info_t *) strtoul((char *) argv[4], 0, 16);
     510        screen_info_t local_output;
     511        screen_info_t *output = &local_output;
     512        // zero input
     513        memset(&input, 0, sizeof(screen_info_input_t));
    505514        // zero output
    506         memset(output, 0, sizeof(screen_info_t));
    507 
    508         // argv[1] is address of virtual BIOS mem...
    509         // argv[2] is the size
    510         biosmem = (u8 *) strtoul(argv[1], 0, 16);
    511         biosmem_size = strtoul(argv[2], 0, 16);;
    512         if (biosmem_size < MIN_REQUIRED_VMEM_SIZE) {
    513                 printf("Error: Not enough virtual memory: %x, required: %x!\n",
    514                        biosmem_size, MIN_REQUIRED_VMEM_SIZE);
    515                 return -1;
    516         }
    517         // argv[3] is the device to open and use...
    518         if (dev_init((char *) argv[3]) != 0) {
    519                 printf("Error initializing device!\n");
    520                 return -1;
    521         }
    522         //setup interrupt handler
    523         X86EMU_intrFuncs intrFuncs[256];
    524         for (i = 0; i < 256; i++)
    525                 intrFuncs[i] = handleInterrupt;
    526         X86EMU_setupIntrFuncs(intrFuncs);
    527         X86EMU_setupPioFuncs(&my_pio_funcs);
    528         X86EMU_setupMemFuncs(&my_mem_funcs);
    529 
    530         // set mem_base
    531         M.mem_base = (long) biosmem;
    532         M.mem_size = biosmem_size;
    533         DEBUG_PRINTF_VBE("membase set: %08x, size: %08x\n", (int) M.mem_base,
    534                          (int) M.mem_size);
     515        memset(&output, 0, sizeof(screen_info_t));
    535516
    536517        vbe_info_t info;
     
    614595                //DEBUG_PRINTF_VBE("%x: Mode: %04x\n", i, mode_info.video_mode);
    615596                vbe_get_mode_info(&mode_info);
    616 #if 0
     597
     598                // FIXME all these values are little endian!
     599
    617600                DEBUG_PRINTF_VBE("Video Mode 0x%04x available, %s\n",
    618601                                 mode_info.video_mode,
     
    647630                DEBUG_PRINTF_VBE("\tFramebuffer Offset: %08x\n",
    648631                                 mode_info.framebuffer_address);
    649 #endif
    650                 if ((mode_info.bits_per_pixel == input.color_depth)
    651                     && (mode_info.x_resolution <= input.max_screen_width)
    652                     && ((mode_info.attributes & 0x80) != 0)     // framebuffer mode
    653                     && ((mode_info.attributes & 0x10) != 0)     // graphics
    654                     && ((mode_info.attributes & 0x8) != 0)      // color
    655                     && (mode_info.x_resolution > best_mode_info.x_resolution))  // better than previous best_mode
     632
     633                if ((mode_info.vesa.bits_per_pixel == input.color_depth)
     634                    && (le16_to_cpu(mode_info.vesa.x_resolution) <= input.max_screen_width)
     635                    && ((le16_to_cpu(mode_info.vesa.mode_attributes) & 0x80) != 0)      // framebuffer mode
     636                    && ((le16_to_cpu(mode_info.vesa.mode_attributes) & 0x10) != 0)      // graphics
     637                    && ((le16_to_cpu(mode_info.vesa.mode_attributes) & 0x8) != 0)       // color
     638                    && (le16_to_cpu(mode_info.vesa.x_resolution) > le16_to_cpu(best_mode_info.vesa.x_resolution)))      // better than previous best_mode
    656639                {
    657640                        // yiiiihaah... we found a new best mode
     
    758741                vbe_set_color(0xFF, 0x00FFFFFF);
    759742
    760                 output->screen_width = best_mode_info.x_resolution;
    761                 output->screen_height = best_mode_info.y_resolution;
    762                 output->screen_linebytes = best_mode_info.linebytes;
    763                 output->color_depth = best_mode_info.bits_per_pixel;
     743                output->screen_width = le16_to_cpu(best_mode_info.vesa.x_resolution);
     744                output->screen_height = le16_to_cpu(best_mode_info.vesa.y_resolution);
     745                output->screen_linebytes = le16_to_cpu(best_mode_info.vesa.bytes_per_scanline);
     746                output->color_depth = best_mode_info.vesa.bits_per_pixel;
    764747                output->framebuffer_address =
    765                     best_mode_info.framebuffer_address;
     748                    le32_to_cpu(best_mode_info.vesa.phys_base_ptr);
    766749        } else {
    767750                printf("%s: No suitable video mode found!\n", __func__);
     
    771754        return 0;
    772755}
     756
     757#if CONFIG_BOOTSPLASH
     758vbe_mode_info_t mode_info;
     759
     760void vbe_set_graphics(void)
     761{
     762        u8 rval;
     763        int i;
     764
     765        vbe_info_t info;
     766        rval = vbe_info(&info);
     767        if (rval != 0)
     768                return;
     769
     770        DEBUG_PRINTF_VBE("VbeSignature: %s\n", info.signature);
     771        DEBUG_PRINTF_VBE("VbeVersion: 0x%04x\n", info.version);
     772        DEBUG_PRINTF_VBE("OemString: %s\n", info.oem_string_ptr);
     773        DEBUG_PRINTF_VBE("Capabilities:\n");
     774        DEBUG_PRINTF_VBE("\tDAC: %s\n",
     775                         (info.capabilities & 0x1) ==
     776                         0 ? "fixed 6bit" : "switchable 6/8bit");
     777        DEBUG_PRINTF_VBE("\tVGA: %s\n",
     778                         (info.capabilities & 0x2) ==
     779                         0 ? "compatible" : "not compatible");
     780        DEBUG_PRINTF_VBE("\tRAMDAC: %s\n",
     781                         (info.capabilities & 0x4) ==
     782                         0 ? "normal" : "use blank bit in Function 09h");
     783
     784        mode_info.video_mode = (1 << 14) | CONFIG_FRAMEBUFFER_VESA_MODE;
     785        vbe_get_mode_info(&mode_info);
     786        unsigned char *framebuffer =
     787                (unsigned char *) le32_to_cpu(mode_info.vesa.phys_base_ptr);
     788        DEBUG_PRINTF_VBE("FRAMEBUFFER: 0x%08x\n", framebuffer);
     789        vbe_set_mode(&mode_info);
     790
     791        struct jpeg_decdata *decdata;
     792        decdata = malloc(sizeof(*decdata));
     793
     794        /* Switching Intel IGD to 1MB video memory will break this. Who
     795         * cares. */
     796        int imagesize = 1024*768*2;
     797       
     798        struct cbfs_file *file = cbfs_find("bootsplash.jpg");
     799        if (!file) {
     800                DEBUG_PRINTF_VBE("Could not find bootsplash.jpg\n");
     801                return;
     802        }
     803        unsigned char *jpeg = ((unsigned char *)file) + ntohl(file->offset);
     804        DEBUG_PRINTF_VBE("Splash at %08x ...\n", jpeg);
     805        dump(jpeg, 64);
     806
     807        int ret = 0;
     808        DEBUG_PRINTF_VBE("Decompressing boot splash screen...\n");
     809        ret = jpeg_decode(jpeg, framebuffer, 1024, 768, 16, decdata);
     810        DEBUG_PRINTF_VBE("returns %x\n", ret);
     811}
     812
     813void fill_lb_framebuffer(struct lb_framebuffer *framebuffer)
     814{
     815        framebuffer->physical_address = le32_to_cpu(mode_info.vesa.phys_base_ptr);
     816
     817        framebuffer->x_resolution = le16_to_cpu(mode_info.vesa.x_resolution);
     818        framebuffer->y_resolution = le16_to_cpu(mode_info.vesa.y_resolution);
     819        framebuffer->bytes_per_line = le16_to_cpu(mode_info.vesa.bytes_per_scanline);
     820        framebuffer->bits_per_pixel = mode_info.vesa.bits_per_pixel;
     821
     822        framebuffer->red_mask_pos = mode_info.vesa.red_mask_pos;
     823        framebuffer->red_mask_size = mode_info.vesa.red_mask_size;
     824
     825        framebuffer->green_mask_pos = mode_info.vesa.green_mask_pos;
     826        framebuffer->green_mask_size = mode_info.vesa.green_mask_size;
     827
     828        framebuffer->blue_mask_pos = mode_info.vesa.blue_mask_pos;
     829        framebuffer->blue_mask_size = mode_info.vesa.blue_mask_size;
     830
     831        framebuffer->reserved_mask_pos = mode_info.vesa.reserved_mask_pos;
     832        framebuffer->reserved_mask_size = mode_info.vesa.reserved_mask_size;
     833}
     834
     835void vbe_textmode_console(void)
     836{
     837        /* Wait, just a little bit more, pleeeease ;-) */
     838        delay(2);
     839
     840        M.x86.R_EAX = 0x0003;
     841        runInt10();
     842}
     843
     844#endif
Note: See TracChangeset for help on using the changeset viewer.