Commit 03bcbc44d81b4c9c5d97208f0759abf4c78fc779

Change some definitions to const types and inline functions
  
99
1010using namespace std;
1111
12// Macros used in the bitset algorithms.
13#define INDEX_FROM_BIT(a) (a/(8*4))
14#define OFFSET_FROM_BIT(a) (a%(8*4))
15
1612// Placement address and kernel heap aredefined in src/mm/kheap.c
1713extern uintptr placement_address;
1814extern heap::heap * kheap;
2626 uintptr * frames;
2727 u32int n_frames;
2828
29 // Inline functions used in the bitset algorithms.
30 template<typename T>
31 inline uintptr index_from_bit(const T& a)
32 {
33 return a / (8 * 4);
34 }
35
36 template<typename T>
37 inline uintptr offset_from_bit(const T& a)
38 {
39 return a % (8 * 4);
40 }
41
42
2943 // Paging function prototypes
3044 void set_frame(uintptr address);
3145 void clear_frame(uintptr address);
5757
5858 // Work out the number of frames we can fit in our memory, allocate
5959 // space for them, and then clear that memory
60 n_frames = memory_end / PAGE_SIZE;
61 frames = (uintptr *) kmalloc(INDEX_FROM_BIT(n_frames));
62 memset(frames, 0, INDEX_FROM_BIT(n_frames));
60 n_frames = memory_end / PageSize;
61 frames = (uintptr *) kmalloc(index_from_bit(n_frames));
62 memset(frames, 0, index_from_bit(n_frames));
6363
6464 // Make a page directory for the kernel, and set its physical address
6565 kernel_directory = (page_directory_t *) kmalloc(sizeof(page_directory_t), true);
7373 // yet because they have to be indentity mapped first
7474 u32int i;
7575
76 for(i = KHEAP_START; i < KHEAP_START + KHEAP_INITIAL_SIZE; i += PAGE_SIZE)
76 for(i = KHeapStart; i < KHeapStart + KHeapInitialSize; i += PageSize)
7777 {
7878 get_page(i, true, kernel_directory);
7979 }
8383 // enabled. We loop and change the placement address before calling kmalloc()
8484 i = 0;
8585
86 while(i < placement_address + PAGE_SIZE)
86 while(i < placement_address + PageSize)
8787 {
8888 // Set the kernel code as readable but not writable from the userspace
8989 allocate_frame(get_page(i, true, kernel_directory), true, false);
9090
91 i += PAGE_SIZE;
91 i += PageSize;
9292 }
9393
9494 // Allocate the pages for the kernel heap (mapped earlier)
95 for(i = KHEAP_START; i < KHEAP_START + KHEAP_INITIAL_SIZE; i += PAGE_SIZE)
95 for(i = KHeapStart; i < KHeapStart + KHeapInitialSize; i += PageSize)
9696 {
9797 allocate_frame(get_page(i, true, kernel_directory), true, false);
9898 }
104104 switch_directory(kernel_directory);
105105
106106 // Now we need to initialise a heap for the kernel to use
107 kheap = heap::create_heap(KHEAP_START, KHEAP_START + KHEAP_INITIAL_SIZE, 0xCFFFF000, false, false);
107 kheap = heap::create_heap(KHeapStart, KHeapStart + KHeapInitialSize, 0xCFFFF000, false, false);
108108
109109 // Clone the kernel directory and switch to the clone
110110 current_directory = clone_directory(kernel_directory);
117117 // Set a frame in the bitset
118118 void set_frame(uintptr address)
119119 {
120 u32int frame = address / PAGE_SIZE;
121 u32int index = INDEX_FROM_BIT(frame);
122 u32int offset = OFFSET_FROM_BIT(frame);
120 uintptr frame = address / PageSize;
121 uintptr index = index_from_bit(frame);
122 uintptr offset = offset_from_bit(frame);
123123
124124 frames[index] |= (0x1 << offset);
125125 }
127127 // Clear a frame in the bitset
128128 void clear_frame(uintptr address)
129129 {
130 u32int frame = address / PAGE_SIZE;
131 u32int index = INDEX_FROM_BIT(frame);
132 u32int offset = OFFSET_FROM_BIT(frame);
130 uintptr frame = address / PageSize;
131 uintptr index = index_from_bit(frame);
132 uintptr offset = offset_from_bit(frame);
133133
134134 frames[index] &= ~(0x1 << offset);
135135 }
137137 // Test to see if a frame exists
138138 uintptr test_frame(uintptr address)
139139 {
140 u32int frame = address / PAGE_SIZE;
141 u32int index = INDEX_FROM_BIT(frame);
142 u32int offset = OFFSET_FROM_BIT(frame);
140 uintptr frame = address / PageSize;
141 uintptr index = index_from_bit(frame);
142 uintptr offset = offset_from_bit(frame);
143143
144144 return (frames[index] & (0x1 << offset));
145145 }
147147 // Find the first available free frame
148148 uintptr first_frame()
149149 {
150 for(u32int i = 0; i < INDEX_FROM_BIT(n_frames); i++)
150 for(u32int i = 0; i < index_from_bit(n_frames); i++)
151151 {
152152 if(frames[i] != 0xFFFFFFFF) // No free frames
153153 {
182182 panic("No free frames");
183183 }
184184
185 set_frame(index * PAGE_SIZE);
185 set_frame(index * PageSize);
186186 page->present = 1; // Mark as present
187187 page->rw = (writable)?1:0; // Is the page writable
188188 page->user = (kernel)?0:1; // Is this a user mode page?
231231 page_t * get_page(uintptr address, bool make, page_directory_t * dir)
232232 {
233233 // Change the address into an index
234 address /= PAGE_SIZE;
234 address /= PageSize;
235235
236236 // Find the page table containing the address
237237 u32int table_index = address / 1024;
250250 dir->tables[table_index] = (page_table_t *)kmalloc(sizeof(page_table_t), &temp, true);
251251
252252 // Clear the memory space allocated for the page
253 memset(dir->tables[table_index], 0, PAGE_SIZE);
253 memset(dir->tables[table_index], 0, PageSize);
254254
255255 // Set the page as present, writable and user mode
256256 dir->tablesPhysical[table_index] = temp | 0x7;
330330 if(src->pages[i].dirty == 1) table->pages[i].dirty = 1;
331331
332332 // Physically copy the data accross
333 copy_page_physical(src->pages[i].frame * PAGE_SIZE, table->pages[i].frame * PAGE_SIZE);
333 copy_page_physical(src->pages[i].frame * PageSize, table->pages[i].frame * PageSize);
334334 }
335335
336336 return table;
  
55#include "mm/kheap.h"
66#include "isr.h"
77
8#define PAGE_SIZE 0x1000
8const size_t PageSize = 0x1000;
99
1010namespace paging
1111{
  
3636 heap * temp = new heap;
3737
3838 // Make sure that the start and end addresses are page aligned
39 ASSERT(start % PAGE_SIZE == 0);
40 ASSERT(end % PAGE_SIZE == 0);
39 ASSERT(start % PageSize == 0);
40 ASSERT(end % PageSize == 0);
4141
4242 // Initialise our index
43 temp->heap_index = create_index((uintptr *)start, HEAP_INDEX_SIZE);
43 temp->heap_index = create_index((uintptr *)start, IndexSize);
4444
4545 // Move the start address past the index
46 start += sizeof(uintptr *) * HEAP_INDEX_SIZE;
46 start += sizeof(uintptr *) * IndexSize;
4747
4848 // Make sure the start address is page aligned
4949 if ((start & 0xFFFFF000) != 0)
5050 {
5151 start &= 0xFFFFF000;
52 start += PAGE_SIZE;
52 start += PageSize;
5353 }
5454
5555 // Fill the structure with the start, end and max addresses
6262 // The heap should be just one large hole to start off
6363 header * hole = (header *) start;
6464 hole->size = end - start;
65 hole->magic = HEAP_MAGIC;
65 hole->magic = Magic;
6666 hole->is_hole = true;
6767
6868 // Insert this hole into the index
162162
163163 if(((location + sizeof(header)) & 0xFFFFF000) != 0)
164164 {
165 offset = PAGE_SIZE - (location + sizeof(header)) % PAGE_SIZE;
165 offset = PageSize - (location + sizeof(header)) % PageSize;
166166 }
167167
168168 s32int hole_size = (s32int)head->size - offset;
206206 if((new_size & 0xFFFFF000) != 0)
207207 {
208208 new_size &= 0xFFFFF000;
209 new_size += PAGE_SIZE;
209 new_size += PageSize;
210210 }
211211
212212 // Make sure we aren't trying to expand the heap too much
220220 {
221221 paging::allocate_frame(paging::get_page(heap->start_address + i, true, kernel_directory),
222222 heap->supervisor, heap->readonly);
223 i += PAGE_SIZE;
223 i += PageSize;
224224 }
225225
226226 heap->end_address = heap->start_address + new_size;
233233 ASSERT(new_size < heap->end_address - heap->start_address);
234234
235235 // Find the nearest following page boundary
236 if(new_size & PAGE_SIZE)
236 if(new_size & PageSize)
237237 {
238 new_size &= PAGE_SIZE;
239 new_size += PAGE_SIZE;
238 new_size &= PageSize;
239 new_size += PageSize;
240240 }
241241
242242 // We can only contract the heap as small as its minimum size
243 if(new_size < HEAP_MIN_SIZE)
243 if(new_size < MinSize)
244244 {
245 new_size = HEAP_MIN_SIZE;
245 new_size = MinSize;
246246 }
247247
248248 // Calculate the current heap size
249249 size_t old_size = heap->end_address - heap->start_address;
250250
251 size_t i = old_size - PAGE_SIZE;
251 size_t i = old_size - PageSize;
252252
253253 while(new_size < i)
254254 {
255255 paging::free_frame(paging::get_page(heap->start_address + i, false, kernel_directory));
256 i -= PAGE_SIZE;
256 i -= PageSize;
257257 }
258258
259259 // Set the new end address of the contracted heap
272272 if(phys != NULL)
273273 {
274274 paging::page_t * page = paging::get_page((uintptr)address, false, kernel_directory);
275 *phys = (page->frame * PAGE_SIZE) + ((uintptr)address & 0xFFF);
275 *phys = (page->frame * PageSize) + ((uintptr)address & 0xFFF);
276276 }
277277
278278 return (uintptr)address;
289289 {
290290 // If it's not aligned...
291291 placement_address &= 0xFFFFF000;
292 placement_address += PAGE_SIZE;
292 placement_address += PageSize;
293293 }
294294
295295 if(phys != NULL)
357357 {
358358 // We didn't find any, so we need to add a new header
359359 header * head = (header *) old_end_address;
360 head->magic = HEAP_MAGIC;
360 head->magic = Magic;
361361 head->size = new_length - old_length;
362362 head->is_hole = true;
363363 footer * foot = (footer *) (old_end_address + head->size - sizeof(footer));
364 foot->magic = HEAP_MAGIC;
364 foot->magic = Magic;
365365 foot->head = head;
366366
367367 // Insert this hole into the index
376376 // Rewrite the footer
377377 footer * foot = (footer *) ((uintptr)head + head->size - sizeof(footer));
378378 foot->head = head;
379 foot->magic = HEAP_MAGIC;
379 foot->magic = Magic;
380380 }
381381
382382 // Now we have enough space. Run this function again and return the result
404404 // already aligned. Also, make a hole in front of the block to not waste space
405405 if(page_align && (original_hole_pos & 0xFFFFF000))
406406 {
407 uintptr new_location = original_hole_pos + PAGE_SIZE - (original_hole_pos & 0xFFF) - sizeof(header);
407 uintptr new_location = original_hole_pos + PageSize - (original_hole_pos & 0xFFF) - sizeof(header);
408408
409409 // The new hole's header
410410 header * hole_header = (header *) original_hole_pos;
411 hole_header->size = PAGE_SIZE - (original_hole_pos & 0xFFF) - sizeof(header);
412 hole_header->magic = HEAP_MAGIC;
411 hole_header->size = PageSize - (original_hole_pos & 0xFFF) - sizeof(header);
412 hole_header->magic = Magic;
413413 hole_header->is_hole = true;
414414
415415 // A matching footer before our allocated block
416416 footer * hole_footer = (footer *) ((uintptr)new_location - sizeof(footer));
417 hole_footer->magic = HEAP_MAGIC;
417 hole_footer->magic = Magic;
418418 hole_footer->head = hole_header;
419419 original_hole_pos = new_location;
420420 original_hole_size = original_hole_size - hole_header->size;
427427
428428 // Overwrite the hole's header
429429 header * block_header = (header *) original_hole_pos;
430 block_header->magic = HEAP_MAGIC;
430 block_header->magic = Magic;
431431 block_header->is_hole = false;
432432 block_header->size = new_size;
433433
434434 // And the footer
435435 footer * block_footer = (footer *) (original_hole_pos + sizeof(header) + size);
436 block_footer->magic = HEAP_MAGIC;
436 block_footer->magic = Magic;
437437 block_footer->head = block_header;
438438
439439 // If we have the space, we should make another hole after the block we just allocated
440440 if(original_hole_size - new_size > 0)
441441 {
442442 header * new_hole_header = (header *) (original_hole_pos + sizeof(header) + size + sizeof(footer));
443 new_hole_header->magic = HEAP_MAGIC;
443 new_hole_header->magic = Magic;
444444 new_hole_header->size = original_hole_size - new_size;
445445
446446 // The new hole's matching footer
449449
450450 if((uintptr) new_hole_footer < heap->end_address)
451451 {
452 new_hole_footer->magic = HEAP_MAGIC;
452 new_hole_footer->magic = Magic;
453453 new_hole_footer->head = new_hole_header;
454454 }
455455
474474
475475 // Sanity checks, to make sure that neither the header nor footer have been corrupted
476476 // or overwritten
477 ASSERT(head->magic == HEAP_MAGIC);
478 ASSERT(foot->magic == HEAP_MAGIC);
477 ASSERT(head->magic == Magic);
478 ASSERT(foot->magic == Magic);
479479
480480 // Mark this block of memory as a hole
481481 head->is_hole = true;
488488 footer * test_footer = (footer *) ((uintptr)head - sizeof(footer));
489489
490490 // Check if this is a footer, and see if it is a hole
491 if(test_footer->magic == HEAP_MAGIC && test_footer->head->is_hole)
491 if(test_footer->magic == Magic && test_footer->head->is_hole)
492492 {
493493 // Remember the current memory block's size
494494 u32int cache_size = head->size;
509509 // If the next header in the heap is a hole, unify this and the next hole
510510 header * test_header = (header *) ((uintptr)foot + sizeof(footer));
511511
512 if(test_header->magic == HEAP_MAGIC && test_header->is_hole)
512 if(test_header->magic == Magic && test_header->is_hole)
513513 {
514514 // Increase the hole's header
515515 head->size += test_header->size;
549549
550550 // Get the footer's address
551551 foot = (footer *) ((uintptr)head + head->size - sizeof(footer));
552 foot->magic = HEAP_MAGIC;
552 foot->magic = Magic;
553553
554554 // Point the footer's head var to our header
555555 foot->head = head;
  
33
44#include "common.h"
55
6#define KHEAP_START 0xC0000000
7#define KHEAP_INITIAL_SIZE 0x100000
8#define HEAP_INDEX_SIZE 0x20000
9#define HEAP_MAGIC 0x123890AB
10#define HEAP_MIN_SIZE 0x70000
6// Kheap constants
7const uintptr KHeapStart = 0xC0000000;
8const size_t KHeapInitialSize = 0x100000;
119
1210namespace heap
1311{
12 // General heap constants
13 const size_t IndexSize = 0x20000;
14 const u32int Magic = 0x123890AB;
15 const size_t MinSize = 0x70000;
16
1417 typedef struct
1518 {
1619 uintptr ** array;
  
5858 void move_stack(void * new_stack_start, size_t size)
5959 {
6060 // Allocate space for the new stack
61 for(uintptr i = (uintptr)new_stack_start; i >= ((uintptr)new_stack_start - size); i -= PAGE_SIZE)
61 for(uintptr i = (uintptr)new_stack_start; i >= ((uintptr)new_stack_start - size); i -= PageSize)
6262 {
6363 // The stack should be user mode and writable
6464 paging::allocate_frame(paging::get_page(i, true, current_directory), false, true);