arch/x86/postcar: Add x86_64 support
* Add support for loading GDT on x86_64. * Add x86_64 assembly code to do the same as the x86_32 code. * Separate x86_32 and x86_64 code. Tested on qemu x86_32 and x86_64 using additional MTRRs. Tested on Lenovo T410 with additional x86_64 patches. Change-Id: I1c190627f5f0ed6f82738cb99423892382899d7b Signed-off-by: Patrick Rudolph <siro@das-labor.org> Reviewed-on: https://review.coreboot.org/c/coreboot/+/30500 Reviewed-by: Arthur Heymans <arthur@aheymans.xyz> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
This commit is contained in:
		@@ -46,7 +46,7 @@ At the moment *$n* is 4, which results in identity mapping the lower 4 GiB.
 | 
			
		||||
* Setup page tables for long mode - *DONE*
 | 
			
		||||
* Add assembly code for long mode - *DONE*
 | 
			
		||||
* Add assembly code for SMM - *DONE*
 | 
			
		||||
* Add assembly code for postcar stage - *TODO*
 | 
			
		||||
* Add assembly code for postcar stage - *DONE*
 | 
			
		||||
* Add assembly code to return to protected mode - *TODO*
 | 
			
		||||
* Implement reference code for mainboard `emulation/qemu-q35` - *TODO*
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -195,7 +195,11 @@ endif # CONFIG_ARCH_ROMSTAGE_X86_32 / CONFIG_ARCH_ROMSTAGE_X86_64
 | 
			
		||||
# postcar
 | 
			
		||||
###############################################################################
 | 
			
		||||
 | 
			
		||||
ifeq ($(CONFIG_ARCH_POSTCAR_X86_32),y)
 | 
			
		||||
$(eval $(call create_class_compiler,postcar,x86_32))
 | 
			
		||||
else
 | 
			
		||||
$(eval $(call create_class_compiler,postcar,x86_64))
 | 
			
		||||
endif
 | 
			
		||||
postcar-generic-ccopts += -D__POSTCAR__
 | 
			
		||||
 | 
			
		||||
postcar-$(CONFIG_HAVE_ACPI_RESUME) += acpi_s3.c
 | 
			
		||||
 
 | 
			
		||||
@@ -10,6 +10,30 @@ post_car_stack_top:
 | 
			
		||||
.long	0
 | 
			
		||||
.long	0
 | 
			
		||||
 | 
			
		||||
#if defined(__x86_64__)
 | 
			
		||||
.code64
 | 
			
		||||
.macro pop_eax_edx
 | 
			
		||||
	pop	%rax
 | 
			
		||||
	mov	%rax, %rdx
 | 
			
		||||
	shr	$32, %rdx
 | 
			
		||||
.endm
 | 
			
		||||
.macro pop_ebx_esi
 | 
			
		||||
	pop	%rbx
 | 
			
		||||
	mov	%rbx, %rsi
 | 
			
		||||
	shr	$32, %rsi
 | 
			
		||||
.endm
 | 
			
		||||
#else
 | 
			
		||||
.code32
 | 
			
		||||
.macro pop_eax_edx
 | 
			
		||||
	pop	%eax
 | 
			
		||||
	pop	%edx
 | 
			
		||||
.endm
 | 
			
		||||
.macro pop_ebx_esi
 | 
			
		||||
	pop	%ebx
 | 
			
		||||
	pop	%esi
 | 
			
		||||
.endm
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
.text
 | 
			
		||||
.global _start
 | 
			
		||||
_start:
 | 
			
		||||
@@ -17,7 +41,11 @@ _start:
 | 
			
		||||
	   is expected to be implemented in assembly. */
 | 
			
		||||
 | 
			
		||||
	/* Migrate GDT to this text segment */
 | 
			
		||||
#if defined(__x86_64__)
 | 
			
		||||
	call	gdt_init64
 | 
			
		||||
#else
 | 
			
		||||
	call	gdt_init
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#ifdef	__x86_64__
 | 
			
		||||
	mov	%rdi, _cbmem_top_ptr
 | 
			
		||||
@@ -31,10 +59,15 @@ _start:
 | 
			
		||||
	call	chipset_teardown_car
 | 
			
		||||
 | 
			
		||||
	/* Enable caching if not already enabled. */
 | 
			
		||||
#ifdef  __x86_64__
 | 
			
		||||
	mov	%cr0, %rax
 | 
			
		||||
	and     $(~(CR0_CD | CR0_NW)), %eax
 | 
			
		||||
	mov	%rax, %cr0
 | 
			
		||||
#else
 | 
			
		||||
	mov	%cr0, %eax
 | 
			
		||||
	and	$(~(CR0_CD | CR0_NW)), %eax
 | 
			
		||||
	mov	%eax, %cr0
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
	/* Ensure cache is clean. */
 | 
			
		||||
	invd
 | 
			
		||||
 | 
			
		||||
@@ -61,8 +94,13 @@ _start:
 | 
			
		||||
	/* Need to align stack to 16 bytes at the call instruction. Therefore
 | 
			
		||||
	   account for the 1 push. */
 | 
			
		||||
	andl	$0xfffffff0, %esp
 | 
			
		||||
#if defined(__x86_64__)
 | 
			
		||||
	mov	%rbp, %rdi
 | 
			
		||||
#else
 | 
			
		||||
	sub	$12, %esp
 | 
			
		||||
	push	%ebp
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	call	soc_set_mtrrs
 | 
			
		||||
	/* Ignore fixing up %esp since we're setting it a new value. */
 | 
			
		||||
 | 
			
		||||
@@ -73,7 +111,7 @@ _start:
 | 
			
		||||
	call	soc_enable_mtrrs
 | 
			
		||||
#else /* CONFIG_SOC_SETS_MSRS */
 | 
			
		||||
	/* Clear variable MTRRs. */
 | 
			
		||||
	pop	%ebx	/* Number to clear */
 | 
			
		||||
	pop_ebx_esi	/* ebx: Number to clear, esi: Number to set */
 | 
			
		||||
	test	%ebx, %ebx
 | 
			
		||||
	jz	2f
 | 
			
		||||
	xor	%eax, %eax
 | 
			
		||||
@@ -89,23 +127,20 @@ _start:
 | 
			
		||||
2:
 | 
			
		||||
 | 
			
		||||
	/* Set Variable MTRRs based on stack contents. */
 | 
			
		||||
	pop	%ebx	/* Number to set. */
 | 
			
		||||
	test	%ebx, %ebx
 | 
			
		||||
	test	%esi, %esi
 | 
			
		||||
	jz	2f
 | 
			
		||||
	mov	$(MTRR_PHYS_BASE(0)), %ecx
 | 
			
		||||
1:
 | 
			
		||||
	/* Write MTRR base. */
 | 
			
		||||
	pop	%eax
 | 
			
		||||
	pop	%edx
 | 
			
		||||
	pop_eax_edx
 | 
			
		||||
	wrmsr
 | 
			
		||||
	inc	%ecx
 | 
			
		||||
	/* Write MTRR mask. */
 | 
			
		||||
	pop	%eax
 | 
			
		||||
	pop	%edx
 | 
			
		||||
	pop_eax_edx
 | 
			
		||||
	wrmsr
 | 
			
		||||
	inc	%ecx
 | 
			
		||||
 | 
			
		||||
	dec	%ebx
 | 
			
		||||
	dec	%esi
 | 
			
		||||
	jnz	1b
 | 
			
		||||
2:
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -15,6 +15,22 @@ gdtptr:
 | 
			
		||||
	.word	gdt_end - gdt -1 /* compute the table limit */
 | 
			
		||||
	.long	gdt		 /* we know the offset */
 | 
			
		||||
 | 
			
		||||
#ifdef __x86_64__
 | 
			
		||||
.code64
 | 
			
		||||
.section ".text._gdt64_", "ax", @progbits
 | 
			
		||||
	.globl gdt_init64
 | 
			
		||||
gdt_init64:
 | 
			
		||||
	lgdt	gdtptr64
 | 
			
		||||
	ret
 | 
			
		||||
 | 
			
		||||
.previous
 | 
			
		||||
	.align	4
 | 
			
		||||
.globl gdtptr64
 | 
			
		||||
gdtptr64:
 | 
			
		||||
	.word	gdt_end - gdt -1 /* compute the table limit */
 | 
			
		||||
	.quad	gdt		 /* we know the offset */
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
	.align	4
 | 
			
		||||
gdt:
 | 
			
		||||
	/* selgdt 0, unused */
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user