|
|
| version 1.33, 2012/01/08 19:09:40 | version 1.35, 2012/06/18 14:30:27 |
|---|---|
| Line 31 | Line 31 |
| /* | /* |
| * memory access check | * 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_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 void MEMCALL cpu_memorywrite_check(descriptor_t *sdp, UINT32 offset, UINT len, int e); |
| static int MEMCALL | 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 limit; |
| UINT32 end; | UINT32 end; |
| 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 166 cpu_memoryread_check(descriptor_t *sdp, | Line 159 cpu_memoryread_check(descriptor_t *sdp, |
| case 6: case 7: /* rw (expand down) */ | case 6: case 7: /* rw (expand down) */ |
| case 10: case 11: /* rx */ | case 10: case 11: /* rx */ |
| case 14: case 15: /* rxc */ | 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; | goto exc; |
| break; | break; |
| Line 205 cpu_memorywrite_check(descriptor_t *sdp, | Line 198 cpu_memorywrite_check(descriptor_t *sdp, |
| switch (sdp->type) { | switch (sdp->type) { |
| case 2: case 3: /* rw */ | case 2: case 3: /* rw */ |
| case 6: case 7: /* rw (expand down) */ | 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; | goto exc; |
| break; | break; |
| Line 224 exc: | Line 217 exc: |
| } | } |
| void MEMCALL | 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 limit; |
| UINT32 start; | UINT32 start; |
| Line 243 cpu_stack_push_check(UINT16 s, descripto | Line 237 cpu_stack_push_check(UINT16 s, descripto |
| } | } |
| start = sp - len; | start = sp - len; |
| limit = SEG_IS_32BIT(sdp) ? 0xffffffff : 0x0000ffff; | limit = is32bit ? 0xffffffff : 0x0000ffff; |
| if (SEG_IS_EXPANDDOWN_DATA(sdp)) { | if (SEG_IS_EXPANDDOWN_DATA(sdp)) { |
| /* expand-down stack */ | /* expand-down stack */ |
| Line 342 exc: | Line 336 exc: |
| } | } |
| void MEMCALL | 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); | __ASSERT(sdp != NULL); |
| Line 356 cpu_stack_pop_check(UINT16 s, descriptor | Line 351 cpu_stack_pop_check(UINT16 s, descriptor |
| goto exc; | goto exc; |
| } | } |
| if (!check_limit_upstairs(sdp, sp, len)) | if (!check_limit_upstairs(sdp, sp, len, is32bit)) |
| goto exc; | goto exc; |
| return; | return; |
| Line 512 cpu_vmemoryread_f(int idx, UINT32 offset | Line 507 cpu_vmemoryread_f(int idx, UINT32 offset |
| if (!(sdp->flag & CPU_DESC_FLAG_READABLE)) { | if (!(sdp->flag & CPU_DESC_FLAG_READABLE)) { |
| cpu_memoryread_check(sdp, offset, 10, CHOOSE_EXCEPTION(idx)); | cpu_memoryread_check(sdp, offset, 10, CHOOSE_EXCEPTION(idx)); |
| } else if (!(sdp->flag & CPU_DESC_FLAG_WHOLEADR)) { | } 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; | goto range_failure; |
| } | } |
| return cpu_lmemoryread_f(addr, CPU_PAGE_READ_DATA | CPU_STAT_USER_MODE); | return cpu_lmemoryread_f(addr, CPU_PAGE_READ_DATA | CPU_STAT_USER_MODE); |
| Line 553 cpu_vmemorywrite_f(int idx, UINT32 offse | Line 548 cpu_vmemorywrite_f(int idx, UINT32 offse |
| if (!(sdp->flag & CPU_DESC_FLAG_WRITABLE)) { | if (!(sdp->flag & CPU_DESC_FLAG_WRITABLE)) { |
| cpu_memorywrite_check(sdp, offset, 10, CHOOSE_EXCEPTION(idx)); | cpu_memorywrite_check(sdp, offset, 10, CHOOSE_EXCEPTION(idx)); |
| } else if (!(sdp->flag & CPU_DESC_FLAG_WHOLEADR)) { | } 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; | goto range_failure; |
| } | } |
| cpu_lmemorywrite_f(addr, value, CPU_PAGE_WRITE_DATA | CPU_STAT_USER_MODE); | cpu_lmemorywrite_f(addr, value, CPU_PAGE_WRITE_DATA | CPU_STAT_USER_MODE); |