From d5e4746cf84a8da1b6465058ec7c7cc19c3c32c0 Mon Sep 17 00:00:00 2001
From: Aaron Durbin <adurbin@chromium.org>
Date: Tue, 17 Apr 2018 14:35:48 -0600
Subject: 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>
---
 src/cpu/x86/pae/pgtbl.c   | 70 +++++++++++++++++++++++++----------------------
 src/include/cpu/x86/pae.h |  8 ++++++
 2 files changed, 45 insertions(+), 33 deletions(-)

(limited to 'src')

diff --git a/src/cpu/x86/pae/pgtbl.c b/src/cpu/x86/pae/pgtbl.c
index 063c9aba38..fe7705f4d0 100644
--- a/src/cpu/x86/pae/pgtbl.c
+++ b/src/cpu/x86/pae/pgtbl.c
@@ -17,48 +17,52 @@
 #include <console/console.h>
 #include <cpu/cpu.h>
 #include <arch/cpu.h>
+#include <cpu/x86/cr.h>
 #include <cpu/x86/msr.h>
 #include <cpu/x86/pae.h>
 #include <rules.h>
 #include <string.h>
 
-#if ENV_RAMSTAGE
-static void paging_off(void)
+void paging_enable_pae_cr3(uintptr_t cr3)
 {
-	__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"
-		);
+	/* Load the page table address */
+	write_cr3(cr3);
+	paging_enable_pae();
 }
 
-static void paging_on(void *pdp)
+void paging_enable_pae(void)
 {
-	__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"
-		);
+	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
 void *map_2M_page(unsigned long page)
 {
 	struct pde {
@@ -82,7 +86,7 @@ void *map_2M_page(unsigned long page)
 		return MAPPING_ERROR;
 	window = page >> 10;
 	if (window != mapped_window[index]) {
-		paging_off();
+		paging_disable_pae();
 		if (window > 1) {
 			struct pde *pd, *pdp;
 			/* Point the page directory pointers at the page
@@ -109,7 +113,7 @@ void *map_2M_page(unsigned long page)
 					| ((i & 0x3ff) << 21) | 0xE3;
 				pd[i].addr_hi = (window >> 1);
 			}
-			paging_on(pdp);
+			paging_enable_pae_cr3((uintptr_t)pdp);
 		}
 		mapped_window[index] = window;
 	}
diff --git a/src/include/cpu/x86/pae.h b/src/include/cpu/x86/pae.h
index 9b9f27b688..5bbfdf3aca 100644
--- a/src/include/cpu/x86/pae.h
+++ b/src/include/cpu/x86/pae.h
@@ -3,6 +3,14 @@
 
 #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 */
 void paging_set_nxe(int enable);
 
-- 
cgit v1.2.3