Skip site navigation (1)Skip section navigation (2)
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>