Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: (43 commits) [POWERPC] Use little-endian bit from firmware ibm,pa-features property [POWERPC] Make sure smp_processor_id works very early in boot [POWERPC] U4 DART improvements [POWERPC] todc: add support for Time-Of-Day-Clock [POWERPC] Make lparcfg.c work when both iseries and pseries are selected [POWERPC] Fix idr locking in init_new_context [POWERPC] mpc7448hpc2 (taiga) board config file [POWERPC] Add tsi108 pci and platform device data register function [POWERPC] Add general support for mpc7448hpc2 (Taiga) platform [POWERPC] Correct the MAX_CONTEXT definition powerpc: minor cleanups for mpc86xx [POWERPC] Make sure we select CONFIG_NEW_LEDS if ADB_PMU_LED is set [POWERPC] Simplify the code defining the 64-bit CPU features [POWERPC] powerpc: kconfig warning fix [POWERPC] Consolidate some of kernel/misc*.S [POWERPC] Remove unused function call_with_mmu_off [POWERPC] update asm-powerpc/time.h [POWERPC] Clean up it_lp_queue.h [POWERPC] Skip the "copy down" of the kernel if it is already at zero. [POWERPC] Add the use of the firmware soft-reset-nmi to kdump. ...
This commit is contained in:
@@ -50,7 +50,8 @@ extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o
|
||||
extra-$(CONFIG_8xx) := head_8xx.o
|
||||
extra-y += vmlinux.lds
|
||||
|
||||
obj-y += time.o prom.o traps.o setup-common.o udbg.o
|
||||
obj-y += time.o prom.o traps.o setup-common.o \
|
||||
udbg.o misc.o
|
||||
obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o
|
||||
obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o
|
||||
obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o
|
||||
|
@@ -125,7 +125,12 @@ _GLOBAL(__save_cpu_setup)
|
||||
cmpwi r0,0x44
|
||||
bne 2f
|
||||
|
||||
1: /* Save HID0,1,4 and 5 */
|
||||
1: /* skip if not running in HV mode */
|
||||
mfmsr r0
|
||||
rldicl. r0,r0,4,63
|
||||
beq 2f
|
||||
|
||||
/* Save HID0,1,4 and 5 */
|
||||
mfspr r3,SPRN_HID0
|
||||
std r3,CS_HID0(r5)
|
||||
mfspr r3,SPRN_HID1
|
||||
@@ -159,7 +164,12 @@ _GLOBAL(__restore_cpu_setup)
|
||||
cmpwi r0,0x44
|
||||
bnelr
|
||||
|
||||
1: /* Before accessing memory, we make sure rm_ci is clear */
|
||||
1: /* skip if not running in HV mode */
|
||||
mfmsr r0
|
||||
rldicl. r0,r0,4,63
|
||||
beqlr
|
||||
|
||||
/* Before accessing memory, we make sure rm_ci is clear */
|
||||
li r0,0
|
||||
mfspr r3,SPRN_HID4
|
||||
rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */
|
||||
|
@@ -722,18 +722,6 @@ struct cpu_spec cpu_specs[] = {
|
||||
.oprofile_type = PPC_OPROFILE_G4,
|
||||
.platform = "ppc7450",
|
||||
},
|
||||
{ /* 8641 */
|
||||
.pvr_mask = 0xffffffff,
|
||||
.pvr_value = 0x80040010,
|
||||
.cpu_name = "8641",
|
||||
.cpu_features = CPU_FTRS_7447A,
|
||||
.cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP,
|
||||
.icache_bsize = 32,
|
||||
.dcache_bsize = 32,
|
||||
.num_pmcs = 6,
|
||||
.cpu_setup = __setup_cpu_745x
|
||||
},
|
||||
|
||||
{ /* 82xx (8240, 8245, 8260 are all 603e cores) */
|
||||
.pvr_mask = 0x7fff0000,
|
||||
.pvr_value = 0x00810000,
|
||||
|
@@ -24,9 +24,11 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/irq.h>
|
||||
|
||||
#include <asm/processor.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/kexec.h>
|
||||
#include <asm/kdump.h>
|
||||
#include <asm/lmb.h>
|
||||
#include <asm/firmware.h>
|
||||
@@ -41,6 +43,7 @@
|
||||
|
||||
/* This keeps a track of which one is crashing cpu. */
|
||||
int crashing_cpu = -1;
|
||||
static cpumask_t cpus_in_crash = CPU_MASK_NONE;
|
||||
|
||||
static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data,
|
||||
size_t data_len)
|
||||
@@ -98,34 +101,66 @@ static void crash_save_this_cpu(struct pt_regs *regs, int cpu)
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
static atomic_t waiting_for_crash_ipi;
|
||||
static atomic_t enter_on_soft_reset = ATOMIC_INIT(0);
|
||||
|
||||
void crash_ipi_callback(struct pt_regs *regs)
|
||||
{
|
||||
int cpu = smp_processor_id();
|
||||
|
||||
if (cpu == crashing_cpu)
|
||||
return;
|
||||
|
||||
if (!cpu_online(cpu))
|
||||
return;
|
||||
|
||||
local_irq_disable();
|
||||
if (!cpu_isset(cpu, cpus_in_crash))
|
||||
crash_save_this_cpu(regs, cpu);
|
||||
cpu_set(cpu, cpus_in_crash);
|
||||
|
||||
/*
|
||||
* Entered via soft-reset - could be the kdump
|
||||
* process is invoked using soft-reset or user activated
|
||||
* it if some CPU did not respond to an IPI.
|
||||
* For soft-reset, the secondary CPU can enter this func
|
||||
* twice. 1 - using IPI, and 2. soft-reset.
|
||||
* Tell the kexec CPU that entered via soft-reset and ready
|
||||
* to go down.
|
||||
*/
|
||||
if (cpu_isset(cpu, cpus_in_sr)) {
|
||||
cpu_clear(cpu, cpus_in_sr);
|
||||
atomic_inc(&enter_on_soft_reset);
|
||||
}
|
||||
|
||||
/*
|
||||
* Starting the kdump boot.
|
||||
* This barrier is needed to make sure that all CPUs are stopped.
|
||||
* If not, soft-reset will be invoked to bring other CPUs.
|
||||
*/
|
||||
while (!cpu_isset(crashing_cpu, cpus_in_crash))
|
||||
cpu_relax();
|
||||
|
||||
if (ppc_md.kexec_cpu_down)
|
||||
ppc_md.kexec_cpu_down(1, 1);
|
||||
|
||||
local_irq_disable();
|
||||
|
||||
crash_save_this_cpu(regs, cpu);
|
||||
atomic_dec(&waiting_for_crash_ipi);
|
||||
kexec_smp_wait();
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
static void crash_kexec_prepare_cpus(void)
|
||||
/*
|
||||
* Wait until all CPUs are entered via soft-reset.
|
||||
*/
|
||||
static void crash_soft_reset_check(int cpu)
|
||||
{
|
||||
unsigned int ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */
|
||||
|
||||
cpu_clear(cpu, cpus_in_sr);
|
||||
while (atomic_read(&enter_on_soft_reset) != ncpus)
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
|
||||
static void crash_kexec_prepare_cpus(int cpu)
|
||||
{
|
||||
unsigned int msecs;
|
||||
|
||||
atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1);
|
||||
unsigned int ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */
|
||||
|
||||
crash_send_ipi(crash_ipi_callback);
|
||||
smp_wmb();
|
||||
@@ -133,14 +168,13 @@ static void crash_kexec_prepare_cpus(void)
|
||||
/*
|
||||
* FIXME: Until we will have the way to stop other CPUSs reliabally,
|
||||
* the crash CPU will send an IPI and wait for other CPUs to
|
||||
* respond. If not, proceed the kexec boot even though we failed to
|
||||
* capture other CPU states.
|
||||
* respond.
|
||||
* Delay of at least 10 seconds.
|
||||
*/
|
||||
printk(KERN_ALERT "Sending IPI to other cpus...\n");
|
||||
printk(KERN_EMERG "Sending IPI to other cpus...\n");
|
||||
msecs = 10000;
|
||||
while ((atomic_read(&waiting_for_crash_ipi) > 0) && (--msecs > 0)) {
|
||||
barrier();
|
||||
while ((cpus_weight(cpus_in_crash) < ncpus) && (--msecs > 0)) {
|
||||
cpu_relax();
|
||||
mdelay(1);
|
||||
}
|
||||
|
||||
@@ -149,18 +183,71 @@ static void crash_kexec_prepare_cpus(void)
|
||||
/*
|
||||
* FIXME: In case if we do not get all CPUs, one possibility: ask the
|
||||
* user to do soft reset such that we get all.
|
||||
* IPI handler is already set by the panic cpu initially. Therefore,
|
||||
* all cpus could invoke this handler from die() and the panic CPU
|
||||
* will call machine_kexec() directly from this handler to do
|
||||
* kexec boot.
|
||||
* Soft-reset will be used until better mechanism is implemented.
|
||||
*/
|
||||
if (atomic_read(&waiting_for_crash_ipi))
|
||||
printk(KERN_ALERT "done waiting: %d cpus not responding\n",
|
||||
atomic_read(&waiting_for_crash_ipi));
|
||||
if (cpus_weight(cpus_in_crash) < ncpus) {
|
||||
printk(KERN_EMERG "done waiting: %d cpu(s) not responding\n",
|
||||
ncpus - cpus_weight(cpus_in_crash));
|
||||
printk(KERN_EMERG "Activate soft-reset to stop other cpu(s)\n");
|
||||
cpus_in_sr = CPU_MASK_NONE;
|
||||
atomic_set(&enter_on_soft_reset, 0);
|
||||
while (cpus_weight(cpus_in_crash) < ncpus)
|
||||
cpu_relax();
|
||||
}
|
||||
/*
|
||||
* Make sure all CPUs are entered via soft-reset if the kdump is
|
||||
* invoked using soft-reset.
|
||||
*/
|
||||
if (cpu_isset(cpu, cpus_in_sr))
|
||||
crash_soft_reset_check(cpu);
|
||||
/* Leave the IPI callback set */
|
||||
}
|
||||
|
||||
/*
|
||||
* This function will be called by secondary cpus or by kexec cpu
|
||||
* if soft-reset is activated to stop some CPUs.
|
||||
*/
|
||||
void crash_kexec_secondary(struct pt_regs *regs)
|
||||
{
|
||||
int cpu = smp_processor_id();
|
||||
unsigned long flags;
|
||||
int msecs = 5;
|
||||
|
||||
local_irq_save(flags);
|
||||
/* Wait 5ms if the kexec CPU is not entered yet. */
|
||||
while (crashing_cpu < 0) {
|
||||
if (--msecs < 0) {
|
||||
/*
|
||||
* Either kdump image is not loaded or
|
||||
* kdump process is not started - Probably xmon
|
||||
* exited using 'x'(exit and recover) or
|
||||
* kexec_should_crash() failed for all running tasks.
|
||||
*/
|
||||
cpu_clear(cpu, cpus_in_sr);
|
||||
local_irq_restore(flags);
|
||||
return;
|
||||
}
|
||||
mdelay(1);
|
||||
cpu_relax();
|
||||
}
|
||||
if (cpu == crashing_cpu) {
|
||||
/*
|
||||
* Panic CPU will enter this func only via soft-reset.
|
||||
* Wait until all secondary CPUs entered and
|
||||
* then start kexec boot.
|
||||
*/
|
||||
crash_soft_reset_check(cpu);
|
||||
cpu_set(crashing_cpu, cpus_in_crash);
|
||||
if (ppc_md.kexec_cpu_down)
|
||||
ppc_md.kexec_cpu_down(1, 0);
|
||||
machine_kexec(kexec_crash_image);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
crash_ipi_callback(regs);
|
||||
}
|
||||
|
||||
#else
|
||||
static void crash_kexec_prepare_cpus(void)
|
||||
static void crash_kexec_prepare_cpus(int cpu)
|
||||
{
|
||||
/*
|
||||
* move the secondarys to us so that we can copy
|
||||
@@ -171,6 +258,10 @@ static void crash_kexec_prepare_cpus(void)
|
||||
smp_release_cpus();
|
||||
}
|
||||
|
||||
void crash_kexec_secondary(struct pt_regs *regs)
|
||||
{
|
||||
cpus_in_sr = CPU_MASK_NONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
void default_machine_crash_shutdown(struct pt_regs *regs)
|
||||
@@ -199,14 +290,14 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
|
||||
desc->chip->disable(irq);
|
||||
}
|
||||
|
||||
if (ppc_md.kexec_cpu_down)
|
||||
ppc_md.kexec_cpu_down(1, 0);
|
||||
|
||||
/*
|
||||
* Make a note of crashing cpu. Will be used in machine_kexec
|
||||
* such that another IPI will not be sent.
|
||||
*/
|
||||
crashing_cpu = smp_processor_id();
|
||||
crash_kexec_prepare_cpus();
|
||||
crash_save_this_cpu(regs, crashing_cpu);
|
||||
crash_kexec_prepare_cpus(crashing_cpu);
|
||||
cpu_set(crashing_cpu, cpus_in_crash);
|
||||
if (ppc_md.kexec_cpu_down)
|
||||
ppc_md.kexec_cpu_down(1, 0);
|
||||
}
|
||||
|
@@ -85,34 +85,6 @@ END_FTR_SECTION(0, 1)
|
||||
/* Catch branch to 0 in real mode */
|
||||
trap
|
||||
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
/*
|
||||
* At offset 0x20, there is a pointer to iSeries LPAR data.
|
||||
* This is required by the hypervisor
|
||||
*/
|
||||
. = 0x20
|
||||
.llong hvReleaseData-KERNELBASE
|
||||
|
||||
/*
|
||||
* At offset 0x28 and 0x30 are offsets to the mschunks_map
|
||||
* array (used by the iSeries LPAR debugger to do translation
|
||||
* between physical addresses and absolute addresses) and
|
||||
* to the pidhash table (also used by the debugger)
|
||||
*/
|
||||
.llong mschunks_map-KERNELBASE
|
||||
.llong 0 /* pidhash-KERNELBASE SFRXXX */
|
||||
|
||||
/* Offset 0x38 - Pointer to start of embedded System.map */
|
||||
.globl embedded_sysmap_start
|
||||
embedded_sysmap_start:
|
||||
.llong 0
|
||||
/* Offset 0x40 - Pointer to end of embedded System.map */
|
||||
.globl embedded_sysmap_end
|
||||
embedded_sysmap_end:
|
||||
.llong 0
|
||||
|
||||
#endif /* CONFIG_PPC_ISERIES */
|
||||
|
||||
/* Secondary processors spin on this value until it goes to 1. */
|
||||
.globl __secondary_hold_spinloop
|
||||
__secondary_hold_spinloop:
|
||||
@@ -124,6 +96,15 @@ __secondary_hold_spinloop:
|
||||
__secondary_hold_acknowledge:
|
||||
.llong 0x0
|
||||
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
/*
|
||||
* At offset 0x20, there is a pointer to iSeries LPAR data.
|
||||
* This is required by the hypervisor
|
||||
*/
|
||||
. = 0x20
|
||||
.llong hvReleaseData-KERNELBASE
|
||||
#endif /* CONFIG_PPC_ISERIES */
|
||||
|
||||
. = 0x60
|
||||
/*
|
||||
* The following code is used on pSeries to hold secondary processors
|
||||
@@ -1602,9 +1583,6 @@ _GLOBAL(__start_initialization_multiplatform)
|
||||
/* Setup some critical 970 SPRs before switching MMU off */
|
||||
bl .__970_cpu_preinit
|
||||
|
||||
/* cpu # */
|
||||
li r24,0
|
||||
|
||||
/* Switch off MMU if not already */
|
||||
LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE)
|
||||
add r4,r4,r30
|
||||
@@ -1683,6 +1661,9 @@ _STATIC(__after_prom_start)
|
||||
/* i.e. where we are running */
|
||||
/* the source addr */
|
||||
|
||||
cmpdi r4,0 /* In some cases the loader may */
|
||||
beq .start_here_multiplatform /* have already put us at zero */
|
||||
/* so we can skip the copy. */
|
||||
LOAD_REG_IMMEDIATE(r5,copy_to_here) /* # bytes of memory to copy */
|
||||
sub r5,r5,r27
|
||||
|
||||
@@ -1962,14 +1943,6 @@ _STATIC(start_here_common)
|
||||
li r3,0
|
||||
bl .do_cpu_ftr_fixups
|
||||
|
||||
LOAD_REG_IMMEDIATE(r26, boot_cpuid)
|
||||
lwz r26,0(r26)
|
||||
|
||||
LOAD_REG_IMMEDIATE(r24, paca) /* Get base vaddr of paca array */
|
||||
mulli r13,r26,PACA_SIZE /* Calculate vaddr of right paca */
|
||||
add r13,r13,r24 /* for this processor. */
|
||||
mtspr SPRN_SPRG3,r13
|
||||
|
||||
/* ptr to current */
|
||||
LOAD_REG_IMMEDIATE(r4, init_task)
|
||||
std r4,PACACURRENT(r13)
|
||||
@@ -1995,17 +1968,6 @@ _STATIC(start_here_common)
|
||||
/* Not reached */
|
||||
BUG_OPCODE
|
||||
|
||||
/* Put the paca pointer into r13 and SPRG3 */
|
||||
_GLOBAL(setup_boot_paca)
|
||||
LOAD_REG_IMMEDIATE(r3, boot_cpuid)
|
||||
lwz r3,0(r3)
|
||||
LOAD_REG_IMMEDIATE(r4, paca) /* Get base vaddr of paca array */
|
||||
mulli r3,r3,PACA_SIZE /* Calculate vaddr of right paca */
|
||||
add r13,r3,r4 /* for this processor. */
|
||||
mtspr SPRN_SPRG3,r13
|
||||
|
||||
blr
|
||||
|
||||
/*
|
||||
* We put a few things here that have to be page-aligned.
|
||||
* This stuff goes at the beginning of the bss, which is page-aligned.
|
||||
|
@@ -38,6 +38,7 @@
|
||||
#include <asm/iommu.h>
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <asm/machdep.h>
|
||||
#include <asm/kdump.h>
|
||||
|
||||
#define DBG(...)
|
||||
|
||||
@@ -440,8 +441,37 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid)
|
||||
tbl->it_largehint = tbl->it_halfpoint;
|
||||
spin_lock_init(&tbl->it_lock);
|
||||
|
||||
#ifdef CONFIG_CRASH_DUMP
|
||||
if (ppc_md.tce_get) {
|
||||
unsigned long index, tceval;
|
||||
unsigned long tcecount = 0;
|
||||
|
||||
/*
|
||||
* Reserve the existing mappings left by the first kernel.
|
||||
*/
|
||||
for (index = 0; index < tbl->it_size; index++) {
|
||||
tceval = ppc_md.tce_get(tbl, index + tbl->it_offset);
|
||||
/*
|
||||
* Freed TCE entry contains 0x7fffffffffffffff on JS20
|
||||
*/
|
||||
if (tceval && (tceval != 0x7fffffffffffffffUL)) {
|
||||
__set_bit(index, tbl->it_map);
|
||||
tcecount++;
|
||||
}
|
||||
}
|
||||
if ((tbl->it_size - tcecount) < KDUMP_MIN_TCE_ENTRIES) {
|
||||
printk(KERN_WARNING "TCE table is full; ");
|
||||
printk(KERN_WARNING "freeing %d entries for the kdump boot\n",
|
||||
KDUMP_MIN_TCE_ENTRIES);
|
||||
for (index = tbl->it_size - KDUMP_MIN_TCE_ENTRIES;
|
||||
index < tbl->it_size; index++)
|
||||
__clear_bit(index, tbl->it_map);
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* Clear the hardware table in case firmware left allocations in it */
|
||||
ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size);
|
||||
#endif
|
||||
|
||||
if (!welcomed) {
|
||||
printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n",
|
||||
|
@@ -302,6 +302,17 @@ void __init find_legacy_serial_ports(void)
|
||||
of_node_put(isa);
|
||||
}
|
||||
|
||||
/* First fill our array with tsi-bridge ports */
|
||||
for (np = NULL; (np = of_find_compatible_node(np, "serial", "ns16550")) != NULL;) {
|
||||
struct device_node *tsi = of_get_parent(np);
|
||||
if (tsi && !strcmp(tsi->type, "tsi-bridge")) {
|
||||
index = add_legacy_soc_port(np, np);
|
||||
if (index >= 0 && np == stdout)
|
||||
legacy_serial_console = index;
|
||||
}
|
||||
of_node_put(tsi);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
/* Next, try to locate PCI ports */
|
||||
for (np = NULL; (np = of_find_all_nodes(np));) {
|
||||
|
@@ -45,11 +45,9 @@
|
||||
static struct proc_dir_entry *proc_ppc64_lparcfg;
|
||||
#define LPARCFG_BUFF_SIZE 4096
|
||||
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
|
||||
/*
|
||||
* For iSeries legacy systems, the PPA purr function is available from the
|
||||
* emulated_time_base field in the paca.
|
||||
* Track sum of all purrs across all processors. This is used to further
|
||||
* calculate usage values by different applications
|
||||
*/
|
||||
static unsigned long get_purr(void)
|
||||
{
|
||||
@@ -57,48 +55,31 @@ static unsigned long get_purr(void)
|
||||
int cpu;
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
sum_purr += lppaca[cpu].emulated_time_base;
|
||||
if (firmware_has_feature(FW_FEATURE_ISERIES))
|
||||
sum_purr += lppaca[cpu].emulated_time_base;
|
||||
else {
|
||||
struct cpu_usage *cu;
|
||||
|
||||
#ifdef PURR_DEBUG
|
||||
printk(KERN_INFO "get_purr for cpu (%d) has value (%ld) \n",
|
||||
cpu, lppaca[cpu].emulated_time_base);
|
||||
#endif
|
||||
cu = &per_cpu(cpu_usage_array, cpu);
|
||||
sum_purr += cu->current_tb;
|
||||
}
|
||||
}
|
||||
return sum_purr;
|
||||
}
|
||||
|
||||
#define lparcfg_write NULL
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
|
||||
/*
|
||||
* Methods used to fetch LPAR data when running on an iSeries platform.
|
||||
*/
|
||||
static int lparcfg_data(struct seq_file *m, void *v)
|
||||
static int iseries_lparcfg_data(struct seq_file *m, void *v)
|
||||
{
|
||||
unsigned long pool_id, lp_index;
|
||||
unsigned long pool_id;
|
||||
int shared, entitled_capacity, max_entitled_capacity;
|
||||
int processors, max_processors;
|
||||
unsigned long purr = get_purr();
|
||||
|
||||
seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS);
|
||||
|
||||
shared = (int)(get_lppaca()->shared_proc);
|
||||
seq_printf(m, "serial_number=%c%c%c%c%c%c%c\n",
|
||||
e2a(xItExtVpdPanel.mfgID[2]),
|
||||
e2a(xItExtVpdPanel.mfgID[3]),
|
||||
e2a(xItExtVpdPanel.systemSerial[1]),
|
||||
e2a(xItExtVpdPanel.systemSerial[2]),
|
||||
e2a(xItExtVpdPanel.systemSerial[3]),
|
||||
e2a(xItExtVpdPanel.systemSerial[4]),
|
||||
e2a(xItExtVpdPanel.systemSerial[5]));
|
||||
|
||||
seq_printf(m, "system_type=%c%c%c%c\n",
|
||||
e2a(xItExtVpdPanel.machineType[0]),
|
||||
e2a(xItExtVpdPanel.machineType[1]),
|
||||
e2a(xItExtVpdPanel.machineType[2]),
|
||||
e2a(xItExtVpdPanel.machineType[3]));
|
||||
|
||||
lp_index = HvLpConfig_getLpIndex();
|
||||
seq_printf(m, "partition_id=%d\n", (int)lp_index);
|
||||
|
||||
seq_printf(m, "system_active_processors=%d\n",
|
||||
(int)HvLpConfig_getSystemPhysicalProcessors());
|
||||
@@ -137,6 +118,14 @@ static int lparcfg_data(struct seq_file *m, void *v)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else /* CONFIG_PPC_ISERIES */
|
||||
|
||||
static int iseries_lparcfg_data(struct seq_file *m, void *v)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PPC_ISERIES */
|
||||
|
||||
#ifdef CONFIG_PPC_PSERIES
|
||||
@@ -213,22 +202,6 @@ static void h_pic(unsigned long *pool_idle_time, unsigned long *num_procs)
|
||||
log_plpar_hcall_return(rc, "H_PIC");
|
||||
}
|
||||
|
||||
/* Track sum of all purrs across all processors. This is used to further */
|
||||
/* calculate usage values by different applications */
|
||||
|
||||
static unsigned long get_purr(void)
|
||||
{
|
||||
unsigned long sum_purr = 0;
|
||||
int cpu;
|
||||
struct cpu_usage *cu;
|
||||
|
||||
for_each_possible_cpu(cpu) {
|
||||
cu = &per_cpu(cpu_usage_array, cpu);
|
||||
sum_purr += cu->current_tb;
|
||||
}
|
||||
return sum_purr;
|
||||
}
|
||||
|
||||
#define SPLPAR_CHARACTERISTICS_TOKEN 20
|
||||
#define SPLPAR_MAXLENGTH 1026*(sizeof(char))
|
||||
|
||||
@@ -333,35 +306,13 @@ static int lparcfg_count_active_processors(void)
|
||||
return count;
|
||||
}
|
||||
|
||||
static int lparcfg_data(struct seq_file *m, void *v)
|
||||
static int pseries_lparcfg_data(struct seq_file *m, void *v)
|
||||
{
|
||||
int partition_potential_processors;
|
||||
int partition_active_processors;
|
||||
struct device_node *rootdn;
|
||||
const char *model = "";
|
||||
const char *system_id = "";
|
||||
unsigned int *lp_index_ptr, lp_index = 0;
|
||||
struct device_node *rtas_node;
|
||||
int *lrdrp = NULL;
|
||||
|
||||
rootdn = find_path_device("/");
|
||||
if (rootdn) {
|
||||
model = get_property(rootdn, "model", NULL);
|
||||
system_id = get_property(rootdn, "system-id", NULL);
|
||||
lp_index_ptr = (unsigned int *)
|
||||
get_property(rootdn, "ibm,partition-no", NULL);
|
||||
if (lp_index_ptr)
|
||||
lp_index = *lp_index_ptr;
|
||||
}
|
||||
|
||||
seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS);
|
||||
|
||||
seq_printf(m, "serial_number=%s\n", system_id);
|
||||
|
||||
seq_printf(m, "system_type=%s\n", model);
|
||||
|
||||
seq_printf(m, "partition_id=%d\n", (int)lp_index);
|
||||
|
||||
rtas_node = find_path_device("/rtas");
|
||||
if (rtas_node)
|
||||
lrdrp = (int *)get_property(rtas_node, "ibm,lrdr-capacity",
|
||||
@@ -549,8 +500,61 @@ out:
|
||||
return retval;
|
||||
}
|
||||
|
||||
#else /* CONFIG_PPC_PSERIES */
|
||||
|
||||
static int pseries_lparcfg_data(struct seq_file *m, void *v)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t lparcfg_write(struct file *file, const char __user * buf,
|
||||
size_t count, loff_t * off)
|
||||
{
|
||||
return count;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PPC_PSERIES */
|
||||
|
||||
static int lparcfg_data(struct seq_file *m, void *v)
|
||||
{
|
||||
struct device_node *rootdn;
|
||||
const char *model = "";
|
||||
const char *system_id = "";
|
||||
const char *tmp;
|
||||
unsigned int *lp_index_ptr, lp_index = 0;
|
||||
|
||||
seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS);
|
||||
|
||||
rootdn = find_path_device("/");
|
||||
if (rootdn) {
|
||||
tmp = get_property(rootdn, "model", NULL);
|
||||
if (tmp) {
|
||||
model = tmp;
|
||||
/* Skip "IBM," - see platforms/iseries/dt.c */
|
||||
if (firmware_has_feature(FW_FEATURE_ISERIES))
|
||||
model += 4;
|
||||
}
|
||||
tmp = get_property(rootdn, "system-id", NULL);
|
||||
if (tmp) {
|
||||
system_id = tmp;
|
||||
/* Skip "IBM," - see platforms/iseries/dt.c */
|
||||
if (firmware_has_feature(FW_FEATURE_ISERIES))
|
||||
system_id += 4;
|
||||
}
|
||||
lp_index_ptr = (unsigned int *)
|
||||
get_property(rootdn, "ibm,partition-no", NULL);
|
||||
if (lp_index_ptr)
|
||||
lp_index = *lp_index_ptr;
|
||||
}
|
||||
seq_printf(m, "serial_number=%s\n", system_id);
|
||||
seq_printf(m, "system_type=%s\n", model);
|
||||
seq_printf(m, "partition_id=%d\n", (int)lp_index);
|
||||
|
||||
if (firmware_has_feature(FW_FEATURE_ISERIES))
|
||||
return iseries_lparcfg_data(m, v);
|
||||
return pseries_lparcfg_data(m, v);
|
||||
}
|
||||
|
||||
static int lparcfg_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
return single_open(file, lparcfg_data, NULL);
|
||||
@@ -569,7 +573,8 @@ int __init lparcfg_init(void)
|
||||
mode_t mode = S_IRUSR | S_IRGRP | S_IROTH;
|
||||
|
||||
/* Allow writing if we have FW_FEATURE_SPLPAR */
|
||||
if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
|
||||
if (firmware_has_feature(FW_FEATURE_SPLPAR) &&
|
||||
!firmware_has_feature(FW_FEATURE_ISERIES)) {
|
||||
lparcfg_fops.write = lparcfg_write;
|
||||
mode |= S_IWUSR;
|
||||
}
|
||||
|
@@ -378,11 +378,13 @@ static void __init export_crashk_values(void)
|
||||
of_node_put(node);
|
||||
}
|
||||
|
||||
void __init kexec_setup(void)
|
||||
static int __init kexec_setup(void)
|
||||
{
|
||||
export_htab_values();
|
||||
export_crashk_values();
|
||||
return 0;
|
||||
}
|
||||
__initcall(kexec_setup);
|
||||
|
||||
static int __init early_parse_crashk(char *p)
|
||||
{
|
||||
|
203
arch/powerpc/kernel/misc.S
Normal file
203
arch/powerpc/kernel/misc.S
Normal file
@@ -0,0 +1,203 @@
|
||||
/*
|
||||
* This file contains miscellaneous low-level functions.
|
||||
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
|
||||
*
|
||||
* Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
|
||||
* and Paul Mackerras.
|
||||
*
|
||||
* Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com)
|
||||
* PPC64 updates by Dave Engebretsen (engebret@us.ibm.com)
|
||||
*
|
||||
* 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 <asm/ppc_asm.h>
|
||||
|
||||
.text
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
#define IN_SYNC twi 0,r5,0; isync
|
||||
#define EIEIO_32
|
||||
#define SYNC_64 sync
|
||||
#else /* CONFIG_PPC32 */
|
||||
#define IN_SYNC
|
||||
#define EIEIO_32 eieio
|
||||
#define SYNC_64
|
||||
#endif
|
||||
/*
|
||||
* Returns (address we are running at) - (address we were linked at)
|
||||
* for use before the text and data are mapped to KERNELBASE.
|
||||
*/
|
||||
|
||||
_GLOBAL(reloc_offset)
|
||||
mflr r0
|
||||
bl 1f
|
||||
1: mflr r3
|
||||
LOAD_REG_IMMEDIATE(r4,1b)
|
||||
subf r3,r4,r3
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
/*
|
||||
* add_reloc_offset(x) returns x + reloc_offset().
|
||||
*/
|
||||
_GLOBAL(add_reloc_offset)
|
||||
mflr r0
|
||||
bl 1f
|
||||
1: mflr r5
|
||||
LOAD_REG_IMMEDIATE(r4,1b)
|
||||
subf r5,r4,r5
|
||||
add r3,r3,r5
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
/*
|
||||
* I/O string operations
|
||||
*
|
||||
* insb(port, buf, len)
|
||||
* outsb(port, buf, len)
|
||||
* insw(port, buf, len)
|
||||
* outsw(port, buf, len)
|
||||
* insl(port, buf, len)
|
||||
* outsl(port, buf, len)
|
||||
* insw_ns(port, buf, len)
|
||||
* outsw_ns(port, buf, len)
|
||||
* insl_ns(port, buf, len)
|
||||
* outsl_ns(port, buf, len)
|
||||
*
|
||||
* The *_ns versions don't do byte-swapping.
|
||||
*/
|
||||
_GLOBAL(_insb)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,1
|
||||
blelr-
|
||||
00: lbz r5,0(r3)
|
||||
eieio
|
||||
stbu r5,1(r4)
|
||||
bdnz 00b
|
||||
IN_SYNC
|
||||
blr
|
||||
|
||||
_GLOBAL(_outsb)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,1
|
||||
blelr-
|
||||
00: lbzu r5,1(r4)
|
||||
stb r5,0(r3)
|
||||
EIEIO_32
|
||||
bdnz 00b
|
||||
SYNC_64
|
||||
blr
|
||||
|
||||
_GLOBAL(_insw)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,2
|
||||
blelr-
|
||||
00: lhbrx r5,0,r3
|
||||
eieio
|
||||
sthu r5,2(r4)
|
||||
bdnz 00b
|
||||
IN_SYNC
|
||||
blr
|
||||
|
||||
_GLOBAL(_outsw)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,2
|
||||
blelr-
|
||||
00: lhzu r5,2(r4)
|
||||
EIEIO_32
|
||||
sthbrx r5,0,r3
|
||||
bdnz 00b
|
||||
SYNC_64
|
||||
blr
|
||||
|
||||
_GLOBAL(_insl)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,4
|
||||
blelr-
|
||||
00: lwbrx r5,0,r3
|
||||
eieio
|
||||
stwu r5,4(r4)
|
||||
bdnz 00b
|
||||
IN_SYNC
|
||||
blr
|
||||
|
||||
_GLOBAL(_outsl)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,4
|
||||
blelr-
|
||||
00: lwzu r5,4(r4)
|
||||
stwbrx r5,0,r3
|
||||
EIEIO_32
|
||||
bdnz 00b
|
||||
SYNC_64
|
||||
blr
|
||||
|
||||
#ifdef CONFIG_PPC32
|
||||
_GLOBAL(__ide_mm_insw)
|
||||
#endif
|
||||
_GLOBAL(_insw_ns)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,2
|
||||
blelr-
|
||||
00: lhz r5,0(r3)
|
||||
eieio
|
||||
sthu r5,2(r4)
|
||||
bdnz 00b
|
||||
IN_SYNC
|
||||
blr
|
||||
|
||||
#ifdef CONFIG_PPC32
|
||||
_GLOBAL(__ide_mm_outsw)
|
||||
#endif
|
||||
_GLOBAL(_outsw_ns)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,2
|
||||
blelr-
|
||||
00: lhzu r5,2(r4)
|
||||
sth r5,0(r3)
|
||||
EIEIO_32
|
||||
bdnz 00b
|
||||
SYNC_64
|
||||
blr
|
||||
|
||||
#ifdef CONFIG_PPC32
|
||||
_GLOBAL(__ide_mm_insl)
|
||||
#endif
|
||||
_GLOBAL(_insl_ns)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,4
|
||||
blelr-
|
||||
00: lwz r5,0(r3)
|
||||
eieio
|
||||
stwu r5,4(r4)
|
||||
bdnz 00b
|
||||
IN_SYNC
|
||||
blr
|
||||
|
||||
#ifdef CONFIG_PPC32
|
||||
_GLOBAL(__ide_mm_outsl)
|
||||
#endif
|
||||
_GLOBAL(_outsl_ns)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,4
|
||||
blelr-
|
||||
00: lwzu r5,4(r4)
|
||||
stw r5,0(r3)
|
||||
EIEIO_32
|
||||
bdnz 00b
|
||||
SYNC_64
|
||||
blr
|
||||
|
@@ -60,32 +60,6 @@ _GLOBAL(mulhdu)
|
||||
addze r3,r3
|
||||
blr
|
||||
|
||||
/*
|
||||
* Returns (address we're running at) - (address we were linked at)
|
||||
* for use before the text and data are mapped to KERNELBASE.
|
||||
*/
|
||||
_GLOBAL(reloc_offset)
|
||||
mflr r0
|
||||
bl 1f
|
||||
1: mflr r3
|
||||
LOAD_REG_IMMEDIATE(r4,1b)
|
||||
subf r3,r4,r3
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
/*
|
||||
* add_reloc_offset(x) returns x + reloc_offset().
|
||||
*/
|
||||
_GLOBAL(add_reloc_offset)
|
||||
mflr r0
|
||||
bl 1f
|
||||
1: mflr r5
|
||||
LOAD_REG_IMMEDIATE(r4,1b)
|
||||
subf r5,r4,r5
|
||||
add r3,r3,r5
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
/*
|
||||
* sub_reloc_offset(x) returns x - reloc_offset().
|
||||
*/
|
||||
@@ -780,136 +754,6 @@ _GLOBAL(atomic_set_mask)
|
||||
bne- 10b
|
||||
blr
|
||||
|
||||
/*
|
||||
* I/O string operations
|
||||
*
|
||||
* insb(port, buf, len)
|
||||
* outsb(port, buf, len)
|
||||
* insw(port, buf, len)
|
||||
* outsw(port, buf, len)
|
||||
* insl(port, buf, len)
|
||||
* outsl(port, buf, len)
|
||||
* insw_ns(port, buf, len)
|
||||
* outsw_ns(port, buf, len)
|
||||
* insl_ns(port, buf, len)
|
||||
* outsl_ns(port, buf, len)
|
||||
*
|
||||
* The *_ns versions don't do byte-swapping.
|
||||
*/
|
||||
_GLOBAL(_insb)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,1
|
||||
blelr-
|
||||
00: lbz r5,0(r3)
|
||||
eieio
|
||||
stbu r5,1(r4)
|
||||
bdnz 00b
|
||||
blr
|
||||
|
||||
_GLOBAL(_outsb)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,1
|
||||
blelr-
|
||||
00: lbzu r5,1(r4)
|
||||
stb r5,0(r3)
|
||||
eieio
|
||||
bdnz 00b
|
||||
blr
|
||||
|
||||
_GLOBAL(_insw)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,2
|
||||
blelr-
|
||||
00: lhbrx r5,0,r3
|
||||
eieio
|
||||
sthu r5,2(r4)
|
||||
bdnz 00b
|
||||
blr
|
||||
|
||||
_GLOBAL(_outsw)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,2
|
||||
blelr-
|
||||
00: lhzu r5,2(r4)
|
||||
eieio
|
||||
sthbrx r5,0,r3
|
||||
bdnz 00b
|
||||
blr
|
||||
|
||||
_GLOBAL(_insl)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,4
|
||||
blelr-
|
||||
00: lwbrx r5,0,r3
|
||||
eieio
|
||||
stwu r5,4(r4)
|
||||
bdnz 00b
|
||||
blr
|
||||
|
||||
_GLOBAL(_outsl)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,4
|
||||
blelr-
|
||||
00: lwzu r5,4(r4)
|
||||
stwbrx r5,0,r3
|
||||
eieio
|
||||
bdnz 00b
|
||||
blr
|
||||
|
||||
_GLOBAL(__ide_mm_insw)
|
||||
_GLOBAL(_insw_ns)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,2
|
||||
blelr-
|
||||
00: lhz r5,0(r3)
|
||||
eieio
|
||||
sthu r5,2(r4)
|
||||
bdnz 00b
|
||||
blr
|
||||
|
||||
_GLOBAL(__ide_mm_outsw)
|
||||
_GLOBAL(_outsw_ns)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,2
|
||||
blelr-
|
||||
00: lhzu r5,2(r4)
|
||||
sth r5,0(r3)
|
||||
eieio
|
||||
bdnz 00b
|
||||
blr
|
||||
|
||||
_GLOBAL(__ide_mm_insl)
|
||||
_GLOBAL(_insl_ns)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,4
|
||||
blelr-
|
||||
00: lwz r5,0(r3)
|
||||
eieio
|
||||
stwu r5,4(r4)
|
||||
bdnz 00b
|
||||
blr
|
||||
|
||||
_GLOBAL(__ide_mm_outsl)
|
||||
_GLOBAL(_outsl_ns)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,4
|
||||
blelr-
|
||||
00: lwzu r5,4(r4)
|
||||
stw r5,0(r3)
|
||||
eieio
|
||||
bdnz 00b
|
||||
blr
|
||||
|
||||
/*
|
||||
* Extended precision shifts.
|
||||
*
|
||||
|
@@ -1,14 +1,12 @@
|
||||
/*
|
||||
* arch/powerpc/kernel/misc64.S
|
||||
*
|
||||
* This file contains miscellaneous low-level functions.
|
||||
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
|
||||
*
|
||||
* Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
|
||||
* and Paul Mackerras.
|
||||
* Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com)
|
||||
* PPC64 updates by Dave Engebretsen (engebret@us.ibm.com)
|
||||
*
|
||||
* PPC64 updates by Dave Engebretsen (engebret@us.ibm.com)
|
||||
*
|
||||
* 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
|
||||
@@ -30,41 +28,10 @@
|
||||
|
||||
.text
|
||||
|
||||
/*
|
||||
* Returns (address we are running at) - (address we were linked at)
|
||||
* for use before the text and data are mapped to KERNELBASE.
|
||||
*/
|
||||
|
||||
_GLOBAL(reloc_offset)
|
||||
mflr r0
|
||||
bl 1f
|
||||
1: mflr r3
|
||||
LOAD_REG_IMMEDIATE(r4,1b)
|
||||
subf r3,r4,r3
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
/*
|
||||
* add_reloc_offset(x) returns x + reloc_offset().
|
||||
*/
|
||||
_GLOBAL(add_reloc_offset)
|
||||
mflr r0
|
||||
bl 1f
|
||||
1: mflr r5
|
||||
LOAD_REG_IMMEDIATE(r4,1b)
|
||||
subf r5,r4,r5
|
||||
add r3,r3,r5
|
||||
mtlr r0
|
||||
blr
|
||||
|
||||
_GLOBAL(get_msr)
|
||||
mfmsr r3
|
||||
blr
|
||||
|
||||
_GLOBAL(get_dar)
|
||||
mfdar r3
|
||||
blr
|
||||
|
||||
_GLOBAL(get_srr0)
|
||||
mfsrr0 r3
|
||||
blr
|
||||
@@ -72,10 +39,6 @@ _GLOBAL(get_srr0)
|
||||
_GLOBAL(get_srr1)
|
||||
mfsrr1 r3
|
||||
blr
|
||||
|
||||
_GLOBAL(get_sp)
|
||||
mr r3,r1
|
||||
blr
|
||||
|
||||
#ifdef CONFIG_IRQSTACKS
|
||||
_GLOBAL(call_do_softirq)
|
||||
@@ -101,48 +64,6 @@ _GLOBAL(call___do_IRQ)
|
||||
blr
|
||||
#endif /* CONFIG_IRQSTACKS */
|
||||
|
||||
/*
|
||||
* To be called by C code which needs to do some operations with MMU
|
||||
* disabled. Note that interrupts have to be disabled by the caller
|
||||
* prior to calling us. The code called _MUST_ be in the RMO of course
|
||||
* and part of the linear mapping as we don't attempt to translate the
|
||||
* stack pointer at all. The function is called with the stack switched
|
||||
* to this CPU emergency stack
|
||||
*
|
||||
* prototype is void *call_with_mmu_off(void *func, void *data);
|
||||
*
|
||||
* the called function is expected to be of the form
|
||||
*
|
||||
* void *called(void *data);
|
||||
*/
|
||||
_GLOBAL(call_with_mmu_off)
|
||||
mflr r0 /* get link, save it on stackframe */
|
||||
std r0,16(r1)
|
||||
mr r1,r5 /* save old stack ptr */
|
||||
ld r1,PACAEMERGSP(r13) /* get emerg. stack */
|
||||
subi r1,r1,STACK_FRAME_OVERHEAD
|
||||
std r0,16(r1) /* save link on emerg. stack */
|
||||
std r5,0(r1) /* save old stack ptr in backchain */
|
||||
ld r3,0(r3) /* get to real function ptr (assume same TOC) */
|
||||
bl 2f /* we need LR to return, continue at label 2 */
|
||||
|
||||
ld r0,16(r1) /* we return here from the call, get LR and */
|
||||
ld r1,0(r1) /* .. old stack ptr */
|
||||
mtspr SPRN_SRR0,r0 /* and get back to virtual mode with these */
|
||||
mfmsr r4
|
||||
ori r4,r4,MSR_IR|MSR_DR
|
||||
mtspr SPRN_SRR1,r4
|
||||
rfid
|
||||
|
||||
2: mtspr SPRN_SRR0,r3 /* coming from above, enter real mode */
|
||||
mr r3,r4 /* get parameter */
|
||||
mfmsr r0
|
||||
ori r0,r0,MSR_IR|MSR_DR
|
||||
xori r0,r0,MSR_IR|MSR_DR
|
||||
mtspr SPRN_SRR1,r0
|
||||
rfid
|
||||
|
||||
|
||||
.section ".toc","aw"
|
||||
PPC64_CACHES:
|
||||
.tc ppc64_caches[TC],ppc64_caches
|
||||
@@ -323,144 +244,6 @@ _GLOBAL(__flush_dcache_icache)
|
||||
bdnz 1b
|
||||
isync
|
||||
blr
|
||||
|
||||
/*
|
||||
* I/O string operations
|
||||
*
|
||||
* insb(port, buf, len)
|
||||
* outsb(port, buf, len)
|
||||
* insw(port, buf, len)
|
||||
* outsw(port, buf, len)
|
||||
* insl(port, buf, len)
|
||||
* outsl(port, buf, len)
|
||||
* insw_ns(port, buf, len)
|
||||
* outsw_ns(port, buf, len)
|
||||
* insl_ns(port, buf, len)
|
||||
* outsl_ns(port, buf, len)
|
||||
*
|
||||
* The *_ns versions don't do byte-swapping.
|
||||
*/
|
||||
_GLOBAL(_insb)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,1
|
||||
blelr-
|
||||
00: lbz r5,0(r3)
|
||||
eieio
|
||||
stbu r5,1(r4)
|
||||
bdnz 00b
|
||||
twi 0,r5,0
|
||||
isync
|
||||
blr
|
||||
|
||||
_GLOBAL(_outsb)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,1
|
||||
blelr-
|
||||
00: lbzu r5,1(r4)
|
||||
stb r5,0(r3)
|
||||
bdnz 00b
|
||||
sync
|
||||
blr
|
||||
|
||||
_GLOBAL(_insw)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,2
|
||||
blelr-
|
||||
00: lhbrx r5,0,r3
|
||||
eieio
|
||||
sthu r5,2(r4)
|
||||
bdnz 00b
|
||||
twi 0,r5,0
|
||||
isync
|
||||
blr
|
||||
|
||||
_GLOBAL(_outsw)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,2
|
||||
blelr-
|
||||
00: lhzu r5,2(r4)
|
||||
sthbrx r5,0,r3
|
||||
bdnz 00b
|
||||
sync
|
||||
blr
|
||||
|
||||
_GLOBAL(_insl)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,4
|
||||
blelr-
|
||||
00: lwbrx r5,0,r3
|
||||
eieio
|
||||
stwu r5,4(r4)
|
||||
bdnz 00b
|
||||
twi 0,r5,0
|
||||
isync
|
||||
blr
|
||||
|
||||
_GLOBAL(_outsl)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,4
|
||||
blelr-
|
||||
00: lwzu r5,4(r4)
|
||||
stwbrx r5,0,r3
|
||||
bdnz 00b
|
||||
sync
|
||||
blr
|
||||
|
||||
/* _GLOBAL(ide_insw) now in drivers/ide/ide-iops.c */
|
||||
_GLOBAL(_insw_ns)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,2
|
||||
blelr-
|
||||
00: lhz r5,0(r3)
|
||||
eieio
|
||||
sthu r5,2(r4)
|
||||
bdnz 00b
|
||||
twi 0,r5,0
|
||||
isync
|
||||
blr
|
||||
|
||||
/* _GLOBAL(ide_outsw) now in drivers/ide/ide-iops.c */
|
||||
_GLOBAL(_outsw_ns)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,2
|
||||
blelr-
|
||||
00: lhzu r5,2(r4)
|
||||
sth r5,0(r3)
|
||||
bdnz 00b
|
||||
sync
|
||||
blr
|
||||
|
||||
_GLOBAL(_insl_ns)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,4
|
||||
blelr-
|
||||
00: lwz r5,0(r3)
|
||||
eieio
|
||||
stwu r5,4(r4)
|
||||
bdnz 00b
|
||||
twi 0,r5,0
|
||||
isync
|
||||
blr
|
||||
|
||||
_GLOBAL(_outsl_ns)
|
||||
cmpwi 0,r5,0
|
||||
mtctr r5
|
||||
subi r4,r4,4
|
||||
blelr-
|
||||
00: lwzu r5,4(r4)
|
||||
stw r5,0(r3)
|
||||
bdnz 00b
|
||||
sync
|
||||
blr
|
||||
|
||||
/*
|
||||
* identify_cpu and calls setup_cpu
|
||||
@@ -605,6 +388,7 @@ _GLOBAL(real_writeb)
|
||||
blr
|
||||
#endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) */
|
||||
|
||||
#ifdef CONFIG_CPU_FREQ_PMAC64
|
||||
/*
|
||||
* SCOM access functions for 970 (FX only for now)
|
||||
*
|
||||
@@ -673,6 +457,7 @@ _GLOBAL(scom970_write)
|
||||
/* restore interrupts */
|
||||
mtmsrd r5,1
|
||||
blr
|
||||
#endif /* CONFIG_CPU_FREQ_PMAC64 */
|
||||
|
||||
|
||||
/*
|
||||
|
@@ -16,7 +16,6 @@
|
||||
#include <asm/ptrace.h>
|
||||
#include <asm/page.h>
|
||||
#include <asm/lppaca.h>
|
||||
#include <asm/iseries/it_lp_queue.h>
|
||||
#include <asm/iseries/it_lp_reg_save.h>
|
||||
#include <asm/paca.h>
|
||||
|
||||
|
@@ -30,6 +30,7 @@
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kexec.h>
|
||||
#include <linux/debugfs.h>
|
||||
|
||||
#include <asm/prom.h>
|
||||
#include <asm/rtas.h>
|
||||
@@ -952,6 +953,7 @@ static struct ibm_pa_feature {
|
||||
/* put this back once we know how to test if firmware does 64k IO */
|
||||
{CPU_FTR_CI_LARGE_PAGE, 0, 1, 2, 0},
|
||||
#endif
|
||||
{CPU_FTR_REAL_LE, PPC_FEATURE_TRUE_LE, 5, 0, 0},
|
||||
};
|
||||
|
||||
static void __init check_cpu_pa_features(unsigned long node)
|
||||
@@ -1124,24 +1126,6 @@ static int __init early_init_dt_scan_chosen(unsigned long node,
|
||||
tce_alloc_end = *lprop;
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PPC_RTAS
|
||||
/* To help early debugging via the front panel, we retrieve a minimal
|
||||
* set of RTAS infos now if available
|
||||
*/
|
||||
{
|
||||
u64 *basep, *entryp, *sizep;
|
||||
|
||||
basep = of_get_flat_dt_prop(node, "linux,rtas-base", NULL);
|
||||
entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL);
|
||||
sizep = of_get_flat_dt_prop(node, "linux,rtas-size", NULL);
|
||||
if (basep && entryp && sizep) {
|
||||
rtas.base = *basep;
|
||||
rtas.entry = *entryp;
|
||||
rtas.size = *sizep;
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_PPC_RTAS */
|
||||
|
||||
#ifdef CONFIG_KEXEC
|
||||
lprop = (u64*)of_get_flat_dt_prop(node, "linux,crashkernel-base", NULL);
|
||||
if (lprop)
|
||||
@@ -1326,6 +1310,11 @@ void __init early_init_devtree(void *params)
|
||||
/* Setup flat device-tree pointer */
|
||||
initial_boot_params = params;
|
||||
|
||||
#ifdef CONFIG_PPC_RTAS
|
||||
/* Some machines might need RTAS info for debugging, grab it now. */
|
||||
of_scan_flat_dt(early_init_dt_scan_rtas, NULL);
|
||||
#endif
|
||||
|
||||
/* Retrieve various informations from the /chosen node of the
|
||||
* device-tree, including the platform type, initrd location and
|
||||
* size, TCE reserve, and more ...
|
||||
@@ -2148,3 +2137,27 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
static struct debugfs_blob_wrapper flat_dt_blob;
|
||||
|
||||
static int __init export_flat_device_tree(void)
|
||||
{
|
||||
struct dentry *d;
|
||||
|
||||
d = debugfs_create_dir("powerpc", NULL);
|
||||
if (!d)
|
||||
return 1;
|
||||
|
||||
flat_dt_blob.data = initial_boot_params;
|
||||
flat_dt_blob.size = initial_boot_params->totalsize;
|
||||
|
||||
d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR,
|
||||
d, &flat_dt_blob);
|
||||
if (!d)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
__initcall(export_flat_device_tree);
|
||||
#endif
|
||||
|
@@ -38,16 +38,19 @@
|
||||
struct rtas_t rtas = {
|
||||
.lock = SPIN_LOCK_UNLOCKED
|
||||
};
|
||||
EXPORT_SYMBOL(rtas);
|
||||
|
||||
struct rtas_suspend_me_data {
|
||||
long waiting;
|
||||
struct rtas_args *args;
|
||||
};
|
||||
|
||||
EXPORT_SYMBOL(rtas);
|
||||
|
||||
DEFINE_SPINLOCK(rtas_data_buf_lock);
|
||||
EXPORT_SYMBOL(rtas_data_buf_lock);
|
||||
|
||||
char rtas_data_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned;
|
||||
EXPORT_SYMBOL(rtas_data_buf);
|
||||
|
||||
unsigned long rtas_rmo_buf;
|
||||
|
||||
/*
|
||||
@@ -106,11 +109,71 @@ static void call_rtas_display_status_delay(char c)
|
||||
}
|
||||
}
|
||||
|
||||
void __init udbg_init_rtas(void)
|
||||
void __init udbg_init_rtas_panel(void)
|
||||
{
|
||||
udbg_putc = call_rtas_display_status_delay;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_UDBG_RTAS_CONSOLE
|
||||
|
||||
/* If you think you're dying before early_init_dt_scan_rtas() does its
|
||||
* work, you can hard code the token values for your firmware here and
|
||||
* hardcode rtas.base/entry etc.
|
||||
*/
|
||||
static unsigned int rtas_putchar_token = RTAS_UNKNOWN_SERVICE;
|
||||
static unsigned int rtas_getchar_token = RTAS_UNKNOWN_SERVICE;
|
||||
|
||||
static void udbg_rtascon_putc(char c)
|
||||
{
|
||||
int tries;
|
||||
|
||||
if (!rtas.base)
|
||||
return;
|
||||
|
||||
/* Add CRs before LFs */
|
||||
if (c == '\n')
|
||||
udbg_rtascon_putc('\r');
|
||||
|
||||
/* if there is more than one character to be displayed, wait a bit */
|
||||
for (tries = 0; tries < 16; tries++) {
|
||||
if (rtas_call(rtas_putchar_token, 1, 1, NULL, c) == 0)
|
||||
break;
|
||||
udelay(1000);
|
||||
}
|
||||
}
|
||||
|
||||
static int udbg_rtascon_getc_poll(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
if (!rtas.base)
|
||||
return -1;
|
||||
|
||||
if (rtas_call(rtas_getchar_token, 0, 2, &c))
|
||||
return -1;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
static int udbg_rtascon_getc(void)
|
||||
{
|
||||
int c;
|
||||
|
||||
while ((c = udbg_rtascon_getc_poll()) == -1)
|
||||
;
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
void __init udbg_init_rtas_console(void)
|
||||
{
|
||||
udbg_putc = udbg_rtascon_putc;
|
||||
udbg_getc = udbg_rtascon_getc;
|
||||
udbg_getc_poll = udbg_rtascon_getc_poll;
|
||||
}
|
||||
#endif /* CONFIG_UDBG_RTAS_CONSOLE */
|
||||
|
||||
void rtas_progress(char *s, unsigned short hex)
|
||||
{
|
||||
struct device_node *root;
|
||||
@@ -236,6 +299,7 @@ int rtas_token(const char *service)
|
||||
tokp = (int *) get_property(rtas.dev, service, NULL);
|
||||
return tokp ? *tokp : RTAS_UNKNOWN_SERVICE;
|
||||
}
|
||||
EXPORT_SYMBOL(rtas_token);
|
||||
|
||||
#ifdef CONFIG_RTAS_ERROR_LOGGING
|
||||
/*
|
||||
@@ -328,7 +392,7 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...)
|
||||
char *buff_copy = NULL;
|
||||
int ret;
|
||||
|
||||
if (token == RTAS_UNKNOWN_SERVICE)
|
||||
if (!rtas.entry || token == RTAS_UNKNOWN_SERVICE)
|
||||
return -1;
|
||||
|
||||
/* Gotta do something different here, use global lock for now... */
|
||||
@@ -369,6 +433,7 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...)
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL(rtas_call);
|
||||
|
||||
/* For RTAS_BUSY (-2), delay for 1 millisecond. For an extended busy status
|
||||
* code of 990n, perform the hinted delay of 10^n (last digit) milliseconds.
|
||||
@@ -388,6 +453,7 @@ unsigned int rtas_busy_delay_time(int status)
|
||||
|
||||
return ms;
|
||||
}
|
||||
EXPORT_SYMBOL(rtas_busy_delay_time);
|
||||
|
||||
/* For an RTAS busy status code, perform the hinted delay. */
|
||||
unsigned int rtas_busy_delay(int status)
|
||||
@@ -401,6 +467,7 @@ unsigned int rtas_busy_delay(int status)
|
||||
|
||||
return ms;
|
||||
}
|
||||
EXPORT_SYMBOL(rtas_busy_delay);
|
||||
|
||||
int rtas_error_rc(int rtas_rc)
|
||||
{
|
||||
@@ -446,6 +513,7 @@ int rtas_get_power_level(int powerdomain, int *level)
|
||||
return rtas_error_rc(rc);
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL(rtas_get_power_level);
|
||||
|
||||
int rtas_set_power_level(int powerdomain, int level, int *setlevel)
|
||||
{
|
||||
@@ -463,6 +531,7 @@ int rtas_set_power_level(int powerdomain, int level, int *setlevel)
|
||||
return rtas_error_rc(rc);
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL(rtas_set_power_level);
|
||||
|
||||
int rtas_get_sensor(int sensor, int index, int *state)
|
||||
{
|
||||
@@ -480,6 +549,7 @@ int rtas_get_sensor(int sensor, int index, int *state)
|
||||
return rtas_error_rc(rc);
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL(rtas_get_sensor);
|
||||
|
||||
int rtas_set_indicator(int indicator, int index, int new_value)
|
||||
{
|
||||
@@ -497,6 +567,7 @@ int rtas_set_indicator(int indicator, int index, int new_value)
|
||||
return rtas_error_rc(rc);
|
||||
return rc;
|
||||
}
|
||||
EXPORT_SYMBOL(rtas_set_indicator);
|
||||
|
||||
void rtas_restart(char *cmd)
|
||||
{
|
||||
@@ -791,14 +862,34 @@ void __init rtas_initialize(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
int __init early_init_dt_scan_rtas(unsigned long node,
|
||||
const char *uname, int depth, void *data)
|
||||
{
|
||||
u32 *basep, *entryp, *sizep;
|
||||
|
||||
EXPORT_SYMBOL(rtas_token);
|
||||
EXPORT_SYMBOL(rtas_call);
|
||||
EXPORT_SYMBOL(rtas_data_buf);
|
||||
EXPORT_SYMBOL(rtas_data_buf_lock);
|
||||
EXPORT_SYMBOL(rtas_busy_delay_time);
|
||||
EXPORT_SYMBOL(rtas_busy_delay);
|
||||
EXPORT_SYMBOL(rtas_get_sensor);
|
||||
EXPORT_SYMBOL(rtas_get_power_level);
|
||||
EXPORT_SYMBOL(rtas_set_power_level);
|
||||
EXPORT_SYMBOL(rtas_set_indicator);
|
||||
if (depth != 1 || strcmp(uname, "rtas") != 0)
|
||||
return 0;
|
||||
|
||||
basep = of_get_flat_dt_prop(node, "linux,rtas-base", NULL);
|
||||
entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL);
|
||||
sizep = of_get_flat_dt_prop(node, "rtas-size", NULL);
|
||||
|
||||
if (basep && entryp && sizep) {
|
||||
rtas.base = *basep;
|
||||
rtas.entry = *entryp;
|
||||
rtas.size = *sizep;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_UDBG_RTAS_CONSOLE
|
||||
basep = of_get_flat_dt_prop(node, "put-term-char", NULL);
|
||||
if (basep)
|
||||
rtas_putchar_token = *basep;
|
||||
|
||||
basep = of_get_flat_dt_prop(node, "get-term-char", NULL);
|
||||
if (basep)
|
||||
rtas_getchar_token = *basep;
|
||||
#endif
|
||||
|
||||
/* break now */
|
||||
return 1;
|
||||
}
|
||||
|
@@ -149,6 +149,13 @@ early_param("smt-enabled", early_smt_enabled);
|
||||
#define check_smt_enabled()
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
/* Put the paca pointer into r13 and SPRG3 */
|
||||
void __init setup_paca(int cpu)
|
||||
{
|
||||
local_paca = &paca[cpu];
|
||||
mtspr(SPRN_SPRG3, local_paca);
|
||||
}
|
||||
|
||||
/*
|
||||
* Early initialization entry point. This is called by head.S
|
||||
* with MMU translation disabled. We rely on the "feature" of
|
||||
@@ -170,6 +177,9 @@ early_param("smt-enabled", early_smt_enabled);
|
||||
|
||||
void __init early_setup(unsigned long dt_ptr)
|
||||
{
|
||||
/* Assume we're on cpu 0 for now. Don't write to the paca yet! */
|
||||
setup_paca(0);
|
||||
|
||||
/* Enable early debugging if any specified (see udbg.h) */
|
||||
udbg_early_init();
|
||||
|
||||
@@ -183,7 +193,7 @@ void __init early_setup(unsigned long dt_ptr)
|
||||
early_init_devtree(__va(dt_ptr));
|
||||
|
||||
/* Now we know the logical id of our boot cpu, setup the paca. */
|
||||
setup_boot_paca();
|
||||
setup_paca(boot_cpuid);
|
||||
|
||||
/* Fix up paca fields required for the boot cpu */
|
||||
get_paca()->cpu_start = 1;
|
||||
@@ -350,19 +360,11 @@ void __init setup_system(void)
|
||||
*/
|
||||
unflatten_device_tree();
|
||||
|
||||
#ifdef CONFIG_KEXEC
|
||||
kexec_setup(); /* requires unflattened device tree. */
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Fill the ppc64_caches & systemcfg structures with informations
|
||||
* retrieved from the device-tree. Need to be called before
|
||||
* finish_device_tree() since the later requires some of the
|
||||
* informations filled up here to properly parse the interrupt
|
||||
* 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).
|
||||
* informations filled up here to properly parse the interrupt tree.
|
||||
*/
|
||||
initialize_cache_info();
|
||||
|
||||
|
@@ -52,9 +52,13 @@
|
||||
#include <asm/firmware.h>
|
||||
#include <asm/processor.h>
|
||||
#endif
|
||||
#include <asm/kexec.h>
|
||||
|
||||
#ifdef CONFIG_PPC64 /* XXX */
|
||||
#define _IO_BASE pci_io_base
|
||||
#ifdef CONFIG_KEXEC
|
||||
cpumask_t cpus_in_sr = CPU_MASK_NONE;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DEBUGGER
|
||||
@@ -97,7 +101,7 @@ static DEFINE_SPINLOCK(die_lock);
|
||||
|
||||
int die(const char *str, struct pt_regs *regs, long err)
|
||||
{
|
||||
static int die_counter, crash_dump_start = 0;
|
||||
static int die_counter;
|
||||
|
||||
if (debugger(regs))
|
||||
return 1;
|
||||
@@ -137,21 +141,12 @@ int die(const char *str, struct pt_regs *regs, long err)
|
||||
print_modules();
|
||||
show_regs(regs);
|
||||
bust_spinlocks(0);
|
||||
|
||||
if (!crash_dump_start && kexec_should_crash(current)) {
|
||||
crash_dump_start = 1;
|
||||
spin_unlock_irq(&die_lock);
|
||||
crash_kexec(regs);
|
||||
/* NOTREACHED */
|
||||
}
|
||||
spin_unlock_irq(&die_lock);
|
||||
if (crash_dump_start)
|
||||
/*
|
||||
* Only for soft-reset: Other CPUs will be responded to an IPI
|
||||
* sent by first kexec CPU.
|
||||
*/
|
||||
for(;;)
|
||||
;
|
||||
|
||||
if (kexec_should_crash(current) ||
|
||||
kexec_sr_activated(smp_processor_id()))
|
||||
crash_kexec(regs);
|
||||
crash_kexec_secondary(regs);
|
||||
|
||||
if (in_interrupt())
|
||||
panic("Fatal exception in interrupt");
|
||||
@@ -215,6 +210,10 @@ void system_reset_exception(struct pt_regs *regs)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_KEXEC
|
||||
cpu_set(smp_processor_id(), cpus_in_sr);
|
||||
#endif
|
||||
|
||||
die("System Reset", regs, SIGABRT);
|
||||
|
||||
/* Must die if the interrupt is not recoverable */
|
||||
|
@@ -34,9 +34,12 @@ void __init udbg_early_init(void)
|
||||
#elif defined(CONFIG_PPC_EARLY_DEBUG_G5)
|
||||
/* For use on Apple G5 machines */
|
||||
udbg_init_pmac_realmode();
|
||||
#elif defined(CONFIG_PPC_EARLY_DEBUG_RTAS)
|
||||
#elif defined(CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL)
|
||||
/* RTAS panel debug */
|
||||
udbg_init_rtas();
|
||||
udbg_init_rtas_panel();
|
||||
#elif defined(CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE)
|
||||
/* RTAS console debug */
|
||||
udbg_init_rtas_console();
|
||||
#elif defined(CONFIG_PPC_EARLY_DEBUG_MAPLE)
|
||||
/* Maple real mode debug */
|
||||
udbg_init_maple_realmode();
|
||||
|
Reference in New Issue
Block a user