Annotation of qemu/roms/openbios/forth/device/pathres.fs, revision 1.1

1.1     ! root        1: \ tag: Path resolution
        !             2: \ 
        !             3: \ this code implements IEEE 1275-1994 path resolution
        !             4: \ 
        !             5: \ Copyright (C) 2003 Samuel Rydh
        !             6: \ 
        !             7: \ See the file "COPYING" for further information about
        !             8: \ the copyright and warranty status of this work.
        !             9: \ 
        !            10: 
        !            11: 0 value interpose-ph
        !            12: 0 0 create interpose-args , ,
        !            13: 
        !            14: : expand-alias ( alias-addr alias-len -- exp-addr exp-len expanded? )
        !            15:   2dup
        !            16:   " /aliases" find-dev 0= if 2drop false exit then
        !            17:   get-package-property if
        !            18:     false
        !            19:   else
        !            20:     2swap 2drop 
        !            21:     \ drop trailing 0 from string
        !            22:     dup if 1- then
        !            23:     true
        !            24:   then
        !            25: ;
        !            26: 
        !            27: \ 
        !            28: \ 4.3.1 Resolve aliases
        !            29: \ 
        !            30: 
        !            31: \ the returned string is allocated with alloc-mem
        !            32: : pathres-resolve-aliases ( path-addr path-len -- path-addr path-len )
        !            33:   over c@ 2f <> if
        !            34:     200 here + >r                \ abuse dictionary for temporary storage
        !            35: 
        !            36:     \ If the pathname does not begin with "/", and its first node name 
        !            37:     \ component is an alias, replace the alias with its expansion.
        !            38:     ascii / split-before         \ (PATH_NAME, "/")  -> (TAIL HEAD)
        !            39:     ascii : split-before         \ (HEAD, ":")  ->  (ALIAS_ARGS AL_NAME)
        !            40:     expand-alias                 ( TAIL ALIAS_ARGS EXP_ALIAS_NAME expanded? )
        !            41:     if
        !            42:       2 pick 0<> if              \ If ALIAS_ARGS is not empty
        !            43:         ascii / split-after      \ (ALIAS_NAME, "/") -> (AL_TAIL AL_HEAD/)
        !            44:         2swap                    ( TAIL AL_HEAD/ AL_TAIL )
        !            45:         ascii : split-before     \ (AL_TAIL, ":") -> (DEAD_ARGS AL_TAIL)
        !            46:         2swap 2drop              ( TAIL AL_ARGS AL_HEAD ALIAS_TAIL )
        !            47:         2swap                    ( TAIL AL_ARGS AL_TAIL AL_HEAD )
        !            48:         r> tmpstrcat tmpstrcat >r
        !            49:       else
        !            50:         2swap 2drop              \ drop ALIAS_ARGS
        !            51:       then
        !            52:       r> tmpstrcat drop
        !            53:     else
        !            54:       \ put thing back together again
        !            55:       r> tmpstrcat tmpstrcat drop
        !            56:     then
        !            57:   then  
        !            58: 
        !            59:   strdup
        !            60:   ( path-addr path-len )
        !            61: ;
        !            62: 
        !            63: \ 
        !            64: \ search struct
        !            65: \ 
        !            66: 
        !            67: struct ( search information )
        !            68:   2 cells field >si.path
        !            69:   2 cells field >si.arguments
        !            70:   2 cells field >si.unit_addr
        !            71:   2 cells field >si.node_name
        !            72:   2 cells field >si.free_me
        !            73:   4 cells field >si.unit_phys
        !            74:   /n field >si.unit_phys_len
        !            75:   /n field >si.save-ihandle
        !            76:   /n field >si.save-phandle
        !            77:   /n field >si.top-ihandle
        !            78:   /n field >si.top-opened        \ set after successful open
        !            79:   /n field >si.child            \ node to match
        !            80: constant sinfo.size
        !            81: 
        !            82: 
        !            83: \ 
        !            84: \ 4.3.6 node name match criteria
        !            85: \ 
        !            86: 
        !            87: : match-nodename ( childname len sinfo -- match? )
        !            88:   >r
        !            89:   2dup r@ >si.node_name 2@
        !            90:   ( [childname] [childname] [nodename] )
        !            91:   strcmp 0= if r> 3drop true exit then
        !            92: 
        !            93:   \ does NODE_NAME contain a comma?
        !            94:   r@ >si.node_name 2@ ascii , strchr
        !            95:   if r> 3drop false exit then
        !            96: 
        !            97:   ( [childname] )
        !            98:   ascii , left-split 2drop r@ >si.node_name 2@
        !            99:   r> drop
        !           100:   strcmp if false else true then
        !           101: ;
        !           102: 
        !           103: 
        !           104: \ 
        !           105: \ 4.3.4 exact match child node
        !           106: \ 
        !           107: 
        !           108: \ If NODE_NAME is not empty, make sure it matches the name property
        !           109: : common-match ( sinfo -- )
        !           110:   >r
        !           111:   \ a) NODE_NAME nonempty
        !           112:   r@ >si.node_name 2@ nip if
        !           113:     " name" r@ >si.child @ get-package-property if -1 throw then
        !           114:     \ name is supposed to be null-terminated
        !           115:     dup 0> if 1- then
        !           116:     \ exit if NODE_NAME does not match
        !           117:     r@ match-nodename 0= if -2 throw then
        !           118:   then
        !           119:   r> drop
        !           120: ;
        !           121:   
        !           122: : (exact-match) ( sinfo -- )
        !           123:   >r
        !           124:   \ a) If NODE_NAME is not empty, make sure it matches the name property
        !           125:   r@ common-match
        !           126: 
        !           127:   \ b) UNIT_PHYS nonempty?
        !           128:   r@ >si.unit_phys_len @ /l* ?dup if
        !           129:     \ check if unit_phys matches
        !           130:     " reg" r@ >si.child @ get-package-property if -3 throw then
        !           131:     ( unitbytes propaddr proplen )
        !           132:     rot r@ >si.unit_phys -rot
        !           133:     ( propaddr unit_phys proplen unitbytes )
        !           134:     swap over < if -4 throw then
        !           135:     comp if -5 throw then
        !           136:   else
        !           137:     \ c) both NODE_NAME and UNIT_PHYS empty?
        !           138:     r@ >si.node_name 2@ nip 0= if -6 throw then
        !           139:   then
        !           140: 
        !           141:   r> drop
        !           142: ;
        !           143: 
        !           144: : exact-match ( sinfo -- match? )
        !           145:   ['] (exact-match) catch if drop false exit then
        !           146:   true
        !           147: ;
        !           148: 
        !           149: \ 
        !           150: \ 4.3.5 wildcard match child node
        !           151: \ 
        !           152: 
        !           153: : (wildcard-match) ( sinfo -- match? )
        !           154:   >r
        !           155:   \ a) If NODE_NAME is not empty, make sure it matches the name property
        !           156:   r@ common-match
        !           157: 
        !           158:   \ b) Fail if "reg" property exist
        !           159:   " reg" r@ >si.child @ get-package-property 0= if -7 throw then
        !           160: 
        !           161:   \ c) Fail if both NODE_NAME and UNIT_ADDR are both empty
        !           162:   r@ >si.unit_phys_len @
        !           163:   r@ >si.node_name 2@ nip
        !           164:   or 0= if -1 throw then
        !           165: 
        !           166:   \ SUCCESS
        !           167:   r> drop
        !           168: ;
        !           169: 
        !           170: : wildcard-match ( sinfo -- match? )
        !           171:   ['] (wildcard-match) catch if drop false exit then
        !           172:   true
        !           173: ;
        !           174: 
        !           175: 
        !           176: \ 
        !           177: \ 4.3.3 match child node
        !           178: \ 
        !           179: 
        !           180: : find-child ( sinfo -- phandle )
        !           181:   >r
        !           182:   \ decode unit address string
        !           183:   r@ >si.unit_addr 2@ dup if
        !           184:     ( str len )
        !           185:     " decode-unit" active-package find-method
        !           186:     if
        !           187:       depth 3 - >r execute depth r@ - r> swap
        !           188:       ( ... a_lo ... a_hi olddepth n )
        !           189:       4 min 0 max
        !           190:       dup r@ >si.unit_phys_len !
        !           191:       ( ... a_lo ... a_hi olddepth n )
        !           192:       r@ >si.unit_phys >r
        !           193:       begin 1- dup 0>= while
        !           194:         rot r> dup la1+ >r l!-be
        !           195:       repeat
        !           196:       r> 2drop
        !           197:       depth!
        !           198:     else
        !           199:       \ no decode-unit method... failure
        !           200:       -99 throw
        !           201:     then
        !           202:   else
        !           203:     2drop
        !           204:     \ clear unit_phys
        !           205:     0 r@ >si.unit_phys_len !
        !           206:     \ r@ >si.unit_phys 4 cells 0 fill
        !           207:   then
        !           208: 
        !           209:   ( R: sinfo )
        !           210:   ['] exact-match
        !           211:   begin dup while
        !           212:     active-package >dn.child @
        !           213:     begin ?dup while
        !           214:       dup r@ >si.child !
        !           215:       ( xt phandle R: sinfo )
        !           216:       r@ 2 pick execute if 2drop r> >si.child @ exit then
        !           217:       >dn.peer @
        !           218:     repeat
        !           219:     ['] exact-match = if ['] wildcard-match else 0 then
        !           220:   repeat
        !           221: 
        !           222:   -99 throw  
        !           223: ;
        !           224: 
        !           225: 
        !           226: \ 
        !           227: \ 4.3.2 Create new linked instance procedure
        !           228: \ 
        !           229: 
        !           230: : link-one ( sinfo -- )
        !           231:   >r
        !           232:   active-package create-instance
        !           233:   dup 0= if -99 throw then
        !           234: 
        !           235:   \ change instance parent
        !           236:   r@ >si.top-ihandle @ over >in.my-parent !
        !           237:   dup r@ >si.top-ihandle !
        !           238:   to my-self
        !           239: 
        !           240:   \ b) set my-args field
        !           241:   r@ >si.arguments 2@ strdup my-self >in.arguments 2!
        !           242:   
        !           243:   \ e) set my-unit field
        !           244:   r@ >si.unit_addr 2@ nip if
        !           245:     \ copy UNIT_PHYS to the my-unit field
        !           246:     r@ >si.unit_phys my-self >in.my-unit 4 cells move
        !           247:   else
        !           248:     \ set unit-addr from reg property
        !           249:     " reg" active-package get-package-property 0= if
        !           250:       \ ( ihandle prop proplen )
        !           251:       \ copy address to my-unit
        !           252:       4 cells min my-self >in.my-unit swap move
        !           253:     else
        !           254:       \ clear my-unit
        !           255:       my-self >in.my-unit 4 cells 0 fill
        !           256:     then
        !           257:   then
        !           258: 
        !           259:   \ top instance has not been opened (yet)
        !           260:   false r> >si.top-opened !
        !           261: ;
        !           262: 
        !           263: : invoke-open ( sinfo -- )
        !           264:   " open" my-self ['] $call-method
        !           265:   catch if 3drop false then
        !           266:   0= if -99 throw then
        !           267:     
        !           268:   true swap >si.top-opened !
        !           269: ;
        !           270: 
        !           271: \ 
        !           272: \ 4.3.7 Handle interposers procedure (supplement)
        !           273: \ 
        !           274: 
        !           275: : handle-interposers ( sinfo -- )
        !           276:   >r
        !           277:   begin
        !           278:     interpose-ph ?dup 
        !           279:   while
        !           280:     0 to interpose-ph
        !           281:     active-package swap active-package!
        !           282: 
        !           283:     \ clear unit address and set arguments
        !           284:     0 0 r@ >si.unit_addr 2!
        !           285:     interpose-args 2@ r@ >si.arguments 2!
        !           286:     r@ link-one
        !           287:     true my-self >in.interposed !
        !           288:     interpose-args 2@ free-mem
        !           289:     r@ invoke-open
        !           290: 
        !           291:     active-package!
        !           292:   repeat
        !           293: 
        !           294:   r> drop
        !           295: ;
        !           296: 
        !           297: \ 
        !           298: \ 4.3.1 Path resolution procedure
        !           299: \ 
        !           300: 
        !           301: \ close-dev ( ihandle -- )
        !           302: \ 
        !           303: : close-dev 
        !           304:   begin
        !           305:     dup 
        !           306:   while
        !           307:     dup >in.my-parent @
        !           308:     swap close-package
        !           309:   repeat
        !           310:   drop
        !           311: ;
        !           312: 
        !           313: : path-res-cleanup ( sinfo close? )
        !           314: 
        !           315:   \ tear down all instances if close? is set
        !           316:   if
        !           317:     dup >si.top-opened @ if
        !           318:       dup >si.top-ihandle @
        !           319:       ?dup if close-dev then
        !           320:     else
        !           321:       dup >si.top-ihandle @ dup
        !           322:       ( sinfo ihandle ihandle )
        !           323:       dup if >in.my-parent @ swap then
        !           324:       ( sinfo parent ihandle )
        !           325:       ?dup if destroy-instance then
        !           326:       ?dup if close-dev then
        !           327:     then
        !           328:   then
        !           329: 
        !           330:   \ restore active-package and my-self
        !           331:   dup >si.save-ihandle @ to my-self
        !           332:   dup >si.save-phandle @ active-package!
        !           333: 
        !           334:   \ free any allocated memory
        !           335:   dup >si.free_me 2@ free-mem
        !           336:   sinfo.size free-mem
        !           337: ;
        !           338: 
        !           339: : (path-resolution) ( context sinfo -- )
        !           340:   >r r@ >si.path 2@
        !           341:   ( context pathstr pathlen )
        !           342: 
        !           343:   \ this allocates a copy of the string
        !           344:   pathres-resolve-aliases
        !           345:   2dup r@ >si.free_me 2!
        !           346: 
        !           347:   \ If the pathname, after possible alias expansion, begins with "/",
        !           348:   \ begin the search at the root node. Otherwise, begin at the active
        !           349:   \ package.
        !           350: 
        !           351:   dup if                    \ make sure string is not empty
        !           352:     over c@ 2f = if
        !           353:       swap char+ swap /c -  \ Remove the "/" from PATH_NAME.
        !           354:       \ Set the active package to the root node.
        !           355:       device-tree @ active-package!
        !           356:     then
        !           357:   then
        !           358: 
        !           359:   r@ >si.path 2!
        !           360:   0 0 r@ >si.unit_addr 2!
        !           361:   0 0 r@ >si.arguments 2!
        !           362:   0 r@ >si.top-ihandle !
        !           363: 
        !           364:   \ If there is no active package, exit this procedure, returning false.
        !           365:   ( context )
        !           366:   active-package 0= if -99 throw then
        !           367: 
        !           368:   \ Begin the creation of an instance chain.
        !           369:   \ NOTE--If, at this step, the active package is not the root node and 
        !           370:   \ we are in open-dev or execute-device-method contexts, the instance 
        !           371:   \ chain that results from the path resolution process may be incomplete.
        !           372: 
        !           373:   active-package swap
        !           374:   ( virt-active-node context )
        !           375:   begin
        !           376:     r@ >si.path 2@ nip          \ nonzero path?
        !           377:   while
        !           378:     \ ( active-node context )
        !           379:     \ is this open-dev or execute-device-method context?
        !           380:     dup if
        !           381:       r@ link-one
        !           382:       over active-package <> my-self >in.interposed !
        !           383:       r@ invoke-open
        !           384:       r@ handle-interposers
        !           385:     then
        !           386:     over active-package!
        !           387: 
        !           388:     r@ >si.path 2@              ( PATH )
        !           389:     
        !           390:     ascii / left-split          ( PATH COMPONENT )
        !           391:     ascii : left-split          ( PATH ARGS NODE_ADDR )
        !           392:     ascii @ left-split          ( PATH ARGS UNIT_ADDR NODE_NAME )
        !           393: 
        !           394:     r@ >si.node_name 2!
        !           395:     r@ >si.unit_addr 2!
        !           396:     r@ >si.arguments 2!
        !           397:     r@ >si.path 2!
        !           398: 
        !           399:     ( virt-active-node context )
        !           400: 
        !           401:     \ 4.3.1 i) pathname has a leading %?
        !           402:     r@ >si.node_name 2@ 2dup 2dup ascii % strchr nip = if
        !           403:       1- swap 1+ swap r@ >si.node_name 2!
        !           404:       " /packages" find-dev drop active-package!
        !           405:       r@ find-child
        !           406:     else
        !           407:       2drop
        !           408:       nip r@ find-child swap over
        !           409:       ( new-node context new-node )
        !           410:     then
        !           411: 
        !           412:     \ (optional: open any nodes between parent and child )
        !           413: 
        !           414:     active-package!
        !           415:   repeat
        !           416: 
        !           417:   ( virt-active-node type )
        !           418:   dup if r@ link-one then
        !           419:   1 = if
        !           420:     dup active-package <> my-self >in.interposed !
        !           421:     r@ invoke-open 
        !           422:     r@ handle-interposers
        !           423:   then
        !           424:   active-package!
        !           425: 
        !           426:   r> drop
        !           427: ;
        !           428: 
        !           429: : path-resolution ( context path-addr path-len -- sinfo true | false )
        !           430:   \ allocate and clear the search block
        !           431:   sinfo.size alloc-mem >r      
        !           432:   r@ sinfo.size 0 fill
        !           433: 
        !           434:   \ store path
        !           435:   r@ >si.path 2!
        !           436: 
        !           437:   \ save ihandle and phandle
        !           438:   my-self r@ >si.save-ihandle !
        !           439:   active-package r@ >si.save-phandle !
        !           440:   
        !           441:   \ save context (if we take an exception)
        !           442:   dup
        !           443: 
        !           444:   r@ ['] (path-resolution)
        !           445:   catch ?dup if
        !           446:     ( context xxx xxx error )
        !           447:     r> true path-res-cleanup
        !           448: 
        !           449:     \ rethrow everything except our "cleanup throw"
        !           450:     dup -99 <> if throw then
        !           451:     3drop
        !           452: 
        !           453:     \ ( context ) throw an exception if this is find-device context
        !           454:     if false else -22 throw then
        !           455:     exit
        !           456:   then
        !           457: 
        !           458:   \ ( context )
        !           459:   drop r> true
        !           460:   ( sinfo true )
        !           461: ;
        !           462: 
        !           463: 
        !           464: : open-dev ( dev-str dev-len -- ihandle | 0 )
        !           465:   1 -rot path-resolution 0= if false exit then
        !           466: 
        !           467:   ( sinfo )
        !           468:   my-self swap
        !           469:   false path-res-cleanup
        !           470: 
        !           471:   ( ihandle )
        !           472: ;
        !           473: 
        !           474: : execute-device-method
        !           475: ( ... dev-str dev-len met-str met-len -- ... false | ?? true )
        !           476:   2swap
        !           477:   2 -rot path-resolution 0= if 2drop false exit then
        !           478:   ( method-str method-len sinfo )
        !           479:   >r
        !           480:   my-self ['] $call-method catch
        !           481:   if 3drop false else true then
        !           482:   r> true path-res-cleanup
        !           483: ;
        !           484: 
        !           485: : find-device ( dev-str dev-len -- )
        !           486:   2dup " .." strcmp 0= if
        !           487:     2drop
        !           488:     active-package dup if >dn.parent @ then
        !           489:     \ ".." in root note?
        !           490:     dup 0= if -22 throw then
        !           491:     active-package!
        !           492:     exit
        !           493:   then
        !           494:   0 -rot path-resolution 0= if false exit then
        !           495:   ( sinfo )
        !           496:   active-package swap
        !           497:   true path-res-cleanup
        !           498:   active-package!
        !           499: ;
        !           500: 
        !           501: \ find-device, but without side effects
        !           502: : (find-dev) ( dev-str dev-len -- phandle true | false )
        !           503:   active-package -rot
        !           504:   ['] find-device catch if 3drop false exit then
        !           505:   active-package swap active-package! true
        !           506: ;
        !           507: 
        !           508: \ Tuck on a node at the end of the chain being created.
        !           509: \ This implementation follows the interpose recommended practice
        !           510: \ (v0.2 draft).
        !           511: 
        !           512: : interpose ( arg-str arg-len phandle -- )
        !           513:   to interpose-ph
        !           514:   strdup interpose-args 2!
        !           515: ;
        !           516: 
        !           517: ['] (find-dev) to find-dev

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.