(in-package :sb!vm)
+;;; The comments in some of the cmucl source read that "the i and d
+;;; caches are unified, and so there is no need to flush them."
+;;;
+;;; Other bits of the cmucl source say that this is not true for
+;;; "newer machines, such as the SuperSPARC and MicroSPARC based
+;;; ones". Welcome to the 21st century... -- CSR, 2002-05-06
(defun sanctify-for-execution (component)
- (declare (ignore component))
+ (without-gcing
+ (alien-funcall (extern-alien "os_flush_icache"
+ (function void
+ system-area-pointer
+ unsigned-long))
+ (code-instructions component)
+ (* (code-header-ref component code-code-size-slot)
+ n-word-bytes)))
nil)
-
return call_into_lisp(function, args, 3);
}
+
.global fun_end_breakpoint_end
fun_end_breakpoint_end:
- .global flush_icache
- FUNCDEF(flush_icache)
-flush_icache:
+ .global sparc_flush_icache
+ FUNCDEF(sparc_flush_icache)
+sparc_flush_icache:
add %o0,%o1,%o2
1: iflush %o0 ! flush instruction cache
add %o0,8,%o0
ta ST_FLUSH_WINDOWS ! flush register windows
retl ! return from leaf routine
nop
+
#include <sys/types.h>
#include <signal.h>
-/* #include <sys/sysinfo.h> */
#include <sys/time.h>
#include <sys/stat.h>
#include <unistd.h>
os_context_register_t *
os_context_register_addr(os_context_t *context, int offset)
{
- /* printf("Offset: %d,", offset);
- printf("Context: %p\n", context);
- printf("PC: %x,", context->si_regs.pc);
- printf("NPC: %x\n", context->si_regs.npc); */
- if (offset == 0) {
- static int zero;
- zero = 0;
- /* printf("Returning: %p pointing to %p\n", &zero, zero); */
- return &zero;
- } else if (offset < 16) {
- /* printf("Returning: %p pointing to %p\n", &context->si_regs.u_regs[offset], context->si_regs.u_regs[offset]); */
- return &context->si_regs.u_regs[offset];
- } else if (offset < 32) {
- int *sp = (int*) context->si_regs.u_regs[14]; /* Stack Pointer ?? */
- /* printf("SP: %p\n", sp);
- printf("Returning: %p pointing to %p\n", &(sp[offset-16]), sp[offset-16]); */
- return &(sp[offset-16]);
- } else
- return 0;
+ if (offset == 0) {
+ static int zero;
+ zero = 0;
+ return &zero;
+ } else if (offset < 16) {
+ return &context->si_regs.u_regs[offset];
+ } else if (offset < 32) {
+ int *sp = (int*) context->si_regs.u_regs[14]; /* Stack Pointer */
+ return &(sp[offset-16]);
+ } else
+ return 0;
}
os_context_register_t *
os_context_pc_addr(os_context_t *context)
{
- return &(context->si_regs.pc);
+ return &(context->si_regs.pc);
}
os_context_register_t *
os_context_npc_addr(os_context_t *context)
{
- return &(context->si_regs.npc);
+ return &(context->si_regs.npc);
}
sigset_t *
os_context_sigmask_addr(os_context_t *context)
{
- return &(context->si_mask);
+ return &(context->si_mask);
}
void os_flush_icache(os_vm_address_t address, os_vm_size_t length)
{
- /* FIXME. There's a bit of stuff in the CMUCL version. It may or
- may not be needed */
+ /* This is the same for linux and solaris, so see sparc-assem.S */
+ sparc_flush_icache(address,length);
}
#include <sys/types.h>
#include <signal.h>
-/* #include <sys/sysinfo.h> */
#include <sys/time.h>
#include <sys/stat.h>
#include <unistd.h>
os_context_register_t *
os_context_pc_addr(os_context_t *context)
{
- return &(context->uc_mcontext.gregs[REG_PC]);
+ return &(context->uc_mcontext.gregs[REG_PC]);
}
os_context_register_t *
os_context_npc_addr(os_context_t *context)
{
- return &(context->uc_mcontext.gregs[REG_nPC]);
+ return &(context->uc_mcontext.gregs[REG_nPC]);
}
sigset_t *
os_context_sigmask_addr(os_context_t *context)
{
- return &(context->uc_sigmask);
+ return &(context->uc_sigmask);
}
void os_flush_icache(os_vm_address_t address, os_vm_size_t length)
{
- /* FIXME. There's a bit of stuff in the CMUCL version. It may or
- may not be needed */
+ /* see sparc-assem.S */
+ sparc_flush_icache(address, length);
}
#include <unistd.h>
#include <errno.h>
#include <sys/param.h>
+#include <sys/utsname.h>
#include "os.h"
#include "arch.h"
static os_vm_size_t real_page_size_difference=0;
-void
-os_init(void)
+/* So, this sucks. Versions of Solaris prior to 8 (SunOS releases
+ earlier than 5.8) do not support MAP_ANON passed as a flag to
+ mmap(). However, we would like SBCL compiled on SunOS 5.7 but
+ running on 5.8 to use MAP_ANON, but because of C's lack of
+ introspection at runtime, we can't grab the right value because
+ it's stuffed in a header file somewhere. We can, however, hardcode
+ it, and test at runtime for whether to use it... -- CSR, 2002-05-06 */
+int KLUDGE_MAYBE_MAP_ANON = 0x0;
+
+void os_init(void)
{
+ struct utsname name;
+ int major_version;
+ int minor_version;
+
+ uname(&name);
+ major_version = atoi(name.release);
+ if (major_version != 5) {
+ lose("sunos major version=%d (which isn't 5!)", major_version);
+ }
+ minor_version = atoi(name.release+2);
+ if (minor_version == 8) {
+ KLUDGE_MAYBE_MAP_ANON = 0x100;
+ }
+ if (minor_version > 8) {
+ FSHOW((stderr, "os_init: Solaris version greater than 8?\nUnknown MAP_ANON behaviour.\n"));
+ }
+
/* I do not understand this at all. FIXME. */
os_vm_page_size = os_real_page_size = sysconf(_SC_PAGESIZE);
fprintf(stderr,"os_init: Pagesize too large (%d > %d)\n",
os_vm_page_size,OS_VM_DEFAULT_PAGESIZE);
exit(1);
- }else{
+ } else {
/*
* we do this because there are apparently dependencies on
* the pagesize being OS_VM_DEFAULT_PAGESIZE somewhere...
}
}
-os_vm_address_t
-os_validate(os_vm_address_t addr, os_vm_size_t len)
+os_vm_address_t os_validate(os_vm_address_t addr, os_vm_size_t len)
{
- int flags = MAP_PRIVATE | MAP_NORESERVE | MAP_ANON;
+ int flags = MAP_PRIVATE | MAP_NORESERVE | KLUDGE_MAYBE_MAP_ANON;
if (addr)
flags |= MAP_FIXED;
return addr;
}
-void
-os_invalidate(os_vm_address_t addr, os_vm_size_t len)
+void os_invalidate(os_vm_address_t addr, os_vm_size_t len)
{
if(munmap((void*) addr, len) == -1)
perror("munmap");
\f
-os_vm_address_t
+os_vm_address_t
os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len)
{
}
}
-static boolean
-in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen)
+static boolean in_range_p(os_vm_address_t a, lispobj sbeg, size_t slen)
{
char* beg = (char*) sbeg;
char* end = (char*) sbeg + slen;
return (adr >= beg && adr < end);
}
-boolean
-is_valid_lisp_addr(os_vm_address_t addr)
+boolean is_valid_lisp_addr(os_vm_address_t addr)
{
- /* Just assume address is valid if it lies within one of the known
+ /* Old CMUCL comment:
+
+ Just assume address is valid if it lies within one of the known
spaces. (Unlike sunos-os which keeps track of every valid page.) */
return ( in_range_p(addr, READ_ONLY_SPACE_START, READ_ONLY_SPACE_SIZE)
|| in_range_p(addr, STATIC_SPACE_START , STATIC_SPACE_SIZE )
;;; for internal versions, especially for internal versions off the
;;; main CVS branch, it gets hairier, e.g. "0.pre7.14.flaky4.13".)
-"0.7.3.10"
+"0.7.3.11"