mirror of
https://github.com/opnsense/src.git
synced 2026-06-10 17:22:46 -04:00
Tweak the AP startup code somewhat. With all the other recent changes,
this now works pretty well for two processors at least. Submitted by: marcel, mostly.
This commit is contained in:
parent
34da0be411
commit
0f638cfaeb
1 changed files with 41 additions and 8 deletions
|
|
@ -45,10 +45,12 @@
|
|||
|
||||
#include <machine/atomic.h>
|
||||
#include <machine/pal.h>
|
||||
#include <machine/pcb.h>
|
||||
#include <machine/pmap.h>
|
||||
#include <machine/clock.h>
|
||||
#include <machine/sal.h>
|
||||
#include <machine/smp.h>
|
||||
#include <machine/fpu.h>
|
||||
|
||||
void cpu_mp_add(uint, uint, uint);
|
||||
void ia64_ap_startup(void);
|
||||
|
|
@ -70,6 +72,7 @@ volatile vm_offset_t ap_stack;
|
|||
volatile struct pcpu *ap_pcpu;
|
||||
volatile int ap_delay;
|
||||
volatile int ap_awake;
|
||||
volatile int ap_spin;
|
||||
|
||||
static void ipi_send(u_int64_t, int);
|
||||
static void cpu_mp_unleash(void *);
|
||||
|
|
@ -80,16 +83,23 @@ ia64_ap_startup(void)
|
|||
__asm __volatile("mov cr.pta=%0;; srlz.i;;" ::
|
||||
"r" (vhpt_base + (1<<8) + (vhpt_size<<2) + 1));
|
||||
|
||||
ia64_set_fpsr(IA64_FPSR_DEFAULT);
|
||||
|
||||
ap_awake = 1;
|
||||
ap_delay = 0;
|
||||
|
||||
/* Wait until it's time for us to be unleashed */
|
||||
while (!smp_started);
|
||||
|
||||
CTR1(KTR_SMP, "SMP: cpu%d launched", PCPU_GET(cpuid));
|
||||
while (ap_spin)
|
||||
/* spin */;
|
||||
|
||||
__asm __volatile("ssm psr.ic|psr.i;; srlz.i;;");
|
||||
|
||||
ap_awake++;
|
||||
while (!smp_started)
|
||||
/* spin */;
|
||||
|
||||
CTR1(KTR_SMP, "SMP: cpu%d launched", PCPU_GET(cpuid));
|
||||
|
||||
binuptime(PCPU_PTR(switchtime));
|
||||
PCPU_SET(switchticks, ticks);
|
||||
|
||||
|
|
@ -168,14 +178,28 @@ cpu_mp_start()
|
|||
{
|
||||
struct pcpu *pc;
|
||||
|
||||
ap_spin = 1;
|
||||
|
||||
SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
|
||||
#if 0
|
||||
pc->pc_current_pmap = PCPU_GET(current_pmap);
|
||||
#endif
|
||||
pc->pc_current_pmap = kernel_pmap;
|
||||
pc->pc_other_cpus = all_cpus & ~pc->pc_cpumask;
|
||||
if (pc->pc_cpuid > 0) {
|
||||
ap_stack = kmem_alloc(kernel_map,
|
||||
KSTACK_PAGES * PAGE_SIZE);
|
||||
void *ks;
|
||||
|
||||
/*
|
||||
* Use contigmalloc for stack so that we can
|
||||
* use a region 7 address for it which makes
|
||||
* it impossible to accidentally lose when
|
||||
* recording a trapframe.
|
||||
*/
|
||||
ks = contigmalloc(KSTACK_PAGES * PAGE_SIZE, M_TEMP,
|
||||
M_WAITOK,
|
||||
0ul,
|
||||
256*1024*1024 - 1,
|
||||
PAGE_SIZE,
|
||||
256*1024*1024);
|
||||
|
||||
ap_stack = IA64_PHYS_TO_RR7(ia64_tpa((u_int64_t)ks));
|
||||
ap_pcpu = pc;
|
||||
ap_delay = 2000;
|
||||
ap_awake = 0;
|
||||
|
|
@ -209,6 +233,8 @@ cpu_mp_unleash(void *dummy)
|
|||
if (!mp_hardware)
|
||||
return;
|
||||
|
||||
breakpoint();
|
||||
|
||||
if (mp_ipi_test != 1)
|
||||
printf("SMP: WARNING: sending of a test IPI failed\n");
|
||||
|
||||
|
|
@ -220,6 +246,12 @@ cpu_mp_unleash(void *dummy)
|
|||
smp_cpus++;
|
||||
}
|
||||
|
||||
ap_awake = 1;
|
||||
ap_spin = 0;
|
||||
|
||||
while (ap_awake != smp_cpus)
|
||||
/* spin */;
|
||||
|
||||
if (smp_cpus != cpus || cpus != mp_ncpus) {
|
||||
printf("SMP: %d CPUs found; %d CPUs usable; %d CPUs woken\n",
|
||||
mp_ncpus, cpus, smp_cpus);
|
||||
|
|
@ -294,6 +326,7 @@ ipi_send(u_int64_t lid, int ipi)
|
|||
pipi = ia64_memory_address(PAL_PIB_DEFAULT_ADDR |
|
||||
((lid & LID_SAPIC_MASK) >> 12));
|
||||
vector = (u_int64_t)(mp_ipi_vector[ipi] & 0xff);
|
||||
CTR3(KTR_SMP, "ipi_send(%p, %ld), cpuid=%d", pipi, vector, PCPU_GET(cpuid));
|
||||
*pipi = vector;
|
||||
ia64_mf_a();
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue