Subversion Repositories shark

Rev

Rev 40 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 pj 1
/* Project:     OSLib
2
 * Description: The OS Construction Kit
3
 * Date:                1.6.2000
4
 * Idea by:             Luca Abeni & Gerardo Lamastra
5
 *
6
 * OSLib is an SO project aimed at developing a common, easy-to-use
7
 * low-level infrastructure for developing OS kernels and Embedded
8
 * Applications; it partially derives from the HARTIK project but it
9
 * currently is independently developed.
10
 *
11
 * OSLib is distributed under GPL License, and some of its code has
12
 * been derived from the Linux kernel source; also some important
13
 * ideas come from studying the DJGPP go32 extender.
14
 *
15
 * We acknowledge the Linux Community, Free Software Foundation,
16
 * D.J. Delorie and all the other developers who believe in the
17
 * freedom of software and ideas.
18
 *
19
 * For legalese, check out the included GPL license.
20
 */
21
 
22
/*	Safe abort routine & timer asm handler	*/
23
 
24
.title	"Timer.S"
25
 
26
#include <ll/i386/sel.h>
27
#include <ll/i386/linkage.h>
28
#include <ll/i386/defs.h>
29
 
30
#include <ll/sys/ll/exc.h>
31
 
32
.data
33
 
34
ASMFILE(TimerHandler)
35
 
36
.extern JmpSel
37
.extern JmpZone
38
.globl SYMBOL_NAME(ll_clock)
39
.globl SYMBOL_NAME(last_handler)
40
 
41
		/* Used as JMP entry point to check if a real	*/
42
		/* context switch is necessary			*/
43
 
44
SYMBOL_NAME_LABEL(ll_clock)	.int	0
45
SYMBOL_NAME_LABEL(last_handler)	.long   0
46
 
47
.extern  SYMBOL_NAME(periodic_wake_up)
48
.extern  SYMBOL_NAME(oneshot_wake_up)
49
 
50
.text
51
		.globl SYMBOL_NAME(ll_timer)
52
/* This is the timer handler; it reloads for safety the DS register; this   */
53
/* prevents from mess when timer interrupts linear access to memory (not in */
54
/* ELF address space); then EOI is sent in order to detect timer overrun    */
55
/* The high level kernel procedure wake_up() is called to perform the 	    */
56
/* preeption at higher level (process descriptos); the resulting context    */
57
/* if different from the old one is used to trigger the task activation.    */
58
 
59
SYMBOL_NAME_LABEL(ll_timer)
60
			pushal
61
			pushw	%ds
62
			pushw	%es
63
			pushw	%fs
64
			pushw	%gs
65
 
66
			movw    $(X_FLATDATA_SEL),%ax
67
			movw    %ax,%ds
68
			movw    %ax,%es
69
 
70
			/* Send EOI to master PIC		*/
71
			/* to perform later the overrun test	*/
72
			movb    $0x20,%al
73
			movl	$0x20,%edx
74
			outb    %al,%dx
75
 
76
			/* Call wake_up(actual_context) */
77
 
78
			movl	SYMBOL_NAME(ll_clock),%eax
79
			incl 	%eax
80
			movl	%eax,SYMBOL_NAME(ll_clock)
81
 
82
			/* The following could be optimized a little... */
83
			xorl %ebx, %ebx
84
			movw %ss, %bx
85
			/* We must switch to a ``safe stack'' */
86
	/*
87
	 * OK, this is the idea: in %esp we have the address of the
88
	 * stack pointer in the APPLICATION address space...
89
	 * We assume that address spaces are implemented through segments...
90
	 * What we have to do is to add the segment base to %esp:
91
	 *	- Load the GDT base in a register
92
	 *	- Add DS * 8 to that value
93
	 *	- Read the corresponding GDT entry (the segment descriptor)
94
	 *	- Compute the base...
95
	 *	It is (*p & 0xFC) | (*(p +1)  & 0x0F) << 16) | *(p + 2)
96
	 */
97
			movl SYMBOL_NAME(GDT_base), %edi
98
			addl %ebx, %edi
99
			xorl %ebx, %ebx
100
			movb 7(%edi), %bh
101
			movb 4(%edi), %bl
102
			shl $16, %ebx
103
			movw 2(%edi), %bx
104
			/* Is it correct? I think so... Test it!!! */
105
			addl %ebx, %esp
106
			/* Save EBX for returning to our stack... */
107
			movw %ds, %cx
108
			movw %ss, %dx
109
			movw %cx, %ss
110
			pushl %ebx
111
			pushl %edx
112
			cld
113
			movl	SYMBOL_NAME(timermode), %eax
114
			cmpl	$1, %eax
115
			je	oneshot
116
			call    SYMBOL_NAME(periodic_wake_up)
117
			jmp	goon
118
oneshot:		call    SYMBOL_NAME(oneshot_wake_up)
227 giacomo 119
                        jmp     Timer_OK
2 pj 120
goon:
121
			/* This is the overrun test		 */
122
			/* Do it after sending EOI to master PIC */
123
 
124
			movb    $0x0A,%al
125
			movl	$0x020,%edx
126
			outb    %al,%dx
127
			inb     %dx,%al
128
			testb   $1,%al
129
			jz      Timer_OK
130
			movl    $(CLOCK_OVERRUN),%eax
131
			pushl	%eax
132
			call    SYMBOL_NAME(ll_abort)
133
 
134
Timer_OK:
135
			/* Restore ESP */
136
			popl	%edx
137
			popl	%ebx	/* We must subtract it from ESP...*/
138
			subl	%ebx, %esp
139
			movw	%dx, %ss
40 pj 140
 
2 pj 141
#ifdef __VIRCSW__
142
 
143
			movw	SYMBOL_NAME(currCtx), %ax
144
			cmpw    %ax,JmpSel
145
			je      NoPreempt2
146
			movw    %ax,JmpSel
147
			ljmp    JmpZone  /* DISPATCH! */
148
#endif
149
NoPreempt2:
150
 
151
			cmpl	$0, SYMBOL_NAME(last_handler)
152
			je	nohandler
153
			movl	SYMBOL_NAME(last_handler), %ebx
154
			call	*%ebx
155
nohandler:
156
			popw	%gs
157
			popw	%fs
158
			popw	%es
159
			popw	%ds
160
			popal
161
			iret