diff --git a/src/arch/x86/car.ld b/src/arch/x86/car.ld index 9d54037b7a..bbfd682934 100644 --- a/src/arch/x86/car.ld +++ b/src/arch/x86/car.ld @@ -122,6 +122,7 @@ _car_region_end = . + CONFIG_DCACHE_RAM_SIZE - (. - _car_region_start) } #if ENV_BOOTBLOCK +. = ALIGN(64); _car_mtrr_end = .; _car_mtrr_start = _car_region_start; diff --git a/src/cpu/intel/car/non-evict/cache_as_ram.S b/src/cpu/intel/car/non-evict/cache_as_ram.S index 7186422595..91035dabb4 100644 --- a/src/cpu/intel/car/non-evict/cache_as_ram.S +++ b/src/cpu/intel/car/non-evict/cache_as_ram.S @@ -151,21 +151,16 @@ update_microcode: jmp update_bsp_microcode end_microcode_update: #endif - /* Disable caching to change MTRR's. */ + + /* Disable caching. */ movl %cr0, %eax orl $CR0_CacheDisable, %eax movl %eax, %cr0 - /* Clear the mask valid to disable the MTRR */ - movl $MTRR_PHYS_MASK(1), %ecx - rdmsr - andl $(~MTRR_PHYS_MASK_VALID), %eax - wrmsr - - /* Enable cache. */ - movl %cr0, %eax - andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax invd + + /* Enable caching */ + andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax movl %eax, %cr0 /* enable the 'no eviction' mode */ @@ -175,36 +170,46 @@ end_microcode_update: andl $~2, %eax wrmsr - /* Clear the cache memory region. This will also fill up the cache. */ - cld - xorl %eax, %eax + /* Fill up the cache next. */ movl $_car_mtrr_start, %edi - movl $_car_mtrr_size, %ecx - shr $2, %ecx - rep stosl - /* enable the 'no eviction run' state */ + /* Number of loops. */ + movl $_car_mtrr_size, %ecx + shr $6, %ecx + xorl %ebx, %ebx + mov $64, %bl + +1: + /* + * BWG: *One* location in each 64-byte cache line must be written + * to set all cached values to modified state. + * + * Value of %eax doesn't matter here. CAR is zeroed later. + * + * Zeroing the whole cache here *not* work when CR0.CD = 0. + * Zeroing the whole cache here *does* work when CR0.CD = 1, + * but will be a couple of times slower (4 times on Sandy Bridge). + */ + movl %eax, (%edi) + addl %ebx, %edi + + loop 1b + + /* enable the 'no eviction run' state. */ movl $NoEvictMod_MSR, %ecx rdmsr - orl $3, %eax - wrmsr - - post_code(POSTCODE_SOC_DISABLE_CACHE) - /* Enable Cache-as-RAM mode by disabling cache. */ - movl %cr0, %eax - orl $CR0_CacheDisable, %eax - movl %eax, %cr0 - - movl $MTRR_PHYS_MASK(1), %ecx - rdmsr - orl $MTRR_PHYS_MASK_VALID, %eax + or $3, %al wrmsr post_code(POSTCODE_SOC_ENABLE_CACHE) - /* Enable cache. */ - movl %cr0, %eax - andl $(~(CR0_CacheDisable | CR0_NoWriteThrough)), %eax - movl %eax, %cr0 + + /* Now that CAR is enabled clear it. */ + movl $_car_mtrr_start, %edi + movl $_car_mtrr_size, %ecx + cld + xorl %eax, %eax + shr $2, %ecx + rep stosl /* Setup the stack. */ mov $_ecar_stack, %esp