[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[COMMITTED] libpoke, poke: support for volatile/non-volatile IO spaces
From: |
Jose E. Marchesi |
Subject: |
[COMMITTED] libpoke, poke: support for volatile/non-volatile IO spaces |
Date: |
Thu, 19 Sep 2024 11:38:38 +0200 |
User-agent: |
Gnus/5.13 (Gnus v5.13) |
This patch introduces the notion of volatile vs. non-volatile IO
spaces in poke, which allows a smarter management of remaps.
Documentation and tests included.
2024-09-19 Jose E. Marchesi <jemarch@gnu.org>
* libpoke/ios-dev.h (struct ios_dev_if): New field
volatile_by_default.
* libpoke/libpoke.h (struct pk_iod_if): Likewise.
* libpoke/ios.c (struct ios): New field volatile_p.
(ios_open): Initialize volatile_p in newly opened IO space.
(ios_volatile_p): Define.
* libpoke/ios-dev-file.c (ios_dev_file_volatile_by_default):
Define.
(ios_dev_file): Set volatile_by_default.
(ios_dev_file_convert_flags): Ignore IOS_F_VOLATILE.
* libpoke/ios-dev-mem.c (ios_dev_mem_volatile_by_default): Define.
(ios_dev_mem): Set volatile_by_default.
* libpoke/ios-dev-mmap.c (ios_dev_mmap_volatile_by_default):
Define.
(ios_dev_mmap): set volatile_by_default.
* libpoke/ios-dev-nbd.c (ios_dev_nbd_volatile_by_default): Define.
(ios_dev_nbd): Set volatile_by_default.
* libpoke/ios-dev-proc.c (ios_dev_proc_volatile_by_default):
Define.
(ios_dev_proc): Set volatile_by_default.
* libpoke/ios-dev-stream.c (ios_dev_stream_volatile_by_default):
Define.
(ios_dev_stream): Set volatile_by_default.
* libpoke/ios-dev-sub.c (ios_dev_sub_volatile_by_default): Define.
(ios_dev_sub): Set volatile_by_default.
* libpoke/ios-dev-zero.c (ios_dev_zero_volatile_by_default):
Define.
(ios_dev_zero): Define volatile_by_default.
* libpoke/pvm.jitter (iogetv): New instruction.
* libpoke/pkl-rt.pk (ioisvolatile): New function.
(IOS_F_VOLATILE): Define.
* poke/pk-cmd-info.pk (pk_info_ios): Add column "Volatile".
* libpoke/ios.h (IOS_F_VOLATILE): Define.
* testsuite/poke.libpoke/foreign-iod.c (iod_volatile_by_default):
New function.
(iod_if): Initialize volatile_by_default.
* libpoke/libpoke.c (pk_register_iod): Update to handle
volatile_by_default.
* testsuite/poke.pkl/open-volatile-1.pk: New test.
* testsuite/poke.pkl/open-volatile-2.pk: Likewise.
* testsuite/poke.pkl/iovolatile-1.pk: Likewise.
* testsuite/poke.cmd/file-bias-1.pk: Update test.
* testsuite/poke.cmd/file-relative.pk: Likewise.
* testsuite/poke.cmd/file-mode.pk: Likewise.
* testsuite/poke.cmd/file-bias-2.pk: Likewise.
* testsuite/Makefile.am (EXTRA_DIST): Add new tests.
* doc/poke.texi (Files as IO Spaces): Update to reflect volatile
attribute of IO spaces.
(Buffers as IO Spaces): Likewise.
(info command): Likewise.
(iovolatile): New section.
(Auto-Remapping): Update.
---
ChangeLog | 55 +++++++++++++
doc/poke.texi | 113 ++++++++++++++------------
libpoke/ios-dev-file.c | 9 +-
libpoke/ios-dev-mem.c | 7 ++
libpoke/ios-dev-mmap.c | 9 +-
libpoke/ios-dev-nbd.c | 7 ++
libpoke/ios-dev-proc.c | 9 +-
libpoke/ios-dev-stream.c | 9 +-
libpoke/ios-dev-sub.c | 11 ++-
libpoke/ios-dev-zero.c | 8 ++
libpoke/ios-dev.h | 1 +
libpoke/ios.c | 16 ++++
libpoke/ios.h | 6 ++
libpoke/libpoke.c | 1 +
libpoke/libpoke.h | 7 +-
libpoke/pkl-rt.pk | 7 ++
libpoke/pvm.jitter | 25 ++++++
poke/pk-cmd-info.pk | 4 +-
testsuite/Makefile.am | 3 +
testsuite/poke.cmd/file-bias-1.pk | 4 +-
testsuite/poke.cmd/file-bias-2.pk | 4 +-
testsuite/poke.cmd/file-mode.pk | 6 +-
testsuite/poke.cmd/file-relative.pk | 4 +-
testsuite/poke.libpoke/foreign-iod.c | 7 ++
testsuite/poke.pkl/iovolatile-1.pk | 8 ++
testsuite/poke.pkl/open-volatile-1.pk | 8 ++
testsuite/poke.pkl/open-volatile-2.pk | 8 ++
27 files changed, 288 insertions(+), 68 deletions(-)
create mode 100644 testsuite/poke.pkl/iovolatile-1.pk
create mode 100644 testsuite/poke.pkl/open-volatile-1.pk
create mode 100644 testsuite/poke.pkl/open-volatile-2.pk
diff --git a/ChangeLog b/ChangeLog
index 6b949026..11b45bf2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,58 @@
+2024-09-19 Jose E. Marchesi <jemarch@gnu.org>
+
+ * libpoke/ios-dev.h (struct ios_dev_if): New field
+ volatile_by_default.
+ * libpoke/libpoke.h (struct pk_iod_if): Likewise.
+ * libpoke/ios.c (struct ios): New field volatile_p.
+ (ios_open): Initialize volatile_p in newly opened IO space.
+ (ios_volatile_p): Define.
+ * libpoke/ios-dev-file.c (ios_dev_file_volatile_by_default):
+ Define.
+ (ios_dev_file): Set volatile_by_default.
+ (ios_dev_file_convert_flags): Ignore IOS_F_VOLATILE.
+ * libpoke/ios-dev-mem.c (ios_dev_mem_volatile_by_default): Define.
+ (ios_dev_mem): Set volatile_by_default.
+ * libpoke/ios-dev-mmap.c (ios_dev_mmap_volatile_by_default):
+ Define.
+ (ios_dev_mmap): set volatile_by_default.
+ * libpoke/ios-dev-nbd.c (ios_dev_nbd_volatile_by_default): Define.
+ (ios_dev_nbd): Set volatile_by_default.
+ * libpoke/ios-dev-proc.c (ios_dev_proc_volatile_by_default):
+ Define.
+ (ios_dev_proc): Set volatile_by_default.
+ * libpoke/ios-dev-stream.c (ios_dev_stream_volatile_by_default):
+ Define.
+ (ios_dev_stream): Set volatile_by_default.
+ * libpoke/ios-dev-sub.c (ios_dev_sub_volatile_by_default): Define.
+ (ios_dev_sub): Set volatile_by_default.
+ * libpoke/ios-dev-zero.c (ios_dev_zero_volatile_by_default):
+ Define.
+ (ios_dev_zero): Define volatile_by_default.
+ * libpoke/pvm.jitter (iogetv): New instruction.
+ * libpoke/pkl-rt.pk (ioisvolatile): New function.
+ (IOS_F_VOLATILE): Define.
+ * poke/pk-cmd-info.pk (pk_info_ios): Add column "Volatile".
+ * libpoke/ios.h (IOS_F_VOLATILE): Define.
+ * testsuite/poke.libpoke/foreign-iod.c (iod_volatile_by_default):
+ New function.
+ (iod_if): Initialize volatile_by_default.
+ * libpoke/libpoke.c (pk_register_iod): Update to handle
+ volatile_by_default.
+ * testsuite/poke.pkl/open-volatile-1.pk: New test.
+ * testsuite/poke.pkl/open-volatile-2.pk: Likewise.
+ * testsuite/poke.pkl/iovolatile-1.pk: Likewise.
+ * testsuite/poke.cmd/file-bias-1.pk: Update test.
+ * testsuite/poke.cmd/file-relative.pk: Likewise.
+ * testsuite/poke.cmd/file-mode.pk: Likewise.
+ * testsuite/poke.cmd/file-bias-2.pk: Likewise.
+ * testsuite/Makefile.am (EXTRA_DIST): Add new tests.
+ * doc/poke.texi (Files as IO Spaces): Update to reflect volatile
+ attribute of IO spaces.
+ (Buffers as IO Spaces): Likewise.
+ (info command): Likewise.
+ (iovolatile): New section.
+ (Auto-Remapping): Update.
+
2024-09-16 Jose E. Marchesi <jemarch@gnu.org>
* poke/pk-cmd-ios.c (file_cmd): Add flags to command synopsis.
diff --git a/doc/poke.texi b/doc/poke.texi
index 8ad3941f..523076c9 100644
--- a/doc/poke.texi
+++ b/doc/poke.texi
@@ -1132,8 +1132,8 @@ about:
@example
(poke) .info ios
- Id Type Mode Bias Size Name
-* 0 FILE rw 0x00000000#B 0x00000398#B ./foo.o
+ Id Type Volatile Mode Bias Size Name
+* 0 FILE no rw 0x00000000#B 0x00000398#B ./foo.o
@end example
The command @command{.info ios} gives us information about all the IO
@@ -1141,10 +1141,13 @@ spaces that are currently open. The first column tells
us a positive
integer that identifies the IOS. This @dfn{IO space identifier} is
unique at any given time. In this example, the id corresponding to
@file{foo.o} is @code{0}. The second column tells us the type of IO
-space. The third column tells us that @file{foo.o} allows both reading
-and writing. The fourth column tells us the size of the file, in
-hexadecimal. The fifth column is the name of the IO space; in this
-case, it is the path to the file being edited.
+space. The third column tells us whether the IO space is
+@dfn{volatile} or not; the contents of a volatile IO space can change
+at any time out of our control. The third column tells us that
+@file{foo.o} allows both reading and writing. The fourth column tells
+us the size of the file, in hexadecimal. The fifth column is the name
+of the IO space; in this case, it is the path to the file being
+edited.
You may wonder what is that weird suffix @code{#B}. It is a unit,
and tells us that the size @code{0x398} is measured in bytes, @i{i.e.} the
@@ -1159,9 +1162,9 @@ clearly, let's open another file:
(poke) .file bar.o
The current IOS is now `./bar.o'.
(poke) .info ios
- Id Type Mode Bias Size Name
-* 1 FILE rw 0x00000000#B 0x00000398#B ./bar.o
- 0 FILE rw 0x00000000#B 0x00000398#B ./foo.o
+ Id Type Volatile Mode Bias Size Name
+* 1 FILE no rw 0x00000000#B 0x00000398#B ./bar.o
+ 0 FILE no rw 0x00000000#B 0x00000398#B ./foo.o
@end example
Ah, there we have both @file{foo.o} and @file{bar.o}. Now the current
@@ -1175,9 +1178,9 @@ an IO space as an argument:
(poke) .ios 0
The current IOS is now `./foo.o'.
(poke) .info ios
- Id Type Mode Bias Size Name
- 1 FILE rw 0x00000000#B 0x00000398#B ./bar.o
-* 0 FILE rw 0x00000000#B 0x00000398#B ./foo.o
+ Id Type Volatile Mode Bias Size Name
+ 1 FILE no rw 0x00000000#B 0x00000398#B ./bar.o
+* 0 FILE no rw 0x00000000#B 0x00000398#B ./foo.o
@end example
@noindent
@@ -1187,8 +1190,8 @@ We are back to @file{foo.o}. Since we are not really
interested in
@example
(poke) .close 1
(poke) .info ios
- Id Type Mode Bias Size Name
-* 0 FILE rw 0x00000000#B 0x00000398#B ./foo.o
+ Id Type Volatile Mode Bias Size Name
+* 0 FILE no rw 0x00000000#B 0x00000398#B ./foo.o
@end example
Note how in the examples above we used the IO space identifiers (0 and
@@ -2737,8 +2740,8 @@ that opened a file as an IO space?
(poke) .file foo.o
The current IOS is now `./foo.o'.
(poke) .info ios
- Id Type Mode Bias Size Name
-* 0 FILE rw 0x00000000#B 0x000004c8#B ./foo.o
+ Id Type Volatile Mode Bias Size Name
+* 0 FILE no rw 0x00000000#B 0x000004c8#B ./foo.o
@end example
@noindent
@@ -2749,9 +2752,9 @@ Memory buffers can be created using a similar dot-command,
(poke) .mem foo
The current IOS is now `*foo*'.
(poke) .info ios
- Id Type Mode Bias Size Name
-* 1 MEMORY 0x00000000#B 0x00001000#B *foo*
- 0 FILE rw 0x00000000#B 0x000004c8#B ./foo.o
+ Id Type Volatile Mode Bias Size Name
+* 1 MEMORY no 0x00000000#B 0x00001000#B *foo*
+ 0 FILE no rw 0x00000000#B 0x000004c8#B ./foo.o
@end example
Note how the name of the buffer is built by prepending and appending
@@ -2874,9 +2877,9 @@ we can continue our work tomorrow. This is how we would
do that:
@example
(poke) .info ios
- Id Type Mode Bias Size Name
-* 1 MEMORY 0x00000000#B 0x00001000#B *scratch*
- 0 FILE rw 0x00000000#B 0x000f4241#B ./foo.o
+ Id Type Volatile Mode Bias Size Name
+* 1 MEMORY no 0x00000000#B 0x00001000#B *scratch*
+ 0 FILE no rw 0x00000000#B 0x000f4241#B ./foo.o
(poke) save :from 0#B :size iosize (1) :file "scratch.dat"
@end example
@@ -3918,9 +3921,9 @@ $ poke p.sbm
(poke) .mem scratch
The current IOS is now `*scratch*'.
(poke) .info ios
- Id Type Mode Bias Size Name
-* 1 MEMORY 0x00000000#B 0x00001000#B *scratch*
- 0 FILE rw 0x00000000#B 0x0000006e#B ./p.sbm
+ Id Type Volatile Mode Bias Size Name
+* 1 MEMORY no 0x00000000#B 0x00001000#B *scratch*
+ 0 FILE no rw 0x00000000#B 0x0000006e#B ./p.sbm
(poke) copy :from_ios 0 :from 0#B :to 0#B :size iosize (0)
(poke) dump
76543210 0011 2233 4455 6677 8899 aabb ccdd eeff 0123456789ABCDEF
@@ -8721,9 +8724,9 @@ Display a list of open files.
@example
(poke) .info ios
- Id Type Mode Bias Size Name
- 1 FILE r 0x00000000#B 0x0000df78#B foo.o
-* 0 FILE rw 0x00000000#B 0x00000022#B foo.bson
+ Id Type Volatile Mode Bias Size Name
+ 1 FILE no r 0x00000000#B 0x0000df78#B foo.o
+* 0 FILE no rw 0x00000000#B 0x00000022#B foo.bson
@end example
@cindex IO space
@@ -8737,9 +8740,9 @@ switch to it as the new current IO space:
(poke) .ios 1
The current file is now `foo.o'.
(poke) .info ios
- Id Type Mode Bias Size Name
-* 1 FILE r 0x00000000#B 0x0000df78#B foo.o
- 0 FILE rw 0x00000000#B 0x00000022#B foo.bson
+ Id Type Volatile Mode Bias Size Name
+* 1 FILE no r 0x00000000#B 0x0000df78#B foo.o
+ 0 FILE no rw 0x00000000#B 0x00000022#B foo.bson
@end example
@item .info variables [@var{regexp}]
@@ -13608,6 +13611,7 @@ memory of some process.
* iosearch:: Search for an IO space by name.
* iolist:: Getting a list of open IO spaces.
* openset:: Opening and setting combined.
+* iovolatile:: Getting whether a given IO space is volatile.
* iosize:: Getting the size of an IO space.
* iotype:: Getting the type of an IO space.
* iohandler:: Getting the handler string of an IO space.
@@ -13859,6 +13863,20 @@ fun openset = (string @var{handler}, uint<64>
@var{flags} = 0) int<32>
Where the meaning of @var{handler}, @var{flags} and the returned value
are exactly like in @code{open}.
+@node iovolatile
+@subsubsection @code{iovolatile}
+@cindex @code{iovolatile}
+
+The @code{iovolatile} builtin returns a boolean indicating whether a
+given IO space is @dfn{volatile}. It has the following prototype:
+
+@example
+fun iovolatile = (int<32> ios = get_ios) int<32>
+@end example
+
+If the IO space specified to @code{iovolatile} doesn't exist,
+@code{E_no_ios} will be raised.
+
@node iosize
@subsubsection @code{iosize}
@cindex @code{iosize}
@@ -14395,11 +14413,12 @@ definition.
@node Auto-Remapping
@subsection Auto-Remapping
@cindex remap
+@cindex volatile IO spaces
By default poke always tries to handle mapped values in a transparent
way, @i{i.e.} in the same way than if the values weren't mapped. To
guarantee that the contents of mapped values are always up to date, it
-issues @dfn{remaps} every time the value gets referenced.
+may need to issue @dfn{remaps} when the value gets referenced.
@noindent
For example, consider the following Poke program:
@@ -14425,26 +14444,16 @@ element in position 2.
This re-mapping 100% guarantees that the mapped values are up to date.
However, this can get very slow, depending on the data structures we
-are poking at.
-
-@noindent
-poke offers a way to turn this auto re-mapping off. In Poke code:
-
-@example
-vm_set_autoremap (0)
-@end example
-
-@noindent
-Or using the poke application CLI:
-
-@example
-(poke) .set autoremap no
-@end example
-
-@noindent
-When auto-remap is switched off, mapped values are used as-is. It is
-then the responsibility of the user to explicitly re-map values using
-the @code{remap} operator. Like:
+are poking at. poke thus tries to be smart and do as less remapping as
+possible. In non-volatile IO spaces, like files, only mapped values
+whose contents have been updated by poke itself will be re-mapped.
+This is in contrast to volatile IO spaces, in which the underlying
+contents may be updated any time out of the control of poke, and
+therefore remapping cannot be avoided. In read-only non-volatile IO
+spaces poke doesn't remap values at all.
+
+The user can explicitly re-map values using the @code{remap} operator.
+Like:
@example
(poke) remap arr
diff --git a/libpoke/ios-dev-file.c b/libpoke/ios-dev-file.c
index 4f663c22..b291b245 100644
--- a/libpoke/ios-dev-file.c
+++ b/libpoke/ios-dev-file.c
@@ -298,6 +298,12 @@ ios_dev_file_flush (void *iod, ios_dev_off offset)
return IOS_OK;
}
+static int
+ios_dev_file_volatile_by_default (void *iod, const char *handler)
+{
+ return 0;
+}
+
struct ios_dev_if ios_dev_file =
{
.get_if_name = ios_dev_file_get_if_name,
@@ -308,5 +314,6 @@ struct ios_dev_if ios_dev_file =
.pwrite = ios_dev_file_pwrite,
.get_flags = ios_dev_file_get_flags,
.size = ios_dev_file_size,
- .flush = ios_dev_file_flush
+ .flush = ios_dev_file_flush,
+ .volatile_by_default = ios_dev_file_volatile_by_default
};
diff --git a/libpoke/ios-dev-mem.c b/libpoke/ios-dev-mem.c
index e945c59b..5be54cd7 100644
--- a/libpoke/ios-dev-mem.c
+++ b/libpoke/ios-dev-mem.c
@@ -163,6 +163,12 @@ ios_dev_mem_flush (void *iod, ios_dev_off offset)
return IOS_OK;
}
+static int
+ios_dev_mem_volatile_by_default (void *iod, const char *handler)
+{
+ return 0;
+}
+
struct ios_dev_if ios_dev_mem =
{
.get_if_name = ios_dev_mem_get_if_name,
@@ -174,4 +180,5 @@ struct ios_dev_if ios_dev_mem =
.get_flags = ios_dev_mem_get_flags,
.size = ios_dev_mem_size,
.flush = ios_dev_mem_flush,
+ .volatile_by_default = ios_dev_mem_volatile_by_default,
};
diff --git a/libpoke/ios-dev-mmap.c b/libpoke/ios-dev-mmap.c
index b619f269..9c1ee1c2 100644
--- a/libpoke/ios-dev-mmap.c
+++ b/libpoke/ios-dev-mmap.c
@@ -447,6 +447,12 @@ ios_dev_mmap_flush (void *iod, ios_dev_off offset)
return IOD_OK;
}
+static int
+ios_dev_mmap_volatile_by_default (void *iod, const char *handler)
+{
+ return 1;
+}
+
struct ios_dev_if ios_dev_mmap =
{
.get_if_name = ios_dev_mmap_get_if_name,
@@ -457,5 +463,6 @@ struct ios_dev_if ios_dev_mmap =
.pwrite = ios_dev_mmap_pwrite,
.get_flags = ios_dev_mmap_get_flags,
.size = ios_dev_mmap_size,
- .flush = ios_dev_mmap_flush
+ .flush = ios_dev_mmap_flush,
+ .volatile_by_default = ios_dev_mmap_volatile_by_default,
};
diff --git a/libpoke/ios-dev-nbd.c b/libpoke/ios-dev-nbd.c
index a6bf2474..be1135f0 100644
--- a/libpoke/ios-dev-nbd.c
+++ b/libpoke/ios-dev-nbd.c
@@ -185,6 +185,12 @@ ios_dev_nbd_flush (void *iod, ios_dev_off offset)
return IOS_OK;
}
+static int
+ios_dev_nbd_volatile_by_default (void *iod, const char *handler)
+{
+ return 1;
+}
+
struct ios_dev_if ios_dev_nbd =
{
.get_if_name = ios_dev_nbd_get_if_name,
@@ -196,4 +202,5 @@ struct ios_dev_if ios_dev_nbd =
.get_flags = ios_dev_nbd_get_flags,
.size = ios_dev_nbd_size,
.flush = ios_dev_nbd_flush,
+ .volatile_by_default = ios_dev_nbd_volatile_by_default,
};
diff --git a/libpoke/ios-dev-proc.c b/libpoke/ios-dev-proc.c
index 8a36b209..c89cc19e 100644
--- a/libpoke/ios-dev-proc.c
+++ b/libpoke/ios-dev-proc.c
@@ -172,6 +172,12 @@ ios_dev_proc_flush (void *iod, ios_dev_off offset)
return IOS_OK;
}
+static int
+ios_dev_proc_volatile_by_default (void *iod, const char *handler)
+{
+ return 1;
+}
+
struct ios_dev_if ios_dev_proc =
{
.get_if_name = ios_dev_proc_get_if_name,
@@ -182,5 +188,6 @@ struct ios_dev_if ios_dev_proc =
.pwrite = ios_dev_proc_pwrite,
.get_flags = ios_dev_proc_get_flags,
.size = ios_dev_proc_size,
- .flush = ios_dev_proc_flush
+ .flush = ios_dev_proc_flush,
+ .volatile_by_default = ios_dev_proc_volatile_by_default,
};
diff --git a/libpoke/ios-dev-stream.c b/libpoke/ios-dev-stream.c
index 1f3a7915..aca0686d 100644
--- a/libpoke/ios-dev-stream.c
+++ b/libpoke/ios-dev-stream.c
@@ -259,6 +259,12 @@ ios_dev_stream_flush (void *iod, ios_dev_off offset)
return IOS_OK;
}
+static int
+ios_dev_stream_volatile_by_default (void *iod, const char *handler)
+{
+ return 1;
+}
+
struct ios_dev_if ios_dev_stream =
{
.get_if_name = ios_dev_stream_get_dev_if_name,
@@ -269,5 +275,6 @@ struct ios_dev_if ios_dev_stream =
.pwrite = ios_dev_stream_pwrite,
.get_flags = ios_dev_stream_get_flags,
.size = ios_dev_stream_size,
- .flush = ios_dev_stream_flush
+ .flush = ios_dev_stream_flush,
+ .volatile_by_default = ios_dev_stream_volatile_by_default,
};
diff --git a/libpoke/ios-dev-sub.c b/libpoke/ios-dev-sub.c
index f0967101..bbb42ead 100644
--- a/libpoke/ios-dev-sub.c
+++ b/libpoke/ios-dev-sub.c
@@ -259,6 +259,14 @@ ios_dev_sub_flush (void *iod, ios_dev_off offset)
return IOS_OK;
}
+static int
+ios_dev_sub_volatile_by_default (void *iod, const char *handler)
+{
+ struct ios_dev_sub *sub = iod;
+
+ return ios_volatile_p (sub->base_ios);
+}
+
struct ios_dev_if ios_dev_sub =
{
.get_if_name = ios_dev_sub_get_if_name,
@@ -269,5 +277,6 @@ struct ios_dev_if ios_dev_sub =
.pwrite = ios_dev_sub_pwrite,
.get_flags = ios_dev_sub_get_flags,
.size = ios_dev_sub_size,
- .flush = ios_dev_sub_flush
+ .flush = ios_dev_sub_flush,
+ .volatile_by_default = ios_dev_sub_volatile_by_default,
};
diff --git a/libpoke/ios-dev-zero.c b/libpoke/ios-dev-zero.c
index a563ad97..a304af41 100644
--- a/libpoke/ios-dev-zero.c
+++ b/libpoke/ios-dev-zero.c
@@ -105,6 +105,13 @@ ios_dev_zero_flush (void *iod, ios_dev_off offset)
return IOS_OK;
}
+static int
+ios_dev_zero_volatile_by_default (void *iod, const char *handler)
+{
+ return 0;
+}
+
+
struct ios_dev_if ios_dev_zero =
{
.get_if_name = ios_dev_zero_get_if_name,
@@ -116,6 +123,7 @@ struct ios_dev_if ios_dev_zero =
.get_flags = ios_dev_zero_get_flags,
.size = ios_dev_zero_size,
.flush = ios_dev_zero_flush,
+ .volatile_by_default = ios_dev_zero_volatile_by_default,
};
/* Handler: <zero> */
diff --git a/libpoke/ios-dev.h b/libpoke/ios-dev.h
index 1d437450..aa8126ac 100644
--- a/libpoke/ios-dev.h
+++ b/libpoke/ios-dev.h
@@ -65,6 +65,7 @@ struct ios_dev_if
uint64_t (*get_flags) (void *dev);
ios_dev_off (*size) (void *dev);
int (*flush) (void *dev, ios_dev_off offset);
+ int (*volatile_by_default) (void *dev, const char *handler);
};
#define IOS_FILE_HANDLER_NORMALIZE(handler, new_handler) \
diff --git a/libpoke/ios.c b/libpoke/ios.c
index 9c2452e0..c53ff13d 100644
--- a/libpoke/ios.c
+++ b/libpoke/ios.c
@@ -64,6 +64,10 @@
NEXT is a pointer to the next open IO space, or NULL.
+ VOLATILE_P determines whether the IO space contents can vary
+ beetween calls to ios_write_*. In other words, a volatile IOS
+ assume that its contents may change at any time.
+
XXX: add status, saved or not saved.
*/
@@ -71,6 +75,7 @@ struct ios
{
int id;
int zombie_p;
+ int volatile_p;
int num_sub_devs;
char *handler;
void *dev;
@@ -244,6 +249,11 @@ found:
if (iod_error || io->dev == NULL)
goto error;
+ /* Set whether the IO space is volatile. If it is not volatile by
+ default then it can be overriden by the IOS_F_VOLATILE flag. */
+ io->volatile_p =
+ (flags & IOS_F_VOLATILE) || dev_if->volatile_by_default (io->dev, handler);
+
/* Increment the id counter after all possible errors are avoided. */
io->id = ios_ctx->next_id++;
@@ -391,6 +401,12 @@ ios_get_id (ios io)
return io->id;
}
+int
+ios_volatile_p (ios io)
+{
+ return io->volatile_p;
+}
+
const char *
ios_get_handler (ios io)
{
diff --git a/libpoke/ios.h b/libpoke/ios.h
index 2ad3947f..7a992fb1 100644
--- a/libpoke/ios.h
+++ b/libpoke/ios.h
@@ -125,6 +125,8 @@ typedef int64_t ios_off;
#define IOS_F_WRITE 2
#define IOS_F_CREATE 16
+#define IOS_F_VOLATILE (1 << 8)
+
#define IOS_M_RDONLY (IOS_F_READ)
#define IOS_M_WRONLY (IOS_F_WRITE)
#define IOS_M_RDWR (IOS_F_READ | IOS_F_WRITE)
@@ -207,6 +209,10 @@ ios ios_search_by_id (ios_context ios_ctx, int id);
int ios_get_id (ios io);
+/* Return whether the given IO space is volatile. */
+
+int ios_volatile_p (ios io);
+
/* Return the handler of the given IO space. */
const char *ios_get_handler (ios io);
diff --git a/libpoke/libpoke.c b/libpoke/libpoke.c
index f88c2128..9c258c83 100644
--- a/libpoke/libpoke.c
+++ b/libpoke/libpoke.c
@@ -1166,6 +1166,7 @@ pk_register_iod (pk_compiler pkc, struct pk_iod_if
*iod_if)
CF (close);
CF (pread);
CF (pwrite);
+ CF (volatile_by_default);
CF (get_flags);
CF (size);
CF (flush);
diff --git a/libpoke/libpoke.h b/libpoke/libpoke.h
index 63f91d1f..2228b522 100644
--- a/libpoke/libpoke.h
+++ b/libpoke/libpoke.h
@@ -1328,7 +1328,6 @@ typedef uint64_t pk_iod_off;
struct pk_iod_if
{
/* Return the name of this device interface. Cannot return NULL. */
-
const char *(*get_if_name) ();
/* Determine whether the provided HANDLER is recognized as a valid
@@ -1358,6 +1357,12 @@ struct pk_iod_if
writes. */
int (*pwrite) (void *dev, const void *buf, size_t count, pk_iod_off offset);
+ /* Return whether IO spaces implemented by this interface are
+ "volatile" by default. Volatile IO spaces assume that their
+ contents can change at any time, and not just as the result of
+ write operations in this interface. */
+ int (*volatile_by_default) (void *dev, const char *handler);
+
/* Return the flags of the device, as it was opened. */
uint64_t (*get_flags) (void *dev);
diff --git a/libpoke/pkl-rt.pk b/libpoke/pkl-rt.pk
index 4f28849d..8566c25f 100644
--- a/libpoke/pkl-rt.pk
+++ b/libpoke/pkl-rt.pk
@@ -367,6 +367,8 @@ immutable var IOS_F_READ = 1;
immutable var IOS_F_WRITE = 2;
immutable var IOS_F_CREATE = 16;
+immutable var IOS_F_VOLATILE = 1 <<. 8;
+
immutable var IOS_M_RDONLY = IOS_F_READ;
immutable var IOS_M_WRONLY = IOS_F_WRITE;
immutable var IOS_M_RDWR = IOS_F_READ | IOS_F_WRITE;
@@ -975,6 +977,11 @@ immutable fun iosearch = (string handler) int<32>:
raise E_no_ios;
}
+immutable fun iovolatile = (int<32>ios = get_ios) int<32>:
+{
+ return asm int<32>: ("iogetv; nip" : ios);
+}
+
immutable fun iosetbias = (offset<uint<64>,1> bias = 0#1, int<32> ios =
get_ios) void:
{
asm ("iosetb; drop" :: bias, ios);
diff --git a/libpoke/pvm.jitter b/libpoke/pvm.jitter
index 8798a0c5..bf516efd 100644
--- a/libpoke/pvm.jitter
+++ b/libpoke/pvm.jitter
@@ -123,6 +123,7 @@ wrapped-functions
ios_map
ios_handler
ios_size
+ ios_volatile_p
ios_open
ios_read_int
ios_read_uint
@@ -1770,6 +1771,30 @@ instruction iohandler ()
end
end
+# Instruction: iogetv
+#
+# Push 1 on the stack if the IO space on the stack is volatile.
+# Push 0 otherwise.
+#
+# If the given IO space doesn't exist then the exception PVM_E_NO_IOS
+# is raised.
+#
+# Stack: ( INT - INT INT )
+# Exceptions: PVM_E_NO_IOS
+
+instruction iogetv ()
+ non-relocatable
+ branching # because of PVM_RAISE_DIRECT
+ code
+ ios_context ios_ctx = PVM_STATE_BACKING_FIELD (ios_ctx);
+ ios io = ios_search_by_id (ios_ctx, PVM_VAL_INT (JITTER_TOP_STACK ()));
+
+ if (io == NULL)
+ PVM_RAISE_DFL (PVM_E_NO_IOS);
+ JITTER_PUSH_STACK (pvm_make_int (ios_volatile_p (io), 32));
+ end
+end
+
# Instruction: iogetb
#
# Each IO space has a bias associated with it, which by default is 0
diff --git a/poke/pk-cmd-info.pk b/poke/pk-cmd-info.pk
index 7b38bfdf..e6c95cc2 100644
--- a/poke/pk-cmd-info.pk
+++ b/poke/pk-cmd-info.pk
@@ -21,12 +21,13 @@
fun pk_info_ios = void:
{
- var table = Pk_Table { num_columns = pk_hserver_p ? 7 : 6,
+ var table = Pk_Table { num_columns = pk_hserver_p ? 8 : 7,
max_column_size = 80 };
table.row ("table-header");
table.column (" Id");
table.column ("Type");
+ table.column ("Volatile");
table.column ("Mode");
table.column ("Bias");
table.column ("Size");
@@ -47,6 +48,7 @@ fun pk_info_ios = void:
table.row;
table.column ((ios == get_ios ? "* " : " ") + format ("%i32d", ios));
table.column (iotype);
+ table.column (iovolatile (ios) ? "yes" : "no");
table.column (mode);
if (bias > 0xffff_ffff)
{
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
index 60794a6b..fda60303 100644
--- a/testsuite/Makefile.am
+++ b/testsuite/Makefile.am
@@ -1807,6 +1807,7 @@ EXTRA_DIST = \
poke.pkl/iosetbias-7.pk\
poke.pkl/iotype-1.pk \
poke.pkl/iotype-2.pk \
+ poke.pkl/iovolatile-1.pk \
poke.pkl/ior-integers-1.pk \
poke.pkl/ior-integers-2.pk \
poke.pkl/ior-int-struct-1.pk \
@@ -2070,6 +2071,8 @@ EXTRA_DIST = \
poke.pkl/open-sub-7.pk \
poke.pkl/open-sub-8.pk \
poke.pkl/open-sub-9.pk \
+ poke.pkl/open-volatile-1.pk \
+ poke.pkl/open-volatile-2.pk \
poke.pkl/optcond-1.pk \
poke.pkl/optcond-1-diag.pk \
poke.pkl/optcond-2.pk \
diff --git a/testsuite/poke.cmd/file-bias-1.pk
b/testsuite/poke.cmd/file-bias-1.pk
index 918c06fd..1bf77d26 100644
--- a/testsuite/poke.cmd/file-bias-1.pk
+++ b/testsuite/poke.cmd/file-bias-1.pk
@@ -4,5 +4,5 @@
/* { dg-command { .file foo.data } } */
/* { dg-command { iosetbias (0x13#b) } } */
/* { dg-command { .info ios } } */
-/* { dg-output " Id +Type +Mode +Bias +Size +Name" } */
-/* { dg-output "\n\\* 0 +FILE +rw +0x00000013#b +0x00000008#B +./foo.data" } */
+/* { dg-output " Id +Type +Volatile +Mode +Bias +Size +Name" } */
+/* { dg-output "\n\\* 0 +FILE +no +rw +0x00000013#b +0x00000008#B +./foo.data"
} */
diff --git a/testsuite/poke.cmd/file-bias-2.pk
b/testsuite/poke.cmd/file-bias-2.pk
index 921188a2..02fa8e71 100644
--- a/testsuite/poke.cmd/file-bias-2.pk
+++ b/testsuite/poke.cmd/file-bias-2.pk
@@ -4,5 +4,5 @@
/* { dg-command { .file foo.data } } */
/* { dg-command { iosetbias (0x13#B) } } */
/* { dg-command { .info ios } } */
-/* { dg-output " Id +Type +Mode +Bias +Size +Name" } */
-/* { dg-output "\n\\* 0 +FILE +rw +0x00000013#B +0x00000008#B +./foo.data" } */
+/* { dg-output " Id +Type +Volatile +Mode +Bias +Size +Name" } */
+/* { dg-output "\n\\* 0 +FILE +no +rw +0x00000013#B +0x00000008#B +./foo.data"
} */
diff --git a/testsuite/poke.cmd/file-mode.pk b/testsuite/poke.cmd/file-mode.pk
index f2777c29..f803b2ad 100644
--- a/testsuite/poke.cmd/file-mode.pk
+++ b/testsuite/poke.cmd/file-mode.pk
@@ -5,6 +5,6 @@
/* { dg-command { .file foo } } */
/* { dg-command { .file /dev/null } } */
/* { dg-command { .info ios } } */
-/* { dg-output " Id +Type +Mode +Bias +Size +Name" } */
-/* { dg-output {\n. 1 +FILE +rw +0x00000000#B +0x00000000#B +/dev/null} } */
-/* { dg-output {\n 0 +FILE +r[w ] +0x00000000#B +0x[0-9a-f]*#B +foo} } */
+/* { dg-output " Id +Type +Volatile +Mode +Bias +Size +Name" } */
+/* { dg-output {\n. 1 +FILE +no +rw +0x00000000#B +0x00000000#B +/dev/null} }
*/
+/* { dg-output {\n 0 +FILE +no +r[w ] +0x00000000#B +0x[0-9a-f]*#B +foo} } */
diff --git a/testsuite/poke.cmd/file-relative.pk
b/testsuite/poke.cmd/file-relative.pk
index dbcb5cfc..fc702635 100644
--- a/testsuite/poke.cmd/file-relative.pk
+++ b/testsuite/poke.cmd/file-relative.pk
@@ -3,5 +3,5 @@
/* { dg-command { .file a#b } } */
/* { dg-command { .info ios } } */
-/* { dg-output " Id +Type +Mode +Bias +Size +Name" } */
-/* { dg-output "\n\\* 0 +FILE +rw +0x00000000#B +0x00000008#B +./a#b" } */
+/* { dg-output " Id +Type +Volatile +Mode +Bias +Size +Name" } */
+/* { dg-output "\n\\* 0 +FILE +no +rw +0x00000000#B +0x00000008#B +./a#b" } */
diff --git a/testsuite/poke.libpoke/foreign-iod.c
b/testsuite/poke.libpoke/foreign-iod.c
index 8eaf0055..f4ad5b15 100644
--- a/testsuite/poke.libpoke/foreign-iod.c
+++ b/testsuite/poke.libpoke/foreign-iod.c
@@ -137,6 +137,12 @@ iod_close (void *dev)
return PK_OK;
}
+int
+iod_volatile_by_default (void *dev, const char *handler)
+{
+ return 0;
+}
+
static uint32_t USER_DATA = 0x706f6b65u; /* "poke" */
struct pk_iod_if iod_if =
@@ -147,6 +153,7 @@ struct pk_iod_if iod_if =
iod_close,
iod_pread,
iod_pwrite,
+ iod_volatile_by_default,
iod_get_flags,
iod_size,
iod_flush,
diff --git a/testsuite/poke.pkl/iovolatile-1.pk
b/testsuite/poke.pkl/iovolatile-1.pk
new file mode 100644
index 00000000..72a7025f
--- /dev/null
+++ b/testsuite/poke.pkl/iovolatile-1.pk
@@ -0,0 +1,8 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x90 0xa0 0xb0
0xc0} foo } */
+
+/* { dg-command {var f = open ("foo")} } */
+/* { dg-command {iovolatile} } */
+/* { dg-output "0" } */
+/* { dg-command { iovolatile (f) } } */
+/* { dg-output "\n0" } */
diff --git a/testsuite/poke.pkl/open-volatile-1.pk
b/testsuite/poke.pkl/open-volatile-1.pk
new file mode 100644
index 00000000..dd31c7fe
--- /dev/null
+++ b/testsuite/poke.pkl/open-volatile-1.pk
@@ -0,0 +1,8 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x90 0xa0 0xb0
0xc0} foo } */
+
+/* File IO spaces are non-volatile by default. */
+
+/* { dg-command {open ("foo")} } */
+/* { dg-command {iovolatile} } */
+/* { dg-output "0" } */
diff --git a/testsuite/poke.pkl/open-volatile-2.pk
b/testsuite/poke.pkl/open-volatile-2.pk
new file mode 100644
index 00000000..037c2556
--- /dev/null
+++ b/testsuite/poke.pkl/open-volatile-2.pk
@@ -0,0 +1,8 @@
+/* { dg-do run } */
+/* { dg-data {c*} {0x10 0x20 0x30 0x40 0x50 0x60 0x70 0x80 0x90 0xa0 0xb0
0xc0} foo } */
+
+/* IOS_F_VOLATILE turns out volatile in file IO spaces. */
+
+/* { dg-command {open ("foo", IOS_F_VOLATILE)} } */
+/* { dg-command {iovolatile} } */
+/* { dg-output "1" } */
--
2.30.2
- [COMMITTED] libpoke, poke: support for volatile/non-volatile IO spaces,
Jose E. Marchesi <=