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_SIZE 28 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_context_lo r30 69#define r_context_hi r31 70#define r_access_lo r32 71#define r_access_hi r33 72#define r_asid r34 73 74STD_ENTRY(flush_and_install_context) 75 /* 76 * Create a stack frame; we can't touch it once we flush the 77 * cache until we install the new page table and flush the TLB. 78 */ 79 { 80 move r_save_sp, sp 81 sw sp, lr 82 addi sp, sp, -FRAME_SIZE 83 } 84 addi r_tmp, sp, FRAME_SP 85 { 86 sw r_tmp, r_save_sp 87 addi r_tmp, sp, FRAME_R30 88 } 89 { 90 sw r_tmp, r30 91 addi r_tmp, sp, FRAME_R31 92 } 93 { 94 sw r_tmp, r31 95 addi r_tmp, sp, FRAME_R32 96 } 97 { 98 sw r_tmp, r32 99 addi r_tmp, sp, FRAME_R33 100 } 101 { 102 sw r_tmp, r33 103 addi r_tmp, sp, FRAME_R34 104 } 105 sw r_tmp, r34 106 107 /* Move some arguments to callee-save registers. */ 108 { 109 move r_context_lo, r_context_lo_in 110 move r_context_hi, r_context_hi_in 111 } 112 { 113 move r_access_lo, r_access_lo_in 114 move r_access_hi, r_access_hi_in 115 } 116 move r_asid, r_asid_in 117 118 /* First, flush our L2 cache. */ 119 { 120 move r0, zero /* cache_pa */ 121 move r1, zero 122 } 123 { 124 auli r2, zero, ha16(HV_FLUSH_EVICT_L2) /* cache_control */ 125 move r3, r_my_cpumask /* cache_cpumask */ 126 } 127 { 128 move r4, zero /* tlb_va */ 129 move r5, zero /* tlb_length */ 130 } 131 { 132 move r6, zero /* tlb_pgsize */ 133 move r7, zero /* tlb_cpumask */ 134 } 135 { 136 move r8, zero /* asids */ 137 move r9, zero /* asidcount */ 138 } 139 jal _hv_flush_remote 140 bnz r0, .Ldone 141 142 /* Now install the new page table. */ 143 { 144 move r0, r_context_lo 145 move r1, r_context_hi 146 } 147 { 148 move r2, r_access_lo 149 move r3, r_access_hi 150 } 151 { 152 move r4, r_asid 153 moveli r5, HV_CTX_DIRECTIO | CTX_PAGE_FLAG 154 } 155 jal _hv_install_context 156 bnz r0, .Ldone 157 158 /* Finally, flush the TLB. */ 159 { 160 movei r0, 0 /* preserve_global */ 161 jal hv_flush_all 162 } 163 164.Ldone: 165 /* Restore the callee-saved registers and return. */ 166 addli lr, sp, FRAME_SIZE 167 { 168 lw lr, lr 169 addli r_tmp, sp, FRAME_R30 170 } 171 { 172 lw r30, r_tmp 173 addli r_tmp, sp, FRAME_R31 174 } 175 { 176 lw r31, r_tmp 177 addli r_tmp, sp, FRAME_R32 178 } 179 { 180 lw r32, r_tmp 181 addli r_tmp, sp, FRAME_R33 182 } 183 { 184 lw r33, r_tmp 185 addli r_tmp, sp, FRAME_R34 186 } 187 { 188 lw r34, r_tmp 189 addi sp, sp, FRAME_SIZE 190 } 191 jrp lr 192 STD_ENDPROC(flush_and_install_context) 193