2 * arch/um/kernel/mem_user.c
4 * BRIEF MODULE DESCRIPTION
5 * user side memory routines for supporting IO memory inside user mode linux
7 * Copyright (C) 2001 RidgeRun, Inc.
8 * Author: RidgeRun, Inc.
9 * Greg Lonnon glonnon@ridgerun.com or info@ridgerun.com
11 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your
14 * option) any later version.
16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
19 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
22 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
23 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 * You should have received a copy of the GNU General Public License along
28 * with this program; if not, write to the Free Software Foundation, Inc.,
29 * 675 Mass Ave, Cambridge, MA 02139, USA.
41 #include <sys/types.h>
43 #include "kern_util.h"
45 #include "user_util.h"
51 extern struct mem_region physmem_region;
53 #define TEMPNAME_TEMPLATE "vm_file-XXXXXX"
55 int create_mem_file(unsigned long len)
60 fd = make_tempfile(TEMPNAME_TEMPLATE, NULL, 1);
61 if (fchmod(fd, 0777) < 0){
65 if(os_seek_file(fd, len) < 0){
70 if(write(fd, &zero, 1) != 1){
74 if(fcntl(fd, F_SETFD, 1) != 0)
75 perror("Setting FD_CLOEXEC failed");
79 int setup_region(struct mem_region *region, void *entry)
85 if(region->start != -1){
86 err = reserve_vm(region->start,
87 region->start + region->len, entry);
89 printk("setup_region : failed to reserve "
90 "0x%x - 0x%x for driver '%s'\n",
92 region->start + region->len,
97 else region->start = get_vm(region->len);
98 if(region->start == 0){
99 if(region->driver == NULL) driver = "physmem";
100 else driver = region->driver;
101 printk("setup_region : failed to find vm for "
102 "driver '%s' (length %d)\n", driver, region->len);
105 if(region->start == uml_physmem){
106 start = (void *) uml_reserved;
107 offset = uml_reserved - uml_physmem;
110 start = (void *) region->start;
114 loc = mmap(start, region->len - offset, PROT_READ | PROT_WRITE,
115 MAP_SHARED | MAP_FIXED, region->fd, offset);
117 perror("Mapping memory");
123 static int __init parse_iomem(char *str, int *add)
130 file = strchr(str,',');
132 printk("parse_iomem : failed to parse iomem\n");
137 fd = os_open_file(file, of_rdwr(OPENFLAGS()), 0);
139 printk("parse_iomem - Couldn't open io file, errno = %d\n",
143 if(fstat(fd, &buf) < 0) {
144 printk("parse_iomem - cannot fstat file, errno = %d\n", errno);
147 add_iomem(driver, fd, buf.st_size);
151 __uml_setup("iomem=", parse_iomem,
152 "iomem=<name>,<file>\n"
153 " Configure <file> as an IO memory region named <name>.\n\n"
160 int logging_line = 0;
161 char logging_buf[256];
163 void log(char *fmt, ...)
167 struct openflags flags;
169 if(logging == 0) return;
171 flags = of_create(of_trunc(of_rdrw(OPENFLAGS())));
172 logging_fd = os_open_file("log", flags, 0644);
174 gettimeofday(&tv, NULL);
175 sprintf(logging_buf, "%d\t %u.%u ", logging_line++, tv.tv_sec,
178 vsprintf(&logging_buf[strlen(logging_buf)], fmt, ap);
180 write(logging_fd, logging_buf, strlen(logging_buf));
184 int map_memory(unsigned long virt, unsigned long phys, unsigned long len,
187 struct mem_region *region = phys_region(phys);
189 return(os_map_memory((void *) virt, region->fd, phys_offset(phys), len,
193 int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x,
196 if(os_protect_memory((void *) addr, len, r, w, x) < 0){
198 panic("protect failed, errno = %d", errno);
204 unsigned long find_iomem(char *driver, unsigned long *len_out)
206 struct mem_region *region;
210 for(i = 0; i < n; i++){
212 if(region == NULL) continue;
213 if((region->driver != NULL) &&
214 !strcmp(region->driver, driver)){
215 *len_out = region->len;
216 return(region->start);
224 * Overrides for Emacs so that we follow Linus's tabbing style.
225 * Emacs will notice this stuff at the end of the file and automatically
226 * adjust the settings for this buffer only. This must remain at the end
228 * ---------------------------------------------------------------------------
230 * c-file-style: "linux"