144 lines
3.3 KiB
C
144 lines
3.3 KiB
C
/*
|
|
* Copyright (c) 2020 Intel Corporation
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
#ifndef ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_INTEL_VTD_H_
|
|
#define ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_INTEL_VTD_H_
|
|
|
|
#define VTD_INT_SHV BIT(3)
|
|
#define VTD_INT_FORMAT BIT(4)
|
|
|
|
/* We don't care about int_idx[15], since the size is fixed to 256,
|
|
* it's always 0
|
|
*/
|
|
#define VTD_MSI_MAP(int_idx, shv) \
|
|
((0x0FEE00000U) | (int_idx << 5) | shv | VTD_INT_FORMAT)
|
|
|
|
/* Interrupt Remapping Table Entry (IRTE) for Remapped Interrupts */
|
|
union vtd_irte {
|
|
struct irte_parts {
|
|
uint64_t low;
|
|
uint64_t high;
|
|
} parts;
|
|
|
|
struct irte_bits {
|
|
uint64_t present : 1;
|
|
uint64_t fpd : 1;
|
|
uint64_t dst_mode : 1;
|
|
uint64_t redirection_hint : 1;
|
|
uint64_t trigger_mode : 1;
|
|
uint64_t delivery_mode : 3;
|
|
uint64_t available : 4;
|
|
uint64_t _reserved_0 : 3;
|
|
uint64_t irte_mode : 1;
|
|
uint64_t vector : 8;
|
|
uint64_t _reserved_1 : 8;
|
|
uint64_t dst_id : 32;
|
|
uint64_t src_id : 16;
|
|
uint64_t src_id_qualifier : 2;
|
|
uint64_t src_validation_type : 2;
|
|
uint64_t _reserved : 44;
|
|
} bits __packed;
|
|
};
|
|
|
|
/* The table must be 4KB aligned, which is exactly 256 entries.
|
|
* And since we allow only 256 entries as a maximum: let's align to it.
|
|
*/
|
|
#define IRTE_NUM 256
|
|
#define IRTA_SIZE 7 /* size = 2^(X+1) where IRTA_SIZE is X 2^8 = 256 */
|
|
|
|
#define QI_NUM 256 /* Which is the minimal number we can set for the queue */
|
|
#define QI_SIZE 0 /* size = 2^(X+8) where QI_SIZE is X: 2^8 = 256 */
|
|
#define QI_WIDTH 128
|
|
|
|
struct qi_descriptor {
|
|
uint64_t low;
|
|
uint64_t high;
|
|
};
|
|
|
|
#define QI_TYPE_ICC 0x1UL
|
|
|
|
union qi_icc_descriptor {
|
|
struct qi_descriptor desc;
|
|
|
|
struct icc_bits {
|
|
uint64_t type : 4;
|
|
uint64_t granularity : 2;
|
|
uint64_t _reserved_0 : 3;
|
|
uint64_t zero : 3;
|
|
uint64_t _reserved_1 : 4;
|
|
uint64_t domain_id : 16;
|
|
uint64_t source_id : 16;
|
|
uint64_t function_mask : 2;
|
|
uint64_t _reserved_2 : 14;
|
|
uint64_t reserved;
|
|
} icc __packed;
|
|
};
|
|
|
|
#define QI_TYPE_IEC 0x4UL
|
|
|
|
union qi_iec_descriptor {
|
|
struct qi_descriptor desc;
|
|
|
|
struct iec_bits {
|
|
uint64_t type : 4;
|
|
uint64_t granularity : 1;
|
|
uint64_t _reserved_0 : 4;
|
|
uint64_t zero : 3;
|
|
uint64_t _reserved_1 : 15;
|
|
uint64_t index_mask : 5;
|
|
uint64_t interrupt_index: 16;
|
|
uint64_t _reserved_2 : 16;
|
|
uint64_t reserved;
|
|
} iec __packed;
|
|
};
|
|
|
|
#define QI_TYPE_WAIT 0x5UL
|
|
|
|
union qi_wait_descriptor {
|
|
struct qi_descriptor desc;
|
|
|
|
struct wait_bits {
|
|
uint64_t type : 4;
|
|
uint64_t interrupt_flag : 1;
|
|
uint64_t status_write : 1;
|
|
uint64_t fence_flag : 1;
|
|
uint64_t page_req_drain : 1;
|
|
uint64_t _reserved_0 : 1;
|
|
uint64_t zero : 3;
|
|
uint64_t _reserved_1 : 20;
|
|
uint64_t status_data : 32;
|
|
uint64_t reserved : 2;
|
|
uint64_t address : 62;
|
|
} wait __packed;
|
|
};
|
|
|
|
#define QI_WAIT_STATUS_INCOMPLETE 0x0UL
|
|
#define QI_WAIT_STATUS_COMPLETE 0x1UL
|
|
|
|
/* Arbitrary wait counter limit */
|
|
#define QI_WAIT_COUNT_LIMIT 100
|
|
|
|
struct vtd_ictl_data {
|
|
DEVICE_MMIO_RAM;
|
|
union vtd_irte irte[IRTE_NUM] __aligned(0x1000);
|
|
struct qi_descriptor qi[QI_NUM] __aligned(0x1000);
|
|
int irqs[IRTE_NUM];
|
|
int vectors[IRTE_NUM];
|
|
bool msi[IRTE_NUM];
|
|
int irte_num_used;
|
|
unsigned int fault_irq;
|
|
uintptr_t fault_record_reg;
|
|
uint16_t fault_record_num;
|
|
uint16_t qi_tail;
|
|
uint8_t fault_vector;
|
|
bool pwc;
|
|
};
|
|
|
|
struct vtd_ictl_cfg {
|
|
DEVICE_MMIO_ROM;
|
|
};
|
|
|
|
#endif /* ZEPHYR_DRIVERS_INTERRUPT_CONTROLLER_INTC_INTEL_VTD_H_ */
|