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:
John Baldwin 2001-12-11 23:33:44 +00:00
parent defd4957cc
commit 0bbc882680
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=87702
107 changed files with 847 additions and 1593 deletions

View File

@ -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);
}

View File

@ -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:

View File

@ -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));

View File

@ -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++;

View File

@ -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. */

View File

@ -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;
}

View File

@ -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);

View File

@ -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. */

View File

@ -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.

View File

@ -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++;

View File

@ -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) */

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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; \

View File

@ -33,7 +33,6 @@
#include <machine/frame.h>
#include <machine/reg.h>
#include <machine/globaldata.h>
#include <machine/alpha_cpu.h>
/*

View File

@ -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_ */

View File

@ -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.
*/

View File

@ -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>

View File

@ -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

View File

@ -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);
}

View File

@ -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

View File

@ -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));

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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_ */

View File

@ -37,7 +37,6 @@
#ifndef _MACHINE_PROC_H_
#define _MACHINE_PROC_H_
#include <machine/globals.h>
#include <machine/segments.h>
struct proc_ldt {

View File

@ -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

View File

@ -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>

View File

@ -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);
}

View File

@ -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));

View File

@ -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);

View File

@ -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;

View File

@ -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() */

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 */

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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;

View File

@ -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_ */

View File

@ -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];

View File

@ -37,7 +37,6 @@
#ifndef _MACHINE_PROC_H_
#define _MACHINE_PROC_H_
#include <machine/globals.h>
#include <machine/segments.h>
struct proc_ldt {

View File

@ -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

View File

@ -510,3 +510,8 @@ db_skip_breakpoint(void)
ddb_regs.tf_cr_iip += 16;
}
}
void
db_show_mdpcpu(struct pcpu *pc)
{
}

View File

@ -34,7 +34,7 @@
* ar.k7 = curthread
* ar.k6 = ksp
* ar.k5 = kbsp
* ar.k4 = globalp
* ar.k4 = pcpup
*/
/*

View File

@ -34,7 +34,7 @@
* ar.k7 = curthread
* ar.k6 = ksp
* ar.k5 = kbsp
* ar.k4 = globalp
* ar.k4 = pcpup
*/
/*

View File

@ -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));

View File

@ -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.
*/

View File

@ -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>

View File

@ -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] ;;

View File

@ -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] ;;

View File

@ -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
;;

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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 ;; \

View File

@ -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_ */

View File

@ -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.
*/

View File

@ -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>

View File

@ -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");

View File

@ -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>

View File

@ -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

View File

@ -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;
}

View File

@ -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++) {

View File

@ -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++) {

View File

@ -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)

View File

@ -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

View File

@ -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 */

View File

@ -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));

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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 */

View File

@ -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_ */

View File

@ -35,8 +35,6 @@
#ifndef _MACHINE_PROC_H_
#define _MACHINE_PROC_H_
#include <machine/globals.h>
/*
* Machine-dependent part of the proc structure
*/

View File

@ -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));

View File

@ -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)

View File

@ -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)

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -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

View File

@ -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_ */

View File

@ -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_ */

View File

@ -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_ */

View File

@ -38,7 +38,6 @@
#ifndef _MACHINE_PROC_H_
#define _MACHINE_PROC_H_
#include <machine/globals.h>
#include <machine/tte.h>
struct mdthread {

View File

@ -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();

View File

@ -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