memtest86plus/system/cache.h
Martin Whitaker d9fee4dcbb Flush caches between writing and verifying test data.
Mostly we write and read large chunks of data which will make it likely
that the data is no longer in the cache when we come to verify it. But
this is not always true, and in any case, we shouldn't rely on it.
2021-12-23 11:00:10 +00:00

78 lines
1.7 KiB
C

// SPDX-License-Identifier: GPL-2.0
#ifndef CACHE_H
#define CACHE_H
/*
* Provides functions to enable, disable, and flush the CPU caches.
*
* Copyright (C) 2020-2021 Martin Whitaker.
*/
/*
* Disable the CPU caches.
*/
static inline void cache_off(void)
{
#ifdef __x86_64__
__asm__ __volatile__ ("\t"
"movq %%cr0, %%rax \n\t"
"orl $0x40000000, %%eax \n\t" /* Set CD */
"movq %%rax, %%cr0 \n\t"
"wbinvd \n"
: /* no outputs */
: /* no inputs */
: "rax", "memory"
);
#else
__asm__ __volatile__ ("\t"
"movl %%cr0, %%eax \n\t"
"orl $0x40000000, %%eax \n\t" /* Set CD */
"movl %%eax, %%cr0 \n\t"
"wbinvd \n"
: /* no outputs */
: /* no inputs */
: "eax", "memory"
);
#endif
}
/*
* Enable the CPU caches.
*/
static inline void cache_on(void)
{
#ifdef __x86_64__
__asm__ __volatile__ ("\t"
"movq %%cr0, %%rax \n\t"
"andl $0x9fffffff, %%eax \n\t" /* Clear CD and NW */
"movq %%rax, %%cr0 \n"
: /* no outputs */
: /* no inputs */
: "rax", "memory"
);
#else
__asm__ __volatile__ ("\t"
"movl %%cr0, %%eax \n\t"
"andl $0x9fffffff, %%eax \n\t" /* Clear CD and NW */
"movl %%eax, %%cr0 \n"
: /* no outputs */
: /* no inputs */
: "eax", "memory"
);
#endif
}
/*
* Flush the CPU caches.
*/
static inline void cache_flush(void)
{
__asm__ __volatile__ ("\t"
"wbinvd\n"
: /* no outputs */
: /* no inputs */
: "memory"
);
}
#endif // CACHE_H