[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [XEN][POWERPC] SCOM access is fully known and working
# HG changeset patch # User Jimi Xenidis <jimix@xxxxxxxxxxxxxx> # Node ID 8cb0d0eea35568f776574e69800448b04447a0b9 # Parent 776efe262006e07e44de3ab5355a07dee1b70994 [XEN][POWERPC] SCOM access is fully known and working Signed-off-by: Jimi Xenidis <jimix@xxxxxxxxxxxxxx> Signed-off-by: Hollis Blanchard <hollisb@xxxxxxxxxx> --- xen/arch/powerpc/powerpc64/ppc970_scom.c | 151 +++++++++++++++++++++---------- 1 files changed, 104 insertions(+), 47 deletions(-) diff -r 776efe262006 -r 8cb0d0eea355 xen/arch/powerpc/powerpc64/ppc970_scom.c --- a/xen/arch/powerpc/powerpc64/ppc970_scom.c Mon Sep 18 17:47:10 2006 -0400 +++ b/xen/arch/powerpc/powerpc64/ppc970_scom.c Thu Sep 21 07:36:17 2006 -0400 @@ -22,33 +22,13 @@ #include <xen/types.h> #include <xen/lib.h> #include <xen/console.h> +#include <xen/errno.h> +#include <asm/delay.h> #define SPRN_SCOMC 276 #define SPRN_SCOMD 277 - -static inline void mtscomc(ulong scomc) -{ - __asm__ __volatile__ ("mtspr %1, %0" : : "r" (scomc), "i"(SPRN_SCOMC)); -} - -static inline ulong mfscomc(void) -{ - ulong scomc; - __asm__ __volatile__ ("mfspr %0, %1" : "=r" (scomc): "i"(SPRN_SCOMC)); - return scomc; -} - -static inline void mtscomd(ulong scomd) -{ - __asm__ __volatile__ ("mtspr %1, %0" : : "r" (scomd), "i"(SPRN_SCOMD)); -} - -static inline ulong mfscomd(void) -{ - ulong scomd; - __asm__ __volatile__ ("mfspr %0, %1" : "=r" (scomd): "i"(SPRN_SCOMD)); - return scomd; -} +#define SCOMC_READ 1 +#define SCOMC_WRITE (!(SCOMC_READ)) union scomc { struct scomc_bits { @@ -68,50 +48,127 @@ union scomc { }; -static inline ulong read_scom(ulong addr) +static inline int read_scom(uint addr, ulong *d) { union scomc c; - ulong d; + ulong flags; - c.word = 0; - c.bits.addr = addr; - c.bits.RW = 0; + /* drop the low 8bits (including parity) */ + addr >>= 8; - mtscomc(c.word); - d = mfscomd(); - c.word = mfscomc(); - if (c.bits.failure) - panic("scom status: 0x%016lx\n", c.word); + /* these give iface errors because the address is ambiguous after + * the above bit dropping */ + BUG_ON(addr == 0x8000); - return d; + for (;;) { + c.word = 0; + c.bits.addr = addr; + c.bits.RW = SCOMC_READ; + + local_irq_save(flags); + asm volatile ( + "sync \n\t" + "mtspr %2, %0 \n\t" + "isync \n\t" + "mfspr %1, %3 \n\t" + "isync \n\t" + "mfspr %0, %2 \n\t" + "isync \n\t" + : "+r" (c.word), "=r" (*d) + : "i"(SPRN_SCOMC), "i"(SPRN_SCOMD)); + + local_irq_restore(flags); + /* WARNING! older 970s (pre FX) shift the bits right 1 position */ + + if (!c.bits.failure) + return 0; + + /* deal with errors */ + /* has SCOM been disabled? */ + if (c.bits.disabled) + return -ENOSYS; + + /* we were passed a bad addr return -1 */ + if (c.bits.addr_error) + return -EINVAL; + + /* this is way bad and we will checkstop soon */ + BUG_ON(c.bits.proto_error); + + if (c.bits.iface_error) + udelay(10); + } } -static inline void write_scom(ulong addr, ulong val) +static inline int write_scom(uint addr, ulong d) { union scomc c; + ulong flags; - c.word = 0; - c.bits.addr = addr; - c.bits.RW = 1; + /* drop the low 8bits (including parity) */ + addr >>= 8; - mtscomd(val); - mtscomc(c.word); - c.word = mfscomc(); - if (c.bits.failure) - panic("scom status: 0x%016lx\n", c.word); + /* these give iface errors because the address is ambiguous after + * the above bit dropping */ + BUG_ON(addr == 0x8000); + + for (;;) { + c.word = 0; + c.bits.addr = addr; + c.bits.RW = SCOMC_WRITE; + + local_irq_save(flags); + asm volatile( + "sync \n\t" + "mtspr %3, %1 \n\t" + "isync \n\t" + "mtspr %2, %0 \n\t" + "isync \n\t" + "mfspr %0, %2 \n\t" + "isync \n\t" + : "+r" (c.word) + : "r" (d), "i"(SPRN_SCOMC), "i"(SPRN_SCOMD)); + local_irq_restore(flags); + + if (!c.bits.failure) + return 0; + + /* has SCOM been disabled? */ + if (c.bits.disabled) + return -ENOSYS; + + /* we were passed a bad addr return -1 */ + if (c.bits.addr_error) + return -EINVAL; + + /* this is way bad and we will checkstop soon */ + BUG_ON(c.bits.proto_error); + + /* check for iface and retry */ + if (c.bits.iface_error) + udelay(10); + } } +/* SCOMC addresses are 16bit but we are given 24 bits in the + * books. The low oerder 8 bits are some kinda parity thin and should + * be ignored */ #define SCOM_AMCS_REG 0x022601 #define SCOM_AMCS_AND_MASK 0x022700 #define SCOM_AMCS_OR_MASK 0x022800 #define SCOM_CMCE 0x030901 #define SCOM_PMCR 0x400801 +#define SCOM_PTSR 0x408001 + +/* cannot access these since only top 16bits are considered */ +#define SCOM_STATUS 0x800003 void cpu_scom_init(void) { -#ifdef not_yet + ulong val; console_start_sync(); - printk("scom PMCR: 0x%016lx\n", read_scom(SCOM_PMCR)); + if (!read_scom(SCOM_PTSR, &val)) + printk("SCOM PTSR: 0x%016lx\n", val); + console_end_sync(); -#endif } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |