blob: fa2956572570bf4a920bf4d64db508912ec3a57f [file] [log] [blame]
\ See license at end of file
purpose: Virtual address space allocator
\ allocate-virtual ( phys space size -- phys space adr )
\ Allocates at least "size" bytes of virtual memory. The actual
\ allocation size is "size" rounded up to a multiple of the page size.
headers
list: fwvirt \ Virtual memory available list
list: osvirt \ Virtual memory that the OS can use but the firmware can't
headerless
: (claim-virt-callback)
( aln|adr size aln size max min -- aln|adr size false | virt true )
4 " claim-virt" ($callback) if ( adr size )
\ There was no "claim-virt" callback, so we return false to
\ indicate that the firmware should proceed.
false ( adr size false )
else ( adr size [ virt ] err? n )
\ There was a "claim-virt" callback. If it succeeded, we return
\ the result under true to indicate that the operation has
\ been performed. If it failed, we throw the error because we
\ are no longer in charge of allocation services.
drop throw ( aln size virt )
nip nip true
then
;
: alloc-virt-callback? ( aln size -- aln size false | virt true )
2dup -1 0 (claim-virt-callback)
;
: claim-virt-callback? ( adr size -- adr size false | virt true )
2dup pagesize -rot swap dup (claim-virt-callback)
;
: release-virt-callback? ( adr size -- true | adr size false )
2dup 2 " release-virt" ($callback) if ( adr size )
\ There was no "release-virt" callback, so we return false to
\ indicate that the firmware should proceed.
false ( adr size false )
else ( adr size err? n )
\ There was a "release-virt" callback. If it failed, oh well.
\ Discard the arguments and return true to indicate that the
\ operation has been done.
2drop 2drop true
then
;
\ Frees the virtual address range "adr len"
: noreclaim-free-virtual ( adr len -- )
>page-boundaries
over fw-virt-base dup fw-virt-size + within if ( adr len )
fwvirt
else ( adr len )
osvirt
then ( adr len memorylist )
['] 2drop is ?splice ( adr len memorylist )
free-memrange
;
headers
\ Frees virtual memory, but not the physical memory behind it
: free-virtual-only ( adr len -- )
>page-boundaries
noreclaim-free-virtual
;
\ Allocates at least "size" bytes of virtual memory for mapping the
\ physical address "phys".
: allocate-aligned-virtual ( phys space alignment size -- phys space virt-adr )
\ Minumum granularity of memory chunks is 1 page
swap pagesize round-up
swap pagesize round-up ( phys space alignment+ size+ )
alloc-virt-callback? if exit then ( phys space alignment+ size+ )
2dup fwvirt allocate-memrange if ( phys space aln size )
osvirt allocate-memrange ( phys space [ adr ] error? )
abort" Insufficient virtual memory" ( phys space adr )
else ( phys space aln size adr )
nip nip ( phys space adr )
then
;
: allocate-virtual ( phys space size -- phys space virt )
1 swap allocate-aligned-virtual
;
headerless
: claim-virtual ( adr size -- adr )
over >r >page-boundaries ( adr,len' )
claim-virt-callback? if drop r> exit then ( adr,len' )
\ Look first in the monitor's piece list
fwvirt ['] contained? find-node ( adr,len' prev next|0 )
dup 0= if
\ If not found in the monitor's virtual list, look in
\ the OS's virtual list.
2drop
osvirt ['] contained? find-node ( adr,len' prev next|0 )
then
dup 0= abort" Virtual address already used" ( adr,len' prev next )
is next-node is prev-node ( adr,len' )
\ There are 4 cases to consider in removing the requested virtual
\ address range from the list:
\ (1) The requested range exactly matches the list node range
\ (2) The requested range is at the beginning of the list node range
\ (3) The requested range is at the end of the list node range
\ (4) The requested range is in the middle of the list node range
\ Remember the range of the node to be deleted
next-node node-range ( adr,len' node-a,l )
\ Remove the node from the list
prev-node delete-after memrange free-node ( adr,len' node-a,l )
\ Give back any left-over portion at the beginning
over 4 pick over - ( adr,len' node-a,l begin-a,l )
dup if noreclaim-free-virtual else 2drop then ( adr,len' node-a,l )
\ Give back any left-over portion at the end
2over + -rot + over - ( adr,len' end-a,l )
dup if noreclaim-free-virtual else 2drop then ( adr,len' )
2drop ( )
r> ( adr )
;
: add-os-piece ( start-adr end-adr -- )
2dup = if 2drop exit then
over - set-node osvirt insert-after
;
headers
external
: claim ( [ virt ] size align -- base )
?dup if ( size align )
\ Alignment should be next power of two
swap allocate-aligned-virtual ( base )
else ( virt size )
claim-virtual ( base )
then ( base )
;
: release ( virt size -- )
release-virt-callback? if exit then
free-virtual-only
;
pagesize constant pagesize
headerless
\ : range>reg ( start end -- ) over - 0 swap encode-reg ;
: make-virt-memlist ( adr len node-adr -- adr len' false )
node-range ( lo size )
>r encode-int encode+
r> encode-int encode+
false
;
headers
5 actions
action: drop
0 0 encode-bytes \ "prime" the property-encoded array
\ Append the pieces from the non-PROM virtual memory list
osvirt ['] make-virt-memlist find-node 2drop ( adr len )
\ Append the pieces from the virtual memory free list
fwvirt ['] make-virt-memlist find-node 2drop ( adr len )
over here - allot ( adr len )
;
action: drop 2drop ;
action: ;
action: drop ;
action: drop ;
" available" make-property-name use-actions
\ LICENSE_BEGIN
\ Copyright (c) 2006 FirmWorks
\
\ Permission is hereby granted, free of charge, to any person obtaining
\ a copy of this software and associated documentation files (the
\ "Software"), to deal in the Software without restriction, including
\ without limitation the rights to use, copy, modify, merge, publish,
\ distribute, sublicense, and/or sell copies of the Software, and to
\ permit persons to whom the Software is furnished to do so, subject to
\ the following conditions:
\
\ The above copyright notice and this permission notice shall be
\ included in all copies or substantial portions of the Software.
\
\ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
\ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
\ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
\ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\
\ LICENSE_END