Subversion Repositories HelenOS-historic

Rev

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

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