/* * Copyright (C) 2001-2004 Jakub Jermar * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * - Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * - Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * - The name of the author may not be used to endorse or promote products * derived from this software without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include #include #include #include #include #include #include #include #include #include #include __u32 frames; __u32 frames_free; __u8 *frame_bitmap; __u32 frame_bitmap_octets; /* * This is for kernel address space frames (allocated with FRAME_KA). * Their addresses may not interfere with user address space. */ __u8 *frame_kernel_bitmap; __u32 kernel_frames; __u32 kernel_frames_free; static spinlock_t framelock; void frame_init(void) { if (config.cpu_active == 1) { /* * The bootstrap processor will allocate all necessary memory for frame allocation. */ frames = config.memory_size / FRAME_SIZE; frame_bitmap_octets = frames / 8 + (frames % 8 > 0); frame_bitmap = (__u8 *) malloc(frame_bitmap_octets); if (!frame_bitmap) panic(PANIC "malloc/frame_bitmap\n"); /* * Mark all frames free. */ memsetb((__address) frame_bitmap, frame_bitmap_octets, 0); frames_free = frames; /* * Will be properly set up by architecture dependent frame init. */ frame_kernel_bitmap = NULL; kernel_frames_free = 0; kernel_frames = 0; } /* * No frame allocations/reservations prior this point. */ frame_arch_init(); if (config.cpu_active == 1) { /* * Create the memory address space map. Marked frames and frame * regions cannot be used for allocation. */ frame_region_not_free(config.base, config.base + config.kernel_size); } } /* * Allocate a frame. */ __address frame_alloc(int flags) { int i; pri_t pri; __u8 **frame_bitmap_ptr = &frame_bitmap; __u32 *frames_ptr = &frames, *frames_free_ptr = &frames_free; if (flags & FRAME_KA) { frame_bitmap_ptr = &frame_kernel_bitmap; frames_ptr = &kernel_frames; frames_free_ptr = &kernel_frames_free; } loop: pri = cpu_priority_high(); spinlock_lock(&framelock); if (*frames_free_ptr) { for (i=0; i < *frames_ptr; i++) { int m, n; m = i / 8; n = i % 8; if (((*frame_bitmap_ptr)[m] & (1<