Martin Roth has uploaded this change for review. ( https://review.coreboot.org/c/coreboot/+/32415
Change subject: soc/amd/picasso: Add code to support Romstage in RAM ......................................................................
soc/amd/picasso: Add code to support Romstage in RAM
AMD's Picasso SOC brings up memory before releasing the X86 processor, and jumps directly to Romstage. This adds the platform support for that.
TEST=None BUG=b:130804851
Signed-off-by: Martin Roth martinroth@chromium.org Change-Id: I5ac62f6f3edb0c903fdc880fa655727ad2bc86bb --- M src/soc/amd/picasso/Kconfig A src/soc/amd/picasso/include/soc/romstage.ld A src/soc/amd/picasso/reset_vector.S 3 files changed, 187 insertions(+), 0 deletions(-)
git pull ssh://review.coreboot.org:29418/coreboot refs/changes/15/32415/1
diff --git a/src/soc/amd/picasso/Kconfig b/src/soc/amd/picasso/Kconfig index 129dedf..3d30b46b 100644 --- a/src/soc/amd/picasso/Kconfig +++ b/src/soc/amd/picasso/Kconfig @@ -26,6 +26,7 @@ select ARCH_VERSTAGE_X86_32 select ARCH_ROMSTAGE_X86_32 select ARCH_RAMSTAGE_X86_32 + select ROMSTAGE_IN_RAM select X86_AMD_FIXED_MTRRS select ACPI_AMD_HARDWARE_SLEEP_VALUES select COLLECT_TIMESTAMPS_NO_TSC diff --git a/src/soc/amd/picasso/include/soc/romstage.ld b/src/soc/amd/picasso/include/soc/romstage.ld new file mode 100644 index 0000000..4be3340 --- /dev/null +++ b/src/soc/amd/picasso/include/soc/romstage.ld @@ -0,0 +1,29 @@ +/* + * This file is part of the coreboot project. + * + * Copyright 2015 Google Inc + * + * 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#if ENV_ROMSTAGE && CONFIG(ROMSTAGE_IN_RAM) +SECTIONS { + _JMP_IN_RAM = CONFIG_ROMSTAGE_ADDR + CONFIG_ROMSTAGE_MAX_SIZE - 0x1000; + . = _JMP_IN_RAM; + .resetram . : { *(.resetram) } + _RST_IN_RAM = CONFIG_ROMSTAGE_ADDR + CONFIG_ROMSTAGE_MAX_SIZE - 0x10; + . = _RST_IN_RAM; + .reset . : { + *(.reset); + . = 15; + BYTE(0x00); + } +} +#endif diff --git a/src/soc/amd/picasso/reset_vector.S b/src/soc/amd/picasso/reset_vector.S new file mode 100644 index 0000000..6a3bbfa --- /dev/null +++ b/src/soc/amd/picasso/reset_vector.S @@ -0,0 +1,157 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2000, Ron Minnich rminnich@lanl.gov + * Advanced Computing Lab, LANL + * Copyright (C) 2019 Advanced Micro Devices, Inc. + * + * 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; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include <cpu/x86/cr.h> +#include <cpu/x86/post_code.h> +#include <arch/rom_segs.h> + +/* The resetram section keeps this code within reach of the first jmp to + * _start16bit. This functionality is contained within bootblock on most + * other systems, however this file is part of romstage which isn't subject + * to the same size limitations. + */ +.section ".resetram", "ax", %progbits + +.align 4096 +.code16 +.globl _start16bit +.type _start16bit, @function + +_start16bit: + cli + /* Save the BIST result */ + movl %eax, %ebp + + post_code(POST_RESET_VECTOR_CORRECT) + + /* IMMEDIATELY invalidate the translation lookaside buffer (TLB) before + * executing any further code. Even though paging is disabled we + * could still get false address translations due to the TLB if we + * didn't invalidate it. Thanks to kmliu@sis.com.tw for this TLB fix. + */ + + xorl %eax, %eax + movl %eax, %cr3 /* Invalidate TLB*/ + + /* + * Load an IDT with NULL limit to prevent the 16bit IDT being used + * in protected mode before c_start.S sets up a 32bit IDT when entering + * RAM stage. In practise: CPU will shutdown on any exception. + * See IA32 manual Vol 3A 19.26 Interrupts. + */ + movl $nullidt_amd, %ebx + lidt %cs:(%bx) + + movl $fseg_gdt, %ebx + lgdtl %cs:(%bx) + + movl %cr0, %eax + andl $0x7FFAFFD1, %eax /* PG,AM,WP,NE,TS,EM,MP = 0 */ + orl $0x60000001, %eax /* CD, NW, PE = 1 */ + movl %eax, %cr0 + + /* Until now, the processor was executing in DRAM however the CS + * register's base and limit looked more like what you see after a + * traditional x86 reset. The value in CS has been 0xf000. Now that + * the GDT is loaded with flat descriptors, try to jump to + * 0x8:$__protected_start at its physical address in DRAM. + */ + ljmpl $ROM_CODE_SEG, $__protected_start + +.align 4 +.globl nullidt_amd +nullidt_amd: + .word 0 /* limit */ + .long 0 + .word 0 + + .align 4 + +gdt: +fseg_gdt: + .word gdt_end - gdt -1 + .long gdt + .word 0 + + /* selgdt 0x08, flat code segment */ + .word 0xffff, 0x0000 + .byte 0x00, 0x9b, 0xcf, 0x00 /* G=1 and 0x0f, So we get 4Gbytes + for limit */ + + /* selgdt 0x10,flat data segment */ + .word 0xffff, 0x0000 + .byte 0x00, 0x93, 0xcf, 0x00 + + /* selgdt 0x18, flat code segment (64-bit) */ + .word 0xffff, 0x0000 + .byte 0x00, 0x9b, 0xaf, 0x00 +gdt_end: + +.code32 +.align 4 + +__protected_start: + post_code(POST_ENTER_PROTECTED_MODE) + + movw $ROM_DATA_SEG, %ax + movw %ax, %ds + movw %ax, %es + movw %ax, %ss + movw %ax, %fs + movw %ax, %gs + +#if CONFIG(SSE) +enable_sse: + mov %cr4, %eax + or $CR4_OSFXSR, %ax + mov %eax, %cr4 +#endif /* CONFIG(SSE) */ + + cld + xor %eax, %eax + movl $(_car_region_end), %ecx + movl $(_car_region_start), %edi + sub %edi, %ecx + rep stosl + + mov $_car_stack_end, %esp + + /* Store BIST and an early timestamp at the top of the stack. See + * structure in soc/romstage.h for layout. + */ + rdtsc /* timestamp */ + push %edx + push %eax + push %ebp /* BIST */ + + and $0xfffffff0, %esp + sub $8, %esp + + jmp _romstage_in_ram_continue + +.section ".reset", "ax", %progbits +.code16 +.globl _start +_start: + .byte 0xe9 + .int _start16bit - ( . + 2 ) + /* Note: The above jump is hand coded to work around bugs in binutils. + * 5 byte are used for a 3 byte instruction. This works because x86 + * is little endian and allows us to use supported 32bit relocations + * instead of the weird 16 bit relocations that binutils does not + * handle consistently between versions because they are used so rarely. + */
Arthur Heymans has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/32415 )
Change subject: soc/amd/picasso: Add code to support Romstage in RAM ......................................................................
Patch Set 1:
Could you add some documentation about what stages are run, in what sort of environment and what they do? I have a few questions about the bootflow. The reset vector is in a romstage located in RAM? Is there a possibility to chose where it executes and who puts it in ram? What should the romstage do besides initializing cbmem and loading ramstage?
Also, is there some public documentation?
Martin Roth has posted comments on this change. ( https://review.coreboot.org/c/coreboot/+/32415 )
Change subject: soc/amd/picasso: Add code to support Romstage in RAM ......................................................................
Patch Set 1:
Patch Set 1:
Could you add some documentation about what stages are run, in what sort of environment and what they do? I have a few questions about the bootflow. The reset vector is in a romstage located in RAM? Is there a possibility to chose where it executes and who puts it in ram? What should the romstage do besides initializing cbmem and loading ramstage?
Also, is there some public documentation?
Here's the comment I write for commit 32414 - I think the answer some of your questions here as well.
It was going to take significant additional changes to coreboot to begin x86 execution with ramstage (e.g. cbmem is assumed already to be online). As a result, we chose to do a small romstage, at least for now.
Here's the current general flow - I'm working on a design doc and will publish something both internally and at coreboot.org about the boot flow.
- Power On - PSP starts from On-Chip firmware - PSP loads minimal off-chip firmware from the SPI ROM. - PSP tries to load coreboot verstage from SPI. - If verstage is available, it does its verification and passes the AMD firmware directory table for the chosen FMAP region back to the PSP to load everything else. - If verstage is not available, the PSP continues from the original AMD firmware directory table. - PSP loads the ABL (AGESA Boot Loader) code and runs that. - The ABL loads the APCB (AGESA PSP Customization Block), a structure containing the setup for AGESA running in the PSP. This contains a number of configuration options as well as the information how to get the SPDs. - ABL initializes memory. I discussed with AMD whether we could continue to let coreboot do the memory initialization instead of the PSP, but the ability to do Cache-as-RAM has been removed, so while it might be possible, it would have to be all written in ASM. - PSP looks up the code destinations in the AMD firmware directory table then decompresses and copies the rest of the FMAP region into memory. It fixes up the x86 CS descriptor to appear to BIOS as any x86 does coming out of reset, except CS's base points to DRAM and not flash. The base is romstage_base + romstage_size - 64KB and IP=0xfff0. - PSP jumps to the x86 reset vector, in this case coreboot's romstage.
Martin Roth has abandoned this change. ( https://review.coreboot.org/c/coreboot/+/32415 )
Change subject: soc/amd/picasso: Add code to support Romstage in RAM ......................................................................
Abandoned
merged into 33759: soc/amd/picasso: Create a hybrid romstage to begin in DRAM