Page 1 of 2
Local apic timer initializing
Posted: Wed Apr 07, 2010 5:09 am
by lemonyii
Hi
I have been stuck for too long in this problem
I follow the instructions form
http://forum.osdev.org/posting.php?mode=post&f=1
and set my apic timer,and corrected some place by posting my previous question at
http://forum.osdev.org/viewtopic.php?f= ... =APIC+init
but it still does not work.
the timer has got a decreasing in CCR,and i checked the IF ,surely 1,
but noting happend,never.
i do this in bochs and the CPU emulated is Pentium 4.(i did in vmware too,but noting different).
it is in 64bit mode.so i am doubting if there are some difference in 64bit mode,such TPR,which i set to be always 0, or i got some mistake in initializing.
my code:
Code: Select all
extern i64 APIC_init(){
sys_call(0ULL,_SYSCALL_LEVEL0,init_apic);
sys_call(1ULL,_SYSCALL_SET_INT,INT_VECTOR_IRQ0,_int_handler_timer,SYS_INT_HANDLER_TYPE_INT64,0ULL,0ULL);
sys_call(0ULL,_SYSCALL_LEVEL0,set_apic_timer,0x8000,0xB0,0x00020000|INT_VECTOR_IRQ0);
return 0;
}
bits 64
align 16
init_apic:
pushf
cli
push rcx
push rsi
mov rcx,1Bh
rdmsr
and rax,0xfffffffffffff000
mov rsi,rax
mov eax,0x000001FF ;0x000001FF -> 0xFFE000F0 - enable local APIC and set spurious int vector to 0xFF
mov [rsi+0xF0],eax
mov eax,0xFFFFFFFF ;0xFFFFFFFF -> 0xFEE000E0 - set destination format register to flat model
mov [rsi+0xE0],eax
mov eax,0x00000000 ;0x00000000 -> 0xFEE00080 - set the task priority register to accept all interrupts
mov [rsi+0x80],eax
xor rax,rax
pop rsi
pop rcx
popf
ret
align 16
set_apic_timer: ;init_apic_timer(CR,DCR,LVT)
;0x0000000B -> 0xFEE003E0 - set timer to divide by 1
;0x00020040 -> 0xFEE00320 - enable timer, set periodic mode, set int vector to 0x40
;0x00000064 -> 0xFEE00380 - set initial count to 100 (and make the timer start counting)
pushf
cli
push rcx
push rsi
mov rcx,1Bh
rdmsr
and rax,0xfffffffffffff000
mov rsi,rax
pop rax ;DCR
mov [rsi+0x3E0],eax
mov [rsi+0x320],edx ;LVT
mov [rsi+0x380],edi ;CR
xor rax,rax
pop rcx
popf
ret
align 16
_int_handler_timer:
push rcx
push rsi
push rax
push rdi
mov rcx,1Bh
rdmsr
and rax,0xfffffffffffff000
mov rsi,rax
;EOI
xor rax,rax
mov [rsi+0xB0],eax
;do something
mov rcx,80*200
mov rdi,0xb8000
mov rax,0x7244
rep
stosw
pop rdi
pop rax
pop rsi
pop rcx
iretq
i think i really need some successfully tested code.
help!
thx
Re: Local apic timer initializing
Posted: Wed Apr 07, 2010 8:28 am
by Brendan
Hi,
I love code with good comments, because good comments make bugs stand out.
Code: Select all
%define LAPIC_timer_divisor 0x03E0
%define LAPIC_timer_vector 0x0320
%define LAPIC_timer_initial_count 0x0380
;void init_apic_timer(uint32_t CR, uint32_t DCR, uint32_t LVT)
;Input
; rsi Local APIC timer divisor (0x0000000B = divide by 1)
; rdx Local APIC timer LVT (0x00020040 = enable timer, set periodic mode, set int vector to 0x40)
; rdi Local APIC timer initial count (0x00000064 = 100 ticks)
align 16
set_apic_timer:
pushf ;Save flags
cli ;Disable IRQs earlier than necessary
push rcx ;Save RCX
push rsi ;Save Local APIC timer divisor
mov rcx,1Bh ;rcx = model specific Local APIC base MSR
rdmsr ;edx:eax = model specific Local APIC base MSR (hopefully)
and rax,0xfffffffffffff000 ;rax = 32-bit physical address of Local APIC (hopefully)
mov rsi,rax ;rsi = 32-bit physical address of Local APIC (hopefully)
pop rax ;rax = Local APIC timer divisor
mov [rsi+LAPIC_timer_divisor],eax ;Set Local APIC timer divisor to value from input parameter that was in rsi
mov [rsi+LAPIC_timer_vector],edx ;Set Local APIC vector to the high 32-bits of the Local APIC base MSR
mov [rsi+LAPIC_timer_initial_count],edi ;Set Local APIC initial count to value from input parameter that was in rdi
xor rax,rax ;rax = zero, because the return value matters for functions that return "void"
pop rcx ;Restore RCX
popf ;Restore flags and (potentially) enable IRQs later than necessary
ret
Cheers,
Brendan
Re: Local apic timer initializing
Posted: Wed Apr 07, 2010 10:31 am
by lemonyii
Hi,
Brendan!
thank you for your replying!
I am so excited when i see your reply!Because i feel your name is so similar,and i am a fish,both here and in OS!
i tried your code,but nothing different.
so i am thinking if i got a mistake somewhere else.would you please remind me?
can the process with a privillige 1 got interrupted? or TPR=0 is making it strange?
my GDT and TSS:
Code:
Code: Select all
align 16,db 0
tmp_gdt:
.NULL dd 0
dd 0
.D0: DD 0FFFFH
DD 0209200H
.D1: DD 0FFFFH
DD 020B200H
.D2: DD 0FFFFH
DD 020D200H
.D3: DD 0FFFFH
DD 020F200H
.C0: dd 0FFFFH
DD 0AF9A00H
.C1: dd 0FFFFH
DD 0AFBA00H
.C2: dd 0FFFFH
DD 0AFDA00H
.C3: dd 0FFFFH
DD 0AFFA00H
.TSS: dd 0 ;THIS WOULD BE INITIALIZED AT KERNEL INITIALING
dd 0
DD 0 ;base 63-32
DD 0 ;Reserved
GDTLEN EQU $-tmp_gdt
SegD0 equ tmp_gdt.D0-tmp_gdt
SegD1 equ tmp_gdt.D1-tmp_gdt
SegD2 equ tmp_gdt.D2-tmp_gdt
SegD3 equ tmp_gdt.D3-tmp_gdt
SegC0 equ tmp_gdt.C0-tmp_gdt
SegC1 equ tmp_gdt.C1-tmp_gdt
SegC2 equ tmp_gdt.C2-tmp_gdt
SegC3 equ tmp_gdt.C3-tmp_gdt
SelectorTSS equ tmp_gdt.TSS-tmp_gdt
GdtPtr: dw GDTLEN-1
DD 0
DD 0
;== TSS ==========================================
align 16,db 0
tss:
.reserved0 dd 0
.rsp0 dd 0
dd 0
.rsp1 dd 0
dd 0
.rsp2 dd 0
dd 0
.reserved1 dd 0
.reserved2 dd 0
.ist1 dd 0
dd 0
.ist2 dd 0
dd 0
.ist3 dd 0
dd 0
.ist4 dd 0
dd 0
.ist5 dd 0
dd 0
.ist6 dd 0
dd 0
.ist7 dd 0
dd 0
.reserved3 dd 0
.reserved4 dd 0
.reserved5 DW 0
.IOMapBase dw 0xffff ;somewhere invalid
;.IOMap dd 0xffffffff ;to ensure that it works well
TSSLEN equ $-tss
idt may not have problems,for i can perform syscalls through interruption for many times.
i really hope you can help me shot this defusing trouble.
thx.
Re: Local apic timer initializing
Posted: Wed Apr 07, 2010 11:08 am
by Brendan
Hi,
lemonyii wrote:i tried your code,but nothing different.
so i am thinking if i got a mistake somewhere else.would you please remind me?
My code is exactly the same as your code, except I added comments. If you read the comments you'll see what the code actually does (and find the bug)...
Cheers,
Brendan
Re: Local apic timer initializing
Posted: Thu Apr 08, 2010 12:22 am
by lemonyii
My code is exactly the same as your code, except I added comments
i found it before i use it.but
If you read the comments you'll see what the code actually does (and find the bug)...
What i have got changed is just
Code: Select all
mov rcx,1Bh ;rcx = model specific Local APIC base MSR
rdmsr ;edx:eax = model specific Local APIC base MSR (hopefully)
mov rsi,rdx ;rsi = higher 32bit
shl rsi,32
and rax,0xfffffffffffff000 ;rax = lower 32-bit physical address of Local APIC (hopefully)
mov esi,eax ;rsi = 64-bit physical address of Local APIC (hopefully)
still nothing happening though the timer is decreasing.
i'm trying.
thx
Re: Local apic timer initializing
Posted: Thu Apr 08, 2010 10:24 am
by Brendan
Hi,
lemonyii wrote:
If you read the comments you'll see what the code actually does (and find the bug)...
What i have got changed is just[/code]
Did you notice the "
;Set Local APIC vector to the high 32-bits of the Local APIC base MSR" comment, or do I need to tattoo your retinas?
Cheers,
Brendan
Re: Local apic timer initializing
Posted: Thu Apr 08, 2010 10:44 pm
by Love4Boobies
Brendan wrote:Did you notice the ";Set Local APIC vector to the high 32-bits of the Local APIC base MSR" comment, or do I need to tattoo your retinas?
High, low, LVT, base MSR, what's the difference? A fish with a tattooed retina sounds far more impressive.
Re: Local apic timer initializing
Posted: Thu Apr 08, 2010 11:34 pm
by lemonyii
Err...
Brendan wrote:
Did you notice the ";Set Local APIC vector to the high 32-bits of the Local APIC base MSR" comment
Brendan
what does it mean? are you suer it is the high 32-bits of THE LAPIC BASE MSR?
i turned the IA32&INTEL64...(2008) again and again but i cannot find such a sentense.
And i changed my code to be like this:
Code: Select all
mov rcx,1Bh ;rcx = model specific Local APIC base MSR
rdmsr ;edx:eax = model specific Local APIC base MSR (hopefully)
mov rsi,rdx ;rsi = higher 32bit
shl rsi,32
and rax,0xfffffffffffff000 ;rax = lower 32-bit physical address of Local APIC (hopefully)
mov esi,eax ;rsi = 64(in fact 32)-bit physical address of Local APIC (hopefully)
pop rax ;rax = Local APIC timer divisor
mov [rsi+LAPIC_timer_divisor],eax ;Set Local APIC timer divisor to value from input parameter that was in rsi
mov [rsi+LAPIC_timer_vector],edx ;Set Local APIC vector to the high 32-bits of the Local APIC base MSR
mov [rsi+LAPIC_timer_initial_count],edi ;Set Local APIC initial count to value from input parameter that was in rdi
mov eax,esi ;eax = apic base
mov rcx,0x1B ;apic base MSR
wrmsr ;apic base MSR <- edx:eax
but it get even worse:the CCR will be always 0xffffffffffffffff.
some more help is needed...
thank you so much!
Re: Local apic timer initializing
Posted: Fri Apr 09, 2010 12:35 pm
by Combuster
The bottom line here would be that you need to learn how to program. And that isn't just putting together words like most people seem to think, but know how to find and correct the wrong combinations.
Re: Local apic timer initializing
Posted: Fri Apr 09, 2010 8:32 pm
by lemonyii
well...
at least i solved a problem for another fish with a tattooed retina at
http://forum.osdev.org/viewtopic.php?f=1&t=21812
before i got my only problem solved.
and you with 5 stars here really frightened me! and i have never enjoyed such a feast.
i will keep on my long march on this which has been a month.
thx
Re: Local apic timer initializing
Posted: Fri Apr 09, 2010 8:56 pm
by Love4Boobies
Okay, here's another hint: what are you supposed to write in the LVT timer register?
Re: Local apic timer initializing
Posted: Fri Apr 09, 2010 9:01 pm
by Brendan
Hi,
lemonyii wrote:i will keep on my long march on this which has been a month.
Do you understand that EDX and RDX are the same register?
For example, you can't put 0x12345678 into RDX, then load 0x9ABCDEF into EDX, then expect RDX to still contain 0x12345678?
Cheers,
Brendan
Re: Local apic timer initializing
Posted: Fri Apr 09, 2010 10:16 pm
by lemonyii
PROBLEM SOLVED!!!!
i rewrite it in C,and then....aha!!!
long march has been end!
and i think edx is the lower 32bits of rdx, and change the edx,the high 32bits of rdx,will remain unchanged,right?
i have write much more in assembly than in C,because i got many problems in complier,
e.g. i spend 3 week to build a cross complie evironment( i tried to used linux,but the driver and LAN problems killed the idea),
and i spend almost a week to learn ELF,and just a problem about alignment and BSS had led to another long march before.
but the fact proved that i am still not good at assemly.
so,i will try to write more in C in the future.
and now i feel it that the most part in solving problems is to find where it to wrong.
And , thank you so much!
Re: Local apic timer initializing
Posted: Fri Apr 09, 2010 10:36 pm
by Love4Boobies
lemonyii wrote:PROBLEM SOLVED!!!!
i rewrite it in C,and then....aha!!!
long march has been end!
Code: Select all
; EDX has the right value set for the LVC timer register on input
.
.
.
rdmsr ;Rewrites EDX in the process of dumping the base MSR
.
.
.
mov [rsi+LAPIC_timer_vector],edx ;Oops!
.
.
.
Re: Local apic timer initializing
Posted: Fri Apr 09, 2010 11:54 pm
by lemonyii
oh! i got it!
hell the rdmsr !
i should have understand when i was tattooed retina by Brendan
and the excuse for that is my official language is not English so that i got a misunderstand at that time
thx