fixed fault priority for memory accesses requiring alignment

This commit is contained in:
Stanislav Shwartsman 2015-01-26 19:09:58 +00:00
parent 74da7a7092
commit 9a70727814
3 changed files with 100 additions and 28 deletions

View File

@ -44,11 +44,20 @@ bx_address bx_asize_mask[] = {
#endif
#endif
bx_bool BX_CPP_AttrRegparmN(3)
BX_CPU_C::write_virtual_checks(bx_segment_reg_t *seg, Bit32u offset, unsigned length)
bx_bool BX_CPP_AttrRegparmN(4)
BX_CPU_C::write_virtual_checks(bx_segment_reg_t *seg, Bit32u offset, unsigned length, bx_bool align)
{
Bit32u upper_limit;
length--;
if (align) {
if (offset & length) {
BX_DEBUG(("read_virtual_checks(): #GP misaligned access"));
exception(BX_GP_EXCEPTION, 0);
}
}
if (seg->cache.valid==0) {
BX_DEBUG(("write_virtual_checks(): segment descriptor not valid"));
return 0;
@ -59,8 +68,6 @@ BX_CPU_C::write_virtual_checks(bx_segment_reg_t *seg, Bit32u offset, unsigned le
return 0;
}
length--;
switch (seg->cache.type) {
case 0: case 1: // read only
case 4: case 5: // read only, expand down
@ -114,11 +121,20 @@ BX_CPU_C::write_virtual_checks(bx_segment_reg_t *seg, Bit32u offset, unsigned le
return 1;
}
bx_bool BX_CPP_AttrRegparmN(3)
BX_CPU_C::read_virtual_checks(bx_segment_reg_t *seg, Bit32u offset, unsigned length)
bx_bool BX_CPP_AttrRegparmN(4)
BX_CPU_C::read_virtual_checks(bx_segment_reg_t *seg, Bit32u offset, unsigned length, bx_bool align)
{
Bit32u upper_limit;
length--;
if (align) {
if (offset & length) {
BX_DEBUG(("read_virtual_checks(): #GP misaligned access"));
exception(BX_GP_EXCEPTION, 0);
}
}
if (seg->cache.valid==0) {
BX_DEBUG(("read_virtual_checks(): segment descriptor not valid"));
return 0;
@ -129,8 +145,6 @@ BX_CPU_C::read_virtual_checks(bx_segment_reg_t *seg, Bit32u offset, unsigned len
return 0;
}
length--;
switch (seg->cache.type) {
case 0: case 1: /* read only */
case 2: case 3: /* read/write */

View File

@ -64,7 +64,7 @@ BX_CPU_C::write_virtual_xmmword_32(unsigned s, Bit32u offset, const BxPackedXmmR
BX_CPP_INLINE void BX_CPP_AttrRegparmN(3)
BX_CPU_C::write_virtual_xmmword_aligned_32(unsigned s, Bit32u offset, const BxPackedXmmRegister *data)
{
Bit32u laddr = agen_write32(s, offset, 16);
Bit32u laddr = agen_write_aligned32(s, offset, 16);
write_linear_xmmword_aligned(s, laddr, data);
}
@ -80,7 +80,7 @@ BX_CPU_C::write_virtual_ymmword_32(unsigned s, Bit32u offset, const BxPackedYmmR
BX_CPP_INLINE void BX_CPP_AttrRegparmN(3)
BX_CPU_C::write_virtual_ymmword_aligned_32(unsigned s, Bit32u offset, const BxPackedYmmRegister *data)
{
Bit32u laddr = agen_write32(s, offset, 32);
Bit32u laddr = agen_write_aligned32(s, offset, 32);
write_linear_ymmword_aligned(s, laddr, data);
}
@ -98,7 +98,7 @@ BX_CPU_C::write_virtual_zmmword_32(unsigned s, Bit32u offset, const BxPackedZmmR
BX_CPP_INLINE void BX_CPP_AttrRegparmN(3)
BX_CPU_C::write_virtual_zmmword_aligned_32(unsigned s, Bit32u offset, const BxPackedZmmRegister *data)
{
Bit32u laddr = agen_write32(s, offset, 64);
Bit32u laddr = agen_write_aligned32(s, offset, 64);
write_linear_zmmword_aligned(s, laddr, data);
}
@ -146,7 +146,7 @@ BX_CPU_C::read_virtual_xmmword_32(unsigned s, Bit32u offset, BxPackedXmmRegister
BX_CPP_INLINE void BX_CPP_AttrRegparmN(3)
BX_CPU_C::read_virtual_xmmword_aligned_32(unsigned s, Bit32u offset, BxPackedXmmRegister *data)
{
Bit32u laddr = agen_read32(s, offset, 16);
Bit32u laddr = agen_read_aligned32(s, offset, 16);
read_linear_xmmword_aligned(s, laddr, data);
}
@ -162,7 +162,7 @@ BX_CPU_C::read_virtual_ymmword_32(unsigned s, Bit32u offset, BxPackedYmmRegister
BX_CPP_INLINE void BX_CPP_AttrRegparmN(3)
BX_CPU_C::read_virtual_ymmword_aligned_32(unsigned s, Bit32u offset, BxPackedYmmRegister *data)
{
Bit32u laddr = agen_read32(s, offset, 32);
Bit32u laddr = agen_read_aligned32(s, offset, 32);
read_linear_ymmword_aligned(s, laddr, data);
}
@ -180,7 +180,7 @@ BX_CPU_C::read_virtual_zmmword_32(unsigned s, Bit32u offset, BxPackedZmmRegister
BX_CPP_INLINE void BX_CPP_AttrRegparmN(3)
BX_CPU_C::read_virtual_zmmword_aligned_32(unsigned s, Bit32u offset, BxPackedZmmRegister *data)
{
Bit32u laddr = agen_read32(s, offset, 64);
Bit32u laddr = agen_read_aligned32(s, offset, 64);
read_linear_zmmword_aligned(s, laddr, data);
}
@ -388,7 +388,7 @@ BX_CPU_C::write_virtual_xmmword(unsigned s, bx_address offset, const BxPackedXmm
BX_CPP_INLINE void BX_CPP_AttrRegparmN(3)
BX_CPU_C::write_virtual_xmmword_aligned(unsigned s, bx_address offset, const BxPackedXmmRegister *data)
{
bx_address laddr = agen_write(s, offset, 16);
bx_address laddr = agen_write_aligned(s, offset, 16);
write_linear_xmmword_aligned(s, laddr, data);
}
@ -404,7 +404,7 @@ BX_CPU_C::write_virtual_ymmword(unsigned s, bx_address offset, const BxPackedYmm
BX_CPP_INLINE void BX_CPP_AttrRegparmN(3)
BX_CPU_C::write_virtual_ymmword_aligned(unsigned s, bx_address offset, const BxPackedYmmRegister *data)
{
bx_address laddr = agen_write(s, offset, 32);
bx_address laddr = agen_write_aligned(s, offset, 32);
write_linear_ymmword_aligned(s, laddr, data);
}
@ -422,7 +422,7 @@ BX_CPU_C::write_virtual_zmmword(unsigned s, bx_address offset, const BxPackedZmm
BX_CPP_INLINE void BX_CPP_AttrRegparmN(3)
BX_CPU_C::write_virtual_zmmword_aligned(unsigned s, bx_address offset, const BxPackedZmmRegister *data)
{
bx_address laddr = agen_write(s, offset, 64);
bx_address laddr = agen_write_aligned(s, offset, 64);
write_linear_zmmword_aligned(s, laddr, data);
}
@ -470,7 +470,7 @@ BX_CPU_C::read_virtual_xmmword(unsigned s, bx_address offset, BxPackedXmmRegiste
BX_CPP_INLINE void BX_CPP_AttrRegparmN(3)
BX_CPU_C::read_virtual_xmmword_aligned(unsigned s, bx_address offset, BxPackedXmmRegister *data)
{
bx_address laddr = agen_read(s, offset, 16);
bx_address laddr = agen_read_aligned(s, offset, 16);
read_linear_xmmword_aligned(s, laddr, data);
}
@ -486,7 +486,7 @@ BX_CPU_C::read_virtual_ymmword(unsigned s, bx_address offset, BxPackedYmmRegiste
BX_CPP_INLINE void BX_CPP_AttrRegparmN(3)
BX_CPU_C::read_virtual_ymmword_aligned(unsigned s, bx_address offset, BxPackedYmmRegister *data)
{
bx_address laddr = agen_read(s, offset, 32);
bx_address laddr = agen_read_aligned(s, offset, 32);
read_linear_ymmword_aligned(s, laddr, data);
}
@ -504,7 +504,7 @@ BX_CPU_C::read_virtual_zmmword(unsigned s, bx_address offset, BxPackedZmmRegiste
BX_CPP_INLINE void BX_CPP_AttrRegparmN(3)
BX_CPU_C::read_virtual_zmmword_aligned(unsigned s, bx_address offset, BxPackedZmmRegister *data)
{
bx_address laddr = agen_read(s, offset, 64);
bx_address laddr = agen_read_aligned(s, offset, 64);
read_linear_zmmword_aligned(s, laddr, data);
}

View File

@ -4463,8 +4463,8 @@ public: // for now...
BX_CPU_THIS_PTR espPageWindowSize = 0;
}
BX_SMF bx_bool write_virtual_checks(bx_segment_reg_t *seg, Bit32u offset, unsigned len) BX_CPP_AttrRegparmN(3);
BX_SMF bx_bool read_virtual_checks(bx_segment_reg_t *seg, Bit32u offset, unsigned len) BX_CPP_AttrRegparmN(3);
BX_SMF bx_bool write_virtual_checks(bx_segment_reg_t *seg, Bit32u offset, unsigned len, bx_bool align = BX_FALSE) BX_CPP_AttrRegparmN(4);
BX_SMF bx_bool read_virtual_checks(bx_segment_reg_t *seg, Bit32u offset, unsigned len, bx_bool align = BX_FALSE) BX_CPP_AttrRegparmN(4);
BX_SMF bx_bool execute_virtual_checks(bx_segment_reg_t *seg, Bit32u offset, unsigned len) BX_CPP_AttrRegparmN(3);
BX_SMF Bit8u read_linear_byte(unsigned seg, bx_address offset) BX_CPP_AttrRegparmN(2);
@ -4998,9 +4998,13 @@ public: // for now...
BX_SMF bx_address agen_read(unsigned seg, bx_address offset, unsigned len);
BX_SMF Bit32u agen_read32(unsigned seg, Bit32u offset, unsigned len);
BX_SMF bx_address agen_read_aligned(unsigned seg, bx_address offset, unsigned len);
BX_SMF Bit32u agen_read_aligned32(unsigned seg, Bit32u offset, unsigned len);
BX_SMF bx_address agen_write(unsigned seg, bx_address offset, unsigned len);
BX_SMF Bit32u agen_write32(unsigned seg, Bit32u offset, unsigned len);
BX_SMF bx_address agen_write_aligned(unsigned seg, bx_address offset, unsigned len);
BX_SMF Bit32u agen_write_aligned32(unsigned seg, Bit32u offset, unsigned len);
DECLARE_EFLAG_ACCESSOR (ID, 21)
DECLARE_EFLAG_ACCESSOR (VIP, 20)
@ -5388,9 +5392,6 @@ BX_CPP_INLINE Bit32u BX_CPU_C::agen_read32(unsigned s, Bit32u offset, unsigned l
if (offset <= (seg->cache.u.segment.limit_scaled-len+1)) {
return get_laddr32(s, offset);
}
// else {
// exception(int_number(s), 0);
// }
}
if (!read_virtual_checks(seg, offset, len))
@ -5399,6 +5400,26 @@ BX_CPP_INLINE Bit32u BX_CPU_C::agen_read32(unsigned s, Bit32u offset, unsigned l
return get_laddr32(s, offset);
}
BX_CPP_INLINE Bit32u BX_CPU_C::agen_read_aligned32(unsigned s, Bit32u offset, unsigned len)
{
bx_segment_reg_t *seg = &BX_CPU_THIS_PTR sregs[s];
if (seg->cache.valid & SegAccessROK4G) {
return get_laddr32(s, offset);
}
if (seg->cache.valid & SegAccessROK) {
if (offset <= (seg->cache.u.segment.limit_scaled-len+1)) {
return get_laddr32(s, offset);
}
}
if (!read_virtual_checks(seg, offset, len, true /* aligned */))
exception(int_number(s), 0);
return get_laddr32(s, offset);
}
BX_CPP_INLINE Bit32u BX_CPU_C::agen_write32(unsigned s, Bit32u offset, unsigned len)
{
bx_segment_reg_t *seg = &BX_CPU_THIS_PTR sregs[s];
@ -5411,9 +5432,6 @@ BX_CPP_INLINE Bit32u BX_CPU_C::agen_write32(unsigned s, Bit32u offset, unsigned
if (offset <= (seg->cache.u.segment.limit_scaled-len+1)) {
return get_laddr32(s, offset);
}
// else {
// exception(int_number(s), 0);
// }
}
if (!write_virtual_checks(seg, offset, len))
@ -5422,6 +5440,26 @@ BX_CPP_INLINE Bit32u BX_CPU_C::agen_write32(unsigned s, Bit32u offset, unsigned
return get_laddr32(s, offset);
}
BX_CPP_INLINE Bit32u BX_CPU_C::agen_write_aligned32(unsigned s, Bit32u offset, unsigned len)
{
bx_segment_reg_t *seg = &BX_CPU_THIS_PTR sregs[s];
if (seg->cache.valid & SegAccessWOK4G) {
return get_laddr32(s, offset);
}
if (seg->cache.valid & SegAccessWOK) {
if (offset <= (seg->cache.u.segment.limit_scaled-len+1)) {
return get_laddr32(s, offset);
}
}
if (!write_virtual_checks(seg, offset, len, true /* aligned */))
exception(int_number(s), 0);
return get_laddr32(s, offset);
}
BX_CPP_INLINE bx_address BX_CPU_C::agen_read(unsigned s, bx_address offset, unsigned len)
{
#if BX_SUPPORT_X86_64
@ -5432,6 +5470,16 @@ BX_CPP_INLINE bx_address BX_CPU_C::agen_read(unsigned s, bx_address offset, unsi
return agen_read32(s, offset, len);
}
BX_CPP_INLINE bx_address BX_CPU_C::agen_read_aligned(unsigned s, bx_address offset, unsigned len)
{
#if BX_SUPPORT_X86_64
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) {
return get_laddr64(s, offset);
}
#endif
return agen_read_aligned32(s, offset, len);
}
BX_CPP_INLINE bx_address BX_CPU_C::agen_write(unsigned s, bx_address offset, unsigned len)
{
#if BX_SUPPORT_X86_64
@ -5442,6 +5490,16 @@ BX_CPP_INLINE bx_address BX_CPU_C::agen_write(unsigned s, bx_address offset, uns
return agen_write32(s, offset, len);
}
BX_CPP_INLINE bx_address BX_CPU_C::agen_write_aligned(unsigned s, bx_address offset, unsigned len)
{
#if BX_SUPPORT_X86_64
if (BX_CPU_THIS_PTR cpu_mode == BX_MODE_LONG_64) {
return get_laddr64(s, offset);
}
#endif
return agen_write_aligned32(s, offset, len);
}
#include "access.h"
BX_CPP_INLINE Bit8u BX_CPU_C::get_reg8l(unsigned reg)