summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjake <jake@FreeBSD.org>2001-09-30 18:48:37 +0000
committerjake <jake@FreeBSD.org>2001-09-30 18:48:37 +0000
commit0faa0047f499fc2e08f43816ca6a239940a9498f (patch)
tree1f0b79f4759bdfbe8386ea97808b9d6318159a2f
parentde1928a0bc09906d2f0199a21ae8209f505c8f76 (diff)
downloadFreeBSD-src-0faa0047f499fc2e08f43816ca6a239940a9498f.zip
FreeBSD-src-0faa0047f499fc2e08f43816ca6a239940a9498f.tar.gz
Move the pcb the to the top of the kernel stack.
Add a guard page at the bottom of the kernel stack. Its unclear how easy it will be to detect these faults and do something useful. Setup the registers on exec how the c runtime expects. Implement various {fill,set}_*regs. Fix proc locking.
-rw-r--r--sys/sparc64/include/param.h5
-rw-r--r--sys/sparc64/sparc64/locore.S4
-rw-r--r--sys/sparc64/sparc64/locore.s4
-rw-r--r--sys/sparc64/sparc64/machdep.c118
-rw-r--r--sys/sparc64/sparc64/vm_machdep.c5
5 files changed, 75 insertions, 61 deletions
diff --git a/sys/sparc64/include/param.h b/sys/sparc64/include/param.h
index 2f8d6a6..6699778 100644
--- a/sys/sparc64/include/param.h
+++ b/sys/sparc64/include/param.h
@@ -115,12 +115,11 @@
#define MAXPHYS (128 * 1024) /* max raw I/O transfer size */
#define MAXDUMPPGS (DFLTPHYS/PAGE_SIZE)
-#define IOPAGES 2 /* pages of i/o permission bitmap */
-
#define KSTACK_PAGES 4 /* pages of kernel stack (with pcb) */
#define UAREA_PAGES 1 /* pages of user area */
-/* #define KSTACK_GUARD */ /* compile in kstack guard page */
+#define KSTACK_GUARD /* compile in kstack guard page */
+#define KSTACK_GUARD_PAGES 1
/*
* Constants related to network buffer management.
diff --git a/sys/sparc64/sparc64/locore.S b/sys/sparc64/sparc64/locore.S
index fabc03e..a007fef 100644
--- a/sys/sparc64/sparc64/locore.S
+++ b/sys/sparc64/sparc64/locore.S
@@ -48,8 +48,8 @@ ENTRY(_start)
wrpr %g0, 0, %cleanwin
wrpr %g0, 0, %pil
- setx kstack0 + KSTACK_PAGES * PAGE_SIZE - SPOFF, %l0, %o5
- save %o5, -CCFSZ, %sp
+ set kstack0 + KSTACK_PAGES * PAGE_SIZE - PCB_SIZEOF, %o0
+ sub %o0, SPOFF + CCFSZ, %sp
mov %g1, %o0
call sparc64_init
diff --git a/sys/sparc64/sparc64/locore.s b/sys/sparc64/sparc64/locore.s
index fabc03e..a007fef 100644
--- a/sys/sparc64/sparc64/locore.s
+++ b/sys/sparc64/sparc64/locore.s
@@ -48,8 +48,8 @@ ENTRY(_start)
wrpr %g0, 0, %cleanwin
wrpr %g0, 0, %pil
- setx kstack0 + KSTACK_PAGES * PAGE_SIZE - SPOFF, %l0, %o5
- save %o5, -CCFSZ, %sp
+ set kstack0 + KSTACK_PAGES * PAGE_SIZE - PCB_SIZEOF, %o0
+ sub %o0, SPOFF + CCFSZ, %sp
mov %g1, %o0
call sparc64_init
diff --git a/sys/sparc64/sparc64/machdep.c b/sys/sparc64/sparc64/machdep.c
index 413a765..a394092 100644
--- a/sys/sparc64/sparc64/machdep.c
+++ b/sys/sparc64/sparc64/machdep.c
@@ -94,24 +94,25 @@ extern char tl0_base[];
extern char _end[];
-int physmem = 0;
+int physmem;
int cold = 1;
long dumplo;
-int Maxmem = 0;
+int Maxmem;
u_long debug_mask;
struct mtx Giant;
struct mtx sched_lock;
-struct globaldata __globaldata;
+static struct globaldata __globaldata;
/*
* This needs not be aligned as the other user areas, provided that process 0
* does not have an fp state (which it doesn't normally).
* This constraint is only here for debugging.
*/
-char uarea0[UAREA_PAGES * PAGE_SIZE] __attribute__ ((aligned (64)));
-char kstack0[KSTACK_PAGES * PAGE_SIZE] __attribute__ ((aligned (64)));
+char kstack0[KSTACK_PAGES * PAGE_SIZE] __attribute__((aligned(64)));
+static char uarea0[UAREA_PAGES * PAGE_SIZE] __attribute__((aligned(64)));
+static struct trapframe frame0;
struct user *proc0uarea;
vm_offset_t proc0kstack;
@@ -133,10 +134,8 @@ cpu_startup(void *arg)
{
phandle_t child;
phandle_t root;
- char name[32];
char type[8];
u_int clock;
- caddr_t p;
root = OF_peer(0);
for (child = OF_child(root); child != 0; child = OF_peer(child)) {
@@ -146,7 +145,6 @@ cpu_startup(void *arg)
}
if (child == 0)
panic("cpu_startup: no cpu\n");
- OF_getprop(child, "name", name, sizeof(name));
OF_getprop(child, "clock-frequency", &clock, sizeof(clock));
tick_tc.tc_get_timecount = tick_get_timecount;
@@ -156,17 +154,7 @@ cpu_startup(void *arg)
tick_tc.tc_name = "tick";
tc_init(&tick_tc);
- p = name;
- if (bcmp(p, "SUNW,", 5) == 0)
- p += 5;
- printf("CPU: %s Processor (%d.%02d MHz CPU)\n", p,
- (clock + 4999) / 1000000, ((clock + 4999) / 10000) % 100);
-#if 0
- ver = rdpr(ver);
- printf("manuf: %#lx impl: %#lx mask: %#lx maxtl: %#lx maxwin: %#lx\n",
- VER_MANUF(ver), VER_IMPL(ver), VER_MASK(ver), VER_MAXTL(ver),
- VER_MAXWIN(ver));
-#endif
+ cpu_identify(clock);
vm_ksubmap_init(&kmi);
@@ -174,9 +162,8 @@ cpu_startup(void *arg)
vm_pager_bufferinit();
globaldata_register(globalp);
-#if 0
+
tick_start(clock, tick_hardclock);
-#endif
}
unsigned
@@ -188,7 +175,6 @@ tick_get_timecount(struct timecounter *tc)
void
sparc64_init(struct bootinfo *bi, ofw_vec_t *vec)
{
- struct trapframe *tf;
u_long ps;
/*
@@ -245,11 +231,9 @@ sparc64_init(struct bootinfo *bi, ofw_vec_t *vec)
proc0.p_stats = &proc0.p_uarea->u_stats;
thread0 = &proc0.p_thread;
thread0->td_kstack = proc0kstack;
- thread0->td_pcb = (struct pcb *)thread0->td_kstack;
- tf = (struct trapframe *)(thread0->td_kstack + KSTACK_PAGES *
- PAGE_SIZE) - 1;
- tf->tf_tstate = TSTATE_IE;
- thread0->td_frame = tf;
+ thread0->td_pcb = (struct pcb *)
+ (thread0->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
+ thread0->td_frame = &frame0;
LIST_INIT(&thread0->td_contested);
/*
@@ -319,7 +303,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
oonstack = 0;
td = curthread;
p = td->td_proc;
- PROC_LOCK(p);
psp = p->p_sigacts;
tf = td->td_frame;
sp = tf->tf_sp + SPOFF;
@@ -373,7 +356,6 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
SIGDELSET(p->p_sigcatch, SIGILL);
SIGDELSET(p->p_sigmask, SIGILL);
psignal(p, SIGILL);
- PROC_UNLOCK(p);
return;
}
@@ -419,6 +401,8 @@ sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
CTR3(KTR_SIG, "sendsig: return td=%p pc=%#lx sp=%#lx", td, tf->tf_tpc,
tf->tf_sp);
+
+ PROC_LOCK(p);
}
#ifndef _SYS_SYSPROTO_H_
@@ -448,6 +432,10 @@ sigreturn(struct thread *td, struct sigreturn_args *uap)
if (((uc.uc_mcontext.mc_tpc | uc.uc_mcontext.mc_tnpc) & 3) != 0)
return (EINVAL);
+#if 0
+ if (!TSTATE_SECURE(uc.uc_mcontext.mc_tstate))
+ return (EINVAL);
+#endif
tf = td->td_frame;
bcopy(uc.uc_mcontext.mc_global, tf->tf_global,
@@ -476,7 +464,8 @@ sigreturn(struct thread *td, struct sigreturn_args *uap)
void
cpu_halt(void)
{
- TODO;
+
+ OF_exit();
}
int
@@ -500,9 +489,10 @@ setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
{
struct pcb *pcb;
struct frame *fp;
+ u_long sp;
/* Round the stack down to a multiple of 16 bytes. */
- stack = ((stack) / 16) * 16;
+ sp = ((stack) / 16) * 16;
pcb = td->td_pcb;
/* XXX: honor the real number of windows... */
bzero(pcb->pcb_rw, sizeof(pcb->pcb_rw));
@@ -529,8 +519,12 @@ setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
bzero(td->td_frame->tf_out, sizeof(td->td_frame->tf_out));
bzero(td->td_frame->tf_global, sizeof(td->td_frame->tf_global));
/* Set up user stack. */
- fp->f_fp = stack - SPOFF;
- td->td_frame->tf_out[6] = stack - SPOFF - sizeof(struct frame);
+ fp->f_fp = sp - SPOFF;
+ td->td_frame->tf_out[0] = stack;
+ td->td_frame->tf_out[1] = 0;
+ td->td_frame->tf_out[2] = 0;
+ td->td_frame->tf_out[3] = PS_STRINGS;
+ td->td_frame->tf_out[6] = sp - SPOFF - sizeof(struct frame);
wr(y, 0, 0);
mtx_unlock_spin(&sched_lock);
}
@@ -544,43 +538,65 @@ Debugger(const char *msg)
}
int
-fill_dbregs(struct thread *td, struct dbreg *dbregs)
-{
- TODO;
- return (0);
-}
-
-int
-set_dbregs(struct thread *td, struct dbreg *dbregs)
-{
- TODO;
- return (0);
-}
-
-int
fill_regs(struct thread *td, struct reg *regs)
{
- TODO;
+ struct trapframe *tf;
+ struct pcb *pcb;
+
+ tf = td->td_frame;
+ pcb = td->td_pcb;
+ bcopy(tf->tf_global, regs->r_global, sizeof(tf->tf_global));
+ bcopy(tf->tf_out, regs->r_out, sizeof(tf->tf_out));
+ regs->r_tstate = tf->tf_tstate;
+ regs->r_pc = tf->tf_tpc;
+ regs->r_npc = tf->tf_tnpc;
+ regs->r_y = pcb->pcb_y;
return (0);
}
int
set_regs(struct thread *td, struct reg *regs)
{
- TODO;
+ struct trapframe *tf;
+ struct pcb *pcb;
+
+ tf = td->td_frame;
+ pcb = td->td_pcb;
+ if (((regs->r_pc | regs->r_npc) & 3) != 0)
+ return (EINVAL);
+#if 0
+ if (!TSTATE_SECURE(regs->r_tstate))
+ return (EINVAL);
+#endif
+ bcopy(regs->r_global, tf->tf_global, sizeof(regs->r_global));
+ bcopy(regs->r_out, tf->tf_out, sizeof(regs->r_out));
+ tf->tf_tstate = regs->r_tstate;
+ tf->tf_tpc = regs->r_pc;
+ tf->tf_tnpc = regs->r_npc;
+ pcb->pcb_y = regs->r_y;
return (0);
}
int
fill_fpregs(struct thread *td, struct fpreg *fpregs)
{
- TODO;
+ struct pcb *pcb;
+
+ pcb = td->td_pcb;
+ bcopy(pcb->pcb_fpstate.fp_fb, fpregs->fr_regs,
+ sizeof(pcb->pcb_fpstate.fp_fb));
+ fpregs->fr_fsr = pcb->pcb_fpstate.fp_fsr;
return (0);
}
int
set_fpregs(struct thread *td, struct fpreg *fpregs)
{
- TODO;
+ struct pcb *pcb;
+
+ pcb = td->td_pcb;
+ bcopy(fpregs->fr_regs, pcb->pcb_fpstate.fp_fb,
+ sizeof(fpregs->fr_regs));
+ pcb->pcb_fpstate.fp_fsr = fpregs->fr_fsr;
return (0);
}
diff --git a/sys/sparc64/sparc64/vm_machdep.c b/sys/sparc64/sparc64/vm_machdep.c
index 1e94d40..c3c31fe 100644
--- a/sys/sparc64/sparc64/vm_machdep.c
+++ b/sys/sparc64/sparc64/vm_machdep.c
@@ -88,7 +88,7 @@ cpu_fork(struct thread *td1, struct proc *p2, int flags)
return;
td2 = &p2->p_thread;
- pcb = (struct pcb *)td2->td_kstack;
+ pcb = (struct pcb *)(td2->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
td2->td_pcb = pcb;
/*
@@ -112,8 +112,7 @@ cpu_fork(struct thread *td1, struct proc *p2, int flags)
* Copy the trap frame for the return to user mode as if from a
* syscall. This copies most of the user mode register values.
*/
- tf = (struct trapframe *)
- (td2->td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
+ tf = (struct trapframe *)pcb - 1;
bcopy(td1->td_frame, tf, sizeof(*tf));
tf->tf_out[0] = 0; /* Child returns zero */
OpenPOWER on IntegriCloud