//! TODO: currently assumes this translation map is active
/*static*/ status_t
ARMPagingMethod32Bit::_EarlyQuery(addr_t virtualAddress,
	phys_addr_t *_physicalAddress)
{
	ARMPagingMethod32Bit* method = ARMPagingMethod32Bit::Method();
	int index = VADDR_TO_PDENT(virtualAddress);
	if ((method->KernelVirtualPageDirectory()[index] & ARM_PDE_TYPE_MASK) == 0) {
		// no pagetable here
		return B_ERROR;
	}

	page_table_entry* entry = (page_table_entry*)
		(method->KernelVirtualPageDirectory()[index] & ARM_PDE_ADDRESS_MASK);
	entry += VADDR_TO_PTENT(virtualAddress);

	if ((*entry & ARM_PTE_TYPE_MASK) == 0) {
		// page mapping not valid
		return B_ERROR;
	}

	*_physicalAddress = (*entry & ARM_PTE_ADDRESS_MASK)
		| VADDR_TO_PGOFF(virtualAddress);

	return B_OK;
}
/*static*/ void
ARMPagingMethod32Bit::_EarlyPreparePageTables(page_table_entry* pageTables,
	addr_t address, size_t size)
{
	ARMPagingMethod32Bit* method = ARMPagingMethod32Bit::Method();
	memset(pageTables, 0, 256 * (size / (B_PAGE_SIZE * 256)));

	// put the array of pgtables directly into the kernel pagedir
	// these will be wired and kept mapped into virtual space to be easy to get
	// to
	{
		addr_t virtualTable = (addr_t)pageTables;

		for (size_t i = 0; i < (size / (B_PAGE_SIZE * 256));
				i++, virtualTable += 256*sizeof(page_directory_entry)) {
			phys_addr_t physicalTable = 0;
			_EarlyQuery(virtualTable, &physicalTable);
			page_directory_entry* entry = method->KernelVirtualPageDirectory()
				+ VADDR_TO_PDENT(address) + i;
			PutPageTableInPageDir(entry, physicalTable,
				B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
		}
	}
}
Example #3
0
status_t
ARMVMTranslationMap32Bit::Init(bool kernel)
{
	TRACE("ARMVMTranslationMap32Bit::Init()\n");

	ARMVMTranslationMap::Init(kernel);

	fPagingStructures = new(std::nothrow) ARMPagingStructures32Bit;
	if (fPagingStructures == NULL)
		return B_NO_MEMORY;

	ARMPagingMethod32Bit* method = ARMPagingMethod32Bit::Method();

	if (!kernel) {
		// user
		// allocate a physical page mapper
		status_t error = method->PhysicalPageMapper()
			->CreateTranslationMapPhysicalPageMapper(&fPageMapper);
		if (error != B_OK)
			return error;

		// allocate the page directory
		page_directory_entry* virtualPageDir = (page_directory_entry*)memalign(
			B_PAGE_SIZE, B_PAGE_SIZE);
		if (virtualPageDir == NULL)
			return B_NO_MEMORY;

		// look up the page directory's physical address
		phys_addr_t physicalPageDir;
		vm_get_page_mapping(VMAddressSpace::KernelID(),
			(addr_t)virtualPageDir, &physicalPageDir);

		fPagingStructures->Init(virtualPageDir, physicalPageDir,
			method->KernelVirtualPageDirectory());
	} else {
		// kernel
		// get the physical page mapper
		fPageMapper = method->KernelPhysicalPageMapper();

		// we already know the kernel pgdir mapping
		fPagingStructures->Init(method->KernelVirtualPageDirectory(),
			method->KernelPhysicalPageDirectory(), NULL);
	}

	return B_OK;
}