Author: bschmidt
Date: Mon Nov 22 20:46:38 2010
New Revision: 215708
URL: http://svn.freebsd.org/changeset/base/215708

Log:
  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>

Modified:
  head/sys/compat/ndis/kern_windrv.c
  head/sys/compat/ndis/ntoskrnl_var.h
  head/sys/compat/ndis/subr_ntoskrnl.c
  head/sys/compat/ndis/winx64_wrap.S

Modified: head/sys/compat/ndis/kern_windrv.c
==============================================================================
--- head/sys/compat/ndis/kern_windrv.c  Mon Nov 22 20:39:29 2010        
(r215707)
+++ head/sys/compat/ndis/kern_windrv.c  Mon Nov 22 20:46:38 2010        
(r215708)
@@ -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, devl
                        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))

Modified: head/sys/compat/ndis/ntoskrnl_var.h
==============================================================================
--- head/sys/compat/ndis/ntoskrnl_var.h Mon Nov 22 20:39:29 2010        
(r215707)
+++ head/sys/compat/ndis/ntoskrnl_var.h Mon Nov 22 20:46:38 2010        
(r215708)
@@ -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 
  * 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 
 #endif /* __i386__ */
 
 #ifdef __amd64__
+#define        KI_USER_SHARED_DATA 0xfffff78000000000UL
 #define        KeAcquireSpinLock(a, b) *(b) = KfAcquireSpinLock(a)
 #define        KeReleaseSpinLock(a, b) KfReleaseSpinLock(a, b)
 

Modified: head/sys/compat/ndis/subr_ntoskrnl.c
==============================================================================
--- head/sys/compat/ndis/subr_ntoskrnl.c        Mon Nov 22 20:39:29 2010        
(r215707)
+++ head/sys/compat/ndis/subr_ntoskrnl.c        Mon Nov 22 20:46:38 2010        
(r215708)
@@ -121,6 +121,7 @@ typedef struct callout_entry callout_ent
 
 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;

Modified: head/sys/compat/ndis/winx64_wrap.S
==============================================================================
--- head/sys/compat/ndis/winx64_wrap.S  Mon Nov 22 20:39:29 2010        
(r215707)
+++ head/sys/compat/ndis/winx64_wrap.S  Mon Nov 22 20:46:38 2010        
(r215708)
@@ -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)
_______________________________________________
svn-src-head@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-head
To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"

Reply via email to