cpu/x86: expose and add paging helper functions

Add the following functions for use outside of the paging module:

void paging_enable_pae_cr3(uintptr_t cr3);
void paging_enable_pae(void);
void paging_disable_pae(void);

The functions just enable and/or disable paging along with PAE.
Disassembly shows equivalent output for both versions.

BUG=b:72728953

Change-Id: I9665e7ec4795a5f52889791f73cf98a8f4def827
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: https://review.coreboot.org/25714
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Furquan Shaikh <furquan@google.com>
Reviewed-by: Justin TerAvest <teravest@chromium.org>
This commit is contained in:
Aaron Durbin 2018-04-17 14:35:48 -06:00 committed by Patrick Georgi
parent ae18f80feb
commit d5e4746cf8
2 changed files with 50 additions and 38 deletions

View File

@ -17,48 +17,52 @@
#include <console/console.h> #include <console/console.h>
#include <cpu/cpu.h> #include <cpu/cpu.h>
#include <arch/cpu.h> #include <arch/cpu.h>
#include <cpu/x86/cr.h>
#include <cpu/x86/msr.h> #include <cpu/x86/msr.h>
#include <cpu/x86/pae.h> #include <cpu/x86/pae.h>
#include <rules.h> #include <rules.h>
#include <string.h> #include <string.h>
void paging_enable_pae_cr3(uintptr_t cr3)
{
/* Load the page table address */
write_cr3(cr3);
paging_enable_pae();
}
void paging_enable_pae(void)
{
CRx_TYPE cr0;
CRx_TYPE cr4;
/* Enable PAE */
cr4 = read_cr4();
cr4 |= CR4_PAE;
write_cr4(cr4);
/* Enable Paging */
cr0 = read_cr0();
cr0 |= CR0_PG;
write_cr0(cr0);
}
void paging_disable_pae(void)
{
CRx_TYPE cr0;
CRx_TYPE cr4;
/* Disable Paging */
cr0 = read_cr0();
cr0 &= ~(CRx_TYPE)CR0_PG;
write_cr0(cr0);
/* Disable PAE */
cr4 = read_cr4();
cr4 &= ~(CRx_TYPE)CR4_PAE;
write_cr4(cr4);
}
#if ENV_RAMSTAGE #if ENV_RAMSTAGE
static void paging_off(void)
{
__asm__ __volatile__ (
/* Disable paging */
"movl %%cr0, %%eax\n\t"
"andl $0x7FFFFFFF, %%eax\n\t"
"movl %%eax, %%cr0\n\t"
/* Disable pae */
"movl %%cr4, %%eax\n\t"
"andl $0xFFFFFFDF, %%eax\n\t"
"movl %%eax, %%cr4\n\t"
:
:
: "eax"
);
}
static void paging_on(void *pdp)
{
__asm__ __volatile__(
/* Load the page table address */
"movl %0, %%cr3\n\t"
/* Enable pae */
"movl %%cr4, %%eax\n\t"
"orl $0x00000020, %%eax\n\t"
"movl %%eax, %%cr4\n\t"
/* Enable paging */
"movl %%cr0, %%eax\n\t"
"orl $0x80000000, %%eax\n\t"
"movl %%eax, %%cr0\n\t"
:
: "r" (pdp)
: "eax"
);
}
void *map_2M_page(unsigned long page) void *map_2M_page(unsigned long page)
{ {
struct pde { struct pde {
@ -82,7 +86,7 @@ void *map_2M_page(unsigned long page)
return MAPPING_ERROR; return MAPPING_ERROR;
window = page >> 10; window = page >> 10;
if (window != mapped_window[index]) { if (window != mapped_window[index]) {
paging_off(); paging_disable_pae();
if (window > 1) { if (window > 1) {
struct pde *pd, *pdp; struct pde *pd, *pdp;
/* Point the page directory pointers at the page /* Point the page directory pointers at the page
@ -109,7 +113,7 @@ void *map_2M_page(unsigned long page)
| ((i & 0x3ff) << 21) | 0xE3; | ((i & 0x3ff) << 21) | 0xE3;
pd[i].addr_hi = (window >> 1); pd[i].addr_hi = (window >> 1);
} }
paging_on(pdp); paging_enable_pae_cr3((uintptr_t)pdp);
} }
mapped_window[index] = window; mapped_window[index] = window;
} }

View File

@ -3,6 +3,14 @@
#include <stdint.h> #include <stdint.h>
/* Enable paging with cr3 value for page directory pointer table as well as PAE
option in cr4. */
void paging_enable_pae_cr3(uintptr_t cr3);
/* Enable paging as well as PAE option in cr4. */
void paging_enable_pae(void);
/* Disable paging as well as PAE option in cr4. */
void paging_disable_pae(void);
/* Set/Clear NXE bit in IA32_EFER MSR */ /* Set/Clear NXE bit in IA32_EFER MSR */
void paging_set_nxe(int enable); void paging_set_nxe(int enable);