Alexandru Gagniuc (mr.nuke.me@gmail.com) just uploaded a new patch set to gerrit, which you can find at https://review.coreboot.org/13301
-gerrit
commit a4af8d0acf1ac4a58996f021e99223920d95a6d4 Author: Alexandru Gagniuc alexandrux.gagniuc@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@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 | 162 +++++++++++++++++++++ .../apollolake/bootblock/early_chipset_config.S | 94 ++++++++++++ src/soc/intel/apollolake/include/soc/bootblock.h | 18 +++ 6 files changed, 330 insertions(+)
diff --git a/src/soc/intel/apollolake/Kconfig b/src/soc/intel/apollolake/Kconfig index ca38494..f7ae68e 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 @@ -32,6 +33,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 b37cf8d..cc3e013 100644 --- a/src/soc/intel/apollolake/Makefile.inc +++ b/src/soc/intel/apollolake/Makefile.inc @@ -7,8 +7,14 @@ 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
+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@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..944c73d --- /dev/null +++ b/src/soc/intel/apollolake/bootblock/cache_as_ram.S @@ -0,0 +1,162 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2015 Intel Corp. + * (Written by Alexandru Gagniuc alexandrux.gagniuc@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/cr.h> +#include <cpu/x86/post_code.h> + +#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) + + /* Disable MTTRs, 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 + + /* Enable caching */ + mov eax, cr0 + and eax, ~(CR0_CD | CR0_NW) + 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, (CONFIG_DCACHE_RAM_SIZE >> 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..95081d3 --- /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@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, (CONFIG_MMCONF_BASE_ADDRESS | 0x68000) /* IOSF PCI dev */ + 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..f5fab18 --- /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@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_BOOTBLOCK_H_ +#define _APOLLOLAKE_BOOTBLOCK_H_ + +void bootblock_car_main(void); + +#endif /* _APOLLOLAKE_BOOTBLOCK_H_ */