pcb.h revision 236772
1200580Sluigi/*-
2200654Sluigi * Copyright (c) 2003 Peter Wemm.
3200580Sluigi * Copyright (c) 1990 The Regents of the University of California.
4200580Sluigi * All rights reserved.
5200580Sluigi *
6200580Sluigi * This code is derived from software contributed to Berkeley by
7200580Sluigi * William Jolitz.
8200580Sluigi *
9200580Sluigi * Redistribution and use in source and binary forms, with or without
10200580Sluigi * modification, are permitted provided that the following conditions
11200580Sluigi * are met:
12200580Sluigi * 1. Redistributions of source code must retain the above copyright
13200580Sluigi *    notice, this list of conditions and the following disclaimer.
14200580Sluigi * 2. Redistributions in binary form must reproduce the above copyright
15200580Sluigi *    notice, this list of conditions and the following disclaimer in the
16200580Sluigi *    documentation and/or other materials provided with the distribution.
17200580Sluigi * 4. Neither the name of the University nor the names of its contributors
18200580Sluigi *    may be used to endorse or promote products derived from this software
19200580Sluigi *    without specific prior written permission.
20200580Sluigi *
21200580Sluigi * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22200580Sluigi * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23200580Sluigi * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24200580Sluigi * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25200580Sluigi * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26200580Sluigi * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27200580Sluigi * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28200580Sluigi * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29200580Sluigi * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30200580Sluigi * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31200580Sluigi * SUCH DAMAGE.
32200580Sluigi *
33225518Sjhb *	from: @(#)pcb.h	5.10 (Berkeley) 5/12/91
34200580Sluigi * $FreeBSD: head/sys/amd64/include/pcb.h 236772 2012-06-09 00:37:26Z iwasaki $
35200580Sluigi */
36200580Sluigi
37200580Sluigi#ifndef _AMD64_PCB_H_
38200580Sluigi#define _AMD64_PCB_H_
39200580Sluigi
40200580Sluigi/*
41200580Sluigi * AMD64 process control block
42295126Sglebius */
43295126Sglebius#include <machine/fpu.h>
44200580Sluigi#include <machine/segments.h>
45200580Sluigi
46200580Sluigistruct pcb {
47200580Sluigi	register_t	pcb_r15;
48238277Shrs	register_t	pcb_r14;
49238277Shrs	register_t	pcb_r13;
50200580Sluigi	register_t	pcb_r12;
51200580Sluigi	register_t	pcb_rbp;
52257176Sglebius	register_t	pcb_rsp;
53238277Shrs	register_t	pcb_rbx;
54200580Sluigi	register_t	pcb_rip;
55239997Seadler	register_t	pcb_fsbase;
56200654Sluigi	register_t	pcb_gsbase;
57200580Sluigi	register_t	pcb_kgsbase;
58200580Sluigi	register_t	pcb_cr0;
59200580Sluigi	register_t	pcb_cr2;
60200580Sluigi	register_t	pcb_cr3;
61201732Sluigi	register_t	pcb_cr4;
62200580Sluigi	register_t	pcb_dr0;
63200580Sluigi	register_t	pcb_dr1;
64200580Sluigi	register_t	pcb_dr2;
65200580Sluigi	register_t	pcb_dr3;
66200580Sluigi	register_t	pcb_dr6;
67200580Sluigi	register_t	pcb_dr7;
68200580Sluigi
69200580Sluigi	struct region_descriptor pcb_gdt;
70200580Sluigi	struct region_descriptor pcb_idt;
71200580Sluigi	struct region_descriptor pcb_ldt;
72240494Sglebius	uint16_t	pcb_tr;
73240494Sglebius
74200580Sluigi	u_int		pcb_flags;
75200580Sluigi#define	PCB_FULL_IRET	0x01	/* full iret is required */
76200580Sluigi#define	PCB_DBREGS	0x02	/* process using debug registers */
77200580Sluigi#define	PCB_KERNFPU	0x04	/* kernel uses fpu */
78200580Sluigi#define	PCB_FPUINITDONE	0x08	/* fpu state is initialized */
79200580Sluigi#define	PCB_USERFPUINITDONE 0x10 /* fpu user state is initialized */
80200580Sluigi#define	PCB_GS32BIT	0x20	/* linux gs switch */
81200580Sluigi#define	PCB_32BIT	0x40	/* process has 32 bit context (segs etc) */
82200580Sluigi
83200580Sluigi	uint16_t	pcb_initial_fpucw;
84200580Sluigi
85200580Sluigi	/* copyin/out fault recovery */
86200580Sluigi	caddr_t		pcb_onfault;
87200580Sluigi
88200580Sluigi	/* 32-bit segment descriptor */
89258465Sluigi	struct user_segment_descriptor pcb_gs32sd;
90258465Sluigi
91258465Sluigi	/* local tss, with i/o bitmap; NULL for common */
92258465Sluigi	struct amd64tss *pcb_tssp;
93258465Sluigi
94258465Sluigi	/* model specific registers */
95200580Sluigi	register_t	pcb_efer;
96200580Sluigi	register_t	pcb_star;
97258465Sluigi	register_t	pcb_lstar;
98200580Sluigi	register_t	pcb_cstar;
99201122Sluigi	register_t	pcb_sfmask;
100201122Sluigi	register_t	pcb_xsmask;
101201122Sluigi
102201122Sluigi	/* fpu context for suspend/resume */
103201122Sluigi	void *		pcb_fpususpend;
104201122Sluigi
105302290Sbz	struct savefpu	*pcb_save;
106302290Sbz
107238277Shrs	uint64_t	pcb_pad[3];
108238277Shrs};
109238277Shrs
110238277Shrs#ifdef _KERNEL
111238277Shrsstruct trapframe;
112238277Shrs
113238277Shrs/*
114200654Sluigi * The pcb_flags is only modified by current thread, or by other threads
115241610Sglebius * when current thread is stopped.  However, current thread may change it
116238277Shrs * from the interrupt context in cpu_switch(), or in the trap handler.
117200654Sluigi * When we read-modify-write pcb_flags from C sources, compiler may generate
118200654Sluigi * code that is not atomic regarding the interrupt handler.  If a trap or
119200654Sluigi * interrupt happens and any flag is modified from the handler, it can be
120200654Sluigi * clobbered with the cached value later.  Therefore, we implement setting
121200654Sluigi * and clearing flags with single-instruction functions, which do not race
122200654Sluigi * with possible modification of the flags from the trap or interrupt context,
123200654Sluigi * because traps and interrupts are executed only on instruction boundary.
124211992Smaxim */
125211992Smaximstatic __inline void
126249925Sglebiusset_pcb_flags(struct pcb *pcb, const u_int flags)
127211992Smaxim{
128211992Smaxim
129239092Sluigi	__asm __volatile("orl %1,%0"
130211992Smaxim	    : "=m" (pcb->pcb_flags) : "ir" (flags), "m" (pcb->pcb_flags)
131211992Smaxim	    : "cc");
132211992Smaxim}
133211992Smaxim
134211992Smaximstatic __inline void
135211992Smaximclear_pcb_flags(struct pcb *pcb, const u_int flags)
136211992Smaxim{
137211992Smaxim
138211992Smaxim	__asm __volatile("andl %1,%0"
139211992Smaxim	    : "=m" (pcb->pcb_flags) : "ir" (~flags), "m" (pcb->pcb_flags)
140211992Smaxim	    : "cc");
141211992Smaxim}
142238277Shrs
143238277Shrsvoid	makectx(struct trapframe *, struct pcb *);
144238277Shrsint	savectx(struct pcb *) __returns_twice;
145238277Shrsvoid	resumectx(struct pcb *);
146241610Sglebius
147238277Shrs#endif
148238277Shrs
149238277Shrs#endif /* _AMD64_PCB_H_ */
150238277Shrs