From 7ee4b75156e4b96833bcfa297e0d0d9106a25518 Mon Sep 17 00:00:00 2001 From: Alexander Boettcher Date: Tue, 27 Nov 2012 12:38:38 +0100 Subject: [PATCH] Fix vesa_drv on native hardware When vesa_drv tries to access values lying across region boundaries, the second region may be not mapped. Fixes #524 --- os/src/drivers/framebuffer/vesa/ifx86emu.cc | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/os/src/drivers/framebuffer/vesa/ifx86emu.cc b/os/src/drivers/framebuffer/vesa/ifx86emu.cc index 24ce869d3..e035a3e6b 100644 --- a/os/src/drivers/framebuffer/vesa/ifx86emu.cc +++ b/os/src/drivers/framebuffer/vesa/ifx86emu.cc @@ -321,22 +321,33 @@ static int map_code_area(void) template static T X86API read(X86emu::u32 addr) { - T ret = *X86emu::virt_addr(addr); + /* + * Access the last byte of the T value, before actually reading the value. + * + * If the value of the address is crossing the current region boundary, + * the region behind the boundary will be allocated. Both regions will be + * merged and can be attached to a different virtual address then when + * only accessing the first bytes of the value. + */ + T * ret = X86emu::virt_addr(addr + sizeof(T) - 1); + ret = X86emu::virt_addr(addr); if (verbose_mem) { - unsigned v = ret; + unsigned v = *ret; PLOG(" io_mem: read [%p,%p) val 0x%ux", reinterpret_cast(addr), reinterpret_cast(addr + sizeof(T)), v); } - return ret; + return *ret; } template static void X86API write(X86emu::u32 addr, T val) { + /* see description of 'read' function */ + X86emu::virt_addr(addr + sizeof(T) - 1); *X86emu::virt_addr(addr) = val; if (verbose_mem) {