Subversion Repositories HelenOS

Rev

Rev 2263 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2263 Rev 2264
1
/*
1
/*
2
 * Copyright (c) 2007 Pavel Jancik, Michal Kebrt
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:
8
 *
8
 *
9
 * - Redistributions of source code must retain the above copyright
9
 * - Redistributions of source code must retain the above copyright
10
 *   notice, this list of conditions and the following disclaimer.
10
 *   notice, this list of conditions and the following disclaimer.
11
 * - Redistributions in binary form must reproduce the above copyright
11
 * - Redistributions in binary form must reproduce the above copyright
12
 *   notice, this list of conditions and the following disclaimer in the
12
 *   notice, this list of conditions and the following disclaimer in the
13
 *   documentation and/or other materials provided with the distribution.
13
 *   documentation and/or other materials provided with the distribution.
14
 * - The name of the author may not be used to endorse or promote products
14
 * - The name of the author may not be used to endorse or promote products
15
 *   derived from this software without specific prior written permission.
15
 *   derived from this software without specific prior written permission.
16
 *
16
 *
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
27
 */
28
 
28
 
29
/** @addtogroup arm32mm
29
/** @addtogroup arm32mm
30
 * @{
30
 * @{
31
 */
31
 */
32
/** @file
32
/** @file
33
 */
33
 */
34
 
34
 
35
#include <arch/mm/page.h>
35
#include <arch/mm/page.h>
36
#include <genarch/mm/page_pt.h>
36
#include <genarch/mm/page_pt.h>
37
#include <arch.h>
37
#include <arch.h>
38
#include <mm/page.h>
38
#include <mm/page.h>
39
#include <align.h>
39
#include <align.h>
40
#include <config.h>
40
#include <config.h>
41
#include <arch/exception.h>
41
#include <arch/exception.h>
42
#include <typedefs.h>
42
#include <typedefs.h>
43
#include <arch/types.h>
43
#include <arch/types.h>
44
#include <interrupt.h>
44
#include <interrupt.h>
45
 
-
 
46
//TODO: remove in final version
-
 
47
#include "../aux_print/printf.h"
45
#include <arch/debug_print/print.h>
48
 
46
 
49
 
47
 
50
// localy used types
48
// localy used types
51
/**
49
/**
52
 * Decribes structure of fault status register in coprocessor 15
50
 * Decribes structure of fault status register in coprocessor 15
53
 */
51
 */
54
typedef struct {
52
typedef struct {
55
        unsigned status              : 3;
53
        unsigned status              : 3;
56
        unsigned domain              : 4;
54
        unsigned domain              : 4;
57
        unsigned zero            : 1;
55
        unsigned zero            : 1;
58
        unsigned should_be_zero      : 24;
56
        unsigned should_be_zero      : 24;
59
} __attribute__ ((packed)) fault_status_t;
57
} __attribute__ ((packed)) fault_status_t;
60
 
58
 
61
/**
59
/**
62
 * Help union used for overcasting integer value into fault_status_t type
60
 * Help union used for overcasting integer value into fault_status_t type
63
 */
61
 */
64
typedef union {
62
typedef union {
65
    fault_status_t  fsr;
63
    fault_status_t  fsr;
66
    uint32_t    dummy;
64
    uint32_t    dummy;
67
} fault_status_union_t;
65
} fault_status_union_t;
68
 
66
 
69
/**
67
/**
70
 * Very simplyfied description of instruction code structure intended for
68
 * Very simplyfied description of instruction code structure intended for
71
 * recognising memmory access of instruction ( reads or writes into memmory)
69
 * recognising memmory access of instruction ( reads or writes into memmory)
72
 * more details: see ARM architecture preference chapter:3.1 Instruction set encoding
70
 * more details: see ARM architecture preference chapter:3.1 Instruction set encoding
73
 */
71
 */
74
typedef struct {
72
typedef struct {
75
        unsigned dummy1              : 4;
73
        unsigned dummy1              : 4;
76
        unsigned bit4                : 1;
74
        unsigned bit4                : 1;
77
        unsigned bits567             : 3;
75
        unsigned bits567             : 3;
78
        unsigned dummy               : 12;
76
        unsigned dummy               : 12;
79
        unsigned access              : 1;
77
        unsigned access              : 1;
80
        unsigned opcode              : 4;
78
        unsigned opcode              : 4;
81
        unsigned instr_type          : 3;
79
        unsigned instr_type          : 3;
82
        unsigned condition       : 4;
80
        unsigned condition       : 4;
83
} __attribute__ ((packed)) instruction_t;
81
} __attribute__ ((packed)) instruction_t;
84
 
82
 
85
/**
83
/**
86
 *  Help union used for overcasting ip register (uint_32_t) value into instruction_t pointer
84
 *  Help union used for overcasting ip register (uint_32_t) value into instruction_t pointer
87
 */
85
 */
88
typedef union {
86
typedef union {
89
    instruction_t*  instr;
87
    instruction_t*  instr;
90
    uint32_t    ip;
88
    uint32_t    ip;
91
} instruction_union_t;
89
} instruction_union_t;
92
 
90
 
93
// localy used functions
91
// localy used functions
94
static fault_status_t read_fault_status_register();
92
static fault_status_t read_fault_status_register();
95
static uintptr_t read_fault_address_register();
93
static uintptr_t read_fault_address_register();
96
static pf_access_t get_memmory_access_type(uint32_t instr_addr, uintptr_t badvaddr);
94
static pf_access_t get_memmory_access_type(uint32_t instr_addr, uintptr_t badvaddr);
97
 
95
 
98
 
96
 
99
/**
97
/**
100
 * Initializes kernel adress space page tables, sets abourts exceptions vectors
98
 * Initializes kernel adress space page tables, sets abourts exceptions vectors
101
 */
99
 */
102
void page_arch_init(void)
100
void page_arch_init(void)
103
{
101
{
104
    uintptr_t cur;
102
    uintptr_t cur;
105
    int flags;
103
    int flags;
106
 
104
 
107
    page_mapping_operations = &pt_mapping_operations;
105
    page_mapping_operations = &pt_mapping_operations;
108
 
106
 
109
    flags = PAGE_CACHEABLE;
107
    flags = PAGE_CACHEABLE;
110
 
108
 
111
    /* PA2KA(identity) mapping for all frames until last_frame */
109
    /* PA2KA(identity) mapping for all frames until last_frame */
112
    for (cur = 0; cur < last_frame; cur += FRAME_SIZE) {
110
    for (cur = 0; cur < last_frame; cur += FRAME_SIZE) {
113
        page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags);
111
        page_mapping_insert(AS_KERNEL, PA2KA(cur), cur, flags);
114
    }
112
    }
115
 
113
 
116
    // TODO: move to the kernel space
114
    // TODO: move to the kernel space
117
    page_mapping_insert(AS_KERNEL, 0x00000000, 0x00000000, flags);
115
    page_mapping_insert(AS_KERNEL, 0x00000000, 0x00000000, flags);
118
    // TODO: remove when aux_printf not needed
116
    // TODO: remove when aux_printf not needed
119
    page_mapping_insert(AS_KERNEL, 0x10000000, 0x10000000, flags);
117
    page_mapping_insert(AS_KERNEL, 0x10000000, 0x10000000, flags);
120
 
118
 
121
    exc_register(EXC_DATA_ABORT,     "page_fault data abort",     (iroutine) data_abourt);
119
    exc_register(EXC_DATA_ABORT,     "page_fault data abort",     (iroutine) data_abourt);
122
    exc_register(EXC_PREFETCH_ABORT, "page_fault prefetch abort", (iroutine) prefetch_abourt);
120
    exc_register(EXC_PREFETCH_ABORT, "page_fault prefetch abort", (iroutine) prefetch_abourt);
123
 
121
 
124
    as_switch(NULL, AS_KERNEL);
122
    as_switch(NULL, AS_KERNEL);
125
 
123
 
126
    // TODO: register fault routine
124
    // TODO: register fault routine
127
}
125
}
128
 
126
 
129
/**
127
/**
130
 * Map device into kernel space.
128
 * Map device into kernel space.
131
 *
129
 *
132
 * This function adds mapping of physical address that is read/write only
130
 * This function adds mapping of physical address that is read/write only
133
 *  from kernel and not bufferable.
131
 *  from kernel and not bufferable.
134
 *
132
 *
135
 * \param physaddr Physical addres where device is connected
133
 * \param physaddr Physical addres where device is connected
136
 * \param size Length of area where device is present
134
 * \param size Length of area where device is present
137
 * \return Virtual address where device will be accessable
135
 * \return Virtual address where device will be accessable
138
 * Note: This is copy of IA32 hw_map code
136
 * Note: This is copy of IA32 hw_map code
139
 */
137
 */
140
uintptr_t hw_map(uintptr_t physaddr, size_t size)
138
uintptr_t hw_map(uintptr_t physaddr, size_t size)
141
{
139
{
142
    if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
140
    if (last_frame + ALIGN_UP(size, PAGE_SIZE) > KA2PA(KERNEL_ADDRESS_SPACE_END_ARCH))
143
        panic("Unable to map physical memory %p (%d bytes)", physaddr, size)
141
        panic("Unable to map physical memory %p (%d bytes)", physaddr, size)
144
 
142
 
145
    uintptr_t virtaddr = PA2KA(last_frame);
143
    uintptr_t virtaddr = PA2KA(last_frame);
146
    pfn_t i;
144
    pfn_t i;
147
    for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++)
145
    for (i = 0; i < ADDR2PFN(ALIGN_UP(size, PAGE_SIZE)); i++)
148
        page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE | PAGE_READ | PAGE_WRITE | PAGE_KERNEL);
146
        page_mapping_insert(AS_KERNEL, virtaddr + PFN2ADDR(i), physaddr + PFN2ADDR(i), PAGE_NOT_CACHEABLE | PAGE_READ | PAGE_WRITE | PAGE_KERNEL);
149
 
147
 
150
    last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
148
    last_frame = ALIGN_UP(last_frame + size, FRAME_SIZE);
151
 
149
 
152
    return virtaddr;
150
    return virtaddr;
153
}
151
}
154
 
152
 
155
//TODO: remove in final version
153
//TODO: remove in final version
156
static void print_istate(istate_t* istate);
154
static void print_istate(istate_t* istate);
157
static void print_istate(istate_t* istate) {
155
static void print_istate(istate_t* istate) {
158
 aux_printf("\nIstate dump:\n");
156
 dprintf("\nIstate dump:\n");
159
 aux_printf("    r0:%X    r1:%X    r2:%X    r3:%X\n", istate->r0,  istate->r1, istate->r2,  istate->r3);
157
 dprintf("    r0:%X    r1:%X    r2:%X    r3:%X\n", istate->r0,  istate->r1, istate->r2,  istate->r3);
160
 aux_printf("    r4:%X    r5:%X    r6:%X    r7:%X\n", istate->r4,  istate->r5, istate->r6,  istate->r7);
158
 dprintf("    r4:%X    r5:%X    r6:%X    r7:%X\n", istate->r4,  istate->r5, istate->r6,  istate->r7);
161
 aux_printf("    r8:%X    r8:%X   r10:%X   r11:%X\n", istate->r8,  istate->r9, istate->r10, istate->r11);
159
 dprintf("    r8:%X    r8:%X   r10:%X   r11:%X\n", istate->r8,  istate->r9, istate->r10, istate->r11);
162
 aux_printf("   r12:%X    sp:%X    lr:%X  spsr:%X\n", istate->r12, istate->sp, istate->lr,  istate->spsr);
160
 dprintf("   r12:%X    sp:%X    lr:%X  spsr:%X\n", istate->r12, istate->sp, istate->lr,  istate->spsr);
163
}
161
}
164
 
162
 
165
/**
163
/**
166
 * \return Value stored in fault status register
164
 * \return Value stored in fault status register
167
 */
165
 */
168
static fault_status_t read_fault_status_register() {
166
static fault_status_t read_fault_status_register() {
169
        fault_status_union_t tmp;
167
        fault_status_union_t tmp;
170
        asm volatile (
168
        asm volatile (
171
        "mrc p15, 0, %0, c5, c0, 0"
169
        "mrc p15, 0, %0, c5, c0, 0"
172
            : "=r"(tmp.dummy)
170
            : "=r"(tmp.dummy)
173
    );
171
    );
174
    return tmp.fsr;
172
    return tmp.fsr;
175
}
173
}
176
 
174
 
177
/**
175
/**
178
 * \return Virtual adress. Access on this addres caused exception
176
 * \return Virtual adress. Access on this addres caused exception
179
 */
177
 */
180
static uintptr_t read_fault_address_register() {
178
static uintptr_t read_fault_address_register() {
181
        uintptr_t tmp;
179
        uintptr_t tmp;
182
    // Fault adress is stored in coprocessor15, register 6
180
    // Fault adress is stored in coprocessor15, register 6
183
    asm volatile (
181
    asm volatile (
184
        "mrc p15, 0, %0, c6, c0, 0"
182
        "mrc p15, 0, %0, c6, c0, 0"
185
        : "=r"(tmp)
183
        : "=r"(tmp)
186
    );
184
    );
187
    return tmp;
185
    return tmp;
188
};
186
};
189
 
187
 
190
/**
188
/**
191
 * Decode instruction and decide if try to read or write into memmory.
189
 * Decode instruction and decide if try to read or write into memmory.
192
 *
190
 *
193
 * \param instr_addr address of instruction which attempts to access into memmory
191
 * \param instr_addr address of instruction which attempts to access into memmory
194
 * \param badvaddr Virtual address on which instruction tries to access
192
 * \param badvaddr Virtual address on which instruction tries to access
195
 * \return type of access into memmory
193
 * \return type of access into memmory
196
 *  Note: return PF_ACESS_EXEC if no memmory acess
194
 *  Note: return PF_ACESS_EXEC if no memmory acess
197
 */
195
 */
198
//TODO: remove debug print in final version ... instead panic return PF_ACESS_EXEC
196
//TODO: remove debug print in final version ... instead panic return PF_ACESS_EXEC
199
pf_access_t get_memmory_access_type(uint32_t instr_addr, uintptr_t badvaddr) {
197
pf_access_t get_memmory_access_type(uint32_t instr_addr, uintptr_t badvaddr) {
200
        instruction_union_t tmp;
198
        instruction_union_t tmp;
201
        tmp.ip = instr_addr;
199
        tmp.ip = instr_addr;
202
    // get instruction op code
200
    // get instruction op code
203
    instruction_t i_code = *(tmp.instr);
201
    instruction_t i_code = *(tmp.instr);
204
 
202
 
205
        aux_printf("get_instruction_memmory_access\n");
203
        dprintf("get_instruction_memmory_access\n");
206
    aux_printf(" i_code:%X\n",i_code);
204
    dprintf(" i_code:%X\n",i_code);
207
    aux_printf(" i_code.condition:%d\n", i_code.condition);
205
    dprintf(" i_code.condition:%d\n", i_code.condition);
208
    aux_printf(" i_code.instr_type:%d\n",i_code.instr_type);
206
    dprintf(" i_code.instr_type:%d\n",i_code.instr_type);
209
    aux_printf(" i_code.opcode:%d\n",i_code.opcode);
207
    dprintf(" i_code.opcode:%d\n",i_code.opcode);
210
    aux_printf(" i_code.acess:%d\n", i_code.access);
208
    dprintf(" i_code.acess:%d\n", i_code.access);
211
    aux_printf(" i_code.dummy:%d\n", i_code.dummy);
209
    dprintf(" i_code.dummy:%d\n", i_code.dummy);
212
    aux_printf(" i_code.bits567%d\n", i_code.bits567);
210
    dprintf(" i_code.bits567%d\n", i_code.bits567);
213
    aux_printf(" i_code.bit4:%d\n", i_code.bit4);
211
    dprintf(" i_code.bit4:%d\n", i_code.bit4);
214
    aux_printf(" i_code.dummy1:%d\n", i_code.dummy1);
212
    dprintf(" i_code.dummy1:%d\n", i_code.dummy1);
215
 
213
 
216
 
214
 
217
        // undefined instructions ... (or special instructions)
215
        // undefined instructions ... (or special instructions)
218
    if ( i_code.condition == 0xf ) {
216
    if ( i_code.condition == 0xf ) {
219
        panic("page_fault - on instruction not acessing to memmory (instr_code:%X, badvaddr:%X)",i_code, badvaddr);
217
        panic("page_fault - on instruction not acessing to memmory (instr_code:%X, badvaddr:%X)",i_code, badvaddr);
220
        return PF_ACCESS_EXEC;
218
        return PF_ACCESS_EXEC;
221
    }
219
    }
222
 
220
 
223
    // load store instructions
221
    // load store instructions
224
        if ( ( i_code.instr_type == 0x2 ) || // load store immediate offset
222
        if ( ( i_code.instr_type == 0x2 ) || // load store immediate offset
225
             ( i_code.instr_type == 0x3 && i_code.bit4 == 0) || // load store register offset
223
             ( i_code.instr_type == 0x3 && i_code.bit4 == 0) || // load store register offset
226
             ( i_code.instr_type == 0x4 ) || // load store multiple
224
             ( i_code.instr_type == 0x4 ) || // load store multiple
227
         ( i_code.instr_type == 0x6 )    // coprocessor load / strore
225
         ( i_code.instr_type == 0x6 )    // coprocessor load / strore
228
       ) {
226
       ) {
229
        if ( i_code.access == 1) {
227
        if ( i_code.access == 1) {
230
            return PF_ACCESS_READ;
228
            return PF_ACCESS_READ;
231
        } else {
229
        } else {
232
            return PF_ACCESS_WRITE;
230
            return PF_ACCESS_WRITE;
233
        }
231
        }
234
    };
232
    };
235
 
233
 
236
    // swap, swpb instruction
234
    // swap, swpb instruction
237
    if ( i_code.instr_type == 0x0 && (i_code.opcode == 0x8 || i_code.opcode == 0xA) &&
235
    if ( i_code.instr_type == 0x0 && (i_code.opcode == 0x8 || i_code.opcode == 0xA) &&
238
         i_code.access == 0x0 && i_code.bits567 == 0x4 && i_code.bit4 == 1 )
236
         i_code.access == 0x0 && i_code.bits567 == 0x4 && i_code.bit4 == 1 )
239
     {
237
     {
240
        /* Swap instructions make read and write in one step.
238
        /* Swap instructions make read and write in one step.
241
         * Type of access that caused exception have to page tables and access rights.
239
         * Type of access that caused exception have to page tables and access rights.
242
         */
240
         */
243
//TODO: ALF!!!!! cann't use AS as is define as THE->as and THE structure is sored after stack_base of current thread
241
//TODO: ALF!!!!! cann't use AS as is define as THE->as and THE structure is sored after stack_base of current thread
244
//      but now ... in exception we have separate stacks <==> different stack_pointer ... so AS contains nonsence data
242
//      but now ... in exception we have separate stacks <==> different stack_pointer ... so AS contains nonsence data
245
//  same case as_page_fault .... it's nessesary to solve "stack" problem
243
//  same case as_page_fault .... it's nessesary to solve "stack" problem
246
                pte_level1_t* pte = (pte_level1_t*)pt_mapping_operations.mapping_find(AS, badvaddr);
244
                pte_level1_t* pte = (pte_level1_t*)pt_mapping_operations.mapping_find(AS, badvaddr);
247
 
245
 
248
        ASSERT(pte);
246
        ASSERT(pte);
249
 
247
 
250
                /* check if read possible
248
                /* check if read possible
251
                 * Note: Don't check PTE_READABLE because it returns 1 everytimes */
249
                 * Note: Don't check PTE_READABLE because it returns 1 everytimes */
252
        if ( !PTE_PRESENT(pte) ) {
250
        if ( !PTE_PRESENT(pte) ) {
253
                return PF_ACCESS_READ;
251
                return PF_ACCESS_READ;
254
        }
252
        }
255
        if ( !PTE_WRITABLE(pte) ) {
253
        if ( !PTE_WRITABLE(pte) ) {
256
            return PF_ACCESS_WRITE;
254
            return PF_ACCESS_WRITE;
257
        }
255
        }
258
        else
256
        else
259
            // badvaddr is present readable and writeable but error occured ... why?
257
            // badvaddr is present readable and writeable but error occured ... why?
260
            panic("page_fault - swap instruction, but address readable and writeable (instr_code:%X, badvaddr:%X)",i_code, badvaddr);
258
            panic("page_fault - swap instruction, but address readable and writeable (instr_code:%X, badvaddr:%X)",i_code, badvaddr);
261
    }
259
    }
262
    panic("page_fault - on instruction not acessing to memmory (instr_code:%X, badvaddr:%X)",i_code, badvaddr);
260
    panic("page_fault - on instruction not acessing to memmory (instr_code:%X, badvaddr:%X)",i_code, badvaddr);
263
    return PF_ACCESS_EXEC;
261
    return PF_ACCESS_EXEC;
264
}
262
}
265
 
263
 
266
/**
264
/**
267
 * Routine that solves exception data_abourt
265
 * Routine that solves exception data_abourt
268
 *  ... you try to load or store value into invalid memmory address
266
 *  ... you try to load or store value into invalid memmory address
269
 * \param istate State of CPU when data abourt occured
267
 * \param istate State of CPU when data abourt occured
270
 * \param n number of exception
268
 * \param n number of exception
271
 */
269
 */
272
//TODO: remove debug prints in final tested version
270
//TODO: remove debug prints in final tested version
273
void data_abourt(int n, istate_t *istate) {
271
void data_abourt(int n, istate_t *istate) {
274
        fault_status_t fsr = read_fault_status_register();
272
        fault_status_t fsr = read_fault_status_register();
275
        uintptr_t  page = read_fault_address_register();
273
        uintptr_t  page = read_fault_address_register();
276
 
274
 
277
    pf_access_t access = get_memmory_access_type( istate->lr, page);
275
    pf_access_t access = get_memmory_access_type( istate->lr, page);
278
 
276
 
279
    print_istate(istate);
277
    print_istate(istate);
280
    aux_printf(" page fault : ip:%X, va:%X, status:%x(%x), access:%d\n", istate->lr, page, fsr.status,fsr, access);
278
    dprintf(" page fault : ip:%X, va:%X, status:%x(%x), access:%d\n", istate->lr, page, fsr.status,fsr, access);
281
 
279
 
282
        int ret = as_page_fault(page, access, istate);
280
        int ret = as_page_fault(page, access, istate);
283
    aux_printf(" as_page_fault ret:%d\n", ret);
281
    dprintf(" as_page_fault ret:%d\n", ret);
284
        if (ret == AS_PF_FAULT) {
282
        if (ret == AS_PF_FAULT) {
285
        fault_if_from_uspace(istate, "Page fault: %#x", page);
283
        fault_if_from_uspace(istate, "Page fault: %#x", page);
286
 
284
 
287
                panic("page fault\n");
285
                panic("page fault\n");
288
        }
286
        }
289
 
287
 
290
    // TODO: Remove this ... now for testing purposes ... it's bad to test page faults in kernel, where no page faults should occures
288
    // TODO: Remove this ... now for testing purposes ... it's bad to test page faults in kernel, where no page faults should occures
291
    panic("page fault ... solved\n");
289
    panic("page fault ... solved\n");
292
 
290
 
293
}
291
}
294
 
292
 
295
/**
293
/**
296
 * Routine that solves exception prefetch_about
294
 * Routine that solves exception prefetch_about
297
 *  ... you try to execute instruction on invalid address
295
 *  ... you try to execute instruction on invalid address
298
 * \param istate State of CPU when prefetch abourt occured
296
 * \param istate State of CPU when prefetch abourt occured
299
 * \param n number of exception
297
 * \param n number of exception
300
 */
298
 */
301
void prefetch_abourt(int n, istate_t *istate) {
299
void prefetch_abourt(int n, istate_t *istate) {
302
 // Prefetch can be made be bkpt instruction
300
 // Prefetch can be made be bkpt instruction
303
    print_istate(istate);
301
    print_istate(istate);
304
    aux_printf(" prefetch_abourt ... instruction on adress:%x can't be fetched\n", istate->lr);
302
    dprintf(" prefetch_abourt ... instruction on adress:%x can't be fetched\n", istate->lr);
305
 
303
 
306
        int ret = as_page_fault(istate->lr, PF_ACCESS_EXEC, istate);
304
        int ret = as_page_fault(istate->lr, PF_ACCESS_EXEC, istate);
307
    aux_printf(" as_page_fault ret:%d\n", ret);
305
    dprintf(" as_page_fault ret:%d\n", ret);
308
        if (ret == AS_PF_FAULT) {
306
        if (ret == AS_PF_FAULT) {
309
                panic("page fault - instruction fetch at addr:%X\n", istate->lr);
307
                panic("page fault - instruction fetch at addr:%X\n", istate->lr);
310
        }
308
        }
311
 
309
 
312
    panic("Prefetch abourt ... solved");
310
    panic("Prefetch abourt ... solved");
313
}
311
}
314
 
312
 
315
/** @}
313
/** @}
316
 */
314
 */
317
 
315
 
318
 
316