new code to control other CPUs: stop_cpus()/restart_cpus()/_Xstopcpu

this code is controlled by smptests.h: TEST_CPUSTOP, OFF by default

new code for handling mixed-mode 8259/APIC programming without 'ExtInt'
this code is controlled by smptests.h: TEST_ALTTIMER, ON by default
This commit is contained in:
Steve Passe 1997-07-13 01:22:48 +00:00
parent c064ef9175
commit 7503ccc1c8
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=27353
11 changed files with 234 additions and 548 deletions

View File

@ -23,7 +23,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
* $Id: db_interface.c,v 1.31 1997/07/06 23:25:46 fsmp Exp $
* $Id: db_interface.c,v 1.9 1997/07/13 00:48:28 smp Exp smp $
*/
/*
@ -139,9 +139,9 @@ kdb_trap(type, code, regs)
cnpollc(TRUE);
#if defined(SMP) && defined(TEST_CPUSTOP)
/* we stop all CPUs except ourselves (obviously) */
/* XXX FIXME: we stop all CPUs except ourselves (obviously) */
stop_cpus(other_cpus);
#endif /* SMP && TEST_CPUSTOP */
#endif /** SMP && TEST_CPUSTOP */
(void) setjmp(db_global_jmpbuf);
db_global_jmpbuf_valid = TRUE;
@ -152,16 +152,14 @@ kdb_trap(type, code, regs)
db_global_jmpbuf_valid = FALSE;
#if defined(SMP) && defined(TEST_CPUSTOP)
/* restart all the CPUs we previously stopped */
#if 0
/* XXX FIXME: restart all the CPUs we previously stopped */
if (stopped_cpus != other_cpus) {
db_printf("whoa, other_cpus: 0x%08x, stopped_cpus: 0x%08x\n",
other_cpus, stopped_cpus);
cngetc();
}
#endif
restart_cpus(stopped_cpus);
#endif /* SMP && TEST_CPUSTOP */
#endif /** SMP && TEST_CPUSTOP */
cnpollc(FALSE);

View File

@ -22,7 +22,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: mp_machdep.c,v 1.7 1997/07/08 23:42:28 smp Exp smp $
* $Id: mp_machdep.c,v 1.14 1997/07/13 00:42:14 smp Exp smp $
*/
#include "opt_smp.h"
@ -45,16 +45,12 @@
#include <machine/mpapic.h>
#include <machine/cpufunc.h>
#include <machine/segments.h>
#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, TEST_CPUSTOP */
#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, TEST_CPUSTOP _TEST1 */
#include <machine/tss.h>
#include <machine/specialreg.h>
#include <i386/i386/cons.h> /* cngetc() */
#if defined(TEST_CPUSTOP)
void db_printf __P((const char *fmt, ...));
#endif /* TEST_CPUSTOP */
#if defined(APIC_IO)
#include <machine/md_var.h> /* setidt() */
#include <i386/isa/icu.h> /* IPIs */
@ -434,14 +430,8 @@ bsp_apic_configure(void)
temp &= ~APIC_LVT_M; /* clear the mask */
lapic.lvt_lint1 = temp;
#if defined(TEST_CPUSTOP)
printf(">>> CPU%02d bsp_apic_configure() lint0: 0x%08x\n",
cpuid, lapic.lvt_lint0);
printf(">>> lint1: 0x%08x\n",
lapic.lvt_lint1);
printf(">>> TPR: 0x%08x\n", lapic.tpr);
printf(">>> SVR: 0x%08x\n", lapic.svr);
#endif /* TEST_CPUSTOP */
if (bootverbose)
apic_dump();
}
#endif /* APIC_IO */
@ -479,6 +469,7 @@ mp_enable(u_int boot_addr)
default_mp_table(x);
#if defined(APIC_IO)
/* fill the LOGICAL io_apic_versions table */
for (apic = 0; apic < mp_napics; ++apic) {
ux = io_apic_read(apic, IOAPIC_VER);
@ -490,6 +481,10 @@ mp_enable(u_int boot_addr)
if (io_apic_setup(apic) < 0)
panic("IO APIC setup failure");
/* install a 'Spurious INTerrupt' vector */
setidt(XSPURIOUSINT_OFFSET, Xspuriousint,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
/* install an inter-CPU IPI for TLB invalidation */
setidt(XINVLTLB_OFFSET, Xinvltlb,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
@ -498,11 +493,14 @@ mp_enable(u_int boot_addr)
/* install an inter-CPU IPI for CPU stop/restart */
setidt(XCPUSTOP_OFFSET, Xcpustop,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
#endif /** TEST_CPUSTOP */
#if defined(TEST_TEST1)
/* install a 'Spurious INTerrupt' vector */
setidt(XSPURIOUSINT_OFFSET, Xspuriousint,
setidt(XTEST1_OFFSET, Xtest1,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
#endif /* TEST_CPUSTOP */
#endif /** TEST_TEST1 */
#endif /* APIC_IO */
/* start each Application Processor */
@ -1741,6 +1739,10 @@ invltlb(void)
#if defined(TEST_CPUSTOP)
#if defined(DEBUG_CPUSTOP)
void db_printf __P((const char *fmt, ...));
#endif /* DEBUG_CPUSTOP */
/*
* When called the executing CPU will send an IPI to all other CPUs
* requesting that they halt execution.
@ -1757,65 +1759,32 @@ invltlb(void)
*
* XXX FIXME: this is not MP-safe, needs a lock to prevent multiple CPUs
* from executing at same time.
*/
extern int cshits[4];
extern int lhits[4];
extern int sihits;
int
stop_cpus( u_int map )
{
#if 1
int x, y;
#endif
if (!smp_active)
return 0;
/* send IPI to all CPUs in map */
#if defined(DEBUG_CPUSTOP)
#if 0
POSTCODE(0xF0);
#endif
db_printf("\nCPU%d stopping CPUs: 0x%08x\n", cpuid, map);
db_printf("b4 stop: cshits: %d, %d, mplock: 0x%08x, lhits: %d, %d, sihits: %d\n",
cshits[0], cshits[1], mp_lock, lhits[0], lhits[1], sihits);
#endif /* DEBUG_CPUSTOP */
stopped_cpus = 0;
#if 0
/* send the Xcpustop IPI to all CPUs in map */
selected_apic_ipi(map, XCPUSTOP_OFFSET, APIC_DELMODE_FIXED);
#else
all_but_self_ipi(XCPUSTOP_OFFSET);
#endif
#if defined(DEBUG_CPUSTOP)
db_printf(" spin\n");
#endif /* DEBUG_CPUSTOP */
#if 0 /** */
y = 0;
while (stopped_cpus != map) {
#if 0
while (stopped_cpus != map)
/* spin */ ;
#else
POSTCODE_LO(stopped_cpus & 0x0f);
#define MAX_SPIN 20000000
for ( x = 0; x < MAX_SPIN; ++x )
;
if (++y > 20) {
stopped_cpus = map;
break;
}
POSTCODE_LO(0x0f);
for ( x = 0; x < MAX_SPIN; ++x )
;
#endif
}
#endif /** 0 */
#if defined(DEBUG_CPUSTOP)
db_printf(" spun\nstopped, sihits: %d\n", sihits);
cngetc();
db_printf(" spun\nstopped\n");
#endif /* DEBUG_CPUSTOP */
return 1;
@ -1842,30 +1811,20 @@ restart_cpus( u_int map )
return 0;
#if defined(DEBUG_CPUSTOP)
#if 0
POSTCODE(0x90);
#endif
db_printf("\nCPU%d restarting CPUs: 0x%08x (0x%08x)\n",
cpuid, map, stopped_cpus);
db_printf("b4 restart: cshits: %d, %d, mplock: 0x%08x, lhits: %d, %d, sihits: %d\n",
cshits[0], cshits[1], mp_lock, lhits[0], lhits[1], sihits);
#endif /* DEBUG_CPUSTOP */
started_cpus = map; /* signal other cpus to restart */
#if 0 /** */
while (started_cpus) /* wait for each to clear its bit */
/* spin */ ;
#endif /** 0 */
#if defined(DEBUG_CPUSTOP)
#if 0
POSTCODE(0xA0);
#endif
db_printf(" restarted\n");
#endif /* DEBUG_CPUSTOP */
return 1;
}
#endif /* TEST_CPUSTOP */
#endif /** TEST_CPUSTOP */

View File

@ -22,7 +22,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: mp_machdep.c,v 1.7 1997/07/08 23:42:28 smp Exp smp $
* $Id: mp_machdep.c,v 1.14 1997/07/13 00:42:14 smp Exp smp $
*/
#include "opt_smp.h"
@ -45,16 +45,12 @@
#include <machine/mpapic.h>
#include <machine/cpufunc.h>
#include <machine/segments.h>
#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, TEST_CPUSTOP */
#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, TEST_CPUSTOP _TEST1 */
#include <machine/tss.h>
#include <machine/specialreg.h>
#include <i386/i386/cons.h> /* cngetc() */
#if defined(TEST_CPUSTOP)
void db_printf __P((const char *fmt, ...));
#endif /* TEST_CPUSTOP */
#if defined(APIC_IO)
#include <machine/md_var.h> /* setidt() */
#include <i386/isa/icu.h> /* IPIs */
@ -434,14 +430,8 @@ bsp_apic_configure(void)
temp &= ~APIC_LVT_M; /* clear the mask */
lapic.lvt_lint1 = temp;
#if defined(TEST_CPUSTOP)
printf(">>> CPU%02d bsp_apic_configure() lint0: 0x%08x\n",
cpuid, lapic.lvt_lint0);
printf(">>> lint1: 0x%08x\n",
lapic.lvt_lint1);
printf(">>> TPR: 0x%08x\n", lapic.tpr);
printf(">>> SVR: 0x%08x\n", lapic.svr);
#endif /* TEST_CPUSTOP */
if (bootverbose)
apic_dump();
}
#endif /* APIC_IO */
@ -479,6 +469,7 @@ mp_enable(u_int boot_addr)
default_mp_table(x);
#if defined(APIC_IO)
/* fill the LOGICAL io_apic_versions table */
for (apic = 0; apic < mp_napics; ++apic) {
ux = io_apic_read(apic, IOAPIC_VER);
@ -490,6 +481,10 @@ mp_enable(u_int boot_addr)
if (io_apic_setup(apic) < 0)
panic("IO APIC setup failure");
/* install a 'Spurious INTerrupt' vector */
setidt(XSPURIOUSINT_OFFSET, Xspuriousint,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
/* install an inter-CPU IPI for TLB invalidation */
setidt(XINVLTLB_OFFSET, Xinvltlb,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
@ -498,11 +493,14 @@ mp_enable(u_int boot_addr)
/* install an inter-CPU IPI for CPU stop/restart */
setidt(XCPUSTOP_OFFSET, Xcpustop,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
#endif /** TEST_CPUSTOP */
#if defined(TEST_TEST1)
/* install a 'Spurious INTerrupt' vector */
setidt(XSPURIOUSINT_OFFSET, Xspuriousint,
setidt(XTEST1_OFFSET, Xtest1,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
#endif /* TEST_CPUSTOP */
#endif /** TEST_TEST1 */
#endif /* APIC_IO */
/* start each Application Processor */
@ -1741,6 +1739,10 @@ invltlb(void)
#if defined(TEST_CPUSTOP)
#if defined(DEBUG_CPUSTOP)
void db_printf __P((const char *fmt, ...));
#endif /* DEBUG_CPUSTOP */
/*
* When called the executing CPU will send an IPI to all other CPUs
* requesting that they halt execution.
@ -1757,65 +1759,32 @@ invltlb(void)
*
* XXX FIXME: this is not MP-safe, needs a lock to prevent multiple CPUs
* from executing at same time.
*/
extern int cshits[4];
extern int lhits[4];
extern int sihits;
int
stop_cpus( u_int map )
{
#if 1
int x, y;
#endif
if (!smp_active)
return 0;
/* send IPI to all CPUs in map */
#if defined(DEBUG_CPUSTOP)
#if 0
POSTCODE(0xF0);
#endif
db_printf("\nCPU%d stopping CPUs: 0x%08x\n", cpuid, map);
db_printf("b4 stop: cshits: %d, %d, mplock: 0x%08x, lhits: %d, %d, sihits: %d\n",
cshits[0], cshits[1], mp_lock, lhits[0], lhits[1], sihits);
#endif /* DEBUG_CPUSTOP */
stopped_cpus = 0;
#if 0
/* send the Xcpustop IPI to all CPUs in map */
selected_apic_ipi(map, XCPUSTOP_OFFSET, APIC_DELMODE_FIXED);
#else
all_but_self_ipi(XCPUSTOP_OFFSET);
#endif
#if defined(DEBUG_CPUSTOP)
db_printf(" spin\n");
#endif /* DEBUG_CPUSTOP */
#if 0 /** */
y = 0;
while (stopped_cpus != map) {
#if 0
while (stopped_cpus != map)
/* spin */ ;
#else
POSTCODE_LO(stopped_cpus & 0x0f);
#define MAX_SPIN 20000000
for ( x = 0; x < MAX_SPIN; ++x )
;
if (++y > 20) {
stopped_cpus = map;
break;
}
POSTCODE_LO(0x0f);
for ( x = 0; x < MAX_SPIN; ++x )
;
#endif
}
#endif /** 0 */
#if defined(DEBUG_CPUSTOP)
db_printf(" spun\nstopped, sihits: %d\n", sihits);
cngetc();
db_printf(" spun\nstopped\n");
#endif /* DEBUG_CPUSTOP */
return 1;
@ -1842,30 +1811,20 @@ restart_cpus( u_int map )
return 0;
#if defined(DEBUG_CPUSTOP)
#if 0
POSTCODE(0x90);
#endif
db_printf("\nCPU%d restarting CPUs: 0x%08x (0x%08x)\n",
cpuid, map, stopped_cpus);
db_printf("b4 restart: cshits: %d, %d, mplock: 0x%08x, lhits: %d, %d, sihits: %d\n",
cshits[0], cshits[1], mp_lock, lhits[0], lhits[1], sihits);
#endif /* DEBUG_CPUSTOP */
started_cpus = map; /* signal other cpus to restart */
#if 0 /** */
while (started_cpus) /* wait for each to clear its bit */
/* spin */ ;
#endif /** 0 */
#if defined(DEBUG_CPUSTOP)
#if 0
POSTCODE(0xA0);
#endif
db_printf(" restarted\n");
#endif /* DEBUG_CPUSTOP */
return 1;
}
#endif /* TEST_CPUSTOP */
#endif /** TEST_CPUSTOP */

View File

@ -22,7 +22,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: mp_machdep.c,v 1.7 1997/07/08 23:42:28 smp Exp smp $
* $Id: mp_machdep.c,v 1.14 1997/07/13 00:42:14 smp Exp smp $
*/
#include "opt_smp.h"
@ -45,16 +45,12 @@
#include <machine/mpapic.h>
#include <machine/cpufunc.h>
#include <machine/segments.h>
#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, TEST_CPUSTOP */
#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, TEST_CPUSTOP _TEST1 */
#include <machine/tss.h>
#include <machine/specialreg.h>
#include <i386/i386/cons.h> /* cngetc() */
#if defined(TEST_CPUSTOP)
void db_printf __P((const char *fmt, ...));
#endif /* TEST_CPUSTOP */
#if defined(APIC_IO)
#include <machine/md_var.h> /* setidt() */
#include <i386/isa/icu.h> /* IPIs */
@ -434,14 +430,8 @@ bsp_apic_configure(void)
temp &= ~APIC_LVT_M; /* clear the mask */
lapic.lvt_lint1 = temp;
#if defined(TEST_CPUSTOP)
printf(">>> CPU%02d bsp_apic_configure() lint0: 0x%08x\n",
cpuid, lapic.lvt_lint0);
printf(">>> lint1: 0x%08x\n",
lapic.lvt_lint1);
printf(">>> TPR: 0x%08x\n", lapic.tpr);
printf(">>> SVR: 0x%08x\n", lapic.svr);
#endif /* TEST_CPUSTOP */
if (bootverbose)
apic_dump();
}
#endif /* APIC_IO */
@ -479,6 +469,7 @@ mp_enable(u_int boot_addr)
default_mp_table(x);
#if defined(APIC_IO)
/* fill the LOGICAL io_apic_versions table */
for (apic = 0; apic < mp_napics; ++apic) {
ux = io_apic_read(apic, IOAPIC_VER);
@ -490,6 +481,10 @@ mp_enable(u_int boot_addr)
if (io_apic_setup(apic) < 0)
panic("IO APIC setup failure");
/* install a 'Spurious INTerrupt' vector */
setidt(XSPURIOUSINT_OFFSET, Xspuriousint,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
/* install an inter-CPU IPI for TLB invalidation */
setidt(XINVLTLB_OFFSET, Xinvltlb,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
@ -498,11 +493,14 @@ mp_enable(u_int boot_addr)
/* install an inter-CPU IPI for CPU stop/restart */
setidt(XCPUSTOP_OFFSET, Xcpustop,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
#endif /** TEST_CPUSTOP */
#if defined(TEST_TEST1)
/* install a 'Spurious INTerrupt' vector */
setidt(XSPURIOUSINT_OFFSET, Xspuriousint,
setidt(XTEST1_OFFSET, Xtest1,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
#endif /* TEST_CPUSTOP */
#endif /** TEST_TEST1 */
#endif /* APIC_IO */
/* start each Application Processor */
@ -1741,6 +1739,10 @@ invltlb(void)
#if defined(TEST_CPUSTOP)
#if defined(DEBUG_CPUSTOP)
void db_printf __P((const char *fmt, ...));
#endif /* DEBUG_CPUSTOP */
/*
* When called the executing CPU will send an IPI to all other CPUs
* requesting that they halt execution.
@ -1757,65 +1759,32 @@ invltlb(void)
*
* XXX FIXME: this is not MP-safe, needs a lock to prevent multiple CPUs
* from executing at same time.
*/
extern int cshits[4];
extern int lhits[4];
extern int sihits;
int
stop_cpus( u_int map )
{
#if 1
int x, y;
#endif
if (!smp_active)
return 0;
/* send IPI to all CPUs in map */
#if defined(DEBUG_CPUSTOP)
#if 0
POSTCODE(0xF0);
#endif
db_printf("\nCPU%d stopping CPUs: 0x%08x\n", cpuid, map);
db_printf("b4 stop: cshits: %d, %d, mplock: 0x%08x, lhits: %d, %d, sihits: %d\n",
cshits[0], cshits[1], mp_lock, lhits[0], lhits[1], sihits);
#endif /* DEBUG_CPUSTOP */
stopped_cpus = 0;
#if 0
/* send the Xcpustop IPI to all CPUs in map */
selected_apic_ipi(map, XCPUSTOP_OFFSET, APIC_DELMODE_FIXED);
#else
all_but_self_ipi(XCPUSTOP_OFFSET);
#endif
#if defined(DEBUG_CPUSTOP)
db_printf(" spin\n");
#endif /* DEBUG_CPUSTOP */
#if 0 /** */
y = 0;
while (stopped_cpus != map) {
#if 0
while (stopped_cpus != map)
/* spin */ ;
#else
POSTCODE_LO(stopped_cpus & 0x0f);
#define MAX_SPIN 20000000
for ( x = 0; x < MAX_SPIN; ++x )
;
if (++y > 20) {
stopped_cpus = map;
break;
}
POSTCODE_LO(0x0f);
for ( x = 0; x < MAX_SPIN; ++x )
;
#endif
}
#endif /** 0 */
#if defined(DEBUG_CPUSTOP)
db_printf(" spun\nstopped, sihits: %d\n", sihits);
cngetc();
db_printf(" spun\nstopped\n");
#endif /* DEBUG_CPUSTOP */
return 1;
@ -1842,30 +1811,20 @@ restart_cpus( u_int map )
return 0;
#if defined(DEBUG_CPUSTOP)
#if 0
POSTCODE(0x90);
#endif
db_printf("\nCPU%d restarting CPUs: 0x%08x (0x%08x)\n",
cpuid, map, stopped_cpus);
db_printf("b4 restart: cshits: %d, %d, mplock: 0x%08x, lhits: %d, %d, sihits: %d\n",
cshits[0], cshits[1], mp_lock, lhits[0], lhits[1], sihits);
#endif /* DEBUG_CPUSTOP */
started_cpus = map; /* signal other cpus to restart */
#if 0 /** */
while (started_cpus) /* wait for each to clear its bit */
/* spin */ ;
#endif /** 0 */
#if defined(DEBUG_CPUSTOP)
#if 0
POSTCODE(0xA0);
#endif
db_printf(" restarted\n");
#endif /* DEBUG_CPUSTOP */
return 1;
}
#endif /* TEST_CPUSTOP */
#endif /** TEST_CPUSTOP */

View File

@ -23,7 +23,7 @@
* any improvements or extensions that they make and grant Carnegie the
* rights to redistribute these changes.
*
* $Id: db_interface.c,v 1.31 1997/07/06 23:25:46 fsmp Exp $
* $Id: db_interface.c,v 1.9 1997/07/13 00:48:28 smp Exp smp $
*/
/*
@ -139,9 +139,9 @@ kdb_trap(type, code, regs)
cnpollc(TRUE);
#if defined(SMP) && defined(TEST_CPUSTOP)
/* we stop all CPUs except ourselves (obviously) */
/* XXX FIXME: we stop all CPUs except ourselves (obviously) */
stop_cpus(other_cpus);
#endif /* SMP && TEST_CPUSTOP */
#endif /** SMP && TEST_CPUSTOP */
(void) setjmp(db_global_jmpbuf);
db_global_jmpbuf_valid = TRUE;
@ -152,16 +152,14 @@ kdb_trap(type, code, regs)
db_global_jmpbuf_valid = FALSE;
#if defined(SMP) && defined(TEST_CPUSTOP)
/* restart all the CPUs we previously stopped */
#if 0
/* XXX FIXME: restart all the CPUs we previously stopped */
if (stopped_cpus != other_cpus) {
db_printf("whoa, other_cpus: 0x%08x, stopped_cpus: 0x%08x\n",
other_cpus, stopped_cpus);
cngetc();
}
#endif
restart_cpus(stopped_cpus);
#endif /* SMP && TEST_CPUSTOP */
#endif /** SMP && TEST_CPUSTOP */
cnpollc(FALSE);

View File

@ -22,7 +22,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: mp_machdep.c,v 1.7 1997/07/08 23:42:28 smp Exp smp $
* $Id: mp_machdep.c,v 1.14 1997/07/13 00:42:14 smp Exp smp $
*/
#include "opt_smp.h"
@ -45,16 +45,12 @@
#include <machine/mpapic.h>
#include <machine/cpufunc.h>
#include <machine/segments.h>
#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, TEST_CPUSTOP */
#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, TEST_CPUSTOP _TEST1 */
#include <machine/tss.h>
#include <machine/specialreg.h>
#include <i386/i386/cons.h> /* cngetc() */
#if defined(TEST_CPUSTOP)
void db_printf __P((const char *fmt, ...));
#endif /* TEST_CPUSTOP */
#if defined(APIC_IO)
#include <machine/md_var.h> /* setidt() */
#include <i386/isa/icu.h> /* IPIs */
@ -434,14 +430,8 @@ bsp_apic_configure(void)
temp &= ~APIC_LVT_M; /* clear the mask */
lapic.lvt_lint1 = temp;
#if defined(TEST_CPUSTOP)
printf(">>> CPU%02d bsp_apic_configure() lint0: 0x%08x\n",
cpuid, lapic.lvt_lint0);
printf(">>> lint1: 0x%08x\n",
lapic.lvt_lint1);
printf(">>> TPR: 0x%08x\n", lapic.tpr);
printf(">>> SVR: 0x%08x\n", lapic.svr);
#endif /* TEST_CPUSTOP */
if (bootverbose)
apic_dump();
}
#endif /* APIC_IO */
@ -479,6 +469,7 @@ mp_enable(u_int boot_addr)
default_mp_table(x);
#if defined(APIC_IO)
/* fill the LOGICAL io_apic_versions table */
for (apic = 0; apic < mp_napics; ++apic) {
ux = io_apic_read(apic, IOAPIC_VER);
@ -490,6 +481,10 @@ mp_enable(u_int boot_addr)
if (io_apic_setup(apic) < 0)
panic("IO APIC setup failure");
/* install a 'Spurious INTerrupt' vector */
setidt(XSPURIOUSINT_OFFSET, Xspuriousint,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
/* install an inter-CPU IPI for TLB invalidation */
setidt(XINVLTLB_OFFSET, Xinvltlb,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
@ -498,11 +493,14 @@ mp_enable(u_int boot_addr)
/* install an inter-CPU IPI for CPU stop/restart */
setidt(XCPUSTOP_OFFSET, Xcpustop,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
#endif /** TEST_CPUSTOP */
#if defined(TEST_TEST1)
/* install a 'Spurious INTerrupt' vector */
setidt(XSPURIOUSINT_OFFSET, Xspuriousint,
setidt(XTEST1_OFFSET, Xtest1,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
#endif /* TEST_CPUSTOP */
#endif /** TEST_TEST1 */
#endif /* APIC_IO */
/* start each Application Processor */
@ -1741,6 +1739,10 @@ invltlb(void)
#if defined(TEST_CPUSTOP)
#if defined(DEBUG_CPUSTOP)
void db_printf __P((const char *fmt, ...));
#endif /* DEBUG_CPUSTOP */
/*
* When called the executing CPU will send an IPI to all other CPUs
* requesting that they halt execution.
@ -1757,65 +1759,32 @@ invltlb(void)
*
* XXX FIXME: this is not MP-safe, needs a lock to prevent multiple CPUs
* from executing at same time.
*/
extern int cshits[4];
extern int lhits[4];
extern int sihits;
int
stop_cpus( u_int map )
{
#if 1
int x, y;
#endif
if (!smp_active)
return 0;
/* send IPI to all CPUs in map */
#if defined(DEBUG_CPUSTOP)
#if 0
POSTCODE(0xF0);
#endif
db_printf("\nCPU%d stopping CPUs: 0x%08x\n", cpuid, map);
db_printf("b4 stop: cshits: %d, %d, mplock: 0x%08x, lhits: %d, %d, sihits: %d\n",
cshits[0], cshits[1], mp_lock, lhits[0], lhits[1], sihits);
#endif /* DEBUG_CPUSTOP */
stopped_cpus = 0;
#if 0
/* send the Xcpustop IPI to all CPUs in map */
selected_apic_ipi(map, XCPUSTOP_OFFSET, APIC_DELMODE_FIXED);
#else
all_but_self_ipi(XCPUSTOP_OFFSET);
#endif
#if defined(DEBUG_CPUSTOP)
db_printf(" spin\n");
#endif /* DEBUG_CPUSTOP */
#if 0 /** */
y = 0;
while (stopped_cpus != map) {
#if 0
while (stopped_cpus != map)
/* spin */ ;
#else
POSTCODE_LO(stopped_cpus & 0x0f);
#define MAX_SPIN 20000000
for ( x = 0; x < MAX_SPIN; ++x )
;
if (++y > 20) {
stopped_cpus = map;
break;
}
POSTCODE_LO(0x0f);
for ( x = 0; x < MAX_SPIN; ++x )
;
#endif
}
#endif /** 0 */
#if defined(DEBUG_CPUSTOP)
db_printf(" spun\nstopped, sihits: %d\n", sihits);
cngetc();
db_printf(" spun\nstopped\n");
#endif /* DEBUG_CPUSTOP */
return 1;
@ -1842,30 +1811,20 @@ restart_cpus( u_int map )
return 0;
#if defined(DEBUG_CPUSTOP)
#if 0
POSTCODE(0x90);
#endif
db_printf("\nCPU%d restarting CPUs: 0x%08x (0x%08x)\n",
cpuid, map, stopped_cpus);
db_printf("b4 restart: cshits: %d, %d, mplock: 0x%08x, lhits: %d, %d, sihits: %d\n",
cshits[0], cshits[1], mp_lock, lhits[0], lhits[1], sihits);
#endif /* DEBUG_CPUSTOP */
started_cpus = map; /* signal other cpus to restart */
#if 0 /** */
while (started_cpus) /* wait for each to clear its bit */
/* spin */ ;
#endif /** 0 */
#if defined(DEBUG_CPUSTOP)
#if 0
POSTCODE(0xA0);
#endif
db_printf(" restarted\n");
#endif /* DEBUG_CPUSTOP */
return 1;
}
#endif /* TEST_CPUSTOP */
#endif /** TEST_CPUSTOP */

View File

@ -22,7 +22,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: mpapic.c,v 1.6 1997/07/08 23:42:28 smp Exp smp $
* $Id: mpapic.c,v 1.10 1997/07/13 00:42:14 smp Exp smp $
*/
#include "opt_smp.h"
@ -33,16 +33,12 @@
#include <machine/smp.h>
#include <machine/mpapic.h>
#include <machine/smptests.h> /** TEST_LOPRIO, TEST_IPI, TEST_CPUSTOP */
#include <machine/smptests.h> /** TEST_LOPRIO, TEST_IPI, TEST_CPUSTOP, TEST_ALTTIMER */
#include <machine/cpufunc.h>
#include <machine/segments.h>
#include <i386/isa/intr_machdep.h> /* Xspuriousint() */
#if defined(TEST_CPUSTOP)
void db_printf __P((const char *fmt, ...));
#endif /* TEST_CPUSTOP */
/* EISA Edge/Level trigger control registers */
#define ELCR0 0x4d0 /* eisa irq 0-7 */
#define ELCR1 0x4d1 /* eisa irq 8-15 */
@ -104,23 +100,37 @@ apic_initialize(void)
temp |= APIC_SVR_SWEN; /* software enable APIC */
temp &= ~APIC_SVR_FOCUS; /* enable 'focus processor' */
#if defined(TEST_CPUSTOP)
/* set the 'spurious INT' vector */
if ((XSPURIOUSINT_OFFSET & APIC_SVR_VEC_FIX) != APIC_SVR_VEC_FIX)
panic("bad XSPURIOUSINT_OFFSET: 0x%08x", XSPURIOUSINT_OFFSET);
temp &= ~APIC_SVR_VEC_PROG; /* clear (programmable) vector field */
temp |= (XSPURIOUSINT_OFFSET & APIC_SVR_VEC_PROG);
#endif /* TEST_CPUSTOP */
#if defined(TEST_TEST1)
if (cpuid == GUARD_CPU) {
temp &= ~APIC_SVR_SWEN; /* software DISABLE APIC */
}
#endif /** TEST_TEST1 */
lapic.svr = temp;
#if defined(TEST_CPUSTOP)
printf(">>> CPU%02d apic_initialize() lint0: 0x%08x\n",
if (bootverbose)
apic_dump();
}
/*
* dump contents of local APIC registers
*/
void
apic_dump(void)
{
printf("SMP: CPU%02d bsp_apic_configure() lint0: 0x%08x\n",
cpuid, lapic.lvt_lint0);
printf(">>> lint1: 0x%08x\n",
printf(" lint1: 0x%08x\n",
lapic.lvt_lint1);
printf(">>> TPR: 0x%08x\n", lapic.tpr);
printf(">>> SVR: 0x%08x\n", lapic.svr);
#endif /* TEST_CPUSTOP */
printf(" TPR: 0x%08x\n", lapic.tpr);
printf(" SVR: 0x%08x\n", lapic.svr);
}
@ -238,13 +248,27 @@ io_apic_setup(int apic)
#undef DEFAULT_FLAGS
#if defined(TEST_ALTTIMER)
#if defined(TIMER_ALL)
#define DEL_MODE IOART_DELLOPRI
#else
#define DEL_MODE IOART_DELFIXED
#endif /** TIMER_ALL */
#else
#define DEL_MODE IOART_DELEXINT
#endif /** TEST_ALTTIMER */
#define DEFAULT_EXTINT_FLAGS \
((u_int32_t) \
(IOART_INTMSET | \
IOART_TRGREDG | \
IOART_INTAHI | \
IOART_DESTPHY | \
IOART_DELEXINT))
DEL_MODE))
/*
* Setup the source of External INTerrupts.
@ -261,11 +285,11 @@ ext_int_setup(int apic, int intr)
return -1;
/** XXX FIXME: changed on 970708, make default if no complaints */
#if 1
#if defined(TIMER_ALL)
target = IOART_DEST;
#else
target = boot_cpu_id << 24;
#endif /* BROADCAST_EXTINT */
#endif /* TIMER_ALL */
select = IOAPIC_REDTBL0 + (2 * intr);
vector = NRSVIDT + intr;
@ -274,8 +298,13 @@ ext_int_setup(int apic, int intr)
io_apic_write(apic, select, flags | vector);
io_apic_write(apic, select + 1, target);
#if defined(TEST_ALTTIMER)
printf("SMP: using ALT timer setup\n");
#endif /** TEST_ALTTIMER */
return 0;
}
#undef DEL_MODE
#undef DEFAULT_EXTINT_FLAGS
@ -646,9 +675,7 @@ selected_apic_ipi(u_int target, int vector, int delivery_mode)
icr_hi = lapic.icr_hi & ~APIC_ID_MASK;
icr_hi |= (CPU_TO_ID(x) << 24);
lapic.icr_hi = icr_hi;
#if defined(TEST_CPUSTOP)
db_printf( "icr_hi: 0x%08x\n", lapic.icr_hi );
#endif /* TEST_CPUSTOP */
/* send the IPI */
if (apic_ipi(APIC_DEST_DESTFLD, vector,
delivery_mode) == -1)

View File

@ -6,7 +6,7 @@
* this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
* ----------------------------------------------------------------------------
*
* $Id: mplock.s,v 1.7 1997/07/08 23:39:02 fsmp Exp $
* $Id: mplock.s,v 1.7 1997/07/13 00:19:24 smp Exp smp $
*
* Functions for locking between CPUs in a SMP system.
*
@ -21,30 +21,15 @@
*
*/
/*
* these are all temps for debugging CPUSTOP code
* they will (hopefully) go away soon...
*/
#define MARK_HITS_NOT
#define ADJUST_TPR_NOT
#define ADJUST_IPL_NOT
#define REALLY_STI_NOT
#define IPI_LEVEL 0x3f
#ifdef MARK_HITS
#define MARK_HIT(X) \
movl _cpuid, %eax ; \
movl $X, _lhits(,%eax,4)
#else
#define MARK_HIT(X)
#endif /* MARK_HITS */
#include "opt_ddb.h"
#include "assym.s" /* system definitions */
#include <machine/specialreg.h> /* x86 special registers */
#include <machine/asmacros.h> /* miscellaneous asm macros */
#include <machine/smptests.h> /** TEST_LOPRIO */
#include <machine/smptests.h> /** TEST_LOPRIO, TEST_CPUSTOP */
#ifdef TEST_CPUSTOP
#include <i386/isa/intr_machdep.h>
#endif
#include <machine/apic.h>
@ -75,15 +60,16 @@ NON_GPROF_ENTRY(MPgetlock)
jne 3f /* ...do not collect $200 */
#if defined(TEST_LOPRIO)
/* 1st acquire, claim LOW PRIO (ie, ALL INTerrupts) */
#ifdef ADJUST_TPR
movl 20(%esp), %eax /* saved copy */
#ifdef TEST_CPUSTOP
#define TPR_STACKOFFSET 20(%esp)
movl TPR_STACKOFFSET, %eax /* saved copy */
andl $0xffffff00, %eax /* clear task priority field */
movl %eax, 20(%esp) /* 're-save' it */
movl %eax, TPR_STACKOFFSET /* 're-save' it */
#else
movl lapic_tpr, %eax /* Task Priority Register */
andl $0xffffff00, %eax /* clear task priority field */
movl %eax, lapic_tpr /* set it */
#endif /** ADJUST_TPR */
#endif /** TEST_CPUSTOP */
#endif /** TEST_LOPRIO */
ret
3: cmpl $0xffffffff, (%edx) /* Wait for it to become free */
@ -160,40 +146,25 @@ NON_GPROF_ENTRY(MPrellock)
* ecx 12(%esp)
* EFLAGS 16(%esp)
* local APIC TPR 20(%esp)
* OR
* ipl 20(%esp)
* eax 24(%esp)
*/
NON_GPROF_ENTRY(get_mplock)
pushl %eax
MARK_HIT(1)
#ifdef ADJUST_TPR
#ifdef TEST_CPUSTOP
movl lapic_tpr, %eax /* get current TPR */
pushl %eax /* save current TPR */
pushfl /* save current EFLAGS */
btl $9, (%esp) /* test EI bit */
jc 1f /* INTs currently enabled */
andl $0xffffff00, %eax /* clear task priority field */
orl $IPI_LEVEL, %eax /* only allow IPIs
orl $TPR_BLOCK_HWI, %eax /* only allow IPIs
movl %eax, lapic_tpr /* set it */
#endif /* ADJUST_TPR */
#ifdef ADJUST_IPL
call _splhigh /* block all INTs EXCEPT IPIs */
pushl %eax /* save ipl */
pushfl /* save current EFLAGS */
btl $9, (%esp) /* test EI bit */
jc 1f /* INTs currently enabled */
#endif /* ADJUST_IPL */
#ifdef REALLY_STI
sti /* allow IPI (and only IPI) INTS */
#endif /* REALLY_STI */
1:
#endif /* TEST_CPUSTOP */
pushl %ecx
pushl %edx
pushl $_mp_lock
@ -202,19 +173,11 @@ NON_GPROF_ENTRY(get_mplock)
popl %edx
popl %ecx
MARK_HIT(0)
#ifdef ADJUST_TPR
#ifdef TEST_CPUSTOP
popfl /* restore original EFLAGS */
popl %eax /* get original/modified TPR value */
movl %eax, lapic_tpr /* restore TPR */
#endif /* ADJUST_TPR */
#ifdef ADJUST_IPL
popfl /* restore original EFLAGS */
call _splx /* restore original ipl */
add $4, %esp
#endif /* ADJUST_IPL */
#endif /* TEST_CPUSTOP */
popl %eax
ret
@ -244,8 +207,6 @@ NON_GPROF_ENTRY(try_mplock)
NON_GPROF_ENTRY(rel_mplock)
pushl %eax
MARK_HIT(128)
pushl %ecx
pushl %edx
pushl $_mp_lock
@ -254,8 +215,6 @@ NON_GPROF_ENTRY(rel_mplock)
popl %edx
popl %ecx
MARK_HIT(0)
popl %eax
ret
@ -264,12 +223,3 @@ NON_GPROF_ENTRY(rel_mplock)
.globl _mp_lock
.align 2 /* mp_lock SHALL be aligned on i386 */
_mp_lock: .long 0
#ifdef MARK_HITS
.globl _lhits
_lhits:
.long 0
.long 0
.long 0
.long 0
#endif /* MARK_HITS */

View File

@ -22,7 +22,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: mp_machdep.c,v 1.7 1997/07/08 23:42:28 smp Exp smp $
* $Id: mp_machdep.c,v 1.14 1997/07/13 00:42:14 smp Exp smp $
*/
#include "opt_smp.h"
@ -45,16 +45,12 @@
#include <machine/mpapic.h>
#include <machine/cpufunc.h>
#include <machine/segments.h>
#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, TEST_CPUSTOP */
#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, TEST_CPUSTOP _TEST1 */
#include <machine/tss.h>
#include <machine/specialreg.h>
#include <i386/i386/cons.h> /* cngetc() */
#if defined(TEST_CPUSTOP)
void db_printf __P((const char *fmt, ...));
#endif /* TEST_CPUSTOP */
#if defined(APIC_IO)
#include <machine/md_var.h> /* setidt() */
#include <i386/isa/icu.h> /* IPIs */
@ -434,14 +430,8 @@ bsp_apic_configure(void)
temp &= ~APIC_LVT_M; /* clear the mask */
lapic.lvt_lint1 = temp;
#if defined(TEST_CPUSTOP)
printf(">>> CPU%02d bsp_apic_configure() lint0: 0x%08x\n",
cpuid, lapic.lvt_lint0);
printf(">>> lint1: 0x%08x\n",
lapic.lvt_lint1);
printf(">>> TPR: 0x%08x\n", lapic.tpr);
printf(">>> SVR: 0x%08x\n", lapic.svr);
#endif /* TEST_CPUSTOP */
if (bootverbose)
apic_dump();
}
#endif /* APIC_IO */
@ -479,6 +469,7 @@ mp_enable(u_int boot_addr)
default_mp_table(x);
#if defined(APIC_IO)
/* fill the LOGICAL io_apic_versions table */
for (apic = 0; apic < mp_napics; ++apic) {
ux = io_apic_read(apic, IOAPIC_VER);
@ -490,6 +481,10 @@ mp_enable(u_int boot_addr)
if (io_apic_setup(apic) < 0)
panic("IO APIC setup failure");
/* install a 'Spurious INTerrupt' vector */
setidt(XSPURIOUSINT_OFFSET, Xspuriousint,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
/* install an inter-CPU IPI for TLB invalidation */
setidt(XINVLTLB_OFFSET, Xinvltlb,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
@ -498,11 +493,14 @@ mp_enable(u_int boot_addr)
/* install an inter-CPU IPI for CPU stop/restart */
setidt(XCPUSTOP_OFFSET, Xcpustop,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
#endif /** TEST_CPUSTOP */
#if defined(TEST_TEST1)
/* install a 'Spurious INTerrupt' vector */
setidt(XSPURIOUSINT_OFFSET, Xspuriousint,
setidt(XTEST1_OFFSET, Xtest1,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
#endif /* TEST_CPUSTOP */
#endif /** TEST_TEST1 */
#endif /* APIC_IO */
/* start each Application Processor */
@ -1741,6 +1739,10 @@ invltlb(void)
#if defined(TEST_CPUSTOP)
#if defined(DEBUG_CPUSTOP)
void db_printf __P((const char *fmt, ...));
#endif /* DEBUG_CPUSTOP */
/*
* When called the executing CPU will send an IPI to all other CPUs
* requesting that they halt execution.
@ -1757,65 +1759,32 @@ invltlb(void)
*
* XXX FIXME: this is not MP-safe, needs a lock to prevent multiple CPUs
* from executing at same time.
*/
extern int cshits[4];
extern int lhits[4];
extern int sihits;
int
stop_cpus( u_int map )
{
#if 1
int x, y;
#endif
if (!smp_active)
return 0;
/* send IPI to all CPUs in map */
#if defined(DEBUG_CPUSTOP)
#if 0
POSTCODE(0xF0);
#endif
db_printf("\nCPU%d stopping CPUs: 0x%08x\n", cpuid, map);
db_printf("b4 stop: cshits: %d, %d, mplock: 0x%08x, lhits: %d, %d, sihits: %d\n",
cshits[0], cshits[1], mp_lock, lhits[0], lhits[1], sihits);
#endif /* DEBUG_CPUSTOP */
stopped_cpus = 0;
#if 0
/* send the Xcpustop IPI to all CPUs in map */
selected_apic_ipi(map, XCPUSTOP_OFFSET, APIC_DELMODE_FIXED);
#else
all_but_self_ipi(XCPUSTOP_OFFSET);
#endif
#if defined(DEBUG_CPUSTOP)
db_printf(" spin\n");
#endif /* DEBUG_CPUSTOP */
#if 0 /** */
y = 0;
while (stopped_cpus != map) {
#if 0
while (stopped_cpus != map)
/* spin */ ;
#else
POSTCODE_LO(stopped_cpus & 0x0f);
#define MAX_SPIN 20000000
for ( x = 0; x < MAX_SPIN; ++x )
;
if (++y > 20) {
stopped_cpus = map;
break;
}
POSTCODE_LO(0x0f);
for ( x = 0; x < MAX_SPIN; ++x )
;
#endif
}
#endif /** 0 */
#if defined(DEBUG_CPUSTOP)
db_printf(" spun\nstopped, sihits: %d\n", sihits);
cngetc();
db_printf(" spun\nstopped\n");
#endif /* DEBUG_CPUSTOP */
return 1;
@ -1842,30 +1811,20 @@ restart_cpus( u_int map )
return 0;
#if defined(DEBUG_CPUSTOP)
#if 0
POSTCODE(0x90);
#endif
db_printf("\nCPU%d restarting CPUs: 0x%08x (0x%08x)\n",
cpuid, map, stopped_cpus);
db_printf("b4 restart: cshits: %d, %d, mplock: 0x%08x, lhits: %d, %d, sihits: %d\n",
cshits[0], cshits[1], mp_lock, lhits[0], lhits[1], sihits);
#endif /* DEBUG_CPUSTOP */
started_cpus = map; /* signal other cpus to restart */
#if 0 /** */
while (started_cpus) /* wait for each to clear its bit */
/* spin */ ;
#endif /** 0 */
#if defined(DEBUG_CPUSTOP)
#if 0
POSTCODE(0xA0);
#endif
db_printf(" restarted\n");
#endif /* DEBUG_CPUSTOP */
return 1;
}
#endif /* TEST_CPUSTOP */
#endif /** TEST_CPUSTOP */

View File

@ -22,7 +22,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: mp_machdep.c,v 1.7 1997/07/08 23:42:28 smp Exp smp $
* $Id: mp_machdep.c,v 1.14 1997/07/13 00:42:14 smp Exp smp $
*/
#include "opt_smp.h"
@ -45,16 +45,12 @@
#include <machine/mpapic.h>
#include <machine/cpufunc.h>
#include <machine/segments.h>
#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, TEST_CPUSTOP */
#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, TEST_CPUSTOP _TEST1 */
#include <machine/tss.h>
#include <machine/specialreg.h>
#include <i386/i386/cons.h> /* cngetc() */
#if defined(TEST_CPUSTOP)
void db_printf __P((const char *fmt, ...));
#endif /* TEST_CPUSTOP */
#if defined(APIC_IO)
#include <machine/md_var.h> /* setidt() */
#include <i386/isa/icu.h> /* IPIs */
@ -434,14 +430,8 @@ bsp_apic_configure(void)
temp &= ~APIC_LVT_M; /* clear the mask */
lapic.lvt_lint1 = temp;
#if defined(TEST_CPUSTOP)
printf(">>> CPU%02d bsp_apic_configure() lint0: 0x%08x\n",
cpuid, lapic.lvt_lint0);
printf(">>> lint1: 0x%08x\n",
lapic.lvt_lint1);
printf(">>> TPR: 0x%08x\n", lapic.tpr);
printf(">>> SVR: 0x%08x\n", lapic.svr);
#endif /* TEST_CPUSTOP */
if (bootverbose)
apic_dump();
}
#endif /* APIC_IO */
@ -479,6 +469,7 @@ mp_enable(u_int boot_addr)
default_mp_table(x);
#if defined(APIC_IO)
/* fill the LOGICAL io_apic_versions table */
for (apic = 0; apic < mp_napics; ++apic) {
ux = io_apic_read(apic, IOAPIC_VER);
@ -490,6 +481,10 @@ mp_enable(u_int boot_addr)
if (io_apic_setup(apic) < 0)
panic("IO APIC setup failure");
/* install a 'Spurious INTerrupt' vector */
setidt(XSPURIOUSINT_OFFSET, Xspuriousint,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
/* install an inter-CPU IPI for TLB invalidation */
setidt(XINVLTLB_OFFSET, Xinvltlb,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
@ -498,11 +493,14 @@ mp_enable(u_int boot_addr)
/* install an inter-CPU IPI for CPU stop/restart */
setidt(XCPUSTOP_OFFSET, Xcpustop,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
#endif /** TEST_CPUSTOP */
#if defined(TEST_TEST1)
/* install a 'Spurious INTerrupt' vector */
setidt(XSPURIOUSINT_OFFSET, Xspuriousint,
setidt(XTEST1_OFFSET, Xtest1,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
#endif /* TEST_CPUSTOP */
#endif /** TEST_TEST1 */
#endif /* APIC_IO */
/* start each Application Processor */
@ -1741,6 +1739,10 @@ invltlb(void)
#if defined(TEST_CPUSTOP)
#if defined(DEBUG_CPUSTOP)
void db_printf __P((const char *fmt, ...));
#endif /* DEBUG_CPUSTOP */
/*
* When called the executing CPU will send an IPI to all other CPUs
* requesting that they halt execution.
@ -1757,65 +1759,32 @@ invltlb(void)
*
* XXX FIXME: this is not MP-safe, needs a lock to prevent multiple CPUs
* from executing at same time.
*/
extern int cshits[4];
extern int lhits[4];
extern int sihits;
int
stop_cpus( u_int map )
{
#if 1
int x, y;
#endif
if (!smp_active)
return 0;
/* send IPI to all CPUs in map */
#if defined(DEBUG_CPUSTOP)
#if 0
POSTCODE(0xF0);
#endif
db_printf("\nCPU%d stopping CPUs: 0x%08x\n", cpuid, map);
db_printf("b4 stop: cshits: %d, %d, mplock: 0x%08x, lhits: %d, %d, sihits: %d\n",
cshits[0], cshits[1], mp_lock, lhits[0], lhits[1], sihits);
#endif /* DEBUG_CPUSTOP */
stopped_cpus = 0;
#if 0
/* send the Xcpustop IPI to all CPUs in map */
selected_apic_ipi(map, XCPUSTOP_OFFSET, APIC_DELMODE_FIXED);
#else
all_but_self_ipi(XCPUSTOP_OFFSET);
#endif
#if defined(DEBUG_CPUSTOP)
db_printf(" spin\n");
#endif /* DEBUG_CPUSTOP */
#if 0 /** */
y = 0;
while (stopped_cpus != map) {
#if 0
while (stopped_cpus != map)
/* spin */ ;
#else
POSTCODE_LO(stopped_cpus & 0x0f);
#define MAX_SPIN 20000000
for ( x = 0; x < MAX_SPIN; ++x )
;
if (++y > 20) {
stopped_cpus = map;
break;
}
POSTCODE_LO(0x0f);
for ( x = 0; x < MAX_SPIN; ++x )
;
#endif
}
#endif /** 0 */
#if defined(DEBUG_CPUSTOP)
db_printf(" spun\nstopped, sihits: %d\n", sihits);
cngetc();
db_printf(" spun\nstopped\n");
#endif /* DEBUG_CPUSTOP */
return 1;
@ -1842,30 +1811,20 @@ restart_cpus( u_int map )
return 0;
#if defined(DEBUG_CPUSTOP)
#if 0
POSTCODE(0x90);
#endif
db_printf("\nCPU%d restarting CPUs: 0x%08x (0x%08x)\n",
cpuid, map, stopped_cpus);
db_printf("b4 restart: cshits: %d, %d, mplock: 0x%08x, lhits: %d, %d, sihits: %d\n",
cshits[0], cshits[1], mp_lock, lhits[0], lhits[1], sihits);
#endif /* DEBUG_CPUSTOP */
started_cpus = map; /* signal other cpus to restart */
#if 0 /** */
while (started_cpus) /* wait for each to clear its bit */
/* spin */ ;
#endif /** 0 */
#if defined(DEBUG_CPUSTOP)
#if 0
POSTCODE(0xA0);
#endif
db_printf(" restarted\n");
#endif /* DEBUG_CPUSTOP */
return 1;
}
#endif /* TEST_CPUSTOP */
#endif /** TEST_CPUSTOP */

View File

@ -22,7 +22,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: mp_machdep.c,v 1.7 1997/07/08 23:42:28 smp Exp smp $
* $Id: mp_machdep.c,v 1.14 1997/07/13 00:42:14 smp Exp smp $
*/
#include "opt_smp.h"
@ -45,16 +45,12 @@
#include <machine/mpapic.h>
#include <machine/cpufunc.h>
#include <machine/segments.h>
#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, TEST_CPUSTOP */
#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, TEST_CPUSTOP _TEST1 */
#include <machine/tss.h>
#include <machine/specialreg.h>
#include <i386/i386/cons.h> /* cngetc() */
#if defined(TEST_CPUSTOP)
void db_printf __P((const char *fmt, ...));
#endif /* TEST_CPUSTOP */
#if defined(APIC_IO)
#include <machine/md_var.h> /* setidt() */
#include <i386/isa/icu.h> /* IPIs */
@ -434,14 +430,8 @@ bsp_apic_configure(void)
temp &= ~APIC_LVT_M; /* clear the mask */
lapic.lvt_lint1 = temp;
#if defined(TEST_CPUSTOP)
printf(">>> CPU%02d bsp_apic_configure() lint0: 0x%08x\n",
cpuid, lapic.lvt_lint0);
printf(">>> lint1: 0x%08x\n",
lapic.lvt_lint1);
printf(">>> TPR: 0x%08x\n", lapic.tpr);
printf(">>> SVR: 0x%08x\n", lapic.svr);
#endif /* TEST_CPUSTOP */
if (bootverbose)
apic_dump();
}
#endif /* APIC_IO */
@ -479,6 +469,7 @@ mp_enable(u_int boot_addr)
default_mp_table(x);
#if defined(APIC_IO)
/* fill the LOGICAL io_apic_versions table */
for (apic = 0; apic < mp_napics; ++apic) {
ux = io_apic_read(apic, IOAPIC_VER);
@ -490,6 +481,10 @@ mp_enable(u_int boot_addr)
if (io_apic_setup(apic) < 0)
panic("IO APIC setup failure");
/* install a 'Spurious INTerrupt' vector */
setidt(XSPURIOUSINT_OFFSET, Xspuriousint,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
/* install an inter-CPU IPI for TLB invalidation */
setidt(XINVLTLB_OFFSET, Xinvltlb,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
@ -498,11 +493,14 @@ mp_enable(u_int boot_addr)
/* install an inter-CPU IPI for CPU stop/restart */
setidt(XCPUSTOP_OFFSET, Xcpustop,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
#endif /** TEST_CPUSTOP */
#if defined(TEST_TEST1)
/* install a 'Spurious INTerrupt' vector */
setidt(XSPURIOUSINT_OFFSET, Xspuriousint,
setidt(XTEST1_OFFSET, Xtest1,
SDT_SYS386IGT, SEL_KPL, GSEL(GCODE_SEL, SEL_KPL));
#endif /* TEST_CPUSTOP */
#endif /** TEST_TEST1 */
#endif /* APIC_IO */
/* start each Application Processor */
@ -1741,6 +1739,10 @@ invltlb(void)
#if defined(TEST_CPUSTOP)
#if defined(DEBUG_CPUSTOP)
void db_printf __P((const char *fmt, ...));
#endif /* DEBUG_CPUSTOP */
/*
* When called the executing CPU will send an IPI to all other CPUs
* requesting that they halt execution.
@ -1757,65 +1759,32 @@ invltlb(void)
*
* XXX FIXME: this is not MP-safe, needs a lock to prevent multiple CPUs
* from executing at same time.
*/
extern int cshits[4];
extern int lhits[4];
extern int sihits;
int
stop_cpus( u_int map )
{
#if 1
int x, y;
#endif
if (!smp_active)
return 0;
/* send IPI to all CPUs in map */
#if defined(DEBUG_CPUSTOP)
#if 0
POSTCODE(0xF0);
#endif
db_printf("\nCPU%d stopping CPUs: 0x%08x\n", cpuid, map);
db_printf("b4 stop: cshits: %d, %d, mplock: 0x%08x, lhits: %d, %d, sihits: %d\n",
cshits[0], cshits[1], mp_lock, lhits[0], lhits[1], sihits);
#endif /* DEBUG_CPUSTOP */
stopped_cpus = 0;
#if 0
/* send the Xcpustop IPI to all CPUs in map */
selected_apic_ipi(map, XCPUSTOP_OFFSET, APIC_DELMODE_FIXED);
#else
all_but_self_ipi(XCPUSTOP_OFFSET);
#endif
#if defined(DEBUG_CPUSTOP)
db_printf(" spin\n");
#endif /* DEBUG_CPUSTOP */
#if 0 /** */
y = 0;
while (stopped_cpus != map) {
#if 0
while (stopped_cpus != map)
/* spin */ ;
#else
POSTCODE_LO(stopped_cpus & 0x0f);
#define MAX_SPIN 20000000
for ( x = 0; x < MAX_SPIN; ++x )
;
if (++y > 20) {
stopped_cpus = map;
break;
}
POSTCODE_LO(0x0f);
for ( x = 0; x < MAX_SPIN; ++x )
;
#endif
}
#endif /** 0 */
#if defined(DEBUG_CPUSTOP)
db_printf(" spun\nstopped, sihits: %d\n", sihits);
cngetc();
db_printf(" spun\nstopped\n");
#endif /* DEBUG_CPUSTOP */
return 1;
@ -1842,30 +1811,20 @@ restart_cpus( u_int map )
return 0;
#if defined(DEBUG_CPUSTOP)
#if 0
POSTCODE(0x90);
#endif
db_printf("\nCPU%d restarting CPUs: 0x%08x (0x%08x)\n",
cpuid, map, stopped_cpus);
db_printf("b4 restart: cshits: %d, %d, mplock: 0x%08x, lhits: %d, %d, sihits: %d\n",
cshits[0], cshits[1], mp_lock, lhits[0], lhits[1], sihits);
#endif /* DEBUG_CPUSTOP */
started_cpus = map; /* signal other cpus to restart */
#if 0 /** */
while (started_cpus) /* wait for each to clear its bit */
/* spin */ ;
#endif /** 0 */
#if defined(DEBUG_CPUSTOP)
#if 0
POSTCODE(0xA0);
#endif
db_printf(" restarted\n");
#endif /* DEBUG_CPUSTOP */
return 1;
}
#endif /* TEST_CPUSTOP */
#endif /** TEST_CPUSTOP */