blob: 814c5f161fa5d27ba3fd2bbd8a8e755bd5122752 [file] [log] [blame]
Yinghai Lu72ee9b02005-12-14 02:39:33 +00001/*
Stefan Reinauerf8ee1802008-01-18 15:08:58 +00002 2005.12 yhlu add coreboot_ram cross the vga font buffer handling
Yinghai Lu72ee9b02005-12-14 02:39:33 +00003*/
4
Eric Biedermanfcd5ace2004-10-14 19:29:29 +00005#include <console/console.h>
6#include <cpu/cpu.h>
7#include <cpu/x86/pae.h>
8#include <string.h>
9
10static void paging_off(void)
11{
12 __asm__ __volatile__ (
13 /* Disable paging */
14 "movl %%cr0, %%eax\n\t"
15 "andl $0x7FFFFFFF, %%eax\n\t"
16 "movl %%eax, %%cr0\n\t"
17 /* Disable pae */
18 "movl %%cr4, %%eax\n\t"
19 "andl $0xFFFFFFDF, %%eax\n\t"
Eric Biedermana172d982004-10-19 05:07:18 +000020 "movl %%eax, %%cr4\n\t"
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000021 :
22 :
23 : "eax"
24 );
25}
26
27static void paging_on(void *pdp)
28{
29 __asm__ __volatile__(
30 /* Load the page table address */
31 "movl %0, %%cr3\n\t"
32 /* Enable pae */
33 "movl %%cr4, %%eax\n\t"
34 "orl $0x00000020, %%eax\n\t"
35 "movl %%eax, %%cr4\n\t"
36 /* Enable paging */
37 "movl %%cr0, %%eax\n\t"
38 "orl $0x80000000, %%eax\n\t"
39 "movl %%eax, %%cr0\n\t"
40 :
41 : "r" (pdp)
42 : "eax"
43 );
44}
45
Stefan Reinauer14e22772010-04-27 06:56:47 +000046void *map_2M_page(unsigned long page)
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000047{
48 struct pde {
49 uint32_t addr_lo;
50 uint32_t addr_hi;
51 } __attribute__ ((packed));
52 struct pg_table {
53 struct pde pd[2048];
54 struct pde pdp[512];
55 } __attribute__ ((packed));
Yinghai Lu72ee9b02005-12-14 02:39:33 +000056
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000057 static struct pg_table pgtbl[CONFIG_MAX_CPUS] __attribute__ ((aligned(4096)));
Eric Biedermanfcd5ace2004-10-14 19:29:29 +000058 static unsigned long mapped_window[CONFIG_MAX_CPUS];
59 unsigned long index;
60 unsigned long window;
61 void *result;
62 int i;
63 index = cpu_index();
64 if ((index < 0) || (index >= CONFIG_MAX_CPUS)) {
65 return MAPPING_ERROR;
66 }
67 window = page >> 10;
68 if (window != mapped_window[index]) {
69 paging_off();
70 if (window > 1) {
71 struct pde *pd, *pdp;
72 /* Point the page directory pointers at the page directories */
73 memset(&pgtbl[index].pdp, 0, sizeof(pgtbl[index].pdp));
74 pd = pgtbl[index].pd;
75 pdp = pgtbl[index].pdp;
76 pdp[0].addr_lo = ((uint32_t)&pd[512*0])|1;
77 pdp[1].addr_lo = ((uint32_t)&pd[512*1])|1;
78 pdp[2].addr_lo = ((uint32_t)&pd[512*2])|1;
79 pdp[3].addr_lo = ((uint32_t)&pd[512*3])|1;
80 /* The first half of the page table is identity mapped */
81 for(i = 0; i < 1024; i++) {
82 pd[i].addr_lo = ((i & 0x3ff) << 21)| 0xE3;
83 pd[i].addr_hi = 0;
84 }
85 /* The second half of the page table holds the mapped page */
86 for(i = 1024; i < 2048; i++) {
87 pd[i].addr_lo = ((window & 1) << 31) | ((i & 0x3ff) << 21) | 0xE3;
88 pd[i].addr_hi = (window >> 1);
89 }
90 paging_on(pdp);
91 }
92 mapped_window[index] = window;
93 }
94 if (window == 0) {
95 result = (void *)(page << 21);
96 } else {
97 result = (void *)(0x80000000 | ((page & 0x3ff) << 21));
98 }
99 return result;
100}