Advertisement
Guest User

Untitled

a guest
Mar 26th, 2017
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 12.71 KB | None | 0 0
  1. // addrspace.cc
  2. // Routines to manage address spaces (executing user programs).
  3. //
  4. // In order to run a user program, you must:
  5. //
  6. // 1. link with the -N -T 0 option
  7. // 2. run coff2noff to convert the object file to Nachos format
  8. // (Nachos object code format is essentially just a simpler
  9. // version of the UNIX executable object code format)
  10. // 3. load the NOFF file into the Nachos file system
  11. // (if you haven't implemented the file system yet, you
  12. // don't need to do this last step)
  13. //
  14. // Copyright (c) 1992-1993 The Regents of the University of California.
  15. // All rights reserved. See copyright.h for copyright notice and limitation
  16. // of liability and disclaimer of warranty provisions.
  17.  
  18. #include "copyright.h"
  19. #include "system.h"
  20. #include "addrspace.h"
  21. #include "noff.h"
  22.  
  23. //Begin code changes by Hayden Presley
  24. struct IPTEntry{
  25. Thread* threadptr;
  26. int vPage;
  27. };
  28. IPTEntry* IPT = new IPTEntry[NumPhysPages];
  29. //End code changes by Hayden Presley
  30.  
  31. //----------------------------------------------------------------------
  32. // SwapHeader
  33. // Do little endian to big endian conversion on the bytes in the
  34. // object file header, in case the file was generated on a little
  35. // endian machine, and we're now running on a big endian machine.
  36. //----------------------------------------------------------------------
  37.  
  38. static void
  39. SwapHeader (NoffHeader *noffH)
  40. {
  41. noffH->noffMagic = WordToHost(noffH->noffMagic);
  42. noffH->code.size = WordToHost(noffH->code.size);
  43. noffH->code.virtualAddr = WordToHost(noffH->code.virtualAddr);
  44. noffH->code.inFileAddr = WordToHost(noffH->code.inFileAddr);
  45. noffH->initData.size = WordToHost(noffH->initData.size);
  46. noffH->initData.virtualAddr = WordToHost(noffH->initData.virtualAddr);
  47. noffH->initData.inFileAddr = WordToHost(noffH->initData.inFileAddr);
  48. noffH->uninitData.size = WordToHost(noffH->uninitData.size);
  49. noffH->uninitData.virtualAddr = WordToHost(noffH->uninitData.virtualAddr);
  50. noffH->uninitData.inFileAddr = WordToHost(noffH->uninitData.inFileAddr);
  51. }
  52.  
  53. //----------------------------------------------------------------------
  54. // AddrSpace::AddrSpace
  55. // Create an address space to run a user program.
  56. // Load the program from a file "executable", and set everything
  57. // up so that we can start executing user instructions.
  58. //
  59. // Assumes that the object code file is in NOFF format.
  60. //
  61. // First, set up the translation from program memory to physical
  62. // memory. For now, this is really simple (1:1), since we are
  63. // only uniprogramming, and we have a single unsegmented page table
  64. //
  65. // "executable" is the file containing the object code to load into memory
  66. //----------------------------------------------------------------------
  67.  
  68. AddrSpace::AddrSpace(OpenFile *executable)
  69. {
  70. unsigned int i, counter;
  71. space = false;
  72.  
  73.  
  74.  
  75. executable->ReadAt((char *)&noffH, sizeof(noffH), 0);
  76. if ((noffH.noffMagic != NOFFMAGIC) &&
  77. (WordToHost(noffH.noffMagic) == NOFFMAGIC))
  78. SwapHeader(&noffH);
  79. ASSERT(noffH.noffMagic == NOFFMAGIC);
  80.  
  81. // how big is address space?
  82. size = noffH.code.size + noffH.initData.size + noffH.uninitData.size
  83. + UserStackSize; // we need to increase the size
  84. // to leave room for the stack
  85. numPages = divRoundUp(size, PageSize);
  86. //printf("%d is numPages\n", numPages);
  87. size = numPages * PageSize;
  88.  
  89. //Change this to reference the bitmap for free pages
  90. //instead of total amount of pages
  91. //This requires a global bitmap instance
  92.  
  93. counter = 0;
  94. for(i = 0; i < NumPhysPages && counter < numPages; i++)
  95. {
  96. if(!memMap->Test(i))
  97. {
  98. if(counter == 0)
  99. startPage = i; //startPage is a class data member
  100. //Should it be public or private? (Currently private)
  101. counter++;
  102. }
  103. else
  104. counter = 0;
  105. }
  106.  
  107. DEBUG('a', "%i contiguous blocks found for %i pages\n", counter, numPages);
  108.  
  109. //If no memory available, terminate
  110. if(counter < numPages)
  111. {
  112. //printf("Not enough contiguous memory for new process; terminating!.\n");
  113. currentThread->killNewChild = true;
  114. //return;
  115. }
  116.  
  117. //If we get past the if statement, then there was sufficient space
  118. space = true;
  119.  
  120. //This safeguards against the loop terminating due to reaching
  121. //the end of the bitmap but no contiguous space being available
  122.  
  123. DEBUG('a', "Initializing address space, numPages=%d, size=%d\n",
  124. numPages, size);
  125. // first, set up the translation
  126. //BEGIN CODE CHANGES BY THOMAS WRAY AND HAYDEN PRESLEY
  127. OPTSize = (numPages / 4) + (numPages%4);
  128. outerPageTable = new TranslationEntry*[4];
  129. for (i = 0; i < 4; i++){
  130. outerPageTable[i] = new TranslationEntry[OPTSize];
  131. for(int j = 0; j < OPTSize; j++){
  132. outerPageTable[i][j].valid = FALSE;
  133. outerPageTable[i][j].virtualPage = j;
  134. outerPageTable[i][j].use = FALSE;
  135. outerPageTable[i][j].dirty = FALSE;
  136. outerPageTable[i][j].readOnly = FALSE;
  137. }
  138. }
  139. //END CODE CHANGES BY THOMAS WRAY AND HAYDEN PRESLEY
  140.  
  141.  
  142. pageTable = new TranslationEntry[4];
  143. for (i = 0; i < numPages; i++) {
  144. pageTable[i].virtualPage = i; // for now, virtual page # = phys page #
  145. pageTable[i].physicalPage = i;
  146. //pageTable[i].physicalPage = i + startPage; NOW DONE IN PAGEFAULTEXCEPTION
  147.  
  148. //Code Change by Thomas Wray
  149. pageTable[i].valid = FALSE; //set each valid bit to false so that a PageFaultException is thrown
  150.  
  151. pageTable[i].use = FALSE;
  152. pageTable[i].dirty = FALSE;
  153. pageTable[i].readOnly = FALSE; // if the code segment was entirely on
  154. // a separate page, we could set its
  155. // pages to be read-only
  156.  
  157. //Take the global bitmap and set the relevant chunks
  158. //to indicate that the memory is in use
  159. //memMap->Mark(i + startPage);
  160. }
  161.  
  162. //memMap->Print(); // Useful!
  163.  
  164. // zero out the entire address space, to zero the unitialized data segment
  165. // and the stack segment
  166. // bzero(machine->mainMemory, size); rm for Solaris
  167. //Edited version adds startPage * PageSize to the address. Hopefully this is proper.
  168. //Either way, it appears to zero out only however much memory is needed,
  169. //so zeroing out all memory doesn't seem to be an issue. - Devin
  170.  
  171. pAddr = startPage * PageSize;
  172.  
  173. //memset(machine->mainMemory + pAddr, 0, size);
  174.  
  175. // then, copy in the code and data segments into memory
  176. //Change these too since they assume virtual page = physical page
  177. //Fix this by adding startPage times page size as an offset
  178. //exec = executable;
  179.  
  180. //Code changes by Thomas Wray and Paul Smith
  181. fileName = new char[10];
  182. sprintf(fileName, "%d.swap", threadID); //come back to this later for thread 0
  183. printf("%s is being made\n", fileName);
  184. fileSystem->Create(fileName, size);
  185. OpenFile* swapFile = fileSystem->Open(fileName);
  186. char* buffer = new char[size];
  187. executable->Read(buffer, size);
  188. swapFile->Write(buffer, size);
  189. delete swapFile;
  190. delete buffer;
  191.  
  192. //Code changes by Thomas wray and Paul smith
  193. }
  194.  
  195. //----------------------------------------------------------------------
  196. // AddrSpace::~AddrSpace
  197. // Dealloate an address space. Nothing for now!
  198. //----------------------------------------------------------------------
  199.  
  200. //Because the initialization already zeroes out the memory to be used,
  201. //is it even necessary to clear out any garbage data during deallocation?
  202.  
  203. AddrSpace::~AddrSpace()
  204. {
  205. // Only clear the memory if it was set to begin with
  206. // which in turn only happens after space is set to true
  207. if(space)
  208. {
  209. /*for(int i = startPage; i < numPages + startPage; i++) // We need an offset of startPage + numPages for clearing.
  210. memMap->Clear(i);*/
  211. for(int i = 0; i < 4; i++){
  212. for(int j = 0; j < OPTSize; j++)
  213. if(outerPageTable[i][j].valid == TRUE)
  214. (memMap->Clear(outerPageTable[i][j].physicalPage));
  215. }
  216.  
  217. for(int i = 0; i < 4; i++){
  218. delete outerPageTable[i];
  219. }
  220. printf("GOT HERE!\n");
  221. delete outerPageTable;
  222. printf("GOT HERE!\n");
  223. //delete pageTable;
  224. memMap->Print();
  225. }
  226.  
  227. //printf("Filename is %s\n\n\n", fileName);
  228. fileSystem->Remove(fileName);
  229. delete fileName;
  230. }
  231.  
  232. //----------------------------------------------------------------------
  233. // AddrSpace::InitRegisters
  234. // Set the initial values for the user-level register set.
  235. //
  236. // We write these directly into the "machine" registers, so
  237. // that we can immediately jump to user code. Note that these
  238. // will be saved/restored into the currentThread->userRegisters
  239. // when this thread is context switched out.
  240. //----------------------------------------------------------------------
  241.  
  242. void
  243. AddrSpace::InitRegisters()
  244. {
  245. int i;
  246.  
  247. for (i = 0; i < NumTotalRegs; i++)
  248. machine->WriteRegister(i, 0);
  249.  
  250. // Initial program counter -- must be location of "Start"
  251. machine->WriteRegister(PCReg, 0);
  252.  
  253. // Need to also tell MIPS where next instruction is, because
  254. // of branch delay possibility
  255. machine->WriteRegister(NextPCReg, 4);
  256.  
  257. // Set the stack register to the end of the address space, where we
  258. // allocated the stack; but subtract off a bit, to make sure we don't
  259. // accidentally reference off the end!
  260. machine->WriteRegister(StackReg, numPages * PageSize - 16);
  261. DEBUG('a', "Initializing stack register to %d\n", numPages * PageSize - 16);
  262. }
  263.  
  264. //----------------------------------------------------------------------
  265. // AddrSpace::SaveState
  266. // On a context switch, save any machine state, specific
  267. // to this address space, that needs saving.
  268. //
  269. // For now, nothing!
  270. //----------------------------------------------------------------------
  271.  
  272. void AddrSpace::SaveState()
  273. {
  274. printf("STATE SAVED\n");
  275. }
  276.  
  277. //----------------------------------------------------------------------
  278. // AddrSpace::RestoreState
  279. // On a context switch, restore the machine state so that
  280. // this address space can run.
  281. //
  282. // For now, tell the machine where to find the page table.
  283. //----------------------------------------------------------------------
  284.  
  285. void AddrSpace::RestoreState()
  286. {
  287. machine->pageTable = pageTable;
  288. machine->pageTableSize = numPages; //size of inner page table for 2 level
  289. }
  290.  
  291.  
  292.  
  293.  
  294.  
  295. //begin code changes by Thomas Wray and Hayden Presley
  296. void AddrSpace::InitPages(int VAddr, int PAddr, bool replaced){
  297.  
  298. OpenFile * swapFile = fileSystem->Open(fileName);
  299. if (swapFile == NULL){
  300. printf("///////////////////////////////////////////////////////////NULL\n");
  301. }
  302. printf("%s is trying to be accessed\n", fileName);
  303. if(!swapFile){
  304. delete swapFile;
  305. return;
  306. }
  307. int outerIndex = pageTable[VAddr/OPTSize].physicalPage;
  308. outerPageTable[outerIndex][VAddr%OPTSize].valid = TRUE;
  309. //pageTable[VAddr].valid = TRUE;
  310.  
  311. /*for (int i = 0; i < machine->pageTableSize; i++){
  312. if (machine->pageTable[i].valid == true){
  313. printf("1");
  314. }
  315. else printf("0");
  316. }
  317. printf("\n");*/
  318.  
  319. if (replaced){
  320. Thread* threadToSwap = IPT[PAddr].threadptr;
  321. int replacing = IPT[PAddr].vPage;
  322. printf("Replacing is %d\n", replacing);
  323. int outerIndex_replacing = threadToSwap->space->pageTable[replacing/threadToSwap->space->OPTSize].physicalPage;
  324. threadToSwap->space->outerPageTable[outerIndex_replacing][replacing%threadToSwap->space->OPTSize].valid = FALSE;
  325. printf("OPENING SWAPFILE: %s\n", threadToSwap->space->fileName);
  326. OpenFile * swapping = fileSystem->Open(threadToSwap->space->fileName);
  327. swapping->WriteAt(&(machine->mainMemory[PAddr * PageSize]), PageSize, threadToSwap->space->noffH.code.inFileAddr + replacing * PageSize);
  328. printf("Location is %d\n",threadToSwap->space->noffH.code.inFileAddr + replacing * PageSize);
  329. delete swapping;
  330. //Begin code changes by Hunter Kliebert
  331. if (pageFlag == TRUE)
  332. printf("\nPAGE FAULT: PROCESS %i REQUESTED VIRTUAL PAGE %i\nSWAP OUT PHYSICAL PAGE %i FROM PROCESS %i\nVIRTUAL PAGE %i REMOVED\n\n",
  333. currentThread->getID(), VAddr, PAddr, threadToSwap->getID(), replacing);
  334. //End code changes by Hunter Kliebert
  335. }
  336.  
  337. //Begin code changes by Hunter Kliebert
  338. else
  339. if (pageFlag == TRUE)
  340. printf("\nPAGE FAULT: PROCESS %i REQUESTED VIRTUAL PAGE %i\nASSIGNED PHYSICAL PAGE %i\n\n", currentThread->getID(), VAddr, PAddr);
  341. //End code changes by Hunter Kliebert
  342.  
  343. memset(machine->mainMemory + PAddr * PageSize, 0, PageSize);
  344.  
  345.  
  346. outerPageTable[outerIndex][VAddr%OPTSize].physicalPage = PAddr;
  347. //pageTable[VAddr].physicalPage = PAddr;
  348. IPT[PAddr].threadptr = currentThread;
  349. IPT[PAddr].vPage = VAddr;
  350. printf("IPT[%d].vPage is %d\n", PAddr, IPT[PAddr].vPage);
  351.  
  352. if (noffH.code.size > 0 && VAddr * PageSize >= 0
  353. && noffH.code.size + noffH.initData.size > VAddr * PageSize) {
  354. swapFile->ReadAt(&(machine->mainMemory[PAddr * PageSize]),
  355. PageSize, noffH.code.inFileAddr + VAddr * PageSize);
  356. }
  357.  
  358. //printf("Init pages: address is %d and %d\n", VAddr, PAddr);
  359.  
  360. delete swapFile;
  361. }
  362. //end code changes by Thomas Wray and Hayden Presley
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement