xref: /openbmc/u-boot/arch/x86/cpu/intel_common/car.S (revision ac378bb05fa3cac3197085431f577e0dbddd4b4a)
183d290c5STom Rini/* SPDX-License-Identifier: GPL-2.0 */
21223d737SSimon Glass/*
31223d737SSimon Glass * Copyright (c) 2014 Google, Inc
41223d737SSimon Glass *
51223d737SSimon Glass * From Coreboot file cpu/intel/model_206ax/cache_as_ram.inc
61223d737SSimon Glass *
71223d737SSimon Glass * Copyright (C) 2000,2007 Ronald G. Minnich <rminnich@gmail.com>
81223d737SSimon Glass * Copyright (C) 2005 Tyan (written by Yinghai Lu for Tyan)
91223d737SSimon Glass * Copyright (C) 2007-2008 coresystems GmbH
101223d737SSimon Glass * Copyright (C) 2012 Kyösti Mälkki <kyosti.malkki@gmail.com>
111223d737SSimon Glass */
121223d737SSimon Glass
131223d737SSimon Glass#include <common.h>
149e66506dSSimon Glass#include <asm/microcode.h>
151223d737SSimon Glass#include <asm/msr-index.h>
161223d737SSimon Glass#include <asm/mtrr.h>
171223d737SSimon Glass#include <asm/post.h>
181223d737SSimon Glass#include <asm/processor.h>
191223d737SSimon Glass#include <asm/processor-flags.h>
201223d737SSimon Glass
211223d737SSimon Glass#define MTRR_PHYS_BASE_MSR(reg) (0x200 + 2 * (reg))
221223d737SSimon Glass#define MTRR_PHYS_MASK_MSR(reg) (0x200 + 2 * (reg) + 1)
231223d737SSimon Glass
241223d737SSimon Glass#define CACHE_AS_RAM_SIZE	CONFIG_DCACHE_RAM_SIZE
251223d737SSimon Glass#define CACHE_AS_RAM_BASE	CONFIG_DCACHE_RAM_BASE
261223d737SSimon Glass
271223d737SSimon Glass/* Cache 4GB - MRC_SIZE_KB for MRC */
281223d737SSimon Glass#define CACHE_MRC_BYTES	((CONFIG_CACHE_MRC_SIZE_KB << 10) - 1)
291223d737SSimon Glass#define CACHE_MRC_BASE		(0xFFFFFFFF - CACHE_MRC_BYTES)
301223d737SSimon Glass#define CACHE_MRC_MASK		(~CACHE_MRC_BYTES)
311223d737SSimon Glass
321223d737SSimon Glass#define CPU_PHYSMASK_HI	(1 << (CONFIG_CPU_ADDR_BITS - 32) - 1)
331223d737SSimon Glass
341223d737SSimon Glass#define NOEVICTMOD_MSR	0x2e0
351223d737SSimon Glass
361223d737SSimon Glass	/*
371223d737SSimon Glass	 * Note: ebp must not be touched in this code as it holds the BIST
381223d737SSimon Glass	 * value (built-in self test). We preserve this value until it can
391223d737SSimon Glass	 * be written to global_data when CAR is ready for use.
401223d737SSimon Glass	 */
411223d737SSimon Glass.globl car_init
421223d737SSimon Glasscar_init:
431223d737SSimon Glass	post_code(POST_CAR_START)
441223d737SSimon Glass
451223d737SSimon Glass	/* Send INIT IPI to all excluding ourself */
461223d737SSimon Glass	movl	$0x000C4500, %eax
471223d737SSimon Glass	movl	$0xFEE00300, %esi
481223d737SSimon Glass	movl	%eax, (%esi)
491223d737SSimon Glass
501223d737SSimon Glass	/* TODO: Load microcode later - the 'no eviction' mode breaks this */
511223d737SSimon Glass	movl	$MSR_IA32_UCODE_WRITE, %ecx
521223d737SSimon Glass	xorl	%edx, %edx
531223d737SSimon Glass	movl	$_dt_ucode_base_size, %eax
541223d737SSimon Glass	movl	(%eax), %eax
551223d737SSimon Glass	addl	$UCODE_HEADER_LEN, %eax
561223d737SSimon Glass	wrmsr
571223d737SSimon Glass
581223d737SSimon Glass	post_code(POST_CAR_SIPI)
591223d737SSimon Glass	/* Zero out all fixed range and variable range MTRRs */
601223d737SSimon Glass	movl	$mtrr_table, %esi
611223d737SSimon Glass	movl	$((mtrr_table_end - mtrr_table) / 2), %edi
621223d737SSimon Glass	xorl	%eax, %eax
631223d737SSimon Glass	xorl	%edx, %edx
641223d737SSimon Glassclear_mtrrs:
651223d737SSimon Glass	movw	(%esi), %bx
661223d737SSimon Glass	movzx	%bx, %ecx
671223d737SSimon Glass	wrmsr
681223d737SSimon Glass	add	$2, %esi
691223d737SSimon Glass	dec	%edi
701223d737SSimon Glass	jnz	clear_mtrrs
711223d737SSimon Glass
721223d737SSimon Glass	post_code(POST_CAR_MTRR)
731223d737SSimon Glass	/* Configure the default memory type to uncacheable */
741223d737SSimon Glass	movl	$MTRR_DEF_TYPE_MSR, %ecx
751223d737SSimon Glass	rdmsr
761223d737SSimon Glass	andl	$(~0x00000cff), %eax
771223d737SSimon Glass	wrmsr
781223d737SSimon Glass
791223d737SSimon Glass	post_code(POST_CAR_UNCACHEABLE)
801223d737SSimon Glass	/* Set Cache-as-RAM base address */
811223d737SSimon Glass	movl	$(MTRR_PHYS_BASE_MSR(0)), %ecx
821223d737SSimon Glass	movl	$(CACHE_AS_RAM_BASE | MTRR_TYPE_WRBACK), %eax
831223d737SSimon Glass	xorl	%edx, %edx
841223d737SSimon Glass	wrmsr
851223d737SSimon Glass
861223d737SSimon Glass	post_code(POST_CAR_BASE_ADDRESS)
871223d737SSimon Glass	/* Set Cache-as-RAM mask */
881223d737SSimon Glass	movl	$(MTRR_PHYS_MASK_MSR(0)), %ecx
891223d737SSimon Glass	movl	$(~(CACHE_AS_RAM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
901223d737SSimon Glass	movl	$CPU_PHYSMASK_HI, %edx
911223d737SSimon Glass	wrmsr
921223d737SSimon Glass
931223d737SSimon Glass	post_code(POST_CAR_MASK)
941223d737SSimon Glass
951223d737SSimon Glass	/* Enable MTRR */
961223d737SSimon Glass	movl	$MTRR_DEF_TYPE_MSR, %ecx
971223d737SSimon Glass	rdmsr
981223d737SSimon Glass	orl	$MTRR_DEF_TYPE_EN, %eax
991223d737SSimon Glass	wrmsr
1001223d737SSimon Glass
1011223d737SSimon Glass	/* Enable cache (CR0.CD = 0, CR0.NW = 0) */
1021223d737SSimon Glass        movl	%cr0, %eax
1031223d737SSimon Glass	andl	$(~(X86_CR0_CD | X86_CR0_NW)), %eax
1041223d737SSimon Glass	invd
1051223d737SSimon Glass	movl	%eax, %cr0
1061223d737SSimon Glass
1071223d737SSimon Glass	/* enable the 'no eviction' mode */
1081223d737SSimon Glass	movl    $NOEVICTMOD_MSR, %ecx
1091223d737SSimon Glass	rdmsr
1101223d737SSimon Glass	orl     $1, %eax
1111223d737SSimon Glass	andl    $~2, %eax
1121223d737SSimon Glass	wrmsr
1131223d737SSimon Glass
1141223d737SSimon Glass       /* Clear the cache memory region. This will also fill up the cache */
1151223d737SSimon Glass	movl	$CACHE_AS_RAM_BASE, %esi
1161223d737SSimon Glass	movl	%esi, %edi
1171223d737SSimon Glass	movl	$(CACHE_AS_RAM_SIZE / 4), %ecx
1181223d737SSimon Glass	xorl	%eax, %eax
1191223d737SSimon Glass	rep	stosl
1201223d737SSimon Glass
1211223d737SSimon Glass	/* enable the 'no eviction run' state */
1221223d737SSimon Glass	movl    $NOEVICTMOD_MSR, %ecx
1231223d737SSimon Glass	rdmsr
1241223d737SSimon Glass	orl     $3, %eax
1251223d737SSimon Glass	wrmsr
1261223d737SSimon Glass
1271223d737SSimon Glass	post_code(POST_CAR_FILL)
1281223d737SSimon Glass	/* Enable Cache-as-RAM mode by disabling cache */
1291223d737SSimon Glass	movl	%cr0, %eax
1301223d737SSimon Glass	orl	$X86_CR0_CD, %eax
1311223d737SSimon Glass	movl	%eax, %cr0
1321223d737SSimon Glass
1331223d737SSimon Glass	/* Enable cache for our code in Flash because we do XIP here */
1341223d737SSimon Glass	movl	$MTRR_PHYS_BASE_MSR(1), %ecx
1351223d737SSimon Glass	xorl	%edx, %edx
1361223d737SSimon Glass	movl    $car_init_ret, %eax
1371223d737SSimon Glass	andl    $(~(CONFIG_XIP_ROM_SIZE - 1)), %eax
1381223d737SSimon Glass	orl	$MTRR_TYPE_WRPROT, %eax
1391223d737SSimon Glass	wrmsr
1401223d737SSimon Glass
1411223d737SSimon Glass	movl	$MTRR_PHYS_MASK_MSR(1), %ecx
1421223d737SSimon Glass	movl	$CPU_PHYSMASK_HI, %edx
1431223d737SSimon Glass	movl	$(~(CONFIG_XIP_ROM_SIZE - 1) | MTRR_PHYS_MASK_VALID), %eax
1441223d737SSimon Glass	wrmsr
1451223d737SSimon Glass
1461223d737SSimon Glass	post_code(POST_CAR_ROM_CACHE)
1471223d737SSimon Glass#ifdef CONFIG_CACHE_MRC_BIN
1481223d737SSimon Glass	/* Enable caching for ram init code to run faster */
1491223d737SSimon Glass	movl	$MTRR_PHYS_BASE_MSR(2), %ecx
1501223d737SSimon Glass	movl	$(CACHE_MRC_BASE | MTRR_TYPE_WRPROT), %eax
1511223d737SSimon Glass	xorl	%edx, %edx
1521223d737SSimon Glass	wrmsr
1531223d737SSimon Glass	movl	$MTRR_PHYS_MASK_MSR(2), %ecx
1541223d737SSimon Glass	movl	$(CACHE_MRC_MASK | MTRR_PHYS_MASK_VALID), %eax
1551223d737SSimon Glass	movl	$CPU_PHYSMASK_HI, %edx
1561223d737SSimon Glass	wrmsr
1571223d737SSimon Glass#endif
1581223d737SSimon Glass
1591223d737SSimon Glass	post_code(POST_CAR_MRC_CACHE)
1601223d737SSimon Glass	/* Enable cache */
1611223d737SSimon Glass	movl	%cr0, %eax
1621223d737SSimon Glass	andl	$(~(X86_CR0_CD | X86_CR0_NW)), %eax
1631223d737SSimon Glass	movl	%eax, %cr0
1641223d737SSimon Glass
1651223d737SSimon Glass	post_code(POST_CAR_CPU_CACHE)
1661223d737SSimon Glass
1671223d737SSimon Glass	/* All CPUs need to be in Wait for SIPI state */
1681223d737SSimon Glasswait_for_sipi:
1691223d737SSimon Glass	movl	(%esi), %eax
1701223d737SSimon Glass	bt	$12, %eax
1711223d737SSimon Glass	jc	wait_for_sipi
1721223d737SSimon Glass
1731223d737SSimon Glass	/* return */
1741223d737SSimon Glass	jmp	car_init_ret
1751223d737SSimon Glass
1761223d737SSimon Glass.globl car_uninit
1771223d737SSimon Glasscar_uninit:
1781223d737SSimon Glass	/* Disable cache */
1791223d737SSimon Glass	movl	%cr0, %eax
1801223d737SSimon Glass	orl	$X86_CR0_CD, %eax
1811223d737SSimon Glass	movl	%eax, %cr0
1821223d737SSimon Glass
1831223d737SSimon Glass	/* Disable MTRRs */
1841223d737SSimon Glass	movl	$MTRR_DEF_TYPE_MSR, %ecx
1851223d737SSimon Glass	rdmsr
1861223d737SSimon Glass	andl	$(~MTRR_DEF_TYPE_EN), %eax
1871223d737SSimon Glass	wrmsr
1881223d737SSimon Glass
1891223d737SSimon Glass	/* Disable the no-eviction run state */
1901223d737SSimon Glass	movl    $NOEVICTMOD_MSR, %ecx
1911223d737SSimon Glass	rdmsr
1921223d737SSimon Glass	andl    $~2, %eax
1931223d737SSimon Glass	wrmsr
1941223d737SSimon Glass
1951223d737SSimon Glass	invd
1961223d737SSimon Glass
1971223d737SSimon Glass	/* Disable the no-eviction mode */
1981223d737SSimon Glass	rdmsr
1991223d737SSimon Glass	andl    $~1, %eax
2001223d737SSimon Glass	wrmsr
2011223d737SSimon Glass
2021223d737SSimon Glass#ifdef CONFIG_CACHE_MRC_BIN
2031223d737SSimon Glass	/* Clear the MTRR that was used to cache MRC */
2041223d737SSimon Glass	xorl	%eax, %eax
2051223d737SSimon Glass	xorl	%edx, %edx
2061223d737SSimon Glass	movl	$MTRR_PHYS_BASE_MSR(2), %ecx
2071223d737SSimon Glass	wrmsr
2081223d737SSimon Glass	movl	$MTRR_PHYS_MASK_MSR(2), %ecx
2091223d737SSimon Glass	wrmsr
2101223d737SSimon Glass#endif
2111223d737SSimon Glass
2121223d737SSimon Glass	/* Enable MTRRs */
2131223d737SSimon Glass	movl	$MTRR_DEF_TYPE_MSR, %ecx
2141223d737SSimon Glass	rdmsr
2151223d737SSimon Glass	orl	$MTRR_DEF_TYPE_EN, %eax
2161223d737SSimon Glass	wrmsr
2171223d737SSimon Glass
2181223d737SSimon Glass	invd
2191223d737SSimon Glass
2201223d737SSimon Glass	ret
2211223d737SSimon Glass
2221223d737SSimon Glassmtrr_table:
2231223d737SSimon Glass	/* Fixed MTRRs */
2241223d737SSimon Glass	.word 0x250, 0x258, 0x259
2251223d737SSimon Glass	.word 0x268, 0x269, 0x26A
2261223d737SSimon Glass	.word 0x26B, 0x26C, 0x26D
2271223d737SSimon Glass	.word 0x26E, 0x26F
2281223d737SSimon Glass	/* Variable MTRRs */
2291223d737SSimon Glass	.word 0x200, 0x201, 0x202, 0x203
2301223d737SSimon Glass	.word 0x204, 0x205, 0x206, 0x207
2311223d737SSimon Glass	.word 0x208, 0x209, 0x20A, 0x20B
2321223d737SSimon Glass	.word 0x20C, 0x20D, 0x20E, 0x20F
2331223d737SSimon Glass	.word 0x210, 0x211, 0x212, 0x213
2341223d737SSimon Glassmtrr_table_end:
2351223d737SSimon Glass
2361223d737SSimon Glass	.align 4
2371223d737SSimon Glass_dt_ucode_base_size:
2381223d737SSimon Glass	/* These next two fields are filled in by ifdtool */
239e77b62e2SSimon Glass.globl ucode_base
240e77b62e2SSimon Glassucode_base:	/* Declared in microcode.h */
2411223d737SSimon Glass	.long	0			/* microcode base */
242*8199a145SIvan Gorinov.globl ucode_size
243*8199a145SIvan Gorinovucode_size:	/* Declared in microcode.h */
2441223d737SSimon Glass	.long	0			/* microcode size */
245