/kernel/trunk/boot/bootcode.inc |
---|
39,9 → 39,11 |
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,7 → 52,6 |
int_data_l: |
os_data_l: |
dw 0xffff |
dw 0x0000 |
db 0x00 |
57,6 → 58,20 |
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 |
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 |
/kernel/trunk/const.inc |
---|
85,6 → 85,12 |
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 |
std_application_base_address equ new_app_base |
RING0_STACK_SIZE equ 0x2000 - 512 ;512 áàéò äëÿ êîíòåêñòà FPU |
PAGES_USED equ 4 |
PG_UNMAP equ 0x000 |
/kernel/trunk/core/syscall.inc |
---|
35,6 → 35,101 |
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 |
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 |
/kernel/trunk/kernel.asm |
---|
371,6 → 371,49 |
; 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 3116 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 150 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 |
call init_mem |
4826,7 → 4869,9 |
ret |
align 4 |
paleholder: |
ret |
; --------------- APM --------------------- |
apm_entry dp 0 |
apm_vf dd 0 |
/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 <eax,ebx,ecx,edx,esi,edi,ebp,esp> |
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 |
/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' |
/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: |