forked from Minki/linux
Merge git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc-merge
Fix up delete/modify conflict of arch/ppc/kernel/process.c by hand (it's gone, gone, gone). Signed-off-by: Linus Torvalds <torvalds@osdl.org>
This commit is contained in:
commit
45bfe98bd7
@ -11,7 +11,8 @@ CFLAGS_btext.o += -fPIC
|
||||
endif
|
||||
|
||||
obj-y := semaphore.o cputable.o ptrace.o syscalls.o \
|
||||
irq.o align.o signal_32.o pmc.o vdso.o
|
||||
irq.o align.o signal_32.o pmc.o vdso.o \
|
||||
init_task.o process.o
|
||||
obj-y += vdso32/
|
||||
obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
|
||||
signal_64.o ptrace32.o systbl.o \
|
||||
@ -44,8 +45,7 @@ extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o
|
||||
extra-$(CONFIG_8xx) := head_8xx.o
|
||||
extra-y += vmlinux.lds
|
||||
|
||||
obj-y += process.o init_task.o time.o \
|
||||
prom.o traps.o setup-common.o udbg.o
|
||||
obj-y += time.o prom.o traps.o setup-common.o udbg.o
|
||||
obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o systbl.o
|
||||
obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o
|
||||
obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o
|
||||
|
@ -53,6 +53,7 @@ EXPORT_SYMBOL(io_page_mask);
|
||||
#ifdef CONFIG_PPC_MULTIPLATFORM
|
||||
static void fixup_resource(struct resource *res, struct pci_dev *dev);
|
||||
static void do_bus_setup(struct pci_bus *bus);
|
||||
static void phbs_remap_io(void);
|
||||
#endif
|
||||
|
||||
/* pci_io_base -- the base address from which io bars are offsets.
|
||||
@ -251,6 +252,7 @@ void pcibios_free_controller(struct pci_controller *phb)
|
||||
kfree(phb);
|
||||
}
|
||||
|
||||
#ifndef CONFIG_PPC_ISERIES
|
||||
void __devinit pcibios_claim_one_bus(struct pci_bus *b)
|
||||
{
|
||||
struct pci_dev *dev;
|
||||
@ -275,7 +277,6 @@ void __devinit pcibios_claim_one_bus(struct pci_bus *b)
|
||||
EXPORT_SYMBOL_GPL(pcibios_claim_one_bus);
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_PPC_ISERIES
|
||||
static void __init pcibios_claim_of_setup(void)
|
||||
{
|
||||
struct pci_bus *b;
|
||||
@ -1218,7 +1219,7 @@ int remap_bus_range(struct pci_bus *bus)
|
||||
}
|
||||
EXPORT_SYMBOL(remap_bus_range);
|
||||
|
||||
void phbs_remap_io(void)
|
||||
static void phbs_remap_io(void)
|
||||
{
|
||||
struct pci_controller *hose, *tmp;
|
||||
|
||||
|
@ -201,13 +201,13 @@ int dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs)
|
||||
}
|
||||
#endif /* CONFIG_SPE */
|
||||
|
||||
#ifndef CONFIG_SMP
|
||||
/*
|
||||
* If we are doing lazy switching of CPU state (FP, altivec or SPE),
|
||||
* and the current task has some state, discard it.
|
||||
*/
|
||||
static inline void discard_lazy_cpu_state(void)
|
||||
void discard_lazy_cpu_state(void)
|
||||
{
|
||||
#ifndef CONFIG_SMP
|
||||
preempt_disable();
|
||||
if (last_task_used_math == current)
|
||||
last_task_used_math = NULL;
|
||||
@ -220,9 +220,10 @@ static inline void discard_lazy_cpu_state(void)
|
||||
last_task_used_spe = NULL;
|
||||
#endif
|
||||
preempt_enable();
|
||||
#endif /* CONFIG_SMP */
|
||||
}
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
#ifdef CONFIG_PPC_MERGE /* XXX for now */
|
||||
int set_dabr(unsigned long dabr)
|
||||
{
|
||||
if (ppc_md.set_dabr)
|
||||
@ -231,6 +232,7 @@ int set_dabr(unsigned long dabr)
|
||||
mtspr(SPRN_DABR, dabr);
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
DEFINE_PER_CPU(struct cpu_usage, cpu_usage_array);
|
||||
|
@ -1100,17 +1100,37 @@ static int __init early_init_dt_scan_memory(unsigned long node,
|
||||
|
||||
static void __init early_reserve_mem(void)
|
||||
{
|
||||
unsigned long base, size;
|
||||
unsigned long *reserve_map;
|
||||
u64 base, size;
|
||||
u64 *reserve_map;
|
||||
|
||||
reserve_map = (unsigned long *)(((unsigned long)initial_boot_params) +
|
||||
reserve_map = (u64 *)(((unsigned long)initial_boot_params) +
|
||||
initial_boot_params->off_mem_rsvmap);
|
||||
#ifdef CONFIG_PPC32
|
||||
/*
|
||||
* Handle the case where we might be booting from an old kexec
|
||||
* image that setup the mem_rsvmap as pairs of 32-bit values
|
||||
*/
|
||||
if (*reserve_map > 0xffffffffull) {
|
||||
u32 base_32, size_32;
|
||||
u32 *reserve_map_32 = (u32 *)reserve_map;
|
||||
|
||||
while (1) {
|
||||
base_32 = *(reserve_map_32++);
|
||||
size_32 = *(reserve_map_32++);
|
||||
if (size_32 == 0)
|
||||
break;
|
||||
DBG("reserving: %lx -> %lx\n", base_32, size_32);
|
||||
lmb_reserve(base_32, size_32);
|
||||
}
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
while (1) {
|
||||
base = *(reserve_map++);
|
||||
size = *(reserve_map++);
|
||||
if (size == 0)
|
||||
break;
|
||||
DBG("reserving: %lx -> %lx\n", base, size);
|
||||
DBG("reserving: %llx -> %llx\n", base, size);
|
||||
lmb_reserve(base, size);
|
||||
}
|
||||
|
||||
|
@ -137,8 +137,8 @@ struct prom_t {
|
||||
};
|
||||
|
||||
struct mem_map_entry {
|
||||
unsigned long base;
|
||||
unsigned long size;
|
||||
u64 base;
|
||||
u64 size;
|
||||
};
|
||||
|
||||
typedef u32 cell_t;
|
||||
@ -897,9 +897,9 @@ static unsigned long __init prom_next_cell(int s, cell_t **cellp)
|
||||
* If problems seem to show up, it would be a good start to track
|
||||
* them down.
|
||||
*/
|
||||
static void reserve_mem(unsigned long base, unsigned long size)
|
||||
static void reserve_mem(u64 base, u64 size)
|
||||
{
|
||||
unsigned long top = base + size;
|
||||
u64 top = base + size;
|
||||
unsigned long cnt = RELOC(mem_reserve_cnt);
|
||||
|
||||
if (size == 0)
|
||||
|
@ -497,6 +497,15 @@ static long restore_user_regs(struct pt_regs *regs,
|
||||
if (err)
|
||||
return 1;
|
||||
|
||||
/*
|
||||
* Do this before updating the thread state in
|
||||
* current->thread.fpr/vr/evr. That way, if we get preempted
|
||||
* and another task grabs the FPU/Altivec/SPE, it won't be
|
||||
* tempted to save the current CPU state into the thread_struct
|
||||
* and corrupt what we are writing there.
|
||||
*/
|
||||
discard_lazy_cpu_state();
|
||||
|
||||
/* force the process to reload the FP registers from
|
||||
current->thread when it next does FP instructions */
|
||||
regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1);
|
||||
@ -538,18 +547,6 @@ static long restore_user_regs(struct pt_regs *regs,
|
||||
return 1;
|
||||
#endif /* CONFIG_SPE */
|
||||
|
||||
#ifndef CONFIG_SMP
|
||||
preempt_disable();
|
||||
if (last_task_used_math == current)
|
||||
last_task_used_math = NULL;
|
||||
if (last_task_used_altivec == current)
|
||||
last_task_used_altivec = NULL;
|
||||
#ifdef CONFIG_SPE
|
||||
if (last_task_used_spe == current)
|
||||
last_task_used_spe = NULL;
|
||||
#endif
|
||||
preempt_enable();
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -207,10 +207,20 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig,
|
||||
|
||||
if (!sig)
|
||||
regs->gpr[13] = save_r13;
|
||||
err |= __copy_from_user(¤t->thread.fpr, &sc->fp_regs, FP_REGS_SIZE);
|
||||
if (set != NULL)
|
||||
err |= __get_user(set->sig[0], &sc->oldmask);
|
||||
|
||||
/*
|
||||
* Do this before updating the thread state in
|
||||
* current->thread.fpr/vr. That way, if we get preempted
|
||||
* and another task grabs the FPU/Altivec, it won't be
|
||||
* tempted to save the current CPU state into the thread_struct
|
||||
* and corrupt what we are writing there.
|
||||
*/
|
||||
discard_lazy_cpu_state();
|
||||
|
||||
err |= __copy_from_user(¤t->thread.fpr, &sc->fp_regs, FP_REGS_SIZE);
|
||||
|
||||
#ifdef CONFIG_ALTIVEC
|
||||
err |= __get_user(v_regs, &sc->v_regs);
|
||||
err |= __get_user(msr, &sc->gp_regs[PT_MSR]);
|
||||
@ -229,14 +239,6 @@ static long restore_sigcontext(struct pt_regs *regs, sigset_t *set, int sig,
|
||||
current->thread.vrsave = 0;
|
||||
#endif /* CONFIG_ALTIVEC */
|
||||
|
||||
#ifndef CONFIG_SMP
|
||||
preempt_disable();
|
||||
if (last_task_used_math == current)
|
||||
last_task_used_math = NULL;
|
||||
if (last_task_used_altivec == current)
|
||||
last_task_used_altivec = NULL;
|
||||
preempt_enable();
|
||||
#endif
|
||||
/* Force reload of FP/VEC */
|
||||
regs->msr &= ~(MSR_FP | MSR_FE0 | MSR_FE1 | MSR_VEC);
|
||||
|
||||
|
@ -142,7 +142,7 @@ static void cbe_idle(void)
|
||||
}
|
||||
}
|
||||
|
||||
int cbe_system_reset_exception(struct pt_regs *regs)
|
||||
static int cbe_system_reset_exception(struct pt_regs *regs)
|
||||
{
|
||||
switch (regs->msr & SRR1_WAKEMASK) {
|
||||
case SRR1_WAKEEE:
|
||||
|
@ -57,7 +57,7 @@
|
||||
#define DBG(fmt...)
|
||||
#endif
|
||||
|
||||
void cell_show_cpuinfo(struct seq_file *m)
|
||||
static void cell_show_cpuinfo(struct seq_file *m)
|
||||
{
|
||||
struct device_node *root;
|
||||
const char *model = "";
|
||||
|
@ -29,7 +29,9 @@
|
||||
* value of the spu_status register after the SPU has stopped.
|
||||
*
|
||||
*/
|
||||
long do_spu_run(struct file *filp, __u32 __user *unpc, __u32 __user *ustatus)
|
||||
static long do_spu_run(struct file *filp,
|
||||
__u32 __user *unpc,
|
||||
__u32 __user *ustatus)
|
||||
{
|
||||
long ret;
|
||||
struct spufs_inode_info *i;
|
||||
|
@ -1,8 +1,8 @@
|
||||
EXTRA_CFLAGS += -mno-minimal-toc
|
||||
|
||||
obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o \
|
||||
hvcall.o proc.o htab.o iommu.o misc.o
|
||||
obj-$(CONFIG_PCI) += pci.o irq.o vpdinfo.o
|
||||
hvcall.o proc.o htab.o iommu.o misc.o irq.o
|
||||
obj-$(CONFIG_PCI) += pci.o vpdinfo.o
|
||||
obj-$(CONFIG_IBMVIO) += vio.o
|
||||
obj-$(CONFIG_SMP) += smp.o
|
||||
obj-$(CONFIG_VIOPATH) += viopath.o
|
||||
|
@ -34,6 +34,8 @@
|
||||
#include <asm/pci-bridge.h>
|
||||
#include <asm/iseries/hv_call_xm.h>
|
||||
|
||||
#include "iommu.h"
|
||||
|
||||
extern struct list_head iSeries_Global_Device_List;
|
||||
|
||||
|
||||
|
35
arch/powerpc/platforms/iseries/iommu.h
Normal file
35
arch/powerpc/platforms/iseries/iommu.h
Normal file
@ -0,0 +1,35 @@
|
||||
#ifndef _PLATFORMS_ISERIES_IOMMU_H
|
||||
#define _PLATFORMS_ISERIES_IOMMU_H
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Stephen Rothwell, IBM Corporation
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the:
|
||||
* Free Software Foundation, Inc.,
|
||||
* 59 Temple Place, Suite 330,
|
||||
* Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
struct device_node;
|
||||
struct iommu_table;
|
||||
|
||||
/* Creates table for an individual device node */
|
||||
extern void iommu_devnode_init_iSeries(struct device_node *dn);
|
||||
|
||||
/* Get table parameters from HV */
|
||||
extern void iommu_table_getparms_iSeries(unsigned long busno,
|
||||
unsigned char slotno, unsigned char virtbus,
|
||||
struct iommu_table *tbl);
|
||||
|
||||
#endif /* _PLATFORMS_ISERIES_IOMMU_H */
|
@ -48,6 +48,8 @@
|
||||
extern void iSeries_smp_message_recv(struct pt_regs *);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
|
||||
enum pci_event_type {
|
||||
pe_bus_created = 0, /* PHB has been created */
|
||||
pe_bus_error = 1, /* PHB has failed */
|
||||
@ -147,20 +149,11 @@ static void int_received(struct pci_event *event, struct pt_regs *regs)
|
||||
static void pci_event_handler(struct HvLpEvent *event, struct pt_regs *regs)
|
||||
{
|
||||
if (event && (event->xType == HvLpEvent_Type_PciIo)) {
|
||||
switch (event->xFlags.xFunction) {
|
||||
case HvLpEvent_Function_Int:
|
||||
if (hvlpevent_is_int(event))
|
||||
int_received((struct pci_event *)event, regs);
|
||||
break;
|
||||
case HvLpEvent_Function_Ack:
|
||||
else
|
||||
printk(KERN_ERR
|
||||
"pci_event_handler: unexpected ack received\n");
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR
|
||||
"pci_event_handler: unexpected event function %d\n",
|
||||
(int)event->xFlags.xFunction);
|
||||
break;
|
||||
}
|
||||
} else if (event)
|
||||
printk(KERN_ERR
|
||||
"pci_event_handler: Unrecognized PCI event type 0x%x\n",
|
||||
@ -334,6 +327,8 @@ int __init iSeries_allocate_IRQ(HvBusNumber bus,
|
||||
return virtirq;
|
||||
}
|
||||
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
/*
|
||||
* Get the next pending IRQ.
|
||||
*/
|
||||
@ -353,6 +348,7 @@ int iSeries_get_irq(struct pt_regs *regs)
|
||||
if (hvlpevent_is_pending())
|
||||
process_hvlpevents(regs);
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
if (num_pending_irqs) {
|
||||
spin_lock(&pending_irqs_lock);
|
||||
for (irq = 0; irq < NR_IRQS; irq++) {
|
||||
@ -366,6 +362,7 @@ int iSeries_get_irq(struct pt_regs *regs)
|
||||
if (irq >= NR_IRQS)
|
||||
irq = -2;
|
||||
}
|
||||
#endif
|
||||
|
||||
return irq;
|
||||
}
|
||||
|
@ -93,10 +93,7 @@ struct ItLpNaca itLpNaca = {
|
||||
.xPirEnvironMode = 0, /* Piranha stuff */
|
||||
.xPirConsoleMode = 0,
|
||||
.xPirDasdMode = 0,
|
||||
.xLparInstalled = 0,
|
||||
.xSysPartitioned = 0,
|
||||
.xHwSyncedTBs = 0,
|
||||
.xIntProcUtilHmt = 0,
|
||||
.flags = 0,
|
||||
.xSpVpdFormat = 0,
|
||||
.xIntProcRatio = 0,
|
||||
.xPlicVrmIndex = 0, /* VRM index of PLIC */
|
||||
|
@ -53,7 +53,7 @@ static struct HvLpEvent * get_next_hvlpevent(void)
|
||||
struct HvLpEvent * event;
|
||||
event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr;
|
||||
|
||||
if (event->xFlags.xValid) {
|
||||
if (hvlpevent_is_valid(event)) {
|
||||
/* rmb() needed only for weakly consistent machines (regatta) */
|
||||
rmb();
|
||||
/* Set pointer to next potential event */
|
||||
@ -84,7 +84,7 @@ int hvlpevent_is_pending(void)
|
||||
|
||||
next_event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr;
|
||||
|
||||
return next_event->xFlags.xValid |
|
||||
return hvlpevent_is_valid(next_event) ||
|
||||
hvlpevent_queue.xPlicOverflowIntPending;
|
||||
}
|
||||
|
||||
@ -101,18 +101,18 @@ static void hvlpevent_clear_valid(struct HvLpEvent * event)
|
||||
switch (extra) {
|
||||
case 3:
|
||||
tmp = (struct HvLpEvent*)((char*)event + 3 * LpEventAlign);
|
||||
tmp->xFlags.xValid = 0;
|
||||
hvlpevent_invalidate(tmp);
|
||||
case 2:
|
||||
tmp = (struct HvLpEvent*)((char*)event + 2 * LpEventAlign);
|
||||
tmp->xFlags.xValid = 0;
|
||||
hvlpevent_invalidate(tmp);
|
||||
case 1:
|
||||
tmp = (struct HvLpEvent*)((char*)event + 1 * LpEventAlign);
|
||||
tmp->xFlags.xValid = 0;
|
||||
hvlpevent_invalidate(tmp);
|
||||
}
|
||||
|
||||
mb();
|
||||
|
||||
event->xFlags.xValid = 0;
|
||||
hvlpevent_invalidate(event);
|
||||
}
|
||||
|
||||
void process_hvlpevents(struct pt_regs *regs)
|
||||
|
@ -251,10 +251,7 @@ static struct pending_event *new_pending_event(void)
|
||||
}
|
||||
memset(ev, 0, sizeof(struct pending_event));
|
||||
hev = &ev->event.hp_lp_event;
|
||||
hev->xFlags.xValid = 1;
|
||||
hev->xFlags.xAckType = HvLpEvent_AckType_ImmediateAck;
|
||||
hev->xFlags.xAckInd = HvLpEvent_AckInd_DoAck;
|
||||
hev->xFlags.xFunction = HvLpEvent_Function_Int;
|
||||
hev->flags = HV_LP_EVENT_VALID | HV_LP_EVENT_DO_ACK | HV_LP_EVENT_INT;
|
||||
hev->xType = HvLpEvent_Type_MachineFac;
|
||||
hev->xSourceLp = HvLpConfig_getLpIndex();
|
||||
hev->xTargetLp = primary_lp;
|
||||
@ -518,17 +515,10 @@ static void handle_ack(struct io_mf_lp_event *event)
|
||||
static void hv_handler(struct HvLpEvent *event, struct pt_regs *regs)
|
||||
{
|
||||
if ((event != NULL) && (event->xType == HvLpEvent_Type_MachineFac)) {
|
||||
switch(event->xFlags.xFunction) {
|
||||
case HvLpEvent_Function_Ack:
|
||||
if (hvlpevent_is_ack(event))
|
||||
handle_ack((struct io_mf_lp_event *)event);
|
||||
break;
|
||||
case HvLpEvent_Function_Int:
|
||||
else
|
||||
handle_int((struct io_mf_lp_event *)event);
|
||||
break;
|
||||
default:
|
||||
printk(KERN_ERR "mf.c: non ack/int event received\n");
|
||||
break;
|
||||
}
|
||||
} else
|
||||
printk(KERN_ERR "mf.c: alien event received\n");
|
||||
}
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "irq.h"
|
||||
#include "pci.h"
|
||||
#include "call_pci.h"
|
||||
#include "iommu.h"
|
||||
|
||||
extern unsigned long io_page_mask;
|
||||
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include <asm/iseries/hv_lp_config.h>
|
||||
#include <asm/iseries/hv_call_xm.h>
|
||||
|
||||
#include "iommu.h"
|
||||
|
||||
struct device *iSeries_vio_dev = &vio_bus_device.dev;
|
||||
EXPORT_SYMBOL(iSeries_vio_dev);
|
||||
|
||||
|
@ -270,7 +270,7 @@ static void handleMonitorEvent(struct HvLpEvent *event)
|
||||
* First see if this is just a normal monitor message from the
|
||||
* other partition
|
||||
*/
|
||||
if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
|
||||
if (hvlpevent_is_int(event)) {
|
||||
remoteLp = event->xSourceLp;
|
||||
if (!viopathStatus[remoteLp].isActive)
|
||||
sendMonMsg(remoteLp);
|
||||
@ -331,13 +331,12 @@ static void handleConfig(struct HvLpEvent *event)
|
||||
{
|
||||
if (!event)
|
||||
return;
|
||||
if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
|
||||
if (hvlpevent_is_int(event)) {
|
||||
printk(VIOPATH_KERN_WARN
|
||||
"unexpected config request from partition %d",
|
||||
event->xSourceLp);
|
||||
|
||||
if ((event->xFlags.xFunction == HvLpEvent_Function_Int) &&
|
||||
(event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck)) {
|
||||
if (hvlpevent_need_ack(event)) {
|
||||
event->xRc = HvLpEvent_Rc_InvalidSubtype;
|
||||
HvCallEvent_ackLpEvent(event);
|
||||
}
|
||||
@ -377,7 +376,7 @@ static void vio_handleEvent(struct HvLpEvent *event, struct pt_regs *regs)
|
||||
int subtype = (event->xSubtype & VIOMAJOR_SUBTYPE_MASK)
|
||||
>> VIOMAJOR_SUBTYPE_SHIFT;
|
||||
|
||||
if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
|
||||
if (hvlpevent_is_int(event)) {
|
||||
remoteLp = event->xSourceLp;
|
||||
/*
|
||||
* The isActive is checked because if the hosting partition
|
||||
@ -436,8 +435,7 @@ static void vio_handleEvent(struct HvLpEvent *event, struct pt_regs *regs)
|
||||
"unexpected virtual io event subtype %d from partition %d\n",
|
||||
event->xSubtype, remoteLp);
|
||||
/* No handler. Ack if necessary */
|
||||
if ((event->xFlags.xFunction == HvLpEvent_Function_Int) &&
|
||||
(event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck)) {
|
||||
if (hvlpevent_is_int(event) && hvlpevent_need_ack(event)) {
|
||||
event->xRc = HvLpEvent_Rc_InvalidSubtype;
|
||||
HvCallEvent_ackLpEvent(event);
|
||||
}
|
||||
|
@ -278,7 +278,7 @@ static void __init l2cr_init(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
void __init pmac_setup_arch(void)
|
||||
static void __init pmac_setup_arch(void)
|
||||
{
|
||||
struct device_node *cpu, *ic;
|
||||
int *fp;
|
||||
|
@ -208,10 +208,11 @@ static void __eeh_mark_slot (struct device_node *dn, int mode_flag)
|
||||
{
|
||||
while (dn) {
|
||||
if (PCI_DN(dn)) {
|
||||
PCI_DN(dn)->eeh_mode |= mode_flag;
|
||||
|
||||
/* Mark the pci device driver too */
|
||||
struct pci_dev *dev = PCI_DN(dn)->pcidev;
|
||||
|
||||
PCI_DN(dn)->eeh_mode |= mode_flag;
|
||||
|
||||
if (dev && dev->driver)
|
||||
dev->error_state = pci_channel_io_frozen;
|
||||
|
||||
|
@ -40,7 +40,7 @@ MODULE_VERSION(HVCS_ARCH_VERSION);
|
||||
* functions aren't performance sensitive, so this conversion isn't an
|
||||
* issue.
|
||||
*/
|
||||
int hvcs_convert(long to_convert)
|
||||
static int hvcs_convert(long to_convert)
|
||||
{
|
||||
switch (to_convert) {
|
||||
case H_Success:
|
||||
@ -91,7 +91,7 @@ int hvcs_free_partner_info(struct list_head *head)
|
||||
EXPORT_SYMBOL(hvcs_free_partner_info);
|
||||
|
||||
/* Helper function for hvcs_get_partner_info */
|
||||
int hvcs_next_partner(uint32_t unit_address,
|
||||
static int hvcs_next_partner(uint32_t unit_address,
|
||||
unsigned long last_p_partition_ID,
|
||||
unsigned long last_p_unit_address, unsigned long *pi_buff)
|
||||
|
||||
|
@ -51,8 +51,6 @@
|
||||
|
||||
#define DBG(fmt...)
|
||||
|
||||
extern int is_python(struct device_node *);
|
||||
|
||||
static void tce_build_pSeries(struct iommu_table *tbl, long index,
|
||||
long npages, unsigned long uaddr,
|
||||
enum dma_data_direction direction)
|
||||
|
@ -192,7 +192,7 @@ struct file_operations scanlog_fops = {
|
||||
.release = scanlog_release,
|
||||
};
|
||||
|
||||
int __init scanlog_init(void)
|
||||
static int __init scanlog_init(void)
|
||||
{
|
||||
struct proc_dir_entry *ent;
|
||||
|
||||
@ -222,7 +222,7 @@ int __init scanlog_init(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void __exit scanlog_cleanup(void)
|
||||
static void __exit scanlog_cleanup(void)
|
||||
{
|
||||
if (proc_ppc64_scan_log_dump) {
|
||||
kfree(proc_ppc64_scan_log_dump->data);
|
||||
|
@ -86,7 +86,7 @@ static void pseries_dedicated_idle(void);
|
||||
|
||||
struct mpic *pSeries_mpic;
|
||||
|
||||
void pSeries_show_cpuinfo(struct seq_file *m)
|
||||
static void pSeries_show_cpuinfo(struct seq_file *m)
|
||||
{
|
||||
struct device_node *root;
|
||||
const char *model = "";
|
||||
|
@ -93,7 +93,7 @@ static int query_cpu_stopped(unsigned int pcpu)
|
||||
return cpu_status;
|
||||
}
|
||||
|
||||
int pSeries_cpu_disable(void)
|
||||
static int pSeries_cpu_disable(void)
|
||||
{
|
||||
int cpu = smp_processor_id();
|
||||
|
||||
@ -109,7 +109,7 @@ int pSeries_cpu_disable(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pSeries_cpu_die(unsigned int cpu)
|
||||
static void pSeries_cpu_die(unsigned int cpu)
|
||||
{
|
||||
int tries;
|
||||
int cpu_status;
|
||||
|
@ -381,7 +381,7 @@ int xics_get_irq(struct pt_regs *regs)
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
irqreturn_t xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
|
||||
static irqreturn_t xics_ipi_action(int irq, void *dev_id, struct pt_regs *regs)
|
||||
{
|
||||
int cpu = smp_processor_id();
|
||||
|
||||
|
@ -139,7 +139,6 @@ static void dart_build(struct iommu_table *tbl, long index,
|
||||
|
||||
*(dp++) = DARTMAP_VALID | (rpn & DARTMAP_RPNMASK);
|
||||
|
||||
rpn++;
|
||||
uaddr += DART_PAGE_SIZE;
|
||||
}
|
||||
|
||||
|
@ -311,7 +311,7 @@ static void release_output_lock(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
int xmon_core(struct pt_regs *regs, int fromipi)
|
||||
static int xmon_core(struct pt_regs *regs, int fromipi)
|
||||
{
|
||||
int cmd = 0;
|
||||
unsigned long msr;
|
||||
@ -528,7 +528,7 @@ xmon_irq(int irq, void *d, struct pt_regs *regs)
|
||||
return IRQ_HANDLED;
|
||||
}
|
||||
|
||||
int xmon_bpt(struct pt_regs *regs)
|
||||
static int xmon_bpt(struct pt_regs *regs)
|
||||
{
|
||||
struct bpt *bp;
|
||||
unsigned long offset;
|
||||
@ -554,7 +554,7 @@ int xmon_bpt(struct pt_regs *regs)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int xmon_sstep(struct pt_regs *regs)
|
||||
static int xmon_sstep(struct pt_regs *regs)
|
||||
{
|
||||
if (user_mode(regs))
|
||||
return 0;
|
||||
@ -562,7 +562,7 @@ int xmon_sstep(struct pt_regs *regs)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int xmon_dabr_match(struct pt_regs *regs)
|
||||
static int xmon_dabr_match(struct pt_regs *regs)
|
||||
{
|
||||
if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
|
||||
return 0;
|
||||
@ -572,7 +572,7 @@ int xmon_dabr_match(struct pt_regs *regs)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int xmon_iabr_match(struct pt_regs *regs)
|
||||
static int xmon_iabr_match(struct pt_regs *regs)
|
||||
{
|
||||
if ((regs->msr & (MSR_IR|MSR_PR|MSR_SF)) != (MSR_IR|MSR_SF))
|
||||
return 0;
|
||||
@ -582,7 +582,7 @@ int xmon_iabr_match(struct pt_regs *regs)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int xmon_ipi(struct pt_regs *regs)
|
||||
static int xmon_ipi(struct pt_regs *regs)
|
||||
{
|
||||
#ifdef CONFIG_SMP
|
||||
if (in_xmon && !cpu_isset(smp_processor_id(), cpus_in_xmon))
|
||||
@ -591,7 +591,7 @@ int xmon_ipi(struct pt_regs *regs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int xmon_fault_handler(struct pt_regs *regs)
|
||||
static int xmon_fault_handler(struct pt_regs *regs)
|
||||
{
|
||||
struct bpt *bp;
|
||||
unsigned long offset;
|
||||
|
@ -13,7 +13,6 @@ extra-$(CONFIG_POWER4) += idle_power4.o
|
||||
extra-y += vmlinux.lds
|
||||
|
||||
obj-y := entry.o traps.o idle.o time.o misc.o \
|
||||
process.o \
|
||||
setup.o \
|
||||
ppc_htab.o
|
||||
obj-$(CONFIG_6xx) += l2cr.o cpu_setup_6xx.o
|
||||
|
@ -1,851 +0,0 @@
|
||||
/*
|
||||
* arch/ppc/kernel/process.c
|
||||
*
|
||||
* Derived from "arch/i386/kernel/process.c"
|
||||
* Copyright (C) 1995 Linus Torvalds
|
||||
*
|
||||
* Updated and modified by Cort Dougan (cort@cs.nmt.edu) and
|
||||
* Paul Mackerras (paulus@cs.anu.edu.au)
|
||||
*
|
||||
* PowerPC version
|
||||
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
|
||||
*
|
||||
* 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/config.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/smp_lock.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/user.h>
|
||||
#include <linux/elf.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/prctl.h>
|
||||
#include <linux/init_task.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kallsyms.h>
|
||||
#include <linux/mqueue.h>
|
||||
#include <linux/hardirq.h>
|
||||
|
||||
#include <asm/pgtable.h>
|
||||
#include <asm/uaccess.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/processor.h>
|
||||
#include <asm/mmu.h>
|
||||
#include <asm/prom.h>
|
||||
|
||||
extern unsigned long _get_SP(void);
|
||||
|
||||
struct task_struct *last_task_used_math = NULL;
|
||||
struct task_struct *last_task_used_altivec = NULL;
|
||||
struct task_struct *last_task_used_spe = NULL;
|
||||
|
||||
static struct fs_struct init_fs = INIT_FS;
|
||||
static struct files_struct init_files = INIT_FILES;
|
||||
static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
|
||||
static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
|
||||
struct mm_struct init_mm = INIT_MM(init_mm);
|
||||
EXPORT_SYMBOL(init_mm);
|
||||
|
||||
/* this is 8kB-aligned so we can get to the thread_info struct
|
||||
at the base of it from the stack pointer with 1 integer instruction. */
|
||||
union thread_union init_thread_union
|
||||
__attribute__((__section__(".data.init_task"))) =
|
||||
{ INIT_THREAD_INFO(init_task) };
|
||||
|
||||
/* initial task structure */
|
||||
struct task_struct init_task = INIT_TASK(init_task);
|
||||
EXPORT_SYMBOL(init_task);
|
||||
|
||||
/* only used to get secondary processor up */
|
||||
struct task_struct *current_set[NR_CPUS] = {&init_task, };
|
||||
|
||||
#undef SHOW_TASK_SWITCHES
|
||||
#undef CHECK_STACK
|
||||
|
||||
#if defined(CHECK_STACK)
|
||||
unsigned long
|
||||
kernel_stack_top(struct task_struct *tsk)
|
||||
{
|
||||
return ((unsigned long)tsk) + sizeof(union task_union);
|
||||
}
|
||||
|
||||
unsigned long
|
||||
task_top(struct task_struct *tsk)
|
||||
{
|
||||
return ((unsigned long)tsk) + sizeof(struct thread_info);
|
||||
}
|
||||
|
||||
/* check to make sure the kernel stack is healthy */
|
||||
int check_stack(struct task_struct *tsk)
|
||||
{
|
||||
unsigned long stack_top = kernel_stack_top(tsk);
|
||||
unsigned long tsk_top = task_top(tsk);
|
||||
int ret = 0;
|
||||
|
||||
#if 0
|
||||
/* check thread magic */
|
||||
if ( tsk->thread.magic != THREAD_MAGIC )
|
||||
{
|
||||
ret |= 1;
|
||||
printk("thread.magic bad: %08x\n", tsk->thread.magic);
|
||||
}
|
||||
#endif
|
||||
|
||||
if ( !tsk )
|
||||
printk("check_stack(): tsk bad tsk %p\n",tsk);
|
||||
|
||||
/* check if stored ksp is bad */
|
||||
if ( (tsk->thread.ksp > stack_top) || (tsk->thread.ksp < tsk_top) )
|
||||
{
|
||||
printk("stack out of bounds: %s/%d\n"
|
||||
" tsk_top %08lx ksp %08lx stack_top %08lx\n",
|
||||
tsk->comm,tsk->pid,
|
||||
tsk_top, tsk->thread.ksp, stack_top);
|
||||
ret |= 2;
|
||||
}
|
||||
|
||||
/* check if stack ptr RIGHT NOW is bad */
|
||||
if ( (tsk == current) && ((_get_SP() > stack_top ) || (_get_SP() < tsk_top)) )
|
||||
{
|
||||
printk("current stack ptr out of bounds: %s/%d\n"
|
||||
" tsk_top %08lx sp %08lx stack_top %08lx\n",
|
||||
current->comm,current->pid,
|
||||
tsk_top, _get_SP(), stack_top);
|
||||
ret |= 4;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* check amount of free stack */
|
||||
for ( i = (unsigned long *)task_top(tsk) ; i < kernel_stack_top(tsk) ; i++ )
|
||||
{
|
||||
if ( !i )
|
||||
printk("check_stack(): i = %p\n", i);
|
||||
if ( *i != 0 )
|
||||
{
|
||||
/* only notify if it's less than 900 bytes */
|
||||
if ( (i - (unsigned long *)task_top(tsk)) < 900 )
|
||||
printk("%d bytes free on stack\n",
|
||||
i - task_top(tsk));
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ret)
|
||||
{
|
||||
panic("bad kernel stack");
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
#endif /* defined(CHECK_STACK) */
|
||||
|
||||
/*
|
||||
* Make sure the floating-point register state in the
|
||||
* the thread_struct is up to date for task tsk.
|
||||
*/
|
||||
void flush_fp_to_thread(struct task_struct *tsk)
|
||||
{
|
||||
if (tsk->thread.regs) {
|
||||
/*
|
||||
* We need to disable preemption here because if we didn't,
|
||||
* another process could get scheduled after the regs->msr
|
||||
* test but before we have finished saving the FP registers
|
||||
* to the thread_struct. That process could take over the
|
||||
* FPU, and then when we get scheduled again we would store
|
||||
* bogus values for the remaining FP registers.
|
||||
*/
|
||||
preempt_disable();
|
||||
if (tsk->thread.regs->msr & MSR_FP) {
|
||||
#ifdef CONFIG_SMP
|
||||
/*
|
||||
* This should only ever be called for current or
|
||||
* for a stopped child process. Since we save away
|
||||
* the FP register state on context switch on SMP,
|
||||
* there is something wrong if a stopped child appears
|
||||
* to still have its FP state in the CPU registers.
|
||||
*/
|
||||
BUG_ON(tsk != current);
|
||||
#endif
|
||||
giveup_fpu(current);
|
||||
}
|
||||
preempt_enable();
|
||||
}
|
||||
}
|
||||
|
||||
void enable_kernel_fp(void)
|
||||
{
|
||||
WARN_ON(preemptible());
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
if (current->thread.regs && (current->thread.regs->msr & MSR_FP))
|
||||
giveup_fpu(current);
|
||||
else
|
||||
giveup_fpu(NULL); /* just enables FP for kernel */
|
||||
#else
|
||||
giveup_fpu(last_task_used_math);
|
||||
#endif /* CONFIG_SMP */
|
||||
}
|
||||
EXPORT_SYMBOL(enable_kernel_fp);
|
||||
|
||||
int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs)
|
||||
{
|
||||
preempt_disable();
|
||||
if (tsk->thread.regs && (tsk->thread.regs->msr & MSR_FP))
|
||||
giveup_fpu(tsk);
|
||||
preempt_enable();
|
||||
memcpy(fpregs, &tsk->thread.fpr[0], sizeof(*fpregs));
|
||||
return 1;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ALTIVEC
|
||||
void enable_kernel_altivec(void)
|
||||
{
|
||||
WARN_ON(preemptible());
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
if (current->thread.regs && (current->thread.regs->msr & MSR_VEC))
|
||||
giveup_altivec(current);
|
||||
else
|
||||
giveup_altivec(NULL); /* just enable AltiVec for kernel - force */
|
||||
#else
|
||||
giveup_altivec(last_task_used_altivec);
|
||||
#endif /* __SMP __ */
|
||||
}
|
||||
EXPORT_SYMBOL(enable_kernel_altivec);
|
||||
|
||||
/*
|
||||
* Make sure the VMX/Altivec register state in the
|
||||
* the thread_struct is up to date for task tsk.
|
||||
*/
|
||||
void flush_altivec_to_thread(struct task_struct *tsk)
|
||||
{
|
||||
if (tsk->thread.regs) {
|
||||
preempt_disable();
|
||||
if (tsk->thread.regs->msr & MSR_VEC) {
|
||||
#ifdef CONFIG_SMP
|
||||
BUG_ON(tsk != current);
|
||||
#endif
|
||||
giveup_altivec(current);
|
||||
}
|
||||
preempt_enable();
|
||||
}
|
||||
}
|
||||
|
||||
int dump_altivec(struct pt_regs *regs, elf_vrregset_t *vrregs)
|
||||
{
|
||||
if (regs->msr & MSR_VEC)
|
||||
giveup_altivec(current);
|
||||
memcpy(vrregs, ¤t->thread.vr[0], sizeof(*vrregs));
|
||||
return 1;
|
||||
}
|
||||
#endif /* CONFIG_ALTIVEC */
|
||||
|
||||
#ifdef CONFIG_SPE
|
||||
void
|
||||
enable_kernel_spe(void)
|
||||
{
|
||||
WARN_ON(preemptible());
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
if (current->thread.regs && (current->thread.regs->msr & MSR_SPE))
|
||||
giveup_spe(current);
|
||||
else
|
||||
giveup_spe(NULL); /* just enable SPE for kernel - force */
|
||||
#else
|
||||
giveup_spe(last_task_used_spe);
|
||||
#endif /* __SMP __ */
|
||||
}
|
||||
EXPORT_SYMBOL(enable_kernel_spe);
|
||||
|
||||
void flush_spe_to_thread(struct task_struct *tsk)
|
||||
{
|
||||
if (tsk->thread.regs) {
|
||||
preempt_disable();
|
||||
if (tsk->thread.regs->msr & MSR_SPE) {
|
||||
#ifdef CONFIG_SMP
|
||||
BUG_ON(tsk != current);
|
||||
#endif
|
||||
giveup_spe(current);
|
||||
}
|
||||
preempt_enable();
|
||||
}
|
||||
}
|
||||
|
||||
int dump_spe(struct pt_regs *regs, elf_vrregset_t *evrregs)
|
||||
{
|
||||
if (regs->msr & MSR_SPE)
|
||||
giveup_spe(current);
|
||||
/* We copy u32 evr[32] + u64 acc + u32 spefscr -> 35 */
|
||||
memcpy(evrregs, ¤t->thread.evr[0], sizeof(u32) * 35);
|
||||
return 1;
|
||||
}
|
||||
#endif /* CONFIG_SPE */
|
||||
|
||||
struct task_struct *__switch_to(struct task_struct *prev,
|
||||
struct task_struct *new)
|
||||
{
|
||||
struct thread_struct *new_thread, *old_thread;
|
||||
unsigned long s;
|
||||
struct task_struct *last;
|
||||
|
||||
local_irq_save(s);
|
||||
#ifdef CHECK_STACK
|
||||
check_stack(prev);
|
||||
check_stack(new);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
/* avoid complexity of lazy save/restore of fpu
|
||||
* by just saving it every time we switch out if
|
||||
* this task used the fpu during the last quantum.
|
||||
*
|
||||
* If it tries to use the fpu again, it'll trap and
|
||||
* reload its fp regs. So we don't have to do a restore
|
||||
* every switch, just a save.
|
||||
* -- Cort
|
||||
*/
|
||||
if (prev->thread.regs && (prev->thread.regs->msr & MSR_FP))
|
||||
giveup_fpu(prev);
|
||||
#ifdef CONFIG_ALTIVEC
|
||||
/*
|
||||
* If the previous thread used altivec in the last quantum
|
||||
* (thus changing altivec regs) then save them.
|
||||
* We used to check the VRSAVE register but not all apps
|
||||
* set it, so we don't rely on it now (and in fact we need
|
||||
* to save & restore VSCR even if VRSAVE == 0). -- paulus
|
||||
*
|
||||
* On SMP we always save/restore altivec regs just to avoid the
|
||||
* complexity of changing processors.
|
||||
* -- Cort
|
||||
*/
|
||||
if ((prev->thread.regs && (prev->thread.regs->msr & MSR_VEC)))
|
||||
giveup_altivec(prev);
|
||||
#endif /* CONFIG_ALTIVEC */
|
||||
#ifdef CONFIG_SPE
|
||||
/*
|
||||
* If the previous thread used spe in the last quantum
|
||||
* (thus changing spe regs) then save them.
|
||||
*
|
||||
* On SMP we always save/restore spe regs just to avoid the
|
||||
* complexity of changing processors.
|
||||
*/
|
||||
if ((prev->thread.regs && (prev->thread.regs->msr & MSR_SPE)))
|
||||
giveup_spe(prev);
|
||||
#endif /* CONFIG_SPE */
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
#ifdef CONFIG_ALTIVEC
|
||||
/* Avoid the trap. On smp this this never happens since
|
||||
* we don't set last_task_used_altivec -- Cort
|
||||
*/
|
||||
if (new->thread.regs && last_task_used_altivec == new)
|
||||
new->thread.regs->msr |= MSR_VEC;
|
||||
#endif
|
||||
#ifdef CONFIG_SPE
|
||||
/* Avoid the trap. On smp this this never happens since
|
||||
* we don't set last_task_used_spe
|
||||
*/
|
||||
if (new->thread.regs && last_task_used_spe == new)
|
||||
new->thread.regs->msr |= MSR_SPE;
|
||||
#endif /* CONFIG_SPE */
|
||||
new_thread = &new->thread;
|
||||
old_thread = ¤t->thread;
|
||||
last = _switch(old_thread, new_thread);
|
||||
local_irq_restore(s);
|
||||
return last;
|
||||
}
|
||||
|
||||
void show_regs(struct pt_regs * regs)
|
||||
{
|
||||
int i, trap;
|
||||
|
||||
printk("NIP: %08lX LR: %08lX SP: %08lX REGS: %p TRAP: %04lx %s\n",
|
||||
regs->nip, regs->link, regs->gpr[1], regs, regs->trap,
|
||||
print_tainted());
|
||||
printk("MSR: %08lx EE: %01x PR: %01x FP: %01x ME: %01x IR/DR: %01x%01x\n",
|
||||
regs->msr, regs->msr&MSR_EE ? 1 : 0, regs->msr&MSR_PR ? 1 : 0,
|
||||
regs->msr & MSR_FP ? 1 : 0,regs->msr&MSR_ME ? 1 : 0,
|
||||
regs->msr&MSR_IR ? 1 : 0,
|
||||
regs->msr&MSR_DR ? 1 : 0);
|
||||
trap = TRAP(regs);
|
||||
if (trap == 0x300 || trap == 0x600)
|
||||
printk("DAR: %08lX, DSISR: %08lX\n", regs->dar, regs->dsisr);
|
||||
printk("TASK = %p[%d] '%s' THREAD: %p\n",
|
||||
current, current->pid, current->comm, task_thread_info(current));
|
||||
printk("Last syscall: %ld ", current->thread.last_syscall);
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
printk(" CPU: %d", smp_processor_id());
|
||||
#endif /* CONFIG_SMP */
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
long r;
|
||||
if ((i % 8) == 0)
|
||||
printk("\n" KERN_INFO "GPR%02d: ", i);
|
||||
if (__get_user(r, ®s->gpr[i]))
|
||||
break;
|
||||
printk("%08lX ", r);
|
||||
if (i == 12 && !FULL_REGS(regs))
|
||||
break;
|
||||
}
|
||||
printk("\n");
|
||||
#ifdef CONFIG_KALLSYMS
|
||||
/*
|
||||
* Lookup NIP late so we have the best change of getting the
|
||||
* above info out without failing
|
||||
*/
|
||||
printk("NIP [%08lx] ", regs->nip);
|
||||
print_symbol("%s\n", regs->nip);
|
||||
printk("LR [%08lx] ", regs->link);
|
||||
print_symbol("%s\n", regs->link);
|
||||
#endif
|
||||
show_stack(current, (unsigned long *) regs->gpr[1]);
|
||||
}
|
||||
|
||||
void exit_thread(void)
|
||||
{
|
||||
preempt_disable();
|
||||
if (last_task_used_math == current)
|
||||
last_task_used_math = NULL;
|
||||
if (last_task_used_altivec == current)
|
||||
last_task_used_altivec = NULL;
|
||||
#ifdef CONFIG_SPE
|
||||
if (last_task_used_spe == current)
|
||||
last_task_used_spe = NULL;
|
||||
#endif
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
void flush_thread(void)
|
||||
{
|
||||
preempt_disable();
|
||||
if (last_task_used_math == current)
|
||||
last_task_used_math = NULL;
|
||||
if (last_task_used_altivec == current)
|
||||
last_task_used_altivec = NULL;
|
||||
#ifdef CONFIG_SPE
|
||||
if (last_task_used_spe == current)
|
||||
last_task_used_spe = NULL;
|
||||
#endif
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
void
|
||||
release_thread(struct task_struct *t)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* This gets called before we allocate a new thread and copy
|
||||
* the current task into it.
|
||||
*/
|
||||
void prepare_to_copy(struct task_struct *tsk)
|
||||
{
|
||||
struct pt_regs *regs = tsk->thread.regs;
|
||||
|
||||
if (regs == NULL)
|
||||
return;
|
||||
preempt_disable();
|
||||
if (regs->msr & MSR_FP)
|
||||
giveup_fpu(current);
|
||||
#ifdef CONFIG_ALTIVEC
|
||||
if (regs->msr & MSR_VEC)
|
||||
giveup_altivec(current);
|
||||
#endif /* CONFIG_ALTIVEC */
|
||||
#ifdef CONFIG_SPE
|
||||
if (regs->msr & MSR_SPE)
|
||||
giveup_spe(current);
|
||||
#endif /* CONFIG_SPE */
|
||||
preempt_enable();
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy a thread..
|
||||
*/
|
||||
int
|
||||
copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
|
||||
unsigned long unused,
|
||||
struct task_struct *p, struct pt_regs *regs)
|
||||
{
|
||||
struct pt_regs *childregs, *kregs;
|
||||
extern void ret_from_fork(void);
|
||||
unsigned long sp = (unsigned long)task_stack_page(p) + THREAD_SIZE;
|
||||
unsigned long childframe;
|
||||
|
||||
CHECK_FULL_REGS(regs);
|
||||
/* Copy registers */
|
||||
sp -= sizeof(struct pt_regs);
|
||||
childregs = (struct pt_regs *) sp;
|
||||
*childregs = *regs;
|
||||
if ((childregs->msr & MSR_PR) == 0) {
|
||||
/* for kernel thread, set `current' and stackptr in new task */
|
||||
childregs->gpr[1] = sp + sizeof(struct pt_regs);
|
||||
childregs->gpr[2] = (unsigned long) p;
|
||||
p->thread.regs = NULL; /* no user register state */
|
||||
} else {
|
||||
childregs->gpr[1] = usp;
|
||||
p->thread.regs = childregs;
|
||||
if (clone_flags & CLONE_SETTLS)
|
||||
childregs->gpr[2] = childregs->gpr[6];
|
||||
}
|
||||
childregs->gpr[3] = 0; /* Result from fork() */
|
||||
sp -= STACK_FRAME_OVERHEAD;
|
||||
childframe = sp;
|
||||
|
||||
/*
|
||||
* The way this works is that at some point in the future
|
||||
* some task will call _switch to switch to the new task.
|
||||
* That will pop off the stack frame created below and start
|
||||
* the new task running at ret_from_fork. The new task will
|
||||
* do some house keeping and then return from the fork or clone
|
||||
* system call, using the stack frame created above.
|
||||
*/
|
||||
sp -= sizeof(struct pt_regs);
|
||||
kregs = (struct pt_regs *) sp;
|
||||
sp -= STACK_FRAME_OVERHEAD;
|
||||
p->thread.ksp = sp;
|
||||
kregs->nip = (unsigned long)ret_from_fork;
|
||||
|
||||
p->thread.last_syscall = -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up a thread for executing a new program
|
||||
*/
|
||||
void start_thread(struct pt_regs *regs, unsigned long nip, unsigned long sp)
|
||||
{
|
||||
set_fs(USER_DS);
|
||||
memset(regs->gpr, 0, sizeof(regs->gpr));
|
||||
regs->ctr = 0;
|
||||
regs->link = 0;
|
||||
regs->xer = 0;
|
||||
regs->ccr = 0;
|
||||
regs->mq = 0;
|
||||
regs->nip = nip;
|
||||
regs->gpr[1] = sp;
|
||||
regs->msr = MSR_USER;
|
||||
preempt_disable();
|
||||
if (last_task_used_math == current)
|
||||
last_task_used_math = NULL;
|
||||
if (last_task_used_altivec == current)
|
||||
last_task_used_altivec = NULL;
|
||||
#ifdef CONFIG_SPE
|
||||
if (last_task_used_spe == current)
|
||||
last_task_used_spe = NULL;
|
||||
#endif
|
||||
preempt_enable();
|
||||
memset(current->thread.fpr, 0, sizeof(current->thread.fpr));
|
||||
current->thread.fpscr.val = 0;
|
||||
#ifdef CONFIG_ALTIVEC
|
||||
memset(current->thread.vr, 0, sizeof(current->thread.vr));
|
||||
memset(¤t->thread.vscr, 0, sizeof(current->thread.vscr));
|
||||
current->thread.vrsave = 0;
|
||||
current->thread.used_vr = 0;
|
||||
#endif /* CONFIG_ALTIVEC */
|
||||
#ifdef CONFIG_SPE
|
||||
memset(current->thread.evr, 0, sizeof(current->thread.evr));
|
||||
current->thread.acc = 0;
|
||||
current->thread.spefscr = 0;
|
||||
current->thread.used_spe = 0;
|
||||
#endif /* CONFIG_SPE */
|
||||
}
|
||||
|
||||
#define PR_FP_ALL_EXCEPT (PR_FP_EXC_DIV | PR_FP_EXC_OVF | PR_FP_EXC_UND \
|
||||
| PR_FP_EXC_RES | PR_FP_EXC_INV)
|
||||
|
||||
int set_fpexc_mode(struct task_struct *tsk, unsigned int val)
|
||||
{
|
||||
struct pt_regs *regs = tsk->thread.regs;
|
||||
|
||||
/* This is a bit hairy. If we are an SPE enabled processor
|
||||
* (have embedded fp) we store the IEEE exception enable flags in
|
||||
* fpexc_mode. fpexc_mode is also used for setting FP exception
|
||||
* mode (asyn, precise, disabled) for 'Classic' FP. */
|
||||
if (val & PR_FP_EXC_SW_ENABLE) {
|
||||
#ifdef CONFIG_SPE
|
||||
tsk->thread.fpexc_mode = val &
|
||||
(PR_FP_EXC_SW_ENABLE | PR_FP_ALL_EXCEPT);
|
||||
#else
|
||||
return -EINVAL;
|
||||
#endif
|
||||
} else {
|
||||
/* on a CONFIG_SPE this does not hurt us. The bits that
|
||||
* __pack_fe01 use do not overlap with bits used for
|
||||
* PR_FP_EXC_SW_ENABLE. Additionally, the MSR[FE0,FE1] bits
|
||||
* on CONFIG_SPE implementations are reserved so writing to
|
||||
* them does not change anything */
|
||||
if (val > PR_FP_EXC_PRECISE)
|
||||
return -EINVAL;
|
||||
tsk->thread.fpexc_mode = __pack_fe01(val);
|
||||
if (regs != NULL && (regs->msr & MSR_FP) != 0)
|
||||
regs->msr = (regs->msr & ~(MSR_FE0|MSR_FE1))
|
||||
| tsk->thread.fpexc_mode;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int get_fpexc_mode(struct task_struct *tsk, unsigned long adr)
|
||||
{
|
||||
unsigned int val;
|
||||
|
||||
if (tsk->thread.fpexc_mode & PR_FP_EXC_SW_ENABLE)
|
||||
#ifdef CONFIG_SPE
|
||||
val = tsk->thread.fpexc_mode;
|
||||
#else
|
||||
return -EINVAL;
|
||||
#endif
|
||||
else
|
||||
val = __unpack_fe01(tsk->thread.fpexc_mode);
|
||||
return put_user(val, (unsigned int __user *) adr);
|
||||
}
|
||||
|
||||
int sys_clone(unsigned long clone_flags, unsigned long usp,
|
||||
int __user *parent_tidp, void __user *child_threadptr,
|
||||
int __user *child_tidp, int p6,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
CHECK_FULL_REGS(regs);
|
||||
if (usp == 0)
|
||||
usp = regs->gpr[1]; /* stack pointer for child */
|
||||
return do_fork(clone_flags, usp, regs, 0, parent_tidp, child_tidp);
|
||||
}
|
||||
|
||||
int sys_fork(unsigned long p1, unsigned long p2, unsigned long p3,
|
||||
unsigned long p4, unsigned long p5, unsigned long p6,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
CHECK_FULL_REGS(regs);
|
||||
return do_fork(SIGCHLD, regs->gpr[1], regs, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
int sys_vfork(unsigned long p1, unsigned long p2, unsigned long p3,
|
||||
unsigned long p4, unsigned long p5, unsigned long p6,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
CHECK_FULL_REGS(regs);
|
||||
return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->gpr[1],
|
||||
regs, 0, NULL, NULL);
|
||||
}
|
||||
|
||||
int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
|
||||
unsigned long a3, unsigned long a4, unsigned long a5,
|
||||
struct pt_regs *regs)
|
||||
{
|
||||
int error;
|
||||
char * filename;
|
||||
|
||||
filename = getname((char __user *) a0);
|
||||
error = PTR_ERR(filename);
|
||||
if (IS_ERR(filename))
|
||||
goto out;
|
||||
preempt_disable();
|
||||
if (regs->msr & MSR_FP)
|
||||
giveup_fpu(current);
|
||||
#ifdef CONFIG_ALTIVEC
|
||||
if (regs->msr & MSR_VEC)
|
||||
giveup_altivec(current);
|
||||
#endif /* CONFIG_ALTIVEC */
|
||||
#ifdef CONFIG_SPE
|
||||
if (regs->msr & MSR_SPE)
|
||||
giveup_spe(current);
|
||||
#endif /* CONFIG_SPE */
|
||||
preempt_enable();
|
||||
error = do_execve(filename, (char __user *__user *) a1,
|
||||
(char __user *__user *) a2, regs);
|
||||
if (error == 0) {
|
||||
task_lock(current);
|
||||
current->ptrace &= ~PT_DTRACE;
|
||||
task_unlock(current);
|
||||
}
|
||||
putname(filename);
|
||||
out:
|
||||
return error;
|
||||
}
|
||||
|
||||
void dump_stack(void)
|
||||
{
|
||||
show_stack(current, NULL);
|
||||
}
|
||||
|
||||
EXPORT_SYMBOL(dump_stack);
|
||||
|
||||
void show_stack(struct task_struct *tsk, unsigned long *stack)
|
||||
{
|
||||
unsigned long sp, stack_top, prev_sp, ret;
|
||||
int count = 0;
|
||||
unsigned long next_exc = 0;
|
||||
struct pt_regs *regs;
|
||||
extern char ret_from_except, ret_from_except_full, ret_from_syscall;
|
||||
|
||||
sp = (unsigned long) stack;
|
||||
if (tsk == NULL)
|
||||
tsk = current;
|
||||
if (sp == 0) {
|
||||
if (tsk == current)
|
||||
asm("mr %0,1" : "=r" (sp));
|
||||
else
|
||||
sp = tsk->thread.ksp;
|
||||
}
|
||||
|
||||
prev_sp = (unsigned long) end_of_stack(tsk);
|
||||
stack_top = (unsigned long) task_stack_page(tsk) + THREAD_SIZE;
|
||||
while (count < 16 && sp > prev_sp && sp < stack_top && (sp & 3) == 0) {
|
||||
if (count == 0) {
|
||||
printk("Call trace:");
|
||||
#ifdef CONFIG_KALLSYMS
|
||||
printk("\n");
|
||||
#endif
|
||||
} else {
|
||||
if (next_exc) {
|
||||
ret = next_exc;
|
||||
next_exc = 0;
|
||||
} else
|
||||
ret = *(unsigned long *)(sp + 4);
|
||||
printk(" [%08lx] ", ret);
|
||||
#ifdef CONFIG_KALLSYMS
|
||||
print_symbol("%s", ret);
|
||||
printk("\n");
|
||||
#endif
|
||||
if (ret == (unsigned long) &ret_from_except
|
||||
|| ret == (unsigned long) &ret_from_except_full
|
||||
|| ret == (unsigned long) &ret_from_syscall) {
|
||||
/* sp + 16 points to an exception frame */
|
||||
regs = (struct pt_regs *) (sp + 16);
|
||||
if (sp + 16 + sizeof(*regs) <= stack_top)
|
||||
next_exc = regs->nip;
|
||||
}
|
||||
}
|
||||
++count;
|
||||
sp = *(unsigned long *)sp;
|
||||
}
|
||||
#ifndef CONFIG_KALLSYMS
|
||||
if (count > 0)
|
||||
printk("\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
/*
|
||||
* Low level print for debugging - Cort
|
||||
*/
|
||||
int __init ll_printk(const char *fmt, ...)
|
||||
{
|
||||
va_list args;
|
||||
char buf[256];
|
||||
int i;
|
||||
|
||||
va_start(args, fmt);
|
||||
i=vsprintf(buf,fmt,args);
|
||||
ll_puts(buf);
|
||||
va_end(args);
|
||||
return i;
|
||||
}
|
||||
|
||||
int lines = 24, cols = 80;
|
||||
int orig_x = 0, orig_y = 0;
|
||||
|
||||
void puthex(unsigned long val)
|
||||
{
|
||||
unsigned char buf[10];
|
||||
int i;
|
||||
for (i = 7; i >= 0; i--)
|
||||
{
|
||||
buf[i] = "0123456789ABCDEF"[val & 0x0F];
|
||||
val >>= 4;
|
||||
}
|
||||
buf[8] = '\0';
|
||||
prom_print(buf);
|
||||
}
|
||||
|
||||
void __init ll_puts(const char *s)
|
||||
{
|
||||
int x,y;
|
||||
char *vidmem = (char *)/*(_ISA_MEM_BASE + 0xB8000) */0xD00B8000;
|
||||
char c;
|
||||
extern int mem_init_done;
|
||||
|
||||
if ( mem_init_done ) /* assume this means we can printk */
|
||||
{
|
||||
printk(s);
|
||||
return;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if ( have_of )
|
||||
{
|
||||
prom_print(s);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* can't ll_puts on chrp without openfirmware yet.
|
||||
* vidmem just needs to be setup for it.
|
||||
* -- Cort
|
||||
*/
|
||||
if ( _machine != _MACH_prep )
|
||||
return;
|
||||
x = orig_x;
|
||||
y = orig_y;
|
||||
|
||||
while ( ( c = *s++ ) != '\0' ) {
|
||||
if ( c == '\n' ) {
|
||||
x = 0;
|
||||
if ( ++y >= lines ) {
|
||||
/*scroll();*/
|
||||
/*y--;*/
|
||||
y = 0;
|
||||
}
|
||||
} else {
|
||||
vidmem [ ( x + cols * y ) * 2 ] = c;
|
||||
if ( ++x >= cols ) {
|
||||
x = 0;
|
||||
if ( ++y >= lines ) {
|
||||
/*scroll();*/
|
||||
/*y--;*/
|
||||
y = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
orig_x = x;
|
||||
orig_y = y;
|
||||
}
|
||||
#endif
|
||||
|
||||
unsigned long get_wchan(struct task_struct *p)
|
||||
{
|
||||
unsigned long ip, sp;
|
||||
unsigned long stack_page = (unsigned long) task_stack_page(p);
|
||||
int count = 0;
|
||||
if (!p || p == current || p->state == TASK_RUNNING)
|
||||
return 0;
|
||||
sp = p->thread.ksp;
|
||||
do {
|
||||
sp = *(unsigned long *)sp;
|
||||
if (sp < stack_page || sp >= stack_page + 8188)
|
||||
return 0;
|
||||
if (count > 0) {
|
||||
ip = *(unsigned long *)(sp + 4);
|
||||
if (!in_sched_functions(ip))
|
||||
return ip;
|
||||
}
|
||||
} while (count++ < 16);
|
||||
return 0;
|
||||
}
|
@ -293,6 +293,7 @@ static int send_request(struct request *req)
|
||||
u16 viocmd;
|
||||
HvLpEvent_Rc hvrc;
|
||||
struct vioblocklpevent *bevent;
|
||||
struct HvLpEvent *hev;
|
||||
struct scatterlist sg[VIOMAXBLOCKDMA];
|
||||
int sgindex;
|
||||
int statindex;
|
||||
@ -347,22 +348,19 @@ static int send_request(struct request *req)
|
||||
* token so we can match the response up later
|
||||
*/
|
||||
memset(bevent, 0, sizeof(struct vioblocklpevent));
|
||||
bevent->event.xFlags.xValid = 1;
|
||||
bevent->event.xFlags.xFunction = HvLpEvent_Function_Int;
|
||||
bevent->event.xFlags.xAckInd = HvLpEvent_AckInd_DoAck;
|
||||
bevent->event.xFlags.xAckType = HvLpEvent_AckType_ImmediateAck;
|
||||
bevent->event.xType = HvLpEvent_Type_VirtualIo;
|
||||
bevent->event.xSubtype = viocmd;
|
||||
bevent->event.xSourceLp = HvLpConfig_getLpIndex();
|
||||
bevent->event.xTargetLp = viopath_hostLp;
|
||||
bevent->event.xSizeMinus1 =
|
||||
hev = &bevent->event;
|
||||
hev->flags = HV_LP_EVENT_VALID | HV_LP_EVENT_DO_ACK |
|
||||
HV_LP_EVENT_INT;
|
||||
hev->xType = HvLpEvent_Type_VirtualIo;
|
||||
hev->xSubtype = viocmd;
|
||||
hev->xSourceLp = HvLpConfig_getLpIndex();
|
||||
hev->xTargetLp = viopath_hostLp;
|
||||
hev->xSizeMinus1 =
|
||||
offsetof(struct vioblocklpevent, u.rw_data.dma_info) +
|
||||
(sizeof(bevent->u.rw_data.dma_info[0]) * nsg) - 1;
|
||||
bevent->event.xSourceInstanceId =
|
||||
viopath_sourceinst(viopath_hostLp);
|
||||
bevent->event.xTargetInstanceId =
|
||||
viopath_targetinst(viopath_hostLp);
|
||||
bevent->event.xCorrelationToken = (u64)req;
|
||||
hev->xSourceInstanceId = viopath_sourceinst(viopath_hostLp);
|
||||
hev->xTargetInstanceId = viopath_targetinst(viopath_hostLp);
|
||||
hev->xCorrelationToken = (u64)req;
|
||||
bevent->version = VIOVERSION;
|
||||
bevent->disk = DEVICE_NO(d);
|
||||
bevent->u.rw_data.offset = start;
|
||||
@ -649,10 +647,10 @@ static void handle_block_event(struct HvLpEvent *event)
|
||||
/* Notification that a partition went away! */
|
||||
return;
|
||||
/* First, we should NEVER get an int here...only acks */
|
||||
if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
|
||||
if (hvlpevent_is_int(event)) {
|
||||
printk(VIOD_KERN_WARNING
|
||||
"Yikes! got an int in viodasd event handler!\n");
|
||||
if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) {
|
||||
if (hvlpevent_need_ack(event)) {
|
||||
event->xRc = HvLpEvent_Rc_InvalidSubtype;
|
||||
HvCallEvent_ackLpEvent(event);
|
||||
}
|
||||
@ -695,7 +693,7 @@ static void handle_block_event(struct HvLpEvent *event)
|
||||
|
||||
default:
|
||||
printk(VIOD_KERN_WARNING "invalid subtype!");
|
||||
if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) {
|
||||
if (hvlpevent_need_ack(event)) {
|
||||
event->xRc = HvLpEvent_Rc_InvalidSubtype;
|
||||
HvCallEvent_ackLpEvent(event);
|
||||
}
|
||||
|
@ -542,10 +542,10 @@ static void vio_handle_cd_event(struct HvLpEvent *event)
|
||||
/* Notification that a partition went away! */
|
||||
return;
|
||||
/* First, we should NEVER get an int here...only acks */
|
||||
if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
|
||||
if (hvlpevent_is_int(event)) {
|
||||
printk(VIOCD_KERN_WARNING
|
||||
"Yikes! got an int in viocd event handler!\n");
|
||||
if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) {
|
||||
if (hvlpevent_need_ack(event)) {
|
||||
event->xRc = HvLpEvent_Rc_InvalidSubtype;
|
||||
HvCallEvent_ackLpEvent(event);
|
||||
}
|
||||
@ -616,7 +616,7 @@ return_complete:
|
||||
printk(VIOCD_KERN_WARNING
|
||||
"message with invalid subtype %0x04X!\n",
|
||||
event->xSubtype & VIOMINOR_SUBTYPE_MASK);
|
||||
if (event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck) {
|
||||
if (hvlpevent_need_ack(event)) {
|
||||
event->xRc = HvLpEvent_Rc_InvalidSubtype;
|
||||
HvCallEvent_ackLpEvent(event);
|
||||
}
|
||||
|
@ -534,7 +534,7 @@ static ssize_t write_kmem(struct file * file, const char __user * buf,
|
||||
return virtr + wrote;
|
||||
}
|
||||
|
||||
#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI))
|
||||
#if defined(CONFIG_ISA) || !defined(__mc68000__)
|
||||
static ssize_t read_port(struct file * file, char __user * buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
@ -795,7 +795,7 @@ static struct file_operations null_fops = {
|
||||
.write = write_null,
|
||||
};
|
||||
|
||||
#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI))
|
||||
#if defined(CONFIG_ISA) || !defined(__mc68000__)
|
||||
static struct file_operations port_fops = {
|
||||
.llseek = memory_lseek,
|
||||
.read = read_port,
|
||||
@ -865,7 +865,7 @@ static int memory_open(struct inode * inode, struct file * filp)
|
||||
case 3:
|
||||
filp->f_op = &null_fops;
|
||||
break;
|
||||
#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI))
|
||||
#if defined(CONFIG_ISA) || !defined(__mc68000__)
|
||||
case 4:
|
||||
filp->f_op = &port_fops;
|
||||
break;
|
||||
@ -912,7 +912,7 @@ static const struct {
|
||||
{1, "mem", S_IRUSR | S_IWUSR | S_IRGRP, &mem_fops},
|
||||
{2, "kmem", S_IRUSR | S_IWUSR | S_IRGRP, &kmem_fops},
|
||||
{3, "null", S_IRUGO | S_IWUGO, &null_fops},
|
||||
#if (defined(CONFIG_ISA) || !defined(__mc68000__)) && (!defined(CONFIG_PPC_ISERIES) || defined(CONFIG_PCI))
|
||||
#if defined(CONFIG_ISA) || !defined(__mc68000__)
|
||||
{4, "port", S_IRUSR | S_IWUSR | S_IRGRP, &port_fops},
|
||||
#endif
|
||||
{5, "zero", S_IRUGO | S_IWUGO, &zero_fops},
|
||||
|
@ -476,19 +476,19 @@ static struct port_info *get_port_data(struct tty_struct *tty)
|
||||
*/
|
||||
static void initDataEvent(struct viocharlpevent *viochar, HvLpIndex lp)
|
||||
{
|
||||
struct HvLpEvent *hev = &viochar->event;
|
||||
|
||||
memset(viochar, 0, sizeof(struct viocharlpevent));
|
||||
|
||||
viochar->event.xFlags.xValid = 1;
|
||||
viochar->event.xFlags.xFunction = HvLpEvent_Function_Int;
|
||||
viochar->event.xFlags.xAckInd = HvLpEvent_AckInd_NoAck;
|
||||
viochar->event.xFlags.xAckType = HvLpEvent_AckType_DeferredAck;
|
||||
viochar->event.xType = HvLpEvent_Type_VirtualIo;
|
||||
viochar->event.xSubtype = viomajorsubtype_chario | viochardata;
|
||||
viochar->event.xSourceLp = HvLpConfig_getLpIndex();
|
||||
viochar->event.xTargetLp = lp;
|
||||
viochar->event.xSizeMinus1 = sizeof(struct viocharlpevent);
|
||||
viochar->event.xSourceInstanceId = viopath_sourceinst(lp);
|
||||
viochar->event.xTargetInstanceId = viopath_targetinst(lp);
|
||||
hev->flags = HV_LP_EVENT_VALID | HV_LP_EVENT_DEFERRED_ACK |
|
||||
HV_LP_EVENT_INT;
|
||||
hev->xType = HvLpEvent_Type_VirtualIo;
|
||||
hev->xSubtype = viomajorsubtype_chario | viochardata;
|
||||
hev->xSourceLp = HvLpConfig_getLpIndex();
|
||||
hev->xTargetLp = lp;
|
||||
hev->xSizeMinus1 = sizeof(struct viocharlpevent);
|
||||
hev->xSourceInstanceId = viopath_sourceinst(lp);
|
||||
hev->xTargetInstanceId = viopath_targetinst(lp);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -752,7 +752,7 @@ static void vioHandleOpenEvent(struct HvLpEvent *event)
|
||||
struct port_info *pi;
|
||||
int reject = 0;
|
||||
|
||||
if (event->xFlags.xFunction == HvLpEvent_Function_Ack) {
|
||||
if (hvlpevent_is_ack(event)) {
|
||||
if (port >= VTTY_PORTS)
|
||||
return;
|
||||
|
||||
@ -788,7 +788,7 @@ static void vioHandleOpenEvent(struct HvLpEvent *event)
|
||||
}
|
||||
|
||||
/* This had better require an ack, otherwise complain */
|
||||
if (event->xFlags.xAckInd != HvLpEvent_AckInd_DoAck) {
|
||||
if (!hvlpevent_need_ack(event)) {
|
||||
printk(VIOCONS_KERN_WARN "viocharopen without ack bit!\n");
|
||||
return;
|
||||
}
|
||||
@ -856,7 +856,7 @@ static void vioHandleCloseEvent(struct HvLpEvent *event)
|
||||
struct viocharlpevent *cevent = (struct viocharlpevent *)event;
|
||||
u8 port = cevent->virtual_device;
|
||||
|
||||
if (event->xFlags.xFunction == HvLpEvent_Function_Int) {
|
||||
if (hvlpevent_is_int(event)) {
|
||||
if (port >= VTTY_PORTS) {
|
||||
printk(VIOCONS_KERN_WARN
|
||||
"close message from invalid virtual device.\n");
|
||||
@ -1056,8 +1056,7 @@ static void vioHandleCharEvent(struct HvLpEvent *event)
|
||||
vioHandleConfig(event);
|
||||
break;
|
||||
default:
|
||||
if ((event->xFlags.xFunction == HvLpEvent_Function_Int) &&
|
||||
(event->xFlags.xAckInd == HvLpEvent_AckInd_DoAck)) {
|
||||
if (hvlpevent_is_int(event) && hvlpevent_need_ack(event)) {
|
||||
event->xRc = HvLpEvent_Rc_InvalidSubtype;
|
||||
HvCallEvent_ackLpEvent(event);
|
||||
}
|
||||
|
@ -590,9 +590,9 @@ static void veth_handle_event(struct HvLpEvent *event, struct pt_regs *regs)
|
||||
{
|
||||
struct veth_lpevent *veth_event = (struct veth_lpevent *)event;
|
||||
|
||||
if (event->xFlags.xFunction == HvLpEvent_Function_Ack)
|
||||
if (hvlpevent_is_ack(event))
|
||||
veth_handle_ack(veth_event);
|
||||
else if (event->xFlags.xFunction == HvLpEvent_Function_Int)
|
||||
else
|
||||
veth_handle_int(veth_event);
|
||||
}
|
||||
|
||||
|
@ -64,25 +64,6 @@ extern void iommu_free_table(struct device_node *dn);
|
||||
|
||||
#endif /* CONFIG_PPC_MULTIPLATFORM */
|
||||
|
||||
#ifdef CONFIG_PPC_PSERIES
|
||||
|
||||
/* Creates table for an individual device node */
|
||||
extern void iommu_devnode_init_pSeries(struct device_node *dn);
|
||||
|
||||
#endif /* CONFIG_PPC_PSERIES */
|
||||
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
|
||||
/* Creates table for an individual device node */
|
||||
extern void iommu_devnode_init_iSeries(struct device_node *dn);
|
||||
/* Get table parameters from HV */
|
||||
extern void iommu_table_getparms_iSeries(unsigned long busno,
|
||||
unsigned char slotno,
|
||||
unsigned char virtbus,
|
||||
struct iommu_table* tbl);
|
||||
|
||||
#endif /* CONFIG_PPC_ISERIES */
|
||||
|
||||
/* Initializes an iommu_table based in values set in the passed-in
|
||||
* structure
|
||||
*/
|
||||
|
@ -1,5 +1,4 @@
|
||||
/*
|
||||
* HvCall.h
|
||||
* Copyright (C) 2001 Mike Corrigan IBM Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -15,8 +14,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* This file contains the "hypervisor call" interface which is used to
|
||||
* drive the hypervisor from the OS.
|
||||
*/
|
||||
|
@ -1,5 +1,4 @@
|
||||
/*
|
||||
* HvCallEvent.h
|
||||
* Copyright (C) 2001 Mike Corrigan IBM Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -15,8 +14,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
/*
|
||||
*
|
||||
* This file contains the "hypervisor call" interface which is used to
|
||||
* drive the hypervisor from the OS.
|
||||
*/
|
||||
@ -33,32 +31,9 @@ typedef u8 HvLpEvent_Type;
|
||||
typedef u8 HvLpEvent_AckInd;
|
||||
typedef u8 HvLpEvent_AckType;
|
||||
|
||||
struct HvCallEvent_PackedParms {
|
||||
u8 xAckType:1;
|
||||
u8 xAckInd:1;
|
||||
u8 xRsvd:1;
|
||||
u8 xTargetLp:5;
|
||||
u8 xType;
|
||||
u16 xSubtype;
|
||||
HvLpInstanceId xSourceInstId;
|
||||
HvLpInstanceId xTargetInstId;
|
||||
};
|
||||
|
||||
typedef u8 HvLpDma_Direction;
|
||||
typedef u8 HvLpDma_AddressType;
|
||||
|
||||
struct HvCallEvent_PackedDmaParms {
|
||||
u8 xDirection:1;
|
||||
u8 xLocalAddrType:1;
|
||||
u8 xRemoteAddrType:1;
|
||||
u8 xRsvd1:5;
|
||||
HvLpIndex xRemoteLp;
|
||||
u8 xType;
|
||||
u8 xRsvd2;
|
||||
HvLpInstanceId xLocalInstId;
|
||||
HvLpInstanceId xRemoteInstId;
|
||||
};
|
||||
|
||||
typedef u64 HvLpEvent_Rc;
|
||||
typedef u64 HvLpDma_Rc;
|
||||
|
||||
@ -92,11 +67,8 @@ static inline void HvCallEvent_setInterLpQueueIndex(u8 queueIndex)
|
||||
static inline void HvCallEvent_setLpEventStack(u8 queueIndex,
|
||||
char *eventStackAddr, u32 eventStackSize)
|
||||
{
|
||||
u64 abs_addr;
|
||||
|
||||
abs_addr = virt_to_abs(eventStackAddr);
|
||||
HvCall3(HvCallEventSetLpEventStack, queueIndex, abs_addr,
|
||||
eventStackSize);
|
||||
HvCall3(HvCallEventSetLpEventStack, queueIndex,
|
||||
virt_to_abs(eventStackAddr), eventStackSize);
|
||||
}
|
||||
|
||||
static inline void HvCallEvent_setLpEventQueueInterruptProc(u8 queueIndex,
|
||||
@ -108,14 +80,7 @@ static inline void HvCallEvent_setLpEventQueueInterruptProc(u8 queueIndex,
|
||||
|
||||
static inline HvLpEvent_Rc HvCallEvent_signalLpEvent(struct HvLpEvent *event)
|
||||
{
|
||||
u64 abs_addr;
|
||||
|
||||
#ifdef DEBUG_SENDEVENT
|
||||
printk("HvCallEvent_signalLpEvent: *event = %016lx\n ",
|
||||
(unsigned long)event);
|
||||
#endif
|
||||
abs_addr = virt_to_abs(event);
|
||||
return HvCall1(HvCallEventSignalLpEvent, abs_addr);
|
||||
return HvCall1(HvCallEventSignalLpEvent, virt_to_abs(event));
|
||||
}
|
||||
|
||||
static inline HvLpEvent_Rc HvCallEvent_signalLpEventFast(HvLpIndex targetLp,
|
||||
@ -127,17 +92,21 @@ static inline HvLpEvent_Rc HvCallEvent_signalLpEventFast(HvLpIndex targetLp,
|
||||
{
|
||||
/* Pack the misc bits into a single Dword to pass to PLIC */
|
||||
union {
|
||||
struct HvCallEvent_PackedParms parms;
|
||||
struct {
|
||||
u8 ack_and_target;
|
||||
u8 type;
|
||||
u16 subtype;
|
||||
HvLpInstanceId src_inst;
|
||||
HvLpInstanceId target_inst;
|
||||
} parms;
|
||||
u64 dword;
|
||||
} packed;
|
||||
packed.parms.xAckType = ackType;
|
||||
packed.parms.xAckInd = ackInd;
|
||||
packed.parms.xRsvd = 0;
|
||||
packed.parms.xTargetLp = targetLp;
|
||||
packed.parms.xType = type;
|
||||
packed.parms.xSubtype = subtype;
|
||||
packed.parms.xSourceInstId = sourceInstanceId;
|
||||
packed.parms.xTargetInstId = targetInstanceId;
|
||||
|
||||
packed.parms.ack_and_target = (ackType << 7) | (ackInd << 6) | targetLp;
|
||||
packed.parms.type = type;
|
||||
packed.parms.subtype = subtype;
|
||||
packed.parms.src_inst = sourceInstanceId;
|
||||
packed.parms.target_inst = targetInstanceId;
|
||||
|
||||
return HvCall7(HvCallEventSignalLpEventParms, packed.dword,
|
||||
correlationToken, eventData1, eventData2,
|
||||
@ -146,18 +115,12 @@ static inline HvLpEvent_Rc HvCallEvent_signalLpEventFast(HvLpIndex targetLp,
|
||||
|
||||
static inline HvLpEvent_Rc HvCallEvent_ackLpEvent(struct HvLpEvent *event)
|
||||
{
|
||||
u64 abs_addr;
|
||||
|
||||
abs_addr = virt_to_abs(event);
|
||||
return HvCall1(HvCallEventAckLpEvent, abs_addr);
|
||||
return HvCall1(HvCallEventAckLpEvent, virt_to_abs(event));
|
||||
}
|
||||
|
||||
static inline HvLpEvent_Rc HvCallEvent_cancelLpEvent(struct HvLpEvent *event)
|
||||
{
|
||||
u64 abs_addr;
|
||||
|
||||
abs_addr = virt_to_abs(event);
|
||||
return HvCall1(HvCallEventCancelLpEvent, abs_addr);
|
||||
return HvCall1(HvCallEventCancelLpEvent, virt_to_abs(event));
|
||||
}
|
||||
|
||||
static inline HvLpInstanceId HvCallEvent_getSourceLpInstanceId(
|
||||
@ -195,59 +158,34 @@ static inline HvLpDma_Rc HvCallEvent_dmaBufList(HvLpEvent_Type type,
|
||||
{
|
||||
/* Pack the misc bits into a single Dword to pass to PLIC */
|
||||
union {
|
||||
struct HvCallEvent_PackedDmaParms parms;
|
||||
struct {
|
||||
u8 flags;
|
||||
HvLpIndex remote;
|
||||
u8 type;
|
||||
u8 reserved;
|
||||
HvLpInstanceId local_inst;
|
||||
HvLpInstanceId remote_inst;
|
||||
} parms;
|
||||
u64 dword;
|
||||
} packed;
|
||||
|
||||
packed.parms.xDirection = direction;
|
||||
packed.parms.xLocalAddrType = localAddressType;
|
||||
packed.parms.xRemoteAddrType = remoteAddressType;
|
||||
packed.parms.xRsvd1 = 0;
|
||||
packed.parms.xRemoteLp = remoteLp;
|
||||
packed.parms.xType = type;
|
||||
packed.parms.xRsvd2 = 0;
|
||||
packed.parms.xLocalInstId = localInstanceId;
|
||||
packed.parms.xRemoteInstId = remoteInstanceId;
|
||||
packed.parms.flags = (direction << 7) |
|
||||
(localAddressType << 6) | (remoteAddressType << 5);
|
||||
packed.parms.remote = remoteLp;
|
||||
packed.parms.type = type;
|
||||
packed.parms.reserved = 0;
|
||||
packed.parms.local_inst = localInstanceId;
|
||||
packed.parms.remote_inst = remoteInstanceId;
|
||||
|
||||
return HvCall4(HvCallEventDmaBufList, packed.dword, localBufList,
|
||||
remoteBufList, transferLength);
|
||||
}
|
||||
|
||||
static inline HvLpDma_Rc HvCallEvent_dmaSingle(HvLpEvent_Type type,
|
||||
HvLpIndex remoteLp, HvLpDma_Direction direction,
|
||||
HvLpInstanceId localInstanceId,
|
||||
HvLpInstanceId remoteInstanceId,
|
||||
HvLpDma_AddressType localAddressType,
|
||||
HvLpDma_AddressType remoteAddressType,
|
||||
u64 localAddrOrTce, u64 remoteAddrOrTce, u32 transferLength)
|
||||
{
|
||||
/* Pack the misc bits into a single Dword to pass to PLIC */
|
||||
union {
|
||||
struct HvCallEvent_PackedDmaParms parms;
|
||||
u64 dword;
|
||||
} packed;
|
||||
|
||||
packed.parms.xDirection = direction;
|
||||
packed.parms.xLocalAddrType = localAddressType;
|
||||
packed.parms.xRemoteAddrType = remoteAddressType;
|
||||
packed.parms.xRsvd1 = 0;
|
||||
packed.parms.xRemoteLp = remoteLp;
|
||||
packed.parms.xType = type;
|
||||
packed.parms.xRsvd2 = 0;
|
||||
packed.parms.xLocalInstId = localInstanceId;
|
||||
packed.parms.xRemoteInstId = remoteInstanceId;
|
||||
|
||||
return (HvLpDma_Rc)HvCall4(HvCallEventDmaSingle, packed.dword,
|
||||
localAddrOrTce, remoteAddrOrTce, transferLength);
|
||||
}
|
||||
|
||||
static inline HvLpDma_Rc HvCallEvent_dmaToSp(void *local, u32 remote,
|
||||
u32 length, HvLpDma_Direction dir)
|
||||
{
|
||||
u64 abs_addr;
|
||||
|
||||
abs_addr = virt_to_abs(local);
|
||||
return HvCall4(HvCallEventDmaToSp, abs_addr, remote, length, dir);
|
||||
return HvCall4(HvCallEventDmaToSp, virt_to_abs(local), remote,
|
||||
length, dir);
|
||||
}
|
||||
|
||||
#endif /* _ASM_POWERPC_ISERIES_HV_CALL_EVENT_H */
|
||||
|
@ -1,5 +1,4 @@
|
||||
/*
|
||||
* HvCallSc.h
|
||||
* Copyright (C) 2001 Mike Corrigan IBM Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -1,5 +1,4 @@
|
||||
/*
|
||||
* HvLpConfig.h
|
||||
* Copyright (C) 2001 Mike Corrigan IBM Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -1,5 +1,4 @@
|
||||
/*
|
||||
* HvLpEvent.h
|
||||
* Copyright (C) 2001 Mike Corrigan IBM Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -32,17 +31,8 @@
|
||||
* partitions through PLIC.
|
||||
*/
|
||||
|
||||
struct HvEventFlags {
|
||||
u8 xValid:1; /* Indicates a valid request x00-x00 */
|
||||
u8 xRsvd1:4; /* Reserved ... */
|
||||
u8 xAckType:1; /* Immediate or deferred ... */
|
||||
u8 xAckInd:1; /* Indicates if ACK required ... */
|
||||
u8 xFunction:1; /* Interrupt or Acknowledge ... */
|
||||
};
|
||||
|
||||
|
||||
struct HvLpEvent {
|
||||
struct HvEventFlags xFlags; /* Event flags x00-x00 */
|
||||
u8 flags; /* Event flags x00-x00 */
|
||||
u8 xType; /* Type of message x01-x01 */
|
||||
u16 xSubtype; /* Subtype for event x02-x03 */
|
||||
u8 xSourceLp; /* Source LP x04-x04 */
|
||||
@ -126,6 +116,11 @@ extern int HvLpEvent_closePath(HvLpEvent_Type eventType, HvLpIndex lpIndex);
|
||||
#define HvLpEvent_AckType_ImmediateAck 0
|
||||
#define HvLpEvent_AckType_DeferredAck 1
|
||||
|
||||
#define HV_LP_EVENT_INT 0x01
|
||||
#define HV_LP_EVENT_DO_ACK 0x02
|
||||
#define HV_LP_EVENT_DEFERRED_ACK 0x04
|
||||
#define HV_LP_EVENT_VALID 0x80
|
||||
|
||||
#define HvLpDma_Direction_LocalToRemote 0
|
||||
#define HvLpDma_Direction_RemoteToLocal 1
|
||||
|
||||
@ -139,4 +134,29 @@ extern int HvLpEvent_closePath(HvLpEvent_Type eventType, HvLpIndex lpIndex);
|
||||
#define HvLpDma_Rc_InvalidAddress 4
|
||||
#define HvLpDma_Rc_InvalidLength 5
|
||||
|
||||
static inline int hvlpevent_is_valid(struct HvLpEvent *h)
|
||||
{
|
||||
return h->flags & HV_LP_EVENT_VALID;
|
||||
}
|
||||
|
||||
static inline void hvlpevent_invalidate(struct HvLpEvent *h)
|
||||
{
|
||||
h->flags &= ~ HV_LP_EVENT_VALID;
|
||||
}
|
||||
|
||||
static inline int hvlpevent_is_int(struct HvLpEvent *h)
|
||||
{
|
||||
return h->flags & HV_LP_EVENT_INT;
|
||||
}
|
||||
|
||||
static inline int hvlpevent_is_ack(struct HvLpEvent *h)
|
||||
{
|
||||
return !hvlpevent_is_int(h);
|
||||
}
|
||||
|
||||
static inline int hvlpevent_need_ack(struct HvLpEvent *h)
|
||||
{
|
||||
return h->flags & HV_LP_EVENT_DO_ACK;
|
||||
}
|
||||
|
||||
#endif /* _ASM_POWERPC_ISERIES_HV_LP_EVENT_H */
|
||||
|
@ -1,5 +1,4 @@
|
||||
/*
|
||||
* HvTypes.h
|
||||
* Copyright (C) 2001 Mike Corrigan IBM Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -6,7 +6,7 @@
|
||||
#ifdef CONFIG_PPC_ISERIES
|
||||
#include <linux/types.h>
|
||||
/*
|
||||
* File iSeries_io.h created by Allan Trautman on Thu Dec 28 2000.
|
||||
* Created by Allan Trautman on Thu Dec 28 2000.
|
||||
*
|
||||
* Remaps the io.h for the iSeries Io
|
||||
* Copyright (C) 2000 Allan H Trautman, IBM Corporation
|
||||
@ -32,6 +32,7 @@
|
||||
* End Change Activity
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_PCI
|
||||
extern u8 iSeries_Read_Byte(const volatile void __iomem * IoAddress);
|
||||
extern u16 iSeries_Read_Word(const volatile void __iomem * IoAddress);
|
||||
extern u32 iSeries_Read_Long(const volatile void __iomem * IoAddress);
|
||||
@ -44,6 +45,17 @@ extern void iSeries_memcpy_toio(volatile void __iomem *dest, void *source,
|
||||
size_t n);
|
||||
extern void iSeries_memcpy_fromio(void *dest,
|
||||
const volatile void __iomem *source, size_t n);
|
||||
#else
|
||||
static inline u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
|
||||
{
|
||||
return 0xff;
|
||||
}
|
||||
|
||||
static inline void iSeries_Write_Byte(u8 IoData,
|
||||
volatile void __iomem *IoAddress)
|
||||
{
|
||||
}
|
||||
#endif /* CONFIG_PCI */
|
||||
|
||||
#endif /* CONFIG_PPC_ISERIES */
|
||||
#endif /* _ASM_POWERPC_ISERIES_ISERIES_IO_H */
|
||||
|
@ -1,5 +1,4 @@
|
||||
/*
|
||||
* ItExtVpdPanel.h
|
||||
* Copyright (C) 2002 Dave Boutcher IBM Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -1,5 +1,4 @@
|
||||
/*
|
||||
* ItLpNaca.h
|
||||
* Copyright (C) 2001 Mike Corrigan IBM Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -37,17 +36,13 @@ struct ItLpNaca {
|
||||
u8 xLpIndex; // LP Index x0B-x0B
|
||||
u16 xMaxLpQueues; // Number of allocated queues x0C-x0D
|
||||
u16 xLpQueueOffset; // Offset to start of LP queues x0E-x0F
|
||||
u8 xPirEnvironMode:8; // Piranha or hardware x10-x10
|
||||
u8 xPirConsoleMode:8; // Piranha console indicator x11-x11
|
||||
u8 xPirDasdMode:8; // Piranha dasd indicator x12-x12
|
||||
u8 xPirEnvironMode; // Piranha or hardware x10-x10
|
||||
u8 xPirConsoleMode; // Piranha console indicator x11-x11
|
||||
u8 xPirDasdMode; // Piranha dasd indicator x12-x12
|
||||
u8 xRsvd1_0[5]; // Reserved for Piranha related x13-x17
|
||||
u8 xLparInstalled:1; // Is LPAR installed on system x18-x1F
|
||||
u8 xSysPartitioned:1; // Is the system partitioned ...
|
||||
u8 xHwSyncedTBs:1; // Hardware synced TBs ...
|
||||
u8 xIntProcUtilHmt:1; // Utilize HMT for interrupts ...
|
||||
u8 xRsvd1_1:4; // Reserved ...
|
||||
u8 xSpVpdFormat:8; // VPD areas are in CSP format ...
|
||||
u8 xIntProcRatio:8; // Ratio of int procs to procs ...
|
||||
u8 flags; // flags, see below x18-x1F
|
||||
u8 xSpVpdFormat; // VPD areas are in CSP format ...
|
||||
u8 xIntProcRatio; // Ratio of int procs to procs ...
|
||||
u8 xRsvd1_2[5]; // Reserved ...
|
||||
u16 xRsvd1_3; // Reserved x20-x21
|
||||
u16 xPlicVrmIndex; // VRM index of PLIC x22-x23
|
||||
@ -77,4 +72,9 @@ struct ItLpNaca {
|
||||
|
||||
extern struct ItLpNaca itLpNaca;
|
||||
|
||||
#define ITLPNACA_LPAR 0x80 /* Is LPAR installed on the system */
|
||||
#define ITLPNACA_PARTITIONED 0x40 /* Is the system partitioned */
|
||||
#define ITLPNACA_HWSYNCEDTBS 0x20 /* Hardware synced TBs */
|
||||
#define ITLPNACA_HMTINT 0x10 /* Utilize MHT for interrupts */
|
||||
|
||||
#endif /* _ASM_POWERPC_ISERIES_IT_LP_NACA_H */
|
||||
|
@ -1,5 +1,4 @@
|
||||
/*
|
||||
* ItLpQueue.h
|
||||
* Copyright (C) 2001 Mike Corrigan IBM Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -1,5 +1,4 @@
|
||||
/*
|
||||
* ItLpRegSave.h
|
||||
* Copyright (C) 2001 Mike Corrigan IBM Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@ -83,4 +82,4 @@ struct ItLpRegSave {
|
||||
|
||||
extern struct ItLpRegSave iseries_reg_save[];
|
||||
|
||||
#endif /* _ITLPREGSAVE_H */
|
||||
#endif /* _ASM_POWERPC_ISERIES_IT_LP_REG_SAVE_H */
|
||||
|
@ -1,5 +1,4 @@
|
||||
/*
|
||||
* LparMap.h
|
||||
* Copyright (C) 2001 Mike Corrigan IBM Corporation
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
|
@ -1,5 +1,4 @@
|
||||
/*
|
||||
* mf.h
|
||||
* Copyright (C) 2001 Troy D. Armstrong IBM Corporation
|
||||
* Copyright (C) 2004 Stephen Rothwell IBM Corporation
|
||||
*
|
||||
|
@ -1,5 +1,4 @@
|
||||
/* -*- linux-c -*-
|
||||
* drivers/char/vio.h
|
||||
*
|
||||
* iSeries Virtual I/O Message Path header
|
||||
*
|
||||
|
@ -142,8 +142,6 @@ void pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus);
|
||||
|
||||
extern int pcibios_remove_root_bus(struct pci_controller *phb);
|
||||
|
||||
extern void phbs_remap_io(void);
|
||||
|
||||
static inline struct pci_controller *pci_bus_to_host(struct pci_bus *bus)
|
||||
{
|
||||
struct device_node *busdn = bus->sysdata;
|
||||
|
@ -133,6 +133,14 @@ extern int fix_alignment(struct pt_regs *);
|
||||
extern void cvt_fd(float *from, double *to, struct thread_struct *thread);
|
||||
extern void cvt_df(double *from, float *to, struct thread_struct *thread);
|
||||
|
||||
#ifndef CONFIG_SMP
|
||||
extern void discard_lazy_cpu_state(void);
|
||||
#else
|
||||
static inline void discard_lazy_cpu_state(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ALTIVEC
|
||||
extern void flush_altivec_to_thread(struct task_struct *);
|
||||
#else
|
||||
|
@ -4,7 +4,6 @@
|
||||
#ifndef __PPC_SYSTEM_H
|
||||
#define __PPC_SYSTEM_H
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/kernel.h>
|
||||
|
||||
#include <asm/atomic.h>
|
||||
@ -39,7 +38,7 @@
|
||||
#ifdef CONFIG_SMP
|
||||
#define smp_mb() mb()
|
||||
#define smp_rmb() rmb()
|
||||
#define smp_wmb() wmb()
|
||||
#define smp_wmb() __asm__ __volatile__ ("eieio" : : : "memory")
|
||||
#define smp_read_barrier_depends() read_barrier_depends()
|
||||
#else
|
||||
#define smp_mb() barrier()
|
||||
@ -74,6 +73,7 @@ extern void chrp_nvram_init(void);
|
||||
extern void read_rtc_time(void);
|
||||
extern void pmac_find_display(void);
|
||||
extern void giveup_fpu(struct task_struct *);
|
||||
extern void disable_kernel_fp(void);
|
||||
extern void enable_kernel_fp(void);
|
||||
extern void flush_fp_to_thread(struct task_struct *);
|
||||
extern void enable_kernel_altivec(void);
|
||||
@ -86,6 +86,14 @@ extern int fix_alignment(struct pt_regs *);
|
||||
extern void cvt_fd(float *from, double *to, struct thread_struct *thread);
|
||||
extern void cvt_df(double *from, float *to, struct thread_struct *thread);
|
||||
|
||||
#ifndef CONFIG_SMP
|
||||
extern void discard_lazy_cpu_state(void);
|
||||
#else
|
||||
static inline void discard_lazy_cpu_state(void)
|
||||
{
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_ALTIVEC
|
||||
extern void flush_altivec_to_thread(struct task_struct *);
|
||||
#else
|
||||
|
Loading…
Reference in New Issue
Block a user