162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 262306a36Sopenharmony_ci#ifndef _ASM_X86_PLATFORM_H 362306a36Sopenharmony_ci#define _ASM_X86_PLATFORM_H 462306a36Sopenharmony_ci 562306a36Sopenharmony_ci#include <asm/bootparam.h> 662306a36Sopenharmony_ci 762306a36Sopenharmony_cistruct ghcb; 862306a36Sopenharmony_cistruct mpc_bus; 962306a36Sopenharmony_cistruct mpc_cpu; 1062306a36Sopenharmony_cistruct pt_regs; 1162306a36Sopenharmony_cistruct mpc_table; 1262306a36Sopenharmony_cistruct cpuinfo_x86; 1362306a36Sopenharmony_cistruct irq_domain; 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci/** 1662306a36Sopenharmony_ci * struct x86_init_mpparse - platform specific mpparse ops 1762306a36Sopenharmony_ci * @setup_ioapic_ids: platform specific ioapic id override 1862306a36Sopenharmony_ci * @find_smp_config: find the smp configuration 1962306a36Sopenharmony_ci * @get_smp_config: get the smp configuration 2062306a36Sopenharmony_ci */ 2162306a36Sopenharmony_cistruct x86_init_mpparse { 2262306a36Sopenharmony_ci void (*setup_ioapic_ids)(void); 2362306a36Sopenharmony_ci void (*find_smp_config)(void); 2462306a36Sopenharmony_ci void (*get_smp_config)(unsigned int early); 2562306a36Sopenharmony_ci}; 2662306a36Sopenharmony_ci 2762306a36Sopenharmony_ci/** 2862306a36Sopenharmony_ci * struct x86_init_resources - platform specific resource related ops 2962306a36Sopenharmony_ci * @probe_roms: probe BIOS roms 3062306a36Sopenharmony_ci * @reserve_resources: reserve the standard resources for the 3162306a36Sopenharmony_ci * platform 3262306a36Sopenharmony_ci * @memory_setup: platform specific memory setup 3362306a36Sopenharmony_ci * 3462306a36Sopenharmony_ci */ 3562306a36Sopenharmony_cistruct x86_init_resources { 3662306a36Sopenharmony_ci void (*probe_roms)(void); 3762306a36Sopenharmony_ci void (*reserve_resources)(void); 3862306a36Sopenharmony_ci char *(*memory_setup)(void); 3962306a36Sopenharmony_ci}; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci/** 4262306a36Sopenharmony_ci * struct x86_init_irqs - platform specific interrupt setup 4362306a36Sopenharmony_ci * @pre_vector_init: init code to run before interrupt vectors 4462306a36Sopenharmony_ci * are set up. 4562306a36Sopenharmony_ci * @intr_init: interrupt init code 4662306a36Sopenharmony_ci * @intr_mode_select: interrupt delivery mode selection 4762306a36Sopenharmony_ci * @intr_mode_init: interrupt delivery mode setup 4862306a36Sopenharmony_ci * @create_pci_msi_domain: Create the PCI/MSI interrupt domain 4962306a36Sopenharmony_ci */ 5062306a36Sopenharmony_cistruct x86_init_irqs { 5162306a36Sopenharmony_ci void (*pre_vector_init)(void); 5262306a36Sopenharmony_ci void (*intr_init)(void); 5362306a36Sopenharmony_ci void (*intr_mode_select)(void); 5462306a36Sopenharmony_ci void (*intr_mode_init)(void); 5562306a36Sopenharmony_ci struct irq_domain *(*create_pci_msi_domain)(void); 5662306a36Sopenharmony_ci}; 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci/** 5962306a36Sopenharmony_ci * struct x86_init_oem - oem platform specific customizing functions 6062306a36Sopenharmony_ci * @arch_setup: platform specific architecture setup 6162306a36Sopenharmony_ci * @banner: print a platform specific banner 6262306a36Sopenharmony_ci */ 6362306a36Sopenharmony_cistruct x86_init_oem { 6462306a36Sopenharmony_ci void (*arch_setup)(void); 6562306a36Sopenharmony_ci void (*banner)(void); 6662306a36Sopenharmony_ci}; 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci/** 6962306a36Sopenharmony_ci * struct x86_init_paging - platform specific paging functions 7062306a36Sopenharmony_ci * @pagetable_init: platform specific paging initialization call to setup 7162306a36Sopenharmony_ci * the kernel pagetables and prepare accessors functions. 7262306a36Sopenharmony_ci * Callback must call paging_init(). Called once after the 7362306a36Sopenharmony_ci * direct mapping for phys memory is available. 7462306a36Sopenharmony_ci */ 7562306a36Sopenharmony_cistruct x86_init_paging { 7662306a36Sopenharmony_ci void (*pagetable_init)(void); 7762306a36Sopenharmony_ci}; 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci/** 8062306a36Sopenharmony_ci * struct x86_init_timers - platform specific timer setup 8162306a36Sopenharmony_ci * @setup_perpcu_clockev: set up the per cpu clock event device for the 8262306a36Sopenharmony_ci * boot cpu 8362306a36Sopenharmony_ci * @timer_init: initialize the platform timer (default PIT/HPET) 8462306a36Sopenharmony_ci * @wallclock_init: init the wallclock device 8562306a36Sopenharmony_ci */ 8662306a36Sopenharmony_cistruct x86_init_timers { 8762306a36Sopenharmony_ci void (*setup_percpu_clockev)(void); 8862306a36Sopenharmony_ci void (*timer_init)(void); 8962306a36Sopenharmony_ci void (*wallclock_init)(void); 9062306a36Sopenharmony_ci}; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci/** 9362306a36Sopenharmony_ci * struct x86_init_iommu - platform specific iommu setup 9462306a36Sopenharmony_ci * @iommu_init: platform specific iommu setup 9562306a36Sopenharmony_ci */ 9662306a36Sopenharmony_cistruct x86_init_iommu { 9762306a36Sopenharmony_ci int (*iommu_init)(void); 9862306a36Sopenharmony_ci}; 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci/** 10162306a36Sopenharmony_ci * struct x86_init_pci - platform specific pci init functions 10262306a36Sopenharmony_ci * @arch_init: platform specific pci arch init call 10362306a36Sopenharmony_ci * @init: platform specific pci subsystem init 10462306a36Sopenharmony_ci * @init_irq: platform specific pci irq init 10562306a36Sopenharmony_ci * @fixup_irqs: platform specific pci irq fixup 10662306a36Sopenharmony_ci */ 10762306a36Sopenharmony_cistruct x86_init_pci { 10862306a36Sopenharmony_ci int (*arch_init)(void); 10962306a36Sopenharmony_ci int (*init)(void); 11062306a36Sopenharmony_ci void (*init_irq)(void); 11162306a36Sopenharmony_ci void (*fixup_irqs)(void); 11262306a36Sopenharmony_ci}; 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci/** 11562306a36Sopenharmony_ci * struct x86_hyper_init - x86 hypervisor init functions 11662306a36Sopenharmony_ci * @init_platform: platform setup 11762306a36Sopenharmony_ci * @guest_late_init: guest late init 11862306a36Sopenharmony_ci * @x2apic_available: X2APIC detection 11962306a36Sopenharmony_ci * @msi_ext_dest_id: MSI supports 15-bit APIC IDs 12062306a36Sopenharmony_ci * @init_mem_mapping: setup early mappings during init_mem_mapping() 12162306a36Sopenharmony_ci * @init_after_bootmem: guest init after boot allocator is finished 12262306a36Sopenharmony_ci */ 12362306a36Sopenharmony_cistruct x86_hyper_init { 12462306a36Sopenharmony_ci void (*init_platform)(void); 12562306a36Sopenharmony_ci void (*guest_late_init)(void); 12662306a36Sopenharmony_ci bool (*x2apic_available)(void); 12762306a36Sopenharmony_ci bool (*msi_ext_dest_id)(void); 12862306a36Sopenharmony_ci void (*init_mem_mapping)(void); 12962306a36Sopenharmony_ci void (*init_after_bootmem)(void); 13062306a36Sopenharmony_ci}; 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci/** 13362306a36Sopenharmony_ci * struct x86_init_acpi - x86 ACPI init functions 13462306a36Sopenharmony_ci * @set_root_poitner: set RSDP address 13562306a36Sopenharmony_ci * @get_root_pointer: get RSDP address 13662306a36Sopenharmony_ci * @reduced_hw_early_init: hardware reduced platform early init 13762306a36Sopenharmony_ci */ 13862306a36Sopenharmony_cistruct x86_init_acpi { 13962306a36Sopenharmony_ci void (*set_root_pointer)(u64 addr); 14062306a36Sopenharmony_ci u64 (*get_root_pointer)(void); 14162306a36Sopenharmony_ci void (*reduced_hw_early_init)(void); 14262306a36Sopenharmony_ci}; 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci/** 14562306a36Sopenharmony_ci * struct x86_guest - Functions used by misc guest incarnations like SEV, TDX, etc. 14662306a36Sopenharmony_ci * 14762306a36Sopenharmony_ci * @enc_status_change_prepare Notify HV before the encryption status of a range is changed 14862306a36Sopenharmony_ci * @enc_status_change_finish Notify HV after the encryption status of a range is changed 14962306a36Sopenharmony_ci * @enc_tlb_flush_required Returns true if a TLB flush is needed before changing page encryption status 15062306a36Sopenharmony_ci * @enc_cache_flush_required Returns true if a cache flush is needed before changing page encryption status 15162306a36Sopenharmony_ci */ 15262306a36Sopenharmony_cistruct x86_guest { 15362306a36Sopenharmony_ci bool (*enc_status_change_prepare)(unsigned long vaddr, int npages, bool enc); 15462306a36Sopenharmony_ci bool (*enc_status_change_finish)(unsigned long vaddr, int npages, bool enc); 15562306a36Sopenharmony_ci bool (*enc_tlb_flush_required)(bool enc); 15662306a36Sopenharmony_ci bool (*enc_cache_flush_required)(void); 15762306a36Sopenharmony_ci}; 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci/** 16062306a36Sopenharmony_ci * struct x86_init_ops - functions for platform specific setup 16162306a36Sopenharmony_ci * 16262306a36Sopenharmony_ci */ 16362306a36Sopenharmony_cistruct x86_init_ops { 16462306a36Sopenharmony_ci struct x86_init_resources resources; 16562306a36Sopenharmony_ci struct x86_init_mpparse mpparse; 16662306a36Sopenharmony_ci struct x86_init_irqs irqs; 16762306a36Sopenharmony_ci struct x86_init_oem oem; 16862306a36Sopenharmony_ci struct x86_init_paging paging; 16962306a36Sopenharmony_ci struct x86_init_timers timers; 17062306a36Sopenharmony_ci struct x86_init_iommu iommu; 17162306a36Sopenharmony_ci struct x86_init_pci pci; 17262306a36Sopenharmony_ci struct x86_hyper_init hyper; 17362306a36Sopenharmony_ci struct x86_init_acpi acpi; 17462306a36Sopenharmony_ci}; 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_ci/** 17762306a36Sopenharmony_ci * struct x86_cpuinit_ops - platform specific cpu hotplug setups 17862306a36Sopenharmony_ci * @setup_percpu_clockev: set up the per cpu clock event device 17962306a36Sopenharmony_ci * @early_percpu_clock_init: early init of the per cpu clock event device 18062306a36Sopenharmony_ci * @fixup_cpu_id: fixup function for cpuinfo_x86::phys_proc_id 18162306a36Sopenharmony_ci * @parallel_bringup: Parallel bringup control 18262306a36Sopenharmony_ci */ 18362306a36Sopenharmony_cistruct x86_cpuinit_ops { 18462306a36Sopenharmony_ci void (*setup_percpu_clockev)(void); 18562306a36Sopenharmony_ci void (*early_percpu_clock_init)(void); 18662306a36Sopenharmony_ci void (*fixup_cpu_id)(struct cpuinfo_x86 *c, int node); 18762306a36Sopenharmony_ci bool parallel_bringup; 18862306a36Sopenharmony_ci}; 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_cistruct timespec64; 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci/** 19362306a36Sopenharmony_ci * struct x86_legacy_devices - legacy x86 devices 19462306a36Sopenharmony_ci * 19562306a36Sopenharmony_ci * @pnpbios: this platform can have a PNPBIOS. If this is disabled the platform 19662306a36Sopenharmony_ci * is known to never have a PNPBIOS. 19762306a36Sopenharmony_ci * 19862306a36Sopenharmony_ci * These are devices known to require LPC or ISA bus. The definition of legacy 19962306a36Sopenharmony_ci * devices adheres to the ACPI 5.2.9.3 IA-PC Boot Architecture flag 20062306a36Sopenharmony_ci * ACPI_FADT_LEGACY_DEVICES. These devices consist of user visible devices on 20162306a36Sopenharmony_ci * the LPC or ISA bus. User visible devices are devices that have end-user 20262306a36Sopenharmony_ci * accessible connectors (for example, LPT parallel port). Legacy devices on 20362306a36Sopenharmony_ci * the LPC bus consist for example of serial and parallel ports, PS/2 keyboard 20462306a36Sopenharmony_ci * / mouse, and the floppy disk controller. A system that lacks all known 20562306a36Sopenharmony_ci * legacy devices can assume all devices can be detected exclusively via 20662306a36Sopenharmony_ci * standard device enumeration mechanisms including the ACPI namespace. 20762306a36Sopenharmony_ci * 20862306a36Sopenharmony_ci * A system which has does not have ACPI_FADT_LEGACY_DEVICES enabled must not 20962306a36Sopenharmony_ci * have any of the legacy devices enumerated below present. 21062306a36Sopenharmony_ci */ 21162306a36Sopenharmony_cistruct x86_legacy_devices { 21262306a36Sopenharmony_ci int pnpbios; 21362306a36Sopenharmony_ci}; 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci/** 21662306a36Sopenharmony_ci * enum x86_legacy_i8042_state - i8042 keyboard controller state 21762306a36Sopenharmony_ci * @X86_LEGACY_I8042_PLATFORM_ABSENT: the controller is always absent on 21862306a36Sopenharmony_ci * given platform/subarch. 21962306a36Sopenharmony_ci * @X86_LEGACY_I8042_FIRMWARE_ABSENT: firmware reports that the controller 22062306a36Sopenharmony_ci * is absent. 22162306a36Sopenharmony_ci * @X86_LEGACY_i8042_EXPECTED_PRESENT: the controller is likely to be 22262306a36Sopenharmony_ci * present, the i8042 driver should probe for controller existence. 22362306a36Sopenharmony_ci */ 22462306a36Sopenharmony_cienum x86_legacy_i8042_state { 22562306a36Sopenharmony_ci X86_LEGACY_I8042_PLATFORM_ABSENT, 22662306a36Sopenharmony_ci X86_LEGACY_I8042_FIRMWARE_ABSENT, 22762306a36Sopenharmony_ci X86_LEGACY_I8042_EXPECTED_PRESENT, 22862306a36Sopenharmony_ci}; 22962306a36Sopenharmony_ci 23062306a36Sopenharmony_ci/** 23162306a36Sopenharmony_ci * struct x86_legacy_features - legacy x86 features 23262306a36Sopenharmony_ci * 23362306a36Sopenharmony_ci * @i8042: indicated if we expect the device to have i8042 controller 23462306a36Sopenharmony_ci * present. 23562306a36Sopenharmony_ci * @rtc: this device has a CMOS real-time clock present 23662306a36Sopenharmony_ci * @reserve_bios_regions: boot code will search for the EBDA address and the 23762306a36Sopenharmony_ci * start of the 640k - 1M BIOS region. If false, the platform must 23862306a36Sopenharmony_ci * ensure that its memory map correctly reserves sub-1MB regions as needed. 23962306a36Sopenharmony_ci * @devices: legacy x86 devices, refer to struct x86_legacy_devices 24062306a36Sopenharmony_ci * documentation for further details. 24162306a36Sopenharmony_ci */ 24262306a36Sopenharmony_cistruct x86_legacy_features { 24362306a36Sopenharmony_ci enum x86_legacy_i8042_state i8042; 24462306a36Sopenharmony_ci int rtc; 24562306a36Sopenharmony_ci int warm_reset; 24662306a36Sopenharmony_ci int no_vga; 24762306a36Sopenharmony_ci int reserve_bios_regions; 24862306a36Sopenharmony_ci struct x86_legacy_devices devices; 24962306a36Sopenharmony_ci}; 25062306a36Sopenharmony_ci 25162306a36Sopenharmony_ci/** 25262306a36Sopenharmony_ci * struct x86_hyper_runtime - x86 hypervisor specific runtime callbacks 25362306a36Sopenharmony_ci * 25462306a36Sopenharmony_ci * @pin_vcpu: pin current vcpu to specified physical 25562306a36Sopenharmony_ci * cpu (run rarely) 25662306a36Sopenharmony_ci * @sev_es_hcall_prepare: Load additional hypervisor-specific 25762306a36Sopenharmony_ci * state into the GHCB when doing a VMMCALL under 25862306a36Sopenharmony_ci * SEV-ES. Called from the #VC exception handler. 25962306a36Sopenharmony_ci * @sev_es_hcall_finish: Copies state from the GHCB back into the 26062306a36Sopenharmony_ci * processor (or pt_regs). Also runs checks on the 26162306a36Sopenharmony_ci * state returned from the hypervisor after a 26262306a36Sopenharmony_ci * VMMCALL under SEV-ES. Needs to return 'false' 26362306a36Sopenharmony_ci * if the checks fail. Called from the #VC 26462306a36Sopenharmony_ci * exception handler. 26562306a36Sopenharmony_ci * @is_private_mmio: For CoCo VMs, must map MMIO address as private. 26662306a36Sopenharmony_ci * Used when device is emulated by a paravisor 26762306a36Sopenharmony_ci * layer in the VM context. 26862306a36Sopenharmony_ci */ 26962306a36Sopenharmony_cistruct x86_hyper_runtime { 27062306a36Sopenharmony_ci void (*pin_vcpu)(int cpu); 27162306a36Sopenharmony_ci void (*sev_es_hcall_prepare)(struct ghcb *ghcb, struct pt_regs *regs); 27262306a36Sopenharmony_ci bool (*sev_es_hcall_finish)(struct ghcb *ghcb, struct pt_regs *regs); 27362306a36Sopenharmony_ci bool (*is_private_mmio)(u64 addr); 27462306a36Sopenharmony_ci}; 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci/** 27762306a36Sopenharmony_ci * struct x86_platform_ops - platform specific runtime functions 27862306a36Sopenharmony_ci * @calibrate_cpu: calibrate CPU 27962306a36Sopenharmony_ci * @calibrate_tsc: calibrate TSC, if different from CPU 28062306a36Sopenharmony_ci * @get_wallclock: get time from HW clock like RTC etc. 28162306a36Sopenharmony_ci * @set_wallclock: set time back to HW clock 28262306a36Sopenharmony_ci * @is_untracked_pat_range exclude from PAT logic 28362306a36Sopenharmony_ci * @nmi_init enable NMI on cpus 28462306a36Sopenharmony_ci * @save_sched_clock_state: save state for sched_clock() on suspend 28562306a36Sopenharmony_ci * @restore_sched_clock_state: restore state for sched_clock() on resume 28662306a36Sopenharmony_ci * @apic_post_init: adjust apic if needed 28762306a36Sopenharmony_ci * @legacy: legacy features 28862306a36Sopenharmony_ci * @set_legacy_features: override legacy features. Use of this callback 28962306a36Sopenharmony_ci * is highly discouraged. You should only need 29062306a36Sopenharmony_ci * this if your hardware platform requires further 29162306a36Sopenharmony_ci * custom fine tuning far beyond what may be 29262306a36Sopenharmony_ci * possible in x86_early_init_platform_quirks() by 29362306a36Sopenharmony_ci * only using the current x86_hardware_subarch 29462306a36Sopenharmony_ci * semantics. 29562306a36Sopenharmony_ci * @realmode_reserve: reserve memory for realmode trampoline 29662306a36Sopenharmony_ci * @realmode_init: initialize realmode trampoline 29762306a36Sopenharmony_ci * @hyper: x86 hypervisor specific runtime callbacks 29862306a36Sopenharmony_ci */ 29962306a36Sopenharmony_cistruct x86_platform_ops { 30062306a36Sopenharmony_ci unsigned long (*calibrate_cpu)(void); 30162306a36Sopenharmony_ci unsigned long (*calibrate_tsc)(void); 30262306a36Sopenharmony_ci void (*get_wallclock)(struct timespec64 *ts); 30362306a36Sopenharmony_ci int (*set_wallclock)(const struct timespec64 *ts); 30462306a36Sopenharmony_ci void (*iommu_shutdown)(void); 30562306a36Sopenharmony_ci bool (*is_untracked_pat_range)(u64 start, u64 end); 30662306a36Sopenharmony_ci void (*nmi_init)(void); 30762306a36Sopenharmony_ci unsigned char (*get_nmi_reason)(void); 30862306a36Sopenharmony_ci void (*save_sched_clock_state)(void); 30962306a36Sopenharmony_ci void (*restore_sched_clock_state)(void); 31062306a36Sopenharmony_ci void (*apic_post_init)(void); 31162306a36Sopenharmony_ci struct x86_legacy_features legacy; 31262306a36Sopenharmony_ci void (*set_legacy_features)(void); 31362306a36Sopenharmony_ci void (*realmode_reserve)(void); 31462306a36Sopenharmony_ci void (*realmode_init)(void); 31562306a36Sopenharmony_ci struct x86_hyper_runtime hyper; 31662306a36Sopenharmony_ci struct x86_guest guest; 31762306a36Sopenharmony_ci}; 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_cistruct x86_apic_ops { 32062306a36Sopenharmony_ci unsigned int (*io_apic_read) (unsigned int apic, unsigned int reg); 32162306a36Sopenharmony_ci void (*restore)(void); 32262306a36Sopenharmony_ci}; 32362306a36Sopenharmony_ci 32462306a36Sopenharmony_ciextern struct x86_init_ops x86_init; 32562306a36Sopenharmony_ciextern struct x86_cpuinit_ops x86_cpuinit; 32662306a36Sopenharmony_ciextern struct x86_platform_ops x86_platform; 32762306a36Sopenharmony_ciextern struct x86_msi_ops x86_msi; 32862306a36Sopenharmony_ciextern struct x86_apic_ops x86_apic_ops; 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ciextern void x86_early_init_platform_quirks(void); 33162306a36Sopenharmony_ciextern void x86_init_noop(void); 33262306a36Sopenharmony_ciextern void x86_init_uint_noop(unsigned int unused); 33362306a36Sopenharmony_ciextern bool bool_x86_init_noop(void); 33462306a36Sopenharmony_ciextern void x86_op_int_noop(int cpu); 33562306a36Sopenharmony_ciextern bool x86_pnpbios_disabled(void); 33662306a36Sopenharmony_ciextern int set_rtc_noop(const struct timespec64 *now); 33762306a36Sopenharmony_ciextern void get_rtc_noop(struct timespec64 *now); 33862306a36Sopenharmony_ci 33962306a36Sopenharmony_ci#endif 340