home *** CD-ROM | disk | FTP | other *** search
/ HAM Radio 3 / hamradioversion3.0examsandprograms1992.iso / misc / 9q920411 / ksubr.c < prev    next >
C/C++ Source or Header  |  1992-04-10  |  7KB  |  257 lines

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