2 * The PCI Library -- Physical memory mapping for POSIX systems
4 * Copyright (c) 2023 Pali Rohár <pali@kernel.org>
6 * Can be freely distributed and used under the terms of the GNU GPL v2+
8 * SPDX-License-Identifier: GPL-2.0-or-later
12 * Tell 32-bit platforms that we are interested in 64-bit variant of off_t type
13 * as 32-bit variant of off_t type is signed and so it cannot represent all
14 * possible 32-bit offsets. It is required because off_t type is used by mmap().
16 #define _FILE_OFFSET_BITS 64
24 #include <sys/types.h>
29 #define OFF_MAX ((((off_t)1 << (sizeof(off_t) * CHAR_BIT - 2)) - 1) * 2 + 1)
37 physmem_init_config(struct pci_access *a)
39 pci_define_param(a, "devmem.path", PCI_PATH_DEVMEM_DEVICE, "Path to the /dev/mem device");
43 physmem_access(struct pci_access *a, int w)
45 const char *devmem = pci_get_param(a, "devmem.path");
46 a->debug("checking access permission of physical memory device %s for %s mode...", devmem, w ? "read/write" : "read-only");
47 return access(devmem, R_OK | (w ? W_OK : 0));
51 physmem_open(struct pci_access *a, int w)
53 const char *devmem = pci_get_param(a, "devmem.path");
54 struct physmem *physmem = pci_malloc(a, sizeof(struct physmem));
56 a->debug("trying to open physical memory device %s in %s mode...", devmem, w ? "read/write" : "read-only");
57 physmem->fd = open(devmem, (w ? O_RDWR : O_RDONLY) | O_DSYNC); /* O_DSYNC bypass CPU cache for mmap() on Linux */
68 physmem_close(struct physmem *physmem)
75 physmem_get_pagesize(struct physmem *physmem UNUSED)
77 return sysconf(_SC_PAGESIZE);
81 physmem_map(struct physmem *physmem, u64 addr, size_t length, int w)
88 return mmap(NULL, length, PROT_READ | (w ? PROT_WRITE : 0), MAP_SHARED, physmem->fd, addr);
92 physmem_unmap(struct physmem *physmem UNUSED, void *ptr, size_t length)
94 return munmap(ptr, length);