ia64/xen-unstable

changeset 18828:e7c421510be9

hvmloader: Pass BDF to PCI option ROMs.

Signed-off-by: Shan Haitao <Haitao.shan@intel.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Mon Nov 24 13:57:48 2008 +0000 (2008-11-24)
parents 521d4d90f6e3
children 436816898c87 c2a018cdb45d
files tools/firmware/hvmloader/hvmloader.c tools/firmware/rombios/rombios.c
line diff
     1.1 --- a/tools/firmware/hvmloader/hvmloader.c	Mon Nov 24 13:43:28 2008 +0000
     1.2 +++ b/tools/firmware/hvmloader/hvmloader.c	Mon Nov 24 13:57:48 2008 +0000
     1.3 @@ -323,13 +323,14 @@ static void pci_setup(void)
     1.4  
     1.5  /*
     1.6   * Scan the list of Option ROMs at @roms for one which supports 
     1.7 - * PCI (@vendor_id, @device_id). If one is found, copy it to @dest and
     1.8 - * return its size rounded up to a multiple 2kB. This function will not
     1.9 - * copy ROMs beyond address 0xE0000.
    1.10 + * PCI (@vendor_id, @device_id) found at slot @devfn. If one is found,
    1.11 + * copy it to @dest and return its size rounded up to a multiple 2kB. This
    1.12 + * function will not copy ROMs beyond address 0xE0000.
    1.13   */
    1.14  #define round_option_rom(x) (((x) + 2047) & ~2047)
    1.15  static int scan_option_rom(
    1.16 -    uint16_t vendor_id, uint16_t device_id, void *roms, uint32_t dest)
    1.17 +    uint8_t devfn, uint16_t vendor_id, uint16_t device_id,
    1.18 +    void *roms, uint32_t dest)
    1.19  {
    1.20      struct option_rom_header *rom;
    1.21      struct option_rom_pnp_header *pnph;
    1.22 @@ -395,7 +396,7 @@ static int scan_option_rom(
    1.23          printf(" - Product name: %s\n",
    1.24                 (char *)rom + pnph->product_name_offset);
    1.25  
    1.26 -    if ( (dest + rom->rom_size * 512) > 0xe0000u )
    1.27 +    if ( (dest + rom->rom_size * 512 + 1) > 0xe0000u )
    1.28      {
    1.29          printf("Option ROM size %x exceeds available space\n",
    1.30                 rom->rom_size * 512);
    1.31 @@ -404,7 +405,8 @@ static int scan_option_rom(
    1.32  
    1.33      orom_ids[nr_roms++] = vendor_id | ((uint32_t)device_id << 16);
    1.34      memcpy((void *)dest, rom, rom->rom_size * 512);
    1.35 -    return round_option_rom(rom->rom_size * 512);
    1.36 +    *(uint8_t *)(dest + rom->rom_size * 512) = devfn;
    1.37 +    return round_option_rom(rom->rom_size * 512 + 1);
    1.38  }
    1.39  
    1.40  /*
    1.41 @@ -414,7 +416,7 @@ static int scan_option_rom(
    1.42   */
    1.43  static int scan_etherboot_nic(uint32_t copy_rom_dest)
    1.44  {
    1.45 -    uint32_t devfn;
    1.46 +    uint8_t devfn;
    1.47      uint16_t class, vendor_id, device_id;
    1.48  
    1.49      for ( devfn = 0; devfn < 128; devfn++ )
    1.50 @@ -428,7 +430,7 @@ static int scan_etherboot_nic(uint32_t c
    1.51               (device_id != 0xffff) &&
    1.52               (class == 0x0200) )
    1.53              return scan_option_rom(
    1.54 -                vendor_id, device_id, etherboot, copy_rom_dest);
    1.55 +                devfn, vendor_id, device_id, etherboot, copy_rom_dest);
    1.56      }
    1.57  
    1.58      return 0;
    1.59 @@ -440,9 +442,9 @@ static int scan_etherboot_nic(uint32_t c
    1.60   */
    1.61  static int pci_load_option_roms(uint32_t rom_base_addr)
    1.62  {
    1.63 -    uint32_t devfn, option_rom_addr, rom_phys_addr = rom_base_addr;
    1.64 +    uint32_t option_rom_addr, rom_phys_addr = rom_base_addr;
    1.65      uint16_t vendor_id, device_id;
    1.66 -    uint8_t class;
    1.67 +    uint8_t devfn, class;
    1.68  
    1.69      for ( devfn = 0; devfn < 128; devfn++ )
    1.70      {
    1.71 @@ -468,8 +470,8 @@ static int pci_load_option_roms(uint32_t
    1.72          pci_writel(devfn, PCI_ROM_ADDRESS, option_rom_addr | 0x1);
    1.73  
    1.74          rom_phys_addr += scan_option_rom(
    1.75 -            vendor_id, device_id, (void *)(option_rom_addr & ~2047),
    1.76 -            rom_phys_addr);
    1.77 +            devfn, vendor_id, device_id,
    1.78 +            (void *)(option_rom_addr & ~2047), rom_phys_addr);
    1.79  
    1.80          /* Restore the default original value of Expansion Bar */
    1.81          pci_writel(devfn, PCI_ROM_ADDRESS, option_rom_addr);
     2.1 --- a/tools/firmware/rombios/rombios.c	Mon Nov 24 13:43:28 2008 +0000
     2.2 +++ b/tools/firmware/rombios/rombios.c	Mon Nov 24 13:57:48 2008 +0000
     2.3 @@ -9677,20 +9677,35 @@ block_count_rounded:
     2.4    pop ds
     2.5    pop ax
     2.6  #endif
     2.7 -  xor  bx, bx   ;; Restore DS back to 0000:
     2.8 -  mov  ds, bx
     2.9    push ax       ;; Save AX
    2.10    push di       ;; Save DI
    2.11    ;; Push addr of ROM entry point
    2.12    push cx       ;; Push seg
    2.13    push #0x0003  ;; Push offset
    2.14  
    2.15 +  ;; Get the BDF into ax before invoking the option ROM
    2.16 +  mov  bl, [2]
    2.17 +  mov  al, bl
    2.18 +  shr  al, #7
    2.19 +  cmp  al, #1
    2.20 +  jne  fetch_bdf
    2.21 +  mov  ax, ds ;; Increment the DS since rom size larger than an segment
    2.22 +  add  ax, #0x1000
    2.23 +  mov  ds, ax
    2.24 +fetch_bdf:
    2.25 +  shl  bx, #9
    2.26 +  xor  ax, ax
    2.27 +  mov  al, [bx]
    2.28 +
    2.29    ;; Point ES:DI at "$PnP", which tells the ROM that we are a PnP BIOS.  
    2.30    ;; That should stop it grabbing INT 19h; we will use its BEV instead.
    2.31 -  mov  ax, #0xf000
    2.32 -  mov  es, ax
    2.33 +  mov  bx, #0xf000
    2.34 +  mov  es, bx
    2.35    lea  di, pnp_string 
    2.36  
    2.37 +  xor  bx, bx   ;; Restore DS back to 0000:
    2.38 +  mov  ds, bx
    2.39 +
    2.40    mov  bp, sp   ;; Call ROM init routine using seg:off on stack
    2.41    db   0xff     ;; call_far ss:[bp+0]
    2.42    db   0x5e