source: trunk/packages/xen-3.1/xen-3.1/xen/arch/powerpc/powerpc64/ppc970_scom.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 18 years ago

Add xen and xen-common

File size: 4.5 KB
Line 
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
15 *
16 * Copyright (C) IBM Corp. 2006
17 *
18 * Authors: Jimi Xenidis <jimix@watson.ibm.com>
19 */
20
21#include <xen/config.h>
22#include <xen/types.h>
23#include <xen/lib.h>
24#include <xen/console.h>
25#include <xen/errno.h>
26#include <asm/delay.h>
27#include <asm/processor.h>
28#include "scom.h"
29
30#undef CONFIG_SCOM
31
32#define SPRN_SCOMC 276
33#define SPRN_SCOMD 277
34#define SCOMC_READ 1
35#define SCOMC_WRITE (!(SCOMC_READ))
36
37union scomc {
38    struct scomc_bits {
39        ulong _reserved_0_31: 32;
40        ulong addr:           16;
41        ulong RW:              1;
42        ulong _reserved_49_55: 7;
43        ulong _reserved_56:    1;
44        ulong proto_error:     1;
45        ulong addr_error:      1;
46        ulong iface_error:     1;
47        ulong disabled:        1;
48        ulong _reserved_61_62: 2;
49        ulong failure:         1;
50    } bits;
51    ulong word;
52};
53
54
55int cpu_scom_read(uint addr, ulong *d)
56{
57    union scomc c;
58    ulong flags;
59
60    /* drop the low 8bits (including parity) */
61    addr >>= 8;
62
63    /* these give iface errors because the addresses are not software
64     * accessible */
65    BUG_ON(addr & 0x8000);
66
67    for (;;) {
68        c.word = 0;
69        c.bits.addr = addr;
70        c.bits.RW = SCOMC_READ;
71
72        local_irq_save(flags);
73        asm volatile (
74            "sync         \n\t"
75            "mtspr %2, %0 \n\t"
76            "isync        \n\t"
77            "mfspr %1, %3 \n\t"
78            "isync        \n\t"
79            "mfspr %0, %2 \n\t"
80            "isync        \n\t"
81            : "+r" (c.word), "=r" (*d)
82            : "i"(SPRN_SCOMC), "i"(SPRN_SCOMD));
83
84        local_irq_restore(flags);
85        /* WARNING! older 970s (pre FX) shift the bits right 1 position */
86
87        if (!c.bits.failure)
88            return 0;
89
90        /* deal with errors */
91        /* has SCOM been disabled? */
92        if (c.bits.disabled)
93            return -ENOSYS;
94
95        /* we were passed a bad addr return -1 */
96        if (c.bits.addr_error)
97            return -EINVAL;
98
99        /* this is way bad and we will checkstop soon */
100        BUG_ON(c.bits.proto_error);
101
102        if (c.bits.iface_error)
103            udelay(10);
104    }
105}
106
107int cpu_scom_write(uint addr, ulong d)
108{
109    union scomc c;
110    ulong flags;
111
112    /* drop the low 8bits (including parity) */
113    addr >>= 8;
114
115    /* these give iface errors because the addresses are not software
116     * accessible */
117    BUG_ON(addr & 0x8000);
118
119    for (;;) {
120        c.word = 0;
121        c.bits.addr = addr;
122        c.bits.RW = SCOMC_WRITE;
123
124        local_irq_save(flags);
125        asm volatile(
126            "sync         \n\t"
127            "mtspr %3, %1 \n\t"
128            "isync        \n\t"
129            "mtspr %2, %0 \n\t"
130            "isync        \n\t"
131            "mfspr %0, %2 \n\t"
132            "isync        \n\t"
133            : "+r" (c.word)
134            : "r" (d), "i"(SPRN_SCOMC), "i"(SPRN_SCOMD));
135        local_irq_restore(flags);
136
137        if (!c.bits.failure)
138            return 0;
139
140        /* has SCOM been disabled? */
141        if (c.bits.disabled)
142            return -ENOSYS;
143
144        /* we were passed a bad addr return -1 */
145        if (c.bits.addr_error)
146            return -EINVAL;
147
148        /* this is way bad and we will checkstop soon */
149        BUG_ON(c.bits.proto_error);
150
151        /* check for iface and retry */
152        if (c.bits.iface_error)
153            udelay(10);
154    }
155}
156
157void cpu_scom_init(void)
158{
159#ifdef CONFIG_SCOM
160    ulong val;
161    if (PVR_REV(mfpvr()) == PV_970FX) {
162        /* these address are only good for 970FX */
163        console_start_sync();
164        if (!cpu_scom_read(SCOM_PTSR, &val))
165            printk("SCOM PTSR: 0x%016lx\n", val);
166
167        console_end_sync();
168    }
169#endif
170}
171
172void cpu_scom_AMCR(void)
173{
174#ifdef CONFIG_SCOM
175    ulong val;
176
177    if (PVR_REV(mfpvr()) == PV_970FX) {
178        /* these address are only good for 970FX */
179        cpu_scom_read(SCOM_AMC_REG, &val);
180        printk("SCOM AMCR: 0x%016lx\n", val);
181    }
182#endif
183}
184
Note: See TracBrowser for help on using the repository browser.