diff options
author | David S. Miller <davem@davemloft.net> | 2013-09-21 00:50:41 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-11-12 18:22:34 -0500 |
commit | b2d438348024b75a1ee8b66b85d77f569a5dfed8 (patch) | |
tree | 057c725d9d058d326533d0947aedd226adb57540 /arch/sparc/kernel | |
parent | f998c9c0d663b013e3aa3ba78908396c8c497218 (diff) |
sparc64: Make PAGE_OFFSET variable.
Choose PAGE_OFFSET dynamically based upon cpu type.
Original UltraSPARC-I (spitfire) chips only supported a 44-bit
virtual address space.
Newer chips (T4 and later) support 52-bit virtual addresses
and up to 47-bits of physical memory space.
Therefore we have to adjust PAGE_SIZE dynamically based upon
the capabilities of the chip.
Note that this change alone does not allow us to support > 43-bit
physical memory, to do that we need to re-arrange our page table
support. The current encodings of the pmd_t and pgd_t pointers
restricts us to "32 + 11" == 43 bits.
This change can waste quite a bit of memory for the various tables.
In particular, a future change should work to size and allocate
kern_linear_bitmap[] and sparc64_valid_addr_bitmap[] dynamically.
This isn't easy as we really cannot take a TLB miss when accessing
kern_linear_bitmap[]. We'd have to lock it into the TLB or similar.
Signed-off-by: David S. Miller <davem@davemloft.net>
Acked-by: Bob Picco <bob.picco@oracle.com>
Diffstat (limited to 'arch/sparc/kernel')
-rw-r--r-- | arch/sparc/kernel/ktlb.S | 30 | ||||
-rw-r--r-- | arch/sparc/kernel/vmlinux.lds.S | 5 |
2 files changed, 30 insertions, 5 deletions
diff --git a/arch/sparc/kernel/ktlb.S b/arch/sparc/kernel/ktlb.S index 7ad46bc0c698..542e96ac4d39 100644 --- a/arch/sparc/kernel/ktlb.S +++ b/arch/sparc/kernel/ktlb.S | |||
@@ -153,12 +153,19 @@ kvmap_dtlb_tsb4m_miss: | |||
153 | /* Clear the PAGE_OFFSET top virtual bits, shift | 153 | /* Clear the PAGE_OFFSET top virtual bits, shift |
154 | * down to get PFN, and make sure PFN is in range. | 154 | * down to get PFN, and make sure PFN is in range. |
155 | */ | 155 | */ |
156 | sllx %g4, PAGE_OFFSET_VA_BITS, %g5 | 156 | 661: sllx %g4, 0, %g5 |
157 | .section .page_offset_shift_patch, "ax" | ||
158 | .word 661b | ||
159 | .previous | ||
157 | 160 | ||
158 | /* Check to see if we know about valid memory at the 4MB | 161 | /* Check to see if we know about valid memory at the 4MB |
159 | * chunk this physical address will reside within. | 162 | * chunk this physical address will reside within. |
160 | */ | 163 | */ |
161 | srlx %g5, PAGE_OFFSET_VA_BITS + MAX_PHYS_ADDRESS_BITS, %g2 | 164 | 661: srlx %g5, MAX_PHYS_ADDRESS_BITS, %g2 |
165 | .section .page_offset_shift_patch, "ax" | ||
166 | .word 661b | ||
167 | .previous | ||
168 | |||
162 | brnz,pn %g2, kvmap_dtlb_longpath | 169 | brnz,pn %g2, kvmap_dtlb_longpath |
163 | nop | 170 | nop |
164 | 171 | ||
@@ -176,7 +183,11 @@ valid_addr_bitmap_patch: | |||
176 | or %g7, %lo(sparc64_valid_addr_bitmap), %g7 | 183 | or %g7, %lo(sparc64_valid_addr_bitmap), %g7 |
177 | .previous | 184 | .previous |
178 | 185 | ||
179 | srlx %g5, PAGE_OFFSET_VA_BITS + ILOG2_4MB, %g2 | 186 | 661: srlx %g5, ILOG2_4MB, %g2 |
187 | .section .page_offset_shift_patch, "ax" | ||
188 | .word 661b | ||
189 | .previous | ||
190 | |||
180 | srlx %g2, 6, %g5 | 191 | srlx %g2, 6, %g5 |
181 | and %g2, 63, %g2 | 192 | and %g2, 63, %g2 |
182 | sllx %g5, 3, %g5 | 193 | sllx %g5, 3, %g5 |
@@ -189,9 +200,18 @@ valid_addr_bitmap_patch: | |||
189 | 2: sethi %hi(kpte_linear_bitmap), %g2 | 200 | 2: sethi %hi(kpte_linear_bitmap), %g2 |
190 | 201 | ||
191 | /* Get the 256MB physical address index. */ | 202 | /* Get the 256MB physical address index. */ |
192 | sllx %g4, PAGE_OFFSET_VA_BITS, %g5 | 203 | 661: sllx %g4, 0, %g5 |
204 | .section .page_offset_shift_patch, "ax" | ||
205 | .word 661b | ||
206 | .previous | ||
207 | |||
193 | or %g2, %lo(kpte_linear_bitmap), %g2 | 208 | or %g2, %lo(kpte_linear_bitmap), %g2 |
194 | srlx %g5, PAGE_OFFSET_VA_BITS + ILOG2_256MB, %g5 | 209 | |
210 | 661: srlx %g5, ILOG2_256MB, %g5 | ||
211 | .section .page_offset_shift_patch, "ax" | ||
212 | .word 661b | ||
213 | .previous | ||
214 | |||
195 | and %g5, (32 - 1), %g7 | 215 | and %g5, (32 - 1), %g7 |
196 | 216 | ||
197 | /* Divide by 32 to get the offset into the bitmask. */ | 217 | /* Divide by 32 to get the offset into the bitmask. */ |
diff --git a/arch/sparc/kernel/vmlinux.lds.S b/arch/sparc/kernel/vmlinux.lds.S index 0bacceb19150..932ff90fd760 100644 --- a/arch/sparc/kernel/vmlinux.lds.S +++ b/arch/sparc/kernel/vmlinux.lds.S | |||
@@ -122,6 +122,11 @@ SECTIONS | |||
122 | *(.swapper_4m_tsb_phys_patch) | 122 | *(.swapper_4m_tsb_phys_patch) |
123 | __swapper_4m_tsb_phys_patch_end = .; | 123 | __swapper_4m_tsb_phys_patch_end = .; |
124 | } | 124 | } |
125 | .page_offset_shift_patch : { | ||
126 | __page_offset_shift_patch = .; | ||
127 | *(.page_offset_shift_patch) | ||
128 | __page_offset_shift_patch_end = .; | ||
129 | } | ||
125 | .popc_3insn_patch : { | 130 | .popc_3insn_patch : { |
126 | __popc_3insn_patch = .; | 131 | __popc_3insn_patch = .; |
127 | *(.popc_3insn_patch) | 132 | *(.popc_3insn_patch) |