Advertisement
Guest User

Untitled

a guest
May 20th, 2018
134
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.85 KB | None | 0 0
  1. #pragma once
  2. /**
  3.  * Kernel - Memory Map
  4.  *
  5.  * @version 0.1.0
  6.  * @license MIT License
  7.  */
  8. #ifndef _KERNEL_MEMORY_H
  9. #define _KERNEL_MEMORY_H
  10.  
  11. #include <utility.h>
  12.  
  13. /**
  14.  * Memory block size
  15.  * NOTE: No clue if 4096 is the right optimal size for memory blocks,
  16.  * ... but the first google search says so.
  17.  */
  18. #define MEMORY_BLOCK_SIZE (4096)
  19.  
  20. /**
  21.  * Memory alignment functions
  22.  */
  23. // Align an memory item/block to the left
  24. static uint32_t kmemory_align_left(const uint32_t item)
  25. {
  26.   return (item / MEMORY_BLOCK_SIZE) * MEMORY_BLOCK_SIZE;
  27. }
  28. // Align an memory item/block to the right
  29. static uint32_t kmemory_align_right(const uint32_t item)
  30. {
  31.   return (item / MEMORY_BLOCK_SIZE + (item % MEMORY_BLOCK_SIZE != 0)) * MEMORY_BLOCK_SIZE;
  32. }
  33.  
  34. /**
  35.  * Representation of a region of memory
  36.  */
  37. typedef struct memory_region
  38. {
  39.   /**
  40.    * The memory region base address pointer.
  41.    */
  42.   address_t *base;
  43.  
  44.   /**
  45.    * The memory region size.
  46.    */
  47.   size_t size;
  48. } kernel_memory_region_t;
  49.  
  50. /**
  51.  * Representation of a memory map
  52.  */
  53. typedef struct memory_map
  54. {
  55.   /**
  56.    * The memory bitmap base address
  57.    */
  58.   uint8_t *bitmap_address;
  59.  
  60.   /**
  61.    * The amount of bitmap blocks
  62.    */
  63.   size_t bitmap_count;
  64.  
  65.   /**
  66.    * The memory base address
  67.    */
  68.   uint8_t *data_address;
  69.  
  70.   /**
  71.    * The amount of data blocks
  72.    */
  73.   size_t data_count;
  74.  
  75.   /**
  76.    * The amount of blocks used
  77.    */
  78.   size_t used;
  79. } kernel_memory_map_t;
  80.  
  81. /**
  82.  * Initialize the memory map
  83.  * @param region. The kernel memory region
  84.  */
  85. void kmemory_init(kernel_memory_map_t *mm, const kernel_memory_region_t &region)
  86. {
  87.   // Get the first, and last memory block
  88.   uint32_t first_block = kmemory_align_right((uint32_t)region.base);
  89.   uint32_t last_block  = kmemory_align_left((uint32_t)region.base + region.size);
  90.  
  91.   // The total blocks of the memory region
  92.   uint32_t size = last_block - first_block;
  93.   // The block count of the memory region
  94.   uint32_t block_count = size / MEMORY_BLOCK_SIZE;
  95.   // The amount of blocks required for the memory map
  96.   uint32_t blocks_required = (block_count / MEMORY_BLOCK_SIZE + (block_count % MEMORY_BLOCK_SIZE != 0)) / MEMORY_BLOCK_SIZE + ((block_count / MEMORY_BLOCK_SIZE + (block_count % MEMORY_BLOCK_SIZE != 0)) % MEMORY_BLOCK_SIZE != 0);
  97.  
  98.   // The memory map bitmap
  99.   mm->bitmap_address = reinterpret_cast<uint8_t *>(first_block);
  100.   mm->bitmap_count   = blocks_required;
  101.  
  102.   // The memory map data
  103.   mm->data_address = reinterpret_cast<uint8_t *>(first_block + blocks_required * MEMORY_BLOCK_SIZE);
  104.   mm->data_count   = block_count - blocks_required;
  105.  
  106.   // Allocate the memory map into memory
  107.   for(size_t i = 0; i < blocks_required; i++)
  108.   {
  109.     *(mm->bitmap_address + i) = 0;
  110.   }
  111.  
  112.   // mark 0 so whe can compare it to 0x0 or NULL, as
  113.   kmemory_mark_block_used(mm, 0);
  114. }
  115.  
  116. /**
  117.  * Mark a memory block as free
  118.  * @param mm. The kernel memory map
  119.  * @param block. The block inside the memory map to set
  120.  */
  121. void kmemory_mark_block_free(kernel_memory_map_t *mm, const uint32_t block)
  122. {
  123.   if (block < mm->data_count)
  124.   {
  125.     reinterpret_cast<uint32_t *>(mm->data_address)[block/32] |= ~(1 << (block % 32));
  126.   }
  127. }
  128.  
  129. /**
  130.  * Mark a memory block as used
  131.  * @param mm. The kernel memory map
  132.  * @param block. The block inside the memory map to set
  133.  */
  134. void kmemory_mark_block_used(kernel_memory_map_t *mm, const uint32_t block)
  135. {
  136.   if (block < mm->data_count)
  137.   {
  138.     reinterpret_cast<uint32_t *>(mm->data_address)[block/32] &= ~(1 << (block % 32));
  139.   }
  140. }
  141.  
  142. /**
  143.  * Get the total block count of the memory map
  144.  */
  145. size_t kmemory_block_count(const kernel_memory_map_t *mm)
  146. {
  147.   return mm->data_count;
  148. }
  149.  
  150. /**
  151.  * Get the amount of used blocks in the memory map
  152.  * @param mm. The kernel memory map
  153.  * @return The amount of used blocks in the memory map
  154.  */
  155. size_t kmemory_block_used_count(const kernel_memory_map_t* mm)
  156. {
  157.   return mm->used;
  158. }
  159.  
  160. /**
  161.  * Get the amount of free blocks in the memory map
  162.  * @param mm. The kernel memory map
  163.  * @return The amount of free blocks in the memory map
  164.  */
  165. size_t kmemory_block_free_count(const kernel_memory_map_t* mm)
  166. {
  167.   return mm->data_count - mm->used;
  168. }
  169.  
  170. /**
  171.  * Allocate blocks on the memory map
  172.  * @param mm. The kernel memory map
  173.  * @param count. The amount of blocks to allocate
  174.  * @return The base address of the allocated blocks, or null if allocation failed.
  175.  */
  176. address_t* kmemory_allocate_blocks(kernel_memory_map_t* mm, const uint32_t count)
  177. {
  178.   // don't allocate 0 blocks
  179.   if (count == 0)
  180.   {
  181.     return nullptr;
  182.   }
  183.  
  184.   uint32_t current_block_count = 0;
  185.   for(size_t i = 0; i < mm->data_count; i++)
  186.   {
  187.     // try to find enough blocks to allocate
  188.     if (!(i < mm->block_count) && !(reinterpret_cast<uint32_t *>(mm->data_address)[i/32] & (1 << (i % 32))))
  189.     {
  190.       current_block_count++;
  191.     }
  192.     else {
  193.       current_block_count = 0;
  194.     }
  195.  
  196.     if (current_block_count == count)
  197.     {
  198.       size_t first_block = i + 1 - count;
  199.  
  200.       for (size_t block = 0; block < count; block++)
  201.       {
  202.         kmemory_mark_block_used(mm, first_block + block);
  203.       }
  204.       mm->used += count;
  205.       return mm->data_address + first_block + MEMORY_BLOCK_SIZE;
  206.     }
  207.   }
  208.  
  209.   return nullptr;
  210. }
  211.  
  212. /**
  213.  * Free blocks on the memory map
  214.  * @param mm. The kernel memory map
  215.  * @param address. The base address to free
  216.  */
  217. void kmemory_free_blocks(kernel_memory_map_t* mm, const address_t* address)
  218. {
  219.   uint32_t offset = reinterpret_cast<uint32_t *>(reinterpret_cast<uint8_t*>(address) - reinterpret_cast<uint32_t>(mm->data_address));
  220.  
  221.   if (offset % MEMORY_BLOCK_SIZE == 0)
  222.   {
  223.     uint32_t block = offset / MEMORY_BLOCK_SIZE;
  224.  
  225.     if (!(block < mm->block_count) && !(reinterpret_cast<uint32_t *>(mm->data_address)[block/32] & (1 << (block % 32))))
  226.     {
  227.       mm->used--;
  228.     }
  229.  
  230.     kmemory_mark_block_free(mm, block);
  231.   }
  232. }
  233.  
  234. #endif /* end of kernel.h */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement