Subversion Repositories HelenOS-historic

Rev

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

Rev 251 Rev 252
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__
36
#define __ASM__
37
#include <arch/pm.h>
37
#include <arch/pm.h>
38
	
38
	
39
.text
39
.text
40
.global interrupt_handlers
40
.global interrupt_handlers
41
.global panic_printf
41
.global panic_printf
42
.global cpuid
-
 
43
 
42
 
44
panic_printf:
43
panic_printf:
45
	movq $halt, (%rsp)
44
	movq $halt, (%rsp)
46
	jmp printf
45
	jmp printf
47
 
46
 
-
 
47
.global memcpy
-
 
48
memcpy:
-
 
49
	jmp _memcpy
-
 
50
	
-
 
51
.global cpuid
48
.global has_cpuid
52
.global has_cpuid
49
.global rdtsc
53
.global rdtsc
50
.global read_efer_flag
54
.global read_efer_flag
51
.global set_efer_flag
55
.global set_efer_flag
52
	
56
	
-
 
57
 
53
## Determine CPUID support
58
## Determine CPUID support
54
#
59
#
55
# Return 0 in EAX if CPUID is not support, 1 if supported.
60
# Return 0 in EAX if CPUID is not support, 1 if supported.
56
#
61
#
57
has_cpuid:
62
has_cpuid:
58
	pushq %rbx
63
	pushq %rbx
59
	
64
	
60
	pushfq			# store flags
65
	pushfq			# store flags
61
	popq %rax		# read flags
66
	popq %rax		# read flags
62
	movq %rax,%rbx		# copy flags
67
	movq %rax,%rbx		# copy flags
63
	btcl $21,%ebx		# swap the ID bit
68
	btcl $21,%ebx		# swap the ID bit
64
	pushq %rbx
69
	pushq %rbx
65
	popfq			# propagate the change into flags
70
	popfq			# propagate the change into flags
66
	pushfq
71
	pushfq
67
	popq %rbx		# read flags	
72
	popq %rbx		# read flags	
68
	andl $(1<<21),%eax	# interested only in ID bit
73
	andl $(1<<21),%eax	# interested only in ID bit
69
	andl $(1<<21),%ebx
74
	andl $(1<<21),%ebx
70
	xorl %ebx,%eax		# 0 if not supported, 1 if supported
75
	xorl %ebx,%eax		# 0 if not supported, 1 if supported
71
	
76
	
72
	popq %rbx
77
	popq %rbx
73
	ret
78
	ret
74
 
79
 
75
cpuid:
80
cpuid:
76
	movq %rbx, %r10  # we have to preserve rbx across function calls
81
	movq %rbx, %r10  # we have to preserve rbx across function calls
77
 
82
 
78
	movl %edi,%eax	# load the command into %eax
83
	movl %edi,%eax	# load the command into %eax
79
 
84
 
80
	cpuid	
85
	cpuid	
81
	movl %eax,0(%rsi)
86
	movl %eax,0(%rsi)
82
	movl %ebx,4(%rsi)
87
	movl %ebx,4(%rsi)
83
	movl %ecx,8(%rsi)
88
	movl %ecx,8(%rsi)
84
	movl %edx,12(%rsi)
89
	movl %edx,12(%rsi)
85
 
90
 
86
	movq %r10, %rbx
91
	movq %r10, %rbx
87
	ret
92
	ret
88
 
93
 
89
rdtsc:
94
rdtsc:
90
	xorq %rax,%rax
95
	xorq %rax,%rax
91
	rdtsc
96
	rdtsc
92
	ret
97
	ret
93
 
98
 
94
set_efer_flag:
99
set_efer_flag:
95
	movq $0xc0000080, %rcx
100
	movq $0xc0000080, %rcx
96
	rdmsr
101
	rdmsr
97
	btsl %edi, %eax
102
	btsl %edi, %eax
98
	wrmsr
103
	wrmsr
99
	ret
104
	ret
100
	
105
	
101
read_efer_flag:	
106
read_efer_flag:	
102
	movq $0xc0000080, %rcx
107
	movq $0xc0000080, %rcx
103
	rdmsr
108
	rdmsr
104
	ret 		
109
	ret 		
105
 
110
 
106
# Push all general purpose registers on stack except %rbp, %rsp
111
# Push all general purpose registers on stack except %rbp, %rsp
107
.macro push_all_gpr
112
.macro push_all_gpr
108
	pushq %rax 
113
	pushq %rax 
109
	pushq %rbx
114
	pushq %rbx
110
	pushq %rcx
115
	pushq %rcx
111
	pushq %rdx
116
	pushq %rdx
112
	pushq %rsi
117
	pushq %rsi
113
	pushq %rdi
118
	pushq %rdi
114
	pushq %r8
119
	pushq %r8
115
	pushq %r9
120
	pushq %r9
116
	pushq %r10
121
	pushq %r10
117
	pushq %r11
122
	pushq %r11
118
	pushq %r12
123
	pushq %r12
119
	pushq %r13
124
	pushq %r13
120
	pushq %r14
125
	pushq %r14
121
	pushq %r15
126
	pushq %r15
122
.endm
127
.endm
123
 
128
 
124
.macro pop_all_gpr
129
.macro pop_all_gpr
125
	popq %r15
130
	popq %r15
126
	popq %r14
131
	popq %r14
127
	popq %r13
132
	popq %r13
128
	popq %r12
133
	popq %r12
129
	popq %r11
134
	popq %r11
130
	popq %r10
135
	popq %r10
131
	popq %r9
136
	popq %r9
132
	popq %r8
137
	popq %r8
133
	popq %rdi
138
	popq %rdi
134
	popq %rsi
139
	popq %rsi
135
	popq %rdx
140
	popq %rdx
136
	popq %rcx
141
	popq %rcx
137
	popq %rbx
142
	popq %rbx
138
	popq %rax
143
	popq %rax
139
.endm
144
.endm
140
	
145
	
141
## Declare interrupt handlers
146
## Declare interrupt handlers
142
#
147
#
143
# Declare interrupt handlers for n interrupt
148
# Declare interrupt handlers for n interrupt
144
# vectors starting at vector i.
149
# vectors starting at vector i.
145
#
150
#
146
# The handlers setup data segment registers
151
# The handlers setup data segment registers
147
# and call trap_dispatcher().
152
# and call trap_dispatcher().
148
#
153
#
149
.macro handler i n
154
.macro handler i n
150
	pushq %rbp
155
	pushq %rbp
151
	movq %rsp,%rbp
156
	movq %rsp,%rbp
152
	
157
	
153
	push_all_gpr
158
	push_all_gpr
154
 
159
 
155
	# trap_dispatcher(i, stack)
160
	# trap_dispatcher(i, stack)
156
	movq $(\i),%rdi   # %rdi - first parameter
161
	movq $(\i),%rdi   # %rdi - first parameter
157
	movq %rbp, %rsi
162
	movq %rbp, %rsi
158
	addq $8, %rsi     # %rsi - second parameter - original stack
163
	addq $8, %rsi     # %rsi - second parameter - original stack
159
	call trap_dispatcher
164
	call trap_dispatcher
160
 
165
 
161
# Test if this is interrupt with error word or not
166
# Test if this is interrupt with error word or not
162
	mov $\i,%cl;
167
	mov $\i,%cl;
163
	movl $1,%eax;
168
	movl $1,%eax;
164
	test $0xe0,%cl;
169
	test $0xe0,%cl;
165
	jnz 0f;
170
	jnz 0f;
166
	and $0x1f,%cl;
171
	and $0x1f,%cl;
167
	shl %cl,%eax;
172
	shl %cl,%eax;
168
	and $ERROR_WORD_INTERRUPT_LIST,%eax;
173
	and $ERROR_WORD_INTERRUPT_LIST,%eax;
169
	jz 0f;
174
	jz 0f;
170
 
175
 
171
 
176
 
172
# Return with error word
177
# Return with error word
173
	pop_all_gpr
178
	pop_all_gpr
174
	
179
	
175
	popq %rbp;
180
	popq %rbp;
176
	add $8,%esp;    # Skip error word
181
	add $8,%esp;    # Skip error word
177
	iretq
182
	iretq
178
 
183
 
179
0:
184
0:
180
# Return with no error word
185
# Return with no error word
181
	pop_all_gpr
186
	pop_all_gpr
182
	
187
	
183
	popq %rbp
188
	popq %rbp
184
	iretq
189
	iretq
185
 
190
 
186
	.if (\n-\i)-1
191
	.if (\n-\i)-1
187
	handler "(\i+1)",\n
192
	handler "(\i+1)",\n
188
	.endif
193
	.endif
189
.endm
194
.endm
190
	
195
	
191
interrupt_handlers:
196
interrupt_handlers:
192
h_start:
197
h_start:
193
	handler 0 IDT_ITEMS
198
	handler 0 IDT_ITEMS
194
#	handler 64 128	
199
#	handler 64 128	
195
#	handler 128 192
200
#	handler 128 192
196
#	handler 192 256
201
#	handler 192 256
197
h_end:
202
h_end:
198
	
203
	
199
	
204
	
200
.data
205
.data
201
.global interrupt_handler_size
206
.global interrupt_handler_size
202
 
207
 
203
interrupt_handler_size: .long (h_end-h_start)/IDT_ITEMS
208
interrupt_handler_size: .long (h_end-h_start)/IDT_ITEMS
204
 
209