From d2b63e1e5109b1cdd876e1400be8910b4c302a9f Mon Sep 17 00:00:00 2001 From: Recolic Keghart <root@recolic.net> Date: Sun, 29 Dec 2019 20:09:31 +0800 Subject: [PATCH] fix problems about IO --- nemu/include/common.h | 2 +- nemu/include/device/port-io.h | 6 ++ nemu/src/cpu/exec/control.cc | 2 +- nemu/src/cpu/exec/system.cc | 19 +++++- nemu/src/device/io/port-io.cc | 59 +++++++------------ nemu/src/device/vga.cc | 7 +-- nexus-am/am/arch/x86-nemu/src/devices/timer.c | 8 ++- nexus-am/libs/klib/src/printf-lib/printf.c | 2 + nexus-am/libs/klib/src/stdio.c | 3 - 9 files changed, 55 insertions(+), 53 deletions(-) diff --git a/nemu/include/common.h b/nemu/include/common.h index d765817..b734ebc 100644 --- a/nemu/include/common.h +++ b/nemu/include/common.h @@ -11,7 +11,7 @@ #endif /* You will define this macro in PA2 */ -//#define HAS_IOE +#define HAS_IOE #include <stdint.h> #include <assert.h> diff --git a/nemu/include/device/port-io.h b/nemu/include/device/port-io.h index 84e2488..62969e3 100644 --- a/nemu/include/device/port-io.h +++ b/nemu/include/device/port-io.h @@ -7,4 +7,10 @@ typedef void(*pio_callback_t)(ioaddr_t, int, bool); void* add_pio_map(ioaddr_t, int, pio_callback_t); +template <size_t Bytes> +uint32_t pio_read_common(ioaddr_t addr); + +template <size_t Bytes> +void pio_write_common(ioaddr_t addr, uint32_t data); + #endif diff --git a/nemu/src/cpu/exec/control.cc b/nemu/src/cpu/exec/control.cc index 8c05bb9..f21343a 100644 --- a/nemu/src/cpu/exec/control.cc +++ b/nemu/src/cpu/exec/control.cc @@ -66,7 +66,7 @@ namespace EHelperImpl { make_EHelper(call_rm) { RLIB_MACRO_DEBUG_ASSERT(decoding.is_operand_size_16 == false); - rlib::println("Reach call_rm. WARNING: this instruction impl is heavily broken."); + // rlib::println("Reach call_rm. WARNING: this instruction impl is heavily broken."); rtl_push<4>(&decoding.seq_eip); rtl_jr(&id_dest->val); diff --git a/nemu/src/cpu/exec/system.cc b/nemu/src/cpu/exec/system.cc index c1876cf..7c820e9 100644 --- a/nemu/src/cpu/exec/system.cc +++ b/nemu/src/cpu/exec/system.cc @@ -1,4 +1,5 @@ #include "cpu/exec.h" +#include "device/port-io.h" void difftest_skip_ref(); void difftest_skip_dut(); @@ -43,7 +44,14 @@ namespace EHelperImpl { } make_EHelper(in) { - TODO(); + rtlreg_t tmp; + switch(id_src->width) + { + case 1: tmp = pio_read_common<1>(id_src->val); break; + case 2: tmp = pio_read_common<2>(id_src->val); break; + case 4: tmp = pio_read_common<4>(id_src->val); break; + } + operand_write(id_dest, &tmp); print_asm_template2(in); @@ -53,8 +61,13 @@ namespace EHelperImpl { } make_EHelper(out) { - TODO(); - + switch(id_src->width) + { + case 1: pio_write_common<1>(id_dest->val, id_src->val); break; + case 2: pio_write_common<2>(id_dest->val, id_src->val); break; + case 4: pio_write_common<4>(id_dest->val, id_src->val); break; + } + print_asm_template2(out); #if defined(DIFF_TEST) diff --git a/nemu/src/device/io/port-io.cc b/nemu/src/device/io/port-io.cc index 0b0960b..cd9a62d 100644 --- a/nemu/src/device/io/port-io.cc +++ b/nemu/src/device/io/port-io.cc @@ -39,49 +39,30 @@ void* add_pio_map(ioaddr_t addr, int len, pio_callback_t callback) { return pio_space + addr; } -static inline uint32_t pio_read_common(ioaddr_t addr, int len) { - assert(addr + len - 1 < PORT_IO_SPACE_MAX); - pio_callback(addr, len, false); // prepare data to read - switch (len) { - case 4: return *(uint32_t *)(pio_space + addr); - case 2: return *(uint16_t *)(pio_space + addr); - case 1: return *(uint8_t *)(pio_space + addr); - default: assert(0); - } -} - -static inline void pio_write_common(ioaddr_t addr, uint32_t data, int len) { - assert(addr + len - 1 < PORT_IO_SPACE_MAX); - switch (len) { - case 4: *(uint32_t *)(pio_space + addr) = data; break; - case 2: *(uint16_t *)(pio_space + addr) = data; break; - case 1: *(uint8_t *)(pio_space + addr) = data; break; - default: assert(0); - } - pio_callback(addr, len, true); -} +template <size_t Bytes> +uint32_t pio_read_common(ioaddr_t addr) { + static_assert(Bytes == 4 || Bytes == 2 || Bytes == 1); + using result_type = std::conditional_t<Bytes == 4, uint32_t, std::conditional_t<Bytes == 2, uint16_t, uint8_t>>; -/* CPU interface */ -uint32_t pio_read_l(ioaddr_t addr) { - return pio_read_common(addr, 4); + assert(addr + Bytes - 1 < PORT_IO_SPACE_MAX); + pio_callback(addr, Bytes, false); // prepare data to read + return *(result_type *)(pio_space + addr); } -uint32_t pio_read_w(ioaddr_t addr) { - return pio_read_common(addr, 2); -} +template <size_t Bytes> +void pio_write_common(ioaddr_t addr, uint32_t data) { + static_assert(Bytes == 4 || Bytes == 2 || Bytes == 1); + using result_type = std::conditional_t<Bytes == 4, uint32_t, std::conditional_t<Bytes == 2, uint16_t, uint8_t>>; -uint32_t pio_read_b(ioaddr_t addr) { - return pio_read_common(addr, 1); + assert(addr + Bytes - 1 < PORT_IO_SPACE_MAX); + *(result_type *)(pio_space + addr) = data; + pio_callback(addr, Bytes, true); } -void pio_write_l(ioaddr_t addr, uint32_t data) { - pio_write_common(addr, data, 4); -} -void pio_write_w(ioaddr_t addr, uint32_t data) { - pio_write_common(addr, data, 2); -} - -void pio_write_b(ioaddr_t addr, uint32_t data) { - pio_write_common(addr, data, 1); -} +template uint32_t pio_read_common<4>(ioaddr_t addr); +template uint32_t pio_read_common<2>(ioaddr_t addr); +template uint32_t pio_read_common<1>(ioaddr_t addr); +template void pio_write_common<4>(ioaddr_t addr, uint32_t data); +template void pio_write_common<2>(ioaddr_t addr, uint32_t data); +template void pio_write_common<1>(ioaddr_t addr, uint32_t data); diff --git a/nemu/src/device/vga.cc b/nemu/src/device/vga.cc index 20c1678..6644584 100644 --- a/nemu/src/device/vga.cc +++ b/nemu/src/device/vga.cc @@ -7,8 +7,7 @@ #include <SDL2/SDL.h> #define VMEM 0x40000 - -#define SCREEN_PORT 0x100 // Note that this is not the standard +#define SCREEN_PORT 0x100 #define SCREEN_H 300 #define SCREEN_W 400 @@ -33,8 +32,8 @@ void init_vga() { texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_ARGB8888, SDL_TEXTUREACCESS_STATIC, SCREEN_W, SCREEN_H); - screensize_port_base = add_pio_map(SCREEN_PORT, 4, NULL); + screensize_port_base = reinterpret_cast<decltype(screensize_port_base)>(add_pio_map(SCREEN_PORT, 4, nullptr)); *screensize_port_base = ((SCREEN_W) << 16) | (SCREEN_H); - vmem = add_mmio_map(VMEM, 0x80000, NULL); + vmem = reinterpret_cast<decltype(vmem)>(add_mmio_map(VMEM, 0x80000, nullptr)); } #endif /* HAS_IOE */ diff --git a/nexus-am/am/arch/x86-nemu/src/devices/timer.c b/nexus-am/am/arch/x86-nemu/src/devices/timer.c index b7c366c..9fd970c 100644 --- a/nexus-am/am/arch/x86-nemu/src/devices/timer.c +++ b/nexus-am/am/arch/x86-nemu/src/devices/timer.c @@ -3,11 +3,15 @@ #include <amdev.h> size_t timer_read(uintptr_t reg, void *buf, size_t size) { + const size_t rtc_port_id = 0x48; + uint64_t curr_time; + switch (reg) { case _DEVREG_TIMER_UPTIME: { _UptimeReg *uptime = (_UptimeReg *)buf; - uptime->hi = 0; - uptime->lo = 0; + curr_time = inl(rtc_port_id); + uptime->hi = curr_time >> 32; + uptime->lo = (uint32_t) curr_time; return sizeof(_UptimeReg); } case _DEVREG_TIMER_DATE: { diff --git a/nexus-am/libs/klib/src/printf-lib/printf.c b/nexus-am/libs/klib/src/printf-lib/printf.c index 8a700ad..23edb2d 100644 --- a/nexus-am/libs/klib/src/printf-lib/printf.c +++ b/nexus-am/libs/klib/src/printf-lib/printf.c @@ -35,6 +35,8 @@ #include "printf.h" +#include "am.h" +void _putchar(char c) {_putc(c);} // define this globally (e.g. gcc -DPRINTF_INCLUDE_CONFIG_H ...) to include the // printf_config.h header file diff --git a/nexus-am/libs/klib/src/stdio.c b/nexus-am/libs/klib/src/stdio.c index 681f124..5807363 100644 --- a/nexus-am/libs/klib/src/stdio.c +++ b/nexus-am/libs/klib/src/stdio.c @@ -30,8 +30,5 @@ int vsprintf_(char *out, const char *fmt, va_list va) { // return 0; //} -void _putchar(char character) { - ; -} #endif -- GitLab