Commit 8752fb78 authored by Anton Blanchard's avatar Anton Blanchard

ppc64: wrap pSeries and iSeries specific code

parent b1c22fd1
......@@ -79,7 +79,7 @@
_stext:
_STATIC(__start)
b .__start_initialization_pSeries
#ifdef CONFIG_PPC_ISERIES
/* At offset 0x20, there is a pointer to iSeries LPAR data.
* This is required by the hypervisor */
. = 0x20
......@@ -90,9 +90,7 @@ _STATIC(__start)
* between physical addresses and absolute addresses) and
* to the pidhash table (also used by the debugger) */
.llong msChunks-KERNELBASE
#ifdef CONFIG_PPC_ISERIES
.llong pidhash-KERNELBASE
#endif
/* Offset 0x38 - Pointer to start of embedded System.map */
.globl embedded_sysmap_start
......@@ -102,6 +100,7 @@ embedded_sysmap_start:
.globl embedded_sysmap_end
embedded_sysmap_end:
.llong 0
#endif
/* Secondary processors spin on this value until it goes to 1. */
.globl __secondary_hold_spinloop
......@@ -365,11 +364,15 @@ __start_interupts:
* point to itVpdAreas. On pSeries native, this value is not used.
*/
. = 0x4000
.globl __end_interupts
.globl __end_interrupts
.globl __start_naca
__end_interupts:
__start_naca:
#ifdef CONFIG_PPC_ISERIES
.llong itVpdAreas
#else
.llong 0x0
#endif
.llong 0x0
.llong 0x0
.llong paca
......@@ -390,6 +393,7 @@ __start_stab:
.globl __end_stab
__end_stab:
#ifdef CONFIG_PPC_ISERIES
/*
* The iSeries LPAR map is at this fixed address
* so that the HvReleaseData structure can address
......@@ -503,7 +507,7 @@ maskable_exception_exit:
mfspr r21,SPRG1
mfspr r20,SPRG2
rfid
#endif
/*
* Data area reserved for FWNMI option.
*/
......@@ -1217,7 +1221,7 @@ _GLOBAL(pseries_secondary_smp_init)
#endif
#endif
b 1b /* Loop until told to go */
#ifdef CONFIG_PPC_ISERIES
_GLOBAL(__start_initialization_iSeries)
LOADADDR(r1,init_thread_union)
......@@ -1241,6 +1245,7 @@ _GLOBAL(__start_initialization_iSeries)
bl .iSeries_fixup_klimit
b .start_here_common
#endif
_GLOBAL(__start_initialization_pSeries)
mr r31,r3 /* save parameters */
......
......@@ -147,6 +147,7 @@ static unsigned long __inline__ count_leading_zeros64( unsigned long x )
return lz;
}
#ifdef CONFIG_PPC_ISERIES
static void tce_build_iSeries(struct TceTable *tbl, long tcenum,
unsigned long uaddr, int direction )
{
......@@ -180,7 +181,9 @@ static void tce_build_iSeries(struct TceTable *tbl, long tcenum,
panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", setTceRc);
}
}
#endif
#ifdef CONFIG_PPC_PSERIES
static void tce_build_pSeries(struct TceTable *tbl, long tcenum,
unsigned long uaddr, int direction )
{
......@@ -199,8 +202,8 @@ static void tce_build_pSeries(struct TceTable *tbl, long tcenum,
tce_addr = ((union Tce *)tbl->base) + tcenum;
*tce_addr = (union Tce)tce.wholeTce;
}
#endif
/*
* Build a TceTable structure. This contains a multi-level bit map which
......@@ -548,6 +551,7 @@ static inline dma_addr_t get_tces( struct TceTable *tbl, unsigned order, void *p
return retTce;
}
#ifdef CONFIG_PPC_ISERIES
static void tce_free_one_iSeries( struct TceTable *tbl, long tcenum )
{
u64 set_tce_rc;
......@@ -560,7 +564,9 @@ static void tce_free_one_iSeries( struct TceTable *tbl, long tcenum )
panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", set_tce_rc);
}
#endif
#ifdef CONFIG_PPC_PSERIES
static void tce_free_one_pSeries( struct TceTable *tbl, long tcenum )
{
union Tce tce;
......@@ -572,6 +578,7 @@ static void tce_free_one_pSeries( struct TceTable *tbl, long tcenum )
*tce_addr = (union Tce)tce.wholeTce;
}
#endif
static void tce_free(struct TceTable *tbl, dma_addr_t dma_addr,
unsigned order, unsigned num_pages)
......@@ -609,6 +616,7 @@ static void tce_free(struct TceTable *tbl, dma_addr_t dma_addr,
free_tce_range( tbl, free_tce, order );
}
#ifdef CONFIG_PPC_ISERIES
void __init create_virtual_bus_tce_table(void)
{
struct TceTable *t;
......@@ -661,6 +669,7 @@ void __init create_virtual_bus_tce_table(void)
}
else printk( "Virtual Bus VIO TCE table failed.\n");
}
#endif
void create_tce_tables_for_buses(struct list_head *bus_list)
{
......@@ -842,6 +851,7 @@ static struct TceTable* findHwTceTable(struct TceTable * newTceTable )
static void getTceTableParmsiSeries(struct iSeries_Device_Node* DevNode,
struct TceTable* newTceTable )
{
#ifdef CONFIG_PPC_ISERIES
struct TceTableManagerCB* pciBusTceTableParms = (struct TceTableManagerCB*)kmalloc( sizeof(struct TceTableManagerCB), GFP_KERNEL );
if(pciBusTceTableParms == NULL) panic("PCI_DMA: TCE Table Allocation failed.");
......@@ -872,6 +882,7 @@ static void getTceTableParmsiSeries(struct iSeries_Device_Node* DevNode,
newTceTable->tceType = TCE_PCI;
kfree(pciBusTceTableParms);
#endif
}
static void getTceTableParmsPSeries(struct pci_controller *phb,
......@@ -1440,15 +1451,19 @@ void pci_unmap_sg(struct pci_dev *pdev, struct scatterlist *sglist, int nelems,
}
#endif
#ifdef CONFIG_PPC_PSERIES
/* These are called very early. */
void tce_init_pSeries(void)
{
ppc_md.tce_build = tce_build_pSeries;
ppc_md.tce_free_one = tce_free_one_pSeries;
}
#endif
#ifdef CONFIG_PPC_ISERIES
void tce_init_iSeries(void)
{
ppc_md.tce_build = tce_build_iSeries;
ppc_md.tce_free_one = tce_free_one_iSeries;
}
#endif
......@@ -1060,9 +1060,11 @@ prom_init(unsigned long r3, unsigned long r4, unsigned long pp,
/* Default machine type. */
_naca->platform = PLATFORM_PSERIES;
#if 0
/* Reset klimit to take into account the embedded system map */
if (RELOC(embedded_sysmap_end))
RELOC(klimit) = __va(PAGE_ALIGN(RELOC(embedded_sysmap_end)));
#endif
/* Get a handle to the prom entry point before anything else */
_prom->entry = pp;
......
......@@ -257,6 +257,7 @@ static int rtc_read_proc(char *page, char **start, off_t off,
return len;
}
#ifdef CONFIG_PPC_ISERIES
/*
* Get the RTC from the virtual service processor
* This requires flowing LpEvents to the primary partition
......@@ -270,60 +271,6 @@ void iSeries_get_rtc_time(struct rtc_time *rtc_tm)
rtc_tm->tm_mon--;
}
void pSeries_get_rtc_time(struct rtc_time *rtc_tm)
{
unsigned long ret[8];
int error;
int count;
/*
* error -2 is clock busy, we keep retrying a few times to see
* if it will come good -- paulus
*/
count = 0;
do {
error = rtas_call(rtas_token("get-time-of-day"), 0, 8, (void *)&ret);
} while (error == -2 && ++count < 1000);
if (error != 0) {
printk(KERN_WARNING "error: reading the clock failed (%d)\n",
error);
return;
}
rtc_tm->tm_sec = ret[5];
rtc_tm->tm_min = ret[4];
rtc_tm->tm_hour = ret[3];
rtc_tm->tm_mday = ret[2];
rtc_tm->tm_mon = ret[1] - 1;
rtc_tm->tm_year = ret[0] - 1900;
}
int pSeries_set_rtc_time(struct rtc_time *tm)
{
int error;
int count;
/*
* error -2 is clock busy, we keep retrying a few times to see
* if it will come good -- paulus
*/
count = 0;
do {
error = rtas_call(rtas_token("set-time-of-day"), 7, 1, NULL,
tm->tm_year + 1900, tm->tm_mon + 1,
tm->tm_mday, tm->tm_hour, tm->tm_min,
tm->tm_sec, 0);
} while (error == -2 && ++count < 1000);
if (error != 0)
printk(KERN_WARNING "error: setting the clock failed (%d)\n",
error);
return 0;
}
/*
* Set the RTC in the virtual service processor
* This requires flowing LpEvents to the primary partition
......@@ -379,3 +326,59 @@ void iSeries_get_boot_time(struct rtc_time *tm)
tm->tm_year -= 1900;
tm->tm_mon -= 1;
}
#endif
#ifdef CONFIG_PPC_PSERIES
void pSeries_get_rtc_time(struct rtc_time *rtc_tm)
{
unsigned long ret[8];
int error;
int count;
/*
* error -2 is clock busy, we keep retrying a few times to see
* if it will come good -- paulus
*/
count = 0;
do {
error = rtas_call(rtas_token("get-time-of-day"), 0, 8, (void *)&ret);
} while (error == -2 && ++count < 1000);
if (error != 0) {
printk(KERN_WARNING "error: reading the clock failed (%d)\n",
error);
return;
}
rtc_tm->tm_sec = ret[5];
rtc_tm->tm_min = ret[4];
rtc_tm->tm_hour = ret[3];
rtc_tm->tm_mday = ret[2];
rtc_tm->tm_mon = ret[1] - 1;
rtc_tm->tm_year = ret[0] - 1900;
}
int pSeries_set_rtc_time(struct rtc_time *tm)
{
int error;
int count;
/*
* error -2 is clock busy, we keep retrying a few times to see
* if it will come good -- paulus
*/
count = 0;
do {
error = rtas_call(rtas_token("set-time-of-day"), 7, 1, NULL,
tm->tm_year + 1900, tm->tm_mon + 1,
tm->tm_mday, tm->tm_hour, tm->tm_min,
tm->tm_sec, 0);
} while (error == -2 && ++count < 1000);
if (error != 0)
printk(KERN_WARNING "error: setting the clock failed (%d)\n",
error);
return 0;
}
#endif
......@@ -153,14 +153,18 @@ void setup_system(unsigned long r3, unsigned long r4, unsigned long r5,
debugger_dabr_match = xmon_dabr_match;
#endif
#ifdef CONFIG_PPC_ISERIES
/* pSeries systems are identified in prom.c via OF. */
if ( itLpNaca.xLparInstalled == 1 )
naca->platform = PLATFORM_ISERIES_LPAR;
#endif
switch (naca->platform) {
#ifdef CONFIG_PPC_ISERIES
case PLATFORM_ISERIES_LPAR:
iSeries_init_early();
break;
#endif
#ifdef CONFIG_PPC_PSERIES
case PLATFORM_PSERIES:
......@@ -215,9 +219,11 @@ void setup_system(unsigned long r3, unsigned long r4, unsigned long r5,
mm_init_ppc64();
switch (naca->platform) {
#ifdef CONFIG_PPC_ISERIES
case PLATFORM_ISERIES_LPAR:
iSeries_init();
break;
#endif
default:
/* The following relies on the device tree being */
/* fully configured. */
......
......@@ -86,6 +86,7 @@ static inline void set_tb(unsigned int upper, unsigned int lower)
mttbl(lower);
}
#ifdef CONFIG_PPC_ISERIES
void iSeries_smp_message_recv( struct pt_regs * regs )
{
int cpu = smp_processor_id();
......@@ -117,7 +118,6 @@ static void smp_iSeries_message_pass(int target, int msg, unsigned long data, in
}
}
#ifdef CONFIG_PPC_ISERIES
static int smp_iSeries_numProcs(void)
{
unsigned np, i;
......@@ -132,7 +132,6 @@ static int smp_iSeries_numProcs(void)
}
return np;
}
#endif
static int smp_iSeries_probe(void)
{
......@@ -189,13 +188,12 @@ void __init smp_init_iSeries(void)
smp_ops->probe = smp_iSeries_probe;
smp_ops->kick_cpu = smp_iSeries_kick_cpu;
smp_ops->setup_cpu = smp_iSeries_setup_cpu;
#ifdef CONFIG_PPC_ISERIES
#warning fix for iseries
naca->processorCount = smp_iSeries_numProcs();
#endif
}
#endif
#ifdef CONFIG_PPC_PSERIES
static void
smp_openpic_message_pass(int target, int msg, unsigned long data, int wait)
{
......@@ -257,6 +255,7 @@ smp_kick_cpu(int nr)
*/
paca[nr].xProcStart = 1;
}
#endif
static void __init smp_space_timers(unsigned int max_cpus)
{
......@@ -273,6 +272,7 @@ static void __init smp_space_timers(unsigned int max_cpus)
}
}
#ifdef CONFIG_PPC_PSERIES
static void __devinit pSeries_setup_cpu(int cpu)
{
if (OpenPIC_Addr) {
......@@ -361,6 +361,7 @@ void __init smp_init_pSeries(void)
smp_ops->kick_cpu = smp_kick_cpu;
smp_ops->setup_cpu = pSeries_setup_cpu;
}
#endif
void smp_local_timer_interrupt(struct pt_regs * regs)
{
......
......@@ -301,9 +301,11 @@ int timer_interrupt(struct pt_regs * regs)
next_dec = lpaca->default_decr;
set_dec(next_dec);
#ifdef CONFIG_PPC_ISERIES
lpq = lpaca->lpQueuePtr;
if (lpq && ItLpQueue_isLpIntPending(lpq))
lpEvent_count += ItLpQueue_process(lpq, regs);
#endif
irq_exit();
......@@ -458,9 +460,11 @@ void __init time_init(void)
ppc_md.calibrate_decr();
if ( ! piranha_simulator ) {
#ifdef CONFIG_PPC_ISERIES
if (!piranha_simulator)
#endif
ppc_md.get_boot_time(&tm);
}
write_lock_irqsave(&xtime_lock, flags);
xtime.tv_sec = mktime(tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
tm.tm_hour, tm.tm_min, tm.tm_sec);
......
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