1*219b2ee8SDavid du Colombier #define _LOCK_EXTENSION 2*219b2ee8SDavid du Colombier #include <stdlib.h> 3*219b2ee8SDavid du Colombier #include <string.h> 4*219b2ee8SDavid du Colombier #include "../plan9/sys9.h" 5*219b2ee8SDavid du Colombier #include <lock.h> 6*219b2ee8SDavid du Colombier 7*219b2ee8SDavid du Colombier enum 8*219b2ee8SDavid du Colombier { 9*219b2ee8SDavid du Colombier Pagesize = 4096, 10*219b2ee8SDavid du Colombier Semperpg = Pagesize/(16*sizeof(unsigned int)), 11*219b2ee8SDavid du Colombier Lockaddr = 0x60000000, 12*219b2ee8SDavid du Colombier 13*219b2ee8SDavid du Colombier POWER = 0x320, 14*219b2ee8SDavid du Colombier MAGNUM = 0x330, 15*219b2ee8SDavid du Colombier MAGNUMII = 0x340, 16*219b2ee8SDavid du Colombier R4K = 0x500, 17*219b2ee8SDavid du Colombier }; 18*219b2ee8SDavid du Colombier 19*219b2ee8SDavid du Colombier static int arch; 20*219b2ee8SDavid du Colombier extern int C_3ktas(int*); 21*219b2ee8SDavid du Colombier extern int C_4ktas(int*); 22*219b2ee8SDavid du Colombier extern int C_fcr0(void); 23*219b2ee8SDavid du Colombier 24*219b2ee8SDavid du Colombier void 25*219b2ee8SDavid du Colombier lockinit() 26*219b2ee8SDavid du Colombier { 27*219b2ee8SDavid du Colombier int n; 28*219b2ee8SDavid du Colombier 29*219b2ee8SDavid du Colombier arch = C_fcr0(); 30*219b2ee8SDavid du Colombier switch(arch) { 31*219b2ee8SDavid du Colombier case POWER: 32*219b2ee8SDavid du Colombier n = _SEGATTACH(0, "lock", (void*)Lockaddr, Pagesize); 33*219b2ee8SDavid du Colombier if(n < 0) { 34*219b2ee8SDavid du Colombier arch = MAGNUM; 35*219b2ee8SDavid du Colombier break; 36*219b2ee8SDavid du Colombier } 37*219b2ee8SDavid du Colombier memset((void*)Lockaddr, 0, Pagesize); 38*219b2ee8SDavid du Colombier break; 39*219b2ee8SDavid du Colombier case MAGNUM: 40*219b2ee8SDavid du Colombier case MAGNUMII: 41*219b2ee8SDavid du Colombier case R4K: 42*219b2ee8SDavid du Colombier break; 43*219b2ee8SDavid du Colombier default: 44*219b2ee8SDavid du Colombier abort(); 45*219b2ee8SDavid du Colombier } 46*219b2ee8SDavid du Colombier 47*219b2ee8SDavid du Colombier } 48*219b2ee8SDavid du Colombier 49*219b2ee8SDavid du Colombier void 50*219b2ee8SDavid du Colombier lock(Lock *lk) 51*219b2ee8SDavid du Colombier { 52*219b2ee8SDavid du Colombier int *hwsem; 53*219b2ee8SDavid du Colombier int hash; 54*219b2ee8SDavid du Colombier 55*219b2ee8SDavid du Colombier switch(arch) { 56*219b2ee8SDavid du Colombier case MAGNUM: 57*219b2ee8SDavid du Colombier case MAGNUMII: 58*219b2ee8SDavid du Colombier while(C_3ktas(&lk->val)) 59*219b2ee8SDavid du Colombier _SLEEP(0); 60*219b2ee8SDavid du Colombier return; 61*219b2ee8SDavid du Colombier case R4K: 62*219b2ee8SDavid du Colombier for(;;){ 63*219b2ee8SDavid du Colombier while(lk->val) 64*219b2ee8SDavid du Colombier ; 65*219b2ee8SDavid du Colombier if(C_4ktas(&lk->val) == 0) 66*219b2ee8SDavid du Colombier return; 67*219b2ee8SDavid du Colombier } 68*219b2ee8SDavid du Colombier break; 69*219b2ee8SDavid du Colombier case POWER: 70*219b2ee8SDavid du Colombier /* Use low order lock bits to generate hash */ 71*219b2ee8SDavid du Colombier hash = ((int)lk/sizeof(int)) & (Semperpg-1); 72*219b2ee8SDavid du Colombier hwsem = (int*)Lockaddr+hash; 73*219b2ee8SDavid du Colombier 74*219b2ee8SDavid du Colombier for(;;) { 75*219b2ee8SDavid du Colombier if((*hwsem & 1) == 0) { 76*219b2ee8SDavid du Colombier if(lk->val) 77*219b2ee8SDavid du Colombier *hwsem = 0; 78*219b2ee8SDavid du Colombier else { 79*219b2ee8SDavid du Colombier lk->val = 1; 80*219b2ee8SDavid du Colombier *hwsem = 0; 81*219b2ee8SDavid du Colombier return; 82*219b2ee8SDavid du Colombier } 83*219b2ee8SDavid du Colombier } 84*219b2ee8SDavid du Colombier while(lk->val) 85*219b2ee8SDavid du Colombier ; 86*219b2ee8SDavid du Colombier } 87*219b2ee8SDavid du Colombier } 88*219b2ee8SDavid du Colombier } 89*219b2ee8SDavid du Colombier 90*219b2ee8SDavid du Colombier int 91*219b2ee8SDavid du Colombier canlock(Lock *lk) 92*219b2ee8SDavid du Colombier { 93*219b2ee8SDavid du Colombier int *hwsem; 94*219b2ee8SDavid du Colombier int hash; 95*219b2ee8SDavid du Colombier 96*219b2ee8SDavid du Colombier switch(arch) { 97*219b2ee8SDavid du Colombier case MAGNUM: 98*219b2ee8SDavid du Colombier case MAGNUMII: 99*219b2ee8SDavid du Colombier if(C_3ktas(&lk->val)) 100*219b2ee8SDavid du Colombier return 0; 101*219b2ee8SDavid du Colombier return 1; 102*219b2ee8SDavid du Colombier case R4K: 103*219b2ee8SDavid du Colombier if(C_4ktas(&lk->val)) 104*219b2ee8SDavid du Colombier return 0; 105*219b2ee8SDavid du Colombier return 1; 106*219b2ee8SDavid du Colombier case POWER: 107*219b2ee8SDavid du Colombier /* Use low order lock bits to generate hash */ 108*219b2ee8SDavid du Colombier hash = ((int)lk/sizeof(int)) & (Semperpg-1); 109*219b2ee8SDavid du Colombier hwsem = (int*)Lockaddr+hash; 110*219b2ee8SDavid du Colombier 111*219b2ee8SDavid du Colombier if((*hwsem & 1) == 0) { 112*219b2ee8SDavid du Colombier if(lk->val) 113*219b2ee8SDavid du Colombier *hwsem = 0; 114*219b2ee8SDavid du Colombier else { 115*219b2ee8SDavid du Colombier lk->val = 1; 116*219b2ee8SDavid du Colombier *hwsem = 0; 117*219b2ee8SDavid du Colombier return 1; 118*219b2ee8SDavid du Colombier } 119*219b2ee8SDavid du Colombier } 120*219b2ee8SDavid du Colombier return 0; 121*219b2ee8SDavid du Colombier } 122*219b2ee8SDavid du Colombier } 123*219b2ee8SDavid du Colombier 124*219b2ee8SDavid du Colombier void 125*219b2ee8SDavid du Colombier unlock(Lock *lk) 126*219b2ee8SDavid du Colombier { 127*219b2ee8SDavid du Colombier lk->val = 0; 128*219b2ee8SDavid du Colombier } 129