1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /******************************************************************************
3  *
4  * Module Name: osunixmap - Unix OSL for file mappings
5  *
6  * Copyright (C) 2000 - 2023, Intel Corp.
7  *
8  *****************************************************************************/
9 
10 #include "acpidump.h"
11 #include <unistd.h>
12 #include <sys/mman.h>
13 #ifdef _free_BSD
14 #include <sys/param.h>
15 #endif
16 
17 #define _COMPONENT          ACPI_OS_SERVICES
18 ACPI_MODULE_NAME("osunixmap")
19 
20 #ifndef O_BINARY
21 #define O_BINARY 0
22 #endif
23 #if defined(_dragon_fly) || defined(_free_BSD) || defined(_QNX)
24 #define MMAP_FLAGS          MAP_SHARED
25 #else
26 #define MMAP_FLAGS          MAP_PRIVATE
27 #endif
28 #define SYSTEM_MEMORY       "/dev/mem"
29 /*******************************************************************************
30  *
31  * FUNCTION:    acpi_os_get_page_size
32  *
33  * PARAMETERS:  None
34  *
35  * RETURN:      Page size of the platform.
36  *
37  * DESCRIPTION: Obtain page size of the platform.
38  *
39  ******************************************************************************/
acpi_os_get_page_size(void)40 static acpi_size acpi_os_get_page_size(void)
41 {
42 
43 #ifdef PAGE_SIZE
44 	return PAGE_SIZE;
45 #else
46 	return sysconf(_SC_PAGESIZE);
47 #endif
48 }
49 
50 /******************************************************************************
51  *
52  * FUNCTION:    acpi_os_map_memory
53  *
54  * PARAMETERS:  where               - Physical address of memory to be mapped
55  *              length              - How much memory to map
56  *
57  * RETURN:      Pointer to mapped memory. Null on error.
58  *
59  * DESCRIPTION: Map physical memory into local address space.
60  *
61  *****************************************************************************/
62 
acpi_os_map_memory(acpi_physical_address where,acpi_size length)63 void *acpi_os_map_memory(acpi_physical_address where, acpi_size length)
64 {
65 	u8 *mapped_memory;
66 	acpi_physical_address offset;
67 	acpi_size page_size;
68 	int fd;
69 
70 	fd = open(SYSTEM_MEMORY, O_RDONLY | O_BINARY);
71 	if (fd < 0) {
72 		fprintf(stderr, "Cannot open %s\n", SYSTEM_MEMORY);
73 		return (NULL);
74 	}
75 
76 	/* Align the offset to use mmap */
77 
78 	page_size = acpi_os_get_page_size();
79 	offset = where % page_size;
80 
81 	/* Map the table header to get the length of the full table */
82 
83 	mapped_memory = mmap(NULL, (length + offset), PROT_READ, MMAP_FLAGS,
84 			     fd, (where - offset));
85 	if (mapped_memory == MAP_FAILED) {
86 		fprintf(stderr, "Cannot map %s\n", SYSTEM_MEMORY);
87 		close(fd);
88 		return (NULL);
89 	}
90 
91 	close(fd);
92 	return (ACPI_CAST8(mapped_memory + offset));
93 }
94 
95 /******************************************************************************
96  *
97  * FUNCTION:    acpi_os_unmap_memory
98  *
99  * PARAMETERS:  where               - Logical address of memory to be unmapped
100  *              length              - How much memory to unmap
101  *
102  * RETURN:      None.
103  *
104  * DESCRIPTION: Delete a previously created mapping. Where and Length must
105  *              correspond to a previous mapping exactly.
106  *
107  *****************************************************************************/
108 
acpi_os_unmap_memory(void * where,acpi_size length)109 void acpi_os_unmap_memory(void *where, acpi_size length)
110 {
111 	acpi_physical_address offset;
112 	acpi_size page_size;
113 
114 	page_size = acpi_os_get_page_size();
115 	offset = ACPI_TO_INTEGER(where) % page_size;
116 	munmap((u8 *)where - offset, (length + offset));
117 }
118