|
@@ -213,6 +213,13 @@ enum iommu_init_state {
|
|
|
IOMMU_INIT_ERROR,
|
|
|
};
|
|
|
|
|
|
+/* Early ioapic and hpet maps from kernel command line */
|
|
|
+#define EARLY_MAP_SIZE 4
|
|
|
+static struct devid_map __initdata early_ioapic_map[EARLY_MAP_SIZE];
|
|
|
+static struct devid_map __initdata early_hpet_map[EARLY_MAP_SIZE];
|
|
|
+static int __initdata early_ioapic_map_size;
|
|
|
+static int __initdata early_hpet_map_size;
|
|
|
+
|
|
|
static enum iommu_init_state init_state = IOMMU_START_STATE;
|
|
|
|
|
|
static int amd_iommu_enable_interrupts(void);
|
|
@@ -738,6 +745,31 @@ static int __init add_special_device(u8 type, u8 id, u16 devid, bool cmd_line)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int __init add_early_maps(void)
|
|
|
+{
|
|
|
+ int i, ret;
|
|
|
+
|
|
|
+ for (i = 0; i < early_ioapic_map_size; ++i) {
|
|
|
+ ret = add_special_device(IVHD_SPECIAL_IOAPIC,
|
|
|
+ early_ioapic_map[i].id,
|
|
|
+ early_ioapic_map[i].devid,
|
|
|
+ early_ioapic_map[i].cmd_line);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i = 0; i < early_hpet_map_size; ++i) {
|
|
|
+ ret = add_special_device(IVHD_SPECIAL_HPET,
|
|
|
+ early_hpet_map[i].id,
|
|
|
+ early_hpet_map[i].devid,
|
|
|
+ early_hpet_map[i].cmd_line);
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Reads the device exclusion range from ACPI and initializes the IOMMU with
|
|
|
* it
|
|
@@ -774,6 +806,12 @@ static int __init init_iommu_from_acpi(struct amd_iommu *iommu,
|
|
|
u32 dev_i, ext_flags = 0;
|
|
|
bool alias = false;
|
|
|
struct ivhd_entry *e;
|
|
|
+ int ret;
|
|
|
+
|
|
|
+
|
|
|
+ ret = add_early_maps();
|
|
|
+ if (ret)
|
|
|
+ return ret;
|
|
|
|
|
|
/*
|
|
|
* First save the recommended feature enable bits from ACPI
|