Skip to contentSkip to conversation

malta4kec hang in calibrate_delay fix

PATCH In review yshi 7 participants 13 messages Sep 4, 2007 – Sep 5, 2007 MIPS

lore
Share & tools
lore

yshi

author
#0 lore raw

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 */
#1 lore raw

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.

---
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 */
author
#2 lore raw
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 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.

---
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 */
#3 lore raw
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.

#4 lore raw
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.

Thomas.

Signature · 2 lines
Crap can work. Given enough thrust pigs will fly, but it's not necessary a
good idea.                                                [ RFC1925, 2.3 ]
#5 lore raw
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.

#6 lore raw
In reply to Kevin D. Kissell
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

#7 lore raw
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_4KEC should be CPU_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

#8 lore raw
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_4KEC should be CPU_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.

#10 lore raw
In reply to yshi
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

#9 lore raw
In reply to Kevin D. Kissell
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_4KEC should be CPU_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->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.

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

author
#11 lore raw
In reply to Ralf Baechle
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_r2 as 1 in your cpu_features_override.h file. 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

#12 lore raw
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