| 1 | /*- |
| 2 | * SPDX-License-Identifier: Beerware |
| 3 | * |
| 4 | * ---------------------------------------------------------------------------- |
| 5 | * "THE BEER-WARE LICENSE" (Revision 42): |
| 6 | * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you |
| 7 | * can do whatever you want with this stuff. If we meet some day, and you think |
| 8 | * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp |
| 9 | * ---------------------------------------------------------------------------- |
| 10 | * |
| 11 | */ |
| 12 | |
| 13 | #ifndef _X86_X86_SMP_H_ |
| 14 | #define	_X86_X86_SMP_H_ |
| 15 | |
| 16 | #include <sys/bus.h> |
| 17 | #include <machine/frame.h> |
| 18 | #include <machine/intr_machdep.h> |
| 19 | #include <x86/apicvar.h> |
| 20 | #include <machine/pcb.h> |
| 21 | |
| 22 | struct pmap; |
| 23 | |
| 24 | #ifdef __i386__ |
| 25 | extern unsigned int boot_address; |
| 26 | #endif |
| 27 | |
| 28 | /* global data in mp_x86.c */ |
| 29 | extern int mp_naps; |
| 30 | extern int boot_cpu_id; |
| 31 | extern int cpu_apic_ids[]; |
| 32 | extern int bootAP; |
| 33 | extern void *dpcpu; |
| 34 | extern char *bootSTK; |
| 35 | extern void *bootstacks[]; |
| 36 | extern unsigned int bootMP_size; |
| 37 | extern volatile int aps_ready; |
| 38 | extern struct mtx ap_boot_mtx; |
| 39 | extern int cpu_logical; |
| 40 | extern int cpu_cores; |
| 41 | extern volatile uint32_t smp_tlb_generation; |
| 42 | extern struct pmap *smp_tlb_pmap; |
| 43 | extern vm_offset_t smp_tlb_addr1, smp_tlb_addr2; |
| 44 | extern u_int xhits_gbl[]; |
| 45 | extern u_int xhits_pg[]; |
| 46 | extern u_int xhits_rng[]; |
| 47 | extern u_int ipi_global; |
| 48 | extern u_int ipi_page; |
| 49 | extern u_int ipi_range; |
| 50 | extern u_int ipi_range_size; |
| 51 | |
| 52 | extern int nmi_kdb_lock; |
| 53 | extern int nmi_is_broadcast; |
| 54 | |
| 55 | struct cpu_info { |
| 56 | 	bool	cpu_present:1; |
| 57 | 	bool	cpu_bsp:1; |
| 58 | 	bool	cpu_disabled:1; |
| 59 | 	bool	cpu_hyperthread:1; |
| 60 | }; |
| 61 | extern struct cpu_info *cpu_info; |
| 62 | |
| 63 | /* |
| 64 | * Set if MWAIT does not reliably wake when the MONITORed address is written. |
| 65 | */ |
| 66 | extern bool mwait_cpustop_broken; |
| 67 | |
| 68 | #ifdef COUNT_IPIS |
| 69 | extern u_long *ipi_invltlb_counts[MAXCPU]; |
| 70 | extern u_long *ipi_invlrng_counts[MAXCPU]; |
| 71 | extern u_long *ipi_invlpg_counts[MAXCPU]; |
| 72 | extern u_long *ipi_invlcache_counts[MAXCPU]; |
| 73 | extern u_long *ipi_rendezvous_counts[MAXCPU]; |
| 74 | #endif |
| 75 | |
| 76 | /* IPI handlers */ |
| 77 | inthand_t |
| 78 | 	IDTVEC(ipi_intr_bitmap_handler), /* Bitmap based IPIs */ |
| 79 | 	IDTVEC(ipi_swi),	/* Runs delayed SWI */ |
| 80 | 	IDTVEC(cpustop),	/* CPU stops & waits to be restarted */ |
| 81 | 	IDTVEC(cpususpend),	/* CPU suspends & waits to be resumed */ |
| 82 | 	IDTVEC(rendezvous);	/* handle CPU rendezvous */ |
| 83 | |
| 84 | typedef void (*smp_invl_cb_t)(struct pmap *, vm_offset_t addr1, |
| 85 | vm_offset_t addr2); |
| 86 | |
| 87 | #ifdef __i386__ |
| 88 | void	alloc_ap_trampoline(vm_paddr_t *physmap, unsigned int *physmap_idx); |
| 89 | #endif |
| 90 | |
| 91 | /* functions in x86_mp.c */ |
| 92 | void	assign_cpu_ids(void); |
| 93 | void	cpu_add(u_int apic_id, char boot_cpu); |
| 94 | void	cpustop_handler(void); |
| 95 | void	cpususpend_handler(void); |
| 96 | void	init_secondary_tail(void); |
| 97 | void	init_secondary(void); |
| 98 | void	ipi_startup(int apic_id, int vector); |
| 99 | void	ipi_all_but_self(u_int ipi); |
| 100 | void 	ipi_bitmap_handler(struct trapframe frame); |
| 101 | void	ipi_cpu(int cpu, u_int ipi); |
| 102 | int	ipi_nmi_handler(void); |
| 103 | void	ipi_swi_handler(struct trapframe frame); |
| 104 | void	ipi_selected(cpuset_t cpus, u_int ipi); |
| 105 | void	ipi_self_from_nmi(u_int vector); |
| 106 | void	set_interrupt_apic_ids(void); |
| 107 | void	mem_range_AP_init(void); |
| 108 | void	topo_probe(void); |
| 109 | |
| 110 | /* functions in mp_machdep.c */ |
| 111 | void	smp_cache_flush(smp_invl_cb_t curcpu_cb); |
| 112 | #ifdef __i386__ |
| 113 | void	smp_masked_invlpg(cpuset_t mask, vm_offset_t addr, struct pmap *pmap, |
| 114 | 	 smp_invl_cb_t curcpu_cb); |
| 115 | void	smp_masked_invlpg_range(cpuset_t mask, vm_offset_t startva, |
| 116 | 	 vm_offset_t endva, struct pmap *pmap, smp_invl_cb_t curcpu_cb); |
| 117 | void	smp_masked_invltlb(cpuset_t mask, struct pmap *pmap, |
| 118 | 	 smp_invl_cb_t curcpu_cb); |
| 119 | #else |
| 120 | void	smp_masked_invlpg(vm_offset_t addr, struct pmap *pmap, |
| 121 | 	 smp_invl_cb_t curcpu_cb); |
| 122 | void	smp_masked_invlpg_range(vm_offset_t startva, vm_offset_t endva, |
| 123 | 	 struct pmap *pmap, smp_invl_cb_t curcpu_cb); |
| 124 | void	smp_masked_invltlb(struct pmap *pmap, smp_invl_cb_t curcpu_cb); |
| 125 | #endif |
| 126 | #endif |