|
|
| version 1.32, 2012/01/08 18:49:31 | version 1.34, 2012/02/05 22:19:47 |
|---|---|
| Line 46 check_limit_upstairs(descriptor_t *sdp, | Line 46 check_limit_upstairs(descriptor_t *sdp, |
| len--; | len--; |
| end = offset + len; | end = offset + len; |
| limit = SEG_IS_32BIT(sdp) ? 0xffffffff : 0x0000ffff; | |
| if (SEG_IS_DATA(sdp) && SEG_IS_EXPANDDOWN_DATA(sdp)) { | if (SEG_IS_DATA(sdp) && SEG_IS_EXPANDDOWN_DATA(sdp)) { |
| /* expand-down data segment */ | /* expand-down data segment */ |
| limit = SEG_IS_32BIT(sdp) ? 0xffffffff : 0x0000ffff; | |
| if (sdp->u.seg.limit == 0) { | if (sdp->u.seg.limit == 0) { |
| /* | /* |
| * 32bit 16bit | * 32bit 16bit |
| Line 93 check_limit_upstairs(descriptor_t *sdp, | Line 93 check_limit_upstairs(descriptor_t *sdp, |
| } | } |
| } else { | } else { |
| /* expand-up data or code segment */ | /* expand-up data or code segment */ |
| if (sdp->u.seg.limit == limit) { | if (sdp->u.seg.limit == 0xffffffff) { |
| /* | /* |
| * 32bit 16bit | * 16/32bit |
| * +-------+ +-------+ FFFFFFFFh | * +-------+ FFFFFFFFh |
| * | | | | | * | | |
| * | | + [1] + 0000FFFFh | * | | |
| * | valid | | | | * | valid | |
| * | | +-------+ 0000FFFFh - len - 1 | * | | |
| * | | | valid | | * | | |
| * +-------+ +-------+ 00000000h | * +-------+ 00000000h |
| */ | */ |
| if (!SEG_IS_32BIT(sdp)) { | sdp->flag |= CPU_DESC_FLAG_WHOLEADR; |
| if ((len > limit) /* len check */ | |
| || (offset + len > limit)) { /* [1] */ | |
| goto exc; | |
| } | |
| } else { | |
| sdp->flag |= CPU_DESC_FLAG_WHOLEADR; | |
| } | |
| } else { | } else { |
| /* | /* |
| * 32bit 16bit | * 16/32bit |
| * +-------+ +-------+ FFFFFFFFh | * +-------+ FFFFFFFFh |
| * | | | | | * | | |
| * | | +.......+ 0000FFFFh | * | | |
| * | [1] | | [1] | | * | [1] | |
| * +.......+ +.......+ seg.limit | * +.......+ seg.limit |
| * | | | | | * | | |
| * +-------+ +-------+ seg.limit - len - 1 | * +-------+ seg.limit - len - 1 |
| * | valid | | valid | | * | valid | |
| * +-------+ +-------+ 00000000h | * +-------+ 00000000h |
| */ | */ |
| if ((len > sdp->u.seg.limit) /* len check */ | if ((len > sdp->u.seg.limit) /* len check */ |
| || (end < offset) /* wrap check */ | || (end < offset) /* wrap check */ |
| Line 482 cpu_memorywrite_f(UINT32 paddr, const RE | Line 475 cpu_memorywrite_f(UINT32 paddr, const RE |
| #include "cpu_mem.mcr" | #include "cpu_mem.mcr" |
| VIRTUAL_ADDRESS_MEMORY_ACCESS_FUNCTION(b, UINT8, 1) | DECLARE_VIRTUAL_ADDRESS_MEMORY_RW_FUNCTIONS(b, UINT8, 1) |
| VIRTUAL_ADDRESS_MEMORY_ACCESS_FUNCTION(w, UINT16, 2) | DECLARE_VIRTUAL_ADDRESS_MEMORY_RMW_FUNCTIONS(b, UINT8, 1) |
| VIRTUAL_ADDRESS_MEMORY_ACCESS_FUNCTION(d, UINT32, 4) | DECLARE_VIRTUAL_ADDRESS_MEMORY_RW_FUNCTIONS(w, UINT16, 2) |
| DECLARE_VIRTUAL_ADDRESS_MEMORY_RMW_FUNCTIONS(w, UINT16, 2) | |
| UINT64 MEMCALL | DECLARE_VIRTUAL_ADDRESS_MEMORY_RW_FUNCTIONS(d, UINT32, 4) |
| cpu_vmemoryread_q(int idx, UINT32 offset) | DECLARE_VIRTUAL_ADDRESS_MEMORY_RMW_FUNCTIONS(d, UINT32, 4) |
| { | DECLARE_VIRTUAL_ADDRESS_MEMORY_RW_FUNCTIONS(q, UINT64, 8) |
| 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; | |
| } | |
| cpu_lmemorywrite_q(addr, value, CPU_PAGE_WRITE_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); | |
| } | |
| REG80 MEMCALL | REG80 MEMCALL |
| cpu_vmemoryread_f(int idx, UINT32 offset) | cpu_vmemoryread_f(int idx, UINT32 offset) |