Add various constants for the PAT MSR and the PAT PTE and PDE flags.
Initialize the PAT MSR during boot to map PAT type 2 to Write-Combining (WC) instead of Uncached (UC-). MFC after: 1 month
This commit is contained in:
parent
20e3d71cdd
commit
2b8a339c7e
@ -514,6 +514,9 @@ init_secondary(void)
|
||||
while (!aps_ready)
|
||||
ia32_pause();
|
||||
|
||||
/* Initialize the PAT MSR. */
|
||||
pmap_init_pat();
|
||||
|
||||
/* set up CPU registers and state */
|
||||
cpu_setregs();
|
||||
|
||||
|
@ -551,6 +551,51 @@ pmap_bootstrap(firstaddr)
|
||||
*CMAP1 = 0;
|
||||
|
||||
invltlb();
|
||||
|
||||
/* Initialize the PAT MSR. */
|
||||
pmap_init_pat();
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the PAT MSR.
|
||||
*/
|
||||
void
|
||||
pmap_init_pat(void)
|
||||
{
|
||||
uint64_t pat_msr;
|
||||
|
||||
/* Bail if this CPU doesn't implement PAT. */
|
||||
if (!(cpu_feature & CPUID_PAT))
|
||||
panic("no PAT??");
|
||||
|
||||
#ifdef PAT_WORKS
|
||||
/*
|
||||
* Leave the indices 0-3 at the default of WB, WT, UC, and UC-.
|
||||
* Program 4 and 5 as WP and WC.
|
||||
* Leave 6 and 7 as UC and UC-.
|
||||
*/
|
||||
pat_msr = rdmsr(MSR_PAT);
|
||||
pat_msr &= ~(PAT_MASK(4) | PAT_MASK(5));
|
||||
pat_msr |= PAT_VALUE(4, PAT_WRITE_PROTECTED) |
|
||||
PAT_VALUE(5, PAT_WRITE_COMBINING);
|
||||
#else
|
||||
/*
|
||||
* Due to some Intel errata, we can only safely use the lower 4
|
||||
* PAT entries. Thus, just replace PAT Index 2 with WC instead
|
||||
* of UC-.
|
||||
*
|
||||
* Intel Pentium III Processor Specification Update
|
||||
* Errata E.27 (Upper Four PAT Entries Not Usable With Mode B
|
||||
* or Mode C Paging)
|
||||
*
|
||||
* Intel Pentium IV Processor Specification Update
|
||||
* Errata N46 (PAT Index MSB May Be Calculated Incorrectly)
|
||||
*/
|
||||
pat_msr = rdmsr(MSR_PAT);
|
||||
pat_msr &= ~PAT_MASK(2);
|
||||
pat_msr |= PAT_VALUE(2, PAT_WRITE_COMBINING);
|
||||
#endif
|
||||
wrmsr(MSR_PAT, pat_msr);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -58,10 +58,12 @@
|
||||
#define PG_A 0x020 /* A Accessed */
|
||||
#define PG_M 0x040 /* D Dirty */
|
||||
#define PG_PS 0x080 /* PS Page size (0=4k,1=4M) */
|
||||
#define PG_PTE_PAT 0x080 /* PAT PAT index */
|
||||
#define PG_G 0x100 /* G Global */
|
||||
#define PG_AVAIL1 0x200 /* / Available for system */
|
||||
#define PG_AVAIL2 0x400 /* < programmers use */
|
||||
#define PG_AVAIL3 0x800 /* \ */
|
||||
#define PG_PDE_PAT 0x1000 /* PAT PAT index */
|
||||
#define PG_NX (1ul<<63) /* No-execute */
|
||||
|
||||
|
||||
@ -300,6 +302,7 @@ extern vm_offset_t virtual_end;
|
||||
#define pmap_page_is_mapped(m) (!TAILQ_EMPTY(&(m)->md.pv_list))
|
||||
|
||||
void pmap_bootstrap(vm_paddr_t *);
|
||||
void pmap_init_pat(void);
|
||||
void pmap_kenter(vm_offset_t va, vm_paddr_t pa);
|
||||
void *pmap_kenter_temporary(vm_paddr_t pa, int i);
|
||||
vm_paddr_t pmap_kextract(vm_offset_t);
|
||||
|
@ -229,6 +229,18 @@
|
||||
#define APICBASE_ENABLED 0x00000800
|
||||
#define APICBASE_ADDRESS 0xfffff000
|
||||
|
||||
/*
|
||||
* PAT modes.
|
||||
*/
|
||||
#define PAT_UNCACHEABLE 0x00
|
||||
#define PAT_WRITE_COMBINING 0x01
|
||||
#define PAT_WRITE_THROUGH 0x04
|
||||
#define PAT_WRITE_PROTECTED 0x05
|
||||
#define PAT_WRITE_BACK 0x06
|
||||
#define PAT_UNCACHED 0x07
|
||||
#define PAT_VALUE(i, m) ((long)(m) << (8 * (i)))
|
||||
#define PAT_MASK(i) PAT_VALUE(i, 0xff)
|
||||
|
||||
/*
|
||||
* Constants related to MTRRs
|
||||
*/
|
||||
|
@ -563,6 +563,9 @@ init_secondary(void)
|
||||
lidt(&r_idt);
|
||||
#endif
|
||||
|
||||
/* Initialize the PAT MSR if present. */
|
||||
pmap_init_pat();
|
||||
|
||||
/* set up CPU registers and state */
|
||||
cpu_setregs();
|
||||
|
||||
|
@ -419,10 +419,55 @@ pmap_bootstrap(firstaddr, loadaddr)
|
||||
for (i = 0; i < NKPT; i++)
|
||||
PTD[i] = 0;
|
||||
|
||||
/* Initialize the PAT MSR if present. */
|
||||
pmap_init_pat();
|
||||
|
||||
/* Turn on PG_G on kernel page(s) */
|
||||
pmap_set_pg();
|
||||
}
|
||||
|
||||
/*
|
||||
* Setup the PAT MSR.
|
||||
*/
|
||||
void
|
||||
pmap_init_pat(void)
|
||||
{
|
||||
uint64_t pat_msr;
|
||||
|
||||
/* Bail if this CPU doesn't implement PAT. */
|
||||
if (!(cpu_feature & CPUID_PAT))
|
||||
return;
|
||||
|
||||
#ifdef PAT_WORKS
|
||||
/*
|
||||
* Leave the indices 0-3 at the default of WB, WT, UC, and UC-.
|
||||
* Program 4 and 5 as WP and WC.
|
||||
* Leave 6 and 7 as UC and UC-.
|
||||
*/
|
||||
pat_msr = rdmsr(MSR_PAT);
|
||||
pat_msr &= ~(PAT_MASK(4) | PAT_MASK(5));
|
||||
pat_msr |= PAT_VALUE(4, PAT_WRITE_PROTECTED) |
|
||||
PAT_VALUE(5, PAT_WRITE_COMBINING);
|
||||
#else
|
||||
/*
|
||||
* Due to some Intel errata, we can only safely use the lower 4
|
||||
* PAT entries. Thus, just replace PAT Index 2 with WC instead
|
||||
* of UC-.
|
||||
*
|
||||
* Intel Pentium III Processor Specification Update
|
||||
* Errata E.27 (Upper Four PAT Entries Not Usable With Mode B
|
||||
* or Mode C Paging)
|
||||
*
|
||||
* Intel Pentium IV Processor Specification Update
|
||||
* Errata N46 (PAT Index MSB May Be Calculated Incorrectly)
|
||||
*/
|
||||
pat_msr = rdmsr(MSR_PAT);
|
||||
pat_msr &= ~PAT_MASK(2);
|
||||
pat_msr |= PAT_VALUE(2, PAT_WRITE_COMBINING);
|
||||
#endif
|
||||
wrmsr(MSR_PAT, pat_msr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set PG_G on kernel pages. Only the BSP calls this when SMP is turned on.
|
||||
*/
|
||||
|
@ -57,10 +57,12 @@
|
||||
#define PG_A 0x020 /* A Accessed */
|
||||
#define PG_M 0x040 /* D Dirty */
|
||||
#define PG_PS 0x080 /* PS Page size (0=4k,1=4M) */
|
||||
#define PG_PTE_PAT 0x080 /* PAT PAT index */
|
||||
#define PG_G 0x100 /* G Global */
|
||||
#define PG_AVAIL1 0x200 /* / Available for system */
|
||||
#define PG_AVAIL2 0x400 /* < programmers use */
|
||||
#define PG_AVAIL3 0x800 /* \ */
|
||||
#define PG_PDE_PAT 0x1000 /* PAT PAT index */
|
||||
|
||||
|
||||
/* Our various interpretations of the above */
|
||||
@ -368,6 +370,7 @@ extern vm_offset_t virtual_end;
|
||||
#define pmap_page_is_mapped(m) (!TAILQ_EMPTY(&(m)->md.pv_list))
|
||||
|
||||
void pmap_bootstrap(vm_paddr_t, vm_paddr_t);
|
||||
void pmap_init_pat(void);
|
||||
void pmap_kenter(vm_offset_t va, vm_paddr_t pa);
|
||||
void *pmap_kenter_temporary(vm_paddr_t pa, int i);
|
||||
void pmap_kremove(vm_offset_t);
|
||||
|
@ -185,6 +185,7 @@
|
||||
#define MSR_MTRR64kBase 0x250
|
||||
#define MSR_MTRR16kBase 0x258
|
||||
#define MSR_MTRR4kBase 0x268
|
||||
#define MSR_PAT 0x277
|
||||
#define MSR_MTRRdefType 0x2ff
|
||||
#define MSR_MC0_CTL 0x400
|
||||
#define MSR_MC0_STATUS 0x401
|
||||
@ -215,6 +216,18 @@
|
||||
#define APICBASE_ENABLED 0x00000800
|
||||
#define APICBASE_ADDRESS 0xfffff000
|
||||
|
||||
/*
|
||||
* PAT modes.
|
||||
*/
|
||||
#define PAT_UNCACHEABLE 0x00
|
||||
#define PAT_WRITE_COMBINING 0x01
|
||||
#define PAT_WRITE_THROUGH 0x04
|
||||
#define PAT_WRITE_PROTECTED 0x05
|
||||
#define PAT_WRITE_BACK 0x06
|
||||
#define PAT_UNCACHED 0x07
|
||||
#define PAT_VALUE(i, m) ((long long)(m) << (8 * (i)))
|
||||
#define PAT_MASK(i) PAT_VALUE(i, 0xff)
|
||||
|
||||
/*
|
||||
* Constants related to MTRRs
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user