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