From owner-svn-src-projects@FreeBSD.ORG Fri Dec 20 14:33:49 2013 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTPS id 3088AB47; Fri, 20 Dec 2013 14:33:49 +0000 (UTC) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id 1BAEA1957; Fri, 20 Dec 2013 14:33:49 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id rBKEXmf5089972; Fri, 20 Dec 2013 14:33:48 GMT (envelope-from andrew@svn.freebsd.org) Received: (from andrew@localhost) by svn.freebsd.org (8.14.7/8.14.7/Submit) id rBKEXmGu089968; Fri, 20 Dec 2013 14:33:48 GMT (envelope-from andrew@svn.freebsd.org) Message-Id: <201312201433.rBKEXmGu089968@svn.freebsd.org> From: Andrew Turner Date: Fri, 20 Dec 2013 14:33:48 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r259648 - in projects/specific_leg/sys/arm: arm include X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.17 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 20 Dec 2013 14:33:49 -0000 Author: andrew Date: Fri Dec 20 14:33:48 2013 New Revision: 259648 URL: http://svnweb.freebsd.org/changeset/base/259648 Log: Map in the DTB passed to us using the Linux ABI. As it may be at any address we move it to just after the kernel. While here fix the spelling of abp. Modified: projects/specific_leg/sys/arm/arm/locore.S projects/specific_leg/sys/arm/arm/machdep.c projects/specific_leg/sys/arm/include/cpu.h Modified: projects/specific_leg/sys/arm/arm/locore.S ============================================================================== --- projects/specific_leg/sys/arm/arm/locore.S Fri Dec 20 14:03:56 2013 (r259647) +++ projects/specific_leg/sys/arm/arm/locore.S Fri Dec 20 14:33:48 2013 (r259648) @@ -221,6 +221,9 @@ virt_done: str ip, [r0, #12] /* store r2 from boot loader */ str fp, [r0, #16] /* store r3 from boot loader */ str r5, [r0, #20] /* store the physical address */ + adr r4, Lpagetable /* load the pagetable address */ + ldr r5, [r4, #4] + str r5, [r0, #24] /* store the pagetable address */ mov fp, #0 /* trace back starts here */ bl _C_LABEL(initarm) /* Off we go */ Modified: projects/specific_leg/sys/arm/arm/machdep.c ============================================================================== --- projects/specific_leg/sys/arm/arm/machdep.c Fri Dec 20 14:03:56 2013 (r259647) +++ projects/specific_leg/sys/arm/arm/machdep.c Fri Dec 20 14:33:48 2013 (r259648) @@ -106,6 +106,7 @@ __FBSDID("$FreeBSD$"); #ifdef FDT #include #include +#include #endif #define DEBUG @@ -167,9 +168,8 @@ static struct pv_addr kernelstack; #define LBABI_MAX_BANKS 10 uint32_t board_id; -struct arm_lbabi_tag *atag_list; char linux_command_line[LBABI_MAX_COMMAND_LINE + 1]; -char atags[LBABI_MAX_COMMAND_LINE * 2]; +//char atags[LBABI_MAX_COMMAND_LINE * 2]; uint32_t memstart[LBABI_MAX_BANKS]; uint32_t memsize[LBABI_MAX_BANKS]; uint32_t membanks; @@ -823,14 +823,19 @@ arm_dump_avail_init(vm_offset_t ramsize, /* * Fake up a boot descriptor table */ -vm_offset_t -fake_preload_metadata(struct arm_boot_params *abp __unused) +static vm_offset_t +build_fake_preload_metadata(struct arm_boot_params *abp __unused, + uint32_t **preload_end) { #ifdef DDB vm_offset_t zstart = 0, zend = 0; #endif vm_offset_t lastaddr; int i = 0; + /* + * fake_preload needs space for 3 items over what we use here + * for the Linux ABI. + */ static uint32_t fake_preload[35]; fake_preload[i++] = MODINFO_NAME; @@ -870,6 +875,12 @@ fake_preload_metadata(struct arm_boot_pa return (lastaddr); } +vm_offset_t +fake_preload_metadata(struct arm_boot_params *abp) +{ + return build_fake_preload_metadata(abp, NULL); +} + void pcpu0_init(void) { @@ -887,9 +898,14 @@ pcpu0_init(void) vm_offset_t linux_parse_boot_param(struct arm_boot_params *abp) { + //struct arm_lbabi_tag *atag_list; + vm_offset_t lastaddr, mapbase; struct arm_lbabi_tag *walker; - uint32_t revision; - uint64_t serial; + //uint32_t revision; + //uint64_t serial; + uint32_t *preload_end; + int fdt_len; + void *data; /* * Linux boot ABI: r0 = 0, r1 is the board type (!= 0) and r2 @@ -900,52 +916,90 @@ linux_parse_boot_param(struct arm_boot_p return 0; board_id = abp->abp_r1; - walker = (struct arm_lbabi_tag *) - (abp->abp_r2 + KERNVIRTADDR - abp->apb_physaddr); - /* xxx - Need to also look for binary device tree */ - if (ATAG_TAG(walker) != ATAG_CORE) - return 0; + /* + * Map the data at abp->abp_r2 into the kernel at 0xe0000000, + * we will move it to a better location later. + */ +#define BOOT_PARAM_ADDR 0xe0000000U + mapbase = abp->abp_r2 & L1_S_FRAME; + pmap_map_chunk(abp->abp_pagetable, BOOT_PARAM_ADDR, + mapbase, L1_S_SIZE, + VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); - atag_list = walker; - while (ATAG_TAG(walker) != ATAG_NONE) { - switch (ATAG_TAG(walker)) { - case ATAG_CORE: - break; - case ATAG_MEM: - if (membanks < LBABI_MAX_BANKS) { - memstart[membanks] = walker->u.tag_mem.start; - memsize[membanks] = walker->u.tag_mem.size; + data = (struct arm_lbabi_tag *) + (abp->abp_r2 + BOOT_PARAM_ADDR - mapbase); +#undef BOOT_PARAM_ADDR + + walker = data; + if (ATAG_TAG(walker) != ATAG_CORE) { + /* TODO: Test this */ +#if 0 + atag_list = walker; + while (ATAG_TAG(walker) != ATAG_NONE) { + switch (ATAG_TAG(walker)) { + case ATAG_CORE: + break; + case ATAG_MEM: + if (membanks < LBABI_MAX_BANKS) { + memstart[membanks] = walker->u.tag_mem.start; + memsize[membanks] = walker->u.tag_mem.size; + } + membanks++; + break; + case ATAG_INITRD2: + break; + case ATAG_SERIAL: + serial = walker->u.tag_sn.low | + ((uint64_t)walker->u.tag_sn.high << 32); + board_set_serial(serial); + break; + case ATAG_REVISION: + revision = walker->u.tag_rev.rev; + board_set_revision(revision); + break; + case ATAG_CMDLINE: + /* XXX open question: Parse this for boothowto? */ + bcopy(walker->u.tag_cmd.command, linux_command_line, + ATAG_SIZE(walker)); + break; + default: + break; } - membanks++; - break; - case ATAG_INITRD2: - break; - case ATAG_SERIAL: - serial = walker->u.tag_sn.low | - ((uint64_t)walker->u.tag_sn.high << 32); - board_set_serial(serial); - break; - case ATAG_REVISION: - revision = walker->u.tag_rev.rev; - board_set_revision(revision); - break; - case ATAG_CMDLINE: - /* XXX open question: Parse this for boothowto? */ - bcopy(walker->u.tag_cmd.command, linux_command_line, - ATAG_SIZE(walker)); - break; - default: - break; + walker = ATAG_NEXT(walker); } - walker = ATAG_NEXT(walker); + + /* Save a copy for later */ + bcopy(atag_list, atags, + (char *)walker - (char *)atag_list + ATAG_SIZE(walker)); +#endif + return fake_preload_metadata(abp); } +#ifdef FDT + else if (fdt_check_header(data) == 0) { + /* We have a DTB */ + + /* Find how much data to copy, and where to copy it to */ + fdt_len = fdt_totalsize(data); + lastaddr = build_fake_preload_metadata(abp, &preload_end); + + /* Move the fdt data to lastaddr */ + fdt_move(data, (void *)lastaddr, fdt_len); + + preload_end[0] = MODINFOMD_DTBP; + preload_end[1] = sizeof(vm_offset_t); + preload_end[2] = lastaddr; + preload_end[3] = 0; + preload_end[4] = 0; + + /* Move lastaddr to skop the dtb */ + lastaddr += fdt_len; - /* Save a copy for later */ - bcopy(atag_list, atags, - (char *)walker - (char *)atag_list + ATAG_SIZE(walker)); + return roundup2(lastaddr, PAGE_SIZE); + } +#endif - return fake_preload_metadata(abp); + return 0; } #endif @@ -979,7 +1033,7 @@ freebsd_parse_boot_param(struct arm_boot ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t); ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t); #endif - preload_addr_relocate = KERNVIRTADDR - abp->apb_physaddr; + preload_addr_relocate = KERNVIRTADDR - abp->abp_physaddr; return lastaddr; } #endif @@ -989,12 +1043,10 @@ default_parse_boot_param(struct arm_boot { vm_offset_t lastaddr; -#if 0 #if defined(LINUX_BOOT_ABI) if ((lastaddr = linux_parse_boot_param(abp)) != 0) return lastaddr; #endif -#endif #if defined(FREEBSD_BOOT_LOADER) if ((lastaddr = freebsd_parse_boot_param(abp)) != 0) return lastaddr; @@ -1211,9 +1263,14 @@ initarm(struct arm_boot_params *abp) vm_offset_t rstart, rend; int curr; + /* + * This needs to be before parse_boot_param as we may map memory in. + * The pmap layer may use the CPUs cache functions which are defined + * when set_cpufuncs has been called. + */ + set_cpufuncs(); lastaddr = parse_boot_param(abp); memsize = 0; - set_cpufuncs(); /* * Find the dtb passed in by the boot loader. @@ -1343,7 +1400,7 @@ initarm(struct arm_boot_params *abp) /* Define a macro to simplify memory allocation */ #define valloc_pages(var, np) \ alloc_pages((var).pv_va, (np)); \ - (var).pv_pa = (var).pv_va + (abp->apb_physaddr - KERNVIRTADDR); + (var).pv_pa = (var).pv_va + (abp->abp_physaddr - KERNVIRTADDR); #define alloc_pages(var, np) \ (var) = freemempos; \ @@ -1364,7 +1421,7 @@ initarm(struct arm_boot_params *abp) L2_TABLE_SIZE_REAL * (i - j); kernel_pt_table[i].pv_pa = kernel_pt_table[i].pv_va - KERNVIRTADDR + - abp->apb_physaddr; + abp->abp_physaddr; } } @@ -1409,7 +1466,7 @@ initarm(struct arm_boot_params *abp) pmap_curmaxkvaddr = l2_start + (l2size - 1) * L1_S_SIZE; /* Map kernel code and data */ - pmap_map_chunk(l1pagetable, KERNVIRTADDR, abp->apb_physaddr, + pmap_map_chunk(l1pagetable, KERNVIRTADDR, abp->abp_physaddr, (((uint32_t)(lastaddr) - KERNVIRTADDR) + PAGE_MASK) & ~PAGE_MASK, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); @@ -1526,7 +1583,7 @@ initarm(struct arm_boot_params *abp) /* * Prepare map of physical memory regions available to vm subsystem. */ - physmap_init(availmem_regions, availmem_regions_sz, abp->apb_physaddr); + physmap_init(availmem_regions, availmem_regions_sz, abp->abp_physaddr); init_param2(physmem); kdb_init(); Modified: projects/specific_leg/sys/arm/include/cpu.h ============================================================================== --- projects/specific_leg/sys/arm/include/cpu.h Fri Dec 20 14:03:56 2013 (r259647) +++ projects/specific_leg/sys/arm/include/cpu.h Fri Dec 20 14:33:48 2013 (r259648) @@ -41,7 +41,8 @@ struct arm_boot_params { register_t abp_r1; /* r1 from the boot loader */ register_t abp_r2; /* r2 from the boot loader */ register_t abp_r3; /* r3 from the boot loader */ - register_t apb_physaddr; /* The kernel physical address */ + vm_offset_t abp_physaddr; /* The kernel physical address */ + vm_offset_t abp_pagetable; /* The early page table */ }; void arm_vector_init(vm_offset_t, int);