void vtd_check_pending_faults(struct per_cpu *cpu_data) { unsigned int fr_index; void *reg_base = dmar_reg_base; unsigned int n; void *fault_reg_addr, *rec_reg_addr; if (cpu_data->cpu_id != fault_reporting_cpu_id) return; for (n = 0; n < dmar_units; n++, reg_base += PAGE_SIZE) { if (mmio_read32_field(reg_base + VTD_FSTS_REG, VTD_FSTS_PPF_MASK)) { fr_index = mmio_read32_field(reg_base + VTD_FSTS_REG, VTD_FSTS_FRI_MASK); fault_reg_addr = vtd_get_fault_rec_reg_addr(reg_base); rec_reg_addr = fault_reg_addr + 16*fr_index; vtd_print_fault_record_reg_status(rec_reg_addr); /* Clear faults in record registers */ mmio_write64_field(rec_reg_addr + VTD_FRCD_HIGH_REG, VTD_FRCD_HIGH_F_MASK, VTD_FRCD_HIGH_F_CLEAR); } } }
static void *vtd_get_fault_rec_reg_addr(void *reg_base) { unsigned int regoffset; void *regaddr; regoffset = mmio_read32_field(reg_base + VTD_CAP_REG, VTD_CAP_FRO_MASK); regaddr = reg_base + 16*regoffset; return regaddr; }
static u32 read_xapic_id(void) { return mmio_read32_field(xapic_page + XAPIC_REG(APIC_REG_ID), XAPIC_DEST_MASK); }