[OpenBIOS] [PATCH] OBP Memory deallocation

Olivier Danet odanet at caramail.com
Sun Feb 9 23:59:52 CET 2014


During boot, NextSTEP do memory allocation & deallocation:
- Implement dumb_memfree()

- Unmap freed memory (during boot, all the virtual memory is probed,
   so freed memory must be properly unmapped)

- The pointer given to dumb_memfree() does not always match the pointer
   returned by dumb_memalloc().
   In that case, try to find a memory area which includes the pointer 
address.
   Ugly, indeed...

Signed-off-by : Olivier Danet <odanet at caramail.com>

Index: arch/sparc32/lib.c
===================================================================
--- arch/sparc32/lib.c    (révision 1257)
+++ arch/sparc32/lib.c    (copie de travail)
@@ -239,10 +245,18 @@
      return obp_memalloc(va, size, align);
  }

-void obp_dumb_memfree(__attribute__((unused))char *va,
-                             __attribute__((unused))unsigned sz)
+void obp_dumb_memfree(char *va, unsigned size)
  {
-    DPRINTF("obp_dumb_memfree 0x%p (size %d)\n", va, sz);
+    phys_addr_t phys;
+    ucell       cellmode;
+
+    DPRINTF("obp_dumb_memfree: virta 0x%x, sz %d\n", (unsigned int)va, 
size);
+
+    phys = ofmem_translate(pointer2cell(va), &cellmode);
+
+    ofmem_unmap(pointer2cell(va), size);
+    ofmem_release_virt(pointer2cell(va), size);
+    ofmem_release_phys(phys, size);
  }

  /* Data fault handling routines */
Index: arch/sparc32/ofmem_sparc32.c
===================================================================
--- arch/sparc32/ofmem_sparc32.c    (révision 1257)
+++ arch/sparc32/ofmem_sparc32.c    (copie de travail)
@@ -133,17 +133,24 @@
  /* Generate memory available property entry for Sparc32 */
  void ofmem_arch_create_available_entry(phandle_t ph, ucell 
*availentry, phys_addr_t start, ucell size)
  {
-  int i = 0;
+    int i;

-    i += ofmem_arch_encode_physaddr(availentry, start);
+    i = ofmem_arch_encode_physaddr(availentry, start);
      availentry[i] = size;
  }

  /* Unmap a set of pages */
  void ofmem_arch_unmap_pages(ucell virt, ucell size)
  {
-    /* OFMEM re-maps the pages for us, so just ensure the TLB is in sync */
-    srmmu_flush_whole_tlb();
+    unsigned i;
+    unsigned long pa;
+
+    for (i = 0; i < size; i += PAGE_SIZE) {
+        pa = find_pte(virt, 0);
+        *(uint32_t *)pa = 0;
+        virt += PAGE_SIZE;
+    }
+    srmmu_flush_whole_tlb();
  }

  /* Map a set of pages */
Index: arch/sparc32/romvec.h
===================================================================
--- arch/sparc32/romvec.h    (révision 1257)
+++ arch/sparc32/romvec.h    (copie de travail)
@@ -30,8 +30,8 @@
  int obp_inst2pkg_handler(int dev_desc);
  char *obp_dumb_memalloc(char *va, unsigned int size);
  char *obp_dumb_memalloc_handler(char *va, unsigned int size);
-void obp_dumb_memfree(__attribute__((unused))char *va, 
__attribute__((unused))unsigned sz);
-void obp_dumb_memfree_handler(__attribute__((unused))char *va, 
__attribute__((unused))unsigned sz);
+void obp_dumb_memfree(char *va, unsigned size);
+void obp_dumb_memfree_handler(char *va, unsigned size);
  char *obp_dumb_mmap(char *va, int which_io, unsigned int pa, unsigned 
int size);
  char *obp_dumb_mmap_handler(char *va, int which_io, unsigned int pa, 
unsigned int size);
  void obp_dumb_munmap(__attribute__((unused)) char *va, 
__attribute__((unused)) unsigned int size);
Index: libopenbios/ofmem_common.c
===================================================================
--- libopenbios/ofmem_common.c    (révision 1257)
+++ libopenbios/ofmem_common.c    (copie de travail)
@@ -887,16 +887,25 @@
          cr = *r;
          *r = (**r).next;
          free(cr);
-
          return;
      }
+        cr = *r;
+    for ( ; *r && ((**r).next)->start < ea; r = &(**r).next) {
+        cr = *r;
+    }

-    for( ; *r && ((**r).next)->start < ea; r=&(**r).next ) {
+    if (((**r).next)->start == ea) {
+        /* Found matching entry */
+        cr = (**r).next;
+        (**r).next = cr->next;
+        free(cr);
+
+    } else {
+        /* Not exactly matching, delete the previous entry, with start 
< ea */
+        free(cr->next);
+        cr->next = (*r)->next;
+        return;
      }
-
-    cr = (**r).next;
-    (**r).next = cr->next;
-    free(cr);
  }

  static int remove_range( phys_addr_t ea, ucell size, range_t **r )
===================================================================






More information about the OpenBIOS mailing list