summaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
Diffstat (limited to 'bin')
-rw-r--r--bin/Makefile.am15
-rw-r--r--bin/nv_disp.c51
-rw-r--r--bin/nv_rd08.c7
-rw-r--r--bin/nv_rd16.c7
-rw-r--r--bin/nv_rd32.c7
-rw-r--r--bin/nv_rdfunc.h88
-rw-r--r--bin/nv_rf08.c6
-rw-r--r--bin/nv_rf16.c6
-rw-r--r--bin/nv_rf32.c6
-rw-r--r--bin/nv_rffunc.h41
-rw-r--r--bin/nv_ri08.c6
-rw-r--r--bin/nv_ri16.c6
-rw-r--r--bin/nv_ri32.c6
-rw-r--r--bin/nv_rifunc.h47
-rw-r--r--bin/nv_rs08.c7
-rw-r--r--bin/nv_rs16.c7
-rw-r--r--bin/nv_rs32.c7
-rw-r--r--bin/nv_rsfunc.h26
-rw-r--r--bin/nv_rv08.c7
-rw-r--r--bin/nv_rv16.c7
-rw-r--r--bin/nv_rv32.c7
-rw-r--r--bin/nv_rvfunc.h26
-rw-r--r--bin/nv_wf08.c6
-rw-r--r--bin/nv_wf16.c6
-rw-r--r--bin/nv_wf32.c6
-rw-r--r--bin/nv_wffunc.h41
-rw-r--r--bin/nv_wi08.c6
-rw-r--r--bin/nv_wi16.c6
-rw-r--r--bin/nv_wi32.c6
-rw-r--r--bin/nv_wifunc.h47
-rw-r--r--bin/nv_wr08.c7
-rw-r--r--bin/nv_wr16.c7
-rw-r--r--bin/nv_wr32.c7
-rw-r--r--bin/nv_wrfunc.h101
-rw-r--r--bin/nv_ws08.c7
-rw-r--r--bin/nv_ws16.c7
-rw-r--r--bin/nv_ws32.c7
-rw-r--r--bin/nv_wsfunc.h24
-rw-r--r--bin/nv_wv08.c7
-rw-r--r--bin/nv_wv16.c7
-rw-r--r--bin/nv_wv32.c7
-rw-r--r--bin/nv_wvfunc.h24
42 files changed, 729 insertions, 0 deletions
diff --git a/bin/Makefile.am b/bin/Makefile.am
new file mode 100644
index 000000000..998e5ebe4
--- /dev/null
+++ b/bin/Makefile.am
@@ -0,0 +1,15 @@
+bin_PROGRAMS = \
+ nv_rd08 nv_rd16 nv_rd32 nv_wr08 nv_wr16 nv_wr32 \
+ nv_rf08 nv_rf16 nv_rf32 nv_wf08 nv_wf16 nv_wf32 \
+ nv_ri08 nv_ri16 nv_ri32 nv_wi08 nv_wi16 nv_wi32 \
+ nv_rv08 nv_rv16 nv_rv32 nv_wv08 nv_wv16 nv_wv32 \
+ nv_rs08 nv_rs16 nv_rs32 nv_ws08 nv_ws16 nv_ws32 \
+ nv_disp
+
+AM_CPPFLAGS = -I$(top_srcdir)/nvkm/include \
+ -I$(top_srcdir)/nvkm \
+ -I$(top_srcdir)/lib/
+
+LDADD = -lpciaccess \
+ $(top_srcdir)/lib/libpciaccessos.la \
+ $(top_srcdir)/nvkm/libnouveau.la
diff --git a/bin/nv_disp.c b/bin/nv_disp.c
new file mode 100644
index 000000000..2b2011380
--- /dev/null
+++ b/bin/nv_disp.c
@@ -0,0 +1,51 @@
+#include <stdlib.h>
+
+#include <core/os.h>
+#include <core/object.h>
+#include <core/device.h>
+
+static unsigned long chan = 0;
+
+static void
+nv_disp(struct nouveau_object *device, u16 mthd, u32 data)
+{
+ if (nv_device(device)->card_type == NV_50) {
+ u32 ctrl = nv_ro32(device, 0x610300 + (chan * 8));
+ nv_wo32(device, 0x610300 + (chan * 8), ctrl | 0x00000001);
+ nv_wo32(device, 0x610304 + (chan * 8), data);
+ nv_wo32(device, 0x610300 + (chan * 8), mthd | 0x80000001);
+ while (nv_ro32(device, 0x610300 + (chan * 8)) & 0x80000000) {}
+ nv_wo32(device, 0x610300 + (chan * 8), ctrl);
+ } else
+ if (nv_device(device)->card_type >= NV_D0 &&
+ nv_device(device)->card_type <= NV_E0) {
+ u32 ctrl = nv_ro32(device, 0x610700 + (chan * 16));
+ nv_wo32(device, 0x610700 + (chan * 16), ctrl | 0x00000001);
+ nv_wo32(device, 0x610704 + (chan * 16), data);
+ nv_wo32(device, 0x610700 + (chan * 16), mthd | 0x80000001);
+ while (nv_ro32(device, 0x610700 + (chan * 16)) & 0x80000000) {}
+ nv_wo32(device, 0x610700 + (chan * 16), ctrl);
+ } else {
+ printk("unsupported chipset\n");
+ exit(1);
+ }
+}
+
+#define FMTADDR "0x%04lx"
+#define FMTDATA "0x%08x"
+#define NAME "nv_disp"
+#define CAST u32
+#define WRITE(o,v) nv_disp(device, (o), (v))
+#define MAIN main_
+#define ENABLE (NV_DEVICE_DISABLE_MMIO | NV_DEVICE_DISABLE_IDENTIFY)
+#include "nv_wrfunc.h"
+
+int
+main(int argc, char **argv)
+{
+ if (argc < 2 || ((chan = strtol(argv[1], NULL, 0)) == ULONG_MAX))
+ return 0;
+
+ argv[1] = argv[0];
+ return main_(argc - 1, argv + 1);
+}
diff --git a/bin/nv_rd08.c b/bin/nv_rd08.c
new file mode 100644
index 000000000..f3384416f
--- /dev/null
+++ b/bin/nv_rd08.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%06lx"
+#define FMTDATA "0x%02x"
+#define NAME "nv_rd08"
+#define CAST u8
+#define READ(o) nv_ro08(device, (o))
+#define MAIN main
+#include "nv_rdfunc.h"
diff --git a/bin/nv_rd16.c b/bin/nv_rd16.c
new file mode 100644
index 000000000..4c37cb7a5
--- /dev/null
+++ b/bin/nv_rd16.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%06lx"
+#define FMTDATA "0x%04x"
+#define NAME "nv_rd16"
+#define CAST u16
+#define READ(o) nv_ro16(device, (o))
+#define MAIN main
+#include "nv_rdfunc.h"
diff --git a/bin/nv_rd32.c b/bin/nv_rd32.c
new file mode 100644
index 000000000..95cbd3b5c
--- /dev/null
+++ b/bin/nv_rd32.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%06lx"
+#define FMTDATA "0x%08x"
+#define NAME "nv_rd32"
+#define CAST u32
+#define READ(o) nv_ro32(device, (o))
+#define MAIN main
+#include "nv_rdfunc.h"
diff --git a/bin/nv_rdfunc.h b/bin/nv_rdfunc.h
new file mode 100644
index 000000000..bca7cca3a
--- /dev/null
+++ b/bin/nv_rdfunc.h
@@ -0,0 +1,88 @@
+#include <stdlib.h>
+#include <limits.h>
+#include <unistd.h>
+
+#include <core/os.h>
+#include <core/object.h>
+#include <core/class.h>
+
+#ifndef ENABLE
+#define ENABLE NV_DEVICE_DISABLE_MMIO
+#endif
+#ifndef DEBUG0
+#define DEBUG0 0ULL
+#endif
+
+int
+main(int argc, char **argv)
+{
+ struct nouveau_object *client;
+ struct nouveau_object *device;
+ struct nv_device_class args;
+ char *rstr = NULL;
+ int quiet = 0;
+ int ret, c;
+
+ while ((c = getopt(argc, argv, "-q")) != -1) {
+ switch (c) {
+ case 'q':
+ quiet = 1;
+ break;
+ case 1:
+ if (rstr)
+ return 1;
+ rstr = optarg;
+ break;
+ }
+ }
+
+ ret = os_client_new(NULL, "fatal", argc, argv, &client);
+ if (ret)
+ return ret;
+
+ args.device = ~0ULL;
+ args.disable = ~ENABLE;
+ args.debug0 = ~DEBUG0;
+
+ ret = nouveau_object_new(client, ~0, 0, 0x0080, &args, sizeof(args),
+ &device);
+ if (ret)
+ return ret;
+
+ while (rstr && *rstr != '\0') {
+ unsigned long cnt = 1;
+ unsigned long reg;
+
+ if ((reg = strtoul(rstr, &rstr, 0)) == ULONG_MAX)
+ return 1;
+
+ if (*rstr == '/') {
+ if ((cnt = strtoul(rstr + 1, &rstr, 0)) == ULONG_MAX)
+ return 1;
+ } else
+ if (*rstr == '+') {
+ if ((cnt = strtoul(rstr + 1, &rstr, 0)) == ULONG_MAX)
+ return 1;
+ cnt /= sizeof(CAST);
+ }
+
+ switch (*rstr) {
+ case ',':
+ rstr++;
+ case '\0':
+ while (cnt--) {
+ CAST val = READ(reg);
+ if (quiet)
+ printk(FMTDATA"\n", val);
+ else
+ printk(NAME" "FMTADDR" "FMTDATA"\n", reg, val);
+ reg += sizeof(CAST);
+ }
+ break;
+ default:
+ return 1;
+ }
+ }
+
+ return 0;
+}
diff --git a/bin/nv_rf08.c b/bin/nv_rf08.c
new file mode 100644
index 000000000..864b98ca6
--- /dev/null
+++ b/bin/nv_rf08.c
@@ -0,0 +1,6 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%02x"
+#define NAME "nv_rf08"
+#define CAST u8
+#define MAIN main
+#include "nv_rffunc.h"
diff --git a/bin/nv_rf16.c b/bin/nv_rf16.c
new file mode 100644
index 000000000..d40c6e20f
--- /dev/null
+++ b/bin/nv_rf16.c
@@ -0,0 +1,6 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%04x"
+#define NAME "nv_rf16"
+#define CAST u16
+#define MAIN main
+#include "nv_rffunc.h"
diff --git a/bin/nv_rf32.c b/bin/nv_rf32.c
new file mode 100644
index 000000000..c84c77b09
--- /dev/null
+++ b/bin/nv_rf32.c
@@ -0,0 +1,6 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%08x"
+#define NAME "nv_rf32"
+#define CAST u32
+#define MAIN main
+#include "nv_rffunc.h"
diff --git a/bin/nv_rffunc.h b/bin/nv_rffunc.h
new file mode 100644
index 000000000..f7db0317f
--- /dev/null
+++ b/bin/nv_rffunc.h
@@ -0,0 +1,41 @@
+#include <stdlib.h>
+
+#include <core/os.h>
+#include <core/object.h>
+#include <core/device.h>
+
+static void __iomem *map = NULL;
+static u64 map_page = ~0ULL;
+
+static CAST
+nv_rfb(struct nouveau_object *device, u64 offset)
+{
+ u64 page = (offset & ~(PAGE_SIZE - 1));
+ u64 addr = (offset & (PAGE_SIZE - 1));
+
+ if (nv_device(device)->card_type < NV_04 ||
+ nv_device(device)->card_type > NV_E0) {
+ printk("unsupported chipset\n");
+ exit(1);
+ }
+
+ if (map_page != page) {
+ if (map)
+ iounmap(map);
+
+ map = ioremap(pci_resource_start(nv_device(device)->pdev, 1) +
+ page, PAGE_SIZE);
+ if (!map) {
+ printk("map failed\n");
+ exit(1);
+ }
+
+ map_page = page;
+ }
+
+ return *(CAST *)(map + addr);
+}
+
+#define READ(o) nv_rfb(device, (o))
+#define ENABLE (NV_DEVICE_DISABLE_MMIO | NV_DEVICE_DISABLE_IDENTIFY)
+#include "nv_rdfunc.h"
diff --git a/bin/nv_ri08.c b/bin/nv_ri08.c
new file mode 100644
index 000000000..5cb4fe74d
--- /dev/null
+++ b/bin/nv_ri08.c
@@ -0,0 +1,6 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%02x"
+#define NAME "nv_ri08"
+#define CAST u8
+#define MAIN main
+#include "nv_rifunc.h"
diff --git a/bin/nv_ri16.c b/bin/nv_ri16.c
new file mode 100644
index 000000000..81aa04894
--- /dev/null
+++ b/bin/nv_ri16.c
@@ -0,0 +1,6 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%04x"
+#define NAME "nv_ri16"
+#define CAST u16
+#define MAIN main
+#include "nv_rifunc.h"
diff --git a/bin/nv_ri32.c b/bin/nv_ri32.c
new file mode 100644
index 000000000..25a98f568
--- /dev/null
+++ b/bin/nv_ri32.c
@@ -0,0 +1,6 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%08x"
+#define NAME "nv_ri32"
+#define CAST u32
+#define MAIN main
+#include "nv_rifunc.h"
diff --git a/bin/nv_rifunc.h b/bin/nv_rifunc.h
new file mode 100644
index 000000000..096e16f2d
--- /dev/null
+++ b/bin/nv_rifunc.h
@@ -0,0 +1,47 @@
+#include <stdlib.h>
+
+#include <core/os.h>
+#include <core/object.h>
+#include <core/device.h>
+
+static void __iomem *map = NULL;
+static u64 map_page = ~0ULL;
+
+static CAST
+nv_rfb(struct nouveau_object *device, u64 offset)
+{
+ struct pci_dev *pdev = nv_device(device)->pdev;
+ u64 page = (offset & ~(PAGE_SIZE - 1));
+ u64 addr = (offset & (PAGE_SIZE - 1));
+
+ if (nv_device(device)->card_type < NV_40 ||
+ nv_device(device)->card_type > NV_E0) {
+ printk("unsupported chipset\n");
+ exit(1);
+ }
+
+ if (map_page != page) {
+ if (map)
+ iounmap(map);
+
+ if (pci_resource_len(pdev, 2)) {
+ map = ioremap(pci_resource_start(pdev, 2) +
+ page, PAGE_SIZE);
+ } else {
+ map = ioremap(pci_resource_start(pdev, 3) +
+ page, PAGE_SIZE);
+ }
+
+ if (!map) {
+ printk("map failed\n");
+ exit(1);
+ }
+
+ map_page = page;
+ }
+
+ return *(CAST *)(map + addr);
+}
+
+#define READ(o) nv_rfb(device, (o))
+#include "nv_rdfunc.h"
diff --git a/bin/nv_rs08.c b/bin/nv_rs08.c
new file mode 100644
index 000000000..b379d7fe8
--- /dev/null
+++ b/bin/nv_rs08.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%02x"
+#define NAME "nv_rs08"
+#define CAST u8
+#define MAIN main
+#define RSYS nv_ro08
+#include "nv_rsfunc.h"
diff --git a/bin/nv_rs16.c b/bin/nv_rs16.c
new file mode 100644
index 000000000..6582197e6
--- /dev/null
+++ b/bin/nv_rs16.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%04x"
+#define NAME "nv_rs16"
+#define CAST u16
+#define MAIN main
+#define RSYS nv_ro16
+#include "nv_rsfunc.h"
diff --git a/bin/nv_rs32.c b/bin/nv_rs32.c
new file mode 100644
index 000000000..326f49fd9
--- /dev/null
+++ b/bin/nv_rs32.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%08x"
+#define NAME "nv_rs32"
+#define CAST u32
+#define MAIN main
+#define RSYS nv_ro32
+#include "nv_rsfunc.h"
diff --git a/bin/nv_rsfunc.h b/bin/nv_rsfunc.h
new file mode 100644
index 000000000..c73f1f737
--- /dev/null
+++ b/bin/nv_rsfunc.h
@@ -0,0 +1,26 @@
+#include <stdlib.h>
+
+#include <core/os.h>
+#include <core/object.h>
+#include <core/device.h>
+
+static CAST
+nv_rsys(struct nouveau_object *device, u64 addr)
+{
+ if (nv_device(device)->card_type >= NV_50 &&
+ nv_device(device)->card_type <= NV_E0) {
+ CAST data;
+ u32 pmem = nv_ro32(device, 0x001700);
+ nv_wo32(device, 0x001700, 0x02000000 | (addr >> 16));
+ data = RSYS(device, 0x700000 + (addr & 0xffffULL));
+ nv_wo32(device, 0x001700, pmem);
+ return data;
+ } else {
+ printk("unsupported chipset\n");
+ exit(1);
+ }
+}
+
+#define READ(o) nv_rsys(device, (o))
+#define ENABLE (NV_DEVICE_DISABLE_MMIO | NV_DEVICE_DISABLE_IDENTIFY)
+#include "nv_rdfunc.h"
diff --git a/bin/nv_rv08.c b/bin/nv_rv08.c
new file mode 100644
index 000000000..1b51c8f40
--- /dev/null
+++ b/bin/nv_rv08.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%02x"
+#define NAME "nv_rv08"
+#define CAST u8
+#define MAIN main
+#define RVRAM nv_ro08
+#include "nv_rvfunc.h"
diff --git a/bin/nv_rv16.c b/bin/nv_rv16.c
new file mode 100644
index 000000000..9f6b6e47e
--- /dev/null
+++ b/bin/nv_rv16.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%04x"
+#define NAME "nv_rv16"
+#define CAST u16
+#define MAIN main
+#define RVRAM nv_ro16
+#include "nv_rvfunc.h"
diff --git a/bin/nv_rv32.c b/bin/nv_rv32.c
new file mode 100644
index 000000000..d147bf17a
--- /dev/null
+++ b/bin/nv_rv32.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%08x"
+#define NAME "nv_rv32"
+#define CAST u32
+#define MAIN main
+#define RVRAM nv_ro32
+#include "nv_rvfunc.h"
diff --git a/bin/nv_rvfunc.h b/bin/nv_rvfunc.h
new file mode 100644
index 000000000..18f43219c
--- /dev/null
+++ b/bin/nv_rvfunc.h
@@ -0,0 +1,26 @@
+#include <stdlib.h>
+
+#include <core/os.h>
+#include <core/object.h>
+#include <core/device.h>
+
+static CAST
+nv_rvram(struct nouveau_object *device, u64 addr)
+{
+ if (nv_device(device)->card_type >= NV_50 &&
+ nv_device(device)->card_type <= NV_E0) {
+ CAST data;
+ u32 pmem = nv_ro32(device, 0x001700);
+ nv_wo32(device, 0x001700, 0x00000000 | (addr >> 16));
+ data = RVRAM(device, 0x700000 + (addr & 0xffffULL));
+ nv_wo32(device, 0x001700, pmem);
+ return data;
+ } else {
+ printk("unsupported chipset\n");
+ exit(1);
+ }
+}
+
+#define READ(o) nv_rvram(device, (o))
+#define ENABLE (NV_DEVICE_DISABLE_MMIO | NV_DEVICE_DISABLE_IDENTIFY)
+#include "nv_rdfunc.h"
diff --git a/bin/nv_wf08.c b/bin/nv_wf08.c
new file mode 100644
index 000000000..f05a7e7cd
--- /dev/null
+++ b/bin/nv_wf08.c
@@ -0,0 +1,6 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%02x"
+#define NAME "nv_wf08"
+#define CAST u8
+#define MAIN main
+#include "nv_wffunc.h"
diff --git a/bin/nv_wf16.c b/bin/nv_wf16.c
new file mode 100644
index 000000000..c1b747cc2
--- /dev/null
+++ b/bin/nv_wf16.c
@@ -0,0 +1,6 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%04x"
+#define NAME "nv_wf16"
+#define CAST u16
+#define MAIN main
+#include "nv_wffunc.h"
diff --git a/bin/nv_wf32.c b/bin/nv_wf32.c
new file mode 100644
index 000000000..88140064c
--- /dev/null
+++ b/bin/nv_wf32.c
@@ -0,0 +1,6 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%08x"
+#define NAME "nv_wf32"
+#define CAST u32
+#define MAIN main
+#include "nv_wffunc.h"
diff --git a/bin/nv_wffunc.h b/bin/nv_wffunc.h
new file mode 100644
index 000000000..4166afd89
--- /dev/null
+++ b/bin/nv_wffunc.h
@@ -0,0 +1,41 @@
+#include <stdlib.h>
+
+#include <core/os.h>
+#include <core/object.h>
+#include <core/device.h>
+
+static void __iomem *map = NULL;
+static u64 map_page = ~0ULL;
+
+static void
+nv_wfb(struct nouveau_object *device, u64 offset, CAST data)
+{
+ u64 page = (offset & ~(PAGE_SIZE - 1));
+ u64 addr = (offset & (PAGE_SIZE - 1));
+
+ if (nv_device(device)->card_type < NV_04 ||
+ nv_device(device)->card_type > NV_E0) {
+ printk("unsupported chipset\n");
+ exit(1);
+ }
+
+ if (map_page != page) {
+ if (map)
+ iounmap(map);
+
+ map = ioremap(pci_resource_start(nv_device(device)->pdev, 1) +
+ page, PAGE_SIZE);
+ if (!map) {
+ printk("map failed\n");
+ exit(1);
+ }
+
+ map_page = page;
+ }
+
+ *(CAST *)(map + addr) = data;
+}
+
+#define WRITE(o,v) nv_wfb(device, (o), (v))
+#define ENABLE (NV_DEVICE_DISABLE_MMIO | NV_DEVICE_DISABLE_IDENTIFY)
+#include "nv_wrfunc.h"
diff --git a/bin/nv_wi08.c b/bin/nv_wi08.c
new file mode 100644
index 000000000..ebd5fb530
--- /dev/null
+++ b/bin/nv_wi08.c
@@ -0,0 +1,6 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%02x"
+#define NAME "nv_wi08"
+#define CAST u8
+#define MAIN main
+#include "nv_wifunc.h"
diff --git a/bin/nv_wi16.c b/bin/nv_wi16.c
new file mode 100644
index 000000000..dc815e7e9
--- /dev/null
+++ b/bin/nv_wi16.c
@@ -0,0 +1,6 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%04x"
+#define NAME "nv_wi16"
+#define CAST u16
+#define MAIN main
+#include "nv_wifunc.h"
diff --git a/bin/nv_wi32.c b/bin/nv_wi32.c
new file mode 100644
index 000000000..a2420facf
--- /dev/null
+++ b/bin/nv_wi32.c
@@ -0,0 +1,6 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%08x"
+#define NAME "nv_wi32"
+#define CAST u32
+#define MAIN main
+#include "nv_wifunc.h"
diff --git a/bin/nv_wifunc.h b/bin/nv_wifunc.h
new file mode 100644
index 000000000..8e4abb1fc
--- /dev/null
+++ b/bin/nv_wifunc.h
@@ -0,0 +1,47 @@
+#include <stdlib.h>
+
+#include <core/os.h>
+#include <core/object.h>
+#include <core/device.h>
+
+static void __iomem *map = NULL;
+static u64 map_page = ~0ULL;
+
+static void
+nv_wfb(struct nouveau_object *device, u64 offset, CAST data)
+{
+ struct pci_dev *pdev = nv_device(device)->pdev;
+ u64 page = (offset & ~(PAGE_SIZE - 1));
+ u64 addr = (offset & (PAGE_SIZE - 1));
+
+ if (nv_device(device)->card_type < NV_40 ||
+ nv_device(device)->card_type > NV_E0) {
+ printk("unsupported chipset\n");
+ exit(1);
+ }
+
+ if (map_page != page) {
+ if (map)
+ iounmap(map);
+
+ if (pci_resource_len(pdev, 2)) {
+ map = ioremap(pci_resource_start(pdev, 2) +
+ page, PAGE_SIZE);
+ } else {
+ map = ioremap(pci_resource_start(pdev, 3) +
+ page, PAGE_SIZE);
+ }
+
+ if (!map) {
+ printk("map failed\n");
+ exit(1);
+ }
+
+ map_page = page;
+ }
+
+ *(CAST *)(map + addr) = data;
+}
+
+#define WRITE(o,v) nv_wfb(device, (o), (v))
+#include "nv_wrfunc.h"
diff --git a/bin/nv_wr08.c b/bin/nv_wr08.c
new file mode 100644
index 000000000..184bfef46
--- /dev/null
+++ b/bin/nv_wr08.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%06lx"
+#define FMTDATA "0x%02x"
+#define NAME "nv_wr08"
+#define CAST u8
+#define WRITE(o,v) nv_wo08(device, (o), (v))
+#define MAIN main
+#include "nv_wrfunc.h"
diff --git a/bin/nv_wr16.c b/bin/nv_wr16.c
new file mode 100644
index 000000000..0e2271eb6
--- /dev/null
+++ b/bin/nv_wr16.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%06lx"
+#define FMTDATA "0x%04x"
+#define NAME "nv_wr16"
+#define CAST u16
+#define WRITE(o,v) nv_wo16(device, (o), (v))
+#define MAIN main
+#include "nv_wrfunc.h"
diff --git a/bin/nv_wr32.c b/bin/nv_wr32.c
new file mode 100644
index 000000000..6dd188840
--- /dev/null
+++ b/bin/nv_wr32.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%06lx"
+#define FMTDATA "0x%08x"
+#define NAME "nv_wr32"
+#define CAST u32
+#define WRITE(o,v) nv_wo32(device, (o), (v))
+#define MAIN main
+#include "nv_wrfunc.h"
diff --git a/bin/nv_wrfunc.h b/bin/nv_wrfunc.h
new file mode 100644
index 000000000..eae75c248
--- /dev/null
+++ b/bin/nv_wrfunc.h
@@ -0,0 +1,101 @@
+#include <stdlib.h>
+#include <limits.h>
+#include <unistd.h>
+
+#include <core/os.h>
+#include <core/object.h>
+#include <core/class.h>
+
+#ifndef ENABLE
+#define ENABLE NV_DEVICE_DISABLE_MMIO
+#endif
+#ifndef DEBUG0
+#define DEBUG0 0ULL
+#endif
+
+int
+MAIN(int argc, char **argv)
+{
+ struct nouveau_object *client;
+ struct nouveau_object *device;
+ struct nv_device_class args;
+ char *rstr = NULL;
+ char *vstr = NULL;
+ int quiet = 0;
+ int ret, c;
+
+ while ((c = getopt(argc, argv, "-q")) != -1) {
+ switch (c) {
+ case 'q':
+ quiet = 1;
+ break;
+ case 1:
+ if (rstr) {
+ if (vstr)
+ return 1;
+ vstr = optarg;
+ } else {
+ rstr = optarg;
+ }
+ break;
+ }
+ }
+
+ ret = os_client_new(NULL, "fatal", argc, argv, &client);
+ if (ret)
+ return ret;
+
+ args.device = ~0ULL;
+ args.disable = ~ENABLE;
+ args.debug0 = ~DEBUG0;
+
+ ret = nouveau_object_new(client, ~0, 0, 0x0080, &args, sizeof(args),
+ &device);
+ if (ret)
+ return ret;
+
+ while (rstr && *rstr != '\0') {
+ unsigned long cnt = 1;
+ unsigned long reg;
+ unsigned long val;
+
+ if ((reg = strtoul(rstr, &rstr, 0)) == ULONG_MAX)
+ return 1;
+
+ if (*rstr == '/') {
+ if ((cnt = strtoul(rstr + 1, &rstr, 0)) == ULONG_MAX)
+ return 1;
+ } else
+ if (*rstr == '+') {
+ if ((cnt = strtoul(rstr + 1, &rstr, 0)) == ULONG_MAX)
+ return 1;
+ cnt /= sizeof(CAST);
+ }
+
+ if (*rstr == '=') {
+ if ((val = strtoul(rstr + 1, &rstr, 0)) == ULONG_MAX)
+ return 1;
+ } else {
+ if (!vstr ||
+ (val = strtoul(vstr, NULL, 0)) == ULONG_MAX)
+ return 1;
+ }
+
+ switch (*rstr) {
+ case ',':
+ rstr++;
+ case '\0':
+ while (cnt--) {
+ if (!quiet)
+ printk(NAME" "FMTADDR" "FMTDATA"\n", reg, (CAST)val);
+ WRITE(reg, val);
+ reg += sizeof(CAST);
+ }
+ break;
+ default:
+ return 1;
+ }
+ }
+
+ return 0;
+}
diff --git a/bin/nv_ws08.c b/bin/nv_ws08.c
new file mode 100644
index 000000000..5d49f2edc
--- /dev/null
+++ b/bin/nv_ws08.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%02x"
+#define NAME "nv_rs08"
+#define CAST u8
+#define MAIN main
+#define WSYS nv_wo08
+#include "nv_wsfunc.h"
diff --git a/bin/nv_ws16.c b/bin/nv_ws16.c
new file mode 100644
index 000000000..a3f0702be
--- /dev/null
+++ b/bin/nv_ws16.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%04x"
+#define NAME "nv_ws16"
+#define CAST u16
+#define MAIN main
+#define WSYS nv_wo16
+#include "nv_wsfunc.h"
diff --git a/bin/nv_ws32.c b/bin/nv_ws32.c
new file mode 100644
index 000000000..78756fe09
--- /dev/null
+++ b/bin/nv_ws32.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%08x"
+#define NAME "nv_ws32"
+#define CAST u32
+#define MAIN main
+#define WSYS nv_wo32
+#include "nv_wsfunc.h"
diff --git a/bin/nv_wsfunc.h b/bin/nv_wsfunc.h
new file mode 100644
index 000000000..596eede5f
--- /dev/null
+++ b/bin/nv_wsfunc.h
@@ -0,0 +1,24 @@
+#include <stdlib.h>
+
+#include <core/os.h>
+#include <core/object.h>
+#include <core/device.h>
+
+static void
+nv_wsys(struct nouveau_object *device, u64 addr, CAST data)
+{
+ if (nv_device(device)->card_type >= NV_50 &&
+ nv_device(device)->card_type <= NV_E0) {
+ u32 pmem = nv_ro32(device, 0x001700);
+ nv_wo32(device, 0x001700, 0x02000000 | (addr >> 16));
+ WSYS(device, 0x700000 + (addr & 0xffffULL), data);
+ nv_wo32(device, 0x001700, pmem);
+ } else {
+ printk("unsupported chipset\n");
+ exit(1);
+ }
+}
+
+#define WRITE(o,v) nv_wsys(device, (o), (v))
+#define ENABLE (NV_DEVICE_DISABLE_MMIO | NV_DEVICE_DISABLE_IDENTIFY)
+#include "nv_wrfunc.h"
diff --git a/bin/nv_wv08.c b/bin/nv_wv08.c
new file mode 100644
index 000000000..c78d42e83
--- /dev/null
+++ b/bin/nv_wv08.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%02x"
+#define NAME "nv_wv08"
+#define CAST u8
+#define MAIN main
+#define WVRAM nv_wo08
+#include "nv_wvfunc.h"
diff --git a/bin/nv_wv16.c b/bin/nv_wv16.c
new file mode 100644
index 000000000..d738cf89f
--- /dev/null
+++ b/bin/nv_wv16.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%04x"
+#define NAME "nv_wv16"
+#define CAST u16
+#define MAIN main
+#define WVRAM nv_wo16
+#include "nv_wvfunc.h"
diff --git a/bin/nv_wv32.c b/bin/nv_wv32.c
new file mode 100644
index 000000000..ba381a38e
--- /dev/null
+++ b/bin/nv_wv32.c
@@ -0,0 +1,7 @@
+#define FMTADDR "0x%08lx"
+#define FMTDATA "0x%08x"
+#define NAME "nv_wv32"
+#define CAST u32
+#define MAIN main
+#define WVRAM nv_wo32
+#include "nv_wvfunc.h"
diff --git a/bin/nv_wvfunc.h b/bin/nv_wvfunc.h
new file mode 100644
index 000000000..1f218ffc6
--- /dev/null
+++ b/bin/nv_wvfunc.h
@@ -0,0 +1,24 @@
+#include <stdlib.h>
+
+#include <core/os.h>
+#include <core/object.h>
+#include <core/device.h>
+
+static void
+nv_wvram(struct nouveau_object *device, u64 addr, CAST data)
+{
+ if (nv_device(device)->card_type >= NV_50 &&
+ nv_device(device)->card_type <= NV_E0) {
+ u32 pmem = nv_ro32(device, 0x001700);
+ nv_wo32(device, 0x001700, 0x00000000 | (addr >> 16));
+ WVRAM(device, 0x700000 + (addr & 0xffffULL), data);
+ nv_wo32(device, 0x001700, pmem);
+ } else {
+ printk("unsupported chipset\n");
+ exit(1);
+ }
+}
+
+#define WRITE(o,v) nv_wvram(device, (o), (v))
+#define ENABLE (NV_DEVICE_DISABLE_MMIO | NV_DEVICE_DISABLE_IDENTIFY)
+#include "nv_wrfunc.h"