Subject: [RFT] 8xx cpm_hostalloc patch was: allow coherent DMA API to work before main page allocator is set up

From: Marcelo Tosatti <[email-masked]>
Date: Sat, 21 May 2005 19:27:13 -0300

Can someone with 8xx using the cpm_uart driver please test 
the attached patch? It should avoid corruption of the pinned
8Mbyte CONFIG_PIN_TLB entry, as noted by Dan. 

On Sat, May 21, 2005 at 05:21:47PM -0400, Dan Malek wrote:
> 
> On May 20, 2005, at 1:51 PM, Marcelo Tosatti wrote:
> 
> >I must be missing something very obvious here, can you explain how
> >did you arrange things in v2.4 such that the console's ->setup
> >method is called _after_ mem_init() ?
> 
> The driver used to use the serial port configuration as left by the
> boot rom until very late into the initialization.  As I have said many
> times in the past, the serial driver went through three different
> levels of configuration.  There was an early configuration that was
> used for kgdb, a later one used by the serial kernel printk, and
> finally a full configuration by the serial driver. 

I have missed your statements about that in the past.

OK, the v2.4 driver is using the dual port RAM: 

        /* Allocate space for two FIFOs.  We can't allocate from host
         * memory yet because vm allocator isn't initialized
         * during this early console init.
         */
        dp_addr = m8xx_cpm_dpalloc(2*EARLY_BUF_SIZE);
        mem_addr = (uint)(&cpmp->cp_dpmem[dp_addr]);

> It's sad that "moving forward" is done at a cost of throwing away
> features that were important. 

Now that I think of it, no v2.6 driver should be calling
dma_alloc_coherent() before mem_init(). I was seeing the problem
because we're still using the old uart driver, which does that, and 
our timer setup routine also.

> is a quick fix, but this further ensures features like pinned TLB
> entries won't work. 

Actually, the quick fix to use bootmem allocator ensures that the 
pinned TLB is _preserved_ (by using a pagetableentry from the consistent 
DMA address space to mark as uncached and invalidate, instead of a pte 
from the kernel direct mapped virtual space which blows away the 8Mbyte
entry - current v2.6 state).

Why do you say that "further ensures that features like pinned TLB 
entries won't work" ? 

If there is really a problem with using the bootmem allocator for 
noncacheable purposes (which I can't see), it should be pretty easy 
to modify cpm_uart to use dpram instead of host bootmem RAM, right?

--- linux-2.6.11.orig/arch/ppc/syslib/m8xx_setup.c	2005-05-20 13:53:17.000000000 -0300
+++ linux-2.6.11/arch/ppc/syslib/m8xx_setup.c	2005-05-20 15:59:24.000000000 -0300
@@ -57,7 +57,7 @@
 extern void m8xx_ide_init(void);
 
 extern unsigned long find_available_memory(void);
-extern void m8xx_cpm_reset(uint cpm_page);
+extern void m8xx_cpm_reset();
 extern void m8xx_wdt_handler_install(bd_t *bp);
 extern void rpxfb_alloc_pages(void);
 extern void cpm_interrupt_init(void);
@@ -70,13 +70,9 @@
 void __init
 m8xx_setup_arch(void)
 {
-	int	cpm_page;
-
-	cpm_page = (int) alloc_bootmem_pages(PAGE_SIZE);
-
 	/* Reset the Communication Processor Module.
 	*/
-	m8xx_cpm_reset(cpm_page);
+	m8xx_cpm_reset();
 
 #ifdef CONFIG_FB_RPX
 	rpxfb_alloc_pages();
--- linux-2.6.11.orig/arch/ppc/8xx_io/commproc.c	2005-05-20 13:53:17.000000000 -0300
+++ linux-2.6.11/arch/ppc/8xx_io/commproc.c	2005-05-22 00:29:42.000000000 -0300
@@ -39,8 +39,6 @@
 #include <asm/tlbflush.h>
 #include <asm/rheap.h>
 
-extern int get_pteptr(struct mm_struct *mm, unsigned long addr, pte_t **ptep);
-
 static void m8xx_cpm_dpinit(void);
 static	uint	host_buffer;	/* One page of host buffer */
 static	uint	host_end;	/* end + 1 */
@@ -111,11 +109,10 @@
 extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
 
 void
-m8xx_cpm_reset(uint bootpage)
+m8xx_cpm_reset(void)
 {
 	volatile immap_t	 *imp;
 	volatile cpm8xx_t	*commproc;
-	pte_t *pte;
 
 	imp = (immap_t *)IMAP_ADDR;
 	commproc = (cpm8xx_t *)&imp->im_cpm;
@@ -143,17 +140,6 @@
 	/* Reclaim the DP memory for our use. */
 	m8xx_cpm_dpinit();
 
-	/* get the PTE for the bootpage */
-	if (!get_pteptr(&init_mm, bootpage, &pte))
-	       panic("get_pteptr failed\n");
-																							
-	/* and make it uncachable */
-	pte_val(*pte) |= _PAGE_NO_CACHE;
-	_tlbie(bootpage);
-
-	host_buffer = bootpage;
-	host_end = host_buffer + PAGE_SIZE;
-
 	/* Tell everyone where the comm processor resides.
 	*/
 	cpmp = (cpm8xx_t *)commproc;