Trim lots of stuff that is now in MI code along with MD alpha code.
This commit is contained in:
parent
ba228f6d96
commit
f2909e6cd8
@ -35,7 +35,6 @@
|
||||
#include <sys/mutex.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/smp.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
@ -44,163 +43,14 @@
|
||||
#include <sys/dkstat.h>
|
||||
|
||||
#include <machine/atomic.h>
|
||||
#include <machine/globaldata.h>
|
||||
#include <machine/pmap.h>
|
||||
#include <machine/rpb.h>
|
||||
#include <machine/clock.h>
|
||||
|
||||
volatile u_int stopped_cpus;
|
||||
volatile u_int started_cpus;
|
||||
volatile u_int checkstate_probed_cpus;
|
||||
volatile u_int checkstate_need_ast;
|
||||
volatile u_int checkstate_pending_ast;
|
||||
struct proc* checkstate_curproc[MAXCPU];
|
||||
int checkstate_cpustate[MAXCPU];
|
||||
u_long checkstate_pc[MAXCPU];
|
||||
volatile u_int resched_cpus;
|
||||
void (*cpustop_restartfunc) __P((void));
|
||||
int mp_ncpus;
|
||||
|
||||
int smp_started;
|
||||
int boot_cpu_id;
|
||||
u_int32_t all_cpus;
|
||||
|
||||
static struct globaldata *cpuno_to_globaldata[MAXCPU];
|
||||
|
||||
int smp_active = 0; /* are the APs allowed to run? */
|
||||
SYSCTL_INT(_machdep, OID_AUTO, smp_active, CTLFLAG_RW, &smp_active, 0, "");
|
||||
|
||||
/* Is forwarding of a interrupt to the CPU holding the ISR lock enabled ? */
|
||||
int forward_irq_enabled = 1;
|
||||
SYSCTL_INT(_machdep, OID_AUTO, forward_irq_enabled, CTLFLAG_RW,
|
||||
&forward_irq_enabled, 0, "");
|
||||
|
||||
/* Enable forwarding of a signal to a process running on a different CPU */
|
||||
static int forward_signal_enabled = 1;
|
||||
SYSCTL_INT(_machdep, OID_AUTO, forward_signal_enabled, CTLFLAG_RW,
|
||||
&forward_signal_enabled, 0, "");
|
||||
|
||||
/* Enable forwarding of roundrobin to all other cpus */
|
||||
static int forward_roundrobin_enabled = 1;
|
||||
SYSCTL_INT(_machdep, OID_AUTO, forward_roundrobin_enabled, CTLFLAG_RW,
|
||||
&forward_roundrobin_enabled, 0, "");
|
||||
|
||||
/*
|
||||
* Communicate with a console running on a secondary processor.
|
||||
* Return 1 on failure.
|
||||
*/
|
||||
static int
|
||||
smp_send_secondary_command(const char *command, int cpuno)
|
||||
{
|
||||
u_int64_t mask;
|
||||
|
||||
mask = 1L << cpuno;
|
||||
struct pcs *cpu = LOCATE_PCS(hwrpb, cpuno);
|
||||
int i, len;
|
||||
|
||||
/*
|
||||
* Sanity check.
|
||||
*/
|
||||
len = strlen(command);
|
||||
if (len > sizeof(cpu->pcs_buffer.rxbuf)) {
|
||||
printf("smp_send_secondary_command: command '%s' too long\n",
|
||||
command);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for the rx bit to clear.
|
||||
*/
|
||||
for (i = 0; i < 100000; i++) {
|
||||
if (!(hwrpb->rpb_rxrdy & mask))
|
||||
break;
|
||||
DELAY(10);
|
||||
}
|
||||
if (hwrpb->rpb_rxrdy & mask)
|
||||
return 0;
|
||||
|
||||
/*
|
||||
* Write the command into the processor's buffer.
|
||||
*/
|
||||
bcopy(command, cpu->pcs_buffer.rxbuf, len);
|
||||
cpu->pcs_buffer.rxlen = len;
|
||||
|
||||
/*
|
||||
* Set the bit in the rxrdy mask and let the secondary try to
|
||||
* handle the command.
|
||||
*/
|
||||
atomic_set_64(&hwrpb->rpb_rxrdy, mask);
|
||||
|
||||
/*
|
||||
* Wait for the rx bit to clear.
|
||||
*/
|
||||
for (i = 0; i < 100000; i++) {
|
||||
if (!(hwrpb->rpb_rxrdy & mask))
|
||||
break;
|
||||
DELAY(10);
|
||||
}
|
||||
if (hwrpb->rpb_rxrdy & mask)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
smp_init_secondary(void)
|
||||
{
|
||||
|
||||
mtx_lock(&Giant);
|
||||
|
||||
printf("smp_init_secondary: called\n");
|
||||
CTR0(KTR_SMP, "smp_init_secondary");
|
||||
|
||||
/*
|
||||
* Add to mask.
|
||||
*/
|
||||
smp_started = 1;
|
||||
if (PCPU_GET(cpuno) + 1 > mp_ncpus)
|
||||
mp_ncpus = PCPU_GET(cpuno) + 1;
|
||||
spl0();
|
||||
|
||||
mtx_unlock(&Giant);
|
||||
}
|
||||
|
||||
extern void smp_init_secondary_glue(void);
|
||||
|
||||
static int
|
||||
smp_start_secondary(int cpuno)
|
||||
{
|
||||
|
||||
printf("smp_start_secondary: starting cpu %d\n", cpuno);
|
||||
|
||||
sz = round_page(UPAGES * PAGE_SIZE);
|
||||
globaldata = malloc(sz, M_TEMP, M_NOWAIT);
|
||||
if (!globaldata) {
|
||||
printf("smp_start_secondary: can't allocate memory\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
globaldata_init(globaldata, cpuno, sz);
|
||||
|
||||
/*
|
||||
* Fire it up and hope for the best.
|
||||
*/
|
||||
if (!smp_send_secondary_command("START\r\n", cpuno)) {
|
||||
printf("smp_init_secondary: can't send START command\n");
|
||||
free(globaldata, M_TEMP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* It worked (I think).
|
||||
*/
|
||||
/* if (bootverbose) */
|
||||
printf("smp_init_secondary: cpu %d started\n", cpuno);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX: needs to move to machdep.c
|
||||
*
|
||||
* Initialise a struct globaldata.
|
||||
*/
|
||||
void
|
||||
@ -217,188 +67,21 @@ globaldata_init(struct globaldata *globaldata, int cpuno, size_t sz)
|
||||
globaldata->gd_next_asn = 0;
|
||||
globaldata->gd_current_asngen = 1;
|
||||
globaldata->gd_cpuid = cpuno;
|
||||
cpuno_to_globaldata[cpuno] = globaldata;
|
||||
globaldata_register(globaldata);
|
||||
}
|
||||
|
||||
struct globaldata *
|
||||
globaldata_find(int cpuno)
|
||||
{
|
||||
|
||||
return cpuno_to_globaldata[cpuno];
|
||||
}
|
||||
|
||||
/* Other stuff */
|
||||
|
||||
/* lock around the MP rendezvous */
|
||||
static struct mtx smp_rv_mtx;
|
||||
|
||||
static void
|
||||
init_locks(void)
|
||||
{
|
||||
|
||||
mtx_init(&smp_rv_mtx, "smp rendezvous", MTX_SPIN);
|
||||
}
|
||||
|
||||
void
|
||||
mp_start()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
mp_announce()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
smp_invltlb()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* When called the executing CPU will send an IPI to all other CPUs
|
||||
* requesting that they halt execution.
|
||||
*
|
||||
* Usually (but not necessarily) called with 'other_cpus' as its arg.
|
||||
*
|
||||
* - Signals all CPUs in map to stop.
|
||||
* - Waits for each to stop.
|
||||
*
|
||||
* Returns:
|
||||
* -1: error
|
||||
* 0: NA
|
||||
* 1: ok
|
||||
*
|
||||
* XXX FIXME: this is not MP-safe, needs a lock to prevent multiple CPUs
|
||||
* from executing at same time.
|
||||
*/
|
||||
int
|
||||
stop_cpus(u_int map)
|
||||
cpu_mp_probe(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!smp_started)
|
||||
return 0;
|
||||
|
||||
CTR1(KTR_SMP, "stop_cpus(%x)", map);
|
||||
|
||||
i = 0;
|
||||
while ((stopped_cpus & map) != map) {
|
||||
/* spin */
|
||||
i++;
|
||||
if (i == 100000) {
|
||||
printf("timeout stopping cpus\n");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
printf("stopped_cpus=%x\n", stopped_cpus);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Called by a CPU to restart stopped CPUs.
|
||||
*
|
||||
* Usually (but not necessarily) called with 'stopped_cpus' as its arg.
|
||||
*
|
||||
* - Signals all CPUs in map to restart.
|
||||
* - Waits for each to restart.
|
||||
*
|
||||
* Returns:
|
||||
* -1: error
|
||||
* 0: NA
|
||||
* 1: ok
|
||||
*/
|
||||
int
|
||||
restart_cpus(u_int map)
|
||||
{
|
||||
|
||||
if (!smp_started)
|
||||
return 0;
|
||||
|
||||
CTR1(KTR_SMP, "restart_cpus(%x)", map);
|
||||
|
||||
started_cpus = map; /* signal other cpus to restart */
|
||||
|
||||
while ((stopped_cpus & map) != 0) /* wait for each to clear its bit */
|
||||
;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* All-CPU rendezvous. CPUs are signalled, all execute the setup function
|
||||
* (if specified), rendezvous, execute the action function (if specified),
|
||||
* rendezvous again, execute the teardown function (if specified), and then
|
||||
* resume.
|
||||
*
|
||||
* Note that the supplied external functions _must_ be reentrant and aware
|
||||
* that they are running in parallel and in an unknown lock context.
|
||||
*/
|
||||
static void (*smp_rv_setup_func)(void *arg);
|
||||
static void (*smp_rv_action_func)(void *arg);
|
||||
static void (*smp_rv_teardown_func)(void *arg);
|
||||
static void *smp_rv_func_arg;
|
||||
static volatile int smp_rv_waiters[2];
|
||||
|
||||
void
|
||||
smp_rendezvous_action(void)
|
||||
{
|
||||
|
||||
/* setup function */
|
||||
if (smp_rv_setup_func != NULL)
|
||||
smp_rv_setup_func(smp_rv_func_arg);
|
||||
/* spin on entry rendezvous */
|
||||
atomic_add_int(&smp_rv_waiters[0], 1);
|
||||
while (smp_rv_waiters[0] < mp_ncpus)
|
||||
;
|
||||
/* action function */
|
||||
if (smp_rv_action_func != NULL)
|
||||
smp_rv_action_func(smp_rv_func_arg);
|
||||
/* spin on exit rendezvous */
|
||||
atomic_add_int(&smp_rv_waiters[1], 1);
|
||||
while (smp_rv_waiters[1] < mp_ncpus)
|
||||
;
|
||||
/* teardown function */
|
||||
if (smp_rv_teardown_func != NULL)
|
||||
smp_rv_teardown_func(smp_rv_func_arg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
smp_rendezvous(void (* setup_func)(void *),
|
||||
void (* action_func)(void *),
|
||||
void (* teardown_func)(void *),
|
||||
void *arg)
|
||||
cpu_mp_start(void)
|
||||
{
|
||||
|
||||
/* obtain rendezvous lock */
|
||||
mtx_lock_spin(&smp_rv_mtx);
|
||||
|
||||
/* set static function pointers */
|
||||
smp_rv_setup_func = setup_func;
|
||||
smp_rv_action_func = action_func;
|
||||
smp_rv_teardown_func = teardown_func;
|
||||
smp_rv_func_arg = arg;
|
||||
smp_rv_waiters[0] = 0;
|
||||
smp_rv_waiters[1] = 0;
|
||||
|
||||
/* call executor function */
|
||||
smp_rendezvous_action();
|
||||
|
||||
/* release lock */
|
||||
mtx_unlock_spin(&smp_rv_mtx);
|
||||
}
|
||||
|
||||
static u_int64_t
|
||||
atomic_readandclear(u_int64_t* p)
|
||||
void
|
||||
cpu_mp_announce(void)
|
||||
{
|
||||
u_int64_t v, temp;
|
||||
|
||||
__asm__ __volatile__ (
|
||||
: "=&r"(v), "=&r"(temp), "=m" (*p)
|
||||
: "m"(*p)
|
||||
: "memory");
|
||||
return v;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user