Rev 4130 | Go to most recent revision | Only display areas with differences | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4130 | 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/as.h> |
36 | #include <arch/mm/as.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 <genarch/mm/page_ht.h> |
39 | #include <genarch/mm/page_ht.h> |
40 | #include <genarch/mm/asid_fifo.h> |
40 | #include <genarch/mm/asid_fifo.h> |
41 | #include <debug.h> |
41 | #include <debug.h> |
42 | #include <config.h> |
42 | #include <config.h> |
43 | #include <arch/sun4v/hypercall.h> |
43 | #include <arch/sun4v/hypercall.h> |
44 | 44 | ||
45 | #ifdef CONFIG_TSB |
45 | #ifdef CONFIG_TSB |
46 | #include <arch/mm/tsb.h> |
46 | #include <arch/mm/tsb.h> |
47 | #include <arch/memstr.h> |
47 | #include <arch/memstr.h> |
48 | #include <arch/asm.h> |
48 | #include <arch/asm.h> |
49 | #include <mm/frame.h> |
49 | #include <mm/frame.h> |
50 | #include <bitops.h> |
50 | #include <bitops.h> |
51 | #include <macros.h> |
51 | #include <macros.h> |
52 | #endif /* CONFIG_TSB */ |
52 | #endif /* CONFIG_TSB */ |
53 | 53 | ||
54 | /** Architecture dependent address space init. */ |
54 | /** Architecture dependent address space init. */ |
55 | void as_arch_init(void) |
55 | void as_arch_init(void) |
56 | { |
56 | { |
57 | if (config.cpu_active == 1) { |
57 | if (config.cpu_active == 1) { |
58 | as_operations = &as_ht_operations; |
58 | as_operations = &as_ht_operations; |
59 | asid_fifo_init(); |
59 | asid_fifo_init(); |
60 | } |
60 | } |
61 | } |
61 | } |
62 | 62 | ||
63 | int as_constructor_arch(as_t *as, int flags) |
63 | int as_constructor_arch(as_t *as, int flags) |
64 | { |
64 | { |
65 | #ifdef CONFIG_TSB |
65 | #ifdef CONFIG_TSB |
66 | int order = fnzb32( |
66 | int order = fnzb32( |
67 | (TSB_ENTRY_COUNT * sizeof(tsb_entry_t)) >> FRAME_WIDTH); |
67 | (TSB_ENTRY_COUNT * sizeof(tsb_entry_t)) >> FRAME_WIDTH); |
68 | 68 | ||
69 | uintptr_t tsb = (uintptr_t) frame_alloc(order, flags | FRAME_KA); |
69 | uintptr_t tsb = (uintptr_t) frame_alloc(order, flags); |
70 | 70 | ||
71 | if (!tsb) |
71 | if (!tsb) |
72 | return -1; |
72 | return -1; |
73 | 73 | ||
74 | as->arch.tsb_description.page_size = PAGESIZE_8K; |
74 | as->arch.tsb_description.page_size = PAGESIZE_8K; |
75 | as->arch.tsb_description.associativity = 1; |
75 | as->arch.tsb_description.associativity = 1; |
76 | as->arch.tsb_description.num_ttes = TSB_ENTRY_COUNT; |
76 | as->arch.tsb_description.num_ttes = TSB_ENTRY_COUNT; |
77 | as->arch.tsb_description.pgsize_mask = 1 << PAGESIZE_8K; |
77 | as->arch.tsb_description.pgsize_mask = 1 << PAGESIZE_8K; |
78 | as->arch.tsb_description.tsb_base = tsb; |
78 | as->arch.tsb_description.tsb_base = tsb; |
79 | as->arch.tsb_description.reserved = 0; |
79 | as->arch.tsb_description.reserved = 0; |
- | 80 | as->arch.tsb_description.context = 0; |
|
80 | 81 | ||
81 | memsetb((void *) as->arch.tsb_description.tsb_base, |
82 | memsetb((void *) PA2KA(as->arch.tsb_description.tsb_base), |
82 | TSB_ENTRY_COUNT * sizeof(tsb_entry_t), 0); |
83 | TSB_ENTRY_COUNT * sizeof(tsb_entry_t), 0); |
83 | #endif |
84 | #endif |
84 | return 0; |
85 | return 0; |
85 | } |
86 | } |
86 | 87 | ||
87 | int as_destructor_arch(as_t *as) |
88 | int as_destructor_arch(as_t *as) |
88 | { |
89 | { |
89 | #ifdef CONFIG_TSB |
90 | #ifdef CONFIG_TSB |
90 | count_t cnt = (TSB_ENTRY_COUNT * sizeof(tsb_entry_t)) >> FRAME_WIDTH; |
91 | count_t cnt = (TSB_ENTRY_COUNT * sizeof(tsb_entry_t)) >> FRAME_WIDTH; |
91 | frame_free(KA2PA((uintptr_t) as->arch.tsb_description.tsb_base)); |
92 | frame_free((uintptr_t) as->arch.tsb_description.tsb_base); |
92 | return cnt; |
93 | return cnt; |
93 | #else |
94 | #else |
94 | return 0; |
95 | return 0; |
95 | #endif |
96 | #endif |
96 | } |
97 | } |
97 | 98 | ||
98 | int as_create_arch(as_t *as, int flags) |
99 | int as_create_arch(as_t *as, int flags) |
99 | { |
100 | { |
100 | #ifdef CONFIG_TSB |
101 | #ifdef CONFIG_TSB |
101 | tsb_invalidate(as, 0, (count_t) -1); |
102 | tsb_invalidate(as, 0, (count_t) -1); |
102 | as->arch.tsb_description.context = as->asid; |
- | |
103 | #endif |
103 | #endif |
104 | return 0; |
104 | return 0; |
105 | } |
105 | } |
106 | 106 | ||
107 | /** Perform sparc64-specific tasks when an address space becomes active on the |
107 | /** Perform sparc64-specific tasks when an address space becomes active on the |
108 | * processor. |
108 | * processor. |
109 | * |
109 | * |
110 | * Install ASID and map TSBs. |
110 | * Install ASID and map TSBs. |
111 | * |
111 | * |
112 | * @param as Address space. |
112 | * @param as Address space. |
113 | */ |
113 | */ |
114 | void as_install_arch(as_t *as) |
114 | void as_install_arch(as_t *as) |
115 | { |
115 | { |
116 | mmu_secondary_context_write(as->asid); |
116 | mmu_secondary_context_write(as->asid); |
117 | 117 | ||
118 | #ifdef CONFIG_TSB |
118 | #ifdef CONFIG_TSB |
119 | uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH); |
119 | uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH); |
120 | 120 | ||
121 | ASSERT(as->arch.tsb_description.tsb_base); |
121 | ASSERT(as->arch.tsb_description.tsb_base); |
122 | uintptr_t tsb = as->arch.tsb_description.tsb_base; |
122 | uintptr_t tsb = PA2KA(as->arch.tsb_description.tsb_base); |
123 | 123 | ||
124 | if (!overlaps(tsb, 8 * MMU_PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) { |
124 | if (!overlaps(tsb, 8 * MMU_PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) { |
125 | /* |
125 | /* |
126 | * TSBs were allocated from memory not covered |
126 | * TSBs were allocated from memory not covered |
127 | * by the locked 4M kernel DTLB entry. We need |
127 | * by the locked 4M kernel DTLB entry. We need |
128 | * to map both TSBs explicitly. |
128 | * to map both TSBs explicitly. |
129 | */ |
129 | */ |
130 | mmu_demap_page(tsb, 0, MMU_FLAG_DTLB); |
130 | mmu_demap_page(tsb, 0, MMU_FLAG_DTLB); |
131 | dtlb_insert_mapping(tsb, KA2PA(tsb), PAGESIZE_64K, true, true); |
131 | dtlb_insert_mapping(tsb, KA2PA(tsb), PAGESIZE_64K, true, true); |
132 | } |
132 | } |
133 | 133 | ||
134 | __hypercall_fast2(MMU_TSB_CTX0, 1, as->arch.tsb_description.tsb_base); |
134 | __hypercall_fast2(MMU_TSB_CTXNON0, 1, KA2PA(&(as->arch.tsb_description))); |
135 | 135 | ||
136 | #endif |
136 | #endif |
137 | } |
137 | } |
138 | 138 | ||
139 | /** Perform sparc64-specific tasks when an address space is removed from the |
139 | /** Perform sparc64-specific tasks when an address space is removed from the |
140 | * processor. |
140 | * processor. |
141 | * |
141 | * |
142 | * Demap TSBs. |
142 | * Demap TSBs. |
143 | * |
143 | * |
144 | * @param as Address space. |
144 | * @param as Address space. |
145 | */ |
145 | */ |
146 | void as_deinstall_arch(as_t *as) |
146 | void as_deinstall_arch(as_t *as) |
147 | { |
147 | { |
148 | /* |
148 | /* |
149 | * Note that we don't and may not lock the address space. That's ok |
149 | * Note that we don't and may not lock the address space. That's ok |
150 | * since we only read members that are currently read-only. |
150 | * since we only read members that are currently read-only. |
151 | * |
151 | * |
152 | * Moreover, the as->asid is protected by asidlock, which is being held. |
152 | * Moreover, the as->asid is protected by asidlock, which is being held. |
153 | */ |
153 | */ |
154 | #ifdef CONFIG_TSB |
154 | #ifdef CONFIG_TSB |
155 | uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH); |
155 | uintptr_t base = ALIGN_DOWN(config.base, 1 << KERNEL_PAGE_WIDTH); |
156 | 156 | ||
157 | ASSERT(as->arch.tsb_description.tsb_base); |
157 | ASSERT(as->arch.tsb_description.tsb_base); |
158 | 158 | ||
159 | uintptr_t tsb = as->arch.tsb_description.tsb_base; |
159 | uintptr_t tsb = PA2KA(as->arch.tsb_description.tsb_base); |
160 | 160 | ||
161 | if (!overlaps(tsb, 8 * MMU_PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) { |
161 | if (!overlaps(tsb, 8 * MMU_PAGE_SIZE, base, 1 << KERNEL_PAGE_WIDTH)) { |
162 | /* |
162 | /* |
163 | * TSBs were allocated from memory not covered |
163 | * TSBs were allocated from memory not covered |
164 | * by the locked 4M kernel DTLB entry. We need |
164 | * by the locked 4M kernel DTLB entry. We need |
165 | * to demap the entry installed by as_install_arch(). |
165 | * to demap the entry installed by as_install_arch(). |
166 | */ |
166 | */ |
167 | __hypercall_fast3(MMU_UNMAP_PERM_ADDR, tsb, 0, MMU_FLAG_DTLB); |
167 | __hypercall_fast3(MMU_UNMAP_PERM_ADDR, tsb, 0, MMU_FLAG_DTLB); |
168 | } |
168 | } |
169 | #endif |
169 | #endif |
170 | } |
170 | } |
171 | 171 | ||
172 | /** @} |
172 | /** @} |
173 | */ |
173 | */ |
174 | 174 |