1533090e5SChristophe Leroy/* SPDX-License-Identifier: GPL-2.0-or-later */ 2533090e5SChristophe Leroy/* 3533090e5SChristophe Leroy * PowerPC version 4533090e5SChristophe Leroy * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) 5533090e5SChristophe Leroy * 6533090e5SChristophe Leroy * Rewritten by Cort Dougan (cort@cs.nmt.edu) for PReP 7533090e5SChristophe Leroy * Copyright (C) 1996 Cort Dougan <cort@cs.nmt.edu> 8533090e5SChristophe Leroy * Adapted for Power Macintosh by Paul Mackerras. 9533090e5SChristophe Leroy * Low-level exception handlers and MMU support 10533090e5SChristophe Leroy * rewritten by Paul Mackerras. 11533090e5SChristophe Leroy * Copyright (C) 1996 Paul Mackerras. 12533090e5SChristophe Leroy * MPC8xx modifications Copyright (C) 1997 Dan Malek (dmalek@jlc.net). 13533090e5SChristophe Leroy * 14533090e5SChristophe Leroy * This file contains the low-level support and setup for the 15533090e5SChristophe Leroy * PowerPC platform, including trap and interrupt dispatch. 16533090e5SChristophe Leroy * (The PPC 8xx embedded CPUs use head_8xx.S instead.) 17533090e5SChristophe Leroy */ 18533090e5SChristophe Leroy 19533090e5SChristophe Leroy#include <linux/init.h> 20533090e5SChristophe Leroy#include <linux/pgtable.h> 212da37761SChristophe Leroy#include <linux/linkage.h> 222da37761SChristophe Leroy 23533090e5SChristophe Leroy#include <asm/reg.h> 24533090e5SChristophe Leroy#include <asm/page.h> 25533090e5SChristophe Leroy#include <asm/mmu.h> 26533090e5SChristophe Leroy#include <asm/cputable.h> 27533090e5SChristophe Leroy#include <asm/cache.h> 28533090e5SChristophe Leroy#include <asm/thread_info.h> 29533090e5SChristophe Leroy#include <asm/ppc_asm.h> 30533090e5SChristophe Leroy#include <asm/asm-offsets.h> 31533090e5SChristophe Leroy#include <asm/ptrace.h> 32533090e5SChristophe Leroy#include <asm/bug.h> 33533090e5SChristophe Leroy#include <asm/kvm_book3s_asm.h> 34533090e5SChristophe Leroy#include <asm/feature-fixups.h> 357fab6397SChristophe Leroy#include <asm/interrupt.h> 36533090e5SChristophe Leroy 37533090e5SChristophe Leroy#include "head_32.h" 38533090e5SChristophe Leroy 39533090e5SChristophe Leroy#define LOAD_BAT(n, reg, RA, RB) \ 40533090e5SChristophe Leroy /* see the comment for clear_bats() -- Cort */ \ 41533090e5SChristophe Leroy li RA,0; \ 42533090e5SChristophe Leroy mtspr SPRN_IBAT##n##U,RA; \ 43533090e5SChristophe Leroy mtspr SPRN_DBAT##n##U,RA; \ 44533090e5SChristophe Leroy lwz RA,(n*16)+0(reg); \ 45533090e5SChristophe Leroy lwz RB,(n*16)+4(reg); \ 46533090e5SChristophe Leroy mtspr SPRN_IBAT##n##U,RA; \ 47533090e5SChristophe Leroy mtspr SPRN_IBAT##n##L,RB; \ 48533090e5SChristophe Leroy lwz RA,(n*16)+8(reg); \ 49533090e5SChristophe Leroy lwz RB,(n*16)+12(reg); \ 50533090e5SChristophe Leroy mtspr SPRN_DBAT##n##U,RA; \ 51533090e5SChristophe Leroy mtspr SPRN_DBAT##n##L,RB 52533090e5SChristophe Leroy 53533090e5SChristophe Leroy __HEAD 5427e21e8fSChristophe Leroy_GLOBAL(_stext); 55533090e5SChristophe Leroy 56533090e5SChristophe Leroy/* 57533090e5SChristophe Leroy * _start is defined this way because the XCOFF loader in the OpenFirmware 58533090e5SChristophe Leroy * on the powermac expects the entry point to be a procedure descriptor. 59533090e5SChristophe Leroy */ 6027e21e8fSChristophe Leroy_GLOBAL(_start); 61533090e5SChristophe Leroy /* 62533090e5SChristophe Leroy * These are here for legacy reasons, the kernel used to 63533090e5SChristophe Leroy * need to look like a coff function entry for the pmac 64533090e5SChristophe Leroy * but we're always started by some kind of bootloader now. 65533090e5SChristophe Leroy * -- Cort 66533090e5SChristophe Leroy */ 67533090e5SChristophe Leroy nop /* used by __secondary_hold on prep (mtx) and chrp smp */ 68533090e5SChristophe Leroy nop /* used by __secondary_hold on prep (mtx) and chrp smp */ 69533090e5SChristophe Leroy nop 70533090e5SChristophe Leroy 71533090e5SChristophe Leroy/* PMAC 72533090e5SChristophe Leroy * Enter here with the kernel text, data and bss loaded starting at 73533090e5SChristophe Leroy * 0, running with virtual == physical mapping. 74533090e5SChristophe Leroy * r5 points to the prom entry point (the client interface handler 75533090e5SChristophe Leroy * address). Address translation is turned on, with the prom 76533090e5SChristophe Leroy * managing the hash table. Interrupts are disabled. The stack 77533090e5SChristophe Leroy * pointer (r1) points to just below the end of the half-meg region 78533090e5SChristophe Leroy * from 0x380000 - 0x400000, which is mapped in already. 79533090e5SChristophe Leroy * 80533090e5SChristophe Leroy * If we are booted from MacOS via BootX, we enter with the kernel 81533090e5SChristophe Leroy * image loaded somewhere, and the following values in registers: 82533090e5SChristophe Leroy * r3: 'BooX' (0x426f6f58) 83533090e5SChristophe Leroy * r4: virtual address of boot_infos_t 84533090e5SChristophe Leroy * r5: 0 85533090e5SChristophe Leroy * 86533090e5SChristophe Leroy * PREP 87533090e5SChristophe Leroy * This is jumped to on prep systems right after the kernel is relocated 88533090e5SChristophe Leroy * to its proper place in memory by the boot loader. The expected layout 89533090e5SChristophe Leroy * of the regs is: 90533090e5SChristophe Leroy * r3: ptr to residual data 91533090e5SChristophe Leroy * r4: initrd_start or if no initrd then 0 92533090e5SChristophe Leroy * r5: initrd_end - unused if r4 is 0 93533090e5SChristophe Leroy * r6: Start of command line string 94533090e5SChristophe Leroy * r7: End of command line string 95533090e5SChristophe Leroy * 96533090e5SChristophe Leroy * This just gets a minimal mmu environment setup so we can call 97533090e5SChristophe Leroy * start_here() to do the real work. 98533090e5SChristophe Leroy * -- Cort 99533090e5SChristophe Leroy */ 100533090e5SChristophe Leroy 101533090e5SChristophe Leroy .globl __start 102533090e5SChristophe Leroy__start: 103533090e5SChristophe Leroy/* 104533090e5SChristophe Leroy * We have to do any OF calls before we map ourselves to KERNELBASE, 105533090e5SChristophe Leroy * because OF may have I/O devices mapped into that area 106533090e5SChristophe Leroy * (particularly on CHRP). 107533090e5SChristophe Leroy */ 108533090e5SChristophe Leroy cmpwi 0,r5,0 109533090e5SChristophe Leroy beq 1f 110533090e5SChristophe Leroy 111533090e5SChristophe Leroy#ifdef CONFIG_PPC_OF_BOOT_TRAMPOLINE 112533090e5SChristophe Leroy /* find out where we are now */ 113533090e5SChristophe Leroy bcl 20,31,$+4 114533090e5SChristophe Leroy0: mflr r8 /* r8 = runtime addr here */ 115533090e5SChristophe Leroy addis r8,r8,(_stext - 0b)@ha 116533090e5SChristophe Leroy addi r8,r8,(_stext - 0b)@l /* current runtime base addr */ 117533090e5SChristophe Leroy bl prom_init 118533090e5SChristophe Leroy#endif /* CONFIG_PPC_OF_BOOT_TRAMPOLINE */ 119533090e5SChristophe Leroy 120533090e5SChristophe Leroy /* We never return. We also hit that trap if trying to boot 121533090e5SChristophe Leroy * from OF while CONFIG_PPC_OF_BOOT_TRAMPOLINE isn't selected */ 122533090e5SChristophe Leroy trap 123533090e5SChristophe Leroy 124533090e5SChristophe Leroy/* 125533090e5SChristophe Leroy * Check for BootX signature when supporting PowerMac and branch to 126533090e5SChristophe Leroy * appropriate trampoline if it's present 127533090e5SChristophe Leroy */ 128533090e5SChristophe Leroy#ifdef CONFIG_PPC_PMAC 129533090e5SChristophe Leroy1: lis r31,0x426f 130533090e5SChristophe Leroy ori r31,r31,0x6f58 131533090e5SChristophe Leroy cmpw 0,r3,r31 132533090e5SChristophe Leroy bne 1f 133533090e5SChristophe Leroy bl bootx_init 134533090e5SChristophe Leroy trap 135533090e5SChristophe Leroy#endif /* CONFIG_PPC_PMAC */ 136533090e5SChristophe Leroy 137533090e5SChristophe Leroy1: mr r31,r3 /* save device tree ptr */ 138533090e5SChristophe Leroy li r24,0 /* cpu # */ 139533090e5SChristophe Leroy 140533090e5SChristophe Leroy/* 141533090e5SChristophe Leroy * early_init() does the early machine identification and does 142533090e5SChristophe Leroy * the necessary low-level setup and clears the BSS 143533090e5SChristophe Leroy * -- Cort <cort@fsmlabs.com> 144533090e5SChristophe Leroy */ 145533090e5SChristophe Leroy bl early_init 146533090e5SChristophe Leroy 147533090e5SChristophe Leroy/* Switch MMU off, clear BATs and flush TLB. At this point, r3 contains 148533090e5SChristophe Leroy * the physical address we are running at, returned by early_init() 149533090e5SChristophe Leroy */ 150533090e5SChristophe Leroy bl mmu_off 151533090e5SChristophe Leroy__after_mmu_off: 152533090e5SChristophe Leroy bl clear_bats 153533090e5SChristophe Leroy bl flush_tlbs 154533090e5SChristophe Leroy 155533090e5SChristophe Leroy bl initial_bats 156533090e5SChristophe Leroy bl load_segment_registers 15701776f07SChristophe Leroy bl reloc_offset 158533090e5SChristophe Leroy bl early_hash_table 159533090e5SChristophe Leroy#if defined(CONFIG_BOOTX_TEXT) 160533090e5SChristophe Leroy bl setup_disp_bat 161533090e5SChristophe Leroy#endif 162533090e5SChristophe Leroy#ifdef CONFIG_PPC_EARLY_DEBUG_CPM 163533090e5SChristophe Leroy bl setup_cpm_bat 164533090e5SChristophe Leroy#endif 165533090e5SChristophe Leroy#ifdef CONFIG_PPC_EARLY_DEBUG_USBGECKO 166533090e5SChristophe Leroy bl setup_usbgecko_bat 167533090e5SChristophe Leroy#endif 168533090e5SChristophe Leroy 169533090e5SChristophe Leroy/* 170533090e5SChristophe Leroy * Call setup_cpu for CPU 0 and initialize 6xx Idle 171533090e5SChristophe Leroy */ 172533090e5SChristophe Leroy bl reloc_offset 173533090e5SChristophe Leroy li r24,0 /* cpu# */ 174533090e5SChristophe Leroy bl call_setup_cpu /* Call setup_cpu for this CPU */ 175533090e5SChristophe Leroy bl reloc_offset 176533090e5SChristophe Leroy bl init_idle_6xx 177533090e5SChristophe Leroy 178533090e5SChristophe Leroy 179533090e5SChristophe Leroy/* 180533090e5SChristophe Leroy * We need to run with _start at physical address 0. 181533090e5SChristophe Leroy * On CHRP, we are loaded at 0x10000 since OF on CHRP uses 182533090e5SChristophe Leroy * the exception vectors at 0 (and therefore this copy 183533090e5SChristophe Leroy * overwrites OF's exception vectors with our own). 184533090e5SChristophe Leroy * The MMU is off at this point. 185533090e5SChristophe Leroy */ 186533090e5SChristophe Leroy bl reloc_offset 187533090e5SChristophe Leroy mr r26,r3 188533090e5SChristophe Leroy addis r4,r3,KERNELBASE@h /* current address of _start */ 189533090e5SChristophe Leroy lis r5,PHYSICAL_START@h 190533090e5SChristophe Leroy cmplw 0,r4,r5 /* already running at PHYSICAL_START? */ 191533090e5SChristophe Leroy bne relocate_kernel 192533090e5SChristophe Leroy/* 193533090e5SChristophe Leroy * we now have the 1st 16M of ram mapped with the bats. 194533090e5SChristophe Leroy * prep needs the mmu to be turned on here, but pmac already has it on. 195533090e5SChristophe Leroy * this shouldn't bother the pmac since it just gets turned on again 196533090e5SChristophe Leroy * as we jump to our code at KERNELBASE. -- Cort 197533090e5SChristophe Leroy * Actually no, pmac doesn't have it on any more. BootX enters with MMU 198533090e5SChristophe Leroy * off, and in other cases, we now turn it off before changing BATs above. 199533090e5SChristophe Leroy */ 200533090e5SChristophe Leroyturn_on_mmu: 201533090e5SChristophe Leroy mfmsr r0 202533090e5SChristophe Leroy ori r0,r0,MSR_DR|MSR_IR|MSR_RI 203533090e5SChristophe Leroy mtspr SPRN_SRR1,r0 204533090e5SChristophe Leroy lis r0,start_here@h 205533090e5SChristophe Leroy ori r0,r0,start_here@l 206533090e5SChristophe Leroy mtspr SPRN_SRR0,r0 207120c0518SChristophe Leroy rfi /* enables MMU */ 208533090e5SChristophe Leroy 209533090e5SChristophe Leroy/* 210533090e5SChristophe Leroy * We need __secondary_hold as a place to hold the other cpus on 211533090e5SChristophe Leroy * an SMP machine, even when we are running a UP kernel. 212533090e5SChristophe Leroy */ 213533090e5SChristophe Leroy . = 0xc0 /* for prep bootloader */ 214533090e5SChristophe Leroy li r3,1 /* MTX only has 1 cpu */ 215533090e5SChristophe Leroy .globl __secondary_hold 216533090e5SChristophe Leroy__secondary_hold: 217533090e5SChristophe Leroy /* tell the master we're here */ 218533090e5SChristophe Leroy stw r3,__secondary_hold_acknowledge@l(0) 219533090e5SChristophe Leroy#ifdef CONFIG_SMP 220533090e5SChristophe Leroy100: lwz r4,0(0) 221533090e5SChristophe Leroy /* wait until we're told to start */ 222533090e5SChristophe Leroy cmpw 0,r4,r3 223533090e5SChristophe Leroy bne 100b 224533090e5SChristophe Leroy /* our cpu # was at addr 0 - go */ 225533090e5SChristophe Leroy mr r24,r3 /* cpu # */ 226533090e5SChristophe Leroy b __secondary_start 227533090e5SChristophe Leroy#else 228533090e5SChristophe Leroy b . 229533090e5SChristophe Leroy#endif /* CONFIG_SMP */ 230533090e5SChristophe Leroy 231533090e5SChristophe Leroy .globl __secondary_hold_spinloop 232533090e5SChristophe Leroy__secondary_hold_spinloop: 233533090e5SChristophe Leroy .long 0 234533090e5SChristophe Leroy .globl __secondary_hold_acknowledge 235533090e5SChristophe Leroy__secondary_hold_acknowledge: 236533090e5SChristophe Leroy .long -1 237533090e5SChristophe Leroy 238533090e5SChristophe Leroy/* System reset */ 239533090e5SChristophe Leroy/* core99 pmac starts the seconary here by changing the vector, and 2406c6aee00SNicholas Piggin putting it back to what it was (unknown_async_exception) when done. */ 2417fab6397SChristophe Leroy EXCEPTION(INTERRUPT_SYSTEM_RESET, Reset, unknown_async_exception) 242533090e5SChristophe Leroy 243533090e5SChristophe Leroy/* Machine check */ 244533090e5SChristophe Leroy/* 245533090e5SChristophe Leroy * On CHRP, this is complicated by the fact that we could get a 246533090e5SChristophe Leroy * machine check inside RTAS, and we have no guarantee that certain 247533090e5SChristophe Leroy * critical registers will have the values we expect. The set of 248533090e5SChristophe Leroy * registers that might have bad values includes all the GPRs 249533090e5SChristophe Leroy * and all the BATs. We indicate that we are in RTAS by putting 250533090e5SChristophe Leroy * a non-zero value, the address of the exception frame to use, 251533090e5SChristophe Leroy * in thread.rtas_sp. The machine check handler checks thread.rtas_sp 252533090e5SChristophe Leroy * and uses its value if it is non-zero. 253533090e5SChristophe Leroy * (Other exception handlers assume that r1 is a valid kernel stack 254533090e5SChristophe Leroy * pointer when we take an exception from supervisor mode.) 255533090e5SChristophe Leroy * -- paulus. 256533090e5SChristophe Leroy */ 2577fab6397SChristophe Leroy START_EXCEPTION(INTERRUPT_MACHINE_CHECK, MachineCheck) 258533090e5SChristophe Leroy EXCEPTION_PROLOG_0 259533090e5SChristophe Leroy#ifdef CONFIG_PPC_CHRP 26098bf2d3fSChristophe Leroy mtspr SPRN_SPRG_SCRATCH2,r1 26198bf2d3fSChristophe Leroy mfspr r1, SPRN_SPRG_THREAD 26298bf2d3fSChristophe Leroy lwz r1, RTAS_SP(r1) 26398bf2d3fSChristophe Leroy cmpwi cr1, r1, 0 26498bf2d3fSChristophe Leroy bne cr1, 7f 26598bf2d3fSChristophe Leroy mfspr r1, SPRN_SPRG_SCRATCH2 266533090e5SChristophe Leroy#endif /* CONFIG_PPC_CHRP */ 2677aa8dd67SChristophe Leroy EXCEPTION_PROLOG_1 268719e7e21SChristophe Leroy7: EXCEPTION_PROLOG_2 0x200 MachineCheck 269533090e5SChristophe Leroy#ifdef CONFIG_PPC_CHRP 270dc13b889SChristophe Leroy beq cr1, 1f 271533090e5SChristophe Leroy twi 31, 0, 0 272533090e5SChristophe Leroy#endif 2734c0104a8SChristophe Leroy1: prepare_transfer_to_handler 2744c0104a8SChristophe Leroy bl machine_check_exception 2754c0104a8SChristophe Leroy b interrupt_return 276533090e5SChristophe Leroy 277533090e5SChristophe Leroy/* Data access exception. */ 2787fab6397SChristophe Leroy START_EXCEPTION(INTERRUPT_DATA_STORAGE, DataAccess) 279259149cfSChristophe Leroy#ifdef CONFIG_PPC_BOOK3S_604 280533090e5SChristophe LeroyBEGIN_MMU_FTR_SECTION 281de1cd079SChristophe Leroy mtspr SPRN_SPRG_SCRATCH2,r10 282de1cd079SChristophe Leroy mfspr r10, SPRN_SPRG_THREAD 283533090e5SChristophe Leroy stw r11, THR11(r10) 284533090e5SChristophe Leroy mfspr r10, SPRN_DSISR 285533090e5SChristophe Leroy mfcr r11 286533090e5SChristophe Leroy andis. r10, r10, (DSISR_BAD_FAULT_32S | DSISR_DABRMATCH)@h 287533090e5SChristophe Leroy mfspr r10, SPRN_SPRG_THREAD 288533090e5SChristophe Leroy beq hash_page_dsi 289533090e5SChristophe Leroy.Lhash_page_dsi_cont: 290533090e5SChristophe Leroy mtcr r11 291533090e5SChristophe Leroy lwz r11, THR11(r10) 292de1cd079SChristophe Leroy mfspr r10, SPRN_SPRG_SCRATCH2 293de1cd079SChristophe LeroyMMU_FTR_SECTION_ELSE 294de1cd079SChristophe Leroy b 1f 295de1cd079SChristophe LeroyALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_HPTE_TABLE) 296259149cfSChristophe Leroy#endif 297de1cd079SChristophe Leroy1: EXCEPTION_PROLOG_0 handle_dar_dsisr=1 298533090e5SChristophe Leroy EXCEPTION_PROLOG_1 2997fab6397SChristophe Leroy EXCEPTION_PROLOG_2 INTERRUPT_DATA_STORAGE DataAccess handle_dar_dsisr=1 3004c0104a8SChristophe Leroy prepare_transfer_to_handler 30162376365SChristophe Leroy lwz r5, _DSISR(r1) 302dc13b889SChristophe Leroy andis. r0, r5, DSISR_DABRMATCH@h 303dc13b889SChristophe Leroy bne- 1f 3044c0104a8SChristophe Leroy bl do_page_fault 3054c0104a8SChristophe Leroy b interrupt_return 3064c0104a8SChristophe Leroy1: bl do_break 3078f6ff5bdSChristophe Leroy REST_NVGPRS(r1) 3088f6ff5bdSChristophe Leroy b interrupt_return 309dc13b889SChristophe Leroy 310533090e5SChristophe Leroy 311533090e5SChristophe Leroy/* Instruction access exception. */ 3127fab6397SChristophe Leroy START_EXCEPTION(INTERRUPT_INST_STORAGE, InstructionAccess) 313533090e5SChristophe Leroy mtspr SPRN_SPRG_SCRATCH0,r10 314533090e5SChristophe Leroy mtspr SPRN_SPRG_SCRATCH1,r11 315533090e5SChristophe Leroy mfspr r10, SPRN_SPRG_THREAD 316533090e5SChristophe Leroy mfspr r11, SPRN_SRR0 317533090e5SChristophe Leroy stw r11, SRR0(r10) 318533090e5SChristophe Leroy mfspr r11, SPRN_SRR1 /* check whether user or kernel */ 319533090e5SChristophe Leroy stw r11, SRR1(r10) 320533090e5SChristophe Leroy mfcr r10 321259149cfSChristophe Leroy#ifdef CONFIG_PPC_BOOK3S_604 322533090e5SChristophe LeroyBEGIN_MMU_FTR_SECTION 323533090e5SChristophe Leroy andis. r11, r11, SRR1_ISI_NOPT@h /* no pte found? */ 324533090e5SChristophe Leroy bne hash_page_isi 325533090e5SChristophe Leroy.Lhash_page_isi_cont: 326533090e5SChristophe Leroy mfspr r11, SPRN_SRR1 /* check whether user or kernel */ 327533090e5SChristophe LeroyEND_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE) 328259149cfSChristophe Leroy#endif 329533090e5SChristophe Leroy andi. r11, r11, MSR_PR 330533090e5SChristophe Leroy 331533090e5SChristophe Leroy EXCEPTION_PROLOG_1 3327fab6397SChristophe Leroy EXCEPTION_PROLOG_2 INTERRUPT_INST_STORAGE InstructionAccess 333533090e5SChristophe Leroy andis. r5,r9,DSISR_SRR1_MATCH_32S@h /* Filter relevant SRR1 bits */ 334a01a3f2dSNicholas Piggin stw r5, _DSISR(r11) 335a01a3f2dSNicholas Piggin stw r12, _DAR(r11) 3364c0104a8SChristophe Leroy prepare_transfer_to_handler 3374c0104a8SChristophe Leroy bl do_page_fault 3384c0104a8SChristophe Leroy b interrupt_return 339533090e5SChristophe Leroy 340533090e5SChristophe Leroy/* External interrupt */ 3417fab6397SChristophe Leroy EXCEPTION(INTERRUPT_EXTERNAL, HardwareInterrupt, do_IRQ) 342533090e5SChristophe Leroy 343533090e5SChristophe Leroy/* Alignment exception */ 3447fab6397SChristophe Leroy START_EXCEPTION(INTERRUPT_ALIGNMENT, Alignment) 3457fab6397SChristophe Leroy EXCEPTION_PROLOG INTERRUPT_ALIGNMENT Alignment handle_dar_dsisr=1 3468f6ff5bdSChristophe Leroy prepare_transfer_to_handler 3478f6ff5bdSChristophe Leroy bl alignment_exception 3488f6ff5bdSChristophe Leroy REST_NVGPRS(r1) 3498f6ff5bdSChristophe Leroy b interrupt_return 350533090e5SChristophe Leroy 351533090e5SChristophe Leroy/* Program check exception */ 3527fab6397SChristophe Leroy START_EXCEPTION(INTERRUPT_PROGRAM, ProgramCheck) 3537fab6397SChristophe Leroy EXCEPTION_PROLOG INTERRUPT_PROGRAM ProgramCheck 3548f6ff5bdSChristophe Leroy prepare_transfer_to_handler 3558f6ff5bdSChristophe Leroy bl program_check_exception 3568f6ff5bdSChristophe Leroy REST_NVGPRS(r1) 3578f6ff5bdSChristophe Leroy b interrupt_return 358533090e5SChristophe Leroy 359533090e5SChristophe Leroy/* Floating-point unavailable */ 3607bf1d7e1SChristophe Leroy START_EXCEPTION(0x800, FPUnavailable) 3617d68c891SChristophe Leroy#ifdef CONFIG_PPC_FPU 362533090e5SChristophe LeroyBEGIN_FTR_SECTION 363533090e5SChristophe Leroy/* 364533090e5SChristophe Leroy * Certain Freescale cores don't have a FPU and treat fp instructions 365533090e5SChristophe Leroy * as a FP Unavailable exception. Redirect to illegal/emulation handling. 366533090e5SChristophe Leroy */ 367533090e5SChristophe Leroy b ProgramCheck 368533090e5SChristophe LeroyEND_FTR_SECTION_IFSET(CPU_FTR_FPU_UNAVAILABLE) 3697fab6397SChristophe Leroy EXCEPTION_PROLOG INTERRUPT_FP_UNAVAIL FPUnavailable 370533090e5SChristophe Leroy beq 1f 371533090e5SChristophe Leroy bl load_up_fpu /* if from user, just load it up */ 372533090e5SChristophe Leroy b fast_exception_return 3734c0104a8SChristophe Leroy1: prepare_transfer_to_handler 3744c0104a8SChristophe Leroy bl kernel_fp_unavailable_exception 3754c0104a8SChristophe Leroy b interrupt_return 3767d68c891SChristophe Leroy#else 3777d68c891SChristophe Leroy b ProgramCheck 3787d68c891SChristophe Leroy#endif 379533090e5SChristophe Leroy 380533090e5SChristophe Leroy/* Decrementer */ 3817fab6397SChristophe Leroy EXCEPTION(INTERRUPT_DECREMENTER, Decrementer, timer_interrupt) 382533090e5SChristophe Leroy 383acc142b6SChristophe Leroy EXCEPTION(0xa00, Trap_0a, unknown_exception) 384acc142b6SChristophe Leroy EXCEPTION(0xb00, Trap_0b, unknown_exception) 385533090e5SChristophe Leroy 386533090e5SChristophe Leroy/* System call */ 3877fab6397SChristophe Leroy START_EXCEPTION(INTERRUPT_SYSCALL, SystemCall) 3887fab6397SChristophe Leroy SYSCALL_ENTRY INTERRUPT_SYSCALL 389533090e5SChristophe Leroy 3907fab6397SChristophe Leroy EXCEPTION(INTERRUPT_TRACE, SingleStep, single_step_exception) 391acc142b6SChristophe Leroy EXCEPTION(0xe00, Trap_0e, unknown_exception) 392533090e5SChristophe Leroy 393533090e5SChristophe Leroy/* 394533090e5SChristophe Leroy * The Altivec unavailable trap is at 0x0f20. Foo. 395533090e5SChristophe Leroy * We effectively remap it to 0x3000. 396533090e5SChristophe Leroy * We include an altivec unavailable exception vector even if 397533090e5SChristophe Leroy * not configured for Altivec, so that you can't panic a 398533090e5SChristophe Leroy * non-altivec kernel running on a machine with altivec just 399533090e5SChristophe Leroy * by executing an altivec instruction. 400533090e5SChristophe Leroy */ 4017fab6397SChristophe Leroy START_EXCEPTION(INTERRUPT_PERFMON, PerformanceMonitorTrap) 402533090e5SChristophe Leroy b PerformanceMonitor 403533090e5SChristophe Leroy 4047fab6397SChristophe Leroy START_EXCEPTION(INTERRUPT_ALTIVEC_UNAVAIL, AltiVecUnavailableTrap) 405533090e5SChristophe Leroy b AltiVecUnavailable 406533090e5SChristophe Leroy 407dc13b889SChristophe Leroy __HEAD 408533090e5SChristophe Leroy/* 409533090e5SChristophe Leroy * Handle TLB miss for instruction on 603/603e. 410533090e5SChristophe Leroy * Note: we get an alternate set of r0 - r3 to use automatically. 411533090e5SChristophe Leroy */ 4127fab6397SChristophe Leroy . = INTERRUPT_INST_TLB_MISS_603 413533090e5SChristophe LeroyInstructionTLBMiss: 414533090e5SChristophe Leroy/* 415533090e5SChristophe Leroy * r0: scratch 416533090e5SChristophe Leroy * r1: linux style pte ( later becomes ppc hardware pte ) 417533090e5SChristophe Leroy * r2: ptr to linux-style pte 418533090e5SChristophe Leroy * r3: scratch 419533090e5SChristophe Leroy */ 420533090e5SChristophe Leroy /* Get PTE (linux-style) and check access */ 421533090e5SChristophe Leroy mfspr r3,SPRN_IMISS 4222a0fb3c1SChristophe Leroy#ifdef CONFIG_MODULES 423533090e5SChristophe Leroy lis r1, TASK_SIZE@h /* check if kernel address */ 424533090e5SChristophe Leroy cmplw 0,r1,r3 425533090e5SChristophe Leroy#endif 426c4a22611SChristophe Leroy mfspr r2, SPRN_SDR1 427c119565aSChristophe Leroy li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC | _PAGE_USER 428c4a22611SChristophe Leroy rlwinm r2, r2, 28, 0xfffff000 4292a0fb3c1SChristophe Leroy#ifdef CONFIG_MODULES 430533090e5SChristophe Leroy bgt- 112f 431533090e5SChristophe Leroy lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ 432c119565aSChristophe Leroy li r1,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC 433533090e5SChristophe Leroy addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */ 434533090e5SChristophe Leroy#endif 435533090e5SChristophe Leroy112: rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */ 436533090e5SChristophe Leroy lwz r2,0(r2) /* get pmd entry */ 437533090e5SChristophe Leroy rlwinm. r2,r2,0,0,19 /* extract address of pte page */ 438533090e5SChristophe Leroy beq- InstructionAddressInvalid /* return if no mapping */ 439533090e5SChristophe Leroy rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */ 440533090e5SChristophe Leroy lwz r0,0(r2) /* get linux-style pte */ 441533090e5SChristophe Leroy andc. r1,r1,r0 /* check access & ~permission */ 442533090e5SChristophe Leroy bne- InstructionAddressInvalid /* return if access not permitted */ 443533090e5SChristophe Leroy /* Convert linux-style PTE to low word of PPC-style PTE */ 444533090e5SChristophe Leroy rlwimi r0,r0,32-2,31,31 /* _PAGE_USER -> PP lsb */ 445533090e5SChristophe Leroy ori r1, r1, 0xe06 /* clear out reserved bits */ 446533090e5SChristophe Leroy andc r1, r0, r1 /* PP = user? 1 : 0 */ 447533090e5SChristophe LeroyBEGIN_FTR_SECTION 448533090e5SChristophe Leroy rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */ 449533090e5SChristophe LeroyEND_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT) 450533090e5SChristophe Leroy mtspr SPRN_RPA,r1 451533090e5SChristophe Leroy tlbli r3 452533090e5SChristophe Leroy mfspr r3,SPRN_SRR1 /* Need to restore CR0 */ 453533090e5SChristophe Leroy mtcrf 0x80,r3 454533090e5SChristophe Leroy rfi 455533090e5SChristophe LeroyInstructionAddressInvalid: 456533090e5SChristophe Leroy mfspr r3,SPRN_SRR1 457533090e5SChristophe Leroy rlwinm r1,r3,9,6,6 /* Get load/store bit */ 458533090e5SChristophe Leroy 459533090e5SChristophe Leroy addis r1,r1,0x2000 460533090e5SChristophe Leroy mtspr SPRN_DSISR,r1 /* (shouldn't be needed) */ 461533090e5SChristophe Leroy andi. r2,r3,0xFFFF /* Clear upper bits of SRR1 */ 462533090e5SChristophe Leroy or r2,r2,r1 463533090e5SChristophe Leroy mtspr SPRN_SRR1,r2 464533090e5SChristophe Leroy mfspr r1,SPRN_IMISS /* Get failing address */ 465533090e5SChristophe Leroy rlwinm. r2,r2,0,31,31 /* Check for little endian access */ 466533090e5SChristophe Leroy rlwimi r2,r2,1,30,30 /* change 1 -> 3 */ 467533090e5SChristophe Leroy xor r1,r1,r2 468533090e5SChristophe Leroy mtspr SPRN_DAR,r1 /* Set fault address */ 469533090e5SChristophe Leroy mfmsr r0 /* Restore "normal" registers */ 470533090e5SChristophe Leroy xoris r0,r0,MSR_TGPR>>16 471533090e5SChristophe Leroy mtcrf 0x80,r3 /* Restore CR0 */ 472533090e5SChristophe Leroy mtmsr r0 473533090e5SChristophe Leroy b InstructionAccess 474533090e5SChristophe Leroy 475533090e5SChristophe Leroy/* 476533090e5SChristophe Leroy * Handle TLB miss for DATA Load operation on 603/603e 477533090e5SChristophe Leroy */ 4787fab6397SChristophe Leroy . = INTERRUPT_DATA_LOAD_TLB_MISS_603 479533090e5SChristophe LeroyDataLoadTLBMiss: 480533090e5SChristophe Leroy/* 481533090e5SChristophe Leroy * r0: scratch 482533090e5SChristophe Leroy * r1: linux style pte ( later becomes ppc hardware pte ) 483533090e5SChristophe Leroy * r2: ptr to linux-style pte 484533090e5SChristophe Leroy * r3: scratch 485533090e5SChristophe Leroy */ 486533090e5SChristophe Leroy /* Get PTE (linux-style) and check access */ 487533090e5SChristophe Leroy mfspr r3,SPRN_DMISS 488533090e5SChristophe Leroy lis r1, TASK_SIZE@h /* check if kernel address */ 489533090e5SChristophe Leroy cmplw 0,r1,r3 490c4a22611SChristophe Leroy mfspr r2, SPRN_SDR1 491c119565aSChristophe Leroy li r1, _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_USER 492c4a22611SChristophe Leroy rlwinm r2, r2, 28, 0xfffff000 493533090e5SChristophe Leroy bgt- 112f 494533090e5SChristophe Leroy lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ 495c119565aSChristophe Leroy li r1, _PAGE_PRESENT | _PAGE_ACCESSED 496533090e5SChristophe Leroy addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */ 497533090e5SChristophe Leroy112: rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */ 498533090e5SChristophe Leroy lwz r2,0(r2) /* get pmd entry */ 499533090e5SChristophe Leroy rlwinm. r2,r2,0,0,19 /* extract address of pte page */ 500533090e5SChristophe Leroy beq- DataAddressInvalid /* return if no mapping */ 501533090e5SChristophe Leroy rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */ 502533090e5SChristophe Leroy lwz r0,0(r2) /* get linux-style pte */ 503533090e5SChristophe Leroy andc. r1,r1,r0 /* check access & ~permission */ 504533090e5SChristophe Leroy bne- DataAddressInvalid /* return if access not permitted */ 505533090e5SChristophe Leroy /* Convert linux-style PTE to low word of PPC-style PTE */ 506533090e5SChristophe Leroy rlwinm r1,r0,32-9,30,30 /* _PAGE_RW -> PP msb */ 507533090e5SChristophe Leroy rlwimi r0,r0,32-1,30,30 /* _PAGE_USER -> PP msb */ 5084634bf44SChristophe Leroy rlwimi r1,r0,32-3,24,24 /* _PAGE_RW -> _PAGE_DIRTY */ 509533090e5SChristophe Leroy rlwimi r0,r0,32-1,31,31 /* _PAGE_USER -> PP lsb */ 5104634bf44SChristophe Leroy xori r1,r1,_PAGE_DIRTY /* clear dirty when not rw */ 511533090e5SChristophe Leroy ori r1,r1,0xe04 /* clear out reserved bits */ 512533090e5SChristophe Leroy andc r1,r0,r1 /* PP = user? rw? 1: 3: 0 */ 513533090e5SChristophe LeroyBEGIN_FTR_SECTION 514533090e5SChristophe Leroy rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */ 515533090e5SChristophe LeroyEND_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT) 516533090e5SChristophe Leroy mtspr SPRN_RPA,r1 517533090e5SChristophe LeroyBEGIN_MMU_FTR_SECTION 518533090e5SChristophe Leroy li r0,1 519533090e5SChristophe Leroy mfspr r1,SPRN_SPRG_603_LRU 520533090e5SChristophe Leroy rlwinm r2,r3,20,27,31 /* Get Address bits 15:19 */ 521533090e5SChristophe Leroy slw r0,r0,r2 522533090e5SChristophe Leroy xor r1,r0,r1 523533090e5SChristophe Leroy srw r0,r1,r2 524533090e5SChristophe Leroy mtspr SPRN_SPRG_603_LRU,r1 525533090e5SChristophe Leroy mfspr r2,SPRN_SRR1 526533090e5SChristophe Leroy rlwimi r2,r0,31-14,14,14 527533090e5SChristophe Leroy mtspr SPRN_SRR1,r2 52870d6ebf8SChristophe Leroy mtcrf 0x80,r2 529533090e5SChristophe Leroy tlbld r3 530533090e5SChristophe Leroy rfi 53170d6ebf8SChristophe LeroyMMU_FTR_SECTION_ELSE 53270d6ebf8SChristophe Leroy mfspr r2,SPRN_SRR1 /* Need to restore CR0 */ 53370d6ebf8SChristophe Leroy mtcrf 0x80,r2 53470d6ebf8SChristophe Leroy tlbld r3 53570d6ebf8SChristophe Leroy rfi 53670d6ebf8SChristophe LeroyALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_NEED_DTLB_SW_LRU) 537533090e5SChristophe LeroyDataAddressInvalid: 538533090e5SChristophe Leroy mfspr r3,SPRN_SRR1 539533090e5SChristophe Leroy rlwinm r1,r3,9,6,6 /* Get load/store bit */ 540533090e5SChristophe Leroy addis r1,r1,0x2000 541533090e5SChristophe Leroy mtspr SPRN_DSISR,r1 542533090e5SChristophe Leroy andi. r2,r3,0xFFFF /* Clear upper bits of SRR1 */ 543533090e5SChristophe Leroy mtspr SPRN_SRR1,r2 544533090e5SChristophe Leroy mfspr r1,SPRN_DMISS /* Get failing address */ 545533090e5SChristophe Leroy rlwinm. r2,r2,0,31,31 /* Check for little endian access */ 546533090e5SChristophe Leroy beq 20f /* Jump if big endian */ 547533090e5SChristophe Leroy xori r1,r1,3 548533090e5SChristophe Leroy20: mtspr SPRN_DAR,r1 /* Set fault address */ 549533090e5SChristophe Leroy mfmsr r0 /* Restore "normal" registers */ 550533090e5SChristophe Leroy xoris r0,r0,MSR_TGPR>>16 551533090e5SChristophe Leroy mtcrf 0x80,r3 /* Restore CR0 */ 552533090e5SChristophe Leroy mtmsr r0 553533090e5SChristophe Leroy b DataAccess 554533090e5SChristophe Leroy 555533090e5SChristophe Leroy/* 556533090e5SChristophe Leroy * Handle TLB miss for DATA Store on 603/603e 557533090e5SChristophe Leroy */ 5587fab6397SChristophe Leroy . = INTERRUPT_DATA_STORE_TLB_MISS_603 559533090e5SChristophe LeroyDataStoreTLBMiss: 560533090e5SChristophe Leroy/* 561533090e5SChristophe Leroy * r0: scratch 562533090e5SChristophe Leroy * r1: linux style pte ( later becomes ppc hardware pte ) 563533090e5SChristophe Leroy * r2: ptr to linux-style pte 564533090e5SChristophe Leroy * r3: scratch 565533090e5SChristophe Leroy */ 566533090e5SChristophe Leroy /* Get PTE (linux-style) and check access */ 567533090e5SChristophe Leroy mfspr r3,SPRN_DMISS 568533090e5SChristophe Leroy lis r1, TASK_SIZE@h /* check if kernel address */ 569533090e5SChristophe Leroy cmplw 0,r1,r3 570c4a22611SChristophe Leroy mfspr r2, SPRN_SDR1 571c119565aSChristophe Leroy li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_USER 572c4a22611SChristophe Leroy rlwinm r2, r2, 28, 0xfffff000 573533090e5SChristophe Leroy bgt- 112f 574533090e5SChristophe Leroy lis r2, (swapper_pg_dir - PAGE_OFFSET)@ha /* if kernel address, use */ 575c119565aSChristophe Leroy li r1, _PAGE_RW | _PAGE_DIRTY | _PAGE_PRESENT | _PAGE_ACCESSED 576533090e5SChristophe Leroy addi r2, r2, (swapper_pg_dir - PAGE_OFFSET)@l /* kernel page table */ 577533090e5SChristophe Leroy112: rlwimi r2,r3,12,20,29 /* insert top 10 bits of address */ 578533090e5SChristophe Leroy lwz r2,0(r2) /* get pmd entry */ 579533090e5SChristophe Leroy rlwinm. r2,r2,0,0,19 /* extract address of pte page */ 580533090e5SChristophe Leroy beq- DataAddressInvalid /* return if no mapping */ 581533090e5SChristophe Leroy rlwimi r2,r3,22,20,29 /* insert next 10 bits of address */ 582533090e5SChristophe Leroy lwz r0,0(r2) /* get linux-style pte */ 583533090e5SChristophe Leroy andc. r1,r1,r0 /* check access & ~permission */ 584533090e5SChristophe Leroy bne- DataAddressInvalid /* return if access not permitted */ 585533090e5SChristophe Leroy /* Convert linux-style PTE to low word of PPC-style PTE */ 586533090e5SChristophe Leroy rlwimi r0,r0,32-2,31,31 /* _PAGE_USER -> PP lsb */ 587533090e5SChristophe Leroy li r1,0xe06 /* clear out reserved bits & PP msb */ 588533090e5SChristophe Leroy andc r1,r0,r1 /* PP = user? 1: 0 */ 589533090e5SChristophe LeroyBEGIN_FTR_SECTION 590533090e5SChristophe Leroy rlwinm r1,r1,0,~_PAGE_COHERENT /* clear M (coherence not required) */ 591533090e5SChristophe LeroyEND_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHERENT) 592533090e5SChristophe Leroy mtspr SPRN_RPA,r1 593533090e5SChristophe Leroy mfspr r2,SPRN_SRR1 /* Need to restore CR0 */ 594533090e5SChristophe Leroy mtcrf 0x80,r2 595533090e5SChristophe LeroyBEGIN_MMU_FTR_SECTION 596533090e5SChristophe Leroy li r0,1 597533090e5SChristophe Leroy mfspr r1,SPRN_SPRG_603_LRU 598533090e5SChristophe Leroy rlwinm r2,r3,20,27,31 /* Get Address bits 15:19 */ 599533090e5SChristophe Leroy slw r0,r0,r2 600533090e5SChristophe Leroy xor r1,r0,r1 601533090e5SChristophe Leroy srw r0,r1,r2 602533090e5SChristophe Leroy mtspr SPRN_SPRG_603_LRU,r1 603533090e5SChristophe Leroy mfspr r2,SPRN_SRR1 604533090e5SChristophe Leroy rlwimi r2,r0,31-14,14,14 605533090e5SChristophe Leroy mtspr SPRN_SRR1,r2 60670d6ebf8SChristophe Leroy mtcrf 0x80,r2 607533090e5SChristophe Leroy tlbld r3 608533090e5SChristophe Leroy rfi 60970d6ebf8SChristophe LeroyMMU_FTR_SECTION_ELSE 61070d6ebf8SChristophe Leroy mfspr r2,SPRN_SRR1 /* Need to restore CR0 */ 61170d6ebf8SChristophe Leroy mtcrf 0x80,r2 61270d6ebf8SChristophe Leroy tlbld r3 61370d6ebf8SChristophe Leroy rfi 61470d6ebf8SChristophe LeroyALT_MMU_FTR_SECTION_END_IFSET(MMU_FTR_NEED_DTLB_SW_LRU) 615533090e5SChristophe Leroy 616533090e5SChristophe Leroy#ifndef CONFIG_ALTIVEC 617533090e5SChristophe Leroy#define altivec_assist_exception unknown_exception 618533090e5SChristophe Leroy#endif 619533090e5SChristophe Leroy 620533090e5SChristophe Leroy#ifndef CONFIG_TAU_INT 6216c6aee00SNicholas Piggin#define TAUException unknown_async_exception 622533090e5SChristophe Leroy#endif 623533090e5SChristophe Leroy 624acc142b6SChristophe Leroy EXCEPTION(0x1300, Trap_13, instruction_breakpoint_exception) 625acc142b6SChristophe Leroy EXCEPTION(0x1400, SMI, SMIException) 626acc142b6SChristophe Leroy EXCEPTION(0x1500, Trap_15, unknown_exception) 627acc142b6SChristophe Leroy EXCEPTION(0x1600, Trap_16, altivec_assist_exception) 628acc142b6SChristophe Leroy EXCEPTION(0x1700, Trap_17, TAUException) 629acc142b6SChristophe Leroy EXCEPTION(0x1800, Trap_18, unknown_exception) 630acc142b6SChristophe Leroy EXCEPTION(0x1900, Trap_19, unknown_exception) 631acc142b6SChristophe Leroy EXCEPTION(0x1a00, Trap_1a, unknown_exception) 632acc142b6SChristophe Leroy EXCEPTION(0x1b00, Trap_1b, unknown_exception) 633acc142b6SChristophe Leroy EXCEPTION(0x1c00, Trap_1c, unknown_exception) 634acc142b6SChristophe Leroy EXCEPTION(0x1d00, Trap_1d, unknown_exception) 635acc142b6SChristophe Leroy EXCEPTION(0x1e00, Trap_1e, unknown_exception) 636acc142b6SChristophe Leroy EXCEPTION(0x1f00, Trap_1f, unknown_exception) 637acc142b6SChristophe Leroy EXCEPTION(0x2000, RunMode, RunModeException) 638acc142b6SChristophe Leroy EXCEPTION(0x2100, Trap_21, unknown_exception) 639acc142b6SChristophe Leroy EXCEPTION(0x2200, Trap_22, unknown_exception) 640acc142b6SChristophe Leroy EXCEPTION(0x2300, Trap_23, unknown_exception) 641acc142b6SChristophe Leroy EXCEPTION(0x2400, Trap_24, unknown_exception) 642acc142b6SChristophe Leroy EXCEPTION(0x2500, Trap_25, unknown_exception) 643acc142b6SChristophe Leroy EXCEPTION(0x2600, Trap_26, unknown_exception) 644acc142b6SChristophe Leroy EXCEPTION(0x2700, Trap_27, unknown_exception) 645acc142b6SChristophe Leroy EXCEPTION(0x2800, Trap_28, unknown_exception) 646acc142b6SChristophe Leroy EXCEPTION(0x2900, Trap_29, unknown_exception) 647acc142b6SChristophe Leroy EXCEPTION(0x2a00, Trap_2a, unknown_exception) 648acc142b6SChristophe Leroy EXCEPTION(0x2b00, Trap_2b, unknown_exception) 649acc142b6SChristophe Leroy EXCEPTION(0x2c00, Trap_2c, unknown_exception) 650acc142b6SChristophe Leroy EXCEPTION(0x2d00, Trap_2d, unknown_exception) 651acc142b6SChristophe Leroy EXCEPTION(0x2e00, Trap_2e, unknown_exception) 652acc142b6SChristophe Leroy EXCEPTION(0x2f00, Trap_2f, unknown_exception) 653533090e5SChristophe Leroy 654dc13b889SChristophe Leroy __HEAD 655533090e5SChristophe Leroy . = 0x3000 656533090e5SChristophe Leroy 657259149cfSChristophe Leroy#ifdef CONFIG_PPC_BOOK3S_604 658533090e5SChristophe Leroy.macro save_regs_thread thread 659533090e5SChristophe Leroy stw r0, THR0(\thread) 660533090e5SChristophe Leroy stw r3, THR3(\thread) 661533090e5SChristophe Leroy stw r4, THR4(\thread) 662533090e5SChristophe Leroy stw r5, THR5(\thread) 663533090e5SChristophe Leroy stw r6, THR6(\thread) 664533090e5SChristophe Leroy stw r8, THR8(\thread) 665533090e5SChristophe Leroy stw r9, THR9(\thread) 666533090e5SChristophe Leroy mflr r0 667533090e5SChristophe Leroy stw r0, THLR(\thread) 668533090e5SChristophe Leroy mfctr r0 669533090e5SChristophe Leroy stw r0, THCTR(\thread) 670533090e5SChristophe Leroy.endm 671533090e5SChristophe Leroy 672533090e5SChristophe Leroy.macro restore_regs_thread thread 673533090e5SChristophe Leroy lwz r0, THLR(\thread) 674533090e5SChristophe Leroy mtlr r0 675533090e5SChristophe Leroy lwz r0, THCTR(\thread) 676533090e5SChristophe Leroy mtctr r0 677533090e5SChristophe Leroy lwz r0, THR0(\thread) 678533090e5SChristophe Leroy lwz r3, THR3(\thread) 679533090e5SChristophe Leroy lwz r4, THR4(\thread) 680533090e5SChristophe Leroy lwz r5, THR5(\thread) 681533090e5SChristophe Leroy lwz r6, THR6(\thread) 682533090e5SChristophe Leroy lwz r8, THR8(\thread) 683533090e5SChristophe Leroy lwz r9, THR9(\thread) 684533090e5SChristophe Leroy.endm 685533090e5SChristophe Leroy 686533090e5SChristophe Leroyhash_page_dsi: 687533090e5SChristophe Leroy save_regs_thread r10 688533090e5SChristophe Leroy mfdsisr r3 689533090e5SChristophe Leroy mfdar r4 690533090e5SChristophe Leroy mfsrr0 r5 691533090e5SChristophe Leroy mfsrr1 r9 692533090e5SChristophe Leroy rlwinm r3, r3, 32 - 15, _PAGE_RW /* DSISR_STORE -> _PAGE_RW */ 693533090e5SChristophe Leroy bl hash_page 694533090e5SChristophe Leroy mfspr r10, SPRN_SPRG_THREAD 695533090e5SChristophe Leroy restore_regs_thread r10 696533090e5SChristophe Leroy b .Lhash_page_dsi_cont 697533090e5SChristophe Leroy 698533090e5SChristophe Leroyhash_page_isi: 699533090e5SChristophe Leroy mr r11, r10 700533090e5SChristophe Leroy mfspr r10, SPRN_SPRG_THREAD 701533090e5SChristophe Leroy save_regs_thread r10 702533090e5SChristophe Leroy li r3, 0 703533090e5SChristophe Leroy lwz r4, SRR0(r10) 704533090e5SChristophe Leroy lwz r9, SRR1(r10) 705533090e5SChristophe Leroy bl hash_page 706533090e5SChristophe Leroy mfspr r10, SPRN_SPRG_THREAD 707533090e5SChristophe Leroy restore_regs_thread r10 708533090e5SChristophe Leroy mr r10, r11 709533090e5SChristophe Leroy b .Lhash_page_isi_cont 710533090e5SChristophe Leroy 711533090e5SChristophe Leroy .globl fast_hash_page_return 712533090e5SChristophe Leroyfast_hash_page_return: 713533090e5SChristophe Leroy andis. r10, r9, SRR1_ISI_NOPT@h /* Set on ISI, cleared on DSI */ 714533090e5SChristophe Leroy mfspr r10, SPRN_SPRG_THREAD 715533090e5SChristophe Leroy restore_regs_thread r10 716533090e5SChristophe Leroy bne 1f 717533090e5SChristophe Leroy 718533090e5SChristophe Leroy /* DSI */ 719533090e5SChristophe Leroy mtcr r11 720533090e5SChristophe Leroy lwz r11, THR11(r10) 721de1cd079SChristophe Leroy mfspr r10, SPRN_SPRG_SCRATCH2 722120c0518SChristophe Leroy rfi 723533090e5SChristophe Leroy 724533090e5SChristophe Leroy1: /* ISI */ 725533090e5SChristophe Leroy mtcr r11 726533090e5SChristophe Leroy mfspr r11, SPRN_SPRG_SCRATCH1 727533090e5SChristophe Leroy mfspr r10, SPRN_SPRG_SCRATCH0 728120c0518SChristophe Leroy rfi 729259149cfSChristophe Leroy#endif /* CONFIG_PPC_BOOK3S_604 */ 730533090e5SChristophe Leroy 7317aa8dd67SChristophe Leroy#ifdef CONFIG_VMAP_STACK 732533090e5SChristophe Leroy vmap_stack_overflow_exception 733533090e5SChristophe Leroy#endif 734533090e5SChristophe Leroy 735dc13b889SChristophe Leroy __HEAD 736533090e5SChristophe LeroyAltiVecUnavailable: 737719e7e21SChristophe Leroy EXCEPTION_PROLOG 0xf20 AltiVecUnavailable 738533090e5SChristophe Leroy#ifdef CONFIG_ALTIVEC 739533090e5SChristophe Leroy beq 1f 740533090e5SChristophe Leroy bl load_up_altivec /* if from user, just load it up */ 741533090e5SChristophe Leroy b fast_exception_return 742533090e5SChristophe Leroy#endif /* CONFIG_ALTIVEC */ 7434c0104a8SChristophe Leroy1: prepare_transfer_to_handler 7444c0104a8SChristophe Leroy bl altivec_unavailable_exception 7454c0104a8SChristophe Leroy b interrupt_return 746533090e5SChristophe Leroy 747dc13b889SChristophe Leroy __HEAD 748533090e5SChristophe LeroyPerformanceMonitor: 749719e7e21SChristophe Leroy EXCEPTION_PROLOG 0xf00 PerformanceMonitor 7504c0104a8SChristophe Leroy prepare_transfer_to_handler 7514c0104a8SChristophe Leroy bl performance_monitor_exception 7524c0104a8SChristophe Leroy b interrupt_return 753533090e5SChristophe Leroy 754533090e5SChristophe Leroy 755dc13b889SChristophe Leroy __HEAD 756533090e5SChristophe Leroy/* 757533090e5SChristophe Leroy * This code is jumped to from the startup code to copy 758533090e5SChristophe Leroy * the kernel image to physical address PHYSICAL_START. 759533090e5SChristophe Leroy */ 760533090e5SChristophe Leroyrelocate_kernel: 761533090e5SChristophe Leroy lis r3,PHYSICAL_START@h /* Destination base address */ 762533090e5SChristophe Leroy li r6,0 /* Destination offset */ 763533090e5SChristophe Leroy li r5,0x4000 /* # bytes of memory to copy */ 764533090e5SChristophe Leroy bl copy_and_flush /* copy the first 0x4000 bytes */ 765533090e5SChristophe Leroy addi r0,r3,4f@l /* jump to the address of 4f */ 766533090e5SChristophe Leroy mtctr r0 /* in copy and do the rest. */ 767533090e5SChristophe Leroy bctr /* jump to the copy */ 76856afad88SChristophe Leroy4: lis r5,_end-KERNELBASE@h 76956afad88SChristophe Leroy ori r5,r5,_end-KERNELBASE@l 770533090e5SChristophe Leroy bl copy_and_flush /* copy the rest */ 771533090e5SChristophe Leroy b turn_on_mmu 772533090e5SChristophe Leroy 773533090e5SChristophe Leroy/* 774533090e5SChristophe Leroy * Copy routine used to copy the kernel to start at physical address 0 775533090e5SChristophe Leroy * and flush and invalidate the caches as needed. 776533090e5SChristophe Leroy * r3 = dest addr, r4 = source addr, r5 = copy limit, r6 = start offset 777533090e5SChristophe Leroy * on exit, r3, r4, r5 are unchanged, r6 is updated to be >= r5. 778533090e5SChristophe Leroy */ 77927e21e8fSChristophe Leroy_GLOBAL(copy_and_flush) 780533090e5SChristophe Leroy addi r5,r5,-4 781533090e5SChristophe Leroy addi r6,r6,-4 782533090e5SChristophe Leroy4: li r0,L1_CACHE_BYTES/4 783533090e5SChristophe Leroy mtctr r0 784533090e5SChristophe Leroy3: addi r6,r6,4 /* copy a cache line */ 785533090e5SChristophe Leroy lwzx r0,r6,r4 786533090e5SChristophe Leroy stwx r0,r6,r3 787533090e5SChristophe Leroy bdnz 3b 788533090e5SChristophe Leroy dcbst r6,r3 /* write it to memory */ 789533090e5SChristophe Leroy sync 790533090e5SChristophe Leroy icbi r6,r3 /* flush the icache line */ 791533090e5SChristophe Leroy cmplw 0,r6,r5 792533090e5SChristophe Leroy blt 4b 793533090e5SChristophe Leroy sync /* additional sync needed on g4 */ 794533090e5SChristophe Leroy isync 795533090e5SChristophe Leroy addi r5,r5,4 796533090e5SChristophe Leroy addi r6,r6,4 797533090e5SChristophe Leroy blr 798533090e5SChristophe Leroy 799533090e5SChristophe Leroy#ifdef CONFIG_SMP 800533090e5SChristophe Leroy .globl __secondary_start_mpc86xx 801533090e5SChristophe Leroy__secondary_start_mpc86xx: 802533090e5SChristophe Leroy mfspr r3, SPRN_PIR 803533090e5SChristophe Leroy stw r3, __secondary_hold_acknowledge@l(0) 804533090e5SChristophe Leroy mr r24, r3 /* cpu # */ 805533090e5SChristophe Leroy b __secondary_start 806533090e5SChristophe Leroy 807533090e5SChristophe Leroy .globl __secondary_start_pmac_0 808533090e5SChristophe Leroy__secondary_start_pmac_0: 809533090e5SChristophe Leroy /* NB the entries for cpus 0, 1, 2 must each occupy 8 bytes. */ 810533090e5SChristophe Leroy li r24,0 811533090e5SChristophe Leroy b 1f 812533090e5SChristophe Leroy li r24,1 813533090e5SChristophe Leroy b 1f 814533090e5SChristophe Leroy li r24,2 815533090e5SChristophe Leroy b 1f 816533090e5SChristophe Leroy li r24,3 817533090e5SChristophe Leroy1: 818533090e5SChristophe Leroy /* on powersurge, we come in here with IR=0 and DR=1, and DBAT 0 819533090e5SChristophe Leroy set to map the 0xf0000000 - 0xffffffff region */ 820533090e5SChristophe Leroy mfmsr r0 821533090e5SChristophe Leroy rlwinm r0,r0,0,28,26 /* clear DR (0x10) */ 822533090e5SChristophe Leroy mtmsr r0 823533090e5SChristophe Leroy isync 824533090e5SChristophe Leroy 825533090e5SChristophe Leroy .globl __secondary_start 826533090e5SChristophe Leroy__secondary_start: 827533090e5SChristophe Leroy /* Copy some CPU settings from CPU 0 */ 828533090e5SChristophe Leroy bl __restore_cpu_setup 829533090e5SChristophe Leroy 830533090e5SChristophe Leroy lis r3,-KERNELBASE@h 831533090e5SChristophe Leroy mr r4,r24 832533090e5SChristophe Leroy bl call_setup_cpu /* Call setup_cpu for this CPU */ 833533090e5SChristophe Leroy lis r3,-KERNELBASE@h 834533090e5SChristophe Leroy bl init_idle_6xx 835533090e5SChristophe Leroy 836533090e5SChristophe Leroy /* get current's stack and current */ 837533090e5SChristophe Leroy lis r2,secondary_current@ha 838533090e5SChristophe Leroy tophys(r2,r2) 839533090e5SChristophe Leroy lwz r2,secondary_current@l(r2) 840533090e5SChristophe Leroy tophys(r1,r2) 841533090e5SChristophe Leroy lwz r1,TASK_STACK(r1) 842533090e5SChristophe Leroy 843533090e5SChristophe Leroy /* stack */ 844*90f1b431SNicholas Piggin addi r1,r1,THREAD_SIZE-STACK_FRAME_MIN_SIZE 845533090e5SChristophe Leroy li r0,0 846533090e5SChristophe Leroy tophys(r3,r1) 847533090e5SChristophe Leroy stw r0,0(r3) 848533090e5SChristophe Leroy 849533090e5SChristophe Leroy /* load up the MMU */ 850533090e5SChristophe Leroy bl load_segment_registers 851533090e5SChristophe Leroy bl load_up_mmu 852533090e5SChristophe Leroy 853533090e5SChristophe Leroy /* ptr to phys current thread */ 854533090e5SChristophe Leroy tophys(r4,r2) 855533090e5SChristophe Leroy addi r4,r4,THREAD /* phys address of our thread_struct */ 856533090e5SChristophe Leroy mtspr SPRN_SPRG_THREAD,r4 857c4a22611SChristophe LeroyBEGIN_MMU_FTR_SECTION 858533090e5SChristophe Leroy lis r4, (swapper_pg_dir - PAGE_OFFSET)@h 859533090e5SChristophe Leroy ori r4, r4, (swapper_pg_dir - PAGE_OFFSET)@l 860c4a22611SChristophe Leroy rlwinm r4, r4, 4, 0xffff01ff 861c4a22611SChristophe Leroy mtspr SPRN_SDR1, r4 862c4a22611SChristophe LeroyEND_MMU_FTR_SECTION_IFCLR(MMU_FTR_HPTE_TABLE) 863533090e5SChristophe Leroy 864533090e5SChristophe Leroy /* enable MMU and jump to start_secondary */ 865533090e5SChristophe Leroy li r4,MSR_KERNEL 866533090e5SChristophe Leroy lis r3,start_secondary@h 867533090e5SChristophe Leroy ori r3,r3,start_secondary@l 868533090e5SChristophe Leroy mtspr SPRN_SRR0,r3 869533090e5SChristophe Leroy mtspr SPRN_SRR1,r4 870120c0518SChristophe Leroy rfi 871533090e5SChristophe Leroy#endif /* CONFIG_SMP */ 872533090e5SChristophe Leroy 873533090e5SChristophe Leroy#ifdef CONFIG_KVM_BOOK3S_HANDLER 874533090e5SChristophe Leroy#include "../kvm/book3s_rmhandlers.S" 875533090e5SChristophe Leroy#endif 876533090e5SChristophe Leroy 877533090e5SChristophe Leroy/* 878533090e5SChristophe Leroy * Load stuff into the MMU. Intended to be called with 879533090e5SChristophe Leroy * IR=0 and DR=0. 880533090e5SChristophe Leroy */ 8812da37761SChristophe LeroySYM_FUNC_START_LOCAL(early_hash_table) 882533090e5SChristophe Leroy sync /* Force all PTE updates to finish */ 883533090e5SChristophe Leroy isync 884533090e5SChristophe Leroy tlbia /* Clear all TLB entries */ 885533090e5SChristophe Leroy sync /* wait for tlbia/tlbie to finish */ 886533090e5SChristophe Leroy TLBSYNC /* ... on all CPUs */ 887533090e5SChristophe Leroy /* Load the SDR1 register (hash table base & size) */ 888533090e5SChristophe Leroy lis r6, early_hash - PAGE_OFFSET@h 889533090e5SChristophe Leroy ori r6, r6, 3 /* 256kB table */ 890533090e5SChristophe Leroy mtspr SPRN_SDR1, r6 891533090e5SChristophe Leroy blr 8922da37761SChristophe LeroySYM_FUNC_END(early_hash_table) 893533090e5SChristophe Leroy 8942da37761SChristophe LeroySYM_FUNC_START_LOCAL(load_up_mmu) 895533090e5SChristophe Leroy sync /* Force all PTE updates to finish */ 896533090e5SChristophe Leroy isync 897533090e5SChristophe Leroy tlbia /* Clear all TLB entries */ 898533090e5SChristophe Leroy sync /* wait for tlbia/tlbie to finish */ 899533090e5SChristophe Leroy TLBSYNC /* ... on all CPUs */ 900c4a22611SChristophe LeroyBEGIN_MMU_FTR_SECTION 901533090e5SChristophe Leroy /* Load the SDR1 register (hash table base & size) */ 902533090e5SChristophe Leroy lis r6,_SDR1@ha 903533090e5SChristophe Leroy tophys(r6,r6) 904533090e5SChristophe Leroy lwz r6,_SDR1@l(r6) 905533090e5SChristophe Leroy mtspr SPRN_SDR1,r6 906c4a22611SChristophe LeroyEND_MMU_FTR_SECTION_IFSET(MMU_FTR_HPTE_TABLE) 907533090e5SChristophe Leroy 908533090e5SChristophe Leroy/* Load the BAT registers with the values set up by MMU_init. */ 909533090e5SChristophe Leroy lis r3,BATS@ha 910533090e5SChristophe Leroy addi r3,r3,BATS@l 911533090e5SChristophe Leroy tophys(r3,r3) 912533090e5SChristophe Leroy LOAD_BAT(0,r3,r4,r5) 913533090e5SChristophe Leroy LOAD_BAT(1,r3,r4,r5) 914533090e5SChristophe Leroy LOAD_BAT(2,r3,r4,r5) 915533090e5SChristophe Leroy LOAD_BAT(3,r3,r4,r5) 916533090e5SChristophe LeroyBEGIN_MMU_FTR_SECTION 917533090e5SChristophe Leroy LOAD_BAT(4,r3,r4,r5) 918533090e5SChristophe Leroy LOAD_BAT(5,r3,r4,r5) 919533090e5SChristophe Leroy LOAD_BAT(6,r3,r4,r5) 920533090e5SChristophe Leroy LOAD_BAT(7,r3,r4,r5) 921533090e5SChristophe LeroyEND_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS) 922533090e5SChristophe Leroy blr 9232da37761SChristophe LeroySYM_FUNC_END(load_up_mmu) 924533090e5SChristophe Leroy 925533090e5SChristophe Leroy_GLOBAL(load_segment_registers) 926533090e5SChristophe Leroy li r0, NUM_USER_SEGMENTS /* load up user segment register values */ 927533090e5SChristophe Leroy mtctr r0 /* for context 0 */ 928526d4a4cSChristophe Leroy#ifdef CONFIG_PPC_KUEP 929526d4a4cSChristophe Leroy lis r3, SR_NX@h /* Kp = 0, Ks = 0, VSID = 0 */ 930526d4a4cSChristophe Leroy#else 931533090e5SChristophe Leroy li r3, 0 /* Kp = 0, Ks = 0, VSID = 0 */ 932526d4a4cSChristophe Leroy#endif 933533090e5SChristophe Leroy li r4, 0 934533090e5SChristophe Leroy3: mtsrin r3, r4 935533090e5SChristophe Leroy addi r3, r3, 0x111 /* increment VSID */ 936533090e5SChristophe Leroy addis r4, r4, 0x1000 /* address of next segment */ 937533090e5SChristophe Leroy bdnz 3b 938533090e5SChristophe Leroy li r0, 16 - NUM_USER_SEGMENTS /* load up kernel segment registers */ 939533090e5SChristophe Leroy mtctr r0 /* for context 0 */ 940533090e5SChristophe Leroy rlwinm r3, r3, 0, ~SR_NX /* Nx = 0 */ 941533090e5SChristophe Leroy rlwinm r3, r3, 0, ~SR_KS /* Ks = 0 */ 942533090e5SChristophe Leroy oris r3, r3, SR_KP@h /* Kp = 1 */ 943533090e5SChristophe Leroy3: mtsrin r3, r4 944533090e5SChristophe Leroy addi r3, r3, 0x111 /* increment VSID */ 945533090e5SChristophe Leroy addis r4, r4, 0x1000 /* address of next segment */ 946533090e5SChristophe Leroy bdnz 3b 947533090e5SChristophe Leroy blr 948533090e5SChristophe Leroy 949533090e5SChristophe Leroy/* 950533090e5SChristophe Leroy * This is where the main kernel code starts. 951533090e5SChristophe Leroy */ 952533090e5SChristophe Leroystart_here: 953533090e5SChristophe Leroy /* ptr to current */ 954533090e5SChristophe Leroy lis r2,init_task@h 955533090e5SChristophe Leroy ori r2,r2,init_task@l 956533090e5SChristophe Leroy /* Set up for using our exception vectors */ 957533090e5SChristophe Leroy /* ptr to phys current thread */ 958533090e5SChristophe Leroy tophys(r4,r2) 959533090e5SChristophe Leroy addi r4,r4,THREAD /* init task's THREAD */ 960533090e5SChristophe Leroy mtspr SPRN_SPRG_THREAD,r4 961c4a22611SChristophe LeroyBEGIN_MMU_FTR_SECTION 962533090e5SChristophe Leroy lis r4, (swapper_pg_dir - PAGE_OFFSET)@h 963533090e5SChristophe Leroy ori r4, r4, (swapper_pg_dir - PAGE_OFFSET)@l 964c4a22611SChristophe Leroy rlwinm r4, r4, 4, 0xffff01ff 965c4a22611SChristophe Leroy mtspr SPRN_SDR1, r4 966c4a22611SChristophe LeroyEND_MMU_FTR_SECTION_IFCLR(MMU_FTR_HPTE_TABLE) 967533090e5SChristophe Leroy 968533090e5SChristophe Leroy /* stack */ 969533090e5SChristophe Leroy lis r1,init_thread_union@ha 970533090e5SChristophe Leroy addi r1,r1,init_thread_union@l 971533090e5SChristophe Leroy li r0,0 972*90f1b431SNicholas Piggin stwu r0,THREAD_SIZE-STACK_FRAME_MIN_SIZE(r1) 973533090e5SChristophe Leroy/* 974533090e5SChristophe Leroy * Do early platform-specific initialization, 975533090e5SChristophe Leroy * and set up the MMU. 976533090e5SChristophe Leroy */ 977533090e5SChristophe Leroy#ifdef CONFIG_KASAN 978533090e5SChristophe Leroy bl kasan_early_init 979533090e5SChristophe Leroy#endif 980533090e5SChristophe Leroy li r3,0 981533090e5SChristophe Leroy mr r4,r31 982533090e5SChristophe Leroy bl machine_init 983533090e5SChristophe Leroy bl __save_cpu_setup 984533090e5SChristophe Leroy bl MMU_init 985533090e5SChristophe Leroy bl MMU_init_hw_patch 986533090e5SChristophe Leroy 987533090e5SChristophe Leroy/* 988533090e5SChristophe Leroy * Go back to running unmapped so we can load up new values 989533090e5SChristophe Leroy * for SDR1 (hash table pointer) and the segment registers 990533090e5SChristophe Leroy * and change to using our exception vectors. 991533090e5SChristophe Leroy */ 992533090e5SChristophe Leroy lis r4,2f@h 993533090e5SChristophe Leroy ori r4,r4,2f@l 994533090e5SChristophe Leroy tophys(r4,r4) 995533090e5SChristophe Leroy li r3,MSR_KERNEL & ~(MSR_IR|MSR_DR) 996533090e5SChristophe Leroy 997533090e5SChristophe Leroy .align 4 998533090e5SChristophe Leroy mtspr SPRN_SRR0,r4 999533090e5SChristophe Leroy mtspr SPRN_SRR1,r3 1000120c0518SChristophe Leroy rfi 1001533090e5SChristophe Leroy/* Load up the kernel context */ 1002533090e5SChristophe Leroy2: bl load_up_mmu 1003533090e5SChristophe Leroy 1004533090e5SChristophe Leroy#ifdef CONFIG_BDI_SWITCH 1005533090e5SChristophe Leroy /* Add helper information for the Abatron bdiGDB debugger. 1006533090e5SChristophe Leroy * We do this here because we know the mmu is disabled, and 1007533090e5SChristophe Leroy * will be enabled for real in just a few instructions. 1008533090e5SChristophe Leroy */ 1009533090e5SChristophe Leroy lis r5, abatron_pteptrs@h 1010533090e5SChristophe Leroy ori r5, r5, abatron_pteptrs@l 1011533090e5SChristophe Leroy stw r5, 0xf0(0) /* This much match your Abatron config */ 1012533090e5SChristophe Leroy lis r6, swapper_pg_dir@h 1013533090e5SChristophe Leroy ori r6, r6, swapper_pg_dir@l 1014533090e5SChristophe Leroy tophys(r5, r5) 1015533090e5SChristophe Leroy stw r6, 0(r5) 1016533090e5SChristophe Leroy#endif /* CONFIG_BDI_SWITCH */ 1017533090e5SChristophe Leroy 1018533090e5SChristophe Leroy/* Now turn on the MMU for real! */ 1019533090e5SChristophe Leroy li r4,MSR_KERNEL 1020533090e5SChristophe Leroy lis r3,start_kernel@h 1021533090e5SChristophe Leroy ori r3,r3,start_kernel@l 1022533090e5SChristophe Leroy mtspr SPRN_SRR0,r3 1023533090e5SChristophe Leroy mtspr SPRN_SRR1,r4 1024120c0518SChristophe Leroy rfi 1025533090e5SChristophe Leroy 1026533090e5SChristophe Leroy/* 1027533090e5SChristophe Leroy * An undocumented "feature" of 604e requires that the v bit 1028533090e5SChristophe Leroy * be cleared before changing BAT values. 1029533090e5SChristophe Leroy * 1030533090e5SChristophe Leroy * Also, newer IBM firmware does not clear bat3 and 4 so 1031533090e5SChristophe Leroy * this makes sure it's done. 1032533090e5SChristophe Leroy * -- Cort 1033533090e5SChristophe Leroy */ 10342da37761SChristophe LeroySYM_FUNC_START_LOCAL(clear_bats) 1035533090e5SChristophe Leroy li r10,0 1036533090e5SChristophe Leroy 1037533090e5SChristophe Leroy mtspr SPRN_DBAT0U,r10 1038533090e5SChristophe Leroy mtspr SPRN_DBAT0L,r10 1039533090e5SChristophe Leroy mtspr SPRN_DBAT1U,r10 1040533090e5SChristophe Leroy mtspr SPRN_DBAT1L,r10 1041533090e5SChristophe Leroy mtspr SPRN_DBAT2U,r10 1042533090e5SChristophe Leroy mtspr SPRN_DBAT2L,r10 1043533090e5SChristophe Leroy mtspr SPRN_DBAT3U,r10 1044533090e5SChristophe Leroy mtspr SPRN_DBAT3L,r10 1045533090e5SChristophe Leroy mtspr SPRN_IBAT0U,r10 1046533090e5SChristophe Leroy mtspr SPRN_IBAT0L,r10 1047533090e5SChristophe Leroy mtspr SPRN_IBAT1U,r10 1048533090e5SChristophe Leroy mtspr SPRN_IBAT1L,r10 1049533090e5SChristophe Leroy mtspr SPRN_IBAT2U,r10 1050533090e5SChristophe Leroy mtspr SPRN_IBAT2L,r10 1051533090e5SChristophe Leroy mtspr SPRN_IBAT3U,r10 1052533090e5SChristophe Leroy mtspr SPRN_IBAT3L,r10 1053533090e5SChristophe LeroyBEGIN_MMU_FTR_SECTION 1054533090e5SChristophe Leroy /* Here's a tweak: at this point, CPU setup have 1055533090e5SChristophe Leroy * not been called yet, so HIGH_BAT_EN may not be 1056533090e5SChristophe Leroy * set in HID0 for the 745x processors. However, it 1057533090e5SChristophe Leroy * seems that doesn't affect our ability to actually 1058533090e5SChristophe Leroy * write to these SPRs. 1059533090e5SChristophe Leroy */ 1060533090e5SChristophe Leroy mtspr SPRN_DBAT4U,r10 1061533090e5SChristophe Leroy mtspr SPRN_DBAT4L,r10 1062533090e5SChristophe Leroy mtspr SPRN_DBAT5U,r10 1063533090e5SChristophe Leroy mtspr SPRN_DBAT5L,r10 1064533090e5SChristophe Leroy mtspr SPRN_DBAT6U,r10 1065533090e5SChristophe Leroy mtspr SPRN_DBAT6L,r10 1066533090e5SChristophe Leroy mtspr SPRN_DBAT7U,r10 1067533090e5SChristophe Leroy mtspr SPRN_DBAT7L,r10 1068533090e5SChristophe Leroy mtspr SPRN_IBAT4U,r10 1069533090e5SChristophe Leroy mtspr SPRN_IBAT4L,r10 1070533090e5SChristophe Leroy mtspr SPRN_IBAT5U,r10 1071533090e5SChristophe Leroy mtspr SPRN_IBAT5L,r10 1072533090e5SChristophe Leroy mtspr SPRN_IBAT6U,r10 1073533090e5SChristophe Leroy mtspr SPRN_IBAT6L,r10 1074533090e5SChristophe Leroy mtspr SPRN_IBAT7U,r10 1075533090e5SChristophe Leroy mtspr SPRN_IBAT7L,r10 1076533090e5SChristophe LeroyEND_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS) 1077533090e5SChristophe Leroy blr 10782da37761SChristophe LeroySYM_FUNC_END(clear_bats) 1079533090e5SChristophe Leroy 108027e21e8fSChristophe Leroy_GLOBAL(update_bats) 1081533090e5SChristophe Leroy lis r4, 1f@h 1082533090e5SChristophe Leroy ori r4, r4, 1f@l 1083533090e5SChristophe Leroy tophys(r4, r4) 1084533090e5SChristophe Leroy mfmsr r6 1085533090e5SChristophe Leroy mflr r7 1086533090e5SChristophe Leroy li r3, MSR_KERNEL & ~(MSR_IR | MSR_DR) 1087533090e5SChristophe Leroy rlwinm r0, r6, 0, ~MSR_RI 1088533090e5SChristophe Leroy rlwinm r0, r0, 0, ~MSR_EE 1089533090e5SChristophe Leroy mtmsr r0 1090533090e5SChristophe Leroy 1091533090e5SChristophe Leroy .align 4 1092533090e5SChristophe Leroy mtspr SPRN_SRR0, r4 1093533090e5SChristophe Leroy mtspr SPRN_SRR1, r3 1094120c0518SChristophe Leroy rfi 1095533090e5SChristophe Leroy1: bl clear_bats 1096533090e5SChristophe Leroy lis r3, BATS@ha 1097533090e5SChristophe Leroy addi r3, r3, BATS@l 1098533090e5SChristophe Leroy tophys(r3, r3) 1099533090e5SChristophe Leroy LOAD_BAT(0, r3, r4, r5) 1100533090e5SChristophe Leroy LOAD_BAT(1, r3, r4, r5) 1101533090e5SChristophe Leroy LOAD_BAT(2, r3, r4, r5) 1102533090e5SChristophe Leroy LOAD_BAT(3, r3, r4, r5) 1103533090e5SChristophe LeroyBEGIN_MMU_FTR_SECTION 1104533090e5SChristophe Leroy LOAD_BAT(4, r3, r4, r5) 1105533090e5SChristophe Leroy LOAD_BAT(5, r3, r4, r5) 1106533090e5SChristophe Leroy LOAD_BAT(6, r3, r4, r5) 1107533090e5SChristophe Leroy LOAD_BAT(7, r3, r4, r5) 1108533090e5SChristophe LeroyEND_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS) 1109533090e5SChristophe Leroy li r3, MSR_KERNEL & ~(MSR_IR | MSR_DR | MSR_RI) 1110533090e5SChristophe Leroy mtmsr r3 1111533090e5SChristophe Leroy mtspr SPRN_SRR0, r7 1112533090e5SChristophe Leroy mtspr SPRN_SRR1, r6 1113120c0518SChristophe Leroy rfi 1114533090e5SChristophe Leroy 11152da37761SChristophe LeroySYM_FUNC_START_LOCAL(flush_tlbs) 1116533090e5SChristophe Leroy lis r10, 0x40 1117533090e5SChristophe Leroy1: addic. r10, r10, -0x1000 1118533090e5SChristophe Leroy tlbie r10 1119533090e5SChristophe Leroy bgt 1b 1120533090e5SChristophe Leroy sync 1121533090e5SChristophe Leroy blr 11222da37761SChristophe LeroySYM_FUNC_END(flush_tlbs) 1123533090e5SChristophe Leroy 11242da37761SChristophe LeroySYM_FUNC_START_LOCAL(mmu_off) 1125533090e5SChristophe Leroy addi r4, r3, __after_mmu_off - _start 1126533090e5SChristophe Leroy mfmsr r3 1127533090e5SChristophe Leroy andi. r0,r3,MSR_DR|MSR_IR /* MMU enabled? */ 1128533090e5SChristophe Leroy beqlr 1129533090e5SChristophe Leroy andc r3,r3,r0 1130533090e5SChristophe Leroy 1131533090e5SChristophe Leroy .align 4 1132533090e5SChristophe Leroy mtspr SPRN_SRR0,r4 1133533090e5SChristophe Leroy mtspr SPRN_SRR1,r3 1134533090e5SChristophe Leroy sync 1135120c0518SChristophe Leroy rfi 11362da37761SChristophe LeroySYM_FUNC_END(mmu_off) 1137533090e5SChristophe Leroy 1138533090e5SChristophe Leroy/* We use one BAT to map up to 256M of RAM at _PAGE_OFFSET */ 11392da37761SChristophe LeroySYM_FUNC_START_LOCAL(initial_bats) 1140533090e5SChristophe Leroy lis r11,PAGE_OFFSET@h 1141533090e5SChristophe Leroy tophys(r8,r11) 1142533090e5SChristophe Leroy#ifdef CONFIG_SMP 1143533090e5SChristophe Leroy ori r8,r8,0x12 /* R/W access, M=1 */ 1144533090e5SChristophe Leroy#else 1145533090e5SChristophe Leroy ori r8,r8,2 /* R/W access */ 1146533090e5SChristophe Leroy#endif /* CONFIG_SMP */ 1147533090e5SChristophe Leroy ori r11,r11,BL_256M<<2|0x2 /* set up BAT registers for 604 */ 1148533090e5SChristophe Leroy 1149533090e5SChristophe Leroy mtspr SPRN_DBAT0L,r8 /* N.B. 6xx have valid */ 1150533090e5SChristophe Leroy mtspr SPRN_DBAT0U,r11 /* bit in upper BAT register */ 1151533090e5SChristophe Leroy mtspr SPRN_IBAT0L,r8 1152533090e5SChristophe Leroy mtspr SPRN_IBAT0U,r11 1153533090e5SChristophe Leroy isync 1154533090e5SChristophe Leroy blr 11552da37761SChristophe LeroySYM_FUNC_END(initial_bats) 1156533090e5SChristophe Leroy 1157533090e5SChristophe Leroy#ifdef CONFIG_BOOTX_TEXT 11582da37761SChristophe LeroySYM_FUNC_START_LOCAL(setup_disp_bat) 1159533090e5SChristophe Leroy /* 1160533090e5SChristophe Leroy * setup the display bat prepared for us in prom.c 1161533090e5SChristophe Leroy */ 1162533090e5SChristophe Leroy mflr r8 1163533090e5SChristophe Leroy bl reloc_offset 1164533090e5SChristophe Leroy mtlr r8 1165533090e5SChristophe Leroy addis r8,r3,disp_BAT@ha 1166533090e5SChristophe Leroy addi r8,r8,disp_BAT@l 1167533090e5SChristophe Leroy cmpwi cr0,r8,0 1168533090e5SChristophe Leroy beqlr 1169533090e5SChristophe Leroy lwz r11,0(r8) 1170533090e5SChristophe Leroy lwz r8,4(r8) 1171533090e5SChristophe Leroy mtspr SPRN_DBAT3L,r8 1172533090e5SChristophe Leroy mtspr SPRN_DBAT3U,r11 1173533090e5SChristophe Leroy blr 11742da37761SChristophe LeroySYM_FUNC_END(setup_disp_bat) 1175533090e5SChristophe Leroy#endif /* CONFIG_BOOTX_TEXT */ 1176533090e5SChristophe Leroy 1177533090e5SChristophe Leroy#ifdef CONFIG_PPC_EARLY_DEBUG_CPM 11782da37761SChristophe LeroySYM_FUNC_START_LOCAL(setup_cpm_bat) 1179533090e5SChristophe Leroy lis r8, 0xf000 1180533090e5SChristophe Leroy ori r8, r8, 0x002a 1181533090e5SChristophe Leroy mtspr SPRN_DBAT1L, r8 1182533090e5SChristophe Leroy 1183533090e5SChristophe Leroy lis r11, 0xf000 1184533090e5SChristophe Leroy ori r11, r11, (BL_1M << 2) | 2 1185533090e5SChristophe Leroy mtspr SPRN_DBAT1U, r11 1186533090e5SChristophe Leroy 1187533090e5SChristophe Leroy blr 11882da37761SChristophe LeroySYM_FUNC_END(setup_cpm_bat) 1189533090e5SChristophe Leroy#endif 1190533090e5SChristophe Leroy 1191533090e5SChristophe Leroy#ifdef CONFIG_PPC_EARLY_DEBUG_USBGECKO 11922da37761SChristophe LeroySYM_FUNC_START_LOCAL(setup_usbgecko_bat) 1193533090e5SChristophe Leroy /* prepare a BAT for early io */ 1194533090e5SChristophe Leroy#if defined(CONFIG_GAMECUBE) 1195533090e5SChristophe Leroy lis r8, 0x0c00 1196533090e5SChristophe Leroy#elif defined(CONFIG_WII) 1197533090e5SChristophe Leroy lis r8, 0x0d00 1198533090e5SChristophe Leroy#else 1199533090e5SChristophe Leroy#error Invalid platform for USB Gecko based early debugging. 1200533090e5SChristophe Leroy#endif 1201533090e5SChristophe Leroy /* 1202533090e5SChristophe Leroy * The virtual address used must match the virtual address 1203533090e5SChristophe Leroy * associated to the fixmap entry FIX_EARLY_DEBUG_BASE. 1204533090e5SChristophe Leroy */ 1205533090e5SChristophe Leroy lis r11, 0xfffe /* top 128K */ 1206533090e5SChristophe Leroy ori r8, r8, 0x002a /* uncached, guarded ,rw */ 1207533090e5SChristophe Leroy ori r11, r11, 0x2 /* 128K, Vs=1, Vp=0 */ 1208533090e5SChristophe Leroy mtspr SPRN_DBAT1L, r8 1209533090e5SChristophe Leroy mtspr SPRN_DBAT1U, r11 1210533090e5SChristophe Leroy blr 12112da37761SChristophe LeroySYM_FUNC_END(setup_usbgecko_bat) 1212533090e5SChristophe Leroy#endif 1213533090e5SChristophe Leroy 1214533090e5SChristophe Leroy .data 1215