- Add a new MD per-CPU field for Alpha 'pal_id' which is the PAL ID

associated with each processor.  This ID is inferred from the index
  of the pcs structure in the hwprb.
- Give Alpha CPUs FreeBSD CPU IDs more like other architectures where the
  boot processor is always CPU 0 and the other processors are numbered
  1 ... N.  List active CPUs in the system in cpu_mp_announce() as well.

Silence on:	alpha@
This commit is contained in:
John Baldwin 2004-11-05 19:16:44 +00:00
parent 57ea1265bd
commit 1aafbc01f9
4 changed files with 54 additions and 41 deletions

View File

@ -864,7 +864,8 @@ alpha_init(pfn, ptb, bim, bip, biv)
/* This is not a 'struct user' */ /* This is not a 'struct user' */
size_t sz = round_page(KSTACK_PAGES * PAGE_SIZE); size_t sz = round_page(KSTACK_PAGES * PAGE_SIZE);
pcpup = (struct pcpu *) pmap_steal_memory(sz); pcpup = (struct pcpu *) pmap_steal_memory(sz);
pcpu_init(pcpup, alpha_pal_whami(), sz); pcpu_init(pcpup, 0, sz);
pcpup->pc_pal_id = alpha_pal_whami();
alpha_pal_wrval((u_int64_t) pcpup); alpha_pal_wrval((u_int64_t) pcpup);
PCPU_GET(next_asn) = 1; /* 0 used for proc0 pmap */ PCPU_GET(next_asn) = 1; /* 0 used for proc0 pmap */
PCPU_SET(curthread, &thread0); PCPU_SET(curthread, &thread0);

View File

@ -61,23 +61,23 @@ static volatile int aps_ready = 0;
static struct mtx ap_boot_mtx; static struct mtx ap_boot_mtx;
u_int boot_cpu_id; u_int64_t boot_cpu_id;
static void release_aps(void *dummy); static void release_aps(void *dummy);
static int smp_cpu_enabled(struct pcs *pcsp); static int smp_cpu_enabled(struct pcs *pcsp);
extern void smp_init_secondary_glue(void); extern void smp_init_secondary_glue(void);
static int smp_send_secondary_command(const char *command, int cpuid); static int smp_send_secondary_command(const char *command, int pal_id);
static int smp_start_secondary(int cpuid); static int smp_start_secondary(int pal_id, int cpuid);
/* /*
* Communicate with a console running on a secondary processor. * Communicate with a console running on a secondary processor.
* Return 1 on failure. * Return 1 on failure.
*/ */
static int static int
smp_send_secondary_command(const char *command, int cpuid) smp_send_secondary_command(const char *command, int pal_id)
{ {
u_int64_t mask = 1L << cpuid; u_int64_t mask = 1L << pal_id;
struct pcs *cpu = LOCATE_PCS(hwrpb, cpuid); struct pcs *cpu = LOCATE_PCS(hwrpb, pal_id);
int i, len; int i, len;
/* /*
@ -165,7 +165,7 @@ smp_init_secondary(void)
/* /*
* Set flags in our per-CPU slot in the HWRPB. * Set flags in our per-CPU slot in the HWRPB.
*/ */
cpu = LOCATE_PCS(hwrpb, PCPU_GET(cpuid)); cpu = LOCATE_PCS(hwrpb, PCPU_GET(pal_id));
cpu->pcs_flags &= ~PCS_BIP; cpu->pcs_flags &= ~PCS_BIP;
cpu->pcs_flags |= PCS_RC; cpu->pcs_flags |= PCS_RC;
alpha_mb(); alpha_mb();
@ -216,9 +216,9 @@ smp_init_secondary(void)
} }
static int static int
smp_start_secondary(int cpuid) smp_start_secondary(int pal_id, int cpuid)
{ {
struct pcs *cpu = LOCATE_PCS(hwrpb, cpuid); struct pcs *cpu = LOCATE_PCS(hwrpb, pal_id);
struct pcs *bootcpu = LOCATE_PCS(hwrpb, boot_cpu_id); struct pcs *bootcpu = LOCATE_PCS(hwrpb, boot_cpu_id);
struct alpha_pcb *pcb = (struct alpha_pcb *) cpu->pcs_hwpcb; struct alpha_pcb *pcb = (struct alpha_pcb *) cpu->pcs_hwpcb;
struct pcpu *pcpu; struct pcpu *pcpu;
@ -226,12 +226,12 @@ smp_start_secondary(int cpuid)
size_t sz; size_t sz;
if ((cpu->pcs_flags & PCS_PV) == 0) { if ((cpu->pcs_flags & PCS_PV) == 0) {
printf("smp_start_secondary: cpu %d PALcode invalid\n", cpuid); printf("smp_start_secondary: cpu %d PALcode invalid\n", pal_id);
return 0; return 0;
} }
if (bootverbose) if (bootverbose)
printf("smp_start_secondary: starting cpu %d\n", cpuid); printf("smp_start_secondary: starting cpu %d\n", pal_id);
sz = round_page((UAREA_PAGES + KSTACK_PAGES) * PAGE_SIZE); sz = round_page((UAREA_PAGES + KSTACK_PAGES) * PAGE_SIZE);
pcpu = malloc(sz, M_TEMP, M_NOWAIT); pcpu = malloc(sz, M_TEMP, M_NOWAIT);
@ -241,6 +241,7 @@ smp_start_secondary(int cpuid)
} }
pcpu_init(pcpu, cpuid, sz); pcpu_init(pcpu, cpuid, sz);
pcpu->pc_pal_id = pal_id;
/* /*
* Copy the idle pcb and setup the address to start executing. * Copy the idle pcb and setup the address to start executing.
@ -270,7 +271,7 @@ smp_start_secondary(int cpuid)
/* /*
* Fire it up and hope for the best. * Fire it up and hope for the best.
*/ */
if (!smp_send_secondary_command("START\r\n", cpuid)) { if (!smp_send_secondary_command("START\r\n", pal_id)) {
printf("smp_start_secondary: can't send START command\n"); printf("smp_start_secondary: can't send START command\n");
pcpu_destroy(pcpu); pcpu_destroy(pcpu);
free(pcpu, M_TEMP); free(pcpu, M_TEMP);
@ -296,7 +297,7 @@ smp_start_secondary(int cpuid)
* It worked (I think). * It worked (I think).
*/ */
if (bootverbose) if (bootverbose)
printf("smp_start_secondary: cpu %d started\n", cpuid); printf("smp_start_secondary: cpu %d started\n", pal_id);
return 1; return 1;
} }
@ -329,16 +330,18 @@ smp_cpu_enabled(struct pcs *pcsp)
void void
cpu_mp_setmaxid(void) cpu_mp_setmaxid(void)
{ {
int i; u_int64_t i;
mp_maxid = 0; mp_maxid = 0;
for (i = 0; i < hwrpb->rpb_pcs_cnt && i < MAXCPU; i++) { for (i = 0; i < hwrpb->rpb_pcs_cnt; i++) {
if (i == PCPU_GET(cpuid)) if (i == PCPU_GET(pal_id))
continue; continue;
if (!smp_cpu_enabled(LOCATE_PCS(hwrpb, i))) if (!smp_cpu_enabled(LOCATE_PCS(hwrpb, i)))
continue; continue;
mp_maxid = i; mp_maxid++;
} }
if (mp_maxid > MAXCPU)
mp_maxid = MAXCPU;
} }
int int
@ -348,7 +351,7 @@ cpu_mp_probe(void)
/* XXX: Need to check for valid platforms here. */ /* XXX: Need to check for valid platforms here. */
boot_cpu_id = PCPU_GET(cpuid); boot_cpu_id = PCPU_GET(pal_id);
KASSERT(boot_cpu_id == hwrpb->rpb_primary_cpu_id, KASSERT(boot_cpu_id == hwrpb->rpb_primary_cpu_id,
("cpu_mp_probe() called on non-primary CPU")); ("cpu_mp_probe() called on non-primary CPU"));
all_cpus = PCPU_GET(cpumask); all_cpus = PCPU_GET(cpumask);
@ -358,12 +361,10 @@ cpu_mp_probe(void)
/* Make sure we have at least one secondary CPU. */ /* Make sure we have at least one secondary CPU. */
cpus = 0; cpus = 0;
for (i = 0; i < hwrpb->rpb_pcs_cnt; i++) { for (i = 0; i < hwrpb->rpb_pcs_cnt; i++) {
if (i == PCPU_GET(cpuid)) if (i == PCPU_GET(pal_id))
continue; continue;
if (!smp_cpu_enabled(LOCATE_PCS(hwrpb, i))) if (!smp_cpu_enabled(LOCATE_PCS(hwrpb, i)))
continue; continue;
if (i > MAXCPU)
continue;
cpus++; cpus++;
} }
return (cpus); return (cpus);
@ -372,10 +373,11 @@ cpu_mp_probe(void)
void void
cpu_mp_start(void) cpu_mp_start(void)
{ {
int i; int i, cpuid;
mtx_init(&ap_boot_mtx, "ap boot", NULL, MTX_SPIN); mtx_init(&ap_boot_mtx, "ap boot", NULL, MTX_SPIN);
cpuid = 1;
for (i = 0; i < hwrpb->rpb_pcs_cnt; i++) { for (i = 0; i < hwrpb->rpb_pcs_cnt; i++) {
struct pcs *pcsp; struct pcs *pcsp;
@ -410,22 +412,30 @@ cpu_mp_start(void)
printf("CPU %d disabled by loader.\n", i); printf("CPU %d disabled by loader.\n", i);
continue; continue;
} }
all_cpus |= (1 << i); if (smp_start_secondary(i, cpuid)) {
mp_ncpus++; all_cpus |= (1 << cpuid);
mp_ncpus++;
cpuid++;
}
} }
PCPU_SET(other_cpus, all_cpus & ~PCPU_GET(cpumask)); PCPU_SET(other_cpus, all_cpus & ~PCPU_GET(cpumask));
for (i = 0; i < hwrpb->rpb_pcs_cnt; i++) {
if (i == boot_cpu_id)
continue;
if (!CPU_ABSENT(i))
smp_start_secondary(i);
}
} }
void void
cpu_mp_announce(void) cpu_mp_announce(void)
{ {
struct pcpu *pc;
int i;
/* List CPUs */
printf(" cpu0 (BSP): PAL ID: %2lu\n", boot_cpu_id);
for (i = 1; i < MAXCPU; i++) {
if (CPU_ABSENT(i))
continue;
pc = pcpu_find(i);
MPASS(pc != NULL);
printf(" cpu%d (AP): PAL ID: %2lu\n", i, pc->pc_pal_id);
}
} }
/* /*
@ -446,8 +456,9 @@ ipi_selected(u_int32_t cpus, u_int64_t ipi)
if (pcpu) { if (pcpu) {
atomic_set_64(&pcpu->pc_pending_ipis, ipi); atomic_set_64(&pcpu->pc_pending_ipis, ipi);
alpha_mb(); alpha_mb();
CTR1(KTR_SMP, "calling alpha_pal_wripir(%d)", cpuid); CTR1(KTR_SMP, "calling alpha_pal_wripir(%d)",
alpha_pal_wripir(cpuid); pcpu->pc_pal_id);
alpha_pal_wripir(pcpu->pc_pal_id);
} }
} }
} }
@ -529,8 +540,8 @@ smp_handle_ipi(struct trapframe *frame)
* requests to provide PALcode to secondaries and to start up new * requests to provide PALcode to secondaries and to start up new
* secondaries that are added to the system on the fly. * secondaries that are added to the system on the fly.
*/ */
if (PCPU_GET(cpuid) == boot_cpu_id) { if (PCPU_GET(pal_id) == boot_cpu_id) {
u_int cpuid; u_int pal_id;
u_int64_t txrdy; u_int64_t txrdy;
#ifdef DIAGNOSTIC #ifdef DIAGNOSTIC
struct pcs *cpu; struct pcs *cpu;
@ -539,18 +550,18 @@ smp_handle_ipi(struct trapframe *frame)
alpha_mb(); alpha_mb();
while (hwrpb->rpb_txrdy != 0) { while (hwrpb->rpb_txrdy != 0) {
cpuid = ffs(hwrpb->rpb_txrdy) - 1; pal_id = ffs(hwrpb->rpb_txrdy) - 1;
#ifdef DIAGNOSTIC #ifdef DIAGNOSTIC
cpu = LOCATE_PCS(hwrpb, cpuid); cpu = LOCATE_PCS(hwrpb, pal_id);
bcopy(&cpu->pcs_buffer.txbuf, buf, bcopy(&cpu->pcs_buffer.txbuf, buf,
cpu->pcs_buffer.txlen); cpu->pcs_buffer.txlen);
buf[cpu->pcs_buffer.txlen] = '\0'; buf[cpu->pcs_buffer.txlen] = '\0';
printf("SMP From CPU%d: %s\n", cpuid, buf); printf("SMP From CPU%d: %s\n", pal_id, buf);
#endif #endif
do { do {
txrdy = hwrpb->rpb_txrdy; txrdy = hwrpb->rpb_txrdy;
} while (atomic_cmpset_64(&hwrpb->rpb_txrdy, txrdy, } while (atomic_cmpset_64(&hwrpb->rpb_txrdy, txrdy,
txrdy & ~(1 << cpuid)) == 0); txrdy & ~(1 << pal_id)) == 0);
} }
} }
} }

View File

@ -34,6 +34,7 @@
#define PCPU_MD_FIELDS \ #define PCPU_MD_FIELDS \
struct alpha_pcb pc_idlepcb; /* pcb for idling */ \ struct alpha_pcb pc_idlepcb; /* pcb for idling */ \
u_int64_t pc_pal_id; /* physical CPU ID */ \
u_int64_t pc_idlepcbphys; /* pa of pc_idlepcb */ \ u_int64_t pc_idlepcbphys; /* pa of pc_idlepcb */ \
u_int64_t pc_pending_ipis; /* pending IPI's */ \ u_int64_t pc_pending_ipis; /* pending IPI's */ \
u_int32_t pc_next_asn; /* next ASN to alloc */ \ u_int32_t pc_next_asn; /* next ASN to alloc */ \

View File

@ -26,7 +26,7 @@
#ifndef LOCORE #ifndef LOCORE
extern u_int boot_cpu_id; extern u_int64_t boot_cpu_id;
void ipi_selected(u_int cpus, u_int64_t ipi); void ipi_selected(u_int cpus, u_int64_t ipi);
void ipi_all(u_int64_t ipi); void ipi_all(u_int64_t ipi);