machdep_ppc4xx.c revision 330897
1/*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (c) 2011-2012 Semihalf. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29#include <sys/cdefs.h> 30__FBSDID("$FreeBSD: stable/11/sys/powerpc/booke/machdep_ppc4xx.c 330897 2018-03-14 03:19:51Z eadler $"); 31 32#include <sys/types.h> 33#include <sys/systm.h> 34 35#include <machine/machdep.h> 36 37#include <powerpc/booke/dcr.h> 38#include <powerpc/apm86xxx/apm86xxx.h> 39 40#include <dev/fdt/fdt_common.h> 41 42#define OCP_ADDR_WORDLO(addr) ((uint32_t)((uint64_t)(addr) & 0xFFFFFFFF)) 43#define OCP_ADDR_WORDHI(addr) ((uint32_t)((uint64_t)(addr) >> 32)) 44 45extern void tlb_write(u_int, uint32_t, uint32_t, uint32_t, tlbtid_t, uint32_t, 46 uint32_t); 47extern void tlb_read(u_int, uint32_t *, uint32_t *, uint32_t *, uint32_t *, 48 uint32_t *, uint32_t *); 49 50unsigned int tlb_static_entries; 51unsigned int tlb_current_entry = TLB_SIZE; 52unsigned int tlb_misses = 0; 53unsigned int tlb_invals = 0; 54 55void tlb_map(uint32_t, uint32_t, uint32_t, uint32_t, uint32_t); 56void tlb_map_mem(uint32_t, uint32_t, uint32_t); 57void tlb_dump(void); 58 59void 60booke_init_tlb(vm_paddr_t fdt_immr_pa) 61{ 62 63 /* Map register space */ 64 tlb_map(APM86XXX_DEEP_SLEEP_VA, 65 OCP_ADDR_WORDLO(APM86XXX_DEEP_SLEEP_PA), 66 OCP_ADDR_WORDHI(APM86XXX_DEEP_SLEEP_PA), TLB_VALID | TLB_SIZE_16M, 67 TLB_SW | TLB_SR | TLB_I | TLB_G); 68 69 tlb_map(APM86XXX_CSR_VA, OCP_ADDR_WORDLO(APM86XXX_CSR_PA), 70 OCP_ADDR_WORDHI(APM86XXX_CSR_PA), TLB_VALID | TLB_SIZE_16M, 71 TLB_SW | TLB_SR | TLB_I | TLB_G); 72 73 tlb_map(APM86XXX_PRIMARY_FABRIC_VA, 74 OCP_ADDR_WORDLO(APM86XXX_PRIMARY_FABRIC_PA), 75 OCP_ADDR_WORDHI(APM86XXX_PRIMARY_FABRIC_PA), 76 TLB_VALID | TLB_SIZE_16M, 77 TLB_SW | TLB_SR | TLB_I | TLB_G); 78 79 tlb_map(APM86XXX_AHB_VA, OCP_ADDR_WORDLO(APM86XXX_AHB_PA), 80 OCP_ADDR_WORDHI(APM86XXX_AHB_PA), 81 TLB_VALID | TLB_SIZE_16M, 82 TLB_SW | TLB_SR | TLB_I | TLB_G); 83 84 /* Map MailBox space */ 85 tlb_map(APM86XXX_MBOX_VA, OCP_ADDR_WORDLO(APM86XXX_MBOX_PA), 86 OCP_ADDR_WORDHI(APM86XXX_MBOX_PA), 87 TLB_VALID | TLB_SIZE_4K, 88 TLB_UX | TLB_UW | TLB_UR | 89 TLB_SX | TLB_SW | TLB_SR | 90 TLB_I | TLB_G); 91 92 tlb_map(APM86XXX_MBOX_VA + 0x1000, 93 OCP_ADDR_WORDLO(APM86XXX_MBOX_PA) + 0x1000, 94 OCP_ADDR_WORDHI(APM86XXX_MBOX_PA), 95 TLB_VALID | TLB_SIZE_4K, 96 TLB_UX | TLB_UW | TLB_UR | 97 TLB_SX | TLB_SW | TLB_SR | 98 TLB_I | TLB_G); 99 100 tlb_map(APM86XXX_MBOX_VA + 0x2000, 101 OCP_ADDR_WORDLO(APM86XXX_MBOX_PA)+ 0x2000, 102 OCP_ADDR_WORDHI(APM86XXX_MBOX_PA), 103 TLB_VALID | TLB_SIZE_4K, 104 TLB_UX | TLB_UW | TLB_UR | 105 TLB_SX | TLB_SW | TLB_SR | 106 TLB_I | TLB_G); 107} 108 109void 110booke_enable_l1_cache(void) 111{ 112} 113 114void 115booke_enable_l2_cache(void) 116{ 117} 118 119void 120booke_enable_l3_cache(void) 121{ 122} 123 124void 125booke_disable_l2_cache(void) 126{ 127 uint32_t ccr1,l2cr0; 128 129 /* Disable L2 cache op broadcast */ 130 ccr1 = mfspr(SPR_CCR1); 131 ccr1 &= ~CCR1_L2COBE; 132 mtspr(SPR_CCR1, ccr1); 133 134 /* Set L2 array size to 0 i.e. disable L2 cache */ 135 mtdcr(DCR_L2DCDCRAI, DCR_L2CR0); 136 l2cr0 = mfdcr(DCR_L2DCDCRDI); 137 l2cr0 &= ~L2CR0_AS; 138 mtdcr(DCR_L2DCDCRDI, l2cr0); 139} 140 141void tlb_map(uint32_t epn, uint32_t rpn, uint32_t erpn, uint32_t flags, 142 uint32_t perms) 143{ 144 145 tlb_write(++tlb_static_entries, epn, rpn, erpn, 0, flags, perms); 146} 147 148static void tlb_dump_entry(u_int entry) 149{ 150 uint32_t epn, rpn, erpn, tid, flags, perms; 151 const char *size; 152 153 tlb_read(entry, &epn, &rpn, &erpn, &tid, &flags, &perms); 154 155 switch (flags & TLB_SIZE_MASK) { 156 case TLB_SIZE_1K: 157 size = " 1k"; 158 break; 159 case TLB_SIZE_4K: 160 size = " 4k"; 161 break; 162 case TLB_SIZE_16K: 163 size = " 16k"; 164 break; 165 case TLB_SIZE_256K: 166 size = "256k"; 167 break; 168 case TLB_SIZE_1M: 169 size = " 1M"; 170 break; 171 case TLB_SIZE_16M: 172 size = " 16M"; 173 break; 174 case TLB_SIZE_256M: 175 size = "256M"; 176 break; 177 case TLB_SIZE_1G: 178 size = " 1G"; 179 break; 180 default: 181 size = "????"; 182 break; 183 } 184 185 186 printf("TLB[%02u]: 0x%08X => " 187 "0x%01X_%08X %s %c %c %s %s %s %s %s " 188 "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c (%u)\n", 189 entry, epn, erpn, rpn, size, 190 (flags & TLB_TS) ? '1' : '0', 191 (flags & TLB_VALID) ? 'V' : '.', 192 (perms & TLB_WL1) ? "WL1" : "___", 193 (perms & TLB_IL1I) ? "IL1I" : "____", 194 (perms & TLB_IL1D) ? "IL1D" : "____", 195 (perms & TLB_IL2I) ? "IL2I" : "____", 196 (perms & TLB_IL2D) ? "IL2D" : "____", 197 (perms & TLB_U0) ? '1' : '.', 198 (perms & TLB_U1) ? '2' : '.', 199 (perms & TLB_U2) ? '3' : '.', 200 (perms & TLB_U3) ? '4' : '.', 201 (perms & TLB_W) ? 'W' : '.', 202 (perms & TLB_I) ? 'I' : '.', 203 (perms & TLB_M) ? 'M' : '.', 204 (perms & TLB_G) ? 'G' : '.', 205 (perms & TLB_E) ? 'E' : '.', 206 (perms & TLB_UX) ? 'x' : '.', 207 (perms & TLB_UW) ? 'w' : '.', 208 (perms & TLB_UR) ? 'r' : '.', 209 (perms & TLB_SX) ? 'X' : '.', 210 (perms & TLB_SW) ? 'W' : '.', 211 (perms & TLB_SR) ? 'R' : '.', 212 tid); 213} 214 215void tlb_dump(void) 216{ 217 int i; 218 219 for (i = 0; i < TLB_SIZE; i++) 220 tlb_dump_entry(i); 221} 222