Subversion Repositories Kolibri OS

Rev

Rev 6296 | Rev 6935 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. #include <ddk.h>
  2. #include <linux/mm.h>
  3. #include <linux/scatterlist.h>
  4. #include <linux/dma-mapping.h>
  5. #include <drm/drmP.h>
  6. #include <drm/i915_drm.h>
  7. #include "i915_drv.h"
  8. #include "intel_drv.h"
  9. #include <linux/hdmi.h>
  10. #include <linux/seq_file.h>
  11. #include <linux/fence.h>
  12. #include "i915_kos32.h"
  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.  
  19.     filep = __builtin_malloc(sizeof(*filep));
  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.  
  37. //    printf("%s file %p pages %p count %d\n",
  38. //              __FUNCTION__,filep, filep->pages, count);
  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;
  61. //        printf("file %p index %d page %x\n", filep, index, page);
  62. //        delay(1);
  63.  
  64.     };
  65.  
  66.     return page;
  67. };
  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.  
  103. void shmem_file_delete(struct file *filep)
  104. {
  105. //    printf("%s file %p pages %p count %d\n",
  106. //            __FUNCTION__, filep, filep->pages, filep->count);
  107.  
  108.     if(filep->pages)
  109.         kfree(filep->pages);
  110. }
  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.  
  180. int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
  181.            enum dma_data_direction direction)
  182. {
  183.     struct scatterlist *s;
  184.     int i;
  185.  
  186.     for_each_sg(sg, s, nents, i) {
  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.  
  193.     return nents;
  194. }
  195.  
  196. void
  197. dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
  198.              enum dma_data_direction direction)
  199. {
  200. };
  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.  
  259. void *kmemdup(const void *src, size_t len, gfp_t gfp)
  260. {
  261.     void *p;
  262.  
  263.     p = kmalloc(len, gfp);
  264.     if (p)
  265.         memcpy(p, src, len);
  266.     return p;
  267. }
  268.  
  269.  
  270.  
  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 <linux/rcupdate.h>
  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.  
  456. int seq_puts(struct seq_file *m, const char *s)
  457. {
  458.     return 0;
  459. };
  460.  
  461. __printf(2, 3) int seq_printf(struct seq_file *m, const char *f, ...)
  462. {
  463.     return 0;
  464. }
  465.  
  466. ktime_t ktime_get(void)
  467. {
  468.     ktime_t t;
  469.  
  470.     t.tv64 = GetClockNs();
  471.  
  472.     return t;
  473. }
  474.  
  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.  
  601. int fb_get_options(const char *name, char **option)
  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. }
  628.