]> Git Repo - J-u-boot.git/blobdiff - lib/lmb.c
aes: Allow to store randomly generated IV in the FIT
[J-u-boot.git] / lib / lmb.c
index ccc8a8a139c8fe58e71a6bbad65d2c1d8e56e247..b03237bc06cba1919e2b88800076adaf22536061 100644 (file)
--- a/lib/lmb.c
+++ b/lib/lmb.c
@@ -201,15 +201,6 @@ static long lmb_add_region_flags(struct alist *lmb_rgn_lst, phys_addr_t base,
                phys_addr_t rgnbase = rgn[i].base;
                phys_size_t rgnsize = rgn[i].size;
                phys_size_t rgnflags = rgn[i].flags;
-               phys_addr_t end = base + size - 1;
-               phys_addr_t rgnend = rgnbase + rgnsize - 1;
-               if (rgnbase <= base && end <= rgnend) {
-                       if (flags == rgnflags)
-                               /* Already have this region, so we're done */
-                               return 0;
-                       else
-                               return -1; /* regions with new flags */
-               }
 
                ret = lmb_addrs_adjacent(base, size, rgnbase, rgnsize);
                if (ret > 0) {
@@ -351,6 +342,86 @@ static phys_addr_t lmb_align_down(phys_addr_t addr, phys_size_t size)
        return addr & ~(size - 1);
 }
 
+/*
+ * IOVA LMB memory maps using lmb pointers instead of the global LMB memory map.
+ */
+
+int io_lmb_setup(struct lmb *io_lmb)
+{
+       int ret;
+
+       ret = alist_init(&io_lmb->free_mem, sizeof(struct lmb_region),
+                        (uint)LMB_ALIST_INITIAL_SIZE);
+       if (!ret) {
+               log_debug("Unable to initialise the list for LMB free IOVA\n");
+               return -ENOMEM;
+       }
+
+       ret = alist_init(&io_lmb->used_mem, sizeof(struct lmb_region),
+                        (uint)LMB_ALIST_INITIAL_SIZE);
+       if (!ret) {
+               log_debug("Unable to initialise the list for LMB used IOVA\n");
+               return -ENOMEM;
+       }
+
+       io_lmb->test = false;
+
+       return 0;
+}
+
+void io_lmb_teardown(struct lmb *io_lmb)
+{
+       alist_uninit(&io_lmb->free_mem);
+       alist_uninit(&io_lmb->used_mem);
+}
+
+long io_lmb_add(struct lmb *io_lmb, phys_addr_t base, phys_size_t size)
+{
+       return lmb_add_region_flags(&io_lmb->free_mem, base, size, LMB_NONE);
+}
+
+/* derived and simplified from _lmb_alloc_base() */
+phys_addr_t io_lmb_alloc(struct lmb *io_lmb, phys_size_t size, ulong align)
+{
+       long i, rgn;
+       phys_addr_t base = 0;
+       phys_addr_t res_base;
+       struct lmb_region *lmb_used = io_lmb->used_mem.data;
+       struct lmb_region *lmb_memory = io_lmb->free_mem.data;
+
+       for (i = io_lmb->free_mem.count - 1; i >= 0; i--) {
+               phys_addr_t lmbbase = lmb_memory[i].base;
+               phys_size_t lmbsize = lmb_memory[i].size;
+
+               if (lmbsize < size)
+                       continue;
+               base = lmb_align_down(lmbbase + lmbsize - size, align);
+
+               while (base && lmbbase <= base) {
+                       rgn = lmb_overlaps_region(&io_lmb->used_mem, base, size);
+                       if (rgn < 0) {
+                               /* This area isn't reserved, take it */
+                               if (lmb_add_region_flags(&io_lmb->used_mem, base,
+                                                        size, LMB_NONE) < 0)
+                                       return 0;
+
+                               return base;
+                       }
+
+                       res_base = lmb_used[rgn].base;
+                       if (res_base < size)
+                               break;
+                       base = lmb_align_down(res_base - size, align);
+               }
+       }
+       return 0;
+}
+
+long io_lmb_free(struct lmb *io_lmb, phys_addr_t base, phys_size_t size)
+{
+       return _lmb_free(&io_lmb->used_mem, base, size);
+}
+
 /*
  * Low level LMB functions are used to manage IOVA memory maps for the Apple
  * dart iommu. They must not access the global LMB memory map.
@@ -401,16 +472,22 @@ static int lmb_map_update_notify(phys_addr_t addr, phys_size_t size, u8 op,
 
 static void lmb_print_region_flags(enum lmb_flags flags)
 {
-       u64 bitpos;
        const char *flag_str[] = { "none", "no-map", "no-overwrite", "no-notify" };
+       unsigned int pflags = flags &
+                             (LMB_NOMAP | LMB_NOOVERWRITE | LMB_NONOTIFY);
+
+       if (flags != pflags) {
+               printf("invalid %#x\n", flags);
+               return;
+       }
 
        do {
-               bitpos = flags ? fls(flags) - 1 : 0;
-               assert_noisy(bitpos < ARRAY_SIZE(flag_str));
+               int bitpos = pflags ? fls(pflags) - 1 : 0;
+
                printf("%s", flag_str[bitpos]);
-               flags &= ~(1ull << bitpos);
-               puts(flags ? ", " : "\n");
-       } while (flags);
+               pflags &= ~(1u << bitpos);
+               puts(pflags ? ", " : "\n");
+       } while (pflags);
 }
 
 static void lmb_dump_region(struct alist *lmb_rgn_lst, char *name)
@@ -420,7 +497,7 @@ static void lmb_dump_region(struct alist *lmb_rgn_lst, char *name)
        enum lmb_flags flags;
        int i;
 
-       printf(" %s.count = 0x%x\n", name, lmb_rgn_lst->count);
+       printf(" %s.count = %#x\n", name, lmb_rgn_lst->count);
 
        for (i = 0; i < lmb_rgn_lst->count; i++) {
                base = rgn[i].base;
@@ -428,7 +505,7 @@ static void lmb_dump_region(struct alist *lmb_rgn_lst, char *name)
                end = base + size - 1;
                flags = rgn[i].flags;
 
-               printf(" %s[%d]\t[0x%llx-0x%llx], 0x%08llx bytes flags: ",
+               printf(" %s[%d]\t[%#llx-%#llx], %#llx bytes, flags: ",
                       name, i, base, end, size);
                lmb_print_region_flags(flags);
        }
@@ -529,6 +606,7 @@ static __maybe_unused void lmb_reserve_common_spl(void)
 void lmb_add_memory(void)
 {
        int i;
+       phys_addr_t bank_end;
        phys_size_t size;
        u64 ram_top = gd->ram_top;
        struct bd_info *bd = gd->bd;
@@ -542,6 +620,8 @@ void lmb_add_memory(void)
 
        for (i = 0; i < CONFIG_NR_DRAM_BANKS; i++) {
                size = bd->bi_dram[i].size;
+               bank_end = bd->bi_dram[i].start + size;
+
                if (size) {
                        lmb_add(bd->bi_dram[i].start, size);
 
@@ -553,6 +633,9 @@ void lmb_add_memory(void)
                        if (bd->bi_dram[i].start >= ram_top)
                                lmb_reserve_flags(bd->bi_dram[i].start, size,
                                                  LMB_NOOVERWRITE);
+                       else if (bank_end > ram_top)
+                               lmb_reserve_flags(ram_top, bank_end - ram_top,
+                                                 LMB_NOOVERWRITE);
                }
        }
 }
This page took 0.026095 seconds and 4 git commands to generate.