16d5af1a3SMichal Simek/* 26d5af1a3SMichal Simek * Copyright (C) 2007-2009 Michal Simek <monstr@monstr.eu> 36d5af1a3SMichal Simek * Copyright (C) 2007-2009 PetaLogix 46d5af1a3SMichal Simek * Copyright (C) 2006 Atmark Techno, Inc. 56d5af1a3SMichal Simek * 65846cc60SMichal Simek * MMU code derived from arch/ppc/kernel/head_4xx.S: 75846cc60SMichal Simek * Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org> 85846cc60SMichal Simek * Initial PowerPC version. 95846cc60SMichal Simek * Copyright (c) 1996 Cort Dougan <cort@cs.nmt.edu> 105846cc60SMichal Simek * Rewritten for PReP 115846cc60SMichal Simek * Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au> 125846cc60SMichal Simek * Low-level exception handers, MMU support, and rewrite. 135846cc60SMichal Simek * Copyright (c) 1997 Dan Malek <dmalek@jlc.net> 145846cc60SMichal Simek * PowerPC 8xx modifications. 155846cc60SMichal Simek * Copyright (c) 1998-1999 TiVo, Inc. 165846cc60SMichal Simek * PowerPC 403GCX modifications. 175846cc60SMichal Simek * Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu> 185846cc60SMichal Simek * PowerPC 403GCX/405GP modifications. 195846cc60SMichal Simek * Copyright 2000 MontaVista Software Inc. 205846cc60SMichal Simek * PPC405 modifications 215846cc60SMichal Simek * PowerPC 403GCX/405GP modifications. 225846cc60SMichal Simek * Author: MontaVista Software, Inc. 235846cc60SMichal Simek * frank_rowand@mvista.com or source@mvista.com 245846cc60SMichal Simek * debbie_chu@mvista.com 255846cc60SMichal Simek * 266d5af1a3SMichal Simek * This file is subject to the terms and conditions of the GNU General Public 276d5af1a3SMichal Simek * License. See the file "COPYING" in the main directory of this archive 286d5af1a3SMichal Simek * for more details. 296d5af1a3SMichal Simek */ 306d5af1a3SMichal Simek 317a0248e8SSteven J. Magnani#include <linux/init.h> 326d5af1a3SMichal Simek#include <linux/linkage.h> 336d5af1a3SMichal Simek#include <asm/thread_info.h> 346d5af1a3SMichal Simek#include <asm/page.h> 35d8678b58SGrant Likely#include <linux/of_fdt.h> /* for OF_DT_HEADER */ 366d5af1a3SMichal Simek 375846cc60SMichal Simek#include <asm/setup.h> /* COMMAND_LINE_SIZE */ 385846cc60SMichal Simek#include <asm/mmu.h> 395846cc60SMichal Simek#include <asm/processor.h> 405846cc60SMichal Simek 41495162dfSMichal Simek.section .data 425846cc60SMichal Simek.global empty_zero_page 435846cc60SMichal Simek.align 12 445846cc60SMichal Simekempty_zero_page: 45ba9c4f88SSteven J. Magnani .space PAGE_SIZE 465846cc60SMichal Simek.global swapper_pg_dir 475846cc60SMichal Simekswapper_pg_dir: 48ba9c4f88SSteven J. Magnani .space PAGE_SIZE 495846cc60SMichal Simek 50495162dfSMichal Simek.section .rodata 51495162dfSMichal Simek.align 4 52495162dfSMichal Simekendian_check: 53495162dfSMichal Simek .word 1 54495162dfSMichal Simek 557a0248e8SSteven J. Magnani __HEAD 566d5af1a3SMichal SimekENTRY(_start) 57ee68f174SMichal Simek#if CONFIG_KERNEL_BASE_ADDR == 0 58ee68f174SMichal Simek brai TOPHYS(real_start) 59ee68f174SMichal Simek .org 0x100 60ee68f174SMichal Simekreal_start: 61ee68f174SMichal Simek#endif 62ee68f174SMichal Simek 63173701d7SMichal Simek mts rmsr, r0 6434b9c07aSMichal Simek/* Disable stack protection from bootloader */ 6534b9c07aSMichal Simek mts rslr, r0 66a49f56eeSEdgar E. Iglesias addi r8, r0, 0xFFFFFFFF 6734b9c07aSMichal Simek mts rshr, r8 682622434eSMichal Simek/* 690eb6aaf5SMichal Simek * According to Xilinx, msrclr instruction behaves like 'mfs rX,rpc' 700eb6aaf5SMichal Simek * if the msrclr instruction is not enabled. We use this to detect 710eb6aaf5SMichal Simek * if the opcode is available, by issuing msrclr and then testing the result. 720eb6aaf5SMichal Simek * r8 == 0 - msr instructions are implemented 730eb6aaf5SMichal Simek * r8 != 0 - msr instructions are not implemented 742622434eSMichal Simek */ 75173701d7SMichal Simek mfs r1, rmsr 760eb6aaf5SMichal Simek msrclr r8, 0 /* clear nothing - just read msr for test */ 770eb6aaf5SMichal Simek cmpu r8, r8, r1 /* r1 must contain msr reg content */ 782622434eSMichal Simek 79909964ecSJohn Williams/* r7 may point to an FDT, or there may be one linked in. 80909964ecSJohn Williams if it's in r7, we've got to save it away ASAP. 81909964ecSJohn Williams We ensure r7 points to a valid FDT, just in case the bootloader 82909964ecSJohn Williams is broken or non-existent */ 83909964ecSJohn Williams beqi r7, no_fdt_arg /* NULL pointer? don't copy */ 84026a2078SMichal Simek/* Does r7 point to a valid FDT? Load HEADER magic number */ 85026a2078SMichal Simek /* Run time Big/Little endian platform */ 86026a2078SMichal Simek /* Save 1 as word and load byte - 0 - BIG, 1 - LITTLE */ 87495162dfSMichal Simek lbui r11, r0, TOPHYS(endian_check) 88026a2078SMichal Simek beqid r11, big_endian /* DO NOT break delay stop dependency */ 89026a2078SMichal Simek lw r11, r0, r7 /* Big endian load in delay slot */ 90026a2078SMichal Simek lwr r11, r0, r7 /* Little endian load */ 91026a2078SMichal Simekbig_endian: 92026a2078SMichal Simek rsubi r11, r11, OF_DT_HEADER /* Check FDT header */ 93ea3fd146SMichal Simek beqi r11, _prepare_copy_fdt 94ea3fd146SMichal Simek or r7, r0, r0 /* clear R7 when not valid DTB */ 95909964ecSJohn Williams bnei r11, no_fdt_arg /* No - get out of here */ 96ea3fd146SMichal Simek_prepare_copy_fdt: 976d5af1a3SMichal Simek or r11, r0, r0 /* incremment */ 98909964ecSJohn Williams ori r4, r0, TOPHYS(_fdt_start) 9922648c98SSiva Durga Prasad Paladugu ori r3, r0, (0x10000 - 4) 1006d5af1a3SMichal Simek_copy_fdt: 1016d5af1a3SMichal Simek lw r12, r7, r11 /* r12 = r7 + r11 */ 1026d5af1a3SMichal Simek sw r12, r4, r11 /* addr[r4 + r11] = r12 */ 1036d5af1a3SMichal Simek addik r11, r11, 4 /* increment counting */ 1046d5af1a3SMichal Simek bgtid r3, _copy_fdt /* loop for all entries */ 1056d5af1a3SMichal Simek addik r3, r3, -4 /* descrement loop */ 1066d5af1a3SMichal Simekno_fdt_arg: 1076d5af1a3SMichal Simek 1085846cc60SMichal Simek#ifndef CONFIG_CMDLINE_BOOL 1095846cc60SMichal Simek/* 1105846cc60SMichal Simek * handling command line 111fcc1c0ffSMichal Simek * copy command line directly to cmd_line placed in data section. 1125846cc60SMichal Simek */ 113fcc1c0ffSMichal Simek beqid r5, skip /* Skip if NULL pointer */ 1144323cd48SMichal Simek or r11, r0, r0 /* incremment */ 115fcc1c0ffSMichal Simek ori r4, r0, cmd_line /* load address of command line */ 1165846cc60SMichal Simek tophys(r4,r4) /* convert to phys address */ 1175846cc60SMichal Simek ori r3, r0, COMMAND_LINE_SIZE - 1 /* number of loops */ 1185846cc60SMichal Simek_copy_command_line: 119*62fa3bc5SMichal Simek /* r2=r5+r11 - r5 contain pointer to command line */ 1204323cd48SMichal Simek lbu r2, r5, r11 121fcc1c0ffSMichal Simek beqid r2, skip /* Skip if no data */ 122*62fa3bc5SMichal Simek sb r2, r4, r11 /* addr[r4+r11]= r2 */ 1234323cd48SMichal Simek addik r11, r11, 1 /* increment counting */ 1245846cc60SMichal Simek bgtid r3, _copy_command_line /* loop for all entries */ 125fcc1c0ffSMichal Simek addik r3, r3, -1 /* decrement loop */ 1265846cc60SMichal Simek addik r5, r4, 0 /* add new space for command line */ 1275846cc60SMichal Simek tovirt(r5,r5) 128fcc1c0ffSMichal Simekskip: 1295846cc60SMichal Simek#endif /* CONFIG_CMDLINE_BOOL */ 1305846cc60SMichal Simek 1315846cc60SMichal Simek#ifdef NOT_COMPILE 1325846cc60SMichal Simek/* save bram context */ 1334323cd48SMichal Simek or r11, r0, r0 /* incremment */ 1345846cc60SMichal Simek ori r4, r0, TOPHYS(_bram_load_start) /* save bram context */ 1355846cc60SMichal Simek ori r3, r0, (LMB_SIZE - 4) 1365846cc60SMichal Simek_copy_bram: 137*62fa3bc5SMichal Simek lw r7, r0, r11 /* r7 = r0 + r11 */ 138*62fa3bc5SMichal Simek sw r7, r4, r11 /* addr[r4 + r11] = r7 */ 1394323cd48SMichal Simek addik r11, r11, 4 /* increment counting */ 1405846cc60SMichal Simek bgtid r3, _copy_bram /* loop for all entries */ 1415846cc60SMichal Simek addik r3, r3, -4 /* descrement loop */ 1425846cc60SMichal Simek#endif 1435846cc60SMichal Simek /* We have to turn on the MMU right away. */ 1445846cc60SMichal Simek 1455846cc60SMichal Simek /* 1465846cc60SMichal Simek * Set up the initial MMU state so we can do the first level of 1475846cc60SMichal Simek * kernel initialization. This maps the first 16 MBytes of memory 1:1 1485846cc60SMichal Simek * virtual to physical. 1495846cc60SMichal Simek */ 1505846cc60SMichal Simek nop 1510691c97dSMichal Simek addik r3, r0, MICROBLAZE_TLB_SIZE -1 /* Invalidate all TLB entries */ 1525846cc60SMichal Simek_invalidate: 1535846cc60SMichal Simek mts rtlbx, r3 1545846cc60SMichal Simek mts rtlbhi, r0 /* flush: ensure V is clear */ 155e02db0aaSMichal Simek mts rtlblo, r0 1565846cc60SMichal Simek bgtid r3, _invalidate /* loop for all entries */ 1575846cc60SMichal Simek addik r3, r3, -1 1585846cc60SMichal Simek /* sync */ 1595846cc60SMichal Simek 160137d0795SMichal Simek /* Setup the kernel PID */ 161137d0795SMichal Simek mts rpid,r0 /* Load the kernel PID */ 162137d0795SMichal Simek nop 163137d0795SMichal Simek bri 4 164137d0795SMichal Simek 1655846cc60SMichal Simek /* 1665846cc60SMichal Simek * We should still be executing code at physical address area 1675846cc60SMichal Simek * RAM_BASEADDR at this point. However, kernel code is at 1685846cc60SMichal Simek * a virtual address. So, set up a TLB mapping to cover this once 1695846cc60SMichal Simek * translation is enabled. 1705846cc60SMichal Simek */ 1715846cc60SMichal Simek 1725846cc60SMichal Simek addik r3,r0, CONFIG_KERNEL_START /* Load the kernel virtual address */ 1735846cc60SMichal Simek tophys(r4,r3) /* Load the kernel physical address */ 1745846cc60SMichal Simek 17595b0f9eaSMichal Simek /* start to do TLB calculation */ 17695b0f9eaSMichal Simek addik r12, r0, _end 17795b0f9eaSMichal Simek rsub r12, r3, r12 1787f15a256SMichal Simek addik r12, r12, CONFIG_LOWMEM_SIZE >> PTE_SHIFT /* that's the pad */ 17995b0f9eaSMichal Simek 18095b0f9eaSMichal Simek or r9, r0, r0 /* TLB0 = 0 */ 18195b0f9eaSMichal Simek or r10, r0, r0 /* TLB1 = 0 */ 18295b0f9eaSMichal Simek 18395b0f9eaSMichal Simek addik r11, r12, -0x1000000 18495b0f9eaSMichal Simek bgei r11, GT16 /* size is greater than 16MB */ 18595b0f9eaSMichal Simek addik r11, r12, -0x0800000 18695b0f9eaSMichal Simek bgei r11, GT8 /* size is greater than 8MB */ 18795b0f9eaSMichal Simek addik r11, r12, -0x0400000 18895b0f9eaSMichal Simek bgei r11, GT4 /* size is greater than 4MB */ 18995b0f9eaSMichal Simek /* size is less than 4MB */ 19095b0f9eaSMichal Simek addik r11, r12, -0x0200000 19195b0f9eaSMichal Simek bgei r11, GT2 /* size is greater than 2MB */ 19295b0f9eaSMichal Simek addik r9, r0, 0x0100000 /* TLB0 must be 1MB */ 19395b0f9eaSMichal Simek addik r11, r12, -0x0100000 19495b0f9eaSMichal Simek bgei r11, GT1 /* size is greater than 1MB */ 19595b0f9eaSMichal Simek /* TLB1 is 0 which is setup above */ 19695b0f9eaSMichal Simek bri tlb_end 19795b0f9eaSMichal SimekGT4: /* r11 contains the rest - will be either 1 or 4 */ 19895b0f9eaSMichal Simek ori r9, r0, 0x400000 /* TLB0 is 4MB */ 19995b0f9eaSMichal Simek bri TLB1 20095b0f9eaSMichal SimekGT16: /* TLB0 is 16MB */ 20195b0f9eaSMichal Simek addik r9, r0, 0x1000000 /* means TLB0 is 16MB */ 20295b0f9eaSMichal SimekTLB1: 203225fba21SAntonio Ospite /* must be used r2 because of subtract if failed */ 20495b0f9eaSMichal Simek addik r2, r11, -0x0400000 20595b0f9eaSMichal Simek bgei r2, GT20 /* size is greater than 16MB */ 20695b0f9eaSMichal Simek /* size is >16MB and <20MB */ 20795b0f9eaSMichal Simek addik r11, r11, -0x0100000 20895b0f9eaSMichal Simek bgei r11, GT17 /* size is greater than 17MB */ 20995b0f9eaSMichal Simek /* kernel is >16MB and < 17MB */ 21095b0f9eaSMichal SimekGT1: 21195b0f9eaSMichal Simek addik r10, r0, 0x0100000 /* means TLB1 is 1MB */ 21295b0f9eaSMichal Simek bri tlb_end 21395b0f9eaSMichal SimekGT2: /* TLB0 is 0 and TLB1 will be 4MB */ 21495b0f9eaSMichal SimekGT17: /* TLB1 is 4MB - kernel size <20MB */ 21595b0f9eaSMichal Simek addik r10, r0, 0x0400000 /* means TLB1 is 4MB */ 21695b0f9eaSMichal Simek bri tlb_end 21795b0f9eaSMichal SimekGT8: /* TLB0 is still zero that's why I can use only TLB1 */ 21895b0f9eaSMichal SimekGT20: /* TLB1 is 16MB - kernel size >20MB */ 21995b0f9eaSMichal Simek addik r10, r0, 0x1000000 /* means TLB1 is 16MB */ 22095b0f9eaSMichal Simektlb_end: 22195b0f9eaSMichal Simek 2225846cc60SMichal Simek /* 2235846cc60SMichal Simek * Configure and load two entries into TLB slots 0 and 1. 2245846cc60SMichal Simek * In case we are pinning TLBs, these are reserved in by the 2255846cc60SMichal Simek * other TLB functions. If not reserving, then it doesn't 2265846cc60SMichal Simek * matter where they are loaded. 2275846cc60SMichal Simek */ 2285846cc60SMichal Simek andi r4,r4,0xfffffc00 /* Mask off the real page number */ 2295846cc60SMichal Simek ori r4,r4,(TLB_WR | TLB_EX) /* Set the write and execute bits */ 2305846cc60SMichal Simek 231e02db0aaSMichal Simek /* 232e02db0aaSMichal Simek * TLB0 is always used - check if is not zero (r9 stores TLB0 value) 233e02db0aaSMichal Simek * if is use TLB1 value and clear it (r10 stores TLB1 value) 234e02db0aaSMichal Simek */ 235e02db0aaSMichal Simek bnei r9, tlb0_not_zero 236e02db0aaSMichal Simek add r9, r10, r0 237e02db0aaSMichal Simek add r10, r0, r0 238e02db0aaSMichal Simektlb0_not_zero: 23995b0f9eaSMichal Simek 24095b0f9eaSMichal Simek /* look at the code below */ 24195b0f9eaSMichal Simek ori r30, r0, 0x200 24295b0f9eaSMichal Simek andi r29, r9, 0x100000 24395b0f9eaSMichal Simek bneid r29, 1f 24495b0f9eaSMichal Simek addik r30, r30, 0x80 24595b0f9eaSMichal Simek andi r29, r9, 0x400000 24695b0f9eaSMichal Simek bneid r29, 1f 24795b0f9eaSMichal Simek addik r30, r30, 0x80 24895b0f9eaSMichal Simek andi r29, r9, 0x1000000 24995b0f9eaSMichal Simek bneid r29, 1f 25095b0f9eaSMichal Simek addik r30, r30, 0x80 25195b0f9eaSMichal Simek1: 2525846cc60SMichal Simek andi r3,r3,0xfffffc00 /* Mask off the effective page number */ 25395b0f9eaSMichal Simek ori r3,r3,(TLB_VALID) 254e02db0aaSMichal Simek or r3, r3, r30 2555846cc60SMichal Simek 256e02db0aaSMichal Simek /* Load tlb_skip size value which is index to first unused TLB entry */ 257e02db0aaSMichal Simek lwi r11, r0, TOPHYS(tlb_skip) 258e02db0aaSMichal Simek mts rtlbx,r11 /* TLB slow 0 */ 2595846cc60SMichal Simek 2605846cc60SMichal Simek mts rtlblo,r4 /* Load the data portion of the entry */ 2615846cc60SMichal Simek mts rtlbhi,r3 /* Load the tag portion of the entry */ 2625846cc60SMichal Simek 263e02db0aaSMichal Simek /* Increase tlb_skip size */ 264e02db0aaSMichal Simek addik r11, r11, 1 265e02db0aaSMichal Simek swi r11, r0, TOPHYS(tlb_skip) 266e02db0aaSMichal Simek 26795b0f9eaSMichal Simek /* TLB1 can be zeroes that's why we not setup it */ 26895b0f9eaSMichal Simek beqi r10, jump_over2 26995b0f9eaSMichal Simek 27095b0f9eaSMichal Simek /* look at the code below */ 27195b0f9eaSMichal Simek ori r30, r0, 0x200 27295b0f9eaSMichal Simek andi r29, r10, 0x100000 27395b0f9eaSMichal Simek bneid r29, 1f 27495b0f9eaSMichal Simek addik r30, r30, 0x80 27595b0f9eaSMichal Simek andi r29, r10, 0x400000 27695b0f9eaSMichal Simek bneid r29, 1f 27795b0f9eaSMichal Simek addik r30, r30, 0x80 27895b0f9eaSMichal Simek andi r29, r10, 0x1000000 27995b0f9eaSMichal Simek bneid r29, 1f 28095b0f9eaSMichal Simek addik r30, r30, 0x80 28195b0f9eaSMichal Simek1: 28295b0f9eaSMichal Simek addk r4, r4, r9 /* previous addr + TLB0 size */ 28395b0f9eaSMichal Simek addk r3, r3, r9 28495b0f9eaSMichal Simek 28595b0f9eaSMichal Simek andi r3,r3,0xfffffc00 /* Mask off the effective page number */ 28695b0f9eaSMichal Simek ori r3,r3,(TLB_VALID) 287e02db0aaSMichal Simek or r3, r3, r30 2885846cc60SMichal Simek 289e02db0aaSMichal Simek lwi r11, r0, TOPHYS(tlb_skip) 290e02db0aaSMichal Simek mts rtlbx, r11 /* r11 is used from TLB0 */ 2915846cc60SMichal Simek 2925846cc60SMichal Simek mts rtlblo,r4 /* Load the data portion of the entry */ 2935846cc60SMichal Simek mts rtlbhi,r3 /* Load the tag portion of the entry */ 2945846cc60SMichal Simek 295e02db0aaSMichal Simek /* Increase tlb_skip size */ 296e02db0aaSMichal Simek addik r11, r11, 1 297e02db0aaSMichal Simek swi r11, r0, TOPHYS(tlb_skip) 298e02db0aaSMichal Simek 29995b0f9eaSMichal Simekjump_over2: 3005846cc60SMichal Simek /* 3015846cc60SMichal Simek * Load a TLB entry for LMB, since we need access to 3025846cc60SMichal Simek * the exception vectors, using a 4k real==virtual mapping. 3035846cc60SMichal Simek */ 304e02db0aaSMichal Simek /* Use temporary TLB_ID for LMB - clear this temporary mapping later */ 3054323cd48SMichal Simek ori r11, r0, MICROBLAZE_LMB_TLB_ID 3064323cd48SMichal Simek mts rtlbx,r11 3075846cc60SMichal Simek 3085846cc60SMichal Simek ori r4,r0,(TLB_WR | TLB_EX) 3095846cc60SMichal Simek ori r3,r0,(TLB_VALID | TLB_PAGESZ(PAGESZ_4K)) 3105846cc60SMichal Simek 3115846cc60SMichal Simek mts rtlblo,r4 /* Load the data portion of the entry */ 3125846cc60SMichal Simek mts rtlbhi,r3 /* Load the tag portion of the entry */ 3135846cc60SMichal Simek 3145846cc60SMichal Simek /* 3155846cc60SMichal Simek * We now have the lower 16 Meg of RAM mapped into TLB entries, and the 3165846cc60SMichal Simek * caches ready to work. 3175846cc60SMichal Simek */ 3185846cc60SMichal Simekturn_on_mmu: 3195846cc60SMichal Simek ori r15,r0,start_here 3205846cc60SMichal Simek ori r4,r0,MSR_KERNEL_VMS 3215846cc60SMichal Simek mts rmsr,r4 3225846cc60SMichal Simek nop 3235846cc60SMichal Simek rted r15,0 /* enables MMU */ 3245846cc60SMichal Simek nop 3255846cc60SMichal Simek 3265846cc60SMichal Simekstart_here: 3275846cc60SMichal Simek 3286d5af1a3SMichal Simek /* Initialize small data anchors */ 329cd341577SMichal Simek addik r13, r0, _KERNEL_SDA_BASE_ 330cd341577SMichal Simek addik r2, r0, _KERNEL_SDA2_BASE_ 3316d5af1a3SMichal Simek 3326d5af1a3SMichal Simek /* Initialize stack pointer */ 333cd341577SMichal Simek addik r1, r0, init_thread_union + THREAD_SIZE - 4 3346d5af1a3SMichal Simek 3356d5af1a3SMichal Simek /* Initialize r31 with current task address */ 336cd341577SMichal Simek addik r31, r0, init_task 3376d5af1a3SMichal Simek 33895b0f9eaSMichal Simek addik r11, r0, machine_early_init 33995b0f9eaSMichal Simek brald r15, r11 3406d5af1a3SMichal Simek nop 3416d5af1a3SMichal Simek 3425846cc60SMichal Simek /* 3435846cc60SMichal Simek * Initialize the MMU. 3445846cc60SMichal Simek */ 3455846cc60SMichal Simek bralid r15, mmu_init 3465846cc60SMichal Simek nop 3475846cc60SMichal Simek 3485846cc60SMichal Simek /* Go back to running unmapped so we can load up new values 3495846cc60SMichal Simek * and change to using our exception vectors. 3505846cc60SMichal Simek * On the MicroBlaze, all we invalidate the used TLB entries to clear 3515846cc60SMichal Simek * the old 16M byte TLB mappings. 3525846cc60SMichal Simek */ 3535846cc60SMichal Simek ori r15,r0,TOPHYS(kernel_load_context) 3545846cc60SMichal Simek ori r4,r0,MSR_KERNEL 3555846cc60SMichal Simek mts rmsr,r4 3565846cc60SMichal Simek nop 3575846cc60SMichal Simek bri 4 3585846cc60SMichal Simek rted r15,0 3595846cc60SMichal Simek nop 3605846cc60SMichal Simek 3615846cc60SMichal Simek /* Load up the kernel context */ 3625846cc60SMichal Simekkernel_load_context: 363e02db0aaSMichal Simek ori r5, r0, MICROBLAZE_LMB_TLB_ID 3645846cc60SMichal Simek mts rtlbx,r5 3655846cc60SMichal Simek nop 3665846cc60SMichal Simek mts rtlbhi,r0 3675846cc60SMichal Simek nop 3685846cc60SMichal Simek addi r15, r0, machine_halt 3695846cc60SMichal Simek ori r17, r0, start_kernel 3705846cc60SMichal Simek ori r4, r0, MSR_KERNEL_VMS 3715846cc60SMichal Simek mts rmsr, r4 3725846cc60SMichal Simek nop 3735846cc60SMichal Simek rted r17, 0 /* enable MMU and jump to start_kernel */ 3745846cc60SMichal Simek nop 375