| 1 | /////////////////////////////////////////////////////////////////////////////////// |
|---|
| 2 | // File : pmem.h |
|---|
| 3 | // Date : 01/09/2014 |
|---|
| 4 | // Author : alain greiner |
|---|
| 5 | // Copyright (c) UPMC-LIP6 |
|---|
| 6 | /////////////////////////////////////////////////////////////////////////////////// |
|---|
| 7 | // The pmem.c and pmem.h files are part ot the GIET-VM nano kernel. |
|---|
| 8 | // They define the data structures and functions used by the boot code |
|---|
| 9 | // to allocate physical memory. |
|---|
| 10 | /////////////////////////////////////////////////////////////////////////////////// |
|---|
| 11 | // The physical address format is 40 bits, structured in five fields: |
|---|
| 12 | // | 4 | 4 | 11 | 9 | 12 | |
|---|
| 13 | // | X | Y | BPPI | SPPI | OFFSET | |
|---|
| 14 | // - The (X,Y) fields define the cluster index |
|---|
| 15 | // - The BPPI field is the Big Physical Page Index |
|---|
| 16 | // - The SPPI field is the Small Physical Page Index |
|---|
| 17 | // - The |X|Y|BPPI|SPPI| concatenation is the PPN (Physical Page Number) |
|---|
| 18 | // |
|---|
| 19 | // The physical memory allocation is statically done by the boot-loader. |
|---|
| 20 | // As the physical memory can be distributed in all clusters, there is |
|---|
| 21 | // one physical memory allocator in each cluster, and the allocation |
|---|
| 22 | // state is defined by the boot_pmem_alloc[x][y] array (defined in the |
|---|
| 23 | // boot.c file). |
|---|
| 24 | // As the allocated physical memory is never released, the allocator structure |
|---|
| 25 | // is very simple and is defined below in the pmem_alloc_t structure. |
|---|
| 26 | // The physical memory allocation in each cluster being done by one single processor |
|---|
| 27 | // (P[x,y,0]), this structure does not contain any lock protecting exclusive access. |
|---|
| 28 | // Both small pages allocator and big pages allocators allocate a variable |
|---|
| 29 | // number of CONTIGUOUS pages in the physical space. |
|---|
| 30 | // The two first big pages in cluster[0][0] are reserved for the boot-loader vsegs, |
|---|
| 31 | // that are identity mapping. They are not allocated by the pmem allocator. |
|---|
| 32 | /////////////////////////////////////////////////////////////////////////////////// |
|---|
| 33 | |
|---|
| 34 | #ifndef _PMEM_H_ |
|---|
| 35 | #define _PMEM_H_ |
|---|
| 36 | |
|---|
| 37 | ///////////////////////////////////////////////////////////////////////////////////// |
|---|
| 38 | // Physical memory allocator in cluster[x][y] |
|---|
| 39 | ///////////////////////////////////////////////////////////////////////////////////// |
|---|
| 40 | |
|---|
| 41 | typedef struct PmemAlloc |
|---|
| 42 | { |
|---|
| 43 | unsigned int x; // allocator x coordinate |
|---|
| 44 | unsigned int y; // allocator y coordinate |
|---|
| 45 | unsigned int max_bppi; // max bppi value in cluster[x][y] |
|---|
| 46 | unsigned int nxt_bppi; // next free bppi in cluster[x][y] |
|---|
| 47 | unsigned int max_sppi; // max sppi value in cluster[x][y] |
|---|
| 48 | unsigned int nxt_sppi; // next free sppi in cluster[x][y] |
|---|
| 49 | unsigned int spp_bppi; // current bppi for small pages |
|---|
| 50 | } pmem_alloc_t; |
|---|
| 51 | |
|---|
| 52 | //////////////////////////////////////////////////////////////////////////////////// |
|---|
| 53 | // functions prototypes |
|---|
| 54 | //////////////////////////////////////////////////////////////////////////////////// |
|---|
| 55 | |
|---|
| 56 | /////////////////////////////////////////////////////////////////////////////////// |
|---|
| 57 | // This function initialises the physical memory allocator in cluster (x,y) |
|---|
| 58 | // The pseg base address and the pseg size must be multiple of 2 Mbytes |
|---|
| 59 | // (one big page). |
|---|
| 60 | // - base is the pseg local base address (no cluster extension) |
|---|
| 61 | // - size is the pseg length (bytes) |
|---|
| 62 | // The first page in cluster[0][0] is reserved for identity mapped vsegs. |
|---|
| 63 | /////////////////////////////////////////////////////////////////////////////////// |
|---|
| 64 | void _pmem_alloc_init( unsigned int x, |
|---|
| 65 | unsigned int y, |
|---|
| 66 | unsigned int base, |
|---|
| 67 | unsigned int size ); |
|---|
| 68 | |
|---|
| 69 | /////////////////////////////////////////////////////////////////////////////////// |
|---|
| 70 | // This function allocates n contiguous small pages (4 Kbytes), |
|---|
| 71 | // from the physical memory allocator defined by the p pointer. |
|---|
| 72 | // It returns the PPN (28 bits) of the first physical small page. |
|---|
| 73 | // Exit if not enough free space. |
|---|
| 74 | /////////////////////////////////////////////////////////////////////////////////// |
|---|
| 75 | unsigned int _get_small_ppn( pmem_alloc_t* p, |
|---|
| 76 | unsigned int n ); |
|---|
| 77 | |
|---|
| 78 | /////////////////////////////////////////////////////////////////////////////////// |
|---|
| 79 | // This function allocates n contiguous big pages (2 Mbytes), |
|---|
| 80 | // from the physical memory allocator defined by the p pointer. |
|---|
| 81 | // It returns the PPN (28 bits) of the first physical big page |
|---|
| 82 | // (the SPPI field of the ppn is always 0). |
|---|
| 83 | // Exit if not enough free space. |
|---|
| 84 | /////////////////////////////////////////////////////////////////////////////////// |
|---|
| 85 | unsigned int _get_big_ppn( pmem_alloc_t* p, |
|---|
| 86 | unsigned int n ); |
|---|
| 87 | |
|---|
| 88 | #endif |
|---|
| 89 | |
|---|
| 90 | // Local Variables: |
|---|
| 91 | // tab-width: 4 |
|---|
| 92 | // c-basic-offset: 4 |
|---|
| 93 | // c-file-offsets:((innamespace . 0)(inline-open . 0)) |
|---|
| 94 | // indent-tabs-mode: nil |
|---|
| 95 | // End: |
|---|
| 96 | // vim: filetype=c:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 |
|---|
| 97 | |
|---|