^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /* SPDX-License-Identifier: GPL-2.0-or-later */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Initial PowerPC version.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 1996 Cort Dougan <cort@cs.nmt.edu>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Rewritten for PReP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Low-level exception handers, MMU support, and rewrite.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Copyright (c) 1997 Dan Malek <dmalek@jlc.net>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * PowerPC 8xx modifications.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Copyright (c) 1998-1999 TiVo, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * PowerPC 403GCX modifications.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * PowerPC 403GCX/405GP modifications.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * Copyright 2000 MontaVista Software Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * PPC405 modifications
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * PowerPC 403GCX/405GP modifications.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * Author: MontaVista Software, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * frank_rowand@mvista.com or source@mvista.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * debbie_chu@mvista.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * Module name: head_4xx.S
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * Description:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * Kernel execution entry point code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/pgtable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/sizes.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <asm/page.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <asm/mmu.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <asm/cputable.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <asm/thread_info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <asm/ppc_asm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <asm/asm-offsets.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <asm/ptrace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <asm/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include "head_32.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) /* As with the other PowerPC ports, it is expected that when code
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * execution begins here, the following registers contain valid, yet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * optional, information:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * r4 - Starting address of the init RAM disk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * r5 - Ending address of the init RAM disk
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * r6 - Start of kernel command line string (e.g. "mem=96m")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) * r7 - End of kernel command line string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * This is all going to change RSN when we add bi_recs....... -- Dan
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) __HEAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) _ENTRY(_stext);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) _ENTRY(_start);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) mr r31,r3 /* save device tree ptr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* We have to turn on the MMU right away so we get cache modes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) * set correctly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) bl initial_mmu
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) /* We now have the lower 16 Meg mapped into TLB entries, and the caches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * ready to work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) turn_on_mmu:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) lis r0,MSR_KERNEL@h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) ori r0,r0,MSR_KERNEL@l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) mtspr SPRN_SRR1,r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) lis r0,start_here@h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) ori r0,r0,start_here@l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) mtspr SPRN_SRR0,r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) rfi /* enables MMU */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) b . /* prevent prefetch past rfi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) * This area is used for temporarily saving registers during the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * critical exception prolog.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) . = 0xc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) crit_save:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) _ENTRY(crit_r10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) .space 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) _ENTRY(crit_r11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) .space 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) _ENTRY(crit_srr0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) .space 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) _ENTRY(crit_srr1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) .space 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) _ENTRY(saved_ksp_limit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) .space 4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) * Exception prolog for critical exceptions. This is a little different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * from the normal exception prolog above since a critical exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * can potentially occur at any point during normal exception processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * Thus we cannot use the same SPRG registers as the normal prolog above.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * Instead we use a couple of words of memory at low physical addresses.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) * This is OK since we don't support SMP on these processors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) #define CRITICAL_EXCEPTION_PROLOG \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) stw r10,crit_r10@l(0); /* save two registers to work with */\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) stw r11,crit_r11@l(0); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) mfcr r10; /* save CR in r10 for now */\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) mfspr r11,SPRN_SRR3; /* check whether user or kernel */\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) andi. r11,r11,MSR_PR; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) lis r11,critirq_ctx@ha; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) tophys(r11,r11); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) lwz r11,critirq_ctx@l(r11); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) beq 1f; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) /* COMING FROM USER MODE */ \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) mfspr r11,SPRN_SPRG_THREAD; /* if from user, start at top of */\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) lwz r11,TASK_STACK-THREAD(r11); /* this thread's kernel stack */\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 1: addi r11,r11,THREAD_SIZE-INT_FRAME_SIZE; /* Alloc an excpt frm */\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) tophys(r11,r11); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) stw r10,_CCR(r11); /* save various registers */\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) stw r12,GPR12(r11); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) stw r9,GPR9(r11); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) mflr r10; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) stw r10,_LINK(r11); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) mfspr r12,SPRN_DEAR; /* save DEAR and ESR in the frame */\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) stw r12,_DEAR(r11); /* since they may have had stuff */\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) mfspr r9,SPRN_ESR; /* in them at the point where the */\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) stw r9,_ESR(r11); /* exception was taken */\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) mfspr r12,SPRN_SRR2; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) stw r1,GPR1(r11); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) mfspr r9,SPRN_SRR3; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) stw r1,0(r11); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) tovirt(r1,r11); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) rlwinm r9,r9,0,14,12; /* clear MSR_WE (necessary?) */\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) stw r0,GPR0(r11); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) lis r10, STACK_FRAME_REGS_MARKER@ha; /* exception frame marker */\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) addi r10, r10, STACK_FRAME_REGS_MARKER@l; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) stw r10, 8(r11); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) SAVE_4GPRS(3, r11); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) SAVE_2GPRS(7, r11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) * State at this point:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * r9 saved in stack frame, now saved SRR3 & ~MSR_WE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * r10 saved in crit_r10 and in stack frame, trashed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * r11 saved in crit_r11 and in stack frame,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * now phys stack/exception frame pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) * r12 saved in stack frame, now saved SRR2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * CR saved in stack frame, CR0.EQ = !SRR3.PR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * LR, DEAR, ESR in stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * r1 saved in stack frame, now virt stack/excframe pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) * r0, r3-r8 saved in stack frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) * Exception vectors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) #define CRITICAL_EXCEPTION(n, label, hdlr) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) START_EXCEPTION(n, label); \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) CRITICAL_EXCEPTION_PROLOG; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) addi r3,r1,STACK_FRAME_OVERHEAD; \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) EXC_XFER_TEMPLATE(hdlr, n+2, (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) crit_transfer_to_handler, ret_from_crit_exc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) * 0x0100 - Critical Interrupt Exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) CRITICAL_EXCEPTION(0x0100, CriticalInterrupt, unknown_exception)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * 0x0200 - Machine Check Exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) * 0x0300 - Data Storage Exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * This happens for just a few reasons. U0 set (but we don't do that),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) * or zone protection fault (user violation, write to protected page).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) * The other Data TLB exceptions bail out to this point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) * if they can't resolve the lightweight TLB fault.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) START_EXCEPTION(0x0300, DataStorage)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) EXCEPTION_PROLOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) mfspr r5, SPRN_ESR /* Grab the ESR, save it, pass arg3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) stw r5, _ESR(r11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) mfspr r4, SPRN_DEAR /* Grab the DEAR, save it, pass arg2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) stw r4, _DEAR(r11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) EXC_XFER_LITE(0x300, handle_page_fault)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * 0x0400 - Instruction Storage Exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) * This is caused by a fetch from non-execute or guarded pages.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) START_EXCEPTION(0x0400, InstructionAccess)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) EXCEPTION_PROLOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) mr r4,r12 /* Pass SRR0 as arg2 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) stw r4, _DEAR(r11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) li r5,0 /* Pass zero as arg3 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) EXC_XFER_LITE(0x400, handle_page_fault)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) /* 0x0500 - External Interrupt Exception */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) EXCEPTION(0x0500, HardwareInterrupt, do_IRQ, EXC_XFER_LITE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) /* 0x0600 - Alignment Exception */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) START_EXCEPTION(0x0600, Alignment)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) EXCEPTION_PROLOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) mfspr r4,SPRN_DEAR /* Grab the DEAR and save it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) stw r4,_DEAR(r11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) addi r3,r1,STACK_FRAME_OVERHEAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) EXC_XFER_STD(0x600, alignment_exception)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* 0x0700 - Program Exception */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) START_EXCEPTION(0x0700, ProgramCheck)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) EXCEPTION_PROLOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) mfspr r4,SPRN_ESR /* Grab the ESR and save it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) stw r4,_ESR(r11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) addi r3,r1,STACK_FRAME_OVERHEAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) EXC_XFER_STD(0x700, program_check_exception)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) EXCEPTION(0x0800, Trap_08, unknown_exception, EXC_XFER_STD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) EXCEPTION(0x0900, Trap_09, unknown_exception, EXC_XFER_STD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) EXCEPTION(0x0A00, Trap_0A, unknown_exception, EXC_XFER_STD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) EXCEPTION(0x0B00, Trap_0B, unknown_exception, EXC_XFER_STD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) /* 0x0C00 - System Call Exception */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) START_EXCEPTION(0x0C00, SystemCall)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) SYSCALL_ENTRY 0xc00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /* Trap_0D is commented out to get more space for system call exception */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) /* EXCEPTION(0x0D00, Trap_0D, unknown_exception, EXC_XFER_STD) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) EXCEPTION(0x0E00, Trap_0E, unknown_exception, EXC_XFER_STD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) EXCEPTION(0x0F00, Trap_0F, unknown_exception, EXC_XFER_STD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* 0x1000 - Programmable Interval Timer (PIT) Exception */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) . = 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) b Decrementer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) /* 0x1010 - Fixed Interval Timer (FIT) Exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) . = 0x1010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) b FITException
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /* 0x1020 - Watchdog Timer (WDT) Exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) . = 0x1020
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) b WDTException
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /* 0x1100 - Data TLB Miss Exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) * As the name implies, translation is not in the MMU, so search the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * page tables and fix it. The only purpose of this function is to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) * load TLB entries from the page table if they exist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) START_EXCEPTION(0x1100, DTLBMiss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) mtspr SPRN_SPRG_SCRATCH0, r10 /* Save some working registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) mtspr SPRN_SPRG_SCRATCH1, r11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) mtspr SPRN_SPRG_SCRATCH3, r12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) mtspr SPRN_SPRG_SCRATCH4, r9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) mfcr r12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) mfspr r9, SPRN_PID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) mtspr SPRN_SPRG_SCRATCH5, r9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) mfspr r10, SPRN_DEAR /* Get faulting address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) /* If we are faulting a kernel address, we have to use the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * kernel page tables.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) lis r11, PAGE_OFFSET@h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) cmplw r10, r11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) blt+ 3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) lis r11, swapper_pg_dir@h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) ori r11, r11, swapper_pg_dir@l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) li r9, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) mtspr SPRN_PID, r9 /* TLB will have 0 TID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) b 4f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /* Get the PGD for the current thread.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) mfspr r11,SPRN_SPRG_THREAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) lwz r11,PGDIR(r11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) tophys(r11, r11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) rlwimi r11, r10, 12, 20, 29 /* Create L1 (pgdir/pmd) address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) lwz r11, 0(r11) /* Get L1 entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) andi. r9, r11, _PMD_PRESENT /* Check if it points to a PTE page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) beq 2f /* Bail if no table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) rlwimi r11, r10, 22, 20, 29 /* Compute PTE address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) lwz r11, 0(r11) /* Get Linux PTE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) li r9, _PAGE_PRESENT | _PAGE_ACCESSED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) andc. r9, r9, r11 /* Check permission */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) bne 5f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) rlwinm r9, r11, 1, _PAGE_RW /* dirty => rw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) and r9, r9, r11 /* hwwrite = dirty & rw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) rlwimi r11, r9, 0, _PAGE_RW /* replace rw by hwwrite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) /* Create TLB tag. This is the faulting address plus a static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * set of bits. These are size, valid, E, U0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) li r9, 0x00c0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) rlwimi r10, r9, 0, 20, 31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) b finish_tlb_load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) 2: /* Check for possible large-page pmd entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) rlwinm. r9, r11, 2, 22, 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) beq 5f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) /* Create TLB tag. This is the faulting address, plus a static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) * set of bits (valid, E, U0) plus the size from the PMD.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) ori r9, r9, 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) rlwimi r10, r9, 0, 20, 31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) b finish_tlb_load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) /* The bailout. Restore registers to pre-exception conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * and call the heavyweights to help us out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) mfspr r9, SPRN_SPRG_SCRATCH5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) mtspr SPRN_PID, r9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) mtcr r12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) mfspr r9, SPRN_SPRG_SCRATCH4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) mfspr r12, SPRN_SPRG_SCRATCH3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) mfspr r11, SPRN_SPRG_SCRATCH1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) mfspr r10, SPRN_SPRG_SCRATCH0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) b DataStorage
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) /* 0x1200 - Instruction TLB Miss Exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * Nearly the same as above, except we get our information from different
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) * registers and bailout to a different point.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) START_EXCEPTION(0x1200, ITLBMiss)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) mtspr SPRN_SPRG_SCRATCH0, r10 /* Save some working registers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) mtspr SPRN_SPRG_SCRATCH1, r11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) mtspr SPRN_SPRG_SCRATCH3, r12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) mtspr SPRN_SPRG_SCRATCH4, r9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) mfcr r12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) mfspr r9, SPRN_PID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) mtspr SPRN_SPRG_SCRATCH5, r9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) mfspr r10, SPRN_SRR0 /* Get faulting address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /* If we are faulting a kernel address, we have to use the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * kernel page tables.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) lis r11, PAGE_OFFSET@h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) cmplw r10, r11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) blt+ 3f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) lis r11, swapper_pg_dir@h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) ori r11, r11, swapper_pg_dir@l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) li r9, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) mtspr SPRN_PID, r9 /* TLB will have 0 TID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) b 4f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /* Get the PGD for the current thread.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) 3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) mfspr r11,SPRN_SPRG_THREAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) lwz r11,PGDIR(r11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) 4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) tophys(r11, r11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) rlwimi r11, r10, 12, 20, 29 /* Create L1 (pgdir/pmd) address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) lwz r11, 0(r11) /* Get L1 entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) andi. r9, r11, _PMD_PRESENT /* Check if it points to a PTE page */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) beq 2f /* Bail if no table */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) rlwimi r11, r10, 22, 20, 29 /* Compute PTE address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) lwz r11, 0(r11) /* Get Linux PTE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) li r9, _PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_EXEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) andc. r9, r9, r11 /* Check permission */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) bne 5f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) rlwinm r9, r11, 1, _PAGE_RW /* dirty => rw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) and r9, r9, r11 /* hwwrite = dirty & rw */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) rlwimi r11, r9, 0, _PAGE_RW /* replace rw by hwwrite */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) /* Create TLB tag. This is the faulting address plus a static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * set of bits. These are size, valid, E, U0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) li r9, 0x00c0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) rlwimi r10, r9, 0, 20, 31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) b finish_tlb_load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) 2: /* Check for possible large-page pmd entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) rlwinm. r9, r11, 2, 22, 24
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) beq 5f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) /* Create TLB tag. This is the faulting address, plus a static
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) * set of bits (valid, E, U0) plus the size from the PMD.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) ori r9, r9, 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) rlwimi r10, r9, 0, 20, 31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) b finish_tlb_load
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) 5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) /* The bailout. Restore registers to pre-exception conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * and call the heavyweights to help us out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) mfspr r9, SPRN_SPRG_SCRATCH5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) mtspr SPRN_PID, r9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) mtcr r12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) mfspr r9, SPRN_SPRG_SCRATCH4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) mfspr r12, SPRN_SPRG_SCRATCH3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) mfspr r11, SPRN_SPRG_SCRATCH1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) mfspr r10, SPRN_SPRG_SCRATCH0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) b InstructionAccess
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) EXCEPTION(0x1300, Trap_13, unknown_exception, EXC_XFER_STD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) EXCEPTION(0x1400, Trap_14, unknown_exception, EXC_XFER_STD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) EXCEPTION(0x1500, Trap_15, unknown_exception, EXC_XFER_STD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) EXCEPTION(0x1600, Trap_16, unknown_exception, EXC_XFER_STD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) EXCEPTION(0x1700, Trap_17, unknown_exception, EXC_XFER_STD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) EXCEPTION(0x1800, Trap_18, unknown_exception, EXC_XFER_STD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) EXCEPTION(0x1900, Trap_19, unknown_exception, EXC_XFER_STD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) EXCEPTION(0x1A00, Trap_1A, unknown_exception, EXC_XFER_STD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) EXCEPTION(0x1B00, Trap_1B, unknown_exception, EXC_XFER_STD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) EXCEPTION(0x1C00, Trap_1C, unknown_exception, EXC_XFER_STD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) EXCEPTION(0x1D00, Trap_1D, unknown_exception, EXC_XFER_STD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) EXCEPTION(0x1E00, Trap_1E, unknown_exception, EXC_XFER_STD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) EXCEPTION(0x1F00, Trap_1F, unknown_exception, EXC_XFER_STD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) /* Check for a single step debug exception while in an exception
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * handler before state has been saved. This is to catch the case
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) * where an instruction that we are trying to single step causes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) * an exception (eg ITLB/DTLB miss) and thus the first instruction of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) * the exception handler generates a single step debug exception.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) * If we get a debug trap on the first instruction of an exception handler,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) * we reset the MSR_DE in the _exception handler's_ MSR (the debug trap is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) * a critical exception, so we are using SPRN_CSRR1 to manipulate the MSR).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) * The exception handler was handling a non-critical interrupt, so it will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) * save (and later restore) the MSR via SPRN_SRR1, which will still have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) * the MSR_DE bit set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) /* 0x2000 - Debug Exception */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) START_EXCEPTION(0x2000, DebugTrap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) CRITICAL_EXCEPTION_PROLOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) * If this is a single step or branch-taken exception in an
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) * exception entry sequence, it was probably meant to apply to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) * the code where the exception occurred (since exception entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) * doesn't turn off DE automatically). We simulate the effect
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) * of turning off DE on entry to an exception handler by turning
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) * off DE in the SRR3 value and clearing the debug status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) mfspr r10,SPRN_DBSR /* check single-step/branch taken */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) andis. r10,r10,DBSR_IC@h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) beq+ 2f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) andi. r10,r9,MSR_IR|MSR_PR /* check supervisor + MMU off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) beq 1f /* branch and fix it up */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) mfspr r10,SPRN_SRR2 /* Faulting instruction address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) cmplwi r10,0x2100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) bgt+ 2f /* address above exception vectors */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) /* here it looks like we got an inappropriate debug exception. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) 1: rlwinm r9,r9,0,~MSR_DE /* clear DE in the SRR3 value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) lis r10,DBSR_IC@h /* clear the IC event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) mtspr SPRN_DBSR,r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) /* restore state and get out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) lwz r10,_CCR(r11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) lwz r0,GPR0(r11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) lwz r1,GPR1(r11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) mtcrf 0x80,r10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) mtspr SPRN_SRR2,r12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) mtspr SPRN_SRR3,r9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) lwz r9,GPR9(r11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) lwz r12,GPR12(r11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) lwz r10,crit_r10@l(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) lwz r11,crit_r11@l(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) rfci
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) b .
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) /* continue normal handling for a critical exception... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) 2: mfspr r4,SPRN_DBSR
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) addi r3,r1,STACK_FRAME_OVERHEAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) EXC_XFER_TEMPLATE(DebugException, 0x2002, \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)), \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) crit_transfer_to_handler, ret_from_crit_exc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) /* Programmable Interval Timer (PIT) Exception. (from 0x1000) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) Decrementer:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) EXCEPTION_PROLOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) lis r0,TSR_PIS@h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) mtspr SPRN_TSR,r0 /* Clear the PIT exception */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) addi r3,r1,STACK_FRAME_OVERHEAD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) EXC_XFER_LITE(0x1000, timer_interrupt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) /* Fixed Interval Timer (FIT) Exception. (from 0x1010) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) FITException:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) EXCEPTION_PROLOG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) addi r3,r1,STACK_FRAME_OVERHEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) EXC_XFER_STD(0x1010, unknown_exception)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) /* Watchdog Timer (WDT) Exception. (from 0x1020) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) WDTException:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) CRITICAL_EXCEPTION_PROLOG;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) addi r3,r1,STACK_FRAME_OVERHEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) EXC_XFER_TEMPLATE(WatchdogException, 0x1020+2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) (MSR_KERNEL & ~(MSR_ME|MSR_DE|MSR_CE)),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) crit_transfer_to_handler, ret_from_crit_exc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) /* Other PowerPC processors, namely those derived from the 6xx-series
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) * have vectors from 0x2100 through 0x2F00 defined, but marked as reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) * However, for the 4xx-series processors these are neither defined nor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) * reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) /* Damn, I came up one instruction too many to fit into the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) * exception space :-). Both the instruction and data TLB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) * miss get to this point to load the TLB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) * r10 - TLB_TAG value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) * r11 - Linux PTE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) * r9 - available to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * PID - loaded with proper value when we get here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * Upon exit, we reload everything and RFI.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) * Actually, it will fit now, but oh well.....a common place
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) * to load the TLB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) tlb_4xx_index:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) .long 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) finish_tlb_load:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) * Clear out the software-only bits in the PTE to generate the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) * TLB_DATA value. These are the bottom 2 bits of the RPM, the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) * top 3 bits of the zone field, and M.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) li r9, 0x0ce2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) andc r11, r11, r9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) /* load the next available TLB index. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) lwz r9, tlb_4xx_index@l(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) addi r9, r9, 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) andi. r9, r9, PPC40X_TLB_SIZE - 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) stw r9, tlb_4xx_index@l(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) tlbwe r11, r9, TLB_DATA /* Load TLB LO */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) tlbwe r10, r9, TLB_TAG /* Load TLB HI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) /* Done...restore registers and get out of here.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) mfspr r9, SPRN_SPRG_SCRATCH5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) mtspr SPRN_PID, r9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) mtcr r12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) mfspr r9, SPRN_SPRG_SCRATCH4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) mfspr r12, SPRN_SPRG_SCRATCH3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) mfspr r11, SPRN_SPRG_SCRATCH1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) mfspr r10, SPRN_SPRG_SCRATCH0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) rfi /* Should sync shadow TLBs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) b . /* prevent prefetch past rfi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556) /* This is where the main kernel code starts.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) start_here:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) /* ptr to current */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) lis r2,init_task@h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) ori r2,r2,init_task@l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) /* ptr to phys current thread */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) tophys(r4,r2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) addi r4,r4,THREAD /* init task's THREAD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) mtspr SPRN_SPRG_THREAD,r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) /* stack */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) lis r1,init_thread_union@ha
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) addi r1,r1,init_thread_union@l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) li r0,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) stwu r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) bl early_init /* We have to do this with MMU on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * Decide what sort of machine this is and initialize the MMU.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) #ifdef CONFIG_KASAN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) bl kasan_early_init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) li r3,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) mr r4,r31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) bl machine_init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) bl MMU_init
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) /* Go back to running unmapped so we can load up new values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) * and change to using our exception vectors.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) * On the 4xx, all we have to do is invalidate the TLB to clear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) * the old 16M byte TLB mappings.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) lis r4,2f@h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) ori r4,r4,2f@l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) tophys(r4,r4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) lis r3,(MSR_KERNEL & ~(MSR_IR|MSR_DR))@h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) ori r3,r3,(MSR_KERNEL & ~(MSR_IR|MSR_DR))@l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) mtspr SPRN_SRR0,r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) mtspr SPRN_SRR1,r3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) rfi
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) b . /* prevent prefetch past rfi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) /* Load up the kernel context */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) 2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) sync /* Flush to memory before changing TLB */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) tlbia
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) isync /* Flush shadow TLBs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) /* set up the PTE pointers for the Abatron bdiGDB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) lis r6, swapper_pg_dir@h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) ori r6, r6, swapper_pg_dir@l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) lis r5, abatron_pteptrs@h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) ori r5, r5, abatron_pteptrs@l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) stw r5, 0xf0(0) /* Must match your Abatron config file */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) tophys(r5,r5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) stw r6, 0(r5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) /* Now turn on the MMU for real! */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) lis r4,MSR_KERNEL@h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) ori r4,r4,MSR_KERNEL@l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) lis r3,start_kernel@h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) ori r3,r3,start_kernel@l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) mtspr SPRN_SRR0,r3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) mtspr SPRN_SRR1,r4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626) rfi /* enable MMU and jump to start_kernel */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) b . /* prevent prefetch past rfi */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) /* Set up the initial MMU state so we can do the first level of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) * kernel initialization. This maps the first 32 MBytes of memory 1:1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) * virtual to physical and more importantly sets the cache mode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) initial_mmu:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) tlbia /* Invalidate all TLB entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) isync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) /* We should still be executing code at physical address 0x0000xxxx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) * at this point. However, start_here is at virtual address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) * 0xC000xxxx. So, set up a TLB mapping to cover this once
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) * translation is enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) lis r3,KERNELBASE@h /* Load the kernel virtual address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) ori r3,r3,KERNELBASE@l
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645) tophys(r4,r3) /* Load the kernel physical address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) iccci r0,r3 /* Invalidate the i-cache before use */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) /* Load the kernel PID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) li r0,0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) mtspr SPRN_PID,r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) sync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) /* Configure and load one entry into TLB slots 63 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) clrrwi r4,r4,10 /* Mask off the real page number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) ori r4,r4,(TLB_WR | TLB_EX) /* Set the write and execute bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) clrrwi r3,r3,10 /* Mask off the effective page number */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) ori r3,r3,(TLB_VALID | TLB_PAGESZ(PAGESZ_16M))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) li r0,63 /* TLB slot 63 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) tlbwe r4,r0,TLB_DATA /* Load the data portion of the entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) tlbwe r3,r0,TLB_TAG /* Load the tag portion of the entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) li r0,62 /* TLB slot 62 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) addis r4,r4,SZ_16M@h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) addis r3,r3,SZ_16M@h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) tlbwe r4,r0,TLB_DATA /* Load the data portion of the entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) tlbwe r3,r0,TLB_TAG /* Load the tag portion of the entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) isync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) /* Establish the exception vector base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) lis r4,KERNELBASE@h /* EVPR only uses the high 16-bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) tophys(r0,r4) /* Use the physical address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) mtspr SPRN_EVPR,r0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) blr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) _GLOBAL(abort)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) mfspr r13,SPRN_DBCR0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) oris r13,r13,DBCR0_RST_SYSTEM@h
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) mtspr SPRN_DBCR0,r13
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) _GLOBAL(set_context)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) #ifdef CONFIG_BDI_SWITCH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) /* Context switch the PTE pointer for the Abatron BDI2000.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) * The PGDIR is the second parameter.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) lis r5, abatron_pteptrs@ha
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) stw r4, abatron_pteptrs@l + 0x4(r5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) sync
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) mtspr SPRN_PID,r3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) isync /* Need an isync to flush shadow */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) /* TLBs after changing PID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) blr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) /* We put a few things here that have to be page-aligned. This stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) * goes at the beginning of the data segment, which is page-aligned.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) .data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) .align 12
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) .globl sdata
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) sdata:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) .globl empty_zero_page
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) empty_zero_page:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) .space 4096
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) EXPORT_SYMBOL(empty_zero_page)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) .globl swapper_pg_dir
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) swapper_pg_dir:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) .space PGD_TABLE_SIZE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) /* Room for two PTE pointers, usually the kernel and current user pointers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) * to their respective root page table.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) abatron_pteptrs:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) .space 8