source: mainline/arch/amd64/src/asm_utils.S@ 389f41e

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 389f41e was d6dcdd2e, checked in by Jakub Jermar <jakub@…>, 20 years ago

Optimize some assembler functions.

  • Property mode set to 100644
File size: 4.2 KB
RevLine 
[e3b9572]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#define __ASM__
37#include <arch/pm.h>
38
39.text
40.global interrupt_handlers
41.global panic_printf
42
43panic_printf:
44 movq $halt, (%rsp)
45 jmp printf
46
[36b209a]47.global memcpy
48memcpy:
49 jmp _memcpy
50
51.global cpuid
[7df54df]52.global has_cpuid
53.global rdtsc
[89344d85]54.global read_efer_flag
55.global set_efer_flag
56
[36b209a]57
[e515167d]58# THIS IS USERSPACE CODE
59.global utext
60utext:
610:
62 int $48
63 jmp 0b
64 # not reached
65utext_end:
66
67.data
68.global utext_size
69utext_size:
70 .long utext_end - utext
71
72
[7df54df]73## Determine CPUID support
74#
75# Return 0 in EAX if CPUID is not support, 1 if supported.
76#
77has_cpuid:
78 pushfq # store flags
79 popq %rax # read flags
[d6dcdd2e]80 movq %rax,%rdx # copy flags
81 btcl $21,%edx # swap the ID bit
82 pushq %rdx
[7df54df]83 popfq # propagate the change into flags
84 pushfq
[d6dcdd2e]85 popq %rdx # read flags
[7df54df]86 andl $(1<<21),%eax # interested only in ID bit
[d6dcdd2e]87 andl $(1<<21),%edx
88 xorl %edx,%eax # 0 if not supported, 1 if supported
[7df54df]89 ret
90
[89344d85]91cpuid:
92 movq %rbx, %r10 # we have to preserve rbx across function calls
93
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
[7df54df]104
105rdtsc:
106 xorq %rax,%rax
107 rdtsc
108 ret
[89344d85]109
110set_efer_flag:
111 movq $0xc0000080, %rcx
112 rdmsr
113 btsl %edi, %eax
114 wrmsr
115 ret
[7df54df]116
[89344d85]117read_efer_flag:
118 movq $0xc0000080, %rcx
119 rdmsr
120 ret
[7df54df]121
[e3b9572]122# Push all general purpose registers on stack except %rbp, %rsp
123.macro push_all_gpr
124 pushq %rax
125 pushq %rbx
126 pushq %rcx
127 pushq %rdx
128 pushq %rsi
129 pushq %rdi
130 pushq %r8
131 pushq %r9
132 pushq %r10
133 pushq %r11
134 pushq %r12
135 pushq %r13
136 pushq %r14
137 pushq %r15
138.endm
139
140.macro pop_all_gpr
141 popq %r15
142 popq %r14
143 popq %r13
144 popq %r12
145 popq %r11
146 popq %r10
147 popq %r9
148 popq %r8
149 popq %rdi
150 popq %rsi
151 popq %rdx
152 popq %rcx
153 popq %rbx
154 popq %rax
155.endm
156
157## Declare interrupt handlers
158#
159# Declare interrupt handlers for n interrupt
160# vectors starting at vector i.
161#
162# The handlers setup data segment registers
163# and call trap_dispatcher().
164#
165.macro handler i n
166 pushq %rbp
167 movq %rsp,%rbp
168
169 push_all_gpr
170
171 movq $(\i),%rdi # %rdi - first parameter
172 movq %rbp, %rsi
173 addq $8, %rsi # %rsi - second parameter - original stack
[3156582]174 call trap_dispatcher # trap_dispatcher(i, stack)
[e3b9572]175
176# Test if this is interrupt with error word or not
177 mov $\i,%cl;
178 movl $1,%eax;
179 test $0xe0,%cl;
180 jnz 0f;
181 and $0x1f,%cl;
182 shl %cl,%eax;
183 and $ERROR_WORD_INTERRUPT_LIST,%eax;
184 jz 0f;
185
186
187# Return with error word
188 pop_all_gpr
189
190 popq %rbp;
191 add $8,%esp; # Skip error word
192 iretq
193
1940:
195# Return with no error word
196 pop_all_gpr
197
198 popq %rbp
199 iretq
200
201 .if (\n-\i)-1
202 handler "(\i+1)",\n
203 .endif
204.endm
205
206interrupt_handlers:
207h_start:
208 handler 0 IDT_ITEMS
209h_end:
210
211
212.data
213.global interrupt_handler_size
214
215interrupt_handler_size: .long (h_end-h_start)/IDT_ITEMS
Note: See TracBrowser for help on using the repository browser.