From b07dfce332c35cf62accbca520b2944b58c37da1 Mon Sep 17 00:00:00 2001 From: "Iliya Mihailov (Ghost)" Date: Sun, 25 Feb 2007 14:20:50 +0000 Subject: [PATCH] Fast System Call Currently it only for kernel developing See : http://meos.sysbin.com/viewtopic.php?t=662 git-svn-id: svn://kolibrios.org@375 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/trunk/boot/bootcode.inc | 33 +-- kernel/trunk/const.inc | 8 + kernel/trunk/core/syscall.inc | 97 +++++++- kernel/trunk/kernel.asm | 63 ++++- programs/develop/fast_call_test/MACROS.INC | 266 +++++++++++++++++++++ programs/develop/fast_call_test/debug.inc | 131 ++++++++++ programs/develop/fast_call_test/test.ASM | 123 ++++++++++ 7 files changed, 695 insertions(+), 26 deletions(-) create mode 100644 programs/develop/fast_call_test/MACROS.INC create mode 100644 programs/develop/fast_call_test/debug.inc create mode 100644 programs/develop/fast_call_test/test.ASM diff --git a/kernel/trunk/boot/bootcode.inc b/kernel/trunk/boot/bootcode.inc index 2a02d6eb60..693859166a 100644 --- a/kernel/trunk/boot/bootcode.inc +++ b/kernel/trunk/boot/bootcode.inc @@ -39,9 +39,11 @@ gdts: dd gdts dw 0 +; Attention! The order first four selectors not to change, is used in Fast System Call +; must be : os_code, os_data, app_code, app_data, .... + int_code_l: os_code_l: - dw 0xffff dw 0x0000 db 0x00 @@ -50,13 +52,26 @@ os_code_l: int_data_l: os_data_l: - dw 0xffff dw 0x0000 db 0x00 dw 11011111b *256 +10010010b db 0x00 +app_code_l: + dw 0xFFFF;((0x80000000-std_application_base_address) shr 12) and 0xffff + dw 0 + db 0x40 + db cpl3 + dw G32+D32+0x6000+0x7; + +app_data_l: + dw 0xFFFF;(0x80000000-std_application_base_address) shr 12 and 0xffff + dw 0 + db 0x40 + db drw3 + dw G32+D32+0x6000+0x7; + ; --------------- APM --------------------- apm_code_32: dw 0x0f ; limit 64kb @@ -75,20 +90,6 @@ apm_data_16: db 0x00 ; ----------------------------------------- -app_code_l: - dw 0xFFFF;((0x80000000-std_application_base_address) shr 12) and 0xffff - dw 0 - db 0x40 - db cpl3 - dw G32+D32+0x6000+0x7; - -app_data_l: - dw 0xFFFF;(0x80000000-std_application_base_address) shr 12 and 0xffff - dw 0 - db 0x40 - db drw3 - dw G32+D32+0x6000+0x7; - graph_data_l: dw 0x7ff diff --git a/kernel/trunk/const.inc b/kernel/trunk/const.inc index af3092001b..7af311ce2b 100644 --- a/kernel/trunk/const.inc +++ b/kernel/trunk/const.inc @@ -85,6 +85,12 @@ CAPS_CMP_LEG equ 72 ; CAPS_SVM equ 73 ;secure virual machine CAPS_ALTMOVCR8 equ 74 ; +; CPU MSR names +MSR_SYSENTER_CS equ 0x174 +MSR_SYSENTER_ESP equ 0x175 +MSR_SYSENTER_EIP equ 0x176 +MSR_AMD_EFER equ 0xC0000080 ; Extended Feature Enable Register +MSR_AMD_STAR equ 0xC0000081 ; SYSCALL/SYSRET Target Address Register CR0_PE equ 0x00000001 ;protected mode CR0_MP equ 0x00000002 ;monitor fpu @@ -246,6 +252,8 @@ twdw equ (CURRENT_TASK-window_data) std_application_base_address equ new_app_base +RING0_STACK_SIZE equ 0x2000 - 512 ;512 байт для контекста FPU + PAGES_USED equ 4 PG_UNMAP equ 0x000 diff --git a/kernel/trunk/core/syscall.inc b/kernel/trunk/core/syscall.inc index b739c182f3..5526bb454a 100644 --- a/kernel/trunk/core/syscall.inc +++ b/kernel/trunk/core/syscall.inc @@ -35,6 +35,101 @@ i40: iretd +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; SYSENTER ENTRY ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +uglobal +times 100 db ? +sysenter_stack: +endg + +align 32 +SYSENTER_VAR equ 0 +sysenter_entry: + ; Настраиваем стек + cli + push eax + mov eax, [ss:CURRENT_TASK] + shl eax, 8 + mov eax, [ss:PROC_BASE + eax + APPDATA.pl0_stack] + lea esp, [ss:eax + RING0_STACK_SIZE] ; configure ESP + mov eax, [ss:sysenter_stack - 4] ; eax - original eax, from app + sti + ;------------------ + push ds es + pushad + cld + + mov ax, word os_data + mov ds, ax + mov es, ax + + mov eax, ebx + mov ebx, ecx + mov ecx, edx + mov edx, esi + mov esi, edi + mov edi, [esp + 28] + + push eax + and edi, 0xff + call dword [servetable + edi * 4] + pop eax + + popad + pop es ds + ;------------------ + mov edx, [SYSENTER_VAR] ; eip + mov ecx, [SYSENTER_VAR + 4] ; esp + sysexit + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; ;; +;; SYSCALL ENTRY ;; +;; ;; +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +align 32 +syscall_entry: + cli + xchg ecx, [esp] + mov [SYSENTER_VAR + 4], esp + mov [ss:sysenter_stack - 4], eax + mov eax, [ss:CURRENT_TASK] + shl eax, 8 + mov eax, [ss:PROC_BASE + eax + APPDATA.pl0_stack] + lea esp, [ss:eax + RING0_STACK_SIZE] ; configure ESP + mov eax, [ss:sysenter_stack - 4] ; eax - original eax, from app + sti + ;------------------ + push ds es + pushad + cld + + mov ax, word os_data + mov ds, ax + mov es, ax + + mov eax, ebx + mov ebx, ecx + mov ecx, edx + mov edx, esi + mov esi, edi + mov edi, [esp + 28] + + push eax + and edi, 0xff + call dword [servetable + edi * 4] + pop eax + + popad + pop es ds + ;------------------ + mov esp, [SYSENTER_VAR + 4] + xchg ecx, [esp] + sysret iglobal ;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; SYSTEM FUNCTIONS TABLE ;; @@ -62,7 +157,7 @@ iglobal dd sys_cachetodiskette ; 16-FlushFloppyCache dd sys_getbutton ; 17-GetButton dd sys_system ; 18-System Services - dd undefined_syscall ; 19-reserved + dd paleholder;undefined_syscall ; 19-reserved dd sys_midi ; 20-ResetMidi and OutputMidi dd sys_setup ; 21-SetMidiBase,SetKeymap,SetShiftKeymap,. dd sys_settime ; 22-setting date,time,clock and alarm-clock diff --git a/kernel/trunk/kernel.asm b/kernel/trunk/kernel.asm index 9d3383b03a..e6bf0383b2 100644 --- a/kernel/trunk/kernel.asm +++ b/kernel/trunk/kernel.asm @@ -166,10 +166,10 @@ end if use32 include 'unpacker.inc' - -__DEBUG__ fix 1 -__DEBUG_LEVEL__ fix 1 -include 'debug-fdo.inc' + +__DEBUG__ fix 1 +__DEBUG_LEVEL__ fix 1 +include 'debug-fdo.inc' iglobal boot_memdetect db 'Determining amount of memory',0 @@ -370,6 +370,49 @@ B32: ; btr [cpu_caps], CAPS_PGE ;test: don't use global pages ; btr [cpu_caps], CAPS_MTRR ;test: don't use MTRR bts [cpu_caps], CAPS_TSC ;force use rdtsc + +; -------- Fast System Call init ---------- + ; Intel SYSENTER/SYSEXIT (AMD CPU support it too) + bt [cpu_caps], CAPS_SEP + jnc .SEnP ; SysEnter not Present + xor edx, edx + mov ecx, MSR_SYSENTER_CS + mov eax, os_code + wrmsr + mov ecx, MSR_SYSENTER_ESP + mov eax, sysenter_stack ; Check it + wrmsr + mov ecx, MSR_SYSENTER_EIP + mov eax, sysenter_entry + wrmsr +.SEnP: + ; AMD SYSCALL/SYSRET + cmp byte[cpu_vendor], 'A' + jne .noSYSCALL + mov eax, 0x80000001 + cpuid + test edx, 0x800 ; bit_11 - SYSCALL/SYSRET support + jz .noSYSCALL + mov ecx, MSR_AMD_EFER + rdmsr + or eax, 1 ; bit_0 - System Call Extension (SCE) + wrmsr + + ; !!!! It`s dirty hack, fix it !!! + ; Bits of EDX : + ; Bit 31–16 During the SYSRET instruction, this field is copied into the CS register + ; and the contents of this field, plus 8, are copied into the SS register. + ; Bit 15–0 During the SYSCALL instruction, this field is copied into the CS register + ; and the contents of this field, plus 8, are copied into the SS register. + + ; mov edx, (os_code + 16) * 65536 + os_code + mov edx, 0x1B0013 + + mov eax, syscall_entry + mov ecx, MSR_AMD_STAR + wrmsr +.noSYSCALL: +; ----------------------------------------- ; MEMORY MODEL call mem_test @@ -4826,7 +4869,9 @@ read_from_hd: ; Read from hd - fn not in use ret - +align 4 +paleholder: + ret ; --------------- APM --------------------- apm_entry dp 0 apm_vf dd 0 @@ -5019,10 +5064,10 @@ iglobal syslang dd 0x1 endg -if __DEBUG__ eq 1 - include_debug_strings -end if - +if __DEBUG__ eq 1 + include_debug_strings +end if + IncludeIGlobals endofcode: IncludeUGlobals diff --git a/programs/develop/fast_call_test/MACROS.INC b/programs/develop/fast_call_test/MACROS.INC new file mode 100644 index 0000000000..58209dc4c9 --- /dev/null +++ b/programs/develop/fast_call_test/MACROS.INC @@ -0,0 +1,266 @@ +; new application structure +macro meos_app_start + { + use32 + org 0x0 + + db 'MENUET01' + dd 0x01 + dd __start + dd __end + dd __memory + dd __stack + + if used __params & ~defined __params + dd __params + else + dd 0x0 + end if + + dd 0x0 + } +MEOS_APP_START fix meos_app_start + +macro code + { + __start: + } +CODE fix code + +macro data + { + __data: + } +DATA fix data + +macro udata + { + if used __params & ~defined __params + __params: + db 0 + __end: + rb 255 + else + __end: + end if + __udata: + } +UDATA fix udata + +macro meos_app_end + { + align 32 + rb 2048 + __stack: + __memory: + } +MEOS_APP_END fix meos_app_end + + +; macro for defining multiline text data +struc mstr [sstring] + { + forward + local ssize + virtual at 0 + db sstring + ssize = $ + end virtual + dd ssize + db sstring + common + dd -1 + } + + +; strings +macro sz name,[data] { ; from MFAR [mike.dld] + common + if used name + label name + end if + forward + if used name + db data + end if + common + if used name + .size = $-name + end if +} + +macro lsz name,[lng,data] { ; from MFAR [mike.dld] + common + if used name + label name + end if + forward + if (used name)&(lang eq lng) + db data + end if + common + if used name + .size = $-name + end if +} + + + +; easy system call macro +macro mpack dest, hsrc, lsrc +{ + if (hsrc eqtype 0) & (lsrc eqtype 0) + mov dest, (hsrc) shl 16 + lsrc + else + if (hsrc eqtype 0) & (~lsrc eqtype 0) + mov dest, (hsrc) shl 16 + add dest, lsrc + else + mov dest, hsrc + shl dest, 16 + add dest, lsrc + end if + end if +} + +macro __mov reg,a { ; mike.dld + if ~a eq + mov reg,a + end if +} + +macro mcall a,b,c,d,e,f { ; mike.dld + __mov eax,a + __mov ebx,b + __mov ecx,c + __mov edx,d + __mov esi,e + __mov edi,f + int 0x40 +} + + + +; language for programs +lang fix ru ; ru en fr ge fi + + + +; optimize the code for size +__regs fix + +macro add arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + inc arg1 + else + add arg1,arg2 + end if + else + add arg1,arg2 + end if + } + +macro sub arg1,arg2 + { + if (arg2 eqtype 0) + if (arg2) = 1 + dec arg1 + else + sub arg1,arg2 + end if + else + sub arg1,arg2 + end if + } + +macro mov arg1,arg2 + { + if (arg1 in __regs) & (arg2 eqtype 0) + if (arg2) = 0 + xor arg1,arg1 + else if (arg2) = 1 + xor arg1,arg1 + inc arg1 + else if (arg2) = -1 + or arg1,-1 + else if (arg2) > -128 & (arg2) < 128 + push arg2 + pop arg1 + else + mov arg1,arg2 + end if + else + mov arg1,arg2 + end if + } + + +macro struct name + { + virtual at 0 + name name + sizeof.#name = $ - name + end virtual + } + +; structures used in MeOS +struc process_information + { + .cpu_usage dd ? ; +0 + .window_stack_position dw ? ; +4 + .window_stack_value dw ? ; +6 + .not_used1 dw ? ; +8 + .process_name rb 12 ; +10 + .memory_start dd ? ; +22 + .used_memory dd ? ; +26 + .PID dd ? ; +30 + .x_start dd ? ; +34 + .y_start dd ? ; +38 + .x_size dd ? ; +42 + .y_size dd ? ; +46 + .slot_state dw ? ; +50 + rb (1024-52) + } +struct process_information + +struc system_colors + { + .frame dd ? + .grab dd ? + .grab_button dd ? + .grab_button_text dd ? + .grab_text dd ? + .work dd ? + .work_button dd ? + .work_button_text dd ? + .work_text dd ? + .work_graph dd ? + } +struct system_colors + + +; constants + +; events +EV_IDLE = 0 +EV_TIMER = 0 +EV_REDRAW = 1 +EV_KEY = 2 +EV_BUTTON = 3 +EV_EXIT = 4 +EV_BACKGROUND = 5 +EV_MOUSE = 6 +EV_IPC = 7 +EV_STACK = 8 + +; event mask bits for function 40 +EVM_REDRAW = 1b +EVM_KEY = 10b +EVM_BUTTON = 100b +EVM_EXIT = 1000b +EVM_BACKGROUND = 10000b +EVM_MOUSE = 100000b +EVM_IPC = 1000000b +EVM_STACK = 10000000b \ No newline at end of file diff --git a/programs/develop/fast_call_test/debug.inc b/programs/develop/fast_call_test/debug.inc new file mode 100644 index 0000000000..f58479019a --- /dev/null +++ b/programs/develop/fast_call_test/debug.inc @@ -0,0 +1,131 @@ +macro debug_print str +{ + local ..string, ..label + + jmp ..label + ..string db str,0 + ..label: + + pushf + pushad + mov edx,..string + call debug_outstr + popad + popf +} + +dps fix debug_print + +macro debug_print_dec arg +{ + pushf + pushad + if ~arg eq eax + mov eax,arg + end if + call debug_outdec + popad + popf +} + +dpd fix debug_print_dec + +;--------------------------------- +debug_outdec: ;(eax - num, edi-str) + push 10 ;2 + pop ecx ;1 + push -'0' ;2 + .l0: + xor edx,edx ;2 + div ecx ;2 + push edx ;1 + test eax,eax ;2 + jnz .l0 ;2 + .l1: + pop eax ;1 + add al,'0' ;2 + call debug_outchar ; stosb + jnz .l1 ;2 + ret ;1 +;--------------------------------- + +debug_outchar: ; al - char + pushf + pushad + mov cl,al + mov eax,63 + mov ebx,1 + int 0x40 + popad + popf +ret + +debug_outstr: + mov eax,63 + mov ebx,1 + @@: + mov cl,[edx] + test cl,cl + jz @f + int 40h + inc edx + jmp @b + @@: + ret + + +macro newline +{ + dps <13,10> +} + +macro print message +{ + dps message + newline +} + +macro pregs +{ + dps "EAX: " + dpd eax + dps " EBX: " + dpd ebx + newline + dps "ECX: " + dpd ecx + dps " EDX: " + dpd edx + newline +} + +macro debug_print_hex arg +{ + pushf + pushad + if ~arg eq eax + mov eax, arg + end if + call debug_outhex + popad + popf +} +dph fix debug_print_hex + +debug_outhex: + ; eax - number + mov edx, 8 + .new_char: + rol eax, 4 + movzx ecx, al + and cl, 0x0f + mov cl, [__hexdigits + ecx] + pushad + mcall 63, 1 + popad + dec edx + jnz .new_char +ret + +__hexdigits: + db '0123456789ABCDEF' \ No newline at end of file diff --git a/programs/develop/fast_call_test/test.ASM b/programs/develop/fast_call_test/test.ASM new file mode 100644 index 0000000000..a828e91616 --- /dev/null +++ b/programs/develop/fast_call_test/test.ASM @@ -0,0 +1,123 @@ +; +; Kolibri Fast Calls test +; +; Compile with FASM for Kolibri +; +; +SYSENTER_VAR equ 0 +use32 +org 0x0 + db 'MENUET01' + dd 0x01 + dd START + dd I_END + dd 0x1000 + dd 0x1000 + dd 0x0, 0x0 + +include 'macros.inc' +include 'debug.inc' + +START: + mov eax, 19 ; функция пустышка + push ecx + syscall + pop ecx + + + print '! Alive !' + + xor eax, eax + cpuid + rdtsc + mov [old_tsc], eax + mov [old_tsc + 4], edx + +; через быстрый вызов +test1: mov ebx, 0x100000 + mov dword[SYSENTER_VAR], .ret_p + mov [SYSENTER_VAR + 4], esp + align 32 +.nxt: mov eax, 19 ; функция пустышка + sysenter ; портятся ecx, edx +.ret_p: dec ebx + jnz .nxt + + xor eax, eax + cpuid + rdtsc + cmp eax, [old_tsc] + jnb @f + dec edx +@@: sub eax, [old_tsc] + sub edx, [old_tsc + 4] + debug_print_hex edx + debug_print_hex eax + print ' <- Fast call' + + + + xor eax, eax + cpuid + rdtsc + mov [old_tsc], eax + mov [old_tsc + 4], edx +; через шлюз прерывания +test2: mov ebx, 0x100000 + align 32 +.nxt: mov eax, 19 ; функция пустышка + int 0x40 + dec ebx + jnz .nxt + + xor eax, eax + cpuid + rdtsc + cmp eax, [old_tsc] + jnb @f + dec edx +@@: sub eax, [old_tsc] + sub edx, [old_tsc + 4] + debug_print_hex edx + debug_print_hex eax + print ' <- Interrupt' + + call show_alive + mov eax, -1 + int 0x40 +;--------------------------------------------- +show_alive: + ; через быстрый вызов, настраиваем регистры для возврата + mov eax, 63 + mov ebx, 1 + mov esi, msg_Ok +.nxt: mov cl, [esi] + test cl, cl + jz .end + + mov dword[SYSENTER_VAR], .ret_p + mov [SYSENTER_VAR + 4], esp + sysenter ; портятся ecx, edx + +.ret_p: inc esi + jmp .nxt +.end: ret + ; через шлюз прерывания + ; mov eax, 63 + ; mov ebx, 1 + ; mov esi, msg_Ok +; @@: mov cl, [esi] + ; test cl, cl + ; jz @f + + ; int 0x40 + + ; inc esi + ; jmp @b +; @@: ret + + +old_tsc: dd 0, 0 + +msg_Ok db 'Alive!', 10, 13, 0 +I_END: \ No newline at end of file