Subversion Repositories Kolibri OS

Rev

Rev 6296 | Rev 6935 | 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 
6660 serge 3
#include 
4
#include 
3260 Serge 5
#include 
6
#include 
7
#include "i915_drv.h"
8
#include "intel_drv.h"
3480 Serge 9
#include 
6084 serge 10
#include 
11
#include 
6088 serge 12
#include "i915_kos32.h"
3260 Serge 13
 
14
struct file *shmem_file_setup(const char *name, loff_t size, unsigned long flags)
15
{
16
    struct file *filep;
17
    int count;
18
 
5354 serge 19
    filep = __builtin_malloc(sizeof(*filep));
3260 Serge 20
 
21
    if(unlikely(filep == NULL))
22
        return ERR_PTR(-ENOMEM);
23
 
24
    count = size / PAGE_SIZE;
25
 
26
    filep->pages = kzalloc(sizeof(struct page *) * count, 0);
27
    if(unlikely(filep->pages == NULL))
28
    {
29
        kfree(filep);
30
        return ERR_PTR(-ENOMEM);
31
    };
32
 
33
    filep->count     = count;
34
    filep->allocated = 0;
35
    filep->vma       = NULL;
36
 
3298 Serge 37
//    printf("%s file %p pages %p count %d\n",
38
//              __FUNCTION__,filep, filep->pages, count);
3260 Serge 39
 
40
    return filep;
41
}
42
 
43
struct page *shmem_read_mapping_page_gfp(struct file *filep,
44
                                         pgoff_t index, gfp_t gfp)
45
{
46
    struct page *page;
47
 
48
    if(unlikely(index >= filep->count))
49
        return ERR_PTR(-EINVAL);
50
 
51
    page = filep->pages[index];
52
 
53
    if(unlikely(page == NULL))
54
    {
55
        page = (struct page *)AllocPage();
56
 
57
        if(unlikely(page == NULL))
58
            return ERR_PTR(-ENOMEM);
59
 
60
        filep->pages[index] = page;
4246 Serge 61
//        printf("file %p index %d page %x\n", filep, index, page);
62
//        delay(1);
63
 
3260 Serge 64
    };
65
 
66
    return page;
67
};
3263 Serge 68
 
69
unsigned long vm_mmap(struct file *file, unsigned long addr,
70
         unsigned long len, unsigned long prot,
71
         unsigned long flag, unsigned long offset)
72
{
73
    char *mem, *ptr;
74
    int i;
75
 
76
    if (unlikely(offset + PAGE_ALIGN(len) < offset))
77
        return -EINVAL;
78
    if (unlikely(offset & ~PAGE_MASK))
79
        return -EINVAL;
80
 
81
    mem = UserAlloc(len);
82
    if(unlikely(mem == NULL))
83
        return -ENOMEM;
84
 
85
    for(i = offset, ptr = mem; i < offset+len; i+= 4096, ptr+= 4096)
86
    {
87
        struct page *page;
88
 
89
        page = shmem_read_mapping_page_gfp(file, i/PAGE_SIZE,0);
90
 
91
        if (unlikely(IS_ERR(page)))
92
            goto err;
93
 
94
        MapPage(ptr, (addr_t)page, PG_SHARED|PG_UW);
95
    }
96
 
97
    return (unsigned long)mem;
98
err:
99
    UserFree(mem);
100
    return -ENOMEM;
101
};
102
 
3290 Serge 103
void shmem_file_delete(struct file *filep)
104
{
3298 Serge 105
//    printf("%s file %p pages %p count %d\n",
106
//            __FUNCTION__, filep, filep->pages, filep->count);
3263 Serge 107
 
3290 Serge 108
    if(filep->pages)
109
        kfree(filep->pages);
110
}
3480 Serge 111
 
112
 
113
 
114
static void *check_bytes8(const u8 *start, u8 value, unsigned int bytes)
115
{
116
        while (bytes) {
117
                if (*start != value)
118
                        return (void *)start;
119
                start++;
120
                bytes--;
121
        }
122
        return NULL;
123
}
124
 
125
/**
126
 * memchr_inv - Find an unmatching character in an area of memory.
127
 * @start: The memory area
128
 * @c: Find a character other than c
129
 * @bytes: The size of the area.
130
 *
131
 * returns the address of the first character other than @c, or %NULL
132
 * if the whole buffer contains just @c.
133
 */
134
void *memchr_inv(const void *start, int c, size_t bytes)
135
{
136
        u8 value = c;
137
        u64 value64;
138
        unsigned int words, prefix;
139
 
140
        if (bytes <= 16)
141
                return check_bytes8(start, value, bytes);
142
 
143
        value64 = value;
144
#if defined(ARCH_HAS_FAST_MULTIPLIER) && BITS_PER_LONG == 64
145
        value64 *= 0x0101010101010101;
146
#elif defined(ARCH_HAS_FAST_MULTIPLIER)
147
        value64 *= 0x01010101;
148
        value64 |= value64 << 32;
149
#else
150
        value64 |= value64 << 8;
151
        value64 |= value64 << 16;
152
        value64 |= value64 << 32;
153
#endif
154
 
155
        prefix = (unsigned long)start % 8;
156
        if (prefix) {
157
                u8 *r;
158
 
159
                prefix = 8 - prefix;
160
                r = check_bytes8(start, value, prefix);
161
                if (r)
162
                        return r;
163
                start += prefix;
164
                bytes -= prefix;
165
        }
166
 
167
        words = bytes / 8;
168
 
169
        while (words) {
170
                if (*(u64 *)start != value64)
171
                        return check_bytes8(start, value, 8);
172
                start += 8;
173
                words--;
174
        }
175
 
176
        return check_bytes8(start, value, bytes % 8);
177
}
178
 
179
 
6660 serge 180
int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
181
           enum dma_data_direction direction)
3480 Serge 182
{
183
    struct scatterlist *s;
184
    int i;
185
 
6660 serge 186
    for_each_sg(sg, s, nents, i) {
3480 Serge 187
        s->dma_address = (dma_addr_t)sg_phys(s);
188
#ifdef CONFIG_NEED_SG_DMA_LENGTH
189
        s->dma_length  = s->length;
190
#endif
191
    }
192
 
6660 serge 193
    return nents;
3480 Serge 194
}
195
 
6660 serge 196
void
197
dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
198
             enum dma_data_direction direction)
199
{
200
};
3480 Serge 201
 
202
 
203
#define _U  0x01    /* upper */
204
#define _L  0x02    /* lower */
205
#define _D  0x04    /* digit */
206
#define _C  0x08    /* cntrl */
207
#define _P  0x10    /* punct */
208
#define _S  0x20    /* white space (space/lf/tab) */
209
#define _X  0x40    /* hex digit */
210
#define _SP 0x80    /* hard space (0x20) */
211
 
212
extern const unsigned char _ctype[];
213
 
214
#define __ismask(x) (_ctype[(int)(unsigned char)(x)])
215
 
216
#define isalnum(c)  ((__ismask(c)&(_U|_L|_D)) != 0)
217
#define isalpha(c)  ((__ismask(c)&(_U|_L)) != 0)
218
#define iscntrl(c)  ((__ismask(c)&(_C)) != 0)
219
#define isdigit(c)  ((__ismask(c)&(_D)) != 0)
220
#define isgraph(c)  ((__ismask(c)&(_P|_U|_L|_D)) != 0)
221
#define islower(c)  ((__ismask(c)&(_L)) != 0)
222
#define isprint(c)  ((__ismask(c)&(_P|_U|_L|_D|_SP)) != 0)
223
#define ispunct(c)  ((__ismask(c)&(_P)) != 0)
224
/* Note: isspace() must return false for %NUL-terminator */
225
#define isspace(c)  ((__ismask(c)&(_S)) != 0)
226
#define isupper(c)  ((__ismask(c)&(_U)) != 0)
227
#define isxdigit(c) ((__ismask(c)&(_D|_X)) != 0)
228
 
229
#define isascii(c) (((unsigned char)(c))<=0x7f)
230
#define toascii(c) (((unsigned char)(c))&0x7f)
231
 
232
static inline unsigned char __tolower(unsigned char c)
233
{
234
    if (isupper(c))
235
        c -= 'A'-'a';
236
    return c;
237
}
238
 
239
static inline unsigned char __toupper(unsigned char c)
240
{
241
    if (islower(c))
242
        c -= 'a'-'A';
243
    return c;
244
}
245
 
246
#define tolower(c) __tolower(c)
247
#define toupper(c) __toupper(c)
248
 
249
/*
250
 * Fast implementation of tolower() for internal usage. Do not use in your
251
 * code.
252
 */
253
static inline char _tolower(const char c)
254
{
255
    return c | 0x20;
256
}
257
 
258
 
4104 Serge 259
void *kmemdup(const void *src, size_t len, gfp_t gfp)
260
{
261
    void *p;
3480 Serge 262
 
4104 Serge 263
    p = kmalloc(len, gfp);
264
    if (p)
265
        memcpy(p, src, len);
266
    return p;
267
}
268
 
269
 
5060 serge 270
 
5354 serge 271
void msleep(unsigned int msecs)
272
{
273
    msecs /= 10;
274
    if(!msecs) msecs = 1;
275
 
276
     __asm__ __volatile__ (
277
     "call *__imp__Delay"
278
     ::"b" (msecs));
279
     __asm__ __volatile__ (
280
     "":::"ebx");
281
 
282
};
283
 
284
 
285
/* simple loop based delay: */
286
static void delay_loop(unsigned long loops)
287
{
288
        asm volatile(
289
                "       test %0,%0      \n"
290
                "       jz 3f           \n"
291
                "       jmp 1f          \n"
292
 
293
                ".align 16              \n"
294
                "1:     jmp 2f          \n"
295
 
296
                ".align 16              \n"
297
                "2:     dec %0          \n"
298
                "       jnz 2b          \n"
299
                "3:     dec %0          \n"
300
 
301
                : /* we don't need output */
302
                :"a" (loops)
303
        );
304
}
305
 
306
 
307
static void (*delay_fn)(unsigned long) = delay_loop;
308
 
309
void __delay(unsigned long loops)
310
{
311
        delay_fn(loops);
312
}
313
 
314
 
315
inline void __const_udelay(unsigned long xloops)
316
{
317
        int d0;
318
 
319
        xloops *= 4;
320
        asm("mull %%edx"
321
                : "=d" (xloops), "=&a" (d0)
322
                : "1" (xloops), ""
323
                (loops_per_jiffy * (HZ/4)));
324
 
325
        __delay(++xloops);
326
}
327
 
328
void __udelay(unsigned long usecs)
329
{
330
        __const_udelay(usecs * 0x000010c7); /* 2**32 / 1000000 (rounded up) */
331
}
332
 
333
unsigned int _sw_hweight32(unsigned int w)
334
{
335
#ifdef CONFIG_ARCH_HAS_FAST_MULTIPLIER
336
        w -= (w >> 1) & 0x55555555;
337
        w =  (w & 0x33333333) + ((w >> 2) & 0x33333333);
338
        w =  (w + (w >> 4)) & 0x0f0f0f0f;
339
        return (w * 0x01010101) >> 24;
340
#else
341
        unsigned int res = w - ((w >> 1) & 0x55555555);
342
        res = (res & 0x33333333) + ((res >> 2) & 0x33333333);
343
        res = (res + (res >> 4)) & 0x0F0F0F0F;
344
        res = res + (res >> 8);
345
        return (res + (res >> 16)) & 0x000000FF;
346
#endif
347
}
348
EXPORT_SYMBOL(_sw_hweight32);
349
 
350
 
351
void usleep_range(unsigned long min, unsigned long max)
352
{
353
    udelay(max);
354
}
355
EXPORT_SYMBOL(usleep_range);
356
 
357
 
358
static unsigned long round_jiffies_common(unsigned long j, int cpu,
359
                bool force_up)
360
{
361
        int rem;
362
        unsigned long original = j;
363
 
364
        /*
365
         * We don't want all cpus firing their timers at once hitting the
366
         * same lock or cachelines, so we skew each extra cpu with an extra
367
         * 3 jiffies. This 3 jiffies came originally from the mm/ code which
368
         * already did this.
369
         * The skew is done by adding 3*cpunr, then round, then subtract this
370
         * extra offset again.
371
         */
372
        j += cpu * 3;
373
 
374
        rem = j % HZ;
375
 
376
        /*
377
         * If the target jiffie is just after a whole second (which can happen
378
         * due to delays of the timer irq, long irq off times etc etc) then
379
         * we should round down to the whole second, not up. Use 1/4th second
380
         * as cutoff for this rounding as an extreme upper bound for this.
381
         * But never round down if @force_up is set.
382
         */
383
        if (rem < HZ/4 && !force_up) /* round down */
384
                j = j - rem;
385
        else /* round up */
386
                j = j - rem + HZ;
387
 
388
        /* now that we have rounded, subtract the extra skew again */
389
        j -= cpu * 3;
390
 
391
        /*
392
         * Make sure j is still in the future. Otherwise return the
393
         * unmodified value.
394
         */
395
        return time_is_after_jiffies(j) ? j : original;
396
}
397
 
398
 
399
unsigned long round_jiffies_up_relative(unsigned long j, int cpu)
400
{
401
        unsigned long j0 = jiffies;
402
 
403
        /* Use j0 because jiffies might change while we run */
404
        return round_jiffies_common(j + j0, 0, true) - j0;
405
}
406
EXPORT_SYMBOL_GPL(__round_jiffies_up_relative);
407
 
408
 
409
#include 
410
 
411
struct rcu_ctrlblk {
412
        struct rcu_head *rcucblist;     /* List of pending callbacks (CBs). */
413
        struct rcu_head **donetail;     /* ->next pointer of last "done" CB. */
414
        struct rcu_head **curtail;      /* ->next pointer of last CB. */
415
//        RCU_TRACE(long qlen);           /* Number of pending CBs. */
416
//        RCU_TRACE(unsigned long gp_start); /* Start time for stalls. */
417
//        RCU_TRACE(unsigned long ticks_this_gp); /* Statistic for stalls. */
418
//        RCU_TRACE(unsigned long jiffies_stall); /* Jiffies at next stall. */
419
//        RCU_TRACE(const char *name);    /* Name of RCU type. */
420
};
421
 
422
/* Definition for rcupdate control block. */
423
static struct rcu_ctrlblk rcu_sched_ctrlblk = {
424
        .donetail       = &rcu_sched_ctrlblk.rcucblist,
425
        .curtail        = &rcu_sched_ctrlblk.rcucblist,
426
//        RCU_TRACE(.name = "rcu_sched")
427
};
428
 
429
static void __call_rcu(struct rcu_head *head,
430
                       void (*func)(struct rcu_head *rcu),
431
                       struct rcu_ctrlblk *rcp)
432
{
433
        unsigned long flags;
434
 
435
//        debug_rcu_head_queue(head);
436
        head->func = func;
437
        head->next = NULL;
438
 
439
        local_irq_save(flags);
440
        *rcp->curtail = head;
441
        rcp->curtail = &head->next;
442
//        RCU_TRACE(rcp->qlen++);
443
        local_irq_restore(flags);
444
}
445
 
446
/*
447
 * Post an RCU callback to be invoked after the end of an RCU-sched grace
448
 * period.  But since we have but one CPU, that would be after any
449
 * quiescent state.
450
 */
451
void call_rcu_sched(struct rcu_head *head, void (*func)(struct rcu_head *rcu))
452
{
453
        __call_rcu(head, func, &rcu_sched_ctrlblk);
454
}
455
 
6084 serge 456
int seq_puts(struct seq_file *m, const char *s)
457
{
458
    return 0;
459
};
5354 serge 460
 
6084 serge 461
__printf(2, 3) int seq_printf(struct seq_file *m, const char *f, ...)
462
{
463
    return 0;
464
}
5354 serge 465
 
6084 serge 466
ktime_t ktime_get(void)
467
{
468
    ktime_t t;
469
 
470
    t.tv64 = GetClockNs();
471
 
472
    return t;
473
}
474
 
6088 serge 475
char *strdup(const char *str)
476
{
477
    size_t len = strlen(str) + 1;
478
    char *copy = __builtin_malloc(len);
479
    if (copy)
480
    {
481
        memcpy (copy, str, len);
482
    }
483
    return copy;
484
}
485
 
486
int split_cmdline(char *cmdline, char **argv)
487
{
488
    enum quote_state
489
    {
490
        QUOTE_NONE,         /* no " active in current parm       */
491
        QUOTE_DELIMITER,    /* " was first char and must be last */
492
        QUOTE_STARTED       /* " was seen, look for a match      */
493
    };
494
 
495
    enum quote_state state;
496
    unsigned int argc;
497
    char *p = cmdline;
498
    char *new_arg, *start;
499
 
500
    argc = 0;
501
 
502
    for(;;)
503
    {
504
        /* skip over spaces and tabs */
505
        if ( *p )
506
        {
507
            while (*p == ' ' || *p == '\t')
508
                ++p;
509
        }
510
 
511
        if (*p == '\0')
512
            break;
513
 
514
        state = QUOTE_NONE;
515
        if( *p == '\"' )
516
        {
517
            p++;
518
            state = QUOTE_DELIMITER;
519
        }
520
        new_arg = start = p;
521
        for (;;)
522
        {
523
            if( *p == '\"' )
524
            {
525
                p++;
526
                if( state == QUOTE_NONE )
527
                {
528
                    state = QUOTE_STARTED;
529
                }
530
                else
531
                {
532
                    state = QUOTE_NONE;
533
                }
534
                continue;
535
            }
536
 
537
            if( *p == ' ' || *p == '\t' )
538
            {
539
                if( state == QUOTE_NONE )
540
                {
541
                    break;
542
                }
543
            }
544
 
545
            if( *p == '\0' )
546
                break;
547
 
548
            if( *p == '\\' )
549
            {
550
                if( p[1] == '\"' )
551
                {
552
                    ++p;
553
                    if( p[-2] == '\\' )
554
                    {
555
                        continue;
556
                    }
557
                }
558
            }
559
            if( argv )
560
            {
561
                *(new_arg++) = *p;
562
            }
563
            ++p;
564
        };
565
 
566
        if( argv )
567
        {
568
            argv[ argc ] = start;
569
            ++argc;
570
 
571
            /*
572
              The *new = '\0' is req'd in case there was a \" to "
573
              translation. It must be after the *p check against
574
              '\0' because new and p could point to the same char
575
              in which case the scan would be terminated too soon.
576
            */
577
 
578
            if( *p == '\0' )
579
            {
580
                *new_arg = '\0';
581
                break;
582
            }
583
            *new_arg = '\0';
584
            ++p;
585
        }
586
        else
587
        {
588
            ++argc;
589
            if( *p == '\0' )
590
            {
591
                break;
592
            }
593
            ++p;
594
        }
595
    }
596
 
597
    return argc;
598
};
599
 
600
 
6660 serge 601
int fb_get_options(const char *name, char **option)
6088 serge 602
{
603
    char *opt, *options = NULL;
604
    int retval = 1;
605
    int name_len;
606
 
607
    if(i915.cmdline_mode == NULL)
608
        return 1;
609
 
610
    name_len = __builtin_strlen(name);
611
 
612
    if (name_len )
613
    {
614
        opt = i915.cmdline_mode;
615
        if (!__builtin_strncmp(name, opt, name_len) &&
616
             opt[name_len] == ':')
617
        {
618
             options = opt + name_len + 1;
619
             retval = 0;
620
        }
621
    }
622
 
623
    if (option)
624
        *option = options;
625
 
626
    return retval;
627
}