Subject: obio_probe_byte
To: None <port-sun3@sun-lamp.cs.berkeley.edu>
From: Michael Richardson <mcr@latour.sandelman.ocunix.on.ca>
List: port-sun3
Date: 03/21/1994 01:23:30
  I wasn't sure exactly how to give the page I allocated via
high_segment_alloc(), so I just hung on to it for future use. I
realize I could have decremented high_segment_free_start by one, but
that seemed too messy and intrusive. Is there a "utility" segment
somewhere?
  It isn't clear to me if I can declare an expression "volatile" -- I
don't want to *do* anything with the data that I read. ("I dunno what
I thinks of this, thar newfangled ANGSTSKI C gloop")

===================================================================
RCS file: /src/master/NetBSD/sys/arch/sun3/dev/obio.c,v
retrieving revision 1.2
diff -c -r1.2 obio.c
*** 1.2	1994/03/04 06:27:01
--- obio.c	1994/03/21 05:52:30
***************
*** 32,35 ****
--- 32,37 ----
   */
+ 
+ #include <setjmp.h>
  #include <sys/systm.h>
  #include <sys/device.h>
  
***************
*** 40,45 ****
--- 42,49 ----
  #include <machine/mon.h>
  #include <machine/isr.h>
  
+ extern int *nofault;
+ 
  #define ALL 0xFF
      
  unsigned char *interrupt_reg = NULL;
***************
*** 153,155 ****
--- 157,203 ----
      return (caddr_t) va;
  }
  
+ /*  
+  * Access to empty obio space causes a BERR, which results in
+  *        a longjmp to *nofault if it is non-NULL.
+  */
+ 
+ int
+ obio_probe_byte(oba)
+ 	caddr_t oba;	/* OBIO address to probe */
+ {
+   vm_offset_t high_segment_alloc();
+   static vm_offset_t probe_va=-1;
+   int *old;
+   volatile char *peek;
+   static  foo;
+   jmp_buf obio_probe_buf;
+   int     success;
+ 
+ 
+   if(probe_va==-1) {
+     /* get a page */
+     probe_va=high_segment_alloc(1);
+   }
+ 
+   /* set up the page */
+   set_pte(probe_va,PG_VALID|PG_SYSTEM|MAKE_PGTYPE(PG_OBIO)|PA_PGNUM((vm_offset_t)oba));
+ 
+   peek=(char *)probe_va;
+ 	
+   old=nofault;
+ 
+   if(setjmp(obio_probe_buf)) {
+     /* jump got tripped. Fail */
+     nofault=old;
+     success=1; 
+   }
+   else {
+     nofault=(int *)obio_probe_buf;
+     foo=(*peek);         /* stick it somewhere, to get around optimizer */
+     nofault=old;
+     success=0;
+   }
+   set_pte(probe_va,PG_INVAL);
+   return(success);
+ }
  
  

------------------------------------------------------------------------------