summaryrefslogtreecommitdiffstats
path: root/qemu/roms/openbios/forth/device/device.fs
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/openbios/forth/device/device.fs')
-rw-r--r--qemu/roms/openbios/forth/device/device.fs202
1 files changed, 202 insertions, 0 deletions
diff --git a/qemu/roms/openbios/forth/device/device.fs b/qemu/roms/openbios/forth/device/device.fs
new file mode 100644
index 000000000..562c9196e
--- /dev/null
+++ b/qemu/roms/openbios/forth/device/device.fs
@@ -0,0 +1,202 @@
+\ tag: Package creation and deletion
+\
+\ this code implements IEEE 1275-1994
+\
+\ Copyright (C) 2003, 2004 Samuel Rydh
+\
+\ See the file "COPYING" for further information about
+\ the copyright and warranty status of this work.
+\
+
+variable device-tree
+
+\ make defined words globally visible
+\
+: external ( -- )
+ active-package ?dup if
+ >dn.methods @ set-current
+ then
+;
+
+\ make the private wordlist active (not an OF word)
+\
+: private ( -- )
+ active-package ?dup if
+ >r
+ forth-wordlist r@ >dn.methods @ r@ >dn.priv-methods @ 3 set-order
+ r> >dn.priv-methods @ set-current
+ then
+;
+
+\ set activate package and make the world visible package wordlist
+\ the current one.
+\
+: active-package! ( phandle -- )
+ dup to active-package
+ \ locally defined words are not available
+ ?dup if
+ forth-wordlist over >dn.methods @ 2 set-order
+ >dn.methods @ set-current
+ else
+ forth-wordlist dup 1 set-order set-current
+ then
+;
+
+
+\ new-device ( -- )
+\
+\ Start new package, as child of active package.
+\ Create a new device node as a child of the active package and make the
+\ new node the active package. Create a new instance and make it the current
+\ instance; the instance that invoked new-device becomes the parent instance
+\ of the new instance.
+\ Subsequently, newly defined Forth words become the methods of the new node
+\ and newly defined data items (such as types variable, value, buffer:, and
+\ defer) are allocated and stored within the new instance.
+
+: new-device ( -- )
+ align-tree dev-node.size alloc-tree >r
+ active-package
+ dup r@ >dn.parent !
+
+ \ ( parent ) hook up at the end of the peer list
+ ?dup if
+ >dn.child
+ begin dup @ while @ >dn.peer repeat
+ r@ swap !
+ else
+ \ we are the root node!
+ r@ to device-tree
+ then
+
+ \ ( -- ) fill in device node stuff
+ inst-node.size r@ >dn.isize !
+
+ \ create two wordlists
+ wordlist r@ >dn.methods !
+ wordlist r@ >dn.priv-methods !
+
+ \ initialize template data
+ r@ >dn.itemplate
+ r@ over >in.device-node !
+ my-self over >in.my-parent !
+
+ \ make it the active package and current instance
+ to my-self
+ r@ active-package!
+
+ \ swtich to public wordlist
+ external
+ r> drop
+;
+
+\ helpers for finish-device (OF does not actually define words
+\ for device node deletion)
+
+: (delete-device) \ ( phandle )
+ >r
+ r@ >dn.parent @
+ ?dup if
+ >dn.child \ ( &first-child )
+ begin dup @ r@ <> while @ >dn.peer repeat
+ r@ >dn.peer @ swap !
+ else
+ \ root node
+ 0 to device-tree
+ then
+
+ \ XXX: free any memory related to this node.
+ \ we could have a list with free device-node headers...
+ r> drop
+;
+
+: delete-device \ ( phandle )
+ >r
+ \ first, get rid of any children
+ begin r@ >dn.child @ dup while
+ (delete-device)
+ repeat
+ drop
+
+ \ then free this node
+ r> (delete-device)
+;
+
+\ finish-device ( -- )
+\
+\ Finish this package, set active package to parent.
+\ Complete a device node that was created by new-device, as follows: If the
+\ device node has no "name" property, remove the device node from the device
+\ tree. Otherwise, save the current values of the current instance's
+\ initialized data items within the active package for later use in
+\ initializing the data items of instances created from that node. In any
+\ case, destroy the current instance, make its parent instance the current
+\ instance, and select the parent node of the device node just completed,
+\ making the parent node the active package again.
+
+: finish-device \ ( -- )
+ my-self
+ dup >in.device-node @ >r
+ >in.my-parent @ to my-self
+
+ ( -- )
+ r@ >dn.parent @ active-package!
+ s" name" r@ get-package-property if
+ \ delete the node (and any children)
+ r@ delete-device
+ else
+ 2drop
+ \ node OK
+ then
+ r> drop
+;
+
+
+\ helper function which creates and initializes an instance.
+\ open is not called. The current instance is not changed.
+\
+: create-instance ( phandle -- ihandle|0 )
+ dup >dn.isize @ ['] alloc-mem catch if 2drop 0 exit then
+ >r
+ \ we need to save the size in order to be able to release it properly
+ dup >dn.isize @ r@ >in.alloced-size !
+
+ \ clear memory (we only need to clear the head; all other data is copied)
+ r@ inst-node.size 0 fill
+
+ ( phandle R: ihandle )
+
+ \ instantiate data
+ dup >dn.methods @ r@ instance-init
+ dup >dn.priv-methods @ r@ instance-init
+
+ \ instantiate
+ dup >dn.itemplate r@ inst-node.size move
+ r@ r@ >in.instance-data !
+ my-self r@ >in.my-parent !
+ drop
+
+ r>
+;
+
+\ helper function which tears down and frees an instance
+: destroy-instance ( ihandle )
+ ?dup if
+ \ free arguments
+ dup >in.arguments 2@ free-mem
+ \ and the instance block
+ dup >in.alloced-size @
+ free-mem
+ then
+;
+
+\ Redefine to word so that statements of the form "0 to active-package"
+\ are supported for bootloaders that require it
+: to
+ ['] ' execute
+ dup ['] active-package = if
+ drop active-package!
+ else
+ (to-xt)
+ then
+; immediate