ref: 2c6802e80f2bc7be660981b183fe89ecd72061ce
parent: 68d6b0808bbd57a91abf2a5ac4571e4372a8d3fc
author: aiju <devnull@localhost>
date: Fri Apr 15 17:01:29 EDT 2011
added io/seg utility
--- /dev/null
+++ b/sys/man/1/io
@@ -1,0 +1,44 @@
+.TH IO 1
+.SH NAME
+io \- access PC I/O registers
+.SH SYNOPSIS
+.B io
+[
+.B -WLMrw
+]
+.I address
+[
+.I value
+]
+.SH DESCRIPTION
+.I io
+accesses PC I/O space.
+The operation to be performed is selected with
+.B -r
+or
+.B -w
+for reading or writing, respectively.
+The default operation size is a byte.
+C style notation for integers (e.g.
+.B 0x42
+or
+.BR 023 )
+is accepted for the
+.I address
+and
+.I value
+parameters.
+.PP
+.TP
+.B -W
+Perform a word (16 bit) operation.
+.TP
+.B -L
+Perform a long / double word (32 bit) operation.
+.TP
+.B -M
+Access a 64 bit wide machine specific register (MSR).
+.SH SOURCE
+.B /sys/src/cmd/io.c
+.SH SEE ALSO
+.IR seg (1)
--- /dev/null
+++ b/sys/man/1/seg
@@ -1,0 +1,51 @@
+.TH SEG 1
+.SH NAME
+seg \- access a named segment
+.SH SYNOPSIS
+.B seg
+[
+.B -WLrw
+]
+.I segment
+.I segment-size
+.I offset
+[
+.I value
+]
+.SH DESCRIPTION
+.B seg
+accesses a named segment as provided by e.g. certain drivers.
+The operation to be performed is selected with
+.B -r
+and
+.B -w
+for reading and writing, respectively.
+The default operation size is a byte.
+C style notation for integers (e.g.
+.B 0x42
+or
+.BR 023 )
+is accepted for the
+.IR segment-size ,
+.IR offset
+and
+.I value
+parameters.
+.PP
+.TP
+.B -W
+Perform a word (16 bit) operation
+.TP
+.B -L
+Perform a long / double word (32 bit) operation.
+.SH SOURCE
+.B /sys/src/cmd/seg.c
+.SH SEE ALSO
+.IR io (1)
+.SH BUGS
+No check of the
+.I segment-size
+and
+.I offset
+parameters is performed whatsoever.
+Odd values may cause the front to fall off.
--- /dev/null
+++ b/sys/src/cmd/io.c
@@ -1,0 +1,55 @@
+#include <u.h>
+#include <libc.h>
+
+const char const * datac[] = {0,"#P/iob","#P/iow",0,"#P/iol",0,0,0,"#P/msr"};
+
+void
+main(int argc, char** argv) {
+ int fd, size, op;
+ ulong port;
+ uvlong data;
+ uchar datab[8];
+
+ data = 0;
+ size = 1;
+ op = -1;
+ ARGBEGIN {
+ case 'W': size = 2; break;
+ case 'L': size = 4; break;
+ case 'M': size = 8; break;
+ case 'r': op = OREAD; break;
+ case 'w': op = OWRITE; break;
+ default: sysfatal("bad flag %c", ARGC());
+ } ARGEND;
+ if(op == -1) sysfatal("no operation selected");
+ if(argc < 1) sysfatal("no port selected");
+ if(op == OWRITE && argc < 2) sysfatal("no data selected");
+ port = strtoul(argv[0], 0, 0);
+ if(op == OWRITE) data = strtoull(argv[1], 0, 0);
+
+ fd = open(datac[size], op);
+ if(fd == -1) sysfatal("open: %r");
+
+ if(op == OWRITE) {
+ datab[0] = data;
+ datab[1] = data >> 8;
+ datab[2] = data >> 16;
+ datab[3] = data >> 24;
+ datab[4] = data >> 32;
+ datab[5] = data >> 40;
+ datab[6] = data >> 48;
+ datab[7] = data >> 56;
+ if(pwrite(fd, datab, size, port) != size)
+ sysfatal("pwrite: %r");
+ }
+ else {
+ memset(datab, 0, 8);
+ if(pread(fd, datab, size, port) != size)
+ sysfatal("pread: %r");
+ data = datab[0] | (datab[1] << 8) | (datab[2] << 16) |
+ (datab[3] << 24) | ((vlong)datab[4] << 32) |
+ ((vlong)datab[5] << 40) | ((vlong)datab[6] << 48) |
+ ((vlong)datab[7] << 56);
+ print("0x%llx\n", data);
+ }
+}
\ No newline at end of file
--- /dev/null
+++ b/sys/src/cmd/seg.c
@@ -1,0 +1,47 @@
+#include <u.h>
+#include <libc.h>
+
+const char datac[] = {0,'b','w',0,'l'};
+
+void
+main(int argc, char** argv) {
+ ulong size, segsize, op, port;
+ char* segment;
+ ulong data;
+ uchar *seg;
+
+ data = 0;
+ size = 1;
+ op = -1;
+ ARGBEGIN {
+ case 'W': size = 2; break;
+ case 'L': size = 4; break;
+ case 'r': op = OREAD; break;
+ case 'w': op = OWRITE; break;
+ default: sysfatal("bad flag %c", ARGC());
+ } ARGEND;
+ if(op == -1) sysfatal("no operation selected");
+ if(argc < 3) sysfatal("no address, no segsize or no segment selected");
+ if(op == OWRITE && argc < 4) sysfatal("no data selected");
+ segment = argv[0];
+ segsize = strtoul(argv[1], 0, 0);
+ port = strtoul(argv[2], 0, 0);
+ if(op == OWRITE) data = strtoul(argv[3], 0, 0);
+
+ seg = segattach(0, segment, 0, segsize);
+ if(seg == (uchar*)-1) sysfatal("segattach: %r");
+
+ if(op == OWRITE) {
+ switch(size) {
+ case 1: *(uchar*)(seg+port) = data; break;
+ case 2: *(ushort*)(seg+port) = data; break;
+ case 4: *(ulong*)(seg+port) = data; break;
+ }
+ }
+ else {
+ data = seg[port];
+ if(size >= 2) data |= seg[port+1] << 8;
+ if(size >= 4) data |= (seg[port+2] << 16) | (seg[port+3] << 24);
+ print("0x%ulx\n", data);
+ }
+}
\ No newline at end of file