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

📄 firewall.c

📁 一个用在mips体系结构中的操作系统
💻 C
字号:
/* * Copyright (C) 1996-1998 by the Board of Trustees *    of Leland Stanford Junior University. *  * This file is part of the SimOS distribution.  * See LICENSE file for terms of the license.  * *//***************************************************************** * firewall.c * *****************************************************************/#include "syslimits.h"#include "simtypes.h"#include "hd.h"#include "checkpoint.h"#include "machine_params.h"#include "cpu_interface.h"#include "cpu_state.h"#include "sim_error.h"#include "addr_layout.h"#include "simutil.h"#include "../../memsystems/flashlite/flash_interface.h"#include "firewall.h"static CptCallback FirewallCheckpointCB;static uint64* fwall[SIM_MAXCPUS]; /* one array allocated for each node */static uint    fwn;                /* number of nodes */static uint    ppn;                /* pages per node */static uint    ppcell;             /* pages per cell */static uint    cpus_per_cell_mask; /* unary of cpus per cell */extern CptVersion cptVersion;/* access functions to fwall array entries */#define FW_ISWR(val, cell) (((val) & ((uint64)1 << cell)) != (uint64)0)#define FW_SETWR(val, cell) ((val) | ((uint64)1 << cell))#define FW_CLRWR(val, cell) ((val) & ~((uint64)1 << cell))/* fast case optimization: power-of-two pages per node, < 32 cells */#define FW_ISWR32(val, cell) ((((uint) val) & (1 << cell)) != 0)static uint    log2ppcell;static uint    log2ppn;static uint    ppnodemask;/* function pointer derefed by caller distinguishes fast and slow cases *//* switch for whether to call firewall code */static uint firewall_enabled_flag;uint64sim_firewall_page_prot(int n, int pg){  ASSERT(0 <= n && n < fwn && 0 <= pg && pg < ppn);  return fwall[n][pg];}voidsim_firewall_set_page_prot_raw(int n, int pgoffs, uint64 prot){   ASSERT(0 <= n && n < fwn && 0 <= pgoffs && pgoffs < ppn);   fwall[n][pgoffs] = prot;}intsim_firewall_set_page_prot(int cpu, int n, int pgoffs, uint64 prot){   uint cellnum = cpu >> log2CPUS_PER_CELL(0);   uint pgcell  = n >> log2CPUS_PER_CELL(0);   ASSERT(0 <= n && n < fwn && 0 <= pgoffs && pgoffs < ppn);   ASSERT(n < 32); /* this function currently doesn't handle n >= 32 */   if ((pgcell == cellnum) || FW_ISWR32(fwall[n][pgoffs], cellnum)) {      /* good, we have write permission */      if (CPUVec.FirewallChange == 0) {         fwall[n][pgoffs] = prot;      } else {         uint prot32    = prot;         uint pgnum     = n * ppn + pgoffs;         uint cellmask  = cpus_per_cell_mask<<(pgcell<<log2CPUS_PER_CELL(0));         uint oldprot   = fwall[n][pgoffs];         uint grantmask = (prot32 & ~oldprot) & ~cellmask;         uint denymask  = (oldprot & ~prot32) & ~cellmask;         /* the cellmask is there to avoid indicating a change for cpus that          * are local to this page (and thus never change firewall          * status irrespective of the bit values).          */         fwall[n][pgoffs] = prot32;         if (grantmask) {            CPUVec.FirewallChange(pgnum * DEFAULT_PAGESZ, 1, grantmask);         }         if (denymask) {            CPUVec.FirewallChange(pgnum * DEFAULT_PAGESZ, 0, denymask);         }      }      return 0;   } else {      LogEntry("Illegal firewall write", cpu, "firewall for %x (cell %d) contents were %llx\n",               n * ppn + pgoffs, pgcell, fwall[n][pgoffs]);      return 1;   }}uintCheckFirewallFast(int cpu, PA paddr){   /* return 1 if access allowed, 0 if violation     * Note that we are in the memory system here:  the remap should have already    * occurred before this is called    */   uint pgnum   = PAGE_NUMBER(paddr);   uint cellnum = cpu >> log2CPUS_PER_CELL(0);   uint pgcell  = pgnum >> log2ppcell;   uint pgnode  = pgnum >> log2ppn;   uint pgoffs  = pgnum & ppnodemask;   return (pgcell == cellnum) || FW_ISWR32(fwall[pgnode][pgoffs], cellnum);}uintCheckFirewallSlow(int cpu, PA paddr){   uint pgnum   = PAGE_NUMBER(paddr);   uint cellnum = cpu >> log2CPUS_PER_CELL(0);   uint pgcell  = pgnum / ppcell;   uint pgnode  = pgnum / ppn;   uint pgoffs  = pgnum % ppn;   return (pgcell == cellnum) || FW_ISWR(fwall[pgnode][pgoffs], cellnum);}voidsim_firewall_init(int restoreFromCkpt, int n, int pg_per_node){  char name[128];  int i;  ASSERT(0 < n && n <= SIM_MAXCPUS);  for (i = 0; i < n; i++) {    sprintf(name, "FWALL_%d", i);    fwall[i] = (uint64*)ZMALLOC(pg_per_node*sizeof(uint64), name);  }  fwn = n;  ppn = pg_per_node;  ppcell = ppn * CPUS_PER_CELL(0);  Simcpt_Register("firewall", FirewallCheckpointCB, ALL_CPUS);  if (restoreFromCkpt) {    Simcpt_Restore("firewall");#ifdef FLASH_HACK    FlashliteFirewallInit();#endif /* FLASH_HACK */  } else {     firewall_enabled_flag = NUM_CELLS(0) > 1;  }  if ((NUM_CELLS(0) < 32) && ((pg_per_node & (pg_per_node-1)) == 0)) {     CPUVec.CheckFirewall = CheckFirewallFast;     log2ppcell = GetLog2(ppcell);     log2ppn = GetLog2(pg_per_node);     ppnodemask = pg_per_node-1;  } else {     CPUVec.CheckFirewall = CheckFirewallSlow;  }  if (!firewall_enabled_flag) {      CPUVec.CheckFirewall = 0;  }  cpus_per_cell_mask = (1 << CPUS_PER_CELL(0)) - 1;}/* Checkpointing support */static intFirewallCheckpointCB(CptDescriptor *cptd){  int i;  /* for compatibility with version 3 checkpoints */  if (cptVersion.ver == 3) {     Simcpt_CptInt(cptd, "NumCells", NO_INDEX, NO_INDEX, &(NUM_CELLS(0)));  }  /* XXX old checkpoints used to set numCells to 0 for simport boots.   * If we're restoring from a checkpoint and that's the case, then   * we're done here.   */  if (cptd->mode == CPT_RESTORE && NUM_CELLS(0) == 0) {    NUM_CELLS(0) = 1;    return 0;  }  ASSERT(NUM_CELLS(0) != 0);  /* XXX the following is not compatible with the old checkpoint format.   * No need to provide compatibility, since old simport checkpoints   * don't use the firewall.   */  Simcpt_OptionalUint(cptd, "FirewallEnabled",NO_INDEX,NO_INDEX,1);  Simcpt_CptUint(cptd, "FirewallEnabled",NO_INDEX,NO_INDEX,                 &firewall_enabled_flag);  Simcpt_CptHex(cptd, "PagesPerNode",NO_INDEX,NO_INDEX,(uint*)&ppn);  for (i = 0; i < NUM_CPUS(0); i++) {    Simcpt_CptBlock(cptd, "FWArray", i, NO_INDEX,		    fwall[i], ppn*sizeof(uint64)/sizeof(char), -1);  }  return 0;}

⌨️ 快捷键说明

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