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 */
39 #include "align.h" /* PTR_ALIGN... */
43 int arch_os_thread_init(struct thread
*thread
)
46 void *top_exception_frame
;
48 void *cur_stack_start
;
49 MEMORY_BASIC_INFORMATION stack_memory
;
51 asm volatile ("movl %%fs:0,%0": "=r" (top_exception_frame
));
52 asm volatile ("movl %%fs:4,%0": "=r" (cur_stack_end
));
54 /* Can't pull stack start from fs:4 or fs:8 or whatever,
55 * because that's only what currently has memory behind
56 * it from being used, so do a quick VirtualQuery() and
57 * grab the AllocationBase. -AB 2006/11/25
60 if (!VirtualQuery(&stack_memory
, &stack_memory
, sizeof(stack_memory
))) {
61 fprintf(stderr
, "VirtualQuery: 0x%lx.\n", GetLastError());
62 lose("Could not query stack memory information.");
65 cur_stack_start
= stack_memory
.AllocationBase
66 /* Kludge: Elide SBCL's guard page from the range. (The
67 * real solution is to not establish SBCL's guard page in
68 * the first place. The trick will be to find a good time
69 * at which to re-enable the Windows guard page when
70 * returning from it though.) */
73 /* We use top_exception_frame rather than cur_stack_end to
74 * elide the last few (boring) stack entries at the bottom of
77 thread
->control_stack_start
= cur_stack_start
;
78 thread
->control_stack_end
= top_exception_frame
;
80 #ifndef LISP_FEATURE_SB_THREAD
82 * Theoretically, threaded SBCL binds directly against
83 * the thread structure for these values. We don't do
84 * threads yet, but we'll probably do the same. We do
85 * need to reset these, though, because they were
86 * initialized based on the wrong stack space.
88 SetSymbolValue(CONTROL_STACK_START
,(lispobj
)thread
->control_stack_start
,thread
);
89 SetSymbolValue(CONTROL_STACK_END
,(lispobj
)thread
->control_stack_end
,thread
);
93 #ifdef LISP_FEATURE_SB_THREAD
94 TlsSetValue(OUR_TLS_INDEX
,thread
);
99 /* free any arch/os-specific resources used by thread, which is now
100 * defunct. Not called on live threads
103 int arch_os_thread_cleanup(struct thread
*thread
) {
107 #if defined(LISP_FEATURE_SB_THREAD)
108 sigset_t
*os_context_sigmask_addr(os_context_t
*context
)
110 return &context
->sigmask
;
114 os_context_register_t
*
115 os_context_register_addr(os_context_t
*context
, int offset
)
117 static const size_t offsets
[8] = {
118 offsetof(CONTEXT
,Eax
),
119 offsetof(CONTEXT
,Ecx
),
120 offsetof(CONTEXT
,Edx
),
121 offsetof(CONTEXT
,Ebx
),
122 offsetof(CONTEXT
,Esp
),
123 offsetof(CONTEXT
,Ebp
),
124 offsetof(CONTEXT
,Esi
),
125 offsetof(CONTEXT
,Edi
),
128 (offset
>= 0 && offset
< 16) ?
129 ((void*)(context
->win32_context
)) + offsets
[offset
>>1] : 0;
132 os_context_register_t
*
133 os_context_pc_addr(os_context_t
*context
)
135 return (void*)&context
->win32_context
->Eip
; /* REG_EIP */
138 os_context_register_t
*
139 os_context_sp_addr(os_context_t
*context
)
141 return (void*)&context
->win32_context
->Esp
; /* REG_UESP */
144 os_context_register_t
*
145 os_context_fp_addr(os_context_t
*context
)
147 return (void*)&context
->win32_context
->Ebp
; /* REG_EBP */
151 os_context_fp_control(os_context_t
*context
)
153 return ((((context
->win32_context
->FloatSave
.ControlWord
) & 0xffff) ^ 0x3f) |
154 (((context
->win32_context
->FloatSave
.StatusWord
) & 0xffff) << 16));
158 os_restore_fp_control(os_context_t
*context
)
160 asm ("fldcw %0" : : "m" (context
->win32_context
->FloatSave
.ControlWord
));
163 os_context_register_t
*
164 os_context_float_register_addr(os_context_t
*context
, int offset
)
166 return (os_context_register_t
*)&context
->win32_context
->FloatSave
.RegisterArea
[offset
];
169 os_flush_icache(os_vm_address_t address
, os_vm_size_t length
)