|
|
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.