1/* 2 * Copyright 2011 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 8 38#define FRAME_R30 16 39#define FRAME_R31 24 40#define FRAME_R32 32 41#define FRAME_R33 40 42#define FRAME_SIZE 48 43 44 45 46 47/* 48 * On entry: 49 * 50 * r0 the new context PA to install (moved to r_context) 51 * r1 PTE to use for context access (moved to r_access) 52 * r2 ASID to use for new context (moved to r_asid) 53 * r3 pointer to cpumask with just this cpu set in it (r_my_cpumask) 54 */ 55 56/* Arguments (caller-save) */ 57#define r_context_in r0 58#define r_access_in r1 59#define r_asid_in r2 60#define r_my_cpumask r3 61 62/* Locals (callee-save); must not be more than FRAME_xxx above. */ 63#define r_save_ics r30 64#define r_context r31 65#define r_access r32 66#define r_asid r33 67 68/* 69 * Caller-save locals and frame constants are the same as 70 * for homecache_migrate_stack_and_flush. 71 */ 72 73STD_ENTRY(flush_and_install_context) 74 /* 75 * Create a stack frame; we can't touch it once we flush the 76 * cache until we install the new page table and flush the TLB. 77 */ 78 { 79 move r_save_sp, sp 80 st sp, lr 81 addi sp, sp, -FRAME_SIZE 82 } 83 addi r_tmp, sp, FRAME_SP 84 { 85 st r_tmp, r_save_sp 86 addi r_tmp, sp, FRAME_R30 87 } 88 { 89 st r_tmp, r30 90 addi r_tmp, sp, FRAME_R31 91 } 92 { 93 st r_tmp, r31 94 addi r_tmp, sp, FRAME_R32 95 } 96 { 97 st r_tmp, r32 98 addi r_tmp, sp, FRAME_R33 99 } 100 st r_tmp, r33 101 102 /* Move some arguments to callee-save registers. */ 103 { 104 move r_context, r_context_in 105 move r_access, r_access_in 106 } 107 move r_asid, r_asid_in 108 109 /* Disable interrupts, since we can't use our stack. */ 110 { 111 mfspr r_save_ics, INTERRUPT_CRITICAL_SECTION 112 movei r_tmp, 1 113 } 114 mtspr INTERRUPT_CRITICAL_SECTION, r_tmp 115 116 /* First, flush our L2 cache. */ 117 { 118 move r0, zero /* cache_pa */ 119 moveli r1, hw2_last(HV_FLUSH_EVICT_L2) /* cache_control */ 120 } 121 { 122 shl16insli r1, r1, hw1(HV_FLUSH_EVICT_L2) 123 move r2, r_my_cpumask /* cache_cpumask */ 124 } 125 { 126 shl16insli r1, r1, hw0(HV_FLUSH_EVICT_L2) 127 move r3, zero /* tlb_va */ 128 } 129 { 130 move r4, zero /* tlb_length */ 131 move r5, zero /* tlb_pgsize */ 132 } 133 { 134 move r6, zero /* tlb_cpumask */ 135 move r7, zero /* asids */ 136 } 137 { 138 move r8, zero /* asidcount */ 139 jal hv_flush_remote 140 } 141 bnez r0, 1f 142 143 /* Now install the new page table. */ 144 { 145 move r0, r_context 146 move r1, r_access 147 } 148 { 149 move r2, r_asid 150 movei r3, HV_CTX_DIRECTIO 151 } 152 jal hv_install_context 153 bnez r0, 1f 154 155 /* Finally, flush the TLB. */ 156 { 157 movei r0, 0 /* preserve_global */ 158 jal hv_flush_all 159 } 160 1611: /* Reset interrupts back how they were before. */ 162 mtspr INTERRUPT_CRITICAL_SECTION, r_save_ics 163 164 /* Restore the callee-saved registers and return. */ 165 addli lr, sp, FRAME_SIZE 166 { 167 ld lr, lr 168 addli r_tmp, sp, FRAME_R30 169 } 170 { 171 ld r30, r_tmp 172 addli r_tmp, sp, FRAME_R31 173 } 174 { 175 ld r31, r_tmp 176 addli r_tmp, sp, FRAME_R32 177 } 178 { 179 ld r32, r_tmp 180 addli r_tmp, sp, FRAME_R33 181 } 182 { 183 ld r33, r_tmp 184 addi sp, sp, FRAME_SIZE 185 } 186 jrp lr 187 STD_ENDPROC(flush_and_install_context) 188