From owner-svn-src-all@freebsd.org Tue Aug 25 14:39:44 2015 Return-Path: Delivered-To: svn-src-all@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id C162899D10F; Tue, 25 Aug 2015 14:39:44 +0000 (UTC) (envelope-from marcel@FreeBSD.org) Received: from repo.freebsd.org (repo.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id AF91FE41; Tue, 25 Aug 2015 14:39:44 +0000 (UTC) (envelope-from marcel@FreeBSD.org) Received: from repo.freebsd.org ([127.0.1.70]) by repo.freebsd.org (8.15.2/8.15.2) with ESMTP id t7PEdixb071534; Tue, 25 Aug 2015 14:39:44 GMT (envelope-from marcel@FreeBSD.org) Received: (from marcel@localhost) by repo.freebsd.org (8.15.2/8.15.2/Submit) id t7PEdf1B071523; Tue, 25 Aug 2015 14:39:41 GMT (envelope-from marcel@FreeBSD.org) Message-Id: <201508251439.t7PEdf1B071523@repo.freebsd.org> X-Authentication-Warning: repo.freebsd.org: marcel set sender to marcel@FreeBSD.org using -f From: Marcel Moolenaar Date: Tue, 25 Aug 2015 14:39:41 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-10@freebsd.org Subject: svn commit: r287126 - in stable/10/sys: amd64/amd64 conf dev/vt/hw/efifb dev/vt/hw/vga i386/i386 x86/include x86/x86 X-SVN-Group: stable-10 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 25 Aug 2015 14:39:44 -0000 Author: marcel Date: Tue Aug 25 14:39:40 2015 New Revision: 287126 URL: https://svnweb.freebsd.org/changeset/base/287126 Log: MFC r286667 & r286723 Better support memory mapped console devices, such as VGA and EFI frame buffers and memory mapped UARTs. PR: 191564, 194952, 202276 Added: stable/10/sys/x86/x86/bus_machdep.c - copied unchanged from r286667, head/sys/x86/x86/bus_machdep.c Modified: stable/10/sys/amd64/amd64/machdep.c stable/10/sys/amd64/amd64/pmap.c stable/10/sys/conf/files.amd64 stable/10/sys/conf/files.i386 stable/10/sys/dev/vt/hw/efifb/efifb.c stable/10/sys/dev/vt/hw/vga/vt_vga.c stable/10/sys/dev/vt/hw/vga/vt_vga_reg.h stable/10/sys/i386/i386/machdep.c stable/10/sys/i386/i386/pmap.c stable/10/sys/x86/include/bus.h Directory Properties: stable/10/ (props changed) Modified: stable/10/sys/amd64/amd64/machdep.c ============================================================================== --- stable/10/sys/amd64/amd64/machdep.c Tue Aug 25 09:16:09 2015 (r287125) +++ stable/10/sys/amd64/amd64/machdep.c Tue Aug 25 14:39:40 2015 (r287126) @@ -1931,38 +1931,6 @@ hammer_time(u_int64_t modulep, u_int64_t MODINFO_METADATA | MODINFOMD_EFI_MAP) != NULL) vty_set_preferred(VTY_VT); - /* - * Initialize the console before we print anything out. - */ - cninit(); - -#ifdef DEV_ISA -#ifdef DEV_ATPIC - elcr_probe(); - atpic_startup(); -#else - /* Reset and mask the atpics and leave them shut down. */ - atpic_reset(); - - /* - * Point the ICU spurious interrupt vectors at the APIC spurious - * interrupt handler. - */ - setidt(IDT_IO_INTS + 7, IDTVEC(spuriousint), SDT_SYSIGT, SEL_KPL, 0); - setidt(IDT_IO_INTS + 15, IDTVEC(spuriousint), SDT_SYSIGT, SEL_KPL, 0); -#endif -#else -#error "have you forgotten the isa device?"; -#endif - - kdb_init(); - -#ifdef KDB - if (boothowto & RB_KDB) - kdb_enter(KDB_WHY_BOOTFLAGS, - "Boot flags requested debugger"); -#endif - identify_cpu(); /* Final stage of CPU initialization */ initializecpu(); /* Initialize CPU registers */ initializecpucache(); @@ -2000,6 +1968,35 @@ hammer_time(u_int64_t modulep, u_int64_t /* now running on new page tables, configured,and u/iom is accessible */ + cninit(); + +#ifdef DEV_ISA +#ifdef DEV_ATPIC + elcr_probe(); + atpic_startup(); +#else + /* Reset and mask the atpics and leave them shut down. */ + atpic_reset(); + + /* + * Point the ICU spurious interrupt vectors at the APIC spurious + * interrupt handler. + */ + setidt(IDT_IO_INTS + 7, IDTVEC(spuriousint), SDT_SYSIGT, SEL_KPL, 0); + setidt(IDT_IO_INTS + 15, IDTVEC(spuriousint), SDT_SYSIGT, SEL_KPL, 0); +#endif +#else +#error "have you forgotten the isa device?"; +#endif + + kdb_init(); + +#ifdef KDB + if (boothowto & RB_KDB) + kdb_enter(KDB_WHY_BOOTFLAGS, + "Boot flags requested debugger"); +#endif + msgbufinit(msgbufp, msgbufsize); fpuinit(); Modified: stable/10/sys/amd64/amd64/pmap.c ============================================================================== --- stable/10/sys/amd64/amd64/pmap.c Tue Aug 25 09:16:09 2015 (r287125) +++ stable/10/sys/amd64/amd64/pmap.c Tue Aug 25 14:39:40 2015 (r287126) @@ -360,6 +360,18 @@ static u_int64_t DMPDphys; /* phys addr static u_int64_t DMPDPphys; /* phys addr of direct mapped level 3 */ static int ndmpdpphys; /* number of DMPDPphys pages */ +/* + * pmap_mapdev support pre initialization (i.e. console) + */ +#define PMAP_PREINIT_MAPPING_COUNT 8 +static struct pmap_preinit_mapping { + vm_paddr_t pa; + vm_offset_t va; + vm_size_t sz; + int mode; +} pmap_preinit_mapping[PMAP_PREINIT_MAPPING_COUNT]; +static int pmap_initialized; + static struct rwlock_padalign pvh_global_lock; /* @@ -1014,6 +1026,7 @@ pmap_page_init(vm_page_t m) void pmap_init(void) { + struct pmap_preinit_mapping *ppim; vm_page_t mpte; vm_size_t s; int i, pv_npg; @@ -1085,6 +1098,22 @@ pmap_init(void) mtx_init(&cpage_lock, "cpage", NULL, MTX_DEF); cpage_a = kva_alloc(PAGE_SIZE); cpage_b = kva_alloc(PAGE_SIZE); + + pmap_initialized = 1; + for (i = 0; i < PMAP_PREINIT_MAPPING_COUNT; i++) { + ppim = pmap_preinit_mapping + i; + if (ppim->va == 0) + continue; + /* Make the direct map consistent */ + if (ppim->pa < dmaplimit && ppim->pa + ppim->sz < dmaplimit) { + (void)pmap_change_attr(PHYS_TO_DMAP(ppim->pa), + ppim->sz, ppim->mode); + } + if (!bootverbose) + continue; + printf("PPIM %u: PA=%#lx, VA=%#lx, size=%#lx, mode=%#x\n", i, + ppim->pa, ppim->va, ppim->sz, ppim->mode); + } } static SYSCTL_NODE(_vm_pmap, OID_AUTO, pde, CTLFLAG_RD, 0, @@ -6231,24 +6260,54 @@ pmap_pde_attr(pd_entry_t *pde, int cache void * pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, int mode) { + struct pmap_preinit_mapping *ppim; vm_offset_t va, offset; vm_size_t tmpsize; + int i; - /* - * If the specified range of physical addresses fits within the direct - * map window, use the direct map. - */ - if (pa < dmaplimit && pa + size < dmaplimit) { - va = PHYS_TO_DMAP(pa); - if (!pmap_change_attr(va, size, mode)) - return ((void *)va); - } offset = pa & PAGE_MASK; size = round_page(offset + size); - va = kva_alloc(size); - if (!va) - panic("pmap_mapdev: Couldn't alloc kernel virtual memory"); pa = trunc_page(pa); + + if (!pmap_initialized) { + va = 0; + for (i = 0; i < PMAP_PREINIT_MAPPING_COUNT; i++) { + ppim = pmap_preinit_mapping + i; + if (ppim->va == 0) { + ppim->pa = pa; + ppim->sz = size; + ppim->mode = mode; + ppim->va = virtual_avail; + virtual_avail += size; + va = ppim->va; + break; + } + } + if (va == 0) + panic("%s: too many preinit mappings", __func__); + } else { + /* + * If we have a preinit mapping, re-use it. + */ + for (i = 0; i < PMAP_PREINIT_MAPPING_COUNT; i++) { + ppim = pmap_preinit_mapping + i; + if (ppim->pa == pa && ppim->sz == size && + ppim->mode == mode) + return ((void *)(ppim->va + offset)); + } + /* + * If the specified range of physical addresses fits within + * the direct map window, use the direct map. + */ + if (pa < dmaplimit && pa + size < dmaplimit) { + va = PHYS_TO_DMAP(pa); + if (!pmap_change_attr(va, size, mode)) + return ((void *)(va + offset)); + } + va = kva_alloc(size); + if (va == 0) + panic("%s: Couldn't allocate KVA", __func__); + } for (tmpsize = 0; tmpsize < size; tmpsize += PAGE_SIZE) pmap_kenter_attr(va + tmpsize, pa + tmpsize, mode); pmap_invalidate_range(kernel_pmap, va, va + tmpsize); @@ -6273,15 +6332,32 @@ pmap_mapbios(vm_paddr_t pa, vm_size_t si void pmap_unmapdev(vm_offset_t va, vm_size_t size) { - vm_offset_t base, offset; + struct pmap_preinit_mapping *ppim; + vm_offset_t offset; + int i; /* If we gave a direct map region in pmap_mapdev, do nothing */ if (va >= DMAP_MIN_ADDRESS && va < DMAP_MAX_ADDRESS) return; - base = trunc_page(va); offset = va & PAGE_MASK; size = round_page(offset + size); - kva_free(base, size); + va = trunc_page(va); + for (i = 0; i < PMAP_PREINIT_MAPPING_COUNT; i++) { + ppim = pmap_preinit_mapping + i; + if (ppim->va == va && ppim->sz == size) { + if (pmap_initialized) + return; + ppim->pa = 0; + ppim->va = 0; + ppim->sz = 0; + ppim->mode = 0; + if (va + size == virtual_avail) + virtual_avail = va; + return; + } + } + if (pmap_initialized) + kva_free(va, size); } /* Modified: stable/10/sys/conf/files.amd64 ============================================================================== --- stable/10/sys/conf/files.amd64 Tue Aug 25 09:16:09 2015 (r287125) +++ stable/10/sys/conf/files.amd64 Tue Aug 25 14:39:40 2015 (r287126) @@ -588,6 +588,7 @@ x86/isa/nmi.c standard x86/isa/orm.c optional isa x86/pci/pci_bus.c optional pci x86/pci/qpi.c optional pci +x86/x86/bus_machdep.c standard x86/x86/busdma_bounce.c standard x86/x86/busdma_machdep.c standard x86/x86/dump_machdep.c standard Modified: stable/10/sys/conf/files.i386 ============================================================================== --- stable/10/sys/conf/files.i386 Tue Aug 25 09:16:09 2015 (r287125) +++ stable/10/sys/conf/files.i386 Tue Aug 25 14:39:40 2015 (r287126) @@ -589,6 +589,7 @@ x86/isa/nmi.c standard x86/isa/orm.c optional isa x86/pci/pci_bus.c optional pci x86/pci/qpi.c optional pci +x86/x86/bus_machdep.c standard x86/x86/busdma_bounce.c standard x86/x86/busdma_machdep.c standard x86/x86/dump_machdep.c standard Modified: stable/10/sys/dev/vt/hw/efifb/efifb.c ============================================================================== --- stable/10/sys/dev/vt/hw/efifb/efifb.c Tue Aug 25 09:16:09 2015 (r287125) +++ stable/10/sys/dev/vt/hw/efifb/efifb.c Tue Aug 25 14:39:40 2015 (r287126) @@ -53,7 +53,6 @@ __FBSDID("$FreeBSD$"); static vd_init_t vt_efifb_init; static vd_probe_t vt_efifb_probe; -static void vt_efifb_remap(void *efifb_data); static struct vt_driver vt_efifb_driver = { .vd_name = "efifb", @@ -73,8 +72,6 @@ static struct vt_driver vt_efifb_driver static struct fb_info local_info; VT_DRIVER_DECLARE(vt_efifb, vt_efifb_driver); -SYSINIT(efifb_remap, SI_SUB_KMEM, SI_ORDER_ANY, vt_efifb_remap, &local_info); - static int vt_efifb_probe(struct vt_device *vd) { @@ -139,12 +136,8 @@ vt_efifb_init(struct vt_device *vd) info->fb_size = info->fb_height * info->fb_stride; info->fb_pbase = efifb->fb_addr; - /* - * Use the direct map as a crutch until pmap is available. Once pmap - * is online, the framebuffer will be remapped by vt_efifb_remap() - * using pmap_mapdev_attr(). - */ - info->fb_vbase = PHYS_TO_DMAP(efifb->fb_addr); + info->fb_vbase = (intptr_t)pmap_mapdev_attr(info->fb_pbase, + info->fb_size, VM_MEMATTR_WRITE_COMBINING); /* Get pixel storage size. */ info->fb_bpp = info->fb_stride / info->fb_width * 8; @@ -160,22 +153,3 @@ vt_efifb_init(struct vt_device *vd) return (CN_INTERNAL); } - -static void -vt_efifb_remap(void *xinfo) -{ - struct fb_info *info = xinfo; - - if (info->fb_pbase == 0) - return; - - /* - * Remap as write-combining. This massively improves performance and - * happens very early in kernel initialization, when everything is - * still single-threaded and interrupts are off, so replacing the - * mapping address is safe. - */ - info->fb_vbase = (intptr_t)pmap_mapdev_attr(info->fb_pbase, - info->fb_size, VM_MEMATTR_WRITE_COMBINING); -} - Modified: stable/10/sys/dev/vt/hw/vga/vt_vga.c ============================================================================== --- stable/10/sys/dev/vt/hw/vga/vt_vga.c Tue Aug 25 09:16:09 2015 (r287125) +++ stable/10/sys/dev/vt/hw/vga/vt_vga.c Tue Aug 25 14:39:40 2015 (r287126) @@ -42,13 +42,6 @@ __FBSDID("$FreeBSD$"); #include -#if defined(__amd64__) || defined(__i386__) -#include -#include -#include -#include -#endif /* __amd64__ || __i386__ */ - struct vga_softc { bus_space_tag_t vga_fb_tag; bus_space_handle_t vga_fb_handle; @@ -885,9 +878,9 @@ vga_bitblt_text_txtmode(struct vt_device /* Convert colors to VGA attributes. */ attr = bg << 4 | fg; - MEM_WRITE1(sc, 0x18000 + (row * 80 + col) * 2 + 0, + MEM_WRITE1(sc, (row * 80 + col) * 2 + 0, ch); - MEM_WRITE1(sc, 0x18000 + (row * 80 + col) * 2 + 1, + MEM_WRITE1(sc, (row * 80 + col) * 2 + 1, attr); } } @@ -1211,9 +1204,7 @@ vga_init(struct vt_device *vd) #if defined(__amd64__) || defined(__i386__) sc->vga_fb_tag = X86_BUS_SPACE_MEM; - sc->vga_fb_handle = KERNBASE + VGA_MEM_BASE; sc->vga_reg_tag = X86_BUS_SPACE_IO; - sc->vga_reg_handle = VGA_REG_BASE; #elif defined(__ia64__) sc->vga_fb_tag = IA64_BUS_SPACE_MEM; sc->vga_fb_handle = IA64_PHYS_TO_RR6(VGA_MEM_BASE); @@ -1223,14 +1214,21 @@ vga_init(struct vt_device *vd) # error "Architecture not yet supported!" #endif + bus_space_map(sc->vga_reg_tag, VGA_REG_BASE, VGA_REG_SIZE, 0, + &sc->vga_reg_handle); + TUNABLE_INT_FETCH("hw.vga.textmode", &textmode); if (textmode) { vd->vd_flags |= VDF_TEXTMODE; vd->vd_width = 80; vd->vd_height = 25; + bus_space_map(sc->vga_fb_tag, VGA_TXT_BASE, VGA_TXT_SIZE, 0, + &sc->vga_fb_handle); } else { vd->vd_width = VT_VGA_WIDTH; vd->vd_height = VT_VGA_HEIGHT; + bus_space_map(sc->vga_fb_tag, VGA_MEM_BASE, VGA_MEM_SIZE, 0, + &sc->vga_fb_handle); } vga_initialize(vd, textmode); Modified: stable/10/sys/dev/vt/hw/vga/vt_vga_reg.h ============================================================================== --- stable/10/sys/dev/vt/hw/vga/vt_vga_reg.h Tue Aug 25 09:16:09 2015 (r287125) +++ stable/10/sys/dev/vt/hw/vga/vt_vga_reg.h Tue Aug 25 14:39:40 2015 (r287126) @@ -49,6 +49,8 @@ #define VGA_MEM_BASE 0xA0000 #define VGA_MEM_SIZE 0x10000 +#define VGA_TXT_BASE 0xB8000 +#define VGA_TXT_SIZE 0x08000 #define VGA_REG_BASE 0x3c0 #define VGA_REG_SIZE 0x10+0x0c Modified: stable/10/sys/i386/i386/machdep.c ============================================================================== --- stable/10/sys/i386/i386/machdep.c Tue Aug 25 09:16:09 2015 (r287125) +++ stable/10/sys/i386/i386/machdep.c Tue Aug 25 14:39:40 2015 (r287126) @@ -3320,6 +3320,40 @@ init386(first) */ i8254_init(); + finishidentcpu(); /* Final stage of CPU initialization */ + setidt(IDT_UD, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL, + GSEL(GCODE_SEL, SEL_KPL)); + setidt(IDT_GP, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL, + GSEL(GCODE_SEL, SEL_KPL)); + initializecpu(); /* Initialize CPU registers */ + initializecpucache(); + + /* pointer to selector slot for %fs/%gs */ + PCPU_SET(fsgs_gdt, &gdt[GUFS_SEL].sd); + + dblfault_tss.tss_esp = dblfault_tss.tss_esp0 = dblfault_tss.tss_esp1 = + dblfault_tss.tss_esp2 = (int)&dblfault_stack[sizeof(dblfault_stack)]; + dblfault_tss.tss_ss = dblfault_tss.tss_ss0 = dblfault_tss.tss_ss1 = + dblfault_tss.tss_ss2 = GSEL(GDATA_SEL, SEL_KPL); +#if defined(PAE) || defined(PAE_TABLES) + dblfault_tss.tss_cr3 = (int)IdlePDPT; +#else + dblfault_tss.tss_cr3 = (int)IdlePTD; +#endif + dblfault_tss.tss_eip = (int)dblfault_handler; + dblfault_tss.tss_eflags = PSL_KERNEL; + dblfault_tss.tss_ds = dblfault_tss.tss_es = + dblfault_tss.tss_gs = GSEL(GDATA_SEL, SEL_KPL); + dblfault_tss.tss_fs = GSEL(GPRIV_SEL, SEL_KPL); + dblfault_tss.tss_cs = GSEL(GCODE_SEL, SEL_KPL); + dblfault_tss.tss_ldt = GSEL(GLDT_SEL, SEL_KPL); + + vm86_initialize(); + getmemsize(first); + init_param2(physmem); + + /* now running on new page tables, configured,and u/iom is accessible */ + /* * Initialize the console before we print anything out. */ @@ -3361,40 +3395,6 @@ init386(first) kdb_enter(KDB_WHY_BOOTFLAGS, "Boot flags requested debugger"); #endif - finishidentcpu(); /* Final stage of CPU initialization */ - setidt(IDT_UD, &IDTVEC(ill), SDT_SYS386TGT, SEL_KPL, - GSEL(GCODE_SEL, SEL_KPL)); - setidt(IDT_GP, &IDTVEC(prot), SDT_SYS386TGT, SEL_KPL, - GSEL(GCODE_SEL, SEL_KPL)); - initializecpu(); /* Initialize CPU registers */ - initializecpucache(); - - /* pointer to selector slot for %fs/%gs */ - PCPU_SET(fsgs_gdt, &gdt[GUFS_SEL].sd); - - dblfault_tss.tss_esp = dblfault_tss.tss_esp0 = dblfault_tss.tss_esp1 = - dblfault_tss.tss_esp2 = (int)&dblfault_stack[sizeof(dblfault_stack)]; - dblfault_tss.tss_ss = dblfault_tss.tss_ss0 = dblfault_tss.tss_ss1 = - dblfault_tss.tss_ss2 = GSEL(GDATA_SEL, SEL_KPL); -#if defined(PAE) || defined(PAE_TABLES) - dblfault_tss.tss_cr3 = (int)IdlePDPT; -#else - dblfault_tss.tss_cr3 = (int)IdlePTD; -#endif - dblfault_tss.tss_eip = (int)dblfault_handler; - dblfault_tss.tss_eflags = PSL_KERNEL; - dblfault_tss.tss_ds = dblfault_tss.tss_es = - dblfault_tss.tss_gs = GSEL(GDATA_SEL, SEL_KPL); - dblfault_tss.tss_fs = GSEL(GPRIV_SEL, SEL_KPL); - dblfault_tss.tss_cs = GSEL(GCODE_SEL, SEL_KPL); - dblfault_tss.tss_ldt = GSEL(GLDT_SEL, SEL_KPL); - - vm86_initialize(); - getmemsize(first); - init_param2(physmem); - - /* now running on new page tables, configured,and u/iom is accessible */ - msgbufinit(msgbufp, msgbufsize); #ifdef DEV_NPX npxinit(true); Modified: stable/10/sys/i386/i386/pmap.c ============================================================================== --- stable/10/sys/i386/i386/pmap.c Tue Aug 25 09:16:09 2015 (r287125) +++ stable/10/sys/i386/i386/pmap.c Tue Aug 25 14:39:40 2015 (r287126) @@ -232,6 +232,18 @@ SYSCTL_INT(_vm_pmap, OID_AUTO, pg_ps_ena #define PAT_INDEX_SIZE 8 static int pat_index[PAT_INDEX_SIZE]; /* cache mode to PAT index conversion */ +/* + * pmap_mapdev support pre initialization (i.e. console) + */ +#define PMAP_PREINIT_MAPPING_COUNT 8 +static struct pmap_preinit_mapping { + vm_paddr_t pa; + vm_offset_t va; + vm_size_t sz; + int mode; +} pmap_preinit_mapping[PMAP_PREINIT_MAPPING_COUNT]; +static int pmap_initialized; + static struct rwlock_padalign pvh_global_lock; /* @@ -731,6 +743,7 @@ pmap_ptelist_init(vm_offset_t *head, voi void pmap_init(void) { + struct pmap_preinit_mapping *ppim; vm_page_t mpte; vm_size_t s; int i, pv_npg; @@ -814,6 +827,17 @@ pmap_init(void) UMA_ZONE_VM | UMA_ZONE_NOFREE); uma_zone_set_allocf(pdptzone, pmap_pdpt_allocf); #endif + + pmap_initialized = 1; + if (!bootverbose) + return; + for (i = 0; i < PMAP_PREINIT_MAPPING_COUNT; i++) { + ppim = pmap_preinit_mapping + i; + if (ppim->va == 0) + continue; + printf("PPIM %u: PA=%#jx, VA=%#x, size=%#x, mode=%#x\n", i, + (uintmax_t)ppim->pa, ppim->va, ppim->sz, ppim->mode); + } } @@ -5162,8 +5186,10 @@ pmap_pde_attr(pd_entry_t *pde, int cache void * pmap_mapdev_attr(vm_paddr_t pa, vm_size_t size, int mode) { + struct pmap_preinit_mapping *ppim; vm_offset_t va, offset; vm_size_t tmpsize; + int i; offset = pa & PAGE_MASK; size = round_page(offset + size); @@ -5171,11 +5197,36 @@ pmap_mapdev_attr(vm_paddr_t pa, vm_size_ if (pa < KERNLOAD && pa + size <= KERNLOAD) va = KERNBASE + pa; - else + else if (!pmap_initialized) { + va = 0; + for (i = 0; i < PMAP_PREINIT_MAPPING_COUNT; i++) { + ppim = pmap_preinit_mapping + i; + if (ppim->va == 0) { + ppim->pa = pa; + ppim->sz = size; + ppim->mode = mode; + ppim->va = virtual_avail; + virtual_avail += size; + va = ppim->va; + break; + } + } + if (va == 0) + panic("%s: too many preinit mappings", __func__); + } else { + /* + * If we have a preinit mapping, re-use it. + */ + for (i = 0; i < PMAP_PREINIT_MAPPING_COUNT; i++) { + ppim = pmap_preinit_mapping + i; + if (ppim->pa == pa && ppim->sz == size && + ppim->mode == mode) + return ((void *)(ppim->va + offset)); + } va = kva_alloc(size); - if (!va) - panic("pmap_mapdev: Couldn't alloc kernel virtual memory"); - + if (va == 0) + panic("%s: Couldn't allocate KVA", __func__); + } for (tmpsize = 0; tmpsize < size; tmpsize += PAGE_SIZE) pmap_kenter_attr(va + tmpsize, pa + tmpsize, mode); pmap_invalidate_range(kernel_pmap, va, va + tmpsize); @@ -5200,14 +5251,31 @@ pmap_mapbios(vm_paddr_t pa, vm_size_t si void pmap_unmapdev(vm_offset_t va, vm_size_t size) { - vm_offset_t base, offset; + struct pmap_preinit_mapping *ppim; + vm_offset_t offset; + int i; if (va >= KERNBASE && va + size <= KERNBASE + KERNLOAD) return; - base = trunc_page(va); offset = va & PAGE_MASK; size = round_page(offset + size); - kva_free(base, size); + va = trunc_page(va); + for (i = 0; i < PMAP_PREINIT_MAPPING_COUNT; i++) { + ppim = pmap_preinit_mapping + i; + if (ppim->va == va && ppim->sz == size) { + if (pmap_initialized) + return; + ppim->pa = 0; + ppim->va = 0; + ppim->sz = 0; + ppim->mode = 0; + if (va + size == virtual_avail) + virtual_avail = va; + return; + } + } + if (pmap_initialized) + kva_free(va, size); } /* Modified: stable/10/sys/x86/include/bus.h ============================================================================== --- stable/10/sys/x86/include/bus.h Tue Aug 25 09:16:09 2015 (r287125) +++ stable/10/sys/x86/include/bus.h Tue Aug 25 14:39:40 2015 (r287126) @@ -130,32 +130,15 @@ * Map a region of device bus space into CPU virtual address space. */ -static __inline int bus_space_map(bus_space_tag_t t, bus_addr_t addr, - bus_size_t size, int flags, - bus_space_handle_t *bshp); - -static __inline int -bus_space_map(bus_space_tag_t t __unused, bus_addr_t addr, - bus_size_t size __unused, int flags __unused, - bus_space_handle_t *bshp) -{ - - *bshp = addr; - return (0); -} +int bus_space_map(bus_space_tag_t tag, bus_addr_t addr, bus_size_t size, + int flags, bus_space_handle_t *bshp); /* * Unmap a region of device bus space. */ -static __inline void bus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, - bus_size_t size); - -static __inline void -bus_space_unmap(bus_space_tag_t t __unused, bus_space_handle_t bsh __unused, - bus_size_t size __unused) -{ -} +void bus_space_unmap(bus_space_tag_t tag, bus_space_handle_t bsh, + bus_size_t size); /* * Get a new handle for a subregion of an already-mapped area of bus space. Copied: stable/10/sys/x86/x86/bus_machdep.c (from r286667, head/sys/x86/x86/bus_machdep.c) ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ stable/10/sys/x86/x86/bus_machdep.c Tue Aug 25 14:39:40 2015 (r287126, copy of r286667, head/sys/x86/x86/bus_machdep.c) @@ -0,0 +1,59 @@ +/*- + * Copyright (c) 2015 Marcel Moolenaar + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include + +#include +#include + +/* + * Implementation of bus_space_map(), which effectively is a thin + * wrapper around pmap_mapdev() for memory mapped I/O space. It's + * implemented here and not in to avoid pollution. + */ +int +bus_space_map(bus_space_tag_t tag, bus_addr_t addr, bus_size_t size, + int flags __unused, bus_space_handle_t *bshp) +{ + + *bshp = (tag == X86_BUS_SPACE_MEM) + ? (uintptr_t)pmap_mapdev(addr, size) + : addr; + return (0); +} + +void +bus_space_unmap(bus_space_tag_t tag, bus_space_handle_t bsh, bus_size_t size) +{ + + if (tag == X86_BUS_SPACE_MEM) + pmap_unmapdev(bsh, size); +}