[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)