archdep.c revision f6e214c7418f43af38bd8c3a557e3d0a1d311cfa
/*
* 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 (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#include <sys/sysmacros.h>
#include <sys/ucontext.h>
#include <sys/asm_linkage.h>
#include <sys/bootconf.h>
#include <sys/archsystm.h>
#include <sys/elf_SPARC.h>
#include <sys/privregs.h>
#include <vm/seg_kmem.h>
/*
* Workaround for broken FDDI driver (remove when 4289172 is fixed)
*/
short cputype = 0x80;
/*
* Get a pc-only stacktrace. Used for kmem_alloc() buffer ownership tracking.
* Returns MIN(current stack depth, pcstack_limit).
*/
int
{
int depth;
int on_intr;
else
/*
* getpcstack_top() processes the frames still in register windows,
* fills nextfp and nextpc with our starting point, and returns
* the number of frames it wrote into pcstack.
*
* Since we cannot afford to take a relocation trap while we are
* messing with register windows, we pass getpcstack_top() a buffer
* on our stack and then copy the result out to the pcstack buffer
* provided by the caller. The size of this buffer is the maximum
* supported number of SPARC register windows; however we ASSERT
* that it returns fewer than that, since it will skip the current
* frame.
*/
}
while (depth < pcstack_limit) {
if (on_intr) {
/*
* Hop from interrupt stack to thread stack.
*/
on_intr = 0;
continue;
}
break;
}
}
return (depth);
}
/*
* The following ELF header fields are defined as processor-specific
* in the SPARC V8 ABI:
*
* e_ident[EI_DATA] encoding of the processor-specific
* data in the object file
* e_machine processor identification
* e_flags processor-specific flags associated
* with the file
*/
/*
* The value of at_flags reflects a platform's cpu module support.
* at_flags is used to check for allowing a binary to execute and
* is passed as the value of the AT_FLAGS auxiliary vector.
*/
int at_flags = 0;
/*
* Check the processor-specific fields of an ELF header.
*
* returns 1 if the fields are valid, 0 otherwise
*/
int
unsigned char e_data,
{
int supported_flags;
if (e_data != ELFDATA2MSB)
return (0);
switch (e_machine) {
case EM_SPARC:
if (e_flags == 0)
return (1);
else
return (0);
case EM_SPARCV9:
/*
* Check that ELF flags are set to supported SPARC V9 flags
*/
if (needed_flags & ~supported_flags)
return (0);
else
return (1);
case EM_SPARC32PLUS:
if ((e_flags & EF_SPARC_32PLUS) != 0 &&
return (1);
else
return (0);
default:
return (0);
}
}
#if defined(_SYSCALL32_IMPL)
#endif
/*
* Gather information about the processor and place it into auxv_hwcap
* so that it can be exported to the linker via the aux vector.
*
* We use this seemingly complicated mechanism so that we can ensure
* cannot discover for itself.
*/
void
bind_hwcap(void)
{
if (auxv_hwcap_include || auxv_hwcap_exclude)
#if defined(_SYSCALL32_IMPL)
/*
* These are now a compatibility artifact; all supported SPARC CPUs
* are V9-capable (and thus support v8plus) and fully implement
* {s,u}mul and {s,u}div.
*/
#endif
}
int
__ipltospl(int ipl)
{
}
/*
* Print a stack backtrace using the specified stack pointer. We delay two
* seconds before continuing, unless this is the panic traceback.
* If we are in the process of panicking, we also attempt to write the
* stack backtrace to a staticly assigned buffer, to allow the panic
* code to find it and write it in to uncompressed pages within the
* system crash dump.
*
* Note that the frame for the starting stack pointer value is omitted because
* the corresponding %pc is not known.
*/
extern char *dump_stack_scratch;
void
{
int on_intr;
uint_t next_offset = 0;
char stack_buffer[2048];
char local_buffer[1024];
if (!panicstr)
if (panicstr && !dump_stack_scratch) {
printf("Warning - stack not written to the dumpbuf\n");
}
/*
* If we are panicking, the high-level interrupt information in
* CPU was overwritten. panic_cpu has the correct values.
*/
kpreempt_disable(); /* prevent migration */
else
char *sym;
if (on_intr) {
/*
* Hop from interrupt stack to thread stack.
*/
on_intr = 0;
continue;
}
break; /* we're outside of the expected range */
}
break;
}
printf("%016lx %s:%s+%lx "
"%s:%s+%lx "
"(%lx, %lx, %lx, %lx, %lx, %lx) | ",
} else {
(void) printf("%016lx %p (%lx, %lx, %lx, "
"%lx, %lx, %lx)\n",
"%p (%lx, %lx, %lx, %lx, %lx, %lx) | ",
(void *)pc,
}
" %%l0-3: %016lx %016lx %016lx %016lx\n"
" %%l4-7: %016lx %016lx %016lx %016lx\n",
if (panicstr && dump_stack_scratch) {
if (next_offset < STACK_BUF_SIZE) {
} else {
/*
* In attempting to save the panic stack
* to the dumpbuf we have overflowed that area.
* Print a warning and continue to printf the
* stack to the msgbuf
*/
printf("Warning: stack in the dump buffer"
" may be incomplete\n");
}
}
}
if (!panicstr) {
printf("end of traceback\n");
} else if (dump_stack_scratch) {
}
}
/*
* Generate a stack backtrace from a saved register set.
*/
void
{
}
void
{
else
}
/*
* Allocate a region of virtual address space, unmapped.
*
* When a hard-redzone (firewall) is in effect, redzone violations are
* caught by the hardware the instant they happen because the first byte
* past the logical end of a firewalled buffer lies at the start of an
* unmapped page. This firewalling is accomplished by bumping up the
* requested address allocation, effectively removing an additional page
* beyond the original request from the available virtual memory arena.
* However, the size of the allocation passed to boot, in boot_alloc(),
* doesn't reflect this additional page and fragmentation of the OBP
* "virtual-memory" "available" lists property occurs. Calling
* prom_claim_virt() for the firewall page avoids this fragmentation.
*/
void *
{
}
/*ARGSUSED*/
int
{
}
/*ARGSUSED*/
int
{
}
/*ARGSUSED*/
int
{
}