Subversion Repositories HelenOS-historic

Rev

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

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