source: mainline/arch/amd64/src/asm_utils.S@ 6d9c49a

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

Added kernel IPC functionality.

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