summaryrefslogtreecommitdiff
path: root/sysutils/jfbterm/files/patch-mtrr
blob: 021779861809862bb5fbe721067c74e99a4e55a0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
--- framebuffer.c.orig	2009-02-23 18:23:54.000000000 -0500
+++ framebuffer.c	2010-02-22 19:26:38.000000000 -0500
@@ -442,6 +442,11 @@
 	assert(initialized);
 
 	if (self->memory != MAP_FAILED) {
+		if (writecombine.enable) {
+			memctl_clearWriteCombine(writecombine.base,
+			    writecombine.size);
+			writecombine.enable = false;
+		}
 		if (munmap(self->memory, self->length) == -1)
 			warn("munmap()");
 		self->memory = MAP_FAILED;
@@ -1162,18 +1167,21 @@
 			warnx("Invalid write-combining base detected. "
 			      "Start of framebuffer memory is %#x.",
 			      video_adapter_info.va_window);
-		writecombine.base = video_adapter_info.va_window;
+		writecombine.base = (u_long)video_adapter_info.va_window;
 		if (writecombine.size != 0 &&
 		    video_adapter_info.va_window_size != writecombine.size)
 			warnx("Invalid write-combining size detected. "
 			      "Framebuffer size is %#x.",
 			      video_adapter_info.va_window_size);
 		writecombine.size = video_adapter_info.va_window_size;
+		writecombine.size = powerof2(writecombine.size) ?
+		    writecombine.size : 1UL << flsl(writecombine.size);
 #endif
-		if (writecombine.base != 0 && writecombine.size != 0)
-			memctl_setWriteCombine(writecombine.base,
-					       writecombine.size);
+		if (writecombine.base == 0 || writecombine.size == 0)
+			writecombine.enable = false;
 	}
+	if (writecombine.enable)
+		memctl_setWriteCombine(writecombine.base, writecombine.size);
 
 	/* VGA */
 #ifdef ENABLE_VGA16FB
--- memctl.c.orig	2009-01-23 10:53:36.000000000 -0500
+++ memctl.c	2010-02-22 19:26:38.000000000 -0500
@@ -92,7 +92,7 @@
 		mem_range_desc.mr_owner[sizeof(mem_range_desc.mr_owner) - 1] =
 			'\0';
 		mem_range_op.mo_desc   = &mem_range_desc;
-		mem_range_op.mo_arg[0] = 0;
+		mem_range_op.mo_arg[0] = MEMRANGE_SET_UPDATE;
 		if (ioctl(fd, MEMRANGE_SET, &mem_range_op) != -1)
 			result = true;
 		close(fd);
@@ -130,3 +130,28 @@
 #endif
 }
 
+void memctl_clearWriteCombine(unsigned long base, unsigned long size)
+{
+#if defined (__FreeBSD__) && (defined (__amd64__) || defined (__i386__))
+	struct mem_range_desc mem_range_desc;
+	struct mem_range_op mem_range_op;
+	int fd;
+
+	assert(base != 0);
+	assert(size != 0);
+
+	privilege_on();
+	fd = open(_PATH_MEM, O_RDONLY);
+	privilege_off();
+	if (fd != -1) {
+		mem_range_desc.mr_base = base;
+		mem_range_desc.mr_len  = size;
+		mem_range_op.mo_desc   = &mem_range_desc;
+		mem_range_op.mo_arg[0] = MEMRANGE_SET_REMOVE;
+		if (ioctl(fd, MEMRANGE_SET, &mem_range_op) == -1)
+			warn("failed to clear mtrr (0x%lx/0x%lx)\n",
+			    base, size);
+		close(fd);
+	}
+#endif
+}
--- memctl.h.orig	2009-01-23 10:53:36.000000000 -0500
+++ memctl.h	2010-02-22 19:26:38.000000000 -0500
@@ -31,6 +31,7 @@
 #include <stdbool.h>
 
 bool memctl_setWriteCombine(unsigned long base, unsigned long size);
+void memctl_clearWriteCombine(unsigned long base, unsigned long size);
 
 #endif /* INCLUDE_MEMCTL_H */