Subversion Repositories HelenOS-historic

Rev

Rev 348 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 348 Rev 472
1
#
1
#
2
# Copyright (C) 2005 Ondrej Palkovsky
2
# Copyright (C) 2005 Ondrej Palkovsky
3
# All rights reserved.
3
# All rights reserved.
4
#
4
#
5
# Redistribution and use in source and binary forms, with or without
5
# Redistribution and use in source and binary forms, with or without
6
# modification, are permitted provided that the following conditions
6
# modification, are permitted provided that the following conditions
7
# are met:
7
# are met:
8
#
8
#
9
# - Redistributions of source code must retain the above copyright
9
# - Redistributions of source code must retain the above copyright
10
#   notice, this list of conditions and the following disclaimer.
10
#   notice, this list of conditions and the following disclaimer.
11
# - Redistributions in binary form must reproduce the above copyright
11
# - Redistributions in binary form must reproduce the above copyright
12
#   notice, this list of conditions and the following disclaimer in the
12
#   notice, this list of conditions and the following disclaimer in the
13
#   documentation and/or other materials provided with the distribution.
13
#   documentation and/or other materials provided with the distribution.
14
# - The name of the author may not be used to endorse or promote products
14
# - The name of the author may not be used to endorse or promote products
15
#   derived from this software without specific prior written permission.
15
#   derived from this software without specific prior written permission.
16
#
16
#
17
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
#
27
#
28
 
28
 
29
 
29
 
30
#  Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error word
30
#  Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error word
31
# and 1 means interrupt with error word
31
# and 1 means interrupt with error word
32
 
32
 
33
	
33
	
34
#define ERROR_WORD_INTERRUPT_LIST 0x00027D00
34
#define ERROR_WORD_INTERRUPT_LIST 0x00027D00
35
 
35
 
36
#define __ASM__
-
 
37
#include <arch/pm.h>
36
#include <arch/pm.h>
38
	
37
	
39
.text
38
.text
40
.global interrupt_handlers
39
.global interrupt_handlers
41
.global panic_printf
40
.global panic_printf
42
 
41
 
43
panic_printf:
42
panic_printf:
44
	movq $halt, (%rsp)
43
	movq $halt, (%rsp)
45
	jmp printf
44
	jmp printf
46
 
45
 
47
.global memcpy
46
.global memcpy
48
memcpy:
47
memcpy:
49
	jmp _memcpy
48
	jmp _memcpy
50
	
49
	
51
.global cpuid
50
.global cpuid
52
.global has_cpuid
51
.global has_cpuid
53
.global rdtsc
52
.global rdtsc
54
.global read_efer_flag
53
.global read_efer_flag
55
.global set_efer_flag
54
.global set_efer_flag
56
	
55
	
57
 
56
 
58
# THIS IS USERSPACE CODE
57
# THIS IS USERSPACE CODE
59
.global utext
58
.global utext
60
utext:
59
utext:
61
0:
60
0:
62
	int $48
61
	int $48
63
	jmp 0b
62
	jmp 0b
64
	# not reached
63
	# not reached
65
utext_end:
64
utext_end:
66
 
65
 
67
.data
66
.data
68
.global utext_size
67
.global utext_size
69
utext_size:
68
utext_size:
70
	.long utext_end - utext 
69
	.long utext_end - utext 
71
 
70
 
72
	
71
	
73
## Determine CPUID support
72
## Determine CPUID support
74
#
73
#
75
# Return 0 in EAX if CPUID is not support, 1 if supported.
74
# Return 0 in EAX if CPUID is not support, 1 if supported.
76
#
75
#
77
has_cpuid:
76
has_cpuid:
78
	pushfq			# store flags
77
	pushfq			# store flags
79
	popq %rax		# read flags
78
	popq %rax		# read flags
80
	movq %rax,%rdx		# copy flags
79
	movq %rax,%rdx		# copy flags
81
	btcl $21,%edx		# swap the ID bit
80
	btcl $21,%edx		# swap the ID bit
82
	pushq %rdx
81
	pushq %rdx
83
	popfq			# propagate the change into flags
82
	popfq			# propagate the change into flags
84
	pushfq
83
	pushfq
85
	popq %rdx		# read flags	
84
	popq %rdx		# read flags	
86
	andl $(1<<21),%eax	# interested only in ID bit
85
	andl $(1<<21),%eax	# interested only in ID bit
87
	andl $(1<<21),%edx
86
	andl $(1<<21),%edx
88
	xorl %edx,%eax		# 0 if not supported, 1 if supported
87
	xorl %edx,%eax		# 0 if not supported, 1 if supported
89
	ret
88
	ret
90
 
89
 
91
cpuid:
90
cpuid:
92
	movq %rbx, %r10  # we have to preserve rbx across function calls
91
	movq %rbx, %r10  # we have to preserve rbx across function calls
93
 
92
 
94
	movl %edi,%eax	# load the command into %eax
93
	movl %edi,%eax	# load the command into %eax
95
 
94
 
96
	cpuid	
95
	cpuid	
97
	movl %eax,0(%rsi)
96
	movl %eax,0(%rsi)
98
	movl %ebx,4(%rsi)
97
	movl %ebx,4(%rsi)
99
	movl %ecx,8(%rsi)
98
	movl %ecx,8(%rsi)
100
	movl %edx,12(%rsi)
99
	movl %edx,12(%rsi)
101
 
100
 
102
	movq %r10, %rbx
101
	movq %r10, %rbx
103
	ret
102
	ret
104
 
103
 
105
rdtsc:
104
rdtsc:
106
	xorq %rax,%rax
105
	xorq %rax,%rax
107
	rdtsc
106
	rdtsc
108
	ret
107
	ret
109
 
108
 
110
set_efer_flag:
109
set_efer_flag:
111
	movq $0xc0000080, %rcx
110
	movq $0xc0000080, %rcx
112
	rdmsr
111
	rdmsr
113
	btsl %edi, %eax
112
	btsl %edi, %eax
114
	wrmsr
113
	wrmsr
115
	ret
114
	ret
116
	
115
	
117
read_efer_flag:	
116
read_efer_flag:	
118
	movq $0xc0000080, %rcx
117
	movq $0xc0000080, %rcx
119
	rdmsr
118
	rdmsr
120
	ret 		
119
	ret 		
121
 
120
 
122
# Push all general purpose registers on stack except %rbp, %rsp
121
# Push all general purpose registers on stack except %rbp, %rsp
123
.macro push_all_gpr
122
.macro push_all_gpr
124
	pushq %rax 
123
	pushq %rax 
125
	pushq %rbx
124
	pushq %rbx
126
	pushq %rcx
125
	pushq %rcx
127
	pushq %rdx
126
	pushq %rdx
128
	pushq %rsi
127
	pushq %rsi
129
	pushq %rdi
128
	pushq %rdi
130
	pushq %r8
129
	pushq %r8
131
	pushq %r9
130
	pushq %r9
132
	pushq %r10
131
	pushq %r10
133
	pushq %r11
132
	pushq %r11
134
	pushq %r12
133
	pushq %r12
135
	pushq %r13
134
	pushq %r13
136
	pushq %r14
135
	pushq %r14
137
	pushq %r15
136
	pushq %r15
138
.endm
137
.endm
139
 
138
 
140
.macro pop_all_gpr
139
.macro pop_all_gpr
141
	popq %r15
140
	popq %r15
142
	popq %r14
141
	popq %r14
143
	popq %r13
142
	popq %r13
144
	popq %r12
143
	popq %r12
145
	popq %r11
144
	popq %r11
146
	popq %r10
145
	popq %r10
147
	popq %r9
146
	popq %r9
148
	popq %r8
147
	popq %r8
149
	popq %rdi
148
	popq %rdi
150
	popq %rsi
149
	popq %rsi
151
	popq %rdx
150
	popq %rdx
152
	popq %rcx
151
	popq %rcx
153
	popq %rbx
152
	popq %rbx
154
	popq %rax
153
	popq %rax
155
.endm
154
.endm
156
	
155
	
157
## Declare interrupt handlers
156
## Declare interrupt handlers
158
#
157
#
159
# Declare interrupt handlers for n interrupt
158
# Declare interrupt handlers for n interrupt
160
# vectors starting at vector i.
159
# vectors starting at vector i.
161
#
160
#
162
# The handlers setup data segment registers
161
# The handlers setup data segment registers
163
# and call trap_dispatcher().
162
# and call trap_dispatcher().
164
#
163
#
165
.macro handler i n
164
.macro handler i n
166
	pushq %rbp
165
	pushq %rbp
167
	movq %rsp,%rbp
166
	movq %rsp,%rbp
168
	
167
	
169
	push_all_gpr
168
	push_all_gpr
170
 
169
 
171
	movq $(\i),%rdi   # %rdi - first parameter
170
	movq $(\i),%rdi   # %rdi - first parameter
172
	movq %rbp, %rsi
171
	movq %rbp, %rsi
173
	addq $8, %rsi     # %rsi - second parameter - original stack
172
	addq $8, %rsi     # %rsi - second parameter - original stack
174
	call trap_dispatcher 	# trap_dispatcher(i, stack)
173
	call trap_dispatcher 	# trap_dispatcher(i, stack)
175
 
174
 
176
# Test if this is interrupt with error word or not
175
# Test if this is interrupt with error word or not
177
	mov $\i,%cl;
176
	mov $\i,%cl;
178
	movl $1,%eax;
177
	movl $1,%eax;
179
	test $0xe0,%cl;
178
	test $0xe0,%cl;
180
	jnz 0f;
179
	jnz 0f;
181
	and $0x1f,%cl;
180
	and $0x1f,%cl;
182
	shl %cl,%eax;
181
	shl %cl,%eax;
183
	and $ERROR_WORD_INTERRUPT_LIST,%eax;
182
	and $ERROR_WORD_INTERRUPT_LIST,%eax;
184
	jz 0f;
183
	jz 0f;
185
 
184
 
186
 
185
 
187
# Return with error word
186
# Return with error word
188
	pop_all_gpr
187
	pop_all_gpr
189
	
188
	
190
	popq %rbp;
189
	popq %rbp;
191
	add $8,%esp;    # Skip error word
190
	add $8,%esp;    # Skip error word
192
	iretq
191
	iretq
193
 
192
 
194
0:
193
0:
195
# Return with no error word
194
# Return with no error word
196
	pop_all_gpr
195
	pop_all_gpr
197
	
196
	
198
	popq %rbp
197
	popq %rbp
199
	iretq
198
	iretq
200
 
199
 
201
	.if (\n-\i)-1
200
	.if (\n-\i)-1
202
	handler "(\i+1)",\n
201
	handler "(\i+1)",\n
203
	.endif
202
	.endif
204
.endm
203
.endm
205
	
204
	
206
interrupt_handlers:
205
interrupt_handlers:
207
h_start:
206
h_start:
208
	handler 0 IDT_ITEMS
207
	handler 0 IDT_ITEMS
209
h_end:
208
h_end:
210
	
209
	
211
	
210
	
212
.data
211
.data
213
.global interrupt_handler_size
212
.global interrupt_handler_size
214
 
213
 
215
interrupt_handler_size: .long (h_end-h_start)/IDT_ITEMS
214
interrupt_handler_size: .long (h_end-h_start)/IDT_ITEMS
216
 
215