Subversion Repositories Kolibri OS

Rev

Rev 4104 | Rev 5060 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3263 Serge 1
#include 
2
#include 
3260 Serge 3
#include 
4
#include 
5
#include "i915_drv.h"
6
#include "intel_drv.h"
3480 Serge 7
#include 
3260 Serge 8
 
9
 
10
struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags)
11
{
12
    struct file *filep;
13
    int count;
14
 
15
    filep = malloc(sizeof(*filep));
16
 
17
    if(unlikely(filep == NULL))
18
        return ERR_PTR(-ENOMEM);
19
 
20
    count = size / PAGE_SIZE;
21
 
22
    filep->pages = kzalloc(sizeof(struct page *) * count, 0);
23
    if(unlikely(filep->pages == NULL))
24
    {
25
        kfree(filep);
26
        return ERR_PTR(-ENOMEM);
27
    };
28
 
29
    filep->count     = count;
30
    filep->allocated = 0;
31
    filep->vma       = NULL;
32
 
3298 Serge 33
//    printf("%s file %p pages %p count %d\n",
34
//              __FUNCTION__,filep, filep->pages, count);
3260 Serge 35
 
36
    return filep;
37
}
38
 
39
struct page *shmem_read_mapping_page_gfp(struct file *filep,
40
                                         pgoff_t index, gfp_t gfp)
41
{
42
    struct page *page;
43
 
44
    if(unlikely(index >= filep->count))
45
        return ERR_PTR(-EINVAL);
46
 
47
    page = filep->pages[index];
48
 
49
    if(unlikely(page == NULL))
50
    {
51
        page = (struct page *)AllocPage();
52
 
53
        if(unlikely(page == NULL))
54
            return ERR_PTR(-ENOMEM);
55
 
56
        filep->pages[index] = page;
4246 Serge 57
//        printf("file %p index %d page %x\n", filep, index, page);
58
//        delay(1);
59
 
3260 Serge 60
    };
61
 
62
    return page;
63
};
3263 Serge 64
 
65
unsigned long vm_mmap(struct file *file, unsigned long addr,
66
         unsigned long len, unsigned long prot,
67
         unsigned long flag, unsigned long offset)
68
{
69
    char *mem, *ptr;
70
    int i;
71
 
72
    if (unlikely(offset + PAGE_ALIGN(len) < offset))
73
        return -EINVAL;
74
    if (unlikely(offset & ~PAGE_MASK))
75
        return -EINVAL;
76
 
77
    mem = UserAlloc(len);
78
    if(unlikely(mem == NULL))
79
        return -ENOMEM;
80
 
81
    for(i = offset, ptr = mem; i < offset+len; i+= 4096, ptr+= 4096)
82
    {
83
        struct page *page;
84
 
85
        page = shmem_read_mapping_page_gfp(file, i/PAGE_SIZE,0);
86
 
87
        if (unlikely(IS_ERR(page)))
88
            goto err;
89
 
90
        MapPage(ptr, (addr_t)page, PG_SHARED|PG_UW);
91
    }
92
 
93
    return (unsigned long)mem;
94
err:
95
    UserFree(mem);
96
    return -ENOMEM;
97
};
98
 
3290 Serge 99
void shmem_file_delete(struct file *filep)
100
{
3298 Serge 101
//    printf("%s file %p pages %p count %d\n",
102
//            __FUNCTION__, filep, filep->pages, filep->count);
3263 Serge 103
 
3290 Serge 104
    if(filep->pages)
105
        kfree(filep->pages);
106
}
3480 Serge 107
 
108
 
109
 
110
static void *check_bytes8(const u8 *start, u8 value, unsigned int bytes)
111
{
112
        while (bytes) {
113
                if (*start != value)
114
                        return (void *)start;
115
                start++;
116
                bytes--;
117
        }
118
        return NULL;
119
}
120
 
121
/**
122
 * memchr_inv - Find an unmatching character in an area of memory.
123
 * @start: The memory area
124
 * @c: Find a character other than c
125
 * @bytes: The size of the area.
126
 *
127
 * returns the address of the first character other than @c, or %NULL
128
 * if the whole buffer contains just @c.
129
 */
130
void *memchr_inv(const void *start, int c, size_t bytes)
131
{
132
        u8 value = c;
133
        u64 value64;
134
        unsigned int words, prefix;
135
 
136
        if (bytes <= 16)
137
                return check_bytes8(start, value, bytes);
138
 
139
        value64 = value;
140
#if defined(ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64
141
        value64 *= 0x0101010101010101;
142
#elif defined(ARCH_HAS_FAST_MULTIPLIER)
143
        value64 *= 0x01010101;
144
        value64 |= value64 << 32;
145
#else
146
        value64 |= value64 << 8;
147
        value64 |= value64 << 16;
148
        value64 |= value64 << 32;
149
#endif
150
 
151
        prefix = (unsigned long)start % 8;
152
        if (prefix) {
153
                u8 *r;
154
 
155
                prefix = 8 - prefix;
156
                r = check_bytes8(start, value, prefix);
157
                if (r)
158
                        return r;
159
                start += prefix;
160
                bytes -= prefix;
161
        }
162
 
163
        words = bytes / 8;
164
 
165
        while (words) {
166
                if (*(u64 *)start != value64)
167
                        return check_bytes8(start, value, 8);
168
                start += 8;
169
                words--;
170
        }
171
 
172
        return check_bytes8(start, value, bytes % 8);
173
}
174
 
175
 
176
 
177
int dma_map_sg(struct device *dev, struct scatterlist *sglist,
178
                           int nelems, int dir)
179
{
180
    struct scatterlist *s;
181
    int i;
182
 
183
    for_each_sg(sglist, s, nelems, i) {
184
        s->dma_address = (dma_addr_t)sg_phys(s);
185
#ifdef CONFIG_NEED_SG_DMA_LENGTH
186
        s->dma_length  = s->length;
187
#endif
188
    }
189
 
190
    return nelems;
191
}
192
 
193
 
194
int vscnprintf(char *buf, size_t size, const char *fmt, va_list args)
195
{
196
    int i;
197
 
198
    i = vsnprintf(buf, size, fmt, args);
199
 
200
    if (likely(i < size))
201
            return i;
202
    if (size != 0)
203
            return size - 1;
204
    return 0;
205
}
206
 
207
 
208
int scnprintf(char *buf, size_t size, const char *fmt, ...)
209
{
210
        va_list args;
211
        int i;
212
 
213
        va_start(args, fmt);
214
        i = vscnprintf(buf, size, fmt, args);
215
        va_end(args);
216
 
217
        return i;
218
}
219
 
220
 
221
 
222
#define _U  0x01    /* upper */
223
#define _L  0x02    /* lower */
224
#define _D  0x04    /* digit */
225
#define _C  0x08    /* cntrl */
226
#define _P  0x10    /* punct */
227
#define _S  0x20    /* white space (space/lf/tab) */
228
#define _X  0x40    /* hex digit */
229
#define _SP 0x80    /* hard space (0x20) */
230
 
231
extern const unsigned char _ctype[];
232
 
233
#define __ismask(x) (_ctype[(int)(unsigned char)(x)])
234
 
235
#define isalnum(c)  ((__ismask(c)&(_U|_L|_D)) != 0)
236
#define isalpha(c)  ((__ismask(c)&(_U|_L)) != 0)
237
#define iscntrl(c)  ((__ismask(c)&(_C)) != 0)
238
#define isdigit(c)  ((__ismask(c)&(_D)) != 0)
239
#define isgraph(c)  ((__ismask(c)&(_P|_U|_L|_D)) != 0)
240
#define islower(c)  ((__ismask(c)&(_L)) != 0)
241
#define isprint(c)  ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0)
242
#define ispunct(c)  ((__ismask(c)&(_P)) != 0)
243
/* Note: isspace() must return false for %NUL-terminator */
244
#define isspace(c)  ((__ismask(c)&(_S)) != 0)
245
#define isupper(c)  ((__ismask(c)&(_U)) != 0)
246
#define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0)
247
 
248
#define isascii(c) (((unsigned char)(c))<=0x7f)
249
#define toascii(c) (((unsigned char)(c))&0x7f)
250
 
251
static inline unsigned char __tolower(unsigned char c)
252
{
253
    if (isupper(c))
254
        c -= 'A'-'a';
255
    return c;
256
}
257
 
258
static inline unsigned char __toupper(unsigned char c)
259
{
260
    if (islower(c))
261
        c -= 'a'-'A';
262
    return c;
263
}
264
 
265
#define tolower(c) __tolower(c)
266
#define toupper(c) __toupper(c)
267
 
268
/*
269
 * Fast implementation of tolower() for internal usage. Do not use in your
270
 * code.
271
 */
272
static inline char _tolower(const char c)
273
{
274
    return c | 0x20;
275
}
276
 
277
 
278
 
279
//const char hex_asc[] = "0123456789abcdef";
280
 
281
/**
282
 * hex_to_bin - convert a hex digit to its real value
283
 * @ch: ascii character represents hex digit
284
 *
285
 * hex_to_bin() converts one hex digit to its actual value or -1 in case of bad
286
 * input.
287
 */
288
int hex_to_bin(char ch)
289
{
290
    if ((ch >= '0') && (ch <= '9'))
291
        return ch - '0';
292
    ch = tolower(ch);
293
    if ((ch >= 'a') && (ch <= 'f'))
294
        return ch - 'a' + 10;
295
    return -1;
296
}
297
EXPORT_SYMBOL(hex_to_bin);
298
 
299
/**
300
 * hex2bin - convert an ascii hexadecimal string to its binary representation
301
 * @dst: binary result
302
 * @src: ascii hexadecimal string
303
 * @count: result length
304
 *
305
 * Return 0 on success, -1 in case of bad input.
306
 */
307
int hex2bin(u8 *dst, const char *src, size_t count)
308
{
309
    while (count--) {
310
        int hi = hex_to_bin(*src++);
311
        int lo = hex_to_bin(*src++);
312
 
313
        if ((hi < 0) || (lo < 0))
314
            return -1;
315
 
316
        *dst++ = (hi << 4) | lo;
317
    }
318
    return 0;
319
}
320
EXPORT_SYMBOL(hex2bin);
321
 
322
/**
323
 * hex_dump_to_buffer - convert a blob of data to "hex ASCII" in memory
324
 * @buf: data blob to dump
325
 * @len: number of bytes in the @buf
326
 * @rowsize: number of bytes to print per line; must be 16 or 32
327
 * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1)
328
 * @linebuf: where to put the converted data
329
 * @linebuflen: total size of @linebuf, including space for terminating NUL
330
 * @ascii: include ASCII after the hex output
331
 *
332
 * hex_dump_to_buffer() works on one "line" of output at a time, i.e.,
333
 * 16 or 32 bytes of input data converted to hex + ASCII output.
334
 *
335
 * Given a buffer of u8 data, hex_dump_to_buffer() converts the input data
336
 * to a hex + ASCII dump at the supplied memory location.
337
 * The converted output is always NUL-terminated.
338
 *
339
 * E.g.:
340
 *   hex_dump_to_buffer(frame->data, frame->len, 16, 1,
341
 *          linebuf, sizeof(linebuf), true);
342
 *
343
 * example output buffer:
344
 * 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f  @ABCDEFGHIJKLMNO
345
 */
346
void hex_dump_to_buffer(const void *buf, size_t len, int rowsize,
347
            int groupsize, char *linebuf, size_t linebuflen,
348
            bool ascii)
349
{
350
    const u8 *ptr = buf;
351
    u8 ch;
352
    int j, lx = 0;
353
    int ascii_column;
354
 
355
    if (rowsize != 16 && rowsize != 32)
356
        rowsize = 16;
357
 
358
    if (!len)
359
        goto nil;
360
    if (len > rowsize)      /* limit to one line at a time */
361
        len = rowsize;
362
    if ((len % groupsize) != 0) /* no mixed size output */
363
        groupsize = 1;
364
 
365
    switch (groupsize) {
366
    case 8: {
367
        const u64 *ptr8 = buf;
368
        int ngroups = len / groupsize;
369
 
370
        for (j = 0; j < ngroups; j++)
371
            lx += scnprintf(linebuf + lx, linebuflen - lx,
372
                    "%s%16.16llx", j ? " " : "",
373
                    (unsigned long long)*(ptr8 + j));
374
        ascii_column = 17 * ngroups + 2;
375
        break;
376
    }
377
 
378
    case 4: {
379
        const u32 *ptr4 = buf;
380
        int ngroups = len / groupsize;
381
 
382
        for (j = 0; j < ngroups; j++)
383
            lx += scnprintf(linebuf + lx, linebuflen - lx,
384
                    "%s%8.8x", j ? " " : "", *(ptr4 + j));
385
        ascii_column = 9 * ngroups + 2;
386
        break;
387
    }
388
 
389
    case 2: {
390
        const u16 *ptr2 = buf;
391
        int ngroups = len / groupsize;
392
 
393
        for (j = 0; j < ngroups; j++)
394
            lx += scnprintf(linebuf + lx, linebuflen - lx,
395
                    "%s%4.4x", j ? " " : "", *(ptr2 + j));
396
        ascii_column = 5 * ngroups + 2;
397
        break;
398
    }
399
 
400
    default:
401
        for (j = 0; (j < len) && (lx + 3) <= linebuflen; j++) {
402
            ch = ptr[j];
403
            linebuf[lx++] = hex_asc_hi(ch);
404
            linebuf[lx++] = hex_asc_lo(ch);
405
            linebuf[lx++] = ' ';
406
        }
407
        if (j)
408
            lx--;
409
 
410
        ascii_column = 3 * rowsize + 2;
411
        break;
412
    }
413
    if (!ascii)
414
        goto nil;
415
 
416
    while (lx < (linebuflen - 1) && lx < (ascii_column - 1))
417
        linebuf[lx++] = ' ';
418
    for (j = 0; (j < len) && (lx + 2) < linebuflen; j++) {
419
        ch = ptr[j];
420
        linebuf[lx++] = (isascii(ch) && isprint(ch)) ? ch : '.';
421
    }
422
nil:
423
    linebuf[lx++] = '\0';
424
}
425
 
426
/**
427
 * print_hex_dump - print a text hex dump to syslog for a binary blob of data
428
 * @level: kernel log level (e.g. KERN_DEBUG)
429
 * @prefix_str: string to prefix each line with;
430
 *  caller supplies trailing spaces for alignment if desired
431
 * @prefix_type: controls whether prefix of an offset, address, or none
432
 *  is printed (%DUMP_PREFIX_OFFSET, %DUMP_PREFIX_ADDRESS, %DUMP_PREFIX_NONE)
433
 * @rowsize: number of bytes to print per line; must be 16 or 32
434
 * @groupsize: number of bytes to print at a time (1, 2, 4, 8; default = 1)
435
 * @buf: data blob to dump
436
 * @len: number of bytes in the @buf
437
 * @ascii: include ASCII after the hex output
438
 *
439
 * Given a buffer of u8 data, print_hex_dump() prints a hex + ASCII dump
440
 * to the kernel log at the specified kernel log level, with an optional
441
 * leading prefix.
442
 *
443
 * print_hex_dump() works on one "line" of output at a time, i.e.,
444
 * 16 or 32 bytes of input data converted to hex + ASCII output.
445
 * print_hex_dump() iterates over the entire input @buf, breaking it into
446
 * "line size" chunks to format and print.
447
 *
448
 * E.g.:
449
 *   print_hex_dump(KERN_DEBUG, "raw data: ", DUMP_PREFIX_ADDRESS,
450
 *          16, 1, frame->data, frame->len, true);
451
 *
452
 * Example output using %DUMP_PREFIX_OFFSET and 1-byte mode:
453
 * 0009ab42: 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d 4e 4f  @ABCDEFGHIJKLMNO
454
 * Example output using %DUMP_PREFIX_ADDRESS and 4-byte mode:
455
 * ffffffff88089af0: 73727170 77767574 7b7a7978 7f7e7d7c  pqrstuvwxyz{|}~.
456
 */
457
void print_hex_dump(const char *level, const char *prefix_str, int prefix_type,
458
            int rowsize, int groupsize,
459
            const void *buf, size_t len, bool ascii)
460
{
461
    const u8 *ptr = buf;
462
    int i, linelen, remaining = len;
463
    unsigned char linebuf[32 * 3 + 2 + 32 + 1];
464
 
465
    if (rowsize != 16 && rowsize != 32)
466
        rowsize = 16;
467
 
468
    for (i = 0; i < len; i += rowsize) {
469
        linelen = min(remaining, rowsize);
470
        remaining -= rowsize;
471
 
472
        hex_dump_to_buffer(ptr + i, linelen, rowsize, groupsize,
473
                   linebuf, sizeof(linebuf), ascii);
474
 
475
        switch (prefix_type) {
476
        case DUMP_PREFIX_ADDRESS:
477
            printk("%s%s%p: %s\n",
478
                   level, prefix_str, ptr + i, linebuf);
479
            break;
480
        case DUMP_PREFIX_OFFSET:
481
            printk("%s%s%.8x: %s\n", level, prefix_str, i, linebuf);
482
            break;
483
        default:
484
            printk("%s%s%s\n", level, prefix_str, linebuf);
485
            break;
486
        }
487
    }
488
}
489
 
490
void print_hex_dump_bytes(const char *prefix_str, int prefix_type,
491
                          const void *buf, size_t len)
492
{
493
    print_hex_dump(KERN_DEBUG, prefix_str, prefix_type, 16, 1,
494
                       buf, len, true);
495
}
496
 
4104 Serge 497
void *kmemdup(const void *src, size_t len, gfp_t gfp)
498
{
499
    void *p;
3480 Serge 500
 
4104 Serge 501
    p = kmalloc(len, gfp);
502
    if (p)
503
        memcpy(p, src, len);
504
    return p;
505
}
506
 
507