Subversion Repositories shark

Compare Revisions

Ignore whitespace Rev 298 → Rev 299

/shark/trunk/oslib/kl/timeint.s
46,8 → 46,99
 
.extern SYMBOL_NAME(periodic_wake_up)
.extern SYMBOL_NAME(oneshot_wake_up)
.extern SYMBOL_NAME(ack_APIC_irq)
 
.text
.globl SYMBOL_NAME(ll_apic_timer)
/* APIC ll_timer */
 
SYMBOL_NAME_LABEL(ll_apic_timer)
pushal
pushw %ds
pushw %es
pushw %fs
pushw %gs
movw $(X_FLATDATA_SEL),%ax
movw %ax,%ds
movw %ax,%es
 
/* Send EOI to APIC */
movl $0xFEE000B0,%ebx
movl $0,(%ebx)
 
/* Call wake_up(actual_context) */
movl SYMBOL_NAME(ll_clock),%eax
incl %eax
movl %eax,SYMBOL_NAME(ll_clock)
/* The following could be optimized a little... */
xorl %ebx, %ebx
movw %ss, %bx
/* We must switch to a ``safe stack'' */
/*
* OK, this is the idea: in %esp we have the address of the
* stack pointer in the APPLICATION address space...
* We assume that address spaces are implemented through segments...
* What we have to do is to add the segment base to %esp:
* - Load the GDT base in a register
* - Add DS * 8 to that value
* - Read the corresponding GDT entry (the segment descriptor)
* - Compute the base...
* It is (*p & 0xFC) | (*(p +1) & 0x0F) << 16) | *(p + 2)
*/
movl SYMBOL_NAME(GDT_base), %edi
addl %ebx, %edi
xorl %ebx, %ebx
movb 7(%edi), %bh
movb 4(%edi), %bl
shl $16, %ebx
movw 2(%edi), %bx
/* Is it correct? I think so... Test it!!! */
addl %ebx, %esp
/* Save EBX for returning to our stack... */
movw %ds, %cx
movw %ss, %dx
movw %cx, %ss
pushl %ebx
pushl %edx
cld
movl SYMBOL_NAME(timermode), %eax
cmpl $1, %eax
je apic_oneshot
call SYMBOL_NAME(periodic_wake_up)
jmp apic_Timer_OK
apic_oneshot: call SYMBOL_NAME(oneshot_wake_up)
apic_Timer_OK:
/* Restore ESP */
popl %edx
popl %ebx /* We must subtract it from ESP...*/
subl %ebx, %esp
movw %dx, %ss
#ifdef __VIRCSW__
 
movw SYMBOL_NAME(currCtx), %ax
cmpw %ax,JmpSel
je apic_NoPreempt2
movw %ax,JmpSel
ljmp JmpZone /* DISPATCH! */
#endif
apic_NoPreempt2:
 
cmpl $0, SYMBOL_NAME(last_handler)
je apic_nohandler
movl SYMBOL_NAME(last_handler), %ebx
call *%ebx
apic_nohandler:
popw %gs
popw %fs
popw %es
popw %ds
popal
iret
 
.globl SYMBOL_NAME(ll_timer)
/* This is the timer handler; it reloads for safety the DS register; this */
/* prevents from mess when timer interrupts linear access to memory (not in */