Changeset f2ef7fd in mainline for kernel


Ignore:
Timestamp:
2008-10-05T21:20:13Z (17 years ago)
Author:
Jakub Jermar <jakub@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
6198611
Parents:
1d132ae
Message:

Support for SYSENTER on ia32.

Location:
kernel/arch
Files:
2 added
7 edited

Legend:

Unmodified
Added
Removed
  • kernel/arch/amd64/include/syscall.h

    r1d132ae rf2ef7fd  
    3636#define KERN_amd64_SYSCALL_H_
    3737
    38 #include <arch/types.h>
    39 
    4038extern void syscall_setup_cpu(void);
    4139
  • kernel/arch/ia32/Makefile.inc

    r1d132ae rf2ef7fd  
    161161        arch/$(ARCH)/src/boot/memmap.c \
    162162        arch/$(ARCH)/src/fpu_context.c \
    163         arch/$(ARCH)/src/debugger.c
     163        arch/$(ARCH)/src/debugger.c \
     164        arch/$(ARCH)/src/syscall.c
  • kernel/arch/ia32/include/asm.h

    r1d132ae rf2ef7fd  
    248248}
    249249
     250/** Write to MSR */
     251static inline void write_msr(uint32_t msr, uint64_t value)
     252{
     253        asm volatile ("wrmsr" : : "c" (msr), "a" ((uint32_t)(value)),
     254            "d" ((uint32_t)(value >> 32)));
     255}
     256
     257static inline uint64_t read_msr(uint32_t msr)
     258{
     259        uint32_t ax, dx;
     260
     261        asm volatile ("rdmsr" : "=a"(ax), "=d"(dx) : "c" (msr));
     262        return ((uint64_t)dx << 32) | ax;
     263}
     264
     265
    250266/** Return base address of current stack
    251267 *
  • kernel/arch/ia32/include/cpu.h

    r1d132ae rf2ef7fd  
    3636#define KERN_ia32_CPU_H_
    3737
     38#define EFLAGS_IF       (1 << 9)
     39#define EFLAGS_RF       (1 << 16)
     40
     41#define CR4_OSFXSR_MASK (1<<9)
     42
     43/* Support for SYSENTER and SYSEXIT */
     44#define IA32_MSR_SYSENTER_CS    0x174
     45#define IA32_MSR_SYSENTER_ESP   0x175
     46#define IA32_MSR_SYSENTER_EIP   0x176
     47
     48#ifndef __ASM__
     49
    3850#include <arch/pm.h>
    3951#include <arch/asm.h>
    40 
    41 #define EFLAGS_IF       (1 << 9)
    42 #define EFLAGS_RF       (1 << 16)
    4352
    4453typedef struct {
     
    5261} cpu_arch_t;
    5362
    54 
    55 #define CR4_OSFXSR_MASK (1<<9)
     63#endif
    5664
    5765#endif
  • kernel/arch/ia32/src/asm.S

    r1d132ae rf2ef7fd  
    147147        popfl
    148148.endm   
     149
     150/*
     151 * The SYSENTER syscall mechanism can be used for syscalls with
     152 * four or fewer arguments. To pass these four arguments, we
     153 * use four registers: EDX, ECX, EBX, ESI. The syscall number
     154 * is passed in EAX. We use EDI to remember the return address
     155 * and EBP to remember the stack. The INT-based syscall mechanism
     156 * can actually handle six arguments plus the syscall number
     157 * entirely in registers.
     158 */
     159.global sysenter_handler
     160sysenter_handler:
     161        pushl %ebp      # remember user stack
     162        pushl %edi      # remember return user address
     163
     164        pushl %gs       # remember TLS
     165
     166        pushl %eax      # syscall number
     167        subl $8, %esp   # unused sixth and fifth argument
     168        pushl %esi      # fourth argument
     169        pushl %ebx      # third argument
     170        pushl %ecx      # second argument
     171        pushl %edx      # first argument
     172
     173        movw $16, %ax
     174        movw %ax, %ds
     175        movw %ax, %es
     176
     177        cld
     178        call syscall_handler
     179        addl $28, %esp  # remove arguments from stack
     180
     181        pop %gs         # restore TLS
     182
     183        pop %edx        # prepare return EIP for SYSEXIT
     184        pop %ecx        # prepare userspace ESP for SYSEXIT
     185
     186        sysexit         # return to userspace
     187
    149188
    150189## Declare interrupt handlers
  • kernel/arch/ia32/src/cpu/cpu.c

    r1d132ae rf2ef7fd  
    4343
    4444#include <arch/smp/apic.h>
     45#include <arch/syscall.h>
    4546
    4647/*
     
    124125                );
    125126        }
     127       
     128        /* Setup fast SYSENTER/SYSEXIT syscalls */
     129        syscall_setup_cpu();
    126130}
    127131
  • kernel/arch/ia32/src/proc/scheduler.c

    r1d132ae rf2ef7fd  
    5959void before_thread_runs_arch(void)
    6060{
    61         CPU->arch.tss->esp0 = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE -
     61        uintptr_t kstk = (uintptr_t) &THREAD->kstack[THREAD_STACK_SIZE -
    6262            SP_DELTA];
     63
     64        /* Set kernel stack for CP3 -> CPL0 switch via SYSENTER */
     65        write_msr(IA32_MSR_SYSENTER_ESP, kstk);
     66
     67        /* Set kernel stack for CPL3 -> CPL0 switch via interrupt */
     68        CPU->arch.tss->esp0 = kstk;
    6369        CPU->arch.tss->ss0 = selector(KDATA_DES);
    6470
Note: See TracChangeset for help on using the changeset viewer.