1 #pragma once 2 #include <common/sys/types.h> 3 #include <common/glib.h> 4 #include "mm-types.h" 5 #include "mm.h" 6 #include "slab.h" 7 8 #define MMIO_BUDDY_MAX_EXP PAGE_1G_SHIFT 9 #define MMIO_BUDDY_MIN_EXP PAGE_4K_SHIFT 10 #define MMIO_BUDDY_REGION_COUNT (MMIO_BUDDY_MAX_EXP - MMIO_BUDDY_MIN_EXP + 1) 11 12 /** 13 * @brief mmio伙伴系统内部的地址区域结构体 14 * 15 */ 16 struct __mmio_buddy_addr_region 17 { 18 struct List list; 19 uint64_t vaddr; // 该内存对象起始位置的虚拟地址 20 }; 21 22 /** 23 * @brief 空闲页数组结构体 24 * 25 */ 26 struct __mmio_free_region_list 27 { 28 struct List list_head; 29 int64_t num_free; // 空闲页的数量 30 }; 31 32 /** 33 * @brief buddy内存池 34 * 35 */ 36 struct mmio_buddy_mem_pool 37 { 38 uint64_t pool_start_addr; // 内存池的起始地址 39 uint64_t pool_size; // 内存池的内存空间总大小 40 spinlock_t op_lock; // 操作锁 41 /** 42 * @brief 空闲地址区域链表 43 * 数组的第i个元素代表大小为2^(i+12)的内存区域 44 */ 45 struct __mmio_free_region_list free_regions[MMIO_BUDDY_REGION_COUNT]; 46 }; 47 48 /** 49 * @brief 释放address region结构体 50 * 51 * @param region 待释放的结构体 52 */ __mmio_buddy_release_addr_region(struct __mmio_buddy_addr_region * region)53static __always_inline void __mmio_buddy_release_addr_region(struct __mmio_buddy_addr_region *region) 54 { 55 kfree(region); 56 } 57 58 /** 59 * @brief 归还一块内存空间到buddy 60 * 61 * @param vaddr 虚拟地址 62 * @param exp 内存空间的大小(2^exp) 63 * @return int 返回码 64 */ 65 int __mmio_buddy_give_back(uint64_t vaddr, int exp); 66 67 /** 68 * @brief 初始化mmio的伙伴系统 69 * 70 */ 71 void mmio_buddy_init(); 72 73 /** 74 * @brief 从buddy中申请一块指定大小的内存区域 75 * 76 * @param exp 内存区域的大小(2^exp) 77 * @return struct __mmio_buddy_addr_region* 符合要求的内存区域。没有满足要求的时候,返回NULL 78 */ 79 struct __mmio_buddy_addr_region *mmio_buddy_query_addr_region(int exp);