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