--- np2/i386c/ia32/cpu_mem.c 2012/01/08 18:26:10 1.31 +++ np2/i386c/ia32/cpu_mem.c 2012/06/18 14:30:27 1.35 @@ -31,12 +31,12 @@ /* * memory access check */ -static int MEMCALL check_limit_upstairs(descriptor_t *sdp, UINT32 offset, UINT len); +static int MEMCALL check_limit_upstairs(descriptor_t *sdp, UINT32 offset, UINT len, BOOL is32bit); static void MEMCALL cpu_memoryread_check(descriptor_t *sdp, UINT32 offset, UINT len, int e); static void MEMCALL cpu_memorywrite_check(descriptor_t *sdp, UINT32 offset, UINT len, int e); static int MEMCALL -check_limit_upstairs(descriptor_t *sdp, UINT32 offset, UINT len) +check_limit_upstairs(descriptor_t *sdp, UINT32 offset, UINT len, BOOL is32bit) { UINT32 limit; UINT32 end; @@ -46,10 +46,10 @@ check_limit_upstairs(descriptor_t *sdp, len--; end = offset + len; - limit = SEG_IS_32BIT(sdp) ? 0xffffffff : 0x0000ffff; if (SEG_IS_DATA(sdp) && SEG_IS_EXPANDDOWN_DATA(sdp)) { /* expand-down data segment */ + limit = SEG_IS_32BIT(sdp) ? 0xffffffff : 0x0000ffff; if (sdp->u.seg.limit == 0) { /* * 32bit 16bit @@ -93,37 +93,30 @@ check_limit_upstairs(descriptor_t *sdp, } } else { /* expand-up data or code segment */ - if (sdp->u.seg.limit == limit) { + if (sdp->u.seg.limit == 0xffffffff) { /* - * 32bit 16bit - * +-------+ +-------+ FFFFFFFFh - * | | | | - * | | + [1] + 0000FFFFh - * | valid | | | - * | | +-------+ 0000FFFFh - len - 1 - * | | | valid | - * +-------+ +-------+ 00000000h + * 16/32bit + * +-------+ FFFFFFFFh + * | | + * | | + * | valid | + * | | + * | | + * +-------+ 00000000h */ - if (!SEG_IS_32BIT(sdp)) { - if ((len > limit) /* len check */ - || (offset + len > limit)) { /* [1] */ - goto exc; - } - } else { - sdp->flag |= CPU_DESC_FLAG_WHOLEADR; - } + sdp->flag |= CPU_DESC_FLAG_WHOLEADR; } else { /* - * 32bit 16bit - * +-------+ +-------+ FFFFFFFFh - * | | | | - * | | +.......+ 0000FFFFh - * | [1] | | [1] | - * +.......+ +.......+ seg.limit - * | | | | - * +-------+ +-------+ seg.limit - len - 1 - * | valid | | valid | - * +-------+ +-------+ 00000000h + * 16/32bit + * +-------+ FFFFFFFFh + * | | + * | | + * | [1] | + * +.......+ seg.limit + * | | + * +-------+ seg.limit - len - 1 + * | valid | + * +-------+ 00000000h */ if ((len > sdp->u.seg.limit) /* len check */ || (end < offset) /* wrap check */ @@ -166,7 +159,7 @@ cpu_memoryread_check(descriptor_t *sdp, case 6: case 7: /* rw (expand down) */ case 10: case 11: /* rx */ case 14: case 15: /* rxc */ - if (!check_limit_upstairs(sdp, offset, len)) + if (!check_limit_upstairs(sdp, offset, len, SEG_IS_32BIT(sdp))) goto exc; break; @@ -205,7 +198,7 @@ cpu_memorywrite_check(descriptor_t *sdp, switch (sdp->type) { case 2: case 3: /* rw */ case 6: case 7: /* rw (expand down) */ - if (!check_limit_upstairs(sdp, offset, len)) + if (!check_limit_upstairs(sdp, offset, len, SEG_IS_32BIT(sdp))) goto exc; break; @@ -224,7 +217,8 @@ exc: } void MEMCALL -cpu_stack_push_check(UINT16 s, descriptor_t *sdp, UINT32 sp, UINT len) +cpu_stack_push_check(UINT16 s, descriptor_t *sdp, UINT32 sp, UINT len, + BOOL is32bit) { UINT32 limit; UINT32 start; @@ -243,7 +237,7 @@ cpu_stack_push_check(UINT16 s, descripto } start = sp - len; - limit = SEG_IS_32BIT(sdp) ? 0xffffffff : 0x0000ffff; + limit = is32bit ? 0xffffffff : 0x0000ffff; if (SEG_IS_EXPANDDOWN_DATA(sdp)) { /* expand-down stack */ @@ -342,7 +336,8 @@ exc: } void MEMCALL -cpu_stack_pop_check(UINT16 s, descriptor_t *sdp, UINT32 sp, UINT len) +cpu_stack_pop_check(UINT16 s, descriptor_t *sdp, UINT32 sp, UINT len, + BOOL is32bit) { __ASSERT(sdp != NULL); @@ -356,7 +351,7 @@ cpu_stack_pop_check(UINT16 s, descriptor goto exc; } - if (!check_limit_upstairs(sdp, sp, len)) + if (!check_limit_upstairs(sdp, sp, len, is32bit)) goto exc; return; @@ -482,85 +477,13 @@ cpu_memorywrite_f(UINT32 paddr, const RE #include "cpu_mem.mcr" -VIRTUAL_ADDRESS_MEMORY_ACCESS_FUNCTION(b, UINT8, 1) -VIRTUAL_ADDRESS_MEMORY_ACCESS_FUNCTION(w, UINT16, 2) -VIRTUAL_ADDRESS_MEMORY_ACCESS_FUNCTION(d, UINT32, 4) - -UINT64 MEMCALL -cpu_vmemoryread_q(int idx, UINT32 offset) -{ - descriptor_t *sdp; - UINT32 addr; - int exc; - - __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); - - sdp = &CPU_STAT_SREG(idx); - addr = sdp->u.seg.segbase + offset; - - if (!CPU_STAT_PM) - return cpu_memoryread_q(addr); - - if (!SEG_IS_VALID(sdp)) { - exc = GP_EXCEPTION; - goto err; - } - if (!(sdp->flag & CPU_DESC_FLAG_READABLE)) { - cpu_memoryread_check(sdp, offset, 8, CHOOSE_EXCEPTION(idx)); - } else if (!(sdp->flag & CPU_DESC_FLAG_WHOLEADR)) { - if (!check_limit_upstairs(sdp, offset, 8)) - goto range_failure; - } - return cpu_lmemoryread_q(addr, CPU_PAGE_READ_DATA | CPU_STAT_USER_MODE); - -range_failure: - VERBOSE(("cpu_vmemoryread_q: type = %d, offset = %08x, limit = %08x", sdp->type, offset, sdp->u.seg.limit)); - exc = CHOOSE_EXCEPTION(idx); -err: - EXCEPTION(exc, 0); - return 0; /* compiler happy */ -} - -void MEMCALL -cpu_vmemorywrite_q(int idx, UINT32 offset, UINT64 value) -{ - descriptor_t *sdp; - UINT32 addr; - int exc; - - __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); - - sdp = &CPU_STAT_SREG(idx); - addr = sdp->u.seg.segbase + offset; - - if (!CPU_STAT_PM) { - cpu_memorywrite_q(addr, value); - return; - } - - if (!SEG_IS_VALID(sdp)) { - exc = GP_EXCEPTION; - goto err; - } - if (!(sdp->flag & CPU_DESC_FLAG_WRITABLE)) { - cpu_memorywrite_check(sdp, offset, 8, CHOOSE_EXCEPTION(idx)); - } else if (!(sdp->flag & CPU_DESC_FLAG_WHOLEADR)) { - if (!check_limit_upstairs(sdp, offset, 8)) - goto range_failure; - } - if (!CPU_STAT_PAGING) { - cpu_memorywrite_q(addr, value); - } else { - cpu_linear_memory_write_q(addr, value, CPU_PAGE_READ_DATA | CPU_STAT_USER_MODE); - } - return; - -range_failure: - VERBOSE(("cpu_vmemorywrite_q: type = %d, offset = %08x, limit = %08x", sdp->type, offset, sdp->u.seg.limit)); - exc = CHOOSE_EXCEPTION(idx); -err: - EXCEPTION(exc, 0); -} +DECLARE_VIRTUAL_ADDRESS_MEMORY_RW_FUNCTIONS(b, UINT8, 1) +DECLARE_VIRTUAL_ADDRESS_MEMORY_RMW_FUNCTIONS(b, UINT8, 1) +DECLARE_VIRTUAL_ADDRESS_MEMORY_RW_FUNCTIONS(w, UINT16, 2) +DECLARE_VIRTUAL_ADDRESS_MEMORY_RMW_FUNCTIONS(w, UINT16, 2) +DECLARE_VIRTUAL_ADDRESS_MEMORY_RW_FUNCTIONS(d, UINT32, 4) +DECLARE_VIRTUAL_ADDRESS_MEMORY_RMW_FUNCTIONS(d, UINT32, 4) +DECLARE_VIRTUAL_ADDRESS_MEMORY_RW_FUNCTIONS(q, UINT64, 8) REG80 MEMCALL cpu_vmemoryread_f(int idx, UINT32 offset) @@ -584,12 +507,10 @@ cpu_vmemoryread_f(int idx, UINT32 offset if (!(sdp->flag & CPU_DESC_FLAG_READABLE)) { cpu_memoryread_check(sdp, offset, 10, CHOOSE_EXCEPTION(idx)); } else if (!(sdp->flag & CPU_DESC_FLAG_WHOLEADR)) { - if (!check_limit_upstairs(sdp, offset, 10)) + if (!check_limit_upstairs(sdp, offset, 10, SEG_IS_32BIT(sdp))) goto range_failure; } - if (!CPU_STAT_PAGING) - return cpu_memoryread_f(addr); - return cpu_linear_memory_read_f(addr, CPU_PAGE_READ_DATA | CPU_PAGE_READ_DATA | CPU_STAT_USER_MODE); + return cpu_lmemoryread_f(addr, CPU_PAGE_READ_DATA | CPU_STAT_USER_MODE); range_failure: VERBOSE(("cpu_vmemoryread_f: type = %d, offset = %08x, limit = %08x", sdp->type, offset, sdp->u.seg.limit)); @@ -627,14 +548,10 @@ cpu_vmemorywrite_f(int idx, UINT32 offse if (!(sdp->flag & CPU_DESC_FLAG_WRITABLE)) { cpu_memorywrite_check(sdp, offset, 10, CHOOSE_EXCEPTION(idx)); } else if (!(sdp->flag & CPU_DESC_FLAG_WHOLEADR)) { - if (!check_limit_upstairs(sdp, offset, 10)) + if (!check_limit_upstairs(sdp, offset, 10, SEG_IS_32BIT(sdp))) goto range_failure; } - if (!CPU_STAT_PAGING) { - cpu_memorywrite_f(addr, value); - } else { - cpu_linear_memory_write_f(addr, value, CPU_PAGE_WRITE_DATA | CPU_STAT_USER_MODE); - } + cpu_lmemorywrite_f(addr, value, CPU_PAGE_WRITE_DATA | CPU_STAT_USER_MODE); return; range_failure: