1793b08e2SChristophe Leroy/* SPDX-License-Identifier: GPL-2.0-or-later */ 2793b08e2SChristophe Leroy/* 3793b08e2SChristophe Leroy * This file contains kexec low-level functions. 4793b08e2SChristophe Leroy * 5793b08e2SChristophe Leroy * Copyright (C) 2002-2003 Eric Biederman <ebiederm@xmission.com> 6793b08e2SChristophe Leroy * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz 7793b08e2SChristophe Leroy * PPC44x port. Copyright (C) 2011, IBM Corporation 8793b08e2SChristophe Leroy * Author: Suzuki Poulose <suzuki@in.ibm.com> 9793b08e2SChristophe Leroy */ 10793b08e2SChristophe Leroy 11793b08e2SChristophe Leroy#include <asm/reg.h> 12793b08e2SChristophe Leroy#include <asm/page.h> 13793b08e2SChristophe Leroy#include <asm/mmu.h> 14793b08e2SChristophe Leroy#include <asm/ppc_asm.h> 15793b08e2SChristophe Leroy#include <asm/kexec.h> 16793b08e2SChristophe Leroy 17793b08e2SChristophe Leroy .text 18793b08e2SChristophe Leroy 19793b08e2SChristophe Leroy /* 20793b08e2SChristophe Leroy * Must be relocatable PIC code callable as a C function. 21793b08e2SChristophe Leroy */ 22793b08e2SChristophe Leroy .globl relocate_new_kernel 23793b08e2SChristophe Leroyrelocate_new_kernel: 24793b08e2SChristophe Leroy /* r3 = page_list */ 25793b08e2SChristophe Leroy /* r4 = reboot_code_buffer */ 26793b08e2SChristophe Leroy /* r5 = start_address */ 27793b08e2SChristophe Leroy 28*dfc3095cSChristophe Leroy#ifdef CONFIG_PPC_85xx 29793b08e2SChristophe Leroy 30793b08e2SChristophe Leroy mr r29, r3 31793b08e2SChristophe Leroy mr r30, r4 32793b08e2SChristophe Leroy mr r31, r5 33793b08e2SChristophe Leroy 34793b08e2SChristophe Leroy#define ENTRY_MAPPING_KEXEC_SETUP 35*dfc3095cSChristophe Leroy#include <kernel/85xx_entry_mapping.S> 36793b08e2SChristophe Leroy#undef ENTRY_MAPPING_KEXEC_SETUP 37793b08e2SChristophe Leroy 38793b08e2SChristophe Leroy mr r3, r29 39793b08e2SChristophe Leroy mr r4, r30 40793b08e2SChristophe Leroy mr r5, r31 41793b08e2SChristophe Leroy 42793b08e2SChristophe Leroy li r0, 0 43793b08e2SChristophe Leroy#elif defined(CONFIG_44x) 44793b08e2SChristophe Leroy 45793b08e2SChristophe Leroy /* Save our parameters */ 46793b08e2SChristophe Leroy mr r29, r3 47793b08e2SChristophe Leroy mr r30, r4 48793b08e2SChristophe Leroy mr r31, r5 49793b08e2SChristophe Leroy 50793b08e2SChristophe Leroy#ifdef CONFIG_PPC_47x 51793b08e2SChristophe Leroy /* Check for 47x cores */ 52793b08e2SChristophe Leroy mfspr r3,SPRN_PVR 53793b08e2SChristophe Leroy srwi r3,r3,16 54793b08e2SChristophe Leroy cmplwi cr0,r3,PVR_476FPE@h 55793b08e2SChristophe Leroy beq setup_map_47x 56793b08e2SChristophe Leroy cmplwi cr0,r3,PVR_476@h 57793b08e2SChristophe Leroy beq setup_map_47x 58793b08e2SChristophe Leroy cmplwi cr0,r3,PVR_476_ISS@h 59793b08e2SChristophe Leroy beq setup_map_47x 60793b08e2SChristophe Leroy#endif /* CONFIG_PPC_47x */ 61793b08e2SChristophe Leroy 62793b08e2SChristophe Leroy/* 63793b08e2SChristophe Leroy * Code for setting up 1:1 mapping for PPC440x for KEXEC 64793b08e2SChristophe Leroy * 65793b08e2SChristophe Leroy * We cannot switch off the MMU on PPC44x. 66793b08e2SChristophe Leroy * So we: 67793b08e2SChristophe Leroy * 1) Invalidate all the mappings except the one we are running from. 68793b08e2SChristophe Leroy * 2) Create a tmp mapping for our code in the other address space(TS) and 69793b08e2SChristophe Leroy * jump to it. Invalidate the entry we started in. 70793b08e2SChristophe Leroy * 3) Create a 1:1 mapping for 0-2GiB in chunks of 256M in original TS. 71793b08e2SChristophe Leroy * 4) Jump to the 1:1 mapping in original TS. 72793b08e2SChristophe Leroy * 5) Invalidate the tmp mapping. 73793b08e2SChristophe Leroy * 74793b08e2SChristophe Leroy * - Based on the kexec support code for FSL BookE 75793b08e2SChristophe Leroy * 76793b08e2SChristophe Leroy */ 77793b08e2SChristophe Leroy 78793b08e2SChristophe Leroy /* 79793b08e2SChristophe Leroy * Load the PID with kernel PID (0). 80793b08e2SChristophe Leroy * Also load our MSR_IS and TID to MMUCR for TLB search. 81793b08e2SChristophe Leroy */ 82793b08e2SChristophe Leroy li r3, 0 83793b08e2SChristophe Leroy mtspr SPRN_PID, r3 84793b08e2SChristophe Leroy mfmsr r4 85793b08e2SChristophe Leroy andi. r4,r4,MSR_IS@l 86793b08e2SChristophe Leroy beq wmmucr 87793b08e2SChristophe Leroy oris r3,r3,PPC44x_MMUCR_STS@h 88793b08e2SChristophe Leroywmmucr: 89793b08e2SChristophe Leroy mtspr SPRN_MMUCR,r3 90793b08e2SChristophe Leroy sync 91793b08e2SChristophe Leroy 92793b08e2SChristophe Leroy /* 93793b08e2SChristophe Leroy * Invalidate all the TLB entries except the current entry 94793b08e2SChristophe Leroy * where we are running from 95793b08e2SChristophe Leroy */ 9633e14024SChristophe Leroy bcl 20,31,$+4 /* Find our address */ 97793b08e2SChristophe Leroy0: mflr r5 /* Make it accessible */ 98793b08e2SChristophe Leroy tlbsx r23,0,r5 /* Find entry we are in */ 99793b08e2SChristophe Leroy li r4,0 /* Start at TLB entry 0 */ 100793b08e2SChristophe Leroy li r3,0 /* Set PAGEID inval value */ 101793b08e2SChristophe Leroy1: cmpw r23,r4 /* Is this our entry? */ 102793b08e2SChristophe Leroy beq skip /* If so, skip the inval */ 103793b08e2SChristophe Leroy tlbwe r3,r4,PPC44x_TLB_PAGEID /* If not, inval the entry */ 104793b08e2SChristophe Leroyskip: 105793b08e2SChristophe Leroy addi r4,r4,1 /* Increment */ 106793b08e2SChristophe Leroy cmpwi r4,64 /* Are we done? */ 107793b08e2SChristophe Leroy bne 1b /* If not, repeat */ 108793b08e2SChristophe Leroy isync 109793b08e2SChristophe Leroy 110793b08e2SChristophe Leroy /* Create a temp mapping and jump to it */ 111793b08e2SChristophe Leroy andi. r6, r23, 1 /* Find the index to use */ 112793b08e2SChristophe Leroy addi r24, r6, 1 /* r24 will contain 1 or 2 */ 113793b08e2SChristophe Leroy 114793b08e2SChristophe Leroy mfmsr r9 /* get the MSR */ 115793b08e2SChristophe Leroy rlwinm r5, r9, 27, 31, 31 /* Extract the MSR[IS] */ 116793b08e2SChristophe Leroy xori r7, r5, 1 /* Use the other address space */ 117793b08e2SChristophe Leroy 118793b08e2SChristophe Leroy /* Read the current mapping entries */ 119793b08e2SChristophe Leroy tlbre r3, r23, PPC44x_TLB_PAGEID 120793b08e2SChristophe Leroy tlbre r4, r23, PPC44x_TLB_XLAT 121793b08e2SChristophe Leroy tlbre r5, r23, PPC44x_TLB_ATTRIB 122793b08e2SChristophe Leroy 123793b08e2SChristophe Leroy /* Save our current XLAT entry */ 124793b08e2SChristophe Leroy mr r25, r4 125793b08e2SChristophe Leroy 126793b08e2SChristophe Leroy /* Extract the TLB PageSize */ 127793b08e2SChristophe Leroy li r10, 1 /* r10 will hold PageSize */ 128793b08e2SChristophe Leroy rlwinm r11, r3, 0, 24, 27 /* bits 24-27 */ 129793b08e2SChristophe Leroy 130793b08e2SChristophe Leroy /* XXX: As of now we use 256M, 4K pages */ 131793b08e2SChristophe Leroy cmpwi r11, PPC44x_TLB_256M 132793b08e2SChristophe Leroy bne tlb_4k 133793b08e2SChristophe Leroy rotlwi r10, r10, 28 /* r10 = 256M */ 134793b08e2SChristophe Leroy b write_out 135793b08e2SChristophe Leroytlb_4k: 136793b08e2SChristophe Leroy cmpwi r11, PPC44x_TLB_4K 137793b08e2SChristophe Leroy bne default 138793b08e2SChristophe Leroy rotlwi r10, r10, 12 /* r10 = 4K */ 139793b08e2SChristophe Leroy b write_out 140793b08e2SChristophe Leroydefault: 141793b08e2SChristophe Leroy rotlwi r10, r10, 10 /* r10 = 1K */ 142793b08e2SChristophe Leroy 143793b08e2SChristophe Leroywrite_out: 144793b08e2SChristophe Leroy /* 145793b08e2SChristophe Leroy * Write out the tmp 1:1 mapping for this code in other address space 146793b08e2SChristophe Leroy * Fixup EPN = RPN , TS=other address space 147793b08e2SChristophe Leroy */ 148793b08e2SChristophe Leroy insrwi r3, r7, 1, 23 /* Bit 23 is TS for PAGEID field */ 149793b08e2SChristophe Leroy 150793b08e2SChristophe Leroy /* Write out the tmp mapping entries */ 151793b08e2SChristophe Leroy tlbwe r3, r24, PPC44x_TLB_PAGEID 152793b08e2SChristophe Leroy tlbwe r4, r24, PPC44x_TLB_XLAT 153793b08e2SChristophe Leroy tlbwe r5, r24, PPC44x_TLB_ATTRIB 154793b08e2SChristophe Leroy 155793b08e2SChristophe Leroy subi r11, r10, 1 /* PageOffset Mask = PageSize - 1 */ 156793b08e2SChristophe Leroy not r10, r11 /* Mask for PageNum */ 157793b08e2SChristophe Leroy 158793b08e2SChristophe Leroy /* Switch to other address space in MSR */ 159793b08e2SChristophe Leroy insrwi r9, r7, 1, 26 /* Set MSR[IS] = r7 */ 160793b08e2SChristophe Leroy 16133e14024SChristophe Leroy bcl 20,31,$+4 162793b08e2SChristophe Leroy1: mflr r8 163793b08e2SChristophe Leroy addi r8, r8, (2f-1b) /* Find the target offset */ 164793b08e2SChristophe Leroy 165793b08e2SChristophe Leroy /* Jump to the tmp mapping */ 166793b08e2SChristophe Leroy mtspr SPRN_SRR0, r8 167793b08e2SChristophe Leroy mtspr SPRN_SRR1, r9 168793b08e2SChristophe Leroy rfi 169793b08e2SChristophe Leroy 170793b08e2SChristophe Leroy2: 171793b08e2SChristophe Leroy /* Invalidate the entry we were executing from */ 172793b08e2SChristophe Leroy li r3, 0 173793b08e2SChristophe Leroy tlbwe r3, r23, PPC44x_TLB_PAGEID 174793b08e2SChristophe Leroy 175793b08e2SChristophe Leroy /* attribute fields. rwx for SUPERVISOR mode */ 176793b08e2SChristophe Leroy li r5, 0 177793b08e2SChristophe Leroy ori r5, r5, (PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G) 178793b08e2SChristophe Leroy 179793b08e2SChristophe Leroy /* Create 1:1 mapping in 256M pages */ 180793b08e2SChristophe Leroy xori r7, r7, 1 /* Revert back to Original TS */ 181793b08e2SChristophe Leroy 182793b08e2SChristophe Leroy li r8, 0 /* PageNumber */ 183793b08e2SChristophe Leroy li r6, 3 /* TLB Index, start at 3 */ 184793b08e2SChristophe Leroy 185793b08e2SChristophe Leroynext_tlb: 186793b08e2SChristophe Leroy rotlwi r3, r8, 28 /* Create EPN (bits 0-3) */ 187793b08e2SChristophe Leroy mr r4, r3 /* RPN = EPN */ 188793b08e2SChristophe Leroy ori r3, r3, (PPC44x_TLB_VALID | PPC44x_TLB_256M) /* SIZE = 256M, Valid */ 189793b08e2SChristophe Leroy insrwi r3, r7, 1, 23 /* Set TS from r7 */ 190793b08e2SChristophe Leroy 191793b08e2SChristophe Leroy tlbwe r3, r6, PPC44x_TLB_PAGEID /* PageID field : EPN, V, SIZE */ 192793b08e2SChristophe Leroy tlbwe r4, r6, PPC44x_TLB_XLAT /* Address translation : RPN */ 193793b08e2SChristophe Leroy tlbwe r5, r6, PPC44x_TLB_ATTRIB /* Attributes */ 194793b08e2SChristophe Leroy 195793b08e2SChristophe Leroy addi r8, r8, 1 /* Increment PN */ 196793b08e2SChristophe Leroy addi r6, r6, 1 /* Increment TLB Index */ 197793b08e2SChristophe Leroy cmpwi r8, 8 /* Are we done ? */ 198793b08e2SChristophe Leroy bne next_tlb 199793b08e2SChristophe Leroy isync 200793b08e2SChristophe Leroy 201793b08e2SChristophe Leroy /* Jump to the new mapping 1:1 */ 202793b08e2SChristophe Leroy li r9,0 203793b08e2SChristophe Leroy insrwi r9, r7, 1, 26 /* Set MSR[IS] = r7 */ 204793b08e2SChristophe Leroy 20533e14024SChristophe Leroy bcl 20,31,$+4 206793b08e2SChristophe Leroy1: mflr r8 207793b08e2SChristophe Leroy and r8, r8, r11 /* Get our offset within page */ 208793b08e2SChristophe Leroy addi r8, r8, (2f-1b) 209793b08e2SChristophe Leroy 210793b08e2SChristophe Leroy and r5, r25, r10 /* Get our target PageNum */ 211793b08e2SChristophe Leroy or r8, r8, r5 /* Target jump address */ 212793b08e2SChristophe Leroy 213793b08e2SChristophe Leroy mtspr SPRN_SRR0, r8 214793b08e2SChristophe Leroy mtspr SPRN_SRR1, r9 215793b08e2SChristophe Leroy rfi 216793b08e2SChristophe Leroy2: 217793b08e2SChristophe Leroy /* Invalidate the tmp entry we used */ 218793b08e2SChristophe Leroy li r3, 0 219793b08e2SChristophe Leroy tlbwe r3, r24, PPC44x_TLB_PAGEID 220793b08e2SChristophe Leroy sync 221793b08e2SChristophe Leroy b ppc44x_map_done 222793b08e2SChristophe Leroy 223793b08e2SChristophe Leroy#ifdef CONFIG_PPC_47x 224793b08e2SChristophe Leroy 225793b08e2SChristophe Leroy /* 1:1 mapping for 47x */ 226793b08e2SChristophe Leroy 227793b08e2SChristophe Leroysetup_map_47x: 228793b08e2SChristophe Leroy 229793b08e2SChristophe Leroy /* 230793b08e2SChristophe Leroy * Load the kernel pid (0) to PID and also to MMUCR[TID]. 231793b08e2SChristophe Leroy * Also set the MSR IS->MMUCR STS 232793b08e2SChristophe Leroy */ 233793b08e2SChristophe Leroy li r3, 0 234793b08e2SChristophe Leroy mtspr SPRN_PID, r3 /* Set PID */ 235793b08e2SChristophe Leroy mfmsr r4 /* Get MSR */ 236793b08e2SChristophe Leroy andi. r4, r4, MSR_IS@l /* TS=1? */ 237793b08e2SChristophe Leroy beq 1f /* If not, leave STS=0 */ 238793b08e2SChristophe Leroy oris r3, r3, PPC47x_MMUCR_STS@h /* Set STS=1 */ 239793b08e2SChristophe Leroy1: mtspr SPRN_MMUCR, r3 /* Put MMUCR */ 240793b08e2SChristophe Leroy sync 241793b08e2SChristophe Leroy 242793b08e2SChristophe Leroy /* Find the entry we are running from */ 24333e14024SChristophe Leroy bcl 20,31,$+4 244793b08e2SChristophe Leroy2: mflr r23 245793b08e2SChristophe Leroy tlbsx r23, 0, r23 246793b08e2SChristophe Leroy tlbre r24, r23, 0 /* TLB Word 0 */ 247793b08e2SChristophe Leroy tlbre r25, r23, 1 /* TLB Word 1 */ 248793b08e2SChristophe Leroy tlbre r26, r23, 2 /* TLB Word 2 */ 249793b08e2SChristophe Leroy 250793b08e2SChristophe Leroy 251793b08e2SChristophe Leroy /* 252793b08e2SChristophe Leroy * Invalidates all the tlb entries by writing to 256 RPNs(r4) 253793b08e2SChristophe Leroy * of 4k page size in all 4 ways (0-3 in r3). 254793b08e2SChristophe Leroy * This would invalidate the entire UTLB including the one we are 255793b08e2SChristophe Leroy * running from. However the shadow TLB entries would help us 256793b08e2SChristophe Leroy * to continue the execution, until we flush them (rfi/isync). 257793b08e2SChristophe Leroy */ 258793b08e2SChristophe Leroy addis r3, 0, 0x8000 /* specify the way */ 259793b08e2SChristophe Leroy addi r4, 0, 0 /* TLB Word0 = (EPN=0, VALID = 0) */ 260793b08e2SChristophe Leroy addi r5, 0, 0 261793b08e2SChristophe Leroy b clear_utlb_entry 262793b08e2SChristophe Leroy 263793b08e2SChristophe Leroy /* Align the loop to speed things up. from head_44x.S */ 264793b08e2SChristophe Leroy .align 6 265793b08e2SChristophe Leroy 266793b08e2SChristophe Leroyclear_utlb_entry: 267793b08e2SChristophe Leroy 268793b08e2SChristophe Leroy tlbwe r4, r3, 0 269793b08e2SChristophe Leroy tlbwe r5, r3, 1 270793b08e2SChristophe Leroy tlbwe r5, r3, 2 271793b08e2SChristophe Leroy addis r3, r3, 0x2000 /* Increment the way */ 272793b08e2SChristophe Leroy cmpwi r3, 0 273793b08e2SChristophe Leroy bne clear_utlb_entry 274793b08e2SChristophe Leroy addis r3, 0, 0x8000 275793b08e2SChristophe Leroy addis r4, r4, 0x100 /* Increment the EPN */ 276793b08e2SChristophe Leroy cmpwi r4, 0 277793b08e2SChristophe Leroy bne clear_utlb_entry 278793b08e2SChristophe Leroy 279793b08e2SChristophe Leroy /* Create the entries in the other address space */ 280793b08e2SChristophe Leroy mfmsr r5 281793b08e2SChristophe Leroy rlwinm r7, r5, 27, 31, 31 /* Get the TS (Bit 26) from MSR */ 282793b08e2SChristophe Leroy xori r7, r7, 1 /* r7 = !TS */ 283793b08e2SChristophe Leroy 284793b08e2SChristophe Leroy insrwi r24, r7, 1, 21 /* Change the TS in the saved TLB word 0 */ 285793b08e2SChristophe Leroy 286793b08e2SChristophe Leroy /* 287793b08e2SChristophe Leroy * write out the TLB entries for the tmp mapping 288793b08e2SChristophe Leroy * Use way '0' so that we could easily invalidate it later. 289793b08e2SChristophe Leroy */ 290793b08e2SChristophe Leroy lis r3, 0x8000 /* Way '0' */ 291793b08e2SChristophe Leroy 292793b08e2SChristophe Leroy tlbwe r24, r3, 0 293793b08e2SChristophe Leroy tlbwe r25, r3, 1 294793b08e2SChristophe Leroy tlbwe r26, r3, 2 295793b08e2SChristophe Leroy 296793b08e2SChristophe Leroy /* Update the msr to the new TS */ 297793b08e2SChristophe Leroy insrwi r5, r7, 1, 26 298793b08e2SChristophe Leroy 29933e14024SChristophe Leroy bcl 20,31,$+4 300793b08e2SChristophe Leroy1: mflr r6 301793b08e2SChristophe Leroy addi r6, r6, (2f-1b) 302793b08e2SChristophe Leroy 303793b08e2SChristophe Leroy mtspr SPRN_SRR0, r6 304793b08e2SChristophe Leroy mtspr SPRN_SRR1, r5 305793b08e2SChristophe Leroy rfi 306793b08e2SChristophe Leroy 307793b08e2SChristophe Leroy /* 308793b08e2SChristophe Leroy * Now we are in the tmp address space. 309793b08e2SChristophe Leroy * Create a 1:1 mapping for 0-2GiB in the original TS. 310793b08e2SChristophe Leroy */ 311793b08e2SChristophe Leroy2: 312793b08e2SChristophe Leroy li r3, 0 313793b08e2SChristophe Leroy li r4, 0 /* TLB Word 0 */ 314793b08e2SChristophe Leroy li r5, 0 /* TLB Word 1 */ 315793b08e2SChristophe Leroy li r6, 0 316793b08e2SChristophe Leroy ori r6, r6, PPC47x_TLB2_S_RWX /* TLB word 2 */ 317793b08e2SChristophe Leroy 318793b08e2SChristophe Leroy li r8, 0 /* PageIndex */ 319793b08e2SChristophe Leroy 320793b08e2SChristophe Leroy xori r7, r7, 1 /* revert back to original TS */ 321793b08e2SChristophe Leroy 322793b08e2SChristophe Leroywrite_utlb: 323793b08e2SChristophe Leroy rotlwi r5, r8, 28 /* RPN = PageIndex * 256M */ 324793b08e2SChristophe Leroy /* ERPN = 0 as we don't use memory above 2G */ 325793b08e2SChristophe Leroy 326793b08e2SChristophe Leroy mr r4, r5 /* EPN = RPN */ 327793b08e2SChristophe Leroy ori r4, r4, (PPC47x_TLB0_VALID | PPC47x_TLB0_256M) 328793b08e2SChristophe Leroy insrwi r4, r7, 1, 21 /* Insert the TS to Word 0 */ 329793b08e2SChristophe Leroy 330793b08e2SChristophe Leroy tlbwe r4, r3, 0 /* Write out the entries */ 331793b08e2SChristophe Leroy tlbwe r5, r3, 1 332793b08e2SChristophe Leroy tlbwe r6, r3, 2 333793b08e2SChristophe Leroy addi r8, r8, 1 334793b08e2SChristophe Leroy cmpwi r8, 8 /* Have we completed ? */ 335793b08e2SChristophe Leroy bne write_utlb 336793b08e2SChristophe Leroy 337793b08e2SChristophe Leroy /* make sure we complete the TLB write up */ 338793b08e2SChristophe Leroy isync 339793b08e2SChristophe Leroy 340793b08e2SChristophe Leroy /* 341793b08e2SChristophe Leroy * Prepare to jump to the 1:1 mapping. 342793b08e2SChristophe Leroy * 1) Extract page size of the tmp mapping 343793b08e2SChristophe Leroy * DSIZ = TLB_Word0[22:27] 344793b08e2SChristophe Leroy * 2) Calculate the physical address of the address 345793b08e2SChristophe Leroy * to jump to. 346793b08e2SChristophe Leroy */ 347793b08e2SChristophe Leroy rlwinm r10, r24, 0, 22, 27 348793b08e2SChristophe Leroy 349793b08e2SChristophe Leroy cmpwi r10, PPC47x_TLB0_4K 350793b08e2SChristophe Leroy bne 0f 351793b08e2SChristophe Leroy li r10, 0x1000 /* r10 = 4k */ 352793b08e2SChristophe Leroy bl 1f 353793b08e2SChristophe Leroy 354793b08e2SChristophe Leroy0: 355793b08e2SChristophe Leroy /* Defaults to 256M */ 356793b08e2SChristophe Leroy lis r10, 0x1000 357793b08e2SChristophe Leroy 35833e14024SChristophe Leroy bcl 20,31,$+4 359793b08e2SChristophe Leroy1: mflr r4 360793b08e2SChristophe Leroy addi r4, r4, (2f-1b) /* virtual address of 2f */ 361793b08e2SChristophe Leroy 362793b08e2SChristophe Leroy subi r11, r10, 1 /* offsetmask = Pagesize - 1 */ 363793b08e2SChristophe Leroy not r10, r11 /* Pagemask = ~(offsetmask) */ 364793b08e2SChristophe Leroy 365793b08e2SChristophe Leroy and r5, r25, r10 /* Physical page */ 366793b08e2SChristophe Leroy and r6, r4, r11 /* offset within the current page */ 367793b08e2SChristophe Leroy 368793b08e2SChristophe Leroy or r5, r5, r6 /* Physical address for 2f */ 369793b08e2SChristophe Leroy 370793b08e2SChristophe Leroy /* Switch the TS in MSR to the original one */ 371793b08e2SChristophe Leroy mfmsr r8 372793b08e2SChristophe Leroy insrwi r8, r7, 1, 26 373793b08e2SChristophe Leroy 374793b08e2SChristophe Leroy mtspr SPRN_SRR1, r8 375793b08e2SChristophe Leroy mtspr SPRN_SRR0, r5 376793b08e2SChristophe Leroy rfi 377793b08e2SChristophe Leroy 378793b08e2SChristophe Leroy2: 379793b08e2SChristophe Leroy /* Invalidate the tmp mapping */ 380793b08e2SChristophe Leroy lis r3, 0x8000 /* Way '0' */ 381793b08e2SChristophe Leroy 382793b08e2SChristophe Leroy clrrwi r24, r24, 12 /* Clear the valid bit */ 383793b08e2SChristophe Leroy tlbwe r24, r3, 0 384793b08e2SChristophe Leroy tlbwe r25, r3, 1 385793b08e2SChristophe Leroy tlbwe r26, r3, 2 386793b08e2SChristophe Leroy 387793b08e2SChristophe Leroy /* Make sure we complete the TLB write and flush the shadow TLB */ 388793b08e2SChristophe Leroy isync 389793b08e2SChristophe Leroy 390793b08e2SChristophe Leroy#endif 391793b08e2SChristophe Leroy 392793b08e2SChristophe Leroyppc44x_map_done: 393793b08e2SChristophe Leroy 394793b08e2SChristophe Leroy 395793b08e2SChristophe Leroy /* Restore the parameters */ 396793b08e2SChristophe Leroy mr r3, r29 397793b08e2SChristophe Leroy mr r4, r30 398793b08e2SChristophe Leroy mr r5, r31 399793b08e2SChristophe Leroy 400793b08e2SChristophe Leroy li r0, 0 401793b08e2SChristophe Leroy#else 402793b08e2SChristophe Leroy li r0, 0 403793b08e2SChristophe Leroy 404793b08e2SChristophe Leroy /* 405793b08e2SChristophe Leroy * Set Machine Status Register to a known status, 406793b08e2SChristophe Leroy * switch the MMU off and jump to 1: in a single step. 407793b08e2SChristophe Leroy */ 408793b08e2SChristophe Leroy 409793b08e2SChristophe Leroy mr r8, r0 410793b08e2SChristophe Leroy ori r8, r8, MSR_RI|MSR_ME 411793b08e2SChristophe Leroy mtspr SPRN_SRR1, r8 412793b08e2SChristophe Leroy addi r8, r4, 1f - relocate_new_kernel 413793b08e2SChristophe Leroy mtspr SPRN_SRR0, r8 414793b08e2SChristophe Leroy sync 415793b08e2SChristophe Leroy rfi 416793b08e2SChristophe Leroy 417793b08e2SChristophe Leroy1: 418793b08e2SChristophe Leroy#endif 419793b08e2SChristophe Leroy /* from this point address translation is turned off */ 420793b08e2SChristophe Leroy /* and interrupts are disabled */ 421793b08e2SChristophe Leroy 422793b08e2SChristophe Leroy /* set a new stack at the bottom of our page... */ 423793b08e2SChristophe Leroy /* (not really needed now) */ 424793b08e2SChristophe Leroy addi r1, r4, KEXEC_CONTROL_PAGE_SIZE - 8 /* for LR Save+Back Chain */ 425793b08e2SChristophe Leroy stw r0, 0(r1) 426793b08e2SChristophe Leroy 427793b08e2SChristophe Leroy /* Do the copies */ 428793b08e2SChristophe Leroy li r6, 0 /* checksum */ 429793b08e2SChristophe Leroy mr r0, r3 430793b08e2SChristophe Leroy b 1f 431793b08e2SChristophe Leroy 432793b08e2SChristophe Leroy0: /* top, read another word for the indirection page */ 433793b08e2SChristophe Leroy lwzu r0, 4(r3) 434793b08e2SChristophe Leroy 435793b08e2SChristophe Leroy1: 436793b08e2SChristophe Leroy /* is it a destination page? (r8) */ 437793b08e2SChristophe Leroy rlwinm. r7, r0, 0, 31, 31 /* IND_DESTINATION (1<<0) */ 438793b08e2SChristophe Leroy beq 2f 439793b08e2SChristophe Leroy 440793b08e2SChristophe Leroy rlwinm r8, r0, 0, 0, 19 /* clear kexec flags, page align */ 441793b08e2SChristophe Leroy b 0b 442793b08e2SChristophe Leroy 443793b08e2SChristophe Leroy2: /* is it an indirection page? (r3) */ 444793b08e2SChristophe Leroy rlwinm. r7, r0, 0, 30, 30 /* IND_INDIRECTION (1<<1) */ 445793b08e2SChristophe Leroy beq 2f 446793b08e2SChristophe Leroy 447793b08e2SChristophe Leroy rlwinm r3, r0, 0, 0, 19 /* clear kexec flags, page align */ 448793b08e2SChristophe Leroy subi r3, r3, 4 449793b08e2SChristophe Leroy b 0b 450793b08e2SChristophe Leroy 451793b08e2SChristophe Leroy2: /* are we done? */ 452793b08e2SChristophe Leroy rlwinm. r7, r0, 0, 29, 29 /* IND_DONE (1<<2) */ 453793b08e2SChristophe Leroy beq 2f 454793b08e2SChristophe Leroy b 3f 455793b08e2SChristophe Leroy 456793b08e2SChristophe Leroy2: /* is it a source page? (r9) */ 457793b08e2SChristophe Leroy rlwinm. r7, r0, 0, 28, 28 /* IND_SOURCE (1<<3) */ 458793b08e2SChristophe Leroy beq 0b 459793b08e2SChristophe Leroy 460793b08e2SChristophe Leroy rlwinm r9, r0, 0, 0, 19 /* clear kexec flags, page align */ 461793b08e2SChristophe Leroy 462793b08e2SChristophe Leroy li r7, PAGE_SIZE / 4 463793b08e2SChristophe Leroy mtctr r7 464793b08e2SChristophe Leroy subi r9, r9, 4 465793b08e2SChristophe Leroy subi r8, r8, 4 466793b08e2SChristophe Leroy9: 467793b08e2SChristophe Leroy lwzu r0, 4(r9) /* do the copy */ 468793b08e2SChristophe Leroy xor r6, r6, r0 469793b08e2SChristophe Leroy stwu r0, 4(r8) 470793b08e2SChristophe Leroy dcbst 0, r8 471793b08e2SChristophe Leroy sync 472793b08e2SChristophe Leroy icbi 0, r8 473793b08e2SChristophe Leroy bdnz 9b 474793b08e2SChristophe Leroy 475793b08e2SChristophe Leroy addi r9, r9, 4 476793b08e2SChristophe Leroy addi r8, r8, 4 477793b08e2SChristophe Leroy b 0b 478793b08e2SChristophe Leroy 479793b08e2SChristophe Leroy3: 480793b08e2SChristophe Leroy 481793b08e2SChristophe Leroy /* To be certain of avoiding problems with self-modifying code 482793b08e2SChristophe Leroy * execute a serializing instruction here. 483793b08e2SChristophe Leroy */ 484793b08e2SChristophe Leroy isync 485793b08e2SChristophe Leroy sync 486793b08e2SChristophe Leroy 487793b08e2SChristophe Leroy mfspr r3, SPRN_PIR /* current core we are running on */ 488793b08e2SChristophe Leroy mr r4, r5 /* load physical address of chunk called */ 489793b08e2SChristophe Leroy 490793b08e2SChristophe Leroy /* jump to the entry point, usually the setup routine */ 491793b08e2SChristophe Leroy mtlr r5 492793b08e2SChristophe Leroy blrl 493793b08e2SChristophe Leroy 494793b08e2SChristophe Leroy1: b 1b 495793b08e2SChristophe Leroy 496793b08e2SChristophe Leroyrelocate_new_kernel_end: 497793b08e2SChristophe Leroy 498793b08e2SChristophe Leroy .globl relocate_new_kernel_size 499793b08e2SChristophe Leroyrelocate_new_kernel_size: 500793b08e2SChristophe Leroy .long relocate_new_kernel_end - relocate_new_kernel 501