source: mainline/arch/amd64/src/asm_utils.S@ 65640fef

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 65640fef was 37b451f7, checked in by Ondrej Palkovsky <ondrap@…>, 19 years ago

Added (finally!) userspace to AMD64.
It does not work on Simics *$U&%&$&*#. Broken simics!!!
There should be probably LEA instead of MOV/ADD, but LEA does not
work in neither qemu nor bochs. Any other simulator to test? :-/

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