aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2013-10-15 09:12:24 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2013-10-18 14:16:01 -0400
commit8754c4bf2ac1a64d5c1409a0ae98e21a8f3541c5 (patch)
tree2a579c5437b1cbf2af86a891bcc2368608983b69 /arch/arm
parent75c912a367fbdc07f0ef6f5384acd5028beb225e (diff)
parenta77e0c7b2774fd52ce6bf25c2c3ffdccb7b110ff (diff)
Merge branch 'for-rmk/arm-mm-lpae' of git://git.kernel.org/pub/scm/linux/kernel/git/ssantosh/linux-keystone into devel-stable
This series extends the existing ARM v2p runtime patching for 64 bit. Needed for LPAE machines which have physical memory beyond 4GB.
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/include/asm/mach/arch.h1
-rw-r--r--arch/arm/include/asm/memory.h75
-rw-r--r--arch/arm/kernel/armksyms.c1
-rw-r--r--arch/arm/kernel/head.S63
-rw-r--r--arch/arm/kernel/setup.c4
-rw-r--r--arch/arm/kernel/smp.c2
-rw-r--r--arch/arm/mm/idmap.c8
-rw-r--r--arch/arm/mm/mmu.c82
8 files changed, 206 insertions, 30 deletions
diff --git a/arch/arm/include/asm/mach/arch.h b/arch/arm/include/asm/mach/arch.h
index 402a2bc6aa68..17a3fa2979e8 100644
--- a/arch/arm/include/asm/mach/arch.h
+++ b/arch/arm/include/asm/mach/arch.h
@@ -49,6 +49,7 @@ struct machine_desc {
49 bool (*smp_init)(void); 49 bool (*smp_init)(void);
50 void (*fixup)(struct tag *, char **, 50 void (*fixup)(struct tag *, char **,
51 struct meminfo *); 51 struct meminfo *);
52 void (*init_meminfo)(void);
52 void (*reserve)(void);/* reserve mem blocks */ 53 void (*reserve)(void);/* reserve mem blocks */
53 void (*map_io)(void);/* IO mapping function */ 54 void (*map_io)(void);/* IO mapping function */
54 void (*init_early)(void); 55 void (*init_early)(void);
diff --git a/arch/arm/include/asm/memory.h b/arch/arm/include/asm/memory.h
index e750a938fd3c..6748d6295a1a 100644
--- a/arch/arm/include/asm/memory.h
+++ b/arch/arm/include/asm/memory.h
@@ -172,8 +172,14 @@
172 * so that all we need to do is modify the 8-bit constant field. 172 * so that all we need to do is modify the 8-bit constant field.
173 */ 173 */
174#define __PV_BITS_31_24 0x81000000 174#define __PV_BITS_31_24 0x81000000
175#define __PV_BITS_7_0 0x81
176
177extern phys_addr_t (*arch_virt_to_idmap) (unsigned long x);
178extern u64 __pv_phys_offset;
179extern u64 __pv_offset;
180extern void fixup_pv_table(const void *, unsigned long);
181extern const void *__pv_table_begin, *__pv_table_end;
175 182
176extern unsigned long __pv_phys_offset;
177#define PHYS_OFFSET __pv_phys_offset 183#define PHYS_OFFSET __pv_phys_offset
178 184
179#define __pv_stub(from,to,instr,type) \ 185#define __pv_stub(from,to,instr,type) \
@@ -185,22 +191,58 @@ extern unsigned long __pv_phys_offset;
185 : "=r" (to) \ 191 : "=r" (to) \
186 : "r" (from), "I" (type)) 192 : "r" (from), "I" (type))
187 193
188static inline unsigned long __virt_to_phys(unsigned long x) 194#define __pv_stub_mov_hi(t) \
195 __asm__ volatile("@ __pv_stub_mov\n" \
196 "1: mov %R0, %1\n" \
197 " .pushsection .pv_table,\"a\"\n" \
198 " .long 1b\n" \
199 " .popsection\n" \
200 : "=r" (t) \
201 : "I" (__PV_BITS_7_0))
202
203#define __pv_add_carry_stub(x, y) \
204 __asm__ volatile("@ __pv_add_carry_stub\n" \
205 "1: adds %Q0, %1, %2\n" \
206 " adc %R0, %R0, #0\n" \
207 " .pushsection .pv_table,\"a\"\n" \
208 " .long 1b\n" \
209 " .popsection\n" \
210 : "+r" (y) \
211 : "r" (x), "I" (__PV_BITS_31_24) \
212 : "cc")
213
214static inline phys_addr_t __virt_to_phys(unsigned long x)
189{ 215{
190 unsigned long t; 216 phys_addr_t t;
191 __pv_stub(x, t, "add", __PV_BITS_31_24); 217
218 if (sizeof(phys_addr_t) == 4) {
219 __pv_stub(x, t, "add", __PV_BITS_31_24);
220 } else {
221 __pv_stub_mov_hi(t);
222 __pv_add_carry_stub(x, t);
223 }
192 return t; 224 return t;
193} 225}
194 226
195static inline unsigned long __phys_to_virt(unsigned long x) 227static inline unsigned long __phys_to_virt(phys_addr_t x)
196{ 228{
197 unsigned long t; 229 unsigned long t;
198 __pv_stub(x, t, "sub", __PV_BITS_31_24); 230 __pv_stub(x, t, "sub", __PV_BITS_31_24);
199 return t; 231 return t;
200} 232}
233
201#else 234#else
202#define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET) 235
203#define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET) 236static inline phys_addr_t __virt_to_phys(unsigned long x)
237{
238 return (phys_addr_t)x - PAGE_OFFSET + PHYS_OFFSET;
239}
240
241static inline unsigned long __phys_to_virt(phys_addr_t x)
242{
243 return x - PHYS_OFFSET + PAGE_OFFSET;
244}
245
204#endif 246#endif
205#endif 247#endif
206#endif /* __ASSEMBLY__ */ 248#endif /* __ASSEMBLY__ */
@@ -238,17 +280,32 @@ static inline phys_addr_t virt_to_phys(const volatile void *x)
238 280
239static inline void *phys_to_virt(phys_addr_t x) 281static inline void *phys_to_virt(phys_addr_t x)
240{ 282{
241 return (void *)(__phys_to_virt((unsigned long)(x))); 283 return (void *)__phys_to_virt(x);
242} 284}
243 285
244/* 286/*
245 * Drivers should NOT use these either. 287 * Drivers should NOT use these either.
246 */ 288 */
247#define __pa(x) __virt_to_phys((unsigned long)(x)) 289#define __pa(x) __virt_to_phys((unsigned long)(x))
248#define __va(x) ((void *)__phys_to_virt((unsigned long)(x))) 290#define __va(x) ((void *)__phys_to_virt((phys_addr_t)(x)))
249#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT) 291#define pfn_to_kaddr(pfn) __va((pfn) << PAGE_SHIFT)
250 292
251/* 293/*
294 * These are for systems that have a hardware interconnect supported alias of
295 * physical memory for idmap purposes. Most cases should leave these
296 * untouched.
297 */
298static inline phys_addr_t __virt_to_idmap(unsigned long x)
299{
300 if (arch_virt_to_idmap)
301 return arch_virt_to_idmap(x);
302 else
303 return __virt_to_phys(x);
304}
305
306#define virt_to_idmap(x) __virt_to_idmap((unsigned long)(x))
307
308/*
252 * Virtual <-> DMA view memory address translations 309 * Virtual <-> DMA view memory address translations
253 * Again, these are *only* valid on the kernel direct mapped RAM 310 * Again, these are *only* valid on the kernel direct mapped RAM
254 * memory. Use of these is *deprecated* (and that doesn't mean 311 * memory. Use of these is *deprecated* (and that doesn't mean
diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c
index 60d3b738d420..1f031ddd0667 100644
--- a/arch/arm/kernel/armksyms.c
+++ b/arch/arm/kernel/armksyms.c
@@ -155,4 +155,5 @@ EXPORT_SYMBOL(__gnu_mcount_nc);
155 155
156#ifdef CONFIG_ARM_PATCH_PHYS_VIRT 156#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
157EXPORT_SYMBOL(__pv_phys_offset); 157EXPORT_SYMBOL(__pv_phys_offset);
158EXPORT_SYMBOL(__pv_offset);
158#endif 159#endif
diff --git a/arch/arm/kernel/head.S b/arch/arm/kernel/head.S
index 2c7cc1e03473..54547947a4e9 100644
--- a/arch/arm/kernel/head.S
+++ b/arch/arm/kernel/head.S
@@ -536,6 +536,14 @@ ENTRY(fixup_smp)
536 ldmfd sp!, {r4 - r6, pc} 536 ldmfd sp!, {r4 - r6, pc}
537ENDPROC(fixup_smp) 537ENDPROC(fixup_smp)
538 538
539#ifdef __ARMEB_
540#define LOW_OFFSET 0x4
541#define HIGH_OFFSET 0x0
542#else
543#define LOW_OFFSET 0x0
544#define HIGH_OFFSET 0x4
545#endif
546
539#ifdef CONFIG_ARM_PATCH_PHYS_VIRT 547#ifdef CONFIG_ARM_PATCH_PHYS_VIRT
540 548
541/* __fixup_pv_table - patch the stub instructions with the delta between 549/* __fixup_pv_table - patch the stub instructions with the delta between
@@ -546,17 +554,20 @@ ENDPROC(fixup_smp)
546 __HEAD 554 __HEAD
547__fixup_pv_table: 555__fixup_pv_table:
548 adr r0, 1f 556 adr r0, 1f
549 ldmia r0, {r3-r5, r7} 557 ldmia r0, {r3-r7}
550 sub r3, r0, r3 @ PHYS_OFFSET - PAGE_OFFSET 558 mvn ip, #0
559 subs r3, r0, r3 @ PHYS_OFFSET - PAGE_OFFSET
551 add r4, r4, r3 @ adjust table start address 560 add r4, r4, r3 @ adjust table start address
552 add r5, r5, r3 @ adjust table end address 561 add r5, r5, r3 @ adjust table end address
553 add r7, r7, r3 @ adjust __pv_phys_offset address 562 add r6, r6, r3 @ adjust __pv_phys_offset address
554 str r8, [r7] @ save computed PHYS_OFFSET to __pv_phys_offset 563 add r7, r7, r3 @ adjust __pv_offset address
564 str r8, [r6, #LOW_OFFSET] @ save computed PHYS_OFFSET to __pv_phys_offset
565 strcc ip, [r7, #HIGH_OFFSET] @ save to __pv_offset high bits
555 mov r6, r3, lsr #24 @ constant for add/sub instructions 566 mov r6, r3, lsr #24 @ constant for add/sub instructions
556 teq r3, r6, lsl #24 @ must be 16MiB aligned 567 teq r3, r6, lsl #24 @ must be 16MiB aligned
557THUMB( it ne @ cross section branch ) 568THUMB( it ne @ cross section branch )
558 bne __error 569 bne __error
559 str r6, [r7, #4] @ save to __pv_offset 570 str r3, [r7, #LOW_OFFSET] @ save to __pv_offset low bits
560 b __fixup_a_pv_table 571 b __fixup_a_pv_table
561ENDPROC(__fixup_pv_table) 572ENDPROC(__fixup_pv_table)
562 573
@@ -565,10 +576,19 @@ ENDPROC(__fixup_pv_table)
565 .long __pv_table_begin 576 .long __pv_table_begin
566 .long __pv_table_end 577 .long __pv_table_end
5672: .long __pv_phys_offset 5782: .long __pv_phys_offset
579 .long __pv_offset
568 580
569 .text 581 .text
570__fixup_a_pv_table: 582__fixup_a_pv_table:
583 adr r0, 3f
584 ldr r6, [r0]
585 add r6, r6, r3
586 ldr r0, [r6, #HIGH_OFFSET] @ pv_offset high word
587 ldr r6, [r6, #LOW_OFFSET] @ pv_offset low word
588 mov r6, r6, lsr #24
589 cmn r0, #1
571#ifdef CONFIG_THUMB2_KERNEL 590#ifdef CONFIG_THUMB2_KERNEL
591 moveq r0, #0x200000 @ set bit 21, mov to mvn instruction
572 lsls r6, #24 592 lsls r6, #24
573 beq 2f 593 beq 2f
574 clz r7, r6 594 clz r7, r6
@@ -582,18 +602,28 @@ __fixup_a_pv_table:
582 b 2f 602 b 2f
5831: add r7, r3 6031: add r7, r3
584 ldrh ip, [r7, #2] 604 ldrh ip, [r7, #2]
585 and ip, 0x8f00 605 tst ip, #0x4000
586 orr ip, r6 @ mask in offset bits 31-24 606 and ip, #0x8f00
607 orrne ip, r6 @ mask in offset bits 31-24
608 orreq ip, r0 @ mask in offset bits 7-0
587 strh ip, [r7, #2] 609 strh ip, [r7, #2]
610 ldrheq ip, [r7]
611 biceq ip, #0x20
612 orreq ip, ip, r0, lsr #16
613 strheq ip, [r7]
5882: cmp r4, r5 6142: cmp r4, r5
589 ldrcc r7, [r4], #4 @ use branch for delay slot 615 ldrcc r7, [r4], #4 @ use branch for delay slot
590 bcc 1b 616 bcc 1b
591 bx lr 617 bx lr
592#else 618#else
619 moveq r0, #0x400000 @ set bit 22, mov to mvn instruction
593 b 2f 620 b 2f
5941: ldr ip, [r7, r3] 6211: ldr ip, [r7, r3]
595 bic ip, ip, #0x000000ff 622 bic ip, ip, #0x000000ff
596 orr ip, ip, r6 @ mask in offset bits 31-24 623 tst ip, #0xf00 @ check the rotation field
624 orrne ip, ip, r6 @ mask in offset bits 31-24
625 biceq ip, ip, #0x400000 @ clear bit 22
626 orreq ip, ip, r0 @ mask in offset bits 7-0
597 str ip, [r7, r3] 627 str ip, [r7, r3]
5982: cmp r4, r5 6282: cmp r4, r5
599 ldrcc r7, [r4], #4 @ use branch for delay slot 629 ldrcc r7, [r4], #4 @ use branch for delay slot
@@ -602,28 +632,29 @@ __fixup_a_pv_table:
602#endif 632#endif
603ENDPROC(__fixup_a_pv_table) 633ENDPROC(__fixup_a_pv_table)
604 634
6353: .long __pv_offset
636
605ENTRY(fixup_pv_table) 637ENTRY(fixup_pv_table)
606 stmfd sp!, {r4 - r7, lr} 638 stmfd sp!, {r4 - r7, lr}
607 ldr r2, 2f @ get address of __pv_phys_offset
608 mov r3, #0 @ no offset 639 mov r3, #0 @ no offset
609 mov r4, r0 @ r0 = table start 640 mov r4, r0 @ r0 = table start
610 add r5, r0, r1 @ r1 = table size 641 add r5, r0, r1 @ r1 = table size
611 ldr r6, [r2, #4] @ get __pv_offset
612 bl __fixup_a_pv_table 642 bl __fixup_a_pv_table
613 ldmfd sp!, {r4 - r7, pc} 643 ldmfd sp!, {r4 - r7, pc}
614ENDPROC(fixup_pv_table) 644ENDPROC(fixup_pv_table)
615 645
616 .align
6172: .long __pv_phys_offset
618
619 .data 646 .data
620 .globl __pv_phys_offset 647 .globl __pv_phys_offset
621 .type __pv_phys_offset, %object 648 .type __pv_phys_offset, %object
622__pv_phys_offset: 649__pv_phys_offset:
623 .long 0 650 .quad 0
624 .size __pv_phys_offset, . - __pv_phys_offset 651 .size __pv_phys_offset, . -__pv_phys_offset
652
653 .globl __pv_offset
654 .type __pv_offset, %object
625__pv_offset: 655__pv_offset:
626 .long 0 656 .quad 0
657 .size __pv_offset, . -__pv_offset
627#endif 658#endif
628 659
629#include "head-common.S" 660#include "head-common.S"
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index 0e1e2b3afa45..af7b7db4699e 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -73,6 +73,8 @@ __setup("fpe=", fpe_setup);
73#endif 73#endif
74 74
75extern void paging_init(const struct machine_desc *desc); 75extern void paging_init(const struct machine_desc *desc);
76extern void early_paging_init(const struct machine_desc *,
77 struct proc_info_list *);
76extern void sanity_check_meminfo(void); 78extern void sanity_check_meminfo(void);
77extern enum reboot_mode reboot_mode; 79extern enum reboot_mode reboot_mode;
78extern void setup_dma_zone(const struct machine_desc *desc); 80extern void setup_dma_zone(const struct machine_desc *desc);
@@ -878,6 +880,8 @@ void __init setup_arch(char **cmdline_p)
878 parse_early_param(); 880 parse_early_param();
879 881
880 sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL); 882 sort(&meminfo.bank, meminfo.nr_banks, sizeof(meminfo.bank[0]), meminfo_cmp, NULL);
883
884 early_paging_init(mdesc, lookup_processor_type(read_cpuid_id()));
881 sanity_check_meminfo(); 885 sanity_check_meminfo();
882 arm_memblock_init(&meminfo, mdesc); 886 arm_memblock_init(&meminfo, mdesc);
883 887
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c
index 7d80a549cae5..5c820cbcf918 100644
--- a/arch/arm/kernel/smp.c
+++ b/arch/arm/kernel/smp.c
@@ -81,7 +81,7 @@ void __init smp_set_ops(struct smp_operations *ops)
81 81
82static unsigned long get_arch_pgd(pgd_t *pgd) 82static unsigned long get_arch_pgd(pgd_t *pgd)
83{ 83{
84 phys_addr_t pgdir = virt_to_phys(pgd); 84 phys_addr_t pgdir = virt_to_idmap(pgd);
85 BUG_ON(pgdir & ARCH_PGD_MASK); 85 BUG_ON(pgdir & ARCH_PGD_MASK);
86 return pgdir >> ARCH_PGD_SHIFT; 86 return pgdir >> ARCH_PGD_SHIFT;
87} 87}
diff --git a/arch/arm/mm/idmap.c b/arch/arm/mm/idmap.c
index 83cb3ac27095..8e0e52eb76b5 100644
--- a/arch/arm/mm/idmap.c
+++ b/arch/arm/mm/idmap.c
@@ -10,6 +10,7 @@
10#include <asm/system_info.h> 10#include <asm/system_info.h>
11 11
12pgd_t *idmap_pgd; 12pgd_t *idmap_pgd;
13phys_addr_t (*arch_virt_to_idmap) (unsigned long x);
13 14
14#ifdef CONFIG_ARM_LPAE 15#ifdef CONFIG_ARM_LPAE
15static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end, 16static void idmap_add_pmd(pud_t *pud, unsigned long addr, unsigned long end,
@@ -67,8 +68,9 @@ static void identity_mapping_add(pgd_t *pgd, const char *text_start,
67 unsigned long addr, end; 68 unsigned long addr, end;
68 unsigned long next; 69 unsigned long next;
69 70
70 addr = virt_to_phys(text_start); 71 addr = virt_to_idmap(text_start);
71 end = virt_to_phys(text_end); 72 end = virt_to_idmap(text_end);
73 pr_info("Setting up static identity map for 0x%lx - 0x%lx\n", addr, end);
72 74
73 prot |= PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AF; 75 prot |= PMD_TYPE_SECT | PMD_SECT_AP_WRITE | PMD_SECT_AF;
74 76
@@ -90,8 +92,6 @@ static int __init init_static_idmap(void)
90 if (!idmap_pgd) 92 if (!idmap_pgd)
91 return -ENOMEM; 93 return -ENOMEM;
92 94
93 pr_info("Setting up static identity map for 0x%p - 0x%p\n",
94 __idmap_text_start, __idmap_text_end);
95 identity_mapping_add(idmap_pgd, __idmap_text_start, 95 identity_mapping_add(idmap_pgd, __idmap_text_start,
96 __idmap_text_end, 0); 96 __idmap_text_end, 0);
97 97
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index b1d17eeb59b8..78eeeca78f5a 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -28,6 +28,8 @@
28#include <asm/highmem.h> 28#include <asm/highmem.h>
29#include <asm/system_info.h> 29#include <asm/system_info.h>
30#include <asm/traps.h> 30#include <asm/traps.h>
31#include <asm/procinfo.h>
32#include <asm/memory.h>
31 33
32#include <asm/mach/arch.h> 34#include <asm/mach/arch.h>
33#include <asm/mach/map.h> 35#include <asm/mach/map.h>
@@ -1315,6 +1317,86 @@ static void __init map_lowmem(void)
1315 } 1317 }
1316} 1318}
1317 1319
1320#ifdef CONFIG_ARM_LPAE
1321/*
1322 * early_paging_init() recreates boot time page table setup, allowing machines
1323 * to switch over to a high (>4G) address space on LPAE systems
1324 */
1325void __init early_paging_init(const struct machine_desc *mdesc,
1326 struct proc_info_list *procinfo)
1327{
1328 pmdval_t pmdprot = procinfo->__cpu_mm_mmu_flags;
1329 unsigned long map_start, map_end;
1330 pgd_t *pgd0, *pgdk;
1331 pud_t *pud0, *pudk, *pud_start;
1332 pmd_t *pmd0, *pmdk;
1333 phys_addr_t phys;
1334 int i;
1335
1336 if (!(mdesc->init_meminfo))
1337 return;
1338
1339 /* remap kernel code and data */
1340 map_start = init_mm.start_code;
1341 map_end = init_mm.brk;
1342
1343 /* get a handle on things... */
1344 pgd0 = pgd_offset_k(0);
1345 pud_start = pud0 = pud_offset(pgd0, 0);
1346 pmd0 = pmd_offset(pud0, 0);
1347
1348 pgdk = pgd_offset_k(map_start);
1349 pudk = pud_offset(pgdk, map_start);
1350 pmdk = pmd_offset(pudk, map_start);
1351
1352 mdesc->init_meminfo();
1353
1354 /* Run the patch stub to update the constants */
1355 fixup_pv_table(&__pv_table_begin,
1356 (&__pv_table_end - &__pv_table_begin) << 2);
1357
1358 /*
1359 * Cache cleaning operations for self-modifying code
1360 * We should clean the entries by MVA but running a
1361 * for loop over every pv_table entry pointer would
1362 * just complicate the code.
1363 */
1364 flush_cache_louis();
1365 dsb();
1366 isb();
1367
1368 /* remap level 1 table */
1369 for (i = 0; i < PTRS_PER_PGD; pud0++, i++) {
1370 set_pud(pud0,
1371 __pud(__pa(pmd0) | PMD_TYPE_TABLE | L_PGD_SWAPPER));
1372 pmd0 += PTRS_PER_PMD;
1373 }
1374
1375 /* remap pmds for kernel mapping */
1376 phys = __pa(map_start) & PMD_MASK;
1377 do {
1378 *pmdk++ = __pmd(phys | pmdprot);
1379 phys += PMD_SIZE;
1380 } while (phys < map_end);
1381
1382 flush_cache_all();
1383 cpu_switch_mm(pgd0, &init_mm);
1384 cpu_set_ttbr(1, __pa(pgd0) + TTBR1_OFFSET);
1385 local_flush_bp_all();
1386 local_flush_tlb_all();
1387}
1388
1389#else
1390
1391void __init early_paging_init(const struct machine_desc *mdesc,
1392 struct proc_info_list *procinfo)
1393{
1394 if (mdesc->init_meminfo)
1395 mdesc->init_meminfo();
1396}
1397
1398#endif
1399
1318/* 1400/*
1319 * paging_init() sets up the page tables, initialises the zone memory 1401 * paging_init() sets up the page tables, initialises the zone memory
1320 * maps, and sets up the zero page, bad page and bad page tables. 1402 * maps, and sets up the zero page, bad page and bad page tables.