bugfixes related to mmap usage for ROM
[libpicofe.git] / linux / plat.c
1 #define _GNU_SOURCE
2 #include <stdio.h>
3 #include <string.h>
4 #include <dirent.h>
5 #include <sys/time.h>
6 #include <time.h>
7 #include <unistd.h>
8 #include <sys/mman.h>
9
10 #include "../common/plat.h"
11
12
13 int plat_is_dir(const char *path)
14 {
15         DIR *dir;
16         if ((dir = opendir(path))) {
17                 closedir(dir);
18                 return 1;
19         }
20         return 0;
21 }
22
23 int plat_get_root_dir(char *dst, int len)
24 {
25         extern char **g_argv;
26         int j;
27
28         strncpy(dst, g_argv[0], len);
29         len -= 32; // reserve
30         if (len < 0) len = 0;
31         dst[len] = 0;
32         for (j = strlen(dst); j > 0; j--)
33                 if (dst[j] == '/') { dst[j+1] = 0; break; }
34
35         return j + 1;
36 }
37
38 #ifdef __GP2X__
39 /* Wiz has a borked gettimeofday().. */
40 #define plat_get_ticks_ms plat_get_ticks_ms_good
41 #define plat_get_ticks_us plat_get_ticks_us_good
42 #endif
43
44 unsigned int plat_get_ticks_ms(void)
45 {
46         struct timeval tv;
47         unsigned int ret;
48
49         gettimeofday(&tv, NULL);
50
51         ret = (unsigned)tv.tv_sec * 1000;
52         /* approximate /= 1000 */
53         ret += ((unsigned)tv.tv_usec * 4195) >> 22;
54
55         return ret;
56 }
57
58 unsigned int plat_get_ticks_us(void)
59 {
60         struct timeval tv;
61         unsigned int ret;
62
63         gettimeofday(&tv, NULL);
64
65         ret = (unsigned)tv.tv_sec * 1000000;
66         ret += (unsigned)tv.tv_usec;
67
68         return ret;
69 }
70
71 void plat_sleep_ms(int ms)
72 {
73         usleep(ms * 1000);
74 }
75
76 int plat_wait_event(int *fds_hnds, int count, int timeout_ms)
77 {
78         struct timeval tv, *timeout = NULL;
79         int i, ret, fdmax = -1;
80         fd_set fdset;
81
82         if (timeout_ms >= 0) {
83                 tv.tv_sec = timeout_ms / 1000;
84                 tv.tv_usec = (timeout_ms % 1000) * 1000;
85                 timeout = &tv;
86         }
87
88         FD_ZERO(&fdset);
89         for (i = 0; i < count; i++) {
90                 if (fds_hnds[i] > fdmax) fdmax = fds_hnds[i];
91                 FD_SET(fds_hnds[i], &fdset);
92         }
93
94         ret = select(fdmax + 1, &fdset, NULL, NULL, timeout);
95         if (ret == -1)
96         {
97                 perror("plat_wait_event: select failed");
98                 sleep(1);
99                 return -1;
100         }
101
102         if (ret == 0)
103                 return -1; /* timeout */
104
105         ret = -1;
106         for (i = 0; i < count; i++)
107                 if (FD_ISSET(fds_hnds[i], &fdset))
108                         ret = fds_hnds[i];
109
110         return ret;
111 }
112
113 void *plat_mmap(unsigned long addr, size_t size)
114 {
115         void *req, *ret;
116
117         req = (void *)addr;
118         ret = mmap(req, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
119         if (ret == MAP_FAILED)
120                 return NULL;
121         if (ret != req)
122                 printf("warning: mmaped to %p, requested %p\n", ret, req);
123
124         return ret;
125 }
126
127 void *plat_mremap(void *ptr, size_t oldsize, size_t newsize)
128 {
129         void *ret;
130
131         ret = mremap(ptr, oldsize, newsize, MREMAP_MAYMOVE);
132         if (ret == MAP_FAILED)
133                 return NULL;
134         if (ret != ptr)
135                 printf("warning: mremap moved: %p -> %p\n", ptr, ret);
136
137         return ret;
138 }
139
140 void plat_munmap(void *ptr, size_t size)
141 {
142         munmap(ptr, size);
143 }
144