1 /******************************************************************************
2  *
3  * Module Name: osunixmap - Unix OSL for file mappings
4  *
5  *****************************************************************************/
6 
7 /*
8  * Copyright (C) 2000 - 2018, Intel Corp.
9  * All rights reserved.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions, and the following disclaimer,
16  *    without modification.
17  * 2. Redistributions in binary form must reproduce at minimum a disclaimer
18  *    substantially similar to the "NO WARRANTY" disclaimer below
19  *    ("Disclaimer") and any redistribution must be conditioned upon
20  *    including a substantially similar Disclaimer requirement for further
21  *    binary redistribution.
22  * 3. Neither the names of the above-listed copyright holders nor the names
23  *    of any contributors may be used to endorse or promote products derived
24  *    from this software without specific prior written permission.
25  *
26  * Alternatively, this software may be distributed under the terms of the
27  * GNU General Public License ("GPL") version 2 as published by the Free
28  * Software Foundation.
29  *
30  * NO WARRANTY
31  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
32  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
33  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
34  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
35  * HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
36  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
37  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
38  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
39  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40  * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
41  * POSSIBILITY OF SUCH DAMAGES.
42  */
43 
44 #include "acpidump.h"
45 #include <unistd.h>
46 #include <sys/mman.h>
47 #ifdef _free_BSD
48 #include <sys/param.h>
49 #endif
50 
51 #define _COMPONENT          ACPI_OS_SERVICES
52 ACPI_MODULE_NAME("osunixmap")
53 
54 #ifndef O_BINARY
55 #define O_BINARY 0
56 #endif
57 #if defined(_dragon_fly) || defined(_free_BSD) || defined(_QNX)
58 #define MMAP_FLAGS          MAP_SHARED
59 #else
60 #define MMAP_FLAGS          MAP_PRIVATE
61 #endif
62 #define SYSTEM_MEMORY       "/dev/mem"
63 /*******************************************************************************
64  *
65  * FUNCTION:    acpi_os_get_page_size
66  *
67  * PARAMETERS:  None
68  *
69  * RETURN:      Page size of the platform.
70  *
71  * DESCRIPTION: Obtain page size of the platform.
72  *
73  ******************************************************************************/
74 static acpi_size acpi_os_get_page_size(void)
75 {
76 
77 #ifdef PAGE_SIZE
78 	return PAGE_SIZE;
79 #else
80 	return sysconf(_SC_PAGESIZE);
81 #endif
82 }
83 
84 /******************************************************************************
85  *
86  * FUNCTION:    acpi_os_map_memory
87  *
88  * PARAMETERS:  where               - Physical address of memory to be mapped
89  *              length              - How much memory to map
90  *
91  * RETURN:      Pointer to mapped memory. Null on error.
92  *
93  * DESCRIPTION: Map physical memory into local address space.
94  *
95  *****************************************************************************/
96 
97 void *acpi_os_map_memory(acpi_physical_address where, acpi_size length)
98 {
99 	u8 *mapped_memory;
100 	acpi_physical_address offset;
101 	acpi_size page_size;
102 	int fd;
103 
104 	fd = open(SYSTEM_MEMORY, O_RDONLY | O_BINARY);
105 	if (fd < 0) {
106 		fprintf(stderr, "Cannot open %s\n", SYSTEM_MEMORY);
107 		return (NULL);
108 	}
109 
110 	/* Align the offset to use mmap */
111 
112 	page_size = acpi_os_get_page_size();
113 	offset = where % page_size;
114 
115 	/* Map the table header to get the length of the full table */
116 
117 	mapped_memory = mmap(NULL, (length + offset), PROT_READ, MMAP_FLAGS,
118 			     fd, (where - offset));
119 	if (mapped_memory == MAP_FAILED) {
120 		fprintf(stderr, "Cannot map %s\n", SYSTEM_MEMORY);
121 		close(fd);
122 		return (NULL);
123 	}
124 
125 	close(fd);
126 	return (ACPI_CAST8(mapped_memory + offset));
127 }
128 
129 /******************************************************************************
130  *
131  * FUNCTION:    acpi_os_unmap_memory
132  *
133  * PARAMETERS:  where               - Logical address of memory to be unmapped
134  *              length              - How much memory to unmap
135  *
136  * RETURN:      None.
137  *
138  * DESCRIPTION: Delete a previously created mapping. Where and Length must
139  *              correspond to a previous mapping exactly.
140  *
141  *****************************************************************************/
142 
143 void acpi_os_unmap_memory(void *where, acpi_size length)
144 {
145 	acpi_physical_address offset;
146 	acpi_size page_size;
147 
148 	page_size = acpi_os_get_page_size();
149 	offset = ACPI_TO_INTEGER(where) % page_size;
150 	munmap((u8 *)where - offset, (length + offset));
151 }
152