|
@@ -581,42 +581,10 @@ static void setup_mmu_htw(void)
|
|
/*
|
|
/*
|
|
* Early initialization of the MMU TLB code
|
|
* Early initialization of the MMU TLB code
|
|
*/
|
|
*/
|
|
-static void __early_init_mmu(int boot_cpu)
|
|
|
|
|
|
+static void early_init_this_mmu(void)
|
|
{
|
|
{
|
|
unsigned int mas4;
|
|
unsigned int mas4;
|
|
|
|
|
|
- /* XXX This will have to be decided at runtime, but right
|
|
|
|
- * now our boot and TLB miss code hard wires it. Ideally
|
|
|
|
- * we should find out a suitable page size and patch the
|
|
|
|
- * TLB miss code (either that or use the PACA to store
|
|
|
|
- * the value we want)
|
|
|
|
- */
|
|
|
|
- mmu_linear_psize = MMU_PAGE_1G;
|
|
|
|
-
|
|
|
|
- /* XXX This should be decided at runtime based on supported
|
|
|
|
- * page sizes in the TLB, but for now let's assume 16M is
|
|
|
|
- * always there and a good fit (which it probably is)
|
|
|
|
- *
|
|
|
|
- * Freescale booke only supports 4K pages in TLB0, so use that.
|
|
|
|
- */
|
|
|
|
- if (mmu_has_feature(MMU_FTR_TYPE_FSL_E))
|
|
|
|
- mmu_vmemmap_psize = MMU_PAGE_4K;
|
|
|
|
- else
|
|
|
|
- mmu_vmemmap_psize = MMU_PAGE_16M;
|
|
|
|
-
|
|
|
|
- /* XXX This code only checks for TLB 0 capabilities and doesn't
|
|
|
|
- * check what page size combos are supported by the HW. It
|
|
|
|
- * also doesn't handle the case where a separate array holds
|
|
|
|
- * the IND entries from the array loaded by the PT.
|
|
|
|
- */
|
|
|
|
- if (boot_cpu) {
|
|
|
|
- /* Look for supported page sizes */
|
|
|
|
- setup_page_sizes();
|
|
|
|
-
|
|
|
|
- /* Look for HW tablewalk support */
|
|
|
|
- setup_mmu_htw();
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
/* Set MAS4 based on page table setting */
|
|
/* Set MAS4 based on page table setting */
|
|
|
|
|
|
mas4 = 0x4 << MAS4_WIMGED_SHIFT;
|
|
mas4 = 0x4 << MAS4_WIMGED_SHIFT;
|
|
@@ -650,11 +618,6 @@ static void __early_init_mmu(int boot_cpu)
|
|
}
|
|
}
|
|
mtspr(SPRN_MAS4, mas4);
|
|
mtspr(SPRN_MAS4, mas4);
|
|
|
|
|
|
- /* Set the global containing the top of the linear mapping
|
|
|
|
- * for use by the TLB miss code
|
|
|
|
- */
|
|
|
|
- linear_map_top = memblock_end_of_DRAM();
|
|
|
|
-
|
|
|
|
#ifdef CONFIG_PPC_FSL_BOOK3E
|
|
#ifdef CONFIG_PPC_FSL_BOOK3E
|
|
if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
|
|
if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
|
|
unsigned int num_cams;
|
|
unsigned int num_cams;
|
|
@@ -662,10 +625,49 @@ static void __early_init_mmu(int boot_cpu)
|
|
/* use a quarter of the TLBCAM for bolted linear map */
|
|
/* use a quarter of the TLBCAM for bolted linear map */
|
|
num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4;
|
|
num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4;
|
|
linear_map_top = map_mem_in_cams(linear_map_top, num_cams);
|
|
linear_map_top = map_mem_in_cams(linear_map_top, num_cams);
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
|
|
- /* limit memory so we dont have linear faults */
|
|
|
|
- memblock_enforce_memory_limit(linear_map_top);
|
|
|
|
|
|
+ /* A sync won't hurt us after mucking around with
|
|
|
|
+ * the MMU configuration
|
|
|
|
+ */
|
|
|
|
+ mb();
|
|
|
|
+}
|
|
|
|
|
|
|
|
+static void __init early_init_mmu_global(void)
|
|
|
|
+{
|
|
|
|
+ /* XXX This will have to be decided at runtime, but right
|
|
|
|
+ * now our boot and TLB miss code hard wires it. Ideally
|
|
|
|
+ * we should find out a suitable page size and patch the
|
|
|
|
+ * TLB miss code (either that or use the PACA to store
|
|
|
|
+ * the value we want)
|
|
|
|
+ */
|
|
|
|
+ mmu_linear_psize = MMU_PAGE_1G;
|
|
|
|
+
|
|
|
|
+ /* XXX This should be decided at runtime based on supported
|
|
|
|
+ * page sizes in the TLB, but for now let's assume 16M is
|
|
|
|
+ * always there and a good fit (which it probably is)
|
|
|
|
+ *
|
|
|
|
+ * Freescale booke only supports 4K pages in TLB0, so use that.
|
|
|
|
+ */
|
|
|
|
+ if (mmu_has_feature(MMU_FTR_TYPE_FSL_E))
|
|
|
|
+ mmu_vmemmap_psize = MMU_PAGE_4K;
|
|
|
|
+ else
|
|
|
|
+ mmu_vmemmap_psize = MMU_PAGE_16M;
|
|
|
|
+
|
|
|
|
+ /* XXX This code only checks for TLB 0 capabilities and doesn't
|
|
|
|
+ * check what page size combos are supported by the HW. It
|
|
|
|
+ * also doesn't handle the case where a separate array holds
|
|
|
|
+ * the IND entries from the array loaded by the PT.
|
|
|
|
+ */
|
|
|
|
+ /* Look for supported page sizes */
|
|
|
|
+ setup_page_sizes();
|
|
|
|
+
|
|
|
|
+ /* Look for HW tablewalk support */
|
|
|
|
+ setup_mmu_htw();
|
|
|
|
+
|
|
|
|
+#ifdef CONFIG_PPC_FSL_BOOK3E
|
|
|
|
+ if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
|
|
if (book3e_htw_mode == PPC_HTW_NONE) {
|
|
if (book3e_htw_mode == PPC_HTW_NONE) {
|
|
extlb_level_exc = EX_TLB_SIZE;
|
|
extlb_level_exc = EX_TLB_SIZE;
|
|
patch_exception(0x1c0, exc_data_tlb_miss_bolted_book3e);
|
|
patch_exception(0x1c0, exc_data_tlb_miss_bolted_book3e);
|
|
@@ -675,22 +677,41 @@ static void __early_init_mmu(int boot_cpu)
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|
|
|
|
|
|
- /* A sync won't hurt us after mucking around with
|
|
|
|
- * the MMU configuration
|
|
|
|
|
|
+ /* Set the global containing the top of the linear mapping
|
|
|
|
+ * for use by the TLB miss code
|
|
*/
|
|
*/
|
|
- mb();
|
|
|
|
|
|
+ linear_map_top = memblock_end_of_DRAM();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void __init early_mmu_set_memory_limit(void)
|
|
|
|
+{
|
|
|
|
+#ifdef CONFIG_PPC_FSL_BOOK3E
|
|
|
|
+ if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
|
|
|
|
+ /*
|
|
|
|
+ * Limit memory so we dont have linear faults.
|
|
|
|
+ * Unlike memblock_set_current_limit, which limits
|
|
|
|
+ * memory available during early boot, this permanently
|
|
|
|
+ * reduces the memory available to Linux. We need to
|
|
|
|
+ * do this because highmem is not supported on 64-bit.
|
|
|
|
+ */
|
|
|
|
+ memblock_enforce_memory_limit(linear_map_top);
|
|
|
|
+ }
|
|
|
|
+#endif
|
|
|
|
|
|
memblock_set_current_limit(linear_map_top);
|
|
memblock_set_current_limit(linear_map_top);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+/* boot cpu only */
|
|
void __init early_init_mmu(void)
|
|
void __init early_init_mmu(void)
|
|
{
|
|
{
|
|
- __early_init_mmu(1);
|
|
|
|
|
|
+ early_init_mmu_global();
|
|
|
|
+ early_init_this_mmu();
|
|
|
|
+ early_mmu_set_memory_limit();
|
|
}
|
|
}
|
|
|
|
|
|
void early_init_mmu_secondary(void)
|
|
void early_init_mmu_secondary(void)
|
|
{
|
|
{
|
|
- __early_init_mmu(0);
|
|
|
|
|
|
+ early_init_this_mmu();
|
|
}
|
|
}
|
|
|
|
|
|
void setup_initial_memory_limit(phys_addr_t first_memblock_base,
|
|
void setup_initial_memory_limit(phys_addr_t first_memblock_base,
|