Subversion Repositories HelenOS

Rev

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

Rev 2132 Rev 2134
Line 79... Line 79...
79
    elf_header_t *elf = area->backend_data.elf;
79
    elf_header_t *elf = area->backend_data.elf;
80
    elf_segment_header_t *entry = area->backend_data.segment;
80
    elf_segment_header_t *entry = area->backend_data.segment;
81
    btree_node_t *leaf;
81
    btree_node_t *leaf;
82
    uintptr_t base, frame;
82
    uintptr_t base, frame;
83
    index_t i;
83
    index_t i;
-
 
84
    bool dirty = false;
84
 
85
 
85
    if (!as_area_check_access(area, access))
86
    if (!as_area_check_access(area, access))
86
        return AS_PF_FAULT;
87
        return AS_PF_FAULT;
87
 
88
 
88
    ASSERT((addr >= entry->p_vaddr) &&
89
    ASSERT((addr >= entry->p_vaddr) &&
Line 145... Line 146...
145
         */
146
         */
146
        if (entry->p_flags & PF_W) {
147
        if (entry->p_flags & PF_W) {
147
            frame = (uintptr_t)frame_alloc(ONE_FRAME, 0);
148
            frame = (uintptr_t)frame_alloc(ONE_FRAME, 0);
148
            memcpy((void *) PA2KA(frame),
149
            memcpy((void *) PA2KA(frame),
149
                (void *) (base + i * FRAME_SIZE), FRAME_SIZE);
150
                (void *) (base + i * FRAME_SIZE), FRAME_SIZE);
-
 
151
            dirty = true;
150
           
152
 
151
            if (area->sh_info) {
153
            if (area->sh_info) {
152
                frame_reference_add(ADDR2PFN(frame));
154
                frame_reference_add(ADDR2PFN(frame));
153
                btree_insert(&area->sh_info->pagemap,
155
                btree_insert(&area->sh_info->pagemap,
154
                    ALIGN_DOWN(addr, PAGE_SIZE) - area->base,
156
                    ALIGN_DOWN(addr, PAGE_SIZE) - area->base,
155
                    (void *) frame, leaf);
157
                    (void *) frame, leaf);
Line 166... Line 168...
166
         * To resolve the situation, a frame must be allocated
168
         * To resolve the situation, a frame must be allocated
167
         * and cleared.
169
         * and cleared.
168
         */
170
         */
169
        frame = (uintptr_t)frame_alloc(ONE_FRAME, 0);
171
        frame = (uintptr_t)frame_alloc(ONE_FRAME, 0);
170
        memsetb(PA2KA(frame), FRAME_SIZE, 0);
172
        memsetb(PA2KA(frame), FRAME_SIZE, 0);
-
 
173
        dirty = true;
171
 
174
 
172
        if (area->sh_info) {
175
        if (area->sh_info) {
173
            frame_reference_add(ADDR2PFN(frame));
176
            frame_reference_add(ADDR2PFN(frame));
174
            btree_insert(&area->sh_info->pagemap,
177
            btree_insert(&area->sh_info->pagemap,
175
                ALIGN_DOWN(addr, PAGE_SIZE) - area->base,
178
                ALIGN_DOWN(addr, PAGE_SIZE) - area->base,
Line 186... Line 189...
186
        size = entry->p_filesz - (i<<PAGE_WIDTH);
189
        size = entry->p_filesz - (i<<PAGE_WIDTH);
187
        frame = (uintptr_t)frame_alloc(ONE_FRAME, 0);
190
        frame = (uintptr_t)frame_alloc(ONE_FRAME, 0);
188
        memsetb(PA2KA(frame) + size, FRAME_SIZE - size, 0);
191
        memsetb(PA2KA(frame) + size, FRAME_SIZE - size, 0);
189
        memcpy((void *) PA2KA(frame), (void *) (base + i * FRAME_SIZE),
192
        memcpy((void *) PA2KA(frame), (void *) (base + i * FRAME_SIZE),
190
            size);
193
            size);
-
 
194
        dirty = true;
191
 
195
 
192
        if (area->sh_info) {
196
        if (area->sh_info) {
193
            frame_reference_add(ADDR2PFN(frame));
197
            frame_reference_add(ADDR2PFN(frame));
194
            btree_insert(&area->sh_info->pagemap,
198
            btree_insert(&area->sh_info->pagemap,
195
                ALIGN_DOWN(addr, PAGE_SIZE) - area->base,
199
                ALIGN_DOWN(addr, PAGE_SIZE) - area->base,
Line 203... Line 207...
203
   
207
   
204
    page_mapping_insert(AS, addr, frame, as_area_get_flags(area));
208
    page_mapping_insert(AS, addr, frame, as_area_get_flags(area));
205
    if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1))
209
    if (!used_space_insert(area, ALIGN_DOWN(addr, PAGE_SIZE), 1))
206
        panic("Could not insert used space.\n");
210
        panic("Could not insert used space.\n");
207
 
211
 
-
 
212
#ifdef CONFIG_VIRT_IDX_DCACHE
-
 
213
    if (dirty && PAGE_COLOR(PA2KA(frame)) != PAGE_COLOR(addr)) {
-
 
214
        /*
-
 
215
         * By writing to the frame using kernel virtual address,
-
 
216
         * we have created an illegal virtual alias. We now have to
-
 
217
         * invalidate cachelines belonging to addr on all processors
-
 
218
         * so that they will be reloaded with the new content on next
-
 
219
         * read.
-
 
220
         */
-
 
221
        dcache_flush_frame(addr, frame);
-
 
222
        dcache_shootdown_start(DCACHE_INVL_FRAME, PAGE_COLOR(addr), frame);
-
 
223
        dcache_shootdown_finalize();
-
 
224
    }
-
 
225
#endif
-
 
226
 
208
    return AS_PF_OK;
227
    return AS_PF_OK;
209
}
228
}
210
 
229
 
211
/** Free a frame that is backed by the ELF backend.
230
/** Free a frame that is backed by the ELF backend.
212
 *
231
 *
Line 236... Line 255...
236
            /*
255
            /*
237
             * Free the frame with the copy of writable segment
256
             * Free the frame with the copy of writable segment
238
             * data.
257
             * data.
239
             */
258
             */
240
            frame_free(frame);
259
            frame_free(frame);
241
#ifdef CONFIG_VIRT_IDX_DCACHE
-
 
242
                dcache_flush_frame(page, frame);
-
 
243
#endif
-
 
244
        }
260
        }
245
    } else {
261
    } else {
246
        /*
262
        /*
247
         * The frame is either anonymous memory or the mixed case (i.e.
263
         * The frame is either anonymous memory or the mixed case (i.e.
248
         * lower part is backed by the ELF image and the upper is
264
         * lower part is backed by the ELF image and the upper is
249
         * anonymous). In any case, a frame needs to be freed.
265
         * anonymous). In any case, a frame needs to be freed.
250
         */
266
         */
251
        frame_free(frame);
267
        frame_free(frame);
252
#ifdef CONFIG_VIRT_IDX_DCACHE
-
 
253
            dcache_flush_frame(page, frame);
-
 
254
#endif
-
 
255
    }
268
    }
256
}
269
}
257
 
270
 
258
/** Share ELF image backed address space area.
271
/** Share ELF image backed address space area.
259
 *
272
 *