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 }