~galfy/helenos/bird-port-mainline

« back to all changes in this revision

Viewing changes to kernel/arch/sparc64/include/trap/mmu.h

  • Committer: Martin Decky
  • Date: 2009-08-04 11:19:19 UTC
  • Revision ID: martin@uranus.dsrg.hide.ms.mff.cuni.cz-20090804111919-evyclddlr3v5lhmp
Initial import

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (c) 2006 Jakub Jermar
 
3
 * All rights reserved.
 
4
 *
 
5
 * Redistribution and use in source and binary forms, with or without
 
6
 * modification, are permitted provided that the following conditions
 
7
 * are met:
 
8
 *
 
9
 * - Redistributions of source code must retain the above copyright
 
10
 *   notice, this list of conditions and the following disclaimer.
 
11
 * - Redistributions in binary form must reproduce the above copyright
 
12
 *   notice, this list of conditions and the following disclaimer in the
 
13
 *   documentation and/or other materials provided with the distribution.
 
14
 * - The name of the author may not be used to endorse or promote products
 
15
 *   derived from this software without specific prior written permission.
 
16
 *
 
17
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 
18
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 
19
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 
20
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 
21
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
 
22
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 
23
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 
24
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
27
 */
 
28
 
 
29
/** @addtogroup sparc64interrupt
 
30
 * @{
 
31
 */
 
32
/**
 
33
 * @file
 
34
 * @brief This file contains fast MMU trap handlers.
 
35
 */
 
36
 
 
37
#ifndef KERN_sparc64_MMU_TRAP_H_
 
38
#define KERN_sparc64_MMU_TRAP_H_
 
39
 
 
40
#include <arch/stack.h>
 
41
#include <arch/regdef.h>
 
42
#include <arch/mm/tlb.h>
 
43
#include <arch/mm/mmu.h>
 
44
#include <arch/mm/tte.h>
 
45
#include <arch/trap/regwin.h>
 
46
 
 
47
#ifdef CONFIG_TSB
 
48
#include <arch/mm/tsb.h>
 
49
#endif
 
50
 
 
51
#define TT_FAST_INSTRUCTION_ACCESS_MMU_MISS     0x64
 
52
#define TT_FAST_DATA_ACCESS_MMU_MISS            0x68
 
53
#define TT_FAST_DATA_ACCESS_PROTECTION          0x6c
 
54
 
 
55
#define FAST_MMU_HANDLER_SIZE                   128
 
56
 
 
57
#ifdef __ASM__
 
58
 
 
59
.macro FAST_INSTRUCTION_ACCESS_MMU_MISS_HANDLER
 
60
        /*
 
61
         * First, try to refill TLB from TSB.
 
62
         */
 
63
#ifdef CONFIG_TSB
 
64
        ldxa [%g0] ASI_IMMU, %g1                        ! read TSB Tag Target Register
 
65
        ldxa [%g0] ASI_IMMU_TSB_8KB_PTR_REG, %g2        ! read TSB 8K Pointer
 
66
        ldda [%g2] ASI_NUCLEUS_QUAD_LDD, %g4            ! 16-byte atomic load into %g4 and %g5
 
67
        cmp %g1, %g4                                    ! is this the entry we are looking for?
 
68
        bne,pn %xcc, 0f
 
69
        nop
 
70
        stxa %g5, [%g0] ASI_ITLB_DATA_IN_REG            ! copy mapping from ITSB to ITLB
 
71
        retry
 
72
#endif
 
73
 
 
74
0:
 
75
        wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
 
76
        PREEMPTIBLE_HANDLER fast_instruction_access_mmu_miss
 
77
.endm
 
78
 
 
79
.macro FAST_DATA_ACCESS_MMU_MISS_HANDLER tl
 
80
        /*
 
81
         * First, try to refill TLB from TSB.
 
82
         */
 
83
 
 
84
#ifdef CONFIG_TSB
 
85
        ldxa [%g0] ASI_DMMU, %g1                        ! read TSB Tag Target Register
 
86
        srlx %g1, TSB_TAG_TARGET_CONTEXT_SHIFT, %g2     ! is this a kernel miss?
 
87
        brz,pn %g2, 0f
 
88
        ldxa [%g0] ASI_DMMU_TSB_8KB_PTR_REG, %g3        ! read TSB 8K Pointer
 
89
        ldda [%g3] ASI_NUCLEUS_QUAD_LDD, %g4            ! 16-byte atomic load into %g4 and %g5
 
90
        cmp %g1, %g4                                    ! is this the entry we are looking for?
 
91
        bne,pn %xcc, 0f
 
92
        nop
 
93
        stxa %g5, [%g0] ASI_DTLB_DATA_IN_REG            ! copy mapping from DTSB to DTLB
 
94
        retry
 
95
#endif
 
96
 
 
97
        /*
 
98
         * Second, test if it is the portion of the kernel address space
 
99
         * which is faulting. If that is the case, immediately create
 
100
         * identity mapping for that page in DTLB. VPN 0 is excluded from
 
101
         * this treatment.
 
102
         *
 
103
         * Note that branch-delay slots are used in order to save space.
 
104
         */
 
105
0:
 
106
        sethi %hi(fast_data_access_mmu_miss_data_hi), %g7
 
107
        wr %g0, ASI_DMMU, %asi
 
108
        ldxa [VA_DMMU_TAG_ACCESS] %asi, %g1             ! read the faulting Context and VPN
 
109
        set TLB_TAG_ACCESS_CONTEXT_MASK, %g2
 
110
        andcc %g1, %g2, %g3                             ! get Context
 
111
        bnz %xcc, 0f                                    ! Context is non-zero
 
112
        andncc %g1, %g2, %g3                            ! get page address into %g3
 
113
        bz  %xcc, 0f                                    ! page address is zero
 
114
        ldx [%g7 + %lo(end_of_identity)], %g4
 
115
        cmp %g3, %g4
 
116
        bgeu %xcc, 0f
 
117
 
 
118
        ldx [%g7 + %lo(kernel_8k_tlb_data_template)], %g2
 
119
        add %g3, %g2, %g2
 
120
        stxa %g2, [%g0] ASI_DTLB_DATA_IN_REG            ! identity map the kernel page
 
121
        retry
 
122
 
 
123
        /*
 
124
         * Third, catch and handle special cases when the trap is caused by
 
125
         * the userspace register window spill or fill handler. In case
 
126
         * one of these two traps caused this trap, we just lower the trap
 
127
         * level and service the DTLB miss. In the end, we restart
 
128
         * the offending SAVE or RESTORE.
 
129
         */
 
130
0:
 
131
.if (\tl > 0)
 
132
        wrpr %g0, 1, %tl
 
133
.endif
 
134
 
 
135
        /*
 
136
         * Switch from the MM globals.
 
137
         */
 
138
        wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
 
139
 
 
140
        /*
 
141
         * Read the Tag Access register for the higher-level handler.
 
142
         * This is necessary to survive nested DTLB misses.
 
143
         */     
 
144
        ldxa [VA_DMMU_TAG_ACCESS] %asi, %g2
 
145
 
 
146
        /*
 
147
         * g2 will be passed as an argument to fast_data_access_mmu_miss().
 
148
         */
 
149
        PREEMPTIBLE_HANDLER fast_data_access_mmu_miss
 
150
.endm
 
151
 
 
152
.macro FAST_DATA_ACCESS_PROTECTION_HANDLER tl
 
153
        /*
 
154
         * The same special case as in FAST_DATA_ACCESS_MMU_MISS_HANDLER.
 
155
         */
 
156
 
 
157
.if (\tl > 0)
 
158
        wrpr %g0, 1, %tl
 
159
.endif
 
160
 
 
161
        /*
 
162
         * Switch from the MM globals.
 
163
         */
 
164
        wrpr %g0, PSTATE_PRIV_BIT | PSTATE_AG_BIT, %pstate
 
165
 
 
166
        /*
 
167
         * Read the Tag Access register for the higher-level handler.
 
168
         * This is necessary to survive nested DTLB misses.
 
169
         */     
 
170
        mov VA_DMMU_TAG_ACCESS, %g2
 
171
        ldxa [%g2] ASI_DMMU, %g2
 
172
 
 
173
        /*
 
174
         * g2 will be passed as an argument to fast_data_access_mmu_miss().
 
175
         */
 
176
        PREEMPTIBLE_HANDLER fast_data_access_protection
 
177
.endm
 
178
 
 
179
#endif /* __ASM__ */
 
180
 
 
181
#endif
 
182
 
 
183
/** @}
 
184
 */