Changeset a35b458 in mainline for kernel/arch/sparc64/src
- Timestamp:
- 2018-03-02T20:10:49Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- f1380b7
- Parents:
- 3061bc1
- git-author:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-02-28 17:38:31)
- git-committer:
- Jiří Zárevúcky <zarevucky.jiri@…> (2018-03-02 20:10:49)
- Location:
- kernel/arch/sparc64/src
- Files:
-
- 36 edited
Legend:
- Unmodified
- Added
- Removed
-
kernel/arch/sparc64/src/asm.S
r3061bc1 ra35b458 47 47 add %o0, 7, %g1 48 48 mov 0, %g3 49 49 50 50 0: 51 51 52 52 brz,pn %o2, 2f 53 53 mov 0, %g2 54 54 55 55 1: 56 56 57 57 lduba [%g3 + %o1] ASI_AIUS, %g1 58 58 add %g2, 1, %g2 … … 61 61 bne,pt %xcc, 1b 62 62 mov %g2, %g3 63 63 64 64 2: 65 65 66 66 jmp %o7 + 8 /* exit point */ 67 67 mov %o3, %o0 68 68 69 69 3: 70 70 71 71 and %g1, -8, %g1 72 72 cmp %o0, %g1 … … 76 76 brz,pn %g4, 5f 77 77 mov 0, %g5 78 78 79 79 4: 80 80 81 81 sllx %g3, 3, %g2 82 82 add %g5, 1, %g3 … … 86 86 bne,pt %xcc, 4b 87 87 stx %g1, [%o0 + %g2] 88 88 89 89 5: 90 90 91 91 and %o2, 7, %o2 92 92 brz,pn %o2, 2b … … 96 96 add %g1, %o1, %g4 97 97 mov 0, %g3 98 98 99 99 6: 100 100 101 101 lduba [%g2 + %g4] ASI_AIUS, %g1 102 102 stb %g1, [%g2 + %o0] … … 105 105 bne,pt %xcc, 6b 106 106 mov %g2, %g3 107 107 108 108 jmp %o7 + 8 /* exit point */ 109 109 mov %o3, %o0 … … 121 121 add %o0, 7, %g1 122 122 mov 0, %g3 123 123 124 124 0: 125 125 126 126 brz,pn %o2, 2f 127 127 mov 0, %g2 128 128 129 129 1: 130 130 131 131 ldub [%g3 + %o1], %g1 132 132 add %g2, 1, %g2 … … 135 135 bne,pt %xcc, 1b 136 136 mov %g2, %g3 137 137 138 138 2: 139 139 140 140 jmp %o7 + 8 /* exit point */ 141 141 mov %o3, %o0 142 142 143 143 3: 144 144 145 145 and %g1, -8, %g1 146 146 cmp %o0, %g1 … … 150 150 brz,pn %g4, 5f 151 151 mov 0, %g5 152 152 153 153 4: 154 154 155 155 sllx %g3, 3, %g2 156 156 add %g5, 1, %g3 … … 160 160 bne,pt %xcc, 4b 161 161 stxa %g1, [%o0 + %g2] ASI_AIUS 162 162 163 163 5: 164 164 165 165 and %o2, 7, %o2 166 166 brz,pn %o2, 2b … … 170 170 add %g1, %o1, %g4 171 171 mov 0, %g3 172 172 173 173 6: 174 174 175 175 ldub [%g2 + %g4], %g1 176 176 stba %g1, [%g2 + %o0] ASI_AIUS … … 179 179 bne,pt %xcc, 6b 180 180 mov %g2, %g3 181 181 182 182 jmp %o7 + 8 /* exit point */ 183 183 mov %o3, %o0 -
kernel/arch/sparc64/src/console.c
r3061bc1 ra35b458 69 69 if (!screen) 70 70 panic("Cannot find %s.", (char *) prop_scr->value); 71 71 72 72 scr_init(screen); 73 73 #endif … … 82 82 if (!keyboard) 83 83 panic("Cannot find %s.", (char *) prop_kbd->value); 84 84 85 85 kbd_init(keyboard); 86 86 #endif … … 95 95 ofw_tree_node_t *aliases; 96 96 ofw_tree_property_t *prop; 97 97 98 98 aliases = ofw_tree_lookup("/aliases"); 99 99 if (!aliases) 100 100 panic("Cannot find '/aliases'."); 101 101 102 102 /* "def-cn" = "default console" */ 103 103 prop = ofw_tree_getprop(aliases, "def-cn"); 104 104 105 105 if ((!prop) || (!prop->value)) 106 106 standard_console_init(aliases); -
kernel/arch/sparc64/src/cpu/sun4u/cpu.c
r3061bc1 ra35b458 59 59 if ((!prop) || (!prop->value)) 60 60 prop = ofw_tree_getprop(node, "cpuid"); 61 61 62 62 if (prop && prop->value) { 63 63 mid = *((uint32_t *) prop->value); … … 69 69 } 70 70 } 71 71 72 72 return -1; 73 73 } … … 80 80 ofw_tree_node_t *node; 81 81 uint32_t clock_frequency = 0; 82 82 83 83 CPU->arch.mid = read_mid(); 84 84 85 85 /* 86 86 * Detect processor frequency. … … 109 109 } 110 110 } 111 111 112 112 CPU->arch.clock_frequency = clock_frequency; 113 113 tick_init(); … … 146 146 break; 147 147 } 148 148 149 149 switch (CPU->arch.ver.impl) { 150 150 case IMPL_ULTRASPARCI: -
kernel/arch/sparc64/src/cpu/sun4v/cpu.c
r3061bc1 ra35b458 71 71 } 72 72 } 73 73 74 74 tick_init(); 75 75 -
kernel/arch/sparc64/src/debug/stacktrace.c
r3061bc1 ra35b458 57 57 { 58 58 uintptr_t kstack; 59 59 60 60 #if defined(SUN4U) 61 61 kstack = read_from_ag_g6(); -
kernel/arch/sparc64/src/drivers/kbd.c
r3061bc1 ra35b458 62 62 { 63 63 const char *name = ofw_tree_node_name(node); 64 64 65 65 if (str_cmp(name, "su") != 0) 66 66 return false; 67 67 68 68 /* 69 69 * Read 'interrupts' property. … … 75 75 return false; 76 76 } 77 77 78 78 uint32_t interrupts = *((uint32_t *) prop->value); 79 79 80 80 /* 81 81 * Read 'reg' property. … … 87 87 return false; 88 88 } 89 89 90 90 size_t size = ((ofw_ebus_reg_t *) prop->value)->size; 91 91 92 92 uintptr_t pa = 0; // Prevent -Werror=maybe-uninitialized 93 93 if (!ofw_ebus_apply_ranges(node->parent, … … 97 97 return false; 98 98 } 99 99 100 100 inr_t inr; 101 101 cir_t cir; … … 108 108 return false; 109 109 } 110 110 111 111 /* 112 112 * We need to pass aligned address to hw_map(). … … 117 117 uintptr_t aligned_addr = ALIGN_DOWN(pa, PAGE_SIZE); 118 118 size_t offset = pa - aligned_addr; 119 119 120 120 ioport8_t *ns16550 = (ioport8_t *) (km_map(aligned_addr, offset + size, 121 121 PAGE_WRITE | PAGE_NOT_CACHEABLE) + offset); 122 122 123 123 ns16550_instance_t *ns16550_instance = ns16550_init(ns16550, 0, inr, cir, 124 124 cir_arg, NULL); … … 131 131 } 132 132 } 133 133 134 134 /* 135 135 * This is the necessary evil until the userspace drivers are … … 140 140 sysinfo_set_item_val("kbd.address.physical", NULL, pa); 141 141 sysinfo_set_item_val("kbd.type.ns16550", NULL, true); 142 142 143 143 return true; 144 144 } -
kernel/arch/sparc64/src/drivers/niagara.c
r3061bc1 ra35b458 126 126 * shared buffer to the console. 127 127 */ 128 128 129 129 while (output_buffer.read_ptr != output_buffer.write_ptr) { 130 130 do_putchar(output_buffer.data[output_buffer.read_ptr]); … … 132 132 ((output_buffer.read_ptr) + 1) % OUTPUT_BUFFER_SIZE; 133 133 } 134 134 135 135 /* 136 136 * Read character from keyboard. 137 137 */ 138 138 139 139 uint64_t c; 140 140 if (__hypercall_fast_ret1(0, 0, 0, 0, 0, CONS_GETCHAR, &c) == HV_EOK) { … … 174 174 if (instance) 175 175 return; 176 176 177 177 instance = malloc(sizeof(niagara_instance_t), FRAME_ATOMIC); 178 178 instance->thread = thread_create(kniagarapoll, NULL, TASK, 179 179 THREAD_FLAG_UNCOUNTED, "kniagarapoll"); 180 180 181 181 if (!instance->thread) { 182 182 free(instance); … … 184 184 return; 185 185 } 186 186 187 187 instance->srlnin = NULL; 188 188 189 189 output_buffer.read_ptr = 0; 190 190 output_buffer.write_ptr = 0; 191 191 input_buffer.write_ptr = 0; 192 192 input_buffer.read_ptr = 0; 193 193 194 194 /* 195 195 * Set sysinfos and pareas so that the userspace counterpart of the … … 197 197 * buffers. 198 198 */ 199 199 200 200 sysinfo_set_item_val("fb", NULL, true); 201 201 sysinfo_set_item_val("fb.kind", NULL, 5); 202 202 203 203 sysinfo_set_item_val("niagara.outbuf.address", NULL, 204 204 KA2PA(&output_buffer)); … … 207 207 sysinfo_set_item_val("niagara.outbuf.datasize", NULL, 208 208 OUTPUT_BUFFER_SIZE); 209 209 210 210 sysinfo_set_item_val("niagara.inbuf.address", NULL, 211 211 KA2PA(&input_buffer)); … … 214 214 sysinfo_set_item_val("niagara.inbuf.datasize", NULL, 215 215 INPUT_BUFFER_SIZE); 216 216 217 217 outbuf_parea.pbase = (uintptr_t) (KA2PA(&output_buffer)); 218 218 outbuf_parea.frames = 1; … … 220 220 outbuf_parea.mapped = false; 221 221 ddi_parea_register(&outbuf_parea); 222 222 223 223 inbuf_parea.pbase = (uintptr_t) (KA2PA(&input_buffer)); 224 224 inbuf_parea.frames = 1; … … 226 226 inbuf_parea.mapped = false; 227 227 ddi_parea_register(&inbuf_parea); 228 228 229 229 outdev_t *niagara_dev = malloc(sizeof(outdev_t), FRAME_ATOMIC); 230 230 outdev_initialize("niagara_dev", niagara_dev, &niagara_ops); … … 238 238 { 239 239 niagara_init(); 240 240 241 241 if (instance) { 242 242 srln_instance_t *srln_instance = srln_init(); … … 244 244 indev_t *sink = stdin_wire(); 245 245 indev_t *srln = srln_wire(srln_instance, sink); 246 246 247 247 instance->srlnin = srln; 248 248 thread_ready(instance->thread); 249 249 } 250 250 } 251 251 252 252 return instance; 253 253 } -
kernel/arch/sparc64/src/drivers/pci.c
r3061bc1 ra35b458 183 183 if (!prop || !prop->value) 184 184 return NULL; 185 185 186 186 if (str_cmp(prop->value, "SUNW,sabre") == 0) { 187 187 /* -
kernel/arch/sparc64/src/drivers/scr.c
r3061bc1 ra35b458 67 67 ofw_sbus_reg_t *sbus_reg; 68 68 const char *name; 69 69 70 70 name = ofw_tree_node_name(node); 71 71 72 72 if (str_cmp(name, "SUNW,m64B") == 0) 73 73 scr_type = SCR_ATYFB; … … 80 80 else if (str_cmp(name, "QEMU,VGA") == 0) 81 81 scr_type = SCR_QEMU_VGA; 82 82 83 83 if (scr_type == SCR_UNKNOWN) { 84 84 log(LF_ARCH, LVL_ERROR, "Unknown screen device."); 85 85 return; 86 86 } 87 87 88 88 uintptr_t fb_addr; 89 89 unsigned int fb_offset = 0; … … 121 121 return; 122 122 } 123 123 124 124 pci_reg = &((ofw_pci_reg_t *) prop->value)[1]; 125 125 126 126 if (!ofw_pci_reg_absolutize(node, pci_reg, &pci_abs_reg)) { 127 127 log(LF_ARCH, LVL_ERROR, … … 129 129 return; 130 130 } 131 131 132 132 if (!ofw_pci_apply_ranges(node->parent, &pci_abs_reg, 133 133 &fb_addr)) { … … 136 136 return; 137 137 } 138 138 139 139 switch (fb_depth) { 140 140 case 8: … … 159 159 return; 160 160 } 161 161 162 162 break; 163 163 case SCR_XVR: … … 167 167 return; 168 168 } 169 169 170 170 pci_reg = &((ofw_pci_reg_t *) prop->value)[1]; 171 171 172 172 if (!ofw_pci_reg_absolutize(node, pci_reg, &pci_abs_reg)) { 173 173 log(LF_ARCH, LVL_ERROR, … … 175 175 return; 176 176 } 177 177 178 178 if (!ofw_pci_apply_ranges(node->parent, &pci_abs_reg, 179 179 &fb_addr)) { … … 207 207 return; 208 208 } 209 209 210 210 break; 211 211 case SCR_FFB: … … 231 231 return; 232 232 } 233 233 234 234 sbus_reg = &((ofw_sbus_reg_t *) prop->value)[0]; 235 235 if (!ofw_sbus_apply_ranges(node->parent, sbus_reg, &fb_addr)) { … … 238 238 return; 239 239 } 240 240 241 241 break; 242 242 … … 297 297 .visual = visual, 298 298 }; 299 299 300 300 outdev_t *fbdev = fb_init(&props); 301 301 if (fbdev) -
kernel/arch/sparc64/src/drivers/tick.c
r3061bc1 ra35b458 89 89 90 90 softint.value = softint_read(); 91 91 92 92 /* 93 93 * Make sure we are servicing interrupt_level_14 94 94 */ 95 95 assert(n == TT_INTERRUPT_LEVEL_14); 96 96 97 97 /* 98 98 * Make sure we are servicing TICK_INT. … … 106 106 clear.tick_int = 1; 107 107 clear_softint_write(clear.value); 108 108 109 109 /* 110 110 * Reprogram the compare register. -
kernel/arch/sparc64/src/fpu_context.c
r3061bc1 ra35b458 67 67 * GCC (4.1.1) can't handle more than 30 operands in one asm statement. 68 68 */ 69 69 70 70 asm volatile ( 71 71 "std %%f32, %0\n" … … 90 90 "=m" (fctx->d[28]), "=m" (fctx->d[29]), "=m" (fctx->d[30]), "=m" (fctx->d[31]) 91 91 ); 92 92 93 93 asm volatile ("stx %%fsr, %0\n" : "=m" (fctx->fsr)); 94 94 } … … 119 119 "m" (fctx->d[12]), "m" (fctx->d[13]), "m" (fctx->d[14]), "m" (fctx->d[15]) 120 120 ); 121 121 122 122 /* 123 123 * We need to split loading of the floating-point registers because 124 124 * GCC (4.1.1) can't handle more than 30 operands in one asm statement. 125 125 */ 126 126 127 127 asm volatile ( 128 128 "ldd %0, %%f32\n" … … 148 148 "m" (fctx->d[28]), "m" (fctx->d[29]), "m" (fctx->d[30]), "m" (fctx->d[31]) 149 149 ); 150 150 151 151 asm volatile ("ldx %0, %%fsr\n" : : "m" (fctx->fsr)); 152 152 } … … 155 155 { 156 156 pstate_reg_t pstate; 157 157 158 158 pstate.value = pstate_read(); 159 159 pstate.pef = true; … … 164 164 { 165 165 pstate_reg_t pstate; 166 166 167 167 pstate.value = pstate_read(); 168 168 pstate.pef = false; -
kernel/arch/sparc64/src/mm/sun4u/as.c
r3061bc1 ra35b458 69 69 tsb_entry_t *tsb = (tsb_entry_t *) PA2KA(tsb_base); 70 70 memsetb(tsb, TSB_SIZE, 0); 71 71 72 72 as->arch.itsb = tsb; 73 73 as->arch.dtsb = tsb + ITSB_ENTRY_COUNT; 74 74 #endif 75 75 76 76 return EOK; 77 77 } … … 81 81 #ifdef CONFIG_TSB 82 82 frame_free(KA2PA((uintptr_t) as->arch.itsb), TSB_FRAMES); 83 83 84 84 return TSB_FRAMES; 85 85 #else … … 93 93 tsb_invalidate(as, 0, (size_t) -1); 94 94 #endif 95 95 96 96 return 0; 97 97 } … … 107 107 { 108 108 tlb_context_reg_t ctx; 109 109 110 110 /* 111 111 * Note that we don't and may not lock the address space. That's ok … … 115 115 * 116 116 */ 117 117 118 118 /* 119 119 * Write ASID to secondary context register. The primary context … … 126 126 ctx.context = as->asid; 127 127 mmu_secondary_context_write(ctx.v); 128 128 129 129 #ifdef CONFIG_TSB 130 130 uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH); 131 131 132 132 assert(as->arch.itsb); 133 133 assert(as->arch.dtsb); 134 134 135 135 uintptr_t tsb = (uintptr_t) as->arch.itsb; 136 136 137 137 if (!overlaps(tsb, TSB_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) { 138 138 /* … … 145 145 dtlb_insert_mapping(tsb, KA2PA(tsb), PAGESIZE_64K, true, true); 146 146 } 147 147 148 148 /* 149 149 * Setup TSB Base registers. … … 151 151 */ 152 152 tsb_base_reg_t tsb_base_reg; 153 153 154 154 tsb_base_reg.value = 0; 155 155 tsb_base_reg.size = TSB_BASE_REG_SIZE; 156 156 tsb_base_reg.split = 0; 157 157 158 158 tsb_base_reg.base = ((uintptr_t) as->arch.itsb) >> MMU_PAGE_WIDTH; 159 159 itsb_base_write(tsb_base_reg.value); 160 160 tsb_base_reg.base = ((uintptr_t) as->arch.dtsb) >> MMU_PAGE_WIDTH; 161 161 dtsb_base_write(tsb_base_reg.value); 162 162 163 163 #if defined (US3) 164 164 /* … … 198 198 * 199 199 */ 200 200 201 201 #ifdef CONFIG_TSB 202 202 uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH); 203 203 204 204 assert(as->arch.itsb); 205 205 assert(as->arch.dtsb); 206 206 207 207 uintptr_t tsb = (uintptr_t) as->arch.itsb; 208 208 209 209 if (!overlaps(tsb, TSB_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) { 210 210 /* -
kernel/arch/sparc64/src/mm/sun4u/frame.c
r3061bc1 ra35b458 48 48 { 49 49 unsigned int i; 50 50 51 51 for (i = 0; i < memmap.cnt; i++) { 52 52 uintptr_t base; … … 62 62 size = ALIGN_DOWN(memmap.zones[i].size - 63 63 (base - ((uintptr_t) memmap.zones[i].start)), FRAME_SIZE); 64 64 65 65 if (!frame_adjust_zone_bounds(low, &base, &size)) 66 66 continue; 67 67 68 68 pfn_t confdata; 69 69 pfn_t pfn = ADDR2PFN(base); … … 74 74 if (confdata == ADDR2PFN(KA2PA(PFN2ADDR(0)))) 75 75 confdata = ADDR2PFN(KA2PA(PFN2ADDR(2))); 76 76 77 77 zone_create(pfn, count, confdata, 78 78 ZONE_AVAILABLE | ZONE_LOWMEM); … … 90 90 if (config.cpu_active > 1) 91 91 return; 92 92 93 93 frame_common_arch_init(true); 94 94 95 95 /* 96 96 * On sparc64, physical memory can start on a non-zero address. -
kernel/arch/sparc64/src/mm/sun4u/tlb.c
r3061bc1 ra35b458 178 178 tag.context = t->as->asid; 179 179 tag.vpn = pg.vpn; 180 180 181 181 itlb_tag_access_write(tag.value); 182 182 183 183 data.value = 0; 184 184 data.v = true; … … 190 190 data.w = false; 191 191 data.g = t->g; 192 192 193 193 itlb_data_in_write(data.value); 194 194 } … … 353 353 tlb_data_t d; 354 354 tlb_tag_read_reg_t t; 355 355 356 356 printf("I-TLB contents:\n"); 357 357 for (i = 0; i < ITLB_ENTRY_COUNT; i++) { … … 377 377 tlb_data_t d; 378 378 tlb_tag_read_reg_t t; 379 379 380 380 printf("TLB_ISMALL contents:\n"); 381 381 for (i = 0; i < tlb_ismall_size(); i++) { … … 384 384 print_tlb_entry(i, t, d); 385 385 } 386 386 387 387 printf("TLB_IBIG contents:\n"); 388 388 for (i = 0; i < tlb_ibig_size(); i++) { … … 391 391 print_tlb_entry(i, t, d); 392 392 } 393 393 394 394 printf("TLB_DSMALL contents:\n"); 395 395 for (i = 0; i < tlb_dsmall_size(); i++) { … … 398 398 print_tlb_entry(i, t, d); 399 399 } 400 400 401 401 printf("TLB_DBIG_1 contents:\n"); 402 402 for (i = 0; i < tlb_dbig_size(); i++) { … … 405 405 print_tlb_entry(i, t, d); 406 406 } 407 407 408 408 printf("TLB_DBIG_2 contents:\n"); 409 409 for (i = 0; i < tlb_dbig_size(); i++) { … … 423 423 sfsr.value = dtlb_sfsr_read(); 424 424 sfar = dtlb_sfar_read(); 425 425 426 426 #if defined (US) 427 427 printf("DTLB SFSR: asi=%#x, ft=%#x, e=%d, ct=%d, pr=%d, w=%d, ow=%d, " … … 433 433 sfsr.e, sfsr.ct, sfsr.pr, sfsr.w, sfsr.ow, sfsr.fv); 434 434 #endif 435 435 436 436 printf("DTLB SFAR: address=%p\n", (void *) sfar); 437 437 438 438 dtlb_sfsr_write(0); 439 439 } … … 446 446 sfsr.value = dtlb_sfsr_read(); 447 447 sfar = dtlb_sfar_read(); 448 448 449 449 #if defined (US) 450 450 printf("DTLB SFSR: asi=%#x, ft=%#x, e=%d, ct=%d, pr=%d, w=%d, ow=%d, " … … 456 456 sfsr.e, sfsr.ct, sfsr.pr, sfsr.w, sfsr.ow, sfsr.fv); 457 457 #endif 458 458 459 459 printf("DTLB SFAR: address=%p\n", (void *) sfar); 460 460 461 461 dtlb_sfsr_write(0); 462 462 } … … 467 467 { 468 468 int i; 469 469 470 470 /* 471 471 * Walk all ITLB and DTLB entries and remove all unlocked mappings. … … 521 521 { 522 522 tlb_context_reg_t pc_save, ctx; 523 523 524 524 /* switch to nucleus because we are mapped by the primary context */ 525 525 nucleus_enter(); 526 526 527 527 ctx.v = pc_save.v = mmu_primary_context_read(); 528 528 ctx.context = asid; 529 529 mmu_primary_context_write(ctx.v); 530 530 531 531 itlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_PRIMARY, 0); 532 532 dtlb_demap(TLB_DEMAP_CONTEXT, TLB_DEMAP_PRIMARY, 0); 533 533 534 534 mmu_primary_context_write(pc_save.v); 535 535 536 536 nucleus_leave(); 537 537 } … … 548 548 unsigned int i; 549 549 tlb_context_reg_t pc_save, ctx; 550 550 551 551 /* switch to nucleus because we are mapped by the primary context */ 552 552 nucleus_enter(); 553 553 554 554 ctx.v = pc_save.v = mmu_primary_context_read(); 555 555 ctx.context = asid; 556 556 mmu_primary_context_write(ctx.v); 557 557 558 558 for (i = 0; i < cnt * MMU_PAGES_PER_PAGE; i++) { 559 559 itlb_demap(TLB_DEMAP_PAGE, TLB_DEMAP_PRIMARY, … … 562 562 page + i * MMU_PAGE_SIZE); 563 563 } 564 564 565 565 mmu_primary_context_write(pc_save.v); 566 566 567 567 nucleus_leave(); 568 568 } -
kernel/arch/sparc64/src/mm/sun4u/tsb.c
r3061bc1 ra35b458 57 57 size_t i; 58 58 size_t cnt; 59 59 60 60 assert(as->arch.itsb); 61 61 assert(as->arch.dtsb); 62 62 63 63 i0 = (page >> MMU_PAGE_WIDTH) & ITSB_ENTRY_MASK; 64 64 … … 67 67 else 68 68 cnt = pages * 2; 69 69 70 70 for (i = 0; i < cnt; i++) { 71 71 as->arch.itsb[(i0 + i) & ITSB_ENTRY_MASK].tag.invalid = true; … … 86 86 87 87 assert(index <= 1); 88 88 89 89 as = t->as; 90 90 entry = ((t->page >> MMU_PAGE_WIDTH) + index) & ITSB_ENTRY_MASK; … … 112 112 tte->data.p = t->k; /* p as privileged, k as kernel */ 113 113 tte->data.v = t->p; /* v as valid, p as present */ 114 114 115 115 write_barrier(); 116 116 117 117 tte->tag.invalid = false; /* mark the entry as valid */ 118 118 } … … 129 129 tsb_entry_t *tte; 130 130 size_t entry; 131 131 132 132 assert(index <= 1); 133 133 … … 161 161 tte->data.w = ro ? false : t->w; 162 162 tte->data.v = t->p; 163 163 164 164 write_barrier(); 165 165 166 166 tte->tag.invalid = false; /* mark the entry as valid */ 167 167 } -
kernel/arch/sparc64/src/mm/sun4v/as.c
r3061bc1 ra35b458 79 79 as->arch.tsb_description.reserved = 0; 80 80 as->arch.tsb_description.context = 0; 81 81 82 82 memsetb(tsb, TSB_SIZE, 0); 83 83 #endif 84 84 85 85 return EOK; 86 86 } … … 90 90 #ifdef CONFIG_TSB 91 91 frame_free(as->arch.tsb_description.tsb_base, TSB_FRAMES); 92 92 93 93 return TSB_FRAMES; 94 94 #else … … 102 102 tsb_invalidate(as, 0, (size_t) -1); 103 103 #endif 104 104 105 105 return EOK; 106 106 } … … 117 117 { 118 118 mmu_secondary_context_write(as->asid); 119 119 120 120 #ifdef CONFIG_TSB 121 121 uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH); 122 122 123 123 assert(as->arch.tsb_description.tsb_base); 124 124 uintptr_t tsb = PA2KA(as->arch.tsb_description.tsb_base); 125 125 126 126 if (!overlaps(tsb, TSB_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) { 127 127 /* … … 134 134 dtlb_insert_mapping(tsb, KA2PA(tsb), PAGESIZE_64K, true, true); 135 135 } 136 136 137 137 __hypercall_fast2(MMU_TSB_CTXNON0, 1, KA2PA(&as->arch.tsb_description)); 138 138 #endif … … 156 156 * 157 157 */ 158 158 159 159 #ifdef CONFIG_TSB 160 160 uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH); 161 161 162 162 assert(as->arch.tsb_description.tsb_base); 163 163 164 164 uintptr_t tsb = PA2KA(as->arch.tsb_description.tsb_base); 165 165 166 166 if (!overlaps(tsb, TSB_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) { 167 167 /* -
kernel/arch/sparc64/src/mm/sun4v/frame.c
r3061bc1 ra35b458 48 48 { 49 49 unsigned int i; 50 50 51 51 for (i = 0; i < memmap.cnt; i++) { 52 52 uintptr_t base; … … 62 62 size = ALIGN_DOWN(memmap.zones[i].size - 63 63 (base - ((uintptr_t) memmap.zones[i].start)), FRAME_SIZE); 64 64 65 65 if (!frame_adjust_zone_bounds(low, &base, &size)) 66 66 continue; … … 74 74 if (confdata == ADDR2PFN(KA2PA(PFN2ADDR(0)))) 75 75 confdata = ADDR2PFN(KA2PA(PFN2ADDR(2))); 76 76 77 77 zone_create(pfn, count, confdata, 78 78 ZONE_AVAILABLE | ZONE_LOWMEM); -
kernel/arch/sparc64/src/mm/sun4v/tlb.c
r3061bc1 ra35b458 128 128 { 129 129 tte_data_t data; 130 130 131 131 data.value = 0; 132 132 data.v = true; … … 143 143 data.w = true; 144 144 data.size = pagesize; 145 145 146 146 if (locked) { 147 147 __hypercall_fast4( … … 163 163 { 164 164 tte_data_t data; 165 165 166 166 data.value = 0; 167 167 data.v = true; … … 178 178 data.w = ro ? false : t->w; 179 179 data.size = PAGESIZE_8K; 180 180 181 181 __hypercall_hyperfast( 182 182 t->page, t->as->asid, data.value, MMU_FLAG_DTLB, 0, MMU_MAP_ADDR); … … 190 190 { 191 191 tte_data_t data; 192 192 193 193 data.value = 0; 194 194 data.v = true; … … 203 203 data.w = false; 204 204 data.size = PAGESIZE_8K; 205 205 206 206 __hypercall_hyperfast( 207 207 t->page, t->as->asid, data.value, MMU_FLAG_ITLB, 0, MMU_MAP_ADDR); … … 387 387 { 388 388 unsigned int i; 389 389 390 390 /* switch to nucleus because we are mapped by the primary context */ 391 391 nucleus_enter(); -
kernel/arch/sparc64/src/mm/sun4v/tsb.c
r3061bc1 ra35b458 59 59 size_t i0, i; 60 60 size_t cnt; 61 61 62 62 assert(as->arch.tsb_description.tsb_base); 63 63 64 64 i0 = (page >> MMU_PAGE_WIDTH) & TSB_ENTRY_MASK; 65 65 … … 68 68 else 69 69 cnt = pages; 70 70 71 71 tsb = (tsb_entry_t *) PA2KA(as->arch.tsb_description.tsb_base); 72 72 for (i = 0; i < cnt; i++) … … 87 87 as = t->as; 88 88 index = (t->page >> MMU_PAGE_WIDTH) & TSB_ENTRY_MASK; 89 89 90 90 tsb = (tsb_entry_t *) PA2KA(as->arch.tsb_description.tsb_base); 91 91 tte = &tsb[index]; … … 114 114 tte->data.w = false; 115 115 tte->data.size = PAGESIZE_8K; 116 116 117 117 write_barrier(); 118 118 119 119 tte->data.v = t->p; /* v as valid, p as present */ 120 120 } … … 162 162 tte->data.w = ro ? false : t->w; 163 163 tte->data.size = PAGESIZE_8K; 164 164 165 165 write_barrier(); 166 166 167 167 tte->data.v = t->p; /* v as valid, p as present */ 168 168 } -
kernel/arch/sparc64/src/proc/sun4v/scheduler.c
r3061bc1 ra35b458 71 71 THREAD->arch.uspace_window_buffer = 72 72 (uint8_t *) asi_u64_read(ASI_SCRATCHPAD, SCRATCHPAD_WBUF); 73 73 74 74 } 75 75 } -
kernel/arch/sparc64/src/smp/sun4u/ipi.c
r3061bc1 ra35b458 97 97 * we explicitly disable preemption. 98 98 */ 99 99 100 100 preemption_disable(); 101 101 102 102 status = asi_u64_read(ASI_INTR_DISPATCH_STATUS, 0); 103 103 if (status & INTR_DISPATCH_STATUS_BUSY) 104 104 panic("Interrupt Dispatch Status busy bit set\n"); 105 105 106 106 assert(!(pstate_read() & PSTATE_IE_BIT)); 107 107 108 108 do { 109 109 set_intr_w_data(func); … … 111 111 (mid << INTR_VEC_DISPATCH_MID_SHIFT) | 112 112 VA_INTR_W_DISPATCH, 0); 113 113 114 114 membar(); 115 115 116 116 do { 117 117 status = asi_u64_read(ASI_INTR_DISPATCH_STATUS, 0); 118 118 } while (status & INTR_DISPATCH_STATUS_BUSY); 119 119 120 120 done = !(status & INTR_DISPATCH_STATUS_NACK); 121 121 if (!done) { … … 128 128 } 129 129 } while (!done); 130 130 131 131 preemption_enable(); 132 132 } … … 147 147 { 148 148 unsigned int i; 149 149 150 150 void (* func)(void); 151 151 152 152 switch (ipi) { 153 153 case IPI_TLB_SHOOTDOWN: … … 158 158 break; 159 159 } 160 160 161 161 /* 162 162 * As long as we don't support hot-plugging … … 165 165 * without locking. 166 166 */ 167 167 168 168 for (i = 0; i < config.cpu_active; i++) { 169 169 if (&cpus[i] == CPU) … … 187 187 { 188 188 assert(&cpus[cpu_id] != CPU); 189 189 190 190 if (ipi == IPI_SMP_CALL) { 191 191 cross_call(cpus[cpu_id].arch.mid, smp_call_ipi_recv); -
kernel/arch/sparc64/src/smp/sun4u/smp.c
r3061bc1 ra35b458 62 62 ofw_tree_node_t *node; 63 63 unsigned int cnt = 0; 64 64 65 65 if (is_us() || is_us_iii()) { 66 66 node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); … … 76 76 } 77 77 } 78 78 79 79 config.cpu_count = max(1, cnt); 80 80 } … … 89 89 uint32_t mid; 90 90 ofw_tree_property_t *prop; 91 91 92 92 /* 'upa-portid' for US, 'portid' for US-III, 'cpuid' for US-IV */ 93 93 prop = ofw_tree_getprop(node, "upa-portid"); … … 96 96 if ((!prop) || (!prop->value)) 97 97 prop = ofw_tree_getprop(node, "cpuid"); 98 98 99 99 if (!prop || prop->value == NULL) 100 100 return; 101 101 102 102 mid = *((uint32_t *) prop->value); 103 103 if (CPU->arch.mid == mid) … … 105 105 106 106 waking_up_mid = mid; 107 107 108 108 if (waitq_sleep_timeout(&ap_completion_wq, 1000000, 109 109 SYNCH_FLAGS_NONE, NULL) == ETIMEOUT) … … 117 117 ofw_tree_node_t *node; 118 118 int i; 119 119 120 120 if (is_us() || is_us_iii()) { 121 121 node = ofw_tree_find_child_by_device_type(cpus_parent(), "cpu"); -
kernel/arch/sparc64/src/smp/sun4v/ipi.c
r3061bc1 ra35b458 96 96 { 97 97 void (* func)(void); 98 98 99 99 switch (ipi) { 100 100 case IPI_TLB_SHOOTDOWN: -
kernel/arch/sparc64/src/smp/sun4v/smp.c
r3061bc1 ra35b458 359 359 if (__hypercall_fast1(CPU_STOP, cpuid) != EOK) 360 360 return false; 361 361 362 362 /* wait for the CPU to stop */ 363 363 uint64_t state; … … 365 365 while (state == CPU_STATE_RUNNING) 366 366 __hypercall_fast_ret1(cpuid, 0, 0, 0, 0, CPU_STATE, &state); 367 367 368 368 /* make the CPU run again and execute HelenOS code */ 369 369 if (__hypercall_fast4(CPU_START, cpuid, … … 372 372 return false; 373 373 #endif 374 374 375 375 if (waitq_sleep_timeout(&ap_completion_wq, 10000000, 376 376 SYNCH_FLAGS_NONE, NULL) == ETIMEOUT) 377 377 printf("%s: waiting for processor (cpuid = %" PRIu64 ") timed out\n", 378 378 __func__, cpuid); 379 379 380 380 return true; 381 381 } -
kernel/arch/sparc64/src/sparc64.c
r3061bc1 ra35b458 79 79 if (options) { 80 80 ofw_tree_property_t *prop; 81 81 82 82 prop = ofw_tree_getprop(options, "boot-args"); 83 83 if (prop && prop->value) { -
kernel/arch/sparc64/src/sun4u/asm.S
r3061bc1 ra35b458 102 102 wrpr %g1, TSTATE_IE_BIT, %tstate 103 103 wrpr %i0, 0, %tnpc 104 104 105 105 /* 106 106 * Set primary context according to secondary context. … … 117 117 */ 118 118 wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(1), %wstate 119 119 120 120 done ! jump to userspace 121 121 FUNCTION_END(switch_to_userspace) -
kernel/arch/sparc64/src/sun4u/sparc64.c
r3061bc1 ra35b458 72 72 /* Copy init task info. */ 73 73 init.cnt = min3(bootinfo->taskmap.cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); 74 74 75 75 size_t i; 76 76 for (i = 0; i < init.cnt; i++) { … … 80 80 bootinfo->taskmap.tasks[i].name); 81 81 } 82 82 83 83 /* Copy physical memory map. */ 84 84 memmap.total = bootinfo->memmap.total; … … 88 88 memmap.zones[i].size = bootinfo->memmap.zones[i].size; 89 89 } 90 90 91 91 /* Copy boot allocations info. */ 92 92 ballocs.base = bootinfo->ballocs.base; 93 93 ballocs.size = bootinfo->ballocs.size; 94 94 95 95 ofw_tree_init(bootinfo->ofw_root); 96 96 } … … 111 111 /* Map OFW information into sysinfo */ 112 112 ofw_sysinfo_map(); 113 113 114 114 /* 115 115 * We have 2^11 different interrupt vectors. … … 167 167 (ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT) + STACK_BIAS), 168 168 (uintptr_t) kernel_uarg->uspace_uarg); 169 169 170 170 /* Not reached */ 171 171 while (1); -
kernel/arch/sparc64/src/sun4u/start.S
r3061bc1 ra35b458 85 85 ! Get bits (PHYSMEM_ADDR_SIZE - 1):13 of physmem_base. 86 86 srlx %l6, 13, %l5 87 87 88 88 ! l5 <= physmem_base[(PHYSMEM_ADDR_SIZE - 1):13] 89 89 sllx %l5, 13 + (63 - (PHYSMEM_ADDR_SIZE - 1)), %l5 … … 101 101 wrpr %g0, NWINDOWS - 1, %cleanwin ! prevent needless clean_window 102 102 ! traps for kernel 103 103 104 104 wrpr %g0, 0, %wstate ! use default spill/fill trap 105 105 … … 132 132 set (TLB_DEMAP_CONTEXT << TLB_DEMAP_TYPE_SHIFT) | (context_id << \ 133 133 TLB_DEMAP_CONTEXT_SHIFT), %r1 134 134 135 135 ! demap context 0 136 136 SET_TLB_DEMAP_CMD(g1, TLB_DEMAP_NUCLEUS) … … 161 161 sllx %r2, TTE_V_SHIFT, %r2; \ 162 162 or %r1, %r2, %r1; 163 163 164 164 ! write DTLB data and install the kernel mapping 165 165 SET_TLB_DATA(g1, g2, TTE_L | TTE_W) ! use non-global mapping … … 182 182 stxa %g1, [%g0] ASI_DTLB_DATA_IN_REG 183 183 membar #Sync 184 184 185 185 /* 186 186 * Now is time to take over the IMMU. Unfortunatelly, it cannot be done … … 202 202 * the taken over DTLB. 203 203 */ 204 204 205 205 set kernel_image_start, %g5 206 206 207 207 ! write ITLB tag of context 1 208 208 SET_TLB_TAG(g1, MEM_CONTEXT_TEMP) … … 215 215 stxa %g1, [%g0] ASI_ITLB_DATA_IN_REG 216 216 flush %g5 217 217 218 218 ! switch to context 1 219 219 mov MEM_CONTEXT_TEMP, %g1 220 220 stxa %g1, [VA_PRIMARY_CONTEXT_REG] %asi ! ASI_DMMU is correct here !!! 221 221 flush %g5 222 222 223 223 ! demap context 0 224 224 SET_TLB_DEMAP_CMD(g1, TLB_DEMAP_NUCLEUS) 225 225 stxa %g0, [%g1] ASI_IMMU_DEMAP 226 226 flush %g5 227 227 228 228 ! write ITLB tag of context 0 229 229 SET_TLB_TAG(g1, MEM_CONTEXT_KERNEL) … … 244 244 stxa %g0, [%g1] ASI_IMMU_DEMAP 245 245 flush %g5 246 246 247 247 ! set context 0 in the primary context register 248 248 stxa %g0, [VA_PRIMARY_CONTEXT_REG] %asi ! ASI_DMMU is correct here !!! 249 249 flush %g5 250 250 251 251 ! leave nucleus - using primary context, i.e. context 0 252 252 wrpr %g0, 0, %tl … … 271 271 or %l3, %l5, %l3 272 272 stx %l3, [%l4 + %lo(kernel_8k_tlb_data_template)] 273 273 274 274 ! flush the whole D-cache 275 275 set (DCACHE_SIZE - DCACHE_LINE_SIZE), %g1 276 276 stxa %g0, [%g1] ASI_DCACHE_TAG 277 277 278 278 0: 279 279 membar #Sync … … 282 282 stxa %g0, [%g1] ASI_DCACHE_TAG 283 283 membar #Sync 284 284 285 285 /* 286 286 * So far, we have not touched the stack. … … 290 290 or %sp, %lo(temporary_boot_stack), %sp 291 291 sub %sp, STACK_BIAS, %sp 292 292 293 293 /* 294 294 * Call sparc64_pre_main(bootinfo) … … 296 296 call sparc64_pre_main 297 297 mov %o1, %o0 298 298 299 299 /* 300 300 * Create the first stack frame. … … 372 372 /* Not reached. */ 373 373 #endif 374 374 375 375 0: 376 376 ba,a %xcc, 0b -
kernel/arch/sparc64/src/sun4v/asm.S
r3061bc1 ra35b458 58 58 wrpr %g1, TSTATE_IE_BIT, %tstate 59 59 wrpr %i0, 0, %tnpc 60 60 61 61 /* 62 62 * Set primary context according to secondary context. -
kernel/arch/sparc64/src/sun4v/md.c
r3061bc1 ra35b458 244 244 char *head; 245 245 more = str_parse_head(&name, &head); 246 246 247 247 while (md_next_child(&node)) { 248 248 element_idx_t child = md_get_child_node(node); … … 292 292 return true; 293 293 } 294 294 295 295 (*node)++; 296 296 } while (element->tag != LIST_END); -
kernel/arch/sparc64/src/sun4v/sparc64.c
r3061bc1 ra35b458 74 74 /* Copy init task info. */ 75 75 init.cnt = min3(bootinfo->taskmap.cnt, TASKMAP_MAX_RECORDS, CONFIG_INIT_TASKS); 76 76 77 77 size_t i; 78 78 for (i = 0; i < init.cnt; i++) { … … 82 82 bootinfo->taskmap.tasks[i].name); 83 83 } 84 84 85 85 /* Copy physical memory map. */ 86 86 memmap.total = bootinfo->memmap.total; … … 90 90 memmap.zones[i].size = bootinfo->memmap.zones[i].size; 91 91 } 92 92 93 93 md_init(); 94 94 } … … 109 109 /* Map OFW information into sysinfo */ 110 110 ofw_sysinfo_map(); 111 111 112 112 /* 113 113 * We have 2^11 different interrupt vectors. … … 165 165 (ALIGN_UP(STACK_ITEM_SIZE, STACK_ALIGNMENT) + STACK_BIAS), 166 166 (uintptr_t) kernel_uarg->uspace_uarg); 167 167 168 168 /* Not reached */ 169 169 while (1); -
kernel/arch/sparc64/src/sun4v/start.S
r3061bc1 ra35b458 115 115 ! Get bits (PHYSMEM_ADDR_SIZE - 1):13 of physmem_base. 116 116 srlx %l6, 13, %l5 117 117 118 118 ! l5 <= physmem_base[(PHYSMEM_ADDR_SIZE - 1):13] 119 119 sllx %l5, 13 + (63 - (PHYSMEM_ADDR_SIZE - 1)), %l5 … … 130 130 wrpr %g0, NWINDOWS - 1, %cleanwin ! prevent needless clean_window 131 131 ! traps for kernel 132 132 133 133 wrpr %g0, 0, %wstate ! use default spill/fill trap 134 134 … … 252 252 call sparc64_pre_main 253 253 or %l1, %g0, %o0 254 254 255 255 /* 256 256 * Create the first stack frame. -
kernel/arch/sparc64/src/trap/exception.c
r3061bc1 ra35b458 48 48 const char *tpcs = symtab_fmt_name_lookup(istate->tpc); 49 49 const char *tnpcs = symtab_fmt_name_lookup(istate->tnpc); 50 50 51 51 printf("TSTATE=%#" PRIx64 "\n", istate->tstate); 52 52 printf("TPC=%#" PRIx64 " (%s)\n", istate->tpc, tpcs); … … 100 100 { 101 101 fprs_reg_t fprs; 102 102 103 103 fprs.value = fprs_read(); 104 104 if (!fprs.fef) { -
kernel/arch/sparc64/src/trap/sun4u/interrupt.c
r3061bc1 ra35b458 58 58 if (status & (!INTR_DISPATCH_STATUS_BUSY)) 59 59 panic("Interrupt Dispatch Status busy bit not set\n"); 60 60 61 61 uint64_t intrcv = asi_u64_read(ASI_INTR_RECEIVE, 0); 62 62 #if defined (US) … … 65 65 uint64_t data0 = asi_u64_read(ASI_INTR_R, VA_INTR_R_DATA_0); 66 66 #endif 67 67 68 68 irq_t *irq = irq_dispatch_and_lock(data0); 69 69 if (irq) { … … 72 72 */ 73 73 irq->handler(irq); 74 74 75 75 /* 76 76 * See if there is a clear-interrupt-routine and call it. … … 78 78 if (irq->cir) 79 79 irq->cir(irq->cir_arg, irq->inr); 80 80 81 81 irq_spinlock_unlock(&irq->lock, false); 82 82 } else if (data0 > config.base) { … … 103 103 #endif 104 104 } 105 105 106 106 membar(); 107 107 asi_u64_write(ASI_INTR_RECEIVE, 0, 0); -
kernel/arch/sparc64/src/trap/sun4u/trap_table.S
r3061bc1 ra35b458 502 502 .if NOT(\is_syscall) 503 503 rdpr %tstate, %g3 504 504 505 505 /* 506 506 * One of the ways this handler can be invoked is after a nested MMU trap from … … 576 576 */ 577 577 wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(0), %wstate 578 578 579 579 /* 580 580 * Copy arguments. … … 605 605 */ 606 606 stx %g4, [%sp + STACK_BIAS + ISTATE_OFFSET_Y] 607 607 608 608 wrpr %g0, 0, %tl 609 609 wrpr %g0, PSTATE_PRIV_BIT | PSTATE_PEF_BIT, %pstate 610 610 SAVE_GLOBALS 611 611 612 612 .if NOT(\is_syscall) 613 613 /* … … 629 629 wrpr %g0, PSTATE_AG_BIT | PSTATE_PRIV_BIT, %pstate 630 630 wrpr %g0, 1, %tl 631 631 632 632 /* 633 633 * Read TSTATE, TPC and TNPC from saved copy. … … 742 742 rd %pc, %g1 743 743 flush %g1 744 744 745 745 rdpr %cwp, %g1 746 746 rdpr %otherwin, %g2 … … 800 800 mov NWINDOWS - 2, %g1 ! use dealy slot for both cases 801 801 sub %g1, %g2, %g1 802 802 803 803 wrpr %g0, 0, %otherwin 804 804 wrpr %g1, 0, %cansave ! NWINDOWS - 2 - CANRESTORE … … 845 845 and %g1, NWINDOWS - 1, %g1 846 846 wrpr %g1, 0, %cwp ! CWP-- 847 847 848 848 .if \is_syscall 849 849 done -
kernel/arch/sparc64/src/trap/sun4v/trap_table.S
r3061bc1 ra35b458 606 606 and \tmpreg1, NWINDOWS - 1, \tmpreg1 ! modulo NWINDOWS 607 607 wrpr \tmpreg1, %cwp 608 608 609 609 ! spill to kernel stack 610 610 stx %l0, [%sp + STACK_BIAS + L0_OFFSET] … … 766 766 ldx [%sp + STACK_BIAS + ISTATE_OFFSET_Y], %g4 767 767 wr %g4, %y 768 768 769 769 /* If TSTATE.CWP + 1 == CWP, then we do not have to fix CWP. */ 770 770 and %g1, TSTATE_CWP_MASK, %l0 … … 871 871 and \tmpreg1, NWINDOWS - 1, \tmpreg1 ! modulo NWINDOWS 872 872 wrpr \tmpreg1, %cwp 873 873 874 874 ! spill to userspace window buffer 875 875 SAVE_TO_USPACE_WBUF \tmpreg3, \tmpreg1 … … 1028 1028 mov NWINDOWS - 2, %g1 ! use dealy slot for both cases 1029 1029 sub %g1, %g2, %g1 1030 1030 1031 1031 wrpr %g0, 0, %otherwin 1032 1032 wrpr %g1, 0, %cansave ! NWINDOWS - 2 - CANRESTORE … … 1073 1073 and %g1, NWINDOWS - 1, %g1 1074 1074 wrpr %g1, 0, %cwp ! CWP-- 1075 1075 1076 1076 .if \is_syscall 1077 1077 done
Note:
See TracChangeset
for help on using the changeset viewer.