added io/seg utility
This commit is contained in:
parent
68d6b0808b
commit
2c6802e80f
4 changed files with 197 additions and 0 deletions
44
sys/man/1/io
Normal file
44
sys/man/1/io
Normal file
|
@ -0,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)
|
51
sys/man/1/seg
Normal file
51
sys/man/1/seg
Normal file
|
@ -0,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.
|
55
sys/src/cmd/io.c
Normal file
55
sys/src/cmd/io.c
Normal file
|
@ -0,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);
|
||||||
|
}
|
||||||
|
}
|
47
sys/src/cmd/seg.c
Normal file
47
sys/src/cmd/seg.c
Normal file
|
@ -0,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);
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue