[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/bsp/lk/arch/microblaze/arch.c b/src/bsp/lk/arch/microblaze/arch.c
new file mode 100644
index 0000000..3dad646
--- /dev/null
+++ b/src/bsp/lk/arch/microblaze/arch.c
@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2015 Travis Geiselbrecht
+ *
+ * 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 <trace.h>
+#include <debug.h>
+#include <stdint.h>
+#include <arch/microblaze.h>
+
+#define LOCAL_TRACE 0
+
+void arch_early_init(void)
+{
+    LTRACE;
+
+    /* enable i/d cache */
+    uint32_t val = mb_read_msr();
+    val |= (1 << (31 - 26)) | (1 << (31 - 24));
+    mb_write_msr(val);
+}
+
+void arch_init(void)
+{
+    LTRACE;
+}
+
+void arch_idle(void)
+{
+    asm volatile("sleep");
+}
+
+void arch_chain_load(void *entry, ulong arg0, ulong arg1, ulong arg2, ulong arg3)
+{
+    PANIC_UNIMPLEMENTED;
+}
+
+/* unimplemented cache operations */
+void arch_disable_cache(uint flags) { PANIC_UNIMPLEMENTED; }
+void arch_enable_cache(uint flags) { PANIC_UNIMPLEMENTED; }
+
+void arch_clean_cache_range(addr_t start, size_t len) { PANIC_UNIMPLEMENTED; }
+void arch_clean_invalidate_cache_range(addr_t start, size_t len) { PANIC_UNIMPLEMENTED; }
+void arch_invalidate_cache_range(addr_t start, size_t len) { PANIC_UNIMPLEMENTED; }
+void arch_sync_cache_range(addr_t start, size_t len) { PANIC_UNIMPLEMENTED; }
diff --git a/src/bsp/lk/arch/microblaze/asm.S b/src/bsp/lk/arch/microblaze/asm.S
new file mode 100644
index 0000000..24933fd
--- /dev/null
+++ b/src/bsp/lk/arch/microblaze/asm.S
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2015 Travis Geiselbrecht
+ *
+ * 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>
+
+/* void microblaze_context_switch(
+    struct microblaze_context_switch_frame *oldcs,
+    struct microblaze_context_switch_frame *newcs); */
+FUNCTION(microblaze_context_switch)
+    # r5 = oldcs
+    # r6 = newcs
+    swi     r1, r5, 0x0
+    swi     r2, r5, 0x4
+    swi     r13, r5, 0x8
+    swi     r14, r5, 0xc
+    swi     r15, r5, 0x10
+    swi     r16, r5, 0x14
+    swi     r17, r5, 0x18
+    swi     r18, r5, 0x1c
+    swi     r19, r5, 0x20
+    swi     r20, r5, 0x24
+    swi     r21, r5, 0x28
+    swi     r22, r5, 0x2c
+    swi     r23, r5, 0x30
+    swi     r24, r5, 0x34
+    swi     r25, r5, 0x38
+    swi     r26, r5, 0x3c
+    swi     r27, r5, 0x40
+    swi     r28, r5, 0x44
+    swi     r29, r5, 0x48
+    swi     r30, r5, 0x4c
+    swi     r31, r5, 0x50
+
+    # restore the new context
+    lwi     r31, r6, 0x50
+    lwi     r30, r6, 0x4c
+    lwi     r29, r6, 0x48
+    lwi     r28, r6, 0x44
+    lwi     r27, r6, 0x40
+    lwi     r26, r6, 0x3c
+    lwi     r25, r6, 0x38
+    lwi     r24, r6, 0x34
+    lwi     r23, r6, 0x30
+    lwi     r22, r6, 0x2c
+    lwi     r21, r6, 0x28
+    lwi     r20, r6, 0x24
+    lwi     r19, r6, 0x20
+    lwi     r18, r6, 0x1c
+    lwi     r17, r6, 0x18
+    lwi     r16, r6, 0x14
+    lwi     r15, r6, 0x10
+    lwi     r14, r6, 0xc
+    lwi     r13, r6, 0x8
+    lwi     r2, r6, 0x4
+    lwi     r1, r6, 0x0
+
+    rtsd    r15, 8
+    nop
+
diff --git a/src/bsp/lk/arch/microblaze/exceptions.c b/src/bsp/lk/arch/microblaze/exceptions.c
new file mode 100644
index 0000000..857662e
--- /dev/null
+++ b/src/bsp/lk/arch/microblaze/exceptions.c
@@ -0,0 +1,37 @@
+/*
+ * Copyright (c) 2015 Travis Geiselbrecht
+ *
+ * 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 <compiler.h>
+#include <trace.h>
+#include <arch/microblaze.h>
+#include <kernel/thread.h>
+
+void microblaze_irq(void) __attribute__((interrupt_handler));
+
+enum handler_return platform_irq_handler(void);
+
+void microblaze_irq(void)
+{
+    if (platform_irq_handler() == INT_RESCHEDULE)
+        thread_preempt();
+}
+
diff --git a/src/bsp/lk/arch/microblaze/include/arch/arch_ops.h b/src/bsp/lk/arch/microblaze/include/arch/arch_ops.h
new file mode 100644
index 0000000..8646f34
--- /dev/null
+++ b/src/bsp/lk/arch/microblaze/include/arch/arch_ops.h
@@ -0,0 +1,109 @@
+/*
+ * Copyright (c) 2015 Travis Geiselbrecht
+ *
+ * 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.
+ */
+#pragma once
+
+#include <compiler.h>
+
+#define USE_MSRSET 1
+
+static inline void arch_enable_ints(void)
+{
+    CF;
+    uint32_t temp;
+    __asm__ volatile(
+#if USE_MSRSET
+        "msrset %0, (1<<1)"
+#else
+        "mfs    %0, rmsr;"
+        "ori    %0, %0, (1<<1);"
+        "mts    rmsr, %0"
+#endif
+        : "=r" (temp));
+}
+
+static inline void arch_disable_ints(void)
+{
+    uint32_t temp;
+    __asm__ volatile(
+#if USE_MSRSET
+        "msrclr %0, (1<<1)"
+#else
+        "mfs    %0, rmsr;"
+        "andni  %0, %0, (1<<1);"
+        "mts    rmsr, %0"
+#endif
+        : "=r" (temp));
+    CF;
+}
+
+static inline bool arch_ints_disabled(void)
+{
+    uint32_t state;
+
+    __asm__ volatile(
+        "mfs    %0, rmsr;"
+        : "=r" (state));
+
+    return !(state & (1<<1));
+}
+
+static inline int atomic_add(volatile int *ptr, int val)
+{
+    return __atomic_fetch_add(ptr, val, __ATOMIC_RELAXED);
+}
+
+static inline int atomic_or(volatile int *ptr, int val)
+{
+    return __atomic_fetch_or(ptr, val, __ATOMIC_RELAXED);
+}
+
+static inline int atomic_and(volatile int *ptr, int val)
+{
+    return __atomic_fetch_and(ptr, val, __ATOMIC_RELAXED);
+}
+
+static inline int atomic_swap(volatile int *ptr, int val)
+{
+    return __atomic_exchange_n(ptr, val, __ATOMIC_RELAXED);
+}
+
+/* use a global pointer to store the current_thread */
+extern struct thread *_current_thread;
+
+static inline struct thread *get_current_thread(void)
+{
+    return _current_thread;
+}
+
+static inline void set_current_thread(struct thread *t)
+{
+    _current_thread = t;
+}
+
+static inline uint32_t arch_cycle_count(void) { return 0; }
+
+static inline uint arch_curr_cpu_num(void)
+{
+    return 0;
+}
+
diff --git a/src/bsp/lk/arch/microblaze/include/arch/arch_thread.h b/src/bsp/lk/arch/microblaze/include/arch/arch_thread.h
new file mode 100644
index 0000000..baa650c
--- /dev/null
+++ b/src/bsp/lk/arch/microblaze/include/arch/arch_thread.h
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2015 Travis Geiselbrecht
+ *
+ * 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.
+ */
+#pragma once
+
+#include <sys/types.h>
+
+struct microblaze_context_switch_frame {
+    uint32_t r1; // stack pointer
+    uint32_t r2; // read-only small data base pointer
+
+    uint32_t r13; // read-write small data base pointer
+    uint32_t r14;
+    uint32_t r15; // link register
+    uint32_t r16;
+    uint32_t r17;
+    uint32_t r18;
+
+    /* callee saved */
+    uint32_t r19;
+    uint32_t r20;
+    uint32_t r21;
+    uint32_t r22;
+    uint32_t r23;
+    uint32_t r24;
+    uint32_t r25;
+    uint32_t r26;
+    uint32_t r27;
+    uint32_t r28;
+    uint32_t r29;
+    uint32_t r30;
+    uint32_t r31;
+};
+
+struct arch_thread {
+    struct microblaze_context_switch_frame cs_frame;
+};
+
+void microblaze_context_switch(struct microblaze_context_switch_frame *oldcs,
+    struct microblaze_context_switch_frame *newcs);
+
diff --git a/src/bsp/lk/arch/microblaze/include/arch/defines.h b/src/bsp/lk/arch/microblaze/include/arch/defines.h
new file mode 100644
index 0000000..2d3d8e7
--- /dev/null
+++ b/src/bsp/lk/arch/microblaze/include/arch/defines.h
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2015 Travis Geiselbrecht
+ *
+ * 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.
+ */
+#pragma once
+
+#define PAGE_SIZE 4096
+#define PAGE_SIZE_SHIFT 12
+
+// XXX is this right?
+#define CACHE_LINE 32
+
+#define ARCH_DEFAULT_STACK_SIZE 4096
diff --git a/src/bsp/lk/arch/microblaze/include/arch/microblaze.h b/src/bsp/lk/arch/microblaze/include/arch/microblaze.h
new file mode 100644
index 0000000..3f14333
--- /dev/null
+++ b/src/bsp/lk/arch/microblaze/include/arch/microblaze.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015 Travis Geiselbrecht
+ *
+ * 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.
+ */
+#pragma once
+
+static inline uint32_t mb_read_msr(void)
+{
+    uint32_t temp;
+    __asm__ volatile(
+        "mfs    %0, rmsr;" : "=r" (temp));
+
+    return temp;
+}
+
+static inline void mb_write_msr(uint32_t val)
+{
+    __asm__ volatile(
+        "mts    rmsr, %0" :: "r" (val));
+}
+
+
diff --git a/src/bsp/lk/arch/microblaze/include/arch/spinlock.h b/src/bsp/lk/arch/microblaze/include/arch/spinlock.h
new file mode 100644
index 0000000..5c50c5b
--- /dev/null
+++ b/src/bsp/lk/arch/microblaze/include/arch/spinlock.h
@@ -0,0 +1,92 @@
+/*
+ * Copyright (c) 2015 Travis Geiselbrecht
+ *
+ * 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.
+ */
+#pragma once
+
+#include <arch/ops.h>
+#include <stdbool.h>
+
+#if WITH_SMP
+#error microblaze does not support SMP
+#endif
+
+#define SPIN_LOCK_INITIAL_VALUE (0)
+
+typedef unsigned int spin_lock_t;
+
+typedef unsigned int spin_lock_saved_state_t;
+typedef unsigned int spin_lock_save_flags_t;
+
+static inline void arch_spin_lock(spin_lock_t *lock)
+{
+    *lock = 1;
+}
+
+static inline int arch_spin_trylock(spin_lock_t *lock)
+{
+    return 0;
+}
+
+static inline void arch_spin_unlock(spin_lock_t *lock)
+{
+    *lock = 0;
+}
+
+static inline void arch_spin_lock_init(spin_lock_t *lock)
+{
+    *lock = SPIN_LOCK_INITIAL_VALUE;
+}
+
+static inline bool arch_spin_lock_held(spin_lock_t *lock)
+{
+    return *lock != 0;
+}
+
+    /* default arm flag is to just disable plain irqs */
+#define ARCH_DEFAULT_SPIN_LOCK_FLAG_INTERRUPTS  0
+
+enum {
+    /* private */
+    SPIN_LOCK_STATE_RESTORE_IRQ = 1,
+};
+
+static inline void
+arch_interrupt_save(spin_lock_saved_state_t *statep, spin_lock_save_flags_t flags)
+{
+    spin_lock_saved_state_t state = 0;
+    if (!arch_ints_disabled()) {
+        state |= SPIN_LOCK_STATE_RESTORE_IRQ;
+        arch_disable_ints();
+    }
+    *statep = state;
+}
+
+static inline void
+arch_interrupt_restore(spin_lock_saved_state_t old_state, spin_lock_save_flags_t flags)
+{
+    if (old_state & SPIN_LOCK_STATE_RESTORE_IRQ)
+        arch_enable_ints();
+}
+
+
+
+
diff --git a/src/bsp/lk/arch/microblaze/linker.ld b/src/bsp/lk/arch/microblaze/linker.ld
new file mode 100644
index 0000000..5c549e7
--- /dev/null
+++ b/src/bsp/lk/arch/microblaze/linker.ld
@@ -0,0 +1,129 @@
+OUTPUT_FORMAT("elf32-microblaze", "elf32-microblaze", "elf32-microblaze")
+OUTPUT_ARCH(microblaze)
+
+ENTRY(_start)
+SECTIONS
+{
+    . = %KERNEL_BASE% + %KERNEL_LOAD_OFFSET%;
+
+    _start = .;
+
+    /* vector table goes at 0, for qemu target, at least */
+    .vectors : AT(%VECTOR_BASE_PHYS%) {
+        KEEP(*(.vectors))
+    }
+
+    /* text/read-only data */
+    /* set the load address to physical MEMBASE */
+    .text : AT(%MEMBASE% + %KERNEL_LOAD_OFFSET% + SIZEOF(.vectors)) {
+        KEEP(*(.text.boot))
+        *(.text* .gnu.linkonce.t.*)
+    }
+
+    .interp : { *(.interp) }
+    .hash : { *(.hash) }
+    .dynsym : { *(.dynsym) }
+    .dynstr : { *(.dynstr) }
+    .rel.text : { *(.rel.text) *(.rel.gnu.linkonce.t*) }
+    .rela.text : { *(.rela.text) *(.rela.gnu.linkonce.t*) }
+    .rel.data : { *(.rel.data) *(.rel.gnu.linkonce.d*) }
+    .rela.data : { *(.rela.data) *(.rela.gnu.linkonce.d*) }
+    .rel.rodata : { *(.rel.rodata) *(.rel.gnu.linkonce.r*) }
+    .rela.rodata : { *(.rela.rodata) *(.rela.gnu.linkonce.r*) }
+    .rel.got : { *(.rel.got) }
+    .rela.got : { *(.rela.got) }
+    .rel.ctors : { *(.rel.ctors) }
+    .rela.ctors : { *(.rela.ctors) }
+    .rel.dtors : { *(.rel.dtors) }
+    .rela.dtors : { *(.rela.dtors) }
+    .rel.init : { *(.rel.init) }
+    .rela.init : { *(.rela.init) }
+    .rel.fini : { *(.rel.fini) }
+    .rela.fini : { *(.rela.fini) }
+    .rel.bss : { *(.rel.bss) }
+    .rela.bss : { *(.rela.bss) }
+    .rel.plt : { *(.rel.plt) }
+    .rela.plt : { *(.rela.plt) }
+    .init : { *(.init) }
+    .plt : { *(.plt) }
+
+    .rodata : ALIGN(4) {
+        __rodata_start = .;
+        *(.rodata .rodata.* .gnu.linkonce.r.*)
+        . = ALIGN(4);
+        _SDATA2_START__ = .;
+        *(.sdata2)
+        _SDATA2_END__ = .;
+    }
+
+    /*
+     * extra linker scripts tend to insert sections just after .rodata,
+     * so we want to make sure this symbol comes after anything inserted above,
+     * but not aligned to the next section necessarily.
+     */
+    .dummy_post_rodata : {
+        __rodata_end = .;
+    }
+
+    .data : ALIGN(4) {
+        /* writable data  */
+        __data_start_rom = .;
+        /* in one segment binaries, the rom data address is on top of the ram data address */
+        __data_start = .;
+        *(.data .data.* .gnu.linkonce.d.*)
+        __ctor_list = .;
+        KEEP(*(.ctors .init_array))
+        __ctor_end = .;
+        __dtor_list = .;
+        KEEP(*(.dtors .fini_array))
+        __dtor_end = .;
+        *(.got*)
+        *(.dynamic)
+
+        /* read-write small data with initial value */
+        _SDATA_START__ = .;
+        *(.sdata)
+        _SDATA_END__ = .;
+    }
+
+    /*
+     * extra linker scripts tend to insert sections just after .data,
+     * so we want to make sure this symbol comes after anything inserted above,
+     * but not aligned to the next section necessarily.
+     */
+    .dummy_post_data : {
+        __data_end = .;
+    }
+
+    /* unintialized data (in same segment as writable data) */
+    .bss : ALIGN(4) {
+        __bss_start = .;
+
+        /* read only small variables without initial value */
+        _SBSS2_START__ = .;
+        *(.sbss2*)
+        _SBSS2_END__ = .;
+
+        /* read-write small variables without initial value */
+        _sbss_start__ = .;
+        *(.sbss*)
+        _sbss_end__ = .;
+
+        /* regular bss */
+        *(.bss .bss.*)
+        *(.gnu.linkonce.b.*)
+        *(COMMON)
+
+        . = ALIGN(4);
+        __bss_end = .;
+    }
+
+    _end = .;
+
+    . = %KERNEL_BASE% + %MEMSIZE%;
+    _end_of_ram = .;
+
+    /* Strip unnecessary stuff */
+    /DISCARD/ : { *(.comment .note .eh_frame) }
+}
+
diff --git a/src/bsp/lk/arch/microblaze/rules.mk b/src/bsp/lk/arch/microblaze/rules.mk
new file mode 100644
index 0000000..86f4a11
--- /dev/null
+++ b/src/bsp/lk/arch/microblaze/rules.mk
@@ -0,0 +1,70 @@
+LOCAL_DIR := $(GET_LOCAL_DIR)
+
+MODULE := $(LOCAL_DIR)
+
+MODULE_SRCS += \
+	$(LOCAL_DIR)/start.S \
+	$(LOCAL_DIR)/arch.c \
+	$(LOCAL_DIR)/asm.S \
+	$(LOCAL_DIR)/exceptions.c \
+	$(LOCAL_DIR)/thread.c \
+
+#	$(LOCAL_DIR)/cache.c \
+	$(LOCAL_DIR)/cache-ops.S \
+	$(LOCAL_DIR)/ops.S \
+	$(LOCAL_DIR)/mmu.c \
+	$(LOCAL_DIR)/faults.c \
+	$(LOCAL_DIR)/descriptor.c
+
+GLOBAL_DEFINES += \
+	SMP_MAX_CPUS=1
+
+# set the default toolchain to microblaze elf and set a #define
+ifndef TOOLCHAIN_PREFIX
+TOOLCHAIN_PREFIX := microblaze-elf-
+endif
+
+WITH_LINKER_GC ?= 0
+
+LITTLE_ENDIAN ?= 0
+
+ifneq ($(LITTLE_ENDIAN),0)
+GLOBAL_COMPILEFLAGS += -mlittle-endian
+GLOBAL_LDFLAGS += -EL
+GLOBAL_MODULE_LDFLAGS += -EL
+endif
+
+
+cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc /dev/null 2>&1`"; \
+	then echo "$(2)"; else echo "$(3)"; fi ;)
+
+ARCH_COMPILEFLAGS :=
+ARCH_OPTFLAGS := -O2
+
+GLOBAL_LDFLAGS += -relax
+
+KERNEL_BASE ?= $(MEMBASE)
+KERNEL_LOAD_OFFSET ?= 0
+VECTOR_BASE_PHYS ?= 0
+
+GLOBAL_DEFINES += \
+    MEMBASE=$(MEMBASE) \
+    MEMSIZE=$(MEMSIZE)
+
+# potentially generated files that should be cleaned out with clean make rule
+GENERATED += \
+	$(BUILDDIR)/linker.ld
+
+# rules for generating the linker
+$(BUILDDIR)/linker.ld: $(LOCAL_DIR)/linker.ld $(wildcard arch/*.ld) linkerscript.phony
+	@echo generating $@
+	@$(MKDIR)
+	$(NOECHO)sed "s/%MEMBASE%/$(MEMBASE)/;s/%MEMSIZE%/$(MEMSIZE)/;s/%KERNEL_BASE%/$(KERNEL_BASE)/;s/%KERNEL_LOAD_OFFSET%/$(KERNEL_LOAD_OFFSET)/;s/%VECTOR_BASE_PHYS%/$(VECTOR_BASE_PHYS)/" < $< > $@.tmp
+	@$(call TESTANDREPLACEFILE,$@.tmp,$@)
+
+linkerscript.phony:
+.PHONY: linkerscript.phony
+
+LINKER_SCRIPT += $(BUILDDIR)/linker.ld
+
+include make/module.mk
diff --git a/src/bsp/lk/arch/microblaze/start.S b/src/bsp/lk/arch/microblaze/start.S
new file mode 100644
index 0000000..744f0d6
--- /dev/null
+++ b/src/bsp/lk/arch/microblaze/start.S
@@ -0,0 +1,82 @@
+/*
+ * Copyright (c) 2015 Travis Geiselbrecht
+ *
+ * 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>
+
+.section ".vectors", "ax"
+.globl _vectab
+_vectab:
+/* vector table here */
+    # start vector
+    brai start
+    # user exception
+    brai unhandled_exception
+    # interrupt
+    brai microblaze_irq
+    # break
+    brai unhandled_exception
+    # hardware exception
+    brai unhandled_exception
+
+    # reserved for future
+.fill (0x50 - 0x28)
+
+.section ".text.boot"
+FUNCTION(start)
+    # set the default stack
+    addik   r1, r0, default_stack_top
+
+    # set up small data pointers
+    addik   r2, r0, _SDATA2_START__
+    addik   r13, r0, _SDATA_START__
+
+    # set the processor mode to default
+    mts     rmsr, r0
+
+    # zero out bss sections
+    addik   r5, r0, __bss_start
+    addik   r6, r0, 0
+    rsubik  r7, r5, __bss_end
+    brlid   r15, memset
+    nop
+
+    # arguments to main
+    addik   r5, r0, 1
+    addik   r6, r0, 2
+    addik   r7, r0, 3
+    brlid   r15, lk_main
+    addik   r8, r0, 4
+
+    # shouldn't be here
+    bri     .
+
+FUNCTION(unhandled_exception)
+    bri     .
+
+.bss
+.align 3
+LOCAL_DATA(default_stack)
+    .skip 4096
+LOCAL_DATA(default_stack_top)
+
+/* vim: set ts=4 sw=4 expandtab: */
+
diff --git a/src/bsp/lk/arch/microblaze/thread.c b/src/bsp/lk/arch/microblaze/thread.c
new file mode 100644
index 0000000..41410bd
--- /dev/null
+++ b/src/bsp/lk/arch/microblaze/thread.c
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2015 Travis Geiselbrecht
+ *
+ * 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 <debug.h>
+#include <trace.h>
+#include <sys/types.h>
+#include <string.h>
+#include <stdlib.h>
+#include <kernel/thread.h>
+#include <arch/microblaze.h>
+
+#define LOCAL_TRACE 0
+
+struct thread *_current_thread;
+
+static void initial_thread_func(void) __NO_RETURN;
+static void initial_thread_func(void)
+{
+    thread_t *ct = get_current_thread();
+
+#if LOCAL_TRACE
+    LTRACEF("thread %p calling %p with arg %p\n", ct, ct->entry, ct->arg);
+    dump_thread(ct);
+#endif
+
+    /* release the thread lock that was implicitly held across the reschedule */
+    spin_unlock(&thread_lock);
+    arch_enable_ints();
+
+    int ret = ct->entry(ct->arg);
+
+    LTRACEF("thread %p exiting with %d\n", ct, ret);
+
+    thread_exit(ret);
+}
+
+void arch_thread_initialize(thread_t *t)
+{
+    LTRACEF("t %p (%s)\n", t, t->name);
+
+    /* some registers we want to clone for the new thread */
+    register uint32_t r2 asm("r2");
+    register uint32_t r13 asm("r13");
+
+    /* zero out the thread context */
+    memset(&t->arch.cs_frame, 0, sizeof(t->arch.cs_frame));
+
+    t->arch.cs_frame.r1 = (vaddr_t)t->stack + t->stack_size;
+    t->arch.cs_frame.r2 = r2;
+    t->arch.cs_frame.r13 = r13;
+    t->arch.cs_frame.r15 = (vaddr_t)&initial_thread_func;
+    // NOTE: appears to be bug in binutils 2.25 that forces us to -8 from the offset
+    // using this method if gc-sections is enabled.
+    *(volatile uint32_t *)&t->arch.cs_frame.r15 -= 8;
+}
+
+void arch_context_switch(thread_t *oldthread, thread_t *newthread)
+{
+    LTRACEF("old %p (%s), new %p (%s)\n", oldthread, oldthread->name, newthread, newthread->name);
+
+    microblaze_context_switch(&oldthread->arch.cs_frame, &newthread->arch.cs_frame);
+}
+
+void arch_dump_thread(thread_t *t)
+{
+    if (t->state != THREAD_RUNNING) {
+        dprintf(INFO, "\tarch: ");
+        dprintf(INFO, "sp 0x%x\n", t->arch.cs_frame.r1);
+    }
+}
+