malta4kec hang in calibrate_delay fix
PATCH 1/1 malta4kec hang in calibrate_delay fix
perfmon2 patch changed timer interrupt handler of malta board. When kernel handles timer interrupt, interrupt handler will read 30 bit of cause register. If this bit is zero, timer interrupt handler will exit, won't really handle interrupt. Because Malta 4kec board's core revision is CoreFPGA-3, this core's cause register doesn't implement 30 bit, so kernel always read zero from this bit. This will cause kernel hang in calibrate_delay.
---b/arch/mips/mips-boards/generic/time.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
---
arch/mips/mips-boards/generic/time.c +0 -0
@@ -136,11 +136,13 @@ irqreturn_t mips_timer_interrupt(int irq
#else /* CONFIG_MIPS_MT_SMTC */
int r2 = cpu_has_mips_r2;- if (handle_perf_irq(r2))
- goto out;
+ if (mips_revision_corid != MIPS_REVISION_CORID_CORE_FPGA3) {
+ if (handle_perf_irq(r2))
+ goto out;
- if (r2 && ((read_c0_cause() & (1 << 30)) == 0))
- goto out;
+ if (r2 && ((read_c0_cause() & (1 << 30)) == 0))
+ goto out;
+ }
if (cpu == 0) {
/*
@@ -294,7 +296,12 @@ void __init plat_timer_setup(struct irqa
{
if (cpu_has_vint)
set_vi_handler(cp0_compare_irq, mips_timer_dispatch);- mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
+
+ if (mips_revision_corid != MIPS_REVISION_CORID_CORE_FPGA3)
+ mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE + cp0_compare_irq;
+ else
+ mips_cpu_timer_irq = MIPS_CPU_IRQ_BASE +
+ CP0_LEGACY_COMPARE_IRQ;
}
/* we are using the cpu counter for timer interrupts */The 4KEc is a MIPS32 Release 2 processor, for which the implementation of the Cause.TI bit (bit 30) is required. You may have a defective board or a bad FPGA bitfile. Please work with your support contacts at MIPS to verify that this is not the case. It may also be that there's something more subtle going on in the interrupt processing, such that the Cause.TI bit is being cleared before it can be sampled by the code you've changed. But while the patch below presumably solves the symptoms of your problem, I really don't think that a kernel hack based on detecting CoreFPA3 is an appropriate solution. I work every day with Malta/CoreFPGA3 bitfiles and have not seen Cause.TI fail to function in any of the Release 2 core bitfiles I've used.
Regards,
Kevin K.
----- Original Message -----
From: "yshi" <[email protected]>
To: <[email protected]>
Sent: Tuesday, September 04, 2007 10:52 AM
Subject: [PATCH] malta4kec hang in calibrate_delay fix
Quoted 51 lines
perfmon2 patch changed timer interrupt handler of malta board. When kernel handles timer interrupt, interrupt handler will read 30 bit of cause register. If this bit is zero, timer interrupt handler will exit, won't really handle interrupt. Because Malta 4kec board's core revision is CoreFPGA-3, this core's cause register doesn't implement 30 bit, so kernel always read zero from this bit. This will cause kernel hang in
calibrate_delay.Signed-off-by Yang Shi <[email protected]>---
b/arch/mips/mips-boards/generic/time.c| 17 ++++++++++++-----1 file changed, 12 insertions(+), 5 deletions(-)---
arch/mips/mips-boards/generic/time.c +12
-5@@ -136,11 +136,13 @@ irqreturn_t mips_timer_interrupt(int irq#else /* CONFIG_MIPS_MT_SMTC */ int r2 = cpu_has_mips_r2; -if (handle_perf_irq (r2)) - goto out; +if (mips_revision_corid !=MIPS_REVISION_CORID_CORE_FPGA3 ) { +if (handle_perf_irq (r2)) + goto out; -if (r2 && ((read_c0_cause () & (1 <<30 )) ==0 )) - goto out; +if (r2 && ((read_c0_cause () & (1 <<30 )) ==0 )) + goto out; + }if (cpu ==0 ) {/* @@ -294,7 +296,12 @@ void __init plat_timer_setup(struct irqa {if (cpu_has_vint)set_vi_handler (cp0_compare_irq, mips_timer_dispatch); - mips_cpu_timer_irq =MIPS_CPU_IRQ_BASE + cp0_compare_irq; + +if (mips_revision_corid !=MIPS_REVISION_CORID_CORE_FPGA3 ) + mips_cpu_timer_irq =MIPS_CPU_IRQ_BASE + cp0_compare_irq; +else + mips_cpu_timer_irq =MIPS_CPU_IRQ_BASE + +CP0_LEGACY_COMPARE_IRQ ; }/* we are using the cpu counter for timer interrupts */
Quoted 10 lines · 在 2007-09-04二的 12:03 +0200,Kevin D. Kissell写道:
The 4KEc is a MIPS32 Release 2 processor, for which the implementation of the Cause.TI bit (bit 30) is required. You may have a defective board or a bad FPGA bitfile. Please work with your support contacts at MIPS to verify that this is not the case. It may also be that there's something more subtle going on in the interrupt processing, such that the Cause.TI bit is being cleared before it can be sampled by the code you've changed. But while the patch below presumably solves the symptoms of your problem, I really don't think that a kernel hack based on detecting CoreFPA3 is an appropriate solution. I work every day with Malta/CoreFPGA3 bitfiles and have not seen Cause.TI fail to function in any of the Release 2 core bitfiles I've used.
My board's core is Release 1 core. So Cause.TI bit always is zero. Maybe I need update this patch to reflect this, i.e add #ifdef to distinguish Release 1 and Release 2. Thanks.
Best Regards,
Yang Shi
Quoted 63 lines
Regards,
Kevin K.
----- Original Message -----
From: "yshi" <[email protected]>
To: <[email protected]>
Sent: Tuesday, September 04, 2007 10:52 AM
Subject: [PATCH] malta4kec hang incalibrate_delayfixQuoted 51 lines
perfmon2 patch changed timer interrupt handler of malta board. When kernel handles timer interrupt, interrupt handler will read 30 bit of cause register. If this bit is zero, timer interrupt handler will exit, won't really handle interrupt. Because Malta 4kec board's core revision is CoreFPGA-3, this core's cause register doesn't implement 30 bit, so kernel always read zero from this bit. This will cause kernel hang in
calibrate_delay.Signed-off-by Yang Shi <[email protected]>---
b/arch/mips/mips-boards/generic/time.c| 17 ++++++++++++-----1 file changed, 12 insertions(+), 5 deletions(-)---
arch/mips/mips-boards/generic/time.c +12
-5@@ -136,11 +136,13 @@ irqreturn_t mips_timer_interrupt(int irq#else /* CONFIG_MIPS_MT_SMTC */ int r2 = cpu_has_mips_r2; -if (handle_perf_irq (r2)) - goto out; +if (mips_revision_corid !=MIPS_REVISION_CORID_CORE_FPGA3 ) { +if (handle_perf_irq (r2)) + goto out; -if (r2 && ((read_c0_cause () & (1 <<30 )) ==0 )) - goto out; +if (r2 && ((read_c0_cause () & (1 <<30 )) ==0 )) + goto out; + }if (cpu ==0 ) {/* @@ -294,7 +296,12 @@ void __init plat_timer_setup(struct irqa {if (cpu_has_vint)set_vi_handler (cp0_compare_irq, mips_timer_dispatch); - mips_cpu_timer_irq =MIPS_CPU_IRQ_BASE + cp0_compare_irq; + +if (mips_revision_corid !=MIPS_REVISION_CORID_CORE_FPGA3 ) + mips_cpu_timer_irq =MIPS_CPU_IRQ_BASE + cp0_compare_irq; +else + mips_cpu_timer_irq =MIPS_CPU_IRQ_BASE + +CP0_LEGACY_COMPARE_IRQ ; }/* we are using the cpu counter for timer interrupts */
Quoted 12 lines · 在 2007-09-04二的 12:03 +0200,Kevin D. Kissell写道:
Quoted 10 lines
The 4KEc is a MIPS32 Release 2 processor, for which the implementation of the Cause.TI bit (bit 30) is required. You may have a defective board or a bad FPGA bitfile. Please work with your support contacts at MIPS to verify that this is not the case. It may also be that there's something more subtle going on in the interrupt processing, such that the Cause.TI bit is being cleared before it can be sampled by the code you've changed. But while the patch below presumably solves the symptoms of your problem, I really don't think that a kernel hack based on detecting CoreFPA3 is an appropriate solution. I work every day with Malta/CoreFPGA3 bitfiles and have not seen Cause.TI fail to function in any of the Release 2 core bitfiles I've used.
Quoted 3 lines
My board's core is Release 1 core. So Cause.TI bit always is zero. Maybe I need update this patch to reflect this, i.e add #ifdef to distinguish Release 1 and Release 2. Thanks.
In that case, your core is a 4Kc and not a 4KEc. The "r2" value in the code you're looking at should therefore be zero. I don't have the rest of the kernel tree you're using in front of me, but I can't help but suspect that either cpu_has_mips_r2 has a broken definition, or that handle_iperf_irq() isn't correctly setting its return value if the r2 argument is zero. There should in principle be no need to add more #ifdefs than there already are in the code in question.
Regards,
Kevin K.
Thomas Bogendoerfer
maintainerQuoted 1 line
In that case, your core is a 4Kc and not a 4KEc. The "r2" value in the
does that mean all 4KEc must support MIPS32R2 ? TI claims to use an 4KEc core for their AR7/UR8 SoCs, but they only support MIPS32R1.
Thomas.
Signature · 2 lines
Crap can work. Given enough thrust pigs will fly, but it's not necessary a good idea. [ RFC1925, 2.3 ]
Quoted 4 lines
Quoted 1 line
In that case, your core is a 4Kc and not a 4KEc. The "r2" value in the
does that mean all 4KEc must support MIPS32R2 ? TI claims to use an 4KEc core for their AR7/UR8 SoCs, but they only support MIPS32R1.
There are two main differences between the 4K and the 4KE: Write-back caches and MIPS32R2. I honestly don't know if it's possible to synthesise a 4KE so as to inhibit the MIPS32R2 features, but it would be a surprising thing to do. I have no idea what TI actually does, but I could imagine, hypothetically, a customer who had done a design based around the original 4K, and who upgraded it to the 4KE, deciding not to upgrade their chip-level testing to cover the Release 2 features, and therefore not wanting to guarantee them for their customers. These things happen. But, again, I have no idea what TI actually does. I *do* know that the 4KE is a Release 2 part.
Regards,
Kevin K.
Quoted 12 lines · Kevin D. Kissell
Quoted 12 lines
??? 2007-09-04?????? 12:03 +0200???Kevin D. Kissell?????????
Quoted 10 lines
The 4KEc is a MIPS32 Release 2 processor, for which the implementation of the Cause.TI bit (bit 30) is required. You may have a defective board or a bad FPGA bitfile. Please work with your support contacts at MIPS to verify that this is not the case. It may also be that there's something more subtle going on in the interrupt processing, such that the Cause.TI bit is being cleared before it can be sampled by the code you've changed. But while the patch below presumably solves the symptoms of your problem, I really don't think that a kernel hack based on detecting CoreFPA3 is an appropriate solution. I work every day with Malta/CoreFPGA3 bitfiles and have not seen Cause.TI fail to function in any of the Release 2 core bitfiles I've used.
Quoted 5 lines
Quoted 3 lines
My board's core is Release 1 core. So Cause.TI bit always is zero. Maybe I need update this patch to reflect this, i.e add #ifdef to distinguish Release 1 and Release 2. Thanks.
In that case, your core is a 4Kc and not a 4KEc.
Not quite true, early revisions of the 4KEc were only release 1. This seems to be a bug in arch/mips/cpu-probe.c:
static inline void cpu_probe_mips(struct cpuinfo_mips *c)
{
decode_configs(c);
switch (c->processor_id & 0xff00) {
case PRID_IMP_4KC:
c->cputype = CPU_4KC;
break;
case PRID_IMP_4KEC:
c->cputype = CPU_4KEC;
break;
case PRID_IMP_4KECR2:
c->cputype = CPU_4KEC;
break;
...The type for PRID_IMP_4KEC should be CPU_4KC.
Thiemo
Quoted 40 lines · Thiemo Seufer
Quoted 13 lines · Kevin D. Kissell
Quoted 13 lines
??? 2007-09-04?????? 12:03 +0200???Kevin D. Kissell?????????
Quoted 11 lines
The 4KEc is a MIPS32 Release 2 processor, for which the implementation of the Cause.TI bit (bit 30) is required. You may have a defective board or a bad FPGA bitfile. Please work with your support contacts at MIPS to verify that this is not the case. It may also be that there's something more subtle going on in the interrupt processing, such that the Cause.TI bit is being cleared before it can be sampled by the code you've changed. But while the patch below presumably solves the symptoms of your problem, I really don't think that a kernel hack based on detecting CoreFPA3 is an appropriate solution. I work every day with Malta/CoreFPGA3 bitfiles and have not seen Cause.TI fail to function in any of the Release 2 core bitfiles I've used.
Quoted 6 lines
Quoted 4 lines
My board's core is Release 1 core. So Cause.TI bit always is zero. Maybe I need update this patch to reflect this, i.e add #ifdef to distinguish Release 1 and Release 2. Thanks.
In that case, your core is a 4Kc and not a 4KEc.
Not quite true, early revisions of the 4KEc were only release 1. This seems to be a bug in
arch/mips/cpu-probe.c:static inline void
cpu_probe_mips(struct cpuinfo_mips *c){ decode_configs(c); switch (c->processor_id & 0xff00) { case PRID_IMP_4KC: c->cputype = CPU_4KC; break; case PRID_IMP_4KEC: c->cputype = CPU_4KEC; break; case PRID_IMP_4KECR2: c->cputype = CPU_4KEC; break; ...
Quoted 3 lines
The type for
PRID_IMP_4KECshould beCPU_4KC.
Maybe the probing code should read the ISA revision level from the AR bits (12:10) of the Config0 register to figure out which revision of the ISA is implemented.
Nigel
Quoted 20 lines
Quoted 20 lines
Quoted 1 line
In that case, your core is a 4Kc and not a 4KEc.
Not quite true, early revisions of the 4KEc were only release 1. This seems to be a bug in
arch/mips/cpu-probe.c:static inline void
cpu_probe_mips(struct cpuinfo_mips *c){ decode_configs(c); switch (c->processor_id & 0xff00) { case PRID_IMP_4KC: c->cputype = CPU_4KC; break; case PRID_IMP_4KEC: c->cputype = CPU_4KEC; break; case PRID_IMP_4KECR2: c->cputype = CPU_4KEC; break;...
Quoted 7 lines
Quoted 3 lines
The type for
PRID_IMP_4KECshould beCPU_4KC.Maybe the probing code should read the ISA revision level from the AR bits (12:10) of the Config0 register to figure out which revision of the ISA is implemented.
It does. c->cputype isn't what needs to be modulated here, it's c->isa_level, which gets decoded as part of decode_configs(), as near as I can tell correctly in the most recent source tree I've got. And it's isa_level that's being tested by the cpu_has_mips32r2 et. al. macros.
Regards,
Kevin K.
Quoted 24 lines · Kevin D. Kissell
Quoted 24 lines
Quoted 23 lines
Quoted 1 line
In that case, your core is a 4Kc and not a 4KEc.
Not quite true, early revisions of the 4KEc were only release 1. This seems to be a bug in
arch/mips/cpu-probe.c:static inline void
cpu_probe_mips(struct cpuinfo_mips *c){ decode_configs(c); switch (c->processor_id & 0xff00) { case PRID_IMP_4KC: c->cputype = CPU_4KC; break; case PRID_IMP_4KEC: c->cputype = CPU_4KEC; break; case PRID_IMP_4KECR2: c->cputype = CPU_4KEC; break;...
The type for
PRID_IMP_4KECshould beCPU_4KC.
Quoted 5 lines
Quoted 3 lines
Maybe the probing code should read the ISA revision level from the AR bits (12:10) of the Config0 register to figure out which revision of the ISA is implemented.
It does.
Indeed.
Quoted 4 lines
c->cputypeisn't what needs to be modulated here, it'sc->isa_level, which gets decoded as part ofdecode_configs(), as near as I can tell correctly in the most recent source tree I've got. And it'sisa_levelthat's being tested by thecpu_has_mips32r2et. al. macros.
Unless it got hardcoded in include/asm-mips/mach-foo/cpu-features-override.h. Maybe Windriver has a local patch which does that by accident.
Thiemo
Quoted 7 lines · yshi
perfmon2 patch changed timer interrupt handler of malta board. When kernel handles timer interrupt, interrupt handler will read 30 bit of cause register. If this bit is zero, timer interrupt handler will exit, won't really handle interrupt. Because Malta 4kec board's core revision is CoreFPGA-3, this core's cause register doesn't implement 30 bit, so kernel always read zero from this bit. This will cause kernel hang in
calibrate_delay.
You seem to have defined cpu_has_mips_r2 as 1 in your cpu_features_override.h file. Classic cut'n'paste error I'd guess :-)
Ralf
Quoted 10 lines · 在 2007-09-04二的 13:44 +0100,Ralf Baechle写道:
Quoted 7 lines · yshi
perfmon2 patch changed timer interrupt handler of malta board. When kernel handles timer interrupt, interrupt handler will read 30 bit of cause register. If this bit is zero, timer interrupt handler will exit, won't really handle interrupt. Because Malta 4kec board's core revision is CoreFPGA-3, this core's cause register doesn't implement 30 bit, so kernel always read zero from this bit. This will cause kernel hang in
calibrate_delay.
Quoted 2 lines
You seem to have defined
cpu_has_mips_r2as 1 in yourcpu_features_override.hfile. Classic cut'n'paste error I'd guess :-)
I double checked the revision of this board's core. The core is Release 2(cpu_has_mips_r2 is 0x40). So I enabled Release 2 in kernel config. But kernel still hangs in calibrate_delay.
I investigated this problem further and found IntCtl register's value is always zero! So this cause that kernel registers timer interrupt handler to the wrong IRQ number, because kernel read IntCtl.IPTI bits to determine timer IRQ number. If I use default IRQ number, kernel will works well. I printed my board information from YAMON as follows:
Compilation time = Jul 4 2006 17:12:50 Board type/revision = 0x02 (Malta) / 0x00 Core board type/revision = 0x09 (CoreFPGA-3) / 0x01 System controller/revision = MIPS SOC-it 101 EC-32 / 1.3 SDR-FW-1:1 FPGA revision = 0x0001 MAC address = 00.d0.a0.00.04.e1 Board S/N = 0000000961 PCI bus frequency = 25 MHz Processor Company ID/options = 0x01 (MIPS Technologies, Inc.) / 0x00 Processor ID/revision = 0x90 (MIPS 4KEc) / 0x68 Endianness = Big CPU/Bus frequency = 33 MHz / 33 MHz Flash memory size = 4 MByte SDRAM size = 32 MByte First free SDRAM address = 0x800b6980
According MIPS32 Release 2 specification, IntCtl.IPTI bits should not be zero, at least 2 and it's readonly. So, is my board defective or an old version? Thanks.
Best Regards,
Yang Shi
Quoted 2 lines
Ralf
Quoted 3 lines · yshi
According MIPS32 Release 2 specification, IntCtl.IPTI bits should not be zero, at least 2 and it's readonly. So, is my board defective or an old version? Thanks.
The IntCtl.IPTI field is initialised by some external signals going
into the core. These signals should be driven by some wrapper code built into the FPGA bitfile. It sounds like you may have an old or misconfigured bitfile. I think the best bet is to contact MIPS support ([email protected]) who can supply you with an updated bitfile if required.
Chris
Signature · 2 lines
Chris Dearman 7200 Cambridge Research Park +44 1223 203108 MIPS Technologies (UK) Waterbeach, Cambs CB25 9TL fax +44 1223 203181