From owner-freebsd-hackers@FreeBSD.ORG Fri Jun 13 13:31:53 2003 Return-Path: Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id AB62A37B401 for ; Fri, 13 Jun 2003 13:31:53 -0700 (PDT) Received: from hysteria.spc.org (hysteria.spc.org [195.206.69.234]) by mx1.FreeBSD.org (Postfix) with SMTP id 67CCE43FF9 for ; Fri, 13 Jun 2003 13:31:50 -0700 (PDT) (envelope-from bms@hysteria.spc.org) Received: (qmail 26139 invoked by uid 5013); 7 Jun 2003 12:23:49 -0000 Date: Sat, 7 Jun 2003 13:23:48 +0100 From: Bruce M Simpson To: cd_freebsd Message-ID: <20030607122348.GG23471@spc.org> Mail-Followup-To: Bruce M Simpson , cd_freebsd , freebsd-hackers@freebsd.org References: <200306061330.AA25428118@gatorzone.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <200306061330.AA25428118@gatorzone.com> User-Agent: Mutt/1.4.1i cc: freebsd-hackers@freebsd.org Subject: Re: Mapping Physical Memory without a Device? X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 13 Jun 2003 20:31:54 -0000 On Fri, Jun 06, 2003 at 01:30:28PM -0400, cd_freebsd wrote: > I would like to be able to map memory before I have a device to work with (to read system BIOS information or mess with the video buffer). Is this possible? In linux, I would just call ioremap_nocache or request region. Is there a way to use bus_alloc_resource or something similar to accomplish this? I assume you wish to do this from within the kernel. The key ingredient here is pmap_kenter(). You would want to do something like this: ... struct pcmem_softc { int sc_unit; device_t sc_dev; dev_t sc_cdev; ... /* common memory mapping descriptors */ u_int32_t sc_cm_base; int sc_cm_size; vm_offset_t sc_cm_kva_base; u_int32_t sc_cm_kva_size; ... }; static vm_offset_t pcmem_phys_map(struct pcmem_softc *sc) { int i; u_int32_t off; u_int32_t pa; vm_offset_t va; vm_offset_t size; /* * ensure the range to be mapped fits within page boundaries. */ pa = round_page((u_int32_t) sc->sc_cm_base); sc->sc_cm_kva_size = size = round_page((u_int32_t) sc->sc_cm_size); off = (u_int32_t) sc->sc_cm_base - pa; /* * reserve a pageable memory range within the kva. */ va = kmem_alloc_pageable(kernel_map, size); if (va == (vm_offset_t) 0) return (va); /* * wire each page into kva. */ for (i = 0; i < size; i += PAGE_SIZE) { pmap_kenter(va + i, pa + i); } #ifdef __i386__ invltlb(); #endif return (va + off); } I wrote the above segment knowing much less about vm than I do now, so it's probably too pmap and arch specific and could be done better. Anything more elaborate (e.g. exporting pages to userland) would require you to use a pager of type OBJT_PHYS. BMS