Guest User

Untitled

a guest
Apr 25th, 2018
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.88 KB | None | 0 0
  1. /* file: tunix.c core kernel code */
  2.  
  3. #include <stdio.h>
  4. #include <cpu.h>
  5. #include <gates.h>
  6. #include "tsyscall.h"
  7. #include "tsystm.h"
  8. #include "proc.h"
  9. #include "sched.h"
  10.  
  11. /* for saved eflags register initialization */
  12. #define EFLAGS_IF 0x200
  13. /* for saved esp register--stack bases for user programs */
  14. /* could use enum here */
  15. #define STACKBASE1 0x3f0000
  16. #define STACKBASE2 0x3e0000
  17. #define STACKBASE3 0x3d0000
  18. #define TICKS10MSEC 0x2E9C
  19.  
  20. extern IntHandler syscall; /* the assembler envelope routine    */
  21. extern void ustart1(void),ustart2(void), ustart3(void);
  22. extern void finale(void);
  23.  
  24. void k_init(void);
  25. void syscallc( int user_eax, int devcode, char *buff , int bufflen);
  26. void debug_set_trap_gate(int n, IntHandler *inthand_addr, int debug);
  27. void set_trap_gate(int n, IntHandler *inthand_addr);
  28. void process0(void), init_proctab(void), shutdown(void);
  29. int sysexit(int);
  30.  
  31. /* Record debug info in otherwise free memory between program and stack */
  32. /* 0x300000 = 3M, the start of the last M of user memory on the SAPC */
  33. #define DEBUG_AREA 0x300000
  34. char *debug_log_area = (char *)DEBUG_AREA;
  35. char *debug_record;  /* current pointer into log area */
  36.  
  37. /* kernel globals added for scheduler */
  38. PEntry proctab[NPROC],*curproc;
  39. int number_of_zombie;
  40.  
  41. #define MAX_CALL 6
  42.  
  43. /* syscall dispatch table */
  44. static  struct sysent {
  45.        short   sy_narg;        /* total number of arguments */
  46.        int     (*sy_call)(int, ...);   /* handler */
  47. } sysent[MAX_CALL];
  48.  
  49. /* end of kernel globals */
  50.  
  51.  
  52. /****************************************************************************/
  53. /* k_init: this function for the initialize  of the kernel system*/
  54. /****************************************************************************/
  55.  
  56. void k_init(void){
  57.   debug_record = debug_log_area; /* clear debug log */
  58.   strcpy(debug_record,"");
  59.  
  60.   cli();
  61.   ioinit();            /* initialize the deivce */
  62.   set_trap_gate(0x80, &syscall);   /* SET THE TRAP GATE*/
  63.  
  64.   /* Note: Could set these with initializers */
  65.   /* Need to cast function pointer type to keep ANSI C happy */
  66.   sysent[TREAD].sy_call = (int (*)(int, ...))sysread;
  67.   sysent[TWRITE].sy_call = (int (*)(int, ...))syswrite;
  68.   sysent[TEXIT].sy_call = (int (*)(int, ...))sysexit;
  69.  
  70.   sysent[TEXIT].sy_narg = 1;    /* set the arg number of function */
  71.   sysent[TREAD].sy_narg = 3;
  72.   sysent[TIOCTL].sy_narg = 3;
  73.   sysent[TWRITE].sy_narg = 3;
  74.  
  75.   init_proctab();
  76.   tickinit();
  77.   process0();           /* rest of kernel operation (non-init) */
  78. }
  79.  
  80. // taken from my CS341 MP4
  81. void inittimer() {
  82.   tickcount = 0;
  83.   cli();
  84.   /* irq 0 maps to slot n = 0x20 in IDT for linux setup */
  85.   set_intr_gate(TIMER0_IRQ+IRQ_TO_INT_N_SHIFT, &irq0inthand);
  86.   pic_enable_irq(TIMER0_IRQ);
  87.   timer_running = 0;        /* starts running at call to starttimer */
  88.   set_timer_count(TICKS10MSEC);
  89. #ifdef DEBUG
  90.   printf("Enabling interrupts in CPU\n");
  91. #endif
  92.   sti();
  93. }
  94.  
  95. // taken from my CS341 MP4
  96. void set_timer_count(int count) {
  97.   outpt(TIMER_CNTRL_PORT, TIMER0|TIMER_SET_ALL|TIMER_MODE_RATEGEN|TIMER_BINARY_COUNTER);
  98.   outpt(TIMER0_COUNT_PORT,count&0xff); /* set LSB here */
  99.   outpt(TIMER0_COUNT_PORT,count>>8); /* and MSB here */
  100.   smalldelay();         /* give the timer a moment to init. */
  101. }
  102.  
  103. // taken from my CS341 MP4
  104. void smalldelay(void) { // about 10 us on a SAPC (400Mhz Pentium)
  105.   int i;
  106.   for (i=0;i<1000;i++)
  107.     ;
  108. }
  109.  
  110. /****************************************************************************/
  111. /* process0:  code for process 0: runs when necessary, shuts down            */
  112. /****************************************************************************/
  113. void process0()
  114. {
  115.   int i;
  116.  
  117.   /* execution will come back here when restore process 0*/
  118.   while (number_of_zombie < NPROC-1) { /* proc 0 can't be zombie */    
  119.     sti();          /* let proc 0 take interrupts (important!) */
  120.     cli();
  121.     scheduler();
  122.   }
  123.   kprintf("SHUTTING DOWN\n");
  124.   sti();
  125.   for (i=0; i< 1000000; i++)
  126.     ;               /* let output finish (kludge) */
  127.  
  128.   for(i=1;i<NPROC;i++)
  129.     kprintf("\nEXIT CODE OF PROCESS %d: %d\n",i,proctab[i].p_exitval);
  130.  
  131.   shutdown();
  132.   /* note that we can return, in process0, to the startup module
  133.      with its int $3.  It's OK to jump to finale, but not necessary */
  134. }
  135. /****************************************************************************/
  136. /* init_proctab: this function for setting init_sp, init_pc              */
  137. /* zeroing out savededp, and set to RUN                                     */
  138. /****************************************************************************/
  139. void init_proctab()
  140. {
  141.   int i;
  142.  
  143.   proctab[1].p_savedregs[SAVED_PC] = (int)&ustart1;
  144.   proctab[2].p_savedregs[SAVED_PC] = (int)&ustart2;
  145.   proctab[3].p_savedregs[SAVED_PC] = (int)&ustart3;
  146.  
  147.   proctab[1].p_savedregs[SAVED_ESP] = STACKBASE1;
  148.   proctab[2].p_savedregs[SAVED_ESP] = STACKBASE2;
  149.   proctab[3].p_savedregs[SAVED_ESP] = STACKBASE3;
  150.  
  151.   for(i=0;i<NPROC;i++){
  152.     proctab[i].p_savedregs[SAVED_EBP] = 0;
  153.     proctab[i].p_savedregs[SAVED_EFLAGS] = EFLAGS_IF; /* make IF=1 */
  154.     proctab[i].p_status=RUN;
  155.   }
  156.  
  157.   curproc=&proctab[0];
  158.  
  159.   number_of_zombie=0;
  160. }
  161.  
  162. /* shut the system down */
  163. void shutdown()
  164. {
  165.   kprintf("SHUTTING THE SYSTEM DOWN!\n");
  166.   kprintf("Debug log from run:\n");
  167.   kprintf("Marking kernel events as follows:\n");
  168.   kprintf("  ^a   COM2 input interrupt, a received\n");
  169.   kprintf("  ~    COM2 output interrupt, ordinary char output\n");
  170.   kprintf("  ~e   COM2 output interrupt, echo output\n");
  171.   kprintf("  ~s   COM2 output interrupt, shutdown TX ints\n");
  172.   kprintf("  |(1z-2) process switch from 1, now a zombie, to 2\n");
  173.   kprintf("  |(1b-2) process switch from 1, now blocked, to 2\n");
  174.   kprintf("  |(2-1) process switch (by preemption) from 2 to 1\n");
  175.   kprintf("%s", debug_log_area);    /* the debug log from memory */
  176.   kprintf("\nLEAVE KERNEL!\n\n");
  177.   finale();     /* trap to Tutor */
  178. }
  179.  
  180. /****************************************************************************/
  181. /* syscallc: this function for the C part of the 0x80 trap handler          */
  182. /* OK to just switch on the system call number here                         */
  183. /* By putting the return value of syswrite, etc. in user_eax, it gets       */
  184. /* popped back in sysentry.s and returned to user in eax                    */
  185. /****************************************************************************/
  186.  
  187. void syscallc( int user_eax, int devcode, char *buff , int bufflen){
  188.   int nargs;
  189.   int syscall_no = user_eax;
  190.  
  191.   switch(nargs = sysent[syscall_no].sy_narg)
  192.     {
  193.     case 1:         /* 1-argument system call */
  194.     user_eax = sysent[syscall_no].sy_call(devcode);   /* sysexit */
  195.     break;
  196.     case 3:         /* 3-arg system call: calls sysread or syswrite */
  197.     user_eax = sysent[syscall_no].sy_call(devcode,buff,bufflen);
  198.     break;
  199.     default: kprintf("bad # syscall args %d, syscall #%d\n",
  200.              nargs, syscall_no);
  201.     }
  202. }
  203.  
  204. /****************************************************************************/
  205. /* sysexit: this function for the exit syscall function */
  206. /****************************************************************************/
  207.  
  208. int sysexit(int exit_code)
  209. {
  210.   cli();
  211.   curproc->p_exitval = exit_code;
  212.   curproc->p_status = ZOMBIE;
  213.   number_of_zombie++;
  214.   scheduler();
  215.   /* never returns */      
  216.   return 0;    /* never happens, but avoids warning about no return value */
  217. }
  218.  
  219. /****************************************************************************/
  220. /* set_trap_gate: this function for setting the trap gate */
  221. /****************************************************************************/
  222.  
  223. void set_trap_gate(int n, IntHandler *inthand_addr)
  224. {
  225.   debug_set_trap_gate(n, inthand_addr, 0);
  226. }
  227.  
  228. /* write the nth idt descriptor as a trap gate to inthand_addr */
  229. void debug_set_trap_gate(int n, IntHandler *inthand_addr, int debug)
  230. {
  231.   char *idt_addr;
  232.   Gate_descriptor *idt, *desc;
  233.   unsigned int limit = 0;
  234.   extern void locate_idt(unsigned int *, char **);
  235.  
  236.   if (debug)
  237.     kprintf("Calling locate_idt to do sidt instruction...\n");
  238.   locate_idt(&limit,&idt_addr);
  239.   /* convert to CS seg offset, i.e., ordinary address, then to typed pointer */
  240.   idt = (Gate_descriptor *)(idt_addr - KERNEL_BASE_LA);
  241.   if (debug)
  242.     kprintf("Found idt at %x, lim %x\n",idt, limit);
  243.   desc = &idt[n];               /* select nth descriptor in idt table */
  244.   /* fill in descriptor */
  245.   if (debug)
  246.     kprintf("Filling in desc at %x with addr %x\n",(unsigned int)desc,
  247.            (unsigned int)inthand_addr);
  248.   desc->selector = KERNEL_CS;   /* CS seg selector for int. handler */
  249.   desc->addr_hi = ((unsigned int)inthand_addr)>>16; /* CS seg offset of inthand */
  250.   desc->addr_lo = ((unsigned int)inthand_addr)&0xffff;
  251.   desc->flags = GATE_P|GATE_DPL_KERNEL|GATE_TRAPGATE; /* valid, trap */
  252.   desc->zero = 0;
  253. }
  254.  
  255. /* append msg to memory debugging log */
  256. void debug_log(char *msg)
  257. {
  258.     strcpy(debug_record, msg);
  259.     debug_record +=strlen(msg);
  260. }
Add Comment
Please, Sign In to add comment