Subversion Repositories HelenOS

Rev

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

Rev 3044 Rev 3274
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
#define IREGISTER_SPACE 120
29
#define IREGISTER_SPACE 120
30
 
30
 
31
#define IOFFSET_RAX 0x0
31
#define IOFFSET_RAX 0x0
32
#define IOFFSET_RBX 0x8
32
#define IOFFSET_RBX 0x8
33
#define IOFFSET_RCX 0x10
33
#define IOFFSET_RCX 0x10
34
#define IOFFSET_RDX 0x18
34
#define IOFFSET_RDX 0x18
35
#define IOFFSET_RSI 0x20
35
#define IOFFSET_RSI 0x20
36
#define IOFFSET_RDI 0x28
36
#define IOFFSET_RDI 0x28
37
#define IOFFSET_R8 0x30
37
#define IOFFSET_R8 0x30
38
#define IOFFSET_R9 0x38
38
#define IOFFSET_R9 0x38
39
#define IOFFSET_R10 0x40
39
#define IOFFSET_R10 0x40
40
#define IOFFSET_R11 0x48
40
#define IOFFSET_R11 0x48
41
#define IOFFSET_R12 0x50
41
#define IOFFSET_R12 0x50
42
#define IOFFSET_R13 0x58
42
#define IOFFSET_R13 0x58
43
#define IOFFSET_R14 0x60
43
#define IOFFSET_R14 0x60
44
#define IOFFSET_R15 0x68
44
#define IOFFSET_R15 0x68
45
#define IOFFSET_RBP 0x70
45
#define IOFFSET_RBP 0x70
46
 
46
 
47
#  Mask for interrupts 0 - 31 (bits 0 - 31) where 0 means that int has no error word
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
48
# and 1 means interrupt with error word
49
#define ERROR_WORD_INTERRUPT_LIST 0x00027D00
49
#define ERROR_WORD_INTERRUPT_LIST 0x00027D00
50
 
50
 
51
#include <arch/pm.h>
51
#include <arch/pm.h>
52
#include <arch/mm/page.h>
52
#include <arch/mm/page.h>
53
	
53
	
54
.text
54
.text
55
.global interrupt_handlers
55
.global interrupt_handlers
56
.global syscall_entry
56
.global syscall_entry
57
.global panic_printf
57
.global panic_printf
58
 
58
 
59
panic_printf:
59
panic_printf:
60
	movq $halt, (%rsp)
60
	movq $halt, (%rsp)
61
	jmp printf
61
	jmp printf
62
 
62
 
63
.global cpuid
63
.global cpuid
64
.global has_cpuid
64
.global has_cpuid
65
.global get_cycle
65
.global get_cycle
66
.global read_efer_flag
66
.global read_efer_flag
67
.global set_efer_flag
67
.global set_efer_flag
68
.global memsetb
68
.global memsetb
69
.global memsetw
69
.global memsetw
70
.global memcpy
70
.global memcpy
71
.global memcpy_from_uspace
71
.global memcpy_from_uspace
72
.global memcpy_to_uspace
72
.global memcpy_to_uspace
73
.global memcpy_from_uspace_failover_address
73
.global memcpy_from_uspace_failover_address
74
.global memcpy_to_uspace_failover_address
74
.global memcpy_to_uspace_failover_address
75
 
75
 
76
# Wrapper for generic memsetb
76
# Wrapper for generic memsetb
77
memsetb:
77
memsetb:
78
	jmp _memsetb
78
	jmp _memsetb
79
 
79
 
80
# Wrapper for generic memsetw
80
# Wrapper for generic memsetw
81
memsetw:
81
memsetw:
82
	jmp _memsetw
82
	jmp _memsetw
83
 
83
 
84
#define MEMCPY_DST	%rdi
84
#define MEMCPY_DST	%rdi
85
#define MEMCPY_SRC	%rsi
85
#define MEMCPY_SRC	%rsi
86
#define MEMCPY_SIZE	%rdx
86
#define MEMCPY_SIZE	%rdx
87
 
87
 
88
/**
88
/**
89
 * Copy memory from/to userspace.
89
 * Copy memory from/to userspace.
90
 *
90
 *
91
 * This is almost conventional memcpy().
91
 * This is almost conventional memcpy().
92
 * The difference is that there is a failover part
92
 * The difference is that there is a failover part
93
 * to where control is returned from a page fault if
93
 * to where control is returned from a page fault if
94
 * the page fault occurs during copy_from_uspace()
94
 * the page fault occurs during copy_from_uspace()
95
 * or copy_to_uspace().
95
 * or copy_to_uspace().
96
 *
96
 *
97
 * @param MEMCPY_DST	Destination address.
97
 * @param MEMCPY_DST	Destination address.
98
 * @param MEMCPY_SRC	Source address.
98
 * @param MEMCPY_SRC	Source address.
99
 * @param MEMCPY_SIZE	Number of bytes to copy.
99
 * @param MEMCPY_SIZE	Number of bytes to copy.
100
 *
100
 *
101
 * @retrun MEMCPY_SRC on success, 0 on failure.
101
 * @retrun MEMCPY_DST on success, 0 on failure.
102
 */
102
 */
103
memcpy:
103
memcpy:
104
memcpy_from_uspace:
104
memcpy_from_uspace:
105
memcpy_to_uspace:
105
memcpy_to_uspace:
106
	movq MEMCPY_SRC, %rax
106
	movq MEMCPY_DST, %rax
107
 
107
 
108
	movq MEMCPY_SIZE, %rcx
108
	movq MEMCPY_SIZE, %rcx
109
	shrq $3, %rcx			/* size / 8 */
109
	shrq $3, %rcx			/* size / 8 */
110
	
110
	
111
	rep movsq			/* copy as much as possible word by word */
111
	rep movsq			/* copy as much as possible word by word */
112
 
112
 
113
	movq MEMCPY_SIZE, %rcx
113
	movq MEMCPY_SIZE, %rcx
114
	andq $7, %rcx			/* size % 8 */
114
	andq $7, %rcx			/* size % 8 */
115
	jz 0f
115
	jz 0f
116
	
116
	
117
	rep movsb			/* copy the rest byte by byte */
117
	rep movsb			/* copy the rest byte by byte */
118
	
118
	
119
0:
119
0:
120
	ret				/* return MEMCPY_SRC, success */
120
	ret				/* return MEMCPY_SRC, success */
121
 
121
 
122
memcpy_from_uspace_failover_address:
122
memcpy_from_uspace_failover_address:
123
memcpy_to_uspace_failover_address:
123
memcpy_to_uspace_failover_address:
124
	xorq %rax, %rax			/* return 0, failure */
124
	xorq %rax, %rax			/* return 0, failure */
125
	ret
125
	ret
126
 
126
 
127
## Determine CPUID support
127
## Determine CPUID support
128
#
128
#
129
# Return 0 in EAX if CPUID is not support, 1 if supported.
129
# Return 0 in EAX if CPUID is not support, 1 if supported.
130
#
130
#
131
has_cpuid:
131
has_cpuid:
132
	pushfq			# store flags
132
	pushfq			# store flags
133
	popq %rax		# read flags
133
	popq %rax		# read flags
134
	movq %rax,%rdx		# copy flags
134
	movq %rax,%rdx		# copy flags
135
	btcl $21,%edx		# swap the ID bit
135
	btcl $21,%edx		# swap the ID bit
136
	pushq %rdx
136
	pushq %rdx
137
	popfq			# propagate the change into flags
137
	popfq			# propagate the change into flags
138
	pushfq
138
	pushfq
139
	popq %rdx		# read flags	
139
	popq %rdx		# read flags	
140
	andl $(1<<21),%eax	# interested only in ID bit
140
	andl $(1<<21),%eax	# interested only in ID bit
141
	andl $(1<<21),%edx
141
	andl $(1<<21),%edx
142
	xorl %edx,%eax		# 0 if not supported, 1 if supported
142
	xorl %edx,%eax		# 0 if not supported, 1 if supported
143
	ret
143
	ret
144
 
144
 
145
cpuid:
145
cpuid:
146
	movq %rbx, %r10  # we have to preserve rbx across function calls
146
	movq %rbx, %r10  # we have to preserve rbx across function calls
147
 
147
 
148
	movl %edi,%eax	# load the command into %eax
148
	movl %edi,%eax	# load the command into %eax
149
 
149
 
150
	cpuid	
150
	cpuid	
151
	movl %eax,0(%rsi)
151
	movl %eax,0(%rsi)
152
	movl %ebx,4(%rsi)
152
	movl %ebx,4(%rsi)
153
	movl %ecx,8(%rsi)
153
	movl %ecx,8(%rsi)
154
	movl %edx,12(%rsi)
154
	movl %edx,12(%rsi)
155
 
155
 
156
	movq %r10, %rbx
156
	movq %r10, %rbx
157
	ret
157
	ret
158
 
158
 
159
get_cycle:
159
get_cycle:
160
	xorq %rax,%rax
160
	xorq %rax,%rax
161
	rdtsc
161
	rdtsc
162
	ret
162
	ret
163
 
163
 
164
set_efer_flag:
164
set_efer_flag:
165
	movq $0xc0000080, %rcx
165
	movq $0xc0000080, %rcx
166
	rdmsr
166
	rdmsr
167
	btsl %edi, %eax
167
	btsl %edi, %eax
168
	wrmsr
168
	wrmsr
169
	ret
169
	ret
170
	
170
	
171
read_efer_flag:	
171
read_efer_flag:	
172
	movq $0xc0000080, %rcx
172
	movq $0xc0000080, %rcx
173
	rdmsr
173
	rdmsr
174
	ret 		
174
	ret 		
175
 
175
 
176
# Push all general purpose registers on stack except %rbp, %rsp
176
# Push all general purpose registers on stack except %rbp, %rsp
177
.macro save_all_gpr
177
.macro save_all_gpr
178
	movq %rax, IOFFSET_RAX(%rsp)
178
	movq %rax, IOFFSET_RAX(%rsp)
179
	movq %rcx, IOFFSET_RCX(%rsp)
179
	movq %rcx, IOFFSET_RCX(%rsp)
180
	movq %rdx, IOFFSET_RDX(%rsp)
180
	movq %rdx, IOFFSET_RDX(%rsp)
181
	movq %rsi, IOFFSET_RSI(%rsp)
181
	movq %rsi, IOFFSET_RSI(%rsp)
182
	movq %rdi, IOFFSET_RDI(%rsp)
182
	movq %rdi, IOFFSET_RDI(%rsp)
183
	movq %r8, IOFFSET_R8(%rsp)
183
	movq %r8, IOFFSET_R8(%rsp)
184
	movq %r9, IOFFSET_R9(%rsp)
184
	movq %r9, IOFFSET_R9(%rsp)
185
	movq %r10, IOFFSET_R10(%rsp)
185
	movq %r10, IOFFSET_R10(%rsp)
186
	movq %r11, IOFFSET_R11(%rsp)
186
	movq %r11, IOFFSET_R11(%rsp)
187
#ifdef CONFIG_DEBUG_ALLREGS	
187
#ifdef CONFIG_DEBUG_ALLREGS	
188
	movq %rbx, IOFFSET_RBX(%rsp)
188
	movq %rbx, IOFFSET_RBX(%rsp)
189
	movq %rbp, IOFFSET_RBP(%rsp)
189
	movq %rbp, IOFFSET_RBP(%rsp)
190
	movq %r12, IOFFSET_R12(%rsp)
190
	movq %r12, IOFFSET_R12(%rsp)
191
	movq %r13, IOFFSET_R13(%rsp)
191
	movq %r13, IOFFSET_R13(%rsp)
192
	movq %r14, IOFFSET_R14(%rsp)
192
	movq %r14, IOFFSET_R14(%rsp)
193
	movq %r15, IOFFSET_R15(%rsp)
193
	movq %r15, IOFFSET_R15(%rsp)
194
#endif
194
#endif
195
.endm
195
.endm
196
 
196
 
197
.macro restore_all_gpr
197
.macro restore_all_gpr
198
	movq IOFFSET_RAX(%rsp), %rax
198
	movq IOFFSET_RAX(%rsp), %rax
199
	movq IOFFSET_RCX(%rsp), %rcx
199
	movq IOFFSET_RCX(%rsp), %rcx
200
	movq IOFFSET_RDX(%rsp), %rdx
200
	movq IOFFSET_RDX(%rsp), %rdx
201
	movq IOFFSET_RSI(%rsp), %rsi
201
	movq IOFFSET_RSI(%rsp), %rsi
202
	movq IOFFSET_RDI(%rsp), %rdi
202
	movq IOFFSET_RDI(%rsp), %rdi
203
	movq IOFFSET_R8(%rsp), %r8
203
	movq IOFFSET_R8(%rsp), %r8
204
	movq IOFFSET_R9(%rsp), %r9
204
	movq IOFFSET_R9(%rsp), %r9
205
	movq IOFFSET_R10(%rsp), %r10
205
	movq IOFFSET_R10(%rsp), %r10
206
	movq IOFFSET_R11(%rsp), %r11
206
	movq IOFFSET_R11(%rsp), %r11
207
#ifdef CONFIG_DEBUG_ALLREGS	
207
#ifdef CONFIG_DEBUG_ALLREGS	
208
	movq IOFFSET_RBX(%rsp), %rbx
208
	movq IOFFSET_RBX(%rsp), %rbx
209
	movq IOFFSET_RBP(%rsp), %rbp
209
	movq IOFFSET_RBP(%rsp), %rbp
210
	movq IOFFSET_R12(%rsp), %r12
210
	movq IOFFSET_R12(%rsp), %r12
211
	movq IOFFSET_R13(%rsp), %r13
211
	movq IOFFSET_R13(%rsp), %r13
212
	movq IOFFSET_R14(%rsp), %r14
212
	movq IOFFSET_R14(%rsp), %r14
213
	movq IOFFSET_R15(%rsp), %r15
213
	movq IOFFSET_R15(%rsp), %r15
214
#endif
214
#endif
215
.endm
215
.endm
216
 
216
 
217
#ifdef CONFIG_DEBUG_ALLREGS
217
#ifdef CONFIG_DEBUG_ALLREGS
218
# define INTERRUPT_ALIGN 256
218
# define INTERRUPT_ALIGN 256
219
#else
219
#else
220
# define INTERRUPT_ALIGN 128
220
# define INTERRUPT_ALIGN 128
221
#endif
221
#endif
222
	
222
	
223
## Declare interrupt handlers
223
## Declare interrupt handlers
224
#
224
#
225
# Declare interrupt handlers for n interrupt
225
# Declare interrupt handlers for n interrupt
226
# vectors starting at vector i.
226
# vectors starting at vector i.
227
#
227
#
228
# The handlers call exc_dispatch().
228
# The handlers call exc_dispatch().
229
#
229
#
230
.macro handler i n
230
.macro handler i n
231
 
231
 
232
	/*
232
	/*
233
	 * Choose between version with error code and version without error
233
	 * Choose between version with error code and version without error
234
	 * code. Both versions have to be of the same size. amd64 assembly is,
234
	 * code. Both versions have to be of the same size. amd64 assembly is,
235
	 * however, a little bit tricky. For instance, subq $0x80, %rsp and
235
	 * however, a little bit tricky. For instance, subq $0x80, %rsp and
236
	 * subq $0x78, %rsp can result in two instructions with different
236
	 * subq $0x78, %rsp can result in two instructions with different
237
	 * op-code lengths.
237
	 * op-code lengths.
238
	 * Therefore we align the interrupt handlers.
238
	 * Therefore we align the interrupt handlers.
239
	 */
239
	 */
240
 
240
 
241
	.iflt \i-32
241
	.iflt \i-32
242
		.if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
242
		.if (1 << \i) & ERROR_WORD_INTERRUPT_LIST
243
			/*
243
			/*
244
			 * Version with error word.
244
			 * Version with error word.
245
			 */
245
			 */
246
			subq $IREGISTER_SPACE, %rsp
246
			subq $IREGISTER_SPACE, %rsp
247
		.else
247
		.else
248
			/*
248
			/*
249
			 * Version without error word,
249
			 * Version without error word,
250
			 */
250
			 */
251
			subq $(IREGISTER_SPACE+8), %rsp
251
			subq $(IREGISTER_SPACE+8), %rsp
252
		.endif
252
		.endif
253
	.else
253
	.else
254
		/*
254
		/*
255
		 * Version without error word,
255
		 * Version without error word,
256
		 */
256
		 */
257
		subq $(IREGISTER_SPACE+8), %rsp
257
		subq $(IREGISTER_SPACE+8), %rsp
258
	.endif	
258
	.endif	
259
 
259
 
260
	save_all_gpr
260
	save_all_gpr
261
	cld
261
	cld
262
 
262
 
263
	movq $(\i), %rdi   	# %rdi - first parameter
263
	movq $(\i), %rdi   	# %rdi - first parameter
264
	movq %rsp, %rsi   	# %rsi - pointer to istate
264
	movq %rsp, %rsi   	# %rsi - pointer to istate
265
	call exc_dispatch 	# exc_dispatch(i, istate)
265
	call exc_dispatch 	# exc_dispatch(i, istate)
266
	
266
	
267
	restore_all_gpr
267
	restore_all_gpr
268
	# $8 = Skip error word
268
	# $8 = Skip error word
269
	addq $(IREGISTER_SPACE+8), %rsp
269
	addq $(IREGISTER_SPACE+8), %rsp
270
	iretq
270
	iretq
271
 
271
 
272
	.align INTERRUPT_ALIGN
272
	.align INTERRUPT_ALIGN
273
	.if (\n-\i)-1
273
	.if (\n-\i)-1
274
	handler "(\i+1)",\n
274
	handler "(\i+1)",\n
275
	.endif
275
	.endif
276
.endm
276
.endm
277
 
277
 
278
.align INTERRUPT_ALIGN
278
.align INTERRUPT_ALIGN
279
interrupt_handlers:
279
interrupt_handlers:
280
h_start:
280
h_start:
281
	handler 0 IDT_ITEMS
281
	handler 0 IDT_ITEMS
282
h_end:
282
h_end:
283
 
283
 
284
## Low-level syscall handler
284
## Low-level syscall handler
285
# 
285
# 
286
# Registers on entry:
286
# Registers on entry:
287
#
287
#
288
# @param rcx		Userspace return address.
288
# @param rcx		Userspace return address.
289
# @param r11		Userspace RLFAGS.
289
# @param r11		Userspace RLFAGS.
290
#
290
#
291
# @param rax		Syscall number.
291
# @param rax		Syscall number.
292
# @param rdi		1st syscall argument.
292
# @param rdi		1st syscall argument.
293
# @param rsi		2nd syscall argument.
293
# @param rsi		2nd syscall argument.
294
# @param rdx		3rd syscall argument.
294
# @param rdx		3rd syscall argument.
295
# @param r10		4th syscall argument. Used instead of RCX because the
295
# @param r10		4th syscall argument. Used instead of RCX because the
296
#			SYSCALL instruction clobbers it.
296
#			SYSCALL instruction clobbers it.
297
# @param r8		5th syscall argument.
297
# @param r8		5th syscall argument.
298
# @param r9		6th syscall argument.
298
# @param r9		6th syscall argument.
299
#
299
#
300
# @return		Return value is in rax.
300
# @return		Return value is in rax.
301
#
301
#
302
syscall_entry:
302
syscall_entry:
303
	swapgs			# Switch to hidden gs	
303
	swapgs			# Switch to hidden gs	
304
	# 
304
	# 
305
	# %gs:0			Scratch space for this thread's user RSP
305
	# %gs:0			Scratch space for this thread's user RSP
306
	# %gs:8			Address to be used as this thread's kernel RSP
306
	# %gs:8			Address to be used as this thread's kernel RSP
307
	#
307
	#
308
	movq %rsp, %gs:0	# Save this thread's user RSP
308
	movq %rsp, %gs:0	# Save this thread's user RSP
309
	movq %gs:8, %rsp	# Set this thread's kernel RSP
309
	movq %gs:8, %rsp	# Set this thread's kernel RSP
310
	swapgs			# Switch back to remain consistent
310
	swapgs			# Switch back to remain consistent
311
	sti
311
	sti
312
	
312
	
313
	pushq %rcx
313
	pushq %rcx
314
	pushq %r11
314
	pushq %r11
315
 
315
 
316
	movq %r10, %rcx		# Copy the 4th argument where it is expected 
316
	movq %r10, %rcx		# Copy the 4th argument where it is expected 
317
	pushq %rax
317
	pushq %rax
318
	call syscall_handler
318
	call syscall_handler
319
	addq $8, %rsp
319
	addq $8, %rsp
320
		
320
		
321
	popq %r11
321
	popq %r11
322
	popq %rcx
322
	popq %rcx
323
 
323
 
324
	cli
324
	cli
325
	swapgs
325
	swapgs
326
	movq %gs:0, %rsp	# Restore the user RSP
326
	movq %gs:0, %rsp	# Restore the user RSP
327
	swapgs
327
	swapgs
328
 
328
 
329
	sysretq
329
	sysretq
330
 
330
 
331
.data
331
.data
332
.global interrupt_handler_size
332
.global interrupt_handler_size
333
 
333
 
334
interrupt_handler_size: .quad (h_end-h_start)/IDT_ITEMS
334
interrupt_handler_size: .quad (h_end-h_start)/IDT_ITEMS
335
 
335