# libpmp
## pmp_heap.c
``` c
void pmp_mmap(unsigned int start, unsigned int end, unsigned char privilege,
int v_pmp_id);
```
* 重新整理这个链表,如果有重叠就进行拆分,保证插入`[start, end]后`,最后链表中的每个节点存储的区间都没有重叠。
* 遍历原来的链表,找到所有和`[start, end]`有重叠的区间`[si, ei]`,然后切分成若干个小区间(切分方法如下),每个小区间存成一个链表节点。注意,如果两个完全相同的区间优先级不同,那么它们将会作为两个节点(两个节点只有优先级不同)同时存在链表中。
* 切分的例子:
* 切分完之后,需要更新PMP entry,更新的方法如下:
* 遍历所有的PMP entry,对于某一个PMP entry管理的区间,如果这个区间和`[start, end]` 有交集,那么分为三种情况,假设PMP entry管理的区间是`[s, e]`
* 如果`[start, end]`包含了`[s, e]`,那么`[s, e]`一定和上面切分后的某个小区间范围相同。这时候就比较两者的优先级,如果PMP entry的优先级低,就需要refresh。
* 如果`[start, end]`和`[s, e]`不是包含,只是有交集,那么二者的交集部分一定和上面切分后的某个小区间范围相同,这时候也是比较这两个小区间的优先级,处理方法和上面相同。
例子:
``` c
void pmp_free(v_id)
```
* 遍历链表,如果某个节点的id和传入的id相同,直接从链表中删除。
* 遍历PMP entry,如果PMP entry中的区间id和传入的id相同,就直接把这个PMP entry抹除。
## exception.c
``` c
pmp_exception_handler(void * addr);
```
* 异常处理程序,当用户访问一个地址时,如果PMP规定这个地址访问不合法,就会调用异常处理函数。
* 如果这个地址在PMP区间里,不用管。
* 如果不在,就把这个地址当作参数,在链表里,找到优先级最高的区间,然后放到物理的PMP寄存器中。
pmp_util.c
pmp_debug.c