/* MMDirectMapping.c, Copyright (c) by George Fankhauser, Swiss Federal Institute of Technology, Computer Engineering and Networks Laboratory. TOPSY -- A Teachable Operating System. Implementation of a tiny and simple micro kernel for teaching purposes. For further information, please visit http://www.tik.ee.ethz.ch/~topsy This software is provided under the terms of the GNU General Public Licence. A full copy of the GNU GPL is provided in the file COPYING found in the development root of Topsy. */ /* File: $Source: /usr/drwho/vault/cvs/topsy/Topsy/Memory/mips/MMDirectMapping.c,v $ Author(s): George Fankhauser Affiliation: ETH Zuerich, TIK Version: $Revision: 1.14 $ Creation Date: Last Date of Change: $Date: 2000/03/31 17:50:32 $ by: $Author: gfa $ $Log: MMDirectMapping.c,v $ Revision 1.14 2000/03/31 17:50:32 gfa Merged with /Net from several term projects Revision 1.13 1999/12/13 21:48:31 ruf GNU General Public Licence Update Revision 1.12 1999/10/31 14:42:47 jeker first fixes for SimOS Revision 1.11 1999/10/27 14:20:08 jeker fixes in mips asm code Revision 1.10 1999/10/27 11:04:59 jeker fixes R4k R3k port Revision 1.9 1999/10/27 04:51:07 jeker *** empty log message *** Revision 1.8 1999/10/21 20:22:28 jeker first commit for the R4k support Revision 1.7 1999/04/08 15:29:10 jeker Forgot to define bootStackBottom Revision 1.6 1998/04/11 20:22:05 gfa uses longCopy Revision 1.5 1997/04/23 11:52:13 gfa beautyfied * Revision 1.4 1997/04/13 16:22:33 gfa * added user-in-kernel-at address * * Revision 1.3 1997/04/13 15:32:17 gfa * fixed mmAddressSpaceRange * * Revision 1.2 1997/04/06 18:48:27 gfa * moved to $(ARCH) directory * * Revision 1.1 1997/04/06 15:45:24 gfa * Initial revision * * Revision 1.9 1997/03/27 13:54:20 conrad * failed for vmProtect * * Revision 1.8 1997/03/16 22:15:48 gfa * first implementation of the low level functions * * Revision 1.7 1997/03/14 00:00:22 gfa * moved phy/log page macros to MemoryLayout.h * * Revision 1.6 1997/03/11 08:15:27 gfa * tlb setup tested and working * * Revision 1.5 1997/03/09 20:47:25 gfa * wrote init and address space functions * * Revision 1.4 1997/02/13 16:25:21 zitzler * cosmetics (now very pretty) * * Revision 1.3 1997/02/13 16:23:07 zitzler * cosmetics * * Revision 1.2 1997/02/13 15:43:44 conrad * First compilation/linking of complete environment (all modules) * * Revision 1.1 1997/02/12 16:18:30 zitzler * Initial revision * */ #include "MMMapping.h" #include "Threads.h" #include "Support.h" #include "SupportMIPS.h" #include "tlb.h" #include "cpu.h" unsigned int bootStackBottom; Error mmInitMemoryMapping(Address codeAddr, unsigned long int codeSize, Address dataAddr, unsigned long int dataSize, Address userLoadedInKernelAt) { /* to simulate a directmapped memory on a paged machine we fill * the TLB to provide the user with 64*4k memory from 4k to (256+4)k - 1. * Pages from [PHYSMEM-256k, PHYSMEM] are mapped to [4, 260k]. * Page Table Entries are set to valid and global. * (setting up a *real* virtual memory system is lot harder) */ Register lo, hi; unsigned int i; unsigned long int lo0, lo1; /* start at 0x00001000 to leave page zero invalid (nil pointer catcher) */ hi = KUSEG_BASE+PAGESIZE; if ( getPRID() == PRID_R3k ) { /* R3k TLB */ ioConsolePutString("Topsy is running on a mips R3k machine\n"); lo = ((PHYSMEM-USERMEM+PHYS_BASE) & TLB_LO_PFN_MASK_R3k) | TLB_VALID_R3k | TLB_GLOBAL_R3k | TLB_DIRTY_R3k; for (i = 0; i < TLB_SIZE_R3k; i++) { setR3kTLBEntry(lo, hi, i); hi += PAGESIZE; lo += PAGESIZE; /* yes, physical pages */ } } else { /* R4k TLB */ ioConsolePutString("Topsy is running on a mips R4k machine\n"); lo = (((PHYSMEM-USERMEM+PHYS_BASE)>>TLB_LO_PFN_SHIFT_R4k) & TLB_LO_PFN_MASK_R4k) | TLB_CACHED_R4k | TLB_DIRTY_R4k | TLB_VALID_R4k | TLB_GLOBAL_R4k; lo0 = 0 | TLB_GLOBAL_R4k; lo1 = lo; for (i = 0; i < TLB_USER_SIZE_R4k; i++) { setR4kTLBEntry(lo0, lo1, hi, i); hi += (PAGESIZE<<1); lo += (PAGESIZE>>6); /* yes, physical pages */ lo0 = lo; lo += (PAGESIZE>>6); lo1 = lo; } lo1 = 0 | TLB_GLOBAL_R4k; setR4kTLBEntry(lo0, lo1, hi, i); hi += (PAGESIZE<<2); lo0 = 0 | TLB_GLOBAL_R4k; for (i = (TLB_USER_SIZE_R4k+1); i < TLB_SIZE_R4k; i++) { setR4kTLBEntry(lo0, lo0, hi, i); } /* set number of wired TLB entries */ setR4kTLBWired(TLB_SAFE_SIZE_R4k); } /* once the mapping is done, copy user code and data */ byteCopy(codeAddr, userLoadedInKernelAt, codeSize); byteCopy(dataAddr, (Address)((unsigned long)userLoadedInKernelAt + (unsigned long)dataAddr - (unsigned long)codeAddr), dataSize); return MM_INITMEMORYMAPPINGOK; } Error mmMapPages(Page startPage, Page nOfPages, PageStatus pstat) { return MM_MAPPAGESOK; } Error mmUnmapPages(Page startPage, Page nOfPages) { return MM_UNMAPPAGESOK; } Error mmMovePage(Page from, Page to) { /* direct mapped memory systems can only copy the page */ byteCopy((Address)(to*LOGICALPAGESIZE), (Address)(from*LOGICALPAGESIZE), LOGICALPAGESIZE); zeroOut((Address)(from*LOGICALPAGESIZE), LOGICALPAGESIZE); return MM_MOVEPAGEOK; } Error mmProtectPage(Page page, ProtectionMode pmode) { /* direct mapped memory does nothing */ return MM_PROTECTPAGEFAILED; } Error mmAddressSpaceRange(AddressSpace space, Address* addressPtr, unsigned long int* sizePtr) { if (space == KERNEL) { *addressPtr = (Address)K0SEG_BASE; *sizePtr = (PHYSMEM-USERMEM); /* 768kB */ } else if (space == USER) { *addressPtr = (Address)KUSEG_BASE + PAGESIZE; /* zero page invalid */ *sizePtr = USERMEM; /* 256kB */ } else return MM_ADDRESSSPACERANGEFAILED; return MM_ADDRESSSPACERANGEOK; }