diff --git a/nemu/include/macro.h b/nemu/include/macro.h index 68b9399fb591ac99a8541e769c66d78df12e9d6b..2bc2d2b77ec74ecb6a2dde413b3d531610c84ea9 100644 --- a/nemu/include/macro.h +++ b/nemu/include/macro.h @@ -15,4 +15,7 @@ #define RLIB_MACRO_DEBUG_ASSERT(expr) #endif +#define RLIB_MACRO_LIKELY(x) __builtin_expect((x),1) +#define RLIB_MACRO_UNLIKELY(x) __builtin_expect((x),0) + #endif diff --git a/nemu/src/device/io/mmio.cc b/nemu/src/device/io/mmio.cc index 529845fe4d038ed724a139a22c0f3f63fbea9ceb..396f0ede02f279af5758403e9c2788806fa702c4 100644 --- a/nemu/src/device/io/mmio.cc +++ b/nemu/src/device/io/mmio.cc @@ -33,7 +33,7 @@ void* add_mmio_map(paddr_t addr, int len, mmio_callback_t callback) { } /* bus interface */ -int is_mmio(paddr_t addr) { +__attribute__((hot)) int is_mmio(paddr_t addr) { int i; for (i = 0; i < nr_map; i ++) { if (addr >= maps[i].low && addr <= maps[i].high) { diff --git a/nemu/src/memory/memory.cc b/nemu/src/memory/memory.cc index 5fb2155def3c9ab4487f22957523225ff60945a7..8bce9de0feab69e7e41135d967b52e29ecc87391 100644 --- a/nemu/src/memory/memory.cc +++ b/nemu/src/memory/memory.cc @@ -1,4 +1,5 @@ #include "nemu.h" +#include "device/mmio.h" #define PMEM_SIZE (128 * 1024 * 1024) @@ -13,21 +14,25 @@ uint8_t pmem[PMEM_SIZE]; __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)); + + if(const auto mmio_id = is_mmio(addr);(-1 == mmio_id)) { + return pmem_rw(addr, uint32_t) & niddle[len]; + } + else { + return mmio_read(addr, len, mmio_id); + } } void paddr_write(paddr_t addr, uint32_t data, int len) { - memcpy(guest_to_host(addr), &data, len); + if(const auto mmio_id = is_mmio(addr);(-1 == mmio_id)) { + memcpy(guest_to_host(addr), &data, len); + } + else { + mmio_write(addr, len, data, mmio_id); + } } + // len is Bytes. uint32_t vaddr_read(vaddr_t addr, int len) { return paddr_read(addr, len); diff --git a/nexus-am/am/arch/x86-nemu/src/devices/input.c b/nexus-am/am/arch/x86-nemu/src/devices/input.c index a0634a778d2e26d2d6c72da0998d30e2d0cfebbc..15173f5d216813888cb8f3f5cf22a417e48ff7be 100644 --- a/nexus-am/am/arch/x86-nemu/src/devices/input.c +++ b/nexus-am/am/arch/x86-nemu/src/devices/input.c @@ -3,11 +3,15 @@ #include <amdev.h> size_t input_read(uintptr_t reg, void *buf, size_t size) { + const uint32_t I8042_DATA_PORT = 0x60; switch (reg) { case _DEVREG_INPUT_KBD: { _KbdReg *kbd = (_KbdReg *)buf; - kbd->keydown = 0; - kbd->keycode = _KEY_NONE; + uint32_t press = inl(I8042_DATA_PORT); + kbd->keycode = press; + if(press != _KEY_NONE){ + kbd->keydown = !(kbd->keydown); + } return sizeof(_KbdReg); } } diff --git a/nexus-am/am/arch/x86-nemu/src/devices/video.c b/nexus-am/am/arch/x86-nemu/src/devices/video.c index f56057286afd174c6f843bec4c7418f27da7110f..00cb3ab36ee163a673c9df420ddff6f4203e97f6 100644 --- a/nexus-am/am/arch/x86-nemu/src/devices/video.c +++ b/nexus-am/am/arch/x86-nemu/src/devices/video.c @@ -6,11 +6,13 @@ static uint32_t* const fb __attribute__((used)) = (uint32_t *)0x40000; size_t video_read(uintptr_t reg, void *buf, size_t size) { + const uint32_t SCREEN_PORT = 0x100; switch (reg) { case _DEVREG_VIDEO_INFO: { _VideoInfoReg *info = (_VideoInfoReg *)buf; - info->width = 0; - info->height = 0; + uint32_t screen = inl(SCREEN_PORT); + info->width = screen >> 16; + info->height = screen << 16 >> 16; return sizeof(_VideoInfoReg); } } @@ -21,7 +23,13 @@ size_t video_write(uintptr_t reg, void *buf, size_t size) { switch (reg) { case _DEVREG_VIDEO_FBCTL: { _FBCtlReg *ctl = (_FBCtlReg *)buf; - +int i; +int size = screen_width() * screen_height(); +for (i = 0; i < size; i ++) fb[i] = i; +// for(int i = 0; i < ctl->h; ++i) +// { +// memcpy(fb+(ctl->y+i)*screen_width()+ctl->x,ctl->pixels+i*ctl->w,ctl->w*4); +// } if (ctl->sync) { // do nothing, hardware syncs. }