1/* 2 * Copyright 2010 Tilera Corporation. All Rights Reserved. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation, version 2. 7 * 8 * This program is distributed in the hope that it will be useful, but 9 * WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or 11 * NON INFRINGEMENT. See the GNU General Public License for 12 * more details. 13 * 14 * This routine is a helper for migrating the home of a set of pages to 15 * a new cpu. See the documentation in homecache.c for more information. 16 */ 17 18#include <linux/linkage.h> 19#include <linux/threads.h> 20#include <asm/page.h> 21#include <asm/thread_info.h> 22#include <asm/types.h> 23#include <asm/asm-offsets.h> 24#include <hv/hypervisor.h> 25 26 .text 27 28/* 29 * First, some definitions that apply to all the code in the file. 30 */ 31 32/* Locals (caller-save) */ 33#define r_tmp r10 34#define r_save_sp r11 35 36/* What we save where in the stack frame; must include all callee-saves. */ 37#define FRAME_SP 4 38#define FRAME_R30 8 39#define FRAME_R31 12 40#define FRAME_R32 16 41#define FRAME_R33 20 42#define FRAME_R34 24 43#define FRAME_R35 28 44#define FRAME_SIZE 32 45 46 47 48 49/* 50 * On entry: 51 * 52 * r0 low word of the new context PA to install (moved to r_context_lo) 53 * r1 high word of the new context PA to install (moved to r_context_hi) 54 * r2 low word of PTE to use for context access (moved to r_access_lo) 55 * r3 high word of PTE to use for context access (moved to r_access_lo) 56 * r4 ASID to use for new context (moved to r_asid) 57 * r5 pointer to cpumask with just this cpu set in it (r_my_cpumask) 58 */ 59 60/* Arguments (caller-save) */ 61#define r_context_lo_in r0 62#define r_context_hi_in r1 63#define r_access_lo_in r2 64#define r_access_hi_in r3 65#define r_asid_in r4 66#define r_my_cpumask r5 67 68/* Locals (callee-save); must not be more than FRAME_xxx above. */ 69#define r_save_ics r30 70#define r_context_lo r31 71#define r_context_hi r32 72#define r_access_lo r33 73#define r_access_hi r34 74#define r_asid r35 75 76STD_ENTRY(flush_and_install_context) 77 /* 78 * Create a stack frame; we can't touch it once we flush the 79 * cache until we install the new page table and flush the TLB. 80 */ 81 { 82 move r_save_sp, sp 83 sw sp, lr 84 addi sp, sp, -FRAME_SIZE 85 } 86 addi r_tmp, sp, FRAME_SP 87 { 88 sw r_tmp, r_save_sp 89 addi r_tmp, sp, FRAME_R30 90 } 91 { 92 sw r_tmp, r30 93 addi r_tmp, sp, FRAME_R31 94 } 95 { 96 sw r_tmp, r31 97 addi r_tmp, sp, FRAME_R32 98 } 99 { 100 sw r_tmp, r32 101 addi r_tmp, sp, FRAME_R33 102 } 103 { 104 sw r_tmp, r33 105 addi r_tmp, sp, FRAME_R34 106 } 107 { 108 sw r_tmp, r34 109 addi r_tmp, sp, FRAME_R35 110 } 111 sw r_tmp, r35 112 113 /* Move some arguments to callee-save registers. */ 114 { 115 move r_context_lo, r_context_lo_in 116 move r_context_hi, r_context_hi_in 117 } 118 { 119 move r_access_lo, r_access_lo_in 120 move r_access_hi, r_access_hi_in 121 } 122 move r_asid, r_asid_in 123 124 /* Disable interrupts, since we can't use our stack. */ 125 { 126 mfspr r_save_ics, INTERRUPT_CRITICAL_SECTION 127 movei r_tmp, 1 128 } 129 mtspr INTERRUPT_CRITICAL_SECTION, r_tmp 130 131 /* First, flush our L2 cache. */ 132 { 133 move r0, zero /* cache_pa */ 134 move r1, zero 135 } 136 { 137 auli r2, zero, ha16(HV_FLUSH_EVICT_L2) /* cache_control */ 138 move r3, r_my_cpumask /* cache_cpumask */ 139 } 140 { 141 move r4, zero /* tlb_va */ 142 move r5, zero /* tlb_length */ 143 } 144 { 145 move r6, zero /* tlb_pgsize */ 146 move r7, zero /* tlb_cpumask */ 147 } 148 { 149 move r8, zero /* asids */ 150 move r9, zero /* asidcount */ 151 } 152 jal hv_flush_remote 153 bnz r0, .Ldone 154 155 /* Now install the new page table. */ 156 { 157 move r0, r_context_lo 158 move r1, r_context_hi 159 } 160 { 161 move r2, r_access_lo 162 move r3, r_access_hi 163 } 164 { 165 move r4, r_asid 166 movei r5, HV_CTX_DIRECTIO 167 } 168 jal hv_install_context 169 bnz r0, .Ldone 170 171 /* Finally, flush the TLB. */ 172 { 173 movei r0, 0 /* preserve_global */ 174 jal hv_flush_all 175 } 176 177.Ldone: 178 /* Reset interrupts back how they were before. */ 179 mtspr INTERRUPT_CRITICAL_SECTION, r_save_ics 180 181 /* Restore the callee-saved registers and return. */ 182 addli lr, sp, FRAME_SIZE 183 { 184 lw lr, lr 185 addli r_tmp, sp, FRAME_R30 186 } 187 { 188 lw r30, r_tmp 189 addli r_tmp, sp, FRAME_R31 190 } 191 { 192 lw r31, r_tmp 193 addli r_tmp, sp, FRAME_R32 194 } 195 { 196 lw r32, r_tmp 197 addli r_tmp, sp, FRAME_R33 198 } 199 { 200 lw r33, r_tmp 201 addli r_tmp, sp, FRAME_R34 202 } 203 { 204 lw r34, r_tmp 205 addli r_tmp, sp, FRAME_R35 206 } 207 { 208 lw r35, r_tmp 209 addi sp, sp, FRAME_SIZE 210 } 211 jrp lr 212 STD_ENDPROC(flush_and_install_context) 213