/*1* Copyright 2011 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 837#define FRAME_R30 1638#define FRAME_R31 2439#define FRAME_R32 3240#define FRAME_R33 4041#define FRAME_SIZE 484243444546/*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*/5455/* Arguments (caller-save) */56#define r_context_in r057#define r_access_in r158#define r_asid_in r259#define r_my_cpumask r36061/* Locals (callee-save); must not be more than FRAME_xxx above. */62#define r_save_ics r3063#define r_context r3164#define r_access r3265#define r_asid r336667/*68* Caller-save locals and frame constants are the same as69* for homecache_migrate_stack_and_flush.70*/7172STD_ENTRY(flush_and_install_context)73/*74* Create a stack frame; we can't touch it once we flush the75* cache until we install the new page table and flush the TLB.76*/77{78move r_save_sp, sp79st sp, lr80addi sp, sp, -FRAME_SIZE81}82addi r_tmp, sp, FRAME_SP83{84st r_tmp, r_save_sp85addi r_tmp, sp, FRAME_R3086}87{88st r_tmp, r3089addi r_tmp, sp, FRAME_R3190}91{92st r_tmp, r3193addi r_tmp, sp, FRAME_R3294}95{96st r_tmp, r3297addi r_tmp, sp, FRAME_R3398}99st r_tmp, r33100101/* Move some arguments to callee-save registers. */102{103move r_context, r_context_in104move r_access, r_access_in105}106move r_asid, r_asid_in107108/* Disable interrupts, since we can't use our stack. */109{110mfspr r_save_ics, INTERRUPT_CRITICAL_SECTION111movei r_tmp, 1112}113mtspr INTERRUPT_CRITICAL_SECTION, r_tmp114115/* First, flush our L2 cache. */116{117move r0, zero /* cache_pa */118moveli r1, hw2_last(HV_FLUSH_EVICT_L2) /* cache_control */119}120{121shl16insli r1, r1, hw1(HV_FLUSH_EVICT_L2)122move r2, r_my_cpumask /* cache_cpumask */123}124{125shl16insli r1, r1, hw0(HV_FLUSH_EVICT_L2)126move r3, zero /* tlb_va */127}128{129move r4, zero /* tlb_length */130move r5, zero /* tlb_pgsize */131}132{133move r6, zero /* tlb_cpumask */134move r7, zero /* asids */135}136{137move r8, zero /* asidcount */138jal hv_flush_remote139}140bnez r0, 1f141142/* Now install the new page table. */143{144move r0, r_context145move r1, r_access146}147{148move r2, r_asid149movei r3, HV_CTX_DIRECTIO150}151jal hv_install_context152bnez r0, 1f153154/* Finally, flush the TLB. */155{156movei r0, 0 /* preserve_global */157jal hv_flush_all158}1591601: /* Reset interrupts back how they were before. */161mtspr INTERRUPT_CRITICAL_SECTION, r_save_ics162163/* Restore the callee-saved registers and return. */164addli lr, sp, FRAME_SIZE165{166ld lr, lr167addli r_tmp, sp, FRAME_R30168}169{170ld r30, r_tmp171addli r_tmp, sp, FRAME_R31172}173{174ld r31, r_tmp175addli r_tmp, sp, FRAME_R32176}177{178ld r32, r_tmp179addli r_tmp, sp, FRAME_R33180}181{182ld r33, r_tmp183addi sp, sp, FRAME_SIZE184}185jrp lr186STD_ENDPROC(flush_and_install_context)187188189