home *** CD-ROM | disk | FTP | other *** search
/ High Voltage Shareware / high1.zip / high1 / DIR3 / KA9Q212.ZIP / KSUBR.C < prev    next >
C/C++ Source or Header  |  1993-02-07  |  7KB  |  269 lines

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