Subversion Repositories HelenOS-historic

Rev

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

Rev 826 Rev 832
Line 101... Line 101...
101
 *
101
 *
102
 * Remove any mapping of 'page' within address space 'as'.
102
 * Remove any mapping of 'page' within address space 'as'.
103
 * TLB shootdown should follow in order to make effects of
103
 * TLB shootdown should follow in order to make effects of
104
 * this call visible.
104
 * this call visible.
105
 *
105
 *
-
 
106
 * Empty page tables except PTL0 are freed.
-
 
107
 *
106
 * The address space must be locked and interrupts must be disabled.
108
 * The address space must be locked and interrupts must be disabled.
107
 *
109
 *
108
 * @param as Address space to wich page belongs.
110
 * @param as Address space to wich page belongs.
109
 * @param page Virtual address of the page to be demapped.
111
 * @param page Virtual address of the page to be demapped.
110
 */
112
 */
111
void pt_mapping_remove(as_t *as, __address page)
113
void pt_mapping_remove(as_t *as, __address page)
112
{
114
{
113
    pte_t *ptl0, *ptl1, *ptl2, *ptl3;
115
    pte_t *ptl0, *ptl1, *ptl2, *ptl3;
-
 
116
    bool empty = true;
-
 
117
    int i;
-
 
118
 
-
 
119
    /*
-
 
120
     * First, remove the mapping, if it exists.
-
 
121
     */
114
 
122
 
115
    ptl0 = (pte_t *) PA2KA((__address) as->page_table);
123
    ptl0 = (pte_t *) PA2KA((__address) as->page_table);
116
 
124
 
117
    if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT)
125
    if (GET_PTL1_FLAGS(ptl0, PTL0_INDEX(page)) & PAGE_NOT_PRESENT)
118
        return;
126
        return;
Line 129... Line 137...
129
 
137
 
130
    ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
138
    ptl3 = (pte_t *) PA2KA(GET_PTL3_ADDRESS(ptl2, PTL2_INDEX(page)));
131
 
139
 
132
    /* Destroy the mapping. Setting to PAGE_NOT_PRESENT is not sufficient. */
140
    /* Destroy the mapping. Setting to PAGE_NOT_PRESENT is not sufficient. */
133
    memsetb((__address) &ptl3[PTL3_INDEX(page)], sizeof(pte_t), 0);
141
    memsetb((__address) &ptl3[PTL3_INDEX(page)], sizeof(pte_t), 0);
-
 
142
 
-
 
143
    /*
-
 
144
     * Second, free all empty tables along the way from PTL3 down to PTL0.
-
 
145
     */
-
 
146
   
-
 
147
    /* check PTL3 */
-
 
148
    for (i = 0; i < PTL3_ENTRIES; i++) {
-
 
149
        if (PTE_VALID(&ptl3[i])) {
-
 
150
            empty = false;
-
 
151
            break;
-
 
152
        }
-
 
153
    }
-
 
154
    if (empty) {
-
 
155
        /*
-
 
156
         * PTL3 is empty.
-
 
157
         * Release the frame and remove PTL3 pointer from preceding table.
-
 
158
         */
-
 
159
        frame_free(ADDR2PFN(KA2PA((__address) ptl3)));
-
 
160
        if (PTL2_ENTRIES)
-
 
161
            memsetb((__address) &ptl2[PTL2_INDEX(page)], sizeof(pte_t), 0);
-
 
162
        else if (PTL1_ENTRIES)
-
 
163
            memsetb((__address) &ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0);
-
 
164
        else
-
 
165
            memsetb((__address) &ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
-
 
166
    } else {
-
 
167
        /*
-
 
168
         * PTL3 is not empty.
-
 
169
         * Therefore, there must be a path from PTL0 to PTL3 and
-
 
170
         * thus nothing to free in higher levels.
-
 
171
         */
-
 
172
        return;
-
 
173
    }
-
 
174
   
-
 
175
    /* check PTL2, empty is still true */
-
 
176
    if (PTL2_ENTRIES) {
-
 
177
        for (i = 0; i < PTL2_ENTRIES; i++) {
-
 
178
            if (PTE_VALID(&ptl2[i])) {
-
 
179
                empty = false;
-
 
180
                break;
-
 
181
            }
-
 
182
        }
-
 
183
        if (empty) {
-
 
184
            /*
-
 
185
             * PTL2 is empty.
-
 
186
             * Release the frame and remove PTL2 pointer from preceding table.
-
 
187
             */
-
 
188
            frame_free(ADDR2PFN(KA2PA((__address) ptl2)));
-
 
189
            if (PTL1_ENTRIES)
-
 
190
                memsetb((__address) &ptl1[PTL1_INDEX(page)], sizeof(pte_t), 0);
-
 
191
            else
-
 
192
                memsetb((__address) &ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
-
 
193
        }
-
 
194
        else {
-
 
195
            /*
-
 
196
             * PTL2 is not empty.
-
 
197
             * Therefore, there must be a path from PTL0 to PTL2 and
-
 
198
             * thus nothing to free in higher levels.
-
 
199
             */
-
 
200
            return;
-
 
201
        }
-
 
202
    }
-
 
203
 
-
 
204
    /* check PTL1, empty is still true */
-
 
205
    if (PTL1_ENTRIES) {
-
 
206
        for (i = 0; i < PTL1_ENTRIES; i++) {
-
 
207
            if (PTE_VALID(&ptl1[i])) {
-
 
208
                empty = false;
-
 
209
                break;
-
 
210
            }
-
 
211
        }
-
 
212
        if (empty) {
-
 
213
            /*
-
 
214
             * PTL1 is empty.
-
 
215
             * Release the frame and remove PTL1 pointer from preceding table.
-
 
216
             */
-
 
217
            frame_free(ADDR2PFN(KA2PA((__address) ptl1)));
-
 
218
            memsetb((__address) &ptl0[PTL0_INDEX(page)], sizeof(pte_t), 0);
-
 
219
        }
-
 
220
    }
-
 
221
 
134
}
222
}
135
 
223
 
136
/** Find mapping for virtual page in hierarchical page tables.
224
/** Find mapping for virtual page in hierarchical page tables.
137
 *
225
 *
138
 * Find mapping for virtual page.
226
 * Find mapping for virtual page.