Overhaul the per-CPU support a bit:
- The MI portions of struct globaldata have been consolidated into a MI struct pcpu. The MD per-CPU data are specified via a macro defined in machine/pcpu.h. A macro was chosen over a struct mdpcpu so that the interface would be cleaner (PCPU_GET(my_md_field) vs. PCPU_GET(md.md_my_md_field)). - All references to globaldata are changed to pcpu instead. In a UP kernel, this data was stored as global variables which is where the original name came from. In an SMP world this data is per-CPU and ideally private to each CPU outside of the context of debuggers. This also included combining machine/globaldata.h and machine/globals.h into machine/pcpu.h. - The pointer to the thread using the FPU on i386 was renamed from npxthread to fpcurthread to be identical with other architectures. - Make the show pcpu ddb command MI with a MD callout to display MD fields. - The globaldata_register() function was renamed to pcpu_init() and now init's MI fields of a struct pcpu in addition to registering it with the internal array and list. - A pcpu_destroy() function was added to remove a struct pcpu from the internal array and list. Tested on: alpha, i386 Reviewed by: peter, jake
This commit is contained in:
parent
defd4957cc
commit
0bbc882680
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=87702
@ -571,52 +571,10 @@ db_branch_taken(ins, pc, regs)
|
||||
return (newpc);
|
||||
}
|
||||
|
||||
DB_SHOW_COMMAND(pcpu, db_show_pcpu)
|
||||
void
|
||||
db_show_mdpcpu(struct pcpu *pc)
|
||||
{
|
||||
struct globaldata *gd;
|
||||
#ifdef SMP
|
||||
int id;
|
||||
|
||||
if (have_addr)
|
||||
id = ((addr >> 4) % 16) * 10 + (addr % 16);
|
||||
else
|
||||
id = PCPU_GET(cpuid);
|
||||
gd = globaldata_find(id);
|
||||
if (gd == NULL) {
|
||||
db_printf("CPU %d not found\n", id);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
gd = GLOBALP;
|
||||
#endif
|
||||
db_printf("cpuid = %d\n", gd->gd_cpuid);
|
||||
db_printf("ipis = %lx\n", gd->gd_pending_ipis);
|
||||
db_printf("next ASN = %d\n", gd->gd_next_asn);
|
||||
db_printf("curthread = ");
|
||||
if (gd->gd_curthread != NULL)
|
||||
db_printf("%p: pid %d \"%s\"\n", gd->gd_curthread,
|
||||
gd->gd_curthread->td_proc->p_pid,
|
||||
gd->gd_curthread->td_proc->p_comm);
|
||||
else
|
||||
db_printf("none\n");
|
||||
db_printf("curpcb = %p\n", gd->gd_curpcb);
|
||||
db_printf("fpcurthread = ");
|
||||
if (gd->gd_fpcurthread != NULL)
|
||||
db_printf("%p: pid %d \"%s\"\n", gd->gd_fpcurthread,
|
||||
gd->gd_fpcurthread->td_proc->p_pid,
|
||||
gd->gd_fpcurthread->td_proc->p_comm);
|
||||
else
|
||||
db_printf("none\n");
|
||||
db_printf("idlethread = ");
|
||||
if (gd->gd_idlethread != NULL)
|
||||
db_printf("%p: pid %d \"%s\"\n", gd->gd_idlethread,
|
||||
gd->gd_idlethread->td_proc->p_pid,
|
||||
gd->gd_idlethread->td_proc->p_comm);
|
||||
else
|
||||
db_printf("none\n");
|
||||
|
||||
#ifdef WITNESS
|
||||
db_printf("spin locks held:\n");
|
||||
witness_list_locks(&gd->gd_spinlocks);
|
||||
#endif
|
||||
db_printf("ipis = 0x%lx\n", pc->pc_pending_ipis);
|
||||
db_printf("next ASN = %d\n", pc->pc_next_asn);
|
||||
}
|
||||
|
@ -139,7 +139,7 @@
|
||||
beq t1, exception_return
|
||||
|
||||
/* set the hae register if this process has specified a value */
|
||||
ldq s0, GD_CURTHREAD(globalp)
|
||||
ldq s0, PC_CURTHREAD(pcpup)
|
||||
ldq t1, TD_MD_FLAGS(s0)
|
||||
and t1, MDP_HAEUSED
|
||||
beq t1, 3f
|
||||
@ -255,7 +255,7 @@ LEAF(exception_return, 1) /* XXX should be NESTED */
|
||||
br pv, Ler1
|
||||
Ler1: LDGP(pv)
|
||||
|
||||
ldq s0, GD_CURTHREAD(globalp) /* save curthread in s0 */
|
||||
ldq s0, PC_CURTHREAD(pcpup) /* save curthread in s0 */
|
||||
#ifdef SMP
|
||||
ldl s1, TD_MD_KERNNEST(s0)
|
||||
subl s1, 1, s1 /* decrement nesting level */
|
||||
@ -275,7 +275,7 @@ Ler1: LDGP(pv)
|
||||
Lkernelret:
|
||||
#ifdef SMP
|
||||
beq s1, Lrestoreregs
|
||||
stq globalp, (FRAME_T7*8)(sp) /* fixup globalp */
|
||||
stq pcpup, (FRAME_T7*8)(sp) /* fixup pcpup */
|
||||
#endif
|
||||
|
||||
Lrestoreregs:
|
||||
|
@ -54,7 +54,6 @@
|
||||
#include <sys/ktr.h>
|
||||
#include <machine/frame.h>
|
||||
#include <machine/chipset.h>
|
||||
#include <machine/globaldata.h>
|
||||
#include <sys/vmmeter.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_param.h>
|
||||
@ -68,12 +67,12 @@
|
||||
#include <nfsclient/nfs.h>
|
||||
#include <nfsclient/nfsdiskless.h>
|
||||
|
||||
ASSYM(GD_CURTHREAD, offsetof(struct globaldata, gd_curthread));
|
||||
ASSYM(GD_FPCURTHREAD, offsetof(struct globaldata, gd_fpcurthread));
|
||||
ASSYM(GD_CURPCB, offsetof(struct globaldata, gd_curpcb));
|
||||
ASSYM(GD_SWITCHTIME, offsetof(struct globaldata, gd_switchtime));
|
||||
ASSYM(GD_CPUID, offsetof(struct globaldata, gd_cpuid));
|
||||
ASSYM(GD_IDLEPCBPHYS, offsetof(struct globaldata, gd_idlepcbphys));
|
||||
ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread));
|
||||
ASSYM(PC_FPCURTHREAD, offsetof(struct pcpu, pc_fpcurthread));
|
||||
ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb));
|
||||
ASSYM(PC_SWITCHTIME, offsetof(struct pcpu, pc_switchtime));
|
||||
ASSYM(PC_CPUID, offsetof(struct pcpu, pc_cpuid));
|
||||
ASSYM(PC_IDLEPCBPHYS, offsetof(struct pcpu, pc_idlepcbphys));
|
||||
|
||||
ASSYM(MTX_LOCK, offsetof(struct mtx, mtx_lock));
|
||||
ASSYM(MTX_RECURSE, offsetof(struct mtx, mtx_recurse));
|
||||
|
@ -101,7 +101,7 @@ interrupt(a0, a1, a2, framep)
|
||||
#ifdef SMP
|
||||
s = critical_enter();
|
||||
#endif
|
||||
globalp = (struct globaldata *) alpha_pal_rdval();
|
||||
pcpup = (struct pcpu *) alpha_pal_rdval();
|
||||
td = curthread;
|
||||
#ifdef SMP
|
||||
td->td_md.md_kernnest++;
|
||||
|
@ -81,7 +81,7 @@
|
||||
*/
|
||||
#define SWITCH_CONTEXT \
|
||||
/* Make a note of the context we're running on. */ \
|
||||
stq a0, GD_CURPCB(globalp); \
|
||||
stq a0, PC_CURPCB(pcpup); \
|
||||
\
|
||||
/* Swap in the new context. */ \
|
||||
call_pal PAL_OSF1_swpctx
|
||||
@ -111,10 +111,10 @@
|
||||
call_pal PAL_OSF1_wrvptptr /* clobbers a0, t0, t8-t11 */
|
||||
|
||||
/*
|
||||
* Initialise globalp.
|
||||
* Initialise pcpup.
|
||||
*/
|
||||
call_pal PAL_OSF1_rdval /* clobbers t0, t8-t11 */
|
||||
mov v0, globalp
|
||||
mov v0, pcpup
|
||||
|
||||
/*
|
||||
* Switch to proc0's PCB.
|
||||
@ -148,10 +148,10 @@
|
||||
br pv, 1f
|
||||
1: LDGP(pv)
|
||||
|
||||
call_pal PAL_rdunique /* initialise globalp */
|
||||
mov v0, globalp
|
||||
call_pal PAL_rdunique /* initialise pcpup */
|
||||
mov v0, pcpup
|
||||
|
||||
ldq a0, GD_IDLEPCBPHYS(globalp) /* switch to idle ctx */
|
||||
ldq a0, PC_IDLEPCBPHYS(pcpup) /* switch to idle ctx */
|
||||
call_pal PAL_OSF1_swpctx
|
||||
|
||||
/* Load KGP with current GP. */
|
||||
|
@ -905,14 +905,14 @@ alpha_init(pfn, ptb, bim, bip, biv)
|
||||
(thread0->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
|
||||
/*
|
||||
* Setup the global data for the bootstrap cpu.
|
||||
* Setup the per-CPU data for the bootstrap cpu.
|
||||
*/
|
||||
{
|
||||
/* This is not a 'struct user' */
|
||||
size_t sz = round_page(KSTACK_PAGES * PAGE_SIZE);
|
||||
globalp = (struct globaldata *) pmap_steal_memory(sz);
|
||||
globaldata_init(globalp, alpha_pal_whami(), sz);
|
||||
alpha_pal_wrval((u_int64_t) globalp);
|
||||
pcpup = (struct pcpu *) pmap_steal_memory(sz);
|
||||
pcpu_init(pcpup, alpha_pal_whami(), sz);
|
||||
alpha_pal_wrval((u_int64_t) pcpup);
|
||||
PCPU_GET(next_asn) = 1; /* 0 used for proc0 pmap */
|
||||
#ifdef SMP
|
||||
thread0->td_md.md_kernnest = 1;
|
||||
@ -943,14 +943,8 @@ alpha_init(pfn, ptb, bim, bip, biv)
|
||||
thread0->td_frame = (struct trapframe *)thread0->td_pcb - 1;
|
||||
thread0->td_pcb->pcb_hw.apcb_ksp = (u_int64_t)thread0->td_frame;
|
||||
|
||||
/*
|
||||
* Get the right value for the boot cpu's idle ptbr.
|
||||
*/
|
||||
globalp->gd_idlepcb.apcb_ptbr = thread0->td_pcb->pcb_hw.apcb_ptbr;
|
||||
|
||||
/* Setup curthread so that mutexes work */
|
||||
PCPU_SET(curthread, thread0);
|
||||
PCPU_SET(spinlocks, NULL);
|
||||
|
||||
LIST_INIT(&thread0->td_contested);
|
||||
|
||||
@ -2149,18 +2143,15 @@ alpha_fpstate_switch(struct thread *td)
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialise a struct globaldata.
|
||||
* Initialise a struct pcpu.
|
||||
*/
|
||||
void
|
||||
globaldata_init(struct globaldata *globaldata, int cpuid, size_t sz)
|
||||
cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz)
|
||||
{
|
||||
bzero(globaldata, sz);
|
||||
globaldata->gd_idlepcbphys = vtophys((vm_offset_t) &globaldata->gd_idlepcb);
|
||||
globaldata->gd_idlepcb.apcb_ksp = (u_int64_t)
|
||||
((caddr_t) globaldata + sz - sizeof(struct trapframe));
|
||||
globaldata->gd_idlepcb.apcb_ptbr = thread0->td_pcb->pcb_hw.apcb_ptbr;
|
||||
globaldata->gd_cpuid = cpuid;
|
||||
globaldata->gd_next_asn = 0;
|
||||
globaldata->gd_current_asngen = 1;
|
||||
globaldata_register(globaldata);
|
||||
|
||||
pcpu->pc_idlepcbphys = vtophys((vm_offset_t) &pcpu->pc_idlepcb);
|
||||
pcpu->pc_idlepcb.apcb_ksp = (u_int64_t)
|
||||
((caddr_t) pcpu + sz - sizeof(struct trapframe));
|
||||
pcpu->pc_idlepcb.apcb_ptbr = thread0->td_pcb->pcb_hw.apcb_ptbr;
|
||||
pcpu->pc_current_asngen = 1;
|
||||
}
|
||||
|
@ -46,7 +46,6 @@
|
||||
#include <sys/dkstat.h>
|
||||
|
||||
#include <machine/atomic.h>
|
||||
#include <machine/globaldata.h>
|
||||
#include <machine/pmap.h>
|
||||
#include <machine/rpb.h>
|
||||
#include <machine/clock.h>
|
||||
@ -132,9 +131,9 @@ smp_init_secondary(void)
|
||||
/*spin*/ ;
|
||||
|
||||
/*
|
||||
* Record the globaldata pointer in the per-cpu system value.
|
||||
* Record the pcpu pointer in the per-cpu system value.
|
||||
*/
|
||||
alpha_pal_wrval((u_int64_t) globalp);
|
||||
alpha_pal_wrval((u_int64_t) pcpup);
|
||||
|
||||
/*
|
||||
* Point interrupt/exception vectors to our own.
|
||||
@ -157,9 +156,10 @@ smp_init_secondary(void)
|
||||
/*
|
||||
* Set curproc to our per-cpu idleproc so that mutexes have
|
||||
* something unique to lock with.
|
||||
*
|
||||
* XXX: shouldn't this already be set for us?
|
||||
*/
|
||||
PCPU_SET(curthread, PCPU_GET(idlethread));
|
||||
PCPU_SET(spinlocks, NULL);
|
||||
|
||||
/*
|
||||
* Set flags in our per-CPU slot in the HWRPB.
|
||||
@ -181,7 +181,7 @@ smp_init_secondary(void)
|
||||
* stack pointer for sanity.
|
||||
*/
|
||||
curthread->td_frame =
|
||||
(struct trapframe *)globalp->gd_idlepcb.apcb_ksp;
|
||||
(struct trapframe *)PCPU_PTR(idlepcb)->apcb_ksp;
|
||||
|
||||
mtx_lock_spin(&ap_boot_mtx);
|
||||
|
||||
@ -220,7 +220,7 @@ smp_start_secondary(int cpuid)
|
||||
struct pcs *cpu = LOCATE_PCS(hwrpb, cpuid);
|
||||
struct pcs *bootcpu = LOCATE_PCS(hwrpb, boot_cpu_id);
|
||||
struct alpha_pcb *pcb = (struct alpha_pcb *) cpu->pcs_hwpcb;
|
||||
struct globaldata *globaldata;
|
||||
struct pcpu *pcpu;
|
||||
int i;
|
||||
size_t sz;
|
||||
|
||||
@ -233,21 +233,21 @@ smp_start_secondary(int cpuid)
|
||||
printf("smp_start_secondary: starting cpu %d\n", cpuid);
|
||||
|
||||
sz = round_page((UAREA_PAGES + KSTACK_PAGES) * PAGE_SIZE);
|
||||
globaldata = malloc(sz, M_TEMP, M_NOWAIT);
|
||||
if (!globaldata) {
|
||||
pcpu = malloc(sz, M_TEMP, M_NOWAIT);
|
||||
if (!pcpu) {
|
||||
printf("smp_start_secondary: can't allocate memory\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
globaldata_init(globaldata, cpuid, sz);
|
||||
pcpu_init(pcpu, cpuid, sz);
|
||||
|
||||
/*
|
||||
* Copy the idle pcb and setup the address to start executing.
|
||||
* Use the pcb unique value to point the secondary at its globaldata
|
||||
* Use the pcb unique value to point the secondary at its pcpu
|
||||
* structure.
|
||||
*/
|
||||
*pcb = globaldata->gd_idlepcb;
|
||||
pcb->apcb_unique = (u_int64_t)globaldata;
|
||||
*pcb = pcpu->pc_idlepcb;
|
||||
pcb->apcb_unique = (u_int64_t)pcpu;
|
||||
hwrpb->rpb_restart = (u_int64_t) smp_init_secondary_glue;
|
||||
hwrpb->rpb_restart_val = (u_int64_t) smp_init_secondary_glue;
|
||||
hwrpb->rpb_checksum = hwrpb_checksum();
|
||||
@ -271,10 +271,11 @@ smp_start_secondary(int cpuid)
|
||||
*/
|
||||
if (!smp_send_secondary_command("START\r\n", cpuid)) {
|
||||
printf("smp_start_secondary: can't send START command\n");
|
||||
free(globaldata, M_TEMP);
|
||||
pcpu_destroy(pcpu);
|
||||
free(pcpu, M_TEMP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Wait for the secondary to set the BIP flag in its structure.
|
||||
*/
|
||||
@ -285,9 +286,11 @@ smp_start_secondary(int cpuid)
|
||||
}
|
||||
if (!(cpu->pcs_flags & PCS_BIP)) {
|
||||
printf("smp_start_secondary: secondary did not respond\n");
|
||||
free(globaldata, M_TEMP);
|
||||
pcpu_destroy(pcpu);
|
||||
free(pcpu, M_TEMP);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* It worked (I think).
|
||||
*/
|
||||
@ -410,7 +413,7 @@ cpu_mp_announce(void)
|
||||
void
|
||||
ipi_selected(u_int32_t cpus, u_int64_t ipi)
|
||||
{
|
||||
struct globaldata *globaldata;
|
||||
struct pcpu *pcpu;
|
||||
|
||||
CTR2(KTR_SMP, "ipi_selected: cpus: %x ipi: %lx", cpus, ipi);
|
||||
alpha_mb();
|
||||
@ -418,9 +421,9 @@ ipi_selected(u_int32_t cpus, u_int64_t ipi)
|
||||
int cpuid = ffs(cpus) - 1;
|
||||
cpus &= ~(1 << cpuid);
|
||||
|
||||
globaldata = globaldata_find(cpuid);
|
||||
if (globaldata) {
|
||||
atomic_set_64(&globaldata->gd_pending_ipis, ipi);
|
||||
pcpu = pcpu_find(cpuid);
|
||||
if (pcpu) {
|
||||
atomic_set_64(&pcpu->pc_pending_ipis, ipi);
|
||||
alpha_mb();
|
||||
CTR1(KTR_SMP, "calling alpha_pal_wripir(%d)", cpuid);
|
||||
alpha_pal_wripir(cpuid);
|
||||
|
@ -72,7 +72,7 @@
|
||||
beq t1, fusufault
|
||||
|
||||
lda t0, fusufault /* trap faults */
|
||||
ldq t2, GD_CURTHREAD(globalp)
|
||||
ldq t2, PC_CURTHREAD(pcpup)
|
||||
ldq t2, TD_PCB(t2)
|
||||
stq t0, PCB_ONFAULT(t2)
|
||||
|
||||
@ -92,7 +92,7 @@
|
||||
beq t1, fusufault
|
||||
|
||||
lda t0, fusufault /* trap faults */
|
||||
ldq t2, GD_CURTHREAD(globalp)
|
||||
ldq t2, PC_CURTHREAD(pcpup)
|
||||
ldq t2, TD_PCB(t2)
|
||||
stq t0, PCB_ONFAULT(t2)
|
||||
|
||||
@ -117,7 +117,7 @@
|
||||
beq t1, fusufault
|
||||
|
||||
lda t0, fusufault /* trap faults */
|
||||
ldq t2, GD_CURTHREAD(globalp)
|
||||
ldq t2, PC_CURTHREAD(pcpup)
|
||||
ldq t2, TD_PCB(t2)
|
||||
stq t0, PCB_ONFAULT(t2)
|
||||
|
||||
@ -136,7 +136,7 @@
|
||||
beq t1, fusufault
|
||||
|
||||
lda t0, fusufault /* trap faults */
|
||||
ldq t2, GD_CURTHREAD(globalp)
|
||||
ldq t2, PC_CURTHREAD(pcpup)
|
||||
ldq t2, TD_PCB(t2)
|
||||
stq t0, PCB_ONFAULT(t2)
|
||||
|
||||
@ -154,7 +154,7 @@
|
||||
END(suibyte)
|
||||
|
||||
LEAF(fusufault, 0)
|
||||
ldq t0, GD_CURTHREAD(globalp)
|
||||
ldq t0, PC_CURTHREAD(pcpup)
|
||||
ldq t0, TD_PCB(t0)
|
||||
stq zero, PCB_ONFAULT(t0)
|
||||
ldiq v0, -1
|
||||
@ -222,13 +222,13 @@ NESTED(copyinstr, 4, 16, ra, 0, 0)
|
||||
beq t1, copyerr /* if it's not, error out. */
|
||||
lda v0, copyerr /* set up fault handler. */
|
||||
.set noat
|
||||
ldq at_reg, GD_CURTHREAD(globalp)
|
||||
ldq at_reg, PC_CURTHREAD(pcpup)
|
||||
ldq at_reg, TD_PCB(at_reg)
|
||||
stq v0, PCB_ONFAULT(at_reg)
|
||||
.set at
|
||||
CALL(copystr) /* do the copy. */
|
||||
.set noat
|
||||
ldq at_reg, GD_CURTHREAD(globalp) /* kill the fault handler. */
|
||||
ldq at_reg, PC_CURTHREAD(pcpup) /* kill the fault handler. */
|
||||
ldq at_reg, TD_PCB(at_reg)
|
||||
stq zero, PCB_ONFAULT(at_reg)
|
||||
.set at
|
||||
@ -246,13 +246,13 @@ NESTED(copyoutstr, 4, 16, ra, 0, 0)
|
||||
beq t1, copyerr /* if it's not, error out. */
|
||||
lda v0, copyerr /* set up fault handler. */
|
||||
.set noat
|
||||
ldq at_reg, GD_CURTHREAD(globalp)
|
||||
ldq at_reg, PC_CURTHREAD(pcpup)
|
||||
ldq at_reg, TD_PCB(at_reg)
|
||||
stq v0, PCB_ONFAULT(at_reg)
|
||||
.set at
|
||||
CALL(copystr) /* do the copy. */
|
||||
.set noat
|
||||
ldq at_reg, GD_CURTHREAD(globalp) /* kill the fault handler. */
|
||||
ldq at_reg, PC_CURTHREAD(pcpup) /* kill the fault handler. */
|
||||
ldq at_reg, TD_PCB(at_reg)
|
||||
stq zero, PCB_ONFAULT(at_reg)
|
||||
.set at
|
||||
@ -514,13 +514,13 @@ NESTED(copyin, 3, 16, ra, 0, 0)
|
||||
beq t1, copyerr /* if it's not, error out. */
|
||||
lda v0, copyerr /* set up fault handler. */
|
||||
.set noat
|
||||
ldq at_reg, GD_CURTHREAD(globalp)
|
||||
ldq at_reg, PC_CURTHREAD(pcpup)
|
||||
ldq at_reg, TD_PCB(at_reg)
|
||||
stq v0, PCB_ONFAULT(at_reg)
|
||||
.set at
|
||||
CALL(bcopy) /* do the copy. */
|
||||
.set noat
|
||||
ldq at_reg, GD_CURTHREAD(globalp) /* kill the fault handler. */
|
||||
ldq at_reg, PC_CURTHREAD(pcpup) /* kill the fault handler. */
|
||||
ldq at_reg, TD_PCB(at_reg)
|
||||
stq zero, PCB_ONFAULT(at_reg)
|
||||
.set at
|
||||
@ -539,13 +539,13 @@ NESTED(copyout, 3, 16, ra, 0, 0)
|
||||
beq t1, copyerr /* if it's not, error out. */
|
||||
lda v0, copyerr /* set up fault handler. */
|
||||
.set noat
|
||||
ldq at_reg, GD_CURTHREAD(globalp)
|
||||
ldq at_reg, PC_CURTHREAD(pcpup)
|
||||
ldq at_reg, TD_PCB(at_reg)
|
||||
stq v0, PCB_ONFAULT(at_reg)
|
||||
.set at
|
||||
CALL(bcopy) /* do the copy. */
|
||||
.set noat
|
||||
ldq at_reg, GD_CURTHREAD(globalp) /* kill the fault handler. */
|
||||
ldq at_reg, PC_CURTHREAD(pcpup) /* kill the fault handler. */
|
||||
ldq at_reg, TD_PCB(at_reg)
|
||||
stq zero, PCB_ONFAULT(at_reg)
|
||||
.set at
|
||||
@ -556,7 +556,7 @@ NESTED(copyout, 3, 16, ra, 0, 0)
|
||||
END(copyout)
|
||||
|
||||
LEAF(copyerr, 0)
|
||||
ldq t0, GD_CURTHREAD(globalp)
|
||||
ldq t0, PC_CURTHREAD(pcpup)
|
||||
ldq t0, TD_PCB(t0)
|
||||
stq zero, PCB_ONFAULT(t0) /* reset fault handler. */
|
||||
ldq ra, (16-8)(sp) /* restore ra. */
|
||||
|
@ -41,7 +41,7 @@
|
||||
*/
|
||||
#define SWITCH_CONTEXT \
|
||||
/* Make a note of the context we're running on. */ \
|
||||
stq a0, GD_CURPCB(globalp); \
|
||||
stq a0, PC_CURPCB(pcpup); \
|
||||
\
|
||||
/* Swap in the new context. */ \
|
||||
call_pal PAL_OSF1_swpctx
|
||||
@ -103,7 +103,7 @@ LEAF(cpu_throw, 0)
|
||||
LEAF(cpu_switch, 1)
|
||||
LDGP(pv)
|
||||
/* do an inline savectx(), to save old context */
|
||||
ldq a0, GD_CURTHREAD(globalp)
|
||||
ldq a0, PC_CURTHREAD(pcpup)
|
||||
ldq a1, TD_PCB(a0)
|
||||
/* NOTE: ksp is stored by the swpctx */
|
||||
stq s0, PCB_CONTEXT+(0 * 8)(a1) /* store s0 - s6 */
|
||||
@ -188,7 +188,7 @@ Lcs7:
|
||||
* because we might have re-entered cpu_switch() from idle(),
|
||||
* in which case curthread would be NULL.
|
||||
*/
|
||||
stq s2, GD_CURTHREAD(globalp) /* curthread = p */
|
||||
stq s2, PC_CURTHREAD(pcpup) /* curthread = p */
|
||||
|
||||
/*
|
||||
* Now running on the new u struct.
|
||||
|
@ -272,7 +272,7 @@ trap(a0, a1, a2, entry, framep)
|
||||
#ifdef SMP
|
||||
s = critical_enter();
|
||||
#endif
|
||||
globalp = (struct globaldata *) alpha_pal_rdval();
|
||||
pcpup = (struct pcpu *) alpha_pal_rdval();
|
||||
td = curthread;
|
||||
#ifdef SMP
|
||||
td->td_md.md_kernnest++;
|
||||
@ -674,7 +674,7 @@ syscall(code, framep)
|
||||
#ifdef SMP
|
||||
s = critical_enter();
|
||||
#endif
|
||||
globalp = (struct globaldata *) alpha_pal_rdval();
|
||||
pcpup = (struct pcpu *) alpha_pal_rdval();
|
||||
td = curthread;
|
||||
#ifdef SMP
|
||||
td->td_md.md_kernnest++;
|
||||
|
@ -91,7 +91,7 @@
|
||||
|
||||
/* In the kernel, we use t7 to point at the per-cpu globals. */
|
||||
#ifdef _KERNEL
|
||||
#define globalp $8
|
||||
#define pcpup $8
|
||||
#endif
|
||||
|
||||
/* Floating point registers (XXXX VERIFY THIS) */
|
||||
|
@ -1,74 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Luoqi Chen <luoqi@freebsd.org>
|
||||
* Copyright (c) Peter Wemm <peter@netplex.com.au>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_GLOBALDATA_H_
|
||||
#define _MACHINE_GLOBALDATA_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#include <sys/queue.h>
|
||||
|
||||
/*
|
||||
* This structure maps out the global data that needs to be kept on a
|
||||
* per-cpu basis. genassym uses this to generate offsets for the assembler
|
||||
* code, which also provides external symbols so that C can get at them as
|
||||
* though they were really globals. This structure is pointed to by
|
||||
* the per-cpu system value (see alpha_pal_rdval() and alpha_pal_wrval()).
|
||||
* Inside the kernel, the globally reserved register t7 is used to
|
||||
* point at the globaldata structure.
|
||||
*/
|
||||
struct globaldata {
|
||||
struct alpha_pcb gd_idlepcb; /* pcb for idling */
|
||||
struct thread *gd_curthread; /* current thread */
|
||||
struct thread *gd_idlethread; /* idle thread */
|
||||
struct thread *gd_fpcurthread; /* fp state owner */
|
||||
struct pcb *gd_curpcb; /* current pcb */
|
||||
struct timeval gd_switchtime;
|
||||
int gd_switchticks;
|
||||
u_int gd_cpuid; /* this cpu number */
|
||||
u_int gd_other_cpus; /* all other cpus */
|
||||
u_int64_t gd_idlepcbphys; /* pa of gd_idlepcb */
|
||||
u_int64_t gd_pending_ipis; /* pending IPI events */
|
||||
u_int32_t gd_next_asn; /* next ASN to allocate */
|
||||
u_int32_t gd_current_asngen; /* ASN rollover check */
|
||||
|
||||
SLIST_ENTRY(globaldata) gd_allcpu;
|
||||
struct lock_list_entry *gd_spinlocks;
|
||||
#ifdef KTR_PERCPU
|
||||
int gd_ktr_idx; /* Index into trace table */
|
||||
char *gd_ktr_buf;
|
||||
char gd_ktr_buf_data[0];
|
||||
#endif
|
||||
};
|
||||
|
||||
void globaldata_init(struct globaldata *pcpu, int cpuid, size_t sz);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !_MACHINE_GLOBALDATA_H_ */
|
@ -1,51 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Luoqi Chen <luoqi@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_GLOBALS_H_
|
||||
#define _MACHINE_GLOBALS_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <machine/globaldata.h>
|
||||
|
||||
register struct globaldata *globalp __asm__("$8");
|
||||
|
||||
#define GLOBALP globalp
|
||||
|
||||
#define PCPU_GET(member) (GLOBALP->gd_ ## member)
|
||||
#define PCPU_PTR(member) (&GLOBALP->gd_ ## member)
|
||||
#define PCPU_SET(member,value) (GLOBALP->gd_ ## member = (value))
|
||||
|
||||
#define curthread PCPU_GET(curthread)
|
||||
#define CURPROC (curthread->td_proc)
|
||||
#define curproc (curthread->td_proc)
|
||||
#define curksegrp (curthread->td_ksegrp)
|
||||
#define curkse (curthread->td_kse)
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !_MACHINE_GLOBALS_H_ */
|
@ -58,7 +58,7 @@ extern struct mtx clock_lock;
|
||||
1: ldq_l a0, lck+MTX_LOCK; \
|
||||
cmpeq a0, MTX_UNOWNED, a1; \
|
||||
beq a1, 1b; \
|
||||
ldq a0, PC_CURTHREAD(globalp); \
|
||||
ldq a0, PC_CURTHREAD(pcpup); \
|
||||
stq_c a0, lck+MTX_LOCK; \
|
||||
beq a0, 1b; \
|
||||
mb; \
|
||||
|
@ -33,7 +33,6 @@
|
||||
|
||||
#include <machine/frame.h>
|
||||
#include <machine/reg.h>
|
||||
#include <machine/globaldata.h>
|
||||
#include <machine/alpha_cpu.h>
|
||||
|
||||
/*
|
||||
|
@ -27,48 +27,26 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_GLOBALDATA_H_
|
||||
#define _MACHINE_GLOBALDATA_H_
|
||||
#ifndef _MACHINE_PCPU_H_
|
||||
#define _MACHINE_PCPU_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#include <sys/queue.h>
|
||||
#define PCPU_MD_FIELDS \
|
||||
struct alpha_pcb pc_idlepcb; /* pcb for idling */ \
|
||||
u_int64_t pc_idlepcbphys; /* pa of pc_idlepcb */ \
|
||||
u_int64_t pc_pending_ipis; /* pending IPI's */ \
|
||||
u_int32_t pc_next_asn; /* next ASN to alloc */ \
|
||||
u_int32_t pc_current_asngen /* ASN rollover check */
|
||||
|
||||
/*
|
||||
* This structure maps out the global data that needs to be kept on a
|
||||
* per-cpu basis. genassym uses this to generate offsets for the assembler
|
||||
* code, which also provides external symbols so that C can get at them as
|
||||
* though they were really globals. This structure is pointed to by
|
||||
* the per-cpu system value (see alpha_pal_rdval() and alpha_pal_wrval()).
|
||||
* Inside the kernel, the globally reserved register t7 is used to
|
||||
* point at the globaldata structure.
|
||||
*/
|
||||
struct globaldata {
|
||||
struct alpha_pcb gd_idlepcb; /* pcb for idling */
|
||||
struct thread *gd_curthread; /* current thread */
|
||||
struct thread *gd_idlethread; /* idle thread */
|
||||
struct thread *gd_fpcurthread; /* fp state owner */
|
||||
struct pcb *gd_curpcb; /* current pcb */
|
||||
struct timeval gd_switchtime;
|
||||
int gd_switchticks;
|
||||
u_int gd_cpuid; /* this cpu number */
|
||||
u_int gd_other_cpus; /* all other cpus */
|
||||
u_int64_t gd_idlepcbphys; /* pa of gd_idlepcb */
|
||||
u_int64_t gd_pending_ipis; /* pending IPI events */
|
||||
u_int32_t gd_next_asn; /* next ASN to allocate */
|
||||
u_int32_t gd_current_asngen; /* ASN rollover check */
|
||||
struct pcpu;
|
||||
|
||||
SLIST_ENTRY(globaldata) gd_allcpu;
|
||||
struct lock_list_entry *gd_spinlocks;
|
||||
#ifdef KTR_PERCPU
|
||||
int gd_ktr_idx; /* Index into trace table */
|
||||
char *gd_ktr_buf;
|
||||
char gd_ktr_buf_data[0];
|
||||
#endif
|
||||
};
|
||||
register struct pcpu *pcpup __asm__("$8");
|
||||
|
||||
void globaldata_init(struct globaldata *pcpu, int cpuid, size_t sz);
|
||||
#define PCPU_GET(member) (pcpup->pc_ ## member)
|
||||
#define PCPU_PTR(member) (&pcpup->pc_ ## member)
|
||||
#define PCPU_SET(member,value) (pcpup->pc_ ## member = (value))
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !_MACHINE_GLOBALDATA_H_ */
|
||||
#endif /* !_MACHINE_PCPU_H_ */
|
||||
|
@ -31,9 +31,6 @@
|
||||
#ifndef _MACHINE_PROC_H_
|
||||
#define _MACHINE_PROC_H_
|
||||
|
||||
#include <machine/globaldata.h>
|
||||
#include <machine/globals.h>
|
||||
|
||||
/*
|
||||
* Machine-dependent part of the proc struct for the Alpha.
|
||||
*/
|
||||
|
@ -36,9 +36,9 @@
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/pcpu.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
#include <machine/globals.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/segments.h>
|
||||
#include <machine/stdarg.h>
|
||||
|
@ -123,7 +123,7 @@ ENTRY(cpu_switch)
|
||||
|
||||
#ifdef DEV_NPX
|
||||
/* have we used fp, and need a save? */
|
||||
cmpl %ecx,PCPU(NPXTHREAD)
|
||||
cmpl %ecx,PCPU(FPCURTHREAD)
|
||||
jne 1f
|
||||
addl $PCB_SAVEFPU,%edx /* h/w bugs make saving complicated */
|
||||
pushl %edx
|
||||
@ -337,20 +337,20 @@ ENTRY(savectx)
|
||||
|
||||
#ifdef DEV_NPX
|
||||
/*
|
||||
* If npxthread == NULL, then the npx h/w state is irrelevant and the
|
||||
* If fpcurthread == NULL, then the npx h/w state is irrelevant and the
|
||||
* state had better already be in the pcb. This is true for forks
|
||||
* but not for dumps (the old book-keeping with FP flags in the pcb
|
||||
* always lost for dumps because the dump pcb has 0 flags).
|
||||
*
|
||||
* If npxthread != NULL, then we have to save the npx h/w state to
|
||||
* npxthread's pcb and copy it to the requested pcb, or save to the
|
||||
* If fpcurthread != NULL, then we have to save the npx h/w state to
|
||||
* fpcurthread's pcb and copy it to the requested pcb, or save to the
|
||||
* requested pcb and reload. Copying is easier because we would
|
||||
* have to handle h/w bugs for reloading. We used to lose the
|
||||
* parent's npx state for forks by forgetting to reload.
|
||||
*/
|
||||
pushfl
|
||||
cli
|
||||
movl PCPU(NPXTHREAD),%eax
|
||||
movl PCPU(FPCURTHREAD),%eax
|
||||
testl %eax,%eax
|
||||
je 1f
|
||||
|
||||
|
@ -332,48 +332,9 @@ Debugger(msg)
|
||||
}
|
||||
}
|
||||
|
||||
DB_SHOW_COMMAND(pcpu, db_show_pcpu)
|
||||
void
|
||||
db_show_mdpcpu(struct pcpu *pc)
|
||||
{
|
||||
struct globaldata *gd;
|
||||
#ifdef SMP
|
||||
int id;
|
||||
|
||||
if (have_addr)
|
||||
id = ((addr >> 4) % 16) * 10 + (addr % 16);
|
||||
else
|
||||
id = PCPU_GET(cpuid);
|
||||
gd = globaldata_find(id);
|
||||
if (gd == NULL) {
|
||||
db_printf("CPU %d not found\n", id);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
gd = GLOBALDATA;
|
||||
#endif
|
||||
db_printf("cpuid = %d\n", gd->gd_cpuid);
|
||||
db_printf("curthread = ");
|
||||
if (gd->gd_curthread != NULL)
|
||||
db_printf("%p: pid %d \"%s\"\n", gd->gd_curthread,
|
||||
gd->gd_curthread->td_proc->p_pid, gd->gd_curthread->td_proc->p_comm);
|
||||
else
|
||||
db_printf("none\n");
|
||||
db_printf("curpcb = %p\n", gd->gd_curpcb);
|
||||
db_printf("npxthread = ");
|
||||
if (gd->gd_npxthread != NULL)
|
||||
db_printf("%p: pid %d \"%s\"\n", gd->gd_npxthread,
|
||||
gd->gd_npxthread->td_proc->p_pid, gd->gd_npxthread->td_proc->p_comm);
|
||||
else
|
||||
db_printf("none\n");
|
||||
db_printf("idlethread = ");
|
||||
if (gd->gd_idlethread != NULL)
|
||||
db_printf("%p: pid %d \"%s\"\n", gd->gd_idlethread,
|
||||
gd->gd_idlethread->td_proc->p_pid,
|
||||
gd->gd_idlethread->td_proc->p_comm);
|
||||
else
|
||||
db_printf("none\n");
|
||||
|
||||
#ifdef WITNESS
|
||||
db_printf("spin locks held:\n");
|
||||
witness_list_locks(&gd->gd_spinlocks);
|
||||
#endif
|
||||
db_printf("currentldt = 0x%x\n", pc->pc_currentldt);
|
||||
}
|
||||
|
@ -237,7 +237,7 @@ npx_intr(dummy)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* npxthread is normally non-null here. In that case, schedule an
|
||||
* fpcurthread is normally non-null here. In that case, schedule an
|
||||
* AST to finish the exception handling in the correct context
|
||||
* (this interrupt may occur after the thread has entered the
|
||||
* kernel via a syscall or an interrupt). Otherwise, the npx
|
||||
@ -248,7 +248,7 @@ npx_intr(dummy)
|
||||
* that caused it and it will repeat. We will eventually (usually
|
||||
* soon) win the race to handle the interrupt properly.
|
||||
*/
|
||||
td = PCPU_GET(npxthread);
|
||||
td = PCPU_GET(fpcurthread);
|
||||
if (td != NULL) {
|
||||
td->td_pcb->pcb_flags |= PCB_NPXTRAP;
|
||||
mtx_lock_spin(&sched_lock);
|
||||
@ -513,7 +513,7 @@ npxinit(control)
|
||||
/*
|
||||
* fninit has the same h/w bugs as fnsave. Use the detoxified
|
||||
* fnsave to throw away any junk in the fpu. npxsave() initializes
|
||||
* the fpu and sets npxthread = NULL as important side effects.
|
||||
* the fpu and sets fpcurthread = NULL as important side effects.
|
||||
*/
|
||||
savecrit = critical_enter();
|
||||
npxsave(&dummy);
|
||||
@ -540,7 +540,7 @@ npxexit(td)
|
||||
critical_t savecrit;
|
||||
|
||||
savecrit = critical_enter();
|
||||
if (td == PCPU_GET(npxthread))
|
||||
if (td == PCPU_GET(fpcurthread))
|
||||
npxsave(&PCPU_GET(curpcb)->pcb_save);
|
||||
critical_exit(savecrit);
|
||||
#ifdef NPX_DEBUG
|
||||
@ -758,8 +758,8 @@ npxtrap()
|
||||
u_long *exstat;
|
||||
|
||||
if (!npx_exists) {
|
||||
printf("npxtrap: npxthread = %p, curthread = %p, npx_exists = %d\n",
|
||||
PCPU_GET(npxthread), curthread, npx_exists);
|
||||
printf("npxtrap: fpcurthread = %p, curthread = %p, npx_exists = %d\n",
|
||||
PCPU_GET(fpcurthread), curthread, npx_exists);
|
||||
panic("npxtrap from nowhere");
|
||||
}
|
||||
savecrit = critical_enter();
|
||||
@ -769,7 +769,7 @@ npxtrap()
|
||||
* state to memory. Fetch the relevant parts of the state from
|
||||
* wherever they are.
|
||||
*/
|
||||
if (PCPU_GET(npxthread) != curthread) {
|
||||
if (PCPU_GET(fpcurthread) != curthread) {
|
||||
control = GET_FPU_CW(curthread);
|
||||
status = GET_FPU_SW(curthread);
|
||||
} else {
|
||||
@ -779,7 +779,7 @@ npxtrap()
|
||||
|
||||
exstat = GET_FPU_EXSW_PTR(curthread->td_pcb);
|
||||
*exstat = status;
|
||||
if (PCPU_GET(npxthread) != curthread)
|
||||
if (PCPU_GET(fpcurthread) != curthread)
|
||||
GET_FPU_SW(curthread) &= ~0x80bf;
|
||||
else
|
||||
fnclex();
|
||||
@ -790,7 +790,7 @@ npxtrap()
|
||||
/*
|
||||
* Implement device not available (DNA) exception
|
||||
*
|
||||
* It would be better to switch FP context here (if curthread != npxthread)
|
||||
* It would be better to switch FP context here (if curthread != fpcurthread)
|
||||
* and not necessarily for every context switch, but it is too hard to
|
||||
* access foreign pcb's.
|
||||
*/
|
||||
@ -802,9 +802,9 @@ npxdna()
|
||||
|
||||
if (!npx_exists)
|
||||
return (0);
|
||||
if (PCPU_GET(npxthread) != NULL) {
|
||||
printf("npxdna: npxthread = %p, curthread = %p\n",
|
||||
PCPU_GET(npxthread), curthread);
|
||||
if (PCPU_GET(fpcurthread) != NULL) {
|
||||
printf("npxdna: fpcurthread = %p, curthread = %p\n",
|
||||
PCPU_GET(fpcurthread), curthread);
|
||||
panic("npxdna");
|
||||
}
|
||||
s = critical_enter();
|
||||
@ -812,7 +812,7 @@ npxdna()
|
||||
/*
|
||||
* Record new context early in case frstor causes an IRQ13.
|
||||
*/
|
||||
PCPU_SET(npxthread, curthread);
|
||||
PCPU_SET(fpcurthread, curthread);
|
||||
|
||||
exstat = GET_FPU_EXSW_PTR(PCPU_GET(curpcb));
|
||||
*exstat = 0;
|
||||
@ -844,13 +844,13 @@ npxdna()
|
||||
* after the process has entered the kernel. It may even be delivered after
|
||||
* the fnsave here completes. A spurious IRQ13 for the fnsave is handled in
|
||||
* the same way as a very-late-arriving non-spurious IRQ13 from user mode:
|
||||
* it is normally ignored at first because we set npxthread to NULL; it is
|
||||
* it is normally ignored at first because we set fpcurthread to NULL; it is
|
||||
* normally retriggered in npxdna() after return to user mode.
|
||||
*
|
||||
* npxsave() must be called with interrupts disabled, so that it clears
|
||||
* npxthread atomically with saving the state. We require callers to do the
|
||||
* fpcurthread atomically with saving the state. We require callers to do the
|
||||
* disabling, since most callers need to disable interrupts anyway to call
|
||||
* npxsave() atomically with checking npxthread.
|
||||
* npxsave() atomically with checking fpcurthread.
|
||||
*
|
||||
* A previous version of npxsave() went to great lengths to excecute fnsave
|
||||
* with interrupts enabled in case executing it froze the CPU. This case
|
||||
@ -866,7 +866,7 @@ npxsave(addr)
|
||||
fpusave(addr);
|
||||
|
||||
start_emulating();
|
||||
PCPU_SET(npxthread, NULL);
|
||||
PCPU_SET(fpcurthread, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -51,10 +51,6 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/resourcevar.h>
|
||||
#include <sys/user.h>
|
||||
/* XXX */
|
||||
#ifdef KTR_PERCPU
|
||||
#include <sys/ktr.h>
|
||||
#endif
|
||||
#include <machine/bootinfo.h>
|
||||
#include <machine/tss.h>
|
||||
#include <sys/vmmeter.h>
|
||||
@ -75,7 +71,6 @@
|
||||
#endif
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/sigframe.h>
|
||||
#include <machine/globaldata.h>
|
||||
#include <machine/vm86.h>
|
||||
#include <machine/proc.h>
|
||||
|
||||
@ -177,27 +172,19 @@ ASSYM(BI_SIZE, offsetof(struct bootinfo, bi_size));
|
||||
ASSYM(BI_SYMTAB, offsetof(struct bootinfo, bi_symtab));
|
||||
ASSYM(BI_ESYMTAB, offsetof(struct bootinfo, bi_esymtab));
|
||||
ASSYM(BI_KERNEND, offsetof(struct bootinfo, bi_kernend));
|
||||
ASSYM(GD_SIZEOF, sizeof(struct globaldata));
|
||||
ASSYM(GD_PRVSPACE, offsetof(struct globaldata, gd_prvspace));
|
||||
ASSYM(GD_CURTHREAD, offsetof(struct globaldata, gd_curthread));
|
||||
ASSYM(GD_NPXTHREAD, offsetof(struct globaldata, gd_npxthread));
|
||||
ASSYM(GD_IDLETHREAD, offsetof(struct globaldata, gd_idlethread));
|
||||
ASSYM(GD_CURPCB, offsetof(struct globaldata, gd_curpcb));
|
||||
ASSYM(GD_COMMON_TSS, offsetof(struct globaldata, gd_common_tss));
|
||||
ASSYM(GD_SWITCHTIME, offsetof(struct globaldata, gd_switchtime));
|
||||
ASSYM(GD_SWITCHTICKS, offsetof(struct globaldata, gd_switchticks));
|
||||
ASSYM(GD_COMMON_TSSD, offsetof(struct globaldata, gd_common_tssd));
|
||||
ASSYM(GD_TSS_GDT, offsetof(struct globaldata, gd_tss_gdt));
|
||||
ASSYM(GD_CURRENTLDT, offsetof(struct globaldata, gd_currentldt));
|
||||
|
||||
/* XXX */
|
||||
#ifdef KTR_PERCPU
|
||||
ASSYM(GD_KTR_IDX, offsetof(struct globaldata, gd_ktr_idx));
|
||||
ASSYM(GD_KTR_BUF, offsetof(struct globaldata, gd_ktr_buf));
|
||||
ASSYM(GD_KTR_BUF_DATA, offsetof(struct globaldata, gd_ktr_buf_data));
|
||||
#endif
|
||||
|
||||
ASSYM(GD_CPUID, offsetof(struct globaldata, gd_cpuid));
|
||||
ASSYM(PC_SIZEOF, sizeof(struct pcpu));
|
||||
ASSYM(PC_PRVSPACE, offsetof(struct pcpu, pc_prvspace));
|
||||
ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread));
|
||||
ASSYM(PC_FPCURTHREAD, offsetof(struct pcpu, pc_fpcurthread));
|
||||
ASSYM(PC_IDLETHREAD, offsetof(struct pcpu, pc_idlethread));
|
||||
ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb));
|
||||
ASSYM(PC_COMMON_TSS, offsetof(struct pcpu, pc_common_tss));
|
||||
ASSYM(PC_SWITCHTIME, offsetof(struct pcpu, pc_switchtime));
|
||||
ASSYM(PC_SWITCHTICKS, offsetof(struct pcpu, pc_switchticks));
|
||||
ASSYM(PC_COMMON_TSSD, offsetof(struct pcpu, pc_common_tssd));
|
||||
ASSYM(PC_TSS_GDT, offsetof(struct pcpu, pc_tss_gdt));
|
||||
ASSYM(PC_CURRENTLDT, offsetof(struct pcpu, pc_currentldt));
|
||||
ASSYM(PC_CPUID, offsetof(struct pcpu, pc_cpuid));
|
||||
|
||||
#ifdef SMP
|
||||
ASSYM(LA_VER, offsetof(struct LAPIC, version));
|
||||
|
@ -104,7 +104,6 @@
|
||||
#include <machine/pc/bios.h>
|
||||
#include <machine/pcb_ext.h> /* pcb.h included via sys/user.h */
|
||||
#include <machine/proc.h>
|
||||
#include <machine/globals.h>
|
||||
#ifdef PERFMON
|
||||
#include <machine/perfmon.h>
|
||||
#endif
|
||||
@ -207,7 +206,7 @@ struct kva_md_info kmi;
|
||||
|
||||
static struct trapframe proc0_tf;
|
||||
#ifndef SMP
|
||||
static struct globaldata __globaldata;
|
||||
static struct pcpu __pcpu;
|
||||
#endif
|
||||
|
||||
struct mtx sched_lock;
|
||||
@ -262,7 +261,6 @@ cpu_startup(dummy)
|
||||
bufinit();
|
||||
vm_pager_bufferinit();
|
||||
|
||||
globaldata_register(GLOBALDATA);
|
||||
#ifndef SMP
|
||||
/* For SMP, we delay the cpu_setregs() until after SMP startup. */
|
||||
cpu_setregs();
|
||||
@ -1670,6 +1668,7 @@ init386(first)
|
||||
/* table descriptors - used to load tables by microp */
|
||||
struct region_descriptor r_gdt, r_idt;
|
||||
#endif
|
||||
struct pcpu *pc;
|
||||
|
||||
proc_linkup(&proc0);
|
||||
proc0.p_uarea = proc0uarea;
|
||||
@ -1706,20 +1705,16 @@ init386(first)
|
||||
gdt_segs[GCODE_SEL].ssd_limit = atop(0 - 1);
|
||||
gdt_segs[GDATA_SEL].ssd_limit = atop(0 - 1);
|
||||
#ifdef SMP
|
||||
pc = &SMP_prvspace[0];
|
||||
gdt_segs[GPRIV_SEL].ssd_limit =
|
||||
atop(sizeof(struct privatespace) - 1);
|
||||
gdt_segs[GPRIV_SEL].ssd_base = (int) &SMP_prvspace[0];
|
||||
gdt_segs[GPROC0_SEL].ssd_base =
|
||||
(int) &SMP_prvspace[0].globaldata.gd_common_tss;
|
||||
SMP_prvspace[0].globaldata.gd_prvspace = &SMP_prvspace[0].globaldata;
|
||||
#else
|
||||
pc = &__pcpu;
|
||||
gdt_segs[GPRIV_SEL].ssd_limit =
|
||||
atop(sizeof(struct globaldata) - 1);
|
||||
gdt_segs[GPRIV_SEL].ssd_base = (int) &__globaldata;
|
||||
gdt_segs[GPROC0_SEL].ssd_base =
|
||||
(int) &__globaldata.gd_common_tss;
|
||||
__globaldata.gd_prvspace = &__globaldata;
|
||||
atop(sizeof(struct pcpu) - 1);
|
||||
#endif
|
||||
gdt_segs[GPRIV_SEL].ssd_base = (int) pc;
|
||||
gdt_segs[GPROC0_SEL].ssd_base = (int) &pc->pc_common_tss;
|
||||
|
||||
for (x = 0; x < NGDT; x++) {
|
||||
#ifdef BDE_DEBUGGER
|
||||
@ -1734,10 +1729,11 @@ init386(first)
|
||||
r_gdt.rd_base = (int) gdt;
|
||||
lgdt(&r_gdt);
|
||||
|
||||
/* setup curproc so that mutexes work */
|
||||
pcpu_init(pc, 0, sizeof(struct pcpu));
|
||||
PCPU_SET(prvspace, pc);
|
||||
|
||||
/* setup curproc so that mutexes work */
|
||||
PCPU_SET(curthread, thread0);
|
||||
PCPU_SET(spinlocks, NULL);
|
||||
|
||||
LIST_INIT(&thread0->td_contested);
|
||||
|
||||
@ -1907,6 +1903,11 @@ init386(first)
|
||||
thread0->td_frame = &proc0_tf;
|
||||
}
|
||||
|
||||
void
|
||||
cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(I586_CPU) && !defined(NO_F00F_HACK)
|
||||
static void f00f_hack(void *unused);
|
||||
SYSINIT(f00f_hack, SI_SUB_INTRINSIC, SI_ORDER_FIRST, f00f_hack, NULL);
|
||||
|
@ -71,7 +71,6 @@
|
||||
#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, TEST_TEST1 */
|
||||
#include <machine/tss.h>
|
||||
#include <machine/specialreg.h>
|
||||
#include <machine/globaldata.h>
|
||||
#include <machine/privatespace.h>
|
||||
|
||||
#if defined(APIC_IO)
|
||||
@ -477,9 +476,9 @@ init_secondary(void)
|
||||
|
||||
gdt_segs[GPRIV_SEL].ssd_base = (int) &SMP_prvspace[myid];
|
||||
gdt_segs[GPROC0_SEL].ssd_base =
|
||||
(int) &SMP_prvspace[myid].globaldata.gd_common_tss;
|
||||
SMP_prvspace[myid].globaldata.gd_prvspace =
|
||||
&SMP_prvspace[myid].globaldata;
|
||||
(int) &SMP_prvspace[myid].pcpu.pc_common_tss;
|
||||
SMP_prvspace[myid].pcpu.pc_prvspace =
|
||||
&SMP_prvspace[myid].pcpu;
|
||||
|
||||
for (x = 0; x < NGDT; x++) {
|
||||
ssdtosd(&gdt_segs[x], &gdt[myid * NGDT + x].sd);
|
||||
@ -1915,7 +1914,7 @@ start_all_aps(u_int boot_addr)
|
||||
int x, i, pg;
|
||||
u_char mpbiosreason;
|
||||
u_long mpbioswarmvec;
|
||||
struct globaldata *gd;
|
||||
struct pcpu *pc;
|
||||
char *stack;
|
||||
uintptr_t kptbase;
|
||||
|
||||
@ -1955,10 +1954,10 @@ start_all_aps(u_int boot_addr)
|
||||
pg = x * i386_btop(sizeof(struct privatespace));
|
||||
|
||||
/* allocate a new private data page */
|
||||
gd = (struct globaldata *)kmem_alloc(kernel_map, PAGE_SIZE);
|
||||
pc = (struct pcpu *)kmem_alloc(kernel_map, PAGE_SIZE);
|
||||
|
||||
/* wire it into the private page table page */
|
||||
SMPpt[pg] = (pt_entry_t)(PG_V | PG_RW | vtophys(gd));
|
||||
SMPpt[pg] = (pt_entry_t)(PG_V | PG_RW | vtophys(pc));
|
||||
|
||||
/* allocate and set up an idle stack data page */
|
||||
stack = (char *)kmem_alloc(kernel_map, KSTACK_PAGES * PAGE_SIZE); /* XXXKSE */
|
||||
@ -1967,8 +1966,7 @@ start_all_aps(u_int boot_addr)
|
||||
(PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack));
|
||||
|
||||
/* prime data page for it to use */
|
||||
gd->gd_cpuid = x;
|
||||
globaldata_register(gd);
|
||||
pcpu_init(pc, x, sizeof(struct pcpu));
|
||||
|
||||
/* setup a vector to our boot code */
|
||||
*((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET;
|
||||
|
@ -71,7 +71,6 @@
|
||||
#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, TEST_TEST1 */
|
||||
#include <machine/tss.h>
|
||||
#include <machine/specialreg.h>
|
||||
#include <machine/globaldata.h>
|
||||
#include <machine/privatespace.h>
|
||||
|
||||
#if defined(APIC_IO)
|
||||
@ -477,9 +476,9 @@ init_secondary(void)
|
||||
|
||||
gdt_segs[GPRIV_SEL].ssd_base = (int) &SMP_prvspace[myid];
|
||||
gdt_segs[GPROC0_SEL].ssd_base =
|
||||
(int) &SMP_prvspace[myid].globaldata.gd_common_tss;
|
||||
SMP_prvspace[myid].globaldata.gd_prvspace =
|
||||
&SMP_prvspace[myid].globaldata;
|
||||
(int) &SMP_prvspace[myid].pcpu.pc_common_tss;
|
||||
SMP_prvspace[myid].pcpu.pc_prvspace =
|
||||
&SMP_prvspace[myid].pcpu;
|
||||
|
||||
for (x = 0; x < NGDT; x++) {
|
||||
ssdtosd(&gdt_segs[x], &gdt[myid * NGDT + x].sd);
|
||||
@ -1915,7 +1914,7 @@ start_all_aps(u_int boot_addr)
|
||||
int x, i, pg;
|
||||
u_char mpbiosreason;
|
||||
u_long mpbioswarmvec;
|
||||
struct globaldata *gd;
|
||||
struct pcpu *pc;
|
||||
char *stack;
|
||||
uintptr_t kptbase;
|
||||
|
||||
@ -1955,10 +1954,10 @@ start_all_aps(u_int boot_addr)
|
||||
pg = x * i386_btop(sizeof(struct privatespace));
|
||||
|
||||
/* allocate a new private data page */
|
||||
gd = (struct globaldata *)kmem_alloc(kernel_map, PAGE_SIZE);
|
||||
pc = (struct pcpu *)kmem_alloc(kernel_map, PAGE_SIZE);
|
||||
|
||||
/* wire it into the private page table page */
|
||||
SMPpt[pg] = (pt_entry_t)(PG_V | PG_RW | vtophys(gd));
|
||||
SMPpt[pg] = (pt_entry_t)(PG_V | PG_RW | vtophys(pc));
|
||||
|
||||
/* allocate and set up an idle stack data page */
|
||||
stack = (char *)kmem_alloc(kernel_map, KSTACK_PAGES * PAGE_SIZE); /* XXXKSE */
|
||||
@ -1967,8 +1966,7 @@ start_all_aps(u_int boot_addr)
|
||||
(PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack));
|
||||
|
||||
/* prime data page for it to use */
|
||||
gd->gd_cpuid = x;
|
||||
globaldata_register(gd);
|
||||
pcpu_init(pc, x, sizeof(struct pcpu));
|
||||
|
||||
/* setup a vector to our boot code */
|
||||
*((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET;
|
||||
|
@ -105,7 +105,6 @@
|
||||
#include <machine/apic.h>
|
||||
#include <machine/segments.h>
|
||||
#include <machine/tss.h>
|
||||
#include <machine/globaldata.h>
|
||||
#endif /* SMP || APIC_IO */
|
||||
|
||||
#define PMAP_KEEP_PDIRS
|
||||
|
@ -216,8 +216,8 @@ ENTRY(i586_bzero)
|
||||
* complicated since we avoid it if possible at all levels. We
|
||||
* want to localize the complications even when that increases them.
|
||||
* Here the extra work involves preserving CR0_TS in TS.
|
||||
* `npxthread != NULL' is supposed to be the condition that all the
|
||||
* FPU resources belong to an application, but npxthread and CR0_TS
|
||||
* `fpcurthread != NULL' is supposed to be the condition that all the
|
||||
* FPU resources belong to an application, but fpcurthread and CR0_TS
|
||||
* aren't set atomically enough for this condition to work in
|
||||
* interrupt handlers.
|
||||
*
|
||||
@ -241,7 +241,7 @@ ENTRY(i586_bzero)
|
||||
* method. CR0_TS must be preserved although it is very likely to
|
||||
* always end up as clear.
|
||||
*/
|
||||
cmpl $0,PCPU(NPXTHREAD)
|
||||
cmpl $0,PCPU(FPCURTHREAD)
|
||||
je i586_bz1
|
||||
|
||||
/*
|
||||
@ -303,7 +303,7 @@ fpureg_i586_bzero_loop:
|
||||
cmpl $8,%ecx
|
||||
jae fpureg_i586_bzero_loop
|
||||
|
||||
cmpl $0,PCPU(NPXTHREAD)
|
||||
cmpl $0,PCPU(FPCURTHREAD)
|
||||
je i586_bz3
|
||||
|
||||
/* XXX check that the condition for cases 1-2 stayed false. */
|
||||
@ -517,7 +517,7 @@ ENTRY(i586_bcopy)
|
||||
|
||||
sarb $1,kernel_fpu_lock
|
||||
jc small_i586_bcopy
|
||||
cmpl $0,PCPU(NPXTHREAD)
|
||||
cmpl $0,PCPU(FPCURTHREAD)
|
||||
je i586_bc1
|
||||
|
||||
/* XXX turn off handling of cases 1-2, as above. */
|
||||
@ -593,7 +593,7 @@ large_i586_bcopy_loop:
|
||||
cmpl $64,%ecx
|
||||
jae 4b
|
||||
|
||||
cmpl $0,PCPU(NPXTHREAD)
|
||||
cmpl $0,PCPU(FPCURTHREAD)
|
||||
je i586_bc2
|
||||
|
||||
/* XXX check that the condition for cases 1-2 stayed false. */
|
||||
@ -991,14 +991,14 @@ ENTRY(fastmove)
|
||||
/* XXX grab FPU context atomically. */
|
||||
cli
|
||||
|
||||
/* if (npxthread != NULL) { */
|
||||
cmpl $0,PCPU(NPXTHREAD)
|
||||
/* if (fpcurthread != NULL) { */
|
||||
cmpl $0,PCPU(FPCURTHREAD)
|
||||
je 6f
|
||||
/* fnsave(&curpcb->pcb_savefpu); */
|
||||
movl PCPU(CURPCB),%eax
|
||||
fnsave PCB_SAVEFPU(%eax)
|
||||
/* NPXTHREAD = NULL; */
|
||||
movl $0,PCPU(NPXTHREAD)
|
||||
/* FPCURTHREAD = NULL; */
|
||||
movl $0,PCPU(FPCURTHREAD)
|
||||
/* } */
|
||||
6:
|
||||
/* now we own the FPU. */
|
||||
@ -1026,9 +1026,9 @@ ENTRY(fastmove)
|
||||
movl -4(%ebp),%edi
|
||||
/* stop_emulating(); */
|
||||
clts
|
||||
/* npxthread = curthread; */
|
||||
/* fpcurthread = curthread; */
|
||||
movl PCPU(CURTHREAD),%eax
|
||||
movl %eax,PCPU(NPXTHREAD)
|
||||
movl %eax,PCPU(FPCURTHREAD)
|
||||
movl PCPU(CURPCB),%eax
|
||||
|
||||
/* XXX end of atomic FPU context grab. */
|
||||
@ -1113,8 +1113,8 @@ fastmove_loop:
|
||||
smsw %ax
|
||||
orb $CR0_TS,%al
|
||||
lmsw %ax
|
||||
/* npxthread = NULL; */
|
||||
movl $0,PCPU(NPXTHREAD)
|
||||
/* fpcurthread = NULL; */
|
||||
movl $0,PCPU(FPCURTHREAD)
|
||||
|
||||
/* XXX end of atomic FPU context ungrab. */
|
||||
sti
|
||||
@ -1154,7 +1154,7 @@ fastmove_fault:
|
||||
smsw %ax
|
||||
orb $CR0_TS,%al
|
||||
lmsw %ax
|
||||
movl $0,PCPU(NPXTHREAD)
|
||||
movl $0,PCPU(FPCURTHREAD)
|
||||
|
||||
/* XXX end of atomic FPU context ungrab. */
|
||||
sti
|
||||
|
@ -216,8 +216,8 @@ ENTRY(i586_bzero)
|
||||
* complicated since we avoid it if possible at all levels. We
|
||||
* want to localize the complications even when that increases them.
|
||||
* Here the extra work involves preserving CR0_TS in TS.
|
||||
* `npxthread != NULL' is supposed to be the condition that all the
|
||||
* FPU resources belong to an application, but npxthread and CR0_TS
|
||||
* `fpcurthread != NULL' is supposed to be the condition that all the
|
||||
* FPU resources belong to an application, but fpcurthread and CR0_TS
|
||||
* aren't set atomically enough for this condition to work in
|
||||
* interrupt handlers.
|
||||
*
|
||||
@ -241,7 +241,7 @@ ENTRY(i586_bzero)
|
||||
* method. CR0_TS must be preserved although it is very likely to
|
||||
* always end up as clear.
|
||||
*/
|
||||
cmpl $0,PCPU(NPXTHREAD)
|
||||
cmpl $0,PCPU(FPCURTHREAD)
|
||||
je i586_bz1
|
||||
|
||||
/*
|
||||
@ -303,7 +303,7 @@ fpureg_i586_bzero_loop:
|
||||
cmpl $8,%ecx
|
||||
jae fpureg_i586_bzero_loop
|
||||
|
||||
cmpl $0,PCPU(NPXTHREAD)
|
||||
cmpl $0,PCPU(FPCURTHREAD)
|
||||
je i586_bz3
|
||||
|
||||
/* XXX check that the condition for cases 1-2 stayed false. */
|
||||
@ -517,7 +517,7 @@ ENTRY(i586_bcopy)
|
||||
|
||||
sarb $1,kernel_fpu_lock
|
||||
jc small_i586_bcopy
|
||||
cmpl $0,PCPU(NPXTHREAD)
|
||||
cmpl $0,PCPU(FPCURTHREAD)
|
||||
je i586_bc1
|
||||
|
||||
/* XXX turn off handling of cases 1-2, as above. */
|
||||
@ -593,7 +593,7 @@ large_i586_bcopy_loop:
|
||||
cmpl $64,%ecx
|
||||
jae 4b
|
||||
|
||||
cmpl $0,PCPU(NPXTHREAD)
|
||||
cmpl $0,PCPU(FPCURTHREAD)
|
||||
je i586_bc2
|
||||
|
||||
/* XXX check that the condition for cases 1-2 stayed false. */
|
||||
@ -991,14 +991,14 @@ ENTRY(fastmove)
|
||||
/* XXX grab FPU context atomically. */
|
||||
cli
|
||||
|
||||
/* if (npxthread != NULL) { */
|
||||
cmpl $0,PCPU(NPXTHREAD)
|
||||
/* if (fpcurthread != NULL) { */
|
||||
cmpl $0,PCPU(FPCURTHREAD)
|
||||
je 6f
|
||||
/* fnsave(&curpcb->pcb_savefpu); */
|
||||
movl PCPU(CURPCB),%eax
|
||||
fnsave PCB_SAVEFPU(%eax)
|
||||
/* NPXTHREAD = NULL; */
|
||||
movl $0,PCPU(NPXTHREAD)
|
||||
/* FPCURTHREAD = NULL; */
|
||||
movl $0,PCPU(FPCURTHREAD)
|
||||
/* } */
|
||||
6:
|
||||
/* now we own the FPU. */
|
||||
@ -1026,9 +1026,9 @@ ENTRY(fastmove)
|
||||
movl -4(%ebp),%edi
|
||||
/* stop_emulating(); */
|
||||
clts
|
||||
/* npxthread = curthread; */
|
||||
/* fpcurthread = curthread; */
|
||||
movl PCPU(CURTHREAD),%eax
|
||||
movl %eax,PCPU(NPXTHREAD)
|
||||
movl %eax,PCPU(FPCURTHREAD)
|
||||
movl PCPU(CURPCB),%eax
|
||||
|
||||
/* XXX end of atomic FPU context grab. */
|
||||
@ -1113,8 +1113,8 @@ fastmove_loop:
|
||||
smsw %ax
|
||||
orb $CR0_TS,%al
|
||||
lmsw %ax
|
||||
/* npxthread = NULL; */
|
||||
movl $0,PCPU(NPXTHREAD)
|
||||
/* fpcurthread = NULL; */
|
||||
movl $0,PCPU(FPCURTHREAD)
|
||||
|
||||
/* XXX end of atomic FPU context ungrab. */
|
||||
sti
|
||||
@ -1154,7 +1154,7 @@ fastmove_fault:
|
||||
smsw %ax
|
||||
orb $CR0_TS,%al
|
||||
lmsw %ax
|
||||
movl $0,PCPU(NPXTHREAD)
|
||||
movl $0,PCPU(FPCURTHREAD)
|
||||
|
||||
/* XXX end of atomic FPU context ungrab. */
|
||||
sti
|
||||
|
@ -123,7 +123,7 @@ ENTRY(cpu_switch)
|
||||
|
||||
#ifdef DEV_NPX
|
||||
/* have we used fp, and need a save? */
|
||||
cmpl %ecx,PCPU(NPXTHREAD)
|
||||
cmpl %ecx,PCPU(FPCURTHREAD)
|
||||
jne 1f
|
||||
addl $PCB_SAVEFPU,%edx /* h/w bugs make saving complicated */
|
||||
pushl %edx
|
||||
@ -337,20 +337,20 @@ ENTRY(savectx)
|
||||
|
||||
#ifdef DEV_NPX
|
||||
/*
|
||||
* If npxthread == NULL, then the npx h/w state is irrelevant and the
|
||||
* If fpcurthread == NULL, then the npx h/w state is irrelevant and the
|
||||
* state had better already be in the pcb. This is true for forks
|
||||
* but not for dumps (the old book-keeping with FP flags in the pcb
|
||||
* always lost for dumps because the dump pcb has 0 flags).
|
||||
*
|
||||
* If npxthread != NULL, then we have to save the npx h/w state to
|
||||
* npxthread's pcb and copy it to the requested pcb, or save to the
|
||||
* If fpcurthread != NULL, then we have to save the npx h/w state to
|
||||
* fpcurthread's pcb and copy it to the requested pcb, or save to the
|
||||
* requested pcb and reload. Copying is easier because we would
|
||||
* have to handle h/w bugs for reloading. We used to lose the
|
||||
* parent's npx state for forks by forgetting to reload.
|
||||
*/
|
||||
pushfl
|
||||
cli
|
||||
movl PCPU(NPXTHREAD),%eax
|
||||
movl PCPU(FPCURTHREAD),%eax
|
||||
testl %eax,%eax
|
||||
je 1f
|
||||
|
||||
|
@ -154,7 +154,7 @@ cpu_fork(td1, p2, flags)
|
||||
if (td1 == curthread)
|
||||
td1->td_pcb->pcb_gs = rgs();
|
||||
savecrit = critical_enter();
|
||||
if (PCPU_GET(npxthread) == td1)
|
||||
if (PCPU_GET(fpcurthread) == td1)
|
||||
npxsave(&td1->td_pcb->pcb_save);
|
||||
critical_exit(savecrit);
|
||||
#endif
|
||||
|
@ -64,9 +64,9 @@
|
||||
#define NON_GPROF_RET .byte 0xc3 /* opcode for `ret' */
|
||||
|
||||
#ifdef LOCORE
|
||||
#define PCPU(member) %fs:GD_ ## member
|
||||
#define PCPU_ADDR(member, reg) movl %fs:GD_PRVSPACE,reg; \
|
||||
addl $GD_ ## member,reg
|
||||
#define PCPU(member) %fs:PC_ ## member
|
||||
#define PCPU_ADDR(member, reg) movl %fs:PC_PRVSPACE,reg; \
|
||||
addl $PC_ ## member,reg
|
||||
#endif
|
||||
|
||||
#ifdef GPROF
|
||||
|
@ -46,7 +46,6 @@
|
||||
#include <machine/psl.h>
|
||||
#include <machine/frame.h>
|
||||
#include <machine/segments.h>
|
||||
#include <machine/globals.h>
|
||||
|
||||
/*
|
||||
* definitions of cpu-dependent requirements
|
||||
|
@ -71,7 +71,6 @@
|
||||
#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, TEST_TEST1 */
|
||||
#include <machine/tss.h>
|
||||
#include <machine/specialreg.h>
|
||||
#include <machine/globaldata.h>
|
||||
#include <machine/privatespace.h>
|
||||
|
||||
#if defined(APIC_IO)
|
||||
@ -477,9 +476,9 @@ init_secondary(void)
|
||||
|
||||
gdt_segs[GPRIV_SEL].ssd_base = (int) &SMP_prvspace[myid];
|
||||
gdt_segs[GPROC0_SEL].ssd_base =
|
||||
(int) &SMP_prvspace[myid].globaldata.gd_common_tss;
|
||||
SMP_prvspace[myid].globaldata.gd_prvspace =
|
||||
&SMP_prvspace[myid].globaldata;
|
||||
(int) &SMP_prvspace[myid].pcpu.pc_common_tss;
|
||||
SMP_prvspace[myid].pcpu.pc_prvspace =
|
||||
&SMP_prvspace[myid].pcpu;
|
||||
|
||||
for (x = 0; x < NGDT; x++) {
|
||||
ssdtosd(&gdt_segs[x], &gdt[myid * NGDT + x].sd);
|
||||
@ -1915,7 +1914,7 @@ start_all_aps(u_int boot_addr)
|
||||
int x, i, pg;
|
||||
u_char mpbiosreason;
|
||||
u_long mpbioswarmvec;
|
||||
struct globaldata *gd;
|
||||
struct pcpu *pc;
|
||||
char *stack;
|
||||
uintptr_t kptbase;
|
||||
|
||||
@ -1955,10 +1954,10 @@ start_all_aps(u_int boot_addr)
|
||||
pg = x * i386_btop(sizeof(struct privatespace));
|
||||
|
||||
/* allocate a new private data page */
|
||||
gd = (struct globaldata *)kmem_alloc(kernel_map, PAGE_SIZE);
|
||||
pc = (struct pcpu *)kmem_alloc(kernel_map, PAGE_SIZE);
|
||||
|
||||
/* wire it into the private page table page */
|
||||
SMPpt[pg] = (pt_entry_t)(PG_V | PG_RW | vtophys(gd));
|
||||
SMPpt[pg] = (pt_entry_t)(PG_V | PG_RW | vtophys(pc));
|
||||
|
||||
/* allocate and set up an idle stack data page */
|
||||
stack = (char *)kmem_alloc(kernel_map, KSTACK_PAGES * PAGE_SIZE); /* XXXKSE */
|
||||
@ -1967,8 +1966,7 @@ start_all_aps(u_int boot_addr)
|
||||
(PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack));
|
||||
|
||||
/* prime data page for it to use */
|
||||
gd->gd_cpuid = x;
|
||||
globaldata_register(gd);
|
||||
pcpu_init(pc, x, sizeof(struct pcpu));
|
||||
|
||||
/* setup a vector to our boot code */
|
||||
*((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET;
|
||||
|
@ -26,54 +26,122 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_GLOBALDATA_H_
|
||||
#define _MACHINE_GLOBALDATA_H_
|
||||
#ifndef _MACHINE_PCPU_H_
|
||||
#define _MACHINE_PCPU_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#ifndef __GNUC__
|
||||
#error gcc is required to use this file
|
||||
#endif
|
||||
|
||||
#include <machine/segments.h>
|
||||
#include <machine/tss.h>
|
||||
|
||||
/* XXX */
|
||||
#ifdef KTR_PERCPU
|
||||
#include <sys/ktr.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This structure maps out the global data that needs to be kept on a
|
||||
* per-cpu basis. genassym uses this to generate offsets for the assembler
|
||||
* code, which also provides external symbols so that C can get at them as
|
||||
* though they were really globals.
|
||||
*
|
||||
* The SMP parts are setup in pmap.c and locore.s for the BSP, and
|
||||
* mp_machdep.c sets up the data for the AP's to "see" when they awake.
|
||||
* The reason for doing it via a struct is so that an array of pointers
|
||||
* to each CPU's data can be set up for things like "check curproc on all
|
||||
* other processors"
|
||||
*/
|
||||
struct globaldata {
|
||||
struct globaldata *gd_prvspace; /* Self-reference */
|
||||
struct thread *gd_curthread;
|
||||
struct thread *gd_npxthread;
|
||||
struct pcb *gd_curpcb;
|
||||
struct thread *gd_idlethread;
|
||||
struct timeval gd_switchtime;
|
||||
struct i386tss gd_common_tss;
|
||||
int gd_switchticks;
|
||||
struct segment_descriptor gd_common_tssd;
|
||||
struct segment_descriptor *gd_tss_gdt;
|
||||
int gd_currentldt;
|
||||
u_int gd_cpuid;
|
||||
u_int gd_other_cpus;
|
||||
SLIST_ENTRY(globaldata) gd_allcpu;
|
||||
struct lock_list_entry *gd_spinlocks;
|
||||
#ifdef KTR_PERCPU
|
||||
int gd_ktr_idx; /* Index into trace table */
|
||||
char *gd_ktr_buf;
|
||||
char gd_ktr_buf_data[KTR_SIZE];
|
||||
#endif
|
||||
};
|
||||
#define PCPU_MD_FIELDS \
|
||||
struct pcpu *pc_prvspace; /* Self-reference */ \
|
||||
struct i386tss pc_common_tss; \
|
||||
struct segment_descriptor pc_common_tssd; \
|
||||
struct segment_descriptor *pc_tss_gdt; \
|
||||
int pc_currentldt
|
||||
|
||||
/*
|
||||
* Evaluates to the byte offset of the per-cpu variable name.
|
||||
*/
|
||||
#define __pcpu_offset(name) \
|
||||
__offsetof(struct pcpu, name)
|
||||
|
||||
/*
|
||||
* Evaluates to the type of the per-cpu variable name.
|
||||
*/
|
||||
#define __pcpu_type(name) \
|
||||
__typeof(((struct pcpu *)0)->name)
|
||||
|
||||
/*
|
||||
* Evaluates to the address of the per-cpu variable name.
|
||||
*/
|
||||
#define __PCPU_PTR(name) ({ \
|
||||
__pcpu_type(name) *__p; \
|
||||
\
|
||||
__asm __volatile("movl %%fs:%1,%0; addl %2,%0" \
|
||||
: "=r" (__p) \
|
||||
: "m" (*(struct pcpu *)(__pcpu_offset(pc_prvspace))), \
|
||||
"i" (__pcpu_offset(name))); \
|
||||
\
|
||||
__p; \
|
||||
})
|
||||
|
||||
/*
|
||||
* Evaluates to the value of the per-cpu variable name.
|
||||
*/
|
||||
#define __PCPU_GET(name) ({ \
|
||||
__pcpu_type(name) __result; \
|
||||
\
|
||||
if (sizeof(__result) == 1) { \
|
||||
u_char __b; \
|
||||
__asm __volatile("movb %%fs:%1,%0" \
|
||||
: "=r" (__b) \
|
||||
: "m" (*(u_char *)(__pcpu_offset(name)))); \
|
||||
__result = *(__pcpu_type(name) *)&__b; \
|
||||
} else if (sizeof(__result) == 2) { \
|
||||
u_short __w; \
|
||||
__asm __volatile("movw %%fs:%1,%0" \
|
||||
: "=r" (__w) \
|
||||
: "m" (*(u_short *)(__pcpu_offset(name)))); \
|
||||
__result = *(__pcpu_type(name) *)&__w; \
|
||||
} else if (sizeof(__result) == 4) { \
|
||||
u_int __i; \
|
||||
__asm __volatile("movl %%fs:%1,%0" \
|
||||
: "=r" (__i) \
|
||||
: "m" (*(u_int *)(__pcpu_offset(name)))); \
|
||||
__result = *(__pcpu_type(name) *)&__i; \
|
||||
} else { \
|
||||
__result = *__PCPU_PTR(name); \
|
||||
} \
|
||||
\
|
||||
__result; \
|
||||
})
|
||||
|
||||
/*
|
||||
* Sets the value of the per-cpu variable name to value val.
|
||||
*/
|
||||
#define __PCPU_SET(name, val) ({ \
|
||||
__pcpu_type(name) __val = (val); \
|
||||
\
|
||||
if (sizeof(__val) == 1) { \
|
||||
u_char __b; \
|
||||
__b = *(u_char *)&__val; \
|
||||
__asm __volatile("movb %1,%%fs:%0" \
|
||||
: "=m" (*(u_char *)(__pcpu_offset(name))) \
|
||||
: "r" (__b)); \
|
||||
} else if (sizeof(__val) == 2) { \
|
||||
u_short __w; \
|
||||
__w = *(u_short *)&__val; \
|
||||
__asm __volatile("movw %1,%%fs:%0" \
|
||||
: "=m" (*(u_short *)(__pcpu_offset(name))) \
|
||||
: "r" (__w)); \
|
||||
} else if (sizeof(__val) == 4) { \
|
||||
u_int __i; \
|
||||
__i = *(u_int *)&__val; \
|
||||
__asm __volatile("movl %1,%%fs:%0" \
|
||||
: "=m" (*(u_int *)(__pcpu_offset(name))) \
|
||||
: "r" (__i)); \
|
||||
} else { \
|
||||
*__PCPU_PTR(name) = __val; \
|
||||
} \
|
||||
})
|
||||
|
||||
#define PCPU_GET(member) __PCPU_GET(pc_ ## member)
|
||||
#define PCPU_PTR(member) __PCPU_PTR(pc_ ## member)
|
||||
#define PCPU_SET(member, val) __PCPU_SET(pc_ ## member, val)
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* ! _MACHINE_GLOBALDATA_H_ */
|
||||
#endif /* ! _MACHINE_PCPU_H_ */
|
||||
|
@ -37,7 +37,6 @@
|
||||
#ifndef _MACHINE_PROC_H_
|
||||
#define _MACHINE_PROC_H_
|
||||
|
||||
#include <machine/globals.h>
|
||||
#include <machine/segments.h>
|
||||
|
||||
struct proc_ldt {
|
||||
|
@ -237,7 +237,7 @@ npx_intr(dummy)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* npxthread is normally non-null here. In that case, schedule an
|
||||
* fpcurthread is normally non-null here. In that case, schedule an
|
||||
* AST to finish the exception handling in the correct context
|
||||
* (this interrupt may occur after the thread has entered the
|
||||
* kernel via a syscall or an interrupt). Otherwise, the npx
|
||||
@ -248,7 +248,7 @@ npx_intr(dummy)
|
||||
* that caused it and it will repeat. We will eventually (usually
|
||||
* soon) win the race to handle the interrupt properly.
|
||||
*/
|
||||
td = PCPU_GET(npxthread);
|
||||
td = PCPU_GET(fpcurthread);
|
||||
if (td != NULL) {
|
||||
td->td_pcb->pcb_flags |= PCB_NPXTRAP;
|
||||
mtx_lock_spin(&sched_lock);
|
||||
@ -513,7 +513,7 @@ npxinit(control)
|
||||
/*
|
||||
* fninit has the same h/w bugs as fnsave. Use the detoxified
|
||||
* fnsave to throw away any junk in the fpu. npxsave() initializes
|
||||
* the fpu and sets npxthread = NULL as important side effects.
|
||||
* the fpu and sets fpcurthread = NULL as important side effects.
|
||||
*/
|
||||
savecrit = critical_enter();
|
||||
npxsave(&dummy);
|
||||
@ -540,7 +540,7 @@ npxexit(td)
|
||||
critical_t savecrit;
|
||||
|
||||
savecrit = critical_enter();
|
||||
if (td == PCPU_GET(npxthread))
|
||||
if (td == PCPU_GET(fpcurthread))
|
||||
npxsave(&PCPU_GET(curpcb)->pcb_save);
|
||||
critical_exit(savecrit);
|
||||
#ifdef NPX_DEBUG
|
||||
@ -758,8 +758,8 @@ npxtrap()
|
||||
u_long *exstat;
|
||||
|
||||
if (!npx_exists) {
|
||||
printf("npxtrap: npxthread = %p, curthread = %p, npx_exists = %d\n",
|
||||
PCPU_GET(npxthread), curthread, npx_exists);
|
||||
printf("npxtrap: fpcurthread = %p, curthread = %p, npx_exists = %d\n",
|
||||
PCPU_GET(fpcurthread), curthread, npx_exists);
|
||||
panic("npxtrap from nowhere");
|
||||
}
|
||||
savecrit = critical_enter();
|
||||
@ -769,7 +769,7 @@ npxtrap()
|
||||
* state to memory. Fetch the relevant parts of the state from
|
||||
* wherever they are.
|
||||
*/
|
||||
if (PCPU_GET(npxthread) != curthread) {
|
||||
if (PCPU_GET(fpcurthread) != curthread) {
|
||||
control = GET_FPU_CW(curthread);
|
||||
status = GET_FPU_SW(curthread);
|
||||
} else {
|
||||
@ -779,7 +779,7 @@ npxtrap()
|
||||
|
||||
exstat = GET_FPU_EXSW_PTR(curthread->td_pcb);
|
||||
*exstat = status;
|
||||
if (PCPU_GET(npxthread) != curthread)
|
||||
if (PCPU_GET(fpcurthread) != curthread)
|
||||
GET_FPU_SW(curthread) &= ~0x80bf;
|
||||
else
|
||||
fnclex();
|
||||
@ -790,7 +790,7 @@ npxtrap()
|
||||
/*
|
||||
* Implement device not available (DNA) exception
|
||||
*
|
||||
* It would be better to switch FP context here (if curthread != npxthread)
|
||||
* It would be better to switch FP context here (if curthread != fpcurthread)
|
||||
* and not necessarily for every context switch, but it is too hard to
|
||||
* access foreign pcb's.
|
||||
*/
|
||||
@ -802,9 +802,9 @@ npxdna()
|
||||
|
||||
if (!npx_exists)
|
||||
return (0);
|
||||
if (PCPU_GET(npxthread) != NULL) {
|
||||
printf("npxdna: npxthread = %p, curthread = %p\n",
|
||||
PCPU_GET(npxthread), curthread);
|
||||
if (PCPU_GET(fpcurthread) != NULL) {
|
||||
printf("npxdna: fpcurthread = %p, curthread = %p\n",
|
||||
PCPU_GET(fpcurthread), curthread);
|
||||
panic("npxdna");
|
||||
}
|
||||
s = critical_enter();
|
||||
@ -812,7 +812,7 @@ npxdna()
|
||||
/*
|
||||
* Record new context early in case frstor causes an IRQ13.
|
||||
*/
|
||||
PCPU_SET(npxthread, curthread);
|
||||
PCPU_SET(fpcurthread, curthread);
|
||||
|
||||
exstat = GET_FPU_EXSW_PTR(PCPU_GET(curpcb));
|
||||
*exstat = 0;
|
||||
@ -844,13 +844,13 @@ npxdna()
|
||||
* after the process has entered the kernel. It may even be delivered after
|
||||
* the fnsave here completes. A spurious IRQ13 for the fnsave is handled in
|
||||
* the same way as a very-late-arriving non-spurious IRQ13 from user mode:
|
||||
* it is normally ignored at first because we set npxthread to NULL; it is
|
||||
* it is normally ignored at first because we set fpcurthread to NULL; it is
|
||||
* normally retriggered in npxdna() after return to user mode.
|
||||
*
|
||||
* npxsave() must be called with interrupts disabled, so that it clears
|
||||
* npxthread atomically with saving the state. We require callers to do the
|
||||
* fpcurthread atomically with saving the state. We require callers to do the
|
||||
* disabling, since most callers need to disable interrupts anyway to call
|
||||
* npxsave() atomically with checking npxthread.
|
||||
* npxsave() atomically with checking fpcurthread.
|
||||
*
|
||||
* A previous version of npxsave() went to great lengths to excecute fnsave
|
||||
* with interrupts enabled in case executing it froze the CPU. This case
|
||||
@ -866,7 +866,7 @@ npxsave(addr)
|
||||
fpusave(addr);
|
||||
|
||||
start_emulating();
|
||||
PCPU_SET(npxthread, NULL);
|
||||
PCPU_SET(fpcurthread, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -36,9 +36,9 @@
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/bus.h>
|
||||
#include <sys/pcpu.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/pmap.h>
|
||||
#include <machine/globals.h>
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/segments.h>
|
||||
#include <machine/stdarg.h>
|
||||
|
@ -332,48 +332,9 @@ Debugger(msg)
|
||||
}
|
||||
}
|
||||
|
||||
DB_SHOW_COMMAND(pcpu, db_show_pcpu)
|
||||
void
|
||||
db_show_mdpcpu(struct pcpu *pc)
|
||||
{
|
||||
struct globaldata *gd;
|
||||
#ifdef SMP
|
||||
int id;
|
||||
|
||||
if (have_addr)
|
||||
id = ((addr >> 4) % 16) * 10 + (addr % 16);
|
||||
else
|
||||
id = PCPU_GET(cpuid);
|
||||
gd = globaldata_find(id);
|
||||
if (gd == NULL) {
|
||||
db_printf("CPU %d not found\n", id);
|
||||
return;
|
||||
}
|
||||
#else
|
||||
gd = GLOBALDATA;
|
||||
#endif
|
||||
db_printf("cpuid = %d\n", gd->gd_cpuid);
|
||||
db_printf("curthread = ");
|
||||
if (gd->gd_curthread != NULL)
|
||||
db_printf("%p: pid %d \"%s\"\n", gd->gd_curthread,
|
||||
gd->gd_curthread->td_proc->p_pid, gd->gd_curthread->td_proc->p_comm);
|
||||
else
|
||||
db_printf("none\n");
|
||||
db_printf("curpcb = %p\n", gd->gd_curpcb);
|
||||
db_printf("npxthread = ");
|
||||
if (gd->gd_npxthread != NULL)
|
||||
db_printf("%p: pid %d \"%s\"\n", gd->gd_npxthread,
|
||||
gd->gd_npxthread->td_proc->p_pid, gd->gd_npxthread->td_proc->p_comm);
|
||||
else
|
||||
db_printf("none\n");
|
||||
db_printf("idlethread = ");
|
||||
if (gd->gd_idlethread != NULL)
|
||||
db_printf("%p: pid %d \"%s\"\n", gd->gd_idlethread,
|
||||
gd->gd_idlethread->td_proc->p_pid,
|
||||
gd->gd_idlethread->td_proc->p_comm);
|
||||
else
|
||||
db_printf("none\n");
|
||||
|
||||
#ifdef WITNESS
|
||||
db_printf("spin locks held:\n");
|
||||
witness_list_locks(&gd->gd_spinlocks);
|
||||
#endif
|
||||
db_printf("currentldt = 0x%x\n", pc->pc_currentldt);
|
||||
}
|
||||
|
@ -51,10 +51,6 @@
|
||||
#include <sys/socket.h>
|
||||
#include <sys/resourcevar.h>
|
||||
#include <sys/user.h>
|
||||
/* XXX */
|
||||
#ifdef KTR_PERCPU
|
||||
#include <sys/ktr.h>
|
||||
#endif
|
||||
#include <machine/bootinfo.h>
|
||||
#include <machine/tss.h>
|
||||
#include <sys/vmmeter.h>
|
||||
@ -75,7 +71,6 @@
|
||||
#endif
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/sigframe.h>
|
||||
#include <machine/globaldata.h>
|
||||
#include <machine/vm86.h>
|
||||
#include <machine/proc.h>
|
||||
|
||||
@ -177,27 +172,19 @@ ASSYM(BI_SIZE, offsetof(struct bootinfo, bi_size));
|
||||
ASSYM(BI_SYMTAB, offsetof(struct bootinfo, bi_symtab));
|
||||
ASSYM(BI_ESYMTAB, offsetof(struct bootinfo, bi_esymtab));
|
||||
ASSYM(BI_KERNEND, offsetof(struct bootinfo, bi_kernend));
|
||||
ASSYM(GD_SIZEOF, sizeof(struct globaldata));
|
||||
ASSYM(GD_PRVSPACE, offsetof(struct globaldata, gd_prvspace));
|
||||
ASSYM(GD_CURTHREAD, offsetof(struct globaldata, gd_curthread));
|
||||
ASSYM(GD_NPXTHREAD, offsetof(struct globaldata, gd_npxthread));
|
||||
ASSYM(GD_IDLETHREAD, offsetof(struct globaldata, gd_idlethread));
|
||||
ASSYM(GD_CURPCB, offsetof(struct globaldata, gd_curpcb));
|
||||
ASSYM(GD_COMMON_TSS, offsetof(struct globaldata, gd_common_tss));
|
||||
ASSYM(GD_SWITCHTIME, offsetof(struct globaldata, gd_switchtime));
|
||||
ASSYM(GD_SWITCHTICKS, offsetof(struct globaldata, gd_switchticks));
|
||||
ASSYM(GD_COMMON_TSSD, offsetof(struct globaldata, gd_common_tssd));
|
||||
ASSYM(GD_TSS_GDT, offsetof(struct globaldata, gd_tss_gdt));
|
||||
ASSYM(GD_CURRENTLDT, offsetof(struct globaldata, gd_currentldt));
|
||||
|
||||
/* XXX */
|
||||
#ifdef KTR_PERCPU
|
||||
ASSYM(GD_KTR_IDX, offsetof(struct globaldata, gd_ktr_idx));
|
||||
ASSYM(GD_KTR_BUF, offsetof(struct globaldata, gd_ktr_buf));
|
||||
ASSYM(GD_KTR_BUF_DATA, offsetof(struct globaldata, gd_ktr_buf_data));
|
||||
#endif
|
||||
|
||||
ASSYM(GD_CPUID, offsetof(struct globaldata, gd_cpuid));
|
||||
ASSYM(PC_SIZEOF, sizeof(struct pcpu));
|
||||
ASSYM(PC_PRVSPACE, offsetof(struct pcpu, pc_prvspace));
|
||||
ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread));
|
||||
ASSYM(PC_FPCURTHREAD, offsetof(struct pcpu, pc_fpcurthread));
|
||||
ASSYM(PC_IDLETHREAD, offsetof(struct pcpu, pc_idlethread));
|
||||
ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb));
|
||||
ASSYM(PC_COMMON_TSS, offsetof(struct pcpu, pc_common_tss));
|
||||
ASSYM(PC_SWITCHTIME, offsetof(struct pcpu, pc_switchtime));
|
||||
ASSYM(PC_SWITCHTICKS, offsetof(struct pcpu, pc_switchticks));
|
||||
ASSYM(PC_COMMON_TSSD, offsetof(struct pcpu, pc_common_tssd));
|
||||
ASSYM(PC_TSS_GDT, offsetof(struct pcpu, pc_tss_gdt));
|
||||
ASSYM(PC_CURRENTLDT, offsetof(struct pcpu, pc_currentldt));
|
||||
ASSYM(PC_CPUID, offsetof(struct pcpu, pc_cpuid));
|
||||
|
||||
#ifdef SMP
|
||||
ASSYM(LA_VER, offsetof(struct LAPIC, version));
|
||||
|
@ -104,7 +104,6 @@
|
||||
#include <machine/pc/bios.h>
|
||||
#include <machine/pcb_ext.h> /* pcb.h included via sys/user.h */
|
||||
#include <machine/proc.h>
|
||||
#include <machine/globals.h>
|
||||
#ifdef PERFMON
|
||||
#include <machine/perfmon.h>
|
||||
#endif
|
||||
@ -207,7 +206,7 @@ struct kva_md_info kmi;
|
||||
|
||||
static struct trapframe proc0_tf;
|
||||
#ifndef SMP
|
||||
static struct globaldata __globaldata;
|
||||
static struct pcpu __pcpu;
|
||||
#endif
|
||||
|
||||
struct mtx sched_lock;
|
||||
@ -262,7 +261,6 @@ cpu_startup(dummy)
|
||||
bufinit();
|
||||
vm_pager_bufferinit();
|
||||
|
||||
globaldata_register(GLOBALDATA);
|
||||
#ifndef SMP
|
||||
/* For SMP, we delay the cpu_setregs() until after SMP startup. */
|
||||
cpu_setregs();
|
||||
@ -1670,6 +1668,7 @@ init386(first)
|
||||
/* table descriptors - used to load tables by microp */
|
||||
struct region_descriptor r_gdt, r_idt;
|
||||
#endif
|
||||
struct pcpu *pc;
|
||||
|
||||
proc_linkup(&proc0);
|
||||
proc0.p_uarea = proc0uarea;
|
||||
@ -1706,20 +1705,16 @@ init386(first)
|
||||
gdt_segs[GCODE_SEL].ssd_limit = atop(0 - 1);
|
||||
gdt_segs[GDATA_SEL].ssd_limit = atop(0 - 1);
|
||||
#ifdef SMP
|
||||
pc = &SMP_prvspace[0];
|
||||
gdt_segs[GPRIV_SEL].ssd_limit =
|
||||
atop(sizeof(struct privatespace) - 1);
|
||||
gdt_segs[GPRIV_SEL].ssd_base = (int) &SMP_prvspace[0];
|
||||
gdt_segs[GPROC0_SEL].ssd_base =
|
||||
(int) &SMP_prvspace[0].globaldata.gd_common_tss;
|
||||
SMP_prvspace[0].globaldata.gd_prvspace = &SMP_prvspace[0].globaldata;
|
||||
#else
|
||||
pc = &__pcpu;
|
||||
gdt_segs[GPRIV_SEL].ssd_limit =
|
||||
atop(sizeof(struct globaldata) - 1);
|
||||
gdt_segs[GPRIV_SEL].ssd_base = (int) &__globaldata;
|
||||
gdt_segs[GPROC0_SEL].ssd_base =
|
||||
(int) &__globaldata.gd_common_tss;
|
||||
__globaldata.gd_prvspace = &__globaldata;
|
||||
atop(sizeof(struct pcpu) - 1);
|
||||
#endif
|
||||
gdt_segs[GPRIV_SEL].ssd_base = (int) pc;
|
||||
gdt_segs[GPROC0_SEL].ssd_base = (int) &pc->pc_common_tss;
|
||||
|
||||
for (x = 0; x < NGDT; x++) {
|
||||
#ifdef BDE_DEBUGGER
|
||||
@ -1734,10 +1729,11 @@ init386(first)
|
||||
r_gdt.rd_base = (int) gdt;
|
||||
lgdt(&r_gdt);
|
||||
|
||||
/* setup curproc so that mutexes work */
|
||||
pcpu_init(pc, 0, sizeof(struct pcpu));
|
||||
PCPU_SET(prvspace, pc);
|
||||
|
||||
/* setup curproc so that mutexes work */
|
||||
PCPU_SET(curthread, thread0);
|
||||
PCPU_SET(spinlocks, NULL);
|
||||
|
||||
LIST_INIT(&thread0->td_contested);
|
||||
|
||||
@ -1907,6 +1903,11 @@ init386(first)
|
||||
thread0->td_frame = &proc0_tf;
|
||||
}
|
||||
|
||||
void
|
||||
cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size)
|
||||
{
|
||||
}
|
||||
|
||||
#if defined(I586_CPU) && !defined(NO_F00F_HACK)
|
||||
static void f00f_hack(void *unused);
|
||||
SYSINIT(f00f_hack, SI_SUB_INTRINSIC, SI_ORDER_FIRST, f00f_hack, NULL);
|
||||
|
@ -71,7 +71,6 @@
|
||||
#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, TEST_TEST1 */
|
||||
#include <machine/tss.h>
|
||||
#include <machine/specialreg.h>
|
||||
#include <machine/globaldata.h>
|
||||
#include <machine/privatespace.h>
|
||||
|
||||
#if defined(APIC_IO)
|
||||
@ -477,9 +476,9 @@ init_secondary(void)
|
||||
|
||||
gdt_segs[GPRIV_SEL].ssd_base = (int) &SMP_prvspace[myid];
|
||||
gdt_segs[GPROC0_SEL].ssd_base =
|
||||
(int) &SMP_prvspace[myid].globaldata.gd_common_tss;
|
||||
SMP_prvspace[myid].globaldata.gd_prvspace =
|
||||
&SMP_prvspace[myid].globaldata;
|
||||
(int) &SMP_prvspace[myid].pcpu.pc_common_tss;
|
||||
SMP_prvspace[myid].pcpu.pc_prvspace =
|
||||
&SMP_prvspace[myid].pcpu;
|
||||
|
||||
for (x = 0; x < NGDT; x++) {
|
||||
ssdtosd(&gdt_segs[x], &gdt[myid * NGDT + x].sd);
|
||||
@ -1915,7 +1914,7 @@ start_all_aps(u_int boot_addr)
|
||||
int x, i, pg;
|
||||
u_char mpbiosreason;
|
||||
u_long mpbioswarmvec;
|
||||
struct globaldata *gd;
|
||||
struct pcpu *pc;
|
||||
char *stack;
|
||||
uintptr_t kptbase;
|
||||
|
||||
@ -1955,10 +1954,10 @@ start_all_aps(u_int boot_addr)
|
||||
pg = x * i386_btop(sizeof(struct privatespace));
|
||||
|
||||
/* allocate a new private data page */
|
||||
gd = (struct globaldata *)kmem_alloc(kernel_map, PAGE_SIZE);
|
||||
pc = (struct pcpu *)kmem_alloc(kernel_map, PAGE_SIZE);
|
||||
|
||||
/* wire it into the private page table page */
|
||||
SMPpt[pg] = (pt_entry_t)(PG_V | PG_RW | vtophys(gd));
|
||||
SMPpt[pg] = (pt_entry_t)(PG_V | PG_RW | vtophys(pc));
|
||||
|
||||
/* allocate and set up an idle stack data page */
|
||||
stack = (char *)kmem_alloc(kernel_map, KSTACK_PAGES * PAGE_SIZE); /* XXXKSE */
|
||||
@ -1967,8 +1966,7 @@ start_all_aps(u_int boot_addr)
|
||||
(PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack));
|
||||
|
||||
/* prime data page for it to use */
|
||||
gd->gd_cpuid = x;
|
||||
globaldata_register(gd);
|
||||
pcpu_init(pc, x, sizeof(struct pcpu));
|
||||
|
||||
/* setup a vector to our boot code */
|
||||
*((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET;
|
||||
|
@ -35,7 +35,6 @@
|
||||
#include <machine/smptests.h> /** TEST_TEST1 */
|
||||
#include <machine/smp.h>
|
||||
#include <machine/mpapic.h>
|
||||
#include <machine/globaldata.h>
|
||||
#include <machine/segments.h>
|
||||
|
||||
#include <i386/isa/intr_machdep.h> /* Xspuriousint() */
|
||||
|
@ -71,7 +71,6 @@
|
||||
#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, TEST_TEST1 */
|
||||
#include <machine/tss.h>
|
||||
#include <machine/specialreg.h>
|
||||
#include <machine/globaldata.h>
|
||||
#include <machine/privatespace.h>
|
||||
|
||||
#if defined(APIC_IO)
|
||||
@ -477,9 +476,9 @@ init_secondary(void)
|
||||
|
||||
gdt_segs[GPRIV_SEL].ssd_base = (int) &SMP_prvspace[myid];
|
||||
gdt_segs[GPROC0_SEL].ssd_base =
|
||||
(int) &SMP_prvspace[myid].globaldata.gd_common_tss;
|
||||
SMP_prvspace[myid].globaldata.gd_prvspace =
|
||||
&SMP_prvspace[myid].globaldata;
|
||||
(int) &SMP_prvspace[myid].pcpu.pc_common_tss;
|
||||
SMP_prvspace[myid].pcpu.pc_prvspace =
|
||||
&SMP_prvspace[myid].pcpu;
|
||||
|
||||
for (x = 0; x < NGDT; x++) {
|
||||
ssdtosd(&gdt_segs[x], &gdt[myid * NGDT + x].sd);
|
||||
@ -1915,7 +1914,7 @@ start_all_aps(u_int boot_addr)
|
||||
int x, i, pg;
|
||||
u_char mpbiosreason;
|
||||
u_long mpbioswarmvec;
|
||||
struct globaldata *gd;
|
||||
struct pcpu *pc;
|
||||
char *stack;
|
||||
uintptr_t kptbase;
|
||||
|
||||
@ -1955,10 +1954,10 @@ start_all_aps(u_int boot_addr)
|
||||
pg = x * i386_btop(sizeof(struct privatespace));
|
||||
|
||||
/* allocate a new private data page */
|
||||
gd = (struct globaldata *)kmem_alloc(kernel_map, PAGE_SIZE);
|
||||
pc = (struct pcpu *)kmem_alloc(kernel_map, PAGE_SIZE);
|
||||
|
||||
/* wire it into the private page table page */
|
||||
SMPpt[pg] = (pt_entry_t)(PG_V | PG_RW | vtophys(gd));
|
||||
SMPpt[pg] = (pt_entry_t)(PG_V | PG_RW | vtophys(pc));
|
||||
|
||||
/* allocate and set up an idle stack data page */
|
||||
stack = (char *)kmem_alloc(kernel_map, KSTACK_PAGES * PAGE_SIZE); /* XXXKSE */
|
||||
@ -1967,8 +1966,7 @@ start_all_aps(u_int boot_addr)
|
||||
(PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack));
|
||||
|
||||
/* prime data page for it to use */
|
||||
gd->gd_cpuid = x;
|
||||
globaldata_register(gd);
|
||||
pcpu_init(pc, x, sizeof(struct pcpu));
|
||||
|
||||
/* setup a vector to our boot code */
|
||||
*((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET;
|
||||
|
@ -105,7 +105,6 @@
|
||||
#include <machine/apic.h>
|
||||
#include <machine/segments.h>
|
||||
#include <machine/tss.h>
|
||||
#include <machine/globaldata.h>
|
||||
#endif /* SMP || APIC_IO */
|
||||
|
||||
#define PMAP_KEEP_PDIRS
|
||||
|
@ -216,8 +216,8 @@ ENTRY(i586_bzero)
|
||||
* complicated since we avoid it if possible at all levels. We
|
||||
* want to localize the complications even when that increases them.
|
||||
* Here the extra work involves preserving CR0_TS in TS.
|
||||
* `npxthread != NULL' is supposed to be the condition that all the
|
||||
* FPU resources belong to an application, but npxthread and CR0_TS
|
||||
* `fpcurthread != NULL' is supposed to be the condition that all the
|
||||
* FPU resources belong to an application, but fpcurthread and CR0_TS
|
||||
* aren't set atomically enough for this condition to work in
|
||||
* interrupt handlers.
|
||||
*
|
||||
@ -241,7 +241,7 @@ ENTRY(i586_bzero)
|
||||
* method. CR0_TS must be preserved although it is very likely to
|
||||
* always end up as clear.
|
||||
*/
|
||||
cmpl $0,PCPU(NPXTHREAD)
|
||||
cmpl $0,PCPU(FPCURTHREAD)
|
||||
je i586_bz1
|
||||
|
||||
/*
|
||||
@ -303,7 +303,7 @@ fpureg_i586_bzero_loop:
|
||||
cmpl $8,%ecx
|
||||
jae fpureg_i586_bzero_loop
|
||||
|
||||
cmpl $0,PCPU(NPXTHREAD)
|
||||
cmpl $0,PCPU(FPCURTHREAD)
|
||||
je i586_bz3
|
||||
|
||||
/* XXX check that the condition for cases 1-2 stayed false. */
|
||||
@ -517,7 +517,7 @@ ENTRY(i586_bcopy)
|
||||
|
||||
sarb $1,kernel_fpu_lock
|
||||
jc small_i586_bcopy
|
||||
cmpl $0,PCPU(NPXTHREAD)
|
||||
cmpl $0,PCPU(FPCURTHREAD)
|
||||
je i586_bc1
|
||||
|
||||
/* XXX turn off handling of cases 1-2, as above. */
|
||||
@ -593,7 +593,7 @@ large_i586_bcopy_loop:
|
||||
cmpl $64,%ecx
|
||||
jae 4b
|
||||
|
||||
cmpl $0,PCPU(NPXTHREAD)
|
||||
cmpl $0,PCPU(FPCURTHREAD)
|
||||
je i586_bc2
|
||||
|
||||
/* XXX check that the condition for cases 1-2 stayed false. */
|
||||
@ -991,14 +991,14 @@ ENTRY(fastmove)
|
||||
/* XXX grab FPU context atomically. */
|
||||
cli
|
||||
|
||||
/* if (npxthread != NULL) { */
|
||||
cmpl $0,PCPU(NPXTHREAD)
|
||||
/* if (fpcurthread != NULL) { */
|
||||
cmpl $0,PCPU(FPCURTHREAD)
|
||||
je 6f
|
||||
/* fnsave(&curpcb->pcb_savefpu); */
|
||||
movl PCPU(CURPCB),%eax
|
||||
fnsave PCB_SAVEFPU(%eax)
|
||||
/* NPXTHREAD = NULL; */
|
||||
movl $0,PCPU(NPXTHREAD)
|
||||
/* FPCURTHREAD = NULL; */
|
||||
movl $0,PCPU(FPCURTHREAD)
|
||||
/* } */
|
||||
6:
|
||||
/* now we own the FPU. */
|
||||
@ -1026,9 +1026,9 @@ ENTRY(fastmove)
|
||||
movl -4(%ebp),%edi
|
||||
/* stop_emulating(); */
|
||||
clts
|
||||
/* npxthread = curthread; */
|
||||
/* fpcurthread = curthread; */
|
||||
movl PCPU(CURTHREAD),%eax
|
||||
movl %eax,PCPU(NPXTHREAD)
|
||||
movl %eax,PCPU(FPCURTHREAD)
|
||||
movl PCPU(CURPCB),%eax
|
||||
|
||||
/* XXX end of atomic FPU context grab. */
|
||||
@ -1113,8 +1113,8 @@ fastmove_loop:
|
||||
smsw %ax
|
||||
orb $CR0_TS,%al
|
||||
lmsw %ax
|
||||
/* npxthread = NULL; */
|
||||
movl $0,PCPU(NPXTHREAD)
|
||||
/* fpcurthread = NULL; */
|
||||
movl $0,PCPU(FPCURTHREAD)
|
||||
|
||||
/* XXX end of atomic FPU context ungrab. */
|
||||
sti
|
||||
@ -1154,7 +1154,7 @@ fastmove_fault:
|
||||
smsw %ax
|
||||
orb $CR0_TS,%al
|
||||
lmsw %ax
|
||||
movl $0,PCPU(NPXTHREAD)
|
||||
movl $0,PCPU(FPCURTHREAD)
|
||||
|
||||
/* XXX end of atomic FPU context ungrab. */
|
||||
sti
|
||||
|
@ -123,7 +123,7 @@ ENTRY(cpu_switch)
|
||||
|
||||
#ifdef DEV_NPX
|
||||
/* have we used fp, and need a save? */
|
||||
cmpl %ecx,PCPU(NPXTHREAD)
|
||||
cmpl %ecx,PCPU(FPCURTHREAD)
|
||||
jne 1f
|
||||
addl $PCB_SAVEFPU,%edx /* h/w bugs make saving complicated */
|
||||
pushl %edx
|
||||
@ -337,20 +337,20 @@ ENTRY(savectx)
|
||||
|
||||
#ifdef DEV_NPX
|
||||
/*
|
||||
* If npxthread == NULL, then the npx h/w state is irrelevant and the
|
||||
* If fpcurthread == NULL, then the npx h/w state is irrelevant and the
|
||||
* state had better already be in the pcb. This is true for forks
|
||||
* but not for dumps (the old book-keeping with FP flags in the pcb
|
||||
* always lost for dumps because the dump pcb has 0 flags).
|
||||
*
|
||||
* If npxthread != NULL, then we have to save the npx h/w state to
|
||||
* npxthread's pcb and copy it to the requested pcb, or save to the
|
||||
* If fpcurthread != NULL, then we have to save the npx h/w state to
|
||||
* fpcurthread's pcb and copy it to the requested pcb, or save to the
|
||||
* requested pcb and reload. Copying is easier because we would
|
||||
* have to handle h/w bugs for reloading. We used to lose the
|
||||
* parent's npx state for forks by forgetting to reload.
|
||||
*/
|
||||
pushfl
|
||||
cli
|
||||
movl PCPU(NPXTHREAD),%eax
|
||||
movl PCPU(FPCURTHREAD),%eax
|
||||
testl %eax,%eax
|
||||
je 1f
|
||||
|
||||
|
@ -68,7 +68,7 @@ ENTRY(vm86_bioscall)
|
||||
pushfl
|
||||
cli
|
||||
movl PCPU(CURTHREAD),%ecx
|
||||
cmpl %ecx,PCPU(NPXTHREAD) /* do we need to save fp? */
|
||||
cmpl %ecx,PCPU(FPCURTHREAD) /* do we need to save fp? */
|
||||
jne 1f
|
||||
testl %ecx,%ecx
|
||||
je 1f /* no curproc/npxproc */
|
||||
|
@ -154,7 +154,7 @@ cpu_fork(td1, p2, flags)
|
||||
if (td1 == curthread)
|
||||
td1->td_pcb->pcb_gs = rgs();
|
||||
savecrit = critical_enter();
|
||||
if (PCPU_GET(npxthread) == td1)
|
||||
if (PCPU_GET(fpcurthread) == td1)
|
||||
npxsave(&td1->td_pcb->pcb_save);
|
||||
critical_exit(savecrit);
|
||||
#endif
|
||||
|
@ -64,9 +64,9 @@
|
||||
#define NON_GPROF_RET .byte 0xc3 /* opcode for `ret' */
|
||||
|
||||
#ifdef LOCORE
|
||||
#define PCPU(member) %fs:GD_ ## member
|
||||
#define PCPU_ADDR(member, reg) movl %fs:GD_PRVSPACE,reg; \
|
||||
addl $GD_ ## member,reg
|
||||
#define PCPU(member) %fs:PC_ ## member
|
||||
#define PCPU_ADDR(member, reg) movl %fs:PC_PRVSPACE,reg; \
|
||||
addl $PC_ ## member,reg
|
||||
#endif
|
||||
|
||||
#ifdef GPROF
|
||||
|
@ -46,7 +46,6 @@
|
||||
#include <machine/psl.h>
|
||||
#include <machine/frame.h>
|
||||
#include <machine/segments.h>
|
||||
#include <machine/globals.h>
|
||||
|
||||
/*
|
||||
* definitions of cpu-dependent requirements
|
||||
|
@ -1,79 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) Peter Wemm <peter@netplex.com.au>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_GLOBALDATA_H_
|
||||
#define _MACHINE_GLOBALDATA_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#include <machine/segments.h>
|
||||
#include <machine/tss.h>
|
||||
|
||||
/* XXX */
|
||||
#ifdef KTR_PERCPU
|
||||
#include <sys/ktr.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This structure maps out the global data that needs to be kept on a
|
||||
* per-cpu basis. genassym uses this to generate offsets for the assembler
|
||||
* code, which also provides external symbols so that C can get at them as
|
||||
* though they were really globals.
|
||||
*
|
||||
* The SMP parts are setup in pmap.c and locore.s for the BSP, and
|
||||
* mp_machdep.c sets up the data for the AP's to "see" when they awake.
|
||||
* The reason for doing it via a struct is so that an array of pointers
|
||||
* to each CPU's data can be set up for things like "check curproc on all
|
||||
* other processors"
|
||||
*/
|
||||
struct globaldata {
|
||||
struct globaldata *gd_prvspace; /* Self-reference */
|
||||
struct thread *gd_curthread;
|
||||
struct thread *gd_npxthread;
|
||||
struct pcb *gd_curpcb;
|
||||
struct thread *gd_idlethread;
|
||||
struct timeval gd_switchtime;
|
||||
struct i386tss gd_common_tss;
|
||||
int gd_switchticks;
|
||||
struct segment_descriptor gd_common_tssd;
|
||||
struct segment_descriptor *gd_tss_gdt;
|
||||
int gd_currentldt;
|
||||
u_int gd_cpuid;
|
||||
u_int gd_other_cpus;
|
||||
SLIST_ENTRY(globaldata) gd_allcpu;
|
||||
struct lock_list_entry *gd_spinlocks;
|
||||
#ifdef KTR_PERCPU
|
||||
int gd_ktr_idx; /* Index into trace table */
|
||||
char *gd_ktr_buf;
|
||||
char gd_ktr_buf_data[KTR_SIZE];
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* ! _MACHINE_GLOBALDATA_H_ */
|
@ -1,141 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Luoqi Chen <luoqi@freebsd.org>
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2000 Jake Burkholder <jake@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_GLOBALS_H_
|
||||
#define _MACHINE_GLOBALS_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#include <machine/globaldata.h>
|
||||
|
||||
#ifndef __GNUC__
|
||||
#error gcc is required to use this file
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Evaluates to the byte offset of the per-cpu variable name.
|
||||
*/
|
||||
#define __pcpu_offset(name) \
|
||||
__offsetof(struct globaldata, name)
|
||||
|
||||
/*
|
||||
* Evaluates to the type of the per-cpu variable name.
|
||||
*/
|
||||
#define __pcpu_type(name) \
|
||||
__typeof(((struct globaldata *)0)->name)
|
||||
|
||||
/*
|
||||
* Evaluates to the address of the per-cpu variable name.
|
||||
*/
|
||||
#define __PCPU_PTR(name) ({ \
|
||||
__pcpu_type(name) *__p; \
|
||||
\
|
||||
__asm __volatile("movl %%fs:%1,%0; addl %2,%0" \
|
||||
: "=r" (__p) \
|
||||
: "m" (*(struct globaldata *)(__pcpu_offset(gd_prvspace))), \
|
||||
"i" (__pcpu_offset(name))); \
|
||||
\
|
||||
__p; \
|
||||
})
|
||||
|
||||
/*
|
||||
* Evaluates to the value of the per-cpu variable name.
|
||||
*/
|
||||
#define __PCPU_GET(name) ({ \
|
||||
__pcpu_type(name) __result; \
|
||||
\
|
||||
if (sizeof(__result) == 1) { \
|
||||
u_char __b; \
|
||||
__asm __volatile("movb %%fs:%1,%0" \
|
||||
: "=r" (__b) \
|
||||
: "m" (*(u_char *)(__pcpu_offset(name)))); \
|
||||
__result = *(__pcpu_type(name) *)&__b; \
|
||||
} else if (sizeof(__result) == 2) { \
|
||||
u_short __w; \
|
||||
__asm __volatile("movw %%fs:%1,%0" \
|
||||
: "=r" (__w) \
|
||||
: "m" (*(u_short *)(__pcpu_offset(name)))); \
|
||||
__result = *(__pcpu_type(name) *)&__w; \
|
||||
} else if (sizeof(__result) == 4) { \
|
||||
u_int __i; \
|
||||
__asm __volatile("movl %%fs:%1,%0" \
|
||||
: "=r" (__i) \
|
||||
: "m" (*(u_int *)(__pcpu_offset(name)))); \
|
||||
__result = *(__pcpu_type(name) *)&__i; \
|
||||
} else { \
|
||||
__result = *__PCPU_PTR(name); \
|
||||
} \
|
||||
\
|
||||
__result; \
|
||||
})
|
||||
|
||||
/*
|
||||
* Sets the value of the per-cpu variable name to value val.
|
||||
*/
|
||||
#define __PCPU_SET(name, val) ({ \
|
||||
__pcpu_type(name) __val = (val); \
|
||||
\
|
||||
if (sizeof(__val) == 1) { \
|
||||
u_char __b; \
|
||||
__b = *(u_char *)&__val; \
|
||||
__asm __volatile("movb %1,%%fs:%0" \
|
||||
: "=m" (*(u_char *)(__pcpu_offset(name))) \
|
||||
: "r" (__b)); \
|
||||
} else if (sizeof(__val) == 2) { \
|
||||
u_short __w; \
|
||||
__w = *(u_short *)&__val; \
|
||||
__asm __volatile("movw %1,%%fs:%0" \
|
||||
: "=m" (*(u_short *)(__pcpu_offset(name))) \
|
||||
: "r" (__w)); \
|
||||
} else if (sizeof(__val) == 4) { \
|
||||
u_int __i; \
|
||||
__i = *(u_int *)&__val; \
|
||||
__asm __volatile("movl %1,%%fs:%0" \
|
||||
: "=m" (*(u_int *)(__pcpu_offset(name))) \
|
||||
: "r" (__i)); \
|
||||
} else { \
|
||||
*__PCPU_PTR(name) = __val; \
|
||||
} \
|
||||
})
|
||||
|
||||
#define PCPU_GET(member) __PCPU_GET(gd_ ## member)
|
||||
#define PCPU_PTR(member) __PCPU_PTR(gd_ ## member)
|
||||
#define PCPU_SET(member, val) __PCPU_SET(gd_ ## member, val)
|
||||
|
||||
#define GLOBALDATA PCPU_GET(prvspace)
|
||||
#define curthread PCPU_GET(curthread)
|
||||
#define CURPROC (curthread->td_proc)
|
||||
#define curproc (curthread->td_proc)
|
||||
#define curksegrp (curthread->td_ksegrp)
|
||||
#define curkse (curthread->td_kse)
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !_MACHINE_GLOBALS_H_ */
|
@ -71,7 +71,6 @@
|
||||
#include <machine/smptests.h> /** TEST_DEFAULT_CONFIG, TEST_TEST1 */
|
||||
#include <machine/tss.h>
|
||||
#include <machine/specialreg.h>
|
||||
#include <machine/globaldata.h>
|
||||
#include <machine/privatespace.h>
|
||||
|
||||
#if defined(APIC_IO)
|
||||
@ -477,9 +476,9 @@ init_secondary(void)
|
||||
|
||||
gdt_segs[GPRIV_SEL].ssd_base = (int) &SMP_prvspace[myid];
|
||||
gdt_segs[GPROC0_SEL].ssd_base =
|
||||
(int) &SMP_prvspace[myid].globaldata.gd_common_tss;
|
||||
SMP_prvspace[myid].globaldata.gd_prvspace =
|
||||
&SMP_prvspace[myid].globaldata;
|
||||
(int) &SMP_prvspace[myid].pcpu.pc_common_tss;
|
||||
SMP_prvspace[myid].pcpu.pc_prvspace =
|
||||
&SMP_prvspace[myid].pcpu;
|
||||
|
||||
for (x = 0; x < NGDT; x++) {
|
||||
ssdtosd(&gdt_segs[x], &gdt[myid * NGDT + x].sd);
|
||||
@ -1915,7 +1914,7 @@ start_all_aps(u_int boot_addr)
|
||||
int x, i, pg;
|
||||
u_char mpbiosreason;
|
||||
u_long mpbioswarmvec;
|
||||
struct globaldata *gd;
|
||||
struct pcpu *pc;
|
||||
char *stack;
|
||||
uintptr_t kptbase;
|
||||
|
||||
@ -1955,10 +1954,10 @@ start_all_aps(u_int boot_addr)
|
||||
pg = x * i386_btop(sizeof(struct privatespace));
|
||||
|
||||
/* allocate a new private data page */
|
||||
gd = (struct globaldata *)kmem_alloc(kernel_map, PAGE_SIZE);
|
||||
pc = (struct pcpu *)kmem_alloc(kernel_map, PAGE_SIZE);
|
||||
|
||||
/* wire it into the private page table page */
|
||||
SMPpt[pg] = (pt_entry_t)(PG_V | PG_RW | vtophys(gd));
|
||||
SMPpt[pg] = (pt_entry_t)(PG_V | PG_RW | vtophys(pc));
|
||||
|
||||
/* allocate and set up an idle stack data page */
|
||||
stack = (char *)kmem_alloc(kernel_map, KSTACK_PAGES * PAGE_SIZE); /* XXXKSE */
|
||||
@ -1967,8 +1966,7 @@ start_all_aps(u_int boot_addr)
|
||||
(PG_V | PG_RW | vtophys(PAGE_SIZE * i + stack));
|
||||
|
||||
/* prime data page for it to use */
|
||||
gd->gd_cpuid = x;
|
||||
globaldata_register(gd);
|
||||
pcpu_init(pc, x, sizeof(struct pcpu));
|
||||
|
||||
/* setup a vector to our boot code */
|
||||
*((volatile u_short *) WARMBOOT_OFF) = WARMBOOT_TARGET;
|
||||
|
@ -26,54 +26,122 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_GLOBALDATA_H_
|
||||
#define _MACHINE_GLOBALDATA_H_
|
||||
#ifndef _MACHINE_PCPU_H_
|
||||
#define _MACHINE_PCPU_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#ifndef __GNUC__
|
||||
#error gcc is required to use this file
|
||||
#endif
|
||||
|
||||
#include <machine/segments.h>
|
||||
#include <machine/tss.h>
|
||||
|
||||
/* XXX */
|
||||
#ifdef KTR_PERCPU
|
||||
#include <sys/ktr.h>
|
||||
#endif
|
||||
|
||||
/*
|
||||
* This structure maps out the global data that needs to be kept on a
|
||||
* per-cpu basis. genassym uses this to generate offsets for the assembler
|
||||
* code, which also provides external symbols so that C can get at them as
|
||||
* though they were really globals.
|
||||
*
|
||||
* The SMP parts are setup in pmap.c and locore.s for the BSP, and
|
||||
* mp_machdep.c sets up the data for the AP's to "see" when they awake.
|
||||
* The reason for doing it via a struct is so that an array of pointers
|
||||
* to each CPU's data can be set up for things like "check curproc on all
|
||||
* other processors"
|
||||
*/
|
||||
struct globaldata {
|
||||
struct globaldata *gd_prvspace; /* Self-reference */
|
||||
struct thread *gd_curthread;
|
||||
struct thread *gd_npxthread;
|
||||
struct pcb *gd_curpcb;
|
||||
struct thread *gd_idlethread;
|
||||
struct timeval gd_switchtime;
|
||||
struct i386tss gd_common_tss;
|
||||
int gd_switchticks;
|
||||
struct segment_descriptor gd_common_tssd;
|
||||
struct segment_descriptor *gd_tss_gdt;
|
||||
int gd_currentldt;
|
||||
u_int gd_cpuid;
|
||||
u_int gd_other_cpus;
|
||||
SLIST_ENTRY(globaldata) gd_allcpu;
|
||||
struct lock_list_entry *gd_spinlocks;
|
||||
#ifdef KTR_PERCPU
|
||||
int gd_ktr_idx; /* Index into trace table */
|
||||
char *gd_ktr_buf;
|
||||
char gd_ktr_buf_data[KTR_SIZE];
|
||||
#endif
|
||||
};
|
||||
#define PCPU_MD_FIELDS \
|
||||
struct pcpu *pc_prvspace; /* Self-reference */ \
|
||||
struct i386tss pc_common_tss; \
|
||||
struct segment_descriptor pc_common_tssd; \
|
||||
struct segment_descriptor *pc_tss_gdt; \
|
||||
int pc_currentldt
|
||||
|
||||
/*
|
||||
* Evaluates to the byte offset of the per-cpu variable name.
|
||||
*/
|
||||
#define __pcpu_offset(name) \
|
||||
__offsetof(struct pcpu, name)
|
||||
|
||||
/*
|
||||
* Evaluates to the type of the per-cpu variable name.
|
||||
*/
|
||||
#define __pcpu_type(name) \
|
||||
__typeof(((struct pcpu *)0)->name)
|
||||
|
||||
/*
|
||||
* Evaluates to the address of the per-cpu variable name.
|
||||
*/
|
||||
#define __PCPU_PTR(name) ({ \
|
||||
__pcpu_type(name) *__p; \
|
||||
\
|
||||
__asm __volatile("movl %%fs:%1,%0; addl %2,%0" \
|
||||
: "=r" (__p) \
|
||||
: "m" (*(struct pcpu *)(__pcpu_offset(pc_prvspace))), \
|
||||
"i" (__pcpu_offset(name))); \
|
||||
\
|
||||
__p; \
|
||||
})
|
||||
|
||||
/*
|
||||
* Evaluates to the value of the per-cpu variable name.
|
||||
*/
|
||||
#define __PCPU_GET(name) ({ \
|
||||
__pcpu_type(name) __result; \
|
||||
\
|
||||
if (sizeof(__result) == 1) { \
|
||||
u_char __b; \
|
||||
__asm __volatile("movb %%fs:%1,%0" \
|
||||
: "=r" (__b) \
|
||||
: "m" (*(u_char *)(__pcpu_offset(name)))); \
|
||||
__result = *(__pcpu_type(name) *)&__b; \
|
||||
} else if (sizeof(__result) == 2) { \
|
||||
u_short __w; \
|
||||
__asm __volatile("movw %%fs:%1,%0" \
|
||||
: "=r" (__w) \
|
||||
: "m" (*(u_short *)(__pcpu_offset(name)))); \
|
||||
__result = *(__pcpu_type(name) *)&__w; \
|
||||
} else if (sizeof(__result) == 4) { \
|
||||
u_int __i; \
|
||||
__asm __volatile("movl %%fs:%1,%0" \
|
||||
: "=r" (__i) \
|
||||
: "m" (*(u_int *)(__pcpu_offset(name)))); \
|
||||
__result = *(__pcpu_type(name) *)&__i; \
|
||||
} else { \
|
||||
__result = *__PCPU_PTR(name); \
|
||||
} \
|
||||
\
|
||||
__result; \
|
||||
})
|
||||
|
||||
/*
|
||||
* Sets the value of the per-cpu variable name to value val.
|
||||
*/
|
||||
#define __PCPU_SET(name, val) ({ \
|
||||
__pcpu_type(name) __val = (val); \
|
||||
\
|
||||
if (sizeof(__val) == 1) { \
|
||||
u_char __b; \
|
||||
__b = *(u_char *)&__val; \
|
||||
__asm __volatile("movb %1,%%fs:%0" \
|
||||
: "=m" (*(u_char *)(__pcpu_offset(name))) \
|
||||
: "r" (__b)); \
|
||||
} else if (sizeof(__val) == 2) { \
|
||||
u_short __w; \
|
||||
__w = *(u_short *)&__val; \
|
||||
__asm __volatile("movw %1,%%fs:%0" \
|
||||
: "=m" (*(u_short *)(__pcpu_offset(name))) \
|
||||
: "r" (__w)); \
|
||||
} else if (sizeof(__val) == 4) { \
|
||||
u_int __i; \
|
||||
__i = *(u_int *)&__val; \
|
||||
__asm __volatile("movl %1,%%fs:%0" \
|
||||
: "=m" (*(u_int *)(__pcpu_offset(name))) \
|
||||
: "r" (__i)); \
|
||||
} else { \
|
||||
*__PCPU_PTR(name) = __val; \
|
||||
} \
|
||||
})
|
||||
|
||||
#define PCPU_GET(member) __PCPU_GET(pc_ ## member)
|
||||
#define PCPU_PTR(member) __PCPU_PTR(pc_ ## member)
|
||||
#define PCPU_SET(member, val) __PCPU_SET(pc_ ## member, val)
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* ! _MACHINE_GLOBALDATA_H_ */
|
||||
#endif /* ! _MACHINE_PCPU_H_ */
|
||||
|
@ -36,8 +36,8 @@
|
||||
*/
|
||||
struct privatespace {
|
||||
/* page 0 - data page */
|
||||
struct globaldata globaldata;
|
||||
char __filler0[PAGE_SIZE - sizeof(struct globaldata)];
|
||||
struct pcpu pcpu;
|
||||
char __filler0[PAGE_SIZE - sizeof(struct pcpu)];
|
||||
|
||||
/* page 1 - idle stack (KSTACK_PAGES pages) */
|
||||
char idlekstack[KSTACK_PAGES * PAGE_SIZE];
|
||||
|
@ -37,7 +37,6 @@
|
||||
#ifndef _MACHINE_PROC_H_
|
||||
#define _MACHINE_PROC_H_
|
||||
|
||||
#include <machine/globals.h>
|
||||
#include <machine/segments.h>
|
||||
|
||||
struct proc_ldt {
|
||||
|
@ -237,7 +237,7 @@ npx_intr(dummy)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* npxthread is normally non-null here. In that case, schedule an
|
||||
* fpcurthread is normally non-null here. In that case, schedule an
|
||||
* AST to finish the exception handling in the correct context
|
||||
* (this interrupt may occur after the thread has entered the
|
||||
* kernel via a syscall or an interrupt). Otherwise, the npx
|
||||
@ -248,7 +248,7 @@ npx_intr(dummy)
|
||||
* that caused it and it will repeat. We will eventually (usually
|
||||
* soon) win the race to handle the interrupt properly.
|
||||
*/
|
||||
td = PCPU_GET(npxthread);
|
||||
td = PCPU_GET(fpcurthread);
|
||||
if (td != NULL) {
|
||||
td->td_pcb->pcb_flags |= PCB_NPXTRAP;
|
||||
mtx_lock_spin(&sched_lock);
|
||||
@ -513,7 +513,7 @@ npxinit(control)
|
||||
/*
|
||||
* fninit has the same h/w bugs as fnsave. Use the detoxified
|
||||
* fnsave to throw away any junk in the fpu. npxsave() initializes
|
||||
* the fpu and sets npxthread = NULL as important side effects.
|
||||
* the fpu and sets fpcurthread = NULL as important side effects.
|
||||
*/
|
||||
savecrit = critical_enter();
|
||||
npxsave(&dummy);
|
||||
@ -540,7 +540,7 @@ npxexit(td)
|
||||
critical_t savecrit;
|
||||
|
||||
savecrit = critical_enter();
|
||||
if (td == PCPU_GET(npxthread))
|
||||
if (td == PCPU_GET(fpcurthread))
|
||||
npxsave(&PCPU_GET(curpcb)->pcb_save);
|
||||
critical_exit(savecrit);
|
||||
#ifdef NPX_DEBUG
|
||||
@ -758,8 +758,8 @@ npxtrap()
|
||||
u_long *exstat;
|
||||
|
||||
if (!npx_exists) {
|
||||
printf("npxtrap: npxthread = %p, curthread = %p, npx_exists = %d\n",
|
||||
PCPU_GET(npxthread), curthread, npx_exists);
|
||||
printf("npxtrap: fpcurthread = %p, curthread = %p, npx_exists = %d\n",
|
||||
PCPU_GET(fpcurthread), curthread, npx_exists);
|
||||
panic("npxtrap from nowhere");
|
||||
}
|
||||
savecrit = critical_enter();
|
||||
@ -769,7 +769,7 @@ npxtrap()
|
||||
* state to memory. Fetch the relevant parts of the state from
|
||||
* wherever they are.
|
||||
*/
|
||||
if (PCPU_GET(npxthread) != curthread) {
|
||||
if (PCPU_GET(fpcurthread) != curthread) {
|
||||
control = GET_FPU_CW(curthread);
|
||||
status = GET_FPU_SW(curthread);
|
||||
} else {
|
||||
@ -779,7 +779,7 @@ npxtrap()
|
||||
|
||||
exstat = GET_FPU_EXSW_PTR(curthread->td_pcb);
|
||||
*exstat = status;
|
||||
if (PCPU_GET(npxthread) != curthread)
|
||||
if (PCPU_GET(fpcurthread) != curthread)
|
||||
GET_FPU_SW(curthread) &= ~0x80bf;
|
||||
else
|
||||
fnclex();
|
||||
@ -790,7 +790,7 @@ npxtrap()
|
||||
/*
|
||||
* Implement device not available (DNA) exception
|
||||
*
|
||||
* It would be better to switch FP context here (if curthread != npxthread)
|
||||
* It would be better to switch FP context here (if curthread != fpcurthread)
|
||||
* and not necessarily for every context switch, but it is too hard to
|
||||
* access foreign pcb's.
|
||||
*/
|
||||
@ -802,9 +802,9 @@ npxdna()
|
||||
|
||||
if (!npx_exists)
|
||||
return (0);
|
||||
if (PCPU_GET(npxthread) != NULL) {
|
||||
printf("npxdna: npxthread = %p, curthread = %p\n",
|
||||
PCPU_GET(npxthread), curthread);
|
||||
if (PCPU_GET(fpcurthread) != NULL) {
|
||||
printf("npxdna: fpcurthread = %p, curthread = %p\n",
|
||||
PCPU_GET(fpcurthread), curthread);
|
||||
panic("npxdna");
|
||||
}
|
||||
s = critical_enter();
|
||||
@ -812,7 +812,7 @@ npxdna()
|
||||
/*
|
||||
* Record new context early in case frstor causes an IRQ13.
|
||||
*/
|
||||
PCPU_SET(npxthread, curthread);
|
||||
PCPU_SET(fpcurthread, curthread);
|
||||
|
||||
exstat = GET_FPU_EXSW_PTR(PCPU_GET(curpcb));
|
||||
*exstat = 0;
|
||||
@ -844,13 +844,13 @@ npxdna()
|
||||
* after the process has entered the kernel. It may even be delivered after
|
||||
* the fnsave here completes. A spurious IRQ13 for the fnsave is handled in
|
||||
* the same way as a very-late-arriving non-spurious IRQ13 from user mode:
|
||||
* it is normally ignored at first because we set npxthread to NULL; it is
|
||||
* it is normally ignored at first because we set fpcurthread to NULL; it is
|
||||
* normally retriggered in npxdna() after return to user mode.
|
||||
*
|
||||
* npxsave() must be called with interrupts disabled, so that it clears
|
||||
* npxthread atomically with saving the state. We require callers to do the
|
||||
* fpcurthread atomically with saving the state. We require callers to do the
|
||||
* disabling, since most callers need to disable interrupts anyway to call
|
||||
* npxsave() atomically with checking npxthread.
|
||||
* npxsave() atomically with checking fpcurthread.
|
||||
*
|
||||
* A previous version of npxsave() went to great lengths to excecute fnsave
|
||||
* with interrupts enabled in case executing it froze the CPU. This case
|
||||
@ -866,7 +866,7 @@ npxsave(addr)
|
||||
fpusave(addr);
|
||||
|
||||
start_emulating();
|
||||
PCPU_SET(npxthread, NULL);
|
||||
PCPU_SET(fpcurthread, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -510,3 +510,8 @@ db_skip_breakpoint(void)
|
||||
ddb_regs.tf_cr_iip += 16;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
db_show_mdpcpu(struct pcpu *pc)
|
||||
{
|
||||
}
|
||||
|
@ -34,7 +34,7 @@
|
||||
* ar.k7 = curthread
|
||||
* ar.k6 = ksp
|
||||
* ar.k5 = kbsp
|
||||
* ar.k4 = globalp
|
||||
* ar.k4 = pcpup
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -34,7 +34,7 @@
|
||||
* ar.k7 = curthread
|
||||
* ar.k6 = ksp
|
||||
* ar.k5 = kbsp
|
||||
* ar.k4 = globalp
|
||||
* ar.k4 = pcpup
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -63,11 +63,11 @@
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
ASSYM(GD_CURTHREAD, offsetof(struct globaldata, gd_curthread));
|
||||
ASSYM(GD_FPCURTHREAD, offsetof(struct globaldata, gd_fpcurthread));
|
||||
ASSYM(GD_CURPCB, offsetof(struct globaldata, gd_curpcb));
|
||||
ASSYM(GD_SWITCHTIME, offsetof(struct globaldata, gd_switchtime));
|
||||
ASSYM(GD_CPUID, offsetof(struct globaldata, gd_cpuid));
|
||||
ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread));
|
||||
ASSYM(PC_FPCURTHREAD, offsetof(struct pcpu, pc_fpcurthread));
|
||||
ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb));
|
||||
ASSYM(PC_SWITCHTIME, offsetof(struct pcpu, pc_switchtime));
|
||||
ASSYM(PC_CPUID, offsetof(struct pcpu, pc_cpuid));
|
||||
|
||||
ASSYM(MTX_LOCK, offsetof(struct mtx, mtx_lock));
|
||||
ASSYM(MTX_RECURSE, offsetof(struct mtx, mtx_recurse));
|
||||
|
@ -246,6 +246,11 @@ cpu_startup(dummy)
|
||||
ia64_probe_sapics();
|
||||
}
|
||||
|
||||
void
|
||||
cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t size)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
identifycpu(void)
|
||||
{
|
||||
@ -671,9 +676,9 @@ ia64_init(u_int64_t arg1, u_int64_t arg2)
|
||||
{
|
||||
/* This is not a 'struct user' */
|
||||
size_t sz = round_page(KSTACK_PAGES * PAGE_SIZE);
|
||||
globalp = (struct globaldata *) pmap_steal_memory(sz);
|
||||
globaldata_init(globalp, 0, sz);
|
||||
ia64_set_k4((u_int64_t) globalp);
|
||||
pcpup = (struct pcpu *) pmap_steal_memory(sz);
|
||||
pcpu_init(pcpup, 0, sz);
|
||||
ia64_set_k4((u_int64_t) pcpup);
|
||||
PCPU_GET(next_asn) = 1; /* 0 used for proc0 pmap */
|
||||
}
|
||||
|
||||
@ -697,7 +702,6 @@ ia64_init(u_int64_t arg1, u_int64_t arg2)
|
||||
|
||||
/* Setup curproc so that mutexes work */
|
||||
PCPU_SET(curthread, thread0);
|
||||
PCPU_SET(spinlocks, NULL);
|
||||
|
||||
LIST_INIT(&thread0->td_contested);
|
||||
|
||||
@ -1382,17 +1386,6 @@ ia64_fpstate_switch(struct thread *td)
|
||||
td->td_md.md_flags |= MDP_FPUSED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialise a struct globaldata.
|
||||
*/
|
||||
void
|
||||
globaldata_init(struct globaldata *globaldata, int cpuid, size_t sz)
|
||||
{
|
||||
bzero(globaldata, sz);
|
||||
globaldata->gd_cpuid = cpuid;
|
||||
globaldata_register(globaldata);
|
||||
}
|
||||
|
||||
/*
|
||||
* Utility functions for manipulating instruction bundles.
|
||||
*/
|
||||
|
@ -42,7 +42,6 @@
|
||||
#include <vm/pmap.h>
|
||||
|
||||
#include <machine/atomic.h>
|
||||
#include <machine/globaldata.h>
|
||||
#include <machine/pal.h>
|
||||
#include <machine/pmap.h>
|
||||
#include <machine/clock.h>
|
||||
|
@ -199,7 +199,7 @@ ENTRY(suword, 2)
|
||||
(p6) br.dpnt.few fusufault
|
||||
|
||||
movl r14=fusufault // set up fault handler.
|
||||
add r15=GD_CURTHREAD,r13 // find curthread
|
||||
add r15=PC_CURTHREAD,r13 // find curthread
|
||||
;;
|
||||
ld8 r15=[r15]
|
||||
;;
|
||||
@ -227,7 +227,7 @@ ENTRY(subyte, 2)
|
||||
(p6) br.dpnt.few fusufault
|
||||
|
||||
movl r14=fusufault // set up fault handler.
|
||||
add r15=GD_CURTHREAD,r13 // find curthread
|
||||
add r15=PC_CURTHREAD,r13 // find curthread
|
||||
;;
|
||||
ld8 r15=[r15]
|
||||
;;
|
||||
@ -255,7 +255,7 @@ ENTRY(fuword, 1)
|
||||
(p6) br.dpnt.few fusufault
|
||||
|
||||
movl r14=fusufault // set up fault handler.
|
||||
add r15=GD_CURTHREAD,r13 // find curthread
|
||||
add r15=PC_CURTHREAD,r13 // find curthread
|
||||
;;
|
||||
ld8 r15=[r15]
|
||||
;;
|
||||
@ -282,7 +282,7 @@ ENTRY(fubyte, 1)
|
||||
(p6) br.dpnt.few fusufault
|
||||
|
||||
movl r14=fusufault // set up fault handler.
|
||||
add r15=GD_CURTHREAD,r13 // find curthread
|
||||
add r15=PC_CURTHREAD,r13 // find curthread
|
||||
;;
|
||||
ld8 r15=[r15]
|
||||
;;
|
||||
@ -376,7 +376,7 @@ ENTRY(copyinstr, 4)
|
||||
;;
|
||||
(p6) br.cond.spnt.few copyerr // if it's not, error out.
|
||||
movl r14=copyerr // set up fault handler.
|
||||
add r15=GD_CURTHREAD,r13 // find curthread
|
||||
add r15=PC_CURTHREAD,r13 // find curthread
|
||||
;;
|
||||
ld8 r15=[r15]
|
||||
;;
|
||||
@ -416,7 +416,7 @@ ENTRY(copyoutstr, 4)
|
||||
;;
|
||||
(p6) br.cond.spnt.few copyerr // if it's not, error out.
|
||||
movl r14=copyerr // set up fault handler.
|
||||
add r15=GD_CURTHREAD,r13 // find curthread
|
||||
add r15=PC_CURTHREAD,r13 // find curthread
|
||||
;;
|
||||
ld8 r15=[r15]
|
||||
;;
|
||||
@ -536,7 +536,7 @@ ENTRY(copyin, 3)
|
||||
;;
|
||||
(p6) br.cond.spnt.few copyerr // if it's not, error out.
|
||||
movl r14=copyerr // set up fault handler.
|
||||
add r15=GD_CURTHREAD,r13 // find curthread
|
||||
add r15=PC_CURTHREAD,r13 // find curthread
|
||||
;;
|
||||
ld8 r15=[r15]
|
||||
;;
|
||||
@ -576,7 +576,7 @@ ENTRY(copyout, 3)
|
||||
;;
|
||||
(p6) br.cond.spnt.few copyerr // if it's not, error out.
|
||||
movl r14=copyerr // set up fault handler.
|
||||
add r15=GD_CURTHREAD,r13 // find curthread
|
||||
add r15=PC_CURTHREAD,r13 // find curthread
|
||||
;;
|
||||
ld8 r15=[r15]
|
||||
;;
|
||||
@ -602,7 +602,7 @@ END(copyout)
|
||||
|
||||
ENTRY(copyerr, 0)
|
||||
|
||||
add r14=GD_CURTHREAD,r13 ;; // find curthread
|
||||
add r14=PC_CURTHREAD,r13 ;; // find curthread
|
||||
ld8 r14=[r14] ;;
|
||||
add r14=TD_PCB,r14 ;; // curthread->td_addr
|
||||
ld8 r14=[r14] ;;
|
||||
|
@ -199,7 +199,7 @@ ENTRY(suword, 2)
|
||||
(p6) br.dpnt.few fusufault
|
||||
|
||||
movl r14=fusufault // set up fault handler.
|
||||
add r15=GD_CURTHREAD,r13 // find curthread
|
||||
add r15=PC_CURTHREAD,r13 // find curthread
|
||||
;;
|
||||
ld8 r15=[r15]
|
||||
;;
|
||||
@ -227,7 +227,7 @@ ENTRY(subyte, 2)
|
||||
(p6) br.dpnt.few fusufault
|
||||
|
||||
movl r14=fusufault // set up fault handler.
|
||||
add r15=GD_CURTHREAD,r13 // find curthread
|
||||
add r15=PC_CURTHREAD,r13 // find curthread
|
||||
;;
|
||||
ld8 r15=[r15]
|
||||
;;
|
||||
@ -255,7 +255,7 @@ ENTRY(fuword, 1)
|
||||
(p6) br.dpnt.few fusufault
|
||||
|
||||
movl r14=fusufault // set up fault handler.
|
||||
add r15=GD_CURTHREAD,r13 // find curthread
|
||||
add r15=PC_CURTHREAD,r13 // find curthread
|
||||
;;
|
||||
ld8 r15=[r15]
|
||||
;;
|
||||
@ -282,7 +282,7 @@ ENTRY(fubyte, 1)
|
||||
(p6) br.dpnt.few fusufault
|
||||
|
||||
movl r14=fusufault // set up fault handler.
|
||||
add r15=GD_CURTHREAD,r13 // find curthread
|
||||
add r15=PC_CURTHREAD,r13 // find curthread
|
||||
;;
|
||||
ld8 r15=[r15]
|
||||
;;
|
||||
@ -376,7 +376,7 @@ ENTRY(copyinstr, 4)
|
||||
;;
|
||||
(p6) br.cond.spnt.few copyerr // if it's not, error out.
|
||||
movl r14=copyerr // set up fault handler.
|
||||
add r15=GD_CURTHREAD,r13 // find curthread
|
||||
add r15=PC_CURTHREAD,r13 // find curthread
|
||||
;;
|
||||
ld8 r15=[r15]
|
||||
;;
|
||||
@ -416,7 +416,7 @@ ENTRY(copyoutstr, 4)
|
||||
;;
|
||||
(p6) br.cond.spnt.few copyerr // if it's not, error out.
|
||||
movl r14=copyerr // set up fault handler.
|
||||
add r15=GD_CURTHREAD,r13 // find curthread
|
||||
add r15=PC_CURTHREAD,r13 // find curthread
|
||||
;;
|
||||
ld8 r15=[r15]
|
||||
;;
|
||||
@ -536,7 +536,7 @@ ENTRY(copyin, 3)
|
||||
;;
|
||||
(p6) br.cond.spnt.few copyerr // if it's not, error out.
|
||||
movl r14=copyerr // set up fault handler.
|
||||
add r15=GD_CURTHREAD,r13 // find curthread
|
||||
add r15=PC_CURTHREAD,r13 // find curthread
|
||||
;;
|
||||
ld8 r15=[r15]
|
||||
;;
|
||||
@ -576,7 +576,7 @@ ENTRY(copyout, 3)
|
||||
;;
|
||||
(p6) br.cond.spnt.few copyerr // if it's not, error out.
|
||||
movl r14=copyerr // set up fault handler.
|
||||
add r15=GD_CURTHREAD,r13 // find curthread
|
||||
add r15=PC_CURTHREAD,r13 // find curthread
|
||||
;;
|
||||
ld8 r15=[r15]
|
||||
;;
|
||||
@ -602,7 +602,7 @@ END(copyout)
|
||||
|
||||
ENTRY(copyerr, 0)
|
||||
|
||||
add r14=GD_CURTHREAD,r13 ;; // find curthread
|
||||
add r14=PC_CURTHREAD,r13 ;; // find curthread
|
||||
ld8 r14=[r14] ;;
|
||||
add r14=TD_PCB,r14 ;; // curthread->td_addr
|
||||
ld8 r14=[r14] ;;
|
||||
|
@ -158,7 +158,7 @@ ENTRY(restorectx, 1)
|
||||
|
||||
ENTRY(cpu_switch, 0)
|
||||
|
||||
add r16=GD_CURTHREAD,r13 ;;
|
||||
add r16=PC_CURTHREAD,r13 ;;
|
||||
ld8 r17=[r16] ;;
|
||||
add r17=TD_PCB,r17 ;;
|
||||
ld8 r17=[r17]
|
||||
@ -211,7 +211,7 @@ ENTRY(cpu_switch, 0)
|
||||
|
||||
br.call.sptk.few rp=choosethread
|
||||
|
||||
add r14=GD_CURTHREAD,r13 ;;
|
||||
add r14=PC_CURTHREAD,r13 ;;
|
||||
ld8 r15=[r14] ;;
|
||||
|
||||
#if 0
|
||||
@ -228,7 +228,7 @@ ENTRY(cpu_switch, 0)
|
||||
#endif
|
||||
|
||||
1:
|
||||
st8 [r14]=ret0 // set r13->gd_curthread
|
||||
st8 [r14]=ret0 // set r13->pc_curthread
|
||||
mov ar.k7=ret0
|
||||
mov r4=ret0 // save from call
|
||||
;;
|
||||
|
@ -1,73 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Luoqi Chen <luoqi@freebsd.org>
|
||||
* Copyright (c) Peter Wemm <peter@netplex.com.au>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_GLOBALDATA_H_
|
||||
#define _MACHINE_GLOBALDATA_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#include <sys/queue.h>
|
||||
|
||||
/*
|
||||
* This structure maps out the global data that needs to be kept on a
|
||||
* per-cpu basis. genassym uses this to generate offsets for the assembler
|
||||
* code, which also provides external symbols so that C can get at them as
|
||||
* though they were really globals. This structure is pointed to by
|
||||
* the per-cpu system value (see alpha_pal_rdval() and alpha_pal_wrval()).
|
||||
* Inside the kernel, the globally reserved register t7 is used to
|
||||
* point at the globaldata structure.
|
||||
*/
|
||||
struct globaldata {
|
||||
struct thread *gd_curthread; /* current thread */
|
||||
struct thread *gd_idlethread; /* idle thread */
|
||||
struct thread *gd_fpcurthread; /* fp state owner */
|
||||
struct pcb *gd_curpcb; /* current pcb */
|
||||
struct timeval gd_switchtime;
|
||||
int gd_switchticks;
|
||||
u_int gd_cpuid; /* this cpu number */
|
||||
u_int gd_other_cpus; /* all other cpus */
|
||||
u_int64_t gd_pending_ipis; /* pending IPI events */
|
||||
struct pmap *gd_current_pmap; /* which pmap is active */
|
||||
u_int32_t gd_next_asn; /* next ASN to allocate */
|
||||
u_int32_t gd_current_asngen; /* ASN rollover check */
|
||||
|
||||
SLIST_ENTRY(globaldata) gd_allcpu;
|
||||
struct lock_list_entry *gd_spinlocks;
|
||||
#ifdef KTR_PERCPU
|
||||
int gd_ktr_idx; /* Index into trace table */
|
||||
char *gd_ktr_buf;
|
||||
char gd_ktr_buf_data[0];
|
||||
#endif
|
||||
};
|
||||
|
||||
void globaldata_init(struct globaldata *pcpu, int cpuid, size_t sz);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !_MACHINE_GLOBALDATA_H_ */
|
@ -1,51 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Luoqi Chen <luoqi@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_GLOBALS_H_
|
||||
#define _MACHINE_GLOBALS_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <machine/globaldata.h>
|
||||
|
||||
register struct globaldata *globalp __asm__("r13");
|
||||
|
||||
#define GLOBALP globalp
|
||||
|
||||
#define PCPU_GET(member) (GLOBALP->gd_ ## member)
|
||||
#define PCPU_PTR(member) (&GLOBALP->gd_ ## member)
|
||||
#define PCPU_SET(member,value) (GLOBALP->gd_ ## member = (value))
|
||||
|
||||
#define curthread PCPU_GET(curthread)
|
||||
#define CURPROC (curthread->td_proc)
|
||||
#define curproc (curthread->td_proc)
|
||||
#define curksegrp (curthread->td_ksegrp)
|
||||
#define curkse (curthread->td_kse)
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !_MACHINE_GLOBALS_H_ */
|
@ -49,7 +49,7 @@
|
||||
*/
|
||||
#define MTX_ENTER(lck, rPSR, rOLD, rNEW, rLCK) \
|
||||
mov rPSR=psr ; \
|
||||
mov rNEW=globalp ; \
|
||||
mov rNEW=pcpup ; \
|
||||
addl rLCK=@ltoff(lck),gp ;; \
|
||||
ld8 rLCK=[rLCK] ;; \
|
||||
add rLCK=MTX_LOCK,rLCK ;; \
|
||||
|
@ -27,47 +27,25 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_GLOBALDATA_H_
|
||||
#define _MACHINE_GLOBALDATA_H_
|
||||
#ifndef _MACHINE_PCPU_H_
|
||||
#define _MACHINE_PCPU_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#include <sys/queue.h>
|
||||
#define PCPU_MD_FIELDS \
|
||||
u_int64_t pc_pending_ipis; /* pending IPIs */ \
|
||||
struct pmap *pc_current_pmap; /* active pmap */ \
|
||||
u_int32_t pc_next_asn; /* next ASN to alloc */ \
|
||||
u_int32_t pc_current_asngen /* ASN rollover check */
|
||||
|
||||
/*
|
||||
* This structure maps out the global data that needs to be kept on a
|
||||
* per-cpu basis. genassym uses this to generate offsets for the assembler
|
||||
* code, which also provides external symbols so that C can get at them as
|
||||
* though they were really globals. This structure is pointed to by
|
||||
* the per-cpu system value (see alpha_pal_rdval() and alpha_pal_wrval()).
|
||||
* Inside the kernel, the globally reserved register t7 is used to
|
||||
* point at the globaldata structure.
|
||||
*/
|
||||
struct globaldata {
|
||||
struct thread *gd_curthread; /* current thread */
|
||||
struct thread *gd_idlethread; /* idle thread */
|
||||
struct thread *gd_fpcurthread; /* fp state owner */
|
||||
struct pcb *gd_curpcb; /* current pcb */
|
||||
struct timeval gd_switchtime;
|
||||
int gd_switchticks;
|
||||
u_int gd_cpuid; /* this cpu number */
|
||||
u_int gd_other_cpus; /* all other cpus */
|
||||
u_int64_t gd_pending_ipis; /* pending IPI events */
|
||||
struct pmap *gd_current_pmap; /* which pmap is active */
|
||||
u_int32_t gd_next_asn; /* next ASN to allocate */
|
||||
u_int32_t gd_current_asngen; /* ASN rollover check */
|
||||
struct pcpu;
|
||||
|
||||
SLIST_ENTRY(globaldata) gd_allcpu;
|
||||
struct lock_list_entry *gd_spinlocks;
|
||||
#ifdef KTR_PERCPU
|
||||
int gd_ktr_idx; /* Index into trace table */
|
||||
char *gd_ktr_buf;
|
||||
char gd_ktr_buf_data[0];
|
||||
#endif
|
||||
};
|
||||
register struct pcpu *pcpup __asm__("r13");
|
||||
|
||||
void globaldata_init(struct globaldata *pcpu, int cpuid, size_t sz);
|
||||
#define PCPU_GET(member) (pcpup->pc_ ## member)
|
||||
#define PCPU_PTR(member) (&pcpup->pc_ ## member)
|
||||
#define PCPU_SET(member,value) (pcpup->pc_ ## member = (value))
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !_MACHINE_GLOBALDATA_H_ */
|
||||
#endif /* !_MACHINE_PCPU_H_ */
|
||||
|
@ -31,9 +31,6 @@
|
||||
#ifndef _MACHINE_PROC_H_
|
||||
#define _MACHINE_PROC_H_
|
||||
|
||||
#include <machine/globaldata.h>
|
||||
#include <machine/globals.h>
|
||||
|
||||
/*
|
||||
* Machine-dependent part of the proc struct for the Alpha.
|
||||
*/
|
||||
|
@ -68,7 +68,6 @@
|
||||
#include <sys/conf.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
#include <machine/globals.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_param.h>
|
||||
|
@ -37,18 +37,18 @@ static void
|
||||
idle_setup(void *dummy)
|
||||
{
|
||||
#ifdef SMP
|
||||
struct globaldata *gd;
|
||||
struct pcpu *pc;
|
||||
#endif
|
||||
struct proc *p;
|
||||
int error;
|
||||
|
||||
#ifdef SMP
|
||||
SLIST_FOREACH(gd, &cpuhead, gd_allcpu) {
|
||||
SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
|
||||
error = kthread_create(idle_proc, NULL, &p,
|
||||
RFSTOPPED | RFHIGHPID, "idle: cpu%d", gd->gd_cpuid);
|
||||
gd->gd_idlethread = &p->p_thread;
|
||||
if (gd->gd_curthread == NULL)
|
||||
gd->gd_curthread = gd->gd_idlethread;
|
||||
RFSTOPPED | RFHIGHPID, "idle: cpu%d", pc->pc_cpuid);
|
||||
pc->pc_idlethread = &p->p_thread;
|
||||
if (pc->pc_curthread == NULL)
|
||||
pc->pc_curthread = pc->pc_idlethread;
|
||||
#else
|
||||
error = kthread_create(idle_proc, NULL, &p,
|
||||
RFSTOPPED | RFHIGHPID, "idle");
|
||||
|
@ -42,10 +42,10 @@
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/ktr.h>
|
||||
#include <sys/libkern.h>
|
||||
#include <sys/pcpu.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/time.h>
|
||||
#include <machine/globals.h>
|
||||
#include <machine/stdarg.h>
|
||||
|
||||
#include <ddb/ddb.h>
|
||||
|
@ -44,32 +44,100 @@
|
||||
* sole CPU as 0.
|
||||
*/
|
||||
|
||||
#include "opt_ddb.h"
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/linker_set.h>
|
||||
#include <sys/lock.h>
|
||||
#include <sys/pcpu.h>
|
||||
#include <sys/proc.h>
|
||||
#include <ddb/ddb.h>
|
||||
|
||||
static struct globaldata *cpuid_to_globaldata[MAXCPU];
|
||||
static struct pcpu *cpuid_to_pcpu[MAXCPU];
|
||||
struct cpuhead cpuhead = SLIST_HEAD_INITIALIZER(cpuhead);
|
||||
|
||||
/*
|
||||
* Register a struct globaldata.
|
||||
* Initialize the MI portions of a struct pcpu.
|
||||
*/
|
||||
void
|
||||
globaldata_register(struct globaldata *globaldata)
|
||||
pcpu_init(struct pcpu *pcpu, int cpuid, size_t size)
|
||||
{
|
||||
|
||||
KASSERT(globaldata->gd_cpuid >= 0 && globaldata->gd_cpuid < MAXCPU,
|
||||
("globaldata_register: invalid cpuid"));
|
||||
cpuid_to_globaldata[globaldata->gd_cpuid] = globaldata;
|
||||
SLIST_INSERT_HEAD(&cpuhead, globaldata, gd_allcpu);
|
||||
bzero(pcpu, size);
|
||||
KASSERT(cpuid >= 0 && cpuid < MAXCPU,
|
||||
("pcpu_init: invalid cpuid %d", cpuid));
|
||||
pcpu->pc_cpuid = cpuid;
|
||||
cpuid_to_pcpu[cpuid] = pcpu;
|
||||
SLIST_INSERT_HEAD(&cpuhead, pcpu, pc_allcpu);
|
||||
cpu_pcpu_init(pcpu, cpuid, size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Locate a struct globaldata by cpu id.
|
||||
* Destroy a struct pcpu.
|
||||
*/
|
||||
struct globaldata *
|
||||
globaldata_find(u_int cpuid)
|
||||
void
|
||||
pcpu_destroy(struct pcpu *pcpu)
|
||||
{
|
||||
|
||||
return (cpuid_to_globaldata[cpuid]);
|
||||
SLIST_REMOVE(&cpuhead, pcpu, pcpu, pc_allcpu);
|
||||
cpuid_to_pcpu[pcpu->pc_cpuid] = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Locate a struct pcpu by cpu id.
|
||||
*/
|
||||
struct pcpu *
|
||||
pcpu_find(u_int cpuid)
|
||||
{
|
||||
|
||||
return (cpuid_to_pcpu[cpuid]);
|
||||
}
|
||||
|
||||
#ifdef DDB
|
||||
DB_SHOW_COMMAND(pcpu, db_show_pcpu)
|
||||
{
|
||||
struct pcpu *pc;
|
||||
struct thread *td;
|
||||
int id;
|
||||
|
||||
if (have_addr)
|
||||
id = ((addr >> 4) % 16) * 10 + (addr % 16);
|
||||
else
|
||||
id = PCPU_GET(cpuid);
|
||||
pc = pcpu_find(id);
|
||||
if (pc == NULL) {
|
||||
db_printf("CPU %d not found\n", id);
|
||||
return;
|
||||
}
|
||||
db_printf("cpuid = %d\n", pc->pc_cpuid);
|
||||
db_printf("curthread = ");
|
||||
td = pc->pc_curthread;
|
||||
if (td != NULL)
|
||||
db_printf("%p: pid %d \"%s\"\n", td, td->td_proc->p_pid,
|
||||
td->td_proc->p_comm);
|
||||
else
|
||||
db_printf("none\n");
|
||||
db_printf("curpcb = %p\n", pc->pc_curpcb);
|
||||
db_printf("fpcurthread = ");
|
||||
td = pc->pc_fpcurthread;
|
||||
if (td != NULL)
|
||||
db_printf("%p: pid %d \"%s\"\n", td, td->td_proc->p_pid,
|
||||
td->td_proc->p_comm);
|
||||
else
|
||||
db_printf("none\n");
|
||||
db_printf("idlethread = ");
|
||||
td = pc->pc_idlethread;
|
||||
if (td != NULL)
|
||||
db_printf("%p: pid %d \"%s\"\n", td, td->td_proc->p_pid,
|
||||
td->td_proc->p_comm);
|
||||
else
|
||||
db_printf("none\n");
|
||||
db_show_mdpcpu(pc);
|
||||
|
||||
#ifdef WITNESS
|
||||
db_printf("spin locks held:\n");
|
||||
witness_list_locks(&pc->pc_spinlocks);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
@ -132,7 +132,7 @@ forward_signal(struct thread *td)
|
||||
void
|
||||
forward_roundrobin(void)
|
||||
{
|
||||
struct globaldata *gd;
|
||||
struct pcpu *pc;
|
||||
struct thread *td;
|
||||
u_int id, map;
|
||||
|
||||
@ -145,11 +145,11 @@ forward_roundrobin(void)
|
||||
if (!forward_roundrobin_enabled)
|
||||
return;
|
||||
map = 0;
|
||||
SLIST_FOREACH(gd, &cpuhead, gd_allcpu) {
|
||||
td = gd->gd_curthread;
|
||||
id = gd->gd_cpuid;
|
||||
SLIST_FOREACH(pc, &cpuhead, pc_allcpu) {
|
||||
td = pc->pc_curthread;
|
||||
id = pc->pc_cpuid;
|
||||
if (id != PCPU_GET(cpuid) && (id & stopped_cpus) == 0 &&
|
||||
td != gd->gd_idlethread) {
|
||||
td != pc->pc_idlethread) {
|
||||
td->td_kse->ke_flags |= KEF_NEEDRESCHED;
|
||||
map |= id;
|
||||
}
|
||||
|
@ -104,7 +104,6 @@
|
||||
#include <machine/pc/bios.h>
|
||||
#include <machine/pcb_ext.h> /* pcb.h included via sys/user.h */
|
||||
#include <machine/proc.h>
|
||||
#include <machine/globals.h>
|
||||
#ifdef PERFMON
|
||||
#include <machine/perfmon.h>
|
||||
#endif
|
||||
@ -220,7 +219,7 @@ struct kva_md_info kmi;
|
||||
|
||||
static struct trapframe proc0_tf;
|
||||
#ifndef SMP
|
||||
static struct globaldata __globaldata;
|
||||
static struct pcpu __pcpu;
|
||||
#endif
|
||||
|
||||
struct mtx sched_lock;
|
||||
@ -275,7 +274,7 @@ cpu_startup(dummy)
|
||||
bufinit();
|
||||
vm_pager_bufferinit();
|
||||
|
||||
globaldata_register(GLOBALDATA);
|
||||
pcpu_init(GLOBALDATA, 0, sizeof(struct pcpu));
|
||||
#ifndef SMP
|
||||
/* For SMP, we delay the cpu_setregs() until after SMP startup. */
|
||||
cpu_setregs();
|
||||
@ -1774,15 +1773,15 @@ init386(first)
|
||||
atop(sizeof(struct privatespace) - 1);
|
||||
gdt_segs[GPRIV_SEL].ssd_base = (int) &SMP_prvspace[0];
|
||||
gdt_segs[GPROC0_SEL].ssd_base =
|
||||
(int) &SMP_prvspace[0].globaldata.gd_common_tss;
|
||||
SMP_prvspace[0].globaldata.gd_prvspace = &SMP_prvspace[0].globaldata;
|
||||
(int) &SMP_prvspace[0].pcpu.pc_common_tss;
|
||||
SMP_prvspace[0].pcpu.pc_prvspace = &SMP_prvspace[0].pcpu;
|
||||
#else
|
||||
gdt_segs[GPRIV_SEL].ssd_limit =
|
||||
atop(sizeof(struct globaldata) - 1);
|
||||
gdt_segs[GPRIV_SEL].ssd_base = (int) &__globaldata;
|
||||
atop(sizeof(struct pcpu) - 1);
|
||||
gdt_segs[GPRIV_SEL].ssd_base = (int) &__pcpu;
|
||||
gdt_segs[GPROC0_SEL].ssd_base =
|
||||
(int) &__globaldata.gd_common_tss;
|
||||
__globaldata.gd_prvspace = &__globaldata;
|
||||
(int) &__pcpu.pc_common_tss;
|
||||
__pcpu.pc_prvspace = &__pcpu;
|
||||
#endif
|
||||
|
||||
for (x = 0; x < NGDT; x++) {
|
||||
|
@ -104,7 +104,6 @@
|
||||
#include <machine/pc/bios.h>
|
||||
#include <machine/pcb_ext.h> /* pcb.h included via sys/user.h */
|
||||
#include <machine/proc.h>
|
||||
#include <machine/globals.h>
|
||||
#ifdef PERFMON
|
||||
#include <machine/perfmon.h>
|
||||
#endif
|
||||
@ -220,7 +219,7 @@ struct kva_md_info kmi;
|
||||
|
||||
static struct trapframe proc0_tf;
|
||||
#ifndef SMP
|
||||
static struct globaldata __globaldata;
|
||||
static struct pcpu __pcpu;
|
||||
#endif
|
||||
|
||||
struct mtx sched_lock;
|
||||
@ -275,7 +274,7 @@ cpu_startup(dummy)
|
||||
bufinit();
|
||||
vm_pager_bufferinit();
|
||||
|
||||
globaldata_register(GLOBALDATA);
|
||||
pcpu_init(GLOBALDATA, 0, sizeof(struct pcpu));
|
||||
#ifndef SMP
|
||||
/* For SMP, we delay the cpu_setregs() until after SMP startup. */
|
||||
cpu_setregs();
|
||||
@ -1774,15 +1773,15 @@ init386(first)
|
||||
atop(sizeof(struct privatespace) - 1);
|
||||
gdt_segs[GPRIV_SEL].ssd_base = (int) &SMP_prvspace[0];
|
||||
gdt_segs[GPROC0_SEL].ssd_base =
|
||||
(int) &SMP_prvspace[0].globaldata.gd_common_tss;
|
||||
SMP_prvspace[0].globaldata.gd_prvspace = &SMP_prvspace[0].globaldata;
|
||||
(int) &SMP_prvspace[0].pcpu.pc_common_tss;
|
||||
SMP_prvspace[0].pcpu.pc_prvspace = &SMP_prvspace[0].pcpu;
|
||||
#else
|
||||
gdt_segs[GPRIV_SEL].ssd_limit =
|
||||
atop(sizeof(struct globaldata) - 1);
|
||||
gdt_segs[GPRIV_SEL].ssd_base = (int) &__globaldata;
|
||||
atop(sizeof(struct pcpu) - 1);
|
||||
gdt_segs[GPRIV_SEL].ssd_base = (int) &__pcpu;
|
||||
gdt_segs[GPROC0_SEL].ssd_base =
|
||||
(int) &__globaldata.gd_common_tss;
|
||||
__globaldata.gd_prvspace = &__globaldata;
|
||||
(int) &__pcpu.pc_common_tss;
|
||||
__pcpu.pc_prvspace = &__pcpu;
|
||||
#endif
|
||||
|
||||
for (x = 0; x < NGDT; x++) {
|
||||
|
@ -424,7 +424,7 @@ trapcode:
|
||||
mtcr 31
|
||||
bc 4,17,1f /* branch if PSL_PR is clear */
|
||||
mfsprg 1,0
|
||||
lwz 1,GD_CURPCB(1)
|
||||
lwz 1,PC_CURPCB(1)
|
||||
addi 1,1,USPACE /* stack is top of user struct */
|
||||
1:
|
||||
bla s_trap
|
||||
@ -447,7 +447,7 @@ alitrap:
|
||||
mtcr 31
|
||||
bc 4,17,1f /* branch if PSL_PR is clear */
|
||||
mfsprg 1,0
|
||||
lwz 1,GD_CURPCB(1)
|
||||
lwz 1,PC_CURPCB(1)
|
||||
addi 1,1,USPACE /* stack is top of user struct */
|
||||
1:
|
||||
bla s_trap
|
||||
@ -913,7 +913,7 @@ realtrap:
|
||||
overwritten) */
|
||||
bc 4,17,s_trap /* branch if PSL_PR is false */
|
||||
mfsprg 1,0
|
||||
lwz 1,GD_CURPCB(1)
|
||||
lwz 1,PC_CURPCB(1)
|
||||
addi 1,1,USPACE /* stack is top of user struct */
|
||||
|
||||
/*
|
||||
@ -1109,8 +1109,8 @@ intr_exit:
|
||||
/* Returning to user mode? */
|
||||
mtcr 6 /* saved SRR1 */
|
||||
bc 4,17,1f /* branch if PSL_PR is false */
|
||||
mfsprg 3,0 /* get globaldata */
|
||||
lwz 3,GD_CURPCB(3) /* get curpcb from globaldata */
|
||||
mfsprg 3,0 /* get pcpu */
|
||||
lwz 3,PC_CURPCB(3) /* get curpcb from pcpu */
|
||||
lwz 3,PCB_PMR(3) /* get pmap real address from curpcb */
|
||||
mtsr KERNEL_SR,3
|
||||
/* Setup for entry to realtrap: */
|
||||
@ -1330,7 +1330,7 @@ setfault:
|
||||
mflr 0
|
||||
mfcr 12
|
||||
mfsprg 4,0
|
||||
lwz 4,GD_CURPCB(4)
|
||||
lwz 4,PC_CURPCB(4)
|
||||
stw 3,PCB_ONFAULT(4)
|
||||
stw 0,0(3)
|
||||
stw 1,4(3)
|
||||
|
@ -101,7 +101,6 @@ static const char rcsid[] =
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/reg.h>
|
||||
#include <machine/fpu.h>
|
||||
#include <machine/globaldata.h>
|
||||
#include <machine/vmparam.h>
|
||||
#include <machine/elf.h>
|
||||
#include <machine/trap.h>
|
||||
@ -352,7 +351,7 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args)
|
||||
{
|
||||
unsigned int exc, scratch;
|
||||
struct mem_region *allmem, *availmem, *mp;
|
||||
struct globaldata *globalp;
|
||||
struct pcpu *pcpup;
|
||||
|
||||
/*
|
||||
* Set up BAT0 to only map the lowest 256 MB area
|
||||
@ -426,14 +425,14 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args)
|
||||
thread0->td_pcb = (struct pcb *)
|
||||
(thread0->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
|
||||
globalp = pmap_steal_memory(round_page(sizeof(struct globaldata)));
|
||||
pcpup = pmap_steal_memory(round_page(sizeof(struct pcpu)));
|
||||
|
||||
/*
|
||||
* XXX: Pass 0 as CPU id. This is bad. We need to work out
|
||||
* XXX: which CPU we are somehow.
|
||||
*/
|
||||
globaldata_init(globalp, 0, sizeof(struct globaldata));
|
||||
__asm ("mtsprg 0, %0" :: "r"(globalp));
|
||||
pcpu_init(pcpup, 0, sizeof(struct pcpu));
|
||||
__asm ("mtsprg 0, %0" :: "r"(pcpup));
|
||||
|
||||
/* Init basic tunables, hz etc */
|
||||
init_param1();
|
||||
@ -442,7 +441,6 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args)
|
||||
/* setup curproc so the mutexes work */
|
||||
|
||||
PCPU_SET(curthread, thread0);
|
||||
PCPU_SET(spinlocks, NULL);
|
||||
|
||||
LIST_INIT(&thread0->td_contested);
|
||||
|
||||
@ -457,14 +455,13 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args)
|
||||
mtx_init(&Giant, "Giant", MTX_DEF | MTX_RECURSE);
|
||||
mtx_init(&sched_lock, "sched lock", MTX_SPIN | MTX_RECURSE);
|
||||
mtx_init(&proc0.p_mtx, "process lock", MTX_DEF);
|
||||
mtx_lock(&Giant);
|
||||
|
||||
/*
|
||||
* Initialise console.
|
||||
*/
|
||||
cninit();
|
||||
|
||||
mtx_lock(&Giant);
|
||||
|
||||
#ifdef __notyet__ /* Needs some rethinking regarding real/virtual OFW */
|
||||
OF_set_callback(callback);
|
||||
#endif
|
||||
@ -908,16 +905,13 @@ ptrace_clear_single_step(struct thread *td)
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialise a struct globaldata.
|
||||
* Initialise a struct pcpu.
|
||||
*/
|
||||
void
|
||||
globaldata_init(struct globaldata *globaldata, int cpuid, size_t sz)
|
||||
{
|
||||
cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz)
|
||||
{
|
||||
|
||||
bzero(globaldata, sz);
|
||||
globaldata->gd_cpuid = cpuid;
|
||||
globaldata->gd_next_asn = 0;
|
||||
globaldata->gd_current_asngen = 1;
|
||||
pcpu->pc_current_asngen = 1;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -72,8 +72,8 @@
|
||||
*/
|
||||
ENTRY(cpu_switch)
|
||||
mflr %r30
|
||||
mfsprg %r3,%r0 /* Get the globaldata pointer */
|
||||
lwz %r4,GD_CURTHREAD(%r3) /* Get the current thread */
|
||||
mfsprg %r3,%r0 /* Get the pcpu pointer */
|
||||
lwz %r4,PC_CURTHREAD(%r3) /* Get the current thread */
|
||||
lwz %r3,TD_PCB(%r4) /* Get a pointer to the PCB */
|
||||
|
||||
stmw %r14,PCB_CONTEXT(%r3) /* Save the non-volatile GP regs */
|
||||
@ -95,8 +95,8 @@ ENTRY(cpu_switch)
|
||||
bl pmap_activate /* Activate the new address space */
|
||||
|
||||
mtlr %r30
|
||||
mfsprg %r4,%r0 /* Get the globaldata pointer */
|
||||
stw %r14,GD_CURTHREAD(%r4) /* Store new current thread */
|
||||
mfsprg %r4,%r0 /* Get the pcpu pointer */
|
||||
stw %r14,PC_CURTHREAD(%r4) /* Store new current thread */
|
||||
lwz %r4,TD_PCB(%r14) /* Grab the new PCB */
|
||||
|
||||
lwz %r29, PCB_FLAGS(%r4) /* Restore FPU regs if needed */
|
||||
|
@ -141,10 +141,10 @@ powerpc_mb(void)
|
||||
__asm __volatile("eieio; sync" : : : "memory");
|
||||
}
|
||||
|
||||
static __inline struct globaldata *
|
||||
powerpc_get_globalp(void)
|
||||
static __inline struct pcpu *
|
||||
powerpc_get_pcpup(void)
|
||||
{
|
||||
struct globaldata *ret;
|
||||
struct pcpu *ret;
|
||||
|
||||
__asm ("mfsprg %0, 0" : "=r"(ret));
|
||||
|
||||
|
@ -1,72 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Luoqi Chen <luoqi@freebsd.org>
|
||||
* Copyright (c) Peter Wemm <peter@netplex.com.au>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_GLOBALDATA_H_
|
||||
#define _MACHINE_GLOBALDATA_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#include <sys/queue.h>
|
||||
|
||||
/*
|
||||
* This structure maps out the global data that needs to be kept on a
|
||||
* per-cpu basis. genassym uses this to generate offsets for the assembler
|
||||
* code, which also provides external symbols so that C can get at them as
|
||||
* though they were really globals. This structure is pointed to by
|
||||
* the per-cpu system value (see alpha_pal_rdval() and alpha_pal_wrval()).
|
||||
* Inside the kernel, the globally reserved register t7 is used to
|
||||
* point at the globaldata structure.
|
||||
*/
|
||||
struct globaldata {
|
||||
struct thread *gd_curthread; /* current thread */
|
||||
struct thread *gd_idlethread; /* idle thread */
|
||||
struct thread *gd_fpcurthread; /* fp state owner */
|
||||
struct pcb *gd_curpcb; /* current pcb */
|
||||
struct timeval gd_switchtime;
|
||||
int gd_switchticks;
|
||||
u_int gd_cpuid; /* this cpu number */
|
||||
u_int gd_other_cpus; /* all other cpus */
|
||||
int gd_inside_intr;
|
||||
u_int32_t gd_next_asn; /* next ASN to allocate */
|
||||
u_int32_t gd_current_asngen; /* ASN rollover check */
|
||||
|
||||
SLIST_ENTRY(globaldata) gd_allcpu;
|
||||
struct lock_list_entry *gd_spinlocks;
|
||||
#ifdef KTR_PERCPU
|
||||
int gd_ktr_idx; /* Index into trace table */
|
||||
char *gd_ktr_buf;
|
||||
char gd_ktr_buf_data[KTR_SIZE];
|
||||
#endif
|
||||
};
|
||||
|
||||
void globaldata_init(struct globaldata *pcpu, int cpuid, size_t sz);
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !_MACHINE_GLOBALDATA_H_ */
|
@ -1,50 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Luoqi Chen <luoqi@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_GLOBALS_H_
|
||||
#define _MACHINE_GLOBALS_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <machine/cpufunc.h>
|
||||
#include <machine/globaldata.h>
|
||||
|
||||
#define GLOBALP ((struct globaldata *) powerpc_get_globalp())
|
||||
|
||||
#define PCPU_GET(member) (GLOBALP->gd_ ## member)
|
||||
#define PCPU_PTR(member) (&GLOBALP->gd_ ## member)
|
||||
#define PCPU_SET(member,value) (GLOBALP->gd_ ## member = (value))
|
||||
|
||||
#define curthread PCPU_GET(curthread)
|
||||
#define CURPROC (curthread->td_proc)
|
||||
#define curproc (curthread->td_proc)
|
||||
#define curksegrp (curthread->td_ksegrp)
|
||||
#define curkse (curthread->td_kse)
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !_MACHINE_GLOBALS_H_ */
|
@ -60,7 +60,7 @@
|
||||
lwarx r0, r11, lck; \ /* load current lock value */
|
||||
cmplwi r0, r1, MTX_UNOWNED; \ /* compare with unowned */
|
||||
beq 1; \ /* if owned, loop */
|
||||
lwz r0, PC_CURPROC(globalp); \ /* load curproc */
|
||||
lwz r0, PC_CURPROC(pcpup); \ /* load curproc */
|
||||
stwcx. r0, r11, lck; \ /* attempt to store */
|
||||
beq 1; \ /* loop if failed */
|
||||
sync; \ /* sync */
|
||||
|
@ -27,46 +27,23 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_GLOBALDATA_H_
|
||||
#define _MACHINE_GLOBALDATA_H_
|
||||
#ifndef _MACHINE_PCPU_H_
|
||||
#define _MACHINE_PCPU_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <machine/cpufunc.h>
|
||||
|
||||
#include <sys/queue.h>
|
||||
#define PCPU_MD_FIELDS \
|
||||
int pc_inside_intr; \
|
||||
u_int32_t pc_next_asn; /* next ASN to alloc */ \
|
||||
u_int32_t pc_current_asngen /* ASN rollover check */
|
||||
|
||||
/*
|
||||
* This structure maps out the global data that needs to be kept on a
|
||||
* per-cpu basis. genassym uses this to generate offsets for the assembler
|
||||
* code, which also provides external symbols so that C can get at them as
|
||||
* though they were really globals. This structure is pointed to by
|
||||
* the per-cpu system value (see alpha_pal_rdval() and alpha_pal_wrval()).
|
||||
* Inside the kernel, the globally reserved register t7 is used to
|
||||
* point at the globaldata structure.
|
||||
*/
|
||||
struct globaldata {
|
||||
struct thread *gd_curthread; /* current thread */
|
||||
struct thread *gd_idlethread; /* idle thread */
|
||||
struct thread *gd_fpcurthread; /* fp state owner */
|
||||
struct pcb *gd_curpcb; /* current pcb */
|
||||
struct timeval gd_switchtime;
|
||||
int gd_switchticks;
|
||||
u_int gd_cpuid; /* this cpu number */
|
||||
u_int gd_other_cpus; /* all other cpus */
|
||||
int gd_inside_intr;
|
||||
u_int32_t gd_next_asn; /* next ASN to allocate */
|
||||
u_int32_t gd_current_asngen; /* ASN rollover check */
|
||||
#define PCPUP ((struct pcpu *) powerpc_get_pcpup())
|
||||
|
||||
SLIST_ENTRY(globaldata) gd_allcpu;
|
||||
struct lock_list_entry *gd_spinlocks;
|
||||
#ifdef KTR_PERCPU
|
||||
int gd_ktr_idx; /* Index into trace table */
|
||||
char *gd_ktr_buf;
|
||||
char gd_ktr_buf_data[KTR_SIZE];
|
||||
#endif
|
||||
};
|
||||
|
||||
void globaldata_init(struct globaldata *pcpu, int cpuid, size_t sz);
|
||||
#define PCPU_GET(member) (PCPUP->pc_ ## member)
|
||||
#define PCPU_PTR(member) (&PCPUP->pc_ ## member)
|
||||
#define PCPU_SET(member,value) (PCPUP->pc_ ## member = (value))
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !_MACHINE_GLOBALDATA_H_ */
|
||||
#endif /* !_MACHINE_PCPU_H_ */
|
||||
|
@ -35,8 +35,6 @@
|
||||
#ifndef _MACHINE_PROC_H_
|
||||
#define _MACHINE_PROC_H_
|
||||
|
||||
#include <machine/globals.h>
|
||||
|
||||
/*
|
||||
* Machine-dependent part of the proc structure
|
||||
*/
|
||||
|
@ -60,9 +60,9 @@
|
||||
#include <machine/pcb.h>
|
||||
#include <machine/pmap.h>
|
||||
|
||||
ASSYM(GD_CURTHREAD, offsetof(struct globaldata, gd_curthread));
|
||||
ASSYM(GD_CURPCB, offsetof(struct globaldata, gd_curpcb));
|
||||
ASSYM(GD_SWITCHTIME, offsetof(struct globaldata, gd_switchtime));
|
||||
ASSYM(PC_CURTHREAD, offsetof(struct pcpu, pc_curthread));
|
||||
ASSYM(PC_CURPCB, offsetof(struct pcpu, pc_curpcb));
|
||||
ASSYM(PC_SWITCHTIME, offsetof(struct pcpu, pc_switchtime));
|
||||
|
||||
ASSYM(MTX_LOCK, offsetof(struct mtx, mtx_lock));
|
||||
ASSYM(MTX_RECURSECNT, offsetof(struct mtx, mtx_recurse));
|
||||
|
@ -424,7 +424,7 @@ trapcode:
|
||||
mtcr 31
|
||||
bc 4,17,1f /* branch if PSL_PR is clear */
|
||||
mfsprg 1,0
|
||||
lwz 1,GD_CURPCB(1)
|
||||
lwz 1,PC_CURPCB(1)
|
||||
addi 1,1,USPACE /* stack is top of user struct */
|
||||
1:
|
||||
bla s_trap
|
||||
@ -447,7 +447,7 @@ alitrap:
|
||||
mtcr 31
|
||||
bc 4,17,1f /* branch if PSL_PR is clear */
|
||||
mfsprg 1,0
|
||||
lwz 1,GD_CURPCB(1)
|
||||
lwz 1,PC_CURPCB(1)
|
||||
addi 1,1,USPACE /* stack is top of user struct */
|
||||
1:
|
||||
bla s_trap
|
||||
@ -913,7 +913,7 @@ realtrap:
|
||||
overwritten) */
|
||||
bc 4,17,s_trap /* branch if PSL_PR is false */
|
||||
mfsprg 1,0
|
||||
lwz 1,GD_CURPCB(1)
|
||||
lwz 1,PC_CURPCB(1)
|
||||
addi 1,1,USPACE /* stack is top of user struct */
|
||||
|
||||
/*
|
||||
@ -1109,8 +1109,8 @@ intr_exit:
|
||||
/* Returning to user mode? */
|
||||
mtcr 6 /* saved SRR1 */
|
||||
bc 4,17,1f /* branch if PSL_PR is false */
|
||||
mfsprg 3,0 /* get globaldata */
|
||||
lwz 3,GD_CURPCB(3) /* get curpcb from globaldata */
|
||||
mfsprg 3,0 /* get pcpu */
|
||||
lwz 3,PC_CURPCB(3) /* get curpcb from pcpu */
|
||||
lwz 3,PCB_PMR(3) /* get pmap real address from curpcb */
|
||||
mtsr KERNEL_SR,3
|
||||
/* Setup for entry to realtrap: */
|
||||
@ -1330,7 +1330,7 @@ setfault:
|
||||
mflr 0
|
||||
mfcr 12
|
||||
mfsprg 4,0
|
||||
lwz 4,GD_CURPCB(4)
|
||||
lwz 4,PC_CURPCB(4)
|
||||
stw 3,PCB_ONFAULT(4)
|
||||
stw 0,0(3)
|
||||
stw 1,4(3)
|
||||
|
@ -424,7 +424,7 @@ trapcode:
|
||||
mtcr 31
|
||||
bc 4,17,1f /* branch if PSL_PR is clear */
|
||||
mfsprg 1,0
|
||||
lwz 1,GD_CURPCB(1)
|
||||
lwz 1,PC_CURPCB(1)
|
||||
addi 1,1,USPACE /* stack is top of user struct */
|
||||
1:
|
||||
bla s_trap
|
||||
@ -447,7 +447,7 @@ alitrap:
|
||||
mtcr 31
|
||||
bc 4,17,1f /* branch if PSL_PR is clear */
|
||||
mfsprg 1,0
|
||||
lwz 1,GD_CURPCB(1)
|
||||
lwz 1,PC_CURPCB(1)
|
||||
addi 1,1,USPACE /* stack is top of user struct */
|
||||
1:
|
||||
bla s_trap
|
||||
@ -913,7 +913,7 @@ realtrap:
|
||||
overwritten) */
|
||||
bc 4,17,s_trap /* branch if PSL_PR is false */
|
||||
mfsprg 1,0
|
||||
lwz 1,GD_CURPCB(1)
|
||||
lwz 1,PC_CURPCB(1)
|
||||
addi 1,1,USPACE /* stack is top of user struct */
|
||||
|
||||
/*
|
||||
@ -1109,8 +1109,8 @@ intr_exit:
|
||||
/* Returning to user mode? */
|
||||
mtcr 6 /* saved SRR1 */
|
||||
bc 4,17,1f /* branch if PSL_PR is false */
|
||||
mfsprg 3,0 /* get globaldata */
|
||||
lwz 3,GD_CURPCB(3) /* get curpcb from globaldata */
|
||||
mfsprg 3,0 /* get pcpu */
|
||||
lwz 3,PC_CURPCB(3) /* get curpcb from pcpu */
|
||||
lwz 3,PCB_PMR(3) /* get pmap real address from curpcb */
|
||||
mtsr KERNEL_SR,3
|
||||
/* Setup for entry to realtrap: */
|
||||
@ -1330,7 +1330,7 @@ setfault:
|
||||
mflr 0
|
||||
mfcr 12
|
||||
mfsprg 4,0
|
||||
lwz 4,GD_CURPCB(4)
|
||||
lwz 4,PC_CURPCB(4)
|
||||
stw 3,PCB_ONFAULT(4)
|
||||
stw 0,0(3)
|
||||
stw 1,4(3)
|
||||
|
@ -101,7 +101,6 @@ static const char rcsid[] =
|
||||
#include <machine/md_var.h>
|
||||
#include <machine/reg.h>
|
||||
#include <machine/fpu.h>
|
||||
#include <machine/globaldata.h>
|
||||
#include <machine/vmparam.h>
|
||||
#include <machine/elf.h>
|
||||
#include <machine/trap.h>
|
||||
@ -352,7 +351,7 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args)
|
||||
{
|
||||
unsigned int exc, scratch;
|
||||
struct mem_region *allmem, *availmem, *mp;
|
||||
struct globaldata *globalp;
|
||||
struct pcpu *pcpup;
|
||||
|
||||
/*
|
||||
* Set up BAT0 to only map the lowest 256 MB area
|
||||
@ -426,14 +425,14 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args)
|
||||
thread0->td_pcb = (struct pcb *)
|
||||
(thread0->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
|
||||
globalp = pmap_steal_memory(round_page(sizeof(struct globaldata)));
|
||||
pcpup = pmap_steal_memory(round_page(sizeof(struct pcpu)));
|
||||
|
||||
/*
|
||||
* XXX: Pass 0 as CPU id. This is bad. We need to work out
|
||||
* XXX: which CPU we are somehow.
|
||||
*/
|
||||
globaldata_init(globalp, 0, sizeof(struct globaldata));
|
||||
__asm ("mtsprg 0, %0" :: "r"(globalp));
|
||||
pcpu_init(pcpup, 0, sizeof(struct pcpu));
|
||||
__asm ("mtsprg 0, %0" :: "r"(pcpup));
|
||||
|
||||
/* Init basic tunables, hz etc */
|
||||
init_param1();
|
||||
@ -442,7 +441,6 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args)
|
||||
/* setup curproc so the mutexes work */
|
||||
|
||||
PCPU_SET(curthread, thread0);
|
||||
PCPU_SET(spinlocks, NULL);
|
||||
|
||||
LIST_INIT(&thread0->td_contested);
|
||||
|
||||
@ -457,14 +455,13 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args)
|
||||
mtx_init(&Giant, "Giant", MTX_DEF | MTX_RECURSE);
|
||||
mtx_init(&sched_lock, "sched lock", MTX_SPIN | MTX_RECURSE);
|
||||
mtx_init(&proc0.p_mtx, "process lock", MTX_DEF);
|
||||
mtx_lock(&Giant);
|
||||
|
||||
/*
|
||||
* Initialise console.
|
||||
*/
|
||||
cninit();
|
||||
|
||||
mtx_lock(&Giant);
|
||||
|
||||
#ifdef __notyet__ /* Needs some rethinking regarding real/virtual OFW */
|
||||
OF_set_callback(callback);
|
||||
#endif
|
||||
@ -908,16 +905,13 @@ ptrace_clear_single_step(struct thread *td)
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialise a struct globaldata.
|
||||
* Initialise a struct pcpu.
|
||||
*/
|
||||
void
|
||||
globaldata_init(struct globaldata *globaldata, int cpuid, size_t sz)
|
||||
{
|
||||
cpu_pcpu_init(struct pcpu *pcpu, int cpuid, size_t sz)
|
||||
{
|
||||
|
||||
bzero(globaldata, sz);
|
||||
globaldata->gd_cpuid = cpuid;
|
||||
globaldata->gd_next_asn = 0;
|
||||
globaldata->gd_current_asngen = 1;
|
||||
pcpu->pc_current_asngen = 1;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -72,8 +72,8 @@
|
||||
*/
|
||||
ENTRY(cpu_switch)
|
||||
mflr %r30
|
||||
mfsprg %r3,%r0 /* Get the globaldata pointer */
|
||||
lwz %r4,GD_CURTHREAD(%r3) /* Get the current thread */
|
||||
mfsprg %r3,%r0 /* Get the pcpu pointer */
|
||||
lwz %r4,PC_CURTHREAD(%r3) /* Get the current thread */
|
||||
lwz %r3,TD_PCB(%r4) /* Get a pointer to the PCB */
|
||||
|
||||
stmw %r14,PCB_CONTEXT(%r3) /* Save the non-volatile GP regs */
|
||||
@ -95,8 +95,8 @@ ENTRY(cpu_switch)
|
||||
bl pmap_activate /* Activate the new address space */
|
||||
|
||||
mtlr %r30
|
||||
mfsprg %r4,%r0 /* Get the globaldata pointer */
|
||||
stw %r14,GD_CURTHREAD(%r4) /* Store new current thread */
|
||||
mfsprg %r4,%r0 /* Get the pcpu pointer */
|
||||
stw %r14,PC_CURTHREAD(%r4) /* Store new current thread */
|
||||
lwz %r4,TD_PCB(%r14) /* Grab the new PCB */
|
||||
|
||||
lwz %r29, PCB_FLAGS(%r4) /* Restore FPU regs if needed */
|
||||
|
@ -72,8 +72,8 @@
|
||||
*/
|
||||
ENTRY(cpu_switch)
|
||||
mflr %r30
|
||||
mfsprg %r3,%r0 /* Get the globaldata pointer */
|
||||
lwz %r4,GD_CURTHREAD(%r3) /* Get the current thread */
|
||||
mfsprg %r3,%r0 /* Get the pcpu pointer */
|
||||
lwz %r4,PC_CURTHREAD(%r3) /* Get the current thread */
|
||||
lwz %r3,TD_PCB(%r4) /* Get a pointer to the PCB */
|
||||
|
||||
stmw %r14,PCB_CONTEXT(%r3) /* Save the non-volatile GP regs */
|
||||
@ -95,8 +95,8 @@ ENTRY(cpu_switch)
|
||||
bl pmap_activate /* Activate the new address space */
|
||||
|
||||
mtlr %r30
|
||||
mfsprg %r4,%r0 /* Get the globaldata pointer */
|
||||
stw %r14,GD_CURTHREAD(%r4) /* Store new current thread */
|
||||
mfsprg %r4,%r0 /* Get the pcpu pointer */
|
||||
stw %r14,PC_CURTHREAD(%r4) /* Store new current thread */
|
||||
lwz %r4,TD_PCB(%r14) /* Grab the new PCB */
|
||||
|
||||
lwz %r29, PCB_FLAGS(%r4) /* Restore FPU regs if needed */
|
||||
|
@ -36,8 +36,8 @@
|
||||
.register %g6,#ignore
|
||||
.register %g7,#ignore
|
||||
|
||||
#define PCPU(member) %g7 + GD_ ## member
|
||||
#define PCPU_ADDR(member, reg) add %g7, GD_ ## member, reg
|
||||
#define PCPU(member) %g7 + PC_ ## member
|
||||
#define PCPU_ADDR(member, reg) add %g7, PC_ ## member, reg
|
||||
|
||||
#define DEBUGGER() ta %xcc, 1
|
||||
|
||||
|
@ -1,78 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Luoqi Chen <luoqi@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* from: FreeBSD: src/sys/i386/include/globaldata.h,v 1.27 2001/04/27
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_GLOBALDATA_H_
|
||||
#define _MACHINE_GLOBALDATA_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <machine/frame.h>
|
||||
#include <machine/intr_machdep.h>
|
||||
|
||||
#define ALT_STACK_SIZE 128
|
||||
|
||||
/*
|
||||
* This structure maps out the global data that needs to be kept on a
|
||||
* per-cpu basis. genassym uses this to generate offsets for the assembler
|
||||
* code, which also provides external symbols so that C can get at them as
|
||||
* though they were really globals. This structure is pointed to by
|
||||
* the per-cpu system value.
|
||||
* Inside the kernel, the globally reserved register g7 is used to
|
||||
* point at the globaldata structure.
|
||||
*/
|
||||
struct globaldata {
|
||||
struct thread *gd_curthread; /* current thread */
|
||||
struct thread *gd_idlethread; /* idle thread */
|
||||
struct pcb *gd_curpcb; /* current pcb */
|
||||
struct timeval gd_switchtime;
|
||||
int gd_switchticks;
|
||||
u_int gd_cpuid; /* this cpu number */
|
||||
u_int gd_other_cpus; /* all other cpus */
|
||||
SLIST_ENTRY(globaldata) gd_allcpu;
|
||||
struct lock_list_entry *gd_spinlocks;
|
||||
|
||||
struct intr_queue gd_iq; /* interrupt queuq */
|
||||
u_long gd_alt_stack[ALT_STACK_SIZE]; /* alternate global stack */
|
||||
u_int gd_wp_insn; /* watch point support */
|
||||
u_long gd_wp_pstate;
|
||||
u_long gd_wp_va;
|
||||
int gd_wp_mask;
|
||||
|
||||
#ifdef KTR_PERCPU
|
||||
int gd_ktr_idx; /* index into trace table */
|
||||
char *gd_ktr_buf;
|
||||
char gd_ktr_buf_data[0];
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !_MACHINE_GLOBALDATA_H_ */
|
@ -1,51 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1999 Luoqi Chen <luoqi@freebsd.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_GLOBALS_H_
|
||||
#define _MACHINE_GLOBALS_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
#include <machine/globaldata.h>
|
||||
|
||||
register struct globaldata *globalp __asm__("%g7");
|
||||
|
||||
#define GLOBALP globalp
|
||||
|
||||
#define PCPU_GET(member) (GLOBALP->gd_ ## member)
|
||||
#define PCPU_PTR(member) (&GLOBALP->gd_ ## member)
|
||||
#define PCPU_SET(member,value) (GLOBALP->gd_ ## member = (value))
|
||||
|
||||
#define curthread PCPU_GET(curthread)
|
||||
#define CURPROC (curthread->td_proc)
|
||||
#define curproc (curthread->td_proc)
|
||||
#define curksegrp (curthread->td_ksegrp)
|
||||
#define curkse (curthread->td_kse)
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !_MACHINE_GLOBALS_H_ */
|
@ -27,52 +27,36 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _MACHINE_GLOBALDATA_H_
|
||||
#define _MACHINE_GLOBALDATA_H_
|
||||
#ifndef _MACHINE_PCPU_H_
|
||||
#define _MACHINE_PCPU_H_
|
||||
|
||||
#ifdef _KERNEL
|
||||
|
||||
#include <sys/queue.h>
|
||||
|
||||
#include <machine/frame.h>
|
||||
#include <machine/intr_machdep.h>
|
||||
|
||||
#define ALT_STACK_SIZE 128
|
||||
|
||||
/*
|
||||
* This structure maps out the global data that needs to be kept on a
|
||||
* per-cpu basis. genassym uses this to generate offsets for the assembler
|
||||
* code, which also provides external symbols so that C can get at them as
|
||||
* though they were really globals. This structure is pointed to by
|
||||
* the per-cpu system value.
|
||||
* Inside the kernel, the globally reserved register g7 is used to
|
||||
* point at the globaldata structure.
|
||||
*/
|
||||
struct globaldata {
|
||||
struct thread *gd_curthread; /* current thread */
|
||||
struct thread *gd_idlethread; /* idle thread */
|
||||
struct pcb *gd_curpcb; /* current pcb */
|
||||
struct timeval gd_switchtime;
|
||||
int gd_switchticks;
|
||||
u_int gd_cpuid; /* this cpu number */
|
||||
u_int gd_other_cpus; /* all other cpus */
|
||||
SLIST_ENTRY(globaldata) gd_allcpu;
|
||||
struct lock_list_entry *gd_spinlocks;
|
||||
#define PCPU_MD_FIELDS \
|
||||
struct intr_queue pc_iq; /* interrupt queuq */ \
|
||||
u_long pc_alt_stack[ALT_STACK_SIZE]; /* alt global stack */ \
|
||||
u_int pc_wp_insn; /* watch point support */ \
|
||||
u_long pc_wp_pstate; \
|
||||
u_long pc_wp_va; \
|
||||
int pc_wp_mask
|
||||
|
||||
struct intr_queue gd_iq; /* interrupt queuq */
|
||||
u_long gd_alt_stack[ALT_STACK_SIZE]; /* alternate global stack */
|
||||
u_int gd_wp_insn; /* watch point support */
|
||||
u_long gd_wp_pstate;
|
||||
u_long gd_wp_va;
|
||||
int gd_wp_mask;
|
||||
struct pcpu;
|
||||
|
||||
#ifdef KTR_PERCPU
|
||||
int gd_ktr_idx; /* index into trace table */
|
||||
char *gd_ktr_buf;
|
||||
char gd_ktr_buf_data[0];
|
||||
#endif
|
||||
};
|
||||
register struct pcpu *pcpup __asm__("%g7");
|
||||
|
||||
#define PCPU_GET(member) (pcpup->pc_ ## member)
|
||||
#define PCPU_PTR(member) (&pcpup->pc_ ## member)
|
||||
#define PCPU_SET(member,value) (pcpup->pc_ ## member = (value))
|
||||
|
||||
#endif /* _KERNEL */
|
||||
|
||||
#endif /* !_MACHINE_GLOBALDATA_H_ */
|
||||
#endif /* !_MACHINE_PCPU_H_ */
|
||||
|
@ -38,7 +38,6 @@
|
||||
#ifndef _MACHINE_PROC_H_
|
||||
#define _MACHINE_PROC_H_
|
||||
|
||||
#include <machine/globals.h>
|
||||
#include <machine/tte.h>
|
||||
|
||||
struct mdthread {
|
||||
|
@ -103,6 +103,11 @@ db_write_bytes(vm_offset_t addr, size_t size, char *data)
|
||||
db_nofault = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
db_show_mdpcpu(struct pcpu *pc)
|
||||
{
|
||||
}
|
||||
|
||||
DB_COMMAND(reboot, db_reboot)
|
||||
{
|
||||
cpu_reset();
|
||||
|
@ -1754,7 +1754,7 @@ tl1_breakpoint:
|
||||
* NOTE: We must be very careful setting up the per-cpu pointer. We know that
|
||||
* it has been pre-set in alternate globals, so we read it from there and setup
|
||||
* the normal %g7 *before* enabling interrupts. This avoids any possibility
|
||||
* of cpu migration and using the wrong globalp.
|
||||
* of cpu migration and using the wrong pcpup.
|
||||
*/
|
||||
ENTRY(tl0_trap)
|
||||
/*
|
||||
@ -2097,7 +2097,7 @@ END(tl0_ret)
|
||||
* the outs don't need to be saved.
|
||||
*
|
||||
* NOTE: See comments above tl0_trap for song and dance about chip bugs and
|
||||
* setting up globalp.
|
||||
* setting up pcpup.
|
||||
*/
|
||||
ENTRY(tl1_trap)
|
||||
sub %sp, TF_SIZEOF, %sp
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user