source: mainline/kernel/arch/mips32/src/mm/frame.c@ edebc15c

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since edebc15c was edebc15c, checked in by Martin Decky <martin@…>, 17 years ago

physical memory detection in MSIM (discontinous regions supported)
remove Sgi Indy (ARC) support — it was unmaintaned, untested for years and without uspace support

  • Property mode set to 100644
File size: 6.3 KB
RevLine 
[f761f1eb]1/*
[df4ed85]2 * Copyright (c) 2005 Jakub Jermar
[f761f1eb]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
[a6dd361]29/** @addtogroup mips32mm
[b45c443]30 * @{
31 */
32/** @file
33 */
34
[edebc15c]35#include <macros.h>
[f761f1eb]36#include <arch/mm/frame.h>
[edebc15c]37#include <arch/mm/tlb.h>
[f761f1eb]38#include <mm/frame.h>
[edebc15c]39#include <mm/asid.h>
[84dd253]40#include <config.h>
[edebc15c]41#include <arch/drivers/msim.h>
42#include <arch/drivers/serial.h>
43#include <print.h>
44#include <debug.h>
45
46#define TLB_PAGE_MASK_1M (0xff << 13)
47
48#define ZERO_FRAMES 4096
49#define ZERO_PAGE_WIDTH 20 /* 1M */
50#define ZERO_PAGE_SIZE (1 << ZERO_PAGE_WIDTH)
51#define ZERO_PAGE_ASID ASID_INVALID
52#define ZERO_PAGE_TLBI 0
53#define ZERO_PAGE_ADDR 0
54#define ZERO_PAGE_OFFSET (ZERO_PAGE_SIZE / sizeof(uint32_t) - 1)
55#define ZERO_PAGE_VALUE (*((volatile uint32_t *) ZERO_PAGE_ADDR + ZERO_PAGE_OFFSET))
56
57#define MAX_REGIONS 32
58
59typedef struct {
60 pfn_t start;
61 pfn_t count;
62} phys_region_t;
63
64static count_t phys_regions_count = 0;
65static phys_region_t phys_regions[MAX_REGIONS];
66
67
68/** Check whether frame is available
69 *
70 * Returns true if given frame is generally available for use.
71 * Returns false if given frame is used for physical memory
72 * mapped devices and cannot be used.
73 *
74 */
75static bool frame_available(pfn_t frame)
76{
77 /* MSIM device (dprinter) */
78 if (frame == (KA2PA(MSIM_VIDEORAM) >> ZERO_PAGE_WIDTH))
79 return false;
80
81 /* MSIM device (dkeyboard) */
82 if (frame == (KA2PA(MSIM_KBD_ADDRESS) >> ZERO_PAGE_WIDTH))
83 return false;
84
85 /* Simics device (serial line) */
86 if (frame == (KA2PA(SERIAL_ADDRESS) >> ZERO_PAGE_WIDTH))
87 return false;
88
89 return true;
90}
91
92
93/** Check whether frame is safe to write
94 *
95 * Returns true if given frame is safe for read/write test.
96 * Returns false if given frame should not be touched.
97 *
98 */
99static bool frame_safe(pfn_t frame) __attribute__((unused));
100static bool frame_safe(pfn_t frame)
101{
102 /* Kernel structures */
103 if ((frame << ZERO_PAGE_WIDTH) < KA2PA(config.base))
104 return false;
105
106 /* Kernel */
107 if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE,
108 KA2PA(config.base), config.kernel_size))
109 return false;
110
111 /* Kernel stack */
112 if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE,
113 KA2PA(config.stack_base), config.stack_size))
114 return false;
115
116 /* Init tasks */
117 bool safe = true;
118 count_t i;
119 for (i = 0; i < init.cnt; i++)
120 if (overlaps(frame << ZERO_PAGE_WIDTH, ZERO_PAGE_SIZE,
121 KA2PA(init.tasks[i].addr), init.tasks[i].size)) {
122 safe = false;
123 break;
124 }
125
126 return safe;
127}
128
129static void frame_add_region(pfn_t start_frame, pfn_t end_frame)
130{
131 if (end_frame > start_frame) {
132 /* Convert 1M frames to 16K frames */
133 pfn_t first = ADDR2PFN(start_frame << ZERO_PAGE_WIDTH);
134 pfn_t count = ADDR2PFN((end_frame - start_frame - 1) << ZERO_PAGE_WIDTH);
135
136 /* Interrupt vector frame is blacklisted */
137 pfn_t conf_frame;
138 if (start_frame == 0)
139 conf_frame = 1;
140 else
141 conf_frame = first;
142
143 zone_create(first, count, conf_frame, 0);
144
145 if (phys_regions_count < MAX_REGIONS) {
146 phys_regions[phys_regions_count].start = first;
147 phys_regions[phys_regions_count].count = count;
148 phys_regions_count++;
149 }
150 }
151}
152
[f761f1eb]153
[939dfd7]154/** Create memory zones
155 *
[edebc15c]156 * Walk through available 1 MB chunks of physical
157 * memory and create zones.
158 *
[939dfd7]159 */
[f761f1eb]160void frame_arch_init(void)
161{
[edebc15c]162 cp0_index_write(ZERO_PAGE_TLBI);
163 tlbr();
164
165 uint32_t orig_pagemask = cp0_pagemask_read();
166 uint32_t orig_lo0 = cp0_entry_lo0_read();
167 uint32_t orig_lo1 = cp0_entry_lo1_read();
168 uint32_t orig_hi = cp0_entry_hi_read();
169
170 pfn_t start_frame = 0;
171 pfn_t frame;
172 bool avail = true;
173
174 /* Walk through all 1 MB frames */
175 for (frame = 0; frame < ZERO_FRAMES; frame++) {
176 if (!frame_available(frame))
177 avail = false;
178 else {
179 if (frame_safe(frame)) {
180 entry_lo_t lo0;
181 entry_lo_t lo1;
182 entry_hi_t hi;
183 tlb_prepare_entry_lo(&lo0, false, true, true, false, frame << (ZERO_PAGE_WIDTH - 12));
184 tlb_prepare_entry_lo(&lo1, false, false, false, false, 0);
185 tlb_prepare_entry_hi(&hi, ZERO_PAGE_ASID, ZERO_PAGE_ADDR);
186
187 cp0_index_write(ZERO_PAGE_TLBI);
188 cp0_pagemask_write(TLB_PAGE_MASK_1M);
189 cp0_entry_lo0_write(lo0.value);
190 cp0_entry_lo1_write(lo1.value);
191 cp0_entry_hi_write(hi.value);
192 tlbwi();
193
194 ZERO_PAGE_VALUE = 0;
195 if (ZERO_PAGE_VALUE != 0)
196 avail = false;
197 else {
198 ZERO_PAGE_VALUE = 0xdeadbeef;
199 if (ZERO_PAGE_VALUE != 0xdeadbeef)
200 avail = false;
201 }
202 }
203 }
204
205 if (!avail) {
206 frame_add_region(start_frame, frame);
207 start_frame = frame + 1;
208 avail = true;
209 }
[085d973]210 }
[edebc15c]211
212 frame_add_region(start_frame, frame);
213
214 /* Cleanup TLB */
215 cp0_index_write(ZERO_PAGE_TLBI);
216 cp0_pagemask_write(orig_pagemask);
217 cp0_entry_lo0_write(orig_lo0);
218 cp0_entry_lo1_write(orig_lo1);
219 cp0_entry_hi_write(orig_hi);
220 tlbwi();
221
222 /* Blacklist interrupt vector frame */
223 frame_mark_unavailable(0, 1);
224}
225
226
227void physmem_print(void)
228{
229 printf("Base Size\n");
230 printf("---------- ----------\n");
231
232 count_t i;
233 for (i = 0; i < phys_regions_count; i++) {
234 printf("%#10x %10u\n",
235 PFN2ADDR(phys_regions[i].start), PFN2ADDR(phys_regions[i].count));
236 }
[f761f1eb]237}
[b45c443]238
[a6dd361]239/** @}
[b45c443]240 */
Note: See TracBrowser for help on using the repository browser.