0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

lspci Expantion Rom の [vurtual][disable]表示条件

Posted at

lspci.c
virtual 変数がセットされたとき、[virtualが表示される]

lspci.c
static void
show_rom(struct device *d, int reg)
{
...
  if (virtual)
    printf(" [virtual]");

virtual変数は初期値0

  int virtual = 0;

 

virtual変数が1に設定される条件は、以下を全て満たすこと

  1. regが0以上
  2. romのPCI_ROM_ADDRESS_MASKビットが有効
  3. flgのPCI_ROM_ADDRESS_MASKビットが無効
  4. ioflgのPCI_IORESOURCE_PCI_EA_BEIが無効
  if (reg >= 0 && (rom & PCI_ROM_ADDRESS_MASK) && !(flg & PCI_ROM_ADDRESS_MASK) && !(ioflg & PCI_IORESOURCE_PCI_EA_BEI))
    {
      flg = rom;
      virtual = 1;
    }

条件1. regが0以上

regはshow_romの第2引数
PCIヘッダタイプ0の場合は、PCI_ROM_ADDRESS 0x30

#define PCI_ROM_ADDRESS 0x30
lspci.c
static void
show_htype0(struct device *d)
{
  show_bases(d, 6, 0);
  show_rom(d, PCI_ROM_ADDRESS);
  show_caps(d, PCI_CAPABILITY_LIST);
}

条件2. romのPCI_ROM_ADDRESS_MASKビットが有効

romは第1引数d から辿れる rom_base_addr変数

 struct pci_dev *p = d->dev;
 pciaddr_t rom = p->rom_base_addr;

rom_base_addrはsysfs_get_resroucesで取得する

static void
sysfs_get_resources(struct pci_dev *d)
{
      else if (i == 6)
	{
	  d->rom_flags = flags;
	  flags &= PCI_ADDR_FLAG_MASK;
	  d->rom_base_addr = start | flags;
	  d->rom_size = size;
	  have_rom_base = 1;
	}

PCI_ROM_ADDRESS_MASKビットは下位11ビットをクリア
(romのPCI_ROM_ADDRESS_MASKビットが有効とは、12ビット以上が0ではないこと)

lib/header.h
#define PCI_ROM_ADDRESS_MASK (~(pciaddr_t)0x7ff)

条件3. flgのPCI_ROM_ADDRESS_MASKビットが無効(12ビット以上が0)

今回reg>0なので、flgはget_conf_longで取得する

  u32 flg = reg >= 0 ? get_conf_long(d, reg) : ioflg_to_pciflg(ioflg);
lspci.c
u32
get_conf_long(struct device *d, unsigned int pos)
{
  check_conf_range(d, pos, 4);
  return d->config[pos] |
    (d->config[pos+1] << 8) |
    (d->config[pos+2] << 16) |
    (d->config[pos+3] << 24);
}

config値は、PCIコンフィグレーション空間の値を保持している?

lspci.c
/*** PCI devices and access to their config space ***/
struct device {
  struct device *next;
  struct pci_dev *dev;
  /* Bus topology calculated by grow_tree() */
  struct device *bus_next;
  struct bus *parent_bus;
  struct bridge *bridge;
  /* Cache */
  int no_config_access;
  unsigned int config_cached, config_bufsize;
  byte *config;				/* Cached configuration space data */
  byte *present;			/* Maps which configuration bytes are present */
};

条件4. ioflgのPCI_IORESOURCE_PCI_EA_BEIが無効

#define PCI_IORESOURCE_PCI_EA_BEI (1<<5)

ioflgは、p->known_fieldsのPCI_FILL_IO_FLAGSビットが有効であれば、p->rom_flags値

  pciaddr_t ioflg = (p->known_fields & PCI_FILL_IO_FLAGS) ? p->rom_flags : 0;
pci.h
#define PCI_FILL_IO_FLAGS 0x1000

PCI_FILL_IO_FLAGSビットが有効だと[enhanced]が表示される

  if (ioflg & PCI_IORESOURCE_PCI_EA_BEI)
      printf(" [enhanced]");

[disabled] 表示条件

lspci.c
  if (!(flg & PCI_ROM_ADDRESS_ENABLE))
    printf(" [disabled]");
  else if (!virtual && !(cmd & PCI_COMMAND_MEMORY))
    printf(" [disabled by cmd]");
lib/header.h
#define  PCI_ROM_ADDRESS_ENABLE	0x01

virtual=1 がセットされるとき、flg = rom
virtual=0 のとき、PCI Expantion ROM addressレジスタ値

u32 flg = reg >= 0 ? get_conf_long(d, reg) : ioflg_to_pciflg(ioflg);

show_rom関数全体

lspci.c
static void
show_rom(struct device *d, int reg)
{
  struct pci_dev *p = d->dev;
  pciaddr_t rom = p->rom_base_addr;
  pciaddr_t len = (p->known_fields & PCI_FILL_SIZES) ? p->rom_size : 0;
  pciaddr_t ioflg = (p->known_fields & PCI_FILL_IO_FLAGS) ? p->rom_flags : 0;
  u32 flg = reg >= 0 ? get_conf_long(d, reg) : ioflg_to_pciflg(ioflg);
  word cmd = reg >= 0 ? get_conf_word(d, PCI_COMMAND) : PCI_COMMAND_MEMORY;
  int virtual = 0;

  if (!rom && !flg && !len)
    return;

  if (reg >= 0 && (rom & PCI_ROM_ADDRESS_MASK) && !(flg & PCI_ROM_ADDRESS_MASK) && !(ioflg & PCI_IORESOURCE_PCI_EA_BEI))
    {
      flg = rom;
      virtual = 1;
    }

  printf("\tExpansion ROM at ");
  if (rom & PCI_ROM_ADDRESS_MASK)
    printf(PCIADDR_T_FMT, rom & PCI_ROM_ADDRESS_MASK);
  else if (flg & PCI_ROM_ADDRESS_MASK)
    printf("<ignored>");
  else
    printf("<unassigned>");

  if (virtual)
    printf(" [virtual]");

  if (!(flg & PCI_ROM_ADDRESS_ENABLE))
    printf(" [disabled]");
  else if (!virtual && !(cmd & PCI_COMMAND_MEMORY))
    printf(" [disabled by cmd]");

  if (ioflg & PCI_IORESOURCE_PCI_EA_BEI)
      printf(" [enhanced]");

  show_size(len);
  putchar('\n');
}
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?