Changeset ad4b32c in mainline
- Timestamp:
- 2009-09-04T21:50:59Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 309ede1
- Parents:
- 7e266ff (diff), 40240b1 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 2 added
- 20 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/arm32/include/elf.h
r7e266ff rad4b32c 27 27 */ 28 28 29 /** @addtogroup arm32 29 /** @addtogroup arm32 30 30 * @{ 31 31 */ … … 37 37 #define KERN_arm32_ELF_H_ 38 38 39 #define ELF_MACHINEEM_ARM39 #define ELF_MACHINE EM_ARM 40 40 41 #ifdef BIG_ENDIAN42 #define ELF_DATA_ENCODINGELFDATA2MSB41 #ifdef __BE__ 42 #define ELF_DATA_ENCODING ELFDATA2MSB 43 43 #else 44 #define ELF_DATA_ENCODINGELFDATA2LSB44 #define ELF_DATA_ENCODING ELFDATA2LSB 45 45 #endif 46 46 47 #define ELF_CLASS 47 #define ELF_CLASS ELFCLASS32 48 48 49 49 #endif -
kernel/arch/ia64/include/asm.h
r7e266ff rad4b32c 27 27 */ 28 28 29 /** @addtogroup ia64 29 /** @addtogroup ia64 30 30 * @{ 31 31 */ … … 41 41 #include <arch/register.h> 42 42 43 #define IA64_IOSPACE_ADDRESS 0xE001000000000000ULL43 #define IA64_IOSPACE_ADDRESS 0xE001000000000000ULL 44 44 45 45 static inline void pio_write_8(ioport8_t *port, uint8_t v) 46 46 { 47 47 uintptr_t prt = (uintptr_t) port; 48 49 *((ioport8_t *) (IA64_IOSPACE_ADDRESS +48 49 *((ioport8_t *) (IA64_IOSPACE_ADDRESS + 50 50 ((prt & 0xfff) | ((prt >> 2) << 12)))) = v; 51 52 asm volatile ("mf\n" ::: "memory"); 51 52 asm volatile ( 53 "mf\n" 54 ::: "memory" 55 ); 53 56 } 54 57 … … 56 59 { 57 60 uintptr_t prt = (uintptr_t) port; 58 59 *((ioport16_t *) (IA64_IOSPACE_ADDRESS +61 62 *((ioport16_t *) (IA64_IOSPACE_ADDRESS + 60 63 ((prt & 0xfff) | ((prt >> 2) << 12)))) = v; 61 62 asm volatile ("mf\n" ::: "memory"); 64 65 asm volatile ( 66 "mf\n" 67 ::: "memory" 68 ); 63 69 } 64 70 … … 66 72 { 67 73 uintptr_t prt = (uintptr_t) port; 68 69 *((ioport32_t *) (IA64_IOSPACE_ADDRESS +74 75 *((ioport32_t *) (IA64_IOSPACE_ADDRESS + 70 76 ((prt & 0xfff) | ((prt >> 2) << 12)))) = v; 71 72 asm volatile ("mf\n" ::: "memory"); 77 78 asm volatile ( 79 "mf\n" 80 ::: "memory" 81 ); 73 82 } 74 83 … … 76 85 { 77 86 uintptr_t prt = (uintptr_t) port; 78 79 asm volatile ("mf\n" ::: "memory"); 80 81 return *((ioport8_t *)(IA64_IOSPACE_ADDRESS + 87 88 asm volatile ( 89 "mf\n" 90 ::: "memory" 91 ); 92 93 return *((ioport8_t *) (IA64_IOSPACE_ADDRESS + 82 94 ((prt & 0xfff) | ((prt >> 2) << 12)))); 83 95 } … … 86 98 { 87 99 uintptr_t prt = (uintptr_t) port; 88 89 asm volatile ("mf\n" ::: "memory"); 90 91 return *((ioport16_t *)(IA64_IOSPACE_ADDRESS + 100 101 asm volatile ( 102 "mf\n" 103 ::: "memory" 104 ); 105 106 return *((ioport16_t *) (IA64_IOSPACE_ADDRESS + 92 107 ((prt & 0xfff) | ((prt >> 2) << 12)))); 93 108 } … … 96 111 { 97 112 uintptr_t prt = (uintptr_t) port; 98 99 asm volatile ("mf\n" ::: "memory"); 100 101 return *((ioport32_t *)(IA64_IOSPACE_ADDRESS + 113 114 asm volatile ( 115 "mf\n" 116 ::: "memory" 117 ); 118 119 return *((ioport32_t *) (IA64_IOSPACE_ADDRESS + 102 120 ((prt & 0xfff) | ((prt >> 2) << 12)))); 103 121 } … … 112 130 { 113 131 uint64_t v; 114 115 //I'm not sure why but this code bad inlines in scheduler, 116 //so THE shifts about 16B and causes kernel panic 117 //asm volatile ("and %0 = %1, r12" : "=r" (v) : "r" (~(STACK_SIZE-1))); 118 //return v; 119 120 //this code have the same meaning but inlines well 121 asm volatile ("mov %0 = r12" : "=r" (v) ); 122 return v & (~(STACK_SIZE-1)); 132 133 /* I'm not sure why but this code bad inlines in scheduler, 134 so THE shifts about 16B and causes kernel panic 135 136 asm volatile ( 137 "and %[value] = %[mask], r12" 138 : [value] "=r" (v) 139 : [mask] "r" (~(STACK_SIZE - 1)) 140 ); 141 return v; 142 143 This code have the same meaning but inlines well. 144 */ 145 146 asm volatile ( 147 "mov %[value] = r12" 148 : [value] "=r" (v) 149 ); 150 151 return (v & (~(STACK_SIZE - 1))); 123 152 } 124 153 … … 131 160 uint64_t v; 132 161 133 asm volatile ("mov %0 = psr\n" : "=r" (v)); 162 asm volatile ( 163 "mov %[value] = psr\n" 164 : [value] "=r" (v) 165 ); 134 166 135 167 return v; … … 144 176 uint64_t v; 145 177 146 asm volatile ("mov %0 = cr.iva\n" : "=r" (v)); 178 asm volatile ( 179 "mov %[value] = cr.iva\n" 180 : [value] "=r" (v) 181 ); 147 182 148 183 return v; … … 155 190 static inline void iva_write(uint64_t v) 156 191 { 157 asm volatile ("mov cr.iva = %0\n" : : "r" (v)); 192 asm volatile ( 193 "mov cr.iva = %[value]\n" 194 :: [value] "r" (v) 195 ); 158 196 } 159 197 … … 167 205 uint64_t v; 168 206 169 asm volatile ("mov %0 = cr.ivr\n" : "=r" (v)); 207 asm volatile ( 208 "mov %[value] = cr.ivr\n" 209 : [value] "=r" (v) 210 ); 170 211 171 212 return v; … … 176 217 uint64_t v; 177 218 178 asm volatile ("mov %0 = cr64\n" : "=r" (v)); 219 asm volatile ( 220 "mov %[value] = cr64\n" 221 : [value] "=r" (v) 222 ); 179 223 180 224 return v; … … 188 232 static inline void itc_write(uint64_t v) 189 233 { 190 asm volatile ("mov ar.itc = %0\n" : : "r" (v)); 234 asm volatile ( 235 "mov ar.itc = %[value]\n" 236 :: [value] "r" (v) 237 ); 191 238 } 192 239 … … 199 246 uint64_t v; 200 247 201 asm volatile ("mov %0 = ar.itc\n" : "=r" (v)); 248 asm volatile ( 249 "mov %[value] = ar.itc\n" 250 : [value] "=r" (v) 251 ); 202 252 203 253 return v; … … 210 260 static inline void itm_write(uint64_t v) 211 261 { 212 asm volatile ("mov cr.itm = %0\n" : : "r" (v)); 262 asm volatile ( 263 "mov cr.itm = %[value]\n" 264 :: [value] "r" (v) 265 ); 213 266 } 214 267 … … 221 274 uint64_t v; 222 275 223 asm volatile ("mov %0 = cr.itm\n" : "=r" (v)); 276 asm volatile ( 277 "mov %[value] = cr.itm\n" 278 : [value] "=r" (v) 279 ); 224 280 225 281 return v; … … 234 290 uint64_t v; 235 291 236 asm volatile ("mov %0 = cr.itv\n" : "=r" (v)); 292 asm volatile ( 293 "mov %[value] = cr.itv\n" 294 : [value] "=r" (v) 295 ); 237 296 238 297 return v; … … 245 304 static inline void itv_write(uint64_t v) 246 305 { 247 asm volatile ("mov cr.itv = %0\n" : : "r" (v)); 306 asm volatile ( 307 "mov cr.itv = %[value]\n" 308 :: [value] "r" (v) 309 ); 248 310 } 249 311 … … 254 316 static inline void eoi_write(uint64_t v) 255 317 { 256 asm volatile ("mov cr.eoi = %0\n" : : "r" (v)); 318 asm volatile ( 319 "mov cr.eoi = %[value]\n" 320 :: [value] "r" (v) 321 ); 257 322 } 258 323 … … 264 329 { 265 330 uint64_t v; 266 267 asm volatile ("mov %0 = cr.tpr\n" : "=r" (v)); 331 332 asm volatile ( 333 "mov %[value] = cr.tpr\n" 334 : [value] "=r" (v) 335 ); 268 336 269 337 return v; … … 276 344 static inline void tpr_write(uint64_t v) 277 345 { 278 asm volatile ("mov cr.tpr = %0\n" : : "r" (v)); 346 asm volatile ( 347 "mov cr.tpr = %[value]\n" 348 :: [value] "r" (v) 349 ); 279 350 } 280 351 … … 291 362 292 363 asm volatile ( 293 "mov % 0= psr\n"294 "rsm % 1\n"295 : "=r" (v)296 : "i" (PSR_I_MASK)364 "mov %[value] = psr\n" 365 "rsm %[mask]\n" 366 : [value] "=r" (v) 367 : [mask] "i" (PSR_I_MASK) 297 368 ); 298 369 … … 312 383 313 384 asm volatile ( 314 "mov % 0= psr\n"315 "ssm % 1\n"385 "mov %[value] = psr\n" 386 "ssm %[mask]\n" 316 387 ";;\n" 317 388 "srlz.d\n" 318 : "=r" (v)319 : "i" (PSR_I_MASK)389 : [value] "=r" (v) 390 : [mask] "i" (PSR_I_MASK) 320 391 ); 321 392 … … 349 420 static inline void pk_disable(void) 350 421 { 351 asm volatile ("rsm %0\n" : : "i" (PSR_PK_MASK)); 422 asm volatile ( 423 "rsm %[mask]\n" 424 :: [mask] "i" (PSR_PK_MASK) 425 ); 352 426 } 353 427 -
kernel/arch/ia64/include/atomic.h
r7e266ff rad4b32c 27 27 */ 28 28 29 /** @addtogroup ia64 29 /** @addtogroup ia64 30 30 * @{ 31 31 */ … … 36 36 #define KERN_ia64_ATOMIC_H_ 37 37 38 /** Atomic addition.39 *40 * @param val Atomic value.41 * @param imm Value to add.42 *43 * @return Value before addition.44 */45 static inline long atomic_add(atomic_t *val, int imm)46 {47 long v;48 49 asm volatile ("fetchadd8.rel %0 = %1, %2\n" : "=r" (v),50 "+m" (val->count) : "i" (imm));51 52 return v;53 }54 55 38 static inline uint64_t test_and_set(atomic_t *val) 56 39 { … … 58 41 59 42 asm volatile ( 60 "movl %0 = 0x1;;\n" 61 "xchg8 %0 = %1, %0;;\n" 62 : "=r" (v), "+m" (val->count) 43 "movl %[v] = 0x1;;\n" 44 "xchg8 %[v] = %[count], %[v];;\n" 45 : [v] "=r" (v), 46 [count] "+m" (val->count) 63 47 ); 64 48 … … 76 60 static inline void atomic_inc(atomic_t *val) 77 61 { 78 atomic_add(val, 1); 62 long v; 63 64 asm volatile ( 65 "fetchadd8.rel %[v] = %[count], 1\n" 66 : [v] "=r" (v), 67 [count] "+m" (val->count) 68 ); 79 69 } 80 70 81 71 static inline void atomic_dec(atomic_t *val) 82 72 { 83 atomic_add(val, -1); 73 long v; 74 75 asm volatile ( 76 "fetchadd8.rel %[v] = %[count], -1\n" 77 : [v] "=r" (v), 78 [count] "+m" (val->count) 79 ); 84 80 } 85 81 86 82 static inline long atomic_preinc(atomic_t *val) 87 83 { 88 return atomic_add(val, 1) + 1; 84 long v; 85 86 asm volatile ( 87 "fetchadd8.rel %[v] = %[count], 1\n" 88 : [v] "=r" (v), 89 [count] "+m" (val->count) 90 ); 91 92 return (v + 1); 89 93 } 90 94 91 95 static inline long atomic_predec(atomic_t *val) 92 96 { 93 return atomic_add(val, -1) - 1; 97 long v; 98 99 asm volatile ( 100 "fetchadd8.rel %[v] = %[count], -1\n" 101 : [v] "=r" (v), 102 [count] "+m" (val->count) 103 ); 104 105 return (v - 1); 94 106 } 95 107 96 108 static inline long atomic_postinc(atomic_t *val) 97 109 { 98 return atomic_add(val, 1); 110 long v; 111 112 asm volatile ( 113 "fetchadd8.rel %[v] = %[count], 1\n" 114 : [v] "=r" (v), 115 [count] "+m" (val->count) 116 ); 117 118 return v; 99 119 } 100 120 101 121 static inline long atomic_postdec(atomic_t *val) 102 122 { 103 return atomic_add(val, -1); 123 long v; 124 125 asm volatile ( 126 "fetchadd8.rel %[v] = %[count], -1\n" 127 : [v] "=r" (v), 128 [count] "+m" (val->count) 129 ); 130 131 return v; 104 132 } 105 133 -
kernel/arch/ia64/include/interrupt.h
r7e266ff rad4b32c 40 40 41 41 /** ia64 has 256 INRs. */ 42 #define INR_COUNT 42 #define INR_COUNT 256 43 43 44 44 /* … … 47 47 * to genarch. 48 48 */ 49 #define IVT_ITEMS 50 #define IVT_FIRST 49 #define IVT_ITEMS 0 50 #define IVT_FIRST 0 51 51 52 52 /** External Interrupt vectors. */ 53 53 54 #define VECTOR_TLB_SHOOTDOWN_IPI 0xf0 55 #define INTERRUPT_TIMER 255 56 #define IRQ_KBD (0x01 + LEGACY_INTERRUPT_BASE) 57 #define IRQ_MOUSE (0x0c + LEGACY_INTERRUPT_BASE) 58 #define INTERRUPT_SPURIOUS 15 59 #define LEGACY_INTERRUPT_BASE 0x20 54 #define VECTOR_TLB_SHOOTDOWN_IPI 0xf0 55 56 #define INTERRUPT_SPURIOUS 15 57 #define INTERRUPT_TIMER 255 58 59 #define LEGACY_INTERRUPT_BASE 0x20 60 61 #define IRQ_KBD (0x01 + LEGACY_INTERRUPT_BASE) 62 #define IRQ_MOUSE (0x0c + LEGACY_INTERRUPT_BASE) 60 63 61 64 /** General Exception codes. */ 62 #define GE_ILLEGALOP 63 #define GE_PRIVOP 64 #define GE_PRIVREG 65 #define GE_RESREGFLD 66 #define GE_DISBLDISTRAN 67 #define GE_ILLEGALDEP 65 #define GE_ILLEGALOP 0 66 #define GE_PRIVOP 1 67 #define GE_PRIVREG 2 68 #define GE_RESREGFLD 3 69 #define GE_DISBLDISTRAN 4 70 #define GE_ILLEGALDEP 8 68 71 69 #define EOI 0/**< The actual value doesn't matter. */72 #define EOI 0 /**< The actual value doesn't matter. */ 70 73 71 74 typedef struct { … … 100 103 uint128_t f30; 101 104 uint128_t f31; 102 105 103 106 uintptr_t ar_bsp; 104 107 uintptr_t ar_bspstore; … … 132 135 { 133 136 istate->cr_iip = retaddr; 134 istate->cr_ipsr.ri = 0; 137 istate->cr_ipsr.ri = 0; /* return to instruction slot #0 */ 135 138 } 136 139 -
kernel/arch/ia64/include/mm/as.h
r7e266ff rad4b32c 27 27 */ 28 28 29 /** @addtogroup ia64mm 29 /** @addtogroup ia64mm 30 30 * @{ 31 31 */ … … 36 36 #define KERN_ia64_AS_H_ 37 37 38 #define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH 38 #define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH 0 39 39 40 #define KERNEL_ADDRESS_SPACE_START_ARCH (unsigned long) 0xe000000000000000ULL41 #define KERNEL_ADDRESS_SPACE_END_ARCH (unsigned long) 0xffffffffffffffffULL42 #define USER_ADDRESS_SPACE_START_ARCH (unsigned long) 0x0000000000000000ULL43 #define USER_ADDRESS_SPACE_END_ARCH (unsigned long) 0xdfffffffffffffffULL40 #define KERNEL_ADDRESS_SPACE_START_ARCH ((unsigned long) 0xe000000000000000ULL) 41 #define KERNEL_ADDRESS_SPACE_END_ARCH ((unsigned long) 0xffffffffffffffffULL) 42 #define USER_ADDRESS_SPACE_START_ARCH ((unsigned long) 0x0000000000000000ULL) 43 #define USER_ADDRESS_SPACE_END_ARCH ((unsigned long) 0xdfffffffffffffffULL) 44 44 45 #define USTACK_ADDRESS_ARCH 45 #define USTACK_ADDRESS_ARCH 0x0000000ff0000000ULL 46 46 47 47 typedef struct { … … 50 50 #include <genarch/mm/as_ht.h> 51 51 52 #define as_constructor_arch(as, flags) 53 #define as_destructor_arch(as) 54 #define as_create_arch(as, flags) 52 #define as_constructor_arch(as, flags) (as != as) 53 #define as_destructor_arch(as) (as != as) 54 #define as_create_arch(as, flags) (as != as) 55 55 #define as_deinstall_arch(as) 56 56 #define as_invalidate_translation_cache(as, page, cnt) -
kernel/arch/ia64/include/mm/page.h
r7e266ff rad4b32c 28 28 */ 29 29 30 /** @addtogroup ia64mm 30 /** @addtogroup ia64mm 31 31 * @{ 32 32 */ … … 39 39 #include <arch/mm/frame.h> 40 40 41 #define PAGE_SIZE 42 #define PAGE_WIDTH 41 #define PAGE_SIZE FRAME_SIZE 42 #define PAGE_WIDTH FRAME_WIDTH 43 43 44 44 #ifdef KERNEL 45 45 46 46 /** Bit width of the TLB-locked portion of kernel address space. */ 47 #define KERNEL_PAGE_WIDTH 28/* 256M */48 #define IO_PAGE_WIDTH 26/* 64M */49 #define FW_PAGE_WIDTH 28/* 256M */50 51 #define USPACE_IO_PAGE_WIDTH 12/* 4K */47 #define KERNEL_PAGE_WIDTH 28 /* 256M */ 48 #define IO_PAGE_WIDTH 26 /* 64M */ 49 #define FW_PAGE_WIDTH 28 /* 256M */ 50 51 #define USPACE_IO_PAGE_WIDTH 12 /* 4K */ 52 52 53 53 … … 59 59 60 60 /* Firmware area (bellow 4GB in phys mem) */ 61 #define FW_OFFSET 61 #define FW_OFFSET 0x00000000F0000000 62 62 /* Legacy IO space */ 63 #define IO_OFFSET 63 #define IO_OFFSET 0x0001000000000000 64 64 /* Videoram - now mapped to 0 as VGA text mode vram on 0xb8000 */ 65 #define VIO_OFFSET 66 67 68 #define PPN_SHIFT 69 70 #define VRN_SHIFT 71 #define VRN_MASK (7LL << VRN_SHIFT)72 #define VA2VRN(va) ((va)>>VRN_SHIFT)65 #define VIO_OFFSET 0x0002000000000000 66 67 68 #define PPN_SHIFT 12 69 70 #define VRN_SHIFT 61 71 #define VRN_MASK (7ULL << VRN_SHIFT) 72 #define VA2VRN(va) ((va) >> VRN_SHIFT) 73 73 74 74 #ifdef __ASM__ 75 #define VRN_KERNEL775 #define VRN_KERNEL 7 76 76 #else 77 #define VRN_KERNEL 7LL77 #define VRN_KERNEL 7ULL 78 78 #endif 79 79 80 #define REGION_REGISTERS 81 82 #define KA2PA(x) ((uintptr_t) (x- (VRN_KERNEL << VRN_SHIFT)))83 #define PA2KA(x) ((uintptr_t) (x+ (VRN_KERNEL << VRN_SHIFT)))84 85 #define VHPT_WIDTH 20/* 1M */86 #define VHPT_SIZE 87 88 #define PTA_BASE_SHIFT 80 #define REGION_REGISTERS 8 81 82 #define KA2PA(x) ((uintptr_t) ((x) - (VRN_KERNEL << VRN_SHIFT))) 83 #define PA2KA(x) ((uintptr_t) ((x) + (VRN_KERNEL << VRN_SHIFT))) 84 85 #define VHPT_WIDTH 20 /* 1M */ 86 #define VHPT_SIZE (1 << VHPT_WIDTH) 87 88 #define PTA_BASE_SHIFT 15 89 89 90 90 /** Memory Attributes. */ 91 #define MA_WRITEBACK 0x092 #define MA_UNCACHEABLE 0x491 #define MA_WRITEBACK 0x00 92 #define MA_UNCACHEABLE 0x04 93 93 94 94 /** Privilege Levels. Only the most and the least privileged ones are ever used. */ 95 #define PL_KERNEL 0x096 #define PL_USER 0x395 #define PL_KERNEL 0x00 96 #define PL_USER 0x03 97 97 98 98 /* Access Rigths. Only certain combinations are used by the kernel. */ 99 #define AR_READ 0x0100 #define AR_EXECUTE 0x1101 #define AR_WRITE 0x299 #define AR_READ 0x00 100 #define AR_EXECUTE 0x01 101 #define AR_WRITE 0x02 102 102 103 103 #ifndef __ASM__ … … 113 113 struct vhpt_tag_info { 114 114 unsigned long long tag : 63; 115 unsigned ti : 1;115 unsigned int ti : 1; 116 116 } __attribute__ ((packed)); 117 117 … … 123 123 struct vhpt_entry_present { 124 124 /* Word 0 */ 125 unsigned p : 1;126 unsigned : 1;127 unsigned ma : 3;128 unsigned a : 1;129 unsigned d : 1;130 unsigned pl : 2;131 unsigned ar : 3;125 unsigned int p : 1; 126 unsigned int : 1; 127 unsigned int ma : 3; 128 unsigned int a : 1; 129 unsigned int d : 1; 130 unsigned int pl : 2; 131 unsigned int ar : 3; 132 132 unsigned long long ppn : 38; 133 unsigned : 2;134 unsigned ed : 1;135 unsigned i g1 : 11;133 unsigned int : 2; 134 unsigned int ed : 1; 135 unsigned int ig1 : 11; 136 136 137 137 /* Word 1 */ 138 unsigned : 2;139 unsigned ps : 6;140 unsigned key : 24;141 unsigned : 32;138 unsigned int : 2; 139 unsigned int ps : 6; 140 unsigned int key : 24; 141 unsigned int : 32; 142 142 143 143 /* Word 2 */ 144 144 union vhpt_tag tag; 145 145 146 /* Word 3 */ 146 /* Word 3 */ 147 147 uint64_t ig3 : 64; 148 148 } __attribute__ ((packed)); … … 150 150 struct vhpt_entry_not_present { 151 151 /* Word 0 */ 152 unsigned p : 1;152 unsigned int p : 1; 153 153 unsigned long long ig0 : 52; 154 unsigned i g1 : 11;154 unsigned int ig1 : 11; 155 155 156 156 /* Word 1 */ 157 unsigned : 2;158 unsigned ps : 6;157 unsigned int : 2; 158 unsigned int ps : 6; 159 159 unsigned long long ig2 : 56; 160 160 161 161 /* Word 2 */ 162 162 union vhpt_tag tag; 163 163 164 /* Word 3 */ 164 /* Word 3 */ 165 165 uint64_t ig3 : 64; 166 166 } __attribute__ ((packed)); 167 167 168 typedef union vhpt_entry{168 typedef union { 169 169 struct vhpt_entry_present present; 170 170 struct vhpt_entry_not_present not_present; … … 173 173 174 174 struct region_register_map { 175 unsigned ve : 1;176 unsigned : 1;177 unsigned ps : 6;178 unsigned rid : 24;179 unsigned : 32;180 } __attribute__ ((packed)); 181 182 typedef union region_register{175 unsigned int ve : 1; 176 unsigned int : 1; 177 unsigned int ps : 6; 178 unsigned int rid : 24; 179 unsigned int : 32; 180 } __attribute__ ((packed)); 181 182 typedef union { 183 183 struct region_register_map map; 184 184 unsigned long long word; 185 } region_register ;185 } region_register_t; 186 186 187 187 struct pta_register_map { 188 unsigned ve : 1;189 unsigned : 1;190 unsigned size : 6;191 unsigned vf : 1;192 unsigned : 6;188 unsigned int ve : 1; 189 unsigned int : 1; 190 unsigned int size : 6; 191 unsigned int vf : 1; 192 unsigned int : 6; 193 193 unsigned long long base : 49; 194 194 } __attribute__ ((packed)); … … 197 197 struct pta_register_map map; 198 198 uint64_t word; 199 } pta_register ;199 } pta_register_t; 200 200 201 201 /** Return Translation Hashed Entry Address. … … 211 211 { 212 212 uint64_t ret; 213 214 asm volatile ("thash %0 = %1\n" : "=r" (ret) : "r" (va)); 215 213 214 asm volatile ( 215 "thash %[ret] = %[va]\n" 216 : [ret] "=r" (ret) 217 : [va] "r" (va) 218 ); 219 216 220 return ret; 217 221 } … … 229 233 { 230 234 uint64_t ret; 231 232 asm volatile ("ttag %0 = %1\n" : "=r" (ret) : "r" (va)); 233 235 236 asm volatile ( 237 "ttag %[ret] = %[va]\n" 238 : [ret] "=r" (ret) 239 : [va] "r" (va) 240 ); 241 234 242 return ret; 235 243 } … … 244 252 { 245 253 uint64_t ret; 254 246 255 ASSERT(i < REGION_REGISTERS); 247 asm volatile ("mov %0 = rr[%1]\n" : "=r" (ret) : "r" (i << VRN_SHIFT)); 256 257 asm volatile ( 258 "mov %[ret] = rr[%[index]]\n" 259 : [ret] "=r" (ret) 260 : [index] "r" (i << VRN_SHIFT) 261 ); 262 248 263 return ret; 249 264 } … … 257 272 { 258 273 ASSERT(i < REGION_REGISTERS); 259 asm volatile ( 260 "mov rr[%0] = %1\n" 261 : 262 : "r" (i << VRN_SHIFT), "r" (v) 263 ); 264 } 265 274 275 asm volatile ( 276 "mov rr[%[index]] = %[value]\n" 277 :: [index] "r" (i << VRN_SHIFT), 278 [value] "r" (v) 279 ); 280 } 281 266 282 /** Read Page Table Register. 267 283 * … … 272 288 uint64_t ret; 273 289 274 asm volatile ("mov %0 = cr.pta\n" : "=r" (ret)); 290 asm volatile ( 291 "mov %[ret] = cr.pta\n" 292 : [ret] "=r" (ret) 293 ); 275 294 276 295 return ret; … … 283 302 static inline void pta_write(uint64_t v) 284 303 { 285 asm volatile ("mov cr.pta = %0\n" : : "r" (v)); 304 asm volatile ( 305 "mov cr.pta = %[value]\n" 306 :: [value] "r" (v) 307 ); 286 308 } 287 309 -
kernel/arch/ia64/include/mm/tlb.h
r7e266ff rad4b32c 27 27 */ 28 28 29 /** @addtogroup ia64mm 29 /** @addtogroup ia64mm 30 30 * @{ 31 31 */ … … 42 42 43 43 /** Data and instruction Translation Register indices. */ 44 #define DTR_KERNEL 45 #define ITR_KERNEL 46 #define DTR_KSTACK1 47 #define DTR_KSTACK2 44 #define DTR_KERNEL 0 45 #define ITR_KERNEL 0 46 #define DTR_KSTACK1 4 47 #define DTR_KSTACK2 5 48 48 49 49 /** Portion of TLB insertion format data structure. */ 50 union tlb_entry{50 typedef union { 51 51 uint64_t word[2]; 52 52 struct { 53 53 /* Word 0 */ 54 unsigned p : 1;/**< Present. */55 unsigned : 1;56 unsigned ma : 3;/**< Memory attribute. */57 unsigned a : 1;/**< Accessed. */58 unsigned d : 1;/**< Dirty. */59 unsigned pl : 2;/**< Privilege level. */60 unsigned ar : 3;/**< Access rights. */61 unsigned long long ppn : 38; 62 unsigned : 2;63 unsigned ed : 1;64 unsigned i g1 : 11;65 54 unsigned int p : 1; /**< Present. */ 55 unsigned int : 1; 56 unsigned int ma : 3; /**< Memory attribute. */ 57 unsigned int a : 1; /**< Accessed. */ 58 unsigned int d : 1; /**< Dirty. */ 59 unsigned int pl : 2; /**< Privilege level. */ 60 unsigned int ar : 3; /**< Access rights. */ 61 unsigned long long ppn : 38; /**< Physical Page Number, a.k.a. PFN. */ 62 unsigned int : 2; 63 unsigned int ed : 1; 64 unsigned int ig1 : 11; 65 66 66 /* Word 1 */ 67 unsigned : 2;68 unsigned ps : 6;/**< Page size will be 2^ps. */69 unsigned key : 24;/**< Protection key, unused. */70 unsigned : 32;67 unsigned int : 2; 68 unsigned int ps : 6; /**< Page size will be 2^ps. */ 69 unsigned int key : 24; /**< Protection key, unused. */ 70 unsigned int : 32; 71 71 } __attribute__ ((packed)); 72 } __attribute__ ((packed)); 73 typedef union tlb_entry tlb_entry_t; 72 } __attribute__ ((packed)) tlb_entry_t; 74 73 75 74 extern void tc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtc); -
kernel/arch/ia64/include/register.h
r7e266ff rad4b32c 27 27 */ 28 28 29 /** @addtogroup ia64 29 /** @addtogroup ia64 30 30 * @{ 31 31 */ … … 36 36 #define KERN_ia64_REGISTER_H_ 37 37 38 #define CR_IVR_MASK 0xf 39 #define PSR_IC_MASK 0x2000 40 #define PSR_I_MASK 0x4000 41 #define PSR_PK_MASK 0x8000 42 43 #define PSR_DT_MASK (1 << 17) 44 #define PSR_RT_MASK (1 << 27) 45 46 #define PSR_DFL_MASK (1 << 18) 47 #define PSR_DFH_MASK (1 << 19) 48 49 #define PSR_IT_MASK 0x0000001000000000 50 51 #define PSR_CPL_SHIFT 32 52 #define PSR_CPL_MASK_SHIFTED 3 53 54 #define PFM_MASK (~0x3fffffffff) 55 56 #define RSC_MODE_MASK 3 57 #define RSC_PL_MASK 12 38 #define DCR_PP_MASK (1 << 0) 39 #define DCR_BE_MASK (1 << 1) 40 #define DCR_LC_MASK (1 << 2) 41 #define DCR_DM_MASK (1 << 8) 42 #define DCR_DP_MASK (1 << 9) 43 #define DCR_DK_MASK (1 << 10) 44 #define DCR_DX_MASK (1 << 11) 45 #define DCR_DR_MASK (1 << 12) 46 #define DCR_DA_MASK (1 << 13) 47 #define DCR_DD_MASK (1 << 14) 48 49 #define CR_IVR_MASK 0x0f 50 51 #define PSR_IC_MASK (1 << 13) 52 #define PSR_I_MASK (1 << 14) 53 #define PSR_PK_MASK (1 << 15) 54 #define PSR_DT_MASK (1 << 17) 55 #define PSR_DFL_MASK (1 << 18) 56 #define PSR_DFH_MASK (1 << 19) 57 #define PSR_RT_MASK (1 << 27) 58 #define PSR_IT_MASK (1 << 36) 59 60 #define PSR_CPL_SHIFT 32 61 #define PSR_CPL_MASK_SHIFTED 3 62 63 #define PFM_MASK (~0x3fffffffff) 64 65 #define RSC_MODE_MASK 3 66 #define RSC_PL_MASK 12 58 67 59 68 /** Application registers. */ 60 #define AR_KR0 61 #define AR_KR1 62 #define AR_KR2 63 #define AR_KR3 64 #define AR_KR4 65 #define AR_KR5 66 #define AR_KR6 67 #define AR_KR7 68 /* AR 8-15reserved */69 #define AR_RSC 70 #define AR_BSP 71 #define AR_BSPSTORE 72 #define AR_RNAT 73 /* AR 20 reserved */74 #define AR_FCR 75 /* AR 22-23reserved */76 #define AR_EFLAG 77 #define AR_CSD 78 #define AR_SSD 79 #define AR_CFLG 80 #define AR_FSR 81 #define AR_FIR 82 #define AR_FDR 83 /* AR 31 reserved */84 #define AR_CCV 85 /* AR 33-35reserved */86 #define AR_UNAT 87 /* AR 37-39reserved */88 #define AR_FPSR 89 /* AR 41-43reserved */90 #define AR_ITC 91 /* AR 45-47reserved */92 /* AR 48-63ignored */93 #define AR_PFS 94 #define AR_LC 95 #define AR_EC 96 /* AR 67-111reserved */97 /* AR 112-127ignored */69 #define AR_KR0 0 70 #define AR_KR1 1 71 #define AR_KR2 2 72 #define AR_KR3 3 73 #define AR_KR4 4 74 #define AR_KR5 5 75 #define AR_KR6 6 76 #define AR_KR7 7 77 /* ARs 8-15 are reserved */ 78 #define AR_RSC 16 79 #define AR_BSP 17 80 #define AR_BSPSTORE 18 81 #define AR_RNAT 19 82 /* AR 20 is reserved */ 83 #define AR_FCR 21 84 /* ARs 22-23 are reserved */ 85 #define AR_EFLAG 24 86 #define AR_CSD 25 87 #define AR_SSD 26 88 #define AR_CFLG 27 89 #define AR_FSR 28 90 #define AR_FIR 29 91 #define AR_FDR 30 92 /* AR 31 is reserved */ 93 #define AR_CCV 32 94 /* ARs 33-35 are reserved */ 95 #define AR_UNAT 36 96 /* ARs 37-39 are reserved */ 97 #define AR_FPSR 40 98 /* ARs 41-43 are reserved */ 99 #define AR_ITC 44 100 /* ARs 45-47 are reserved */ 101 /* ARs 48-63 are ignored */ 102 #define AR_PFS 64 103 #define AR_LC 65 104 #define AR_EC 66 105 /* ARs 67-111 are reserved */ 106 /* ARs 112-127 are ignored */ 98 107 99 108 /** Control registers. */ 100 #define CR_DCR 101 #define CR_ITM 102 #define CR_IVA 103 /* CR3-CR7 reserved */104 #define CR_PTA 105 /* CR9-CR15 reserved */106 #define CR_IPSR 107 #define CR_ISR 108 /* CR18 reserved */109 #define CR_IIP 110 #define CR_IFA 111 #define CR_ITIR 112 #define CR_IIPA 113 #define CR_IFS 114 #define CR_IIM 115 #define CR_IHA 116 /* CR26-CR63 reserved */117 #define CR_LID 118 #define CR_IVR 119 #define CR_TPR 120 #define CR_EOI 121 #define CR_IRR0 122 #define CR_IRR1 123 #define CR_IRR2 124 #define CR_IRR3 125 #define CR_ITV 126 #define CR_PMV 127 #define CR_CMCV 128 /* CR75-CR79 reserved */129 #define CR_LRR0 130 #define CR_LRR1 131 /* CR82-CR127 reserved */109 #define CR_DCR 0 110 #define CR_ITM 1 111 #define CR_IVA 2 112 /* CR3-CR7 are reserved */ 113 #define CR_PTA 8 114 /* CR9-CR15 are reserved */ 115 #define CR_IPSR 16 116 #define CR_ISR 17 117 /* CR18 is reserved */ 118 #define CR_IIP 19 119 #define CR_IFA 20 120 #define CR_ITIR 21 121 #define CR_IIPA 22 122 #define CR_IFS 23 123 #define CR_IIM 24 124 #define CR_IHA 25 125 /* CR26-CR63 are reserved */ 126 #define CR_LID 64 127 #define CR_IVR 65 128 #define CR_TPR 66 129 #define CR_EOI 67 130 #define CR_IRR0 68 131 #define CR_IRR1 69 132 #define CR_IRR2 70 133 #define CR_IRR3 71 134 #define CR_ITV 72 135 #define CR_PMV 73 136 #define CR_CMCV 74 137 /* CR75-CR79 are reserved */ 138 #define CR_LRR0 80 139 #define CR_LRR1 81 140 /* CR82-CR127 are reserved */ 132 141 133 142 #ifndef __ASM__ … … 136 145 137 146 /** Processor Status Register. */ 138 union psr { 139 uint64_t value; 140 struct { 141 unsigned : 1; 142 unsigned be : 1; /**< Big-Endian data accesses. */ 143 unsigned up : 1; /**< User Performance monitor enable. */ 144 unsigned ac : 1; /**< Alignment Check. */ 145 unsigned mfl : 1; /**< Lower floating-point register written. */ 146 unsigned mfh : 1; /**< Upper floating-point register written. */ 147 unsigned : 7; 148 unsigned ic : 1; /**< Interruption Collection. */ 149 unsigned i : 1; /**< Interrupt Bit. */ 150 unsigned pk : 1; /**< Protection Key enable. */ 151 unsigned : 1; 152 unsigned dt : 1; /**< Data address Translation. */ 153 unsigned dfl : 1; /**< Disabled Floating-point Low register set. */ 154 unsigned dfh : 1; /**< Disabled Floating-point High register set. */ 155 unsigned sp : 1; /**< Secure Performance monitors. */ 156 unsigned pp : 1; /**< Privileged Performance monitor enable. */ 157 unsigned di : 1; /**< Disable Instruction set transition. */ 158 unsigned si : 1; /**< Secure Interval timer. */ 159 unsigned db : 1; /**< Debug Breakpoint fault. */ 160 unsigned lp : 1; /**< Lower Privilege transfer trap. */ 161 unsigned tb : 1; /**< Taken Branch trap. */ 162 unsigned rt : 1; /**< Register Stack Translation. */ 163 unsigned : 4; 164 unsigned cpl : 2; /**< Current Privilege Level. */ 165 unsigned is : 1; /**< Instruction Set. */ 166 unsigned mc : 1; /**< Machine Check abort mask. */ 167 unsigned it : 1; /**< Instruction address Translation. */ 168 unsigned id : 1; /**< Instruction Debug fault disable. */ 169 unsigned da : 1; /**< Disable Data Access and Dirty-bit faults. */ 170 unsigned dd : 1; /**< Data Debug fault disable. */ 171 unsigned ss : 1; /**< Single Step enable. */ 172 unsigned ri : 2; /**< Restart Instruction. */ 173 unsigned ed : 1; /**< Exception Deferral. */ 174 unsigned bn : 1; /**< Register Bank. */ 175 unsigned ia : 1; /**< Disable Instruction Access-bit faults. */ 176 } __attribute__ ((packed)); 177 }; 178 typedef union psr psr_t; 147 typedef union { 148 uint64_t value; 149 struct { 150 unsigned int : 1; 151 unsigned int be : 1; /**< Big-Endian data accesses. */ 152 unsigned int up : 1; /**< User Performance monitor enable. */ 153 unsigned int ac : 1; /**< Alignment Check. */ 154 unsigned int mfl : 1; /**< Lower floating-point register written. */ 155 unsigned int mfh : 1; /**< Upper floating-point register written. */ 156 unsigned int : 7; 157 unsigned int ic : 1; /**< Interruption Collection. */ 158 unsigned int i : 1; /**< Interrupt Bit. */ 159 unsigned int pk : 1; /**< Protection Key enable. */ 160 unsigned int : 1; 161 unsigned int dt : 1; /**< Data address Translation. */ 162 unsigned int dfl : 1; /**< Disabled Floating-point Low register set. */ 163 unsigned int dfh : 1; /**< Disabled Floating-point High register set. */ 164 unsigned int sp : 1; /**< Secure Performance monitors. */ 165 unsigned int pp : 1; /**< Privileged Performance monitor enable. */ 166 unsigned int di : 1; /**< Disable Instruction set transition. */ 167 unsigned int si : 1; /**< Secure Interval timer. */ 168 unsigned int db : 1; /**< Debug Breakpoint fault. */ 169 unsigned int lp : 1; /**< Lower Privilege transfer trap. */ 170 unsigned int tb : 1; /**< Taken Branch trap. */ 171 unsigned int rt : 1; /**< Register Stack Translation. */ 172 unsigned int : 4; 173 unsigned int cpl : 2; /**< Current Privilege Level. */ 174 unsigned int is : 1; /**< Instruction Set. */ 175 unsigned int mc : 1; /**< Machine Check abort mask. */ 176 unsigned int it : 1; /**< Instruction address Translation. */ 177 unsigned int id : 1; /**< Instruction Debug fault disable. */ 178 unsigned int da : 1; /**< Disable Data Access and Dirty-bit faults. */ 179 unsigned int dd : 1; /**< Data Debug fault disable. */ 180 unsigned int ss : 1; /**< Single Step enable. */ 181 unsigned int ri : 2; /**< Restart Instruction. */ 182 unsigned int ed : 1; /**< Exception Deferral. */ 183 unsigned int bn : 1; /**< Register Bank. */ 184 unsigned int ia : 1; /**< Disable Instruction Access-bit faults. */ 185 } __attribute__ ((packed)); 186 } psr_t; 179 187 180 188 /** Register Stack Configuration Register */ 181 union rsc { 182 uint64_t value; 183 struct { 184 unsigned mode : 2; 185 unsigned pl : 2; /**< Privilege Level. */ 186 unsigned be : 1; /**< Big-endian. */ 187 unsigned : 11; 188 unsigned loadrs : 14; 189 } __attribute__ ((packed)); 190 }; 191 typedef union rsc rsc_t; 189 typedef union { 190 uint64_t value; 191 struct { 192 unsigned int mode : 2; 193 unsigned int pl : 2; /**< Privilege Level. */ 194 unsigned int be : 1; /**< Big-endian. */ 195 unsigned int : 11; 196 unsigned int loadrs : 14; 197 } __attribute__ ((packed)); 198 } rsc_t; 192 199 193 200 /** External Interrupt Vector Register */ 194 union cr_ivr { 195 uint8_t vector; 196 uint64_t value; 197 }; 198 199 typedef union cr_ivr cr_ivr_t; 201 typedef union { 202 uint8_t vector; 203 uint64_t value; 204 } cr_ivr_t; 200 205 201 206 /** Task Priority Register */ 202 union cr_tpr { 203 struct { 204 unsigned : 4; 205 unsigned mic: 4; /**< Mask Interrupt Class. */ 206 unsigned : 8; 207 unsigned mmi: 1; /**< Mask Maskable Interrupts. */ 208 } __attribute__ ((packed)); 209 uint64_t value; 210 }; 211 212 typedef union cr_tpr cr_tpr_t; 207 typedef union { 208 uint64_t value; 209 struct { 210 unsigned int : 4; 211 unsigned int mic: 4; /**< Mask Interrupt Class. */ 212 unsigned int : 8; 213 unsigned int mmi: 1; /**< Mask Maskable Interrupts. */ 214 } __attribute__ ((packed)); 215 } cr_tpr_t; 213 216 214 217 /** Interval Timer Vector */ 215 union cr_itv { 216 struct { 217 unsigned vector : 8; 218 unsigned : 4; 219 unsigned : 1; 220 unsigned : 3; 221 unsigned m : 1; /**< Mask. */ 222 } __attribute__ ((packed)); 223 uint64_t value; 224 }; 225 226 typedef union cr_itv cr_itv_t; 218 typedef union { 219 uint64_t value; 220 struct { 221 unsigned int vector : 8; 222 unsigned int : 4; 223 unsigned int : 1; 224 unsigned int : 3; 225 unsigned int m : 1; /**< Mask. */ 226 } __attribute__ ((packed)); 227 } cr_itv_t; 227 228 228 229 /** Interruption Status Register */ 229 union cr_isr { 230 typedef union { 231 uint64_t value; 230 232 struct { 231 233 union { 232 234 /** General Exception code field structuring. */ 235 uint16_t code; 233 236 struct { 234 unsigned ge_na : 4;235 unsigned ge_code : 4;237 unsigned int ge_na : 4; 238 unsigned int ge_code : 4; 236 239 } __attribute__ ((packed)); 237 uint16_t code;238 240 }; 239 241 uint8_t vector; 240 unsigned : 8; 241 unsigned x : 1; /**< Execute exception. */ 242 unsigned w : 1; /**< Write exception. */ 243 unsigned r : 1; /**< Read exception. */ 244 unsigned na : 1; /**< Non-access exception. */ 245 unsigned sp : 1; /**< Speculative load exception. */ 246 unsigned rs : 1; /**< Register stack. */ 247 unsigned ir : 1; /**< Incomplete Register frame. */ 248 unsigned ni : 1; /**< Nested Interruption. */ 249 unsigned so : 1; /**< IA-32 Supervisor Override. */ 250 unsigned ei : 2; /**< Excepting Instruction. */ 251 unsigned ed : 1; /**< Exception Deferral. */ 252 unsigned : 20; 253 } __attribute__ ((packed)); 254 uint64_t value; 255 }; 256 257 typedef union cr_isr cr_isr_t; 242 unsigned int : 8; 243 unsigned int x : 1; /**< Execute exception. */ 244 unsigned int w : 1; /**< Write exception. */ 245 unsigned int r : 1; /**< Read exception. */ 246 unsigned int na : 1; /**< Non-access exception. */ 247 unsigned int sp : 1; /**< Speculative load exception. */ 248 unsigned int rs : 1; /**< Register stack. */ 249 unsigned int ir : 1; /**< Incomplete Register frame. */ 250 unsigned int ni : 1; /**< Nested Interruption. */ 251 unsigned int so : 1; /**< IA-32 Supervisor Override. */ 252 unsigned int ei : 2; /**< Excepting Instruction. */ 253 unsigned int ed : 1; /**< Exception Deferral. */ 254 unsigned int : 20; 255 } __attribute__ ((packed)); 256 } cr_isr_t; 258 257 259 258 /** CPUID Register 3 */ 260 union cpuid3 { 259 typedef union { 260 uint64_t value; 261 261 struct { 262 262 uint8_t number; … … 266 266 uint8_t archrev; 267 267 } __attribute__ ((packed)); 268 uint64_t value; 269 }; 270 271 typedef union cpuid3 cpuid3_t; 268 } cpuid3_t; 272 269 273 270 #endif /* !__ASM__ */ -
kernel/arch/ia64/src/mm/as.c
r7e266ff rad4b32c 55 55 void as_install_arch(as_t *as) 56 56 { 57 region_register rr;57 region_register_t rr; 58 58 int i; 59 59 -
kernel/arch/ia64/src/mm/page.c
r7e266ff rad4b32c 63 63 void set_environment(void) 64 64 { 65 region_register rr;66 pta_register pta;65 region_register_t rr; 66 pta_register_t pta; 67 67 int i; 68 68 #ifdef CONFIG_VHPT … … 131 131 vhpt_entry_t *vhpt_hash(uintptr_t page, asid_t asid) 132 132 { 133 region_register rr_save, rr;133 region_register_t rr_save, rr; 134 134 size_t vrn; 135 135 rid_t rid; … … 176 176 bool vhpt_compare(uintptr_t page, asid_t asid, vhpt_entry_t *v) 177 177 { 178 region_register rr_save, rr;178 region_register_t rr_save, rr; 179 179 size_t vrn; 180 180 rid_t rid; … … 223 223 int flags) 224 224 { 225 region_register rr_save, rr;225 region_register_t rr_save, rr; 226 226 size_t vrn; 227 227 rid_t rid; … … 257 257 v->present.ma = (flags & PAGE_CACHEABLE) ? 258 258 MA_WRITEBACK : MA_UNCACHEABLE; 259 v->present.a = false; 260 v->present.d = false; 259 v->present.a = false; /* not accessed */ 260 v->present.d = false; /* not dirty */ 261 261 v->present.pl = (flags & PAGE_USER) ? PL_USER : PL_KERNEL; 262 262 v->present.ar = (flags & PAGE_WRITE) ? AR_WRITE : AR_READ; 263 263 v->present.ar |= (flags & PAGE_EXEC) ? AR_EXECUTE : 0; 264 264 v->present.ppn = frame >> PPN_SHIFT; 265 v->present.ed = false; 265 v->present.ed = false; /* exception not deffered */ 266 266 v->present.ps = PAGE_WIDTH; 267 267 v->present.key = 0; -
kernel/arch/ia64/src/mm/tlb.c
r7e266ff rad4b32c 27 27 */ 28 28 29 /** @addtogroup ia64mm 29 /** @addtogroup ia64mm 30 30 * @{ 31 31 */ … … 53 53 #include <interrupt.h> 54 54 55 #define IO_FRAME_BASE 0xFFFFC000000 56 55 57 /** Invalidate all TLB entries. */ 56 58 void tlb_invalidate_all(void) … … 59 61 uintptr_t adr; 60 62 uint32_t count1, count2, stride1, stride2; 61 63 62 64 unsigned int i, j; 63 65 64 66 adr = PAL_PTCE_INFO_BASE(); 65 67 count1 = PAL_PTCE_INFO_COUNT1(); … … 67 69 stride1 = PAL_PTCE_INFO_STRIDE1(); 68 70 stride2 = PAL_PTCE_INFO_STRIDE2(); 69 71 70 72 ipl = interrupts_disable(); 71 73 72 74 for (i = 0; i < count1; i++) { 73 75 for (j = 0; j < count2; j++) { 74 76 asm volatile ( 75 "ptc.e %0 ;;" 76 : 77 : "r" (adr) 77 "ptc.e %[adr] ;;" 78 :: [adr] "r" (adr) 78 79 ); 79 80 adr += stride2; … … 81 82 adr += stride1; 82 83 } 83 84 84 85 interrupts_restore(ipl); 85 86 86 87 srlz_d(); 87 88 srlz_i(); 89 88 90 #ifdef CONFIG_VHPT 89 91 vhpt_invalidate_all(); 90 #endif 92 #endif 91 93 } 92 94 93 95 /** Invalidate entries belonging to an address space. 94 96 * 95 * @param asid Address space identifier. 97 * @param asid Address space identifier. 98 * 96 99 */ 97 100 void tlb_invalidate_asid(asid_t asid) … … 103 106 void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt) 104 107 { 105 region_register rr;108 region_register_t rr; 106 109 bool restore_rr = false; 107 110 int b = 0; 108 111 int c = cnt; 109 112 110 113 uintptr_t va; 111 114 va = page; 112 115 113 116 rr.word = rr_read(VA2VRN(va)); 114 117 if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA2VRN(va))))) { … … 117 120 * Save the old content of the register and replace the RID. 118 121 */ 119 region_register rr0;120 122 region_register_t rr0; 123 121 124 rr0 = rr; 122 125 rr0.map.rid = ASID2RID(asid, VA2VRN(va)); … … 126 129 } 127 130 128 while (c >>= 1)131 while (c >>= 1) 129 132 b++; 130 133 b >>= 1; … … 169 172 break; 170 173 } 171 for(; va < (page + cnt * PAGE_SIZE); va += (1 << ps)) 172 asm volatile ("ptc.l %0, %1;;" :: "r" (va), "r" (ps << 2)); 174 175 for (; va < (page + cnt * PAGE_SIZE); va += (1 << ps)) 176 asm volatile ( 177 "ptc.l %[va], %[ps] ;;" 178 :: [va]"r" (va), 179 [ps] "r" (ps << 2) 180 ); 181 173 182 srlz_d(); 174 183 srlz_i(); … … 183 192 /** Insert data into data translation cache. 184 193 * 185 * @param va Virtual page address. 186 * @param asid Address space identifier. 187 * @param entry The rest of TLB entry as required by TLB insertion 188 * format. 194 * @param va Virtual page address. 195 * @param asid Address space identifier. 196 * @param entry The rest of TLB entry as required by TLB insertion 197 * format. 198 * 189 199 */ 190 200 void dtc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry) … … 195 205 /** Insert data into instruction translation cache. 196 206 * 197 * @param va 198 * @param asid 199 * @param entry 200 * 207 * @param va Virtual page address. 208 * @param asid Address space identifier. 209 * @param entry The rest of TLB entry as required by TLB insertion 210 * format. 201 211 */ 202 212 void itc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry) … … 207 217 /** Insert data into instruction or data translation cache. 208 218 * 209 * @param va Virtual page address. 210 * @param asid Address space identifier. 211 * @param entry The rest of TLB entry as required by TLB insertion 212 * format. 213 * @param dtc If true, insert into data translation cache, use 214 * instruction translation cache otherwise. 219 * @param va Virtual page address. 220 * @param asid Address space identifier. 221 * @param entry The rest of TLB entry as required by TLB insertion 222 * format. 223 * @param dtc If true, insert into data translation cache, use 224 * instruction translation cache otherwise. 225 * 215 226 */ 216 227 void tc_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtc) 217 228 { 218 region_register rr;229 region_register_t rr; 219 230 bool restore_rr = false; 220 231 221 232 rr.word = rr_read(VA2VRN(va)); 222 233 if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA2VRN(va))))) { … … 225 236 * Save the old content of the register and replace the RID. 226 237 */ 227 region_register rr0;228 238 region_register_t rr0; 239 229 240 rr0 = rr; 230 241 rr0.map.rid = ASID2RID(asid, VA2VRN(va)); … … 235 246 236 247 asm volatile ( 237 "mov r8 = psr;;\n" 238 "rsm %0;;\n" /* PSR_IC_MASK */ 239 "srlz.d;;\n" 240 "srlz.i;;\n" 241 "mov cr.ifa = %1\n" /* va */ 242 "mov cr.itir = %2;;\n" /* entry.word[1] */ 243 "cmp.eq p6,p7 = %4,r0;;\n" /* decide between itc and dtc */ 244 "(p6) itc.i %3;;\n" 245 "(p7) itc.d %3;;\n" 246 "mov psr.l = r8;;\n" 247 "srlz.d;;\n" 248 : 249 : "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), 250 "r" (entry.word[0]), "r" (dtc) 248 "mov r8 = psr ;;\n" 249 "rsm %[mask] ;;\n" /* PSR_IC_MASK */ 250 "srlz.d ;;\n" 251 "srlz.i ;;\n" 252 "mov cr.ifa = %[va]\n" /* va */ 253 "mov cr.itir = %[word1] ;;\n" /* entry.word[1] */ 254 "cmp.eq p6, p7 = %[dtc], r0 ;;\n" /* decide between itc and dtc */ 255 "(p6) itc.i %[word0] ;;\n" 256 "(p7) itc.d %[word0] ;;\n" 257 "mov psr.l = r8 ;;\n" 258 "srlz.d ;;\n" 259 :: [mask] "i" (PSR_IC_MASK), 260 [va] "r" (va), 261 [word0] "r" (entry.word[0]), 262 [word1] "r" (entry.word[1]), 263 [dtc] "r" (dtc) 251 264 : "p6", "p7", "r8" 252 265 ); … … 261 274 /** Insert data into instruction translation register. 262 275 * 263 * @param va 264 * @param asid 265 * @param entry 266 * 267 * @param tr 268 * /269 void 270 itr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, size_t tr)276 * @param va Virtual page address. 277 * @param asid Address space identifier. 278 * @param entry The rest of TLB entry as required by TLB insertion 279 * format. 280 * @param tr Translation register. 281 * 282 */ 283 void itr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, size_t tr) 271 284 { 272 285 tr_mapping_insert(va, asid, entry, false, tr); … … 275 288 /** Insert data into data translation register. 276 289 * 277 * @param va 278 * @param asid 279 * @param entry 280 * 281 * @param tr 282 * /283 void 284 dtr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, size_t tr)290 * @param va Virtual page address. 291 * @param asid Address space identifier. 292 * @param entry The rest of TLB entry as required by TLB insertion 293 * format. 294 * @param tr Translation register. 295 * 296 */ 297 void dtr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, size_t tr) 285 298 { 286 299 tr_mapping_insert(va, asid, entry, true, tr); … … 289 302 /** Insert data into instruction or data translation register. 290 303 * 291 * @param va 292 * @param asid 293 * @param entry 294 * 295 * @param dtr 296 * 297 * @param tr 298 * /299 void 300 tr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtr,304 * @param va Virtual page address. 305 * @param asid Address space identifier. 306 * @param entry The rest of TLB entry as required by TLB insertion 307 * format. 308 * @param dtr If true, insert into data translation register, use 309 * instruction translation register otherwise. 310 * @param tr Translation register. 311 * 312 */ 313 void tr_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry, bool dtr, 301 314 size_t tr) 302 315 { 303 region_register rr;316 region_register_t rr; 304 317 bool restore_rr = false; 305 318 306 319 rr.word = rr_read(VA2VRN(va)); 307 320 if ((restore_rr = (rr.map.rid != ASID2RID(asid, VA2VRN(va))))) { … … 310 323 * Save the old content of the register and replace the RID. 311 324 */ 312 region_register rr0;313 325 region_register_t rr0; 326 314 327 rr0 = rr; 315 328 rr0.map.rid = ASID2RID(asid, VA2VRN(va)); … … 318 331 srlz_i(); 319 332 } 320 333 321 334 asm volatile ( 322 "mov r8 = psr;;\n" 323 "rsm %0;;\n" /* PSR_IC_MASK */ 324 "srlz.d;;\n" 325 "srlz.i;;\n" 326 "mov cr.ifa = %1\n" /* va */ 327 "mov cr.itir = %2;;\n" /* entry.word[1] */ 328 "cmp.eq p6,p7 = %5,r0;;\n" /* decide between itr and dtr */ 329 "(p6) itr.i itr[%4] = %3;;\n" 330 "(p7) itr.d dtr[%4] = %3;;\n" 331 "mov psr.l = r8;;\n" 332 "srlz.d;;\n" 333 : 334 : "i" (PSR_IC_MASK), "r" (va), "r" (entry.word[1]), 335 "r" (entry.word[0]), "r" (tr), "r" (dtr) 335 "mov r8 = psr ;;\n" 336 "rsm %[mask] ;;\n" /* PSR_IC_MASK */ 337 "srlz.d ;;\n" 338 "srlz.i ;;\n" 339 "mov cr.ifa = %[va]\n" /* va */ 340 "mov cr.itir = %[word1] ;;\n" /* entry.word[1] */ 341 "cmp.eq p6, p7 = %[dtr], r0 ;;\n" /* decide between itr and dtr */ 342 "(p6) itr.i itr[%[tr]] = %[word0] ;;\n" 343 "(p7) itr.d dtr[%[tr]] = %[word0] ;;\n" 344 "mov psr.l = r8 ;;\n" 345 "srlz.d ;;\n" 346 :: [mask] "i" (PSR_IC_MASK), 347 [va] "r" (va), 348 [word1] "r" (entry.word[1]), 349 [word0] "r" (entry.word[0]), 350 [tr] "r" (tr), 351 [dtr] "r" (dtr) 336 352 : "p6", "p7", "r8" 337 353 ); … … 346 362 /** Insert data into DTLB. 347 363 * 348 * @param page 349 * @param frame 350 * @param dtr 351 * 352 * @param tr 353 * /354 void 355 dtlb_kernel_mapping_insert(uintptr_t page, uintptr_t frame, bool dtr,364 * @param page Virtual page address including VRN bits. 365 * @param frame Physical frame address. 366 * @param dtr If true, insert into data translation register, use data 367 * translation cache otherwise. 368 * @param tr Translation register if dtr is true, ignored otherwise. 369 * 370 */ 371 void dtlb_kernel_mapping_insert(uintptr_t page, uintptr_t frame, bool dtr, 356 372 size_t tr) 357 373 { … … 361 377 entry.word[1] = 0; 362 378 363 entry.p = true; 379 entry.p = true; /* present */ 364 380 entry.ma = MA_WRITEBACK; 365 entry.a = true; 366 entry.d = true; 381 entry.a = true; /* already accessed */ 382 entry.d = true; /* already dirty */ 367 383 entry.pl = PL_KERNEL; 368 384 entry.ar = AR_READ | AR_WRITE; … … 380 396 * Purge DTR entries used by the kernel. 381 397 * 382 * @param page Virtual page address including VRN bits. 383 * @param width Width of the purge in bits. 398 * @param page Virtual page address including VRN bits. 399 * @param width Width of the purge in bits. 400 * 384 401 */ 385 402 void dtr_purge(uintptr_t page, size_t width) 386 403 { 387 asm volatile ("ptr.d %0, %1\n" : : "r" (page), "r" (width << 2)); 404 asm volatile ( 405 "ptr.d %[page], %[width]\n" 406 :: [page] "r" (page), 407 [width] "r" (width << 2) 408 ); 388 409 } 389 410 … … 391 412 /** Copy content of PTE into data translation cache. 392 413 * 393 * @param t PTE. 414 * @param t PTE. 415 * 394 416 */ 395 417 void dtc_pte_copy(pte_t *t) 396 418 { 397 419 tlb_entry_t entry; 398 420 399 421 entry.word[0] = 0; 400 422 entry.word[1] = 0; … … 410 432 411 433 dtc_mapping_insert(t->page, t->as->asid, entry); 434 412 435 #ifdef CONFIG_VHPT 413 436 vhpt_mapping_insert(t->page, t->as->asid, entry); 414 #endif 437 #endif 415 438 } 416 439 417 440 /** Copy content of PTE into instruction translation cache. 418 441 * 419 * @param t PTE. 442 * @param t PTE. 443 * 420 444 */ 421 445 void itc_pte_copy(pte_t *t) 422 446 { 423 447 tlb_entry_t entry; 424 448 425 449 entry.word[0] = 0; 426 450 entry.word[1] = 0; … … 437 461 438 462 itc_mapping_insert(t->page, t->as->asid, entry); 463 439 464 #ifdef CONFIG_VHPT 440 465 vhpt_mapping_insert(t->page, t->as->asid, entry); 441 #endif 466 #endif 442 467 } 443 468 444 469 /** Instruction TLB fault handler for faults with VHPT turned off. 445 470 * 446 * @param vector Interruption vector. 447 * @param istate Structure with saved interruption state. 471 * @param vector Interruption vector. 472 * @param istate Structure with saved interruption state. 473 * 448 474 */ 449 475 void alternate_instruction_tlb_fault(uint64_t vector, istate_t *istate) 450 476 { 451 region_register rr;477 region_register_t rr; 452 478 rid_t rid; 453 479 uintptr_t va; 454 480 pte_t *t; 455 481 456 va = istate->cr_ifa; 482 va = istate->cr_ifa; /* faulting address */ 457 483 rr.word = rr_read(VA2VRN(va)); 458 484 rid = rr.map.rid; 459 485 460 486 page_table_lock(AS, true); 461 487 t = page_mapping_find(AS, va); … … 473 499 page_table_unlock(AS, true); 474 500 if (as_page_fault(va, PF_ACCESS_EXEC, istate) == AS_PF_FAULT) { 475 fault_if_from_uspace(istate, "Page fault at %p.",va);501 fault_if_from_uspace(istate, "Page fault at %p.", va); 476 502 panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid, 477 503 istate->cr_iip); … … 488 514 } 489 515 490 #define IO_FRAME_BASE 0xFFFFC000000491 492 516 /** 493 517 * There is special handling of memory mapped legacy io, because of 4KB sized 494 518 * access for userspace. 495 519 * 496 * @param va Virtual address of page fault. 497 * @param istate Structure with saved interruption state. 498 * 499 * @return One on success, zero on failure. 520 * @param va Virtual address of page fault. 521 * @param istate Structure with saved interruption state. 522 * 523 * @return One on success, zero on failure. 524 * 500 525 */ 501 526 static int try_memmap_io_insertion(uintptr_t va, istate_t *istate) … … 505 530 uint64_t io_page = (va & ((1 << IO_PAGE_WIDTH) - 1)) >> 506 531 USPACE_IO_PAGE_WIDTH; 507 532 508 533 if (is_io_page_accessible(io_page)) { 509 534 uint64_t page, frame; 510 535 511 536 page = IO_OFFSET + 512 537 (1 << USPACE_IO_PAGE_WIDTH) * io_page; 513 538 frame = IO_FRAME_BASE + 514 539 (1 << USPACE_IO_PAGE_WIDTH) * io_page; 515 540 516 541 tlb_entry_t entry; 517 542 518 543 entry.word[0] = 0; 519 544 entry.word[1] = 0; 520 521 entry.p = true; 522 entry.ma = MA_UNCACHEABLE; 523 entry.a = true; 524 entry.d = true; 545 546 entry.p = true; /* present */ 547 entry.ma = MA_UNCACHEABLE; 548 entry.a = true; /* already accessed */ 549 entry.d = true; /* already dirty */ 525 550 entry.pl = PL_USER; 526 551 entry.ar = AR_READ | AR_WRITE; 527 552 entry.ppn = frame >> PPN_SHIFT; 528 553 entry.ps = USPACE_IO_PAGE_WIDTH; 529 554 530 555 dtc_mapping_insert(page, TASK->as->asid, entry); 531 556 return 1; … … 536 561 } 537 562 } 538 563 539 564 return 0; 540 565 } … … 542 567 /** Data TLB fault handler for faults with VHPT turned off. 543 568 * 544 * @param vector Interruption vector. 545 * @param istate Structure with saved interruption state. 569 * @param vector Interruption vector. 570 * @param istate Structure with saved interruption state. 571 * 546 572 */ 547 573 void alternate_data_tlb_fault(uint64_t vector, istate_t *istate) 548 574 { 549 region_register rr; 550 rid_t rid; 551 uintptr_t va; 552 pte_t *t; 553 554 va = istate->cr_ifa; /* faulting address */ 555 rr.word = rr_read(VA2VRN(va)); 556 rid = rr.map.rid; 575 if (istate->cr_isr.sp) { 576 /* Speculative load. Deffer the exception 577 until a more clever approach can be used. 578 579 Currently if we try to find the mapping 580 for the speculative load while in the kernel, 581 we might introduce a livelock because of 582 the possibly invalid values of the address. */ 583 istate->cr_ipsr.ed = true; 584 return; 585 } 586 587 uintptr_t va = istate->cr_ifa; /* faulting address */ 588 589 region_register_t rr; 590 rr.word = rr_read(VA2VRN(va)); 591 rid_t rid = rr.map.rid; 557 592 if (RID2ASID(rid) == ASID_KERNEL) { 558 593 if (VA2VRN(va) == VRN_KERNEL) { … … 565 600 } 566 601 } 567 602 603 568 604 page_table_lock(AS, true); 569 t= page_mapping_find(AS, va);570 if ( t) {605 pte_t *entry = page_mapping_find(AS, va); 606 if (entry) { 571 607 /* 572 608 * The mapping was found in the software page hash table. 573 609 * Insert it into data translation cache. 574 610 */ 575 dtc_pte_copy( t);611 dtc_pte_copy(entry); 576 612 page_table_unlock(AS, true); 577 613 } else { … … 579 615 if (try_memmap_io_insertion(va, istate)) 580 616 return; 581 /* 582 * Forward the page fault to the address space page fault 617 618 /* 619 * Forward the page fault to the address space page fault 583 620 * handler. 584 621 */ 585 622 if (as_page_fault(va, PF_ACCESS_READ, istate) == AS_PF_FAULT) { 586 fault_if_from_uspace(istate, "Page fault at %p.",va);623 fault_if_from_uspace(istate, "Page fault at %p.", va); 587 624 panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid, 588 625 istate->cr_iip); … … 595 632 * This fault should not occur. 596 633 * 597 * @param vector Interruption vector. 598 * @param istate Structure with saved interruption state. 634 * @param vector Interruption vector. 635 * @param istate Structure with saved interruption state. 636 * 599 637 */ 600 638 void data_nested_tlb_fault(uint64_t vector, istate_t *istate) 601 639 { 602 panic("%s.", __func__);640 ASSERT(false); 603 641 } 604 642 605 643 /** Data Dirty bit fault handler. 606 644 * 607 * @param vector Interruption vector. 608 * @param istate Structure with saved interruption state. 645 * @param vector Interruption vector. 646 * @param istate Structure with saved interruption state. 647 * 609 648 */ 610 649 void data_dirty_bit_fault(uint64_t vector, istate_t *istate) 611 650 { 612 region_register rr;651 region_register_t rr; 613 652 rid_t rid; 614 653 uintptr_t va; 615 654 pte_t *t; 616 655 617 va = istate->cr_ifa; 656 va = istate->cr_ifa; /* faulting address */ 618 657 rr.word = rr_read(VA2VRN(va)); 619 658 rid = rr.map.rid; 620 659 621 660 page_table_lock(AS, true); 622 661 t = page_mapping_find(AS, va); 623 ASSERT( t && t->p);624 if ( t && t->p && t->w) {662 ASSERT((t) && (t->p)); 663 if ((t) && (t->p) && (t->w)) { 625 664 /* 626 665 * Update the Dirty bit in page tables and reinsert … … 631 670 } else { 632 671 if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) { 633 fault_if_from_uspace(istate, "Page fault at %p.",va);672 fault_if_from_uspace(istate, "Page fault at %p.", va); 634 673 panic("%s: va=%p, rid=%d, iip=%p.", __func__, va, rid, 635 674 istate->cr_iip); … … 641 680 /** Instruction access bit fault handler. 642 681 * 643 * @param vector Interruption vector. 644 * @param istate Structure with saved interruption state. 682 * @param vector Interruption vector. 683 * @param istate Structure with saved interruption state. 684 * 645 685 */ 646 686 void instruction_access_bit_fault(uint64_t vector, istate_t *istate) 647 687 { 648 region_register rr;688 region_register_t rr; 649 689 rid_t rid; 650 690 uintptr_t va; 651 pte_t *t; 652 653 va = istate->cr_ifa; 691 pte_t *t; 692 693 va = istate->cr_ifa; /* faulting address */ 654 694 rr.word = rr_read(VA2VRN(va)); 655 695 rid = rr.map.rid; 656 696 657 697 page_table_lock(AS, true); 658 698 t = page_mapping_find(AS, va); 659 ASSERT( t && t->p);660 if ( t && t->p && t->x) {699 ASSERT((t) && (t->p)); 700 if ((t) && (t->p) && (t->x)) { 661 701 /* 662 702 * Update the Accessed bit in page tables and reinsert … … 679 719 * @param vector Interruption vector. 680 720 * @param istate Structure with saved interruption state. 721 * 681 722 */ 682 723 void data_access_bit_fault(uint64_t vector, istate_t *istate) 683 724 { 684 region_register rr;725 region_register_t rr; 685 726 rid_t rid; 686 727 uintptr_t va; 687 728 pte_t *t; 688 689 va = istate->cr_ifa; 729 730 va = istate->cr_ifa; /* faulting address */ 690 731 rr.word = rr_read(VA2VRN(va)); 691 732 rid = rr.map.rid; 692 733 693 734 page_table_lock(AS, true); 694 735 t = page_mapping_find(AS, va); 695 ASSERT( t && t->p);696 if ( t && t->p) {736 ASSERT((t) && (t->p)); 737 if ((t) && (t->p)) { 697 738 /* 698 739 * Update the Accessed bit in page tables and reinsert … … 715 756 * @param vector Interruption vector. 716 757 * @param istate Structure with saved interruption state. 758 * 717 759 */ 718 760 void data_access_rights_fault(uint64_t vector, istate_t *istate) 719 761 { 720 region_register rr;762 region_register_t rr; 721 763 rid_t rid; 722 764 uintptr_t va; 723 765 pte_t *t; 724 725 va = istate->cr_ifa; 766 767 va = istate->cr_ifa; /* faulting address */ 726 768 rr.word = rr_read(VA2VRN(va)); 727 769 rid = rr.map.rid; 728 770 729 771 /* 730 772 * Assume a write to a read-only page. … … 732 774 page_table_lock(AS, true); 733 775 t = page_mapping_find(AS, va); 734 ASSERT( t && t->p);776 ASSERT((t) && (t->p)); 735 777 ASSERT(!t->w); 736 778 if (as_page_fault(va, PF_ACCESS_WRITE, istate) == AS_PF_FAULT) { … … 746 788 * @param vector Interruption vector. 747 789 * @param istate Structure with saved interruption state. 790 * 748 791 */ 749 792 void page_not_present(uint64_t vector, istate_t *istate) 750 793 { 751 region_register rr;794 region_register_t rr; 752 795 rid_t rid; 753 796 uintptr_t va; 754 797 pte_t *t; 755 798 756 va = istate->cr_ifa; 799 va = istate->cr_ifa; /* faulting address */ 757 800 rr.word = rr_read(VA2VRN(va)); 758 801 rid = rr.map.rid; 759 802 760 803 page_table_lock(AS, true); 761 804 t = page_mapping_find(AS, va); -
kernel/arch/ia64/src/mm/vhpt.c
r7e266ff rad4b32c 27 27 */ 28 28 29 /** @addtogroup ia64mm 29 /** @addtogroup ia64mm 30 30 * @{ 31 31 */ … … 44 44 vhpt_base = frame_alloc(VHPT_WIDTH - FRAME_WIDTH, 45 45 FRAME_KA | FRAME_ATOMIC); 46 if (!vhpt_base) 46 if (!vhpt_base) 47 47 panic("Kernel configured with VHPT but no memory for table."); 48 48 vhpt_invalidate_all(); … … 53 53 void vhpt_mapping_insert(uintptr_t va, asid_t asid, tlb_entry_t entry) 54 54 { 55 region_register rr_save, rr;55 region_register_t rr_save, rr; 56 56 size_t vrn; 57 57 rid_t rid; 58 58 uint64_t tag; 59 59 60 60 vhpt_entry_t *ventry; 61 62 61 63 62 vrn = va >> VRN_SHIFT; 64 63 rid = ASID2RID(asid, vrn); 65 64 66 65 rr_save.word = rr_read(vrn); 67 66 rr.word = rr_save.word; … … 75 74 srlz_i(); 76 75 srlz_d(); 77 76 78 77 ventry->word[0] = entry.word[0]; 79 78 ventry->word[1] = entry.word[1]; -
kernel/arch/ia64/src/start.S
r7e266ff rad4b32c 32 32 #include <mm/asid.h> 33 33 34 #define RR_MASK (0xFFFFFFFF00000002)35 #define RID_SHIFT 36 #define PS_SHIFT 37 38 #define KERNEL_TRANSLATION_I 39 #define KERNEL_TRANSLATION_D 40 #define KERNEL_TRANSLATION_VIO 41 #define KERNEL_TRANSLATION_IO 0x00100FFFFC00067142 #define KERNEL_TRANSLATION_FW 0x00100000F000067134 #define RR_MASK (0xFFFFFFFF00000002) 35 #define RID_SHIFT 8 36 #define PS_SHIFT 2 37 38 #define KERNEL_TRANSLATION_I 0x0010000000000661 39 #define KERNEL_TRANSLATION_D 0x0010000000000661 40 #define KERNEL_TRANSLATION_VIO 0x0010000000000671 41 #define KERNEL_TRANSLATION_IO 0x00100FFFFC000671 42 #define KERNEL_TRANSLATION_FW 0x00100000F0000671 43 43 44 44 .section K_TEXT_START, "ax" … … 49 49 kernel_image_start: 50 50 .auto 51 51 52 52 #ifdef CONFIG_SMP 53 53 # Identify self(CPU) in OS structures by ID / EID 54 54 55 55 mov r9 = cr64 56 56 mov r10 = 1 … … 62 62 st1 [r8] = r10 63 63 #endif 64 64 65 65 mov psr.l = r0 66 66 srlz.i 67 67 srlz.d 68 68 69 69 # Fill TR.i and TR.d using Region Register #VRN_KERNEL 70 70 71 71 movl r8 = (VRN_KERNEL << VRN_SHIFT) 72 72 mov r9 = rr[r8] 73 73 74 74 movl r10 = (RR_MASK) 75 75 and r9 = r10, r9 76 76 movl r10 = ((RID_KERNEL << RID_SHIFT) | (KERNEL_PAGE_WIDTH << PS_SHIFT)) 77 or 78 77 or r9 = r10, r9 78 79 79 mov rr[r8] = r9 80 80 81 81 movl r8 = (VRN_KERNEL << VRN_SHIFT) 82 82 mov cr.ifa = r8 83 83 84 84 mov r11 = cr.itir 85 85 movl r10 = (KERNEL_PAGE_WIDTH << PS_SHIFT) 86 86 or r10 = r10, r11 87 87 mov cr.itir = r10 88 88 89 89 movl r10 = (KERNEL_TRANSLATION_I) 90 90 itr.i itr[r0] = r10 91 91 movl r10 = (KERNEL_TRANSLATION_D) 92 92 itr.d dtr[r0] = r10 93 93 94 94 movl r7 = 1 95 95 movl r8 = (VRN_KERNEL << VRN_SHIFT) | VIO_OFFSET … … 97 97 movl r10 = (KERNEL_TRANSLATION_VIO) 98 98 itr.d dtr[r7] = r10 99 99 100 100 mov r11 = cr.itir 101 101 movl r10 = ~0xfc … … 104 104 or r10 = r10, r11 105 105 mov cr.itir = r10 106 106 107 107 movl r7 = 2 108 108 movl r8 = (VRN_KERNEL << VRN_SHIFT) | IO_OFFSET … … 110 110 movl r10 = (KERNEL_TRANSLATION_IO) 111 111 itr.d dtr[r7] = r10 112 113 # Setup mapping for fi mware arrea (also SAPIC)114 112 113 # Setup mapping for firmware area (also SAPIC) 114 115 115 mov r11 = cr.itir 116 116 movl r10 = ~0xfc … … 119 119 or r10 = r10, r11 120 120 mov cr.itir = r10 121 121 122 122 movl r7 = 3 123 123 movl r8 = (VRN_KERNEL << VRN_SHIFT) | FW_OFFSET … … 125 125 movl r10 = (KERNEL_TRANSLATION_FW) 126 126 itr.d dtr[r7] = r10 127 127 128 # Initialize DSR 129 130 movl r10 = (DCR_DP_MASK | DCR_DK_MASK | DCR_DX_MASK | DCR_DR_MASK | DCR_DA_MASK | DCR_DD_MASK | DCR_LC_MASK) 131 mov r9 = cr.dcr 132 or r10 = r10, r9 133 mov cr.dcr = r10 134 128 135 # Initialize PSR 129 136 130 137 movl r10 = (PSR_DT_MASK | PSR_RT_MASK | PSR_IT_MASK | PSR_IC_MASK) /* Enable paging */ 131 138 mov r9 = psr 132 139 133 140 or r10 = r10, r9 134 141 mov cr.ipsr = r10 … … 138 145 srlz.d 139 146 srlz.i 140 147 141 148 .explicit 142 149 143 150 /* 144 151 * Return From Interrupt is the only way to … … 147 154 rfi ;; 148 155 149 150 156 .global paging_start 151 157 paging_start: 152 158 153 159 /* 154 160 * Now we are paging. 155 161 */ 156 162 157 163 # Switch to register bank 1 158 164 bsw.1 159 165 160 166 #ifdef CONFIG_SMP 161 167 # Am I BSP or AP? … … 164 170 cmp.eq p3, p2 = r20, r0 ;; 165 171 #else 166 cmp.eq p3, p2 = r0, r0 ;; 167 #endif 172 cmp.eq p3, p2 = r0, r0 ;; /* you are BSP */ 173 #endif /* CONFIG_SMP */ 168 174 169 175 # Initialize register stack … … 172 178 mov ar.bspstore = r8 173 179 loadrs 174 180 175 181 # Initialize memory stack to some sane value 176 182 movl r12 = stack0 ;; 177 add r12 = -16, r12 178 183 add r12 = -16, r12 /* allocate a scratch area on the stack */ 184 179 185 # Initialize gp (Global Pointer) register 180 movl r20 = (VRN_KERNEL << VRN_SHIFT) ;;181 or r20 = r20, r1;;186 movl r20 = (VRN_KERNEL << VRN_SHIFT) ;; 187 or r20 = r20, r1 ;; 182 188 movl r1 = _hardcoded_load_address 183 189 … … 192 198 (p3) addl r19 = @gprel(hardcoded_load_address), gp 193 199 (p3) addl r21 = @gprel(bootinfo), gp 194 ;;200 ;; 195 201 (p3) st8 [r17] = r14 196 202 (p3) st8 [r18] = r15 197 203 (p3) st8 [r19] = r16 198 204 (p3) st8 [r21] = r20 199 205 200 206 ssm (1 << 19) ;; /* Disable f32 - f127 */ 201 207 srlz.i 202 208 srlz.d ;; 203 209 204 210 #ifdef CONFIG_SMP 205 211 (p2) movl r18 = main_ap ;; 206 (p2) 212 (p2) mov b1 = r18 ;; 207 213 (p2) br.call.sptk.many b0 = b1 208 214 209 215 # Mark that BSP is on 216 210 217 mov r20 = 1 ;; 211 218 movl r21 = bsp_started ;; 212 219 st8 [r21] = r20 ;; 213 220 #endif 214 221 215 222 br.call.sptk.many b0 = arch_pre_main 216 223 217 224 movl r18 = main_bsp ;; 218 225 mov b1 = r18 ;; … … 227 234 kernel_image_ap_start: 228 235 .auto 229 236 230 237 # Identify self(CPU) in OS structures by ID / EID 231 238 232 239 mov r9 = cr64 233 240 mov r10 = 1 … … 240 247 241 248 # Wait for wakeup synchro signal (#3 in cpu_by_id_eid_list) 242 249 243 250 kernel_image_ap_start_loop: 244 251 movl r11 = kernel_image_ap_start_loop 245 252 and r11 = r11, r12 246 mov b1 = r11 247 248 ld1 r20 = [r8] ;;249 movl r21 = 3 ;;250 cmp.eq p2, p3 = r20, r21 ;;253 mov b1 = r11 254 255 ld1 r20 = [r8] 256 movl r21 = 3 257 cmp.eq p2, p3 = r20, r21 251 258 (p3) br.call.sptk.many b0 = b1 252 259 253 260 movl r11 = kernel_image_start 254 261 and r11 = r11, r12 255 mov b1 = r11 262 mov b1 = r11 256 263 br.call.sptk.many b0 = b1 257 264 … … 259 266 .global bsp_started 260 267 bsp_started: 261 .space 8268 .space 8 262 269 263 270 .align 4096 264 271 .global cpu_by_id_eid_list 265 272 cpu_by_id_eid_list: 266 .space 65536267 268 #endif 273 .space 65536 274 275 #endif /* CONFIG_SMP */ -
kernel/arch/mips32/include/mm/tlb.h
r7e266ff rad4b32c 59 59 typedef union { 60 60 struct { 61 #ifdef BIG_ENDIAN61 #ifdef __BE__ 62 62 unsigned : 2; /* zero */ 63 63 unsigned pfn : 24; /* frame number */ … … 80 80 typedef union { 81 81 struct { 82 #ifdef BIG_ENDIAN82 #ifdef __BE__ 83 83 unsigned vpn2 : 19; 84 84 unsigned : 5; … … 95 95 typedef union { 96 96 struct { 97 #ifdef BIG_ENDIAN97 #ifdef __BE__ 98 98 unsigned : 7; 99 99 unsigned mask : 12; … … 110 110 typedef union { 111 111 struct { 112 #ifdef BIG_ENDIAN112 #ifdef __BE__ 113 113 unsigned p : 1; 114 114 unsigned : 27; -
uspace/app/bdsh/cmds/modules/bdd/bdd.c
r7e266ff rad4b32c 112 112 while (size > 0) { 113 113 rc = block_get(&block, handle, boff, 0); 114 assert(rc == EOK); 114 if (rc != EOK) { 115 printf("Error: could not get block %u, device %u.\n", 116 boff, handle); 117 return CMD_FAILURE; 118 } 115 119 blk = (uint8_t *) block->data; 116 120 … … 142 146 143 147 rc = block_put(block); 144 assert(rc == EOK); 148 if (rc != EOK) { 149 printf("Error: could not put block %p.\n", 150 block); 151 return CMD_FAILURE; 152 } 145 153 146 154 if (size > rows * BPR) -
uspace/lib/libblock/libblock.c
r7e266ff rad4b32c 345 345 link_t *l; 346 346 unsigned long key = boff; 347 int rc = EOK;347 int rc; 348 348 349 349 devcon = devcon_search(dev_handle); … … 355 355 356 356 retry: 357 rc = EOK; 358 b = NULL; 359 357 360 fibril_mutex_lock(&cache->lock); 358 361 l = hash_table_find(&cache->block_hash, &key); … … 394 397 unsigned long temp_key; 395 398 recycle: 396 assert(!list_empty(&cache->free_head)); 399 if (list_empty(&cache->free_head)) { 400 fibril_mutex_unlock(&cache->lock); 401 rc = ENOMEM; 402 goto out; 403 } 397 404 l = cache->free_head.next; 398 405 b = list_get_instance(l, block_t, free_link); … … 477 484 478 485 fibril_mutex_unlock(&b->lock); 486 } 487 out: 488 if ((rc != EOK) && b) { 489 assert(b->toxic); 490 (void) block_put(b); 491 b = NULL; 479 492 } 480 493 *block = b; -
uspace/lib/libc/arch/ia64/include/atomic.h
r7e266ff rad4b32c 27 27 */ 28 28 29 /** @addtogroup libcia64 29 /** @addtogroup libcia64 30 30 * @{ 31 31 */ … … 36 36 #define LIBC_ia64_ATOMIC_H_ 37 37 38 /** Atomic addition. 39 * 40 * @param val Atomic value. 41 * @param imm Value to add. 42 * 43 * @return Value before addition. 44 */ 45 static inline long atomic_add(atomic_t *val, int imm) 38 static inline void atomic_inc(atomic_t *val) 46 39 { 47 40 long v; 41 42 asm volatile ( 43 "fetchadd8.rel %[v] = %[count], 1\n" 44 : [v] "=r" (v), 45 [count] "+m" (val->count) 46 ); 47 } 48 48 49 asm volatile ("fetchadd8.rel %0 = %1, %2\n" : "=r" (v), "+m" (val->count) : "i" (imm)); 50 49 static inline void atomic_dec(atomic_t *val) 50 { 51 long v; 52 53 asm volatile ( 54 "fetchadd8.rel %[v] = %[count], -1\n" 55 : [v] "=r" (v), 56 [count] "+m" (val->count) 57 ); 58 } 59 60 static inline long atomic_preinc(atomic_t *val) 61 { 62 long v; 63 64 asm volatile ( 65 "fetchadd8.rel %[v] = %[count], 1\n" 66 : [v] "=r" (v), 67 [count] "+m" (val->count) 68 ); 69 70 return (v + 1); 71 } 72 73 static inline long atomic_predec(atomic_t *val) 74 { 75 long v; 76 77 asm volatile ( 78 "fetchadd8.rel %[v] = %[count], -1\n" 79 : [v] "=r" (v), 80 [count] "+m" (val->count) 81 ); 82 83 return (v - 1); 84 } 85 86 static inline long atomic_postinc(atomic_t *val) 87 { 88 long v; 89 90 asm volatile ( 91 "fetchadd8.rel %[v] = %[count], 1\n" 92 : [v] "=r" (v), 93 [count] "+m" (val->count) 94 ); 95 51 96 return v; 52 97 } 53 98 54 static inline void atomic_inc(atomic_t *val) { atomic_add(val, 1); } 55 static inline void atomic_dec(atomic_t *val) { atomic_add(val, -1); } 56 57 static inline long atomic_preinc(atomic_t *val) { return atomic_add(val, 1) + 1; } 58 static inline long atomic_predec(atomic_t *val) { return atomic_add(val, -1) - 1; } 59 60 static inline long atomic_postinc(atomic_t *val) { return atomic_add(val, 1); } 61 static inline long atomic_postdec(atomic_t *val) { return atomic_add(val, -1); } 99 static inline long atomic_postdec(atomic_t *val) 100 { 101 long v; 102 103 asm volatile ( 104 "fetchadd8.rel %[v] = %[count], -1\n" 105 : [v] "=r" (v), 106 [count] "+m" (val->count) 107 ); 108 109 return v; 110 } 62 111 63 112 #endif -
uspace/srv/fs/fat/fat_fat.c
r7e266ff rad4b32c 61 61 * @param dev_handle Device handle of the device with the file. 62 62 * @param firstc First cluster to start the walk with. 63 * @param lastc If non-NULL, output argument hodling the last cluster number visited. 63 * @param lastc If non-NULL, output argument hodling the last cluster 64 * number visited. 65 * @param numc If non-NULL, output argument holding the number of 66 * clusters seen during the walk. 64 67 * @param max_clusters Maximum number of clusters to visit. 65 68 * 66 * @return Number of clusters seen during the walk.67 */ 68 uint16_t69 * @return EOK on success or a negative error code. 70 */ 71 int 69 72 fat_cluster_walk(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc, 70 fat_cluster_t *lastc, uint16_t max_clusters)73 fat_cluster_t *lastc, uint16_t *numc, uint16_t max_clusters) 71 74 { 72 75 block_t *b; … … 84 87 if (lastc) 85 88 *lastc = firstc; 86 return 0; 89 if (numc) 90 *numc = 0; 91 return EOK; 87 92 } 88 93 … … 98 103 /* read FAT1 */ 99 104 rc = block_get(&b, dev_handle, rscnt + fsec, BLOCK_FLAGS_NONE); 100 assert(rc == EOK); 105 if (rc != EOK) 106 return rc; 101 107 clst = uint16_t_le2host(((fat_cluster_t *)b->data)[fidx]); 102 108 assert(clst != FAT_CLST_BAD); 103 109 rc = block_put(b); 104 assert(rc == EOK); 110 if (rc != EOK) 111 return rc; 105 112 clusters++; 106 113 } … … 108 115 if (lastc && clst < FAT_CLST_LAST1) 109 116 *lastc = clst; 110 111 return clusters; 117 if (numc) 118 *numc = clusters; 119 120 return EOK; 112 121 } 113 122 114 123 /** Read block from file located on a FAT file system. 115 124 * 125 * @param block Pointer to a block pointer for storing result. 116 126 * @param bs Buffer holding the boot sector of the file system. 117 127 * @param dev_handle Device handle of the file system. … … 121 131 * @param flags Flags passed to libblock. 122 132 * 123 * @return Block structure holding the requested block. 124 */ 125 block_t * 126 _fat_block_get(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc, 127 bn_t bn, int flags) 128 { 129 block_t *b; 133 * @return EOK on success or a negative error code. 134 */ 135 int 136 _fat_block_get(block_t **block, fat_bs_t *bs, dev_handle_t dev_handle, 137 fat_cluster_t firstc, bn_t bn, int flags) 138 { 130 139 unsigned bps; 131 140 unsigned rscnt; /* block address of the first FAT */ … … 134 143 unsigned sf; 135 144 unsigned ssa; /* size of the system area */ 136 unsigned clusters, max_clusters; 145 uint16_t clusters; 146 unsigned max_clusters; 137 147 fat_cluster_t lastc; 138 148 int rc; … … 150 160 /* root directory special case */ 151 161 assert(bn < rds); 152 rc = block_get( &b, dev_handle, rscnt + bs->fatcnt * sf + bn,162 rc = block_get(block, dev_handle, rscnt + bs->fatcnt * sf + bn, 153 163 flags); 154 assert(rc == EOK); 155 return b; 164 return rc; 156 165 } 157 166 158 167 max_clusters = bn / bs->spc; 159 clusters = fat_cluster_walk(bs, dev_handle, firstc, &lastc,168 rc = fat_cluster_walk(bs, dev_handle, firstc, &lastc, &clusters, 160 169 max_clusters); 170 if (rc != EOK) 171 return rc; 161 172 assert(clusters == max_clusters); 162 173 163 rc = block_get(&b, dev_handle, ssa + 164 (lastc - FAT_CLST_FIRST) * bs->spc + bn % bs->spc, flags); 165 assert(rc == EOK); 166 167 return b; 174 rc = block_get(block, dev_handle, 175 ssa + (lastc - FAT_CLST_FIRST) * bs->spc + bn % bs->spc, flags); 176 177 return rc; 168 178 } 169 179 … … 177 187 * this argument is ignored. 178 188 * @param pos Position in the last node block. 179 */ 180 void fat_fill_gap(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl, off_t pos) 189 * 190 * @return EOK on success or a negative error code. 191 */ 192 int fat_fill_gap(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl, off_t pos) 181 193 { 182 194 uint16_t bps; … … 196 208 int flags = (o % bps == 0) ? 197 209 BLOCK_FLAGS_NOREAD : BLOCK_FLAGS_NONE; 198 b = fat_block_get(bs, nodep, o / bps, flags); 210 rc = fat_block_get(&b, bs, nodep, o / bps, flags); 211 if (rc != EOK) 212 return rc; 199 213 memset(b->data + o % bps, 0, bps - o % bps); 200 214 b->dirty = true; /* need to sync node */ 201 215 rc = block_put(b); 202 assert(rc == EOK); 216 if (rc != EOK) 217 return rc; 203 218 } 204 219 205 220 if (o >= pos) 206 return ;221 return EOK; 207 222 208 223 /* zero out the initial part of the new cluster chain */ 209 224 for (o = boundary; o < pos; o += bps) { 210 b = _fat_block_get(bs, nodep->idx->dev_handle, mcl,225 rc = _fat_block_get(&b, bs, nodep->idx->dev_handle, mcl, 211 226 (o - boundary) / bps, BLOCK_FLAGS_NOREAD); 227 if (rc != EOK) 228 return rc; 212 229 memset(b->data, 0, min(bps, pos - o)); 213 230 b->dirty = true; /* need to sync node */ 214 231 rc = block_put(b); 215 assert(rc == EOK); 216 } 232 if (rc != EOK) 233 return rc; 234 } 235 236 return EOK; 217 237 } 218 238 … … 222 242 * @param dev_handle Device handle for the file system. 223 243 * @param clst Cluster which to get. 224 * 225 * @return Value found in the cluster. 226 */ 227 fat_cluster_t 228 fat_get_cluster(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t clst) 244 * @param value Output argument holding the value of the cluster. 245 * 246 * @return EOK or a negative error code. 247 */ 248 int 249 fat_get_cluster(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t clst, 250 fat_cluster_t *value) 229 251 { 230 252 block_t *b; 231 253 uint16_t bps; 232 254 uint16_t rscnt; 233 fat_cluster_t *cp , value;255 fat_cluster_t *cp; 234 256 int rc; 235 257 … … 239 261 rc = block_get(&b, dev_handle, rscnt + 240 262 (clst * sizeof(fat_cluster_t)) / bps, BLOCK_FLAGS_NONE); 241 assert(rc == EOK); 263 if (rc != EOK) 264 return rc; 242 265 cp = (fat_cluster_t *)b->data + clst % (bps / sizeof(fat_cluster_t)); 243 value = uint16_t_le2host(*cp);266 *value = uint16_t_le2host(*cp); 244 267 rc = block_put(b); 245 assert(rc == EOK); 246 247 return value; 268 269 return rc; 248 270 } 249 271 … … 255 277 * @param clst Cluster which is to be set. 256 278 * @param value Value to set the cluster with. 257 */ 258 void 279 * 280 * @return EOK on success or a negative error code. 281 */ 282 int 259 283 fat_set_cluster(fat_bs_t *bs, dev_handle_t dev_handle, unsigned fatno, 260 284 fat_cluster_t clst, fat_cluster_t value) … … 274 298 rc = block_get(&b, dev_handle, rscnt + sf * fatno + 275 299 (clst * sizeof(fat_cluster_t)) / bps, BLOCK_FLAGS_NONE); 276 assert(rc == EOK); 300 if (rc != EOK) 301 return rc; 277 302 cp = (fat_cluster_t *)b->data + clst % (bps / sizeof(fat_cluster_t)); 278 303 *cp = host2uint16_t_le(value); 279 304 b->dirty = true; /* need to sync block */ 280 305 rc = block_put(b); 281 assert(rc == EOK);306 return rc; 282 307 } 283 308 … … 288 313 * @param lifo Chain of allocated clusters. 289 314 * @param nclsts Number of clusters in the lifo chain. 290 */ 291 void fat_alloc_shadow_clusters(fat_bs_t *bs, dev_handle_t dev_handle, 315 * 316 * @return EOK on success or a negative error code. 317 */ 318 int fat_alloc_shadow_clusters(fat_bs_t *bs, dev_handle_t dev_handle, 292 319 fat_cluster_t *lifo, unsigned nclsts) 293 320 { 294 321 uint8_t fatno; 295 322 unsigned c; 323 int rc; 296 324 297 325 for (fatno = FAT1 + 1; fatno < bs->fatcnt; fatno++) { 298 326 for (c = 0; c < nclsts; c++) { 299 fat_set_cluster(bs, dev_handle, fatno, lifo[c],327 rc = fat_set_cluster(bs, dev_handle, fatno, lifo[c], 300 328 c == 0 ? FAT_CLST_LAST1 : lifo[c - 1]); 329 if (rc != EOK) 330 return rc; 301 331 } 302 332 } 333 334 return EOK; 303 335 } 304 336 … … 347 379 for (b = 0, cl = 0; b < sf; b++) { 348 380 rc = block_get(&blk, dev_handle, rscnt + b, BLOCK_FLAGS_NONE); 381 if (rc != EOK) 382 goto error; 349 383 for (c = 0; c < bps / sizeof(fat_cluster_t); c++, cl++) { 350 384 fat_cluster_t *clst = (fat_cluster_t *)blk->data + c; … … 362 396 /* we are almost done */ 363 397 rc = block_put(blk); 364 assert(rc == EOK); 398 if (rc != EOK) 399 goto error; 365 400 /* update the shadow copies of FAT */ 366 fat_alloc_shadow_clusters(bs,401 rc = fat_alloc_shadow_clusters(bs, 367 402 dev_handle, lifo, nclsts); 403 if (rc != EOK) 404 goto error; 368 405 *mcl = lifo[found - 1]; 369 406 *lcl = lifo[0]; … … 375 412 } 376 413 rc = block_put(blk); 377 assert(rc == EOK); 414 if (rc != EOK) { 415 error: 416 fibril_mutex_unlock(&fat_alloc_lock); 417 free(lifo); 418 return rc; 419 } 378 420 } 379 421 fibril_mutex_unlock(&fat_alloc_lock); … … 384 426 */ 385 427 while (found--) { 386 fat_set_cluster(bs, dev_handle, FAT1, lifo[found],428 rc = fat_set_cluster(bs, dev_handle, FAT1, lifo[found], 387 429 FAT_CLST_RES0); 430 if (rc != EOK) { 431 free(lifo); 432 return rc; 433 } 388 434 } 389 435 … … 397 443 * @param dev_handle Device handle of the file system. 398 444 * @param firstc First cluster in the chain which is to be freed. 399 */ 400 void 445 * 446 * @return EOK on success or a negative return code. 447 */ 448 int 401 449 fat_free_clusters(fat_bs_t *bs, dev_handle_t dev_handle, fat_cluster_t firstc) 402 450 { 403 451 unsigned fatno; 404 452 fat_cluster_t nextc; 453 int rc; 405 454 406 455 /* Mark all clusters in the chain as free in all copies of FAT. */ 407 456 while (firstc < FAT_CLST_LAST1) { 408 457 assert(firstc >= FAT_CLST_FIRST && firstc < FAT_CLST_BAD); 409 nextc = fat_get_cluster(bs, dev_handle, firstc); 410 for (fatno = FAT1; fatno < bs->fatcnt; fatno++) 411 fat_set_cluster(bs, dev_handle, fatno, firstc, 458 rc = fat_get_cluster(bs, dev_handle, firstc, &nextc); 459 if (rc != EOK) 460 return rc; 461 for (fatno = FAT1; fatno < bs->fatcnt; fatno++) { 462 rc = fat_set_cluster(bs, dev_handle, fatno, firstc, 412 463 FAT_CLST_RES0); 464 if (rc != EOK) 465 return rc; 466 } 467 413 468 firstc = nextc; 414 469 } 470 471 return EOK; 415 472 } 416 473 … … 420 477 * @param nodep Node representing the file. 421 478 * @param mcl First cluster of the cluster chain to append. 422 */ 423 void fat_append_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl) 479 * 480 * @return EOK on success or a negative error code. 481 */ 482 int fat_append_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t mcl) 424 483 { 425 484 dev_handle_t dev_handle = nodep->idx->dev_handle; 426 485 fat_cluster_t lcl; 486 uint16_t numc; 427 487 uint8_t fatno; 428 429 if (fat_cluster_walk(bs, dev_handle, nodep->firstc, &lcl, 430 (uint16_t) -1) == 0) { 488 int rc; 489 490 rc = fat_cluster_walk(bs, dev_handle, nodep->firstc, &lcl, &numc, 491 (uint16_t) -1); 492 if (rc != EOK) 493 return rc; 494 495 if (numc == 0) { 431 496 /* No clusters allocated to the node yet. */ 432 497 nodep->firstc = mcl; 433 498 nodep->dirty = true; /* need to sync node */ 434 return; 435 } 436 437 for (fatno = FAT1; fatno < bs->fatcnt; fatno++) 438 fat_set_cluster(bs, nodep->idx->dev_handle, fatno, lcl, mcl); 499 return EOK; 500 } 501 502 for (fatno = FAT1; fatno < bs->fatcnt; fatno++) { 503 rc = fat_set_cluster(bs, nodep->idx->dev_handle, fatno, lcl, 504 mcl); 505 if (rc != EOK) 506 return rc; 507 } 508 509 return EOK; 439 510 } 440 511 … … 446 517 * argument is FAT_CLST_RES0, then all clusters will 447 518 * be chopped off. 448 */ 449 void fat_chop_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t lastc) 450 { 519 * 520 * @return EOK on success or a negative return code. 521 */ 522 int fat_chop_clusters(fat_bs_t *bs, fat_node_t *nodep, fat_cluster_t lastc) 523 { 524 int rc; 525 451 526 dev_handle_t dev_handle = nodep->idx->dev_handle; 452 527 if (lastc == FAT_CLST_RES0) { 453 528 /* The node will have zero size and no clusters allocated. */ 454 fat_free_clusters(bs, dev_handle, nodep->firstc); 529 rc = fat_free_clusters(bs, dev_handle, nodep->firstc); 530 if (rc != EOK) 531 return rc; 455 532 nodep->firstc = FAT_CLST_RES0; 456 533 nodep->dirty = true; /* need to sync node */ … … 459 536 unsigned fatno; 460 537 461 nextc = fat_get_cluster(bs, dev_handle, lastc); 538 rc = fat_get_cluster(bs, dev_handle, lastc, &nextc); 539 if (rc != EOK) 540 return rc; 462 541 463 542 /* Terminate the cluster chain in all copies of FAT. */ 464 for (fatno = FAT1; fatno < bs->fatcnt; fatno++) 465 fat_set_cluster(bs, dev_handle, fatno, lastc, FAT_CLST_LAST1); 543 for (fatno = FAT1; fatno < bs->fatcnt; fatno++) { 544 rc = fat_set_cluster(bs, dev_handle, fatno, lastc, 545 FAT_CLST_LAST1); 546 if (rc != EOK) 547 return rc; 548 } 466 549 467 550 /* Free all following clusters. */ 468 fat_free_clusters(bs, dev_handle, nextc); 469 } 470 } 471 472 void 551 rc = fat_free_clusters(bs, dev_handle, nextc); 552 if (rc != EOK) 553 return rc; 554 } 555 556 return EOK; 557 } 558 559 int 473 560 fat_zero_cluster(struct fat_bs *bs, dev_handle_t dev_handle, fat_cluster_t c) 474 561 { … … 481 568 482 569 for (i = 0; i < bs->spc; i++) { 483 b = _fat_block_get(bs, dev_handle, c, i, BLOCK_FLAGS_NOREAD); 570 rc = _fat_block_get(&b, bs, dev_handle, c, i, 571 BLOCK_FLAGS_NOREAD); 572 if (rc != EOK) 573 return rc; 484 574 memset(b->data, 0, bps); 485 575 b->dirty = true; 486 576 rc = block_put(b); 487 assert(rc == EOK); 488 } 577 if (rc != EOK) 578 return rc; 579 } 580 581 return EOK; 489 582 } 490 583 -
uspace/srv/fs/fat/fat_fat.h
r7e266ff rad4b32c 59 59 typedef uint16_t fat_cluster_t; 60 60 61 #define fat_clusters_get( bs, dh, fc) \62 fat_cluster_walk((bs), (dh), (fc), NULL, ( uint16_t) -1)63 extern uint16_t fat_cluster_walk(struct fat_bs *, dev_handle_t, fat_cluster_t,64 fat_cluster_t *, uint16_t );61 #define fat_clusters_get(numc, bs, dh, fc) \ 62 fat_cluster_walk((bs), (dh), (fc), NULL, (numc), (uint16_t) -1) 63 extern int fat_cluster_walk(struct fat_bs *, dev_handle_t, fat_cluster_t, 64 fat_cluster_t *, uint16_t *, uint16_t); 65 65 66 #define fat_block_get(bs, np, bn, flags) \ 67 _fat_block_get((bs), (np)->idx->dev_handle, (np)->firstc, (bn), (flags)) 66 #define fat_block_get(b, bs, np, bn, flags) \ 67 _fat_block_get((b), (bs), (np)->idx->dev_handle, (np)->firstc, (bn), \ 68 (flags)) 68 69 69 extern struct block *_fat_block_get(struct fat_bs *, dev_handle_t,70 extern int _fat_block_get(block_t **, struct fat_bs *, dev_handle_t, 70 71 fat_cluster_t, bn_t, int); 71 72 72 extern voidfat_append_clusters(struct fat_bs *, struct fat_node *,73 extern int fat_append_clusters(struct fat_bs *, struct fat_node *, 73 74 fat_cluster_t); 74 extern voidfat_chop_clusters(struct fat_bs *, struct fat_node *,75 extern int fat_chop_clusters(struct fat_bs *, struct fat_node *, 75 76 fat_cluster_t); 76 77 extern int fat_alloc_clusters(struct fat_bs *, dev_handle_t, unsigned, 77 78 fat_cluster_t *, fat_cluster_t *); 78 extern voidfat_free_clusters(struct fat_bs *, dev_handle_t, fat_cluster_t);79 extern voidfat_alloc_shadow_clusters(struct fat_bs *, dev_handle_t,79 extern int fat_free_clusters(struct fat_bs *, dev_handle_t, fat_cluster_t); 80 extern int fat_alloc_shadow_clusters(struct fat_bs *, dev_handle_t, 80 81 fat_cluster_t *, unsigned); 81 extern fat_cluster_t fat_get_cluster(struct fat_bs *, dev_handle_t, fat_cluster_t); 82 extern void fat_set_cluster(struct fat_bs *, dev_handle_t, unsigned, 82 extern int fat_get_cluster(struct fat_bs *, dev_handle_t, fat_cluster_t, 83 fat_cluster_t *); 84 extern int fat_set_cluster(struct fat_bs *, dev_handle_t, unsigned, 83 85 fat_cluster_t, fat_cluster_t); 84 extern voidfat_fill_gap(struct fat_bs *, struct fat_node *, fat_cluster_t,86 extern int fat_fill_gap(struct fat_bs *, struct fat_node *, fat_cluster_t, 85 87 off_t); 86 extern voidfat_zero_cluster(struct fat_bs *, dev_handle_t, fat_cluster_t);88 extern int fat_zero_cluster(struct fat_bs *, dev_handle_t, fat_cluster_t); 87 89 88 90 #endif -
uspace/srv/fs/fat/fat_ops.c
r7e266ff rad4b32c 94 94 95 95 /* Read the block that contains the dentry of interest. */ 96 b = _fat_block_get(bs, node->idx->dev_handle, node->idx->pfc,96 rc = _fat_block_get(&b, bs, node->idx->dev_handle, node->idx->pfc, 97 97 (node->idx->pdi * sizeof(fat_dentry_t)) / bps, BLOCK_FLAGS_NONE); 98 assert(rc == EOK); 98 99 99 100 d = ((fat_dentry_t *)b->data) + (node->idx->pdi % dps); … … 202 203 203 204 /* Read the block that contains the dentry of interest. */ 204 b = _fat_block_get(bs, idxp->dev_handle, idxp->pfc,205 rc = _fat_block_get(&b, bs, idxp->dev_handle, idxp->pfc, 205 206 (idxp->pdi * sizeof(fat_dentry_t)) / bps, BLOCK_FLAGS_NONE); 206 assert( b);207 assert(rc == EOK); 207 208 208 209 d = ((fat_dentry_t *)b->data) + (idxp->pdi % dps); … … 219 220 * size of the directory by walking the FAT. 220 221 */ 221 nodep->size = bps * spc * fat_clusters_get(bs, idxp->dev_handle, 222 uint16_t clusters; 223 rc = fat_clusters_get(&clusters, bs, idxp->dev_handle, 222 224 uint16_t_le2host(d->firstc)); 225 assert(rc == EOK); 226 nodep->size = bps * spc * clusters; 223 227 } else { 224 228 nodep->type = FAT_FILE; … … 325 329 nodep = fat_node_get_new(); 326 330 if (!nodep) { 327 fat_free_clusters(bs, dev_handle, mcl);331 (void) fat_free_clusters(bs, dev_handle, mcl); 328 332 return NULL; 329 333 } 330 334 idxp = fat_idx_get_new(dev_handle); 331 335 if (!idxp) { 332 fat_free_clusters(bs, dev_handle, mcl);336 (void) fat_free_clusters(bs, dev_handle, mcl); 333 337 fat_node_put(FS_NODE(nodep)); 334 338 return NULL; … … 337 341 if (flags & L_DIRECTORY) { 338 342 /* Populate the new cluster with unused dentries. */ 339 fat_zero_cluster(bs, dev_handle, mcl); 343 rc = fat_zero_cluster(bs, dev_handle, mcl); 344 assert(rc == EOK); 340 345 nodep->type = FAT_DIRECTORY; 341 346 nodep->firstc = mcl; … … 361 366 fat_node_t *nodep = FAT_NODE(fn); 362 367 fat_bs_t *bs; 368 int rc = EOK; 363 369 364 370 /* … … 379 385 assert(nodep->size); 380 386 /* Free all clusters allocated to the node. */ 381 fat_free_clusters(bs, nodep->idx->dev_handle, nodep->firstc); 387 rc = fat_free_clusters(bs, nodep->idx->dev_handle, 388 nodep->firstc); 382 389 } 383 390 … … 385 392 free(nodep->bp); 386 393 free(nodep); 387 return EOK;394 return rc; 388 395 } 389 396 … … 433 440 434 441 for (i = 0; i < blocks; i++) { 435 b = fat_block_get(bs, parentp, i, BLOCK_FLAGS_NONE); 442 rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE); 443 assert(rc == EOK); 436 444 for (j = 0; j < dps; j++) { 437 445 d = ((fat_dentry_t *)b->data) + j; … … 465 473 return rc; 466 474 } 467 fat_zero_cluster(bs, parentp->idx->dev_handle, mcl); 468 fat_append_clusters(bs, parentp, mcl); 475 rc = fat_zero_cluster(bs, parentp->idx->dev_handle, mcl); 476 assert(rc == EOK); 477 rc = fat_append_clusters(bs, parentp, mcl); 478 assert(rc == EOK); 469 479 parentp->size += bps * bs->spc; 470 480 parentp->dirty = true; /* need to sync node */ 471 b = fat_block_get(bs, parentp, i, BLOCK_FLAGS_NONE); 481 rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE); 482 assert(rc == EOK); 472 483 d = (fat_dentry_t *)b->data; 473 484 … … 494 505 * not use them anyway, so this is rather a sign of our good will. 495 506 */ 496 b = fat_block_get(bs, childp, 0, BLOCK_FLAGS_NONE); 507 rc = fat_block_get(&b, bs, childp, 0, BLOCK_FLAGS_NONE); 508 assert(rc == EOK); 497 509 d = (fat_dentry_t *)b->data; 498 510 if (fat_classify_dentry(d) == FAT_DENTRY_LAST || … … 561 573 bps = uint16_t_le2host(bs->bps); 562 574 563 b = _fat_block_get(bs, childp->idx->dev_handle, childp->idx->pfc,575 rc = _fat_block_get(&b, bs, childp->idx->dev_handle, childp->idx->pfc, 564 576 (childp->idx->pdi * sizeof(fat_dentry_t)) / bps, 565 577 BLOCK_FLAGS_NONE); 578 assert(rc == EOK); 566 579 d = (fat_dentry_t *)b->data + 567 580 (childp->idx->pdi % (bps / sizeof(fat_dentry_t))); … … 605 618 blocks = parentp->size / bps; 606 619 for (i = 0; i < blocks; i++) { 607 b = fat_block_get(bs, parentp, i, BLOCK_FLAGS_NONE); 620 rc = fat_block_get(&b, bs, parentp, i, BLOCK_FLAGS_NONE); 621 assert(rc == EOK); 608 622 for (j = 0; j < dps; j++) { 609 623 d = ((fat_dentry_t *)b->data) + j; … … 698 712 fat_dentry_t *d; 699 713 700 b = fat_block_get(bs, nodep, i, BLOCK_FLAGS_NONE); 714 rc = fat_block_get(&b, bs, nodep, i, BLOCK_FLAGS_NONE); 715 assert(rc == EOK); 701 716 for (j = 0; j < dps; j++) { 702 717 d = ((fat_dentry_t *)b->data) + j; … … 953 968 bytes = min(len, bps - pos % bps); 954 969 bytes = min(bytes, nodep->size - pos); 955 b = fat_block_get(bs, nodep, pos / bps,970 rc = fat_block_get(&b, bs, nodep, pos / bps, 956 971 BLOCK_FLAGS_NONE); 972 assert(rc == EOK); 957 973 (void) ipc_data_read_finalize(callid, b->data + pos % bps, 958 974 bytes); … … 980 996 off_t o; 981 997 982 b = fat_block_get(bs, nodep, bnum, BLOCK_FLAGS_NONE); 998 rc = fat_block_get(&b, bs, nodep, bnum, 999 BLOCK_FLAGS_NONE); 1000 assert(rc == EOK); 983 1001 for (o = pos % (bps / sizeof(fat_dentry_t)); 984 1002 o < bps / sizeof(fat_dentry_t); … … 1075 1093 * next block size boundary. 1076 1094 */ 1077 fat_fill_gap(bs, nodep, FAT_CLST_RES0, pos); 1078 b = fat_block_get(bs, nodep, pos / bps, flags); 1095 rc = fat_fill_gap(bs, nodep, FAT_CLST_RES0, pos); 1096 assert(rc == EOK); 1097 rc = fat_block_get(&b, bs, nodep, pos / bps, flags); 1098 assert(rc == EOK); 1079 1099 (void) ipc_data_write_finalize(callid, b->data + pos % bps, 1080 1100 bytes); … … 1109 1129 } 1110 1130 /* zero fill any gaps */ 1111 fat_fill_gap(bs, nodep, mcl, pos); 1112 b = _fat_block_get(bs, dev_handle, lcl, (pos / bps) % spc, 1131 rc = fat_fill_gap(bs, nodep, mcl, pos); 1132 assert(rc == EOK); 1133 rc = _fat_block_get(&b, bs, dev_handle, lcl, (pos / bps) % spc, 1113 1134 flags); 1135 assert(rc == EOK); 1114 1136 (void) ipc_data_write_finalize(callid, b->data + pos % bps, 1115 1137 bytes); … … 1121 1143 * node's cluster chain. 1122 1144 */ 1123 fat_append_clusters(bs, nodep, mcl); 1145 rc = fat_append_clusters(bs, nodep, mcl); 1146 assert(rc == EOK); 1124 1147 nodep->size = pos + bytes; 1125 1148 nodep->dirty = true; /* need to sync node */ … … 1174 1197 */ 1175 1198 if (size == 0) { 1176 fat_chop_clusters(bs, nodep, FAT_CLST_RES0); 1199 rc = fat_chop_clusters(bs, nodep, FAT_CLST_RES0); 1200 if (rc != EOK) 1201 goto out; 1177 1202 } else { 1178 1203 fat_cluster_t lastc; 1179 (void) fat_cluster_walk(bs, dev_handle, nodep->firstc, 1180 &lastc, (size - 1) / bpc); 1181 fat_chop_clusters(bs, nodep, lastc); 1204 rc = fat_cluster_walk(bs, dev_handle, nodep->firstc, 1205 &lastc, NULL, (size - 1) / bpc); 1206 if (rc != EOK) 1207 goto out; 1208 rc = fat_chop_clusters(bs, nodep, lastc); 1209 if (rc != EOK) 1210 goto out; 1182 1211 } 1183 1212 nodep->size = size; … … 1185 1214 rc = EOK; 1186 1215 } 1216 out: 1187 1217 fat_node_put(fn); 1188 1218 ipc_answer_0(rid, rc);
Note:
See TracChangeset
for help on using the changeset viewer.