| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * Common prep/pmac/chrp boot and setup code. |
|---|
| 3 | 4 | */ |
|---|
| .. | .. |
|---|
| 17 | 18 | #include <linux/console.h> |
|---|
| 18 | 19 | #include <linux/memblock.h> |
|---|
| 19 | 20 | #include <linux/export.h> |
|---|
| 21 | +#include <linux/nvram.h> |
|---|
| 22 | +#include <linux/pgtable.h> |
|---|
| 20 | 23 | |
|---|
| 21 | 24 | #include <asm/io.h> |
|---|
| 22 | 25 | #include <asm/prom.h> |
|---|
| 23 | 26 | #include <asm/processor.h> |
|---|
| 24 | | -#include <asm/pgtable.h> |
|---|
| 25 | 27 | #include <asm/setup.h> |
|---|
| 26 | 28 | #include <asm/smp.h> |
|---|
| 27 | 29 | #include <asm/elf.h> |
|---|
| .. | .. |
|---|
| 42 | 44 | #include <asm/asm-prototypes.h> |
|---|
| 43 | 45 | #include <asm/kdump.h> |
|---|
| 44 | 46 | #include <asm/feature-fixups.h> |
|---|
| 47 | +#include <asm/early_ioremap.h> |
|---|
| 45 | 48 | |
|---|
| 46 | 49 | #include "setup.h" |
|---|
| 47 | 50 | |
|---|
| .. | .. |
|---|
| 55 | 58 | int smp_hw_index[NR_CPUS]; |
|---|
| 56 | 59 | EXPORT_SYMBOL(smp_hw_index); |
|---|
| 57 | 60 | |
|---|
| 58 | | -unsigned long ISA_DMA_THRESHOLD; |
|---|
| 59 | 61 | unsigned int DMA_MODE_READ; |
|---|
| 60 | 62 | unsigned int DMA_MODE_WRITE; |
|---|
| 61 | 63 | |
|---|
| 62 | | -EXPORT_SYMBOL(ISA_DMA_THRESHOLD); |
|---|
| 63 | 64 | EXPORT_SYMBOL(DMA_MODE_READ); |
|---|
| 64 | 65 | EXPORT_SYMBOL(DMA_MODE_WRITE); |
|---|
| 65 | | - |
|---|
| 66 | | -/* |
|---|
| 67 | | - * We're called here very early in the boot. |
|---|
| 68 | | - * |
|---|
| 69 | | - * Note that the kernel may be running at an address which is different |
|---|
| 70 | | - * from the address that it was linked at, so we must use RELOC/PTRRELOC |
|---|
| 71 | | - * to access static data (including strings). -- paulus |
|---|
| 72 | | - */ |
|---|
| 73 | | -notrace unsigned long __init early_init(unsigned long dt_ptr) |
|---|
| 74 | | -{ |
|---|
| 75 | | - unsigned long offset = reloc_offset(); |
|---|
| 76 | | - |
|---|
| 77 | | - /* First zero the BSS -- use memset_io, some platforms don't have |
|---|
| 78 | | - * caches on yet */ |
|---|
| 79 | | - memset_io((void __iomem *)PTRRELOC(&__bss_start), 0, |
|---|
| 80 | | - __bss_stop - __bss_start); |
|---|
| 81 | | - |
|---|
| 82 | | - /* |
|---|
| 83 | | - * Identify the CPU type and fix up code sections |
|---|
| 84 | | - * that depend on which cpu we have. |
|---|
| 85 | | - */ |
|---|
| 86 | | - identify_cpu(offset, mfspr(SPRN_PVR)); |
|---|
| 87 | | - |
|---|
| 88 | | - apply_feature_fixups(); |
|---|
| 89 | | - |
|---|
| 90 | | - return KERNELBASE + offset; |
|---|
| 91 | | -} |
|---|
| 92 | | - |
|---|
| 93 | 66 | |
|---|
| 94 | 67 | /* |
|---|
| 95 | 68 | * This is run before start_kernel(), the kernel has been relocated |
|---|
| .. | .. |
|---|
| 101 | 74 | */ |
|---|
| 102 | 75 | notrace void __init machine_init(u64 dt_ptr) |
|---|
| 103 | 76 | { |
|---|
| 104 | | - unsigned int *addr = (unsigned int *)((unsigned long)&patch__memset_nocache + |
|---|
| 105 | | - patch__memset_nocache); |
|---|
| 106 | | - unsigned long insn; |
|---|
| 77 | + struct ppc_inst *addr = (struct ppc_inst *)patch_site_addr(&patch__memset_nocache); |
|---|
| 78 | + struct ppc_inst insn; |
|---|
| 107 | 79 | |
|---|
| 108 | 80 | /* Configure static keys first, now that we're relocated. */ |
|---|
| 109 | 81 | setup_feature_keys(); |
|---|
| 110 | 82 | |
|---|
| 83 | + early_ioremap_init(); |
|---|
| 84 | + |
|---|
| 111 | 85 | /* Enable early debugging if any specified (see udbg.h) */ |
|---|
| 112 | 86 | udbg_early_init(); |
|---|
| 113 | 87 | |
|---|
| 114 | | - patch_instruction_site(&patch__memcpy_nocache, PPC_INST_NOP); |
|---|
| 88 | + patch_instruction_site(&patch__memcpy_nocache, ppc_inst(PPC_INST_NOP)); |
|---|
| 115 | 89 | |
|---|
| 116 | | - insn = create_cond_branch(addr, branch_target(addr), 0x820000); |
|---|
| 90 | + create_cond_branch(&insn, addr, branch_target(addr), 0x820000); |
|---|
| 117 | 91 | patch_instruction(addr, insn); /* replace b by bne cr0 */ |
|---|
| 118 | 92 | |
|---|
| 119 | 93 | /* Do some early initialization based on the flat device tree */ |
|---|
| .. | .. |
|---|
| 149 | 123 | } |
|---|
| 150 | 124 | __setup("l3cr=", ppc_setup_l3cr); |
|---|
| 151 | 125 | |
|---|
| 152 | | -#ifdef CONFIG_GENERIC_NVRAM |
|---|
| 153 | | - |
|---|
| 154 | | -/* Generic nvram hooks used by drivers/char/gen_nvram.c */ |
|---|
| 155 | | -unsigned char nvram_read_byte(int addr) |
|---|
| 156 | | -{ |
|---|
| 157 | | - if (ppc_md.nvram_read_val) |
|---|
| 158 | | - return ppc_md.nvram_read_val(addr); |
|---|
| 159 | | - return 0xff; |
|---|
| 160 | | -} |
|---|
| 161 | | -EXPORT_SYMBOL(nvram_read_byte); |
|---|
| 162 | | - |
|---|
| 163 | | -void nvram_write_byte(unsigned char val, int addr) |
|---|
| 164 | | -{ |
|---|
| 165 | | - if (ppc_md.nvram_write_val) |
|---|
| 166 | | - ppc_md.nvram_write_val(addr, val); |
|---|
| 167 | | -} |
|---|
| 168 | | -EXPORT_SYMBOL(nvram_write_byte); |
|---|
| 169 | | - |
|---|
| 170 | | -ssize_t nvram_get_size(void) |
|---|
| 171 | | -{ |
|---|
| 172 | | - if (ppc_md.nvram_size) |
|---|
| 173 | | - return ppc_md.nvram_size(); |
|---|
| 174 | | - return -1; |
|---|
| 175 | | -} |
|---|
| 176 | | -EXPORT_SYMBOL(nvram_get_size); |
|---|
| 177 | | - |
|---|
| 178 | | -void nvram_sync(void) |
|---|
| 179 | | -{ |
|---|
| 180 | | - if (ppc_md.nvram_sync) |
|---|
| 181 | | - ppc_md.nvram_sync(); |
|---|
| 182 | | -} |
|---|
| 183 | | -EXPORT_SYMBOL(nvram_sync); |
|---|
| 184 | | - |
|---|
| 185 | | -#endif /* CONFIG_NVRAM */ |
|---|
| 186 | | - |
|---|
| 187 | 126 | static int __init ppc_init(void) |
|---|
| 188 | 127 | { |
|---|
| 189 | 128 | /* clear the progress line */ |
|---|
| .. | .. |
|---|
| 198 | 137 | } |
|---|
| 199 | 138 | arch_initcall(ppc_init); |
|---|
| 200 | 139 | |
|---|
| 140 | +static void *__init alloc_stack(void) |
|---|
| 141 | +{ |
|---|
| 142 | + void *ptr = memblock_alloc(THREAD_SIZE, THREAD_ALIGN); |
|---|
| 143 | + |
|---|
| 144 | + if (!ptr) |
|---|
| 145 | + panic("cannot allocate %d bytes for stack at %pS\n", |
|---|
| 146 | + THREAD_SIZE, (void *)_RET_IP_); |
|---|
| 147 | + |
|---|
| 148 | + return ptr; |
|---|
| 149 | +} |
|---|
| 150 | + |
|---|
| 201 | 151 | void __init irqstack_early_init(void) |
|---|
| 202 | 152 | { |
|---|
| 203 | 153 | unsigned int i; |
|---|
| 204 | 154 | |
|---|
| 155 | + if (IS_ENABLED(CONFIG_VMAP_STACK)) |
|---|
| 156 | + return; |
|---|
| 157 | + |
|---|
| 205 | 158 | /* interrupt stacks must be in lowmem, we get that for free on ppc32 |
|---|
| 206 | 159 | * as the memblock is limited to lowmem by default */ |
|---|
| 207 | 160 | for_each_possible_cpu(i) { |
|---|
| 208 | | - softirq_ctx[i] = (struct thread_info *) |
|---|
| 209 | | - __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); |
|---|
| 210 | | - hardirq_ctx[i] = (struct thread_info *) |
|---|
| 211 | | - __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); |
|---|
| 161 | + softirq_ctx[i] = alloc_stack(); |
|---|
| 162 | + hardirq_ctx[i] = alloc_stack(); |
|---|
| 212 | 163 | } |
|---|
| 213 | 164 | } |
|---|
| 165 | + |
|---|
| 166 | +#ifdef CONFIG_VMAP_STACK |
|---|
| 167 | +void *emergency_ctx[NR_CPUS] __ro_after_init = {[0] = &init_stack}; |
|---|
| 168 | + |
|---|
| 169 | +void __init emergency_stack_init(void) |
|---|
| 170 | +{ |
|---|
| 171 | + unsigned int i; |
|---|
| 172 | + |
|---|
| 173 | + for_each_possible_cpu(i) |
|---|
| 174 | + emergency_ctx[i] = alloc_stack(); |
|---|
| 175 | +} |
|---|
| 176 | +#endif |
|---|
| 214 | 177 | |
|---|
| 215 | 178 | #if defined(CONFIG_BOOKE) || defined(CONFIG_40x) |
|---|
| 216 | 179 | void __init exc_lvl_early_init(void) |
|---|
| .. | .. |
|---|
| 226 | 189 | hw_cpu = 0; |
|---|
| 227 | 190 | #endif |
|---|
| 228 | 191 | |
|---|
| 229 | | - critirq_ctx[hw_cpu] = (struct thread_info *) |
|---|
| 230 | | - __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); |
|---|
| 192 | + critirq_ctx[hw_cpu] = alloc_stack(); |
|---|
| 231 | 193 | #ifdef CONFIG_BOOKE |
|---|
| 232 | | - dbgirq_ctx[hw_cpu] = (struct thread_info *) |
|---|
| 233 | | - __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); |
|---|
| 234 | | - mcheckirq_ctx[hw_cpu] = (struct thread_info *) |
|---|
| 235 | | - __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE)); |
|---|
| 194 | + dbgirq_ctx[hw_cpu] = alloc_stack(); |
|---|
| 195 | + mcheckirq_ctx[hw_cpu] = alloc_stack(); |
|---|
| 236 | 196 | #endif |
|---|
| 237 | 197 | } |
|---|
| 238 | 198 | } |
|---|
| .. | .. |
|---|
| 240 | 200 | |
|---|
| 241 | 201 | void __init setup_power_save(void) |
|---|
| 242 | 202 | { |
|---|
| 243 | | -#ifdef CONFIG_6xx |
|---|
| 203 | +#ifdef CONFIG_PPC_BOOK3S_32 |
|---|
| 244 | 204 | if (cpu_has_feature(CPU_FTR_CAN_DOZE) || |
|---|
| 245 | 205 | cpu_has_feature(CPU_FTR_CAN_NAP)) |
|---|
| 246 | 206 | ppc_md.power_save = ppc6xx_idle; |
|---|
| .. | .. |
|---|
| 263 | 223 | dcache_bsize = cur_cpu_spec->dcache_bsize; |
|---|
| 264 | 224 | icache_bsize = cur_cpu_spec->icache_bsize; |
|---|
| 265 | 225 | ucache_bsize = 0; |
|---|
| 266 | | - if (cpu_has_feature(CPU_FTR_UNIFIED_ID_CACHE)) |
|---|
| 226 | + if (IS_ENABLED(CONFIG_E200)) |
|---|
| 267 | 227 | ucache_bsize = icache_bsize = dcache_bsize; |
|---|
| 268 | 228 | } |
|---|