From c159b7a71f76ada52ffe743b3b249b4b2420c2c7 Mon Sep 17 00:00:00 2001
From: hallgren <hallgren>
Date: Tue, 27 Jul 1993 16:02:04 +0000
Subject: [PATCH] Initial revision

---
 lisp/hpux-os.c | 348 +++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 348 insertions(+)
 create mode 100644 lisp/hpux-os.c

diff --git a/lisp/hpux-os.c b/lisp/hpux-os.c
new file mode 100644
index 000000000..73459276e
--- /dev/null
+++ b/lisp/hpux-os.c
@@ -0,0 +1,348 @@
+/*
+ * $Header: /Volumes/share2/src/cmucl/cvs2git/cvsroot/src/lisp/hpux-os.c,v 1.1 1993/07/27 16:02:04 hallgren Exp $
+ *
+ * OS-dependent routines.  This file (along with os.h) exports an
+ * OS-independent interface to the operating system VM facilities.
+ * Suprisingly, this interface looks a lot like the Mach interface
+ * (but simpler in some places).  For some operating systems, a subset
+ * of these functions will have to be emulated.
+ *
+ */
+
+/* Assumptions these routines are based on:
+os_validate: Not called with NULL for an addr.
+os_invalidate: Never called.
+os_map: Files are only mapped at the beginning of one of the areas passed
+	to os_validate.
+os_protect: Only called on an entire region when giving permissions and only
+	    called from some point in a segment to the end of the segment
+	    when removing them.
+	    Only called with all protections or no protections.
+os_zero: Only ever zeroed from some point in a segment to the end of the
+	 segment.
+os_allocate_at: Calls to here are disjoint from those around it (the others
+	in os-common.c) since it calls os_validate and the others (in 
+	os-common.c) use malloc, etc.
+Note that os_validate does not actually allocate memory until it has to map
+the particular section in.
+*/
+
+/* #define DEBUG */
+
+#include <stdio.h>
+#include <assert.h>
+#include <signal.h>
+#include <sys/file.h>
+#include <unistd.h>
+#include "os.h"
+#include <sys/resource.h>
+#include "interrupt.h"
+#include <netdb.h>
+
+os_vm_size_t os_vm_page_size=(-1);
+
+#define MAX_SEGMENTS 20
+#define ALLOC_SIZE 0x10000   
+static struct segment {
+  os_vm_address_t base;
+  os_vm_size_t len;
+  os_vm_address_t valid;
+  os_vm_address_t protected;
+} segments[MAX_SEGMENTS];
+
+void
+os_init()
+{
+  int i;
+  os_vm_page_size=sysconf(_SC_PAGE_SIZE);
+  for(i=0;i<MAX_SEGMENTS;i++)
+    segments[i].len=0;
+}
+
+
+os_vm_address_t
+os_validate(os_vm_address_t addr, os_vm_size_t len)
+{
+  int fd,i;
+  caddr_t ret;
+
+  addr=os_trunc_to_page(addr);
+  len=os_round_up_size_to_page(len);
+
+#ifdef DEBUG
+  printf("os_validate: addr: 0x%X, len: 0x%X, end: 0x%X\n",addr,len,addr+len);
+#endif  
+  assert(addr!=NULL);
+  assert(len!=0);
+
+  for(i=0;i<MAX_SEGMENTS;i++)
+    if(segments[i].len==0) break;
+
+  assert(i!=MAX_SEGMENTS);
+
+  segments[i].base=addr;
+  segments[i].len=len;
+  segments[i].valid=addr;
+  segments[i].protected=addr+len;
+  return addr;
+}
+
+void
+os_invalidate(os_vm_address_t addr, os_vm_size_t len)
+{
+  assert(FALSE);
+}
+
+os_vm_address_t
+os_map(int fd, int offset, os_vm_address_t addr, os_vm_size_t len)
+{
+  int i;
+
+  addr=os_trunc_to_page(addr);
+  len=os_round_up_size_to_page(len);
+
+  if(mmap(addr,len,OS_VM_PROT_ALL,MAP_FILE|MAP_FIXED|MAP_PRIVATE,fd,
+	  (off_t)offset) == (os_vm_address_t)-1) {
+    perror("mmap");
+    return NULL;
+  }
+
+  for(i=0;i<MAX_SEGMENTS;i++)
+    if(segments[i].len!=0 && segments[i].base==addr) break;
+
+  assert(i!=MAX_SEGMENTS);
+  assert(segments[i].valid==addr);
+
+  segments[i].valid=addr+len;
+#ifdef DEBUG
+  printf("os_map: addr: 0x%X, len: 0x%X, end: 0x%X\n",addr,len,addr+len);
+#endif
+  return addr;
+}
+
+void
+os_flush_icache(os_vm_address_t address, os_vm_size_t length)
+{
+  sanctify_for_execution(address,length);
+}
+
+void
+os_protect(os_vm_address_t addr, os_vm_size_t len, os_vm_prot_t prot)
+{
+  int i;
+  addr=os_trunc_to_page(addr);
+  len=os_round_up_size_to_page(len);
+
+  for(i=0;i<MAX_SEGMENTS;i++)
+    if(segments[i].base<=addr && addr<segments[i].base+segments[i].len)
+      break;
+
+  assert(i!=MAX_SEGMENTS);
+
+  if(prot) {
+    assert(segments[i].base==addr && segments[i].len==len);
+    segments[i].protected=addr+len;
+  } else {
+    assert(segments[i].protected==addr+len);
+    segments[i].protected=addr;
+  }
+
+  if(addr<segments[i].valid)
+    if(mprotect(addr,segments[i].valid-addr,prot) == -1) {
+      perror("mprotect");
+      printf("segments[i].base: 0x%X\n",segments[i].base);
+      printf("segments[i].len: 0x%X\n",segments[i].len);
+      printf("segments[i].valid: 0x%X\n",segments[i].valid);
+      printf("addr: 0x%X, segments[i].valid-addr: 0x%X\n",addr,
+	     segments[i].valid-addr);
+      printf("prot: 0x%X, len 0x%X\n",prot,len);
+      assert(FALSE);
+    }
+#ifdef DEBUG
+  printf("os_protect: addr: 0x%X, len: 0x%X, end: 0x%X, prot 0x%X\n",
+	 addr,len,addr+len,prot);
+#endif
+}
+
+boolean
+valid_addr(os_vm_address_t addr)
+{
+  int i;
+
+  for(i=0;i<MAX_SEGMENTS;i++)
+    if(segments[i].base<=addr && addr<segments[i].base+segments[i].len)
+      return TRUE;
+  return FALSE;
+}
+
+void
+segv_handler(int signal, int code, struct sigcontext *context)
+{
+  int i;
+  os_vm_address_t addr,nvalid;
+  sigsetmask(BLOCKABLE);
+
+  addr=(os_vm_address_t)context->sc_sl.sl_ss.ss_cr21;  /* verify this!!! */
+  for(i=0;i<MAX_SEGMENTS;i++)
+    if(segments[i].len!=0 && segments[i].base<=addr &&
+       addr<segments[i].base+segments[i].len)
+      break;
+  if(i==MAX_SEGMENTS || addr<segments[i].valid)
+    interrupt_handle_now(signal,code,context);
+  else if(segments[i].protected<=addr) {
+    if(!interrupt_maybe_gc(signal,code,context))
+      interrupt_handle_now(signal,code,context);
+  } else {
+    nvalid=((os_vm_address_t)(((long)(addr+ALLOC_SIZE))&~((long)(ALLOC_SIZE-1))));
+    if(nvalid>segments[i].protected) nvalid=segments[i].protected;
+
+#ifdef DEBUG
+    printf("Mapping: addr: 0x%08x, old: 0x%08x, new: 0x%08x\n",
+	   addr,segments[i].valid,nvalid);
+#endif
+
+    if(mmap(segments[i].valid,nvalid-segments[i].valid,
+	    OS_VM_PROT_ALL,MAP_ANONYMOUS|MAP_FIXED|MAP_PRIVATE,-1,0) == 
+       (os_vm_address_t)-1) {
+      perror("mmap");
+      printf("segments[i].base: 0x%X\n",segments[i].base);
+      printf("segments[i].len: 0x%X\n",segments[i].len);
+      printf("segments[i].valid: 0x%X\n",segments[i].valid);
+      printf("segments[i].protected: 0x%X\n",segments[i].protected);
+      printf("nvalid: 0x%X\n",nvalid);
+      printf("nvalid-segments[i].valid: 0x%X\n",nvalid-segments[i].valid);
+      assert(FALSE);
+    }
+    segments[i].valid=nvalid;
+  }
+}
+
+void
+sigbus_handler(int signal, int code, struct sigcontext *context)
+{
+#ifdef DEBUG
+  printf("Bus Error at 0x%X\n",context->sc_sl.sl_ss.ss_cr21);
+#endif
+
+  if(!interrupt_maybe_gc(signal, code, context))
+    interrupt_handle_now(signal, code, context);
+}
+
+void
+os_install_interrupt_handlers()
+{
+  interrupt_install_low_level_handler(SIGSEGV,segv_handler);
+  interrupt_install_low_level_handler(SIGBUS,sigbus_handler);
+}
+
+void
+os_zero(os_vm_address_t addr,os_vm_size_t length)
+{
+    os_vm_address_t block_start;
+    os_vm_size_t block_size;
+    int i;
+
+#ifdef DEBUG
+    fprintf(stderr,"os_zero: addr: 0x%08x, len: 0x%08x, end: 0x%X\n",addr,
+	    length,addr+length);
+#endif
+
+    block_start=os_round_up_to_page(addr);
+
+    length-=block_start-addr;
+    block_size=os_trunc_size_to_page(length);
+
+    if(block_start>addr)
+      bzero((char *)addr,block_start-addr);
+    if(block_size<length)
+      assert(FALSE);
+    
+    if (block_size != 0) {
+	/* Now deallocate and allocate the block so that it */
+	/* faults in  zero-filled. */
+
+        for(i=0;i<MAX_SEGMENTS;i++)
+          if(segments[i].base<=block_start && 
+             block_start<segments[i].base+segments[i].len)
+            break;
+        assert(i!=MAX_SEGMENTS);
+        assert(block_start+block_size==segments[i].base+segments[i].len);
+
+	if(segments[i].valid>block_start) {
+          if(munmap(block_start,segments[i].valid-block_start)==-1) {
+            perror("munmap");
+	    return;
+	  }
+	  segments[i].valid=block_start;
+	}
+    }
+}
+
+os_vm_address_t
+os_allocate(os_vm_size_t len)
+{
+  return (os_vm_address_t) malloc(len);
+}
+
+os_vm_address_t
+os_allocate_at(os_vm_address_t addr, os_vm_size_t len)
+{
+  return os_validate(addr, len);
+}
+
+void
+os_deallocate(os_vm_address_t addr,os_vm_size_t len)
+{
+  free(addr);
+}
+
+os_vm_address_t
+os_reallocate(os_vm_address_t addr, os_vm_size_t old_len,
+			      os_vm_size_t len)
+{
+  addr=(os_vm_address_t) realloc(addr,len);
+  assert(addr!=NULL);
+  return addr;
+}
+
+void
+getrusage(int who,struct rusage *rusage)
+{
+  bzero(rusage,sizeof(struct rusage));
+}
+
+int
+getdtablesize(void)
+{
+  struct rlimit rlp;
+  assert(getrlimit(RLIMIT_NOFILE,&rlp)==0);
+  return rlp.rlim_cur;
+}
+
+unsigned long
+gethostid(void)
+{
+  char hostname[256];
+  struct hostent *hostent;
+  static unsigned long addr=NULL;
+
+  if(addr) return addr;
+
+  if(gethostname(hostname, sizeof(hostname)) == -1) {
+    perror("gethostname");
+    return 0;
+  }
+
+  hostent = gethostbyname(hostname);
+  if(hostent == NULL) {
+    perror("gethostbyname");
+    return 0;
+  }
+
+  addr = ((unsigned char *)(hostent->h_addr))[0] << 24 |
+         ((unsigned char *)(hostent->h_addr))[1] << 16 |
+         ((unsigned char *)(hostent->h_addr))[2] << 8 |
+	 ((unsigned char *)(hostent->h_addr))[3];
+
+  return addr;
+}
-- 
GitLab