mapper.c revision 1.1
11.1Skamil/* $NetBSD: mapper.c,v 1.1 2019/01/17 20:47:42 kamil Exp $ */ 21.1Skamil 31.1Skamil/*- 41.1Skamil * Copyright (c) 2019 The NetBSD Foundation, Inc. 51.1Skamil * All rights reserved. 61.1Skamil * 71.1Skamil * Redistribution and use in source and binary forms, with or without 81.1Skamil * modification, are permitted provided that the following conditions 91.1Skamil * are met: 101.1Skamil * 1. Redistributions of source code must retain the above copyright 111.1Skamil * notice, this list of conditions and the following disclaimer. 121.1Skamil * 2. Redistributions in binary form must reproduce the above copyright 131.1Skamil * notice, this list of conditions and the following disclaimer in the 141.1Skamil * documentation and/or other materials provided with the distribution. 151.1Skamil * 161.1Skamil * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 171.1Skamil * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 181.1Skamil * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 191.1Skamil * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 201.1Skamil * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 211.1Skamil * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 221.1Skamil * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 231.1Skamil * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 241.1Skamil * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 251.1Skamil * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 261.1Skamil * POSSIBILITY OF SUCH DAMAGE. 271.1Skamil */ 281.1Skamil 291.1Skamil#include <sys/cdefs.h> 301.1Skamil__KERNEL_RCSID(0, "$NetBSD: mapper.c,v 1.1 2019/01/17 20:47:42 kamil Exp $"); 311.1Skamil 321.1Skamil#include <sys/param.h> 331.1Skamil#include <sys/conf.h> 341.1Skamil#include <sys/device.h> 351.1Skamil#include <sys/kernel.h> 361.1Skamil#include <sys/kmem.h> 371.1Skamil#include <sys/module.h> 381.1Skamil#include <sys/systm.h> 391.1Skamil 401.1Skamil#include <uvm/uvm.h> 411.1Skamil 421.1Skamil/* 431.1Skamil * Creating a device /dev/mapper for demonstration. 441.1Skamil * To use this device you need to do: 451.1Skamil * mknod /dev/mapper c 210 0 461.1Skamil * 471.1Skamil */ 481.1Skamil 491.1Skamildev_type_open(mapper_open); 501.1Skamildev_type_close(mapper_close); 511.1Skamildev_type_mmap(mapper_mmap); 521.1Skamil 531.1Skamilstatic struct cdevsw mapper_cdevsw = { 541.1Skamil .d_open = mapper_open, 551.1Skamil .d_close = mapper_close, 561.1Skamil .d_read = noread, 571.1Skamil .d_write = nowrite, 581.1Skamil .d_ioctl = noioctl, 591.1Skamil .d_stop = nostop, 601.1Skamil .d_tty = notty, 611.1Skamil .d_poll = nopoll, 621.1Skamil .d_mmap = mapper_mmap, 631.1Skamil .d_kqfilter = nokqfilter, 641.1Skamil .d_discard = nodiscard, 651.1Skamil .d_flag = D_OTHER 661.1Skamil}; 671.1Skamil 681.1Skamilstruct mapper_softc { 691.1Skamil int refcnt; 701.1Skamil char *buffer; 711.1Skamil}; 721.1Skamil 731.1Skamilstatic struct mapper_softc sc; 741.1Skamil 751.1Skamilint 761.1Skamilmapper_open(dev_t self __unused, int flag __unused, int mode __unused, 771.1Skamil struct lwp *l __unused) 781.1Skamil{ 791.1Skamil if (sc.refcnt > 0) 801.1Skamil return EBUSY; 811.1Skamil ++sc.refcnt; 821.1Skamil sc.buffer = kmem_zalloc(PAGE_SIZE, KM_SLEEP); 831.1Skamil snprintf(sc.buffer, PAGE_SIZE, "Hey There!"); 841.1Skamil return 0; 851.1Skamil} 861.1Skamil 871.1Skamilint 881.1Skamilmapper_close(dev_t self __unused, int flag __unused, int mode __unused, 891.1Skamil struct lwp *l __unused) 901.1Skamil{ 911.1Skamil kmem_free(sc.buffer, PAGE_SIZE); 921.1Skamil --sc.refcnt; 931.1Skamil return 0; 941.1Skamil} 951.1Skamil 961.1Skamil/* 971.1Skamil * Here, pmap_extract() is used to extract the mapping from the specified 981.1Skamil * physical map for the provided virtual address, where pmap_kernel() points 991.1Skamil * to the kernel pmap. 1001.1Skamil */ 1011.1Skamil 1021.1Skamilpaddr_t 1031.1Skamilmapper_mmap(dev_t dev, off_t off, int prot) 1041.1Skamil{ 1051.1Skamil paddr_t pa; 1061.1Skamil 1071.1Skamil if (off & PAGE_MASK) 1081.1Skamil return (paddr_t)-1; 1091.1Skamil if (prot != VM_PROT_READ) 1101.1Skamil return (paddr_t)-1; 1111.1Skamil if (pmap_extract(pmap_kernel(), (vaddr_t)sc.buffer, &pa)) 1121.1Skamil return (paddr_t)atop(pa); 1131.1Skamil 1141.1Skamil return (paddr_t)-1; 1151.1Skamil} 1161.1Skamil 1171.1SkamilMODULE(MODULE_CLASS_MISC, mapper, NULL); 1181.1Skamil 1191.1Skamilstatic int 1201.1Skamilmapper_modcmd(modcmd_t cmd, void *arg __unused) 1211.1Skamil{ 1221.1Skamil /* The major should be verified and changed if needed to avoid 1231.1Skamil * conflicts with other devices. */ 1241.1Skamil int cmajor = 210, bmajor = -1; 1251.1Skamil 1261.1Skamil switch (cmd) { 1271.1Skamil case MODULE_CMD_INIT: 1281.1Skamil if (devsw_attach("mapper", NULL, &bmajor, &mapper_cdevsw, 1291.1Skamil &cmajor)) 1301.1Skamil return ENXIO; 1311.1Skamil return 0; 1321.1Skamil case MODULE_CMD_FINI: 1331.1Skamil if (sc.refcnt > 0) 1341.1Skamil return EBUSY; 1351.1Skamil devsw_detach(NULL, &mapper_cdevsw); 1361.1Skamil return 0; 1371.1Skamil default: 1381.1Skamil return ENOTTY; 1391.1Skamil } 1401.1Skamil return 0; 1411.1Skamil} 142