xref: /netbsd-src/sys/arch/hpc/stand/hpcboot/arm/arm_mmu.cpp (revision ce099b40997c43048fb78bd578195f81d2456523)
1*ce099b40Smartin /* -*-C++-*-	$NetBSD: arm_mmu.cpp,v 1.6 2008/04/28 20:23:20 martin Exp $	*/
29173eae7Such 
39173eae7Such /*-
49173eae7Such  * Copyright (c) 2001 The NetBSD Foundation, Inc.
59173eae7Such  * All rights reserved.
69173eae7Such  *
79173eae7Such  * This code is derived from software contributed to The NetBSD Foundation
89173eae7Such  * by UCHIYAMA Yasushi.
99173eae7Such  *
109173eae7Such  * Redistribution and use in source and binary forms, with or without
119173eae7Such  * modification, are permitted provided that the following conditions
129173eae7Such  * are met:
139173eae7Such  * 1. Redistributions of source code must retain the above copyright
149173eae7Such  *    notice, this list of conditions and the following disclaimer.
159173eae7Such  * 2. Redistributions in binary form must reproduce the above copyright
169173eae7Such  *    notice, this list of conditions and the following disclaimer in the
179173eae7Such  *    documentation and/or other materials provided with the distribution.
189173eae7Such  *
199173eae7Such  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
209173eae7Such  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
219173eae7Such  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
229173eae7Such  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
239173eae7Such  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
249173eae7Such  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
259173eae7Such  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
269173eae7Such  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
279173eae7Such  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
289173eae7Such  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
299173eae7Such  * POSSIBILITY OF SUCH DAMAGE.
309173eae7Such  */
319173eae7Such 
329173eae7Such #include <arm/arm_mmu.h>
339173eae7Such #include <console.h>
349173eae7Such 
MemoryManager_ArmMMU(Console * & cons,size_t pagesize)359173eae7Such MemoryManager_ArmMMU::MemoryManager_ArmMMU(Console *&cons,
369173eae7Such     size_t pagesize)
379173eae7Such 	: MemoryManager(cons, pagesize)
389173eae7Such {
399173eae7Such 	DPRINTF((TEXT("Use ARM software MMU.\n")));
409173eae7Such }
419173eae7Such 
~MemoryManager_ArmMMU(void)429173eae7Such MemoryManager_ArmMMU::~MemoryManager_ArmMMU(void)
439173eae7Such {
449173eae7Such 	SetKMode(_kmode);
459173eae7Such }
469173eae7Such 
479173eae7Such BOOL
init(void)489173eae7Such MemoryManager_ArmMMU::init(void)
499173eae7Such {
5024c8a902Suwe 	uint32_t reg;
519173eae7Such 
529173eae7Such 	_kmode = SetKMode(1);
539173eae7Such 	// Check system mode
549173eae7Such 	if ((GetCPSR() & 0x1f) != 0x1f) {
559173eae7Such 		DPRINTF((TEXT("not System mode\n")));
569173eae7Such 		return FALSE;
579173eae7Such 	}
589173eae7Such 	// Domain access control.(full access)
599173eae7Such 	SetCop15Reg3(~0);
609173eae7Such 
619173eae7Such 	// Get Translation table base.
629173eae7Such 	reg = GetCop15Reg2();
639173eae7Such 	_table_base =  reg & ARM_MMU_TABLEBASE_MASK;
649173eae7Such 	DPRINTF((TEXT("page directory address=0x%08x->0x%08x(0x%08x)\n"),
659173eae7Such 	    _table_base, readPhysical4(_table_base), reg));
669173eae7Such 
679173eae7Such 	return TRUE;
689173eae7Such }
699173eae7Such 
709173eae7Such paddr_t
searchPage(vaddr_t vaddr)719173eae7Such MemoryManager_ArmMMU::searchPage(vaddr_t vaddr)
729173eae7Such {
739173eae7Such 	paddr_t daddr, paddr = ~0;
7424c8a902Suwe 	uint32_t desc1, desc2;
759173eae7Such 
769173eae7Such 	// set marker.
779173eae7Such 	memset(LPVOID(vaddr), 0xa5, _page_size);
789173eae7Such 
799173eae7Such 	// PID virtual address mapping.
809173eae7Such 	DPRINTF((TEXT("Virtual Address 0x%08x"), vaddr));
819173eae7Such 	vaddr |= GetCop15Reg13();
829173eae7Such 	DPRINTF((TEXT("(+PID)-> 0x%08x\n"), vaddr));
839173eae7Such 
849173eae7Such 	daddr = _table_base | ARM_MMU_TABLEINDEX(vaddr);
859173eae7Such 	desc1 = readPhysical4(daddr);
869173eae7Such 	DPRINTF((TEXT("1st level descriptor 0x%08x(addr 0x%08x)\n"),
879173eae7Such 	    desc1, daddr));
889173eae7Such 
899173eae7Such 	switch(ARM_MMU_LEVEL1DESC_TRANSLATE_TYPE(desc1)) {
909173eae7Such 	default:
919173eae7Such 		DPRINTF((TEXT("1st level descriptor fault.\n")));
929173eae7Such 		break;
939173eae7Such 	case ARM_MMU_LEVEL1DESC_TRANSLATE_SECTION:
949173eae7Such 		paddr = ARM_MMU_SECTION_BASE(desc1) |
959173eae7Such 		    ARM_MMU_VADDR_SECTION_INDEX(vaddr);
969173eae7Such 		DPRINTF((TEXT("section Physical Address 0x%08x\n"), paddr));
979173eae7Such 		break;
989173eae7Such 	case ARM_MMU_LEVEL1DESC_TRANSLATE_PAGE:
999173eae7Such 		DPRINTF((TEXT("-> Level2 page descriptor.\n")));
1009173eae7Such 		daddr = ARM_MMU_PTE_BASE(desc1) |
1019173eae7Such 		    ARM_MMU_VADDR_PTE_INDEX(vaddr);
1029173eae7Such 		desc2 = readPhysical4(daddr);
1039173eae7Such 		DPRINTF((TEXT("2nd level descriptor 0x%08x(addr 0x%08x)\n"),
1049173eae7Such 		    desc2, daddr));
1059173eae7Such 		switch(desc2 & 0x3) {
1069173eae7Such 		default:
1079173eae7Such 			DPRINTF((TEXT("2nd level descriptor fault.\n")));
1089173eae7Such 			break;
1099173eae7Such 		case 2: // 4Kpage
1109173eae7Such 			paddr =(desc2 & 0xfffff000) |(vaddr & 0x00000fff);
1119173eae7Such 			break;
1129173eae7Such 		case 1: // 64Kpage
1139173eae7Such 			paddr =(desc2 & 0xffff0000) |(vaddr & 0x0000ffff);
1149173eae7Such 			break;
1159173eae7Such 		}
1169173eae7Such 		break;
1179173eae7Such 	}
1189173eae7Such 
1199173eae7Such 	return paddr;
1209173eae7Such }
121