From 2c6802e80f2bc7be660981b183fe89ecd72061ce Mon Sep 17 00:00:00 2001 From: aiju Date: Fri, 15 Apr 2011 21:01:29 +0200 Subject: [PATCH] added io/seg utility --- sys/man/1/io | 44 +++++++++++++++++++++++++++++++++++++ sys/man/1/seg | 51 +++++++++++++++++++++++++++++++++++++++++++ sys/src/cmd/io.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++ sys/src/cmd/seg.c | 47 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 197 insertions(+) create mode 100644 sys/man/1/io create mode 100644 sys/man/1/seg create mode 100644 sys/src/cmd/io.c create mode 100644 sys/src/cmd/seg.c diff --git a/sys/man/1/io b/sys/man/1/io new file mode 100644 index 000000000..e96a60be0 --- /dev/null +++ b/sys/man/1/io @@ -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) diff --git a/sys/man/1/seg b/sys/man/1/seg new file mode 100644 index 000000000..3fd87f2e2 --- /dev/null +++ b/sys/man/1/seg @@ -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. diff --git a/sys/src/cmd/io.c b/sys/src/cmd/io.c new file mode 100644 index 000000000..59ccf22fd --- /dev/null +++ b/sys/src/cmd/io.c @@ -0,0 +1,55 @@ +#include +#include + +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 diff --git a/sys/src/cmd/seg.c b/sys/src/cmd/seg.c new file mode 100644 index 000000000..367aad988 --- /dev/null +++ b/sys/src/cmd/seg.c @@ -0,0 +1,47 @@ +#include +#include + +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