mirror of https://gitee.com/openkylin/linux.git
Merge branch 'master' into upstream
Conflicts: net/ieee80211/ieee80211_crypt_tkip.c net/ieee80211/ieee80211_crypt_wep.c
This commit is contained in:
commit
28eb177dfa
|
@ -19,15 +19,14 @@ At the lowest level are algorithms, which register dynamically with the
|
||||||
API.
|
API.
|
||||||
|
|
||||||
'Transforms' are user-instantiated objects, which maintain state, handle all
|
'Transforms' are user-instantiated objects, which maintain state, handle all
|
||||||
of the implementation logic (e.g. manipulating page vectors), provide an
|
of the implementation logic (e.g. manipulating page vectors) and provide an
|
||||||
abstraction to the underlying algorithms, and handle common logical
|
abstraction to the underlying algorithms. However, at the user
|
||||||
operations (e.g. cipher modes, HMAC for digests). However, at the user
|
|
||||||
level they are very simple.
|
level they are very simple.
|
||||||
|
|
||||||
Conceptually, the API layering looks like this:
|
Conceptually, the API layering looks like this:
|
||||||
|
|
||||||
[transform api] (user interface)
|
[transform api] (user interface)
|
||||||
[transform ops] (per-type logic glue e.g. cipher.c, digest.c)
|
[transform ops] (per-type logic glue e.g. cipher.c, compress.c)
|
||||||
[algorithm api] (for registering algorithms)
|
[algorithm api] (for registering algorithms)
|
||||||
|
|
||||||
The idea is to make the user interface and algorithm registration API
|
The idea is to make the user interface and algorithm registration API
|
||||||
|
@ -44,22 +43,27 @@ under development.
|
||||||
Here's an example of how to use the API:
|
Here's an example of how to use the API:
|
||||||
|
|
||||||
#include <linux/crypto.h>
|
#include <linux/crypto.h>
|
||||||
|
#include <linux/err.h>
|
||||||
|
#include <linux/scatterlist.h>
|
||||||
|
|
||||||
struct scatterlist sg[2];
|
struct scatterlist sg[2];
|
||||||
char result[128];
|
char result[128];
|
||||||
struct crypto_tfm *tfm;
|
struct crypto_hash *tfm;
|
||||||
|
struct hash_desc desc;
|
||||||
|
|
||||||
tfm = crypto_alloc_tfm("md5", 0);
|
tfm = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);
|
||||||
if (tfm == NULL)
|
if (IS_ERR(tfm))
|
||||||
fail();
|
fail();
|
||||||
|
|
||||||
/* ... set up the scatterlists ... */
|
/* ... set up the scatterlists ... */
|
||||||
|
|
||||||
crypto_digest_init(tfm);
|
desc.tfm = tfm;
|
||||||
crypto_digest_update(tfm, &sg, 2);
|
desc.flags = 0;
|
||||||
crypto_digest_final(tfm, result);
|
|
||||||
|
|
||||||
crypto_free_tfm(tfm);
|
if (crypto_hash_digest(&desc, &sg, 2, result))
|
||||||
|
fail();
|
||||||
|
|
||||||
|
crypto_free_hash(tfm);
|
||||||
|
|
||||||
|
|
||||||
Many real examples are available in the regression test module (tcrypt.c).
|
Many real examples are available in the regression test module (tcrypt.c).
|
||||||
|
@ -126,7 +130,7 @@ might already be working on.
|
||||||
BUGS
|
BUGS
|
||||||
|
|
||||||
Send bug reports to:
|
Send bug reports to:
|
||||||
James Morris <jmorris@redhat.com>
|
Herbert Xu <herbert@gondor.apana.org.au>
|
||||||
Cc: David S. Miller <davem@redhat.com>
|
Cc: David S. Miller <davem@redhat.com>
|
||||||
|
|
||||||
|
|
||||||
|
@ -134,13 +138,14 @@ FURTHER INFORMATION
|
||||||
|
|
||||||
For further patches and various updates, including the current TODO
|
For further patches and various updates, including the current TODO
|
||||||
list, see:
|
list, see:
|
||||||
http://samba.org/~jamesm/crypto/
|
http://gondor.apana.org.au/~herbert/crypto/
|
||||||
|
|
||||||
|
|
||||||
AUTHORS
|
AUTHORS
|
||||||
|
|
||||||
James Morris
|
James Morris
|
||||||
David S. Miller
|
David S. Miller
|
||||||
|
Herbert Xu
|
||||||
|
|
||||||
|
|
||||||
CREDITS
|
CREDITS
|
||||||
|
@ -238,8 +243,11 @@ Anubis algorithm contributors:
|
||||||
Tiger algorithm contributors:
|
Tiger algorithm contributors:
|
||||||
Aaron Grothe
|
Aaron Grothe
|
||||||
|
|
||||||
|
VIA PadLock contributors:
|
||||||
|
Michal Ludvig
|
||||||
|
|
||||||
Generic scatterwalk code by Adam J. Richter <adam@yggdrasil.com>
|
Generic scatterwalk code by Adam J. Richter <adam@yggdrasil.com>
|
||||||
|
|
||||||
Please send any credits updates or corrections to:
|
Please send any credits updates or corrections to:
|
||||||
James Morris <jmorris@redhat.com>
|
Herbert Xu <herbert@gondor.apana.org.au>
|
||||||
|
|
||||||
|
|
25
MAINTAINERS
25
MAINTAINERS
|
@ -298,6 +298,14 @@ L: info-linux@geode.amd.com
|
||||||
W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html
|
W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_2452_11363,00.html
|
||||||
S: Supported
|
S: Supported
|
||||||
|
|
||||||
|
AMSO1100 RNIC DRIVER
|
||||||
|
P: Tom Tucker
|
||||||
|
M: tom@opengridcomputing.com
|
||||||
|
P: Steve Wise
|
||||||
|
M: swise@opengridcomputing.com
|
||||||
|
L: openib-general@openib.org
|
||||||
|
S: Maintained
|
||||||
|
|
||||||
AOA (Apple Onboard Audio) ALSA DRIVER
|
AOA (Apple Onboard Audio) ALSA DRIVER
|
||||||
P: Johannes Berg
|
P: Johannes Berg
|
||||||
M: johannes@sipsolutions.net
|
M: johannes@sipsolutions.net
|
||||||
|
@ -991,6 +999,14 @@ EFS FILESYSTEM
|
||||||
W: http://aeschi.ch.eu.org/efs/
|
W: http://aeschi.ch.eu.org/efs/
|
||||||
S: Orphan
|
S: Orphan
|
||||||
|
|
||||||
|
EHCA (IBM GX bus InfiniBand adapter) DRIVER:
|
||||||
|
P: Hoang-Nam Nguyen
|
||||||
|
M: hnguyen@de.ibm.com
|
||||||
|
P: Christoph Raisch
|
||||||
|
M: raisch@de.ibm.com
|
||||||
|
L: openib-general@openib.org
|
||||||
|
S: Supported
|
||||||
|
|
||||||
EMU10K1 SOUND DRIVER
|
EMU10K1 SOUND DRIVER
|
||||||
P: James Courtier-Dutton
|
P: James Courtier-Dutton
|
||||||
M: James@superbug.demon.co.uk
|
M: James@superbug.demon.co.uk
|
||||||
|
@ -1783,6 +1799,13 @@ W: http://www.penguinppc.org/
|
||||||
L: linuxppc-embedded@ozlabs.org
|
L: linuxppc-embedded@ozlabs.org
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
LINUX FOR POWERPC PA SEMI PWRFICIENT
|
||||||
|
P: Olof Johansson
|
||||||
|
M: olof@lixom.net
|
||||||
|
W: http://www.pasemi.com/
|
||||||
|
L: linuxppc-dev@ozlabs.org
|
||||||
|
S: Supported
|
||||||
|
|
||||||
LLC (802.2)
|
LLC (802.2)
|
||||||
P: Arnaldo Carvalho de Melo
|
P: Arnaldo Carvalho de Melo
|
||||||
M: acme@conectiva.com.br
|
M: acme@conectiva.com.br
|
||||||
|
@ -2451,6 +2474,8 @@ S: Maintained
|
||||||
S390
|
S390
|
||||||
P: Martin Schwidefsky
|
P: Martin Schwidefsky
|
||||||
M: schwidefsky@de.ibm.com
|
M: schwidefsky@de.ibm.com
|
||||||
|
P: Heiko Carstens
|
||||||
|
M: heiko.carstens@de.ibm.com
|
||||||
M: linux390@de.ibm.com
|
M: linux390@de.ibm.com
|
||||||
L: linux-390@vm.marist.edu
|
L: linux-390@vm.marist.edu
|
||||||
W: http://www.ibm.com/developerworks/linux/linux390/
|
W: http://www.ibm.com/developerworks/linux/linux390/
|
||||||
|
|
|
@ -5,5 +5,8 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o
|
obj-$(CONFIG_CRYPTO_AES_586) += aes-i586.o
|
||||||
|
obj-$(CONFIG_CRYPTO_TWOFISH_586) += twofish-i586.o
|
||||||
|
|
||||||
aes-i586-y := aes-i586-asm.o aes.o
|
aes-i586-y := aes-i586-asm.o aes.o
|
||||||
|
twofish-i586-y := twofish-i586-asm.o twofish.o
|
||||||
|
|
||||||
|
|
|
@ -379,12 +379,13 @@ static void gen_tabs(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
|
static int aes_set_key(struct crypto_tfm *tfm, const u8 *in_key,
|
||||||
unsigned int key_len, u32 *flags)
|
unsigned int key_len)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
u32 ss[8];
|
u32 ss[8];
|
||||||
struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
|
struct aes_ctx *ctx = crypto_tfm_ctx(tfm);
|
||||||
const __le32 *key = (const __le32 *)in_key;
|
const __le32 *key = (const __le32 *)in_key;
|
||||||
|
u32 *flags = &tfm->crt_flags;
|
||||||
|
|
||||||
/* encryption schedule */
|
/* encryption schedule */
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,335 @@
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2006 by Joachim Fritschi, <jfritschi@freenet.de> *
|
||||||
|
* *
|
||||||
|
* 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. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
.file "twofish-i586-asm.S"
|
||||||
|
.text
|
||||||
|
|
||||||
|
#include <asm/asm-offsets.h>
|
||||||
|
|
||||||
|
/* return adress at 0 */
|
||||||
|
|
||||||
|
#define in_blk 12 /* input byte array address parameter*/
|
||||||
|
#define out_blk 8 /* output byte array address parameter*/
|
||||||
|
#define tfm 4 /* Twofish context structure */
|
||||||
|
|
||||||
|
#define a_offset 0
|
||||||
|
#define b_offset 4
|
||||||
|
#define c_offset 8
|
||||||
|
#define d_offset 12
|
||||||
|
|
||||||
|
/* Structure of the crypto context struct*/
|
||||||
|
|
||||||
|
#define s0 0 /* S0 Array 256 Words each */
|
||||||
|
#define s1 1024 /* S1 Array */
|
||||||
|
#define s2 2048 /* S2 Array */
|
||||||
|
#define s3 3072 /* S3 Array */
|
||||||
|
#define w 4096 /* 8 whitening keys (word) */
|
||||||
|
#define k 4128 /* key 1-32 ( word ) */
|
||||||
|
|
||||||
|
/* define a few register aliases to allow macro substitution */
|
||||||
|
|
||||||
|
#define R0D %eax
|
||||||
|
#define R0B %al
|
||||||
|
#define R0H %ah
|
||||||
|
|
||||||
|
#define R1D %ebx
|
||||||
|
#define R1B %bl
|
||||||
|
#define R1H %bh
|
||||||
|
|
||||||
|
#define R2D %ecx
|
||||||
|
#define R2B %cl
|
||||||
|
#define R2H %ch
|
||||||
|
|
||||||
|
#define R3D %edx
|
||||||
|
#define R3B %dl
|
||||||
|
#define R3H %dh
|
||||||
|
|
||||||
|
|
||||||
|
/* performs input whitening */
|
||||||
|
#define input_whitening(src,context,offset)\
|
||||||
|
xor w+offset(context), src;
|
||||||
|
|
||||||
|
/* performs input whitening */
|
||||||
|
#define output_whitening(src,context,offset)\
|
||||||
|
xor w+16+offset(context), src;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* a input register containing a (rotated 16)
|
||||||
|
* b input register containing b
|
||||||
|
* c input register containing c
|
||||||
|
* d input register containing d (already rol $1)
|
||||||
|
* operations on a and b are interleaved to increase performance
|
||||||
|
*/
|
||||||
|
#define encrypt_round(a,b,c,d,round)\
|
||||||
|
push d ## D;\
|
||||||
|
movzx b ## B, %edi;\
|
||||||
|
mov s1(%ebp,%edi,4),d ## D;\
|
||||||
|
movzx a ## B, %edi;\
|
||||||
|
mov s2(%ebp,%edi,4),%esi;\
|
||||||
|
movzx b ## H, %edi;\
|
||||||
|
ror $16, b ## D;\
|
||||||
|
xor s2(%ebp,%edi,4),d ## D;\
|
||||||
|
movzx a ## H, %edi;\
|
||||||
|
ror $16, a ## D;\
|
||||||
|
xor s3(%ebp,%edi,4),%esi;\
|
||||||
|
movzx b ## B, %edi;\
|
||||||
|
xor s3(%ebp,%edi,4),d ## D;\
|
||||||
|
movzx a ## B, %edi;\
|
||||||
|
xor (%ebp,%edi,4), %esi;\
|
||||||
|
movzx b ## H, %edi;\
|
||||||
|
ror $15, b ## D;\
|
||||||
|
xor (%ebp,%edi,4), d ## D;\
|
||||||
|
movzx a ## H, %edi;\
|
||||||
|
xor s1(%ebp,%edi,4),%esi;\
|
||||||
|
pop %edi;\
|
||||||
|
add d ## D, %esi;\
|
||||||
|
add %esi, d ## D;\
|
||||||
|
add k+round(%ebp), %esi;\
|
||||||
|
xor %esi, c ## D;\
|
||||||
|
rol $15, c ## D;\
|
||||||
|
add k+4+round(%ebp),d ## D;\
|
||||||
|
xor %edi, d ## D;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* a input register containing a (rotated 16)
|
||||||
|
* b input register containing b
|
||||||
|
* c input register containing c
|
||||||
|
* d input register containing d (already rol $1)
|
||||||
|
* operations on a and b are interleaved to increase performance
|
||||||
|
* last round has different rotations for the output preparation
|
||||||
|
*/
|
||||||
|
#define encrypt_last_round(a,b,c,d,round)\
|
||||||
|
push d ## D;\
|
||||||
|
movzx b ## B, %edi;\
|
||||||
|
mov s1(%ebp,%edi,4),d ## D;\
|
||||||
|
movzx a ## B, %edi;\
|
||||||
|
mov s2(%ebp,%edi,4),%esi;\
|
||||||
|
movzx b ## H, %edi;\
|
||||||
|
ror $16, b ## D;\
|
||||||
|
xor s2(%ebp,%edi,4),d ## D;\
|
||||||
|
movzx a ## H, %edi;\
|
||||||
|
ror $16, a ## D;\
|
||||||
|
xor s3(%ebp,%edi,4),%esi;\
|
||||||
|
movzx b ## B, %edi;\
|
||||||
|
xor s3(%ebp,%edi,4),d ## D;\
|
||||||
|
movzx a ## B, %edi;\
|
||||||
|
xor (%ebp,%edi,4), %esi;\
|
||||||
|
movzx b ## H, %edi;\
|
||||||
|
ror $16, b ## D;\
|
||||||
|
xor (%ebp,%edi,4), d ## D;\
|
||||||
|
movzx a ## H, %edi;\
|
||||||
|
xor s1(%ebp,%edi,4),%esi;\
|
||||||
|
pop %edi;\
|
||||||
|
add d ## D, %esi;\
|
||||||
|
add %esi, d ## D;\
|
||||||
|
add k+round(%ebp), %esi;\
|
||||||
|
xor %esi, c ## D;\
|
||||||
|
ror $1, c ## D;\
|
||||||
|
add k+4+round(%ebp),d ## D;\
|
||||||
|
xor %edi, d ## D;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* a input register containing a
|
||||||
|
* b input register containing b (rotated 16)
|
||||||
|
* c input register containing c
|
||||||
|
* d input register containing d (already rol $1)
|
||||||
|
* operations on a and b are interleaved to increase performance
|
||||||
|
*/
|
||||||
|
#define decrypt_round(a,b,c,d,round)\
|
||||||
|
push c ## D;\
|
||||||
|
movzx a ## B, %edi;\
|
||||||
|
mov (%ebp,%edi,4), c ## D;\
|
||||||
|
movzx b ## B, %edi;\
|
||||||
|
mov s3(%ebp,%edi,4),%esi;\
|
||||||
|
movzx a ## H, %edi;\
|
||||||
|
ror $16, a ## D;\
|
||||||
|
xor s1(%ebp,%edi,4),c ## D;\
|
||||||
|
movzx b ## H, %edi;\
|
||||||
|
ror $16, b ## D;\
|
||||||
|
xor (%ebp,%edi,4), %esi;\
|
||||||
|
movzx a ## B, %edi;\
|
||||||
|
xor s2(%ebp,%edi,4),c ## D;\
|
||||||
|
movzx b ## B, %edi;\
|
||||||
|
xor s1(%ebp,%edi,4),%esi;\
|
||||||
|
movzx a ## H, %edi;\
|
||||||
|
ror $15, a ## D;\
|
||||||
|
xor s3(%ebp,%edi,4),c ## D;\
|
||||||
|
movzx b ## H, %edi;\
|
||||||
|
xor s2(%ebp,%edi,4),%esi;\
|
||||||
|
pop %edi;\
|
||||||
|
add %esi, c ## D;\
|
||||||
|
add c ## D, %esi;\
|
||||||
|
add k+round(%ebp), c ## D;\
|
||||||
|
xor %edi, c ## D;\
|
||||||
|
add k+4+round(%ebp),%esi;\
|
||||||
|
xor %esi, d ## D;\
|
||||||
|
rol $15, d ## D;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* a input register containing a
|
||||||
|
* b input register containing b (rotated 16)
|
||||||
|
* c input register containing c
|
||||||
|
* d input register containing d (already rol $1)
|
||||||
|
* operations on a and b are interleaved to increase performance
|
||||||
|
* last round has different rotations for the output preparation
|
||||||
|
*/
|
||||||
|
#define decrypt_last_round(a,b,c,d,round)\
|
||||||
|
push c ## D;\
|
||||||
|
movzx a ## B, %edi;\
|
||||||
|
mov (%ebp,%edi,4), c ## D;\
|
||||||
|
movzx b ## B, %edi;\
|
||||||
|
mov s3(%ebp,%edi,4),%esi;\
|
||||||
|
movzx a ## H, %edi;\
|
||||||
|
ror $16, a ## D;\
|
||||||
|
xor s1(%ebp,%edi,4),c ## D;\
|
||||||
|
movzx b ## H, %edi;\
|
||||||
|
ror $16, b ## D;\
|
||||||
|
xor (%ebp,%edi,4), %esi;\
|
||||||
|
movzx a ## B, %edi;\
|
||||||
|
xor s2(%ebp,%edi,4),c ## D;\
|
||||||
|
movzx b ## B, %edi;\
|
||||||
|
xor s1(%ebp,%edi,4),%esi;\
|
||||||
|
movzx a ## H, %edi;\
|
||||||
|
ror $16, a ## D;\
|
||||||
|
xor s3(%ebp,%edi,4),c ## D;\
|
||||||
|
movzx b ## H, %edi;\
|
||||||
|
xor s2(%ebp,%edi,4),%esi;\
|
||||||
|
pop %edi;\
|
||||||
|
add %esi, c ## D;\
|
||||||
|
add c ## D, %esi;\
|
||||||
|
add k+round(%ebp), c ## D;\
|
||||||
|
xor %edi, c ## D;\
|
||||||
|
add k+4+round(%ebp),%esi;\
|
||||||
|
xor %esi, d ## D;\
|
||||||
|
ror $1, d ## D;
|
||||||
|
|
||||||
|
.align 4
|
||||||
|
.global twofish_enc_blk
|
||||||
|
.global twofish_dec_blk
|
||||||
|
|
||||||
|
twofish_enc_blk:
|
||||||
|
push %ebp /* save registers according to calling convention*/
|
||||||
|
push %ebx
|
||||||
|
push %esi
|
||||||
|
push %edi
|
||||||
|
|
||||||
|
mov tfm + 16(%esp), %ebp /* abuse the base pointer: set new base bointer to the crypto tfm */
|
||||||
|
add $crypto_tfm_ctx_offset, %ebp /* ctx adress */
|
||||||
|
mov in_blk+16(%esp),%edi /* input adress in edi */
|
||||||
|
|
||||||
|
mov (%edi), %eax
|
||||||
|
mov b_offset(%edi), %ebx
|
||||||
|
mov c_offset(%edi), %ecx
|
||||||
|
mov d_offset(%edi), %edx
|
||||||
|
input_whitening(%eax,%ebp,a_offset)
|
||||||
|
ror $16, %eax
|
||||||
|
input_whitening(%ebx,%ebp,b_offset)
|
||||||
|
input_whitening(%ecx,%ebp,c_offset)
|
||||||
|
input_whitening(%edx,%ebp,d_offset)
|
||||||
|
rol $1, %edx
|
||||||
|
|
||||||
|
encrypt_round(R0,R1,R2,R3,0);
|
||||||
|
encrypt_round(R2,R3,R0,R1,8);
|
||||||
|
encrypt_round(R0,R1,R2,R3,2*8);
|
||||||
|
encrypt_round(R2,R3,R0,R1,3*8);
|
||||||
|
encrypt_round(R0,R1,R2,R3,4*8);
|
||||||
|
encrypt_round(R2,R3,R0,R1,5*8);
|
||||||
|
encrypt_round(R0,R1,R2,R3,6*8);
|
||||||
|
encrypt_round(R2,R3,R0,R1,7*8);
|
||||||
|
encrypt_round(R0,R1,R2,R3,8*8);
|
||||||
|
encrypt_round(R2,R3,R0,R1,9*8);
|
||||||
|
encrypt_round(R0,R1,R2,R3,10*8);
|
||||||
|
encrypt_round(R2,R3,R0,R1,11*8);
|
||||||
|
encrypt_round(R0,R1,R2,R3,12*8);
|
||||||
|
encrypt_round(R2,R3,R0,R1,13*8);
|
||||||
|
encrypt_round(R0,R1,R2,R3,14*8);
|
||||||
|
encrypt_last_round(R2,R3,R0,R1,15*8);
|
||||||
|
|
||||||
|
output_whitening(%eax,%ebp,c_offset)
|
||||||
|
output_whitening(%ebx,%ebp,d_offset)
|
||||||
|
output_whitening(%ecx,%ebp,a_offset)
|
||||||
|
output_whitening(%edx,%ebp,b_offset)
|
||||||
|
mov out_blk+16(%esp),%edi;
|
||||||
|
mov %eax, c_offset(%edi)
|
||||||
|
mov %ebx, d_offset(%edi)
|
||||||
|
mov %ecx, (%edi)
|
||||||
|
mov %edx, b_offset(%edi)
|
||||||
|
|
||||||
|
pop %edi
|
||||||
|
pop %esi
|
||||||
|
pop %ebx
|
||||||
|
pop %ebp
|
||||||
|
mov $1, %eax
|
||||||
|
ret
|
||||||
|
|
||||||
|
twofish_dec_blk:
|
||||||
|
push %ebp /* save registers according to calling convention*/
|
||||||
|
push %ebx
|
||||||
|
push %esi
|
||||||
|
push %edi
|
||||||
|
|
||||||
|
|
||||||
|
mov tfm + 16(%esp), %ebp /* abuse the base pointer: set new base bointer to the crypto tfm */
|
||||||
|
add $crypto_tfm_ctx_offset, %ebp /* ctx adress */
|
||||||
|
mov in_blk+16(%esp),%edi /* input adress in edi */
|
||||||
|
|
||||||
|
mov (%edi), %eax
|
||||||
|
mov b_offset(%edi), %ebx
|
||||||
|
mov c_offset(%edi), %ecx
|
||||||
|
mov d_offset(%edi), %edx
|
||||||
|
output_whitening(%eax,%ebp,a_offset)
|
||||||
|
output_whitening(%ebx,%ebp,b_offset)
|
||||||
|
ror $16, %ebx
|
||||||
|
output_whitening(%ecx,%ebp,c_offset)
|
||||||
|
output_whitening(%edx,%ebp,d_offset)
|
||||||
|
rol $1, %ecx
|
||||||
|
|
||||||
|
decrypt_round(R0,R1,R2,R3,15*8);
|
||||||
|
decrypt_round(R2,R3,R0,R1,14*8);
|
||||||
|
decrypt_round(R0,R1,R2,R3,13*8);
|
||||||
|
decrypt_round(R2,R3,R0,R1,12*8);
|
||||||
|
decrypt_round(R0,R1,R2,R3,11*8);
|
||||||
|
decrypt_round(R2,R3,R0,R1,10*8);
|
||||||
|
decrypt_round(R0,R1,R2,R3,9*8);
|
||||||
|
decrypt_round(R2,R3,R0,R1,8*8);
|
||||||
|
decrypt_round(R0,R1,R2,R3,7*8);
|
||||||
|
decrypt_round(R2,R3,R0,R1,6*8);
|
||||||
|
decrypt_round(R0,R1,R2,R3,5*8);
|
||||||
|
decrypt_round(R2,R3,R0,R1,4*8);
|
||||||
|
decrypt_round(R0,R1,R2,R3,3*8);
|
||||||
|
decrypt_round(R2,R3,R0,R1,2*8);
|
||||||
|
decrypt_round(R0,R1,R2,R3,1*8);
|
||||||
|
decrypt_last_round(R2,R3,R0,R1,0);
|
||||||
|
|
||||||
|
input_whitening(%eax,%ebp,c_offset)
|
||||||
|
input_whitening(%ebx,%ebp,d_offset)
|
||||||
|
input_whitening(%ecx,%ebp,a_offset)
|
||||||
|
input_whitening(%edx,%ebp,b_offset)
|
||||||
|
mov out_blk+16(%esp),%edi;
|
||||||
|
mov %eax, c_offset(%edi)
|
||||||
|
mov %ebx, d_offset(%edi)
|
||||||
|
mov %ecx, (%edi)
|
||||||
|
mov %edx, b_offset(%edi)
|
||||||
|
|
||||||
|
pop %edi
|
||||||
|
pop %esi
|
||||||
|
pop %ebx
|
||||||
|
pop %ebp
|
||||||
|
mov $1, %eax
|
||||||
|
ret
|
|
@ -0,0 +1,97 @@
|
||||||
|
/*
|
||||||
|
* Glue Code for optimized 586 assembler version of TWOFISH
|
||||||
|
*
|
||||||
|
* Originally Twofish for GPG
|
||||||
|
* By Matthew Skala <mskala@ansuz.sooke.bc.ca>, July 26, 1998
|
||||||
|
* 256-bit key length added March 20, 1999
|
||||||
|
* Some modifications to reduce the text size by Werner Koch, April, 1998
|
||||||
|
* Ported to the kerneli patch by Marc Mutz <Marc@Mutz.com>
|
||||||
|
* Ported to CryptoAPI by Colin Slater <hoho@tacomeat.net>
|
||||||
|
*
|
||||||
|
* The original author has disclaimed all copyright interest in this
|
||||||
|
* code and thus put it in the public domain. The subsequent authors
|
||||||
|
* have put this under the GNU General Public License.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*
|
||||||
|
* This code is a "clean room" implementation, written from the paper
|
||||||
|
* _Twofish: A 128-Bit Block Cipher_ by Bruce Schneier, John Kelsey,
|
||||||
|
* Doug Whiting, David Wagner, Chris Hall, and Niels Ferguson, available
|
||||||
|
* through http://www.counterpane.com/twofish.html
|
||||||
|
*
|
||||||
|
* For background information on multiplication in finite fields, used for
|
||||||
|
* the matrix operations in the key schedule, see the book _Contemporary
|
||||||
|
* Abstract Algebra_ by Joseph A. Gallian, especially chapter 22 in the
|
||||||
|
* Third Edition.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <crypto/twofish.h>
|
||||||
|
#include <linux/crypto.h>
|
||||||
|
#include <linux/init.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
|
||||||
|
asmlinkage void twofish_enc_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
|
||||||
|
asmlinkage void twofish_dec_blk(struct crypto_tfm *tfm, u8 *dst, const u8 *src);
|
||||||
|
|
||||||
|
static void twofish_encrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
|
||||||
|
{
|
||||||
|
twofish_enc_blk(tfm, dst, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void twofish_decrypt(struct crypto_tfm *tfm, u8 *dst, const u8 *src)
|
||||||
|
{
|
||||||
|
twofish_dec_blk(tfm, dst, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct crypto_alg alg = {
|
||||||
|
.cra_name = "twofish",
|
||||||
|
.cra_driver_name = "twofish-i586",
|
||||||
|
.cra_priority = 200,
|
||||||
|
.cra_flags = CRYPTO_ALG_TYPE_CIPHER,
|
||||||
|
.cra_blocksize = TF_BLOCK_SIZE,
|
||||||
|
.cra_ctxsize = sizeof(struct twofish_ctx),
|
||||||
|
.cra_alignmask = 3,
|
||||||
|
.cra_module = THIS_MODULE,
|
||||||
|
.cra_list = LIST_HEAD_INIT(alg.cra_list),
|
||||||
|
.cra_u = {
|
||||||
|
.cipher = {
|
||||||
|
.cia_min_keysize = TF_MIN_KEY_SIZE,
|
||||||
|
.cia_max_keysize = TF_MAX_KEY_SIZE,
|
||||||
|
.cia_setkey = twofish_setkey,
|
||||||
|
.cia_encrypt = twofish_encrypt,
|
||||||
|
.cia_decrypt = twofish_decrypt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
static int __init init(void)
|
||||||
|
{
|
||||||
|
return crypto_register_alg(&alg);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __exit fini(void)
|
||||||
|
{
|
||||||
|
crypto_unregister_alg(&alg);
|
||||||
|
}
|
||||||
|
|
||||||
|
module_init(init);
|
||||||
|
module_exit(fini);
|
||||||
|
|
||||||
|
MODULE_LICENSE("GPL");
|
||||||
|
MODULE_DESCRIPTION ("Twofish Cipher Algorithm, i586 asm optimized");
|
||||||
|
MODULE_ALIAS("twofish");
|
|
@ -417,6 +417,17 @@ config PPC_MAPLE
|
||||||
This option enables support for the Maple 970FX Evaluation Board.
|
This option enables support for the Maple 970FX Evaluation Board.
|
||||||
For more informations, refer to <http://www.970eval.com>
|
For more informations, refer to <http://www.970eval.com>
|
||||||
|
|
||||||
|
config PPC_PASEMI
|
||||||
|
depends on PPC_MULTIPLATFORM && PPC64
|
||||||
|
bool "PA Semi SoC-based platforms"
|
||||||
|
default n
|
||||||
|
select MPIC
|
||||||
|
select PPC_UDBG_16550
|
||||||
|
select GENERIC_TBSYNC
|
||||||
|
help
|
||||||
|
This option enables support for PA Semi's PWRficient line
|
||||||
|
of SoC processors, including PA6T-1682M
|
||||||
|
|
||||||
config PPC_CELL
|
config PPC_CELL
|
||||||
bool
|
bool
|
||||||
default n
|
default n
|
||||||
|
@ -436,7 +447,8 @@ config PPC_IBM_CELL_BLADE
|
||||||
select UDBG_RTAS_CONSOLE
|
select UDBG_RTAS_CONSOLE
|
||||||
|
|
||||||
config UDBG_RTAS_CONSOLE
|
config UDBG_RTAS_CONSOLE
|
||||||
bool
|
bool "RTAS based debug console"
|
||||||
|
depends on PPC_RTAS
|
||||||
default n
|
default n
|
||||||
|
|
||||||
config XICS
|
config XICS
|
||||||
|
|
|
@ -18,6 +18,20 @@ config DEBUG_STACK_USAGE
|
||||||
|
|
||||||
This option will slow down process creation somewhat.
|
This option will slow down process creation somewhat.
|
||||||
|
|
||||||
|
config HCALL_STATS
|
||||||
|
bool "Hypervisor call instrumentation"
|
||||||
|
depends on PPC_PSERIES && DEBUG_FS
|
||||||
|
help
|
||||||
|
Adds code to keep track of the number of hypervisor calls made and
|
||||||
|
the amount of time spent in hypervisor callsr. Wall time spent in
|
||||||
|
each call is always calculated, and if available CPU cycles spent
|
||||||
|
are also calculated. A directory named hcall_inst is added at the
|
||||||
|
root of the debugfs filesystem. Within the hcall_inst directory
|
||||||
|
are files that contain CPU specific call statistics.
|
||||||
|
|
||||||
|
This option will add a small amount of overhead to all hypervisor
|
||||||
|
calls.
|
||||||
|
|
||||||
config DEBUGGER
|
config DEBUGGER
|
||||||
bool "Enable debugger hooks"
|
bool "Enable debugger hooks"
|
||||||
depends on DEBUG_KERNEL
|
depends on DEBUG_KERNEL
|
||||||
|
@ -74,6 +88,8 @@ config XMON
|
||||||
very early during boot. 'xmon=on' will just enable the xmon
|
very early during boot. 'xmon=on' will just enable the xmon
|
||||||
debugger hooks. 'xmon=off' will disable the debugger hooks
|
debugger hooks. 'xmon=off' will disable the debugger hooks
|
||||||
if CONFIG_XMON_DEFAULT is set.
|
if CONFIG_XMON_DEFAULT is set.
|
||||||
|
xmon will print a backtrace on the very first invocation.
|
||||||
|
'xmon=nobt' will disable this autobacktrace.
|
||||||
|
|
||||||
config XMON_DEFAULT
|
config XMON_DEFAULT
|
||||||
bool "Enable xmon by default"
|
bool "Enable xmon by default"
|
||||||
|
|
|
@ -36,11 +36,16 @@ zliblinuxheader := zlib.h zconf.h zutil.h
|
||||||
$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
|
$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) $(addprefix $(obj)/,$(zlibheader))
|
||||||
#$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h)
|
#$(addprefix $(obj)/,main.o): $(addprefix $(obj)/,zlib.h)
|
||||||
|
|
||||||
src-boot := crt0.S string.S prom.c stdio.c main.c div64.S
|
src-boot-$(CONFIG_PPC_MULTIPLATFORM) := of.c
|
||||||
|
src-boot := crt0.S string.S stdio.c main.c div64.S $(src-boot-y)
|
||||||
src-boot += $(zlib)
|
src-boot += $(zlib)
|
||||||
src-boot := $(addprefix $(obj)/, $(src-boot))
|
src-boot := $(addprefix $(obj)/, $(src-boot))
|
||||||
obj-boot := $(addsuffix .o, $(basename $(src-boot)))
|
obj-boot := $(addsuffix .o, $(basename $(src-boot)))
|
||||||
|
|
||||||
|
ifeq ($(call cc-option-yn, -fstack-protector),y)
|
||||||
|
BOOTCFLAGS += -fno-stack-protector
|
||||||
|
endif
|
||||||
|
|
||||||
BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj)
|
BOOTCFLAGS += -I$(obj) -I$(srctree)/$(obj)
|
||||||
|
|
||||||
quiet_cmd_copy_zlib = COPY $@
|
quiet_cmd_copy_zlib = COPY $@
|
||||||
|
|
|
@ -214,10 +214,10 @@ b800 0 0 3 700 14 8
|
||||||
b800 0 0 4 700 15 8
|
b800 0 0 4 700 15 8
|
||||||
|
|
||||||
/* IDSEL 0x18 */
|
/* IDSEL 0x18 */
|
||||||
b000 0 0 1 700 15 8
|
c000 0 0 1 700 15 8
|
||||||
b000 0 0 2 700 16 8
|
c000 0 0 2 700 16 8
|
||||||
b000 0 0 3 700 17 8
|
c000 0 0 3 700 17 8
|
||||||
b000 0 0 4 700 14 8>;
|
c000 0 0 4 700 14 8>;
|
||||||
interrupt-parent = <700>;
|
interrupt-parent = <700>;
|
||||||
interrupts = <42 8>;
|
interrupts = <42 8>;
|
||||||
bus-range = <0 0>;
|
bus-range = <0 0>;
|
||||||
|
@ -274,10 +274,10 @@ b800 0 0 3 700 14 8
|
||||||
b800 0 0 4 700 15 8
|
b800 0 0 4 700 15 8
|
||||||
|
|
||||||
/* IDSEL 0x18 */
|
/* IDSEL 0x18 */
|
||||||
b000 0 0 1 700 15 8
|
c000 0 0 1 700 15 8
|
||||||
b000 0 0 2 700 16 8
|
c000 0 0 2 700 16 8
|
||||||
b000 0 0 3 700 17 8
|
c000 0 0 3 700 17 8
|
||||||
b000 0 0 4 700 14 8>;
|
c000 0 0 4 700 14 8>;
|
||||||
interrupt-parent = <700>;
|
interrupt-parent = <700>;
|
||||||
interrupts = <42 8>;
|
interrupts = <42 8>;
|
||||||
bus-range = <0 0>;
|
bus-range = <0 0>;
|
||||||
|
|
|
@ -0,0 +1,46 @@
|
||||||
|
/*
|
||||||
|
* 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, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef FLATDEVTREE_H
|
||||||
|
#define FLATDEVTREE_H
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
/* Definitions used by the flattened device tree */
|
||||||
|
#define OF_DT_HEADER 0xd00dfeed /* marker */
|
||||||
|
#define OF_DT_BEGIN_NODE 0x1 /* Start of node, full name */
|
||||||
|
#define OF_DT_END_NODE 0x2 /* End node */
|
||||||
|
#define OF_DT_PROP 0x3 /* Property: name off, size, content */
|
||||||
|
#define OF_DT_NOP 0x4 /* nop */
|
||||||
|
#define OF_DT_END 0x9
|
||||||
|
|
||||||
|
#define OF_DT_VERSION 0x10
|
||||||
|
|
||||||
|
struct boot_param_header {
|
||||||
|
u32 magic; /* magic word OF_DT_HEADER */
|
||||||
|
u32 totalsize; /* total size of DT block */
|
||||||
|
u32 off_dt_struct; /* offset to structure */
|
||||||
|
u32 off_dt_strings; /* offset to strings */
|
||||||
|
u32 off_mem_rsvmap; /* offset to memory reserve map */
|
||||||
|
u32 version; /* format version */
|
||||||
|
u32 last_comp_version; /* last compatible version */
|
||||||
|
/* version 2 fields below */
|
||||||
|
u32 boot_cpuid_phys; /* Physical CPU id we're booting on */
|
||||||
|
/* version 3 fields below */
|
||||||
|
u32 dt_strings_size; /* size of the DT strings block */
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif /* FLATDEVTREE_H */
|
|
@ -14,17 +14,12 @@
|
||||||
#include "page.h"
|
#include "page.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
#include "prom.h"
|
|
||||||
#include "zlib.h"
|
#include "zlib.h"
|
||||||
|
#include "ops.h"
|
||||||
|
#include "flatdevtree.h"
|
||||||
|
|
||||||
extern void flush_cache(void *, unsigned long);
|
extern void flush_cache(void *, unsigned long);
|
||||||
|
|
||||||
|
|
||||||
/* Value picked to match that used by yaboot */
|
|
||||||
#define PROG_START 0x01400000 /* only used on 64-bit systems */
|
|
||||||
#define RAM_END (512<<20) /* Fixme: use OF */
|
|
||||||
#define ONE_MB 0x100000
|
|
||||||
|
|
||||||
extern char _start[];
|
extern char _start[];
|
||||||
extern char __bss_start[];
|
extern char __bss_start[];
|
||||||
extern char _end[];
|
extern char _end[];
|
||||||
|
@ -33,14 +28,6 @@ extern char _vmlinux_end[];
|
||||||
extern char _initrd_start[];
|
extern char _initrd_start[];
|
||||||
extern char _initrd_end[];
|
extern char _initrd_end[];
|
||||||
|
|
||||||
/* A buffer that may be edited by tools operating on a zImage binary so as to
|
|
||||||
* edit the command line passed to vmlinux (by setting /chosen/bootargs).
|
|
||||||
* The buffer is put in it's own section so that tools may locate it easier.
|
|
||||||
*/
|
|
||||||
static char builtin_cmdline[512]
|
|
||||||
__attribute__((section("__builtin_cmdline")));
|
|
||||||
|
|
||||||
|
|
||||||
struct addr_range {
|
struct addr_range {
|
||||||
unsigned long addr;
|
unsigned long addr;
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
|
@ -51,21 +38,16 @@ static struct addr_range vmlinuz;
|
||||||
static struct addr_range initrd;
|
static struct addr_range initrd;
|
||||||
|
|
||||||
static unsigned long elfoffset;
|
static unsigned long elfoffset;
|
||||||
|
static int is_64bit;
|
||||||
|
|
||||||
static char scratch[46912]; /* scratch space for gunzip, from zlib_inflate_workspacesize() */
|
/* scratch space for gunzip; 46912 is from zlib_inflate_workspacesize() */
|
||||||
|
static char scratch[46912];
|
||||||
static char elfheader[256];
|
static char elfheader[256];
|
||||||
|
|
||||||
|
typedef void (*kernel_entry_t)(unsigned long, unsigned long, void *);
|
||||||
typedef void (*kernel_entry_t)( unsigned long,
|
|
||||||
unsigned long,
|
|
||||||
void *,
|
|
||||||
void *);
|
|
||||||
|
|
||||||
|
|
||||||
#undef DEBUG
|
#undef DEBUG
|
||||||
|
|
||||||
static unsigned long claim_base;
|
|
||||||
|
|
||||||
#define HEAD_CRC 2
|
#define HEAD_CRC 2
|
||||||
#define EXTRA_FIELD 4
|
#define EXTRA_FIELD 4
|
||||||
#define ORIG_NAME 8
|
#define ORIG_NAME 8
|
||||||
|
@ -123,24 +105,6 @@ static void gunzip(void *dst, int dstlen, unsigned char *src, int *lenp)
|
||||||
zlib_inflateEnd(&s);
|
zlib_inflateEnd(&s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long try_claim(unsigned long size)
|
|
||||||
{
|
|
||||||
unsigned long addr = 0;
|
|
||||||
|
|
||||||
for(; claim_base < RAM_END; claim_base += ONE_MB) {
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf(" trying: 0x%08lx\n\r", claim_base);
|
|
||||||
#endif
|
|
||||||
addr = (unsigned long)claim(claim_base, size, 0);
|
|
||||||
if ((void *)addr != (void *)-1)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (addr == 0)
|
|
||||||
return 0;
|
|
||||||
claim_base = PAGE_ALIGN(claim_base + size);
|
|
||||||
return addr;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int is_elf64(void *hdr)
|
static int is_elf64(void *hdr)
|
||||||
{
|
{
|
||||||
Elf64_Ehdr *elf64 = hdr;
|
Elf64_Ehdr *elf64 = hdr;
|
||||||
|
@ -169,16 +133,7 @@ static int is_elf64(void *hdr)
|
||||||
vmlinux.size = (unsigned long)elf64ph->p_filesz + elfoffset;
|
vmlinux.size = (unsigned long)elf64ph->p_filesz + elfoffset;
|
||||||
vmlinux.memsize = (unsigned long)elf64ph->p_memsz + elfoffset;
|
vmlinux.memsize = (unsigned long)elf64ph->p_memsz + elfoffset;
|
||||||
|
|
||||||
#if defined(PROG_START)
|
is_64bit = 1;
|
||||||
/*
|
|
||||||
* Maintain a "magic" minimum address. This keeps some older
|
|
||||||
* firmware platforms running.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (claim_base < PROG_START)
|
|
||||||
claim_base = PROG_START;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,47 +167,9 @@ static int is_elf32(void *hdr)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void export_cmdline(void* chosen_handle)
|
static void prep_kernel(unsigned long *a1, unsigned long *a2)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
char cmdline[2] = { 0, 0 };
|
|
||||||
|
|
||||||
if (builtin_cmdline[0] == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
len = getprop(chosen_handle, "bootargs", cmdline, sizeof(cmdline));
|
|
||||||
if (len > 0 && cmdline[0] != 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
setprop(chosen_handle, "bootargs", builtin_cmdline,
|
|
||||||
strlen(builtin_cmdline) + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
|
|
||||||
{
|
|
||||||
int len;
|
|
||||||
kernel_entry_t kernel_entry;
|
|
||||||
|
|
||||||
memset(__bss_start, 0, _end - __bss_start);
|
|
||||||
|
|
||||||
prom = (int (*)(void *)) promptr;
|
|
||||||
chosen_handle = finddevice("/chosen");
|
|
||||||
if (chosen_handle == (void *) -1)
|
|
||||||
exit();
|
|
||||||
if (getprop(chosen_handle, "stdout", &stdout, sizeof(stdout)) != 4)
|
|
||||||
exit();
|
|
||||||
|
|
||||||
printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", _start, sp);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The first available claim_base must be above the end of the
|
|
||||||
* the loaded kernel wrapper file (_start to _end includes the
|
|
||||||
* initrd image if it is present) and rounded up to a nice
|
|
||||||
* 1 MB boundary for good measure.
|
|
||||||
*/
|
|
||||||
|
|
||||||
claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB);
|
|
||||||
|
|
||||||
vmlinuz.addr = (unsigned long)_vmlinux_start;
|
vmlinuz.addr = (unsigned long)_vmlinux_start;
|
||||||
vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
|
vmlinuz.size = (unsigned long)(_vmlinux_end - _vmlinux_start);
|
||||||
|
@ -263,43 +180,51 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
|
||||||
gunzip(elfheader, sizeof(elfheader),
|
gunzip(elfheader, sizeof(elfheader),
|
||||||
(unsigned char *)vmlinuz.addr, &len);
|
(unsigned char *)vmlinuz.addr, &len);
|
||||||
} else
|
} else
|
||||||
memcpy(elfheader, (const void *)vmlinuz.addr, sizeof(elfheader));
|
memcpy(elfheader, (const void *)vmlinuz.addr,
|
||||||
|
sizeof(elfheader));
|
||||||
|
|
||||||
if (!is_elf64(elfheader) && !is_elf32(elfheader)) {
|
if (!is_elf64(elfheader) && !is_elf32(elfheader)) {
|
||||||
printf("Error: not a valid PPC32 or PPC64 ELF file!\n\r");
|
printf("Error: not a valid PPC32 or PPC64 ELF file!\n\r");
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
if (platform_ops.image_hdr)
|
||||||
|
platform_ops.image_hdr(elfheader);
|
||||||
|
|
||||||
/* We need to claim the memsize plus the file offset since gzip
|
/* We need to alloc the memsize plus the file offset since gzip
|
||||||
* will expand the header (file offset), then the kernel, then
|
* will expand the header (file offset), then the kernel, then
|
||||||
* possible rubbish we don't care about. But the kernel bss must
|
* possible rubbish we don't care about. But the kernel bss must
|
||||||
* be claimed (it will be zero'd by the kernel itself)
|
* be claimed (it will be zero'd by the kernel itself)
|
||||||
*/
|
*/
|
||||||
printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux.memsize);
|
printf("Allocating 0x%lx bytes for kernel ...\n\r", vmlinux.memsize);
|
||||||
vmlinux.addr = try_claim(vmlinux.memsize);
|
vmlinux.addr = (unsigned long)malloc(vmlinux.memsize);
|
||||||
if (vmlinux.addr == 0) {
|
if (vmlinux.addr == 0) {
|
||||||
printf("Can't allocate memory for kernel image !\n\r");
|
printf("Can't allocate memory for kernel image !\n\r");
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now we try to claim memory for the initrd (and copy it there)
|
* Now we try to alloc memory for the initrd (and copy it there)
|
||||||
*/
|
*/
|
||||||
initrd.size = (unsigned long)(_initrd_end - _initrd_start);
|
initrd.size = (unsigned long)(_initrd_end - _initrd_start);
|
||||||
initrd.memsize = initrd.size;
|
initrd.memsize = initrd.size;
|
||||||
if ( initrd.size > 0 ) {
|
if ( initrd.size > 0 ) {
|
||||||
printf("Allocating 0x%lx bytes for initrd ...\n\r", initrd.size);
|
printf("Allocating 0x%lx bytes for initrd ...\n\r",
|
||||||
initrd.addr = try_claim(initrd.size);
|
initrd.size);
|
||||||
|
initrd.addr = (unsigned long)malloc((u32)initrd.size);
|
||||||
if (initrd.addr == 0) {
|
if (initrd.addr == 0) {
|
||||||
printf("Can't allocate memory for initial ramdisk !\n\r");
|
printf("Can't allocate memory for initial "
|
||||||
|
"ramdisk !\n\r");
|
||||||
exit();
|
exit();
|
||||||
}
|
}
|
||||||
a1 = initrd.addr;
|
*a1 = initrd.addr;
|
||||||
a2 = initrd.size;
|
*a2 = initrd.size;
|
||||||
printf("initial ramdisk moving 0x%lx <- 0x%lx (0x%lx bytes)\n\r",
|
printf("initial ramdisk moving 0x%lx <- 0x%lx "
|
||||||
initrd.addr, (unsigned long)_initrd_start, initrd.size);
|
"(0x%lx bytes)\n\r", initrd.addr,
|
||||||
memmove((void *)initrd.addr, (void *)_initrd_start, initrd.size);
|
(unsigned long)_initrd_start, initrd.size);
|
||||||
printf("initrd head: 0x%lx\n\r", *((unsigned long *)initrd.addr));
|
memmove((void *)initrd.addr, (void *)_initrd_start,
|
||||||
|
initrd.size);
|
||||||
|
printf("initrd head: 0x%lx\n\r",
|
||||||
|
*((unsigned long *)initrd.addr));
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Eventually gunzip the kernel */
|
/* Eventually gunzip the kernel */
|
||||||
|
@ -311,11 +236,10 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
|
||||||
(unsigned char *)vmlinuz.addr, &len);
|
(unsigned char *)vmlinuz.addr, &len);
|
||||||
printf("done 0x%lx bytes\n\r", len);
|
printf("done 0x%lx bytes\n\r", len);
|
||||||
} else {
|
} else {
|
||||||
memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,vmlinuz.size);
|
memmove((void *)vmlinux.addr,(void *)vmlinuz.addr,
|
||||||
|
vmlinuz.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
export_cmdline(chosen_handle);
|
|
||||||
|
|
||||||
/* Skip over the ELF header */
|
/* Skip over the ELF header */
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("... skipping 0x%lx bytes of ELF header\n\r",
|
printf("... skipping 0x%lx bytes of ELF header\n\r",
|
||||||
|
@ -324,23 +248,107 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
|
||||||
vmlinux.addr += elfoffset;
|
vmlinux.addr += elfoffset;
|
||||||
|
|
||||||
flush_cache((void *)vmlinux.addr, vmlinux.size);
|
flush_cache((void *)vmlinux.addr, vmlinux.size);
|
||||||
|
|
||||||
kernel_entry = (kernel_entry_t)vmlinux.addr;
|
|
||||||
#ifdef DEBUG
|
|
||||||
printf( "kernel:\n\r"
|
|
||||||
" entry addr = 0x%lx\n\r"
|
|
||||||
" a1 = 0x%lx,\n\r"
|
|
||||||
" a2 = 0x%lx,\n\r"
|
|
||||||
" prom = 0x%lx,\n\r"
|
|
||||||
" bi_recs = 0x%lx,\n\r",
|
|
||||||
(unsigned long)kernel_entry, a1, a2,
|
|
||||||
(unsigned long)prom, NULL);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
kernel_entry(a1, a2, prom, NULL);
|
|
||||||
|
|
||||||
printf("Error: Linux kernel returned to zImage bootloader!\n\r");
|
|
||||||
|
|
||||||
exit();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void __attribute__ ((weak)) ft_init(void *dt_blob)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/* A buffer that may be edited by tools operating on a zImage binary so as to
|
||||||
|
* edit the command line passed to vmlinux (by setting /chosen/bootargs).
|
||||||
|
* The buffer is put in it's own section so that tools may locate it easier.
|
||||||
|
*/
|
||||||
|
static char builtin_cmdline[COMMAND_LINE_SIZE]
|
||||||
|
__attribute__((__section__("__builtin_cmdline")));
|
||||||
|
|
||||||
|
static void get_cmdline(char *buf, int size)
|
||||||
|
{
|
||||||
|
void *devp;
|
||||||
|
int len = strlen(builtin_cmdline);
|
||||||
|
|
||||||
|
buf[0] = '\0';
|
||||||
|
|
||||||
|
if (len > 0) { /* builtin_cmdline overrides dt's /chosen/bootargs */
|
||||||
|
len = min(len, size-1);
|
||||||
|
strncpy(buf, builtin_cmdline, len);
|
||||||
|
buf[len] = '\0';
|
||||||
|
}
|
||||||
|
else if ((devp = finddevice("/chosen")))
|
||||||
|
getprop(devp, "bootargs", buf, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void set_cmdline(char *buf)
|
||||||
|
{
|
||||||
|
void *devp;
|
||||||
|
|
||||||
|
if ((devp = finddevice("/chosen")))
|
||||||
|
setprop(devp, "bootargs", buf, strlen(buf) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Section where ft can be tacked on after zImage is built */
|
||||||
|
union blobspace {
|
||||||
|
struct boot_param_header hdr;
|
||||||
|
char space[8*1024];
|
||||||
|
} dt_blob __attribute__((__section__("__builtin_ft")));
|
||||||
|
|
||||||
|
struct platform_ops platform_ops;
|
||||||
|
struct dt_ops dt_ops;
|
||||||
|
struct console_ops console_ops;
|
||||||
|
|
||||||
|
void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
|
||||||
|
{
|
||||||
|
int have_dt = 0;
|
||||||
|
kernel_entry_t kentry;
|
||||||
|
char cmdline[COMMAND_LINE_SIZE];
|
||||||
|
|
||||||
|
memset(__bss_start, 0, _end - __bss_start);
|
||||||
|
memset(&platform_ops, 0, sizeof(platform_ops));
|
||||||
|
memset(&dt_ops, 0, sizeof(dt_ops));
|
||||||
|
memset(&console_ops, 0, sizeof(console_ops));
|
||||||
|
|
||||||
|
/* Override the dt_ops and device tree if there was an flat dev
|
||||||
|
* tree attached to the zImage.
|
||||||
|
*/
|
||||||
|
if (dt_blob.hdr.magic == OF_DT_HEADER) {
|
||||||
|
have_dt = 1;
|
||||||
|
ft_init(&dt_blob);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (platform_init(promptr))
|
||||||
|
exit();
|
||||||
|
if (console_ops.open && (console_ops.open() < 0))
|
||||||
|
exit();
|
||||||
|
if (platform_ops.fixups)
|
||||||
|
platform_ops.fixups();
|
||||||
|
|
||||||
|
printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r",
|
||||||
|
_start, sp);
|
||||||
|
|
||||||
|
prep_kernel(&a1, &a2);
|
||||||
|
|
||||||
|
/* If cmdline came from zimage wrapper or if we can edit the one
|
||||||
|
* in the dt, print it out and edit it, if possible.
|
||||||
|
*/
|
||||||
|
if ((strlen(builtin_cmdline) > 0) || console_ops.edit_cmdline) {
|
||||||
|
get_cmdline(cmdline, COMMAND_LINE_SIZE);
|
||||||
|
printf("\n\rLinux/PowerPC load: %s", cmdline);
|
||||||
|
if (console_ops.edit_cmdline)
|
||||||
|
console_ops.edit_cmdline(cmdline, COMMAND_LINE_SIZE);
|
||||||
|
printf("\n\r");
|
||||||
|
set_cmdline(cmdline);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (console_ops.close)
|
||||||
|
console_ops.close();
|
||||||
|
|
||||||
|
kentry = (kernel_entry_t) vmlinux.addr;
|
||||||
|
if (have_dt)
|
||||||
|
kentry(dt_ops.ft_addr(), 0, NULL);
|
||||||
|
else
|
||||||
|
/* XXX initrd addr/size should be passed in properties */
|
||||||
|
kentry(a1, a2, promptr);
|
||||||
|
|
||||||
|
/* console closed so printf below may not work */
|
||||||
|
printf("Error: Linux kernel returned to zImage boot wrapper!\n\r");
|
||||||
|
exit();
|
||||||
|
}
|
||||||
|
|
|
@ -8,15 +8,29 @@
|
||||||
*/
|
*/
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
#include "types.h"
|
||||||
|
#include "elf.h"
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
#include "prom.h"
|
#include "page.h"
|
||||||
|
#include "ops.h"
|
||||||
|
|
||||||
|
typedef void *ihandle;
|
||||||
|
typedef void *phandle;
|
||||||
|
|
||||||
|
extern char _end[];
|
||||||
|
|
||||||
|
/* Value picked to match that used by yaboot */
|
||||||
|
#define PROG_START 0x01400000 /* only used on 64-bit systems */
|
||||||
|
#define RAM_END (512<<20) /* Fixme: use OF */
|
||||||
|
#define ONE_MB 0x100000
|
||||||
|
|
||||||
int (*prom) (void *);
|
int (*prom) (void *);
|
||||||
phandle chosen_handle;
|
|
||||||
ihandle stdout;
|
|
||||||
|
|
||||||
int call_prom(const char *service, int nargs, int nret, ...)
|
|
||||||
|
static unsigned long claim_base;
|
||||||
|
|
||||||
|
static int call_prom(const char *service, int nargs, int nret, ...)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct prom_args {
|
struct prom_args {
|
||||||
|
@ -45,7 +59,7 @@ int call_prom(const char *service, int nargs, int nret, ...)
|
||||||
return (nret > 0)? args.args[nargs]: 0;
|
return (nret > 0)? args.args[nargs]: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int call_prom_ret(const char *service, int nargs, int nret,
|
static int call_prom_ret(const char *service, int nargs, int nret,
|
||||||
unsigned int *rets, ...)
|
unsigned int *rets, ...)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
@ -79,11 +93,6 @@ int call_prom_ret(const char *service, int nargs, int nret,
|
||||||
return (nret > 0)? args.args[nargs]: 0;
|
return (nret > 0)? args.args[nargs]: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int write(void *handle, void *ptr, int nb)
|
|
||||||
{
|
|
||||||
return call_prom("write", 3, 1, handle, ptr, nb);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Older OF's require that when claiming a specific range of addresses,
|
* Older OF's require that when claiming a specific range of addresses,
|
||||||
* we claim the physical space in the /memory node and the virtual
|
* we claim the physical space in the /memory node and the virtual
|
||||||
|
@ -142,7 +151,7 @@ static int check_of_version(void)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *claim(unsigned long virt, unsigned long size, unsigned long align)
|
static void *claim(unsigned long virt, unsigned long size, unsigned long align)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
unsigned int result;
|
unsigned int result;
|
||||||
|
@ -163,3 +172,112 @@ void *claim(unsigned long virt, unsigned long size, unsigned long align)
|
||||||
0x12, size, virt, virt);
|
0x12, size, virt, virt);
|
||||||
return (void *) virt;
|
return (void *) virt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void *of_try_claim(u32 size)
|
||||||
|
{
|
||||||
|
unsigned long addr = 0;
|
||||||
|
static u8 first_time = 1;
|
||||||
|
|
||||||
|
if (first_time) {
|
||||||
|
claim_base = _ALIGN_UP((unsigned long)_end, ONE_MB);
|
||||||
|
first_time = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(; claim_base < RAM_END; claim_base += ONE_MB) {
|
||||||
|
#ifdef DEBUG
|
||||||
|
printf(" trying: 0x%08lx\n\r", claim_base);
|
||||||
|
#endif
|
||||||
|
addr = (unsigned long)claim(claim_base, size, 0);
|
||||||
|
if ((void *)addr != (void *)-1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (addr == 0)
|
||||||
|
return NULL;
|
||||||
|
claim_base = PAGE_ALIGN(claim_base + size);
|
||||||
|
return (void *)addr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void of_image_hdr(const void *hdr)
|
||||||
|
{
|
||||||
|
const Elf64_Ehdr *elf64 = hdr;
|
||||||
|
|
||||||
|
if (elf64->e_ident[EI_CLASS] == ELFCLASS64) {
|
||||||
|
/*
|
||||||
|
* Maintain a "magic" minimum address. This keeps some older
|
||||||
|
* firmware platforms running.
|
||||||
|
*/
|
||||||
|
if (claim_base < PROG_START)
|
||||||
|
claim_base = PROG_START;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void of_exit(void)
|
||||||
|
{
|
||||||
|
call_prom("exit", 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OF device tree routines
|
||||||
|
*/
|
||||||
|
static void *of_finddevice(const char *name)
|
||||||
|
{
|
||||||
|
return (phandle) call_prom("finddevice", 1, 1, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int of_getprop(const void *phandle, const char *name, void *buf,
|
||||||
|
const int buflen)
|
||||||
|
{
|
||||||
|
return call_prom("getprop", 4, 1, phandle, name, buf, buflen);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int of_setprop(const void *phandle, const char *name, const void *buf,
|
||||||
|
const int buflen)
|
||||||
|
{
|
||||||
|
return call_prom("setprop", 4, 1, phandle, name, buf, buflen);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* OF console routines
|
||||||
|
*/
|
||||||
|
static void *of_stdout_handle;
|
||||||
|
|
||||||
|
static int of_console_open(void)
|
||||||
|
{
|
||||||
|
void *devp;
|
||||||
|
|
||||||
|
if (((devp = finddevice("/chosen")) != NULL)
|
||||||
|
&& (getprop(devp, "stdout", &of_stdout_handle,
|
||||||
|
sizeof(of_stdout_handle))
|
||||||
|
== sizeof(of_stdout_handle)))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void of_console_write(char *buf, int len)
|
||||||
|
{
|
||||||
|
call_prom("write", 3, 1, of_stdout_handle, buf, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
int platform_init(void *promptr)
|
||||||
|
{
|
||||||
|
platform_ops.fixups = NULL;
|
||||||
|
platform_ops.image_hdr = of_image_hdr;
|
||||||
|
platform_ops.malloc = of_try_claim;
|
||||||
|
platform_ops.free = NULL;
|
||||||
|
platform_ops.exit = of_exit;
|
||||||
|
|
||||||
|
dt_ops.finddevice = of_finddevice;
|
||||||
|
dt_ops.getprop = of_getprop;
|
||||||
|
dt_ops.setprop = of_setprop;
|
||||||
|
dt_ops.translate_addr = NULL;
|
||||||
|
|
||||||
|
console_ops.open = of_console_open;
|
||||||
|
console_ops.write = of_console_write;
|
||||||
|
console_ops.edit_cmdline = NULL;
|
||||||
|
console_ops.close = NULL;
|
||||||
|
console_ops.data = NULL;
|
||||||
|
|
||||||
|
prom = (int (*)(void *))promptr;
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -0,0 +1,100 @@
|
||||||
|
/*
|
||||||
|
* Global definition of all the bootwrapper operations.
|
||||||
|
*
|
||||||
|
* Author: Mark A. Greer <mgreer@mvista.com>
|
||||||
|
*
|
||||||
|
* 2006 (c) MontaVista Software, Inc. This file is licensed under
|
||||||
|
* the terms of the GNU General Public License version 2. This program
|
||||||
|
* is licensed "as is" without any warranty of any kind, whether express
|
||||||
|
* or implied.
|
||||||
|
*/
|
||||||
|
#ifndef _PPC_BOOT_OPS_H_
|
||||||
|
#define _PPC_BOOT_OPS_H_
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
#define COMMAND_LINE_SIZE 512
|
||||||
|
#define MAX_PATH_LEN 256
|
||||||
|
#define MAX_PROP_LEN 256 /* What should this be? */
|
||||||
|
|
||||||
|
/* Platform specific operations */
|
||||||
|
struct platform_ops {
|
||||||
|
void (*fixups)(void);
|
||||||
|
void (*image_hdr)(const void *);
|
||||||
|
void * (*malloc)(u32 size);
|
||||||
|
void (*free)(void *ptr, u32 size);
|
||||||
|
void (*exit)(void);
|
||||||
|
};
|
||||||
|
extern struct platform_ops platform_ops;
|
||||||
|
|
||||||
|
/* Device Tree operations */
|
||||||
|
struct dt_ops {
|
||||||
|
void * (*finddevice)(const char *name);
|
||||||
|
int (*getprop)(const void *node, const char *name, void *buf,
|
||||||
|
const int buflen);
|
||||||
|
int (*setprop)(const void *node, const char *name,
|
||||||
|
const void *buf, const int buflen);
|
||||||
|
u64 (*translate_addr)(const char *path, const u32 *in_addr,
|
||||||
|
const u32 addr_len);
|
||||||
|
unsigned long (*ft_addr)(void);
|
||||||
|
};
|
||||||
|
extern struct dt_ops dt_ops;
|
||||||
|
|
||||||
|
/* Console operations */
|
||||||
|
struct console_ops {
|
||||||
|
int (*open)(void);
|
||||||
|
void (*write)(char *buf, int len);
|
||||||
|
void (*edit_cmdline)(char *buf, int len);
|
||||||
|
void (*close)(void);
|
||||||
|
void *data;
|
||||||
|
};
|
||||||
|
extern struct console_ops console_ops;
|
||||||
|
|
||||||
|
/* Serial console operations */
|
||||||
|
struct serial_console_data {
|
||||||
|
int (*open)(void);
|
||||||
|
void (*putc)(unsigned char c);
|
||||||
|
unsigned char (*getc)(void);
|
||||||
|
u8 (*tstc)(void);
|
||||||
|
void (*close)(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
extern int platform_init(void *promptr);
|
||||||
|
extern void simple_alloc_init(void);
|
||||||
|
extern void ft_init(void *dt_blob);
|
||||||
|
extern int serial_console_init(void);
|
||||||
|
|
||||||
|
static inline void *finddevice(const char *name)
|
||||||
|
{
|
||||||
|
return (dt_ops.finddevice) ? dt_ops.finddevice(name) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int getprop(void *devp, const char *name, void *buf, int buflen)
|
||||||
|
{
|
||||||
|
return (dt_ops.getprop) ? dt_ops.getprop(devp, name, buf, buflen) : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline int setprop(void *devp, const char *name, void *buf, int buflen)
|
||||||
|
{
|
||||||
|
return (dt_ops.setprop) ? dt_ops.setprop(devp, name, buf, buflen) : -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void *malloc(u32 size)
|
||||||
|
{
|
||||||
|
return (platform_ops.malloc) ? platform_ops.malloc(size) : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void free(void *ptr, u32 size)
|
||||||
|
{
|
||||||
|
if (platform_ops.free)
|
||||||
|
platform_ops.free(ptr, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void exit(void)
|
||||||
|
{
|
||||||
|
if (platform_ops.exit)
|
||||||
|
platform_ops.exit();
|
||||||
|
for(;;);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* _PPC_BOOT_OPS_H_ */
|
|
@ -1,41 +0,0 @@
|
||||||
#ifndef _PPC_BOOT_PROM_H_
|
|
||||||
#define _PPC_BOOT_PROM_H_
|
|
||||||
|
|
||||||
typedef void *phandle;
|
|
||||||
typedef void *ihandle;
|
|
||||||
|
|
||||||
extern int (*prom) (void *);
|
|
||||||
extern phandle chosen_handle;
|
|
||||||
extern ihandle stdout;
|
|
||||||
|
|
||||||
int call_prom(const char *service, int nargs, int nret, ...);
|
|
||||||
int call_prom_ret(const char *service, int nargs, int nret,
|
|
||||||
unsigned int *rets, ...);
|
|
||||||
|
|
||||||
extern int write(void *handle, void *ptr, int nb);
|
|
||||||
extern void *claim(unsigned long virt, unsigned long size, unsigned long aln);
|
|
||||||
|
|
||||||
static inline void exit(void)
|
|
||||||
{
|
|
||||||
call_prom("exit", 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline phandle finddevice(const char *name)
|
|
||||||
{
|
|
||||||
return (phandle) call_prom("finddevice", 1, 1, name);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int getprop(void *phandle, const char *name,
|
|
||||||
void *buf, int buflen)
|
|
||||||
{
|
|
||||||
return call_prom("getprop", 4, 1, phandle, name, buf, buflen);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static inline int setprop(void *phandle, const char *name,
|
|
||||||
void *buf, int buflen)
|
|
||||||
{
|
|
||||||
return call_prom("setprop", 4, 1, phandle, name, buf, buflen);
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif /* _PPC_BOOT_PROM_H_ */
|
|
|
@ -10,7 +10,7 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include "string.h"
|
#include "string.h"
|
||||||
#include "stdio.h"
|
#include "stdio.h"
|
||||||
#include "prom.h"
|
#include "ops.h"
|
||||||
|
|
||||||
size_t strnlen(const char * s, size_t count)
|
size_t strnlen(const char * s, size_t count)
|
||||||
{
|
{
|
||||||
|
@ -320,6 +320,6 @@ printf(const char *fmt, ...)
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
n = vsprintf(sprint_buf, fmt, args);
|
n = vsprintf(sprint_buf, fmt, args);
|
||||||
va_end(args);
|
va_end(args);
|
||||||
write(stdout, sprint_buf, n);
|
console_ops.write(sprint_buf, n);
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,16 @@
|
||||||
#ifndef _PPC_BOOT_STDIO_H_
|
#ifndef _PPC_BOOT_STDIO_H_
|
||||||
#define _PPC_BOOT_STDIO_H_
|
#define _PPC_BOOT_STDIO_H_
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#define ENOMEM 12 /* Out of Memory */
|
||||||
|
#define EINVAL 22 /* Invalid argument */
|
||||||
|
#define ENOSPC 28 /* No space left on device */
|
||||||
|
|
||||||
extern int printf(const char *fmt, ...);
|
extern int printf(const char *fmt, ...);
|
||||||
|
|
||||||
|
#define fprintf(fmt, args...) printf(args)
|
||||||
|
|
||||||
extern int sprintf(char *buf, const char *fmt, ...);
|
extern int sprintf(char *buf, const char *fmt, ...);
|
||||||
|
|
||||||
extern int vsprintf(char *buf, const char *fmt, va_list args);
|
extern int vsprintf(char *buf, const char *fmt, va_list args);
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
#ifndef _TYPES_H_
|
||||||
|
#define _TYPES_H_
|
||||||
|
|
||||||
|
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
|
||||||
|
|
||||||
|
typedef unsigned char u8;
|
||||||
|
typedef unsigned short u16;
|
||||||
|
typedef unsigned int u32;
|
||||||
|
typedef unsigned long long u64;
|
||||||
|
|
||||||
|
#define min(x,y) ({ \
|
||||||
|
typeof(x) _x = (x); \
|
||||||
|
typeof(y) _y = (y); \
|
||||||
|
(void) (&_x == &_y); \
|
||||||
|
_x < _y ? _x : _y; })
|
||||||
|
|
||||||
|
#define max(x,y) ({ \
|
||||||
|
typeof(x) _x = (x); \
|
||||||
|
typeof(y) _y = (y); \
|
||||||
|
(void) (&_x == &_y); \
|
||||||
|
_x > _y ? _x : _y; })
|
||||||
|
|
||||||
|
#endif /* _TYPES_H_ */
|
|
@ -496,7 +496,7 @@ CONFIG_E1000=y
|
||||||
# CONFIG_SKY2 is not set
|
# CONFIG_SKY2 is not set
|
||||||
# CONFIG_SK98LIN is not set
|
# CONFIG_SK98LIN is not set
|
||||||
# CONFIG_VIA_VELOCITY is not set
|
# CONFIG_VIA_VELOCITY is not set
|
||||||
# CONFIG_TIGON3 is not set
|
CONFIG_TIGON3=y
|
||||||
# CONFIG_BNX2 is not set
|
# CONFIG_BNX2 is not set
|
||||||
# CONFIG_MV643XX_ETH is not set
|
# CONFIG_MV643XX_ETH is not set
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ obj-y := semaphore.o cputable.o ptrace.o syscalls.o \
|
||||||
obj-y += vdso32/
|
obj-y += vdso32/
|
||||||
obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
|
obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
|
||||||
signal_64.o ptrace32.o \
|
signal_64.o ptrace32.o \
|
||||||
paca.o cpu_setup_power4.o \
|
paca.o cpu_setup_ppc970.o \
|
||||||
firmware.o sysfs.o
|
firmware.o sysfs.o
|
||||||
obj-$(CONFIG_PPC64) += vdso64/
|
obj-$(CONFIG_PPC64) += vdso64/
|
||||||
obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
|
obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
|
||||||
|
@ -51,7 +51,7 @@ extra-$(CONFIG_8xx) := head_8xx.o
|
||||||
extra-y += vmlinux.lds
|
extra-y += vmlinux.lds
|
||||||
|
|
||||||
obj-y += time.o prom.o traps.o setup-common.o \
|
obj-y += time.o prom.o traps.o setup-common.o \
|
||||||
udbg.o misc.o
|
udbg.o misc.o io.o
|
||||||
obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o
|
obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o
|
||||||
obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o
|
obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o
|
||||||
obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o
|
obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o
|
||||||
|
|
|
@ -40,9 +40,10 @@
|
||||||
#ifdef CONFIG_PPC64
|
#ifdef CONFIG_PPC64
|
||||||
#include <asm/paca.h>
|
#include <asm/paca.h>
|
||||||
#include <asm/lppaca.h>
|
#include <asm/lppaca.h>
|
||||||
#include <asm/iseries/hv_lp_event.h>
|
|
||||||
#include <asm/cache.h>
|
#include <asm/cache.h>
|
||||||
#include <asm/compat.h>
|
#include <asm/compat.h>
|
||||||
|
#include <asm/mmu.h>
|
||||||
|
#include <asm/hvcall.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DEFINE(sym, val) \
|
#define DEFINE(sym, val) \
|
||||||
|
@ -136,11 +137,18 @@ int main(void)
|
||||||
DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr));
|
DEFINE(PACA_STARTPURR, offsetof(struct paca_struct, startpurr));
|
||||||
DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
|
DEFINE(PACA_USER_TIME, offsetof(struct paca_struct, user_time));
|
||||||
DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
|
DEFINE(PACA_SYSTEM_TIME, offsetof(struct paca_struct, system_time));
|
||||||
|
DEFINE(PACA_SLBSHADOWPTR, offsetof(struct paca_struct, slb_shadow_ptr));
|
||||||
|
DEFINE(PACA_DATA_OFFSET, offsetof(struct paca_struct, data_offset));
|
||||||
|
|
||||||
|
DEFINE(SLBSHADOW_STACKVSID,
|
||||||
|
offsetof(struct slb_shadow, save_area[SLB_NUM_BOLTED - 1].vsid));
|
||||||
|
DEFINE(SLBSHADOW_STACKESID,
|
||||||
|
offsetof(struct slb_shadow, save_area[SLB_NUM_BOLTED - 1].esid));
|
||||||
DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0));
|
DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0));
|
||||||
DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1));
|
DEFINE(LPPACASRR1, offsetof(struct lppaca, saved_srr1));
|
||||||
DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int));
|
DEFINE(LPPACAANYINT, offsetof(struct lppaca, int_dword.any_int));
|
||||||
DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int));
|
DEFINE(LPPACADECRINT, offsetof(struct lppaca, int_dword.fields.decr_int));
|
||||||
|
DEFINE(SLBSHADOW_SAVEAREA, offsetof(struct slb_shadow, save_area));
|
||||||
#endif /* CONFIG_PPC64 */
|
#endif /* CONFIG_PPC64 */
|
||||||
|
|
||||||
/* RTAS */
|
/* RTAS */
|
||||||
|
@ -159,6 +167,12 @@ int main(void)
|
||||||
/* Create extra stack space for SRR0 and SRR1 when calling prom/rtas. */
|
/* Create extra stack space for SRR0 and SRR1 when calling prom/rtas. */
|
||||||
DEFINE(PROM_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16);
|
DEFINE(PROM_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16);
|
||||||
DEFINE(RTAS_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16);
|
DEFINE(RTAS_FRAME_SIZE, STACK_FRAME_OVERHEAD + sizeof(struct pt_regs) + 16);
|
||||||
|
|
||||||
|
/* hcall statistics */
|
||||||
|
DEFINE(HCALL_STAT_SIZE, sizeof(struct hcall_stats));
|
||||||
|
DEFINE(HCALL_STAT_CALLS, offsetof(struct hcall_stats, num_calls));
|
||||||
|
DEFINE(HCALL_STAT_TB, offsetof(struct hcall_stats, tb_total));
|
||||||
|
DEFINE(HCALL_STAT_PURR, offsetof(struct hcall_stats, purr_total));
|
||||||
#endif /* CONFIG_PPC64 */
|
#endif /* CONFIG_PPC64 */
|
||||||
DEFINE(GPR0, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[0]));
|
DEFINE(GPR0, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[0]));
|
||||||
DEFINE(GPR1, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[1]));
|
DEFINE(GPR1, STACK_FRAME_OVERHEAD+offsetof(struct pt_regs, gpr[1]));
|
||||||
|
@ -240,6 +254,7 @@ int main(void)
|
||||||
DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value));
|
DEFINE(CPU_SPEC_PVR_VALUE, offsetof(struct cpu_spec, pvr_value));
|
||||||
DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
|
DEFINE(CPU_SPEC_FEATURES, offsetof(struct cpu_spec, cpu_features));
|
||||||
DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
|
DEFINE(CPU_SPEC_SETUP, offsetof(struct cpu_spec, cpu_setup));
|
||||||
|
DEFINE(CPU_SPEC_RESTORE, offsetof(struct cpu_spec, cpu_restore));
|
||||||
|
|
||||||
#ifndef CONFIG_PPC64
|
#ifndef CONFIG_PPC64
|
||||||
DEFINE(pbe_address, offsetof(struct pbe, address));
|
DEFINE(pbe_address, offsetof(struct pbe, address));
|
||||||
|
|
|
@ -158,35 +158,35 @@ int btext_initialize(struct device_node *np)
|
||||||
{
|
{
|
||||||
unsigned int width, height, depth, pitch;
|
unsigned int width, height, depth, pitch;
|
||||||
unsigned long address = 0;
|
unsigned long address = 0;
|
||||||
u32 *prop;
|
const u32 *prop;
|
||||||
|
|
||||||
prop = (u32 *)get_property(np, "linux,bootx-width", NULL);
|
prop = get_property(np, "linux,bootx-width", NULL);
|
||||||
if (prop == NULL)
|
if (prop == NULL)
|
||||||
prop = (u32 *)get_property(np, "width", NULL);
|
prop = get_property(np, "width", NULL);
|
||||||
if (prop == NULL)
|
if (prop == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
width = *prop;
|
width = *prop;
|
||||||
prop = (u32 *)get_property(np, "linux,bootx-height", NULL);
|
prop = get_property(np, "linux,bootx-height", NULL);
|
||||||
if (prop == NULL)
|
if (prop == NULL)
|
||||||
prop = (u32 *)get_property(np, "height", NULL);
|
prop = get_property(np, "height", NULL);
|
||||||
if (prop == NULL)
|
if (prop == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
height = *prop;
|
height = *prop;
|
||||||
prop = (u32 *)get_property(np, "linux,bootx-depth", NULL);
|
prop = get_property(np, "linux,bootx-depth", NULL);
|
||||||
if (prop == NULL)
|
if (prop == NULL)
|
||||||
prop = (u32 *)get_property(np, "depth", NULL);
|
prop = get_property(np, "depth", NULL);
|
||||||
if (prop == NULL)
|
if (prop == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
depth = *prop;
|
depth = *prop;
|
||||||
pitch = width * ((depth + 7) / 8);
|
pitch = width * ((depth + 7) / 8);
|
||||||
prop = (u32 *)get_property(np, "linux,bootx-linebytes", NULL);
|
prop = get_property(np, "linux,bootx-linebytes", NULL);
|
||||||
if (prop == NULL)
|
if (prop == NULL)
|
||||||
prop = (u32 *)get_property(np, "linebytes", NULL);
|
prop = get_property(np, "linebytes", NULL);
|
||||||
if (prop)
|
if (prop)
|
||||||
pitch = *prop;
|
pitch = *prop;
|
||||||
if (pitch == 1)
|
if (pitch == 1)
|
||||||
pitch = 0x1000;
|
pitch = 0x1000;
|
||||||
prop = (u32 *)get_property(np, "address", NULL);
|
prop = get_property(np, "address", NULL);
|
||||||
if (prop)
|
if (prop)
|
||||||
address = *prop;
|
address = *prop;
|
||||||
|
|
||||||
|
@ -214,11 +214,11 @@ int btext_initialize(struct device_node *np)
|
||||||
|
|
||||||
int __init btext_find_display(int allow_nonstdout)
|
int __init btext_find_display(int allow_nonstdout)
|
||||||
{
|
{
|
||||||
char *name;
|
const char *name;
|
||||||
struct device_node *np = NULL;
|
struct device_node *np = NULL;
|
||||||
int rc = -ENODEV;
|
int rc = -ENODEV;
|
||||||
|
|
||||||
name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
|
name = get_property(of_chosen, "linux,stdout-path", NULL);
|
||||||
if (name != NULL) {
|
if (name != NULL) {
|
||||||
np = of_find_node_by_path(name);
|
np = of_find_node_by_path(name);
|
||||||
if (np != NULL) {
|
if (np != NULL) {
|
||||||
|
|
|
@ -16,27 +16,12 @@
|
||||||
#include <asm/asm-offsets.h>
|
#include <asm/asm-offsets.h>
|
||||||
#include <asm/cache.h>
|
#include <asm/cache.h>
|
||||||
|
|
||||||
_GLOBAL(__970_cpu_preinit)
|
_GLOBAL(__cpu_preinit_ppc970)
|
||||||
/*
|
/* Do nothing if not running in HV mode */
|
||||||
* Do nothing if not running in HV mode
|
|
||||||
*/
|
|
||||||
mfmsr r0
|
mfmsr r0
|
||||||
rldicl. r0,r0,4,63
|
rldicl. r0,r0,4,63
|
||||||
beqlr
|
beqlr
|
||||||
|
|
||||||
/*
|
|
||||||
* Deal only with PPC970 and PPC970FX.
|
|
||||||
*/
|
|
||||||
mfspr r0,SPRN_PVR
|
|
||||||
srwi r0,r0,16
|
|
||||||
cmpwi r0,0x39
|
|
||||||
beq 1f
|
|
||||||
cmpwi r0,0x3c
|
|
||||||
beq 1f
|
|
||||||
cmpwi r0,0x44
|
|
||||||
bnelr
|
|
||||||
1:
|
|
||||||
|
|
||||||
/* Make sure HID4:rm_ci is off before MMU is turned off, that large
|
/* Make sure HID4:rm_ci is off before MMU is turned off, that large
|
||||||
* pages are enabled with HID4:61 and clear HID5:DCBZ_size and
|
* pages are enabled with HID4:61 and clear HID5:DCBZ_size and
|
||||||
* HID5:DCBZ32_ill
|
* HID5:DCBZ32_ill
|
||||||
|
@ -72,23 +57,6 @@ _GLOBAL(__970_cpu_preinit)
|
||||||
isync
|
isync
|
||||||
blr
|
blr
|
||||||
|
|
||||||
_GLOBAL(__setup_cpu_ppc970)
|
|
||||||
mfspr r0,SPRN_HID0
|
|
||||||
li r11,5 /* clear DOZE and SLEEP */
|
|
||||||
rldimi r0,r11,52,8 /* set NAP and DPM */
|
|
||||||
li r11,0
|
|
||||||
rldimi r0,r11,32,31 /* clear EN_ATTN */
|
|
||||||
mtspr SPRN_HID0,r0
|
|
||||||
mfspr r0,SPRN_HID0
|
|
||||||
mfspr r0,SPRN_HID0
|
|
||||||
mfspr r0,SPRN_HID0
|
|
||||||
mfspr r0,SPRN_HID0
|
|
||||||
mfspr r0,SPRN_HID0
|
|
||||||
mfspr r0,SPRN_HID0
|
|
||||||
sync
|
|
||||||
isync
|
|
||||||
blr
|
|
||||||
|
|
||||||
/* Definitions for the table use to save CPU states */
|
/* Definitions for the table use to save CPU states */
|
||||||
#define CS_HID0 0
|
#define CS_HID0 0
|
||||||
#define CS_HID1 8
|
#define CS_HID1 8
|
||||||
|
@ -103,33 +71,30 @@ cpu_state_storage:
|
||||||
.balign L1_CACHE_BYTES,0
|
.balign L1_CACHE_BYTES,0
|
||||||
.text
|
.text
|
||||||
|
|
||||||
/* Called in normal context to backup CPU 0 state. This
|
|
||||||
* does not include cache settings. This function is also
|
|
||||||
* called for machine sleep. This does not include the MMU
|
|
||||||
* setup, BATs, etc... but rather the "special" registers
|
|
||||||
* like HID0, HID1, HID4, etc...
|
|
||||||
*/
|
|
||||||
_GLOBAL(__save_cpu_setup)
|
|
||||||
/* Some CR fields are volatile, we back it up all */
|
|
||||||
mfcr r7
|
|
||||||
|
|
||||||
/* Get storage ptr */
|
_GLOBAL(__setup_cpu_ppc970)
|
||||||
LOAD_REG_IMMEDIATE(r5,cpu_state_storage)
|
/* Do nothing if not running in HV mode */
|
||||||
|
|
||||||
/* We only deal with 970 for now */
|
|
||||||
mfspr r0,SPRN_PVR
|
|
||||||
srwi r0,r0,16
|
|
||||||
cmpwi r0,0x39
|
|
||||||
beq 1f
|
|
||||||
cmpwi r0,0x3c
|
|
||||||
beq 1f
|
|
||||||
cmpwi r0,0x44
|
|
||||||
bne 2f
|
|
||||||
|
|
||||||
1: /* skip if not running in HV mode */
|
|
||||||
mfmsr r0
|
mfmsr r0
|
||||||
rldicl. r0,r0,4,63
|
rldicl. r0,r0,4,63
|
||||||
beq 2f
|
beqlr
|
||||||
|
|
||||||
|
mfspr r0,SPRN_HID0
|
||||||
|
li r11,5 /* clear DOZE and SLEEP */
|
||||||
|
rldimi r0,r11,52,8 /* set NAP and DPM */
|
||||||
|
li r11,0
|
||||||
|
rldimi r0,r11,32,31 /* clear EN_ATTN */
|
||||||
|
mtspr SPRN_HID0,r0
|
||||||
|
mfspr r0,SPRN_HID0
|
||||||
|
mfspr r0,SPRN_HID0
|
||||||
|
mfspr r0,SPRN_HID0
|
||||||
|
mfspr r0,SPRN_HID0
|
||||||
|
mfspr r0,SPRN_HID0
|
||||||
|
mfspr r0,SPRN_HID0
|
||||||
|
sync
|
||||||
|
isync
|
||||||
|
|
||||||
|
/* Save away cpu state */
|
||||||
|
LOAD_REG_IMMEDIATE(r5,cpu_state_storage)
|
||||||
|
|
||||||
/* Save HID0,1,4 and 5 */
|
/* Save HID0,1,4 and 5 */
|
||||||
mfspr r3,SPRN_HID0
|
mfspr r3,SPRN_HID0
|
||||||
|
@ -141,35 +106,19 @@ _GLOBAL(__save_cpu_setup)
|
||||||
mfspr r3,SPRN_HID5
|
mfspr r3,SPRN_HID5
|
||||||
std r3,CS_HID5(r5)
|
std r3,CS_HID5(r5)
|
||||||
|
|
||||||
2:
|
|
||||||
mtcr r7
|
|
||||||
blr
|
blr
|
||||||
|
|
||||||
/* Called with no MMU context (typically MSR:IR/DR off) to
|
/* Called with no MMU context (typically MSR:IR/DR off) to
|
||||||
* restore CPU state as backed up by the previous
|
* restore CPU state as backed up by the previous
|
||||||
* function. This does not include cache setting
|
* function. This does not include cache setting
|
||||||
*/
|
*/
|
||||||
_GLOBAL(__restore_cpu_setup)
|
_GLOBAL(__restore_cpu_ppc970)
|
||||||
/* Get storage ptr (FIXME when using anton reloc as we
|
/* Do nothing if not running in HV mode */
|
||||||
* are running with translation disabled here
|
|
||||||
*/
|
|
||||||
LOAD_REG_IMMEDIATE(r5,cpu_state_storage)
|
|
||||||
|
|
||||||
/* We only deal with 970 for now */
|
|
||||||
mfspr r0,SPRN_PVR
|
|
||||||
srwi r0,r0,16
|
|
||||||
cmpwi r0,0x39
|
|
||||||
beq 1f
|
|
||||||
cmpwi r0,0x3c
|
|
||||||
beq 1f
|
|
||||||
cmpwi r0,0x44
|
|
||||||
bnelr
|
|
||||||
|
|
||||||
1: /* skip if not running in HV mode */
|
|
||||||
mfmsr r0
|
mfmsr r0
|
||||||
rldicl. r0,r0,4,63
|
rldicl. r0,r0,4,63
|
||||||
beqlr
|
beqlr
|
||||||
|
|
||||||
|
LOAD_REG_IMMEDIATE(r5,cpu_state_storage)
|
||||||
/* Before accessing memory, we make sure rm_ci is clear */
|
/* Before accessing memory, we make sure rm_ci is clear */
|
||||||
li r0,0
|
li r0,0
|
||||||
mfspr r3,SPRN_HID4
|
mfspr r3,SPRN_HID4
|
|
@ -39,7 +39,10 @@ extern void __setup_cpu_7400(unsigned long offset, struct cpu_spec* spec);
|
||||||
extern void __setup_cpu_7410(unsigned long offset, struct cpu_spec* spec);
|
extern void __setup_cpu_7410(unsigned long offset, struct cpu_spec* spec);
|
||||||
extern void __setup_cpu_745x(unsigned long offset, struct cpu_spec* spec);
|
extern void __setup_cpu_745x(unsigned long offset, struct cpu_spec* spec);
|
||||||
#endif /* CONFIG_PPC32 */
|
#endif /* CONFIG_PPC32 */
|
||||||
|
#ifdef CONFIG_PPC64
|
||||||
extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
|
extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
|
||||||
|
extern void __restore_cpu_ppc970(void);
|
||||||
|
#endif /* CONFIG_PPC64 */
|
||||||
|
|
||||||
/* This table only contains "desktop" CPUs, it need to be filled with embedded
|
/* This table only contains "desktop" CPUs, it need to be filled with embedded
|
||||||
* ones as well...
|
* ones as well...
|
||||||
|
@ -55,6 +58,9 @@ extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
|
||||||
#define COMMON_USER_POWER6 (COMMON_USER_PPC64 | PPC_FEATURE_ARCH_2_05 |\
|
#define COMMON_USER_POWER6 (COMMON_USER_PPC64 | PPC_FEATURE_ARCH_2_05 |\
|
||||||
PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP | \
|
PPC_FEATURE_SMT | PPC_FEATURE_ICACHE_SNOOP | \
|
||||||
PPC_FEATURE_TRUE_LE)
|
PPC_FEATURE_TRUE_LE)
|
||||||
|
#define COMMON_USER_PA6T (COMMON_USER_PPC64 | PPC_FEATURE_PA6T |\
|
||||||
|
PPC_FEATURE_TRUE_LE | \
|
||||||
|
PPC_FEATURE_HAS_ALTIVEC_COMP)
|
||||||
#define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \
|
#define COMMON_USER_BOOKE (PPC_FEATURE_32 | PPC_FEATURE_HAS_MMU | \
|
||||||
PPC_FEATURE_BOOKE)
|
PPC_FEATURE_BOOKE)
|
||||||
|
|
||||||
|
@ -184,6 +190,7 @@ struct cpu_spec cpu_specs[] = {
|
||||||
.dcache_bsize = 128,
|
.dcache_bsize = 128,
|
||||||
.num_pmcs = 8,
|
.num_pmcs = 8,
|
||||||
.cpu_setup = __setup_cpu_ppc970,
|
.cpu_setup = __setup_cpu_ppc970,
|
||||||
|
.cpu_restore = __restore_cpu_ppc970,
|
||||||
.oprofile_cpu_type = "ppc64/970",
|
.oprofile_cpu_type = "ppc64/970",
|
||||||
.oprofile_type = PPC_OPROFILE_POWER4,
|
.oprofile_type = PPC_OPROFILE_POWER4,
|
||||||
.platform = "ppc970",
|
.platform = "ppc970",
|
||||||
|
@ -199,6 +206,7 @@ struct cpu_spec cpu_specs[] = {
|
||||||
.dcache_bsize = 128,
|
.dcache_bsize = 128,
|
||||||
.num_pmcs = 8,
|
.num_pmcs = 8,
|
||||||
.cpu_setup = __setup_cpu_ppc970,
|
.cpu_setup = __setup_cpu_ppc970,
|
||||||
|
.cpu_restore = __restore_cpu_ppc970,
|
||||||
.oprofile_cpu_type = "ppc64/970",
|
.oprofile_cpu_type = "ppc64/970",
|
||||||
.oprofile_type = PPC_OPROFILE_POWER4,
|
.oprofile_type = PPC_OPROFILE_POWER4,
|
||||||
.platform = "ppc970",
|
.platform = "ppc970",
|
||||||
|
@ -214,6 +222,7 @@ struct cpu_spec cpu_specs[] = {
|
||||||
.dcache_bsize = 128,
|
.dcache_bsize = 128,
|
||||||
.num_pmcs = 8,
|
.num_pmcs = 8,
|
||||||
.cpu_setup = __setup_cpu_ppc970,
|
.cpu_setup = __setup_cpu_ppc970,
|
||||||
|
.cpu_restore = __restore_cpu_ppc970,
|
||||||
.oprofile_cpu_type = "ppc64/970",
|
.oprofile_cpu_type = "ppc64/970",
|
||||||
.oprofile_type = PPC_OPROFILE_POWER4,
|
.oprofile_type = PPC_OPROFILE_POWER4,
|
||||||
.platform = "ppc970",
|
.platform = "ppc970",
|
||||||
|
@ -280,6 +289,17 @@ struct cpu_spec cpu_specs[] = {
|
||||||
.dcache_bsize = 128,
|
.dcache_bsize = 128,
|
||||||
.platform = "ppc-cell-be",
|
.platform = "ppc-cell-be",
|
||||||
},
|
},
|
||||||
|
{ /* PA Semi PA6T */
|
||||||
|
.pvr_mask = 0x7fff0000,
|
||||||
|
.pvr_value = 0x00900000,
|
||||||
|
.cpu_name = "PA6T",
|
||||||
|
.cpu_features = CPU_FTRS_PA6T,
|
||||||
|
.cpu_user_features = COMMON_USER_PA6T,
|
||||||
|
.icache_bsize = 64,
|
||||||
|
.dcache_bsize = 64,
|
||||||
|
.num_pmcs = 6,
|
||||||
|
.platform = "pa6t",
|
||||||
|
},
|
||||||
{ /* default match */
|
{ /* default match */
|
||||||
.pvr_mask = 0x00000000,
|
.pvr_mask = 0x00000000,
|
||||||
.pvr_value = 0x00000000,
|
.pvr_value = 0x00000000,
|
||||||
|
@ -929,6 +949,7 @@ struct cpu_spec cpu_specs[] = {
|
||||||
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
|
PPC_FEATURE_HAS_MMU | PPC_FEATURE_HAS_4xxMAC,
|
||||||
.icache_bsize = 32,
|
.icache_bsize = 32,
|
||||||
.dcache_bsize = 32,
|
.dcache_bsize = 32,
|
||||||
|
.platform = "ppc405",
|
||||||
},
|
},
|
||||||
{ /* 405EP */
|
{ /* 405EP */
|
||||||
.pvr_mask = 0xffff0000,
|
.pvr_mask = 0xffff0000,
|
||||||
|
|
|
@ -80,7 +80,7 @@ static int __init parse_savemaxmem(char *p)
|
||||||
}
|
}
|
||||||
__setup("savemaxmem=", parse_savemaxmem);
|
__setup("savemaxmem=", parse_savemaxmem);
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* copy_oldmem_page - copy one page from "oldmem"
|
* copy_oldmem_page - copy one page from "oldmem"
|
||||||
* @pfn: page frame number to be copied
|
* @pfn: page frame number to be copied
|
||||||
* @buf: target memory address for the copy; this can be in kernel address
|
* @buf: target memory address for the copy; this can be in kernel address
|
||||||
|
|
|
@ -35,10 +35,9 @@ int dma_supported(struct device *dev, u64 mask)
|
||||||
{
|
{
|
||||||
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
||||||
|
|
||||||
if (dma_ops)
|
BUG_ON(!dma_ops);
|
||||||
|
|
||||||
return dma_ops->dma_supported(dev, mask);
|
return dma_ops->dma_supported(dev, mask);
|
||||||
BUG();
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dma_supported);
|
EXPORT_SYMBOL(dma_supported);
|
||||||
|
|
||||||
|
@ -66,10 +65,9 @@ void *dma_alloc_coherent(struct device *dev, size_t size,
|
||||||
{
|
{
|
||||||
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
||||||
|
|
||||||
if (dma_ops)
|
BUG_ON(!dma_ops);
|
||||||
|
|
||||||
return dma_ops->alloc_coherent(dev, size, dma_handle, flag);
|
return dma_ops->alloc_coherent(dev, size, dma_handle, flag);
|
||||||
BUG();
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dma_alloc_coherent);
|
EXPORT_SYMBOL(dma_alloc_coherent);
|
||||||
|
|
||||||
|
@ -78,10 +76,9 @@ void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
|
||||||
{
|
{
|
||||||
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
||||||
|
|
||||||
if (dma_ops)
|
BUG_ON(!dma_ops);
|
||||||
|
|
||||||
dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
|
dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
|
||||||
else
|
|
||||||
BUG();
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dma_free_coherent);
|
EXPORT_SYMBOL(dma_free_coherent);
|
||||||
|
|
||||||
|
@ -90,10 +87,9 @@ dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, size_t size,
|
||||||
{
|
{
|
||||||
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
||||||
|
|
||||||
if (dma_ops)
|
BUG_ON(!dma_ops);
|
||||||
|
|
||||||
return dma_ops->map_single(dev, cpu_addr, size, direction);
|
return dma_ops->map_single(dev, cpu_addr, size, direction);
|
||||||
BUG();
|
|
||||||
return (dma_addr_t)0;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dma_map_single);
|
EXPORT_SYMBOL(dma_map_single);
|
||||||
|
|
||||||
|
@ -102,10 +98,9 @@ void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
|
||||||
{
|
{
|
||||||
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
||||||
|
|
||||||
if (dma_ops)
|
BUG_ON(!dma_ops);
|
||||||
|
|
||||||
dma_ops->unmap_single(dev, dma_addr, size, direction);
|
dma_ops->unmap_single(dev, dma_addr, size, direction);
|
||||||
else
|
|
||||||
BUG();
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dma_unmap_single);
|
EXPORT_SYMBOL(dma_unmap_single);
|
||||||
|
|
||||||
|
@ -115,11 +110,10 @@ dma_addr_t dma_map_page(struct device *dev, struct page *page,
|
||||||
{
|
{
|
||||||
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
||||||
|
|
||||||
if (dma_ops)
|
BUG_ON(!dma_ops);
|
||||||
return dma_ops->map_single(dev,
|
|
||||||
(page_address(page) + offset), size, direction);
|
return dma_ops->map_single(dev, page_address(page) + offset, size,
|
||||||
BUG();
|
direction);
|
||||||
return (dma_addr_t)0;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dma_map_page);
|
EXPORT_SYMBOL(dma_map_page);
|
||||||
|
|
||||||
|
@ -128,10 +122,9 @@ void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
|
||||||
{
|
{
|
||||||
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
||||||
|
|
||||||
if (dma_ops)
|
BUG_ON(!dma_ops);
|
||||||
|
|
||||||
dma_ops->unmap_single(dev, dma_address, size, direction);
|
dma_ops->unmap_single(dev, dma_address, size, direction);
|
||||||
else
|
|
||||||
BUG();
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dma_unmap_page);
|
EXPORT_SYMBOL(dma_unmap_page);
|
||||||
|
|
||||||
|
@ -140,10 +133,9 @@ int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
|
||||||
{
|
{
|
||||||
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
||||||
|
|
||||||
if (dma_ops)
|
BUG_ON(!dma_ops);
|
||||||
|
|
||||||
return dma_ops->map_sg(dev, sg, nents, direction);
|
return dma_ops->map_sg(dev, sg, nents, direction);
|
||||||
BUG();
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dma_map_sg);
|
EXPORT_SYMBOL(dma_map_sg);
|
||||||
|
|
||||||
|
@ -152,9 +144,8 @@ void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
|
||||||
{
|
{
|
||||||
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
|
||||||
|
|
||||||
if (dma_ops)
|
BUG_ON(!dma_ops);
|
||||||
|
|
||||||
dma_ops->unmap_sg(dev, sg, nhwentries, direction);
|
dma_ops->unmap_sg(dev, sg, nhwentries, direction);
|
||||||
else
|
|
||||||
BUG();
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(dma_unmap_sg);
|
EXPORT_SYMBOL(dma_unmap_sg);
|
||||||
|
|
|
@ -375,6 +375,14 @@ BEGIN_FTR_SECTION
|
||||||
ld r7,KSP_VSID(r4) /* Get new stack's VSID */
|
ld r7,KSP_VSID(r4) /* Get new stack's VSID */
|
||||||
oris r0,r6,(SLB_ESID_V)@h
|
oris r0,r6,(SLB_ESID_V)@h
|
||||||
ori r0,r0,(SLB_NUM_BOLTED-1)@l
|
ori r0,r0,(SLB_NUM_BOLTED-1)@l
|
||||||
|
|
||||||
|
/* Update the last bolted SLB */
|
||||||
|
ld r9,PACA_SLBSHADOWPTR(r13)
|
||||||
|
li r12,0
|
||||||
|
std r12,SLBSHADOW_STACKESID(r9) /* Clear ESID */
|
||||||
|
std r7,SLBSHADOW_STACKVSID(r9) /* Save VSID */
|
||||||
|
std r0,SLBSHADOW_STACKESID(r9) /* Save ESID */
|
||||||
|
|
||||||
slbie r6
|
slbie r6
|
||||||
slbie r6 /* Workaround POWER5 < DD2.1 issue */
|
slbie r6 /* Workaround POWER5 < DD2.1 issue */
|
||||||
slbmte r7,r0
|
slbmte r7,r0
|
||||||
|
|
|
@ -132,7 +132,7 @@ _GLOBAL(__secondary_hold)
|
||||||
bne 100b
|
bne 100b
|
||||||
|
|
||||||
#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
|
#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
|
||||||
LOAD_REG_IMMEDIATE(r4, .pSeries_secondary_smp_init)
|
LOAD_REG_IMMEDIATE(r4, .generic_secondary_smp_init)
|
||||||
mtctr r4
|
mtctr r4
|
||||||
mr r3,r24
|
mr r3,r24
|
||||||
bctr
|
bctr
|
||||||
|
@ -1484,19 +1484,17 @@ fwnmi_data_area:
|
||||||
. = 0x8000
|
. = 0x8000
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* On pSeries, secondary processors spin in the following code.
|
* On pSeries and most other platforms, secondary processors spin
|
||||||
|
* in the following code.
|
||||||
* At entry, r3 = this processor's number (physical cpu id)
|
* At entry, r3 = this processor's number (physical cpu id)
|
||||||
*/
|
*/
|
||||||
_GLOBAL(pSeries_secondary_smp_init)
|
_GLOBAL(generic_secondary_smp_init)
|
||||||
mr r24,r3
|
mr r24,r3
|
||||||
|
|
||||||
/* turn on 64-bit mode */
|
/* turn on 64-bit mode */
|
||||||
bl .enable_64b_mode
|
bl .enable_64b_mode
|
||||||
isync
|
isync
|
||||||
|
|
||||||
/* Copy some CPU settings from CPU 0 */
|
|
||||||
bl .__restore_cpu_setup
|
|
||||||
|
|
||||||
/* Set up a paca value for this processor. Since we have the
|
/* Set up a paca value for this processor. Since we have the
|
||||||
* physical cpu id in r24, we need to search the pacas to find
|
* physical cpu id in r24, we need to search the pacas to find
|
||||||
* which logical id maps to our physical one.
|
* which logical id maps to our physical one.
|
||||||
|
@ -1522,15 +1520,28 @@ _GLOBAL(pSeries_secondary_smp_init)
|
||||||
/* start. */
|
/* start. */
|
||||||
sync
|
sync
|
||||||
|
|
||||||
/* Create a temp kernel stack for use before relocation is on. */
|
#ifndef CONFIG_SMP
|
||||||
|
b 3b /* Never go on non-SMP */
|
||||||
|
#else
|
||||||
|
cmpwi 0,r23,0
|
||||||
|
beq 3b /* Loop until told to go */
|
||||||
|
|
||||||
|
/* See if we need to call a cpu state restore handler */
|
||||||
|
LOAD_REG_IMMEDIATE(r23, cur_cpu_spec)
|
||||||
|
ld r23,0(r23)
|
||||||
|
ld r23,CPU_SPEC_RESTORE(r23)
|
||||||
|
cmpdi 0,r23,0
|
||||||
|
beq 4f
|
||||||
|
ld r23,0(r23)
|
||||||
|
mtctr r23
|
||||||
|
bctrl
|
||||||
|
|
||||||
|
4: /* Create a temp kernel stack for use before relocation is on. */
|
||||||
ld r1,PACAEMERGSP(r13)
|
ld r1,PACAEMERGSP(r13)
|
||||||
subi r1,r1,STACK_FRAME_OVERHEAD
|
subi r1,r1,STACK_FRAME_OVERHEAD
|
||||||
|
|
||||||
cmpwi 0,r23,0
|
b .__secondary_start
|
||||||
#ifdef CONFIG_SMP
|
|
||||||
bne .__secondary_start
|
|
||||||
#endif
|
#endif
|
||||||
b 3b /* Loop until told to go */
|
|
||||||
|
|
||||||
#ifdef CONFIG_PPC_ISERIES
|
#ifdef CONFIG_PPC_ISERIES
|
||||||
_STATIC(__start_initialization_iSeries)
|
_STATIC(__start_initialization_iSeries)
|
||||||
|
@ -1611,7 +1622,16 @@ _GLOBAL(__start_initialization_multiplatform)
|
||||||
bl .enable_64b_mode
|
bl .enable_64b_mode
|
||||||
|
|
||||||
/* Setup some critical 970 SPRs before switching MMU off */
|
/* Setup some critical 970 SPRs before switching MMU off */
|
||||||
bl .__970_cpu_preinit
|
mfspr r0,SPRN_PVR
|
||||||
|
srwi r0,r0,16
|
||||||
|
cmpwi r0,0x39 /* 970 */
|
||||||
|
beq 1f
|
||||||
|
cmpwi r0,0x3c /* 970FX */
|
||||||
|
beq 1f
|
||||||
|
cmpwi r0,0x44 /* 970MP */
|
||||||
|
bne 2f
|
||||||
|
1: bl .__cpu_preinit_ppc970
|
||||||
|
2:
|
||||||
|
|
||||||
/* Switch off MMU if not already */
|
/* Switch off MMU if not already */
|
||||||
LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE)
|
LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE)
|
||||||
|
@ -1728,7 +1748,7 @@ _STATIC(__after_prom_start)
|
||||||
_GLOBAL(copy_and_flush)
|
_GLOBAL(copy_and_flush)
|
||||||
addi r5,r5,-8
|
addi r5,r5,-8
|
||||||
addi r6,r6,-8
|
addi r6,r6,-8
|
||||||
4: li r0,16 /* Use the least common */
|
4: li r0,8 /* Use the smallest common */
|
||||||
/* denominator cache line */
|
/* denominator cache line */
|
||||||
/* size. This results in */
|
/* size. This results in */
|
||||||
/* extra cache line flushes */
|
/* extra cache line flushes */
|
||||||
|
@ -1782,7 +1802,7 @@ _GLOBAL(pmac_secondary_start)
|
||||||
isync
|
isync
|
||||||
|
|
||||||
/* Copy some CPU settings from CPU 0 */
|
/* Copy some CPU settings from CPU 0 */
|
||||||
bl .__restore_cpu_setup
|
bl .__restore_cpu_ppc970
|
||||||
|
|
||||||
/* pSeries do that early though I don't think we really need it */
|
/* pSeries do that early though I don't think we really need it */
|
||||||
mfmsr r3
|
mfmsr r3
|
||||||
|
@ -1932,12 +1952,6 @@ _STATIC(start_here_multiplatform)
|
||||||
mr r5,r26
|
mr r5,r26
|
||||||
bl .identify_cpu
|
bl .identify_cpu
|
||||||
|
|
||||||
/* Save some low level config HIDs of CPU0 to be copied to
|
|
||||||
* other CPUs later on, or used for suspend/resume
|
|
||||||
*/
|
|
||||||
bl .__save_cpu_setup
|
|
||||||
sync
|
|
||||||
|
|
||||||
/* Do very early kernel initializations, including initial hash table,
|
/* Do very early kernel initializations, including initial hash table,
|
||||||
* stab and slb setup before we turn on relocation. */
|
* stab and slb setup before we turn on relocation. */
|
||||||
|
|
||||||
|
|
|
@ -167,7 +167,7 @@ static DEVICE_ATTR(name, S_IRUSR | S_IRGRP | S_IROTH, ibmebusdev_show_name,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
static struct ibmebus_dev* __devinit ibmebus_register_device_common(
|
static struct ibmebus_dev* __devinit ibmebus_register_device_common(
|
||||||
struct ibmebus_dev *dev, char *name)
|
struct ibmebus_dev *dev, const char *name)
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
|
@ -194,10 +194,10 @@ static struct ibmebus_dev* __devinit ibmebus_register_device_node(
|
||||||
struct device_node *dn)
|
struct device_node *dn)
|
||||||
{
|
{
|
||||||
struct ibmebus_dev *dev;
|
struct ibmebus_dev *dev;
|
||||||
char *loc_code;
|
const char *loc_code;
|
||||||
int length;
|
int length;
|
||||||
|
|
||||||
loc_code = (char *)get_property(dn, "ibm,loc-code", NULL);
|
loc_code = get_property(dn, "ibm,loc-code", NULL);
|
||||||
if (!loc_code) {
|
if (!loc_code) {
|
||||||
printk(KERN_WARNING "%s: node %s missing 'ibm,loc-code'\n",
|
printk(KERN_WARNING "%s: node %s missing 'ibm,loc-code'\n",
|
||||||
__FUNCTION__, dn->name ? dn->name : "<unknown>");
|
__FUNCTION__, dn->name ? dn->name : "<unknown>");
|
||||||
|
|
|
@ -0,0 +1,131 @@
|
||||||
|
/*
|
||||||
|
* I/O string operations
|
||||||
|
* Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
|
||||||
|
* Copyright (C) 2006 IBM Corporation
|
||||||
|
*
|
||||||
|
* Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
|
||||||
|
* and Paul Mackerras.
|
||||||
|
*
|
||||||
|
* Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com)
|
||||||
|
* PPC64 updates by Dave Engebretsen (engebret@us.ibm.com)
|
||||||
|
*
|
||||||
|
* Rewritten in C by Stephen Rothwell.
|
||||||
|
*
|
||||||
|
* 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/kernel.h>
|
||||||
|
#include <linux/types.h>
|
||||||
|
#include <linux/compiler.h>
|
||||||
|
#include <linux/module.h>
|
||||||
|
|
||||||
|
#include <asm/io.h>
|
||||||
|
#include <asm/firmware.h>
|
||||||
|
#include <asm/bug.h>
|
||||||
|
|
||||||
|
void _insb(volatile u8 __iomem *port, void *buf, long count)
|
||||||
|
{
|
||||||
|
u8 *tbuf = buf;
|
||||||
|
u8 tmp;
|
||||||
|
|
||||||
|
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||||
|
|
||||||
|
if (unlikely(count <= 0))
|
||||||
|
return;
|
||||||
|
asm volatile("sync");
|
||||||
|
do {
|
||||||
|
tmp = *port;
|
||||||
|
asm volatile("eieio");
|
||||||
|
*tbuf++ = tmp;
|
||||||
|
} while (--count != 0);
|
||||||
|
asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(_insb);
|
||||||
|
|
||||||
|
void _outsb(volatile u8 __iomem *port, const void *buf, long count)
|
||||||
|
{
|
||||||
|
const u8 *tbuf = buf;
|
||||||
|
|
||||||
|
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||||
|
|
||||||
|
if (unlikely(count <= 0))
|
||||||
|
return;
|
||||||
|
asm volatile("sync");
|
||||||
|
do {
|
||||||
|
*port = *tbuf++;
|
||||||
|
} while (--count != 0);
|
||||||
|
asm volatile("sync");
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(_outsb);
|
||||||
|
|
||||||
|
void _insw_ns(volatile u16 __iomem *port, void *buf, long count)
|
||||||
|
{
|
||||||
|
u16 *tbuf = buf;
|
||||||
|
u16 tmp;
|
||||||
|
|
||||||
|
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||||
|
|
||||||
|
if (unlikely(count <= 0))
|
||||||
|
return;
|
||||||
|
asm volatile("sync");
|
||||||
|
do {
|
||||||
|
tmp = *port;
|
||||||
|
asm volatile("eieio");
|
||||||
|
*tbuf++ = tmp;
|
||||||
|
} while (--count != 0);
|
||||||
|
asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(_insw_ns);
|
||||||
|
|
||||||
|
void _outsw_ns(volatile u16 __iomem *port, const void *buf, long count)
|
||||||
|
{
|
||||||
|
const u16 *tbuf = buf;
|
||||||
|
|
||||||
|
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||||
|
|
||||||
|
if (unlikely(count <= 0))
|
||||||
|
return;
|
||||||
|
asm volatile("sync");
|
||||||
|
do {
|
||||||
|
*port = *tbuf++;
|
||||||
|
} while (--count != 0);
|
||||||
|
asm volatile("sync");
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(_outsw_ns);
|
||||||
|
|
||||||
|
void _insl_ns(volatile u32 __iomem *port, void *buf, long count)
|
||||||
|
{
|
||||||
|
u32 *tbuf = buf;
|
||||||
|
u32 tmp;
|
||||||
|
|
||||||
|
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||||
|
|
||||||
|
if (unlikely(count <= 0))
|
||||||
|
return;
|
||||||
|
asm volatile("sync");
|
||||||
|
do {
|
||||||
|
tmp = *port;
|
||||||
|
asm volatile("eieio");
|
||||||
|
*tbuf++ = tmp;
|
||||||
|
} while (--count != 0);
|
||||||
|
asm volatile("twi 0,%0,0; isync" : : "r" (tmp));
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(_insl_ns);
|
||||||
|
|
||||||
|
void _outsl_ns(volatile u32 __iomem *port, const void *buf, long count)
|
||||||
|
{
|
||||||
|
const u32 *tbuf = buf;
|
||||||
|
|
||||||
|
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||||
|
|
||||||
|
if (unlikely(count <= 0))
|
||||||
|
return;
|
||||||
|
asm volatile("sync");
|
||||||
|
do {
|
||||||
|
*port = *tbuf++;
|
||||||
|
} while (--count != 0);
|
||||||
|
asm volatile("sync");
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(_outsl_ns);
|
|
@ -52,6 +52,7 @@
|
||||||
#include <linux/radix-tree.h>
|
#include <linux/radix-tree.h>
|
||||||
#include <linux/mutex.h>
|
#include <linux/mutex.h>
|
||||||
#include <linux/bootmem.h>
|
#include <linux/bootmem.h>
|
||||||
|
#include <linux/pci.h>
|
||||||
|
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
|
@ -875,12 +876,14 @@ int pci_enable_msi(struct pci_dev * pdev)
|
||||||
else
|
else
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(pci_enable_msi);
|
||||||
|
|
||||||
void pci_disable_msi(struct pci_dev * pdev)
|
void pci_disable_msi(struct pci_dev * pdev)
|
||||||
{
|
{
|
||||||
if (ppc_md.disable_msi)
|
if (ppc_md.disable_msi)
|
||||||
ppc_md.disable_msi(pdev);
|
ppc_md.disable_msi(pdev);
|
||||||
}
|
}
|
||||||
|
EXPORT_SYMBOL(pci_disable_msi);
|
||||||
|
|
||||||
void pci_scan_msi_device(struct pci_dev *dev) {}
|
void pci_scan_msi_device(struct pci_dev *dev) {}
|
||||||
int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) {return -1;}
|
int pci_enable_msix(struct pci_dev* dev, struct msix_entry *entries, int nvec) {return -1;}
|
||||||
|
@ -888,6 +891,8 @@ void pci_disable_msix(struct pci_dev *dev) {}
|
||||||
void msi_remove_pci_irq_vectors(struct pci_dev *dev) {}
|
void msi_remove_pci_irq_vectors(struct pci_dev *dev) {}
|
||||||
void disable_msi_mode(struct pci_dev *dev, int pos, int type) {}
|
void disable_msi_mode(struct pci_dev *dev, int pos, int type) {}
|
||||||
void pci_no_msi(void) {}
|
void pci_no_msi(void) {}
|
||||||
|
EXPORT_SYMBOL(pci_enable_msix);
|
||||||
|
EXPORT_SYMBOL(pci_disable_msix);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -39,16 +39,17 @@ static int __init add_legacy_port(struct device_node *np, int want_index,
|
||||||
phys_addr_t taddr, unsigned long irq,
|
phys_addr_t taddr, unsigned long irq,
|
||||||
upf_t flags, int irq_check_parent)
|
upf_t flags, int irq_check_parent)
|
||||||
{
|
{
|
||||||
u32 *clk, *spd, clock = BASE_BAUD * 16;
|
const u32 *clk, *spd;
|
||||||
|
u32 clock = BASE_BAUD * 16;
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
/* get clock freq. if present */
|
/* get clock freq. if present */
|
||||||
clk = (u32 *)get_property(np, "clock-frequency", NULL);
|
clk = get_property(np, "clock-frequency", NULL);
|
||||||
if (clk && *clk)
|
if (clk && *clk)
|
||||||
clock = *clk;
|
clock = *clk;
|
||||||
|
|
||||||
/* get default speed if present */
|
/* get default speed if present */
|
||||||
spd = (u32 *)get_property(np, "current-speed", NULL);
|
spd = get_property(np, "current-speed", NULL);
|
||||||
|
|
||||||
/* If we have a location index, then try to use it */
|
/* If we have a location index, then try to use it */
|
||||||
if (want_index >= 0 && want_index < MAX_LEGACY_SERIAL_PORTS)
|
if (want_index >= 0 && want_index < MAX_LEGACY_SERIAL_PORTS)
|
||||||
|
@ -113,7 +114,7 @@ static int __init add_legacy_soc_port(struct device_node *np,
|
||||||
struct device_node *soc_dev)
|
struct device_node *soc_dev)
|
||||||
{
|
{
|
||||||
u64 addr;
|
u64 addr;
|
||||||
u32 *addrp;
|
const u32 *addrp;
|
||||||
upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
|
upf_t flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
|
||||||
struct device_node *tsi = of_get_parent(np);
|
struct device_node *tsi = of_get_parent(np);
|
||||||
|
|
||||||
|
@ -144,15 +145,15 @@ static int __init add_legacy_soc_port(struct device_node *np,
|
||||||
static int __init add_legacy_isa_port(struct device_node *np,
|
static int __init add_legacy_isa_port(struct device_node *np,
|
||||||
struct device_node *isa_brg)
|
struct device_node *isa_brg)
|
||||||
{
|
{
|
||||||
u32 *reg;
|
const u32 *reg;
|
||||||
char *typep;
|
const char *typep;
|
||||||
int index = -1;
|
int index = -1;
|
||||||
u64 taddr;
|
u64 taddr;
|
||||||
|
|
||||||
DBG(" -> add_legacy_isa_port(%s)\n", np->full_name);
|
DBG(" -> add_legacy_isa_port(%s)\n", np->full_name);
|
||||||
|
|
||||||
/* Get the ISA port number */
|
/* Get the ISA port number */
|
||||||
reg = (u32 *)get_property(np, "reg", NULL);
|
reg = get_property(np, "reg", NULL);
|
||||||
if (reg == NULL)
|
if (reg == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -163,7 +164,7 @@ static int __init add_legacy_isa_port(struct device_node *np,
|
||||||
/* Now look for an "ibm,aix-loc" property that gives us ordering
|
/* Now look for an "ibm,aix-loc" property that gives us ordering
|
||||||
* if any...
|
* if any...
|
||||||
*/
|
*/
|
||||||
typep = (char *)get_property(np, "ibm,aix-loc", NULL);
|
typep = get_property(np, "ibm,aix-loc", NULL);
|
||||||
|
|
||||||
/* If we have a location index, then use it */
|
/* If we have a location index, then use it */
|
||||||
if (typep && *typep == 'S')
|
if (typep && *typep == 'S')
|
||||||
|
@ -188,7 +189,7 @@ static int __init add_legacy_pci_port(struct device_node *np,
|
||||||
struct device_node *pci_dev)
|
struct device_node *pci_dev)
|
||||||
{
|
{
|
||||||
u64 addr, base;
|
u64 addr, base;
|
||||||
u32 *addrp;
|
const u32 *addrp;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
int iotype, index = -1, lindex = 0;
|
int iotype, index = -1, lindex = 0;
|
||||||
|
|
||||||
|
@ -227,7 +228,7 @@ static int __init add_legacy_pci_port(struct device_node *np,
|
||||||
* we get to their "reg" property
|
* we get to their "reg" property
|
||||||
*/
|
*/
|
||||||
if (np != pci_dev) {
|
if (np != pci_dev) {
|
||||||
u32 *reg = (u32 *)get_property(np, "reg", NULL);
|
const u32 *reg = get_property(np, "reg", NULL);
|
||||||
if (reg && (*reg < 4))
|
if (reg && (*reg < 4))
|
||||||
index = lindex = *reg;
|
index = lindex = *reg;
|
||||||
}
|
}
|
||||||
|
@ -285,13 +286,13 @@ static void __init setup_legacy_serial_console(int console)
|
||||||
void __init find_legacy_serial_ports(void)
|
void __init find_legacy_serial_ports(void)
|
||||||
{
|
{
|
||||||
struct device_node *np, *stdout = NULL;
|
struct device_node *np, *stdout = NULL;
|
||||||
char *path;
|
const char *path;
|
||||||
int index;
|
int index;
|
||||||
|
|
||||||
DBG(" -> find_legacy_serial_port()\n");
|
DBG(" -> find_legacy_serial_port()\n");
|
||||||
|
|
||||||
/* Now find out if one of these is out firmware console */
|
/* Now find out if one of these is out firmware console */
|
||||||
path = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
|
path = get_property(of_chosen, "linux,stdout-path", NULL);
|
||||||
if (path != NULL) {
|
if (path != NULL) {
|
||||||
stdout = of_find_node_by_path(path);
|
stdout = of_find_node_by_path(path);
|
||||||
if (stdout)
|
if (stdout)
|
||||||
|
@ -491,8 +492,8 @@ static int __init check_legacy_serial_console(void)
|
||||||
{
|
{
|
||||||
struct device_node *prom_stdout = NULL;
|
struct device_node *prom_stdout = NULL;
|
||||||
int speed = 0, offset = 0;
|
int speed = 0, offset = 0;
|
||||||
char *name;
|
const char *name;
|
||||||
u32 *spd;
|
const u32 *spd;
|
||||||
|
|
||||||
DBG(" -> check_legacy_serial_console()\n");
|
DBG(" -> check_legacy_serial_console()\n");
|
||||||
|
|
||||||
|
@ -513,7 +514,7 @@ static int __init check_legacy_serial_console(void)
|
||||||
}
|
}
|
||||||
/* We are getting a weird phandle from OF ... */
|
/* We are getting a weird phandle from OF ... */
|
||||||
/* ... So use the full path instead */
|
/* ... So use the full path instead */
|
||||||
name = (char *)get_property(of_chosen, "linux,stdout-path", NULL);
|
name = get_property(of_chosen, "linux,stdout-path", NULL);
|
||||||
if (name == NULL) {
|
if (name == NULL) {
|
||||||
DBG(" no linux,stdout-path !\n");
|
DBG(" no linux,stdout-path !\n");
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
@ -525,12 +526,12 @@ static int __init check_legacy_serial_console(void)
|
||||||
}
|
}
|
||||||
DBG("stdout is %s\n", prom_stdout->full_name);
|
DBG("stdout is %s\n", prom_stdout->full_name);
|
||||||
|
|
||||||
name = (char *)get_property(prom_stdout, "name", NULL);
|
name = get_property(prom_stdout, "name", NULL);
|
||||||
if (!name) {
|
if (!name) {
|
||||||
DBG(" stdout package has no name !\n");
|
DBG(" stdout package has no name !\n");
|
||||||
goto not_found;
|
goto not_found;
|
||||||
}
|
}
|
||||||
spd = (u32 *)get_property(prom_stdout, "current-speed", NULL);
|
spd = get_property(prom_stdout, "current-speed", NULL);
|
||||||
if (spd)
|
if (spd)
|
||||||
speed = *spd;
|
speed = *spd;
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,6 @@
|
||||||
#include <asm/rtas.h>
|
#include <asm/rtas.h>
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
#include <asm/time.h>
|
#include <asm/time.h>
|
||||||
#include <asm/iseries/it_exp_vpd_panel.h>
|
|
||||||
#include <asm/prom.h>
|
#include <asm/prom.h>
|
||||||
#include <asm/vdso_datapage.h>
|
#include <asm/vdso_datapage.h>
|
||||||
|
|
||||||
|
@ -183,8 +182,14 @@ static unsigned int h_get_ppp(unsigned long *entitled,
|
||||||
unsigned long *resource)
|
unsigned long *resource)
|
||||||
{
|
{
|
||||||
unsigned long rc;
|
unsigned long rc;
|
||||||
rc = plpar_hcall_4out(H_GET_PPP, 0, 0, 0, 0, entitled, unallocated,
|
unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
|
||||||
aggregation, resource);
|
|
||||||
|
rc = plpar_hcall(H_GET_PPP, retbuf);
|
||||||
|
|
||||||
|
*entitled = retbuf[0];
|
||||||
|
*unallocated = retbuf[1];
|
||||||
|
*aggregation = retbuf[2];
|
||||||
|
*resource = retbuf[3];
|
||||||
|
|
||||||
log_plpar_hcall_return(rc, "H_GET_PPP");
|
log_plpar_hcall_return(rc, "H_GET_PPP");
|
||||||
|
|
||||||
|
@ -194,8 +199,12 @@ static unsigned int h_get_ppp(unsigned long *entitled,
|
||||||
static void h_pic(unsigned long *pool_idle_time, unsigned long *num_procs)
|
static void h_pic(unsigned long *pool_idle_time, unsigned long *num_procs)
|
||||||
{
|
{
|
||||||
unsigned long rc;
|
unsigned long rc;
|
||||||
unsigned long dummy;
|
unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
|
||||||
rc = plpar_hcall(H_PIC, 0, 0, 0, 0, pool_idle_time, num_procs, &dummy);
|
|
||||||
|
rc = plpar_hcall(H_PIC, retbuf);
|
||||||
|
|
||||||
|
*pool_idle_time = retbuf[0];
|
||||||
|
*num_procs = retbuf[1];
|
||||||
|
|
||||||
if (rc != H_AUTHORITY)
|
if (rc != H_AUTHORITY)
|
||||||
log_plpar_hcall_return(rc, "H_PIC");
|
log_plpar_hcall_return(rc, "H_PIC");
|
||||||
|
@ -310,12 +319,11 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
|
||||||
int partition_potential_processors;
|
int partition_potential_processors;
|
||||||
int partition_active_processors;
|
int partition_active_processors;
|
||||||
struct device_node *rtas_node;
|
struct device_node *rtas_node;
|
||||||
int *lrdrp = NULL;
|
const int *lrdrp = NULL;
|
||||||
|
|
||||||
rtas_node = find_path_device("/rtas");
|
rtas_node = find_path_device("/rtas");
|
||||||
if (rtas_node)
|
if (rtas_node)
|
||||||
lrdrp = (int *)get_property(rtas_node, "ibm,lrdr-capacity",
|
lrdrp = get_property(rtas_node, "ibm,lrdr-capacity", NULL);
|
||||||
NULL);
|
|
||||||
|
|
||||||
if (lrdrp == NULL) {
|
if (lrdrp == NULL) {
|
||||||
partition_potential_processors = vdso_data->processorCount;
|
partition_potential_processors = vdso_data->processorCount;
|
||||||
|
@ -520,7 +528,8 @@ static int lparcfg_data(struct seq_file *m, void *v)
|
||||||
const char *model = "";
|
const char *model = "";
|
||||||
const char *system_id = "";
|
const char *system_id = "";
|
||||||
const char *tmp;
|
const char *tmp;
|
||||||
unsigned int *lp_index_ptr, lp_index = 0;
|
const unsigned int *lp_index_ptr;
|
||||||
|
unsigned int lp_index = 0;
|
||||||
|
|
||||||
seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS);
|
seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS);
|
||||||
|
|
||||||
|
@ -540,8 +549,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
|
||||||
if (firmware_has_feature(FW_FEATURE_ISERIES))
|
if (firmware_has_feature(FW_FEATURE_ISERIES))
|
||||||
system_id += 4;
|
system_id += 4;
|
||||||
}
|
}
|
||||||
lp_index_ptr = (unsigned int *)
|
lp_index_ptr = get_property(rootdn, "ibm,partition-no", NULL);
|
||||||
get_property(rootdn, "ibm,partition-no", NULL);
|
|
||||||
if (lp_index_ptr)
|
if (lp_index_ptr)
|
||||||
lp_index = *lp_index_ptr;
|
lp_index = *lp_index_ptr;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,8 +31,8 @@ int default_machine_kexec_prepare(struct kimage *image)
|
||||||
unsigned long begin, end; /* limits of segment */
|
unsigned long begin, end; /* limits of segment */
|
||||||
unsigned long low, high; /* limits of blocked memory range */
|
unsigned long low, high; /* limits of blocked memory range */
|
||||||
struct device_node *node;
|
struct device_node *node;
|
||||||
unsigned long *basep;
|
const unsigned long *basep;
|
||||||
unsigned int *sizep;
|
const unsigned int *sizep;
|
||||||
|
|
||||||
if (!ppc_md.hpte_clear_all)
|
if (!ppc_md.hpte_clear_all)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
@ -72,10 +72,8 @@ int default_machine_kexec_prepare(struct kimage *image)
|
||||||
/* We also should not overwrite the tce tables */
|
/* We also should not overwrite the tce tables */
|
||||||
for (node = of_find_node_by_type(NULL, "pci"); node != NULL;
|
for (node = of_find_node_by_type(NULL, "pci"); node != NULL;
|
||||||
node = of_find_node_by_type(node, "pci")) {
|
node = of_find_node_by_type(node, "pci")) {
|
||||||
basep = (unsigned long *)get_property(node, "linux,tce-base",
|
basep = get_property(node, "linux,tce-base", NULL);
|
||||||
NULL);
|
sizep = get_property(node, "linux,tce-size", NULL);
|
||||||
sizep = (unsigned int *)get_property(node, "linux,tce-size",
|
|
||||||
NULL);
|
|
||||||
if (basep == NULL || sizep == NULL)
|
if (basep == NULL || sizep == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -43,162 +43,3 @@ _GLOBAL(add_reloc_offset)
|
||||||
add r3,r3,r5
|
add r3,r3,r5
|
||||||
mtlr r0
|
mtlr r0
|
||||||
blr
|
blr
|
||||||
|
|
||||||
/*
|
|
||||||
* I/O string operations
|
|
||||||
*
|
|
||||||
* insb(port, buf, len)
|
|
||||||
* outsb(port, buf, len)
|
|
||||||
* insw(port, buf, len)
|
|
||||||
* outsw(port, buf, len)
|
|
||||||
* insl(port, buf, len)
|
|
||||||
* outsl(port, buf, len)
|
|
||||||
* insw_ns(port, buf, len)
|
|
||||||
* outsw_ns(port, buf, len)
|
|
||||||
* insl_ns(port, buf, len)
|
|
||||||
* outsl_ns(port, buf, len)
|
|
||||||
*
|
|
||||||
* The *_ns versions don't do byte-swapping.
|
|
||||||
*/
|
|
||||||
_GLOBAL(_insb)
|
|
||||||
sync
|
|
||||||
cmpwi 0,r5,0
|
|
||||||
mtctr r5
|
|
||||||
subi r4,r4,1
|
|
||||||
blelr-
|
|
||||||
00: lbz r5,0(r3)
|
|
||||||
eieio
|
|
||||||
stbu r5,1(r4)
|
|
||||||
bdnz 00b
|
|
||||||
twi 0,r5,0
|
|
||||||
isync
|
|
||||||
blr
|
|
||||||
|
|
||||||
_GLOBAL(_outsb)
|
|
||||||
cmpwi 0,r5,0
|
|
||||||
mtctr r5
|
|
||||||
subi r4,r4,1
|
|
||||||
blelr-
|
|
||||||
sync
|
|
||||||
00: lbzu r5,1(r4)
|
|
||||||
stb r5,0(r3)
|
|
||||||
bdnz 00b
|
|
||||||
sync
|
|
||||||
blr
|
|
||||||
|
|
||||||
_GLOBAL(_insw)
|
|
||||||
sync
|
|
||||||
cmpwi 0,r5,0
|
|
||||||
mtctr r5
|
|
||||||
subi r4,r4,2
|
|
||||||
blelr-
|
|
||||||
00: lhbrx r5,0,r3
|
|
||||||
eieio
|
|
||||||
sthu r5,2(r4)
|
|
||||||
bdnz 00b
|
|
||||||
twi 0,r5,0
|
|
||||||
isync
|
|
||||||
blr
|
|
||||||
|
|
||||||
_GLOBAL(_outsw)
|
|
||||||
cmpwi 0,r5,0
|
|
||||||
mtctr r5
|
|
||||||
subi r4,r4,2
|
|
||||||
blelr-
|
|
||||||
sync
|
|
||||||
00: lhzu r5,2(r4)
|
|
||||||
sthbrx r5,0,r3
|
|
||||||
bdnz 00b
|
|
||||||
sync
|
|
||||||
blr
|
|
||||||
|
|
||||||
_GLOBAL(_insl)
|
|
||||||
sync
|
|
||||||
cmpwi 0,r5,0
|
|
||||||
mtctr r5
|
|
||||||
subi r4,r4,4
|
|
||||||
blelr-
|
|
||||||
00: lwbrx r5,0,r3
|
|
||||||
eieio
|
|
||||||
stwu r5,4(r4)
|
|
||||||
bdnz 00b
|
|
||||||
twi 0,r5,0
|
|
||||||
isync
|
|
||||||
blr
|
|
||||||
|
|
||||||
_GLOBAL(_outsl)
|
|
||||||
cmpwi 0,r5,0
|
|
||||||
mtctr r5
|
|
||||||
subi r4,r4,4
|
|
||||||
blelr-
|
|
||||||
sync
|
|
||||||
00: lwzu r5,4(r4)
|
|
||||||
stwbrx r5,0,r3
|
|
||||||
bdnz 00b
|
|
||||||
sync
|
|
||||||
blr
|
|
||||||
|
|
||||||
#ifdef CONFIG_PPC32
|
|
||||||
_GLOBAL(__ide_mm_insw)
|
|
||||||
#endif
|
|
||||||
_GLOBAL(_insw_ns)
|
|
||||||
sync
|
|
||||||
cmpwi 0,r5,0
|
|
||||||
mtctr r5
|
|
||||||
subi r4,r4,2
|
|
||||||
blelr-
|
|
||||||
00: lhz r5,0(r3)
|
|
||||||
eieio
|
|
||||||
sthu r5,2(r4)
|
|
||||||
bdnz 00b
|
|
||||||
twi 0,r5,0
|
|
||||||
isync
|
|
||||||
blr
|
|
||||||
|
|
||||||
#ifdef CONFIG_PPC32
|
|
||||||
_GLOBAL(__ide_mm_outsw)
|
|
||||||
#endif
|
|
||||||
_GLOBAL(_outsw_ns)
|
|
||||||
cmpwi 0,r5,0
|
|
||||||
mtctr r5
|
|
||||||
subi r4,r4,2
|
|
||||||
blelr-
|
|
||||||
sync
|
|
||||||
00: lhzu r5,2(r4)
|
|
||||||
sth r5,0(r3)
|
|
||||||
bdnz 00b
|
|
||||||
sync
|
|
||||||
blr
|
|
||||||
|
|
||||||
#ifdef CONFIG_PPC32
|
|
||||||
_GLOBAL(__ide_mm_insl)
|
|
||||||
#endif
|
|
||||||
_GLOBAL(_insl_ns)
|
|
||||||
sync
|
|
||||||
cmpwi 0,r5,0
|
|
||||||
mtctr r5
|
|
||||||
subi r4,r4,4
|
|
||||||
blelr-
|
|
||||||
00: lwz r5,0(r3)
|
|
||||||
eieio
|
|
||||||
stwu r5,4(r4)
|
|
||||||
bdnz 00b
|
|
||||||
twi 0,r5,0
|
|
||||||
isync
|
|
||||||
blr
|
|
||||||
|
|
||||||
#ifdef CONFIG_PPC32
|
|
||||||
_GLOBAL(__ide_mm_outsl)
|
|
||||||
#endif
|
|
||||||
_GLOBAL(_outsl_ns)
|
|
||||||
cmpwi 0,r5,0
|
|
||||||
mtctr r5
|
|
||||||
subi r4,r4,4
|
|
||||||
blelr-
|
|
||||||
sync
|
|
||||||
00: lwzu r5,4(r4)
|
|
||||||
stw r5,0(r3)
|
|
||||||
bdnz 00b
|
|
||||||
sync
|
|
||||||
blr
|
|
||||||
|
|
||||||
|
|
|
@ -189,27 +189,9 @@ void of_release_dev(struct device *dev)
|
||||||
int of_device_register(struct of_device *ofdev)
|
int of_device_register(struct of_device *ofdev)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
struct of_device **odprop;
|
|
||||||
|
|
||||||
BUG_ON(ofdev->node == NULL);
|
BUG_ON(ofdev->node == NULL);
|
||||||
|
|
||||||
odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL);
|
|
||||||
if (!odprop) {
|
|
||||||
struct property *new_prop;
|
|
||||||
|
|
||||||
new_prop = kmalloc(sizeof(struct property) + sizeof(struct of_device *),
|
|
||||||
GFP_KERNEL);
|
|
||||||
if (new_prop == NULL)
|
|
||||||
return -ENOMEM;
|
|
||||||
new_prop->name = "linux,device";
|
|
||||||
new_prop->length = sizeof(sizeof(struct of_device *));
|
|
||||||
new_prop->value = (unsigned char *)&new_prop[1];
|
|
||||||
odprop = (struct of_device **)new_prop->value;
|
|
||||||
*odprop = NULL;
|
|
||||||
prom_add_property(ofdev->node, new_prop);
|
|
||||||
}
|
|
||||||
*odprop = ofdev;
|
|
||||||
|
|
||||||
rc = device_register(&ofdev->dev);
|
rc = device_register(&ofdev->dev);
|
||||||
if (rc)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -221,14 +203,8 @@ int of_device_register(struct of_device *ofdev)
|
||||||
|
|
||||||
void of_device_unregister(struct of_device *ofdev)
|
void of_device_unregister(struct of_device *ofdev)
|
||||||
{
|
{
|
||||||
struct of_device **odprop;
|
|
||||||
|
|
||||||
device_remove_file(&ofdev->dev, &dev_attr_devspec);
|
device_remove_file(&ofdev->dev, &dev_attr_devspec);
|
||||||
|
|
||||||
odprop = (struct of_device **)get_property(ofdev->node, "linux,device", NULL);
|
|
||||||
if (odprop)
|
|
||||||
*odprop = NULL;
|
|
||||||
|
|
||||||
device_unregister(&ofdev->dev);
|
device_unregister(&ofdev->dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include <asm/lppaca.h>
|
#include <asm/lppaca.h>
|
||||||
#include <asm/iseries/it_lp_reg_save.h>
|
#include <asm/iseries/it_lp_reg_save.h>
|
||||||
#include <asm/paca.h>
|
#include <asm/paca.h>
|
||||||
|
#include <asm/mmu.h>
|
||||||
|
|
||||||
|
|
||||||
/* This symbol is provided by the linker - let it fill in the paca
|
/* This symbol is provided by the linker - let it fill in the paca
|
||||||
|
@ -45,6 +46,17 @@ struct lppaca lppaca[] = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 3 persistent SLBs are registered here. The buffer will be zero
|
||||||
|
* initially, hence will all be invaild until we actually write them.
|
||||||
|
*/
|
||||||
|
struct slb_shadow slb_shadow[] __cacheline_aligned = {
|
||||||
|
[0 ... (NR_CPUS-1)] = {
|
||||||
|
.persistent = SLB_NUM_BOLTED,
|
||||||
|
.buffer_length = sizeof(struct slb_shadow),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
/* The Paca is an array with one entry per processor. Each contains an
|
/* The Paca is an array with one entry per processor. Each contains an
|
||||||
* lppaca, which contains the information shared between the
|
* lppaca, which contains the information shared between the
|
||||||
* hypervisor and Linux.
|
* hypervisor and Linux.
|
||||||
|
@ -59,7 +71,8 @@ struct lppaca lppaca[] = {
|
||||||
.lock_token = 0x8000, \
|
.lock_token = 0x8000, \
|
||||||
.paca_index = (number), /* Paca Index */ \
|
.paca_index = (number), /* Paca Index */ \
|
||||||
.kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \
|
.kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \
|
||||||
.hw_cpu_id = 0xffff,
|
.hw_cpu_id = 0xffff, \
|
||||||
|
.slb_shadow_ptr = &slb_shadow[number],
|
||||||
|
|
||||||
#ifdef CONFIG_PPC_ISERIES
|
#ifdef CONFIG_PPC_ISERIES
|
||||||
#define PACA_INIT_ISERIES(number) \
|
#define PACA_INIT_ISERIES(number) \
|
||||||
|
|
|
@ -633,12 +633,12 @@ pcibios_alloc_controller(void)
|
||||||
static void
|
static void
|
||||||
make_one_node_map(struct device_node* node, u8 pci_bus)
|
make_one_node_map(struct device_node* node, u8 pci_bus)
|
||||||
{
|
{
|
||||||
int *bus_range;
|
const int *bus_range;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
if (pci_bus >= pci_bus_count)
|
if (pci_bus >= pci_bus_count)
|
||||||
return;
|
return;
|
||||||
bus_range = (int *) get_property(node, "bus-range", &len);
|
bus_range = get_property(node, "bus-range", &len);
|
||||||
if (bus_range == NULL || len < 2 * sizeof(int)) {
|
if (bus_range == NULL || len < 2 * sizeof(int)) {
|
||||||
printk(KERN_WARNING "Can't get bus-range for %s, "
|
printk(KERN_WARNING "Can't get bus-range for %s, "
|
||||||
"assuming it starts at 0\n", node->full_name);
|
"assuming it starts at 0\n", node->full_name);
|
||||||
|
@ -648,13 +648,13 @@ make_one_node_map(struct device_node* node, u8 pci_bus)
|
||||||
|
|
||||||
for (node=node->child; node != 0;node = node->sibling) {
|
for (node=node->child; node != 0;node = node->sibling) {
|
||||||
struct pci_dev* dev;
|
struct pci_dev* dev;
|
||||||
unsigned int *class_code, *reg;
|
const unsigned int *class_code, *reg;
|
||||||
|
|
||||||
class_code = (unsigned int *) get_property(node, "class-code", NULL);
|
class_code = get_property(node, "class-code", NULL);
|
||||||
if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
|
if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
|
||||||
(*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
|
(*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
|
||||||
continue;
|
continue;
|
||||||
reg = (unsigned int *)get_property(node, "reg", NULL);
|
reg = get_property(node, "reg", NULL);
|
||||||
if (!reg)
|
if (!reg)
|
||||||
continue;
|
continue;
|
||||||
dev = pci_find_slot(pci_bus, ((reg[0] >> 8) & 0xff));
|
dev = pci_find_slot(pci_bus, ((reg[0] >> 8) & 0xff));
|
||||||
|
@ -669,7 +669,7 @@ pcibios_make_OF_bus_map(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct pci_controller* hose;
|
struct pci_controller* hose;
|
||||||
u8* of_prop_map;
|
struct property *map_prop;
|
||||||
|
|
||||||
pci_to_OF_bus_map = (u8*)kmalloc(pci_bus_count, GFP_KERNEL);
|
pci_to_OF_bus_map = (u8*)kmalloc(pci_bus_count, GFP_KERNEL);
|
||||||
if (!pci_to_OF_bus_map) {
|
if (!pci_to_OF_bus_map) {
|
||||||
|
@ -691,9 +691,12 @@ pcibios_make_OF_bus_map(void)
|
||||||
continue;
|
continue;
|
||||||
make_one_node_map(node, hose->first_busno);
|
make_one_node_map(node, hose->first_busno);
|
||||||
}
|
}
|
||||||
of_prop_map = get_property(find_path_device("/"), "pci-OF-bus-map", NULL);
|
map_prop = of_find_property(find_path_device("/"),
|
||||||
if (of_prop_map)
|
"pci-OF-bus-map", NULL);
|
||||||
memcpy(of_prop_map, pci_to_OF_bus_map, pci_bus_count);
|
if (map_prop) {
|
||||||
|
BUG_ON(pci_bus_count > map_prop->length);
|
||||||
|
memcpy(map_prop->value, pci_to_OF_bus_map, pci_bus_count);
|
||||||
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printk("PCI->OF bus map:\n");
|
printk("PCI->OF bus map:\n");
|
||||||
for (i=0; i<pci_bus_count; i++) {
|
for (i=0; i<pci_bus_count; i++) {
|
||||||
|
@ -712,7 +715,7 @@ scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void*
|
||||||
struct device_node* sub_node;
|
struct device_node* sub_node;
|
||||||
|
|
||||||
for (; node != 0;node = node->sibling) {
|
for (; node != 0;node = node->sibling) {
|
||||||
unsigned int *class_code;
|
const unsigned int *class_code;
|
||||||
|
|
||||||
if (filter(node, data))
|
if (filter(node, data))
|
||||||
return node;
|
return node;
|
||||||
|
@ -722,7 +725,7 @@ scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void*
|
||||||
* a fake root for all functions of a multi-function device,
|
* a fake root for all functions of a multi-function device,
|
||||||
* we go down them as well.
|
* we go down them as well.
|
||||||
*/
|
*/
|
||||||
class_code = (unsigned int *) get_property(node, "class-code", NULL);
|
class_code = get_property(node, "class-code", NULL);
|
||||||
if ((!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
|
if ((!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
|
||||||
(*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) &&
|
(*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS)) &&
|
||||||
strcmp(node->name, "multifunc-device"))
|
strcmp(node->name, "multifunc-device"))
|
||||||
|
@ -737,10 +740,10 @@ scan_OF_pci_childs(struct device_node* node, pci_OF_scan_iterator filter, void*
|
||||||
static int
|
static int
|
||||||
scan_OF_pci_childs_iterator(struct device_node* node, void* data)
|
scan_OF_pci_childs_iterator(struct device_node* node, void* data)
|
||||||
{
|
{
|
||||||
unsigned int *reg;
|
const unsigned int *reg;
|
||||||
u8* fdata = (u8*)data;
|
u8* fdata = (u8*)data;
|
||||||
|
|
||||||
reg = (unsigned int *) get_property(node, "reg", NULL);
|
reg = get_property(node, "reg", NULL);
|
||||||
if (reg && ((reg[0] >> 8) & 0xff) == fdata[1]
|
if (reg && ((reg[0] >> 8) & 0xff) == fdata[1]
|
||||||
&& ((reg[0] >> 16) & 0xff) == fdata[0])
|
&& ((reg[0] >> 16) & 0xff) == fdata[0])
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -841,7 +844,7 @@ find_OF_pci_device_filter(struct device_node* node, void* data)
|
||||||
int
|
int
|
||||||
pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)
|
pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)
|
||||||
{
|
{
|
||||||
unsigned int *reg;
|
const unsigned int *reg;
|
||||||
struct pci_controller* hose;
|
struct pci_controller* hose;
|
||||||
struct pci_dev* dev = NULL;
|
struct pci_dev* dev = NULL;
|
||||||
|
|
||||||
|
@ -854,7 +857,7 @@ pci_device_from_OF_node(struct device_node* node, u8* bus, u8* devfn)
|
||||||
if (!scan_OF_pci_childs(((struct device_node*)hose->arch_data)->child,
|
if (!scan_OF_pci_childs(((struct device_node*)hose->arch_data)->child,
|
||||||
find_OF_pci_device_filter, (void *)node))
|
find_OF_pci_device_filter, (void *)node))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
reg = (unsigned int *) get_property(node, "reg", NULL);
|
reg = get_property(node, "reg", NULL);
|
||||||
if (!reg)
|
if (!reg)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
*bus = (reg[0] >> 16) & 0xff;
|
*bus = (reg[0] >> 16) & 0xff;
|
||||||
|
@ -885,8 +888,8 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose,
|
||||||
struct device_node *dev, int primary)
|
struct device_node *dev, int primary)
|
||||||
{
|
{
|
||||||
static unsigned int static_lc_ranges[256] __initdata;
|
static unsigned int static_lc_ranges[256] __initdata;
|
||||||
unsigned int *dt_ranges, *lc_ranges, *ranges, *prev;
|
const unsigned int *dt_ranges;
|
||||||
unsigned int size;
|
unsigned int *lc_ranges, *ranges, *prev, size;
|
||||||
int rlen = 0, orig_rlen;
|
int rlen = 0, orig_rlen;
|
||||||
int memno = 0;
|
int memno = 0;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
|
@ -897,7 +900,7 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose,
|
||||||
* that can have more than 3 ranges, fortunately using contiguous
|
* that can have more than 3 ranges, fortunately using contiguous
|
||||||
* addresses -- BenH
|
* addresses -- BenH
|
||||||
*/
|
*/
|
||||||
dt_ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
|
dt_ranges = get_property(dev, "ranges", &rlen);
|
||||||
if (!dt_ranges)
|
if (!dt_ranges)
|
||||||
return;
|
return;
|
||||||
/* Sanity check, though hopefully that never happens */
|
/* Sanity check, though hopefully that never happens */
|
||||||
|
|
|
@ -185,34 +185,6 @@ static void __devinit pci_setup_pci_controller(struct pci_controller *hose)
|
||||||
spin_unlock(&hose_spinlock);
|
spin_unlock(&hose_spinlock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void add_linux_pci_domain(struct device_node *dev,
|
|
||||||
struct pci_controller *phb)
|
|
||||||
{
|
|
||||||
struct property *of_prop;
|
|
||||||
unsigned int size;
|
|
||||||
|
|
||||||
of_prop = (struct property *)
|
|
||||||
get_property(dev, "linux,pci-domain", &size);
|
|
||||||
if (of_prop != NULL)
|
|
||||||
return;
|
|
||||||
WARN_ON(of_prop && size < sizeof(int));
|
|
||||||
if (of_prop && size < sizeof(int))
|
|
||||||
of_prop = NULL;
|
|
||||||
size = sizeof(struct property) + sizeof(int);
|
|
||||||
if (of_prop == NULL) {
|
|
||||||
if (mem_init_done)
|
|
||||||
of_prop = kmalloc(size, GFP_KERNEL);
|
|
||||||
else
|
|
||||||
of_prop = alloc_bootmem(size);
|
|
||||||
}
|
|
||||||
memset(of_prop, 0, sizeof(struct property));
|
|
||||||
of_prop->name = "linux,pci-domain";
|
|
||||||
of_prop->length = sizeof(int);
|
|
||||||
of_prop->value = (unsigned char *)&of_prop[1];
|
|
||||||
*((int *)of_prop->value) = phb->global_number;
|
|
||||||
prom_add_property(dev, of_prop);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct pci_controller * pcibios_alloc_controller(struct device_node *dev)
|
struct pci_controller * pcibios_alloc_controller(struct device_node *dev)
|
||||||
{
|
{
|
||||||
struct pci_controller *phb;
|
struct pci_controller *phb;
|
||||||
|
@ -226,22 +198,13 @@ struct pci_controller * pcibios_alloc_controller(struct device_node *dev)
|
||||||
pci_setup_pci_controller(phb);
|
pci_setup_pci_controller(phb);
|
||||||
phb->arch_data = dev;
|
phb->arch_data = dev;
|
||||||
phb->is_dynamic = mem_init_done;
|
phb->is_dynamic = mem_init_done;
|
||||||
if (dev) {
|
if (dev)
|
||||||
PHB_SET_NODE(phb, of_node_to_nid(dev));
|
PHB_SET_NODE(phb, of_node_to_nid(dev));
|
||||||
add_linux_pci_domain(dev, phb);
|
|
||||||
}
|
|
||||||
return phb;
|
return phb;
|
||||||
}
|
}
|
||||||
|
|
||||||
void pcibios_free_controller(struct pci_controller *phb)
|
void pcibios_free_controller(struct pci_controller *phb)
|
||||||
{
|
{
|
||||||
if (phb->arch_data) {
|
|
||||||
struct device_node *np = phb->arch_data;
|
|
||||||
int *domain = (int *)get_property(np,
|
|
||||||
"linux,pci-domain", NULL);
|
|
||||||
if (domain)
|
|
||||||
*domain = -1;
|
|
||||||
}
|
|
||||||
if (phb->is_dynamic)
|
if (phb->is_dynamic)
|
||||||
kfree(phb);
|
kfree(phb);
|
||||||
}
|
}
|
||||||
|
@ -283,10 +246,10 @@ static void __init pcibios_claim_of_setup(void)
|
||||||
#ifdef CONFIG_PPC_MULTIPLATFORM
|
#ifdef CONFIG_PPC_MULTIPLATFORM
|
||||||
static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
|
static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
|
||||||
{
|
{
|
||||||
u32 *prop;
|
const u32 *prop;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
prop = (u32 *) get_property(np, name, &len);
|
prop = get_property(np, name, &len);
|
||||||
if (prop && len >= 4)
|
if (prop && len >= 4)
|
||||||
return *prop;
|
return *prop;
|
||||||
return def;
|
return def;
|
||||||
|
@ -315,10 +278,11 @@ static void pci_parse_of_addrs(struct device_node *node, struct pci_dev *dev)
|
||||||
u64 base, size;
|
u64 base, size;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
u32 *addrs, i;
|
const u32 *addrs;
|
||||||
|
u32 i;
|
||||||
int proplen;
|
int proplen;
|
||||||
|
|
||||||
addrs = (u32 *) get_property(node, "assigned-addresses", &proplen);
|
addrs = get_property(node, "assigned-addresses", &proplen);
|
||||||
if (!addrs)
|
if (!addrs)
|
||||||
return;
|
return;
|
||||||
DBG(" parse addresses (%d bytes) @ %p\n", proplen, addrs);
|
DBG(" parse addresses (%d bytes) @ %p\n", proplen, addrs);
|
||||||
|
@ -418,7 +382,7 @@ void __devinit of_scan_bus(struct device_node *node,
|
||||||
struct pci_bus *bus)
|
struct pci_bus *bus)
|
||||||
{
|
{
|
||||||
struct device_node *child = NULL;
|
struct device_node *child = NULL;
|
||||||
u32 *reg;
|
const u32 *reg;
|
||||||
int reglen, devfn;
|
int reglen, devfn;
|
||||||
struct pci_dev *dev;
|
struct pci_dev *dev;
|
||||||
|
|
||||||
|
@ -426,7 +390,7 @@ void __devinit of_scan_bus(struct device_node *node,
|
||||||
|
|
||||||
while ((child = of_get_next_child(node, child)) != NULL) {
|
while ((child = of_get_next_child(node, child)) != NULL) {
|
||||||
DBG(" * %s\n", child->full_name);
|
DBG(" * %s\n", child->full_name);
|
||||||
reg = (u32 *) get_property(child, "reg", ®len);
|
reg = get_property(child, "reg", ®len);
|
||||||
if (reg == NULL || reglen < 20)
|
if (reg == NULL || reglen < 20)
|
||||||
continue;
|
continue;
|
||||||
devfn = (reg[0] >> 8) & 0xff;
|
devfn = (reg[0] >> 8) & 0xff;
|
||||||
|
@ -450,7 +414,7 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
|
||||||
struct pci_dev *dev)
|
struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
struct pci_bus *bus;
|
struct pci_bus *bus;
|
||||||
u32 *busrange, *ranges;
|
const u32 *busrange, *ranges;
|
||||||
int len, i, mode;
|
int len, i, mode;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
|
@ -459,13 +423,13 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
|
||||||
DBG("of_scan_pci_bridge(%s)\n", node->full_name);
|
DBG("of_scan_pci_bridge(%s)\n", node->full_name);
|
||||||
|
|
||||||
/* parse bus-range property */
|
/* parse bus-range property */
|
||||||
busrange = (u32 *) get_property(node, "bus-range", &len);
|
busrange = get_property(node, "bus-range", &len);
|
||||||
if (busrange == NULL || len != 8) {
|
if (busrange == NULL || len != 8) {
|
||||||
printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %s\n",
|
printk(KERN_DEBUG "Can't get bus-range for PCI-PCI bridge %s\n",
|
||||||
node->full_name);
|
node->full_name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ranges = (u32 *) get_property(node, "ranges", &len);
|
ranges = get_property(node, "ranges", &len);
|
||||||
if (ranges == NULL) {
|
if (ranges == NULL) {
|
||||||
printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n",
|
printk(KERN_DEBUG "Can't get ranges for PCI-PCI bridge %s\n",
|
||||||
node->full_name);
|
node->full_name);
|
||||||
|
@ -929,13 +893,13 @@ static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node,
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct isa_range *range;
|
const struct isa_range *range;
|
||||||
unsigned long pci_addr;
|
unsigned long pci_addr;
|
||||||
unsigned int isa_addr;
|
unsigned int isa_addr;
|
||||||
unsigned int size;
|
unsigned int size;
|
||||||
int rlen = 0;
|
int rlen = 0;
|
||||||
|
|
||||||
range = (struct isa_range *) get_property(isa_node, "ranges", &rlen);
|
range = get_property(isa_node, "ranges", &rlen);
|
||||||
if (range == NULL || (rlen < sizeof(struct isa_range))) {
|
if (range == NULL || (rlen < sizeof(struct isa_range))) {
|
||||||
printk(KERN_ERR "no ISA ranges or unexpected isa range size,"
|
printk(KERN_ERR "no ISA ranges or unexpected isa range size,"
|
||||||
"mapping 64k\n");
|
"mapping 64k\n");
|
||||||
|
@ -976,7 +940,8 @@ static void __devinit pci_process_ISA_OF_ranges(struct device_node *isa_node,
|
||||||
void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
|
void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
|
||||||
struct device_node *dev, int prim)
|
struct device_node *dev, int prim)
|
||||||
{
|
{
|
||||||
unsigned int *ranges, pci_space;
|
const unsigned int *ranges;
|
||||||
|
unsigned int pci_space;
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
int rlen = 0;
|
int rlen = 0;
|
||||||
int memno = 0;
|
int memno = 0;
|
||||||
|
@ -994,7 +959,7 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
|
||||||
* (size depending on dev->n_addr_cells)
|
* (size depending on dev->n_addr_cells)
|
||||||
* cells 4+5 or 5+6: the size of the range
|
* cells 4+5 or 5+6: the size of the range
|
||||||
*/
|
*/
|
||||||
ranges = (unsigned int *) get_property(dev, "ranges", &rlen);
|
ranges = get_property(dev, "ranges", &rlen);
|
||||||
if (ranges == NULL)
|
if (ranges == NULL)
|
||||||
return;
|
return;
|
||||||
hose->io_base_phys = 0;
|
hose->io_base_phys = 0;
|
||||||
|
|
|
@ -40,8 +40,8 @@
|
||||||
static void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
|
static void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
|
||||||
{
|
{
|
||||||
struct pci_controller *phb = data;
|
struct pci_controller *phb = data;
|
||||||
int *type = (int *)get_property(dn, "ibm,pci-config-space-type", NULL);
|
const int *type = get_property(dn, "ibm,pci-config-space-type", NULL);
|
||||||
u32 *regs;
|
const u32 *regs;
|
||||||
struct pci_dn *pdn;
|
struct pci_dn *pdn;
|
||||||
|
|
||||||
if (mem_init_done)
|
if (mem_init_done)
|
||||||
|
@ -54,14 +54,14 @@ static void * __devinit update_dn_pci_info(struct device_node *dn, void *data)
|
||||||
dn->data = pdn;
|
dn->data = pdn;
|
||||||
pdn->node = dn;
|
pdn->node = dn;
|
||||||
pdn->phb = phb;
|
pdn->phb = phb;
|
||||||
regs = (u32 *)get_property(dn, "reg", NULL);
|
regs = get_property(dn, "reg", NULL);
|
||||||
if (regs) {
|
if (regs) {
|
||||||
/* First register entry is addr (00BBSS00) */
|
/* First register entry is addr (00BBSS00) */
|
||||||
pdn->busno = (regs[0] >> 16) & 0xff;
|
pdn->busno = (regs[0] >> 16) & 0xff;
|
||||||
pdn->devfn = (regs[0] >> 8) & 0xff;
|
pdn->devfn = (regs[0] >> 8) & 0xff;
|
||||||
}
|
}
|
||||||
if (firmware_has_feature(FW_FEATURE_ISERIES)) {
|
if (firmware_has_feature(FW_FEATURE_ISERIES)) {
|
||||||
u32 *busp = (u32 *)get_property(dn, "linux,subbus", NULL);
|
const u32 *busp = get_property(dn, "linux,subbus", NULL);
|
||||||
if (busp)
|
if (busp)
|
||||||
pdn->bussubno = *busp;
|
pdn->bussubno = *busp;
|
||||||
}
|
}
|
||||||
|
@ -96,10 +96,11 @@ void *traverse_pci_devices(struct device_node *start, traverse_func pre,
|
||||||
|
|
||||||
/* We started with a phb, iterate all childs */
|
/* We started with a phb, iterate all childs */
|
||||||
for (dn = start->child; dn; dn = nextdn) {
|
for (dn = start->child; dn; dn = nextdn) {
|
||||||
u32 *classp, class;
|
const u32 *classp;
|
||||||
|
u32 class;
|
||||||
|
|
||||||
nextdn = NULL;
|
nextdn = NULL;
|
||||||
classp = (u32 *)get_property(dn, "class-code", NULL);
|
classp = get_property(dn, "class-code", NULL);
|
||||||
class = classp ? *classp : 0;
|
class = classp ? *classp : 0;
|
||||||
|
|
||||||
if (pre && ((ret = pre(dn, data)) != NULL))
|
if (pre && ((ret = pre(dn, data)) != NULL))
|
||||||
|
|
|
@ -91,25 +91,10 @@ EXPORT_SYMBOL(__copy_tofrom_user);
|
||||||
EXPORT_SYMBOL(__clear_user);
|
EXPORT_SYMBOL(__clear_user);
|
||||||
EXPORT_SYMBOL(__strncpy_from_user);
|
EXPORT_SYMBOL(__strncpy_from_user);
|
||||||
EXPORT_SYMBOL(__strnlen_user);
|
EXPORT_SYMBOL(__strnlen_user);
|
||||||
|
#ifdef CONFIG_PPC64
|
||||||
#ifndef __powerpc64__
|
EXPORT_SYMBOL(copy_4K_page);
|
||||||
EXPORT_SYMBOL(__ide_mm_insl);
|
|
||||||
EXPORT_SYMBOL(__ide_mm_outsw);
|
|
||||||
EXPORT_SYMBOL(__ide_mm_insw);
|
|
||||||
EXPORT_SYMBOL(__ide_mm_outsl);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
EXPORT_SYMBOL(_insb);
|
|
||||||
EXPORT_SYMBOL(_outsb);
|
|
||||||
EXPORT_SYMBOL(_insw);
|
|
||||||
EXPORT_SYMBOL(_outsw);
|
|
||||||
EXPORT_SYMBOL(_insl);
|
|
||||||
EXPORT_SYMBOL(_outsl);
|
|
||||||
EXPORT_SYMBOL(_insw_ns);
|
|
||||||
EXPORT_SYMBOL(_outsw_ns);
|
|
||||||
EXPORT_SYMBOL(_insl_ns);
|
|
||||||
EXPORT_SYMBOL(_outsl_ns);
|
|
||||||
|
|
||||||
#if defined(CONFIG_PPC32) && (defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE))
|
#if defined(CONFIG_PPC32) && (defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE))
|
||||||
EXPORT_SYMBOL(ppc_ide_md);
|
EXPORT_SYMBOL(ppc_ide_md);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -757,24 +757,9 @@ static int __init early_init_dt_scan_root(unsigned long node,
|
||||||
static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp)
|
static unsigned long __init dt_mem_next_cell(int s, cell_t **cellp)
|
||||||
{
|
{
|
||||||
cell_t *p = *cellp;
|
cell_t *p = *cellp;
|
||||||
unsigned long r;
|
|
||||||
|
|
||||||
/* Ignore more than 2 cells */
|
*cellp = p + s;
|
||||||
while (s > sizeof(unsigned long) / 4) {
|
return of_read_ulong(p, s);
|
||||||
p++;
|
|
||||||
s--;
|
|
||||||
}
|
|
||||||
r = *p++;
|
|
||||||
#ifdef CONFIG_PPC64
|
|
||||||
if (s > 1) {
|
|
||||||
r <<= 32;
|
|
||||||
r |= *(p++);
|
|
||||||
s--;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
*cellp = p;
|
|
||||||
return r;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -942,11 +927,11 @@ void __init early_init_devtree(void *params)
|
||||||
int
|
int
|
||||||
prom_n_addr_cells(struct device_node* np)
|
prom_n_addr_cells(struct device_node* np)
|
||||||
{
|
{
|
||||||
int* ip;
|
const int *ip;
|
||||||
do {
|
do {
|
||||||
if (np->parent)
|
if (np->parent)
|
||||||
np = np->parent;
|
np = np->parent;
|
||||||
ip = (int *) get_property(np, "#address-cells", NULL);
|
ip = get_property(np, "#address-cells", NULL);
|
||||||
if (ip != NULL)
|
if (ip != NULL)
|
||||||
return *ip;
|
return *ip;
|
||||||
} while (np->parent);
|
} while (np->parent);
|
||||||
|
@ -958,11 +943,11 @@ EXPORT_SYMBOL(prom_n_addr_cells);
|
||||||
int
|
int
|
||||||
prom_n_size_cells(struct device_node* np)
|
prom_n_size_cells(struct device_node* np)
|
||||||
{
|
{
|
||||||
int* ip;
|
const int* ip;
|
||||||
do {
|
do {
|
||||||
if (np->parent)
|
if (np->parent)
|
||||||
np = np->parent;
|
np = np->parent;
|
||||||
ip = (int *) get_property(np, "#size-cells", NULL);
|
ip = get_property(np, "#size-cells", NULL);
|
||||||
if (ip != NULL)
|
if (ip != NULL)
|
||||||
return *ip;
|
return *ip;
|
||||||
} while (np->parent);
|
} while (np->parent);
|
||||||
|
@ -1034,7 +1019,7 @@ int device_is_compatible(struct device_node *device, const char *compat)
|
||||||
const char* cp;
|
const char* cp;
|
||||||
int cplen, l;
|
int cplen, l;
|
||||||
|
|
||||||
cp = (char *) get_property(device, "compatible", &cplen);
|
cp = get_property(device, "compatible", &cplen);
|
||||||
if (cp == NULL)
|
if (cp == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
while (cplen > 0) {
|
while (cplen > 0) {
|
||||||
|
@ -1449,7 +1434,7 @@ static int of_finish_dynamic_node(struct device_node *node)
|
||||||
{
|
{
|
||||||
struct device_node *parent = of_get_parent(node);
|
struct device_node *parent = of_get_parent(node);
|
||||||
int err = 0;
|
int err = 0;
|
||||||
phandle *ibm_phandle;
|
const phandle *ibm_phandle;
|
||||||
|
|
||||||
node->name = get_property(node, "name", NULL);
|
node->name = get_property(node, "name", NULL);
|
||||||
node->type = get_property(node, "device_type", NULL);
|
node->type = get_property(node, "device_type", NULL);
|
||||||
|
@ -1466,8 +1451,7 @@ static int of_finish_dynamic_node(struct device_node *node)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
/* fix up new node's linux_phandle field */
|
/* fix up new node's linux_phandle field */
|
||||||
if ((ibm_phandle = (unsigned int *)get_property(node,
|
if ((ibm_phandle = get_property(node, "ibm,phandle", NULL)))
|
||||||
"ibm,phandle", NULL)))
|
|
||||||
node->linux_phandle = *ibm_phandle;
|
node->linux_phandle = *ibm_phandle;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
@ -1528,7 +1512,7 @@ struct property *of_find_property(struct device_node *np, const char *name,
|
||||||
* Find a property with a given name for a given node
|
* Find a property with a given name for a given node
|
||||||
* and return the value.
|
* and return the value.
|
||||||
*/
|
*/
|
||||||
void *get_property(struct device_node *np, const char *name, int *lenp)
|
const void *get_property(struct device_node *np, const char *name, int *lenp)
|
||||||
{
|
{
|
||||||
struct property *pp = of_find_property(np,name,lenp);
|
struct property *pp = of_find_property(np,name,lenp);
|
||||||
return pp ? pp->value : NULL;
|
return pp ? pp->value : NULL;
|
||||||
|
@ -1658,16 +1642,16 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
|
||||||
hardid = get_hard_smp_processor_id(cpu);
|
hardid = get_hard_smp_processor_id(cpu);
|
||||||
|
|
||||||
for_each_node_by_type(np, "cpu") {
|
for_each_node_by_type(np, "cpu") {
|
||||||
u32 *intserv;
|
const u32 *intserv;
|
||||||
unsigned int plen, t;
|
unsigned int plen, t;
|
||||||
|
|
||||||
/* Check for ibm,ppc-interrupt-server#s. If it doesn't exist
|
/* Check for ibm,ppc-interrupt-server#s. If it doesn't exist
|
||||||
* fallback to "reg" property and assume no threads
|
* fallback to "reg" property and assume no threads
|
||||||
*/
|
*/
|
||||||
intserv = (u32 *)get_property(np, "ibm,ppc-interrupt-server#s",
|
intserv = get_property(np, "ibm,ppc-interrupt-server#s",
|
||||||
&plen);
|
&plen);
|
||||||
if (intserv == NULL) {
|
if (intserv == NULL) {
|
||||||
u32 *reg = (u32 *)get_property(np, "reg", NULL);
|
const u32 *reg = get_property(np, "reg", NULL);
|
||||||
if (reg == NULL)
|
if (reg == NULL)
|
||||||
continue;
|
continue;
|
||||||
if (*reg == hardid) {
|
if (*reg == hardid) {
|
||||||
|
|
|
@ -2033,16 +2033,22 @@ static void __init fixup_device_tree_maple(void)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_PPC_CHRP
|
#ifdef CONFIG_PPC_CHRP
|
||||||
/* Pegasos lacks the "ranges" property in the isa node */
|
/* Pegasos and BriQ lacks the "ranges" property in the isa node */
|
||||||
static void __init fixup_device_tree_chrp(void)
|
static void __init fixup_device_tree_chrp(void)
|
||||||
{
|
{
|
||||||
phandle isa;
|
phandle isa;
|
||||||
u32 isa_ranges[6];
|
u32 isa_ranges[6];
|
||||||
|
u32 rloc = 0x01006000; /* IO space; PCI device = 12 */
|
||||||
char *name;
|
char *name;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
name = "/pci@80000000/isa@c";
|
name = "/pci@80000000/isa@c";
|
||||||
isa = call_prom("finddevice", 1, 1, ADDR(name));
|
isa = call_prom("finddevice", 1, 1, ADDR(name));
|
||||||
|
if (!PHANDLE_VALID(isa)) {
|
||||||
|
name = "/pci@ff500000/isa@6";
|
||||||
|
isa = call_prom("finddevice", 1, 1, ADDR(name));
|
||||||
|
rloc = 0x01003000; /* IO space; PCI device = 6 */
|
||||||
|
}
|
||||||
if (!PHANDLE_VALID(isa))
|
if (!PHANDLE_VALID(isa))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -2054,7 +2060,7 @@ static void __init fixup_device_tree_chrp(void)
|
||||||
|
|
||||||
isa_ranges[0] = 0x1;
|
isa_ranges[0] = 0x1;
|
||||||
isa_ranges[1] = 0x0;
|
isa_ranges[1] = 0x0;
|
||||||
isa_ranges[2] = 0x01006000;
|
isa_ranges[2] = rloc;
|
||||||
isa_ranges[3] = 0x0;
|
isa_ranges[3] = 0x0;
|
||||||
isa_ranges[4] = 0x0;
|
isa_ranges[4] = 0x0;
|
||||||
isa_ranges[5] = 0x00010000;
|
isa_ranges[5] = 0x00010000;
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
/* Debug utility */
|
/* Debug utility */
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
static void of_dump_addr(const char *s, u32 *addr, int na)
|
static void of_dump_addr(const char *s, const u32 *addr, int na)
|
||||||
{
|
{
|
||||||
printk("%s", s);
|
printk("%s", s);
|
||||||
while(na--)
|
while(na--)
|
||||||
|
@ -35,7 +35,7 @@ static void of_dump_addr(const char *s, u32 *addr, int na)
|
||||||
printk("\n");
|
printk("\n");
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
static void of_dump_addr(const char *s, u32 *addr, int na) { }
|
static void of_dump_addr(const char *s, const u32 *addr, int na) { }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
@ -46,9 +46,10 @@ struct of_bus {
|
||||||
int (*match)(struct device_node *parent);
|
int (*match)(struct device_node *parent);
|
||||||
void (*count_cells)(struct device_node *child,
|
void (*count_cells)(struct device_node *child,
|
||||||
int *addrc, int *sizec);
|
int *addrc, int *sizec);
|
||||||
u64 (*map)(u32 *addr, u32 *range, int na, int ns, int pna);
|
u64 (*map)(u32 *addr, const u32 *range,
|
||||||
|
int na, int ns, int pna);
|
||||||
int (*translate)(u32 *addr, u64 offset, int na);
|
int (*translate)(u32 *addr, u64 offset, int na);
|
||||||
unsigned int (*get_flags)(u32 *addr);
|
unsigned int (*get_flags)(const u32 *addr);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,7 +66,8 @@ static void of_bus_default_count_cells(struct device_node *dev,
|
||||||
*sizec = prom_n_size_cells(dev);
|
*sizec = prom_n_size_cells(dev);
|
||||||
}
|
}
|
||||||
|
|
||||||
static u64 of_bus_default_map(u32 *addr, u32 *range, int na, int ns, int pna)
|
static u64 of_bus_default_map(u32 *addr, const u32 *range,
|
||||||
|
int na, int ns, int pna)
|
||||||
{
|
{
|
||||||
u64 cp, s, da;
|
u64 cp, s, da;
|
||||||
|
|
||||||
|
@ -93,7 +95,7 @@ static int of_bus_default_translate(u32 *addr, u64 offset, int na)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int of_bus_default_get_flags(u32 *addr)
|
static unsigned int of_bus_default_get_flags(const u32 *addr)
|
||||||
{
|
{
|
||||||
return IORESOURCE_MEM;
|
return IORESOURCE_MEM;
|
||||||
}
|
}
|
||||||
|
@ -118,7 +120,7 @@ static void of_bus_pci_count_cells(struct device_node *np,
|
||||||
*sizec = 2;
|
*sizec = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u64 of_bus_pci_map(u32 *addr, u32 *range, int na, int ns, int pna)
|
static u64 of_bus_pci_map(u32 *addr, const u32 *range, int na, int ns, int pna)
|
||||||
{
|
{
|
||||||
u64 cp, s, da;
|
u64 cp, s, da;
|
||||||
|
|
||||||
|
@ -143,7 +145,7 @@ static int of_bus_pci_translate(u32 *addr, u64 offset, int na)
|
||||||
return of_bus_default_translate(addr + 1, offset, na - 1);
|
return of_bus_default_translate(addr + 1, offset, na - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int of_bus_pci_get_flags(u32 *addr)
|
static unsigned int of_bus_pci_get_flags(const u32 *addr)
|
||||||
{
|
{
|
||||||
unsigned int flags = 0;
|
unsigned int flags = 0;
|
||||||
u32 w = addr[0];
|
u32 w = addr[0];
|
||||||
|
@ -178,7 +180,7 @@ static void of_bus_isa_count_cells(struct device_node *child,
|
||||||
*sizec = 1;
|
*sizec = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static u64 of_bus_isa_map(u32 *addr, u32 *range, int na, int ns, int pna)
|
static u64 of_bus_isa_map(u32 *addr, const u32 *range, int na, int ns, int pna)
|
||||||
{
|
{
|
||||||
u64 cp, s, da;
|
u64 cp, s, da;
|
||||||
|
|
||||||
|
@ -203,7 +205,7 @@ static int of_bus_isa_translate(u32 *addr, u64 offset, int na)
|
||||||
return of_bus_default_translate(addr + 1, offset, na - 1);
|
return of_bus_default_translate(addr + 1, offset, na - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned int of_bus_isa_get_flags(u32 *addr)
|
static unsigned int of_bus_isa_get_flags(const u32 *addr)
|
||||||
{
|
{
|
||||||
unsigned int flags = 0;
|
unsigned int flags = 0;
|
||||||
u32 w = addr[0];
|
u32 w = addr[0];
|
||||||
|
@ -268,7 +270,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
|
||||||
struct of_bus *pbus, u32 *addr,
|
struct of_bus *pbus, u32 *addr,
|
||||||
int na, int ns, int pna)
|
int na, int ns, int pna)
|
||||||
{
|
{
|
||||||
u32 *ranges;
|
const u32 *ranges;
|
||||||
unsigned int rlen;
|
unsigned int rlen;
|
||||||
int rone;
|
int rone;
|
||||||
u64 offset = OF_BAD_ADDR;
|
u64 offset = OF_BAD_ADDR;
|
||||||
|
@ -285,7 +287,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
|
||||||
* to translate addresses that aren't supposed to be translated in
|
* to translate addresses that aren't supposed to be translated in
|
||||||
* the first place. --BenH.
|
* the first place. --BenH.
|
||||||
*/
|
*/
|
||||||
ranges = (u32 *)get_property(parent, "ranges", &rlen);
|
ranges = get_property(parent, "ranges", &rlen);
|
||||||
if (ranges == NULL || rlen == 0) {
|
if (ranges == NULL || rlen == 0) {
|
||||||
offset = of_read_number(addr, na);
|
offset = of_read_number(addr, na);
|
||||||
memset(addr, 0, pna * 4);
|
memset(addr, 0, pna * 4);
|
||||||
|
@ -328,7 +330,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
|
||||||
* that can be mapped to a cpu physical address). This is not really specified
|
* that can be mapped to a cpu physical address). This is not really specified
|
||||||
* that way, but this is traditionally the way IBM at least do things
|
* that way, but this is traditionally the way IBM at least do things
|
||||||
*/
|
*/
|
||||||
u64 of_translate_address(struct device_node *dev, u32 *in_addr)
|
u64 of_translate_address(struct device_node *dev, const u32 *in_addr)
|
||||||
{
|
{
|
||||||
struct device_node *parent = NULL;
|
struct device_node *parent = NULL;
|
||||||
struct of_bus *bus, *pbus;
|
struct of_bus *bus, *pbus;
|
||||||
|
@ -405,10 +407,10 @@ u64 of_translate_address(struct device_node *dev, u32 *in_addr)
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(of_translate_address);
|
EXPORT_SYMBOL(of_translate_address);
|
||||||
|
|
||||||
u32 *of_get_address(struct device_node *dev, int index, u64 *size,
|
const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
|
||||||
unsigned int *flags)
|
unsigned int *flags)
|
||||||
{
|
{
|
||||||
u32 *prop;
|
const u32 *prop;
|
||||||
unsigned int psize;
|
unsigned int psize;
|
||||||
struct device_node *parent;
|
struct device_node *parent;
|
||||||
struct of_bus *bus;
|
struct of_bus *bus;
|
||||||
|
@ -425,7 +427,7 @@ u32 *of_get_address(struct device_node *dev, int index, u64 *size,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Get "reg" or "assigned-addresses" property */
|
/* Get "reg" or "assigned-addresses" property */
|
||||||
prop = (u32 *)get_property(dev, bus->addresses, &psize);
|
prop = get_property(dev, bus->addresses, &psize);
|
||||||
if (prop == NULL)
|
if (prop == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
psize /= 4;
|
psize /= 4;
|
||||||
|
@ -443,10 +445,10 @@ u32 *of_get_address(struct device_node *dev, int index, u64 *size,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(of_get_address);
|
EXPORT_SYMBOL(of_get_address);
|
||||||
|
|
||||||
u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
|
const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
|
||||||
unsigned int *flags)
|
unsigned int *flags)
|
||||||
{
|
{
|
||||||
u32 *prop;
|
const u32 *prop;
|
||||||
unsigned int psize;
|
unsigned int psize;
|
||||||
struct device_node *parent;
|
struct device_node *parent;
|
||||||
struct of_bus *bus;
|
struct of_bus *bus;
|
||||||
|
@ -467,7 +469,7 @@ u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Get "reg" or "assigned-addresses" property */
|
/* Get "reg" or "assigned-addresses" property */
|
||||||
prop = (u32 *)get_property(dev, bus->addresses, &psize);
|
prop = get_property(dev, bus->addresses, &psize);
|
||||||
if (prop == NULL)
|
if (prop == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
psize /= 4;
|
psize /= 4;
|
||||||
|
@ -485,7 +487,7 @@ u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(of_get_pci_address);
|
EXPORT_SYMBOL(of_get_pci_address);
|
||||||
|
|
||||||
static int __of_address_to_resource(struct device_node *dev, u32 *addrp,
|
static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
|
||||||
u64 size, unsigned int flags,
|
u64 size, unsigned int flags,
|
||||||
struct resource *r)
|
struct resource *r)
|
||||||
{
|
{
|
||||||
|
@ -516,7 +518,7 @@ static int __of_address_to_resource(struct device_node *dev, u32 *addrp,
|
||||||
int of_address_to_resource(struct device_node *dev, int index,
|
int of_address_to_resource(struct device_node *dev, int index,
|
||||||
struct resource *r)
|
struct resource *r)
|
||||||
{
|
{
|
||||||
u32 *addrp;
|
const u32 *addrp;
|
||||||
u64 size;
|
u64 size;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
|
|
||||||
|
@ -530,7 +532,7 @@ EXPORT_SYMBOL_GPL(of_address_to_resource);
|
||||||
int of_pci_address_to_resource(struct device_node *dev, int bar,
|
int of_pci_address_to_resource(struct device_node *dev, int bar,
|
||||||
struct resource *r)
|
struct resource *r)
|
||||||
{
|
{
|
||||||
u32 *addrp;
|
const u32 *addrp;
|
||||||
u64 size;
|
u64 size;
|
||||||
unsigned int flags;
|
unsigned int flags;
|
||||||
|
|
||||||
|
@ -541,13 +543,14 @@ int of_pci_address_to_resource(struct device_node *dev, int bar,
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
|
EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
|
||||||
|
|
||||||
void of_parse_dma_window(struct device_node *dn, unsigned char *dma_window_prop,
|
void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
|
||||||
unsigned long *busno, unsigned long *phys, unsigned long *size)
|
unsigned long *busno, unsigned long *phys, unsigned long *size)
|
||||||
{
|
{
|
||||||
u32 *dma_window, cells;
|
const u32 *dma_window;
|
||||||
unsigned char *prop;
|
u32 cells;
|
||||||
|
const unsigned char *prop;
|
||||||
|
|
||||||
dma_window = (u32 *)dma_window_prop;
|
dma_window = dma_window_prop;
|
||||||
|
|
||||||
/* busno is always one cell */
|
/* busno is always one cell */
|
||||||
*busno = *(dma_window++);
|
*busno = *(dma_window++);
|
||||||
|
@ -576,13 +579,13 @@ static struct device_node *of_irq_dflt_pic;
|
||||||
static struct device_node *of_irq_find_parent(struct device_node *child)
|
static struct device_node *of_irq_find_parent(struct device_node *child)
|
||||||
{
|
{
|
||||||
struct device_node *p;
|
struct device_node *p;
|
||||||
phandle *parp;
|
const phandle *parp;
|
||||||
|
|
||||||
if (!of_node_get(child))
|
if (!of_node_get(child))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
parp = (phandle *)get_property(child, "interrupt-parent", NULL);
|
parp = get_property(child, "interrupt-parent", NULL);
|
||||||
if (parp == NULL)
|
if (parp == NULL)
|
||||||
p = of_get_parent(child);
|
p = of_get_parent(child);
|
||||||
else {
|
else {
|
||||||
|
@ -639,11 +642,11 @@ void of_irq_map_init(unsigned int flags)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
|
int of_irq_map_raw(struct device_node *parent, const u32 *intspec, u32 ointsize,
|
||||||
u32 *addr, struct of_irq *out_irq)
|
const u32 *addr, struct of_irq *out_irq)
|
||||||
{
|
{
|
||||||
struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
|
struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL;
|
||||||
u32 *tmp, *imap, *imask;
|
const u32 *tmp, *imap, *imask;
|
||||||
u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
|
u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0;
|
||||||
int imaplen, match, i;
|
int imaplen, match, i;
|
||||||
|
|
||||||
|
@ -657,7 +660,7 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
|
||||||
* is none, we are nice and just walk up the tree
|
* is none, we are nice and just walk up the tree
|
||||||
*/
|
*/
|
||||||
do {
|
do {
|
||||||
tmp = (u32 *)get_property(ipar, "#interrupt-cells", NULL);
|
tmp = get_property(ipar, "#interrupt-cells", NULL);
|
||||||
if (tmp != NULL) {
|
if (tmp != NULL) {
|
||||||
intsize = *tmp;
|
intsize = *tmp;
|
||||||
break;
|
break;
|
||||||
|
@ -681,7 +684,7 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
|
||||||
*/
|
*/
|
||||||
old = of_node_get(ipar);
|
old = of_node_get(ipar);
|
||||||
do {
|
do {
|
||||||
tmp = (u32 *)get_property(old, "#address-cells", NULL);
|
tmp = get_property(old, "#address-cells", NULL);
|
||||||
tnode = of_get_parent(old);
|
tnode = of_get_parent(old);
|
||||||
of_node_put(old);
|
of_node_put(old);
|
||||||
old = tnode;
|
old = tnode;
|
||||||
|
@ -708,7 +711,7 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Now look for an interrupt-map */
|
/* Now look for an interrupt-map */
|
||||||
imap = (u32 *)get_property(ipar, "interrupt-map", &imaplen);
|
imap = get_property(ipar, "interrupt-map", &imaplen);
|
||||||
/* No interrupt map, check for an interrupt parent */
|
/* No interrupt map, check for an interrupt parent */
|
||||||
if (imap == NULL) {
|
if (imap == NULL) {
|
||||||
DBG(" -> no map, getting parent\n");
|
DBG(" -> no map, getting parent\n");
|
||||||
|
@ -718,7 +721,7 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
|
||||||
imaplen /= sizeof(u32);
|
imaplen /= sizeof(u32);
|
||||||
|
|
||||||
/* Look for a mask */
|
/* Look for a mask */
|
||||||
imask = (u32 *)get_property(ipar, "interrupt-map-mask", NULL);
|
imask = get_property(ipar, "interrupt-map-mask", NULL);
|
||||||
|
|
||||||
/* If we were passed no "reg" property and we attempt to parse
|
/* If we were passed no "reg" property and we attempt to parse
|
||||||
* an interrupt-map, then #address-cells must be 0.
|
* an interrupt-map, then #address-cells must be 0.
|
||||||
|
@ -765,14 +768,14 @@ int of_irq_map_raw(struct device_node *parent, u32 *intspec, u32 ointsize,
|
||||||
/* Get #interrupt-cells and #address-cells of new
|
/* Get #interrupt-cells and #address-cells of new
|
||||||
* parent
|
* parent
|
||||||
*/
|
*/
|
||||||
tmp = (u32 *)get_property(newpar, "#interrupt-cells",
|
tmp = get_property(newpar, "#interrupt-cells",
|
||||||
NULL);
|
NULL);
|
||||||
if (tmp == NULL) {
|
if (tmp == NULL) {
|
||||||
DBG(" -> parent lacks #interrupt-cells !\n");
|
DBG(" -> parent lacks #interrupt-cells !\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
newintsize = *tmp;
|
newintsize = *tmp;
|
||||||
tmp = (u32 *)get_property(newpar, "#address-cells",
|
tmp = get_property(newpar, "#address-cells",
|
||||||
NULL);
|
NULL);
|
||||||
newaddrsize = (tmp == NULL) ? 0 : *tmp;
|
newaddrsize = (tmp == NULL) ? 0 : *tmp;
|
||||||
|
|
||||||
|
@ -818,14 +821,14 @@ EXPORT_SYMBOL_GPL(of_irq_map_raw);
|
||||||
static int of_irq_map_oldworld(struct device_node *device, int index,
|
static int of_irq_map_oldworld(struct device_node *device, int index,
|
||||||
struct of_irq *out_irq)
|
struct of_irq *out_irq)
|
||||||
{
|
{
|
||||||
u32 *ints;
|
const u32 *ints;
|
||||||
int intlen;
|
int intlen;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Old machines just have a list of interrupt numbers
|
* Old machines just have a list of interrupt numbers
|
||||||
* and no interrupt-controller nodes.
|
* and no interrupt-controller nodes.
|
||||||
*/
|
*/
|
||||||
ints = (u32 *) get_property(device, "AAPL,interrupts", &intlen);
|
ints = get_property(device, "AAPL,interrupts", &intlen);
|
||||||
if (ints == NULL)
|
if (ints == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
intlen /= sizeof(u32);
|
intlen /= sizeof(u32);
|
||||||
|
@ -850,7 +853,8 @@ static int of_irq_map_oldworld(struct device_node *device, int index,
|
||||||
int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq)
|
int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq)
|
||||||
{
|
{
|
||||||
struct device_node *p;
|
struct device_node *p;
|
||||||
u32 *intspec, *tmp, intsize, intlen, *addr;
|
const u32 *intspec, *tmp, *addr;
|
||||||
|
u32 intsize, intlen;
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
DBG("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index);
|
DBG("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index);
|
||||||
|
@ -860,13 +864,13 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq
|
||||||
return of_irq_map_oldworld(device, index, out_irq);
|
return of_irq_map_oldworld(device, index, out_irq);
|
||||||
|
|
||||||
/* Get the interrupts property */
|
/* Get the interrupts property */
|
||||||
intspec = (u32 *)get_property(device, "interrupts", &intlen);
|
intspec = get_property(device, "interrupts", &intlen);
|
||||||
if (intspec == NULL)
|
if (intspec == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
intlen /= sizeof(u32);
|
intlen /= sizeof(u32);
|
||||||
|
|
||||||
/* Get the reg property (if any) */
|
/* Get the reg property (if any) */
|
||||||
addr = (u32 *)get_property(device, "reg", NULL);
|
addr = get_property(device, "reg", NULL);
|
||||||
|
|
||||||
/* Look for the interrupt parent. */
|
/* Look for the interrupt parent. */
|
||||||
p = of_irq_find_parent(device);
|
p = of_irq_find_parent(device);
|
||||||
|
@ -874,7 +878,7 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
/* Get size of interrupt specifier */
|
/* Get size of interrupt specifier */
|
||||||
tmp = (u32 *)get_property(p, "#interrupt-cells", NULL);
|
tmp = get_property(p, "#interrupt-cells", NULL);
|
||||||
if (tmp == NULL) {
|
if (tmp == NULL) {
|
||||||
of_node_put(p);
|
of_node_put(p);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
|
@ -246,12 +246,12 @@ struct file_operations ppc_rtas_rmo_buf_ops = {
|
||||||
|
|
||||||
static int ppc_rtas_find_all_sensors(void);
|
static int ppc_rtas_find_all_sensors(void);
|
||||||
static void ppc_rtas_process_sensor(struct seq_file *m,
|
static void ppc_rtas_process_sensor(struct seq_file *m,
|
||||||
struct individual_sensor *s, int state, int error, char *loc);
|
struct individual_sensor *s, int state, int error, const char *loc);
|
||||||
static char *ppc_rtas_process_error(int error);
|
static char *ppc_rtas_process_error(int error);
|
||||||
static void get_location_code(struct seq_file *m,
|
static void get_location_code(struct seq_file *m,
|
||||||
struct individual_sensor *s, char *loc);
|
struct individual_sensor *s, const char *loc);
|
||||||
static void check_location_string(struct seq_file *m, char *c);
|
static void check_location_string(struct seq_file *m, const char *c);
|
||||||
static void check_location(struct seq_file *m, char *c);
|
static void check_location(struct seq_file *m, const char *c);
|
||||||
|
|
||||||
static int __init proc_rtas_init(void)
|
static int __init proc_rtas_init(void)
|
||||||
{
|
{
|
||||||
|
@ -446,11 +446,11 @@ static int ppc_rtas_sensors_show(struct seq_file *m, void *v)
|
||||||
for (i=0; i<sensors.quant; i++) {
|
for (i=0; i<sensors.quant; i++) {
|
||||||
struct individual_sensor *p = &sensors.sensor[i];
|
struct individual_sensor *p = &sensors.sensor[i];
|
||||||
char rstr[64];
|
char rstr[64];
|
||||||
char *loc;
|
const char *loc;
|
||||||
int llen, offs;
|
int llen, offs;
|
||||||
|
|
||||||
sprintf (rstr, SENSOR_PREFIX"%04d", p->token);
|
sprintf (rstr, SENSOR_PREFIX"%04d", p->token);
|
||||||
loc = (char *) get_property(rtas_node, rstr, &llen);
|
loc = get_property(rtas_node, rstr, &llen);
|
||||||
|
|
||||||
/* A sensor may have multiple instances */
|
/* A sensor may have multiple instances */
|
||||||
for (j = 0, offs = 0; j <= p->quant; j++) {
|
for (j = 0, offs = 0; j <= p->quant; j++) {
|
||||||
|
@ -474,10 +474,10 @@ static int ppc_rtas_sensors_show(struct seq_file *m, void *v)
|
||||||
|
|
||||||
static int ppc_rtas_find_all_sensors(void)
|
static int ppc_rtas_find_all_sensors(void)
|
||||||
{
|
{
|
||||||
unsigned int *utmp;
|
const unsigned int *utmp;
|
||||||
int len, i;
|
int len, i;
|
||||||
|
|
||||||
utmp = (unsigned int *) get_property(rtas_node, "rtas-sensors", &len);
|
utmp = get_property(rtas_node, "rtas-sensors", &len);
|
||||||
if (utmp == NULL) {
|
if (utmp == NULL) {
|
||||||
printk (KERN_ERR "error: could not get rtas-sensors\n");
|
printk (KERN_ERR "error: could not get rtas-sensors\n");
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -530,7 +530,7 @@ static char *ppc_rtas_process_error(int error)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void ppc_rtas_process_sensor(struct seq_file *m,
|
static void ppc_rtas_process_sensor(struct seq_file *m,
|
||||||
struct individual_sensor *s, int state, int error, char *loc)
|
struct individual_sensor *s, int state, int error, const char *loc)
|
||||||
{
|
{
|
||||||
/* Defined return vales */
|
/* Defined return vales */
|
||||||
const char * key_switch[] = { "Off\t", "Normal\t", "Secure\t",
|
const char * key_switch[] = { "Off\t", "Normal\t", "Secure\t",
|
||||||
|
@ -682,7 +682,7 @@ static void ppc_rtas_process_sensor(struct seq_file *m,
|
||||||
|
|
||||||
/* ****************************************************************** */
|
/* ****************************************************************** */
|
||||||
|
|
||||||
static void check_location(struct seq_file *m, char *c)
|
static void check_location(struct seq_file *m, const char *c)
|
||||||
{
|
{
|
||||||
switch (c[0]) {
|
switch (c[0]) {
|
||||||
case LOC_PLANAR:
|
case LOC_PLANAR:
|
||||||
|
@ -719,7 +719,7 @@ static void check_location(struct seq_file *m, char *c)
|
||||||
* ${LETTER}${NUMBER}[[-/]${LETTER}${NUMBER} [ ... ] ]
|
* ${LETTER}${NUMBER}[[-/]${LETTER}${NUMBER} [ ... ] ]
|
||||||
* the '.' may be an abbrevation
|
* the '.' may be an abbrevation
|
||||||
*/
|
*/
|
||||||
static void check_location_string(struct seq_file *m, char *c)
|
static void check_location_string(struct seq_file *m, const char *c)
|
||||||
{
|
{
|
||||||
while (*c) {
|
while (*c) {
|
||||||
if (isalpha(*c) || *c == '.')
|
if (isalpha(*c) || *c == '.')
|
||||||
|
@ -733,7 +733,8 @@ static void check_location_string(struct seq_file *m, char *c)
|
||||||
|
|
||||||
/* ****************************************************************** */
|
/* ****************************************************************** */
|
||||||
|
|
||||||
static void get_location_code(struct seq_file *m, struct individual_sensor *s, char *loc)
|
static void get_location_code(struct seq_file *m, struct individual_sensor *s,
|
||||||
|
const char *loc)
|
||||||
{
|
{
|
||||||
if (!loc || !*loc) {
|
if (!loc || !*loc) {
|
||||||
seq_printf(m, "---");/* does not have a location */
|
seq_printf(m, "---");/* does not have a location */
|
||||||
|
|
|
@ -177,10 +177,12 @@ void __init udbg_init_rtas_console(void)
|
||||||
void rtas_progress(char *s, unsigned short hex)
|
void rtas_progress(char *s, unsigned short hex)
|
||||||
{
|
{
|
||||||
struct device_node *root;
|
struct device_node *root;
|
||||||
int width, *p;
|
int width;
|
||||||
|
const int *p;
|
||||||
char *os;
|
char *os;
|
||||||
static int display_character, set_indicator;
|
static int display_character, set_indicator;
|
||||||
static int display_width, display_lines, *row_width, form_feed;
|
static int display_width, display_lines, form_feed;
|
||||||
|
const static int *row_width;
|
||||||
static DEFINE_SPINLOCK(progress_lock);
|
static DEFINE_SPINLOCK(progress_lock);
|
||||||
static int current_line;
|
static int current_line;
|
||||||
static int pending_newline = 0; /* did last write end with unprinted newline? */
|
static int pending_newline = 0; /* did last write end with unprinted newline? */
|
||||||
|
@ -191,16 +193,16 @@ void rtas_progress(char *s, unsigned short hex)
|
||||||
if (display_width == 0) {
|
if (display_width == 0) {
|
||||||
display_width = 0x10;
|
display_width = 0x10;
|
||||||
if ((root = find_path_device("/rtas"))) {
|
if ((root = find_path_device("/rtas"))) {
|
||||||
if ((p = (unsigned int *)get_property(root,
|
if ((p = get_property(root,
|
||||||
"ibm,display-line-length", NULL)))
|
"ibm,display-line-length", NULL)))
|
||||||
display_width = *p;
|
display_width = *p;
|
||||||
if ((p = (unsigned int *)get_property(root,
|
if ((p = get_property(root,
|
||||||
"ibm,form-feed", NULL)))
|
"ibm,form-feed", NULL)))
|
||||||
form_feed = *p;
|
form_feed = *p;
|
||||||
if ((p = (unsigned int *)get_property(root,
|
if ((p = get_property(root,
|
||||||
"ibm,display-number-of-lines", NULL)))
|
"ibm,display-number-of-lines", NULL)))
|
||||||
display_lines = *p;
|
display_lines = *p;
|
||||||
row_width = (unsigned int *)get_property(root,
|
row_width = get_property(root,
|
||||||
"ibm,display-truncation-length", NULL);
|
"ibm,display-truncation-length", NULL);
|
||||||
}
|
}
|
||||||
display_character = rtas_token("display-character");
|
display_character = rtas_token("display-character");
|
||||||
|
@ -293,10 +295,10 @@ EXPORT_SYMBOL(rtas_progress); /* needed by rtas_flash module */
|
||||||
|
|
||||||
int rtas_token(const char *service)
|
int rtas_token(const char *service)
|
||||||
{
|
{
|
||||||
int *tokp;
|
const int *tokp;
|
||||||
if (rtas.dev == NULL)
|
if (rtas.dev == NULL)
|
||||||
return RTAS_UNKNOWN_SERVICE;
|
return RTAS_UNKNOWN_SERVICE;
|
||||||
tokp = (int *) get_property(rtas.dev, service, NULL);
|
tokp = get_property(rtas.dev, service, NULL);
|
||||||
return tokp ? *tokp : RTAS_UNKNOWN_SERVICE;
|
return tokp ? *tokp : RTAS_UNKNOWN_SERVICE;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(rtas_token);
|
EXPORT_SYMBOL(rtas_token);
|
||||||
|
@ -626,6 +628,9 @@ void rtas_os_term(char *str)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
|
if (panic_timeout)
|
||||||
|
return;
|
||||||
|
|
||||||
if (RTAS_UNKNOWN_SERVICE == rtas_token("ibm,os-term"))
|
if (RTAS_UNKNOWN_SERVICE == rtas_token("ibm,os-term"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -687,15 +692,14 @@ static int rtas_ibm_suspend_me(struct rtas_args *args)
|
||||||
int i;
|
int i;
|
||||||
long state;
|
long state;
|
||||||
long rc;
|
long rc;
|
||||||
unsigned long dummy;
|
unsigned long retbuf[PLPAR_HCALL_BUFSIZE];
|
||||||
|
|
||||||
struct rtas_suspend_me_data data;
|
struct rtas_suspend_me_data data;
|
||||||
|
|
||||||
/* Make sure the state is valid */
|
/* Make sure the state is valid */
|
||||||
rc = plpar_hcall(H_VASI_STATE,
|
rc = plpar_hcall(H_VASI_STATE, retbuf,
|
||||||
((u64)args->args[0] << 32) | args->args[1],
|
((u64)args->args[0] << 32) | args->args[1]);
|
||||||
0, 0, 0,
|
|
||||||
&state, &dummy, &dummy);
|
state = retbuf[0];
|
||||||
|
|
||||||
if (rc) {
|
if (rc) {
|
||||||
printk(KERN_ERR "rtas_ibm_suspend_me: vasi_state returned %ld\n",rc);
|
printk(KERN_ERR "rtas_ibm_suspend_me: vasi_state returned %ld\n",rc);
|
||||||
|
@ -845,15 +849,15 @@ void __init rtas_initialize(void)
|
||||||
*/
|
*/
|
||||||
rtas.dev = of_find_node_by_name(NULL, "rtas");
|
rtas.dev = of_find_node_by_name(NULL, "rtas");
|
||||||
if (rtas.dev) {
|
if (rtas.dev) {
|
||||||
u32 *basep, *entryp;
|
const u32 *basep, *entryp, *sizep;
|
||||||
u32 *sizep;
|
|
||||||
|
|
||||||
basep = (u32 *)get_property(rtas.dev, "linux,rtas-base", NULL);
|
basep = get_property(rtas.dev, "linux,rtas-base", NULL);
|
||||||
sizep = (u32 *)get_property(rtas.dev, "rtas-size", NULL);
|
sizep = get_property(rtas.dev, "rtas-size", NULL);
|
||||||
if (basep != NULL && sizep != NULL) {
|
if (basep != NULL && sizep != NULL) {
|
||||||
rtas.base = *basep;
|
rtas.base = *basep;
|
||||||
rtas.size = *sizep;
|
rtas.size = *sizep;
|
||||||
entryp = (u32 *)get_property(rtas.dev, "linux,rtas-entry", NULL);
|
entryp = get_property(rtas.dev,
|
||||||
|
"linux,rtas-entry", NULL);
|
||||||
if (entryp == NULL) /* Ugh */
|
if (entryp == NULL) /* Ugh */
|
||||||
rtas.entry = rtas.base;
|
rtas.entry = rtas.base;
|
||||||
else
|
else
|
||||||
|
@ -909,6 +913,11 @@ int __init early_init_dt_scan_rtas(unsigned long node,
|
||||||
basep = of_get_flat_dt_prop(node, "get-term-char", NULL);
|
basep = of_get_flat_dt_prop(node, "get-term-char", NULL);
|
||||||
if (basep)
|
if (basep)
|
||||||
rtas_getchar_token = *basep;
|
rtas_getchar_token = *basep;
|
||||||
|
|
||||||
|
if (rtas_putchar_token != RTAS_UNKNOWN_SERVICE &&
|
||||||
|
rtas_getchar_token != RTAS_UNKNOWN_SERVICE)
|
||||||
|
udbg_init_rtas_console();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* break now */
|
/* break now */
|
||||||
|
|
|
@ -57,7 +57,7 @@ static inline int config_access_valid(struct pci_dn *dn, int where)
|
||||||
|
|
||||||
static int of_device_available(struct device_node * dn)
|
static int of_device_available(struct device_node * dn)
|
||||||
{
|
{
|
||||||
char * status;
|
const char *status;
|
||||||
|
|
||||||
status = get_property(dn, "status", NULL);
|
status = get_property(dn, "status", NULL);
|
||||||
|
|
||||||
|
@ -81,8 +81,7 @@ int rtas_read_config(struct pci_dn *pdn, int where, int size, u32 *val)
|
||||||
if (!config_access_valid(pdn, where))
|
if (!config_access_valid(pdn, where))
|
||||||
return PCIBIOS_BAD_REGISTER_NUMBER;
|
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||||
|
|
||||||
addr = ((where & 0xf00) << 20) | (pdn->busno << 16) |
|
addr = rtas_config_addr(pdn->busno, pdn->devfn, where);
|
||||||
(pdn->devfn << 8) | (where & 0xff);
|
|
||||||
buid = pdn->phb->buid;
|
buid = pdn->phb->buid;
|
||||||
if (buid) {
|
if (buid) {
|
||||||
ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval,
|
ret = rtas_call(ibm_read_pci_config, 4, 2, &returnval,
|
||||||
|
@ -134,8 +133,7 @@ int rtas_write_config(struct pci_dn *pdn, int where, int size, u32 val)
|
||||||
if (!config_access_valid(pdn, where))
|
if (!config_access_valid(pdn, where))
|
||||||
return PCIBIOS_BAD_REGISTER_NUMBER;
|
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||||
|
|
||||||
addr = ((where & 0xf00) << 20) | (pdn->busno << 16) |
|
addr = rtas_config_addr(pdn->busno, pdn->devfn, where);
|
||||||
(pdn->devfn << 8) | (where & 0xff);
|
|
||||||
buid = pdn->phb->buid;
|
buid = pdn->phb->buid;
|
||||||
if (buid) {
|
if (buid) {
|
||||||
ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr,
|
ret = rtas_call(ibm_write_pci_config, 5, 1, NULL, addr,
|
||||||
|
@ -178,7 +176,7 @@ struct pci_ops rtas_pci_ops = {
|
||||||
|
|
||||||
int is_python(struct device_node *dev)
|
int is_python(struct device_node *dev)
|
||||||
{
|
{
|
||||||
char *model = (char *)get_property(dev, "model", NULL);
|
const char *model = get_property(dev, "model", NULL);
|
||||||
|
|
||||||
if (model && strstr(model, "Python"))
|
if (model && strstr(model, "Python"))
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -234,7 +232,7 @@ void __init init_pci_config_tokens (void)
|
||||||
unsigned long __devinit get_phb_buid (struct device_node *phb)
|
unsigned long __devinit get_phb_buid (struct device_node *phb)
|
||||||
{
|
{
|
||||||
int addr_cells;
|
int addr_cells;
|
||||||
unsigned int *buid_vals;
|
const unsigned int *buid_vals;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
unsigned long buid;
|
unsigned long buid;
|
||||||
|
|
||||||
|
@ -247,7 +245,7 @@ unsigned long __devinit get_phb_buid (struct device_node *phb)
|
||||||
if (phb->parent->parent)
|
if (phb->parent->parent)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
buid_vals = (unsigned int *) get_property(phb, "reg", &len);
|
buid_vals = get_property(phb, "reg", &len);
|
||||||
if (buid_vals == NULL)
|
if (buid_vals == NULL)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
@ -264,10 +262,10 @@ unsigned long __devinit get_phb_buid (struct device_node *phb)
|
||||||
static int phb_set_bus_ranges(struct device_node *dev,
|
static int phb_set_bus_ranges(struct device_node *dev,
|
||||||
struct pci_controller *phb)
|
struct pci_controller *phb)
|
||||||
{
|
{
|
||||||
int *bus_range;
|
const int *bus_range;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
|
|
||||||
bus_range = (int *) get_property(dev, "bus-range", &len);
|
bus_range = get_property(dev, "bus-range", &len);
|
||||||
if (bus_range == NULL || len < 2 * sizeof(int)) {
|
if (bus_range == NULL || len < 2 * sizeof(int)) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -325,14 +323,14 @@ unsigned long __init find_and_init_phbs(void)
|
||||||
* in chosen.
|
* in chosen.
|
||||||
*/
|
*/
|
||||||
if (of_chosen) {
|
if (of_chosen) {
|
||||||
int *prop;
|
const int *prop;
|
||||||
|
|
||||||
prop = (int *)get_property(of_chosen, "linux,pci-probe-only",
|
prop = get_property(of_chosen,
|
||||||
NULL);
|
"linux,pci-probe-only", NULL);
|
||||||
if (prop)
|
if (prop)
|
||||||
pci_probe_only = *prop;
|
pci_probe_only = *prop;
|
||||||
|
|
||||||
prop = (int *)get_property(of_chosen,
|
prop = get_property(of_chosen,
|
||||||
"linux,pci-assign-all-buses", NULL);
|
"linux,pci-assign-all-buses", NULL);
|
||||||
if (prop)
|
if (prop)
|
||||||
pci_assign_all_buses = *prop;
|
pci_assign_all_buses = *prop;
|
||||||
|
|
|
@ -304,19 +304,21 @@ struct seq_operations cpuinfo_op = {
|
||||||
void __init check_for_initrd(void)
|
void __init check_for_initrd(void)
|
||||||
{
|
{
|
||||||
#ifdef CONFIG_BLK_DEV_INITRD
|
#ifdef CONFIG_BLK_DEV_INITRD
|
||||||
unsigned long *prop;
|
const unsigned int *prop;
|
||||||
|
int len;
|
||||||
|
|
||||||
DBG(" -> check_for_initrd()\n");
|
DBG(" -> check_for_initrd()\n");
|
||||||
|
|
||||||
if (of_chosen) {
|
if (of_chosen) {
|
||||||
prop = (unsigned long *)get_property(of_chosen,
|
prop = get_property(of_chosen, "linux,initrd-start", &len);
|
||||||
"linux,initrd-start", NULL);
|
|
||||||
if (prop != NULL) {
|
if (prop != NULL) {
|
||||||
initrd_start = (unsigned long)__va(*prop);
|
initrd_start = (unsigned long)
|
||||||
prop = (unsigned long *)get_property(of_chosen,
|
__va(of_read_ulong(prop, len / 4));
|
||||||
"linux,initrd-end", NULL);
|
prop = get_property(of_chosen,
|
||||||
|
"linux,initrd-end", &len);
|
||||||
if (prop != NULL) {
|
if (prop != NULL) {
|
||||||
initrd_end = (unsigned long)__va(*prop);
|
initrd_end = (unsigned long)
|
||||||
|
__va(of_read_ulong(prop, len / 4));
|
||||||
initrd_below_start_ok = 1;
|
initrd_below_start_ok = 1;
|
||||||
} else
|
} else
|
||||||
initrd_start = 0;
|
initrd_start = 0;
|
||||||
|
@ -366,15 +368,14 @@ void __init smp_setup_cpu_maps(void)
|
||||||
int cpu = 0;
|
int cpu = 0;
|
||||||
|
|
||||||
while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) {
|
while ((dn = of_find_node_by_type(dn, "cpu")) && cpu < NR_CPUS) {
|
||||||
int *intserv;
|
const int *intserv;
|
||||||
int j, len = sizeof(u32), nthreads = 1;
|
int j, len = sizeof(u32), nthreads = 1;
|
||||||
|
|
||||||
intserv = (int *)get_property(dn, "ibm,ppc-interrupt-server#s",
|
intserv = get_property(dn, "ibm,ppc-interrupt-server#s", &len);
|
||||||
&len);
|
|
||||||
if (intserv)
|
if (intserv)
|
||||||
nthreads = len / sizeof(int);
|
nthreads = len / sizeof(int);
|
||||||
else {
|
else {
|
||||||
intserv = (int *) get_property(dn, "reg", NULL);
|
intserv = get_property(dn, "reg", NULL);
|
||||||
if (!intserv)
|
if (!intserv)
|
||||||
intserv = &cpu; /* assume logical == phys */
|
intserv = &cpu; /* assume logical == phys */
|
||||||
}
|
}
|
||||||
|
@ -395,13 +396,12 @@ void __init smp_setup_cpu_maps(void)
|
||||||
if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR) &&
|
if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR) &&
|
||||||
(dn = of_find_node_by_path("/rtas"))) {
|
(dn = of_find_node_by_path("/rtas"))) {
|
||||||
int num_addr_cell, num_size_cell, maxcpus;
|
int num_addr_cell, num_size_cell, maxcpus;
|
||||||
unsigned int *ireg;
|
const unsigned int *ireg;
|
||||||
|
|
||||||
num_addr_cell = prom_n_addr_cells(dn);
|
num_addr_cell = prom_n_addr_cells(dn);
|
||||||
num_size_cell = prom_n_size_cells(dn);
|
num_size_cell = prom_n_size_cells(dn);
|
||||||
|
|
||||||
ireg = (unsigned int *)
|
ireg = get_property(dn, "ibm,lrdr-capacity", NULL);
|
||||||
get_property(dn, "ibm,lrdr-capacity", NULL);
|
|
||||||
|
|
||||||
if (!ireg)
|
if (!ireg)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -444,6 +444,8 @@ void __init smp_setup_cpu_maps(void)
|
||||||
|
|
||||||
int __initdata do_early_xmon;
|
int __initdata do_early_xmon;
|
||||||
#ifdef CONFIG_XMON
|
#ifdef CONFIG_XMON
|
||||||
|
extern int xmon_no_auto_backtrace;
|
||||||
|
|
||||||
static int __init early_xmon(char *p)
|
static int __init early_xmon(char *p)
|
||||||
{
|
{
|
||||||
/* ensure xmon is enabled */
|
/* ensure xmon is enabled */
|
||||||
|
@ -452,6 +454,8 @@ static int __init early_xmon(char *p)
|
||||||
xmon_init(1);
|
xmon_init(1);
|
||||||
if (strncmp(p, "off", 3) == 0)
|
if (strncmp(p, "off", 3) == 0)
|
||||||
xmon_init(0);
|
xmon_init(0);
|
||||||
|
if (strncmp(p, "nobt", 4) == 0)
|
||||||
|
xmon_no_auto_backtrace = 1;
|
||||||
if (strncmp(p, "early", 5) != 0)
|
if (strncmp(p, "early", 5) != 0)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,7 +56,6 @@
|
||||||
#include <asm/page.h>
|
#include <asm/page.h>
|
||||||
#include <asm/mmu.h>
|
#include <asm/mmu.h>
|
||||||
#include <asm/lmb.h>
|
#include <asm/lmb.h>
|
||||||
#include <asm/iseries/it_lp_naca.h>
|
|
||||||
#include <asm/firmware.h>
|
#include <asm/firmware.h>
|
||||||
#include <asm/xmon.h>
|
#include <asm/xmon.h>
|
||||||
#include <asm/udbg.h>
|
#include <asm/udbg.h>
|
||||||
|
@ -79,10 +78,10 @@ u64 ppc64_pft_size;
|
||||||
* before we've read this from the device tree.
|
* before we've read this from the device tree.
|
||||||
*/
|
*/
|
||||||
struct ppc64_caches ppc64_caches = {
|
struct ppc64_caches ppc64_caches = {
|
||||||
.dline_size = 0x80,
|
.dline_size = 0x40,
|
||||||
.log_dline_size = 7,
|
.log_dline_size = 6,
|
||||||
.iline_size = 0x80,
|
.iline_size = 0x40,
|
||||||
.log_iline_size = 7
|
.log_iline_size = 6
|
||||||
};
|
};
|
||||||
EXPORT_SYMBOL_GPL(ppc64_caches);
|
EXPORT_SYMBOL_GPL(ppc64_caches);
|
||||||
|
|
||||||
|
@ -107,7 +106,7 @@ static int smt_enabled_cmdline;
|
||||||
static void check_smt_enabled(void)
|
static void check_smt_enabled(void)
|
||||||
{
|
{
|
||||||
struct device_node *dn;
|
struct device_node *dn;
|
||||||
char *smt_option;
|
const char *smt_option;
|
||||||
|
|
||||||
/* Allow the command line to overrule the OF option */
|
/* Allow the command line to overrule the OF option */
|
||||||
if (smt_enabled_cmdline)
|
if (smt_enabled_cmdline)
|
||||||
|
@ -116,7 +115,7 @@ static void check_smt_enabled(void)
|
||||||
dn = of_find_node_by_path("/options");
|
dn = of_find_node_by_path("/options");
|
||||||
|
|
||||||
if (dn) {
|
if (dn) {
|
||||||
smt_option = (char *)get_property(dn, "ibm,smt-enabled", NULL);
|
smt_option = get_property(dn, "ibm,smt-enabled", NULL);
|
||||||
|
|
||||||
if (smt_option) {
|
if (smt_option) {
|
||||||
if (!strcmp(smt_option, "on"))
|
if (!strcmp(smt_option, "on"))
|
||||||
|
@ -293,7 +292,7 @@ static void __init initialize_cache_info(void)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if ( num_cpus == 1 ) {
|
if ( num_cpus == 1 ) {
|
||||||
u32 *sizep, *lsizep;
|
const u32 *sizep, *lsizep;
|
||||||
u32 size, lsize;
|
u32 size, lsize;
|
||||||
const char *dc, *ic;
|
const char *dc, *ic;
|
||||||
|
|
||||||
|
@ -308,10 +307,10 @@ static void __init initialize_cache_info(void)
|
||||||
|
|
||||||
size = 0;
|
size = 0;
|
||||||
lsize = cur_cpu_spec->dcache_bsize;
|
lsize = cur_cpu_spec->dcache_bsize;
|
||||||
sizep = (u32 *)get_property(np, "d-cache-size", NULL);
|
sizep = get_property(np, "d-cache-size", NULL);
|
||||||
if (sizep != NULL)
|
if (sizep != NULL)
|
||||||
size = *sizep;
|
size = *sizep;
|
||||||
lsizep = (u32 *) get_property(np, dc, NULL);
|
lsizep = get_property(np, dc, NULL);
|
||||||
if (lsizep != NULL)
|
if (lsizep != NULL)
|
||||||
lsize = *lsizep;
|
lsize = *lsizep;
|
||||||
if (sizep == 0 || lsizep == 0)
|
if (sizep == 0 || lsizep == 0)
|
||||||
|
@ -325,10 +324,10 @@ static void __init initialize_cache_info(void)
|
||||||
|
|
||||||
size = 0;
|
size = 0;
|
||||||
lsize = cur_cpu_spec->icache_bsize;
|
lsize = cur_cpu_spec->icache_bsize;
|
||||||
sizep = (u32 *)get_property(np, "i-cache-size", NULL);
|
sizep = get_property(np, "i-cache-size", NULL);
|
||||||
if (sizep != NULL)
|
if (sizep != NULL)
|
||||||
size = *sizep;
|
size = *sizep;
|
||||||
lsizep = (u32 *)get_property(np, ic, NULL);
|
lsizep = get_property(np, ic, NULL);
|
||||||
if (lsizep != NULL)
|
if (lsizep != NULL)
|
||||||
lsize = *lsizep;
|
lsize = *lsizep;
|
||||||
if (sizep == 0 || lsizep == 0)
|
if (sizep == 0 || lsizep == 0)
|
||||||
|
|
|
@ -60,7 +60,7 @@ static int smt_snooze_cmdline;
|
||||||
static int __init smt_setup(void)
|
static int __init smt_setup(void)
|
||||||
{
|
{
|
||||||
struct device_node *options;
|
struct device_node *options;
|
||||||
unsigned int *val;
|
const unsigned int *val;
|
||||||
unsigned int cpu;
|
unsigned int cpu;
|
||||||
|
|
||||||
if (!cpu_has_feature(CPU_FTR_SMT))
|
if (!cpu_has_feature(CPU_FTR_SMT))
|
||||||
|
@ -70,8 +70,7 @@ static int __init smt_setup(void)
|
||||||
if (!options)
|
if (!options)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
val = (unsigned int *)get_property(options, "ibm,smt-snooze-delay",
|
val = get_property(options, "ibm,smt-snooze-delay", NULL);
|
||||||
NULL);
|
|
||||||
if (!smt_snooze_cmdline && val) {
|
if (!smt_snooze_cmdline && val) {
|
||||||
for_each_possible_cpu(cpu)
|
for_each_possible_cpu(cpu)
|
||||||
per_cpu(smt_snooze_delay, cpu) = *val;
|
per_cpu(smt_snooze_delay, cpu) = *val;
|
||||||
|
@ -231,7 +230,7 @@ static void register_cpu_online(unsigned int cpu)
|
||||||
if (cur_cpu_spec->num_pmcs >= 8)
|
if (cur_cpu_spec->num_pmcs >= 8)
|
||||||
sysdev_create_file(s, &attr_pmc8);
|
sysdev_create_file(s, &attr_pmc8);
|
||||||
|
|
||||||
if (cpu_has_feature(CPU_FTR_SMT))
|
if (cpu_has_feature(CPU_FTR_PURR))
|
||||||
sysdev_create_file(s, &attr_purr);
|
sysdev_create_file(s, &attr_purr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,7 +272,7 @@ static void unregister_cpu_online(unsigned int cpu)
|
||||||
if (cur_cpu_spec->num_pmcs >= 8)
|
if (cur_cpu_spec->num_pmcs >= 8)
|
||||||
sysdev_remove_file(s, &attr_pmc8);
|
sysdev_remove_file(s, &attr_pmc8);
|
||||||
|
|
||||||
if (cpu_has_feature(CPU_FTR_SMT))
|
if (cpu_has_feature(CPU_FTR_PURR))
|
||||||
sysdev_remove_file(s, &attr_purr);
|
sysdev_remove_file(s, &attr_purr);
|
||||||
}
|
}
|
||||||
#endif /* CONFIG_HOTPLUG_CPU */
|
#endif /* CONFIG_HOTPLUG_CPU */
|
||||||
|
|
|
@ -860,19 +860,17 @@ EXPORT_SYMBOL(do_settimeofday);
|
||||||
static int __init get_freq(char *name, int cells, unsigned long *val)
|
static int __init get_freq(char *name, int cells, unsigned long *val)
|
||||||
{
|
{
|
||||||
struct device_node *cpu;
|
struct device_node *cpu;
|
||||||
unsigned int *fp;
|
const unsigned int *fp;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
|
|
||||||
/* The cpu node should have timebase and clock frequency properties */
|
/* The cpu node should have timebase and clock frequency properties */
|
||||||
cpu = of_find_node_by_type(NULL, "cpu");
|
cpu = of_find_node_by_type(NULL, "cpu");
|
||||||
|
|
||||||
if (cpu) {
|
if (cpu) {
|
||||||
fp = (unsigned int *)get_property(cpu, name, NULL);
|
fp = get_property(cpu, name, NULL);
|
||||||
if (fp) {
|
if (fp) {
|
||||||
found = 1;
|
found = 1;
|
||||||
*val = 0;
|
*val = of_read_ulong(fp, cells);
|
||||||
while (cells--)
|
|
||||||
*val = (*val << 32) | *fp++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
of_node_put(cpu);
|
of_node_put(cpu);
|
||||||
|
|
|
@ -598,6 +598,9 @@ static void parse_fpe(struct pt_regs *regs)
|
||||||
#define INST_STSWI 0x7c0005aa
|
#define INST_STSWI 0x7c0005aa
|
||||||
#define INST_STSWX 0x7c00052a
|
#define INST_STSWX 0x7c00052a
|
||||||
|
|
||||||
|
#define INST_POPCNTB 0x7c0000f4
|
||||||
|
#define INST_POPCNTB_MASK 0xfc0007fe
|
||||||
|
|
||||||
static int emulate_string_inst(struct pt_regs *regs, u32 instword)
|
static int emulate_string_inst(struct pt_regs *regs, u32 instword)
|
||||||
{
|
{
|
||||||
u8 rT = (instword >> 21) & 0x1f;
|
u8 rT = (instword >> 21) & 0x1f;
|
||||||
|
@ -666,6 +669,23 @@ static int emulate_string_inst(struct pt_regs *regs, u32 instword)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int emulate_popcntb_inst(struct pt_regs *regs, u32 instword)
|
||||||
|
{
|
||||||
|
u32 ra,rs;
|
||||||
|
unsigned long tmp;
|
||||||
|
|
||||||
|
ra = (instword >> 16) & 0x1f;
|
||||||
|
rs = (instword >> 21) & 0x1f;
|
||||||
|
|
||||||
|
tmp = regs->gpr[rs];
|
||||||
|
tmp = tmp - ((tmp >> 1) & 0x5555555555555555ULL);
|
||||||
|
tmp = (tmp & 0x3333333333333333ULL) + ((tmp >> 2) & 0x3333333333333333ULL);
|
||||||
|
tmp = (tmp + (tmp >> 4)) & 0x0f0f0f0f0f0f0f0fULL;
|
||||||
|
regs->gpr[ra] = tmp;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int emulate_instruction(struct pt_regs *regs)
|
static int emulate_instruction(struct pt_regs *regs)
|
||||||
{
|
{
|
||||||
u32 instword;
|
u32 instword;
|
||||||
|
@ -703,6 +723,11 @@ static int emulate_instruction(struct pt_regs *regs)
|
||||||
if ((instword & INST_STRING_GEN_MASK) == INST_STRING)
|
if ((instword & INST_STRING_GEN_MASK) == INST_STRING)
|
||||||
return emulate_string_inst(regs, instword);
|
return emulate_string_inst(regs, instword);
|
||||||
|
|
||||||
|
/* Emulate the popcntb (Population Count Bytes) instruction. */
|
||||||
|
if ((instword & INST_POPCNTB_MASK) == INST_POPCNTB) {
|
||||||
|
return emulate_popcntb_inst(regs, instword);
|
||||||
|
}
|
||||||
|
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -77,7 +77,7 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
|
||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
unsigned char *dma_window;
|
const unsigned char *dma_window;
|
||||||
struct iommu_table *tbl;
|
struct iommu_table *tbl;
|
||||||
unsigned long offset, size;
|
unsigned long offset, size;
|
||||||
|
|
||||||
|
@ -217,7 +217,7 @@ static void __devinit vio_dev_release(struct device *dev)
|
||||||
struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
|
struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
|
||||||
{
|
{
|
||||||
struct vio_dev *viodev;
|
struct vio_dev *viodev;
|
||||||
unsigned int *unit_address;
|
const unsigned int *unit_address;
|
||||||
|
|
||||||
/* we need the 'device_type' property, in order to match with drivers */
|
/* we need the 'device_type' property, in order to match with drivers */
|
||||||
if (of_node->type == NULL) {
|
if (of_node->type == NULL) {
|
||||||
|
@ -227,7 +227,7 @@ struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
unit_address = (unsigned int *)get_property(of_node, "reg", NULL);
|
unit_address = get_property(of_node, "reg", NULL);
|
||||||
if (unit_address == NULL) {
|
if (unit_address == NULL) {
|
||||||
printk(KERN_WARNING "%s: node %s missing 'reg'\n",
|
printk(KERN_WARNING "%s: node %s missing 'reg'\n",
|
||||||
__FUNCTION__,
|
__FUNCTION__,
|
||||||
|
@ -249,7 +249,7 @@ struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
|
||||||
viodev->type = of_node->type;
|
viodev->type = of_node->type;
|
||||||
viodev->unit_address = *unit_address;
|
viodev->unit_address = *unit_address;
|
||||||
if (firmware_has_feature(FW_FEATURE_ISERIES)) {
|
if (firmware_has_feature(FW_FEATURE_ISERIES)) {
|
||||||
unit_address = (unsigned int *)get_property(of_node,
|
unit_address = get_property(of_node,
|
||||||
"linux,unit_address", NULL);
|
"linux,unit_address", NULL);
|
||||||
if (unit_address != NULL)
|
if (unit_address != NULL)
|
||||||
viodev->unit_address = *unit_address;
|
viodev->unit_address = *unit_address;
|
||||||
|
@ -423,7 +423,7 @@ static int vio_hotplug(struct device *dev, char **envp, int num_envp,
|
||||||
{
|
{
|
||||||
const struct vio_dev *vio_dev = to_vio_dev(dev);
|
const struct vio_dev *vio_dev = to_vio_dev(dev);
|
||||||
struct device_node *dn = dev->platform_data;
|
struct device_node *dn = dev->platform_data;
|
||||||
char *cp;
|
const char *cp;
|
||||||
int length;
|
int length;
|
||||||
|
|
||||||
if (!num_envp)
|
if (!num_envp)
|
||||||
|
@ -431,7 +431,7 @@ static int vio_hotplug(struct device *dev, char **envp, int num_envp,
|
||||||
|
|
||||||
if (!dn)
|
if (!dn)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
cp = (char *)get_property(dn, "compatible", &length);
|
cp = get_property(dn, "compatible", &length);
|
||||||
if (!cp)
|
if (!cp)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
|
@ -493,11 +493,11 @@ static struct vio_dev *vio_find_name(const char *kobj_name)
|
||||||
*/
|
*/
|
||||||
struct vio_dev *vio_find_node(struct device_node *vnode)
|
struct vio_dev *vio_find_node(struct device_node *vnode)
|
||||||
{
|
{
|
||||||
uint32_t *unit_address;
|
const uint32_t *unit_address;
|
||||||
char kobj_name[BUS_ID_SIZE];
|
char kobj_name[BUS_ID_SIZE];
|
||||||
|
|
||||||
/* construct the kobject name from the device node */
|
/* construct the kobject name from the device node */
|
||||||
unit_address = (uint32_t *)get_property(vnode, "reg", NULL);
|
unit_address = get_property(vnode, "reg", NULL);
|
||||||
if (!unit_address)
|
if (!unit_address)
|
||||||
return NULL;
|
return NULL;
|
||||||
snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address);
|
snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address);
|
||||||
|
|
|
@ -14,7 +14,6 @@ endif
|
||||||
obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \
|
obj-$(CONFIG_PPC64) += checksum_64.o copypage_64.o copyuser_64.o \
|
||||||
memcpy_64.o usercopy_64.o mem_64.o string.o \
|
memcpy_64.o usercopy_64.o mem_64.o string.o \
|
||||||
strcase.o
|
strcase.o
|
||||||
obj-$(CONFIG_PPC_ISERIES) += e2a.o
|
|
||||||
obj-$(CONFIG_XMON) += sstep.o
|
obj-$(CONFIG_XMON) += sstep.o
|
||||||
|
|
||||||
ifeq ($(CONFIG_PPC64),y)
|
ifeq ($(CONFIG_PPC64),y)
|
||||||
|
|
|
@ -1,116 +0,0 @@
|
||||||
/*
|
|
||||||
* EBCDIC to ASCII conversion
|
|
||||||
*
|
|
||||||
* This function moved here from arch/powerpc/platforms/iseries/viopath.c
|
|
||||||
*
|
|
||||||
* (C) Copyright 2000-2004 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) anyu 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
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <linux/module.h>
|
|
||||||
|
|
||||||
unsigned char e2a(unsigned char x)
|
|
||||||
{
|
|
||||||
switch (x) {
|
|
||||||
case 0xF0:
|
|
||||||
return '0';
|
|
||||||
case 0xF1:
|
|
||||||
return '1';
|
|
||||||
case 0xF2:
|
|
||||||
return '2';
|
|
||||||
case 0xF3:
|
|
||||||
return '3';
|
|
||||||
case 0xF4:
|
|
||||||
return '4';
|
|
||||||
case 0xF5:
|
|
||||||
return '5';
|
|
||||||
case 0xF6:
|
|
||||||
return '6';
|
|
||||||
case 0xF7:
|
|
||||||
return '7';
|
|
||||||
case 0xF8:
|
|
||||||
return '8';
|
|
||||||
case 0xF9:
|
|
||||||
return '9';
|
|
||||||
case 0xC1:
|
|
||||||
return 'A';
|
|
||||||
case 0xC2:
|
|
||||||
return 'B';
|
|
||||||
case 0xC3:
|
|
||||||
return 'C';
|
|
||||||
case 0xC4:
|
|
||||||
return 'D';
|
|
||||||
case 0xC5:
|
|
||||||
return 'E';
|
|
||||||
case 0xC6:
|
|
||||||
return 'F';
|
|
||||||
case 0xC7:
|
|
||||||
return 'G';
|
|
||||||
case 0xC8:
|
|
||||||
return 'H';
|
|
||||||
case 0xC9:
|
|
||||||
return 'I';
|
|
||||||
case 0xD1:
|
|
||||||
return 'J';
|
|
||||||
case 0xD2:
|
|
||||||
return 'K';
|
|
||||||
case 0xD3:
|
|
||||||
return 'L';
|
|
||||||
case 0xD4:
|
|
||||||
return 'M';
|
|
||||||
case 0xD5:
|
|
||||||
return 'N';
|
|
||||||
case 0xD6:
|
|
||||||
return 'O';
|
|
||||||
case 0xD7:
|
|
||||||
return 'P';
|
|
||||||
case 0xD8:
|
|
||||||
return 'Q';
|
|
||||||
case 0xD9:
|
|
||||||
return 'R';
|
|
||||||
case 0xE2:
|
|
||||||
return 'S';
|
|
||||||
case 0xE3:
|
|
||||||
return 'T';
|
|
||||||
case 0xE4:
|
|
||||||
return 'U';
|
|
||||||
case 0xE5:
|
|
||||||
return 'V';
|
|
||||||
case 0xE6:
|
|
||||||
return 'W';
|
|
||||||
case 0xE7:
|
|
||||||
return 'X';
|
|
||||||
case 0xE8:
|
|
||||||
return 'Y';
|
|
||||||
case 0xE9:
|
|
||||||
return 'Z';
|
|
||||||
}
|
|
||||||
return ' ';
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(e2a);
|
|
||||||
|
|
||||||
unsigned char* strne2a(unsigned char *dest, const unsigned char *src, size_t n)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
n = strnlen(src, n);
|
|
||||||
|
|
||||||
for (i = 0; i < n; i++)
|
|
||||||
dest[i] = e2a(src[i]);
|
|
||||||
|
|
||||||
return dest;
|
|
||||||
}
|
|
|
@ -23,6 +23,7 @@
|
||||||
#include <asm/hvcall.h>
|
#include <asm/hvcall.h>
|
||||||
#include <asm/iseries/hv_call.h>
|
#include <asm/iseries/hv_call.h>
|
||||||
#include <asm/smp.h>
|
#include <asm/smp.h>
|
||||||
|
#include <asm/firmware.h>
|
||||||
|
|
||||||
void __spin_yield(raw_spinlock_t *lock)
|
void __spin_yield(raw_spinlock_t *lock)
|
||||||
{
|
{
|
||||||
|
@ -39,13 +40,12 @@ void __spin_yield(raw_spinlock_t *lock)
|
||||||
rmb();
|
rmb();
|
||||||
if (lock->slock != lock_value)
|
if (lock->slock != lock_value)
|
||||||
return; /* something has changed */
|
return; /* something has changed */
|
||||||
#ifdef CONFIG_PPC_ISERIES
|
if (firmware_has_feature(FW_FEATURE_ISERIES))
|
||||||
HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc,
|
HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc,
|
||||||
((u64)holder_cpu << 32) | yield_count);
|
((u64)holder_cpu << 32) | yield_count);
|
||||||
#else
|
else
|
||||||
plpar_hcall_norets(H_CONFER, get_hard_smp_processor_id(holder_cpu),
|
plpar_hcall_norets(H_CONFER,
|
||||||
yield_count);
|
get_hard_smp_processor_id(holder_cpu), yield_count);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -69,13 +69,12 @@ void __rw_yield(raw_rwlock_t *rw)
|
||||||
rmb();
|
rmb();
|
||||||
if (rw->lock != lock_value)
|
if (rw->lock != lock_value)
|
||||||
return; /* something has changed */
|
return; /* something has changed */
|
||||||
#ifdef CONFIG_PPC_ISERIES
|
if (firmware_has_feature(FW_FEATURE_ISERIES))
|
||||||
HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc,
|
HvCall2(HvCallBaseYieldProcessor, HvCall_YieldToProc,
|
||||||
((u64)holder_cpu << 32) | yield_count);
|
((u64)holder_cpu << 32) | yield_count);
|
||||||
#else
|
else
|
||||||
plpar_hcall_norets(H_CONFER, get_hard_smp_processor_id(holder_cpu),
|
plpar_hcall_norets(H_CONFER,
|
||||||
yield_count);
|
get_hard_smp_processor_id(holder_cpu), yield_count);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -159,12 +159,12 @@ static struct device_node * __cpuinit find_cpu_node(unsigned int cpu)
|
||||||
{
|
{
|
||||||
unsigned int hw_cpuid = get_hard_smp_processor_id(cpu);
|
unsigned int hw_cpuid = get_hard_smp_processor_id(cpu);
|
||||||
struct device_node *cpu_node = NULL;
|
struct device_node *cpu_node = NULL;
|
||||||
unsigned int *interrupt_server, *reg;
|
const unsigned int *interrupt_server, *reg;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
while ((cpu_node = of_find_node_by_type(cpu_node, "cpu")) != NULL) {
|
while ((cpu_node = of_find_node_by_type(cpu_node, "cpu")) != NULL) {
|
||||||
/* Try interrupt server first */
|
/* Try interrupt server first */
|
||||||
interrupt_server = (unsigned int *)get_property(cpu_node,
|
interrupt_server = get_property(cpu_node,
|
||||||
"ibm,ppc-interrupt-server#s", &len);
|
"ibm,ppc-interrupt-server#s", &len);
|
||||||
|
|
||||||
len = len / sizeof(u32);
|
len = len / sizeof(u32);
|
||||||
|
@ -175,8 +175,7 @@ static struct device_node * __cpuinit find_cpu_node(unsigned int cpu)
|
||||||
return cpu_node;
|
return cpu_node;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
reg = (unsigned int *)get_property(cpu_node,
|
reg = get_property(cpu_node, "reg", &len);
|
||||||
"reg", &len);
|
|
||||||
if (reg && (len > 0) && (reg[0] == hw_cpuid))
|
if (reg && (len > 0) && (reg[0] == hw_cpuid))
|
||||||
return cpu_node;
|
return cpu_node;
|
||||||
}
|
}
|
||||||
|
@ -186,9 +185,9 @@ static struct device_node * __cpuinit find_cpu_node(unsigned int cpu)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* must hold reference to node during call */
|
/* must hold reference to node during call */
|
||||||
static int *of_get_associativity(struct device_node *dev)
|
static const int *of_get_associativity(struct device_node *dev)
|
||||||
{
|
{
|
||||||
return (unsigned int *)get_property(dev, "ibm,associativity", NULL);
|
return get_property(dev, "ibm,associativity", NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa
|
/* Returns nid in the range [0..MAX_NUMNODES-1], or -1 if no useful numa
|
||||||
|
@ -197,7 +196,7 @@ static int *of_get_associativity(struct device_node *dev)
|
||||||
static int of_node_to_nid_single(struct device_node *device)
|
static int of_node_to_nid_single(struct device_node *device)
|
||||||
{
|
{
|
||||||
int nid = -1;
|
int nid = -1;
|
||||||
unsigned int *tmp;
|
const unsigned int *tmp;
|
||||||
|
|
||||||
if (min_common_depth == -1)
|
if (min_common_depth == -1)
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -255,7 +254,7 @@ EXPORT_SYMBOL_GPL(of_node_to_nid);
|
||||||
static int __init find_min_common_depth(void)
|
static int __init find_min_common_depth(void)
|
||||||
{
|
{
|
||||||
int depth;
|
int depth;
|
||||||
unsigned int *ref_points;
|
const unsigned int *ref_points;
|
||||||
struct device_node *rtas_root;
|
struct device_node *rtas_root;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
|
|
||||||
|
@ -270,7 +269,7 @@ static int __init find_min_common_depth(void)
|
||||||
* configuration (should be all 0's) and the second is for a normal
|
* configuration (should be all 0's) and the second is for a normal
|
||||||
* NUMA configuration.
|
* NUMA configuration.
|
||||||
*/
|
*/
|
||||||
ref_points = (unsigned int *)get_property(rtas_root,
|
ref_points = get_property(rtas_root,
|
||||||
"ibm,associativity-reference-points", &len);
|
"ibm,associativity-reference-points", &len);
|
||||||
|
|
||||||
if ((len >= 1) && ref_points) {
|
if ((len >= 1) && ref_points) {
|
||||||
|
@ -297,7 +296,7 @@ static void __init get_n_mem_cells(int *n_addr_cells, int *n_size_cells)
|
||||||
of_node_put(memory);
|
of_node_put(memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned long __devinit read_n_cells(int n, unsigned int **buf)
|
static unsigned long __devinit read_n_cells(int n, const unsigned int **buf)
|
||||||
{
|
{
|
||||||
unsigned long result = 0;
|
unsigned long result = 0;
|
||||||
|
|
||||||
|
@ -435,15 +434,13 @@ static int __init parse_numa_properties(void)
|
||||||
unsigned long size;
|
unsigned long size;
|
||||||
int nid;
|
int nid;
|
||||||
int ranges;
|
int ranges;
|
||||||
unsigned int *memcell_buf;
|
const unsigned int *memcell_buf;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
|
|
||||||
memcell_buf = (unsigned int *)get_property(memory,
|
memcell_buf = get_property(memory,
|
||||||
"linux,usable-memory", &len);
|
"linux,usable-memory", &len);
|
||||||
if (!memcell_buf || len <= 0)
|
if (!memcell_buf || len <= 0)
|
||||||
memcell_buf =
|
memcell_buf = get_property(memory, "reg", &len);
|
||||||
(unsigned int *)get_property(memory, "reg",
|
|
||||||
&len);
|
|
||||||
if (!memcell_buf || len <= 0)
|
if (!memcell_buf || len <= 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
@ -787,10 +784,10 @@ int hot_add_scn_to_nid(unsigned long scn_addr)
|
||||||
while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
|
while ((memory = of_find_node_by_type(memory, "memory")) != NULL) {
|
||||||
unsigned long start, size;
|
unsigned long start, size;
|
||||||
int ranges;
|
int ranges;
|
||||||
unsigned int *memcell_buf;
|
const unsigned int *memcell_buf;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
|
|
||||||
memcell_buf = (unsigned int *)get_property(memory, "reg", &len);
|
memcell_buf = get_property(memory, "reg", &len);
|
||||||
if (!memcell_buf || len <= 0)
|
if (!memcell_buf || len <= 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
#include <asm/paca.h>
|
#include <asm/paca.h>
|
||||||
#include <asm/cputable.h>
|
#include <asm/cputable.h>
|
||||||
#include <asm/cacheflush.h>
|
#include <asm/cacheflush.h>
|
||||||
|
#include <asm/smp.h>
|
||||||
|
#include <linux/compiler.h>
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#define DBG(fmt...) udbg_printf(fmt)
|
#define DBG(fmt...) udbg_printf(fmt)
|
||||||
|
@ -50,9 +52,32 @@ static inline unsigned long mk_vsid_data(unsigned long ea, unsigned long flags)
|
||||||
return (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | flags;
|
return (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void create_slbe(unsigned long ea, unsigned long flags,
|
static inline void slb_shadow_update(unsigned long esid, unsigned long vsid,
|
||||||
unsigned long entry)
|
unsigned long entry)
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
|
* Clear the ESID first so the entry is not valid while we are
|
||||||
|
* updating it.
|
||||||
|
*/
|
||||||
|
get_slb_shadow()->save_area[entry].esid = 0;
|
||||||
|
barrier();
|
||||||
|
get_slb_shadow()->save_area[entry].vsid = vsid;
|
||||||
|
barrier();
|
||||||
|
get_slb_shadow()->save_area[entry].esid = esid;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void create_shadowed_slbe(unsigned long ea, unsigned long flags,
|
||||||
|
unsigned long entry)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Updating the shadow buffer before writing the SLB ensures
|
||||||
|
* we don't get a stale entry here if we get preempted by PHYP
|
||||||
|
* between these two statements.
|
||||||
|
*/
|
||||||
|
slb_shadow_update(mk_esid_data(ea, entry), mk_vsid_data(ea, flags),
|
||||||
|
entry);
|
||||||
|
|
||||||
asm volatile("slbmte %0,%1" :
|
asm volatile("slbmte %0,%1" :
|
||||||
: "r" (mk_vsid_data(ea, flags)),
|
: "r" (mk_vsid_data(ea, flags)),
|
||||||
"r" (mk_esid_data(ea, entry))
|
"r" (mk_esid_data(ea, entry))
|
||||||
|
@ -77,6 +102,10 @@ void slb_flush_and_rebolt(void)
|
||||||
if ((ksp_esid_data & ESID_MASK) == PAGE_OFFSET)
|
if ((ksp_esid_data & ESID_MASK) == PAGE_OFFSET)
|
||||||
ksp_esid_data &= ~SLB_ESID_V;
|
ksp_esid_data &= ~SLB_ESID_V;
|
||||||
|
|
||||||
|
/* Only third entry (stack) may change here so only resave that */
|
||||||
|
slb_shadow_update(ksp_esid_data,
|
||||||
|
mk_vsid_data(ksp_esid_data, lflags), 2);
|
||||||
|
|
||||||
/* We need to do this all in asm, so we're sure we don't touch
|
/* We need to do this all in asm, so we're sure we don't touch
|
||||||
* the stack between the slbia and rebolting it. */
|
* the stack between the slbia and rebolting it. */
|
||||||
asm volatile("isync\n"
|
asm volatile("isync\n"
|
||||||
|
@ -209,9 +238,9 @@ void slb_initialize(void)
|
||||||
asm volatile("isync":::"memory");
|
asm volatile("isync":::"memory");
|
||||||
asm volatile("slbmte %0,%0"::"r" (0) : "memory");
|
asm volatile("slbmte %0,%0"::"r" (0) : "memory");
|
||||||
asm volatile("isync; slbia; isync":::"memory");
|
asm volatile("isync; slbia; isync":::"memory");
|
||||||
create_slbe(PAGE_OFFSET, lflags, 0);
|
create_shadowed_slbe(PAGE_OFFSET, lflags, 0);
|
||||||
|
|
||||||
create_slbe(VMALLOC_START, vflags, 1);
|
create_shadowed_slbe(VMALLOC_START, vflags, 1);
|
||||||
|
|
||||||
/* We don't bolt the stack for the time being - we're in boot,
|
/* We don't bolt the stack for the time being - we're in boot,
|
||||||
* so the stack is in the bolted segment. By the time it goes
|
* so the stack is in the bolted segment. By the time it goes
|
||||||
|
|
|
@ -146,6 +146,7 @@ void hpte_update(struct mm_struct *mm, unsigned long addr,
|
||||||
psize = mmu_huge_psize;
|
psize = mmu_huge_psize;
|
||||||
#else
|
#else
|
||||||
BUG();
|
BUG();
|
||||||
|
psize = pte_pagesize_index(pte); /* shutup gcc */
|
||||||
#endif
|
#endif
|
||||||
} else
|
} else
|
||||||
psize = pte_pagesize_index(pte);
|
psize = pte_pagesize_index(pte);
|
||||||
|
|
|
@ -60,8 +60,8 @@ static void __init mpc834x_itx_setup_arch(void)
|
||||||
|
|
||||||
np = of_find_node_by_type(NULL, "cpu");
|
np = of_find_node_by_type(NULL, "cpu");
|
||||||
if (np != 0) {
|
if (np != 0) {
|
||||||
unsigned int *fp =
|
const unsigned int *fp =
|
||||||
(int *)get_property(np, "clock-frequency", NULL);
|
get_property(np, "clock-frequency", NULL);
|
||||||
if (fp != 0)
|
if (fp != 0)
|
||||||
loops_per_jiffy = *fp / HZ;
|
loops_per_jiffy = *fp / HZ;
|
||||||
else
|
else
|
||||||
|
|
|
@ -57,8 +57,8 @@ static void __init mpc834x_sys_setup_arch(void)
|
||||||
|
|
||||||
np = of_find_node_by_type(NULL, "cpu");
|
np = of_find_node_by_type(NULL, "cpu");
|
||||||
if (np != 0) {
|
if (np != 0) {
|
||||||
unsigned int *fp =
|
const unsigned int *fp =
|
||||||
(int *)get_property(np, "clock-frequency", NULL);
|
get_property(np, "clock-frequency", NULL);
|
||||||
if (fp != 0)
|
if (fp != 0)
|
||||||
loops_per_jiffy = *fp / HZ;
|
loops_per_jiffy = *fp / HZ;
|
||||||
else
|
else
|
||||||
|
|
|
@ -59,7 +59,7 @@ int __init add_bridge(struct device_node *dev)
|
||||||
int len;
|
int len;
|
||||||
struct pci_controller *hose;
|
struct pci_controller *hose;
|
||||||
struct resource rsrc;
|
struct resource rsrc;
|
||||||
int *bus_range;
|
const int *bus_range;
|
||||||
int primary = 1, has_address = 0;
|
int primary = 1, has_address = 0;
|
||||||
phys_addr_t immr = get_immrbase();
|
phys_addr_t immr = get_immrbase();
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ int __init add_bridge(struct device_node *dev)
|
||||||
has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
|
has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
|
||||||
|
|
||||||
/* Get bus range if any */
|
/* Get bus range if any */
|
||||||
bus_range = (int *)get_property(dev, "bus-range", &len);
|
bus_range = get_property(dev, "bus-range", &len);
|
||||||
if (bus_range == NULL || len < 2 * sizeof(int)) {
|
if (bus_range == NULL || len < 2 * sizeof(int)) {
|
||||||
printk(KERN_WARNING "Can't get bus-range for %s, assume"
|
printk(KERN_WARNING "Can't get bus-range for %s, assume"
|
||||||
" bus 0\n", dev->full_name);
|
" bus 0\n", dev->full_name);
|
||||||
|
|
|
@ -121,9 +121,9 @@ static void __init mpc85xx_ads_setup_arch(void)
|
||||||
|
|
||||||
cpu = of_find_node_by_type(NULL, "cpu");
|
cpu = of_find_node_by_type(NULL, "cpu");
|
||||||
if (cpu != 0) {
|
if (cpu != 0) {
|
||||||
unsigned int *fp;
|
const unsigned int *fp;
|
||||||
|
|
||||||
fp = (int *)get_property(cpu, "clock-frequency", NULL);
|
fp = get_property(cpu, "clock-frequency", NULL);
|
||||||
if (fp != 0)
|
if (fp != 0)
|
||||||
loops_per_jiffy = *fp / HZ;
|
loops_per_jiffy = *fp / HZ;
|
||||||
else
|
else
|
||||||
|
|
|
@ -241,9 +241,9 @@ mpc85xx_cds_setup_arch(void)
|
||||||
|
|
||||||
cpu = of_find_node_by_type(NULL, "cpu");
|
cpu = of_find_node_by_type(NULL, "cpu");
|
||||||
if (cpu != 0) {
|
if (cpu != 0) {
|
||||||
unsigned int *fp;
|
const unsigned int *fp;
|
||||||
|
|
||||||
fp = (int *)get_property(cpu, "clock-frequency", NULL);
|
fp = get_property(cpu, "clock-frequency", NULL);
|
||||||
if (fp != 0)
|
if (fp != 0)
|
||||||
loops_per_jiffy = *fp / HZ;
|
loops_per_jiffy = *fp / HZ;
|
||||||
else
|
else
|
||||||
|
|
|
@ -41,7 +41,7 @@ int __init add_bridge(struct device_node *dev)
|
||||||
int len;
|
int len;
|
||||||
struct pci_controller *hose;
|
struct pci_controller *hose;
|
||||||
struct resource rsrc;
|
struct resource rsrc;
|
||||||
int *bus_range;
|
const int *bus_range;
|
||||||
int primary = 1, has_address = 0;
|
int primary = 1, has_address = 0;
|
||||||
phys_addr_t immr = get_immrbase();
|
phys_addr_t immr = get_immrbase();
|
||||||
|
|
||||||
|
@ -51,7 +51,7 @@ int __init add_bridge(struct device_node *dev)
|
||||||
has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
|
has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
|
||||||
|
|
||||||
/* Get bus range if any */
|
/* Get bus range if any */
|
||||||
bus_range = (int *) get_property(dev, "bus-range", &len);
|
bus_range = get_property(dev, "bus-range", &len);
|
||||||
if (bus_range == NULL || len < 2 * sizeof(int)) {
|
if (bus_range == NULL || len < 2 * sizeof(int)) {
|
||||||
printk(KERN_WARNING "Can't get bus-range for %s, assume"
|
printk(KERN_WARNING "Can't get bus-range for %s, assume"
|
||||||
" bus 0\n", dev->full_name);
|
" bus 0\n", dev->full_name);
|
||||||
|
|
|
@ -347,9 +347,9 @@ mpc86xx_hpcn_setup_arch(void)
|
||||||
|
|
||||||
np = of_find_node_by_type(NULL, "cpu");
|
np = of_find_node_by_type(NULL, "cpu");
|
||||||
if (np != 0) {
|
if (np != 0) {
|
||||||
unsigned int *fp;
|
const unsigned int *fp;
|
||||||
|
|
||||||
fp = (int *)get_property(np, "clock-frequency", NULL);
|
fp = get_property(np, "clock-frequency", NULL);
|
||||||
if (fp != 0)
|
if (fp != 0)
|
||||||
loops_per_jiffy = *fp / HZ;
|
loops_per_jiffy = *fp / HZ;
|
||||||
else
|
else
|
||||||
|
|
|
@ -153,7 +153,7 @@ int __init add_bridge(struct device_node *dev)
|
||||||
int len;
|
int len;
|
||||||
struct pci_controller *hose;
|
struct pci_controller *hose;
|
||||||
struct resource rsrc;
|
struct resource rsrc;
|
||||||
int *bus_range;
|
const int *bus_range;
|
||||||
int has_address = 0;
|
int has_address = 0;
|
||||||
int primary = 0;
|
int primary = 0;
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ int __init add_bridge(struct device_node *dev)
|
||||||
has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
|
has_address = (of_address_to_resource(dev, 0, &rsrc) == 0);
|
||||||
|
|
||||||
/* Get bus range if any */
|
/* Get bus range if any */
|
||||||
bus_range = (int *) get_property(dev, "bus-range", &len);
|
bus_range = get_property(dev, "bus-range", &len);
|
||||||
if (bus_range == NULL || len < 2 * sizeof(int))
|
if (bus_range == NULL || len < 2 * sizeof(int))
|
||||||
printk(KERN_WARNING "Can't get bus-range for %s, assume"
|
printk(KERN_WARNING "Can't get bus-range for %s, assume"
|
||||||
" bus 0\n", dev->full_name);
|
" bus 0\n", dev->full_name);
|
||||||
|
|
|
@ -13,5 +13,6 @@ obj-$(CONFIG_PPC_86xx) += 86xx/
|
||||||
obj-$(CONFIG_PPC_PSERIES) += pseries/
|
obj-$(CONFIG_PPC_PSERIES) += pseries/
|
||||||
obj-$(CONFIG_PPC_ISERIES) += iseries/
|
obj-$(CONFIG_PPC_ISERIES) += iseries/
|
||||||
obj-$(CONFIG_PPC_MAPLE) += maple/
|
obj-$(CONFIG_PPC_MAPLE) += maple/
|
||||||
|
obj-$(CONFIG_PPC_PASEMI) += pasemi/
|
||||||
obj-$(CONFIG_PPC_CELL) += cell/
|
obj-$(CONFIG_PPC_CELL) += cell/
|
||||||
obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/
|
obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/
|
||||||
|
|
|
@ -97,7 +97,7 @@ void __init cbe_regs_init(void)
|
||||||
struct cbe_regs_map *map = &cbe_regs_maps[cbe_regs_map_count++];
|
struct cbe_regs_map *map = &cbe_regs_maps[cbe_regs_map_count++];
|
||||||
|
|
||||||
/* That hack must die die die ! */
|
/* That hack must die die die ! */
|
||||||
struct address_prop {
|
const struct address_prop {
|
||||||
unsigned long address;
|
unsigned long address;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
} __attribute__((packed)) *prop;
|
} __attribute__((packed)) *prop;
|
||||||
|
@ -114,13 +114,11 @@ void __init cbe_regs_init(void)
|
||||||
if (cbe_thread_map[i].cpu_node == cpu)
|
if (cbe_thread_map[i].cpu_node == cpu)
|
||||||
cbe_thread_map[i].regs = map;
|
cbe_thread_map[i].regs = map;
|
||||||
|
|
||||||
prop = (struct address_prop *)get_property(cpu, "pervasive",
|
prop = get_property(cpu, "pervasive", NULL);
|
||||||
NULL);
|
|
||||||
if (prop != NULL)
|
if (prop != NULL)
|
||||||
map->pmd_regs = ioremap(prop->address, prop->len);
|
map->pmd_regs = ioremap(prop->address, prop->len);
|
||||||
|
|
||||||
prop = (struct address_prop *)get_property(cpu, "iic",
|
prop = get_property(cpu, "iic", NULL);
|
||||||
NULL);
|
|
||||||
if (prop != NULL)
|
if (prop != NULL)
|
||||||
map->iic_regs = ioremap(prop->address, prop->len);
|
map->iic_regs = ioremap(prop->address, prop->len);
|
||||||
}
|
}
|
||||||
|
|
|
@ -250,15 +250,14 @@ static int __init setup_iic(void)
|
||||||
struct resource r0, r1;
|
struct resource r0, r1;
|
||||||
struct irq_host *host;
|
struct irq_host *host;
|
||||||
int found = 0;
|
int found = 0;
|
||||||
u32 *np;
|
const u32 *np;
|
||||||
|
|
||||||
for (dn = NULL;
|
for (dn = NULL;
|
||||||
(dn = of_find_node_by_name(dn,"interrupt-controller")) != NULL;) {
|
(dn = of_find_node_by_name(dn,"interrupt-controller")) != NULL;) {
|
||||||
if (!device_is_compatible(dn,
|
if (!device_is_compatible(dn,
|
||||||
"IBM,CBEA-Internal-Interrupt-Controller"))
|
"IBM,CBEA-Internal-Interrupt-Controller"))
|
||||||
continue;
|
continue;
|
||||||
np = (u32 *)get_property(dn, "ibm,interrupt-server-ranges",
|
np = get_property(dn, "ibm,interrupt-server-ranges", NULL);
|
||||||
NULL);
|
|
||||||
if (np == NULL) {
|
if (np == NULL) {
|
||||||
printk(KERN_WARNING "IIC: CPU association not found\n");
|
printk(KERN_WARNING "IIC: CPU association not found\n");
|
||||||
of_node_put(dn);
|
of_node_put(dn);
|
||||||
|
|
|
@ -308,15 +308,16 @@ static void cell_do_map_iommu(struct cell_iommu *iommu,
|
||||||
|
|
||||||
static void iommu_devnode_setup(struct device_node *d)
|
static void iommu_devnode_setup(struct device_node *d)
|
||||||
{
|
{
|
||||||
unsigned int *ioid;
|
const unsigned int *ioid;
|
||||||
unsigned long *dma_window, map_start, map_size, token;
|
unsigned long map_start, map_size, token;
|
||||||
|
const unsigned long *dma_window;
|
||||||
struct cell_iommu *iommu;
|
struct cell_iommu *iommu;
|
||||||
|
|
||||||
ioid = (unsigned int *)get_property(d, "ioid", NULL);
|
ioid = get_property(d, "ioid", NULL);
|
||||||
if (!ioid)
|
if (!ioid)
|
||||||
pr_debug("No ioid entry found !\n");
|
pr_debug("No ioid entry found !\n");
|
||||||
|
|
||||||
dma_window = (unsigned long *)get_property(d, "ibm,dma-window", NULL);
|
dma_window = get_property(d, "ibm,dma-window", NULL);
|
||||||
if (!dma_window)
|
if (!dma_window)
|
||||||
pr_debug("No ibm,dma-window entry found !\n");
|
pr_debug("No ibm,dma-window entry found !\n");
|
||||||
|
|
||||||
|
@ -371,8 +372,9 @@ static int cell_map_iommu_hardcoded(int num_nodes)
|
||||||
|
|
||||||
static int cell_map_iommu(void)
|
static int cell_map_iommu(void)
|
||||||
{
|
{
|
||||||
unsigned int num_nodes = 0, *node_id;
|
unsigned int num_nodes = 0;
|
||||||
unsigned long *base, *mmio_base;
|
const unsigned int *node_id;
|
||||||
|
const unsigned long *base, *mmio_base;
|
||||||
struct device_node *dn;
|
struct device_node *dn;
|
||||||
struct cell_iommu *iommu = NULL;
|
struct cell_iommu *iommu = NULL;
|
||||||
|
|
||||||
|
@ -381,7 +383,7 @@ static int cell_map_iommu(void)
|
||||||
for(dn = of_find_node_by_type(NULL, "cpu");
|
for(dn = of_find_node_by_type(NULL, "cpu");
|
||||||
dn;
|
dn;
|
||||||
dn = of_find_node_by_type(dn, "cpu")) {
|
dn = of_find_node_by_type(dn, "cpu")) {
|
||||||
node_id = (unsigned int *)get_property(dn, "node-id", NULL);
|
node_id = get_property(dn, "node-id", NULL);
|
||||||
|
|
||||||
if (num_nodes < *node_id)
|
if (num_nodes < *node_id)
|
||||||
num_nodes = *node_id;
|
num_nodes = *node_id;
|
||||||
|
@ -396,9 +398,9 @@ static int cell_map_iommu(void)
|
||||||
dn;
|
dn;
|
||||||
dn = of_find_node_by_type(dn, "cpu")) {
|
dn = of_find_node_by_type(dn, "cpu")) {
|
||||||
|
|
||||||
node_id = (unsigned int *)get_property(dn, "node-id", NULL);
|
node_id = get_property(dn, "node-id", NULL);
|
||||||
base = (unsigned long *)get_property(dn, "ioc-cache", NULL);
|
base = get_property(dn, "ioc-cache", NULL);
|
||||||
mmio_base = (unsigned long *)get_property(dn, "ioc-translation", NULL);
|
mmio_base = get_property(dn, "ioc-translation", NULL);
|
||||||
|
|
||||||
if (!base || !mmio_base || !node_id)
|
if (!base || !mmio_base || !node_id)
|
||||||
return cell_map_iommu_hardcoded(num_nodes);
|
return cell_map_iommu_hardcoded(num_nodes);
|
||||||
|
|
|
@ -150,10 +150,6 @@ static int __init cell_probe(void)
|
||||||
!of_flat_dt_is_compatible(root, "IBM,CPBW-1.0"))
|
!of_flat_dt_is_compatible(root, "IBM,CPBW-1.0"))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#ifdef CONFIG_UDBG_RTAS_CONSOLE
|
|
||||||
udbg_init_rtas_console();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
hpte_init_native();
|
hpte_init_native();
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
|
@ -57,7 +57,7 @@
|
||||||
*/
|
*/
|
||||||
static cpumask_t of_spin_map;
|
static cpumask_t of_spin_map;
|
||||||
|
|
||||||
extern void pSeries_secondary_smp_init(unsigned long);
|
extern void generic_secondary_smp_init(unsigned long);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* smp_startup_cpu() - start the given cpu
|
* smp_startup_cpu() - start the given cpu
|
||||||
|
@ -74,7 +74,7 @@ static inline int __devinit smp_startup_cpu(unsigned int lcpu)
|
||||||
{
|
{
|
||||||
int status;
|
int status;
|
||||||
unsigned long start_here = __pa((u32)*((unsigned long *)
|
unsigned long start_here = __pa((u32)*((unsigned long *)
|
||||||
pSeries_secondary_smp_init));
|
generic_secondary_smp_init));
|
||||||
unsigned int pcpu;
|
unsigned int pcpu;
|
||||||
int start_cpu;
|
int start_cpu;
|
||||||
|
|
||||||
|
|
|
@ -240,7 +240,7 @@ static void spider_irq_cascade(unsigned int irq, struct irq_desc *desc,
|
||||||
static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
|
static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
|
||||||
{
|
{
|
||||||
unsigned int virq;
|
unsigned int virq;
|
||||||
u32 *imap, *tmp;
|
const u32 *imap, *tmp;
|
||||||
int imaplen, intsize, unit;
|
int imaplen, intsize, unit;
|
||||||
struct device_node *iic;
|
struct device_node *iic;
|
||||||
struct irq_host *iic_host;
|
struct irq_host *iic_host;
|
||||||
|
@ -258,25 +258,25 @@ static unsigned int __init spider_find_cascade_and_node(struct spider_pic *pic)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Now do the horrible hacks */
|
/* Now do the horrible hacks */
|
||||||
tmp = (u32 *)get_property(pic->of_node, "#interrupt-cells", NULL);
|
tmp = get_property(pic->of_node, "#interrupt-cells", NULL);
|
||||||
if (tmp == NULL)
|
if (tmp == NULL)
|
||||||
return NO_IRQ;
|
return NO_IRQ;
|
||||||
intsize = *tmp;
|
intsize = *tmp;
|
||||||
imap = (u32 *)get_property(pic->of_node, "interrupt-map", &imaplen);
|
imap = get_property(pic->of_node, "interrupt-map", &imaplen);
|
||||||
if (imap == NULL || imaplen < (intsize + 1))
|
if (imap == NULL || imaplen < (intsize + 1))
|
||||||
return NO_IRQ;
|
return NO_IRQ;
|
||||||
iic = of_find_node_by_phandle(imap[intsize]);
|
iic = of_find_node_by_phandle(imap[intsize]);
|
||||||
if (iic == NULL)
|
if (iic == NULL)
|
||||||
return NO_IRQ;
|
return NO_IRQ;
|
||||||
imap += intsize + 1;
|
imap += intsize + 1;
|
||||||
tmp = (u32 *)get_property(iic, "#interrupt-cells", NULL);
|
tmp = get_property(iic, "#interrupt-cells", NULL);
|
||||||
if (tmp == NULL)
|
if (tmp == NULL)
|
||||||
return NO_IRQ;
|
return NO_IRQ;
|
||||||
intsize = *tmp;
|
intsize = *tmp;
|
||||||
/* Assume unit is last entry of interrupt specifier */
|
/* Assume unit is last entry of interrupt specifier */
|
||||||
unit = imap[intsize - 1];
|
unit = imap[intsize - 1];
|
||||||
/* Ok, we have a unit, now let's try to get the node */
|
/* Ok, we have a unit, now let's try to get the node */
|
||||||
tmp = (u32 *)get_property(iic, "ibm,interrupt-server-ranges", NULL);
|
tmp = get_property(iic, "ibm,interrupt-server-ranges", NULL);
|
||||||
if (tmp == NULL) {
|
if (tmp == NULL) {
|
||||||
of_node_put(iic);
|
of_node_put(iic);
|
||||||
return NO_IRQ;
|
return NO_IRQ;
|
||||||
|
|
|
@ -488,10 +488,10 @@ int spu_irq_class_1_bottom(struct spu *spu)
|
||||||
|
|
||||||
static int __init find_spu_node_id(struct device_node *spe)
|
static int __init find_spu_node_id(struct device_node *spe)
|
||||||
{
|
{
|
||||||
unsigned int *id;
|
const unsigned int *id;
|
||||||
struct device_node *cpu;
|
struct device_node *cpu;
|
||||||
cpu = spe->parent->parent;
|
cpu = spe->parent->parent;
|
||||||
id = (unsigned int *)get_property(cpu, "node-id", NULL);
|
id = get_property(cpu, "node-id", NULL);
|
||||||
return id ? *id : 0;
|
return id ? *id : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -500,7 +500,7 @@ static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe,
|
||||||
{
|
{
|
||||||
static DEFINE_MUTEX(add_spumem_mutex);
|
static DEFINE_MUTEX(add_spumem_mutex);
|
||||||
|
|
||||||
struct address_prop {
|
const struct address_prop {
|
||||||
unsigned long address;
|
unsigned long address;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
} __attribute__((packed)) *p;
|
} __attribute__((packed)) *p;
|
||||||
|
@ -511,7 +511,7 @@ static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe,
|
||||||
struct zone *zone;
|
struct zone *zone;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
p = (void*)get_property(spe, prop, &proplen);
|
p = get_property(spe, prop, &proplen);
|
||||||
WARN_ON(proplen != sizeof (*p));
|
WARN_ON(proplen != sizeof (*p));
|
||||||
|
|
||||||
start_pfn = p->address >> PAGE_SHIFT;
|
start_pfn = p->address >> PAGE_SHIFT;
|
||||||
|
@ -531,12 +531,12 @@ static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe,
|
||||||
static void __iomem * __init map_spe_prop(struct spu *spu,
|
static void __iomem * __init map_spe_prop(struct spu *spu,
|
||||||
struct device_node *n, const char *name)
|
struct device_node *n, const char *name)
|
||||||
{
|
{
|
||||||
struct address_prop {
|
const struct address_prop {
|
||||||
unsigned long address;
|
unsigned long address;
|
||||||
unsigned int len;
|
unsigned int len;
|
||||||
} __attribute__((packed)) *prop;
|
} __attribute__((packed)) *prop;
|
||||||
|
|
||||||
void *p;
|
const void *p;
|
||||||
int proplen;
|
int proplen;
|
||||||
void* ret = NULL;
|
void* ret = NULL;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
@ -570,14 +570,14 @@ static int __init spu_map_interrupts(struct spu *spu, struct device_node *np)
|
||||||
{
|
{
|
||||||
struct irq_host *host;
|
struct irq_host *host;
|
||||||
unsigned int isrc;
|
unsigned int isrc;
|
||||||
u32 *tmp;
|
const u32 *tmp;
|
||||||
|
|
||||||
host = iic_get_irq_host(spu->node);
|
host = iic_get_irq_host(spu->node);
|
||||||
if (host == NULL)
|
if (host == NULL)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
/* Get the interrupt source from the device-tree */
|
/* Get the interrupt source from the device-tree */
|
||||||
tmp = (u32 *)get_property(np, "isrc", NULL);
|
tmp = get_property(np, "isrc", NULL);
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
spu->isrc = isrc = tmp[0];
|
spu->isrc = isrc = tmp[0];
|
||||||
|
@ -593,7 +593,7 @@ static int __init spu_map_interrupts(struct spu *spu, struct device_node *np)
|
||||||
|
|
||||||
static int __init spu_map_device(struct spu *spu, struct device_node *node)
|
static int __init spu_map_device(struct spu *spu, struct device_node *node)
|
||||||
{
|
{
|
||||||
char *prop;
|
const char *prop;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = -ENODEV;
|
ret = -ENODEV;
|
||||||
|
|
|
@ -67,13 +67,14 @@ static void chrp_nvram_write(int addr, unsigned char val)
|
||||||
void __init chrp_nvram_init(void)
|
void __init chrp_nvram_init(void)
|
||||||
{
|
{
|
||||||
struct device_node *nvram;
|
struct device_node *nvram;
|
||||||
unsigned int *nbytes_p, proplen;
|
const unsigned int *nbytes_p;
|
||||||
|
unsigned int proplen;
|
||||||
|
|
||||||
nvram = of_find_node_by_type(NULL, "nvram");
|
nvram = of_find_node_by_type(NULL, "nvram");
|
||||||
if (nvram == NULL)
|
if (nvram == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
nbytes_p = (unsigned int *)get_property(nvram, "#bytes", &proplen);
|
nbytes_p = get_property(nvram, "#bytes", &proplen);
|
||||||
if (nbytes_p == NULL || proplen != sizeof(unsigned int))
|
if (nbytes_p == NULL || proplen != sizeof(unsigned int))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -214,11 +214,11 @@ void __init
|
||||||
chrp_find_bridges(void)
|
chrp_find_bridges(void)
|
||||||
{
|
{
|
||||||
struct device_node *dev;
|
struct device_node *dev;
|
||||||
int *bus_range;
|
const int *bus_range;
|
||||||
int len, index = -1;
|
int len, index = -1;
|
||||||
struct pci_controller *hose;
|
struct pci_controller *hose;
|
||||||
unsigned int *dma;
|
const unsigned int *dma;
|
||||||
char *model, *machine;
|
const char *model, *machine;
|
||||||
int is_longtrail = 0, is_mot = 0, is_pegasos = 0;
|
int is_longtrail = 0, is_mot = 0, is_pegasos = 0;
|
||||||
struct device_node *root = find_path_device("/");
|
struct device_node *root = find_path_device("/");
|
||||||
struct resource r;
|
struct resource r;
|
||||||
|
@ -246,7 +246,7 @@ chrp_find_bridges(void)
|
||||||
dev->full_name);
|
dev->full_name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
bus_range = (int *) get_property(dev, "bus-range", &len);
|
bus_range = get_property(dev, "bus-range", &len);
|
||||||
if (bus_range == NULL || len < 2 * sizeof(int)) {
|
if (bus_range == NULL || len < 2 * sizeof(int)) {
|
||||||
printk(KERN_WARNING "Can't get bus-range for %s\n",
|
printk(KERN_WARNING "Can't get bus-range for %s\n",
|
||||||
dev->full_name);
|
dev->full_name);
|
||||||
|
@ -257,7 +257,7 @@ chrp_find_bridges(void)
|
||||||
else
|
else
|
||||||
printk(KERN_INFO "PCI buses %d..%d",
|
printk(KERN_INFO "PCI buses %d..%d",
|
||||||
bus_range[0], bus_range[1]);
|
bus_range[0], bus_range[1]);
|
||||||
printk(" controlled by %s", dev->type);
|
printk(" controlled by %s", dev->full_name);
|
||||||
if (!is_longtrail)
|
if (!is_longtrail)
|
||||||
printk(" at %llx", (unsigned long long)r.start);
|
printk(" at %llx", (unsigned long long)r.start);
|
||||||
printk("\n");
|
printk("\n");
|
||||||
|
@ -289,6 +289,19 @@ chrp_find_bridges(void)
|
||||||
setup_indirect_pci(hose, 0xfec00cf8, 0xfee00cfc);
|
setup_indirect_pci(hose, 0xfec00cf8, 0xfee00cfc);
|
||||||
} else if (is_pegasos == 2) {
|
} else if (is_pegasos == 2) {
|
||||||
setup_peg2(hose, dev);
|
setup_peg2(hose, dev);
|
||||||
|
} else if (!strncmp(model, "IBM,CPC710", 10)) {
|
||||||
|
setup_indirect_pci(hose,
|
||||||
|
r.start + 0x000f8000,
|
||||||
|
r.start + 0x000f8010);
|
||||||
|
if (index == 0) {
|
||||||
|
dma = get_property(dev, "system-dma-base",&len);
|
||||||
|
if (dma && len >= sizeof(*dma)) {
|
||||||
|
dma = (unsigned int *)
|
||||||
|
(((unsigned long)dma) +
|
||||||
|
len - sizeof(*dma));
|
||||||
|
pci_dram_offset = *dma;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
printk("No methods for %s (model %s), using RTAS\n",
|
printk("No methods for %s (model %s), using RTAS\n",
|
||||||
dev->full_name, model);
|
dev->full_name, model);
|
||||||
|
@ -299,15 +312,35 @@ chrp_find_bridges(void)
|
||||||
|
|
||||||
/* check the first bridge for a property that we can
|
/* check the first bridge for a property that we can
|
||||||
use to set pci_dram_offset */
|
use to set pci_dram_offset */
|
||||||
dma = (unsigned int *)
|
dma = get_property(dev, "ibm,dma-ranges", &len);
|
||||||
get_property(dev, "ibm,dma-ranges", &len);
|
|
||||||
if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) {
|
if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) {
|
||||||
pci_dram_offset = dma[2] - dma[3];
|
pci_dram_offset = dma[2] - dma[3];
|
||||||
printk("pci_dram_offset = %lx\n", pci_dram_offset);
|
printk("pci_dram_offset = %lx\n", pci_dram_offset);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Do not fixup interrupts from OF tree on pegasos */
|
|
||||||
if (is_pegasos)
|
|
||||||
ppc_md.pcibios_fixup = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* SL82C105 IDE Control/Status Register */
|
||||||
|
#define SL82C105_IDECSR 0x40
|
||||||
|
|
||||||
|
/* Fixup for Winbond ATA quirk, required for briq */
|
||||||
|
void chrp_pci_fixup_winbond_ata(struct pci_dev *sl82c105)
|
||||||
|
{
|
||||||
|
u8 progif;
|
||||||
|
|
||||||
|
/* If non-briq machines need that fixup too, please speak up */
|
||||||
|
if (!machine_is(chrp) || _chrp_type != _CHRP_briq)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if ((sl82c105->class & 5) != 5) {
|
||||||
|
printk("W83C553: Switching SL82C105 IDE to PCI native mode\n");
|
||||||
|
/* Enable SL82C105 PCI native IDE mode */
|
||||||
|
pci_read_config_byte(sl82c105, PCI_CLASS_PROG, &progif);
|
||||||
|
pci_write_config_byte(sl82c105, PCI_CLASS_PROG, progif | 0x05);
|
||||||
|
sl82c105->class |= 0x05;
|
||||||
|
/* Disable SL82C105 second port */
|
||||||
|
pci_write_config_word(sl82c105, SL82C105_IDECSR, 0x0003);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105,
|
||||||
|
chrp_pci_fixup_winbond_ata);
|
||||||
|
|
|
@ -74,6 +74,9 @@ extern irqreturn_t xmon_irq(int, void *, struct pt_regs *);
|
||||||
|
|
||||||
extern unsigned long loops_per_jiffy;
|
extern unsigned long loops_per_jiffy;
|
||||||
|
|
||||||
|
/* To be replaced by RTAS when available */
|
||||||
|
static unsigned int *briq_SPOR;
|
||||||
|
|
||||||
#ifdef CONFIG_SMP
|
#ifdef CONFIG_SMP
|
||||||
extern struct smp_ops_t chrp_smp_ops;
|
extern struct smp_ops_t chrp_smp_ops;
|
||||||
#endif
|
#endif
|
||||||
|
@ -92,6 +95,15 @@ static const char *gg2_cachemodes[4] = {
|
||||||
"Disabled", "Write-Through", "Copy-Back", "Transparent Mode"
|
"Disabled", "Write-Through", "Copy-Back", "Transparent Mode"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const char *chrp_names[] = {
|
||||||
|
"Unknown",
|
||||||
|
"","","",
|
||||||
|
"Motorola",
|
||||||
|
"IBM or Longtrail",
|
||||||
|
"Genesi Pegasos",
|
||||||
|
"Total Impact Briq"
|
||||||
|
};
|
||||||
|
|
||||||
void chrp_show_cpuinfo(struct seq_file *m)
|
void chrp_show_cpuinfo(struct seq_file *m)
|
||||||
{
|
{
|
||||||
int i, sdramen;
|
int i, sdramen;
|
||||||
|
@ -214,8 +226,7 @@ static void __init pegasos_set_l2cr(void)
|
||||||
/* Enable L2 cache if needed */
|
/* Enable L2 cache if needed */
|
||||||
np = find_type_devices("cpu");
|
np = find_type_devices("cpu");
|
||||||
if (np != NULL) {
|
if (np != NULL) {
|
||||||
unsigned int *l2cr = (unsigned int *)
|
const unsigned int *l2cr = get_property(np, "l2cr", NULL);
|
||||||
get_property (np, "l2cr", NULL);
|
|
||||||
if (l2cr == NULL) {
|
if (l2cr == NULL) {
|
||||||
printk ("Pegasos l2cr : no cpu l2cr property found\n");
|
printk ("Pegasos l2cr : no cpu l2cr property found\n");
|
||||||
return;
|
return;
|
||||||
|
@ -229,10 +240,18 @@ static void __init pegasos_set_l2cr(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void briq_restart(char *cmd)
|
||||||
|
{
|
||||||
|
local_irq_disable();
|
||||||
|
if (briq_SPOR)
|
||||||
|
out_be32(briq_SPOR, 0);
|
||||||
|
for(;;);
|
||||||
|
}
|
||||||
|
|
||||||
void __init chrp_setup_arch(void)
|
void __init chrp_setup_arch(void)
|
||||||
{
|
{
|
||||||
struct device_node *root = find_path_device ("/");
|
struct device_node *root = find_path_device ("/");
|
||||||
char *machine = NULL;
|
const char *machine = NULL;
|
||||||
|
|
||||||
/* init to some ~sane value until calibrate_delay() runs */
|
/* init to some ~sane value until calibrate_delay() runs */
|
||||||
loops_per_jiffy = 50000000/HZ;
|
loops_per_jiffy = 50000000/HZ;
|
||||||
|
@ -245,11 +264,16 @@ void __init chrp_setup_arch(void)
|
||||||
_chrp_type = _CHRP_IBM;
|
_chrp_type = _CHRP_IBM;
|
||||||
} else if (machine && strncmp(machine, "MOT", 3) == 0) {
|
} else if (machine && strncmp(machine, "MOT", 3) == 0) {
|
||||||
_chrp_type = _CHRP_Motorola;
|
_chrp_type = _CHRP_Motorola;
|
||||||
|
} else if (machine && strncmp(machine, "TotalImpact,BRIQ-1", 18) == 0) {
|
||||||
|
_chrp_type = _CHRP_briq;
|
||||||
|
/* Map the SPOR register on briq and change the restart hook */
|
||||||
|
briq_SPOR = (unsigned int *)ioremap(0xff0000e8, 4);
|
||||||
|
ppc_md.restart = briq_restart;
|
||||||
} else {
|
} else {
|
||||||
/* Let's assume it is an IBM chrp if all else fails */
|
/* Let's assume it is an IBM chrp if all else fails */
|
||||||
_chrp_type = _CHRP_IBM;
|
_chrp_type = _CHRP_IBM;
|
||||||
}
|
}
|
||||||
printk("chrp type = %x\n", _chrp_type);
|
printk("chrp type = %x [%s]\n", _chrp_type, chrp_names[_chrp_type]);
|
||||||
|
|
||||||
rtas_initialize();
|
rtas_initialize();
|
||||||
if (rtas_token("display-character") >= 0)
|
if (rtas_token("display-character") >= 0)
|
||||||
|
@ -328,7 +352,7 @@ static void __init chrp_find_openpic(void)
|
||||||
struct device_node *np, *root;
|
struct device_node *np, *root;
|
||||||
int len, i, j;
|
int len, i, j;
|
||||||
int isu_size, idu_size;
|
int isu_size, idu_size;
|
||||||
unsigned int *iranges, *opprop = NULL;
|
const unsigned int *iranges, *opprop = NULL;
|
||||||
int oplen = 0;
|
int oplen = 0;
|
||||||
unsigned long opaddr;
|
unsigned long opaddr;
|
||||||
int na = 1;
|
int na = 1;
|
||||||
|
@ -338,8 +362,7 @@ static void __init chrp_find_openpic(void)
|
||||||
return;
|
return;
|
||||||
root = of_find_node_by_path("/");
|
root = of_find_node_by_path("/");
|
||||||
if (root) {
|
if (root) {
|
||||||
opprop = (unsigned int *) get_property
|
opprop = get_property(root, "platform-open-pic", &oplen);
|
||||||
(root, "platform-open-pic", &oplen);
|
|
||||||
na = prom_n_addr_cells(root);
|
na = prom_n_addr_cells(root);
|
||||||
}
|
}
|
||||||
if (opprop && oplen >= na * sizeof(unsigned int)) {
|
if (opprop && oplen >= na * sizeof(unsigned int)) {
|
||||||
|
@ -356,7 +379,7 @@ static void __init chrp_find_openpic(void)
|
||||||
|
|
||||||
printk(KERN_INFO "OpenPIC at %lx\n", opaddr);
|
printk(KERN_INFO "OpenPIC at %lx\n", opaddr);
|
||||||
|
|
||||||
iranges = (unsigned int *) get_property(np, "interrupt-ranges", &len);
|
iranges = get_property(np, "interrupt-ranges", &len);
|
||||||
if (iranges == NULL)
|
if (iranges == NULL)
|
||||||
len = 0; /* non-distributed mpic */
|
len = 0; /* non-distributed mpic */
|
||||||
else
|
else
|
||||||
|
@ -442,8 +465,8 @@ static void __init chrp_find_8259(void)
|
||||||
* from anyway
|
* from anyway
|
||||||
*/
|
*/
|
||||||
for (np = find_devices("pci"); np != NULL; np = np->next) {
|
for (np = find_devices("pci"); np != NULL; np = np->next) {
|
||||||
unsigned int *addrp = (unsigned int *)
|
const unsigned int *addrp = get_property(np,
|
||||||
get_property(np, "8259-interrupt-acknowledge", NULL);
|
"8259-interrupt-acknowledge", NULL);
|
||||||
|
|
||||||
if (addrp == NULL)
|
if (addrp == NULL)
|
||||||
continue;
|
continue;
|
||||||
|
@ -502,7 +525,7 @@ void __init
|
||||||
chrp_init2(void)
|
chrp_init2(void)
|
||||||
{
|
{
|
||||||
struct device_node *device;
|
struct device_node *device;
|
||||||
unsigned int *p = NULL;
|
const unsigned int *p = NULL;
|
||||||
|
|
||||||
#ifdef CONFIG_NVRAM
|
#ifdef CONFIG_NVRAM
|
||||||
chrp_nvram_init();
|
chrp_nvram_init();
|
||||||
|
@ -520,8 +543,7 @@ chrp_init2(void)
|
||||||
*/
|
*/
|
||||||
device = find_devices("rtas");
|
device = find_devices("rtas");
|
||||||
if (device)
|
if (device)
|
||||||
p = (unsigned int *) get_property
|
p = get_property(device, "rtas-event-scan-rate", NULL);
|
||||||
(device, "rtas-event-scan-rate", NULL);
|
|
||||||
if (p && *p) {
|
if (p && *p) {
|
||||||
/*
|
/*
|
||||||
* Arrange to call chrp_event_scan at least *p times
|
* Arrange to call chrp_event_scan at least *p times
|
||||||
|
|
|
@ -95,7 +95,7 @@ void mpc7448_hpc2_fixup_irq(struct pci_dev *dev)
|
||||||
{
|
{
|
||||||
struct pci_controller *hose;
|
struct pci_controller *hose;
|
||||||
struct device_node *node;
|
struct device_node *node;
|
||||||
unsigned int *interrupt;
|
const unsigned int *interrupt;
|
||||||
int busnr;
|
int busnr;
|
||||||
int len;
|
int len;
|
||||||
u8 slot;
|
u8 slot;
|
||||||
|
@ -112,7 +112,7 @@ void mpc7448_hpc2_fixup_irq(struct pci_dev *dev)
|
||||||
if (!node)
|
if (!node)
|
||||||
printk(KERN_ERR "No pci node found\n");
|
printk(KERN_ERR "No pci node found\n");
|
||||||
|
|
||||||
interrupt = (unsigned int *) get_property(node, "interrupt-map", &len);
|
interrupt = get_property(node, "interrupt-map", &len);
|
||||||
slot = find_slot_by_devfn(interrupt, dev->devfn);
|
slot = find_slot_by_devfn(interrupt, dev->devfn);
|
||||||
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
|
pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
|
||||||
if (pin == 0 || pin > 4)
|
if (pin == 0 || pin > 4)
|
||||||
|
@ -141,9 +141,9 @@ static void __init mpc7448_hpc2_setup_arch(void)
|
||||||
|
|
||||||
cpu = of_find_node_by_type(NULL, "cpu");
|
cpu = of_find_node_by_type(NULL, "cpu");
|
||||||
if (cpu != 0) {
|
if (cpu != 0) {
|
||||||
unsigned int *fp;
|
const unsigned int *fp;
|
||||||
|
|
||||||
fp = (int *)get_property(cpu, "clock-frequency", NULL);
|
fp = get_property(cpu, "clock-frequency", NULL);
|
||||||
if (fp != 0)
|
if (fp != 0)
|
||||||
loops_per_jiffy = *fp / HZ;
|
loops_per_jiffy = *fp / HZ;
|
||||||
else
|
else
|
||||||
|
|
|
@ -3,7 +3,11 @@ menu "iSeries device drivers"
|
||||||
depends on PPC_ISERIES
|
depends on PPC_ISERIES
|
||||||
|
|
||||||
config VIOCONS
|
config VIOCONS
|
||||||
tristate "iSeries Virtual Console Support"
|
tristate "iSeries Virtual Console Support (Obsolete)"
|
||||||
|
help
|
||||||
|
This is the old virtual console driver for legacy iSeries.
|
||||||
|
You should use the iSeries Hypervisor Virtual Console
|
||||||
|
support instead.
|
||||||
|
|
||||||
config VIODASD
|
config VIODASD
|
||||||
tristate "iSeries Virtual I/O disk support"
|
tristate "iSeries Virtual I/O disk support"
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2005-2006 Michael Ellerman, IBM Corporation
|
* Copyright (C) 2005-2006 Michael Ellerman, IBM Corporation
|
||||||
|
* Copyright (C) 2000-2004, IBM Corporation
|
||||||
*
|
*
|
||||||
* Description:
|
* Description:
|
||||||
* This file contains all the routines to build a flattened device
|
* This file contains all the routines to build a flattened device
|
||||||
|
@ -33,13 +34,13 @@
|
||||||
#include <asm/iseries/hv_types.h>
|
#include <asm/iseries/hv_types.h>
|
||||||
#include <asm/iseries/hv_lp_config.h>
|
#include <asm/iseries/hv_lp_config.h>
|
||||||
#include <asm/iseries/hv_call_xm.h>
|
#include <asm/iseries/hv_call_xm.h>
|
||||||
#include <asm/iseries/it_exp_vpd_panel.h>
|
|
||||||
#include <asm/udbg.h>
|
#include <asm/udbg.h>
|
||||||
|
|
||||||
#include "processor_vpd.h"
|
#include "processor_vpd.h"
|
||||||
#include "call_hpt.h"
|
#include "call_hpt.h"
|
||||||
#include "call_pci.h"
|
#include "call_pci.h"
|
||||||
#include "pci.h"
|
#include "pci.h"
|
||||||
|
#include "it_exp_vpd_panel.h"
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
#define DBG(fmt...) udbg_printf(fmt)
|
#define DBG(fmt...) udbg_printf(fmt)
|
||||||
|
@ -76,6 +77,43 @@ static char __initdata device_type_pci[] = "pci";
|
||||||
static char __initdata device_type_vdevice[] = "vdevice";
|
static char __initdata device_type_vdevice[] = "vdevice";
|
||||||
static char __initdata device_type_vscsi[] = "vscsi";
|
static char __initdata device_type_vscsi[] = "vscsi";
|
||||||
|
|
||||||
|
|
||||||
|
/* EBCDIC to ASCII conversion routines */
|
||||||
|
|
||||||
|
static unsigned char __init e2a(unsigned char x)
|
||||||
|
{
|
||||||
|
switch (x) {
|
||||||
|
case 0x81 ... 0x89:
|
||||||
|
return x - 0x81 + 'a';
|
||||||
|
case 0x91 ... 0x99:
|
||||||
|
return x - 0x91 + 'j';
|
||||||
|
case 0xA2 ... 0xA9:
|
||||||
|
return x - 0xA2 + 's';
|
||||||
|
case 0xC1 ... 0xC9:
|
||||||
|
return x - 0xC1 + 'A';
|
||||||
|
case 0xD1 ... 0xD9:
|
||||||
|
return x - 0xD1 + 'J';
|
||||||
|
case 0xE2 ... 0xE9:
|
||||||
|
return x - 0xE2 + 'S';
|
||||||
|
case 0xF0 ... 0xF9:
|
||||||
|
return x - 0xF0 + '0';
|
||||||
|
}
|
||||||
|
return ' ';
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned char * __init strne2a(unsigned char *dest,
|
||||||
|
const unsigned char *src, size_t n)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
n = strnlen(src, n);
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
dest[i] = e2a(src[i]);
|
||||||
|
|
||||||
|
return dest;
|
||||||
|
}
|
||||||
|
|
||||||
static struct iseries_flat_dt * __init dt_init(void)
|
static struct iseries_flat_dt * __init dt_init(void)
|
||||||
{
|
{
|
||||||
struct iseries_flat_dt *dt;
|
struct iseries_flat_dt *dt;
|
||||||
|
@ -298,7 +336,8 @@ static void __init dt_vdevices(struct iseries_flat_dt *dt)
|
||||||
dt_prop_u32(dt, "#address-cells", 1);
|
dt_prop_u32(dt, "#address-cells", 1);
|
||||||
dt_prop_u32(dt, "#size-cells", 0);
|
dt_prop_u32(dt, "#size-cells", 0);
|
||||||
|
|
||||||
dt_do_vdevice(dt, "vty", reg, -1, device_type_serial, NULL, 1);
|
dt_do_vdevice(dt, "vty", reg, -1, device_type_serial,
|
||||||
|
"IBM,iSeries-vty", 1);
|
||||||
reg++;
|
reg++;
|
||||||
|
|
||||||
dt_do_vdevice(dt, "v-scsi", reg, -1, device_type_vscsi,
|
dt_do_vdevice(dt, "v-scsi", reg, -1, device_type_vscsi,
|
||||||
|
|
|
@ -18,9 +18,22 @@
|
||||||
|
|
||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
#include <asm/iseries/hv_lp_config.h>
|
#include <asm/iseries/hv_lp_config.h>
|
||||||
|
#include "it_lp_naca.h"
|
||||||
|
|
||||||
HvLpIndex HvLpConfig_getLpIndex_outline(void)
|
HvLpIndex HvLpConfig_getLpIndex_outline(void)
|
||||||
{
|
{
|
||||||
return HvLpConfig_getLpIndex();
|
return HvLpConfig_getLpIndex();
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(HvLpConfig_getLpIndex_outline);
|
EXPORT_SYMBOL(HvLpConfig_getLpIndex_outline);
|
||||||
|
|
||||||
|
HvLpIndex HvLpConfig_getLpIndex(void)
|
||||||
|
{
|
||||||
|
return itLpNaca.xLpIndex;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(HvLpConfig_getLpIndex);
|
||||||
|
|
||||||
|
HvLpIndex HvLpConfig_getPrimaryLpIndex(void)
|
||||||
|
{
|
||||||
|
return itLpNaca.xPrimaryLpIndex;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL_GPL(HvLpConfig_getPrimaryLpIndex);
|
||||||
|
|
|
@ -87,6 +87,23 @@ static void tce_free_iSeries(struct iommu_table *tbl, long index, long npages)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Structure passed to HvCallXm_getTceTableParms
|
||||||
|
*/
|
||||||
|
struct iommu_table_cb {
|
||||||
|
unsigned long itc_busno; /* Bus number for this tce table */
|
||||||
|
unsigned long itc_start; /* Will be NULL for secondary */
|
||||||
|
unsigned long itc_totalsize; /* Size (in pages) of whole table */
|
||||||
|
unsigned long itc_offset; /* Index into real tce table of the
|
||||||
|
start of our section */
|
||||||
|
unsigned long itc_size; /* Size (in pages) of our section */
|
||||||
|
unsigned long itc_index; /* Index of this tce table */
|
||||||
|
unsigned short itc_maxtables; /* Max num of tables for partition */
|
||||||
|
unsigned char itc_virtbus; /* Flag to indicate virtual bus */
|
||||||
|
unsigned char itc_slotno; /* IOA Tce Slot Index */
|
||||||
|
unsigned char itc_rsvd[4];
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Call Hv with the architected data structure to get TCE table info.
|
* Call Hv with the architected data structure to get TCE table info.
|
||||||
* info. Put the returned data into the Linux representation of the
|
* info. Put the returned data into the Linux representation of the
|
||||||
|
@ -162,7 +179,7 @@ void iommu_devnode_init_iSeries(struct device_node *dn)
|
||||||
{
|
{
|
||||||
struct iommu_table *tbl;
|
struct iommu_table *tbl;
|
||||||
struct pci_dn *pdn = PCI_DN(dn);
|
struct pci_dn *pdn = PCI_DN(dn);
|
||||||
u32 *lsn = (u32 *)get_property(dn, "linux,logical-slot-number", NULL);
|
const u32 *lsn = get_property(dn, "linux,logical-slot-number", NULL);
|
||||||
|
|
||||||
BUG_ON(lsn == NULL);
|
BUG_ON(lsn == NULL);
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,8 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
#ifndef _ASM_POWERPC_ISERIES_IT_EXT_VPD_PANEL_H
|
#ifndef _PLATFORMS_ISERIES_IT_EXT_VPD_PANEL_H
|
||||||
#define _ASM_POWERPC_ISERIES_IT_EXT_VPD_PANEL_H
|
#define _PLATFORMS_ISERIES_IT_EXT_VPD_PANEL_H
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This struct maps the panel information
|
* This struct maps the panel information
|
||||||
|
@ -48,4 +48,4 @@ struct ItExtVpdPanel {
|
||||||
|
|
||||||
extern struct ItExtVpdPanel xItExtVpdPanel;
|
extern struct ItExtVpdPanel xItExtVpdPanel;
|
||||||
|
|
||||||
#endif /* _ASM_POWERPC_ISERIES_IT_EXT_VPD_PANEL_H */
|
#endif /* _PLATFORMS_ISERIES_IT_EXT_VPD_PANEL_H */
|
|
@ -15,8 +15,8 @@
|
||||||
* along with this program; if not, write to the Free Software
|
* along with this program; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*/
|
*/
|
||||||
#ifndef _ASM_POWERPC_ISERIES_IT_LP_NACA_H
|
#ifndef _PLATFORMS_ISERIES_IT_LP_NACA_H
|
||||||
#define _ASM_POWERPC_ISERIES_IT_LP_NACA_H
|
#define _PLATFORMS_ISERIES_IT_LP_NACA_H
|
||||||
|
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
|
|
||||||
|
@ -77,4 +77,4 @@ extern struct ItLpNaca itLpNaca;
|
||||||
#define ITLPNACA_HWSYNCEDTBS 0x20 /* Hardware synced TBs */
|
#define ITLPNACA_HWSYNCEDTBS 0x20 /* Hardware synced TBs */
|
||||||
#define ITLPNACA_HMTINT 0x10 /* Utilize MHT for interrupts */
|
#define ITLPNACA_HMTINT 0x10 /* Utilize MHT for interrupts */
|
||||||
|
|
||||||
#endif /* _ASM_POWERPC_ISERIES_IT_LP_NACA_H */
|
#endif /* _PLATFORMS_ISERIES_IT_LP_NACA_H */
|
|
@ -13,12 +13,10 @@
|
||||||
#include <asm/processor.h>
|
#include <asm/processor.h>
|
||||||
#include <asm/ptrace.h>
|
#include <asm/ptrace.h>
|
||||||
#include <asm/abs_addr.h>
|
#include <asm/abs_addr.h>
|
||||||
#include <asm/iseries/it_lp_naca.h>
|
|
||||||
#include <asm/lppaca.h>
|
#include <asm/lppaca.h>
|
||||||
#include <asm/iseries/it_lp_reg_save.h>
|
#include <asm/iseries/it_lp_reg_save.h>
|
||||||
#include <asm/paca.h>
|
#include <asm/paca.h>
|
||||||
#include <asm/iseries/lpar_map.h>
|
#include <asm/iseries/lpar_map.h>
|
||||||
#include <asm/iseries/it_exp_vpd_panel.h>
|
|
||||||
#include <asm/iseries/it_lp_queue.h>
|
#include <asm/iseries/it_lp_queue.h>
|
||||||
|
|
||||||
#include "naca.h"
|
#include "naca.h"
|
||||||
|
@ -27,6 +25,8 @@
|
||||||
#include "ipl_parms.h"
|
#include "ipl_parms.h"
|
||||||
#include "processor_vpd.h"
|
#include "processor_vpd.h"
|
||||||
#include "release_data.h"
|
#include "release_data.h"
|
||||||
|
#include "it_exp_vpd_panel.h"
|
||||||
|
#include "it_lp_naca.h"
|
||||||
|
|
||||||
/* The HvReleaseData is the root of the information shared between
|
/* The HvReleaseData is the root of the information shared between
|
||||||
* the hypervisor and Linux.
|
* the hypervisor and Linux.
|
||||||
|
@ -127,14 +127,12 @@ struct ItLpNaca itLpNaca = {
|
||||||
(u64)instruction_access_slb_iSeries /* 0x480 I-SLB */
|
(u64)instruction_access_slb_iSeries /* 0x480 I-SLB */
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
EXPORT_SYMBOL(itLpNaca);
|
|
||||||
|
|
||||||
/* May be filled in by the hypervisor so cannot end up in the BSS */
|
/* May be filled in by the hypervisor so cannot end up in the BSS */
|
||||||
struct ItIplParmsReal xItIplParmsReal __attribute__((__section__(".data")));
|
struct ItIplParmsReal xItIplParmsReal __attribute__((__section__(".data")));
|
||||||
|
|
||||||
/* May be filled in by the hypervisor so cannot end up in the BSS */
|
/* May be filled in by the hypervisor so cannot end up in the BSS */
|
||||||
struct ItExtVpdPanel xItExtVpdPanel __attribute__((__section__(".data")));
|
struct ItExtVpdPanel xItExtVpdPanel __attribute__((__section__(".data")));
|
||||||
EXPORT_SYMBOL(xItExtVpdPanel);
|
|
||||||
|
|
||||||
#define maxPhysicalProcessors 32
|
#define maxPhysicalProcessors 32
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@
|
||||||
#include <asm/iseries/it_lp_queue.h>
|
#include <asm/iseries/it_lp_queue.h>
|
||||||
#include <asm/iseries/hv_lp_event.h>
|
#include <asm/iseries/hv_lp_event.h>
|
||||||
#include <asm/iseries/hv_call_event.h>
|
#include <asm/iseries/hv_call_event.h>
|
||||||
#include <asm/iseries/it_lp_naca.h>
|
#include "it_lp_naca.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The LpQueue is used to pass event data from the hypervisor to
|
* The LpQueue is used to pass event data from the hypervisor to
|
||||||
|
|
|
@ -61,9 +61,9 @@ struct IoHriMainStoreSegment4 {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Main Store VPD for Power4 */
|
/* Main Store VPD for Power4 */
|
||||||
struct IoHriMainStoreChipInfo1 {
|
struct __attribute((packed)) IoHriMainStoreChipInfo1 {
|
||||||
u32 chipMfgID __attribute((packed));
|
u32 chipMfgID;
|
||||||
char chipECLevel[4] __attribute((packed));
|
char chipECLevel[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IoHriMainStoreVpdIdData {
|
struct IoHriMainStoreVpdIdData {
|
||||||
|
@ -73,72 +73,72 @@ struct IoHriMainStoreVpdIdData {
|
||||||
char serialNumber[12];
|
char serialNumber[12];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IoHriMainStoreVpdFruData {
|
struct __attribute((packed)) IoHriMainStoreVpdFruData {
|
||||||
char fruLabel[8] __attribute((packed));
|
char fruLabel[8];
|
||||||
u8 numberOfSlots __attribute((packed));
|
u8 numberOfSlots;
|
||||||
u8 pluggingType __attribute((packed));
|
u8 pluggingType;
|
||||||
u16 slotMapIndex __attribute((packed));
|
u16 slotMapIndex;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IoHriMainStoreAdrRangeBlock {
|
struct __attribute((packed)) IoHriMainStoreAdrRangeBlock {
|
||||||
void *blockStart __attribute((packed));
|
void *blockStart;
|
||||||
void *blockEnd __attribute((packed));
|
void *blockEnd;
|
||||||
u32 blockProcChipId __attribute((packed));
|
u32 blockProcChipId;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MaxAreaAdrRangeBlocks 4
|
#define MaxAreaAdrRangeBlocks 4
|
||||||
|
|
||||||
struct IoHriMainStoreArea4 {
|
struct __attribute((packed)) IoHriMainStoreArea4 {
|
||||||
u32 msVpdFormat __attribute((packed));
|
u32 msVpdFormat;
|
||||||
u8 containedVpdType __attribute((packed));
|
u8 containedVpdType;
|
||||||
u8 reserved1 __attribute((packed));
|
u8 reserved1;
|
||||||
u16 reserved2 __attribute((packed));
|
u16 reserved2;
|
||||||
|
|
||||||
u64 msExists __attribute((packed));
|
u64 msExists;
|
||||||
u64 msFunctional __attribute((packed));
|
u64 msFunctional;
|
||||||
|
|
||||||
u32 memorySize __attribute((packed));
|
u32 memorySize;
|
||||||
u32 procNodeId __attribute((packed));
|
u32 procNodeId;
|
||||||
|
|
||||||
u32 numAdrRangeBlocks __attribute((packed));
|
u32 numAdrRangeBlocks;
|
||||||
struct IoHriMainStoreAdrRangeBlock xAdrRangeBlock[MaxAreaAdrRangeBlocks] __attribute((packed));
|
struct IoHriMainStoreAdrRangeBlock xAdrRangeBlock[MaxAreaAdrRangeBlocks];
|
||||||
|
|
||||||
struct IoHriMainStoreChipInfo1 chipInfo0 __attribute((packed));
|
struct IoHriMainStoreChipInfo1 chipInfo0;
|
||||||
struct IoHriMainStoreChipInfo1 chipInfo1 __attribute((packed));
|
struct IoHriMainStoreChipInfo1 chipInfo1;
|
||||||
struct IoHriMainStoreChipInfo1 chipInfo2 __attribute((packed));
|
struct IoHriMainStoreChipInfo1 chipInfo2;
|
||||||
struct IoHriMainStoreChipInfo1 chipInfo3 __attribute((packed));
|
struct IoHriMainStoreChipInfo1 chipInfo3;
|
||||||
struct IoHriMainStoreChipInfo1 chipInfo4 __attribute((packed));
|
struct IoHriMainStoreChipInfo1 chipInfo4;
|
||||||
struct IoHriMainStoreChipInfo1 chipInfo5 __attribute((packed));
|
struct IoHriMainStoreChipInfo1 chipInfo5;
|
||||||
struct IoHriMainStoreChipInfo1 chipInfo6 __attribute((packed));
|
struct IoHriMainStoreChipInfo1 chipInfo6;
|
||||||
struct IoHriMainStoreChipInfo1 chipInfo7 __attribute((packed));
|
struct IoHriMainStoreChipInfo1 chipInfo7;
|
||||||
|
|
||||||
void *msRamAreaArray __attribute((packed));
|
void *msRamAreaArray;
|
||||||
u32 msRamAreaArrayNumEntries __attribute((packed));
|
u32 msRamAreaArrayNumEntries;
|
||||||
u32 msRamAreaArrayEntrySize __attribute((packed));
|
u32 msRamAreaArrayEntrySize;
|
||||||
|
|
||||||
u32 numaDimmExists __attribute((packed));
|
u32 numaDimmExists;
|
||||||
u32 numaDimmFunctional __attribute((packed));
|
u32 numaDimmFunctional;
|
||||||
void *numaDimmArray __attribute((packed));
|
void *numaDimmArray;
|
||||||
u32 numaDimmArrayNumEntries __attribute((packed));
|
u32 numaDimmArrayNumEntries;
|
||||||
u32 numaDimmArrayEntrySize __attribute((packed));
|
u32 numaDimmArrayEntrySize;
|
||||||
|
|
||||||
struct IoHriMainStoreVpdIdData idData __attribute((packed));
|
struct IoHriMainStoreVpdIdData idData;
|
||||||
|
|
||||||
u64 powerData __attribute((packed));
|
u64 powerData;
|
||||||
u64 cardAssemblyPartNum __attribute((packed));
|
u64 cardAssemblyPartNum;
|
||||||
u64 chipSerialNum __attribute((packed));
|
u64 chipSerialNum;
|
||||||
|
|
||||||
u64 reserved3 __attribute((packed));
|
u64 reserved3;
|
||||||
char reserved4[16] __attribute((packed));
|
char reserved4[16];
|
||||||
|
|
||||||
struct IoHriMainStoreVpdFruData fruData __attribute((packed));
|
struct IoHriMainStoreVpdFruData fruData;
|
||||||
|
|
||||||
u8 vpdPortNum __attribute((packed));
|
u8 vpdPortNum;
|
||||||
u8 reserved5 __attribute((packed));
|
u8 reserved5;
|
||||||
u8 frameId __attribute((packed));
|
u8 frameId;
|
||||||
u8 rackUnit __attribute((packed));
|
u8 rackUnit;
|
||||||
char asciiKeywordVpd[256] __attribute((packed));
|
char asciiKeywordVpd[256];
|
||||||
u32 reserved6 __attribute((packed));
|
u32 reserved6;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
#include <asm/pci-bridge.h>
|
#include <asm/pci-bridge.h>
|
||||||
#include <asm/iommu.h>
|
#include <asm/iommu.h>
|
||||||
#include <asm/abs_addr.h>
|
#include <asm/abs_addr.h>
|
||||||
|
#include <asm/firmware.h>
|
||||||
|
|
||||||
#include <asm/iseries/hv_call_xm.h>
|
#include <asm/iseries/hv_call_xm.h>
|
||||||
#include <asm/iseries/mf.h>
|
#include <asm/iseries/mf.h>
|
||||||
|
@ -176,12 +177,12 @@ void iSeries_pcibios_init(void)
|
||||||
}
|
}
|
||||||
while ((node = of_get_next_child(root, node)) != NULL) {
|
while ((node = of_get_next_child(root, node)) != NULL) {
|
||||||
HvBusNumber bus;
|
HvBusNumber bus;
|
||||||
u32 *busp;
|
const u32 *busp;
|
||||||
|
|
||||||
if ((node->type == NULL) || (strcmp(node->type, "pci") != 0))
|
if ((node->type == NULL) || (strcmp(node->type, "pci") != 0))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
busp = (u32 *)get_property(node, "bus-range", NULL);
|
busp = get_property(node, "bus-range", NULL);
|
||||||
if (busp == NULL)
|
if (busp == NULL)
|
||||||
continue;
|
continue;
|
||||||
bus = *busp;
|
bus = *busp;
|
||||||
|
@ -221,10 +222,9 @@ void __init iSeries_pci_final_fixup(void)
|
||||||
|
|
||||||
if (node != NULL) {
|
if (node != NULL) {
|
||||||
struct pci_dn *pdn = PCI_DN(node);
|
struct pci_dn *pdn = PCI_DN(node);
|
||||||
u32 *agent;
|
const u32 *agent;
|
||||||
|
|
||||||
agent = (u32 *)get_property(node, "linux,agent-id",
|
agent = get_property(node, "linux,agent-id", NULL);
|
||||||
NULL);
|
|
||||||
if ((pdn != NULL) && (agent != NULL)) {
|
if ((pdn != NULL) && (agent != NULL)) {
|
||||||
u8 irq = iSeries_allocate_IRQ(pdn->busno, 0,
|
u8 irq = iSeries_allocate_IRQ(pdn->busno, 0,
|
||||||
pdn->bussubno);
|
pdn->bussubno);
|
||||||
|
@ -270,46 +270,6 @@ void pcibios_fixup_resources(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* I/0 Memory copy MUST use mmio commands on iSeries
|
|
||||||
* To do; For performance, include the hv call directly
|
|
||||||
*/
|
|
||||||
void iSeries_memset_io(volatile void __iomem *dest, char c, size_t Count)
|
|
||||||
{
|
|
||||||
u8 ByteValue = c;
|
|
||||||
long NumberOfBytes = Count;
|
|
||||||
|
|
||||||
while (NumberOfBytes > 0) {
|
|
||||||
iSeries_Write_Byte(ByteValue, dest++);
|
|
||||||
-- NumberOfBytes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(iSeries_memset_io);
|
|
||||||
|
|
||||||
void iSeries_memcpy_toio(volatile void __iomem *dest, void *source, size_t count)
|
|
||||||
{
|
|
||||||
char *src = source;
|
|
||||||
long NumberOfBytes = count;
|
|
||||||
|
|
||||||
while (NumberOfBytes > 0) {
|
|
||||||
iSeries_Write_Byte(*src++, dest++);
|
|
||||||
-- NumberOfBytes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(iSeries_memcpy_toio);
|
|
||||||
|
|
||||||
void iSeries_memcpy_fromio(void *dest, const volatile void __iomem *src, size_t count)
|
|
||||||
{
|
|
||||||
char *dst = dest;
|
|
||||||
long NumberOfBytes = count;
|
|
||||||
|
|
||||||
while (NumberOfBytes > 0) {
|
|
||||||
*dst++ = iSeries_Read_Byte(src++);
|
|
||||||
-- NumberOfBytes;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EXPORT_SYMBOL(iSeries_memcpy_fromio);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Look down the chain to find the matching Device Device
|
* Look down the chain to find the matching Device Device
|
||||||
*/
|
*/
|
||||||
|
@ -492,7 +452,7 @@ static inline struct device_node *xlate_iomm_address(
|
||||||
* iSeries_Read_Word = Read Word (16 bit)
|
* iSeries_Read_Word = Read Word (16 bit)
|
||||||
* iSeries_Read_Long = Read Long (32 bit)
|
* iSeries_Read_Long = Read Long (32 bit)
|
||||||
*/
|
*/
|
||||||
u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
|
static u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
|
||||||
{
|
{
|
||||||
u64 BarOffset;
|
u64 BarOffset;
|
||||||
u64 dsa;
|
u64 dsa;
|
||||||
|
@ -519,9 +479,8 @@ u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
|
||||||
|
|
||||||
return (u8)ret.value;
|
return (u8)ret.value;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(iSeries_Read_Byte);
|
|
||||||
|
|
||||||
u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
|
static u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
|
||||||
{
|
{
|
||||||
u64 BarOffset;
|
u64 BarOffset;
|
||||||
u64 dsa;
|
u64 dsa;
|
||||||
|
@ -549,9 +508,8 @@ u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
|
||||||
|
|
||||||
return swab16((u16)ret.value);
|
return swab16((u16)ret.value);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(iSeries_Read_Word);
|
|
||||||
|
|
||||||
u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
|
static u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
|
||||||
{
|
{
|
||||||
u64 BarOffset;
|
u64 BarOffset;
|
||||||
u64 dsa;
|
u64 dsa;
|
||||||
|
@ -579,7 +537,6 @@ u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
|
||||||
|
|
||||||
return swab32((u32)ret.value);
|
return swab32((u32)ret.value);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(iSeries_Read_Long);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Write MM I/O Instructions for the iSeries
|
* Write MM I/O Instructions for the iSeries
|
||||||
|
@ -588,7 +545,7 @@ EXPORT_SYMBOL(iSeries_Read_Long);
|
||||||
* iSeries_Write_Word = Write Word(16 bit)
|
* iSeries_Write_Word = Write Word(16 bit)
|
||||||
* iSeries_Write_Long = Write Long(32 bit)
|
* iSeries_Write_Long = Write Long(32 bit)
|
||||||
*/
|
*/
|
||||||
void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
|
static void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
|
||||||
{
|
{
|
||||||
u64 BarOffset;
|
u64 BarOffset;
|
||||||
u64 dsa;
|
u64 dsa;
|
||||||
|
@ -613,9 +570,8 @@ void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
|
||||||
rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0);
|
rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0);
|
||||||
} while (CheckReturnCode("WWB", DevNode, &retry, rc) != 0);
|
} while (CheckReturnCode("WWB", DevNode, &retry, rc) != 0);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(iSeries_Write_Byte);
|
|
||||||
|
|
||||||
void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress)
|
static void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress)
|
||||||
{
|
{
|
||||||
u64 BarOffset;
|
u64 BarOffset;
|
||||||
u64 dsa;
|
u64 dsa;
|
||||||
|
@ -640,9 +596,8 @@ void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress)
|
||||||
rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0);
|
rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0);
|
||||||
} while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0);
|
} while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(iSeries_Write_Word);
|
|
||||||
|
|
||||||
void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress)
|
static void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress)
|
||||||
{
|
{
|
||||||
u64 BarOffset;
|
u64 BarOffset;
|
||||||
u64 dsa;
|
u64 dsa;
|
||||||
|
@ -667,4 +622,224 @@ void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress)
|
||||||
rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0);
|
rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0);
|
||||||
} while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0);
|
} while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(iSeries_Write_Long);
|
|
||||||
|
extern unsigned char __raw_readb(const volatile void __iomem *addr)
|
||||||
|
{
|
||||||
|
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||||
|
|
||||||
|
return *(volatile unsigned char __force *)addr;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(__raw_readb);
|
||||||
|
|
||||||
|
extern unsigned short __raw_readw(const volatile void __iomem *addr)
|
||||||
|
{
|
||||||
|
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||||
|
|
||||||
|
return *(volatile unsigned short __force *)addr;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(__raw_readw);
|
||||||
|
|
||||||
|
extern unsigned int __raw_readl(const volatile void __iomem *addr)
|
||||||
|
{
|
||||||
|
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||||
|
|
||||||
|
return *(volatile unsigned int __force *)addr;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(__raw_readl);
|
||||||
|
|
||||||
|
extern unsigned long __raw_readq(const volatile void __iomem *addr)
|
||||||
|
{
|
||||||
|
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||||
|
|
||||||
|
return *(volatile unsigned long __force *)addr;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(__raw_readq);
|
||||||
|
|
||||||
|
extern void __raw_writeb(unsigned char v, volatile void __iomem *addr)
|
||||||
|
{
|
||||||
|
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||||
|
|
||||||
|
*(volatile unsigned char __force *)addr = v;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(__raw_writeb);
|
||||||
|
|
||||||
|
extern void __raw_writew(unsigned short v, volatile void __iomem *addr)
|
||||||
|
{
|
||||||
|
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||||
|
|
||||||
|
*(volatile unsigned short __force *)addr = v;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(__raw_writew);
|
||||||
|
|
||||||
|
extern void __raw_writel(unsigned int v, volatile void __iomem *addr)
|
||||||
|
{
|
||||||
|
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||||
|
|
||||||
|
*(volatile unsigned int __force *)addr = v;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(__raw_writel);
|
||||||
|
|
||||||
|
extern void __raw_writeq(unsigned long v, volatile void __iomem *addr)
|
||||||
|
{
|
||||||
|
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||||
|
|
||||||
|
*(volatile unsigned long __force *)addr = v;
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(__raw_writeq);
|
||||||
|
|
||||||
|
int in_8(const volatile unsigned char __iomem *addr)
|
||||||
|
{
|
||||||
|
if (firmware_has_feature(FW_FEATURE_ISERIES))
|
||||||
|
return iSeries_Read_Byte(addr);
|
||||||
|
return __in_8(addr);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(in_8);
|
||||||
|
|
||||||
|
void out_8(volatile unsigned char __iomem *addr, int val)
|
||||||
|
{
|
||||||
|
if (firmware_has_feature(FW_FEATURE_ISERIES))
|
||||||
|
iSeries_Write_Byte(val, addr);
|
||||||
|
else
|
||||||
|
__out_8(addr, val);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(out_8);
|
||||||
|
|
||||||
|
int in_le16(const volatile unsigned short __iomem *addr)
|
||||||
|
{
|
||||||
|
if (firmware_has_feature(FW_FEATURE_ISERIES))
|
||||||
|
return iSeries_Read_Word(addr);
|
||||||
|
return __in_le16(addr);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(in_le16);
|
||||||
|
|
||||||
|
int in_be16(const volatile unsigned short __iomem *addr)
|
||||||
|
{
|
||||||
|
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||||
|
|
||||||
|
return __in_be16(addr);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(in_be16);
|
||||||
|
|
||||||
|
void out_le16(volatile unsigned short __iomem *addr, int val)
|
||||||
|
{
|
||||||
|
if (firmware_has_feature(FW_FEATURE_ISERIES))
|
||||||
|
iSeries_Write_Word(val, addr);
|
||||||
|
else
|
||||||
|
__out_le16(addr, val);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(out_le16);
|
||||||
|
|
||||||
|
void out_be16(volatile unsigned short __iomem *addr, int val)
|
||||||
|
{
|
||||||
|
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||||
|
|
||||||
|
__out_be16(addr, val);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(out_be16);
|
||||||
|
|
||||||
|
unsigned in_le32(const volatile unsigned __iomem *addr)
|
||||||
|
{
|
||||||
|
if (firmware_has_feature(FW_FEATURE_ISERIES))
|
||||||
|
return iSeries_Read_Long(addr);
|
||||||
|
return __in_le32(addr);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(in_le32);
|
||||||
|
|
||||||
|
unsigned in_be32(const volatile unsigned __iomem *addr)
|
||||||
|
{
|
||||||
|
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||||
|
|
||||||
|
return __in_be32(addr);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(in_be32);
|
||||||
|
|
||||||
|
void out_le32(volatile unsigned __iomem *addr, int val)
|
||||||
|
{
|
||||||
|
if (firmware_has_feature(FW_FEATURE_ISERIES))
|
||||||
|
iSeries_Write_Long(val, addr);
|
||||||
|
else
|
||||||
|
__out_le32(addr, val);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(out_le32);
|
||||||
|
|
||||||
|
void out_be32(volatile unsigned __iomem *addr, int val)
|
||||||
|
{
|
||||||
|
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||||
|
|
||||||
|
__out_be32(addr, val);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(out_be32);
|
||||||
|
|
||||||
|
unsigned long in_le64(const volatile unsigned long __iomem *addr)
|
||||||
|
{
|
||||||
|
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||||
|
|
||||||
|
return __in_le64(addr);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(in_le64);
|
||||||
|
|
||||||
|
unsigned long in_be64(const volatile unsigned long __iomem *addr)
|
||||||
|
{
|
||||||
|
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||||
|
|
||||||
|
return __in_be64(addr);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(in_be64);
|
||||||
|
|
||||||
|
void out_le64(volatile unsigned long __iomem *addr, unsigned long val)
|
||||||
|
{
|
||||||
|
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||||
|
|
||||||
|
__out_le64(addr, val);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(out_le64);
|
||||||
|
|
||||||
|
void out_be64(volatile unsigned long __iomem *addr, unsigned long val)
|
||||||
|
{
|
||||||
|
BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
|
||||||
|
|
||||||
|
__out_be64(addr, val);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(out_be64);
|
||||||
|
|
||||||
|
void memset_io(volatile void __iomem *addr, int c, unsigned long n)
|
||||||
|
{
|
||||||
|
if (firmware_has_feature(FW_FEATURE_ISERIES)) {
|
||||||
|
volatile char __iomem *d = addr;
|
||||||
|
|
||||||
|
while (n-- > 0) {
|
||||||
|
iSeries_Write_Byte(c, d++);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
eeh_memset_io(addr, c, n);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(memset_io);
|
||||||
|
|
||||||
|
void memcpy_fromio(void *dest, const volatile void __iomem *src,
|
||||||
|
unsigned long n)
|
||||||
|
{
|
||||||
|
if (firmware_has_feature(FW_FEATURE_ISERIES)) {
|
||||||
|
char *d = dest;
|
||||||
|
const volatile char __iomem *s = src;
|
||||||
|
|
||||||
|
while (n-- > 0) {
|
||||||
|
*d++ = iSeries_Read_Byte(s++);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
eeh_memcpy_fromio(dest, src, n);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(memcpy_fromio);
|
||||||
|
|
||||||
|
void memcpy_toio(volatile void __iomem *dest, const void *src, unsigned long n)
|
||||||
|
{
|
||||||
|
if (firmware_has_feature(FW_FEATURE_ISERIES)) {
|
||||||
|
const char *s = src;
|
||||||
|
volatile char __iomem *d = dest;
|
||||||
|
|
||||||
|
while (n-- > 0) {
|
||||||
|
iSeries_Write_Byte(*s++, d++);
|
||||||
|
}
|
||||||
|
} else
|
||||||
|
eeh_memcpy_toio(dest, src, n);
|
||||||
|
}
|
||||||
|
EXPORT_SYMBOL(memcpy_toio);
|
||||||
|
|
|
@ -59,6 +59,7 @@
|
||||||
#include "irq.h"
|
#include "irq.h"
|
||||||
#include "vpd_areas.h"
|
#include "vpd_areas.h"
|
||||||
#include "processor_vpd.h"
|
#include "processor_vpd.h"
|
||||||
|
#include "it_lp_naca.h"
|
||||||
#include "main_store.h"
|
#include "main_store.h"
|
||||||
#include "call_sm.h"
|
#include "call_sm.h"
|
||||||
#include "call_hpt.h"
|
#include "call_hpt.h"
|
||||||
|
|
|
@ -41,8 +41,8 @@
|
||||||
|
|
||||||
#include <asm/system.h>
|
#include <asm/system.h>
|
||||||
#include <asm/uaccess.h>
|
#include <asm/uaccess.h>
|
||||||
|
#include <asm/prom.h>
|
||||||
#include <asm/iseries/hv_types.h>
|
#include <asm/iseries/hv_types.h>
|
||||||
#include <asm/iseries/it_exp_vpd_panel.h>
|
|
||||||
#include <asm/iseries/hv_lp_event.h>
|
#include <asm/iseries/hv_lp_event.h>
|
||||||
#include <asm/iseries/hv_lp_config.h>
|
#include <asm/iseries/hv_lp_config.h>
|
||||||
#include <asm/iseries/mf.h>
|
#include <asm/iseries/mf.h>
|
||||||
|
@ -116,6 +116,8 @@ static int proc_viopath_show(struct seq_file *m, void *v)
|
||||||
dma_addr_t handle;
|
dma_addr_t handle;
|
||||||
HvLpEvent_Rc hvrc;
|
HvLpEvent_Rc hvrc;
|
||||||
DECLARE_MUTEX_LOCKED(Semaphore);
|
DECLARE_MUTEX_LOCKED(Semaphore);
|
||||||
|
struct device_node *node;
|
||||||
|
const char *sysid;
|
||||||
|
|
||||||
buf = kmalloc(HW_PAGE_SIZE, GFP_KERNEL);
|
buf = kmalloc(HW_PAGE_SIZE, GFP_KERNEL);
|
||||||
if (!buf)
|
if (!buf)
|
||||||
|
@ -143,20 +145,26 @@ static int proc_viopath_show(struct seq_file *m, void *v)
|
||||||
|
|
||||||
buf[HW_PAGE_SIZE-1] = '\0';
|
buf[HW_PAGE_SIZE-1] = '\0';
|
||||||
seq_printf(m, "%s", buf);
|
seq_printf(m, "%s", buf);
|
||||||
seq_printf(m, "AVAILABLE_VETH=%x\n", vlanMap);
|
|
||||||
seq_printf(m, "SRLNBR=%c%c%c%c%c%c%c\n",
|
|
||||||
e2a(xItExtVpdPanel.mfgID[2]),
|
|
||||||
e2a(xItExtVpdPanel.mfgID[3]),
|
|
||||||
e2a(xItExtVpdPanel.systemSerial[1]),
|
|
||||||
e2a(xItExtVpdPanel.systemSerial[2]),
|
|
||||||
e2a(xItExtVpdPanel.systemSerial[3]),
|
|
||||||
e2a(xItExtVpdPanel.systemSerial[4]),
|
|
||||||
e2a(xItExtVpdPanel.systemSerial[5]));
|
|
||||||
|
|
||||||
dma_unmap_single(iSeries_vio_dev, handle, HW_PAGE_SIZE,
|
dma_unmap_single(iSeries_vio_dev, handle, HW_PAGE_SIZE,
|
||||||
DMA_FROM_DEVICE);
|
DMA_FROM_DEVICE);
|
||||||
kfree(buf);
|
kfree(buf);
|
||||||
|
|
||||||
|
seq_printf(m, "AVAILABLE_VETH=%x\n", vlanMap);
|
||||||
|
|
||||||
|
node = of_find_node_by_path("/");
|
||||||
|
sysid = NULL;
|
||||||
|
if (node != NULL)
|
||||||
|
sysid = get_property(node, "system-id", NULL);
|
||||||
|
|
||||||
|
if (sysid == NULL)
|
||||||
|
seq_printf(m, "SRLNBR=<UNKNOWN>\n");
|
||||||
|
else
|
||||||
|
/* Skip "IBM," on front of serial number, see dt.c */
|
||||||
|
seq_printf(m, "SRLNBR=%s\n", sysid + 4);
|
||||||
|
|
||||||
|
of_node_put(node);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -188,7 +188,7 @@ static void __init iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen,
|
||||||
{
|
{
|
||||||
u8 *TagPtr = VpdData;
|
u8 *TagPtr = VpdData;
|
||||||
int DataLen = VpdDataLen - 3;
|
int DataLen = VpdDataLen - 3;
|
||||||
u8 PhbId;
|
u8 PhbId = 0xff;
|
||||||
|
|
||||||
while ((*TagPtr != VpdEndOfAreaTag) && (DataLen > 0)) {
|
while ((*TagPtr != VpdEndOfAreaTag) && (DataLen > 0)) {
|
||||||
int AreaLen = *(TagPtr + 1) + (*(TagPtr + 2) * 256);
|
int AreaLen = *(TagPtr + 1) + (*(TagPtr + 2) * 256);
|
||||||
|
@ -205,15 +205,16 @@ static void __init iSeries_Parse_Vpd(u8 *VpdData, int VpdDataLen,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent,
|
static int __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent,
|
||||||
u8 *frame, char card[4])
|
u8 *frame, char card[4])
|
||||||
{
|
{
|
||||||
|
int status = 0;
|
||||||
int BusVpdLen = 0;
|
int BusVpdLen = 0;
|
||||||
u8 *BusVpdPtr = kmalloc(BUS_VPDSIZE, GFP_KERNEL);
|
u8 *BusVpdPtr = kmalloc(BUS_VPDSIZE, GFP_KERNEL);
|
||||||
|
|
||||||
if (BusVpdPtr == NULL) {
|
if (BusVpdPtr == NULL) {
|
||||||
printk("PCI: Bus VPD Buffer allocation failure.\n");
|
printk("PCI: Bus VPD Buffer allocation failure.\n");
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
BusVpdLen = HvCallPci_getBusVpd(bus, iseries_hv_addr(BusVpdPtr),
|
BusVpdLen = HvCallPci_getBusVpd(bus, iseries_hv_addr(BusVpdPtr),
|
||||||
BUS_VPDSIZE);
|
BUS_VPDSIZE);
|
||||||
|
@ -228,8 +229,10 @@ static void __init iSeries_Get_Location_Code(u16 bus, HvAgentId agent,
|
||||||
goto out_free;
|
goto out_free;
|
||||||
}
|
}
|
||||||
iSeries_Parse_Vpd(BusVpdPtr, BusVpdLen, agent, frame, card);
|
iSeries_Parse_Vpd(BusVpdPtr, BusVpdLen, agent, frame, card);
|
||||||
|
status = 1;
|
||||||
out_free:
|
out_free:
|
||||||
kfree(BusVpdPtr);
|
kfree(BusVpdPtr);
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -246,7 +249,7 @@ void __init iSeries_Device_Information(struct pci_dev *PciDev, int count)
|
||||||
struct device_node *DevNode = PciDev->sysdata;
|
struct device_node *DevNode = PciDev->sysdata;
|
||||||
struct pci_dn *pdn;
|
struct pci_dn *pdn;
|
||||||
u16 bus;
|
u16 bus;
|
||||||
u8 frame;
|
u8 frame = 0;
|
||||||
char card[4];
|
char card[4];
|
||||||
HvSubBusNumber subbus;
|
HvSubBusNumber subbus;
|
||||||
HvAgentId agent;
|
HvAgentId agent;
|
||||||
|
@ -262,10 +265,11 @@ void __init iSeries_Device_Information(struct pci_dev *PciDev, int count)
|
||||||
subbus = pdn->bussubno;
|
subbus = pdn->bussubno;
|
||||||
agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus),
|
agent = ISERIES_PCI_AGENTID(ISERIES_GET_DEVICE_FROM_SUBBUS(subbus),
|
||||||
ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus));
|
ISERIES_GET_FUNCTION_FROM_SUBBUS(subbus));
|
||||||
iSeries_Get_Location_Code(bus, agent, &frame, card);
|
|
||||||
|
|
||||||
printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, Card %4s ",
|
if (iSeries_Get_Location_Code(bus, agent, &frame, card)) {
|
||||||
count, bus, PCI_SLOT(PciDev->devfn), PciDev->vendor,
|
printk("%d. PCI: Bus%3d, Device%3d, Vendor %04X Frame%3d, "
|
||||||
frame, card);
|
"Card %4s 0x%04X\n", count, bus,
|
||||||
printk("0x%04X\n", (int)(PciDev->class >> 8));
|
PCI_SLOT(PciDev->devfn), PciDev->vendor, frame,
|
||||||
|
card, (int)(PciDev->class >> 8));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,16 +38,16 @@ static struct pci_controller *u3_agp, *u3_ht;
|
||||||
static int __init fixup_one_level_bus_range(struct device_node *node, int higher)
|
static int __init fixup_one_level_bus_range(struct device_node *node, int higher)
|
||||||
{
|
{
|
||||||
for (; node != 0;node = node->sibling) {
|
for (; node != 0;node = node->sibling) {
|
||||||
int * bus_range;
|
const int *bus_range;
|
||||||
unsigned int *class_code;
|
const unsigned int *class_code;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
/* For PCI<->PCI bridges or CardBus bridges, we go down */
|
/* For PCI<->PCI bridges or CardBus bridges, we go down */
|
||||||
class_code = (unsigned int *) get_property(node, "class-code", NULL);
|
class_code = get_property(node, "class-code", NULL);
|
||||||
if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
|
if (!class_code || ((*class_code >> 8) != PCI_CLASS_BRIDGE_PCI &&
|
||||||
(*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
|
(*class_code >> 8) != PCI_CLASS_BRIDGE_CARDBUS))
|
||||||
continue;
|
continue;
|
||||||
bus_range = (int *) get_property(node, "bus-range", &len);
|
bus_range = get_property(node, "bus-range", &len);
|
||||||
if (bus_range != NULL && len > 2 * sizeof(int)) {
|
if (bus_range != NULL && len > 2 * sizeof(int)) {
|
||||||
if (bus_range[1] > higher)
|
if (bus_range[1] > higher)
|
||||||
higher = bus_range[1];
|
higher = bus_range[1];
|
||||||
|
@ -66,29 +66,35 @@ static int __init fixup_one_level_bus_range(struct device_node *node, int higher
|
||||||
static void __init fixup_bus_range(struct device_node *bridge)
|
static void __init fixup_bus_range(struct device_node *bridge)
|
||||||
{
|
{
|
||||||
int *bus_range;
|
int *bus_range;
|
||||||
|
struct property *prop;
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
/* Lookup the "bus-range" property for the hose */
|
/* Lookup the "bus-range" property for the hose */
|
||||||
bus_range = (int *) get_property(bridge, "bus-range", &len);
|
prop = of_find_property(bridge, "bus-range", &len);
|
||||||
if (bus_range == NULL || len < 2 * sizeof(int)) {
|
if (prop == NULL || prop->value == NULL || len < 2 * sizeof(int)) {
|
||||||
printk(KERN_WARNING "Can't get bus-range for %s\n",
|
printk(KERN_WARNING "Can't get bus-range for %s\n",
|
||||||
bridge->full_name);
|
bridge->full_name);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
bus_range = (int *)prop->value;
|
||||||
bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]);
|
bus_range[1] = fixup_one_level_bus_range(bridge->child, bus_range[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define U3_AGP_CFA0(devfn, off) \
|
static unsigned long u3_agp_cfa0(u8 devfn, u8 off)
|
||||||
((1 << (unsigned long)PCI_SLOT(dev_fn)) \
|
{
|
||||||
| (((unsigned long)PCI_FUNC(dev_fn)) << 8) \
|
return (1 << (unsigned long)PCI_SLOT(devfn)) |
|
||||||
| (((unsigned long)(off)) & 0xFCUL))
|
((unsigned long)PCI_FUNC(devfn) << 8) |
|
||||||
|
((unsigned long)off & 0xFCUL);
|
||||||
|
}
|
||||||
|
|
||||||
#define U3_AGP_CFA1(bus, devfn, off) \
|
static unsigned long u3_agp_cfa1(u8 bus, u8 devfn, u8 off)
|
||||||
((((unsigned long)(bus)) << 16) \
|
{
|
||||||
|(((unsigned long)(devfn)) << 8) \
|
return ((unsigned long)bus << 16) |
|
||||||
|(((unsigned long)(off)) & 0xFCUL) \
|
((unsigned long)devfn << 8) |
|
||||||
|1UL)
|
((unsigned long)off & 0xFCUL) |
|
||||||
|
1UL;
|
||||||
|
}
|
||||||
|
|
||||||
static unsigned long u3_agp_cfg_access(struct pci_controller* hose,
|
static unsigned long u3_agp_cfg_access(struct pci_controller* hose,
|
||||||
u8 bus, u8 dev_fn, u8 offset)
|
u8 bus, u8 dev_fn, u8 offset)
|
||||||
|
@ -98,9 +104,9 @@ static unsigned long u3_agp_cfg_access(struct pci_controller* hose,
|
||||||
if (bus == hose->first_busno) {
|
if (bus == hose->first_busno) {
|
||||||
if (dev_fn < (11 << 3))
|
if (dev_fn < (11 << 3))
|
||||||
return 0;
|
return 0;
|
||||||
caddr = U3_AGP_CFA0(dev_fn, offset);
|
caddr = u3_agp_cfa0(dev_fn, offset);
|
||||||
} else
|
} else
|
||||||
caddr = U3_AGP_CFA1(bus, dev_fn, offset);
|
caddr = u3_agp_cfa1(bus, dev_fn, offset);
|
||||||
|
|
||||||
/* Uninorth will return garbage if we don't read back the value ! */
|
/* Uninorth will return garbage if we don't read back the value ! */
|
||||||
do {
|
do {
|
||||||
|
@ -182,13 +188,15 @@ static struct pci_ops u3_agp_pci_ops =
|
||||||
u3_agp_write_config
|
u3_agp_write_config
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static unsigned long u3_ht_cfa0(u8 devfn, u8 off)
|
||||||
|
{
|
||||||
|
return (devfn << 8) | off;
|
||||||
|
}
|
||||||
|
|
||||||
#define U3_HT_CFA0(devfn, off) \
|
static unsigned long u3_ht_cfa1(u8 bus, u8 devfn, u8 off)
|
||||||
((((unsigned long)devfn) << 8) | offset)
|
{
|
||||||
#define U3_HT_CFA1(bus, devfn, off) \
|
return u3_ht_cfa0(devfn, off) + (bus << 16) + 0x01000000UL;
|
||||||
(U3_HT_CFA0(devfn, off) \
|
}
|
||||||
+ (((unsigned long)bus) << 16) \
|
|
||||||
+ 0x01000000UL)
|
|
||||||
|
|
||||||
static unsigned long u3_ht_cfg_access(struct pci_controller* hose,
|
static unsigned long u3_ht_cfg_access(struct pci_controller* hose,
|
||||||
u8 bus, u8 devfn, u8 offset)
|
u8 bus, u8 devfn, u8 offset)
|
||||||
|
@ -196,9 +204,9 @@ static unsigned long u3_ht_cfg_access(struct pci_controller* hose,
|
||||||
if (bus == hose->first_busno) {
|
if (bus == hose->first_busno) {
|
||||||
if (PCI_SLOT(devfn) == 0)
|
if (PCI_SLOT(devfn) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
return ((unsigned long)hose->cfg_data) + U3_HT_CFA0(devfn, offset);
|
return ((unsigned long)hose->cfg_data) + u3_ht_cfa0(devfn, offset);
|
||||||
} else
|
} else
|
||||||
return ((unsigned long)hose->cfg_data) + U3_HT_CFA1(bus, devfn, offset);
|
return ((unsigned long)hose->cfg_data) + u3_ht_cfa1(bus, devfn, offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
|
static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||||
|
@ -211,6 +219,9 @@ static int u3_ht_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||||
if (hose == NULL)
|
if (hose == NULL)
|
||||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
|
|
||||||
|
if (offset > 0xff)
|
||||||
|
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||||
|
|
||||||
addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
|
addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
|
||||||
if (!addr)
|
if (!addr)
|
||||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
|
@ -243,6 +254,9 @@ static int u3_ht_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||||
if (hose == NULL)
|
if (hose == NULL)
|
||||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
|
|
||||||
|
if (offset > 0xff)
|
||||||
|
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||||
|
|
||||||
addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
|
addr = u3_ht_cfg_access(hose, bus->number, devfn, offset);
|
||||||
if (!addr)
|
if (!addr)
|
||||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
|
@ -314,12 +328,12 @@ static int __init add_bridge(struct device_node *dev)
|
||||||
int len;
|
int len;
|
||||||
struct pci_controller *hose;
|
struct pci_controller *hose;
|
||||||
char* disp_name;
|
char* disp_name;
|
||||||
int *bus_range;
|
const int *bus_range;
|
||||||
int primary = 1;
|
int primary = 1;
|
||||||
|
|
||||||
DBG("Adding PCI host bridge %s\n", dev->full_name);
|
DBG("Adding PCI host bridge %s\n", dev->full_name);
|
||||||
|
|
||||||
bus_range = (int *) get_property(dev, "bus-range", &len);
|
bus_range = get_property(dev, "bus-range", &len);
|
||||||
if (bus_range == NULL || len < 2 * sizeof(int)) {
|
if (bus_range == NULL || len < 2 * sizeof(int)) {
|
||||||
printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n",
|
printk(KERN_WARNING "Can't get bus-range for %s, assume bus 0\n",
|
||||||
dev->full_name);
|
dev->full_name);
|
||||||
|
|
|
@ -99,8 +99,7 @@ static unsigned long maple_find_nvram_base(void)
|
||||||
static void maple_restart(char *cmd)
|
static void maple_restart(char *cmd)
|
||||||
{
|
{
|
||||||
unsigned int maple_nvram_base;
|
unsigned int maple_nvram_base;
|
||||||
unsigned int maple_nvram_offset;
|
const unsigned int *maple_nvram_offset, *maple_nvram_command;
|
||||||
unsigned int maple_nvram_command;
|
|
||||||
struct device_node *sp;
|
struct device_node *sp;
|
||||||
|
|
||||||
maple_nvram_base = maple_find_nvram_base();
|
maple_nvram_base = maple_find_nvram_base();
|
||||||
|
@ -113,14 +112,12 @@ static void maple_restart(char *cmd)
|
||||||
printk(KERN_EMERG "Maple: Unable to find Service Processor\n");
|
printk(KERN_EMERG "Maple: Unable to find Service Processor\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
maple_nvram_offset = *(unsigned int*) get_property(sp,
|
maple_nvram_offset = get_property(sp, "restart-addr", NULL);
|
||||||
"restart-addr", NULL);
|
maple_nvram_command = get_property(sp, "restart-value", NULL);
|
||||||
maple_nvram_command = *(unsigned int*) get_property(sp,
|
|
||||||
"restart-value", NULL);
|
|
||||||
of_node_put(sp);
|
of_node_put(sp);
|
||||||
|
|
||||||
/* send command */
|
/* send command */
|
||||||
outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset);
|
outb_p(*maple_nvram_command, maple_nvram_base + *maple_nvram_offset);
|
||||||
for (;;) ;
|
for (;;) ;
|
||||||
fail:
|
fail:
|
||||||
printk(KERN_EMERG "Maple: Manual Restart Required\n");
|
printk(KERN_EMERG "Maple: Manual Restart Required\n");
|
||||||
|
@ -129,8 +126,7 @@ static void maple_restart(char *cmd)
|
||||||
static void maple_power_off(void)
|
static void maple_power_off(void)
|
||||||
{
|
{
|
||||||
unsigned int maple_nvram_base;
|
unsigned int maple_nvram_base;
|
||||||
unsigned int maple_nvram_offset;
|
const unsigned int *maple_nvram_offset, *maple_nvram_command;
|
||||||
unsigned int maple_nvram_command;
|
|
||||||
struct device_node *sp;
|
struct device_node *sp;
|
||||||
|
|
||||||
maple_nvram_base = maple_find_nvram_base();
|
maple_nvram_base = maple_find_nvram_base();
|
||||||
|
@ -143,14 +139,12 @@ static void maple_power_off(void)
|
||||||
printk(KERN_EMERG "Maple: Unable to find Service Processor\n");
|
printk(KERN_EMERG "Maple: Unable to find Service Processor\n");
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
maple_nvram_offset = *(unsigned int*) get_property(sp,
|
maple_nvram_offset = get_property(sp, "power-off-addr", NULL);
|
||||||
"power-off-addr", NULL);
|
maple_nvram_command = get_property(sp, "power-off-value", NULL);
|
||||||
maple_nvram_command = *(unsigned int*) get_property(sp,
|
|
||||||
"power-off-value", NULL);
|
|
||||||
of_node_put(sp);
|
of_node_put(sp);
|
||||||
|
|
||||||
/* send command */
|
/* send command */
|
||||||
outb_p(maple_nvram_command, maple_nvram_base + maple_nvram_offset);
|
outb_p(*maple_nvram_command, maple_nvram_base + *maple_nvram_offset);
|
||||||
for (;;) ;
|
for (;;) ;
|
||||||
fail:
|
fail:
|
||||||
printk(KERN_EMERG "Maple: Manual Power-Down Required\n");
|
printk(KERN_EMERG "Maple: Manual Power-Down Required\n");
|
||||||
|
@ -211,7 +205,7 @@ static void __init maple_init_early(void)
|
||||||
static void __init maple_init_IRQ(void)
|
static void __init maple_init_IRQ(void)
|
||||||
{
|
{
|
||||||
struct device_node *root, *np, *mpic_node = NULL;
|
struct device_node *root, *np, *mpic_node = NULL;
|
||||||
unsigned int *opprop;
|
const unsigned int *opprop;
|
||||||
unsigned long openpic_addr = 0;
|
unsigned long openpic_addr = 0;
|
||||||
int naddr, n, i, opplen, has_isus = 0;
|
int naddr, n, i, opplen, has_isus = 0;
|
||||||
struct mpic *mpic;
|
struct mpic *mpic;
|
||||||
|
@ -241,8 +235,7 @@ static void __init maple_init_IRQ(void)
|
||||||
/* Find address list in /platform-open-pic */
|
/* Find address list in /platform-open-pic */
|
||||||
root = of_find_node_by_path("/");
|
root = of_find_node_by_path("/");
|
||||||
naddr = prom_n_addr_cells(root);
|
naddr = prom_n_addr_cells(root);
|
||||||
opprop = (unsigned int *) get_property(root, "platform-open-pic",
|
opprop = get_property(root, "platform-open-pic", &opplen);
|
||||||
&opplen);
|
|
||||||
if (opprop != 0) {
|
if (opprop != 0) {
|
||||||
openpic_addr = of_read_number(opprop, naddr);
|
openpic_addr = of_read_number(opprop, naddr);
|
||||||
has_isus = (opplen > naddr);
|
has_isus = (opplen > naddr);
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
obj-y += setup.o pci.o time.o
|
|
@ -0,0 +1,8 @@
|
||||||
|
#ifndef _PASEMI_PASEMI_H
|
||||||
|
#define _PASEMI_PASEMI_H
|
||||||
|
|
||||||
|
extern unsigned long pas_get_boot_time(void);
|
||||||
|
extern void pas_pci_init(void);
|
||||||
|
extern void pas_pcibios_fixup(void);
|
||||||
|
|
||||||
|
#endif /* _PASEMI_PASEMI_H */
|
|
@ -0,0 +1,198 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2006 PA Semi, Inc
|
||||||
|
*
|
||||||
|
* Authors: Kip Walker, PA Semi
|
||||||
|
* Olof Johansson, PA Semi
|
||||||
|
*
|
||||||
|
* Maintained by: Olof Johansson <olof@lixom.net>
|
||||||
|
*
|
||||||
|
* Based on arch/powerpc/platforms/maple/pci.c
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/pci.h>
|
||||||
|
|
||||||
|
#include <asm/pci-bridge.h>
|
||||||
|
#include <asm/machdep.h>
|
||||||
|
|
||||||
|
#include <asm/ppc-pci.h>
|
||||||
|
|
||||||
|
#define PA_PXP_CFA(bus, devfn, off) (((bus) << 20) | ((devfn) << 12) | (off))
|
||||||
|
|
||||||
|
#define CONFIG_OFFSET_VALID(off) ((off) < 4096)
|
||||||
|
|
||||||
|
static unsigned long pa_pxp_cfg_addr(struct pci_controller *hose,
|
||||||
|
u8 bus, u8 devfn, int offset)
|
||||||
|
{
|
||||||
|
return ((unsigned long)hose->cfg_data) + PA_PXP_CFA(bus, devfn, offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pa_pxp_read_config(struct pci_bus *bus, unsigned int devfn,
|
||||||
|
int offset, int len, u32 *val)
|
||||||
|
{
|
||||||
|
struct pci_controller *hose;
|
||||||
|
unsigned long addr;
|
||||||
|
|
||||||
|
hose = pci_bus_to_host(bus);
|
||||||
|
if (!hose)
|
||||||
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
|
|
||||||
|
if (!CONFIG_OFFSET_VALID(offset))
|
||||||
|
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||||
|
|
||||||
|
addr = pa_pxp_cfg_addr(hose, bus->number, devfn, offset);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note: the caller has already checked that offset is
|
||||||
|
* suitably aligned and that len is 1, 2 or 4.
|
||||||
|
*/
|
||||||
|
switch (len) {
|
||||||
|
case 1:
|
||||||
|
*val = in_8((u8 *)addr);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
*val = in_le16((u16 *)addr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
*val = in_le32((u32 *)addr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return PCIBIOS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int pa_pxp_write_config(struct pci_bus *bus, unsigned int devfn,
|
||||||
|
int offset, int len, u32 val)
|
||||||
|
{
|
||||||
|
struct pci_controller *hose;
|
||||||
|
unsigned long addr;
|
||||||
|
|
||||||
|
hose = pci_bus_to_host(bus);
|
||||||
|
if (!hose)
|
||||||
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
|
|
||||||
|
if (!CONFIG_OFFSET_VALID(offset))
|
||||||
|
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||||
|
|
||||||
|
addr = pa_pxp_cfg_addr(hose, bus->number, devfn, offset);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Note: the caller has already checked that offset is
|
||||||
|
* suitably aligned and that len is 1, 2 or 4.
|
||||||
|
*/
|
||||||
|
switch (len) {
|
||||||
|
case 1:
|
||||||
|
out_8((u8 *)addr, val);
|
||||||
|
(void) in_8((u8 *)addr);
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
out_le16((u16 *)addr, val);
|
||||||
|
(void) in_le16((u16 *)addr);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
out_le32((u32 *)addr, val);
|
||||||
|
(void) in_le32((u32 *)addr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return PCIBIOS_SUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct pci_ops pa_pxp_ops = {
|
||||||
|
pa_pxp_read_config,
|
||||||
|
pa_pxp_write_config,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void __init setup_pa_pxp(struct pci_controller *hose)
|
||||||
|
{
|
||||||
|
hose->ops = &pa_pxp_ops;
|
||||||
|
hose->cfg_data = ioremap(0xe0000000, 0x10000000);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init add_bridge(struct device_node *dev)
|
||||||
|
{
|
||||||
|
struct pci_controller *hose;
|
||||||
|
|
||||||
|
pr_debug("Adding PCI host bridge %s\n", dev->full_name);
|
||||||
|
|
||||||
|
hose = pcibios_alloc_controller(dev);
|
||||||
|
if (!hose)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
hose->first_busno = 0;
|
||||||
|
hose->last_busno = 0xff;
|
||||||
|
|
||||||
|
setup_pa_pxp(hose);
|
||||||
|
|
||||||
|
printk(KERN_INFO "Found PA-PXP PCI host bridge.\n");
|
||||||
|
|
||||||
|
/* Interpret the "ranges" property */
|
||||||
|
/* This also maps the I/O region and sets isa_io/mem_base */
|
||||||
|
pci_process_bridge_OF_ranges(hose, dev, 1);
|
||||||
|
pci_setup_phb_io(hose, 1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void __init pas_pcibios_fixup(void)
|
||||||
|
{
|
||||||
|
struct pci_dev *dev = NULL;
|
||||||
|
|
||||||
|
for_each_pci_dev(dev)
|
||||||
|
pci_read_irq_line(dev);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __init pas_fixup_phb_resources(void)
|
||||||
|
{
|
||||||
|
struct pci_controller *hose, *tmp;
|
||||||
|
|
||||||
|
list_for_each_entry_safe(hose, tmp, &hose_list, list_node) {
|
||||||
|
unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base;
|
||||||
|
hose->io_resource.start += offset;
|
||||||
|
hose->io_resource.end += offset;
|
||||||
|
printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n",
|
||||||
|
hose->global_number,
|
||||||
|
hose->io_resource.start, hose->io_resource.end);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void __init pas_pci_init(void)
|
||||||
|
{
|
||||||
|
struct device_node *np, *root;
|
||||||
|
|
||||||
|
root = of_find_node_by_path("/");
|
||||||
|
if (!root) {
|
||||||
|
printk(KERN_CRIT "pas_pci_init: can't find root "
|
||||||
|
"of device tree\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (np = NULL; (np = of_get_next_child(root, np)) != NULL;)
|
||||||
|
if (np->name && !strcmp(np->name, "pxp") && !add_bridge(np))
|
||||||
|
of_node_get(np);
|
||||||
|
|
||||||
|
of_node_put(root);
|
||||||
|
|
||||||
|
pas_fixup_phb_resources();
|
||||||
|
|
||||||
|
/* Setup the linkage between OF nodes and PHBs */
|
||||||
|
pci_devs_phb_init();
|
||||||
|
|
||||||
|
/* Use the common resource allocation mechanism */
|
||||||
|
pci_probe_only = 1;
|
||||||
|
}
|
|
@ -0,0 +1,188 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2006 PA Semi, Inc
|
||||||
|
*
|
||||||
|
* Authors: Kip Walker, PA Semi
|
||||||
|
* Olof Johansson, PA Semi
|
||||||
|
*
|
||||||
|
* Maintained by: Olof Johansson <olof@lixom.net>
|
||||||
|
*
|
||||||
|
* Based on arch/powerpc/platforms/maple/setup.c
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/config.h>
|
||||||
|
#include <linux/errno.h>
|
||||||
|
#include <linux/kernel.h>
|
||||||
|
#include <linux/delay.h>
|
||||||
|
#include <linux/console.h>
|
||||||
|
|
||||||
|
#include <asm/prom.h>
|
||||||
|
#include <asm/system.h>
|
||||||
|
#include <asm/iommu.h>
|
||||||
|
#include <asm/machdep.h>
|
||||||
|
#include <asm/mpic.h>
|
||||||
|
#include <asm/smp.h>
|
||||||
|
#include <asm/time.h>
|
||||||
|
|
||||||
|
#include "pasemi.h"
|
||||||
|
|
||||||
|
static void pas_restart(char *cmd)
|
||||||
|
{
|
||||||
|
printk("restart unimplemented, looping...\n");
|
||||||
|
for (;;) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pas_power_off(void)
|
||||||
|
{
|
||||||
|
printk("power off unimplemented, looping...\n");
|
||||||
|
for (;;) ;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pas_halt(void)
|
||||||
|
{
|
||||||
|
pas_power_off();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
struct smp_ops_t pas_smp_ops = {
|
||||||
|
.probe = smp_mpic_probe,
|
||||||
|
.message_pass = smp_mpic_message_pass,
|
||||||
|
.kick_cpu = smp_generic_kick_cpu,
|
||||||
|
.setup_cpu = smp_mpic_setup_cpu,
|
||||||
|
.give_timebase = smp_generic_give_timebase,
|
||||||
|
.take_timebase = smp_generic_take_timebase,
|
||||||
|
};
|
||||||
|
#endif /* CONFIG_SMP */
|
||||||
|
|
||||||
|
void __init pas_setup_arch(void)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_SMP
|
||||||
|
/* Setup SMP callback */
|
||||||
|
smp_ops = &pas_smp_ops;
|
||||||
|
#endif
|
||||||
|
/* Lookup PCI hosts */
|
||||||
|
pas_pci_init();
|
||||||
|
|
||||||
|
#ifdef CONFIG_DUMMY_CONSOLE
|
||||||
|
conswitchp = &dummy_con;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
printk(KERN_DEBUG "Using default idle loop\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void iommu_dev_setup_null(struct pci_dev *dev) { }
|
||||||
|
static void iommu_bus_setup_null(struct pci_bus *bus) { }
|
||||||
|
|
||||||
|
static void __init pas_init_early(void)
|
||||||
|
{
|
||||||
|
/* No iommu code yet */
|
||||||
|
ppc_md.iommu_dev_setup = iommu_dev_setup_null;
|
||||||
|
ppc_md.iommu_bus_setup = iommu_bus_setup_null;
|
||||||
|
pci_direct_iommu_init();
|
||||||
|
}
|
||||||
|
|
||||||
|
/* No legacy IO on our parts */
|
||||||
|
static int pas_check_legacy_ioport(unsigned int baseport)
|
||||||
|
{
|
||||||
|
return -ENODEV;
|
||||||
|
}
|
||||||
|
|
||||||
|
static __init void pas_init_IRQ(void)
|
||||||
|
{
|
||||||
|
struct device_node *np;
|
||||||
|
struct device_node *root, *mpic_node;
|
||||||
|
unsigned long openpic_addr;
|
||||||
|
const unsigned int *opprop;
|
||||||
|
int naddr, opplen;
|
||||||
|
struct mpic *mpic;
|
||||||
|
|
||||||
|
mpic_node = NULL;
|
||||||
|
|
||||||
|
for_each_node_by_type(np, "interrupt-controller")
|
||||||
|
if (device_is_compatible(np, "open-pic")) {
|
||||||
|
mpic_node = np;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!mpic_node)
|
||||||
|
for_each_node_by_type(np, "open-pic") {
|
||||||
|
mpic_node = np;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (!mpic_node) {
|
||||||
|
printk(KERN_ERR
|
||||||
|
"Failed to locate the MPIC interrupt controller\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Find address list in /platform-open-pic */
|
||||||
|
root = of_find_node_by_path("/");
|
||||||
|
naddr = prom_n_addr_cells(root);
|
||||||
|
opprop = get_property(root, "platform-open-pic", &opplen);
|
||||||
|
if (!opprop) {
|
||||||
|
printk(KERN_ERR "No platform-open-pic property.\n");
|
||||||
|
of_node_put(root);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
openpic_addr = of_read_number(opprop, naddr);
|
||||||
|
printk(KERN_DEBUG "OpenPIC addr: %lx\n", openpic_addr);
|
||||||
|
of_node_put(root);
|
||||||
|
|
||||||
|
mpic = mpic_alloc(mpic_node, openpic_addr, MPIC_PRIMARY, 0, 0,
|
||||||
|
" PAS-OPIC ");
|
||||||
|
BUG_ON(!mpic);
|
||||||
|
|
||||||
|
mpic_assign_isu(mpic, 0, openpic_addr + 0x10000);
|
||||||
|
mpic_init(mpic);
|
||||||
|
of_node_put(mpic_node);
|
||||||
|
of_node_put(root);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void __init pas_progress(char *s, unsigned short hex)
|
||||||
|
{
|
||||||
|
printk("[%04x] : %s\n", hex, s ? s : "");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Called very early, MMU is off, device-tree isn't unflattened
|
||||||
|
*/
|
||||||
|
static int __init pas_probe(void)
|
||||||
|
{
|
||||||
|
unsigned long root = of_get_flat_dt_root();
|
||||||
|
|
||||||
|
if (!of_flat_dt_is_compatible(root, "PA6T-1682M"))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
hpte_init_native();
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
define_machine(pas) {
|
||||||
|
.name = "PA Semi PA6T-1682M",
|
||||||
|
.probe = pas_probe,
|
||||||
|
.setup_arch = pas_setup_arch,
|
||||||
|
.init_early = pas_init_early,
|
||||||
|
.init_IRQ = pas_init_IRQ,
|
||||||
|
.get_irq = mpic_get_irq,
|
||||||
|
.pcibios_fixup = pas_pcibios_fixup,
|
||||||
|
.restart = pas_restart,
|
||||||
|
.power_off = pas_power_off,
|
||||||
|
.halt = pas_halt,
|
||||||
|
.get_boot_time = pas_get_boot_time,
|
||||||
|
.calibrate_decr = generic_calibrate_decr,
|
||||||
|
.check_legacy_ioport = pas_check_legacy_ioport,
|
||||||
|
.progress = pas_progress,
|
||||||
|
};
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2006 PA Semi, Inc
|
||||||
|
*
|
||||||
|
* Maintained by: Olof Johansson <olof@lixom.net>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* 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
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <linux/config.h>
|
||||||
|
#include <linux/time.h>
|
||||||
|
|
||||||
|
#include <asm/time.h>
|
||||||
|
|
||||||
|
unsigned long __init pas_get_boot_time(void)
|
||||||
|
{
|
||||||
|
/* Let's just return a fake date right now */
|
||||||
|
return mktime(2006, 1, 1, 12, 0, 0);
|
||||||
|
}
|
|
@ -60,7 +60,8 @@ int pmac_has_backlight_type(const char *type)
|
||||||
struct device_node* bk_node = find_devices("backlight");
|
struct device_node* bk_node = find_devices("backlight");
|
||||||
|
|
||||||
if (bk_node) {
|
if (bk_node) {
|
||||||
char *prop = get_property(bk_node, "backlight-control", NULL);
|
const char *prop = get_property(bk_node,
|
||||||
|
"backlight-control", NULL);
|
||||||
if (prop && strncmp(prop, type, strlen(type)) == 0)
|
if (prop && strncmp(prop, type, strlen(type)) == 0)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue