Changeset f2ef7fd in mainline


Ignore:
Timestamp:
2008-10-05T21:20:13Z (16 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.

Files:
2 added
20 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
  • uspace/app/trace/trace.c

    r1d132ae rf2ef7fd  
    3636#include <stdlib.h>
    3737#include <unistd.h>
    38 #include <syscall.h>
    3938#include <ipc/ipc.h>
    4039#include <fibril.h>
     
    4443#include <task.h>
    4544#include <loader/loader.h>
     45
     46#include <libc.h>
    4647
    4748// Temporary: service and method names
  • uspace/lib/libc/arch/amd64/include/syscall.h

    r1d132ae rf2ef7fd  
    3737#define LIBC_amd64_SYSCALL_H_
    3838
     39#define LIBARCH_SYSCALL_GENERIC
     40
    3941#include <syscall.h>
    4042
  • uspace/lib/libc/arch/arm32/include/syscall.h

    r1d132ae rf2ef7fd  
    3131 */
    3232/** @file
    33  *  @brief Empty.
     33 *  @brief
    3434 */
    3535
    3636#ifndef LIBC_arm32_SYSCALL_H_
    3737#define LIBC_arm32_SYSCALL_H_
     38
     39#define LIBARCH_SYSCALL_GENERIC
    3840
    3941#include <syscall.h>
  • uspace/lib/libc/arch/ia32/include/syscall.h

    r1d132ae rf2ef7fd  
    3737#define LIBC_ia32_SYSCALL_H_
    3838
    39 #include <syscall.h>
     39#include <sys/types.h>
     40#include <kernel/syscall/syscall.h>
     41
     42#define __syscall0      __syscall_sysenter
     43#define __syscall1      __syscall_sysenter
     44#define __syscall2      __syscall_sysenter
     45#define __syscall3      __syscall_sysenter
     46#define __syscall4      __syscall_sysenter
     47#define __syscall5      __syscall_int
     48#define __syscall6      __syscall_int
     49
     50extern sysarg_t
     51__syscall_sysenter(const sysarg_t, const sysarg_t, const sysarg_t, const sysarg_t,
     52     const sysarg_t, const sysarg_t, const syscall_t);
     53
     54extern sysarg_t
     55__syscall_int(const sysarg_t, const sysarg_t, const sysarg_t, const sysarg_t,
     56     const sysarg_t, const sysarg_t, const syscall_t);
    4057
    4158#endif
  • uspace/lib/libc/arch/ia32/src/syscall.S

    r1d132ae rf2ef7fd  
    2929.text
    3030
    31 /** Syscall wrapper.
     31/** Syscall wrapper - INT $0x30 version.
    3232 *
    3333 * Mind the order of arguments. First two arguments and the syscall number go to
     
    3535 * could benefit from this and not save unused registers on the stack.
    3636 */
    37 .global __syscall
    38 __syscall:
     37.global __syscall_int
     38__syscall_int:
    3939        pushl %ebx
    4040        pushl %esi
     
    5454        popl %ebx
    5555        ret
     56
     57
     58/** Syscall wrapper - SYSENTER version.
     59 *
     60 * This is an optimized version of syscall for four or less arguments.  Note
     61 * that EBP and EDI are used to remember user stack address and the return
     62 * address. The kernel part doesn't save DS, ES and FS so the handler restores
     63 * these to the selector immediately following CS (it must be the flat data
     64 * segment, otherwise the SYSENTER wouldn't work in the first place).
     65 */
     66.global __syscall_sysenter
     67__syscall_sysenter:
     68        pushl %ebx
     69        pushl %esi
     70        pushl %edi
     71        pushl %ebp
     72        mov %esp, %ebp
     73        lea ra, %edi
     74        movl 20(%esp), %edx     # First argument.
     75        movl 24(%esp), %ecx     # Second argument.
     76        movl 28(%esp), %ebx     # Third argument.
     77        movl 32(%esp), %esi     # Fourth argument.
     78        movl 44(%esp), %eax     # Syscall number.
     79        sysenter
     80ra:
     81        movw %cs, %cx
     82        addw $8, %cx
     83        movw %cx, %ds
     84        movw %cx, %es
     85        movw %cx, %fs
     86        popl %ebp
     87        popl %edi
     88        popl %esi
     89        popl %ebx
     90        ret
  • uspace/lib/libc/arch/ia64/include/syscall.h

    r1d132ae rf2ef7fd  
    3737#define LIBC_ia64_SYSCALL_H_
    3838
     39#define LIBARCH_SYSCALL_GENERIC
     40
    3941#include <syscall.h>
    4042
  • uspace/lib/libc/arch/mips32/include/syscall.h

    r1d132ae rf2ef7fd  
    3737#define LIBC_mips32_SYSCALL_H_
    3838
     39#define LIBARCH_SYSCALL_GENERIC
     40
    3941#include <syscall.h>
    4042
  • uspace/lib/libc/arch/ppc32/include/syscall.h

    r1d132ae rf2ef7fd  
    3737#define LIBC_ppc32_SYSCALL_H_
    3838
     39#define LIBARCH_SYSCALL_GENERIC
     40
    3941#include <syscall.h>
    4042
  • uspace/lib/libc/arch/ppc64/include/syscall.h

    r1d132ae rf2ef7fd  
    3737#define LIBC_ppc64_SYSCALL_H_
    3838
     39#define LIBARCH_SYSCALL_GENERIC
     40
    3941#include <syscall.h>
    4042
  • uspace/lib/libc/arch/sparc64/include/syscall.h

    r1d132ae rf2ef7fd  
    3939#include <kernel/syscall/syscall.h>
    4040
     41#define __syscall0      __syscall
     42#define __syscall1      __syscall
     43#define __syscall2      __syscall
     44#define __syscall3      __syscall
     45#define __syscall4      __syscall
     46#define __syscall5      __syscall
     47#define __syscall6      __syscall
     48
    4149static inline sysarg_t
    4250__syscall(const sysarg_t p1, const sysarg_t p2, const sysarg_t p3,
  • uspace/lib/libc/generic/udebug.c

    r1d132ae rf2ef7fd  
    3535#include <udebug.h>
    3636#include <sys/types.h>
    37 #include <syscall.h>
    3837#include <ipc/ipc.h>
    3938#include <async.h>
  • uspace/lib/libc/include/libc.h

    r1d132ae rf2ef7fd  
    4040#include <libarch/syscall.h>
    4141
    42 #define __SYSCALL0(id) __syscall(0, 0, 0, 0, 0, 0, id)
    43 #define __SYSCALL1(id, p1) __syscall(p1, 0, 0, 0, 0, 0, id)
    44 #define __SYSCALL2(id, p1, p2) __syscall(p1, p2, 0, 0, 0, 0, id)
    45 #define __SYSCALL3(id, p1, p2, p3) __syscall(p1, p2, p3, 0, 0, 0, id)
    46 #define __SYSCALL4(id, p1, p2, p3, p4) __syscall(p1, p2, p3, p4, 0, 0, id)
    47 #define __SYSCALL5(id, p1, p2, p3, p4, p5) __syscall(p1, p2, p3, p4, p5, 0, id)
     42#define __SYSCALL0(id) __syscall0(0, 0, 0, 0, 0, 0, id)
     43#define __SYSCALL1(id, p1) __syscall1(p1, 0, 0, 0, 0, 0, id)
     44#define __SYSCALL2(id, p1, p2) __syscall2(p1, p2, 0, 0, 0, 0, id)
     45#define __SYSCALL3(id, p1, p2, p3) __syscall3(p1, p2, p3, 0, 0, 0, id)
     46#define __SYSCALL4(id, p1, p2, p3, p4) __syscall4(p1, p2, p3, p4, 0, 0, id)
     47#define __SYSCALL5(id, p1, p2, p3, p4, p5) __syscall5(p1, p2, p3, p4, p5, 0, id)
    4848#define __SYSCALL6(id, p1, p2, p3, p4, p5, p6) \
    49     __syscall(p1, p2, p3, p4, p5, p6,id)
     49    __syscall6(p1, p2, p3, p4, p5, p6, id)
    5050
    5151extern void __main(void *pcb_ptr);
  • uspace/lib/libc/include/syscall.h

    r1d132ae rf2ef7fd  
    3333 * @file
    3434 * @brief       Syscall function declaration for architectures that don't
    35  *              inline syscalls.
     35 *              inline syscalls or architectures that handle syscalls
     36 *              according to the number of arguments.
    3637 */
    3738
     
    3940#define LIBC_SYSCALL_H_
    4041
     42#ifndef LIBARCH_SYSCALL_GENERIC
     43#error "You can't include this file directly."
     44#endif
     45
    4146#include <sys/types.h>
    4247#include <kernel/syscall/syscall.h>
     48
     49#define __syscall0      __syscall
     50#define __syscall1      __syscall
     51#define __syscall2      __syscall
     52#define __syscall3      __syscall
     53#define __syscall4      __syscall
     54#define __syscall5      __syscall
     55#define __syscall6      __syscall
    4356
    4457extern sysarg_t __syscall(const sysarg_t p1, const sysarg_t p2,
Note: See TracChangeset for help on using the changeset viewer.