[SLOF] [PATCH slof] pci-phb: Reimplement dma-map-in/out

Alexey Kardashevskiy aik at ozlabs.ru
Thu Nov 14 14:33:41 AEDT 2019


The immediate problem with the code is that it relies on memory allocator
aligning addresses to the size. This is true for SLOF but not for GRUB
and in unaligned situations we end up mapping more pages than bm-alloc
allocated.

This fixes the problem by calculating aligned DMA size before calling
bm-alloc. While at this, simplify the code by removing global variables.

Signed-off-by: Alexey Kardashevskiy <aik at ozlabs.ru>
---
 board-qemu/slof/pci-phb.fs | 77 +++++++++++++++++---------------------
 1 file changed, 34 insertions(+), 43 deletions(-)

diff --git a/board-qemu/slof/pci-phb.fs b/board-qemu/slof/pci-phb.fs
index 06729bcf77a0..a1ea8f5e476f 100644
--- a/board-qemu/slof/pci-phb.fs
+++ b/board-qemu/slof/pci-phb.fs
@@ -107,10 +107,6 @@ setup-puid
 0 VALUE dma-window-size         \ Size of the window
 
 0 VALUE bm-handle               \ Bitmap allocator handle
-0 VALUE my-virt
-0 VALUE my-size
-0 VALUE dev-addr
-0 VALUE tmp-dev-addr
 
 \ Read helper variables (LIOBN, DMA window base and size) from the
 \ "ibm,dma-window" property. This property can be either located
@@ -152,62 +148,57 @@ setup-puid
    dma-window-size mod dma-window-base +
 ;
 
+: align-4k
+    fff not and
+;
+
+\ grub does not align allocated addresses to the size
+\ so when mapping in dma-map-in, sometime we call H_PUT_TCE more than
+\ bm-alloc allocated
+: dma-align ( virt size -- virt aligned-size )
+    over fff and + fff + fff not and
+;
+
 : dma-map-in  ( virt size cachable? -- devaddr )
    phb-debug? IF cr ." dma-map-in called: " .s cr THEN
    (init-dma-window-vars)
-   drop                               ( virt size )
-
-   to my-size
-   to my-virt
-   bm-handle my-size bm-alloc
-   to dev-addr
-   dev-addr 0 < IF
-       ." Bitmap allocation Failed " dev-addr .
-       FALSE EXIT
+   drop dma-align tuck		    ( size virt size )
+   bm-handle swap bm-alloc	    ( size virt dev-addr )
+   dup 0 < IF
+       ." Bitmap allocation Failed "
+       2drop
+       0 EXIT
    THEN
-   dev-addr to tmp-dev-addr
 
-   my-virt my-size
-   bounds dup >r                      ( v+s virt  R: virt )
-   swap fff + fff not and             \ Align end to next 4k boundary
-   swap fff not and                   ( v+s' virt'  R: virt )
+   over fff and over or >r	    \ add page offset to return value
+   align-4k swap align-4k 	    ( size dev-addr virt r: dev-addr )
+   3 OR                             \ Allow read and write
+   rot				    ( virt dev-addr size r: dev-addr )
+   0
    ?DO
-       \ ." mapping " i . cr
-       dma-window-liobn                \ liobn
-       tmp-dev-addr                    \ ioba
-       i 3 OR                          \ Make a read- & writeable TCE
-       ( liobn ioba tce  R: virt )
+       2dup dma-window-liobn -rot
        hv-put-tce ABORT" H_PUT_TCE failed"
-       tmp-dev-addr 1000 + to tmp-dev-addr
+       1000 + swap 1000 + swap
    1000 +LOOP
-   r> drop
-   my-virt FFF and dev-addr or
    (clear-dma-window-vars)
+   2drop
+   r>
 ;
 
 : dma-map-out  ( virt devaddr size -- )
    phb-debug? IF cr ." dma-map-out called: " .s cr THEN
    (init-dma-window-vars)
-   to my-size
-   to dev-addr
-   to my-virt
-   dev-addr fff not and to dev-addr
-   dev-addr to tmp-dev-addr
-
-   my-virt my-size                    ( virt size )
-   bounds                             ( v+s virt )
-   swap fff + fff not and             \ Align end to next 4k boundary
-   swap fff not and                   ( v+s' virt' )
+   rot drop		( devaddr size )
+   dma-align
+   2dup swap fff not and swap bm-handle -rot
+   bm-free
+   0
    ?DO
-       \ ." unmapping " i . cr
-       dma-window-liobn                \ liobn
-       tmp-dev-addr                    \ ioba
-       i                               \ Lowest bits not set => invalid TCE
-       ( liobn ioba tce )
+       dup 0 dma-window-liobn -rot
        hv-put-tce ABORT" H_PUT_TCE failed"
-       tmp-dev-addr 1000 + to tmp-dev-addr
+       1000 +
    1000 +LOOP
-   bm-handle dev-addr my-size bm-free
+   drop
    (clear-dma-window-vars)
 ;
 
-- 
2.17.1



More information about the SLOF mailing list