[Feature]add MT2731_MP2_MR2_SVN388 baseline version

Change-Id: Ief04314834b31e27effab435d3ca8ba33b499059
diff --git a/src/bsp/lk/platform/pc/platform.c b/src/bsp/lk/platform/pc/platform.c
new file mode 100644
index 0000000..d97190c
--- /dev/null
+++ b/src/bsp/lk/platform/pc/platform.c
@@ -0,0 +1,250 @@
+/*
+ * Copyright (c) 2009 Corey Tabaka
+ * Copyright (c) 2015 Intel Corporation
+ *
+ * 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 <err.h>
+#include <trace.h>
+#include <arch/x86/mmu.h>
+#include <platform.h>
+#include "platform_p.h"
+#include <platform/pc.h>
+#include <platform/multiboot.h>
+#include <platform/console.h>
+#include <platform/keyboard.h>
+#include <dev/pci.h>
+#include <dev/uart.h>
+#include <arch/x86.h>
+#include <arch/mmu.h>
+#include <malloc.h>
+#include <string.h>
+#include <assert.h>
+#include <kernel/vm.h>
+
+extern multiboot_info_t *_multiboot_info;
+
+#define DEFAULT_MEMEND (16*1024*1024)
+
+#ifdef WITH_KERNEL_VM
+extern int _end;
+static uintptr_t _heap_end = (uintptr_t)DEFAULT_MEMEND;
+#else
+extern uintptr_t _heap_end;
+#endif
+extern uint64_t __code_start;
+extern uint64_t __code_end;
+extern uint64_t __rodata_start;
+extern uint64_t __rodata_end;
+extern uint64_t __data_start;
+extern uint64_t __data_end;
+extern uint64_t __bss_start;
+extern uint64_t __bss_end;
+extern void pci_init(void);
+extern void arch_mmu_init(void);
+
+/* Address width including virtual/physical address*/
+uint8_t g_vaddr_width = 0;
+uint8_t g_paddr_width = 0;
+
+/* Kernel global CR3 */
+map_addr_t g_CR3 = 0;
+
+void platform_init_mmu_mappings(void)
+{
+    struct map_range range;
+    arch_flags_t access;
+    map_addr_t *init_table, phy_init_table;
+    uint32_t   addr_width;
+
+    /* getting the address width from CPUID instr */
+    /* Bits 07-00: Physical Address width info */
+    /* Bits 15-08: Linear Address width info */
+    addr_width    = x86_get_address_width();
+    g_paddr_width = (uint8_t)(addr_width & 0xFF);
+    g_vaddr_width = (uint8_t)((addr_width >> 8) & 0xFF);
+
+    /* Creating the First page in the page table hirerachy */
+    /* Can be pml4, pdpt or pdt based on x86_64, x86 PAE mode & x86 non-PAE mode respectively */
+    init_table = memalign(PAGE_SIZE, PAGE_SIZE);
+    ASSERT(init_table);
+    memset(init_table, 0, PAGE_SIZE);
+
+    phy_init_table = (map_addr_t)X86_VIRT_TO_PHYS(init_table);
+
+    /* kernel code section mapping */
+    access = ARCH_MMU_FLAG_PERM_RO;
+    range.start_vaddr = range.start_paddr = (map_addr_t) &__code_start;
+    range.size = ((map_addr_t)&__code_end) - ((map_addr_t)&__code_start);
+    x86_mmu_map_range(phy_init_table, &range, access);
+
+    /* kernel data section mapping */
+    access = 0;
+#if defined(ARCH_X86_64) || defined(PAE_MODE_ENABLED)
+    access |= ARCH_MMU_FLAG_PERM_NO_EXECUTE;
+#endif
+    range.start_vaddr = range.start_paddr = (map_addr_t) &__data_start;
+    range.size = ((map_addr_t)&__data_end) - ((map_addr_t)&__data_start);
+    x86_mmu_map_range(phy_init_table, &range, access);
+
+    /* kernel rodata section mapping */
+    access = ARCH_MMU_FLAG_PERM_RO;
+#if defined(ARCH_X86_64) || defined(PAE_MODE_ENABLED)
+    access |= ARCH_MMU_FLAG_PERM_NO_EXECUTE;
+#endif
+    range.start_vaddr = range.start_paddr = (map_addr_t) &__rodata_start;
+    range.size = ((map_addr_t)&__rodata_end) - ((map_addr_t)&__rodata_start);
+    x86_mmu_map_range(phy_init_table, &range, access);
+
+    /* kernel bss section and kernel heap mappings */
+    access = 0;
+#ifdef ARCH_X86_64
+    access |= ARCH_MMU_FLAG_PERM_NO_EXECUTE;
+#endif
+    range.start_vaddr = range.start_paddr = (map_addr_t) &__bss_start;
+    range.size = ((map_addr_t)_heap_end) - ((map_addr_t)&__bss_start);
+    x86_mmu_map_range(phy_init_table, &range, access);
+
+    /* Mapping for BIOS, devices */
+    access = 0;
+    range.start_vaddr = range.start_paddr = (map_addr_t) 0;
+    range.size = ((map_addr_t)&__code_start);
+    x86_mmu_map_range(phy_init_table, &range, access);
+
+    /* Moving to the new CR3 */
+    g_CR3 = (map_addr_t)phy_init_table;
+    x86_set_cr3((map_addr_t)phy_init_table);
+}
+
+#if WITH_KERNEL_VM
+struct mmu_initial_mapping mmu_initial_mappings[] = {
+    /* all of detected memory */
+    {
+        .phys = MEMBASE,
+        .virt = MEMBASE,
+        .size = DEFAULT_MEMEND - MEMBASE,
+        .flags = 0,
+        .name = "memory"
+    },
+
+    /* null entry to terminate the list */
+    { 0 }
+};
+
+/* set up the size of the identity map of physical ram to virtual at the base
+ * of the kernel to match what we detected in platform_init_multiboot_info()
+ */
+void initial_mapping_init(void)
+{
+    /* tweak the amount of physical memory map we have mapped
+     * in the mmu_initial_mappings table, which is used by the vm
+     * for reverse lookups of memory in the kernel area */
+    mmu_initial_mappings[0].size = _heap_end - mmu_initial_mappings[0].virt;
+}
+
+static pmm_arena_t mem_arena = {
+    .name = "memory",
+    .base = MEMBASE, /* start 2MB into memory */
+    .size = DEFAULT_MEMEND, /* default amount of memory in case we don't have multiboot */
+    .priority = 1,
+    .flags = PMM_ARENA_FLAG_KMAP
+};
+
+/* set up the size of the physical memory map based on the end of memory we detected in
+ * platform_init_multiboot_info()
+ */
+void mem_arena_init(void)
+{
+    uintptr_t mem_base = ((uintptr_t)MEMBASE);
+    uintptr_t mem_size = (uintptr_t)_heap_end - (uintptr_t)mem_base;
+
+    mem_arena.base = PAGE_ALIGN(mem_base);
+    mem_arena.size = PAGE_ALIGN(mem_size);
+}
+#endif
+
+void platform_init_multiboot_info(void)
+{
+    if (_multiboot_info) {
+        if (_multiboot_info->flags & MB_INFO_MEM_SIZE) {
+            _heap_end = _multiboot_info->mem_upper * 1024;
+        }
+
+        if (_multiboot_info->flags & MB_INFO_MMAP) {
+            memory_map_t *mmap = (memory_map_t *)(uintptr_t)(_multiboot_info->mmap_addr - 4);
+
+            for (uint i = 0; i < _multiboot_info->mmap_length / sizeof(memory_map_t); i++) {
+
+                if (mmap[i].type == MB_MMAP_TYPE_AVAILABLE && mmap[i].base_addr_low >= _heap_end) {
+                    _heap_end = mmap[i].base_addr_low + mmap[i].length_low;
+                } else if (mmap[i].type != MB_MMAP_TYPE_AVAILABLE && mmap[i].base_addr_low >= _heap_end) {
+                    /*
+                     * break on first memory hole above default heap end for now.
+                     * later we can add facilities for adding free chunks to the
+                     * heap for each segregated memory region.
+                     */
+                    break;
+                }
+            }
+        }
+    }
+}
+
+void platform_early_init(void)
+{
+
+    platform_init_uart();
+
+    /* get the text console working */
+    platform_init_console();
+
+    /* initialize the interrupt controller */
+    platform_init_interrupts();
+
+    /* initialize the timer */
+    platform_init_timer();
+
+    /* look at multiboot to determine our memory size */
+    platform_init_multiboot_info();
+
+#ifdef WITH_KERNEL_VM
+    initial_mapping_init();
+    mem_arena_init();
+    pmm_add_arena(&mem_arena);
+#endif
+}
+
+void platform_init(void)
+{
+    uart_init();
+
+    platform_init_keyboard();
+#if defined(ARCH_X86)
+    pci_init();
+#endif
+
+    /* MMU init for x86 Archs done after the heap is setup */
+    // XXX move this into arch/
+    arch_mmu_init();
+    platform_init_mmu_mappings();
+}
+
+/* vim: set noexpandtab: */