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>
|
|
|
|
#include <machine/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[];
|
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];
|
2011-05-20 14:53:16 +00:00
|
|
|
extern u_long *ipi_lazypmap_counts[MAXCPU];
|
2005-12-05 22:25:41 +00:00
|
|
|
#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 */
|
2011-05-20 14:53:16 +00:00
|
|
|
IDTVEC(rendezvous), /* handle CPU rendezvous */
|
|
|
|
IDTVEC(lazypmap); /* handle lazy pmap release */
|
1997-04-26 11:46:25 +00:00
|
|
|
|
|
|
|
/* functions in mp_machdep.c */
|
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);
|
2012-05-20 08:17:20 +00:00
|
|
|
#ifndef XEN
|
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);
|
2012-05-20 08:17:20 +00:00
|
|
|
#endif
|
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);
|
2008-10-21 08:01:19 +00:00
|
|
|
#ifndef XEN
|
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);
|
2008-10-21 08:01:19 +00:00
|
|
|
#endif
|
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);
|
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);
|
1997-04-26 11:46:25 +00:00
|
|
|
|
2008-09-25 07:09:50 +00:00
|
|
|
#ifdef XEN
|
|
|
|
void ipi_to_irq_init(void);
|
2008-10-21 06:38:05 +00:00
|
|
|
|
2008-10-24 07:58:38 +00:00
|
|
|
#define RESCHEDULE_VECTOR 0
|
|
|
|
#define CALL_FUNCTION_VECTOR 1
|
2008-10-21 06:38:05 +00:00
|
|
|
#define NR_IPIS 2
|
|
|
|
|
2008-09-25 07:09:50 +00:00
|
|
|
#endif
|
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_ */
|