archdep.c 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.
*/
/* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
/* All Rights Reserved */
#pragma ident "%Z%%M% %I% %E% SMI"
#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. Note
* that the frame for the starting stack pointer value is omitted because
* the corresponding %pc is not known.
*/
void
{
int on_intr;
if (!panicstr)
/*
* 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 "
} else {
printf("%016lx %p (%lx, %lx, %lx, %lx, %lx, %lx)\n",
}
printf(" %%l0-3: %016lx %016lx %016lx %016lx\n"
" %%l4-7: %016lx %016lx %016lx %016lx\n",
}
if (!panicstr) {
printf("end of traceback\n");
}
}
/*
* 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
{
}