Initial commit of OpenSPARC T2 architecture model.
[OpenSPARC-T2-SAM] / obp / obp / dev / sun4v-devices / iommu / iommu.fth
\ ========== Copyright Header Begin ==========================================
\
\ Hypervisor Software File: iommu.fth
\
\ Copyright (c) 2006 Sun Microsystems, Inc. All Rights Reserved.
\
\ - Do no alter or remove copyright notices
\
\ - Redistribution and use of this software in source and binary forms, with
\ or without modification, are permitted provided that the following
\ conditions are met:
\
\ - Redistribution of source code must retain the above copyright notice,
\ this list of conditions and the following disclaimer.
\
\ - Redistribution in binary form must reproduce the above copyright notice,
\ this list of conditions and the following disclaimer in the
\ documentation and/or other materials provided with the distribution.
\
\ Neither the name of Sun Microsystems, Inc. or the names of contributors
\ may be used to endorse or promote products derived from this software
\ without specific prior written permission.
\
\ This software is provided "AS IS," without a warranty of any kind.
\ ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES,
\ INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A
\ PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN
\ MICROSYSTEMS, INC. ("SUN") AND ITS LICENSORS SHALL NOT BE LIABLE FOR
\ ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
\ DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
\ OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
\ FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE
\ DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY,
\ ARISING OUT OF THE USE OF OR INABILITY TO USE THIS SOFTWARE, EVEN IF
\ SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
\
\ You acknowledge that this software is not designed, licensed or
\ intended for use in the design, construction, operation or maintenance of
\ any nuclear facility.
\
\ ========== Copyright Header End ============================================
id: @(#)iommu.fth 1.3 07/05/06
purpose:
copyright: Copyright 2007 Sun Microsystems, Inc. All Rights Reserved
copyright: Use is subject to license terms.
headerless
my-space h# fff.ffff and constant devhandle
0 constant tsbnum
1 constant pci-map-attr-read
2 constant pci-map-attr-write
pci-map-attr-read pci-map-attr-write or
constant io-attributes
h# b0 constant iommu-map-fun
h# b1 constant iommu-demap-fun
h# b2 constant iommu-getmap-fun
h# b3 constant iommu-getbypass-fun
h# b4 constant config-get-fun
h# b5 constant config-put-fun
h# b8 constant dma-sync-fun
h# 80 constant fast-trap#
1 constant pci-map-attr-read
2 constant pci-map-attr-write
pci-map-attr-read pci-map-attr-write or constant pci-map-attr
1 constant pci-sync-device
2 constant pci-sync-cpu
pci-sync-device pci-sync-cpu or constant pci-sync
variable dma-list dma-list off
virtual-dma-addr virtual-dma-size dma-list free-memrange
1 constant ENOCUP
2 constant ENORADDR
3 constant EOINTR
4 constant EBADPGSZ
5 constant EBADTSB
6 constant EINVAL
7 constant EBADTRAP
8 constant EBADALIGN
9 constant EWOULDBLOCK
d# 10 constant ENOACCESS
d# 11 constant EIO
d# 12 constant ECPUERROR
d# 13 constant ENOTSUPPORTED
d# 14 constant ENOMAP
d# 15 constant ETOOMANY
: fast-trap ( ??? #in #out fun# -- ??? )
dup >r fast-trap# htrap ( ??? status )( R: fun# )
r> swap ( ??? fun# status )
?dup if ( ??? fun# status| )
cmn-error[
case
ENOCUP of " ENOCUP" endof
ENORADDR of " Invalid real address" endof
EOINTR of " EOINTR" endof
EBADPGSZ of " EBADPGSZ" endof
EBADTSB of " EBADTSB" endof
EINVAL of " Invalid hypervisor argument(s)" endof
EBADTRAP of " EBADTRAP" endof
EBADALIGN of " Improperly aligned address" endof
EWOULDBLOCK of " EWOULDBLOCK" endof
ENOACCESS of " Access to real address offset not permitted" endof
EIO of " EIO" endof
ECPUERROR of " ECPUERROR" endof
ENOTSUPPORTED of " Hypervisor function not supported" endof
ENOMAP of " ENOMAP" endof
ETOOMANY of " ETOOMANY" endof
" Invalid Hypervisor error code" rot
endcase
rot " %s. function: %x" ]cmn-end
else ( ??? fun# )
drop ( ??? )
then ( ??? )
;
headers
: pci-config-get ( pci-device pci-config-offset size -- data error-flag )
>r >r >r devhandle r> r> r> ( devhandle pci-device pci-config-offset size )
4 3 config-get-fun fast-trap ( data error-flag )
;
: pci-config-put ( pci-device pci-config-offset size data -- error-flag )
>r >r >r >r devhandle r> r> r> r> ( devhandle pci-device pci-config-offset size data )
5 2 config-put-fun fast-trap ( error-flag )
;
: pci-iommu-getmap ( tsbindex -- raddr io-attributes )
devhandle swap 2 3 iommu-getmap-fun fast-trap
;
: (pci-iommu-map) ( tsbid #ttes io-page-list-p -- #ttes-actual )
>r >r >r devhandle r> r> pci-map-attr r> ( dev tsbid #ttes io-attributes io-page-list-p )
5 2 iommu-map-fun fast-trap ( #ttes-actual )
;
: pci-iommu-map ( tsbindex #ttes io-page-list-p -- )
begin ( tsbindex #ttes io-page-list-p )
over >r 3dup (pci-iommu-map) r> ( tsbindex #ttes io-page-list-p #ttes-actual #ttes )
over <> ( tsbindex #ttes io-page-list-p #ttes-actual more? )
while ( tsbindex #ttes io-page-list-p #ttes-actual )
tuck /x * + >r ( tsbindex #ttes #ttes-actual )( R: io-page-list-p' )
tuck - >r ( tsbindex #ttes-actual )( R: io-page-list-p' #ttes' )
+ r> r> ( tsbindex' #ttes' io-page-list-p' )( R: )
repeat ( tsbindex' #ttes' io-page-list-p' )
2drop 2drop ( )
;
: (pci-iommu-demap) ( tsbindex #ttes -- #ttes-actual )
>r >r devhandle r> r> ( dev tsbindex #ttes )
3 2 iommu-demap-fun fast-trap ( #ttes-actual )
;
: pci-iommu-demap ( tsbindex #ttes -- )
begin ( tsbindex #ttes )
dup ( tsbindex #ttes #ttes )
while
2dup (pci-iommu-demap) ( tsbindex #ttes #ttes-actual )
tuck - -rot + swap ( tsbindex' #ttes' )
repeat ( tsbindex' #ttes' )
2drop ( )
;
: (pci-dma-sync) ( raddr size io-sync-direction -- #synced )
>r devhandle -rot r> ( dev raddr size io-sync-direction )
4 2 dma-sync-fun fast-trap ( #synced )
;
: pci-dma-sync ( raddr size -- )
2dup >r >r ( raddr size ) ( R: raddr size )
begin ( raddr size )
dup ( raddr size size )
while
2dup pci-sync-cpu (pci-dma-sync) ( raddr size #synced )
tuck - -rot + swap ( raddr' size' )
repeat ( raddr' size' )
2drop ( )
r> r> ( raddr size )
begin ( raddr size )
dup ( raddr size size )
while ( raddr size )
2dup pci-sync-device (pci-dma-sync) ( raddr size #synced )
tuck - -rot + swap ( raddr' size' )
repeat ( raddr' size' )
2drop ( )
;
: setup-io-page-list ( raddr io-page-list #ttes -- )
0 ?do ( raddr io-page-list )
2dup x! /x + swap ( io-page-list' raddr )
mmu-pagesize + swap ( raddr' io-page-list' )
loop ( raddr' io-page-list' )
2drop ( )
;
external
: dma-alloc ( size -- vaddr ) mmu-pagesize swap 0 claim ;
: dma-free ( vaddr size -- ) swap release ;
: dma-sync ( virt-addr dev-addr size -- )
rot >physical drop swap ( dev-addr raddr size)
pci-dma-sync ( dev-addr )
drop
;
: dma-map-in ( virt size cache? -- dma-virt )
drop mmu-pagesize round-up ( virt size' )
mmu-pagesize over dma-list ( virt size align size list )
allocate-memrange throw dup >r ( virt size dma-virt )( R: dma-virt )
virtual-dma-base dup and32 - ( virt size offset )
mmu-pagesize / -rot ( tsbindex virt size )
mmu-pagesize / tuck tuck /x * ( tsbindex #ttes #ttes virt /io-page-list )
>r r@ /x swap 0 claim ( tsbindex #ttes #ttes virt io-page-list )( R: dma-virt /io-page-list )
dup >r swap ( tsbindex #ttes #ttes io-page-list virt )( R: dma-virt /io-page-list io-page-list )
>physical drop ( tsbindex #ttes #ttes io-page-list raddr )
swap rot setup-io-page-list ( tsbindex #ttes )
r@ >physical drop ( tsbindex #ttes io-page-list-p )( R: dma-virt /io-page-list io-page-list )
pci-iommu-map r> r> ( io-page-list /io-page-list )( R: dma-virt )
swap release r> ( dma-virt )( R: )
;
: dma-map-out ( virt dma-virt size -- )
mmu-pagesize round-up ( virt devadr size' )
2dup dma-list free-memrange ( virt devadr size' )
mmu-pagesize / swap ( virt #ttes devadr )
virtual-dma-base dup and32 - ( virt #ttes offset )
mmu-pagesize / swap ( virt tsbindex #ttes )
pci-iommu-demap drop ( )
;
headers
: dma-mapped? ( dma-virt -- raddr )
virtual-dma-base dup and32 - ( offset )
mmu-pagesize / ( tsbindex )
pci-iommu-getmap ( raddr attributes )
." attributes: 0x" .h cr ( raddr )
." raddr: 0x" .h ( )
;
headerless