Subversion Repositories HelenOS

Rev

Rev 2199 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2199 Rev 2238
Line 1... Line 1...
1
/*
1
/*
2
 * Copyright (c) 2003-2007 Jakub Jermar
2
 * Copyright (c) 2007 Pavel Jancik, Michal Kebrt
3
 * All rights reserved.
3
 * All rights reserved.
4
 *
4
 *
5
 * Redistribution and use in source and binary forms, with or without
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions
6
 * modification, are permitted provided that the following conditions
7
 * are met:
7
 * are met:
Line 52... Line 52...
52
#   define KA2PA(x) ((x) - 0x80000000)
52
#   define KA2PA(x) ((x) - 0x80000000)
53
#   define PA2KA(x) ((x) + 0x80000000)
53
#   define PA2KA(x) ((x) + 0x80000000)
54
#endif
54
#endif
55
 
55
 
56
#ifdef KERNEL
56
#ifdef KERNEL
57
// Using small pages <==> 4kb
-
 
58
#define PTL0_ENTRIES_ARCH   (2<<12) // 4096
-
 
59
#define PTL1_ENTRIES_ARCH   0   
-
 
60
#define PTL2_ENTRIES_ARCH   0   
-
 
61
#define PTL3_ENTRIES_ARCH   (2<<8)  // 256
-
 
62
 
-
 
63
#define PTL0_INDEX_ARCH(vaddr)  (((vaddr) >> 20) & 0xfff)
-
 
64
#define PTL1_INDEX_ARCH(vaddr)  0   
-
 
65
#define PTL2_INDEX_ARCH(vaddr)  0   
-
 
66
#define PTL3_INDEX_ARCH(vaddr)  (((vaddr) >> 12) & 0x0ff)
-
 
67
 
-
 
68
 
-
 
69
#define GET_PTL1_ADDRESS_ARCH(ptl0, i)      ((pte_t *)(  (((pte_level0_t*)(ptl0))[(i)]).coarse_table_addr << 10 ))
-
 
70
#define GET_PTL2_ADDRESS_ARCH(ptl1, i)      (ptl1)
-
 
71
#define GET_PTL3_ADDRESS_ARCH(ptl2, i)      (ptl2)
-
 
72
#define GET_FRAME_ADDRESS_ARCH(ptl3, i)     ( (uintptr_t)(((pte_level1_t*)(ptl3))[(i)]).frame_base_addr << 12 ))
-
 
73
 
57
 
-
 
58
// "small" pages (4KB) used
-
 
59
#define PTL0_ENTRIES_ARCH    (2<<12)    // 4096
-
 
60
#define PTL1_ENTRIES_ARCH     0 
-
 
61
#define PTL2_ENTRIES_ARCH     0 
-
 
62
#define PTL3_ENTRIES_ARCH    (2<<8)     // 256
-
 
63
 
-
 
64
#define PTL0_INDEX_ARCH(vaddr)    (((vaddr) >> 20) & 0xfff)
-
 
65
#define PTL1_INDEX_ARCH(vaddr)    0 
-
 
66
#define PTL2_INDEX_ARCH(vaddr)    0 
-
 
67
#define PTL3_INDEX_ARCH(vaddr)    (((vaddr) >> 12) & 0x0ff)
-
 
68
 
-
 
69
#define GET_PTL1_ADDRESS_ARCH(ptl0, i)      ((pte_t *)( (((pte_level0_t*)(ptl0))[(i)]).coarse_table_addr << 10 ))
-
 
70
#define GET_PTL2_ADDRESS_ARCH(ptl1, i)      (ptl1)
-
 
71
#define GET_PTL3_ADDRESS_ARCH(ptl2, i)      (ptl2)
-
 
72
#define GET_FRAME_ADDRESS_ARCH(ptl3, i)     ((uintptr_t)( (((pte_level1_t*)(ptl3))[(i)]).frame_base_addr << 12 ))
-
 
73
 
74
#define SET_PTL0_ADDRESS_ARCH(ptl0)         ( set_ptl0_addr((pte_level0_t *)(ptl0)) )
74
#define SET_PTL0_ADDRESS_ARCH(ptl0)         (set_ptl0_addr((pte_level0_t *)(ptl0)))
75
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a)   (((pte_level0_t *)(ptl0))[(i)].coarse_table_addr = (a)>>10)
75
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a)   (((pte_level0_t *)(ptl0))[(i)].coarse_table_addr = (a)>>10)
76
#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
76
#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
77
#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
77
#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
78
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a)  (((pte_level1_t *)(ptl3))[(i)].frame_base_addr = (a)>>12)
78
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a)  (((pte_level1_t *)(ptl3))[(i)].frame_base_addr = (a)>>12)
79
 
79
 
80
#define GET_PTL1_FLAGS_ARCH(ptl0, i)        get_pt_level0_flags((pte_level0_t *)(ptl0), (index_t)(i))
80
#define GET_PTL1_FLAGS_ARCH(ptl0, i)        get_pt_level0_flags((pte_level0_t *)(ptl0), (index_t)(i))
81
#define GET_PTL2_FLAGS_ARCH(ptl1, i)        PAGE_PRESENT
81
#define GET_PTL2_FLAGS_ARCH(ptl1, i)        PAGE_PRESENT
82
#define GET_PTL3_FLAGS_ARCH(ptl2, i)        PAGE_PRESENT
82
#define GET_PTL3_FLAGS_ARCH(ptl2, i)        PAGE_PRESENT
83
#define GET_FRAME_FLAGS_ARCH(ptl3, i)       get_pt_level1_flags((pte_level1_t *)(ptl3), (index_t)(i))
83
#define GET_FRAME_FLAGS_ARCH(ptl3, i)       get_pt_level1_flags((pte_level1_t *)(ptl3), (index_t)(i))
84
 
84
 
85
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x)     set_pt_level0_flags((pte_level0_t *)(ptl0), (index_t)(i), (x))
85
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x)     set_pt_level0_flags((pte_level0_t *)(ptl0), (index_t)(i), (x))
86
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
86
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
87
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
87
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
88
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x)    set_pt_level1_flags((pte_level1_t *)(ptl3), (index_t)(i), (x))
88
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x)    set_pt_level1_flags((pte_level1_t *)(ptl3), (index_t)(i), (x))
89
 
89
 
90
#define PTE_VALID_ARCH(pte)                 (*((uint32_t *) (pte)) != 0)
90
#define PTE_VALID_ARCH(pte)                 (*((uint32_t *) (pte)) != 0)
91
#define PTE_PRESENT_ARCH(pte)               ( ((pte_level0_t *)(pte))->descriptor_type )
91
#define PTE_PRESENT_ARCH(pte)               ( ((pte_level0_t *)(pte))->descriptor_type )
-
 
92
// pte should point into ptl3 
92
#define PTE_GET_FRAME_ARCH(pte)             ( ((pte_level1_t *)(pte))->frame_base_addr << FRAME_WIDTH)  // pte should point into ptl3 
93
#define PTE_GET_FRAME_ARCH(pte)             ( ((pte_level1_t *)(pte))->frame_base_addr << FRAME_WIDTH)
-
 
94
// pte should point into ptl3 
93
#define PTE_WRITABLE_ARCH(pte)              ( ((pte_level1_t *)(pte))->access_permission_0 == pte_ap_user_rw_kernel_rw )  // pte should point into ptl3
95
#define PTE_WRITABLE_ARCH(pte)              ( ((pte_level1_t *)(pte))->access_permission_0 == pte_ap_user_rw_kernel_rw ) 
94
#define PTE_EXECUTABLE_ARCH(pte)               1
96
#define PTE_EXECUTABLE_ARCH(pte)            1
95
 
97
 
96
#ifndef __ASM__
98
#ifndef __ASM__
97
 
99
 
98
/** Set adress of paging level 0 table
100
/** Sets the address of level 0 page table.
99
 * \param pt pointer to page table to set
101
 * \param pt pointer to the page table to set
100
 */  
102
 */  
101
static inline void set_ptl0_addr( pte_level0_t* pt){
103
static inline void set_ptl0_addr( pte_level0_t* pt)
-
 
104
{
102
    asm volatile ( "mcr p15, 0, %0, c2, c0, 0 \n"
105
    asm volatile ( "mcr p15, 0, %0, c2, c0, 0 \n"
103
    :
106
        :
104
    : "r"(pt)
107
        : "r"(pt)
105
    );
108
    );
106
   
109
   
107
}
110
}
108
 
111
 
109
//TODO Comment: Page table structure as in other architectures
112
//TODO Comment: Page table structure as in other architectures
110
 
-
 
111
static inline int get_pt_level0_flags(pte_level0_t *pt, index_t i)
113
static inline int get_pt_level0_flags(pte_level0_t *pt, index_t i)
112
{
114
{
113
  pte_level0_t *p = &pt[i];
115
    pte_level0_t *p = &pt[i];
114
 
116
 
115
    return (
117
    return (
116
        ( p->descriptor_type != pte_descriptor_not_preset ) << PAGE_PRESENT_SHIFT |
118
        ( p->descriptor_type != pte_descriptor_not_preset ) << PAGE_PRESENT_SHIFT |
117
        ( 1 << PAGE_READ_SHIFT ) |
119
        ( 1 << PAGE_READ_SHIFT ) |
118
        ( 1 << PAGE_EXEC_SHIFT ) |
120
        ( 1 << PAGE_EXEC_SHIFT ) |
119
        ( 1 << PAGE_CACHEABLE  )
121
        ( 1 << PAGE_CACHEABLE  )
120
    );
122
    );
121
 
-
 
122
}
123
}
-
 
124
 
123
static inline int get_pt_level1_flags(pte_level1_t *pt, index_t i)
125
static inline int get_pt_level1_flags(pte_level1_t *pt, index_t i)
124
{
126
{
125
  pte_level1_t *p = &pt[i];
127
  pte_level1_t *p = &pt[i];
126
 
128
 
127
    return (
129
    return (
Line 136... Line 138...
136
 
138
 
137
    );
139
    );
138
 
140
 
139
}
141
}
140
 
142
 
141
 
-
 
142
static inline void set_pt_level0_flags(pte_level0_t *pt, index_t i, int flags)
143
static inline void set_pt_level0_flags(pte_level0_t *pt, index_t i, int flags)
143
{
144
{
144
    pte_level0_t *p = &pt[i];
145
    pte_level0_t *p = &pt[i];
145
   
146
   
146
    if ( flags & PAGE_NOT_PRESENT ) {
147
    if ( flags & PAGE_NOT_PRESENT ) {
147
      p->descriptor_type = pte_descriptor_not_preset;
148
        p->descriptor_type = pte_descriptor_not_preset;
148
      p->should_be_zero  = 1;
149
        p->should_be_zero  = 1;
149
    } else
150
    } else {
150
    {
-
 
151
      p->descriptor_type = pte_descriptor_coarse_table;
151
        p->descriptor_type = pte_descriptor_coarse_table;
152
      p->should_be_zero  = 0;
152
        p->should_be_zero  = 0;
153
    }
153
    }
154
    return;
-
 
155
}
154
}
156
 
155
 
157
/* We use same acess rights for whole page, so if page is set as not preset then
156
/* TODO: rewrite comment: We use same acess rights for whole page, so if page is set as not preset then
158
 * in acess_rigts_3 set value 1
157
 * in acess_rigts_3 set value 1
159
 */  
158
 */  
160
static inline void set_pt_level1_flags(pte_level1_t *pt, index_t i, int flags)
159
static inline void set_pt_level1_flags(pte_level1_t *pt, index_t i, int flags)
161
{
160
{
162
    pte_level1_t *p = &pt[i];
161
    pte_level1_t *p = &pt[i];
163
   
162
   
164
    if ( flags & PAGE_NOT_PRESENT ) {
163
    if ( flags & PAGE_NOT_PRESENT ) {
165
      p->descriptor_type      = pte_descriptor_not_preset;
164
        p->descriptor_type      = pte_descriptor_not_preset;
166
      p->access_permission_3  = 1;
165
        p->access_permission_3  = 1;
167
    } else
166
    } else {
168
    {
-
 
169
      p->descriptor_type      = pte_descriptor_coarse_table;
167
        p->descriptor_type      = pte_descriptor_coarse_table;
170
      p->access_permission_3  = p->access_permission_0;
168
        p->access_permission_3  = p->access_permission_0;
171
    }
169
    }
172
 
170
 
173
  p->cacheable = p->bufferable = (flags & PAGE_CACHEABLE) != 0;
171
    p->cacheable = p->bufferable = (flags & PAGE_CACHEABLE) != 0;
-
 
172
 
174
  // default kernel rw, user none
173
    // default kernel rw, user none
-
 
174
    p->access_permission_0 = p->access_permission_1 =
175
  p->access_permission_0 = p->access_permission_1 = p->access_permission_2 = p->access_permission_3 = pte_ap_user_no_kernel_rw;
175
        p->access_permission_2 = p->access_permission_3 = pte_ap_user_no_kernel_rw;
-
 
176
 
176
  if ( flags & PAGE_USER )  {
177
    if ( flags & PAGE_USER )  {
177
      if ( flags & PAGE_READ )
178
        if ( flags & PAGE_READ ) {
-
 
179
            p->access_permission_0 = p->access_permission_1 =
178
          p->access_permission_0 = p->access_permission_1 = p->access_permission_2 = p->access_permission_3 = pte_ap_user_ro_kernel_rw;
180
                p->access_permission_2 = p->access_permission_3 =
-
 
181
                pte_ap_user_ro_kernel_rw;
-
 
182
        }
179
      if ( flags & PAGE_WRITE )
183
        if ( flags & PAGE_WRITE ) {
-
 
184
            p->access_permission_0 = p->access_permission_1 =
180
          p->access_permission_0 = p->access_permission_1 = p->access_permission_2 = p->access_permission_3 = pte_ap_user_rw_kernel_rw;
185
                p->access_permission_2 = p->access_permission_3 =
-
 
186
                pte_ap_user_rw_kernel_rw;
181
  }
187
        }
182
    return; return;
188
    }
183
}
189
}
184
 
190
 
185
extern void page_arch_init(void);
191
extern void page_arch_init(void);
186
 
192
 
187
#endif /* __ASM__ */
193
#endif /* __ASM__ */