---
# System prepended metadata

title: libpmp

---

# 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]`，然后切分成若干个小区间（切分方法如下），每个小区间存成一个链表节点。注意，如果两个完全相同的区间优先级不同，那么它们将会作为两个节点（两个节点只有优先级不同）同时存在链表中。
    * 切分的例子：![](https://i.imgur.com/lanVJg6.png)

* 切分完之后，需要更新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