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