xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

INT10.HOWTO (14516B)


      1 
      2                  INT10  X86 Real Mode executor
      3                  =============================
      4 
      5 		         PRELIMINARY
      6 
      7 INT10 is  a XFree86  module for soft-booting  and executing  real mode
      8 int10 BIOS calls. The BIOS call code is largely untested, yet.
      9 
     10 1. Usage
     11 ========
     12 
     13 To   use   the   int10   module   in  a   driver   the   header   file
     14 xfree86/os-support/int10/xf86int10.h must be included.
     15 
     16  a. Initialization
     17  -----------------
     18 
     19 The int10-executer gets initialized by calling:
     20 
     21    xf86Int10InfoPtr xf86InitInt10(int entityIndex);
     22 
     23 The  function  will soft-boot  any  non-primary  device  and return  a
     24 pointer  to a  xf86Int10InfoRec on  success. If  anything fails  or if
     25 int10 execution  is disabled by an  option in the  device section NULL
     26 will  be returned.   The driver  should store  this pointer  for later
     27 calls to other int10 module functions.
     28 
     29  b. Memory allocation
     30  --------------------
     31 
     32 To allocate memory in the real mode execution environment
     33     
     34    void * xf86Int10AllocPages(xf86Int10InfoPtr pInt,int num, int *off);
     35 
     36 can  be called.  It  allocates num  consecutive  pagesize chunks.   It
     37 returns the address of the allocated area. off is set to its offset in
     38 the real mode memory space.
     39 
     40   void xf86Int10FreePages(xf86Int10InfoPtr pInt, void *pbase, int num);
     41 
     42 Is used to free num pages beginning at pbase.
     43 
     44  c. Doing int10 BIOS calls
     45  -------------------------
     46 
     47 The BIOS call is executed by calling:
     48    
     49    void xf86ExecX86int10(xf86Int10InfoPtr pInt);
     50 
     51 The number  of the interrupt (normally  10) and the  initial values of
     52 the ax, bx, cx, dx, si, di  and es x86-CPU registers can be set in the
     53 xf86Int10InfoRec  passed to  the function.   On return  this structure
     54 contains the  exit values  of the registers  listed above and  the CPU
     55 flag register.
     56 
     57  d. De-initializing
     58  -----------------
     59 
     60 If no further int10 calls are required for a certain chipset
     61 the driver should call:
     62 
     63   void xf86FreeInt10(xf86Int10InfoPtr pInt);
     64 
     65 to free the memory allocated for real mode int10 calls.
     66 
     67 
     68 2. Porting issues
     69 =================
     70 
     71 The int10 real mode executor is  designed to run on top of various x86
     72 CPU emulators as well as in vm86  mode of a real x86 CPU. If used with
     73 a CPU  emulator the emulator and  CPU specific interfaces  can be held
     74 separate thus  requiring minimal efforts  to port the int10  module to
     75 new  platforms.   Currently  an  interface  to the  x86emu  real  mode
     76 emulator is  provided.  Since  details of setting  up and  running the
     77 vm86  mode   is  platform   dependent  both  the   platform  dependent
     78 environment and the emulation layer  have to be ported. Several helper
     79 functions are provided for that.
     80 
     81 A CPU emulator should meet certain requirements to be usable
     82 for the INT10 executor:
     83 
     84 1. It must trap  calls to intXX instructions and  pass execution to an
     85    external  function  which  is   allowed  to  modify  CPU  registers
     86    including  the instruction  pointer  (IP) before  returning to  the
     87    emulator for  continuing execution.  When the external  function is
     88    called the  IP must point to  the instruction past  the intXX call.
     89 
     90 2. The  emulator should  use externally  provided functions  to handle
     91    PIO.
     92 
     93 3.  The emulator  should be able to use  externally provided functions
     94  to access memory  from the real mode memory  environment.  Note, that
     95  the  vm86  mode  usually  requires  one hunk  of  consecutive  memory
     96  starting at address  0 in the process virtual  memory space.  Thus if
     97  this mode is to be used, the OS environment has to be able to provide
     98  that, ie. it must be able to remap the processes virtual memory space
     99  onto itself.  If the emulator is able to handle memory access through
    100  externally  provided functions the  real mode  process memory  can be
    101  located anywhere  in the processes  virtual memory. It does  not even
    102  have to be consecutive.
    103 
    104 4. The executor should terminate on encountering a 'hlt' instruction.
    105 
    106 
    107 Functions to implement:
    108 
    109 To simplify development  the code has been split  into a general setup
    110 part and an emulator specific one. A generic setup code is provided in
    111 generic.c.  It  should be  usable  with  any  emulator satisfying  the
    112 conditions mentioned  above. Therefore the following  section on int10
    113 setup may be skipped when porting int10 to new emulator.
    114 
    115 If the  vm86() is to be used  no memory access functions  can be used.
    116 Therefore the layout of the real mode memory image has to meet certain
    117 requirements. Therefore  when porting to  other platforms a  new setup
    118 code may  have to  be designed, too.  The following section  will give
    119 guidelines how  this may be  done. A sample implementation  using SysV
    120 IPC to  map the  appropriate real  mode memory image  to address  0 in
    121 virtual  address  space  just  prior  to execution  may  be  found  in
    122 xfree86/os-support/linux/int10/linux.c.
    123 
    124 On  non-PC like  platforms emulation  of certain  PC features  such as
    125 initialization of  BIOS int vectors, sys_BIOS constants  or PCI config
    126 method 1 can be turned on by defining _PC.
    127 
    128 I. Setup Code
    129 -------------
    130 
    131 This sets  up the real mode  memory image, calls the  emulator to POST
    132 the chipset if required and  maintains memory allocations in real mode
    133 address space.
    134 
    135 1. xf86Int10InfoPtr xf86InitInt10(int entityIndex);
    136 
    137 This  function should  first find  the screen  assigned to  the entity
    138 carrying entitiyIndex and then call
    139 
    140        Bool int10skip(ScrnInfoPtr pScrn)
    141 
    142 to find out if the user  has requested not to initialize int10.  If so
    143 xf86InitInt10()  should  return  NULL. Otherwise  an  xf86Int10InfoRec
    144 should be allocated.  This structure contains the following fields:
    145 
    146     a. int entityIndex   - index of the entity whose BIOS is to be 
    147                            executed.
    148     b. int scrnIndex     - index of the screen assigned the entity.
    149     c. pointer cpuRegs   - pointer to a emulator/vm86-mode private 
    150                            structure.  May hold cpu register values 
    151                            for the emulator.
    152     d. CARD16 BIOSseg    - Video BIOS segment address.
    153     e. pointer private   - pointer to a os specific data structure.
    154     f. struct _int10Mem* - pointer to a structure to hold the memory
    155                            access functions for use by an emulator.
    156     g. int num           - number of the int to be called.
    157     h. int ax..es,flags  - CPU register values to pass to int-call.
    158 
    159 The Init  function should initialize  a-f. To initialize  the emulator
    160 specific execute environment the function
    161 
    162      Bool xf86Int10ExecSetup(xf86Int10InfoPtr pInt)
    163 
    164 should be called. If this function returns FALSE any already allocated
    165 memory should be freed and xf86Int10Init(0 should exit returning NULL.
    166 
    167 If the  platform has  a PC  like system BIOS  it may  be copied  to or
    168 mapped into memory  locations SYS_BIOS to SYS_SIZE-1 of  the real mode
    169 memory environment of this process. Otherwise the helper function: 
    170 
    171 int setup_system_bios(CARD32 base_addr); 
    172 
    173 may be  called to set  up a rudimentary  system BIOS sufficient  to be
    174 used to  boot video BIOSes.   base_addr specifies the  virtual address
    175 corresponding to SYS_BIOS in the  real mode environment.  If a PC-like
    176 int vector and BIOS data area is available it should be copied to 0 to
    177 LOW_PAGE_SIZE of the entities real mode environment.  In this case the
    178 video interrupt  related entries should  be reset for  all non-primary
    179 cards by calling:
    180 
    181 void reset_int_vect(xf86Int10InfoPtr pInt); To initialize the
    182 
    183 correct video BIOS  entry points the BIOS must  be warm-booted.  If no
    184 PC-like int vector is available one can be set up by calling 
    185 
    186 void setup_int_vect(xf86Int10InfoPtr pInt); 
    187 
    188 In this  case the  video BIOS  has to be  warm-booted always.   If the
    189 video BIOS  for this entity has  been installed during boot  it may be
    190 mapped (or  copied) directly to the  correct address in  the real mode
    191 memory environment.  Otherwise
    192 
    193 int mapPciRom(xf86Int10InfoPtr pInt, unsigned char * address); 
    194 
    195 should  be called  to copy  the BIOS  image from  PCI  ROM.  'address'
    196 specifies the address this image should be copied to. Sufficient space
    197 to  hold an entire  BIOS image  should be  allocated prior  to calling
    198 mapPciRom(). This function  will return the size of  the BIOS image in
    199 bytes  if  it   was  able  to  successfully  copy   the  image  and  0
    200 otherwise. To create a well defined point to exit the softbooter
    201 
    202 void set_return_trap(xf86Int10Ptr pInt); 
    203 
    204 may be called.  It sets up a 'hlt' instruction  in the emulator memory
    205 just above the BIOS variable area. Before entering real mode execution
    206 this address will be pushed onto  the return stack.  If the BIOS needs
    207 to be  warm-booted this should be done  before leaving xf86InitInt10()
    208 by setting num in the xf86Int10InfoRec to 0xe6 and calling
    209 
    210 void xf86ExecX86int10(xf86Int10IfoPtr pInt); 
    211 
    212 The  implementation of this  function will  be discussed  below.  This
    213 function  should be  wrapped  by calls  to void  LockLegacyVGA(screen,
    214 legacyVGAPtr vga); and void UnlockLegacyVGA(screen, legacyVGAPtr vga);
    215 The struct  vga is  used to hold  the state  of the legacy  VGA access
    216 registers  if  a legacy  VGA  device  exists.  xf86InitInt10()  should
    217 return a pointer to the xf86Int10InfoRec allocated.
    218 
    219 2. Bool MapCurrentInt10(xf86Int10InfoPtr pInt);
    220 
    221 In case  a platform specific  mapping has to  be performed to  map the
    222 memory allocated for the real  mode memory environment into a specific
    223 location prior to executing the x86 real mode code a function
    224 
    225         Bool MapCurrentInt10(xf86Int10InfoPtr pInt);
    226 
    227 has to  be provided. It will  be called by a  helper function whenever
    228 the active entity changes. If the  vm86 mode is used it is most likely
    229 that the 1MB real mode memory space located somewhere in the processes
    230 virtual memory  will have to be  remapped to address 0  of the virtual
    231 memory space.
    232 
    233 3.   void xf86FreeInt10(xf86Int10InfoPtr pInt);
    234 
    235 To free all memory allocated for video BIOS calls of a specific entity
    236 the function
    237 
    238        void xf86FreeInt10(xf86Int10InfoPtr pInt);
    239 
    240 should  be  provided.  If  the  entity  to  be  freed  was  mapped  by
    241 MapCurrentInt10() this mapping needs to be undone also.
    242 
    243 4. 
    244    void * xf86Int10AllocPages(xf86Int10InfoPtr pInt,int num, int *off)
    245    void xf86Int10FreePages(xf86Int10InfoPtr pInt, void *pbase, int num)
    246 
    247 xf86Int10AllocPages()  should  allocate  'num'  consecutive  page-size
    248 chunks of memory. In real mode memory space this range needs to occupy
    249 consecutive addresses,  too. The function  must return the  address of
    250 this memory.  The offset in real  mode memory needs to  be returned in
    251 'off'. If  no block of 'num'  pages are available  the function should
    252 return NULL.
    253 
    254 xf86Int10FreePages() will  free the  'num' pages starting  at 'pbase'.
    255 'num'  is  equal  to  the  number  of  pages  allocated  by  a  single
    256 xf86Int10AllocatePages()  call. 'pbase'  is the  address of  the range
    257 previously returned by xf86Int10AllocatePages().
    258 
    259 II. Emulator specific functions
    260 -------------------------------
    261 
    262 1. Bool xf86Int10ExecSetup(xf86Int10InfoPtr pInt);
    263 
    264 This function will  be called from xf86InitInt10(). It  may be used to
    265 set  up   the  static  emulator   specific  part  of  the   real  mode
    266 environment. On success it should return TRUE.
    267 
    268 2. xf86ExecX86int10(xf86Int10InfoPtr pInt);
    269 
    270 This function  gets called  to execute  an int call.  It may  call the
    271 helper function:
    272 
    273        void setup_int(xf86Int10InfoPrt pInt);
    274 
    275 to copy the register values  to the emulator specific locations and to
    276 set up the non-static real mode execution environment.  On return from
    277 setup_int()   'Int10Current'   holds   a   pointer  to   the   current
    278 xf86Int10InfoRec.
    279 
    280 It should start execution by calling 
    281 
    282        Bool int_handler(xf86Int10InfoPtr pInt);
    283 
    284 and if this function returns TRUE it should call whatever necessary to
    285 continue execution until a  'hlt' instruction is encountered.  To copy
    286 the resulting register values back to the xf86Int10InfoRec structure
    287 
    288      void finish_int(xf86Int10InfoPtr pInt);
    289 
    290 should be called. 
    291 
    292 Helper  functions are  provided to  aid the  implementation of  a vm86
    293 call:
    294 
    295   Bool vm86_GP_fault(xf86Int10InfoPtr pInt);
    296 
    297 This  function  handles  instructions  which  cause  a  vm86  call  to
    298 trap.  PIO  access  is handled  by  the  in/out  calls as  defined  in
    299 compiler.h. Optionally the PIO  instructions can be logged by defining
    300 PRINT_PORT in xf86int10.h. This is meant for debugging purposes.
    301 
    302 Unknown  instructions  and   'hlt'  cause  vm86_GP_fault()  to  return
    303 FALSE. Otherwise TRUE is returned.
    304 
    305 Note: This  function is  currently based on  the Linux vm86  call.  It
    306 might have  to be modified  or even rewritten  for other OS.   So your
    307 mileage may vary.
    308 
    309 Functions to dump memory, code, xf86 CPU register values and stack are
    310 also provided.  Take a  look at  helper.c To view  a memory  range the
    311 function
    312 
    313     void dprint(unsigned long start, unsigned long size)
    314 
    315 is provided. The use should be self explanatory.
    316 
    317 Register  and memory  access functions  are provided  in helper_mem.c.
    318 The PIO register access functions  can trap access to PCI config space
    319 access register (config method 1) if _PC is not defined.
    320 
    321 A header  file 'defines.h' is required to  define OS/emulator specific
    322 ways  to access  memory and  xf86 CPU  registers: Defines  need  to be
    323 provided     for    memory     byte/work/long     read/write    access
    324 (MEM_RB(name,addr),MEM_RW(name,addr),MEM_RL(name,addr),
    325 MEM_WB(name,addr,val),MEM_WL(name,addr,val),MEM_WL(name,addr,val))   of
    326 the real mode memory environment. 'name' will contain a pointer to the
    327 current   xf86Int10InfoRec.  Currently   defines  are   available  for
    328 vm86-mode under  Linux and x86emu.  They may be activated  by defining
    329 _X86EMU or _VM86_LINUX respectively.
    330 
    331 Note: Emulators usually are not able to pass this pointer when calling
    332 memory  access functions.  In this  case a  global variable  should be
    333 defined  which can  hold this  pointer. This  variable can  be  set in
    334 MapCurrentInt10().  It also  must be  set in  xf86InitInt10()  if this
    335 function  calls the  memory  access functions  either  directly or  by
    336 calling  xf86ExecX86int10(pInt).   Defines   to  access  the  emulator
    337 specific   xf86   CPU    register   locations   are   also   required:
    338 X86_EAX,...,X86_EFLAGS  for  access  of  the full  32  bit  registers,
    339 X86_AX...X86_FLAGS   for  access   of   the  16   bit  registers   and
    340 XF86_AL,XF86_BL,XF86_CL,XF86_DL  to  access  the  lower  byte  of  the
    341 AX,BX,CX and DX register.
    342 
    343 
    344 $XFree86: xc/programs/Xserver/hw/xfree86/int10/INT10.HOWTO,v 1.2 2000/02/08 13:13:22 eich Exp $