Date: Wed, 30 Apr 2003 16:07:16 -0700 (PDT) From: Marcel Moolenaar <marcel@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 30177 for review Message-ID: <200304302307.h3UN7GDp045393@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=30177 Change 30177 by marcel@marcel_nfs on 2003/04/30 16:06:14 Hook up ia32 support again: o Move option IA32 to opt_global.h so that we can use conditional compilation more safely, such as in pcb.h o Add functions ia32_restorectx() and ia32_savectx() and call them from cpu_throw() and cpu_switch(). This mimics the current implementation by treating the ia32 registers as preserved resources. We should have enough unused "slots" in the trapframe to treat them as scratch resources eventually. The free "slots" are those fields that relate to the RSE (bsp, ndirty, pfs, cfm and rnat) and NaTs (unat). DOing the ia32 context switch in cpu_switch() is the least difficult approach for now. Note that ar.csd and ar.ssd are part of the ia64 runtime now and consequently are saved and restored in the trapframe already (they are defined as scratch). o Support for exec'ing an ia32 binary by using the EPC syscall is not added. Focus is on getting the break based syscall to work first, which at this point is getting things hooked up again and see where it fails. Affected files ... .. //depot/projects/ia64_epc/sys/conf/options.ia64#3 edit .. //depot/projects/ia64_epc/sys/ia64/ia32/ia32_sysvec.c#2 edit .. //depot/projects/ia64_epc/sys/ia64/ia64/genassym.c#8 edit .. //depot/projects/ia64_epc/sys/ia64/ia64/machdep.c#19 edit .. //depot/projects/ia64_epc/sys/ia64/include/pcb.h#8 edit Differences ... ==== //depot/projects/ia64_epc/sys/conf/options.ia64#3 (text+ko) ==== @@ -4,7 +4,7 @@ ITANIUM opt_global.h ITANIUM2 opt_global.h -IA32 +IA32 opt_global.h PAGE_SIZE_4K opt_global.h PAGE_SIZE_8K opt_global.h ==== //depot/projects/ia64_epc/sys/ia64/ia32/ia32_sysvec.c#2 (text+ko) ==== @@ -244,44 +244,19 @@ struct segment_descriptor desc; struct vmspace *vmspace = td->td_proc->p_vmspace; - /* - * Make sure that we restore the entire trapframe after an - * execve. - */ - frame->tf_flags &= ~FRAME_SYSCALL; + exec_setregs(td, entry, stack, ps_strings); - bzero(frame->tf_r, sizeof(frame->tf_r)); - bzero(frame->tf_f, sizeof(frame->tf_f)); - - frame->tf_cr_iip = entry; - frame->tf_cr_ipsr = (IA64_PSR_IC - | IA64_PSR_I - | IA64_PSR_IT - | IA64_PSR_DT - | IA64_PSR_RT - | IA64_PSR_DFH - | IA64_PSR_IS - | IA64_PSR_BN - | IA64_PSR_CPL_USER); - frame->tf_r[FRAME_R12] = stack; + /* Mark this process as using the ia32 instruction set. */ + frame->tf_special.psr |= IA64_PSR_IS; codesel = LSEL(LUCODE_SEL, SEL_UPL); datasel = LSEL(LUDATA_SEL, SEL_UPL); ldtsel = GSEL(GLDT_SEL, SEL_UPL); -#if 1 - frame->tf_r[FRAME_R16] = (datasel << 48) | (datasel << 32) - | (datasel << 16) | datasel; - frame->tf_r[FRAME_R17] = (ldtsel << 32) | (datasel << 16) | codesel; -#else - frame->tf_r[FRAME_R16] = datasel; - frame->tf_r[FRAME_R17] = codesel; - frame->tf_r[FRAME_R18] = datasel; - frame->tf_r[FRAME_R19] = datasel; - frame->tf_r[FRAME_R20] = datasel; - frame->tf_r[FRAME_R21] = datasel; - frame->tf_r[FRAME_R22] = ldtsel; -#endif + /* Setup ia32 segment registers. */ + frame->tf_scratch.gr16 = (datasel << 48) | (datasel << 32) | + (datasel << 16) | datasel; + frame->tf_scratch.gr17 = (ldtsel << 32) | (datasel << 16) | codesel; /* * Build the GDT and LDT. @@ -330,12 +305,13 @@ + (1L << 59) /* present */ + (1L << 62) /* 32 bits */ + (1L << 63); /* page granularity */ - ia64_set_csd(codeseg); - ia64_set_ssd(dataseg); - frame->tf_r[FRAME_R24] = dataseg; /* ESD */ - frame->tf_r[FRAME_R27] = dataseg; /* DSD */ - frame->tf_r[FRAME_R28] = dataseg; /* FSD */ - frame->tf_r[FRAME_R29] = dataseg; /* GSD */ + + frame->tf_scratch.csd = codeseg; + frame->tf_scratch.ssd = dataseg; + frame->tf_scratch.gr24 = dataseg; /* ESD */ + frame->tf_scratch.gr27 = dataseg; /* DSD */ + frame->tf_scratch.gr28 = dataseg; /* FSD */ + frame->tf_scratch.gr29 = dataseg; /* GSD */ gdtseg = gdt /* base */ + ((8L*NGDT - 1) << 32) /* limit */ @@ -351,13 +327,16 @@ + (1L << 59) /* present */ + (0L << 62) /* 16 bits */ + (0L << 63); /* byte granularity */ - frame->tf_r[FRAME_R30] = ldtseg; /* LDTD */ - frame->tf_r[FRAME_R31] = gdtseg; /* GDTD */ + + frame->tf_scratch.gr30 = ldtseg; /* LDTD */ + frame->tf_scratch.gr31 = gdtseg; /* GDTD */ +#if 0 ia64_set_eflag(PSL_USER); +#endif /* PS_STRINGS value for BSD/OS binaries. It is 0 for non-BSD/OS. */ - frame->tf_r[FRAME_R11] = IA32_PS_STRINGS; + frame->tf_scratch.gr11 = IA32_PS_STRINGS; /* * XXX - Linux emulator @@ -366,3 +345,27 @@ */ td->td_retval[1] = 0; } + +void +ia32_restorectx(struct pcb *pcb) +{ + + ia64_set_cflg(pcb->pcb_ia32_cflg); + ia64_set_eflag(pcb->pcb_ia32_eflag); + ia64_set_fcr(pcb->pcb_ia32_fcr); + ia64_set_fdr(pcb->pcb_ia32_fdr); + ia64_set_fir(pcb->pcb_ia32_fir); + ia64_set_fsr(pcb->pcb_ia32_fsr); +} + +void +ia32_savectx(struct pcb *pcb) +{ + + pcb->pcb_ia32_cflg = ia64_get_cflg(); + pcb->pcb_ia32_eflag = ia64_get_eflag(); + pcb->pcb_ia32_fcr = ia64_get_fcr(); + pcb->pcb_ia32_fdr = ia64_get_fdr(); + pcb->pcb_ia32_fir = ia64_get_fir(); + pcb->pcb_ia32_fsr = ia64_get_fsr(); +} ==== //depot/projects/ia64_epc/sys/ia64/ia64/genassym.c#8 (text+ko) ==== @@ -37,8 +37,6 @@ * $FreeBSD: src/sys/ia64/ia64/genassym.c,v 1.33 2003/02/17 09:55:09 julian Exp $ */ -#include "opt_ia32.h" - #include <sys/param.h> #include <sys/systm.h> #include <sys/assym.h> @@ -78,10 +76,6 @@ ASSYM(FRAME_SYSCALL, FRAME_SYSCALL); -#ifdef IA32 -ASSYM(IA32, IA32); -#endif - ASSYM(KSTACK_PAGES, KSTACK_PAGES); ASSYM(MC_PRESERVED, offsetof(mcontext_t, mc_preserved)); ==== //depot/projects/ia64_epc/sys/ia64/ia64/machdep.c#19 (text+ko) ==== @@ -219,10 +219,16 @@ oldpcb = old->td_pcb; oldpcb->pcb_current_pmap = PCPU_GET(current_pmap); +#if IA32 + ia32_savectx(oldpcb); +#endif if (!savectx(oldpcb)) { newpcb = new->td_pcb; pmap_install(newpcb->pcb_current_pmap); PCPU_SET(curthread, new); +#if IA32 + ia32_restorectx(newpcb); +#endif restorectx(newpcb); } } @@ -235,6 +241,9 @@ newpcb = new->td_pcb; pmap_install(newpcb->pcb_current_pmap); PCPU_SET(curthread, new); +#if IA32 + ia32_restorectx(newpcb); +#endif restorectx(newpcb); /* We should not get here. */ panic("cpu_throw: restorectx() returned"); ==== //depot/projects/ia64_epc/sys/ia64/include/pcb.h#8 (text+ko) ==== @@ -46,13 +46,29 @@ uint64_t pcb_onfault; /* for copy faults */ uint64_t pcb_accessaddr; /* for [fs]uswintr */ + +#if IA32 + uint64_t pcb_ia32_cflg; + uint64_t pcb_ia32_eflag; + uint64_t pcb_ia32_fcr; + uint64_t pcb_ia32_fdr; + uint64_t pcb_ia32_fir; + uint64_t pcb_ia32_fsr; +#endif }; #ifdef _KERNEL + #define savectx savectx__ void restorectx(struct pcb *) __dead2; int savectx(struct pcb *); void swapctx(struct pcb *old, struct pcb *new); + +#if IA32 +void ia32_restorectx(struct pcb *); +void ia32_savectx(struct pcb *); +#endif + #endif #endif /* _MACHINE_PCB_H_ */
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200304302307.h3UN7GDp045393>