mirror of
https://github.com/opnsense/src.git
synced 2026-05-28 04:12:45 -04:00
Share IPI init and startup code of mp_machdep.c with acpi_wakeup.c
as ipi_startup().
This commit is contained in:
parent
aa445c9d7c
commit
77c80e2e5b
5 changed files with 111 additions and 131 deletions
|
|
@ -981,6 +981,60 @@ start_ap(int apic_id)
|
|||
/* used as a watchpoint to signal AP startup */
|
||||
cpus = mp_naps;
|
||||
|
||||
ipi_startup(apic_id, vector);
|
||||
|
||||
/* Wait up to 5 seconds for it to start. */
|
||||
for (ms = 0; ms < 5000; ms++) {
|
||||
if (mp_naps > cpus)
|
||||
return 1; /* return SUCCESS */
|
||||
DELAY(1000);
|
||||
}
|
||||
return 0; /* return FAILURE */
|
||||
}
|
||||
|
||||
#ifdef COUNT_XINVLTLB_HITS
|
||||
u_int xhits_gbl[MAXCPU];
|
||||
u_int xhits_pg[MAXCPU];
|
||||
u_int xhits_rng[MAXCPU];
|
||||
static SYSCTL_NODE(_debug, OID_AUTO, xhits, CTLFLAG_RW, 0, "");
|
||||
SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, global, CTLFLAG_RW, &xhits_gbl,
|
||||
sizeof(xhits_gbl), "IU", "");
|
||||
SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, page, CTLFLAG_RW, &xhits_pg,
|
||||
sizeof(xhits_pg), "IU", "");
|
||||
SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, range, CTLFLAG_RW, &xhits_rng,
|
||||
sizeof(xhits_rng), "IU", "");
|
||||
|
||||
u_int ipi_global;
|
||||
u_int ipi_page;
|
||||
u_int ipi_range;
|
||||
u_int ipi_range_size;
|
||||
SYSCTL_UINT(_debug_xhits, OID_AUTO, ipi_global, CTLFLAG_RW, &ipi_global, 0, "");
|
||||
SYSCTL_UINT(_debug_xhits, OID_AUTO, ipi_page, CTLFLAG_RW, &ipi_page, 0, "");
|
||||
SYSCTL_UINT(_debug_xhits, OID_AUTO, ipi_range, CTLFLAG_RW, &ipi_range, 0, "");
|
||||
SYSCTL_UINT(_debug_xhits, OID_AUTO, ipi_range_size, CTLFLAG_RW,
|
||||
&ipi_range_size, 0, "");
|
||||
|
||||
u_int ipi_masked_global;
|
||||
u_int ipi_masked_page;
|
||||
u_int ipi_masked_range;
|
||||
u_int ipi_masked_range_size;
|
||||
SYSCTL_UINT(_debug_xhits, OID_AUTO, ipi_masked_global, CTLFLAG_RW,
|
||||
&ipi_masked_global, 0, "");
|
||||
SYSCTL_UINT(_debug_xhits, OID_AUTO, ipi_masked_page, CTLFLAG_RW,
|
||||
&ipi_masked_page, 0, "");
|
||||
SYSCTL_UINT(_debug_xhits, OID_AUTO, ipi_masked_range, CTLFLAG_RW,
|
||||
&ipi_masked_range, 0, "");
|
||||
SYSCTL_UINT(_debug_xhits, OID_AUTO, ipi_masked_range_size, CTLFLAG_RW,
|
||||
&ipi_masked_range_size, 0, "");
|
||||
#endif /* COUNT_XINVLTLB_HITS */
|
||||
|
||||
/*
|
||||
* Init and startup IPI.
|
||||
*/
|
||||
void
|
||||
ipi_startup(int apic_id, int vector)
|
||||
{
|
||||
|
||||
/*
|
||||
* first we do an INIT/RESET IPI this INIT IPI might be run, reseting
|
||||
* and running the target CPU. OR this INIT IPI might be latched (P5
|
||||
|
|
@ -1031,52 +1085,8 @@ start_ap(int apic_id)
|
|||
vector, apic_id);
|
||||
lapic_ipi_wait(-1);
|
||||
DELAY(200); /* wait ~200uS */
|
||||
|
||||
/* Wait up to 5 seconds for it to start. */
|
||||
for (ms = 0; ms < 5000; ms++) {
|
||||
if (mp_naps > cpus)
|
||||
return 1; /* return SUCCESS */
|
||||
DELAY(1000);
|
||||
}
|
||||
return 0; /* return FAILURE */
|
||||
}
|
||||
|
||||
#ifdef COUNT_XINVLTLB_HITS
|
||||
u_int xhits_gbl[MAXCPU];
|
||||
u_int xhits_pg[MAXCPU];
|
||||
u_int xhits_rng[MAXCPU];
|
||||
static SYSCTL_NODE(_debug, OID_AUTO, xhits, CTLFLAG_RW, 0, "");
|
||||
SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, global, CTLFLAG_RW, &xhits_gbl,
|
||||
sizeof(xhits_gbl), "IU", "");
|
||||
SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, page, CTLFLAG_RW, &xhits_pg,
|
||||
sizeof(xhits_pg), "IU", "");
|
||||
SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, range, CTLFLAG_RW, &xhits_rng,
|
||||
sizeof(xhits_rng), "IU", "");
|
||||
|
||||
u_int ipi_global;
|
||||
u_int ipi_page;
|
||||
u_int ipi_range;
|
||||
u_int ipi_range_size;
|
||||
SYSCTL_UINT(_debug_xhits, OID_AUTO, ipi_global, CTLFLAG_RW, &ipi_global, 0, "");
|
||||
SYSCTL_UINT(_debug_xhits, OID_AUTO, ipi_page, CTLFLAG_RW, &ipi_page, 0, "");
|
||||
SYSCTL_UINT(_debug_xhits, OID_AUTO, ipi_range, CTLFLAG_RW, &ipi_range, 0, "");
|
||||
SYSCTL_UINT(_debug_xhits, OID_AUTO, ipi_range_size, CTLFLAG_RW,
|
||||
&ipi_range_size, 0, "");
|
||||
|
||||
u_int ipi_masked_global;
|
||||
u_int ipi_masked_page;
|
||||
u_int ipi_masked_range;
|
||||
u_int ipi_masked_range_size;
|
||||
SYSCTL_UINT(_debug_xhits, OID_AUTO, ipi_masked_global, CTLFLAG_RW,
|
||||
&ipi_masked_global, 0, "");
|
||||
SYSCTL_UINT(_debug_xhits, OID_AUTO, ipi_masked_page, CTLFLAG_RW,
|
||||
&ipi_masked_page, 0, "");
|
||||
SYSCTL_UINT(_debug_xhits, OID_AUTO, ipi_masked_range, CTLFLAG_RW,
|
||||
&ipi_masked_range, 0, "");
|
||||
SYSCTL_UINT(_debug_xhits, OID_AUTO, ipi_masked_range_size, CTLFLAG_RW,
|
||||
&ipi_masked_range_size, 0, "");
|
||||
#endif /* COUNT_XINVLTLB_HITS */
|
||||
|
||||
/*
|
||||
* Send an IPI to specified CPU handling the bitmap logic.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -59,6 +59,7 @@ void cpu_add(u_int apic_id, char boot_cpu);
|
|||
void cpustop_handler(void);
|
||||
void cpususpend_handler(void);
|
||||
void init_secondary(void);
|
||||
void ipi_startup(int apic_id, int vector);
|
||||
void ipi_all_but_self(u_int ipi);
|
||||
void ipi_bitmap_handler(struct trapframe frame);
|
||||
void ipi_cpu(int cpu, u_int ipi);
|
||||
|
|
|
|||
|
|
@ -1081,6 +1081,60 @@ start_ap(int apic_id)
|
|||
/* used as a watchpoint to signal AP startup */
|
||||
cpus = mp_naps;
|
||||
|
||||
ipi_startup(apic_id, vector);
|
||||
|
||||
/* Wait up to 5 seconds for it to start. */
|
||||
for (ms = 0; ms < 5000; ms++) {
|
||||
if (mp_naps > cpus)
|
||||
return 1; /* return SUCCESS */
|
||||
DELAY(1000);
|
||||
}
|
||||
return 0; /* return FAILURE */
|
||||
}
|
||||
|
||||
#ifdef COUNT_XINVLTLB_HITS
|
||||
u_int xhits_gbl[MAXCPU];
|
||||
u_int xhits_pg[MAXCPU];
|
||||
u_int xhits_rng[MAXCPU];
|
||||
static SYSCTL_NODE(_debug, OID_AUTO, xhits, CTLFLAG_RW, 0, "");
|
||||
SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, global, CTLFLAG_RW, &xhits_gbl,
|
||||
sizeof(xhits_gbl), "IU", "");
|
||||
SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, page, CTLFLAG_RW, &xhits_pg,
|
||||
sizeof(xhits_pg), "IU", "");
|
||||
SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, range, CTLFLAG_RW, &xhits_rng,
|
||||
sizeof(xhits_rng), "IU", "");
|
||||
|
||||
u_int ipi_global;
|
||||
u_int ipi_page;
|
||||
u_int ipi_range;
|
||||
u_int ipi_range_size;
|
||||
SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_global, CTLFLAG_RW, &ipi_global, 0, "");
|
||||
SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_page, CTLFLAG_RW, &ipi_page, 0, "");
|
||||
SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_range, CTLFLAG_RW, &ipi_range, 0, "");
|
||||
SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_range_size, CTLFLAG_RW, &ipi_range_size,
|
||||
0, "");
|
||||
|
||||
u_int ipi_masked_global;
|
||||
u_int ipi_masked_page;
|
||||
u_int ipi_masked_range;
|
||||
u_int ipi_masked_range_size;
|
||||
SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_masked_global, CTLFLAG_RW,
|
||||
&ipi_masked_global, 0, "");
|
||||
SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_masked_page, CTLFLAG_RW,
|
||||
&ipi_masked_page, 0, "");
|
||||
SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_masked_range, CTLFLAG_RW,
|
||||
&ipi_masked_range, 0, "");
|
||||
SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_masked_range_size, CTLFLAG_RW,
|
||||
&ipi_masked_range_size, 0, "");
|
||||
#endif /* COUNT_XINVLTLB_HITS */
|
||||
|
||||
/*
|
||||
* Init and startup IPI.
|
||||
*/
|
||||
void
|
||||
ipi_startup(int apic_id, int vector)
|
||||
{
|
||||
|
||||
/*
|
||||
* first we do an INIT/RESET IPI this INIT IPI might be run, reseting
|
||||
* and running the target CPU. OR this INIT IPI might be latched (P5
|
||||
|
|
@ -1131,52 +1185,8 @@ start_ap(int apic_id)
|
|||
vector, apic_id);
|
||||
lapic_ipi_wait(-1);
|
||||
DELAY(200); /* wait ~200uS */
|
||||
|
||||
/* Wait up to 5 seconds for it to start. */
|
||||
for (ms = 0; ms < 5000; ms++) {
|
||||
if (mp_naps > cpus)
|
||||
return 1; /* return SUCCESS */
|
||||
DELAY(1000);
|
||||
}
|
||||
return 0; /* return FAILURE */
|
||||
}
|
||||
|
||||
#ifdef COUNT_XINVLTLB_HITS
|
||||
u_int xhits_gbl[MAXCPU];
|
||||
u_int xhits_pg[MAXCPU];
|
||||
u_int xhits_rng[MAXCPU];
|
||||
static SYSCTL_NODE(_debug, OID_AUTO, xhits, CTLFLAG_RW, 0, "");
|
||||
SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, global, CTLFLAG_RW, &xhits_gbl,
|
||||
sizeof(xhits_gbl), "IU", "");
|
||||
SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, page, CTLFLAG_RW, &xhits_pg,
|
||||
sizeof(xhits_pg), "IU", "");
|
||||
SYSCTL_OPAQUE(_debug_xhits, OID_AUTO, range, CTLFLAG_RW, &xhits_rng,
|
||||
sizeof(xhits_rng), "IU", "");
|
||||
|
||||
u_int ipi_global;
|
||||
u_int ipi_page;
|
||||
u_int ipi_range;
|
||||
u_int ipi_range_size;
|
||||
SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_global, CTLFLAG_RW, &ipi_global, 0, "");
|
||||
SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_page, CTLFLAG_RW, &ipi_page, 0, "");
|
||||
SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_range, CTLFLAG_RW, &ipi_range, 0, "");
|
||||
SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_range_size, CTLFLAG_RW, &ipi_range_size,
|
||||
0, "");
|
||||
|
||||
u_int ipi_masked_global;
|
||||
u_int ipi_masked_page;
|
||||
u_int ipi_masked_range;
|
||||
u_int ipi_masked_range_size;
|
||||
SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_masked_global, CTLFLAG_RW,
|
||||
&ipi_masked_global, 0, "");
|
||||
SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_masked_page, CTLFLAG_RW,
|
||||
&ipi_masked_page, 0, "");
|
||||
SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_masked_range, CTLFLAG_RW,
|
||||
&ipi_masked_range, 0, "");
|
||||
SYSCTL_INT(_debug_xhits, OID_AUTO, ipi_masked_range_size, CTLFLAG_RW,
|
||||
&ipi_masked_range_size, 0, "");
|
||||
#endif /* COUNT_XINVLTLB_HITS */
|
||||
|
||||
/*
|
||||
* Send an IPI to specified CPU handling the bitmap logic.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@ void cpustop_handler(void);
|
|||
void cpususpend_handler(void);
|
||||
#endif
|
||||
void init_secondary(void);
|
||||
void ipi_startup(int apic_id, int vector);
|
||||
void ipi_all_but_self(u_int ipi);
|
||||
#ifndef XEN
|
||||
void ipi_bitmap_handler(struct trapframe frame);
|
||||
|
|
|
|||
|
|
@ -118,49 +118,7 @@ acpi_wakeup_ap(struct acpi_softc *sc, int cpu)
|
|||
WAKECODE_FIXUP(wakeup_gdt + 2, uint64_t,
|
||||
susppcbs[cpu]->pcb_gdt.rd_base);
|
||||
|
||||
/* do an INIT IPI: assert RESET */
|
||||
lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE |
|
||||
APIC_LEVEL_ASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_INIT, apic_id);
|
||||
|
||||
/* wait for pending status end */
|
||||
lapic_ipi_wait(-1);
|
||||
|
||||
/* do an INIT IPI: deassert RESET */
|
||||
lapic_ipi_raw(APIC_DEST_ALLESELF | APIC_TRIGMOD_LEVEL |
|
||||
APIC_LEVEL_DEASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_INIT, 0);
|
||||
|
||||
/* wait for pending status end */
|
||||
DELAY(10000); /* wait ~10mS */
|
||||
lapic_ipi_wait(-1);
|
||||
|
||||
/*
|
||||
* next we do a STARTUP IPI: the previous INIT IPI might still be
|
||||
* latched, (P5 bug) this 1st STARTUP would then terminate
|
||||
* immediately, and the previously started INIT IPI would continue. OR
|
||||
* the previous INIT IPI has already run. and this STARTUP IPI will
|
||||
* run. OR the previous INIT IPI was ignored. and this STARTUP IPI
|
||||
* will run.
|
||||
*/
|
||||
|
||||
/* do a STARTUP IPI */
|
||||
lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE |
|
||||
APIC_LEVEL_DEASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_STARTUP |
|
||||
vector, apic_id);
|
||||
lapic_ipi_wait(-1);
|
||||
DELAY(200); /* wait ~200uS */
|
||||
|
||||
/*
|
||||
* finally we do a 2nd STARTUP IPI: this 2nd STARTUP IPI should run IF
|
||||
* the previous STARTUP IPI was cancelled by a latched INIT IPI. OR
|
||||
* this STARTUP IPI will be ignored, as only ONE STARTUP IPI is
|
||||
* recognized after hardware RESET or INIT IPI.
|
||||
*/
|
||||
|
||||
lapic_ipi_raw(APIC_DEST_DESTFLD | APIC_TRIGMOD_EDGE |
|
||||
APIC_LEVEL_DEASSERT | APIC_DESTMODE_PHY | APIC_DELMODE_STARTUP |
|
||||
vector, apic_id);
|
||||
lapic_ipi_wait(-1);
|
||||
DELAY(200); /* wait ~200uS */
|
||||
ipi_startup(apic_id, vector);
|
||||
|
||||
/* Wait up to 5 seconds for it to resume. */
|
||||
for (ms = 0; ms < 5000; ms++) {
|
||||
|
|
|
|||
Loading…
Reference in a new issue