1/* $NetBSD: epoc32.cpp,v 1.2 2016/02/01 17:44:19 christos Exp $ */ 2/* 3 * Copyright (c) 2013 KIYOHARA Takashi 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 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * 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 AUTHOR BE LIABLE FOR ANY DIRECT, 19 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 23 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 28#include <e32base.h> 29#include <e32def.h> 30#include <e32std.h> 31 32#include "cpu.h" 33#include "e32boot.h" 34#include "ekern.h" 35#include "epoc32.h" 36 37#include "arm/armreg.h" 38#include "arm/arm32/pte.h" 39 40 41static inline void 42AllowAllDomains(void) 43{ 44 TUint domains; 45 46#define ALL_DOMAINS(v) \ 47 (((v) << 28) | \ 48 ((v) << 24) | \ 49 ((v) << 20) | \ 50 ((v) << 16) | \ 51 ((v) << 12) | \ 52 ((v) << 8) | \ 53 ((v) << 4) | \ 54 ((v) << 0)) 55 56 domains = ALL_DOMAINS(0xf); 57 __asm("mcr p15, 0, %0, c3, c0" : : "r"(domains)); 58} 59 60EPOC32::EPOC32(const EPOC32& c) 61{ 62 cpu = c.cpu; 63} 64 65EPOC32::EPOC32(void) 66{ 67 TUint procid; 68 69 __asm("mrc p15, 0, %0, c0, c0" : "=r"(procid)); 70 if (procid == CPU_ID_SA1100) { 71 cpu = new SA1100; 72 } else if ((procid & CPU_ID_IMPLEMENTOR_MASK) == CPU_ID_ARM_LTD) { 73 if (CPU_ID_IS7(procid)) { 74 if ((procid & CPU_ID_7ARCH_MASK) == CPU_ID_7ARCH_V3) 75 cpu = new ARM7; 76 else 77 cpu = new ARM7TDMI; 78 } 79 } 80} 81 82EPOC32::~EPOC32(void) 83{ 84} 85 86TAny * 87EPOC32::GetPhysicalAddress(TAny *address) 88{ 89 TUint l1Index, l1, pageOffset, pa, va; 90 TUint *l1Tbl; 91 92 AllowAllDomains(); 93 94 l1Tbl = GetTTB(); 95 96 va = (TUint)address; 97 pa = pageOffset = 0; 98 l1Index = (va & L1_ADDR_BITS) >> L1_S_SHIFT; 99 l1 = *(l1Tbl + l1Index); 100 switch (l1 & L1_TYPE_MASK) { 101 case L1_TYPE_INV: 102 case L1_TYPE_F: 103 return NULL; 104 105 case L1_TYPE_S: 106 pa = l1 & L1_S_ADDR_MASK; 107 pageOffset = va & L1_S_OFFSET; 108 break; 109 110 case L1_TYPE_C: 111 { 112 TUint *l2Tbl, tag; 113 114 l2Tbl = (TUint *)(l1 & L1_C_ADDR_MASK); 115 tag = MapPhysicalAddress(l2Tbl, (TAny **)&l2Tbl); 116 pa = *(l2Tbl + ((va & L2_ADDR_BITS) >> 12)); 117 UnmapPhysicalAddress(l2Tbl, tag); 118 119 switch (pa & L2_TYPE_MASK) { 120 case L2_TYPE_L: 121 pa &= L2_L_FRAME; 122 pageOffset = va & L2_L_OFFSET; 123 break; 124 125 case L2_TYPE_S: 126 pa &= L2_S_FRAME; 127 pageOffset = va & L2_S_OFFSET; 128 break; 129 130 default: 131 pageOffset = 0xffffffff; /* XXXX */ 132 } 133 } 134 } 135 return (TAny *)(pa | pageOffset); 136} 137 138TUint 139EPOC32::MapPhysicalAddress(TAny *pa, TAny **vap) 140{ 141 TUint *l1Tbl, l1Index, l1, tag; 142 143 AllowAllDomains(); 144 145 l1Tbl = GetTTB(); 146 147 l1Index = ((TUint)pa & L1_ADDR_BITS) >> L1_S_SHIFT; 148 l1 = ((TUint)pa & L1_S_ADDR_MASK) | 149 L1_S_AP(AP_KRW) | L1_S_IMP | L1_TYPE_S; 150 tag = *(l1Tbl + l1Index); 151 *(l1Tbl + l1Index) = l1; 152 cpu->cacheFlush(); 153 cpu->tlbFlush(); 154 *vap = pa; 155 156 return tag; 157} 158 159void 160EPOC32::UnmapPhysicalAddress(TAny *address, TUint tag) 161{ 162 TUint *l1Tbl, l1Index, pa; 163 164 AllowAllDomains(); 165 166 l1Tbl = GetTTB(); 167 168 pa = (TUint)address; 169 l1Index = (pa & L1_ADDR_BITS) >> L1_S_SHIFT; 170 *(l1Tbl + l1Index) = tag; 171 cpu->cacheFlush(); 172 cpu->tlbFlush(); 173} 174