source: mainline/src/mm/frame.c@ a7a10630

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a7a10630 was a7a10630, checked in by Jakub Jermar <jakub@…>, 20 years ago

SMP recovery patch #2 (SMP is no longer broken !!!).
Fix missing KA2PA() operation in ap.S which was causing page faults during AP early initialization.
Fix bug in map_page_to_frame(): 'root' was interpretted as kernel address while read_dba() returns physical address.
Make references to page directory and page tables use kernel addresses instead of physical addresses.

Massive frame allocation code cleanup.
Basically revert to what we had had before implementation of userspace.

Usual cosmetics.

  • Property mode set to 100644
File size: 4.8 KB
Line 
1/*
2 * Copyright (C) 2001-2004 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#include <arch/types.h>
30#include <func.h>
31
32#include <mm/heap.h>
33#include <mm/frame.h>
34#include <mm/page.h>
35#include <mm/vm.h>
36#include <arch/mm/page.h>
37
38#include <config.h>
39#include <memstr.h>
40
41#include <panic.h>
42
43#include <synch/spinlock.h>
44
45count_t frames = 0;
46count_t frames_free;
47
48__u8 *frame_bitmap;
49count_t frame_bitmap_octets;
50
51static spinlock_t framelock;
52
53void frame_init(void)
54{
55 if (config.cpu_active == 1) {
56
57 /*
58 * The bootstrap processor will allocate all necessary memory for frame allocation.
59 */
60
61 frames = config.memory_size / FRAME_SIZE;
62 frame_bitmap_octets = frames / 8 + (frames % 8 > 0);
63 frame_bitmap = (__u8 *) malloc(frame_bitmap_octets);
64 if (!frame_bitmap)
65 panic("malloc/frame_bitmap\n");
66
67 /*
68 * Mark all frames free.
69 */
70 memsetb((__address) frame_bitmap, frame_bitmap_octets, 0);
71 frames_free = frames;
72 }
73
74 /*
75 * No frame allocations/reservations prior this point.
76 */
77
78 frame_arch_init();
79
80 if (config.cpu_active == 1) {
81 /*
82 * Create the memory address space map. Marked frames and frame
83 * regions cannot be used for allocation.
84 */
85 frame_region_not_free(config.base, config.base + config.kernel_size);
86 }
87}
88
89/*
90 * Allocate a frame.
91 */
92__address frame_alloc(int flags)
93{
94 int i;
95 pri_t pri;
96
97loop:
98 pri = cpu_priority_high();
99 spinlock_lock(&framelock);
100 if (frames_free) {
101 for (i=0; i < frames; i++) {
102 int m, n;
103
104 m = i / 8;
105 n = i % 8;
106
107 if ((frame_bitmap[m] & (1<<n)) == 0) {
108 frame_bitmap[m] |= (1<<n);
109 frames_free--;
110 spinlock_unlock(&framelock);
111 cpu_priority_restore(pri);
112 if (flags & FRAME_KA) return PA2KA(i*FRAME_SIZE);
113 return i*FRAME_SIZE;
114 }
115 }
116 panic("frames_free inconsistent (%d)\n", frames_free);
117 }
118 spinlock_unlock(&framelock);
119 cpu_priority_restore(pri);
120
121 if (flags & FRAME_PANIC)
122 panic("unable to allocate frame\n");
123
124 /* TODO: implement sleeping logic here */
125 panic("sleep not supported\n");
126
127 goto loop;
128}
129
130/*
131 * Free a frame.
132 */
133void frame_free(__address addr)
134{
135 pri_t pri;
136 __u32 frame;
137
138 pri = cpu_priority_high();
139 spinlock_lock(&framelock);
140
141 frame = IS_KA(addr) ? KA2PA(addr) : addr;
142 frame /= FRAME_SIZE;
143 if (frame < frames) {
144 int m, n;
145
146 m = frame / 8;
147 n = frame % 8;
148
149 if (frame_bitmap[m] & (1<<n)) {
150 frame_bitmap[m] &= ~(1<<n);
151 frames_free++;
152 }
153 else panic("frame already free\n");
154 }
155 else panic("frame number too big\n");
156
157 spinlock_unlock(&framelock);
158 cpu_priority_restore(pri);
159}
160
161/*
162 * Don't use this function for normal allocation. Use frame_alloc() instead.
163 * Use this function to declare that some special frame is not free.
164 */
165void frame_not_free(__address addr)
166{
167 pri_t pri;
168 __u32 frame;
169
170 pri = cpu_priority_high();
171 spinlock_lock(&framelock);
172 frame = IS_KA(addr) ? KA2PA(addr) : addr;
173 frame /= FRAME_SIZE;
174 if (frame < frames) {
175 int m, n;
176
177 m = frame / 8;
178 n = frame % 8;
179
180 if ((frame_bitmap[m] & (1<<n)) == 0) {
181 frame_bitmap[m] |= (1<<n);
182 frames_free--;
183 }
184 }
185 spinlock_unlock(&framelock);
186 cpu_priority_restore(pri);
187}
188
189void frame_region_not_free(__address start, __address stop)
190{
191 __u32 i;
192
193 start /= FRAME_SIZE;
194 stop /= FRAME_SIZE;
195 for (i = start; i <= stop; i++)
196 frame_not_free(i * FRAME_SIZE);
197}
Note: See TracBrowser for help on using the repository browser.