diff options
author | wpaul <wpaul@FreeBSD.org> | 2003-12-12 22:35:13 +0000 |
---|---|---|
committer | wpaul <wpaul@FreeBSD.org> | 2003-12-12 22:35:13 +0000 |
commit | 27ada5499823ed0f050b3303fd142aa9877e464c (patch) | |
tree | badbfcef48d28701f70f9f6b266eb56f8e83d6ee | |
parent | 84ea3f4d2d8a60b69579809d6d8e580bd294c5f0 (diff) | |
download | FreeBSD-src-27ada5499823ed0f050b3303fd142aa9877e464c.zip FreeBSD-src-27ada5499823ed0f050b3303fd142aa9877e464c.tar.gz |
Implement some more NDIS and ntoskrnl API calls:
subr_ndis.c: NdisGetCurrentSystemTime() which, according to the
Microsoft documentation returns "the number of 100 nanosecond
intervals since January 1, 1601." I have no idea what's so special
about that epoch or why they chose 100 nanosecond ticks. I don't
know the proper offset to convert nanotime() from the UNIX epoch
to January 1, 1601, so for now I'm just doing the unit convertion
to 100s of nanoseconds.
subr_ntoskrnl.c: memcpy(), memset(), ExInterlockedPopEntrySList(),
ExInterlockedPushEntrySList().
The latter two are different from InterlockedPopEntrySList()
and InterlockedPushEntrySList() in that they accept a spinlock to
hold while executing, whereas the non-Ex routines use a lock
internal to ntoskrnl. I also modified ExInitializePagedLookasideList()
and ExInitializeNPagedLookasideList() to initialize mutex locks
within the lookaside structures. It seems that in NDIS 5.0,
the lookaside allocate/free routines ExInterlockedPopEntrySList()
and ExInterlockedPushEntrySList(), which require the use of the
per-lookaside spinlock, whereas in NDIS 5.1, the per-lookaside
spinlock is deprecated. We need to support both cases.
Note that I appear to be doing something wrong with
ExInterlockedPopEntrySList() and ExInterlockedPushEntrySList():
they don't appear to obtain proper pointers to their arguments,
so I'm probably doing something wrong in terms of their calling
convention (they're declared to be FASTCALL in Widnows, and I'm
not sure what that means for gcc). It happens that in my stub
lookaside implementation, they don't need to do any work anyway,
so for now I've hacked them to always return NULL, which avoids
corrupting the stack. I need to do this right though.
-rw-r--r-- | sys/compat/ndis/subr_ndis.c | 17 | ||||
-rw-r--r-- | sys/compat/ndis/subr_ntoskrnl.c | 62 |
2 files changed, 79 insertions, 0 deletions
diff --git a/sys/compat/ndis/subr_ndis.c b/sys/compat/ndis/subr_ndis.c index 41a9442..d01866b 100644 --- a/sys/compat/ndis/subr_ndis.c +++ b/sys/compat/ndis/subr_ndis.c @@ -61,6 +61,7 @@ __FBSDID("$FreeBSD$"); #include <sys/mutex.h> #include <sys/socket.h> #include <sys/sysctl.h> +#include <sys/timespec.h> #include <net/if.h> #include <net/if_arp.h> @@ -207,6 +208,7 @@ __stdcall static ndis_list_entry *ndis_insert_tail(ndis_list_entry *, ndis_list_entry *, ndis_spin_lock *); __stdcall static uint8_t ndis_sync_with_intr(ndis_miniport_interrupt *, void *, void *); +__stdcall static void ndis_time(uint64_t *); __stdcall static void dummy(void); @@ -1839,6 +1841,20 @@ ndis_sync_with_intr(intr, syncfunc, syncctx) return(sync(syncctx)); } +/* + * Return the number of 100 nanosecond intervals since + * January 1, 1601. (?!?!) + */ +__stdcall static void +ndis_time(tval) + uint64_t *tval; +{ + struct timespec ts; + nanotime(&ts); + *tval = (ts.tv_nsec / 100) + (ts.tv_nsec * 10000000); + return; +} + __stdcall static void dummy() { @@ -1847,6 +1863,7 @@ dummy() } image_patch_table ndis_functbl[] = { + { "NdisGetCurrentSystemTime", (FUNC)ndis_time }, { "NdisMSynchronizeWithInterrupt", (FUNC)ndis_sync_with_intr }, { "NdisMAllocateSharedMemoryAsync", (FUNC)ndis_alloc_sharedmem_async }, { "NdisInterlockedInsertHeadList", (FUNC)ndis_insert_head }, diff --git a/sys/compat/ndis/subr_ntoskrnl.c b/sys/compat/ndis/subr_ntoskrnl.c index 04399c7..3a1d125 100644 --- a/sys/compat/ndis/subr_ntoskrnl.c +++ b/sys/compat/ndis/subr_ntoskrnl.c @@ -97,6 +97,9 @@ __stdcall static void ntoskrnl_init_nplookaside(npaged_lookaside_list *, __stdcall static void ntoskrnl_delete_nplookaside(npaged_lookaside_list *); static slist_entry *ntoskrnl_push_slist(slist_entry *, slist_entry *); static slist_entry *ntoskrnl_pop_slist(slist_entry *); +static slist_entry *ntoskrnl_push_slist_ex(slist_entry *, + slist_entry *, kspin_lock *); +static slist_entry *ntoskrnl_pop_slist_ex(slist_entry *, kspin_lock *); __stdcall static void dummy(void); static struct mtx ntoskrnl_interlock; @@ -352,6 +355,8 @@ ntoskrnl_init_lookaside(lookaside, allocfunc, freefunc, uint32_t tag; uint16_t depth; { + struct mtx *mtx; + lookaside->nll_l.gl_size = size; lookaside->nll_l.gl_tag = tag; if (allocfunc == NULL) @@ -364,6 +369,13 @@ ntoskrnl_init_lookaside(lookaside, allocfunc, freefunc, else lookaside->nll_l.gl_freefunc = freefunc; + mtx = malloc(sizeof(struct mtx), M_DEVBUF, M_NOWAIT|M_ZERO); + if (mtx == NULL) + return; + mtx_init(mtx, "ndisnplook", "ndis lookaside lock", + MTX_DEF | MTX_RECURSE | MTX_DUPOK); + lookaside->nll_obsoletelock = (kspin_lock)mtx; + return; } @@ -371,6 +383,8 @@ __stdcall static void ntoskrnl_delete_lookaside(lookaside) paged_lookaside_list *lookaside; { + mtx_destroy((struct mtx *)lookaside->nll_obsoletelock); + free((struct mtx *)lookaside->nll_obsoletelock, M_DEVBUF); return; } @@ -385,6 +399,8 @@ ntoskrnl_init_nplookaside(lookaside, allocfunc, freefunc, uint32_t tag; uint16_t depth; { + struct mtx *mtx; + lookaside->nll_l.gl_size = size; lookaside->nll_l.gl_tag = tag; if (allocfunc == NULL) @@ -397,6 +413,13 @@ ntoskrnl_init_nplookaside(lookaside, allocfunc, freefunc, else lookaside->nll_l.gl_freefunc = freefunc; + mtx = malloc(sizeof(struct mtx), M_DEVBUF, M_NOWAIT|M_ZERO); + if (mtx == NULL) + return; + mtx_init(mtx, "ndisnplook", "ndis lookaside lock", + MTX_DEF | MTX_RECURSE | MTX_DUPOK); + lookaside->nll_obsoletelock = (kspin_lock)mtx; + return; } @@ -404,6 +427,8 @@ __stdcall static void ntoskrnl_delete_nplookaside(lookaside) npaged_lookaside_list *lookaside; { + mtx_destroy((struct mtx *)lookaside->nll_obsoletelock); + free((struct mtx *)lookaside->nll_obsoletelock, M_DEVBUF); return; } @@ -439,6 +464,38 @@ ntoskrnl_pop_slist(head) return(first); } +__stdcall static slist_entry * +ntoskrnl_push_slist_ex(head, entry, lock) + slist_entry *head; + slist_entry *entry; + kspin_lock *lock; +{ + slist_entry *oldhead; + return(NULL); + mtx_lock((struct mtx *)*lock); + oldhead = head->sl_next; + entry->sl_next = head->sl_next; + head->sl_next = entry; + mtx_unlock((struct mtx *)*lock); + return(oldhead); +} + +__stdcall static slist_entry * +ntoskrnl_pop_slist_ex(head, lock) + slist_entry *head; + kspin_lock *lock; +{ + slist_entry *first; + + return(NULL); + mtx_lock((struct mtx *)*lock); + first = head->sl_next; + if (first != NULL) + head->sl_next = first->sl_next; + mtx_unlock((struct mtx *)*lock); + return(first); +} + __stdcall static void dummy() { @@ -455,6 +512,9 @@ image_patch_table ntoskrnl_functbl[] = { { "strcmp", (FUNC)strcmp }, { "strncpy", (FUNC)strncpy }, { "strcpy", (FUNC)strcpy }, + { "strlen", (FUNC)strlen }, + { "memcpy", (FUNC)memcpy }, + { "memset", (FUNC)memset }, { "IofCallDriver", (FUNC)ntoskrnl_iofcalldriver }, { "IoBuildSynchronousFsdRequest", (FUNC)ntoskrnl_iobuildsynchfsdreq }, { "KeWaitForSingleObject", (FUNC)ntoskrnl_waitforobj }, @@ -481,6 +541,8 @@ image_patch_table ntoskrnl_functbl[] = { { "ExDeleteNPagedLookasideList", (FUNC)ntoskrnl_delete_nplookaside }, { "InterlockedPopEntrySList", (FUNC)ntoskrnl_pop_slist }, { "InterlockedPushEntrySList", (FUNC)ntoskrnl_push_slist }, + { "ExInterlockedPopEntrySList", (FUNC)ntoskrnl_pop_slist_ex }, + { "ExInterlockedPushEntrySList",(FUNC)ntoskrnl_push_slist_ex }, /* * This last entry is a catch-all for any function we haven't |