summaryrefslogtreecommitdiff
path: root/contrib/libdha/mtrr.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/libdha/mtrr.c')
-rw-r--r--contrib/libdha/mtrr.c91
1 files changed, 91 insertions, 0 deletions
diff --git a/contrib/libdha/mtrr.c b/contrib/libdha/mtrr.c
new file mode 100644
index 000000000..48ae5a1fd
--- /dev/null
+++ b/contrib/libdha/mtrr.c
@@ -0,0 +1,91 @@
+/*
+ mtrr.c - Stuff for optimizing memory access
+ Copyrights:
+ 2002 - Linux version by Nick Kurshev
+ Licence: GPL
+*/
+
+#include "config.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include "kernelhelper/dhahelper.h"
+#include "libdha.h"
+
+#if defined (__i386__) && defined (__NetBSD__)
+#include <sys/param.h>
+#if __NetBSD_Version__ > 105240000
+#include <stdint.h>
+#include <stdlib.h>
+#include <machine/mtrr.h>
+#include <machine/sysarch.h>
+#endif
+#endif
+
+int mtrr_set_type(unsigned base,unsigned size,int type)
+{
+ int dhahelper_fd;
+ dhahelper_fd = open("/dev/dhahelper",O_RDWR);
+ if(dhahelper_fd > 0)
+ {
+ int retval;
+ dhahelper_mtrr_t mtrrs;
+ mtrrs.operation = MTRR_OP_ADD;
+ mtrrs.start = base;
+ mtrrs.size = size;
+ mtrrs.type = type;
+ retval = ioctl(dhahelper_fd, DHAHELPER_ACK_IRQ, &mtrrs);
+ close(dhahelper_fd);
+ return retval;
+ }
+#if defined (__NetBSD__) && (__NetBSD_Version__) > 105240000
+ {
+ struct mtrr *mtrrp;
+ int n;
+
+ mtrrp = malloc(sizeof (struct mtrr));
+ mtrrp->base = base;
+ mtrrp->len = size;
+ mtrrp->type = type;
+ mtrrp->flags = MTRR_VALID | MTRR_PRIVATE;
+ n = 1;
+
+ if (i386_set_mtrr(mtrrp, &n) < 0) {
+ free(mtrrp);
+ return errno;
+ }
+ free(mtrrp);
+ return 0;
+ }
+#else
+ {
+ FILE * mtrr_fd;
+ char * stype;
+ switch(type)
+ {
+ case MTRR_TYPE_UNCACHABLE: stype = "uncachable"; break;
+ case MTRR_TYPE_WRCOMB: stype = "write-combining"; break;
+ case MTRR_TYPE_WRTHROUGH: stype = "write-through"; break;
+ case MTRR_TYPE_WRPROT: stype = "write-protect"; break;
+ case MTRR_TYPE_WRBACK: stype = "write-back"; break;
+ default: return EINVAL;
+ }
+ mtrr_fd = fopen("/proc/mtrr","wt");
+ if(mtrr_fd)
+ {
+ char sout[256];
+ unsigned wr_len;
+ sprintf(sout,"base=0x%08X size=0x%08X type=%s\n",base,size,stype);
+ wr_len = fprintf(mtrr_fd,"%s",sout);
+ /*printf("MTRR: %s\n",sout);*/
+ fclose(mtrr_fd);
+ return wr_len == strlen(sout) ? 0 : EPERM;
+ }
+ }
+#endif
+ return ENOSYS;
+}