热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

SkyEye硬件模拟平台,硬件仿真实现之三

文章标题:SkyEye硬件模拟平台,硬件仿真实现之三。Linux是中国IT实验室的一个技术频道。包含桌面应用,Linux系统管理,内核研究,嵌入式系统和开源等一些基本分类

  1. MMU和Memory系统结构
  
图 0-1 arm系统中MMU和Memory的系统结构

  
 

  arm系统中MMU和Memory的系统结构如图 0 1所示。不过具体的CPU在实现MMU时差别较大,可能对其做简化和扩展, SkyEye的MMU模拟实现基于此,在提供一个标准的接口基础上,分成与具体CPU类型无关的MMU模拟子模块和与具体CPU类型相关的MMU模拟子模块两个主要部分。
  
  2. arm 数据访问的基本流程图
  arm CPU进行数据访问的基本流程如图 0 2所示。
  
图 0-2 arm CPU进行数据访问的基本流程

  
 

  3. MMU的统一接口
  
  数据结构
  
  typedef struct mmu_state_t {
  armword control; //CP15 control register
  armword translation_table_base; //CP15 translation table base register
  armword domain_access_control; //CP15 domain access control register
  armword fault_status; //CP15 fault status register
  armword fault_address; //CP15 fault address register
  armword last_domain;  //last access domain
  armword process_id;  //CP15 process id register
  mmu_ops_t ops;
  union{
  sa_mmu_t sa_mmu;
  arm7100_mmu_t arm7100_mmu;
  }u;
  } mmu_state_t;
  
  typedef struct mmu_ops_s{
  int (*init)(armul_State *state);/*initilization*/
  void (*exit)(armul_State *state);/*free on exit*/
  fault_t (*read_byte)(ARMul_State *state, ARMword va, armword *data);
  fault_t (*write_byte)(ARMul_State *state, ARMword va, armword data);
  fault_t (*read_halfword)(ARMul_State *state, ARMword va, armword *data);
  fault_t (*write_halfword)(ARMul_State *state, ARMword va,armword data);
  fault_t (*read_word)(ARMul_State *state, ARMword va,armword *data);
  fault_t (*write_word)(ARMul_State *state, ARMword va,armword data);
  fault_t (*load_instr)(ARMul_State *state, ARMword va, armword *instr);
  void (*mcr)(ARMul_State *state, ARMword instr, armword val);
  ARMword (*mrc)(ARMul_State *state, armword instr);
  }mmu_ops_t;
  
  数据结构armul_State中类型为mmu_state_t的mmu代表模拟中MMU的状态。mmu_state_t中的ops提供具体mmu的接口函数,同时包括一个联合结构u用于具体mmu实现的数据结构。
  
  4. 与具体CPU类型无关的MMU模拟子模块
  与具体CPU类型无关的MMU模拟子模块是实现MMU模拟的基础,它实现了TLB,TTW, 访问控制,CACHE, Write Buffer,Read Buffer等MMU要素的模拟,并且提供了较统一的接口,可以较灵活地组合实现具体MMU模拟。
  
  TLB的实现(mmu/tlb.[ch])
  TLB是一个表,它的表项包含地址映射信息和访问控制信息,地址转换信息只有在该表中查询不到时,才通过TTW在内存中查找。
  
  数据结构
  
  TLB 映射类型
  typedef enum tlb_mapping_t {
  TLB_INVALID = 0,
  TLB_SMALLPAGE = 1,
  TLB_LARGEPAGE = 2,
  TLB_SECTION = 3
  } tlb_mapping_t;
  
  TLB 表项
  
  typedef struct tlb_entry_t {
  armword virt_addr;  //virtual address
  armword phys_addr; //physical address
  armword perms;   //access permission
  armword domain;  //access domain
  tlb_mapping_t mapping; //tlb mapping type
  } tlb_entry_t;
  
  TLB 表
  
  typedef struct tlb_s{
  int num; /*num of tlb entry*/
  int cycle; /*current tlb cycle,used for allocate tlb_entry*/
  tlb_entry_t *entrys;
  }tlb_t;
  
  接口函数
  
  int mmu_tlb_init(tlb_t *tlb_t, int num);
  初始化TLB
  void mmu_tlb_exit(tlb_t *tlb_t);
  释放TLB
  void mmu_tlb_invalidate_all(armul_State *state, tlb_t *tlb_t);
  无效所有的tlb_entry
  void mmu_tlb_invalidate_entry(ARMul_State *state, tlb_t *tlb_t, armword virt_addr);
  无效包含指定virt_addr的tlb_entry.
  tlb_entry_t * mmu_tlb_search(ARMul_State *state, tlb_t *tlb_t, armword virt_addr);
  根据virt_addr查找tlb_entry
  
  TTW的实现(mmu/tlb.[ch])
  arm系统中通过2级映射,实现了页式地址转换。
  
  接口函数
  
  fault_t translate(ARMul_State *state, armword virt_addr, tlb_t *tlb_t, tlb_entry_t **tlb)
  {
  /*首先查找TLB表,如果没有找到,执行TTW并更新TLB表*/
  
  *tlb = mmu_tlb_search(state, tlb_t, virt_addr);/*查找tlb*/
  if (!*tlb) {
  /* 没有找到,进行TTW*/
  armword l1addr, l1desc; /*一级描述符地址、一级描述符*/
  tlb_entry_t entry;
  
  l1addr = state->mmu.translation_table_base & 0xFFFFC000;
  l1addr = (l1addr | (virt_addr >> 18)) & ~3; /*计算一级描述符地址*/
  l1desc = mem_read_word(state, l1addr); /*读取一级描述符*/
  switch (l1desc & 3) {
  case 0:
  case 3:
  return SECTION_TRANSLATION_FAULT;
  case 1:
  /*页式变换*/
  {
  armword l2addr, l2desc; /*二级描述符的地址,二级描述符*/
  
  l2addr = l1desc & 0xFFFFFC00;
  /*计算二级描述符的地址*/
  l2addr = (l2addr | ((virt_addr & 0x000FF000) >> 10)) & ~3;
  /*读取二级描述符*/
  l2desc = mem_read_word(state, l2addr);
  
  entry.virt_addr = virt_addr;
  entry.phys_addr = l2desc;
  entry.perms = l2desc & 0x00000FFC;
  entry.domain = (l1desc >> 5) & 0x0000000F;
  switch (l2desc & 3) {
  case 0:
  case 3:
  state->mmu.last_domain = entry.domain;
  return PAGE_TRANSLATION_FAULT;
  case 1:
  entry.mapping = TLB_LARGEPAGE; /*大页*/
  break;
  case 2:
  entry.mapping = TLB_SMALLPAGE; /*小页*/
  break;
  }
  }
  break;
  case 2:
  /*段变换*/
  entry.virt_addr = virt_addr;
  entry.phys_addr = l1desc;
  entry.perms = l1desc & 0x00000C0C;
  entry.domain = (l1desc >> 5) & 0x0000000F;
  entry.mapping = TLB_SECTION;
  break;
  }
  entry.virt_addr &= tlb_masks[entry.mapping];
  entry.phys_addr &= tlb_masks[entry.mapping];
  
  /* 更新tlb*/
  *tlb = &tlb_t->entrys[tlb_t->cycle];
  tlb_t->cycle = (tlb_t->cycle + 1) % tlb_t->num;
  **tlb = entry;
  }
  state->mmu.last_domain = (*tlb)->domain;
  return NO_FAULT;
  }
  
  访问控制的实现(mmu/tlb.[ch])
  
  接口函数
  
  fault_t check_access(ARMul_State *state, armword virt_addr,
  tlb_entry_t *tlb, int read);
  
  CACHE的实现(mmu/cache.[ch])
  
  arm系统中一般只实现组相联CACHE。组相联CACHE分成多组,一个组有包括多个CACHE line,一个32位地址可以由下图表示。
  
  Tag Set Word 1 0
  
  数据结构
  
  Cache行
  
  typedef struct cache_line_t{
  armword tag; /* cache line align address |
  bit2: last half dirty
  bit1: first half dirty
  bit0: cache valid flag
  */
  armword pa; /*physical address*/
  armword *data; /*array of cached data*/
  }cache_line_t;
  
  #define TAG_VALID_FLAG 0x00000001
  #define TAG_FIRST_HALF_DIRTY 0x00000002
  #define TAG_LAST_HALF_DIRTY 0x00000004
  
  Cache 组
  
  typedef struct cache_set_s{
  cache_line_t *lines;
  int cycle; /*used for cache line allocation*/
  }cache_set_t;
  
  Cache 结构
  
  typedef struct cache_s{
  int width; /*bytes in a line*/
  int way; /*way of set asscociate*/
  int set; /*num of set*/
  int w_mode; /*write back or write through*/
  //int a_mode; /*alloc mode: random or round-bin*/
  cache_set_t *sets;
  }cache_t;
  
  接口函数
  
  /*Cache的初始化和释放*/
  int mmu_cache_init(cache_t *cache_t, int width, int way, int set, int w_mode);
  void mmu_cache_exit(cache_t *cache_t);
  /*Cache 查找和分配*/
  cache_line_t * mmu_cache_search(ARMul_State *state, cache_t *cache_t, armword va);
  cache_line_t * mmu_cache_alloc(ARMul_State *state, cache_t *cache_t, ARMword va, armword pa
推荐阅读
  • 如何实现织梦DedeCms全站伪静态
    本文介绍了如何通过修改织梦DedeCms源代码来实现全站伪静态,以提高管理和SEO效果。全站伪静态可以避免重复URL的问题,同时通过使用mod_rewrite伪静态模块和.htaccess正则表达式,可以更好地适应搜索引擎的需求。文章还提到了一些相关的技术和工具,如Ubuntu、qt编程、tomcat端口、爬虫、php request根目录等。 ... [详细]
  • PHP玩家基地系统毕业设计(附源码、运行环境)的用户登录界面、游戏管理和玩家作品管理
    本文介绍了一个PHP玩家基地系统的毕业设计,包括用户登录界面、游戏管理和玩家作品管理等功能。附带源码和运行环境,并提供免费赠送本源代码和数据库的方式,请私信获取详细信息。摘要共计约XXX字。 ... [详细]
  • 本文描述了作者第一次参加比赛的经历和感受。作者是小学六年级时参加比赛的唯一选手,感到有些紧张。在比赛期间,作者与学长学姐一起用餐,在比赛题目中遇到了一些困难,但最终成功解决。作者还尝试了一款游戏,在回程的路上感到晕车。最终,作者以110分的成绩取得了省一会的资格,并坚定了继续学习的决心。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • 基于layUI的图片上传前预览功能的2种实现方式
    本文介绍了基于layUI的图片上传前预览功能的两种实现方式:一种是使用blob+FileReader,另一种是使用layUI自带的参数。通过选择文件后点击文件名,在页面中间弹窗内预览图片。其中,layUI自带的参数实现了图片预览功能。该功能依赖于layUI的上传模块,并使用了blob和FileReader来读取本地文件并获取图像的base64编码。点击文件名时会执行See()函数。摘要长度为169字。 ... [详细]
  • 搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的详细步骤
    本文详细介绍了搭建Windows Server 2012 R2 IIS8.5+PHP(FastCGI)+MySQL环境的步骤,包括环境说明、相关软件下载的地址以及所需的插件下载地址。 ... [详细]
  • PHP图片截取方法及应用实例
    本文介绍了使用PHP动态切割JPEG图片的方法,并提供了应用实例,包括截取视频图、提取文章内容中的图片地址、裁切图片等问题。详细介绍了相关的PHP函数和参数的使用,以及图片切割的具体步骤。同时,还提供了一些注意事项和优化建议。通过本文的学习,读者可以掌握PHP图片截取的技巧,实现自己的需求。 ... [详细]
  • 关羽败走麦城时路过马超封地 马超为何没有出手救人
    对当年关羽败走麦城,恰好路过马超的封地,为啥马超不救他?很感兴趣的小伙伴们,趣历史小编带来详细的文章供大家参考。说到英雄好汉,便要提到一本名著了,没错,那就是《三国演义》。书中虽 ... [详细]
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • PHP设置MySQL字符集的方法及使用mysqli_set_charset函数
    本文介绍了PHP设置MySQL字符集的方法,详细介绍了使用mysqli_set_charset函数来规定与数据库服务器进行数据传送时要使用的字符集。通过示例代码演示了如何设置默认客户端字符集。 ... [详细]
  • Java序列化对象传给PHP的方法及原理解析
    本文介绍了Java序列化对象传给PHP的方法及原理,包括Java对象传递的方式、序列化的方式、PHP中的序列化用法介绍、Java是否能反序列化PHP的数据、Java序列化的原理以及解决Java序列化中的问题。同时还解释了序列化的概念和作用,以及代码执行序列化所需要的权限。最后指出,序列化会将对象实例的所有字段都进行序列化,使得数据能够被表示为实例的序列化数据,但只有能够解释该格式的代码才能够确定数据的内容。 ... [详细]
  • 橱窗设计的表现手法及其应用
    本文介绍了橱窗设计的表现手法,包括直接展示、寓意与联想、夸张与幽默等。通过对商品的折、拉、叠、挂、堆等陈列技巧,橱窗设计能够充分展现商品的形态、质地、色彩、样式等特性。同时,寓意与联想可以通过象形形式或抽象几何道具来唤起消费者的联想与共鸣,创造出强烈的时代气息和视觉空间。合理的夸张和贴切的幽默能够明显夸大商品的美的因素,给人以新颖奇特的心理感受,引起人们的笑声和思考。通过这些表现手法,橱窗设计能够有效地传达商品的个性内涵,吸引消费者的注意力。 ... [详细]
  • HDU 2372 El Dorado(DP)的最长上升子序列长度求解方法
    本文介绍了解决HDU 2372 El Dorado问题的一种动态规划方法,通过循环k的方式求解最长上升子序列的长度。具体实现过程包括初始化dp数组、读取数列、计算最长上升子序列长度等步骤。 ... [详细]
  • faceu激萌变老特效的使用方法详解
    本文介绍了faceu激萌变老特效的使用方法,包括打开faceu激萌app、点击贴纸、选择热门贴纸中的变老特效,然后对准人脸进行拍摄,即可给照片添加变老特效。操作简单,适合新用户使用。 ... [详细]
author-avatar
鸳鸯520_205
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有