Subversion Repositories HelenOS-historic

Rev

Rev 1021 | Rev 1121 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
224 palkovsky 1
#
2
# Copyright (C) 2005 Ondrej Palkovsky
3
# All rights reserved.
4
#
5
# Redistribution and use in source and binary forms, with or without
6
# modification, are permitted provided that the following conditions
7
# are met:
8
#
9
# - Redistributions of source code must retain the above copyright
10
#   notice, this list of conditions and the following disclaimer.
11
# - Redistributions in binary form must reproduce the above copyright
12
#   notice, this list of conditions and the following disclaimer in the
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
15
#   derived from this software without specific prior written permission.
16
#
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
19
# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
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
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
26
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
#
28
 
1021 jermar 29
#define IREGISTER_SPACE 120
224 palkovsky 30
 
1021 jermar 31
#define IOFFSET_RAX 0x0
32
#define IOFFSET_RBX 0x8
33
#define IOFFSET_RCX 0x10
34
#define IOFFSET_RDX 0x18
35
#define IOFFSET_RSI 0x20
36
#define IOFFSET_RDI 0x28
37
#define IOFFSET_R8 0x30
38
#define IOFFSET_R9 0x38
39
#define IOFFSET_R10 0x40
40
#define IOFFSET_R11 0x48
41
#define IOFFSET_R12 0x50
42
#define IOFFSET_R13 0x58
43
#define IOFFSET_R14 0x60
44
#define IOFFSET_R15 0x68
45
#define IOFFSET_RBP 0x70
46
 
224 palkovsky 47
#  Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error word
48
# and 1 means interrupt with error word
49
#define ERROR_WORD_INTERRUPT_LIST 0x00027D00
50
 
51
#include <arch/pm.h>
808 palkovsky 52
#include <arch/mm/page.h>
224 palkovsky 53
 
54
.text
55
.global interrupt_handlers
803 palkovsky 56
.global syscall_entry
224 palkovsky 57
.global panic_printf
58
 
59
panic_printf:
60
	movq $halt, (%rsp)
61
	jmp printf
62
 
252 palkovsky 63
.global memcpy
64
memcpy:
65
	jmp _memcpy
66
 
67
.global cpuid
242 palkovsky 68
.global has_cpuid
69
.global rdtsc
251 palkovsky 70
.global read_efer_flag
71
.global set_efer_flag
72
 
242 palkovsky 73
## Determine CPUID support
74
#
75
# Return 0 in EAX if CPUID is not support, 1 if supported.
76
#
77
has_cpuid:
78
	pushfq			# store flags
79
	popq %rax		# read flags
348 jermar 80
	movq %rax,%rdx		# copy flags
81
	btcl $21,%edx		# swap the ID bit
82
	pushq %rdx
242 palkovsky 83
	popfq			# propagate the change into flags
84
	pushfq
348 jermar 85
	popq %rdx		# read flags	
242 palkovsky 86
	andl $(1<<21),%eax	# interested only in ID bit
348 jermar 87
	andl $(1<<21),%edx
88
	xorl %edx,%eax		# 0 if not supported, 1 if supported
242 palkovsky 89
	ret
90
 
251 palkovsky 91
cpuid:
92
	movq %rbx, %r10  # we have to preserve rbx across function calls
242 palkovsky 93
 
251 palkovsky 94
	movl %edi,%eax	# load the command into %eax
95
 
96
	cpuid	
97
	movl %eax,0(%rsi)
98
	movl %ebx,4(%rsi)
99
	movl %ecx,8(%rsi)
100
	movl %edx,12(%rsi)
101
 
102
	movq %r10, %rbx
103
	ret
104
 
242 palkovsky 105
rdtsc:
106
	xorq %rax,%rax
107
	rdtsc
108
	ret
251 palkovsky 109
 
110
set_efer_flag:
111
	movq $0xc0000080, %rcx
112
	rdmsr
113
	btsl %edi, %eax
114
	wrmsr
115
	ret
242 palkovsky 116
 
251 palkovsky 117
read_efer_flag:	
118
	movq $0xc0000080, %rcx
119
	rdmsr
120
	ret 		
242 palkovsky 121
 
224 palkovsky 122
# Push all general purpose registers on stack except %rbp, %rsp
799 palkovsky 123
.macro save_all_gpr
124
	movq %rax, IOFFSET_RAX(%rsp)
125
	movq %rcx, IOFFSET_RCX(%rsp)
126
	movq %rdx, IOFFSET_RDX(%rsp)
127
	movq %rsi, IOFFSET_RSI(%rsp)
128
	movq %rdi, IOFFSET_RDI(%rsp)
129
	movq %r8, IOFFSET_R8(%rsp)
130
	movq %r9, IOFFSET_R9(%rsp)
131
	movq %r10, IOFFSET_R10(%rsp)
132
	movq %r11, IOFFSET_R11(%rsp)
1094 palkovsky 133
#ifdef CONFIG_DEBUG_ALLREGS	
134
	movq %rbx, IOFFSET_RBX(%rsp)
135
	movq %rbp, IOFFSET_RBP(%rsp)
799 palkovsky 136
	movq %r12, IOFFSET_R12(%rsp)
137
	movq %r13, IOFFSET_R13(%rsp)
138
	movq %r14, IOFFSET_R14(%rsp)
139
	movq %r15, IOFFSET_R15(%rsp)
1094 palkovsky 140
#endif
224 palkovsky 141
.endm
142
 
799 palkovsky 143
.macro restore_all_gpr
144
	movq IOFFSET_RAX(%rsp), %rax
145
	movq IOFFSET_RCX(%rsp), %rcx
146
	movq IOFFSET_RDX(%rsp), %rdx
147
	movq IOFFSET_RSI(%rsp), %rsi
148
	movq IOFFSET_RDI(%rsp), %rdi
149
	movq IOFFSET_R8(%rsp), %r8
150
	movq IOFFSET_R9(%rsp), %r9
151
	movq IOFFSET_R10(%rsp), %r10
152
	movq IOFFSET_R11(%rsp), %r11
1094 palkovsky 153
#ifdef CONFIG_DEBUG_ALLREGS	
154
	movq IOFFSET_RBX(%rsp), %rbx
155
	movq IOFFSET_RBP(%rsp), %rbp
799 palkovsky 156
	movq IOFFSET_R12(%rsp), %r12
157
	movq IOFFSET_R13(%rsp), %r13
158
	movq IOFFSET_R14(%rsp), %r14
159
	movq IOFFSET_R15(%rsp), %r15
1094 palkovsky 160
#endif
224 palkovsky 161
.endm
1021 jermar 162
 
1094 palkovsky 163
#ifdef CONFIG_DEBUG_ALLREGS
164
# define INTERRUPT_ALIGN 256
165
#else
166
# define INTERRUPT_ALIGN 128
167
#endif
168
 
224 palkovsky 169
## Declare interrupt handlers
170
#
171
# Declare interrupt handlers for n interrupt
172
# vectors starting at vector i.
173
#
1021 jermar 174
# The handlers call exc_dispatch().
224 palkovsky 175
#
176
.macro handler i n
177
 
1021 jermar 178
	/*
179
	 * Choose between version with error code and version without error code.
180
	 * Both versions have to be of the same size. amd64 assembly is, however,
181
	 * a little bit tricky. For instance, subq $0x80, %rsp and subq $0x78, %rsp
182
	 * can result in two instructions with different op-code lengths.
183
	 * Therefore, pay special attention to the extra NOP's that serve as
184
	 * a necessary fill.
185
	 */
224 palkovsky 186
 
1021 jermar 187
	.iflt \i-32
188
		.if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
189
			/*
190
			 * Version with error word.
191
			 */
192
			subq $IREGISTER_SPACE, %rsp
193
		.else
194
			/*
195
			 * Version without error word,
196
			 */
197
			subq $(IREGISTER_SPACE+8), %rsp
198
		.endif
199
	.else
200
		/*
201
		 * Version without error word,
202
		 */
203
		subq $(IREGISTER_SPACE+8), %rsp
204
	.endif	
224 palkovsky 205
 
1021 jermar 206
	save_all_gpr
224 palkovsky 207
 
1021 jermar 208
	movq $(\i), %rdi   	# %rdi - first parameter
209
	movq %rsp, %rsi   	# %rsi - pointer to istate
210
	call exc_dispatch 	# exc_dispatch(i, istate)
211
 
799 palkovsky 212
	restore_all_gpr
213
	# $8 = Skip error word
1021 jermar 214
	addq $(IREGISTER_SPACE+8), %rsp
224 palkovsky 215
	iretq
216
 
1094 palkovsky 217
	.align INTERRUPT_ALIGN
224 palkovsky 218
	.if (\n-\i)-1
219
	handler "(\i+1)",\n
220
	.endif
221
.endm
1094 palkovsky 222
 
223
.align INTERRUPT_ALIGN
224 palkovsky 224
interrupt_handlers:
225
h_start:
226
	handler 0 IDT_ITEMS
227
h_end:
803 palkovsky 228
 
224 palkovsky 229
 
803 palkovsky 230
syscall_entry:
806 palkovsky 231
	# Switch to hidden gs	
232
	swapgs
808 palkovsky 233
	# %gs:0 now points to pointer to stack page
234
	mov %gs:0, %r10     # We have a ptr to stack page in r10
235
	addq $PAGE_SIZE-16, %r10 # We need some space to store old %sp
806 palkovsky 236
 
237
	movq %rsp, 0(%r10)  # Save old stack pointer to stack
238
	movq %r10, %rsp     # Change to new stack
239
	pushq %rcx          # Return address
240
	pushq %r11          # Save flags
241
 
242
	# Switch back to remain consistent
243
	swapgs 
244
 
955 palkovsky 245
	sti
806 palkovsky 246
	movq %r9, %rcx      # Exchange last parameter as a third
803 palkovsky 247
	call syscall_handler
955 palkovsky 248
	cli                 # We will be touching stack pointer
249
 
806 palkovsky 250
	popq %r11
251
	popq %rcx
252
	movq 0(%rsp), %rsp
253
	sysretq
803 palkovsky 254
 
224 palkovsky 255
.data
256
.global interrupt_handler_size
257
 
820 jermar 258
interrupt_handler_size: .quad (h_end-h_start)/IDT_ITEMS