[coreboot-gerrit] Patch set updated for coreboot: soc/apollolake: Add initial cache-as-ram setup for bootblock

Alexandru Gagniuc (mr.nuke.me@gmail.com) gerrit at coreboot.org
Mon Jan 25 18:03:25 CET 2016


Alexandru Gagniuc (mr.nuke.me at gmail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/13301

-gerrit

commit ebc0e14cd9966ea281cf9affe50eda7b0ead7cd2
Author: Alexandru Gagniuc <alexandrux.gagniuc at intel.com>
Date:   Tue Oct 6 17:16:41 2015 -0700

    soc/apollolake: Add initial cache-as-ram setup for bootblock
    
    This is the minimum setup needed to both get cache-as-ram setup and a
    C environment working. On apollolake, we only get 32 KiB of data
    loaded into an SRAM that is readonly to the main CPU. Due to this
    restriction we have to set CAR and a C environment very early on.
    
    While we originally had the code written in ATT syntax, we decided to
    rewrite in intel syntax so we can better collaborate with other teams.
    The rewrite also helped us catch a few bugs.
    
    Change-Id: I65c51f972580609d2c1f03dfe2a86bc5d45d1e46
    Signed-off-by: Alexandru Gagniuc <alexandrux.gagniuc at intel.com>
---
 src/soc/intel/apollolake/Kconfig                   |  27 ++++
 src/soc/intel/apollolake/Makefile.inc              |   6 +-
 src/soc/intel/apollolake/bootblock/bootblock_car.c |  23 +++
 src/soc/intel/apollolake/bootblock/cache_as_ram.S  | 165 +++++++++++++++++++++
 .../apollolake/bootblock/early_chipset_config.S    |  94 ++++++++++++
 src/soc/intel/apollolake/include/soc/bootblock.h   |  18 +++
 6 files changed, 332 insertions(+), 1 deletion(-)

diff --git a/src/soc/intel/apollolake/Kconfig b/src/soc/intel/apollolake/Kconfig
index cf0544d..919b27f 100644
--- a/src/soc/intel/apollolake/Kconfig
+++ b/src/soc/intel/apollolake/Kconfig
@@ -18,6 +18,7 @@ config CPU_SPECIFIC_OPTIONS
 	select SSE2
 	select SUPPORT_CPU_UCODE_IN_CBFS
 	# Misc options
+	select C_ENVIRONMENT_BOOTBLOCK
 	select COLLECT_TIMESTAMPS
 	select HAVE_INTEL_FIRMWARE
 	select MMCONF_SUPPORT
@@ -31,6 +32,32 @@ config CPU_SPECIFIC_OPTIONS
 	select SOC_INTEL_COMMON
 	select UDELAY_TSC
 
+config MMCONF_BASE_ADDRESS
+	hex "PCI MMIO Base Address"
+	default 0xe0000000
+
+config IOSF_BASE_ADDRESS
+	hex "MMIO Base Address of sideband bus"
+	default 0xd0000000
+
+config DCACHE_RAM_BASE
+	hex "Base address of cache-as-RAM"
+	default 0xfef00000
+
+config DCACHE_RAM_SIZE
+	hex "Length in bytes of cache-as-RAM"
+	default 0x80000
+	help
+	  The size of the cache-as-ram region required during bootblock
+	  and/or romstage.
+
+config DCACHE_RAM_BOOTBLOCK_STACK_SIZE
+	hex
+	default 0x800
+	help
+	  The amount of anticipated stack usage from the bootblock during
+	  pre-romstage initialization.
+
 config CPU_ADDR_BITS
 	int
 	default 36
diff --git a/src/soc/intel/apollolake/Makefile.inc b/src/soc/intel/apollolake/Makefile.inc
index b0aeb31..945946a 100644
--- a/src/soc/intel/apollolake/Makefile.inc
+++ b/src/soc/intel/apollolake/Makefile.inc
@@ -7,12 +7,16 @@ subdirs-y += ../../../cpu/x86/mtrr
 subdirs-y += ../../../cpu/x86/smm
 subdirs-y += ../../../cpu/x86/tsc
 
+bootblock-y += bootblock/bootblock_car.c
+bootblock-y += bootblock/cache_as_ram.S
+bootblock-y += bootblock/early_chipset_config.S
+
 romstage-y += placeholders.c
 smm-y += placeholders.c
 ramstage-y += placeholders.c
 
 # cpu_microcode_bins += ???
 
-# CPPFLAGS_common += -I$(src)/soc/intel/apollolake/include
+CPPFLAGS_common += -I$(src)/soc/intel/apollolake/include
 
 endif
diff --git a/src/soc/intel/apollolake/bootblock/bootblock_car.c b/src/soc/intel/apollolake/bootblock/bootblock_car.c
new file mode 100644
index 0000000..4be0815
--- /dev/null
+++ b/src/soc/intel/apollolake/bootblock/bootblock_car.c
@@ -0,0 +1,23 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Intel Corp.
+ * (Written by Alexandru Gagniuc <alexandrux.gagniuc at intel.com> for Intel Corp.)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <arch/io.h>
+#include <soc/bootblock.h>
+
+void bootblock_car_main(void)
+{
+	/* Quick post code to show we made it to C code */
+	outb(0x30, 0x80);
+	/* Don't return, so we see the above post code */
+	while (1)
+		;
+}
diff --git a/src/soc/intel/apollolake/bootblock/cache_as_ram.S b/src/soc/intel/apollolake/bootblock/cache_as_ram.S
new file mode 100644
index 0000000..e451f66
--- /dev/null
+++ b/src/soc/intel/apollolake/bootblock/cache_as_ram.S
@@ -0,0 +1,165 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Intel Corp.
+ * (Written by Alexandru Gagniuc <alexandrux.gagniuc at intel.com> for Intel Corp.)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <device/pci_def.h>
+#include <cpu/x86/mtrr.h>
+#include <cpu/x86/cache.h>
+#include <cpu/x86/post_code.h>
+#include <cbmem.h>
+
+#define CR0_CACHE_DISABLE	(1 << 30)
+#define CR0_NO_WRITE		(1 << 29)
+
+#define EVICT_CTL_MSR		0x2e0
+
+.intel_syntax noprefix
+
+#undef post_code
+#define post_code(value)	\
+	mov	al, value;	\
+	outb	CONFIG_POST_IO_PORT, al
+
+.global cache_as_ram
+cache_as_ram:
+	post_code(0x21)
+
+	/* Clear/disable fixed MTRRs */
+	mov	ebx, offset fixed_mtrr_list_size
+	xor	eax, eax
+	xor	edx, edx
+clear_fixed_mtrr:
+	add	ebx, -2
+	movzxw	ecx, word ptr [fixed_mtrr_list + ebx]
+	wrmsr
+	jnz	clear_fixed_mtrr
+
+	post_code(0x22)
+
+	/* Figure put how many MTRRs we have, and clear them out */
+	mov	ecx, MTRR_CAP_MSR
+	rdmsr
+	movzxb	ebx, al		/* Number of variable MTRRs */
+	mov	ecx, MTRR_PHYS_BASE(0)
+	xor	eax, eax
+	xor	edx, edx
+clear_var_mtrr:
+	wrmsr
+	inc	ecx
+	wrmsr
+	inc	ecx
+	dec	ebx
+	jnz	clear_var_mtrr
+
+	post_code(0x23)
+
+	/* Configure default memory type to uncacheable (UC) */
+	mov 	ecx, MTRR_DEF_TYPE_MSR
+	rdmsr
+	and	eax, ~0xcff
+	wrmsr
+
+	post_code(0x24)
+
+	/* Configure CAR region as write-back (WB) */
+	mov	ecx, MTRR_PHYS_BASE(0)
+	mov	eax, CONFIG_DCACHE_RAM_BASE		/* base */
+	or	eax, MTRR_TYPE_WRBACK
+	xor	edx, edx
+	wrmsr
+
+	/* Configure the MTRR mask for the size region */
+	mov	ecx, MTRR_PHYS_MASK(0)
+	mov	eax, ~(CONFIG_DCACHE_RAM_SIZE - 1)	/* size mask */
+	or	eax, MTRR_PHYS_MASK_VALID
+	wrmsr
+
+	post_code(0x25)
+
+	/* Enable variable MTRRs */
+	mov	ecx, MTRR_DEF_TYPE_MSR
+	rdmsr
+	or	eax, MTRR_DEF_TYPE_EN
+	wrmsr
+
+	/* Cache tricks */
+	mov	eax, cr0
+	and	eax, ~(CR0_CACHE_DISABLE | CR0_NO_WRITE)
+	invd
+	mov	cr0, eax
+
+	/* Disable cache eviction (setup stage) */
+	mov	ecx, EVICT_CTL_MSR
+	rdmsr
+	or	eax, 1
+	wrmsr
+
+	post_code(0x26)
+
+	/* Write something to each cache line */
+	mov	eax, 0xcafebabe
+	mov	edi, CONFIG_DCACHE_RAM_BASE
+	mov	ecx, (0x80000 >> 6)
+cache_init_loop:
+	mov	[edi], eax
+	sfence
+	add	edi, 64
+	loop cache_init_loop
+
+	post_code(0x27)
+
+	/* Disable cache eviction (run stage) */
+	mov	ecx, EVICT_CTL_MSR
+	rdmsr
+	or	eax, 2
+	wrmsr
+
+	post_code(0x28)
+
+car_init_done:
+
+	/* Setup bootblock stack */
+	mov	esp, CONFIG_DCACHE_RAM_BASE
+	add 	esp, CONFIG_DCACHE_RAM_BOOTBLOCK_STACK_SIZE
+
+	/* Make sure CAR region is executable */
+	mov	ecx, 0x120
+	rdmsr
+	or	ah, 0x1
+	wrmsr
+
+before_carstage:
+	post_code(0x2b)
+
+	/* Call romstage.c main function. */
+	push .halt_forever	/* In case bootblock_car_main returns */
+	jmp bootblock_car_main
+
+	/* Never reached */
+
+.halt_forever:
+	post_code(POST_DEAD_CODE)
+	hlt
+	jmp	.halt_forever
+
+fixed_mtrr_list:
+	.word	MTRR_FIX_64K_00000
+	.word	MTRR_FIX_16K_80000
+	.word	MTRR_FIX_16K_A0000
+	.word	MTRR_FIX_4K_C0000
+	.word	MTRR_FIX_4K_C8000
+	.word	MTRR_FIX_4K_D0000
+	.word	MTRR_FIX_4K_D8000
+	.word	MTRR_FIX_4K_E0000
+	.word	MTRR_FIX_4K_E8000
+	.word	MTRR_FIX_4K_F0000
+	.word	MTRR_FIX_4K_F8000
+fixed_mtrr_list_size = . - fixed_mtrr_list
diff --git a/src/soc/intel/apollolake/bootblock/early_chipset_config.S b/src/soc/intel/apollolake/bootblock/early_chipset_config.S
new file mode 100644
index 0000000..113188c
--- /dev/null
+++ b/src/soc/intel/apollolake/bootblock/early_chipset_config.S
@@ -0,0 +1,94 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Intel Corp.
+ * (Written by Alexandru Gagniuc <alexandrux.gagniuc at intel.com> for Intel Corp.)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+.intel_syntax noprefix
+.extern cache_as_ram
+
+#define post_code(value)	\
+	mov	al, value;	\
+	outb	CONFIG_POST_IO_PORT, al
+
+.global bootblock_pre_c_entry
+bootblock_pre_c_entry:
+	/*
+	 * eax:  BIST value
+	 */
+	movd	mm2, eax
+
+	post_code(0x20)
+
+enable_pciex_bar:
+	mov	eax, 0x80000060		/* ROOT PCI device reg60 PCIEX_BAR_*/
+	mov	dx, 0xcf8
+	out	dx, eax
+	mov	eax, (CONFIG_MMCONF_BASE_ADDRESS | 1)
+	mov	dx, 0xcfc
+	out	dx, eax
+
+enable_iosf_bar:
+	mov	ebp, 0xe0068000				/* IOSF PCI device */
+	mov	dword ptr [ebp + 0x10], CONFIG_IOSF_BASE_ADDRESS /* BAR 0 */
+	mov	word ptr [ebp + 0x04], 0x06		/* PCI command */
+
+
+/* We need LPC for port80, but it won't work if the pads are not configured */
+configure_lpc_pads:
+	mov	ecx, offset num_lpc_pads /* Number of pads to configure */
+	lea	esi, lpc_pad_params
+init_lpc_pad:
+	mov	edi, [esi + 0x00]	/* MMIO addr of pad config registers */
+	mov	eax, [esi + 0x04]	/* Pad CONF0 value */
+	mov	edx, [esi + 0x08]	/* Pad CONF1 value */
+	mov	[edi + 0x00], eax	/* Write CONF0 to config register */
+	mov	[edi + 0x04], edx	/* Write CONF1 to config register */
+	add	esi, 0x0c
+	loop	init_lpc_pad
+
+	jmp	cache_as_ram
+
+/* FIXME: Find a better way to define these */
+
+#define LPC_CLKOUT0	0x118
+#define LPC_CLKOUT1	0x120
+#define LPC_AD0		0x128
+#define LPC_AD1		0x130
+#define LPC_AD2		0x138
+#define LPC_AD3		0x140
+#define LPC_CLKRUN	0x148
+#define LPC_FRAME	0x150
+
+#define XLATE_LPC(off)	((0xc0 << 16 ) | (0x500 + (off)))
+#define PAD_MMIO_ADDR(poff)	CONFIG_IOSF_BASE_ADDRESS + XLATE_LPC(poff)
+
+lpc_pad_params:
+	.long	PAD_MMIO_ADDR(LPC_CLKOUT0)
+	.long	0x44000400
+	.long	0x0003C000
+	.long	PAD_MMIO_ADDR(LPC_AD0)
+	.long	0x44000402
+	.long	0x0003F000
+	.long	PAD_MMIO_ADDR(LPC_AD1)
+	.long	0x44000402
+	.long	0x0003F000
+	.long	PAD_MMIO_ADDR(LPC_AD2)
+	.long	0x44000402
+	.long	0x0003F000
+	.long	PAD_MMIO_ADDR(LPC_AD3)
+	.long	0x44000402
+	.long	0x0003F000
+	.long	PAD_MMIO_ADDR(LPC_FRAME)
+	.long	0x44000400
+	.long	0x0003F000
+	.long	PAD_MMIO_ADDR(LPC_CLKOUT1)
+	.long	0x44000400
+	.long	0x0003C000
+num_lpc_pads = ( . - lpc_pad_params) / 0xc
diff --git a/src/soc/intel/apollolake/include/soc/bootblock.h b/src/soc/intel/apollolake/include/soc/bootblock.h
new file mode 100644
index 0000000..48e9e25
--- /dev/null
+++ b/src/soc/intel/apollolake/include/soc/bootblock.h
@@ -0,0 +1,18 @@
+/*
+ * This file is part of the coreboot project.
+ *
+ * Copyright (C) 2015 Intel Corp.
+ * (Written by Alexandru Gagniuc <alexandrux.gagniuc at intel.com> for Intel Corp.)
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef _APOLLOLAKE_BOOTBLOC_H_
+#define _APOLLOLAKE_BOOTBLOC_H_
+
+void bootblock_car_main(void);
+
+#endif /* _APOLLOLAKE_BOOTBLOC_H_ */



More information about the coreboot-gerrit mailing list