16b7ba544SRafal Jaworowski/*- 228bb01e5SRafal Jaworowski * Copyright (C) 2007-2009 Semihalf, Rafal Jaworowski <raj@semihalf.com> 36b7ba544SRafal Jaworowski * Copyright (C) 2006 Semihalf, Marian Balakowicz <m8@semihalf.com> 46b7ba544SRafal Jaworowski * All rights reserved. 56b7ba544SRafal Jaworowski * 66b7ba544SRafal Jaworowski * Redistribution and use in source and binary forms, with or without 76b7ba544SRafal Jaworowski * modification, are permitted provided that the following conditions 86b7ba544SRafal Jaworowski * are met: 96b7ba544SRafal Jaworowski * 1. Redistributions of source code must retain the above copyright 106b7ba544SRafal Jaworowski * notice, this list of conditions and the following disclaimer. 116b7ba544SRafal Jaworowski * 2. Redistributions in binary form must reproduce the above copyright 126b7ba544SRafal Jaworowski * notice, this list of conditions and the following disclaimer in the 136b7ba544SRafal Jaworowski * documentation and/or other materials provided with the distribution. 146b7ba544SRafal Jaworowski * 156b7ba544SRafal Jaworowski * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 166b7ba544SRafal Jaworowski * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 176b7ba544SRafal Jaworowski * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN 186b7ba544SRafal Jaworowski * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 196b7ba544SRafal Jaworowski * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED 206b7ba544SRafal Jaworowski * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 216b7ba544SRafal Jaworowski * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 226b7ba544SRafal Jaworowski * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 236b7ba544SRafal Jaworowski * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 246b7ba544SRafal Jaworowski * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 256b7ba544SRafal Jaworowski */ 266b7ba544SRafal Jaworowski 27fc2a8776SEd Maste#include "assym.inc" 286b7ba544SRafal Jaworowski 29a7452468SJustin Hibbits#include "opt_hwpmc_hooks.h" 30a7452468SJustin Hibbits 316b7ba544SRafal Jaworowski#include <machine/asm.h> 32b9b8eb77SRafal Jaworowski#include <machine/hid.h> 33fdd28cb8SRafal Jaworowski#include <machine/param.h> 346b7ba544SRafal Jaworowski#include <machine/spr.h> 356b7ba544SRafal Jaworowski#include <machine/pte.h> 366b7ba544SRafal Jaworowski#include <machine/trap.h> 376b7ba544SRafal Jaworowski#include <machine/vmparam.h> 386b7ba544SRafal Jaworowski#include <machine/tlb.h> 396b7ba544SRafal Jaworowski 40ab3f2a38SBrandon Bergren#ifdef _CALL_ELF 41ab3f2a38SBrandon Bergren.abiversion _CALL_ELF 42ab3f2a38SBrandon Bergren#endif 43ab3f2a38SBrandon Bergren 44959aea56SRafal Jaworowski#define TMPSTACKSZ 16384 45959aea56SRafal Jaworowski 46e683c328SJustin Hibbits#ifdef __powerpc64__ 47e683c328SJustin Hibbits#define GET_TOCBASE(r) \ 48e683c328SJustin Hibbits mfspr r, SPR_SPRG8 49e683c328SJustin Hibbits#define TOC_RESTORE nop 50e683c328SJustin Hibbits#define CMPI cmpdi 51e683c328SJustin Hibbits#define CMPL cmpld 52e683c328SJustin Hibbits#define LOAD ld 53e683c328SJustin Hibbits#define LOADX ldarx 54e683c328SJustin Hibbits#define STORE std 55e683c328SJustin Hibbits#define STOREX stdcx. 56e683c328SJustin Hibbits#define STU stdu 57e683c328SJustin Hibbits#define CALLSIZE 48 58e683c328SJustin Hibbits#define REDZONE 288 59e683c328SJustin Hibbits#define THREAD_REG %r13 60e683c328SJustin Hibbits#define ADDR(x) \ 61e683c328SJustin Hibbits .llong x 6261b9e7efSJustin Hibbits#define WORD_SIZE 8 63e683c328SJustin Hibbits#else 64e683c328SJustin Hibbits#define GET_TOCBASE(r) 65e683c328SJustin Hibbits#define TOC_RESTORE 66e683c328SJustin Hibbits#define CMPI cmpwi 67e683c328SJustin Hibbits#define CMPL cmplw 68e683c328SJustin Hibbits#define LOAD lwz 69e683c328SJustin Hibbits#define LOADX lwarx 70e683c328SJustin Hibbits#define STOREX stwcx. 71e683c328SJustin Hibbits#define STORE stw 72e683c328SJustin Hibbits#define STU stwu 73e683c328SJustin Hibbits#define CALLSIZE 8 74e683c328SJustin Hibbits#define REDZONE 0 75e683c328SJustin Hibbits#define THREAD_REG %r2 76e683c328SJustin Hibbits#define ADDR(x) \ 77e683c328SJustin Hibbits .long x 7861b9e7efSJustin Hibbits#define WORD_SIZE 4 79e683c328SJustin Hibbits#endif 80e683c328SJustin Hibbits 81ab3f2a38SBrandon Bergren#ifdef __powerpc64__ 82ab3f2a38SBrandon Bergren /* Placate lld by creating a kboot stub. */ 83ab3f2a38SBrandon Bergren .section ".text.kboot", "x", @progbits 84ab3f2a38SBrandon Bergren b __start 85ab3f2a38SBrandon Bergren#endif 86ab3f2a38SBrandon Bergren 87dc9d1684SMarcel Moolenaar .text 88dc9d1684SMarcel Moolenaar .globl btext 89dc9d1684SMarcel Moolenaarbtext: 90dc9d1684SMarcel Moolenaar 916b7ba544SRafal Jaworowski/* 926b7ba544SRafal Jaworowski * This symbol is here for the benefit of kvm_mkdb, and is supposed to 936b7ba544SRafal Jaworowski * mark the start of kernel text. 946b7ba544SRafal Jaworowski */ 956b7ba544SRafal Jaworowski .globl kernel_text 966b7ba544SRafal Jaworowskikernel_text: 976b7ba544SRafal Jaworowski 986b7ba544SRafal Jaworowski/* 996b7ba544SRafal Jaworowski * Startup entry. Note, this must be the first thing in the text segment! 1006b7ba544SRafal Jaworowski */ 1016b7ba544SRafal Jaworowski .text 1026b7ba544SRafal Jaworowski .globl __start 1036b7ba544SRafal Jaworowski__start: 1046b7ba544SRafal Jaworowski 1056b7ba544SRafal Jaworowski/* 106fdd28cb8SRafal Jaworowski * Assumptions on the boot loader: 1077f7fcf55SJustin Hibbits * - System memory starts from physical address 0 1087f7fcf55SJustin Hibbits * - It's mapped by a single TLB1 entry 1096b7ba544SRafal Jaworowski * - TLB1 mapping is 1:1 pa to va 1107f7fcf55SJustin Hibbits * - Kernel is loaded at 64MB boundary 1117f7fcf55SJustin Hibbits * - All PID registers are set to the same value 112fdd28cb8SRafal Jaworowski * - CPU is running in AS=0 1136b7ba544SRafal Jaworowski * 114fdd28cb8SRafal Jaworowski * Registers contents provided by the loader(8): 1156b7ba544SRafal Jaworowski * r1 : stack pointer 1166b7ba544SRafal Jaworowski * r3 : metadata pointer 1176b7ba544SRafal Jaworowski * 1186b7ba544SRafal Jaworowski * We rearrange the TLB1 layout as follows: 1197f7fcf55SJustin Hibbits * - Find TLB1 entry we started in 1207f7fcf55SJustin Hibbits * - Make sure it's protected, invalidate other entries 1217f7fcf55SJustin Hibbits * - Create temp entry in the second AS (make sure it's not TLB[1]) 1227f7fcf55SJustin Hibbits * - Switch to temp mapping 1237f7fcf55SJustin Hibbits * - Map 64MB of RAM in TLB1[1] 124ea32838aSJustin Hibbits * - Use AS=0, set EPN to VM_MIN_KERNEL_ADDRESS and RPN to kernel load address 125caa7e52fSEitan Adler * - Switch to TLB1[1] mapping 1267f7fcf55SJustin Hibbits * - Invalidate temp mapping 1276b7ba544SRafal Jaworowski * 128fdd28cb8SRafal Jaworowski * locore registers use: 1296b7ba544SRafal Jaworowski * r1 : stack pointer 130fdd28cb8SRafal Jaworowski * r2 : trace pointer (AP only, for early diagnostics) 1312b5bf115SMarcel Moolenaar * r3-r27 : scratch registers 132ebf84cecSMarcel Moolenaar * r28 : temp TLB1 entry 133ebf84cecSMarcel Moolenaar * r29 : initial TLB1 entry we started in 134ebf84cecSMarcel Moolenaar * r30-r31 : arguments (metadata pointer) 1356b7ba544SRafal Jaworowski */ 1366b7ba544SRafal Jaworowski 1376b7ba544SRafal Jaworowski/* 138ebf84cecSMarcel Moolenaar * Keep arguments in r30 & r31 for later use. 1396b7ba544SRafal Jaworowski */ 140ebf84cecSMarcel Moolenaar mr %r30, %r3 141ebf84cecSMarcel Moolenaar mr %r31, %r4 1426b7ba544SRafal Jaworowski 1436b7ba544SRafal Jaworowski/* 1446b7ba544SRafal Jaworowski * Initial cleanup 1456b7ba544SRafal Jaworowski */ 146fdd28cb8SRafal Jaworowski li %r3, PSL_DE /* Keep debug exceptions for CodeWarrior. */ 147e683c328SJustin Hibbits#ifdef __powerpc64__ 148e683c328SJustin Hibbits oris %r3, %r3, PSL_CM@h 149e683c328SJustin Hibbits#endif 150fdd28cb8SRafal Jaworowski mtmsr %r3 1516b7ba544SRafal Jaworowski isync 1526b7ba544SRafal Jaworowski 153f60708c9SJustin Hibbits/* 154f60708c9SJustin Hibbits * Initial HIDs configuration 155f60708c9SJustin Hibbits */ 156f60708c9SJustin Hibbits1: 1577f7fcf55SJustin Hibbits mfpvr %r3 1587f7fcf55SJustin Hibbits rlwinm %r3, %r3, 16, 16, 31 1597f7fcf55SJustin Hibbits 1607f7fcf55SJustin Hibbits lis %r4, HID0_E500_DEFAULT_SET@h 1617f7fcf55SJustin Hibbits ori %r4, %r4, HID0_E500_DEFAULT_SET@l 1627f7fcf55SJustin Hibbits 1637f7fcf55SJustin Hibbits /* Check for e500mc and e5500 */ 1647f7fcf55SJustin Hibbits cmpli 0, 0, %r3, FSL_E500mc 1657f7fcf55SJustin Hibbits bne 2f 1667f7fcf55SJustin Hibbits 1677f7fcf55SJustin Hibbits lis %r4, HID0_E500MC_DEFAULT_SET@h 1687f7fcf55SJustin Hibbits ori %r4, %r4, HID0_E500MC_DEFAULT_SET@l 1697f7fcf55SJustin Hibbits b 3f 1707f7fcf55SJustin Hibbits2: 1717f7fcf55SJustin Hibbits cmpli 0, 0, %r3, FSL_E5500 1727f7fcf55SJustin Hibbits bne 3f 1737f7fcf55SJustin Hibbits 1747f7fcf55SJustin Hibbits lis %r4, HID0_E5500_DEFAULT_SET@h 1757f7fcf55SJustin Hibbits ori %r4, %r4, HID0_E5500_DEFAULT_SET@l 1767f7fcf55SJustin Hibbits 1777f7fcf55SJustin Hibbits3: 1787f7fcf55SJustin Hibbits mtspr SPR_HID0, %r4 179b9b8eb77SRafal Jaworowski isync 1807f7fcf55SJustin Hibbits 1817f7fcf55SJustin Hibbits/* 1827f7fcf55SJustin Hibbits * E500mc and E5500 do not have HID1 register, so skip HID1 setup on 1837f7fcf55SJustin Hibbits * this core. 1847f7fcf55SJustin Hibbits */ 1857f7fcf55SJustin Hibbits cmpli 0, 0, %r3, FSL_E500mc 1867f7fcf55SJustin Hibbits beq 1f 1877f7fcf55SJustin Hibbits cmpli 0, 0, %r3, FSL_E5500 1887f7fcf55SJustin Hibbits beq 1f 189beacb098SJustin Hibbits cmpli 0, 0, %r3, FSL_E6500 190beacb098SJustin Hibbits beq 1f 1917f7fcf55SJustin Hibbits 192b9b8eb77SRafal Jaworowski lis %r3, HID1_E500_DEFAULT_SET@h 193b9b8eb77SRafal Jaworowski ori %r3, %r3, HID1_E500_DEFAULT_SET@l 194b9b8eb77SRafal Jaworowski mtspr SPR_HID1, %r3 195b9b8eb77SRafal Jaworowski isync 1967f7fcf55SJustin Hibbits1: 197fdd28cb8SRafal Jaworowski /* Invalidate all entries in TLB0 */ 198fdd28cb8SRafal Jaworowski li %r3, 0 199fdd28cb8SRafal Jaworowski bl tlb_inval_all 2006b7ba544SRafal Jaworowski 2012b5bf115SMarcel Moolenaar cmpwi %r30, 0 2022b5bf115SMarcel Moolenaar beq done_mapping 2032b5bf115SMarcel Moolenaar 2046b7ba544SRafal Jaworowski/* 205fdd28cb8SRafal Jaworowski * Locate the TLB1 entry that maps this code 2066b7ba544SRafal Jaworowski */ 207fdd28cb8SRafal Jaworowski bl 1f 208fdd28cb8SRafal Jaworowski1: mflr %r3 209ebf84cecSMarcel Moolenaar bl tlb1_find_current /* the entry found is returned in r29 */ 2106b7ba544SRafal Jaworowski 211fdd28cb8SRafal Jaworowski bl tlb1_inval_all_but_current 2124a49da83SMarcel Moolenaar 2136b7ba544SRafal Jaworowski/* 214fdd28cb8SRafal Jaworowski * Create temporary mapping in AS=1 and switch to it 2156b7ba544SRafal Jaworowski */ 216fdd28cb8SRafal Jaworowski bl tlb1_temp_mapping_as1 2176b7ba544SRafal Jaworowski 218fdd28cb8SRafal Jaworowski mfmsr %r3 219fdd28cb8SRafal Jaworowski ori %r3, %r3, (PSL_IS | PSL_DS) 220fdd28cb8SRafal Jaworowski bl 2f 221fdd28cb8SRafal Jaworowski2: mflr %r4 222d071aa6dSJustin Hibbits addi %r4, %r4, (3f - 2b) 223fdd28cb8SRafal Jaworowski mtspr SPR_SRR0, %r4 224fdd28cb8SRafal Jaworowski mtspr SPR_SRR1, %r3 2256b7ba544SRafal Jaworowski rfi /* Switch context */ 2266b7ba544SRafal Jaworowski 2276b7ba544SRafal Jaworowski/* 2286b7ba544SRafal Jaworowski * Invalidate initial entry 2296b7ba544SRafal Jaworowski */ 230d071aa6dSJustin Hibbits3: 231ebf84cecSMarcel Moolenaar mr %r3, %r29 2326b7ba544SRafal Jaworowski bl tlb1_inval_entry 2336b7ba544SRafal Jaworowski 2346b7ba544SRafal Jaworowski/* 2356b7ba544SRafal Jaworowski * Setup final mapping in TLB1[1] and switch to it 2366b7ba544SRafal Jaworowski */ 2377f7fcf55SJustin Hibbits /* Final kernel mapping, map in 64 MB of RAM */ 238fdd28cb8SRafal Jaworowski lis %r3, MAS0_TLBSEL1@h /* Select TLB1 */ 2396a76463eSMarcel Moolenaar li %r4, 0 /* Entry 0 */ 2407f7fcf55SJustin Hibbits rlwimi %r3, %r4, 16, 10, 15 241fdd28cb8SRafal Jaworowski mtspr SPR_MAS0, %r3 2426b7ba544SRafal Jaworowski isync 2436b7ba544SRafal Jaworowski 244d2a406ddSNathan Whitehorn li %r3, (TLB_SIZE_64M << MAS1_TSIZE_SHIFT)@l 245fdd28cb8SRafal Jaworowski oris %r3, %r3, (MAS1_VALID | MAS1_IPROT)@h 246fdd28cb8SRafal Jaworowski mtspr SPR_MAS1, %r3 /* note TS was not filled, so it's TS=0 */ 2476b7ba544SRafal Jaworowski isync 2486b7ba544SRafal Jaworowski 249ea32838aSJustin Hibbits LOAD_ADDR(%r3, VM_MIN_KERNEL_ADDRESS) 250f60708c9SJustin Hibbits ori %r3, %r3, (_TLB_ENTRY_SHARED | MAS2_M)@l /* WIMGE = 0b00100 */ 251fdd28cb8SRafal Jaworowski mtspr SPR_MAS2, %r3 2526b7ba544SRafal Jaworowski isync 2536b7ba544SRafal Jaworowski 254fdd28cb8SRafal Jaworowski /* Discover phys load address */ 255fdd28cb8SRafal Jaworowski bl 3f 256fdd28cb8SRafal Jaworowski3: mflr %r4 /* Use current address */ 2577f7fcf55SJustin Hibbits rlwinm %r4, %r4, 0, 0, 5 /* 64MB alignment mask */ 258fdd28cb8SRafal Jaworowski ori %r4, %r4, (MAS3_SX | MAS3_SW | MAS3_SR)@l 259fdd28cb8SRafal Jaworowski mtspr SPR_MAS3, %r4 /* Set RPN and protection */ 2606b7ba544SRafal Jaworowski isync 2610af5d6f7SJustin Hibbits li %r4, 0 2620af5d6f7SJustin Hibbits mtspr SPR_MAS7, %r4 2635b4c63b7SJustin Hibbits isync 2646b7ba544SRafal Jaworowski tlbwe 2656b7ba544SRafal Jaworowski isync 2666b7ba544SRafal Jaworowski msync 2676b7ba544SRafal Jaworowski 2686b7ba544SRafal Jaworowski /* Switch to the above TLB1[1] mapping */ 269fdd28cb8SRafal Jaworowski bl 4f 270fdd28cb8SRafal Jaworowski4: mflr %r4 271e683c328SJustin Hibbits#ifdef __powerpc64__ 272e683c328SJustin Hibbits clrldi %r4, %r4, 38 273e683c328SJustin Hibbits clrrdi %r3, %r3, 12 274e683c328SJustin Hibbits#else 275e683c328SJustin Hibbits rlwinm %r4, %r4, 0, 6, 31 /* Current offset from kernel load address */ 276fdd28cb8SRafal Jaworowski rlwinm %r3, %r3, 0, 0, 19 277e683c328SJustin Hibbits#endif 278fdd28cb8SRafal Jaworowski add %r4, %r4, %r3 /* Convert to kernel virtual address */ 279d071aa6dSJustin Hibbits addi %r4, %r4, (5f - 4b) 280fdd28cb8SRafal Jaworowski li %r3, PSL_DE /* Note AS=0 */ 281e683c328SJustin Hibbits#ifdef __powerpc64__ 282e683c328SJustin Hibbits oris %r3, %r3, PSL_CM@h 283e683c328SJustin Hibbits#endif 284fdd28cb8SRafal Jaworowski mtspr SPR_SRR0, %r4 285fdd28cb8SRafal Jaworowski mtspr SPR_SRR1, %r3 2866b7ba544SRafal Jaworowski rfi 2876b7ba544SRafal Jaworowski 2886b7ba544SRafal Jaworowski/* 2896b7ba544SRafal Jaworowski * Invalidate temp mapping 2906b7ba544SRafal Jaworowski */ 291d071aa6dSJustin Hibbits5: 292ebf84cecSMarcel Moolenaar mr %r3, %r28 2936b7ba544SRafal Jaworowski bl tlb1_inval_entry 2946b7ba544SRafal Jaworowski 2952b5bf115SMarcel Moolenaardone_mapping: 296fdd28cb8SRafal Jaworowski 297e683c328SJustin Hibbits#ifdef __powerpc64__ 298e683c328SJustin Hibbits /* Set up the TOC pointer */ 299e683c328SJustin Hibbits b 0f 300e683c328SJustin Hibbits .align 3 301e683c328SJustin Hibbits0: nop 302e683c328SJustin Hibbits bl 1f 303e683c328SJustin Hibbits .llong __tocbase + 0x8000 - . 304e683c328SJustin Hibbits1: mflr %r2 305e683c328SJustin Hibbits ld %r1,0(%r2) 306e683c328SJustin Hibbits add %r2,%r1,%r2 307e683c328SJustin Hibbits mtspr SPR_SPRG8, %r2 30869cea06fSJustin Hibbits nop 309e683c328SJustin Hibbits 310e683c328SJustin Hibbits /* Get load offset */ 311e683c328SJustin Hibbits ld %r31,-0x8000(%r2) /* First TOC entry is TOC base */ 312e683c328SJustin Hibbits subf %r31,%r31,%r2 /* Subtract from real TOC base to get base */ 313e683c328SJustin Hibbits 314e683c328SJustin Hibbits /* Set up the stack pointer */ 31569cea06fSJustin Hibbits bl 1f 31669cea06fSJustin Hibbits .llong tmpstack + TMPSTACKSZ - 96 - . 31769cea06fSJustin Hibbits1: mflr %r3 31869cea06fSJustin Hibbits ld %r1,0(%r3) 31969cea06fSJustin Hibbits add %r1,%r1,%r3 320ab3f2a38SBrandon Bergren/* 321ab3f2a38SBrandon Bergren * Relocate kernel 322ab3f2a38SBrandon Bergren */ 323e683c328SJustin Hibbits bl 1f 324e683c328SJustin Hibbits .llong _DYNAMIC-. 325e683c328SJustin Hibbits1: mflr %r3 326e683c328SJustin Hibbits ld %r4,0(%r3) 327e683c328SJustin Hibbits add %r3,%r4,%r3 328e683c328SJustin Hibbits mr %r4,%r31 329e683c328SJustin Hibbits#else 330fdd28cb8SRafal Jaworowski/* 3316b7ba544SRafal Jaworowski * Setup a temporary stack 3326b7ba544SRafal Jaworowski */ 3335c845fdeSNathan Whitehorn bl 1f 3345c845fdeSNathan Whitehorn .long tmpstack-. 3355c845fdeSNathan Whitehorn1: mflr %r1 3365c845fdeSNathan Whitehorn lwz %r2,0(%r1) 3375c845fdeSNathan Whitehorn add %r1,%r1,%r2 338bb808254SNathan Whitehorn addi %r1, %r1, (TMPSTACKSZ - 16) 3396b7ba544SRafal Jaworowski 3406b7ba544SRafal Jaworowski/* 3415c845fdeSNathan Whitehorn * Relocate kernel 3425c845fdeSNathan Whitehorn */ 3435c845fdeSNathan Whitehorn bl 1f 3445c845fdeSNathan Whitehorn .long _DYNAMIC-. 3455c845fdeSNathan Whitehorn .long _GLOBAL_OFFSET_TABLE_-. 3465c845fdeSNathan Whitehorn1: mflr %r5 3475c845fdeSNathan Whitehorn lwz %r3,0(%r5) /* _DYNAMIC in %r3 */ 3485c845fdeSNathan Whitehorn add %r3,%r3,%r5 3495c845fdeSNathan Whitehorn lwz %r4,4(%r5) /* GOT pointer */ 3505c845fdeSNathan Whitehorn add %r4,%r4,%r5 3515c845fdeSNathan Whitehorn lwz %r4,4(%r4) /* got[0] is _DYNAMIC link addr */ 3525c845fdeSNathan Whitehorn subf %r4,%r4,%r3 /* subtract to calculate relocbase */ 353e683c328SJustin Hibbits#endif 354e683c328SJustin Hibbits bl CNAME(elf_reloc_self) 355e683c328SJustin Hibbits TOC_RESTORE 3565c845fdeSNathan Whitehorn 3575c845fdeSNathan Whitehorn/* 358f01415c3SRafal Jaworowski * Initialise exception vector offsets 3596b7ba544SRafal Jaworowski */ 360e683c328SJustin Hibbits bl CNAME(ivor_setup) 361e683c328SJustin Hibbits TOC_RESTORE 3626b7ba544SRafal Jaworowski 3636b7ba544SRafal Jaworowski/* 364fdd28cb8SRafal Jaworowski * Set up arguments and jump to system initialization code 3656b7ba544SRafal Jaworowski */ 366ebf84cecSMarcel Moolenaar mr %r3, %r30 367ebf84cecSMarcel Moolenaar mr %r4, %r31 3686b7ba544SRafal Jaworowski 36917f4cae4SRafal Jaworowski /* Prepare core */ 370e683c328SJustin Hibbits bl CNAME(booke_init) 371e683c328SJustin Hibbits TOC_RESTORE 372959aea56SRafal Jaworowski 373fdd28cb8SRafal Jaworowski /* Switch to thread0.td_kstack now */ 374959aea56SRafal Jaworowski mr %r1, %r3 375959aea56SRafal Jaworowski li %r3, 0 376e683c328SJustin Hibbits STORE %r3, 0(%r1) 377959aea56SRafal Jaworowski 378fdd28cb8SRafal Jaworowski /* Machine independet part, does not return */ 379e683c328SJustin Hibbits bl CNAME(mi_startup) 380e683c328SJustin Hibbits TOC_RESTORE 381fdd28cb8SRafal Jaworowski /* NOT REACHED */ 382fdd28cb8SRafal Jaworowski5: b 5b 3836b7ba544SRafal Jaworowski 38428bb01e5SRafal Jaworowski 38528bb01e5SRafal Jaworowski#ifdef SMP 38628bb01e5SRafal Jaworowski/************************************************************************/ 38728bb01e5SRafal Jaworowski/* AP Boot page */ 38828bb01e5SRafal Jaworowski/************************************************************************/ 38928bb01e5SRafal Jaworowski .text 39028bb01e5SRafal Jaworowski .globl __boot_page 39128bb01e5SRafal Jaworowski .align 12 39228bb01e5SRafal Jaworowski__boot_page: 393ab3f2a38SBrandon Bergren /* 394ab3f2a38SBrandon Bergren * The boot page is a special page of memory used during AP bringup. 395ab3f2a38SBrandon Bergren * Before the AP comes out of reset, the physical 4K page holding this 396ab3f2a38SBrandon Bergren * code is arranged to be mapped at 0xfffff000 by use of 397ab3f2a38SBrandon Bergren * platform-dependent registers. 398ab3f2a38SBrandon Bergren * 399ab3f2a38SBrandon Bergren * Alternatively, this page may be executed using an ePAPR-standardized 400ab3f2a38SBrandon Bergren * method -- writing to the address specified in "cpu-release-addr". 401ab3f2a38SBrandon Bergren * 402ab3f2a38SBrandon Bergren * In either case, execution begins at the last instruction of the 403ab3f2a38SBrandon Bergren * page, which is a branch back to the start of the page. 404ab3f2a38SBrandon Bergren * 405ab3f2a38SBrandon Bergren * The code in the page must do initial MMU setup and normalize the 406ab3f2a38SBrandon Bergren * TLBs for regular operation in the correct address space before 407ab3f2a38SBrandon Bergren * reading outside the page. 408ab3f2a38SBrandon Bergren * 409ab3f2a38SBrandon Bergren * This implementation accomplishes this by: 410ab3f2a38SBrandon Bergren * 1) Wiping TLB0 and all TLB1 entries but the one currently in use. 411ab3f2a38SBrandon Bergren * 2) Establishing a temporary 4K TLB1 mapping in AS=1, and switching 412ab3f2a38SBrandon Bergren * to it with rfi. This entry must NOT be in TLB1 slot 0. 413ab3f2a38SBrandon Bergren * (This is needed to give the code freedom to clean up AS=0.) 414ab3f2a38SBrandon Bergren * 3) Removing the initial TLB1 entry, leaving us with a single valid 415ab3f2a38SBrandon Bergren * TLB1 entry, NOT in slot 0. 416ab3f2a38SBrandon Bergren * 4) Installing an AS0 entry in TLB1 slot 0 mapping the 64MB kernel 417ab3f2a38SBrandon Bergren * segment at its final virtual address. A second rfi is done to 418ab3f2a38SBrandon Bergren * switch to the final address space. At this point we can finally 419ab3f2a38SBrandon Bergren * access the rest of the kernel segment safely. 420ab3f2a38SBrandon Bergren * 5) The temporary TLB1 AS=1 entry is removed, finally leaving us in 421ab3f2a38SBrandon Bergren * a consistent (but minimal) state. 422ab3f2a38SBrandon Bergren * 6) Set up TOC, stack, and pcpu registers. 423ab3f2a38SBrandon Bergren * 7) Now that we can finally call C code, call pmap_boostrap_ap(), 424ab3f2a38SBrandon Bergren * which finishes copying in the shared TLB1 entries. 425ab3f2a38SBrandon Bergren * 426ab3f2a38SBrandon Bergren * At this point, the MMU is fully set up, and we can proceed with 427ab3f2a38SBrandon Bergren * running the actual AP bootstrap code. 428ab3f2a38SBrandon Bergren * 429ab3f2a38SBrandon Bergren * Pieces of this code are also used for UP kernel, but in this case 430ab3f2a38SBrandon Bergren * the sections specific to boot page functionality are dropped by 431ab3f2a38SBrandon Bergren * the preprocessor. 432ab3f2a38SBrandon Bergren */ 433ab3f2a38SBrandon Bergren#ifdef __powerpc64__ 434ab3f2a38SBrandon Bergren nop /* PPC64 alignment word. 64-bit target. */ 435ab3f2a38SBrandon Bergren#endif 436ab3f2a38SBrandon Bergren bl 1f /* 32-bit target. */ 43728bb01e5SRafal Jaworowski 438f60708c9SJustin Hibbits .globl bp_trace 439f60708c9SJustin Hibbitsbp_trace: 440ab3f2a38SBrandon Bergren ADDR(0) /* Trace pointer (%r31). */ 441a45d9127SMarcel Moolenaar 442f60708c9SJustin Hibbits .globl bp_kernload 443f60708c9SJustin Hibbitsbp_kernload: 4444160ed6fSJustin Hibbits .llong 0 /* Kern phys. load address. */ 445ab3f2a38SBrandon Bergren 446ab3f2a38SBrandon Bergren .globl bp_virtaddr 447ab3f2a38SBrandon Bergrenbp_virtaddr: 448ab3f2a38SBrandon Bergren ADDR(0) /* Virt. address of __boot_page. */ 44928bb01e5SRafal Jaworowski 45028bb01e5SRafal Jaworowski/* 45128bb01e5SRafal Jaworowski * Initial configuration 45228bb01e5SRafal Jaworowski */ 453f60708c9SJustin Hibbits1: 454f60708c9SJustin Hibbits mflr %r31 /* r31 hold the address of bp_trace */ 455a45d9127SMarcel Moolenaar 45628bb01e5SRafal Jaworowski /* Set HIDs */ 4577f7fcf55SJustin Hibbits mfpvr %r3 4587f7fcf55SJustin Hibbits rlwinm %r3, %r3, 16, 16, 31 4597f7fcf55SJustin Hibbits 4607f7fcf55SJustin Hibbits /* HID0 for E500 is default */ 4617f7fcf55SJustin Hibbits lis %r4, HID0_E500_DEFAULT_SET@h 4627f7fcf55SJustin Hibbits ori %r4, %r4, HID0_E500_DEFAULT_SET@l 4637f7fcf55SJustin Hibbits 4647f7fcf55SJustin Hibbits cmpli 0, 0, %r3, FSL_E500mc 4657f7fcf55SJustin Hibbits bne 2f 4667f7fcf55SJustin Hibbits lis %r4, HID0_E500MC_DEFAULT_SET@h 4677f7fcf55SJustin Hibbits ori %r4, %r4, HID0_E500MC_DEFAULT_SET@l 4687f7fcf55SJustin Hibbits b 3f 4697f7fcf55SJustin Hibbits2: 4707f7fcf55SJustin Hibbits cmpli 0, 0, %r3, FSL_E5500 4717f7fcf55SJustin Hibbits bne 3f 4727f7fcf55SJustin Hibbits lis %r4, HID0_E5500_DEFAULT_SET@h 4737f7fcf55SJustin Hibbits ori %r4, %r4, HID0_E5500_DEFAULT_SET@l 4747f7fcf55SJustin Hibbits3: 4757f7fcf55SJustin Hibbits mtspr SPR_HID0, %r4 47628bb01e5SRafal Jaworowski isync 4777f7fcf55SJustin Hibbits 47828bb01e5SRafal Jaworowski /* Enable branch prediction */ 47928bb01e5SRafal Jaworowski li %r3, BUCSR_BPEN 48028bb01e5SRafal Jaworowski mtspr SPR_BUCSR, %r3 48128bb01e5SRafal Jaworowski isync 48228bb01e5SRafal Jaworowski 48328bb01e5SRafal Jaworowski /* Invalidate all entries in TLB0 */ 48428bb01e5SRafal Jaworowski li %r3, 0 48528bb01e5SRafal Jaworowski bl tlb_inval_all 48628bb01e5SRafal Jaworowski 48728bb01e5SRafal Jaworowski/* 48828bb01e5SRafal Jaworowski * Find TLB1 entry which is translating us now 48928bb01e5SRafal Jaworowski */ 49028bb01e5SRafal Jaworowski bl 2f 49128bb01e5SRafal Jaworowski2: mflr %r3 492ebf84cecSMarcel Moolenaar bl tlb1_find_current /* the entry number found is in r29 */ 49328bb01e5SRafal Jaworowski 49428bb01e5SRafal Jaworowski bl tlb1_inval_all_but_current 4954a49da83SMarcel Moolenaar 49628bb01e5SRafal Jaworowski/* 49728bb01e5SRafal Jaworowski * Create temporary translation in AS=1 and switch to it 49828bb01e5SRafal Jaworowski */ 499f60708c9SJustin Hibbits 50028bb01e5SRafal Jaworowski bl tlb1_temp_mapping_as1 50128bb01e5SRafal Jaworowski 50228bb01e5SRafal Jaworowski mfmsr %r3 50328bb01e5SRafal Jaworowski ori %r3, %r3, (PSL_IS | PSL_DS) 504e683c328SJustin Hibbits#ifdef __powerpc64__ 505ab3f2a38SBrandon Bergren oris %r3, %r3, PSL_CM@h /* Ensure we're in 64-bit after RFI */ 506e683c328SJustin Hibbits#endif 50728bb01e5SRafal Jaworowski bl 3f 50828bb01e5SRafal Jaworowski3: mflr %r4 509d071aa6dSJustin Hibbits addi %r4, %r4, (4f - 3b) 51028bb01e5SRafal Jaworowski mtspr SPR_SRR0, %r4 51128bb01e5SRafal Jaworowski mtspr SPR_SRR1, %r3 51228bb01e5SRafal Jaworowski rfi /* Switch context */ 51328bb01e5SRafal Jaworowski 51428bb01e5SRafal Jaworowski/* 51528bb01e5SRafal Jaworowski * Invalidate initial entry 51628bb01e5SRafal Jaworowski */ 517d071aa6dSJustin Hibbits4: 518ebf84cecSMarcel Moolenaar mr %r3, %r29 51928bb01e5SRafal Jaworowski bl tlb1_inval_entry 52028bb01e5SRafal Jaworowski 52128bb01e5SRafal Jaworowski/* 522ab3f2a38SBrandon Bergren * Setup final mapping in TLB1[0] and switch to it 52328bb01e5SRafal Jaworowski */ 524f60708c9SJustin Hibbits /* Final kernel mapping, map in 64 MB of RAM */ 525f60708c9SJustin Hibbits lis %r3, MAS0_TLBSEL1@h /* Select TLB1 */ 526f60708c9SJustin Hibbits li %r4, 0 /* Entry 0 */ 527f60708c9SJustin Hibbits rlwimi %r3, %r4, 16, 4, 15 52828bb01e5SRafal Jaworowski mtspr SPR_MAS0, %r3 52928bb01e5SRafal Jaworowski isync 530f60708c9SJustin Hibbits 531f60708c9SJustin Hibbits li %r3, (TLB_SIZE_64M << MAS1_TSIZE_SHIFT)@l 532f60708c9SJustin Hibbits oris %r3, %r3, (MAS1_VALID | MAS1_IPROT)@h 533f60708c9SJustin Hibbits mtspr SPR_MAS1, %r3 /* note TS was not filled, so it's TS=0 */ 53428bb01e5SRafal Jaworowski isync 535f60708c9SJustin Hibbits 536ea32838aSJustin Hibbits LOAD_ADDR(%r3, VM_MIN_KERNEL_ADDRESS) 537f60708c9SJustin Hibbits ori %r3, %r3, (_TLB_ENTRY_SHARED | MAS2_M)@l /* WIMGE = 0b00100 */ 53828bb01e5SRafal Jaworowski mtspr SPR_MAS2, %r3 53928bb01e5SRafal Jaworowski isync 540f60708c9SJustin Hibbits 541f60708c9SJustin Hibbits /* Retrieve kernel load [physical] address from bp_kernload */ 542ab3f2a38SBrandon Bergren5: 543ab3f2a38SBrandon Bergren mflr %r3 544e683c328SJustin Hibbits#ifdef __powerpc64__ 545ab3f2a38SBrandon Bergren clrrdi %r3, %r3, PAGE_SHIFT /* trunc_page(%r3) */ 546e683c328SJustin Hibbits#else 547ab3f2a38SBrandon Bergren clrrwi %r3, %r3, PAGE_SHIFT /* trunc_page(%r3) */ 548e683c328SJustin Hibbits#endif 5494160ed6fSJustin Hibbits /* Load lower half of the kernel loadaddr. */ 5504160ed6fSJustin Hibbits lwz %r4, (bp_kernload - __boot_page + 4)(%r3) 551ab3f2a38SBrandon Bergren LOAD %r5, (bp_virtaddr - __boot_page)(%r3) 552f60708c9SJustin Hibbits 553f60708c9SJustin Hibbits /* Set RPN and protection */ 554ab3f2a38SBrandon Bergren ori %r4, %r4, (MAS3_SX | MAS3_SW | MAS3_SR)@l 555ab3f2a38SBrandon Bergren mtspr SPR_MAS3, %r4 55628bb01e5SRafal Jaworowski isync 5574160ed6fSJustin Hibbits lwz %r4, (bp_kernload - __boot_page)(%r3) 5580af5d6f7SJustin Hibbits mtspr SPR_MAS7, %r4 5595b4c63b7SJustin Hibbits isync 56028bb01e5SRafal Jaworowski tlbwe 56128bb01e5SRafal Jaworowski isync 56228bb01e5SRafal Jaworowski msync 56328bb01e5SRafal Jaworowski 56428bb01e5SRafal Jaworowski /* Switch to the final mapping */ 565d071aa6dSJustin Hibbits bl 6f 566d071aa6dSJustin Hibbits6: mflr %r3 56728bb01e5SRafal Jaworowski rlwinm %r3, %r3, 0, 0xfff /* Offset from boot page start */ 568ab3f2a38SBrandon Bergren add %r3, %r3, %r5 /* Make this a virtual address */ 569ab3f2a38SBrandon Bergren addi %r3, %r3, (7f - 6b) /* And figure out return address. */ 570e683c328SJustin Hibbits#ifdef __powerpc64__ 571e683c328SJustin Hibbits lis %r4, PSL_CM@h /* Note AS=0 */ 572e683c328SJustin Hibbits#else 57328bb01e5SRafal Jaworowski li %r4, 0 /* Note AS=0 */ 574e683c328SJustin Hibbits#endif 57528bb01e5SRafal Jaworowski mtspr SPR_SRR0, %r3 57628bb01e5SRafal Jaworowski mtspr SPR_SRR1, %r4 57728bb01e5SRafal Jaworowski rfi 578d071aa6dSJustin Hibbits7: 57928bb01e5SRafal Jaworowski 58028bb01e5SRafal Jaworowski/* 581ea32838aSJustin Hibbits * At this point we're running at virtual addresses VM_MIN_KERNEL_ADDRESS and 582ea32838aSJustin Hibbits * beyond so it's allowed to directly access all locations the kernel was linked 58328bb01e5SRafal Jaworowski * against. 58428bb01e5SRafal Jaworowski */ 58528bb01e5SRafal Jaworowski 58628bb01e5SRafal Jaworowski/* 58728bb01e5SRafal Jaworowski * Invalidate temp mapping 58828bb01e5SRafal Jaworowski */ 589ebf84cecSMarcel Moolenaar mr %r3, %r28 59028bb01e5SRafal Jaworowski bl tlb1_inval_entry 59128bb01e5SRafal Jaworowski 592e683c328SJustin Hibbits#ifdef __powerpc64__ 593e683c328SJustin Hibbits /* Set up the TOC pointer */ 594e683c328SJustin Hibbits b 0f 595e683c328SJustin Hibbits .align 3 596e683c328SJustin Hibbits0: nop 597e683c328SJustin Hibbits bl 1f 598e683c328SJustin Hibbits .llong __tocbase + 0x8000 - . 599e683c328SJustin Hibbits1: mflr %r2 600e683c328SJustin Hibbits ld %r1,0(%r2) 601e683c328SJustin Hibbits add %r2,%r1,%r2 602e683c328SJustin Hibbits mtspr SPR_SPRG8, %r2 603e683c328SJustin Hibbits 604e683c328SJustin Hibbits /* Set up the stack pointer */ 6050499e9c6SJustin Hibbits addis %r1,%r2,TOC_REF(tmpstack)@ha 6060499e9c6SJustin Hibbits ld %r1,TOC_REF(tmpstack)@l(%r1) 607e683c328SJustin Hibbits addi %r1,%r1,TMPSTACKSZ-96 608e683c328SJustin Hibbits#else 60928bb01e5SRafal Jaworowski/* 61028bb01e5SRafal Jaworowski * Setup a temporary stack 61128bb01e5SRafal Jaworowski */ 6125c845fdeSNathan Whitehorn bl 1f 6135c845fdeSNathan Whitehorn .long tmpstack-. 6145c845fdeSNathan Whitehorn1: mflr %r1 6155c845fdeSNathan Whitehorn lwz %r2,0(%r1) 6165c845fdeSNathan Whitehorn add %r1,%r1,%r2 617f60708c9SJustin Hibbits stw %r1, 0(%r1) 618bb808254SNathan Whitehorn addi %r1, %r1, (TMPSTACKSZ - 16) 619e683c328SJustin Hibbits#endif 62028bb01e5SRafal Jaworowski 62128bb01e5SRafal Jaworowski/* 62228bb01e5SRafal Jaworowski * Initialise exception vector offsets 62328bb01e5SRafal Jaworowski */ 624e683c328SJustin Hibbits bl CNAME(ivor_setup) 625e683c328SJustin Hibbits TOC_RESTORE 62628bb01e5SRafal Jaworowski 62728bb01e5SRafal Jaworowski /* 62828bb01e5SRafal Jaworowski * Assign our pcpu instance 62928bb01e5SRafal Jaworowski */ 6305c845fdeSNathan Whitehorn bl 1f 6315c845fdeSNathan Whitehorn .long ap_pcpu-. 6325c845fdeSNathan Whitehorn1: mflr %r4 6335c845fdeSNathan Whitehorn lwz %r3, 0(%r4) 6345c845fdeSNathan Whitehorn add %r3, %r3, %r4 635e683c328SJustin Hibbits LOAD %r3, 0(%r3) 63628bb01e5SRafal Jaworowski mtsprg0 %r3 63728bb01e5SRafal Jaworowski 638e683c328SJustin Hibbits bl CNAME(pmap_bootstrap_ap) 639e683c328SJustin Hibbits TOC_RESTORE 64028bb01e5SRafal Jaworowski 641e683c328SJustin Hibbits bl CNAME(cpudep_ap_bootstrap) 642e683c328SJustin Hibbits TOC_RESTORE 64328bb01e5SRafal Jaworowski /* Switch to the idle thread's kstack */ 64428bb01e5SRafal Jaworowski mr %r1, %r3 64528bb01e5SRafal Jaworowski 646e683c328SJustin Hibbits bl CNAME(machdep_ap_bootstrap) 647e683c328SJustin Hibbits TOC_RESTORE 64828bb01e5SRafal Jaworowski 64928bb01e5SRafal Jaworowski /* NOT REACHED */ 65028bb01e5SRafal Jaworowski6: b 6b 65128bb01e5SRafal Jaworowski#endif /* SMP */ 65228bb01e5SRafal Jaworowski 653f60708c9SJustin Hibbits#if defined (BOOKE_E500) 654fdd28cb8SRafal Jaworowski/* 655fdd28cb8SRafal Jaworowski * Invalidate all entries in the given TLB. 656fdd28cb8SRafal Jaworowski * 657fdd28cb8SRafal Jaworowski * r3 TLBSEL 658fdd28cb8SRafal Jaworowski */ 659fdd28cb8SRafal Jaworowskitlb_inval_all: 6607f7fcf55SJustin Hibbits rlwinm %r3, %r3, 3, (1 << 3) /* TLBSEL */ 6617f7fcf55SJustin Hibbits ori %r3, %r3, (1 << 2) /* INVALL */ 662fdd28cb8SRafal Jaworowski tlbivax 0, %r3 6636b7ba544SRafal Jaworowski isync 664fdd28cb8SRafal Jaworowski msync 6656b7ba544SRafal Jaworowski 666fdd28cb8SRafal Jaworowski tlbsync 667fdd28cb8SRafal Jaworowski msync 668fdd28cb8SRafal Jaworowski blr 669fdd28cb8SRafal Jaworowski 670fdd28cb8SRafal Jaworowski/* 671ebf84cecSMarcel Moolenaar * expects address to look up in r3, returns entry number in r29 672fdd28cb8SRafal Jaworowski * 673fdd28cb8SRafal Jaworowski * FIXME: the hidden assumption is we are now running in AS=0, but we should 674fdd28cb8SRafal Jaworowski * retrieve actual AS from MSR[IS|DS] and put it in MAS6[SAS] 675fdd28cb8SRafal Jaworowski */ 676fdd28cb8SRafal Jaworowskitlb1_find_current: 677fdd28cb8SRafal Jaworowski mfspr %r17, SPR_PID0 678fdd28cb8SRafal Jaworowski slwi %r17, %r17, MAS6_SPID0_SHIFT 679fdd28cb8SRafal Jaworowski mtspr SPR_MAS6, %r17 680fdd28cb8SRafal Jaworowski isync 681fdd28cb8SRafal Jaworowski tlbsx 0, %r3 682fdd28cb8SRafal Jaworowski mfspr %r17, SPR_MAS0 683f60708c9SJustin Hibbits rlwinm %r29, %r17, 16, 26, 31 /* MAS0[ESEL] -> r29 */ 684fdd28cb8SRafal Jaworowski 685fdd28cb8SRafal Jaworowski /* Make sure we have IPROT set on the entry */ 686fdd28cb8SRafal Jaworowski mfspr %r17, SPR_MAS1 687fdd28cb8SRafal Jaworowski oris %r17, %r17, MAS1_IPROT@h 688fdd28cb8SRafal Jaworowski mtspr SPR_MAS1, %r17 6896b7ba544SRafal Jaworowski isync 6906b7ba544SRafal Jaworowski tlbwe 6916b7ba544SRafal Jaworowski isync 6926b7ba544SRafal Jaworowski msync 6936b7ba544SRafal Jaworowski blr 6946b7ba544SRafal Jaworowski 695fdd28cb8SRafal Jaworowski/* 696fdd28cb8SRafal Jaworowski * Invalidates a single entry in TLB1. 697fdd28cb8SRafal Jaworowski * 698fdd28cb8SRafal Jaworowski * r3 ESEL 699fdd28cb8SRafal Jaworowski * r4-r5 scratched 700fdd28cb8SRafal Jaworowski */ 701fdd28cb8SRafal Jaworowskitlb1_inval_entry: 702fdd28cb8SRafal Jaworowski lis %r4, MAS0_TLBSEL1@h /* Select TLB1 */ 7037f7fcf55SJustin Hibbits rlwimi %r4, %r3, 16, 10, 15 /* Select our entry */ 704fdd28cb8SRafal Jaworowski mtspr SPR_MAS0, %r4 705fdd28cb8SRafal Jaworowski isync 706fdd28cb8SRafal Jaworowski tlbre 707fdd28cb8SRafal Jaworowski li %r5, 0 /* MAS1[V] = 0 */ 708fdd28cb8SRafal Jaworowski mtspr SPR_MAS1, %r5 709fdd28cb8SRafal Jaworowski isync 710fdd28cb8SRafal Jaworowski tlbwe 711fdd28cb8SRafal Jaworowski isync 712fdd28cb8SRafal Jaworowski msync 713fdd28cb8SRafal Jaworowski blr 714fdd28cb8SRafal Jaworowski 715fdd28cb8SRafal Jaworowski/* 716f60708c9SJustin Hibbits * r29 current entry number 717f60708c9SJustin Hibbits * r28 returned temp entry 718f60708c9SJustin Hibbits * r3-r5 scratched 719fdd28cb8SRafal Jaworowski */ 720fdd28cb8SRafal Jaworowskitlb1_temp_mapping_as1: 721fdd28cb8SRafal Jaworowski /* Read our current translation */ 722fdd28cb8SRafal Jaworowski lis %r3, MAS0_TLBSEL1@h /* Select TLB1 */ 7237f7fcf55SJustin Hibbits rlwimi %r3, %r29, 16, 10, 15 /* Select our current entry */ 724fdd28cb8SRafal Jaworowski mtspr SPR_MAS0, %r3 725fdd28cb8SRafal Jaworowski isync 726fdd28cb8SRafal Jaworowski tlbre 727fdd28cb8SRafal Jaworowski 728f60708c9SJustin Hibbits /* 729f60708c9SJustin Hibbits * Prepare and write temp entry 730f60708c9SJustin Hibbits * 731f60708c9SJustin Hibbits * FIXME this is not robust against overflow i.e. when the current 732f60708c9SJustin Hibbits * entry is the last in TLB1 733f60708c9SJustin Hibbits */ 734fdd28cb8SRafal Jaworowski lis %r3, MAS0_TLBSEL1@h /* Select TLB1 */ 735f60708c9SJustin Hibbits addi %r28, %r29, 1 /* Use next entry. */ 7367f7fcf55SJustin Hibbits rlwimi %r3, %r28, 16, 10, 15 /* Select temp entry */ 737fdd28cb8SRafal Jaworowski mtspr SPR_MAS0, %r3 738fdd28cb8SRafal Jaworowski isync 739fdd28cb8SRafal Jaworowski mfspr %r5, SPR_MAS1 740fdd28cb8SRafal Jaworowski li %r4, 1 /* AS=1 */ 741fdd28cb8SRafal Jaworowski rlwimi %r5, %r4, 12, 19, 19 742fdd28cb8SRafal Jaworowski li %r4, 0 /* Global mapping, TID=0 */ 743fdd28cb8SRafal Jaworowski rlwimi %r5, %r4, 16, 8, 15 744fdd28cb8SRafal Jaworowski oris %r5, %r5, (MAS1_VALID | MAS1_IPROT)@h 745fdd28cb8SRafal Jaworowski mtspr SPR_MAS1, %r5 746fdd28cb8SRafal Jaworowski isync 7477f7fcf55SJustin Hibbits mflr %r3 7480af5d6f7SJustin Hibbits li %r4, 0 7490af5d6f7SJustin Hibbits mtspr SPR_MAS7, %r4 7507f7fcf55SJustin Hibbits mtlr %r3 7515b4c63b7SJustin Hibbits isync 752fdd28cb8SRafal Jaworowski tlbwe 753fdd28cb8SRafal Jaworowski isync 754fdd28cb8SRafal Jaworowski msync 755fdd28cb8SRafal Jaworowski blr 756fdd28cb8SRafal Jaworowski 757fdd28cb8SRafal Jaworowski/* 758fdd28cb8SRafal Jaworowski * Loops over TLB1, invalidates all entries skipping the one which currently 759fdd28cb8SRafal Jaworowski * maps this code. 760fdd28cb8SRafal Jaworowski * 761ebf84cecSMarcel Moolenaar * r29 current entry 762fdd28cb8SRafal Jaworowski * r3-r5 scratched 763fdd28cb8SRafal Jaworowski */ 764fdd28cb8SRafal Jaworowskitlb1_inval_all_but_current: 765fdd28cb8SRafal Jaworowski mfspr %r3, SPR_TLB1CFG /* Get number of entries */ 766fdd28cb8SRafal Jaworowski andi. %r3, %r3, TLBCFG_NENTRY_MASK@l 767fdd28cb8SRafal Jaworowski li %r4, 0 /* Start from Entry 0 */ 768fdd28cb8SRafal Jaworowski1: lis %r5, MAS0_TLBSEL1@h 7697f7fcf55SJustin Hibbits rlwimi %r5, %r4, 16, 10, 15 770fdd28cb8SRafal Jaworowski mtspr SPR_MAS0, %r5 771fdd28cb8SRafal Jaworowski isync 772fdd28cb8SRafal Jaworowski tlbre 773fdd28cb8SRafal Jaworowski mfspr %r5, SPR_MAS1 774ebf84cecSMarcel Moolenaar cmpw %r4, %r29 /* our current entry? */ 775fdd28cb8SRafal Jaworowski beq 2f 776fdd28cb8SRafal Jaworowski rlwinm %r5, %r5, 0, 2, 31 /* clear VALID and IPROT bits */ 777fdd28cb8SRafal Jaworowski mtspr SPR_MAS1, %r5 778fdd28cb8SRafal Jaworowski isync 779fdd28cb8SRafal Jaworowski tlbwe 780fdd28cb8SRafal Jaworowski isync 781fdd28cb8SRafal Jaworowski msync 782fdd28cb8SRafal Jaworowski2: addi %r4, %r4, 1 783fdd28cb8SRafal Jaworowski cmpw %r4, %r3 /* Check if this is the last entry */ 784fdd28cb8SRafal Jaworowski bne 1b 785fdd28cb8SRafal Jaworowski blr 786f60708c9SJustin Hibbits#endif 7877f7fcf55SJustin Hibbits 78828bb01e5SRafal Jaworowski#ifdef SMP 789f60708c9SJustin Hibbits.globl __boot_tlb1 790f60708c9SJustin Hibbits /* 791f60708c9SJustin Hibbits * The __boot_tlb1 table is used to hold BSP TLB1 entries 792f60708c9SJustin Hibbits * marked with _TLB_ENTRY_SHARED flag during AP bootstrap. 793f60708c9SJustin Hibbits * The BSP fills in the table in tlb_ap_prep() function. Next, 794f60708c9SJustin Hibbits * AP loads its contents to TLB1 hardware in pmap_bootstrap_ap(). 795f60708c9SJustin Hibbits */ 796f60708c9SJustin Hibbits__boot_tlb1: 797f60708c9SJustin Hibbits .space TLB1_MAX_ENTRIES * TLB_ENTRY_SIZE 798f60708c9SJustin Hibbits 79928bb01e5SRafal Jaworowski__boot_page_padding: 80028bb01e5SRafal Jaworowski /* 80128bb01e5SRafal Jaworowski * Boot page needs to be exactly 4K, with the last word of this page 80228bb01e5SRafal Jaworowski * acting as the reset vector, so we need to stuff the remainder. 80328bb01e5SRafal Jaworowski * Upon release from holdoff CPU fetches the last word of the boot 80428bb01e5SRafal Jaworowski * page. 80528bb01e5SRafal Jaworowski */ 80628bb01e5SRafal Jaworowski .space 4092 - (__boot_page_padding - __boot_page) 80728bb01e5SRafal Jaworowski b __boot_page 808ab3f2a38SBrandon Bergren /* 809ab3f2a38SBrandon Bergren * This is the end of the boot page. 810ab3f2a38SBrandon Bergren * During AP startup, the previous instruction is at 0xfffffffc 811ab3f2a38SBrandon Bergren * virtual (i.e. the reset vector.) 812ab3f2a38SBrandon Bergren */ 81328bb01e5SRafal Jaworowski#endif /* SMP */ 81428bb01e5SRafal Jaworowski 815fdd28cb8SRafal Jaworowski/************************************************************************/ 816fdd28cb8SRafal Jaworowski/* locore subroutines */ 817fdd28cb8SRafal Jaworowski/************************************************************************/ 818fdd28cb8SRafal Jaworowski 8196b7ba544SRafal Jaworowski/* 8206b7ba544SRafal Jaworowski * Cache disable/enable/inval sequences according 8216b7ba544SRafal Jaworowski * to section 2.16 of E500CORE RM. 8226b7ba544SRafal Jaworowski */ 8236b7ba544SRafal JaworowskiENTRY(dcache_inval) 8246b7ba544SRafal Jaworowski /* Invalidate d-cache */ 8256b7ba544SRafal Jaworowski mfspr %r3, SPR_L1CSR0 8266b7ba544SRafal Jaworowski ori %r3, %r3, (L1CSR0_DCFI | L1CSR0_DCLFR)@l 8276b7ba544SRafal Jaworowski msync 8286b7ba544SRafal Jaworowski isync 8296b7ba544SRafal Jaworowski mtspr SPR_L1CSR0, %r3 8306b7ba544SRafal Jaworowski isync 831ece0de20SRafal Jaworowski1: mfspr %r3, SPR_L1CSR0 832ece0de20SRafal Jaworowski andi. %r3, %r3, L1CSR0_DCFI 833ece0de20SRafal Jaworowski bne 1b 8346b7ba544SRafal Jaworowski blr 835*78599c32SConrad MeyerEND(dcache_inval) 8366b7ba544SRafal Jaworowski 8376b7ba544SRafal JaworowskiENTRY(dcache_disable) 8386b7ba544SRafal Jaworowski /* Disable d-cache */ 8396b7ba544SRafal Jaworowski mfspr %r3, SPR_L1CSR0 8406b7ba544SRafal Jaworowski li %r4, L1CSR0_DCE@l 8416b7ba544SRafal Jaworowski not %r4, %r4 8426b7ba544SRafal Jaworowski and %r3, %r3, %r4 8436b7ba544SRafal Jaworowski msync 8446b7ba544SRafal Jaworowski isync 8456b7ba544SRafal Jaworowski mtspr SPR_L1CSR0, %r3 8466b7ba544SRafal Jaworowski isync 8476b7ba544SRafal Jaworowski blr 848*78599c32SConrad MeyerEND(dcache_disable) 8496b7ba544SRafal Jaworowski 8506b7ba544SRafal JaworowskiENTRY(dcache_enable) 8516b7ba544SRafal Jaworowski /* Enable d-cache */ 8526b7ba544SRafal Jaworowski mfspr %r3, SPR_L1CSR0 8536b7ba544SRafal Jaworowski oris %r3, %r3, (L1CSR0_DCPE | L1CSR0_DCE)@h 8546b7ba544SRafal Jaworowski ori %r3, %r3, (L1CSR0_DCPE | L1CSR0_DCE)@l 8556b7ba544SRafal Jaworowski msync 8566b7ba544SRafal Jaworowski isync 8576b7ba544SRafal Jaworowski mtspr SPR_L1CSR0, %r3 8586b7ba544SRafal Jaworowski isync 8596b7ba544SRafal Jaworowski blr 860*78599c32SConrad MeyerEND(dcache_enable) 8616b7ba544SRafal Jaworowski 8626b7ba544SRafal JaworowskiENTRY(icache_inval) 8636b7ba544SRafal Jaworowski /* Invalidate i-cache */ 8646b7ba544SRafal Jaworowski mfspr %r3, SPR_L1CSR1 8656b7ba544SRafal Jaworowski ori %r3, %r3, (L1CSR1_ICFI | L1CSR1_ICLFR)@l 8666b7ba544SRafal Jaworowski isync 8676b7ba544SRafal Jaworowski mtspr SPR_L1CSR1, %r3 8686b7ba544SRafal Jaworowski isync 869ece0de20SRafal Jaworowski1: mfspr %r3, SPR_L1CSR1 870ece0de20SRafal Jaworowski andi. %r3, %r3, L1CSR1_ICFI 871ece0de20SRafal Jaworowski bne 1b 8726b7ba544SRafal Jaworowski blr 873*78599c32SConrad MeyerEND(icache_inval) 8746b7ba544SRafal Jaworowski 8756b7ba544SRafal JaworowskiENTRY(icache_disable) 8766b7ba544SRafal Jaworowski /* Disable i-cache */ 8776b7ba544SRafal Jaworowski mfspr %r3, SPR_L1CSR1 8786b7ba544SRafal Jaworowski li %r4, L1CSR1_ICE@l 8796b7ba544SRafal Jaworowski not %r4, %r4 8806b7ba544SRafal Jaworowski and %r3, %r3, %r4 8816b7ba544SRafal Jaworowski isync 8826b7ba544SRafal Jaworowski mtspr SPR_L1CSR1, %r3 8836b7ba544SRafal Jaworowski isync 8846b7ba544SRafal Jaworowski blr 885*78599c32SConrad MeyerEND(icache_disable) 8866b7ba544SRafal Jaworowski 8876b7ba544SRafal JaworowskiENTRY(icache_enable) 8886b7ba544SRafal Jaworowski /* Enable i-cache */ 8896b7ba544SRafal Jaworowski mfspr %r3, SPR_L1CSR1 8906b7ba544SRafal Jaworowski oris %r3, %r3, (L1CSR1_ICPE | L1CSR1_ICE)@h 8916b7ba544SRafal Jaworowski ori %r3, %r3, (L1CSR1_ICPE | L1CSR1_ICE)@l 8926b7ba544SRafal Jaworowski isync 8936b7ba544SRafal Jaworowski mtspr SPR_L1CSR1, %r3 8946b7ba544SRafal Jaworowski isync 8956b7ba544SRafal Jaworowski blr 896*78599c32SConrad MeyerEND(icache_enable) 8976b7ba544SRafal Jaworowski 8986b7ba544SRafal Jaworowski/* 8993f068cbfSJustin Hibbits * L2 cache disable/enable/inval sequences for E500mc. 9003f068cbfSJustin Hibbits */ 9013f068cbfSJustin Hibbits 9023f068cbfSJustin HibbitsENTRY(l2cache_inval) 9033f068cbfSJustin Hibbits mfspr %r3, SPR_L2CSR0 9043f068cbfSJustin Hibbits oris %r3, %r3, (L2CSR0_L2FI | L2CSR0_L2LFC)@h 9053f068cbfSJustin Hibbits ori %r3, %r3, (L2CSR0_L2FI | L2CSR0_L2LFC)@l 9063f068cbfSJustin Hibbits isync 9073f068cbfSJustin Hibbits mtspr SPR_L2CSR0, %r3 9083f068cbfSJustin Hibbits isync 9093f068cbfSJustin Hibbits1: mfspr %r3, SPR_L2CSR0 9103f068cbfSJustin Hibbits andis. %r3, %r3, L2CSR0_L2FI@h 9113f068cbfSJustin Hibbits bne 1b 9123f068cbfSJustin Hibbits blr 913*78599c32SConrad MeyerEND(l2cache_inval) 9143f068cbfSJustin Hibbits 9153f068cbfSJustin HibbitsENTRY(l2cache_enable) 9163f068cbfSJustin Hibbits mfspr %r3, SPR_L2CSR0 9173f068cbfSJustin Hibbits oris %r3, %r3, (L2CSR0_L2E | L2CSR0_L2PE)@h 9183f068cbfSJustin Hibbits isync 9193f068cbfSJustin Hibbits mtspr SPR_L2CSR0, %r3 9203f068cbfSJustin Hibbits isync 9213f068cbfSJustin Hibbits blr 922*78599c32SConrad MeyerEND(l2cache_enable) 9233f068cbfSJustin Hibbits 9243f068cbfSJustin Hibbits/* 9253f068cbfSJustin Hibbits * Branch predictor setup. 9263f068cbfSJustin Hibbits */ 9273f068cbfSJustin HibbitsENTRY(bpred_enable) 9283f068cbfSJustin Hibbits mfspr %r3, SPR_BUCSR 9293f068cbfSJustin Hibbits ori %r3, %r3, BUCSR_BBFI 9303f068cbfSJustin Hibbits isync 9313f068cbfSJustin Hibbits mtspr SPR_BUCSR, %r3 9323f068cbfSJustin Hibbits isync 9333f068cbfSJustin Hibbits ori %r3, %r3, BUCSR_BPEN 9343f068cbfSJustin Hibbits isync 9353f068cbfSJustin Hibbits mtspr SPR_BUCSR, %r3 9363f068cbfSJustin Hibbits isync 9373f068cbfSJustin Hibbits blr 938*78599c32SConrad MeyerEND(bpred_enable) 9393f068cbfSJustin Hibbits 940cbc3c68dSJustin Hibbits/* 941cbc3c68dSJustin Hibbits * XXX: This should be moved to a shared AIM/booke asm file, if one ever is 942cbc3c68dSJustin Hibbits * created. 943cbc3c68dSJustin Hibbits */ 944cbc3c68dSJustin HibbitsENTRY(get_spr) 945ab3f2a38SBrandon Bergren /* Note: The spr number is patched at runtime */ 946cbc3c68dSJustin Hibbits mfspr %r3, 0 947cbc3c68dSJustin Hibbits blr 948*78599c32SConrad MeyerEND(get_spr) 949cbc3c68dSJustin Hibbits 9506b7ba544SRafal Jaworowski/************************************************************************/ 9516b7ba544SRafal Jaworowski/* Data section */ 9526b7ba544SRafal Jaworowski/************************************************************************/ 9536b7ba544SRafal Jaworowski .data 9545c845fdeSNathan Whitehorn .align 3 9555c845fdeSNathan WhitehornGLOBAL(__startkernel) 956e683c328SJustin Hibbits ADDR(begin) 9575c845fdeSNathan WhitehornGLOBAL(__endkernel) 958e683c328SJustin Hibbits ADDR(end) 9596b7ba544SRafal Jaworowski .align 4 960959aea56SRafal Jaworowskitmpstack: 961959aea56SRafal Jaworowski .space TMPSTACKSZ 962bb808254SNathan Whitehorntmpstackbound: 963bb808254SNathan Whitehorn .space 10240 /* XXX: this really should not be necessary */ 964e683c328SJustin Hibbits#ifdef __powerpc64__ 965e683c328SJustin HibbitsTOC_ENTRY(tmpstack) 966ab3f2a38SBrandon Bergren#ifdef SMP 967e683c328SJustin HibbitsTOC_ENTRY(bp_kernload) 968e683c328SJustin Hibbits#endif 969ab3f2a38SBrandon Bergren#endif 9706b7ba544SRafal Jaworowski 9716b7ba544SRafal Jaworowski/* 9726b7ba544SRafal Jaworowski * Compiled KERNBASE locations 9736b7ba544SRafal Jaworowski */ 9746b7ba544SRafal Jaworowski .globl kernbase 9756b7ba544SRafal Jaworowski .set kernbase, KERNBASE 9766b7ba544SRafal Jaworowski 9776b7ba544SRafal Jaworowski#include <powerpc/booke/trap_subr.S> 978