实现read函数时不要忘记对齐,其中讲义提示:
总是读取地址为 raddr & ~0x3u的4字节返回
所以需要把读进来的地址进行 & ~0x3u,得到对齐后的地址,
而后在把对齐后的物理地址转为虚拟地址guest_to_host(addr),
最后进行组合就ok了,例如:
地址: 0x80000000 0x80000001 0x80000002 0x80000003
数据: 0x12 0x34 0x56 0x78
如果 raddr = 0x80000003,对齐后的地址是 0x80000000,读取的 4 字节数据组合后为 0x78563412,该数据将作为函数的返回值。
最终实现代码如下:
static word_t pmem_read(paddr_t addr) {
paddr_t adapt_addr = addr & ~0x3u;
uint8_t *ret = guest_to_host(adapt_addr);
word_t data;
for (int i = 0; i < 4; i++){
data |= ret[i] << ( i * 8);
}
return ret;
}
利用或操作进行拼接。
写操作同理,讲义中提示:
extern "C" void pmem_write(int waddr, int wdata, char wmask) {
// 总是往地址为`waddr & ~0x3u`的4字节按写掩码`wmask`写入`wdata`
// `wmask`中每比特表示`wdata`中1个字节的掩码,
// 如`wmask = 0x3`代表只写入最低2个字节, 内存中的其它字节保持不变
}
根据刚才的对齐规则,掩码也是相同机理
extern "C" void pmem_write(int waddr, int wdata, char wmask) {
//host_write(guest_to_host(addr), len, data);
paddr_t adapt_addr = waddr & ~0x3u;
uint8_t *vaddr = guest_to_host(adapt_addr);
for(int i = 0; i < 4; i++){
if (wmask & (1 << i)) {
vaddr[i] = (wdata >> (i * 8)) & 0xFF;
}
}
}
标签:0x3u,addr,wmask,read,write,int,host,字节,pm
From: https://www.cnblogs.com/ink-bai/p/18200788