Palacios Public Git Repository

To checkout Palacios execute

  git clone http://v3vee.org/palacios/palacios.web/palacios.git
This will give you the master branch. You probably want the devel branch or one of the release branches. To switch to the devel branch, simply execute
  cd palacios
  git checkout --track -b devel origin/devel
The other branches are similar.


Release 1.0
[palacios.git] / palacios / src / geekos / lowlevel.asm
diff --git a/palacios/src/geekos/lowlevel.asm b/palacios/src/geekos/lowlevel.asm
deleted file mode 100644 (file)
index 63f93c2..0000000
+++ /dev/null
@@ -1,576 +0,0 @@
-; -*- fundamental -*-
-; Low level interrupt/thread handling code for GeekOS.
-; Copyright (c) 2001,2003,2004 David H. Hovemeyer <daveho@cs.umd.edu>
-; Copyright (c) 2003, Jeffrey K. Hollingsworth <hollings@cs.umd.edu>
-; $Revision: 1.1 $
-
-; This is free software.  You are permitted to use,
-; redistribute, and modify it as specified in the file "COPYING".
-
-; This is 32 bit code to be linked into the kernel.
-; It defines low level interrupt handler entry points that we'll use
-; to populate the IDT.  It also contains the interrupt handling
-; and thread context switch code.
-
-%include "defs.asm"
-%include "symbol.asm"
-%include "util.asm"
-
-
-[BITS 32]
-
-; ----------------------------------------------------------------------
-; Definitions
-; ----------------------------------------------------------------------
-
-; This is the size of the Interrupt_State struct in int.h
-INTERRUPT_STATE_SIZE equ 64
-
-; Save registers prior to calling a handler function.
-; This must be kept up to date with:
-;   - Interrupt_State struct in int.h
-;   - Setup_Initial_Thread_Context() in kthread.c
-%macro Save_Registers 0
-       push    eax
-       push    ebx
-       push    ecx
-       push    edx
-       push    esi
-       push    edi
-       push    ebp
-       push    ds
-       push    es
-       push    fs
-       push    gs
-%endmacro
-
-; Restore registers and clean up the stack after calling a handler function
-; (i.e., just before we return from the interrupt via an iret instruction).
-%macro Restore_Registers 0
-       pop     gs
-       pop     fs
-       pop     es
-       pop     ds
-       pop     ebp
-       pop     edi
-       pop     esi
-       pop     edx
-       pop     ecx
-       pop     ebx
-       pop     eax
-       add     esp, 8  ; skip int num and error code
-%endmacro
-
-; Code to activate a new user context (if necessary), before returning
-; to executing a thread.  Should be called just before restoring
-; registers (because the interrupt context is used).
-%macro Activate_User_Context 0 
-       ; If the new thread has a user context which is not the current
-       ; one, activate it.
-       push    esp                     ; Interrupt_State pointer
-       push    dword [g_currentThread] ; Kernel_Thread pointer
-;      call    Switch_To_User_Context 
-       add     esp, 8                  ; clear 2 arguments
-%endmacro
-
-; Number of bytes between the top of the stack and
-; the interrupt number after the general-purpose and segment
-; registers have been saved.
-REG_SKIP equ (11*4)
-
-; Template for entry point code for interrupts that have
-; an explicit processor-generated error code.
-; The argument is the interrupt number.
-%macro Int_With_Err 1
-align 8
-       push    dword %1        ; push interrupt number
-       jmp     Handle_Interrupt ; jump to common handler
-%endmacro
-
-; Template for entry point code for interrupts that do not
-; generate an explicit error code.  We push a dummy error
-; code on the stack, so the stack layout is the same
-; for all interrupts.
-%macro Int_No_Err 1
-align 8
-       push    dword 0         ; fake error code
-       push    dword %1        ; push interrupt number
-       jmp     Handle_Interrupt ; jump to common handler
-%endmacro
-
-
-; ----------------------------------------------------------------------
-; Symbol imports and exports
-; ----------------------------------------------------------------------
-
-; This symbol is defined in idt.c, and is a table of addresses
-; of C handler functions for interrupts.
-IMPORT g_interruptTable
-
-; Global variable pointing to context struct for current thread.
-IMPORT g_currentThread
-
-; Set to non-zero when we need to choose a new thread
-; in the interrupt return code.
-IMPORT g_needReschedule
-
-; Set to non-zero when preemption is disabled.
-IMPORT g_preemptionDisabled
-
-; This is the function that returns the next runnable thread.
-IMPORT Get_Next_Runnable
-
-; Function to put a thread on the run queue.
-IMPORT Make_Runnable
-
-; Function to activate a new user context (if needed).
-IMPORT Switch_To_User_Context
-
-; Sizes of interrupt handler entry points for interrupts with
-; and without error codes.  The code in idt.c uses this
-; information to infer the layout of the table of interrupt
-; handler entry points, without needing a separate linker
-; symbol for each one (which is quite tedious to type :-)
-EXPORT g_handlerSizeNoErr
-EXPORT g_handlerSizeErr
-
-; Simple functions to load the IDTR, GDTR, and LDTR.
-EXPORT Load_IDTR
-EXPORT Load_GDTR
-EXPORT Load_LDTR
-
-; Beginning and end of the table of interrupt entry points.
-EXPORT g_entryPointTableStart
-EXPORT g_entryPointTableEnd
-
-; Thread context switch function.
-EXPORT Switch_To_Thread
-
-; Return current value of eflags register.
-EXPORT Get_Current_EFLAGS
-
-; Return the return address
-EXPORT Get_EIP
-; ESP
-EXPORT Get_ESP
-; EBP
-EXPORT Get_EBP
-
-; Virtual memory support.
-EXPORT Enable_Paging
-EXPORT Set_PDBR
-EXPORT Get_PDBR
-EXPORT Flush_TLB
-
-; CPUID functions
-EXPORT cpuid_ecx
-EXPORT cpuid_eax
-
-; Utility Functions
-EXPORT Set_MSR
-EXPORT Get_MSR
-
-EXPORT Get_CR2
-
-
-EXPORT Proc_test
-
-; ----------------------------------------------------------------------
-; Code
-; ----------------------------------------------------------------------
-
-[SECTION .text]
-
-; Load IDTR with 6-byte pointer whose address is passed as
-; the parameter.
-align 8
-Load_IDTR:
-       mov     eax, [esp+4]
-       lidt    [eax]
-       ret
-
-;  Load the GDTR with 6-byte pointer whose address is
-; passed as the parameter.  Assumes that interrupts
-; are disabled.
-align 8
-Load_GDTR:
-       mov     eax, [esp+4]
-       lgdt    [eax]
-       ; Reload segment registers
-       mov     ax, KERNEL_DS
-       mov     ds, ax
-       mov     es, ax
-       mov     fs, ax
-       mov     gs, ax
-       mov     ss, ax
-       jmp     KERNEL_CS:.here
-.here:
-       ret
-
-; Load the LDT whose selector is passed as a parameter.
-align 8
-Load_LDTR:
-       mov     eax, [esp+4]
-       lldt    ax
-       ret
-
-;
-; Start paging
-;      load crt3 with the passed page directory pointer
-;      enable paging bit in cr2
-align 8
-Enable_Paging:
-       push    ebp
-       mov     ebp, esp
-       push    eax
-       push    ebx
-       mov     eax, [ebp+8]
-       mov     cr3, eax
-       mov     eax, cr3
-       mov     cr3, eax
-       mov     ebx, cr0
-       or      ebx, 0x80000000
-       mov     cr0, ebx
-       pop     ebx
-       pop     eax
-       pop     ebp
-       ret
-
-
-
-
-       
-;
-; Change PDBR 
-;      load cr3 with the passed page directory pointer
-align 8
-Set_PDBR:
-       mov     eax, [esp+4]
-       mov     cr3, eax
-       ret
-
-;
-; Get the current PDBR.
-; This is useful for lazily switching address spaces;
-; only switch if the new thread has a different address space.
-;
-align 8
-Get_PDBR:
-       mov     eax, cr3
-       ret
-
-;
-; Flush TLB - just need to re-load cr3 to force this to happen
-;
-align 8
-Flush_TLB:
-       mov     eax, cr3
-       mov     cr3, eax
-       ret
-
-
-;
-; cpuid_ecx - return the ecx register from cpuid
-;
-align 8
-cpuid_ecx:
-       push    ebp
-       mov     ebp, esp
-       push    ecx
-       mov     eax, [ebp + 8]
-       cpuid
-       mov     eax, ecx
-       pop     ecx
-       pop     ebp
-       ret
-
-;
-; cpuid_eax - return the eax register from cpuid
-;
-align 8
-cpuid_eax:
-       mov     eax, [esp+4]
-       cpuid
-       ret
-
-;
-; Set_MSR  - Set the value of a given MSR
-;
-align 8
-Set_MSR:
-       push    ebp
-       mov     ebp, esp
-       pusha
-       mov     eax, [ebp+16]
-       mov     edx, [ebp+12]
-       mov     ecx, [ebp+8]
-       wrmsr
-       popa
-       pop     ebp
-       ret
-
-
-
-;
-; Get_MSR  -  Get the value of a given MSR
-; void Get_MSR(int MSR, void * high_byte, void * low_byte);
-;
-align 8
-Get_MSR:
-       push    ebp
-       mov     ebp, esp
-       pusha
-       mov     ecx, [ebp+8]
-       rdmsr
-       mov     ebx, [ebp+12]
-       mov     [ebx], edx
-       mov     ebx, [ebp+16]
-       mov     [ebx], eax
-       popa
-       pop     ebp
-       ret
-
-
-
-align 8
-Get_CR2:
-       mov     eax, cr2
-       ret
-
-
-align 8
-Proc_test:
-       push    ebp
-       mov     ebp, esp
-       push    ebx
-       mov     ebx, [ebp + 8]
-       mov     eax, [ebp + 12]
-
-       add     eax, ebx
-       pop     ebx
-       pop     ebp
-       ret
-
-
-; Common interrupt handling code.
-; Save registers, call C handler function,
-; possibly choose a new thread to run, restore
-; registers, return from the interrupt.
-align 8
-Handle_Interrupt:
-       ; Save registers (general purpose and segment)
-       Save_Registers
-
-       ; Ensure that we're using the kernel data segment
-       mov     ax, KERNEL_DS
-       mov     ds, ax
-       mov     es, ax
-
-       ; Get the address of the C handler function from the
-       ; table of handler functions.
-       mov     eax, g_interruptTable   ; get address of handler table
-       mov     esi, [esp+REG_SKIP]     ; get interrupt number
-       mov     ebx, [eax+esi*4]        ; get address of handler function
-
-       ; Call the handler.
-       ; The argument passed is a pointer to an Interrupt_State struct,
-       ; which describes the stack layout for all interrupts.
-       push    esp
-       call    ebx
-       add     esp, 4                  ; clear 1 argument
-
-       ; If preemption is disabled, then the current thread
-       ; keeps running.
-       cmp     [g_preemptionDisabled], dword 0
-       jne     .restore
-
-       ; See if we need to choose a new thread to run.
-       cmp     [g_needReschedule], dword 0
-       je      .restore
-
-       ; Put current thread back on the run queue
-       push    dword [g_currentThread]
-       call    Make_Runnable
-       add     esp, 4                  ; clear 1 argument
-
-       ; Save stack pointer in current thread context, and
-       ; clear numTicks field.
-       mov     eax, [g_currentThread]
-       mov     [eax+0], esp            ; esp field
-       mov     [eax+4], dword 0        ; numTicks field
-
-       ; Pick a new thread to run, and switch to its stack
-       call    Get_Next_Runnable
-       mov     [g_currentThread], eax
-       mov     esp, [eax+0]            ; esp field
-
-       ; Clear "need reschedule" flag
-       mov     [g_needReschedule], dword 0
-
-.restore:
-       ; Activate the user context, if necessary.
-       Activate_User_Context
-
-       ; Restore registers
-       Restore_Registers
-
-       ; Return from the interrupt.
-       iret
-
-; ----------------------------------------------------------------------
-; Switch_To_Thread()
-;   Save context of currently executing thread, and activate
-;   the thread whose context object is passed as a parameter.
-; 
-; Parameter: 
-;   - ptr to Kernel_Thread whose state should be restored and made active
-;
-; Notes:
-; Called with interrupts disabled.
-; This must be kept up to date with definition of Kernel_Thread
-; struct, in kthread.h.
-; ----------------------------------------------------------------------
-align 16
-Switch_To_Thread:
-       ; Modify the stack to allow a later return via an iret instruction.
-       ; We start with a stack that looks like this:
-       ;
-       ;            thread_ptr
-       ;    esp --> return addr
-       ;
-       ; We change it to look like this:
-       ;
-       ;            thread_ptr
-       ;            eflags
-       ;            cs
-       ;    esp --> return addr
-
-       push    eax             ; save eax
-       mov     eax, [esp+4]    ; get return address
-       mov     [esp-4], eax    ; move return addr down 8 bytes from orig loc
-       add     esp, 8          ; move stack ptr up
-       pushfd                  ; put eflags where return address was
-       mov     eax, [esp-4]    ; restore saved value of eax
-       push    dword KERNEL_CS ; push cs selector
-       sub     esp, 4          ; point stack ptr at return address
-
-       ; Push fake error code and interrupt number
-       push    dword 0
-       push    dword 0
-
-       ; Save general purpose registers.
-       Save_Registers
-
-       ; Save stack pointer in the thread context struct (at offset 0).
-       mov     eax, [g_currentThread]
-       mov     [eax+0], esp
-
-       ; Clear numTicks field in thread context, since this
-       ; thread is being suspended.
-       mov     [eax+4], dword 0
-
-       ; Load the pointer to the new thread context into eax.
-       ; We skip over the Interrupt_State struct on the stack to
-       ; get the parameter.
-       mov     eax, [esp+INTERRUPT_STATE_SIZE]
-
-       ; Make the new thread current, and switch to its stack.
-       mov     [g_currentThread], eax
-       mov     esp, [eax+0]
-
-       ; Activate the user context, if necessary.
-       Activate_User_Context
-
-       ; Restore general purpose and segment registers, and clear interrupt
-       ; number and error code.
-       Restore_Registers
-
-       ; We'll return to the place where the thread was
-       ; executing last.
-       iret
-
-; Return current contents of eflags register.
-align 16
-Get_Current_EFLAGS:
-       pushfd                  ; push eflags
-       pop     eax             ; pop contents into eax
-       ret
-
-
-
-; Return the eip of the next instruction after the caller
-align 16
-Get_EIP:
-       mov     eax, [esp]
-       ret
-
-; Return the current esp in the procedure
-align 16
-Get_ESP:
-       mov     eax, esp
-       ret
-
-; Return the current ebp in the procedure
-align 16
-Get_EBP:
-       mov     eax, ebp
-       ret
-
-
-
-; ----------------------------------------------------------------------
-; Generate interrupt-specific entry points for all interrupts.
-; We also define symbols to indicate the extend of the table
-; of entry points, and the size of individual entry points.
-; ----------------------------------------------------------------------
-align 8
-g_entryPointTableStart:
-
-; Handlers for processor-generated exceptions, as defined by
-; Intel 486 manual.
-Int_No_Err 0
-align 8
-Before_No_Err:
-Int_No_Err 1
-align 8
-After_No_Err:
-Int_No_Err 2   ; FIXME: not described in 486 manual
-Int_No_Err 3
-Int_No_Err 4
-Int_No_Err 5
-Int_No_Err 6
-Int_No_Err 7
-align 8
-Before_Err:
-Int_With_Err 8
-align 8
-After_Err:
-Int_No_Err 9   ; FIXME: not described in 486 manual
-Int_With_Err 10
-Int_With_Err 11
-Int_With_Err 12
-Int_With_Err 13
-Int_With_Err 14
-Int_No_Err 15  ; FIXME: not described in 486 manual
-Int_No_Err 16
-Int_With_Err 17
-
-; The remaining interrupts (18 - 255) do not have error codes.
-; We can generate them all in one go with nasm's %rep construct.
-%assign intNum 18
-%rep (256 - 18)
-Int_No_Err intNum
-%assign intNum intNum+1
-%endrep
-
-align 8
-g_entryPointTableEnd:
-
-[SECTION .data]
-
-; Exported symbols defining the size of handler entry points
-; (both with and without error codes).
-align 4
-g_handlerSizeNoErr: dd (After_No_Err - Before_No_Err)
-align 4
-g_handlerSizeErr: dd (After_Err - Before_Err)