home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 3 / hamradioversion3.0examsandprograms1992.iso / packet / n17jsrc / ksubr.c < prev    next >
C/C++ Source or Header  |  1991-02-09  |  7KB  |  257 lines

  1. /* Machine or compiler-dependent portions of kernel
  2.  * Turbo-C version for PC
  3.  * Copyright 1991 Phil Karn, KA9Q
  4.  */
  5. #include <stdio.h>
  6. #include <dos.h>
  7. #include "global.h"
  8. #include "proc.h"
  9. #include "pc.h"
  10. #include "commands.h"
  11.  
  12. static char *Taskers[] = {
  13.     "",
  14.     "DoubleDos",
  15.     "DesqView",
  16.     "Windows",
  17. };
  18.  
  19.  
  20. static oldNull;
  21.  
  22. /* Template for contents of jmp_buf in Turbo C */
  23. struct env {
  24.     unsigned    sp;
  25.     unsigned    ss;
  26.     unsigned    flag;
  27.     unsigned    cs;
  28.     unsigned    ip;
  29.     unsigned    bp;
  30.     unsigned    di;
  31.     unsigned    es;
  32.     unsigned    si;
  33.     unsigned    ds;
  34. };
  35.  
  36. static int chkintstk __ARGS((void));
  37. static int stkutil __ARGS((struct proc *pp));
  38.  
  39. void
  40. kinit()
  41. {
  42.     int i;
  43.  
  44.     /* Initialize interrupt stack for high-water-mark checking */
  45.     for(i=0;i<512;i++)
  46.         Intstk[i] = STACKPAT;
  47.  
  48.     /* Remember location 0 pattern to detect null pointer derefs */
  49.     oldNull = *(unsigned short *)NULL;
  50.  
  51. }
  52. /* Print process table info
  53.  * Since things can change while ps is running, the ready proceses are
  54.  * displayed last. This is because an interrupt can make a process ready,
  55.  * but a ready process won't spontaneously become unready. Therefore a
  56.  * process that changes during ps may show up twice, but this is better
  57.  * than not having it showing up at all.
  58.  */
  59. int
  60. ps(argc,argv,p)
  61. int argc;
  62. char *argv[];
  63. void *p;
  64. {
  65.     register struct proc *pp;
  66.     register struct env *ep;
  67.     int i;
  68.  
  69.     tprintf("Uptime %s Stack %x max intstk %u",tformat(secclock()),
  70.         getss(),chkintstk());
  71.     if(Mtasker != 0){
  72.         tprintf(" Running under %s",Taskers[Mtasker]);
  73.     }
  74.     tprintf("\n");
  75.  
  76.     tprintf("PID       SP        stksize   maxstk    event     fl  in  out  name\n");
  77.  
  78.     for(pp = Susptab;pp != NULLPROC;pp = pp->next){
  79.         ep = (struct env *)&pp->env;
  80.         if(tprintf("%-10lx%-10lx%-10u%-10u%-10lx%c%c%c %3d %3d  %s\n",
  81.          ptol(pp),
  82.          ptol(MK_FP(ep->ss,ep->sp)),
  83.          pp->stksize,
  84.          stkutil(pp),
  85.          ptol(pp->event),
  86.          pp->i_state ? 'I' : ' ',
  87.          (pp->state & WAITING) ? 'W' : ' ',
  88.          (pp->state & SUSPEND) ? 'S' : ' ',
  89.          pp->input, pp->output,
  90.          pp->name) == EOF)
  91.             return 0;
  92.     }
  93.     for(i=0;i<PHASH;i++){
  94.         for(pp = Waittab[i];pp != NULLPROC;pp = pp->next){
  95.             ep = (struct env *)&pp->env;
  96.             if(tprintf("%-10lx%-10lx%-10u%-10u%-10lx%c%c%c %2d %2d  %s\n",
  97.              ptol(pp),ptol(MK_FP(ep->ss,ep->sp)),pp->stksize,stkutil(pp),
  98.              ptol(pp->event),
  99.              pp->i_state ? 'I' : ' ',
  100.              (pp->state & WAITING) ? 'W' : ' ',
  101.              (pp->state & SUSPEND) ? 'S' : ' ',
  102.              pp->input,pp->output,
  103.              pp->name) == EOF)
  104.                 return 0;
  105.         }
  106.     }
  107.     for(pp = Rdytab;pp != NULLPROC;pp = pp->next){
  108.         ep = (struct env *)&pp->env;
  109.         if(tprintf("%-10lx%-10lx%-10u%-10u          %c%c%c %2d %2d  %s\n",
  110.          ptol(pp),ptol(MK_FP(ep->ss,ep->sp)),pp->stksize,stkutil(pp),
  111.          pp->i_state ? 'I' : ' ',
  112.          (pp->state & WAITING) ? 'W' : ' ',
  113.          (pp->state & SUSPEND) ? 'S' : ' ',
  114.          pp->input,pp->output,
  115.          pp->name) == EOF)
  116.             return 0;
  117.     }
  118.     if(Curproc != NULLPROC){
  119.         ep = (struct env *)&Curproc->env;
  120.         tprintf("%-10lx%-10lx%-10u%-10u          %c   %2d %2d  %s\n",
  121.          ptol(Curproc),ptol(MK_FP(ep->ss,ep->sp)),Curproc->stksize,
  122.          stkutil(Curproc),
  123.          Curproc->i_state ? 'I' : ' ',
  124.          Curproc->input,Curproc->output,
  125.          Curproc->name);
  126.     }
  127.     return 0;
  128. }
  129. static int
  130. stkutil(pp)
  131. struct proc *pp;
  132. {
  133.     unsigned i;
  134.     register int16 *sp;
  135.  
  136.     i = pp->stksize;
  137.     for(sp = pp->stack;*sp == STACKPAT && sp < pp->stack + pp->stksize;sp++)
  138.         i--;
  139.     return i;
  140. }
  141. /* Return number of used words in interrupt stack. Note hardwired value
  142.  * for stack size; this is also found in the various .asm files
  143.  */
  144. static int
  145. chkintstk()
  146. {
  147.     register int i;
  148.     register int16 *cp;
  149.  
  150.     for(i=512,cp = Intstk; i != 0 && *cp == STACKPAT; cp++)
  151.         i--;
  152.     return i;
  153. }
  154.  
  155. /* Verify that stack pointer for current process is within legal limits;
  156.  * also check that no one has dereferenced a null pointer
  157.  */
  158. void
  159. chkstk()
  160. {
  161.     int16 *sbase;
  162.     int16 *stop;
  163.     int16 *sp;
  164.     extern int Nokeys;        /* indicates we are shelled out [pc.c]*/
  165.  
  166.     sp = MK_FP(_SS,_SP);
  167.     if(_SS == _DS){
  168.         /* Probably in interrupt context */
  169.         return;
  170.     }
  171.     sbase = Curproc->stack;
  172.     if(sbase == NULL)
  173.         return;    /* Main task -- too hard to check */
  174.  
  175.     stop = sbase + Curproc->stksize;
  176.     if(sp < sbase || sp >= stop){
  177.         printf("Stack violation, process %s\n",Curproc->name);
  178.         printf("SP = %lx, legal stack range [%lx,%lx)\n",
  179.         ptol(sp),ptol(sbase),ptol(stop));
  180.         fflush(stdout);
  181.         killself();
  182.     }
  183.     if(*(unsigned short *)NULL != oldNull && Nokeys){
  184.         if(!Nokeys)        /* don't complain if we are shelled out */
  185.             printf("WARNING: Location 0 smashed, process %s\n",Curproc->name);
  186.         *(unsigned short *)NULL = oldNull;
  187.         fflush(stdout);
  188.     }
  189. }
  190. /* Machine-dependent initialization of a task */
  191. void
  192. psetup(pp,iarg,parg1,parg2,pc)
  193. struct proc *pp;    /* Pointer to task structure */
  194. int iarg;        /* Generic integer arg */
  195. void *parg1;        /* Generic pointer arg #1 */
  196. void *parg2;        /* Generic pointer arg #2 */
  197. void (*pc)();        /* Initial execution address */
  198. {
  199.     register int *stktop;
  200.     register struct env *ep;
  201.  
  202.     /* Set up stack to make it appear as if the user's function was called
  203.      * by killself() with the specified arguments. When the user returns,
  204.      * killself() automatically cleans up.
  205.      *
  206.      * First, push args on stack in reverse order, simulating what C
  207.      * does just before it calls a function.
  208.      */
  209.     stktop = (int *)(pp->stack + pp->stksize);
  210. #ifdef    LARGEDATA
  211.     *--stktop = FP_SEG(parg2);
  212. #endif
  213.     *--stktop = FP_OFF(parg2);
  214. #ifdef    LARGEDATA
  215.     *--stktop = FP_SEG(parg1);
  216. #endif
  217.     *--stktop = FP_OFF(parg1);
  218.     *--stktop = iarg;
  219.         
  220.     /* Now push the entry address of killself(), simulating the call to
  221.      * the user function.
  222.      */
  223. #ifdef    LARGECODE
  224.     *--stktop = FP_SEG(killself);
  225. #endif
  226.     *--stktop = FP_OFF(killself);
  227.  
  228.     /* Set up task environment. Note that for Turbo-C, the setjmp
  229.      * sets the interrupt enable flag in the environment so that
  230.      * interrupts will be enabled when the task runs for the first time.
  231.      * Note that this requires newproc() to be called with interrupts
  232.      * enabled!
  233.      */
  234.     setjmp(pp->env);
  235.     ep = (struct env *)&pp->env;
  236.     ep->ss = FP_SEG(stktop);
  237.     ep->sp = FP_OFF(stktop);
  238.     ep->cs = FP_SEG(pc);    /* Doesn't hurt in small model */
  239.     ep->ip = FP_OFF(pc);
  240.     /* Task initially runs with interrupts on */
  241.     pp->i_state = 1;
  242. }
  243. unsigned
  244. phash(event)
  245. void *event;
  246. {
  247.     register unsigned x;
  248.  
  249.     /* Fold the two halves of the pointer */
  250.     x = FP_SEG(event) ^ FP_OFF(event);
  251.  
  252.     /* If PHASH is a power of two, this will simply mask off the
  253.      * higher order bits
  254.      */
  255.     return x % PHASH;
  256. }
  257.