2005-01-05 20:17:21 +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_
|
|
|
|
|
2003-11-17 08:58:16 +00:00
|
|
|
#ifdef _KERNEL
|
|
|
|
|
|
|
|
#ifdef SMP
|
|
|
|
|
|
|
|
#ifndef LOCORE
|
|
|
|
|
|
|
|
#include <sys/bus.h>
|
|
|
|
#include <machine/frame.h>
|
|
|
|
#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>
|
2003-11-17 08:58:16 +00:00
|
|
|
|
|
|
|
/* global symbols in mpboot.S */
|
|
|
|
extern char mptramp_start[];
|
|
|
|
extern char mptramp_end[];
|
|
|
|
extern u_int32_t mptramp_pagetables;
|
|
|
|
|
|
|
|
/* global data in mp_machdep.c */
|
|
|
|
extern int mp_naps;
|
|
|
|
extern int boot_cpu_id;
|
|
|
|
extern struct pcb stoppcbs[];
|
2007-03-06 17:16:47 +00:00
|
|
|
extern int cpu_apic_ids[];
|
2010-06-17 11:54:49 +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];
|
|
|
|
extern u_long *ipi_invlcache_counts[MAXCPU];
|
|
|
|
extern u_long *ipi_rendezvous_counts[MAXCPU];
|
|
|
|
#endif
|
2003-11-17 08:58:16 +00:00
|
|
|
|
|
|
|
/* IPI handlers */
|
|
|
|
inthand_t
|
2013-09-04 23:31:29 +00:00
|
|
|
IDTVEC(invltlb_pcid), /* TLB shootdowns - global, pcid enabled */
|
2003-11-17 08:58:16 +00:00
|
|
|
IDTVEC(invltlb), /* TLB shootdowns - global */
|
2013-09-04 23:31:29 +00:00
|
|
|
IDTVEC(invlpg_pcid), /* TLB shootdowns - 1 page, pcid enabled */
|
2003-11-17 08:58:16 +00:00
|
|
|
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 */
|
2005-01-21 06:01:20 +00:00
|
|
|
IDTVEC(ipi_intr_bitmap_handler), /* Bitmap based IPIs */
|
2003-11-17 08:58:16 +00:00
|
|
|
IDTVEC(cpustop), /* CPU stops & waits to be restarted */
|
2009-03-17 00:48:11 +00:00
|
|
|
IDTVEC(cpususpend), /* CPU suspends & waits to be resumed */
|
2004-05-16 22:11:50 +00:00
|
|
|
IDTVEC(rendezvous); /* handle CPU rendezvous */
|
2003-11-17 08:58:16 +00:00
|
|
|
|
2013-08-30 07:59:49 +00:00
|
|
|
struct pmap;
|
|
|
|
|
2003-11-17 08:58:16 +00:00
|
|
|
/* functions in mp_machdep.c */
|
|
|
|
void cpu_add(u_int apic_id, char boot_cpu);
|
2005-12-08 18:33:30 +00:00
|
|
|
void cpustop_handler(void);
|
2009-03-17 00:48:11 +00:00
|
|
|
void cpususpend_handler(void);
|
2014-03-11 10:03:29 +00:00
|
|
|
void invltlb_handler(void);
|
|
|
|
void invltlb_pcid_handler(void);
|
|
|
|
void invlpg_handler(void);
|
|
|
|
void invlpg_pcid_handler(void);
|
|
|
|
void invlrng_handler(void);
|
|
|
|
void invlcache_handler(void);
|
2003-11-17 08:58:16 +00:00
|
|
|
void init_secondary(void);
|
2012-06-12 00:14:54 +00:00
|
|
|
void ipi_startup(int apic_id, int vector);
|
2003-11-17 08:58:16 +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-17 08:58:16 +00:00
|
|
|
u_int mp_bootaddress(u_int);
|
2006-05-01 21:36:47 +00:00
|
|
|
void smp_cache_flush(void);
|
2013-08-30 07:59:49 +00:00
|
|
|
void smp_invlpg(struct pmap *pmap, vm_offset_t addr);
|
|
|
|
void smp_masked_invlpg(cpuset_t mask, struct pmap *pmap, vm_offset_t addr);
|
|
|
|
void smp_invlpg_range(struct pmap *pmap, vm_offset_t startva,
|
2003-11-17 08:58:16 +00:00
|
|
|
vm_offset_t endva);
|
2013-08-30 07:59:49 +00:00
|
|
|
void smp_masked_invlpg_range(cpuset_t mask, struct pmap *pmap,
|
|
|
|
vm_offset_t startva, vm_offset_t endva);
|
|
|
|
void smp_invltlb(struct pmap *pmap);
|
|
|
|
void smp_masked_invltlb(cpuset_t mask, struct pmap *pmap);
|
2003-11-17 08:58:16 +00:00
|
|
|
|
|
|
|
#endif /* !LOCORE */
|
|
|
|
#endif /* SMP */
|
|
|
|
|
|
|
|
#endif /* _KERNEL */
|
1997-04-26 11:46:25 +00:00
|
|
|
#endif /* _MACHINE_SMP_H_ */
|