Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on May 8th, 2012  |  syntax: C  |  size: 20.93 KB  |  hits: 24  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
This paste has a previous version, view the difference. Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. #include <inc/mmu.h>
  2.  
  3. #include <inc/x86.h>
  4.  
  5. #include <inc/assert.h>
  6.  
  7.  
  8.  
  9. #include <kern/memory_manager.h>
  10.  
  11. #include <kern/trap.h>
  12.  
  13. #include <kern/console.h>
  14.  
  15. #include <kern/command_prompt.h>
  16.  
  17. #include <kern/user_environment.h>
  18.  
  19. #include <kern/file_manager.h>
  20.  
  21. #include <kern/syscall.h>
  22.  
  23. #include <kern/sched.h>
  24.  
  25. #include <kern/kclock.h>
  26.  
  27. #include <kern/trap.h>
  28.  
  29.  
  30.  
  31. static struct Taskstate ts;
  32.  
  33.  
  34.  
  35.  
  36.  
  37.  
  38.  
  39. /// Interrupt descriptor table.  (Must be built at run time because
  40.  
  41. /// shifted function addresses can't be represented in relocation records.)
  42.  
  43. ///
  44.  
  45.  
  46.  
  47. struct Gatedesc idt[256] = { { 0 } };
  48.  
  49. struct Pseudodesc idt_pd = {
  50.  
  51.                 sizeof(idt) - 1, (uint32) idt
  52.  
  53. };
  54.  
  55. extern  void (*PAGE_FAULT)();
  56.  
  57. extern  void (*SYSCALL_HANDLER)();
  58.  
  59. extern  void (*DBL_FAULT)();
  60.  
  61.  
  62.  
  63. extern  void (*ALL_FAULTS0)();
  64.  
  65. extern  void (*ALL_FAULTS1)();
  66.  
  67. extern  void (*ALL_FAULTS2)();
  68.  
  69. extern  void (*ALL_FAULTS3)();
  70.  
  71. extern  void (*ALL_FAULTS4)();
  72.  
  73. extern  void (*ALL_FAULTS5)();
  74.  
  75. extern  void (*ALL_FAULTS6)();
  76.  
  77. extern  void (*ALL_FAULTS7)();
  78.  
  79. //extern  void (*ALL_FAULTS8)();
  80.  
  81. //extern  void (*ALL_FAULTS9)();
  82.  
  83. extern  void (*ALL_FAULTS10)();
  84.  
  85. extern  void (*ALL_FAULTS11)();
  86.  
  87. extern  void (*ALL_FAULTS12)();
  88.  
  89. extern  void (*ALL_FAULTS13)();
  90.  
  91. //extern  void (*ALL_FAULTS14)();
  92.  
  93. //extern  void (*ALL_FAULTS15)();
  94.  
  95. extern  void (*ALL_FAULTS16)();
  96.  
  97. extern  void (*ALL_FAULTS17)();
  98.  
  99. extern  void (*ALL_FAULTS18)();
  100.  
  101. extern  void (*ALL_FAULTS19)();
  102.  
  103.  
  104.  
  105.  
  106.  
  107. extern  void (*ALL_FAULTS32)();
  108.  
  109. extern  void (*ALL_FAULTS33)();
  110.  
  111. extern  void (*ALL_FAULTS34)();
  112.  
  113. extern  void (*ALL_FAULTS35)();
  114.  
  115. extern  void (*ALL_FAULTS36)();
  116.  
  117. extern  void (*ALL_FAULTS37)();
  118.  
  119. extern  void (*ALL_FAULTS38)();
  120.  
  121. extern  void (*ALL_FAULTS39)();
  122.  
  123. extern  void (*ALL_FAULTS40)();
  124.  
  125. extern  void (*ALL_FAULTS41)();
  126.  
  127. extern  void (*ALL_FAULTS42)();
  128.  
  129. extern  void (*ALL_FAULTS43)();
  130.  
  131. extern  void (*ALL_FAULTS44)();
  132.  
  133. extern  void (*ALL_FAULTS45)();
  134.  
  135. extern  void (*ALL_FAULTS46)();
  136.  
  137. extern  void (*ALL_FAULTS47)();
  138.  
  139.  
  140.  
  141.  
  142.  
  143.  
  144.  
  145. static const char *trapname(int trapno)
  146.  
  147. {
  148.  
  149.         static const char * const excnames[] = {
  150.  
  151.                         "Divide error",
  152.  
  153.                         "Debug",
  154.  
  155.                         "Non-Maskable Interrupt",
  156.  
  157.                         "Breakpoint",
  158.  
  159.                         "Overflow",
  160.  
  161.                         "BOUND Range Exceeded",
  162.  
  163.                         "Invalid Opcode",
  164.  
  165.                         "Device Not Available",
  166.  
  167.                         "Double Fault",
  168.  
  169.                         "Coprocessor Segment Overrun",
  170.  
  171.                         "Invalid TSS",
  172.  
  173.                         "Segment Not Present",
  174.  
  175.                         "Stack Fault",
  176.  
  177.                         "General Protection",
  178.  
  179.                         "Page Fault",
  180.  
  181.                         "(unknown trap)",
  182.  
  183.                         "x87 FPU Floating-Point Error",
  184.  
  185.                         "Alignment Check",
  186.  
  187.                         "Machine-Check",
  188.  
  189.                         "SIMD Floating-Point Exception"
  190.  
  191.         };
  192.  
  193.  
  194.  
  195.         if (trapno < sizeof(excnames)/sizeof(excnames[0]))
  196.  
  197.                 return excnames[trapno];
  198.  
  199.         if (trapno == T_SYSCALL)
  200.  
  201.                 return "System call";
  202.  
  203.         return "(unknown trap)";
  204.  
  205. }
  206.  
  207.  
  208.  
  209.  
  210.  
  211. void
  212.  
  213. idt_init(void)
  214.  
  215. {
  216.  
  217.         extern struct Segdesc gdt[];
  218.  
  219.  
  220.  
  221.         // LAB 3: Your code here.
  222.  
  223.         //initialize idt
  224.  
  225.         SETGATE(idt[T_PGFLT], 0, GD_KT , &PAGE_FAULT, 0) ;
  226.  
  227.         SETGATE(idt[T_SYSCALL], 0, GD_KT , &SYSCALL_HANDLER, 3) ;
  228.  
  229.         SETGATE(idt[T_DBLFLT], 0, GD_KT , &DBL_FAULT, 0) ;
  230.  
  231.  
  232.  
  233.  
  234.  
  235.         SETGATE(idt[T_DIVIDE   ], 0, GD_KT , &ALL_FAULTS0, 3) ;
  236.  
  237.         SETGATE(idt[T_DEBUG    ], 1, GD_KT , &ALL_FAULTS1, 3) ;
  238.  
  239.         SETGATE(idt[T_NMI      ], 0, GD_KT , &ALL_FAULTS2, 3) ;
  240.  
  241.         SETGATE(idt[T_BRKPT    ], 1, GD_KT , &ALL_FAULTS3, 3) ;
  242.  
  243.         SETGATE(idt[T_OFLOW    ], 1, GD_KT , &ALL_FAULTS4, 3) ;
  244.  
  245.         SETGATE(idt[T_BOUND    ], 0, GD_KT , &ALL_FAULTS5, 3) ;
  246.  
  247.         SETGATE(idt[T_ILLOP    ], 0, GD_KT , &ALL_FAULTS6, 3) ;
  248.  
  249.         SETGATE(idt[T_DEVICE   ], 0, GD_KT , &ALL_FAULTS7, 3) ;
  250.  
  251.         //SETGATE(idt[T_DBLFLT   ], 0, GD_KT , &ALL_FAULTS, 3) ;
  252.  
  253.         //SETGATE(idt[], 0, GD_KT , &ALL_FAULTS, 3) ;
  254.  
  255.         SETGATE(idt[T_TSS      ], 0, GD_KT , &ALL_FAULTS10, 3) ;
  256.  
  257.         SETGATE(idt[T_SEGNP    ], 0, GD_KT , &ALL_FAULTS11, 3) ;
  258.  
  259.         SETGATE(idt[T_STACK    ], 0, GD_KT , &ALL_FAULTS12, 3) ;
  260.  
  261.         SETGATE(idt[T_GPFLT    ], 0, GD_KT , &ALL_FAULTS13, 3) ;
  262.  
  263.         //SETGATE(idt[T_PGFLT    ], 0, GD_KT , &ALL_FAULTS, 3) ;
  264.  
  265.         //SETGATE(idt[ne T_RES   ], 0, GD_KT , &ALL_FAULTS, 3) ;
  266.  
  267.         SETGATE(idt[T_FPERR    ], 0, GD_KT , &ALL_FAULTS16, 3) ;
  268.  
  269.         SETGATE(idt[T_ALIGN    ], 0, GD_KT , &ALL_FAULTS17, 3) ;
  270.  
  271.         SETGATE(idt[T_MCHK     ], 0, GD_KT , &ALL_FAULTS18, 3) ;
  272.  
  273.         SETGATE(idt[T_SIMDERR  ], 0, GD_KT , &ALL_FAULTS19, 3) ;
  274.  
  275.  
  276.  
  277.  
  278.  
  279.         SETGATE(idt[IRQ0_Clock], 0, GD_KT , &ALL_FAULTS32, 3) ;
  280.  
  281.         SETGATE(idt[33], 0, GD_KT , &ALL_FAULTS33, 3) ;
  282.  
  283.         SETGATE(idt[34], 0, GD_KT , &ALL_FAULTS34, 3) ;
  284.  
  285.         SETGATE(idt[35], 0, GD_KT , &ALL_FAULTS35, 3) ;
  286.  
  287.         SETGATE(idt[36], 0, GD_KT , &ALL_FAULTS36, 3) ;
  288.  
  289.         SETGATE(idt[37], 0, GD_KT , &ALL_FAULTS37, 3) ;
  290.  
  291.         SETGATE(idt[38], 0, GD_KT , &ALL_FAULTS38, 3) ;
  292.  
  293.         SETGATE(idt[39], 0, GD_KT , &ALL_FAULTS39, 3) ;
  294.  
  295.         SETGATE(idt[40], 0, GD_KT , &ALL_FAULTS40, 3) ;
  296.  
  297.         SETGATE(idt[41], 0, GD_KT , &ALL_FAULTS41, 3) ;
  298.  
  299.         SETGATE(idt[42], 0, GD_KT , &ALL_FAULTS42, 3) ;
  300.  
  301.         SETGATE(idt[43], 0, GD_KT , &ALL_FAULTS43, 3) ;
  302.  
  303.         SETGATE(idt[44], 0, GD_KT , &ALL_FAULTS44, 3) ;
  304.  
  305.         SETGATE(idt[45], 0, GD_KT , &ALL_FAULTS45, 3) ;
  306.  
  307.         SETGATE(idt[46], 0, GD_KT , &ALL_FAULTS46, 3) ;
  308.  
  309.         SETGATE(idt[47], 0, GD_KT , &ALL_FAULTS47, 3) ;
  310.  
  311.  
  312.  
  313.  
  314.  
  315.  
  316.  
  317.         // Setup a TSS so that we get the right stack
  318.  
  319.         // when we trap to the kernel.
  320.  
  321.         ts.ts_esp0 = KERNEL_STACK_TOP;
  322.  
  323.         ts.ts_ss0 = GD_KD;
  324.  
  325.  
  326.  
  327.         // Initialize the TSS field of the gdt.
  328.  
  329.         gdt[GD_TSS >> 3] = SEG16(STS_T32A, (uint32) (&ts),
  330.  
  331.                         sizeof(struct Taskstate), 0);
  332.  
  333.         gdt[GD_TSS >> 3].sd_s = 0;
  334.  
  335.  
  336.  
  337.         // Load the TSS
  338.  
  339.         ltr(GD_TSS);
  340.  
  341.  
  342.  
  343.         // Load the IDT
  344.  
  345.         asm volatile("lidt idt_pd");
  346.  
  347. }
  348.  
  349.  
  350.  
  351. void print_trapframe(struct Trapframe *tf)
  352.  
  353. {
  354.  
  355.         cprintf("TRAP frame at %p\n", tf);
  356.  
  357.         print_regs(&tf->tf_regs);
  358.  
  359.         cprintf("  es   0x----%04x\n", tf->tf_es);
  360.  
  361.         cprintf("  ds   0x----%04x\n", tf->tf_ds);
  362.  
  363.         cprintf("  trap 0x%08x %s - %d\n", tf->tf_trapno, trapname(tf->tf_trapno), tf->tf_trapno);
  364.  
  365.         cprintf("  err  0x%08x\n", tf->tf_err);
  366.  
  367.         cprintf("  eip  0x%08x\n", tf->tf_eip);
  368.  
  369.         cprintf("  cs   0x----%04x\n", tf->tf_cs);
  370.  
  371.         cprintf("  flag 0x%08x\n", tf->tf_eflags);
  372.  
  373.         cprintf("  esp  0x%08x\n", tf->tf_esp);
  374.  
  375.         cprintf("  ss   0x----%04x\n", tf->tf_ss);
  376.  
  377. }
  378.  
  379.  
  380.  
  381. void print_regs(struct PushRegs *regs)
  382.  
  383. {
  384.  
  385.         cprintf("  edi  0x%08x\n", regs->reg_edi);
  386.  
  387.         cprintf("  esi  0x%08x\n", regs->reg_esi);
  388.  
  389.         cprintf("  ebp  0x%08x\n", regs->reg_ebp);
  390.  
  391.         cprintf("  oesp 0x%08x\n", regs->reg_oesp);
  392.  
  393.         cprintf("  ebx  0x%08x\n", regs->reg_ebx);
  394.  
  395.         cprintf("  edx  0x%08x\n", regs->reg_edx);
  396.  
  397.         cprintf("  ecx  0x%08x\n", regs->reg_ecx);
  398.  
  399.         cprintf("  eax  0x%08x\n", regs->reg_eax);
  400.  
  401. }
  402.  
  403.  
  404.  
  405. static void trap_dispatch(struct Trapframe *tf)
  406.  
  407. {
  408.  
  409.         // Handle processor exceptions.
  410.  
  411.         // LAB 3: Your code here.
  412.  
  413.  
  414.  
  415.         if(tf->tf_trapno == T_PGFLT)
  416.  
  417.         {
  418.  
  419.                 if(isPageReplacmentAlgorithmLRU()){
  420.  
  421.                         update_WS_time_stamps();
  422.  
  423.                 }
  424.  
  425.                 fault_handler(tf);
  426.  
  427.         }
  428.  
  429.         else if (tf->tf_trapno == T_SYSCALL)
  430.  
  431.         {
  432.  
  433.                 uint32 ret = syscall(tf->tf_regs.reg_eax
  434.  
  435.                                 ,tf->tf_regs.reg_edx
  436.  
  437.                                 ,tf->tf_regs.reg_ecx
  438.  
  439.                                 ,tf->tf_regs.reg_ebx
  440.  
  441.                                 ,tf->tf_regs.reg_edi
  442.  
  443.                                 ,tf->tf_regs.reg_esi);
  444.  
  445.                 tf->tf_regs.reg_eax = ret;
  446.  
  447.         }
  448.  
  449.         else if(tf->tf_trapno == T_DBLFLT)
  450.  
  451.         {
  452.  
  453.                 cprintf("aywa ya basha\n");
  454.  
  455.         }
  456.  
  457.         else if (tf->tf_trapno == IRQ0_Clock)
  458.  
  459.         {
  460.  
  461.                 clock_interrupt_handler() ;
  462.  
  463.         }
  464.  
  465.  
  466.  
  467.         else
  468.  
  469.         {
  470.  
  471.                 // Unexpected trap: The user process or the kernel has a bug.
  472.  
  473.                 //print_trapframe(tf);
  474.  
  475.                 if (tf->tf_cs == GD_KT)
  476.  
  477.                         panic("unhandled trap in kernel");
  478.  
  479.                 else {
  480.  
  481.                         //env_destroy(curenv);
  482.  
  483.                         return;
  484.  
  485.                 }
  486.  
  487.         }
  488.  
  489.         return;
  490.  
  491. }
  492.  
  493.  
  494.  
  495. void trap(struct Trapframe *tf)
  496.  
  497. {
  498.  
  499.         kclock_stop();
  500.  
  501.  
  502.  
  503.         //struct Trapframe* old_tf = tf ;
  504.  
  505.         if ((tf->tf_cs & 3) == 3) {
  506.  
  507.                 // Trapped from user mode.
  508.  
  509.                 // Copy trap frame (which is currently on the stack)
  510.  
  511.                 // into 'curenv->env_tf', so that running the environment
  512.  
  513.                 // will restart at the trap point.
  514.  
  515.                 assert(curenv);
  516.  
  517.                 curenv->env_tf = *tf;
  518.  
  519.                 // The trapframe on the stack should be ignored from here on.
  520.  
  521.                 tf = &(curenv->env_tf);
  522.  
  523.         }
  524.  
  525.  
  526.  
  527.         //      cprintf("================================================================\n");
  528.  
  529.         //      cprintf("kernel: trap to be dispatched: %s # = %d, IP = %x\n", trapname(tf->tf_trapno), tf->tf_trapno, tf->tf_eip) ;
  530.  
  531.         if(tf->tf_trapno == IRQ0_Clock)
  532.  
  533.         {
  534.  
  535.                 //              cprintf("Clock INT: EIP = %x, ECX = %x, EFlags = %x, SP = %x\n", tf->tf_eip, tf->tf_regs.reg_ecx, tf->tf_eflags, tf->tf_esp);
  536.  
  537.                 //uint32 time_bef = time ;
  538.  
  539.                 //cprintf("timenow bef lag in trap = %d\n", time);
  540.  
  541.                 //              int cc=0; int ccc=0;
  542.  
  543.                 //              for(;cc<35000; cc++)
  544.  
  545.                 //              {
  546.  
  547.                 //                      ccc++;
  548.  
  549.                 //              }
  550.  
  551.                 //cprintf("timenow aft lag in trap= %d\n", time);
  552.  
  553.  
  554.  
  555.         }
  556.  
  557.         // Dispatch based on what type of trap occurred
  558.  
  559.         trap_dispatch(tf);
  560.  
  561.  
  562.  
  563.  
  564.  
  565.         // Return to the current environment, which should be runnable.
  566.  
  567.         assert(curenv && curenv->env_status == ENV_RUNNABLE);
  568.  
  569.  
  570.  
  571.         /// Mahmoud added code: I am here checking to see to where should
  572.  
  573.         /// the trap routine exit, to kernel code or to user code ?
  574.  
  575.         /// refer to : Intel 80386 Reference Programmer's Manual/s09_08.htm
  576.  
  577.         /// chapter 9.8.14
  578.  
  579.         {
  580.  
  581.                 if((tf->tf_err & 0x4) == 0)
  582.  
  583.                 {
  584.  
  585.                         //cprintf("Last trap [%s] came from kernel mode, returning to kernel eip = %x\n",trapname(tf->tf_trapno), tf->tf_eip);
  586.  
  587.                         //the Trap came from supervisor mode
  588.  
  589.                         //LOG_STATMENT(cprintf("Last trap came from kernel mode, returning to kernel eip = %x",tf->tf_eip));
  590.  
  591.                 }
  592.  
  593.                 else
  594.  
  595.                 {
  596.  
  597.                         //cprintf("Last trap [%s] came from USER mode, returning to user eip = %x\n",trapname(tf->tf_trapno), tf->tf_eip);
  598.  
  599.                         //the Trap came from user mode
  600.  
  601.                         //LOG_STATMENT(cprintf("Last trap came from user mode, returning to user eip = %x",tf->tf_eip));               
  602.  
  603.                 }      
  604.  
  605.         }
  606.  
  607.  
  608.  
  609.         //      tf = curenv->env_tf ;
  610.  
  611.         env_run(curenv);
  612.  
  613. }
  614.  
  615.  
  616.  
  617. void setPageReplacmentAlgorithmLRU(){_PageRepAlgoType = PG_REP_LRU;}
  618.  
  619. void setPageReplacmentAlgorithmCLOCK(){_PageRepAlgoType = PG_REP_CLOCK;}
  620.  
  621. void setPageReplacmentAlgorithmFIFO(){_PageRepAlgoType = PG_REP_FIFO;}
  622.  
  623.  
  624.  
  625. uint32 isPageReplacmentAlgorithmLRU(){if(_PageRepAlgoType == PG_REP_LRU) return 1; return 0;}
  626.  
  627. uint32 isPageReplacmentAlgorithmCLOCK(){if(_PageRepAlgoType == PG_REP_CLOCK) return 1; return 0;}
  628.  
  629. uint32 isPageReplacmentAlgorithmFIFO(){if(_PageRepAlgoType == PG_REP_FIFO) return 1; return 0;}
  630.  
  631.  
  632.  
  633. void detect_modified_loop()
  634.  
  635. {
  636.  
  637.         struct  Frame_Info * slowPtr = LIST_FIRST(&modified_frame_list);
  638.  
  639.         struct  Frame_Info * fastPtr = LIST_FIRST(&modified_frame_list);
  640.  
  641.  
  642.  
  643.  
  644.  
  645.         while (slowPtr && fastPtr) {
  646.  
  647.                 fastPtr = LIST_NEXT(fastPtr); // advance the fast pointer
  648.  
  649.                 if (fastPtr == slowPtr) // and check if its equal to the slow pointer
  650.  
  651.                 {
  652.  
  653.                         cprintf("loop detected in modiflist\n");
  654.  
  655.                         break;
  656.  
  657.                 }
  658.  
  659.  
  660.  
  661.                 if (fastPtr == NULL) {
  662.  
  663.                         break; // since fastPtr is NULL we reached the tail
  664.  
  665.                 }
  666.  
  667.  
  668.  
  669.                 fastPtr = LIST_NEXT(fastPtr); //advance and check again
  670.  
  671.                 if (fastPtr == slowPtr) {
  672.  
  673.                         cprintf("loop detected in modiflist\n");
  674.  
  675.                         break;
  676.  
  677.                 }
  678.  
  679.  
  680.  
  681.                 slowPtr = LIST_NEXT(slowPtr); // advance the slow pointer only once
  682.  
  683.         }
  684.  
  685.         cprintf("finished modi loop detection\n");
  686.  
  687. }
  688.  
  689.  
  690.  
  691. void fault_handler(struct Trapframe *tf)
  692.  
  693. {
  694.  
  695.         uint32 fault_va;
  696.  
  697.  
  698.  
  699.         // Read processor's CR2 register to find the faulting address
  700.  
  701.         fault_va = rcr2();
  702.  
  703.  
  704.  
  705.         //get a pointer to the environment that caused the fault at runtime
  706.  
  707.         struct Env* faulted_env = curenv;
  708.  
  709.  
  710.  
  711.         //check the faulted address, is it a table or not ?
  712.  
  713.         //If the directory entry of the faulted address is NOT PRESENT then
  714.  
  715.         if ( (curenv->env_pgdir[PDX(fault_va)] & PERM_PRESENT) != PERM_PRESENT)
  716.  
  717.         {
  718.  
  719.                 /* we have a table fault ============================================================= */
  720.  
  721.                 //cprintf("[%s] user TABLE fault va %08x\n", curenv->prog_name, fault_va);
  722.  
  723.                 faulted_env->tableFaultsCounter ++ ;
  724.  
  725.  
  726.  
  727.                 table_fault_handler(faulted_env, fault_va);
  728.  
  729.         }
  730.  
  731.         else
  732.  
  733.         {
  734.  
  735.                 /* we have normal page fault ============================================================= */
  736.  
  737.                 //cprintf("[%08s] user PAGE fault va %08x\n", curenv->prog_name, fault_va);
  738.  
  739.                 faulted_env->pageFaultsCounter ++ ;
  740.  
  741.  
  742.  
  743.                 page_fault_handler(faulted_env, fault_va);
  744.  
  745.         }
  746.  
  747.  
  748.  
  749.         /*************************************************************/
  750.  
  751.         //Refresh the TLB cache
  752.  
  753.         tlbflush();
  754.  
  755.         /*************************************************************/
  756.  
  757. }
  758.  
  759.  
  760.  
  761.  
  762.  
  763.  
  764.  
  765. //Handle the table fault
  766.  
  767. void table_fault_handler(struct Env * curenv, uint32 fault_va)
  768.  
  769. {
  770.  
  771.         cprintf("\nTable fault\n");
  772.  
  773.         uint32 tableWorkingSetSize= env_table_ws_get_size(curenv);
  774.  
  775.         cprintf("Table Working Set Size %u - Max Size: %u\n", tableWorkingSetSize, TABLE_WS_MAX_SIZE);
  776.  
  777.         if(tableWorkingSetSize == TABLE_WS_MAX_SIZE)
  778.  
  779.         {
  780.  
  781.                 int Victim_index;
  782.  
  783.                 if (isPageReplacmentAlgorithmCLOCK())
  784.  
  785.                 {
  786.  
  787.                         cprintf("Clock table replacement: \n");
  788.  
  789.                         Victim_index=getTableVictimCLOCK(curenv);
  790.  
  791.                 }
  792.  
  793.                 else if(isPageReplacmentAlgorithmLRU())
  794.  
  795.                 {
  796.  
  797.                         Victim_index=getTableVictimLRU(curenv);
  798.  
  799.                 }
  800.  
  801.                 else if(isPageReplacmentAlgorithmFIFO())
  802.  
  803.                         panic("FIFO page replacement isn't implemented yet!!");
  804.  
  805.  
  806.  
  807.                 removeTableVictim(curenv,Victim_index);
  808.  
  809.                 placeFaultedTable(curenv,fault_va,Victim_index);
  810.  
  811.         }
  812.  
  813.         else
  814.  
  815.         {
  816.  
  817.                 int index=0;
  818.  
  819.                 for(;index<TABLE_WS_MAX_SIZE;index ++)
  820.  
  821.                 {
  822.  
  823.                         if(curenv->tableWorkingSet[index].empty==1)
  824.  
  825.                                 break;
  826.  
  827.                 }
  828.  
  829.                 placeFaultedTable(curenv,fault_va,index);
  830.  
  831.         }
  832.  
  833. }
  834.  
  835.  
  836.  
  837. //Handle the page fault
  838.  
  839. void page_fault_handler(struct Env * curenv, uint32 fault_va)
  840.  
  841. {
  842.  
  843.         cprintf("\nPage Fault!!\n");
  844.  
  845.         uint32 pageWorkingSetSize= env_page_ws_get_size(curenv);
  846.  
  847.         cprintf("Page Working Set Size %u - Max Size: %u\n", pageWorkingSetSize, PAGE_WS_MAX_SIZE);
  848.  
  849.         if(pageWorkingSetSize == PAGE_WS_MAX_SIZE )
  850.  
  851.         {
  852.  
  853.                 int Victim_index;
  854.  
  855.                 if (isPageReplacmentAlgorithmCLOCK())
  856.  
  857.                 {
  858.  
  859.                         cprintf("Clock page replacement: \n");
  860.  
  861.                         Victim_index = getPageVictimCLOCK(curenv);
  862.  
  863.                 }
  864.  
  865.                 else if(isPageReplacmentAlgorithmLRU())
  866.  
  867.                 {
  868.  
  869.                         Victim_index = getPageVictimLRU(curenv);
  870.  
  871.                 }
  872.  
  873.                 else if(isPageReplacmentAlgorithmFIFO())
  874.  
  875.                         panic("FIFO page replacement isn't implemented yet!!");
  876.  
  877.  
  878.  
  879.                 removePageVictim(curenv,Victim_index);
  880.  
  881.                 placeFaultedPage(curenv,fault_va,Victim_index);
  882.  
  883.         }
  884.  
  885.         else
  886.  
  887.         {
  888.  
  889.                 int index=0;
  890.  
  891.                 for(;index<PAGE_WS_MAX_SIZE;index ++)
  892.  
  893.                 {
  894.  
  895.                         if(curenv->pageWorkingSet[index].empty==1)
  896.  
  897.                                 break;
  898.  
  899.                 }
  900.  
  901.                 placeFaultedPage(curenv,fault_va,index);
  902.  
  903.         }
  904.  
  905. }
  906.  
  907.  
  908.  
  909. int getTableVictimLRU(struct Env* env)
  910.  
  911. {
  912.  
  913.         return _getVictimLRU(env->tableWorkingSet, env_table_ws_get_size(env));
  914.  
  915. }
  916.  
  917. int getPageVictimLRU(struct Env* env)
  918.  
  919. {
  920.  
  921.         return _getVictimLRU(env->pageWorkingSet, env_page_ws_get_size(env));
  922.  
  923. }
  924.  
  925. int getTableVictimCLOCK(struct Env* env)
  926.  
  927. {
  928.  
  929.         //cprintf("\t[Table]before get victim: %u - ", env->table_last_WS_index);
  930.  
  931.         int vic = _getVictimTableCLOCK(env->tableWorkingSet,env_table_ws_get_size(env), &env->table_last_WS_index, env->env_pgdir);
  932.  
  933.         //cprintf("after get victim: %u\n", env->table_last_WS_index);
  934.  
  935.         return vic;
  936.  
  937. }
  938.  
  939. int getPageVictimCLOCK(struct Env* env)
  940.  
  941. {
  942.  
  943.         return _getVictimPageCLOCK(env->pageWorkingSet, env_page_ws_get_size(env), &env->page_last_WS_index, env->env_pgdir);
  944.  
  945. }
  946.  
  947.  
  948.  
  949. int _getVictimPageCLOCK(struct WorkingSetElement* ws, int wsSize, uint32* lastWSIndex, uint32* pgDir)
  950.  
  951. {
  952.  
  953.         int cur_index, currentWSIndex;
  954.  
  955.         currentWSIndex = *lastWSIndex;
  956.  
  957.  
  958.  
  959.         //cprintf("CLOCK index: %d\n", currentWSIndex);
  960.  
  961.  
  962.  
  963.         uint32* ptr_pageTable;
  964.  
  965.         // Iterate over WS to get the victim page
  966.  
  967.         while(1)
  968.  
  969.         {
  970.  
  971.                 // Get the page table corresponding to the current WS Virtual Address
  972.  
  973.                 assert(get_page_table(pgDir, (void *)ws[currentWSIndex].virtual_address, &ptr_pageTable) != TABLE_NOT_EXIST);
  974.  
  975.  
  976.  
  977.                 // If the accessed bit is set to 0, this is the victim
  978.  
  979.                 if( (ptr_pageTable[PTX(ws[currentWSIndex].virtual_address)] & PERM_USED) != PERM_USED)
  980.  
  981.                         break;
  982.  
  983.  
  984.  
  985.                 // Wasn't the victim, clear its accessed bit
  986.  
  987.                 ptr_pageTable[PTX(ws[currentWSIndex].virtual_address)] &= ~PERM_USED;
  988.  
  989.                 currentWSIndex ++;
  990.  
  991.                 currentWSIndex %= wsSize;
  992.  
  993.         }
  994.  
  995.         // Update the lastWSIndex to the next WS element
  996.  
  997.         *lastWSIndex = (currentWSIndex + 1)% wsSize;
  998.  
  999.         return currentWSIndex;
  1000.  
  1001. }
  1002.  
  1003.  
  1004.  
  1005. int _getVictimTableCLOCK(struct WorkingSetElement* ws, int wsSize, uint32* lastWSIndex, uint32* pgDir)
  1006.  
  1007. {
  1008.  
  1009.         int currentWSIndex;
  1010.  
  1011.         currentWSIndex = *lastWSIndex;
  1012.  
  1013.  
  1014.  
  1015.         while(1)
  1016.  
  1017.         {
  1018.  
  1019.                 //cprintf("Table address : %x\n",pgDir[PDX(ws[currentWSIndex].virtual_address)]);
  1020.  
  1021.                 // If the accessed bit is set to 0, this is the victim
  1022.  
  1023.                 if ((pgDir[PDX(ws[currentWSIndex].virtual_address)] & PERM_USED) != PERM_USED)
  1024.  
  1025.                         break;
  1026.  
  1027.                 // Wasn't find victim, clear its accessed bit
  1028.  
  1029.                 pgDir[PDX(ws[currentWSIndex].virtual_address)] &= ~PERM_USED;
  1030.  
  1031.                 currentWSIndex++;
  1032.  
  1033.                 currentWSIndex %= wsSize;
  1034.  
  1035.         }
  1036.  
  1037.         // Update the lastWSIndex to the next WS element
  1038.  
  1039.         *lastWSIndex = (currentWSIndex + 1) % wsSize;
  1040.  
  1041.         return currentWSIndex;
  1042.  
  1043. }
  1044.  
  1045.  
  1046.  
  1047. int _getVictimLRU(struct WorkingSetElement* ws, int wsSize)
  1048.  
  1049. {
  1050.  
  1051.         int cur_index, lru_index;
  1052.  
  1053.         uint32 lru_timestamp = 0xFFFFFFFF;
  1054.  
  1055.         lru_index = -1;
  1056.  
  1057.  
  1058.  
  1059.         for(cur_index = 0; cur_index < wsSize; cur_index++)
  1060.  
  1061.         {
  1062.  
  1063.                 if(lru_timestamp > ws[cur_index].time_stamp)
  1064.  
  1065.                 {
  1066.  
  1067.                         lru_index = cur_index;
  1068.  
  1069.                         lru_timestamp = ws[cur_index].time_stamp;
  1070.  
  1071.                 }
  1072.  
  1073.         }
  1074.  
  1075.  
  1076.  
  1077.         assert(lru_index != -1);
  1078.  
  1079.         return lru_index;
  1080.  
  1081. }
  1082.  
  1083. void removePageVictim(struct Env* env, int victimIndex)
  1084.  
  1085. {
  1086.  
  1087.         uint32 VA = env->pageWorkingSet[victimIndex].virtual_address;
  1088.  
  1089.         uint32* ptrTable;
  1090.  
  1091.         get_page_table(env->env_pgdir, (void*) VA, &ptrTable);
  1092.  
  1093.         uint32 victimPA = ptrTable[PTX(VA)];
  1094.  
  1095.         struct Frame_Info* ptrVictimFrame = to_frame_info(EXTRACT_ADDRESS(victimPA));
  1096.  
  1097.         ptrVictimFrame ->isBuffered = 1;
  1098.  
  1099.         ptrVictimFrame ->environment = env;
  1100.  
  1101.         ptrVictimFrame ->va = VA;
  1102.  
  1103.  
  1104.  
  1105.         pt_set_page_permissions(env, VA, PERM_BUFFERED, PERM_PRESENT);
  1106.  
  1107.  
  1108.  
  1109.         if ((victimPA & PERM_MODIFIED) != PERM_MODIFIED)
  1110.  
  1111.                 bufferList_add_page(&free_frame_list, ptrVictimFrame);
  1112.  
  1113.         else
  1114.  
  1115.         {
  1116.  
  1117.                 bufferList_add_page(&modified_frame_list, ptrVictimFrame);
  1118.  
  1119.  
  1120.  
  1121.                 if (modified_frame_list.size == MAX_MODIFIED_LIST_COUNT)
  1122.  
  1123.                 {
  1124.  
  1125.                         struct Frame_Info* curPtrFrameInfo;
  1126.  
  1127.                         LIST_FOREACH(curPtrFrameInfo,&modified_frame_list)
  1128.  
  1129.                         {
  1130.  
  1131.                                 if (curPtrFrameInfo->environment == env)
  1132.  
  1133.                                 {
  1134.  
  1135.                                         pf_update_env_page(env,(uint32*)curPtrFrameInfo->va,curPtrFrameInfo);
  1136.  
  1137.                                         pt_set_page_permissions(env,curPtrFrameInfo->va,0,PERM_MODIFIED);
  1138.  
  1139.                                         bufferlist_remove_page(&modified_frame_list,curPtrFrameInfo);
  1140.  
  1141.                                         bufferList_add_page(&free_frame_list,curPtrFrameInfo);
  1142.  
  1143.                                 }
  1144.  
  1145.                         }
  1146.  
  1147.  
  1148.  
  1149.                 }
  1150.  
  1151.  
  1152.  
  1153.         }
  1154.  
  1155.  
  1156.  
  1157. }
  1158.  
  1159. void removeTableVictim(struct Env* env , int victimIndex)
  1160.  
  1161. {
  1162.  
  1163.         uint32* ptrTable;
  1164.  
  1165.         uint32* VA=(uint32*)env->pageWorkingSet[victimIndex].virtual_address;
  1166.  
  1167.         pf_write_env_table(env,env->pageWorkingSet[victimIndex].virtual_address,ptrTable);
  1168.  
  1169.         env->env_pgdir[PDX(ptrTable)] &= ~PERM_PRESENT;
  1170.  
  1171.         struct Frame_Info* ptr_TableFrameinfo= to_frame_info(K_PHYSICAL_ADDRESS(ptrTable));
  1172.  
  1173.         free_frame(ptr_TableFrameinfo);
  1174.  
  1175.         ptr_TableFrameinfo ->references=0;
  1176.  
  1177.         env_table_ws_clear_entry(env,victimIndex);
  1178.  
  1179. }
  1180.  
  1181.  
  1182.  
  1183. int placeFaultedPage(struct Env* env,uint32 fault_va,int Index)
  1184.  
  1185. {
  1186.  
  1187.         //cprintf("placeFaultedPage\n");
  1188.  
  1189.         //uint32 VA = env->pageWorkingSet[Index].virtual_address;
  1190.  
  1191.         uint32* ptrTable;
  1192.  
  1193.         uint32 PA;
  1194.  
  1195.         get_page_table(env->env_pgdir,(void*)fault_va,&ptrTable);
  1196.  
  1197.         PA = ptrTable[PTX(fault_va)];
  1198.  
  1199.  
  1200.  
  1201.         if((PA & PERM_BUFFERED ) == PERM_BUFFERED)
  1202.  
  1203.         {
  1204.  
  1205.                 pt_set_page_permissions(env,fault_va,PERM_PRESENT,PERM_BUFFERED);
  1206.  
  1207.                 struct Frame_Info* ptrBufferedPageFrameInfo= to_frame_info(EXTRACT_ADDRESS(PA));
  1208.  
  1209.                 ptrBufferedPageFrameInfo->isBuffered=0;
  1210.  
  1211.  
  1212.  
  1213.                 if( (PA & PERM_MODIFIED ) == PERM_MODIFIED)
  1214.  
  1215.                         bufferlist_remove_page(&modified_frame_list,ptrBufferedPageFrameInfo);
  1216.  
  1217.                 else
  1218.  
  1219.                         bufferlist_remove_page(&free_frame_list,ptrBufferedPageFrameInfo);
  1220.  
  1221.         }
  1222.  
  1223.         else
  1224.  
  1225.         {
  1226.  
  1227.                 struct Frame_Info* ptrPlacedPageFrameinfo ;
  1228.  
  1229.                 allocate_frame(&ptrPlacedPageFrameinfo);
  1230.  
  1231.                 map_frame(env->env_pgdir,ptrPlacedPageFrameinfo,(void*)fault_va,PERM_PRESENT | PERM_USER | PERM_WRITEABLE | PERM_USED);
  1232.  
  1233.                 int ret = pf_read_env_page(env,(void*)fault_va);
  1234.  
  1235.                 if(ret == E_PAGE_NOT_EXIST_IN_PF)
  1236.  
  1237.                 {
  1238.  
  1239.                         if(fault_va >= USER_HEAP_MAX && fault_va <= USTACKTOP)
  1240.  
  1241.                                 pf_add_empty_env_page(env,fault_va);
  1242.  
  1243.                 }
  1244.  
  1245.         }
  1246.  
  1247.         env_page_ws_set_entry(env,Index,fault_va);
  1248.  
  1249.         env->page_last_WS_index = (Index + 1) % PAGE_WS_MAX_SIZE;
  1250.  
  1251.         return 0;
  1252.  
  1253. }
  1254.  
  1255. int placeFaultedTable(struct Env* env,uint32 fault_va,int Index)
  1256.  
  1257. {
  1258.  
  1259.         //cprintf("placeFaultedTable  , %x\n",env->env_pgdir[PDX(fault_va)]);
  1260.  
  1261.         uint32* ptrNewTable;
  1262.  
  1263.  
  1264.  
  1265.         //uint32 directory_entry = env->env_pgdir[PDX(fault_va)];
  1266.  
  1267.         cprintf("dir index : %u\n",PDX(fault_va));
  1268.  
  1269.         if(env->env_pgdir[PDX(fault_va)] == 0)
  1270.  
  1271.                 create_page_table(env->env_pgdir,fault_va,&ptrNewTable);
  1272.  
  1273.         else
  1274.  
  1275.         {
  1276.  
  1277.                 pf_read_env_table(env,fault_va,ptrNewTable);
  1278.  
  1279.                 pf_remove_env_table(env,fault_va);
  1280.  
  1281.         }
  1282.  
  1283.         env_table_ws_set_entry(env,Index,fault_va);
  1284.  
  1285.         env->table_last_WS_index = (Index + 1) % TABLE_WS_MAX_SIZE;
  1286.  
  1287.         return 0;
  1288.  
  1289. }