* Re: [PATCH 9/11] celleb: consolidate io-workarounds code
From: Arnd Bergmann @ 2008-03-05 11:43 UTC (permalink / raw)
To: linuxppc-dev; +Cc: paulus
In-Reply-To: <20080305.173755.-1264110031.kouish@swc.toshiba.co.jp>
On Wednesday 05 March 2008, Ishizaki Kou wrote:
> Now, we can use generic io-workarounds mechanism and the workaround
> code for spider-pci. This patch changes Celleb PCI code to use
> spider-pci code.
>
> Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
Acked-by: Arnd Bergmann <arnd@arndb.de>
Removing code is always good, and this one obviously only impacts
celleb, so I'm confident it doesn't hurt on QS20.
^ permalink raw reply
* Re: [PATCH 7/11] celleb: move miscellaneous files for Beat
From: Arnd Bergmann @ 2008-03-05 11:39 UTC (permalink / raw)
To: linuxppc-dev; +Cc: paulus
In-Reply-To: <20080305.173432.84368866.kouish@swc.toshiba.co.jp>
On Wednesday 05 March 2008, Ishizaki Kou wrote:
> This patch moves miscellaneous files for Beat into platforms/cell/.
> All files in this patch are used by celleb-beat only.
>
> Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
Acked-by: Arnd Bergmann <arnd@arndb.de>
if you address my comment to patch 2/11
^ permalink raw reply
* Re: [PATCH 6/11] celleb: move a file for SPU on Beat
From: Arnd Bergmann @ 2008-03-05 11:39 UTC (permalink / raw)
To: linuxppc-dev; +Cc: paulus
In-Reply-To: <20080305.173310.63047261.kouish@swc.toshiba.co.jp>
On Wednesday 05 March 2008, Ishizaki Kou wrote:
> This patch moves SPU support code on Beat into platforms/cell/.
>
> Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
Acked-by: Arnd Bergmann <arnd@arndb.de>
if you address my comment to patch 2/11
^ permalink raw reply
* Re: [PATCH 5/11] celleb: move files for Beat mmu and iommu
From: Arnd Bergmann @ 2008-03-05 11:38 UTC (permalink / raw)
To: linuxppc-dev; +Cc: paulus
In-Reply-To: <20080305.173059.-1962665427.kouish@swc.toshiba.co.jp>
On Wednesday 05 March 2008, Ishizaki Kou wrote:
> This patch moves files for mmu and iommu on Beat into platforms/cell/.
> All files in this patch are used by celleb-beat only.
>
> Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
Acked-by: Arnd Bergmann <arnd@arndb.de>
if you address my comment to patch 2/11
^ permalink raw reply
* Re: [PATCH 4/11] celleb: move files for Beat hvcall interfaces
From: Arnd Bergmann @ 2008-03-05 11:38 UTC (permalink / raw)
To: linuxppc-dev; +Cc: paulus
In-Reply-To: <20080305.172751.-494090812.kouish@swc.toshiba.co.jp>
On Wednesday 05 March 2008, Ishizaki Kou wrote:
> This patch moves files for Beat hvcall interfaces into platforms/cell/.
> All files in this patch are used by celleb-beat only.
>
> Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
Acked-by: Arnd Bergmann <arnd@arndb.de>
if you address my comment to patch 2/11
^ permalink raw reply
* Re: [PATCH 3/11] celleb: move the SCC related code for celleb
From: Arnd Bergmann @ 2008-03-05 11:37 UTC (permalink / raw)
To: linuxppc-dev; +Cc: paulus
In-Reply-To: <20080305.172602.-345488266.kouish@swc.toshiba.co.jp>
On Wednesday 05 March 2008, Ishizaki Kou wrote:
> This patch moves the SCC (Super Companion Chip) related code for celleb
> into platforms/cell/.
> All files in this patch are used by celleb-beat and celleb-native commonly.
>
> Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
Acked-by: Arnd Bergmann <arnd@arndb.de>
if you address my comment to patch 2/11
^ permalink raw reply
* Re: [PATCH 2/11] celleb: move the base part for celleb support
From: Arnd Bergmann @ 2008-03-05 11:36 UTC (permalink / raw)
To: linuxppc-dev; +Cc: paulus
In-Reply-To: <20080305.172345.-1625872818.kouish@swc.toshiba.co.jp>
T24gV2VkbmVzZGF5IDA1IE1hcmNoIDIwMDgsIElzaGl6YWtpIEtvdSB3cm90ZToKPiBUaGlzIHBh
dGNoIG1vdmVzIHRoZSBiYXNlIGNvZGUgZm9yIGNlbGxlYiBzdXBwb3J0IGludG8gcGxhdGZvcm1z
L2NlbGwvLgo+IEFsbCBmaWxlcyBpbiB0aGlzIHBhdGNoIGFyZSB1c2VkIGJ5IGNlbGxlYi1iZWF0
IGFuZCBjZWxsZWItbmF0aXZlIGNvbW1vbmx5LgoKTW92aW5nIGFyb3VuZCB0aGUgZmlsZXMgdGhp
cyB3YXkgaXMgZ29vZCwgYnV0Cgo+ICsrKyBiL2FyY2gvcG93ZXJwYy9wbGF0Zm9ybXMvY2VsbC9N
YWtlZmlsZaCgoKCgoDIwMDgtMDMtMDQgMTQ6MDA6MjguMDAwMDAwMDAwICArMDkwMCAKPiBAQCAt
MjYsMyArMjYsMjAgQEAKPiCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg
IKAgc3B1ZnMvCj4goAo+IKBvYmotJChDT05GSUdfUENJX01TSSmgoKCgoKCgoKCgoKCgoKCgoKAr
PSBheG9uX21zaS5vCj4gKwo+ICsKPiArIyBjZWxsZWIgc3R1ZmYKPiAraWZlcSAoJChDT05GSUdf
UFBDX0NFTExFQikseSkKPiArb2JqLXmgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg
Kz0gY2VsbGViX3NldHVwLm8gXAo+ICugoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg
oKCgoKAgoCBjZWxsZWJfcGNpLm8gY2VsbGViX3NjY19lcGNpLm8gXAo+ICugoKCgoKCgoKCgoKCg
oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKAgoCBjZWxsZWJfc2NjX3BjaWV4Lm8gXAo+ICugoKCg
oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKAgoCBjZWxsZWJfc2NjX3VoYy5vIFwK
PiAroKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgIKAgYmVhdC5vIGJlYXRf
aHRhYi5vIGJlYXRfaHZDYWxsLm8gXAo+ICugoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCg
oKCgoKCgoKAgoCBiZWF0X2ludGVycnVwdC5vIGJlYXRfaW9tbXUubyBcCj4gK6CgoKCgoKCgoKCg
oKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoKCgoCCgIGlvLXdvcmthcm91bmRzLm8gc3BpZGVyLXBj
aS5vCj4gKwo+ICtvYmotJChDT05GSUdfU01QKaCgoKCgoKCgoKCgoKCgoKCgoKCgoKArPSBiZWF0
X3NtcC5vCj4gK29iai0kKENPTkZJR19QUENfVURCR19CRUFUKaCgoKCgoKCgoKCgoCs9IGJlYXRf
dWRiZy5vCj4gK29iai0kKENPTkZJR19TRVJJQUxfVFhYOSmgoKCgoKCgoKCgoKCgoCs9IGNlbGxl
Yl9zY2Nfc2lvLm8KPiArb2JqLSQoQ09ORklHX1NQVV9CQVNFKaCgoKCgoKCgoKCgoKCgoKCgKz0g
YmVhdF9zcHVfcHJpdjEubwo+ICtlbmRpZgoKVGhpcyBsb29rcyBsaWtlIHlvdSBhcmUgcmVmZXJl
bmNpbmcgZmlsZXMgaW4gdGhlIE1ha2VmaWxlIHRoYXQgYXJlIG1vdmVkCmluIHRoZSBsYXRlciBw
YXRjaGVzLiBJbiBvcmRlciB0byBtYWtlIHRoZSBnaXQtYmlzZWN0IHdvcmsgY29ycmVjdGx5Cm9u
IHRoZSBrZXJuZWwgYWZ0ZXIgdGhlIHBhdGNoZXMgYXJlIGFwcGxpZWQsIEknZCBzdWdnZXN0IGVp
dGhlciBtb3ZpbmcKYWxsIGZpbGVzIGF0IG9uY2UsIG9yIHRvIG1vZGlmeSB0aGUgTWFrZWZpbGUg
aW4gZXZlcnkgc3RlcCBvZiB0aGUgd2F5CnNvIHRoYXQgdGhlIGtlcm5lbCBzdGlsbCBidWlsZHMu
CgoJQXJuZCA8PjwK
^ permalink raw reply
* Re: [PATCH 1/11] celleb: coding style cleanup
From: Arnd Bergmann @ 2008-03-05 11:32 UTC (permalink / raw)
To: linuxppc-dev; +Cc: paulus
In-Reply-To: <20080305.172143.-1350505489.kouish@swc.toshiba.co.jp>
On Wednesday 05 March 2008, Ishizaki Kou wrote:
> Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
Acked-by: Arnd Bergmann <arnd@arndb.de>
all changes in here look right, and they don't change the generated
code.
^ permalink raw reply
* Re: [PATCH 0/11] celleb: patchset for 2.6.26
From: Arnd Bergmann @ 2008-03-05 11:31 UTC (permalink / raw)
To: linuxppc-dev; +Cc: paulus
In-Reply-To: <20080305.172000.-1300537299.kouish@swc.toshiba.co.jp>
On Wednesday 05 March 2008, Ishizaki Kou wrote:
> This is a patchset for 2.6.26 which contains following changes:
>=20
> - cleanup =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
[PATCH 1/11]
> - move celleb files into platforms/cell/ =A0[PATCH 2/11]..[PATCH 7/11]
> - consolidate io-workarounds code =A0 =A0 =A0 =A0 [PATCH 8/11]..[PATCH 9/=
11]
> - add support for celleb PCI Express =A0 =A0 =A0[PATCH 10/11]
> - bug fix =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0=
[PATCH 11/11]
>=20
> Consolidating io-workarounds code changes the code to support
> CellBlade PCI. Please test it because I don't have any access to
> CellBlade.
Thanks for your patches, the first look I had at them left a very
good impression with your work. I'll send individual acks when
I'm confident enough with them to work on QS20.
Arnd <><
^ permalink raw reply
* Re: [PATCH] ehea: Fix missing Kconfig dependency
From: Jeff Garzik @ 2008-03-05 11:29 UTC (permalink / raw)
To: Thomas Klein
Cc: Jan-Bernd Themann, netdev, linux-kernel, linux-ppc,
Christoph Raisch, Stefan Roscher
In-Reply-To: <200803031352.06322.osstklei@de.ibm.com>
Thomas Klein wrote:
> Fixed Kconfig: ehea driver requires sparse mem
>
> Signed-off-by: Thomas Klein <tklein@de.ibm.com>
>
> ---
> diff -Nurp linux-2.6.25-rc3.org/drivers/net/Kconfig linux-2.6.25-rc3/drivers/net/Kconfig
> --- linux-2.6.25-rc3.org/drivers/net/Kconfig 2008-02-24 22:25:54.000000000 +0100
> +++ linux-2.6.25-rc3/drivers/net/Kconfig 2008-03-03 13:36:48.000000000 +0100
> @@ -2513,7 +2513,7 @@ config CHELSIO_T3
>
> config EHEA
> tristate "eHEA Ethernet support"
> - depends on IBMEBUS && INET
> + depends on IBMEBUS && INET && SPARSEMEM
> select INET_LRO
> ---help---
applied
^ permalink raw reply
* RE: I2S driver
From: Angelo @ 2008-03-05 10:45 UTC (permalink / raw)
To: Pedro Luis D. L.
In-Reply-To: <BLU106-W11BB87023EFF6EED3D8E4DCA110@phx.gbl>
[-- Attachment #1: Type: text/plain, Size: 298 bytes --]
Pedro wrote:
>Which library do you mean? I don't understand, sorry.
In your previous mail (with code), each lines with an "#include " don't show the name of header file.
thanks
---------------------------------
L'email della prossima generazione? Puoi averla con la Nuova Yahoo! Mail
[-- Attachment #2: Type: text/html, Size: 472 bytes --]
^ permalink raw reply
* Re: [PATCH] math-emu: delete PowerPC old math-emu headers
From: Benjamin Herrenschmidt @ 2008-03-05 10:44 UTC (permalink / raw)
To: Liu Yu; +Cc: linuxppc-dev
In-Reply-To: <12047077481825-git-send-email-Yu.Liu@freescale.com>
On Wed, 2008-03-05 at 17:02 +0800, Liu Yu wrote:
> Use common headers as a replacement.
> The Common headers are located in "include/math-emu/",
> they are used by multiple platforms such as s390, sparc, alpha.
>
> As the common headers have more developers,
> they are more popular and more stable.
>
> In fact, PowerPC old math-emu headers cannot handle float point
> exceptions exactly while the common headers can.
That sounds like an excellent idea. However, were you able to run some
kind of test suite to verify that the emulation works properly ?
Cheers,
Ben.
^ permalink raw reply
* RE: I2S driver
From: Pedro Luis D. L. @ 2008-03-05 10:09 UTC (permalink / raw)
To: linuxppc-embedded
In-Reply-To: <538035.10329.qm@web23104.mail.ird.yahoo.com>
Angelo wrote:
> Thanks for code.
> But why i can't see library?
Which library do you mean? I don't understand, sorry.
=20
>>After the module I send you also the code from another module that>establ=
ishes PSC as I2S configuration. Clocks where adjusted to send>the audio dat=
a also at 44.1 Khz as fine tunned as possible due to>communication requirem=
ents of the attached DAC in that hardware.
> You'll send me another code?
This code was already in my previous email. After "------------------------=
-------------------" at the end of the email. Check it again, hehehe.
> And what about my file lite5200b.dts?
> I must enable some like this?
> // PSC3 in CODEC mode example
> //i2s@2400 { // PSC3
> // device_type =3D "sound";
> // compatible =3D "mpc5200b-psc-i2s";//not 5200 compatible
> // cell-index =3D ;
> // reg =3D ;
> // interrupts =3D ;
> // interrupt-parent =3D <&mpc5200_pic>;
> //};
I didn't need it. :-)
>=20
> ________________________________
> L'email della prossima generazione? Puoi averla con la Nuova Yahoo! Mail
_________________________________________________________________
Tecnolog=EDa, moda, motor, viajes,=85suscr=EDbete a nuestros boletines para=
estar siempre a la =FAltima
http://newsletters.msn.com/hm/maintenanceeses.asp?L=3DES&C=3DES&P=3DWCMaint=
enance&Brand=3DWL&RU=3Dhttp%3a%2f%2fmail.live.com=
^ permalink raw reply
* RE: Virtual device hdlc0 asks to que packet!
From: Joakim Tjernlund @ 2008-03-05 10:04 UTC (permalink / raw)
To: rmcguire; +Cc: linuxppc-embedded
In-Reply-To: <002801c87e9c$f57e4430$6405a8c0@absolut>
On Wed, 2008-03-05 at 00:43 -0800, Russell McGuire wrote:
> Jocke,
>
> I wonder how one change this? I don't remember any of the API calls
> referencing this, so maybe the default to 1000? Or perhaps that is protocol
> specific. I will hunt through some of Freescale's Ethernet drivers and see
> if I can't find anything.
default is 1000 for ethernet.
See tx_queue_len in net/ethernet/eth.c,
ether_setup(struct net_device *dev)
Maybe you can find out from there.
>
> I know that inside the driver, I have 32 RX, and 32 TX buffers <buffer
> descriptors> available. There needs to be some smarter way to manage it
> though than raw numbers. Large file transfers, if they are cached, can
> easily over flow any number of buffers.
>
> Thanks for the note.
>
> -Russ
>
> > -----Original Message-----
> > From: Joakim Tjernlund [mailto:joakim.tjernlund@transmode.se]
> > Sent: Wednesday, March 05, 2008 12:12 AM
> > To: rmcguire@videopresence.com
> > Cc: linuxppc-embedded@ozlabs.org
> > Subject: Re: Virtual device hdlc0 asks to que packet!
> >
> >
> > On Tue, 2008-03-04 at 15:33 -0800, Russell McGuire wrote:
> > > All,
> > >
> > > Background MPC8360, using a T1 PHY as an HDLC device.
> > >
> > > Developing my hdlc driver, and was writing a simple send utility. To
> > test it
> > > out. Things seem well when I had massive delays in between the write()
> > or
> > > sendot(), and I was able to attain 100+Kbytes/sec. However, when I
> > replaced
> > > the simple usleeps(xxx) with select statements, suddenly I started
> > getting a
> > > ton of these messages.
> > >
> > > "Virtual device hdlc0 asks to que packet!"
> > >
> > > Along with dropped or non-sent data.
> > >
> > > In my driver I am tracking the available TX buffers, and issue a
> > > netif_stop_que() statement inside the start_xmit() call, with a
> > > corresponding netif_wake_que() in the tx_handler.
> > >
> > > Is there something else that needs to be done in order to make a select
> > > statement wait for the socket to not be busy? It seems that it always
> > > returns immediately with no timeout.
> > >
> > > I guess the other pieces of the scenario are as follows:
> > >
> > > * Using 'sethdlc hdlc0 hdlc' for the mode, so no IP stack is used.
> > > * Opening the socket to the hdlc device directly to the device itself,
> > i.e.
> > > no port number socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
> > >
> > > I have used both sendto() and write() to pass data down, and they both
> > > return as if all the data has been sent, i.e. I never get an error.
> > >
> > > -Russ
> >
> > When playing with your driver I noticed that the hdlc interfaces had
> > txqueuelen:0
> > Normal eth interfaces has txqueuelen:1000. Maybe you need to add a
> > txqueue to the hdlc interfaces?
> >
> > Jocke
> >
> > PS.
> > The driver seems to work now, I get both TX and RX IRQs now.
>
>
^ permalink raw reply
* RE: [PATCH] math-emu: delete PowerPC old math-emu headers
From: Liu Yu @ 2008-03-05 8:57 UTC (permalink / raw)
To: Liu Yu, linuxppc-dev
In-Reply-To: <12047077481825-git-send-email-Yu.Liu@freescale.com>
Sorry. I forgot to add the serial number.
The three math-emu patches are in the same serial.
> -----Original Message-----
> From: Liu Yu=20
> Sent: Wednesday, March 05, 2008 5:02 PM
> To: linuxppc-dev@ozlabs.org
> Cc: Liu Yu
> Subject: [PATCH] math-emu: delete PowerPC old math-emu headers
>=20
> Use common headers as a replacement.
> The Common headers are located in "include/math-emu/",
> they are used by multiple platforms such as s390, sparc, alpha.
>=20
> As the common headers have more developers,
> they are more popular and more stable.
>=20
> In fact, PowerPC old math-emu headers cannot handle float point
> exceptions exactly while the common headers can.
>=20
^ permalink raw reply
* [PATCH] math-emu: modify the sfp-machine.h to fit the new interface of common math-emu headers
From: Liu Yu @ 2008-03-05 9:02 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Liu Yu
In-Reply-To: <12047077481825-git-send-email-Yu.Liu@freescale.com>
Signed-off-by: Liu Yu <Yu.Liu@freescale.com>
---
include/asm-powerpc/sfp-machine.h | 217 +++++++++++++------------------------
1 files changed, 75 insertions(+), 142 deletions(-)
diff --git a/include/asm-powerpc/sfp-machine.h b/include/asm-powerpc/sfp-machine.h
index 4b17d83..5dac9cd 100644
--- a/include/asm-powerpc/sfp-machine.h
+++ b/include/asm-powerpc/sfp-machine.h
@@ -45,159 +45,46 @@
* gcc's longlong.h is useful.
*/
-/* We need to know how to multiply and divide. If the host word size
- * is >= 2*fracbits you can use FP_MUL_MEAT_n_imm(t,R,X,Y) which
- * codes the multiply with whatever gcc does to 'a * b'.
- * _FP_MUL_MEAT_n_wide(t,R,X,Y,f) is used when you have an asm
- * function that can multiply two 1W values and get a 2W result.
- * Otherwise you're stuck with _FP_MUL_MEAT_n_hard(t,R,X,Y) which
- * does bitshifting to avoid overflow.
- * For division there is FP_DIV_MEAT_n_imm(t,R,X,Y,f) for word size
- * >= 2*fracbits, where f is either _FP_DIV_HELP_imm or
- * _FP_DIV_HELP_ldiv (see op-1.h).
- * _FP_DIV_MEAT_udiv() is if you have asm to do 2W/1W => (1W, 1W).
- * [GCC and glibc have longlong.h which has the asm macro udiv_qrnnd
- * to do this.]
- * In general, 'n' is the number of words required to hold the type,
- * and 't' is either S, D or Q for single/double/quad.
- * -- PMM
- */
-/* Example: SPARC64:
- * #define _FP_MUL_MEAT_S(R,X,Y) _FP_MUL_MEAT_1_imm(S,R,X,Y)
- * #define _FP_MUL_MEAT_D(R,X,Y) _FP_MUL_MEAT_1_wide(D,R,X,Y,umul_ppmm)
- * #define _FP_MUL_MEAT_Q(R,X,Y) _FP_MUL_MEAT_2_wide(Q,R,X,Y,umul_ppmm)
- *
- * #define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_imm(S,R,X,Y,_FP_DIV_HELP_imm)
- * #define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_1_udiv(D,R,X,Y)
- * #define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_2_udiv_64(Q,R,X,Y)
- *
- * Example: i386:
- * #define _FP_MUL_MEAT_S(R,X,Y) _FP_MUL_MEAT_1_wide(S,R,X,Y,_i386_mul_32_64)
- * #define _FP_MUL_MEAT_D(R,X,Y) _FP_MUL_MEAT_2_wide(D,R,X,Y,_i386_mul_32_64)
- *
- * #define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv(S,R,X,Y,_i386_div_64_32)
- * #define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv_64(D,R,X,Y)
- */
-
-#define _FP_MUL_MEAT_S(R,X,Y) _FP_MUL_MEAT_1_wide(S,R,X,Y,umul_ppmm)
-#define _FP_MUL_MEAT_D(R,X,Y) _FP_MUL_MEAT_2_wide(D,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_S(R,X,Y) \
+ _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm)
+#define _FP_MUL_MEAT_D(R,X,Y) \
+ _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm)
#define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv(S,R,X,Y)
-#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv_64(D,R,X,Y)
+#define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y)
/* These macros define what NaN looks like. They're supposed to expand to
* a comma-separated set of 32bit unsigned ints that encode NaN.
*/
-#define _FP_NANFRAC_S _FP_QNANBIT_S
-#define _FP_NANFRAC_D _FP_QNANBIT_D, 0
-#define _FP_NANFRAC_Q _FP_QNANBIT_Q, 0, 0, 0
+#define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1)
+#define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1), -1
+#define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1
+#define _FP_NANSIGN_S 0
+#define _FP_NANSIGN_D 0
+#define _FP_NANSIGN_Q 0
#define _FP_KEEPNANFRACP 1
-/* This macro appears to be called when both X and Y are NaNs, and
- * has to choose one and copy it to R. i386 goes for the larger of the
- * two, sparc64 just picks Y. I don't understand this at all so I'll
- * go with sparc64 because it's shorter :-> -- PMM
+/*
+ * If one NaN is signaling and the other is not,
+ * we choose that one, otherwise we choose X.
*/
-#define _FP_CHOOSENAN(fs, wc, R, X, Y) \
- do { \
- R##_s = Y##_s; \
- _FP_FRAC_COPY_##wc(R,Y); \
- R##_c = FP_CLS_NAN; \
- } while (0)
-
-
-extern void fp_unpack_d(long *, unsigned long *, unsigned long *,
- long *, long *, void *);
-extern int fp_pack_d(void *, long, unsigned long, unsigned long, long, long);
-extern int fp_pack_ds(void *, long, unsigned long, unsigned long, long, long);
-
-#define __FP_UNPACK_RAW_1(fs, X, val) \
- do { \
- union _FP_UNION_##fs *_flo = \
- (union _FP_UNION_##fs *)val; \
- \
- X##_f = _flo->bits.frac; \
- X##_e = _flo->bits.exp; \
- X##_s = _flo->bits.sign; \
- } while (0)
-
-#define __FP_UNPACK_RAW_2(fs, X, val) \
- do { \
- union _FP_UNION_##fs *_flo = \
- (union _FP_UNION_##fs *)val; \
- \
- X##_f0 = _flo->bits.frac0; \
- X##_f1 = _flo->bits.frac1; \
- X##_e = _flo->bits.exp; \
- X##_s = _flo->bits.sign; \
+#define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \
+ do { \
+ if ((_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs) \
+ && !(_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)) \
+ { \
+ R##_s = Y##_s; \
+ _FP_FRAC_COPY_##wc(R,Y); \
+ } \
+ else \
+ { \
+ R##_s = X##_s; \
+ _FP_FRAC_COPY_##wc(R,X); \
+ } \
+ R##_c = FP_CLS_NAN; \
} while (0)
-#define __FP_UNPACK_S(X,val) \
- do { \
- __FP_UNPACK_RAW_1(S,X,val); \
- _FP_UNPACK_CANONICAL(S,1,X); \
- } while (0)
-
-#define __FP_UNPACK_D(X,val) \
- fp_unpack_d(&X##_s, &X##_f1, &X##_f0, &X##_e, &X##_c, val)
-
-#define __FP_PACK_RAW_1(fs, val, X) \
- do { \
- union _FP_UNION_##fs *_flo = \
- (union _FP_UNION_##fs *)val; \
- \
- _flo->bits.frac = X##_f; \
- _flo->bits.exp = X##_e; \
- _flo->bits.sign = X##_s; \
- } while (0)
-
-#define __FP_PACK_RAW_2(fs, val, X) \
- do { \
- union _FP_UNION_##fs *_flo = \
- (union _FP_UNION_##fs *)val; \
- \
- _flo->bits.frac0 = X##_f0; \
- _flo->bits.frac1 = X##_f1; \
- _flo->bits.exp = X##_e; \
- _flo->bits.sign = X##_s; \
- } while (0)
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-
-#define __FPU_FPSCR (current->thread.fpscr.val)
-
-/* We only actually write to the destination register
- * if exceptions signalled (if any) will not trap.
- */
-#define __FPU_ENABLED_EXC \
-({ \
- (__FPU_FPSCR >> 3) & 0x1f; \
-})
-
-#define __FPU_TRAP_P(bits) \
- ((__FPU_ENABLED_EXC & (bits)) != 0)
-
-#define __FP_PACK_S(val,X) \
-({ int __exc = _FP_PACK_CANONICAL(S,1,X); \
- if(!__exc || !__FPU_TRAP_P(__exc)) \
- __FP_PACK_RAW_1(S,val,X); \
- __exc; \
-})
-
-#define __FP_PACK_D(val,X) \
- fp_pack_d(val, X##_s, X##_f1, X##_f0, X##_e, X##_c)
-
-#define __FP_PACK_DS(val,X) \
- fp_pack_ds(val, X##_s, X##_f1, X##_f0, X##_e, X##_c)
-
-/* Obtain the current rounding mode. */
-#define FP_ROUNDMODE \
-({ \
- __FPU_FPSCR & 0x3; \
-})
-
/* the asm fragments go here: all these are taken from glibc-2.0.5's
* stdlib/longlong.h
*/
@@ -359,13 +246,49 @@ extern int fp_pack_ds(void *, long, unsigned long, unsigned long, long, long);
#define __BYTE_ORDER __LITTLE_ENDIAN
#endif
+#include <linux/kernel.h>
+#include <linux/sched.h>
+
+#define __FPU_FPSCR (current->thread.fpscr.val)
+
+/* We only actually write to the destination register
+ * if exceptions signalled (if any) will not trap.
+ */
+#define __FPU_ENABLED_EXC \
+({ \
+ (__FPU_FPSCR >> 3) & 0x1f; \
+})
+
+#define __FPU_TRAP_P(bits) \
+ ((__FPU_ENABLED_EXC & (bits)) != 0)
+
+#define __FP_PACK_DS(val,X) \
+ do { \
+ FP_DECL_S(__X); \
+ FP_CONV(S, D, 1, 2, __X, X); \
+ _FP_PACK_CANONICAL(S, 1, __X); \
+ if (!FP_INHIBIT_RESULTS) { \
+ _FP_UNPACK_CANONICAL(S, 1, __X); \
+ FP_CONV(D, S, 2, 1, X, __X); \
+ _FP_PACK_CANONICAL(D, 2, X); \
+ if (!FP_INHIBIT_RESULTS) { \
+ _FP_PACK_RAW_2_P(D,val,X); \
+ } \
+ } \
+ } while (0)
+
+/* Obtain the current rounding mode. */
+#define FP_ROUNDMODE \
+({ \
+ __FPU_FPSCR & 0x3; \
+})
+
/* Exception flags. */
#define EFLAG_INVALID (1 << (31 - 2))
#define EFLAG_OVERFLOW (1 << (31 - 3))
#define EFLAG_UNDERFLOW (1 << (31 - 4))
#define EFLAG_DIVZERO (1 << (31 - 5))
#define EFLAG_INEXACT (1 << (31 - 6))
-
#define EFLAG_VXSNAN (1 << (31 - 7))
#define EFLAG_VXISI (1 << (31 - 8))
#define EFLAG_VXIDI (1 << (31 - 9))
@@ -375,3 +298,13 @@ extern int fp_pack_ds(void *, long, unsigned long, unsigned long, long, long);
#define EFLAG_VXSOFT (1 << (31 - 21))
#define EFLAG_VXSQRT (1 << (31 - 22))
#define EFLAG_VXCVI (1 << (31 - 23))
+
+#define FP_EX_INVALID EFLAG_INVALID
+#define FP_EX_DIVZERO EFLAG_DIVZERO
+#define FP_EX_OVERFLOW EFLAG_OVERFLOW
+#define FP_EX_UNDERFLOW EFLAG_UNDERFLOW
+#define FP_EX_INEXACT EFLAG_INEXACT
+#define FP_INHIBIT_RESULTS (!FP_CUR_EXCEPTIONS || !__FPU_TRAP_P(FP_CUR_EXCEPTIONS))
+
+#define FP_TRAPPING_EXCEPTIONS __FPU_ENABLED_EXC
+
--
1.5.2
^ permalink raw reply related
* [PATCH] math-emu: use new interface of common math-emu headers in PowerPC math-emu C file
From: Liu Yu @ 2008-03-05 9:02 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Liu Yu
In-Reply-To: <12047077492663-git-send-email-Yu.Liu@freescale.com>
Signed-off-by: Liu Yu <Yu.Liu@freescale.com>
---
arch/powerpc/math-emu/Makefile | 2 +-
arch/powerpc/math-emu/fadd.c | 16 +++++++++-------
arch/powerpc/math-emu/fadds.c | 17 +++++++++--------
arch/powerpc/math-emu/fcmpo.c | 22 +++++++++++++---------
arch/powerpc/math-emu/fcmpu.c | 20 +++++++++++++-------
arch/powerpc/math-emu/fctiw.c | 9 +++++----
arch/powerpc/math-emu/fctiwz.c | 9 +++++----
arch/powerpc/math-emu/fdiv.c | 22 +++++++++-------------
arch/powerpc/math-emu/fdivs.c | 25 ++++++++++---------------
arch/powerpc/math-emu/fmadd.c | 19 ++++++++++---------
arch/powerpc/math-emu/fmadds.c | 21 +++++++++++----------
arch/powerpc/math-emu/fmsub.c | 19 ++++++++++---------
arch/powerpc/math-emu/fmsubs.c | 21 +++++++++++----------
arch/powerpc/math-emu/fmul.c | 15 ++++++++-------
arch/powerpc/math-emu/fmuls.c | 17 +++++++++--------
arch/powerpc/math-emu/fnmadd.c | 19 ++++++++++---------
arch/powerpc/math-emu/fnmadds.c | 21 +++++++++++----------
arch/powerpc/math-emu/fnmsub.c | 19 ++++++++++---------
arch/powerpc/math-emu/fnmsubs.c | 21 +++++++++++----------
arch/powerpc/math-emu/frsp.c | 12 +++++++-----
arch/powerpc/math-emu/fsel.c | 9 +++++----
arch/powerpc/math-emu/fsqrt.c | 15 ++++++++-------
arch/powerpc/math-emu/fsqrts.c | 17 +++++++++--------
arch/powerpc/math-emu/fsub.c | 15 ++++++++-------
arch/powerpc/math-emu/fsubs.c | 17 +++++++++--------
arch/powerpc/math-emu/lfd.c | 4 ++--
arch/powerpc/math-emu/lfs.c | 12 +++++++-----
arch/powerpc/math-emu/math.c | 4 ++--
arch/powerpc/math-emu/mcrfs.c | 2 +-
arch/powerpc/math-emu/mffs.c | 2 +-
arch/powerpc/math-emu/mtfsb0.c | 2 +-
arch/powerpc/math-emu/mtfsb1.c | 2 +-
arch/powerpc/math-emu/mtfsf.c | 2 +-
arch/powerpc/math-emu/mtfsfi.c | 2 +-
arch/powerpc/math-emu/stfs.c | 18 +++++++++---------
arch/powerpc/math-emu/udivmodti4.c | 2 +-
36 files changed, 248 insertions(+), 223 deletions(-)
diff --git a/arch/powerpc/math-emu/Makefile b/arch/powerpc/math-emu/Makefile
index 29bc912..578c39a 100644
--- a/arch/powerpc/math-emu/Makefile
+++ b/arch/powerpc/math-emu/Makefile
@@ -4,7 +4,7 @@ obj-y := math.o fmr.o lfd.o stfd.o
obj-$(CONFIG_MATH_EMULATION) += fabs.o fadd.o fadds.o fcmpo.o fcmpu.o \
fctiw.o fctiwz.o fdiv.o fdivs.o \
fmadd.o fmadds.o fmsub.o fmsubs.o \
- fmul.o fmuls.o fnabs.o fneg.o types.o \
+ fmul.o fmuls.o fnabs.o fneg.o \
fnmadd.o fnmadds.o fnmsub.o fnmsubs.o \
fres.o frsp.o frsqrte.o fsel.o lfs.o \
fsqrt.o fsqrts.o fsub.o fsubs.o \
diff --git a/arch/powerpc/math-emu/fadd.c b/arch/powerpc/math-emu/fadd.c
index fc88364..18643ea 100644
--- a/arch/powerpc/math-emu/fadd.c
+++ b/arch/powerpc/math-emu/fadd.c
@@ -2,23 +2,23 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
-#include "double.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
int
fadd(void *frD, void *frA, void *frB)
{
+ FP_DECL_EX;
FP_DECL_D(A);
FP_DECL_D(B);
FP_DECL_D(R);
- int ret = 0;
#ifdef DEBUG
printk("%s: %p %p %p\n", __FUNCTION__, frD, frA, frB);
#endif
- __FP_UNPACK_D(A, frA);
- __FP_UNPACK_D(B, frB);
+ FP_UNPACK_DP(A, frA);
+ FP_UNPACK_DP(B, frB);
#ifdef DEBUG
printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -26,7 +26,7 @@ fadd(void *frD, void *frA, void *frB)
#endif
if (A_s != B_s && A_c == FP_CLS_INF && B_c == FP_CLS_INF)
- ret |= EFLAG_VXISI;
+ FP_SET_EXCEPTION(EFLAG_VXISI);
FP_ADD_D(R, A, B);
@@ -34,5 +34,7 @@ fadd(void *frD, void *frA, void *frB)
printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
#endif
- return (ret | __FP_PACK_D(frD, R));
+ FP_PACK_DP(frD, R);
+
+ return FP_CUR_EXCEPTIONS;
}
diff --git a/arch/powerpc/math-emu/fadds.c b/arch/powerpc/math-emu/fadds.c
index 93025b6..2b4fe58 100644
--- a/arch/powerpc/math-emu/fadds.c
+++ b/arch/powerpc/math-emu/fadds.c
@@ -2,24 +2,24 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+#include <math-emu/single.h>
int
fadds(void *frD, void *frA, void *frB)
{
+ FP_DECL_EX;
FP_DECL_D(A);
FP_DECL_D(B);
FP_DECL_D(R);
- int ret = 0;
#ifdef DEBUG
printk("%s: %p %p %p\n", __FUNCTION__, frD, frA, frB);
#endif
- __FP_UNPACK_D(A, frA);
- __FP_UNPACK_D(B, frB);
+ FP_UNPACK_DP(A, frA);
+ FP_UNPACK_DP(B, frB);
#ifdef DEBUG
printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -27,13 +27,14 @@ fadds(void *frD, void *frA, void *frB)
#endif
if (A_s != B_s && A_c == FP_CLS_INF && B_c == FP_CLS_INF)
- ret |= EFLAG_VXISI;
+ FP_SET_EXCEPTION(EFLAG_VXISI);
FP_ADD_D(R, A, B);
#ifdef DEBUG
printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
#endif
+ __FP_PACK_DS(frD, R);
- return (ret | __FP_PACK_DS(frD, R));
+ return FP_CUR_EXCEPTIONS;
}
diff --git a/arch/powerpc/math-emu/fcmpo.c b/arch/powerpc/math-emu/fcmpo.c
index 4efac39..adcc4b4 100644
--- a/arch/powerpc/math-emu/fcmpo.c
+++ b/arch/powerpc/math-emu/fcmpo.c
@@ -2,24 +2,24 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
-#include "double.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
int
fcmpo(u32 *ccr, int crfD, void *frA, void *frB)
{
+ FP_DECL_EX;
FP_DECL_D(A);
FP_DECL_D(B);
int code[4] = { (1 << 3), (1 << 1), (1 << 2), (1 << 0) };
long cmp;
- int ret = 0;
#ifdef DEBUG
printk("%s: %p (%08x) %d %p %p\n", __FUNCTION__, ccr, *ccr, crfD, frA, frB);
#endif
- __FP_UNPACK_D(A, frA);
- __FP_UNPACK_D(B, frB);
+ FP_UNPACK_DP(A, frA);
+ FP_UNPACK_DP(B, frB);
#ifdef DEBUG
printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -27,10 +27,14 @@ fcmpo(u32 *ccr, int crfD, void *frA, void *frB)
#endif
if (A_c == FP_CLS_NAN || B_c == FP_CLS_NAN)
- ret |= EFLAG_VXVC;
+ FP_SET_EXCEPTION(EFLAG_VXVC);
- FP_CMP_D(cmp, A, B, 2);
- cmp = code[(cmp + 1) & 3];
+ FP_CMP_D(cmp, A, B, 3);
+ if (cmp == 3 && (FP_ISSIGNAN_D(A) || FP_ISSIGNAN_D(B))){
+ FP_SET_EXCEPTION (FP_EX_INVALID);
+ cmp = 1;
+ } else
+ cmp = code[(cmp + 1) & 3];
__FPU_FPSCR &= ~(0x1f000);
__FPU_FPSCR |= (cmp << 12);
@@ -42,5 +46,5 @@ fcmpo(u32 *ccr, int crfD, void *frA, void *frB)
printk("CR: %08x\n", *ccr);
#endif
- return ret;
+ return FP_CUR_EXCEPTIONS;
}
diff --git a/arch/powerpc/math-emu/fcmpu.c b/arch/powerpc/math-emu/fcmpu.c
index b7e3317..8f91e0b 100644
--- a/arch/powerpc/math-emu/fcmpu.c
+++ b/arch/powerpc/math-emu/fcmpu.c
@@ -2,12 +2,13 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
-#include "double.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
int
fcmpu(u32 *ccr, int crfD, void *frA, void *frB)
{
+ FP_DECL_EX;
FP_DECL_D(A);
FP_DECL_D(B);
int code[4] = { (1 << 3), (1 << 1), (1 << 2), (1 << 0) };
@@ -17,16 +18,21 @@ fcmpu(u32 *ccr, int crfD, void *frA, void *frB)
printk("%s: %p (%08x) %d %p %p\n", __FUNCTION__, ccr, *ccr, crfD, frA, frB);
#endif
- __FP_UNPACK_D(A, frA);
- __FP_UNPACK_D(B, frB);
+ FP_UNPACK_DP(A, frA);
+ FP_UNPACK_DP(B, frB);
#ifdef DEBUG
printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
#endif
- FP_CMP_D(cmp, A, B, 2);
- cmp = code[(cmp + 1) & 3];
+ FP_CMP_D(cmp, A, B, 3);
+ if (cmp == 3 && (FP_ISSIGNAN_D(A) || FP_ISSIGNAN_D(B))){
+ FP_SET_EXCEPTION (FP_EX_INVALID);
+ cmp = 1;
+ } else
+ cmp = code[(cmp + 1) & 3];
+
__FPU_FPSCR &= ~(0x1f000);
__FPU_FPSCR |= (cmp << 12);
@@ -38,5 +44,5 @@ fcmpu(u32 *ccr, int crfD, void *frA, void *frB)
printk("CR: %08x\n", *ccr);
#endif
- return 0;
+ return FP_CUR_EXCEPTIONS;
}
diff --git a/arch/powerpc/math-emu/fctiw.c b/arch/powerpc/math-emu/fctiw.c
index 3b3c98b..f0ae59d 100644
--- a/arch/powerpc/math-emu/fctiw.c
+++ b/arch/powerpc/math-emu/fctiw.c
@@ -2,16 +2,17 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
-#include "double.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
int
fctiw(u32 *frD, void *frB)
{
+ FP_DECL_EX;
FP_DECL_D(B);
unsigned int r;
- __FP_UNPACK_D(B, frB);
+ FP_UNPACK_DP(B, frB);
FP_TO_INT_D(r, B, 32, 1);
frD[1] = r;
@@ -21,5 +22,5 @@ fctiw(u32 *frD, void *frB)
printk("\n");
#endif
- return 0;
+ return FP_CUR_EXCEPTIONS;
}
diff --git a/arch/powerpc/math-emu/fctiwz.c b/arch/powerpc/math-emu/fctiwz.c
index 7717eb6..7dfdd9e 100644
--- a/arch/powerpc/math-emu/fctiwz.c
+++ b/arch/powerpc/math-emu/fctiwz.c
@@ -2,12 +2,13 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
-#include "double.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
int
fctiwz(u32 *frD, void *frB)
{
+ FP_DECL_EX;
FP_DECL_D(B);
u32 fpscr;
unsigned int r;
@@ -16,7 +17,7 @@ fctiwz(u32 *frD, void *frB)
__FPU_FPSCR &= ~(3);
__FPU_FPSCR |= FP_RND_ZERO;
- __FP_UNPACK_D(B, frB);
+ FP_UNPACK_DP(B, frB);
FP_TO_INT_D(r, B, 32, 1);
frD[1] = r;
@@ -28,5 +29,5 @@ fctiwz(u32 *frD, void *frB)
printk("\n");
#endif
- return 0;
+ return FP_CUR_EXCEPTIONS;
}
diff --git a/arch/powerpc/math-emu/fdiv.c b/arch/powerpc/math-emu/fdiv.c
index f2fba82..371d4da 100644
--- a/arch/powerpc/math-emu/fdiv.c
+++ b/arch/powerpc/math-emu/fdiv.c
@@ -2,23 +2,23 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
-#include "double.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
int
fdiv(void *frD, void *frA, void *frB)
{
+ FP_DECL_EX;
FP_DECL_D(A);
FP_DECL_D(B);
FP_DECL_D(R);
- int ret = 0;
#ifdef DEBUG
printk("%s: %p %p %p\n", __FUNCTION__, frD, frA, frB);
#endif
- __FP_UNPACK_D(A, frA);
- __FP_UNPACK_D(B, frB);
+ FP_UNPACK_DP(A, frA);
+ FP_UNPACK_DP(B, frB);
#ifdef DEBUG
printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -26,28 +26,24 @@ fdiv(void *frD, void *frA, void *frB)
#endif
if (A_c == FP_CLS_ZERO && B_c == FP_CLS_ZERO) {
- ret |= EFLAG_VXZDZ;
+ FP_SET_EXCEPTION(EFLAG_VXZDZ);
#ifdef DEBUG
printk("%s: FPSCR_VXZDZ raised\n", __FUNCTION__);
#endif
}
if (A_c == FP_CLS_INF && B_c == FP_CLS_INF) {
- ret |= EFLAG_VXIDI;
+ FP_SET_EXCEPTION(EFLAG_VXIDI);
#ifdef DEBUG
printk("%s: FPSCR_VXIDI raised\n", __FUNCTION__);
#endif
}
- if (B_c == FP_CLS_ZERO && A_c != FP_CLS_ZERO) {
- ret |= EFLAG_DIVZERO;
- if (__FPU_TRAP_P(EFLAG_DIVZERO))
- return ret;
- }
FP_DIV_D(R, A, B);
#ifdef DEBUG
printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
#endif
+ FP_PACK_DP(frD, R);
- return (ret | __FP_PACK_D(frD, R));
+ return FP_CUR_EXCEPTIONS;
}
diff --git a/arch/powerpc/math-emu/fdivs.c b/arch/powerpc/math-emu/fdivs.c
index b971196..2dbd79d 100644
--- a/arch/powerpc/math-emu/fdivs.c
+++ b/arch/powerpc/math-emu/fdivs.c
@@ -2,24 +2,24 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+#include <math-emu/single.h>
int
fdivs(void *frD, void *frA, void *frB)
{
+ FP_DECL_EX;
FP_DECL_D(A);
FP_DECL_D(B);
FP_DECL_D(R);
- int ret = 0;
#ifdef DEBUG
printk("%s: %p %p %p\n", __FUNCTION__, frD, frA, frB);
#endif
- __FP_UNPACK_D(A, frA);
- __FP_UNPACK_D(B, frB);
+ FP_UNPACK_DP(A, frA);
+ FP_UNPACK_DP(B, frB);
#ifdef DEBUG
printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -27,29 +27,24 @@ fdivs(void *frD, void *frA, void *frB)
#endif
if (A_c == FP_CLS_ZERO && B_c == FP_CLS_ZERO) {
- ret |= EFLAG_VXZDZ;
+ FP_SET_EXCEPTION(EFLAG_VXZDZ);
#ifdef DEBUG
printk("%s: FPSCR_VXZDZ raised\n", __FUNCTION__);
#endif
}
if (A_c == FP_CLS_INF && B_c == FP_CLS_INF) {
- ret |= EFLAG_VXIDI;
+ FP_SET_EXCEPTION(EFLAG_VXIDI);
#ifdef DEBUG
printk("%s: FPSCR_VXIDI raised\n", __FUNCTION__);
#endif
}
- if (B_c == FP_CLS_ZERO && A_c != FP_CLS_ZERO) {
- ret |= EFLAG_DIVZERO;
- if (__FPU_TRAP_P(EFLAG_DIVZERO))
- return ret;
- }
-
FP_DIV_D(R, A, B);
#ifdef DEBUG
printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
#endif
+ __FP_PACK_DS(frD, R);
- return (ret | __FP_PACK_DS(frD, R));
+ return FP_CUR_EXCEPTIONS;
}
diff --git a/arch/powerpc/math-emu/fmadd.c b/arch/powerpc/math-emu/fmadd.c
index 0a1dbce..06f49ff 100644
--- a/arch/powerpc/math-emu/fmadd.c
+++ b/arch/powerpc/math-emu/fmadd.c
@@ -2,26 +2,26 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
-#include "double.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
int
fmadd(void *frD, void *frA, void *frB, void *frC)
{
+ FP_DECL_EX;
FP_DECL_D(R);
FP_DECL_D(A);
FP_DECL_D(B);
FP_DECL_D(C);
FP_DECL_D(T);
- int ret = 0;
#ifdef DEBUG
printk("%s: %p %p %p %p\n", __FUNCTION__, frD, frA, frB, frC);
#endif
- __FP_UNPACK_D(A, frA);
- __FP_UNPACK_D(B, frB);
- __FP_UNPACK_D(C, frC);
+ FP_UNPACK_DP(A, frA);
+ FP_UNPACK_DP(B, frB);
+ FP_UNPACK_DP(C, frC);
#ifdef DEBUG
printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -31,18 +31,19 @@ fmadd(void *frD, void *frA, void *frB, void *frC)
if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
(A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
- ret |= EFLAG_VXIMZ;
+ FP_SET_EXCEPTION(EFLAG_VXIMZ);
FP_MUL_D(T, A, C);
if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
- ret |= EFLAG_VXISI;
+ FP_SET_EXCEPTION(EFLAG_VXISI);
FP_ADD_D(R, T, B);
#ifdef DEBUG
printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
#endif
+ FP_PACK_DP(frD, R);
- return (ret | __FP_PACK_D(frD, R));
+ return FP_CUR_EXCEPTIONS;
}
diff --git a/arch/powerpc/math-emu/fmadds.c b/arch/powerpc/math-emu/fmadds.c
index 0f70bba..ef0bac0 100644
--- a/arch/powerpc/math-emu/fmadds.c
+++ b/arch/powerpc/math-emu/fmadds.c
@@ -2,27 +2,27 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+#include <math-emu/single.h>
int
fmadds(void *frD, void *frA, void *frB, void *frC)
{
+ FP_DECL_EX;
FP_DECL_D(R);
FP_DECL_D(A);
FP_DECL_D(B);
FP_DECL_D(C);
FP_DECL_D(T);
- int ret = 0;
#ifdef DEBUG
printk("%s: %p %p %p %p\n", __FUNCTION__, frD, frA, frB, frC);
#endif
- __FP_UNPACK_D(A, frA);
- __FP_UNPACK_D(B, frB);
- __FP_UNPACK_D(C, frC);
+ FP_UNPACK_DP(A, frA);
+ FP_UNPACK_DP(B, frB);
+ FP_UNPACK_DP(C, frC);
#ifdef DEBUG
printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -32,18 +32,19 @@ fmadds(void *frD, void *frA, void *frB, void *frC)
if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
(A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
- ret |= EFLAG_VXIMZ;
+ FP_SET_EXCEPTION(EFLAG_VXIMZ);
FP_MUL_D(T, A, C);
if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
- ret |= EFLAG_VXISI;
+ FP_SET_EXCEPTION(EFLAG_VXISI);
FP_ADD_D(R, T, B);
#ifdef DEBUG
printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
#endif
+ __FP_PACK_DS(frD, R);
- return (ret | __FP_PACK_DS(frD, R));
+ return FP_CUR_EXCEPTIONS;
}
diff --git a/arch/powerpc/math-emu/fmsub.c b/arch/powerpc/math-emu/fmsub.c
index 203fd48..55c851e 100644
--- a/arch/powerpc/math-emu/fmsub.c
+++ b/arch/powerpc/math-emu/fmsub.c
@@ -2,26 +2,26 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
-#include "double.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
int
fmsub(void *frD, void *frA, void *frB, void *frC)
{
+ FP_DECL_EX;
FP_DECL_D(R);
FP_DECL_D(A);
FP_DECL_D(B);
FP_DECL_D(C);
FP_DECL_D(T);
- int ret = 0;
#ifdef DEBUG
printk("%s: %p %p %p %p\n", __FUNCTION__, frD, frA, frB, frC);
#endif
- __FP_UNPACK_D(A, frA);
- __FP_UNPACK_D(B, frB);
- __FP_UNPACK_D(C, frC);
+ FP_UNPACK_DP(A, frA);
+ FP_UNPACK_DP(B, frB);
+ FP_UNPACK_DP(C, frC);
#ifdef DEBUG
printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -31,7 +31,7 @@ fmsub(void *frD, void *frA, void *frB, void *frC)
if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
(A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
- ret |= EFLAG_VXIMZ;
+ FP_SET_EXCEPTION(EFLAG_VXIMZ);
FP_MUL_D(T, A, C);
@@ -39,13 +39,14 @@ fmsub(void *frD, void *frA, void *frB, void *frC)
B_s ^= 1;
if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
- ret |= EFLAG_VXISI;
+ FP_SET_EXCEPTION(EFLAG_VXISI);
FP_ADD_D(R, T, B);
#ifdef DEBUG
printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
#endif
+ FP_PACK_DP(frD, R);
- return (ret | __FP_PACK_D(frD, R));
+ return FP_CUR_EXCEPTIONS;
}
diff --git a/arch/powerpc/math-emu/fmsubs.c b/arch/powerpc/math-emu/fmsubs.c
index 8ce6862..81941df 100644
--- a/arch/powerpc/math-emu/fmsubs.c
+++ b/arch/powerpc/math-emu/fmsubs.c
@@ -2,27 +2,27 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+#include <math-emu/single.h>
int
fmsubs(void *frD, void *frA, void *frB, void *frC)
{
+ FP_DECL_EX;
FP_DECL_D(R);
FP_DECL_D(A);
FP_DECL_D(B);
FP_DECL_D(C);
FP_DECL_D(T);
- int ret = 0;
#ifdef DEBUG
printk("%s: %p %p %p %p\n", __FUNCTION__, frD, frA, frB, frC);
#endif
- __FP_UNPACK_D(A, frA);
- __FP_UNPACK_D(B, frB);
- __FP_UNPACK_D(C, frC);
+ FP_UNPACK_DP(A, frA);
+ FP_UNPACK_DP(B, frB);
+ FP_UNPACK_DP(C, frC);
#ifdef DEBUG
printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -32,7 +32,7 @@ fmsubs(void *frD, void *frA, void *frB, void *frC)
if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
(A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
- ret |= EFLAG_VXIMZ;
+ FP_SET_EXCEPTION(EFLAG_VXIMZ);
FP_MUL_D(T, A, C);
@@ -40,13 +40,14 @@ fmsubs(void *frD, void *frA, void *frB, void *frC)
B_s ^= 1;
if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
- ret |= EFLAG_VXISI;
+ FP_SET_EXCEPTION(EFLAG_VXISI);
FP_ADD_D(R, T, B);
#ifdef DEBUG
printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
#endif
+ __FP_PACK_DS(frD, R);
- return (ret | __FP_PACK_DS(frD, R));
+ return FP_CUR_EXCEPTIONS;
}
diff --git a/arch/powerpc/math-emu/fmul.c b/arch/powerpc/math-emu/fmul.c
index 66c7e79..6f44699 100644
--- a/arch/powerpc/math-emu/fmul.c
+++ b/arch/powerpc/math-emu/fmul.c
@@ -2,23 +2,23 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
-#include "double.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
int
fmul(void *frD, void *frA, void *frB)
{
+ FP_DECL_EX;
FP_DECL_D(A);
FP_DECL_D(B);
FP_DECL_D(R);
- int ret = 0;
#ifdef DEBUG
printk("%s: %p %p %p\n", __FUNCTION__, frD, frA, frB);
#endif
- __FP_UNPACK_D(A, frA);
- __FP_UNPACK_D(B, frB);
+ FP_UNPACK_DP(A, frA);
+ FP_UNPACK_DP(B, frB);
#ifdef DEBUG
printk("A: %ld %lu %lu %ld (%ld) [%08lx.%08lx %lx]\n",
@@ -29,7 +29,7 @@ fmul(void *frD, void *frA, void *frB)
if ((A_c == FP_CLS_INF && B_c == FP_CLS_ZERO) ||
(A_c == FP_CLS_ZERO && B_c == FP_CLS_INF))
- ret |= EFLAG_VXIMZ;
+ FP_SET_EXCEPTION(EFLAG_VXIMZ);
FP_MUL_D(R, A, B);
@@ -37,6 +37,7 @@ fmul(void *frD, void *frA, void *frB)
printk("D: %ld %lu %lu %ld (%ld) [%08lx.%08lx %lx]\n",
R_s, R_f1, R_f0, R_e, R_c, R_f1, R_f0, R_e + 1023);
#endif
+ FP_PACK_DP(frD, R);
- return (ret | __FP_PACK_D(frD, R));
+ return FP_CUR_EXCEPTIONS;
}
diff --git a/arch/powerpc/math-emu/fmuls.c b/arch/powerpc/math-emu/fmuls.c
index 26bc427..6035a10 100644
--- a/arch/powerpc/math-emu/fmuls.c
+++ b/arch/powerpc/math-emu/fmuls.c
@@ -2,24 +2,24 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+#include <math-emu/single.h>
int
fmuls(void *frD, void *frA, void *frB)
{
+ FP_DECL_EX;
FP_DECL_D(A);
FP_DECL_D(B);
FP_DECL_D(R);
- int ret = 0;
#ifdef DEBUG
printk("%s: %p %p %p\n", __FUNCTION__, frD, frA, frB);
#endif
- __FP_UNPACK_D(A, frA);
- __FP_UNPACK_D(B, frB);
+ FP_UNPACK_DP(A, frA);
+ FP_UNPACK_DP(B, frB);
#ifdef DEBUG
printk("A: %ld %lu %lu %ld (%ld) [%08lx.%08lx %lx]\n",
@@ -30,7 +30,7 @@ fmuls(void *frD, void *frA, void *frB)
if ((A_c == FP_CLS_INF && B_c == FP_CLS_ZERO) ||
(A_c == FP_CLS_ZERO && B_c == FP_CLS_INF))
- ret |= EFLAG_VXIMZ;
+ FP_SET_EXCEPTION(EFLAG_VXIMZ);
FP_MUL_D(R, A, B);
@@ -38,6 +38,7 @@ fmuls(void *frD, void *frA, void *frB)
printk("D: %ld %lu %lu %ld (%ld) [%08lx.%08lx %lx]\n",
R_s, R_f1, R_f0, R_e, R_c, R_f1, R_f0, R_e + 1023);
#endif
+ __FP_PACK_DS(frD, R);
- return (ret | __FP_PACK_DS(frD, R));
+ return FP_CUR_EXCEPTIONS;
}
diff --git a/arch/powerpc/math-emu/fnmadd.c b/arch/powerpc/math-emu/fnmadd.c
index 7f31227..8741b56 100644
--- a/arch/powerpc/math-emu/fnmadd.c
+++ b/arch/powerpc/math-emu/fnmadd.c
@@ -2,26 +2,26 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
-#include "double.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
int
fnmadd(void *frD, void *frA, void *frB, void *frC)
{
+ FP_DECL_EX;
FP_DECL_D(R);
FP_DECL_D(A);
FP_DECL_D(B);
FP_DECL_D(C);
FP_DECL_D(T);
- int ret = 0;
#ifdef DEBUG
printk("%s: %p %p %p %p\n", __FUNCTION__, frD, frA, frB, frC);
#endif
- __FP_UNPACK_D(A, frA);
- __FP_UNPACK_D(B, frB);
- __FP_UNPACK_D(C, frC);
+ FP_UNPACK_DP(A, frA);
+ FP_UNPACK_DP(B, frB);
+ FP_UNPACK_DP(C, frC);
#ifdef DEBUG
printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -31,12 +31,12 @@ fnmadd(void *frD, void *frA, void *frB, void *frC)
if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
(A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
- ret |= EFLAG_VXIMZ;
+ FP_SET_EXCEPTION(EFLAG_VXIMZ);
FP_MUL_D(T, A, C);
if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
- ret |= EFLAG_VXISI;
+ FP_SET_EXCEPTION(EFLAG_VXISI);
FP_ADD_D(R, T, B);
@@ -46,6 +46,7 @@ fnmadd(void *frD, void *frA, void *frB, void *frC)
#ifdef DEBUG
printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
#endif
+ FP_PACK_DP(frD, R);
- return (ret | __FP_PACK_D(frD, R));
+ return FP_CUR_EXCEPTIONS;
}
diff --git a/arch/powerpc/math-emu/fnmadds.c b/arch/powerpc/math-emu/fnmadds.c
index 65454c9..d04d4aa 100644
--- a/arch/powerpc/math-emu/fnmadds.c
+++ b/arch/powerpc/math-emu/fnmadds.c
@@ -2,27 +2,27 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+#include <math-emu/single.h>
int
fnmadds(void *frD, void *frA, void *frB, void *frC)
{
+ FP_DECL_EX;
FP_DECL_D(R);
FP_DECL_D(A);
FP_DECL_D(B);
FP_DECL_D(C);
FP_DECL_D(T);
- int ret = 0;
#ifdef DEBUG
printk("%s: %p %p %p %p\n", __FUNCTION__, frD, frA, frB, frC);
#endif
- __FP_UNPACK_D(A, frA);
- __FP_UNPACK_D(B, frB);
- __FP_UNPACK_D(C, frC);
+ FP_UNPACK_DP(A, frA);
+ FP_UNPACK_DP(B, frB);
+ FP_UNPACK_DP(C, frC);
#ifdef DEBUG
printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -32,12 +32,12 @@ fnmadds(void *frD, void *frA, void *frB, void *frC)
if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
(A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
- ret |= EFLAG_VXIMZ;
+ FP_SET_EXCEPTION(EFLAG_VXIMZ);
FP_MUL_D(T, A, C);
if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
- ret |= EFLAG_VXISI;
+ FP_SET_EXCEPTION(EFLAG_VXISI);
FP_ADD_D(R, T, B);
@@ -47,6 +47,7 @@ fnmadds(void *frD, void *frA, void *frB, void *frC)
#ifdef DEBUG
printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
#endif
+ __FP_PACK_DS(frD, R);
- return (ret | __FP_PACK_DS(frD, R));
+ return FP_CUR_EXCEPTIONS;
}
diff --git a/arch/powerpc/math-emu/fnmsub.c b/arch/powerpc/math-emu/fnmsub.c
index f1ca748..0d91e9e 100644
--- a/arch/powerpc/math-emu/fnmsub.c
+++ b/arch/powerpc/math-emu/fnmsub.c
@@ -2,26 +2,26 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
-#include "double.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
int
fnmsub(void *frD, void *frA, void *frB, void *frC)
{
+ FP_DECL_EX;
FP_DECL_D(R);
FP_DECL_D(A);
FP_DECL_D(B);
FP_DECL_D(C);
FP_DECL_D(T);
- int ret = 0;
#ifdef DEBUG
printk("%s: %p %p %p %p\n", __FUNCTION__, frD, frA, frB, frC);
#endif
- __FP_UNPACK_D(A, frA);
- __FP_UNPACK_D(B, frB);
- __FP_UNPACK_D(C, frC);
+ FP_UNPACK_DP(A, frA);
+ FP_UNPACK_DP(B, frB);
+ FP_UNPACK_DP(C, frC);
#ifdef DEBUG
printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -31,7 +31,7 @@ fnmsub(void *frD, void *frA, void *frB, void *frC)
if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
(A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
- ret |= EFLAG_VXIMZ;
+ FP_SET_EXCEPTION(EFLAG_VXIMZ);
FP_MUL_D(T, A, C);
@@ -39,7 +39,7 @@ fnmsub(void *frD, void *frA, void *frB, void *frC)
B_s ^= 1;
if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
- ret |= EFLAG_VXISI;
+ FP_SET_EXCEPTION(EFLAG_VXISI);
FP_ADD_D(R, T, B);
@@ -49,6 +49,7 @@ fnmsub(void *frD, void *frA, void *frB, void *frC)
#ifdef DEBUG
printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
#endif
+ FP_PACK_DP(frD, R);
- return (ret | __FP_PACK_D(frD, R));
+ return FP_CUR_EXCEPTIONS;
}
diff --git a/arch/powerpc/math-emu/fnmsubs.c b/arch/powerpc/math-emu/fnmsubs.c
index 5c9a09a..1e1e168 100644
--- a/arch/powerpc/math-emu/fnmsubs.c
+++ b/arch/powerpc/math-emu/fnmsubs.c
@@ -2,27 +2,27 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+#include <math-emu/single.h>
int
fnmsubs(void *frD, void *frA, void *frB, void *frC)
{
+ FP_DECL_EX;
FP_DECL_D(R);
FP_DECL_D(A);
FP_DECL_D(B);
FP_DECL_D(C);
FP_DECL_D(T);
- int ret = 0;
#ifdef DEBUG
printk("%s: %p %p %p %p\n", __FUNCTION__, frD, frA, frB, frC);
#endif
- __FP_UNPACK_D(A, frA);
- __FP_UNPACK_D(B, frB);
- __FP_UNPACK_D(C, frC);
+ FP_UNPACK_DP(A, frA);
+ FP_UNPACK_DP(B, frB);
+ FP_UNPACK_DP(C, frC);
#ifdef DEBUG
printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -32,7 +32,7 @@ fnmsubs(void *frD, void *frA, void *frB, void *frC)
if ((A_c == FP_CLS_INF && C_c == FP_CLS_ZERO) ||
(A_c == FP_CLS_ZERO && C_c == FP_CLS_INF))
- ret |= EFLAG_VXIMZ;
+ FP_SET_EXCEPTION(EFLAG_VXIMZ);
FP_MUL_D(T, A, C);
@@ -40,7 +40,7 @@ fnmsubs(void *frD, void *frA, void *frB, void *frC)
B_s ^= 1;
if (T_s != B_s && T_c == FP_CLS_INF && B_c == FP_CLS_INF)
- ret |= EFLAG_VXISI;
+ FP_SET_EXCEPTION(EFLAG_VXISI);
FP_ADD_D(R, T, B);
@@ -50,6 +50,7 @@ fnmsubs(void *frD, void *frA, void *frB, void *frC)
#ifdef DEBUG
printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
#endif
+ __FP_PACK_DS(frD, R);
- return (ret | __FP_PACK_DS(frD, R));
+ return FP_CUR_EXCEPTIONS;
}
diff --git a/arch/powerpc/math-emu/frsp.c b/arch/powerpc/math-emu/frsp.c
index d879b2a..6438823 100644
--- a/arch/powerpc/math-emu/frsp.c
+++ b/arch/powerpc/math-emu/frsp.c
@@ -2,24 +2,26 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+#include <math-emu/single.h>
int
frsp(void *frD, void *frB)
{
+ FP_DECL_EX;
FP_DECL_D(B);
#ifdef DEBUG
printk("%s: D %p, B %p\n", __FUNCTION__, frD, frB);
#endif
- __FP_UNPACK_D(B, frB);
+ FP_UNPACK_DP(B, frB);
#ifdef DEBUG
printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
#endif
+ __FP_PACK_DS(frD, B);
- return __FP_PACK_DS(frD, B);
+ return FP_CUR_EXCEPTIONS;
}
diff --git a/arch/powerpc/math-emu/fsel.c b/arch/powerpc/math-emu/fsel.c
index e36e6e7..6fadfb3 100644
--- a/arch/powerpc/math-emu/fsel.c
+++ b/arch/powerpc/math-emu/fsel.c
@@ -2,19 +2,20 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
-#include "double.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
int
fsel(u32 *frD, void *frA, u32 *frB, u32 *frC)
{
+ FP_DECL_EX;
FP_DECL_D(A);
#ifdef DEBUG
printk("%s: %p %p %p %p\n", __FUNCTION__, frD, frA, frB, frC);
#endif
- __FP_UNPACK_D(A, frA);
+ FP_UNPACK_DP(A, frA);
#ifdef DEBUG
printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -34,5 +35,5 @@ fsel(u32 *frD, void *frA, u32 *frB, u32 *frC)
printk("D: %08x.%08x\n", frD[0], frD[1]);
#endif
- return 0;
+ return FP_CUR_EXCEPTIONS;
}
diff --git a/arch/powerpc/math-emu/fsqrt.c b/arch/powerpc/math-emu/fsqrt.c
index 6f8319f..febd878 100644
--- a/arch/powerpc/math-emu/fsqrt.c
+++ b/arch/powerpc/math-emu/fsqrt.c
@@ -2,36 +2,37 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
-#include "double.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
int
fsqrt(void *frD, void *frB)
{
+ FP_DECL_EX;
FP_DECL_D(B);
FP_DECL_D(R);
- int ret = 0;
#ifdef DEBUG
printk("%s: %p %p %p %p\n", __FUNCTION__, frD, frB);
#endif
- __FP_UNPACK_D(B, frB);
+ FP_UNPACK_DP(B, frB);
#ifdef DEBUG
printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
#endif
if (B_s && B_c != FP_CLS_ZERO)
- ret |= EFLAG_VXSQRT;
+ FP_SET_EXCEPTION(EFLAG_VXSQRT);
if (B_c == FP_CLS_NAN)
- ret |= EFLAG_VXSNAN;
+ FP_SET_EXCEPTION(EFLAG_VXSNAN);
FP_SQRT_D(R, B);
#ifdef DEBUG
printk("R: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
#endif
+ FP_PACK_DP(frD, R);
- return (ret | __FP_PACK_D(frD, R));
+ return FP_CUR_EXCEPTIONS;
}
diff --git a/arch/powerpc/math-emu/fsqrts.c b/arch/powerpc/math-emu/fsqrts.c
index 3b2b1cf..fad4f8b 100644
--- a/arch/powerpc/math-emu/fsqrts.c
+++ b/arch/powerpc/math-emu/fsqrts.c
@@ -2,37 +2,38 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+#include <math-emu/single.h>
int
fsqrts(void *frD, void *frB)
{
+ FP_DECL_EX;
FP_DECL_D(B);
FP_DECL_D(R);
- int ret = 0;
#ifdef DEBUG
printk("%s: %p %p %p %p\n", __FUNCTION__, frD, frB);
#endif
- __FP_UNPACK_D(B, frB);
+ FP_UNPACK_DP(B, frB);
#ifdef DEBUG
printk("B: %ld %lu %lu %ld (%ld)\n", B_s, B_f1, B_f0, B_e, B_c);
#endif
if (B_s && B_c != FP_CLS_ZERO)
- ret |= EFLAG_VXSQRT;
+ FP_SET_EXCEPTION(EFLAG_VXSQRT);
if (B_c == FP_CLS_NAN)
- ret |= EFLAG_VXSNAN;
+ FP_SET_EXCEPTION(EFLAG_VXSNAN);
FP_SQRT_D(R, B);
#ifdef DEBUG
printk("R: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
#endif
+ __FP_PACK_DS(frD, R);
- return (ret | __FP_PACK_DS(frD, R));
+ return FP_CUR_EXCEPTIONS;
}
diff --git a/arch/powerpc/math-emu/fsub.c b/arch/powerpc/math-emu/fsub.c
index 9566790..d973919 100644
--- a/arch/powerpc/math-emu/fsub.c
+++ b/arch/powerpc/math-emu/fsub.c
@@ -2,23 +2,23 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
-#include "double.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
int
fsub(void *frD, void *frA, void *frB)
{
+ FP_DECL_EX;
FP_DECL_D(A);
FP_DECL_D(B);
FP_DECL_D(R);
- int ret = 0;
#ifdef DEBUG
printk("%s: %p %p %p\n", __FUNCTION__, frD, frA, frB);
#endif
- __FP_UNPACK_D(A, frA);
- __FP_UNPACK_D(B, frB);
+ FP_UNPACK_DP(A, frA);
+ FP_UNPACK_DP(B, frB);
#ifdef DEBUG
printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -29,13 +29,14 @@ fsub(void *frD, void *frA, void *frB)
B_s ^= 1;
if (A_s != B_s && A_c == FP_CLS_INF && B_c == FP_CLS_INF)
- ret |= EFLAG_VXISI;
+ FP_SET_EXCEPTION(EFLAG_VXISI);
FP_ADD_D(R, A, B);
#ifdef DEBUG
printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
#endif
+ FP_PACK_DP(frD, R);
- return (ret | __FP_PACK_D(frD, R));
+ return FP_CUR_EXCEPTIONS;
}
diff --git a/arch/powerpc/math-emu/fsubs.c b/arch/powerpc/math-emu/fsubs.c
index 3428117..3162382 100644
--- a/arch/powerpc/math-emu/fsubs.c
+++ b/arch/powerpc/math-emu/fsubs.c
@@ -2,24 +2,24 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+#include <math-emu/single.h>
int
fsubs(void *frD, void *frA, void *frB)
{
+ FP_DECL_EX;
FP_DECL_D(A);
FP_DECL_D(B);
FP_DECL_D(R);
- int ret = 0;
#ifdef DEBUG
printk("%s: %p %p %p\n", __FUNCTION__, frD, frA, frB);
#endif
- __FP_UNPACK_D(A, frA);
- __FP_UNPACK_D(B, frB);
+ FP_UNPACK_DP(A, frA);
+ FP_UNPACK_DP(B, frB);
#ifdef DEBUG
printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -30,13 +30,14 @@ fsubs(void *frD, void *frA, void *frB)
B_s ^= 1;
if (A_s != B_s && A_c == FP_CLS_INF && B_c == FP_CLS_INF)
- ret |= EFLAG_VXISI;
+ FP_SET_EXCEPTION(EFLAG_VXISI);
FP_ADD_D(R, A, B);
#ifdef DEBUG
printk("D: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
#endif
+ __FP_PACK_DS(frD, R);
- return (ret | __FP_PACK_DS(frD, R));
+ return FP_CUR_EXCEPTIONS;
}
diff --git a/arch/powerpc/math-emu/lfd.c b/arch/powerpc/math-emu/lfd.c
index 7d38101..e5ad147 100644
--- a/arch/powerpc/math-emu/lfd.c
+++ b/arch/powerpc/math-emu/lfd.c
@@ -2,8 +2,8 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "sfp-machine.h"
-#include "double.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/double.h>
int
lfd(void *frD, void *ea)
diff --git a/arch/powerpc/math-emu/lfs.c b/arch/powerpc/math-emu/lfs.c
index c86dee3..67d3a3e 100644
--- a/arch/powerpc/math-emu/lfs.c
+++ b/arch/powerpc/math-emu/lfs.c
@@ -2,13 +2,14 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+#include <math-emu/single.h>
int
lfs(void *frD, void *ea)
{
+ FP_DECL_EX;
FP_DECL_D(R);
FP_DECL_S(A);
float f;
@@ -20,7 +21,7 @@ lfs(void *frD, void *ea)
if (copy_from_user(&f, ea, sizeof(float)))
return -EFAULT;
- __FP_UNPACK_S(A, &f);
+ FP_UNPACK_SP(A, &f);
#ifdef DEBUG
printk("A: %ld %lu %ld (%ld) [%08lx]\n", A_s, A_f, A_e, A_c,
@@ -32,6 +33,7 @@ lfs(void *frD, void *ea)
#ifdef DEBUG
printk("R: %ld %lu %lu %ld (%ld)\n", R_s, R_f1, R_f0, R_e, R_c);
#endif
+ FP_PACK_DP(frD, R);
- return __FP_PACK_D(frD, R);
+ return FP_CUR_EXCEPTIONS;
}
diff --git a/arch/powerpc/math-emu/math.c b/arch/powerpc/math-emu/math.c
index 381306b..2f355df 100644
--- a/arch/powerpc/math-emu/math.c
+++ b/arch/powerpc/math-emu/math.c
@@ -8,8 +8,8 @@
#include <asm/uaccess.h>
#include <asm/reg.h>
-#include "sfp-machine.h"
-#include "double.h"
+#include <asm/sfp-machine.h>
+#include <math-emu/double.h>
#define FLOATFUNC(x) extern int x(void *, void *, void *, void *)
diff --git a/arch/powerpc/math-emu/mcrfs.c b/arch/powerpc/math-emu/mcrfs.c
index 106dd91..219b09f 100644
--- a/arch/powerpc/math-emu/mcrfs.c
+++ b/arch/powerpc/math-emu/mcrfs.c
@@ -2,7 +2,7 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
+#include <math-emu/soft-fp.h>
int
mcrfs(u32 *ccr, u32 crfD, u32 crfS)
diff --git a/arch/powerpc/math-emu/mffs.c b/arch/powerpc/math-emu/mffs.c
index f477c91..329ff94 100644
--- a/arch/powerpc/math-emu/mffs.c
+++ b/arch/powerpc/math-emu/mffs.c
@@ -2,7 +2,7 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
+#include <math-emu/soft-fp.h>
int
mffs(u32 *frD)
diff --git a/arch/powerpc/math-emu/mtfsb0.c b/arch/powerpc/math-emu/mtfsb0.c
index 99bfd80..3404b2f 100644
--- a/arch/powerpc/math-emu/mtfsb0.c
+++ b/arch/powerpc/math-emu/mtfsb0.c
@@ -2,7 +2,7 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
+#include <math-emu/soft-fp.h>
int
mtfsb0(int crbD)
diff --git a/arch/powerpc/math-emu/mtfsb1.c b/arch/powerpc/math-emu/mtfsb1.c
index 3d9e7ed..933b333 100644
--- a/arch/powerpc/math-emu/mtfsb1.c
+++ b/arch/powerpc/math-emu/mtfsb1.c
@@ -2,7 +2,7 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
+#include <math-emu/soft-fp.h>
int
mtfsb1(int crbD)
diff --git a/arch/powerpc/math-emu/mtfsf.c b/arch/powerpc/math-emu/mtfsf.c
index d70cf71..caeceaa 100644
--- a/arch/powerpc/math-emu/mtfsf.c
+++ b/arch/powerpc/math-emu/mtfsf.c
@@ -2,7 +2,7 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
+#include <math-emu/soft-fp.h>
int
mtfsf(unsigned int FM, u32 *frB)
diff --git a/arch/powerpc/math-emu/mtfsfi.c b/arch/powerpc/math-emu/mtfsfi.c
index 71df854..4c9777a 100644
--- a/arch/powerpc/math-emu/mtfsfi.c
+++ b/arch/powerpc/math-emu/mtfsfi.c
@@ -2,7 +2,7 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
+#include <math-emu/soft-fp.h>
int
mtfsfi(unsigned int crfD, unsigned int IMM)
diff --git a/arch/powerpc/math-emu/stfs.c b/arch/powerpc/math-emu/stfs.c
index e87ca23..d392b38 100644
--- a/arch/powerpc/math-emu/stfs.c
+++ b/arch/powerpc/math-emu/stfs.c
@@ -2,23 +2,23 @@
#include <linux/errno.h>
#include <asm/uaccess.h>
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
+#include <math-emu/soft-fp.h>
+#include <math-emu/double.h>
+#include <math-emu/single.h>
int
stfs(void *frS, void *ea)
{
+ FP_DECL_EX;
FP_DECL_D(A);
FP_DECL_S(R);
float f;
- int err;
#ifdef DEBUG
printk("%s: S %p, ea %p\n", __FUNCTION__, frS, ea);
#endif
- __FP_UNPACK_D(A, frS);
+ FP_UNPACK_DP(A, frS);
#ifdef DEBUG
printk("A: %ld %lu %lu %ld (%ld)\n", A_s, A_f1, A_f0, A_e, A_c);
@@ -30,12 +30,12 @@ stfs(void *frS, void *ea)
printk("R: %ld %lu %ld (%ld)\n", R_s, R_f, R_e, R_c);
#endif
- err = _FP_PACK_CANONICAL(S, 1, R);
- if (!err || !__FPU_TRAP_P(err)) {
- __FP_PACK_RAW_1(S, &f, R);
+ FP_PACK_SP(&f,R);
+
+ if (!FP_INHIBIT_RESULTS) {
if (copy_to_user(ea, &f, sizeof(float)))
return -EFAULT;
}
- return err;
+ return FP_CUR_EXCEPTIONS;
}
diff --git a/arch/powerpc/math-emu/udivmodti4.c b/arch/powerpc/math-emu/udivmodti4.c
index 7e112dc..6172044 100644
--- a/arch/powerpc/math-emu/udivmodti4.c
+++ b/arch/powerpc/math-emu/udivmodti4.c
@@ -1,6 +1,6 @@
/* This has so very few changes over libgcc2's __udivmoddi4 it isn't funny. */
-#include "soft-fp.h"
+#include <math-emu/soft-fp.h>
#undef count_leading_zeros
#define count_leading_zeros __FP_CLZ
--
1.5.2
^ permalink raw reply related
* [PATCH] math-emu: delete PowerPC old math-emu headers
From: Liu Yu @ 2008-03-05 9:02 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Liu Yu
Use common headers as a replacement.
The Common headers are located in "include/math-emu/",
they are used by multiple platforms such as s390, sparc, alpha.
As the common headers have more developers,
they are more popular and more stable.
In fact, PowerPC old math-emu headers cannot handle float point
exceptions exactly while the common headers can.
Signed-off-by: Liu Yu <Yu.Liu@freescale.com>
---
arch/powerpc/math-emu/double.h | 129 ----
arch/powerpc/math-emu/op-1.h | 245 -------
arch/powerpc/math-emu/op-2.h | 434 ------------
arch/powerpc/math-emu/op-4.h | 317 ---------
arch/powerpc/math-emu/op-common.h | 688 --------------------
arch/powerpc/math-emu/single.h | 66 --
arch/powerpc/math-emu/soft-fp.h | 104 ---
arch/powerpc/math-emu/types.c | 51 --
.../math-emu => include/asm-powerpc}/sfp-machine.h | 0
9 files changed, 0 insertions(+), 2034 deletions(-)
delete mode 100644 arch/powerpc/math-emu/double.h
delete mode 100644 arch/powerpc/math-emu/op-1.h
delete mode 100644 arch/powerpc/math-emu/op-2.h
delete mode 100644 arch/powerpc/math-emu/op-4.h
delete mode 100644 arch/powerpc/math-emu/op-common.h
delete mode 100644 arch/powerpc/math-emu/single.h
delete mode 100644 arch/powerpc/math-emu/soft-fp.h
delete mode 100644 arch/powerpc/math-emu/types.c
rename {arch/powerpc/math-emu => include/asm-powerpc}/sfp-machine.h (100%)
diff --git a/arch/powerpc/math-emu/double.h b/arch/powerpc/math-emu/double.h
deleted file mode 100644
index ffba8b6..0000000
--- a/arch/powerpc/math-emu/double.h
+++ /dev/null
@@ -1,129 +0,0 @@
-/*
- * Definitions for IEEE Double Precision
- */
-
-#if _FP_W_TYPE_SIZE < 32
-#error "Here's a nickel kid. Go buy yourself a real computer."
-#endif
-
-#if _FP_W_TYPE_SIZE < 64
-#define _FP_FRACTBITS_D (2 * _FP_W_TYPE_SIZE)
-#else
-#define _FP_FRACTBITS_D _FP_W_TYPE_SIZE
-#endif
-
-#define _FP_FRACBITS_D 53
-#define _FP_FRACXBITS_D (_FP_FRACTBITS_D - _FP_FRACBITS_D)
-#define _FP_WFRACBITS_D (_FP_WORKBITS + _FP_FRACBITS_D)
-#define _FP_WFRACXBITS_D (_FP_FRACTBITS_D - _FP_WFRACBITS_D)
-#define _FP_EXPBITS_D 11
-#define _FP_EXPBIAS_D 1023
-#define _FP_EXPMAX_D 2047
-
-#define _FP_QNANBIT_D \
- ((_FP_W_TYPE)1 << ((_FP_FRACBITS_D-2) % _FP_W_TYPE_SIZE))
-#define _FP_IMPLBIT_D \
- ((_FP_W_TYPE)1 << ((_FP_FRACBITS_D-1) % _FP_W_TYPE_SIZE))
-#define _FP_OVERFLOW_D \
- ((_FP_W_TYPE)1 << (_FP_WFRACBITS_D % _FP_W_TYPE_SIZE))
-
-#if _FP_W_TYPE_SIZE < 64
-
-union _FP_UNION_D
-{
- double flt;
- struct {
-#if __BYTE_ORDER == __BIG_ENDIAN
- unsigned sign : 1;
- unsigned exp : _FP_EXPBITS_D;
- unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE;
- unsigned frac0 : _FP_W_TYPE_SIZE;
-#else
- unsigned frac0 : _FP_W_TYPE_SIZE;
- unsigned frac1 : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0) - _FP_W_TYPE_SIZE;
- unsigned exp : _FP_EXPBITS_D;
- unsigned sign : 1;
-#endif
- } bits __attribute__((packed));
-};
-
-#define FP_DECL_D(X) _FP_DECL(2,X)
-#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_2(D,X,val)
-#define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_2(D,val,X)
-
-#define FP_UNPACK_D(X,val) \
- do { \
- _FP_UNPACK_RAW_2(D,X,val); \
- _FP_UNPACK_CANONICAL(D,2,X); \
- } while (0)
-
-#define FP_PACK_D(val,X) \
- do { \
- _FP_PACK_CANONICAL(D,2,X); \
- _FP_PACK_RAW_2(D,val,X); \
- } while (0)
-
-#define FP_NEG_D(R,X) _FP_NEG(D,2,R,X)
-#define FP_ADD_D(R,X,Y) _FP_ADD(D,2,R,X,Y)
-#define FP_SUB_D(R,X,Y) _FP_SUB(D,2,R,X,Y)
-#define FP_MUL_D(R,X,Y) _FP_MUL(D,2,R,X,Y)
-#define FP_DIV_D(R,X,Y) _FP_DIV(D,2,R,X,Y)
-#define FP_SQRT_D(R,X) _FP_SQRT(D,2,R,X)
-
-#define FP_CMP_D(r,X,Y,un) _FP_CMP(D,2,r,X,Y,un)
-#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,2,r,X,Y)
-
-#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,2,r,X,rsz,rsg)
-#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,2,X,r,rs,rt)
-
-#else
-
-union _FP_UNION_D
-{
- double flt;
- struct {
-#if __BYTE_ORDER == __BIG_ENDIAN
- unsigned sign : 1;
- unsigned exp : _FP_EXPBITS_D;
- unsigned long frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0);
-#else
- unsigned long frac : _FP_FRACBITS_D - (_FP_IMPLBIT_D != 0);
- unsigned exp : _FP_EXPBITS_D;
- unsigned sign : 1;
-#endif
- } bits __attribute__((packed));
-};
-
-#define FP_DECL_D(X) _FP_DECL(1,X)
-#define FP_UNPACK_RAW_D(X,val) _FP_UNPACK_RAW_1(D,X,val)
-#define FP_PACK_RAW_D(val,X) _FP_PACK_RAW_1(D,val,X)
-
-#define FP_UNPACK_D(X,val) \
- do { \
- _FP_UNPACK_RAW_1(D,X,val); \
- _FP_UNPACK_CANONICAL(D,1,X); \
- } while (0)
-
-#define FP_PACK_D(val,X) \
- do { \
- _FP_PACK_CANONICAL(D,1,X); \
- _FP_PACK_RAW_1(D,val,X); \
- } while (0)
-
-#define FP_NEG_D(R,X) _FP_NEG(D,1,R,X)
-#define FP_ADD_D(R,X,Y) _FP_ADD(D,1,R,X,Y)
-#define FP_SUB_D(R,X,Y) _FP_SUB(D,1,R,X,Y)
-#define FP_MUL_D(R,X,Y) _FP_MUL(D,1,R,X,Y)
-#define FP_DIV_D(R,X,Y) _FP_DIV(D,1,R,X,Y)
-#define FP_SQRT_D(R,X) _FP_SQRT(D,1,R,X)
-
-/* The implementation of _FP_MUL_D and _FP_DIV_D should be chosen by
- the target machine. */
-
-#define FP_CMP_D(r,X,Y,un) _FP_CMP(D,1,r,X,Y,un)
-#define FP_CMP_EQ_D(r,X,Y) _FP_CMP_EQ(D,1,r,X,Y)
-
-#define FP_TO_INT_D(r,X,rsz,rsg) _FP_TO_INT(D,1,r,X,rsz,rsg)
-#define FP_FROM_INT_D(X,r,rs,rt) _FP_FROM_INT(D,1,X,r,rs,rt)
-
-#endif /* W_TYPE_SIZE < 64 */
diff --git a/arch/powerpc/math-emu/op-1.h b/arch/powerpc/math-emu/op-1.h
deleted file mode 100644
index c92fa95..0000000
--- a/arch/powerpc/math-emu/op-1.h
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Basic one-word fraction declaration and manipulation.
- */
-
-#define _FP_FRAC_DECL_1(X) _FP_W_TYPE X##_f
-#define _FP_FRAC_COPY_1(D,S) (D##_f = S##_f)
-#define _FP_FRAC_SET_1(X,I) (X##_f = I)
-#define _FP_FRAC_HIGH_1(X) (X##_f)
-#define _FP_FRAC_LOW_1(X) (X##_f)
-#define _FP_FRAC_WORD_1(X,w) (X##_f)
-
-#define _FP_FRAC_ADDI_1(X,I) (X##_f += I)
-#define _FP_FRAC_SLL_1(X,N) \
- do { \
- if (__builtin_constant_p(N) && (N) == 1) \
- X##_f += X##_f; \
- else \
- X##_f <<= (N); \
- } while (0)
-#define _FP_FRAC_SRL_1(X,N) (X##_f >>= N)
-
-/* Right shift with sticky-lsb. */
-#define _FP_FRAC_SRS_1(X,N,sz) __FP_FRAC_SRS_1(X##_f, N, sz)
-
-#define __FP_FRAC_SRS_1(X,N,sz) \
- (X = (X >> (N) | (__builtin_constant_p(N) && (N) == 1 \
- ? X & 1 : (X << (_FP_W_TYPE_SIZE - (N))) != 0)))
-
-#define _FP_FRAC_ADD_1(R,X,Y) (R##_f = X##_f + Y##_f)
-#define _FP_FRAC_SUB_1(R,X,Y) (R##_f = X##_f - Y##_f)
-#define _FP_FRAC_CLZ_1(z, X) __FP_CLZ(z, X##_f)
-
-/* Predicates */
-#define _FP_FRAC_NEGP_1(X) ((_FP_WS_TYPE)X##_f < 0)
-#define _FP_FRAC_ZEROP_1(X) (X##_f == 0)
-#define _FP_FRAC_OVERP_1(fs,X) (X##_f & _FP_OVERFLOW_##fs)
-#define _FP_FRAC_EQ_1(X, Y) (X##_f == Y##_f)
-#define _FP_FRAC_GE_1(X, Y) (X##_f >= Y##_f)
-#define _FP_FRAC_GT_1(X, Y) (X##_f > Y##_f)
-
-#define _FP_ZEROFRAC_1 0
-#define _FP_MINFRAC_1 1
-
-/*
- * Unpack the raw bits of a native fp value. Do not classify or
- * normalize the data.
- */
-
-#define _FP_UNPACK_RAW_1(fs, X, val) \
- do { \
- union _FP_UNION_##fs _flo; _flo.flt = (val); \
- \
- X##_f = _flo.bits.frac; \
- X##_e = _flo.bits.exp; \
- X##_s = _flo.bits.sign; \
- } while (0)
-
-
-/*
- * Repack the raw bits of a native fp value.
- */
-
-#define _FP_PACK_RAW_1(fs, val, X) \
- do { \
- union _FP_UNION_##fs _flo; \
- \
- _flo.bits.frac = X##_f; \
- _flo.bits.exp = X##_e; \
- _flo.bits.sign = X##_s; \
- \
- (val) = _flo.flt; \
- } while (0)
-
-
-/*
- * Multiplication algorithms:
- */
-
-/* Basic. Assuming the host word size is >= 2*FRACBITS, we can do the
- multiplication immediately. */
-
-#define _FP_MUL_MEAT_1_imm(fs, R, X, Y) \
- do { \
- R##_f = X##_f * Y##_f; \
- /* Normalize since we know where the msb of the multiplicands \
- were (bit B), we know that the msb of the of the product is \
- at either 2B or 2B-1. */ \
- _FP_FRAC_SRS_1(R, _FP_WFRACBITS_##fs-1, 2*_FP_WFRACBITS_##fs); \
- } while (0)
-
-/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */
-
-#define _FP_MUL_MEAT_1_wide(fs, R, X, Y, doit) \
- do { \
- _FP_W_TYPE _Z_f0, _Z_f1; \
- doit(_Z_f1, _Z_f0, X##_f, Y##_f); \
- /* Normalize since we know where the msb of the multiplicands \
- were (bit B), we know that the msb of the of the product is \
- at either 2B or 2B-1. */ \
- _FP_FRAC_SRS_2(_Z, _FP_WFRACBITS_##fs-1, 2*_FP_WFRACBITS_##fs); \
- R##_f = _Z_f0; \
- } while (0)
-
-/* Finally, a simple widening multiply algorithm. What fun! */
-
-#define _FP_MUL_MEAT_1_hard(fs, R, X, Y) \
- do { \
- _FP_W_TYPE _xh, _xl, _yh, _yl, _z_f0, _z_f1, _a_f0, _a_f1; \
- \
- /* split the words in half */ \
- _xh = X##_f >> (_FP_W_TYPE_SIZE/2); \
- _xl = X##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1); \
- _yh = Y##_f >> (_FP_W_TYPE_SIZE/2); \
- _yl = Y##_f & (((_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2)) - 1); \
- \
- /* multiply the pieces */ \
- _z_f0 = _xl * _yl; \
- _a_f0 = _xh * _yl; \
- _a_f1 = _xl * _yh; \
- _z_f1 = _xh * _yh; \
- \
- /* reassemble into two full words */ \
- if ((_a_f0 += _a_f1) < _a_f1) \
- _z_f1 += (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE/2); \
- _a_f1 = _a_f0 >> (_FP_W_TYPE_SIZE/2); \
- _a_f0 = _a_f0 << (_FP_W_TYPE_SIZE/2); \
- _FP_FRAC_ADD_2(_z, _z, _a); \
- \
- /* normalize */ \
- _FP_FRAC_SRS_2(_z, _FP_WFRACBITS_##fs - 1, 2*_FP_WFRACBITS_##fs); \
- R##_f = _z_f0; \
- } while (0)
-
-
-/*
- * Division algorithms:
- */
-
-/* Basic. Assuming the host word size is >= 2*FRACBITS, we can do the
- division immediately. Give this macro either _FP_DIV_HELP_imm for
- C primitives or _FP_DIV_HELP_ldiv for the ISO function. Which you
- choose will depend on what the compiler does with divrem4. */
-
-#define _FP_DIV_MEAT_1_imm(fs, R, X, Y, doit) \
- do { \
- _FP_W_TYPE _q, _r; \
- X##_f <<= (X##_f < Y##_f \
- ? R##_e--, _FP_WFRACBITS_##fs \
- : _FP_WFRACBITS_##fs - 1); \
- doit(_q, _r, X##_f, Y##_f); \
- R##_f = _q | (_r != 0); \
- } while (0)
-
-/* GCC's longlong.h defines a 2W / 1W => (1W,1W) primitive udiv_qrnnd
- that may be useful in this situation. This first is for a primitive
- that requires normalization, the second for one that does not. Look
- for UDIV_NEEDS_NORMALIZATION to tell which your machine needs. */
-
-#define _FP_DIV_MEAT_1_udiv_norm(fs, R, X, Y) \
- do { \
- _FP_W_TYPE _nh, _nl, _q, _r; \
- \
- /* Normalize Y -- i.e. make the most significant bit set. */ \
- Y##_f <<= _FP_WFRACXBITS_##fs - 1; \
- \
- /* Shift X op correspondingly high, that is, up one full word. */ \
- if (X##_f <= Y##_f) \
- { \
- _nl = 0; \
- _nh = X##_f; \
- } \
- else \
- { \
- R##_e++; \
- _nl = X##_f << (_FP_W_TYPE_SIZE-1); \
- _nh = X##_f >> 1; \
- } \
- \
- udiv_qrnnd(_q, _r, _nh, _nl, Y##_f); \
- R##_f = _q | (_r != 0); \
- } while (0)
-
-#define _FP_DIV_MEAT_1_udiv(fs, R, X, Y) \
- do { \
- _FP_W_TYPE _nh, _nl, _q, _r; \
- if (X##_f < Y##_f) \
- { \
- R##_e--; \
- _nl = X##_f << _FP_WFRACBITS_##fs; \
- _nh = X##_f >> _FP_WFRACXBITS_##fs; \
- } \
- else \
- { \
- _nl = X##_f << (_FP_WFRACBITS_##fs - 1); \
- _nh = X##_f >> (_FP_WFRACXBITS_##fs + 1); \
- } \
- udiv_qrnnd(_q, _r, _nh, _nl, Y##_f); \
- R##_f = _q | (_r != 0); \
- } while (0)
-
-
-/*
- * Square root algorithms:
- * We have just one right now, maybe Newton approximation
- * should be added for those machines where division is fast.
- */
-
-#define _FP_SQRT_MEAT_1(R, S, T, X, q) \
- do { \
- while (q) \
- { \
- T##_f = S##_f + q; \
- if (T##_f <= X##_f) \
- { \
- S##_f = T##_f + q; \
- X##_f -= T##_f; \
- R##_f += q; \
- } \
- _FP_FRAC_SLL_1(X, 1); \
- q >>= 1; \
- } \
- } while (0)
-
-/*
- * Assembly/disassembly for converting to/from integral types.
- * No shifting or overflow handled here.
- */
-
-#define _FP_FRAC_ASSEMBLE_1(r, X, rsize) (r = X##_f)
-#define _FP_FRAC_DISASSEMBLE_1(X, r, rsize) (X##_f = r)
-
-
-/*
- * Convert FP values between word sizes
- */
-
-#define _FP_FRAC_CONV_1_1(dfs, sfs, D, S) \
- do { \
- D##_f = S##_f; \
- if (_FP_WFRACBITS_##sfs > _FP_WFRACBITS_##dfs) \
- _FP_FRAC_SRS_1(D, (_FP_WFRACBITS_##sfs-_FP_WFRACBITS_##dfs), \
- _FP_WFRACBITS_##sfs); \
- else \
- D##_f <<= _FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs; \
- } while (0)
diff --git a/arch/powerpc/math-emu/op-2.h b/arch/powerpc/math-emu/op-2.h
deleted file mode 100644
index 7d6f17c..0000000
--- a/arch/powerpc/math-emu/op-2.h
+++ /dev/null
@@ -1,434 +0,0 @@
-/*
- * Basic two-word fraction declaration and manipulation.
- */
-
-#define _FP_FRAC_DECL_2(X) _FP_W_TYPE X##_f0, X##_f1
-#define _FP_FRAC_COPY_2(D,S) (D##_f0 = S##_f0, D##_f1 = S##_f1)
-#define _FP_FRAC_SET_2(X,I) __FP_FRAC_SET_2(X, I)
-#define _FP_FRAC_HIGH_2(X) (X##_f1)
-#define _FP_FRAC_LOW_2(X) (X##_f0)
-#define _FP_FRAC_WORD_2(X,w) (X##_f##w)
-
-#define _FP_FRAC_SLL_2(X,N) \
- do { \
- if ((N) < _FP_W_TYPE_SIZE) \
- { \
- if (__builtin_constant_p(N) && (N) == 1) \
- { \
- X##_f1 = X##_f1 + X##_f1 + (((_FP_WS_TYPE)(X##_f0)) < 0); \
- X##_f0 += X##_f0; \
- } \
- else \
- { \
- X##_f1 = X##_f1 << (N) | X##_f0 >> (_FP_W_TYPE_SIZE - (N)); \
- X##_f0 <<= (N); \
- } \
- } \
- else \
- { \
- X##_f1 = X##_f0 << ((N) - _FP_W_TYPE_SIZE); \
- X##_f0 = 0; \
- } \
- } while (0)
-
-#define _FP_FRAC_SRL_2(X,N) \
- do { \
- if ((N) < _FP_W_TYPE_SIZE) \
- { \
- X##_f0 = X##_f0 >> (N) | X##_f1 << (_FP_W_TYPE_SIZE - (N)); \
- X##_f1 >>= (N); \
- } \
- else \
- { \
- X##_f0 = X##_f1 >> ((N) - _FP_W_TYPE_SIZE); \
- X##_f1 = 0; \
- } \
- } while (0)
-
-/* Right shift with sticky-lsb. */
-#define _FP_FRAC_SRS_2(X,N,sz) \
- do { \
- if ((N) < _FP_W_TYPE_SIZE) \
- { \
- X##_f0 = (X##_f1 << (_FP_W_TYPE_SIZE - (N)) | X##_f0 >> (N) | \
- (__builtin_constant_p(N) && (N) == 1 \
- ? X##_f0 & 1 \
- : (X##_f0 << (_FP_W_TYPE_SIZE - (N))) != 0)); \
- X##_f1 >>= (N); \
- } \
- else \
- { \
- X##_f0 = (X##_f1 >> ((N) - _FP_W_TYPE_SIZE) | \
- (((X##_f1 << (2 * _FP_W_TYPE_SIZE - (N))) | \
- X##_f0) != 0)); \
- X##_f1 = 0; \
- } \
- } while (0)
-
-#define _FP_FRAC_ADDI_2(X,I) \
- __FP_FRAC_ADDI_2(X##_f1, X##_f0, I)
-
-#define _FP_FRAC_ADD_2(R,X,Y) \
- __FP_FRAC_ADD_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0)
-
-#define _FP_FRAC_SUB_2(R,X,Y) \
- __FP_FRAC_SUB_2(R##_f1, R##_f0, X##_f1, X##_f0, Y##_f1, Y##_f0)
-
-#define _FP_FRAC_CLZ_2(R,X) \
- do { \
- if (X##_f1) \
- __FP_CLZ(R,X##_f1); \
- else \
- { \
- __FP_CLZ(R,X##_f0); \
- R += _FP_W_TYPE_SIZE; \
- } \
- } while(0)
-
-/* Predicates */
-#define _FP_FRAC_NEGP_2(X) ((_FP_WS_TYPE)X##_f1 < 0)
-#define _FP_FRAC_ZEROP_2(X) ((X##_f1 | X##_f0) == 0)
-#define _FP_FRAC_OVERP_2(fs,X) (X##_f1 & _FP_OVERFLOW_##fs)
-#define _FP_FRAC_EQ_2(X, Y) (X##_f1 == Y##_f1 && X##_f0 == Y##_f0)
-#define _FP_FRAC_GT_2(X, Y) \
- ((X##_f1 > Y##_f1) || (X##_f1 == Y##_f1 && X##_f0 > Y##_f0))
-#define _FP_FRAC_GE_2(X, Y) \
- ((X##_f1 > Y##_f1) || (X##_f1 == Y##_f1 && X##_f0 >= Y##_f0))
-
-#define _FP_ZEROFRAC_2 0, 0
-#define _FP_MINFRAC_2 0, 1
-
-/*
- * Internals
- */
-
-#define __FP_FRAC_SET_2(X,I1,I0) (X##_f0 = I0, X##_f1 = I1)
-
-#define __FP_CLZ_2(R, xh, xl) \
- do { \
- if (xh) \
- __FP_CLZ(R,xl); \
- else \
- { \
- __FP_CLZ(R,xl); \
- R += _FP_W_TYPE_SIZE; \
- } \
- } while(0)
-
-#if 0
-
-#ifndef __FP_FRAC_ADDI_2
-#define __FP_FRAC_ADDI_2(xh, xl, i) \
- (xh += ((xl += i) < i))
-#endif
-#ifndef __FP_FRAC_ADD_2
-#define __FP_FRAC_ADD_2(rh, rl, xh, xl, yh, yl) \
- (rh = xh + yh + ((rl = xl + yl) < xl))
-#endif
-#ifndef __FP_FRAC_SUB_2
-#define __FP_FRAC_SUB_2(rh, rl, xh, xl, yh, yl) \
- (rh = xh - yh - ((rl = xl - yl) > xl))
-#endif
-
-#else
-
-#undef __FP_FRAC_ADDI_2
-#define __FP_FRAC_ADDI_2(xh, xl, i) add_ssaaaa(xh, xl, xh, xl, 0, i)
-#undef __FP_FRAC_ADD_2
-#define __FP_FRAC_ADD_2 add_ssaaaa
-#undef __FP_FRAC_SUB_2
-#define __FP_FRAC_SUB_2 sub_ddmmss
-
-#endif
-
-/*
- * Unpack the raw bits of a native fp value. Do not classify or
- * normalize the data.
- */
-
-#define _FP_UNPACK_RAW_2(fs, X, val) \
- do { \
- union _FP_UNION_##fs _flo; _flo.flt = (val); \
- \
- X##_f0 = _flo.bits.frac0; \
- X##_f1 = _flo.bits.frac1; \
- X##_e = _flo.bits.exp; \
- X##_s = _flo.bits.sign; \
- } while (0)
-
-
-/*
- * Repack the raw bits of a native fp value.
- */
-
-#define _FP_PACK_RAW_2(fs, val, X) \
- do { \
- union _FP_UNION_##fs _flo; \
- \
- _flo.bits.frac0 = X##_f0; \
- _flo.bits.frac1 = X##_f1; \
- _flo.bits.exp = X##_e; \
- _flo.bits.sign = X##_s; \
- \
- (val) = _flo.flt; \
- } while (0)
-
-
-/*
- * Multiplication algorithms:
- */
-
-/* Given a 1W * 1W => 2W primitive, do the extended multiplication. */
-
-#define _FP_MUL_MEAT_2_wide(fs, R, X, Y, doit) \
- do { \
- _FP_FRAC_DECL_4(_z); _FP_FRAC_DECL_2(_b); _FP_FRAC_DECL_2(_c); \
- \
- doit(_FP_FRAC_WORD_4(_z,1), _FP_FRAC_WORD_4(_z,0), X##_f0, Y##_f0); \
- doit(_b_f1, _b_f0, X##_f0, Y##_f1); \
- doit(_c_f1, _c_f0, X##_f1, Y##_f0); \
- doit(_FP_FRAC_WORD_4(_z,3), _FP_FRAC_WORD_4(_z,2), X##_f1, Y##_f1); \
- \
- __FP_FRAC_ADD_4(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
- _FP_FRAC_WORD_4(_z,1),_FP_FRAC_WORD_4(_z,0), \
- 0, _b_f1, _b_f0, 0, \
- _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
- _FP_FRAC_WORD_4(_z,1),_FP_FRAC_WORD_4(_z,0)); \
- __FP_FRAC_ADD_4(_FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
- _FP_FRAC_WORD_4(_z,1),_FP_FRAC_WORD_4(_z,0), \
- 0, _c_f1, _c_f0, 0, \
- _FP_FRAC_WORD_4(_z,3),_FP_FRAC_WORD_4(_z,2), \
- _FP_FRAC_WORD_4(_z,1),_FP_FRAC_WORD_4(_z,0)); \
- \
- /* Normalize since we know where the msb of the multiplicands \
- were (bit B), we know that the msb of the of the product is \
- at either 2B or 2B-1. */ \
- _FP_FRAC_SRS_4(_z, _FP_WFRACBITS_##fs-1, 2*_FP_WFRACBITS_##fs); \
- R##_f0 = _FP_FRAC_WORD_4(_z,0); \
- R##_f1 = _FP_FRAC_WORD_4(_z,1); \
- } while (0)
-
-/* This next macro appears to be totally broken. Fortunately nowhere
- * seems to use it :-> The problem is that we define _z[4] but
- * then use it in _FP_FRAC_SRS_4, which will attempt to access
- * _z_f[n] which will cause an error. The fix probably involves
- * declaring it with _FP_FRAC_DECL_4, see previous macro. -- PMM 02/1998
- */
-#define _FP_MUL_MEAT_2_gmp(fs, R, X, Y) \
- do { \
- _FP_W_TYPE _x[2], _y[2], _z[4]; \
- _x[0] = X##_f0; _x[1] = X##_f1; \
- _y[0] = Y##_f0; _y[1] = Y##_f1; \
- \
- mpn_mul_n(_z, _x, _y, 2); \
- \
- /* Normalize since we know where the msb of the multiplicands \
- were (bit B), we know that the msb of the of the product is \
- at either 2B or 2B-1. */ \
- _FP_FRAC_SRS_4(_z, _FP_WFRACBITS##_fs-1, 2*_FP_WFRACBITS_##fs); \
- R##_f0 = _z[0]; \
- R##_f1 = _z[1]; \
- } while (0)
-
-
-/*
- * Division algorithms:
- * This seems to be giving me difficulties -- PMM
- * Look, NetBSD seems to be able to comment algorithms. Can't you?
- * I've thrown printks at the problem.
- * This now appears to work, but I still don't really know why.
- * Also, I don't think the result is properly normalised...
- */
-
-#define _FP_DIV_MEAT_2_udiv_64(fs, R, X, Y) \
- do { \
- extern void _fp_udivmodti4(_FP_W_TYPE q[2], _FP_W_TYPE r[2], \
- _FP_W_TYPE n1, _FP_W_TYPE n0, \
- _FP_W_TYPE d1, _FP_W_TYPE d0); \
- _FP_W_TYPE _n_f3, _n_f2, _n_f1, _n_f0, _r_f1, _r_f0; \
- _FP_W_TYPE _q_f1, _q_f0, _m_f1, _m_f0; \
- _FP_W_TYPE _rmem[2], _qmem[2]; \
- /* I think this check is to ensure that the result is normalised. \
- * Assuming X,Y normalised (ie in [1.0,2.0)) X/Y will be in \
- * [0.5,2.0). Furthermore, it will be less than 1.0 iff X < Y. \
- * In this case we tweak things. (this is based on comments in \
- * the NetBSD FPU emulation code. ) \
- * We know X,Y are normalised because we ensure this as part of \
- * the unpacking process. -- PMM \
- */ \
- if (_FP_FRAC_GT_2(X, Y)) \
- { \
-/* R##_e++; */ \
- _n_f3 = X##_f1 >> 1; \
- _n_f2 = X##_f1 << (_FP_W_TYPE_SIZE - 1) | X##_f0 >> 1; \
- _n_f1 = X##_f0 << (_FP_W_TYPE_SIZE - 1); \
- _n_f0 = 0; \
- } \
- else \
- { \
- R##_e--; \
- _n_f3 = X##_f1; \
- _n_f2 = X##_f0; \
- _n_f1 = _n_f0 = 0; \
- } \
- \
- /* Normalize, i.e. make the most significant bit of the \
- denominator set. CHANGED: - 1 to nothing -- PMM */ \
- _FP_FRAC_SLL_2(Y, _FP_WFRACXBITS_##fs /* -1 */); \
- \
- /* Do the 256/128 bit division given the 128-bit _fp_udivmodtf4 \
- primitive snagged from libgcc2.c. */ \
- \
- _fp_udivmodti4(_qmem, _rmem, _n_f3, _n_f2, 0, Y##_f1); \
- _q_f1 = _qmem[0]; \
- umul_ppmm(_m_f1, _m_f0, _q_f1, Y##_f0); \
- _r_f1 = _rmem[0]; \
- _r_f0 = _n_f1; \
- if (_FP_FRAC_GT_2(_m, _r)) \
- { \
- _q_f1--; \
- _FP_FRAC_ADD_2(_r, _r, Y); \
- if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r)) \
- { \
- _q_f1--; \
- _FP_FRAC_ADD_2(_r, _r, Y); \
- } \
- } \
- _FP_FRAC_SUB_2(_r, _r, _m); \
- \
- _fp_udivmodti4(_qmem, _rmem, _r_f1, _r_f0, 0, Y##_f1); \
- _q_f0 = _qmem[0]; \
- umul_ppmm(_m_f1, _m_f0, _q_f0, Y##_f0); \
- _r_f1 = _rmem[0]; \
- _r_f0 = _n_f0; \
- if (_FP_FRAC_GT_2(_m, _r)) \
- { \
- _q_f0--; \
- _FP_FRAC_ADD_2(_r, _r, Y); \
- if (_FP_FRAC_GE_2(_r, Y) && _FP_FRAC_GT_2(_m, _r)) \
- { \
- _q_f0--; \
- _FP_FRAC_ADD_2(_r, _r, Y); \
- } \
- } \
- _FP_FRAC_SUB_2(_r, _r, _m); \
- \
- R##_f1 = _q_f1; \
- R##_f0 = _q_f0 | ((_r_f1 | _r_f0) != 0); \
- /* adjust so answer is normalized again. I'm not sure what the \
- * final sz param should be. In practice it's never used since \
- * N is 1 which is always going to be < _FP_W_TYPE_SIZE... \
- */ \
- /* _FP_FRAC_SRS_2(R,1,_FP_WFRACBITS_##fs); */ \
- } while (0)
-
-
-#define _FP_DIV_MEAT_2_gmp(fs, R, X, Y) \
- do { \
- _FP_W_TYPE _x[4], _y[2], _z[4]; \
- _y[0] = Y##_f0; _y[1] = Y##_f1; \
- _x[0] = _x[3] = 0; \
- if (_FP_FRAC_GT_2(X, Y)) \
- { \
- R##_e++; \
- _x[1] = (X##_f0 << (_FP_WFRACBITS-1 - _FP_W_TYPE_SIZE) | \
- X##_f1 >> (_FP_W_TYPE_SIZE - \
- (_FP_WFRACBITS-1 - _FP_W_TYPE_SIZE))); \
- _x[2] = X##_f1 << (_FP_WFRACBITS-1 - _FP_W_TYPE_SIZE); \
- } \
- else \
- { \
- _x[1] = (X##_f0 << (_FP_WFRACBITS - _FP_W_TYPE_SIZE) | \
- X##_f1 >> (_FP_W_TYPE_SIZE - \
- (_FP_WFRACBITS - _FP_W_TYPE_SIZE))); \
- _x[2] = X##_f1 << (_FP_WFRACBITS - _FP_W_TYPE_SIZE); \
- } \
- \
- (void) mpn_divrem (_z, 0, _x, 4, _y, 2); \
- R##_f1 = _z[1]; \
- R##_f0 = _z[0] | ((_x[0] | _x[1]) != 0); \
- } while (0)
-
-
-/*
- * Square root algorithms:
- * We have just one right now, maybe Newton approximation
- * should be added for those machines where division is fast.
- */
-
-#define _FP_SQRT_MEAT_2(R, S, T, X, q) \
- do { \
- while (q) \
- { \
- T##_f1 = S##_f1 + q; \
- if (T##_f1 <= X##_f1) \
- { \
- S##_f1 = T##_f1 + q; \
- X##_f1 -= T##_f1; \
- R##_f1 += q; \
- } \
- _FP_FRAC_SLL_2(X, 1); \
- q >>= 1; \
- } \
- q = (_FP_W_TYPE)1 << (_FP_W_TYPE_SIZE - 1); \
- while (q) \
- { \
- T##_f0 = S##_f0 + q; \
- T##_f1 = S##_f1; \
- if (T##_f1 < X##_f1 || \
- (T##_f1 == X##_f1 && T##_f0 < X##_f0)) \
- { \
- S##_f0 = T##_f0 + q; \
- if (((_FP_WS_TYPE)T##_f0) < 0 && \
- ((_FP_WS_TYPE)S##_f0) >= 0) \
- S##_f1++; \
- _FP_FRAC_SUB_2(X, X, T); \
- R##_f0 += q; \
- } \
- _FP_FRAC_SLL_2(X, 1); \
- q >>= 1; \
- } \
- } while (0)
-
-
-/*
- * Assembly/disassembly for converting to/from integral types.
- * No shifting or overflow handled here.
- */
-
-#define _FP_FRAC_ASSEMBLE_2(r, X, rsize) \
- do { \
- if (rsize <= _FP_W_TYPE_SIZE) \
- r = X##_f0; \
- else \
- { \
- r = X##_f1; \
- r <<= _FP_W_TYPE_SIZE; \
- r += X##_f0; \
- } \
- } while (0)
-
-#define _FP_FRAC_DISASSEMBLE_2(X, r, rsize) \
- do { \
- X##_f0 = r; \
- X##_f1 = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \
- } while (0)
-
-/*
- * Convert FP values between word sizes
- */
-
-#define _FP_FRAC_CONV_1_2(dfs, sfs, D, S) \
- do { \
- _FP_FRAC_SRS_2(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs), \
- _FP_WFRACBITS_##sfs); \
- D##_f = S##_f0; \
- } while (0)
-
-#define _FP_FRAC_CONV_2_1(dfs, sfs, D, S) \
- do { \
- D##_f0 = S##_f; \
- D##_f1 = 0; \
- _FP_FRAC_SLL_2(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs)); \
- } while (0)
-
diff --git a/arch/powerpc/math-emu/op-4.h b/arch/powerpc/math-emu/op-4.h
deleted file mode 100644
index c9ae626..0000000
--- a/arch/powerpc/math-emu/op-4.h
+++ /dev/null
@@ -1,317 +0,0 @@
-/*
- * Basic four-word fraction declaration and manipulation.
- *
- * When adding quadword support for 32 bit machines, we need
- * to be a little careful as double multiply uses some of these
- * macros: (in op-2.h)
- * _FP_MUL_MEAT_2_wide() uses _FP_FRAC_DECL_4, _FP_FRAC_WORD_4,
- * _FP_FRAC_ADD_4, _FP_FRAC_SRS_4
- * _FP_MUL_MEAT_2_gmp() uses _FP_FRAC_SRS_4 (and should use
- * _FP_FRAC_DECL_4: it appears to be broken and is not used
- * anywhere anyway. )
- *
- * I've now fixed all the macros that were here from the sparc64 code.
- * [*none* of the shift macros were correct!] -- PMM 02/1998
- *
- * The only quadword stuff that remains to be coded is:
- * 1) the conversion to/from ints, which requires
- * that we check (in op-common.h) that the following do the right thing
- * for quadwords: _FP_TO_INT(Q,4,r,X,rsz,rsg), _FP_FROM_INT(Q,4,X,r,rs,rt)
- * 2) multiply, divide and sqrt, which require:
- * _FP_MUL_MEAT_4_*(R,X,Y), _FP_DIV_MEAT_4_*(R,X,Y), _FP_SQRT_MEAT_4(R,S,T,X,q),
- * This also needs _FP_MUL_MEAT_Q and _FP_DIV_MEAT_Q to be defined to
- * some suitable _FP_MUL_MEAT_4_* macros in sfp-machine.h.
- * [we're free to choose whatever FP_MUL_MEAT_4_* macros we need for
- * these; they are used nowhere else. ]
- */
-
-#define _FP_FRAC_DECL_4(X) _FP_W_TYPE X##_f[4]
-#define _FP_FRAC_COPY_4(D,S) \
- (D##_f[0] = S##_f[0], D##_f[1] = S##_f[1], \
- D##_f[2] = S##_f[2], D##_f[3] = S##_f[3])
-/* The _FP_FRAC_SET_n(X,I) macro is intended for use with another
- * macro such as _FP_ZEROFRAC_n which returns n comma separated values.
- * The result is that we get an expansion of __FP_FRAC_SET_n(X,I0,I1,I2,I3)
- * which just assigns the In values to the array X##_f[].
- * This is why the number of parameters doesn't appear to match
- * at first glance... -- PMM
- */
-#define _FP_FRAC_SET_4(X,I) __FP_FRAC_SET_4(X, I)
-#define _FP_FRAC_HIGH_4(X) (X##_f[3])
-#define _FP_FRAC_LOW_4(X) (X##_f[0])
-#define _FP_FRAC_WORD_4(X,w) (X##_f[w])
-
-#define _FP_FRAC_SLL_4(X,N) \
- do { \
- _FP_I_TYPE _up, _down, _skip, _i; \
- _skip = (N) / _FP_W_TYPE_SIZE; \
- _up = (N) % _FP_W_TYPE_SIZE; \
- _down = _FP_W_TYPE_SIZE - _up; \
- for (_i = 3; _i > _skip; --_i) \
- X##_f[_i] = X##_f[_i-_skip] << _up | X##_f[_i-_skip-1] >> _down; \
-/* bugfixed: was X##_f[_i] <<= _up; -- PMM 02/1998 */ \
- X##_f[_i] = X##_f[0] << _up; \
- for (--_i; _i >= 0; --_i) \
- X##_f[_i] = 0; \
- } while (0)
-
-/* This one was broken too */
-#define _FP_FRAC_SRL_4(X,N) \
- do { \
- _FP_I_TYPE _up, _down, _skip, _i; \
- _skip = (N) / _FP_W_TYPE_SIZE; \
- _down = (N) % _FP_W_TYPE_SIZE; \
- _up = _FP_W_TYPE_SIZE - _down; \
- for (_i = 0; _i < 3-_skip; ++_i) \
- X##_f[_i] = X##_f[_i+_skip] >> _down | X##_f[_i+_skip+1] << _up; \
- X##_f[_i] = X##_f[3] >> _down; \
- for (++_i; _i < 4; ++_i) \
- X##_f[_i] = 0; \
- } while (0)
-
-
-/* Right shift with sticky-lsb.
- * What this actually means is that we do a standard right-shift,
- * but that if any of the bits that fall off the right hand side
- * were one then we always set the LSbit.
- */
-#define _FP_FRAC_SRS_4(X,N,size) \
- do { \
- _FP_I_TYPE _up, _down, _skip, _i; \
- _FP_W_TYPE _s; \
- _skip = (N) / _FP_W_TYPE_SIZE; \
- _down = (N) % _FP_W_TYPE_SIZE; \
- _up = _FP_W_TYPE_SIZE - _down; \
- for (_s = _i = 0; _i < _skip; ++_i) \
- _s |= X##_f[_i]; \
- _s |= X##_f[_i] << _up; \
-/* s is now != 0 if we want to set the LSbit */ \
- for (_i = 0; _i < 3-_skip; ++_i) \
- X##_f[_i] = X##_f[_i+_skip] >> _down | X##_f[_i+_skip+1] << _up; \
- X##_f[_i] = X##_f[3] >> _down; \
- for (++_i; _i < 4; ++_i) \
- X##_f[_i] = 0; \
- /* don't fix the LSB until the very end when we're sure f[0] is stable */ \
- X##_f[0] |= (_s != 0); \
- } while (0)
-
-#define _FP_FRAC_ADD_4(R,X,Y) \
- __FP_FRAC_ADD_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0], \
- X##_f[3], X##_f[2], X##_f[1], X##_f[0], \
- Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
-
-#define _FP_FRAC_SUB_4(R,X,Y) \
- __FP_FRAC_SUB_4(R##_f[3], R##_f[2], R##_f[1], R##_f[0], \
- X##_f[3], X##_f[2], X##_f[1], X##_f[0], \
- Y##_f[3], Y##_f[2], Y##_f[1], Y##_f[0])
-
-#define _FP_FRAC_ADDI_4(X,I) \
- __FP_FRAC_ADDI_4(X##_f[3], X##_f[2], X##_f[1], X##_f[0], I)
-
-#define _FP_ZEROFRAC_4 0,0,0,0
-#define _FP_MINFRAC_4 0,0,0,1
-
-#define _FP_FRAC_ZEROP_4(X) ((X##_f[0] | X##_f[1] | X##_f[2] | X##_f[3]) == 0)
-#define _FP_FRAC_NEGP_4(X) ((_FP_WS_TYPE)X##_f[3] < 0)
-#define _FP_FRAC_OVERP_4(fs,X) (X##_f[0] & _FP_OVERFLOW_##fs)
-
-#define _FP_FRAC_EQ_4(X,Y) \
- (X##_f[0] == Y##_f[0] && X##_f[1] == Y##_f[1] \
- && X##_f[2] == Y##_f[2] && X##_f[3] == Y##_f[3])
-
-#define _FP_FRAC_GT_4(X,Y) \
- (X##_f[3] > Y##_f[3] || \
- (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] || \
- (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] || \
- (X##_f[1] == Y##_f[1] && X##_f[0] > Y##_f[0]) \
- )) \
- )) \
- )
-
-#define _FP_FRAC_GE_4(X,Y) \
- (X##_f[3] > Y##_f[3] || \
- (X##_f[3] == Y##_f[3] && (X##_f[2] > Y##_f[2] || \
- (X##_f[2] == Y##_f[2] && (X##_f[1] > Y##_f[1] || \
- (X##_f[1] == Y##_f[1] && X##_f[0] >= Y##_f[0]) \
- )) \
- )) \
- )
-
-
-#define _FP_FRAC_CLZ_4(R,X) \
- do { \
- if (X##_f[3]) \
- { \
- __FP_CLZ(R,X##_f[3]); \
- } \
- else if (X##_f[2]) \
- { \
- __FP_CLZ(R,X##_f[2]); \
- R += _FP_W_TYPE_SIZE; \
- } \
- else if (X##_f[1]) \
- { \
- __FP_CLZ(R,X##_f[2]); \
- R += _FP_W_TYPE_SIZE*2; \
- } \
- else \
- { \
- __FP_CLZ(R,X##_f[0]); \
- R += _FP_W_TYPE_SIZE*3; \
- } \
- } while(0)
-
-
-#define _FP_UNPACK_RAW_4(fs, X, val) \
- do { \
- union _FP_UNION_##fs _flo; _flo.flt = (val); \
- X##_f[0] = _flo.bits.frac0; \
- X##_f[1] = _flo.bits.frac1; \
- X##_f[2] = _flo.bits.frac2; \
- X##_f[3] = _flo.bits.frac3; \
- X##_e = _flo.bits.exp; \
- X##_s = _flo.bits.sign; \
- } while (0)
-
-#define _FP_PACK_RAW_4(fs, val, X) \
- do { \
- union _FP_UNION_##fs _flo; \
- _flo.bits.frac0 = X##_f[0]; \
- _flo.bits.frac1 = X##_f[1]; \
- _flo.bits.frac2 = X##_f[2]; \
- _flo.bits.frac3 = X##_f[3]; \
- _flo.bits.exp = X##_e; \
- _flo.bits.sign = X##_s; \
- (val) = _flo.flt; \
- } while (0)
-
-
-/*
- * Internals
- */
-
-#define __FP_FRAC_SET_4(X,I3,I2,I1,I0) \
- (X##_f[3] = I3, X##_f[2] = I2, X##_f[1] = I1, X##_f[0] = I0)
-
-#ifndef __FP_FRAC_ADD_4
-#define __FP_FRAC_ADD_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \
- do { \
- int _c1, _c2, _c3; \
- r0 = x0 + y0; \
- _c1 = r0 < x0; \
- r1 = x1 + y1; \
- _c2 = r1 < x1; \
- r1 += _c1; \
- _c2 |= r1 < _c1; \
- r2 = x2 + y2; \
- _c3 = r2 < x2; \
- r2 += _c2; \
- _c3 |= r2 < _c2; \
- r3 = x3 + y3 + _c3; \
- } while (0)
-#endif
-
-#ifndef __FP_FRAC_SUB_4
-#define __FP_FRAC_SUB_4(r3,r2,r1,r0,x3,x2,x1,x0,y3,y2,y1,y0) \
- do { \
- int _c1, _c2, _c3; \
- r0 = x0 - y0; \
- _c1 = r0 > x0; \
- r1 = x1 - y1; \
- _c2 = r1 > x1; \
- r1 -= _c1; \
- _c2 |= r1 > _c1; \
- r2 = x2 - y2; \
- _c3 = r2 > x2; \
- r2 -= _c2; \
- _c3 |= r2 > _c2; \
- r3 = x3 - y3 - _c3; \
- } while (0)
-#endif
-
-#ifndef __FP_FRAC_ADDI_4
-/* I always wanted to be a lisp programmer :-> */
-#define __FP_FRAC_ADDI_4(x3,x2,x1,x0,i) \
- (x3 += ((x2 += ((x1 += ((x0 += i) < x0)) < x1) < x2)))
-#endif
-
-/* Convert FP values between word sizes. This appears to be more
- * complicated than I'd have expected it to be, so these might be
- * wrong... These macros are in any case somewhat bogus because they
- * use information about what various FRAC_n variables look like
- * internally [eg, that 2 word vars are X_f0 and x_f1]. But so do
- * the ones in op-2.h and op-1.h.
- */
-#define _FP_FRAC_CONV_1_4(dfs, sfs, D, S) \
- do { \
- _FP_FRAC_SRS_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs), \
- _FP_WFRACBITS_##sfs); \
- D##_f = S##_f[0]; \
- } while (0)
-
-#define _FP_FRAC_CONV_2_4(dfs, sfs, D, S) \
- do { \
- _FP_FRAC_SRS_4(S, (_FP_WFRACBITS_##sfs - _FP_WFRACBITS_##dfs), \
- _FP_WFRACBITS_##sfs); \
- D##_f0 = S##_f[0]; \
- D##_f1 = S##_f[1]; \
- } while (0)
-
-/* Assembly/disassembly for converting to/from integral types.
- * No shifting or overflow handled here.
- */
-/* Put the FP value X into r, which is an integer of size rsize. */
-#define _FP_FRAC_ASSEMBLE_4(r, X, rsize) \
- do { \
- if (rsize <= _FP_W_TYPE_SIZE) \
- r = X##_f[0]; \
- else if (rsize <= 2*_FP_W_TYPE_SIZE) \
- { \
- r = X##_f[1]; \
- r <<= _FP_W_TYPE_SIZE; \
- r += X##_f[0]; \
- } \
- else \
- { \
- /* I'm feeling lazy so we deal with int == 3words (implausible)*/ \
- /* and int == 4words as a single case. */ \
- r = X##_f[3]; \
- r <<= _FP_W_TYPE_SIZE; \
- r += X##_f[2]; \
- r <<= _FP_W_TYPE_SIZE; \
- r += X##_f[1]; \
- r <<= _FP_W_TYPE_SIZE; \
- r += X##_f[0]; \
- } \
- } while (0)
-
-/* "No disassemble Number Five!" */
-/* move an integer of size rsize into X's fractional part. We rely on
- * the _f[] array consisting of words of size _FP_W_TYPE_SIZE to avoid
- * having to mask the values we store into it.
- */
-#define _FP_FRAC_DISASSEMBLE_4(X, r, rsize) \
- do { \
- X##_f[0] = r; \
- X##_f[1] = (rsize <= _FP_W_TYPE_SIZE ? 0 : r >> _FP_W_TYPE_SIZE); \
- X##_f[2] = (rsize <= 2*_FP_W_TYPE_SIZE ? 0 : r >> 2*_FP_W_TYPE_SIZE); \
- X##_f[3] = (rsize <= 3*_FP_W_TYPE_SIZE ? 0 : r >> 3*_FP_W_TYPE_SIZE); \
- } while (0)
-
-#define _FP_FRAC_CONV_4_1(dfs, sfs, D, S) \
- do { \
- D##_f[0] = S##_f; \
- D##_f[1] = D##_f[2] = D##_f[3] = 0; \
- _FP_FRAC_SLL_4(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs)); \
- } while (0)
-
-#define _FP_FRAC_CONV_4_2(dfs, sfs, D, S) \
- do { \
- D##_f[0] = S##_f0; \
- D##_f[1] = S##_f1; \
- D##_f[2] = D##_f[3] = 0; \
- _FP_FRAC_SLL_4(D, (_FP_WFRACBITS_##dfs - _FP_WFRACBITS_##sfs)); \
- } while (0)
-
-/* FIXME! This has to be written */
-#define _FP_SQRT_MEAT_4(R, S, T, X, q)
diff --git a/arch/powerpc/math-emu/op-common.h b/arch/powerpc/math-emu/op-common.h
deleted file mode 100644
index afb82b6..0000000
--- a/arch/powerpc/math-emu/op-common.h
+++ /dev/null
@@ -1,688 +0,0 @@
-#define _FP_DECL(wc, X) \
- _FP_I_TYPE X##_c, X##_s, X##_e; \
- _FP_FRAC_DECL_##wc(X)
-
-/*
- * Finish truely unpacking a native fp value by classifying the kind
- * of fp value and normalizing both the exponent and the fraction.
- */
-
-#define _FP_UNPACK_CANONICAL(fs, wc, X) \
-do { \
- switch (X##_e) \
- { \
- default: \
- _FP_FRAC_HIGH_##wc(X) |= _FP_IMPLBIT_##fs; \
- _FP_FRAC_SLL_##wc(X, _FP_WORKBITS); \
- X##_e -= _FP_EXPBIAS_##fs; \
- X##_c = FP_CLS_NORMAL; \
- break; \
- \
- case 0: \
- if (_FP_FRAC_ZEROP_##wc(X)) \
- X##_c = FP_CLS_ZERO; \
- else \
- { \
- /* a denormalized number */ \
- _FP_I_TYPE _shift; \
- _FP_FRAC_CLZ_##wc(_shift, X); \
- _shift -= _FP_FRACXBITS_##fs; \
- _FP_FRAC_SLL_##wc(X, (_shift+_FP_WORKBITS)); \
- X##_e -= _FP_EXPBIAS_##fs - 1 + _shift; \
- X##_c = FP_CLS_NORMAL; \
- } \
- break; \
- \
- case _FP_EXPMAX_##fs: \
- if (_FP_FRAC_ZEROP_##wc(X)) \
- X##_c = FP_CLS_INF; \
- else \
- /* we don't differentiate between signaling and quiet nans */ \
- X##_c = FP_CLS_NAN; \
- break; \
- } \
-} while (0)
-
-
-/*
- * Before packing the bits back into the native fp result, take care
- * of such mundane things as rounding and overflow. Also, for some
- * kinds of fp values, the original parts may not have been fully
- * extracted -- but that is ok, we can regenerate them now.
- */
-
-#define _FP_PACK_CANONICAL(fs, wc, X) \
-({int __ret = 0; \
- switch (X##_c) \
- { \
- case FP_CLS_NORMAL: \
- X##_e += _FP_EXPBIAS_##fs; \
- if (X##_e > 0) \
- { \
- __ret |= _FP_ROUND(wc, X); \
- if (_FP_FRAC_OVERP_##wc(fs, X)) \
- { \
- _FP_FRAC_SRL_##wc(X, (_FP_WORKBITS+1)); \
- X##_e++; \
- } \
- else \
- _FP_FRAC_SRL_##wc(X, _FP_WORKBITS); \
- if (X##_e >= _FP_EXPMAX_##fs) \
- { \
- /* overflow to infinity */ \
- X##_e = _FP_EXPMAX_##fs; \
- _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
- __ret |= EFLAG_OVERFLOW; \
- } \
- } \
- else \
- { \
- /* we've got a denormalized number */ \
- X##_e = -X##_e + 1; \
- if (X##_e <= _FP_WFRACBITS_##fs) \
- { \
- _FP_FRAC_SRS_##wc(X, X##_e, _FP_WFRACBITS_##fs); \
- _FP_FRAC_SLL_##wc(X, 1); \
- if (_FP_FRAC_OVERP_##wc(fs, X)) \
- { \
- X##_e = 1; \
- _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
- } \
- else \
- { \
- X##_e = 0; \
- _FP_FRAC_SRL_##wc(X, _FP_WORKBITS+1); \
- __ret |= EFLAG_UNDERFLOW; \
- } \
- } \
- else \
- { \
- /* underflow to zero */ \
- X##_e = 0; \
- _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
- __ret |= EFLAG_UNDERFLOW; \
- } \
- } \
- break; \
- \
- case FP_CLS_ZERO: \
- X##_e = 0; \
- _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
- break; \
- \
- case FP_CLS_INF: \
- X##_e = _FP_EXPMAX_##fs; \
- _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
- break; \
- \
- case FP_CLS_NAN: \
- X##_e = _FP_EXPMAX_##fs; \
- if (!_FP_KEEPNANFRACP) \
- { \
- _FP_FRAC_SET_##wc(X, _FP_NANFRAC_##fs); \
- X##_s = 0; \
- } \
- else \
- _FP_FRAC_HIGH_##wc(X) |= _FP_QNANBIT_##fs; \
- break; \
- } \
- __ret; \
-})
-
-
-/*
- * Main addition routine. The input values should be cooked.
- */
-
-#define _FP_ADD(fs, wc, R, X, Y) \
-do { \
- switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
- { \
- case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
- { \
- /* shift the smaller number so that its exponent matches the larger */ \
- _FP_I_TYPE diff = X##_e - Y##_e; \
- \
- if (diff < 0) \
- { \
- diff = -diff; \
- if (diff <= _FP_WFRACBITS_##fs) \
- _FP_FRAC_SRS_##wc(X, diff, _FP_WFRACBITS_##fs); \
- else if (!_FP_FRAC_ZEROP_##wc(X)) \
- _FP_FRAC_SET_##wc(X, _FP_MINFRAC_##wc); \
- else \
- _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
- R##_e = Y##_e; \
- } \
- else \
- { \
- if (diff > 0) \
- { \
- if (diff <= _FP_WFRACBITS_##fs) \
- _FP_FRAC_SRS_##wc(Y, diff, _FP_WFRACBITS_##fs); \
- else if (!_FP_FRAC_ZEROP_##wc(Y)) \
- _FP_FRAC_SET_##wc(Y, _FP_MINFRAC_##wc); \
- else \
- _FP_FRAC_SET_##wc(Y, _FP_ZEROFRAC_##wc); \
- } \
- R##_e = X##_e; \
- } \
- \
- R##_c = FP_CLS_NORMAL; \
- \
- if (X##_s == Y##_s) \
- { \
- R##_s = X##_s; \
- _FP_FRAC_ADD_##wc(R, X, Y); \
- if (_FP_FRAC_OVERP_##wc(fs, R)) \
- { \
- _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
- R##_e++; \
- } \
- } \
- else \
- { \
- R##_s = X##_s; \
- _FP_FRAC_SUB_##wc(R, X, Y); \
- if (_FP_FRAC_ZEROP_##wc(R)) \
- { \
- /* return an exact zero */ \
- if (FP_ROUNDMODE == FP_RND_MINF) \
- R##_s |= Y##_s; \
- else \
- R##_s &= Y##_s; \
- R##_c = FP_CLS_ZERO; \
- } \
- else \
- { \
- if (_FP_FRAC_NEGP_##wc(R)) \
- { \
- _FP_FRAC_SUB_##wc(R, Y, X); \
- R##_s = Y##_s; \
- } \
- \
- /* renormalize after subtraction */ \
- _FP_FRAC_CLZ_##wc(diff, R); \
- diff -= _FP_WFRACXBITS_##fs; \
- if (diff) \
- { \
- R##_e -= diff; \
- _FP_FRAC_SLL_##wc(R, diff); \
- } \
- } \
- } \
- break; \
- } \
- \
- case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
- _FP_CHOOSENAN(fs, wc, R, X, Y); \
- break; \
- \
- case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
- R##_e = X##_e; \
- case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
- case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
- case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
- _FP_FRAC_COPY_##wc(R, X); \
- R##_s = X##_s; \
- R##_c = X##_c; \
- break; \
- \
- case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
- R##_e = Y##_e; \
- case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
- case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
- case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
- _FP_FRAC_COPY_##wc(R, Y); \
- R##_s = Y##_s; \
- R##_c = Y##_c; \
- break; \
- \
- case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
- if (X##_s != Y##_s) \
- { \
- /* +INF + -INF => NAN */ \
- _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
- R##_s = X##_s ^ Y##_s; \
- R##_c = FP_CLS_NAN; \
- break; \
- } \
- /* FALLTHRU */ \
- \
- case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
- case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
- R##_s = X##_s; \
- R##_c = FP_CLS_INF; \
- break; \
- \
- case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
- case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
- R##_s = Y##_s; \
- R##_c = FP_CLS_INF; \
- break; \
- \
- case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
- /* make sure the sign is correct */ \
- if (FP_ROUNDMODE == FP_RND_MINF) \
- R##_s = X##_s | Y##_s; \
- else \
- R##_s = X##_s & Y##_s; \
- R##_c = FP_CLS_ZERO; \
- break; \
- \
- default: \
- abort(); \
- } \
-} while (0)
-
-
-/*
- * Main negation routine. FIXME -- when we care about setting exception
- * bits reliably, this will not do. We should examine all of the fp classes.
- */
-
-#define _FP_NEG(fs, wc, R, X) \
- do { \
- _FP_FRAC_COPY_##wc(R, X); \
- R##_c = X##_c; \
- R##_e = X##_e; \
- R##_s = 1 ^ X##_s; \
- } while (0)
-
-
-/*
- * Main multiplication routine. The input values should be cooked.
- */
-
-#define _FP_MUL(fs, wc, R, X, Y) \
-do { \
- R##_s = X##_s ^ Y##_s; \
- switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
- { \
- case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
- R##_c = FP_CLS_NORMAL; \
- R##_e = X##_e + Y##_e + 1; \
- \
- _FP_MUL_MEAT_##fs(R,X,Y); \
- \
- if (_FP_FRAC_OVERP_##wc(fs, R)) \
- _FP_FRAC_SRS_##wc(R, 1, _FP_WFRACBITS_##fs); \
- else \
- R##_e--; \
- break; \
- \
- case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
- _FP_CHOOSENAN(fs, wc, R, X, Y); \
- break; \
- \
- case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
- case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
- case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
- R##_s = X##_s; \
- \
- case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
- case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
- case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
- case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
- _FP_FRAC_COPY_##wc(R, X); \
- R##_c = X##_c; \
- break; \
- \
- case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
- case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
- case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
- R##_s = Y##_s; \
- \
- case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
- case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
- _FP_FRAC_COPY_##wc(R, Y); \
- R##_c = Y##_c; \
- break; \
- \
- case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
- case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
- R##_c = FP_CLS_NAN; \
- _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
- break; \
- \
- default: \
- abort(); \
- } \
-} while (0)
-
-
-/*
- * Main division routine. The input values should be cooked.
- */
-
-#define _FP_DIV(fs, wc, R, X, Y) \
-do { \
- R##_s = X##_s ^ Y##_s; \
- switch (_FP_CLS_COMBINE(X##_c, Y##_c)) \
- { \
- case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NORMAL): \
- R##_c = FP_CLS_NORMAL; \
- R##_e = X##_e - Y##_e; \
- \
- _FP_DIV_MEAT_##fs(R,X,Y); \
- break; \
- \
- case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NAN): \
- _FP_CHOOSENAN(fs, wc, R, X, Y); \
- break; \
- \
- case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_NORMAL): \
- case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_INF): \
- case _FP_CLS_COMBINE(FP_CLS_NAN,FP_CLS_ZERO): \
- R##_s = X##_s; \
- _FP_FRAC_COPY_##wc(R, X); \
- R##_c = X##_c; \
- break; \
- \
- case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_NAN): \
- case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NAN): \
- case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NAN): \
- R##_s = Y##_s; \
- _FP_FRAC_COPY_##wc(R, Y); \
- R##_c = Y##_c; \
- break; \
- \
- case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_INF): \
- case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_INF): \
- case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_NORMAL): \
- R##_c = FP_CLS_ZERO; \
- break; \
- \
- case _FP_CLS_COMBINE(FP_CLS_NORMAL,FP_CLS_ZERO): \
- case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_ZERO): \
- case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_NORMAL): \
- R##_c = FP_CLS_INF; \
- break; \
- \
- case _FP_CLS_COMBINE(FP_CLS_INF,FP_CLS_INF): \
- case _FP_CLS_COMBINE(FP_CLS_ZERO,FP_CLS_ZERO): \
- R##_c = FP_CLS_NAN; \
- _FP_FRAC_SET_##wc(R, _FP_NANFRAC_##fs); \
- break; \
- \
- default: \
- abort(); \
- } \
-} while (0)
-
-
-/*
- * Main differential comparison routine. The inputs should be raw not
- * cooked. The return is -1,0,1 for normal values, 2 otherwise.
- */
-
-#define _FP_CMP(fs, wc, ret, X, Y, un) \
- do { \
- /* NANs are unordered */ \
- if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
- || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \
- { \
- ret = un; \
- } \
- else \
- { \
- int __x_zero = (!X##_e && _FP_FRAC_ZEROP_##wc(X)) ? 1 : 0; \
- int __y_zero = (!Y##_e && _FP_FRAC_ZEROP_##wc(Y)) ? 1 : 0; \
- \
- if (__x_zero && __y_zero) \
- ret = 0; \
- else if (__x_zero) \
- ret = Y##_s ? 1 : -1; \
- else if (__y_zero) \
- ret = X##_s ? -1 : 1; \
- else if (X##_s != Y##_s) \
- ret = X##_s ? -1 : 1; \
- else if (X##_e > Y##_e) \
- ret = X##_s ? -1 : 1; \
- else if (X##_e < Y##_e) \
- ret = X##_s ? 1 : -1; \
- else if (_FP_FRAC_GT_##wc(X, Y)) \
- ret = X##_s ? -1 : 1; \
- else if (_FP_FRAC_GT_##wc(Y, X)) \
- ret = X##_s ? 1 : -1; \
- else \
- ret = 0; \
- } \
- } while (0)
-
-
-/* Simplification for strict equality. */
-
-#define _FP_CMP_EQ(fs, wc, ret, X, Y) \
- do { \
- /* NANs are unordered */ \
- if ((X##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(X)) \
- || (Y##_e == _FP_EXPMAX_##fs && !_FP_FRAC_ZEROP_##wc(Y))) \
- { \
- ret = 1; \
- } \
- else \
- { \
- ret = !(X##_e == Y##_e \
- && _FP_FRAC_EQ_##wc(X, Y) \
- && (X##_s == Y##_s || !X##_e && _FP_FRAC_ZEROP_##wc(X))); \
- } \
- } while (0)
-
-/*
- * Main square root routine. The input value should be cooked.
- */
-
-#define _FP_SQRT(fs, wc, R, X) \
-do { \
- _FP_FRAC_DECL_##wc(T); _FP_FRAC_DECL_##wc(S); \
- _FP_W_TYPE q; \
- switch (X##_c) \
- { \
- case FP_CLS_NAN: \
- R##_s = 0; \
- R##_c = FP_CLS_NAN; \
- _FP_FRAC_SET_##wc(X, _FP_ZEROFRAC_##wc); \
- break; \
- case FP_CLS_INF: \
- if (X##_s) \
- { \
- R##_s = 0; \
- R##_c = FP_CLS_NAN; /* sNAN */ \
- } \
- else \
- { \
- R##_s = 0; \
- R##_c = FP_CLS_INF; /* sqrt(+inf) = +inf */ \
- } \
- break; \
- case FP_CLS_ZERO: \
- R##_s = X##_s; \
- R##_c = FP_CLS_ZERO; /* sqrt(+-0) = +-0 */ \
- break; \
- case FP_CLS_NORMAL: \
- R##_s = 0; \
- if (X##_s) \
- { \
- R##_c = FP_CLS_NAN; /* sNAN */ \
- break; \
- } \
- R##_c = FP_CLS_NORMAL; \
- if (X##_e & 1) \
- _FP_FRAC_SLL_##wc(X, 1); \
- R##_e = X##_e >> 1; \
- _FP_FRAC_SET_##wc(S, _FP_ZEROFRAC_##wc); \
- _FP_FRAC_SET_##wc(R, _FP_ZEROFRAC_##wc); \
- q = _FP_OVERFLOW_##fs; \
- _FP_FRAC_SLL_##wc(X, 1); \
- _FP_SQRT_MEAT_##wc(R, S, T, X, q); \
- _FP_FRAC_SRL_##wc(R, 1); \
- } \
- } while (0)
-
-/*
- * Convert from FP to integer
- */
-
-/* "When a NaN, infinity, large positive argument >= 2147483648.0, or
- * large negative argument <= -2147483649.0 is converted to an integer,
- * the invalid_current bit...should be set and fp_exception_IEEE_754 should
- * be raised. If the floating point invalid trap is disabled, no trap occurs
- * and a numerical result is generated: if the sign bit of the operand
- * is 0, the result is 2147483647; if the sign bit of the operand is 1,
- * the result is -2147483648."
- * Similarly for conversion to extended ints, except that the boundaries
- * are >= 2^63, <= -(2^63 + 1), and the results are 2^63 + 1 for s=0 and
- * -2^63 for s=1.
- * -- SPARC Architecture Manual V9, Appendix B, which specifies how
- * SPARCs resolve implementation dependencies in the IEEE-754 spec.
- * I don't believe that the code below follows this. I'm not even sure
- * it's right!
- * It doesn't cope with needing to convert to an n bit integer when there
- * is no n bit integer type. Fortunately gcc provides long long so this
- * isn't a problem for sparc32.
- * I have, however, fixed its NaN handling to conform as above.
- * -- PMM 02/1998
- * NB: rsigned is not 'is r declared signed?' but 'should the value stored
- * in r be signed or unsigned?'. r is always(?) declared unsigned.
- * Comments below are mine, BTW -- PMM
- */
-#define _FP_TO_INT(fs, wc, r, X, rsize, rsigned) \
- do { \
- switch (X##_c) \
- { \
- case FP_CLS_NORMAL: \
- if (X##_e < 0) \
- { \
- /* case FP_CLS_NAN: see above! */ \
- case FP_CLS_ZERO: \
- r = 0; \
- } \
- else if (X##_e >= rsize - (rsigned != 0)) \
- { /* overflow */ \
- case FP_CLS_NAN: \
- case FP_CLS_INF: \
- if (rsigned) \
- { \
- r = 1; \
- r <<= rsize - 1; \
- r -= 1 - X##_s; \
- } \
- else \
- { \
- r = 0; \
- if (!X##_s) \
- r = ~r; \
- } \
- } \
- else \
- { \
- if (_FP_W_TYPE_SIZE*wc < rsize) \
- { \
- _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
- r <<= X##_e - _FP_WFRACBITS_##fs; \
- } \
- else \
- { \
- if (X##_e >= _FP_WFRACBITS_##fs) \
- _FP_FRAC_SLL_##wc(X, (X##_e - _FP_WFRACBITS_##fs + 1));\
- else \
- _FP_FRAC_SRL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1));\
- _FP_FRAC_ASSEMBLE_##wc(r, X, rsize); \
- } \
- if (rsigned && X##_s) \
- r = -r; \
- } \
- break; \
- } \
- } while (0)
-
-#define _FP_FROM_INT(fs, wc, X, r, rsize, rtype) \
- do { \
- if (r) \
- { \
- X##_c = FP_CLS_NORMAL; \
- \
- if ((X##_s = (r < 0))) \
- r = -r; \
- /* Note that `r' is now considered unsigned, so we don't have \
- to worry about the single signed overflow case. */ \
- \
- if (rsize <= _FP_W_TYPE_SIZE) \
- __FP_CLZ(X##_e, r); \
- else \
- __FP_CLZ_2(X##_e, (_FP_W_TYPE)(r >> _FP_W_TYPE_SIZE), \
- (_FP_W_TYPE)r); \
- if (rsize < _FP_W_TYPE_SIZE) \
- X##_e -= (_FP_W_TYPE_SIZE - rsize); \
- X##_e = rsize - X##_e - 1; \
- \
- if (_FP_FRACBITS_##fs < rsize && _FP_WFRACBITS_##fs < X##_e) \
- __FP_FRAC_SRS_1(r, (X##_e - _FP_WFRACBITS_##fs), rsize); \
- r &= ~((_FP_W_TYPE)1 << X##_e); \
- _FP_FRAC_DISASSEMBLE_##wc(X, ((unsigned rtype)r), rsize); \
- _FP_FRAC_SLL_##wc(X, (_FP_WFRACBITS_##fs - X##_e - 1)); \
- } \
- else \
- { \
- X##_c = FP_CLS_ZERO, X##_s = 0; \
- } \
- } while (0)
-
-
-#define FP_CONV(dfs,sfs,dwc,swc,D,S) \
- do { \
- _FP_FRAC_CONV_##dwc##_##swc(dfs, sfs, D, S); \
- D##_e = S##_e; \
- D##_c = S##_c; \
- D##_s = S##_s; \
- } while (0)
-
-/*
- * Helper primitives.
- */
-
-/* Count leading zeros in a word. */
-
-#ifndef __FP_CLZ
-#if _FP_W_TYPE_SIZE < 64
-/* this is just to shut the compiler up about shifts > word length -- PMM 02/1998 */
-#define __FP_CLZ(r, x) \
- do { \
- _FP_W_TYPE _t = (x); \
- r = _FP_W_TYPE_SIZE - 1; \
- if (_t > 0xffff) r -= 16; \
- if (_t > 0xffff) _t >>= 16; \
- if (_t > 0xff) r -= 8; \
- if (_t > 0xff) _t >>= 8; \
- if (_t & 0xf0) r -= 4; \
- if (_t & 0xf0) _t >>= 4; \
- if (_t & 0xc) r -= 2; \
- if (_t & 0xc) _t >>= 2; \
- if (_t & 0x2) r -= 1; \
- } while (0)
-#else /* not _FP_W_TYPE_SIZE < 64 */
-#define __FP_CLZ(r, x) \
- do { \
- _FP_W_TYPE _t = (x); \
- r = _FP_W_TYPE_SIZE - 1; \
- if (_t > 0xffffffff) r -= 32; \
- if (_t > 0xffffffff) _t >>= 32; \
- if (_t > 0xffff) r -= 16; \
- if (_t > 0xffff) _t >>= 16; \
- if (_t > 0xff) r -= 8; \
- if (_t > 0xff) _t >>= 8; \
- if (_t & 0xf0) r -= 4; \
- if (_t & 0xf0) _t >>= 4; \
- if (_t & 0xc) r -= 2; \
- if (_t & 0xc) _t >>= 2; \
- if (_t & 0x2) r -= 1; \
- } while (0)
-#endif /* not _FP_W_TYPE_SIZE < 64 */
-#endif /* ndef __FP_CLZ */
-
-#define _FP_DIV_HELP_imm(q, r, n, d) \
- do { \
- q = n / d, r = n % d; \
- } while (0)
-
diff --git a/arch/powerpc/math-emu/single.h b/arch/powerpc/math-emu/single.h
deleted file mode 100644
index f19d994..0000000
--- a/arch/powerpc/math-emu/single.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * Definitions for IEEE Single Precision
- */
-
-#if _FP_W_TYPE_SIZE < 32
-#error "Here's a nickel kid. Go buy yourself a real computer."
-#endif
-
-#define _FP_FRACBITS_S 24
-#define _FP_FRACXBITS_S (_FP_W_TYPE_SIZE - _FP_FRACBITS_S)
-#define _FP_WFRACBITS_S (_FP_WORKBITS + _FP_FRACBITS_S)
-#define _FP_WFRACXBITS_S (_FP_W_TYPE_SIZE - _FP_WFRACBITS_S)
-#define _FP_EXPBITS_S 8
-#define _FP_EXPBIAS_S 127
-#define _FP_EXPMAX_S 255
-#define _FP_QNANBIT_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-2))
-#define _FP_IMPLBIT_S ((_FP_W_TYPE)1 << (_FP_FRACBITS_S-1))
-#define _FP_OVERFLOW_S ((_FP_W_TYPE)1 << (_FP_WFRACBITS_S))
-
-/* The implementation of _FP_MUL_MEAT_S and _FP_DIV_MEAT_S should be
- chosen by the target machine. */
-
-union _FP_UNION_S
-{
- float flt;
- struct {
-#if __BYTE_ORDER == __BIG_ENDIAN
- unsigned sign : 1;
- unsigned exp : _FP_EXPBITS_S;
- unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0);
-#else
- unsigned frac : _FP_FRACBITS_S - (_FP_IMPLBIT_S != 0);
- unsigned exp : _FP_EXPBITS_S;
- unsigned sign : 1;
-#endif
- } bits __attribute__((packed));
-};
-
-#define FP_DECL_S(X) _FP_DECL(1,X)
-#define FP_UNPACK_RAW_S(X,val) _FP_UNPACK_RAW_1(S,X,val)
-#define FP_PACK_RAW_S(val,X) _FP_PACK_RAW_1(S,val,X)
-
-#define FP_UNPACK_S(X,val) \
- do { \
- _FP_UNPACK_RAW_1(S,X,val); \
- _FP_UNPACK_CANONICAL(S,1,X); \
- } while (0)
-
-#define FP_PACK_S(val,X) \
- do { \
- _FP_PACK_CANONICAL(S,1,X); \
- _FP_PACK_RAW_1(S,val,X); \
- } while (0)
-
-#define FP_NEG_S(R,X) _FP_NEG(S,1,R,X)
-#define FP_ADD_S(R,X,Y) _FP_ADD(S,1,R,X,Y)
-#define FP_SUB_S(R,X,Y) _FP_SUB(S,1,R,X,Y)
-#define FP_MUL_S(R,X,Y) _FP_MUL(S,1,R,X,Y)
-#define FP_DIV_S(R,X,Y) _FP_DIV(S,1,R,X,Y)
-#define FP_SQRT_S(R,X) _FP_SQRT(S,1,R,X)
-
-#define FP_CMP_S(r,X,Y,un) _FP_CMP(S,1,r,X,Y,un)
-#define FP_CMP_EQ_S(r,X,Y) _FP_CMP_EQ(S,1,r,X,Y)
-
-#define FP_TO_INT_S(r,X,rsz,rsg) _FP_TO_INT(S,1,r,X,rsz,rsg)
-#define FP_FROM_INT_S(X,r,rs,rt) _FP_FROM_INT(S,1,X,r,rs,rt)
diff --git a/arch/powerpc/math-emu/soft-fp.h b/arch/powerpc/math-emu/soft-fp.h
deleted file mode 100644
index cca3959..0000000
--- a/arch/powerpc/math-emu/soft-fp.h
+++ /dev/null
@@ -1,104 +0,0 @@
-#ifndef SOFT_FP_H
-#define SOFT_FP_H
-
-#include "sfp-machine.h"
-
-#define _FP_WORKBITS 3
-#define _FP_WORK_LSB ((_FP_W_TYPE)1 << 3)
-#define _FP_WORK_ROUND ((_FP_W_TYPE)1 << 2)
-#define _FP_WORK_GUARD ((_FP_W_TYPE)1 << 1)
-#define _FP_WORK_STICKY ((_FP_W_TYPE)1 << 0)
-
-#ifndef FP_RND_NEAREST
-# define FP_RND_NEAREST 0
-# define FP_RND_ZERO 1
-# define FP_RND_PINF 2
-# define FP_RND_MINF 3
-#ifndef FP_ROUNDMODE
-# define FP_ROUNDMODE FP_RND_NEAREST
-#endif
-#endif
-
-#define _FP_ROUND_NEAREST(wc, X) \
-({ int __ret = 0; \
- int __frac = _FP_FRAC_LOW_##wc(X) & 15; \
- if (__frac & 7) { \
- __ret = EFLAG_INEXACT; \
- if ((__frac & 7) != _FP_WORK_ROUND) \
- _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND); \
- else if (__frac & _FP_WORK_LSB) \
- _FP_FRAC_ADDI_##wc(X, _FP_WORK_ROUND); \
- } \
- __ret; \
-})
-
-#define _FP_ROUND_ZERO(wc, X) \
-({ int __ret = 0; \
- if (_FP_FRAC_LOW_##wc(X) & 7) \
- __ret = EFLAG_INEXACT; \
- __ret; \
-})
-
-#define _FP_ROUND_PINF(wc, X) \
-({ int __ret = EFLAG_INEXACT; \
- if (!X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \
- _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \
- else __ret = 0; \
- __ret; \
-})
-
-#define _FP_ROUND_MINF(wc, X) \
-({ int __ret = EFLAG_INEXACT; \
- if (X##_s && (_FP_FRAC_LOW_##wc(X) & 7)) \
- _FP_FRAC_ADDI_##wc(X, _FP_WORK_LSB); \
- else __ret = 0; \
- __ret; \
-})
-
-#define _FP_ROUND(wc, X) \
-({ int __ret = 0; \
- switch (FP_ROUNDMODE) \
- { \
- case FP_RND_NEAREST: \
- __ret |= _FP_ROUND_NEAREST(wc,X); \
- break; \
- case FP_RND_ZERO: \
- __ret |= _FP_ROUND_ZERO(wc,X); \
- break; \
- case FP_RND_PINF: \
- __ret |= _FP_ROUND_PINF(wc,X); \
- break; \
- case FP_RND_MINF: \
- __ret |= _FP_ROUND_MINF(wc,X); \
- break; \
- }; \
- __ret; \
-})
-
-#define FP_CLS_NORMAL 0
-#define FP_CLS_ZERO 1
-#define FP_CLS_INF 2
-#define FP_CLS_NAN 3
-
-#define _FP_CLS_COMBINE(x,y) (((x) << 2) | (y))
-
-#include "op-1.h"
-#include "op-2.h"
-#include "op-4.h"
-#include "op-common.h"
-
-/* Sigh. Silly things longlong.h needs. */
-#define UWtype _FP_W_TYPE
-#define W_TYPE_SIZE _FP_W_TYPE_SIZE
-
-typedef int SItype __attribute__((mode(SI)));
-typedef int DItype __attribute__((mode(DI)));
-typedef unsigned int USItype __attribute__((mode(SI)));
-typedef unsigned int UDItype __attribute__((mode(DI)));
-#if _FP_W_TYPE_SIZE == 32
-typedef unsigned int UHWtype __attribute__((mode(HI)));
-#elif _FP_W_TYPE_SIZE == 64
-typedef USItype UHWtype;
-#endif
-
-#endif
diff --git a/arch/powerpc/math-emu/types.c b/arch/powerpc/math-emu/types.c
deleted file mode 100644
index e1ed15d..0000000
--- a/arch/powerpc/math-emu/types.c
+++ /dev/null
@@ -1,51 +0,0 @@
-#include "soft-fp.h"
-#include "double.h"
-#include "single.h"
-
-void
-fp_unpack_d(long *_s, unsigned long *_f1, unsigned long *_f0,
- long *_e, long *_c, void *val)
-{
- FP_DECL_D(X);
-
- __FP_UNPACK_RAW_2(D, X, val);
-
- _FP_UNPACK_CANONICAL(D, 2, X);
-
- *_s = X_s;
- *_f1 = X_f1;
- *_f0 = X_f0;
- *_e = X_e;
- *_c = X_c;
-}
-
-int
-fp_pack_d(void *val, long X_s, unsigned long X_f1,
- unsigned long X_f0, long X_e, long X_c)
-{
- int exc;
-
- exc = _FP_PACK_CANONICAL(D, 2, X);
- if (!exc || !__FPU_TRAP_P(exc))
- __FP_PACK_RAW_2(D, val, X);
- return exc;
-}
-
-int
-fp_pack_ds(void *val, long X_s, unsigned long X_f1,
- unsigned long X_f0, long X_e, long X_c)
-{
- FP_DECL_S(__X);
- int exc;
-
- FP_CONV(S, D, 1, 2, __X, X);
- exc = _FP_PACK_CANONICAL(S, 1, __X);
- if (!exc || !__FPU_TRAP_P(exc)) {
- _FP_UNPACK_CANONICAL(S, 1, __X);
- FP_CONV(D, S, 2, 1, X, __X);
- exc |= _FP_PACK_CANONICAL(D, 2, X);
- if (!exc || !__FPU_TRAP_P(exc))
- __FP_PACK_RAW_2(D, val, X);
- }
- return exc;
-}
diff --git a/arch/powerpc/math-emu/sfp-machine.h b/include/asm-powerpc/sfp-machine.h
similarity index 100%
rename from arch/powerpc/math-emu/sfp-machine.h
rename to include/asm-powerpc/sfp-machine.h
--
1.5.2
^ permalink raw reply related
* RE: Virtual device hdlc0 asks to que packet!
From: Russell McGuire @ 2008-03-05 8:43 UTC (permalink / raw)
To: joakim.tjernlund; +Cc: linuxppc-embedded
In-Reply-To: <1204704716.20637.50.camel@gentoo-jocke.transmode.se>
Jocke,
I wonder how one change this? I don't remember any of the API calls
referencing this, so maybe the default to 1000? Or perhaps that is protocol
specific. I will hunt through some of Freescale's Ethernet drivers and see
if I can't find anything.
I know that inside the driver, I have 32 RX, and 32 TX buffers <buffer
descriptors> available. There needs to be some smarter way to manage it
though than raw numbers. Large file transfers, if they are cached, can
easily over flow any number of buffers.
Thanks for the note.
-Russ
> -----Original Message-----
> From: Joakim Tjernlund [mailto:joakim.tjernlund@transmode.se]
> Sent: Wednesday, March 05, 2008 12:12 AM
> To: rmcguire@videopresence.com
> Cc: linuxppc-embedded@ozlabs.org
> Subject: Re: Virtual device hdlc0 asks to que packet!
>
>
> On Tue, 2008-03-04 at 15:33 -0800, Russell McGuire wrote:
> > All,
> >
> > Background MPC8360, using a T1 PHY as an HDLC device.
> >
> > Developing my hdlc driver, and was writing a simple send utility. To
> test it
> > out. Things seem well when I had massive delays in between the write()
> or
> > sendot(), and I was able to attain 100+Kbytes/sec. However, when I
> replaced
> > the simple usleeps(xxx) with select statements, suddenly I started
> getting a
> > ton of these messages.
> >
> > "Virtual device hdlc0 asks to que packet!"
> >
> > Along with dropped or non-sent data.
> >
> > In my driver I am tracking the available TX buffers, and issue a
> > netif_stop_que() statement inside the start_xmit() call, with a
> > corresponding netif_wake_que() in the tx_handler.
> >
> > Is there something else that needs to be done in order to make a select
> > statement wait for the socket to not be busy? It seems that it always
> > returns immediately with no timeout.
> >
> > I guess the other pieces of the scenario are as follows:
> >
> > * Using 'sethdlc hdlc0 hdlc' for the mode, so no IP stack is used.
> > * Opening the socket to the hdlc device directly to the device itself,
> i.e.
> > no port number socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
> >
> > I have used both sendto() and write() to pass data down, and they both
> > return as if all the data has been sent, i.e. I never get an error.
> >
> > -Russ
>
> When playing with your driver I noticed that the hdlc interfaces had
> txqueuelen:0
> Normal eth interfaces has txqueuelen:1000. Maybe you need to add a
> txqueue to the hdlc interfaces?
>
> Jocke
>
> PS.
> The driver seems to work now, I get both TX and RX IRQs now.
^ permalink raw reply
* [PATCH 11/11] hvcbeat: fix buffer manipulation
From: Ishizaki Kou @ 2008-03-05 8:41 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
This patch fixes a potential bug at drivers/char/hvc_beat.c.
- hvc_put_term_char routine will decrement "rest" variable twice,
and forget to advance "buf" pointer by "nlen" bytes.
This bug was not hit because the output handler in
drivers/char/hvc_console.c splits given output into 16 bytes
at maximum.
Reported-by: Timur Tabi <timur@freescale.com>
Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
---
drivers/char/hvc_beat.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
Index: b/drivers/char/hvc_beat.c
===================================================================
--- a/drivers/char/hvc_beat.c 2008-03-03 23:49:18.000000000 +0900
+++ b/drivers/char/hvc_beat.c 2008-03-04 15:14:35.000000000 +0900
@@ -78,8 +78,8 @@
for (rest = cnt; rest > 0; rest -= nlen) {
nlen = (rest > 16) ? 16 : rest;
memcpy(kb, buf, nlen);
- beat_put_term_char(vtermno, rest, kb[0], kb[1]);
- rest -= nlen;
+ beat_put_term_char(vtermno, nlen, kb[0], kb[1]);
+ buf += nlen;
}
return cnt;
}
^ permalink raw reply
* [PATCH 10/11] celleb: add support for PCI Express
From: Ishizaki Kou @ 2008-03-05 8:39 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
This patch adds support for PCI Express port on Celleb. I/O space
of this PCI Express port is not mapped in memory space. So we use
the io-workaround mechanism to make accesses indirect.
Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
---
arch/powerpc/platforms/cell/celleb_pci.c | 9
arch/powerpc/platforms/cell/celleb_pci.h | 4
arch/powerpc/platforms/cell/celleb_scc.h | 87 ++++
arch/powerpc/platforms/cell/celleb_scc_pciex.c | 541 +++++++++++++++++++++++++
4 files changed, 641 insertions(+)
Index: b/arch/powerpc/platforms/cell/celleb_pci.c
===================================================================
--- a/arch/powerpc/platforms/cell/celleb_pci.c 2008-03-04 14:01:10.000000000 +0900
+++ b/arch/powerpc/platforms/cell/celleb_pci.c 2008-03-04 14:01:27.000000000 +0900
@@ -464,6 +464,9 @@
.name = "epci",
.data = celleb_setup_epci,
}, {
+ .name = "pcie",
+ .data = celleb_setup_pciex,
+ }, {
},
};
@@ -504,6 +507,12 @@
.data = (void *)0,
},
}, {
+ .name = "pcie",
+ .data = &(struct celleb_iowa_bus_param){
+ .ops = &scc_pciex_ops,
+ .init = &scc_pciex_iowa_init,
+ }
+ }, {
},
};
Index: b/arch/powerpc/platforms/cell/celleb_pci.h
===================================================================
--- a/arch/powerpc/platforms/cell/celleb_pci.h 2008-03-04 14:01:10.000000000 +0900
+++ b/arch/powerpc/platforms/cell/celleb_pci.h 2008-03-04 14:01:27.000000000 +0900
@@ -33,7 +33,11 @@
extern int celleb_pci_probe_mode(struct pci_bus *);
extern int celleb_setup_epci(struct device_node *, struct pci_controller *);
+extern int celleb_setup_pciex(struct device_node *, struct pci_controller *);
+
extern int __init celleb_io_workaround_init(void);
+extern struct ppc_pci_io scc_pciex_ops;
+int __init scc_pciex_iowa_init(struct iowa_bus *, void *);
#endif /* _CELLEB_PCI_H */
Index: b/arch/powerpc/platforms/cell/celleb_scc.h
===================================================================
--- a/arch/powerpc/platforms/cell/celleb_scc.h 2008-03-04 14:00:42.000000000 +0900
+++ b/arch/powerpc/platforms/cell/celleb_scc.h 2008-03-04 14:01:27.000000000 +0900
@@ -125,6 +125,93 @@
/* bits for SCC_EPCI_CNTOPT */
#define SCC_EPCI_CNTOPT_O2PMB 0x00000002
+/* SCC PCIEXC SMMIO registers */
+#define PEXCADRS 0x000
+#define PEXCWDATA 0x004
+#define PEXCRDATA 0x008
+#define PEXDADRS 0x010
+#define PEXDCMND 0x014
+#define PEXDWDATA 0x018
+#define PEXDRDATA 0x01c
+#define PEXREQID 0x020
+#define PEXTIDMAP 0x024
+#define PEXINTMASK 0x028
+#define PEXINTSTS 0x02c
+#define PEXAERRMASK 0x030
+#define PEXAERRSTS 0x034
+#define PEXPRERRMASK 0x040
+#define PEXPRERRSTS 0x044
+#define PEXPRERRID01 0x048
+#define PEXPRERRID23 0x04c
+#define PEXVDMASK 0x050
+#define PEXVDSTS 0x054
+#define PEXRCVCPLIDA 0x060
+#define PEXLENERRIDA 0x068
+#define PEXPHYPLLST 0x070
+#define PEXDMRDEN0 0x100
+#define PEXDMRDADR0 0x104
+#define PEXDMRDENX 0x110
+#define PEXDMRDADRX 0x114
+#define PEXECMODE 0xf00
+#define PEXMAEA(n) (0xf50 + (8 * n))
+#define PEXMAEC(n) (0xf54 + (8 * n))
+#define PEXCCRCTRL 0xff0
+
+/* SCC PCIEXC bits and shifts for PEXCADRS */
+#define PEXCADRS_BYTE_EN_SHIFT 20
+#define PEXCADRS_CMD_SHIFT 16
+#define PEXCADRS_CMD_READ (0xa << PEXCADRS_CMD_SHIFT)
+#define PEXCADRS_CMD_WRITE (0xb << PEXCADRS_CMD_SHIFT)
+
+/* SCC PCIEXC shifts for PEXDADRS */
+#define PEXDADRS_BUSNO_SHIFT 20
+#define PEXDADRS_DEVNO_SHIFT 15
+#define PEXDADRS_FUNCNO_SHIFT 12
+
+/* SCC PCIEXC bits and shifts for PEXDCMND */
+#define PEXDCMND_BYTE_EN_SHIFT 4
+#define PEXDCMND_IO_READ 0x2
+#define PEXDCMND_IO_WRITE 0x3
+#define PEXDCMND_CONFIG_READ 0xa
+#define PEXDCMND_CONFIG_WRITE 0xb
+
+/* SCC PCIEXC bits for PEXPHYPLLST */
+#define PEXPHYPLLST_PEXPHYAPLLST 0x00000001
+
+/* SCC PCIEXC bits for PEXECMODE */
+#define PEXECMODE_ALL_THROUGH 0x00000000
+#define PEXECMODE_ALL_8BIT 0x00550155
+#define PEXECMODE_ALL_16BIT 0x00aa02aa
+
+/* SCC PCIEXC bits for PEXCCRCTRL */
+#define PEXCCRCTRL_PEXIPCOREEN 0x00040000
+#define PEXCCRCTRL_PEXIPCONTEN 0x00020000
+#define PEXCCRCTRL_PEXPHYPLLEN 0x00010000
+#define PEXCCRCTRL_PCIEXCAOCKEN 0x00000100
+
+/* SCC PCIEXC port configuration registers */
+#define PEXTCERRCHK 0x21c
+#define PEXTAMAPB0 0x220
+#define PEXTAMAPL0 0x224
+#define PEXTAMAPB(n) (PEXTAMAPB0 + 8 * (n))
+#define PEXTAMAPL(n) (PEXTAMAPL0 + 8 * (n))
+#define PEXCHVC0P 0x500
+#define PEXCHVC0NP 0x504
+#define PEXCHVC0C 0x508
+#define PEXCDVC0P 0x50c
+#define PEXCDVC0NP 0x510
+#define PEXCDVC0C 0x514
+#define PEXCHVCXP 0x518
+#define PEXCHVCXNP 0x51c
+#define PEXCHVCXC 0x520
+#define PEXCDVCXP 0x524
+#define PEXCDVCXNP 0x528
+#define PEXCDVCXC 0x52c
+#define PEXCTTRG 0x530
+#define PEXTSCTRL 0x700
+#define PEXTSSTS 0x704
+#define PEXSKPCTRL 0x708
+
/* UHC registers */
#define SCC_UHC_CKRCTRL 0xff0
#define SCC_UHC_ECMODE 0xf00
Index: b/arch/powerpc/platforms/cell/celleb_scc_pciex.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/arch/powerpc/platforms/cell/celleb_scc_pciex.c 2008-03-04 14:10:35.000000000 +0900
@@ -0,0 +1,541 @@
+/*
+ * Support for Celleb PCI-Express.
+ *
+ * (C) Copyright 2007-2008 TOSHIBA 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) 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/pci.h>
+#include <linux/string.h>
+#include <linux/init.h>
+#include <linux/bootmem.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/iommu.h>
+#include <asm/byteorder.h>
+
+#include "io-workarounds.h"
+#include "celleb_scc.h"
+#include "celleb_pci.h"
+
+#define PEX_IN(base, off) in_be32((void *)(base) + (off))
+#define PEX_OUT(base, off, data) out_be32((void *)(base) + (off), (data))
+
+static void scc_pciex_io_flush(struct iowa_bus *bus)
+{
+ (void)PEX_IN(bus->phb->cfg_addr, PEXDMRDEN0);
+}
+
+/*
+ * Memory space access to device on PCIEX
+ */
+#define PCIEX_MMIO_READ(name, ret) \
+static ret scc_pciex_##name(const PCI_IO_ADDR addr) \
+{ \
+ ret val = __do_##name(addr); \
+ scc_pciex_io_flush(iowa_mem_find_bus(addr)); \
+ return val; \
+}
+
+#define PCIEX_MMIO_READ_STR(name) \
+static void scc_pciex_##name(const PCI_IO_ADDR addr, void *buf, \
+ unsigned long count) \
+{ \
+ __do_##name(addr, buf, count); \
+ scc_pciex_io_flush(iowa_mem_find_bus(addr)); \
+}
+
+PCIEX_MMIO_READ(readb, u8)
+PCIEX_MMIO_READ(readw, u16)
+PCIEX_MMIO_READ(readl, u32)
+PCIEX_MMIO_READ(readq, u64)
+PCIEX_MMIO_READ(readw_be, u16)
+PCIEX_MMIO_READ(readl_be, u32)
+PCIEX_MMIO_READ(readq_be, u64)
+PCIEX_MMIO_READ_STR(readsb)
+PCIEX_MMIO_READ_STR(readsw)
+PCIEX_MMIO_READ_STR(readsl)
+
+static void scc_pciex_memcpy_fromio(void *dest, const PCI_IO_ADDR src,
+ unsigned long n)
+{
+ __do_memcpy_fromio(dest, src, n);
+ scc_pciex_io_flush(iowa_mem_find_bus(src));
+}
+
+/*
+ * I/O port access to devices on PCIEX.
+ */
+
+static inline unsigned long get_bus_address(struct pci_controller *phb,
+ unsigned long port)
+{
+ return port - ((unsigned long)(phb->io_base_virt) - _IO_BASE);
+}
+
+static u32 scc_pciex_read_port(struct pci_controller *phb,
+ unsigned long port, int size)
+{
+ unsigned int byte_enable;
+ unsigned int cmd, shift;
+ unsigned long addr;
+ u32 data, ret;
+
+ BUG_ON(((port & 0x3ul) + size) > 4);
+
+ addr = get_bus_address(phb, port);
+ shift = addr & 0x3ul;
+ byte_enable = ((1 << size) - 1) << shift;
+ cmd = PEXDCMND_IO_READ | (byte_enable << PEXDCMND_BYTE_EN_SHIFT);
+ PEX_OUT(phb->cfg_addr, PEXDADRS, (addr & ~0x3ul));
+ PEX_OUT(phb->cfg_addr, PEXDCMND, cmd);
+ data = PEX_IN(phb->cfg_addr, PEXDRDATA);
+ ret = (data >> (shift * 8)) & (0xFFFFFFFF >> ((4 - size) * 8));
+
+ pr_debug("PCIEX:PIO READ:port=0x%lx, addr=0x%lx, size=%d, be=%x,"
+ " cmd=%x, data=%x, ret=%x\n", port, addr, size, byte_enable,
+ cmd, data, ret);
+
+ return ret;
+}
+
+static void scc_pciex_write_port(struct pci_controller *phb,
+ unsigned long port, int size, u32 val)
+{
+ unsigned int byte_enable;
+ unsigned int cmd, shift;
+ unsigned long addr;
+ u32 data;
+
+ BUG_ON(((port & 0x3ul) + size) > 4);
+
+ addr = get_bus_address(phb, port);
+ shift = addr & 0x3ul;
+ byte_enable = ((1 << size) - 1) << shift;
+ cmd = PEXDCMND_IO_WRITE | (byte_enable << PEXDCMND_BYTE_EN_SHIFT);
+ data = (val & (0xFFFFFFFF >> (4 - size) * 8)) << (shift * 8);
+ PEX_OUT(phb->cfg_addr, PEXDADRS, (addr & ~0x3ul));
+ PEX_OUT(phb->cfg_addr, PEXDCMND, cmd);
+ PEX_OUT(phb->cfg_addr, PEXDWDATA, data);
+
+ pr_debug("PCIEX:PIO WRITE:port=0x%lx, addr=%lx, size=%d, val=%x,"
+ " be=%x, cmd=%x, data=%x\n", port, addr, size, val,
+ byte_enable, cmd, data);
+}
+
+static u8 __scc_pciex_inb(struct pci_controller *phb, unsigned long port)
+{
+ return (u8)scc_pciex_read_port(phb, port, 1);
+}
+
+static u16 __scc_pciex_inw(struct pci_controller *phb, unsigned long port)
+{
+ u32 data;
+ if ((port & 0x3ul) < 3)
+ data = scc_pciex_read_port(phb, port, 2);
+ else {
+ u32 d1 = scc_pciex_read_port(phb, port, 1);
+ u32 d2 = scc_pciex_read_port(phb, port + 1, 1);
+ data = d1 | (d2 << 8);
+ }
+ return (u16)data;
+}
+
+static u32 __scc_pciex_inl(struct pci_controller *phb, unsigned long port)
+{
+ unsigned int mod = port & 0x3ul;
+ u32 data;
+ if (mod == 0)
+ data = scc_pciex_read_port(phb, port, 4);
+ else {
+ u32 d1 = scc_pciex_read_port(phb, port, 4 - mod);
+ u32 d2 = scc_pciex_read_port(phb, port + 1, mod);
+ data = d1 | (d2 << (mod * 8));
+ }
+ return data;
+}
+
+static void __scc_pciex_outb(struct pci_controller *phb,
+ u8 val, unsigned long port)
+{
+ scc_pciex_write_port(phb, port, 1, (u32)val);
+}
+
+static void __scc_pciex_outw(struct pci_controller *phb,
+ u16 val, unsigned long port)
+{
+ if ((port & 0x3ul) < 3)
+ scc_pciex_write_port(phb, port, 2, (u32)val);
+ else {
+ u32 d1 = val & 0x000000FF;
+ u32 d2 = (val & 0x0000FF00) >> 8;
+ scc_pciex_write_port(phb, port, 1, d1);
+ scc_pciex_write_port(phb, port + 1, 1, d2);
+ }
+}
+
+static void __scc_pciex_outl(struct pci_controller *phb,
+ u32 val, unsigned long port)
+{
+ unsigned int mod = port & 0x3ul;
+ if (mod == 0)
+ scc_pciex_write_port(phb, port, 4, val);
+ else {
+ u32 d1 = val & (0xFFFFFFFFul >> (mod * 8));
+ u32 d2 = val >> ((4 - mod) * 8);
+ scc_pciex_write_port(phb, port, 4 - mod, d1);
+ scc_pciex_write_port(phb, port + 1, mod, d2);
+ }
+}
+
+#define PCIEX_PIO_FUNC(size, name) \
+static u##size scc_pciex_in##name(unsigned long port) \
+{ \
+ struct iowa_bus *bus = iowa_pio_find_bus(port); \
+ u##size data = __scc_pciex_in##name(bus->phb, port); \
+ scc_pciex_io_flush(bus); \
+ return data; \
+} \
+static void scc_pciex_ins##name(unsigned long p, void *b, unsigned long c) \
+{ \
+ struct iowa_bus *bus = iowa_pio_find_bus(p); \
+ u##size *dst = b; \
+ for (; c != 0; c--, dst++) \
+ *dst = cpu_to_le##size(__scc_pciex_in##name(bus->phb, p)); \
+ scc_pciex_io_flush(bus); \
+} \
+static void scc_pciex_out##name(u##size val, unsigned long port) \
+{ \
+ struct iowa_bus *bus = iowa_pio_find_bus(port); \
+ __scc_pciex_out##name(bus->phb, val, port); \
+} \
+static void scc_pciex_outs##name(unsigned long p, const void *b, \
+ unsigned long c) \
+{ \
+ struct iowa_bus *bus = iowa_pio_find_bus(p); \
+ const u##size *src = b; \
+ for (; c != 0; c--, src++) \
+ __scc_pciex_out##name(bus->phb, le##size##_to_cpu(*src), p); \
+}
+#define cpu_to_le8(x) (x)
+#define le8_to_cpu(x) (x)
+PCIEX_PIO_FUNC(8, b)
+PCIEX_PIO_FUNC(16, w)
+PCIEX_PIO_FUNC(32, l)
+
+struct ppc_pci_io scc_pciex_ops = {
+ .readb = scc_pciex_readb,
+ .readw = scc_pciex_readw,
+ .readl = scc_pciex_readl,
+ .readq = scc_pciex_readq,
+ .readw_be = scc_pciex_readw_be,
+ .readl_be = scc_pciex_readl_be,
+ .readq_be = scc_pciex_readq_be,
+ .readsb = scc_pciex_readsb,
+ .readsw = scc_pciex_readsw,
+ .readsl = scc_pciex_readsl,
+ .memcpy_fromio = scc_pciex_memcpy_fromio,
+ .inb = scc_pciex_inb,
+ .inw = scc_pciex_inw,
+ .inl = scc_pciex_inl,
+ .outb = scc_pciex_outb,
+ .outw = scc_pciex_outw,
+ .outl = scc_pciex_outl,
+ .insb = scc_pciex_insb,
+ .insw = scc_pciex_insw,
+ .insl = scc_pciex_insl,
+ .outsb = scc_pciex_outsb,
+ .outsw = scc_pciex_outsw,
+ .outsl = scc_pciex_outsl,
+};
+
+int __init scc_pciex_iowa_init(struct iowa_bus *bus, void *data)
+{
+ dma_addr_t dummy_page_da;
+ void *dummy_page_va;
+
+ dummy_page_va = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!dummy_page_va) {
+ pr_err("PCIEX:Alloc dummy_page_va failed\n");
+ return -1;
+ }
+
+ dummy_page_da = dma_map_single(bus->phb->parent, dummy_page_va,
+ PAGE_SIZE, DMA_FROM_DEVICE);
+ if (dummy_page_da == DMA_FROM_DEVICE) {
+ pr_err("PCIEX:Map dummy page failed.\n");
+ kfree(dummy_page_va);
+ return -1;
+ }
+
+ PEX_OUT(bus->phb->cfg_addr, PEXDMRDADR0, dummy_page_da);
+
+ return 0;
+}
+
+/*
+ * config space access
+ */
+#define MK_PEXDADRS(bus_no, dev_no, func_no, addr) \
+ ((uint32_t)(((addr) & ~0x3UL) | \
+ ((bus_no) << PEXDADRS_BUSNO_SHIFT) | \
+ ((dev_no) << PEXDADRS_DEVNO_SHIFT) | \
+ ((func_no) << PEXDADRS_FUNCNO_SHIFT)))
+
+#define MK_PEXDCMND_BYTE_EN(addr, size) \
+ ((((0x1 << (size))-1) << ((addr) & 0x3)) << PEXDCMND_BYTE_EN_SHIFT)
+#define MK_PEXDCMND(cmd, addr, size) ((cmd) | MK_PEXDCMND_BYTE_EN(addr, size))
+
+static uint32_t config_read_pciex_dev(unsigned int *base,
+ uint64_t bus_no, uint64_t dev_no, uint64_t func_no,
+ uint64_t off, uint64_t size)
+{
+ uint32_t ret;
+ uint32_t addr, cmd;
+
+ addr = MK_PEXDADRS(bus_no, dev_no, func_no, off);
+ cmd = MK_PEXDCMND(PEXDCMND_CONFIG_READ, off, size);
+ PEX_OUT(base, PEXDADRS, addr);
+ PEX_OUT(base, PEXDCMND, cmd);
+ ret = (PEX_IN(base, PEXDRDATA)
+ >> ((off & (4-size)) * 8)) & ((0x1 << (size * 8)) - 1);
+ return ret;
+}
+
+static void config_write_pciex_dev(unsigned int *base, uint64_t bus_no,
+ uint64_t dev_no, uint64_t func_no, uint64_t off, uint64_t size,
+ uint32_t data)
+{
+ uint32_t addr, cmd;
+
+ addr = MK_PEXDADRS(bus_no, dev_no, func_no, off);
+ cmd = MK_PEXDCMND(PEXDCMND_CONFIG_WRITE, off, size);
+ PEX_OUT(base, PEXDADRS, addr);
+ PEX_OUT(base, PEXDCMND, cmd);
+ PEX_OUT(base, PEXDWDATA,
+ (data & ((0x1 << (size * 8)) - 1)) << ((off & (4-size)) * 8));
+}
+
+#define MK_PEXCADRS_BYTE_EN(off, len) \
+ ((((0x1 << (len)) - 1) << ((off) & 0x3)) << PEXCADRS_BYTE_EN_SHIFT)
+#define MK_PEXCADRS(cmd, addr, size) \
+ ((cmd) | MK_PEXCADRS_BYTE_EN(addr, size) | ((addr) & ~0x3))
+static uint32_t config_read_pciex_rc(unsigned int *base,
+ uint32_t where, uint32_t size)
+{
+ PEX_OUT(base, PEXCADRS, MK_PEXCADRS(PEXCADRS_CMD_READ, where, size));
+ return (PEX_IN(base, PEXCRDATA)
+ >> ((where & (4 - size)) * 8)) & ((0x1 << (size * 8)) - 1);
+}
+
+static void config_write_pciex_rc(unsigned int *base, uint32_t where,
+ uint32_t size, uint32_t val)
+{
+ uint32_t data;
+
+ data = (val & ((0x1 << (size * 8)) - 1)) << ((where & (4 - size)) * 8);
+ PEX_OUT(base, PEXCADRS, MK_PEXCADRS(PEXCADRS_CMD_WRITE, where, size));
+ PEX_OUT(base, PEXCWDATA, data);
+}
+
+/* Interfaces */
+/* Note: Work-around
+ * On SCC PCIEXC, one device is seen on all 32 dev_no.
+ * As SCC PCIEXC can have only one device on the bus, we look only one dev_no.
+ * (dev_no = 1)
+ */
+static int scc_pciex_read_config(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, unsigned int *val)
+{
+ struct device_node *dn;
+ struct pci_controller *phb;
+
+ dn = bus->sysdata;
+ phb = pci_find_hose_for_OF_device(dn);
+
+ if (bus->number == phb->first_busno && PCI_SLOT(devfn) != 1) {
+ *val = ~0;
+ return PCIBIOS_DEVICE_NOT_FOUND;
+ }
+
+ if (bus->number == 0 && PCI_SLOT(devfn) == 0)
+ *val = config_read_pciex_rc(phb->cfg_addr, where, size);
+ else
+ *val = config_read_pciex_dev(phb->cfg_addr, bus->number,
+ PCI_SLOT(devfn), PCI_FUNC(devfn), where, size);
+
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static int scc_pciex_write_config(struct pci_bus *bus, unsigned int devfn,
+ int where, int size, unsigned int val)
+{
+ struct device_node *dn;
+ struct pci_controller *phb;
+
+ dn = bus->sysdata;
+ phb = pci_find_hose_for_OF_device(dn);
+
+ if (bus->number == phb->first_busno && PCI_SLOT(devfn) != 1)
+ return PCIBIOS_DEVICE_NOT_FOUND;
+
+ if (bus->number == 0 && PCI_SLOT(devfn) == 0)
+ config_write_pciex_rc(phb->cfg_addr, where, size, val);
+ else
+ config_write_pciex_dev(phb->cfg_addr, bus->number,
+ PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, val);
+ return PCIBIOS_SUCCESSFUL;
+}
+
+static struct pci_ops scc_pciex_pci_ops = {
+ scc_pciex_read_config,
+ scc_pciex_write_config,
+};
+
+static void pciex_clear_intr_all(unsigned int *base)
+{
+ PEX_OUT(base, PEXAERRSTS, 0xffffffff);
+ PEX_OUT(base, PEXPRERRSTS, 0xffffffff);
+ PEX_OUT(base, PEXINTSTS, 0xffffffff);
+}
+
+#if 0
+static void pciex_disable_intr_all(unsigned int *base)
+{
+ PEX_OUT(base, PEXINTMASK, 0x0);
+ PEX_OUT(base, PEXAERRMASK, 0x0);
+ PEX_OUT(base, PEXPRERRMASK, 0x0);
+ PEX_OUT(base, PEXVDMASK, 0x0);
+}
+#endif
+
+static void pciex_enable_intr_all(unsigned int *base)
+{
+ PEX_OUT(base, PEXINTMASK, 0x0000e7f1);
+ PEX_OUT(base, PEXAERRMASK, 0x03ff01ff);
+ PEX_OUT(base, PEXPRERRMASK, 0x0001010f);
+ PEX_OUT(base, PEXVDMASK, 0x00000001);
+}
+
+void pciex_check_status(unsigned int *base)
+{
+ uint32_t err = 0;
+ uint32_t intsts, aerr, prerr, rcvcp, lenerr;
+ uint32_t maea, maec;
+
+ intsts = PEX_IN(base, PEXINTSTS);
+ aerr = PEX_IN(base, PEXAERRSTS);
+ prerr = PEX_IN(base, PEXPRERRSTS);
+ rcvcp = PEX_IN(base, PEXRCVCPLIDA);
+ lenerr = PEX_IN(base, PEXLENERRIDA);
+
+ if (intsts || aerr || prerr || rcvcp || lenerr)
+ err = 1;
+
+ pr_info("PCEXC interrupt!!\n");
+ pr_info("PEXINTSTS :0x%08x\n", intsts);
+ pr_info("PEXAERRSTS :0x%08x\n", aerr);
+ pr_info("PEXPRERRSTS :0x%08x\n", prerr);
+ pr_info("PEXRCVCPLIDA :0x%08x\n", rcvcp);
+ pr_info("PEXLENERRIDA :0x%08x\n", lenerr);
+
+ /* print detail of Protection Error */
+ if (intsts & 0x00004000) {
+ uint32_t i, n;
+ for (i = 0; i < 4; i++) {
+ n = 1 << i;
+ if (prerr & n) {
+ maea = PEX_IN(base, PEXMAEA(i));
+ maec = PEX_IN(base, PEXMAEC(i));
+ pr_info("PEXMAEC%d :0x%08x\n", i, maec);
+ pr_info("PEXMAEA%d :0x%08x\n", i, maea);
+ }
+ }
+ }
+
+ if (err)
+ pciex_clear_intr_all(base);
+}
+
+static irqreturn_t pciex_handle_internal_irq(int irq, void *dev_id)
+{
+ struct pci_controller *phb = dev_id;
+
+ pr_debug("PCIEX:pciex_handle_internal_irq(irq=%d)\n", irq);
+
+ BUG_ON(phb->cfg_addr == NULL);
+
+ pciex_check_status(phb->cfg_addr);
+
+ return IRQ_HANDLED;
+}
+
+int celleb_setup_pciex(struct device_node *node, struct pci_controller *phb)
+{
+ struct resource r;
+ struct of_irq oirq;
+ int virq;
+
+ /* SMMIO registers; used inside this file */
+ if (of_address_to_resource(node, 0, &r)) {
+ pr_err("PCIEXC:Failed to get config resource.\n");
+ return 1;
+ }
+ phb->cfg_addr = ioremap(r.start, r.end - r.start + 1);
+ if (!phb->cfg_addr) {
+ pr_err("PCIEXC:Failed to remap SMMIO region.\n");
+ return 1;
+ }
+
+ /* Not use cfg_data, cmd and data regs are near address reg */
+ phb->cfg_data = NULL;
+
+ /* set pci_ops */
+ phb->ops = &scc_pciex_pci_ops;
+
+ /* internal interrupt handler */
+ if (of_irq_map_one(node, 1, &oirq)) {
+ pr_err("PCIEXC:Failed to map irq\n");
+ goto error;
+ }
+ virq = irq_create_of_mapping(oirq.controller, oirq.specifier,
+ oirq.size);
+ if (request_irq(virq, pciex_handle_internal_irq,
+ IRQF_DISABLED, "pciex", (void *)phb)) {
+ pr_err("PCIEXC:Failed to request irq\n");
+ goto error;
+ }
+
+ /* enable all interrupts */
+ pciex_clear_intr_all(phb->cfg_addr);
+ pciex_enable_intr_all(phb->cfg_addr);
+ /* MSI: TBD */
+
+ return 0;
+
+error:
+ phb->cfg_data = NULL;
+ if (phb->cfg_addr)
+ iounmap(phb->cfg_addr);
+ phb->cfg_addr = NULL;
+ return 1;
+}
^ permalink raw reply
* [PATCH 9/11] celleb: consolidate io-workarounds code
From: Ishizaki Kou @ 2008-03-05 8:37 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
Now, we can use generic io-workarounds mechanism and the workaround
code for spider-pci. This patch changes Celleb PCI code to use
spider-pci code.
Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
---
arch/powerpc/platforms/cell/celleb_pci.c | 53 +++-
arch/powerpc/platforms/cell/celleb_pci.h | 9
arch/powerpc/platforms/cell/celleb_scc_epci.c | 48 ----
arch/powerpc/platforms/cell/celleb_setup.c | 3
arch/powerpc/platforms/celleb/io-workarounds.c | 280 -------------------------
5 files changed, 47 insertions(+), 346 deletions(-)
Index: b/arch/powerpc/platforms/cell/celleb_pci.c
===================================================================
--- a/arch/powerpc/platforms/cell/celleb_pci.c 2008-03-04 14:00:28.000000000 +0900
+++ b/arch/powerpc/platforms/cell/celleb_pci.c 2008-03-04 14:01:10.000000000 +0900
@@ -40,6 +40,7 @@
#include <asm/pci-bridge.h>
#include <asm/ppc-pci.h>
+#include "io-workarounds.h"
#include "celleb_pci.h"
#define MAX_PCI_DEVICES 32
@@ -455,17 +456,6 @@
return 0;
}
-void __init fake_pci_workaround_init(struct pci_controller *phb)
-{
- /**
- * We will add fake pci bus to scc_pci_bus for the purpose to improve
- * I/O Macro performance. But device-tree and device drivers
- * are not ready to use address with a token.
- */
-
- /* celleb_pci_add_one(phb, NULL); */
-}
-
static struct of_device_id celleb_phb_match[] __initdata = {
{
.name = "pci-pseudo",
@@ -498,3 +488,44 @@
{
return PCI_PROBE_DEVTREE;
}
+
+struct celleb_iowa_bus_param {
+ struct ppc_pci_io *ops;
+ int (*init)(struct iowa_bus *, void *);
+ void *data;
+};
+
+static struct of_device_id celleb_io_workaround_match[] __initdata = {
+ {
+ .name = "epci",
+ .data = &(struct celleb_iowa_bus_param){
+ .ops = &spiderpci_ops,
+ .init = &spiderpci_iowa_init,
+ .data = (void *)0,
+ },
+ }, {
+ },
+};
+
+int __init celleb_io_workaround_init(void)
+{
+ struct pci_controller *phb;
+ struct device_node *node;
+ struct celleb_iowa_bus_param *param;
+ const struct of_device_id *match;
+
+ list_for_each_entry(phb, &hose_list, list_node) {
+ node = phb->dn;
+ match = of_match_node(celleb_io_workaround_match, node);
+
+ if (match) {
+ param = match->data;
+ iowa_register_bus(phb, param->ops, param->init,
+ param->data);
+ }
+ }
+
+ io_workaround_init();
+
+ return 0;
+}
Index: b/arch/powerpc/platforms/cell/celleb_pci.h
===================================================================
--- a/arch/powerpc/platforms/cell/celleb_pci.h 2008-03-04 14:00:28.000000000 +0900
+++ b/arch/powerpc/platforms/cell/celleb_pci.h 2008-03-04 14:01:10.000000000 +0900
@@ -27,16 +27,13 @@
#include <asm/prom.h>
#include <asm/ppc-pci.h>
+#include "io-workarounds.h"
+
extern int celleb_setup_phb(struct pci_controller *);
extern int celleb_pci_probe_mode(struct pci_bus *);
extern int celleb_setup_epci(struct device_node *, struct pci_controller *);
+extern int __init celleb_io_workaround_init(void);
-extern void *celleb_dummy_page_va;
-extern int __init celleb_pci_workaround_init(void);
-extern void __init celleb_pci_add_one(struct pci_controller *,
- void (*)(struct pci_controller *));
-extern void fake_pci_workaround_init(struct pci_controller *);
-extern void epci_workaround_init(struct pci_controller *);
#endif /* _CELLEB_PCI_H */
Index: b/arch/powerpc/platforms/cell/celleb_scc_epci.c
===================================================================
--- a/arch/powerpc/platforms/cell/celleb_scc_epci.c 2008-03-04 14:00:42.000000000 +0900
+++ b/arch/powerpc/platforms/cell/celleb_scc_epci.c 2008-03-04 14:01:10.000000000 +0900
@@ -41,10 +41,6 @@
#define iob() __asm__ __volatile__("eieio; sync":::"memory")
-struct epci_private {
- dma_addr_t dummy_page_da;
-};
-
static inline PCI_IO_ADDR celleb_epci_get_epci_base(
struct pci_controller *hose)
{
@@ -69,42 +65,6 @@
return hose->cfg_data;
}
-static void scc_epci_dummy_read(struct pci_controller *hose)
-{
- PCI_IO_ADDR epci_base;
- u32 val;
-
- epci_base = celleb_epci_get_epci_base(hose);
-
- val = in_be32(epci_base + SCC_EPCI_WATRP);
- iosync();
-
- return;
-}
-
-void __init epci_workaround_init(struct pci_controller *hose)
-{
- PCI_IO_ADDR epci_base;
- PCI_IO_ADDR reg;
- struct epci_private *private = hose->private_data;
-
- BUG_ON(!private);
-
- private->dummy_page_da = dma_map_single(hose->parent,
- celleb_dummy_page_va, PAGE_SIZE, DMA_FROM_DEVICE);
- if (private->dummy_page_da == DMA_ERROR_CODE) {
- printk(KERN_ERR "EPCI: dummy read disabled. "
- "Map dummy page failed.\n");
- return;
- }
-
- celleb_pci_add_one(hose, scc_epci_dummy_read);
- epci_base = celleb_epci_get_epci_base(hose);
-
- reg = epci_base + SCC_EPCI_DUMYRADR;
- out_be32(reg, private->dummy_page_da);
-}
-
static inline void clear_and_disable_master_abort_interrupt(
struct pci_controller *hose)
{
@@ -456,20 +416,12 @@
pr_debug("EPCI: cfg_data map 0x%016lx->0x%016lx + 0x%016lx\n",
r.start, (unsigned long)hose->cfg_data, (r.end - r.start + 1));
- hose->private_data = kzalloc(sizeof(struct epci_private), GFP_KERNEL);
- if (hose->private_data == NULL) {
- printk(KERN_ERR "EPCI: no memory for private data.\n");
- goto error;
- }
-
hose->ops = &celleb_epci_ops;
celleb_epci_init(hose);
return 0;
error:
- kfree(hose->private_data);
-
if (hose->cfg_addr)
iounmap(hose->cfg_addr);
Index: b/arch/powerpc/platforms/celleb/io-workarounds.c
===================================================================
--- a/arch/powerpc/platforms/celleb/io-workarounds.c 2008-03-04 13:54:15.000000000 +0900
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,280 +0,0 @@
-/*
- * Support for Celleb io workarounds
- *
- * (C) Copyright 2006-2007 TOSHIBA CORPORATION
- *
- * This file is based to arch/powerpc/platform/cell/io-workarounds.c
- *
- * 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#undef DEBUG
-
-#include <linux/of.h>
-#include <linux/of_device.h>
-#include <linux/irq.h>
-
-#include <asm/io.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
-#include <asm/pci-bridge.h>
-#include <asm/ppc-pci.h>
-
-#include "pci.h"
-
-#define MAX_CELLEB_PCI_BUS 4
-
-void *celleb_dummy_page_va;
-
-static struct celleb_pci_bus {
- struct pci_controller *phb;
- void (*dummy_read)(struct pci_controller *);
-} celleb_pci_busses[MAX_CELLEB_PCI_BUS];
-
-static int celleb_pci_count = 0;
-
-static struct celleb_pci_bus *celleb_pci_find(unsigned long vaddr,
- unsigned long paddr)
-{
- int i, j;
- struct resource *res;
-
- for (i = 0; i < celleb_pci_count; i++) {
- struct celleb_pci_bus *bus = &celleb_pci_busses[i];
- struct pci_controller *phb = bus->phb;
- if (paddr)
- for (j = 0; j < 3; j++) {
- res = &phb->mem_resources[j];
- if (paddr >= res->start && paddr <= res->end)
- return bus;
- }
- res = &phb->io_resource;
- if (vaddr && vaddr >= res->start && vaddr <= res->end)
- return bus;
- }
- return NULL;
-}
-
-static void celleb_io_flush(const PCI_IO_ADDR addr)
-{
- struct celleb_pci_bus *bus;
- int token;
-
- token = PCI_GET_ADDR_TOKEN(addr);
-
- if (token && token <= celleb_pci_count)
- bus = &celleb_pci_busses[token - 1];
- else {
- unsigned long vaddr, paddr;
- pte_t *ptep;
-
- vaddr = (unsigned long)PCI_FIX_ADDR(addr);
- if (vaddr < PHB_IO_BASE || vaddr >= PHB_IO_END)
- return;
-
- ptep = find_linux_pte(init_mm.pgd, vaddr);
- if (ptep == NULL)
- paddr = 0;
- else
- paddr = pte_pfn(*ptep) << PAGE_SHIFT;
- bus = celleb_pci_find(vaddr, paddr);
-
- if (bus == NULL)
- return;
- }
-
- if (bus->dummy_read)
- bus->dummy_read(bus->phb);
-}
-
-static u8 celleb_readb(const PCI_IO_ADDR addr)
-{
- u8 val;
- val = __do_readb(addr);
- celleb_io_flush(addr);
- return val;
-}
-
-static u16 celleb_readw(const PCI_IO_ADDR addr)
-{
- u16 val;
- val = __do_readw(addr);
- celleb_io_flush(addr);
- return val;
-}
-
-static u32 celleb_readl(const PCI_IO_ADDR addr)
-{
- u32 val;
- val = __do_readl(addr);
- celleb_io_flush(addr);
- return val;
-}
-
-static u64 celleb_readq(const PCI_IO_ADDR addr)
-{
- u64 val;
- val = __do_readq(addr);
- celleb_io_flush(addr);
- return val;
-}
-
-static u16 celleb_readw_be(const PCI_IO_ADDR addr)
-{
- u16 val;
- val = __do_readw_be(addr);
- celleb_io_flush(addr);
- return val;
-}
-
-static u32 celleb_readl_be(const PCI_IO_ADDR addr)
-{
- u32 val;
- val = __do_readl_be(addr);
- celleb_io_flush(addr);
- return val;
-}
-
-static u64 celleb_readq_be(const PCI_IO_ADDR addr)
-{
- u64 val;
- val = __do_readq_be(addr);
- celleb_io_flush(addr);
- return val;
-}
-
-static void celleb_readsb(const PCI_IO_ADDR addr,
- void *buf, unsigned long count)
-{
- __do_readsb(addr, buf, count);
- celleb_io_flush(addr);
-}
-
-static void celleb_readsw(const PCI_IO_ADDR addr,
- void *buf, unsigned long count)
-{
- __do_readsw(addr, buf, count);
- celleb_io_flush(addr);
-}
-
-static void celleb_readsl(const PCI_IO_ADDR addr,
- void *buf, unsigned long count)
-{
- __do_readsl(addr, buf, count);
- celleb_io_flush(addr);
-}
-
-static void celleb_memcpy_fromio(void *dest,
- const PCI_IO_ADDR src,
- unsigned long n)
-{
- __do_memcpy_fromio(dest, src, n);
- celleb_io_flush(src);
-}
-
-static void __iomem *celleb_ioremap(unsigned long addr,
- unsigned long size,
- unsigned long flags)
-{
- struct celleb_pci_bus *bus;
- void __iomem *res = __ioremap(addr, size, flags);
- int busno;
-
- bus = celleb_pci_find(0, addr);
- if (bus != NULL) {
- busno = bus - celleb_pci_busses;
- PCI_SET_ADDR_TOKEN(res, busno + 1);
- }
- return res;
-}
-
-static void celleb_iounmap(volatile void __iomem *addr)
-{
- return __iounmap(PCI_FIX_ADDR(addr));
-}
-
-static struct ppc_pci_io celleb_pci_io __initdata = {
- .readb = celleb_readb,
- .readw = celleb_readw,
- .readl = celleb_readl,
- .readq = celleb_readq,
- .readw_be = celleb_readw_be,
- .readl_be = celleb_readl_be,
- .readq_be = celleb_readq_be,
- .readsb = celleb_readsb,
- .readsw = celleb_readsw,
- .readsl = celleb_readsl,
- .memcpy_fromio = celleb_memcpy_fromio,
-};
-
-void __init celleb_pci_add_one(struct pci_controller *phb,
- void (*dummy_read)(struct pci_controller *))
-{
- struct celleb_pci_bus *bus = &celleb_pci_busses[celleb_pci_count];
- struct device_node *np = phb->dn;
-
- if (celleb_pci_count >= MAX_CELLEB_PCI_BUS) {
- printk(KERN_ERR "Too many pci bridges, workarounds"
- " disabled for %s\n", np->full_name);
- return;
- }
-
- celleb_pci_count++;
-
- bus->phb = phb;
- bus->dummy_read = dummy_read;
-}
-
-static struct of_device_id celleb_pci_workaround_match[] __initdata = {
- {
- .name = "pci-pseudo",
- .data = fake_pci_workaround_init,
- }, {
- .name = "epci",
- .data = epci_workaround_init,
- }, {
- },
-};
-
-int __init celleb_pci_workaround_init(void)
-{
- struct pci_controller *phb;
- struct device_node *node;
- const struct of_device_id *match;
- void (*init_func)(struct pci_controller *);
-
- celleb_dummy_page_va = kmalloc(PAGE_SIZE, GFP_KERNEL);
- if (!celleb_dummy_page_va) {
- printk(KERN_ERR "Celleb: dummy read disabled. "
- "Alloc celleb_dummy_page_va failed\n");
- return 1;
- }
-
- list_for_each_entry(phb, &hose_list, list_node) {
- node = phb->dn;
- match = of_match_node(celleb_pci_workaround_match, node);
-
- if (match) {
- init_func = match->data;
- (*init_func)(phb);
- }
- }
-
- ppc_pci_io = celleb_pci_io;
- ppc_md.ioremap = celleb_ioremap;
- ppc_md.iounmap = celleb_iounmap;
-
- return 0;
-}
Index: b/arch/powerpc/platforms/cell/celleb_setup.c
===================================================================
--- a/arch/powerpc/platforms/cell/celleb_setup.c 2008-03-04 14:00:28.000000000 +0900
+++ b/arch/powerpc/platforms/cell/celleb_setup.c 2008-03-04 14:01:10.000000000 +0900
@@ -114,7 +114,8 @@
/* Publish OF platform devices for southbridge IOs */
of_platform_bus_probe(NULL, celleb_bus_ids, NULL);
- celleb_pci_workaround_init();
+ /* Setup io-workaround for pci busses */
+ celleb_io_workaround_init();
return 0;
}
^ permalink raw reply
* [PATCH 8/11] cell: generalize io-workarounds code
From: Ishizaki Kou @ 2008-03-05 8:36 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
This patch splits cell io-workaround code into spider-pci dependent
code and a generic part, and also adds interfaces to the generic
io-workaround mechanism.
Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
---
Please test on CellBlade because I don't have any access to CellBlade.
arch/powerpc/platforms/cell/Makefile | 3
arch/powerpc/platforms/cell/io-workarounds.c | 365 +++++++--------------------
arch/powerpc/platforms/cell/io-workarounds.h | 45 +++
arch/powerpc/platforms/cell/spider-pci.c | 217 ++++++++++++++++
include/asm-powerpc/io-defs.h | 107 +++----
include/asm-powerpc/io.h | 8
6 files changed, 427 insertions(+), 318 deletions(-)
Index: b/arch/powerpc/platforms/cell/Makefile
===================================================================
--- a/arch/powerpc/platforms/cell/Makefile 2008-03-04 14:00:28.000000000 +0900
+++ b/arch/powerpc/platforms/cell/Makefile 2008-03-04 14:01:07.000000000 +0900
@@ -1,6 +1,7 @@
obj-$(CONFIG_PPC_CELL_NATIVE) += interrupt.o iommu.o setup.o \
cbe_regs.o spider-pic.o \
- pervasive.o pmu.o io-workarounds.o
+ pervasive.o pmu.o io-workarounds.o \
+ spider-pci.o
obj-$(CONFIG_CBE_RAS) += ras.o
obj-$(CONFIG_CBE_THERM) += cbe_thermal.o
Index: b/arch/powerpc/platforms/cell/io-workarounds.c
===================================================================
--- a/arch/powerpc/platforms/cell/io-workarounds.c 2008-03-04 13:54:15.000000000 +0900
+++ b/arch/powerpc/platforms/cell/io-workarounds.c 2008-03-04 14:01:07.000000000 +0900
@@ -1,343 +1,188 @@
/*
+ * Support PCI IO workaround
+ *
* Copyright (C) 2006 Benjamin Herrenschmidt <benh@kernel.crashing.org>
* IBM, Corp.
+ * (C) Copyright 2007-2008 TOSHIBA CORPORATION
*
* 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.
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
+
#undef DEBUG
#include <linux/kernel.h>
-#include <linux/mm.h>
-#include <linux/pci.h>
-#include <asm/io.h>
+
#include <asm/machdep.h>
-#include <asm/pci-bridge.h>
+#include <asm/pgtable.h>
#include <asm/ppc-pci.h>
+#include <asm/io.h>
+#include "io-workarounds.h"
-#define SPIDER_PCI_REG_BASE 0xd000
-#define SPIDER_PCI_VCI_CNTL_STAT 0x0110
-#define SPIDER_PCI_DUMMY_READ 0x0810
-#define SPIDER_PCI_DUMMY_READ_BASE 0x0814
-
-/* Undefine that to re-enable bogus prefetch
- *
- * Without that workaround, the chip will do bogus prefetch past
- * page boundary from system memory. This setting will disable that,
- * though the documentation is unclear as to the consequences of doing
- * so, either purely performances, or possible misbehaviour... It's not
- * clear wether the chip can handle unaligned accesses at all without
- * prefetching enabled.
- *
- * For now, things appear to be behaving properly with that prefetching
- * disabled and IDE, possibly because IDE isn't doing any unaligned
- * access.
- */
-#define SPIDER_DISABLE_PREFETCH
-
-#define MAX_SPIDERS 3
+#define IOWA_MAX_BUS 8
-static struct spider_pci_bus {
- void __iomem *regs;
- unsigned long mmio_start;
- unsigned long mmio_end;
- unsigned long pio_vstart;
- unsigned long pio_vend;
-} spider_pci_busses[MAX_SPIDERS];
-static int spider_pci_count;
+static struct iowa_bus iowa_busses[IOWA_MAX_BUS];
+static unsigned int iowa_bus_count;
-static struct spider_pci_bus *spider_pci_find(unsigned long vaddr,
- unsigned long paddr)
+static struct iowa_bus *iowa_pci_find(unsigned long vaddr, unsigned long paddr)
{
- int i;
+ int i, j;
+ struct resource *res;
- for (i = 0; i < spider_pci_count; i++) {
- struct spider_pci_bus *bus = &spider_pci_busses[i];
- if (paddr && paddr >= bus->mmio_start && paddr < bus->mmio_end)
- return bus;
- if (vaddr && vaddr >= bus->pio_vstart && vaddr < bus->pio_vend)
+ for (i = 0; i < iowa_bus_count; i++) {
+ struct iowa_bus *bus = &iowa_busses[i];
+ struct pci_controller *phb = bus->phb;
+
+ if (vaddr && vaddr >= bus->pio_vstart && vaddr <= bus->pio_vend)
return bus;
+
+ if (paddr)
+ for (j = 0; j < 3; j++) {
+ res = &phb->mem_resources[j];
+ if (paddr >= res->start && paddr <= res->end)
+ return bus;
+ }
}
+
return NULL;
}
-static void spider_io_flush(const volatile void __iomem *addr)
+struct iowa_bus *iowa_mem_find_bus(const PCI_IO_ADDR addr)
{
- struct spider_pci_bus *bus;
+ struct iowa_bus *bus;
int token;
- /* Get platform token (set by ioremap) from address */
token = PCI_GET_ADDR_TOKEN(addr);
- /* Fast path if we have a non-0 token, it indicates which bus we
- * are on.
- *
- * If the token is 0, that means either that the ioremap was done
- * before we initialized this layer, or it's a PIO operation. We
- * fallback to a low path in this case. Hopefully, internal devices
- * which are ioremap'ed early should use in_XX/out_XX functions
- * instead of the PCI ones and thus not suffer from the slowdown.
- *
- * Also note that currently, the workaround will not work for areas
- * that are not mapped with PTEs (bolted in the hash table). This
- * is the case for ioremaps done very early at boot (before
- * mem_init_done) and includes the mapping of the ISA IO space.
- *
- * Fortunately, none of the affected devices is expected to do DMA
- * and thus there should be no problem in practice.
- *
- * In order to improve performances, we only do the PTE search for
- * addresses falling in the PHB IO space area. That means it will
- * not work for hotplug'ed PHBs but those don't exist with Spider.
- */
- if (token && token <= spider_pci_count)
- bus = &spider_pci_busses[token - 1];
+ if (token && token <= iowa_bus_count)
+ bus = &iowa_busses[token - 1];
else {
unsigned long vaddr, paddr;
pte_t *ptep;
- /* Fixup physical address */
vaddr = (unsigned long)PCI_FIX_ADDR(addr);
+ if (vaddr < PHB_IO_BASE || vaddr >= PHB_IO_END)
+ return NULL;
- /* Check if it's in allowed range for PIO */
- if (vaddr < PHB_IO_BASE || vaddr > PHB_IO_END)
- return;
-
- /* Try to find a PTE. If not, clear the paddr, we'll do
- * a vaddr only lookup (PIO only)
- */
ptep = find_linux_pte(init_mm.pgd, vaddr);
if (ptep == NULL)
paddr = 0;
else
paddr = pte_pfn(*ptep) << PAGE_SHIFT;
+ bus = iowa_pci_find(vaddr, paddr);
- bus = spider_pci_find(vaddr, paddr);
if (bus == NULL)
- return;
+ return NULL;
}
- /* Now do the workaround
- */
- (void)in_be32(bus->regs + SPIDER_PCI_DUMMY_READ);
+ return bus;
}
-static u8 spider_readb(const volatile void __iomem *addr)
+struct iowa_bus *iowa_pio_find_bus(unsigned long port)
{
- u8 val = __do_readb(addr);
- spider_io_flush(addr);
- return val;
+ unsigned long vaddr = (unsigned long)pci_io_base + port;
+ return iowa_pci_find(vaddr, 0);
}
-static u16 spider_readw(const volatile void __iomem *addr)
-{
- u16 val = __do_readw(addr);
- spider_io_flush(addr);
- return val;
-}
-static u32 spider_readl(const volatile void __iomem *addr)
-{
- u32 val = __do_readl(addr);
- spider_io_flush(addr);
- return val;
+#define DEF_PCI_AC_RET(name, ret, at, al, space, aa) \
+static ret iowa_##name at \
+{ \
+ struct iowa_bus *bus; \
+ bus = iowa_##space##_find_bus(aa); \
+ if (bus && bus->ops && bus->ops->name) \
+ return bus->ops->name al; \
+ return __do_##name al; \
}
-static u64 spider_readq(const volatile void __iomem *addr)
-{
- u64 val = __do_readq(addr);
- spider_io_flush(addr);
- return val;
+#define DEF_PCI_AC_NORET(name, at, al, space, aa) \
+static void iowa_##name at \
+{ \
+ struct iowa_bus *bus; \
+ bus = iowa_##space##_find_bus(aa); \
+ if (bus && bus->ops && bus->ops->name) { \
+ bus->ops->name al; \
+ return; \
+ } \
+ __do_##name al; \
}
-static u16 spider_readw_be(const volatile void __iomem *addr)
-{
- u16 val = __do_readw_be(addr);
- spider_io_flush(addr);
- return val;
-}
+#include <asm/io-defs.h>
-static u32 spider_readl_be(const volatile void __iomem *addr)
-{
- u32 val = __do_readl_be(addr);
- spider_io_flush(addr);
- return val;
-}
+#undef DEF_PCI_AC_RET
+#undef DEF_PCI_AC_NORET
-static u64 spider_readq_be(const volatile void __iomem *addr)
-{
- u64 val = __do_readq_be(addr);
- spider_io_flush(addr);
- return val;
-}
-
-static void spider_readsb(const volatile void __iomem *addr, void *buf,
- unsigned long count)
-{
- __do_readsb(addr, buf, count);
- spider_io_flush(addr);
-}
+static struct ppc_pci_io __initdata iowa_pci_io = {
-static void spider_readsw(const volatile void __iomem *addr, void *buf,
- unsigned long count)
-{
- __do_readsw(addr, buf, count);
- spider_io_flush(addr);
-}
+#define DEF_PCI_AC_RET(name, ret, at, al, space, aa) .name = iowa_##name,
+#define DEF_PCI_AC_NORET(name, at, al, space, aa) .name = iowa_##name,
-static void spider_readsl(const volatile void __iomem *addr, void *buf,
- unsigned long count)
-{
- __do_readsl(addr, buf, count);
- spider_io_flush(addr);
-}
+#include <asm/io-defs.h>
-static void spider_memcpy_fromio(void *dest, const volatile void __iomem *src,
- unsigned long n)
-{
- __do_memcpy_fromio(dest, src, n);
- spider_io_flush(src);
-}
+#undef DEF_PCI_AC_RET
+#undef DEF_PCI_AC_NORET
+};
-static void __iomem * spider_ioremap(unsigned long addr, unsigned long size,
- unsigned long flags)
+static void __iomem *iowa_ioremap(unsigned long addr, unsigned long size,
+ unsigned long flags)
{
- struct spider_pci_bus *bus;
+ struct iowa_bus *bus;
void __iomem *res = __ioremap(addr, size, flags);
int busno;
- pr_debug("spider_ioremap(0x%lx, 0x%lx, 0x%lx) -> 0x%p\n",
- addr, size, flags, res);
-
- bus = spider_pci_find(0, addr);
+ bus = iowa_pci_find(0, addr);
if (bus != NULL) {
- busno = bus - spider_pci_busses;
- pr_debug(" found bus %d, setting token\n", busno);
+ busno = bus - iowa_busses;
PCI_SET_ADDR_TOKEN(res, busno + 1);
}
- pr_debug(" result=0x%p\n", res);
-
return res;
}
-static void __init spider_pci_setup_chip(struct spider_pci_bus *bus)
-{
-#ifdef SPIDER_DISABLE_PREFETCH
- u32 val = in_be32(bus->regs + SPIDER_PCI_VCI_CNTL_STAT);
- pr_debug(" PVCI_Control_Status was 0x%08x\n", val);
- out_be32(bus->regs + SPIDER_PCI_VCI_CNTL_STAT, val | 0x8);
-#endif
-
- /* Configure the dummy address for the workaround */
- out_be32(bus->regs + SPIDER_PCI_DUMMY_READ_BASE, 0x80000000);
-}
-
-static void __init spider_pci_add_one(struct pci_controller *phb)
+/* Regist new bus to support workaround */
+void __init iowa_register_bus(struct pci_controller *phb,
+ struct ppc_pci_io *ops,
+ int (*initfunc)(struct iowa_bus *, void *), void *data)
{
- struct spider_pci_bus *bus = &spider_pci_busses[spider_pci_count];
+ struct iowa_bus *bus;
struct device_node *np = phb->dn;
- struct resource rsrc;
- void __iomem *regs;
- if (spider_pci_count >= MAX_SPIDERS) {
- printk(KERN_ERR "Too many spider bridges, workarounds"
- " disabled for %s\n", np->full_name);
+ if (iowa_bus_count >= IOWA_MAX_BUS) {
+ pr_err("IOWA:Too many pci bridges, "
+ "workarounds disabled for %s\n", np->full_name);
return;
}
- /* Get the registers for the beast */
- if (of_address_to_resource(np, 0, &rsrc)) {
- printk(KERN_ERR "Failed to get registers for spider %s"
- " workarounds disabled\n", np->full_name);
- return;
- }
-
- /* Mask out some useless bits in there to get to the base of the
- * spider chip
- */
- rsrc.start &= ~0xfffffffful;
-
- /* Map them */
- regs = ioremap(rsrc.start + SPIDER_PCI_REG_BASE, 0x1000);
- if (regs == NULL) {
- printk(KERN_ERR "Failed to map registers for spider %s"
- " workarounds disabled\n", np->full_name);
- return;
- }
-
- spider_pci_count++;
-
- /* We assume spiders only have one MMIO resource */
- bus->mmio_start = phb->mem_resources[0].start;
- bus->mmio_end = phb->mem_resources[0].end + 1;
-
+ bus = &iowa_busses[iowa_bus_count];
+ bus->phb = phb;
+ bus->ops = ops;
bus->pio_vstart = (unsigned long)phb->io_base_virt;
- bus->pio_vend = bus->pio_vstart + phb->pci_io_size;
+ bus->pio_vend = bus->pio_vstart + phb->pci_io_size - 1;
- bus->regs = regs;
-
- printk(KERN_INFO "PCI: Spider MMIO workaround for %s\n",np->full_name);
+ if (initfunc)
+ if ((*initfunc)(bus, data))
+ return;
- pr_debug(" mmio (P) = 0x%016lx..0x%016lx\n",
- bus->mmio_start, bus->mmio_end);
- pr_debug(" pio (V) = 0x%016lx..0x%016lx\n",
- bus->pio_vstart, bus->pio_vend);
- pr_debug(" regs (P) = 0x%016lx (V) = 0x%p\n",
- rsrc.start + SPIDER_PCI_REG_BASE, bus->regs);
+ iowa_bus_count++;
- spider_pci_setup_chip(bus);
+ pr_debug("IOWA:[%d]Add bus, %s.\n", iowa_bus_count-1, np->full_name);
}
-static struct ppc_pci_io __initdata spider_pci_io = {
- .readb = spider_readb,
- .readw = spider_readw,
- .readl = spider_readl,
- .readq = spider_readq,
- .readw_be = spider_readw_be,
- .readl_be = spider_readl_be,
- .readq_be = spider_readq_be,
- .readsb = spider_readsb,
- .readsw = spider_readsw,
- .readsl = spider_readsl,
- .memcpy_fromio = spider_memcpy_fromio,
-};
-
-static int __init spider_pci_workaround_init(void)
+/* enable IO workaround */
+void __init io_workaround_init(void)
{
- struct pci_controller *phb;
-
- /* Find spider bridges. We assume they have been all probed
- * in setup_arch(). If that was to change, we would need to
- * update this code to cope with dynamically added busses
- */
- list_for_each_entry(phb, &hose_list, list_node) {
- struct device_node *np = phb->dn;
- const char *model = of_get_property(np, "model", NULL);
-
- /* If no model property or name isn't exactly "pci", skip */
- if (model == NULL || strcmp(np->name, "pci"))
- continue;
- /* If model is not "Spider", skip */
- if (strcmp(model, "Spider"))
- continue;
- spider_pci_add_one(phb);
- }
-
- /* No Spider PCI found, exit */
- if (spider_pci_count == 0)
- return 0;
-
- /* Setup IO callbacks. We only setup MMIO reads. PIO reads will
- * fallback to MMIO reads (though without a token, thus slower)
- */
- ppc_pci_io = spider_pci_io;
-
- /* Setup ioremap callback */
- ppc_md.ioremap = spider_ioremap;
-
- return 0;
+ ppc_pci_io = iowa_pci_io;
+ ppc_md.ioremap = iowa_ioremap;
}
-machine_arch_initcall(cell, spider_pci_workaround_init);
Index: b/arch/powerpc/platforms/cell/io-workarounds.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/arch/powerpc/platforms/cell/io-workarounds.h 2008-03-04 14:01:07.000000000 +0900
@@ -0,0 +1,45 @@
+/*
+ * Support PCI IO workaround
+ *
+ * (C) Copyright 2007-2008 TOSHIBA 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) 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _IO_WORKAROUNDS_H
+#define _IO_WORKAROUNDS_H
+
+#include <asm/io.h>
+#include <asm/pci-bridge.h>
+
+/* Bus info */
+struct iowa_bus {
+ struct pci_controller *phb;
+ struct ppc_pci_io *ops;
+ unsigned long pio_vstart;
+ unsigned long pio_vend;
+ void *private;
+};
+
+void __init io_workaround_init(void);
+void __init iowa_register_bus(struct pci_controller *, struct ppc_pci_io *,
+ int (*)(struct iowa_bus *, void *), void *);
+struct iowa_bus *iowa_mem_find_bus(const PCI_IO_ADDR);
+struct iowa_bus *iowa_pio_find_bus(unsigned long);
+
+extern struct ppc_pci_io spiderpci_ops;
+int spiderpci_iowa_init(struct iowa_bus *, void *);
+
+#endif /* _IO_WORKAROUNDS_H */
Index: b/arch/powerpc/platforms/cell/spider-pci.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/arch/powerpc/platforms/cell/spider-pci.c 2008-03-04 14:01:07.000000000 +0900
@@ -0,0 +1,217 @@
+/*
+ * IO workarounds for PCI on Celleb/Cell platform
+ *
+ * (C) Copyright 2006-2007 TOSHIBA 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) 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#undef DEBUG
+
+#include <linux/kernel.h>
+
+#include <asm/ppc-pci.h>
+#include <asm/pci-bridge.h>
+#include <asm/io.h>
+
+#include "io-workarounds.h"
+
+#undef SPIDER_PCI_DISABLE_PREFETCH
+
+#define SPIDER_PCI_REG_BASE 0xd000
+#define SPIDER_PCI_REG_SIZE 0x1000
+#define SPIDER_PCI_VCI_CNTL_STAT 0x0110
+#define SPIDER_PCI_DUMMY_READ 0x0810
+#define SPIDER_PCI_DUMMY_READ_BASE 0x0814
+
+struct spiderpci_iowa_private {
+ void __iomem *regs;
+};
+
+static void spiderpci_io_flush(struct iowa_bus *bus)
+{
+ struct spiderpci_iowa_private *priv;
+ u32 val;
+
+ priv = bus->private;
+ val = in_be32(priv->regs + SPIDER_PCI_DUMMY_READ);
+ iosync();
+}
+
+#define SPIDER_PCI_MMIO_READ(name, ret) \
+static ret spiderpci_##name(const PCI_IO_ADDR addr) \
+{ \
+ ret val = __do_##name(addr); \
+ spiderpci_io_flush(iowa_mem_find_bus(addr)); \
+ return val; \
+}
+
+#define SPIDER_PCI_MMIO_READ_STR(name) \
+static void spiderpci_##name(const PCI_IO_ADDR addr, void *buf, \
+ unsigned long count) \
+{ \
+ __do_##name(addr, buf, count); \
+ spiderpci_io_flush(iowa_mem_find_bus(addr)); \
+}
+
+SPIDER_PCI_MMIO_READ(readb, u8)
+SPIDER_PCI_MMIO_READ(readw, u16)
+SPIDER_PCI_MMIO_READ(readl, u32)
+SPIDER_PCI_MMIO_READ(readq, u64)
+SPIDER_PCI_MMIO_READ(readw_be, u16)
+SPIDER_PCI_MMIO_READ(readl_be, u32)
+SPIDER_PCI_MMIO_READ(readq_be, u64)
+SPIDER_PCI_MMIO_READ_STR(readsb)
+SPIDER_PCI_MMIO_READ_STR(readsw)
+SPIDER_PCI_MMIO_READ_STR(readsl)
+
+static void spiderpci_memcpy_fromio(void *dest, const PCI_IO_ADDR src,
+ unsigned long n)
+{
+ __do_memcpy_fromio(dest, src, n);
+ spiderpci_io_flush(iowa_mem_find_bus(src));
+}
+
+static int __init spiderpci_pci_setup_chip(struct pci_controller *phb,
+ void __iomem *regs)
+{
+ void *dummy_page_va;
+ dma_addr_t dummy_page_da;
+
+#ifdef SPIDER_PCI_DISABLE_PREFETCH
+ u32 val = in_be32(regs + SPIDER_PCI_VCI_CNTL_STAT);
+ pr_debug("SPIDER_IOWA:PVCI_Control_Status was 0x%08x\n", val);
+ out_be32(regs + SPIDER_PCI_VCI_CNTL_STAT, val | 0x8);
+#endif /* SPIDER_PCI_DISABLE_PREFETCH */
+
+ /* setup dummy read */
+ /*
+ * On CellBlade, we can't know that which XDR memory is used by
+ * kmalloc() to allocate dummy_page_va.
+ * In order to imporve the performance, the XDR which is used to
+ * allocate dummy_page_va is the nearest the spider-pci.
+ * We have to select the CBE which is the nearest the spider-pci
+ * to allocate memory from the best XDR, but I don't know that
+ * how to do.
+ *
+ * Celleb does not have this problem, because it has only one XDR.
+ */
+ dummy_page_va = kmalloc(PAGE_SIZE, GFP_KERNEL);
+ if (!dummy_page_va) {
+ pr_err("SPIDERPCI-IOWA:Alloc dummy_page_va failed.\n");
+ return -1;
+ }
+
+ dummy_page_da = dma_map_single(phb->parent, dummy_page_va,
+ PAGE_SIZE, DMA_FROM_DEVICE);
+ if (dummy_page_da == DMA_ERROR_CODE) {
+ pr_err("SPIDER-IOWA:Map dummy page filed.\n");
+ kfree(dummy_page_va);
+ return -1;
+ }
+
+ out_be32(regs + SPIDER_PCI_DUMMY_READ_BASE, dummy_page_da);
+
+ return 0;
+}
+
+int __init spiderpci_iowa_init(struct iowa_bus *bus, void *data)
+{
+ void __iomem *regs = NULL;
+ struct spiderpci_iowa_private *priv;
+ struct device_node *np = bus->phb->dn;
+ struct resource r;
+ unsigned long offset = (unsigned long)data;
+
+ pr_debug("SPIDERPCI-IOWA:Bus initialize for spider(%s)\n",
+ np->full_name);
+
+ priv = kzalloc(sizeof(struct spiderpci_iowa_private), GFP_KERNEL);
+ if (!priv) {
+ pr_err("SPIDERPCI-IOWA:"
+ "Can't allocate struct spiderpci_iowa_private");
+ return -1;
+ }
+
+ if (of_address_to_resource(np, 0, &r)) {
+ pr_err("SPIDERPCI-IOWA:Can't get resource.\n");
+ goto error;
+ }
+
+ regs = ioremap(r.start + offset, SPIDER_PCI_REG_SIZE);
+ if (!regs) {
+ pr_err("SPIDERPCI-IOWA:ioremap failed.\n");
+ goto error;
+ }
+ priv->regs = regs;
+ bus->private = priv;
+
+ if (spiderpci_pci_setup_chip(bus->phb, regs))
+ goto error;
+
+ return 0;
+
+error:
+ kfree(priv);
+ bus->private = NULL;
+
+ if (regs)
+ iounmap(regs);
+
+ return -1;
+}
+
+struct ppc_pci_io spiderpci_ops = {
+ .readb = spiderpci_readb,
+ .readw = spiderpci_readw,
+ .readl = spiderpci_readl,
+ .readq = spiderpci_readq,
+ .readw_be = spiderpci_readw_be,
+ .readl_be = spiderpci_readl_be,
+ .readq_be = spiderpci_readq_be,
+ .readsb = spiderpci_readsb,
+ .readsw = spiderpci_readsw,
+ .readsl = spiderpci_readsl,
+ .memcpy_fromio = spiderpci_memcpy_fromio,
+};
+
+/* We must setup the IOMMU before spider_io_workaround_init() is called. */
+static int __init spider_pci_workaround_init(void)
+{
+ struct pci_controller *phb;
+
+ /* Find spider bridges. We assume they have been all probed
+ * in setup_arch(). If that was to change, we would need to
+ * update this code to cope with dynamically added busses
+ */
+ list_for_each_entry(phb, &hose_list, list_node) {
+ struct device_node *np = phb->dn;
+ const char *model = of_get_property(np, "model", NULL);
+
+ /* If no model property or name isn't exactly "pci", skip */
+ if (model == NULL || strcmp(np->name, "pci"))
+ continue;
+ /* If model is not "Spider", skip */
+ if (strcmp(model, "Spider"))
+ continue;
+ iowa_register_bus(phb, &spiderpci_ops, &spiderpci_iowa_init,
+ (void *)SPIDER_PCI_REG_BASE);
+ }
+
+ io_workaround_init();
+
+ return 0;
+}
+machine_arch_initcall_sync(cell, spider_pci_workaround_init);
Index: b/include/asm-powerpc/io-defs.h
===================================================================
--- a/include/asm-powerpc/io-defs.h 2008-03-04 13:54:15.000000000 +0900
+++ b/include/asm-powerpc/io-defs.h 2008-03-04 14:01:07.000000000 +0900
@@ -1,59 +1,60 @@
/* This file is meant to be include multiple times by other headers */
+/* last 2 argments are used by platforms/cell/io-workarounds.[ch] */
-DEF_PCI_AC_RET(readb, u8, (const PCI_IO_ADDR addr), (addr))
-DEF_PCI_AC_RET(readw, u16, (const PCI_IO_ADDR addr), (addr))
-DEF_PCI_AC_RET(readl, u32, (const PCI_IO_ADDR addr), (addr))
-DEF_PCI_AC_RET(readw_be, u16, (const PCI_IO_ADDR addr), (addr))
-DEF_PCI_AC_RET(readl_be, u32, (const PCI_IO_ADDR addr), (addr))
-DEF_PCI_AC_NORET(writeb, (u8 val, PCI_IO_ADDR addr), (val, addr))
-DEF_PCI_AC_NORET(writew, (u16 val, PCI_IO_ADDR addr), (val, addr))
-DEF_PCI_AC_NORET(writel, (u32 val, PCI_IO_ADDR addr), (val, addr))
-DEF_PCI_AC_NORET(writew_be, (u16 val, PCI_IO_ADDR addr), (val, addr))
-DEF_PCI_AC_NORET(writel_be, (u32 val, PCI_IO_ADDR addr), (val, addr))
+DEF_PCI_AC_RET(readb, u8, (const PCI_IO_ADDR addr), (addr), mem, addr)
+DEF_PCI_AC_RET(readw, u16, (const PCI_IO_ADDR addr), (addr), mem, addr)
+DEF_PCI_AC_RET(readl, u32, (const PCI_IO_ADDR addr), (addr), mem, addr)
+DEF_PCI_AC_RET(readw_be, u16, (const PCI_IO_ADDR addr), (addr), mem, addr)
+DEF_PCI_AC_RET(readl_be, u32, (const PCI_IO_ADDR addr), (addr), mem, addr)
+DEF_PCI_AC_NORET(writeb, (u8 val, PCI_IO_ADDR addr), (val, addr), mem, addr)
+DEF_PCI_AC_NORET(writew, (u16 val, PCI_IO_ADDR addr), (val, addr), mem, addr)
+DEF_PCI_AC_NORET(writel, (u32 val, PCI_IO_ADDR addr), (val, addr), mem, addr)
+DEF_PCI_AC_NORET(writew_be, (u16 val, PCI_IO_ADDR addr), (val, addr), mem, addr)
+DEF_PCI_AC_NORET(writel_be, (u32 val, PCI_IO_ADDR addr), (val, addr), mem, addr)
#ifdef __powerpc64__
-DEF_PCI_AC_RET(readq, u64, (const PCI_IO_ADDR addr), (addr))
-DEF_PCI_AC_RET(readq_be, u64, (const PCI_IO_ADDR addr), (addr))
-DEF_PCI_AC_NORET(writeq, (u64 val, PCI_IO_ADDR addr), (val, addr))
-DEF_PCI_AC_NORET(writeq_be, (u64 val, PCI_IO_ADDR addr), (val, addr))
+DEF_PCI_AC_RET(readq, u64, (const PCI_IO_ADDR addr), (addr), mem, addr)
+DEF_PCI_AC_RET(readq_be, u64, (const PCI_IO_ADDR addr), (addr), mem, addr)
+DEF_PCI_AC_NORET(writeq, (u64 val, PCI_IO_ADDR addr), (val, addr), mem, addr)
+DEF_PCI_AC_NORET(writeq_be, (u64 val, PCI_IO_ADDR addr), (val, addr), mem, addr)
#endif /* __powerpc64__ */
-DEF_PCI_AC_RET(inb, u8, (unsigned long port), (port))
-DEF_PCI_AC_RET(inw, u16, (unsigned long port), (port))
-DEF_PCI_AC_RET(inl, u32, (unsigned long port), (port))
-DEF_PCI_AC_NORET(outb, (u8 val, unsigned long port), (val, port))
-DEF_PCI_AC_NORET(outw, (u16 val, unsigned long port), (val, port))
-DEF_PCI_AC_NORET(outl, (u32 val, unsigned long port), (val, port))
-
-DEF_PCI_AC_NORET(readsb, (const PCI_IO_ADDR a, void *b, unsigned long c), \
- (a, b, c))
-DEF_PCI_AC_NORET(readsw, (const PCI_IO_ADDR a, void *b, unsigned long c), \
- (a, b, c))
-DEF_PCI_AC_NORET(readsl, (const PCI_IO_ADDR a, void *b, unsigned long c), \
- (a, b, c))
-DEF_PCI_AC_NORET(writesb, (PCI_IO_ADDR a, const void *b, unsigned long c), \
- (a, b, c))
-DEF_PCI_AC_NORET(writesw, (PCI_IO_ADDR a, const void *b, unsigned long c), \
- (a, b, c))
-DEF_PCI_AC_NORET(writesl, (PCI_IO_ADDR a, const void *b, unsigned long c), \
- (a, b, c))
-
-DEF_PCI_AC_NORET(insb, (unsigned long p, void *b, unsigned long c), \
- (p, b, c))
-DEF_PCI_AC_NORET(insw, (unsigned long p, void *b, unsigned long c), \
- (p, b, c))
-DEF_PCI_AC_NORET(insl, (unsigned long p, void *b, unsigned long c), \
- (p, b, c))
-DEF_PCI_AC_NORET(outsb, (unsigned long p, const void *b, unsigned long c), \
- (p, b, c))
-DEF_PCI_AC_NORET(outsw, (unsigned long p, const void *b, unsigned long c), \
- (p, b, c))
-DEF_PCI_AC_NORET(outsl, (unsigned long p, const void *b, unsigned long c), \
- (p, b, c))
-
-DEF_PCI_AC_NORET(memset_io, (PCI_IO_ADDR a, int c, unsigned long n), \
- (a, c, n))
-DEF_PCI_AC_NORET(memcpy_fromio,(void *d,const PCI_IO_ADDR s,unsigned long n), \
- (d, s, n))
-DEF_PCI_AC_NORET(memcpy_toio,(PCI_IO_ADDR d,const void *s,unsigned long n), \
- (d, s, n))
+DEF_PCI_AC_RET(inb, u8, (unsigned long port), (port), pio, port)
+DEF_PCI_AC_RET(inw, u16, (unsigned long port), (port), pio, port)
+DEF_PCI_AC_RET(inl, u32, (unsigned long port), (port), pio, port)
+DEF_PCI_AC_NORET(outb, (u8 val, unsigned long port), (val, port), pio, port)
+DEF_PCI_AC_NORET(outw, (u16 val, unsigned long port), (val, port), pio, port)
+DEF_PCI_AC_NORET(outl, (u32 val, unsigned long port), (val, port), pio, port)
+
+DEF_PCI_AC_NORET(readsb, (const PCI_IO_ADDR a, void *b, unsigned long c),
+ (a, b, c), mem, a)
+DEF_PCI_AC_NORET(readsw, (const PCI_IO_ADDR a, void *b, unsigned long c),
+ (a, b, c), mem, a)
+DEF_PCI_AC_NORET(readsl, (const PCI_IO_ADDR a, void *b, unsigned long c),
+ (a, b, c), mem, a)
+DEF_PCI_AC_NORET(writesb, (PCI_IO_ADDR a, const void *b, unsigned long c),
+ (a, b, c), mem, a)
+DEF_PCI_AC_NORET(writesw, (PCI_IO_ADDR a, const void *b, unsigned long c),
+ (a, b, c), mem, a)
+DEF_PCI_AC_NORET(writesl, (PCI_IO_ADDR a, const void *b, unsigned long c),
+ (a, b, c), mem, a)
+
+DEF_PCI_AC_NORET(insb, (unsigned long p, void *b, unsigned long c),
+ (p, b, c), pio, p)
+DEF_PCI_AC_NORET(insw, (unsigned long p, void *b, unsigned long c),
+ (p, b, c), pio, p)
+DEF_PCI_AC_NORET(insl, (unsigned long p, void *b, unsigned long c),
+ (p, b, c), pio, p)
+DEF_PCI_AC_NORET(outsb, (unsigned long p, const void *b, unsigned long c),
+ (p, b, c), pio, p)
+DEF_PCI_AC_NORET(outsw, (unsigned long p, const void *b, unsigned long c),
+ (p, b, c), pio, p)
+DEF_PCI_AC_NORET(outsl, (unsigned long p, const void *b, unsigned long c),
+ (p, b, c), pio, p)
+
+DEF_PCI_AC_NORET(memset_io, (PCI_IO_ADDR a, int c, unsigned long n),
+ (a, c, n), mem, a)
+DEF_PCI_AC_NORET(memcpy_fromio, (void *d, const PCI_IO_ADDR s, unsigned long n),
+ (d, s, n), mem, s)
+DEF_PCI_AC_NORET(memcpy_toio, (PCI_IO_ADDR d, const void *s, unsigned long n),
+ (d, s, n), mem, d)
Index: b/include/asm-powerpc/io.h
===================================================================
--- a/include/asm-powerpc/io.h 2008-03-04 13:54:15.000000000 +0900
+++ b/include/asm-powerpc/io.h 2008-03-04 14:01:07.000000000 +0900
@@ -458,8 +458,8 @@
/* Structure containing all the hooks */
extern struct ppc_pci_io {
-#define DEF_PCI_AC_RET(name, ret, at, al) ret (*name) at;
-#define DEF_PCI_AC_NORET(name, at, al) void (*name) at;
+#define DEF_PCI_AC_RET(name, ret, at, al, space, aa) ret (*name) at;
+#define DEF_PCI_AC_NORET(name, at, al, space, aa) void (*name) at;
#include <asm/io-defs.h>
@@ -469,7 +469,7 @@
} ppc_pci_io;
/* The inline wrappers */
-#define DEF_PCI_AC_RET(name, ret, at, al) \
+#define DEF_PCI_AC_RET(name, ret, at, al, space, aa) \
static inline ret name at \
{ \
if (DEF_PCI_HOOK(ppc_pci_io.name) != NULL) \
@@ -477,7 +477,7 @@
return __do_##name al; \
}
-#define DEF_PCI_AC_NORET(name, at, al) \
+#define DEF_PCI_AC_NORET(name, at, al, space, aa) \
static inline void name at \
{ \
if (DEF_PCI_HOOK(ppc_pci_io.name) != NULL) \
^ permalink raw reply
* [PATCH 7/11] celleb: move miscellaneous files for Beat
From: Ishizaki Kou @ 2008-03-05 8:34 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
This patch moves miscellaneous files for Beat into platforms/cell/.
All files in this patch are used by celleb-beat only.
Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
---
arch/powerpc/platforms/cell/beat.c | 264 +++++++++++++++++++++++++
arch/powerpc/platforms/cell/beat.h | 42 ++++
arch/powerpc/platforms/cell/beat_interrupt.c | 283 +++++++++++++++++++++++++++
arch/powerpc/platforms/cell/beat_interrupt.h | 33 +++
arch/powerpc/platforms/cell/beat_smp.c | 124 +++++++++++
arch/powerpc/platforms/cell/beat_udbg.c | 98 +++++++++
arch/powerpc/platforms/celleb/beat.c | 264 -------------------------
arch/powerpc/platforms/celleb/beat.h | 42 ----
arch/powerpc/platforms/celleb/interrupt.c | 283 ---------------------------
arch/powerpc/platforms/celleb/interrupt.h | 33 ---
arch/powerpc/platforms/celleb/smp.c | 124 -----------
arch/powerpc/platforms/celleb/udbg_beat.c | 98 ---------
12 files changed, 844 insertions(+), 844 deletions(-)
Index: b/arch/powerpc/platforms/cell/beat.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/arch/powerpc/platforms/cell/beat.c 2008-03-04 14:01:05.000000000 +0900
@@ -0,0 +1,264 @@
+/*
+ * Simple routines for Celleb/Beat
+ *
+ * (C) Copyright 2006-2007 TOSHIBA 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) 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/rtc.h>
+#include <linux/interrupt.h>
+#include <linux/irqreturn.h>
+#include <linux/reboot.h>
+
+#include <asm/hvconsole.h>
+#include <asm/time.h>
+#include <asm/machdep.h>
+#include <asm/firmware.h>
+
+#include "beat_wrapper.h"
+#include "beat.h"
+#include "beat_interrupt.h"
+
+static int beat_pm_poweroff_flag;
+
+void beat_restart(char *cmd)
+{
+ beat_shutdown_logical_partition(!beat_pm_poweroff_flag);
+}
+
+void beat_power_off(void)
+{
+ beat_shutdown_logical_partition(0);
+}
+
+u64 beat_halt_code = 0x1000000000000000UL;
+EXPORT_SYMBOL(beat_halt_code);
+
+void beat_halt(void)
+{
+ beat_shutdown_logical_partition(beat_halt_code);
+}
+
+int beat_set_rtc_time(struct rtc_time *rtc_time)
+{
+ u64 tim;
+ tim = mktime(rtc_time->tm_year+1900,
+ rtc_time->tm_mon+1, rtc_time->tm_mday,
+ rtc_time->tm_hour, rtc_time->tm_min, rtc_time->tm_sec);
+ if (beat_rtc_write(tim))
+ return -1;
+ return 0;
+}
+
+void beat_get_rtc_time(struct rtc_time *rtc_time)
+{
+ u64 tim;
+
+ if (beat_rtc_read(&tim))
+ tim = 0;
+ to_tm(tim, rtc_time);
+ rtc_time->tm_year -= 1900;
+ rtc_time->tm_mon -= 1;
+}
+
+#define BEAT_NVRAM_SIZE 4096
+
+ssize_t beat_nvram_read(char *buf, size_t count, loff_t *index)
+{
+ unsigned int i;
+ unsigned long len;
+ char *p = buf;
+
+ if (*index >= BEAT_NVRAM_SIZE)
+ return -ENODEV;
+ i = *index;
+ if (i + count > BEAT_NVRAM_SIZE)
+ count = BEAT_NVRAM_SIZE - i;
+
+ for (; count != 0; count -= len) {
+ len = count;
+ if (len > BEAT_NVRW_CNT)
+ len = BEAT_NVRW_CNT;
+ if (beat_eeprom_read(i, len, p))
+ return -EIO;
+
+ p += len;
+ i += len;
+ }
+ *index = i;
+ return p - buf;
+}
+
+ssize_t beat_nvram_write(char *buf, size_t count, loff_t *index)
+{
+ unsigned int i;
+ unsigned long len;
+ char *p = buf;
+
+ if (*index >= BEAT_NVRAM_SIZE)
+ return -ENODEV;
+ i = *index;
+ if (i + count > BEAT_NVRAM_SIZE)
+ count = BEAT_NVRAM_SIZE - i;
+
+ for (; count != 0; count -= len) {
+ len = count;
+ if (len > BEAT_NVRW_CNT)
+ len = BEAT_NVRW_CNT;
+ if (beat_eeprom_write(i, len, p))
+ return -EIO;
+
+ p += len;
+ i += len;
+ }
+ *index = i;
+ return p - buf;
+}
+
+ssize_t beat_nvram_get_size(void)
+{
+ return BEAT_NVRAM_SIZE;
+}
+
+int beat_set_xdabr(unsigned long dabr)
+{
+ if (beat_set_dabr(dabr, DABRX_KERNEL | DABRX_USER))
+ return -1;
+ return 0;
+}
+
+int64_t beat_get_term_char(u64 vterm, u64 *len, u64 *t1, u64 *t2)
+{
+ u64 db[2];
+ s64 ret;
+
+ ret = beat_get_characters_from_console(vterm, len, (u8 *)db);
+ if (ret == 0) {
+ *t1 = db[0];
+ *t2 = db[1];
+ }
+ return ret;
+}
+EXPORT_SYMBOL(beat_get_term_char);
+
+int64_t beat_put_term_char(u64 vterm, u64 len, u64 t1, u64 t2)
+{
+ u64 db[2];
+
+ db[0] = t1;
+ db[1] = t2;
+ return beat_put_characters_to_console(vterm, len, (u8 *)db);
+}
+EXPORT_SYMBOL(beat_put_term_char);
+
+void beat_power_save(void)
+{
+ beat_pause(0);
+}
+
+#ifdef CONFIG_KEXEC
+void beat_kexec_cpu_down(int crash, int secondary)
+{
+ beatic_deinit_IRQ();
+}
+#endif
+
+static irqreturn_t beat_power_event(int virq, void *arg)
+{
+ printk(KERN_DEBUG "Beat: power button pressed\n");
+ beat_pm_poweroff_flag = 1;
+ ctrl_alt_del();
+ return IRQ_HANDLED;
+}
+
+static irqreturn_t beat_reset_event(int virq, void *arg)
+{
+ printk(KERN_DEBUG "Beat: reset button pressed\n");
+ beat_pm_poweroff_flag = 0;
+ ctrl_alt_del();
+ return IRQ_HANDLED;
+}
+
+static struct beat_event_list {
+ const char *typecode;
+ irq_handler_t handler;
+ unsigned int virq;
+} beat_event_list[] = {
+ { "power", beat_power_event, 0 },
+ { "reset", beat_reset_event, 0 },
+};
+
+static int __init beat_register_event(void)
+{
+ u64 path[4], data[2];
+ int rc, i;
+ unsigned int virq;
+
+ for (i = 0; i < ARRAY_SIZE(beat_event_list); i++) {
+ struct beat_event_list *ev = &beat_event_list[i];
+
+ if (beat_construct_event_receive_port(data) != 0) {
+ printk(KERN_ERR "Beat: "
+ "cannot construct event receive port for %s\n",
+ ev->typecode);
+ return -EINVAL;
+ }
+
+ virq = irq_create_mapping(NULL, data[0]);
+ if (virq == NO_IRQ) {
+ printk(KERN_ERR "Beat: failed to get virtual IRQ"
+ " for event receive port for %s\n",
+ ev->typecode);
+ beat_destruct_event_receive_port(data[0]);
+ return -EIO;
+ }
+ ev->virq = virq;
+
+ rc = request_irq(virq, ev->handler, IRQF_DISABLED,
+ ev->typecode, NULL);
+ if (rc != 0) {
+ printk(KERN_ERR "Beat: failed to request virtual IRQ"
+ " for event receive port for %s\n",
+ ev->typecode);
+ beat_destruct_event_receive_port(data[0]);
+ return rc;
+ }
+
+ path[0] = 0x1000000065780000ul; /* 1,ex */
+ path[1] = 0x627574746f6e0000ul; /* button */
+ path[2] = 0;
+ strncpy((char *)&path[2], ev->typecode, 8);
+ path[3] = 0;
+ data[1] = 0;
+
+ beat_create_repository_node(path, data);
+ }
+ return 0;
+}
+
+static int __init beat_event_init(void)
+{
+ if (!firmware_has_feature(FW_FEATURE_BEAT))
+ return -EINVAL;
+
+ beat_pm_poweroff_flag = 0;
+ return beat_register_event();
+}
+
+device_initcall(beat_event_init);
Index: b/arch/powerpc/platforms/cell/beat.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/arch/powerpc/platforms/cell/beat.h 2008-03-04 14:01:05.000000000 +0900
@@ -0,0 +1,42 @@
+/*
+ * Guest OS Interfaces.
+ *
+ * (C) Copyright 2006 TOSHIBA 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) 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef _CELLEB_BEAT_H
+#define _CELLEB_BEAT_H
+
+#define DABRX_KERNEL (1UL<<1)
+#define DABRX_USER (1UL<<0)
+
+int64_t beat_get_term_char(uint64_t, uint64_t *, uint64_t *, uint64_t *);
+int64_t beat_put_term_char(uint64_t, uint64_t, uint64_t, uint64_t);
+int64_t beat_repository_encode(int, const char *, uint64_t[4]);
+void beat_restart(char *);
+void beat_power_off(void);
+void beat_halt(void);
+int beat_set_rtc_time(struct rtc_time *);
+void beat_get_rtc_time(struct rtc_time *);
+ssize_t beat_nvram_get_size(void);
+ssize_t beat_nvram_read(char *, size_t, loff_t *);
+ssize_t beat_nvram_write(char *, size_t, loff_t *);
+int beat_set_xdabr(unsigned long);
+void beat_power_save(void);
+void beat_kexec_cpu_down(int, int);
+
+#endif /* _CELLEB_BEAT_H */
Index: b/arch/powerpc/platforms/cell/beat_interrupt.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/arch/powerpc/platforms/cell/beat_interrupt.c 2008-03-04 14:01:05.000000000 +0900
@@ -0,0 +1,283 @@
+/*
+ * Celleb/Beat Interrupt controller
+ *
+ * (C) Copyright 2006-2007 TOSHIBA 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) 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/percpu.h>
+#include <linux/types.h>
+
+#include <asm/machdep.h>
+
+#include "beat_interrupt.h"
+#include "beat_wrapper.h"
+
+#define MAX_IRQS NR_IRQS
+static DEFINE_SPINLOCK(beatic_irq_mask_lock);
+static uint64_t beatic_irq_mask_enable[(MAX_IRQS+255)/64];
+static uint64_t beatic_irq_mask_ack[(MAX_IRQS+255)/64];
+
+static struct irq_host *beatic_host;
+
+/*
+ * In this implementation, "virq" == "IRQ plug number",
+ * "(irq_hw_number_t)hwirq" == "IRQ outlet number".
+ */
+
+/* assumption: locked */
+static inline void beatic_update_irq_mask(unsigned int irq_plug)
+{
+ int off;
+ unsigned long masks[4];
+
+ off = (irq_plug / 256) * 4;
+ masks[0] = beatic_irq_mask_enable[off + 0]
+ & beatic_irq_mask_ack[off + 0];
+ masks[1] = beatic_irq_mask_enable[off + 1]
+ & beatic_irq_mask_ack[off + 1];
+ masks[2] = beatic_irq_mask_enable[off + 2]
+ & beatic_irq_mask_ack[off + 2];
+ masks[3] = beatic_irq_mask_enable[off + 3]
+ & beatic_irq_mask_ack[off + 3];
+ if (beat_set_interrupt_mask(irq_plug&~255UL,
+ masks[0], masks[1], masks[2], masks[3]) != 0)
+ panic("Failed to set mask IRQ!");
+}
+
+static void beatic_mask_irq(unsigned int irq_plug)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&beatic_irq_mask_lock, flags);
+ beatic_irq_mask_enable[irq_plug/64] &= ~(1UL << (63 - (irq_plug%64)));
+ beatic_update_irq_mask(irq_plug);
+ spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
+}
+
+static void beatic_unmask_irq(unsigned int irq_plug)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&beatic_irq_mask_lock, flags);
+ beatic_irq_mask_enable[irq_plug/64] |= 1UL << (63 - (irq_plug%64));
+ beatic_update_irq_mask(irq_plug);
+ spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
+}
+
+static void beatic_ack_irq(unsigned int irq_plug)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&beatic_irq_mask_lock, flags);
+ beatic_irq_mask_ack[irq_plug/64] &= ~(1UL << (63 - (irq_plug%64)));
+ beatic_update_irq_mask(irq_plug);
+ spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
+}
+
+static void beatic_end_irq(unsigned int irq_plug)
+{
+ s64 err;
+ unsigned long flags;
+
+ err = beat_downcount_of_interrupt(irq_plug);
+ if (err != 0) {
+ if ((err & 0xFFFFFFFF) != 0xFFFFFFF5) /* -11: wrong state */
+ panic("Failed to downcount IRQ! Error = %16lx", err);
+
+ printk(KERN_ERR "IRQ over-downcounted, plug %d\n", irq_plug);
+ }
+ spin_lock_irqsave(&beatic_irq_mask_lock, flags);
+ beatic_irq_mask_ack[irq_plug/64] |= 1UL << (63 - (irq_plug%64));
+ beatic_update_irq_mask(irq_plug);
+ spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
+}
+
+static struct irq_chip beatic_pic = {
+ .typename = " CELL-BEAT ",
+ .unmask = beatic_unmask_irq,
+ .mask = beatic_mask_irq,
+ .eoi = beatic_end_irq,
+};
+
+/*
+ * Dispose binding hardware IRQ number (hw) and Virtuql IRQ number (virq),
+ * update flags.
+ *
+ * Note that the number (virq) is already assigned at upper layer.
+ */
+static void beatic_pic_host_unmap(struct irq_host *h, unsigned int virq)
+{
+ beat_destruct_irq_plug(virq);
+}
+
+/*
+ * Create or update binding hardware IRQ number (hw) and Virtuql
+ * IRQ number (virq). This is called only once for a given mapping.
+ *
+ * Note that the number (virq) is already assigned at upper layer.
+ */
+static int beatic_pic_host_map(struct irq_host *h, unsigned int virq,
+ irq_hw_number_t hw)
+{
+ struct irq_desc *desc = get_irq_desc(virq);
+ int64_t err;
+
+ err = beat_construct_and_connect_irq_plug(virq, hw);
+ if (err < 0)
+ return -EIO;
+
+ desc->status |= IRQ_LEVEL;
+ set_irq_chip_and_handler(virq, &beatic_pic, handle_fasteoi_irq);
+ return 0;
+}
+
+/*
+ * Update binding hardware IRQ number (hw) and Virtuql
+ * IRQ number (virq). This is called only once for a given mapping.
+ */
+static void beatic_pic_host_remap(struct irq_host *h, unsigned int virq,
+ irq_hw_number_t hw)
+{
+ beat_construct_and_connect_irq_plug(virq, hw);
+}
+
+/*
+ * Translate device-tree interrupt spec to irq_hw_number_t style (ulong),
+ * to pass away to irq_create_mapping().
+ *
+ * Called from irq_create_of_mapping() only.
+ * Note: We have only 1 entry to translate.
+ */
+static int beatic_pic_host_xlate(struct irq_host *h, struct device_node *ct,
+ u32 *intspec, unsigned int intsize,
+ irq_hw_number_t *out_hwirq,
+ unsigned int *out_flags)
+{
+ u64 *intspec2 = (u64 *)intspec;
+
+ *out_hwirq = *intspec2;
+ *out_flags |= IRQ_TYPE_LEVEL_LOW;
+ return 0;
+}
+
+static int beatic_pic_host_match(struct irq_host *h, struct device_node *np)
+{
+ /* Match all */
+ return 1;
+}
+
+static struct irq_host_ops beatic_pic_host_ops = {
+ .map = beatic_pic_host_map,
+ .remap = beatic_pic_host_remap,
+ .unmap = beatic_pic_host_unmap,
+ .xlate = beatic_pic_host_xlate,
+ .match = beatic_pic_host_match,
+};
+
+/*
+ * Get an IRQ number
+ * Note: returns VIRQ
+ */
+static inline unsigned int beatic_get_irq_plug(void)
+{
+ int i;
+ uint64_t pending[4], ub;
+
+ for (i = 0; i < MAX_IRQS; i += 256) {
+ beat_detect_pending_interrupts(i, pending);
+ __asm__ ("cntlzd %0,%1":"=r"(ub):
+ "r"(pending[0] & beatic_irq_mask_enable[i/64+0]
+ & beatic_irq_mask_ack[i/64+0]));
+ if (ub != 64)
+ return i + ub + 0;
+ __asm__ ("cntlzd %0,%1":"=r"(ub):
+ "r"(pending[1] & beatic_irq_mask_enable[i/64+1]
+ & beatic_irq_mask_ack[i/64+1]));
+ if (ub != 64)
+ return i + ub + 64;
+ __asm__ ("cntlzd %0,%1":"=r"(ub):
+ "r"(pending[2] & beatic_irq_mask_enable[i/64+2]
+ & beatic_irq_mask_ack[i/64+2]));
+ if (ub != 64)
+ return i + ub + 128;
+ __asm__ ("cntlzd %0,%1":"=r"(ub):
+ "r"(pending[3] & beatic_irq_mask_enable[i/64+3]
+ & beatic_irq_mask_ack[i/64+3]));
+ if (ub != 64)
+ return i + ub + 192;
+ }
+
+ return NO_IRQ;
+}
+unsigned int beatic_get_irq(void)
+{
+ unsigned int ret;
+
+ ret = beatic_get_irq_plug();
+ if (ret != NO_IRQ)
+ beatic_ack_irq(ret);
+ return ret;
+}
+
+/*
+ */
+void __init beatic_init_IRQ(void)
+{
+ int i;
+
+ memset(beatic_irq_mask_enable, 0, sizeof(beatic_irq_mask_enable));
+ memset(beatic_irq_mask_ack, 255, sizeof(beatic_irq_mask_ack));
+ for (i = 0; i < MAX_IRQS; i += 256)
+ beat_set_interrupt_mask(i, 0L, 0L, 0L, 0L);
+
+ /* Set out get_irq function */
+ ppc_md.get_irq = beatic_get_irq;
+
+ /* Allocate an irq host */
+ beatic_host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0,
+ &beatic_pic_host_ops,
+ 0);
+ BUG_ON(beatic_host == NULL);
+ irq_set_default_host(beatic_host);
+}
+
+#ifdef CONFIG_SMP
+
+/* Nullified to compile with SMP mode */
+void beatic_setup_cpu(int cpu)
+{
+}
+
+void beatic_cause_IPI(int cpu, int mesg)
+{
+}
+
+void beatic_request_IPIs(void)
+{
+}
+#endif /* CONFIG_SMP */
+
+void beatic_deinit_IRQ(void)
+{
+ int i;
+
+ for (i = 1; i < NR_IRQS; i++)
+ beat_destruct_irq_plug(i);
+}
Index: b/arch/powerpc/platforms/cell/beat_interrupt.h
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/arch/powerpc/platforms/cell/beat_interrupt.h 2008-03-04 14:01:05.000000000 +0900
@@ -0,0 +1,33 @@
+/*
+ * Celleb/Beat Interrupt controller
+ *
+ * (C) Copyright 2006 TOSHIBA 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) 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef ASM_BEAT_PIC_H
+#define ASM_BEAT_PIC_H
+#ifdef __KERNEL__
+
+extern void beatic_init_IRQ(void);
+extern unsigned int beatic_get_irq(void);
+extern void beatic_cause_IPI(int cpu, int mesg);
+extern void beatic_request_IPIs(void);
+extern void beatic_setup_cpu(int);
+extern void beatic_deinit_IRQ(void);
+
+#endif
+#endif /* ASM_BEAT_PIC_H */
Index: b/arch/powerpc/platforms/cell/beat_smp.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/arch/powerpc/platforms/cell/beat_smp.c 2008-03-04 14:01:05.000000000 +0900
@@ -0,0 +1,124 @@
+/*
+ * SMP support for Celleb platform. (Incomplete)
+ *
+ * (C) Copyright 2006 TOSHIBA CORPORATION
+ *
+ * This code is based on arch/powerpc/platforms/cell/smp.c:
+ * Dave Engebretsen, Peter Bergner, and
+ * Mike Corrigan {engebret|bergner|mikec}@us.ibm.com
+ * Plus various changes from other IBM teams...
+ *
+ * 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#undef DEBUG
+
+#include <linux/kernel.h>
+#include <linux/smp.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/threads.h>
+#include <linux/cpu.h>
+
+#include <asm/irq.h>
+#include <asm/smp.h>
+#include <asm/machdep.h>
+#include <asm/udbg.h>
+
+#include "beat_interrupt.h"
+
+#ifdef DEBUG
+#define DBG(fmt...) udbg_printf(fmt)
+#else
+#define DBG(fmt...)
+#endif
+
+/*
+ * The primary thread of each non-boot processor is recorded here before
+ * smp init.
+ */
+/* static cpumask_t of_spin_map; */
+
+/**
+ * smp_startup_cpu() - start the given cpu
+ *
+ * At boot time, there is nothing to do for primary threads which were
+ * started from Open Firmware. For anything else, call RTAS with the
+ * appropriate start location.
+ *
+ * Returns:
+ * 0 - failure
+ * 1 - success
+ */
+static inline int __devinit smp_startup_cpu(unsigned int lcpu)
+{
+ return 0;
+}
+
+static void smp_beatic_message_pass(int target, int msg)
+{
+ unsigned int i;
+
+ if (target < NR_CPUS) {
+ beatic_cause_IPI(target, msg);
+ } else {
+ for_each_online_cpu(i) {
+ if (target == MSG_ALL_BUT_SELF
+ && i == smp_processor_id())
+ continue;
+ beatic_cause_IPI(i, msg);
+ }
+ }
+}
+
+static int __init smp_beatic_probe(void)
+{
+ return cpus_weight(cpu_possible_map);
+}
+
+static void __devinit smp_beatic_setup_cpu(int cpu)
+{
+ beatic_setup_cpu(cpu);
+}
+
+static void __devinit smp_celleb_kick_cpu(int nr)
+{
+ BUG_ON(nr < 0 || nr >= NR_CPUS);
+
+ if (!smp_startup_cpu(nr))
+ return;
+}
+
+static int smp_celleb_cpu_bootable(unsigned int nr)
+{
+ return 1;
+}
+static struct smp_ops_t bpa_beatic_smp_ops = {
+ .message_pass = smp_beatic_message_pass,
+ .probe = smp_beatic_probe,
+ .kick_cpu = smp_celleb_kick_cpu,
+ .setup_cpu = smp_beatic_setup_cpu,
+ .cpu_bootable = smp_celleb_cpu_bootable,
+};
+
+/* This is called very early */
+void __init smp_init_celleb(void)
+{
+ DBG(" -> smp_init_celleb()\n");
+
+ smp_ops = &bpa_beatic_smp_ops;
+
+ DBG(" <- smp_init_celleb()\n");
+}
Index: b/arch/powerpc/platforms/cell/beat_udbg.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/arch/powerpc/platforms/cell/beat_udbg.c 2008-03-04 14:01:05.000000000 +0900
@@ -0,0 +1,98 @@
+/*
+ * udbg function for Beat
+ *
+ * (C) Copyright 2006 TOSHIBA 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) 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/kernel.h>
+#include <linux/console.h>
+
+#include <asm/machdep.h>
+#include <asm/prom.h>
+#include <asm/udbg.h>
+
+#include "beat.h"
+
+#define celleb_vtermno 0
+
+static void udbg_putc_beat(char c)
+{
+ unsigned long rc;
+
+ if (c == '\n')
+ udbg_putc_beat('\r');
+
+ rc = beat_put_term_char(celleb_vtermno, 1, (uint64_t)c << 56, 0);
+}
+
+/* Buffered chars getc */
+static long inbuflen;
+static long inbuf[2]; /* must be 2 longs */
+
+static int udbg_getc_poll_beat(void)
+{
+ /* The interface is tricky because it may return up to 16 chars.
+ * We save them statically for future calls to udbg_getc().
+ */
+ char ch, *buf = (char *)inbuf;
+ int i;
+ long rc;
+ if (inbuflen == 0) {
+ /* get some more chars. */
+ inbuflen = 0;
+ rc = beat_get_term_char(celleb_vtermno, &inbuflen,
+ inbuf+0, inbuf+1);
+ if (rc != 0)
+ inbuflen = 0; /* otherwise inbuflen is garbage */
+ }
+ if (inbuflen <= 0 || inbuflen > 16) {
+ /* Catch error case as well as other oddities (corruption) */
+ inbuflen = 0;
+ return -1;
+ }
+ ch = buf[0];
+ for (i = 1; i < inbuflen; i++) /* shuffle them down. */
+ buf[i-1] = buf[i];
+ inbuflen--;
+ return ch;
+}
+
+static int udbg_getc_beat(void)
+{
+ int ch;
+ for (;;) {
+ ch = udbg_getc_poll_beat();
+ if (ch == -1) {
+ /* This shouldn't be needed...but... */
+ volatile unsigned long delay;
+ for (delay = 0; delay < 2000000; delay++)
+ ;
+ } else {
+ return ch;
+ }
+ }
+}
+
+/* call this from early_init() for a working debug console on
+ * vterm capable LPAR machines
+ */
+void __init udbg_init_debug_beat(void)
+{
+ udbg_putc = udbg_putc_beat;
+ udbg_getc = udbg_getc_beat;
+ udbg_getc_poll = udbg_getc_poll_beat;
+}
Index: b/arch/powerpc/platforms/celleb/beat.c
===================================================================
--- a/arch/powerpc/platforms/celleb/beat.c 2008-03-04 13:54:19.000000000 +0900
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,264 +0,0 @@
-/*
- * Simple routines for Celleb/Beat
- *
- * (C) Copyright 2006-2007 TOSHIBA 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) 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <linux/module.h>
-#include <linux/init.h>
-#include <linux/err.h>
-#include <linux/rtc.h>
-#include <linux/interrupt.h>
-#include <linux/irqreturn.h>
-#include <linux/reboot.h>
-
-#include <asm/hvconsole.h>
-#include <asm/time.h>
-#include <asm/machdep.h>
-#include <asm/firmware.h>
-
-#include "beat_wrapper.h"
-#include "beat.h"
-#include "interrupt.h"
-
-static int beat_pm_poweroff_flag;
-
-void beat_restart(char *cmd)
-{
- beat_shutdown_logical_partition(!beat_pm_poweroff_flag);
-}
-
-void beat_power_off(void)
-{
- beat_shutdown_logical_partition(0);
-}
-
-u64 beat_halt_code = 0x1000000000000000UL;
-EXPORT_SYMBOL(beat_halt_code);
-
-void beat_halt(void)
-{
- beat_shutdown_logical_partition(beat_halt_code);
-}
-
-int beat_set_rtc_time(struct rtc_time *rtc_time)
-{
- u64 tim;
- tim = mktime(rtc_time->tm_year+1900,
- rtc_time->tm_mon+1, rtc_time->tm_mday,
- rtc_time->tm_hour, rtc_time->tm_min, rtc_time->tm_sec);
- if (beat_rtc_write(tim))
- return -1;
- return 0;
-}
-
-void beat_get_rtc_time(struct rtc_time *rtc_time)
-{
- u64 tim;
-
- if (beat_rtc_read(&tim))
- tim = 0;
- to_tm(tim, rtc_time);
- rtc_time->tm_year -= 1900;
- rtc_time->tm_mon -= 1;
-}
-
-#define BEAT_NVRAM_SIZE 4096
-
-ssize_t beat_nvram_read(char *buf, size_t count, loff_t *index)
-{
- unsigned int i;
- unsigned long len;
- char *p = buf;
-
- if (*index >= BEAT_NVRAM_SIZE)
- return -ENODEV;
- i = *index;
- if (i + count > BEAT_NVRAM_SIZE)
- count = BEAT_NVRAM_SIZE - i;
-
- for (; count != 0; count -= len) {
- len = count;
- if (len > BEAT_NVRW_CNT)
- len = BEAT_NVRW_CNT;
- if (beat_eeprom_read(i, len, p))
- return -EIO;
-
- p += len;
- i += len;
- }
- *index = i;
- return p - buf;
-}
-
-ssize_t beat_nvram_write(char *buf, size_t count, loff_t *index)
-{
- unsigned int i;
- unsigned long len;
- char *p = buf;
-
- if (*index >= BEAT_NVRAM_SIZE)
- return -ENODEV;
- i = *index;
- if (i + count > BEAT_NVRAM_SIZE)
- count = BEAT_NVRAM_SIZE - i;
-
- for (; count != 0; count -= len) {
- len = count;
- if (len > BEAT_NVRW_CNT)
- len = BEAT_NVRW_CNT;
- if (beat_eeprom_write(i, len, p))
- return -EIO;
-
- p += len;
- i += len;
- }
- *index = i;
- return p - buf;
-}
-
-ssize_t beat_nvram_get_size(void)
-{
- return BEAT_NVRAM_SIZE;
-}
-
-int beat_set_xdabr(unsigned long dabr)
-{
- if (beat_set_dabr(dabr, DABRX_KERNEL | DABRX_USER))
- return -1;
- return 0;
-}
-
-int64_t beat_get_term_char(u64 vterm, u64 *len, u64 *t1, u64 *t2)
-{
- u64 db[2];
- s64 ret;
-
- ret = beat_get_characters_from_console(vterm, len, (u8 *)db);
- if (ret == 0) {
- *t1 = db[0];
- *t2 = db[1];
- }
- return ret;
-}
-EXPORT_SYMBOL(beat_get_term_char);
-
-int64_t beat_put_term_char(u64 vterm, u64 len, u64 t1, u64 t2)
-{
- u64 db[2];
-
- db[0] = t1;
- db[1] = t2;
- return beat_put_characters_to_console(vterm, len, (u8 *)db);
-}
-EXPORT_SYMBOL(beat_put_term_char);
-
-void beat_power_save(void)
-{
- beat_pause(0);
-}
-
-#ifdef CONFIG_KEXEC
-void beat_kexec_cpu_down(int crash, int secondary)
-{
- beatic_deinit_IRQ();
-}
-#endif
-
-static irqreturn_t beat_power_event(int virq, void *arg)
-{
- printk(KERN_DEBUG "Beat: power button pressed\n");
- beat_pm_poweroff_flag = 1;
- ctrl_alt_del();
- return IRQ_HANDLED;
-}
-
-static irqreturn_t beat_reset_event(int virq, void *arg)
-{
- printk(KERN_DEBUG "Beat: reset button pressed\n");
- beat_pm_poweroff_flag = 0;
- ctrl_alt_del();
- return IRQ_HANDLED;
-}
-
-static struct beat_event_list {
- const char *typecode;
- irq_handler_t handler;
- unsigned int virq;
-} beat_event_list[] = {
- { "power", beat_power_event, 0 },
- { "reset", beat_reset_event, 0 },
-};
-
-static int __init beat_register_event(void)
-{
- u64 path[4], data[2];
- int rc, i;
- unsigned int virq;
-
- for (i = 0; i < ARRAY_SIZE(beat_event_list); i++) {
- struct beat_event_list *ev = &beat_event_list[i];
-
- if (beat_construct_event_receive_port(data) != 0) {
- printk(KERN_ERR "Beat: "
- "cannot construct event receive port for %s\n",
- ev->typecode);
- return -EINVAL;
- }
-
- virq = irq_create_mapping(NULL, data[0]);
- if (virq == NO_IRQ) {
- printk(KERN_ERR "Beat: failed to get virtual IRQ"
- " for event receive port for %s\n",
- ev->typecode);
- beat_destruct_event_receive_port(data[0]);
- return -EIO;
- }
- ev->virq = virq;
-
- rc = request_irq(virq, ev->handler, IRQF_DISABLED,
- ev->typecode, NULL);
- if (rc != 0) {
- printk(KERN_ERR "Beat: failed to request virtual IRQ"
- " for event receive port for %s\n",
- ev->typecode);
- beat_destruct_event_receive_port(data[0]);
- return rc;
- }
-
- path[0] = 0x1000000065780000ul; /* 1,ex */
- path[1] = 0x627574746f6e0000ul; /* button */
- path[2] = 0;
- strncpy((char *)&path[2], ev->typecode, 8);
- path[3] = 0;
- data[1] = 0;
-
- beat_create_repository_node(path, data);
- }
- return 0;
-}
-
-static int __init beat_event_init(void)
-{
- if (!firmware_has_feature(FW_FEATURE_BEAT))
- return -EINVAL;
-
- beat_pm_poweroff_flag = 0;
- return beat_register_event();
-}
-
-device_initcall(beat_event_init);
Index: b/arch/powerpc/platforms/celleb/beat.h
===================================================================
--- a/arch/powerpc/platforms/celleb/beat.h 2008-03-04 13:54:19.000000000 +0900
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,42 +0,0 @@
-/*
- * Guest OS Interfaces.
- *
- * (C) Copyright 2006 TOSHIBA 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) 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef _CELLEB_BEAT_H
-#define _CELLEB_BEAT_H
-
-#define DABRX_KERNEL (1UL<<1)
-#define DABRX_USER (1UL<<0)
-
-int64_t beat_get_term_char(uint64_t, uint64_t *, uint64_t *, uint64_t *);
-int64_t beat_put_term_char(uint64_t, uint64_t, uint64_t, uint64_t);
-int64_t beat_repository_encode(int, const char *, uint64_t[4]);
-void beat_restart(char *);
-void beat_power_off(void);
-void beat_halt(void);
-int beat_set_rtc_time(struct rtc_time *);
-void beat_get_rtc_time(struct rtc_time *);
-ssize_t beat_nvram_get_size(void);
-ssize_t beat_nvram_read(char *, size_t, loff_t *);
-ssize_t beat_nvram_write(char *, size_t, loff_t *);
-int beat_set_xdabr(unsigned long);
-void beat_power_save(void);
-void beat_kexec_cpu_down(int, int);
-
-#endif /* _CELLEB_BEAT_H */
Index: b/arch/powerpc/platforms/celleb/interrupt.c
===================================================================
--- a/arch/powerpc/platforms/celleb/interrupt.c 2008-03-04 13:54:19.000000000 +0900
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,283 +0,0 @@
-/*
- * Celleb/Beat Interrupt controller
- *
- * (C) Copyright 2006-2007 TOSHIBA 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) 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/percpu.h>
-#include <linux/types.h>
-
-#include <asm/machdep.h>
-
-#include "interrupt.h"
-#include "beat_wrapper.h"
-
-#define MAX_IRQS NR_IRQS
-static DEFINE_SPINLOCK(beatic_irq_mask_lock);
-static uint64_t beatic_irq_mask_enable[(MAX_IRQS+255)/64];
-static uint64_t beatic_irq_mask_ack[(MAX_IRQS+255)/64];
-
-static struct irq_host *beatic_host;
-
-/*
- * In this implementation, "virq" == "IRQ plug number",
- * "(irq_hw_number_t)hwirq" == "IRQ outlet number".
- */
-
-/* assumption: locked */
-static inline void beatic_update_irq_mask(unsigned int irq_plug)
-{
- int off;
- unsigned long masks[4];
-
- off = (irq_plug / 256) * 4;
- masks[0] = beatic_irq_mask_enable[off + 0]
- & beatic_irq_mask_ack[off + 0];
- masks[1] = beatic_irq_mask_enable[off + 1]
- & beatic_irq_mask_ack[off + 1];
- masks[2] = beatic_irq_mask_enable[off + 2]
- & beatic_irq_mask_ack[off + 2];
- masks[3] = beatic_irq_mask_enable[off + 3]
- & beatic_irq_mask_ack[off + 3];
- if (beat_set_interrupt_mask(irq_plug&~255UL,
- masks[0], masks[1], masks[2], masks[3]) != 0)
- panic("Failed to set mask IRQ!");
-}
-
-static void beatic_mask_irq(unsigned int irq_plug)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&beatic_irq_mask_lock, flags);
- beatic_irq_mask_enable[irq_plug/64] &= ~(1UL << (63 - (irq_plug%64)));
- beatic_update_irq_mask(irq_plug);
- spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
-}
-
-static void beatic_unmask_irq(unsigned int irq_plug)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&beatic_irq_mask_lock, flags);
- beatic_irq_mask_enable[irq_plug/64] |= 1UL << (63 - (irq_plug%64));
- beatic_update_irq_mask(irq_plug);
- spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
-}
-
-static void beatic_ack_irq(unsigned int irq_plug)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&beatic_irq_mask_lock, flags);
- beatic_irq_mask_ack[irq_plug/64] &= ~(1UL << (63 - (irq_plug%64)));
- beatic_update_irq_mask(irq_plug);
- spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
-}
-
-static void beatic_end_irq(unsigned int irq_plug)
-{
- s64 err;
- unsigned long flags;
-
- err = beat_downcount_of_interrupt(irq_plug);
- if (err != 0) {
- if ((err & 0xFFFFFFFF) != 0xFFFFFFF5) /* -11: wrong state */
- panic("Failed to downcount IRQ! Error = %16lx", err);
-
- printk(KERN_ERR "IRQ over-downcounted, plug %d\n", irq_plug);
- }
- spin_lock_irqsave(&beatic_irq_mask_lock, flags);
- beatic_irq_mask_ack[irq_plug/64] |= 1UL << (63 - (irq_plug%64));
- beatic_update_irq_mask(irq_plug);
- spin_unlock_irqrestore(&beatic_irq_mask_lock, flags);
-}
-
-static struct irq_chip beatic_pic = {
- .typename = " CELL-BEAT ",
- .unmask = beatic_unmask_irq,
- .mask = beatic_mask_irq,
- .eoi = beatic_end_irq,
-};
-
-/*
- * Dispose binding hardware IRQ number (hw) and Virtuql IRQ number (virq),
- * update flags.
- *
- * Note that the number (virq) is already assigned at upper layer.
- */
-static void beatic_pic_host_unmap(struct irq_host *h, unsigned int virq)
-{
- beat_destruct_irq_plug(virq);
-}
-
-/*
- * Create or update binding hardware IRQ number (hw) and Virtuql
- * IRQ number (virq). This is called only once for a given mapping.
- *
- * Note that the number (virq) is already assigned at upper layer.
- */
-static int beatic_pic_host_map(struct irq_host *h, unsigned int virq,
- irq_hw_number_t hw)
-{
- struct irq_desc *desc = get_irq_desc(virq);
- int64_t err;
-
- err = beat_construct_and_connect_irq_plug(virq, hw);
- if (err < 0)
- return -EIO;
-
- desc->status |= IRQ_LEVEL;
- set_irq_chip_and_handler(virq, &beatic_pic, handle_fasteoi_irq);
- return 0;
-}
-
-/*
- * Update binding hardware IRQ number (hw) and Virtuql
- * IRQ number (virq). This is called only once for a given mapping.
- */
-static void beatic_pic_host_remap(struct irq_host *h, unsigned int virq,
- irq_hw_number_t hw)
-{
- beat_construct_and_connect_irq_plug(virq, hw);
-}
-
-/*
- * Translate device-tree interrupt spec to irq_hw_number_t style (ulong),
- * to pass away to irq_create_mapping().
- *
- * Called from irq_create_of_mapping() only.
- * Note: We have only 1 entry to translate.
- */
-static int beatic_pic_host_xlate(struct irq_host *h, struct device_node *ct,
- u32 *intspec, unsigned int intsize,
- irq_hw_number_t *out_hwirq,
- unsigned int *out_flags)
-{
- u64 *intspec2 = (u64 *)intspec;
-
- *out_hwirq = *intspec2;
- *out_flags |= IRQ_TYPE_LEVEL_LOW;
- return 0;
-}
-
-static int beatic_pic_host_match(struct irq_host *h, struct device_node *np)
-{
- /* Match all */
- return 1;
-}
-
-static struct irq_host_ops beatic_pic_host_ops = {
- .map = beatic_pic_host_map,
- .remap = beatic_pic_host_remap,
- .unmap = beatic_pic_host_unmap,
- .xlate = beatic_pic_host_xlate,
- .match = beatic_pic_host_match,
-};
-
-/*
- * Get an IRQ number
- * Note: returns VIRQ
- */
-static inline unsigned int beatic_get_irq_plug(void)
-{
- int i;
- uint64_t pending[4], ub;
-
- for (i = 0; i < MAX_IRQS; i += 256) {
- beat_detect_pending_interrupts(i, pending);
- __asm__ ("cntlzd %0,%1":"=r"(ub):
- "r"(pending[0] & beatic_irq_mask_enable[i/64+0]
- & beatic_irq_mask_ack[i/64+0]));
- if (ub != 64)
- return i + ub + 0;
- __asm__ ("cntlzd %0,%1":"=r"(ub):
- "r"(pending[1] & beatic_irq_mask_enable[i/64+1]
- & beatic_irq_mask_ack[i/64+1]));
- if (ub != 64)
- return i + ub + 64;
- __asm__ ("cntlzd %0,%1":"=r"(ub):
- "r"(pending[2] & beatic_irq_mask_enable[i/64+2]
- & beatic_irq_mask_ack[i/64+2]));
- if (ub != 64)
- return i + ub + 128;
- __asm__ ("cntlzd %0,%1":"=r"(ub):
- "r"(pending[3] & beatic_irq_mask_enable[i/64+3]
- & beatic_irq_mask_ack[i/64+3]));
- if (ub != 64)
- return i + ub + 192;
- }
-
- return NO_IRQ;
-}
-unsigned int beatic_get_irq(void)
-{
- unsigned int ret;
-
- ret = beatic_get_irq_plug();
- if (ret != NO_IRQ)
- beatic_ack_irq(ret);
- return ret;
-}
-
-/*
- */
-void __init beatic_init_IRQ(void)
-{
- int i;
-
- memset(beatic_irq_mask_enable, 0, sizeof(beatic_irq_mask_enable));
- memset(beatic_irq_mask_ack, 255, sizeof(beatic_irq_mask_ack));
- for (i = 0; i < MAX_IRQS; i += 256)
- beat_set_interrupt_mask(i, 0L, 0L, 0L, 0L);
-
- /* Set out get_irq function */
- ppc_md.get_irq = beatic_get_irq;
-
- /* Allocate an irq host */
- beatic_host = irq_alloc_host(NULL, IRQ_HOST_MAP_NOMAP, 0,
- &beatic_pic_host_ops,
- 0);
- BUG_ON(beatic_host == NULL);
- irq_set_default_host(beatic_host);
-}
-
-#ifdef CONFIG_SMP
-
-/* Nullified to compile with SMP mode */
-void beatic_setup_cpu(int cpu)
-{
-}
-
-void beatic_cause_IPI(int cpu, int mesg)
-{
-}
-
-void beatic_request_IPIs(void)
-{
-}
-#endif /* CONFIG_SMP */
-
-void beatic_deinit_IRQ(void)
-{
- int i;
-
- for (i = 1; i < NR_IRQS; i++)
- beat_destruct_irq_plug(i);
-}
Index: b/arch/powerpc/platforms/celleb/interrupt.h
===================================================================
--- a/arch/powerpc/platforms/celleb/interrupt.h 2008-03-04 13:54:15.000000000 +0900
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,33 +0,0 @@
-/*
- * Celleb/Beat Interrupt controller
- *
- * (C) Copyright 2006 TOSHIBA 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) 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#ifndef ASM_BEAT_PIC_H
-#define ASM_BEAT_PIC_H
-#ifdef __KERNEL__
-
-extern void beatic_init_IRQ(void);
-extern unsigned int beatic_get_irq(void);
-extern void beatic_cause_IPI(int cpu, int mesg);
-extern void beatic_request_IPIs(void);
-extern void beatic_setup_cpu(int);
-extern void beatic_deinit_IRQ(void);
-
-#endif
-#endif /* ASM_BEAT_PIC_H */
Index: b/arch/powerpc/platforms/celleb/smp.c
===================================================================
--- a/arch/powerpc/platforms/celleb/smp.c 2008-03-04 13:54:15.000000000 +0900
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,124 +0,0 @@
-/*
- * SMP support for Celleb platform. (Incomplete)
- *
- * (C) Copyright 2006 TOSHIBA CORPORATION
- *
- * This code is based on arch/powerpc/platforms/cell/smp.c:
- * Dave Engebretsen, Peter Bergner, and
- * Mike Corrigan {engebret|bergner|mikec}@us.ibm.com
- * Plus various changes from other IBM teams...
- *
- * 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#undef DEBUG
-
-#include <linux/kernel.h>
-#include <linux/smp.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/threads.h>
-#include <linux/cpu.h>
-
-#include <asm/irq.h>
-#include <asm/smp.h>
-#include <asm/machdep.h>
-#include <asm/udbg.h>
-
-#include "interrupt.h"
-
-#ifdef DEBUG
-#define DBG(fmt...) udbg_printf(fmt)
-#else
-#define DBG(fmt...)
-#endif
-
-/*
- * The primary thread of each non-boot processor is recorded here before
- * smp init.
- */
-/* static cpumask_t of_spin_map; */
-
-/**
- * smp_startup_cpu() - start the given cpu
- *
- * At boot time, there is nothing to do for primary threads which were
- * started from Open Firmware. For anything else, call RTAS with the
- * appropriate start location.
- *
- * Returns:
- * 0 - failure
- * 1 - success
- */
-static inline int __devinit smp_startup_cpu(unsigned int lcpu)
-{
- return 0;
-}
-
-static void smp_beatic_message_pass(int target, int msg)
-{
- unsigned int i;
-
- if (target < NR_CPUS) {
- beatic_cause_IPI(target, msg);
- } else {
- for_each_online_cpu(i) {
- if (target == MSG_ALL_BUT_SELF
- && i == smp_processor_id())
- continue;
- beatic_cause_IPI(i, msg);
- }
- }
-}
-
-static int __init smp_beatic_probe(void)
-{
- return cpus_weight(cpu_possible_map);
-}
-
-static void __devinit smp_beatic_setup_cpu(int cpu)
-{
- beatic_setup_cpu(cpu);
-}
-
-static void __devinit smp_celleb_kick_cpu(int nr)
-{
- BUG_ON(nr < 0 || nr >= NR_CPUS);
-
- if (!smp_startup_cpu(nr))
- return;
-}
-
-static int smp_celleb_cpu_bootable(unsigned int nr)
-{
- return 1;
-}
-static struct smp_ops_t bpa_beatic_smp_ops = {
- .message_pass = smp_beatic_message_pass,
- .probe = smp_beatic_probe,
- .kick_cpu = smp_celleb_kick_cpu,
- .setup_cpu = smp_beatic_setup_cpu,
- .cpu_bootable = smp_celleb_cpu_bootable,
-};
-
-/* This is called very early */
-void __init smp_init_celleb(void)
-{
- DBG(" -> smp_init_celleb()\n");
-
- smp_ops = &bpa_beatic_smp_ops;
-
- DBG(" <- smp_init_celleb()\n");
-}
Index: b/arch/powerpc/platforms/celleb/udbg_beat.c
===================================================================
--- a/arch/powerpc/platforms/celleb/udbg_beat.c 2008-03-04 13:54:19.000000000 +0900
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,98 +0,0 @@
-/*
- * udbg function for Beat
- *
- * (C) Copyright 2006 TOSHIBA 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) 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <linux/kernel.h>
-#include <linux/console.h>
-
-#include <asm/machdep.h>
-#include <asm/prom.h>
-#include <asm/udbg.h>
-
-#include "beat.h"
-
-#define celleb_vtermno 0
-
-static void udbg_putc_beat(char c)
-{
- unsigned long rc;
-
- if (c == '\n')
- udbg_putc_beat('\r');
-
- rc = beat_put_term_char(celleb_vtermno, 1, (uint64_t)c << 56, 0);
-}
-
-/* Buffered chars getc */
-static long inbuflen;
-static long inbuf[2]; /* must be 2 longs */
-
-static int udbg_getc_poll_beat(void)
-{
- /* The interface is tricky because it may return up to 16 chars.
- * We save them statically for future calls to udbg_getc().
- */
- char ch, *buf = (char *)inbuf;
- int i;
- long rc;
- if (inbuflen == 0) {
- /* get some more chars. */
- inbuflen = 0;
- rc = beat_get_term_char(celleb_vtermno, &inbuflen,
- inbuf+0, inbuf+1);
- if (rc != 0)
- inbuflen = 0; /* otherwise inbuflen is garbage */
- }
- if (inbuflen <= 0 || inbuflen > 16) {
- /* Catch error case as well as other oddities (corruption) */
- inbuflen = 0;
- return -1;
- }
- ch = buf[0];
- for (i = 1; i < inbuflen; i++) /* shuffle them down. */
- buf[i-1] = buf[i];
- inbuflen--;
- return ch;
-}
-
-static int udbg_getc_beat(void)
-{
- int ch;
- for (;;) {
- ch = udbg_getc_poll_beat();
- if (ch == -1) {
- /* This shouldn't be needed...but... */
- volatile unsigned long delay;
- for (delay = 0; delay < 2000000; delay++)
- ;
- } else {
- return ch;
- }
- }
-}
-
-/* call this from early_init() for a working debug console on
- * vterm capable LPAR machines
- */
-void __init udbg_init_debug_beat(void)
-{
- udbg_putc = udbg_putc_beat;
- udbg_getc = udbg_getc_beat;
- udbg_getc_poll = udbg_getc_poll_beat;
-}
^ permalink raw reply
* [PATCH 6/11] celleb: move a file for SPU on Beat
From: Ishizaki Kou @ 2008-03-05 8:33 UTC (permalink / raw)
To: paulus; +Cc: linuxppc-dev
This patch moves SPU support code on Beat into platforms/cell/.
Signed-off-by: Kou Ishizaki <kou.ishizaki@toshiba.co.jp>
---
arch/powerpc/platforms/cell/beat_spu_priv1.c | 207 +++++++++++++++++++++++++++
arch/powerpc/platforms/celleb/spu_priv1.c | 207 ---------------------------
2 files changed, 207 insertions(+), 207 deletions(-)
Index: b/arch/powerpc/platforms/cell/beat_spu_priv1.c
===================================================================
--- /dev/null 1970-01-01 00:00:00.000000000 +0000
+++ b/arch/powerpc/platforms/cell/beat_spu_priv1.c 2008-03-04 14:01:03.000000000 +0900
@@ -0,0 +1,207 @@
+/*
+ * spu hypervisor abstraction for Beat
+ *
+ * (C) Copyright 2006-2007 TOSHIBA 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) 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.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <linux/module.h>
+
+#include <asm/types.h>
+#include <asm/spu.h>
+#include <asm/spu_priv1.h>
+
+#include "beat_wrapper.h"
+
+static inline void _int_mask_set(struct spu *spu, int class, u64 mask)
+{
+ spu->shadow_int_mask_RW[class] = mask;
+ beat_set_irq_mask_for_spe(spu->spe_id, class, mask);
+}
+
+static inline u64 _int_mask_get(struct spu *spu, int class)
+{
+ return spu->shadow_int_mask_RW[class];
+}
+
+static void int_mask_set(struct spu *spu, int class, u64 mask)
+{
+ _int_mask_set(spu, class, mask);
+}
+
+static u64 int_mask_get(struct spu *spu, int class)
+{
+ return _int_mask_get(spu, class);
+}
+
+static void int_mask_and(struct spu *spu, int class, u64 mask)
+{
+ u64 old_mask;
+ old_mask = _int_mask_get(spu, class);
+ _int_mask_set(spu, class, old_mask & mask);
+}
+
+static void int_mask_or(struct spu *spu, int class, u64 mask)
+{
+ u64 old_mask;
+ old_mask = _int_mask_get(spu, class);
+ _int_mask_set(spu, class, old_mask | mask);
+}
+
+static void int_stat_clear(struct spu *spu, int class, u64 stat)
+{
+ beat_clear_interrupt_status_of_spe(spu->spe_id, class, stat);
+}
+
+static u64 int_stat_get(struct spu *spu, int class)
+{
+ u64 int_stat;
+ beat_get_interrupt_status_of_spe(spu->spe_id, class, &int_stat);
+ return int_stat;
+}
+
+static void cpu_affinity_set(struct spu *spu, int cpu)
+{
+ return;
+}
+
+static u64 mfc_dar_get(struct spu *spu)
+{
+ u64 dar;
+ beat_get_spe_privileged_state_1_registers(
+ spu->spe_id,
+ offsetof(struct spu_priv1, mfc_dar_RW), &dar);
+ return dar;
+}
+
+static u64 mfc_dsisr_get(struct spu *spu)
+{
+ u64 dsisr;
+ beat_get_spe_privileged_state_1_registers(
+ spu->spe_id,
+ offsetof(struct spu_priv1, mfc_dsisr_RW), &dsisr);
+ return dsisr;
+}
+
+static void mfc_dsisr_set(struct spu *spu, u64 dsisr)
+{
+ beat_set_spe_privileged_state_1_registers(
+ spu->spe_id,
+ offsetof(struct spu_priv1, mfc_dsisr_RW), dsisr);
+}
+
+static void mfc_sdr_setup(struct spu *spu)
+{
+ return;
+}
+
+static void mfc_sr1_set(struct spu *spu, u64 sr1)
+{
+ beat_set_spe_privileged_state_1_registers(
+ spu->spe_id,
+ offsetof(struct spu_priv1, mfc_sr1_RW), sr1);
+}
+
+static u64 mfc_sr1_get(struct spu *spu)
+{
+ u64 sr1;
+ beat_get_spe_privileged_state_1_registers(
+ spu->spe_id,
+ offsetof(struct spu_priv1, mfc_sr1_RW), &sr1);
+ return sr1;
+}
+
+static void mfc_tclass_id_set(struct spu *spu, u64 tclass_id)
+{
+ beat_set_spe_privileged_state_1_registers(
+ spu->spe_id,
+ offsetof(struct spu_priv1, mfc_tclass_id_RW), tclass_id);
+}
+
+static u64 mfc_tclass_id_get(struct spu *spu)
+{
+ u64 tclass_id;
+ beat_get_spe_privileged_state_1_registers(
+ spu->spe_id,
+ offsetof(struct spu_priv1, mfc_tclass_id_RW), &tclass_id);
+ return tclass_id;
+}
+
+static void tlb_invalidate(struct spu *spu)
+{
+ beat_set_spe_privileged_state_1_registers(
+ spu->spe_id,
+ offsetof(struct spu_priv1, tlb_invalidate_entry_W), 0ul);
+}
+
+static void resource_allocation_groupID_set(struct spu *spu, u64 id)
+{
+ beat_set_spe_privileged_state_1_registers(
+ spu->spe_id,
+ offsetof(struct spu_priv1, resource_allocation_groupID_RW),
+ id);
+}
+
+static u64 resource_allocation_groupID_get(struct spu *spu)
+{
+ u64 id;
+ beat_get_spe_privileged_state_1_registers(
+ spu->spe_id,
+ offsetof(struct spu_priv1, resource_allocation_groupID_RW),
+ &id);
+ return id;
+}
+
+static void resource_allocation_enable_set(struct spu *spu, u64 enable)
+{
+ beat_set_spe_privileged_state_1_registers(
+ spu->spe_id,
+ offsetof(struct spu_priv1, resource_allocation_enable_RW),
+ enable);
+}
+
+static u64 resource_allocation_enable_get(struct spu *spu)
+{
+ u64 enable;
+ beat_get_spe_privileged_state_1_registers(
+ spu->spe_id,
+ offsetof(struct spu_priv1, resource_allocation_enable_RW),
+ &enable);
+ return enable;
+}
+
+const struct spu_priv1_ops spu_priv1_beat_ops = {
+ .int_mask_and = int_mask_and,
+ .int_mask_or = int_mask_or,
+ .int_mask_set = int_mask_set,
+ .int_mask_get = int_mask_get,
+ .int_stat_clear = int_stat_clear,
+ .int_stat_get = int_stat_get,
+ .cpu_affinity_set = cpu_affinity_set,
+ .mfc_dar_get = mfc_dar_get,
+ .mfc_dsisr_get = mfc_dsisr_get,
+ .mfc_dsisr_set = mfc_dsisr_set,
+ .mfc_sdr_setup = mfc_sdr_setup,
+ .mfc_sr1_set = mfc_sr1_set,
+ .mfc_sr1_get = mfc_sr1_get,
+ .mfc_tclass_id_set = mfc_tclass_id_set,
+ .mfc_tclass_id_get = mfc_tclass_id_get,
+ .tlb_invalidate = tlb_invalidate,
+ .resource_allocation_groupID_set = resource_allocation_groupID_set,
+ .resource_allocation_groupID_get = resource_allocation_groupID_get,
+ .resource_allocation_enable_set = resource_allocation_enable_set,
+ .resource_allocation_enable_get = resource_allocation_enable_get,
+};
Index: b/arch/powerpc/platforms/celleb/spu_priv1.c
===================================================================
--- a/arch/powerpc/platforms/celleb/spu_priv1.c 2008-03-04 13:54:19.000000000 +0900
+++ /dev/null 1970-01-01 00:00:00.000000000 +0000
@@ -1,207 +0,0 @@
-/*
- * spu hypervisor abstraction for Beat
- *
- * (C) Copyright 2006-2007 TOSHIBA 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) 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.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <linux/module.h>
-
-#include <asm/types.h>
-#include <asm/spu.h>
-#include <asm/spu_priv1.h>
-
-#include "beat_wrapper.h"
-
-static inline void _int_mask_set(struct spu *spu, int class, u64 mask)
-{
- spu->shadow_int_mask_RW[class] = mask;
- beat_set_irq_mask_for_spe(spu->spe_id, class, mask);
-}
-
-static inline u64 _int_mask_get(struct spu *spu, int class)
-{
- return spu->shadow_int_mask_RW[class];
-}
-
-static void int_mask_set(struct spu *spu, int class, u64 mask)
-{
- _int_mask_set(spu, class, mask);
-}
-
-static u64 int_mask_get(struct spu *spu, int class)
-{
- return _int_mask_get(spu, class);
-}
-
-static void int_mask_and(struct spu *spu, int class, u64 mask)
-{
- u64 old_mask;
- old_mask = _int_mask_get(spu, class);
- _int_mask_set(spu, class, old_mask & mask);
-}
-
-static void int_mask_or(struct spu *spu, int class, u64 mask)
-{
- u64 old_mask;
- old_mask = _int_mask_get(spu, class);
- _int_mask_set(spu, class, old_mask | mask);
-}
-
-static void int_stat_clear(struct spu *spu, int class, u64 stat)
-{
- beat_clear_interrupt_status_of_spe(spu->spe_id, class, stat);
-}
-
-static u64 int_stat_get(struct spu *spu, int class)
-{
- u64 int_stat;
- beat_get_interrupt_status_of_spe(spu->spe_id, class, &int_stat);
- return int_stat;
-}
-
-static void cpu_affinity_set(struct spu *spu, int cpu)
-{
- return;
-}
-
-static u64 mfc_dar_get(struct spu *spu)
-{
- u64 dar;
- beat_get_spe_privileged_state_1_registers(
- spu->spe_id,
- offsetof(struct spu_priv1, mfc_dar_RW), &dar);
- return dar;
-}
-
-static u64 mfc_dsisr_get(struct spu *spu)
-{
- u64 dsisr;
- beat_get_spe_privileged_state_1_registers(
- spu->spe_id,
- offsetof(struct spu_priv1, mfc_dsisr_RW), &dsisr);
- return dsisr;
-}
-
-static void mfc_dsisr_set(struct spu *spu, u64 dsisr)
-{
- beat_set_spe_privileged_state_1_registers(
- spu->spe_id,
- offsetof(struct spu_priv1, mfc_dsisr_RW), dsisr);
-}
-
-static void mfc_sdr_setup(struct spu *spu)
-{
- return;
-}
-
-static void mfc_sr1_set(struct spu *spu, u64 sr1)
-{
- beat_set_spe_privileged_state_1_registers(
- spu->spe_id,
- offsetof(struct spu_priv1, mfc_sr1_RW), sr1);
-}
-
-static u64 mfc_sr1_get(struct spu *spu)
-{
- u64 sr1;
- beat_get_spe_privileged_state_1_registers(
- spu->spe_id,
- offsetof(struct spu_priv1, mfc_sr1_RW), &sr1);
- return sr1;
-}
-
-static void mfc_tclass_id_set(struct spu *spu, u64 tclass_id)
-{
- beat_set_spe_privileged_state_1_registers(
- spu->spe_id,
- offsetof(struct spu_priv1, mfc_tclass_id_RW), tclass_id);
-}
-
-static u64 mfc_tclass_id_get(struct spu *spu)
-{
- u64 tclass_id;
- beat_get_spe_privileged_state_1_registers(
- spu->spe_id,
- offsetof(struct spu_priv1, mfc_tclass_id_RW), &tclass_id);
- return tclass_id;
-}
-
-static void tlb_invalidate(struct spu *spu)
-{
- beat_set_spe_privileged_state_1_registers(
- spu->spe_id,
- offsetof(struct spu_priv1, tlb_invalidate_entry_W), 0ul);
-}
-
-static void resource_allocation_groupID_set(struct spu *spu, u64 id)
-{
- beat_set_spe_privileged_state_1_registers(
- spu->spe_id,
- offsetof(struct spu_priv1, resource_allocation_groupID_RW),
- id);
-}
-
-static u64 resource_allocation_groupID_get(struct spu *spu)
-{
- u64 id;
- beat_get_spe_privileged_state_1_registers(
- spu->spe_id,
- offsetof(struct spu_priv1, resource_allocation_groupID_RW),
- &id);
- return id;
-}
-
-static void resource_allocation_enable_set(struct spu *spu, u64 enable)
-{
- beat_set_spe_privileged_state_1_registers(
- spu->spe_id,
- offsetof(struct spu_priv1, resource_allocation_enable_RW),
- enable);
-}
-
-static u64 resource_allocation_enable_get(struct spu *spu)
-{
- u64 enable;
- beat_get_spe_privileged_state_1_registers(
- spu->spe_id,
- offsetof(struct spu_priv1, resource_allocation_enable_RW),
- &enable);
- return enable;
-}
-
-const struct spu_priv1_ops spu_priv1_beat_ops = {
- .int_mask_and = int_mask_and,
- .int_mask_or = int_mask_or,
- .int_mask_set = int_mask_set,
- .int_mask_get = int_mask_get,
- .int_stat_clear = int_stat_clear,
- .int_stat_get = int_stat_get,
- .cpu_affinity_set = cpu_affinity_set,
- .mfc_dar_get = mfc_dar_get,
- .mfc_dsisr_get = mfc_dsisr_get,
- .mfc_dsisr_set = mfc_dsisr_set,
- .mfc_sdr_setup = mfc_sdr_setup,
- .mfc_sr1_set = mfc_sr1_set,
- .mfc_sr1_get = mfc_sr1_get,
- .mfc_tclass_id_set = mfc_tclass_id_set,
- .mfc_tclass_id_get = mfc_tclass_id_get,
- .tlb_invalidate = tlb_invalidate,
- .resource_allocation_groupID_set = resource_allocation_groupID_set,
- .resource_allocation_groupID_get = resource_allocation_groupID_get,
- .resource_allocation_enable_set = resource_allocation_enable_set,
- .resource_allocation_enable_get = resource_allocation_enable_get,
-};
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox