win-pvdrivers

view xenpci/memory.c @ 329:daa0a9b0fef0

move hvm_get_stubs and hvm_free_stubs into a .c from a .h
author Andy Grover <andy.grover@oracle.com>
date Thu Jun 19 16:51:44 2008 -0700 (2008-06-19)
parents 435e5753300f
children 52533409dbbd
line source
1 #include "xenpci.h"
2 #include <hypercall.h>
4 static pgentry_t *demand_map_pgt;
5 static void *demand_map_area_start;
7 static NTSTATUS
8 hvm_get_stubs(PXENPCI_DEVICE_DATA xpdd)
9 {
10 DWORD32 cpuid_output[4];
11 char xensig[13];
12 ULONG i;
13 ULONG pages;
14 ULONG msr;
16 __cpuid(cpuid_output, 0x40000000);
17 *(ULONG*)(xensig + 0) = cpuid_output[1];
18 *(ULONG*)(xensig + 4) = cpuid_output[2];
19 *(ULONG*)(xensig + 8) = cpuid_output[3];
20 xensig[12] = '\0';
21 KdPrint((__DRIVER_NAME " Xen Signature = %s, EAX = 0x%08x\n", xensig, cpuid_output[0]));
23 __cpuid(cpuid_output, 0x40000002);
24 pages = cpuid_output[0];
25 msr = cpuid_output[1];
26 //KdPrint((__DRIVER_NAME " Hypercall area is %u pages.\n", pages));
28 xpdd->hypercall_stubs = ExAllocatePoolWithTag(NonPagedPool, pages * PAGE_SIZE, XENPCI_POOL_TAG);
29 KdPrint((__DRIVER_NAME " Hypercall area at %p\n", xpdd->hypercall_stubs));
31 if (!xpdd->hypercall_stubs)
32 return 1;
33 for (i = 0; i < pages; i++) {
34 ULONGLONG pfn;
35 pfn = (MmGetPhysicalAddress(xpdd->hypercall_stubs + i * PAGE_SIZE).QuadPart >> PAGE_SHIFT);
36 KdPrint((__DRIVER_NAME " pfn = %16lX\n", pfn));
37 __writemsr(msr, (pfn << PAGE_SHIFT) + i);
38 }
39 return STATUS_SUCCESS;
40 }
42 static NTSTATUS
43 hvm_free_stubs(PXENPCI_DEVICE_DATA xpdd)
44 {
45 ExFreePoolWithTag(xpdd->hypercall_stubs, XENPCI_POOL_TAG);
47 return STATUS_SUCCESS;
48 }
50 PVOID
51 map_frames(PULONG f, ULONG n)
52 {
53 unsigned long x;
54 unsigned long y = 0;
55 mmu_update_t mmu_updates[16];
56 int rc;
58 for (x = 0; x <= 1024 - n; x += y + 1) {
59 for (y = 0; y < n; y++)
60 if (demand_map_pgt[x+y] & _PAGE_PRESENT)
61 break;
62 if (y == n)
63 break;
64 }
65 if (y != n) {
66 KdPrint((__DRIVER_NAME " Failed to map %ld frames!\n", n));
67 return NULL;
68 }
70 for (y = 0; y < n; y++) {
71 //mmu_updates[y].ptr = virt_to_mach(&demand_map_pgt[x + y]);
72 mmu_updates[y].ptr = MmGetPhysicalAddress(&demand_map_pgt[x + y]).QuadPart;
73 mmu_updates[y].val = (f[y] << PAGE_SHIFT) | L1_PROT;
74 }
76 rc = HYPERVISOR_mmu_update(mmu_updates, n, NULL, DOMID_SELF);
77 if (rc < 0) {
78 KdPrint((__DRIVER_NAME " Map %ld failed: %d.\n", n, rc));
79 return NULL;
80 } else {
81 return (PVOID)(ULONG)((ULONG)demand_map_area_start + x * PAGE_SIZE);
82 }
83 }