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);
+ }
------------------------------------------------------------------------------