Subject: Re: NetBSD support PXA255?
To: None <kamalp@acm.org>
From: Hiroyuki Bessho <bsh@grotto.jp>
List: port-arm
Date: 03/14/2005 16:10:01
At Mon, 14 Mar 2005 10:41:34 +0900,
Hiroyuki Bessho wrote:

> 
>   I'm just working on that part of lubbock_machdep.c to use
> pmap_devmap_bootstrap() as seen in other boards' *_machdep.c.
> 

   Here's the diffs for Lubbock.  This is simpler and gives us smaller
diffs to other eval boards.  I'm going to change *_machdep.c for
Samsung's boards in the same way.

   I'm going to commit this unless it conflicts badly with someone's
work based on Lubbock port.  Please let me know if it makes you
unhappy.

Regards,

bsh.

cvs diff: Diffing sys/arch/arm/xscale
Index: sys/arch/arm/xscale/pxa2x0_space.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/xscale/pxa2x0_space.c,v
retrieving revision 1.5
diff -u -u -r1.5 pxa2x0_space.c
--- sys/arch/arm/xscale/pxa2x0_space.c	7 Jun 2004 19:45:22 -0000	1.5
+++ sys/arch/arm/xscale/pxa2x0_space.c	14 Mar 2005 06:57:39 -0000
@@ -175,13 +175,12 @@
 	u_long startpa, endpa, pa;
 	vaddr_t va;
 	pt_entry_t *pte;
+	const struct pmap_devmap	*pd;
 
-	if ((u_long)bpa > (u_long)KERNEL_BASE) {
-		/* Some IO registers (ex. UART ports for console)
-		   are mapped to fixed address by board specific
-		   routine. */
-		*bshp = bpa;
-		return(0);
+	if ((pd = pmap_devmap_find_pa(bpa, size)) != NULL) {
+		/* Device was statically mapped. */
+		*bshp = pd->pd_va + (bpa - pd->pd_pa);
+		return 0;
 	}
 
 	startpa = trunc_page(bpa);
@@ -214,11 +213,18 @@
 void
 pxa2x0_bs_unmap(void *t, bus_space_handle_t bsh, bus_size_t size)
 {
+	vaddr_t	va;
+	vaddr_t	endva;
 
-	if (bsh > (u_long)KERNEL_BASE) 
+	if (pmap_devmap_find_va(bsh, size) != NULL) {
+		/* Device was statically mapped; nothing to do. */
 		return;
+	}
+
+	endva = round_page(bsh + size);
+	va = trunc_page(bsh);
 
-	uvm_km_free(kernel_map, bsh, size);
+	uvm_km_free(kernel_map, va, endva - va);
 }
 
 
cvs diff: Diffing sys/arch/evbarm/lubbock
Index: sys/arch/evbarm/lubbock/lubbock_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/evbarm/lubbock/lubbock_machdep.c,v
retrieving revision 1.5
diff -u -u -r1.5 lubbock_machdep.c
--- sys/arch/evbarm/lubbock/lubbock_machdep.c	26 Feb 2005 10:22:41 -0000	1.5
+++ sys/arch/evbarm/lubbock/lubbock_machdep.c	14 Mar 2005 06:57:39 -0000
@@ -1,7 +1,7 @@
 /*	$NetBSD: lubbock_machdep.c,v 1.5 2005/02/26 10:22:41 bsh Exp $ */
 
 /*
- * Copyright (c) 2002, 2003  Genetec Corporation.  All rights reserved.
+ * Copyright (c) 2002, 2003, 2005  Genetec Corporation.  All rights reserved.
  * Written by Hiroyuki Bessho for Genetec Corporation.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -349,110 +349,57 @@
 /*
  * Mapping table for core kernel memory. These areas are mapped in
  * init time at fixed virtual address with section mappings. 
+ *
+ * Since we map these registers using pmap_devmap_bootstrap() which
+ * calls pmap_map_chunk(), we map registers segment-aligned and
+ * segment-rounded in order to avoid using 2nd page tables.
  */
-struct l1_sec_map {
-	vaddr_t	va;
-	vaddr_t	pa;
-	vsize_t	size;
-	int flags;
-} l1_sec_table[] = {
+#define	_A(a)	((a) & ~L1_S_OFFSET)
+#define	_S(s)	(((s) + L1_S_SIZE - 1) & ~(L1_S_SIZE-1))
+
+static const struct pmap_devmap lubbock_devmap[] = {
     {
 	    LUBBOCK_OBIO_VBASE,
-	    LUBBOCK_OBIO_PBASE,
-	    LUBBOCK_OBIO_SIZE,
-	    PTE_NOCACHE,
+	    _A(LUBBOCK_OBIO_PBASE),
+	    _S(LUBBOCK_OBIO_SIZE),
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE,
     },
     {
 	    LUBBOCK_GPIO_VBASE,
-	    PXA2X0_GPIO_BASE,
-	    PXA2X0_GPIO_SIZE,
-	    PTE_NOCACHE,
+	    _A(PXA2X0_GPIO_BASE),
+	    _S(PXA2X0_GPIO_SIZE),
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE,
     },
     {
 	    LUBBOCK_CLKMAN_VBASE,
-	    PXA2X0_CLKMAN_BASE,
-	    PXA2X0_CLKMAN_SIZE,
-	    PTE_NOCACHE,
+	    _A(PXA2X0_CLKMAN_BASE),
+	    _S(PXA2X0_CLKMAN_SIZE),
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE,
     },
     {
 	    LUBBOCK_INTCTL_VBASE,
-	    PXA2X0_INTCTL_BASE,
-	    PXA2X0_INTCTL_SIZE,
-	    PTE_NOCACHE,
+	    _A(PXA2X0_INTCTL_BASE),
+	    _S(PXA2X0_INTCTL_SIZE),
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE,
+    },
+    {
+	    LUBBOCK_FFUART_VBASE,
+	    _A(PXA2X0_FFUART_BASE),
+	    _S(4 * COM_NPORTS),
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE,
     },
+    {
+	    LUBBOCK_BTUART_VBASE,
+	    _A(PXA2X0_BTUART_BASE),
+	    _S(4 * COM_NPORTS),
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE,
+    },
+
     {0, 0, 0, 0,}
 };
 
-static void
-map_io_area(paddr_t pagedir)
-{
-	int loop;
-
-	/*
-	 * Map devices we can map w/ section mappings.
-	 */
-	loop = 0;
-	while (l1_sec_table[loop].size) {
-		vm_size_t sz;
-
-#ifdef VERBOSE_INIT_ARM
-		printf("%08lx -> %08lx @ %08lx\n", l1_sec_table[loop].pa,
-		    l1_sec_table[loop].pa + l1_sec_table[loop].size - 1,
-		    l1_sec_table[loop].va);
-#endif
-		for (sz = 0; sz < l1_sec_table[loop].size; sz += L1_S_SIZE)
-			pmap_map_section(pagedir, l1_sec_table[loop].va + sz,
-			    l1_sec_table[loop].pa + sz,
-			    VM_PROT_READ|VM_PROT_WRITE,
-			    l1_sec_table[loop].flags);
-		++loop;
-	}
-}
-
-/*
- * simple memory mapping function used in early bootstrap stage
- * before pmap is initialized.
- * size and cacheability are ignored and map one section with nocache.
- */
-static vaddr_t section_free = LUBBOCK_VBASE_FREE;
-
-static int
-bootstrap_bs_map(void *t, bus_addr_t bpa, bus_size_t size,
-    int cacheable, bus_space_handle_t *bshp)
-{
-	u_long startpa;
-	vaddr_t va;
-	pd_entry_t *pagedir = read_ttb();
-	/* This assumes PA==VA for page directory */
-
-	va = section_free;
-	section_free += L1_S_SIZE;
-
-	startpa = trunc_page(bpa);
-	pmap_map_section((vaddr_t)pagedir, va, startpa, 
-	    VM_PROT_READ|VM_PROT_WRITE, PTE_NOCACHE);
-	cpu_tlb_flushD();
-
-	*bshp = (bus_space_handle_t)(va + (bpa - startpa));
-
-	return(0);
-}
-
-static void
-copy_io_area_map(pd_entry_t *new_pd)
-{
-	pd_entry_t *cur_pd = read_ttb();
-	vaddr_t va;
-
-	for (va = LUBBOCK_IO_AREA_VBASE;
-	     (cur_pd[va>>L1_S_SHIFT] & L1_TYPE_MASK) == L1_TYPE_S;
-	     va += L1_S_SIZE) {
-
-		new_pd[va>>L1_S_SHIFT] = cur_pd[va>>L1_S_SHIFT];
-	}
-}
-
-
+#undef	_A
+#undef	_S
 
 /*
  * u_int initarm(...)
@@ -481,27 +428,32 @@
 #ifdef DIAGNOSTIC
 	extern vsize_t xscale_minidata_clean_size; /* used in KASSERT */
 #endif
-	struct bus_space tmp_bs_tag;
-	int	(*map_func_save)(void *, bus_addr_t, bus_size_t, int, 
-	    bus_space_handle_t *);
 #define LEDSTEP_P() 	ioreg_write(LUBBOCK_OBIO_PBASE+LUBBOCK_HEXLED, led_data++)
 #define LEDSTEP() hex_led(led_data++)
 
 	/* use physical address until pagetable is set */
 	LEDSTEP_P();
 
+	/* map some peripheral registers at static I/O area */
+	pmap_devmap_bootstrap((vaddr_t)read_ttb(), lubbock_devmap);
+
+	LEDSTEP_P();
+
 	/* start 32.768KHz OSC */
-	ioreg_write(PXA2X0_CLKMAN_BASE + 0x08, 2);
+	ioreg_write(LUBBOCK_CLKMAN_VBASE + 0x08, 2);
+	/* Get ready for splfoo() */
+	pxa2x0_intr_bootstrap(LUBBOCK_INTCTL_VBASE);
+
+	LEDSTEP();
 
 	/*
 	 * Heads up ... Setup the CPU / MMU / TLB functions
 	 */
 	if (set_cpufuncs())
 		panic("cpu not recognized!");
-	LEDSTEP_P();
 
-	/* Get ready for splfoo() */
-	pxa2x0_intr_bootstrap(PXA2X0_INTCTL_BASE);
+	LEDSTEP();
+
 
 #if 0
 	/* Calibrate the delay loop. */
@@ -538,25 +490,15 @@
 	 * 0xc0000000 - 0xcfffffff  Y Y Y  Cache Flush Region 
 	 * (done by this routine)
 	 * 0xfd000000 - 0xfd0000ff  N N N  I/O baseboard registers
-	 * 0xfd100000 - 0xfd2fffff  N N N  Processor Registers.
+	 * 0xfd100000 - 0xfd3fffff  N N N  Processor Registers.
+	 * 0xfd400000 - 0xfd4fffff  N N N  FF-UART
+	 * 0xfd500000 - 0xfd5fffff  N N N  BT-UART
 	 *
 	 * The first level page table is at 0xa0004000.  There are also
 	 * 2 second-level tables at 0xa0008000 and 0xa0008400.
 	 *
 	 */
 
-	{
-		/*
-		 * Tweak RedBoot's pagetable so that we can access to
-		 * some registers at same VA before and after installing 
-		 * our page table. 
-		 */
-		paddr_t ttb = (paddr_t)read_ttb();
-
-		map_io_area(ttb);
-		cpu_tlb_flushD();
-	}
-
 	/* setup GPIO for BTUART, in case bootloader doesn't take care of it */
 	pxa2x0_gpio_bootstrap(LUBBOCK_GPIO_VBASE);
 	pxa2x0_gpio_set_function(42, GPIO_ALT_FN_1_IN);
@@ -571,14 +513,6 @@
 
 	LEDSTEP();
 
-	tmp_bs_tag = pxa2x0_bs_tag;
-	tmp_bs_tag.bs_map = bootstrap_bs_map;
-	map_func_save = pxa2x0_a4x_bs_tag.bs_map;
-	pxa2x0_a4x_bs_tag.bs_map = bootstrap_bs_map;
-
-	LEDSTEP();
-
-
 	consinit();
 	LEDSTEP();
 #ifdef KGDB
@@ -879,7 +813,7 @@
 	 * map integrated peripherals at same address in l1pagetable
 	 * so that we can continue to use console.
 	 */
-	copy_io_area_map((pd_entry_t *)l1pagetable);
+	pmap_devmap_bootstrap(l1pagetable, lubbock_devmap);
 
 	/*
 	 * Give the XScale global cache clean code an appropriately
@@ -918,12 +852,6 @@
 
 	LEDSTEP();
 
-	/* set new intc register address so that splfoo() doesn't
-	   touch illegal address.  */
-	pxa2x0_intr_bootstrap(LUBBOCK_INTCTL_VBASE);
-
-	LEDSTEP();
-
 	cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT);
 	setttb(kernel_l1pt.pv_pa);
 	cpu_tlb_flushID();
@@ -1028,8 +956,6 @@
 		Debugger();
 #endif
 
-	pxa2x0_a4x_bs_tag.bs_map = map_func_save ;
-
 	/* We return the new stack pointer address */
 	return(kernelstack.pv_va + USPACE_SVC_STACK_TOP);
 }
Index: sys/arch/evbarm/lubbock/lubbock_reg.h
===================================================================
RCS file: /cvsroot/src/sys/arch/evbarm/lubbock/lubbock_reg.h,v
retrieving revision 1.2
diff -u -u -r1.2 lubbock_reg.h
--- sys/arch/evbarm/lubbock/lubbock_reg.h	10 Sep 2004 15:27:10 -0000	1.2
+++ sys/arch/evbarm/lubbock/lubbock_reg.h	14 Mar 2005 06:57:39 -0000
@@ -1,7 +1,7 @@
 /*	$NetBSD: lubbock_reg.h,v 1.2 2004/09/10 15:27:10 nathanw Exp $ */
 
 /*
- * Copyright (c) 2002, 2003  Genetec Corporation.  All rights reserved.
+ * Copyright (c) 2002, 2003, 2005  Genetec Corporation.  All rights reserved.
  * Written by Hiroyuki Bessho for Genetec Corporation.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -58,7 +58,8 @@
 #define LUBBOCK_GPIO_VBASE	0xfd100000
 #define LUBBOCK_CLKMAN_VBASE 	0xfd200000
 #define LUBBOCK_INTCTL_VBASE 	0xfd300000
-#define LUBBOCK_VBASE_FREE	0xfd400000
+#define LUBBOCK_FFUART_VBASE	0xfd400000
+#define LUBBOCK_BTUART_VBASE	0xfd500000
 /* FFUART and/or BTUART are mapped to this area when
    used for console or kgdb port */