コード例 #1
0
ファイル: ia32_signal.c プロジェクト: BillTheBest/libuinet
static void
ia32_get_fpcontext(struct thread *td, struct ia32_mcontext *mcp,
    char *xfpusave, size_t xfpusave_len)
{
	size_t max_len, len;

	/*
	 * XXX Format of 64bit and 32bit FXSAVE areas differs. FXSAVE
	 * in 32bit mode saves %cs and %ds, while on 64bit it saves
	 * 64bit instruction and data pointers. Ignore the difference
	 * for now, it should be irrelevant for most applications.
	 */
	mcp->mc_ownedfp = fpugetregs(td);
	bcopy(get_pcb_user_save_td(td), &mcp->mc_fpstate,
	    sizeof(mcp->mc_fpstate));
	mcp->mc_fpformat = fpuformat();
	if (!use_xsave || xfpusave_len == 0)
		return;
	max_len = cpu_max_ext_state_size - sizeof(struct savefpu);
	len = xfpusave_len;
	if (len > max_len) {
		len = max_len;
		bzero(xfpusave + max_len, len - max_len);
	}
	mcp->mc_flags |= _MC_HASFPXSTATE;
	mcp->mc_xfpustate_len = len;
	bcopy(get_pcb_user_save_td(td) + 1, xfpusave, len);
}
コード例 #2
0
ファイル: ia32_signal.c プロジェクト: ppaeps/freebsd-head
static void
ia32_get_fpcontext(struct thread *td, struct ia32_mcontext *mcp)
{

	/*
	 * XXX Format of 64bit and 32bit FXSAVE areas differs. FXSAVE
	 * in 32bit mode saves %cs and %ds, while on 64bit it saves
	 * 64bit instruction and data pointers. Ignore the difference
	 * for now, it should be irrelevant for most applications.
	 */
	mcp->mc_ownedfp = fpugetregs(td);
	bcopy(&td->td_pcb->pcb_user_save, &mcp->mc_fpstate,
	    sizeof(mcp->mc_fpstate));
	mcp->mc_fpformat = fpuformat();
}
コード例 #3
0
ファイル: ia32_sysvec.c プロジェクト: jaredmcneill/freebsd
void
elf32_dump_thread(struct thread *td, void *dst, size_t *off)
{
	void *buf;
	size_t len;

	len = 0;
	if (use_xsave) {
		if (dst != NULL) {
			fpugetregs(td);
			len += elf32_populate_note(NT_X86_XSTATE,
			    get_pcb_user_save_td(td), dst,
			    cpu_max_ext_state_size, &buf);
			*(uint64_t *)((char *)buf + X86_XSTATE_XCR0_OFFSET) =
			    xsave_mask;
		} else
			len += elf32_populate_note(NT_X86_XSTATE, NULL, NULL,
			    cpu_max_ext_state_size, NULL);
	}
	*off = len;
}
コード例 #4
0
ファイル: ia32_reg.c プロジェクト: ele7enxxh/dtrace-pf
int
fill_fpregs32(struct thread *td, struct fpreg32 *regs)
{
	struct savefpu *sv_fpu;
	struct save87 *sv_87;
	struct env87 *penv_87;
	struct envxmm *penv_xmm;
	int i;

	bzero(regs, sizeof(*regs));
	sv_87 = (struct save87 *)regs;
	penv_87 = &sv_87->sv_env;
	fpugetregs(td);
	sv_fpu = get_pcb_user_save_td(td);
	penv_xmm = &sv_fpu->sv_env;
	
	/* FPU control/status */
	penv_87->en_cw = penv_xmm->en_cw;
	penv_87->en_sw = penv_xmm->en_sw;
	penv_87->en_tw = penv_xmm->en_tw;
	/*
	 * XXX for en_fip/fcs/foo/fos, check if the fxsave format
	 * uses the old-style layout for 32 bit user apps.  If so,
	 * read the ip and operand segment registers from there.
	 * For now, use the process's %cs/%ds.
	 */
	penv_87->en_fip = penv_xmm->en_rip;
	penv_87->en_fcs = td->td_frame->tf_cs;
	penv_87->en_opcode = penv_xmm->en_opcode;
	penv_87->en_foo = penv_xmm->en_rdp;
	/* Entry into the kernel always sets TF_HASSEGS */
	penv_87->en_fos = td->td_frame->tf_ds;

	/* FPU registers */
	for (i = 0; i < 8; ++i)
		sv_87->sv_ac[i] = sv_fpu->sv_fp[i].fp_acc;

	return (0);
}
コード例 #5
0
int
acpi_sleep_machdep(struct acpi_softc *sc, int state)
{
	struct savefpu	*stopfpu;
#ifdef SMP
	cpumask_t	wakeup_cpus;
#endif
	register_t	cr3, rf;
	ACPI_STATUS	status;
	int		ret;

	ret = -1;

	if (sc->acpi_wakeaddr == 0ul)
		return (ret);

#ifdef SMP
	wakeup_cpus = PCPU_GET(other_cpus);
#endif

	AcpiSetFirmwareWakingVector(WAKECODE_PADDR(sc));

	rf = intr_disable();
	intr_suspend();

	/*
	 * Temporarily switch to the kernel pmap because it provides
	 * an identity mapping (setup at boot) for the low physical
	 * memory region containing the wakeup code.
	 */
	cr3 = rcr3();
	load_cr3(KPML4phys);

	stopfpu = &stopxpcbs[0].xpcb_pcb.pcb_save;
	if (acpi_savecpu(&stopxpcbs[0])) {
		fpugetregs(curthread, stopfpu);

#ifdef SMP
		if (wakeup_cpus != 0 && suspend_cpus(wakeup_cpus) == 0) {
			device_printf(sc->acpi_dev,
			    "Failed to suspend APs: CPU mask = 0x%jx\n",
			    (uintmax_t)(wakeup_cpus & ~stopped_cpus));
			goto out;
		}
#endif

		WAKECODE_FIXUP(resume_beep, uint8_t, (acpi_resume_beep != 0));
		WAKECODE_FIXUP(reset_video, uint8_t, (acpi_reset_video != 0));

		WAKECODE_FIXUP(wakeup_xpcb, struct xpcb *, &stopxpcbs[0]);
		WAKECODE_FIXUP(wakeup_gdt, uint16_t,
		    stopxpcbs[0].xpcb_gdt.rd_limit);
		WAKECODE_FIXUP(wakeup_gdt + 2, uint64_t,
		    stopxpcbs[0].xpcb_gdt.rd_base);
		WAKECODE_FIXUP(wakeup_cpu, int, 0);

		/* Call ACPICA to enter the desired sleep state */
		if (state == ACPI_STATE_S4 && sc->acpi_s4bios)
			status = AcpiEnterSleepStateS4bios();
		else
			status = AcpiEnterSleepState(state);

		if (status != AE_OK) {
			device_printf(sc->acpi_dev,
			    "AcpiEnterSleepState failed - %s\n",
			    AcpiFormatException(status));
			goto out;
		}

		for (;;)
			ia32_pause();
	} else {