Changeset ecd1a0a in mainline
- Timestamp:
- 2012-09-04T10:09:41Z (12 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- cc250b3
- Parents:
- c5b69a5e
- Location:
- kernel/arch/arm32
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/arm32/include/mm/page_fault.h
rc5b69a5e recd1a0a 40 40 41 41 42 /** Decribes CP15 "fault status register" (FSR). */ 43 typedef struct { 44 unsigned status : 3; 45 unsigned domain : 4; 46 unsigned zero : 1; 47 unsigned should_be_zero : 24; 48 } ATTRIBUTE_PACKED fault_status_t; 49 50 51 /** Help union used for casting integer value into #fault_status_t. */ 42 /** Decribes CP15 "fault status register" (FSR). 43 * 44 * See ARM Architecture Reference Manual ch. B4.9.6 (pdf p.743). 45 */ 52 46 typedef union { 53 fault_status_t fs; 54 uint32_t dummy; 55 } fault_status_union_t; 47 struct { 48 unsigned status : 4; 49 unsigned domain : 4; 50 unsigned zero : 1; 51 unsigned sbz0 : 1; 52 unsigned fs : 1; /**< armv6+ mandated, earlier IPLM. DEFINED */ 53 unsigned wr : 1; /**< armv6+ only */ 54 unsigned should_be_zero : 20; 55 } ATTRIBUTE_PACKED data; 56 struct { 57 unsigned status : 4; 58 unsigned sbz0 : 6; 59 unsigned fs : 1; 60 unsigned should_be_zero : 21; 61 } ATTRIBUTE_PACKED inst; 62 uint32_t raw; 63 } fault_status_t; 56 64 57 65 -
kernel/arch/arm32/src/mm/page_fault.c
rc5b69a5e recd1a0a 42 42 #include <print.h> 43 43 44 /** Returns value stored in fault status register.44 /** Returns value stored in comnbined/data fault status register. 45 45 * 46 46 * @return Value stored in CP15 fault status register (FSR). 47 */ 48 static inline fault_status_t read_fault_status_register(void) 49 { 50 fault_status_union_t fsu; 51 52 /* fault status is stored in CP15 register 5 */ 47 * 48 * "VMSAv6 added a fifth fault status bit (bit[10]) to both the IFSR and DFSR. 49 * It is IMPLEMENTATION DEFINED how this bit is encoded in earlier versions of 50 * the architecture. A write flag (bit[11] of the DFSR) has also been 51 * introduced." 52 * ARM Architecture Reference Manual version i ch. B4.6 (PDF p. 719) 53 * 54 * See ch. B4.9.6 for location of data/instruction FSR. 55 * 56 */ 57 static inline fault_status_t read_data_fault_status_register(void) 58 { 59 fault_status_t fsu; 60 61 /* Combined/Data fault status is stored in CP15 register 5, c0. */ 53 62 asm volatile ( 54 63 "mrc p15, 0, %[dummy], c5, c0, 0" 55 : [dummy] "=r" (fsu. dummy)64 : [dummy] "=r" (fsu.raw) 56 65 ); 57 66 58 return fsu.fs; 59 } 60 61 /** Returns FAR (fault address register) content. 62 * 63 * @return FAR (fault address register) content (address that caused a page 67 return fsu; 68 } 69 70 /** Returns DFAR (fault address register) content. 71 * 72 * This register is equivalent to FAR on pre armv6 machines. 73 * 74 * @return DFAR (fault address register) content (address that caused a page 64 75 * fault) 65 76 */ 66 static inline uintptr_t read_ fault_address_register(void)77 static inline uintptr_t read_data_fault_address_register(void) 67 78 { 68 79 uintptr_t ret; … … 122 133 } 123 134 135 #if defined(PROCESSOR_armv4) | defined(PROCESSOR_armv5) 124 136 /** Decides whether read or write into memory is requested. 125 137 * … … 166 178 return PF_ACCESS_EXEC; 167 179 } 180 #endif 168 181 169 182 /** Handles "data abort" exception (load or store at invalid address). … … 175 188 void data_abort(unsigned int exc_no, istate_t *istate) 176 189 { 177 fault_status_t fsr __attribute__ ((unused)) = 178 read_fault_status_register(); 179 uintptr_t badvaddr = read_fault_address_register(); 180 181 pf_access_t access = get_memory_access_type(istate->pc, badvaddr); 182 190 uintptr_t badvaddr = read_data_fault_address_register(); 191 192 #if defined(PROCESSOR_armv6) | defined(PROCESSOR_armv7_a) 193 fault_status_t fsr = read_data_fault_status_register(); 194 const pf_access_t access = 195 fsr.data.wr ? PF_ACCESS_WRITE : PF_ACCESS_READ; 196 #elif defined(PROCESSOR_armv4) | defined(PROCESSOR_armv5) 197 const pf_access_t access = get_memory_access_type(istate->pc, badvaddr); 198 #else 199 #error "Unsupported architecture" 200 #endif 183 201 int ret = as_page_fault(badvaddr, access, istate); 184 202 … … 197 215 void prefetch_abort(unsigned int exc_no, istate_t *istate) 198 216 { 217 /* NOTE: We should use IFAR and IFSR here. */ 199 218 int ret = as_page_fault(istate->pc, PF_ACCESS_EXEC, istate); 200 219
Note:
See TracChangeset
for help on using the changeset viewer.