- implemented sendsig/sigreturn
- sysctl for cacheline size, required by libc/rtld - init'd more exception vectors - fixed problem with register overwrite in exec_setregs - removed redundant NetBSD code Approved by: benno
This commit is contained in:
parent
3f3331903d
commit
81a6d01d1c
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=103600
@ -88,6 +88,7 @@ static const char rcsid[] =
|
||||
#include <sys/linker.h>
|
||||
#include <sys/cons.h>
|
||||
#include <sys/ucontext.h>
|
||||
#include <sys/sysent.h>
|
||||
#include <net/netisr.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_kern.h>
|
||||
@ -129,6 +130,10 @@ SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "");
|
||||
static char model[128];
|
||||
SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD, model, 0, "");
|
||||
|
||||
static int cacheline_size = CACHELINESIZE;
|
||||
SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size,
|
||||
CTLFLAG_RD, &cacheline_size, 0, "");
|
||||
|
||||
char bootpath[256];
|
||||
|
||||
#ifdef DDB
|
||||
@ -146,9 +151,7 @@ int restore_ofw_mapping(void);
|
||||
|
||||
void install_extint(void (*)(void));
|
||||
|
||||
#ifdef COMPAT_43
|
||||
void osendsig(sig_t, int, sigset_t *, u_long);
|
||||
#endif
|
||||
int setfault(faultbuf); /* defined in locore.S */
|
||||
|
||||
static int
|
||||
sysctl_hw_physmem(SYSCTL_HANDLER_ARGS)
|
||||
@ -382,12 +385,15 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp)
|
||||
/*
|
||||
* XXX: Initialize the interrupt tables.
|
||||
*/
|
||||
bcopy(&trapcode, (void *)EXC_DECR, (size_t)&trapsize);
|
||||
bcopy(&dsitrap, (void *)EXC_DSI, (size_t)&dsisize);
|
||||
bcopy(&isitrap, (void *)EXC_ISI, (size_t)&isisize);
|
||||
bcopy(&trapcode, (void *)EXC_SC, (size_t)&trapsize);
|
||||
bcopy(&trapcode, (void *)EXC_FPU, (size_t)&trapsize);
|
||||
bcopy(&trapcode, (void *)EXC_EXI, (size_t)&trapsize);
|
||||
bcopy(&trapcode, (void *)EXC_ALI, (size_t)&trapsize);
|
||||
bcopy(&trapcode, (void *)EXC_PGM, (size_t)&trapsize);
|
||||
bcopy(&trapcode, (void *)EXC_FPU, (size_t)&trapsize);
|
||||
bcopy(&trapcode, (void *)EXC_DECR, (size_t)&trapsize);
|
||||
bcopy(&trapcode, (void *)EXC_SC, (size_t)&trapsize);
|
||||
bcopy(&trapcode, (void *)EXC_TRC, (size_t)&trapsize);
|
||||
|
||||
/*
|
||||
* Start initializing proc0 and thread0.
|
||||
@ -411,6 +417,11 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp)
|
||||
|
||||
mutex_init();
|
||||
|
||||
/*
|
||||
* Make sure translation has been enabled
|
||||
*/
|
||||
mtmsr(mfmsr() | PSL_IR|PSL_DR|PSL_ME|PSL_RI);
|
||||
|
||||
/*
|
||||
* Initialise virtual memory.
|
||||
*/
|
||||
@ -437,307 +448,6 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp)
|
||||
msgbufinit(msgbufp, MSGBUF_SIZE);
|
||||
}
|
||||
|
||||
#if 0 /* XXX: Old powerpc_init */
|
||||
void
|
||||
powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args)
|
||||
{
|
||||
unsigned int exc, scratch;
|
||||
struct mem_region *allmem, *availmem, *mp;
|
||||
struct pcpu *pcpup;
|
||||
|
||||
/*
|
||||
* Set up BAT0 to only map the lowest 256 MB area
|
||||
*/
|
||||
battable[0].batl = BATL(0x00000000, BAT_M, BAT_PP_RW);
|
||||
battable[0].batu = BATU(0x00000000, BAT_BL_256M, BAT_Vs);
|
||||
|
||||
/*
|
||||
* Map PCI memory space.
|
||||
*/
|
||||
battable[0x8].batl = BATL(0x80000000, BAT_I, BAT_PP_RW);
|
||||
battable[0x8].batu = BATU(0x80000000, BAT_BL_256M, BAT_Vs);
|
||||
|
||||
battable[0x9].batl = BATL(0x90000000, BAT_I, BAT_PP_RW);
|
||||
battable[0x9].batu = BATU(0x90000000, BAT_BL_256M, BAT_Vs);
|
||||
|
||||
battable[0xa].batl = BATL(0xa0000000, BAT_I, BAT_PP_RW);
|
||||
battable[0xa].batu = BATU(0xa0000000, BAT_BL_256M, BAT_Vs);
|
||||
|
||||
/*
|
||||
* Map obio devices.
|
||||
*/
|
||||
battable[0xf].batl = BATL(0xf0000000, BAT_I, BAT_PP_RW);
|
||||
battable[0xf].batu = BATU(0xf0000000, BAT_BL_256M, BAT_Vs);
|
||||
|
||||
/*
|
||||
* Now setup fixed bat registers
|
||||
*
|
||||
* Note that we still run in real mode, and the BAT
|
||||
* registers were cleared above.
|
||||
*/
|
||||
/* BAT0 used for initial 256 MB segment */
|
||||
__asm __volatile ("mtibatl 0,%0; mtibatu 0,%1;"
|
||||
"mtdbatl 0,%0; mtdbatu 0,%1;"
|
||||
:: "r"(battable[0].batl), "r"(battable[0].batu));
|
||||
/*
|
||||
* Set up battable to map all RAM regions.
|
||||
* This is here because mem_regions() call needs bat0 set up.
|
||||
*/
|
||||
mem_regions(&allmem, &availmem);
|
||||
|
||||
/* Calculate the physical memory in the machine */
|
||||
for (mp = allmem; mp->size; mp++)
|
||||
physmem += btoc(mp->size);
|
||||
|
||||
for (mp = allmem; mp->size; mp++) {
|
||||
vm_offset_t pa = mp->start & 0xf0000000;
|
||||
vm_offset_t end = mp->start + mp->size;
|
||||
|
||||
do {
|
||||
u_int n = pa >> 28;
|
||||
|
||||
battable[n].batl = BATL(pa, BAT_M, BAT_PP_RW);
|
||||
battable[n].batu = BATU(pa, BAT_BL_256M, BAT_Vs);
|
||||
pa += 0x10000000;
|
||||
} while (pa < end);
|
||||
}
|
||||
|
||||
chosen = OF_finddevice("/chosen");
|
||||
save_ofw_mapping();
|
||||
|
||||
pmap_setavailmem(startkernel, endkernel);
|
||||
|
||||
proc_linkup(&proc0, &ksegrp0, &kse0, &thread0);
|
||||
|
||||
proc0uarea = (struct user *)pmap_steal_memory(UAREA_PAGES * PAGE_SIZE);
|
||||
proc0kstack = pmap_steal_memory(KSTACK_PAGES * PAGE_SIZE);
|
||||
proc0.p_uarea = proc0uarea;
|
||||
thread0.td_kstack = proc0kstack;
|
||||
thread0.td_pcb = (struct pcb *)
|
||||
(thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
|
||||
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.
|
||||
*/
|
||||
pcpu_init(pcpup, 0, sizeof(struct pcpu));
|
||||
__asm ("mtsprg 0, %0" :: "r"(pcpup));
|
||||
|
||||
/* Init basic tunables, hz etc */
|
||||
init_param1();
|
||||
init_param2(physmem);
|
||||
|
||||
PCPU_SET(curthread, &thread0);
|
||||
|
||||
/* XXX: NetBSDism I _think_. Not sure yet. */
|
||||
#if 0
|
||||
curpm = PCPU_GET(curpcb)->pcb_pmreal = PCPU_GET(curpcb)->pcb_pm = kernel_pmap;
|
||||
#endif
|
||||
|
||||
mutex_init();
|
||||
|
||||
/*
|
||||
* Initialise console.
|
||||
*/
|
||||
cninit();
|
||||
|
||||
#ifdef __notyet__ /* Needs some rethinking regarding real/virtual OFW */
|
||||
OF_set_callback(callback);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set up trap vectors
|
||||
*/
|
||||
for (exc = EXC_RSVD; exc <= EXC_LAST; exc += 0x100) {
|
||||
switch (exc) {
|
||||
default:
|
||||
bcopy(&trapcode, (void *)exc, (size_t)&trapsize);
|
||||
break;
|
||||
case EXC_DECR:
|
||||
bcopy(&decrint, (void *)EXC_DECR, (size_t)&decrsize);
|
||||
break;
|
||||
#if 0 /* XXX: Not enabling these traps yet. */
|
||||
case EXC_EXI:
|
||||
/*
|
||||
* This one is (potentially) installed during autoconf
|
||||
*/
|
||||
break;
|
||||
case EXC_ALI:
|
||||
bcopy(&alitrap, (void *)EXC_ALI, (size_t)&alisize);
|
||||
break;
|
||||
case EXC_DSI:
|
||||
bcopy(&dsitrap, (void *)EXC_DSI, (size_t)&dsisize);
|
||||
break;
|
||||
case EXC_ISI:
|
||||
bcopy(&isitrap, (void *)EXC_ISI, (size_t)&isisize);
|
||||
break;
|
||||
case EXC_IMISS:
|
||||
bcopy(&tlbimiss, (void *)EXC_IMISS, (size_t)&tlbimsize);
|
||||
break;
|
||||
case EXC_DLMISS:
|
||||
bcopy(&tlbdlmiss, (void *)EXC_DLMISS, (size_t)&tlbdlmsize);
|
||||
break;
|
||||
case EXC_DSMISS:
|
||||
bcopy(&tlbdsmiss, (void *)EXC_DSMISS, (size_t)&tlbdsmsize);
|
||||
break;
|
||||
#if defined(DDB) || defined(IPKDB)
|
||||
case EXC_TRC:
|
||||
case EXC_PGM:
|
||||
case EXC_BPT:
|
||||
#if defined(DDB)
|
||||
bcopy(&ddblow, (void *)exc, (size_t)&ddbsize);
|
||||
#else
|
||||
bcopy(&ipkdblow, (void *)exc, (size_t)&ipkdbsize);
|
||||
#endif
|
||||
break;
|
||||
#endif /* DDB || IPKDB */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 /* XXX: coming soon... */
|
||||
/*
|
||||
* external interrupt handler install
|
||||
*/
|
||||
install_extint(ext_intr);
|
||||
#endif
|
||||
|
||||
__syncicache((void *)EXC_RST, EXC_LAST - EXC_RST + 0x100);
|
||||
|
||||
/*
|
||||
* Now enable translation (and machine checks/recoverable interrupts).
|
||||
*/
|
||||
__asm ("mfmsr %0" : "=r"(scratch));
|
||||
scratch |= PSL_IR | PSL_DR | PSL_ME | PSL_RI;
|
||||
__asm ("mtmsr %0" :: "r"(scratch));
|
||||
|
||||
ofmsr &= ~PSL_IP;
|
||||
|
||||
/*
|
||||
* Parse arg string.
|
||||
*/
|
||||
#ifdef DDB
|
||||
bcopy(args + strlen(args) + 1, &startsym, sizeof(startsym));
|
||||
bcopy(args + strlen(args) + 5, &endsym, sizeof(endsym));
|
||||
if (startsym == NULL || endsym == NULL)
|
||||
startsym = endsym = NULL;
|
||||
#endif
|
||||
|
||||
strcpy(bootpath, args);
|
||||
args = bootpath;
|
||||
while (*++args && *args != ' ');
|
||||
if (*args) {
|
||||
*args++ = 0;
|
||||
while (*args) {
|
||||
switch (*args++) {
|
||||
case 'a':
|
||||
boothowto |= RB_ASKNAME;
|
||||
break;
|
||||
case 's':
|
||||
boothowto |= RB_SINGLE;
|
||||
break;
|
||||
case 'd':
|
||||
boothowto |= RB_KDB;
|
||||
break;
|
||||
case 'v':
|
||||
boothowto |= RB_VERBOSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DDB
|
||||
ddb_init((int)((u_int)endsym - (u_int)startsym), startsym, endsym);
|
||||
#endif
|
||||
#ifdef IPKDB
|
||||
/*
|
||||
* Now trap to IPKDB
|
||||
*/
|
||||
ipkdb_init();
|
||||
if (boothowto & RB_KDB)
|
||||
ipkdb_connect(0);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set the page size.
|
||||
*/
|
||||
#if 0
|
||||
vm_set_page_size();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize pmap module.
|
||||
*/
|
||||
pmap_bootstrap();
|
||||
|
||||
restore_ofw_mapping();
|
||||
|
||||
PCPU_GET(next_asn) = 1; /* 0 used for proc0 pmap */
|
||||
|
||||
/* setup proc 0's pcb */
|
||||
thread0.td_pcb->pcb_flags = 0; /* XXXKSE */
|
||||
thread0.td_frame = &proc0_tf;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int N_mapping;
|
||||
static struct {
|
||||
vm_offset_t va;
|
||||
int len;
|
||||
vm_offset_t pa;
|
||||
int mode;
|
||||
} ofw_mapping[256];
|
||||
|
||||
int
|
||||
save_ofw_mapping()
|
||||
{
|
||||
int mmui, mmu;
|
||||
|
||||
OF_getprop(chosen, "mmu", &mmui, 4);
|
||||
mmu = OF_instance_to_package(mmui);
|
||||
|
||||
bzero(ofw_mapping, sizeof(ofw_mapping));
|
||||
|
||||
N_mapping =
|
||||
OF_getprop(mmu, "translations", ofw_mapping, sizeof(ofw_mapping));
|
||||
N_mapping /= sizeof(ofw_mapping[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
restore_ofw_mapping()
|
||||
{
|
||||
int i;
|
||||
struct vm_page pg;
|
||||
|
||||
pmap_pinit(&ofw_pmap);
|
||||
|
||||
ofw_pmap.pm_sr[KERNEL_SR] = KERNEL_SEGMENT;
|
||||
|
||||
for (i = 0; i < N_mapping; i++) {
|
||||
vm_offset_t pa = ofw_mapping[i].pa;
|
||||
vm_offset_t va = ofw_mapping[i].va;
|
||||
int size = ofw_mapping[i].len;
|
||||
|
||||
if (va < 0x80000000) /* XXX */
|
||||
continue;
|
||||
|
||||
while (size > 0) {
|
||||
pg.phys_addr = pa;
|
||||
pmap_enter(&ofw_pmap, va, &pg, VM_PROT_ALL,
|
||||
VM_PROT_ALL);
|
||||
pa += PAGE_SIZE;
|
||||
va += PAGE_SIZE;
|
||||
size -= PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
bzero(void *buf, size_t len)
|
||||
{
|
||||
@ -775,34 +485,117 @@ bzero(void *buf, size_t len)
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
delay(unsigned n)
|
||||
{
|
||||
u_long tb;
|
||||
|
||||
do {
|
||||
__asm __volatile("mftb %0" : "=r" (tb));
|
||||
} while (n > (int)(tb & 0xffffffff));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef COMPAT_43
|
||||
void
|
||||
osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
{
|
||||
|
||||
/* XXX: To be done */
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
{
|
||||
struct trapframe *tf;
|
||||
struct sigframe *sfp;
|
||||
struct sigacts *psp;
|
||||
struct sigframe sf;
|
||||
struct thread *td;
|
||||
struct proc *p;
|
||||
int oonstack, rndfsize;
|
||||
|
||||
/* XXX: To be done */
|
||||
return;
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
psp = p->p_sigacts;
|
||||
tf = td->td_frame;
|
||||
oonstack = sigonstack(tf->fixreg[1]);
|
||||
|
||||
rndfsize = ((sizeof(sf) + 15) / 16) * 16;
|
||||
|
||||
CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm,
|
||||
catcher, sig);
|
||||
|
||||
/*
|
||||
* Save user context
|
||||
*/
|
||||
memset(&sf, 0, sizeof(sf));
|
||||
sf.sf_uc.uc_sigmask = *mask;
|
||||
sf.sf_uc.uc_stack = p->p_sigstk;
|
||||
sf.sf_uc.uc_stack.ss_flags = (p->p_flag & P_ALTSTACK)
|
||||
? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
|
||||
|
||||
sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
|
||||
memcpy(&sf.sf_uc.uc_mcontext.mc_frame, tf, sizeof(struct trapframe));
|
||||
|
||||
/*
|
||||
* Allocate and validate space for the signal handler context.
|
||||
*/
|
||||
if ((p->p_flag & P_ALTSTACK) != 0 && !oonstack &&
|
||||
SIGISMEMBER(psp->ps_sigonstack, sig)) {
|
||||
sfp = (struct sigframe *)((caddr_t)p->p_sigstk.ss_sp +
|
||||
p->p_sigstk.ss_size - rndfsize);
|
||||
} else {
|
||||
sfp = (struct sigframe *)(tf->fixreg[1] - rndfsize);
|
||||
}
|
||||
PROC_UNLOCK(p);
|
||||
|
||||
/*
|
||||
* Translate the signal if appropriate (Linux emu ?)
|
||||
*/
|
||||
if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
|
||||
sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
|
||||
|
||||
/*
|
||||
* Save the floating-point state, if necessary, then copy it.
|
||||
*/
|
||||
/* XXX */
|
||||
|
||||
/*
|
||||
* Set up the registers to return to sigcode.
|
||||
*
|
||||
* r1/sp - sigframe ptr
|
||||
* lr - sig function, dispatched to by blrl in trampoline
|
||||
* r3 - sig number
|
||||
* r4 - SIGINFO ? &siginfo : exception code
|
||||
* r5 - user context
|
||||
* srr0 - trampoline function addr
|
||||
*/
|
||||
tf->lr = (register_t)catcher;
|
||||
tf->fixreg[1] = (register_t)sfp;
|
||||
tf->fixreg[FIRSTARG] = sig;
|
||||
tf->fixreg[FIRSTARG+2] = (register_t)&sfp->sf_uc;
|
||||
|
||||
PROC_LOCK(p);
|
||||
if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) {
|
||||
/*
|
||||
* Signal handler installed with SA_SIGINFO.
|
||||
*/
|
||||
tf->fixreg[FIRSTARG+1] = (register_t)&sfp->sf_si;
|
||||
|
||||
/*
|
||||
* Fill siginfo structure.
|
||||
*/
|
||||
sf.sf_si.si_signo = sig;
|
||||
sf.sf_si.si_code = code;
|
||||
sf.sf_si.si_addr = (void *)tf->srr0;
|
||||
sf.sf_si.si_pid = p->p_pid;
|
||||
sf.sf_si.si_uid = p->p_ucred->cr_uid;
|
||||
} else {
|
||||
/* Old FreeBSD-style arguments. */
|
||||
tf->fixreg[FIRSTARG+1] = code;
|
||||
}
|
||||
PROC_UNLOCK(p);
|
||||
|
||||
tf->srr0 = (register_t)(PS_STRINGS - *(p->p_sysent->sv_szsigcode));
|
||||
|
||||
/*
|
||||
* copy the frame out to userland.
|
||||
*/
|
||||
if (copyout((caddr_t)&sf, (caddr_t)sfp, sizeof(sf)) != 0) {
|
||||
/*
|
||||
* Process has trashed its stack. Kill it.
|
||||
*/
|
||||
CTR2(KTR_SIG, "sendsig: sigexit td=%p sfp=%p", td, sfp);
|
||||
PROC_LOCK(p);
|
||||
sigexit(td, SIGILL);
|
||||
}
|
||||
|
||||
CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td,
|
||||
tf->srr0, tf->fixreg[1]);
|
||||
|
||||
PROC_LOCK(p);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -820,9 +613,47 @@ osigreturn(struct thread *td, struct osigreturn_args *uap)
|
||||
int
|
||||
sigreturn(struct thread *td, struct sigreturn_args *uap)
|
||||
{
|
||||
struct trapframe *tf;
|
||||
struct proc *p;
|
||||
ucontext_t uc;
|
||||
|
||||
/* XXX: To be done */
|
||||
return(ENOSYS);
|
||||
CTR2(KTR_SIG, "sigreturn: td=%p ucp=%p", td, uap->sigcntxp);
|
||||
|
||||
if (copyin(uap->sigcntxp, &uc, sizeof(uc)) != 0) {
|
||||
CTR1(KTR_SIG, "sigreturn: efault td=%p", td);
|
||||
return (EFAULT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't let the user set privileged MSR bits
|
||||
*/
|
||||
tf = td->td_frame;
|
||||
if ((uc.uc_mcontext.mc_frame.srr1 & PSL_USERSTATIC) !=
|
||||
(tf->srr1 & PSL_USERSTATIC)) {
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore the user-supplied context
|
||||
*/
|
||||
memcpy(tf, &uc.uc_mcontext.mc_frame, sizeof(struct trapframe));
|
||||
|
||||
p = td->td_proc;
|
||||
PROC_LOCK(p);
|
||||
p->p_sigmask = uc.uc_sigmask;
|
||||
SIG_CANTMASK(p->p_sigmask);
|
||||
signotify(p);
|
||||
PROC_UNLOCK(p);
|
||||
|
||||
/*
|
||||
* Restore FP state
|
||||
*/
|
||||
/* XXX */
|
||||
|
||||
CTR3(KTR_SIG, "sigreturn: return td=%p pc=%#x sp=%#x",
|
||||
td, tf->srr0, tf->fixreg[1]);
|
||||
|
||||
return (EJUSTRETURN);
|
||||
}
|
||||
|
||||
void
|
||||
@ -873,6 +704,14 @@ exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
|
||||
* XXX We have to set both regs and retval here due to different
|
||||
* XXX calling convention in trap.c and init_main.c.
|
||||
*/
|
||||
/*
|
||||
* XXX PG: these get overwritten in the syscall return code.
|
||||
* execve() should return EJUSTRETURN, like it does on NetBSD.
|
||||
* Emulate by setting the syscall return value cells. The
|
||||
* registers still have to be set for init's fork trampoline.
|
||||
*/
|
||||
td->td_retval[0] = arginfo.ps_nargvstr;
|
||||
td->td_retval[1] = (register_t)arginfo.ps_argvstr;
|
||||
tf->fixreg[3] = arginfo.ps_nargvstr;
|
||||
tf->fixreg[4] = (register_t)arginfo.ps_argvstr;
|
||||
tf->fixreg[5] = (register_t)arginfo.ps_envstr;
|
||||
@ -953,14 +792,6 @@ ptrace_single_step(struct thread *td)
|
||||
return (ENOSYS);
|
||||
}
|
||||
|
||||
int
|
||||
ptrace_clear_single_step(struct thread *td)
|
||||
{
|
||||
|
||||
/* XXX: coming soon... */
|
||||
return (ENOSYS);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialise a struct pcpu.
|
||||
*/
|
||||
|
@ -88,6 +88,7 @@ static const char rcsid[] =
|
||||
#include <sys/linker.h>
|
||||
#include <sys/cons.h>
|
||||
#include <sys/ucontext.h>
|
||||
#include <sys/sysent.h>
|
||||
#include <net/netisr.h>
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_kern.h>
|
||||
@ -129,6 +130,10 @@ SYSCTL_STRING(_hw, HW_MACHINE, machine, CTLFLAG_RD, machine, 0, "");
|
||||
static char model[128];
|
||||
SYSCTL_STRING(_hw, HW_MODEL, model, CTLFLAG_RD, model, 0, "");
|
||||
|
||||
static int cacheline_size = CACHELINESIZE;
|
||||
SYSCTL_INT(_machdep, CPU_CACHELINE, cacheline_size,
|
||||
CTLFLAG_RD, &cacheline_size, 0, "");
|
||||
|
||||
char bootpath[256];
|
||||
|
||||
#ifdef DDB
|
||||
@ -146,9 +151,7 @@ int restore_ofw_mapping(void);
|
||||
|
||||
void install_extint(void (*)(void));
|
||||
|
||||
#ifdef COMPAT_43
|
||||
void osendsig(sig_t, int, sigset_t *, u_long);
|
||||
#endif
|
||||
int setfault(faultbuf); /* defined in locore.S */
|
||||
|
||||
static int
|
||||
sysctl_hw_physmem(SYSCTL_HANDLER_ARGS)
|
||||
@ -382,12 +385,15 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp)
|
||||
/*
|
||||
* XXX: Initialize the interrupt tables.
|
||||
*/
|
||||
bcopy(&trapcode, (void *)EXC_DECR, (size_t)&trapsize);
|
||||
bcopy(&dsitrap, (void *)EXC_DSI, (size_t)&dsisize);
|
||||
bcopy(&isitrap, (void *)EXC_ISI, (size_t)&isisize);
|
||||
bcopy(&trapcode, (void *)EXC_SC, (size_t)&trapsize);
|
||||
bcopy(&trapcode, (void *)EXC_FPU, (size_t)&trapsize);
|
||||
bcopy(&trapcode, (void *)EXC_EXI, (size_t)&trapsize);
|
||||
bcopy(&trapcode, (void *)EXC_ALI, (size_t)&trapsize);
|
||||
bcopy(&trapcode, (void *)EXC_PGM, (size_t)&trapsize);
|
||||
bcopy(&trapcode, (void *)EXC_FPU, (size_t)&trapsize);
|
||||
bcopy(&trapcode, (void *)EXC_DECR, (size_t)&trapsize);
|
||||
bcopy(&trapcode, (void *)EXC_SC, (size_t)&trapsize);
|
||||
bcopy(&trapcode, (void *)EXC_TRC, (size_t)&trapsize);
|
||||
|
||||
/*
|
||||
* Start initializing proc0 and thread0.
|
||||
@ -411,6 +417,11 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp)
|
||||
|
||||
mutex_init();
|
||||
|
||||
/*
|
||||
* Make sure translation has been enabled
|
||||
*/
|
||||
mtmsr(mfmsr() | PSL_IR|PSL_DR|PSL_ME|PSL_RI);
|
||||
|
||||
/*
|
||||
* Initialise virtual memory.
|
||||
*/
|
||||
@ -437,307 +448,6 @@ powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, void *mdp)
|
||||
msgbufinit(msgbufp, MSGBUF_SIZE);
|
||||
}
|
||||
|
||||
#if 0 /* XXX: Old powerpc_init */
|
||||
void
|
||||
powerpc_init(u_int startkernel, u_int endkernel, u_int basekernel, char *args)
|
||||
{
|
||||
unsigned int exc, scratch;
|
||||
struct mem_region *allmem, *availmem, *mp;
|
||||
struct pcpu *pcpup;
|
||||
|
||||
/*
|
||||
* Set up BAT0 to only map the lowest 256 MB area
|
||||
*/
|
||||
battable[0].batl = BATL(0x00000000, BAT_M, BAT_PP_RW);
|
||||
battable[0].batu = BATU(0x00000000, BAT_BL_256M, BAT_Vs);
|
||||
|
||||
/*
|
||||
* Map PCI memory space.
|
||||
*/
|
||||
battable[0x8].batl = BATL(0x80000000, BAT_I, BAT_PP_RW);
|
||||
battable[0x8].batu = BATU(0x80000000, BAT_BL_256M, BAT_Vs);
|
||||
|
||||
battable[0x9].batl = BATL(0x90000000, BAT_I, BAT_PP_RW);
|
||||
battable[0x9].batu = BATU(0x90000000, BAT_BL_256M, BAT_Vs);
|
||||
|
||||
battable[0xa].batl = BATL(0xa0000000, BAT_I, BAT_PP_RW);
|
||||
battable[0xa].batu = BATU(0xa0000000, BAT_BL_256M, BAT_Vs);
|
||||
|
||||
/*
|
||||
* Map obio devices.
|
||||
*/
|
||||
battable[0xf].batl = BATL(0xf0000000, BAT_I, BAT_PP_RW);
|
||||
battable[0xf].batu = BATU(0xf0000000, BAT_BL_256M, BAT_Vs);
|
||||
|
||||
/*
|
||||
* Now setup fixed bat registers
|
||||
*
|
||||
* Note that we still run in real mode, and the BAT
|
||||
* registers were cleared above.
|
||||
*/
|
||||
/* BAT0 used for initial 256 MB segment */
|
||||
__asm __volatile ("mtibatl 0,%0; mtibatu 0,%1;"
|
||||
"mtdbatl 0,%0; mtdbatu 0,%1;"
|
||||
:: "r"(battable[0].batl), "r"(battable[0].batu));
|
||||
/*
|
||||
* Set up battable to map all RAM regions.
|
||||
* This is here because mem_regions() call needs bat0 set up.
|
||||
*/
|
||||
mem_regions(&allmem, &availmem);
|
||||
|
||||
/* Calculate the physical memory in the machine */
|
||||
for (mp = allmem; mp->size; mp++)
|
||||
physmem += btoc(mp->size);
|
||||
|
||||
for (mp = allmem; mp->size; mp++) {
|
||||
vm_offset_t pa = mp->start & 0xf0000000;
|
||||
vm_offset_t end = mp->start + mp->size;
|
||||
|
||||
do {
|
||||
u_int n = pa >> 28;
|
||||
|
||||
battable[n].batl = BATL(pa, BAT_M, BAT_PP_RW);
|
||||
battable[n].batu = BATU(pa, BAT_BL_256M, BAT_Vs);
|
||||
pa += 0x10000000;
|
||||
} while (pa < end);
|
||||
}
|
||||
|
||||
chosen = OF_finddevice("/chosen");
|
||||
save_ofw_mapping();
|
||||
|
||||
pmap_setavailmem(startkernel, endkernel);
|
||||
|
||||
proc_linkup(&proc0, &ksegrp0, &kse0, &thread0);
|
||||
|
||||
proc0uarea = (struct user *)pmap_steal_memory(UAREA_PAGES * PAGE_SIZE);
|
||||
proc0kstack = pmap_steal_memory(KSTACK_PAGES * PAGE_SIZE);
|
||||
proc0.p_uarea = proc0uarea;
|
||||
thread0.td_kstack = proc0kstack;
|
||||
thread0.td_pcb = (struct pcb *)
|
||||
(thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
|
||||
|
||||
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.
|
||||
*/
|
||||
pcpu_init(pcpup, 0, sizeof(struct pcpu));
|
||||
__asm ("mtsprg 0, %0" :: "r"(pcpup));
|
||||
|
||||
/* Init basic tunables, hz etc */
|
||||
init_param1();
|
||||
init_param2(physmem);
|
||||
|
||||
PCPU_SET(curthread, &thread0);
|
||||
|
||||
/* XXX: NetBSDism I _think_. Not sure yet. */
|
||||
#if 0
|
||||
curpm = PCPU_GET(curpcb)->pcb_pmreal = PCPU_GET(curpcb)->pcb_pm = kernel_pmap;
|
||||
#endif
|
||||
|
||||
mutex_init();
|
||||
|
||||
/*
|
||||
* Initialise console.
|
||||
*/
|
||||
cninit();
|
||||
|
||||
#ifdef __notyet__ /* Needs some rethinking regarding real/virtual OFW */
|
||||
OF_set_callback(callback);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set up trap vectors
|
||||
*/
|
||||
for (exc = EXC_RSVD; exc <= EXC_LAST; exc += 0x100) {
|
||||
switch (exc) {
|
||||
default:
|
||||
bcopy(&trapcode, (void *)exc, (size_t)&trapsize);
|
||||
break;
|
||||
case EXC_DECR:
|
||||
bcopy(&decrint, (void *)EXC_DECR, (size_t)&decrsize);
|
||||
break;
|
||||
#if 0 /* XXX: Not enabling these traps yet. */
|
||||
case EXC_EXI:
|
||||
/*
|
||||
* This one is (potentially) installed during autoconf
|
||||
*/
|
||||
break;
|
||||
case EXC_ALI:
|
||||
bcopy(&alitrap, (void *)EXC_ALI, (size_t)&alisize);
|
||||
break;
|
||||
case EXC_DSI:
|
||||
bcopy(&dsitrap, (void *)EXC_DSI, (size_t)&dsisize);
|
||||
break;
|
||||
case EXC_ISI:
|
||||
bcopy(&isitrap, (void *)EXC_ISI, (size_t)&isisize);
|
||||
break;
|
||||
case EXC_IMISS:
|
||||
bcopy(&tlbimiss, (void *)EXC_IMISS, (size_t)&tlbimsize);
|
||||
break;
|
||||
case EXC_DLMISS:
|
||||
bcopy(&tlbdlmiss, (void *)EXC_DLMISS, (size_t)&tlbdlmsize);
|
||||
break;
|
||||
case EXC_DSMISS:
|
||||
bcopy(&tlbdsmiss, (void *)EXC_DSMISS, (size_t)&tlbdsmsize);
|
||||
break;
|
||||
#if defined(DDB) || defined(IPKDB)
|
||||
case EXC_TRC:
|
||||
case EXC_PGM:
|
||||
case EXC_BPT:
|
||||
#if defined(DDB)
|
||||
bcopy(&ddblow, (void *)exc, (size_t)&ddbsize);
|
||||
#else
|
||||
bcopy(&ipkdblow, (void *)exc, (size_t)&ipkdbsize);
|
||||
#endif
|
||||
break;
|
||||
#endif /* DDB || IPKDB */
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if 0 /* XXX: coming soon... */
|
||||
/*
|
||||
* external interrupt handler install
|
||||
*/
|
||||
install_extint(ext_intr);
|
||||
#endif
|
||||
|
||||
__syncicache((void *)EXC_RST, EXC_LAST - EXC_RST + 0x100);
|
||||
|
||||
/*
|
||||
* Now enable translation (and machine checks/recoverable interrupts).
|
||||
*/
|
||||
__asm ("mfmsr %0" : "=r"(scratch));
|
||||
scratch |= PSL_IR | PSL_DR | PSL_ME | PSL_RI;
|
||||
__asm ("mtmsr %0" :: "r"(scratch));
|
||||
|
||||
ofmsr &= ~PSL_IP;
|
||||
|
||||
/*
|
||||
* Parse arg string.
|
||||
*/
|
||||
#ifdef DDB
|
||||
bcopy(args + strlen(args) + 1, &startsym, sizeof(startsym));
|
||||
bcopy(args + strlen(args) + 5, &endsym, sizeof(endsym));
|
||||
if (startsym == NULL || endsym == NULL)
|
||||
startsym = endsym = NULL;
|
||||
#endif
|
||||
|
||||
strcpy(bootpath, args);
|
||||
args = bootpath;
|
||||
while (*++args && *args != ' ');
|
||||
if (*args) {
|
||||
*args++ = 0;
|
||||
while (*args) {
|
||||
switch (*args++) {
|
||||
case 'a':
|
||||
boothowto |= RB_ASKNAME;
|
||||
break;
|
||||
case 's':
|
||||
boothowto |= RB_SINGLE;
|
||||
break;
|
||||
case 'd':
|
||||
boothowto |= RB_KDB;
|
||||
break;
|
||||
case 'v':
|
||||
boothowto |= RB_VERBOSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DDB
|
||||
ddb_init((int)((u_int)endsym - (u_int)startsym), startsym, endsym);
|
||||
#endif
|
||||
#ifdef IPKDB
|
||||
/*
|
||||
* Now trap to IPKDB
|
||||
*/
|
||||
ipkdb_init();
|
||||
if (boothowto & RB_KDB)
|
||||
ipkdb_connect(0);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Set the page size.
|
||||
*/
|
||||
#if 0
|
||||
vm_set_page_size();
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Initialize pmap module.
|
||||
*/
|
||||
pmap_bootstrap();
|
||||
|
||||
restore_ofw_mapping();
|
||||
|
||||
PCPU_GET(next_asn) = 1; /* 0 used for proc0 pmap */
|
||||
|
||||
/* setup proc 0's pcb */
|
||||
thread0.td_pcb->pcb_flags = 0; /* XXXKSE */
|
||||
thread0.td_frame = &proc0_tf;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int N_mapping;
|
||||
static struct {
|
||||
vm_offset_t va;
|
||||
int len;
|
||||
vm_offset_t pa;
|
||||
int mode;
|
||||
} ofw_mapping[256];
|
||||
|
||||
int
|
||||
save_ofw_mapping()
|
||||
{
|
||||
int mmui, mmu;
|
||||
|
||||
OF_getprop(chosen, "mmu", &mmui, 4);
|
||||
mmu = OF_instance_to_package(mmui);
|
||||
|
||||
bzero(ofw_mapping, sizeof(ofw_mapping));
|
||||
|
||||
N_mapping =
|
||||
OF_getprop(mmu, "translations", ofw_mapping, sizeof(ofw_mapping));
|
||||
N_mapping /= sizeof(ofw_mapping[0]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
restore_ofw_mapping()
|
||||
{
|
||||
int i;
|
||||
struct vm_page pg;
|
||||
|
||||
pmap_pinit(&ofw_pmap);
|
||||
|
||||
ofw_pmap.pm_sr[KERNEL_SR] = KERNEL_SEGMENT;
|
||||
|
||||
for (i = 0; i < N_mapping; i++) {
|
||||
vm_offset_t pa = ofw_mapping[i].pa;
|
||||
vm_offset_t va = ofw_mapping[i].va;
|
||||
int size = ofw_mapping[i].len;
|
||||
|
||||
if (va < 0x80000000) /* XXX */
|
||||
continue;
|
||||
|
||||
while (size > 0) {
|
||||
pg.phys_addr = pa;
|
||||
pmap_enter(&ofw_pmap, va, &pg, VM_PROT_ALL,
|
||||
VM_PROT_ALL);
|
||||
pa += PAGE_SIZE;
|
||||
va += PAGE_SIZE;
|
||||
size -= PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
bzero(void *buf, size_t len)
|
||||
{
|
||||
@ -775,34 +485,117 @@ bzero(void *buf, size_t len)
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
void
|
||||
delay(unsigned n)
|
||||
{
|
||||
u_long tb;
|
||||
|
||||
do {
|
||||
__asm __volatile("mftb %0" : "=r" (tb));
|
||||
} while (n > (int)(tb & 0xffffffff));
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef COMPAT_43
|
||||
void
|
||||
osendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
{
|
||||
|
||||
/* XXX: To be done */
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
|
||||
{
|
||||
struct trapframe *tf;
|
||||
struct sigframe *sfp;
|
||||
struct sigacts *psp;
|
||||
struct sigframe sf;
|
||||
struct thread *td;
|
||||
struct proc *p;
|
||||
int oonstack, rndfsize;
|
||||
|
||||
/* XXX: To be done */
|
||||
return;
|
||||
td = curthread;
|
||||
p = td->td_proc;
|
||||
psp = p->p_sigacts;
|
||||
tf = td->td_frame;
|
||||
oonstack = sigonstack(tf->fixreg[1]);
|
||||
|
||||
rndfsize = ((sizeof(sf) + 15) / 16) * 16;
|
||||
|
||||
CTR4(KTR_SIG, "sendsig: td=%p (%s) catcher=%p sig=%d", td, p->p_comm,
|
||||
catcher, sig);
|
||||
|
||||
/*
|
||||
* Save user context
|
||||
*/
|
||||
memset(&sf, 0, sizeof(sf));
|
||||
sf.sf_uc.uc_sigmask = *mask;
|
||||
sf.sf_uc.uc_stack = p->p_sigstk;
|
||||
sf.sf_uc.uc_stack.ss_flags = (p->p_flag & P_ALTSTACK)
|
||||
? ((oonstack) ? SS_ONSTACK : 0) : SS_DISABLE;
|
||||
|
||||
sf.sf_uc.uc_mcontext.mc_onstack = (oonstack) ? 1 : 0;
|
||||
memcpy(&sf.sf_uc.uc_mcontext.mc_frame, tf, sizeof(struct trapframe));
|
||||
|
||||
/*
|
||||
* Allocate and validate space for the signal handler context.
|
||||
*/
|
||||
if ((p->p_flag & P_ALTSTACK) != 0 && !oonstack &&
|
||||
SIGISMEMBER(psp->ps_sigonstack, sig)) {
|
||||
sfp = (struct sigframe *)((caddr_t)p->p_sigstk.ss_sp +
|
||||
p->p_sigstk.ss_size - rndfsize);
|
||||
} else {
|
||||
sfp = (struct sigframe *)(tf->fixreg[1] - rndfsize);
|
||||
}
|
||||
PROC_UNLOCK(p);
|
||||
|
||||
/*
|
||||
* Translate the signal if appropriate (Linux emu ?)
|
||||
*/
|
||||
if (p->p_sysent->sv_sigtbl && sig <= p->p_sysent->sv_sigsize)
|
||||
sig = p->p_sysent->sv_sigtbl[_SIG_IDX(sig)];
|
||||
|
||||
/*
|
||||
* Save the floating-point state, if necessary, then copy it.
|
||||
*/
|
||||
/* XXX */
|
||||
|
||||
/*
|
||||
* Set up the registers to return to sigcode.
|
||||
*
|
||||
* r1/sp - sigframe ptr
|
||||
* lr - sig function, dispatched to by blrl in trampoline
|
||||
* r3 - sig number
|
||||
* r4 - SIGINFO ? &siginfo : exception code
|
||||
* r5 - user context
|
||||
* srr0 - trampoline function addr
|
||||
*/
|
||||
tf->lr = (register_t)catcher;
|
||||
tf->fixreg[1] = (register_t)sfp;
|
||||
tf->fixreg[FIRSTARG] = sig;
|
||||
tf->fixreg[FIRSTARG+2] = (register_t)&sfp->sf_uc;
|
||||
|
||||
PROC_LOCK(p);
|
||||
if (SIGISMEMBER(p->p_sigacts->ps_siginfo, sig)) {
|
||||
/*
|
||||
* Signal handler installed with SA_SIGINFO.
|
||||
*/
|
||||
tf->fixreg[FIRSTARG+1] = (register_t)&sfp->sf_si;
|
||||
|
||||
/*
|
||||
* Fill siginfo structure.
|
||||
*/
|
||||
sf.sf_si.si_signo = sig;
|
||||
sf.sf_si.si_code = code;
|
||||
sf.sf_si.si_addr = (void *)tf->srr0;
|
||||
sf.sf_si.si_pid = p->p_pid;
|
||||
sf.sf_si.si_uid = p->p_ucred->cr_uid;
|
||||
} else {
|
||||
/* Old FreeBSD-style arguments. */
|
||||
tf->fixreg[FIRSTARG+1] = code;
|
||||
}
|
||||
PROC_UNLOCK(p);
|
||||
|
||||
tf->srr0 = (register_t)(PS_STRINGS - *(p->p_sysent->sv_szsigcode));
|
||||
|
||||
/*
|
||||
* copy the frame out to userland.
|
||||
*/
|
||||
if (copyout((caddr_t)&sf, (caddr_t)sfp, sizeof(sf)) != 0) {
|
||||
/*
|
||||
* Process has trashed its stack. Kill it.
|
||||
*/
|
||||
CTR2(KTR_SIG, "sendsig: sigexit td=%p sfp=%p", td, sfp);
|
||||
PROC_LOCK(p);
|
||||
sigexit(td, SIGILL);
|
||||
}
|
||||
|
||||
CTR3(KTR_SIG, "sendsig: return td=%p pc=%#x sp=%#x", td,
|
||||
tf->srr0, tf->fixreg[1]);
|
||||
|
||||
PROC_LOCK(p);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -820,9 +613,47 @@ osigreturn(struct thread *td, struct osigreturn_args *uap)
|
||||
int
|
||||
sigreturn(struct thread *td, struct sigreturn_args *uap)
|
||||
{
|
||||
struct trapframe *tf;
|
||||
struct proc *p;
|
||||
ucontext_t uc;
|
||||
|
||||
/* XXX: To be done */
|
||||
return(ENOSYS);
|
||||
CTR2(KTR_SIG, "sigreturn: td=%p ucp=%p", td, uap->sigcntxp);
|
||||
|
||||
if (copyin(uap->sigcntxp, &uc, sizeof(uc)) != 0) {
|
||||
CTR1(KTR_SIG, "sigreturn: efault td=%p", td);
|
||||
return (EFAULT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Don't let the user set privileged MSR bits
|
||||
*/
|
||||
tf = td->td_frame;
|
||||
if ((uc.uc_mcontext.mc_frame.srr1 & PSL_USERSTATIC) !=
|
||||
(tf->srr1 & PSL_USERSTATIC)) {
|
||||
return (EINVAL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Restore the user-supplied context
|
||||
*/
|
||||
memcpy(tf, &uc.uc_mcontext.mc_frame, sizeof(struct trapframe));
|
||||
|
||||
p = td->td_proc;
|
||||
PROC_LOCK(p);
|
||||
p->p_sigmask = uc.uc_sigmask;
|
||||
SIG_CANTMASK(p->p_sigmask);
|
||||
signotify(p);
|
||||
PROC_UNLOCK(p);
|
||||
|
||||
/*
|
||||
* Restore FP state
|
||||
*/
|
||||
/* XXX */
|
||||
|
||||
CTR3(KTR_SIG, "sigreturn: return td=%p pc=%#x sp=%#x",
|
||||
td, tf->srr0, tf->fixreg[1]);
|
||||
|
||||
return (EJUSTRETURN);
|
||||
}
|
||||
|
||||
void
|
||||
@ -873,6 +704,14 @@ exec_setregs(struct thread *td, u_long entry, u_long stack, u_long ps_strings)
|
||||
* XXX We have to set both regs and retval here due to different
|
||||
* XXX calling convention in trap.c and init_main.c.
|
||||
*/
|
||||
/*
|
||||
* XXX PG: these get overwritten in the syscall return code.
|
||||
* execve() should return EJUSTRETURN, like it does on NetBSD.
|
||||
* Emulate by setting the syscall return value cells. The
|
||||
* registers still have to be set for init's fork trampoline.
|
||||
*/
|
||||
td->td_retval[0] = arginfo.ps_nargvstr;
|
||||
td->td_retval[1] = (register_t)arginfo.ps_argvstr;
|
||||
tf->fixreg[3] = arginfo.ps_nargvstr;
|
||||
tf->fixreg[4] = (register_t)arginfo.ps_argvstr;
|
||||
tf->fixreg[5] = (register_t)arginfo.ps_envstr;
|
||||
@ -953,14 +792,6 @@ ptrace_single_step(struct thread *td)
|
||||
return (ENOSYS);
|
||||
}
|
||||
|
||||
int
|
||||
ptrace_clear_single_step(struct thread *td)
|
||||
{
|
||||
|
||||
/* XXX: coming soon... */
|
||||
return (ENOSYS);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialise a struct pcpu.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user