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 the order given in mdb_kreg.h. It also has a
* pointer to our cpusave area.
*
* We need to save, into the cpusave area, a pointer to these saved
* registers. After that, we save a few more registers, ready the
* machine for debugger entry, and enter the debugger.
*/
/* 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
/* Pass cpusave and debugger return code for "call" to resume */
#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 current register state */
/*
* Switch to the kernel's GSBASE. Neither GSBASE nor the ill-named
* KGSBASE can be trusted, as the kernel may or may not have already
* done a swapgs. All is not lost, as the kernel can divine the correct
* value for us.
*/
GET_CPUSAVE_ADDR /* %rax = cpusave, %rbx = 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: /*
* The master is still set. That should only happen if we hit a trap
* while running in the debugger. Note that it may be an intentional
* fault. kmdb_dpi_handle_fault will sort it all out.
*/
/*
* 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. That
* is, there's the return %rip at %rsp, and that's about it. We need
* to make it look like an interrupt stack. When we first save, we'll
* reverse the saved %ss and %rip, which we'll fix back up when we've
* freed up some general-purpose registers. We'll also need to fix up
* the saved %rsp.
*/
/*
* We've saved all of the general-purpose registers, and have a stack
* that is irettable (after we strip down to the error code)
*/
GET_CPUSAVE_ADDR /* %rax = cpusave, %rbx = CPU ID */
#endif /* __lint */