Changeset da1bafb in mainline for kernel/arch
- Timestamp:
- 2010-05-24T18:57:31Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 0095368
- Parents:
- 666f492
- Location:
- kernel/arch
- Files:
-
- 26 edited
-
amd64/include/debugger.h (modified) (1 diff)
-
amd64/src/ddi/ddi.c (modified) (5 diffs)
-
amd64/src/debugger.c (modified) (13 diffs)
-
amd64/src/interrupt.c (modified) (5 diffs)
-
ia32/include/smp/apic.h (modified) (9 diffs)
-
ia32/src/ddi/ddi.c (modified) (5 diffs)
-
ia32/src/drivers/i8254.c (modified) (5 diffs)
-
ia32/src/interrupt.c (modified) (10 diffs)
-
ia32/src/smp/apic.c (modified) (36 diffs)
-
ia64/src/drivers/it.c (modified) (7 diffs)
-
ia64/src/interrupt.c (modified) (8 diffs)
-
mips32/include/asm.h (modified) (3 diffs)
-
mips32/include/debugger.h (modified) (1 diff)
-
mips32/include/mm/as.h (modified) (2 diffs)
-
mips32/src/debugger.c (modified) (9 diffs)
-
mips32/src/exception.c (modified) (6 diffs)
-
mips32/src/interrupt.c (modified) (4 diffs)
-
ppc32/include/asm.h (modified) (2 diffs)
-
ppc32/include/mm/frame.h (modified) (1 diff)
-
ppc32/src/debug/stacktrace.c (modified) (1 diff)
-
ppc32/src/mm/as.c (modified) (1 diff)
-
ppc32/src/mm/frame.c (modified) (4 diffs)
-
ppc32/src/mm/tlb.c (modified) (23 diffs)
-
sparc64/src/mm/sun4u/as.c (modified) (12 diffs)
-
sparc64/src/mm/sun4v/as.c (modified) (11 diffs)
-
sparc64/src/trap/sun4u/interrupt.c (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/amd64/include/debugger.h
r666f492 rda1bafb 38 38 #include <typedefs.h> 39 39 40 #define BKPOINTS_MAX 440 #define BKPOINTS_MAX 4 41 41 42 42 /* Flags that are passed to breakpoint_add function */ 43 #define BKPOINT_INSTR 0x144 #define BKPOINT_WRITE 0x245 #define BKPOINT_READ_WRITE 0x443 #define BKPOINT_INSTR 0x1 44 #define BKPOINT_WRITE 0x2 45 #define BKPOINT_READ_WRITE 0x4 46 46 47 #define BKPOINT_CHECK_ZERO 0x847 #define BKPOINT_CHECK_ZERO 0x8 48 48 49 49 50 50 extern void debugger_init(void); 51 extern int breakpoint_add(const void * where, const int flags, int curidx);52 extern void breakpoint_del(int slot);51 extern int breakpoint_add(const void *, const unsigned int, int); 52 extern void breakpoint_del(int); 53 53 54 54 #endif -
kernel/arch/amd64/src/ddi/ddi.c
r666f492 rda1bafb 49 49 * Interrupts are disabled and task is locked. 50 50 * 51 * @param task Task.51 * @param task Task. 52 52 * @param ioaddr Startign I/O space address. 53 * @param size Size of the enabled I/O range.53 * @param size Size of the enabled I/O range. 54 54 * 55 55 * @return 0 on success or an error code from errno.h. 56 * 56 57 */ 57 58 int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size) 58 59 { 59 size_t bits; 60 61 bits = ioaddr + size; 60 size_t bits = ioaddr + size; 62 61 if (bits > IO_PORTS) 63 62 return ENOENT; 64 63 65 64 if (task->arch.iomap.bits < bits) { 66 bitmap_t oldiomap;67 uint8_t *newmap;68 69 65 /* 70 66 * The I/O permission bitmap is too small and needs to be grown. 71 67 */ 72 68 73 newmap = (uint8_t *) malloc(BITS2BYTES(bits), FRAME_ATOMIC);69 uint8_t *newmap = (uint8_t *) malloc(BITS2BYTES(bits), FRAME_ATOMIC); 74 70 if (!newmap) 75 71 return ENOMEM; 76 72 73 bitmap_t oldiomap; 77 74 bitmap_initialize(&oldiomap, task->arch.iomap.map, 78 75 task->arch.iomap.bits); … … 115 112 * 116 113 * Interrupts must be disabled prior this call. 114 * 117 115 */ 118 116 void io_perm_bitmap_install(void) 119 117 { 120 size_t bits;121 ptr_16_64_t cpugdtr;122 descriptor_t *gdt_p;123 tss_descriptor_t *tss_desc;124 size_t ver;125 126 118 /* First, copy the I/O Permission Bitmap. */ 127 spinlock_lock(&TASK->lock); 128 ver = TASK->arch.iomapver; 129 if ((bits = TASK->arch.iomap.bits)) { 119 irq_spinlock_lock(&TASK->lock, false); 120 size_t ver = TASK->arch.iomapver; 121 size_t bits = TASK->arch.iomap.bits; 122 if (bits) { 123 ASSERT(TASK->arch.iomap.map); 124 130 125 bitmap_t iomap; 131 132 ASSERT(TASK->arch.iomap.map);133 126 bitmap_initialize(&iomap, CPU->arch.tss->iomap, 134 127 TSS_IOMAP_SIZE * 8); 135 128 bitmap_copy(&iomap, &TASK->arch.iomap, TASK->arch.iomap.bits); 129 136 130 /* 137 131 * It is safe to set the trailing eight bits because of the … … 140 134 bitmap_set_range(&iomap, ALIGN_UP(TASK->arch.iomap.bits, 8), 8); 141 135 } 142 spinlock_unlock(&TASK->lock);136 irq_spinlock_unlock(&TASK->lock, false); 143 137 144 138 /* … … 146 140 * Take the extra ending byte will all bits set into account. 147 141 */ 142 ptr_16_64_t cpugdtr; 148 143 gdtr_store(&cpugdtr); 149 gdt_p = (descriptor_t *) cpugdtr.base; 144 145 descriptor_t *gdt_p = (descriptor_t *) cpugdtr.base; 150 146 gdt_tss_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + BITS2BYTES(bits)); 151 147 gdtr_load(&cpugdtr); … … 155 151 * type must be changed to describe inactive TSS. 156 152 */ 157 tss_desc = (tss_descriptor_t *) &gdt_p[TSS_DES];153 tss_descriptor_t *tss_desc = (tss_descriptor_t *) &gdt_p[TSS_DES]; 158 154 tss_desc->type = AR_TSS; 159 155 tr_load(gdtselector(TSS_DES)); -
kernel/arch/amd64/src/debugger.c
r666f492 rda1bafb 46 46 #include <symtab.h> 47 47 48 #ifdef __64_BITS__ 49 #define getip(x) ((x)->rip) 50 #endif 51 52 #ifdef __32_BITS__ 53 #define getip(x) ((x)->eip) 54 #endif 55 48 56 typedef struct { 49 uintptr_t address; /**< Breakpoint address */50 int flags;/**< Flags regarding breakpoint */51 int counter;/**< How many times the exception occured */57 uintptr_t address; /**< Breakpoint address */ 58 unsigned int flags; /**< Flags regarding breakpoint */ 59 size_t counter; /**< How many times the exception occured */ 52 60 } bpinfo_t; 53 61 54 62 static bpinfo_t breakpoints[BKPOINTS_MAX]; 55 SPINLOCK_INITIALIZE(bkpoint_lock);63 IRQ_SPINLOCK_STATIC_INITIALIZE(bkpoint_lock); 56 64 57 65 #ifdef CONFIG_KCONSOLE 58 66 59 static int cmd_print_breakpoints(cmd_arg_t *argv); 67 static int cmd_print_breakpoints(cmd_arg_t *); 68 static int cmd_del_breakpoint(cmd_arg_t *); 69 static int cmd_add_breakpoint(cmd_arg_t *); 70 60 71 static cmd_info_t bkpts_info = { 61 72 .name = "bkpts", … … 65 76 }; 66 77 67 static int cmd_del_breakpoint(cmd_arg_t *argv);68 78 static cmd_arg_t del_argv = { 69 79 .type = ARG_TYPE_INT 70 80 }; 81 71 82 static cmd_info_t delbkpt_info = { 72 83 .name = "delbkpt", 73 .description = " delbkpt <number> -Delete breakpoint.",84 .description = "Delete breakpoint.", 74 85 .func = cmd_del_breakpoint, 75 86 .argc = 1, … … 77 88 }; 78 89 79 static int cmd_add_breakpoint(cmd_arg_t *argv);80 90 static cmd_arg_t add_argv = { 81 91 .type = ARG_TYPE_INT 82 92 }; 93 83 94 static cmd_info_t addbkpt_info = { 84 95 .name = "addbkpt", 85 .description = " addbkpt <&symbol> - newbreakpoint.",96 .description = "Add breakpoint.", 86 97 .func = cmd_add_breakpoint, 87 98 .argc = 1, … … 92 103 .type = ARG_TYPE_INT 93 104 }; 105 94 106 static cmd_info_t addwatchp_info = { 95 107 .name = "addwatchp", 96 .description = " addbwatchp <&symbol> - newwrite watchpoint.",108 .description = "Add write watchpoint.", 97 109 .func = cmd_add_breakpoint, 98 110 .argc = 1, … … 102 114 #endif /* CONFIG_KCONSOLE */ 103 115 104 /* Setup DR register according to table */ 116 /** Setup DR register according to table 117 * 118 */ 105 119 static void setup_dr(int curidx) 106 120 { 107 unative_t dr7; 121 ASSERT(curidx >= 0); 122 108 123 bpinfo_t *cur = &breakpoints[curidx]; 109 int flags = breakpoints[curidx].flags;110 124 unsigned int flags = breakpoints[curidx].flags; 125 111 126 /* Disable breakpoint in DR7 */ 112 dr7 = read_dr7(); 113 dr7 &= ~(0x2 << (curidx*2)); 114 115 if (cur->address) { /* Setup DR register */ 127 unative_t dr7 = read_dr7(); 128 dr7 &= ~(0x2 << (curidx * 2)); 129 130 /* Setup DR register */ 131 if (cur->address) { 116 132 /* Set breakpoint to debug registers */ 117 133 switch (curidx) { … … 129 145 break; 130 146 } 147 131 148 /* Set type to requested breakpoint & length*/ 132 dr7 &= ~ (0x3 << (16 + 4*curidx)); 133 dr7 &= ~ (0x3 << (18 + 4*curidx)); 134 if ((flags & BKPOINT_INSTR)) { 135 ; 136 } else { 149 dr7 &= ~(0x3 << (16 + 4 * curidx)); 150 dr7 &= ~(0x3 << (18 + 4 * curidx)); 137 151 152 if (!(flags & BKPOINT_INSTR)) { 138 153 #ifdef __32_BITS__ 139 154 dr7 |= ((unative_t) 0x3) << (18 + 4 * curidx); 140 155 #endif 141 156 142 157 #ifdef __64_BITS__ 143 158 dr7 |= ((unative_t) 0x2) << (18 + 4 * curidx); … … 149 164 dr7 |= ((unative_t) 0x3) << (16 + 4 * curidx); 150 165 } 151 166 152 167 /* Enable global breakpoint */ 153 168 dr7 |= 0x2 << (curidx * 2); 154 169 155 170 write_dr7(dr7); 156 157 } 158 } 159 171 } 172 } 173 160 174 /** Enable hardware breakpoint 161 175 * 162 176 * @param where Address of HW breakpoint 163 177 * @param flags Type of breakpoint (EXECUTE, WRITE) 178 * 164 179 * @return Debug slot on success, -1 - no available HW breakpoint 165 */ 166 int breakpoint_add(const void *where, const int flags, int curidx) 167 { 168 ipl_t ipl; 169 int i; 170 bpinfo_t *cur; 171 180 * 181 */ 182 int breakpoint_add(const void *where, const unsigned int flags, int curidx) 183 { 172 184 ASSERT(flags & (BKPOINT_INSTR | BKPOINT_WRITE | BKPOINT_READ_WRITE)); 173 174 ipl = interrupts_disable(); 175 spinlock_lock(&bkpoint_lock); 185 186 irq_spinlock_lock(&bkpoint_lock, true); 176 187 177 188 if (curidx == -1) { 178 189 /* Find free space in slots */ 179 for (i = 0; i < BKPOINTS_MAX; i++) 190 unsigned int i; 191 for (i = 0; i < BKPOINTS_MAX; i++) { 180 192 if (!breakpoints[i].address) { 181 193 curidx = i; 182 194 break; 183 195 } 196 } 197 184 198 if (curidx == -1) { 185 199 /* Too many breakpoints */ 186 spinlock_unlock(&bkpoint_lock); 187 interrupts_restore(ipl); 200 irq_spinlock_unlock(&bkpoint_lock, true); 188 201 return -1; 189 202 } 190 203 } 191 cur = &breakpoints[curidx]; 192 204 205 bpinfo_t *cur = &breakpoints[curidx]; 206 193 207 cur->address = (uintptr_t) where; 194 208 cur->flags = flags; 195 209 cur->counter = 0; 196 210 197 211 setup_dr(curidx); 198 199 spinlock_unlock(&bkpoint_lock); 200 interrupts_restore(ipl); 201 212 213 irq_spinlock_unlock(&bkpoint_lock, true); 214 202 215 /* Send IPI */ 203 216 // ipi_broadcast(VECTOR_DEBUG_IPI); 204 217 205 218 return curidx; 206 219 } 207 220 208 #ifdef __64_BITS__209 #define getip(x) ((x)->rip)210 #else211 #define getip(x) ((x)->eip)212 #endif213 214 221 static void handle_exception(int slot, istate_t *istate) 215 222 { 223 ASSERT(slot >= 0); 216 224 ASSERT(breakpoints[slot].address); 217 225 218 226 /* Handle zero checker */ 219 if (! (breakpoints[slot].flags & BKPOINT_INSTR)) {227 if (!(breakpoints[slot].flags & BKPOINT_INSTR)) { 220 228 if ((breakpoints[slot].flags & BKPOINT_CHECK_ZERO)) { 221 229 if (*((unative_t *) breakpoints[slot].address) != 0) 222 230 return; 231 223 232 printf("*** Found ZERO on address %lx (slot %d) ***\n", 224 233 breakpoints[slot].address, slot); … … 228 237 } 229 238 } 230 239 231 240 printf("Reached breakpoint %d:%lx (%s)\n", slot, getip(istate), 232 241 symtab_fmt_name_lookup(getip(istate))); 233 242 234 243 #ifdef CONFIG_KCONSOLE 235 244 atomic_set(&haltstate, 1); … … 241 250 void breakpoint_del(int slot) 242 251 { 243 bpinfo_t *cur; 244 ipl_t ipl; 245 246 ipl = interrupts_disable(); 247 spinlock_lock(&bkpoint_lock); 248 249 cur = &breakpoints[slot]; 252 ASSERT(slot >= 0); 253 254 irq_spinlock_lock(&bkpoint_lock, true); 255 256 bpinfo_t *cur = &breakpoints[slot]; 250 257 if (!cur->address) { 251 spinlock_unlock(&bkpoint_lock); 252 interrupts_restore(ipl); 258 irq_spinlock_unlock(&bkpoint_lock, true); 253 259 return; 254 260 } 255 261 256 262 cur->address = NULL; 257 263 258 264 setup_dr(slot); 259 260 spinlock_unlock(&bkpoint_lock); 261 interrupts_restore(ipl); 265 266 irq_spinlock_unlock(&bkpoint_lock, true); 262 267 // ipi_broadcast(VECTOR_DEBUG_IPI); 263 268 } 264 269 265 266 267 270 static void debug_exception(int n __attribute__((unused)), istate_t *istate) 268 271 { 269 unative_t dr6;270 int i;271 272 272 /* Set RF to restart the instruction */ 273 273 #ifdef __64_BITS__ 274 274 istate->rflags |= RFLAGS_RF; 275 #else 275 #endif 276 277 #ifdef __32_BITS__ 276 278 istate->eflags |= EFLAGS_RF; 277 279 #endif 278 279 dr6 = read_dr6(); 280 for (i=0; i < BKPOINTS_MAX; i++) { 280 281 unative_t dr6 = read_dr6(); 282 283 unsigned int i; 284 for (i = 0; i < BKPOINTS_MAX; i++) { 281 285 if (dr6 & (1 << i)) { 282 286 dr6 &= ~ (1 << i); … … 289 293 290 294 #ifdef CONFIG_SMP 291 static void 292 debug_ipi(int n __attribute__((unused)), 295 static void debug_ipi(int n __attribute__((unused)), 293 296 istate_t *istate __attribute__((unused))) 294 297 { 295 i nt i;296 297 spinlock_lock(&bkpoint_lock);298 irq_spinlock_lock(&bkpoint_lock, false); 299 300 unsigned int i; 298 301 for (i = 0; i < BKPOINTS_MAX; i++) 299 302 setup_dr(i); 300 spinlock_unlock(&bkpoint_lock); 301 } 302 #endif 303 304 /** Initialize debugger */ 303 304 irq_spinlock_unlock(&bkpoint_lock, false); 305 } 306 #endif /* CONFIG_SMP */ 307 308 /** Initialize debugger 309 * 310 */ 305 311 void debugger_init() 306 312 { 307 int i; 308 313 unsigned int i; 309 314 for (i = 0; i < BKPOINTS_MAX; i++) 310 315 breakpoints[i].address = NULL; 311 316 312 317 #ifdef CONFIG_KCONSOLE 313 318 cmd_initialize(&bkpts_info); 314 319 if (!cmd_register(&bkpts_info)) 315 320 printf("Cannot register command %s\n", bkpts_info.name); 316 321 317 322 cmd_initialize(&delbkpt_info); 318 323 if (!cmd_register(&delbkpt_info)) 319 324 printf("Cannot register command %s\n", delbkpt_info.name); 320 325 321 326 cmd_initialize(&addbkpt_info); 322 327 if (!cmd_register(&addbkpt_info)) 323 328 printf("Cannot register command %s\n", addbkpt_info.name); 324 329 325 330 cmd_initialize(&addwatchp_info); 326 331 if (!cmd_register(&addwatchp_info)) … … 331 336 #ifdef CONFIG_SMP 332 337 exc_register(VECTOR_DEBUG_IPI, "debugger_smp", debug_ipi); 333 #endif 338 #endif /* CONFIG_SMP */ 334 339 } 335 340 336 341 #ifdef CONFIG_KCONSOLE 337 /** Print table of active breakpoints */ 342 /** Print table of active breakpoints 343 * 344 */ 338 345 int cmd_print_breakpoints(cmd_arg_t *argv __attribute__((unused))) 339 346 { 340 unsigned int i;341 342 347 #ifdef __32_BITS__ 343 348 printf("# Count Address In symbol\n"); 344 349 printf("-- ----- ---------- ---------\n"); 345 350 #endif 346 351 347 352 #ifdef __64_BITS__ 348 353 printf("# Count Address In symbol\n"); … … 350 355 #endif 351 356 352 for (i = 0; i < BKPOINTS_MAX; i++) 357 unsigned int i; 358 for (i = 0; i < BKPOINTS_MAX; i++) { 353 359 if (breakpoints[i].address) { 354 360 const char *symbol = symtab_fmt_name_lookup( 355 361 breakpoints[i].address); 356 362 357 363 #ifdef __32_BITS__ 358 printf("%-2u %-5 d %#10zx%s\n", i,364 printf("%-2u %-5" PRIs " %p %s\n", i, 359 365 breakpoints[i].counter, breakpoints[i].address, 360 366 symbol); 361 367 #endif 362 368 363 369 #ifdef __64_BITS__ 364 printf("%-2u %-5 d %#18zx%s\n", i,370 printf("%-2u %-5" PRIs " %p %s\n", i, 365 371 breakpoints[i].counter, breakpoints[i].address, 366 372 symbol); 367 373 #endif 368 369 } 374 } 375 } 376 370 377 return 1; 371 378 } 372 379 373 /** Remove breakpoint from table */ 380 /** Remove breakpoint from table 381 * 382 */ 374 383 int cmd_del_breakpoint(cmd_arg_t *argv) 375 384 { … … 379 388 return 0; 380 389 } 390 381 391 breakpoint_del(argv->intval); 382 392 return 1; 383 393 } 384 394 385 /** Add new breakpoint to table */ 395 /** Add new breakpoint to table 396 * 397 */ 386 398 static int cmd_add_breakpoint(cmd_arg_t *argv) 387 399 { 388 int flags; 389 int id; 390 391 if (argv == &add_argv) { 400 unsigned int flags; 401 if (argv == &add_argv) 392 402 flags = BKPOINT_INSTR; 393 } else { /* addwatchp */403 else 394 404 flags = BKPOINT_WRITE; 395 }405 396 406 printf("Adding breakpoint on address: %p\n", argv->intval); 397 id = breakpoint_add((void *)argv->intval, flags, -1); 407 408 int id = breakpoint_add((void *)argv->intval, flags, -1); 398 409 if (id < 0) 399 410 printf("Add breakpoint failed.\n"); -
kernel/arch/amd64/src/interrupt.c
r666f492 rda1bafb 106 106 } 107 107 108 /** General Protection Fault. */ 108 /** General Protection Fault. 109 * 110 */ 109 111 static void gp_fault(int n, istate_t *istate) 110 112 { 111 113 if (TASK) { 112 size_t ver; 113 114 spinlock_lock(&TASK->lock); 115 ver = TASK->arch.iomapver; 116 spinlock_unlock(&TASK->lock); 117 114 irq_spinlock_lock(&TASK->lock, false); 115 size_t ver = TASK->arch.iomapver; 116 irq_spinlock_unlock(&TASK->lock, false); 117 118 118 if (CPU->arch.iomapver_copy != ver) { 119 119 /* … … 129 129 fault_if_from_uspace(istate, "General protection fault."); 130 130 } 131 131 132 132 decode_istate(n, istate); 133 133 panic("General protection fault."); … … 159 159 #endif 160 160 161 /** Handler of IRQ exceptions */ 161 /** Handler of IRQ exceptions. 162 * 163 */ 162 164 static void irq_interrupt(int n, istate_t *istate) 163 165 { … … 174 176 * The IRQ handler was found. 175 177 */ 176 178 177 179 if (irq->preack) { 178 180 /* Send EOI before processing the interrupt */ … … 181 183 } 182 184 irq->handler(irq); 183 spinlock_unlock(&irq->lock);185 irq_spinlock_unlock(&irq->lock, false); 184 186 } else { 185 187 /* -
kernel/arch/ia32/include/smp/apic.h
r666f492 rda1bafb 27 27 */ 28 28 29 /** @addtogroup ia32 29 /** @addtogroup ia32 30 30 * @{ 31 31 */ … … 39 39 #include <cpu.h> 40 40 41 #define FIXED (0<<0)42 #define LOPRI (1<<0)43 44 #define APIC_ID_COUNT 1641 #define FIXED (0 << 0) 42 #define LOPRI (1 << 0) 43 44 #define APIC_ID_COUNT 16 45 45 46 46 /* local APIC macros */ 47 #define IPI_INIT 048 #define IPI_STARTUP 047 #define IPI_INIT 0 48 #define IPI_STARTUP 0 49 49 50 50 /** Delivery modes. */ 51 #define DELMOD_FIXED 0x052 #define DELMOD_LOWPRI 0x153 #define DELMOD_SMI 0x251 #define DELMOD_FIXED 0x0 52 #define DELMOD_LOWPRI 0x1 53 #define DELMOD_SMI 0x2 54 54 /* 0x3 reserved */ 55 #define DELMOD_NMI 0x456 #define DELMOD_INIT 0x557 #define DELMOD_STARTUP 0x658 #define DELMOD_EXTINT 0x755 #define DELMOD_NMI 0x4 56 #define DELMOD_INIT 0x5 57 #define DELMOD_STARTUP 0x6 58 #define DELMOD_EXTINT 0x7 59 59 60 60 /** Destination modes. */ 61 #define DESTMOD_PHYS 0x062 #define DESTMOD_LOGIC 0x161 #define DESTMOD_PHYS 0x0 62 #define DESTMOD_LOGIC 0x1 63 63 64 64 /** Trigger Modes. */ 65 #define TRIGMOD_EDGE 0x066 #define TRIGMOD_LEVEL 0x165 #define TRIGMOD_EDGE 0x0 66 #define TRIGMOD_LEVEL 0x1 67 67 68 68 /** Levels. */ 69 #define LEVEL_DEASSERT 0x070 #define LEVEL_ASSERT 0x169 #define LEVEL_DEASSERT 0x0 70 #define LEVEL_ASSERT 0x1 71 71 72 72 /** Destination Shorthands. */ 73 #define SHORTHAND_NONE 0x074 #define SHORTHAND_SELF 0x175 #define SHORTHAND_ALL_INCL 0x276 #define SHORTHAND_ALL_EXCL 0x373 #define SHORTHAND_NONE 0x0 74 #define SHORTHAND_SELF 0x1 75 #define SHORTHAND_ALL_INCL 0x2 76 #define SHORTHAND_ALL_EXCL 0x3 77 77 78 78 /** Interrupt Input Pin Polarities. */ 79 #define POLARITY_HIGH 0x080 #define POLARITY_LOW 0x179 #define POLARITY_HIGH 0x0 80 #define POLARITY_LOW 0x1 81 81 82 82 /** Divide Values. (Bit 2 is always 0) */ 83 #define DIVIDE_2 0x084 #define DIVIDE_4 0x185 #define DIVIDE_8 0x286 #define DIVIDE_16 0x387 #define DIVIDE_32 0x888 #define DIVIDE_64 0x989 #define DIVIDE_128 0xa90 #define DIVIDE_1 0xb83 #define DIVIDE_2 0x0 84 #define DIVIDE_4 0x1 85 #define DIVIDE_8 0x2 86 #define DIVIDE_16 0x3 87 #define DIVIDE_32 0x8 88 #define DIVIDE_64 0x9 89 #define DIVIDE_128 0xa 90 #define DIVIDE_1 0xb 91 91 92 92 /** Timer Modes. */ 93 #define TIMER_ONESHOT 0x094 #define TIMER_PERIODIC 0x193 #define TIMER_ONESHOT 0x0 94 #define TIMER_PERIODIC 0x1 95 95 96 96 /** Delivery status. */ 97 #define DELIVS_IDLE 0x098 #define DELIVS_PENDING 0x197 #define DELIVS_IDLE 0x0 98 #define DELIVS_PENDING 0x1 99 99 100 100 /** Destination masks. */ 101 #define DEST_ALL 0xff101 #define DEST_ALL 0xff 102 102 103 103 /** Dest format models. */ 104 #define MODEL_FLAT 0xf105 #define MODEL_CLUSTER 0x0104 #define MODEL_FLAT 0xf 105 #define MODEL_CLUSTER 0x0 106 106 107 107 /** Interrupt Command Register. */ 108 #define ICRlo (0x300 / sizeof(uint32_t)) 109 #define ICRhi (0x310 / sizeof(uint32_t)) 108 #define ICRlo (0x300 / sizeof(uint32_t)) 109 #define ICRhi (0x310 / sizeof(uint32_t)) 110 110 111 typedef struct { 111 112 union { 112 113 uint32_t lo; 113 114 struct { 114 uint8_t vector; /**< Interrupt Vector. */115 unsigned delmod : 3;/**< Delivery Mode. */116 unsigned destmod : 1;/**< Destination Mode. */117 unsigned delivs : 1;/**< Delivery status (RO). */118 unsigned : 1;/**< Reserved. */119 unsigned level : 1;/**< Level. */120 unsigned trigger_mode : 1;/**< Trigger Mode. */121 unsigned : 2;/**< Reserved. */122 unsigned shorthand : 2;/**< Destination Shorthand. */123 unsigned : 12;/**< Reserved. */115 uint8_t vector; /**< Interrupt Vector. */ 116 unsigned int delmod : 3; /**< Delivery Mode. */ 117 unsigned int destmod : 1; /**< Destination Mode. */ 118 unsigned int delivs : 1; /**< Delivery status (RO). */ 119 unsigned int : 1; /**< Reserved. */ 120 unsigned int level : 1; /**< Level. */ 121 unsigned int trigger_mode : 1; /**< Trigger Mode. */ 122 unsigned int : 2; /**< Reserved. */ 123 unsigned int shorthand : 2; /**< Destination Shorthand. */ 124 unsigned int : 12; /**< Reserved. */ 124 125 } __attribute__ ((packed)); 125 126 }; … … 127 128 uint32_t hi; 128 129 struct { 129 unsigned : 24;/**< Reserved. */130 uint8_t dest; /**< Destination field. */130 unsigned int : 24; /**< Reserved. */ 131 uint8_t dest; /**< Destination field. */ 131 132 } __attribute__ ((packed)); 132 133 }; … … 134 135 135 136 /* End Of Interrupt. */ 136 #define EOI (0x0b0 / sizeof(uint32_t))137 #define EOI (0x0b0 / sizeof(uint32_t)) 137 138 138 139 /** Error Status Register. */ 139 #define ESR (0x280 / sizeof(uint32_t)) 140 #define ESR (0x280 / sizeof(uint32_t)) 141 140 142 typedef union { 141 143 uint32_t value; 142 144 uint8_t err_bitmap; 143 145 struct { 144 unsigned send_checksum_error : 1;145 unsigned receive_checksum_error : 1;146 unsigned send_accept_error : 1;147 unsigned receive_accept_error : 1;148 unsigned : 1;149 unsigned send_illegal_vector : 1;150 unsigned received_illegal_vector : 1;151 unsigned i llegal_register_address : 1;152 unsigned : 24;146 unsigned int send_checksum_error : 1; 147 unsigned int receive_checksum_error : 1; 148 unsigned int send_accept_error : 1; 149 unsigned int receive_accept_error : 1; 150 unsigned int : 1; 151 unsigned int send_illegal_vector : 1; 152 unsigned int received_illegal_vector : 1; 153 unsigned int illegal_register_address : 1; 154 unsigned int : 24; 153 155 } __attribute__ ((packed)); 154 156 } esr_t; 155 157 156 158 /* Task Priority Register */ 157 #define TPR (0x080 / sizeof(uint32_t)) 158 typedef union { 159 uint32_t value; 160 struct { 161 unsigned pri_sc : 4; /**< Task Priority Sub-Class. */ 162 unsigned pri : 4; /**< Task Priority. */ 159 #define TPR (0x080 / sizeof(uint32_t)) 160 161 typedef union { 162 uint32_t value; 163 struct { 164 unsigned int pri_sc : 4; /**< Task Priority Sub-Class. */ 165 unsigned int pri : 4; /**< Task Priority. */ 163 166 } __attribute__ ((packed)); 164 167 } tpr_t; 165 168 166 169 /** Spurious-Interrupt Vector Register. */ 167 #define SVR (0x0f0 / sizeof(uint32_t)) 168 typedef union { 169 uint32_t value; 170 struct { 171 uint8_t vector; /**< Spurious Vector. */ 172 unsigned lapic_enabled : 1; /**< APIC Software Enable/Disable. */ 173 unsigned focus_checking : 1; /**< Focus Processor Checking. */ 174 unsigned : 22; /**< Reserved. */ 170 #define SVR (0x0f0 / sizeof(uint32_t)) 171 172 typedef union { 173 uint32_t value; 174 struct { 175 uint8_t vector; /**< Spurious Vector. */ 176 unsigned int lapic_enabled : 1; /**< APIC Software Enable/Disable. */ 177 unsigned int focus_checking : 1; /**< Focus Processor Checking. */ 178 unsigned int : 22; /**< Reserved. */ 175 179 } __attribute__ ((packed)); 176 180 } svr_t; 177 181 178 182 /** Time Divide Configuration Register. */ 179 #define TDCR (0x3e0 / sizeof(uint32_t)) 180 typedef union { 181 uint32_t value; 182 struct { 183 unsigned div_value : 4; /**< Divide Value, bit 2 is always 0. */ 184 unsigned : 28; /**< Reserved. */ 183 #define TDCR (0x3e0 / sizeof(uint32_t)) 184 185 typedef union { 186 uint32_t value; 187 struct { 188 unsigned int div_value : 4; /**< Divide Value, bit 2 is always 0. */ 189 unsigned int : 28; /**< Reserved. */ 185 190 } __attribute__ ((packed)); 186 191 } tdcr_t; 187 192 188 193 /* Initial Count Register for Timer */ 189 #define ICRT (0x380 / sizeof(uint32_t))194 #define ICRT (0x380 / sizeof(uint32_t)) 190 195 191 196 /* Current Count Register for Timer */ 192 #define CCRT (0x390 / sizeof(uint32_t))197 #define CCRT (0x390 / sizeof(uint32_t)) 193 198 194 199 /** LVT Timer register. */ 195 #define LVT_Tm (0x320 / sizeof(uint32_t)) 196 typedef union { 197 uint32_t value; 198 struct { 199 uint8_t vector; /**< Local Timer Interrupt vector. */ 200 unsigned : 4; /**< Reserved. */ 201 unsigned delivs : 1; /**< Delivery status (RO). */ 202 unsigned : 3; /**< Reserved. */ 203 unsigned masked : 1; /**< Interrupt Mask. */ 204 unsigned mode : 1; /**< Timer Mode. */ 205 unsigned : 14; /**< Reserved. */ 200 #define LVT_Tm (0x320 / sizeof(uint32_t)) 201 202 typedef union { 203 uint32_t value; 204 struct { 205 uint8_t vector; /**< Local Timer Interrupt vector. */ 206 unsigned int : 4; /**< Reserved. */ 207 unsigned int delivs : 1; /**< Delivery status (RO). */ 208 unsigned int : 3; /**< Reserved. */ 209 unsigned int masked : 1; /**< Interrupt Mask. */ 210 unsigned int mode : 1; /**< Timer Mode. */ 211 unsigned int : 14; /**< Reserved. */ 206 212 } __attribute__ ((packed)); 207 213 } lvt_tm_t; 208 214 209 215 /** LVT LINT registers. */ 210 #define LVT_LINT0 (0x350 / sizeof(uint32_t)) 211 #define LVT_LINT1 (0x360 / sizeof(uint32_t)) 212 typedef union { 213 uint32_t value; 214 struct { 215 uint8_t vector; /**< LINT Interrupt vector. */ 216 unsigned delmod : 3; /**< Delivery Mode. */ 217 unsigned : 1; /**< Reserved. */ 218 unsigned delivs : 1; /**< Delivery status (RO). */ 219 unsigned intpol : 1; /**< Interrupt Input Pin Polarity. */ 220 unsigned irr : 1; /**< Remote IRR (RO). */ 221 unsigned trigger_mode : 1; /**< Trigger Mode. */ 222 unsigned masked : 1; /**< Interrupt Mask. */ 223 unsigned : 15; /**< Reserved. */ 216 #define LVT_LINT0 (0x350 / sizeof(uint32_t)) 217 #define LVT_LINT1 (0x360 / sizeof(uint32_t)) 218 219 typedef union { 220 uint32_t value; 221 struct { 222 uint8_t vector; /**< LINT Interrupt vector. */ 223 unsigned int delmod : 3; /**< Delivery Mode. */ 224 unsigned int : 1; /**< Reserved. */ 225 unsigned int delivs : 1; /**< Delivery status (RO). */ 226 unsigned int intpol : 1; /**< Interrupt Input Pin Polarity. */ 227 unsigned int irr : 1; /**< Remote IRR (RO). */ 228 unsigned int trigger_mode : 1; /**< Trigger Mode. */ 229 unsigned int masked : 1; /**< Interrupt Mask. */ 230 unsigned int : 15; /**< Reserved. */ 224 231 } __attribute__ ((packed)); 225 232 } lvt_lint_t; 226 233 227 234 /** LVT Error register. */ 228 #define LVT_Err (0x370 / sizeof(uint32_t)) 229 typedef union { 230 uint32_t value; 231 struct { 232 uint8_t vector; /**< Local Timer Interrupt vector. */ 233 unsigned : 4; /**< Reserved. */ 234 unsigned delivs : 1; /**< Delivery status (RO). */ 235 unsigned : 3; /**< Reserved. */ 236 unsigned masked : 1; /**< Interrupt Mask. */ 237 unsigned : 15; /**< Reserved. */ 235 #define LVT_Err (0x370 / sizeof(uint32_t)) 236 237 typedef union { 238 uint32_t value; 239 struct { 240 uint8_t vector; /**< Local Timer Interrupt vector. */ 241 unsigned int : 4; /**< Reserved. */ 242 unsigned int delivs : 1; /**< Delivery status (RO). */ 243 unsigned int : 3; /**< Reserved. */ 244 unsigned int masked : 1; /**< Interrupt Mask. */ 245 unsigned int : 15; /**< Reserved. */ 238 246 } __attribute__ ((packed)); 239 247 } lvt_error_t; 240 248 241 249 /** Local APIC ID Register. */ 242 #define L_APIC_ID (0x020 / sizeof(uint32_t)) 243 typedef union { 244 uint32_t value; 245 struct { 246 unsigned : 24; /**< Reserved. */ 247 uint8_t apic_id; /**< Local APIC ID. */ 250 #define L_APIC_ID (0x020 / sizeof(uint32_t)) 251 252 typedef union { 253 uint32_t value; 254 struct { 255 unsigned int : 24; /**< Reserved. */ 256 uint8_t apic_id; /**< Local APIC ID. */ 248 257 } __attribute__ ((packed)); 249 258 } l_apic_id_t; 250 259 251 260 /** Local APIC Version Register */ 252 #define LAVR (0x030 / sizeof(uint32_t)) 253 #define LAVR_Mask 0xff 254 #define is_local_apic(x) (((x) & LAVR_Mask & 0xf0) == 0x1) 255 #define is_82489DX_apic(x) ((((x) & LAVR_Mask & 0xf0) == 0x0)) 256 #define is_local_xapic(x) (((x) & LAVR_Mask) == 0x14) 261 #define LAVR (0x030 / sizeof(uint32_t)) 262 #define LAVR_Mask 0xff 263 264 #define is_local_apic(x) (((x) & LAVR_Mask & 0xf0) == 0x1) 265 #define is_82489DX_apic(x) ((((x) & LAVR_Mask & 0xf0) == 0x0)) 266 #define is_local_xapic(x) (((x) & LAVR_Mask) == 0x14) 257 267 258 268 /** Logical Destination Register. */ 259 #define LDR (0x0d0 / sizeof(uint32_t)) 260 typedef union { 261 uint32_t value; 262 struct { 263 unsigned : 24; /**< Reserved. */ 264 uint8_t id; /**< Logical APIC ID. */ 269 #define LDR (0x0d0 / sizeof(uint32_t)) 270 271 typedef union { 272 uint32_t value; 273 struct { 274 unsigned int : 24; /**< Reserved. */ 275 uint8_t id; /**< Logical APIC ID. */ 265 276 } __attribute__ ((packed)); 266 277 } ldr_t; 267 278 268 279 /** Destination Format Register. */ 269 #define DFR (0x0e0 / sizeof(uint32_t)) 270 typedef union { 271 uint32_t value; 272 struct { 273 unsigned : 28; /**< Reserved, all ones. */ 274 unsigned model : 4; /**< Model. */ 280 #define DFR (0x0e0 / sizeof(uint32_t)) 281 282 typedef union { 283 uint32_t value; 284 struct { 285 unsigned int : 28; /**< Reserved, all ones. */ 286 unsigned int model : 4; /**< Model. */ 275 287 } __attribute__ ((packed)); 276 288 } dfr_t; 277 289 278 290 /* IO APIC */ 279 #define IOREGSEL (0x00 / sizeof(uint32_t))280 #define IOWIN (0x10 / sizeof(uint32_t))281 282 #define IOAPICID 0x00283 #define IOAPICVER 0x01284 #define IOAPICARB 0x02285 #define IOREDTBL 0x10291 #define IOREGSEL (0x00 / sizeof(uint32_t)) 292 #define IOWIN (0x10 / sizeof(uint32_t)) 293 294 #define IOAPICID 0x00 295 #define IOAPICVER 0x01 296 #define IOAPICARB 0x02 297 #define IOREDTBL 0x10 286 298 287 299 /** I/O Register Select Register. */ … … 289 301 uint32_t value; 290 302 struct { 291 uint8_t reg_addr; /**< APIC Register Address. */292 unsigned : 24;/**< Reserved. */303 uint8_t reg_addr; /**< APIC Register Address. */ 304 unsigned int : 24; /**< Reserved. */ 293 305 } __attribute__ ((packed)); 294 306 } io_regsel_t; … … 299 311 uint32_t lo; 300 312 struct { 301 uint8_t intvec; /**< Interrupt Vector. */302 unsigned delmod : 3;/**< Delivery Mode. */303 unsigned destmod : 1;/**< Destination mode. */304 unsigned delivs : 1;/**< Delivery status (RO). */305 unsigned int pol : 1;/**< Interrupt Input Pin Polarity. */306 unsigned i rr : 1;/**< Remote IRR (RO). */307 unsigned trigger_mode : 1;/**< Trigger Mode. */308 unsigned masked : 1;/**< Interrupt Mask. */309 unsigned : 15;/**< Reserved. */313 uint8_t intvec; /**< Interrupt Vector. */ 314 unsigned int delmod : 3; /**< Delivery Mode. */ 315 unsigned int destmod : 1; /**< Destination mode. */ 316 unsigned int delivs : 1; /**< Delivery status (RO). */ 317 unsigned int intpol : 1; /**< Interrupt Input Pin Polarity. */ 318 unsigned int irr : 1; /**< Remote IRR (RO). */ 319 unsigned int trigger_mode : 1; /**< Trigger Mode. */ 320 unsigned int masked : 1; /**< Interrupt Mask. */ 321 unsigned int : 15; /**< Reserved. */ 310 322 } __attribute__ ((packed)); 311 323 }; … … 313 325 uint32_t hi; 314 326 struct { 315 unsigned : 24;/**< Reserved. */316 uint8_t dest : 8; /**< Destination Field. */327 unsigned int : 24; /**< Reserved. */ 328 uint8_t dest : 8; /**< Destination Field. */ 317 329 } __attribute__ ((packed)); 318 330 }; … … 325 337 uint32_t value; 326 338 struct { 327 unsigned : 24;/**< Reserved. */328 unsigned apic_id : 4;/**< IO APIC ID. */329 unsigned : 4;/**< Reserved. */339 unsigned int : 24; /**< Reserved. */ 340 unsigned int apic_id : 4; /**< IO APIC ID. */ 341 unsigned int : 4; /**< Reserved. */ 330 342 } __attribute__ ((packed)); 331 343 } io_apic_id_t; … … 340 352 extern void l_apic_init(void); 341 353 extern void l_apic_eoi(void); 342 extern int l_apic_broadcast_custom_ipi(uint8_t vector);343 extern int l_apic_send_init_ipi(uint8_t apicid);354 extern int l_apic_broadcast_custom_ipi(uint8_t); 355 extern int l_apic_send_init_ipi(uint8_t); 344 356 extern void l_apic_debug(void); 345 357 extern uint8_t l_apic_id(void); 346 358 347 extern uint32_t io_apic_read(uint8_t address);348 extern void io_apic_write(uint8_t address , uint32_t x);349 extern void io_apic_change_ioredtbl(uint8_t pin, uint8_t dest, uint8_t v, int flags);350 extern void io_apic_disable_irqs(uint16_t irqmask);351 extern void io_apic_enable_irqs(uint16_t irqmask);359 extern uint32_t io_apic_read(uint8_t); 360 extern void io_apic_write(uint8_t, uint32_t); 361 extern void io_apic_change_ioredtbl(uint8_t pin, uint8_t dest, uint8_t v, unsigned int); 362 extern void io_apic_disable_irqs(uint16_t); 363 extern void io_apic_enable_irqs(uint16_t); 352 364 353 365 #endif -
kernel/arch/ia32/src/ddi/ddi.c
r666f492 rda1bafb 50 50 * Interrupts are disabled and task is locked. 51 51 * 52 * @param task Task.52 * @param task Task. 53 53 * @param ioaddr Startign I/O space address. 54 * @param size Size of the enabled I/O range.54 * @param size Size of the enabled I/O range. 55 55 * 56 56 * @return 0 on success or an error code from errno.h. 57 * 57 58 */ 58 59 int ddi_iospace_enable_arch(task_t *task, uintptr_t ioaddr, size_t size) 59 60 { 60 size_t bits; 61 62 bits = ioaddr + size; 61 size_t bits = ioaddr + size; 63 62 if (bits > IO_PORTS) 64 63 return ENOENT; 65 64 66 65 if (task->arch.iomap.bits < bits) { 67 bitmap_t oldiomap;68 uint8_t *newmap;69 70 66 /* 71 67 * The I/O permission bitmap is too small and needs to be grown. 72 68 */ 73 69 74 newmap = (uint8_t *) malloc(BITS2BYTES(bits), FRAME_ATOMIC);70 uint8_t *newmap = (uint8_t *) malloc(BITS2BYTES(bits), FRAME_ATOMIC); 75 71 if (!newmap) 76 72 return ENOMEM; 77 73 74 bitmap_t oldiomap; 78 75 bitmap_initialize(&oldiomap, task->arch.iomap.map, 79 76 task->arch.iomap.bits); 80 77 bitmap_initialize(&task->arch.iomap, newmap, bits); 81 78 82 79 /* 83 80 * Mark the new range inaccessible. … … 85 82 bitmap_set_range(&task->arch.iomap, oldiomap.bits, 86 83 bits - oldiomap.bits); 87 84 88 85 /* 89 86 * In case there really existed smaller iomap, 90 87 * copy its contents and deallocate it. 91 */ 88 */ 92 89 if (oldiomap.bits) { 93 90 bitmap_copy(&task->arch.iomap, &oldiomap, … … 96 93 } 97 94 } 98 95 99 96 /* 100 97 * Enable the range and we are done. 101 98 */ 102 99 bitmap_clear_range(&task->arch.iomap, (size_t) ioaddr, (size_t) size); 103 100 104 101 /* 105 102 * Increment I/O Permission bitmap generation counter. 106 103 */ 107 104 task->arch.iomapver++; 108 105 109 106 return 0; 110 107 } … … 116 113 * 117 114 * Interrupts must be disabled prior this call. 115 * 118 116 */ 119 117 void io_perm_bitmap_install(void) 120 118 { 121 size_t bits;122 ptr_16_32_t cpugdtr;123 descriptor_t *gdt_p;124 size_t ver;125 126 119 /* First, copy the I/O Permission Bitmap. */ 127 spinlock_lock(&TASK->lock); 128 ver = TASK->arch.iomapver; 129 if ((bits = TASK->arch.iomap.bits)) { 120 irq_spinlock_lock(&TASK->lock, false); 121 size_t ver = TASK->arch.iomapver; 122 size_t bits = TASK->arch.iomap.bits; 123 if (bits) { 124 ASSERT(TASK->arch.iomap.map); 125 130 126 bitmap_t iomap; 131 task_t *task = TASK;132 133 ASSERT(TASK->arch.iomap.map);134 127 bitmap_initialize(&iomap, CPU->arch.tss->iomap, 135 128 TSS_IOMAP_SIZE * 8); 136 bitmap_copy(&iomap, &task->arch.iomap, task->arch.iomap.bits); 129 bitmap_copy(&iomap, &TASK->arch.iomap, TASK->arch.iomap.bits); 130 137 131 /* 138 132 * It is safe to set the trailing eight bits because of the … … 141 135 bitmap_set_range(&iomap, ALIGN_UP(TASK->arch.iomap.bits, 8), 8); 142 136 } 143 spinlock_unlock(&TASK->lock);144 137 irq_spinlock_unlock(&TASK->lock, false); 138 145 139 /* 146 140 * Second, adjust TSS segment limit. 147 141 * Take the extra ending byte with all bits set into account. 148 142 */ 143 ptr_16_32_t cpugdtr; 149 144 gdtr_store(&cpugdtr); 150 gdt_p = (descriptor_t *) cpugdtr.base; 145 146 descriptor_t *gdt_p = (descriptor_t *) cpugdtr.base; 151 147 gdt_setlimit(&gdt_p[TSS_DES], TSS_BASIC_SIZE + BITS2BYTES(bits)); 152 148 gdtr_load(&cpugdtr); 153 149 154 150 /* 155 151 * Before we load new TSS limit, the current TSS descriptor -
kernel/arch/ia32/src/drivers/i8254.c
r666f492 rda1bafb 54 54 #include <ddi/device.h> 55 55 56 #define CLK_PORT1 ((ioport8_t *)0x40)57 #define CLK_PORT4 ((ioport8_t *)0x43)56 #define CLK_PORT1 ((ioport8_t *) 0x40) 57 #define CLK_PORT4 ((ioport8_t *) 0x43) 58 58 59 #define CLK_CONST 1193180 60 #define MAGIC_NUMBER 1194 59 #define CLK_CONST 1193180 60 #define MAGIC_NUMBER 1194 61 62 #define LOOPS 150000 63 #define SHIFT 11 61 64 62 65 static irq_t i8254_irq; … … 75 78 * lock. We just release it, call clock() and then reacquire it again. 76 79 */ 77 spinlock_unlock(&irq->lock);80 irq_spinlock_unlock(&irq->lock, false); 78 81 clock(); 79 spinlock_lock(&irq->lock);82 irq_spinlock_lock(&irq->lock, false); 80 83 } 81 84 … … 102 105 } 103 106 104 #define LOOPS 150000105 #define SHIFT 11106 107 void i8254_calibrate_delay_loop(void) 107 108 { 108 uint64_t clk1, clk2;109 uint32_t t1, t2, o1, o2;110 uint8_t not_ok;111 112 113 109 /* 114 110 * One-shot timer. Count-down from 0xffff at 1193180Hz … … 118 114 pio_write_8(CLK_PORT1, 0xff); 119 115 pio_write_8(CLK_PORT1, 0xff); 120 116 117 uint8_t not_ok; 118 uint32_t t1; 119 uint32_t t2; 120 121 121 do { 122 122 /* will read both status and count */ … … 126 126 t1 |= pio_read_8(CLK_PORT1) << 8; 127 127 } while (not_ok); 128 128 129 129 asm_delay_loop(LOOPS); 130 130 131 131 pio_write_8(CLK_PORT4, 0xd2); 132 132 t2 = pio_read_8(CLK_PORT1); 133 133 t2 |= pio_read_8(CLK_PORT1) << 8; 134 134 135 135 /* 136 136 * We want to determine the overhead of the calibrating mechanism. 137 137 */ 138 138 pio_write_8(CLK_PORT4, 0xd2); 139 o1 = pio_read_8(CLK_PORT1);139 uint32_t o1 = pio_read_8(CLK_PORT1); 140 140 o1 |= pio_read_8(CLK_PORT1) << 8; 141 141 142 142 asm_fake_loop(LOOPS); 143 143 144 144 pio_write_8(CLK_PORT4, 0xd2); 145 o2 = pio_read_8(CLK_PORT1);145 uint32_t o2 = pio_read_8(CLK_PORT1); 146 146 o2 |= pio_read_8(CLK_PORT1) << 8; 147 147 148 148 CPU->delay_loop_const = 149 149 ((MAGIC_NUMBER * LOOPS) / 1000) / ((t1 - t2) - (o1 - o2)) + 150 150 (((MAGIC_NUMBER * LOOPS) / 1000) % ((t1 - t2) - (o1 - o2)) ? 1 : 0); 151 152 clk1 = get_cycle();151 152 uint64_t clk1 = get_cycle(); 153 153 delay(1 << SHIFT); 154 clk2 = get_cycle();154 uint64_t clk2 = get_cycle(); 155 155 156 156 CPU->frequency_mhz = (clk2 - clk1) >> SHIFT; 157 157 158 158 return; 159 159 } -
kernel/arch/ia32/src/interrupt.c
r666f492 rda1bafb 94 94 { 95 95 fault_if_from_uspace(istate, "Unserviced interrupt: %d.", n); 96 96 97 97 decode_istate(istate); 98 98 panic("Unserviced interrupt: %d.", n); … … 102 102 { 103 103 fault_if_from_uspace(istate, "Divide error."); 104 104 105 105 decode_istate(istate); 106 106 panic("Divide error."); … … 111 111 { 112 112 if (TASK) { 113 size_t ver; 113 irq_spinlock_lock(&TASK->lock, false); 114 size_t ver = TASK->arch.iomapver; 115 irq_spinlock_unlock(&TASK->lock, false); 114 116 115 spinlock_lock(&TASK->lock);116 ver = TASK->arch.iomapver;117 spinlock_unlock(&TASK->lock);118 119 117 if (CPU->arch.iomapver_copy != ver) { 120 118 /* … … 130 128 fault_if_from_uspace(istate, "General protection fault."); 131 129 } 132 130 133 131 decode_istate(istate); 134 132 panic("General protection fault."); … … 138 136 { 139 137 fault_if_from_uspace(istate, "Stack fault."); 140 138 141 139 decode_istate(istate); 142 140 panic("Stack fault."); … … 146 144 { 147 145 uint32_t mxcsr; 148 asm (146 asm volatile ( 149 147 "stmxcsr %[mxcsr]\n" 150 148 : [mxcsr] "=m" (mxcsr) 151 149 ); 150 152 151 fault_if_from_uspace(istate, "SIMD FP exception(19), MXCSR: %#zx.", 153 152 (unative_t) mxcsr); … … 158 157 } 159 158 160 static void nm_fault(int n __attribute__((unused)), istate_t *istate __attribute__((unused))) 161 { 162 #ifdef CONFIG_FPU_LAZY 159 static void nm_fault(int n __attribute__((unused)), 160 istate_t *istate __attribute__((unused))) 161 { 162 #ifdef CONFIG_FPU_LAZY 163 163 scheduler_fpu_lazy_request(); 164 164 #else … … 169 169 170 170 #ifdef CONFIG_SMP 171 static void tlb_shootdown_ipi(int n __attribute__((unused)), istate_t *istate __attribute__((unused))) 171 static void tlb_shootdown_ipi(int n __attribute__((unused)), 172 istate_t *istate __attribute__((unused))) 172 173 { 173 174 trap_virtual_eoi(); … … 191 192 * The IRQ handler was found. 192 193 */ 193 194 194 195 if (irq->preack) { 195 196 /* Send EOI before processing the interrupt */ … … 198 199 } 199 200 irq->handler(irq); 200 spinlock_unlock(&irq->lock);201 irq_spinlock_unlock(&irq->lock, false); 201 202 } else { 202 203 /* -
kernel/arch/ia32/src/smp/apic.c
r666f492 rda1bafb 53 53 * Advanced Programmable Interrupt Controller for SMP systems. 54 54 * Tested on: 55 * Bochs 2.0.2 - Bochs 2.2.6 with 2-8 CPUs 56 * Simics 2.0.28 - Simics 2.2.19 2-15 CPUs 57 * VMware Workstation 5.5 with 2 CPUs 58 * QEMU 0.8.0 with 2-15 CPUs 59 * ASUS P/I-P65UP5 + ASUS C-P55T2D REV. 1.41 with 2x 200Mhz Pentium CPUs 60 * ASUS PCH-DL with 2x 3000Mhz Pentium 4 Xeon (HT) CPUs 61 * MSI K7D Master-L with 2x 2100MHz Athlon MP CPUs 55 * Bochs 2.0.2 - Bochs 2.2.6 with 2-8 CPUs 56 * Simics 2.0.28 - Simics 2.2.19 2-15 CPUs 57 * VMware Workstation 5.5 with 2 CPUs 58 * QEMU 0.8.0 with 2-15 CPUs 59 * ASUS P/I-P65UP5 + ASUS C-P55T2D REV. 1.41 with 2x 200Mhz Pentium CPUs 60 * ASUS PCH-DL with 2x 3000Mhz Pentium 4 Xeon (HT) CPUs 61 * MSI K7D Master-L with 2x 2100MHz Athlon MP CPUs 62 * 62 63 */ 63 64 … … 69 70 * optimize the code too much and accesses to l_apic and io_apic, that must 70 71 * always be 32-bit, would use byte oriented instructions. 72 * 71 73 */ 72 74 volatile uint32_t *l_apic = (uint32_t *) 0xfee00000; … … 79 81 80 82 #ifdef LAPIC_VERBOSE 81 static c har *delmod_str[] = {83 static const char *delmod_str[] = { 82 84 "Fixed", 83 85 "Lowest Priority", … … 90 92 }; 91 93 92 static c har *destmod_str[] = {94 static const char *destmod_str[] = { 93 95 "Physical", 94 96 "Logical" 95 97 }; 96 98 97 static c har *trigmod_str[] = {99 static const char *trigmod_str[] = { 98 100 "Edge", 99 101 "Level" 100 102 }; 101 103 102 static c har *mask_str[] = {104 static const char *mask_str[] = { 103 105 "Unmasked", 104 106 "Masked" 105 107 }; 106 108 107 static c har *delivs_str[] = {109 static const char *delivs_str[] = { 108 110 "Idle", 109 111 "Send Pending" 110 112 }; 111 113 112 static c har *tm_mode_str[] = {114 static const char *tm_mode_str[] = { 113 115 "One-shot", 114 116 "Periodic" 115 117 }; 116 118 117 static c har *intpol_str[] = {119 static const char *intpol_str[] = { 118 120 "Polarity High", 119 121 "Polarity Low" … … 123 125 /** APIC spurious interrupt handler. 124 126 * 125 * @param n Interrupt vector.127 * @param n Interrupt vector. 126 128 * @param istate Interrupted state. 127 */ 128 static void apic_spurious(int n __attribute__((unused)), istate_t *istate __attribute__((unused))) 129 * 130 */ 131 static void apic_spurious(int n __attribute__((unused)), 132 istate_t *istate __attribute__((unused))) 129 133 { 130 134 #ifdef CONFIG_DEBUG … … 145 149 * irq->lock so we just unlock it and then lock it again. 146 150 */ 147 spinlock_unlock(&irq->lock);151 irq_spinlock_unlock(&irq->lock, false); 148 152 clock(); 149 spinlock_lock(&irq->lock);153 irq_spinlock_lock(&irq->lock, false); 150 154 } 151 155 … … 153 157 void apic_init(void) 154 158 { 155 io_apic_id_t idreg;156 157 159 exc_register(VECTOR_APIC_SPUR, "apic_spurious", (iroutine) apic_spurious); 158 160 159 161 enable_irqs_function = io_apic_enable_irqs; 160 162 disable_irqs_function = io_apic_disable_irqs; … … 179 181 for (i = 0; i < IRQ_COUNT; i++) { 180 182 int pin; 181 183 182 184 if ((pin = smp_irq_to_pin(i)) != -1) 183 185 io_apic_change_ioredtbl((uint8_t) pin, DEST_ALL, (uint8_t) (IVT_IRQBASE + i), LOPRI); … … 187 189 * Ensure that io_apic has unique ID. 188 190 */ 191 io_apic_id_t idreg; 192 189 193 idreg.value = io_apic_read(IOAPICID); 190 if ((1 << idreg.apic_id) & apic_id_mask) { /* see if IO APIC ID is used already */194 if ((1 << idreg.apic_id) & apic_id_mask) { /* See if IO APIC ID is used already */ 191 195 for (i = 0; i < APIC_ID_COUNT; i++) { 192 196 if (!((1 << i) & apic_id_mask)) { … … 197 201 } 198 202 } 199 203 200 204 /* 201 205 * Configure the BSP's lapic. 202 206 */ 203 207 l_apic_init(); 204 205 l_apic_debug(); 208 l_apic_debug(); 206 209 } 207 210 … … 211 214 * 212 215 * @return 0 on error, 1 on success. 216 * 213 217 */ 214 218 int apic_poll_errors(void) … … 232 236 if (esr.illegal_register_address) 233 237 printf("Illegal Register Address\n"); 234 238 235 239 return !esr.err_bitmap; 236 240 } … … 241 245 * 242 246 * @return 0 on failure, 1 on success. 247 * 243 248 */ 244 249 int l_apic_broadcast_custom_ipi(uint8_t vector) 245 250 { 246 251 icr_t icr; 247 252 248 253 icr.lo = l_apic[ICRlo]; 249 254 icr.delmod = DELMOD_FIXED; … … 253 258 icr.trigger_mode = TRIGMOD_LEVEL; 254 259 icr.vector = vector; 255 260 256 261 l_apic[ICRlo] = icr.lo; 257 262 258 263 icr.lo = l_apic[ICRlo]; 259 264 if (icr.delivs == DELIVS_PENDING) { … … 262 267 #endif 263 268 } 264 269 265 270 return apic_poll_errors(); 266 271 } … … 271 276 * 272 277 * @return 0 on failure, 1 on success. 278 * 273 279 */ 274 280 int l_apic_send_init_ipi(uint8_t apicid) 275 281 { 282 /* 283 * Read the ICR register in and zero all non-reserved fields. 284 */ 276 285 icr_t icr; 277 int i; 278 279 /* 280 * Read the ICR register in and zero all non-reserved fields. 281 */ 286 282 287 icr.lo = l_apic[ICRlo]; 283 288 icr.hi = l_apic[ICRhi]; … … 293 298 l_apic[ICRhi] = icr.hi; 294 299 l_apic[ICRlo] = icr.lo; 295 300 296 301 /* 297 302 * According to MP Specification, 20us should be enough to … … 299 304 */ 300 305 delay(20); 301 306 302 307 if (!apic_poll_errors()) 303 308 return 0; 304 309 305 310 icr.lo = l_apic[ICRlo]; 306 311 if (icr.delivs == DELIVS_PENDING) { … … 309 314 #endif 310 315 } 311 316 312 317 icr.delmod = DELMOD_INIT; 313 318 icr.destmod = DESTMOD_PHYS; … … 317 322 icr.vector = 0; 318 323 l_apic[ICRlo] = icr.lo; 319 324 320 325 /* 321 326 * Wait 10ms as MP Specification specifies. 322 327 */ 323 328 delay(10000); 324 329 325 330 if (!is_82489DX_apic(l_apic[LAVR])) { 326 331 /* 327 332 * If this is not 82489DX-based l_apic we must send two STARTUP IPI's. 328 333 */ 329 for (i = 0; i<2; i++) { 334 unsigned int i; 335 for (i = 0; i < 2; i++) { 330 336 icr.lo = l_apic[ICRlo]; 331 337 icr.vector = (uint8_t) (((uintptr_t) ap_boot) >> 12); /* calculate the reset vector */ … … 346 352 void l_apic_init(void) 347 353 { 354 /* Initialize LVT Error register. */ 348 355 lvt_error_t error; 349 lvt_lint_t lint; 350 tpr_t tpr; 351 svr_t svr; 352 icr_t icr; 353 tdcr_t tdcr; 354 lvt_tm_t tm; 355 ldr_t ldr; 356 dfr_t dfr; 357 uint32_t t1, t2; 358 359 /* Initialize LVT Error register. */ 356 360 357 error.value = l_apic[LVT_Err]; 361 358 error.masked = true; 362 359 l_apic[LVT_Err] = error.value; 363 360 364 361 /* Initialize LVT LINT0 register. */ 362 lvt_lint_t lint; 363 365 364 lint.value = l_apic[LVT_LINT0]; 366 365 lint.masked = true; 367 366 l_apic[LVT_LINT0] = lint.value; 368 367 369 368 /* Initialize LVT LINT1 register. */ 370 369 lint.value = l_apic[LVT_LINT1]; 371 370 lint.masked = true; 372 371 l_apic[LVT_LINT1] = lint.value; 373 372 374 373 /* Task Priority Register initialization. */ 374 tpr_t tpr; 375 375 376 tpr.value = l_apic[TPR]; 376 377 tpr.pri_sc = 0; … … 379 380 380 381 /* Spurious-Interrupt Vector Register initialization. */ 382 svr_t svr; 383 381 384 svr.value = l_apic[SVR]; 382 385 svr.vector = VECTOR_APIC_SPUR; … … 384 387 svr.focus_checking = true; 385 388 l_apic[SVR] = svr.value; 386 389 387 390 if (CPU->arch.family >= 6) 388 391 enable_l_apic_in_msr(); 389 392 390 393 /* Interrupt Command Register initialization. */ 394 icr_t icr; 395 391 396 icr.lo = l_apic[ICRlo]; 392 397 icr.delmod = DELMOD_INIT; … … 398 403 399 404 /* Timer Divide Configuration Register initialization. */ 405 tdcr_t tdcr; 406 400 407 tdcr.value = l_apic[TDCR]; 401 408 tdcr.div_value = DIVIDE_1; 402 409 l_apic[TDCR] = tdcr.value; 403 410 404 411 /* Program local timer. */ 412 lvt_tm_t tm; 413 405 414 tm.value = l_apic[LVT_Tm]; 406 415 tm.vector = VECTOR_CLK; … … 408 417 tm.masked = false; 409 418 l_apic[LVT_Tm] = tm.value; 410 419 411 420 /* 412 421 * Measure and configure the timer to generate timer 413 422 * interrupt with period 1s/HZ seconds. 414 423 */ 424 uint32_t t1 = l_apic[CCRT]; 425 l_apic[ICRT] = 0xffffffff; 426 427 while (l_apic[CCRT] == t1); 428 415 429 t1 = l_apic[CCRT]; 416 l_apic[ICRT] = 0xffffffff; 417 418 while (l_apic[CCRT] == t1) 419 ; 420 421 t1 = l_apic[CCRT]; 422 delay(1000000/HZ); 423 t2 = l_apic[CCRT]; 424 425 l_apic[ICRT] = t1-t2; 430 delay(1000000 / HZ); 431 uint32_t t2 = l_apic[CCRT]; 432 433 l_apic[ICRT] = t1 - t2; 426 434 427 435 /* Program Logical Destination Register. */ 428 436 ASSERT(CPU->id < 8); 437 ldr_t ldr; 438 429 439 ldr.value = l_apic[LDR]; 430 440 ldr.id = (uint8_t) (1 << CPU->id); … … 432 442 433 443 /* Program Destination Format Register for Flat mode. */ 444 dfr_t dfr; 445 434 446 dfr.value = l_apic[DFR]; 435 447 dfr.model = MODEL_FLAT; … … 447 459 { 448 460 #ifdef LAPIC_VERBOSE 461 printf("LVT on cpu%" PRIs ", LAPIC ID: %" PRIu8 "\n", CPU->id, l_apic_id()); 462 449 463 lvt_tm_t tm; 450 lvt_lint_t lint;451 lvt_error_t error;452 453 printf("LVT on cpu%d, LAPIC ID: %d\n", CPU->id, l_apic_id());454 455 464 tm.value = l_apic[LVT_Tm]; 456 465 printf("LVT Tm: vector=%hhd, %s, %s, %s\n", tm.vector, delivs_str[tm.delivs], mask_str[tm.masked], tm_mode_str[tm.mode]); 466 467 lvt_lint_t lint; 457 468 lint.value = l_apic[LVT_LINT0]; 458 469 printf("LVT LINT0: vector=%hhd, %s, %s, %s, irr=%d, %s, %s\n", tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs], intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode], mask_str[lint.masked]); 459 470 lint.value = l_apic[LVT_LINT1]; 460 471 printf("LVT LINT1: vector=%hhd, %s, %s, %s, irr=%d, %s, %s\n", tm.vector, delmod_str[lint.delmod], delivs_str[lint.delivs], intpol_str[lint.intpol], lint.irr, trigmod_str[lint.trigger_mode], mask_str[lint.masked]); 472 473 lvt_error_t error; 461 474 error.value = l_apic[LVT_Err]; 462 475 printf("LVT Err: vector=%hhd, %s, %s\n", error.vector, delivs_str[error.delivs], mask_str[error.masked]); … … 467 480 * 468 481 * @return Local APIC ID. 482 * 469 483 */ 470 484 uint8_t l_apic_id(void) … … 481 495 * 482 496 * @return Content of the addressed IO APIC register. 497 * 483 498 */ 484 499 uint32_t io_apic_read(uint8_t address) … … 495 510 * 496 511 * @param address IO APIC register address. 497 * @param x Content to be written to the addressed IO APIC register. 498 */ 499 void io_apic_write(uint8_t address, uint32_t x) 512 * @param val Content to be written to the addressed IO APIC register. 513 * 514 */ 515 void io_apic_write(uint8_t address, uint32_t val) 500 516 { 501 517 io_regsel_t regsel; … … 504 520 regsel.reg_addr = address; 505 521 io_apic[IOREGSEL] = regsel.value; 506 io_apic[IOWIN] = x;522 io_apic[IOWIN] = val; 507 523 } 508 524 509 525 /** Change some attributes of one item in I/O Redirection Table. 510 526 * 511 * @param pin IO APIC pin number.512 * @param dest Interrupt destination address.513 * @param v Interrupt vector to trigger.527 * @param pin IO APIC pin number. 528 * @param dest Interrupt destination address. 529 * @param vec Interrupt vector to trigger. 514 530 * @param flags Flags. 515 */ 516 void io_apic_change_ioredtbl(uint8_t pin, uint8_t dest, uint8_t v, int flags) 517 { 518 io_redirection_reg_t reg; 519 int dlvr = DELMOD_FIXED; 531 * 532 */ 533 void io_apic_change_ioredtbl(uint8_t pin, uint8_t dest, uint8_t vec, 534 unsigned int flags) 535 { 536 unsigned int dlvr; 520 537 521 538 if (flags & LOPRI) 522 539 dlvr = DELMOD_LOWPRI; 523 540 else 541 dlvr = DELMOD_FIXED; 542 543 io_redirection_reg_t reg; 524 544 reg.lo = io_apic_read((uint8_t) (IOREDTBL + pin * 2)); 525 545 reg.hi = io_apic_read((uint8_t) (IOREDTBL + pin * 2 + 1)); … … 530 550 reg.intpol = POLARITY_HIGH; 531 551 reg.delmod = dlvr; 532 reg.intvec = v ;533 552 reg.intvec = vec; 553 534 554 io_apic_write((uint8_t) (IOREDTBL + pin * 2), reg.lo); 535 555 io_apic_write((uint8_t) (IOREDTBL + pin * 2 + 1), reg.hi); … … 539 559 * 540 560 * @param irqmask Bitmask of IRQs to be masked (0 = do not mask, 1 = mask). 561 * 541 562 */ 542 563 void io_apic_disable_irqs(uint16_t irqmask) 543 564 { 544 io_redirection_reg_t reg;545 565 unsigned int i; 546 int pin;547 548 566 for (i = 0; i < 16; i++) { 549 567 if (irqmask & (1 << i)) { … … 552 570 * mapping for the respective IRQ number. 553 571 */ 554 pin = smp_irq_to_pin(i);572 int pin = smp_irq_to_pin(i); 555 573 if (pin != -1) { 574 io_redirection_reg_t reg; 575 556 576 reg.lo = io_apic_read((uint8_t) (IOREDTBL + pin * 2)); 557 577 reg.masked = true; … … 566 586 * 567 587 * @param irqmask Bitmask of IRQs to be unmasked (0 = do not unmask, 1 = unmask). 588 * 568 589 */ 569 590 void io_apic_enable_irqs(uint16_t irqmask) 570 591 { 571 592 unsigned int i; 572 int pin;573 io_redirection_reg_t reg;574 575 593 for (i = 0; i < 16; i++) { 576 594 if (irqmask & (1 << i)) { … … 579 597 * mapping for the respective IRQ number. 580 598 */ 581 pin = smp_irq_to_pin(i);599 int pin = smp_irq_to_pin(i); 582 600 if (pin != -1) { 601 io_redirection_reg_t reg; 602 583 603 reg.lo = io_apic_read((uint8_t) (IOREDTBL + pin * 2)); 584 604 reg.masked = false; -
kernel/arch/ia64/src/drivers/it.c
r666f492 rda1bafb 34 34 35 35 /** Interval Timer driver. */ 36 36 37 37 #include <arch/drivers/it.h> 38 38 #include <arch/interrupt.h> … … 45 45 #include <arch.h> 46 46 47 #define IT_SERVICE_CLOCKS 6447 #define IT_SERVICE_CLOCKS 64 48 48 49 #define FREQ_NUMERATOR_SHIFT 3250 #define FREQ_NUMERATOR_MASK 0xffffffff00000000ULL49 #define FREQ_NUMERATOR_SHIFT 32 50 #define FREQ_NUMERATOR_MASK 0xffffffff00000000ULL 51 51 52 #define FREQ_DENOMINATOR_SHIFT 053 #define FREQ_DENOMINATOR_MASK 0xffffffffULL52 #define FREQ_DENOMINATOR_SHIFT 0 53 #define FREQ_DENOMINATOR_MASK 0xffffffffULL 54 54 55 55 uint64_t it_delta; … … 63 63 void it_init(void) 64 64 { 65 cr_itv_t itv;66 67 65 if (config.cpu_active == 1) { 68 66 irq_initialize(&it_irq); … … 83 81 } 84 82 85 /* initialize Interval Timer external interrupt vector */ 83 /* Initialize Interval Timer external interrupt vector */ 84 cr_itv_t itv; 85 86 86 itv.value = itv_read(); 87 87 itv.vector = INTERRUPT_TIMER; 88 88 itv.m = 0; 89 89 itv_write(itv.value); 90 91 /* set Interval Timer Counter to zero */90 91 /* Set Interval Timer Counter to zero */ 92 92 itc_write(0); 93 93 94 /* generate first Interval Timer interrupt in IT_DELTA ticks */94 /* Generate first Interval Timer interrupt in IT_DELTA ticks */ 95 95 itm_write(IT_DELTA); 96 97 /* propagate changes */96 97 /* Propagate changes */ 98 98 srlz_d(); 99 99 } … … 104 104 * 105 105 * @return Always IRQ_ACCEPT. 106 * 106 107 */ 107 108 irq_ownership_t it_claim(irq_t *irq) … … 113 114 void it_interrupt(irq_t *irq) 114 115 { 115 int64_t c;116 int64_t m;117 118 116 eoi_write(EOI); 119 117 120 m = itm_read();118 int64_t itm = itm_read(); 121 119 122 while ( 1) {123 c = itc_read();124 c += IT_SERVICE_CLOCKS;125 126 m += IT_DELTA;127 if ( m -c < 0)120 while (true) { 121 int64_t itc = itc_read(); 122 itc += IT_SERVICE_CLOCKS; 123 124 itm += IT_DELTA; 125 if (itm - itc < 0) 128 126 CPU->missed_clock_ticks++; 129 127 else … … 131 129 } 132 130 133 itm_write( m);134 srlz_d(); /* propagate changes */135 131 itm_write(itm); 132 srlz_d(); /* Propagate changes */ 133 136 134 /* 137 135 * We are holding a lock which prevents preemption. 138 136 * Release the lock, call clock() and reacquire the lock again. 139 137 */ 140 spinlock_unlock(&irq->lock);138 irq_spinlock_unlock(&irq->lock, false); 141 139 clock(); 142 spinlock_lock(&irq->lock);140 irq_spinlock_lock(&irq->lock, false); 143 141 } 144 142 -
kernel/arch/ia64/src/interrupt.c
r666f492 rda1bafb 57 57 #include <putchar.h> 58 58 59 #define VECTORS_64_BUNDLE 20 60 #define VECTORS_16_BUNDLE 48 61 #define VECTORS_16_BUNDLE_START 0x5000 62 #define VECTOR_MAX 0x7f00 63 64 #define BUNDLE_SIZE 16 59 #define VECTORS_64_BUNDLE 20 60 #define VECTORS_16_BUNDLE 48 61 #define VECTORS_16_BUNDLE_START 0x5000 62 63 #define VECTOR_MAX 0x7f00 64 65 #define BUNDLE_SIZE 16 65 66 66 67 static const char *vector_names_64_bundle[VECTORS_64_BUNDLE] = { … … 134 135 static void dump_interrupted_context(istate_t *istate) 135 136 { 136 const char *ifa = symtab_fmt_name_lookup(istate->cr_ifa);137 const char *iipa = symtab_fmt_name_lookup(istate->cr_iipa);138 const char *iip = symtab_fmt_name_lookup(istate->cr_iip);139 140 137 putchar('\n'); 141 138 printf("Interrupted context dump:\n"); … … 149 146 istate->cr_ipsr); 150 147 151 printf("cr.iip=%#018llx, #%d\t(%s)\n", istate->cr_iip, 152 istate->cr_isr.ei, iip); 153 printf("cr.iipa=%#018llx\t(%s)\n", istate->cr_iipa, iipa); 154 printf("cr.ifa=%#018llx\t(%s)\n", istate->cr_ifa, ifa); 148 printf("cr.iip=%#018llx, #%d\t(%s)\n", istate->cr_iip, istate->cr_isr.ei, 149 symtab_fmt_name_lookup(istate->cr_iip)); 150 printf("cr.iipa=%#018llx\t(%s)\n", istate->cr_iipa, 151 symtab_fmt_name_lookup(istate->cr_iipa)); 152 printf("cr.ifa=%#018llx\t(%s)\n", istate->cr_ifa, 153 symtab_fmt_name_lookup(istate->cr_ifa)); 155 154 } 156 155 … … 218 217 istate->cr_ipsr.ri++; 219 218 } 220 219 221 220 return syscall_handler(istate->in0, istate->in1, istate->in2, 222 221 istate->in3, istate->in4, istate->in5, istate->in6); … … 234 233 static void end_of_local_irq(void) 235 234 { 236 asm volatile ("mov cr.eoi=r0;;"); 237 } 238 235 asm volatile ( 236 "mov cr.eoi=r0;;" 237 ); 238 } 239 239 240 240 void external_interrupt(uint64_t vector, istate_t *istate) 241 241 { 242 242 cr_ivr_t ivr; 243 irq_t *irq;244 243 245 244 ivr.value = ivr_read(); 246 245 srlz_d(); 247 246 247 irq_t *irq; 248 248 249 switch (ivr.vector) { 249 250 case INTERRUPT_SPURIOUS: … … 252 253 #endif 253 254 break; 254 255 255 256 #ifdef CONFIG_SMP 256 257 case VECTOR_TLB_SHOOTDOWN_IPI: … … 259 260 break; 260 261 #endif 261 262 262 263 case INTERRUPT_TIMER: 263 264 irq = irq_dispatch_and_lock(ivr.vector); 264 265 if (irq) { 265 266 irq->handler(irq); 266 spinlock_unlock(&irq->lock);267 irq_spinlock_unlock(&irq->lock, false); 267 268 } else { 268 269 panic("Unhandled Internal Timer Interrupt (%d).", … … 283 284 if (!irq->preack) 284 285 end_of_local_irq(); 285 spinlock_unlock(&irq->lock);286 irq_spinlock_unlock(&irq->lock, false); 286 287 } else { 287 288 /* -
kernel/arch/mips32/include/asm.h
r666f492 rda1bafb 39 39 #include <config.h> 40 40 41 42 41 static inline void cpu_sleep(void) 43 42 { … … 47 46 48 47 /** Return base address of current stack 49 * 48 * 50 49 * Return the base address of the current stack. 51 50 * The stack is assumed to be STACK_SIZE bytes long. 52 51 * The stack must start on page boundary. 52 * 53 53 */ 54 54 static inline uintptr_t get_stack_base(void) 55 55 { 56 uintptr_t v;56 uintptr_t base; 57 57 58 58 asm volatile ( 59 "and % 0, $29, %1\n"60 : "=r" (v)61 : "r" (~(STACK_SIZE-1))59 "and %[base], $29, %[mask]\n" 60 : [base] "=r" (base) 61 : [mask] "r" (~(STACK_SIZE - 1)) 62 62 ); 63 63 64 return v;64 return base; 65 65 } 66 66 … … 78 78 static inline void pio_write_8(ioport8_t *port, uint8_t v) 79 79 { 80 *port = v; 80 *port = v; 81 81 } 82 82 83 83 static inline void pio_write_16(ioport16_t *port, uint16_t v) 84 84 { 85 *port = v; 85 *port = v; 86 86 } 87 87 88 88 static inline void pio_write_32(ioport32_t *port, uint32_t v) 89 89 { 90 *port = v; 90 *port = v; 91 91 } 92 92 -
kernel/arch/mips32/include/debugger.h
r666f492 rda1bafb 41 41 #define BKPOINTS_MAX 10 42 42 43 #define BKPOINT_INPROG (1 << 0) /**< Breakpoint was shot */ 44 #define BKPOINT_ONESHOT (1 << 1) /**< One-time breakpoint,mandatory for j/b 45 instructions */ 46 #define BKPOINT_REINST (1 << 2) /**< Breakpoint is set on the next 47 instruction, so that it could be 48 reinstalled on the previous one */ 49 #define BKPOINT_FUNCCALL (1 << 3) /**< Call a predefined function */ 43 /** Breakpoint was shot */ 44 #define BKPOINT_INPROG (1 << 0) 45 46 /** One-time breakpoint, mandatory for j/b instructions */ 47 #define BKPOINT_ONESHOT (1 << 1) 48 49 /** 50 * Breakpoint is set on the next instruction, so that it 51 * could be reinstalled on the previous one 52 */ 53 #define BKPOINT_REINST (1 << 2) 54 55 /** Call a predefined function */ 56 #define BKPOINT_FUNCCALL (1 << 3) 57 50 58 51 59 typedef struct { 52 uintptr_t address; /**< Breakpoint address */53 unative_t instruction; /**< Original instruction */60 uintptr_t address; /**< Breakpoint address */ 61 unative_t instruction; /**< Original instruction */ 54 62 unative_t nextinstruction; /**< Original instruction following break */ 55 int flags;/**< Flags regarding breakpoint */63 unsigned int flags; /**< Flags regarding breakpoint */ 56 64 size_t counter; 57 void (*bkfunc)(void * b, istate_t *istate);65 void (*bkfunc)(void *, istate_t *); 58 66 } bpinfo_t; 59 67 68 extern bpinfo_t breakpoints[BKPOINTS_MAX]; 69 60 70 extern void debugger_init(void); 61 void debugger_bpoint(istate_t *istate); 62 63 extern bpinfo_t breakpoints[BKPOINTS_MAX]; 71 extern void debugger_bpoint(istate_t *); 64 72 65 73 #endif -
kernel/arch/mips32/include/mm/as.h
r666f492 rda1bafb 27 27 */ 28 28 29 /** @addtogroup mips32mm 29 /** @addtogroup mips32mm 30 30 * @{ 31 31 */ … … 36 36 #define KERN_mips32_AS_H_ 37 37 38 #define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH 038 #define KERNEL_ADDRESS_SPACE_SHADOWED_ARCH 0 39 39 40 40 #define KERNEL_ADDRESS_SPACE_START_ARCH (unsigned long) 0x80000000 -
kernel/arch/mips32/src/debugger.c
r666f492 rda1bafb 46 46 47 47 bpinfo_t breakpoints[BKPOINTS_MAX]; 48 SPINLOCK_INITIALIZE(bkpoint_lock);48 IRQ_SPINLOCK_STATIC_INITIALIZE(bkpoint_lock); 49 49 50 50 #ifdef CONFIG_KCONSOLE 51 51 52 static int cmd_print_breakpoints(cmd_arg_t *argv); 52 static int cmd_print_breakpoints(cmd_arg_t *); 53 static int cmd_del_breakpoint(cmd_arg_t *); 54 static int cmd_add_breakpoint(cmd_arg_t *); 55 53 56 static cmd_info_t bkpts_info = { 54 57 .name = "bkpts", … … 58 61 }; 59 62 60 static int cmd_del_breakpoint(cmd_arg_t *argv);61 63 static cmd_arg_t del_argv = { 62 64 .type = ARG_TYPE_INT 63 65 }; 66 64 67 static cmd_info_t delbkpt_info = { 65 68 .name = "delbkpt", 66 .description = " delbkpt <number> -Delete breakpoint.",69 .description = "Delete breakpoint.", 67 70 .func = cmd_del_breakpoint, 68 71 .argc = 1, … … 70 73 }; 71 74 72 static int cmd_add_breakpoint(cmd_arg_t *argv);73 75 static cmd_arg_t add_argv = { 74 76 .type = ARG_TYPE_INT 75 77 }; 78 76 79 static cmd_info_t addbkpt_info = { 77 80 .name = "addbkpt", 78 .description = "addbkpt <&symbol> - new bkpoint. Break on J/Branch " 79 "insts unsupported.", 81 .description = "Add bkpoint (break on J/Branch insts unsupported).", 80 82 .func = cmd_add_breakpoint, 81 83 .argc = 1, … … 89 91 static cmd_info_t addbkpte_info = { 90 92 .name = "addbkpte", 91 .description = "addebkpte <&symbol> <&func> - new bkpoint. Call " 92 "func(or Nothing if 0).", 93 .description = "Add bkpoint with a trigger function.", 93 94 .func = cmd_add_breakpoint, 94 95 .argc = 2, … … 100 101 uint32_t value; 101 102 } jmpinstr[] = { 102 {0xf3ff0000, 0x41000000}, /* BCzF */ 103 {0xf3ff0000, 0x41020000}, /* BCzFL */ 104 {0xf3ff0000, 0x41010000}, /* BCzT */ 105 {0xf3ff0000, 0x41030000}, /* BCzTL */ 106 {0xfc000000, 0x10000000}, /* BEQ */ 107 {0xfc000000, 0x50000000}, /* BEQL */ 108 {0xfc1f0000, 0x04010000}, /* BEQL */ 109 {0xfc1f0000, 0x04110000}, /* BGEZAL */ 110 {0xfc1f0000, 0x04130000}, /* BGEZALL */ 111 {0xfc1f0000, 0x04030000}, /* BGEZL */ 112 {0xfc1f0000, 0x1c000000}, /* BGTZ */ 113 {0xfc1f0000, 0x5c000000}, /* BGTZL */ 114 {0xfc1f0000, 0x18000000}, /* BLEZ */ 115 {0xfc1f0000, 0x58000000}, /* BLEZL */ 116 {0xfc1f0000, 0x04000000}, /* BLTZ */ 117 {0xfc1f0000, 0x04100000}, /* BLTZAL */ 118 {0xfc1f0000, 0x04120000}, /* BLTZALL */ 119 {0xfc1f0000, 0x04020000}, /* BLTZL */ 120 {0xfc000000, 0x14000000}, /* BNE */ 121 {0xfc000000, 0x54000000}, /* BNEL */ 122 {0xfc000000, 0x08000000}, /* J */ 123 {0xfc000000, 0x0c000000}, /* JAL */ 124 {0xfc1f07ff, 0x00000009}, /* JALR */ 125 {0, 0} /* EndOfTable */ 126 }; 127 103 {0xf3ff0000, 0x41000000}, /* BCzF */ 104 {0xf3ff0000, 0x41020000}, /* BCzFL */ 105 {0xf3ff0000, 0x41010000}, /* BCzT */ 106 {0xf3ff0000, 0x41030000}, /* BCzTL */ 107 {0xfc000000, 0x10000000}, /* BEQ */ 108 {0xfc000000, 0x50000000}, /* BEQL */ 109 {0xfc1f0000, 0x04010000}, /* BEQL */ 110 {0xfc1f0000, 0x04110000}, /* BGEZAL */ 111 {0xfc1f0000, 0x04130000}, /* BGEZALL */ 112 {0xfc1f0000, 0x04030000}, /* BGEZL */ 113 {0xfc1f0000, 0x1c000000}, /* BGTZ */ 114 {0xfc1f0000, 0x5c000000}, /* BGTZL */ 115 {0xfc1f0000, 0x18000000}, /* BLEZ */ 116 {0xfc1f0000, 0x58000000}, /* BLEZL */ 117 {0xfc1f0000, 0x04000000}, /* BLTZ */ 118 {0xfc1f0000, 0x04100000}, /* BLTZAL */ 119 {0xfc1f0000, 0x04120000}, /* BLTZALL */ 120 {0xfc1f0000, 0x04020000}, /* BLTZL */ 121 {0xfc000000, 0x14000000}, /* BNE */ 122 {0xfc000000, 0x54000000}, /* BNEL */ 123 {0xfc000000, 0x08000000}, /* J */ 124 {0xfc000000, 0x0c000000}, /* JAL */ 125 {0xfc1f07ff, 0x00000009}, /* JALR */ 126 {0, 0} /* end of table */ 127 }; 128 128 129 129 /** Test, if the given instruction is a jump or branch instruction 130 130 * 131 131 * @param instr Instruction code 132 * @return true - it is jump instruction, false otherwise 132 * 133 * @return true if it is jump instruction, false otherwise 133 134 * 134 135 */ 135 136 static bool is_jump(unative_t instr) 136 137 { 137 int i;138 138 unsigned int i; 139 139 140 for (i = 0; jmpinstr[i].andmask; i++) { 140 141 if ((instr & jmpinstr[i].andmask) == jmpinstr[i].value) 141 142 return true; 142 143 } 143 144 144 145 return false; 145 146 } 146 147 147 /** Add new breakpoint to table */ 148 /** Add new breakpoint to table 149 * 150 */ 148 151 int cmd_add_breakpoint(cmd_arg_t *argv) 149 152 { 150 bpinfo_t *cur = NULL;151 ipl_t ipl;152 int i;153 154 153 if (argv->intval & 0x3) { 155 154 printf("Not aligned instruction, forgot to use &symbol?\n"); 156 155 return 1; 157 156 } 158 ipl = interrupts_disable();159 spinlock_lock(&bkpoint_lock);160 157 158 irq_spinlock_lock(&bkpoint_lock, true); 159 161 160 /* Check, that the breakpoints do not conflict */ 161 unsigned int i; 162 162 for (i = 0; i < BKPOINTS_MAX; i++) { 163 if (breakpoints[i].address == (uintptr_t) argv->intval) {163 if (breakpoints[i].address == (uintptr_t) argv->intval) { 164 164 printf("Duplicate breakpoint %d.\n", i); 165 spinlock_unlock(&bkpoint_lock); 166 interrupts_restore(ipl); 165 irq_spinlock_unlock(&bkpoint_lock, true); 167 166 return 0; 168 } else if ( breakpoints[i].address == (uintptr_t)argv->intval +169 sizeof(unative_t) ||breakpoints[i].address ==170 (uintptr_t) argv->intval - sizeof(unative_t)) {167 } else if ((breakpoints[i].address == (uintptr_t) argv->intval + 168 sizeof(unative_t)) || (breakpoints[i].address == 169 (uintptr_t) argv->intval - sizeof(unative_t))) { 171 170 printf("Adjacent breakpoints not supported, conflict " 172 171 "with %d.\n", i); 173 spinlock_unlock(&bkpoint_lock); 174 interrupts_restore(ipl); 172 irq_spinlock_unlock(&bkpoint_lock, true); 175 173 return 0; 176 174 } 177 175 178 176 } 179 180 for (i = 0; i < BKPOINTS_MAX; i++) 177 178 bpinfo_t *cur = NULL; 179 180 for (i = 0; i < BKPOINTS_MAX; i++) { 181 181 if (!breakpoints[i].address) { 182 182 cur = &breakpoints[i]; 183 183 break; 184 184 } 185 } 186 185 187 if (!cur) { 186 188 printf("Too many breakpoints.\n"); 187 spinlock_unlock(&bkpoint_lock); 188 interrupts_restore(ipl); 189 irq_spinlock_unlock(&bkpoint_lock, true); 189 190 return 0; 190 191 } 192 193 printf("Adding breakpoint on address %p\n", argv->intval); 194 191 195 cur->address = (uintptr_t) argv->intval; 192 printf("Adding breakpoint on address: %p\n", argv->intval); 193 cur->instruction = ((unative_t *)cur->address)[0]; 194 cur->nextinstruction = ((unative_t *)cur->address)[1]; 196 cur->instruction = ((unative_t *) cur->address)[0]; 197 cur->nextinstruction = ((unative_t *) cur->address)[1]; 195 198 if (argv == &add_argv) { 196 199 cur->flags = 0; 197 } else { /* We are add extended */200 } else { /* We are add extended */ 198 201 cur->flags = BKPOINT_FUNCCALL; 199 202 cur->bkfunc = (void (*)(void *, istate_t *)) argv[1].intval; 200 203 } 204 201 205 if (is_jump(cur->instruction)) 202 206 cur->flags |= BKPOINT_ONESHOT; 207 203 208 cur->counter = 0; 204 209 205 210 /* Set breakpoint */ 206 *((unative_t *) cur->address) = 0x0d;211 *((unative_t *) cur->address) = 0x0d; 207 212 smc_coherence(cur->address); 208 209 spinlock_unlock(&bkpoint_lock); 210 interrupts_restore(ipl); 211 213 214 irq_spinlock_unlock(&bkpoint_lock, true); 215 212 216 return 1; 213 217 } 214 218 215 /** Remove breakpoint from table */ 219 /** Remove breakpoint from table 220 * 221 */ 216 222 int cmd_del_breakpoint(cmd_arg_t *argv) 217 223 { 218 bpinfo_t *cur;219 ipl_t ipl;220 221 224 if (argv->intval > BKPOINTS_MAX) { 222 225 printf("Invalid breakpoint number.\n"); 223 226 return 0; 224 227 } 225 ipl = interrupts_disable();226 spinlock_lock(&bkpoint_lock);227 228 cur = &breakpoints[argv->intval];228 229 irq_spinlock_lock(&bkpoint_lock, true); 230 231 bpinfo_t *cur = &breakpoints[argv->intval]; 229 232 if (!cur->address) { 230 233 printf("Breakpoint does not exist.\n"); 231 spinlock_unlock(&bkpoint_lock); 232 interrupts_restore(ipl); 234 irq_spinlock_unlock(&bkpoint_lock, true); 233 235 return 0; 234 236 } 237 235 238 if ((cur->flags & BKPOINT_INPROG) && (cur->flags & BKPOINT_ONESHOT)) { 236 239 printf("Cannot remove one-shot breakpoint in-progress\n"); 237 spinlock_unlock(&bkpoint_lock); 238 interrupts_restore(ipl); 240 irq_spinlock_unlock(&bkpoint_lock, true); 239 241 return 0; 240 242 } 241 ((uint32_t *)cur->address)[0] = cur->instruction; 242 smc_coherence(((uint32_t *)cur->address)[0]); 243 ((uint32_t *)cur->address)[1] = cur->nextinstruction; 244 smc_coherence(((uint32_t *)cur->address)[1]); 245 243 244 ((uint32_t *) cur->address)[0] = cur->instruction; 245 smc_coherence(((uint32_t *) cur->address)[0]); 246 ((uint32_t *) cur->address)[1] = cur->nextinstruction; 247 smc_coherence(((uint32_t *) cur->address)[1]); 248 246 249 cur->address = NULL; 247 248 spinlock_unlock(&bkpoint_lock); 249 interrupts_restore(ipl); 250 251 irq_spinlock_unlock(&bkpoint_lock, true); 250 252 return 1; 251 253 } 252 254 253 /** Print table of active breakpoints */ 255 /** Print table of active breakpoints 256 * 257 */ 254 258 int cmd_print_breakpoints(cmd_arg_t *argv) 255 259 { … … 276 280 } 277 281 278 #endif 279 280 /** Initialize debugger */ 282 #endif /* CONFIG_KCONSOLE */ 283 284 /** Initialize debugger 285 * 286 */ 281 287 void debugger_init() 282 288 { 283 int i;284 289 unsigned int i; 290 285 291 for (i = 0; i < BKPOINTS_MAX; i++) 286 292 breakpoints[i].address = NULL; 287 293 288 294 #ifdef CONFIG_KCONSOLE 289 295 cmd_initialize(&bkpts_info); 290 296 if (!cmd_register(&bkpts_info)) 291 297 printf("Cannot register command %s\n", bkpts_info.name); 292 298 293 299 cmd_initialize(&delbkpt_info); 294 300 if (!cmd_register(&delbkpt_info)) 295 301 printf("Cannot register command %s\n", delbkpt_info.name); 296 302 297 303 cmd_initialize(&addbkpt_info); 298 304 if (!cmd_register(&addbkpt_info)) 299 305 printf("Cannot register command %s\n", addbkpt_info.name); 300 306 301 307 cmd_initialize(&addbkpte_info); 302 308 if (!cmd_register(&addbkpte_info)) 303 309 printf("Cannot register command %s\n", addbkpte_info.name); 304 #endif 310 #endif /* CONFIG_KCONSOLE */ 305 311 } 306 312 307 313 /** Handle breakpoint 308 314 * 309 * Find breakpoint in breakpoint table. 315 * Find breakpoint in breakpoint table. 310 316 * If found, call kconsole, set break on next instruction and reexecute. 311 317 * If we are on "next instruction", set it back on the first and reexecute. 312 318 * If breakpoint not found in breakpoint table, call kconsole and start 313 319 * next instruction. 320 * 314 321 */ 315 322 void debugger_bpoint(istate_t *istate) 316 323 { 317 bpinfo_t *cur = NULL;318 uintptr_t fireaddr = istate->epc;319 int i;320 321 324 /* test branch delay slot */ 322 325 if (cp0_cause_read() & 0x80000000) 323 326 panic("Breakpoint in branch delay slot not supported."); 324 325 spinlock_lock(&bkpoint_lock); 327 328 irq_spinlock_lock(&bkpoint_lock, false); 329 330 bpinfo_t *cur = NULL; 331 uintptr_t fireaddr = istate->epc; 332 unsigned int i; 333 326 334 for (i = 0; i < BKPOINTS_MAX; i++) { 327 335 /* Normal breakpoint */ 328 if ( fireaddr == breakpoints[i].address&&329 !(breakpoints[i].flags & BKPOINT_REINST)) {336 if ((fireaddr == breakpoints[i].address) && 337 (!(breakpoints[i].flags & BKPOINT_REINST))) { 330 338 cur = &breakpoints[i]; 331 339 break; 332 340 } 341 333 342 /* Reinst only breakpoint */ 334 343 if ((breakpoints[i].flags & BKPOINT_REINST) && … … 338 347 } 339 348 } 349 340 350 if (cur) { 341 351 if (cur->flags & BKPOINT_REINST) { 342 352 /* Set breakpoint on first instruction */ 343 ((uint32_t *) cur->address)[0] = 0x0d;353 ((uint32_t *) cur->address)[0] = 0x0d; 344 354 smc_coherence(((uint32_t *)cur->address)[0]); 355 345 356 /* Return back the second */ 346 ((uint32_t *)cur->address)[1] = cur->nextinstruction; 347 smc_coherence(((uint32_t *)cur->address)[1]); 357 ((uint32_t *) cur->address)[1] = cur->nextinstruction; 358 smc_coherence(((uint32_t *) cur->address)[1]); 359 348 360 cur->flags &= ~BKPOINT_REINST; 349 spinlock_unlock(&bkpoint_lock);361 irq_spinlock_unlock(&bkpoint_lock, false); 350 362 return; 351 } 363 } 364 352 365 if (cur->flags & BKPOINT_INPROG) 353 366 printf("Warning: breakpoint recursion\n"); 354 367 355 368 if (!(cur->flags & BKPOINT_FUNCCALL)) { 356 printf("***Breakpoint % d: %p in %s.\n", i, fireaddr,357 symtab_fmt_name_lookup( istate->epc));358 } 359 369 printf("***Breakpoint %u: %p in %s.\n", i, fireaddr, 370 symtab_fmt_name_lookup(fireaddr)); 371 } 372 360 373 /* Return first instruction back */ 361 374 ((uint32_t *)cur->address)[0] = cur->instruction; … … 371 384 printf("***Breakpoint %d: %p in %s.\n", i, fireaddr, 372 385 symtab_fmt_name_lookup(fireaddr)); 373 386 374 387 /* Move on to next instruction */ 375 388 istate->epc += 4; 376 389 } 390 377 391 if (cur) 378 392 cur->counter++; 393 379 394 if (cur && (cur->flags & BKPOINT_FUNCCALL)) { 380 395 /* Allow zero bkfunc, just for counting */ … … 383 398 } else { 384 399 #ifdef CONFIG_KCONSOLE 385 /* This disables all other processors - we are not SMP, 400 /* 401 * This disables all other processors - we are not SMP, 386 402 * actually this gets us to cpu_halt, if scheduler() is run 387 403 * - we generally do not want scheduler to be run from debug, 388 404 * so this is a good idea 389 */ 405 */ 390 406 atomic_set(&haltstate, 1); 391 spinlock_unlock(&bkpoint_lock);407 irq_spinlock_unlock(&bkpoint_lock, false); 392 408 393 409 kconsole("debug", "Debug console ready.\n", false); 394 410 395 spinlock_lock(&bkpoint_lock);411 irq_spinlock_lock(&bkpoint_lock, false); 396 412 atomic_set(&haltstate, 0); 397 413 #endif 398 414 } 399 if (cur && cur->address == fireaddr && (cur->flags & BKPOINT_INPROG)) { 415 416 if ((cur) && (cur->address == fireaddr) 417 && ((cur->flags & BKPOINT_INPROG))) { 400 418 /* Remove one-shot breakpoint */ 401 419 if ((cur->flags & BKPOINT_ONESHOT)) 402 420 cur->address = NULL; 421 403 422 /* Remove in-progress flag */ 404 423 cur->flags &= ~BKPOINT_INPROG; 405 } 406 spinlock_unlock(&bkpoint_lock); 424 } 425 426 irq_spinlock_unlock(&bkpoint_lock, false); 407 427 } 408 428 -
kernel/arch/mips32/src/exception.c
r666f492 rda1bafb 27 27 */ 28 28 29 /** @addtogroup mips32 29 /** @addtogroup mips32 30 30 * @{ 31 31 */ … … 67 67 "Floating Point", 68 68 NULL, NULL, NULL, NULL, NULL, NULL, NULL, 69 "WatchHi/WatchLo", /* 23 */69 "WatchHi/WatchLo", /* 23 */ 70 70 NULL, NULL, NULL, NULL, NULL, NULL, NULL, 71 71 "Virtual Coherency - data", … … 74 74 static void print_regdump(istate_t *istate) 75 75 { 76 const char *pcsymbol = symtab_fmt_name_lookup(istate->epc); 77 const char *rasymbol = symtab_fmt_name_lookup(istate->ra); 78 79 printf("PC: %#x(%s) RA: %#x(%s), SP(%p)\n", istate->epc, pcsymbol, 80 istate->ra, rasymbol, istate->sp); 76 printf("PC: %#x(%s) RA: %#x(%s), SP(%p)\n", istate->epc, 77 symtab_fmt_name_lookup(istate->epc), istate->ra, 78 symtab_fmt_name_lookup(istate->ra), istate->sp); 81 79 } 82 80 … … 135 133 static void interrupt_exception(int n, istate_t *istate) 136 134 { 137 uint32_t cause;138 int i;135 /* Decode interrupt number and process the interrupt */ 136 uint32_t cause = (cp0_cause_read() >> 8) & 0xff; 139 137 140 /* decode interrupt number and process the interrupt */ 141 cause = (cp0_cause_read() >> 8) & 0xff; 142 138 unsigned int i; 143 139 for (i = 0; i < 8; i++) { 144 140 if (cause & (1 << i)) { … … 149 145 */ 150 146 irq->handler(irq); 151 spinlock_unlock(&irq->lock);147 irq_spinlock_unlock(&irq->lock, false); 152 148 } else { 153 149 /* … … 172 168 { 173 169 int i; 174 170 175 171 /* Clear exception table */ 176 172 for (i = 0; i < IVT_ITEMS; i++) -
kernel/arch/mips32/src/interrupt.c
r666f492 rda1bafb 48 48 function virtual_timer_fnc = NULL; 49 49 static irq_t timer_irq; 50 51 // TODO: This is SMP unsafe!!! 52 53 uint32_t count_hi = 0; 54 static unsigned long nextcount; 55 static unsigned long lastcount; 50 56 51 57 /** Disable interrupts. … … 99 105 } 100 106 101 /* TODO: This is SMP unsafe!!! */ 102 uint32_t count_hi = 0; 103 static unsigned long nextcount; 104 static unsigned long lastcount; 105 106 /** Start hardware clock */ 107 /** Start hardware clock 108 * 109 */ 107 110 static void timer_start(void) 108 111 { … … 119 122 static void timer_irq_handler(irq_t *irq) 120 123 { 121 unsigned long drift;122 123 124 if (cp0_count_read() < lastcount) 124 125 /* Count overflow detected */ 125 126 count_hi++; 127 126 128 lastcount = cp0_count_read(); 127 129 128 drift = cp0_count_read() - nextcount;130 unsigned long drift = cp0_count_read() - nextcount; 129 131 while (drift > cp0_compare_value) { 130 132 drift -= cp0_compare_value; 131 133 CPU->missed_clock_ticks++; 132 134 } 135 133 136 nextcount = cp0_count_read() + cp0_compare_value - drift; 134 137 cp0_compare_write(nextcount); … … 138 141 * Release the lock, call clock() and reacquire the lock again. 139 142 */ 140 spinlock_unlock(&irq->lock);143 irq_spinlock_unlock(&irq->lock, false); 141 144 clock(); 142 spinlock_lock(&irq->lock);145 irq_spinlock_lock(&irq->lock, false); 143 146 144 147 if (virtual_timer_fnc != NULL) -
kernel/arch/ppc32/include/asm.h
r666f492 rda1bafb 39 39 #include <config.h> 40 40 #include <arch/cpu.h> 41 #include <arch/mm/asid.h> 41 42 42 43 static inline uint32_t msr_read(void) … … 58 59 :: [msr] "r" (msr) 59 60 ); 61 } 62 63 static inline void sr_set(uint32_t flags, asid_t asid, uint32_t sr) 64 { 65 asm volatile ( 66 "mtsrin %[value], %[sr]\n" 67 :: [value] "r" ((flags << 16) + (asid << 4) + sr), 68 [sr] "r" (sr << 28) 69 ); 70 } 71 72 static inline uint32_t sr_get(uint32_t vaddr) 73 { 74 uint32_t vsid; 75 76 asm volatile ( 77 "mfsrin %[vsid], %[vaddr]\n" 78 : [vsid] "=r" (vsid) 79 : [vaddr] "r" (vaddr) 80 ); 81 82 return vsid; 83 } 84 85 static inline uint32_t sdr1_get(void) 86 { 87 uint32_t sdr1; 88 89 asm volatile ( 90 "mfsdr1 %[sdr1]\n" 91 : [sdr1] "=r" (sdr1) 92 ); 93 94 return sdr1; 60 95 } 61 96 -
kernel/arch/ppc32/include/mm/frame.h
r666f492 rda1bafb 46 46 extern uintptr_t last_frame; 47 47 48 static inline uint32_t physmem_top(void) 49 { 50 uint32_t physmem; 51 52 asm volatile ( 53 "mfsprg3 %[physmem]\n" 54 : [physmem] "=r" (physmem) 55 ); 56 57 return physmem; 58 } 59 48 60 extern void frame_arch_init(void); 49 61 extern void physmem_print(void); -
kernel/arch/ppc32/src/debug/stacktrace.c
r666f492 rda1bafb 66 66 bool uspace_frame_pointer_prev(uintptr_t fp, uintptr_t *prev) 67 67 { 68 return false; 68 return !copy_from_uspace((void *) prev, 69 (uint32_t *) fp + FRAME_OFFSET_FP_PREV, sizeof(*prev)); 69 70 } 70 71 71 72 bool uspace_return_address_get(uintptr_t fp, uintptr_t *ra) 72 73 { 73 return false; 74 return !copy_from_uspace((void *) ra, (uint32_t *) fp + FRAME_OFFSET_RA, 75 sizeof(*ra)); 74 76 } 75 77 -
kernel/arch/ppc32/src/mm/as.c
r666f492 rda1bafb 55 55 void as_install_arch(as_t *as) 56 56 { 57 asid_t asid;58 57 uint32_t sr; 59 60 asid = as->asid;61 58 62 59 /* Lower 2 GB, user and supervisor access */ 63 for (sr = 0; sr < 8; sr++) { 64 asm volatile ( 65 "mtsrin %0, %1\n" 66 : 67 : "r" ((0x6000 << 16) + (asid << 4) + sr), "r" (sr << 28) 68 ); 69 } 60 for (sr = 0; sr < 8; sr++) 61 sr_set(0x6000, as->asid, sr); 70 62 71 63 /* Upper 2 GB, only supervisor access */ 72 for (sr = 8; sr < 16; sr++) { 73 asm volatile ( 74 "mtsrin %0, %1\n" 75 : 76 : "r" ((0x4000 << 16) + (asid << 4) + sr), "r" (sr << 28) 77 ); 78 } 64 for (sr = 8; sr < 16; sr++) 65 sr_set(0x4000, as->asid, sr); 79 66 } 80 67 -
kernel/arch/ppc32/src/mm/frame.c
r666f492 rda1bafb 45 45 void physmem_print(void) 46 46 { 47 unsigned int i;48 49 47 printf("Base Size\n"); 50 48 printf("---------- ----------\n"); 51 49 50 size_t i; 52 51 for (i = 0; i < memmap.cnt; i++) { 53 52 printf("%#10x %#10x\n", memmap.zones[i].start, 54 memmap.zones[i].size);53 memmap.zones[i].size); 55 54 } 56 55 } … … 60 59 pfn_t minconf = 2; 61 60 size_t i; 62 pfn_t start, conf;63 size_t size;64 61 65 62 for (i = 0; i < memmap.cnt; i++) { 66 start = ADDR2PFN(ALIGN_UP((uintptr_t) memmap.zones[i].start, FRAME_SIZE)); 67 size = SIZE2FRAMES(ALIGN_DOWN(memmap.zones[i].size, FRAME_SIZE)); 63 pfn_t start = ADDR2PFN(ALIGN_UP((uintptr_t) memmap.zones[i].start, 64 FRAME_SIZE)); 65 size_t size = SIZE2FRAMES(ALIGN_DOWN(memmap.zones[i].size, FRAME_SIZE)); 68 66 67 pfn_t conf; 69 68 if ((minconf < start) || (minconf >= start + size)) 70 69 conf = start; … … 73 72 74 73 zone_create(start, size, conf, 0); 75 if (last_frame < ALIGN_UP((uintptr_t) memmap.zones[i].start + memmap.zones[i].size, FRAME_SIZE)) 76 last_frame = ALIGN_UP((uintptr_t) memmap.zones[i].start + memmap.zones[i].size, FRAME_SIZE); 74 if (last_frame < ALIGN_UP((uintptr_t) memmap.zones[i].start 75 + memmap.zones[i].size, FRAME_SIZE)) 76 last_frame = ALIGN_UP((uintptr_t) memmap.zones[i].start 77 + memmap.zones[i].size, FRAME_SIZE); 77 78 } 78 79 … … 82 83 83 84 /* Mark the Page Hash Table frames as unavailable */ 84 uint32_t sdr1; 85 asm volatile ( 86 "mfsdr1 %0\n" 87 : "=r" (sdr1) 88 ); 89 frame_mark_unavailable(ADDR2PFN(sdr1 & 0xffff000), 16); // FIXME 85 uint32_t sdr1 = sdr1_get(); 86 87 // FIXME: compute size of PHT exactly 88 frame_mark_unavailable(ADDR2PFN(sdr1 & 0xffff000), 16); 90 89 } 91 90 -
kernel/arch/ppc32/src/mm/tlb.c
r666f492 rda1bafb 45 45 46 46 static unsigned int seed = 10; 47 static unsigned int seed_real __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42;48 47 static unsigned int seed_real 48 __attribute__ ((section("K_UNMAPPED_DATA_START"))) = 42; 49 49 50 50 /** Try to find PTE for faulting address … … 54 54 * if lock is true. 55 55 * 56 * @param as Address space.57 * @param lock Lock/unlock the address space.58 * @param badvaddr Faulting virtual address.59 * @param access Access mode that caused the fault.60 * @param istate Pointer to interrupted state.61 * @param pfrc Pointer to variable where as_page_fault() return code62 * will be stored.63 * @return PTE on success, NULL otherwise.64 * 65 * /66 static pte_t * 67 find_mapping_and_check(as_t *as, bool lock, uintptr_t badvaddr, int access,68 i state_t *istate, int *pfrc)56 * @param as Address space. 57 * @param lock Lock/unlock the address space. 58 * @param badvaddr Faulting virtual address. 59 * @param access Access mode that caused the fault. 60 * @param istate Pointer to interrupted state. 61 * @param pfrc Pointer to variable where as_page_fault() return code 62 * will be stored. 63 * 64 * @return PTE on success, NULL otherwise. 65 * 66 */ 67 static pte_t *find_mapping_and_check(as_t *as, bool lock, uintptr_t badvaddr, 68 int access, istate_t *istate, int *pfrc) 69 69 { 70 70 /* 71 71 * Check if the mapping exists in page tables. 72 */ 72 */ 73 73 pte_t *pte = page_mapping_find(as, badvaddr); 74 74 if ((pte) && (pte->present)) { … … 79 79 return pte; 80 80 } else { 81 int rc;82 83 81 /* 84 82 * Mapping not found in page tables. … … 86 84 */ 87 85 page_table_unlock(as, lock); 88 switch (rc = as_page_fault(badvaddr, access, istate)) { 86 87 int rc = as_page_fault(badvaddr, access, istate); 88 switch (rc) { 89 89 case AS_PF_OK: 90 90 /* … … 107 107 default: 108 108 panic("Unexpected rc (%d).", rc); 109 } 110 } 111 } 112 109 } 110 } 111 } 113 112 114 113 static void pht_refill_fail(uintptr_t badvaddr, istate_t *istate) … … 123 122 } 124 123 125 126 124 static void pht_insert(const uintptr_t vaddr, const pte_t *pte) 127 125 { … … 129 127 uint32_t api = (vaddr >> 22) & 0x3f; 130 128 131 uint32_t vsid; 132 asm volatile ( 133 "mfsrin %0, %1\n" 134 : "=r" (vsid) 135 : "r" (vaddr) 136 ); 137 138 uint32_t sdr1; 139 asm volatile ( 140 "mfsdr1 %0\n" 141 : "=r" (sdr1) 142 ); 129 uint32_t vsid = sr_get(vaddr); 130 uint32_t sdr1 = sdr1_get(); 131 132 // FIXME: compute size of PHT exactly 143 133 phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000); 144 134 … … 215 205 } 216 206 217 218 207 /** Process Instruction/Data Storage Exception 219 208 * … … 224 213 void pht_refill(int n, istate_t *istate) 225 214 { 226 uintptr_t badvaddr;227 pte_t *pte;228 int pfrc;229 215 as_t *as; 230 216 bool lock; … … 238 224 } 239 225 226 uintptr_t badvaddr; 227 240 228 if (n == VECTOR_DATA_STORAGE) 241 229 badvaddr = istate->dar; 242 230 else 243 231 badvaddr = istate->pc; 244 232 245 233 page_table_lock(as, lock); 246 234 247 pte = find_mapping_and_check(as, lock, badvaddr, 235 int pfrc; 236 pte_t *pte = find_mapping_and_check(as, lock, badvaddr, 248 237 PF_ACCESS_READ /* FIXME */, istate, &pfrc); 238 249 239 if (!pte) { 250 240 switch (pfrc) { … … 264 254 } 265 255 266 pte->accessed = 1; /* Record access to PTE */ 256 /* Record access to PTE */ 257 pte->accessed = 1; 267 258 pht_insert(badvaddr, pte); 268 259 … … 274 265 pht_refill_fail(badvaddr, istate); 275 266 } 276 277 267 278 268 /** Process Instruction/Data Storage Exception in Real Mode … … 291 281 badvaddr = istate->pc; 292 282 293 uint32_t physmem; 294 asm volatile ( 295 "mfsprg3 %0\n" 296 : "=r" (physmem) 297 ); 283 uint32_t physmem = physmem_top(); 298 284 299 285 if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem))) … … 303 289 uint32_t api = (badvaddr >> 22) & 0x3f; 304 290 305 uint32_t vsid; 306 asm volatile ( 307 "mfsrin %0, %1\n" 308 : "=r" (vsid) 309 : "r" (badvaddr) 310 ); 311 312 uint32_t sdr1; 313 asm volatile ( 314 "mfsdr1 %0\n" 315 : "=r" (sdr1) 316 ); 291 uint32_t vsid = sr_get(badvaddr); 292 uint32_t sdr1 = sdr1_get(); 293 294 // FIXME: compute size of PHT exactly 317 295 phte_t *phte_real = (phte_t *) (sdr1 & 0xffff0000); 318 296 … … 396 374 } 397 375 398 399 376 /** Process ITLB/DTLB Miss Exception in Real Mode 400 377 * … … 404 381 { 405 382 uint32_t badvaddr = tlbmiss & 0xfffffffc; 406 407 uint32_t physmem; 408 asm volatile ( 409 "mfsprg3 %0\n" 410 : "=r" (physmem) 411 ); 383 uint32_t physmem = physmem_top(); 412 384 413 385 if ((badvaddr < PA2KA(0)) || (badvaddr >= PA2KA(physmem))) … … 420 392 uint32_t index = 0; 421 393 asm volatile ( 422 "mtspr 981, % 0\n"423 "mtspr 982, % 1\n"424 "tlbld % 2\n"425 "tlbli % 2\n"426 : "=r" (index)427 : "r" (ptehi),428 "r" (ptelo)394 "mtspr 981, %[ptehi]\n" 395 "mtspr 982, %[ptelo]\n" 396 "tlbld %[index]\n" 397 "tlbli %[index]\n" 398 : [index] "=r" (index) 399 : [ptehi] "r" (ptehi), 400 [ptelo] "r" (ptelo) 429 401 ); 430 402 } 431 403 432 433 404 void tlb_arch_init(void) 434 405 { … … 436 407 } 437 408 438 439 409 void tlb_invalidate_all(void) 440 410 { 441 411 uint32_t index; 412 442 413 asm volatile ( 443 "li % 0, 0\n"414 "li %[index], 0\n" 444 415 "sync\n" 445 416 446 417 ".rept 64\n" 447 " tlbie %0\n"448 " addi %0, %0, 0x1000\n"418 " tlbie %[index]\n" 419 " addi %[index], %[index], 0x1000\n" 449 420 ".endr\n" 450 421 … … 452 423 "tlbsync\n" 453 424 "sync\n" 454 : "=r" (index)425 : [index] "=r" (index) 455 426 ); 456 427 } 457 428 458 459 429 void tlb_invalidate_asid(asid_t asid) 460 430 { 461 uint32_t sdr1; 462 asm volatile ( 463 "mfsdr1 %0\n" 464 : "=r" (sdr1) 465 ); 431 uint32_t sdr1 = sdr1_get(); 432 433 // FIXME: compute size of PHT exactly 466 434 phte_t *phte = (phte_t *) PA2KA(sdr1 & 0xffff0000); 467 435 468 uint32_t i;436 size_t i; 469 437 for (i = 0; i < 8192; i++) { 470 438 if ((phte[i].v) && (phte[i].vsid >= (asid << 4)) && … … 472 440 phte[i].v = 0; 473 441 } 442 474 443 tlb_invalidate_all(); 475 444 } 476 477 445 478 446 void tlb_invalidate_pages(asid_t asid, uintptr_t page, size_t cnt) … … 482 450 } 483 451 484 485 452 #define PRINT_BAT(name, ureg, lreg) \ 486 453 asm volatile ( \ 487 "mfspr %0," #ureg "\n" \ 488 "mfspr %1," #lreg "\n" \ 489 : "=r" (upper), "=r" (lower) \ 454 "mfspr %[upper], " #ureg "\n" \ 455 "mfspr %[lower], " #lreg "\n" \ 456 : [upper] "=r" (upper), \ 457 [lower] "=r" (lower) \ 490 458 ); \ 459 \ 491 460 mask = (upper & 0x1ffc) >> 2; \ 492 461 if (upper & 3) { \ 493 462 uint32_t tmp = mask; \ 494 463 length = 128; \ 464 \ 495 465 while (tmp) { \ 496 466 if ((tmp & 1) == 0) { \ … … 503 473 } else \ 504 474 length = 0; \ 475 \ 505 476 printf(name ": page=%.*p frame=%.*p length=%d KB (mask=%#x)%s%s\n", \ 506 477 sizeof(upper) * 2, upper & 0xffff0000, sizeof(lower) * 2, \ … … 515 486 516 487 for (sr = 0; sr < 16; sr++) { 517 uint32_t vsid; 518 asm volatile ( 519 "mfsrin %0, %1\n" 520 : "=r" (vsid) 521 : "r" (sr << 28) 522 ); 488 uint32_t vsid = sr_get(sr << 28); 489 523 490 printf("sr[%02u]: vsid=%.*p (asid=%u)%s%s\n", sr, 524 491 sizeof(vsid) * 2, vsid & 0xffffff, (vsid & 0xffffff) >> 4, -
kernel/arch/sparc64/src/mm/sun4u/as.c
r666f492 rda1bafb 41 41 42 42 #ifdef CONFIG_TSB 43 43 44 #include <arch/mm/tsb.h> 44 45 #include <arch/memstr.h> … … 47 48 #include <bitops.h> 48 49 #include <macros.h> 50 49 51 #endif /* CONFIG_TSB */ 50 52 … … 58 60 } 59 61 60 int as_constructor_arch(as_t *as, int flags)62 int as_constructor_arch(as_t *as, unsigned int flags) 61 63 { 62 64 #ifdef CONFIG_TSB … … 64 66 * The order must be calculated with respect to the emulated 65 67 * 16K page size. 66 */ 67 int order = fnzb32(((ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) * 68 * 69 */ 70 uint8_t order = fnzb32(((ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) * 68 71 sizeof(tsb_entry_t)) >> FRAME_WIDTH); 69 72 70 73 uintptr_t tsb = (uintptr_t) frame_alloc(order, flags | FRAME_KA); 71 74 72 75 if (!tsb) 73 76 return -1; 74 77 75 78 as->arch.itsb = (tsb_entry_t *) tsb; 76 79 as->arch.dtsb = (tsb_entry_t *) (tsb + ITSB_ENTRY_COUNT * 77 80 sizeof(tsb_entry_t)); 78 81 79 82 memsetb(as->arch.itsb, 80 83 (ITSB_ENTRY_COUNT + DTSB_ENTRY_COUNT) * sizeof(tsb_entry_t), 0); 81 84 #endif 85 82 86 return 0; 83 87 } … … 93 97 sizeof(tsb_entry_t)) >> FRAME_WIDTH; 94 98 frame_free(KA2PA((uintptr_t) as->arch.itsb)); 99 95 100 return cnt; 96 101 #else … … 99 104 } 100 105 101 int as_create_arch(as_t *as, int flags)106 int as_create_arch(as_t *as, unsigned int flags) 102 107 { 103 108 #ifdef CONFIG_TSB 104 109 tsb_invalidate(as, 0, (size_t) -1); 105 110 #endif 111 106 112 return 0; 107 113 } … … 123 129 * 124 130 * Moreover, the as->asid is protected by asidlock, which is being held. 131 * 125 132 */ 126 133 … … 130 137 * secondary context register from the TL=1 code just before switch to 131 138 * userspace. 139 * 132 140 */ 133 141 ctx.v = 0; 134 142 ctx.context = as->asid; 135 143 mmu_secondary_context_write(ctx.v); 136 137 #ifdef CONFIG_TSB 144 145 #ifdef CONFIG_TSB 138 146 uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH); 139 147 140 148 ASSERT(as->arch.itsb && as->arch.dtsb); 141 149 142 150 uintptr_t tsb = (uintptr_t) as->arch.itsb; 143 151 144 152 if (!overlaps(tsb, 8 * MMU_PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) { 145 153 /* … … 147 155 * by the locked 4M kernel DTLB entry. We need 148 156 * to map both TSBs explicitly. 157 * 149 158 */ 150 159 dtlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_NUCLEUS, tsb); 151 160 dtlb_insert_mapping(tsb, KA2PA(tsb), PAGESIZE_64K, true, true); 152 161 } 153 162 154 163 /* 155 164 * Setup TSB Base registers. 165 * 156 166 */ 157 167 tsb_base_reg_t tsb_base; 158 168 159 169 tsb_base.value = 0; 160 170 tsb_base.size = TSB_SIZE; 161 171 tsb_base.split = 0; 162 172 163 173 tsb_base.base = ((uintptr_t) as->arch.itsb) >> MMU_PAGE_WIDTH; 164 174 itsb_base_write(tsb_base.value); … … 175 185 * Clearing the extension registers will ensure that the value of the 176 186 * TSB Base register will be used as an address of TSB, making the code 177 * compatible with the US port. 187 * compatible with the US port. 188 * 178 189 */ 179 190 itsb_primary_extension_write(0); … … 195 206 void as_deinstall_arch(as_t *as) 196 207 { 197 198 208 /* 199 209 * Note that we don't and may not lock the address space. That's ok … … 201 211 * 202 212 * Moreover, the as->asid is protected by asidlock, which is being held. 203 */ 204 213 * 214 */ 215 205 216 #ifdef CONFIG_TSB 206 217 uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH); 207 218 208 219 ASSERT(as->arch.itsb && as->arch.dtsb); 209 220 210 221 uintptr_t tsb = (uintptr_t) as->arch.itsb; 211 222 212 223 if (!overlaps(tsb, 8 * MMU_PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) { 213 224 /* -
kernel/arch/sparc64/src/mm/sun4v/as.c
r666f492 rda1bafb 44 44 45 45 #ifdef CONFIG_TSB 46 46 47 #include <arch/mm/tsb.h> 47 48 #include <arch/memstr.h> … … 50 51 #include <bitops.h> 51 52 #include <macros.h> 53 52 54 #endif /* CONFIG_TSB */ 53 55 … … 61 63 } 62 64 63 int as_constructor_arch(as_t *as, int flags)65 int as_constructor_arch(as_t *as, unsigned int flags) 64 66 { 65 67 #ifdef CONFIG_TSB 66 int order = fnzb32(68 uint8_t order = fnzb32( 67 69 (TSB_ENTRY_COUNT * sizeof(tsb_entry_t)) >> FRAME_WIDTH); 68 70 69 71 uintptr_t tsb = (uintptr_t) frame_alloc(order, flags); 70 72 71 73 if (!tsb) 72 74 return -1; 73 75 74 76 as->arch.tsb_description.page_size = PAGESIZE_8K; 75 77 as->arch.tsb_description.associativity = 1; … … 79 81 as->arch.tsb_description.reserved = 0; 80 82 as->arch.tsb_description.context = 0; 81 83 82 84 memsetb((void *) PA2KA(as->arch.tsb_description.tsb_base), 83 85 TSB_ENTRY_COUNT * sizeof(tsb_entry_t), 0); 84 86 #endif 87 85 88 return 0; 86 89 } … … 91 94 size_t cnt = (TSB_ENTRY_COUNT * sizeof(tsb_entry_t)) >> FRAME_WIDTH; 92 95 frame_free((uintptr_t) as->arch.tsb_description.tsb_base); 96 93 97 return cnt; 94 98 #else … … 97 101 } 98 102 99 int as_create_arch(as_t *as, int flags)103 int as_create_arch(as_t *as, unsigned int flags) 100 104 { 101 105 #ifdef CONFIG_TSB 102 106 tsb_invalidate(as, 0, (size_t) -1); 103 107 #endif 108 104 109 return 0; 105 110 } … … 111 116 * 112 117 * @param as Address space. 118 * 113 119 */ 114 120 void as_install_arch(as_t *as) 115 121 { 116 122 mmu_secondary_context_write(as->asid); 117 #ifdef CONFIG_TSB 123 124 #ifdef CONFIG_TSB 118 125 uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH); 119 126 120 127 ASSERT(as->arch.tsb_description.tsb_base); 121 128 uintptr_t tsb = PA2KA(as->arch.tsb_description.tsb_base); 122 129 123 130 if (!overlaps(tsb, 8 * MMU_PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) { 124 131 /* … … 126 133 * by the locked 4M kernel DTLB entry. We need 127 134 * to map both TSBs explicitly. 135 * 128 136 */ 129 137 mmu_demap_page(tsb, 0, MMU_FLAG_DTLB); 130 138 dtlb_insert_mapping(tsb, KA2PA(tsb), PAGESIZE_64K, true, true); 131 139 } 132 140 133 141 __hypercall_fast2(MMU_TSB_CTXNON0, 1, KA2PA(&(as->arch.tsb_description))); 134 135 142 #endif 136 143 } … … 142 149 * 143 150 * @param as Address space. 151 * 144 152 */ 145 153 void as_deinstall_arch(as_t *as) 146 154 { 147 148 155 /* 149 156 * Note that we don't and may not lock the address space. That's ok … … 151 158 * 152 159 * Moreover, the as->asid is protected by asidlock, which is being held. 160 * 153 161 */ 154 162 155 163 #ifdef CONFIG_TSB 156 164 uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH); 157 165 158 166 ASSERT(as->arch.tsb_description.tsb_base); 159 167 160 168 uintptr_t tsb = PA2KA(as->arch.tsb_description.tsb_base); 161 169 162 170 if (!overlaps(tsb, 8 * MMU_PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) { 163 171 /* … … 165 173 * by the locked 4M kernel DTLB entry. We need 166 174 * to demap the entry installed by as_install_arch(). 175 * 167 176 */ 168 177 __hypercall_fast3(MMU_UNMAP_PERM_ADDR, tsb, 0, MMU_FLAG_DTLB); -
kernel/arch/sparc64/src/trap/sun4u/interrupt.c
r666f492 rda1bafb 55 55 void interrupt(int n, istate_t *istate) 56 56 { 57 uint64_t status; 58 uint64_t intrcv; 59 uint64_t data0; 60 status = asi_u64_read(ASI_INTR_DISPATCH_STATUS, 0); 57 uint64_t status = asi_u64_read(ASI_INTR_DISPATCH_STATUS, 0); 61 58 if (status & (!INTR_DISPATCH_STATUS_BUSY)) 62 59 panic("Interrupt Dispatch Status busy bit not set\n"); 63 64 intrcv = asi_u64_read(ASI_INTR_RECEIVE, 0);60 61 uint64_t intrcv = asi_u64_read(ASI_INTR_RECEIVE, 0); 65 62 #if defined (US) 66 data0 = asi_u64_read(ASI_INTR_R, ASI_UDB_INTR_R_DATA_0);63 uint64_t data0 = asi_u64_read(ASI_INTR_R, ASI_UDB_INTR_R_DATA_0); 67 64 #elif defined (US3) 68 data0 = asi_u64_read(ASI_INTR_R, VA_INTR_R_DATA_0);65 uint64_t data0 = asi_u64_read(ASI_INTR_R, VA_INTR_R_DATA_0); 69 66 #endif 70 67 71 68 irq_t *irq = irq_dispatch_and_lock(data0); 72 69 if (irq) { … … 75 72 */ 76 73 irq->handler(irq); 74 77 75 /* 78 76 * See if there is a clear-interrupt-routine and call it. 79 77 */ 80 if (irq->cir) {78 if (irq->cir) 81 79 irq->cir(irq->cir_arg, irq->inr); 82 }83 spinlock_unlock(&irq->lock);80 81 irq_spinlock_unlock(&irq->lock, false); 84 82 } else if (data0 > config.base) { 85 83 /* … … 90 88 */ 91 89 #ifdef CONFIG_SMP 92 if (data0 == (uintptr_t) tlb_shootdown_ipi_recv) {90 if (data0 == (uintptr_t) tlb_shootdown_ipi_recv) 93 91 tlb_shootdown_ipi_recv(); 94 }95 92 #endif 96 93 } else { … … 101 98 printf("cpu%u: spurious interrupt (intrcv=%#" PRIx64 102 99 ", data0=%#" PRIx64 ")\n", CPU->id, intrcv, data0); 100 #else 101 (void) intrcv; 103 102 #endif 104 103 } 105 104 106 105 membar(); 107 106 asi_u64_write(ASI_INTR_RECEIVE, 0, 0);
Note:
See TracChangeset
for help on using the changeset viewer.
