Coherent4.2.10/include/common/_gregset.h
/* (-lgl
* Coherent 386 release 4.2
* Copyright (c) 1982, 1993 by Mark Williams Company.
* All rights reserved. May not be copied without permission.
* For copying permission and licensing info, write licensing@mwc.com
-lgl) */
#ifndef __COMMON__GREGSET_H__
#define __COMMON__GREGSET_H__
/*
* This file defines a "register set" type along the lines of the "gregset_t"
* type defined for the process file-system in System V, Release 4. This
* subsumes the function of the <sys/reg.h> header in the iBCS2 specification,
* which describes the layout of data on the signal stack and also within the
* kernel (in COHERENT, via the "u.u_regl" pointer, and in SCO via "u.u_ar0")
* in terms of an array of "int". With the introduction of this type, the U
* area structure has been removed as an anachronism.
*
* This file defines the structure layout; an incomplete type declaration is
* present in another file for use by code that has no need to know the
* internal structure of such items.
*/
#include <common/__types.h>
#include <common/gregset.h>
/*
* Definitions for dealing with the flag register. The flag register should
* only be accessed by the following macros; for public use we declare a
* non-arithmetic type. For the 286 part of the structure, we define a
* suitable non-arithmetic type, but no macros; such elements may be copied,
* but not manipulated.
*/
/*
* Codes for I/O privelege levels. This level specifies a cut-off processor
* privelege level (as given by the CPL, the privelege level of the currently
* executing code segment) above which certain instructions require special
* privelege.
*/
enum __iopl {
_IOPL_0, _IOPL_1, _IOPL_2, _IOPL_3,
__FLAG_IOPL_MASK = _IOPL_3
};
typedef enum __iopl __iopl_t;
typedef struct __flag_reg * __flag_reg_t;
typedef __ulong_t __flag_arith_t;
typedef struct {
__ushort_t __286;
} __286_flags_t;
enum {
__CARRY_FLAG_SHIFT,
__PARITY_FLAG_SHIFT = 2,
__AUXCARRY_FLAG_SHIFT = 4,
__ZERO_FLAG_SHIFT = 6,
__SIGN_FLAG_SHIFT,
__TRAP_FLAG_SHIFT,
__INTERRUPT_FLAG_SHIFT,
__DIRECTION_FLAG_SHIFT,
__OVERFLOW_FLAG_SHIFT,
__IOPL_SHIFT,
__NESTED_FLAG_SHIFT = 14,
__RESUME_FLAG_SHIFT = 16,
__V8086_FLAG_SHIFT,
__ALIGNCHECK_FLAG_SHIFT
};
/*
* Except for the IOPL field, all the currently defined members of the flag
* word are single bits; here we simply define a general framework for dealing
* with them and the shift positions for the most common flags.
*/
#define __FLAG_MASK(value, shift) \
((__flag_arith_t) (value) << \
(__CONCAT (shift, _FLAG_SHIFT) + 0U))
#define __FLAG_GET_FLAG(flags, shift) \
((__flag_arith_t) (flags) >> \
(__CONCAT (shift, _FLAG_SHIFT) & 1) != 0)
#define __FLAG_SET_FLAG_TO(flags, value, shift) \
((__flag_reg_t) \
(((__flag_arith_t) (flags) & ~ __FLAG_MASK (1, shift)) | \
__FLAG_MASK (value, shift)))
#define __FLAG_SET_FLAG(flags, shift) __FLAG_SET_FLAG_TO (flags, 1, shift)
#define __FLAG_CLEAR_FLAG(flags, shift) __FLAG_SET_FLAG_TO (flags, 0, shift)
#define __FLAG_GET_IOPL(flags) \
((__iopl_t) ((__flag_arith_t) (flags) >> __IOPL_SHIFT) & \
__IOPL_MASK)
/*
* Special case for clearing all the status (i.e., user-modifiable) flags to
* a known state.
*/
#define __FLAG_STATUS_MASK (__FLAG_MASK (1, __OVERFLOW) | \
__FLAG_MASK (1, __SIGN) | \
__FLAG_MASK (1, __ZERO) | \
__FLAG_MASK (1, __AUXCARRY) | \
__FLAG_MASK (1, __PARITY) | \
__FLAG_MASK (1, __CARRY))
#define __FLAG_CLEAR_STATUS(flags) \
((__flag_reg_t) ((__flag_arith_t) (flags) & \
~ __FLAG_STATUS_MASK))
/*
* Type for describing an Intel-style selector. We have few choices as to how
* to define this type, because the size of a selector does not match that of
* a pointer for the usual pointer-to-incomplete-type technique.
*
* However, because selector access relates only to the i386 processor family,
* this is actually desirable as we do not want access to these items to be
* made directly in portable code anyway.
*/
typedef __ushort_t __sel_arith_t;
typedef struct {
__sel_arith_t __selector;
} __selector_t;
#define __SELECTOR_ARITH(selp) ((selp).__selector)
/*
* Describe privilege rings verbosely.
*/
enum {
_PRIVILEGE_RING_0,
_PRIVILEGE_RING_1,
_PRIVILEGE_RING_2,
_PRIVILEGE_RING_3,
_USER_PRIVILEGE = _PRIVILEGE_RING_3,
__PRIVILEGE_RING_MASK = _PRIVILEGE_RING_3
};
/*
* A bit in the selector selects whether the selector refers to a descriptor
* in the local descriptor table or the global descriptor table.
*/
enum {
_GLOBAL_DESCRIPTOR,
_LOCAL_DESCRIPTOR,
__DESCRIPTOR_TABLE_MASK = _LOCAL_DESCRIPTOR
};
/*
* A part of the selector forms an index into one of the selected descriptor
* tables. Here, we only deal with the generic aspect of this; index values
* for particular segments are described elsewhere.
*/
enum {
__DESCRIPTOR_INDEX_MASK = 0x1FFF
};
/*
* Shift values for the various components of a selector.
*/
#define __SELECTOR_PRIVILEGE_SHIFT 0U
#define __SELECTOR_TABLE_SHIFT 2U
#define __SELECTOR_INDEX_SHIFT 3U
#define __SELECTOR_PRIVILEGE(selp) \
((__SELECTOR_ARITH (selp) >> __SELECTOR_PRIVILEGE_SHIFT) & \
__PRIVILEGE_RING_MASK)
#define __SELECTOR_TABLE(selp) \
((__SELECTOR_ARITH (selp) >> __SELECTOR_TABLE_SHIFT) & \
__DESCRIPTOR_TABLE_MASK)
#define __SELECTOR_DESCRIPTOR(selp) \
((__SELECTOR_ARITH (selp) >> __SELECTOR_INDEX_SHIFT) & \
__DESCRIPTOR_INDEX_MASK)
#define __MAKE_SELECTOR_ARITH(index,table,privelege) \
(((index) << __SELECTOR_INDEX_SHIFT) | \
((table) << __SELECTOR_TABLE_SHIFT) | \
((privelege) << __SELECTOR_PRIVILEGE_SHIFT))
#define __SET_SELECTOR(selp,arith) \
((void) (__SELECTOR_ARITH (selp) = (arith)))
/*
* General register-set description structure, without padding.
*/
union __gregset {
/*
* Frame for i386 task.
*/
struct {
/*
* Pushed by the trap handler.
*/
__selector_t _gs;
__ushort_t _pad1;
__selector_t _fs;
__ushort_t _pad2;
__selector_t _es;
__ushort_t _pad3;
__selector_t _ds;
__ushort_t _pad4;
/*
* Pushed by the trap handler with a "pusha" intruction.
*/
__ulong_t _edi;
__ulong_t _esi;
__ulong_t _ebp;
__ulong_t _esp;
__ulong_t _ebx;
__ulong_t _edx;
__ulong_t _ecx;
__ulong_t _eax;
/*
* Created by the i386 when handling exceptions, or by the
* trap code when handling software/hardware interrupts.
*/
__ulong_t _trapno;
__ulong_t _err;
/*
* General i386 inter-level interrupt return frame.
*/
__ulong_t _eip;
__selector_t _cs;
__ushort_t _pad5;
__flag_reg_t _eflags;
__ulong_t _uesp;
__selector_t _ss;
__ushort_t _pad6;
} _i386;
/*
* Frame for i286 task, created from the same code as above but with
* only the low 16 bits of general registers containing valid data.
*/
struct {
/*
* Pushed by the trap handler.
*/
__selector_t _gs;
__ushort_t _pad1;
__selector_t _fs;
__ushort_t _pad2;
__selector_t _es;
__ushort_t _pad3;
__selector_t _ds;
__ushort_t _pad4;
/*
* Pushed by the trap handler with a "pusha" intruction.
*/
__ushort_t _di;
__ushort_t _pad6;
__ushort_t _si;
__ushort_t _pad7;
__ushort_t _bp;
__ushort_t _pad8;
__ulong_t _esp; /* kernel %esp */
__ushort_t _bx;
__ushort_t _pad9;
__ushort_t _dx;
__ushort_t _pad10;
__ushort_t _cx;
__ushort_t _pad11;
__ushort_t _ax;
__ushort_t _pad12;
/*
* Created by the i386 when handling exceptions, or by the
* trap code when handling software/hardware interrupts.
*/
__ulong_t _trapno;
__ulong_t _err;
/*
* General i386 inter-level interrupt return frame.
*/
__ushort_t _ip;
__ushort_t _pad13;
__selector_t _cs;
__ushort_t _pad14;
__286_flags_t _flags;
__ushort_t _pad15;
__ushort_t _usp;
__ushort_t _pad16;
__selector_t _ss;
__ushort_t _pad17;
} _i286;
};
/*
* The notion of "flags" and "program counter" are fairly universal, although
* details vary wildly. The notion of a "flags" register encompasses condition
* codes on CISC-style processors, but is more oriented towards processor
* control functions such as endianness on RISC processors.
*
* Program counters are fairly universal, though. We also provide a predicate
* for testing whether a context is a saved user context or system context.
*/
#define __FLAG_REG(rp) ((rp)->_i386._eflags)
#define __PC_REG(rp) ((rp)->_i386._eip)
#define __IS_USER_REGS(rp) (__SELECTOR_PRIVILEGE ((rp)->_i386._cs) \
== _USER_PRIVILEGE)
#endif /* ! defined (__COMMON__GREGSET_H__) */