2 * This file contains the routines for initializing the MMU
3 * on the 8xx series of chips.
6 * Derived from arch/powerpc/mm/40x_mmu.c:
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
15 #include <linux/memblock.h>
19 extern int __map_without_ltlbs
;
21 * MMU_init_hw does the chip-specific initialization of the MMU hardware.
23 void __init
MMU_init_hw(void)
25 /* Nothing to do for the time being but keep it similar to other PPC */
28 #define LARGE_PAGE_SIZE_4M (1<<22)
29 #define LARGE_PAGE_SIZE_8M (1<<23)
30 #define LARGE_PAGE_SIZE_64M (1<<26)
32 unsigned long __init
mmu_mapin_ram(unsigned long top
)
34 unsigned long v
, s
, mapped
;
41 if (__map_without_ltlbs
)
44 #ifdef CONFIG_PPC_4K_PAGES
45 while (s
>= LARGE_PAGE_SIZE_8M
) {
47 unsigned long val
= p
| MD_PS8MEG
;
49 pmdp
= pmd_offset(pud_offset(pgd_offset_k(v
), v
), v
);
51 *pmdp
++ = __pmd(val
+ LARGE_PAGE_SIZE_4M
);
53 v
+= LARGE_PAGE_SIZE_8M
;
54 p
+= LARGE_PAGE_SIZE_8M
;
55 s
-= LARGE_PAGE_SIZE_8M
;
57 #else /* CONFIG_PPC_16K_PAGES */
58 while (s
>= LARGE_PAGE_SIZE_64M
) {
60 unsigned long val
= p
| MD_PS8MEG
;
62 pmdp
= pmd_offset(pud_offset(pgd_offset_k(v
), v
), v
);
65 v
+= LARGE_PAGE_SIZE_64M
;
66 p
+= LARGE_PAGE_SIZE_64M
;
67 s
-= LARGE_PAGE_SIZE_64M
;
73 /* If the size of RAM is not an exact power of two, we may not
74 * have covered RAM in its entirety with 8 MiB
75 * pages. Consequently, restrict the top end of RAM currently
76 * allocable so that calls to the MEMBLOCK to allocate PTEs for "tail"
77 * coverage with normal-sized pages (or other reasons) do not
78 * attempt to allocate outside the allowed range.
80 memblock_set_current_limit(mapped
);
85 void setup_initial_memory_limit(phys_addr_t first_memblock_base
,
86 phys_addr_t first_memblock_size
)
88 /* We don't currently support the first MEMBLOCK not mapping 0
89 * physical on those processors
91 BUG_ON(first_memblock_base
!= 0);
94 /* 8xx can only access 24MB at the moment */
95 memblock_set_current_limit(min_t(u64
, first_memblock_size
, 0x01800000));
97 /* 8xx can only access 8MB at the moment */
98 memblock_set_current_limit(min_t(u64
, first_memblock_size
, 0x00800000));
103 * Set up to use a given MMU context.
104 * id is context number, pgd is PGD pointer.
106 * We place the physical address of the new task page directory loaded
107 * into the MMU base register, and set the ASID compare register with
110 void set_context(unsigned long id
, pgd_t
*pgd
)
112 s16 offset
= (s16
)(__pa(swapper_pg_dir
));
114 #ifdef CONFIG_BDI_SWITCH
115 pgd_t
**ptr
= *(pgd_t
***)(KERNELBASE
+ 0xf0);
117 /* Context switch the PTE pointer for the Abatron BDI2000.
118 * The PGDIR is passed as second argument.
123 /* Register M_TW will contain base address of level 1 table minus the
124 * lower part of the kernel PGDIR base address, so that all accesses to
125 * level 1 table are done relative to lower part of kernel PGDIR base
128 mtspr(SPRN_M_TW
, __pa(pgd
) - offset
);
131 mtspr(SPRN_M_CASID
, id
);
136 void flush_instruction_cache(void)
139 mtspr(SPRN_IC_CST
, IDC_INVALL
);