/*
    Copyright 2007 (c) by S. Ryffel,
    Swiss Federal Institute of Technology,
    Computer Engineering and Networks Laboratory.

    TOPSY -- A Teachable Operating System.
             Implementation of a tiny and simple
             micro kernel for teaching purposes.

    For further information, please visit http://www.tik.ee.ethz.ch/~topsy

    This software is provided under the terms of the GNU General Public 
    Licence. A full copy of the GNU GPL is provided in the file COPYING 
    found in the development root of Topsy.
*/
/*
	
    File:                  $Source$
    Affiliation:           ETH Zuerich, TIK
    Version:               $Revision$
    Last Date of Change:   $Date$  by: $Author$

*/

#include "asm.h"                /* Topsy/ia32/ */
#include "MemoryLayout.h"       /* Memory/ia32/ */

#define KILOBYTE        1024
#define MEGABYTE        1024*KILOBYTE
#define HALFMEGA         512*KILOBYTE
#define BITSPERPAGE     4096*8

////
// void __zero_page(ushort sel, ulong page_addr);
////
ASM_PROC_FRAME(__zero_page)
        ENTER
        pushl   %eax
        pushl   %ecx
        pushl   %edi
        pushw   %es

        movl    ARG1,%eax
        movw    %ax,%es
        xorl    %eax,%eax
        movl    ARG2,%edi
        movl    $4095,%ecx
        rep
        stosb

        popw    %es
        popl    %edi
        popl    %ecx
        popl    %eax
        LEAVE

////
// void __set_PDBR(int pdbr);
////
ASM_PROC_FRAME(__set_PDBR)
  ENTER
  pushl   %eax
  
  movl    ARG1,%eax
  movl    %eax,%cr3
  
  popl    %eax
  LEAVE


////
// int __get_PDBR(void);
////
ASM_PROC_FRAME(__get_PDBR)
  ENTER
  
  movl    %cr3,%eax
  
  LEAVE


////
// void __activate_MMU(void);
////
ASM_PROC_FRAME(__activate_MMU)
  ENTER
  pushl   %eax
  
  movl    %cr0, %eax        
  orl     $0x80000000, %eax   // set the Paging Enable Bit (Bit 31)
  movl    %eax, %cr0
  ljmp    $GC_OS_CODE_SEL,$1f	/* Clear prefetch and normalize %eip */
1:

  popl    %eax
  LEAVE

////
// unsigned long __get_page_fault_addr(void);
////

ASM_PROC_FRAME(__get_page_fault_addr)
  ENTER
  
  movl    %cr2, %eax    // %cr2 holds the Page Fault Linear Address
  
  LEAVE

/*
////
// unsigned long __get_page_fault_eip(void);
////

ASM_PROC_FRAME(__get_page_fault_eip)
  ENTER
  
  movl    %cr2, %eax    // %cr2 holds the Page Fault Linear Address
  
  LEAVE
*/

////
// void __inv_tlb(void);
////
 ASM_PROC_FRAME(__inv_tlb)
  ENTER
  pushl   %eax

  movl    %cr3,%eax   
  movl    %eax,%cr3   // reloading %cr3 invalidates the TLB
                      //  (XXX except global pages)

  popl    %eax
  LEAVE
 


////
// void __inv_tlb_entry(unsigned long virt);
////

ASM_PROC_FRAME(__inv_tlb_entry)
  ENTER
  pushl   %eax

  movl    ARG1,%eax
  invlpg  (%eax)      // invalidate entry containing the memory location %eax

  popl    %eax
  LEAVE


////
// void __cli(int* flags);
////

ASM_PROC_FRAME(__cli)
  ENTER
  pushl   %eax

  pushfl
  
  movl    ARG1, %eax
  popl    (%eax)

  cli

  popl    %eax
  LEAVE

////
// void __sti(int* flags);
////

ASM_PROC_FRAME(__sti)
  ENTER
  pushl   %eax

  pushfl
  
  movl    ARG1, %eax
  popl    (%eax)

  sti

  popl    %eax
  LEAVE



////
// void __restore_flags(int flags);
////

ASM_PROC_FRAME(__restore_flags)
  ENTER

  pushl   ARG1
  popfl
  
  LEAVE

