ppc405 core, VIA VT82C686A chipset, linux_2.4.22_pre5, and IDE DMA woes

3 messages, 2 authors, 2005-02-09 · open the first message on its own page

ppc405 core, VIA VT82C686A chipset, linux_2.4.22_pre5, and IDE DMA woes

From: John F Davis <hidden>
Date: 2005-01-29 18:14:10

Hello

I am trying to get DMA working on a ppc405 core on a custom SOC with IDE 
DMA using a VIA VT82C686A southbridge.  I apologize for the length of this 
note. 

Here is my environment, configuration, attempts at fixing the system, what 
works, and what doesn't.

o  Using linux 2.4.22 pre5 kernel from ppc devel bitkeeper tree.  Using 
cross compiler gcc version 3.2.3

o  On this box non dma IDE works flawlessy with and without 405 data 
caching.

o  DMA IDE works when caching is disabled.  When caching is enabled and 
DMA ide is enabled, the system works for a while and then it gets a Data 
Storage Exception when it tries to do a write.  The exception is usually 
involves writing to a very similar address no matter how and when the 
exception occurs.

o  I am using hdparm to enable and disable the IDE DMA at the command 
line.  I ususally cause the oops by running consecutive hdparm tests from 
two different TTY logins.  If that does not cause it to oops then starting 
X windows, playing a movie from disk and then issuing the hdparm test most 
certainly will.

o  Here are some sample oops messages and ksymoops interpetations.  (There 
is more info after the oops messages.)

# Oops: kernel access of bad area, sig: 11
NIP: A002EC04 XER: 20000000 LR: A002EB84 SP: ACBC5D60 REGS: acbc5cb0 TRAP: 
0800    Tainted: P 
MSR: 00001030 EE: 0 PR: 0 FP: 0 ME: 1 IR/DR: 11
DEAR: 5459545D, ESR: 00800000 
TASK = acbc4000[156] 'xine' Last syscall: 4 
last math 00000000 last altivec 00000000 
PLB0: bear= 0x00000000 acr=   0x00000000 besr=  0x00000000
PLB0 to OPB: bear= 0xc27e3183 besr0= 0xc0000000 besr1= 0x00000000
 
GPR00: 00000000 ACBC5D60 ACBC4000 00000001 00009030 00000001 000009B0 
AB126000 
GPR08: FFFFFFFF AB14F020 54595459 A02E9DDC 24044082 10115790 00000000 
100E10B0 
GPR16: ACBC5EA0 AB0FE000 A007ACA8 ACBC5E08 AEB3F080 AEB3F080 000009B0 
00001000 
GPR24: 00000000 A04D2BA8 00000001 00000000 00001000 000000F0 AB126F60 
A02E9DD4 
Call backtrace:  
00000003 A002E3E4 A003A084 A003A1C0 A003A504 A003AC90 A003B4D8 
A007B000 A002A874 A002AECC A0037564 A000279C 0FECCD18 0EFC53BC 
0FF50A48 0FEC7914 0FC0B408 
 
produces:*************************
quoted
NIP; a002ec04 <kmem_find_general_cachep+6ec/2614>   <=====
quoted
GPR1; acbc5d60 <_end+c925038/12618420>
GPR2; acbc4000 <_end+c9232d8/12618420>
GPR7; ab126000 <_end+ae852d8/12618420>
GPR9; ab14f020 <_end+aeae2f8/12618420>
GPR11; a02e9ddc <_end+490b4/12618420>
GPR16; acbc5ea0 <_end+c925178/12618420>
GPR17; ab0fe000 <_end+ae5d2d8/12618420>
GPR18; a007aca8 <journal_blocks_per_page+4340/87fc>
GPR19; acbc5e08 <_end+c9250e0/12618420>
GPR20; aeb3f080 <_end+e89e358/12618420>
GPR21; aeb3f080 <_end+e89e358/12618420>
GPR25; a04d2ba8 <_end+231e80/12618420>
GPR30; ab126f60 <_end+ae86238/12618420>
GPR31; a02e9dd4 <_end+490ac/12618420>
Trace; 00000003 Before first symbol
Trace; a002e3e4 <kmem_cache_alloc+10/20>
Trace; a003a084 <get_unused_buffer_head+68/c8>
Trace; a003a1c0 <set_bh_page+dc/334>
Trace; a003a504 <create_empty_buffers+24/908>
Trace; a003ac90 <create_empty_buffers+7b0/908>
Trace; a003b4d8 <block_prepare_write+34/a8>
Trace; a007b000 <journal_blocks_per_page+4698/87fc>
Trace; a002a874 <read_cache_page+5f4/aac>
Trace; a002aecc <generic_file_write+1a0/2400>
Trace; a0037564 <default_llseek+490/e10>
Trace; a000279c <set_context+3b4/5e0>
Trace; 0feccd18 Before first symbol
Trace; 0efc53bc Before first symbol
Trace; 0ff50a48 Before first symbol
Trace; 0fec7914 Before first symbol
Trace; 0fc0b408 Before first symbol


5 warnings and 2 errors issued.  Results may not be reliable.

===========================================================

quoted
NIP; a002ec40 <kmem_find_general_cachep+728/2614>   <=====
quoted
GPR1; ab53dd10 <_end+b29cfe8/125fe420>
GPR2; ab53c000 <_end+b29b2d8/125fe420>
GPR7; ad4f0000 <_end+d24f2d8/125fe420>
GPR8; a0270000 <ide_register_driver+9e3c/be50>
GPR9; a02e9ddc <_end+490b4/125fe420>
GPR11; a02e9de4 <_end+490bc/125fe420>
GPR18; a00284d0 <do_generic_file_read+73c/804>
GPR19; ada5ff60 <_end+d7bf238/125fe420>
GPR20; ab53ded8 <_end+b29d1b0/125fe420>
GPR21; a003ea04 <sb_min_blocksize+60/4c8>
GPR25; a052bd04 <_end+28afdc/125fe420>
GPR30; a02e9ddc <_end+490b4/125fe420>
GPR31; a02e9dd4 <_end+490ac/125fe420>
Trace; 00000000 Before first symbol
Trace; a002e3e4 <kmem_cache_alloc+10/20>
Trace; a003a084 <get_unused_buffer_head+68/c8>
Trace; a003a1c0 <set_bh_page+dc/334>
Trace; a003a504 <create_empty_buffers+24/908>
Trace; a003b094 <block_read_full_page+2ac/2d8>
Trace; a003ead0 <sb_min_blocksize+12c/4c8>
Trace; a00272b4 <filemap_fdatawait+414/4dc>
Trace; a0027c40 <grab_cache_page_nowait+22c/380>
Trace; a0028108 <do_generic_file_read+374/804>
Trace; a0028640 <generic_file_read+a8/9d4>
Trace; a0037414 <default_llseek+340/e10>
Trace; a000279c <set_context+3b8/5e4>
Trace; 00000000 Before first symbol
Trace; 10001dcc Before first symbol
Trace; 10002ba4 Before first symbol
Trace; 10003f94 Before first symbol
Trace; 0fee4920 Before first symbol
Trace; 00000000 Before first symbol



=======================================================


Trace; a00190dc <__tasklet_hi_schedule+204/250>
Trace; a002e3e4 <kmem_cache_alloc+10/20>
Trace; a003a084 <get_unused_buffer_head+68/c8>
Trace; a003a1c0 <set_bh_page+dc/334>
Trace; a003a504 <create_empty_buffers+24/908>
Trace; a003b094 <block_read_full_page+2ac/2d8>
Trace; a003ead0 <sb_min_blocksize+12c/4c8>
Trace; a00272b4 <filemap_fdatawait+414/4dc>
Trace; a0027c40 <grab_cache_page_nowait+22c/380>
Trace; a0027f3c <do_generic_file_read+1a8/804>
Trace; a0028640 <generic_file_read+a8/9d4>
Trace; a0037414 <default_llseek+340/e10>
Trace; a000279c <set_context+3b8/5e4>
Trace; 00000000 Before first symbol
Trace; 10001dcc Before first symbol
Trace; 10002ba4 Before first __ide_dma_write
symbol 
Trace; 1__ide_dma_write
0003f94 Before first symbol
Trace; 0fee4920 Before first symbol
Trace; 00000000 Before first symbol


i========================================
# Oops: kernel access of bad area, sig: 11
NIP: A002EC40 XER: 20000000 LR: A002EB84 SP: AF40BD10 REGS: af40bc60 TRAP: 
0800    Tainted: P 
MSR: 00001030 EE: 0 PR: 0 FP: 0 ME: 1 IR/DR: 11
DEAR: 54D954DD, ESR: 00800000 
TASK = af40a000[292] 'hdparm' Last syscall: 3 
last math 00000000 last altivec 00000000 
PLB0: bear= 0x60000000 acr=   0x00000000 besr=  0x00000000
PLB0 to OPB: bear= 0xc27e3183 besr0= 0xc0000000 besr1= 0x00000000
 
GPR00: 00000000 AF40BD10 AF40A000 00000001 00009030 00000001 0000000A 
AC091000 
GPR08: A0270000 A02E9DDC 54D954D9 A02E9DE4 84002082 101EDDE4 00000000 
00000000 
GPR16: 00000000 00000000 A00284D0 ADC0E760 AF40BED8 A003EA04 00000001 
00000000 
GPR24: 00000C00 A045BBA0 00000001 00000000 00000400 000000F0 A02E9DDC 
A02E9DD4 
Call backtrace:  
A045FED4 A002E3E4 A003A084 A003A1C0 A003A504 A003B094 A003EAD0 
A00272B4 A0027C40 A0028108 A0028640 A0037414 A000279C 00000000 
10001DCC 10002BA4 10003F94 0FEE4920 00000000 
# Oops: kernel access of bad area, sig: 11
NIP: A002EC40 XER: 20000000 LR: A002EB84 SP: AF40BD10 REGS: af40bc60 TRAP: 
0800    Tainted: P 
MSR: 00001030 EE: 0 PR: 0 FP: 0 ME: 1 IR/DR: 11
DEAR: 54D954DD, ESR: 00800000 
TASK = af40a000[292] 'hdparm' Last syscall: 3 
last math 00000000 last altivec 00000000 
PLB0: bear= 0x60000000 acr=   0x00000000 besr=  0x00000000
PLB0 to OPB: bear= 0xc27e3183 besr0= 0xc0000000 besr1= 0x00000000
 
GPR00: 00000000 AF40BD10 AF40A000 00000001 00009030 00000001 0000000A 
AC091000 
GPR08: A0270000 A02E9DDC 54D954D9 A02E9DE4 84002082 101EDDE4 00000000 
00000000 
GPR16: 00000000 00000000 A00284D0 ADC0E760 AF40BED8 A003EA04 00000001 
00000000 
GPR24: 00000C00 A045BBA0 00000001 00000000 00000400 000000F0 A02E9DDC 
A02E9DD4 
Call backtrace:  
A045FED4 A002E3E4 A003A084 A003A1C0 A003A504 A003B094 A003EAD0 
A00272B4 A0027C40 A0028108 A0028640 A0037414 A000279C 00000000 
10001DCC 10002BA4 10003F94 0FEE4920 00000000 
quoted
NIP; a002ec40 <kmem_find_general_cachep+728/2614>   <=====
quoted
GPR1; af40bd10 <_end+f16afe8/125fe420>
GPR2; af40a000 <_end+f1692d8/125fe420>
GPR7; ac091000 <_end+bdf02d8/125fe420>
GPR8; a0270000 <ide_register_driver+9e3c/be50>
GPR9; a02e9ddc <_end+490b4/125fe420>
GPR11; a02e9de4 <_end+490bc/125fe420>
GPR18; a00284d0 <do_generic_file_read+73c/804>
GPR19; adc0e760 <_end+d96da38/125fe420>
GPR20; af40bed8 <_end+f16b1b0/125fe420>
GPR21; a003ea04 <sb_min_blocksize+60/4c8>
GPR25; a045bba0 <_end+1bae78/125fe420>
GPR30; a02e9ddc <_end+490b4/125fe420>
GPR31; a02e9dd4 <_end+490ac/125fe420>
Trace; a045fed4 <_end+1bf1ac/125fe420>
Trace; a002e3e4 <kmem_cache_alloc+10/20>
Trace; a003a084 <get_unused_buffer_head+68/c8>
Trace; a003a1c0 <set_bh_page+dc/334>
Trace; a003a504 <create_empty_buffers+24/908>
Trace; a003b094 <block_read_full_page+2ac/2d8>
Trace; a003ead0 <sb_min_blocksize+12c/4c8>
Trace; a00272b4 <filemap_fdatawait+414/4dc>
Trace; a0027c40 <grab_cache_page_nowait+22c/380>
Trace; a0028108 <do_generic_file_read+374/804>
Trace; a0028640 <generic_file_read+a8/9d4>
Trace; a0037414 <default_llseek+340/e10>
Trace; a000279c <set_context+3b8/5e4>
Trace; 00000000 Before first symbol
Trace; 10001dcc Before first symbol
Trace; 10002ba4 Before first symbol
Trace; 10003f94 Before first symbol
Trace; 0fee4920 Before first symbol
Trace; 00000000 Before first symbol

==========================================================

added the debug code to drivers/block/ll_rw_blk.c
#Oops: kernel access of bad area, sig: 11
NIP: A002EC04 XER: 20000000 LR: A002EB84 SP: ACF25D60 REGS: acf25cb0 TRAP: 
0800    Tainted: P 
MSR: 00001030 EE: 0 PR: 0 FP: 0 ME: 1 IR/DR: 11
DEAR: 54D954DD, ESR: 00800000 
TASK = acf24000[139] 'xine' Last syscall: 4 
last math 00000000 last altivec 00000000 
PLB0: bear= 0x60000000 acr=   0x00000000 besr=  0x00000000
PLB0 to OPB: bear= 0xc27e3183 besr0= 0xc0000000 besr1= 0x00000000
 
GPR00: 00000000 ACF25D60 ACF24000 00000001 00009030 00000001 0000042C 
AB9F1000 
GPR08: FFFFFFFF ABA1A020 54D954D9 A02E9DDC 24044082 10115790 00000000 
100E10B0 
GPR16: ACF25EA0 AB9CE000 A007ACA8 ACF25E08 AC58F680 AC58F680 0000042C 
00001000 
GPR24: 00000000 A04EAF68 00000001 00000000 00001000 000000F0 AB9F1F60 
A02E9DD4 
Call backtrace:  
00000003 A002E3E4 A003A084 A003A1C0 A003A504 A003AC90 A003B4D8 
A007B000 A002A874 A002AECC A0037564 A000279C 0FECCD18 0EFC53BC 
0FF50A48 0FEC7914 0FC0B408 

Was so hosed I could not run ksymoops.
================================

 Timing buffered disk reads:  Oops: kernel access of bad area, sig: 11
NIP: A002EC28 XER: 20000000 LR: A002EB84 SP: AE1F7D10 REGS: ae1f7c60 TRAP: 
0800    Tainted: P 
MSR: 00001030 EE: 0 PR: 0 FP: 0 ME: 1 IR/DR: 11
DEAR: 54D954D9, ESR: 00000000 
TASK = ae1f6000[131] 'hdparm' Last syscall: 3 
last math 00000000 last altivec 00000000 
PLB0: bear= 0x60000000 acr=   0x00000000 besr=  0x00000000
PLB0 to OPB: bear= 0xc27e3183 besr0= 0xc0000000 besr1= 0x00000000
 
GPR00: A02E9DE4 AE1F7D10 AE1F6000 00000001 00009030 00000002 00000003 
54D954D9 
GPR08: A0270000 00000000 A0270000 00000001 84002042 10025468 00000000 
00000000 
GPR16: 00000000 00000000 A00284D0 AC3CE760 AE1F7ED8 A003EA1C 00000000 
00000000 
GPR24: 00000C00 A054755C 00000001 00000000 00000400 000000F0 A02E9DDC 
A02E9DD4 
Call backtrace:  
A00190DC A002E3E4 A003A09C A003A1D8 A003A51C A003B0AC A003EAE8 
A00272B4 A0027C40 A0027F3C A0028640 A0037414 A000279C 00000000 
10001DCC 10002BA4 10003F94 0FEE4920 00000000 
Segmentation fault 

Warning (Oops_read): Code line not seen, dumping what data is available

quoted
NIP; a002ec28 <kmem_find_general_cachep+710/2614>   <=====
quoted
GPR0; a02e9de4 <_end+490bc/125fe420>
GPR1; ae1f7d10 <_end+df56fe8/125fe420>
GPR2; ae1f6000 <_end+df552d8/125fe420>
GPR8; a0270000 <ide_register_driver+9e3c/be50>
GPR10; a0270000 <ide_register_driver+9e3c/be50>
GPR18; a00284d0 <do_generic_file_read+73c/804>
GPR19; ac3ce760 <_end+c12da38/125fe420>
GPR20; ae1f7ed8 <_end+df571b0/125fe420>
GPR21; a003ea1c <sb_min_blocksize+60/4c8>
GPR25; a054755c <_end+2a6834/125fe420>
GPR30; a02e9ddc <_end+490b4/125fe420>
GPR31; a02e9dd4 <_end+490ac/125fe420>
Trace; a00190dc <__tasklet_hi_schedule+204/250>
Trace; a002e3e4 <kmem_cache_alloc+10/20>
Trace; a003a09c <get_unused_buffer_head+80/e0>
Trace; a003a1d8 <set_bh_page+dc/334>
Trace; a003a51c <create_empty_buffers+24/908>
Trace; a003b0ac <block_read_full_page+2ac/2d8>
Trace; a003eae8 <sb_min_blocksize+12c/4c8>
Trace; a00272b4 <filemap_fdatawait+414/4dc>
Trace; a0027c40 <grab_cache_page_nowait+22c/380>
Trace; a0027f3c <do_generic_file_read+1a8/804>
Trace; a0028640 <generic_file_read+a8/9d4>
Trace; a0037414 <default_llseek+340/e10>
Trace; a000279c <set_context+3b8/5e4>
Trace; 00000000 Before first symbol
Trace; 10001dcc Before first symbol
Trace; 10002ba4 Before first symbol
Trace; 10003f94 Before first symbol
Trace; 0fee4920 Before first symbol




Here is a dump of the configuration space for the isa bridge and ide 
interface on the VIA chipset in both human readable form and raw form.

 The ISA bridge:
0000:00:01.0 ISA bridge: VIA Technologies, Inc. VT82C686 [Apollo Super 
South] (rev 40)
        Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- 
ParErr- Stepping+ SERR- FastB2B-
        Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- 
<TAbort- <MAbort- >SERR- <PERR-
        Latency: 0
        Interrupt: pin ? routed to IRQ 46
        Capabilities: [c0] Power Management version 2
                Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA 
PME(D0-,D1-,D2-,D3hot-,D3cold-)
                Status: D0 PME-Enable- DSel=0 DScale=0 PME-

and in raw form
0000:00:01.0 ISA bridge: VIA Technologies, Inc. VT82C686 [Apollo Super 
South] (rev 40)
00: 06 11 86 06 87 00 10 02 40 00 01 06 00 00 80 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 c0 00 00 00 00 00 00 00 00 00 00 00
40: 08 01 00 00 00 00 00 00 05 01 84 00 00 00 00 03
50: 0e 00 34 00 0f 90 ba 00 00 04 bf 00 00 00 00 00
60: d8 ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 88 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 01 00 00 00 60 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 42 00 00 00 00 00 00 00 00 00


The IDE Interface:
0000:00:01.1 IDE interface: VIA Technologies, Inc. 
VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (rev 06) (prog-if 
8f [Master SecP SecO PriP PriO])
        Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- 
ParErr- Stepping- SERR- FastB2B-
        Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- 
<TAbort- <MAbort- >SERR- <PERR-
        Latency: 128
        Interrupt: pin ? routed to IRQ 46
        Region 0: I/O ports at fff8 [size=8]
        Region 1: I/O ports at fff4 [size=4]
        Region 2: I/O ports at ffe8 [size=8]
        Region 3: I/O ports at ffe4 [size=4]
        Region 4: I/O ports at ffd0 [size=16]
        Capabilities: [c0] Power Management version 2
                Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA 
PME(D0-,D1-,D2-,D3hot-,D3cold-)
                Status: D0 PME-Enable- DSel=0 DScale=0 PME-


and in raw form
0000:00:01.1 IDE interface: VIA Technologies, Inc. 
VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (rev 06)
00: 06 11 71 05 07 00 90 02 06 8f 01 01 00 80 00 00
10: f9 ff 00 00 f5 ff 00 00 e9 ff 00 00 e5 ff 00 00
20: d1 ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 c0 00 00 00 00 00 00 00 0e 00 00 00
40: 0b 02 c9 3a 08 00 c0 00 a8 a8 a8 20 3f 00 ff 20
50: 07 07 07 e4 04 00 00 00 a8 a8 a8 a8 00 00 00 00
60: 00 02 00 00 00 00 00 00 00 02 00 00 00 00 00 00
70: 02 01 00 00 00 00 00 00 02 01 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 06 00 71 05 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00


Here is a summary of what I have tried in the kernel code.

o  I tried the unaligned buffer patch to see if I had alignment problems. 
I dont.
o  I tried to flush the cache instead of invalidating it in the 
consistent_sync PCI_DMA_FROMDEVICE case.
o  I tried to flush the consistent sync the memory in the ide_build_sglist 
routine in a manner similar to Dan Malek in his 4xx OCP IDE driver.
o  I tried to flush the cache based upon the dma table after the 
ide_build_dmatable call as done in the Amiga One port which also uses the 
VIA chipset.
o  I tried converting the kmalloc calls for the sg_table to non cacheable 
as well.

Here is the cleaned up diff with the debug printk's and my comments 
removed.

diff -Naur orig/arch/ppc/mm/cachemap.c mod/arch/ppc/mm/cachemap.c
--- orig/arch/ppc/mm/cachemap.c 2005-01-29 13:06:41.000000000 -0500
+++ mod/arch/ppc/mm/cachemap.c  2005-01-29 13:04:10.000000000 -0500
@@ -146,10 +146,28 @@
        unsigned long start = (unsigned long)vaddr;
        unsigned long end   = start + size;
 
        switch (direction) {
        case PCI_DMA_NONE:
                BUG();
        case PCI_DMA_FROMDEVICE:        /* invalidate only */
+//             printk("consistent sync: PCI_DMA_FROMDEVICE\n");
+
+#ifdef CONFIG_DEBUG_CONSISTENT_SYNC
+       if (unlikely(start & (L1_CACHE_LINE_SIZE - 1)) || 
+           unlikely(end & (L1_CACHE_LINE_SIZE - 1)))
+       {
+           static unsigned int count = 0;
+           if (++count < 10)
+               //printk(KERN_WARNING
+               printk(
+                   "consistent_sync: 0x%08lx-0x%08lx "
+                   "is not properly aligned, lr 0x%p\n", 
+                   start, end, __builtin_return_address(0));
+       } 
+#endif
+
                flush_dcache_range(start, end);
+//             invalidate_dcache_range(start, end);
 
                break;
        case PCI_DMA_TODEVICE:          /* writeback only */
+//             printk("consistent sync: PCI_DMA_TODEVICE\n");
                clean_dcache_range(start, end);
                break;
        case PCI_DMA_BIDIRECTIONAL:     /* writeback and invalidate */
+//             printk("consistent sync: PCI_DMA_BIDIRECTIONAL\n");
                flush_dcache_range(start, end);
                break;
        }
diff -Naur orig/drivers/ide/ide-dma.c mod/drivers/ide/ide-dma.c
--- orig/drivers/ide/ide-dma.c  2005-01-29 13:06:53.000000000 -0500
+++ mod/drivers/ide/ide-dma.c   2005-01-29 12:55:15.000000000 -0500
 static int ide_build_sglist (ide_hwif_t *hwif, struct request *rq, int 
ddir)
 {
        struct buffer_head *bh;
        unsigned long lastdataend = ~0UL;
        int nents = 0;
 
        if (hwif->sg_dma_active)
                BUG();
 
@@ -270,6 +291,17 @@
                }
 
                if (contig) {
+                       unsigned int size, addr;
+
+                       addr = virt_to_bus(bh->b_data);
+                       size = bh->b_size;
+                       if (ddir)
+                               consistent_sync(bh->b_data, size, 
PCI_DMA_TODEVICE);
+                       else
+                               consistent_sync(bh->b_data, size, 
PCI_DMA_FROMDEVICE);
+
+
+
                        sg[nents - 1].length += bh->b_size;
                        lastdataend += bh->b_size;
                        continue;
@@ -281,10 +313,26 @@
                memset(&sg[nents], 0, sizeof(*sg));
 
                if (bh->b_page) {
+                       unsigned int size, addr;
+
+
+                       addr = virt_to_bus(bh->b_data);
+                       size = bh->b_size;
+                       if (ddir)
+                               consistent_sync(bh->b_data, size, 
PCI_DMA_TODEVICE);
+                       else
+                               consistent_sync(bh->b_data, size, 
PCI_DMA_FROMDEVICE);
+
+
                        sg[nents].page = bh->b_page;
                        sg[nents].offset = bh_offset(bh);
                        lastdataend = bh_phys(bh) + bh->b_size;
+                       //printk("we are using pages\n");
+
+
+
                } else {
+                       printk("we are using datas\n");
                        if ((unsigned long) bh->b_data < PAGE_SIZE)
                                BUG();
 
@@ -300,6 +348,8 @@
                BUG();
 
        hwif->sg_dma_direction = ddir;
        return pci_map_sg(hwif->pci_dev, sg, nents, ddir);
 }
 
@@ -686,9 +751,18 @@
        u8 dma_stat = 0, lba48 = (drive->addressing == 1) ? 1 : 0;
        task_ioreg_t command    = WIN_NOP;
 
        if (!(count = ide_build_dmatable(drive, rq, PCI_DMA_FROMDEVICE)))
                /* try PIO instead of DMA */
                return 1;
+#if 1   /* MAI: make sure RAM's copy of dma table is up to date */
+       /* flush (start, stop) */
+//     printk("ide_dma_read\n");
+//     printk("\tflush_dcache_range start=%x 
size=%x\n",hwif->dmatable_cpu, hwif->dmatable_cpu +(count << 3));
+       flush_dcache_range (hwif->dmatable_cpu, hwif->dmatable_cpu + 
(count << 3));
+#endif
        /* PRD table */
        hwif->OUTL(hwif->dmatable_dma, hwif->dma_prdtable);
        /* specify r/w */
@@ -732,9 +806,18 @@
        u8 dma_stat = 0, lba48  = (drive->addressing == 1) ? 1 : 0;
        task_ioreg_t command    = WIN_NOP;
 
+//     printk("__ide_dma_write\n");
+ 
+
        if (!(count = ide_build_dmatable(drive, rq, PCI_DMA_TODEVICE)))
                /* try PIO instead of DMA */
                return 1;
+#if 1   /* MAI: make sure RAM's copy of dma table is up to date */
+       // This is flushing the virt address table.
+//     printk("ide_dma_write\n");
+//     printk("\tflush_dcache_range start=%x 
size=%x\n",hwif->dmatable_cpu, hwif->dmatable_cpu +(count << 3));
+       flush_dcache_range (hwif->dmatable_cpu, hwif->dmatable_cpu + 
(count << 3));
+#endif
        /* PRD table */
        hwif->OUTL(hwif->dmatable_dma, hwif->dma_prdtable);
        /* specify r/w */
@@ -994,12 +1077,14 @@
                hwif->dmatable_cpu = NULL;
        }
        if (hwif->sg_table) {
-               kfree(hwif->sg_table);
+/* jfd                 kfree(hwif->sg_table);  */
+               pci_free_consistent(NULL, sizeof(struct scatterlist) * 
PRD_ENTRIES, hwif->sg_table,NULL);
                hwif->sg_table = NULL;
        }
        return 1;
 }
 
+
 int ide_release_mmio_dma (ide_hwif_t *hwif)
 {
        if ((hwif->dma_extra) && (hwif->channel == 0))
@@ -1039,11 +1124,26 @@
 
 int ide_allocate_dma_engine (ide_hwif_t *hwif)
 {
+
+       printk("ide_allocate_dma_engine\n");
+
        hwif->dmatable_cpu = pci_alloc_consistent(hwif->pci_dev,
                                                  PRD_ENTRIES * PRD_BYTES,
                                                  &hwif->dmatable_dma);
+
+       printk("\t dma table bus addr %x\n",hwif->dmatable_dma);
+       printk("\t dma table virt addr %x\n",hwif->dmatable_cpu);
+       printk("\t size 
%x*%x=%x\n",PRD_ENTRIES,PRD_BYTES,PRD_ENTRIES*PRD_BYTES);
+
+
+
+       hwif->sg_table = pci_alloc_consistent(NULL,sizeof(struct 
scatterlist) * PRD_ENTRIES,
+                               &hwif->sg_table);
+#if 0
        hwif->sg_table = kmalloc(sizeof(struct scatterlist) * PRD_ENTRIES,
                                GFP_KERNEL);
+jfd 
+#endif

Re: ppc405 core, VIA VT82C686A chipset, linux_2.4.22_pre5, and IDE DMA woes

From: Lawrence E. Bakst <hidden>
Date: 2005-02-09 10:49:22

1. Can you say exactly which 405 core you are using?

2. Is it Xilinx?

3. Have you read all the eratta for your core?

4. How is the VIA VT82C686A hooked to the 405? Via a bus mastering EBC?

Best,

leb


At 1:12 PM -0500 1/29/05, John F Davis wrote:
quoted hunk
Hello

I am trying to get DMA working on a ppc405 core on a custom SOC with IDE
DMA using a VIA VT82C686A southbridge.  I apologize for the length of this
note.

Here is my environment, configuration, attempts at fixing the system, what
works, and what doesn't.

o  Using linux 2.4.22 pre5 kernel from ppc devel bitkeeper tree.  Using
cross compiler gcc version 3.2.3

o  On this box non dma IDE works flawlessy with and without 405 data
caching.

o  DMA IDE works when caching is disabled.  When caching is enabled and
DMA ide is enabled, the system works for a while and then it gets a Data
Storage Exception when it tries to do a write.  The exception is usually
involves writing to a very similar address no matter how and when the
exception occurs.

o  I am using hdparm to enable and disable the IDE DMA at the command
line.  I ususally cause the oops by running consecutive hdparm tests from
two different TTY logins.  If that does not cause it to oops then starting
X windows, playing a movie from disk and then issuing the hdparm test most
certainly will.

o  Here are some sample oops messages and ksymoops interpetations.  (There
is more info after the oops messages.)

# Oops: kernel access of bad area, sig: 11
NIP: A002EC04 XER: 20000000 LR: A002EB84 SP: ACBC5D60 REGS: acbc5cb0 TRAP:
0800    Tainted: P
MSR: 00001030 EE: 0 PR: 0 FP: 0 ME: 1 IR/DR: 11
DEAR: 5459545D, ESR: 00800000
TASK = acbc4000[156] 'xine' Last syscall: 4
last math 00000000 last altivec 00000000
PLB0: bear= 0x00000000 acr=   0x00000000 besr=  0x00000000
PLB0 to OPB: bear= 0xc27e3183 besr0= 0xc0000000 besr1= 0x00000000

GPR00: 00000000 ACBC5D60 ACBC4000 00000001 00009030 00000001 000009B0
AB126000
GPR08: FFFFFFFF AB14F020 54595459 A02E9DDC 24044082 10115790 00000000
100E10B0
GPR16: ACBC5EA0 AB0FE000 A007ACA8 ACBC5E08 AEB3F080 AEB3F080 000009B0
00001000
GPR24: 00000000 A04D2BA8 00000001 00000000 00001000 000000F0 AB126F60
A02E9DD4
Call backtrace: 
00000003 A002E3E4 A003A084 A003A1C0 A003A504 A003AC90 A003B4D8
A007B000 A002A874 A002AECC A0037564 A000279C 0FECCD18 0EFC53BC
0FF50A48 0FEC7914 0FC0B408

produces:*************************
quoted
quoted
NIP; a002ec04 <kmem_find_general_cachep+6ec/2614>   <=====
quoted
quoted
GPR1; acbc5d60 <_end+c925038/12618420>
GPR2; acbc4000 <_end+c9232d8/12618420>
GPR7; ab126000 <_end+ae852d8/12618420>
GPR9; ab14f020 <_end+aeae2f8/12618420>
GPR11; a02e9ddc <_end+490b4/12618420>
GPR16; acbc5ea0 <_end+c925178/12618420>
GPR17; ab0fe000 <_end+ae5d2d8/12618420>
GPR18; a007aca8 <journal_blocks_per_page+4340/87fc>
GPR19; acbc5e08 <_end+c9250e0/12618420>
GPR20; aeb3f080 <_end+e89e358/12618420>
GPR21; aeb3f080 <_end+e89e358/12618420>
GPR25; a04d2ba8 <_end+231e80/12618420>
GPR30; ab126f60 <_end+ae86238/12618420>
GPR31; a02e9dd4 <_end+490ac/12618420>
Trace; 00000003 Before first symbol
Trace; a002e3e4 <kmem_cache_alloc+10/20>
Trace; a003a084 <get_unused_buffer_head+68/c8>
Trace; a003a1c0 <set_bh_page+dc/334>
Trace; a003a504 <create_empty_buffers+24/908>
Trace; a003ac90 <create_empty_buffers+7b0/908>
Trace; a003b4d8 <block_prepare_write+34/a8>
Trace; a007b000 <journal_blocks_per_page+4698/87fc>
Trace; a002a874 <read_cache_page+5f4/aac>
Trace; a002aecc <generic_file_write+1a0/2400>
Trace; a0037564 <default_llseek+490/e10>
Trace; a000279c <set_context+3b4/5e0>
Trace; 0feccd18 Before first symbol
Trace; 0efc53bc Before first symbol
Trace; 0ff50a48 Before first symbol
Trace; 0fec7914 Before first symbol
Trace; 0fc0b408 Before first symbol


5 warnings and 2 errors issued.  Results may not be reliable.

===========================================================

quoted
quoted
NIP; a002ec40 <kmem_find_general_cachep+728/2614>   <=====
quoted
quoted
GPR1; ab53dd10 <_end+b29cfe8/125fe420>
GPR2; ab53c000 <_end+b29b2d8/125fe420>
GPR7; ad4f0000 <_end+d24f2d8/125fe420>
GPR8; a0270000 <ide_register_driver+9e3c/be50>
GPR9; a02e9ddc <_end+490b4/125fe420>
GPR11; a02e9de4 <_end+490bc/125fe420>
GPR18; a00284d0 <do_generic_file_read+73c/804>
GPR19; ada5ff60 <_end+d7bf238/125fe420>
GPR20; ab53ded8 <_end+b29d1b0/125fe420>
GPR21; a003ea04 <sb_min_blocksize+60/4c8>
GPR25; a052bd04 <_end+28afdc/125fe420>
GPR30; a02e9ddc <_end+490b4/125fe420>
GPR31; a02e9dd4 <_end+490ac/125fe420>
Trace; 00000000 Before first symbol
Trace; a002e3e4 <kmem_cache_alloc+10/20>
Trace; a003a084 <get_unused_buffer_head+68/c8>
Trace; a003a1c0 <set_bh_page+dc/334>
Trace; a003a504 <create_empty_buffers+24/908>
Trace; a003b094 <block_read_full_page+2ac/2d8>
Trace; a003ead0 <sb_min_blocksize+12c/4c8>
Trace; a00272b4 <filemap_fdatawait+414/4dc>
Trace; a0027c40 <grab_cache_page_nowait+22c/380>
Trace; a0028108 <do_generic_file_read+374/804>
Trace; a0028640 <generic_file_read+a8/9d4>
Trace; a0037414 <default_llseek+340/e10>
Trace; a000279c <set_context+3b8/5e4>
Trace; 00000000 Before first symbol
Trace; 10001dcc Before first symbol
Trace; 10002ba4 Before first symbol
Trace; 10003f94 Before first symbol
Trace; 0fee4920 Before first symbol
Trace; 00000000 Before first symbol



=======================================================


Trace; a00190dc <__tasklet_hi_schedule+204/250>
Trace; a002e3e4 <kmem_cache_alloc+10/20>
Trace; a003a084 <get_unused_buffer_head+68/c8>
Trace; a003a1c0 <set_bh_page+dc/334>
Trace; a003a504 <create_empty_buffers+24/908>
Trace; a003b094 <block_read_full_page+2ac/2d8>
Trace; a003ead0 <sb_min_blocksize+12c/4c8>
Trace; a00272b4 <filemap_fdatawait+414/4dc>
Trace; a0027c40 <grab_cache_page_nowait+22c/380>
Trace; a0027f3c <do_generic_file_read+1a8/804>
Trace; a0028640 <generic_file_read+a8/9d4>
Trace; a0037414 <default_llseek+340/e10>
Trace; a000279c <set_context+3b8/5e4>
Trace; 00000000 Before first symbol
Trace; 10001dcc Before first symbol
Trace; 10002ba4 Before first __ide_dma_write
symbol
Trace; 1__ide_dma_write
0003f94 Before first symbol
Trace; 0fee4920 Before first symbol
Trace; 00000000 Before first symbol


i========================================
# Oops: kernel access of bad area, sig: 11
NIP: A002EC40 XER: 20000000 LR: A002EB84 SP: AF40BD10 REGS: af40bc60 TRAP:
0800    Tainted: P
MSR: 00001030 EE: 0 PR: 0 FP: 0 ME: 1 IR/DR: 11
DEAR: 54D954DD, ESR: 00800000
TASK = af40a000[292] 'hdparm' Last syscall: 3
last math 00000000 last altivec 00000000
PLB0: bear= 0x60000000 acr=   0x00000000 besr=  0x00000000
PLB0 to OPB: bear= 0xc27e3183 besr0= 0xc0000000 besr1= 0x00000000

GPR00: 00000000 AF40BD10 AF40A000 00000001 00009030 00000001 0000000A
AC091000
GPR08: A0270000 A02E9DDC 54D954D9 A02E9DE4 84002082 101EDDE4 00000000
00000000
GPR16: 00000000 00000000 A00284D0 ADC0E760 AF40BED8 A003EA04 00000001
00000000
GPR24: 00000C00 A045BBA0 00000001 00000000 00000400 000000F0 A02E9DDC
A02E9DD4
Call backtrace: 
A045FED4 A002E3E4 A003A084 A003A1C0 A003A504 A003B094 A003EAD0
A00272B4 A0027C40 A0028108 A0028640 A0037414 A000279C 00000000
10001DCC 10002BA4 10003F94 0FEE4920 00000000
# Oops: kernel access of bad area, sig: 11
NIP: A002EC40 XER: 20000000 LR: A002EB84 SP: AF40BD10 REGS: af40bc60 TRAP:
0800    Tainted: P
MSR: 00001030 EE: 0 PR: 0 FP: 0 ME: 1 IR/DR: 11
DEAR: 54D954DD, ESR: 00800000
TASK = af40a000[292] 'hdparm' Last syscall: 3
last math 00000000 last altivec 00000000
PLB0: bear= 0x60000000 acr=   0x00000000 besr=  0x00000000
PLB0 to OPB: bear= 0xc27e3183 besr0= 0xc0000000 besr1= 0x00000000

GPR00: 00000000 AF40BD10 AF40A000 00000001 00009030 00000001 0000000A
AC091000
GPR08: A0270000 A02E9DDC 54D954D9 A02E9DE4 84002082 101EDDE4 00000000
00000000
GPR16: 00000000 00000000 A00284D0 ADC0E760 AF40BED8 A003EA04 00000001
00000000
GPR24: 00000C00 A045BBA0 00000001 00000000 00000400 000000F0 A02E9DDC
A02E9DD4
Call backtrace: 
A045FED4 A002E3E4 A003A084 A003A1C0 A003A504 A003B094 A003EAD0
A00272B4 A0027C40 A0028108 A0028640 A0037414 A000279C 00000000
10001DCC 10002BA4 10003F94 0FEE4920 00000000
quoted
quoted
NIP; a002ec40 <kmem_find_general_cachep+728/2614>   <=====
quoted
quoted
GPR1; af40bd10 <_end+f16afe8/125fe420>
GPR2; af40a000 <_end+f1692d8/125fe420>
GPR7; ac091000 <_end+bdf02d8/125fe420>
GPR8; a0270000 <ide_register_driver+9e3c/be50>
GPR9; a02e9ddc <_end+490b4/125fe420>
GPR11; a02e9de4 <_end+490bc/125fe420>
GPR18; a00284d0 <do_generic_file_read+73c/804>
GPR19; adc0e760 <_end+d96da38/125fe420>
GPR20; af40bed8 <_end+f16b1b0/125fe420>
GPR21; a003ea04 <sb_min_blocksize+60/4c8>
GPR25; a045bba0 <_end+1bae78/125fe420>
GPR30; a02e9ddc <_end+490b4/125fe420>
GPR31; a02e9dd4 <_end+490ac/125fe420>
Trace; a045fed4 <_end+1bf1ac/125fe420>
Trace; a002e3e4 <kmem_cache_alloc+10/20>
Trace; a003a084 <get_unused_buffer_head+68/c8>
Trace; a003a1c0 <set_bh_page+dc/334>
Trace; a003a504 <create_empty_buffers+24/908>
Trace; a003b094 <block_read_full_page+2ac/2d8>
Trace; a003ead0 <sb_min_blocksize+12c/4c8>
Trace; a00272b4 <filemap_fdatawait+414/4dc>
Trace; a0027c40 <grab_cache_page_nowait+22c/380>
Trace; a0028108 <do_generic_file_read+374/804>
Trace; a0028640 <generic_file_read+a8/9d4>
Trace; a0037414 <default_llseek+340/e10>
Trace; a000279c <set_context+3b8/5e4>
Trace; 00000000 Before first symbol
Trace; 10001dcc Before first symbol
Trace; 10002ba4 Before first symbol
Trace; 10003f94 Before first symbol
Trace; 0fee4920 Before first symbol
Trace; 00000000 Before first symbol

==========================================================

added the debug code to drivers/block/ll_rw_blk.c
#Oops: kernel access of bad area, sig: 11
NIP: A002EC04 XER: 20000000 LR: A002EB84 SP: ACF25D60 REGS: acf25cb0 TRAP:
0800    Tainted: P
MSR: 00001030 EE: 0 PR: 0 FP: 0 ME: 1 IR/DR: 11
DEAR: 54D954DD, ESR: 00800000
TASK = acf24000[139] 'xine' Last syscall: 4
last math 00000000 last altivec 00000000
PLB0: bear= 0x60000000 acr=   0x00000000 besr=  0x00000000
PLB0 to OPB: bear= 0xc27e3183 besr0= 0xc0000000 besr1= 0x00000000

GPR00: 00000000 ACF25D60 ACF24000 00000001 00009030 00000001 0000042C
AB9F1000
GPR08: FFFFFFFF ABA1A020 54D954D9 A02E9DDC 24044082 10115790 00000000
100E10B0
GPR16: ACF25EA0 AB9CE000 A007ACA8 ACF25E08 AC58F680 AC58F680 0000042C
00001000
GPR24: 00000000 A04EAF68 00000001 00000000 00001000 000000F0 AB9F1F60
A02E9DD4
Call backtrace: 
00000003 A002E3E4 A003A084 A003A1C0 A003A504 A003AC90 A003B4D8
A007B000 A002A874 A002AECC A0037564 A000279C 0FECCD18 0EFC53BC
0FF50A48 0FEC7914 0FC0B408

Was so hosed I could not run ksymoops.
================================

Timing buffered disk reads:  Oops: kernel access of bad area, sig: 11
NIP: A002EC28 XER: 20000000 LR: A002EB84 SP: AE1F7D10 REGS: ae1f7c60 TRAP:
0800    Tainted: P
MSR: 00001030 EE: 0 PR: 0 FP: 0 ME: 1 IR/DR: 11
DEAR: 54D954D9, ESR: 00000000
TASK = ae1f6000[131] 'hdparm' Last syscall: 3
last math 00000000 last altivec 00000000
PLB0: bear= 0x60000000 acr=   0x00000000 besr=  0x00000000
PLB0 to OPB: bear= 0xc27e3183 besr0= 0xc0000000 besr1= 0x00000000

GPR00: A02E9DE4 AE1F7D10 AE1F6000 00000001 00009030 00000002 00000003
54D954D9
GPR08: A0270000 00000000 A0270000 00000001 84002042 10025468 00000000
00000000
GPR16: 00000000 00000000 A00284D0 AC3CE760 AE1F7ED8 A003EA1C 00000000
00000000
GPR24: 00000C00 A054755C 00000001 00000000 00000400 000000F0 A02E9DDC
A02E9DD4
Call backtrace: 
A00190DC A002E3E4 A003A09C A003A1D8 A003A51C A003B0AC A003EAE8
A00272B4 A0027C40 A0027F3C A0028640 A0037414 A000279C 00000000
10001DCC 10002BA4 10003F94 0FEE4920 00000000
Segmentation fault

Warning (Oops_read): Code line not seen, dumping what data is available

quoted
quoted
NIP; a002ec28 <kmem_find_general_cachep+710/2614>   <=====
quoted
quoted
GPR0; a02e9de4 <_end+490bc/125fe420>
GPR1; ae1f7d10 <_end+df56fe8/125fe420>
GPR2; ae1f6000 <_end+df552d8/125fe420>
GPR8; a0270000 <ide_register_driver+9e3c/be50>
GPR10; a0270000 <ide_register_driver+9e3c/be50>
GPR18; a00284d0 <do_generic_file_read+73c/804>
GPR19; ac3ce760 <_end+c12da38/125fe420>
GPR20; ae1f7ed8 <_end+df571b0/125fe420>
GPR21; a003ea1c <sb_min_blocksize+60/4c8>
GPR25; a054755c <_end+2a6834/125fe420>
GPR30; a02e9ddc <_end+490b4/125fe420>
GPR31; a02e9dd4 <_end+490ac/125fe420>
Trace; a00190dc <__tasklet_hi_schedule+204/250>
Trace; a002e3e4 <kmem_cache_alloc+10/20>
Trace; a003a09c <get_unused_buffer_head+80/e0>
Trace; a003a1d8 <set_bh_page+dc/334>
Trace; a003a51c <create_empty_buffers+24/908>
Trace; a003b0ac <block_read_full_page+2ac/2d8>
Trace; a003eae8 <sb_min_blocksize+12c/4c8>
Trace; a00272b4 <filemap_fdatawait+414/4dc>
Trace; a0027c40 <grab_cache_page_nowait+22c/380>
Trace; a0027f3c <do_generic_file_read+1a8/804>
Trace; a0028640 <generic_file_read+a8/9d4>
Trace; a0037414 <default_llseek+340/e10>
Trace; a000279c <set_context+3b8/5e4>
Trace; 00000000 Before first symbol
Trace; 10001dcc Before first symbol
Trace; 10002ba4 Before first symbol
Trace; 10003f94 Before first symbol
Trace; 0fee4920 Before first symbol




Here is a dump of the configuration space for the isa bridge and ide
interface on the VIA chipset in both human readable form and raw form.

The ISA bridge:
0000:00:01.0 ISA bridge: VIA Technologies, Inc. VT82C686 [Apollo Super
South] (rev 40)
       Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
ParErr- Stepping+ SERR- FastB2B-
       Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort-
<TAbort- <MAbort- >SERR- <PERR-
       Latency: 0
       Interrupt: pin ? routed to IRQ 46
       Capabilities: [c0] Power Management version 2
               Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA
PME(D0-,D1-,D2-,D3hot-,D3cold-)
               Status: D0 PME-Enable- DSel=0 DScale=0 PME-

and in raw form
0000:00:01.0 ISA bridge: VIA Technologies, Inc. VT82C686 [Apollo Super
South] (rev 40)
00: 06 11 86 06 87 00 10 02 40 00 01 06 00 00 80 00
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 c0 00 00 00 00 00 00 00 00 00 00 00
40: 08 01 00 00 00 00 00 00 05 01 84 00 00 00 00 03
50: 0e 00 34 00 0f 90 ba 00 00 04 bf 00 00 00 00 00
60: d8 ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00
70: 00 00 00 00 00 00 00 88 00 00 00 00 00 00 00 00
80: 00 00 00 00 00 01 00 00 00 60 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 42 00 00 00 00 00 00 00 00 00


The IDE Interface:
0000:00:01.1 IDE interface: VIA Technologies, Inc.
VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (rev 06) (prog-if
8f [Master SecP SecO PriP PriO])
       Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop-
ParErr- Stepping- SERR- FastB2B-
       Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort-
<TAbort- <MAbort- >SERR- <PERR-
       Latency: 128
       Interrupt: pin ? routed to IRQ 46
       Region 0: I/O ports at fff8 [size=8]
       Region 1: I/O ports at fff4 [size=4]
       Region 2: I/O ports at ffe8 [size=8]
       Region 3: I/O ports at ffe4 [size=4]
       Region 4: I/O ports at ffd0 [size=16]
       Capabilities: [c0] Power Management version 2
               Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA
PME(D0-,D1-,D2-,D3hot-,D3cold-)
               Status: D0 PME-Enable- DSel=0 DScale=0 PME-


and in raw form
0000:00:01.1 IDE interface: VIA Technologies, Inc.
VT82C586A/B/VT82C686/A/B/VT823x/A/C PIPC Bus Master IDE (rev 06)
00: 06 11 71 05 07 00 90 02 06 8f 01 01 00 80 00 00
10: f9 ff 00 00 f5 ff 00 00 e9 ff 00 00 e5 ff 00 00
20: d1 ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30: 00 00 00 00 c0 00 00 00 00 00 00 00 0e 00 00 00
40: 0b 02 c9 3a 08 00 c0 00 a8 a8 a8 20 3f 00 ff 20
50: 07 07 07 e4 04 00 00 00 a8 a8 a8 a8 00 00 00 00
60: 00 02 00 00 00 00 00 00 00 02 00 00 00 00 00 00
70: 02 01 00 00 00 00 00 00 02 01 00 00 00 00 00 00
80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
c0: 01 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00
d0: 06 00 71 05 00 00 00 00 00 00 00 00 00 00 00 00
e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00


Here is a summary of what I have tried in the kernel code.

o  I tried the unaligned buffer patch to see if I had alignment problems.
I dont.
o  I tried to flush the cache instead of invalidating it in the
consistent_sync PCI_DMA_FROMDEVICE case.
o  I tried to flush the consistent sync the memory in the ide_build_sglist
routine in a manner similar to Dan Malek in his 4xx OCP IDE driver.
o  I tried to flush the cache based upon the dma table after the
ide_build_dmatable call as done in the Amiga One port which also uses the
VIA chipset.
o  I tried converting the kmalloc calls for the sg_table to non cacheable
as well.

Here is the cleaned up diff with the debug printk's and my comments
removed.

diff -Naur orig/arch/ppc/mm/cachemap.c mod/arch/ppc/mm/cachemap.c
--- orig/arch/ppc/mm/cachemap.c 2005-01-29 13:06:41.000000000 -0500
+++ mod/arch/ppc/mm/cachemap.c  2005-01-29 13:04:10.000000000 -0500
@@ -146,10 +146,28 @@
       unsigned long start = (unsigned long)vaddr;
       unsigned long end   = start + size;

       switch (direction) {
       case PCI_DMA_NONE:
               BUG();
       case PCI_DMA_FROMDEVICE:        /* invalidate only */
+//             printk("consistent sync: PCI_DMA_FROMDEVICE\n");
+
+#ifdef CONFIG_DEBUG_CONSISTENT_SYNC
+       if (unlikely(start & (L1_CACHE_LINE_SIZE - 1)) ||
+           unlikely(end & (L1_CACHE_LINE_SIZE - 1)))
+       {
+           static unsigned int count = 0;
+           if (++count < 10)
+               //printk(KERN_WARNING
+               printk(
+                   "consistent_sync: 0x%08lx-0x%08lx "
+                   "is not properly aligned, lr 0x%p\n",
+                   start, end, __builtin_return_address(0));
+       }
+#endif
+
               flush_dcache_range(start, end);
+//             invalidate_dcache_range(start, end);

               break;
       case PCI_DMA_TODEVICE:          /* writeback only */
+//             printk("consistent sync: PCI_DMA_TODEVICE\n");
               clean_dcache_range(start, end);
               break;
       case PCI_DMA_BIDIRECTIONAL:     /* writeback and invalidate */
+//             printk("consistent sync: PCI_DMA_BIDIRECTIONAL\n");
               flush_dcache_range(start, end);
               break;
       }
diff -Naur orig/drivers/ide/ide-dma.c mod/drivers/ide/ide-dma.c
--- orig/drivers/ide/ide-dma.c  2005-01-29 13:06:53.000000000 -0500
+++ mod/drivers/ide/ide-dma.c   2005-01-29 12:55:15.000000000 -0500
static int ide_build_sglist (ide_hwif_t *hwif, struct request *rq, int
ddir)
{
       struct buffer_head *bh;
       unsigned long lastdataend = ~0UL;
       int nents = 0;

       if (hwif->sg_dma_active)
               BUG();
@@ -270,6 +291,17 @@
               }

               if (contig) {
+                       unsigned int size, addr;
+
+                       addr = virt_to_bus(bh->b_data);
+                       size = bh->b_size;
+                       if (ddir)
+                               consistent_sync(bh->b_data, size,
PCI_DMA_TODEVICE);
+                       else
+                               consistent_sync(bh->b_data, size,
PCI_DMA_FROMDEVICE);
+
+
+
                       sg[nents - 1].length += bh->b_size;
                       lastdataend += bh->b_size;
                       continue;
@@ -281,10 +313,26 @@
               memset(&sg[nents], 0, sizeof(*sg));

               if (bh->b_page) {
+                       unsigned int size, addr;
+
+
+                       addr = virt_to_bus(bh->b_data);
+                       size = bh->b_size;
+                       if (ddir)
+                               consistent_sync(bh->b_data, size,
PCI_DMA_TODEVICE);
+                       else
+                               consistent_sync(bh->b_data, size,
PCI_DMA_FROMDEVICE);
+
+
                       sg[nents].page = bh->b_page;
                       sg[nents].offset = bh_offset(bh);
                       lastdataend = bh_phys(bh) + bh->b_size;
+                       //printk("we are using pages\n");
+
+
+
               } else {
+                       printk("we are using datas\n");
                       if ((unsigned long) bh->b_data < PAGE_SIZE)
                               BUG();
@@ -300,6 +348,8 @@
               BUG();

       hwif->sg_dma_direction = ddir;
       return pci_map_sg(hwif->pci_dev, sg, nents, ddir);
}
@@ -686,9 +751,18 @@
       u8 dma_stat = 0, lba48 = (drive->addressing == 1) ? 1 : 0;
       task_ioreg_t command    = WIN_NOP;

       if (!(count = ide_build_dmatable(drive, rq, PCI_DMA_FROMDEVICE)))
               /* try PIO instead of DMA */
               return 1;
+#if 1   /* MAI: make sure RAM's copy of dma table is up to date */
+       /* flush (start, stop) */
+//     printk("ide_dma_read\n");
+//     printk("\tflush_dcache_range start=%x
size=%x\n",hwif->dmatable_cpu, hwif->dmatable_cpu +(count << 3));
+       flush_dcache_range (hwif->dmatable_cpu, hwif->dmatable_cpu +
(count << 3));
+#endif
       /* PRD table */
       hwif->OUTL(hwif->dmatable_dma, hwif->dma_prdtable);
       /* specify r/w */
@@ -732,9 +806,18 @@
       u8 dma_stat = 0, lba48  = (drive->addressing == 1) ? 1 : 0;
       task_ioreg_t command    = WIN_NOP;

+//     printk("__ide_dma_write\n");
+
+
       if (!(count = ide_build_dmatable(drive, rq, PCI_DMA_TODEVICE)))
               /* try PIO instead of DMA */
               return 1;
+#if 1   /* MAI: make sure RAM's copy of dma table is up to date */
+       // This is flushing the virt address table.
+//     printk("ide_dma_write\n");
+//     printk("\tflush_dcache_range start=%x
size=%x\n",hwif->dmatable_cpu, hwif->dmatable_cpu +(count << 3));
+       flush_dcache_range (hwif->dmatable_cpu, hwif->dmatable_cpu +
(count << 3));
+#endif
       /* PRD table */
       hwif->OUTL(hwif->dmatable_dma, hwif->dma_prdtable);
       /* specify r/w */
@@ -994,12 +1077,14 @@
               hwif->dmatable_cpu = NULL;
       }
       if (hwif->sg_table) {
-               kfree(hwif->sg_table);
+/* jfd                 kfree(hwif->sg_table);  */
+               pci_free_consistent(NULL, sizeof(struct scatterlist) *
PRD_ENTRIES, hwif->sg_table,NULL);
               hwif->sg_table = NULL;
       }
       return 1;
}

+
int ide_release_mmio_dma (ide_hwif_t *hwif)
{
       if ((hwif->dma_extra) && (hwif->channel == 0))
@@ -1039,11 +1124,26 @@
int ide_allocate_dma_engine (ide_hwif_t *hwif)
{
+
+       printk("ide_allocate_dma_engine\n");
+
       hwif->dmatable_cpu = pci_alloc_consistent(hwif->pci_dev,
                                                 PRD_ENTRIES * PRD_BYTES,
                                                 &hwif->dmatable_dma);
+
+       printk("\t dma table bus addr %x\n",hwif->dmatable_dma);
+       printk("\t dma table virt addr %x\n",hwif->dmatable_cpu);
+       printk("\t size
%x*%x=%x\n",PRD_ENTRIES,PRD_BYTES,PRD_ENTRIES*PRD_BYTES);
+
+
+
+       hwif->sg_table = pci_alloc_consistent(NULL,sizeof(struct
scatterlist) * PRD_ENTRIES,
+                               &hwif->sg_table);
+#if 0
       hwif->sg_table = kmalloc(sizeof(struct scatterlist) * PRD_ENTRIES,
                               GFP_KERNEL);
+jfd
+#endif



_______________________________________________
Linuxppc-embedded mailing list
Linuxppc-embedded@ozlabs.org
https://ozlabs.org/mailman/listinfo/linuxppc-embedded

Re: ppc405 core, VIA VT82C686A chipset, linux_2.4.22_pre5, and IDE DMA woes

From: John F Davis <hidden>
Date: 2005-02-09 20:53:07

"Lawrence E. Bakst" [off-list ref] 
02/09/2005 05:34 AM

To
John F Davis/Raleigh/IBM@ibmus, linuxppc-embedded@ozlabs.org
cc

Subject
Re: ppc405 core, VIA VT82C686A chipset, linux_2.4.22_pre5,      and IDE 
DMA woes






1. Can you say exactly which 405 core you are using?
D4V6

2. Is it Xilinx?
No

3. Have you read all the eratta for your core?
Yes

4. How is the VIA VT82C686A hooked to the 405? Via a bus mastering EBC?

PCI PLB Macro
Best,

leb
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help