@ -46,8 +46,11 @@
* BIOS in u - boot .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
# include <common.h>
# include "biosemui.h"
# include <bios_emul.h>
# include <errno.h>
# include <malloc.h>
# include <vbe.h>
# include "biosemui.h"
/* Length of the BIOS image */
# define MAX_BIOSLEN (128 * 1024L)
@ -59,17 +62,54 @@ static u32 saveBaseAddress14;
static u32 saveBaseAddress18 ;
static u32 saveBaseAddress20 ;
static void atibios_set_vesa_mode ( RMREGS * regs , int vesa_mode ,
struct vbe_mode_info * mode_info )
{
debug ( " VBE: Setting VESA mode %#04x \n " , vesa_mode ) ;
/* request linear framebuffer mode */
vesa_mode | = ( 1 < < 14 ) ;
/* request clearing of framebuffer */
vesa_mode & = ~ ( 1 < < 15 ) ;
regs - > e . eax = VESA_SET_MODE ;
regs - > e . ebx = vesa_mode ;
BE_int86 ( 0x10 , regs , regs ) ;
int offset = 0x2000 ;
void * buffer = ( void * ) ( M . mem_base + offset ) ;
u16 buffer_seg = ( ( ( unsigned long ) offset ) > > 4 ) & 0xff00 ;
u16 buffer_adr = ( ( unsigned long ) offset ) & 0xffff ;
regs - > e . eax = VESA_GET_MODE_INFO ;
regs - > e . ebx = 0 ;
regs - > e . ecx = vesa_mode ;
regs - > e . edx = 0 ;
regs - > e . esi = buffer_seg ;
regs - > e . edi = buffer_adr ;
BE_int86 ( 0x10 , regs , regs ) ;
memcpy ( mode_info - > mode_info_block , buffer ,
sizeof ( struct vbe_mode_info ) ) ;
mode_info - > valid = true ;
vesa_mode | = ( 1 < < 14 ) ;
/* request clearing of framebuffer */
vesa_mode & = ~ ( 1 < < 15 ) ;
regs - > e . eax = VESA_SET_MODE ;
regs - > e . ebx = vesa_mode ;
BE_int86 ( 0x10 , regs , regs ) ;
}
/****************************************************************************
PARAMETERS :
pcidev - PCI device info for the video card on the bus to boot
VGAInfo - BIOS emulator VGA info structure
vga_i nfo - BIOS emulator VGA info structure
REMARKS :
This function executes the BIOS POST code on the controller . We assume that
at this stage the controller has its I / O and memory space enabled and
that all other controllers are in a disabled state .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void PCI_doBIOSPOST ( pci_dev_t pcidev , BE_VGAInfo * VGAInfo )
static void PCI_doBIOSPOST ( pci_dev_t pcidev , BE_VGAInfo * vga_info ,
int vesa_mode , struct vbe_mode_info * mode_info )
{
RMREGS regs ;
RMSREGS sregs ;
@ -84,13 +124,16 @@ static void PCI_doBIOSPOST(pci_dev_t pcidev, BE_VGAInfo * VGAInfo)
( ( int ) PCI_DEV ( pcidev ) < < 3 ) | ( int ) PCI_FUNC ( pcidev ) ;
/*Setup the X86 emulator for the VGA BIOS*/
BE_setVGA ( VGAI nfo) ;
BE_setVGA ( vga_i nfo) ;
/*Execute the BIOS POST code*/
BE_callRealMode ( 0xC000 , 0x0003 , & regs , & sregs ) ;
/*Cleanup and exit*/
BE_getVGA ( VGAInfo ) ;
BE_getVGA ( vga_info ) ;
if ( vesa_mode ! = - 1 )
atibios_set_vesa_mode ( & regs , vesa_mode , mode_info ) ;
}
/****************************************************************************
@ -244,60 +287,61 @@ REMARKS:
Loads and POST ' s the display controllers BIOS , directly from the BIOS
image we can extract over the PCI bus .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int PCI_postController ( pci_dev_t pcidev , BE_VGAInfo * VGAInfo )
static int PCI_postController ( pci_dev_t pcidev , uchar * bios_rom , int bios_len ,
BE_VGAInfo * vga_info , int vesa_mode ,
struct vbe_mode_info * mode_info )
{
u32 BIOSImageLen ;
uchar * mappedBIOS ;
uchar * copyOfBIOS ;
/*Allocate memory to store copy of BIOS from display controller*/
if ( ( mappedBIOS = PCI_mapBIOSImage ( pcidev ) ) = = NULL ) {
printf ( " videoboot: Video ROM failed to map! \n " ) ;
return false ;
}
u32 bios_image_len ;
uchar * mapped_bios ;
uchar * copy_of_bios ;
if ( bios_rom ) {
copy_of_bios = bios_rom ;
bios_image_len = bios_len ;
} else {
/*
* Allocate memory to store copy of BIOS from display
* controller
*/
mapped_bios = PCI_mapBIOSImage ( pcidev ) ;
if ( mapped_bios = = NULL ) {
printf ( " videoboot: Video ROM failed to map! \n " ) ;
return false ;
}
BIOSImageLen = mappedBIOS [ 2 ] * 512 ;
bios_image_len = mapped_bios [ 2 ] * 512 ;
if ( ( copyOfBIOS = malloc ( BIOSImageLen ) ) = = NULL ) {
printf ( " videoboot: Out of memory! \n " ) ;
return false ;
copy_of_bios = malloc ( bios_image_len ) ;
if ( copy_of_bios = = NULL ) {
printf ( " videoboot: Out of memory! \n " ) ;
return false ;
}
memcpy ( copy_of_bios , mapped_bios , bios_image_len ) ;
PCI_unmapBIOSImage ( pcidev , mapped_bios ) ;
}
memcpy ( copyOfBIOS , mappedBIOS , BIOSImageLen ) ;
PCI_unmapBIOSImage ( pcidev , mappedBIOS ) ;
/*Save information in VGAInfo structure*/
VGAInfo - > function = PCI_FUNC ( pcidev ) ;
VGAInfo - > device = PCI_DEV ( pcidev ) ;
VGAInfo - > bus = PCI_BUS ( pcidev ) ;
VGAInfo - > pcidev = pcidev ;
VGAInfo - > BIOSImage = copyOfBIOS ;
VGAInfo - > BIOSImageLen = BIOSImageLen ;
/*Save information in vga_info structure*/
vga_info - > function = PCI_FUNC ( pcidev ) ;
vga_info - > device = PCI_DEV ( pcidev ) ;
vga_info - > bus = PCI_BUS ( pcidev ) ;
vga_info - > pcidev = pcidev ;
vga_info - > BIOSImage = copy_of_bios ;
vga_info - > BIOSImageLen = bios_image_len ;
/*Now execute the BIOS POST for the device*/
if ( copyOfBIOS [ 0 ] ! = 0x55 | | copyOfBIOS [ 1 ] ! = 0xAA ) {
if ( copy_of_bios [ 0 ] ! = 0x55 | | copy_of_bios [ 1 ] ! = 0xAA ) {
printf ( " videoboot: Video ROM image is invalid! \n " ) ;
return false ;
}
PCI_doBIOSPOST ( pcidev , VGAI nfo) ;
PCI_doBIOSPOST ( pcidev , vga_info , vesa_mode , mode_i nfo) ;
/*Reset the size of the BIOS image to the final size*/
VGAI nfo- > BIOSImageLen = copyOfBIOS [ 2 ] * 512 ;
vga_i nfo- > BIOSImageLen = copy_of_bios [ 2 ] * 512 ;
return true ;
}
/****************************************************************************
PARAMETERS :
pcidev - PCI device info for the video card on the bus to boot
pVGAInfo - Place to return VGA info structure is requested
cleanUp - true to clean up on exit , false to leave emulator active
REMARKS :
Boots the PCI / AGP video card on the bus using the Video ROM BIOS image
and the X86 BIOS emulator module .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int BootVideoCardBIOS ( pci_dev_t pcidev , BE_VGAInfo * * pVGAInfo , int cleanUp )
int biosemu_setup ( pci_dev_t pcidev , BE_VGAInfo * * vga_infop )
{
BE_VGAInfo * VGAInfo ;
@ -307,28 +351,70 @@ int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo ** pVGAInfo, int cleanUp)
/*Initialise the x86 BIOS emulator*/
if ( ( VGAInfo = malloc ( sizeof ( * VGAInfo ) ) ) = = NULL ) {
printf ( " videoboot: Out of memory! \n " ) ;
return false ;
return - ENOMEM ;
}
memset ( VGAInfo , 0 , sizeof ( * VGAInfo ) ) ;
BE_init ( 0 , 65536 , VGAInfo , 0 ) ;
* vga_infop = VGAInfo ;
/*Post all the display controller BIOS'es*/
if ( ! PCI_postController ( pcidev , VGAInfo ) )
return false ;
return 0 ;
}
/*Cleanup and exit the emulator if requested. If the BIOS emulator
is needed after booting the card , we will not call BE_exit and
leave it enabled for further use ( ie : VESA driver etc ) .
void biosemu_set_interrupt_handler ( int intnum , int ( * int_func ) ( void ) )
{
X86EMU_setupIntrFunc ( intnum , ( X86EMU_intrFuncs ) int_func ) ;
}
int biosemu_run ( pci_dev_t pcidev , uchar * bios_rom , int bios_len ,
BE_VGAInfo * vga_info , int clean_up , int vesa_mode ,
struct vbe_mode_info * mode_info )
{
/*Post all the display controller BIOS'es*/
if ( ! PCI_postController ( pcidev , bios_rom , bios_len , vga_info ,
vesa_mode , mode_info ) )
return - EINVAL ;
/*
* Cleanup and exit the emulator if requested . If the BIOS emulator
* is needed after booting the card , we will not call BE_exit and
* leave it enabled for further use ( ie : VESA driver etc ) .
*/
if ( cleanUp ) {
if ( clean_u p ) {
BE_exit ( ) ;
if ( VGAInfo - > BIOSImage )
free ( VGAInfo - > BIOSImage ) ;
free ( VGAInfo ) ;
VGAInfo = NULL ;
if ( vga_i nfo- > BIOSImage )
free ( vga_i nfo- > BIOSImage ) ;
free ( vga_i nfo) ;
vga_i nfo = NULL ;
}
/*Return VGA info pointer if the caller requested it*/
return 0 ;
}
/****************************************************************************
PARAMETERS :
pcidev - PCI device info for the video card on the bus to boot
pVGAInfo - Place to return VGA info structure is requested
cleanUp - true to clean up on exit , false to leave emulator active
REMARKS :
Boots the PCI / AGP video card on the bus using the Video ROM BIOS image
and the X86 BIOS emulator module .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int BootVideoCardBIOS ( pci_dev_t pcidev , BE_VGAInfo * * pVGAInfo , int clean_up )
{
BE_VGAInfo * VGAInfo ;
int ret ;
ret = biosemu_setup ( pcidev , & VGAInfo ) ;
if ( ret )
return false ;
ret = biosemu_run ( pcidev , NULL , 0 , VGAInfo , clean_up , - 1 , NULL ) ;
if ( ret )
return false ;
/* Return VGA info pointer if the caller requested it*/
if ( pVGAInfo )
* pVGAInfo = VGAInfo ;
return true ;
}