diff --git a/nemu/include/common.h b/nemu/include/common.h index d7658173d93d3e3c845fe43e6fbd7ad7608aa846..b734ebc0e3100c1c84e49fb8e93a1cb011d8eee5 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 84e2488d5a2a629abdcd4256710fdf88a275b62b..62969e3993f382838cd1652f4ef79b4149a5ab53 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 8c05bb96a5619fd0996619a62c5194713792a9bf..f21343ac1bfc5c1942a7e407019b7b252e5ac725 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 c1876cf6a13a644399072f7b7066dd6e5377cb13..7c820e92673ba5d05497edf801cad2d795d0acfb 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 0b0960b6470af32266529a9ac9e6ccd1d89f915c..cd9a62d8f3e93c655c35920760a519c697f6446f 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 20c1678c73548e6cd507d0f8c390dfc21d72d978..66445841d2b6d50cda986da93c74f0740338f649 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 b7c366cddf8fcc1c79f2d3d3504c876a90792bf7..9fd970cbd575995ee63c88b49ac719fc156972dd 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 8a700add4c85e36e2c9ff01fd1f1a7c3acb28e22..23edb2dfa671526c98e7d6c4ea036ddbb38d2880 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 681f124b032d542c73631459224454daf83dbe19..5807363e6502af940aea29da7549ffc402b5e53a 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