Example #1
0
void free_pde(page_dir_t *pd, unsigned idx)
{
	if(!pd[idx]) 
		return;
	if(pd[idx] & PAGE_LARGE) {
		mm_physical_deallocate(pd[idx] & PAGE_MASK);
		pd[idx]=0;
		return;
	}
	addr_t physical = pd[idx]&PAGE_MASK;
	assert(!(pd[idx] & (1 << 7)));
	page_table_t *table = (addr_t *)(physical + PHYS_PAGE_MAP);
	for(unsigned i=0;i<512;i++)
	{
		if(table[i])
		{
			addr_t tmp = table[i];
			table[i]=0;
			if((tmp & PAGE_MASK_PHYSICAL) != sysgate_page)
				mm_physical_deallocate(tmp & PAGE_MASK_PHYSICAL);
		}
	}
	pd[idx]=0;
	mm_physical_deallocate(physical);
}
Example #2
0
static void process_memorymap(struct multiboot *mboot)
{
	addr_t i = mboot->mmap_addr;
	unsigned long num_pages = 0;
	unsigned long unusable = 0;
	uint64_t j = 0;
	uint64_t address;
	uint64_t length;
	uint64_t highest_page = 0;
	uint64_t lowest_page = ~0;
	int found_contiguous = 0;
	pm_location = ((((addr_t)&kernel_end - MEMMAP_KERNEL_START) & ~(PAGE_SIZE - 1)) + PAGE_SIZE + 0x100000);
	while ((pm_location >= initrd_start_page && pm_location <= initrd_end_page))
		pm_location += PAGE_SIZE;

	while (i < (mboot->mmap_addr + mboot->mmap_length)) {
		mmap_entry_t *me = (mmap_entry_t *)(i + MEMMAP_KERNEL_START);
		address = ((uint64_t)me->base_addr_high << 32) | (uint64_t)me->base_addr_low;
		length = (((uint64_t)me->length_high << 32) | me->length_low);
		if (me->type == 1 && length > 0)
		{
			for (j = address; j < (address + length); j += PAGE_SIZE)
			{
				addr_t page;
				// 32 bit can only handle addresses up to 0xFFFFFFFF, above this == ignore.
				page = j;

				if (__is_actually_free(page)) {
					if (lowest_page > page)
						lowest_page = page;
					if (page > highest_page)
						highest_page = page;
					num_pages++;
					mm_physical_deallocate(page);
				}
			}
		}
		i += me->size + sizeof(uint32_t);
	}
	printk(1, "[MM]: Highest page = %x, Lowest page = %x, num_pages = %d\n", highest_page, lowest_page, num_pages);
	if (!j)
		PANIC(PANIC_MEM | PANIC_NOSYNC, "Memory map corrupted!", EFAULT);
	int gbs = 0;
	int mbs = ((num_pages * PAGE_SIZE)/1024)/1024;
	if (mbs < 4) {
		printk(KERN_PANIC, "%d MB, %d pages", mbs, num_pages);
		PANIC(PANIC_MEM | PANIC_NOSYNC, "Not enough memory, system wont work!", ENOMEM);
	}
	gbs = mbs/1024;
	if (gbs > 0)
	{
		printk(KERN_MILE, "%d GB", gbs);
		mbs = mbs % 1024;
	}
	printk(KERN_MILE, "%d MB available memory (page size = %d KB, kmalloc=slab: ok)\n", mbs, PAGE_SIZE/1024);
	printk(KERN_DEBUG, "[MM]: num pages = %d\n", num_pages);
	pm_num_pages = num_pages;
	maximum_page_number = highest_page / PAGE_SIZE;
	set_ksf(KSF_MEMMAPPED);
}
Example #3
0
void arch_mm_context_destroy(struct vmm_context *vc)
{
	pml4_t *pml4 = (pml4_t *)vc->root_virtual;
	unsigned int E = PML4_INDEX(MEMMAP_KERNEL_START);
	for(unsigned i=0;i<E;i++)
		free_pml4e(pml4, i);
	mm_physical_deallocate(vc->root_physical);
}
Example #4
0
void free_pml4e(pml4_t *pml4, unsigned idx)
{
	if(!pml4[idx]) 
		return;
	addr_t physical = pml4[idx]&PAGE_MASK;
	pdpt_t *pdpt = (addr_t *)(physical + PHYS_PAGE_MAP);
	for(unsigned i=0;i<512;i++)
		free_pdpte(pdpt, i);
	pml4[idx]=0;
	mm_physical_deallocate(physical);
}
Example #5
0
void free_pdpte(pdpt_t *pdpt, unsigned idx)
{
	if(!pdpt[idx]) 
		return;
	addr_t physical = pdpt[idx]&PAGE_MASK;
	page_dir_t *pd = (addr_t *)(physical + PHYS_PAGE_MAP);
	for(unsigned i=0;i<512;i++)
		free_pde(pd, i);
	pdpt[idx]=0;
	mm_physical_deallocate(physical);
}
Example #6
0
int mm_free_dma_buffer(struct dma_region *d)
{
	int npages = ((d->p.size - 1) / mm_page_size(0)) + 1;
	for (int i = 0; i < npages; i++)
		mm_virtual_unmap(d->v + i * mm_page_size(0));
	mm_physical_deallocate(d->p.address);
	struct valloc_region reg;
	reg.flags = 0;
	reg.start = d->v;
	reg.npages = npages;
	valloc_deallocate(&dma_virtual, &reg);
	d->p.address = d->v = 0;
	return 0;
}
Example #7
0
int mm_physical_decrement_count(addr_t page)
{
	if (!frames)
		return 0;
	ASSERT(page);
	if ((page / PAGE_SIZE) < maximum_page_number) {
		size_t old;
		if ((old = atomic_fetch_sub(&frames[page / PAGE_SIZE].count, 1)) == 1) {
			mm_physical_deallocate(page);
		}
		ASSERT(old);
		return old;
	}
	return 0;
}
Example #8
0
static void process_memorymap(struct multiboot *mboot)
{
	addr_t i = mboot->mmap_addr;
	unsigned long num_pages=0, unusable=0;
	uint64_t j=0, address, length, highest_page = 0, lowest_page = ~0;
	int found_contiguous=0;
	pm_location = ((((addr_t)&kernel_end - MEMMAP_KERNEL_START) & ~(PAGE_SIZE-1)) + PAGE_SIZE + 0x100000 /* HACK */);
	while((pm_location >= initrd_start_page && pm_location <= initrd_end_page))
		pm_location += PAGE_SIZE;

	while(i < (mboot->mmap_addr + mboot->mmap_length)){
		mmap_entry_t *me = (mmap_entry_t *)(i + MEMMAP_KERNEL_START);
		address = ((uint64_t)me->base_addr_high << 32) | (uint64_t)me->base_addr_low;
		length = (((uint64_t)me->length_high<<32) | me->length_low);
		if(me->type == 1 && length > 0)
		{
			for (j=address; 
				j < (address+length); j += PAGE_SIZE)
			{
				addr_t page;
#if ADDR_BITS == 32
				/* 32-bit can only handle the lower 32 bits of the address. If we're
				 * considering an address above 0xFFFFFFFF, we have to ignore it */
				page = (addr_t)(j & 0xFFFFFFFF);
				if((j >> 32) != 0)
					break;
#else
				page = j;
#endif
				if(__is_actually_free(page)) {
					if(lowest_page > page)
						lowest_page=page;
					if(page > highest_page)
						highest_page=page;
					num_pages++;
					mm_physical_deallocate(page);
				}
			}
		}
		i += me->size + sizeof (uint32_t);
	}
	printk(1, "[mm]: Highest page = %x, Lowest page = %x, num_pages = %d               \n", highest_page, lowest_page, num_pages);
	if(!j)
		panic(PANIC_MEM | PANIC_NOSYNC, "Memory map corrupted");
	int gbs=0;
	int mbs = ((num_pages * PAGE_SIZE)/1024)/1024;
	if(mbs < 4){
		panic(PANIC_MEM | PANIC_NOSYNC, 
				"Not enough memory, system wont work (%d MB, %d pages)", 
				mbs, num_pages);
	}
	gbs = mbs/1024;
	if(gbs > 0)
	{
		printk(KERN_MILE, "%d GB and ", gbs);
		mbs = mbs % 1024;
	}
	printk(KERN_MILE, "%d MB available memory (page size=%d KB, kmalloc=slab: ok)\n"
 			, mbs, PAGE_SIZE/1024);
	printk(1, "[mm]: num pages = %d\n", num_pages);
	pm_num_pages=num_pages;
	maximum_page_number = highest_page / PAGE_SIZE;
	set_ksf(KSF_MEMMAPPED);
}