privregs.h revision 7c478bd95313f5f23a4c958a745db2134aa03244
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License, Version 1.0 only
* (the "License"). You may not use this file except in compliance
* with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _AMD64_SYS_PRIVREGS_H
#define _AMD64_SYS_PRIVREGS_H
#pragma ident "%Z%%M% %I% %E% SMI"
#ifdef __cplusplus
extern "C" {
#endif
/*
* This file describes the cpu's privileged register set, and
* how the machine state is saved on the stack when a trap occurs.
*/
#if !defined(__amd64)
#error "non-amd64 code depends on amd64 privileged header!"
#endif
#ifndef _ASM
/*
* This is NOT the structure to use for general purpose debugging;
* see /proc for that. This is NOT the structure to use to decode
*/
struct regs {
/*
* Extra frame for mdb to follow through high level interrupts and
* system traps. Set them to 0 to terminate stacktrace.
*/
/*
* (the rest of these are defined by the hardware)
*/
};
#ifdef _KERNEL
#endif /* _KERNEL */
#else /* !_ASM */
/*
* Create a struct regs on the stack suitable for an
* interrupt trap.
*
* The swapgs instruction is conditionalized to make sure that
* interrupts in kernel mode don't cause us to switch back to
* the user's gsbase!
*
* Assumes that the trap handler has already pushed an
* appropriate r_err and r_trapno
*/
#define __SAVE_REGS \
rdmsr; \
rdmsr; \
/*
* Push register state onto the stack. If we've
* interrupted userland, do a swapgs as well.
*/
#define INTR_PUSH \
__SAVE_REGS; \
je 6f; \
swapgs; \
6:
#define TRAP_PUSH \
__SAVE_REGS; \
je 6f; \
swapgs; \
6:
#define DFTRAP_PUSH \
#define __RESTORE_REGS \
#define INTR_POP \
je 5f; \
je 8f; \
5: swapgs; \
#define USER_POP \
swapgs; \
#define USER32_POP \
swapgs; \
/*
* Smaller versions of INTR_PUSH and INTR_POP for fast traps.
* The following registers have been pushed onto the stack by
* hardware at this point:
*
* greg_t r_rip;
* greg_t r_cs;
* greg_t r_rfl;
* greg_t r_rsp;
* greg_t r_ss;
*
* This handler is executed both by 32-bit and 64-bit applications.
* 64-bit applications allow us to treat the set (%rdi, %rsi, %rdx,
* %rcx, %r8, %r9, %r10, %r11, %rax) as volatile across function calls.
* However, 32-bit applications only expect (%eax, %edx, %ecx) to be volatile
* across a function call -- in particular, %esi and %edi MUST be saved!
*
* We could do this differently by making a FAST_INTR_PUSH32 for 32-bit
* programs, and FAST_INTR_PUSH for 64-bit programs, but it doesn't seem
* particularly worth it.
*/
#define FAST_INTR_PUSH \
#define FAST_INTR_POP \
swapgs; \
#define DISABLE_INTR_FLAGS \
#define ENABLE_INTR_FLAGS \
#endif /* !_ASM */
#include <sys/controlregs.h>
{
"movq %%cr8, %0"
: "=r" (value));
return (value);
}
{
"movq %0, %%cr8"
: /* no output */
: "r" (value));
}
#else
#endif /* !defined(__lint) && defined(__GNUC__) */
#endif /* _KERNEL && !_ASM */
/* Control register layout for panic dump */
#define CREGSZ 0x68
#define CREG_GDT 0
#define CREG_IDT 0x10
#define CREG_LDT 0x20
#define CREG_TASKR 0x28
#define CREG_CR0 0x30
#define CREG_CR2 0x38
#define CREG_CR3 0x40
#define CREG_CR4 0x48
#define CREG_CR8 0x50
#define CREG_KGSBASE 0x58
#define CREG_EFER 0x60
#if !defined(_ASM)
struct cregs {
};
#if defined(_KERNEL)
#endif /* _KERNEL */
#endif /* _ASM */
#ifdef __cplusplus
}
#endif
#endif /* _AMD64_SYS_PRIVREGS_H */