Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 9 Jul 2012 18:34:21 +0000 (UTC)
From:      Jakub Wojciech Klama <jceel@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-user@freebsd.org
Subject:   svn commit: r238306 - in user/jceel/soc2012_armv6/sys: arm/arm arm/include dev/uart
Message-ID:  <201207091834.q69IYLtk033668@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: jceel
Date: Mon Jul  9 18:34:21 2012
New Revision: 238306
URL: http://svn.freebsd.org/changeset/base/238306

Log:
  ARM machdep refactoring: rewritten MMU initialization code (which creates
  initial pagetables before bootstrapping pmap, set stacks, msgbuf, etc)
  to be more versatile and easier to understand. Moved such routine into
  arm/machdep.c file. Moved some frequently-used routines from individual
  ports machdep files into arm/machdep.c file. Changed pmap_devmap entries
  allocation: now virtual address of device mapping is allocated dynamically.
  This change will free port developers from managing virtual address space
  and make mappings more compact (only needed devices will be mapped
  without gaps between them). Also, pmap_devmap entries has a name: if
  pmap_devmap entry name will match device alias in .dts file, physical
  address and size of mapping will be automatically aquired from FDT.

Modified:
  user/jceel/soc2012_armv6/sys/arm/arm/machdep.c
  user/jceel/soc2012_armv6/sys/arm/arm/pmap.c
  user/jceel/soc2012_armv6/sys/arm/include/machdep.h
  user/jceel/soc2012_armv6/sys/arm/include/pmap.h
  user/jceel/soc2012_armv6/sys/dev/uart/uart_bus_fdt.c
  user/jceel/soc2012_armv6/sys/dev/uart/uart_dev_lpc.c

Modified: user/jceel/soc2012_armv6/sys/arm/arm/machdep.c
==============================================================================
--- user/jceel/soc2012_armv6/sys/arm/arm/machdep.c	Mon Jul  9 18:01:40 2012	(r238305)
+++ user/jceel/soc2012_armv6/sys/arm/arm/machdep.c	Mon Jul  9 18:34:21 2012	(r238306)
@@ -65,6 +65,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/mutex.h>
+#include <sys/msgbuf.h>
 #include <sys/pcpu.h>
 #include <sys/ptrace.h>
 #include <sys/signalvar.h>
@@ -82,6 +83,7 @@ __FBSDID("$FreeBSD$");
 
 #include <machine/armreg.h>
 #include <machine/cpu.h>
+#include <machine/early_uart.h>
 #include <machine/machdep.h>
 #include <machine/md_var.h>
 #include <machine/metadata.h>
@@ -93,15 +95,50 @@ __FBSDID("$FreeBSD$");
 #include <machine/vmparam.h>
 #include <machine/sysarch.h>
 
+#include <dev/fdt/fdt_common.h>
+#include <dev/ofw/openfirm.h>
+
+/* Define various stack sizes in pages */
+#define IRQ_STACK_SIZE	1
+#define ABT_STACK_SIZE	1
+#define UND_STACK_SIZE	1
+
+#define	ARM_DEVMAP_START	0xf0000000
+
 struct pcpu __pcpu[MAXCPU];
 struct pcpu *pcpup = &__pcpu[0];
 
+static struct trapframe proc0_tf;
+
 uint32_t cpu_reset_address = 0;
 int cold = 1;
 vm_offset_t vector_page;
 
 long realmem = 0;
 
+extern u_int data_abort_handler_address;
+extern u_int prefetch_abort_handler_address;
+extern u_int undefined_handler_address;
+
+extern vm_offset_t pmap_bootstrap_lastaddr;
+
+struct pv_addr systempage;
+struct pv_addr msgbufpv;
+struct pv_addr irqstack;
+struct pv_addr undstack;
+struct pv_addr abtstack;
+struct pv_addr kernelstack;
+
+extern struct pmap_devmap arm_pmap_devmap[];
+struct pv_addr arm_bootstrap_l2pt[128];
+vm_offset_t arm_free_va, arm_free_pa, arm_allocated_va;
+vm_offset_t arm_start_va, arm_start_pa;
+vm_offset_t arm_devmap_size;
+vm_offset_t pmap_bootstrap_lastaddr;
+
+vm_paddr_t phys_avail[10];
+vm_paddr_t dump_avail[4];
+
 int (*_arm_memcpy)(void *, void *, int, int) = NULL;
 int (*_arm_bzero)(void *, int, int) = NULL;
 int _min_memcpy_size = 0;
@@ -112,6 +149,10 @@ extern int *end;
 extern vm_offset_t ksym_start, ksym_end;
 #endif
 
+static void arm_valloc_pages(struct pv_addr *, size_t, size_t);
+static void arm_process_devmap(struct pmap_devmap *);
+static void arm_bootstrap_pagetables(uint32_t, struct pv_addr *, struct pv_addr *);
+
 void
 sendsig(catcher, ksi, mask)
 	sig_t catcher;
@@ -731,6 +772,22 @@ fake_preload_metadata(void)
 	return (lastaddr);
 }
 
+/*
+ * Initialize proc0
+ */
+void
+init_proc0(vm_offset_t kstack)
+{
+	proc_linkup0(&proc0, &thread0);
+	thread0.td_kstack = kstack;
+	thread0.td_pcb = (struct pcb *)
+		(thread0.td_kstack + KSTACK_PAGES * PAGE_SIZE) - 1;
+	thread0.td_pcb->pcb_flags = 0;
+	thread0.td_frame = &proc0_tf;
+	pcpup->pc_curpcb = thread0.td_pcb;
+}
+
+
 void
 pcpu0_init(void)
 {
@@ -743,3 +800,381 @@ pcpu0_init(void)
 	PCPU_SET(cpu, 0);
 #endif
 }
+
+static void
+arm_valloc_pages(struct pv_addr *result, size_t npages, size_t boundary)
+{
+	npages *= PAGE_SIZE;
+	boundary *= PAGE_SIZE;
+
+	/* First, round up to specified boundary */
+	arm_free_pa = roundup(arm_free_pa, boundary);
+	arm_free_va = roundup(arm_free_va, boundary);
+
+	result->pv_pa = arm_free_pa;
+	arm_free_pa += npages;
+	result->pv_va = arm_free_va;
+	arm_free_va += npages;
+	arm_allocated_va += npages;
+	memset((void *)result->pv_va, 0, npages);
+
+	edebugf("pa=0x%x va=0x%x size=0x%x\n", result->pv_pa, result->pv_va, npages);
+}
+
+static void
+arm_bootstrap_pagetables(uint32_t memsize, struct pv_addr *vectors, struct pv_addr *l1pt)
+{
+	struct pv_addr *l2pt = arm_bootstrap_l2pt;
+	vm_offset_t l2_start;
+	vm_offset_t pagetables_size = 0;
+	int l2_needed;
+	int l2_devmap;
+	int i, j;
+
+	/* Allocate L1 pagetable */
+	arm_valloc_pages(l1pt, L1_TABLE_SIZE / PAGE_SIZE, L1_TABLE_SIZE / PAGE_SIZE);
+	pagetables_size += L1_TABLE_SIZE;
+
+	/* 
+	 * Calculate number of needed L2 pagetables: we are starting with 
+	 * one needed to map vectors page
+	 */
+	l2_start = rounddown(arm_free_va, L1_S_SIZE);
+	l2_needed = 1; /* vectors */
+	l2_devmap = roundup(arm_devmap_size, L1_S_SIZE) >> L1_S_SHIFT;
+	/* Add needed number of tables to hold vm_page array */
+	l2_needed += roundup((memsize / PAGE_SIZE) * sizeof(struct vm_page), L1_S_SIZE) >> L1_S_SHIFT;
+	/* And then to map kernel text and data and associated structures */
+	l2_needed += roundup(arm_free_va - l2_start, L1_S_SIZE) >> L1_S_SHIFT;
+	/* ...and to map devmap table */
+	l2_needed += l2_devmap; 
+	/* 
+	 * Finally, round up to 4 to not waste space, as we can fit 4
+	 * pagetables on one page
+	 */
+	l2_needed = roundup(l2_needed, 4);
+
+	edebugf("L2 needed=%d devmap=%d\n", l2_needed, l2_devmap);
+
+	/* Allocate L2 page tables */
+	arm_valloc_pages(&l2pt[0], (l2_needed * L2_TABLE_SIZE_REAL) / PAGE_SIZE, 1);
+	pagetables_size += (l2_needed * L2_TABLE_SIZE_REAL);
+	
+	for (i = 1; i < l2_needed; i++) {
+		/* Fill in L2 page table addresses */
+		l2pt[i].pv_pa = l2pt[0].pv_pa + (i * L2_TABLE_SIZE_REAL);
+		l2pt[i].pv_va = l2pt[0].pv_va + (i * L2_TABLE_SIZE_REAL);
+	}
+
+	for (i = 0; i < l2_needed - l2_devmap - 1; i++) {
+		pmap_link_l2pt(l1pt->pv_va, l2_start + (i * L1_S_SIZE), &l2pt[i]);
+		edebugf("link L2 page table %d at 0x%x\n", i, l2_start + (i * L1_S_SIZE));
+	}
+
+	/* Tell pmap about currently maximum mapped VA address */
+	pmap_curmaxkvaddr = roundup(arm_free_va, L1_S_SIZE);
+
+	/* Link devmap tables */
+	for (j = 0; j < l2_devmap; j++) {
+		pmap_link_l2pt(l1pt->pv_va, ARM_DEVMAP_START + (j * L1_S_SIZE), &l2pt[i + j]);
+		edebugf("link L2 page table %d at 0x%x\n", i + j, ARM_DEVMAP_START + (j * L1_S_SIZE));
+	}
+
+	/* Link and map vectors page */
+	pmap_link_l2pt(l1pt->pv_va, ARM_VECTORS_HIGH, &l2pt[l2_needed - 1]);
+	pmap_map_entry(l1pt->pv_va, ARM_VECTORS_HIGH, vectors->pv_pa,
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	
+	/* Map kernel and structures */
+	pmap_map_chunk(l1pt->pv_va, arm_start_va, arm_start_pa,
+	    arm_allocated_va - pagetables_size,
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE);
+	
+	/* Map pagetables itself: L1 */
+	pmap_map_chunk(l1pt->pv_va, l1pt->pv_va, l1pt->pv_pa, L1_TABLE_SIZE,
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
+	
+	/* and L2 */
+	pmap_map_chunk(l1pt->pv_va, l2pt[0].pv_va, l2pt[0].pv_pa, 
+	    L2_TABLE_SIZE_REAL * l2_needed,
+	    VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE);
+}
+
+static void
+arm_process_devmap(struct pmap_devmap *devmap)
+{
+	struct fdt_range ranges[8];
+	struct fdt_range *rptr = ranges;
+	struct pmap_devmap *entry;
+	phandle_t node, parent;
+	vm_offset_t totalsize = 0;
+	u_long start, size;
+	int addr_cells, size_cells, par_addr_cells;
+	int nranges, i;
+
+	edebugf("processing devmap entries\n");
+
+	for (i = 0; devmap[i].pd_name != NULL || devmap[i].pd_pa != 0; i++) {
+		entry = &devmap[i];
+		if (entry->pd_name != NULL) {
+
+			edebugf("fdt %s: ", entry->pd_name);
+
+			node = !strcmp(entry->pd_name, "console-uart")
+			    ? fdt_lookup_console_uart()
+			    : OF_finddevice(entry->pd_name);
+	
+			eprintf("node=0x%x ", node);
+
+			if (node == -1)
+				goto notfound;
+
+			if ((parent = OF_parent(node)) <= 0)
+				goto notfound;
+
+			if (fdt_addrsize_cells(parent, &addr_cells, &size_cells))
+				goto notfound;
+			
+			if ((par_addr_cells = fdt_parent_addr_cells(parent)) > 2)
+				goto notfound;
+			
+			nranges = fdt_read_ranges(parent, &rptr, addr_cells, 
+			    par_addr_cells, size_cells);
+			
+			if (nranges <= 0)
+				goto notfound;
+
+			fdt_regsize(node, &start, &size);
+
+			start += fdt_ranges_lookup(ranges, nranges, start, size);
+
+			entry->pd_pa = rounddown(start, PAGE_SIZE);
+			entry->pd_size = roundup(size, PAGE_SIZE);
+
+		} else
+			edebugf("entry: ");
+
+notfound:
+		entry->pd_va = ARM_DEVMAP_START + totalsize;
+		totalsize += entry->pd_size;
+		eprintf("pa=0x%x va=0x%x size=0x%x\n", entry->pd_pa, entry->pd_va, entry->pd_size);
+	}
+
+	edebugf("total mapped size: 0x%x\n", totalsize);
+	arm_devmap_size = totalsize;
+}
+
+
+void *
+arm_mmu_init(uint32_t memsize, uint32_t lastaddr, int high_vectors)
+{
+	struct pv_addr pagetable;
+	struct pv_addr dpcpu;
+
+	arm_start_va = KERNVIRTADDR;
+	arm_start_pa = KERNPHYSADDR;
+	arm_free_va = roundup(lastaddr, PAGE_SIZE);
+	arm_free_pa = arm_free_va + (KERNPHYSADDR - KERNVIRTADDR);
+	arm_allocated_va = arm_free_va - arm_start_va;
+	pmap_bootstrap_lastaddr = ARM_DEVMAP_START - ARM_NOCACHE_KVA_SIZE;
+	
+	edebugf("arm_free_va=0x%x arm_free_pa=0x%x\n", arm_start_va, arm_free_va);
+	edebugf("using %s vectors address\n", high_vectors ? "high" : "low");
+
+	/*
+	 * Allocate a page for the system page mapped to 0x00000000
+	 * or 0xffff0000. This page will just contain the system vectors
+	 * and can be shared by all processes.
+	 */
+	arm_valloc_pages(&systempage, 1, 1);
+
+	/* Allocate dynamic per-cpu area. */
+	arm_valloc_pages(&dpcpu, DPCPU_SIZE / PAGE_SIZE, 1);
+	dpcpu_init((void *)dpcpu.pv_va, 0);
+
+	/* Allocate stacks for all modes */
+	arm_valloc_pages(&irqstack, IRQ_STACK_SIZE * MAXCPU, 1);
+	arm_valloc_pages(&abtstack, ABT_STACK_SIZE * MAXCPU, 1);
+	arm_valloc_pages(&undstack, UND_STACK_SIZE * MAXCPU, 1);
+	arm_valloc_pages(&kernelstack, KSTACK_PAGES * MAXCPU, 1);
+
+	init_param1();
+
+	/* Allocate space for message buffer */
+	arm_valloc_pages(&msgbufpv, round_page(msgbufsize) / PAGE_SIZE, 1);
+	
+	/* Calculate devmap size */
+	arm_process_devmap(arm_pmap_devmap);
+
+	/* Construct bootstrap pagetables */
+	arm_bootstrap_pagetables(memsize, &systempage, &pagetable);
+	pmap_devmap_bootstrap(pagetable.pv_va, arm_pmap_devmap);
+	
+	edebugf("L1 table pa=0x%x va=0x%x\n", pagetable.pv_pa, pagetable.pv_va);
+
+	/* Launch our bootstrap pagetable */
+	cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)) |
+	    DOMAIN_CLIENT);
+	setttb(pagetable.pv_pa);
+	cpu_tlb_flushID();
+	cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2));
+
+#ifdef ARM_EARLY_DEBUG
+	arm_early_uart_base(pmap_devmap_find_name("console-uart")->pd_va);
+#endif
+
+	edebugf("bootstrap pagetable launched\n");
+
+	/*
+	 * Pages were allocated during the secondary bootstrap for the
+	 * stacks for different CPU modes.
+	 * We must now set the r13 registers in the different CPU modes to
+	 * point to these stacks.
+	 * Since the ARM stacks use STMFD etc. we must set r13 to the top end
+	 * of the stack memory.
+	 */
+	cpu_control(CPU_CONTROL_MMU_ENABLE, CPU_CONTROL_MMU_ENABLE);
+	set_stackptrs(0);
+
+	/*
+	 * We must now clean the cache again....
+	 * Cleaning may be done by reading new data to displace any
+	 * dirty data in the cache. This will have happened in setttb()
+	 * but since we are boot strapping the addresses used for the read
+	 * may have just been remapped and thus the cache could be out
+	 * of sync. A re-clean after the switch will cure this.
+	 * After booting there are no gross relocations of the kernel thus
+	 * this problem will not occur after initarm().
+	 */
+	cpu_idcache_wbinv_all();
+
+	/* Set stack for exception handlers */
+	data_abort_handler_address = (u_int)data_abort_handler;
+	prefetch_abort_handler_address = (u_int)prefetch_abort_handler;
+	undefined_handler_address = (u_int)undefinedinstruction_bounce;
+	undefined_init();
+
+	init_proc0(kernelstack.pv_va);
+	arm_vector_init(ARM_VECTORS_HIGH, ARM_VEC_ALL);
+
+	dump_avail[0] = 0;
+	dump_avail[1] = memsize;
+	dump_avail[2] = 0;
+	dump_avail[3] = 0;
+
+	pmap_bootstrap(arm_free_va, pmap_bootstrap_lastaddr, &pagetable);
+	msgbufp = (void *)msgbufpv.pv_va;
+	msgbufinit(msgbufp, msgbufsize);
+
+	edebugf("MMU initialized\n");
+
+	return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP -
+	    sizeof(struct pcb)));
+}
+
+void
+set_stackptrs(int cpu)
+{
+
+	set_stackptr(PSR_IRQ32_MODE,
+	    irqstack.pv_va + ((IRQ_STACK_SIZE * PAGE_SIZE) * (cpu + 1)));
+	set_stackptr(PSR_ABT32_MODE,
+	    abtstack.pv_va + ((ABT_STACK_SIZE * PAGE_SIZE) * (cpu + 1)));
+	set_stackptr(PSR_UND32_MODE,
+	    undstack.pv_va + ((UND_STACK_SIZE * PAGE_SIZE) * (cpu + 1)));
+}
+
+void
+physmap_init(struct mem_region *availmem_regions, int availmem_regions_sz)
+{
+	int i, j, cnt;
+	vm_offset_t phys_kernelend, kernload;
+	uint32_t s, e, sz;
+	struct mem_region *mp, *mp1;
+
+	phys_kernelend = KERNPHYSADDR + (virtual_avail - KERNVIRTADDR);
+	kernload = KERNPHYSADDR;
+
+	/*
+	 * Remove kernel physical address range from avail
+	 * regions list. Page align all regions.
+	 * Non-page aligned memory isn't very interesting to us.
+	 * Also, sort the entries for ascending addresses.
+	 */
+	sz = 0;
+	cnt = availmem_regions_sz;
+	eprintf("processing avail regions:\n");
+	for (mp = availmem_regions; mp->mr_size; mp++) {
+		s = mp->mr_start;
+		e = mp->mr_start + mp->mr_size;
+		eprintf(" 0x%x-0x%x -> ", s, e);
+		/* Check whether this region holds all of the kernel. */
+		if (s < kernload && e > phys_kernelend) {
+			availmem_regions[cnt].mr_start = phys_kernelend;
+			availmem_regions[cnt++].mr_size = e - phys_kernelend;
+			e = kernload;
+		}
+		/* Look whether this regions starts within the kernel. */
+		if (s >= kernload && s < phys_kernelend) {
+			if (e <= phys_kernelend)
+				goto empty;
+			s = phys_kernelend;
+		}
+		/* Now look whether this region ends within the kernel. */
+		if (e > kernload && e <= phys_kernelend) {
+			if (s >= kernload) {
+				goto empty;
+			}
+			e = kernload;
+		}
+		/* Now page align the start and size of the region. */
+		s = round_page(s);
+		e = trunc_page(e);
+		if (e < s)
+			e = s;
+		sz = e - s;
+		eprintf("0x%x-0x%x = 0x%x\n", s, e, sz);
+
+		/* Check whether some memory is left here. */
+		if (sz == 0) {
+		empty:
+			eprintf("skipping\n");
+			bcopy(mp + 1, mp,
+			    (cnt - (mp - availmem_regions)) * sizeof(*mp));
+			cnt--;
+			mp--;
+			continue;
+		}
+
+		/* Do an insertion sort. */
+		for (mp1 = availmem_regions; mp1 < mp; mp1++)
+			if (s < mp1->mr_start)
+				break;
+		if (mp1 < mp) {
+			bcopy(mp1, mp1 + 1, (char *)mp - (char *)mp1);
+			mp1->mr_start = s;
+			mp1->mr_size = sz;
+		} else {
+			mp->mr_start = s;
+			mp->mr_size = sz;
+		}
+	}
+	availmem_regions_sz = cnt;
+
+	/* Fill in phys_avail table, based on availmem_regions */
+	eprintf("fill in phys_avail:\n");
+	for (i = 0, j = 0; i < availmem_regions_sz; i++, j += 2) {
+
+		eprintf(" region: 0x%x - 0x%x (0x%x)\n",
+		    availmem_regions[i].mr_start,
+		    availmem_regions[i].mr_start + availmem_regions[i].mr_size,
+		    availmem_regions[i].mr_size);
+
+		phys_avail[j] = availmem_regions[i].mr_start;
+		phys_avail[j + 1] = availmem_regions[i].mr_start +
+		    availmem_regions[i].mr_size;
+	}
+	phys_avail[j] = 0;
+	phys_avail[j + 1] = 0;
+}
+

Modified: user/jceel/soc2012_armv6/sys/arm/arm/pmap.c
==============================================================================
--- user/jceel/soc2012_armv6/sys/arm/arm/pmap.c	Mon Jul  9 18:01:40 2012	(r238305)
+++ user/jceel/soc2012_armv6/sys/arm/arm/pmap.c	Mon Jul  9 18:34:21 2012	(r238306)
@@ -4855,7 +4855,10 @@ pmap_devmap_bootstrap(vm_offset_t l1pt, 
 
 	pmap_devmap_table = table;
 
-	for (i = 0; pmap_devmap_table[i].pd_size != 0; i++) {
+	for (i = 0; pmap_devmap_table[i].pd_size != 0 || pmap_devmap_table[i].pd_name != NULL ; i++) {
+		if (pmap_devmap_table[i].pd_size == 0)
+			continue;
+
 #ifdef VERBOSE_INIT_ARM
 		printf("devmap: %08x -> %08x @ %08x\n",
 		    pmap_devmap_table[i].pd_pa,
@@ -4875,17 +4878,18 @@ const struct pmap_devmap *
 pmap_devmap_find_pa(vm_paddr_t pa, vm_size_t size)
 {
 	int i;
-
+	
 	if (pmap_devmap_table == NULL)
 		return (NULL);
-
-	for (i = 0; pmap_devmap_table[i].pd_size != 0; i++) {
+	
+	for (i = 0; pmap_devmap_table[i].pd_name != NULL ||
+	    pmap_devmap_table[i].pd_size != 0; i++) {
 		if (pa >= pmap_devmap_table[i].pd_pa &&
 		    pa + size <= pmap_devmap_table[i].pd_pa +
 				 pmap_devmap_table[i].pd_size)
 			return (&pmap_devmap_table[i]);
 	}
-
+	
 	return (NULL);
 }
 
@@ -4897,7 +4901,8 @@ pmap_devmap_find_va(vm_offset_t va, vm_s
 	if (pmap_devmap_table == NULL)
 		return (NULL);
 
-	for (i = 0; pmap_devmap_table[i].pd_size != 0; i++) {
+	for (i = 0; pmap_devmap_table[i].pd_name != NULL || 
+	    pmap_devmap_table[i].pd_size != 0; i++) {
 		if (va >= pmap_devmap_table[i].pd_va &&
 		    va + size <= pmap_devmap_table[i].pd_va +
 				 pmap_devmap_table[i].pd_size)
@@ -4907,3 +4912,19 @@ pmap_devmap_find_va(vm_offset_t va, vm_s
 	return (NULL);
 }
 
+const struct pmap_devmap *
+pmap_devmap_find_name(const char *name)
+{
+	int i;
+
+	if (pmap_devmap_table == NULL)
+		return (NULL);
+
+	for (i = 0; pmap_devmap_table[i].pd_name != NULL ||
+	    pmap_devmap_table[i].pd_size != 0; i++) {
+		if (!strcmp(name, pmap_devmap_table[i].pd_name))
+			return (&pmap_devmap_table[i]);
+	}
+
+	return (NULL);
+}

Modified: user/jceel/soc2012_armv6/sys/arm/include/machdep.h
==============================================================================
--- user/jceel/soc2012_armv6/sys/arm/include/machdep.h	Mon Jul  9 18:01:40 2012	(r238305)
+++ user/jceel/soc2012_armv6/sys/arm/include/machdep.h	Mon Jul  9 18:34:21 2012	(r238306)
@@ -4,9 +4,15 @@
 #ifndef _MACHDEP_BOOT_MACHDEP_H_
 #define _MACHDEP_BOOT_MACHDEP_H_
 
+#include <machine/fdt.h>
+
 /* misc prototypes used by the many arm machdeps */
 void arm_lock_cache_line(vm_offset_t);
 vm_offset_t fake_preload_metadata(void);
+void init_proc0(vm_offset_t kstack);
+void *arm_mmu_init(uint32_t, uint32_t, int);
+void set_stackptrs(int);
+void physmap_init(struct mem_region *, int);
 void halt(void);
 void data_abort_handler(trapframe_t *);
 void prefetch_abort_handler(trapframe_t *);

Modified: user/jceel/soc2012_armv6/sys/arm/include/pmap.h
==============================================================================
--- user/jceel/soc2012_armv6/sys/arm/include/pmap.h	Mon Jul  9 18:01:40 2012	(r238305)
+++ user/jceel/soc2012_armv6/sys/arm/include/pmap.h	Mon Jul  9 18:34:21 2012	(r238306)
@@ -629,6 +629,7 @@ void pmap_update(pmap_t);
  * static mappings of devices, created at bootstrap time.
  */
 struct pmap_devmap {
+	const char *	pd_name;	/* FDT device handle */
 	vm_offset_t	pd_va;		/* virtual address */
 	vm_paddr_t	pd_pa;		/* physical address */
 	vm_size_t	pd_size;	/* size of region */
@@ -636,8 +637,13 @@ struct pmap_devmap {
 	int		pd_cache;	/* cache attributes */
 };
 
+#define	DEVMAP_FDT(_name, _prot, _cache)	{_name, 0, 0, 0, _prot, _cache}
+#define	DEVMAP_ENTRY(_pa, _size, _prot, _cache)	{NULL, 0, _pa, _size, _prot, _cache}
+#define	DEVMAP_END				{NULL, 0, 0, 0, 0, 0}
+
 const struct pmap_devmap *pmap_devmap_find_pa(vm_paddr_t, vm_size_t);
 const struct pmap_devmap *pmap_devmap_find_va(vm_offset_t, vm_size_t);
+const struct pmap_devmap *pmap_devmap_find_name(const char *name);
 
 void	pmap_devmap_bootstrap(vm_offset_t, const struct pmap_devmap *);
 void	pmap_devmap_register(const struct pmap_devmap *);

Modified: user/jceel/soc2012_armv6/sys/dev/uart/uart_bus_fdt.c
==============================================================================
--- user/jceel/soc2012_armv6/sys/dev/uart/uart_bus_fdt.c	Mon Jul  9 18:01:40 2012	(r238305)
+++ user/jceel/soc2012_armv6/sys/dev/uart/uart_bus_fdt.c	Mon Jul  9 18:34:21 2012	(r238306)
@@ -135,9 +135,8 @@ uart_cpu_eqres(struct uart_bas *b1, stru
 int
 uart_cpu_getdev(int devtype, struct uart_devinfo *di)
 {
-	char buf[64];
 	struct uart_class *class;
-	phandle_t node, parent, chosen;
+	phandle_t node, parent;
 	pcell_t shift, br, rclk;
 	u_long start, size;
 	struct fdt_range ranges[8];
@@ -160,16 +159,7 @@ uart_cpu_getdev(int devtype, struct uart
 	/*
 	 * Retrieve /chosen/std{in,out}.
 	 */
-	if ((chosen = OF_finddevice("/chosen")) == -1)
-		return (ENXIO);
-	if (OF_getprop(chosen, "stdin", buf, sizeof(buf)) <= 0)
-		return (ENXIO);
-	if ((node = OF_finddevice(buf)) == -1)
-		return (ENXIO);
-	if (OF_getprop(chosen, "stdout", buf, sizeof(buf)) <= 0)
-		return (ENXIO);
-	if (OF_finddevice(buf) != node)
-		/* Only stdin == stdout is supported. */
+	if ((node = fdt_lookup_console_uart()) == -1)
 		return (ENXIO);
 
 	/*

Modified: user/jceel/soc2012_armv6/sys/dev/uart/uart_dev_lpc.c
==============================================================================
--- user/jceel/soc2012_armv6/sys/dev/uart/uart_dev_lpc.c	Mon Jul  9 18:01:40 2012	(r238305)
+++ user/jceel/soc2012_armv6/sys/dev/uart/uart_dev_lpc.c	Mon Jul  9 18:34:21 2012	(r238306)
@@ -45,14 +45,17 @@ __FBSDID("$FreeBSD: projects/armv6/sys/d
 #define	DEFAULT_RCLK		(13 * 1000 * 1000)
 #define	LPC_UART_NO(_bas)	(((_bas->bsh) - LPC_UART_BASE) >> 15)
 
+static bus_space_handle_t uartctrl_bsh;
+static bus_space_handle_t clkpwr_bsh;
+
 #define	lpc_ns8250_get_auxreg(_bas, _reg)	\
-    bus_space_read_4((_bas)->bst, LPC_UART_CONTROL_BASE, _reg)
+    bus_space_read_4((_bas)->bst, uartctrl_bsh, _reg)
 #define	lpc_ns8250_set_auxreg(_bas, _reg, _val)	\
-    bus_space_write_4((_bas)->bst, LPC_UART_CONTROL_BASE, _reg, _val);
+    bus_space_write_4((_bas)->bst, uartctrl_bsh, _reg, _val);
 #define	lpc_ns8250_get_clkreg(_bas, _reg)	\
-    bus_space_read_4((_bas)->bst, LPC_CLKPWR_BASE, (_reg))
+    bus_space_read_4((_bas)->bst, clkpwr_bsh, (_reg))
 #define	lpc_ns8250_set_clkreg(_bas, _reg, _val)	\
-    bus_space_write_4((_bas)->bst, LPC_CLKPWR_BASE, (_reg), (_val))
+    bus_space_write_4((_bas)->bst, clkpwr_bsh, (_reg), (_val))
 
 /*
  * Clear pending interrupts. THRE is cleared by reading IIR. Data
@@ -292,6 +295,9 @@ lpc_ns8250_init(struct uart_bas *bas, in
 	u_char	ier;
 	u_long	clkmode;
 	
+	bus_space_map(bas->bst, LPC_UART_CONTROL_BASE, LPC_UART_CONTROL_SIZE, 0, &uartctrl_bsh);
+	bus_space_map(bas->bst, LPC_CLKPWR_BASE, LPC_CLKPWR_SIZE, 0, &clkpwr_bsh);
+
 	/* Enable UART clock */
 	clkmode = lpc_ns8250_get_auxreg(bas, LPC_UART_CLKMODE);
 	lpc_ns8250_set_auxreg(bas, LPC_UART_CLKMODE,



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201207091834.q69IYLtk033668>