* [PATCH] IP28 fixes
@ 2008-01-12 23:00 Thomas Bogendoerfer
2008-01-14 0:10 ` Ralf Baechle
0 siblings, 1 reply; 4+ messages in thread
From: Thomas Bogendoerfer @ 2008-01-12 23:00 UTC (permalink / raw)
To: linux-mips; +Cc: ralf
- ISA DMA is broken on IP28
- bus error handler improved to not issue bus errors for
speculative accesses to CPU and GIO addresses. We now
treat CSTAT_ADDR and GSTAT_TIME errors as non fatal, when
they are issues via MC error interrupt. For real (non
speculative) bus errors a DBE will be issued, which is
lethal as before. Handling the issue this way gets rid
of decoding instructions
Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
---
arch/mips/Kconfig | 1 +
arch/mips/sgi-ip22/ip28-berr.c | 203 +---------------------------------------
2 files changed, 4 insertions(+), 200 deletions(-)
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 3541402..2996b9f 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -457,6 +457,7 @@ config SGI_IP28
select CSRC_R4K
select DEFAULT_SGI_PARTITION
select DMA_NONCOHERENT
+ select GENERIC_ISA_DMA_SUPPORT_BROKEN
select IRQ_CPU
select HW_HAS_EISA
select I8253
diff --git a/arch/mips/sgi-ip22/ip28-berr.c b/arch/mips/sgi-ip22/ip28-berr.c
index 0ee5be8..b09d7d5 100644
--- a/arch/mips/sgi-ip22/ip28-berr.c
+++ b/arch/mips/sgi-ip22/ip28-berr.c
@@ -299,198 +299,6 @@ static void print_buserr(const struct pt_regs *regs)
}
/*
- * Try to find out, whether the bus error is caused by the instruction
- * at EPC, otherwise we have an asynchronous error.
- *
- * Doc1: "MIPS IV Instruction Set", Rev 3.2 (SGI 007-2597-001)
- * Doc2: "MIPS R10000 Microporcessor User's Manual", Ver 2.0 (SGI 007-2490-001)
- * Doc3: "MIPS R4000 Microporcessor User's Manual", 2nd Ed. (SGI 007-2489-001)
- */
-
-#define JMP_INDEX26_OP 1
-#define JMP_REGISTER_OP 2
-#define JMP_PCREL16_OP 3
-#define BASE_OFFSET_OP 4
-#define BASE_IDXREG_OP 5
-
-/* Match virtual address in an insn with physical error address */
-
-static int match_addr(unsigned paddr, unsigned long vaddr)
-{
- unsigned long uaddr;
-
- if ((vaddr & 0xffffffff80000000L) == 0xffffffff80000000L)
- uaddr = (unsigned) CPHYSADDR(vaddr);
- else if ((vaddr >> 62) == 2)
- uaddr = (unsigned) XPHYSADDR(vaddr);
- else {
- unsigned long eh = vaddr & ~0x1fffL;
-
- eh |= read_c0_entryhi() & 0xff;
- write_c0_entryhi(eh);
- tlb_probe();
- if (read_c0_index() & 0x80000000)
- return 0;
- tlb_read();
- if (vaddr & (1L << PAGE_SHIFT))
- uaddr = (unsigned) read_c0_entrylo1();
- else
- uaddr = (unsigned) read_c0_entrylo0();
- uaddr <<= 6;
- uaddr &= ~PAGE_MASK;
- uaddr |= vaddr & PAGE_MASK;
- }
- return ((uaddr & ~0x7f) == (paddr & ~0x7f));
-}
-
-/* Check, which kind of memory reference is triggered by `insn' */
-
-static int check_special(unsigned insn)
-{
- /* See Doc1, page A-180 */
- unsigned func = insn & 0x3f;
-
- if (8 == func || 8+1 == func) /* JR, JALR */
- return JMP_REGISTER_OP;
-
- return 0;
-}
-
-static int check_regimm(unsigned insn)
-{
- /* See Doc1, page A-180 */
- unsigned rt = (insn >> 19) & 3; /* bits 20..19[..16] */
-
- /* BLTZ, BGEZ, BLTZL, BBGEZL || BLTZAL, BGEZAL, BLTZALL, BBGEZALL */
- if (!rt || 2 == rt)
- return JMP_PCREL16_OP;
-
- return 0;
-}
-
-static int check_cop0(unsigned insn)
-{
- /* See Doc2, pages 287 ff., 187 ff. */
- if ((insn >> 26) == 5*8+7) /* CACHE */
- switch ((insn >> 16) & 0x1f) {
- case Index_Writeback_Inv_D:
- case Hit_Writeback_Inv_D:
- case Index_Writeback_Inv_S:
- case Hit_Writeback_Inv_S:
- return BASE_OFFSET_OP;
- }
- return 0;
-}
-
-static int check_cop1(unsigned insn)
-{
- /* See Doc1, pages B-108 ff. */
- unsigned fmt = (insn >> 21) & 0x1f; /* bits 25..21 */
-
- if (8 == fmt) /* BC1* */
- return JMP_PCREL16_OP;
-
- return 0;
-}
-
-static int check_cop1x(unsigned insn)
-{
- /* See Doc1, pages B-108 ff. */
- switch (insn & 0x3f) {
- case 0: /* LWXC1 */
- case 1: /* LDXC1 */
- case 8: /* SWXC1 */
- case 8+1: /* SDXC1 */
- return BASE_IDXREG_OP;
- }
- return 0;
-}
-
-static int check_plain(unsigned insn)
-{
- /* See Doc1, page A-180 */
- unsigned opcode = insn >> 26;
-
- if (2 == opcode || 3 == opcode) /* J, JAL */
- return JMP_INDEX26_OP;
-
- if ((4 <= opcode && opcode <= 7) || /* BEQ, BNE, BLEZ, BGTZ */
- (4+2*8 <= opcode && opcode <= 7+2*8)) /* BEQL, BNEL, BLEZL, BGTZL */
- return JMP_PCREL16_OP;
-
- if (6*8+3 == opcode) /* PREF */
- return 0;
-
- if (3*8+2 == opcode || 3*8+3 == opcode || /* LDL, LDR */
- 4*8 <= opcode) /* misc. LOAD, STORE */
- return BASE_OFFSET_OP;
-
- return 0;
-}
-
-/* Check, whether the insn at EPC causes a memory access at `paddr' */
-
-static int check_addr_in_insn(unsigned paddr, const struct pt_regs *regs)
-{
- unsigned long epc;
- unsigned insn;
- unsigned long a;
- int typ;
-
- epc = regs->cp0_cause & CAUSEF_BD ? regs->cp0_epc:regs->cp0_epc+4;
-
- /* show_code() from kernel/traps.c */
- if (__get_user(insn, (u32 *)epc))
- return 1;
-
- /* See Doc1, pages A-180, B-108 ff. */
- switch (insn >> 26) {
- case 0:
- typ = check_special(insn);
- break;
- case 1:
- typ = check_regimm(insn);
- break;
- case 2*8: /* COP0 */
- case 5*8+7: /* CACHE */
- typ = check_cop0(insn);
- break;
- case 2*8+1:
- typ = check_cop1(insn);
- break;
- case 2*8+3:
- typ = check_cop1x(insn);
- break;
- default:
- typ = check_plain(insn);
- break;
- }
- switch (typ) {
- case JMP_INDEX26_OP:
- a = (regs->cp0_epc + 4) & ~0xfffffff;
- a |= (insn & 0x3ffffff) << 2;
- return match_addr(paddr, a);
- case JMP_REGISTER_OP:
- a = regs->regs[(insn >> 21) & 0x1f];
- return match_addr(paddr, a);
- case JMP_PCREL16_OP:
- a = regs->cp0_epc + 4 + ((insn & 0xffff) << 2);
- return match_addr(paddr, a);
- case BASE_OFFSET_OP:
- a = regs->regs[(insn >> 21) & 0x1f] + (insn & 0xffff);
- return match_addr(paddr, a);
- case BASE_IDXREG_OP:
- a = regs->regs[(insn >> 21) & 0x1f];
- a += regs->regs[(insn >> 16) & 0x1f];
- return match_addr(paddr, a);
- case 0:
- return 0;
- }
- /* Assume it would be too dangerous to continue ... */
- return 1;
-}
-
-/*
* Check, whether MC's (virtual) DMA address caused the bus error.
* See "Virtual DMA Specification", Draft 1.5, Feb 13 1992, SGI
*/
@@ -594,16 +402,11 @@ static int ip28_be_interrupt(const struct pt_regs *regs)
/* Any state other than "Memory bus error" is fatal. */
if (cpu_err_stat & CPU_ERRMASK & ~SGIMC_CSTAT_ADDR)
- goto mips_be_fatal;
-
- /* GIO errors are fatal */
- if (gio_err_stat & GIO_ERRMASK)
goto mips_be_fatal;
- /* Finding `cpu_err_addr' in the insn at EPC is fatal. */
- if ((cpu_err_stat & CPU_ERRMASK) &&
- check_addr_in_insn(cpu_err_addr, regs))
- goto mips_be_fatal;
+ /* GIO errors other than timeouts are fatal */
+ if (gio_err_stat & GIO_ERRMASK & ~SGIMC_GSTAT_TIME)
+ goto mips_be_fatal;
/*
* Now we have an asynchronous bus error, speculatively or DMA caused.
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH] IP28 fixes
2008-01-12 23:00 [PATCH] IP28 fixes Thomas Bogendoerfer
@ 2008-01-14 0:10 ` Ralf Baechle
2008-01-14 14:24 ` Sergei Shtylyov
0 siblings, 1 reply; 4+ messages in thread
From: Ralf Baechle @ 2008-01-14 0:10 UTC (permalink / raw)
To: Thomas Bogendoerfer; +Cc: linux-mips
On Sun, Jan 13, 2008 at 12:00:51AM +0100, Thomas Bogendoerfer wrote:
> - ISA DMA is broken on IP28
> - bus error handler improved to not issue bus errors for
> speculative accesses to CPU and GIO addresses. We now
> treat CSTAT_ADDR and GSTAT_TIME errors as non fatal, when
> they are issues via MC error interrupt. For real (non
> speculative) bus errors a DBE will be issued, which is
> lethal as before. Handling the issue this way gets rid
> of decoding instructions
>
> Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
Folded into the "[MIPS] IP28 support" patch for 2.6.28.
Thanks,
Ralf
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] IP28 fixes
2008-01-14 0:10 ` Ralf Baechle
@ 2008-01-14 14:24 ` Sergei Shtylyov
2008-01-14 15:21 ` Sergei Shtylyov
0 siblings, 1 reply; 4+ messages in thread
From: Sergei Shtylyov @ 2008-01-14 14:24 UTC (permalink / raw)
To: Ralf Baechle; +Cc: Thomas Bogendoerfer, linux-mips
Ralf Baechle wrote:
>>- ISA DMA is broken on IP28
>>- bus error handler improved to not issue bus errors for
>> speculative accesses to CPU and GIO addresses. We now
>> treat CSTAT_ADDR and GSTAT_TIME errors as non fatal, when
>> they are issues via MC error interrupt. For real (non
>> speculative) bus errors a DBE will be issued, which is
>> lethal as before. Handling the issue this way gets rid
>> of decoding instructions
>>Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
> Folded into the "[MIPS] IP28 support" patch for 2.6.28.
Poor IP32 will have to wait couple of years? ;-)
> Thanks,
> Ralf
WBR, Sergei
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH] IP28 fixes
2008-01-14 14:24 ` Sergei Shtylyov
@ 2008-01-14 15:21 ` Sergei Shtylyov
0 siblings, 0 replies; 4+ messages in thread
From: Sergei Shtylyov @ 2008-01-14 15:21 UTC (permalink / raw)
To: Sergei Shtylyov; +Cc: Ralf Baechle, Thomas Bogendoerfer, linux-mips
I wrote:
>>> - ISA DMA is broken on IP28
>>> - bus error handler improved to not issue bus errors for
>>> speculative accesses to CPU and GIO addresses. We now
>>> treat CSTAT_ADDR and GSTAT_TIME errors as non fatal, when
>>> they are issues via MC error interrupt. For real (non
>>> speculative) bus errors a DBE will be issued, which is
>>> lethal as before. Handling the issue this way gets rid
>>> of decoding instructions
>>> Signed-off-by: Thomas Bogendoerfer <tsbogend@alpha.franken.de>
>> Folded into the "[MIPS] IP28 support" patch for 2.6.28.
> Poor IP32 will have to wait couple of years? ;-)
I meant IP28 of course. 1:1 in typos. :-)
>> Thanks,
>> Ralf
WBR, Sergei
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2008-01-14 15:21 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-01-12 23:00 [PATCH] IP28 fixes Thomas Bogendoerfer
2008-01-14 0:10 ` Ralf Baechle
2008-01-14 14:24 ` Sergei Shtylyov
2008-01-14 15:21 ` Sergei Shtylyov
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox