aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/mm/init.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-02-07 02:44:37 -0500
committerDavid S. Miller <davem@sunset.davemloft.net>2006-03-20 04:11:52 -0500
commitd257d5da39a78b32721ca84b2ba7f461f2f7ed7f (patch)
treeac28d377688ebe13a4d38e05f4ff65ba73d8652a /arch/sparc64/mm/init.c
parent840aaef8db32572b6d11e0d5cb5e6efcbc812000 (diff)
[SPARC64]: Initial sun4v TLB miss handling infrastructure.
Things are a little tricky because, unlike sun4u, we have to: 1) do a hypervisor trap to do the TLB load. 2) do the TSB lookup calculations by hand Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/mm/init.c')
-rw-r--r--arch/sparc64/mm/init.c24
1 files changed, 23 insertions, 1 deletions
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index ab50cd9618f3..e9aac424877f 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -1050,8 +1050,25 @@ unsigned long __init find_ecache_flush_span(unsigned long size)
1050 1050
1051static void __init tsb_phys_patch(void) 1051static void __init tsb_phys_patch(void)
1052{ 1052{
1053 struct tsb_ldquad_phys_patch_entry *pquad;
1053 struct tsb_phys_patch_entry *p; 1054 struct tsb_phys_patch_entry *p;
1054 1055
1056 pquad = &__tsb_ldquad_phys_patch;
1057 while (pquad < &__tsb_ldquad_phys_patch_end) {
1058 unsigned long addr = pquad->addr;
1059
1060 if (tlb_type == hypervisor)
1061 *(unsigned int *) addr = pquad->sun4v_insn;
1062 else
1063 *(unsigned int *) addr = pquad->sun4u_insn;
1064 wmb();
1065 __asm__ __volatile__("flush %0"
1066 : /* no outputs */
1067 : "r" (addr));
1068
1069 pquad++;
1070 }
1071
1055 p = &__tsb_phys_patch; 1072 p = &__tsb_phys_patch;
1056 while (p < &__tsb_phys_patch_end) { 1073 while (p < &__tsb_phys_patch_end) {
1057 unsigned long addr = p->addr; 1074 unsigned long addr = p->addr;
@@ -1069,6 +1086,7 @@ static void __init tsb_phys_patch(void)
1069/* paging_init() sets up the page tables */ 1086/* paging_init() sets up the page tables */
1070 1087
1071extern void cheetah_ecache_flush_init(void); 1088extern void cheetah_ecache_flush_init(void);
1089extern void sun4v_patch_tlb_handlers(void);
1072 1090
1073static unsigned long last_valid_pfn; 1091static unsigned long last_valid_pfn;
1074pgd_t swapper_pg_dir[2048]; 1092pgd_t swapper_pg_dir[2048];
@@ -1078,9 +1096,13 @@ void __init paging_init(void)
1078 unsigned long end_pfn, pages_avail, shift; 1096 unsigned long end_pfn, pages_avail, shift;
1079 unsigned long real_end, i; 1097 unsigned long real_end, i;
1080 1098
1081 if (tlb_type == cheetah_plus) 1099 if (tlb_type == cheetah_plus ||
1100 tlb_type == hypervisor)
1082 tsb_phys_patch(); 1101 tsb_phys_patch();
1083 1102
1103 if (tlb_type == hypervisor)
1104 sun4v_patch_tlb_handlers();
1105
1084 /* Find available physical memory... */ 1106 /* Find available physical memory... */
1085 read_obp_memory("available", &pavail[0], &pavail_ents); 1107 read_obp_memory("available", &pavail[0], &pavail_ents);
1086 1108