linprocfs - Introduce /proc/mounts
[dragonfly.git] / sys / emulation / ndis / ntoskrnl_var.h
blob98cb6d989e092a64131f94aa7685f5af07bbf2fa
1 /*
2 * Copyright (c) 2003
3 * Bill Paul <wpaul@windriver.com>. All rights reserved.
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 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by Bill Paul.
16 * 4. Neither the name of the author nor the names of any co-contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30 * THE POSSIBILITY OF SUCH DAMAGE.
32 * $FreeBSD: src/sys/compat/ndis/ntoskrnl_var.h,v 1.15 2004/04/20 02:27:38 wpaul Exp $
33 * $DragonFly: src/sys/emulation/ndis/ntoskrnl_var.h,v 1.4 2007/11/14 18:27:52 swildner Exp $
36 #ifndef _NTOSKRNL_VAR_H_
37 #define _NTOSKRNL_VAR_H_
39 /* Note: assumes x86 page size of 4K. */
40 #define PAGE_SHIFT 12
41 #define SPAN_PAGES(ptr, len) \
42 ((uint32_t)((((uintptr_t)(ptr) & (PAGE_SIZE -1)) + \
43 (len) + (PAGE_SIZE - 1)) >> PAGE_SHIFT))
44 #define PAGE_ALIGN(ptr) \
45 ((void *)((uintptr_t)(ptr) & ~(PAGE_SIZE - 1)))
46 #define BYTE_OFFSET(ptr) \
47 ((uint32_t)((uintptr_t)(ptr) & (PAGE_SIZE - 1)))
48 #define MDL_INIT(b, baseva, len) \
49 (b)->nb_next = NULL; \
50 (b)->nb_size = (uint16_t)(sizeof(struct ndis_buffer) + \
51 (sizeof(uint32_t) * SPAN_PAGES((baseva), (len)))); \
52 (b)->nb_flags = 0; \
53 (b)->nb_startva = (void *)PAGE_ALIGN((baseva)); \
54 (b)->nb_byteoffset = BYTE_OFFSET((baseva)); \
55 (b)->nb_bytecount = (uint32_t)(len);
56 #define MDL_VA(b) \
57 ((void *)((char *)((b)->nb_startva) + (b)->nb_byteoffset))
59 #define WDM_MAJOR 1
60 #define WDM_MINOR_WIN98 0x00
61 #define WDM_MINOR_WINME 0x05
62 #define WDM_MINOR_WIN2000 0x10
63 #define WDM_MINOR_WINXP 0x20
64 #define WDM_MINOR_WIN2003 0x30
66 /*-
67 * The ndis_kspin_lock type is called KSPIN_LOCK in MS-Windows.
68 * According to the Windows DDK header files, KSPIN_LOCK is defined like this:
69 * typedef ULONG_PTR KSPIN_LOCK;
71 * From basetsd.h (SDK, Feb. 2003):
72 * typedef [public] unsigned __int3264 ULONG_PTR, *PULONG_PTR;
73 * typedef unsigned __int64 ULONG_PTR, *PULONG_PTR;
74 * typedef _W64 unsigned long ULONG_PTR, *PULONG_PTR;
76 * The keyword __int3264 specifies an integral type that has the following
77 * properties:
78 * + It is 32-bit on 32-bit platforms
79 * + It is 64-bit on 64-bit platforms
80 * + It is 32-bit on the wire for backward compatibility.
81 * It gets truncated on the sending side and extended appropriately
82 * (signed or unsigned) on the receiving side.
84 * Thus register_t seems the proper mapping onto FreeBSD for spin locks.
87 typedef register_t kspin_lock;
89 struct slist_entry {
90 struct slist_entry *sl_next;
93 typedef struct slist_entry slist_entry;
95 union slist_header {
96 uint64_t slh_align;
97 struct {
98 struct slist_entry *slh_next;
99 uint16_t slh_depth;
100 uint16_t slh_seq;
101 } slh_list;
104 typedef union slist_header slist_header;
106 struct list_entry {
107 struct list_entry *nle_flink;
108 struct list_entry *nle_blink;
111 typedef struct list_entry list_entry;
113 #define INIT_LIST_HEAD(l) \
114 l->nle_flink = l->nle_blink = l
116 #define REMOVE_LIST_ENTRY(e) \
117 do { \
118 list_entry *b; \
119 list_entry *f; \
121 f = e->nle_flink; \
122 b = e->nle_blink; \
123 b->nle_flink = f; \
124 f->nle_blink = b; \
125 } while (0)
127 #define REMOVE_LIST_HEAD(l) \
128 do { \
129 list_entry *f; \
130 list_entry *e; \
132 e = l->nle_flink; \
133 f = e->nle_flink; \
134 l->nle_flink = f; \
135 f->nle_blink = l; \
136 } while (0)
138 #define REMOVE_LIST_TAIL(l) \
139 do { \
140 list_entry *b; \
141 list_entry *e; \
143 e = l->nle_blink; \
144 b = e->nle_blink; \
145 l->nle_blink = b; \
146 b->nle_flink = l; \
147 } while (0)
149 #define INSERT_LIST_TAIL(l, e) \
150 do { \
151 list_entry *b; \
153 b = l->nle_blink; \
154 e->nle_flink = l; \
155 e->nle_blink = b; \
156 b->nle_flink = e; \
157 l->nle_blink = e; \
158 } while (0)
160 #define INSERT_LIST_HEAD(l, e) \
161 do { \
162 list_entry *f; \
164 f = l->nle_flink; \
165 e->nle_flink = f; \
166 e->nle_blink = l; \
167 f->nle_blink = e; \
168 l->nle_flink = e; \
169 } while (0)
171 struct nt_dispatch_header {
172 uint8_t dh_type;
173 uint8_t dh_abs;
174 uint8_t dh_size;
175 uint8_t dh_inserted;
176 uint32_t dh_sigstate;
177 list_entry dh_waitlisthead;
180 typedef struct nt_dispatch_header nt_dispatch_header;
182 #define OTYPE_EVENT 0
183 #define OTYPE_MUTEX 1
184 #define OTYPE_THREAD 2
185 #define OTYPE_TIMER 3
187 /* Windows dispatcher levels. */
189 #define PASSIVE_LEVEL 0
190 #define LOW_LEVEL 0
191 #define APC_LEVEL 1
192 #define DISPATCH_LEVEL 2
193 #define DEVICE_LEVEL (DISPATCH_LEVEL + 1)
194 #define PROFILE_LEVEL 27
195 #define CLOCK1_LEVEL 28
196 #define CLOCK2_LEVEL 28
197 #define IPI_LEVEL 29
198 #define POWER_LEVEL 30
199 #define HIGH_LEVEL 31
201 #define SYNC_LEVEL_UP DISPATCH_LEVEL
202 #define SYNC_LEVEL_MP (IPI_LEVEL - 1)
204 #define AT_PASSIVE_LEVEL(td) \
205 ((td)->td_proc->p_flag & P_KTHREAD == FALSE)
207 #define AT_DISPATCH_LEVEL(td) \
208 (lwkt_getpri(td) == TDPRI_INT_HIGH)
210 struct nt_objref {
211 nt_dispatch_header no_dh;
212 void *no_obj;
213 TAILQ_ENTRY(nt_objref) link;
216 TAILQ_HEAD(nt_objref_head, nt_objref);
218 typedef struct nt_objref nt_objref;
220 #define EVENT_TYPE_NOTIFY 0
221 #define EVENT_TYPE_SYNC 1
224 * For ktimers, we use a struct callout pointer in a union
225 * to overlay the callout handle over the k_timerlistentry.
226 * The latter is a list_entry, which is two pointers, so
227 * there's enough space available to hide a callout handle
228 * there.
231 struct ktimer {
232 nt_dispatch_header k_header;
233 uint64_t k_duetime;
234 union {
235 list_entry k_timerlistentry;
236 struct callout *k_handle;
237 } u;
238 void *k_dpc;
239 uint32_t k_period;
242 #define k_timerlistentry u.k_timerlistentry
243 #define k_handle u.k_handle
245 typedef struct ktimer ktimer;
247 struct nt_kevent {
248 nt_dispatch_header k_header;
251 typedef struct nt_kevent nt_kevent;
253 /* Kernel defered procedure call (i.e. timer callback) */
255 struct kdpc;
256 typedef __stdcall void (*kdpc_func)(struct kdpc *, void *, void *, void *);
258 struct kdpc {
259 uint16_t k_type;
260 uint8_t k_num;
261 uint8_t k_importance;
262 list_entry k_dpclistentry;
263 kdpc_func k_deferedfunc;
264 void *k_deferredctx;
265 void *k_sysarg1;
266 void *k_sysarg2;
267 register_t k_lock;
270 typedef struct kdpc kdpc;
273 * Note: the acquisition count is BSD-specific. The Microsoft
274 * documentation says that mutexes can be acquired recursively
275 * by a given thread, but that you must release the mutex as
276 * many times as you acquired it before it will be set to the
277 * signalled state (i.e. before any other threads waiting on
278 * the object will be woken up). However the Windows KMUTANT
279 * structure has no field for keeping track of the number of
280 * acquisitions, so we need to add one ourselves. As long as
281 * driver code treats the mutex as opaque, we should be ok.
283 struct kmutant {
284 nt_dispatch_header km_header;
285 union {
286 list_entry km_listentry;
287 uint32_t km_acquirecnt;
288 } u;
289 void *km_ownerthread;
290 uint8_t km_abandoned;
291 uint8_t km_apcdisable;
294 #define km_listentry u.km_listentry
295 #define km_acquirecnt u.km_acquirecnt
297 typedef struct kmutant kmutant;
299 #define LOOKASIDE_DEPTH 256
301 struct general_lookaside {
302 slist_header gl_listhead;
303 uint16_t gl_depth;
304 uint16_t gl_maxdepth;
305 uint32_t gl_totallocs;
306 union {
307 uint32_t gl_allocmisses;
308 uint32_t gl_allochits;
309 } u_a;
310 uint32_t gl_totalfrees;
311 union {
312 uint32_t gl_freemisses;
313 uint32_t gl_freehits;
314 } u_m;
315 uint32_t gl_type;
316 uint32_t gl_tag;
317 uint32_t gl_size;
318 void *gl_allocfunc;
319 void *gl_freefunc;
320 list_entry gl_listent;
321 uint32_t gl_lasttotallocs;
322 union {
323 uint32_t gl_lastallocmisses;
324 uint32_t gl_lastallochits;
325 } u_l;
326 uint32_t gl_rsvd[2];
329 typedef struct general_lookaside general_lookaside;
331 struct npaged_lookaside_list {
332 general_lookaside nll_l;
333 kspin_lock nll_obsoletelock;
336 typedef struct npaged_lookaside_list npaged_lookaside_list;
337 typedef struct npaged_lookaside_list paged_lookaside_list;
339 typedef void * (*lookaside_alloc_func)(uint32_t, size_t, uint32_t);
340 typedef void (*lookaside_free_func)(void *);
342 struct irp;
344 struct kdevice_qentry {
345 list_entry kqe_devlistent;
346 uint32_t kqe_sortkey;
347 uint8_t kqe_inserted;
350 typedef struct kdevice_qentry kdevice_qentry;
352 struct kdevice_queue {
353 uint16_t kq_type;
354 uint16_t kq_size;
355 list_entry kq_devlisthead;
356 kspin_lock kq_lock;
357 uint8_t kq_busy;
360 typedef struct kdevice_queue kdevice_queue;
362 struct wait_ctx_block {
363 kdevice_qentry wcb_waitqueue;
364 void *wcb_devfunc;
365 void *wcb_devctx;
366 uint32_t wcb_mapregcnt;
367 void *wcb_devobj;
368 void *wcb_curirp;
369 void *wcb_bufchaindpc;
372 typedef struct wait_ctx_block wait_ctx_block;
374 struct wait_block {
375 list_entry wb_waitlist;
376 void *wb_kthread;
377 nt_dispatch_header *wb_object;
378 struct wait_block *wb_next;
379 uint16_t wb_waitkey;
380 uint16_t wb_waittype;
383 typedef struct wait_block wait_block;
385 #define THREAD_WAIT_OBJECTS 3
386 #define MAX_WAIT_OBJECTS 64
388 #define WAITTYPE_ALL 0
389 #define WAITTYPE_ANY 1
391 struct thread_context {
392 void *tc_thrctx;
393 void *tc_thrfunc;
396 typedef struct thread_context thread_context;
398 struct device_object {
399 uint16_t do_type;
400 uint16_t do_size;
401 uint32_t do_refcnt;
402 struct device_object *do_drvobj;
403 struct device_object *do_nextdev;
404 struct device_object *do_attacheddev;
405 struct irp *do_currirp;
406 void *do_iotimer;
407 uint32_t do_flags;
408 uint32_t do_characteristics;
409 void *do_vpb;
410 void *do_devext;
411 uint8_t do_stacksize;
412 union {
413 list_entry do_listent;
414 wait_ctx_block do_wcb;
415 } queue;
416 uint32_t do_alignreq;
417 kdevice_queue do_devqueue;
418 struct kdpc do_dpc;
419 uint32_t do_activethreads;
420 void *do_securitydesc;
421 struct nt_kevent do_devlock;
422 uint16_t do_sectorsz;
423 uint16_t do_spare1;
424 void *do_devobj_ext;
425 void *do_rsvd;
428 typedef struct device_object device_object;
430 struct irp {
431 uint32_t i_dummy;
434 typedef struct irp irp;
436 typedef uint32_t (*driver_dispatch)(device_object *, irp *);
438 #define DEVPROP_DEVICE_DESCRIPTION 0x00000000
439 #define DEVPROP_HARDWARE_ID 0x00000001
440 #define DEVPROP_COMPATIBLE_IDS 0x00000002
441 #define DEVPROP_BOOTCONF 0x00000003
442 #define DEVPROP_BOOTCONF_TRANSLATED 0x00000004
443 #define DEVPROP_CLASS_NAME 0x00000005
444 #define DEVPROP_CLASS_GUID 0x00000006
445 #define DEVPROP_DRIVER_KEYNAME 0x00000007
446 #define DEVPROP_MANUFACTURER 0x00000008
447 #define DEVPROP_FRIENDLYNAME 0x00000009
448 #define DEVPROP_LOCATION_INFO 0x0000000A
449 #define DEVPROP_PHYSDEV_NAME 0x0000000B
450 #define DEVPROP_BUSTYPE_GUID 0x0000000C
451 #define DEVPROP_LEGACY_BUSTYPE 0x0000000D
452 #define DEVPROP_BUS_NUMBER 0x0000000E
453 #define DEVPROP_ENUMERATOR_NAME 0x0000000F
454 #define DEVPROP_ADDRESS 0x00000010
455 #define DEVPROP_UINUMBER 0x00000011
456 #define DEVPROP_INSTALL_STATE 0x00000012
457 #define DEVPROP_REMOVAL_POLICY 0x00000013
459 #define STATUS_SUCCESS 0x00000000
460 #define STATUS_USER_APC 0x000000C0
461 #define STATUS_KERNEL_APC 0x00000100
462 #define STATUS_ALERTED 0x00000101
463 #define STATUS_TIMEOUT 0x00000102
464 #define STATUS_INVALID_PARAMETER 0xC000000D
465 #define STATUS_INVALID_DEVICE_REQUEST 0xC0000010
466 #define STATUS_BUFFER_TOO_SMALL 0xC0000023
467 #define STATUS_MUTANT_NOT_OWNED 0xC0000046
468 #define STATUS_INVALID_PARAMETER_2 0xC00000F0
470 #define STATUS_WAIT_0 0x00000000
473 * FreeBSD's kernel stack is 2 pages in size by default. The
474 * Windows stack is larger, so we need to give our threads more
475 * stack pages. 4 should be enough, we use 8 just to extra safe.
477 #define NDIS_KSTACK_PAGES 8
479 extern image_patch_table ntoskrnl_functbl[];
481 __BEGIN_DECLS
482 extern int ntoskrnl_libinit(void);
483 extern int ntoskrnl_libfini(void);
484 __stdcall extern void ntoskrnl_init_dpc(kdpc *, void *, void *);
485 __stdcall extern uint8_t ntoskrnl_queue_dpc(kdpc *, void *, void *);
486 __stdcall extern uint8_t ntoskrnl_dequeue_dpc(kdpc *);
487 __stdcall extern void ntoskrnl_init_timer(ktimer *);
488 __stdcall extern void ntoskrnl_init_timer_ex(ktimer *, uint32_t);
489 __stdcall extern uint8_t ntoskrnl_set_timer(ktimer *, int64_t, kdpc *);
490 __stdcall extern uint8_t ntoskrnl_set_timer_ex(ktimer *, int64_t,
491 uint32_t, kdpc *);
492 __stdcall extern uint8_t ntoskrnl_cancel_timer(ktimer *);
493 __stdcall extern uint8_t ntoskrnl_read_timer(ktimer *);
494 __stdcall extern uint32_t ntoskrnl_waitforobj(nt_dispatch_header *, uint32_t,
495 uint32_t, uint8_t, int64_t *);
496 __stdcall extern void ntoskrnl_init_event(nt_kevent *, uint32_t, uint8_t);
497 __stdcall extern void ntoskrnl_clear_event(nt_kevent *);
498 __stdcall extern uint32_t ntoskrnl_read_event(nt_kevent *);
499 __stdcall extern uint32_t ntoskrnl_set_event(nt_kevent *, uint32_t, uint8_t);
500 __stdcall extern uint32_t ntoskrnl_reset_event(nt_kevent *);
501 __stdcall __regcall void ntoskrnl_lock_dpc(REGARGS1(kspin_lock *lock));
502 __stdcall __regcall void ntoskrnl_unlock_dpc(REGARGS1(kspin_lock *lock));
505 * On the Windows x86 arch, KeAcquireSpinLock() and KeReleaseSpinLock()
506 * routines live in the HAL. We try to imitate this behavior.
508 #ifdef __i386__
509 #define ntoskrnl_acquire_spinlock(a, b) \
510 *(b) = FASTCALL(hal_lock, a, 0)
511 #define ntoskrnl_release_spinlock(a, b) \
512 FASTCALL(hal_unlock, a, b)
513 #endif /* __i386__ */
514 __END_DECLS
516 #endif /* _NTOSKRNL_VAR_H_ */