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. + */