Commit 2c24cc13 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] ppc64: preliminary iseries support, from Paul Mackerras

From: Anton Blanchard <anton@samba.org>

Preliminary iSeries support.  Still a bit hackish in parts but it does
compile.  The viodasd driver is almost completely untested so don't trust it
with your data.
parent 228ab0bd
......@@ -10,20 +10,25 @@ obj-y := setup.o entry.o traps.o irq.o idle.o \
align.o semaphore.o bitops.o stab.o htab.o pacaData.o \
udbg.o binfmt_elf32.o sys_ppc32.o ioctl32.o \
ptrace32.o signal32.o pmc.o rtc.o init_task.o \
lmb.o pci.o pci_dn.o pci_dma.o cputable.o
lmb.o cputable.o
obj-$(CONFIG_PPC_ISERIES) += iSeries_pci.o iSeries_pci_reset.o \
iSeries_IoMmTable.o iSeries_irq.o \
obj-$(CONFIG_PCI) += pci.o pci_dn.o pci_dma.o
ifdef CONFIG_PPC_ISERIES
obj-$(CONFIG_PCI) += iSeries_pci.o iSeries_pci_reset.o \
iSeries_IoMmTable.o
endif
obj-$(CONFIG_PPC_ISERIES) += iSeries_irq.o \
iSeries_VpdInfo.o XmPciLpEvent.o \
HvCall.o HvLpConfig.o LparData.o mf_proc.o \
iSeries_setup.o ItLpQueue.o hvCall.o \
mf.o HvLpEvent.o iSeries_proc.o
mf.o HvLpEvent.o iSeries_proc.o iSeries_htab.o \
proc_pmc.o
obj-$(CONFIG_PPC_PSERIES) += pSeries_pci.o pSeries_lpar.o pSeries_hvCall.o \
eeh.o nvram.o rtasd.o ras.o
# Change this to pSeries only once we've got iSeries up to date
obj-y += open_pic.o xics.o pSeries_htab.o rtas.o \
eeh.o nvram.o rtasd.o ras.o \
open_pic.o xics.o pSeries_htab.o rtas.o \
chrp_setup.o i8259.o prom.o
obj-$(CONFIG_PROC_FS) += proc_ppc64.o
......@@ -32,5 +37,6 @@ obj-$(CONFIG_SMP) += smp.o
obj-$(CONFIG_MODULES) += module.o ppc_ksyms.o
obj-$(CONFIG_PPC_RTAS) += rtas-proc.o
obj-$(CONFIG_SCANLOG) += scanlog.o
obj-$(CONFIG_VIOPATH) += viopath.o
CFLAGS_ioctl32.o += -Ifs/
......@@ -65,8 +65,6 @@
#include <asm/ppcdebug.h>
#include <asm/cputable.h>
extern volatile unsigned char *chrp_int_ack_special;
void chrp_progress(char *, unsigned short);
extern void openpic_init_IRQ(void);
......
......@@ -275,15 +275,6 @@ _GLOBAL(_switch)
addi r6,r4,-THREAD /* Convert THREAD to 'current' */
std r6,PACACURRENT(r13) /* Set new 'current' */
#ifdef CONFIG_PPC_ISERIES
#error fixme
ld r7,TI_FLAGS(r4) /* Get run light flag */
mfspr r9,CTRLF
srdi r7,r7,1 /* Align to run light bit in CTRL reg */
insrdi r9,r7,1,63 /* Insert run light into CTRL */
mtspr CTRLT,r9
#endif
ld r1,KSP(r4) /* Load new stack pointer */
ld r6,_CCR(r1)
mtcrf 0xFF,r6
......@@ -291,6 +282,15 @@ _GLOBAL(_switch)
REST_8GPRS(14, r1)
REST_10GPRS(22, r1)
#ifdef CONFIG_PPC_ISERIES
clrrdi r7,r1,THREAD_SHIFT /* get current_thread_info() */
ld r7,TI_FLAGS(r7) /* Get run light flag */
mfspr r9,CTRLF
srdi r7,r7,TIF_RUN_LIGHT
insrdi r9,r7,1,63 /* Insert run light into CTRL */
mtspr CTRLT,r9
#endif
/* convert old thread to its task_struct for return value */
addi r3,r3,-THREAD
ld r7,_NIP(r1) /* Return to _switch caller in new task */
......@@ -308,39 +308,16 @@ _GLOBAL(ret_from_fork)
b .ret_from_except
_GLOBAL(ret_from_except)
#ifdef CONFIG_PPC_ISERIES
ld r5,SOFTE(r1)
cmpdi 0,r5,0
beq 4f
irq_recheck:
/* Check for pending interrupts (iSeries) */
CHECKANYINT(r3,r4)
beq+ 4f /* skip do_IRQ if no interrupts */
#warning FIX ISERIES
mfspr r5,SPRG3
li r3,0
stb r3,PACAPROCENABLED(r5) /* ensure we are disabled */
addi r3,r1,STACK_FRAME_OVERHEAD
bl .do_IRQ
b irq_recheck /* loop back and handle more */
4:
#endif
/*
* Disable interrupts so that current_thread_info()->flags
* can't change between when we test it and when we return
* from the interrupt.
*/
recheck:
mfmsr r10 /* Get current interrupt state */
li r4,0
ori r4,r4,MSR_EE
andc r10,r10,r4 /* clear MSR_EE */
mtmsrd r10,1 /* Update machine state */
#ifdef CONFIG_PPC_ISERIES
#error fix iSeries soft disable
#endif
andc r9,r10,r4 /* clear MSR_EE */
mtmsrd r9,1 /* Update machine state */
ld r3,_MSR(r1) /* Returning to user mode? */
andi. r3,r3,MSR_PR
......@@ -364,6 +341,28 @@ recheck:
REST_GPR(13,r1)
restore:
#ifdef CONFIG_PPC_ISERIES
ld r5,SOFTE(r1)
mfspr r4,SPRG3 /* get paca address */
cmpdi 0,r5,0
beq 4f
/* Check for pending interrupts (iSeries) */
/* this is CHECKANYINT except that we already have the paca address */
ld r3,PACALPPACA+LPPACAANYINT(r4)
cmpdi r3,0
beq+ 4f /* skip do_IRQ if no interrupts */
mfspr r13,SPRG3 /* get paca pointer back */
li r3,0
stb r3,PACAPROCENABLED(r13) /* ensure we are soft-disabled */
mtmsrd r10 /* hard-enable again */
addi r3,r1,STACK_FRAME_OVERHEAD
bl .do_IRQ
b .ret_from_except /* loop back and handle more */
4: stb r5,PACAPROCENABLED(r4)
#endif
ld r3,_CTR(r1)
ld r0,_LINK(r1)
mtctr r3
......@@ -377,12 +376,6 @@ restore:
stdcx. r0,0,r1 /* to clear the reservation */
#ifdef DO_SOFT_DISABLE
/* XXX do this in do_work, r13 isnt valid here */
ld r0,SOFTE(r1)
stb r0,PACAPROCENABLED(r13)
#endif
mfmsr r0
li r2, MSR_RI
andc r0,r0,r2
......@@ -407,21 +400,21 @@ restore:
/* Note: this must change if we start using the TIF_NOTIFY_RESUME bit */
do_work:
/* Enable interrupts */
ori r10,r10,MSR_EE
mtmsrd r10,1
andi. r0,r3,_TIF_NEED_RESCHED
beq 1f
bl .schedule
b recheck
b .ret_from_except
1: andi. r0,r3,_TIF_SIGPENDING
beq recheck
beq .ret_from_except
li r3,0
addi r4,r1,STACK_FRAME_OVERHEAD
bl .do_signal
b recheck
b .ret_from_except
#ifdef CONFIG_PPC_PSERIES
/*
* On CHRP, the Run-Time Abstraction Services (RTAS) have to be
* called with the MMU off.
......@@ -632,3 +625,4 @@ _GLOBAL(enter_prom)
mtlr r0
blr /* return to caller */
#endif /* defined(CONFIG_PPC_PSERIES) */
......@@ -91,20 +91,26 @@
.text
.globl _stext
_stext:
#ifdef CONFIG_PPC_PSERIES
_STATIC(__start)
b .__start_initialization_pSeries
#endif
#ifdef CONFIG_PPC_ISERIES
/* At offset 0x20, there is a pointer to iSeries LPAR data.
* This is required by the hypervisor */
/*
* 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
/*
* At offset 0x28 and 0x30 are offsets to the msChunks
* 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) */
* to the pidhash table (also used by the debugger)
*/
.llong msChunks-KERNELBASE
.llong pidhash-KERNELBASE
.llong 0 /* pidhash-KERNELBASE SFRXXX */
/* Offset 0x38 - Pointer to start of embedded System.map */
.globl embedded_sysmap_start
......@@ -114,7 +120,7 @@ embedded_sysmap_start:
.globl embedded_sysmap_end
embedded_sysmap_end:
.llong 0
#endif
#else
/* Secondary processors spin on this value until it goes to 1. */
.globl __secondary_hold_spinloop
......@@ -164,6 +170,7 @@ _GLOBAL(__secondary_hold)
BUG_OPCODE
#endif
#endif
#endif
/*
* The following macros define the code that appears as
......@@ -245,6 +252,14 @@ _GLOBAL(__secondary_hold)
std r22,EX_SRR0(r21); /* save SRR0 in exc. frame */ \
ld r23,LPPACA+LPPACASRR1(r20); /* Get SRR1 from ItLpPaca */ \
std r23,EX_SRR1(r21); /* save SRR1 in exc. frame */ \
\
mfspr r23,DAR; /* Save DAR in exc. frame */ \
std r23,EX_DAR(r21); \
mfspr r23,DSISR; /* Save DSISR in exc. frame */ \
stw r23,EX_DSISR(r21); \
mfspr r23,SPRG2; /* Save r20 in exc. frame */ \
std r23,EX_R20(r21); \
\
mfcr r23; /* save CR in r23 */
/*
......@@ -1114,7 +1129,6 @@ _GLOBAL(save_remaining_regs)
SET_REG_TO_CONST(r22, MSR_KERNEL)
#ifdef DO_SOFT_DISABLE
#warning FIX ISERIES
stb r20,PACAPROCENABLED(r13) /* possibly soft enable */
ori r22,r22,MSR_EE /* always hard enable */
#else
......@@ -1220,6 +1234,7 @@ _GLOBAL(__start_initialization_iSeries)
b .start_here_common
#endif
#ifdef CONFIG_PPC_PSERIES
_GLOBAL(__start_initialization_pSeries)
mr r31,r3 /* save parameters */
mr r30,r4
......@@ -1329,6 +1344,7 @@ _STATIC(__after_prom_start)
sub r5,r5,r27
bl .copy_and_flush /* copy the rest */
b .start_here_pSeries
#endif
/*
* Copy routine used to copy the kernel to start at physical address 0
......@@ -1595,6 +1611,7 @@ _GLOBAL(enable_32b_mode)
isync
blr
#ifdef CONFIG_PPC_PSERIES
/*
* This is where the main kernel code starts.
*/
......@@ -1730,6 +1747,7 @@ _STATIC(start_here_pSeries)
mtspr SRR0,r3
mtspr SRR1,r4
rfid
#endif /* CONFIG_PPC_PSERIES */
/* This is where all platforms converge execution */
_STATIC(start_here_common)
......@@ -1804,10 +1822,8 @@ _STATIC(start_here_common)
/* Load up the kernel context */
5:
#ifdef DO_SOFT_DISABLE
#warning FIX ISERIES
mfspr r4,SPRG3
li r5,0
stb r5,PACAPROCENABLED(r4) /* Soft Disabled */
stb r5,PACAPROCENABLED(r13) /* Soft Disabled */
mfmsr r5
ori r5,r5,MSR_EE /* Hard Enabled */
mtmsrd r5
......
......@@ -75,6 +75,7 @@ loop_forever(void)
;
}
#ifdef CONFIG_PPC_PSERIES
static inline void
create_pte_mapping(unsigned long start, unsigned long end,
unsigned long mode, int large)
......@@ -181,6 +182,7 @@ htab_initialize(void)
}
#undef KB
#undef MB
#endif
/*
* find_linux_pte returns the address of a linux pte for a given
......
#define PCIFR(...)
/************************************************************************/
/* This module supports the iSeries I/O Address translation mapping */
/* Copyright (C) 20yy <Allan H Trautman> <IBM Corp> */
......
/*
* iSeries hashtable management.
* Derived from pSeries_htab.c
*
* SMP scalability work:
* Copyright (C) 2001 Anton Blanchard <anton@au.ibm.com>, IBM
*
* 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/machdep.h>
#include <asm/pgtable.h>
#include <asm/mmu.h>
#include <asm/mmu_context.h>
#include <asm/iSeries/HvCallHpt.h>
#include <asm/abs_addr.h>
#if 0
#include <linux/spinlock.h>
#include <linux/bitops.h>
#include <linux/threads.h>
#include <linux/smp.h>
#include <asm/tlbflush.h>
#include <asm/tlb.h>
#include <asm/cputable.h>
#endif
static long iSeries_hpte_insert(unsigned long hpte_group, unsigned long va,
unsigned long prpn, int secondary,
unsigned long hpteflags, int bolted, int large)
{
long slot;
HPTE lhpte;
/*
* The hypervisor tries both primary and secondary.
* If we are being called to insert in the secondary,
* it means we have already tried both primary and secondary,
* so we return failure immediately.
*/
if (secondary)
return -1;
slot = HvCallHpt_findValid(&lhpte, va >> PAGE_SHIFT);
if (lhpte.dw0.dw0.v)
panic("select_hpte_slot found entry already valid\n");
if (slot == -1) /* No available entry found in either group */
return -1;
if (slot < 0) { /* MSB set means secondary group */
secondary = 1;
slot &= 0x7fffffffffffffff;
}
lhpte.dw1.dword1 = 0;
lhpte.dw1.dw1.rpn = physRpn_to_absRpn(prpn);
lhpte.dw1.flags.flags = hpteflags;
lhpte.dw0.dword0 = 0;
lhpte.dw0.dw0.avpn = va >> 23;
lhpte.dw0.dw0.h = secondary;
lhpte.dw0.dw0.bolted = bolted;
lhpte.dw0.dw0.v = 1;
/* Now fill in the actual HPTE */
HvCallHpt_addValidate(slot, secondary, &lhpte);
return (secondary << 3) | (slot & 7);
}
static unsigned long iSeries_hpte_getword0(unsigned long slot)
{
unsigned long dword0;
HPTE hpte;
HvCallHpt_get(&hpte, slot);
dword0 = hpte.dw0.dword0;
return dword0;
}
static long iSeries_hpte_remove(unsigned long hpte_group)
{
unsigned long slot_offset;
int i;
HPTE lhpte;
/* Pick a random slot to start at */
slot_offset = mftb() & 0x7;
for (i = 0; i < HPTES_PER_GROUP; i++) {
lhpte.dw0.dword0 =
iSeries_hpte_getword0(hpte_group + slot_offset);
if (!lhpte.dw0.dw0.bolted) {
HvCallHpt_invalidateSetSwBitsGet(hpte_group +
slot_offset, 0, 0);
return i;
}
slot_offset++;
slot_offset &= 0x7;
}
return -1;
}
static long iSeries_hpte_updatepp(unsigned long slot, unsigned long newpp,
unsigned long va, int large, int local)
{
HPTE hpte;
unsigned long avpn = va >> 23;
HvCallHpt_get(&hpte, slot);
if ((hpte.dw0.dw0.avpn == avpn) && (hpte.dw0.dw0.v)) {
HvCallHpt_setPp(slot, newpp);
return 0;
}
return -1;
}
/*
* Functions used to find the PTE for a particular virtual address.
* Only used during boot when bolting pages.
*
* Input : vpn : virtual page number
* Output: PTE index within the page table of the entry
* -1 on failure
*/
static long iSeries_hpte_find(unsigned long vpn)
{
HPTE hpte;
long slot;
/*
* The HvCallHpt_findValid interface is as follows:
* 0xffffffffffffffff : No entry found.
* 0x00000000xxxxxxxx : Entry found in primary group, slot x
* 0x80000000xxxxxxxx : Entry found in secondary group, slot x
*/
slot = HvCallHpt_findValid(&hpte, vpn);
if (hpte.dw0.dw0.v) {
if (slot < 0) {
slot &= 0x7fffffffffffffff;
slot = -slot;
}
} else
slot = -1;
return slot;
}
/*
* Update the page protection bits. Intended to be used to create
* guard pages for kernel data structures on pages which are bolted
* in the HPT. Assumes pages being operated on will not be stolen.
* Does not work on large pages.
*
* No need to lock here because we should be the only user.
*/
static void iSeries_hpte_updateboltedpp(unsigned long newpp, unsigned long ea)
{
unsigned long vsid,va,vpn;
long slot;
vsid = get_kernel_vsid(ea);
va = (vsid << 28) | (ea & 0x0fffffff);
vpn = va >> PAGE_SHIFT;
slot = iSeries_hpte_find(vpn);
if (slot == -1)
panic("updateboltedpp: Could not find page to bolt\n");
HvCallHpt_setPp(slot, newpp);
}
static void iSeries_hpte_invalidate(unsigned long slot, unsigned long va,
int large, int local)
{
HPTE lhpte;
unsigned long avpn = va >> 23;
lhpte.dw0.dword0 = iSeries_hpte_getword0(slot);
if ((lhpte.dw0.dw0.avpn == avpn) && lhpte.dw0.dw0.v)
HvCallHpt_invalidateSetSwBitsGet(slot, 0, 0);
}
void hpte_init_iSeries(void)
{
ppc_md.hpte_invalidate = iSeries_hpte_invalidate;
ppc_md.hpte_updatepp = iSeries_hpte_updatepp;
ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp;
ppc_md.hpte_insert = iSeries_hpte_insert;
ppc_md.hpte_remove = iSeries_hpte_remove;
}
This diff is collapsed.
This diff is collapsed.
#define PCIFR(...)
/************************************************************************/
/* File iSeries_pci_reset.c created by Allan Trautman on Mar 21 2001. */
/************************************************************************/
......
......@@ -27,9 +27,8 @@
#include <asm/iSeries/iSeries_proc.h>
#endif
static struct proc_dir_entry * iSeries_proc_root = NULL;
static int iSeries_proc_initializationDone = 0;
static struct proc_dir_entry *iSeries_proc_root;
static int iSeries_proc_initializationDone;
static spinlock_t iSeries_proc_lock;
struct iSeries_proc_registration
......@@ -96,21 +95,22 @@ void iSeries_proc_create(void)
{
unsigned long flags;
struct iSeries_proc_registration *reg = NULL;
spin_lock_irqsave(&iSeries_proc_lock, flags);
printk("iSeries_proc: Creating /proc/iSeries\n");
spin_lock_irqsave(&iSeries_proc_lock, flags);
iSeries_proc_root = proc_mkdir("iSeries", 0);
if (!iSeries_proc_root) return;
if (!iSeries_proc_root)
goto out;
MYQUEUEDEQ(&iSeries_queued, reg);
while (reg != NULL) {
(*(reg->functionMember))(iSeries_proc_root);
MYQUEUEDEQ(&iSeries_queued, reg);
}
iSeries_proc_initializationDone = 1;
out:
spin_unlock_irqrestore(&iSeries_proc_lock, flags);
}
......
This diff is collapsed.
......@@ -20,23 +20,22 @@
#define __ISERIES_SETUP_H__
extern void iSeries_init_early(void);
extern void iSeries_init(unsigned long r3,
unsigned long ird_start,
unsigned long ird_end,
unsigned long cline_start,
extern void iSeries_init(unsigned long r3, unsigned long ird_start,
unsigned long ird_end, unsigned long cline_start,
unsigned long cline_end);
extern void iSeries_setup_arch(void);
extern void iSeries_setup_residual(struct seq_file *m);
extern void iSeries_setup_residual(struct seq_file *m, int cpu_id);
extern void iSeries_get_cpuinfo(struct seq_file *m);
extern void iSeries_init_IRQ(void);
extern void iSeries_init_irq_desc(irq_desc_t *);
extern int iSeries_get_irq(struct pt_regs *regs);
extern void iSeries_restart(char *cmd);
extern void iSeries_power_off(void);
extern void iSeries_halt(void);
extern void iSeries_time_init(void);
extern void iSeries_get_boot_time(struct rtc_time *tm);
extern int iSeries_set_rtc_time(unsigned long now);
extern unsigned long iSeries_get_rtc_time(void);
extern int iSeries_set_rtc_time(struct rtc_time *tm);
extern void iSeries_get_rtc_time(struct rtc_time *tm);
extern void iSeries_calibrate_decr(void);
extern void iSeries_progress( char *, unsigned short );
......
......@@ -70,7 +70,7 @@ static void yield_shared_processor(void)
lpaca->next_jiffy_update_tb);
lpaca->yielded = 0; /* Back to IPI's */
locale_irq_enable();
local_irq_enable();
/*
* The decrementer stops during the yield. Force a fake
......@@ -89,16 +89,14 @@ int iSeries_idle(void)
long oldval;
unsigned long CTRL;
/* endless loop with no priority at all */
current->nice = 20;
current->counter = -100;
/* ensure iSeries run light will be out when idle */
current->thread.flags &= ~PPC_FLAG_RUN_LIGHT;
clear_thread_flag(TIF_RUN_LIGHT);
CTRL = mfspr(CTRLF);
CTRL &= ~RUNLATCH;
mtspr(CTRLT, CTRL);
#if 0
init_idle();
#endif
lpaca = get_paca();
......@@ -106,26 +104,29 @@ int iSeries_idle(void)
if (lpaca->xLpPaca.xSharedProc) {
if (ItLpQueue_isLpIntPending(lpaca->lpQueuePtr))
process_iSeries_events();
if (!current->need_resched)
if (!need_resched())
yield_shared_processor();
} else {
/* Avoid an IPI by setting need_resched */
oldval = xchg(&current->need_resched, -1);
oldval = test_and_clear_thread_flag(TIF_NEED_RESCHED);
if (!oldval) {
while(current->need_resched == -1) {
set_thread_flag(TIF_POLLING_NRFLAG);
while (!need_resched()) {
HMT_medium();
if (ItLpQueue_isLpIntPending(lpaca->lpQueuePtr))
process_iSeries_events();
HMT_low();
}
HMT_medium();
clear_thread_flag(TIF_POLLING_NRFLAG);
} else {
set_need_resched();
}
}
HMT_medium();
if (current->need_resched) {
lpaca->xLpPaca.xIdle = 0;
schedule();
check_pgt_cache();
}
}
return 0;
}
......@@ -158,10 +159,11 @@ int default_idle(void)
return 0;
}
#ifdef CONFIG_PPC_PSERIES
int dedicated_idle(void)
{
long oldval;
struct paca_struct *lpaca = get_paca(), *ppaca;;
struct paca_struct *lpaca = get_paca(), *ppaca;
unsigned long start_snooze;
ppaca = &paca[(lpaca->xPacaIndex) ^ 1];
......@@ -274,6 +276,7 @@ int shared_idle(void)
return 0;
}
#endif
int cpu_idle(void)
{
......
......@@ -59,7 +59,6 @@
extern void iSeries_smp_message_recv( struct pt_regs * );
#endif
volatile unsigned char *chrp_int_ack_special;
static void register_irq_proc (unsigned int irq);
irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = {
......@@ -561,17 +560,14 @@ void ppc_irq_dispatch_handler(struct pt_regs *regs, int irq)
spin_unlock(&desc->lock);
}
#ifdef CONFIG_PPC_ISERIES
int do_IRQ(struct pt_regs *regs)
{
int irq, first = 1;
#ifdef CONFIG_PPC_ISERIES
struct paca_struct *lpaca;
struct ItLpQueue *lpq;
#endif
irq_enter();
#ifdef CONFIG_PPC_ISERIES
lpaca = get_paca();
#ifdef CONFIG_SMP
if (lpaca->xLpPaca.xIntDword.xFields.xIpiCnt) {
......@@ -582,7 +578,24 @@ int do_IRQ(struct pt_regs *regs)
lpq = lpaca->lpQueuePtr;
if (lpq && ItLpQueue_isLpIntPending(lpq))
lpEvent_count += ItLpQueue_process(lpq, regs);
#else
irq_exit();
if (lpaca->xLpPaca.xIntDword.xFields.xDecrInt) {
lpaca->xLpPaca.xIntDword.xFields.xDecrInt = 0;
/* Signal a fake decrementer interrupt */
timer_interrupt(regs);
}
return 1; /* lets ret_from_int know we can do checks */
}
#else /* CONFIG_PPC_ISERIES */
int do_IRQ(struct pt_regs *regs)
{
int irq, first = 1;
irq_enter();
/*
* Every arch is required to implement ppc_md.get_irq.
* This function will either return an irq number or -1 to
......@@ -598,20 +611,12 @@ int do_IRQ(struct pt_regs *regs)
if (irq != -2 && first)
/* That's not SMP safe ... but who cares ? */
ppc_spurious_interrupts++;
#endif
irq_exit();
#ifdef CONFIG_PPC_ISERIES
if (lpaca->xLpPaca.xIntDword.xFields.xDecrInt) {
lpaca->xLpPaca.xIntDword.xFields.xDecrInt = 0;
/* Signal a fake decrementer interrupt */
timer_interrupt(regs);
}
#endif
return 1; /* lets ret_from_int know we can do checks */
}
#endif /* CONFIG_PPC_ISERIES */
unsigned long probe_irq_on (void)
{
......@@ -636,9 +641,9 @@ void __init init_IRQ(void)
{
static int once = 0;
if ( once )
if (once)
return;
else
once++;
ppc_md.init_IRQ();
......
This diff is collapsed.
......@@ -66,32 +66,31 @@ _GLOBAL(get_sp)
blr
#ifdef CONFIG_PPC_ISERIES
/* unsigned long __no_use_save_flags(void) */
_GLOBAL(__no_use_save_flags)
#warning FIX ISERIES
mfspr r4,SPRG3
lbz r3,PACAPROCENABLED(r4)
/* unsigned long local_save_flags(void) */
_GLOBAL(local_get_flags)
lbz r3,PACAPROCENABLED(r13)
blr
/* void __no_use_restore_flags(unsigned long flags) */
_GLOBAL(__no_use_restore_flags)
/*
* Just set/clear the MSR_EE bit through restore/flags but do not
* change anything else. This is needed by the RT system and makes
* sense anyway.
* -- Cort
*/
#warning FIX ISERIES
mfspr r6,SPRG3
lbz r5,PACAPROCENABLED(r6)
/* unsigned long local_irq_disable(void) */
_GLOBAL(local_irq_disable)
lbz r3,PACAPROCENABLED(r13)
li r4,0
stb r4,PACAPROCENABLED(r13)
blr /* Done */
/* void local_irq_restore(unsigned long flags) */
_GLOBAL(local_irq_restore)
lbz r5,PACAPROCENABLED(r13)
/* Check if things are setup the way we want _already_. */
cmpw 0,r3,r5
beqlr
/* are we enabling interrupts? */
cmpi 0,r3,0
stb r3,PACAPROCENABLED(r6)
stb r3,PACAPROCENABLED(r13)
beqlr
/* Check pending interrupts */
/* A decrementer, IPI or PMC interrupt may have occurred
* while we were in the hypervisor (which enables) */
CHECKANYINT(r4,r5)
beqlr
......@@ -101,35 +100,8 @@ _GLOBAL(__no_use_restore_flags)
li r0,0x5555
sc
blr
#endif /* CONFIG_PPC_ISERIES */
_GLOBAL(__no_use_cli)
#warning FIX ISERIES
mfspr r5,SPRG3
lbz r3,PACAPROCENABLED(r5)
li r4,0
stb r4,PACAPROCENABLED(r5)
blr /* Done */
_GLOBAL(__no_use_sti)
#warning FIX ISERIES
mfspr r6,SPRG3
li r3,1
stb r3,PACAPROCENABLED(r6)
/* Check for pending interrupts
* A decrementer, IPI or PMC interrupt may have occurred
* while we were in the hypervisor (which enables)
*/
CHECKANYINT(r4,r5)
beqlr
/*
* Handle pending interrupts in interrupt context
*/
li r0,0x5555
sc
blr
#endif
/*
* Flush instruction cache.
*/
......@@ -595,6 +567,10 @@ SYSCALL(dup)
SYSCALL(execve)
SYSCALL(waitpid)
#ifdef CONFIG_PPC_ISERIES /* hack hack hack */
#define ppc_rtas sys_ni_syscall
#endif
/* Why isn't this a) automatic, b) written in 'C'? */
.balign 8
_GLOBAL(sys_call_table32)
......
This diff is collapsed.
......@@ -46,6 +46,7 @@
static void * __init
update_dn_pci_info(struct device_node *dn, void *data)
{
#ifdef CONFIG_PPC_PSERIES
struct pci_controller *phb = (struct pci_controller *)data;
u32 *regs;
char *device_type = get_property(dn, "device_type", 0);
......@@ -64,6 +65,7 @@ update_dn_pci_info(struct device_node *dn, void *data)
dn->devfn = (regs[0] >> 8) & 0xff;
}
}
#endif
return NULL;
}
......@@ -97,6 +99,7 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre, travers
return ret;
for (dn = start->child; dn; dn = nextdn) {
nextdn = NULL;
#ifdef CONFIG_PPC_PSERIES
if (get_property(dn, "class-code", 0)) {
if (pre && (ret = pre(dn, data)) != NULL)
return ret;
......@@ -112,6 +115,7 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre, travers
post(dn, data);
}
}
#endif
if (!nextdn) {
/* Walk up to next valid sibling. */
do {
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -28,10 +28,7 @@
#include <asm/types.h>
#include <asm/ptrace.h>
#include <asm/iSeries/HvTypes.h>
#ifndef _HVCALLEVENT_H
#include <asm/iSeries/HvCallEvent.h>
#endif
//=====================================================================
//
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment