/*
*
* Common boot and setup code.
*
* Copyright (C) 2001 PPC64 Team, IBM Corp
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version
* 2 of the License, or (at your option) any later version.
*/
#include <linux/export.h>
#include <linux/string.h>
#include <linux/sched.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/reboot.h>
#include <linux/delay.h>
#include <linux/initrd.h>
#include <linux/seq_file.h>
#include <linux/ioport.h>
#include <linux/console.h>
#include <linux/utsname.h>
#include <linux/tty.h>
#include <linux/root_dev.h>
#include <linux/notifier.h>
#include <linux/cpu.h>
#include <linux/unistd.h>
#include <linux/serial.h>
#include <linux/serial_8250.h>
#include <linux/memblock.h>
#include <linux/pci.h>
#include <linux/lockdep.h>
#include <linux/memory.h>
#include <linux/nmi.h>
#include <asm/debugfs.h>
#include <asm/io.h>
#include <asm/kdump.h>
#include <asm/prom.h>
#include <asm/processor.h>
#include <asm/pgtable.h>
#include <asm/smp.h>
#include <asm/elf.h>
#include <asm/machdep.h>
#include <asm/paca.h>
#include <asm/time.h>
#include <asm/cputable.h>
#include <asm/dt_cpu_ftrs.h>
#include <asm/sections.h>
#include <asm/btext.h>
#include <asm/nvram.h>
#include <asm/setup.h>
#include <asm/rtas.h>
#include <asm/iommu.h>
#include <asm/serial.h>
#include <asm/cache.h>
#include <asm/page.h>
#include <asm/mmu.h>
#include <asm/firmware.h>
#include <asm/xmon.h>
#include <asm/udbg.h>
#include <asm/kexec.h>
#include <asm/code-patching.h>
#include <asm/livepatch.h>
#include <asm/opal.h>
#include <asm/cputhreads.h>
#include <asm/hw_irq.h>
#include <asm/feature-fixups.h>
#include "setup.h"
#ifdef DEBUG
#define DBG(fmt...) udbg_printf(fmt)
#else
#define DBG(fmt...)
#endif
int spinning_secondaries;
u64 ppc64_pft_size;
struct ppc64_caches ppc64_caches = {
.l1d = {
.block_size = 0x40,
.log_block_size = 6,
},
.l1i = {
.block_size = 0x40,
.log_block_size = 6
},
};
EXPORT_SYMBOL_GPL(ppc64_caches);
#if defined(CONFIG_PPC_BOOK3E) && defined(CONFIG_SMP)
void __init setup_tlb_core_data(void)
{
int cpu;
BUILD_BUG_ON(offsetof(struct tlb_core_data, lock) != 0);
for_each_possible_cpu(cpu) {
int first = cpu_first_thread_sibling(cpu);
/*
* If we boot via kdump on a non-primary thread,
* make sure we point at the thread that actually
* set up this TLB.
*/
if (cpu_first_thread_sibling(boot_cpuid) == first)
first = boot_cpuid;
paca_ptrs[cpu]->tcd_ptr = &paca_ptrs[first]->tcd;
/*
* If we have threads, we need either tlbsrx.
* or e6500 tablewalk mode, or else TLB handlers
* will be racy and could produce duplicate entries.
* Should we panic instead?
*/
WARN_ONCE(smt_enabled_at_boot >= 2 &&
!mmu_has_feature(MMU_FTR_USE_TLBRSRV) &&
book3e_htw_mode != PPC_HTW_E6500,
"%s: unsupported MMU configuration\n", __func__);
}
}
#endif
#ifdef CONFIG_SMP
static char *smt_enabled_cmdline;
/* Look for ibm,smt-enabled OF option */
void __init check_smt_enabled(void)
{
struct device_node *dn;
const char *smt_option;
/* Default to enabling all threads */
smt_enabled_at_boot = threads_per_core;
/* Allow the command line to overrule the OF option */
if (smt_enabled_cmdline) {
if (!strcmp(smt_enabled_cmdline, "on"))
smt_enabled_at_boot = threads_per_core;
else if (!strcmp(smt_enabled_cmdline, "off"))
smt_enabled_at_boot = 0;
else {
int smt;
int rc;
rc = kstrtoint(smt_enabled_cmdline, 10, &smt);
if (!rc)
smt_enabled_at_boot =
min(threads_per_core, smt);
}
} else {
dn = of_find_node_by_path("/options");
if (dn) {
smt_option = of_get_property(dn, "ibm,smt-enabled",
NULL);
if (smt_option) {
if (!strcmp(smt_option, "on"))
smt_enabled_at_boot = threads_per_core;
else if (!strcmp(smt_option, "off"))
smt_enabled_at_boot = 0;
}
of_node_put(dn);
}
}
}
/* Look for smt-enabled= cmdline option */
static int __init early_smt_enabled(char *p)
{
smt_enabled_cmdline = p;
return 0;
}
early_param("smt-enabled", early_smt_enabled);
#endif /* CONFIG_SMP */
/** Fix up paca fields required for the boot cpu */
static void __init fixup_boot_paca(void)
{
/* The boot cpu is started */
get_paca()->cpu_start = 1;
/* Allow percpu accesses to work until we setup percpu data */
get_paca()->data_offset = 0;
/* Mark interrupts disabled in PACA */
irq_soft_mask_set(IRQS_DISABLED);
}
static void __init configure_exceptions(void)
{
/*
* Setup the trampolines from the lowmem exception vectors
* to the kdump kernel when not using a relocatable kernel.
*/
setup_kdump_trampoline();
/* Under a PAPR hypervisor, we need hypercalls */