⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pagetable.cc

📁 ml-rsim 多处理器模拟器 支持类bsd操作系统
💻 CC
字号:
/* * Copyright (c) 2002 The Board of Trustees of the University of Illinois and *                    William Marsh Rice University * Copyright (c) 2002 The University of Utah * Copyright (c) 2002 The University of Notre Dame du Lac * * All rights reserved. * * Based on RSIM 1.0, developed by: *   Professor Sarita Adve's RSIM research group *   University of Illinois at Urbana-Champaign and     William Marsh Rice University *   http://www.cs.uiuc.edu/rsim and http://www.ece.rice.edu/~rsim/dist.html * ML-RSIM/URSIM extensions by: *   The Impulse Research Group, University of Utah *   http://www.cs.utah.edu/impulse *   Lambert Schaelicke, University of Utah and University of Notre Dame du Lac *   http://www.cse.nd.edu/~lambert *   Mike Parker, University of Utah *   http://www.cs.utah.edu/~map * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal with the Software without restriction, including without * limitation the rights to use, copy, modify, merge, publish, distribute, * sublicense, and/or sell copies of the Software, and to permit persons to * whom the Software is furnished to do so, subject to the following * conditions: * * 1. Redistributions of source code must retain the above copyright notice, *    this list of conditions and the following disclaimers.  * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimers in the *    documentation and/or other materials provided with the distribution. * 3. Neither the names of Professor Sarita Adve's RSIM research group, *    the University of Illinois at Urbana-Champaign, William Marsh Rice *    University, nor the names of its contributors may be used to endorse *    or promote products derived from this Software without specific prior *    written permission.  * 4. Neither the names of the ML-RSIM project, the URSIM project, the *    Impulse research group, the University of Utah, the University of *    Notre Dame du Lac, nor the names of its contributors may be used to *    endorse or promote products derived from this software without specific *    prior written permission.  * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR * OTHER DEALINGS WITH THE SOFTWARE.  *//***************************************************************************//* Per-node physical page table                                            *//* Maps physical (simulated) addresses to memory on the host machine.      *//***************************************************************************/#include <string.h>#include <malloc.h>extern "C"{#include "sim_main/simsys.h"#include "sim_main/util.h"}#include "Processor/simio.h"#include "Processor/procstate.h"#include "Processor/pagetable.h"#include "Processor/endian_swap.h"page_table **PageTables;/*=========================================================================*//* Constructor: initialize array of anchor elements.                       *//*=========================================================================*/page_table::page_table(){  for (int n = 0; n < PAGETABLE_SIZE; n++)    {      data[n].phys_addr = 0;      data[n].sim_addr  = NULL;      data[n].next      = NULL;    }}/*=========================================================================*//* Destructor: free all elements.                                          *//*=========================================================================*/page_table::~page_table(){  struct page_table_entry *pte, *npte;  for (int n = 0; n < PAGETABLE_SIZE; n++)    {      pte = data[n].next;      while (pte)	{	  npte = pte->next;	  delete pte;	  pte = npte;	}    }}/*=========================================================================*//* Insert: insert an entry into the hash table. Hash physical page number  *//* to find anchor element, scan linked list of elements until either an    *//* unused element (sim_addr == NULL) or the end of the list is found (in   *//* which case a new element is allocated and appended) and fill in the     *//* found empty element.                                                    *//*=========================================================================*/void page_table::insert(unsigned phys_addr, char *sim_addr){  unsigned index;  page_table_entry *pte;  index = (phys_addr / PAGE_SIZE) & PAGETABLE_HASH;  pte = &data[index];  while (pte->sim_addr != NULL)    {      if (pte->next == NULL)	pte->next = new page_table_entry();      pte = pte->next;    }  pte->phys_addr = phys_addr / PAGE_SIZE;  pte->sim_addr  = sim_addr;}/*=========================================================================*//* Remove: hash physical page number to find anchor element. If anchor is  *//* to be removed, copy next element into anchor and remove next element    *//* from list, or just clear anchor element if no next element is found.    *//* If anchor is not the desired element, scan list until element is found, *//* keep track of previous element and simply remove desired element.       *//*=========================================================================*/void page_table::remove(unsigned phys_addr){  unsigned          index;  page_table_entry *pte, *opte;  index = (phys_addr / PAGE_SIZE) & PAGETABLE_HASH;  pte = &data[index];  if (pte->phys_addr == phys_addr / PAGE_SIZE)  // anchor needs to be removed    {      if (pte->next != NULL)                      // has next element	{	  pte->phys_addr = pte->next->phys_addr;  // copy element	  pte->sim_addr  = pte->next->sim_addr;	  opte = pte->next;                       // save pointer to it	  pte->next      = pte->next->next;       // remove from linked list	  delete opte;                            // delete it	}      else                                        // anchor has no next elem.	{	  pte->phys_addr = 0;                     // clear it	  pte->sim_addr  = NULL;	  pte->next      = NULL;	}      return;    }    opte = pte;                                     // anchor is not desired elm.  pte = pte->next;  while (pte)                                     // look for match    {      if (pte->phys_addr == phys_addr / PAGE_SIZE)	{	  opte->next = pte->next;                 // remove element from list	  delete pte;                             // delete it	  return;	}      opte = pte;      pte = pte->next;    }}/*=========================================================================*//* Initialize per-node page table                                          *//*=========================================================================*/extern "C" void PageTable_init(void){  int i;  PageTables = (page_table**)malloc(ARCH_numnodes *				    sizeof(page_table*));   if (!PageTables)    YS__errmsg(0, "Malloc failed at %s:%i", __FILE__, __LINE__);     for (i = 0; i < ARCH_numnodes; i++)    PageTables[i] = new page_table();}/*=========================================================================*//* Insert a mapping for 1 page (4K) into the page table for this node, in  *//* addition allocate physical (host) memory.                               *//*=========================================================================*/extern "C" void PageTable_insert_alloc(int node_id, unsigned addr){  char *sim_mem = 0;  sim_mem = PageTables[node_id]->lookup(addr);  if (!sim_mem)    {      sim_mem = (char*)malloc(PAGE_SIZE);      PageTables[node_id]->insert(addr, sim_mem);    }}extern "C" void PageTable_insert(int node_id, unsigned addr, char *sim_mem){  char *sm;  sm = PageTables[node_id]->lookup(addr);  if (!sm)    PageTables[node_id]->insert(addr, sim_mem);}/*=========================================================================*//* Lookup address in page table                                            *//*=========================================================================*/extern "C" char *PageTable_lookup(int node_id, unsigned addr){  return PageTables[node_id]->lookup(addr);}  /*=========================================================================*//* Remove address from page table, with or without deallocating the        *//* simulator page.                                                         *//*=========================================================================*/extern "C" void PageTable_remove(int node_id, unsigned addr){  PageTables[node_id]->remove(addr);}extern "C" void PageTable_remove_free(int node_id, unsigned addr){  char *sim_mem = PageTables[node_id]->lookup(addr);  if (sim_mem)    free(sim_mem);  PageTables[node_id]->remove(addr);}/*=========================================================================*//* Read integer value                                                      *//*=========================================================================*/extern "C" unsigned int read_int(int node_id, unsigned addr){  char *pa;  unsigned int r;  pa = PageTables[node_id]->lookup(addr);  if (!pa)    YS__errmsg(node_id, "Attempt to access non-existing memory %x\n", addr);  r = endian_swap(*(unsigned int*)pa);  return(r);}/*=========================================================================*//* Read character value                                                    *//*=========================================================================*/extern "C" unsigned char read_char(int node_id, unsigned addr){  char *pa;  unsigned char r;    pa = PageTables[node_id]->lookup(addr);  if (!pa)    YS__errmsg(node_id, "Attempt to access non-existing memory %x\n", addr);  r = *(unsigned char*)pa;  return(r);}/*=========================================================================*//* Read float value                                                        *//*=========================================================================*/extern "C" float read_float(int node_id, unsigned addr){  char *pa;  float r;    pa = PageTables[node_id]->lookup(addr);  if (!pa)    YS__errmsg(node_id, "Attempt to access non-existing memory %x\n", addr);  r = endian_swap(*(float*)pa);  return(r);}/*=========================================================================*//* Read double value                                                       *//*=========================================================================*/extern "C" double read_double(int node_id, unsigned addr){  char *pa;  double r;    pa = PageTables[node_id]->lookup(addr);  if (!pa)    YS__errmsg(node_id, "Attempt to access non-existing memory %x\n", addr);  r = endian_swap(*(double*)pa);  return(r);}/*=========================================================================*//* Read bit i within an integer                                            *//*=========================================================================*/extern "C" int read_bit(int node_id, unsigned addr, int i){  char *pa;  unsigned r;  pa = PageTables[node_id]->lookup(addr);  if (!pa)    YS__errmsg(node_id, "Attempt to access non-existing memory %x\n", addr);  r = endian_swap(*(unsigned*)pa);  return((r >> i) & 1);}/*=========================================================================*//* Write integer value                                                     *//*=========================================================================*/extern "C" void write_int(int node_id, unsigned addr, unsigned int v){  char *pa;    pa = PageTables[node_id]->lookup(addr);  if (!pa)    YS__errmsg(node_id, "Attempt to access non-existing memory %x\n", addr);  *(unsigned int*)pa = endian_swap(v);}/*=========================================================================*//* Write character value                                                   *//*=========================================================================*/extern "C" void write_char(int node_id, unsigned addr, unsigned char v){  char *pa;  pa = PageTables[node_id]->lookup(addr);  if (!pa)    YS__errmsg(node_id, "Attempt to access non-existing memory %x\n", addr);  *(unsigned char*)pa = v;}/*=========================================================================*//* Write float value                                                       *//*=========================================================================*/extern "C" void write_float(int node_id, unsigned addr, float v){  char *pa;    pa = PageTables[node_id]->lookup(addr);  if (!pa)    YS__errmsg(node_id, "Attempt to access non-existing memory %x\n", addr);  *(float*)pa = endian_swap(v);}/*=========================================================================*//* Write double value                                                      *//*=========================================================================*/extern "C" void write_double(int node_id, unsigned addr, double v){  char *pa;    pa = PageTables[node_id]->lookup(addr);  if (!pa)    YS__errmsg(node_id, "Attempt to access non-existing memory %x\n", addr);  *(double*)pa = endian_swap(v);}/*=========================================================================*//* Write bit 1                                                             *//*=========================================================================*/extern "C" void write_bit(int node_id, unsigned addr, int i, unsigned v){  char *pa;  unsigned oldval;  pa = PageTables[node_id]->lookup(addr);  if (!pa)    YS__errmsg(node_id, "Attempt to access non-existing memory %x\n", addr);  oldval = endian_swap(*(unsigned*)pa);  if (v == 0)    oldval &= (0xFFFFFFFE << i);  else    oldval |= (0x00000001 << i);  *(unsigned*)pa = endian_swap(oldval);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -