kaif_startup.s 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.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Debugger entry for both master and slave CPUs
*/
#if defined(__lint)
#endif
#include <sys/segments.h>
#include <sys/asm_linkage.h>
#include <sys/controlregs.h>
#include <sys/x86_archext.h>
#include <mdb/mdb_kreg.h>
#include <kmdb/kaif_asmutil.h>
#include <kmdb/kaif_regs.h>
#include <kmdb/kaif_off.h>
#include <kmdb/kmdb_dpi_isadep.h>
#if !defined(__lint)
/* XXX implement me */
/*
* The state of the world:
*
* The stack has a complete set of saved registers and segment
* selectors, arranged in `struct regs' order (or vice-versa), up to
* and including EFLAGS. It also has a pointer to our cpusave area.
*
* We need to save a pointer to these saved registers. We also want
* to adjust the saved %esp - it should point just beyond the saved
* registers to the last frame of the thread we interrupted. Finally,
* we want to clear out bits 16-31 of the saved selectors, as the
* selector pushls don't automatically clear them.
*/
/* Save off %cr0, and clear write protect */
/* Save the debug registers and disable any active watchpoints */
/*
* Save any requested MSRs.
*/
1:
rdmsr /* addr in %ecx, value into %edx:%eax */
jmp 1b
#endif /* !__lint */
/*
* The main entry point for master CPUs. It also serves as the trap handler
* for all traps and interrupts taken during single-step.
*/
#if defined(__lint)
void
kaif_cmnint(void)
{
}
#else /* __lint */
/* Save all registers and selectors */
/*
* If the kernel has started using its own selectors, we should too.
* Update our saved selectors if they haven't been updated already.
*/
/*
* The kernel switched, but we haven't. Update our saved selectors
* to match the kernel's copies for use below.
*/
1:
/*
* Set the selectors to a known state. If we come in from kmdb's IDT,
* we'll be on boot's %cs. This will cause GET_CPUSAVE_ADDR to return
* CPU 0's cpusave, regardless of which CPU we're on, and chaos will
* ensue. So, if we've got $KCSSEL in kaif_cs, switch to it. The other
* selectors are restored normally.
*/
jne 1f
1:
GET_CPUSAVE_ADDR /* %eax = cpusave, %ebx = CPU ID */
/*
* Were we in the debugger when we took the trap (i.e. was %esp in one
* of the debugger's memory ranges)?
*/
jmp 1b
3: /*
* %esp was within one of the debugger's memory ranges. This should only
* happen when we take a trap while running in the debugger.
* kmdb_dpi_handle_fault will determine whether or not it was an expected
* trap, and will take the appropriate action.
*/
/*
* If we're here, we ran into a debugger problem, and the user
* elected to solve it by having the debugger debug itself. The
* state we're about to save is that of the debugger when it took
* the fault.
*/
#endif /* __lint */
/*
* The cross-call handler for slave CPUs.
*
* The debugger is single-threaded, so only one CPU, called the master, may be
* running it at any given time. The other CPUs, known as slaves, spin in a
* busy loop until there's something for them to do. This is the entry point
* for the slaves - they'll be sent here in response to a cross-call sent by the
* master.
*/
#if defined(__lint)
char kaif_slave_entry_patch;
void
kaif_slave_entry(void)
{
}
#else /* __lint */
/* kaif_msr_add_clrentry knows where this is */
/*
* Cross calls are implemented as function calls, so our stack currently
* looks like one you'd get from a zero-argument function call. There's
* an %eip at %esp, and that's about it. We want to make it look like the
* master CPU's stack. By doing this, we can use the same resume code for
* both master and slave. We need to make our stack look like a `struct
* regs' before we jump into the common save routine.
*/
/* Swap our saved EFLAGS and %eip. Each is where the other should be */
/* Our stack now matches struct regs, and is irettable */
/* Load sanitized segment selectors */
GET_CPUSAVE_ADDR /* %eax = cpusave, %ebx = CPU ID */
#endif /* __lint */