/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (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 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
#if defined(__lint)
int silence_lint = 0;
#else
#include <sys/segments.h>
#include <sys/controlregs.h>
/*
* Do a call into BIOS. This goes down to 16 bit real mode and back again.
*/
/*
* instruction prefix to change operand size in instruction
*/
#if defined(__amd64)
#endif
#if defined(__i386)
/*
* Save caller registers
*/
/* get registers argument into esi */
/* put interrupt number in %bl */
/* Switch to a low memory stack */
/* allocate space for args on stack */
/*
* Save caller registers
*/
/* Switch to a low memory stack */
/* put interrupt number in %bl */
/* allocate space for args on stack */
#endif
/* copy args from high memory to stack in low memory */
/*
* Save system registers
*/
#if defined(__amd64)
/*
*/
#endif
/*
* set offsets in 16 bit ljmp instructions below
*/
/*
* insert BIOS interrupt number into later instruction
*/
jmp 1f
1:
/*
* zero out all the registers to make sure they're 16 bit clean
*/
#if defined(__amd64)
#endif
/*
*/
#if defined(__amd64)
/*
* Shut down 64 bit mode. First get into compatiblity mode.
*/
pushq $1f
1:
/*
* disable long mode by:
* - shutting down paging (bit 31 of cr0)
* - flushing the TLB
* - disabling LME (long made enable) in EFER (extended feature reg)
*/
1:
#endif
/*
* ok.. now enter 16 bit mode, so we can shut down protected mode
*
* We'll have to act like we're still in a 32 bit section.
* So the code from this point has DATASZ in front of it to get 32 bit
* operands. If DATASZ is missing the operands will be 16 bit.
*
* Now shut down paging and protected (ie. segmentation) modes.
*/
/*
* Make sure hidden parts of segment registers are 16 bit clean
*/
.value 0 /* addr (16 bit) */
/*
* zero out the remaining segment registers
*/
/*
* load the arguments to the BIOS call from the stack
*/
/*
* do the actual BIOS call
*/
int $0x10 /* this int number is overwritten */
cli /* ensure interrupts remain disabled */
/*
* save results of the BIOS call
*/
/*
* Restore protected mode and 32 bit execution
*/
push $0 /* make sure %ds is zero before lgdt */
.value 0 /* temp GDT in currently addressible mem */
.value 0 /* addr (still in 16 bit) */
/*
*/
/*
* Re-enable paging. Note we only use 32 bit mov's to restore these
* control registers. That's OK as the upper 32 bits are always zero.
*/
#if defined(__amd64)
/*
* re-enable long mode
*/
#endif
#if defined(__amd64)
/*
* transition back to 64 bit mode
*/
#endif
/*
* restore caller frame pointer and segment registers
*/
/*
* Before loading the task register we need to reset the busy bit
* in its corresponding GDT selector. The busy bit is the 2nd bit in
* the 5th byte of the selector.
*/
#if defined(__i386)
#endif
#if defined(__i386)
#endif
.newcs:
#if defined(__amd64)
/*
* restore the hidden kernel segment base register values
*/
je 1f
1:
#endif
/*
* copy results to caller's location, then restore remaining registers
*/
#if defined(__i386)
#endif
/*
* Caller's registers to restore
*/
.align 4
.long 0
.long 0
.long 0
.long 0
.long 0
.align 8
#if defined(__amd64)
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
#endif /* __amd64 */
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.quad 0
.value 0
.value 0
.value 0
.value 0
.value 0
.value 0
.value 0x3ff
.quad 0
/*
* We need to trampoline thru a gdt we have in low memory.
*/
#include "../boot/boot_gdt.s"
#endif /* __lint */