Merge branch 'linus' into cpus4096
[linux-2.6] / arch / powerpc / kernel / head_44x.S
1 /*
2  * Kernel execution entry point code.
3  *
4  *    Copyright (c) 1995-1996 Gary Thomas <gdt@linuxppc.org>
5  *      Initial PowerPC version.
6  *    Copyright (c) 1996 Cort Dougan <cort@cs.nmt.edu>
7  *      Rewritten for PReP
8  *    Copyright (c) 1996 Paul Mackerras <paulus@cs.anu.edu.au>
9  *      Low-level exception handers, MMU support, and rewrite.
10  *    Copyright (c) 1997 Dan Malek <dmalek@jlc.net>
11  *      PowerPC 8xx modifications.
12  *    Copyright (c) 1998-1999 TiVo, Inc.
13  *      PowerPC 403GCX modifications.
14  *    Copyright (c) 1999 Grant Erickson <grant@lcse.umn.edu>
15  *      PowerPC 403GCX/405GP modifications.
16  *    Copyright 2000 MontaVista Software Inc.
17  *      PPC405 modifications
18  *      PowerPC 403GCX/405GP modifications.
19  *      Author: MontaVista Software, Inc.
20  *              frank_rowand@mvista.com or source@mvista.com
21  *              debbie_chu@mvista.com
22  *    Copyright 2002-2005 MontaVista Software, Inc.
23  *      PowerPC 44x support, Matt Porter <mporter@kernel.crashing.org>
24  *
25  * This program is free software; you can redistribute  it and/or modify it
26  * under  the terms of  the GNU General  Public License as published by the
27  * Free Software Foundation;  either version 2 of the  License, or (at your
28  * option) any later version.
29  */
30
31 #include <asm/processor.h>
32 #include <asm/page.h>
33 #include <asm/mmu.h>
34 #include <asm/pgtable.h>
35 #include <asm/cputable.h>
36 #include <asm/thread_info.h>
37 #include <asm/ppc_asm.h>
38 #include <asm/asm-offsets.h>
39 #include "head_booke.h"
40
41
42 /* As with the other PowerPC ports, it is expected that when code
43  * execution begins here, the following registers contain valid, yet
44  * optional, information:
45  *
46  *   r3 - Board info structure pointer (DRAM, frequency, MAC address, etc.)
47  *   r4 - Starting address of the init RAM disk
48  *   r5 - Ending address of the init RAM disk
49  *   r6 - Start of kernel command line string (e.g. "mem=128")
50  *   r7 - End of kernel command line string
51  *
52  */
53         .section        .text.head, "ax"
54 _ENTRY(_stext);
55 _ENTRY(_start);
56         /*
57          * Reserve a word at a fixed location to store the address
58          * of abatron_pteptrs
59          */
60         nop
61 /*
62  * Save parameters we are passed
63  */
64         mr      r31,r3
65         mr      r30,r4
66         mr      r29,r5
67         mr      r28,r6
68         mr      r27,r7
69         li      r24,0           /* CPU number */
70
71 /*
72  * Set up the initial MMU state
73  *
74  * We are still executing code at the virtual address
75  * mappings set by the firmware for the base of RAM.
76  *
77  * We first invalidate all TLB entries but the one
78  * we are running from.  We then load the KERNELBASE
79  * mappings so we can begin to use kernel addresses
80  * natively and so the interrupt vector locations are
81  * permanently pinned (necessary since Book E
82  * implementations always have translation enabled).
83  *
84  * TODO: Use the known TLB entry we are running from to
85  *       determine which physical region we are located
86  *       in.  This can be used to determine where in RAM
87  *       (on a shared CPU system) or PCI memory space
88  *       (on a DRAMless system) we are located.
89  *       For now, we assume a perfect world which means
90  *       we are located at the base of DRAM (physical 0).
91  */
92
93 /*
94  * Search TLB for entry that we are currently using.
95  * Invalidate all entries but the one we are using.
96  */
97         /* Load our current PID->MMUCR TID and MSR IS->MMUCR STS */
98         mfspr   r3,SPRN_PID                     /* Get PID */
99         mfmsr   r4                              /* Get MSR */
100         andi.   r4,r4,MSR_IS@l                  /* TS=1? */
101         beq     wmmucr                          /* If not, leave STS=0 */
102         oris    r3,r3,PPC44x_MMUCR_STS@h        /* Set STS=1 */
103 wmmucr: mtspr   SPRN_MMUCR,r3                   /* Put MMUCR */
104         sync
105
106         bl      invstr                          /* Find our address */
107 invstr: mflr    r5                              /* Make it accessible */
108         tlbsx   r23,0,r5                        /* Find entry we are in */
109         li      r4,0                            /* Start at TLB entry 0 */
110         li      r3,0                            /* Set PAGEID inval value */
111 1:      cmpw    r23,r4                          /* Is this our entry? */
112         beq     skpinv                          /* If so, skip the inval */
113         tlbwe   r3,r4,PPC44x_TLB_PAGEID         /* If not, inval the entry */
114 skpinv: addi    r4,r4,1                         /* Increment */
115         cmpwi   r4,64                           /* Are we done? */
116         bne     1b                              /* If not, repeat */
117         isync                                   /* If so, context change */
118
119 /*
120  * Configure and load pinned entry into TLB slot 63.
121  */
122
123         lis     r3,PAGE_OFFSET@h
124         ori     r3,r3,PAGE_OFFSET@l
125
126         /* Kernel is at the base of RAM */
127         li r4, 0                        /* Load the kernel physical address */
128
129         /* Load the kernel PID = 0 */
130         li      r0,0
131         mtspr   SPRN_PID,r0
132         sync
133
134         /* Initialize MMUCR */
135         li      r5,0
136         mtspr   SPRN_MMUCR,r5
137         sync
138
139         /* pageid fields */
140         clrrwi  r3,r3,10                /* Mask off the effective page number */
141         ori     r3,r3,PPC44x_TLB_VALID | PPC44x_TLB_256M
142
143         /* xlat fields */
144         clrrwi  r4,r4,10                /* Mask off the real page number */
145                                         /* ERPN is 0 for first 4GB page */
146
147         /* attrib fields */
148         /* Added guarded bit to protect against speculative loads/stores */
149         li      r5,0
150         ori     r5,r5,(PPC44x_TLB_SW | PPC44x_TLB_SR | PPC44x_TLB_SX | PPC44x_TLB_G)
151
152         li      r0,63                    /* TLB slot 63 */
153
154         tlbwe   r3,r0,PPC44x_TLB_PAGEID /* Load the pageid fields */
155         tlbwe   r4,r0,PPC44x_TLB_XLAT   /* Load the translation fields */
156         tlbwe   r5,r0,PPC44x_TLB_ATTRIB /* Load the attrib/access fields */
157
158         /* Force context change */
159         mfmsr   r0
160         mtspr   SPRN_SRR1, r0
161         lis     r0,3f@h
162         ori     r0,r0,3f@l
163         mtspr   SPRN_SRR0,r0
164         sync
165         rfi
166
167         /* If necessary, invalidate original entry we used */
168 3:      cmpwi   r23,63
169         beq     4f
170         li      r6,0
171         tlbwe   r6,r23,PPC44x_TLB_PAGEID
172         isync
173
174 4:
175 #ifdef CONFIG_PPC_EARLY_DEBUG_44x
176         /* Add UART mapping for early debug. */
177
178         /* pageid fields */
179         lis     r3,PPC44x_EARLY_DEBUG_VIRTADDR@h
180         ori     r3,r3,PPC44x_TLB_VALID|PPC44x_TLB_TS|PPC44x_TLB_64K
181
182         /* xlat fields */
183         lis     r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSLOW@h
184         ori     r4,r4,CONFIG_PPC_EARLY_DEBUG_44x_PHYSHIGH
185
186         /* attrib fields */
187         li      r5,(PPC44x_TLB_SW|PPC44x_TLB_SR|PPC44x_TLB_I|PPC44x_TLB_G)
188         li      r0,62                    /* TLB slot 0 */
189
190         tlbwe   r3,r0,PPC44x_TLB_PAGEID
191         tlbwe   r4,r0,PPC44x_TLB_XLAT
192         tlbwe   r5,r0,PPC44x_TLB_ATTRIB
193
194         /* Force context change */
195         isync
196 #endif /* CONFIG_PPC_EARLY_DEBUG_44x */
197
198         /* Establish the interrupt vector offsets */
199         SET_IVOR(0,  CriticalInput);
200         SET_IVOR(1,  MachineCheck);
201         SET_IVOR(2,  DataStorage);
202         SET_IVOR(3,  InstructionStorage);
203         SET_IVOR(4,  ExternalInput);
204         SET_IVOR(5,  Alignment);
205         SET_IVOR(6,  Program);
206         SET_IVOR(7,  FloatingPointUnavailable);
207         SET_IVOR(8,  SystemCall);
208         SET_IVOR(9,  AuxillaryProcessorUnavailable);
209         SET_IVOR(10, Decrementer);
210         SET_IVOR(11, FixedIntervalTimer);
211         SET_IVOR(12, WatchdogTimer);
212         SET_IVOR(13, DataTLBError);
213         SET_IVOR(14, InstructionTLBError);
214         SET_IVOR(15, DebugCrit);
215
216         /* Establish the interrupt vector base */
217         lis     r4,interrupt_base@h     /* IVPR only uses the high 16-bits */
218         mtspr   SPRN_IVPR,r4
219
220         /*
221          * This is where the main kernel code starts.
222          */
223
224         /* ptr to current */
225         lis     r2,init_task@h
226         ori     r2,r2,init_task@l
227
228         /* ptr to current thread */
229         addi    r4,r2,THREAD    /* init task's THREAD */
230         mtspr   SPRN_SPRG3,r4
231
232         /* stack */
233         lis     r1,init_thread_union@h
234         ori     r1,r1,init_thread_union@l
235         li      r0,0
236         stwu    r0,THREAD_SIZE-STACK_FRAME_OVERHEAD(r1)
237
238         bl      early_init
239
240 /*
241  * Decide what sort of machine this is and initialize the MMU.
242  */
243         mr      r3,r31
244         mr      r4,r30
245         mr      r5,r29
246         mr      r6,r28
247         mr      r7,r27
248         bl      machine_init
249         bl      MMU_init
250
251         /* Setup PTE pointers for the Abatron bdiGDB */
252         lis     r6, swapper_pg_dir@h
253         ori     r6, r6, swapper_pg_dir@l
254         lis     r5, abatron_pteptrs@h
255         ori     r5, r5, abatron_pteptrs@l
256         lis     r4, KERNELBASE@h
257         ori     r4, r4, KERNELBASE@l
258         stw     r5, 0(r4)       /* Save abatron_pteptrs at a fixed location */
259         stw     r6, 0(r5)
260
261         /* Let's move on */
262         lis     r4,start_kernel@h
263         ori     r4,r4,start_kernel@l
264         lis     r3,MSR_KERNEL@h
265         ori     r3,r3,MSR_KERNEL@l
266         mtspr   SPRN_SRR0,r4
267         mtspr   SPRN_SRR1,r3
268         rfi                     /* change context and jump to start_kernel */
269
270 /*
271  * Interrupt vector entry code
272  *
273  * The Book E MMUs are always on so we don't need to handle
274  * interrupts in real mode as with previous PPC processors. In
275  * this case we handle interrupts in the kernel virtual address
276  * space.
277  *
278  * Interrupt vectors are dynamically placed relative to the
279  * interrupt prefix as determined by the address of interrupt_base.
280  * The interrupt vectors offsets are programmed using the labels
281  * for each interrupt vector entry.
282  *
283  * Interrupt vectors must be aligned on a 16 byte boundary.
284  * We align on a 32 byte cache line boundary for good measure.
285  */
286
287 interrupt_base:
288         /* Critical Input Interrupt */
289         CRITICAL_EXCEPTION(0x0100, CriticalInput, unknown_exception)
290
291         /* Machine Check Interrupt */
292         CRITICAL_EXCEPTION(0x0200, MachineCheck, machine_check_exception)
293         MCHECK_EXCEPTION(0x0210, MachineCheckA, machine_check_exception)
294
295         /* Data Storage Interrupt */
296         DATA_STORAGE_EXCEPTION
297
298                 /* Instruction Storage Interrupt */
299         INSTRUCTION_STORAGE_EXCEPTION
300
301         /* External Input Interrupt */
302         EXCEPTION(0x0500, ExternalInput, do_IRQ, EXC_XFER_LITE)
303
304         /* Alignment Interrupt */
305         ALIGNMENT_EXCEPTION
306
307         /* Program Interrupt */
308         PROGRAM_EXCEPTION
309
310         /* Floating Point Unavailable Interrupt */
311 #ifdef CONFIG_PPC_FPU
312         FP_UNAVAILABLE_EXCEPTION
313 #else
314         EXCEPTION(0x2010, FloatingPointUnavailable, unknown_exception, EXC_XFER_EE)
315 #endif
316         /* System Call Interrupt */
317         START_EXCEPTION(SystemCall)
318         NORMAL_EXCEPTION_PROLOG
319         EXC_XFER_EE_LITE(0x0c00, DoSyscall)
320
321         /* Auxillary Processor Unavailable Interrupt */
322         EXCEPTION(0x2020, AuxillaryProcessorUnavailable, unknown_exception, EXC_XFER_EE)
323
324         /* Decrementer Interrupt */
325         DECREMENTER_EXCEPTION
326
327         /* Fixed Internal Timer Interrupt */
328         /* TODO: Add FIT support */
329         EXCEPTION(0x1010, FixedIntervalTimer, unknown_exception, EXC_XFER_EE)
330
331         /* Watchdog Timer Interrupt */
332         /* TODO: Add watchdog support */
333 #ifdef CONFIG_BOOKE_WDT
334         CRITICAL_EXCEPTION(0x1020, WatchdogTimer, WatchdogException)
335 #else
336         CRITICAL_EXCEPTION(0x1020, WatchdogTimer, unknown_exception)
337 #endif
338
339         /* Data TLB Error Interrupt */
340         START_EXCEPTION(DataTLBError)
341         mtspr   SPRN_SPRG0, r10         /* Save some working registers */
342         mtspr   SPRN_SPRG1, r11
343         mtspr   SPRN_SPRG4W, r12
344         mtspr   SPRN_SPRG5W, r13
345         mfcr    r11
346         mtspr   SPRN_SPRG7W, r11
347         mfspr   r10, SPRN_DEAR          /* Get faulting address */
348
349         /* If we are faulting a kernel address, we have to use the
350          * kernel page tables.
351          */
352         lis     r11, PAGE_OFFSET@h
353         cmplw   r10, r11
354         blt+    3f
355         lis     r11, swapper_pg_dir@h
356         ori     r11, r11, swapper_pg_dir@l
357
358         mfspr   r12,SPRN_MMUCR
359         rlwinm  r12,r12,0,0,23          /* Clear TID */
360
361         b       4f
362
363         /* Get the PGD for the current thread */
364 3:
365         mfspr   r11,SPRN_SPRG3
366         lwz     r11,PGDIR(r11)
367
368         /* Load PID into MMUCR TID */
369         mfspr   r12,SPRN_MMUCR
370         mfspr   r13,SPRN_PID            /* Get PID */
371         rlwimi  r12,r13,0,24,31         /* Set TID */
372
373 4:
374         mtspr   SPRN_MMUCR,r12
375
376         /* Mask of required permission bits. Note that while we
377          * do copy ESR:ST to _PAGE_RW position as trying to write
378          * to an RO page is pretty common, we don't do it with
379          * _PAGE_DIRTY. We could do it, but it's a fairly rare
380          * event so I'd rather take the overhead when it happens
381          * rather than adding an instruction here. We should measure
382          * whether the whole thing is worth it in the first place
383          * as we could avoid loading SPRN_ESR completely in the first
384          * place...
385          *
386          * TODO: Is it worth doing that mfspr & rlwimi in the first
387          *       place or can we save a couple of instructions here ?
388          */
389         mfspr   r12,SPRN_ESR
390         li      r13,_PAGE_PRESENT|_PAGE_ACCESSED
391         rlwimi  r13,r12,10,30,30
392
393         /* Load the PTE */
394         rlwinm  r12, r10, 13, 19, 29    /* Compute pgdir/pmd offset */
395         lwzx    r11, r12, r11           /* Get pgd/pmd entry */
396         rlwinm. r12, r11, 0, 0, 20      /* Extract pt base address */
397         beq     2f                      /* Bail if no table */
398
399         rlwimi  r12, r10, 23, 20, 28    /* Compute pte address */
400         lwz     r11, 0(r12)             /* Get high word of pte entry */
401         lwz     r12, 4(r12)             /* Get low word of pte entry */
402
403         lis     r10,tlb_44x_index@ha
404
405         andc.   r13,r13,r12             /* Check permission */
406
407         /* Load the next available TLB index */
408         lwz     r13,tlb_44x_index@l(r10)
409
410         bne     2f                      /* Bail if permission mismach */
411
412         /* Increment, rollover, and store TLB index */
413         addi    r13,r13,1
414
415         /* Compare with watermark (instruction gets patched) */
416         .globl tlb_44x_patch_hwater_D
417 tlb_44x_patch_hwater_D:
418         cmpwi   0,r13,1                 /* reserve entries */
419         ble     5f
420         li      r13,0
421 5:
422         /* Store the next available TLB index */
423         stw     r13,tlb_44x_index@l(r10)
424
425         /* Re-load the faulting address */
426         mfspr   r10,SPRN_DEAR
427
428          /* Jump to common tlb load */
429         b       finish_tlb_load
430
431 2:
432         /* The bailout.  Restore registers to pre-exception conditions
433          * and call the heavyweights to help us out.
434          */
435         mfspr   r11, SPRN_SPRG7R
436         mtcr    r11
437         mfspr   r13, SPRN_SPRG5R
438         mfspr   r12, SPRN_SPRG4R
439         mfspr   r11, SPRN_SPRG1
440         mfspr   r10, SPRN_SPRG0
441         b       DataStorage
442
443         /* Instruction TLB Error Interrupt */
444         /*
445          * Nearly the same as above, except we get our
446          * information from different registers and bailout
447          * to a different point.
448          */
449         START_EXCEPTION(InstructionTLBError)
450         mtspr   SPRN_SPRG0, r10         /* Save some working registers */
451         mtspr   SPRN_SPRG1, r11
452         mtspr   SPRN_SPRG4W, r12
453         mtspr   SPRN_SPRG5W, r13
454         mfcr    r11
455         mtspr   SPRN_SPRG7W, r11
456         mfspr   r10, SPRN_SRR0          /* Get faulting address */
457
458         /* If we are faulting a kernel address, we have to use the
459          * kernel page tables.
460          */
461         lis     r11, PAGE_OFFSET@h
462         cmplw   r10, r11
463         blt+    3f
464         lis     r11, swapper_pg_dir@h
465         ori     r11, r11, swapper_pg_dir@l
466
467         mfspr   r12,SPRN_MMUCR
468         rlwinm  r12,r12,0,0,23          /* Clear TID */
469
470         b       4f
471
472         /* Get the PGD for the current thread */
473 3:
474         mfspr   r11,SPRN_SPRG3
475         lwz     r11,PGDIR(r11)
476
477         /* Load PID into MMUCR TID */
478         mfspr   r12,SPRN_MMUCR
479         mfspr   r13,SPRN_PID            /* Get PID */
480         rlwimi  r12,r13,0,24,31         /* Set TID */
481
482 4:
483         mtspr   SPRN_MMUCR,r12
484
485         /* Make up the required permissions */
486         li      r13,_PAGE_PRESENT | _PAGE_ACCESSED | _PAGE_HWEXEC
487
488         rlwinm  r12, r10, 13, 19, 29    /* Compute pgdir/pmd offset */
489         lwzx    r11, r12, r11           /* Get pgd/pmd entry */
490         rlwinm. r12, r11, 0, 0, 20      /* Extract pt base address */
491         beq     2f                      /* Bail if no table */
492
493         rlwimi  r12, r10, 23, 20, 28    /* Compute pte address */
494         lwz     r11, 0(r12)             /* Get high word of pte entry */
495         lwz     r12, 4(r12)             /* Get low word of pte entry */
496
497         lis     r10,tlb_44x_index@ha
498
499         andc.   r13,r13,r12             /* Check permission */
500
501         /* Load the next available TLB index */
502         lwz     r13,tlb_44x_index@l(r10)
503
504         bne     2f                      /* Bail if permission mismach */
505
506         /* Increment, rollover, and store TLB index */
507         addi    r13,r13,1
508
509         /* Compare with watermark (instruction gets patched) */
510         .globl tlb_44x_patch_hwater_I
511 tlb_44x_patch_hwater_I:
512         cmpwi   0,r13,1                 /* reserve entries */
513         ble     5f
514         li      r13,0
515 5:
516         /* Store the next available TLB index */
517         stw     r13,tlb_44x_index@l(r10)
518
519         /* Re-load the faulting address */
520         mfspr   r10,SPRN_SRR0
521
522         /* Jump to common TLB load point */
523         b       finish_tlb_load
524
525 2:
526         /* The bailout.  Restore registers to pre-exception conditions
527          * and call the heavyweights to help us out.
528          */
529         mfspr   r11, SPRN_SPRG7R
530         mtcr    r11
531         mfspr   r13, SPRN_SPRG5R
532         mfspr   r12, SPRN_SPRG4R
533         mfspr   r11, SPRN_SPRG1
534         mfspr   r10, SPRN_SPRG0
535         b       InstructionStorage
536
537         /* Debug Interrupt */
538         DEBUG_CRIT_EXCEPTION
539
540 /*
541  * Local functions
542   */
543
544 /*
545
546  * Both the instruction and data TLB miss get to this
547  * point to load the TLB.
548  *      r10 - EA of fault
549  *      r11 - PTE high word value
550  *      r12 - PTE low word value
551  *      r13 - TLB index
552  *      MMUCR - loaded with proper value when we get here
553  *      Upon exit, we reload everything and RFI.
554  */
555 finish_tlb_load:
556         /* Combine RPN & ERPN an write WS 0 */
557         rlwimi  r11,r12,0,0,19
558         tlbwe   r11,r13,PPC44x_TLB_XLAT
559
560         /*
561          * Create WS1. This is the faulting address (EPN),
562          * page size, and valid flag.
563          */
564         li      r11,PPC44x_TLB_VALID | PPC44x_TLB_4K
565         rlwimi  r10,r11,0,20,31                 /* Insert valid and page size*/
566         tlbwe   r10,r13,PPC44x_TLB_PAGEID       /* Write PAGEID */
567
568         /* And WS 2 */
569         li      r10,0xf85                       /* Mask to apply from PTE */
570         rlwimi  r10,r12,29,30,30                /* DIRTY -> SW position */
571         and     r11,r12,r10                     /* Mask PTE bits to keep */
572         andi.   r10,r12,_PAGE_USER              /* User page ? */
573         beq     1f                              /* nope, leave U bits empty */
574         rlwimi  r11,r11,3,26,28                 /* yes, copy S bits to U */
575 1:      tlbwe   r11,r13,PPC44x_TLB_ATTRIB       /* Write ATTRIB */
576
577         /* Done...restore registers and get out of here.
578         */
579         mfspr   r11, SPRN_SPRG7R
580         mtcr    r11
581         mfspr   r13, SPRN_SPRG5R
582         mfspr   r12, SPRN_SPRG4R
583         mfspr   r11, SPRN_SPRG1
584         mfspr   r10, SPRN_SPRG0
585         rfi                                     /* Force context change */
586
587 /*
588  * Global functions
589  */
590
591 /*
592  * Adjust the machine check IVOR on 440A cores
593  */
594 _GLOBAL(__fixup_440A_mcheck)
595         li      r3,MachineCheckA@l
596         mtspr   SPRN_IVOR1,r3
597         sync
598         blr
599
600 /*
601  * extern void giveup_altivec(struct task_struct *prev)
602  *
603  * The 44x core does not have an AltiVec unit.
604  */
605 _GLOBAL(giveup_altivec)
606         blr
607
608 /*
609  * extern void giveup_fpu(struct task_struct *prev)
610  *
611  * The 44x core does not have an FPU.
612  */
613 #ifndef CONFIG_PPC_FPU
614 _GLOBAL(giveup_fpu)
615         blr
616 #endif
617
618 _GLOBAL(set_context)
619
620 #ifdef CONFIG_BDI_SWITCH
621         /* Context switch the PTE pointer for the Abatron BDI2000.
622          * The PGDIR is the second parameter.
623          */
624         lis     r5, abatron_pteptrs@h
625         ori     r5, r5, abatron_pteptrs@l
626         stw     r4, 0x4(r5)
627 #endif
628         mtspr   SPRN_PID,r3
629         isync                   /* Force context change */
630         blr
631
632 /*
633  * We put a few things here that have to be page-aligned. This stuff
634  * goes at the beginning of the data segment, which is page-aligned.
635  */
636         .data
637         .align  12
638         .globl  sdata
639 sdata:
640         .globl  empty_zero_page
641 empty_zero_page:
642         .space  4096
643
644 /*
645  * To support >32-bit physical addresses, we use an 8KB pgdir.
646  */
647         .globl  swapper_pg_dir
648 swapper_pg_dir:
649         .space  PGD_TABLE_SIZE
650
651 /*
652  * Room for two PTE pointers, usually the kernel and current user pointers
653  * to their respective root page table.
654  */
655 abatron_pteptrs:
656         .space  8