home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / arch / blackfin / include / asm / mmu_context.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  4.8 KB  |  189 lines

  1. /*
  2.  * File:         include/asm-blackfin/mmu_context.h
  3.  * Based on:
  4.  * Author:
  5.  *
  6.  * Created:
  7.  * Description:
  8.  *
  9.  * Modified:
  10.  *               Copyright 2004-2006 Analog Devices Inc.
  11.  *
  12.  * Bugs:         Enter bugs at http://blackfin.uclinux.org/
  13.  *
  14.  * This program is free software; you can redistribute it and/or modify
  15.  * it under the terms of the GNU General Public License as published by
  16.  * the Free Software Foundation; either version 2 of the License, or
  17.  * (at your option) any later version.
  18.  *
  19.  * This program is distributed in the hope that it will be useful,
  20.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  22.  * GNU General Public License for more details.
  23.  *
  24.  * You should have received a copy of the GNU General Public License
  25.  * along with this program; if not, see the file COPYING, or write
  26.  * to the Free Software Foundation, Inc.,
  27.  * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
  28.  */
  29.  
  30. #ifndef __BLACKFIN_MMU_CONTEXT_H__
  31. #define __BLACKFIN_MMU_CONTEXT_H__
  32.  
  33. #include <linux/gfp.h>
  34. #include <linux/sched.h>
  35. #include <asm/setup.h>
  36. #include <asm/page.h>
  37. #include <asm/pgalloc.h>
  38. #include <asm/cplbinit.h>
  39.  
  40. extern void *current_l1_stack_save;
  41. extern int nr_l1stack_tasks;
  42. extern void *l1_stack_base;
  43. extern unsigned long l1_stack_len;
  44.  
  45. extern int l1sram_free(const void*);
  46. extern void *l1sram_alloc_max(void*);
  47.  
  48. static inline void free_l1stack(void)
  49. {
  50.     nr_l1stack_tasks--;
  51.     if (nr_l1stack_tasks == 0)
  52.         l1sram_free(l1_stack_base);
  53. }
  54.  
  55. static inline unsigned long
  56. alloc_l1stack(unsigned long length, unsigned long *stack_base)
  57. {
  58.     if (nr_l1stack_tasks == 0) {
  59.         l1_stack_base = l1sram_alloc_max(&l1_stack_len);
  60.         if (!l1_stack_base)
  61.             return 0;
  62.     }
  63.  
  64.     if (l1_stack_len < length) {
  65.         if (nr_l1stack_tasks == 0)
  66.             l1sram_free(l1_stack_base);
  67.         return 0;
  68.     }
  69.     *stack_base = (unsigned long)l1_stack_base;
  70.     nr_l1stack_tasks++;
  71.     return l1_stack_len;
  72. }
  73.  
  74. static inline int
  75. activate_l1stack(struct mm_struct *mm, unsigned long sp_base)
  76. {
  77.     if (current_l1_stack_save)
  78.         memcpy(current_l1_stack_save, l1_stack_base, l1_stack_len);
  79.     mm->context.l1_stack_save = current_l1_stack_save = (void*)sp_base;
  80.     memcpy(l1_stack_base, current_l1_stack_save, l1_stack_len);
  81.     return 1;
  82. }
  83.  
  84. #define deactivate_mm(tsk,mm)    do { } while (0)
  85.  
  86. #define activate_mm(prev, next) switch_mm(prev, next, NULL)
  87.  
  88. static inline void switch_mm(struct mm_struct *prev_mm, struct mm_struct *next_mm,
  89.                  struct task_struct *tsk)
  90. {
  91.     if (prev_mm == next_mm)
  92.         return;
  93. #ifdef CONFIG_MPU
  94.     if (prev_mm->context.page_rwx_mask == current_rwx_mask) {
  95.         flush_switched_cplbs();
  96.         set_mask_dcplbs(next_mm->context.page_rwx_mask);
  97.     }
  98. #endif
  99.  
  100. #ifdef CONFIG_APP_STACK_L1
  101.     /* L1 stack switching.  */
  102.     if (!next_mm->context.l1_stack_save)
  103.         return;
  104.     if (next_mm->context.l1_stack_save == current_l1_stack_save)
  105.         return;
  106.     if (current_l1_stack_save) {
  107.         memcpy(current_l1_stack_save, l1_stack_base, l1_stack_len);
  108.     }
  109.     current_l1_stack_save = next_mm->context.l1_stack_save;
  110.     memcpy(l1_stack_base, current_l1_stack_save, l1_stack_len);
  111. #endif
  112. }
  113.  
  114. #ifdef CONFIG_MPU
  115. static inline void protect_page(struct mm_struct *mm, unsigned long addr,
  116.                 unsigned long flags)
  117. {
  118.     unsigned long *mask = mm->context.page_rwx_mask;
  119.     unsigned long page = addr >> 12;
  120.     unsigned long idx = page >> 5;
  121.     unsigned long bit = 1 << (page & 31);
  122.  
  123.     if (flags & VM_MAYREAD)
  124.         mask[idx] |= bit;
  125.     else
  126.         mask[idx] &= ~bit;
  127.     mask += page_mask_nelts;
  128.     if (flags & VM_MAYWRITE)
  129.         mask[idx] |= bit;
  130.     else
  131.         mask[idx] &= ~bit;
  132.     mask += page_mask_nelts;
  133.     if (flags & VM_MAYEXEC)
  134.         mask[idx] |= bit;
  135.     else
  136.         mask[idx] &= ~bit;
  137. }
  138.  
  139. static inline void update_protections(struct mm_struct *mm)
  140. {
  141.     if (mm->context.page_rwx_mask == current_rwx_mask) {
  142.         flush_switched_cplbs();
  143.         set_mask_dcplbs(mm->context.page_rwx_mask);
  144.     }
  145. }
  146. #endif
  147.  
  148. static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk)
  149. {
  150. }
  151.  
  152. /* Called when creating a new context during fork() or execve().  */
  153. static inline int
  154. init_new_context(struct task_struct *tsk, struct mm_struct *mm)
  155. {
  156. #ifdef CONFIG_MPU
  157.     unsigned long p = __get_free_pages(GFP_KERNEL, page_mask_order);
  158.     mm->context.page_rwx_mask = (unsigned long *)p;
  159.     memset(mm->context.page_rwx_mask, 0,
  160.            page_mask_nelts * 3 * sizeof(long));
  161. #endif
  162.     return 0;
  163. }
  164.  
  165. static inline void destroy_context(struct mm_struct *mm)
  166. {
  167.     struct sram_list_struct *tmp;
  168.  
  169. #ifdef CONFIG_APP_STACK_L1
  170.     if (current_l1_stack_save == mm->context.l1_stack_save)
  171.         current_l1_stack_save = 0;
  172.     if (mm->context.l1_stack_save)
  173.         free_l1stack();
  174. #endif
  175.  
  176.     while ((tmp = mm->context.sram_list)) {
  177.         mm->context.sram_list = tmp->next;
  178.         sram_free(tmp->addr);
  179.         kfree(tmp);
  180.     }
  181. #ifdef CONFIG_MPU
  182.     if (current_rwx_mask == mm->context.page_rwx_mask)
  183.         current_rwx_mask = NULL;
  184.     free_pages((unsigned long)mm->context.page_rwx_mask, page_mask_order);
  185. #endif
  186. }
  187.  
  188. #endif
  189.