00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include<linux/unistd.h>
00012 #include<linux/linkage.h>
00013 #include<linux/sched.h>
00014 #include<asm/bitops.h>
00015 #include<starlet.h>
00016 #include<ssdef.h>
00017 #include<pridef.h>
00018 #include<statedef.h>
00019 #include<evtdef.h>
00020 #include<ipldef.h>
00021 #include<descrip.h>
00022 #include <system_data_cells.h>
00023 #include <exe_routines.h>
00024 #include <sch_routines.h>
00025 #include <misc_routines.h>
00026 #include <ipl.h>
00027 #include <internals.h>
00028 #include <prvdef.h>
00029
00030
00031
00032 unsigned long maxprocesscnt=MAXPROCESSCNT;
00033
00034
00035
00036
00037
00038
00039 int exe_process_check_priv(struct _pcb * p) {
00040 int priv = ctl_gl_pcb->pcb$l_priv;
00041
00042
00043
00044 if (p != ctl_gl_pcb && (priv & PRV$M_WORLD) == 0) {
00045 return SS__NOPRIV;
00046
00047 }
00048 return SS__NORMAL;
00049 }
00050
00051 int inline process_bit_shift() {
00052 return sch_gl_pixwidth;
00053 }
00054
00055 int inline process_index_mask() {
00056 return (1 << sch_gl_pixwidth)-1;
00057 }
00058
00059 int inline process_seq_mask() {
00060 return 0x1ffff & (~process_index_mask());
00061 }
00062
00063 int alloc_ipid() {
00064 int i;
00065 unsigned long *vec=sch_gl_pcbvec;
00066 unsigned long *seq=sch_gl_seqvec;
00067 for (i=2;i<MAXPROCESSCNT;i++) {
00068 if (vec[i]==0) {
00069 return i| ((seq[i]++)<<16);
00070 }
00071 }
00072 printk(KERN_EMERG "alloc_ipid 0\n");
00073 return 0;
00074 }
00075
00076 void * exe_ipid_to_pcb(unsigned long pid) {
00077 int i;
00078 if ((pid&0xffff)>MAXPROCESSCNT) printk(KERN_EMERG "EXE %x\n",pid);
00079 if ((pid&0xffff)>MAXPROCESSCNT) {
00080 unsigned long * x=&i;
00081 printk(KERN_EMERG "FIND2 %d %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x\n",pid,pid,x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10],x[11],x[12],x[13],x[14],x[15],x[16]);
00082 }
00083 if ((pid&0xffff)>sch_gl_maxpix) return 0;
00084 unsigned long *vec=sch_gl_pcbvec;
00085 if (vec[pid&0xffff] && ((struct _pcb *)vec[pid&0xffff])->pcb_l_pid==pid)
00086 return vec[pid&0xffff];
00087 return 0;
00088 return find_process_by_pid(pid);
00089 }
00090
00091 void * exe_epid_to_pcb(unsigned long pid) {
00092 int ipid=exe_epid_to_ipid(pid);
00093 if (ipid) return exe_ipid_to_pcb(ipid);
00094 return 0;
00095 }
00096 extern long csid;
00097 int exe_epid_to_ipid(unsigned long pid) {
00098 if (pid == INIT_PID_REAL) return INIT_PID;
00099 unsigned long *vec=sch_gl_pcbvec;
00100 long mask = process_index_mask();
00101 struct _pcb * p;
00102 if ((csid&0xff)==(pid>>21)) {
00103 int ipid=(pid&mask)|(((pid&0x1ffff)>>process_bit_shift())<<16);
00104 if (vec[ipid&0xffff] && ((struct _pcb *)vec[ipid&0xffff])->pcb_l_pid==ipid)
00105 { } else {
00106 if (vec[ipid&0xffff])
00107 printk(KERN_EMERG "panic? ipid %x %x %x %x\n",pid,ipid,((struct _pcb *)vec[ipid&0xffff])->pcb_l_pid,((struct _pcb *)vec[ipid&0xffff])->pcb$l_epid);
00108 else
00109 printk(KERN_EMERG "panic? no vec ipid %x %x %x %x\n",pid,ipid,vec[ipid&0xffff],0);
00110 }
00111 return ipid;
00112 }
00113 if ((pid&0xfffe0000))
00114 return 0;
00115 return 0;
00116 p = find_process_by_pid(pid);
00117 if (p) return p->pcb_l_pid;
00118 return 0;
00119 }
00120
00121 int exe_ipid_to_epid(unsigned long pid) {
00122 int i;
00123 unsigned long *vec=sch_gl_pcbvec;
00124 unsigned long *seq=sch_gl_seqvec;
00125 long shift = process_bit_shift();
00126 long mask = process_index_mask();
00127 long seqno = seq[pid&0xffff]-1;
00128 return ((csid&0xff)<<21) | (seqno<<shift) | (pid&0xffff);
00129 }
00130
00131 int exe_a_pid_to_ipid(unsigned long pid) {
00132 int i;
00133 unsigned long *vec=sch_gl_pcbvec;
00134 unsigned long *seq=sch_gl_seqvec;
00135 long shift = process_bit_shift();
00136 long mask = process_index_mask();
00137 long seqno = seq[pid&0xffff]-1;
00138 return ((csid&0xff)<<21) | (seqno<<shift) | (pid&0xffff);
00139 }
00140
00141 #if 0
00142 long fixi=0;
00143 long fixs[1024];
00144 #endif
00145
00146
00147
00148
00149
00150 void fixup_hib_pc(void * dummy) {
00151 #ifdef __i386__
00152 char ** addr = dummy + 0x28;
00153 (*addr)-=7;
00154 #else
00155 char ** addr = dummy + 0xa0;
00156 #if 0
00157 fixs[fixi++]=addr;
00158 fixs[fixi++]=*addr;
00159 if(fixi>1000)fixi=0;
00160 #endif
00161 (*addr)-=9;
00162 #endif
00163 }
00164
00165
00166
00167
00168
00169 asmlinkage int exe_hiber(long dummy) {
00170
00171 #ifdef __x86_64__
00172 __asm__ __volatile__ ("movq %%rsp,%0; ":"=r" (dummy) );
00173 #endif
00174
00175 struct _pcb * p=current;
00176 vmslock(&SPIN_SCHED,IPL__SCHED);
00177 #if 0
00178 if (p->pcb_l_sts & PCB$M_WAKEPEN) {
00179 p->pcb_l_sts&=~PCB$M_WAKEPEN;
00180 }
00181 #endif
00182
00183
00184 if (test_and_clear_bit(12,&p->pcb_l_sts)) {
00185
00186
00187 vmsunlock(&SPIN_SCHED,IPL__ASTDEL);
00188
00189 setipl(0);
00190 return SS__NORMAL;
00191 }
00192
00193
00194
00195 #ifdef __i386__
00196 fixup_hib_pc(&dummy);
00197 #else
00198 fixup_hib_pc(dummy-0x10);
00199 #endif
00200
00201 int ret = sch_wait(p,sch$gq_hibwq);
00202 setipl(0);
00203 return ret;
00204 }
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 int exe_nampid(struct _pcb *p, unsigned long *pidadr, void *prcnam, struct _pcb ** retpcb, unsigned long * retipid, unsigned long *retepid) {
00218 int sts = SS__NORMAL;
00219 int ipid = 0;
00220 unsigned long *vec=sch_gl_pcbvec;
00221
00222
00223
00224 vmslock(&SPIN_SCHED,IPL__SCHED);
00225 *retpcb=0;
00226 *retipid=0;
00227 *retepid=0;
00228 if (pidadr==0 && prcnam==0) {
00229 *retipid=p->pcb_l_pid;
00230 *retepid=p->pcb_l_epid;
00231 *retpcb=p;
00232 return SS__NORMAL;
00233 }
00234
00235 if (pidadr && *pidadr) {
00236 ipid=exe_epid_to_ipid(*pidadr);
00237
00238 if (ipid==0 && is_cluster_on())
00239 return SS__REMOTE_PROC;
00240
00241 if (ipid == 0)
00242 goto not_found;
00243
00244 sts = exe_process_check_priv (vec[ipid&0xffff]);
00245 if ((sts & 1) == 0)
00246 goto error;
00247 *retipid=ipid;
00248 *retpcb=vec[ipid&0xffff];
00249 *retepid=*pidadr;
00250 return SS__NORMAL;
00251 }
00252
00253 if (prcnam) {
00254 int i;
00255 struct dsc_descriptor * d = prcnam;
00256
00257
00258
00259
00260 for (i=2;i<MAXPROCESSCNT;i++) {
00261 if (vec[i]!=0) {
00262 struct _pcb * p=vec[i];
00263 if (strncmp(d->dsc_a_pointer,p->pcb$t_lname,d->dsc$w_length)==0) {
00264
00265 sts = exe_process_check_priv (vec[ipid&0xffff]);
00266 if ((sts & 1) == 0)
00267 goto error;
00268 *retipid=vec[i];
00269 *retpcb=p;
00270 return SS__NORMAL;
00271 }
00272 }
00273
00274 }
00275 goto not_found;
00276 return SS__NORMAL;
00277 }
00278
00279
00280 not_found:
00281 vmsunlock(&SPIN_SCHED,IPL__ASTDEL);
00282 return 0;
00283 error:
00284 vmsunlock(&SPIN_SCHED,IPL__ASTDEL);
00285 return sts;
00286 }
00287
00288 #if 0
00289
00290 void * exe_nampid2(struct _pcb *p, unsigned long *pidadr, void *prcnam) {
00291
00292 vmslock(&SPIN_SCHED,IPL__SCHED);
00293 if (pidadr==0 && prcnam==0) {
00294 return p;
00295 }
00296 if (pidadr) {
00297 struct _pcb * tmp, **htable = &pidhash[pid_hashfn(*pidadr)];
00298
00299 for(tmp = *htable; tmp && tmp->pid != *pidadr; tmp = tmp->pidhash_next) ;
00300
00301 return tmp;
00302 }
00303 if (prcnam) {
00304
00305 return;
00306 }
00307
00308 vmsunlock(&SPIN_SCHED,IPL__ASTDEL);
00309 return 0;
00310 }
00311 #endif
00312
00313
00314
00315
00316
00317 asmlinkage int exe_wake(unsigned long *pidadr, void *prcnam) {
00318 struct _pcb * retpcb, *p;
00319 unsigned long retipid, retepid;
00320
00321 int sts=exe_nampid(current,pidadr,prcnam,&retpcb,&retipid,&retepid);
00322 p=retpcb;
00323 if (p) {
00324
00325
00326 sch_wake(p->pcb$l_pid);
00327
00328 vmsunlock(&SPIN_SCHED,IPL__ASTDEL);
00329 return;
00330 }
00331
00332 setipl(0);
00333 }
00334
00335
00336
00337
00338
00339 asmlinkage int exe_suspnd(unsigned int *pidadr, void *prcnam, unsigned int flags ) {
00340
00341 }
00342
00343
00344
00345
00346
00347 asmlinkage int exe_resume (unsigned int *pidadr, void *prcnam) {
00348 struct _pcb * retpcb, *p;
00349 unsigned long retipid, retepid;
00350
00351 int sts=exe_nampid(current,pidadr,prcnam,&retpcb,&retipid,&retepid);
00352 p=retpcb;
00353
00354 vmsunlock(&SPIN_SCHED,0);
00355 if (p) {
00356
00357
00358 sch_rse(p,PRI$_RESAVL,EVT$_RESUME);
00359 return;
00360 }
00361
00362 return SS__NORMAL;
00363 }
00364
00365
00366
00367
00368
00369
00370
00371 asmlinkage int exe_setprn(struct dsc$descriptor *s) {
00372 struct _pcb *p=0;
00373
00374 if (!p) p=current;
00375 p=current;
00376
00377 strncpy(p->pcb_t_lname,s->dsc$a_pointer,s->dsc$w_length);
00378 p->pcb_t_lname[s->dsc$w_length]=0;
00379 return SS__NORMAL;
00380 }
00381
00382 inline void *find_task_by_pid(int pid) {
00383 int tsk;
00384 tsk=exe_ipid_to_pcb(pid);
00385 if (tsk) return tsk;
00386 long *x=&tsk;
00387 printk(KERN_EMERG "FIND %d %x %x %x %x %x %x %x %x %x %x\n",pid,pid,x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8]);
00388 return 0;
00389 }
00390