2 * The x86 Win32 incarnation of arch-dependent OS-dependent routines.
3 * See also "win32-os.c".
7 * This software is part of the SBCL system. See the README file for
10 * This software is derived from the CMU CL system, which was
11 * written at Carnegie Mellon University and released into the
12 * public domain. The software is in the public domain and is
13 * provided with absolutely no warranty. See the COPYING and CREDITS
14 * files for more information.
19 #include <sys/param.h>
21 #include <sys/types.h>
28 #include "interrupt.h"
33 #include <sys/types.h>
38 #include "thread.h" /* dynamic_values_bytes */
42 size_t os_vm_page_size;
44 int arch_os_thread_init(struct thread *thread)
47 void *top_exception_frame;
49 void *cur_stack_start;
50 MEMORY_BASIC_INFORMATION stack_memory;
52 asm volatile ("mov %%gs:0,%0": "=r" (top_exception_frame));
53 asm volatile ("mov %%gs:8,%0": "=r" (cur_stack_end));
55 /* Can't pull stack start from fs:4 or fs:8 or whatever,
56 * because that's only what currently has memory behind
57 * it from being used, so do a quick VirtualQuery() and
58 * grab the AllocationBase. -AB 2006/11/25
61 if (!VirtualQuery(&stack_memory, &stack_memory, sizeof(stack_memory))) {
62 fprintf(stderr, "VirtualQuery: 0x%lx.\n", GetLastError());
63 lose("Could not query stack memory information.");
66 cur_stack_start = stack_memory.AllocationBase
67 /* OS provides its own guard page at the stack start,
68 and we have ours. Do you really want to see how they interact? */
71 /* We use top_exception_frame rather than cur_stack_end to
72 * elide the last few (boring) stack entries at the bottom of
75 thread->control_stack_start = cur_stack_start;
76 thread->control_stack_end = cur_stack_end;
78 #ifndef LISP_FEATURE_SB_THREAD
80 * Theoretically, threaded SBCL binds directly against
81 * the thread structure for these values. We don't do
82 * threads yet, but we'll probably do the same. We do
83 * need to reset these, though, because they were
84 * initialized based on the wrong stack space.
86 SetSymbolValue(CONTROL_STACK_START,(lispobj)thread->control_stack_start,thread);
87 SetSymbolValue(CONTROL_STACK_END,(lispobj)thread->control_stack_end,thread);
91 #ifdef LISP_FEATURE_SB_THREAD
92 pthread_setspecific(specials,thread);
97 /* free any arch/os-specific resources used by thread, which is now
98 * defunct. Not called on live threads
101 int arch_os_thread_cleanup(struct thread *thread) {
105 #if defined(LISP_FEATURE_SB_THREAD)
106 sigset_t *os_context_sigmask_addr(os_context_t *context)
108 return &context->sigmask;
112 os_context_register_t *
113 os_context_register_addr(os_context_t *context, int offset)
115 static const size_t offsets[16] = {
116 offsetof(CONTEXT,Rax),
117 offsetof(CONTEXT,Rcx),
118 offsetof(CONTEXT,Rdx),
119 offsetof(CONTEXT,Rbx),
120 offsetof(CONTEXT,Rsp),
121 offsetof(CONTEXT,Rbp),
122 offsetof(CONTEXT,Rsi),
123 offsetof(CONTEXT,Rdi),
124 offsetof(CONTEXT,R8),
125 offsetof(CONTEXT,R9),
126 offsetof(CONTEXT,R10),
127 offsetof(CONTEXT,R11),
128 offsetof(CONTEXT,R12),
129 offsetof(CONTEXT,R13),
130 offsetof(CONTEXT,R14),
131 offsetof(CONTEXT,R15),
134 (offset >= 0 && offset < 32) ?
135 ((void*)(context->win32_context)) + offsets[offset>>1] : 0;
138 os_context_register_t *
139 os_context_pc_addr(os_context_t *context)
141 return (void*)&context->win32_context->Rip; /* REG_EIP */
144 os_context_register_t *
145 os_context_sp_addr(os_context_t *context)
147 return (void*)&context->win32_context->Rsp; /* REG_UESP */
150 os_context_register_t *
151 os_context_fp_addr(os_context_t *context)
153 return (void*)&context->win32_context->Rbp; /* REG_EBP */
157 os_context_fp_control(os_context_t *context)
159 return ((((context->win32_context->FloatSave.ControlWord) & 0xffff) ^ 0x3f) |
160 (((context->win32_context->FloatSave.StatusWord) & 0xffff) << 16));
164 os_restore_fp_control(os_context_t *context)
166 asm ("fldcw %0" : : "m" (context->win32_context->FloatSave.ControlWord));
170 os_flush_icache(os_vm_address_t address, os_vm_size_t length)