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