Subversion Repositories shark

Rev

Rev 3 | Go to most recent revision | Details | 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
#if 0
87
	/*
88
	 * OK, this is the idea: in %esp we have the address of the
89
	 * stack pointer in the APPLICATION address space...
90
	 * We assume that address spaces are implemented through segments...
91
	 * What we have to do is to add the segment base to %esp:
92
	 *	- Load the GDT base in a register
93
	 *	- Add DS * 8 to that value
94
	 *	- Read the corresponding GDT entry (the segment descriptor)
95
	 *	- Compute the base...
96
	 *	It is (*p & 0xFC) | (*(p +1)  & 0x0F) << 16) | *(p + 2)
97
	 */
98
			movl SYMBOL_NAME(GDT_base), %edi
99
			addl %ebx, %edi
100
			xorl %ebx, %ebx
101
			movb 7(%edi), %bh
102
			movb 4(%edi), %bl
103
			shl $16, %ebx
104
			movw 2(%edi), %bx
105
			/* Is it correct? I think so... Test it!!! */
106
			addl %ebx, %esp
107
			/* Save EBX for returning to our stack... */
108
			movw %ds, %cx
109
			movw %ss, %dx
110
			movw %cx, %ss
111
			pushl %ebx
112
			pushl %edx
113
#endif
114
			cld
115
			movl	SYMBOL_NAME(timermode), %eax
116
			cmpl	$1, %eax
117
			je	oneshot
118
			call    SYMBOL_NAME(periodic_wake_up)
119
			jmp	goon
120
oneshot:		call    SYMBOL_NAME(oneshot_wake_up)
121
goon:
122
			/* This is the overrun test		 */
123
			/* Do it after sending EOI to master PIC */
124
 
125
			movb    $0x0A,%al
126
			movl	$0x020,%edx
127
			outb    %al,%dx
128
			inb     %dx,%al
129
			testb   $1,%al
130
			jz      Timer_OK
131
			movl    $(CLOCK_OVERRUN),%eax
132
			pushl	%eax
133
			call    SYMBOL_NAME(ll_abort)
134
 
135
Timer_OK:
136
#if 0
137
			/* Restore ESP */
138
			popl	%edx
139
			popl	%ebx	/* We must subtract it from ESP...*/
140
			subl	%ebx, %esp
141
			movw	%dx, %ss
142
#endif
143
#ifdef __VIRCSW__
144
 
145
			movw	SYMBOL_NAME(currCtx), %ax
146
			cmpw    %ax,JmpSel
147
			je      NoPreempt2
148
			movw    %ax,JmpSel
149
			ljmp    JmpZone  /* DISPATCH! */
150
#endif
151
NoPreempt2:
152
 
153
			cmpl	$0, SYMBOL_NAME(last_handler)
154
			je	nohandler
155
			movl	SYMBOL_NAME(last_handler), %ebx
156
			call	*%ebx
157
nohandler:
158
			popw	%gs
159
			popw	%fs
160
			popw	%es
161
			popw	%ds
162
			popal
163
			iret