MCFG表的parse

acpi_init-> pci_mmcfg_late_init

void __init pci_mmcfg_late_init(void)
{
    int err = acpi_table_parse(ACPI_SIG_MCFG, pci_mcfg_parse);
    if (err)
        pr_err("Failed to parse MCFG (%d)\n", err);
}
pci_mmcfg_late_init 主要调用pci_mcfg_parse
static __init int pci_mcfg_parse(struct acpi_table_header *header)
{
    struct acpi_table_mcfg *mcfg;
    struct acpi_mcfg_allocation *mptr;
    struct mcfg_entry *e, *arr;
    int i, n;
    if (header->length < sizeof(struct acpi_table_mcfg))
        return -EINVAL;
    n = (header->length - sizeof(struct acpi_table_mcfg)) /
                    sizeof(struct acpi_mcfg_allocation);
    mcfg = (struct acpi_table_mcfg *)header;
    mptr = (struct acpi_mcfg_allocation *) &mcfg[1];
    arr = kcalloc(n, sizeof(*arr), GFP_KERNEL);
    if (!arr)
        return -ENOMEM;
    for (i = 0, e = arr; i < n; i++, mptr++, e++) {
        e->segment = mptr->pci_segment;
        e->addr =  mptr->address;
        e->bus_start = mptr->start_bus_number;
        e->bus_end = mptr->end_bus_number;
        list_add(&e->list, &pci_mcfg_list);
    }
    pr_info("MCFG table detected, %d entries\n", n);
    return 0;
}
可以看到pci_mcfg_parse 根据约定好的格式填充mcfg_entry的每一项,并将mcfg_entry放到pci_mcfg_list
列表中.
pci_acpi_setup_ecam_mapping->pci_mcfg_lookup 来查找mcfg的address
static struct pci_config_window *
pci_acpi_setup_ecam_mapping(struct acpi_pci_root *root)
{
    if (!root->mcfg_addr)
        root->mcfg_addr = pci_mcfg_lookup(seg, bus_res);
    
}
phys_addr_t pci_mcfg_lookup(u16 seg, struct resource *bus_res)
{
    struct mcfg_entry *e;
    list_for_each_entry(e, &pci_mcfg_list, list) {
        if (e->segment == seg && e->bus_start == bus_res->start &&
            e->bus_end >= bus_res->end)
            return e->addr;
    }
    return 0;
}
可见要segment/bus_start/bus_end 相等才算找到addr
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值