diff mbox

[3/4] Add a global "dir" method

Message ID 1467857393-3728-3-git-send-email-benh@kernel.crashing.org
State Accepted
Headers show

Commit Message

Benjamin Herrenschmidt July 7, 2016, 2:09 a.m. UTC
This adds a method akin to "boot" and "load" which takes the subsequent
command line arguments, parses them as a device specification and
calls the dir method on said device

Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
 slof/fs/boot.fs               | 15 ++++++++++++
 slof/fs/packages/fat-files.fs | 56 ++++++++++++++++++++++++++++++++++---------
 2 files changed, 60 insertions(+), 11 deletions(-)

Comments

Alexey Kardashevskiy July 25, 2016, 5:45 a.m. UTC | #1
On 07/07/16 12:09, Benjamin Herrenschmidt wrote:
> This adds a method akin to "boot" and "load" which takes the subsequent
> command line arguments, parses them as a device specification and
> calls the dir method on said device

How is it supposed to work exactly? I made an 4G image, formatted as
"mkdosfs -F 32 -I /dev/sdb" and passed to QEMU as an USB stick:


0 > devalias
scsi : /pci@800000020000000/usb@0/storage@1
disk : /pci@800000020000000/usb@0/storage@1/disk@101000000000000
usb0 : /pci@800000020000000/usb@0
hvterm : /vdevice/vty@71000100
nvram : /vdevice/nvram@71000000 ok
0 > dir disk
Directory of: /pci@800000020000000/usb@0/storage@1/disk@101000000000000 ...
no dir method on target !

 ok
0 > dir disk,0
Directory of: disk,0 ...  ok
0 >    ok
0 >




> 
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
>  slof/fs/boot.fs               | 15 ++++++++++++
>  slof/fs/packages/fat-files.fs | 56 ++++++++++++++++++++++++++++++++++---------
>  2 files changed, 60 insertions(+), 11 deletions(-)
> 
> diff --git a/slof/fs/boot.fs b/slof/fs/boot.fs
> index e99a164..e436380 100644
> --- a/slof/fs/boot.fs
> +++ b/slof/fs/boot.fs
> @@ -174,6 +174,21 @@ defer go ( -- )
>  \ Generic device load method:
>  \ *
>  
> +: do-dir ( devstr len -- )
> +  cr ." Directory of: " 2dup type ."  ... "
> +  open-dev dup IF
> +    s" dir" 2 pick ['] $call-method CATCH IF
> +       ." no dir method on target !" cr
> +       3drop
> +    THEN
> +    close-dev cr
> +  ELSE drop THEN
> +;
> +
> +: dir ( "{devstring}" -- )
> +    parse-word de-alias do-dir
> +;
> +
>  : do-load ( devstr len -- img-size )	\ Device method wrapper
>     use-load-watchdog? IF
>        \ Set watchdog timer to 10 minutes, multiply with 2 because DHCP
> diff --git a/slof/fs/packages/fat-files.fs b/slof/fs/packages/fat-files.fs
> index 9e389eb..e5b08bd 100644
> --- a/slof/fs/packages/fat-files.fs
> +++ b/slof/fs/packages/fat-files.fs
> @@ -33,6 +33,8 @@ INSTANCE VARIABLE root-offset
>  INSTANCE VARIABLE cluster-offset
>  INSTANCE VARIABLE #clusters
>  
> +INSTANCE VARIABLE dir?
> +
>  : seek  s" seek" $call-parent ;
>  : read  s" read" $call-parent ;
>  
> @@ -54,7 +56,7 @@ CREATE fat-buf 8 allot
>    fat-buf 8 read 8 <> ABORT" fat-files read-fat: read failed"
>    fat-buf 8c@ bxjoin fat-type @ dup >r 2* #split drop r> #split
>    rot IF swap THEN drop ;
> -  
> +
>  INSTANCE VARIABLE next-cluster
>  
>  : read-cluster ( cluster# -- )
> @@ -129,14 +131,35 @@ CREATE dos-name b allot
>  : find-file ( dir-cluster name len -- cluster file-len is-dir? true | false )
>    make-dos-name read-dir BEGIN (find-file) 0= WHILE next-cluster @ WHILE
>    next-cluster @ read-cluster REPEAT false ELSE true THEN ;
> -: find-path ( dir-cluster name len -- cluster file-len true | false )
> -  dup 0= IF 3drop false ."  empty name " EXIT THEN
> -  over c@ [char] \ = IF 1 /string  RECURSE EXIT THEN
> -  [char] \ split 2>r find-file 0= IF 2r> 2drop false ."  not found " EXIT THEN
> -  r@ 0<> <> IF 2drop 2r> 2drop false ."  no dir<->file match " EXIT THEN
> -  r@ 0<> IF drop 2r> RECURSE EXIT THEN
> -  2r> 2drop true ;
> -  
> +
> +: find-path ( dir-cluster name len -- cluster file-len is-dir? true | false )
> +  dup 0= IF
> +    \ empty name, assume directory
> +    2drop 0 true true EXIT
> +  THEN
> +  \ Strip leading backslashes
> +  over c@ [char] \ = IF
> +    1 /string  RECURSE EXIT
> +  THEN
> +  \ Split at backslash
> +  [char] \ split
> +  \ Store right side on return stack
> +  2>r
> +  find-file
> +  0= IF
> +    2r> 2drop false ."  not found " EXIT
> +  THEN
> +  \ right side (from stack) has non-0 len, must be a dir
> +  dup 0= r@ 0<> and IF
> +     3drop 2r> 2drop false ." path component not a dir " EXIT
> +  THEN
> +  r@ 0<> IF
> +    2drop 2r> RECURSE EXIT
> +  THEN
> +  2r> 2drop
> +  true
> +;
> +
>  : do-super ( -- )
>    0 200 read-data
>    data @ 0b + 2c@ bwjoin bytes/sector !
> @@ -203,7 +226,18 @@ INSTANCE VARIABLE pos-in-data
>    file-len @ read dup file-len @ <> ABORT" fat-files: failed loading file" ;
>  
>  : close  free-data ;
> +
> +: dir
> +  dir? @ IF file-cluster @ .dir ELSE ." not a directory!" cr THEN
> +  ;
> +
>  : open
>    do-super
> -  0 my-args find-path 0= IF close false EXIT THEN
> -  file-len !  file-cluster !  0 0 seek 0= ;
> +  0 my-args find-path
> +  0= IF free-data false EXIT
> +  THEN
> +  dir? ! file-len !  file-cluster !
> +  dir? @ IF
> +    0 0 seek 0=
> +  ELSE true THEN
> +;
>
diff mbox

Patch

diff --git a/slof/fs/boot.fs b/slof/fs/boot.fs
index e99a164..e436380 100644
--- a/slof/fs/boot.fs
+++ b/slof/fs/boot.fs
@@ -174,6 +174,21 @@  defer go ( -- )
 \ Generic device load method:
 \ *
 
+: do-dir ( devstr len -- )
+  cr ." Directory of: " 2dup type ."  ... "
+  open-dev dup IF
+    s" dir" 2 pick ['] $call-method CATCH IF
+       ." no dir method on target !" cr
+       3drop
+    THEN
+    close-dev cr
+  ELSE drop THEN
+;
+
+: dir ( "{devstring}" -- )
+    parse-word de-alias do-dir
+;
+
 : do-load ( devstr len -- img-size )	\ Device method wrapper
    use-load-watchdog? IF
       \ Set watchdog timer to 10 minutes, multiply with 2 because DHCP
diff --git a/slof/fs/packages/fat-files.fs b/slof/fs/packages/fat-files.fs
index 9e389eb..e5b08bd 100644
--- a/slof/fs/packages/fat-files.fs
+++ b/slof/fs/packages/fat-files.fs
@@ -33,6 +33,8 @@  INSTANCE VARIABLE root-offset
 INSTANCE VARIABLE cluster-offset
 INSTANCE VARIABLE #clusters
 
+INSTANCE VARIABLE dir?
+
 : seek  s" seek" $call-parent ;
 : read  s" read" $call-parent ;
 
@@ -54,7 +56,7 @@  CREATE fat-buf 8 allot
   fat-buf 8 read 8 <> ABORT" fat-files read-fat: read failed"
   fat-buf 8c@ bxjoin fat-type @ dup >r 2* #split drop r> #split
   rot IF swap THEN drop ;
-  
+
 INSTANCE VARIABLE next-cluster
 
 : read-cluster ( cluster# -- )
@@ -129,14 +131,35 @@  CREATE dos-name b allot
 : find-file ( dir-cluster name len -- cluster file-len is-dir? true | false )
   make-dos-name read-dir BEGIN (find-file) 0= WHILE next-cluster @ WHILE
   next-cluster @ read-cluster REPEAT false ELSE true THEN ;
-: find-path ( dir-cluster name len -- cluster file-len true | false )
-  dup 0= IF 3drop false ."  empty name " EXIT THEN
-  over c@ [char] \ = IF 1 /string  RECURSE EXIT THEN
-  [char] \ split 2>r find-file 0= IF 2r> 2drop false ."  not found " EXIT THEN
-  r@ 0<> <> IF 2drop 2r> 2drop false ."  no dir<->file match " EXIT THEN
-  r@ 0<> IF drop 2r> RECURSE EXIT THEN
-  2r> 2drop true ;
-  
+
+: find-path ( dir-cluster name len -- cluster file-len is-dir? true | false )
+  dup 0= IF
+    \ empty name, assume directory
+    2drop 0 true true EXIT
+  THEN
+  \ Strip leading backslashes
+  over c@ [char] \ = IF
+    1 /string  RECURSE EXIT
+  THEN
+  \ Split at backslash
+  [char] \ split
+  \ Store right side on return stack
+  2>r
+  find-file
+  0= IF
+    2r> 2drop false ."  not found " EXIT
+  THEN
+  \ right side (from stack) has non-0 len, must be a dir
+  dup 0= r@ 0<> and IF
+     3drop 2r> 2drop false ." path component not a dir " EXIT
+  THEN
+  r@ 0<> IF
+    2drop 2r> RECURSE EXIT
+  THEN
+  2r> 2drop
+  true
+;
+
 : do-super ( -- )
   0 200 read-data
   data @ 0b + 2c@ bwjoin bytes/sector !
@@ -203,7 +226,18 @@  INSTANCE VARIABLE pos-in-data
   file-len @ read dup file-len @ <> ABORT" fat-files: failed loading file" ;
 
 : close  free-data ;
+
+: dir
+  dir? @ IF file-cluster @ .dir ELSE ." not a directory!" cr THEN
+  ;
+
 : open
   do-super
-  0 my-args find-path 0= IF close false EXIT THEN
-  file-len !  file-cluster !  0 0 seek 0= ;
+  0 my-args find-path
+  0= IF free-data false EXIT
+  THEN
+  dir? ! file-len !  file-cluster !
+  dir? @ IF
+    0 0 seek 0=
+  ELSE true THEN
+;