* Re: [U-Boot-Users] Help required to bring up kernel from U-Boot
From: batsayan.das @ 2005-12-16 10:49 UTC (permalink / raw)
To: Wolfgang Denk; +Cc: linuxppc-embedded
In-Reply-To: <20051216101101.7B82B353416@atlas.denx.de>
[-- Attachment #1: Type: text/plain, Size: 2954 bytes --]
1. Doing the changes in Linux tree suggested in
http://www.denx.de/wiki/view/DULG/LinuxHangsAfterUncompressingKernel
yields the same result. We already did those changes.
2. Here is the procedure how I got the o/p of printk even if I do not get
anything at console.
Run u-boot from Trace32
bootm <addr> // Now in our case Linux hangs after giving the o/p "##
Transferring control to Linux (at address 00000000) ..."
stop u-boot //Do not hard reset the target
Again run U-Boot from Trace32
md <addrss of log_buf> // search for "log_buf" in System.map in Linux
tree. You will get this address.
Batsayan Das
Tata Consultancy Services Limited
Mailto: batsayan.das@tcs.com
Website: http://www.tcs.com
Wolfgang Denk <wd@denx.de>
Sent by: wd@denx.de
12/16/2005 03:41 PM
To
batsayan.das@tcs.com
cc
u-boot-users@lists.sourceforge.net, linuxppc-embedded@ozlabs.org
Subject
Re: [U-Boot-Users] Help required to bring up kernel from U-Boot
In message
<OFB8CF31AB.E132BC0B-ON652570D9.001789DD-652570D9.001A8A99@tcs.com> you
wrote:
>
> I copied uImage to location 0x04000000 and the Load Address=0x00000000
> and Entry point=0x00000000. The bootm 0x04000000 gives the o/p
> "Transferring Control to Linux" and then nothing comes. Where is the
> wrong?
This is a FAQ. Please see http://www.denx.de/wiki/DULG/Faq
> 1. What are the minimum information Linux needs from U-Boot to come up
> properly? In the Linux source tree we have put some printk statement
and
> found that base address of SDRAM, size, etc are passed correctly to
Linux
> by U-Boot.
Be careful with printk() at inappropieate places (i.e. too early).
But tell me - how where you able to see anthing with printk if
"nothing comes" as you write above ???
> 2. Is the info passed from U-Boot is sufficient enough to make the
kernel
> up?
Yes, of course. It works on thousands of systems.
> 3. If not, where should I concentrate in Linux tree?
On your changes.
And please keep this off the U-Boot list. It is off topic here.
Best regards,
Wolfgang Denk
--
Software Engineering: Embedded and Realtime Systems, Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
CONSUMER NOTICE: Because of the "Uncertainty Principle," It Is
Impossible for the Consumer to Find Out at the Same Time Both
Precisely Where This Product Is and How Fast It Is Moving.
ForwardSourceID:NT000081B2
Notice: The information contained in this e-mail message and/or attachments to it may contain confidential or privileged information. If you are not the intended recipient, any dissemination, use, review, distribution, printing or copying of the information contained in this e-mail message and/or attachments to it are strictly prohibited. If you have received this communication in error, please notify us by reply e-mail or telephone and immediately and permanently delete the message and any attachments. Thank you
[-- Attachment #2: Type: text/html, Size: 4580 bytes --]
^ permalink raw reply
* MPC5200 TXRTS feature
From: Stefan Eletzhofer @ 2005-12-16 11:16 UTC (permalink / raw)
To: ML linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 765 bytes --]
Hi,
has anyone got the "TXRTS" feature working on the Freescale MPC5200? I
need that to use PSC6 for RS485.
I've tried some hints I found in a thread starting here:
http://article.gmane.org/gmane.comp.hardware.motorola.microcontrollers.coldfire/6225
but no luck, so far.
I got it working by manually asserting and negating RTS through OP1/OP0,
and waiting for the TX_FIFO_EMPTY bit, but I really want to use the
TXRTS feature, which _should_ deassert RTS automatically one bit-time
after the last bit is shifted out.
Thanks,
Stefan E.
--
Stefan Eletzhofer
InQuant GmbH
Bahnhofstraße 11
D-88214 Ravensburg
http://www.inquant.de
http://www.eletztrick.de
+49 (0) 751 35 44 112
+49 (0) 171 23 24 529 (Mobil)
+49 (0) 751 35 44 115 (FAX)
[-- Attachment #2: Dies ist ein digital signierter Nachrichtenteil --]
[-- Type: application/pgp-signature, Size: 189 bytes --]
^ permalink raw reply
* Re: MPC5200 ppc_md.set_rtc_time
From: Andrey Volkov @ 2005-12-16 10:42 UTC (permalink / raw)
To: ML linuxppc-embedded
In-Reply-To: <43A2071A.3030802@digis.net>
Hello Frank,
bennett78 wrote:
> Hi:
> How / when does "ppc_md.set_rtc_time" get filled
> in for Lite5200?
>
> Config for support /dev/rtc enables CONFIG_PPC_RTC
> which enable driver/char/rtc.c which mentions CMOS_WRITE
> panics the kernel!
>
> I trying to use driver/char/genrtc.c. I can set date
> but not hwclock.
>
>> hwclock --set --date="9/22/96 16:45:05"
> gen_set_rtc_irq_bit:exit
> gen_rtc_ioctl RTC_SET_TIME 00000060
> RTC_SET_TIME: Invalid argument
> ioctl() to /dev/rtc to set the time failed.
>
> bash-2.05b# cat /proc/driver/rtc
> rtc_time : 00:50339648:36914
> rtc_date : -1072186980-497--1073718072
> rtc_epoch : 1900
> alarm : 00:00:00
> DST_enable : no
> BCD : yes
> 24hr : yes
> square_wave : no
> alarm_IRQ : no
> update_IRQ : no <----- how can I hook one?
> periodic_IRQ : no
> periodic_freq : 0
> batt_status : okay
>
>
> thanks,
>
> */Frank Bennett
> /*
For 2.6 kernel, check arch/ppc/syslib/lite5200.c, especially
platform_init() (at the end of file).
--
Regards
Andrey Volkov
^ permalink raw reply
* Re: [U-Boot-Users] Help required to bring up kernel from U-Boot
From: Wolfgang Denk @ 2005-12-16 10:11 UTC (permalink / raw)
To: batsayan.das; +Cc: u-boot-users, linuxppc-embedded
In-Reply-To: <OFB8CF31AB.E132BC0B-ON652570D9.001789DD-652570D9.001A8A99@tcs.com>
In message <OFB8CF31AB.E132BC0B-ON652570D9.001789DD-652570D9.001A8A99@tcs.com> you wrote:
>
> I copied uImage to location 0x04000000 and the Load Address=0x00000000
> and Entry point=0x00000000. The bootm 0x04000000 gives the o/p
> "Transferring Control to Linux" and then nothing comes. Where is the
> wrong?
This is a FAQ. Please see http://www.denx.de/wiki/DULG/Faq
> 1. What are the minimum information Linux needs from U-Boot to come up
> properly? In the Linux source tree we have put some printk statement and
> found that base address of SDRAM, size, etc are passed correctly to Linux
> by U-Boot.
Be careful with printk() at inappropieate places (i.e. too early).
But tell me - how where you able to see anthing with printk if
"nothing comes" as you write above ???
> 2. Is the info passed from U-Boot is sufficient enough to make the kernel
> up?
Yes, of course. It works on thousands of systems.
> 3. If not, where should I concentrate in Linux tree?
On your changes.
And please keep this off the U-Boot list. It is off topic here.
Best regards,
Wolfgang Denk
--
Software Engineering: Embedded and Realtime Systems, Embedded Linux
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
CONSUMER NOTICE: Because of the "Uncertainty Principle," It Is
Impossible for the Consumer to Find Out at the Same Time Both
Precisely Where This Product Is and How Fast It Is Moving.
^ permalink raw reply
* Powermac real-mode? setting?
From: Andrei Warkentin @ 2005-12-16 8:53 UTC (permalink / raw)
To: linuxppc-dev
Hello,
As far as I understand, linux expects to be started in virt-mode,
with MMU on. Does anyone know if setting real-mode? to true will
work correctly? I'm trying to get something in the way of a home-brew
kernel going on an G4 OF 3.0-based machine, and was wondering if it
was possible to start out with the MMU off.
Thank you very much and have a nice day.
Andrei Warkentin
andrey.warkentin@gmail.com
Cell: (+1) (847) 321-15-55
Office: (+1) (312) 756-15-00 x614
^ permalink raw reply
* Typo in arch/ppc/kernel/head.S?
From: Andrei Warkentin @ 2005-12-16 7:35 UTC (permalink / raw)
To: linuxppc-dev
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
Hello,
I was looking at head.S under arch/ppc/kernel and it seems the
comment above ".globl __start" is slightly off. Under
the PMAC section it mentions that .text/.data/.bss are loaded @ 0x0,
while they could be pretty much loaded anywhere but 0x0, with OF
exception vectors being there. Am I understanding this correctly?
Thanks and have a good day.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (Darwin)
iD8DBQFDom5cY/rXIPQviuERAslLAJ47nV8Qo+UlzulU0VxuBdIdqEX4bQCeKB/e
ix1RS2t/M0tbqrO/3qZqDEA=
=RlQu
-----END PGP SIGNATURE-----
^ permalink raw reply
* help reqd for mpc8260 linux
From: prabha.j @ 2005-12-16 4:44 UTC (permalink / raw)
To: linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 1771 bytes --]
Hi All,
I working on custom board(mpc8260) . Now the bootlader is working and when
i dowload the kernel image through u-boot it gives messages as
"Transferring Conrol to Linux" and then nothing comes. I am using
Linux-2.4.25 and eldk toolkit ,both from denx.
My boards memory map is SDRAM starts from 0 and flash starts from
0x30000000. and baudrate is 57600 and IMMR is 0xF000000 .
When i was debugging in
start_here(arch/ppc/kernel/head.S)
It is passing the machine_init and MMU_init functions (This i have seen
by putting printk and seeing it in log_buf) and then in this code
lis r4,2f@h
ori r4,r4,2f@l
tophys(r4,r4)
li r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
FIX_SRR1(r3,r5)
mtspr SRR0,r4
mtspr SRR1,r3
SYNC
bl MMU_init_prabha //(This is just a printk function).Till
here its working.
RFI
If i put the printk after this funtion i am not getting anything in the
log_buf. I simply commented the RFI instruction then also i didn't see any
messages.
Can anybody tell me what may be the problem.
Waiting for reply.
Thanks in advance.
Best Regards
Prabha J.
Tata Consultancy Services Limited
Mailto: prabha.j@tcs.com
Website: http://www.tcs.com
Notice: The information contained in this e-mail message and/or attachments to it may contain confidential or privileged information. If you are not the intended recipient, any dissemination, use, review, distribution, printing or copying of the information contained in this e-mail message and/or attachments to it are strictly prohibited. If you have received this communication in error, please notify us by reply e-mail or telephone and immediately and permanently delete the message and any attachments. Thank you
[-- Attachment #2: Type: text/html, Size: 3106 bytes --]
^ permalink raw reply
* Help required to bring up kernel from U-Boot
From: batsayan.das @ 2005-12-16 4:49 UTC (permalink / raw)
To: u-boot-users; +Cc: linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 1916 bytes --]
Hello,
I am using MPC8260ADS based customs board. I have configured the memory
map in U-Boot as follows
SDRAM : 0x00000000 (size=128 MB)
FLASH : 0x30000000 (size= 1MB)
SRAM : 0xFFF00000 (size 4MB)
There are also other components in the board, like FRAMER , DSP, etc. I
have not initialized the memory map of those components in U-Boot.
I am able to get the U-Boot prompt when run by TRACE23. I have build a
default MPC8260ADS kernel, the only changes I have made is in the variable
IMAP_ADDR , BCSR_ADDR in arch/ppc/platforms/ads8260.h. I have put those
values from the already running U-Boot code.
Our TEXT_BASE=0xFFF00000
HRCW value= "0E A2 82 05"
I copied uImage to location 0x04000000 and the Load Address=0x00000000
and Entry point=0x00000000. The bootm 0x04000000 gives the o/p
"Transferring Control to Linux" and then nothing comes. Where is the
wrong?
My question is
1. What are the minimum information Linux needs from U-Boot to come up
properly? In the Linux source tree we have put some printk statement and
found that base address of SDRAM, size, etc are passed correctly to Linux
by U-Boot.
2. Is the info passed from U-Boot is sufficient enough to make the kernel
up?
3. If not, where should I concentrate in Linux tree?
Pls help.
Thanks,
Batsayan Das
Tata Consultancy Services Limited
Mailto: batsayan.das@tcs.com
Website: http://www.tcs.com
Notice: The information contained in this e-mail message and/or attachments to it may contain confidential or privileged information. If you are not the intended recipient, any dissemination, use, review, distribution, printing or copying of the information contained in this e-mail message and/or attachments to it are strictly prohibited. If you have received this communication in error, please notify us by reply e-mail or telephone and immediately and permanently delete the message and any attachments. Thank you
[-- Attachment #2: Type: text/html, Size: 2827 bytes --]
^ permalink raw reply
* Re: [PATCH] G4+ oprofile support
From: Kumar Gala @ 2005-12-16 3:42 UTC (permalink / raw)
To: Andy Fleming; +Cc: linuxppc-dev
In-Reply-To: <Pine.LNX.4.61.0512151953550.14329@ld0175-tx32.am.freescale.net>
On Dec 15, 2005, at 8:02 PM, Andy Fleming wrote:
> This patch adds oprofile support for the 7450 and all its
> multitudinous
> derivatives.
>
> Signed-off-by: Andy Fleming <afleming@freescale.com>
>
>
> * Added 7450 (and derivatives) support for oprofile
> * Changed e500 cputable to have oprofile model and cpu_type fields
> * Added support for classic 32-bit performance monitor interrupt
> * Cleaned up common powerpc oprofile code to be as common as possible
> * Cleaned up oprofile_impl.h to reflect 32 bit classic code
> * Added 32-bit MMCRx bitfield definitions and SPR numbers
>
> ---
> commit 44e22e7c3358c79517685e7b66ffae17da6f8399
> tree 2f8ee433f01d70e176b074af50fa0bca384699b8
> parent 49d7bc64283970ee83d2c954d04ba00d04e5943d
> author Andrew Fleming <afleming@freescale.com> Thu, 15 Dec 2005
> 15:36:31 -0600
> committer Andrew Fleming <afleming@ld0175-tx32.(none)> Thu, 15 Dec
> 2005 15:36:31 -0600
>
> arch/powerpc/kernel/cputable.c | 74 ++++++++++--
> arch/powerpc/kernel/head_32.S | 12 +-
> arch/powerpc/kernel/pmc.c | 5 +
> arch/powerpc/kernel/traps.c | 2
> arch/powerpc/oprofile/Makefile | 1
> arch/powerpc/oprofile/common.c | 61 ++--------
> arch/powerpc/oprofile/op_model_7450.c | 206 ++++++++++++++++++++++
> +++++++++++
> include/asm-powerpc/oprofile_impl.h | 31 ++++-
> include/asm-powerpc/reg.h | 36 +++++-
> 9 files changed, 344 insertions(+), 84 deletions(-)
>
> diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/
> cputable.c
> index 1d85ced..f7f2a83 100644
> --- a/arch/powerpc/kernel/cputable.c
> +++ b/arch/powerpc/kernel/cputable.c
> @@ -545,7 +545,11 @@ struct cpu_spec cpu_specs[] = {
> .icache_bsize = 32,
> .dcache_bsize = 32,
> .num_pmcs = 6,
> - .cpu_setup = __setup_cpu_745x
> + .cpu_setup = __setup_cpu_745x,
> +#ifdef CONFIG_OPROFILE
> + .oprofile_cpu_type = "ppc/7450",
> + .oprofile_model = &op_model_7450,
> +#endif
> },
> { /* 7450 2.1 */
> .pvr_mask = 0xffffffff,
> @@ -556,7 +560,11 @@ struct cpu_spec cpu_specs[] = {
> .icache_bsize = 32,
> .dcache_bsize = 32,
> .num_pmcs = 6,
> - .cpu_setup = __setup_cpu_745x
> + .cpu_setup = __setup_cpu_745x,
> +#ifdef CONFIG_OPROFILE
> + .oprofile_cpu_type = "ppc/7450",
> + .oprofile_model = &op_model_7450,
> +#endif
> },
> { /* 7450 2.3 and newer */
> .pvr_mask = 0xffff0000,
> @@ -567,7 +575,11 @@ struct cpu_spec cpu_specs[] = {
> .icache_bsize = 32,
> .dcache_bsize = 32,
> .num_pmcs = 6,
> - .cpu_setup = __setup_cpu_745x
> + .cpu_setup = __setup_cpu_745x,
> +#ifdef CONFIG_OPROFILE
> + .oprofile_cpu_type = "ppc/7450",
> + .oprofile_model = &op_model_7450,
> +#endif
> },
> { /* 7455 rev 1.x */
> .pvr_mask = 0xffffff00,
> @@ -578,7 +590,11 @@ struct cpu_spec cpu_specs[] = {
> .icache_bsize = 32,
> .dcache_bsize = 32,
> .num_pmcs = 6,
> - .cpu_setup = __setup_cpu_745x
> + .cpu_setup = __setup_cpu_745x,
> +#ifdef CONFIG_OPROFILE
> + .oprofile_cpu_type = "ppc/7450",
> + .oprofile_model = &op_model_7450,
> +#endif
> },
> { /* 7455 rev 2.0 */
> .pvr_mask = 0xffffffff,
> @@ -589,7 +605,11 @@ struct cpu_spec cpu_specs[] = {
> .icache_bsize = 32,
> .dcache_bsize = 32,
> .num_pmcs = 6,
> - .cpu_setup = __setup_cpu_745x
> + .cpu_setup = __setup_cpu_745x,
> +#ifdef CONFIG_OPROFILE
> + .oprofile_cpu_type = "ppc/7450",
> + .oprofile_model = &op_model_7450,
> +#endif
> },
> { /* 7455 others */
> .pvr_mask = 0xffff0000,
> @@ -600,7 +620,11 @@ struct cpu_spec cpu_specs[] = {
> .icache_bsize = 32,
> .dcache_bsize = 32,
> .num_pmcs = 6,
> - .cpu_setup = __setup_cpu_745x
> + .cpu_setup = __setup_cpu_745x,
> +#ifdef CONFIG_OPROFILE
> + .oprofile_cpu_type = "ppc/7450",
> + .oprofile_model = &op_model_7450,
> +#endif
> },
> { /* 7447/7457 Rev 1.0 */
> .pvr_mask = 0xffffffff,
> @@ -611,7 +635,11 @@ struct cpu_spec cpu_specs[] = {
> .icache_bsize = 32,
> .dcache_bsize = 32,
> .num_pmcs = 6,
> - .cpu_setup = __setup_cpu_745x
> + .cpu_setup = __setup_cpu_745x,
> +#ifdef CONFIG_OPROFILE
> + .oprofile_cpu_type = "ppc/7450",
> + .oprofile_model = &op_model_7450,
> +#endif
> },
> { /* 7447/7457 Rev 1.1 */
> .pvr_mask = 0xffffffff,
> @@ -622,7 +650,11 @@ struct cpu_spec cpu_specs[] = {
> .icache_bsize = 32,
> .dcache_bsize = 32,
> .num_pmcs = 6,
> - .cpu_setup = __setup_cpu_745x
> + .cpu_setup = __setup_cpu_745x,
> +#ifdef CONFIG_OPROFILE
> + .oprofile_cpu_type = "ppc/7450",
> + .oprofile_model = &op_model_7450,
> +#endif
> },
> { /* 7447/7457 Rev 1.2 and later */
> .pvr_mask = 0xffff0000,
> @@ -633,7 +665,11 @@ struct cpu_spec cpu_specs[] = {
> .icache_bsize = 32,
> .dcache_bsize = 32,
> .num_pmcs = 6,
> - .cpu_setup = __setup_cpu_745x
> + .cpu_setup = __setup_cpu_745x,
> +#ifdef CONFIG_OPROFILE
> + .oprofile_cpu_type = "ppc/7450",
> + .oprofile_model = &op_model_7450,
> +#endif
> },
> { /* 7447A */
> .pvr_mask = 0xffff0000,
> @@ -644,7 +680,11 @@ struct cpu_spec cpu_specs[] = {
> .icache_bsize = 32,
> .dcache_bsize = 32,
> .num_pmcs = 6,
> - .cpu_setup = __setup_cpu_745x
> + .cpu_setup = __setup_cpu_745x,
> +#ifdef CONFIG_OPROFILE
> + .oprofile_cpu_type = "ppc/7450",
> + .oprofile_model = &op_model_7450,
> +#endif
> },
> { /* 7448 */
> .pvr_mask = 0xffff0000,
> @@ -655,7 +695,11 @@ struct cpu_spec cpu_specs[] = {
> .icache_bsize = 32,
> .dcache_bsize = 32,
> .num_pmcs = 6,
> - .cpu_setup = __setup_cpu_745x
> + .cpu_setup = __setup_cpu_745x,
> +#ifdef CONFIG_OPROFILE
> + .oprofile_cpu_type = "ppc/7450",
> + .oprofile_model = &op_model_7450,
> +#endif
> },
> { /* 82xx (8240, 8245, 8260 are all 603e cores) */
> .pvr_mask = 0x7fff0000,
> @@ -979,6 +1023,10 @@ struct cpu_spec cpu_specs[] = {
> .icache_bsize = 32,
> .dcache_bsize = 32,
> .num_pmcs = 4,
> +#ifdef CONFIG_OPROFILE
> + .oprofile_cpu_type = "ppc/e500",
> + .oprofile_model = &op_model_fsl_booke,
> +#endif
> },
> { /* e500v2 */
> .pvr_mask = 0xffff0000,
> @@ -992,6 +1040,10 @@ struct cpu_spec cpu_specs[] = {
> .icache_bsize = 32,
> .dcache_bsize = 32,
> .num_pmcs = 4,
> +#ifdef CONFIG_OPROFILE
> + .oprofile_cpu_type = "ppc/e500",
> + .oprofile_model = &op_model_fsl_booke,
> +#endif
> },
> #endif
> #if !CLASSIC_PPC
> diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/
> head_32.S
> index ccdf947..34ff064 100644
> --- a/arch/powerpc/kernel/head_32.S
> +++ b/arch/powerpc/kernel/head_32.S
> @@ -450,16 +450,11 @@ SystemCall:
> * by executing an altivec instruction.
> */
> . = 0xf00
> - b Trap_0f
> + b PerformanceMonitor
>
> . = 0xf20
> b AltiVecUnavailable
>
> -Trap_0f:
> - EXCEPTION_PROLOG
> - addi r3,r1,STACK_FRAME_OVERHEAD
> - EXC_XFER_EE(0xf00, unknown_exception)
> -
> /*
> * Handle TLB miss for instruction on 603/603e.
> * Note: we get an alternate set of r0 - r3 to use automatically.
> @@ -703,6 +698,11 @@ AltiVecUnavailable:
> #endif /* CONFIG_ALTIVEC */
> EXC_XFER_EE_LITE(0xf20, altivec_unavailable_exception)
>
> +PerformanceMonitor:
> + EXCEPTION_PROLOG
> + addi r3,r1,STACK_FRAME_OVERHEAD
> + EXC_XFER_STD(0xf00, performance_monitor_exception)
> +
> #ifdef CONFIG_ALTIVEC
> /* Note that the AltiVec support is closely modeled after the FP
> * support. Changes to one are likely to be applicable to the
> diff --git a/arch/powerpc/kernel/pmc.c b/arch/powerpc/kernel/pmc.c
> index 2d333cc..e6fb194 100644
> --- a/arch/powerpc/kernel/pmc.c
> +++ b/arch/powerpc/kernel/pmc.c
> @@ -43,8 +43,13 @@ static void dummy_perf(struct pt_regs *r
> mtspr(SPRN_MMCR0, mmcr0);
> }
> #else
> +/* Ensure exceptions are disabled */
> static void dummy_perf(struct pt_regs *regs)
> {
> + unsigned int mmcr0 = mfspr(SPRN_MMCR0);
> +
> + mmcr0 &= ~(MMCR0_PMXE);
> + mtspr(SPRN_MMCR0, mmcr0);
> }
> #endif
>
> diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
> index 1511454..8c91369 100644
> --- a/arch/powerpc/kernel/traps.c
> +++ b/arch/powerpc/kernel/traps.c
> @@ -886,12 +886,10 @@ void altivec_unavailable_exception(struc
> die("Unrecoverable VMX/Altivec Unavailable Exception", regs,
> SIGABRT);
> }
>
> -#if defined(CONFIG_PPC64) || defined(CONFIG_E500)
> void performance_monitor_exception(struct pt_regs *regs)
> {
> perf_irq(regs);
> }
> -#endif
>
> #ifdef CONFIG_8xx
> void SoftwareEmulation(struct pt_regs *regs)
> diff --git a/arch/powerpc/oprofile/Makefile b/arch/powerpc/oprofile/
> Makefile
> index 0782d0c..554cd7c 100644
> --- a/arch/powerpc/oprofile/Makefile
> +++ b/arch/powerpc/oprofile/Makefile
> @@ -9,3 +9,4 @@ DRIVER_OBJS := $(addprefix ../../../driv
> oprofile-y := $(DRIVER_OBJS) common.o
> oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o
> oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o
> +oprofile-$(CONFIG_PPC32) += op_model_7450.o
> diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/
> common.c
> index af2c05d..a370778 100644
> --- a/arch/powerpc/oprofile/common.c
> +++ b/arch/powerpc/oprofile/common.c
> @@ -14,9 +14,6 @@
> */
>
> #include <linux/oprofile.h>
> -#ifndef __powerpc64__
> -#include <linux/slab.h>
> -#endif /* ! __powerpc64__ */
> #include <linux/init.h>
> #include <linux/smp.h>
> #include <linux/errno.h>
> @@ -31,10 +28,6 @@ static struct op_powerpc_model *model;
> static struct op_counter_config ctr[OP_MAX_COUNTER];
> static struct op_system_config sys;
>
> -#ifndef __powerpc64__
> -static char *cpu_type;
> -#endif /* ! __powerpc64__ */
> -
> static void op_handle_interrupt(struct pt_regs *regs)
> {
> model->handle_interrupt(regs, ctr);
> @@ -53,14 +46,7 @@ static int op_powerpc_setup(void)
> model->reg_setup(ctr, &sys, model->num_counters);
>
> /* Configure the registers on all cpus. */
> -#ifdef __powerpc64__
> on_each_cpu(model->cpu_setup, NULL, 0, 1);
> -#else /* __powerpc64__ */
> -#if 0
> - /* FIXME: Make multi-cpu work */
> - on_each_cpu(model->reg_setup, NULL, 0, 1);
> -#endif
> -#endif /* __powerpc64__ */
>
> return 0;
> }
> @@ -95,7 +81,7 @@ static int op_powerpc_create_files(struc
> {
> int i;
>
> -#ifdef __powerpc64__
> +#ifdef CONFIG_PPC64
> /*
> * There is one mmcr0, mmcr1 and mmcra for setting the events for
> * all of the counters.
> @@ -103,7 +89,7 @@ static int op_powerpc_create_files(struc
> oprofilefs_create_ulong(sb, root, "mmcr0", &sys.mmcr0);
> oprofilefs_create_ulong(sb, root, "mmcr1", &sys.mmcr1);
> oprofilefs_create_ulong(sb, root, "mmcra", &sys.mmcra);
> -#endif /* __powerpc64__ */
> +#endif
>
> for (i = 0; i < model->num_counters; ++i) {
> struct dentry *dir;
> @@ -115,65 +101,46 @@ static int op_powerpc_create_files(struc
> oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
> oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
> oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
> -#ifdef __powerpc64__
> +
> /*
> - * We dont support per counter user/kernel selection, but
> - * we leave the entries because userspace expects them
> + * Classic PowerPC doesn't support per-counter
> + * control like this, but the options are
> + * expected, so they remain. For Freescale
> + * Book-E style performance monitors, we do
> + * support them.
> */
> -#endif /* __powerpc64__ */
> oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
> oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
>
> -#ifndef __powerpc64__
> - /* FIXME: Not sure if this is used */
> -#endif /* ! __powerpc64__ */
> oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
> }
>
> oprofilefs_create_ulong(sb, root, "enable_kernel",
> &sys.enable_kernel);
> oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user);
> -#ifdef __powerpc64__
> +#ifdef CONFIG_PPC64
> oprofilefs_create_ulong(sb, root, "backtrace_spinlocks",
> &sys.backtrace_spinlocks);
> -#endif /* __powerpc64__ */
> +#endif
>
> /* Default to tracing both kernel and user */
> sys.enable_kernel = 1;
> sys.enable_user = 1;
> -#ifdef __powerpc64__
> +#ifdef CONFIG_PPC64
> /* Turn on backtracing through spinlocks by default */
> sys.backtrace_spinlocks = 1;
> -#endif /* __powerpc64__ */
> +#endif
>
> return 0;
> }
>
> int __init oprofile_arch_init(struct oprofile_operations *ops)
> {
> -#ifndef __powerpc64__
> -#ifdef CONFIG_FSL_BOOKE
> - model = &op_model_fsl_booke;
> -#else
> - return -ENODEV;
> -#endif
> -
> - cpu_type = kmalloc(32, GFP_KERNEL);
> - if (NULL == cpu_type)
> - return -ENOMEM;
> -
> - sprintf(cpu_type, "ppc/%s", cur_cpu_spec->cpu_name);
> -
> - model->num_counters = cur_cpu_spec->num_pmcs;
> -
> - ops->cpu_type = cpu_type;
> -#else /* __powerpc64__ */
> if (!cur_cpu_spec->oprofile_model || !cur_cpu_spec-
> >oprofile_cpu_type)
> return -ENODEV;
> model = cur_cpu_spec->oprofile_model;
> model->num_counters = cur_cpu_spec->num_pmcs;
>
> ops->cpu_type = cur_cpu_spec->oprofile_cpu_type;
> -#endif /* __powerpc64__ */
> ops->create_files = op_powerpc_create_files;
> ops->setup = op_powerpc_setup;
> ops->shutdown = op_powerpc_shutdown;
> @@ -188,8 +155,4 @@ int __init oprofile_arch_init(struct opr
>
> void oprofile_arch_exit(void)
> {
> -#ifndef __powerpc64__
> - kfree(cpu_type);
> - cpu_type = NULL;
> -#endif /* ! __powerpc64__ */
> }
> diff --git a/arch/powerpc/oprofile/op_model_7450.c b/arch/powerpc/
> oprofile/op_model_7450.c
> new file mode 100644
> index 0000000..32abfdb
> --- /dev/null
> +++ b/arch/powerpc/oprofile/op_model_7450.c
> @@ -0,0 +1,206 @@
> +/*
> + * oprofile/op_model_7450.c
> + *
> + * Freescale 745x/744x oprofile support, based on fsl_booke support
> + * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
> + *
> + * Copyright (c) 2004 Freescale Semiconductor, Inc
> + *
> + * Author: Andy Fleming
> + * Maintainer: Kumar Gala <galak@kernel.crashing.org>
> + *
> + * This program is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License
> + * as published by the Free Software Foundation; either version
> + * 2 of the License, or (at your option) any later version.
> + */
> +
> +#include <linux/oprofile.h>
> +#include <linux/init.h>
> +#include <linux/smp.h>
> +#include <asm/ptrace.h>
> +#include <asm/system.h>
> +#include <asm/processor.h>
> +#include <asm/cputable.h>
> +#include <asm/page.h>
> +#include <asm/pmc.h>
> +#include <asm/oprofile_impl.h>
> +
> +static unsigned long reset_value[OP_MAX_COUNTER];
> +
> +static int oprofile_running;
> +static u32 mmcr0_val, mmcr1_val, mmcr2_val;
> +
> +#define MMCR0_PMC1_SHIFT 6
> +#define MMCR0_PMC2_SHIFT 0
> +#define MMCR1_PMC3_SHIFT 27
> +#define MMCR1_PMC4_SHIFT 22
> +#define MMCR1_PMC5_SHIFT 17
> +#define MMCR1_PMC6_SHIFT 11
> +
> +#define mmcr0_event1(event) \
> + ((event << MMCR0_PMC1_SHIFT) & MMCR0_PMC1SEL)
> +#define mmcr0_event2(event) \
> + ((event << MMCR0_PMC2_SHIFT) & MMCR0_PMC2SEL)
> +
> +#define mmcr1_event3(event) \
> + ((event << MMCR1_PMC3_SHIFT) & MMCR1_PMC3SEL)
> +#define mmcr1_event4(event) \
> + ((event << MMCR1_PMC4_SHIFT) & MMCR1_PMC4SEL)
> +#define mmcr1_event5(event) \
> + ((event << MMCR1_PMC5_SHIFT) & MMCR1_PMC5SEL)
> +#define mmcr1_event6(event) \
> + ((event << MMCR1_PMC6_SHIFT) & MMCR1_PMC6SEL)
> +
> +#define MMCR0_INIT (MMCR0_FC | MMCR0_FCS | MMCR0_FCP | MMCR0_FCM1
> | MMCR0_FCM0)
> +
> +/* Unfreezes the counters on this CPU, enables the interrupt,
> + * enables the counters to trigger the interrupt, and sets the
> + * counters to only count when the mark bit is not set.
> + */
> +static void pmc_start_ctrs(void)
> +{
> + u32 mmcr0 = mfspr(SPRN_MMCR0);
> +
> + mmcr0 &= ~(MMCR0_FC | MMCR0_FCM0);
> + mmcr0 |= (MMCR0_FCECE | MMCR0_PMC1CE | MMCR0_PMCnCE | MMCR0_PMXE);
> +
> + mtspr(SPRN_MMCR0, mmcr0);
> +}
> +
> +/* Disables the counters on this CPU, and freezes them */
> +static void pmc_stop_ctrs(void)
> +{
> + u32 mmcr0 = mfspr(SPRN_MMCR0);
> +
> + mmcr0 |= MMCR0_FC;
> + mmcr0 &= ~(MMCR0_FCECE | MMCR0_PMC1CE | MMCR0_PMCnCE | MMCR0_PMXE);
> +
> + mtspr(SPRN_MMCR0, mmcr0);
> +}
> +
> +/* Configures the counters on this CPU based on the global
> + * settings */
> +static void fsl7450_cpu_setup(void *unused)
> +{
> + /* freeze all counters */
> + pmc_stop_ctrs();
> +
> + mtspr(SPRN_MMCR0, mmcr0_val);
> + mtspr(SPRN_MMCR1, mmcr1_val);
> + mtspr(SPRN_MMCR2, mmcr2_val);
> +}
Why hard code this, num_ctrs is passed in?
> +
> +#define NUM_CTRS 6
> +
> +/* Configures the global settings for the countes on all CPUs. */
> +static void fsl7450_reg_setup(struct op_counter_config *ctr,
> + struct op_system_config *sys,
> + int num_ctrs)
> +{
> + int i;
> +
> + /* Our counters count up, and "count" refers to
> + * how much before the next interrupt, and we interrupt
> + * on overflow. So we calculate the starting value
> + * which will give us "count" until overflow.
> + * Then we set the events on the enabled counters */
> + for (i = 0; i < NUM_CTRS; ++i)
> + reset_value[i] = 0x80000000UL - ctr[i].count;
> +
> + /* Set events for Counters 1 & 2 */
> + mmcr0_val = MMCR0_INIT | mmcr0_event1(ctr[0].event)
> + | mmcr0_event2(ctr[1].event);
> +
> + /* Setup user/kernel bits */
> + if (sys->enable_kernel)
> + mmcr0_val &= ~(MMCR0_FCS);
> +
> + if (sys->enable_user)
> + mmcr0_val &= ~(MMCR0_FCP);
> +
> + /* Set events for Counters 3-6 */
> + mmcr1_val = mmcr1_event3(ctr[2].event)
> + | mmcr1_event4(ctr[3].event)
> + | mmcr1_event5(ctr[4].event)
> + | mmcr1_event6(ctr[5].event);
> +
> + mmcr2_val = 0;
> +}
> +
> +/* Sets the counters on this CPU to the chosen values, and starts
> them */
> +static void fsl7450_start(struct op_counter_config *ctr)
> +{
> + int i;
> +
> + mtmsr(mfmsr() | MSR_PMM);
> +
> + for (i = 0; i < NUM_CTRS; ++i) {
> + if (ctr[i].enabled)
> + ctr_write(i, reset_value[i]);
> + else
> + ctr_write(i, 0);
> + }
> +
> + /* Clear the freeze bit, and enable the interrupt.
> + * The counters won't actually start until the rfi clears
> + * the PMM bit */
> + pmc_start_ctrs();
> +
> + oprofile_running = 1;
> +}
> +
> +/* Stop the counters on this CPU */
> +static void fsl7450_stop(void)
> +{
> + /* freeze counters */
> + pmc_stop_ctrs();
> +
> + oprofile_running = 0;
> +
> + mb();
> +}
> +
> +
> +/* Handle the interrupt on this CPU, and log a sample for each
> + * event that triggered the interrupt */
> +static void fsl7450_handle_interrupt(struct pt_regs *regs,
> + struct op_counter_config *ctr)
> +{
> + unsigned long pc;
> + int is_kernel;
> + int val;
> + int i;
> +
> + /* set the PMM bit (see comment below) */
> + mtmsr(mfmsr() | MSR_PMM);
> +
> + pc = mfspr(SPRN_SIAR);
> + is_kernel = (pc >= KERNELBASE);
> +
> + for (i = 0; i < NUM_CTRS; ++i) {
> + val = ctr_read(i);
> + if (val < 0) {
> + if (oprofile_running && ctr[i].enabled) {
> + oprofile_add_pc(pc, is_kernel, i);
> + ctr_write(i, reset_value[i]);
> + } else {
> + ctr_write(i, 0);
> + }
> + }
> + }
> +
> + /* The freeze bit was set by the interrupt. */
> + /* Clear the freeze bit, and reenable the interrupt.
> + * The counters won't actually start until the rfi clears
> + * the PMM bit */
> + pmc_start_ctrs();
> +}
> +
> +struct op_powerpc_model op_model_7450= {
> + .reg_setup = fsl7450_reg_setup,
> + .cpu_setup = fsl7450_cpu_setup,
> + .start = fsl7450_start,
> + .stop = fsl7450_stop,
> + .handle_interrupt = fsl7450_handle_interrupt,
> +};
> diff --git a/include/asm-powerpc/oprofile_impl.h b/include/asm-
> powerpc/oprofile_impl.h
> index 8013cd2..b48d35e 100644
> --- a/include/asm-powerpc/oprofile_impl.h
> +++ b/include/asm-powerpc/oprofile_impl.h
> @@ -22,24 +22,22 @@ struct op_counter_config {
> unsigned long enabled;
> unsigned long event;
> unsigned long count;
Does, classic include ppc64? if so you should be more explicit in the
comment.
> + /* Classic doesn't support per-counter user/kernel selection */
> unsigned long kernel;
> -#ifdef __powerpc64__
> - /* We dont support per counter user/kernel selection */
> -#endif
> unsigned long user;
> unsigned long unit_mask;
> };
>
> /* System-wide configuration as set via oprofilefs. */
> struct op_system_config {
> -#ifdef __powerpc64__
> +#ifdef CONFIG_PPC64
> unsigned long mmcr0;
> unsigned long mmcr1;
> unsigned long mmcra;
> #endif
> unsigned long enable_kernel;
> unsigned long enable_user;
> -#ifdef __powerpc64__
> +#ifdef CONFIG_PPC64
> unsigned long backtrace_spinlocks;
> #endif
> };
> @@ -49,9 +47,7 @@ struct op_powerpc_model {
> void (*reg_setup) (struct op_counter_config *,
> struct op_system_config *,
> int num_counters);
> -#ifdef __powerpc64__
> void (*cpu_setup) (void *);
> -#endif
> void (*start) (struct op_counter_config *);
> void (*stop) (void);
> void (*handle_interrupt) (struct pt_regs *,
> @@ -59,10 +55,19 @@ struct op_powerpc_model {
> int num_counters;
> };
>
> -#ifdef __powerpc64__
> +#ifdef CONFIG_FSL_BOOKE
> +extern struct op_powerpc_model op_model_fsl_booke;
> +#else /* Otherwise, it's classic */
> +
> +#ifdef CONFIG_PPC64
> extern struct op_powerpc_model op_model_rs64;
> extern struct op_powerpc_model op_model_power4;
>
> +#else /* Otherwise, CONFIG_PPC32 */
> +extern struct op_powerpc_model op_model_7450;
> +#endif
> +
> +/* All the classic PPC parts use these */
> static inline unsigned int ctr_read(unsigned int i)
> {
> switch(i) {
> @@ -78,10 +83,14 @@ static inline unsigned int ctr_read(unsi
> return mfspr(SPRN_PMC5);
> case 5:
> return mfspr(SPRN_PMC6);
Are these ifdef's really worth it?
> +
> +/* No PPC32 chip has more than 6 so far */
> +#ifdef CONFIG_PPC64
> case 6:
> return mfspr(SPRN_PMC7);
> case 7:
> return mfspr(SPRN_PMC8);
> +#endif
> default:
> return 0;
> }
> @@ -108,16 +117,20 @@ static inline void ctr_write(unsigned in
> case 5:
> mtspr(SPRN_PMC6, val);
> break;
> +
> +/* No PPC32 chip has more than 6, yet */
> +#ifdef CONFIG_PPC64
> case 6:
> mtspr(SPRN_PMC7, val);
> break;
> case 7:
> mtspr(SPRN_PMC8, val);
> break;
> +#endif
> default:
> break;
> }
> }
> -#endif /* __powerpc64__ */
> +#endif /* !CONFIG_FSL_BOOKE */
>
> #endif /* _ASM_POWERPC_OPROFILE_IMPL_H */
> diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h
> index eb392d0..a9a7685 100644
> --- a/include/asm-powerpc/reg.h
> +++ b/include/asm-powerpc/reg.h
> @@ -443,12 +443,35 @@
> #define SPRN_SDAR 781
>
> #else /* 32-bit */
> -#define SPRN_MMCR0 0x3B8 /* Monitor Mode Control Register 0 */
> -#define SPRN_MMCR1 0x3BC /* Monitor Mode Control Register 1 */
> -#define SPRN_PMC1 0x3B9 /* Performance Counter Register 1 */
> -#define SPRN_PMC2 0x3BA /* Performance Counter Register 2 */
> -#define SPRN_PMC3 0x3BD /* Performance Counter Register 3 */
> -#define SPRN_PMC4 0x3BE /* Performance Counter Register 4 */
> +#define SPRN_MMCR0 952 /* Monitor Mode Control Register 0 */
> +#define MMCR0_FC 0x80000000UL /* freeze counters */
> +#define MMCR0_FCS 0x40000000UL /* freeze in supervisor state */
> +#define MMCR0_FCP 0x20000000UL /* freeze in problem state */
> +#define MMCR0_FCM1 0x10000000UL /* freeze counters while MSR
> mark = 1 */
> +#define MMCR0_FCM0 0x08000000UL /* freeze counters while MSR
> mark = 0 */
> +#define MMCR0_PMXE 0x04000000UL /* performance monitor exception
> enable */
> +#define MMCR0_FCECE 0x02000000UL /* freeze ctrs on enabled cond
> or event */
> +#define MMCR0_TBEE 0x00400000UL /* time base exception enable */
> +#define MMCR0_PMC1CE 0x00008000UL /* PMC1 count enable*/
> +#define MMCR0_PMCnCE 0x00004000UL /* count enable for all but
> PMC 1*/
> +#define MMCR0_TRIGGER 0x00002000UL /* TRIGGER enable */
> +#define MMCR0_PMC1SEL 0x00001fc0UL /* PMC 1 Event */
> +#define MMCR0_PMC2SEL 0x0000003fUL /* PMC 2 Event */
> +
> +#define SPRN_MMCR1 956
> +#define MMCR1_PMC3SEL 0xf8000000UL /* PMC 3 Event */
> +#define MMCR1_PMC4SEL 0x07c00000UL /* PMC 4 Event */
> +#define MMCR1_PMC5SEL 0x003e0000UL /* PMC 5 Event */
> +#define MMCR1_PMC6SEL 0x0001f800UL /* PMC 6 Event */
> +#define SPRN_MMCR2 944
> +#define SPRN_PMC1 953 /* Performance Counter Register 1 */
> +#define SPRN_PMC2 954 /* Performance Counter Register 2 */
> +#define SPRN_PMC3 957 /* Performance Counter Register 3 */
> +#define SPRN_PMC4 958 /* Performance Counter Register 4 */
> +#define SPRN_PMC5 945 /* Performance Counter Register 5 */
> +#define SPRN_PMC6 946 /* Performance Counter Register 6 */
> +
> +#define SPRN_SIAR 955 /* Sampled Instruction Address Register */
>
Why not move all MMCR0_ defines up ?
> /* Bit definitions for MMCR0 and PMC1 / PMC2. */
> #define MMCR0_PMC1_CYCLES (1 << 7)
> @@ -458,7 +481,6 @@
> #define MMCR0_PMC2_CYCLES 0x1
> #define MMCR0_PMC2_ITLB 0x7
> #define MMCR0_PMC2_LOADMISSTIME 0x5
> -#define MMCR0_PMXE (1 << 26)
> #endif
>
> /* Processor Version Register (PVR) field extraction */
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
^ permalink raw reply
* [PATCH] G4+ oprofile support
From: Andy Fleming @ 2005-12-16 2:02 UTC (permalink / raw)
To: linuxppc-dev
This patch adds oprofile support for the 7450 and all its multitudinous
derivatives.
Signed-off-by: Andy Fleming <afleming@freescale.com>
* Added 7450 (and derivatives) support for oprofile
* Changed e500 cputable to have oprofile model and cpu_type fields
* Added support for classic 32-bit performance monitor interrupt
* Cleaned up common powerpc oprofile code to be as common as possible
* Cleaned up oprofile_impl.h to reflect 32 bit classic code
* Added 32-bit MMCRx bitfield definitions and SPR numbers
---
commit 44e22e7c3358c79517685e7b66ffae17da6f8399
tree 2f8ee433f01d70e176b074af50fa0bca384699b8
parent 49d7bc64283970ee83d2c954d04ba00d04e5943d
author Andrew Fleming <afleming@freescale.com> Thu, 15 Dec 2005 15:36:31 -0600
committer Andrew Fleming <afleming@ld0175-tx32.(none)> Thu, 15 Dec 2005 15:36:31 -0600
arch/powerpc/kernel/cputable.c | 74 ++++++++++--
arch/powerpc/kernel/head_32.S | 12 +-
arch/powerpc/kernel/pmc.c | 5 +
arch/powerpc/kernel/traps.c | 2
arch/powerpc/oprofile/Makefile | 1
arch/powerpc/oprofile/common.c | 61 ++--------
arch/powerpc/oprofile/op_model_7450.c | 206 +++++++++++++++++++++++++++++++++
include/asm-powerpc/oprofile_impl.h | 31 ++++-
include/asm-powerpc/reg.h | 36 +++++-
9 files changed, 344 insertions(+), 84 deletions(-)
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index 1d85ced..f7f2a83 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -545,7 +545,11 @@ struct cpu_spec cpu_specs[] = {
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
- .cpu_setup = __setup_cpu_745x
+ .cpu_setup = __setup_cpu_745x,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc/7450",
+ .oprofile_model = &op_model_7450,
+#endif
},
{ /* 7450 2.1 */
.pvr_mask = 0xffffffff,
@@ -556,7 +560,11 @@ struct cpu_spec cpu_specs[] = {
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
- .cpu_setup = __setup_cpu_745x
+ .cpu_setup = __setup_cpu_745x,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc/7450",
+ .oprofile_model = &op_model_7450,
+#endif
},
{ /* 7450 2.3 and newer */
.pvr_mask = 0xffff0000,
@@ -567,7 +575,11 @@ struct cpu_spec cpu_specs[] = {
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
- .cpu_setup = __setup_cpu_745x
+ .cpu_setup = __setup_cpu_745x,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc/7450",
+ .oprofile_model = &op_model_7450,
+#endif
},
{ /* 7455 rev 1.x */
.pvr_mask = 0xffffff00,
@@ -578,7 +590,11 @@ struct cpu_spec cpu_specs[] = {
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
- .cpu_setup = __setup_cpu_745x
+ .cpu_setup = __setup_cpu_745x,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc/7450",
+ .oprofile_model = &op_model_7450,
+#endif
},
{ /* 7455 rev 2.0 */
.pvr_mask = 0xffffffff,
@@ -589,7 +605,11 @@ struct cpu_spec cpu_specs[] = {
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
- .cpu_setup = __setup_cpu_745x
+ .cpu_setup = __setup_cpu_745x,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc/7450",
+ .oprofile_model = &op_model_7450,
+#endif
},
{ /* 7455 others */
.pvr_mask = 0xffff0000,
@@ -600,7 +620,11 @@ struct cpu_spec cpu_specs[] = {
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
- .cpu_setup = __setup_cpu_745x
+ .cpu_setup = __setup_cpu_745x,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc/7450",
+ .oprofile_model = &op_model_7450,
+#endif
},
{ /* 7447/7457 Rev 1.0 */
.pvr_mask = 0xffffffff,
@@ -611,7 +635,11 @@ struct cpu_spec cpu_specs[] = {
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
- .cpu_setup = __setup_cpu_745x
+ .cpu_setup = __setup_cpu_745x,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc/7450",
+ .oprofile_model = &op_model_7450,
+#endif
},
{ /* 7447/7457 Rev 1.1 */
.pvr_mask = 0xffffffff,
@@ -622,7 +650,11 @@ struct cpu_spec cpu_specs[] = {
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
- .cpu_setup = __setup_cpu_745x
+ .cpu_setup = __setup_cpu_745x,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc/7450",
+ .oprofile_model = &op_model_7450,
+#endif
},
{ /* 7447/7457 Rev 1.2 and later */
.pvr_mask = 0xffff0000,
@@ -633,7 +665,11 @@ struct cpu_spec cpu_specs[] = {
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
- .cpu_setup = __setup_cpu_745x
+ .cpu_setup = __setup_cpu_745x,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc/7450",
+ .oprofile_model = &op_model_7450,
+#endif
},
{ /* 7447A */
.pvr_mask = 0xffff0000,
@@ -644,7 +680,11 @@ struct cpu_spec cpu_specs[] = {
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
- .cpu_setup = __setup_cpu_745x
+ .cpu_setup = __setup_cpu_745x,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc/7450",
+ .oprofile_model = &op_model_7450,
+#endif
},
{ /* 7448 */
.pvr_mask = 0xffff0000,
@@ -655,7 +695,11 @@ struct cpu_spec cpu_specs[] = {
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 6,
- .cpu_setup = __setup_cpu_745x
+ .cpu_setup = __setup_cpu_745x,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc/7450",
+ .oprofile_model = &op_model_7450,
+#endif
},
{ /* 82xx (8240, 8245, 8260 are all 603e cores) */
.pvr_mask = 0x7fff0000,
@@ -979,6 +1023,10 @@ struct cpu_spec cpu_specs[] = {
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc/e500",
+ .oprofile_model = &op_model_fsl_booke,
+#endif
},
{ /* e500v2 */
.pvr_mask = 0xffff0000,
@@ -992,6 +1040,10 @@ struct cpu_spec cpu_specs[] = {
.icache_bsize = 32,
.dcache_bsize = 32,
.num_pmcs = 4,
+#ifdef CONFIG_OPROFILE
+ .oprofile_cpu_type = "ppc/e500",
+ .oprofile_model = &op_model_fsl_booke,
+#endif
},
#endif
#if !CLASSIC_PPC
diff --git a/arch/powerpc/kernel/head_32.S b/arch/powerpc/kernel/head_32.S
index ccdf947..34ff064 100644
--- a/arch/powerpc/kernel/head_32.S
+++ b/arch/powerpc/kernel/head_32.S
@@ -450,16 +450,11 @@ SystemCall:
* by executing an altivec instruction.
*/
. = 0xf00
- b Trap_0f
+ b PerformanceMonitor
. = 0xf20
b AltiVecUnavailable
-Trap_0f:
- EXCEPTION_PROLOG
- addi r3,r1,STACK_FRAME_OVERHEAD
- EXC_XFER_EE(0xf00, unknown_exception)
-
/*
* Handle TLB miss for instruction on 603/603e.
* Note: we get an alternate set of r0 - r3 to use automatically.
@@ -703,6 +698,11 @@ AltiVecUnavailable:
#endif /* CONFIG_ALTIVEC */
EXC_XFER_EE_LITE(0xf20, altivec_unavailable_exception)
+PerformanceMonitor:
+ EXCEPTION_PROLOG
+ addi r3,r1,STACK_FRAME_OVERHEAD
+ EXC_XFER_STD(0xf00, performance_monitor_exception)
+
#ifdef CONFIG_ALTIVEC
/* Note that the AltiVec support is closely modeled after the FP
* support. Changes to one are likely to be applicable to the
diff --git a/arch/powerpc/kernel/pmc.c b/arch/powerpc/kernel/pmc.c
index 2d333cc..e6fb194 100644
--- a/arch/powerpc/kernel/pmc.c
+++ b/arch/powerpc/kernel/pmc.c
@@ -43,8 +43,13 @@ static void dummy_perf(struct pt_regs *r
mtspr(SPRN_MMCR0, mmcr0);
}
#else
+/* Ensure exceptions are disabled */
static void dummy_perf(struct pt_regs *regs)
{
+ unsigned int mmcr0 = mfspr(SPRN_MMCR0);
+
+ mmcr0 &= ~(MMCR0_PMXE);
+ mtspr(SPRN_MMCR0, mmcr0);
}
#endif
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 1511454..8c91369 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -886,12 +886,10 @@ void altivec_unavailable_exception(struc
die("Unrecoverable VMX/Altivec Unavailable Exception", regs, SIGABRT);
}
-#if defined(CONFIG_PPC64) || defined(CONFIG_E500)
void performance_monitor_exception(struct pt_regs *regs)
{
perf_irq(regs);
}
-#endif
#ifdef CONFIG_8xx
void SoftwareEmulation(struct pt_regs *regs)
diff --git a/arch/powerpc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile
index 0782d0c..554cd7c 100644
--- a/arch/powerpc/oprofile/Makefile
+++ b/arch/powerpc/oprofile/Makefile
@@ -9,3 +9,4 @@ DRIVER_OBJS := $(addprefix ../../../driv
oprofile-y := $(DRIVER_OBJS) common.o
oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o
oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o
+oprofile-$(CONFIG_PPC32) += op_model_7450.o
diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/common.c
index af2c05d..a370778 100644
--- a/arch/powerpc/oprofile/common.c
+++ b/arch/powerpc/oprofile/common.c
@@ -14,9 +14,6 @@
*/
#include <linux/oprofile.h>
-#ifndef __powerpc64__
-#include <linux/slab.h>
-#endif /* ! __powerpc64__ */
#include <linux/init.h>
#include <linux/smp.h>
#include <linux/errno.h>
@@ -31,10 +28,6 @@ static struct op_powerpc_model *model;
static struct op_counter_config ctr[OP_MAX_COUNTER];
static struct op_system_config sys;
-#ifndef __powerpc64__
-static char *cpu_type;
-#endif /* ! __powerpc64__ */
-
static void op_handle_interrupt(struct pt_regs *regs)
{
model->handle_interrupt(regs, ctr);
@@ -53,14 +46,7 @@ static int op_powerpc_setup(void)
model->reg_setup(ctr, &sys, model->num_counters);
/* Configure the registers on all cpus. */
-#ifdef __powerpc64__
on_each_cpu(model->cpu_setup, NULL, 0, 1);
-#else /* __powerpc64__ */
-#if 0
- /* FIXME: Make multi-cpu work */
- on_each_cpu(model->reg_setup, NULL, 0, 1);
-#endif
-#endif /* __powerpc64__ */
return 0;
}
@@ -95,7 +81,7 @@ static int op_powerpc_create_files(struc
{
int i;
-#ifdef __powerpc64__
+#ifdef CONFIG_PPC64
/*
* There is one mmcr0, mmcr1 and mmcra for setting the events for
* all of the counters.
@@ -103,7 +89,7 @@ static int op_powerpc_create_files(struc
oprofilefs_create_ulong(sb, root, "mmcr0", &sys.mmcr0);
oprofilefs_create_ulong(sb, root, "mmcr1", &sys.mmcr1);
oprofilefs_create_ulong(sb, root, "mmcra", &sys.mmcra);
-#endif /* __powerpc64__ */
+#endif
for (i = 0; i < model->num_counters; ++i) {
struct dentry *dir;
@@ -115,65 +101,46 @@ static int op_powerpc_create_files(struc
oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled);
oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event);
oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count);
-#ifdef __powerpc64__
+
/*
- * We dont support per counter user/kernel selection, but
- * we leave the entries because userspace expects them
+ * Classic PowerPC doesn't support per-counter
+ * control like this, but the options are
+ * expected, so they remain. For Freescale
+ * Book-E style performance monitors, we do
+ * support them.
*/
-#endif /* __powerpc64__ */
oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel);
oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user);
-#ifndef __powerpc64__
- /* FIXME: Not sure if this is used */
-#endif /* ! __powerpc64__ */
oprofilefs_create_ulong(sb, dir, "unit_mask", &ctr[i].unit_mask);
}
oprofilefs_create_ulong(sb, root, "enable_kernel", &sys.enable_kernel);
oprofilefs_create_ulong(sb, root, "enable_user", &sys.enable_user);
-#ifdef __powerpc64__
+#ifdef CONFIG_PPC64
oprofilefs_create_ulong(sb, root, "backtrace_spinlocks",
&sys.backtrace_spinlocks);
-#endif /* __powerpc64__ */
+#endif
/* Default to tracing both kernel and user */
sys.enable_kernel = 1;
sys.enable_user = 1;
-#ifdef __powerpc64__
+#ifdef CONFIG_PPC64
/* Turn on backtracing through spinlocks by default */
sys.backtrace_spinlocks = 1;
-#endif /* __powerpc64__ */
+#endif
return 0;
}
int __init oprofile_arch_init(struct oprofile_operations *ops)
{
-#ifndef __powerpc64__
-#ifdef CONFIG_FSL_BOOKE
- model = &op_model_fsl_booke;
-#else
- return -ENODEV;
-#endif
-
- cpu_type = kmalloc(32, GFP_KERNEL);
- if (NULL == cpu_type)
- return -ENOMEM;
-
- sprintf(cpu_type, "ppc/%s", cur_cpu_spec->cpu_name);
-
- model->num_counters = cur_cpu_spec->num_pmcs;
-
- ops->cpu_type = cpu_type;
-#else /* __powerpc64__ */
if (!cur_cpu_spec->oprofile_model || !cur_cpu_spec->oprofile_cpu_type)
return -ENODEV;
model = cur_cpu_spec->oprofile_model;
model->num_counters = cur_cpu_spec->num_pmcs;
ops->cpu_type = cur_cpu_spec->oprofile_cpu_type;
-#endif /* __powerpc64__ */
ops->create_files = op_powerpc_create_files;
ops->setup = op_powerpc_setup;
ops->shutdown = op_powerpc_shutdown;
@@ -188,8 +155,4 @@ int __init oprofile_arch_init(struct opr
void oprofile_arch_exit(void)
{
-#ifndef __powerpc64__
- kfree(cpu_type);
- cpu_type = NULL;
-#endif /* ! __powerpc64__ */
}
diff --git a/arch/powerpc/oprofile/op_model_7450.c b/arch/powerpc/oprofile/op_model_7450.c
new file mode 100644
index 0000000..32abfdb
--- /dev/null
+++ b/arch/powerpc/oprofile/op_model_7450.c
@@ -0,0 +1,206 @@
+/*
+ * oprofile/op_model_7450.c
+ *
+ * Freescale 745x/744x oprofile support, based on fsl_booke support
+ * Copyright (C) 2004 Anton Blanchard <anton@au.ibm.com>, IBM
+ *
+ * Copyright (c) 2004 Freescale Semiconductor, Inc
+ *
+ * Author: Andy Fleming
+ * Maintainer: Kumar Gala <galak@kernel.crashing.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/oprofile.h>
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <asm/ptrace.h>
+#include <asm/system.h>
+#include <asm/processor.h>
+#include <asm/cputable.h>
+#include <asm/page.h>
+#include <asm/pmc.h>
+#include <asm/oprofile_impl.h>
+
+static unsigned long reset_value[OP_MAX_COUNTER];
+
+static int oprofile_running;
+static u32 mmcr0_val, mmcr1_val, mmcr2_val;
+
+#define MMCR0_PMC1_SHIFT 6
+#define MMCR0_PMC2_SHIFT 0
+#define MMCR1_PMC3_SHIFT 27
+#define MMCR1_PMC4_SHIFT 22
+#define MMCR1_PMC5_SHIFT 17
+#define MMCR1_PMC6_SHIFT 11
+
+#define mmcr0_event1(event) \
+ ((event << MMCR0_PMC1_SHIFT) & MMCR0_PMC1SEL)
+#define mmcr0_event2(event) \
+ ((event << MMCR0_PMC2_SHIFT) & MMCR0_PMC2SEL)
+
+#define mmcr1_event3(event) \
+ ((event << MMCR1_PMC3_SHIFT) & MMCR1_PMC3SEL)
+#define mmcr1_event4(event) \
+ ((event << MMCR1_PMC4_SHIFT) & MMCR1_PMC4SEL)
+#define mmcr1_event5(event) \
+ ((event << MMCR1_PMC5_SHIFT) & MMCR1_PMC5SEL)
+#define mmcr1_event6(event) \
+ ((event << MMCR1_PMC6_SHIFT) & MMCR1_PMC6SEL)
+
+#define MMCR0_INIT (MMCR0_FC | MMCR0_FCS | MMCR0_FCP | MMCR0_FCM1 | MMCR0_FCM0)
+
+/* Unfreezes the counters on this CPU, enables the interrupt,
+ * enables the counters to trigger the interrupt, and sets the
+ * counters to only count when the mark bit is not set.
+ */
+static void pmc_start_ctrs(void)
+{
+ u32 mmcr0 = mfspr(SPRN_MMCR0);
+
+ mmcr0 &= ~(MMCR0_FC | MMCR0_FCM0);
+ mmcr0 |= (MMCR0_FCECE | MMCR0_PMC1CE | MMCR0_PMCnCE | MMCR0_PMXE);
+
+ mtspr(SPRN_MMCR0, mmcr0);
+}
+
+/* Disables the counters on this CPU, and freezes them */
+static void pmc_stop_ctrs(void)
+{
+ u32 mmcr0 = mfspr(SPRN_MMCR0);
+
+ mmcr0 |= MMCR0_FC;
+ mmcr0 &= ~(MMCR0_FCECE | MMCR0_PMC1CE | MMCR0_PMCnCE | MMCR0_PMXE);
+
+ mtspr(SPRN_MMCR0, mmcr0);
+}
+
+/* Configures the counters on this CPU based on the global
+ * settings */
+static void fsl7450_cpu_setup(void *unused)
+{
+ /* freeze all counters */
+ pmc_stop_ctrs();
+
+ mtspr(SPRN_MMCR0, mmcr0_val);
+ mtspr(SPRN_MMCR1, mmcr1_val);
+ mtspr(SPRN_MMCR2, mmcr2_val);
+}
+
+#define NUM_CTRS 6
+
+/* Configures the global settings for the countes on all CPUs. */
+static void fsl7450_reg_setup(struct op_counter_config *ctr,
+ struct op_system_config *sys,
+ int num_ctrs)
+{
+ int i;
+
+ /* Our counters count up, and "count" refers to
+ * how much before the next interrupt, and we interrupt
+ * on overflow. So we calculate the starting value
+ * which will give us "count" until overflow.
+ * Then we set the events on the enabled counters */
+ for (i = 0; i < NUM_CTRS; ++i)
+ reset_value[i] = 0x80000000UL - ctr[i].count;
+
+ /* Set events for Counters 1 & 2 */
+ mmcr0_val = MMCR0_INIT | mmcr0_event1(ctr[0].event)
+ | mmcr0_event2(ctr[1].event);
+
+ /* Setup user/kernel bits */
+ if (sys->enable_kernel)
+ mmcr0_val &= ~(MMCR0_FCS);
+
+ if (sys->enable_user)
+ mmcr0_val &= ~(MMCR0_FCP);
+
+ /* Set events for Counters 3-6 */
+ mmcr1_val = mmcr1_event3(ctr[2].event)
+ | mmcr1_event4(ctr[3].event)
+ | mmcr1_event5(ctr[4].event)
+ | mmcr1_event6(ctr[5].event);
+
+ mmcr2_val = 0;
+}
+
+/* Sets the counters on this CPU to the chosen values, and starts them */
+static void fsl7450_start(struct op_counter_config *ctr)
+{
+ int i;
+
+ mtmsr(mfmsr() | MSR_PMM);
+
+ for (i = 0; i < NUM_CTRS; ++i) {
+ if (ctr[i].enabled)
+ ctr_write(i, reset_value[i]);
+ else
+ ctr_write(i, 0);
+ }
+
+ /* Clear the freeze bit, and enable the interrupt.
+ * The counters won't actually start until the rfi clears
+ * the PMM bit */
+ pmc_start_ctrs();
+
+ oprofile_running = 1;
+}
+
+/* Stop the counters on this CPU */
+static void fsl7450_stop(void)
+{
+ /* freeze counters */
+ pmc_stop_ctrs();
+
+ oprofile_running = 0;
+
+ mb();
+}
+
+
+/* Handle the interrupt on this CPU, and log a sample for each
+ * event that triggered the interrupt */
+static void fsl7450_handle_interrupt(struct pt_regs *regs,
+ struct op_counter_config *ctr)
+{
+ unsigned long pc;
+ int is_kernel;
+ int val;
+ int i;
+
+ /* set the PMM bit (see comment below) */
+ mtmsr(mfmsr() | MSR_PMM);
+
+ pc = mfspr(SPRN_SIAR);
+ is_kernel = (pc >= KERNELBASE);
+
+ for (i = 0; i < NUM_CTRS; ++i) {
+ val = ctr_read(i);
+ if (val < 0) {
+ if (oprofile_running && ctr[i].enabled) {
+ oprofile_add_pc(pc, is_kernel, i);
+ ctr_write(i, reset_value[i]);
+ } else {
+ ctr_write(i, 0);
+ }
+ }
+ }
+
+ /* The freeze bit was set by the interrupt. */
+ /* Clear the freeze bit, and reenable the interrupt.
+ * The counters won't actually start until the rfi clears
+ * the PMM bit */
+ pmc_start_ctrs();
+}
+
+struct op_powerpc_model op_model_7450= {
+ .reg_setup = fsl7450_reg_setup,
+ .cpu_setup = fsl7450_cpu_setup,
+ .start = fsl7450_start,
+ .stop = fsl7450_stop,
+ .handle_interrupt = fsl7450_handle_interrupt,
+};
diff --git a/include/asm-powerpc/oprofile_impl.h b/include/asm-powerpc/oprofile_impl.h
index 8013cd2..b48d35e 100644
--- a/include/asm-powerpc/oprofile_impl.h
+++ b/include/asm-powerpc/oprofile_impl.h
@@ -22,24 +22,22 @@ struct op_counter_config {
unsigned long enabled;
unsigned long event;
unsigned long count;
+ /* Classic doesn't support per-counter user/kernel selection */
unsigned long kernel;
-#ifdef __powerpc64__
- /* We dont support per counter user/kernel selection */
-#endif
unsigned long user;
unsigned long unit_mask;
};
/* System-wide configuration as set via oprofilefs. */
struct op_system_config {
-#ifdef __powerpc64__
+#ifdef CONFIG_PPC64
unsigned long mmcr0;
unsigned long mmcr1;
unsigned long mmcra;
#endif
unsigned long enable_kernel;
unsigned long enable_user;
-#ifdef __powerpc64__
+#ifdef CONFIG_PPC64
unsigned long backtrace_spinlocks;
#endif
};
@@ -49,9 +47,7 @@ struct op_powerpc_model {
void (*reg_setup) (struct op_counter_config *,
struct op_system_config *,
int num_counters);
-#ifdef __powerpc64__
void (*cpu_setup) (void *);
-#endif
void (*start) (struct op_counter_config *);
void (*stop) (void);
void (*handle_interrupt) (struct pt_regs *,
@@ -59,10 +55,19 @@ struct op_powerpc_model {
int num_counters;
};
-#ifdef __powerpc64__
+#ifdef CONFIG_FSL_BOOKE
+extern struct op_powerpc_model op_model_fsl_booke;
+#else /* Otherwise, it's classic */
+
+#ifdef CONFIG_PPC64
extern struct op_powerpc_model op_model_rs64;
extern struct op_powerpc_model op_model_power4;
+#else /* Otherwise, CONFIG_PPC32 */
+extern struct op_powerpc_model op_model_7450;
+#endif
+
+/* All the classic PPC parts use these */
static inline unsigned int ctr_read(unsigned int i)
{
switch(i) {
@@ -78,10 +83,14 @@ static inline unsigned int ctr_read(unsi
return mfspr(SPRN_PMC5);
case 5:
return mfspr(SPRN_PMC6);
+
+/* No PPC32 chip has more than 6 so far */
+#ifdef CONFIG_PPC64
case 6:
return mfspr(SPRN_PMC7);
case 7:
return mfspr(SPRN_PMC8);
+#endif
default:
return 0;
}
@@ -108,16 +117,20 @@ static inline void ctr_write(unsigned in
case 5:
mtspr(SPRN_PMC6, val);
break;
+
+/* No PPC32 chip has more than 6, yet */
+#ifdef CONFIG_PPC64
case 6:
mtspr(SPRN_PMC7, val);
break;
case 7:
mtspr(SPRN_PMC8, val);
break;
+#endif
default:
break;
}
}
-#endif /* __powerpc64__ */
+#endif /* !CONFIG_FSL_BOOKE */
#endif /* _ASM_POWERPC_OPROFILE_IMPL_H */
diff --git a/include/asm-powerpc/reg.h b/include/asm-powerpc/reg.h
index eb392d0..a9a7685 100644
--- a/include/asm-powerpc/reg.h
+++ b/include/asm-powerpc/reg.h
@@ -443,12 +443,35 @@
#define SPRN_SDAR 781
#else /* 32-bit */
-#define SPRN_MMCR0 0x3B8 /* Monitor Mode Control Register 0 */
-#define SPRN_MMCR1 0x3BC /* Monitor Mode Control Register 1 */
-#define SPRN_PMC1 0x3B9 /* Performance Counter Register 1 */
-#define SPRN_PMC2 0x3BA /* Performance Counter Register 2 */
-#define SPRN_PMC3 0x3BD /* Performance Counter Register 3 */
-#define SPRN_PMC4 0x3BE /* Performance Counter Register 4 */
+#define SPRN_MMCR0 952 /* Monitor Mode Control Register 0 */
+#define MMCR0_FC 0x80000000UL /* freeze counters */
+#define MMCR0_FCS 0x40000000UL /* freeze in supervisor state */
+#define MMCR0_FCP 0x20000000UL /* freeze in problem state */
+#define MMCR0_FCM1 0x10000000UL /* freeze counters while MSR mark = 1 */
+#define MMCR0_FCM0 0x08000000UL /* freeze counters while MSR mark = 0 */
+#define MMCR0_PMXE 0x04000000UL /* performance monitor exception enable */
+#define MMCR0_FCECE 0x02000000UL /* freeze ctrs on enabled cond or event */
+#define MMCR0_TBEE 0x00400000UL /* time base exception enable */
+#define MMCR0_PMC1CE 0x00008000UL /* PMC1 count enable*/
+#define MMCR0_PMCnCE 0x00004000UL /* count enable for all but PMC 1*/
+#define MMCR0_TRIGGER 0x00002000UL /* TRIGGER enable */
+#define MMCR0_PMC1SEL 0x00001fc0UL /* PMC 1 Event */
+#define MMCR0_PMC2SEL 0x0000003fUL /* PMC 2 Event */
+
+#define SPRN_MMCR1 956
+#define MMCR1_PMC3SEL 0xf8000000UL /* PMC 3 Event */
+#define MMCR1_PMC4SEL 0x07c00000UL /* PMC 4 Event */
+#define MMCR1_PMC5SEL 0x003e0000UL /* PMC 5 Event */
+#define MMCR1_PMC6SEL 0x0001f800UL /* PMC 6 Event */
+#define SPRN_MMCR2 944
+#define SPRN_PMC1 953 /* Performance Counter Register 1 */
+#define SPRN_PMC2 954 /* Performance Counter Register 2 */
+#define SPRN_PMC3 957 /* Performance Counter Register 3 */
+#define SPRN_PMC4 958 /* Performance Counter Register 4 */
+#define SPRN_PMC5 945 /* Performance Counter Register 5 */
+#define SPRN_PMC6 946 /* Performance Counter Register 6 */
+
+#define SPRN_SIAR 955 /* Sampled Instruction Address Register */
/* Bit definitions for MMCR0 and PMC1 / PMC2. */
#define MMCR0_PMC1_CYCLES (1 << 7)
@@ -458,7 +481,6 @@
#define MMCR0_PMC2_CYCLES 0x1
#define MMCR0_PMC2_ITLB 0x7
#define MMCR0_PMC2_LOADMISSTIME 0x5
-#define MMCR0_PMXE (1 << 26)
#endif
/* Processor Version Register (PVR) field extraction */
^ permalink raw reply related
* MPC5200 ppc_md.set_rtc_time
From: bennett78 @ 2005-12-16 0:15 UTC (permalink / raw)
To: linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 871 bytes --]
Hi:
How / when does "ppc_md.set_rtc_time" get filled
in for Lite5200?
Config for support /dev/rtc enables CONFIG_PPC_RTC
which enable driver/char/rtc.c which mentions CMOS_WRITE
panics the kernel!
I trying to use driver/char/genrtc.c. I can set date
but not hwclock.
> hwclock --set --date="9/22/96 16:45:05"
gen_set_rtc_irq_bit:exit
gen_rtc_ioctl RTC_SET_TIME 00000060
RTC_SET_TIME: Invalid argument
ioctl() to /dev/rtc to set the time failed.
bash-2.05b# cat /proc/driver/rtc
rtc_time : 00:50339648:36914
rtc_date : -1072186980-497--1073718072
rtc_epoch : 1900
alarm : 00:00:00
DST_enable : no
BCD : yes
24hr : yes
square_wave : no
alarm_IRQ : no
update_IRQ : no <----- how can I hook one?
periodic_IRQ : no
periodic_freq : 0
batt_status : okay
thanks,
*/Frank Bennett
/*
[-- Attachment #2: Type: text/html, Size: 1876 bytes --]
^ permalink raw reply
* Crash after successfully mounting root filesystem over NFS
From: Gil Madar @ 2005-12-15 22:20 UTC (permalink / raw)
To: linuxppc-embedded
Hi All,
I dumped part of the output, kept in the log_buf.
Please note the MPC866 receives an exception during access to the dual port ram...
This, of course leads to another exception, and so on.
The exception is during early stages of running busybox.
If I run a
while ( 1 ) schedule();
instead of loading root filesystem over NFS, the target respondes to pings without any problem.
I'm clueless whether this is a setup problem, or a software broblem.
I appreciate any comment.
Thans for your time,
Gil
----------------8X----------------------------------------------------------------
<6>NET: Registered protocol family 17
<4>IP-Config: Complete:
<4> device=eth0, addr=10.0.0.4, mask=255.0.0.0, gw=10.0.0.138,
<4> host=idu, domain=, nis-domain=(none),
<4> bootserver=10.0.0.2, rootserver=10.0.0.2, rootpath=
<5>Looking up port of RPC 100003/2 on 10.0.0.2
<5>Looking up port of RPC 100005/1 on 10.0.0.2
<4>VFS: Mounted root (nfs filesystem).
<4>Freeing unused kernel memory: 92k init
<6>init() line 782 /bin/busybox
<4>Oops: kernel access of bad area, sig: 11 [#1]
<4>Oops: kernel access of bad area, sig: 11 [#2]
<4>NIP: C016A1AC LR: C0010FEC SP: C02ED340 REGS: c02ed290 TRAP: 0300 Not tainted
<4>MSR: 00001032 EE: 0 PR: 0 FP: 0 ME: 1 IR/DR: 11
<4>DAR: 0F002820, DSISR: C0000000
<4>TASK = c02e9ae0[1] 'busybox' THREAD: c02ec000
<4>Last syscall: 11
<6>GPR00: 00000000 C02ED340 C02E9AE0 0F002820 C02903D0 0000002E 0EFFFFFF 00000000
<6>GPR08: C0260000 C026BF34 0F002820 C026BF34 00000001 00011F48 1007D900 00000000
<6>GPR16: C037E090 00000007 C02EDF10 00000000 0A000002 00000000 00000801 C0260000
<6>GPR24: C025EAC4 00001032 C0260000 C0260000 C0290000 000009CA 0000099C 0000000D
<4>Call trace: [00000000] [c0011148] [c0011714] [c001153c] [c0011338] [c00033d4] [c0009f38] [c0002f20] [c018f964] [c019d52c] [c018f9b4] [c01a941c] [c01ab380] [c01c6b14] [c01c6f30]
<0>Kernel panic - not syncing: Aiee, killing interrupt handler!
<4> <0>Rebooting in 180 seconds..Oops: kernel access of bad area, sig: 11 [#3]
<4>NIP: C000C99C LR: C00042BC SP: C02ED080 REGS: c02ecfd0 TRAP: 0300 Not tainted
<4>MSR: 00001032 EE: 0 PR: 0 FP: 0 ME: 1 IR/DR: 11
<4>DAR: 0F00001C, DSISR: C0000000
<4>TASK = c02e9ae0[1] 'busybox' THREAD: c02ec000
<4>Last syscall: 11
<6>GPR00: C00042BC C02ED080 C02E9AE0 C02ED0C0 C0290000 C0290000 C0260000 000009CA
<6>GPR08: C0290000 0F000000 C02EC000 00010100 002E9CA8 00011F48 1007D900 00000000
<6>GPR16: C037E090 00000007 C02EDF10 00000000 0A000002 00000000 00000801 C0260000
<6>GPR24: C025EAC4 00001032 C0260000 C0290000 001CFDE0 00000001 C028E360 C02ED0C0
<4>Call trace: [c00042bc] [c000312c] [c0004a6c] [c0013a6c] [c00033f0] [c0009f38] [c0002f20] [c01e0f78] [00000000] [c0011148] [c0011714] [c001153c] [c0011338] [c00033d4] [c0009f38]
<4>Oops: kernel access of bad area, sig: 11 [#4]
<4>NIP: C000C99C LR: C00042BC SP: C02ECE90 REGS: c02ecde0 TRAP: 0300 Not tainted
<4>MSR: 00001032 EE: 0 PR: 0 FP: 0 ME: 1 IR/DR: 11
<4>DAR: 0F00001C, DSISR: C0000000
<4>TASK = c02e9ae0[1] 'busybox' THREAD: c02ec000
----------------8X----------------------------------------------------------------
^ permalink raw reply
* Re: [PATCH 2.6 1/2] usb/input: Add relayfs support to appletouch driver
From: Dmitry Torokhov @ 2005-12-15 21:38 UTC (permalink / raw)
To: Michael Hanselmann; +Cc: linuxppc-dev, linux-kernel, linux-input, kernel-stuff
In-Reply-To: <20051215212635.GA6195@hansmi.ch>
On 12/15/05, Michael Hanselmann <linux-kernel@hansmi.ch> wrote:
> On Thu, Dec 15, 2005 at 11:50:17AM -0800, Olof Johansson wrote:
> > I think I agree with previous comments regarding debug code in the driv=
er:
> > It's unlikely to ever be used by more than a couple of people at very
> > rare occasions (new hardware releases), and the barrier to using it is
> > still high; new users need to learn how to parse the data anyway. I don=
't
> > see a reason to include this in mainline.
>
> Okay, based on your comments, please drop that patch. How about the one
> to support the Geyser 2 device? Should I do a rediff without relayfs
> support?
>
If you could rediff it without relayfs I would add it to the input
tree. Altough I am not sure if manually unrolling that loop is such a
good idea. Maybe we should leave it to the compiler?
--
Dmitry
^ permalink raw reply
* Re: [PATCH 2.6 1/2] usb/input: Add relayfs support to appletouch driver
From: Michael Hanselmann @ 2005-12-15 21:26 UTC (permalink / raw)
To: Olof Johansson
Cc: linux-input, linuxppc-dev, dtor_core, linux-kernel, kernel-stuff
In-Reply-To: <20051215195017.GA7195@pb15.lixom.net>
On Thu, Dec 15, 2005 at 11:50:17AM -0800, Olof Johansson wrote:
> I think I agree with previous comments regarding debug code in the driver:
> It's unlikely to ever be used by more than a couple of people at very
> rare occasions (new hardware releases), and the barrier to using it is
> still high; new users need to learn how to parse the data anyway. I don't
> see a reason to include this in mainline.
Okay, based on your comments, please drop that patch. How about the one
to support the Geyser 2 device? Should I do a rediff without relayfs
support?
Greets,
Michael
^ permalink raw reply
* [RFC][PATCH] ppc32: Make platform devices being able to assign functions
From: Vitaly Bordug @ 2005-12-15 19:59 UTC (permalink / raw)
To: linuxppc-embedded list
[-- Attachment #1: Type: text/plain, Size: 560 bytes --]
The idea is to modify a .name field on a platform device, when PDs with the
same names are to be used within different drivers, as
<device_name> -> <device_name>:<function>
Corresponding drivers should change the .name in struct device_driver to
reflect upper of course.
Signed-off-by: Vitaly Bordug <vbordug@ru.mvista.com>
This is preliminary version, maybe some issues still need not be cleaned up, and there is no
"generic" platform_notify for board_specific code yet, but I'd like to see opinions concerning this stuff meantime.
--
Sincerely,
Vitaly
[-- Attachment #2: ppc_sys_addon2.patch --]
[-- Type: text/x-patch, Size: 6785 bytes --]
diff --git a/arch/ppc/syslib/ppc_sys.c b/arch/ppc/syslib/ppc_sys.c
index c0b93c4..568b40b 100644
--- a/arch/ppc/syslib/ppc_sys.c
+++ b/arch/ppc/syslib/ppc_sys.c
@@ -15,11 +15,24 @@
*/
#include <linux/string.h>
+#include <linux/bootmem.h>
+#include <linux/platform_device.h>
#include <asm/ppc_sys.h>
int (*ppc_sys_device_fixup) (struct platform_device * pdev);
static int ppc_sys_inited;
+static int ppc_sys_func_inited;
+
+static const char *ppc_sys_func_names[] = {
+ [FUNC_ENABLED] = "dummy",
+ [FUNC_ETH] = "eth",
+ [FUNC_UART] = "uart",
+ [FUNC_HLDC] = "hldc",
+ [FUNC_USB] = "usb",
+ [FUNC_IRDA] = "irda",
+ [FUNC_DISABLED] = "off",
+};
void __init identify_ppc_sys_by_id(u32 id)
{
@@ -38,13 +51,13 @@ void __init identify_ppc_sys_by_id(u32 i
void __init identify_ppc_sys_by_name(char *name)
{
unsigned int i = 0;
- while (ppc_sys_specs[i].ppc_sys_name[0])
- {
+ while (ppc_sys_specs[i].ppc_sys_name[0]) {
if (!strcmp(ppc_sys_specs[i].ppc_sys_name, name))
break;
i++;
}
cur_ppc_sys_spec = &ppc_sys_specs[i];
+
return;
}
@@ -128,6 +141,92 @@ void ppc_sys_device_remove(enum ppc_sys_
}
}
+/*
+ Function assignment stuff.
+ Intended to work as follows:
+ the device name defined in foo_devices.c will be concatenated with :"func",
+ where func is string map of respective function from platfom_device_func enum
+
+ The FUNC_ENABLED function is intended to remove all assignments, making the device to appear
+ in platform bus with unmodified name.
+ */
+
+/*
+ Here we'll replace .name pointers with fixed-lenght strings
+ Hereby, this should be called *before* any func stuff triggeded.
+ */
+void ppc_sys_device_initfunc(void)
+{
+ int i;
+ const char *name;
+ static char new_names[NUM_PPC_SYS_DEVS][BUS_ID_SIZE];
+ enum ppc_sys_devices cur_dev;
+
+ /* If inited yet, do nothing */
+ if (ppc_sys_func_inited)
+ return;
+
+ for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) {
+ if ((cur_dev = cur_ppc_sys_spec->device_list[i]) < 0)
+ continue;
+
+ if (ppc_sys_platform_devices[cur_dev].name) {
+ /*backup name */
+ name = ppc_sys_platform_devices[cur_dev].name;
+ strlcpy(new_names[i], name, BUS_ID_SIZE);
+ ppc_sys_platform_devices[cur_dev].name = new_names[i];
+ }
+ }
+
+ ppc_sys_func_inited =1;
+}
+
+/*The "engine" of the func stuff. Here we either concat specified function string description
+ to the name, or remove it if FUNC_ENABLED parameter is passed here*/
+void ppc_sys_device_setfunc(enum ppc_sys_devices dev,
+ enum platform_device_func func)
+{
+ char *s;
+ char *name = (char *)ppc_sys_platform_devices[dev].name;
+ char tmp[BUS_ID_SIZE];
+
+ if(!ppc_sys_func_inited) {
+ printk (KERN_ERR"Unable to later function - not inited!\n");
+ return;
+ }
+
+ if (ppc_sys_inited) {
+ platform_device_unregister(&ppc_sys_platform_devices[dev]);
+ }
+
+ if ((s = (char *)strchr(name, ':')) != NULL) { /* reassign */
+ /* Either change the name after ':' or remove func modifications */
+ if (func != FUNC_ENABLED)
+ strlcpy(s + 1, ppc_sys_func_names[func], BUS_ID_SIZE);
+ else
+ *s = 0;
+ } else if (func != FUNC_ENABLED) {
+ /* do assignment if it is not just "enable" request */
+ sprintf(tmp, "%s:%s", name, ppc_sys_func_names[func]);
+ strlcpy(name, tmp, BUS_ID_SIZE);
+ }
+
+ if (ppc_sys_inited) {
+ platform_device_register(&ppc_sys_platform_devices[dev]);
+ }
+}
+
+void ppc_sys_device_set_func_all(enum platform_device_func func)
+{
+ enum ppc_sys_devices cur_dev;
+ int i;
+
+ for (i = 0; i < cur_ppc_sys_spec->num_devices; i++) {
+ cur_dev = cur_ppc_sys_spec->device_list[i];
+ ppc_sys_device_setfunc(cur_dev, func);
+ }
+}
+
static int __init ppc_sys_init(void)
{
unsigned int i, dev_id, ret = 0;
diff --git a/include/asm-ppc/mpc10x.h b/include/asm-ppc/mpc10x.h
index 77b1e09..976ad3d 100644
--- a/include/asm-ppc/mpc10x.h
+++ b/include/asm-ppc/mpc10x.h
@@ -165,6 +165,7 @@ enum ppc_sys_devices {
MPC10X_DMA1,
MPC10X_UART0,
MPC10X_UART1,
+ NUM_PPC_SYS_DEVS,
};
int mpc10x_bridge_init(struct pci_controller *hose,
diff --git a/include/asm-ppc/mpc52xx.h b/include/asm-ppc/mpc52xx.h
index e5f80c2..b2cb44f 100644
--- a/include/asm-ppc/mpc52xx.h
+++ b/include/asm-ppc/mpc52xx.h
@@ -49,6 +49,7 @@ enum ppc_sys_devices {
MPC52xx_ATA,
MPC52xx_I2C1,
MPC52xx_I2C2,
+ NUM_PPC_SYS_DEVS,
};
diff --git a/include/asm-ppc/mpc8260.h b/include/asm-ppc/mpc8260.h
index 3214526..6ba69a8 100644
--- a/include/asm-ppc/mpc8260.h
+++ b/include/asm-ppc/mpc8260.h
@@ -83,6 +83,7 @@ enum ppc_sys_devices {
MPC82xx_CPM_SMC2,
MPC82xx_CPM_USB,
MPC82xx_SEC1,
+ NUM_PPC_SYS_DEVS,
};
#ifndef __ASSEMBLY__
diff --git a/include/asm-ppc/mpc83xx.h b/include/asm-ppc/mpc83xx.h
index 7cdf60f..3c23fc4 100644
--- a/include/asm-ppc/mpc83xx.h
+++ b/include/asm-ppc/mpc83xx.h
@@ -108,6 +108,7 @@ enum ppc_sys_devices {
MPC83xx_USB2_DR,
MPC83xx_USB2_MPH,
MPC83xx_MDIO,
+ NUM_PPC_SYS_DEVS,
};
#endif /* CONFIG_83xx */
diff --git a/include/asm-ppc/mpc85xx.h b/include/asm-ppc/mpc85xx.h
index 9d14bae..2a77884 100644
--- a/include/asm-ppc/mpc85xx.h
+++ b/include/asm-ppc/mpc85xx.h
@@ -135,6 +135,7 @@ enum ppc_sys_devices {
MPC85xx_eTSEC4,
MPC85xx_IIC2,
MPC85xx_MDIO,
+ NUM_PPC_SYS_DEVS,
};
/* Internal interrupts are all Level Sensitive, and Positive Polarity */
diff --git a/include/asm-ppc/mpc8xx.h b/include/asm-ppc/mpc8xx.h
index 46f159c..90e3d59 100644
--- a/include/asm-ppc/mpc8xx.h
+++ b/include/asm-ppc/mpc8xx.h
@@ -111,6 +111,7 @@ enum ppc_sys_devices {
MPC8xx_CPM_SMC1,
MPC8xx_CPM_SMC2,
MPC8xx_CPM_USB,
+ NUM_PPC_SYS_DEVS,
};
#ifndef BOARD_CHIP_NAME
diff --git a/include/asm-ppc/ppc_sys.h b/include/asm-ppc/ppc_sys.h
index 83d8c77..02f812f 100644
--- a/include/asm-ppc/ppc_sys.h
+++ b/include/asm-ppc/ppc_sys.h
@@ -72,5 +72,11 @@ extern void *ppc_sys_get_pdata(enum ppc_
/* remove a device from the system */
extern void ppc_sys_device_remove(enum ppc_sys_devices dev);
+/*Function assignment stuff*/
+void ppc_sys_device_initfunc(void);
+void ppc_sys_device_setfunc(enum ppc_sys_devices dev,
+ enum platform_device_func func);
+void ppc_sys_device_set_func_all(enum platform_device_func func);
+
#endif /* __ASM_PPC_SYS_H */
#endif /* __KERNEL__ */
diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h
index 17e336f..346796f 100644
--- a/include/linux/platform_device.h
+++ b/include/linux/platform_device.h
@@ -21,6 +21,16 @@ struct platform_device {
struct resource * resource;
};
+enum platform_device_func {
+ FUNC_ENABLED = 0,
+ FUNC_ETH = 1,
+ FUNC_UART = 2,
+ FUNC_HLDC = 3,
+ FUNC_USB = 4,
+ FUNC_IRDA = 5,
+ FUNC_DISABLED = 6,
+};
+
#define to_platform_device(x) container_of((x), struct platform_device, dev)
extern int platform_device_register(struct platform_device *);
^ permalink raw reply related
* Re: [PATCH 2.6 1/2] usb/input: Add relayfs support to appletouch driver
From: Olof Johansson @ 2005-12-15 19:50 UTC (permalink / raw)
To: Michael Hanselmann
Cc: linux-input, linuxppc-dev, dtor_core, linux-kernel, kernel-stuff
In-Reply-To: <20051214233108.GA20127@hansmi.ch>
On Thu, Dec 15, 2005 at 12:31:08AM +0100, Michael Hanselmann wrote:
> This patch adds support for relayfs to the appletouch driver to make debugging
> easier.
I think I agree with previous comments regarding debug code in the driver:
It's unlikely to ever be used by more than a couple of people at very
rare occasions (new hardware releases), and the barrier to using it is
still high; new users need to learn how to parse the data anyway. I don't
see a reason to include this in mainline.
That aside, comments on the patch below.
> diff -rup linux-2.6.15-rc5.orig/drivers/usb/input/appletouch.c b/drivers/usb/input/appletouch.c
> --- linux-2.6.15-rc5.orig/drivers/usb/input/appletouch.c 2005-12-13 22:44:24.000000000 +0100
> +++ b/drivers/usb/input/appletouch.c 2005-12-15 00:25:09.000000000 +0100
> @@ -6,6 +6,8 @@
> * Copyright (C) 2005 Stelian Pop (stelian@popies.net)
> * Copyright (C) 2005 Frank Arnold (frank@scirocco-5v-turbo.de)
> * Copyright (C) 2005 Peter Osterlund (petero2@telia.com)
> + * Copyright (C) 2005 Parag Warudkar (parag.warudkar@gmail.com)
> + * Copyright (C) 2005 Michael Hanselmann (linux-kernel@hansmi.ch)
> *
> * Thanks to Alex Harper <basilisk@foobox.net> for his inputs.
> *
> @@ -35,6 +37,10 @@
> #include <linux/input.h>
> #include <linux/usb_input.h>
>
> +#if defined(CONFIG_RELAYFS_FS) || defined(CONFIG_RELAYFS_FS_MODULE)
> +#include <linux/relayfs_fs.h>
> +#endif
> +
> /* Apple has powerbooks which have the keyboard with different Product IDs */
> #define APPLE_VENDOR_ID 0x05AC
>
> @@ -73,6 +79,7 @@ MODULE_DEVICE_TABLE (usb, atp_table);
>
> /* maximum pressure this driver will report */
> #define ATP_PRESSURE 300
> +
Whitespace change
> /*
>
> * multiplication factor for the X and Y coordinates.
> * We try to keep the touchpad aspect ratio while still doing only simple
> @@ -124,7 +131,7 @@ struct atp {
> if (debug) printk(format, ##a); \
> } while (0)
>
> -MODULE_AUTHOR("Johannes Berg, Stelian Pop, Frank Arnold");
> +MODULE_AUTHOR("Johannes Berg, Stelian Pop, Frank Arnold, Parag Warudkar, Michael Hanselmann");
> MODULE_DESCRIPTION("Apple PowerBooks USB touchpad driver");
> MODULE_LICENSE("GPL");
>
> @@ -132,6 +139,68 @@ static int debug = 1;
> module_param(debug, int, 0644);
> MODULE_PARM_DESC(debug, "Activate debugging output");
>
> +#if defined(CONFIG_RELAYFS_FS) || defined(CONFIG_RELAYFS_FS_MODULE)
> +static int relayfs;
> +module_param(relayfs, int, 0444);
> +MODULE_PARM_DESC(relayfs, "Activate relayfs support");
> +
> +struct rchan *rch;
> +struct rchan_callbacks *rcb;
static, please.
> +
> +static inline void atp_relayfs_dump(struct atp *dev)
> +{
> + /* "rch" is NULL if relayfs is disabled */
> + if (rch && dev->data) {
> + relay_write(rch, dev->data, dev->urb->actual_length);
> + }
> +}
> +
> +static int appletouch_relayfs_init(void)
> +{
> + // Make sure the variables aren't initialized to some bogus value when
> + // relayfs is disabled
> + rcb = NULL;
> + rch = NULL;
Huh? BSS is initialized to 0, this is unneccessary.
(Also, the comment is C++-style, please use /* */ comments.)
> +
> + if (relayfs) {
Please do:
if (!relayfs)
return 0;
To save indentation.
> + rcb = kmalloc(sizeof(struct rchan_callbacks), GFP_KERNEL);
> + if (!rcb)
> + return -ENOMEM;
> +
> + rcb->subbuf_start = NULL;
> + rcb->buf_mapped = NULL;
> + rcb->buf_unmapped = NULL;
> +
> + rch = relay_open("atpdata", NULL, 256, 256, NULL);
> + if (!rch) {
> + kfree(rcb);
> + return -ENOMEM;
ENOMEM for a failed open? Seems odd to me.
Should you also set rcb = NULL?
> + }
> +
> + printk(KERN_INFO "appletouch: Relayfs enabled.\n");
> + }
> +
> + return 0;
> +}
> +
> +static void appletouch_relayfs_exit(void)
> +{
> + if (rch) {
> + printk(KERN_INFO "appletouch: Relayfs disabled\n");
> + relay_close(rch);
> + rch = NULL;
> + }
> + if (rcb) {
> + kfree(rcb);
> + rcb = NULL;
No need to check arguments to kfree.
> + }
> +}
> +#else
> +static inline void atp_relayfs_dump(struct atp *dev) { }
> +static int appletouch_relayfs_init(void) { return 0; }
> +static void appletouch_relayfs_exit(void) { }
> +#endif
> +
> static int atp_calculate_abs(int *xy_sensors, int nb_sensors, int fact,
> int *z, int *fingers)
> {
> @@ -194,6 +263,8 @@ static void atp_complete(struct urb* urb
> goto exit;
> }
>
> + atp_relayfs_dump(dev);
> +
> /* reorder the sensors values */
> for (i = 0; i < 8; i++) {
> /* X values */
> @@ -297,6 +368,11 @@ exit:
> static int atp_open(struct input_dev *input)
> {
> struct atp *dev = input->private;
> + int result;
> +
> + result = appletouch_relayfs_init();
> + if (result < 0)
> + return result;
Sounds harsh to deny USB open just because relayfs couldn't be setup.
Actually, this way you could just make the init function not return
anything; it doesn't matter if it fails or not -- life will go on.
>
> if (usb_submit_urb(dev->urb, GFP_ATOMIC))
> return -EIO;
> @@ -310,6 +386,8 @@ static void atp_close(struct input_dev *
> struct atp *dev = input->private;
>
> usb_kill_urb(dev->urb);
> + appletouch_relayfs_exit();
> +
> dev->open = 0;
> }
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-dev
^ permalink raw reply
* Re: illegal instructions / irqs disabled warning
From: Kumar Gala @ 2005-12-15 15:47 UTC (permalink / raw)
To: Johannes Berg; +Cc: linuxppc-dev
In-Reply-To: <1134655801.5787.1.camel@localhost>
On Dec 15, 2005, at 8:10 AM, Johannes Berg wrote:
> On Do, 2005-12-15 at 08:04 -0600, Kumar Gala wrote:
>
>> Out of interest, is there a reason you dont handle the emulation in
>> user space?
>
> I'm not even interested in emulating that at all, the kernel just
> checked if it could emulate it (couldn't, so my program died with
> SIGILL)...
> To tell the truth, I was just testing what would happen and wrote a
> buggy program.
Ahh, you should check out LTP its got some tests like this which
generate random instruction images and see what happens. Helps
finding kernel bugs.
- kumar
^ permalink raw reply
* Re: illegal instructions / irqs disabled warning
From: Johannes Berg @ 2005-12-15 14:10 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev
In-Reply-To: <44B795CA-E338-4AAC-937D-F2EEA5E27EB9@kernel.crashing.org>
On Do, 2005-12-15 at 08:04 -0600, Kumar Gala wrote:
> Out of interest, is there a reason you dont handle the emulation in
> user space?
I'm not even interested in emulating that at all, the kernel just
checked if it could emulate it (couldn't, so my program died with
SIGILL)...
To tell the truth, I was just testing what would happen and wrote a
buggy program.
johannes
^ permalink raw reply
* Re: illegal instructions / irqs disabled warning
From: Kumar Gala @ 2005-12-15 14:04 UTC (permalink / raw)
To: Johannes Berg; +Cc: linuxppc-dev
In-Reply-To: <4590.131.234.232.31.1134639886.squirrel@secure.sipsolutions.net>
On Dec 15, 2005, at 3:44 AM, Johannes Berg wrote:
> Paul Mackerras wrote:
>>> So I run across this warning:
>>> [ 2724.595549] Debug: sleeping function called from invalid
>>> context at
>>> arch/ppc/kernel/traps.c:528
>>> [ 2724.595563] in_atomic():0, irqs_disabled():1
>>
>> Hmmm. What kernel version is this? I assume you are using ARCH=ppc,
>> is that right?
>
> 2.6.15-rc5, IIRC (might have been rc1, I currently need to use both
> kernels depending on what I want to do), and yes, ARCH=ppc.
>
>> No, it doesn't mean that. However, if the page isn't in memory,
>> __copy_from_user_inatomic won't try to bring it in if it has been
>> called from an atomic context (i.e. preempt or interrupts disabled).
>
> Good, thanks. So essentially __copy_from_user has the same logic
> (since it
> just calls __copy_from_user_inatomic) but calls might_sleep() to
> show the
> developer what he's doing wrong although it won't actually hurt.
> Right?
>
>> The real question is why we have interrupts disabled in the illegal
>> instruction handler. There was a reason why I wanted interrupts
>> disabled on entry to program_check_exception which I don't recall
>> clearly at the moment, but I think program_check_exception should be
>> doing a local_irq_enable() at some point (and it also shouldn't be
>> trying to emulate instructions for the kernel).
>
> I don't have the code here right now but I did have a userspace
> program
> that it tried to emulate (so I'm not sure if it would try to emulate
> kernel instructions). And it wouldn't emulate that instruction, my
> program
> died with SIGILL, but obviously it still needs to load it to see
> what kind
> of instruction it was.
Out of interest, is there a reason you dont handle the emulation in
user space?
- kumar
^ permalink raw reply
* help needed:Which file is the key file in the ELF(for linux) linker?
From: zengshuai @ 2005-12-15 12:38 UTC (permalink / raw)
To: ppc
//hello.c
int main()
{
int a;
a=1;
}
--------------------------
first time:
#gcc -c -o hello.o hello.c
#ld -o hello.elf hello.o
#file hello.elf
hello.elf: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV),
statically inked, not stripped
second time:
#gcc -c -o hello.o hello.c
#ld -static hello.o /usr/lib/crt1.o /usr/lib/crti.o /usr/
ib/crtn.o /usr/lib/gcc-lib/i386-redhat-linux/3.2.2/crtbegin.o /usr/lib/gcc-lib/
386-redhat-linux/3.2.2/crtend.o -L/usr/lib -lc /usr/lib/gcc-lib/i386-redhat-lin
x/3.2.2/libgcc.a -o hello.elf
#file hello.elf
hello.elf: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV),
for GNU/Linx 2.2.5, statically linked, not stripped
~~~~~~~~~~~~~~~~~~
So,which file is the key file,which cause the change,from elf to linux elf?
How to compile a ELF file using in bareboard and how to compile a ELF file
using in Linux really puzzles me a lot.thanks
------------------------------
我现在使用Sogou.com的2G邮箱了,你也来试试吧!
http://mail.sogou.com/recommend/sogoumail_invite_reg1.jsp?from=sogouinvitation&s_EMAIL=zengshuai%40sogou.com&username=linuxppc-embedded&FullName=linuxppc-embedded&Email=linuxppc-embedded%40ozlabs.org&verify=755eff4e640bdcfc57d93cbd8b0a9cb7
^ permalink raw reply
* USB webcam driver
From: Leena Vachhani @ 2005-12-15 10:14 UTC (permalink / raw)
To: linuxppc-embedded
I am trying to compile USB webcam driver (which works fine with RH 9.0 linux
2.4.20-8 kernel) with montavista linux for IBM PPC405 architecture. The header
file asm/current.h is giving error as "Invalid register name for 'current'".
Header file current.h has only one statement :
register struct task_struct *current asm ("r2");
I don't have any clue what is the problem in this statement. Please help me out.
Thanks
Leena Vachhani
^ permalink raw reply
* Re: 8260 ethernet driver multicast problem
From: Vitaly Bordug @ 2005-12-15 9:59 UTC (permalink / raw)
To: Andy Fleming; +Cc: Robin Mathew, linuxppc-embedded
In-Reply-To: <2750D02C-4FDE-4267-8B60-E1CECDFF55F4@freescale.com>
Andy Fleming wrote:
>
> On Dec 14, 2005, at 09:20, Pantelis Antoniou wrote:
>
>> Robin Mathew wrote:
>>> Hi,
>>> I was encountering a problem with the receipt of multicast packets
>>> from eth
>>> interface in 8260 platform. The issue was traced to the fcc_enet.c
>>> driver. A
>>> stray return in the set_multicast_list function was the culprit.
>>> The following is the changes that I have made-
>>> Index: fcc_enet.c
>>> @@ -1488,7 +1488,6 @@
>>> cep = (struct fcc_enet_private *)dev->priv;
>>> -return;
>>> /* Get pointer to FCC area in parameter RAM.
>>> */
>>> ep = (fcc_enet_t *)dev->base_addr;
>>> Can you please tell me whether there is any issue with setting the
>>> driver in
>>> multicast or promiscous mode. Was this change deliberately done or is it
>>> really a bug?
>>> Thanks in advance,
>>> Robin
>>
>> Robin, what's the kernel version you're using?
>>
>> If you're using 2.6 there's a brand new driver you can use.
>
>
> Has 8260 platform support been pushed out yet?
>
Guess it's not in the stock so far (And I have to update ppc_sys to make the things right), but patches are available here in the list archives.
>
>
> _______________________________________________
> Linuxppc-embedded mailing list
> Linuxppc-embedded@ozlabs.org
> https://ozlabs.org/mailman/listinfo/linuxppc-embedded
>
>
--
Sincerely,
Vitaly
^ permalink raw reply
* Re: illegal instructions / irqs disabled warning
From: Johannes Berg @ 2005-12-15 9:44 UTC (permalink / raw)
To: Paul Mackerras; +Cc: linuxppc-dev
In-Reply-To: <17312.38814.551675.906916@cargo.ozlabs.ibm.com>
Paul Mackerras wrote:
>> So I run across this warning:
>> [ 2724.595549] Debug: sleeping function called from invalid context at
>> arch/ppc/kernel/traps.c:528
>> [ 2724.595563] in_atomic():0, irqs_disabled():1
>
> Hmmm. What kernel version is this? I assume you are using ARCH=ppc,
> is that right?
2.6.15-rc5, IIRC (might have been rc1, I currently need to use both
kernels depending on what I want to do), and yes, ARCH=ppc.
> No, it doesn't mean that. However, if the page isn't in memory,
> __copy_from_user_inatomic won't try to bring it in if it has been
> called from an atomic context (i.e. preempt or interrupts disabled).
Good, thanks. So essentially __copy_from_user has the same logic (since it
just calls __copy_from_user_inatomic) but calls might_sleep() to show the
developer what he's doing wrong although it won't actually hurt. Right?
> The real question is why we have interrupts disabled in the illegal
> instruction handler. There was a reason why I wanted interrupts
> disabled on entry to program_check_exception which I don't recall
> clearly at the moment, but I think program_check_exception should be
> doing a local_irq_enable() at some point (and it also shouldn't be
> trying to emulate instructions for the kernel).
I don't have the code here right now but I did have a userspace program
that it tried to emulate (so I'm not sure if it would try to emulate
kernel instructions). And it wouldn't emulate that instruction, my program
died with SIGILL, but obviously it still needs to load it to see what kind
of instruction it was.
johannes
^ permalink raw reply
* Re: illegal instructions / irqs disabled warning
From: Johannes Berg @ 2005-12-15 9:40 UTC (permalink / raw)
To: Andy Fleming; +Cc: linuxppc-dev
In-Reply-To: <9892D605-1B30-4094-AEEC-9DA6F3B13B05@freescale.com>
Andy Fleming wrote:
> What platform is this on? The copy from user stuff is a bit out of
> my area of expertise, but I've got an implementation of backtrace for
> oprofile running on 85xx. Mostly, it's just a hacked up version of
> the ppc64 patch that was floating around.
ppc32, compiling the kernel with ARCH=ppc still.
johannes
^ permalink raw reply
* help reqd for mpc8260 linux
From: prabha.j @ 2005-12-15 9:22 UTC (permalink / raw)
To: linuxppc-embedded
[-- Attachment #1: Type: text/plain, Size: 1735 bytes --]
Hi All,
I working on custom board(mpc8260) . Now the bootlader is working and when
i dowload the kernel image through u-boot it gives messages as
"Transferring Conrol to Linux" and then nothing comes. I am using
Linux-2.4.25 and eldk toolkit ,both from denx.
My boards memory map is SDRAM starts from 0 and flash starts from
0x30000000. and baudrate is 57600
When i was debugging in
start_here(arch/ppc/kernel/head.S)
It is passing the machine_init and MMU_init(This i have seen by putting
printk and seeing it in log_buf) and then in this code
lis r4,2f@h
ori r4,r4,2f@l
tophys(r4,r4)
li r3,MSR_KERNEL & ~(MSR_IR|MSR_DR)
FIX_SRR1(r3,r5)
mtspr SRR0,r4
mtspr SRR1,r3
SYNC
bl MMU_init_prabha //(This is just a printk function).Till
here its working.
RFI
If i put the printk after this funtion i am not getting anything in the
log_buf. I simply commented the RFI instruction then also i didn't see any
messages.
Can anybody tell me what may be the problem.
Waiting for reply.
Thanks in advance.
Best Regards
Prabha J.
Tata Consultancy Services Limited
Mailto: prabha.j@tcs.com
Website: http://www.tcs.com
Notice: The information contained in this e-mail message and/or attachments to it may contain confidential or privileged information. If you are not the intended recipient, any dissemination, use, review, distribution, printing or copying of the information contained in this e-mail message and/or attachments to it are strictly prohibited. If you have received this communication in error, please notify us by reply e-mail or telephone and immediately and permanently delete the message and any attachments. Thank you
[-- Attachment #2: Type: text/html, Size: 3066 bytes --]
^ 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