/*1* Copyright 2010 Tilera Corporation. All Rights Reserved.2*3* This program is free software; you can redistribute it and/or4* modify it under the terms of the GNU General Public License5* as published by the Free Software Foundation, version 2.6*7* This program is distributed in the hope that it will be useful, but8* WITHOUT ANY WARRANTY; without even the implied warranty of9* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or10* NON INFRINGEMENT. See the GNU General Public License for11* more details.12*13* This routine is a helper for migrating the home of a set of pages to14* a new cpu. See the documentation in homecache.c for more information.15*/1617#include <linux/linkage.h>18#include <linux/threads.h>19#include <asm/page.h>20#include <asm/thread_info.h>21#include <asm/types.h>22#include <asm/asm-offsets.h>23#include <hv/hypervisor.h>2425.text2627/*28* First, some definitions that apply to all the code in the file.29*/3031/* Locals (caller-save) */32#define r_tmp r1033#define r_save_sp r113435/* What we save where in the stack frame; must include all callee-saves. */36#define FRAME_SP 437#define FRAME_R30 838#define FRAME_R31 1239#define FRAME_R32 1640#define FRAME_R33 2041#define FRAME_R34 2442#define FRAME_R35 2843#define FRAME_SIZE 324445464748/*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*/5859/* Arguments (caller-save) */60#define r_context_lo_in r061#define r_context_hi_in r162#define r_access_lo_in r263#define r_access_hi_in r364#define r_asid_in r465#define r_my_cpumask r56667/* Locals (callee-save); must not be more than FRAME_xxx above. */68#define r_save_ics r3069#define r_context_lo r3170#define r_context_hi r3271#define r_access_lo r3372#define r_access_hi r3473#define r_asid r357475STD_ENTRY(flush_and_install_context)76/*77* Create a stack frame; we can't touch it once we flush the78* cache until we install the new page table and flush the TLB.79*/80{81move r_save_sp, sp82sw sp, lr83addi sp, sp, -FRAME_SIZE84}85addi r_tmp, sp, FRAME_SP86{87sw r_tmp, r_save_sp88addi r_tmp, sp, FRAME_R3089}90{91sw r_tmp, r3092addi r_tmp, sp, FRAME_R3193}94{95sw r_tmp, r3196addi r_tmp, sp, FRAME_R3297}98{99sw r_tmp, r32100addi r_tmp, sp, FRAME_R33101}102{103sw r_tmp, r33104addi r_tmp, sp, FRAME_R34105}106{107sw r_tmp, r34108addi r_tmp, sp, FRAME_R35109}110sw r_tmp, r35111112/* Move some arguments to callee-save registers. */113{114move r_context_lo, r_context_lo_in115move r_context_hi, r_context_hi_in116}117{118move r_access_lo, r_access_lo_in119move r_access_hi, r_access_hi_in120}121move r_asid, r_asid_in122123/* Disable interrupts, since we can't use our stack. */124{125mfspr r_save_ics, INTERRUPT_CRITICAL_SECTION126movei r_tmp, 1127}128mtspr INTERRUPT_CRITICAL_SECTION, r_tmp129130/* First, flush our L2 cache. */131{132move r0, zero /* cache_pa */133move r1, zero134}135{136auli r2, zero, ha16(HV_FLUSH_EVICT_L2) /* cache_control */137move r3, r_my_cpumask /* cache_cpumask */138}139{140move r4, zero /* tlb_va */141move r5, zero /* tlb_length */142}143{144move r6, zero /* tlb_pgsize */145move r7, zero /* tlb_cpumask */146}147{148move r8, zero /* asids */149move r9, zero /* asidcount */150}151jal hv_flush_remote152bnz r0, .Ldone153154/* Now install the new page table. */155{156move r0, r_context_lo157move r1, r_context_hi158}159{160move r2, r_access_lo161move r3, r_access_hi162}163{164move r4, r_asid165movei r5, HV_CTX_DIRECTIO166}167jal hv_install_context168bnz r0, .Ldone169170/* Finally, flush the TLB. */171{172movei r0, 0 /* preserve_global */173jal hv_flush_all174}175176.Ldone:177/* Reset interrupts back how they were before. */178mtspr INTERRUPT_CRITICAL_SECTION, r_save_ics179180/* Restore the callee-saved registers and return. */181addli lr, sp, FRAME_SIZE182{183lw lr, lr184addli r_tmp, sp, FRAME_R30185}186{187lw r30, r_tmp188addli r_tmp, sp, FRAME_R31189}190{191lw r31, r_tmp192addli r_tmp, sp, FRAME_R32193}194{195lw r32, r_tmp196addli r_tmp, sp, FRAME_R33197}198{199lw r33, r_tmp200addli r_tmp, sp, FRAME_R34201}202{203lw r34, r_tmp204addli r_tmp, sp, FRAME_R35205}206{207lw r35, r_tmp208addi sp, sp, FRAME_SIZE209}210jrp lr211STD_ENDPROC(flush_and_install_context)212213214