Subversion Repositories HelenOS

Rev

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

Rev 2465 Rev 2467
Line 53... Line 53...
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
 
57
 
-
 
58
/* Number of entries in each level. */
58
#define PTL0_ENTRIES_ARCH   (2 << 12)   /* 4096 */
59
#define PTL0_ENTRIES_ARCH   (2 << 12)   /* 4096 */
59
#define PTL1_ENTRIES_ARCH   0
60
#define PTL1_ENTRIES_ARCH   0
60
#define PTL2_ENTRIES_ARCH   0
61
#define PTL2_ENTRIES_ARCH   0
61
 
-
 
62
/* coarse page tables used (256 * 4 = 1KB per page) */
62
/* coarse page tables used (256 * 4 = 1KB per page) */
63
#define PTL3_ENTRIES_ARCH   (2 << 8)    /* 256 */
63
#define PTL3_ENTRIES_ARCH   (2 << 8)    /* 256 */
64
 
64
 
-
 
65
/* Page table sizes for each level. */
65
#define PTL0_SIZE_ARCH      FOUR_FRAMES
66
#define PTL0_SIZE_ARCH      FOUR_FRAMES
66
#define PTL1_SIZE_ARCH      0
67
#define PTL1_SIZE_ARCH      0
67
#define PTL2_SIZE_ARCH      0
68
#define PTL2_SIZE_ARCH      0
68
#define PTL3_SIZE_ARCH      ONE_FRAME
69
#define PTL3_SIZE_ARCH      ONE_FRAME
69
 
70
 
-
 
71
/* Macros calculating indices into page tables for each level. */
70
#define PTL0_INDEX_ARCH(vaddr)  (((vaddr) >> 20) & 0xfff)
72
#define PTL0_INDEX_ARCH(vaddr)  (((vaddr) >> 20) & 0xfff)
71
#define PTL1_INDEX_ARCH(vaddr)  0
73
#define PTL1_INDEX_ARCH(vaddr)  0
72
#define PTL2_INDEX_ARCH(vaddr)  0
74
#define PTL2_INDEX_ARCH(vaddr)  0
73
#define PTL3_INDEX_ARCH(vaddr)  (((vaddr) >> 12) & 0x0ff)
75
#define PTL3_INDEX_ARCH(vaddr)  (((vaddr) >> 12) & 0x0ff)
74
 
76
 
-
 
77
/* Get PTE address accessors for each level. */
75
#define GET_PTL1_ADDRESS_ARCH(ptl0, i) \
78
#define GET_PTL1_ADDRESS_ARCH(ptl0, i) \
76
    ((pte_t *) ((((pte_level0_t *)(ptl0))[(i)]).coarse_table_addr << 10))
79
    ((pte_t *) ((((pte_level0_t *)(ptl0))[(i)]).coarse_table_addr << 10))
77
#define GET_PTL2_ADDRESS_ARCH(ptl1, i) \
80
#define GET_PTL2_ADDRESS_ARCH(ptl1, i) \
78
    (ptl1)
81
    (ptl1)
79
#define GET_PTL3_ADDRESS_ARCH(ptl2, i) \
82
#define GET_PTL3_ADDRESS_ARCH(ptl2, i) \
80
    (ptl2)
83
    (ptl2)
81
#define GET_FRAME_ADDRESS_ARCH(ptl3, i) \
84
#define GET_FRAME_ADDRESS_ARCH(ptl3, i) \
82
    ((uintptr_t) ((((pte_level1_t *)(ptl3))[(i)]).frame_base_addr << 12))
85
    ((uintptr_t) ((((pte_level1_t *)(ptl3))[(i)]).frame_base_addr << 12))
83
 
86
 
-
 
87
/* Set PTE address accessors for each level. */
84
#define SET_PTL0_ADDRESS_ARCH(ptl0) \
88
#define SET_PTL0_ADDRESS_ARCH(ptl0) \
85
    (set_ptl0_addr((pte_level0_t *) (ptl0)))
89
    (set_ptl0_addr((pte_level0_t *) (ptl0)))
86
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \
90
#define SET_PTL1_ADDRESS_ARCH(ptl0, i, a) \
87
    (((pte_level0_t *) (ptl0))[(i)].coarse_table_addr = (a) >> 10)
91
    (((pte_level0_t *) (ptl0))[(i)].coarse_table_addr = (a) >> 10)
88
#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
92
#define SET_PTL2_ADDRESS_ARCH(ptl1, i, a)
89
#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
93
#define SET_PTL3_ADDRESS_ARCH(ptl2, i, a)
90
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) \
94
#define SET_FRAME_ADDRESS_ARCH(ptl3, i, a) \
91
    (((pte_level1_t *) (ptl3))[(i)].frame_base_addr = (a) >> 12)
95
    (((pte_level1_t *) (ptl3))[(i)].frame_base_addr = (a) >> 12)
92
 
96
 
-
 
97
/* Get PTE flags accessors for each level. */
93
#define GET_PTL1_FLAGS_ARCH(ptl0, i) \
98
#define GET_PTL1_FLAGS_ARCH(ptl0, i) \
94
    get_pt_level0_flags((pte_level0_t *) (ptl0), (index_t) (i))
99
    get_pt_level0_flags((pte_level0_t *) (ptl0), (index_t) (i))
95
#define GET_PTL2_FLAGS_ARCH(ptl1, i) \
100
#define GET_PTL2_FLAGS_ARCH(ptl1, i) \
96
    PAGE_PRESENT
101
    PAGE_PRESENT
97
#define GET_PTL3_FLAGS_ARCH(ptl2, i) \
102
#define GET_PTL3_FLAGS_ARCH(ptl2, i) \
98
    PAGE_PRESENT
103
    PAGE_PRESENT
99
#define GET_FRAME_FLAGS_ARCH(ptl3, i) \
104
#define GET_FRAME_FLAGS_ARCH(ptl3, i) \
100
    get_pt_level1_flags((pte_level1_t *) (ptl3), (index_t) (i))
105
    get_pt_level1_flags((pte_level1_t *) (ptl3), (index_t) (i))
101
 
106
 
-
 
107
/* Set PTE flags accessors for each level. */
102
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \
108
#define SET_PTL1_FLAGS_ARCH(ptl0, i, x) \
103
    set_pt_level0_flags((pte_level0_t *) (ptl0), (index_t) (i), (x))
109
    set_pt_level0_flags((pte_level0_t *) (ptl0), (index_t) (i), (x))
104
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
110
#define SET_PTL2_FLAGS_ARCH(ptl1, i, x)
105
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
111
#define SET_PTL3_FLAGS_ARCH(ptl2, i, x)
106
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \
112
#define SET_FRAME_FLAGS_ARCH(ptl3, i, x) \
107
    set_pt_level1_flags((pte_level1_t *) (ptl3), (index_t) (i), (x))
113
    set_pt_level1_flags((pte_level1_t *) (ptl3), (index_t) (i), (x))
108
 
114
 
-
 
115
/* Macros for querying the last-level PTE entries. */
109
#define PTE_VALID_ARCH(pte) \
116
#define PTE_VALID_ARCH(pte) \
110
    (*((uint32_t *) (pte)) != 0)
117
    (*((uint32_t *) (pte)) != 0)
111
#define PTE_PRESENT_ARCH(pte) \
118
#define PTE_PRESENT_ARCH(pte) \
112
    (((pte_level0_t *) (pte))->descriptor_type != 0)
119
    (((pte_level0_t *) (pte))->descriptor_type != 0)
113
 
-
 
114
/* pte should point into ptl3 */
-
 
115
#define PTE_GET_FRAME_ARCH(pte) \
120
#define PTE_GET_FRAME_ARCH(pte) \
116
    (((pte_level1_t *) (pte))->frame_base_addr << FRAME_WIDTH)
121
    (((pte_level1_t *) (pte))->frame_base_addr << FRAME_WIDTH)
117
 
-
 
118
/* pte should point into ptl3 */
-
 
119
#define PTE_WRITABLE_ARCH(pte) \
122
#define PTE_WRITABLE_ARCH(pte) \
120
    (((pte_level1_t *) (pte))->access_permission_0 == \
123
    (((pte_level1_t *) (pte))->access_permission_0 == \
121
        PTE_AP_USER_RW_KERNEL_RW)
124
        PTE_AP_USER_RW_KERNEL_RW)
122
 
-
 
123
#define PTE_EXECUTABLE_ARCH(pte) \
125
#define PTE_EXECUTABLE_ARCH(pte) \
124
    1
126
    1
125
 
127
 
126
#ifndef __ASM__
128
#ifndef __ASM__
127
 
129
 
128
/** Level 0 page table entry. */
130
/** Level 0 page table entry. */
129
typedef struct {
131
typedef struct {
130
    /* 0b01 for coarse tables, see below for details */
132
    /* 0b01 for coarse tables, see below for details */
131
    unsigned descriptor_type     : 2;
133
    unsigned descriptor_type : 2;
132
    unsigned impl_specific       : 3;
134
    unsigned impl_specific : 3;
133
    unsigned domain              : 4;
135
    unsigned domain : 4;
134
    unsigned should_be_zero      : 1;
136
    unsigned should_be_zero : 1;
135
 
137
 
136
    /* Pointer to the coarse 2nd level page table (holding entries for small
138
    /* Pointer to the coarse 2nd level page table (holding entries for small
137
     * (4KB) or large (64KB) pages. ARM also supports fine 2nd level page
139
     * (4KB) or large (64KB) pages. ARM also supports fine 2nd level page
138
     * tables that may hold even tiny pages (1KB) but they are bigger (4KB
140
     * tables that may hold even tiny pages (1KB) but they are bigger (4KB
139
     * per table in comparison with 1KB per the coarse table)
141
     * per table in comparison with 1KB per the coarse table)
140
     */
142
     */
141
    unsigned coarse_table_addr   : 22;
143
    unsigned coarse_table_addr : 22;
142
} ATTRIBUTE_PACKED pte_level0_t;
144
} ATTRIBUTE_PACKED pte_level0_t;
143
 
145
 
144
/** Level 1 page table entry (small (4KB) pages used). */
146
/** Level 1 page table entry (small (4KB) pages used). */
145
typedef struct {
147
typedef struct {
146
 
148
 
147
    /* 0b10 for small pages */
149
    /* 0b10 for small pages */
148
    unsigned descriptor_type     : 2;
150
    unsigned descriptor_type : 2;
149
    unsigned bufferable          : 1;
151
    unsigned bufferable : 1;
150
    unsigned cacheable           : 1;
152
    unsigned cacheable : 1;
151
 
153
 
152
    /* access permissions for each of 4 subparts of a page
154
    /* access permissions for each of 4 subparts of a page
153
     * (for each 1KB when small pages used */
155
     * (for each 1KB when small pages used */
154
    unsigned access_permission_0 : 2;
156
    unsigned access_permission_0 : 2;
155
    unsigned access_permission_1 : 2;
157
    unsigned access_permission_1 : 2;
156
    unsigned access_permission_2 : 2;
158
    unsigned access_permission_2 : 2;
157
    unsigned access_permission_3 : 2;
159
    unsigned access_permission_3 : 2;
158
    unsigned frame_base_addr     : 20;
160
    unsigned frame_base_addr : 20;
159
} ATTRIBUTE_PACKED pte_level1_t;
161
} ATTRIBUTE_PACKED pte_level1_t;
160
 
162
 
161
 
163
 
162
/* Level 1 page tables access permissions */
164
/* Level 1 page tables access permissions */
163
 
165
 
Line 188... Line 190...
188
 
190
 
189
/** Sets the address of level 0 page table.
191
/** Sets the address of level 0 page table.
190
 *
192
 *
191
 * @param pt    Pointer to the page table to set.
193
 * @param pt    Pointer to the page table to set.
192
 */  
194
 */  
193
static inline void set_ptl0_addr( pte_level0_t *pt)
195
static inline void set_ptl0_addr(pte_level0_t *pt)
194
{
196
{
195
    asm volatile (
197
    asm volatile (
196
        "mcr p15, 0, %0, c2, c0, 0 \n"
198
        "mcr p15, 0, %0, c2, c0, 0 \n"
197
        :
199
        :
198
        : "r"(pt)
200
        : "r"(pt)