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