/*
* Copyright (c) 2006, Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program; If not, see .
*
* Copyright (C) Ashok Raj
* Copyright (C) Shaohua Li
*/
#ifndef _DMAR_H_
#define _DMAR_H_
#include
#include
#include
/* This one is for interrupt remapping */
struct acpi_ioapic_unit {
struct list_head list;
int apic_id;
union {
u16 info;
struct {
u16 func: 3,
dev: 5,
bus: 8;
}bdf;
}ioapic;
};
struct acpi_hpet_unit {
struct list_head list;
unsigned int id;
union {
u16 bdf;
struct {
u16 func: 3,
dev: 5,
bus: 8;
};
};
};
struct dmar_scope {
DECLARE_BITMAP(buses, 256); /* buses owned by this unit */
u16 *devices; /* devices owned by this unit */
int devices_cnt;
};
struct acpi_drhd_unit {
struct dmar_scope scope;
struct list_head list;
u64 address; /* register base address of the unit */
u16 segment;
u8 include_all:1;
struct iommu *iommu;
struct list_head ioapic_list;
struct list_head hpet_list;
};
struct acpi_rmrr_unit {
struct dmar_scope scope;
struct list_head list;
u64 base_address;
u64 end_address;
u16 segment;
u8 allow_all:1;
};
struct acpi_atsr_unit {
struct dmar_scope scope;
struct list_head list;
u16 segment;
u8 all_ports:1;
};
struct acpi_rhsa_unit {
struct list_head list;
u64 address;
u32 proximity_domain;
};
#define for_each_drhd_unit(drhd) \
list_for_each_entry(drhd, &acpi_drhd_units, list)
#define for_each_rmrr_device(rmrr, bdf, idx) \
list_for_each_entry(rmrr, &acpi_rmrr_units, list) \
/* assume there never is a bdf == 0 */ \
for (idx = 0; (bdf = rmrr->scope.devices[idx]) && \
idx < rmrr->scope.devices_cnt; idx++)
struct acpi_drhd_unit *acpi_find_matched_drhd_unit(const struct pci_dev *);
struct acpi_atsr_unit *acpi_find_matched_atsr_unit(const struct pci_dev *);
#define DMAR_TYPE 1
#define RMRR_TYPE 2
#define ATSR_TYPE 3
#define DMAR_OPERATION_TIMEOUT MILLISECS(1000)
#define IOMMU_WAIT_OP(iommu, offset, op, cond, sts) \
do { \
s_time_t start_time = NOW(); \
while (1) { \
sts = op(iommu->reg, offset); \
if ( cond ) \
break; \
if ( NOW() > start_time + DMAR_OPERATION_TIMEOUT ) { \
if ( !kexecing ) \
panic("%s:%d:%s: DMAR hardware is malfunctional",\
__FILE__, __LINE__, __func__); \
else \
break; \
} \
cpu_relax(); \
} \
} while (0)
int vtd_hw_check(void);
void disable_pmr(struct iommu *iommu);
int is_igd_drhd(struct acpi_drhd_unit *drhd);
#endif /* _DMAR_H_ */