os161-1.99
 All Data Structures
ram.c
00001 /*
00002  * Copyright (c) 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009
00003  *      The President and Fellows of Harvard College.
00004  *
00005  * Redistribution and use in source and binary forms, with or without
00006  * modification, are permitted provided that the following conditions
00007  * are met:
00008  * 1. Redistributions of source code must retain the above copyright
00009  *    notice, this list of conditions and the following disclaimer.
00010  * 2. Redistributions in binary form must reproduce the above copyright
00011  *    notice, this list of conditions and the following disclaimer in the
00012  *    documentation and/or other materials provided with the distribution.
00013  * 3. Neither the name of the University nor the names of its contributors
00014  *    may be used to endorse or promote products derived from this software
00015  *    without specific prior written permission.
00016  *
00017  * THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY AND CONTRIBUTORS ``AS IS'' AND
00018  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00019  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
00020  * ARE DISCLAIMED.  IN NO EVENT SHALL THE UNIVERSITY OR CONTRIBUTORS BE LIABLE
00021  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
00022  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
00023  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00024  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00025  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
00026  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
00027  * SUCH DAMAGE.
00028  */
00029 
00030 #include <types.h>
00031 #include <lib.h>
00032 #include <vm.h>
00033 #include <mainbus.h>
00034 
00035 
00036 vaddr_t firstfree;   /* first free virtual address; set by start.S */
00037 
00038 static paddr_t firstpaddr;  /* address of first free physical page */
00039 static paddr_t lastpaddr;   /* one past end of last free physical page */
00040 
00041 /*
00042  * Called very early in system boot to figure out how much physical
00043  * RAM is available.
00044  */
00045 void
00046 ram_bootstrap(void)
00047 {
00048         size_t ramsize;
00049         
00050         /* Get size of RAM. */
00051         ramsize = mainbus_ramsize();
00052 
00053         /*
00054          * This is the same as the last physical address, as long as
00055          * we have less than 508 megabytes of memory. If we had more,
00056          * various annoying properties of the MIPS architecture would
00057          * force the RAM to be discontiguous. This is not a case we 
00058          * are going to worry about.
00059          */
00060         if (ramsize > 508*1024*1024) {
00061                 ramsize = 508*1024*1024;
00062         }
00063 
00064         lastpaddr = ramsize;
00065 
00066         /* 
00067          * Get first free virtual address from where start.S saved it.
00068          * Convert to physical address.
00069          */
00070         firstpaddr = firstfree - MIPS_KSEG0;
00071 
00072         kprintf("%uk physical memory available\n", 
00073                 (lastpaddr-firstpaddr)/1024);
00074 }
00075 
00076 /*
00077  * This function is for allocating physical memory prior to VM
00078  * initialization.
00079  *
00080  * The pages it hands back will not be reported to the VM system when
00081  * the VM system calls ram_getsize(). If it's desired to free up these
00082  * pages later on after bootup is complete, some mechanism for adding
00083  * them to the VM system's page management must be implemented.
00084  * Alternatively, one can do enough VM initialization early so that
00085  * this function is never needed.
00086  *
00087  * Note: while the error return value of 0 is a legal physical address,
00088  * it's not a legal *allocatable* physical address, because it's the
00089  * page with the exception handlers on it.
00090  *
00091  * This function should not be called once the VM system is initialized, 
00092  * so it is not synchronized.
00093  */
00094 paddr_t
00095 ram_stealmem(unsigned long npages)
00096 {
00097         size_t size;
00098         paddr_t paddr;
00099 
00100         size = npages * PAGE_SIZE;
00101 
00102         if (firstpaddr + size > lastpaddr) {
00103                 return 0;
00104         }
00105 
00106         paddr = firstpaddr;
00107         firstpaddr += size;
00108 
00109         return paddr;
00110 }
00111 
00112 /*
00113  * This function is intended to be called by the VM system when it
00114  * initializes in order to find out what memory it has available to
00115  * manage.
00116  *
00117  * This function should not be called once the VM system is initialized, 
00118  * so it is not synchronized.
00119  */
00120 void
00121 ram_getsize(paddr_t *lo, paddr_t *hi)
00122 {
00123         *lo = firstpaddr;
00124         *hi = lastpaddr;
00125         firstpaddr = lastpaddr = 0;
00126 }
 All Data Structures