desctbls.c revision 0baeff3d96eae184e775c1064f1836090446a7bf
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright (c) 1992 Terrence R. Lambert.
* Copyright (c) 1990 The Regents of the University of California.
* All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* William Jolitz.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* from: @(#)machdep.c 7.4 (Berkeley) 6/3/91
*/
#include <sys/segments.h>
#include <sys/x86_archext.h>
#include <sys/archsystm.h>
#include <sys/machsystm.h>
extern void syscall_int(void);
/*
* cpu0 and default tables and structures.
*/
#if defined(__i386)
#endif /* __i386 */
#if defined(__amd64)
#endif /* __amd64 */
char dblfault_stack0[DEFAULTSTKSZ];
extern void fast_null(void);
extern hrtime_t get_hrtime(void);
extern hrtime_t gethrvtime(void);
extern hrtime_t get_hrestime(void);
void (*(fasttable[]))(void) = {
fast_null, /* T_FNULL routine */
fast_null, /* T_FGETFP routine (initially null) */
fast_null, /* T_FSETFP routine (initially null) */
(void (*)())get_hrtime, /* T_GETHRTIME */
(void (*)())gethrvtime, /* T_GETHRVTIME */
(void (*)())get_hrestime, /* T_GETHRESTIME */
(void (*)())getlgrp /* T_GETLGRP */
};
/*
* software prototypes for default local descriptor table
*/
/*
* Routines for loading segment descriptors in format the hardware
* can understand.
*/
#if defined(__amd64)
/*
* In long mode we have the new L or long mode attribute bit
* for code segments. Only the conforming bit in type is used along
* with descriptor priority and present bits. Default operand size must
* be zero when in long mode. In 32-bit compatibility mode all fields
* are treated as in legacy mode. For data segments while in long mode
* only the present bit is loaded.
*/
void
{
/*
* 64-bit long mode.
*/
else
/*
* 32-bit compatibility mode.
*/
}
/*
* Install user segment descriptor for code and data.
*/
void
{
}
#endif /* __i386 */
/*
* Install system segment descriptor for LDT and TSS segments.
*/
#if defined(__amd64)
void
{
}
void
{
}
#endif /* __i386 */
/*
* Install gate segment descriptor for interrupt, trap, call and task gates.
*/
#if defined(__amd64)
/*
* Note stkcpy is replaced with ist. Read the PRM for details on this.
*/
void
{
}
void
{
}
#endif /* __i386 */
/*
* Build kernel GDT.
*/
#if defined(__amd64)
static void
init_gdt(void)
{
/*
* Copy in from boot's gdt to our gdt entries 1 - 4.
* Entry 0 is the null descriptor by definition.
*/
panic("null boot gdt");
/*
* 64-bit kernel code segment.
*/
/*
* 64-bit kernel data segment. The limit attribute is ignored in 64-bit
* mode, but we set it here to 0xFFFF so that we can use the SYSRET
* instruction to return from system calls back to 32-bit applications.
* SYSRET doesn't update the base, limit, or attributes of %ss or %ds
* descriptors. We therefore must ensure that the kernel uses something,
* though it will be ignored by hardware, that is compatible with 32-bit
* apps. For the same reason we must set the default op size of this
* descriptor to 32-bit operands.
*/
/*
* 64-bit user code segment.
*/
/*
* 32-bit user code segment.
*/
/*
* 32 and 64 bit data segments can actually share the same descriptor.
* In long mode only the present bit is checked but all other fields
* are loaded. But in compatibility mode all fields are interpreted
* as in legacy mode so they must be set correctly for a 32-bit data
* segment.
*/
/*
* The 64-bit kernel has no default LDT. By default, the LDT descriptor
* in the GDT is 0.
*/
/*
* Kernel TSS
*/
/*
* Initialize fs and gs descriptors for 32 bit processes.
* Only attributes and limits are initialized, the effective
*/
/*
* Install our new GDT
*/
/*
* Initialize convenient zero base user descriptors for clearing
* lwp private %fs and %gs descriptors in GDT. See setregs() for
* an example.
*/
}
static void
init_gdt(void)
{
/*
* Copy in from boot's gdt to our gdt entries 1 - 4.
* Entry 0 is null descriptor by definition.
*/
panic("null boot gdt");
/*
* Text and data for both kernel and user span entire 32 bit
* address space.
*/
/*
* kernel code segment.
*/
SDP_OP32);
/*
* kernel data segment.
*/
SDP_OP32);
/*
* user code segment.
*/
SDP_OP32);
/*
* user data segment.
*/
SDP_OP32);
/*
* TSS for T_DBLFLT (double fault) handler
*/
/*
* TSS for kernel
*/
/*
* %gs selector for kernel
*/
/*
* Initialize lwp private descriptors.
* Only attributes and limits are initialized, the effective
*/
/*
* Install our new GDT
*/
/*
* Initialize convenient zero base user descriptors for clearing
* lwp private %fs and %gs descriptors in GDT. See setregs() for
* an example.
*/
}
#endif /* __i386 */
#if defined(__amd64)
/*
* Build kernel IDT.
*
* Note that we pretty much require every gate to be an interrupt gate;
* that's because of our dependency on using 'swapgs' every time we come
* into the kernel to find the cpu structure - if we get interrupted just
* before doing that, so that %cs is in kernel mode (so that the trap prolog
* doesn't do a swapgs), but %gsbase is really still pointing at something
* in userland, bad things ensue.
*
* Perhaps they should have invented a trap gate that does an atomic swapgs?
*
* XX64 We do need to think further about the follow-on impact of this.
* Most of the kernel handlers re-enable interrupts as soon as they've
* saved register state and done the swapgs, but there may be something
* more subtle going on.
*/
static void
init_idt(void)
{
char ivctname[80];
void (*ivctptr)(void);
int i;
/*
* Initialize entire table with 'reserved' trap and then overwrite
* specific entries. T_EXTOVRFLT (9) is unsupported and reserved
* since it can only be generated on a 386 processor. 15 is also
* unsupported and reserved.
*/
for (i = 0; i < NIDT; i++)
SEL_KPL);
SEL_KPL);
SEL_KPL);
SEL_KPL);
SEL_UPL);
SEL_UPL);
SEL_KPL);
SEL_KPL);
SEL_KPL);
/*
* double fault handler.
*/
SEL_KPL);
/*
* T_EXTOVRFLT coprocessor-segment-overrun not supported.
*/
SEL_KPL);
SEL_KPL);
SEL_KPL);
SEL_KPL);
SEL_KPL);
/*
* 15 reserved.
*/
SEL_KPL);
SEL_KPL);
SEL_KPL);
SEL_KPL);
/*
* 20-31 reserved
*/
for (i = 20; i < 32; i++)
SEL_KPL);
/*
* interrupts 32 - 255
*/
for (i = 32; i < 256; i++) {
SEL_KPL);
}
/*
* install fast trap handler at 210.
*/
/*
* System call handler.
*/
/*
* Install the DTrace interrupt handlers for the fasttrap provider.
*/
/*
* We must maintain a description of idt0 in convenient IDTR format
* for use by T_NMIFLT and T_PGFLT (nmiint() and pentium_pftrap())
* handlers.
*/
}
/*
* Build kernel IDT.
*/
static void
init_idt(void)
{
char ivctname[80];
void (*ivctptr)(void);
int i;
/*
* Initialize entire table with 'reserved' trap and then overwrite
* specific entries. T_EXTOVRFLT (9) is unsupported and reserved
* since it can only be generated on a 386 processor. 15 is also
* unsupported and reserved.
*/
for (i = 0; i < NIDT; i++)
SEL_KPL);
SEL_KPL);
SEL_KPL);
SEL_KPL);
SEL_UPL);
SEL_UPL);
SEL_KPL);
SEL_KPL);
SEL_KPL);
/*
* Install TSS for T_DBLFLT handler.
*/
SEL_KPL);
/*
* T_EXTOVRFLT coprocessor-segment-overrun not supported.
*/
SEL_KPL);
SEL_KPL);
SEL_KPL);
SEL_KPL);
SEL_KPL);
/*
* 15 reserved.
*/
SEL_KPL);
SEL_KPL);
SEL_KPL);
SEL_KPL);
/*
* 20-31 reserved
*/
for (i = 20; i < 32; i++)
SEL_KPL);
/*
* interrupts 32 - 255
*/
for (i = 32; i < 256; i++) {
SEL_KPL);
}
/*
* install fast trap handler at 210.
*/
/*
* System call handler. Note that we don't use the hardware's parameter
* copying mechanism here; see the comment above sys_call() for details.
*/
/*
* Install the DTrace interrupt handlers for the fasttrap provider.
*/
/*
* We must maintain a description of idt0 in convenient IDTR format
* for use by T_NMIFLT and T_PGFLT (nmiint() and pentium_pftrap())
* handlers.
*/
}
#endif /* __i386 */
/*
* The kernel does not deal with LDTs unless a user explicitly creates
* one. Under normal circumstances, the LDTR contains 0. Any process attempting
* to reference the LDT will therefore cause a #gp. System calls made via the
* obsolete lcall mechanism are emulated by the #gp fault handler.
*/
static void
init_ldt(void)
{
wr_ldtr(0);
}
#if defined(__amd64)
static void
init_tss(void)
{
/*
* tss_rsp0 is dynamically filled in by resume() on each context switch.
* All exceptions but #DF will run on the thread stack.
* Set up the double fault stack here.
*/
/*
* Set I/O bit map offset equal to size of TSS segment limit
* for no I/O permission map. This will force all user I/O
* instructions to generate #gp fault.
*/
/*
* Point %tr to descriptor for ktss0 in gdt.
*/
}
static void
init_tss(void)
{
/*
* ktss0.tss_esp dynamically filled in by resume() on each
* context switch.
*/
/*
* Initialize double fault tss.
*/
/*
* tss_cr3 will get initialized in hat_kern_setup() once our page
* tables have been setup.
*/
/*
* Set I/O bit map offset equal to size of TSS segment limit
* for no I/O permission map. This will force all user I/O
* instructions to generate #gp fault.
*/
/*
* Point %tr to descriptor for ktss0 in gdt.
*/
}
#endif /* __i386 */
void
init_tables(void)
{
init_gdt();
init_tss();
init_idt();
init_ldt();
}