From owner-svn-src-user@FreeBSD.ORG Fri Nov 9 17:47:55 2012 Return-Path: Delivered-To: svn-src-user@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 6386492A; Fri, 9 Nov 2012 17:47:55 +0000 (UTC) (envelope-from andre@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) by mx1.freebsd.org (Postfix) with ESMTP id 467478FC12; Fri, 9 Nov 2012 17:47:55 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.5/8.14.5) with ESMTP id qA9HltCU023663; Fri, 9 Nov 2012 17:47:55 GMT (envelope-from andre@svn.freebsd.org) Received: (from andre@localhost) by svn.freebsd.org (8.14.5/8.14.5/Submit) id qA9HltMn023656; Fri, 9 Nov 2012 17:47:55 GMT (envelope-from andre@svn.freebsd.org) Message-Id: <201211091747.qA9HltMn023656@svn.freebsd.org> From: Andre Oppermann Date: Fri, 9 Nov 2012 17:47:55 +0000 (UTC) To: src-committers@freebsd.org, svn-src-user@freebsd.org Subject: svn commit: r242831 - in user/andre/tcp_workqueue/sys: amd64/amd64 arm/arm arm/at91 arm/broadcom/bcm2835 arm/include arm/lpc arm/mv arm/tegra arm/ti boot/common boot/forth boot/i386/boot2 boot/i386... X-SVN-Group: user MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-user@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the experimental " user" src tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 09 Nov 2012 17:47:55 -0000 Author: andre Date: Fri Nov 9 17:47:54 2012 New Revision: 242831 URL: http://svnweb.freebsd.org/changeset/base/242831 Log: Integrate from HEAD @242829, except for r242601 which is the backout of r242262. Added: user/andre/tcp_workqueue/sys/boot/forth/menusets.4th - copied unchanged from r242829, head/sys/boot/forth/menusets.4th user/andre/tcp_workqueue/sys/boot/forth/menusets.4th.8 - copied unchanged from r242829, head/sys/boot/forth/menusets.4th.8 user/andre/tcp_workqueue/sys/cddl/contrib/opensolaris/uts/powerpc/ - copied from r242829, head/sys/cddl/contrib/opensolaris/uts/powerpc/ user/andre/tcp_workqueue/sys/cddl/dev/dtrace/powerpc/ - copied from r242829, head/sys/cddl/dev/dtrace/powerpc/ user/andre/tcp_workqueue/sys/dev/ath/if_ath_alq.c - copied unchanged from r242829, head/sys/dev/ath/if_ath_alq.c user/andre/tcp_workqueue/sys/dev/ath/if_ath_alq.h - copied unchanged from r242829, head/sys/dev/ath/if_ath_alq.h Modified: user/andre/tcp_workqueue/sys/amd64/amd64/identcpu.c user/andre/tcp_workqueue/sys/amd64/amd64/pmap.c user/andre/tcp_workqueue/sys/arm/arm/machdep.c user/andre/tcp_workqueue/sys/arm/at91/at91_machdep.c user/andre/tcp_workqueue/sys/arm/broadcom/bcm2835/bcm2835_machdep.c user/andre/tcp_workqueue/sys/arm/include/machdep.h user/andre/tcp_workqueue/sys/arm/lpc/lpc_gpio.c user/andre/tcp_workqueue/sys/arm/lpc/lpc_machdep.c user/andre/tcp_workqueue/sys/arm/mv/mv_machdep.c user/andre/tcp_workqueue/sys/arm/tegra/tegra2_machdep.c user/andre/tcp_workqueue/sys/arm/ti/ti_machdep.c user/andre/tcp_workqueue/sys/boot/common/Makefile.inc user/andre/tcp_workqueue/sys/boot/forth/loader.4th user/andre/tcp_workqueue/sys/boot/forth/menu-commands.4th user/andre/tcp_workqueue/sys/boot/forth/menu.4th user/andre/tcp_workqueue/sys/boot/i386/boot2/sio.S user/andre/tcp_workqueue/sys/boot/i386/loader/Makefile user/andre/tcp_workqueue/sys/boot/ia64/common/Makefile user/andre/tcp_workqueue/sys/boot/pc98/boot2/Makefile user/andre/tcp_workqueue/sys/boot/pc98/cdboot/Makefile user/andre/tcp_workqueue/sys/boot/pc98/loader/Makefile user/andre/tcp_workqueue/sys/boot/powerpc/ofw/Makefile user/andre/tcp_workqueue/sys/boot/powerpc/ps3/Makefile user/andre/tcp_workqueue/sys/boot/sparc64/loader/Makefile user/andre/tcp_workqueue/sys/cam/scsi/scsi_enc_ses.c user/andre/tcp_workqueue/sys/cddl/compat/opensolaris/kern/opensolaris_lookup.c user/andre/tcp_workqueue/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c user/andre/tcp_workqueue/sys/cddl/contrib/opensolaris/uts/common/dtrace/dtrace.c user/andre/tcp_workqueue/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_ctldir.c user/andre/tcp_workqueue/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_dir.c user/andre/tcp_workqueue/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c user/andre/tcp_workqueue/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c user/andre/tcp_workqueue/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c user/andre/tcp_workqueue/sys/cddl/dev/lockstat/lockstat.c user/andre/tcp_workqueue/sys/cddl/dev/profile/profile.c user/andre/tcp_workqueue/sys/conf/files.powerpc user/andre/tcp_workqueue/sys/conf/kern.pre.mk user/andre/tcp_workqueue/sys/conf/options user/andre/tcp_workqueue/sys/contrib/ngatm/netnatm/msg/uni_ie.c user/andre/tcp_workqueue/sys/dev/aac/aac_debug.c user/andre/tcp_workqueue/sys/dev/ahci/ahciem.c user/andre/tcp_workqueue/sys/dev/ale/if_ale.c user/andre/tcp_workqueue/sys/dev/asmc/asmc.c user/andre/tcp_workqueue/sys/dev/ata/ata-card.c user/andre/tcp_workqueue/sys/dev/ata/chipsets/ata-acard.c user/andre/tcp_workqueue/sys/dev/ata/chipsets/ata-acerlabs.c user/andre/tcp_workqueue/sys/dev/ata/chipsets/ata-adaptec.c user/andre/tcp_workqueue/sys/dev/ata/chipsets/ata-amd.c user/andre/tcp_workqueue/sys/dev/ata/chipsets/ata-ati.c user/andre/tcp_workqueue/sys/dev/ata/chipsets/ata-highpoint.c user/andre/tcp_workqueue/sys/dev/ata/chipsets/ata-intel.c user/andre/tcp_workqueue/sys/dev/ata/chipsets/ata-ite.c user/andre/tcp_workqueue/sys/dev/ata/chipsets/ata-jmicron.c user/andre/tcp_workqueue/sys/dev/ata/chipsets/ata-marvell.c user/andre/tcp_workqueue/sys/dev/ata/chipsets/ata-nvidia.c user/andre/tcp_workqueue/sys/dev/ata/chipsets/ata-promise.c user/andre/tcp_workqueue/sys/dev/ata/chipsets/ata-serverworks.c user/andre/tcp_workqueue/sys/dev/ata/chipsets/ata-siliconimage.c user/andre/tcp_workqueue/sys/dev/ata/chipsets/ata-sis.c user/andre/tcp_workqueue/sys/dev/ata/chipsets/ata-via.c user/andre/tcp_workqueue/sys/dev/ath/ath_hal/ah.h user/andre/tcp_workqueue/sys/dev/ath/ath_hal/ah_debug.h user/andre/tcp_workqueue/sys/dev/ath/ath_hal/ah_internal.h user/andre/tcp_workqueue/sys/dev/ath/ath_hal/ar5212/ar5212.h user/andre/tcp_workqueue/sys/dev/ath/ath_hal/ar5416/ar5416.h user/andre/tcp_workqueue/sys/dev/ath/ath_hal/ar5416/ar5416_xmit.c user/andre/tcp_workqueue/sys/dev/ath/if_ath.c user/andre/tcp_workqueue/sys/dev/ath/if_ath_debug.c user/andre/tcp_workqueue/sys/dev/ath/if_ath_debug.h user/andre/tcp_workqueue/sys/dev/ath/if_ath_rx.c user/andre/tcp_workqueue/sys/dev/ath/if_ath_rx_edma.c user/andre/tcp_workqueue/sys/dev/ath/if_ath_sysctl.c user/andre/tcp_workqueue/sys/dev/ath/if_ath_tx.c user/andre/tcp_workqueue/sys/dev/ath/if_ath_tx_edma.c user/andre/tcp_workqueue/sys/dev/ath/if_ath_tx_ht.c user/andre/tcp_workqueue/sys/dev/ath/if_athvar.h user/andre/tcp_workqueue/sys/dev/bge/if_bge.c user/andre/tcp_workqueue/sys/dev/bktr/bktr_audio.c user/andre/tcp_workqueue/sys/dev/cas/if_cas.c user/andre/tcp_workqueue/sys/dev/cpuctl/cpuctl.c user/andre/tcp_workqueue/sys/dev/cxgbe/tom/t4_cpl_io.c user/andre/tcp_workqueue/sys/dev/cxgbe/tom/t4_listen.c user/andre/tcp_workqueue/sys/dev/dc/if_dc.c user/andre/tcp_workqueue/sys/dev/drm/via_dma.c user/andre/tcp_workqueue/sys/dev/drm/via_dmablit.c user/andre/tcp_workqueue/sys/dev/etherswitch/arswitch/arswitch.c user/andre/tcp_workqueue/sys/dev/flash/at45d.c user/andre/tcp_workqueue/sys/dev/fxp/if_fxp.c user/andre/tcp_workqueue/sys/dev/gem/if_gem_pci.c user/andre/tcp_workqueue/sys/dev/lge/if_lge.c user/andre/tcp_workqueue/sys/dev/md/md.c user/andre/tcp_workqueue/sys/dev/mfi/mfi.c user/andre/tcp_workqueue/sys/dev/mfi/mfi_cam.c user/andre/tcp_workqueue/sys/dev/mfi/mfi_disk.c user/andre/tcp_workqueue/sys/dev/mfi/mfi_syspd.c user/andre/tcp_workqueue/sys/dev/mfi/mfi_tbolt.c user/andre/tcp_workqueue/sys/dev/mfi/mfivar.h user/andre/tcp_workqueue/sys/dev/mii/mii.c user/andre/tcp_workqueue/sys/dev/mn/if_mn.c user/andre/tcp_workqueue/sys/dev/nge/if_nge.c user/andre/tcp_workqueue/sys/dev/nxge/xgehal/xgehal-device.c user/andre/tcp_workqueue/sys/dev/pci/pci.c user/andre/tcp_workqueue/sys/dev/puc/pucdata.c user/andre/tcp_workqueue/sys/dev/re/if_re.c user/andre/tcp_workqueue/sys/dev/sis/if_sis.c user/andre/tcp_workqueue/sys/dev/sound/pci/emu10kx.c user/andre/tcp_workqueue/sys/dev/ste/if_ste.c user/andre/tcp_workqueue/sys/dev/stge/if_stge.c user/andre/tcp_workqueue/sys/dev/syscons/scvidctl.c user/andre/tcp_workqueue/sys/dev/ti/if_ti.c user/andre/tcp_workqueue/sys/dev/tl/if_tl.c user/andre/tcp_workqueue/sys/dev/twa/tw_cl_misc.c user/andre/tcp_workqueue/sys/dev/uart/uart_bus_acpi.c user/andre/tcp_workqueue/sys/dev/usb/controller/dwc_otg.c user/andre/tcp_workqueue/sys/dev/usb/controller/dwc_otg.h user/andre/tcp_workqueue/sys/dev/usb/controller/dwc_otgreg.h user/andre/tcp_workqueue/sys/dev/usb/controller/ehci.c user/andre/tcp_workqueue/sys/dev/usb/controller/ehci.h user/andre/tcp_workqueue/sys/dev/usb/net/if_udav.c user/andre/tcp_workqueue/sys/dev/usb/quirk/usb_quirk.c user/andre/tcp_workqueue/sys/dev/usb/quirk/usb_quirk.h user/andre/tcp_workqueue/sys/dev/usb/serial/usb_serial.c user/andre/tcp_workqueue/sys/dev/usb/serial/usb_serial.h user/andre/tcp_workqueue/sys/dev/usb/storage/umass.c user/andre/tcp_workqueue/sys/dev/usb/usbdevs user/andre/tcp_workqueue/sys/dev/vr/if_vr.c user/andre/tcp_workqueue/sys/dev/wb/if_wb.c user/andre/tcp_workqueue/sys/dev/xl/if_xl.c user/andre/tcp_workqueue/sys/fs/fuse/fuse_file.c user/andre/tcp_workqueue/sys/fs/fuse/fuse_internal.c user/andre/tcp_workqueue/sys/fs/fuse/fuse_internal.h user/andre/tcp_workqueue/sys/fs/fuse/fuse_io.c user/andre/tcp_workqueue/sys/fs/fuse/fuse_node.c user/andre/tcp_workqueue/sys/fs/fuse/fuse_node.h user/andre/tcp_workqueue/sys/fs/fuse/fuse_vnops.c user/andre/tcp_workqueue/sys/i386/i386/pmap.c user/andre/tcp_workqueue/sys/ia64/ia64/pmap.c user/andre/tcp_workqueue/sys/kern/kern_malloc.c user/andre/tcp_workqueue/sys/kern/kern_rwlock.c user/andre/tcp_workqueue/sys/kern/sched_ule.c user/andre/tcp_workqueue/sys/kern/tty.c user/andre/tcp_workqueue/sys/kern/vfs_subr.c user/andre/tcp_workqueue/sys/libkern/strlcpy.c user/andre/tcp_workqueue/sys/libkern/strlen.c user/andre/tcp_workqueue/sys/mips/conf/AP91.hints user/andre/tcp_workqueue/sys/mips/conf/AP93.hints user/andre/tcp_workqueue/sys/mips/conf/AP96.hints user/andre/tcp_workqueue/sys/mips/conf/RSPRO.hints user/andre/tcp_workqueue/sys/mips/mips/pmap.c user/andre/tcp_workqueue/sys/modules/Makefile user/andre/tcp_workqueue/sys/modules/dtrace/Makefile user/andre/tcp_workqueue/sys/modules/nxge/Makefile user/andre/tcp_workqueue/sys/net/bpf.c user/andre/tcp_workqueue/sys/netinet/sctp_constants.h user/andre/tcp_workqueue/sys/netinet/sctp_indata.c user/andre/tcp_workqueue/sys/netinet/sctp_input.c user/andre/tcp_workqueue/sys/netinet/sctp_output.c user/andre/tcp_workqueue/sys/netinet/sctp_pcb.c user/andre/tcp_workqueue/sys/netinet/sctp_structs.h user/andre/tcp_workqueue/sys/netinet/sctp_timer.c user/andre/tcp_workqueue/sys/netinet/sctputil.c user/andre/tcp_workqueue/sys/netinet/tcp_output.c user/andre/tcp_workqueue/sys/netinet/tcp_subr.c user/andre/tcp_workqueue/sys/netpfil/ipfw/ip_fw_dynamic.c user/andre/tcp_workqueue/sys/netpfil/ipfw/ip_fw_nat.c user/andre/tcp_workqueue/sys/netpfil/ipfw/ip_fw_private.h user/andre/tcp_workqueue/sys/netpfil/pf/if_pfsync.c user/andre/tcp_workqueue/sys/pci/if_rl.c user/andre/tcp_workqueue/sys/powerpc/aim/locore32.S user/andre/tcp_workqueue/sys/powerpc/aim/locore64.S user/andre/tcp_workqueue/sys/powerpc/aim/mmu_oea.c user/andre/tcp_workqueue/sys/powerpc/aim/trap.c user/andre/tcp_workqueue/sys/powerpc/aim/trap_subr32.S user/andre/tcp_workqueue/sys/powerpc/aim/trap_subr64.S user/andre/tcp_workqueue/sys/powerpc/booke/locore.S user/andre/tcp_workqueue/sys/powerpc/booke/machdep.c user/andre/tcp_workqueue/sys/powerpc/booke/platform_bare.c user/andre/tcp_workqueue/sys/powerpc/booke/pmap.c user/andre/tcp_workqueue/sys/powerpc/conf/GENERIC user/andre/tcp_workqueue/sys/sparc64/include/pmap.h user/andre/tcp_workqueue/sys/sparc64/pci/fire.c user/andre/tcp_workqueue/sys/sparc64/pci/psycho.c user/andre/tcp_workqueue/sys/sparc64/pci/schizo.c user/andre/tcp_workqueue/sys/sparc64/sparc64/pmap.c user/andre/tcp_workqueue/sys/sys/_rwlock.h user/andre/tcp_workqueue/sys/sys/param.h user/andre/tcp_workqueue/sys/sys/rwlock.h user/andre/tcp_workqueue/sys/sys/tty.h user/andre/tcp_workqueue/sys/ufs/ffs/ffs_alloc.c user/andre/tcp_workqueue/sys/ufs/ffs/ffs_balloc.c user/andre/tcp_workqueue/sys/ufs/ffs/ffs_softdep.c Directory Properties: user/andre/tcp_workqueue/sys/ (props changed) user/andre/tcp_workqueue/sys/boot/ (props changed) user/andre/tcp_workqueue/sys/boot/powerpc/ofw/ (props changed) user/andre/tcp_workqueue/sys/cddl/contrib/opensolaris/ (props changed) user/andre/tcp_workqueue/sys/conf/ (props changed) Modified: user/andre/tcp_workqueue/sys/amd64/amd64/identcpu.c ============================================================================== --- user/andre/tcp_workqueue/sys/amd64/amd64/identcpu.c Fri Nov 9 17:46:07 2012 (r242830) +++ user/andre/tcp_workqueue/sys/amd64/amd64/identcpu.c Fri Nov 9 17:47:54 2012 (r242831) @@ -481,7 +481,7 @@ SYSINIT(hook_tsc_freq, SI_SUB_CONFIGURE, void identify_cpu(void) { - u_int regs[4]; + u_int regs[4], cpu_stdext_disable; do_cpuid(0, regs); cpu_high = regs[0]; @@ -516,6 +516,20 @@ identify_cpu(void) if (cpu_high >= 7) { cpuid_count(7, 0, regs); cpu_stdext_feature = regs[1]; + + /* + * Some hypervisors fail to filter out unsupported + * extended features. For now, disable the + * extensions, activation of which requires setting a + * bit in CR4, and which VM monitors do not support. + */ + if (cpu_feature2 & CPUID2_HV) { + cpu_stdext_disable = CPUID_STDEXT_FSGSBASE | + CPUID_STDEXT_SMEP; + } else + cpu_stdext_disable = 0; + TUNABLE_INT_FETCH("hw.cpu_stdext_disable", &cpu_stdext_disable); + cpu_stdext_feature &= ~cpu_stdext_disable; } if (cpu_vendor_id == CPU_VENDOR_INTEL || Modified: user/andre/tcp_workqueue/sys/amd64/amd64/pmap.c ============================================================================== --- user/andre/tcp_workqueue/sys/amd64/amd64/pmap.c Fri Nov 9 17:46:07 2012 (r242830) +++ user/andre/tcp_workqueue/sys/amd64/amd64/pmap.c Fri Nov 9 17:47:54 2012 (r242831) @@ -225,16 +225,7 @@ u_int64_t KPML4phys; /* phys addr of ke static u_int64_t DMPDphys; /* phys addr of direct mapped level 2 */ static u_int64_t DMPDPphys; /* phys addr of direct mapped level 3 */ -/* - * Isolate the global pv list lock from data and other locks to prevent false - * sharing within the cache. - */ -static struct { - struct rwlock lock; - char padding[CACHE_LINE_SIZE - sizeof(struct rwlock)]; -} pvh_global __aligned(CACHE_LINE_SIZE); - -#define pvh_global_lock pvh_global.lock +static struct rwlock_padalign pvh_global_lock; /* * Data for the pv entry allocation mechanism Modified: user/andre/tcp_workqueue/sys/arm/arm/machdep.c ============================================================================== --- user/andre/tcp_workqueue/sys/arm/arm/machdep.c Fri Nov 9 17:46:07 2012 (r242830) +++ user/andre/tcp_workqueue/sys/arm/arm/machdep.c Fri Nov 9 17:47:54 2012 (r242831) @@ -44,6 +44,7 @@ #include "opt_compat.h" #include "opt_ddb.h" +#include "opt_platform.h" #include "opt_timer.h" #include @@ -59,11 +60,13 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include #include #include #include +#include #include #include #include @@ -94,6 +97,17 @@ __FBSDID("$FreeBSD$"); #include #include +#ifdef FDT +#include +#include +#endif + +#ifdef DEBUG +#define debugf(fmt, args...) printf(fmt, ##args) +#else +#define debugf(fmt, args...) +#endif + struct pcpu __pcpu[MAXCPU]; struct pcpu *pcpup = &__pcpu[0]; @@ -114,6 +128,35 @@ extern int *end; extern vm_offset_t ksym_start, ksym_end; #endif +#ifdef FDT +/* + * This is the number of L2 page tables required for covering max + * (hypothetical) memsize of 4GB and all kernel mappings (vectors, msgbuf, + * stacks etc.), uprounded to be divisible by 4. + */ +#define KERNEL_PT_MAX 78 + +static struct pv_addr kernel_pt_table[KERNEL_PT_MAX]; + +vm_paddr_t phys_avail[10]; +vm_paddr_t dump_avail[4]; + +extern u_int data_abort_handler_address; +extern u_int prefetch_abort_handler_address; +extern u_int undefined_handler_address; + +vm_paddr_t pmap_pa; + +struct pv_addr systempage; +static struct pv_addr msgbufpv; +struct pv_addr irqstack; +struct pv_addr undstack; +struct pv_addr abtstack; +static struct pv_addr kernelstack; + +const struct pmap_devmap *pmap_devmap_bootstrap_table; +#endif + #if defined(LINUX_BOOT_ABI) #define LBABI_MAX_BANKS 10 @@ -961,3 +1004,407 @@ set_stackptrs(int cpu) undstack.pv_va + ((UND_STACK_SIZE * PAGE_SIZE) * (cpu + 1))); } +#ifdef FDT +static char * +kenv_next(char *cp) +{ + + if (cp != NULL) { + while (*cp != 0) + cp++; + cp++; + if (*cp == 0) + cp = NULL; + } + return (cp); +} + +static void +print_kenv(void) +{ + int len; + char *cp; + + debugf("loader passed (static) kenv:\n"); + if (kern_envp == NULL) { + debugf(" no env, null ptr\n"); + return; + } + debugf(" kern_envp = 0x%08x\n", (uint32_t)kern_envp); + + len = 0; + for (cp = kern_envp; cp != NULL; cp = kenv_next(cp)) + debugf(" %x %s\n", (uint32_t)cp, cp); +} + +static void +print_kernel_section_addr(void) +{ + + debugf("kernel image addresses:\n"); + debugf(" kernbase = 0x%08x\n", (uint32_t)kernbase); + debugf(" _etext (sdata) = 0x%08x\n", (uint32_t)_etext); + debugf(" _edata = 0x%08x\n", (uint32_t)_edata); + debugf(" __bss_start = 0x%08x\n", (uint32_t)__bss_start); + debugf(" _end = 0x%08x\n", (uint32_t)_end); +} + +static 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; + debugf("processing avail regions:\n"); + for (mp = availmem_regions; mp->mr_size; mp++) { + s = mp->mr_start; + e = mp->mr_start + mp->mr_size; + debugf(" %08x-%08x -> ", 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; + debugf("%08x-%08x = %x\n", s, e, sz); + + /* Check whether some memory is left here. */ + if (sz == 0) { + empty: + printf("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 */ + debugf("fill in phys_avail:\n"); + for (i = 0, j = 0; i < availmem_regions_sz; i++, j += 2) { + + debugf(" region: 0x%08x - 0x%08x (0x%08x)\n", + availmem_regions[i].mr_start, + availmem_regions[i].mr_start + availmem_regions[i].mr_size, + availmem_regions[i].mr_size); + + /* + * We should not map the page at PA 0x0000000, the VM can't + * handle it, as pmap_extract() == 0 means failure. + */ + if (availmem_regions[i].mr_start > 0 || + availmem_regions[i].mr_size > PAGE_SIZE) { + phys_avail[j] = availmem_regions[i].mr_start; + if (phys_avail[j] == 0) + phys_avail[j] += PAGE_SIZE; + phys_avail[j + 1] = availmem_regions[i].mr_start + + availmem_regions[i].mr_size; + } else + j -= 2; + } + phys_avail[j] = 0; + phys_avail[j + 1] = 0; +} + +void * +initarm(struct arm_boot_params *abp) +{ + struct mem_region availmem_regions[FDT_MEM_REGIONS]; + struct pv_addr kernel_l1pt; + struct pv_addr dpcpu; + vm_offset_t dtbp, freemempos, l2_start, lastaddr; + vm_offset_t pmap_bootstrap_lastaddr; + uint32_t memsize, l2size; + char *env; + void *kmdp; + u_int l1pagetable; + int i = 0, j = 0, err_devmap = 0; + int availmem_regions_sz; + + lastaddr = parse_boot_param(abp); + memsize = 0; + set_cpufuncs(); + + /* + * Find the dtb passed in by the boot loader. + */ + kmdp = preload_search_by_type("elf kernel"); + if (kmdp != NULL) + dtbp = MD_FETCH(kmdp, MODINFOMD_DTBP, vm_offset_t); + else + dtbp = (vm_offset_t)NULL; + +#if defined(FDT_DTB_STATIC) + /* + * In case the device tree blob was not retrieved (from metadata) try + * to use the statically embedded one. + */ + if (dtbp == (vm_offset_t)NULL) + dtbp = (vm_offset_t)&fdt_static_dtb; +#endif + + if (OF_install(OFW_FDT, 0) == FALSE) + while (1); + + if (OF_init((void *)dtbp) != 0) + while (1); + + /* Grab physical memory regions information from device tree. */ + if (fdt_get_mem_regions(availmem_regions, &availmem_regions_sz, + &memsize) != 0) + while(1); + + /* Platform-specific initialisation */ + pmap_bootstrap_lastaddr = initarm_lastaddr(); + + pcpu0_init(); + + /* Do basic tuning, hz etc */ + init_param1(); + + /* Calculate number of L2 tables needed for mapping vm_page_array */ + l2size = (memsize / PAGE_SIZE) * sizeof(struct vm_page); + l2size = (l2size >> L1_S_SHIFT) + 1; + + /* + * Add one table for end of kernel map, one for stacks, msgbuf and + * L1 and L2 tables map and one for vectors map. + */ + l2size += 3; + + /* Make it divisible by 4 */ + l2size = (l2size + 3) & ~3; + + freemempos = (lastaddr + PAGE_MASK) & ~PAGE_MASK; + + /* Define a macro to simplify memory allocation */ +#define valloc_pages(var, np) \ + alloc_pages((var).pv_va, (np)); \ + (var).pv_pa = (var).pv_va + (KERNPHYSADDR - KERNVIRTADDR); + +#define alloc_pages(var, np) \ + (var) = freemempos; \ + freemempos += (np * PAGE_SIZE); \ + memset((char *)(var), 0, ((np) * PAGE_SIZE)); + + while (((freemempos - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) != 0) + freemempos += PAGE_SIZE; + valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE); + + for (i = 0; i < l2size; ++i) { + if (!(i % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) { + valloc_pages(kernel_pt_table[i], + L2_TABLE_SIZE / PAGE_SIZE); + j = i; + } else { + kernel_pt_table[i].pv_va = kernel_pt_table[j].pv_va + + L2_TABLE_SIZE_REAL * (i - j); + kernel_pt_table[i].pv_pa = + kernel_pt_table[i].pv_va - KERNVIRTADDR + + KERNPHYSADDR; + + } + } + /* + * 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. + */ + valloc_pages(systempage, 1); + + /* Allocate dynamic per-cpu area. */ + valloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE); + dpcpu_init((void *)dpcpu.pv_va, 0); + + /* Allocate stacks for all modes */ + valloc_pages(irqstack, IRQ_STACK_SIZE * MAXCPU); + valloc_pages(abtstack, ABT_STACK_SIZE * MAXCPU); + valloc_pages(undstack, UND_STACK_SIZE * MAXCPU); + valloc_pages(kernelstack, KSTACK_PAGES * MAXCPU); + valloc_pages(msgbufpv, round_page(msgbufsize) / PAGE_SIZE); + + /* + * Now we start construction of the L1 page table + * We start by mapping the L2 page tables into the L1. + * This means that we can replace L1 mappings later on if necessary + */ + l1pagetable = kernel_l1pt.pv_va; + + /* + * Try to map as much as possible of kernel text and data using + * 1MB section mapping and for the rest of initial kernel address + * space use L2 coarse tables. + * + * Link L2 tables for mapping remainder of kernel (modulo 1MB) + * and kernel structures + */ + l2_start = lastaddr & ~(L1_S_OFFSET); + for (i = 0 ; i < l2size - 1; i++) + pmap_link_l2pt(l1pagetable, l2_start + i * L1_S_SIZE, + &kernel_pt_table[i]); + + pmap_curmaxkvaddr = l2_start + (l2size - 1) * L1_S_SIZE; + + /* Map kernel code and data */ + pmap_map_chunk(l1pagetable, KERNVIRTADDR, KERNPHYSADDR, + (((uint32_t)(lastaddr) - KERNVIRTADDR) + PAGE_MASK) & ~PAGE_MASK, + VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); + + + /* Map L1 directory and allocated L2 page tables */ + pmap_map_chunk(l1pagetable, kernel_l1pt.pv_va, kernel_l1pt.pv_pa, + L1_TABLE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE); + + pmap_map_chunk(l1pagetable, kernel_pt_table[0].pv_va, + kernel_pt_table[0].pv_pa, + L2_TABLE_SIZE_REAL * l2size, + VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE); + + /* Map allocated DPCPU, stacks and msgbuf */ + pmap_map_chunk(l1pagetable, dpcpu.pv_va, dpcpu.pv_pa, + freemempos - dpcpu.pv_va, + VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); + + /* Link and map the vector page */ + pmap_link_l2pt(l1pagetable, ARM_VECTORS_HIGH, + &kernel_pt_table[l2size - 1]); + pmap_map_entry(l1pagetable, ARM_VECTORS_HIGH, systempage.pv_pa, + VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE, PTE_CACHE); + + /* Map pmap_devmap[] entries */ + err_devmap = platform_devmap_init(); + pmap_devmap_bootstrap(l1pagetable, pmap_devmap_bootstrap_table); + + cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)) | DOMAIN_CLIENT); + pmap_pa = kernel_l1pt.pv_pa; + setttb(kernel_l1pt.pv_pa); + cpu_tlb_flushID(); + cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)); + + /* + * Only after the SOC registers block is mapped we can perform device + * tree fixups, as they may attempt to read parameters from hardware. + */ + OF_interpret("perform-fixup", 0); + + initarm_gpio_init(); + + cninit(); + + physmem = memsize / PAGE_SIZE; + + debugf("initarm: console initialized\n"); + debugf(" arg1 kmdp = 0x%08x\n", (uint32_t)kmdp); + debugf(" boothowto = 0x%08x\n", boothowto); + debugf(" dtbp = 0x%08x\n", (uint32_t)dtbp); + print_kernel_section_addr(); + print_kenv(); + + env = getenv("kernelname"); + if (env != NULL) + strlcpy(kernelname, env, sizeof(kernelname)); + + if (err_devmap != 0) + printf("WARNING: could not fully configure devmap, error=%d\n", + err_devmap); + + initarm_late_init(); + + /* + * 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); + arm_dump_avail_init(memsize, sizeof(dump_avail) / sizeof(dump_avail[0])); + pmap_bootstrap(freemempos, pmap_bootstrap_lastaddr, &kernel_l1pt); + msgbufp = (void *)msgbufpv.pv_va; + msgbufinit(msgbufp, msgbufsize); + mutex_init(); + + /* + * Prepare map of physical memory regions available to vm subsystem. + */ + physmap_init(availmem_regions, availmem_regions_sz); + + init_param2(physmem); + kdb_init(); + + return ((void *)(kernelstack.pv_va + USPACE_SVC_STACK_TOP - + sizeof(struct pcb))); +} +#endif Modified: user/andre/tcp_workqueue/sys/arm/at91/at91_machdep.c ============================================================================== --- user/andre/tcp_workqueue/sys/arm/at91/at91_machdep.c Fri Nov 9 17:46:07 2012 (r242830) +++ user/andre/tcp_workqueue/sys/arm/at91/at91_machdep.c Fri Nov 9 17:47:54 2012 (r242831) @@ -96,6 +96,10 @@ __FBSDID("$FreeBSD$"); #include #include +#ifndef MAXCPU +#define MAXCPU 1 +#endif + /* Page table for mapping proc0 zero page */ #define KERNEL_PT_SYS 0 #define KERNEL_PT_KERN 1 @@ -454,7 +458,7 @@ initarm(struct arm_boot_params *abp) { struct pv_addr kernel_l1pt; struct pv_addr dpcpu; - int loop, i; + int i; u_int l1pagetable; vm_offset_t freemempos; vm_offset_t afterkern; @@ -482,23 +486,23 @@ initarm(struct arm_boot_params *abp) while (((freemempos - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) != 0) freemempos += PAGE_SIZE; valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE); - for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) { - if (!(loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) { - valloc_pages(kernel_pt_table[loop], + for (i = 0; i < NUM_KERNEL_PTS; ++i) { + if (!(i % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) { + valloc_pages(kernel_pt_table[i], L2_TABLE_SIZE / PAGE_SIZE); } else { - kernel_pt_table[loop].pv_va = freemempos - - (loop % (PAGE_SIZE / L2_TABLE_SIZE_REAL)) * + kernel_pt_table[i].pv_va = freemempos - + (i % (PAGE_SIZE / L2_TABLE_SIZE_REAL)) * L2_TABLE_SIZE_REAL; - kernel_pt_table[loop].pv_pa = - kernel_pt_table[loop].pv_va - KERNVIRTADDR + + kernel_pt_table[i].pv_pa = + kernel_pt_table[i].pv_va - KERNVIRTADDR + KERNPHYSADDR; } } /* - * Allocate a page for the system page mapped to V0x00000000 - * This page will just contain the system vectors and can be - * shared by all processes. + * 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. */ valloc_pages(systempage, 1); @@ -507,10 +511,10 @@ initarm(struct arm_boot_params *abp) dpcpu_init((void *)dpcpu.pv_va, 0); /* Allocate stacks for all modes */ - valloc_pages(irqstack, IRQ_STACK_SIZE); - valloc_pages(abtstack, ABT_STACK_SIZE); - valloc_pages(undstack, UND_STACK_SIZE); - valloc_pages(kernelstack, KSTACK_PAGES); + valloc_pages(irqstack, IRQ_STACK_SIZE * MAXCPU); + valloc_pages(abtstack, ABT_STACK_SIZE * MAXCPU); + valloc_pages(undstack, UND_STACK_SIZE * MAXCPU); + valloc_pages(kernelstack, KSTACK_PAGES * MAXCPU); valloc_pages(msgbufpv, round_page(msgbufsize) / PAGE_SIZE); /* @@ -558,17 +562,17 @@ initarm(struct arm_boot_params *abp) pmap_map_chunk(l1pagetable, msgbufpv.pv_va, msgbufpv.pv_pa, msgbufsize, VM_PROT_READ|VM_PROT_WRITE, PTE_CACHE); - for (loop = 0; loop < NUM_KERNEL_PTS; ++loop) { - pmap_map_chunk(l1pagetable, kernel_pt_table[loop].pv_va, - kernel_pt_table[loop].pv_pa, L2_TABLE_SIZE, + for (i = 0; i < NUM_KERNEL_PTS; ++i) { + pmap_map_chunk(l1pagetable, kernel_pt_table[i].pv_va, + kernel_pt_table[i].pv_pa, L2_TABLE_SIZE, VM_PROT_READ|VM_PROT_WRITE, PTE_PAGETABLE); } pmap_devmap_bootstrap(l1pagetable, at91_devmap); - cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)) | DOMAIN_CLIENT); + cpu_domains((DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)) | DOMAIN_CLIENT); setttb(kernel_l1pt.pv_pa); cpu_tlb_flushID(); - cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL*2)); + cpu_domains(DOMAIN_CLIENT << (PMAP_DOMAIN_KERNEL * 2)); at91_soc_id(); Modified: user/andre/tcp_workqueue/sys/arm/broadcom/bcm2835/bcm2835_machdep.c ============================================================================== --- user/andre/tcp_workqueue/sys/arm/broadcom/bcm2835/bcm2835_machdep.c Fri Nov 9 17:46:07 2012 (r242830) +++ user/andre/tcp_workqueue/sys/arm/broadcom/bcm2835/bcm2835_machdep.c Fri Nov 9 17:47:54 2012 (r242831) @@ -46,514 +46,23 @@ __FBSDID("$FreeBSD$"); #define _ARM32_BUS_DMA_PRIVATE #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include -#include - -#include -#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include + #include -#include +#include /* For trapframe_t, used in */ +#include +#include -#include +#include -#define DEBUG -#ifdef DEBUG -#define debugf(fmt, args...) printf(fmt, ##args) -#else -#define debugf(fmt, args...) -#endif +#include /* Start of address space used for bootstrap map */ #define DEVMAP_BOOTSTRAP_MAP_START 0xE0000000 -/* - * This is the number of L2 page tables required for covering max - * (hypothetical) memsize of 4GB and all kernel mappings (vectors, msgbuf, - * stacks etc.), uprounded to be divisible by 4. - */ -#define KERNEL_PT_MAX 78 - -extern unsigned char kernbase[]; -extern unsigned char _etext[]; -extern unsigned char _edata[]; -extern unsigned char __bss_start[]; -extern unsigned char _end[]; - -#ifdef DDB -extern vm_offset_t ksym_start, ksym_end; -#endif - -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; -extern int *end; - -struct pv_addr kernel_pt_table[KERNEL_PT_MAX]; - -/* Physical and virtual addresses for some global pages */ -vm_paddr_t phys_avail[10]; -vm_paddr_t dump_avail[4]; -vm_offset_t physical_pages; -vm_offset_t pmap_bootstrap_lastaddr; -vm_paddr_t pmap_pa; - -const struct pmap_devmap *pmap_devmap_bootstrap_table; -struct pv_addr systempage; -struct pv_addr msgbufpv; -struct pv_addr irqstack; -struct pv_addr undstack; -struct pv_addr abtstack; -struct pv_addr kernelstack; - -static struct mem_region availmem_regions[FDT_MEM_REGIONS]; -static int availmem_regions_sz; - -static void print_kenv(void); -static void print_kernel_section_addr(void); - -static void physmap_init(void); -static int platform_devmap_init(void); - -static char * -kenv_next(char *cp) -{ - - if (cp != NULL) { - while (*cp != 0) - cp++; - cp++; - if (*cp == 0) - cp = NULL; - } - return (cp); -} - -static void -print_kenv(void) -{ - int len; - char *cp; - - debugf("loader passed (static) kenv:\n"); - if (kern_envp == NULL) { - debugf(" no env, null ptr\n"); - return; - } - debugf(" kern_envp = 0x%08x\n", (uint32_t)kern_envp); - - len = 0; - for (cp = kern_envp; cp != NULL; cp = kenv_next(cp)) - debugf(" %x %s\n", (uint32_t)cp, cp); -} - -static void -print_kernel_section_addr(void) -{ - - debugf("kernel image addresses:\n"); - debugf(" kernbase = 0x%08x\n", (uint32_t)kernbase); - debugf(" _etext (sdata) = 0x%08x\n", (uint32_t)_etext); - debugf(" _edata = 0x%08x\n", (uint32_t)_edata); - debugf(" __bss_start = 0x%08x\n", (uint32_t)__bss_start); - debugf(" _end = 0x%08x\n", (uint32_t)_end); -} - -static void -physmap_init(void) -{ - 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; - debugf("processing avail regions:\n"); - for (mp = availmem_regions; mp->mr_size; mp++) { - s = mp->mr_start; - e = mp->mr_start + mp->mr_size; - debugf(" %08x-%08x -> ", 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; - debugf("%08x-%08x = %x\n", s, e, sz); - - /* Check whether some memory is left here. */ - if (sz == 0) { - empty: - printf("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 */ - debugf("fill in phys_avail:\n"); - for (i = 0, j = 0; i < availmem_regions_sz; i++, j += 2) { - - debugf(" region: 0x%08x - 0x%08x (0x%08x)\n", - availmem_regions[i].mr_start, - availmem_regions[i].mr_start + availmem_regions[i].mr_size, - availmem_regions[i].mr_size); - - /* - * We should not map the page at PA 0x0000000, the VM can't - * handle it, as pmap_extract() == 0 means failure. - */ - if (availmem_regions[i].mr_start > 0 || - availmem_regions[i].mr_size > PAGE_SIZE) { - phys_avail[j] = availmem_regions[i].mr_start; - if (phys_avail[j] == 0) - phys_avail[j] += PAGE_SIZE; - phys_avail[j + 1] = availmem_regions[i].mr_start + - availmem_regions[i].mr_size; - } else - j -= 2; - } - phys_avail[j] = 0; - phys_avail[j + 1] = 0; -} - -void * -initarm(struct arm_boot_params *abp) -{ - struct pv_addr kernel_l1pt; - struct pv_addr dpcpu; - vm_offset_t dtbp, freemempos, l2_start, lastaddr; - uint32_t memsize, l2size; - char *env; - void *kmdp; - u_int l1pagetable; - int i = 0, j = 0, err_devmap = 0; - - lastaddr = parse_boot_param(abp); - memsize = 0; - set_cpufuncs(); - - /* - * Find the dtb passed in by the boot loader. - */ - kmdp = preload_search_by_type("elf kernel"); - if (kmdp != NULL) - dtbp = MD_FETCH(kmdp, MODINFOMD_DTBP, vm_offset_t); - else - dtbp = (vm_offset_t)NULL; - -#if defined(FDT_DTB_STATIC) - /* - * In case the device tree blob was not retrieved (from metadata) try - * to use the statically embedded one. - */ - if (dtbp == (vm_offset_t)NULL) - dtbp = (vm_offset_t)&fdt_static_dtb; -#endif - - if (OF_install(OFW_FDT, 0) == FALSE) - while (1); - - if (OF_init((void *)dtbp) != 0) - while (1); - - /* Grab physical memory regions information from device tree. */ - if (fdt_get_mem_regions(availmem_regions, &availmem_regions_sz, - &memsize) != 0) - while(1); - - /* Platform-specific initialisation */ - pmap_bootstrap_lastaddr = initarm_lastaddr(); - - pcpu0_init(); - - /* Calculate number of L2 tables needed for mapping vm_page_array */ - l2size = (memsize / PAGE_SIZE) * sizeof(struct vm_page); - l2size = (l2size >> L1_S_SHIFT) + 1; - - /* - * Add one table for end of kernel map, one for stacks, msgbuf and - * L1 and L2 tables map and one for vectors map. - */ - l2size += 3; - - /* Make it divisible by 4 */ - l2size = (l2size + 3) & ~3; - -#define KERNEL_TEXT_BASE (KERNBASE) - freemempos = (lastaddr + PAGE_MASK) & ~PAGE_MASK; - - /* Define a macro to simplify memory allocation */ -#define valloc_pages(var, np) \ - alloc_pages((var).pv_va, (np)); \ - (var).pv_pa = (var).pv_va + (KERNPHYSADDR - KERNVIRTADDR); - -#define alloc_pages(var, np) \ - (var) = freemempos; \ - freemempos += (np * PAGE_SIZE); \ - memset((char *)(var), 0, ((np) * PAGE_SIZE)); - - while (((freemempos - L1_TABLE_SIZE) & (L1_TABLE_SIZE - 1)) != 0) - freemempos += PAGE_SIZE; - valloc_pages(kernel_l1pt, L1_TABLE_SIZE / PAGE_SIZE); - - for (i = 0; i < l2size; ++i) { - if (!(i % (PAGE_SIZE / L2_TABLE_SIZE_REAL))) { - valloc_pages(kernel_pt_table[i], - L2_TABLE_SIZE / PAGE_SIZE); - j = i; - } else { - kernel_pt_table[i].pv_va = kernel_pt_table[j].pv_va + - L2_TABLE_SIZE_REAL * (i - j); - kernel_pt_table[i].pv_pa = - kernel_pt_table[i].pv_va - KERNVIRTADDR + - KERNPHYSADDR; - - } - } - /* - * 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. - */ - valloc_pages(systempage, 1); - - /* Allocate dynamic per-cpu area. */ - valloc_pages(dpcpu, DPCPU_SIZE / PAGE_SIZE); *** DIFF OUTPUT TRUNCATED AT 1000 LINES ***