[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/bsp/lk/arch/or1k/start.S b/src/bsp/lk/arch/or1k/start.S
new file mode 100644
index 0000000..5af80fa
--- /dev/null
+++ b/src/bsp/lk/arch/or1k/start.S
@@ -0,0 +1,525 @@
+/*
+ * Copyright (c) 2015 Stefan Kristiansson
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+ * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include <asm.h>
+#include <arch/ops.h>
+#include <arch/or1k/mmu.h>
+#include <kernel/vm.h>
+
+#define RED_ZONE            128
+#define EXCEPTION_FRAME     (128 + RED_ZONE)
+
+/* clobbers r9 and rd, result will be in rd */
+#define get_va_to_pa_offs(rd) \
+    l.movhi rd, hi(.+12)    ;\
+    l.jal   .+8             ;\
+     l.ori  rd, rd, lo(.+4) ;\
+    l.sub   rd, rd, r9
+
+/* clobbers r9 and rd, result will be in rd */
+#define to_phys(sym, rd) \
+    get_va_to_pa_offs(rd)   ;\
+    l.movhi r9, hi(sym)     ;\
+    l.ori   r9, r9, lo(sym) ;\
+    l.sub   rd, r9, rd
+
+.macro exception_entry
+#if WITH_KERNEL_VM
+    l.sw    0(r0), r31
+    l.sw    4(r0), r9
+    get_va_to_pa_offs(r31)
+    l.sub   r1, r1, r31
+    l.lwz   r9, 4(r0)
+#endif
+    l.addi  r1, r1, -EXCEPTION_FRAME
+    l.sw    0(r1), r2
+    l.sw    4(r1), r3
+    l.sw    8(r1), r4
+    l.sw    12(r1), r5
+    l.sw    16(r1), r6
+    l.sw    20(r1), r7
+    l.sw    24(r1), r8
+    l.sw    28(r1), r9
+    l.sw    32(r1), r10
+    l.sw    36(r1), r11
+    l.sw    40(r1), r12
+    l.sw    44(r1), r13
+    l.sw    48(r1), r14
+    l.sw    52(r1), r15
+    l.sw    56(r1), r16
+    l.sw    60(r1), r17
+    l.sw    64(r1), r18
+    l.sw    68(r1), r19
+    l.sw    72(r1), r20
+    l.sw    76(r1), r21
+    l.sw    80(r1), r22
+    l.sw    84(r1), r23
+    l.sw    88(r1), r24
+    l.sw    92(r1), r25
+    l.sw    96(r1), r26
+    l.sw    100(r1), r27
+    l.sw    104(r1), r28
+    l.sw    108(r1), r29
+    l.sw    112(r1), r30
+    l.mfspr r3, r0, OR1K_SPR_SYS_EPCR_ADDR(0)
+    l.sw    120(r1), r3
+    l.mfspr r3, r0, OR1K_SPR_SYS_ESR_ADDR(0)
+    l.sw    124(r1), r3
+#if WITH_KERNEL_VM
+    l.add   r1, r1, r31
+    l.lwz   r31, 0(r0)
+
+    /* enable dmmu and immu */
+    l.mfspr r9, r0, OR1K_SPR_SYS_SR_ADDR
+    l.ori   r9, r9, OR1K_SPR_SYS_SR_DME_MASK | OR1K_SPR_SYS_SR_IME_MASK
+    l.mtspr r0, r9, OR1K_SPR_SYS_ESR_ADDR(0)
+
+    l.movhi r9, hi(.+16)
+    l.ori   r9, r9, lo(.+12)
+    l.mtspr r0, r9, OR1K_SPR_SYS_EPCR_ADDR(0)
+    l.rfe
+#endif
+    l.sw    116(r1), r31
+.endm
+
+.section ".vectors", "ax"
+.org 0x100
+.global _reset
+_reset:
+    l.jal   start
+     l.nop
+
+.org 0x200
+bus_error_exception:
+    exception_entry
+    l.mfspr r4, r0, OR1K_SPR_SYS_EEAR_ADDR(0)
+    l.jal   or1k_busfault_handler
+     l.ori  r3, r1, 0
+    l.j return_from_exception
+     l.nop
+
+.org 0x300
+data_pagefault_exception:
+    exception_entry
+    l.mfspr r4, r0, OR1K_SPR_SYS_EEAR_ADDR(0)
+    l.jal   or1k_data_pagefault_handler
+     l.ori  r3, r1, 0
+    l.j return_from_exception
+     l.nop
+
+.org 0x400
+instruction_pagefault_exception:
+    exception_entry
+    l.mfspr r4, r0, OR1K_SPR_SYS_EEAR_ADDR(0)
+    l.jal   or1k_instruction_pagefault_handler
+     l.ori  r3, r1, 0
+    l.j return_from_exception
+     l.nop
+
+.org 0x500
+tick_timer_exception:
+    exception_entry
+    l.jal   or1k_tick
+     l.nop
+    l.j return_from_exception
+     l.nop
+
+.org 0x600
+alignment_exception:
+    exception_entry
+    l.mfspr r4, r0, OR1K_SPR_SYS_EEAR_ADDR(0)
+    l.jal   or1k_alignment_handler
+     l.ori  r3, r1, 0
+    l.j return_from_exception
+     l.nop
+
+.org 0x700
+illegal_instruction_exception:
+    exception_entry
+    l.mfspr r4, r0, OR1K_SPR_SYS_EEAR_ADDR(0)
+    l.jal   or1k_illegal_instruction_handler
+     l.ori  r3, r1, 0
+    l.j return_from_exception
+     l.nop
+
+.org 0x800
+external_interrupt_exception:
+    exception_entry
+    l.jal   or1k_irq
+     l.nop
+    l.j return_from_exception
+     l.nop
+
+.org 0x900
+dtlb_miss_exception:
+#if WITH_KERNEL_VM
+    l.sw    0(r0), r3
+    l.sw    4(r0), r4
+    l.sw    8(r0), r9
+
+    to_phys(or1k_kernel_translation_table, r3)
+    l.mfspr r4, r0, OR1K_SPR_SYS_EEAR_ADDR(0)
+    /* l1 index */
+    l.srli  r9, r4, 24
+    l.slli  r9, r9, 2
+
+    l.add   r3, r3, r9
+
+    l.lwz   r3, 0(r3) /* l1 entry */
+    l.andi  r9, r3, OR1K_MMU_PG_PRESENT
+    l.sfnei r9, OR1K_MMU_PG_PRESENT
+    l.bf    dtlb_miss_fault
+     l.andi r9, r3, OR1K_MMU_PG_L
+
+    l.sfeqi r9, OR1K_MMU_PG_L
+    /* l2_index */
+    l.srli  r4, r4, 13
+    l.bf    1f
+     l.andi r4, r4, 0x7ff
+    l.slli  r4, r4, 2
+    l.addi  r9, r0, 0xffffe000 /* PAGE_SIZE-1 */
+    l.and   r9, r3, r9
+    l.add   r9, r9, r4
+    l.j 2f
+     l.lwz  r9, 0(r9) /* l2 entry */
+
+/* use bits [23:13] from EEAR */
+1:  l.slli  r4, r4, 13
+    l.or    r9, r3, r4
+
+2:  l.ori   r3,r0,0xf351    /* sw emulation of dmmupr */
+    l.srli  r4,r9,4         /* get PP Index * 4 */
+    l.andi  r4,r4,0xc       /* mask everything but PPI (without X) (& 0b01100)*/
+    l.srl   r3,r3,r4        /* get protection bits from "dmmupr" */
+    /*
+    * The protection bits are unconvienently the "wrong" way in DMMUPR
+    * compared to DTLBR (UWE|URE|SWE|SRE vs SWE|SRE|UWE|URE), so we have
+    * to swap their places...
+    */
+    l.andi  r4,r3,0x3       /* SWE|SRE */
+    l.slli  r4,r4,8         /* 1:0 -> 9:8 */
+    l.andi  r3,r3,0xc       /* UWE|URE */
+    l.slli  r3,r3,4         /* 3:2 -> 7:6 */
+    l.or    r3,r3,r4
+
+    l.addi  r4,r0,0xffffe03f /* protection bit mask */
+    l.and   r4,r9,r4        /* apply the mask */
+    l.or    r9,r4,r3        /* apply protection bits */
+
+    l.mfspr r3, r0, OR1K_SPR_SYS_DMMUCFGR_ADDR
+    l.slli  r3, r3, 31-OR1K_SPR_SYS_DMMUCFGR_NTS_MSB
+    l.srli  r3, r3, 31-OR1K_SPR_SYS_DMMUCFGR_NTS_LSB
+    l.ori   r4, r0, 1
+    l.sll   r3, r4, r3
+    l.addi  r3, r3, -1
+    l.mfspr r4, r0, OR1K_SPR_SYS_EEAR_ADDR(0)
+    l.srli  r4, r4, 13
+    l.and   r3, r4, r3
+    l.mtspr r3, r9, OR1K_SPR_DMMU_DTLBW_TR_ADDR(0,0)
+    l.slli  r4, r4, 13
+    l.ori   r4, r4, OR1K_SPR_DMMU_DTLBW_MR_V_MASK
+    l.mtspr r3, r4, OR1K_SPR_DMMU_DTLBW_MR_ADDR(0,0)
+
+    l.lwz   r3, 0(r0)
+    l.lwz   r4, 4(r0)
+    l.lwz   r9, 8(r0)
+    l.rfe
+#endif /* WITH_KERNEL_VM */
+
+dtlb_miss_fault:
+    l.lwz   r3, 0(r0)
+    l.lwz   r4, 4(r0)
+    l.j     data_pagefault_exception
+     l.lwz   r9, 8(r0)
+
+.org 0xa00
+itlb_miss_exception:
+#if WITH_KERNEL_VM
+    l.sw    0(r0), r3
+    l.sw    4(r0), r4
+    l.sw    8(r0), r9
+
+    to_phys(or1k_kernel_translation_table, r3)
+    l.mfspr r4, r0, OR1K_SPR_SYS_EEAR_ADDR(0)
+    /* l1 index */
+    l.srli  r9, r4, 24
+    l.slli  r9, r9, 2
+
+    l.add   r3, r3, r9
+    l.lwz   r3, 0(r3) /* l1 entry */
+
+    l.andi  r9, r3, OR1K_MMU_PG_PRESENT
+    l.sfnei r9, OR1K_MMU_PG_PRESENT
+    l.bf    itlb_miss_fault
+     l.andi r9, r3, OR1K_MMU_PG_L
+    l.sfeqi r9, OR1K_MMU_PG_L
+    /* l2 index */
+    l.srli  r4, r4, 13
+    l.bf    1f
+     l.andi r4, r4, 0x7ff
+
+    l.slli  r4, r4, 2
+    l.addi  r9, r0, 0xffffe000 /* PAGE_SIZE-1 */
+    l.and   r9, r3, r9
+    l.add   r9, r9, r4
+    l.j 2f
+     l.lwz  r9, 0(r9) /* l2 entry */
+
+    /* use bits [23:13] from EEAR */
+1:  l.slli  r4, r4, 13
+    l.or    r9, r3, r4
+
+2:  l.ori   r3, r0, 0xd00   /* sw emulation of immupr */
+    l.srli  r4, r9, 5       /* get PP Index * 2 */
+    l.andi  r4, r4, 0xa     /* mask everything but PPI (without W) (& 0b1010)*/
+    l.srl   r3, r3, r4      /* get protection bits from "immupr" */
+    l.andi  r3, r3, 0x3     /* mask everything else out */
+    l.slli  r3, r3, 6       /* and put them in their spot */
+    l.addi  r4, r0, 0xffffe03f /* protection bit mask */
+    l.and   r4, r9, r4      /* apply the mask */
+    l.or    r9, r4, r3      /* apply protection bits */
+
+    l.mfspr r3, r0, OR1K_SPR_SYS_IMMUCFGR_ADDR
+    l.slli  r3, r3, 31-OR1K_SPR_SYS_IMMUCFGR_NTS_MSB
+    l.srli  r3, r3, 31-OR1K_SPR_SYS_IMMUCFGR_NTS_LSB
+    l.ori   r4, r0, 1
+    l.sll   r3, r4, r3
+    l.addi  r3, r3, -1
+    l.mfspr r4, r0, OR1K_SPR_SYS_EEAR_ADDR(0)
+    l.srli  r4, r4, 13
+    l.and   r3, r4, r3
+    l.mtspr r3, r9, OR1K_SPR_IMMU_ITLBW_TR_ADDR(0,0)
+
+    l.slli  r4, r4, 13
+    l.ori   r4, r4, OR1K_SPR_IMMU_ITLBW_MR_V_MASK
+    l.mtspr r3, r4, OR1K_SPR_IMMU_ITLBW_MR_ADDR(0,0)
+
+    l.lwz   r3, 0(r0)
+    l.lwz   r4, 4(r0)
+    l.lwz   r9, 8(r0)
+    l.rfe
+#endif /* WITH_KERNEL_VM */
+
+itlb_miss_fault:
+    l.lwz   r3, 0(r0)
+    l.lwz   r4, 4(r0)
+    l.j     instruction_pagefault_exception
+     l.lwz   r9, 8(r0)
+
+.org 0xb00
+range_exception:
+    exception_entry
+    l.ori   r4, r0, 0xb00
+    l.jal   or1k_unhandled_exception
+     l.ori  r3, r1, 0
+    l.j return_from_exception
+     l.nop
+
+.org 0xc00
+syscall_exception:
+    exception_entry
+    l.jal   or1k_syscall_handler
+     l.ori  r3, r1, 0
+    l.j return_from_exception
+     l.nop
+
+.org 0xd00
+fpu_exception:
+    exception_entry
+    l.ori   r4, r0, 0xd00
+    l.jal   or1k_unhandled_exception
+     l.ori  r3, r1, 0
+    l.j return_from_exception
+     l.nop
+
+.org 0xe00
+trap_exception:
+    exception_entry
+    l.ori   r4, r0, 0xe00
+    l.jal   or1k_unhandled_exception
+     l.ori  r3, r1, 0
+    l.j return_from_exception
+     l.nop
+
+.section ".text.boot"
+FUNCTION(start)
+    /* set stack pointer to point at top of default stack */
+    l.movhi r1, hi(default_stack_top)
+    l.ori   r1, r1, lo(default_stack_top)
+
+#if WITH_KERNEL_VM
+    /* invalidate tlbs */
+    l.ori   r3, r0, OR1K_SPR_DMMU_DTLBW_MR_ADDR(0, 0)
+    l.ori   r4, r0, OR1K_SPR_IMMU_ITLBW_MR_ADDR(0, 0)
+    l.addi  r6, r0, 3 /* Maximum number of ways - 1 */
+
+1:  l.addi  r5, r0, 127 /* Maximum number of sets - 1 */
+2:  l.mtspr r3, r0, 0x0
+    l.mtspr r4, r0, 0x0
+
+    l.addi  r3, r3, 1
+    l.addi  r4, r4, 1
+    l.sfeq  r5, r0
+    l.bnf   2b
+     l.addi r5, r5, -1
+
+    l.addi  r3, r3, 128
+    l.addi  r4, r4, 128
+
+    l.sfeq  r6, r0
+    l.bnf   1b
+     l.addi r6, r6, -1
+
+    /* setup initial mappings */
+    get_va_to_pa_offs(r3)
+    l.movhi r4, hi(or1k_kernel_translation_table)
+    l.ori   r4, r4, lo(or1k_kernel_translation_table)
+    l.sub   r4, r4, r3 /* to phys */
+    l.movhi r5, hi(mmu_initial_mappings)
+    l.ori   r5, r5, lo(mmu_initial_mappings)
+    l.sub   r5, r5, r3 /* to phys */
+
+    /* clear the translation table */
+    l.addi  r3, r4, 255*4
+0:  l.sw    0(r3), r0
+    l.sfeq  r3, r4
+    l.bnf   0b
+     l.addi r3, r3, -4
+
+1:  l.lwz   r6, 0(r5) /* phys */
+    l.lwz   r7, 4(r5) /* virt */
+    l.lwz   r8, 8(r5) /* size */
+    l.lwz   r9, 12(r5) /* flags */
+    l.lwz   r10, 16(r5) /* name */
+    l.addi  r5, r5, 20
+
+    /* divide with 16MB */
+    l.srli  r6, r6, 24
+    l.srli  r7, r7, 24
+    l.srli  r8, r8, 24
+
+    l.sfeqi r8, 0
+    l.bf    .Linitial_mapping_done
+     l.nop
+
+2:  l.slli  r3, r7, 2
+    l.add   r3, r4, r3
+    l.slli  r10, r6, 24
+    l.ori   r10, r10, OR1K_MMU_PG_PRESENT | OR1K_MMU_PG_X | OR1K_MMU_PG_W | OR1K_MMU_PG_L
+    l.sfeqi r9, MMU_INITIAL_MAPPING_FLAG_UNCACHED
+    l.bf    3f
+     l.sfeqi r9, MMU_INITIAL_MAPPING_FLAG_DEVICE
+    l.bnf   4f
+     l.nop
+3:  l.ori   r10, r10, OR1K_MMU_PG_CI
+4:  l.sw    0(r3), r10
+    l.addi  r6, r6, 1
+    l.addi  r8, r8, -1
+    l.sfeqi r8, 0
+    l.bnf   2b
+     l.addi r7, r7, 1
+
+    l.j 1b
+     l.nop
+
+.Linitial_mapping_done:
+    /* enable mmu */
+    l.mfspr r3, r0, OR1K_SPR_SYS_SR_ADDR
+    l.ori   r3, r3, OR1K_SPR_SYS_SR_DME_MASK | OR1K_SPR_SYS_SR_IME_MASK
+    l.mtspr r0, r3, OR1K_SPR_SYS_ESR_ADDR(0)
+    /* setup pc to use virtual addresses */
+    l.movhi r3, hi(.+16)
+    l.ori   r3, r3, lo(.+12)
+    l.mtspr r0, r3, OR1K_SPR_SYS_EPCR_ADDR(0)
+    l.rfe
+#endif
+
+    /* invalidate and enable caches */
+    l.jal   arch_invalidate_cache_all
+    l.nop
+    l.jal   arch_enable_cache
+    l.ori  r3, r0, UCACHE
+
+    /* clear bss */
+    l.movhi r3, hi(__bss_start)
+    l.ori   r3, r3, lo(__bss_start)
+    l.movhi r4, hi(__bss_end)
+    l.ori   r4, r4, lo(__bss_end)
+1:  l.sw    0(r3), r0
+    l.sfltu r3, r4
+    l.bf    1b
+     l.addi r3, r3, 4
+
+    /* arguments to main */
+    l.ori   r3, r0, 1
+    l.ori   r4, r0, 2
+    l.ori   r5, r0, 3
+    l.jal   lk_main
+     l.ori  r6, r0, 4
+
+    /* shouldn't happen, but loop if it does */
+    l.j 0
+     l.nop
+
+FUNCTION(return_from_exception)
+    l.lwz   r3, 120(r1)
+    l.mtspr r0, r3, OR1K_SPR_SYS_EPCR_BASE
+    l.lwz   r3, 124(r1)
+    l.mtspr r0, r3, OR1K_SPR_SYS_ESR_BASE
+    l.lwz   r2, 0(r1)
+    l.lwz   r3, 4(r1)
+    l.lwz   r4, 8(r1)
+    l.lwz   r5, 12(r1)
+    l.lwz   r6, 16(r1)
+    l.lwz   r7, 20(r1)
+    l.lwz   r8, 24(r1)
+    l.lwz   r9, 28(r1)
+    l.lwz   r10, 32(r1)
+    l.lwz   r11, 36(r1)
+    l.lwz   r12, 40(r1)
+    l.lwz   r13, 44(r1)
+    l.lwz   r14, 48(r1)
+    l.lwz   r15, 52(r1)
+    l.lwz   r16, 56(r1)
+    l.lwz   r17, 60(r1)
+    l.lwz   r18, 64(r1)
+    l.lwz   r19, 68(r1)
+    l.lwz   r20, 72(r1)
+    l.lwz   r21, 76(r1)
+    l.lwz   r22, 80(r1)
+    l.lwz   r23, 84(r1)
+    l.lwz   r24, 88(r1)
+    l.lwz   r25, 92(r1)
+    l.lwz   r26, 96(r1)
+    l.lwz   r27, 100(r1)
+    l.lwz   r28, 104(r1)
+    l.lwz   r29, 108(r1)
+    l.lwz   r30, 112(r1)
+    l.lwz   r31, 116(r1)
+    l.addi  r1, r1, EXCEPTION_FRAME
+    l.rfe
+
+.section ".bss"
+.align 8
+LOCAL_DATA(default_stack)
+.skip 8192
+LOCAL_DATA(default_stack_top)