IBNOS
paging.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2014, Michael Müller
3  * Copyright (c) 2014, Sebastian Lackner
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions are met:
8  *
9  * 1. Redistributions of source code must retain the above copyright notice, this
10  * list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright notice,
12  * this list of conditions and the following disclaimer in the documentation
13  * and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
16  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
19  * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
22  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *
26  */
27 
28 #ifndef _H_PAGING_
29 #define _H_PAGING_
30 
35 #define PAGETABLE_SIZE 0x1000
36 #define PAGETABLE_MASK 0x3FF
37 #define PAGETABLE_BITS 10
38 #define PAGETABLE_COUNT 0x400
39 
40 #ifdef __KERNEL__
41 
42  #include <stddef.h>
43  #include <stdint.h>
44  #include <stdbool.h>
45 
46  #include <process/thread.h>
47  #include <process/process.h>
48 
49  struct pagingEntry
50  {
51  union
52  {
53  struct
54  {
55  uint32_t present : 1;
56  uint32_t rw : 1;
57  uint32_t user : 1;
58  uint32_t __res1 : 2;
59  uint32_t dirty : 1;
60  uint32_t accessed : 1;
61  uint32_t __res2 : 2;
62  uint32_t avail : 3;
63  uint32_t frame : 20;
64  };
65  uint32_t value;
66  };
67  } __attribute__((packed));
68 
72  uint32_t interrupt_0x0E(uint32_t interrupt, uint32_t error, struct thread *t);
73 
74  /* internally used by physmem.c */
75  void pagingInsertBootMap(uint32_t startIndex, uint32_t stopIndex);
76  void pagingDumpBootMap();
77 
78  void pagingInit();
79  void pagingDumpPageTable(struct process *p);
80 
81  void pagingReserveArea(struct process *p, void *addr, uint32_t length, bool user);
82  void *pagingSearchArea(struct process *p, uint32_t length);
83  void *pagingTrySearchArea(struct process *p, uint32_t length);
84 
85  void *pagingAllocatePhysMem(struct process *p, uint32_t length, bool rw, bool user);
86  void *pagingAllocatePhysMemUnpageable(struct process *p, uint32_t length, bool rw, bool user);
87  void *pagingTryAllocatePhysMem(struct process *p, uint32_t length, bool rw, bool user);
88 
89  void *pagingAllocatePhysMemFixed(struct process *p, void *addr, uint32_t length, bool rw, bool user);
90  void *pagingAllocatePhysMemFixedUnpageable(struct process *p, void *addr, uint32_t length, bool rw, bool user);
91  void *pagingTryAllocatePhysMemFixed(struct process *p, void *addr, uint32_t length, bool rw, bool user);
92 
93  void *pagingReAllocatePhysMem(struct process *p, void *addr, uint32_t old_length, uint32_t new_length, bool rw, bool user);
94 
95  void pagingReleasePhysMem(struct process *p, void *addr, uint32_t length);
96  bool pagingTryReleasePhysMem(struct process *p, void *addr, uint32_t length);
97  bool pagingTryReleaseUserMem(struct process *p, void *addr, uint32_t length);
98 
99  uint32_t pagingGetPhysMem(struct process *p, void *addr);
100 
101  void *pagingMapRemoteMemory(struct process *dst_p, struct process *src_p, void *dst_addr, void *src_addr, uint32_t length, bool rw, bool user);
102  void *pagingTryMapUserMem(struct process *src_p, void *src_addr, uint32_t length, bool rw);
103 
104  void pagingAllocProcessPageTable(struct process *p);
105  void pagingForkProcessPageTable(struct process *destination, struct process *source);
106  void pagingReleaseProcessPageTable(struct process *p);
107  void pagingFillProcessInfo(struct process *p, struct processInfo *info);
108 
109  /* macros to simplify user memory access */
110  struct userMemory
111  {
112  void *addr; /* virtual address in kernel process */
113  uint32_t length; /* length in pages */
114  };
115 
116  static inline bool ACCESS_USER_MEMORY(struct userMemory *k, struct process *p, void *src_addr, uint32_t byte_length, bool rw)
117  {
118  if (!byte_length)
119  {
120  k->length = 0;
121  k->addr = NULL;
122  return true;
123  }
124 
125  k->length = (((uint32_t)src_addr & PAGE_MASK) + byte_length + PAGE_MASK) >> PAGE_BITS;
126  k->addr = pagingTryMapUserMem(p, src_addr, k->length, rw);
127  return (k->addr != NULL);
128  }
129 
130  static inline bool ACCESS_USER_MEMORY_STRUCT(struct userMemory *k, struct process *p, void *src_addr, uint32_t count, uint32_t struct_length, bool rw)
131  {
132  uint64_t byte_length = (uint64_t)count * struct_length;
133  if ((byte_length >> 32) != 0) return false;
134  return ACCESS_USER_MEMORY(k, p, src_addr, byte_length, rw);
135  }
136 
137  static inline void RELEASE_USER_MEMORY(struct userMemory *k)
138  {
139  if (k->addr) pagingReleasePhysMem(NULL, k->addr, k->length);
140  }
141 
142 #endif
143 
146 #endif /* _H_PAGING_ */
void pagingDumpPageTable(struct process *p)
Dumps information about the page table of a specific process.
Definition: paging.c:514
void * pagingReAllocatePhysMem(struct process *p, void *addr, uint32_t old_length, uint32_t new_length, bool rw, bool user)
Reallocates a specific range of virtual memory in a process.
Definition: paging.c:937
uint32_t __res1
Definition: paging.h:58
void pagingReleaseProcessPageTable(struct process *p)
Releases the page directory and page table of a specific process.
Definition: paging.c:1344
uint32_t value
Definition: paging.h:65
uint32_t interrupt_0x0E(uint32_t interrupt, uint32_t error, struct thread *t)
void pagingAllocProcessPageTable(struct process *p)
Allocates the page directory and page table for a specific process.
Definition: paging.c:1236
uint32_t present
Definition: paging.h:55
void pagingInit()
Initializes paging.
Definition: paging.c:467
#define PAGE_MASK
Definition: physmem.h:36
void pagingReserveArea(struct process *p, void *addr, uint32_t length, bool user)
Marks the memory in a specific memory area as reserved.
Definition: paging.c:550
void * pagingAllocatePhysMemFixedUnpageable(struct process *p, void *addr, uint32_t length, bool rw, bool user)
Allocates several pages of unpageable physical memory at a fixed virtual address in a process...
Definition: paging.c:804
void * pagingAllocatePhysMemFixed(struct process *p, void *addr, uint32_t length, bool rw, bool user)
Allocates several pages of physical memory at a fixed virtual address in a process.
Definition: paging.c:778
void * pagingAllocatePhysMemUnpageable(struct process *p, uint32_t length, bool rw, bool user)
Allocates several pages of unpageable physical memory in a process.
Definition: paging.c:686
struct userMemory __attribute__
void pagingDumpBootMap()
Dumps a list of all entries in the boot map.
Definition: paging.c:444
void * pagingAllocatePhysMem(struct process *p, uint32_t length, bool rw, bool user)
Allocates several pages of physical memory in a process.
Definition: paging.c:659
bool pagingTryReleaseUserMem(struct process *p, void *addr, uint32_t length)
Releases several pages of physical memory of a process.
Definition: paging.c:1615
#define PAGE_BITS
Definition: physmem.h:37
uint32_t avail
Definition: paging.h:62
void * pagingSearchArea(struct process *p, uint32_t length)
Searches for a consecutive area of length free pages in a process.
Definition: paging.c:588
bool pagingTryReleasePhysMem(struct process *p, void *addr, uint32_t length)
Releases several pages of physical memory of a process.
Definition: paging.c:1051
Definition: thread.h:47
void * pagingTryAllocatePhysMem(struct process *p, uint32_t length, bool rw, bool user)
Tries to allocates several pages of physical memory in a process.
Definition: paging.c:736
uint32_t rw
Definition: paging.h:56
void * pagingTryAllocatePhysMemFixed(struct process *p, void *addr, uint32_t length, bool rw, bool user)
Allocates several pages of unpageable physical memory at a fixed virtual address in a process...
Definition: paging.c:851
void * pagingTrySearchArea(struct process *p, uint32_t length)
Searches for a consecutive area of length free pages in a process.
Definition: paging.c:612
void pagingReleasePhysMem(struct process *p, void *addr, uint32_t length)
Releases several pages of physical memory in a process.
Definition: paging.c:1034
uint32_t dirty
Definition: paging.h:59
uint32_t length
Definition: paging.h:113
uint32_t accessed
Definition: paging.h:60
uint32_t frame
Definition: paging.h:63
void * addr
Definition: paging.h:112
uint32_t pagingGetPhysMem(struct process *p, void *addr)
Returns the physical page index for a virtual address.
Definition: paging.c:1111
uint32_t __res2
Definition: paging.h:61
uint32_t user
Definition: paging.h:57
void * pagingTryMapUserMem(struct process *src_p, void *src_addr, uint32_t length, bool rw)
Maps some virtual memory of a usermode process into the kernel.
Definition: paging.c:1520
void pagingForkProcessPageTable(struct process *destination, struct process *source)
Duplicate a page table and assigns it to a destination process.
Definition: paging.c:1261
void pagingInsertBootMap(uint32_t startIndex, uint32_t stopIndex)
Appends a specific range of physical pages to the bootmap.
Definition: paging.c:391
void pagingFillProcessInfo(struct process *p, struct processInfo *info)
Fills out all memory related fields in the processInfo structure.
Definition: paging.c:1436
void * pagingMapRemoteMemory(struct process *dst_p, struct process *src_p, void *dst_addr, void *src_addr, uint32_t length, bool rw, bool user)
Maps some virtual memory from one process to another one.
Definition: paging.c:1150