Coverage Report

Created: 2017-10-25 09:10

/root/src/xen/xen/arch/x86/x86_64/acpi_mmcfg.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 *  acpi_mmconfig.c - Architecture-Specific Low-Level ACPI Boot Support
3
 *
4
 *  Copyright (C) 2001, 2002 Paul Diefenbaugh <paul.s.diefenbaugh@intel.com>
5
 *  Copyright (C) 2001 Jun Nakajima <jun.nakajima@intel.com>
6
 *
7
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8
 *
9
 *  This program is free software; you can redistribute it and/or modify
10
 *  it under the terms of the GNU General Public License as published by
11
 *  the Free Software Foundation; either version 2 of the License, or
12
 *  (at your option) any later version.
13
 *
14
 *  This program is distributed in the hope that it will be useful,
15
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17
 *  GNU General Public License for more details.
18
 *
19
 *  You should have received a copy of the GNU General Public License
20
 *  along with this program; If not, see <http://www.gnu.org/licenses/>.
21
 *
22
 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23
 *
24
 * copied from Linux
25
 */
26
27
#include <xen/errno.h>
28
#include <xen/init.h>
29
#include <xen/acpi.h>
30
#include <xen/irq.h>
31
#include <xen/dmi.h>
32
#include <asm/fixmap.h>
33
#include <asm/page.h>
34
#include <asm/apic.h>
35
#include <asm/io_apic.h>
36
#include <asm/apic.h>
37
#include <asm/io.h>
38
#include <asm/mpspec.h>
39
#include <asm/processor.h>
40
#include <mach_apic.h>
41
#include <mach_mpparse.h>
42
43
#include "mmconfig.h"
44
45
/* The physical address of the MMCONFIG aperture.  Set from ACPI tables. */
46
struct acpi_mcfg_allocation *pci_mmcfg_config;
47
int pci_mmcfg_config_num;
48
49
static int __init acpi_mcfg_check_entry(struct acpi_table_mcfg *mcfg,
50
                                        struct acpi_mcfg_allocation *cfg)
51
1
{
52
1
    int year;
53
1
54
1
    if (cfg->address < 0xFFFFFFFF)
55
1
        return 0;
56
1
57
0
    if (!strncmp(mcfg->header.oem_id, "SGI", 3))
58
0
        return 0;
59
0
60
0
    if (mcfg->header.revision >= 1 &&
61
0
        dmi_get_date(DMI_BIOS_DATE, &year, NULL, NULL) &&
62
0
        year >= 2010)
63
0
            return 0;
64
0
65
0
    printk(KERN_ERR "MCFG region for %04x:%02x-%02x at %#"PRIx64
66
0
                    " (above 4GB) ignored\n",
67
0
           cfg->pci_segment, cfg->start_bus_number, cfg->end_bus_number,
68
0
           cfg->address);
69
0
    return -EINVAL;
70
0
}
71
72
int __init acpi_parse_mcfg(struct acpi_table_header *header)
73
1
{
74
1
    struct acpi_table_mcfg *mcfg;
75
1
    unsigned long i;
76
1
77
1
    if (!header)
78
0
        return -EINVAL;
79
1
80
1
    mcfg = (struct acpi_table_mcfg *)header;
81
1
82
1
    /* how many config structures do we have */
83
1
    pci_mmcfg_config_num = 0;
84
1
    i = header->length - sizeof(struct acpi_table_mcfg);
85
2
    while (i >= sizeof(struct acpi_mcfg_allocation)) {
86
1
        ++pci_mmcfg_config_num;
87
1
        i -= sizeof(struct acpi_mcfg_allocation);
88
1
    };
89
1
    if (pci_mmcfg_config_num == 0) {
90
0
        printk(KERN_ERR PREFIX "MMCONFIG has no entries\n");
91
0
        return -ENODEV;
92
0
    }
93
1
94
1
    pci_mmcfg_config = xmalloc_array(struct acpi_mcfg_allocation,
95
1
                                     pci_mmcfg_config_num);
96
1
    if (!pci_mmcfg_config) {
97
0
        printk(KERN_WARNING PREFIX
98
0
               "No memory for MCFG config tables\n");
99
0
        pci_mmcfg_config_num = 0;
100
0
        return -ENOMEM;
101
0
    }
102
1
103
1
    memcpy(pci_mmcfg_config, &mcfg[1],
104
1
           pci_mmcfg_config_num * sizeof(*pci_mmcfg_config));
105
1
106
2
    for (i = 0; i < pci_mmcfg_config_num; ++i) {
107
1
        if (acpi_mcfg_check_entry(mcfg, &pci_mmcfg_config[i])) {
108
0
            xfree(pci_mmcfg_config);
109
0
            pci_mmcfg_config_num = 0;
110
0
            return -ENODEV;
111
0
        }
112
1
        pci_add_segment(pci_mmcfg_config[i].pci_segment);
113
1
    }
114
1
115
1
    return 0;
116
1
}