tlb.h revision 82904
1/*- 2 * Copyright (c) 2001 Jake Burkholder. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 * $FreeBSD: head/sys/sparc64/include/tlb.h 82904 2001-09-03 22:57:21Z jake $ 27 */ 28 29#ifndef _MACHINE_TLB_H_ 30#define _MACHINE_TLB_H_ 31 32#include <sys/ktr.h> 33 34#define TLB_SLOT_COUNT 64 35 36#define TLB_SLOT_TSB_KERNEL_MIN 60 /* XXX */ 37#define TLB_SLOT_TSB_USER_PRIMARY 61 38#define TLB_SLOT_TSB_USER_SECONDARY 62 39#define TLB_SLOT_KERNEL 63 40 41#define TLB_DAR_SLOT_SHIFT (3) 42#define TLB_DAR_SLOT(slot) ((slot) << TLB_DAR_SLOT_SHIFT) 43 44#define TLB_TAR_VA(va) ((va) & ~PAGE_MASK) 45#define TLB_TAR_CTX(ctx) ((ctx) & PAGE_MASK) 46 47#define TLB_DEMAP_ID_SHIFT (4) 48#define TLB_DEMAP_ID_PRIMARY (0) 49#define TLB_DEMAP_ID_SECONDARY (1) 50#define TLB_DEMAP_ID_NUCLEUS (2) 51 52#define TLB_DEMAP_TYPE_SHIFT (6) 53#define TLB_DEMAP_TYPE_PAGE (0) 54#define TLB_DEMAP_TYPE_CONTEXT (1) 55 56#define TLB_DEMAP_VA(va) ((va) & ~PAGE_MASK) 57#define TLB_DEMAP_ID(id) ((id) << TLB_DEMAP_ID_SHIFT) 58#define TLB_DEMAP_TYPE(type) ((type) << TLB_DEMAP_TYPE_SHIFT) 59 60#define TLB_DEMAP_PAGE (TLB_DEMAP_TYPE(TLB_DEMAP_TYPE_PAGE)) 61#define TLB_DEMAP_CONTEXT (TLB_DEMAP_TYPE(TLB_DEMAP_TYPE_CONTEXT)) 62 63#define TLB_DEMAP_PRIMARY (TLB_DEMAP_ID(TLB_DEMAP_ID_PRIMARY)) 64#define TLB_DEMAP_SECONDARY (TLB_DEMAP_ID(TLB_DEMAP_ID_SECONDARY)) 65#define TLB_DEMAP_NUCLEUS (TLB_DEMAP_ID(TLB_DEMAP_ID_NUCLEUS)) 66 67#define TLB_CTX_KERNEL (0) 68 69#define TLB_DTLB (1 << 0) 70#define TLB_ITLB (1 << 1) 71 72#define MMU_SFSR_ASI_SHIFT (16) 73#define MMU_SFSR_FT_SHIFT (7) 74#define MMU_SFSR_E_SHIFT (6) 75#define MMU_SFSR_CT_SHIFT (4) 76#define MMU_SFSR_PR_SHIFT (3) 77#define MMU_SFSR_W_SHIFT (2) 78#define MMU_SFSR_OW_SHIFT (1) 79#define MMU_SFSR_FV_SHIFT (0) 80 81#define MMU_SFSR_ASI_SIZE (8) 82#define MMU_SFSR_FT_SIZE (6) 83#define MMU_SFSR_CT_SIZE (2) 84 85#define MMU_SFSR_W (1L << MMU_SFSR_W_SHIFT) 86 87static __inline void 88tlb_dtlb_page_demap(u_long ctx, vm_offset_t va) 89{ 90 if (ctx == TLB_CTX_KERNEL) { 91 stxa(TLB_DEMAP_VA(va) | TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE, 92 ASI_DMMU_DEMAP, 0); 93 membar(Sync); 94 } else { 95 stxa(AA_DMMU_SCXR, ASI_DMMU, ctx); 96 membar(Sync); 97 stxa(TLB_DEMAP_VA(va) | TLB_DEMAP_SECONDARY | TLB_DEMAP_PAGE, 98 ASI_DMMU_DEMAP, 0); 99 stxa(AA_DMMU_SCXR, ASI_DMMU, 0); 100 membar(Sync); 101 } 102} 103 104static __inline void 105tlb_dtlb_store(vm_offset_t va, u_long ctx, struct tte tte) 106{ 107 stxa(AA_DMMU_TAR, ASI_DMMU, 108 TLB_TAR_VA(va) | TLB_TAR_CTX(ctx)); 109 stxa(0, ASI_DTLB_DATA_IN_REG, tte.tte_data); 110 membar(Sync); 111} 112 113static __inline void 114tlb_dtlb_store_slot(vm_offset_t va, u_long ctx, struct tte tte, int slot) 115{ 116 stxa(AA_DMMU_TAR, ASI_DMMU, TLB_TAR_VA(va) | TLB_TAR_CTX(ctx)); 117 stxa(TLB_DAR_SLOT(slot), ASI_DTLB_DATA_ACCESS_REG, tte.tte_data); 118 membar(Sync); 119} 120 121static __inline void 122tlb_itlb_page_demap(u_long ctx, vm_offset_t va) 123{ 124 if (ctx == TLB_CTX_KERNEL) { 125 stxa(TLB_DEMAP_VA(va) | TLB_DEMAP_NUCLEUS | TLB_DEMAP_PAGE, 126 ASI_IMMU_DEMAP, 0); 127 flush(KERNBASE); 128 } else { 129 stxa(AA_DMMU_SCXR, ASI_DMMU, ctx); 130 membar(Sync); 131 stxa(TLB_DEMAP_VA(va) | TLB_DEMAP_SECONDARY | TLB_DEMAP_PAGE, 132 ASI_IMMU_DEMAP, 0); 133 stxa(AA_DMMU_SCXR, ASI_DMMU, 0); 134 /* flush probably not needed. */ 135 membar(Sync); 136 } 137} 138 139static __inline void 140tlb_itlb_store(vm_offset_t va, u_long ctx, struct tte tte) 141{ 142 stxa(AA_IMMU_TAR, ASI_IMMU, TLB_TAR_VA(va) | TLB_TAR_CTX(ctx)); 143 stxa(0, ASI_ITLB_DATA_IN_REG, tte.tte_data); 144 if (ctx == TLB_CTX_KERNEL) 145 flush(va); 146 else { 147 /* 148 * flush probably not needed and impossible here, no access to 149 * user page. 150 */ 151 membar(Sync); 152 } 153} 154 155static __inline void 156tlb_itlb_store_slot(vm_offset_t va, u_long ctx, struct tte tte, int slot) 157{ 158 stxa(AA_IMMU_TAR, ASI_IMMU, TLB_TAR_VA(va) | TLB_TAR_CTX(ctx)); 159 stxa(TLB_DAR_SLOT(slot), ASI_ITLB_DATA_ACCESS_REG, tte.tte_data); 160 flush(va); 161} 162 163static __inline void 164tlb_page_demap(u_int tlb, u_int ctx, vm_offset_t va) 165{ 166 CTR3(KTR_CT1, "tlb_page_demap: tlb=%#x ctx=%#lx va=%#lx", tlb, ctx, va); 167 if (tlb & TLB_DTLB) 168 tlb_dtlb_page_demap(ctx, va); 169 if (tlb & TLB_ITLB) 170 tlb_itlb_page_demap(ctx, va); 171} 172 173static __inline void 174tlb_store(u_int tlb, vm_offset_t va, u_long ctx, struct tte tte) 175{ 176 CTR4(KTR_CT1, "tlb_store: tlb=%#x va=%#lx ctx=%#lx data=%#lx", 177 tlb, va, ctx, tte.tte_data); 178 if (tlb & TLB_DTLB) 179 tlb_dtlb_store(va, ctx, tte); 180 if (tlb & TLB_ITLB) 181 tlb_itlb_store(va, ctx, tte); 182} 183 184static __inline void 185tlb_store_slot(u_int tlb, vm_offset_t va, u_long ctx, struct tte tte, int slot) 186{ 187 CTR5(KTR_CT1, 188 "tlb_store_slot: tlb=%d va=%#lx ctx=%#lx data=%#lx slot=%d", 189 tlb, va, ctx, tte.tte_data, slot); 190 if (tlb & TLB_DTLB) 191 tlb_dtlb_store_slot(va, ctx, tte, slot); 192 if (tlb & TLB_ITLB) 193 tlb_itlb_store_slot(va, ctx, tte, slot); 194} 195 196#endif /* !_MACHINE_TLB_H_ */ 197