summaryrefslogtreecommitdiffstats
path: root/sys/compat/ndis
diff options
context:
space:
mode:
authorbschmidt <bschmidt@FreeBSD.org>2010-11-22 20:46:38 +0000
committerbschmidt <bschmidt@FreeBSD.org>2010-11-22 20:46:38 +0000
commit82896fc74f46ba5f27ba584ae8f368f7d6da8d12 (patch)
tree53d85df25de638ac8b8d39a702b9e878213ca660 /sys/compat/ndis
parent06a992a873410e4809abaea04c0f44bd903088ff (diff)
downloadFreeBSD-src-82896fc74f46ba5f27ba584ae8f368f7d6da8d12.zip
FreeBSD-src-82896fc74f46ba5f27ba584ae8f368f7d6da8d12.tar.gz
Resurrect amd64 support.
- Many drivers on amd64 are picking system uptime, interrupt time and ticks via global data structure instead of calling functions for performance reasons. For now just patch such address so driver will not trigger page fault when trying to access such data. In future, additional callout may be added to update data in periodic intervals. - On amd64 we need to allocate "shadow space" on stack before calling any function. Submitted by: Paul B Mahol <onemda at gmail.com>
Diffstat (limited to 'sys/compat/ndis')
-rw-r--r--sys/compat/ndis/kern_windrv.c22
-rw-r--r--sys/compat/ndis/ntoskrnl_var.h64
-rw-r--r--sys/compat/ndis/subr_ntoskrnl.c1
-rw-r--r--sys/compat/ndis/winx64_wrap.S16
4 files changed, 95 insertions, 8 deletions
diff --git a/sys/compat/ndis/kern_windrv.c b/sys/compat/ndis/kern_windrv.c
index f231863..5572988 100644
--- a/sys/compat/ndis/kern_windrv.c
+++ b/sys/compat/ndis/kern_windrv.c
@@ -311,6 +311,24 @@ windrv_unload(mod, img, len)
#define WINDRV_LOADED htonl(0x42534F44)
+#ifdef __amd64__
+static void
+patch_user_shared_data_address(vm_offset_t img, size_t len)
+{
+ unsigned long i, n, max_addr, *addr;
+
+ n = len - sizeof(unsigned long);
+ max_addr = KI_USER_SHARED_DATA + sizeof(kuser_shared_data);
+ for (i = 0; i < n; i++) {
+ addr = (unsigned long *)(img + i);
+ if (*addr >= KI_USER_SHARED_DATA && *addr < max_addr) {
+ *addr -= KI_USER_SHARED_DATA;
+ *addr += (unsigned long)&kuser_shared_data;
+ }
+ }
+}
+#endif
+
/*
* Loader routine for actual Windows driver modules, ultimately
* calls the driver's DriverEntry() routine.
@@ -363,6 +381,10 @@ windrv_load(mod, img, len, bustype, devlist, regvals)
return (ENOEXEC);
}
+#ifdef __amd64__
+ patch_user_shared_data_address(img, len);
+#endif
+
/* Dynamically link USBD.SYS -- optional */
if (pe_get_import_descriptor(img, &imp_desc, "USBD") == 0) {
if (pe_patch_imports(img, "USBD", usbd_functbl))
diff --git a/sys/compat/ndis/ntoskrnl_var.h b/sys/compat/ndis/ntoskrnl_var.h
index ebe3f5d..769f93c 100644
--- a/sys/compat/ndis/ntoskrnl_var.h
+++ b/sys/compat/ndis/ntoskrnl_var.h
@@ -605,6 +605,65 @@ struct kinterrupt {
typedef struct kinterrupt kinterrupt;
+struct ksystem_time {
+ uint32_t low_part;
+ int32_t high1_time;
+ int32_t high2_time;
+};
+
+enum nt_product_type {
+ NT_PRODUCT_WIN_NT = 1,
+ NT_PRODUCT_LAN_MAN_NT,
+ NT_PRODUCT_SERVER
+};
+
+enum alt_arch_type {
+ STANDARD_DESIGN,
+ NEC98x86,
+ END_ALTERNATIVES
+};
+
+struct kuser_shared_data {
+ uint32_t tick_count;
+ uint32_t tick_count_multiplier;
+ volatile struct ksystem_time interrupt_time;
+ volatile struct ksystem_time system_time;
+ volatile struct ksystem_time time_zone_bias;
+ uint16_t image_number_low;
+ uint16_t image_number_high;
+ int16_t nt_system_root[260];
+ uint32_t max_stack_trace_depth;
+ uint32_t crypto_exponent;
+ uint32_t time_zone_id;
+ uint32_t large_page_min;
+ uint32_t reserved2[7];
+ enum nt_product_type nt_product_type;
+ uint8_t product_type_is_valid;
+ uint32_t nt_major_version;
+ uint32_t nt_minor_version;
+ uint8_t processor_features[64];
+ uint32_t reserved1;
+ uint32_t reserved3;
+ volatile uint32_t time_slip;
+ enum alt_arch_type alt_arch_type;
+ int64_t system_expiration_date;
+ uint32_t suite_mask;
+ uint8_t kdbg_enabled;
+ volatile uint32_t active_console;
+ volatile uint32_t dismount_count;
+ uint32_t com_plus_package;
+ uint32_t last_system_rit_event_tick_count;
+ uint32_t num_phys_pages;
+ uint8_t safe_boot_mode;
+ uint32_t trace_log;
+ uint64_t fill0;
+ uint64_t sys_call[4];
+ union {
+ volatile struct ksystem_time tick_count;
+ volatile uint64_t tick_count_quad;
+ } tick;
+};
+
/*
* In Windows, there are Physical Device Objects (PDOs) and
* Functional Device Objects (FDOs). Physical Device Objects are
@@ -1324,6 +1383,9 @@ struct drvdb_ent {
};
extern image_patch_table ntoskrnl_functbl[];
+#ifdef __amd64__
+extern struct kuser_shared_data kuser_shared_data;
+#endif
typedef void (*funcptr)(void);
typedef int (*matchfuncptr)(interface_type, void *, void *);
@@ -1438,6 +1500,7 @@ extern void IoQueueWorkItem(io_workitem *, io_workitem_func,
* routines live in the HAL. We try to imitate this behavior.
*/
#ifdef __i386__
+#define KI_USER_SHARED_DATA 0xffdf0000
#define KeAcquireSpinLock(a, b) *(b) = KfAcquireSpinLock(a)
#define KeReleaseSpinLock(a, b) KfReleaseSpinLock(a, b)
#define KeRaiseIrql(a, b) *(b) = KfRaiseIrql(a)
@@ -1447,6 +1510,7 @@ extern void IoQueueWorkItem(io_workitem *, io_workitem_func,
#endif /* __i386__ */
#ifdef __amd64__
+#define KI_USER_SHARED_DATA 0xfffff78000000000UL
#define KeAcquireSpinLock(a, b) *(b) = KfAcquireSpinLock(a)
#define KeReleaseSpinLock(a, b) KfReleaseSpinLock(a, b)
diff --git a/sys/compat/ndis/subr_ntoskrnl.c b/sys/compat/ndis/subr_ntoskrnl.c
index 17ff3e5..80b1d98 100644
--- a/sys/compat/ndis/subr_ntoskrnl.c
+++ b/sys/compat/ndis/subr_ntoskrnl.c
@@ -121,6 +121,7 @@ typedef struct callout_entry callout_entry;
static struct list_entry ntoskrnl_calllist;
static struct mtx ntoskrnl_calllock;
+struct kuser_shared_data kuser_shared_data;
static struct list_entry ntoskrnl_intlist;
static kspin_lock ntoskrnl_intlock;
diff --git a/sys/compat/ndis/winx64_wrap.S b/sys/compat/ndis/winx64_wrap.S
index c44fe05..3e5d994 100644
--- a/sys/compat/ndis/winx64_wrap.S
+++ b/sys/compat/ndis/winx64_wrap.S
@@ -125,26 +125,26 @@ x86_64_wrap_end:
*/
ENTRY(x86_64_call1)
- subq $8,%rsp
+ subq $40,%rsp
mov %rsi,%rcx
call *%rdi
- addq $8,%rsp
+ addq $40,%rsp
ret
ENTRY(x86_64_call2)
- subq $24,%rsp
+ subq $40,%rsp
mov %rsi,%rcx
/* %rdx is already correct */
call *%rdi
- addq $24,%rsp
+ addq $40,%rsp
ret
ENTRY(x86_64_call3)
- subq $24,%rsp
+ subq $40,%rsp
mov %rcx,%r8
mov %rsi,%rcx
call *%rdi
- addq $24,%rsp
+ addq $40,%rsp
ret
ENTRY(x86_64_call4)
@@ -157,13 +157,13 @@ ENTRY(x86_64_call4)
ret
ENTRY(x86_64_call5)
- subq $40,%rsp
+ subq $48,%rsp
mov %r9,32(%rsp)
mov %r8,%r9
mov %rcx,%r8
mov %rsi,%rcx
call *%rdi
- addq $40,%rsp
+ addq $48,%rsp
ret
ENTRY(x86_64_call6)
OpenPOWER on IntegriCloud