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)53 static __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);