LCOV - code coverage report
Current view: top level - arch/x86/include/asm - apic.h (source / functions) Hit Total Coverage
Test: landlock.info Lines: 31 43 72.1 %
Date: 2021-04-22 12:43:58 Functions: 5 6 83.3 %

          Line data    Source code
       1             : /* SPDX-License-Identifier: GPL-2.0-only */
       2             : #ifndef _ASM_X86_APIC_H
       3             : #define _ASM_X86_APIC_H
       4             : 
       5             : #include <linux/cpumask.h>
       6             : 
       7             : #include <asm/alternative.h>
       8             : #include <asm/cpufeature.h>
       9             : #include <asm/apicdef.h>
      10             : #include <linux/atomic.h>
      11             : #include <asm/fixmap.h>
      12             : #include <asm/mpspec.h>
      13             : #include <asm/msr.h>
      14             : #include <asm/hardirq.h>
      15             : 
      16             : #define ARCH_APICTIMER_STOPS_ON_C3      1
      17             : 
      18             : /*
      19             :  * Debugging macros
      20             :  */
      21             : #define APIC_QUIET   0
      22             : #define APIC_VERBOSE 1
      23             : #define APIC_DEBUG   2
      24             : 
      25             : /* Macros for apic_extnmi which controls external NMI masking */
      26             : #define APIC_EXTNMI_BSP         0 /* Default */
      27             : #define APIC_EXTNMI_ALL         1
      28             : #define APIC_EXTNMI_NONE        2
      29             : 
      30             : /*
      31             :  * Define the default level of output to be very little
      32             :  * This can be turned up by using apic=verbose for more
      33             :  * information and apic=debug for _lots_ of information.
      34             :  * apic_verbosity is defined in apic.c
      35             :  */
      36             : #define apic_printk(v, s, a...) do {       \
      37             :                 if ((v) <= apic_verbosity) \
      38             :                         printk(s, ##a);    \
      39             :         } while (0)
      40             : 
      41             : 
      42             : #if defined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_X86_32)
      43             : extern void generic_apic_probe(void);
      44             : #else
      45           1 : static inline void generic_apic_probe(void)
      46             : {
      47           1 : }
      48             : #endif
      49             : 
      50             : #ifdef CONFIG_X86_LOCAL_APIC
      51             : 
      52             : extern int apic_verbosity;
      53             : extern int local_apic_timer_c2_ok;
      54             : 
      55             : extern int disable_apic;
      56             : extern unsigned int lapic_timer_period;
      57             : 
      58             : extern enum apic_intr_mode_id apic_intr_mode;
      59             : enum apic_intr_mode_id {
      60             :         APIC_PIC,
      61             :         APIC_VIRTUAL_WIRE,
      62             :         APIC_VIRTUAL_WIRE_NO_CONFIG,
      63             :         APIC_SYMMETRIC_IO,
      64             :         APIC_SYMMETRIC_IO_NO_ROUTING
      65             : };
      66             : 
      67             : #ifdef CONFIG_SMP
      68             : extern void __inquire_remote_apic(int apicid);
      69             : #else /* CONFIG_SMP */
      70             : static inline void __inquire_remote_apic(int apicid)
      71             : {
      72             : }
      73             : #endif /* CONFIG_SMP */
      74             : 
      75           0 : static inline void default_inquire_remote_apic(int apicid)
      76             : {
      77           0 :         if (apic_verbosity >= APIC_DEBUG)
      78           0 :                 __inquire_remote_apic(apicid);
      79           0 : }
      80             : 
      81             : /*
      82             :  * With 82489DX we can't rely on apic feature bit
      83             :  * retrieved via cpuid but still have to deal with
      84             :  * such an apic chip so we assume that SMP configuration
      85             :  * is found from MP table (64bit case uses ACPI mostly
      86             :  * which set smp presence flag as well so we are safe
      87             :  * to use this helper too).
      88             :  */
      89           0 : static inline bool apic_from_smp_config(void)
      90             : {
      91           0 :         return smp_found_config && !disable_apic;
      92             : }
      93             : 
      94             : /*
      95             :  * Basic functions accessing APICs.
      96             :  */
      97             : #ifdef CONFIG_PARAVIRT
      98             : #include <asm/paravirt.h>
      99             : #endif
     100             : 
     101             : extern int setup_profiling_timer(unsigned int);
     102             : 
     103        2272 : static inline void native_apic_mem_write(u32 reg, u32 v)
     104             : {
     105        2272 :         volatile u32 *addr = (volatile u32 *)(APIC_BASE + reg);
     106             : 
     107        2272 :         alternative_io("movl %0, %P1", "xchgl %0, %P1", X86_BUG_11AP,
     108             :                        ASM_OUTPUT2("=r" (v), "=m" (*addr)),
     109             :                        ASM_OUTPUT2("0" (v), "m" (*addr)));
     110        2293 : }
     111             : 
     112         190 : static inline u32 native_apic_mem_read(u32 reg)
     113             : {
     114         190 :         return *((volatile u32 *)(APIC_BASE + reg));
     115             : }
     116             : 
     117             : extern void native_apic_wait_icr_idle(void);
     118             : extern u32 native_safe_apic_wait_icr_idle(void);
     119             : extern void native_apic_icr_write(u32 low, u32 id);
     120             : extern u64 native_apic_icr_read(void);
     121             : 
     122           1 : static inline bool apic_is_x2apic_enabled(void)
     123             : {
     124           1 :         u64 msr;
     125             : 
     126           1 :         if (rdmsrl_safe(MSR_IA32_APICBASE, &msr))
     127             :                 return false;
     128           1 :         return msr & X2APIC_ENABLE;
     129             : }
     130             : 
     131             : extern void enable_IR_x2apic(void);
     132             : 
     133             : extern int get_physical_broadcast(void);
     134             : 
     135             : extern int lapic_get_maxlvt(void);
     136             : extern void clear_local_APIC(void);
     137             : extern void disconnect_bsp_APIC(int virt_wire_setup);
     138             : extern void disable_local_APIC(void);
     139             : extern void apic_soft_disable(void);
     140             : extern void lapic_shutdown(void);
     141             : extern void sync_Arb_IDs(void);
     142             : extern void init_bsp_APIC(void);
     143             : extern void apic_intr_mode_select(void);
     144             : extern void apic_intr_mode_init(void);
     145             : extern void init_apic_mappings(void);
     146             : void register_lapic_address(unsigned long address);
     147             : extern void setup_boot_APIC_clock(void);
     148             : extern void setup_secondary_APIC_clock(void);
     149             : extern void lapic_update_tsc_freq(void);
     150             : 
     151             : #ifdef CONFIG_X86_64
     152             : static inline int apic_force_enable(unsigned long addr)
     153             : {
     154             :         return -1;
     155             : }
     156             : #else
     157             : extern int apic_force_enable(unsigned long addr);
     158             : #endif
     159             : 
     160             : extern void apic_ap_setup(void);
     161             : 
     162             : /*
     163             :  * On 32bit this is mach-xxx local
     164             :  */
     165             : #ifdef CONFIG_X86_64
     166             : extern int apic_is_clustered_box(void);
     167             : #else
     168             : static inline int apic_is_clustered_box(void)
     169             : {
     170             :         return 0;
     171             : }
     172             : #endif
     173             : 
     174             : extern int setup_APIC_eilvt(u8 lvt_off, u8 vector, u8 msg_type, u8 mask);
     175             : extern void lapic_assign_system_vectors(void);
     176             : extern void lapic_assign_legacy_vector(unsigned int isairq, bool replace);
     177             : extern void lapic_online(void);
     178             : extern void lapic_offline(void);
     179             : extern bool apic_needs_pit(void);
     180             : 
     181             : extern void apic_send_IPI_allbutself(unsigned int vector);
     182             : 
     183             : #else /* !CONFIG_X86_LOCAL_APIC */
     184             : static inline void lapic_shutdown(void) { }
     185             : #define local_apic_timer_c2_ok          1
     186             : static inline void init_apic_mappings(void) { }
     187             : static inline void disable_local_APIC(void) { }
     188             : # define setup_boot_APIC_clock x86_init_noop
     189             : # define setup_secondary_APIC_clock x86_init_noop
     190             : static inline void lapic_update_tsc_freq(void) { }
     191             : static inline void init_bsp_APIC(void) { }
     192             : static inline void apic_intr_mode_select(void) { }
     193             : static inline void apic_intr_mode_init(void) { }
     194             : static inline void lapic_assign_system_vectors(void) { }
     195             : static inline void lapic_assign_legacy_vector(unsigned int i, bool r) { }
     196             : static inline bool apic_needs_pit(void) { return true; }
     197             : #endif /* !CONFIG_X86_LOCAL_APIC */
     198             : 
     199             : #ifdef CONFIG_X86_X2APIC
     200             : static inline void native_apic_msr_write(u32 reg, u32 v)
     201             : {
     202             :         if (reg == APIC_DFR || reg == APIC_ID || reg == APIC_LDR ||
     203             :             reg == APIC_LVR)
     204             :                 return;
     205             : 
     206             :         wrmsr(APIC_BASE_MSR + (reg >> 4), v, 0);
     207             : }
     208             : 
     209             : static inline void native_apic_msr_eoi_write(u32 reg, u32 v)
     210             : {
     211             :         __wrmsr(APIC_BASE_MSR + (APIC_EOI >> 4), APIC_EOI_ACK, 0);
     212             : }
     213             : 
     214             : static inline u32 native_apic_msr_read(u32 reg)
     215             : {
     216             :         u64 msr;
     217             : 
     218             :         if (reg == APIC_DFR)
     219             :                 return -1;
     220             : 
     221             :         rdmsrl(APIC_BASE_MSR + (reg >> 4), msr);
     222             :         return (u32)msr;
     223             : }
     224             : 
     225             : static inline void native_x2apic_wait_icr_idle(void)
     226             : {
     227             :         /* no need to wait for icr idle in x2apic */
     228             :         return;
     229             : }
     230             : 
     231             : static inline u32 native_safe_x2apic_wait_icr_idle(void)
     232             : {
     233             :         /* no need to wait for icr idle in x2apic */
     234             :         return 0;
     235             : }
     236             : 
     237             : static inline void native_x2apic_icr_write(u32 low, u32 id)
     238             : {
     239             :         wrmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), ((__u64) id) << 32 | low);
     240             : }
     241             : 
     242             : static inline u64 native_x2apic_icr_read(void)
     243             : {
     244             :         unsigned long val;
     245             : 
     246             :         rdmsrl(APIC_BASE_MSR + (APIC_ICR >> 4), val);
     247             :         return val;
     248             : }
     249             : 
     250             : extern int x2apic_mode;
     251             : extern int x2apic_phys;
     252             : extern void __init x2apic_set_max_apicid(u32 apicid);
     253             : extern void __init check_x2apic(void);
     254             : extern void x2apic_setup(void);
     255             : static inline int x2apic_enabled(void)
     256             : {
     257             :         return boot_cpu_has(X86_FEATURE_X2APIC) && apic_is_x2apic_enabled();
     258             : }
     259             : 
     260             : #define x2apic_supported()      (boot_cpu_has(X86_FEATURE_X2APIC))
     261             : #else /* !CONFIG_X86_X2APIC */
     262           1 : static inline void check_x2apic(void) { }
     263           4 : static inline void x2apic_setup(void) { }
     264           0 : static inline int x2apic_enabled(void) { return 0; }
     265             : 
     266             : #define x2apic_mode             (0)
     267             : #define x2apic_supported()      (0)
     268             : #endif /* !CONFIG_X86_X2APIC */
     269             : 
     270             : struct irq_data;
     271             : 
     272             : /*
     273             :  * Copyright 2004 James Cleverdon, IBM.
     274             :  *
     275             :  * Generic APIC sub-arch data struct.
     276             :  *
     277             :  * Hacked for x86-64 by James Cleverdon from i386 architecture code by
     278             :  * Martin Bligh, Andi Kleen, James Bottomley, John Stultz, and
     279             :  * James Cleverdon.
     280             :  */
     281             : struct apic {
     282             :         /* Hotpath functions first */
     283             :         void    (*eoi_write)(u32 reg, u32 v);
     284             :         void    (*native_eoi_write)(u32 reg, u32 v);
     285             :         void    (*write)(u32 reg, u32 v);
     286             :         u32     (*read)(u32 reg);
     287             : 
     288             :         /* IPI related functions */
     289             :         void    (*wait_icr_idle)(void);
     290             :         u32     (*safe_wait_icr_idle)(void);
     291             : 
     292             :         void    (*send_IPI)(int cpu, int vector);
     293             :         void    (*send_IPI_mask)(const struct cpumask *mask, int vector);
     294             :         void    (*send_IPI_mask_allbutself)(const struct cpumask *msk, int vec);
     295             :         void    (*send_IPI_allbutself)(int vector);
     296             :         void    (*send_IPI_all)(int vector);
     297             :         void    (*send_IPI_self)(int vector);
     298             : 
     299             :         u32     disable_esr;
     300             : 
     301             :         enum apic_delivery_modes delivery_mode;
     302             :         bool    dest_mode_logical;
     303             : 
     304             :         u32     (*calc_dest_apicid)(unsigned int cpu);
     305             : 
     306             :         /* ICR related functions */
     307             :         u64     (*icr_read)(void);
     308             :         void    (*icr_write)(u32 low, u32 high);
     309             : 
     310             :         /* Probe, setup and smpboot functions */
     311             :         int     (*probe)(void);
     312             :         int     (*acpi_madt_oem_check)(char *oem_id, char *oem_table_id);
     313             :         int     (*apic_id_valid)(u32 apicid);
     314             :         int     (*apic_id_registered)(void);
     315             : 
     316             :         bool    (*check_apicid_used)(physid_mask_t *map, int apicid);
     317             :         void    (*init_apic_ldr)(void);
     318             :         void    (*ioapic_phys_id_map)(physid_mask_t *phys_map, physid_mask_t *retmap);
     319             :         void    (*setup_apic_routing)(void);
     320             :         int     (*cpu_present_to_apicid)(int mps_cpu);
     321             :         void    (*apicid_to_cpu_present)(int phys_apicid, physid_mask_t *retmap);
     322             :         int     (*check_phys_apicid_present)(int phys_apicid);
     323             :         int     (*phys_pkg_id)(int cpuid_apic, int index_msb);
     324             : 
     325             :         u32     (*get_apic_id)(unsigned long x);
     326             :         u32     (*set_apic_id)(unsigned int id);
     327             : 
     328             :         /* wakeup_secondary_cpu */
     329             :         int     (*wakeup_secondary_cpu)(int apicid, unsigned long start_eip);
     330             : 
     331             :         void    (*inquire_remote_apic)(int apicid);
     332             : 
     333             : #ifdef CONFIG_X86_32
     334             :         /*
     335             :          * Called very early during boot from get_smp_config().  It should
     336             :          * return the logical apicid.  x86_[bios]_cpu_to_apicid is
     337             :          * initialized before this function is called.
     338             :          *
     339             :          * If logical apicid can't be determined that early, the function
     340             :          * may return BAD_APICID.  Logical apicid will be configured after
     341             :          * init_apic_ldr() while bringing up CPUs.  Note that NUMA affinity
     342             :          * won't be applied properly during early boot in this case.
     343             :          */
     344             :         int (*x86_32_early_logical_apicid)(int cpu);
     345             : #endif
     346             :         char    *name;
     347             : };
     348             : 
     349             : /*
     350             :  * Pointer to the local APIC driver in use on this system (there's
     351             :  * always just one such driver in use - the kernel decides via an
     352             :  * early probing process which one it picks - and then sticks to it):
     353             :  */
     354             : extern struct apic *apic;
     355             : 
     356             : /*
     357             :  * APIC drivers are probed based on how they are listed in the .apicdrivers
     358             :  * section. So the order is important and enforced by the ordering
     359             :  * of different apic driver files in the Makefile.
     360             :  *
     361             :  * For the files having two apic drivers, we use apic_drivers()
     362             :  * to enforce the order with in them.
     363             :  */
     364             : #define apic_driver(sym)                                        \
     365             :         static const struct apic *__apicdrivers_##sym __used            \
     366             :         __aligned(sizeof(struct apic *))                        \
     367             :         __section(".apicdrivers") = { &sym }
     368             : 
     369             : #define apic_drivers(sym1, sym2)                                        \
     370             :         static struct apic *__apicdrivers_##sym1##sym2[2] __used        \
     371             :         __aligned(sizeof(struct apic *))                                \
     372             :         __section(".apicdrivers") = { &sym1, &sym2 }
     373             : 
     374             : extern struct apic *__apicdrivers[], *__apicdrivers_end[];
     375             : 
     376             : /*
     377             :  * APIC functionality to boot other CPUs - only used on SMP:
     378             :  */
     379             : #ifdef CONFIG_SMP
     380             : extern int wakeup_secondary_cpu_via_nmi(int apicid, unsigned long start_eip);
     381             : extern int lapic_can_unplug_cpu(void);
     382             : #endif
     383             : 
     384             : #ifdef CONFIG_X86_LOCAL_APIC
     385             : 
     386         144 : static inline u32 apic_read(u32 reg)
     387             : {
     388         140 :         return apic->read(reg);
     389             : }
     390             : 
     391          94 : static inline void apic_write(u32 reg, u32 val)
     392             : {
     393          78 :         apic->write(reg, val);
     394          27 : }
     395             : 
     396       90343 : static inline void apic_eoi(void)
     397             : {
     398       90343 :         apic->eoi_write(APIC_EOI, APIC_EOI_ACK);
     399             : }
     400             : 
     401           0 : static inline u64 apic_icr_read(void)
     402             : {
     403           0 :         return apic->icr_read();
     404             : }
     405             : 
     406          12 : static inline void apic_icr_write(u32 low, u32 high)
     407             : {
     408          12 :         apic->icr_write(low, high);
     409             : }
     410             : 
     411           0 : static inline void apic_wait_icr_idle(void)
     412             : {
     413           0 :         apic->wait_icr_idle();
     414           0 : }
     415             : 
     416          12 : static inline u32 safe_apic_wait_icr_idle(void)
     417             : {
     418          12 :         return apic->safe_wait_icr_idle();
     419             : }
     420             : 
     421             : extern void __init apic_set_eoi_write(void (*eoi_write)(u32 reg, u32 v));
     422             : 
     423             : #else /* CONFIG_X86_LOCAL_APIC */
     424             : 
     425             : static inline u32 apic_read(u32 reg) { return 0; }
     426             : static inline void apic_write(u32 reg, u32 val) { }
     427             : static inline void apic_eoi(void) { }
     428             : static inline u64 apic_icr_read(void) { return 0; }
     429             : static inline void apic_icr_write(u32 low, u32 high) { }
     430             : static inline void apic_wait_icr_idle(void) { }
     431             : static inline u32 safe_apic_wait_icr_idle(void) { return 0; }
     432             : static inline void apic_set_eoi_write(void (*eoi_write)(u32 reg, u32 v)) {}
     433             : 
     434             : #endif /* CONFIG_X86_LOCAL_APIC */
     435             : 
     436             : extern void apic_ack_irq(struct irq_data *data);
     437             : 
     438       90343 : static inline void ack_APIC_irq(void)
     439             : {
     440             :         /*
     441             :          * ack_APIC_irq() actually gets compiled as a single instruction
     442             :          * ... yummie.
     443             :          */
     444       90343 :         apic_eoi();
     445        2525 : }
     446             : 
     447             : 
     448             : static inline bool lapic_vector_set_in_irr(unsigned int vector)
     449             : {
     450             :         u32 irr = apic_read(APIC_IRR + (vector / 32 * 0x10));
     451             : 
     452             :         return !!(irr & (1U << (vector % 32)));
     453             : }
     454             : 
     455             : static inline unsigned default_get_apic_id(unsigned long x)
     456             : {
     457             :         unsigned int ver = GET_APIC_VERSION(apic_read(APIC_LVR));
     458             : 
     459             :         if (APIC_XAPIC(ver) || boot_cpu_has(X86_FEATURE_EXTD_APICID))
     460             :                 return (x >> 24) & 0xFF;
     461             :         else
     462             :                 return (x >> 24) & 0x0F;
     463             : }
     464             : 
     465             : /*
     466             :  * Warm reset vector position:
     467             :  */
     468             : #define TRAMPOLINE_PHYS_LOW             0x467
     469             : #define TRAMPOLINE_PHYS_HIGH            0x469
     470             : 
     471             : extern void generic_bigsmp_probe(void);
     472             : 
     473             : #ifdef CONFIG_X86_LOCAL_APIC
     474             : 
     475             : #include <asm/smp.h>
     476             : 
     477             : #define APIC_DFR_VALUE  (APIC_DFR_FLAT)
     478             : 
     479             : DECLARE_EARLY_PER_CPU_READ_MOSTLY(u16, x86_bios_cpu_apicid);
     480             : 
     481             : extern struct apic apic_noop;
     482             : 
     483           4 : static inline unsigned int read_apic_id(void)
     484             : {
     485           4 :         unsigned int reg = apic_read(APIC_ID);
     486             : 
     487           4 :         return apic->get_apic_id(reg);
     488             : }
     489             : 
     490             : extern int default_apic_id_valid(u32 apicid);
     491             : extern int default_acpi_madt_oem_check(char *, char *);
     492             : extern void default_setup_apic_routing(void);
     493             : 
     494             : extern u32 apic_default_calc_apicid(unsigned int cpu);
     495             : extern u32 apic_flat_calc_apicid(unsigned int cpu);
     496             : 
     497             : extern bool default_check_apicid_used(physid_mask_t *map, int apicid);
     498             : extern void default_ioapic_phys_id_map(physid_mask_t *phys_map, physid_mask_t *retmap);
     499             : extern int default_cpu_present_to_apicid(int mps_cpu);
     500             : extern int default_check_phys_apicid_present(int phys_apicid);
     501             : 
     502             : #endif /* CONFIG_X86_LOCAL_APIC */
     503             : 
     504             : #ifdef CONFIG_SMP
     505             : bool apic_id_is_primary_thread(unsigned int id);
     506             : void apic_smt_update(void);
     507             : #else
     508             : static inline bool apic_id_is_primary_thread(unsigned int id) { return false; }
     509             : static inline void apic_smt_update(void) { }
     510             : #endif
     511             : 
     512             : struct msi_msg;
     513             : struct irq_cfg;
     514             : 
     515             : extern void __irq_msi_compose_msg(struct irq_cfg *cfg, struct msi_msg *msg,
     516             :                                   bool dmar);
     517             : 
     518             : extern void ioapic_zap_locks(void);
     519             : 
     520             : #endif /* _ASM_X86_APIC_H */

Generated by: LCOV version 1.14