2005-01-06 22:18:23 +00:00
|
|
|
/*-
|
1997-04-26 11:46:25 +00:00
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
* "THE BEER-WARE LICENSE" (Revision 42):
|
|
|
|
* <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
|
|
|
|
* can do whatever you want with this stuff. If we meet some day, and you think
|
|
|
|
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
|
|
|
|
* ----------------------------------------------------------------------------
|
|
|
|
*
|
1999-08-28 01:08:13 +00:00
|
|
|
* $FreeBSD$
|
1997-04-26 11:46:25 +00:00
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _MACHINE_SMP_H_
|
|
|
|
#define _MACHINE_SMP_H_
|
|
|
|
|
1999-12-29 04:46:21 +00:00
|
|
|
#ifdef _KERNEL
|
1997-04-26 11:46:25 +00:00
|
|
|
|
2003-11-03 22:32:04 +00:00
|
|
|
#ifdef SMP
|
1997-04-26 11:46:25 +00:00
|
|
|
|
1997-07-28 03:59:54 +00:00
|
|
|
#ifndef LOCORE
|
|
|
|
|
2003-11-03 22:32:04 +00:00
|
|
|
#include <sys/bus.h>
|
2001-04-27 19:28:25 +00:00
|
|
|
#include <machine/frame.h>
|
2003-11-03 22:32:04 +00:00
|
|
|
#include <machine/intr_machdep.h>
|
2014-01-23 20:10:22 +00:00
|
|
|
#include <x86/apicvar.h>
|
2007-05-19 05:01:43 +00:00
|
|
|
#include <machine/pcb.h>
|
1997-05-29 05:57:43 +00:00
|
|
|
|
1997-04-26 11:46:25 +00:00
|
|
|
/* global data in mpboot.s */
|
|
|
|
extern int bootMP_size;
|
|
|
|
|
|
|
|
/* functions in mpboot.s */
|
2002-03-23 15:09:35 +00:00
|
|
|
void bootMP(void);
|
1997-04-26 11:46:25 +00:00
|
|
|
|
|
|
|
/* global data in mp_machdep.c */
|
|
|
|
extern int mp_naps;
|
|
|
|
extern int boot_cpu_id;
|
1998-05-17 22:12:14 +00:00
|
|
|
extern struct pcb stoppcbs[];
|
2007-03-06 17:16:47 +00:00
|
|
|
extern int cpu_apic_ids[];
|
2015-04-24 16:20:56 +00:00
|
|
|
extern int bootAP;
|
|
|
|
extern void *dpcpu;
|
|
|
|
extern char *bootSTK;
|
|
|
|
extern int bootAP;
|
|
|
|
extern void *bootstacks[];
|
|
|
|
extern volatile u_int cpu_ipi_pending[];
|
|
|
|
extern volatile int aps_ready;
|
|
|
|
extern struct mtx ap_boot_mtx;
|
|
|
|
extern int cpu_logical;
|
|
|
|
extern int cpu_cores;
|
|
|
|
extern volatile int smp_tlb_wait;
|
|
|
|
extern u_int xhits_gbl[];
|
|
|
|
extern u_int xhits_pg[];
|
|
|
|
extern u_int xhits_rng[];
|
|
|
|
extern u_int ipi_global;
|
|
|
|
extern u_int ipi_page;
|
|
|
|
extern u_int ipi_range;
|
|
|
|
extern u_int ipi_range_size;
|
|
|
|
extern u_int ipi_masked_global;
|
|
|
|
extern u_int ipi_masked_page;
|
|
|
|
extern u_int ipi_masked_range;
|
|
|
|
extern u_int ipi_masked_range_size;
|
|
|
|
|
|
|
|
struct cpu_info {
|
|
|
|
int cpu_present:1;
|
|
|
|
int cpu_bsp:1;
|
|
|
|
int cpu_disabled:1;
|
|
|
|
int cpu_hyperthread:1;
|
|
|
|
};
|
|
|
|
extern struct cpu_info cpu_info[];
|
|
|
|
|
2005-12-05 22:25:41 +00:00
|
|
|
#ifdef COUNT_IPIS
|
|
|
|
extern u_long *ipi_invltlb_counts[MAXCPU];
|
|
|
|
extern u_long *ipi_invlrng_counts[MAXCPU];
|
|
|
|
extern u_long *ipi_invlpg_counts[MAXCPU];
|
2006-05-01 21:36:47 +00:00
|
|
|
extern u_long *ipi_invlcache_counts[MAXCPU];
|
2005-12-05 22:25:41 +00:00
|
|
|
extern u_long *ipi_rendezvous_counts[MAXCPU];
|
|
|
|
#endif
|
2003-11-03 22:32:04 +00:00
|
|
|
|
|
|
|
/* IPI handlers */
|
|
|
|
inthand_t
|
|
|
|
IDTVEC(invltlb), /* TLB shootdowns - global */
|
|
|
|
IDTVEC(invlpg), /* TLB shootdowns - 1 page */
|
|
|
|
IDTVEC(invlrng), /* TLB shootdowns - page range */
|
2006-05-01 21:36:47 +00:00
|
|
|
IDTVEC(invlcache), /* Write back and invalidate cache */
|
2004-12-07 20:15:01 +00:00
|
|
|
IDTVEC(ipi_intr_bitmap_handler), /* Bitmap based IPIs */
|
2003-11-03 22:32:04 +00:00
|
|
|
IDTVEC(cpustop), /* CPU stops & waits to be restarted */
|
Add SMP/i386 suspend/resume support.
Most part is merged from amd64.
- i386/acpica/acpi_wakecode.S
Replaced with amd64 code (from realmode to paging enabling code).
- i386/acpica/acpi_wakeup.c
Replaced with amd64 code (except for wakeup_pagetables stuff).
- i386/include/pcb.h
- i386/i386/genassym.c
Added PCB new members (CR0, CR2, CR4, DS, ED, FS, SS, GDT, IDT, LDT
and TR) needed for suspend/resume, not for context switch.
- i386/i386/swtch.s
Added suspendctx() and resumectx().
Note that savectx() was not changed and used for suspending (while
amd64 code uses it).
BSP and AP execute the same sequence, suspendctx(), acpi_wakecode()
and resumectx() for suspend/resume (in case of UP system also).
- i386/i386/apic_vector.s
Added cpususpend().
- i386/i386/mp_machdep.c
- i386/include/smp.h
Added cpususpend_handler().
- i386/include/apicvar.h
- kern/subr_smp.c
- sys/smp.h
Added IPI_SUSPEND and suspend_cpus().
- i386/i386/initcpu.c
- i386/i386/machdep.c
- i386/include/md_var.h
- pc98/pc98/machdep.c
Moved initializecpu() declarations to md_var.h.
MFC after: 3 days
2012-05-18 18:55:58 +00:00
|
|
|
IDTVEC(cpususpend), /* CPU suspends & waits to be resumed */
|
2015-04-18 21:23:16 +00:00
|
|
|
IDTVEC(rendezvous); /* handle CPU rendezvous */
|
1997-04-26 11:46:25 +00:00
|
|
|
|
|
|
|
/* functions in mp_machdep.c */
|
2015-04-24 16:20:56 +00:00
|
|
|
void assign_cpu_ids(void);
|
2003-11-03 22:32:04 +00:00
|
|
|
void cpu_add(u_int apic_id, char boot_cpu);
|
2005-12-05 22:25:41 +00:00
|
|
|
void cpustop_handler(void);
|
Add SMP/i386 suspend/resume support.
Most part is merged from amd64.
- i386/acpica/acpi_wakecode.S
Replaced with amd64 code (from realmode to paging enabling code).
- i386/acpica/acpi_wakeup.c
Replaced with amd64 code (except for wakeup_pagetables stuff).
- i386/include/pcb.h
- i386/i386/genassym.c
Added PCB new members (CR0, CR2, CR4, DS, ED, FS, SS, GDT, IDT, LDT
and TR) needed for suspend/resume, not for context switch.
- i386/i386/swtch.s
Added suspendctx() and resumectx().
Note that savectx() was not changed and used for suspending (while
amd64 code uses it).
BSP and AP execute the same sequence, suspendctx(), acpi_wakecode()
and resumectx() for suspend/resume (in case of UP system also).
- i386/i386/apic_vector.s
Added cpususpend().
- i386/i386/mp_machdep.c
- i386/include/smp.h
Added cpususpend_handler().
- i386/include/apicvar.h
- kern/subr_smp.c
- sys/smp.h
Added IPI_SUSPEND and suspend_cpus().
- i386/i386/initcpu.c
- i386/i386/machdep.c
- i386/include/md_var.h
- pc98/pc98/machdep.c
Moved initializecpu() declarations to md_var.h.
MFC after: 3 days
2012-05-18 18:55:58 +00:00
|
|
|
void cpususpend_handler(void);
|
2015-04-24 16:20:56 +00:00
|
|
|
void init_secondary_tail(void);
|
2014-03-11 10:03:29 +00:00
|
|
|
void invltlb_handler(void);
|
|
|
|
void invlpg_handler(void);
|
|
|
|
void invlrng_handler(void);
|
|
|
|
void invlcache_handler(void);
|
2002-03-23 15:09:35 +00:00
|
|
|
void init_secondary(void);
|
2012-06-12 00:14:54 +00:00
|
|
|
void ipi_startup(int apic_id, int vector);
|
2002-03-23 15:09:35 +00:00
|
|
|
void ipi_all_but_self(u_int ipi);
|
Tweak how the MD code calls the fooclock() methods some. Instead of
passing a pointer to an opaque clockframe structure and requiring the
MD code to supply CLKF_FOO() macros to extract needed values out of the
opaque structure, just pass the needed values directly. In practice this
means passing the pair (usermode, pc) to hardclock() and profclock() and
passing the boolean (usermode) to hardclock_cpu() and hardclock_process().
Other details:
- Axe clockframe and CLKF_FOO() macros on all architectures. Basically,
all the archs were taking a trapframe and converting it into a clockframe
one way or another. Now they can just extract the PC and usermode values
directly out of the trapframe and pass it to fooclock().
- Renamed hardclock_process() to hardclock_cpu() as the latter is more
accurate.
- On Alpha, we now run profclock() at hz (profhz == hz) rather than at
the slower stathz.
- On Alpha, for the TurboLaser machines that don't have an 8254
timecounter, call hardclock() directly. This removes an extra
conditional check from every clock interrupt on Alpha on the BSP.
There is probably room for even further pruning here by changing Alpha
to use the simplified timecounter we use on x86 with the lapic timer
since we don't get interrupts from the 8254 on Alpha anyway.
- On x86, clkintr() shouldn't ever be called now unless using_lapic_timer
is false, so add a KASSERT() to that affect and remove a condition
to slightly optimize the non-lapic case.
- Change prototypeof arm_handler_execute() so that it's first arg is a
trapframe pointer rather than a void pointer for clarity.
- Use KCOUNT macro in profclock() to lookup the kernel profiling bucket.
Tested on: alpha, amd64, arm, i386, ia64, sparc64
Reviewed by: bde (mostly)
2005-12-22 22:16:09 +00:00
|
|
|
void ipi_bitmap_handler(struct trapframe frame);
|
2010-08-06 15:36:59 +00:00
|
|
|
void ipi_cpu(int cpu, u_int ipi);
|
|
|
|
int ipi_nmi_handler(void);
|
Commit the support for removing cpumask_t and replacing it directly with
cpuset_t objects.
That is going to offer the underlying support for a simple bump of
MAXCPU and then support for number of cpus > 32 (as it is today).
Right now, cpumask_t is an int, 32 bits on all our supported architecture.
cpumask_t on the other side is implemented as an array of longs, and
easilly extendible by definition.
The architectures touched by this commit are the following:
- amd64
- i386
- pc98
- arm
- ia64
- XEN
while the others are still missing.
Userland is believed to be fully converted with the changes contained
here.
Some technical notes:
- This commit may be considered an ABI nop for all the architectures
different from amd64 and ia64 (and sparc64 in the future)
- per-cpu members, which are now converted to cpuset_t, needs to be
accessed avoiding migration, because the size of cpuset_t should be
considered unknown
- size of cpuset_t objects is different from kernel and userland (this is
primirally done in order to leave some more space in userland to cope
with KBI extensions). If you need to access kernel cpuset_t from the
userland please refer to example in this patch on how to do that
correctly (kgdb may be a good source, for example).
- Support for other architectures is going to be added soon
- Only MAXCPU for amd64 is bumped now
The patch has been tested by sbruno and Nicholas Esborn on opteron
4 x 12 pack CPUs. More testing on big SMP is expected to came soon.
pluknet tested the patch with his 8-ways on both amd64 and i386.
Tested by: pluknet, sbruno, gianni, Nicholas Esborn
Reviewed by: jeff, jhb, sbruno
2011-05-05 14:39:14 +00:00
|
|
|
void ipi_selected(cpuset_t cpus, u_int ipi);
|
2003-11-03 22:32:04 +00:00
|
|
|
u_int mp_bootaddress(u_int);
|
2015-04-24 16:20:56 +00:00
|
|
|
void set_interrupt_apic_ids(void);
|
2006-05-01 21:36:47 +00:00
|
|
|
void smp_cache_flush(void);
|
2002-07-12 07:56:11 +00:00
|
|
|
void smp_invlpg(vm_offset_t addr);
|
Commit the support for removing cpumask_t and replacing it directly with
cpuset_t objects.
That is going to offer the underlying support for a simple bump of
MAXCPU and then support for number of cpus > 32 (as it is today).
Right now, cpumask_t is an int, 32 bits on all our supported architecture.
cpumask_t on the other side is implemented as an array of longs, and
easilly extendible by definition.
The architectures touched by this commit are the following:
- amd64
- i386
- pc98
- arm
- ia64
- XEN
while the others are still missing.
Userland is believed to be fully converted with the changes contained
here.
Some technical notes:
- This commit may be considered an ABI nop for all the architectures
different from amd64 and ia64 (and sparc64 in the future)
- per-cpu members, which are now converted to cpuset_t, needs to be
accessed avoiding migration, because the size of cpuset_t should be
considered unknown
- size of cpuset_t objects is different from kernel and userland (this is
primirally done in order to leave some more space in userland to cope
with KBI extensions). If you need to access kernel cpuset_t from the
userland please refer to example in this patch on how to do that
correctly (kgdb may be a good source, for example).
- Support for other architectures is going to be added soon
- Only MAXCPU for amd64 is bumped now
The patch has been tested by sbruno and Nicholas Esborn on opteron
4 x 12 pack CPUs. More testing on big SMP is expected to came soon.
pluknet tested the patch with his 8-ways on both amd64 and i386.
Tested by: pluknet, sbruno, gianni, Nicholas Esborn
Reviewed by: jeff, jhb, sbruno
2011-05-05 14:39:14 +00:00
|
|
|
void smp_masked_invlpg(cpuset_t mask, vm_offset_t addr);
|
2002-07-12 07:56:11 +00:00
|
|
|
void smp_invlpg_range(vm_offset_t startva, vm_offset_t endva);
|
Commit the support for removing cpumask_t and replacing it directly with
cpuset_t objects.
That is going to offer the underlying support for a simple bump of
MAXCPU and then support for number of cpus > 32 (as it is today).
Right now, cpumask_t is an int, 32 bits on all our supported architecture.
cpumask_t on the other side is implemented as an array of longs, and
easilly extendible by definition.
The architectures touched by this commit are the following:
- amd64
- i386
- pc98
- arm
- ia64
- XEN
while the others are still missing.
Userland is believed to be fully converted with the changes contained
here.
Some technical notes:
- This commit may be considered an ABI nop for all the architectures
different from amd64 and ia64 (and sparc64 in the future)
- per-cpu members, which are now converted to cpuset_t, needs to be
accessed avoiding migration, because the size of cpuset_t should be
considered unknown
- size of cpuset_t objects is different from kernel and userland (this is
primirally done in order to leave some more space in userland to cope
with KBI extensions). If you need to access kernel cpuset_t from the
userland please refer to example in this patch on how to do that
correctly (kgdb may be a good source, for example).
- Support for other architectures is going to be added soon
- Only MAXCPU for amd64 is bumped now
The patch has been tested by sbruno and Nicholas Esborn on opteron
4 x 12 pack CPUs. More testing on big SMP is expected to came soon.
pluknet tested the patch with his 8-ways on both amd64 and i386.
Tested by: pluknet, sbruno, gianni, Nicholas Esborn
Reviewed by: jeff, jhb, sbruno
2011-05-05 14:39:14 +00:00
|
|
|
void smp_masked_invlpg_range(cpuset_t mask, vm_offset_t startva,
|
2002-07-12 07:56:11 +00:00
|
|
|
vm_offset_t endva);
|
|
|
|
void smp_invltlb(void);
|
Commit the support for removing cpumask_t and replacing it directly with
cpuset_t objects.
That is going to offer the underlying support for a simple bump of
MAXCPU and then support for number of cpus > 32 (as it is today).
Right now, cpumask_t is an int, 32 bits on all our supported architecture.
cpumask_t on the other side is implemented as an array of longs, and
easilly extendible by definition.
The architectures touched by this commit are the following:
- amd64
- i386
- pc98
- arm
- ia64
- XEN
while the others are still missing.
Userland is believed to be fully converted with the changes contained
here.
Some technical notes:
- This commit may be considered an ABI nop for all the architectures
different from amd64 and ia64 (and sparc64 in the future)
- per-cpu members, which are now converted to cpuset_t, needs to be
accessed avoiding migration, because the size of cpuset_t should be
considered unknown
- size of cpuset_t objects is different from kernel and userland (this is
primirally done in order to leave some more space in userland to cope
with KBI extensions). If you need to access kernel cpuset_t from the
userland please refer to example in this patch on how to do that
correctly (kgdb may be a good source, for example).
- Support for other architectures is going to be added soon
- Only MAXCPU for amd64 is bumped now
The patch has been tested by sbruno and Nicholas Esborn on opteron
4 x 12 pack CPUs. More testing on big SMP is expected to came soon.
pluknet tested the patch with his 8-ways on both amd64 and i386.
Tested by: pluknet, sbruno, gianni, Nicholas Esborn
Reviewed by: jeff, jhb, sbruno
2011-05-05 14:39:14 +00:00
|
|
|
void smp_masked_invltlb(cpuset_t mask);
|
2015-04-24 16:20:56 +00:00
|
|
|
void mem_range_AP_init(void);
|
|
|
|
void topo_probe(void);
|
|
|
|
void ipi_send_cpu(int cpu, u_int ipi);
|
1997-04-26 11:46:25 +00:00
|
|
|
|
1997-07-28 03:59:54 +00:00
|
|
|
#endif /* !LOCORE */
|
2003-11-03 22:32:04 +00:00
|
|
|
#endif /* SMP */
|
2000-03-28 18:06:49 +00:00
|
|
|
|
1999-12-29 04:46:21 +00:00
|
|
|
#endif /* _KERNEL */
|
1997-04-26 11:46:25 +00:00
|
|
|
#endif /* _MACHINE_SMP_H_ */
|