summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwpaul <wpaul@FreeBSD.org>2003-12-12 22:35:13 +0000
committerwpaul <wpaul@FreeBSD.org>2003-12-12 22:35:13 +0000
commit27ada5499823ed0f050b3303fd142aa9877e464c (patch)
treebadbfcef48d28701f70f9f6b266eb56f8e83d6ee
parent84ea3f4d2d8a60b69579809d6d8e580bd294c5f0 (diff)
downloadFreeBSD-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.c17
-rw-r--r--sys/compat/ndis/subr_ntoskrnl.c62
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
OpenPOWER on IntegriCloud