* Re: mmap() frame buffer causes bus error on MIPS ... [not found] <39B5BD14.A8D2F467@mvista.com> @ 2000-09-06 5:48 ` Jun Sun 2000-09-06 21:30 ` Jun Sun 0 siblings, 1 reply; 4+ messages in thread From: Jun Sun @ 2000-09-06 5:48 UTC (permalink / raw) To: linux-fbdev, linux-mips, linux-mips Jun Sun wrote: > > With the help from Attila, I got the latest tdfx framebuffer driver > working on my NEC DDB5476 board. I have console working based on this > driver. > > However, when I try to mmap frame buffer into user land, the mapping is > succesful, but trying to read the buffer causes a bus error. > > I tried to trace the kernel using gdb. fb_mmap() seems to do the right > thing : > > 1) it calls fb->fb_get_fix() to get the buffer address, size, etc. The > values all look fine. The address is physical address, pointing a > mapped PCI memory block. I verified that I can access that address in > gdb. > > 2) for MIPS, fb_mmap() turns off CACHE bit for the page. > > I would imagine when the app tries to read the buffer, a TLB miss is > generated. TLB refill routine probably sets up the right TLB entry, and > the app will try to read again, and get the content. I really can't > think of where the Bus error might occur. > > Does anybody have a clue here? Thanks a lot. > > Jun Did more probing on this. It appears the TLB entry that gets filled is not right, even though the original page entry is generated correctly. See below TLB dump. The original page table still has the same value (not corrupted), and the only explanation is that tlb_refill actually gets the entry from a wrong place. I then tried to decode tlb_refill code but really got lost there. (Is there an explanation about the page table setup?) How could this be? Maybe the pte's are put in the wrong place to begin with? Ralf, please help ... Jun P.S., even though tlb entry is wrong, it does not explain the bus error, because the wrong tlb entry does point to a physical memory area. Hmm, more questions ... ---------------- dump tlb for 0x2ac3d000 : Entry 37 maps address 0x2ac3d000 Index: 37 pgmask=00000000 va=2ac3c000 asid=0000007b [pa=000000 c=0 d=0 v=0 g=0] [pa=2300000 c=2 d=0 v=1 g=0] dump all tlb : Index: 4 pgmask=00000000 va=2abbc000 asid=0000007b [pa=0ff000 c=3 d=0 v=1 g=0] [pa=000000 c=0 d=0 v=0 g=0] Index: 10 pgmask=00000000 va=7fffe000 asid=0000007b [pa=000000 c=0 d=0 v=0 g=0] [pa=0f2000 c=3 d=1 v=1 g=0] Index: 11 pgmask=00000000 va=10052000 asid=0000007b [pa=000000 c=0 d=0 v=0 g=0] [pa=0f0000 c=3 d=1 v=1 g=0] Index: 30 pgmask=00000000 va=00424000 asid=0000007b [pa=0f0000 c=3 d=0 v=1 g=0] [pa=0f0000 c=3 d=0 v=1 g=0] ------------------ Where the pte's are : (gdb) x/32 0x83ca30f0 0x83ca30f0: 0x00000000 0x8c00048f 0x8c001407 0x8c002407 0x83ca3100: 0x8c003407 0x8c004407 0x8c005407 0x8c006407 0x83ca3110: 0x8c007407 0x8c008407 0x8c009407 0x8c00a407 0x83ca3120: 0x8c00b407 0x8c00c407 0x8c00d407 0x8c00e407 0x83ca3130: 0x8c00f407 0x8c010407 0x8c011407 0x8c012407 0x83ca3140: 0x8c013407 0x8c014407 0x8c015407 0x8c016407 0x83ca3150: 0x8c017407 0x8c018407 0x8c019407 0x8c01a407 0x83ca3160: 0x8c01b407 0x8c01c407 0x8c01d407 0x8c01e407 ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: mmap() frame buffer causes bus error on MIPS ... 2000-09-06 5:48 ` mmap() frame buffer causes bus error on MIPS Jun Sun @ 2000-09-06 21:30 ` Jun Sun 2000-09-07 9:20 ` Ralf Baechle 0 siblings, 1 reply; 4+ messages in thread From: Jun Sun @ 2000-09-06 21:30 UTC (permalink / raw) To: linux-fbdev, linux-mips, linux-mips Jun Sun wrote: > > Jun Sun wrote: > > > > With the help from Attila, I got the latest tdfx framebuffer driver > > working on my NEC DDB5476 board. I have console working based on this > > driver. > > > > However, when I try to mmap frame buffer into user land, the mapping is > > succesful, but trying to read the buffer causes a bus error. > > > > I tried to trace the kernel using gdb. fb_mmap() seems to do the right > > thing : > > > > 1) it calls fb->fb_get_fix() to get the buffer address, size, etc. The > > values all look fine. The address is physical address, pointing a > > mapped PCI memory block. I verified that I can access that address in > > gdb. > > > > 2) for MIPS, fb_mmap() turns off CACHE bit for the page. > > > > I would imagine when the app tries to read the buffer, a TLB miss is > > generated. TLB refill routine probably sets up the right TLB entry, and > > the app will try to read again, and get the content. I really can't > > think of where the Bus error might occur. > > > > Does anybody have a clue here? Thanks a lot. > > > > Jun > > Did more probing on this. It appears the TLB entry that gets filled is > not right, even though the original page entry is generated correctly. > See below TLB dump. > This is bogus. The TLB entry is a shifted value (right-shift for 6 bits) of the entry in the page table. That is the reason whe I see two different values. > The original page table still has the same value (not corrupted), and > the only explanation is that tlb_refill actually gets the entry from a > wrong place. I then tried to decode tlb_refill code but really got lost > there. (Is there an explanation about the page table setup?) > > How could this be? Maybe the pte's are put in the wrong place to begin > with? Ralf, please help ... > > Jun > I found the real reason, and had a work-around to make it work for now. However, I am not sure about the right fix. fb_mmap() calls get_fix() to get screen info : fb->fb_get_fix(&fix, PROC_CONSOLE(info), info); fb_mmap() then gets buffer address from fix.smem_start, which is a physical address. It then calls kernel's remap_page_range() with that address, which in turn will generate pte with mk_pte_phys(). In MIPS, mk_pte_phys() is defined as follows : extern inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) { return __pte(((physpage & PAGE_MASK) - PAGE_OFFSET) | pgprot_val(pgprot)); } The problematic part is " - PAGE_OFFSET" (where PAGE_OFFSET is 0x80000000). If "physpage" is a physical address, it should not be substracted by PAGE_OFFSET. This is a bug. On the other hand, I wonder why this bug is there without being caught before (it is so fundamental). If this is not a bug in MIPS kernel, then the fix is in the fb_mmap(), where under __mips__ case, we should add PAGE_OFFSET to the start of buffer address. What is the right fix here? Jun ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: mmap() frame buffer causes bus error on MIPS ... 2000-09-06 21:30 ` Jun Sun @ 2000-09-07 9:20 ` Ralf Baechle 2000-09-07 9:58 ` Ralf Baechle 0 siblings, 1 reply; 4+ messages in thread From: Ralf Baechle @ 2000-09-07 9:20 UTC (permalink / raw) To: Jun Sun; +Cc: linux-fbdev, linux-mips, linux-mips On Wed, Sep 06, 2000 at 02:30:05PM -0700, Jun Sun wrote: > In MIPS, mk_pte_phys() is defined as follows : > > extern inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) > { > return __pte(((physpage & PAGE_MASK) - PAGE_OFFSET) | > pgprot_val(pgprot)); > } > > The problematic part is " - PAGE_OFFSET" (where PAGE_OFFSET is > 0x80000000). If "physpage" is a physical address, it should not be > substracted by PAGE_OFFSET. This is a bug. > > On the other hand, I wonder why this bug is there without being caught > before (it is so fundamental). If this is not a bug in MIPS kernel, > then the fix is in the fb_mmap(), where under __mips__ case, we should > add PAGE_OFFSET to the start of buffer address. The definition should be: extern inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) { return __pte(physpage) | pgprot_val(pgprot); } Masking with PAGE_MASK also seemed to be useless. It's really surprising why it never has been caught. Probably people feed it with the addresses that are tweaked such that sich just work. I'll cook up a patch for this bug. Ralf ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: mmap() frame buffer causes bus error on MIPS ... 2000-09-07 9:20 ` Ralf Baechle @ 2000-09-07 9:58 ` Ralf Baechle 0 siblings, 0 replies; 4+ messages in thread From: Ralf Baechle @ 2000-09-07 9:58 UTC (permalink / raw) To: Jun Sun, linux-fbdev, linux-mips, linux-mips On Thu, Sep 07, 2000 at 11:20:13AM +0200, Ralf Baechle wrote: > The definition should be: > > extern inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) > { > return __pte(physpage) | pgprot_val(pgprot); > } > > Masking with PAGE_MASK also seemed to be useless. > > It's really surprising why it never has been caught. Probably people > feed it with the addresses that are tweaked such that sich just work. > > I'll cook up a patch for this bug. This one has a interesting history in CVS: revision 1.21 date: 1999/07/26 19:42:43; author: harald; state: Exp; lines: +84 -82 The remaining R3000 changes. From now on the CVS will be R3000 aware. R3000 Indigo anyone? :-) which re-establishes a bug which was fixed by: revision 1.16 date: 1998/08/28 23:24:03; author: tsbogend; state: Exp; lines: +2 -2 fixed MAP_NR() second try:-( which I introduced in: revision 1.15 date: 1998/08/25 09:21:59; author: ralf; state: Exp; lines: +148 -70 o Merge with Linux 2.1.116. o New Newport console code. o New G364 console code. which got fixed by: revision 1.13 date: 1998/07/13 23:28:18; author: tsbogend; state: Exp; lines: +1 -1 fixed physical mapping So the original bug is probably as old as the MIPS port itself ... Ouch. Ralf ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2000-09-08 1:45 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <39B5BD14.A8D2F467@mvista.com>
2000-09-06 5:48 ` mmap() frame buffer causes bus error on MIPS Jun Sun
2000-09-06 21:30 ` Jun Sun
2000-09-07 9:20 ` Ralf Baechle
2000-09-07 9:58 ` Ralf Baechle
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox