blob: 85f1a90c55cd817cf994ff5c0b1da6c227380a5d [file] [log] [blame]
Thomas Gleixner57844a82009-08-19 14:48:38 +02001/*
2 * Copyright (C) 2009 Thomas Gleixner <tglx@linutronix.de>
3 *
4 * For licencing details see kernel-base/COPYING
5 */
6#include <linux/init.h>
Thomas Gleixner9325a282009-08-29 17:51:26 +02007#include <linux/ioport.h>
Paul Gortmaker186f4362016-07-13 20:18:56 -04008#include <linux/export.h>
Stefano Stabellini294ee6f2010-10-06 16:12:28 -04009#include <linux/pci.h>
Thomas Gleixner57844a82009-08-19 14:48:38 +020010
Andy Shevchenko81b53e52018-02-20 20:05:05 +020011#include <asm/acpi.h>
Thomas Gleixner816c25e2009-08-19 14:36:27 +020012#include <asm/bios_ebda.h>
Thomas Gleixner6f30c1a2009-08-20 13:19:57 +020013#include <asm/paravirt.h>
Thomas Gleixnerb72d0db2009-08-29 16:24:51 +020014#include <asm/pci_x86.h>
Thomas Gleixnerfd6c6662009-08-20 10:41:58 +020015#include <asm/mpspec.h>
Thomas Gleixner8fee6972009-08-19 14:55:50 +020016#include <asm/setup.h>
Thomas Gleixner736deca2009-08-19 12:35:53 +020017#include <asm/apic.h>
Ingo Molnar66441bd2017-01-27 10:27:10 +010018#include <asm/e820/api.h>
Thomas Gleixner845b3942009-08-19 15:37:03 +020019#include <asm/time.h>
Thomas Gleixnerd9112f42009-08-20 09:41:38 +020020#include <asm/irq.h>
Konrad Rzeszutek Wilk4a8e2a32012-03-28 12:37:36 -040021#include <asm/io_apic.h>
Joerg Roedel71054d82012-09-26 12:44:37 +020022#include <asm/hpet.h>
Ingo Molnareb243d12019-11-20 15:33:57 +010023#include <asm/memtype.h>
Thomas Gleixner2d826402009-08-20 17:06:25 +020024#include <asm/tsc.h>
FUJITA Tomonori338bac52009-10-27 16:34:44 +090025#include <asm/iommu.h>
Jacob Pan064a59b2011-11-10 13:43:05 +000026#include <asm/mach_traps.h>
Thomas Gleixner57844a82009-08-19 14:48:38 +020027
Paul Gortmaker148f9bb2013-06-18 18:23:59 -040028void x86_init_noop(void) { }
Thomas Gleixnerf4848472009-08-20 12:05:01 +020029void __init x86_init_uint_noop(unsigned int unused) { }
Juergen Grossc46dacb2018-02-21 10:42:32 +010030static int __init iommu_init_noop(void) { return 0; }
31static void iommu_shutdown_noop(void) { }
Zhenzhong Duanbef6e0a2019-07-16 12:26:09 +080032bool __init bool_x86_init_noop(void) { return false; }
33void x86_op_int_noop(int cpu) { }
Rahul Tanwarc311ed62019-10-10 17:28:56 +080034static __init int set_rtc_noop(const struct timespec64 *now) { return -EINVAL; }
35static __init void get_rtc_noop(struct timespec64 *now) { }
36
37static __initconst const struct of_device_id of_cmos_match[] = {
38 { .compatible = "motorola,mc146818" },
39 {}
40};
41
42/*
43 * Allow devicetree configured systems to disable the RTC by setting the
44 * corresponding DT node's status property to disabled. Code is optimized
45 * out for CONFIG_OF=n builds.
46 */
47static __init void x86_wallclock_init(void)
48{
49 struct device_node *node = of_find_matching_node(NULL, of_cmos_match);
50
51 if (node && !of_device_is_available(node)) {
52 x86_platform.get_wallclock = get_rtc_noop;
53 x86_platform.set_wallclock = set_rtc_noop;
54 }
55}
Thomas Gleixner57844a82009-08-19 14:48:38 +020056
57/*
58 * The platform setup functions are preset with the default functions
59 * for standard PC hardware.
60 */
Thomas Gleixner54e26032009-09-16 08:42:26 +020061struct x86_init_ops x86_init __initdata = {
Thomas Gleixnerf7cf5a52009-08-19 14:43:56 +020062
63 .resources = {
Dan Williams5d94e812011-03-08 10:36:19 -080064 .probe_roms = probe_roms,
Thomas Gleixner8fee6972009-08-19 14:55:50 +020065 .reserve_resources = reserve_standard_io_resources,
Ingo Molnar103e2062017-01-28 09:58:49 +010066 .memory_setup = e820__memory_setup_default,
Thomas Gleixnerf7cf5a52009-08-19 14:43:56 +020067 },
Thomas Gleixnerf4848472009-08-20 12:05:01 +020068
69 .mpparse = {
70 .mpc_record = x86_init_uint_noop,
Thomas Gleixnerde934102009-08-20 09:27:29 +020071 .setup_ioapic_ids = x86_init_noop,
Thomas Gleixnerfd6c6662009-08-20 10:41:58 +020072 .mpc_apic_id = default_mpc_apic_id,
Thomas Gleixner72302142009-08-20 12:18:32 +020073 .smp_read_mpc_oem = default_smp_read_mpc_oem,
Thomas Gleixner90e1c692009-08-20 12:34:47 +020074 .mpc_oem_bus_info = default_mpc_oem_bus_info,
Thomas Gleixnerb3f1b612009-08-20 11:11:52 +020075 .find_smp_config = default_find_smp_config,
76 .get_smp_config = default_get_smp_config,
Thomas Gleixnerf4848472009-08-20 12:05:01 +020077 },
Thomas Gleixnerd9112f42009-08-20 09:41:38 +020078
79 .irqs = {
80 .pre_vector_init = init_ISA_irqs,
Thomas Gleixner66bcaf02009-08-20 09:59:09 +020081 .intr_init = native_init_IRQ,
Thomas Gleixner428cf902009-08-20 10:35:46 +020082 .trap_init = x86_init_noop,
Thomas Gleixner97992382020-01-23 12:54:53 +010083 .intr_mode_select = apic_intr_mode_select,
Dou Liyang34fba3e2017-09-13 17:12:52 +080084 .intr_mode_init = apic_intr_mode_init
Thomas Gleixnerd9112f42009-08-20 09:41:38 +020085 },
Thomas Gleixner42bbdb42009-08-20 13:04:10 +020086
87 .oem = {
88 .arch_setup = x86_init_noop,
Thomas Gleixner6f30c1a2009-08-20 13:19:57 +020089 .banner = default_banner,
Thomas Gleixner42bbdb42009-08-20 13:04:10 +020090 },
Thomas Gleixner030cb6c2009-08-20 14:30:02 +020091
92 .paging = {
Attilio Rao7737b212012-08-21 21:22:38 +010093 .pagetable_init = native_pagetable_init,
Thomas Gleixner030cb6c2009-08-20 14:30:02 +020094 },
Thomas Gleixner736deca2009-08-19 12:35:53 +020095
96 .timers = {
97 .setup_percpu_clockev = setup_boot_APIC_clock,
Thomas Gleixner845b3942009-08-19 15:37:03 +020098 .timer_init = hpet_time_init,
Rahul Tanwarc311ed62019-10-10 17:28:56 +080099 .wallclock_init = x86_wallclock_init,
Thomas Gleixner736deca2009-08-19 12:35:53 +0200100 },
FUJITA Tomonorid07c1be2009-11-10 19:46:12 +0900101
102 .iommu = {
103 .iommu_init = iommu_init_noop,
104 },
Thomas Gleixnerb72d0db2009-08-29 16:24:51 +0200105
106 .pci = {
107 .init = x86_default_pci_init,
Thomas Gleixnerab3b3792009-08-29 17:47:33 +0200108 .init_irq = x86_default_pci_init_irq,
Thomas Gleixner9325a282009-08-29 17:51:26 +0200109 .fixup_irqs = x86_default_pci_fixup_irqs,
Thomas Gleixnerb72d0db2009-08-29 16:24:51 +0200110 },
Juergen Grossf72e38e2017-11-09 14:27:35 +0100111
112 .hyper = {
113 .init_platform = x86_init_noop,
Juergen Grossf3614642017-11-09 14:27:38 +0100114 .guest_late_init = x86_init_noop,
Juergen Grossf72e38e2017-11-09 14:27:35 +0100115 .x2apic_available = bool_x86_init_noop,
116 .init_mem_mapping = x86_init_noop,
Pavel Tatashin6f84f8d2018-04-10 16:36:10 -0700117 .init_after_bootmem = x86_init_noop,
Juergen Grossf72e38e2017-11-09 14:27:35 +0100118 },
Juergen Gross038bac22018-02-19 11:09:05 +0100119
120 .acpi = {
Josh Boyer41fa1ee2019-08-19 17:17:51 -0700121 .set_root_pointer = x86_default_set_root_pointer,
Juergen Grosse7b66d12018-10-10 08:14:56 +0200122 .get_root_pointer = x86_default_get_root_pointer,
Andy Shevchenko81b53e52018-02-20 20:05:05 +0200123 .reduced_hw_early_init = acpi_generic_reduced_hw_init,
Juergen Gross038bac22018-02-19 11:09:05 +0100124 },
Thomas Gleixner736deca2009-08-19 12:35:53 +0200125};
126
Paul Gortmaker148f9bb2013-06-18 18:23:59 -0400127struct x86_cpuinit_ops x86_cpuinit = {
Igor Mammedovdf156f92012-02-07 15:52:44 +0100128 .early_percpu_clock_init = x86_init_noop,
Thomas Gleixner736deca2009-08-19 12:35:53 +0200129 .setup_percpu_clockev = setup_secondary_APIC_clock,
Thomas Gleixner57844a82009-08-19 14:48:38 +0200130};
Thomas Gleixner2d826402009-08-20 17:06:25 +0200131
Russ Anderson78c06172010-02-26 10:49:12 -0600132static void default_nmi_init(void) { };
133
Kees Cook404f6aa2016-08-08 16:29:06 -0700134struct x86_platform_ops x86_platform __ro_after_init = {
Pavel Tatashin8dbe4382018-07-19 16:55:45 -0400135 .calibrate_cpu = native_calibrate_cpu_early,
Thomas Gleixner2d826402009-08-20 17:06:25 +0200136 .calibrate_tsc = native_calibrate_tsc,
Feng Tang7bd867d2009-09-10 10:48:56 +0800137 .get_wallclock = mach_get_cmos_time,
138 .set_wallclock = mach_set_rtc_mmss,
FUJITA Tomonori338bac52009-10-27 16:34:44 +0900139 .iommu_shutdown = iommu_shutdown_noop,
H. Peter Anvineb41c8b2009-11-23 14:46:07 -0800140 .is_untracked_pat_range = is_ISA_range,
Feng Tangc516ac52010-07-05 23:03:18 +0800141 .nmi_init = default_nmi_init,
Jacob Pan064a59b2011-11-10 13:43:05 +0000142 .get_nmi_reason = default_get_nmi_reason,
Marcelo Tosattib74f05d62012-02-13 11:07:27 -0200143 .save_sched_clock_state = tsc_save_sched_clock_state,
144 .restore_sched_clock_state = tsc_restore_sched_clock_state,
Juergen Grossf72e38e2017-11-09 14:27:35 +0100145 .hyper.pin_vcpu = x86_op_int_noop,
Thomas Gleixner2d826402009-08-20 17:06:25 +0200146};
H. Peter Anvin72550b32010-07-07 16:57:46 -0700147
148EXPORT_SYMBOL_GPL(x86_platform);
Thomas Petazzoni4287d822013-08-09 22:27:06 +0200149
150#if defined(CONFIG_PCI_MSI)
Kees Cook404f6aa2016-08-08 16:29:06 -0700151struct x86_msi_ops x86_msi __ro_after_init = {
Joerg Roedel71054d82012-09-26 12:44:37 +0200152 .setup_msi_irqs = native_setup_msi_irqs,
153 .teardown_msi_irq = native_teardown_msi_irq,
154 .teardown_msi_irqs = default_teardown_msi_irqs,
155 .restore_msi_irqs = default_restore_msi_irqs,
Stefano Stabellini294ee6f2010-10-06 16:12:28 -0400156};
Konrad Rzeszutek Wilk4a8e2a32012-03-28 12:37:36 -0400157
Thomas Petazzoni4287d822013-08-09 22:27:06 +0200158/* MSI arch specific hooks */
159int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
160{
161 return x86_msi.setup_msi_irqs(dev, nvec, type);
162}
163
164void arch_teardown_msi_irqs(struct pci_dev *dev)
165{
166 x86_msi.teardown_msi_irqs(dev);
167}
168
169void arch_teardown_msi_irq(unsigned int irq)
170{
171 x86_msi.teardown_msi_irq(irq);
172}
173
DuanZhenzhongac8344c2013-12-04 13:09:16 +0800174void arch_restore_msi_irqs(struct pci_dev *dev)
Thomas Petazzoni4287d822013-08-09 22:27:06 +0200175{
DuanZhenzhongac8344c2013-12-04 13:09:16 +0800176 x86_msi.restore_msi_irqs(dev);
Thomas Petazzoni4287d822013-08-09 22:27:06 +0200177}
178#endif
179
Baoquan He51b146c2018-02-14 13:46:55 +0800180struct x86_apic_ops x86_apic_ops __ro_after_init = {
181 .io_apic_read = native_io_apic_read,
182 .restore = native_restore_boot_irq_mode,
Konrad Rzeszutek Wilk4a8e2a32012-03-28 12:37:36 -0400183};