source: mainline/kernel/arch/sparc64/src/trap/sun4v/trap_table.S

Last change on this file was a35b458, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 7 years ago

style: Remove trailing whitespace on _all_ lines, including empty ones, for particular file types.

Command used: tools/srepl '\s\+$' '' -- *.c *.h *.py *.sh *.s *.S *.ag

Currently, whitespace on empty lines is very inconsistent.
There are two basic choices: Either remove the whitespace, or keep empty lines
indented to the level of surrounding code. The former is AFAICT more common,
and also much easier to do automatically.

Alternatively, we could write script for automatic indentation, and use that
instead. However, if such a script exists, it's possible to use the indented
style locally, by having the editor apply relevant conversions on load/save,
without affecting remote repository. IMO, it makes more sense to adopt
the simpler rule.

  • Property mode set to 100644
File size: 31.2 KB
RevLine 
[8ac5fe7]1#
[df4ed85]2# Copyright (c) 2005 Jakub Jermar
[74cbac7d]3# Copyright (c) 2008 Pavel Rimsky
[8ac5fe7]4# All rights reserved.
5#
6# Redistribution and use in source and binary forms, with or without
7# modification, are permitted provided that the following conditions
8# are met:
9#
10# - Redistributions of source code must retain the above copyright
11# notice, this list of conditions and the following disclaimer.
12# - Redistributions in binary form must reproduce the above copyright
13# notice, this list of conditions and the following disclaimer in the
14# documentation and/or other materials provided with the distribution.
15# - The name of the author may not be used to endorse or promote products
16# derived from this software without specific prior written permission.
17#
18# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
19# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28#
29
30/**
[fd85ae5]31 * @file
32 * @brief This file contains kernel trap table.
[8ac5fe7]33 */
[7614565]34
35.register %g2, #scratch
36.register %g3, #scratch
37
[8ac5fe7]38.text
39
[a52e2f4]40#include <abi/asmtool.h>
[49b6d32]41#include <arch/trap/trap_table.h>
42#include <arch/trap/regwin.h>
[5b1ced0]43#include <arch/trap/interrupt.h>
[feb5915]44#include <arch/trap/exception.h>
[9314ee1]45#include <arch/trap/syscall.h>
[74cbac7d]46#include <arch/trap/sun4v/mmu.h>
47#include <arch/mm/sun4v/mmu.h>
[ee454eb]48#include <arch/mm/page.h>
[feb5915]49#include <arch/stack.h>
[74cbac7d]50#include <arch/sun4v/regdef.h>
[8c2214e]51#include <arch/sun4v/arch.h>
52#include <arch/sun4v/cpu.h>
[8ac5fe7]53
54#define TABLE_SIZE TRAP_TABLE_SIZE
55#define ENTRY_SIZE TRAP_TABLE_ENTRY_SIZE
56
57/*
[c43fa55]58 * Kernel trap table.
[8ac5fe7]59 */
60.align TABLE_SIZE
[a52e2f4]61SYMBOL(trap_table)
[8ac5fe7]62
[feb5915]63/* TT = 0x08, TL = 0, instruction_access_exception */
[8c2214e]64/* TT = 0x08, TL = 0, IAE_privilege_violation on UltraSPARC T2 */
[feb5915]65.org trap_table + TT_INSTRUCTION_ACCESS_EXCEPTION*ENTRY_SIZE
[a52e2f4]66SYMBOL(instruction_access_exception_tl0)
[cade9c1]67 mov TT_INSTRUCTION_ACCESS_EXCEPTION, %g2
68 clr %g5
[1b20da0]69 PREEMPTIBLE_HANDLER exc_dispatch
[8c2214e]70
71/* TT = 0x09, TL = 0, instruction_access_mmu_miss */
72.org trap_table + TT_INSTRUCTION_ACCESS_MMU_MISS*ENTRY_SIZE
[a52e2f4]73SYMBOL(instruction_access_mmu_miss_handler_tl0)
[40239b9]74 ba,a %xcc, fast_instruction_access_mmu_miss_handler_tl0
[e2bf639]75
76/* TT = 0x0a, TL = 0, instruction_access_error */
77.org trap_table + TT_INSTRUCTION_ACCESS_ERROR*ENTRY_SIZE
[a52e2f4]78SYMBOL(instruction_access_error_tl0)
[cade9c1]79 mov TT_INSTRUCTION_ACCESS_ERROR, %g2
80 clr %g5
81 PREEMPTIBLE_HANDLER exc_dispatch
[feb5915]82
[8c2214e]83/* TT = 0x0b, TL = 0, IAE_unauth_access */
84.org trap_table + TT_IAE_UNAUTH_ACCESS*ENTRY_SIZE
[a52e2f4]85SYMBOL(iae_unauth_access_tl0)
[cade9c1]86 mov TT_IAE_UNAUTH_ACCESS, %g2
87 clr %g5
[1b20da0]88 PREEMPTIBLE_HANDLER exc_dispatch
[8c2214e]89
90/* TT = 0x0c, TL = 0, IAE_nfo_page */
91.org trap_table + TT_IAE_NFO_PAGE*ENTRY_SIZE
[a52e2f4]92SYMBOL(iae_nfo_page_tl0)
[cade9c1]93 mov TT_IAE_NFO_PAGE, %g2
94 clr %g5
[1b20da0]95 PREEMPTIBLE_HANDLER exc_dispatch
[8c2214e]96
[7cb53f62]97/* TT = 0x10, TL = 0, illegal_instruction */
98.org trap_table + TT_ILLEGAL_INSTRUCTION*ENTRY_SIZE
[a52e2f4]99SYMBOL(illegal_instruction_tl0)
[cade9c1]100 mov TT_ILLEGAL_INSTRUCTION, %g2
101 clr %g5
[1b20da0]102 PREEMPTIBLE_HANDLER exc_dispatch
[e2bf639]103
104/* TT = 0x11, TL = 0, privileged_opcode */
105.org trap_table + TT_PRIVILEGED_OPCODE*ENTRY_SIZE
[a52e2f4]106SYMBOL(privileged_opcode_tl0)
[cade9c1]107 mov TT_PRIVILEGED_OPCODE, %g2
108 clr %g5
[1b20da0]109 PREEMPTIBLE_HANDLER exc_dispatch
[7cb53f62]110
[34d9469e]111/* TT = 0x12, TL = 0, unimplemented_LDD */
112.org trap_table + TT_UNIMPLEMENTED_LDD*ENTRY_SIZE
[a52e2f4]113SYMBOL(unimplemented_LDD_tl0)
[cade9c1]114 mov TT_UNIMPLEMENTED_LDD, %g2
115 clr %g5
[1b20da0]116 PREEMPTIBLE_HANDLER exc_dispatch
[34d9469e]117
118/* TT = 0x13, TL = 0, unimplemented_STD */
119.org trap_table + TT_UNIMPLEMENTED_STD*ENTRY_SIZE
[a52e2f4]120SYMBOL(unimplemented_STD_tl0)
[cade9c1]121 mov TT_UNIMPLEMENTED_STD, %g2
122 clr %g5
[1b20da0]123 PREEMPTIBLE_HANDLER exc_dispatch
[34d9469e]124
[8c2214e]125/* TT = 0x14, TL = 0, DAE_invalid_asi */
126.org trap_table + TT_DAE_INVALID_ASI*ENTRY_SIZE
[a52e2f4]127SYMBOL(dae_invalid_asi_tl0)
[cade9c1]128 mov TT_DAE_INVALID_ASI, %g2
129 clr %g5
[1b20da0]130 PREEMPTIBLE_HANDLER exc_dispatch
[8c2214e]131
132/* TT = 0x15, TL = 0, DAE_privilege_violation */
133.org trap_table + TT_DAE_PRIVILEGE_VIOLATION*ENTRY_SIZE
[a52e2f4]134SYMBOL(dae_privilege_violation_tl0)
[cade9c1]135 mov TT_DAE_PRIVILEGE_VIOLATION, %g2
136 clr %g5
[1b20da0]137 PREEMPTIBLE_HANDLER exc_dispatch
[8c2214e]138
139/* TT = 0x16, TL = 0, DAE_nc_page */
140.org trap_table + TT_DAE_NC_PAGE*ENTRY_SIZE
[a52e2f4]141SYMBOL(dae_nc_page_tl0)
[cade9c1]142 mov TT_DAE_NC_PAGE, %g2
143 clr %g5
[1b20da0]144 PREEMPTIBLE_HANDLER exc_dispatch
[8c2214e]145
146/* TT = 0x17, TL = 0, DAE_nfo_page */
147.org trap_table + TT_DAE_NFO_PAGE*ENTRY_SIZE
[a52e2f4]148SYMBOL(dae_nfo_page_tl0)
[cade9c1]149 mov TT_DAE_NFO_PAGE, %g2
150 clr %g5
[1b20da0]151 PREEMPTIBLE_HANDLER exc_dispatch
[8c2214e]152
[6eabb6e6]153/* TT = 0x20, TL = 0, fb_disabled handler */
154.org trap_table + TT_FP_DISABLED*ENTRY_SIZE
[a52e2f4]155SYMBOL(fp_disabled_tl0)
[cade9c1]156 mov TT_FP_DISABLED, %g2
157 clr %g5
[1b20da0]158 PREEMPTIBLE_HANDLER exc_dispatch
[6eabb6e6]159
[34d9469e]160/* TT = 0x21, TL = 0, fb_exception_ieee_754 handler */
161.org trap_table + TT_FP_EXCEPTION_IEEE_754*ENTRY_SIZE
[a52e2f4]162SYMBOL(fp_exception_ieee_754_tl0)
[cade9c1]163 mov TT_FP_EXCEPTION_IEEE_754, %g2
164 clr %g5
[1b20da0]165 PREEMPTIBLE_HANDLER exc_dispatch
[34d9469e]166
167/* TT = 0x22, TL = 0, fb_exception_other handler */
168.org trap_table + TT_FP_EXCEPTION_OTHER*ENTRY_SIZE
[a52e2f4]169SYMBOL(fp_exception_other_tl)
[cade9c1]170 mov TT_FP_EXCEPTION_OTHER, %g2
171 clr %g5
[1b20da0]172 PREEMPTIBLE_HANDLER exc_dispatch
[34d9469e]173
174/* TT = 0x23, TL = 0, tag_overflow */
175.org trap_table + TT_TAG_OVERFLOW*ENTRY_SIZE
[a52e2f4]176SYMBOL(tag_overflow_tl0)
[cade9c1]177 mov TT_TAG_OVERFLOW, %g2
178 clr %g5
[1b20da0]179 PREEMPTIBLE_HANDLER exc_dispatch
[34d9469e]180
[5b1ced0]181/* TT = 0x24, TL = 0, clean_window handler */
[c43fa55]182.org trap_table + TT_CLEAN_WINDOW*ENTRY_SIZE
[a52e2f4]183SYMBOL(clean_window_tl0)
[49b6d32]184 CLEAN_WINDOW_HANDLER
[8ac5fe7]185
[e2bf639]186/* TT = 0x28, TL = 0, division_by_zero */
187.org trap_table + TT_DIVISION_BY_ZERO*ENTRY_SIZE
[a52e2f4]188SYMBOL(division_by_zero_tl0)
[cade9c1]189 mov TT_DIVISION_BY_ZERO, %g2
190 clr %g5
[1b20da0]191 PREEMPTIBLE_HANDLER exc_dispatch
[e2bf639]192
193/* TT = 0x30, TL = 0, data_access_exception */
[8c2214e]194/* TT = 0x30, TL = 0, DAE_side_effect_page for UltraPSARC T2 */
[e2bf639]195.org trap_table + TT_DATA_ACCESS_EXCEPTION*ENTRY_SIZE
[a52e2f4]196SYMBOL(data_access_exception_tl0)
[cade9c1]197 mov TT_DATA_ACCESS_EXCEPTION, %g2
198 clr %g5
[1b20da0]199 PREEMPTIBLE_HANDLER exc_dispatch
[e2bf639]200
[8c2214e]201/* TT = 0x31, TL = 0, data_access_mmu_miss */
202.org trap_table + TT_DATA_ACCESS_MMU_MISS*ENTRY_SIZE
[a52e2f4]203SYMBOL(data_access_mmu_miss_tl0)
[40239b9]204 ba,a %xcc, fast_data_access_mmu_miss_handler_tl0
[8c2214e]205
[97f1691]206/* TT = 0x32, TL = 0, data_access_error */
207.org trap_table + TT_DATA_ACCESS_ERROR*ENTRY_SIZE
[a52e2f4]208SYMBOL(data_access_error_tl0)
[cade9c1]209 mov TT_DATA_ACCESS_ERROR, %g2
210 clr %g5
[1b20da0]211 PREEMPTIBLE_HANDLER exc_dispatch
[97f1691]212
[feb5915]213/* TT = 0x34, TL = 0, mem_address_not_aligned */
214.org trap_table + TT_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
[a52e2f4]215SYMBOL(mem_address_not_aligned_tl0)
[cade9c1]216 mov TT_MEM_ADDRESS_NOT_ALIGNED, %g2
217 clr %g5
[1b20da0]218 PREEMPTIBLE_HANDLER exc_dispatch
[e2bf639]219
[34d9469e]220/* TT = 0x35, TL = 0, LDDF_mem_address_not_aligned */
221.org trap_table + TT_LDDF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
[a52e2f4]222SYMBOL(LDDF_mem_address_not_aligned_tl0)
[cade9c1]223 mov TT_LDDF_MEM_ADDRESS_NOT_ALIGNED, %g2
224 clr %g5
[1b20da0]225 PREEMPTIBLE_HANDLER exc_dispatch
[34d9469e]226
227/* TT = 0x36, TL = 0, STDF_mem_address_not_aligned */
228.org trap_table + TT_STDF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
[a52e2f4]229SYMBOL(STDF_mem_address_not_aligned_tl0)
[cade9c1]230 mov TT_STDF_MEM_ADDRESS_NOT_ALIGNED, %g2
231 clr %g5
[1b20da0]232 PREEMPTIBLE_HANDLER exc_dispatch
[34d9469e]233
234/* TT = 0x37, TL = 0, privileged_action */
[e2bf639]235.org trap_table + TT_PRIVILEGED_ACTION*ENTRY_SIZE
[a52e2f4]236SYMBOL(privileged_action_tl0)
[cade9c1]237 mov TT_PRIVILEGED_ACTION, %g2
238 clr %g5
[1b20da0]239 PREEMPTIBLE_HANDLER exc_dispatch
[feb5915]240
[34d9469e]241/* TT = 0x38, TL = 0, LDQF_mem_address_not_aligned */
242.org trap_table + TT_LDQF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
[a52e2f4]243SYMBOL(LDQF_mem_address_not_aligned_tl0)
[cade9c1]244 mov TT_LDQF_MEM_ADDRESS_NOT_ALIGNED, %g2
245 clr %g5
[1b20da0]246 PREEMPTIBLE_HANDLER exc_dispatch
[34d9469e]247
248/* TT = 0x39, TL = 0, STQF_mem_address_not_aligned */
249.org trap_table + TT_STQF_MEM_ADDRESS_NOT_ALIGNED*ENTRY_SIZE
[a52e2f4]250SYMBOL(STQF_mem_address_not_aligned_tl0)
[cade9c1]251 mov TT_STQF_MEM_ADDRESS_NOT_ALIGNED, %g2
252 clr %g5
[1b20da0]253 PREEMPTIBLE_HANDLER exc_dispatch
[34d9469e]254
[39494010]255/* TT = 0x41, TL = 0, interrupt_level_1 handler */
256.org trap_table + TT_INTERRUPT_LEVEL_1*ENTRY_SIZE
[a52e2f4]257SYMBOL(interrupt_level_1_handler_tl0)
[cade9c1]258 mov TT_INTERRUPT_LEVEL_1, %g2
259 clr %g5
260 PREEMPTIBLE_HANDLER exc_dispatch
[39494010]261
262/* TT = 0x42, TL = 0, interrupt_level_2 handler */
263.org trap_table + TT_INTERRUPT_LEVEL_2*ENTRY_SIZE
[a52e2f4]264SYMBOL(interrupt_level_2_handler_tl0)
[cade9c1]265 mov TT_INTERRUPT_LEVEL_2, %g2
266 clr %g5
267 PREEMPTIBLE_HANDLER exc_dispatch
[39494010]268
269/* TT = 0x43, TL = 0, interrupt_level_3 handler */
270.org trap_table + TT_INTERRUPT_LEVEL_3*ENTRY_SIZE
[a52e2f4]271SYMBOL(interrupt_level_3_handler_tl0)
[cade9c1]272 mov TT_INTERRUPT_LEVEL_3, %g2
273 clr %g5
274 PREEMPTIBLE_HANDLER exc_dispatch
[39494010]275
276/* TT = 0x44, TL = 0, interrupt_level_4 handler */
277.org trap_table + TT_INTERRUPT_LEVEL_4*ENTRY_SIZE
[a52e2f4]278SYMBOL(interrupt_level_4_handler_tl0)
[cade9c1]279 mov TT_INTERRUPT_LEVEL_4, %g2
280 clr %g5
281 PREEMPTIBLE_HANDLER exc_dispatch
[39494010]282
283/* TT = 0x45, TL = 0, interrupt_level_5 handler */
284.org trap_table + TT_INTERRUPT_LEVEL_5*ENTRY_SIZE
[a52e2f4]285SYMBOL(interrupt_level_5_handler_tl0)
[cade9c1]286 mov TT_INTERRUPT_LEVEL_5, %g2
287 clr %g5
288 PREEMPTIBLE_HANDLER exc_dispatch
[39494010]289
290/* TT = 0x46, TL = 0, interrupt_level_6 handler */
291.org trap_table + TT_INTERRUPT_LEVEL_6*ENTRY_SIZE
[a52e2f4]292SYMBOL(interrupt_level_6_handler_tl0)
[cade9c1]293 mov TT_INTERRUPT_LEVEL_6, %g2
294 clr %g5
295 PREEMPTIBLE_HANDLER exc_dispatch
[39494010]296
297/* TT = 0x47, TL = 0, interrupt_level_7 handler */
298.org trap_table + TT_INTERRUPT_LEVEL_7*ENTRY_SIZE
[a52e2f4]299SYMBOL(interrupt_level_7_handler_tl0)
[cade9c1]300 mov TT_INTERRUPT_LEVEL_7, %g2
301 clr %g5
302 PREEMPTIBLE_HANDLER exc_dispatch
[39494010]303
304/* TT = 0x48, TL = 0, interrupt_level_8 handler */
305.org trap_table + TT_INTERRUPT_LEVEL_8*ENTRY_SIZE
[a52e2f4]306SYMBOL(interrupt_level_8_handler_tl0)
[cade9c1]307 mov TT_INTERRUPT_LEVEL_8, %g2
308 clr %g5
309 PREEMPTIBLE_HANDLER exc_dispatch
[39494010]310
311/* TT = 0x49, TL = 0, interrupt_level_9 handler */
312.org trap_table + TT_INTERRUPT_LEVEL_9*ENTRY_SIZE
[a52e2f4]313SYMBOL(interrupt_level_9_handler_tl0)
[cade9c1]314 mov TT_INTERRUPT_LEVEL_9, %g2
315 clr %g5
316 PREEMPTIBLE_HANDLER exc_dispatch
[39494010]317
318/* TT = 0x4a, TL = 0, interrupt_level_10 handler */
319.org trap_table + TT_INTERRUPT_LEVEL_10*ENTRY_SIZE
[a52e2f4]320SYMBOL(interrupt_level_10_handler_tl0)
[cade9c1]321 mov TT_INTERRUPT_LEVEL_10, %g2
322 clr %g5
323 PREEMPTIBLE_HANDLER exc_dispatch
[39494010]324
325/* TT = 0x4b, TL = 0, interrupt_level_11 handler */
326.org trap_table + TT_INTERRUPT_LEVEL_11*ENTRY_SIZE
[a52e2f4]327SYMBOL(interrupt_level_11_handler_tl0)
[cade9c1]328 mov TT_INTERRUPT_LEVEL_11, %g2
329 clr %g5
330 PREEMPTIBLE_HANDLER exc_dispatch
[39494010]331
332/* TT = 0x4c, TL = 0, interrupt_level_12 handler */
333.org trap_table + TT_INTERRUPT_LEVEL_12*ENTRY_SIZE
[a52e2f4]334SYMBOL(interrupt_level_12_handler_tl0)
[cade9c1]335 mov TT_INTERRUPT_LEVEL_12, %g2
336 clr %g5
337 PREEMPTIBLE_HANDLER exc_dispatch
[39494010]338
339/* TT = 0x4d, TL = 0, interrupt_level_13 handler */
340.org trap_table + TT_INTERRUPT_LEVEL_13*ENTRY_SIZE
[a52e2f4]341SYMBOL(interrupt_level_13_handler_tl0)
[cade9c1]342 mov TT_INTERRUPT_LEVEL_13, %g2
343 clr %g5
344 PREEMPTIBLE_HANDLER exc_dispatch
[39494010]345
346/* TT = 0x4e, TL = 0, interrupt_level_14 handler */
347.org trap_table + TT_INTERRUPT_LEVEL_14*ENTRY_SIZE
[a52e2f4]348SYMBOL(interrupt_level_14_handler_tl0)
[cade9c1]349 mov TT_INTERRUPT_LEVEL_14, %g2
350 clr %g5
351 PREEMPTIBLE_HANDLER exc_dispatch
[39494010]352
353/* TT = 0x4f, TL = 0, interrupt_level_15 handler */
354.org trap_table + TT_INTERRUPT_LEVEL_15*ENTRY_SIZE
[a52e2f4]355SYMBOL(interrupt_level_15_handler_tl0)
[cade9c1]356 mov TT_INTERRUPT_LEVEL_15, %g2
357 clr %g5
358 PREEMPTIBLE_HANDLER exc_dispatch
[39494010]359
[008029d]360/* TT = 0x64, TL = 0, fast_instruction_access_MMU_miss */
361.org trap_table + TT_FAST_INSTRUCTION_ACCESS_MMU_MISS*ENTRY_SIZE
[a52e2f4]362SYMBOL(fast_instruction_access_mmu_miss_handler_tl0)
[3da11f37]363 FAST_INSTRUCTION_ACCESS_MMU_MISS_HANDLER
[008029d]364
365/* TT = 0x68, TL = 0, fast_data_access_MMU_miss */
366.org trap_table + TT_FAST_DATA_ACCESS_MMU_MISS*ENTRY_SIZE
[a52e2f4]367SYMBOL(fast_data_access_mmu_miss_handler_tl0)
[e2bf639]368 FAST_DATA_ACCESS_MMU_MISS_HANDLER 0
[008029d]369
370/* TT = 0x6c, TL = 0, fast_data_access_protection */
371.org trap_table + TT_FAST_DATA_ACCESS_PROTECTION*ENTRY_SIZE
[a52e2f4]372SYMBOL(fast_data_access_protection_handler_tl0)
[eb79d60]373 FAST_DATA_ACCESS_PROTECTION_HANDLER 0
[008029d]374
[8c2214e]375/* TT = 0x7c, TL = 0, cpu_mondo */
376.org trap_table + TT_CPU_MONDO*ENTRY_SIZE
[a52e2f4]377SYMBOL(cpu_mondo_handler_tl0)
[cade9c1]378 mov TT_CPU_MONDO, %g2
379 clr %g5
[1b20da0]380 PREEMPTIBLE_HANDLER exc_dispatch
[8c2214e]381
[5b1ced0]382/* TT = 0x80, TL = 0, spill_0_normal handler */
[c43fa55]383.org trap_table + TT_SPILL_0_NORMAL*ENTRY_SIZE
[a52e2f4]384SYMBOL(spill_0_normal_tl0)
[a7961271]385 SPILL_NORMAL_HANDLER_KERNEL
[49b6d32]386
[e11ae91]387/* TT = 0x84, TL = 0, spill_1_normal handler */
388.org trap_table + TT_SPILL_1_NORMAL*ENTRY_SIZE
[a52e2f4]389SYMBOL(spill_1_normal_tl0)
[e11ae91]390 SPILL_NORMAL_HANDLER_USERSPACE
391
392/* TT = 0x88, TL = 0, spill_2_normal handler */
393.org trap_table + TT_SPILL_2_NORMAL*ENTRY_SIZE
[a52e2f4]394SYMBOL(spill_2_normal_tl0)
[e11ae91]395 SPILL_TO_USPACE_WINDOW_BUFFER
396
[cfa70add]397/* TT = 0xa0, TL = 0, spill_0_other handler */
398.org trap_table + TT_SPILL_0_OTHER*ENTRY_SIZE
[a52e2f4]399SYMBOL(spill_0_other_tl0)
[cfa70add]400 SPILL_TO_USPACE_WINDOW_BUFFER
401
[5b1ced0]402/* TT = 0xc0, TL = 0, fill_0_normal handler */
[c43fa55]403.org trap_table + TT_FILL_0_NORMAL*ENTRY_SIZE
[a52e2f4]404SYMBOL(fill_0_normal_tl0)
[a7961271]405 FILL_NORMAL_HANDLER_KERNEL
[8ac5fe7]406
[e11ae91]407/* TT = 0xc4, TL = 0, fill_1_normal handler */
408.org trap_table + TT_FILL_1_NORMAL*ENTRY_SIZE
[a52e2f4]409SYMBOL(fill_1_normal_tl0)
[e11ae91]410 FILL_NORMAL_HANDLER_USERSPACE
411
[3b8fe85]412/* TT = 0x100 - 0x17f, TL = 0, trap_instruction_0 - trap_instruction_7f */
413.irp cur, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,\
414 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38,\
415 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,\
416 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76,\
417 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,\
418 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,\
419 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,\
420 127
421.org trap_table + (TT_TRAP_INSTRUCTION_0+\cur)*ENTRY_SIZE
[a52e2f4]422SYMBOL(trap_instruction_\cur\()_tl0)
[3b8fe85]423 mov \cur, %g2
[cade9c1]424 ba %xcc, trap_instruction_handler
425 clr %g5
[3b8fe85]426.endr
[d93a1c5a]427
[8ac5fe7]428/*
[5b1ced0]429 * Handlers for TL>0.
[8ac5fe7]430 */
431
[feb5915]432/* TT = 0x08, TL > 0, instruction_access_exception */
[8c2214e]433/* TT = 0x08, TL > 0, IAE_privilege_violation on UltraSPARC T2 */
[feb5915]434.org trap_table + (TT_INSTRUCTION_ACCESS_EXCEPTION+512)*ENTRY_SIZE
[a52e2f4]435SYMBOL(instruction_access_exception_tl1)
[eb79d60]436 wrpr %g0, 1, %tl
[cade9c1]437 mov TT_INSTRUCTION_ACCESS_EXCEPTION, %g2
438 clr %g5
[1b20da0]439 PREEMPTIBLE_HANDLER exc_dispatch
[e2bf639]440
[8c2214e]441/* TT = 0x09, TL > 0, instruction_access_mmu_miss */
442.org trap_table + (TT_INSTRUCTION_ACCESS_MMU_MISS+512)*ENTRY_SIZE
[a52e2f4]443SYMBOL(instruction_access_mmu_miss_handler_tl1)
[8c2214e]444 wrpr %g0, 1, %tl
[40239b9]445 ba,a %xcc, fast_instruction_access_mmu_miss_handler_tl0
[8c2214e]446
[e2bf639]447/* TT = 0x0a, TL > 0, instruction_access_error */
448.org trap_table + (TT_INSTRUCTION_ACCESS_ERROR+512)*ENTRY_SIZE
[a52e2f4]449SYMBOL(instruction_access_error_tl1)
[e2bf639]450 wrpr %g0, 1, %tl
[cade9c1]451 mov TT_INSTRUCTION_ACCESS_ERROR, %g2
452 clr %g5
[1b20da0]453 PREEMPTIBLE_HANDLER exc_dispatch
[feb5915]454
[8c2214e]455/* TT = 0x0b, TL > 0, IAE_unauth_access */
456.org trap_table + (TT_IAE_UNAUTH_ACCESS+512)*ENTRY_SIZE
[a52e2f4]457SYMBOL(iae_unauth_access_tl1)
[8c2214e]458 wrpr %g0, 1, %tl
[cade9c1]459 mov TT_IAE_UNAUTH_ACCESS, %g2
460 clr %g5
[1b20da0]461 PREEMPTIBLE_HANDLER exc_dispatch
[8c2214e]462
463/* TT = 0x0c, TL > 0, IAE_nfo_page */
464.org trap_table + (TT_IAE_NFO_PAGE+512)*ENTRY_SIZE
[a52e2f4]465SYMBOL(iae_nfo_page_tl1)
[8c2214e]466 wrpr %g0, 1, %tl
[cade9c1]467 mov TT_IAE_NFO_PAGE, %g2
468 clr %g5
[1b20da0]469 PREEMPTIBLE_HANDLER exc_dispatch
[8c2214e]470
[7cb53f62]471/* TT = 0x10, TL > 0, illegal_instruction */
472.org trap_table + (TT_ILLEGAL_INSTRUCTION+512)*ENTRY_SIZE
[a52e2f4]473SYMBOL(illegal_instruction_tl1)
[e2bf639]474 wrpr %g0, 1, %tl
[cade9c1]475 mov TT_ILLEGAL_INSTRUCTION, %g2
476 clr %g5
[1b20da0]477 PREEMPTIBLE_HANDLER exc_dispatch
[7cb53f62]478
[8c2214e]479/* TT = 0x14, TL > 0, DAE_invalid_asi */
480.org trap_table + (TT_DAE_INVALID_ASI+512)*ENTRY_SIZE
[a52e2f4]481SYMBOL(dae_invalid_asi_tl1)
[8c2214e]482 wrpr %g0, 1, %tl
[cade9c1]483 mov TT_DAE_INVALID_ASI, %g2
484 clr %g5
[1b20da0]485 PREEMPTIBLE_HANDLER exc_dispatch
[8c2214e]486
487/* TT = 0x15, TL > 0, DAE_privilege_violation */
488.org trap_table + (TT_DAE_PRIVILEGE_VIOLATION+512)*ENTRY_SIZE
[a52e2f4]489SYMBOL(dae_privilege_violation_tl1)
[8c2214e]490 wrpr %g0, 1, %tl
[cade9c1]491 mov TT_DAE_PRIVILEGE_VIOLATION, %g2
492 clr %g5
[1b20da0]493 PREEMPTIBLE_HANDLER exc_dispatch
[8c2214e]494
495/* TT = 0x16, TL > 0, DAE_nc_page */
496.org trap_table + (TT_DAE_NC_PAGE+512)*ENTRY_SIZE
[a52e2f4]497SYMBOL(dae_nc_page_tl1)
[8c2214e]498 wrpr %g0, 1, %tl
[cade9c1]499 mov TT_DAE_NC_PAGE, %g2
500 clr %g5
[1b20da0]501 PREEMPTIBLE_HANDLER exc_dispatch
[8c2214e]502
503/* TT = 0x17, TL > 0, DAE_nfo_page */
504.org trap_table + (TT_DAE_NFO_PAGE+512)*ENTRY_SIZE
[a52e2f4]505SYMBOL(dae_nfo_page_tl1)
[8c2214e]506 wrpr %g0, 1, %tl
[cade9c1]507 mov TT_DAE_NFO_PAGE, %g2
508 clr %g5
[1b20da0]509 PREEMPTIBLE_HANDLER exc_dispatch
[8c2214e]510
[5b1ced0]511/* TT = 0x24, TL > 0, clean_window handler */
512.org trap_table + (TT_CLEAN_WINDOW+512)*ENTRY_SIZE
[a52e2f4]513SYMBOL(clean_window_tl1)
[5b1ced0]514 CLEAN_WINDOW_HANDLER
[8ac5fe7]515
[e2bf639]516/* TT = 0x28, TL > 0, division_by_zero */
517.org trap_table + (TT_DIVISION_BY_ZERO+512)*ENTRY_SIZE
[a52e2f4]518SYMBOL(division_by_zero_tl1)
[e2bf639]519 wrpr %g0, 1, %tl
[cade9c1]520 mov TT_DIVISION_BY_ZERO, %g2
521 clr %g5
[1b20da0]522 PREEMPTIBLE_HANDLER exc_dispatch
[e2bf639]523
524/* TT = 0x30, TL > 0, data_access_exception */
525.org trap_table + (TT_DATA_ACCESS_EXCEPTION+512)*ENTRY_SIZE
[a52e2f4]526SYMBOL(data_access_exception_tl1)
[cade9c1]527 wrpr %g0, 1, %tl
528 mov TT_DATA_ACCESS_EXCEPTION, %g2
529 clr %g5
[1b20da0]530 PREEMPTIBLE_HANDLER exc_dispatch
[8c2214e]531
532/* TT = 0x31, TL > 0, data_access_mmu_miss */
533.org trap_table + (TT_DATA_ACCESS_MMU_MISS+512)*ENTRY_SIZE
[a52e2f4]534SYMBOL(data_access_mmu_miss_tl1)
[40239b9]535 ba,a %xcc, fast_data_access_mmu_miss_handler_tl1
[e2bf639]536
[97f1691]537/* TT = 0x32, TL > 0, data_access_error */
538.org trap_table + (TT_DATA_ACCESS_ERROR+512)*ENTRY_SIZE
[a52e2f4]539SYMBOL(data_access_error_tl1)
[e2bf639]540 wrpr %g0, 1, %tl
[cade9c1]541 mov TT_DATA_ACCESS_ERROR, %g2
542 clr %g5
[1b20da0]543 PREEMPTIBLE_HANDLER exc_dispatch
[97f1691]544
[feb5915]545/* TT = 0x34, TL > 0, mem_address_not_aligned */
546.org trap_table + (TT_MEM_ADDRESS_NOT_ALIGNED+512)*ENTRY_SIZE
[a52e2f4]547SYMBOL(mem_address_not_aligned_tl1)
[e2bf639]548 wrpr %g0, 1, %tl
[cade9c1]549 mov TT_MEM_ADDRESS_NOT_ALIGNED, %g2
550 clr %g5
[1b20da0]551 PREEMPTIBLE_HANDLER exc_dispatch
[008029d]552
553/* TT = 0x68, TL > 0, fast_data_access_MMU_miss */
554.org trap_table + (TT_FAST_DATA_ACCESS_MMU_MISS+512)*ENTRY_SIZE
[a52e2f4]555SYMBOL(fast_data_access_mmu_miss_handler_tl1)
[e2bf639]556 FAST_DATA_ACCESS_MMU_MISS_HANDLER 1
[008029d]557
558/* TT = 0x6c, TL > 0, fast_data_access_protection */
559.org trap_table + (TT_FAST_DATA_ACCESS_PROTECTION+512)*ENTRY_SIZE
[a52e2f4]560SYMBOL(fast_data_access_protection_handler_tl1)
[eb79d60]561 FAST_DATA_ACCESS_PROTECTION_HANDLER 1
[008029d]562
[8c2214e]563/* TT = 0x7c, TL > 0, cpu_mondo */
564.org trap_table + (TT_CPU_MONDO+512)*ENTRY_SIZE
[a52e2f4]565SYMBOL(cpu_mondo_handler_tl1)
[8c2214e]566 wrpr %g0, %tl
[cade9c1]567 mov TT_CPU_MONDO, %g2
568 clr %g5
[1b20da0]569 PREEMPTIBLE_HANDLER exc_dispatch
[8c2214e]570
[5b1ced0]571/* TT = 0x80, TL > 0, spill_0_normal handler */
572.org trap_table + (TT_SPILL_0_NORMAL+512)*ENTRY_SIZE
[a52e2f4]573SYMBOL(spill_0_normal_tl1)
[a7961271]574 SPILL_NORMAL_HANDLER_KERNEL
[8ac5fe7]575
[e11ae91]576/* TT = 0x88, TL > 0, spill_2_normal handler */
577.org trap_table + (TT_SPILL_2_NORMAL+512)*ENTRY_SIZE
[a52e2f4]578SYMBOL(spill_2_normal_tl1)
[e11ae91]579 SPILL_TO_USPACE_WINDOW_BUFFER
580
581/* TT = 0xa0, TL > 0, spill_0_other handler */
582.org trap_table + (TT_SPILL_0_OTHER+512)*ENTRY_SIZE
[a52e2f4]583SYMBOL(spill_0_other_tl1)
[e11ae91]584 SPILL_TO_USPACE_WINDOW_BUFFER
585
[5b1ced0]586/* TT = 0xc0, TL > 0, fill_0_normal handler */
587.org trap_table + (TT_FILL_0_NORMAL+512)*ENTRY_SIZE
[a52e2f4]588SYMBOL(fill_0_normal_tl1)
[a7961271]589 FILL_NORMAL_HANDLER_KERNEL
[5b1ced0]590
[282f2c9c]591.align TABLE_SIZE
592
593
[74cbac7d]594/*
595 * Spills the window at CWP + 2 to the kernel stack. This macro is to be
596 * used before doing SAVE when the spill trap is undesirable.
[1b20da0]597 *
[74cbac7d]598 * Parameters:
599 * tmpreg1 global register to be used for scratching purposes
600 * tmpreg2 global register to be used for scratching purposes
601 */
602.macro INLINE_SPILL tmpreg1, tmpreg2
603 ! CWP := CWP + 2
604 rdpr %cwp, \tmpreg2
605 add \tmpreg2, 2, \tmpreg1
606 and \tmpreg1, NWINDOWS - 1, \tmpreg1 ! modulo NWINDOWS
607 wrpr \tmpreg1, %cwp
[a35b458]608
[74cbac7d]609 ! spill to kernel stack
[1b20da0]610 stx %l0, [%sp + STACK_BIAS + L0_OFFSET]
[74cbac7d]611 stx %l1, [%sp + STACK_BIAS + L1_OFFSET]
612 stx %l2, [%sp + STACK_BIAS + L2_OFFSET]
613 stx %l3, [%sp + STACK_BIAS + L3_OFFSET]
614 stx %l4, [%sp + STACK_BIAS + L4_OFFSET]
615 stx %l5, [%sp + STACK_BIAS + L5_OFFSET]
616 stx %l6, [%sp + STACK_BIAS + L6_OFFSET]
617 stx %l7, [%sp + STACK_BIAS + L7_OFFSET]
618 stx %i0, [%sp + STACK_BIAS + I0_OFFSET]
619 stx %i1, [%sp + STACK_BIAS + I1_OFFSET]
620 stx %i2, [%sp + STACK_BIAS + I2_OFFSET]
621 stx %i3, [%sp + STACK_BIAS + I3_OFFSET]
622 stx %i4, [%sp + STACK_BIAS + I4_OFFSET]
623 stx %i5, [%sp + STACK_BIAS + I5_OFFSET]
624 stx %i6, [%sp + STACK_BIAS + I6_OFFSET]
625 stx %i7, [%sp + STACK_BIAS + I7_OFFSET]
626
627 ! CWP := CWP - 2
628 wrpr \tmpreg2, %cwp
629
630 saved
631.endm
[c43fa55]632
[74cbac7d]633/*
634 * Fill the window at CWP - 1 from the kernel stack. This macro is to be
635 * used before doing RESTORE when the fill trap is undesirable.
[1b20da0]636 *
[74cbac7d]637 * Parameters:
638 * tmpreg1 global register to be used for scratching purposes
639 * tmpreg2 global register to be used for scratching purposes
[7614565]640 */
[74cbac7d]641.macro INLINE_FILL tmpreg1, tmpreg2
642 ! CWP := CWP - 1
643 rdpr %cwp, \tmpreg2
644 add \tmpreg2, NWINDOWS - 1, \tmpreg1
645 and \tmpreg1, NWINDOWS - 1, \tmpreg1
646 wrpr \tmpreg1, %cwp
647
648 ! fill from kernel stack
649 ldx [%sp + STACK_BIAS + L0_OFFSET], %l0
650 ldx [%sp + STACK_BIAS + L1_OFFSET], %l1
651 ldx [%sp + STACK_BIAS + L2_OFFSET], %l2
652 ldx [%sp + STACK_BIAS + L3_OFFSET], %l3
653 ldx [%sp + STACK_BIAS + L4_OFFSET], %l4
654 ldx [%sp + STACK_BIAS + L5_OFFSET], %l5
655 ldx [%sp + STACK_BIAS + L6_OFFSET], %l6
656 ldx [%sp + STACK_BIAS + L7_OFFSET], %l7
657 ldx [%sp + STACK_BIAS + I0_OFFSET], %i0
658 ldx [%sp + STACK_BIAS + I1_OFFSET], %i1
659 ldx [%sp + STACK_BIAS + I2_OFFSET], %i2
660 ldx [%sp + STACK_BIAS + I3_OFFSET], %i3
661 ldx [%sp + STACK_BIAS + I4_OFFSET], %i4
662 ldx [%sp + STACK_BIAS + I5_OFFSET], %i5
663 ldx [%sp + STACK_BIAS + I6_OFFSET], %i6
664 ldx [%sp + STACK_BIAS + I7_OFFSET], %i7
665
666 ! CWP := CWP + 1
667 wrpr \tmpreg2, %cwp
668
669 restored
670.endm
671
[eb79d60]672#define NOT(x) ((x) == 0)
673
674/*
675 * Perform all the actions of the preemptible trap handler which are common
676 * for trapping from kernel and trapping from userspace, including call of the
677 * higher level service routine.
678 *
679 * Important note:
680 * This macro must be inserted between the "2:" and "4:" labels. The
681 * inserting code must be aware of the usage of all the registers
682 * contained in this macro.
683 */
684.macro MIDDLE_PART is_syscall
685 /* copy higher level routine's address and its argument */
686 mov %g1, %l0
687.if NOT(\is_syscall)
688 mov %g2, %o0
689.else
690 ! store the syscall number on the stack as 7th argument
[1b20da0]691 stx %g2, [%sp + STACK_BIAS + ISTATE_OFFSET_ARG6]
[eb79d60]692.endif
693
694 /*
695 * Save TSTATE, TPC and TNPC aside.
696 */
697 rdpr %tstate, %g1
698 rdpr %tpc, %g2
699 rdpr %tnpc, %g3
700
[cade9c1]701 stx %g1, [%sp + STACK_BIAS + ISTATE_OFFSET_TSTATE]
702 stx %g2, [%sp + STACK_BIAS + ISTATE_OFFSET_TPC]
703 stx %g3, [%sp + STACK_BIAS + ISTATE_OFFSET_TNPC]
[eb79d60]704
705 /*
706 * Save the Y register.
707 */
708 rd %y, %g4
[cade9c1]709 stx %g4, [%sp + STACK_BIAS + ISTATE_OFFSET_Y]
710
711 /*
712 * Save the faulting page and context.
713 */
714 stx %g5, [%sp + STACK_BIAS + ISTATE_OFFSET_TLB_TAG_ACCESS]
[eb79d60]715
716 /* switch to TL = 0, explicitly enable FPU */
717 wrpr %g0, 0, %tl
718 wrpr %g0, 0, %gl
719 wrpr %g0, PSTATE_PRIV_BIT | PSTATE_PEF_BIT, %pstate
720
721 /* g1 -> l1, ..., g7 -> l7 */
722 SAVE_GLOBALS
723
724.if NOT(\is_syscall)
725 /* call higher-level service routine, pass istate as its 2nd parameter */
726 call %l0
[cade9c1]727 add %sp, STACK_BIAS, %o1
[eb79d60]728.else
729 /* Call the higher-level syscall handler. */
730 !wrpr %g0, PSTATE_PRIV_BIT | PSTATE_PEF_BIT | PSTATE_IE_BIT, %pstate
731 call syscall_handler
732 nop
733 /* copy the value returned by the syscall */
734 mov %o0, %i0
735.endif
736
737 /* l1 -> g1, ..., l7 -> g7 */
738 RESTORE_GLOBALS
739
740 /* we must prserve the PEF bit */
741 rdpr %pstate, %l1
742
743 /* TL := 1, GL := 1 */
744 wrpr %g0, PSTATE_PRIV_BIT, %pstate
745 wrpr %g0, 1, %tl
746 wrpr %g0, 1, %gl
747
748 /* Read TSTATE, TPC and TNPC from saved copy. */
[cade9c1]749 ldx [%sp + STACK_BIAS + ISTATE_OFFSET_TSTATE], %g1
750 ldx [%sp + STACK_BIAS + ISTATE_OFFSET_TPC], %g2
751 ldx [%sp + STACK_BIAS + ISTATE_OFFSET_TNPC], %g3
[eb79d60]752
753 /* Copy PSTATE.PEF to the in-register copy of TSTATE. */
754 and %l1, PSTATE_PEF_BIT, %l1
755 sllx %l1, TSTATE_PSTATE_SHIFT, %l1
756 sethi %hi(TSTATE_PEF_BIT), %g4 ! reset the PEF bit to 0 ...
757 andn %g1, %g4, %g1
758 or %g1, %l1, %g1 ! ... "or" it with saved PEF
759
760 /* Restore TSTATE, TPC and TNPC from saved copies. */
761 wrpr %g1, 0, %tstate
762 wrpr %g2, 0, %tpc
763 wrpr %g3, 0, %tnpc
764
765 /* Restore Y. */
[cade9c1]766 ldx [%sp + STACK_BIAS + ISTATE_OFFSET_Y], %g4
[eb79d60]767 wr %g4, %y
[a35b458]768
[eb79d60]769 /* If TSTATE.CWP + 1 == CWP, then we do not have to fix CWP. */
770 and %g1, TSTATE_CWP_MASK, %l0
771 inc %l0
772 and %l0, NWINDOWS - 1, %l0 ! %l0 mod NWINDOWS
773 rdpr %cwp, %l1
774 cmp %l0, %l1
[40239b9]775 bz %xcc, 4f ! CWP is ok
[eb79d60]776 nop
777
7783:
779 /*
780 * Fix CWP.
781 * In order to recapitulate, the input registers in the current
782 * window are the output registers of the window to which we want
783 * to restore. Because the fill trap fills only input and local
784 * registers of a window, we need to preserve those output
785 * registers manually.
786 */
787 mov %sp, %g2
[cade9c1]788 stx %i0, [%sp + STACK_BIAS + ISTATE_OFFSET_O0]
789 stx %i1, [%sp + STACK_BIAS + ISTATE_OFFSET_O1]
790 stx %i2, [%sp + STACK_BIAS + ISTATE_OFFSET_O2]
791 stx %i3, [%sp + STACK_BIAS + ISTATE_OFFSET_O3]
792 stx %i4, [%sp + STACK_BIAS + ISTATE_OFFSET_O4]
793 stx %i5, [%sp + STACK_BIAS + ISTATE_OFFSET_O5]
794 stx %i6, [%sp + STACK_BIAS + ISTATE_OFFSET_O6]
795 stx %i7, [%sp + STACK_BIAS + ISTATE_OFFSET_O7]
[eb79d60]796 wrpr %l0, 0, %cwp
797 mov %g2, %sp
[cade9c1]798 ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O0], %i0
799 ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O1], %i1
800 ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O2], %i2
801 ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O3], %i3
802 ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O4], %i4
803 ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O5], %i5
804 ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O6], %i6
805 ldx [%sp + STACK_BIAS + ISTATE_OFFSET_O7], %i7
[eb79d60]806.endm
807
808/*
809 * Preemptible trap handler for handling traps from kernel.
810 */
811.macro PREEMPTIBLE_HANDLER_KERNEL
812 /* prevent unnecessary CLEANWIN exceptions */
813 wrpr %g0, NWINDOWS - 1, %cleanwin
814
815 /*
816 * Prevent SAVE instruction from causing a spill exception. If the
817 * CANSAVE register is zero, explicitly spill register window
818 * at CWP + 2.
819 */
820
821 rdpr %cansave, %g3
822 brnz %g3, 2f
823 nop
[21373712]824 rdpr %otherwin, %g4
825 brnz %g4, 1f
826 nop
827
828 /* OTHERWIN is zero, we are spilling a kernel window. */
[eb79d60]829 INLINE_SPILL %g3, %g4
[21373712]830 ba,a %xcc, 2f
831
8321:
833 /* OTHERWIN is non-zero, we are spilling a uspace window. */
834 INLINE_SPILL_TO_WBUF %g3, %g4, %g7
[eb79d60]835
8362:
837 /* ask for new register window */
[cade9c1]838 save %sp, -ISTATE_SIZE, %sp
[eb79d60]839
840 MIDDLE_PART 0
841
8424:
843 /*
844 * Prevent RESTORE instruction from causing a fill exception. If the
845 * CANRESTORE register is zero, explicitly fill register window
846 * at CWP - 1.
847 */
848 rdpr %canrestore, %g1
849 brnz %g1, 5f
850 nop
851 INLINE_FILL %g3, %g4
852
8535:
854 restore
855 retry
856.endm
857
858/*
859 * Spills the window at CWP + 2 to the userspace window buffer. This macro
860 * is to be used before doing SAVE when the spill trap is undesirable.
[1b20da0]861 *
[eb79d60]862 * Parameters:
863 * tmpreg1 global register to be used for scratching purposes
864 * tmpreg2 global register to be used for scratching purposes
865 * tmpreg3 global register to be used for scratching purposes
866 */
867.macro INLINE_SPILL_TO_WBUF tmpreg1, tmpreg2, tmpreg3
868 ! CWP := CWP + 2
869 rdpr %cwp, \tmpreg2
870 add \tmpreg2, 2, \tmpreg1
871 and \tmpreg1, NWINDOWS - 1, \tmpreg1 ! modulo NWINDOWS
872 wrpr \tmpreg1, %cwp
[a35b458]873
[eb79d60]874 ! spill to userspace window buffer
875 SAVE_TO_USPACE_WBUF \tmpreg3, \tmpreg1
876
877 ! CWP := CWP - 2
878 wrpr \tmpreg2, %cwp
879
880 saved
881.endm
882
883/*
884 * Preemptible handler for handling traps from userspace.
885 */
886.macro PREEMPTIBLE_HANDLER_USPACE is_syscall
887 /*
888 * One of the ways this handler can be invoked is after a nested MMU trap from
889 * either spill_1_normal or fill_1_normal traps. Both of these traps manipulate
890 * the CWP register. We deal with the situation by simulating the MMU trap
891 * on TL=1 and restart the respective SAVE or RESTORE instruction once the MMU
892 * trap is resolved. However, because we are in the wrong window from the
893 * perspective of the MMU trap, we need to synchronize CWP with CWP from TL=0.
[1b20da0]894 */
[eb79d60]895.if NOT(\is_syscall)
896 rdpr %tstate, %g3
897 and %g3, TSTATE_CWP_MASK, %g4
898 wrpr %g4, 0, %cwp ! resynchronize CWP
899.endif
900
901 /* prevent unnecessary CLEANWIN exceptions */
902 wrpr %g0, NWINDOWS - 1, %cleanwin
903
904 /*
905 * Prevent SAVE instruction from causing a spill exception. If the
906 * CANSAVE register is zero, explicitly spill register window
907 * at CWP + 2.
908 */
909 rdpr %cansave, %g3
910 brnz %g3, 2f
911 nop
912 INLINE_SPILL_TO_WBUF %g3, %g4, %g7
913
9142:
915 set SCRATCHPAD_KSTACK, %g4
916 ldxa [%g4] ASI_SCRATCHPAD, %g6
[cade9c1]917 save %g6, -ISTATE_SIZE, %sp
[eb79d60]918
919.if \is_syscall
920 /* Copy arguments for the syscall to the new window. */
921 mov %i0, %o0
922 mov %i1, %o1
923 mov %i2, %o2
924 mov %i3, %o3
925 mov %i4, %o4
926 mov %i5, %o5
927.endif
928
[1b20da0]929 mov VA_PRIMARY_CONTEXT_REG, %l0
[eb79d60]930 stxa %g0, [%l0] ASI_PRIMARY_CONTEXT_REG
931 rd %pc, %l0
932 flush %l0
933
934 /* Mark the CANRESTORE windows as OTHER windows. */
935 rdpr %canrestore, %l0
936 wrpr %l0, %otherwin
937 wrpr %g0, %canrestore
938
939 /*
940 * Other window spills will go to the userspace window buffer
941 * and normal spills will go to the kernel stack.
942 */
943 wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(0), %wstate
944
945 MIDDLE_PART \is_syscall
946
9474:
948 /*
949 * Spills and fills will be processed by the {spill,fill}_1_normal
950 * handlers.
951 */
952 wrpr %g0, WSTATE_OTHER(0) | WSTATE_NORMAL(1), %wstate
953
954 /*
955 * Set primary context according to secondary context.
956 */
957 wr %g0, ASI_SECONDARY_CONTEXT_REG, %asi
958 ldxa [VA_SECONDARY_CONTEXT_REG] %asi, %g1
959 wr %g0, ASI_PRIMARY_CONTEXT_REG, %asi
960 stxa %g1, [VA_PRIMARY_CONTEXT_REG] %asi
961 rd %pc, %g1
962 flush %g1
963
964 /* Restoring userspace windows: */
965
966 /* Save address of the userspace window buffer to the %g7 register. */
967 set SCRATCHPAD_WBUF, %g5
968 ldxa [%g5] ASI_SCRATCHPAD, %g7
969
970 rdpr %cwp, %g1
971 rdpr %otherwin, %g2
972
973 /*
974 * Skip all OTHERWIN windows and descend to the first window
975 * in the userspace window buffer.
976 */
977 sub %g1, %g2, %g3
978 dec %g3
979 and %g3, NWINDOWS - 1, %g3
980 wrpr %g3, 0, %cwp
981
982 /*
983 * CWP is now in the window last saved in the userspace window buffer.
984 * Fill all windows stored in the buffer.
985 */
986 clr %g4
9875: andcc %g7, UWB_ALIGNMENT - 1, %g0 ! alignment check
[40239b9]988 bz %xcc, 6f ! %g7 is UWB_ALIGNMENT-aligned, no more windows to refill
[eb79d60]989 nop
990
991 add %g7, -STACK_WINDOW_SAVE_AREA_SIZE, %g7
992 ldx [%g7 + L0_OFFSET], %l0
993 ldx [%g7 + L1_OFFSET], %l1
994 ldx [%g7 + L2_OFFSET], %l2
995 ldx [%g7 + L3_OFFSET], %l3
996 ldx [%g7 + L4_OFFSET], %l4
997 ldx [%g7 + L5_OFFSET], %l5
998 ldx [%g7 + L6_OFFSET], %l6
999 ldx [%g7 + L7_OFFSET], %l7
1000 ldx [%g7 + I0_OFFSET], %i0
1001 ldx [%g7 + I1_OFFSET], %i1
1002 ldx [%g7 + I2_OFFSET], %i2
1003 ldx [%g7 + I3_OFFSET], %i3
1004 ldx [%g7 + I4_OFFSET], %i4
1005 ldx [%g7 + I5_OFFSET], %i5
1006 ldx [%g7 + I6_OFFSET], %i6
1007 ldx [%g7 + I7_OFFSET], %i7
1008
1009 dec %g3
1010 and %g3, NWINDOWS - 1, %g3
1011 wrpr %g3, 0, %cwp ! switch to the preceeding window
1012
[0242621]1013 ba %xcc, 5b
[eb79d60]1014 inc %g4
1015
10166:
1017 /* Save changes of the address of the userspace window buffer. */
1018 stxa %g7, [%g5] ASI_SCRATCHPAD
1019
1020 /*
1021 * Switch back to the proper current window and adjust
1022 * OTHERWIN, CANRESTORE, CANSAVE and CLEANWIN.
1023 */
1024 wrpr %g1, 0, %cwp
1025 add %g4, %g2, %g2
1026 cmp %g2, NWINDOWS - 2
[4bd675d]1027 bg %xcc, 8f ! fix the CANRESTORE=NWINDOWS-1 anomaly
[eb79d60]1028 mov NWINDOWS - 2, %g1 ! use dealy slot for both cases
1029 sub %g1, %g2, %g1
[a35b458]1030
[eb79d60]1031 wrpr %g0, 0, %otherwin
1032 wrpr %g1, 0, %cansave ! NWINDOWS - 2 - CANRESTORE
1033 wrpr %g2, 0, %canrestore ! OTHERWIN + windows in the buffer
1034 wrpr %g2, 0, %cleanwin ! avoid information leak
1035
10367:
1037 restore
1038
1039.if \is_syscall
1040 done
1041.else
1042 retry
1043.endif
1044
10458:
1046 /*
1047 * We got here in order to avoid inconsistency of the window state registers.
1048 * If the:
1049 *
[cade9c1]1050 * save %g6, -ISTATE_SIZE, %sp
[eb79d60]1051 *
1052 * instruction trapped and spilled a register window into the userspace
1053 * window buffer, we have just restored NWINDOWS - 1 register windows.
1054 * However, CANRESTORE can be only NWINDOW - 2 at most.
1055 *
1056 * The solution is to manually switch to (CWP - 1) mod NWINDOWS
1057 * and set the window state registers so that:
1058 *
1059 * CANRESTORE = NWINDOWS - 2
1060 * CLEANWIN = NWINDOWS - 2
1061 * CANSAVE = 0
1062 * OTHERWIN = 0
1063 *
1064 * The RESTORE instruction is therfore to be skipped.
1065 */
1066 wrpr %g0, 0, %otherwin
1067 wrpr %g0, 0, %cansave
1068 wrpr %g1, 0, %canrestore
1069 wrpr %g1, 0, %cleanwin
1070
1071 rdpr %cwp, %g1
1072 dec %g1
1073 and %g1, NWINDOWS - 1, %g1
1074 wrpr %g1, 0, %cwp ! CWP--
[a35b458]1075
[eb79d60]1076.if \is_syscall
1077 done
1078.else
1079 retry
1080.endif
1081
1082.endm
1083
[74cbac7d]1084/* Preemptible trap handler for TL=1.
1085 *
1086 * This trap handler makes arrangements to make calling of scheduler() from
1087 * within a trap context possible. It is called from several other trap
1088 * handlers.
1089 */
1090.macro PREEMPTIBLE_HANDLER_TEMPLATE is_syscall
[eb79d60]1091 rdpr %tstate, %g3
1092 and %g3, TSTATE_PRIV_BIT, %g3
1093 brz %g3, 100f ! trapping from userspace
1094 nop
1095
[74cbac7d]1096 PREEMPTIBLE_HANDLER_KERNEL
[40239b9]1097 ba,a %xcc, 101f
[eb79d60]1098
1099 100:
1100 PREEMPTIBLE_HANDLER_USPACE \is_syscall
1101
1102 101:
[9314ee1]1103.endm
1104
[a52e2f4]1105SYMBOL(preemptible_handler)
[9314ee1]1106 PREEMPTIBLE_HANDLER_TEMPLATE 0
1107
[a52e2f4]1108SYMBOL(trap_instruction_handler)
[9314ee1]1109 PREEMPTIBLE_HANDLER_TEMPLATE 1
Note: See TracBrowser for help on using the repository browser.