#include "nemu.h"

#define PMEM_SIZE (128 * 1024 * 1024)

#define pmem_rw(addr, type) *(type *)({\
    Assert(addr < PMEM_SIZE, "physical address(0x%08x) is out of bound", addr); \
    guest_to_host(addr); \
    })

uint8_t pmem[PMEM_SIZE];

/* Memory accessing interfaces */

__attribute__((hot)) uint32_t paddr_read(paddr_t addr, int len) {
    static const uint32_t niddle[] = {0, 0xff, 0xffff, 0xffffff, 0xffffffff};
    return pmem_rw(addr, uint32_t) & niddle[len];
//  switch(len) {
//    case 4: return pmem_rw(addr, uint32_t);
//    case 2: return pmem_rw(addr, uint32_t) & 0x0000ffff;
//    case 1: return pmem_rw(addr, uint32_t) & 0x000000ff;
//    case 3: return pmem_rw(addr, uint32_t) & 0x00ffffff;
//    case 0: return 0;
//  }
//  return pmem_rw(addr, uint32_t) & (~0u >> ((4 - len) << 3));
}

void paddr_write(paddr_t addr, uint32_t data, int len) {
  memcpy(guest_to_host(addr), &data, len);
}

// len is Bytes.
uint32_t vaddr_read(vaddr_t addr, int len) {
  return paddr_read(addr, len);
}

// len is Bytes.
void vaddr_write(vaddr_t addr, uint32_t data, int len) {
  paddr_write(addr, data, len);
}
