6a4d43e1e209641975fb251180b78c143622e315
/* Awriteable.c 1.2 90/12/04 */
long writeable(infop
, address
, length
)
* Return TRUE (= -1) if the specified bytes can be written without an access
* control violation (limit and/or protection). Page faults are OK.
* If problems, return the code that would be pushed by HW on the
* stack (see the architecture manual).
* Assumption is that in most cases, access is OK, so a quick 'probew'
* will be enough. If not, we have to work harder to determine the exact
* cause and return the right code, without getting the fault here in
* The address is assumed to be write for the user.!
register long Register_12
; /* Has to be first reg ! */
register long Register_11
;
register long Register_10
;
register long Register_9
;
register long Register_8
;
asm (" probew $1,(r12),$1 "); /* Yeach ... */
asm (" beql no_access ");
asm (" addl2 r11,r12 "); /* last byte */
asm (" probew $1,(r12),$1 ");
asm (" beql no_access ");
asm (" movl $-1,r0 "); /* TRUE */
* Now the hard work. Have to check length violation first.
* If any byte (first or last) causes a length violation, report it as such.
asm (" mfpr $3,r8 "); /* Get length registers. P0LR */
asm (" mfpr $5,r9 "); /* P1LR */
asm (" mfpr $7,r10 "); /* P2LR */
asm (" mfpr $1,r11 "); /* SLR */
subspace
= (address
>> 30) & 3;
Register_12
= (address
>> 10) & 0xfffff; /* 1'st byte page # */
last_page
= ( (address
+length
-1) >> 10) & 0xfffff;
if ( (Register_12
>= Register_8
) ||
(last_page
>= Register_8
) ) return (1);
if ( (Register_12
>= Register_9
) ||
(last_page
>= Register_9
) ) return (1);
if ( (Register_12
< Register_10
) ||
(last_page
< Register_10
) ) return (1);
if ( (Register_12
>= Register_11
) ||
(last_page
>= Register_11
) ) return (1);
* OK, it's not a length violation. Must have been an access problem
* NOTE : I definitely ignore the case of 'no PTE access' since I
* assume that's not the case for user mode. Besides, the poor
* guy will just get an access violation that will most probably
* send him into hyperspace anyway, so no need to be too acurate here.