Subversion Repositories HelenOS

Rev

Rev 4129 | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 4129 Rev 4433
1
/*
1
/*
2
 * Copyright (c) 2006 Jakub Jermar
2
 * Copyright (c) 2006 Jakub Jermar
3
 * Copyright (c) 2009 Pavel Rimsky
3
 * Copyright (c) 2009 Pavel Rimsky
4
 * All rights reserved.
4
 * All rights reserved.
5
 *
5
 *
6
 * Redistribution and use in source and binary forms, with or without
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions
7
 * modification, are permitted provided that the following conditions
8
 * are met:
8
 * are met:
9
 *
9
 *
10
 * - Redistributions of source code must retain the above copyright
10
 * - Redistributions of source code must retain the above copyright
11
 *   notice, this list of conditions and the following disclaimer.
11
 *   notice, this list of conditions and the following disclaimer.
12
 * - Redistributions in binary form must reproduce the above copyright
12
 * - Redistributions in binary form must reproduce the above copyright
13
 *   notice, this list of conditions and the following disclaimer in the
13
 *   notice, this list of conditions and the following disclaimer in the
14
 *   documentation and/or other materials provided with the distribution.
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
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.
16
 *   derived from this software without specific prior written permission.
17
 *
17
 *
18
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
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
19
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
20
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
21
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
22
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
23
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
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
24
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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
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.
27
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28
 */
28
 */
29
 
29
 
30
/** @addtogroup sparc64mm  
30
/** @addtogroup sparc64mm  
31
 * @{
31
 * @{
32
 */
32
 */
33
/** @file
33
/** @file
34
 */
34
 */
35
 
35
 
36
#include <arch/mm/tsb.h>
36
#include <arch/mm/tsb.h>
37
#include <arch/mm/pagesize.h>
37
#include <arch/mm/pagesize.h>
38
#include <arch/mm/tlb.h>
38
#include <arch/mm/tlb.h>
39
#include <arch/mm/page.h>
39
#include <arch/mm/page.h>
40
#include <arch/barrier.h>
40
#include <arch/barrier.h>
41
#include <mm/as.h>
41
#include <mm/as.h>
42
#include <arch/types.h>
42
#include <arch/types.h>
43
#include <macros.h>
43
#include <macros.h>
44
#include <debug.h>
44
#include <debug.h>
45
 
45
 
46
#define TSB_INDEX_MASK  ((1 << (21 + 1 + TSB_SIZE - MMU_PAGE_WIDTH)) - 1)
46
#define TSB_INDEX_MASK  ((1 << (21 + 1 + TSB_SIZE - MMU_PAGE_WIDTH)) - 1)
47
 
47
 
48
/** Invalidate portion of TSB.
48
/** Invalidate portion of TSB.
49
 *
49
 *
50
 * We assume that the address space is already locked. Note that respective
50
 * We assume that the address space is already locked. Note that respective
51
 * portions of both TSBs are invalidated at a time.
51
 * portions of both TSBs are invalidated at a time.
52
 *
52
 *
53
 * @param as    Address space.
53
 * @param as    Address space.
54
 * @param page  First page to invalidate in TSB.
54
 * @param page  First page to invalidate in TSB.
55
 * @param pages Number of pages to invalidate. Value of (count_t) -1 means the
55
 * @param pages Number of pages to invalidate. Value of (count_t) -1 means the
56
 *      whole TSB.
56
 *      whole TSB.
57
 */
57
 */
58
void tsb_invalidate(as_t *as, uintptr_t page, count_t pages)
58
void tsb_invalidate(as_t *as, uintptr_t page, count_t pages)
59
{
59
{
60
    index_t i0, i;
60
    index_t i0, i;
61
    count_t cnt;
61
    count_t cnt;
62
   
62
   
63
    ASSERT(as->arch.tsb_description.tsb_base);
63
    ASSERT(as->arch.tsb_description.tsb_base);
64
   
64
   
65
    i0 = (page >> MMU_PAGE_WIDTH) & TSB_INDEX_MASK;
65
    i0 = (page >> MMU_PAGE_WIDTH) & TSB_INDEX_MASK;
66
    ASSERT(i0 < TSB_ENTRY_COUNT);
66
    ASSERT(i0 < TSB_ENTRY_COUNT);
67
 
67
 
68
    if (pages == (count_t) - 1 || (pages) > TSB_ENTRY_COUNT)
68
    if (pages == (count_t) - 1 || (pages) > TSB_ENTRY_COUNT)
69
        cnt = TSB_ENTRY_COUNT;
69
        cnt = TSB_ENTRY_COUNT;
70
    else
70
    else
71
        cnt = pages;
71
        cnt = pages;
72
   
72
   
73
    for (i = 0; i < cnt; i++) {
73
    for (i = 0; i < cnt; i++) {
74
        ((tsb_entry_t *) as->arch.tsb_description.tsb_base)[
74
        ((tsb_entry_t *) PA2KA(as->arch.tsb_description.tsb_base))[
75
            (i0 + i) & (TSB_ENTRY_COUNT - 1)].data.v = false;
75
            (i0 + i) & (TSB_ENTRY_COUNT - 1)].data.v = false;
76
    }
76
    }
77
}
77
}
78
 
78
 
79
/** Copy software PTE to ITSB.
79
/** Copy software PTE to ITSB.
80
 *
80
 *
81
 * @param t     Software PTE.
81
 * @param t     Software PTE.
82
 */
82
 */
83
void itsb_pte_copy(pte_t *t)
83
void itsb_pte_copy(pte_t *t)
84
{
84
{
85
    as_t *as;
85
    as_t *as;
86
    tsb_entry_t *tsb;
86
    tsb_entry_t *tsb;
87
    index_t entry;
87
    index_t entry;
88
 
88
 
89
    as = t->as;
89
    as = t->as;
90
    entry = (t->page >> MMU_PAGE_WIDTH) & TSB_INDEX_MASK;
90
    entry = (t->page >> MMU_PAGE_WIDTH) & TSB_INDEX_MASK;
91
    ASSERT(entry < TSB_ENTRY_COUNT);
91
    ASSERT(entry < TSB_ENTRY_COUNT);
92
    tsb = &((tsb_entry_t *) as->arch.tsb_description.tsb_base)[entry];
92
    tsb = &((tsb_entry_t *) PA2KA(as->arch.tsb_description.tsb_base))[entry];
93
 
93
 
94
    /*
94
    /*
95
     * We use write barriers to make sure that the TSB load
95
     * We use write barriers to make sure that the TSB load
96
     * won't use inconsistent data or that the fault will
96
     * won't use inconsistent data or that the fault will
97
     * be repeated.
97
     * be repeated.
98
     */
98
     */
99
 
99
 
100
    tsb->data.v = false;
100
    tsb->data.v = false;
101
 
101
 
102
    write_barrier();
102
    write_barrier();
103
 
103
 
104
    tsb->tag.context = as->asid;
-
 
105
    tsb->tag.va_tag = t->page >> VA_TAG_PAGE_SHIFT;
104
    tsb->tag.va_tag = t->page >> VA_TAG_PAGE_SHIFT;
106
 
105
 
107
    tsb->data.value = 0;
106
    tsb->data.value = 0;
108
    tsb->data.nfo = false;
107
    tsb->data.nfo = false;
109
    tsb->data.ra = t->frame >> MMU_FRAME_WIDTH;
108
    tsb->data.ra = t->frame >> MMU_FRAME_WIDTH;
110
    tsb->data.ie = false;
109
    tsb->data.ie = false;
111
    tsb->data.e = false;
110
    tsb->data.e = false;
112
    tsb->data.cp = t->c;    /* cp as cache in phys.-idxed, c as cacheable */
111
    tsb->data.cp = t->c;    /* cp as cache in phys.-idxed, c as cacheable */
113
    tsb->data.cv = false;
112
    tsb->data.cv = false;
114
    tsb->data.p = t->k; /* p as privileged, k as kernel */
113
    tsb->data.p = t->k; /* p as privileged, k as kernel */
115
    tsb->data.x = true;
114
    tsb->data.x = true;
116
    tsb->data.w = false;
115
    tsb->data.w = false;
117
    tsb->data.size = PAGESIZE_8K;
116
    tsb->data.size = PAGESIZE_8K;
118
   
117
   
119
    write_barrier();
118
    write_barrier();
120
   
119
   
121
    tsb->data.v = t->p; /* v as valid, p as present */
120
    tsb->data.v = t->p; /* v as valid, p as present */
122
}
121
}
123
 
122
 
124
/** Copy software PTE to DTSB.
123
/** Copy software PTE to DTSB.
125
 *
124
 *
126
 * @param t Software PTE.
125
 * @param t Software PTE.
127
 * @param ro    If true, the mapping is copied read-only.
126
 * @param ro    If true, the mapping is copied read-only.
128
 */
127
 */
129
void dtsb_pte_copy(pte_t *t, bool ro)
128
void dtsb_pte_copy(pte_t *t, bool ro)
130
{
129
{
131
    as_t *as;
130
    as_t *as;
132
    tsb_entry_t *tsb;
131
    tsb_entry_t *tsb;
133
    index_t entry;
132
    index_t entry;
134
 
133
 
135
    as = t->as;
134
    as = t->as;
136
    entry = (t->page >> MMU_PAGE_WIDTH) & TSB_INDEX_MASK;
135
    entry = (t->page >> MMU_PAGE_WIDTH) & TSB_INDEX_MASK;
137
    ASSERT(entry < TSB_ENTRY_COUNT);
136
    ASSERT(entry < TSB_ENTRY_COUNT);
138
    tsb = &((tsb_entry_t *) as->arch.tsb_description.tsb_base)[entry];
137
    tsb = &((tsb_entry_t *) PA2KA(as->arch.tsb_description.tsb_base))[entry];
139
 
138
 
140
    /*
139
    /*
141
     * We use write barriers to make sure that the TSB load
140
     * We use write barriers to make sure that the TSB load
142
     * won't use inconsistent data or that the fault will
141
     * won't use inconsistent data or that the fault will
143
     * be repeated.
142
     * be repeated.
144
     */
143
     */
145
 
144
 
146
    tsb->data.v = false;
145
    tsb->data.v = false;
147
 
146
 
148
    write_barrier();
147
    write_barrier();
149
 
148
 
150
    tsb->tag.context = as->asid;
-
 
151
    tsb->tag.va_tag = t->page >> VA_TAG_PAGE_SHIFT;
149
    tsb->tag.va_tag = t->page >> VA_TAG_PAGE_SHIFT;
152
 
150
 
153
    tsb->data.value = 0;
151
    tsb->data.value = 0;
154
    tsb->data.nfo = false;
152
    tsb->data.nfo = false;
155
    tsb->data.ra = t->frame >> MMU_FRAME_WIDTH;
153
    tsb->data.ra = t->frame >> MMU_FRAME_WIDTH;
156
    tsb->data.ie = false;
154
    tsb->data.ie = false;
157
    tsb->data.e = false;
155
    tsb->data.e = false;
158
    tsb->data.cp = t->c;    /* cp as cache in phys.-idxed, c as cacheable */
156
    tsb->data.cp = t->c;    /* cp as cache in phys.-idxed, c as cacheable */
159
#ifdef CONFIG_VIRT_IDX_DCACHE
157
#ifdef CONFIG_VIRT_IDX_DCACHE
160
    tsb->data.cv = t->c;
158
    tsb->data.cv = t->c;
161
#endif /* CONFIG_VIRT_IDX_DCACHE */
159
#endif /* CONFIG_VIRT_IDX_DCACHE */
162
    tsb->data.p = t->k; /* p as privileged, k as kernel */
160
    tsb->data.p = t->k; /* p as privileged, k as kernel */
163
    tsb->data.x = true;
161
    tsb->data.x = true;
164
    tsb->data.w = ro ? false : t->w;
162
    tsb->data.w = ro ? false : t->w;
165
    tsb->data.size = PAGESIZE_8K;
163
    tsb->data.size = PAGESIZE_8K;
166
   
164
   
167
    write_barrier();
165
    write_barrier();
168
   
166
   
169
    tsb->data.v = t->p; /* v as valid, p as present */
167
    tsb->data.v = t->p; /* v as valid, p as present */
170
}
168
}
171
 
169
 
172
/** @}
170
/** @}
173
 */
171
 */
174
 
172
 
175
 
173
 
176
 
174