Unifying the Lunaix's Physical Memory Model (#28)
[lunaix-os.git] / lunaix-os / kernel / mm / cake.c
index 5e03d347706c8943b08c9f2792aecb9d7765aad7..d9ef3810d5c5831aaaa05d81e889df2df38f6698 100644 (file)
@@ -12,8 +12,7 @@
 
 #include <klibc/string.h>
 #include <lunaix/mm/cake.h>
-#include <lunaix/mm/pmm.h>
-#include <lunaix/mm/vmm.h>
+#include <lunaix/mm/page.h>
 #include <lunaix/spike.h>
 #include <lunaix/syslog.h>
 
@@ -28,11 +27,12 @@ struct llist_header piles = { .next = &piles, .prev = &piles };
 void*
 __alloc_cake(unsigned int cake_pg)
 {
-    uintptr_t pa = pmm_alloc_cpage(KERNEL_PID, cake_pg, 0);
-    if (!pa) {
+    struct leaflet* leaflet = alloc_leaflet(count_order(cake_pg));
+    if (!leaflet) {
         return NULL;
     }
-    return vmm_vmap(pa, cake_pg * PG_SIZE, PG_PREM_RW);
+    
+    return (void*)vmap(leaflet, KERNEL_DATA);
 }
 
 struct cake_s*
@@ -44,9 +44,11 @@ __new_cake(struct cake_pile* pile)
         return NULL;
     }
 
-    int max_piece = pile->pieces_per_cake;
+    u32_t max_piece = pile->pieces_per_cake;
 
-    cake->first_piece = (void*)((uintptr_t)cake + pile->offset);
+    assert(max_piece);
+
+    cake->first_piece = (void*)((ptr_t)cake + pile->offset);
     cake->next_free = 0;
     pile->cakes_count++;
 
@@ -75,16 +77,16 @@ __init_pile(struct cake_pile* pile,
     unsigned int offset = sizeof(long);
 
     // 默认每块儿蛋糕对齐到地址总线宽度
-    if ((options & PILE_CACHELINE)) {
+    if ((options & PILE_ALIGN_CACHE)) {
         // 对齐到128字节缓存行大小,主要用于DMA
         offset = CACHE_LINE_SIZE;
     }
 
     piece_size = ROUNDUP(piece_size, offset);
     *pile = (struct cake_pile){ .piece_size = piece_size,
-                                .cakes_count = 1,
+                                .cakes_count = 0,
                                 .pieces_per_cake =
-                                  (pg_per_cake * PG_SIZE) /
+                                  (pg_per_cake * PAGE_SIZE) /
                                   (piece_size + sizeof(piece_index_t)),
                                 .pg_per_cake = pg_per_cake };
 
@@ -115,6 +117,9 @@ cake_new_pile(char* name,
 {
     struct cake_pile* pile = (struct cake_pile*)cake_grab(&master_pile);
 
+    // must aligned to napot order!
+    assert(is_pot(pg_per_cake));
+
     __init_pile(pile, name, piece_size, pg_per_cake, options);
 
     return pile;
@@ -147,14 +152,14 @@ cake_grab(struct cake_pile* pile)
     pile->alloced_pieces++;
 
     llist_delete(&pos->cakes);
-    if (pos->next_free == EO_FREE_PIECE) {
+    if (pos->free_list[pos->next_free] == EO_FREE_PIECE) {
         llist_append(&pile->full, &pos->cakes);
     } else {
         llist_append(&pile->partial, &pos->cakes);
     }
 
     void* ptr =
-      (void*)((uintptr_t)pos->first_piece + found_index * pile->piece_size);
+      (void*)((ptr_t)pos->first_piece + found_index * pile->piece_size);
 
     if (pile->ctor) {
         pile->ctor(pile, ptr);
@@ -167,6 +172,7 @@ int
 cake_release(struct cake_pile* pile, void* area)
 {
     piece_index_t piece_index;
+    size_t dsize = 0;
     struct cake_s *pos, *n;
     struct llist_header* hdrs[2] = { &pile->full, &pile->partial };
 
@@ -176,8 +182,8 @@ cake_release(struct cake_pile* pile, void* area)
             if (pos->first_piece > area) {
                 continue;
             }
-            piece_index =
-              (uintptr_t)(area - pos->first_piece) / pile->piece_size;
+            dsize = (ptr_t)(area - pos->first_piece);
+            piece_index = dsize / pile->piece_size;
             if (piece_index < pile->pieces_per_cake) {
                 goto found;
             }
@@ -187,8 +193,12 @@ cake_release(struct cake_pile* pile, void* area)
     return 0;
 
 found:
+    assert(!(dsize % pile->piece_size));
     pos->free_list[piece_index] = pos->next_free;
     pos->next_free = piece_index;
+
+    assert_msg(pos->free_list[piece_index] != pos->next_free, "double free");
+
     pos->used_pieces--;
     pile->alloced_pieces--;
 
@@ -199,6 +209,8 @@ found:
         llist_append(&pile->partial, &pos->cakes);
     }
 
+    *((unsigned int*)area) = DEADCAKE_MARK;
+
     return 1;
 }