Commit 7d0daae4 authored by Michael Ellerman's avatar Michael Ellerman Committed by Paul Mackerras

[POWERPC] powerpc: Initialise ppc_md htab pointers earlier

Initialise the ppc_md htab callbacks earlier, in the probe routines. This
allows us to call htab_finish_init() from htab_initialize(), and makes it
private to hash_utils_64.c. Move htab_finish_init() and make_bl() above
htab_initialize() to avoid forward declarations.
Signed-off-by: default avatarMichael Ellerman <michael@ellerman.id.au>
Signed-off-by: default avatarPaul Mackerras <paulus@samba.org>
parent 7a4571ae
...@@ -358,11 +358,7 @@ void __init setup_system(void) ...@@ -358,11 +358,7 @@ void __init setup_system(void)
* Fill the ppc64_caches & systemcfg structures with informations * Fill the ppc64_caches & systemcfg structures with informations
* retrieved from the device-tree. Need to be called before * retrieved from the device-tree. Need to be called before
* finish_device_tree() since the later requires some of the * finish_device_tree() since the later requires some of the
* informations filled up here to properly parse the interrupt * informations filled up here to properly parse the interrupt tree.
* tree.
* It also sets up the cache line sizes which allows to call
* routines like flush_icache_range (used by the hash init
* later on).
*/ */
initialize_cache_info(); initialize_cache_info();
......
...@@ -520,7 +520,7 @@ static inline int tlb_batching_enabled(void) ...@@ -520,7 +520,7 @@ static inline int tlb_batching_enabled(void)
} }
#endif #endif
void hpte_init_native(void) void __init hpte_init_native(void)
{ {
ppc_md.hpte_invalidate = native_hpte_invalidate; ppc_md.hpte_invalidate = native_hpte_invalidate;
ppc_md.hpte_updatepp = native_hpte_updatepp; ppc_md.hpte_updatepp = native_hpte_updatepp;
...@@ -530,5 +530,4 @@ void hpte_init_native(void) ...@@ -530,5 +530,4 @@ void hpte_init_native(void)
ppc_md.hpte_clear_all = native_hpte_clear; ppc_md.hpte_clear_all = native_hpte_clear;
if (tlb_batching_enabled()) if (tlb_batching_enabled())
ppc_md.flush_hash_range = native_flush_hash_range; ppc_md.flush_hash_range = native_flush_hash_range;
htab_finish_init();
} }
...@@ -413,6 +413,41 @@ void create_section_mapping(unsigned long start, unsigned long end) ...@@ -413,6 +413,41 @@ void create_section_mapping(unsigned long start, unsigned long end)
} }
#endif /* CONFIG_MEMORY_HOTPLUG */ #endif /* CONFIG_MEMORY_HOTPLUG */
static inline void make_bl(unsigned int *insn_addr, void *func)
{
unsigned long funcp = *((unsigned long *)func);
int offset = funcp - (unsigned long)insn_addr;
*insn_addr = (unsigned int)(0x48000001 | (offset & 0x03fffffc));
flush_icache_range((unsigned long)insn_addr, 4+
(unsigned long)insn_addr);
}
static void __init htab_finish_init(void)
{
extern unsigned int *htab_call_hpte_insert1;
extern unsigned int *htab_call_hpte_insert2;
extern unsigned int *htab_call_hpte_remove;
extern unsigned int *htab_call_hpte_updatepp;
#ifdef CONFIG_PPC_64K_PAGES
extern unsigned int *ht64_call_hpte_insert1;
extern unsigned int *ht64_call_hpte_insert2;
extern unsigned int *ht64_call_hpte_remove;
extern unsigned int *ht64_call_hpte_updatepp;
make_bl(ht64_call_hpte_insert1, ppc_md.hpte_insert);
make_bl(ht64_call_hpte_insert2, ppc_md.hpte_insert);
make_bl(ht64_call_hpte_remove, ppc_md.hpte_remove);
make_bl(ht64_call_hpte_updatepp, ppc_md.hpte_updatepp);
#endif /* CONFIG_PPC_64K_PAGES */
make_bl(htab_call_hpte_insert1, ppc_md.hpte_insert);
make_bl(htab_call_hpte_insert2, ppc_md.hpte_insert);
make_bl(htab_call_hpte_remove, ppc_md.hpte_remove);
make_bl(htab_call_hpte_updatepp, ppc_md.hpte_updatepp);
}
void __init htab_initialize(void) void __init htab_initialize(void)
{ {
unsigned long table; unsigned long table;
...@@ -525,6 +560,8 @@ void __init htab_initialize(void) ...@@ -525,6 +560,8 @@ void __init htab_initialize(void)
mmu_linear_psize)); mmu_linear_psize));
} }
htab_finish_init();
DBG(" <- htab_initialize()\n"); DBG(" <- htab_initialize()\n");
} }
#undef KB #undef KB
...@@ -787,16 +824,6 @@ void flush_hash_range(unsigned long number, int local) ...@@ -787,16 +824,6 @@ void flush_hash_range(unsigned long number, int local)
} }
} }
static inline void make_bl(unsigned int *insn_addr, void *func)
{
unsigned long funcp = *((unsigned long *)func);
int offset = funcp - (unsigned long)insn_addr;
*insn_addr = (unsigned int)(0x48000001 | (offset & 0x03fffffc));
flush_icache_range((unsigned long)insn_addr, 4+
(unsigned long)insn_addr);
}
/* /*
* low_hash_fault is called when we the low level hash code failed * low_hash_fault is called when we the low level hash code failed
* to instert a PTE due to an hypervisor error * to instert a PTE due to an hypervisor error
...@@ -815,28 +842,3 @@ void low_hash_fault(struct pt_regs *regs, unsigned long address) ...@@ -815,28 +842,3 @@ void low_hash_fault(struct pt_regs *regs, unsigned long address)
} }
bad_page_fault(regs, address, SIGBUS); bad_page_fault(regs, address, SIGBUS);
} }
void __init htab_finish_init(void)
{
extern unsigned int *htab_call_hpte_insert1;
extern unsigned int *htab_call_hpte_insert2;
extern unsigned int *htab_call_hpte_remove;
extern unsigned int *htab_call_hpte_updatepp;
#ifdef CONFIG_PPC_64K_PAGES
extern unsigned int *ht64_call_hpte_insert1;
extern unsigned int *ht64_call_hpte_insert2;
extern unsigned int *ht64_call_hpte_remove;
extern unsigned int *ht64_call_hpte_updatepp;
make_bl(ht64_call_hpte_insert1, ppc_md.hpte_insert);
make_bl(ht64_call_hpte_insert2, ppc_md.hpte_insert);
make_bl(ht64_call_hpte_remove, ppc_md.hpte_remove);
make_bl(ht64_call_hpte_updatepp, ppc_md.hpte_updatepp);
#endif /* CONFIG_PPC_64K_PAGES */
make_bl(htab_call_hpte_insert1, ppc_md.hpte_insert);
make_bl(htab_call_hpte_insert2, ppc_md.hpte_insert);
make_bl(htab_call_hpte_remove, ppc_md.hpte_remove);
make_bl(htab_call_hpte_updatepp, ppc_md.hpte_updatepp);
}
...@@ -125,8 +125,6 @@ static void __init cell_init_early(void) ...@@ -125,8 +125,6 @@ static void __init cell_init_early(void)
{ {
DBG(" -> cell_init_early()\n"); DBG(" -> cell_init_early()\n");
hpte_init_native();
cell_init_iommu(); cell_init_iommu();
ppc64_interrupt_controller = IC_CELL_PIC; ppc64_interrupt_controller = IC_CELL_PIC;
...@@ -139,11 +137,13 @@ static int __init cell_probe(void) ...@@ -139,11 +137,13 @@ static int __init cell_probe(void)
{ {
unsigned long root = of_get_flat_dt_root(); unsigned long root = of_get_flat_dt_root();
if (of_flat_dt_is_compatible(root, "IBM,CBEA") || if (!of_flat_dt_is_compatible(root, "IBM,CBEA") &&
of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) !of_flat_dt_is_compatible(root, "IBM,CPBW-1.0"))
return 1;
return 0; return 0;
hpte_init_native();
return 1;
} }
/* /*
......
...@@ -242,13 +242,11 @@ static void iSeries_hpte_invalidate(unsigned long slot, unsigned long va, ...@@ -242,13 +242,11 @@ static void iSeries_hpte_invalidate(unsigned long slot, unsigned long va,
local_irq_restore(flags); local_irq_restore(flags);
} }
void hpte_init_iSeries(void) void __init hpte_init_iSeries(void)
{ {
ppc_md.hpte_invalidate = iSeries_hpte_invalidate; ppc_md.hpte_invalidate = iSeries_hpte_invalidate;
ppc_md.hpte_updatepp = iSeries_hpte_updatepp; ppc_md.hpte_updatepp = iSeries_hpte_updatepp;
ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp; ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp;
ppc_md.hpte_insert = iSeries_hpte_insert; ppc_md.hpte_insert = iSeries_hpte_insert;
ppc_md.hpte_remove = iSeries_hpte_remove; ppc_md.hpte_remove = iSeries_hpte_remove;
htab_finish_init();
} }
...@@ -318,11 +318,6 @@ static void __init iSeries_init_early(void) ...@@ -318,11 +318,6 @@ static void __init iSeries_init_early(void)
iSeries_recal_tb = get_tb(); iSeries_recal_tb = get_tb();
iSeries_recal_titan = HvCallXm_loadTod(); iSeries_recal_titan = HvCallXm_loadTod();
/*
* Initialize the hash table management pointers
*/
hpte_init_iSeries();
/* /*
* Initialize the DMA/TCE management * Initialize the DMA/TCE management
*/ */
...@@ -671,6 +666,8 @@ static int __init iseries_probe(void) ...@@ -671,6 +666,8 @@ static int __init iseries_probe(void)
*/ */
virt_irq_max = 255; virt_irq_max = 255;
hpte_init_iSeries();
return 1; return 1;
} }
......
...@@ -199,11 +199,6 @@ static void __init maple_init_early(void) ...@@ -199,11 +199,6 @@ static void __init maple_init_early(void)
{ {
DBG(" -> maple_init_early\n"); DBG(" -> maple_init_early\n");
/* Initialize hash table, from now on, we can take hash faults
* and call ioremap
*/
hpte_init_native();
/* Setup interrupt mapping options */ /* Setup interrupt mapping options */
ppc64_interrupt_controller = IC_OPEN_PIC; ppc64_interrupt_controller = IC_OPEN_PIC;
...@@ -272,6 +267,8 @@ static int __init maple_probe(void) ...@@ -272,6 +267,8 @@ static int __init maple_probe(void)
*/ */
alloc_dart_table(); alloc_dart_table();
hpte_init_native();
return 1; return 1;
} }
......
...@@ -600,13 +600,6 @@ pmac_halt(void) ...@@ -600,13 +600,6 @@ pmac_halt(void)
*/ */
static void __init pmac_init_early(void) static void __init pmac_init_early(void)
{ {
#ifdef CONFIG_PPC64
/* Initialize hash table, from now on, we can take hash faults
* and call ioremap
*/
hpte_init_native();
#endif
/* Enable early btext debug if requested */ /* Enable early btext debug if requested */
if (strstr(cmd_line, "btextdbg")) { if (strstr(cmd_line, "btextdbg")) {
udbg_adb_init_early(); udbg_adb_init_early();
...@@ -683,6 +676,8 @@ static int __init pmac_probe(void) ...@@ -683,6 +676,8 @@ static int __init pmac_probe(void)
* part of the cacheable linar mapping * part of the cacheable linar mapping
*/ */
alloc_dart_table(); alloc_dart_table();
hpte_init_native();
#endif #endif
#ifdef CONFIG_PPC32 #ifdef CONFIG_PPC32
......
...@@ -513,7 +513,7 @@ void pSeries_lpar_flush_hash_range(unsigned long number, int local) ...@@ -513,7 +513,7 @@ void pSeries_lpar_flush_hash_range(unsigned long number, int local)
spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags); spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags);
} }
void hpte_init_lpar(void) void __init hpte_init_lpar(void)
{ {
ppc_md.hpte_invalidate = pSeries_lpar_hpte_invalidate; ppc_md.hpte_invalidate = pSeries_lpar_hpte_invalidate;
ppc_md.hpte_updatepp = pSeries_lpar_hpte_updatepp; ppc_md.hpte_updatepp = pSeries_lpar_hpte_updatepp;
...@@ -522,6 +522,4 @@ void hpte_init_lpar(void) ...@@ -522,6 +522,4 @@ void hpte_init_lpar(void)
ppc_md.hpte_remove = pSeries_lpar_hpte_remove; ppc_md.hpte_remove = pSeries_lpar_hpte_remove;
ppc_md.flush_hash_range = pSeries_lpar_flush_hash_range; ppc_md.flush_hash_range = pSeries_lpar_flush_hash_range;
ppc_md.hpte_clear_all = pSeries_lpar_hptab_clear; ppc_md.hpte_clear_all = pSeries_lpar_hptab_clear;
htab_finish_init();
} }
...@@ -323,11 +323,6 @@ static void __init pSeries_init_early(void) ...@@ -323,11 +323,6 @@ static void __init pSeries_init_early(void)
fw_feature_init(); fw_feature_init();
if (firmware_has_feature(FW_FEATURE_LPAR))
hpte_init_lpar();
else
hpte_init_native();
if (firmware_has_feature(FW_FEATURE_LPAR)) if (firmware_has_feature(FW_FEATURE_LPAR))
find_udbg_vterm(); find_udbg_vterm();
...@@ -384,6 +379,11 @@ static int __init pSeries_probe_hypertas(unsigned long node, ...@@ -384,6 +379,11 @@ static int __init pSeries_probe_hypertas(unsigned long node,
if (of_get_flat_dt_prop(node, "ibm,hypertas-functions", NULL) != NULL) if (of_get_flat_dt_prop(node, "ibm,hypertas-functions", NULL) != NULL)
powerpc_firmware_features |= FW_FEATURE_LPAR; powerpc_firmware_features |= FW_FEATURE_LPAR;
if (firmware_has_feature(FW_FEATURE_LPAR))
hpte_init_lpar();
else
hpte_init_native();
return 1; return 1;
} }
......
...@@ -238,7 +238,6 @@ extern int hash_huge_page(struct mm_struct *mm, unsigned long access, ...@@ -238,7 +238,6 @@ extern int hash_huge_page(struct mm_struct *mm, unsigned long access,
unsigned long ea, unsigned long vsid, int local, unsigned long ea, unsigned long vsid, int local,
unsigned long trap); unsigned long trap);
extern void htab_finish_init(void);
extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend, extern int htab_bolt_mapping(unsigned long vstart, unsigned long vend,
unsigned long pstart, unsigned long mode, unsigned long pstart, unsigned long mode,
int psize); int psize);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment