|
|
1.1 root 1: /* Awriteable.c 1.1 86/07/20 */
2:
3: #include "../tahoealign/align.h"
4:
5: long writeable(infop, address, length)
6: process_info *infop;
7: long address, length;
8: /*
9: * Return TRUE (= -1) if the specified bytes can be written without an access
10: * control violation (limit and/or protection). Page faults are OK.
11: * If problems, return the code that would be pushed by HW on the
12: * stack (see the architecture manual).
13: * Assumption is that in most cases, access is OK, so a quick 'probew'
14: * will be enough. If not, we have to work harder to determine the exact
15: * cause and return the right code, without getting the fault here in
16: * the kernel !!.
17: *
18: * The address is assumed to be write for the user.!
19: */
20: {
21: register long Register_12; /* Has to be first reg ! */
22: register long Register_11;
23: register long Register_10;
24: register long Register_9;
25: register long Register_8;
26: register long subspace;
27: register long last_page;
28:
29: Register_12 = address;
30: Register_11 = length-1;
31: asm (" probew $1,(r12),$1 "); /* Yeach ... */
32: asm (" beql no_access ");
33: asm (" addl2 r11,r12 "); /* last byte */
34: asm (" probew $1,(r12),$1 ");
35: asm (" beql no_access ");
36: asm (" movl $-1,r0 "); /* TRUE */
37: asm (" ret#1 ");
38: asm ("no_access: ");
39: /*
40: * Now the hard work. Have to check length violation first.
41: * If any byte (first or last) causes a length violation, report it as such.
42: */
43: asm (" mfpr $3,r8 "); /* Get length registers. P0LR */
44: asm (" mfpr $5,r9 "); /* P1LR */
45: asm (" mfpr $7,r10 "); /* P2LR */
46: asm (" mfpr $1,r11 "); /* SLR */
47:
48: subspace = (address >> 30) & 3;
49: Register_12 = (address >> 10) & 0xfffff; /* 1'st byte page # */
50: last_page = ( (address+length-1) >> 10) & 0xfffff;
51: switch ( subspace ) {
52: case 0:
53: if ( (Register_12 >= Register_8) ||
54: (last_page >= Register_8) ) return (1);
55: break;
56: case 1:
57: if ( (Register_12 >= Register_9) ||
58: (last_page >= Register_9) ) return (1);
59: break;
60: case 2:
61: if ( (Register_12 < Register_10) ||
62: (last_page < Register_10) ) return (1);
63: break;
64: case 3:
65: if ( (Register_12 >= Register_11) ||
66: (last_page >= Register_11) ) return (1);
67: break;
68: }
69: /*
70: * OK, it's not a length violation. Must have been an access problem
71: * (no write by user).
72: *
73: * NOTE : I definitely ignore the case of 'no PTE access' since I
74: * assume that's not the case for user mode. Besides, the poor
75: * guy will just get an access violation that will most probably
76: * send him into hyperspace anyway, so no need to be too acurate here.
77: */
78: return (4);
79: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.