x86: Add basic support to queensbay platform and crownbay board
authorBin Meng <bmeng.cn@gmail.com>
Wed, 17 Dec 2014 07:50:36 +0000 (15:50 +0800)
committerSimon Glass <sjg@chromium.org>
Fri, 19 Dec 2014 00:26:06 +0000 (17:26 -0700)
Implement minimum required functions for the basic support to
queensbay platform and crownbay board.

Currently the implementation is to call fsp_init() in the car_init().
We may move that call to cpu_init_f() in the future.

Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
Acked-by: Simon Glass <sjg@chromium.org>
arch/x86/cpu/queensbay/Makefile [new file with mode: 0644]
arch/x86/cpu/queensbay/tnc.c [new file with mode: 0644]
arch/x86/cpu/queensbay/tnc_car.S [new file with mode: 0644]
arch/x86/cpu/queensbay/tnc_dram.c [new file with mode: 0644]
arch/x86/cpu/queensbay/tnc_pci.c [new file with mode: 0644]
arch/x86/include/asm/ibmpc.h
board/intel/crownbay/MAINTAINERS [new file with mode: 0644]
board/intel/crownbay/Makefile [new file with mode: 0644]
board/intel/crownbay/crownbay.c [new file with mode: 0644]
board/intel/crownbay/start.S [new file with mode: 0644]

diff --git a/arch/x86/cpu/queensbay/Makefile b/arch/x86/cpu/queensbay/Makefile
new file mode 100644 (file)
index 0000000..ace04ca
--- /dev/null
@@ -0,0 +1,9 @@
+#
+# Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y += tnc_car.o tnc_dram.o tnc.o
+obj-y += fsp_configs.o fsp_support.o
+obj-$(CONFIG_PCI) += tnc_pci.o
diff --git a/arch/x86/cpu/queensbay/tnc.c b/arch/x86/cpu/queensbay/tnc.c
new file mode 100644 (file)
index 0000000..8b9815f
--- /dev/null
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+#include <asm/post.h>
+#include <asm/arch/fsp/fsp_support.h>
+#include <asm/processor.h>
+
+int arch_cpu_init(void)
+{
+       post_code(POST_CPU_INIT);
+#ifdef CONFIG_SYS_X86_TSC_TIMER
+       timer_set_base(rdtsc());
+#endif
+
+       return x86_cpu_init_f();
+}
+
+int print_cpuinfo(void)
+{
+       post_code(POST_CPU_INFO);
+       return default_print_cpuinfo();
+}
+
+void reset_cpu(ulong addr)
+{
+       /* cold reset */
+       outb(0x06, PORT_RESET);
+}
+
+void board_final_cleanup(void)
+{
+       u32 status;
+
+       /* call into FspNotify */
+       debug("Calling into FSP (notify phase INIT_PHASE_BOOT): ");
+       status = fsp_notify(NULL, INIT_PHASE_BOOT);
+       if (status != FSP_SUCCESS)
+               debug("fail, error code %x\n", status);
+       else
+               debug("OK\n");
+
+       return;
+}
diff --git a/arch/x86/cpu/queensbay/tnc_car.S b/arch/x86/cpu/queensbay/tnc_car.S
new file mode 100644 (file)
index 0000000..6834a64
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <config.h>
+#include <asm/post.h>
+
+.globl car_init
+car_init:
+       /*
+        * Note: ebp holds the BIST value (built-in self test) so far, but ebp
+        * will be destroyed through the FSP call, thus we have to test the
+        * BIST value here before we call into FSP.
+        */
+       test    %ebp, %ebp
+       jz      car_init_start
+       post_code(POST_BIST_FAILURE)
+       jmp     die
+
+car_init_start:
+       post_code(POST_CAR_START)
+       lea     find_fsp_header_romstack, %esp
+       jmp     find_fsp_header
+
+find_fsp_header_ret:
+       /* EAX points to FSP_INFO_HEADER */
+       mov     %eax, %ebp
+
+       /* sanity test */
+       cmp     $CONFIG_FSP_LOCATION, %eax
+       jb      die
+
+       /* calculate TempRamInitEntry address */
+       mov     0x30(%ebp), %eax
+       add     0x1c(%ebp), %eax
+
+       /* call FSP TempRamInitEntry to setup temporary stack */
+       lea     temp_ram_init_romstack, %esp
+       jmp     *%eax
+
+temp_ram_init_ret:
+       addl    $4, %esp
+       cmp     $0, %eax
+       jnz     car_init_fail
+
+       post_code(POST_CAR_CPU_CACHE)
+
+       /*
+        * The FSP TempRamInit initializes the ecx and edx registers to
+        * point to a temporary but writable memory range (Cache-As-RAM).
+        * ecx: the start of this temporary memory range,
+        * edx: the end of this range.
+        */
+
+       /* stack grows down from top of CAR */
+       movl    %edx, %esp
+
+       /*
+        * TODO:
+        *
+        * According to FSP architecture spec, the fsp_init() will not return
+        * to its caller, instead it requires the bootloader to provide a
+        * so-called continuation function to pass into the FSP as a parameter
+        * of fsp_init, and fsp_init() will call that continuation function
+        * directly.
+        *
+        * The call to fsp_init() may need to be moved out of the car_init()
+        * to cpu_init_f() with the help of some inline assembly codes.
+        * Note there is another issue that fsp_init() will setup another stack
+        * using the fsp_init parameter stack_top after DRAM is initialized,
+        * which means any data on the previous stack (on the CAR) gets lost
+        * (ie: U-Boot global_data). FSP is supposed to support such scenario,
+        * however it does not work. This should be revisited in the future.
+        */
+       movl    $CONFIG_FSP_TEMP_RAM_ADDR, %eax
+       xorl    %edx, %edx
+       xorl    %ecx, %ecx
+       call    fsp_init
+
+.global fsp_init_done
+fsp_init_done:
+       /*
+        * We come here from FspInit with eax pointing to the HOB list.
+        * Save eax to esi temporarily.
+        */
+       movl    %eax, %esi
+       /*
+        * Re-initialize the ebp (BIST) to zero, as we already reach here
+        * which means we passed BIST testing before.
+        */
+       xorl    %ebp, %ebp
+       jmp     car_init_ret
+
+car_init_fail:
+       post_code(POST_CAR_FAILURE)
+
+die:
+       hlt
+       jmp     die
+       hlt
+
+       /*
+        * The function call before CAR initialization is tricky. It cannot
+        * be called using the 'call' instruction but only the 'jmp' with
+        * the help of a handcrafted stack in the ROM. The stack needs to
+        * contain the function return address as well as the parameters.
+        */
+       .balign 4
+find_fsp_header_romstack:
+       .long   find_fsp_header_ret
+
+       .balign 4
+temp_ram_init_romstack:
+       .long   temp_ram_init_ret
+       .long   temp_ram_init_params
+temp_ram_init_params:
+       .long   ucode_start             /* microcode base */
+       .long   ucode_size              /* microcode size */
+       .long   CONFIG_SYS_MONITOR_BASE /* code region base */
+       .long   CONFIG_SYS_MONITOR_LEN  /* code region size */
+
+       .balign 4
+ucode_start:
+       .include "arch/x86/cpu/queensbay/M0220661105.inc"
+ucode_size = ( . - ucode_start)
diff --git a/arch/x86/cpu/queensbay/tnc_dram.c b/arch/x86/cpu/queensbay/tnc_dram.c
new file mode 100644 (file)
index 0000000..dbc1710
--- /dev/null
@@ -0,0 +1,78 @@
+/*
+ * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/fsp/fsp_support.h>
+#include <asm/e820.h>
+#include <asm/post.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int dram_init(void)
+{
+       phys_size_t ram_size = 0;
+       union hob_pointers_t hob;
+
+       hob.raw = gd->arch.hob_list;
+       while (!END_OF_HOB(hob)) {
+               if (hob.hdr->type == HOB_TYPE_RES_DESC) {
+                       if (hob.res_desc->type == RES_SYS_MEM ||
+                           hob.res_desc->type == RES_MEM_RESERVED) {
+                               ram_size += hob.res_desc->len;
+                       }
+               }
+               hob.raw = GET_NEXT_HOB(hob);
+       }
+
+       gd->ram_size = ram_size;
+       post_code(POST_DRAM);
+
+       return 0;
+}
+
+void dram_init_banksize(void)
+{
+       gd->bd->bi_dram[0].start = 0;
+       gd->bd->bi_dram[0].size = gd->ram_size;
+}
+
+/*
+ * This function looks for the highest region of memory lower than 4GB which
+ * has enough space for U-Boot where U-Boot is aligned on a page boundary.
+ * It overrides the default implementation found elsewhere which simply
+ * picks the end of ram, wherever that may be. The location of the stack,
+ * the relocation address, and how far U-Boot is moved by relocation are
+ * set in the global data structure.
+ */
+ulong board_get_usable_ram_top(ulong total_size)
+{
+       return get_usable_lowmem_top(gd->arch.hob_list);
+}
+
+unsigned install_e820_map(unsigned max_entries, struct e820entry *entries)
+{
+       unsigned num_entries = 0;
+
+       union hob_pointers_t hob;
+
+       hob.raw = gd->arch.hob_list;
+
+       while (!END_OF_HOB(hob)) {
+               if (hob.hdr->type == HOB_TYPE_RES_DESC) {
+                       entries[num_entries].addr = hob.res_desc->phys_start;
+                       entries[num_entries].size = hob.res_desc->len;
+
+                       if (hob.res_desc->type == RES_SYS_MEM)
+                               entries[num_entries].type = E820_RAM;
+                       else if (hob.res_desc->type == RES_MEM_RESERVED)
+                               entries[num_entries].type = E820_RESERVED;
+               }
+               hob.raw = GET_NEXT_HOB(hob);
+               num_entries++;
+       }
+
+       return num_entries;
+}
diff --git a/arch/x86/cpu/queensbay/tnc_pci.c b/arch/x86/cpu/queensbay/tnc_pci.c
new file mode 100644 (file)
index 0000000..39bff49
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <pci.h>
+#include <asm/pci.h>
+#include <asm/arch/fsp/fsp_support.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+void board_pci_setup_hose(struct pci_controller *hose)
+{
+       hose->first_busno = 0;
+       hose->last_busno = 0;
+
+       /* PCI memory space */
+       pci_set_region(hose->regions + 0,
+                      CONFIG_PCI_MEM_BUS,
+                      CONFIG_PCI_MEM_PHYS,
+                      CONFIG_PCI_MEM_SIZE,
+                      PCI_REGION_MEM);
+
+       /* PCI IO space */
+       pci_set_region(hose->regions + 1,
+                      CONFIG_PCI_IO_BUS,
+                      CONFIG_PCI_IO_PHYS,
+                      CONFIG_PCI_IO_SIZE,
+                      PCI_REGION_IO);
+
+       pci_set_region(hose->regions + 2,
+                      CONFIG_PCI_PREF_BUS,
+                      CONFIG_PCI_PREF_PHYS,
+                      CONFIG_PCI_PREF_SIZE,
+                      PCI_REGION_PREFETCH);
+
+       pci_set_region(hose->regions + 3,
+                      0,
+                      0,
+                      gd->ram_size,
+                      PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
+
+       hose->region_count = 4;
+}
+
+int board_pci_post_scan(struct pci_controller *hose)
+{
+       u32 status;
+
+       /* call into FspNotify */
+       debug("Calling into FSP (notify phase INIT_PHASE_PCI): ");
+       status = fsp_notify(NULL, INIT_PHASE_PCI);
+       if (status != FSP_SUCCESS)
+               debug("fail, error code %x\n", status);
+       else
+               debug("OK\n");
+
+       return 0;
+}
index e6d183b4796bc8ac951d68d3a9f4a9fdfcccfec5..c3b5187c2242dbadd99bc91a91747e4b4ab82a59 100644 (file)
@@ -18,4 +18,7 @@
 #define SYSCTLA         0x92
 #define SLAVE_PIC       0xa0
 
+#define UART0_BASE     0x3f8
+#define UART1_BASE     0x2f8
+
 #endif
diff --git a/board/intel/crownbay/MAINTAINERS b/board/intel/crownbay/MAINTAINERS
new file mode 100644 (file)
index 0000000..1eb6869
--- /dev/null
@@ -0,0 +1,6 @@
+INTEL CROWNBAY BOARD
+M:     Bin Meng <bmeng.cn@gmail.com>
+S:     Maintained
+F:     board/intel/crownbay/
+F:     include/configs/crownbay.h
+F:     configs/crownbay_defconfig
diff --git a/board/intel/crownbay/Makefile b/board/intel/crownbay/Makefile
new file mode 100644 (file)
index 0000000..aeb219b
--- /dev/null
@@ -0,0 +1,7 @@
+#
+# Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
+#
+# SPDX-License-Identifier:     GPL-2.0+
+#
+
+obj-y  += crownbay.o start.o
diff --git a/board/intel/crownbay/crownbay.c b/board/intel/crownbay/crownbay.c
new file mode 100644 (file)
index 0000000..8c6df98
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/ibmpc.h>
+#include <asm/pnp_def.h>
+#include <smsc_lpc47m.h>
+
+#define SERIAL_DEV PNP_DEV(0x2e, 4)
+
+DECLARE_GLOBAL_DATA_PTR;
+
+int board_early_init_f(void)
+{
+       lpc47m_enable_serial(SERIAL_DEV, UART0_BASE);
+
+       return 0;
+}
diff --git a/board/intel/crownbay/start.S b/board/intel/crownbay/start.S
new file mode 100644 (file)
index 0000000..cf92b4c
--- /dev/null
@@ -0,0 +1,9 @@
+/*
+ * Copyright (C) 2014, Bin Meng <bmeng.cn@gmail.com>
+ *
+ * SPDX-License-Identifier:    GPL-2.0+
+ */
+
+.globl early_board_init
+early_board_init:
+       jmp     early_board_init_ret