diff options
Diffstat (limited to 'src/cpu/x86')
-rw-r--r-- | src/cpu/x86/pae/pgtbl.c | 47 |
1 files changed, 47 insertions, 0 deletions
diff --git a/src/cpu/x86/pae/pgtbl.c b/src/cpu/x86/pae/pgtbl.c index cd03547ef8..c272b2da1c 100644 --- a/src/cpu/x86/pae/pgtbl.c +++ b/src/cpu/x86/pae/pgtbl.c @@ -13,6 +13,7 @@ * GNU General Public License for more details. */ +#include <cbfs.h> #include <compiler.h> #include <console/console.h> #include <cpu/cpu.h> @@ -22,6 +23,7 @@ #include <cpu/x86/pae.h> #include <rules.h> #include <string.h> +#include <symbols.h> void paging_enable_pae_cr3(uintptr_t cr3) { @@ -169,3 +171,48 @@ void paging_set_default_pat(void) PAT_ENCODE(UC_MINUS, 6) | PAT_ENCODE(WT, 7); paging_set_pat(pat); } + +static int read_from_cbfs(const char *name, void *buf, size_t size) +{ + struct cbfsf fh; + struct region_device rdev; + size_t rdev_sz; + + if (cbfs_boot_locate(&fh, name, NULL)) + return -1; + + cbfs_file_data(&rdev, &fh); + + rdev_sz = region_device_sz(&rdev); + + if (size < rdev_sz) { + printk(BIOS_ERR, "%s region too small to load: %zx < %zx\n", + name, size, rdev_sz); + return -1; + } + + if (rdev_readat(&rdev, buf, 0, rdev_sz) != rdev_sz) + return -1; + + return 0; +} + +int paging_enable_for_car(const char *pdpt_name, const char *pt_name) +{ + if (!ENV_CACHE_AS_RAM) + return -1; + + if (read_from_cbfs(pdpt_name, _pdpt, _pdpt_size)) { + printk(BIOS_ERR, "Couldn't load pdpt\n"); + return -1; + } + + if (read_from_cbfs(pt_name, _pagetables, _pagetables_size)) { + printk(BIOS_ERR, "Couldn't load page tables\n"); + return -1; + } + + paging_enable_pae_cr3((uintptr_t)_pdpt); + + return 0; +} |