/* SPDX-License-Identifier: GPL-2.0 */ #ifndef _ASM_X86_RESCTRL_INTERNAL_H #define _ASM_X86_RESCTRL_INTERNAL_H #include #define L3_QOS_CDP_ENABLE 0x01ULL #define L2_QOS_CDP_ENABLE 0x01ULL #define MBM_CNTR_WIDTH_BASE 24 #define MBA_IS_LINEAR 0x4 #define MBM_CNTR_WIDTH_OFFSET_AMD 20 #define RMID_VAL_ERROR BIT_ULL(63) #define RMID_VAL_UNAVAIL BIT_ULL(62) /* * With the above fields in use 62 bits remain in MSR_IA32_QM_CTR for * data to be returned. The counter width is discovered from the hardware * as an offset from MBM_CNTR_WIDTH_BASE. */ #define MBM_CNTR_WIDTH_OFFSET_MAX (62 - MBM_CNTR_WIDTH_BASE) /** * struct arch_mbm_state - values used to compute resctrl_arch_rmid_read()s * return value. * @chunks: Total data moved (multiply by rdt_group.mon_scale to get bytes) * @prev_msr: Value of IA32_QM_CTR last time it was read for the RMID used to * find this struct. */ struct arch_mbm_state { u64 chunks; u64 prev_msr; }; /** * struct rdt_hw_ctrl_domain - Arch private attributes of a set of CPUs that share * a resource for a control function * @d_resctrl: Properties exposed to the resctrl file system * @ctrl_val: array of cache or mem ctrl values (indexed by CLOSID) * * Members of this structure are accessed via helpers that provide abstraction. */ struct rdt_hw_ctrl_domain { struct rdt_ctrl_domain d_resctrl; u32 *ctrl_val; }; /** * struct rdt_hw_mon_domain - Arch private attributes of a set of CPUs that share * a resource for a monitor function * @d_resctrl: Properties exposed to the resctrl file system * @arch_mbm_total: arch private state for MBM total bandwidth * @arch_mbm_local: arch private state for MBM local bandwidth * * Members of this structure are accessed via helpers that provide abstraction. */ struct rdt_hw_mon_domain { struct rdt_mon_domain d_resctrl; struct arch_mbm_state *arch_mbm_total; struct arch_mbm_state *arch_mbm_local; }; static inline struct rdt_hw_ctrl_domain *resctrl_to_arch_ctrl_dom(struct rdt_ctrl_domain *r) { return container_of(r, struct rdt_hw_ctrl_domain, d_resctrl); } static inline struct rdt_hw_mon_domain *resctrl_to_arch_mon_dom(struct rdt_mon_domain *r) { return container_of(r, struct rdt_hw_mon_domain, d_resctrl); } /** * struct msr_param - set a range of MSRs from a domain * @res: The resource to use * @dom: The domain to update * @low: Beginning index from base MSR * @high: End index */ struct msr_param { struct rdt_resource *res; struct rdt_ctrl_domain *dom; u32 low; u32 high; }; /** * struct rdt_hw_resource - arch private attributes of a resctrl resource * @r_resctrl: Attributes of the resource used directly by resctrl. * @num_closid: Maximum number of closid this hardware can support, * regardless of CDP. This is exposed via * resctrl_arch_get_num_closid() to avoid confusion * with struct resctrl_schema's property of the same name, * which has been corrected for features like CDP. * @msr_base: Base MSR address for CBMs * @msr_update: Function pointer to update QOS MSRs * @mon_scale: cqm counter * mon_scale = occupancy in bytes * @mbm_width: Monitor width, to detect and correct for overflow. * @cdp_enabled: CDP state of this resource * * Members of this structure are either private to the architecture * e.g. mbm_width, or accessed via helpers that provide abstraction. e.g. * msr_update and msr_base. */ struct rdt_hw_resource { struct rdt_resource r_resctrl; u32 num_closid; unsigned int msr_base; void (*msr_update)(struct msr_param *m); unsigned int mon_scale; unsigned int mbm_width; bool cdp_enabled; }; static inline struct rdt_hw_resource *resctrl_to_arch_res(struct rdt_resource *r) { return container_of(r, struct rdt_hw_resource, r_resctrl); } extern struct rdt_hw_resource rdt_resources_all[]; void arch_mon_domain_online(struct rdt_resource *r, struct rdt_mon_domain *d); /* CPUID.(EAX=10H, ECX=ResID=1).EAX */ union cpuid_0x10_1_eax { struct { unsigned int cbm_len:5; } split; unsigned int full; }; /* CPUID.(EAX=10H, ECX=ResID=3).EAX */ union cpuid_0x10_3_eax { struct { unsigned int max_delay:12; } split; unsigned int full; }; /* CPUID.(EAX=10H, ECX=ResID).ECX */ union cpuid_0x10_x_ecx { struct { unsigned int reserved:3; unsigned int noncont:1; } split; unsigned int full; }; /* CPUID.(EAX=10H, ECX=ResID).EDX */ union cpuid_0x10_x_edx { struct { unsigned int cos_max:16; } split; unsigned int full; }; void rdt_ctrl_update(void *arg); int rdt_get_mon_l3_config(struct rdt_resource *r); bool rdt_cpu_has(int flag); void __init intel_rdt_mbm_apply_quirk(void); void rdt_domain_reconfigure_cdp(struct rdt_resource *r); #endif /* _ASM_X86_RESCTRL_INTERNAL_H */