| version 1.3, 2004/03/25 15:08:32 | version 1.5, 2008/03/22 04:03:07 | 
| Line 12 | Line 12 | 
 | * 2. Redistributions in binary form must reproduce the above copyright | * 2. Redistributions in binary form must reproduce the above copyright | 
 | *    notice, this list of conditions and the following disclaimer in the | *    notice, this list of conditions and the following disclaimer in the | 
 | *    documentation and/or other materials provided with the distribution. | *    documentation and/or other materials provided with the distribution. | 
 | * 3. The name of the author may not be used to endorse or promote products |  | 
 | *    derived from this software without specific prior written permission. |  | 
 | * | * | 
 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 
 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 
| Line 31 | Line 29 | 
 | valtype MEMCALL \ | valtype MEMCALL \ | 
 | cpu_vmemoryread_##width(int idx, UINT32 offset) \ | cpu_vmemoryread_##width(int idx, UINT32 offset) \ | 
 | { \ | { \ | 
| descriptor_t *sd; \ | descriptor_t *sdp; \ | 
 | UINT32 addr; \ | UINT32 addr; \ | 
 | int exc; \ | int exc; \ | 
 | \ | \ | 
 | __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); \ | __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); \ | 
 | \ | \ | 
| sd = &CPU_STAT_SREG(idx); \ | sdp = &CPU_STAT_SREG(idx); \ | 
| if (!sd->valid) { \ | if (!SEG_IS_VALID(sdp)) { \ | 
 | exc = GP_EXCEPTION; \ | exc = GP_EXCEPTION; \ | 
 | goto err; \ | goto err; \ | 
 | } \ | } \ | 
 | \ | \ | 
| if (!(sd->flag & CPU_DESC_FLAG_READABLE)) { \ | if (!(sdp->flag & CPU_DESC_FLAG_READABLE)) { \ | 
| cpu_memoryread_check(sd, offset, (length), \ | cpu_memoryread_check(sdp, offset, (length), \ | 
 | (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION); \ | (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION); \ | 
| } else { \ | } else if (!(sdp->flag & CPU_DESC_FLAG_WHOLEADR)) { \ | 
| switch (sd->type) { \ | if (!check_limit_upstairs(sdp, offset, (length))) \ | 
| case 4: case 5: case 6: case 7: \ | goto range_failure; \ | 
| if (offset - ((length) - 1) <= sd->u.seg.limit) \ | } \ | 
| goto range_failure; \ | addr = sdp->u.seg.segbase + offset; \ | 
| break; \ |  | 
| \ |  | 
| default: \ |  | 
| if (offset > sd->u.seg.limit - ((length) - 1)) \ |  | 
| goto range_failure; \ |  | 
| break; \ |  | 
| } \ |  | 
| }  \ |  | 
| addr = sd->u.seg.segbase + offset; \ |  | 
 | check_memory_break_point(addr, (length), CPU_DR7_RW_RO); \ | check_memory_break_point(addr, (length), CPU_DR7_RW_RO); \ | 
 | if (!CPU_STAT_PAGING) \ | if (!CPU_STAT_PAGING) \ | 
 | return cpu_memoryread_##width(addr); \ | return cpu_memoryread_##width(addr); \ | 
 | return cpu_linear_memory_read_##width(addr, CPU_PAGE_READ_DATA | CPU_STAT_USER_MODE); \ | return cpu_linear_memory_read_##width(addr, CPU_PAGE_READ_DATA | CPU_STAT_USER_MODE); \ | 
 | \ | \ | 
 | range_failure: \ | range_failure: \ | 
| if (idx == CPU_SS_INDEX) { \ | VERBOSE(("cpu_vmemoryread_" #width ": type = %d, offset = %08x, length = %d, limit = %08x", sdp->type, offset, length, sdp->u.seg.limit)); \ | 
| exc = SS_EXCEPTION; \ | exc = (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION; \ | 
| } else { \ |  | 
| exc = GP_EXCEPTION; \ |  | 
| } \ |  | 
| VERBOSE(("cpu_vmemoryread: type = %d, offset = %08x, length = %d, limit = %08x", sd->type, offset, length, sd->u.seg.limit)); \ |  | 
 | err: \ | err: \ | 
 | EXCEPTION(exc, 0); \ | EXCEPTION(exc, 0); \ | 
 | return 0;       /* compiler happy */ \ | return 0;       /* compiler happy */ \ | 
| Line 80  err: \ | Line 65  err: \ | 
 | void MEMCALL \ | void MEMCALL \ | 
 | cpu_vmemorywrite_##width(int idx, UINT32 offset, valtype value) \ | cpu_vmemorywrite_##width(int idx, UINT32 offset, valtype value) \ | 
 | { \ | { \ | 
| descriptor_t *sd; \ | descriptor_t *sdp; \ | 
 | UINT32 addr; \ | UINT32 addr; \ | 
 | int exc; \ | int exc; \ | 
 | \ | \ | 
 | __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); \ | __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); \ | 
 | \ | \ | 
| sd = &CPU_STAT_SREG(idx); \ | sdp = &CPU_STAT_SREG(idx); \ | 
| if (!sd->valid) { \ | if (!SEG_IS_VALID(sdp)) { \ | 
 | exc = GP_EXCEPTION; \ | exc = GP_EXCEPTION; \ | 
 | goto err; \ | goto err; \ | 
 | } \ | } \ | 
 | \ | \ | 
| if (!(sd->flag & CPU_DESC_FLAG_WRITABLE)) { \ | if (!(sdp->flag & CPU_DESC_FLAG_WRITABLE)) { \ | 
| cpu_memorywrite_check(sd, offset, (length), \ | cpu_memorywrite_check(sdp, offset, (length), \ | 
 | (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION); \ | (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION); \ | 
| } else { \ | } else if (!(sdp->flag & CPU_DESC_FLAG_WHOLEADR)) { \ | 
| switch (sd->type) { \ | if (!check_limit_upstairs(sdp, offset, (length))) \ | 
| case 6: case 7: \ | goto range_failure; \ | 
| if (offset - ((length) - 1) <= sd->u.seg.limit) \ |  | 
| goto range_failure; \ |  | 
| break; \ |  | 
| \ |  | 
| default: \ |  | 
| if (offset > sd->u.seg.limit - ((length) - 1)) \ |  | 
| goto range_failure; \ |  | 
| break; \ |  | 
| } \ |  | 
 | } \ | } \ | 
| addr = sd->u.seg.segbase + offset; \ | addr = sdp->u.seg.segbase + offset; \ | 
 | check_memory_break_point(addr, (length), CPU_DR7_RW_RW); \ | check_memory_break_point(addr, (length), CPU_DR7_RW_RW); \ | 
 | if (!CPU_STAT_PAGING) { \ | if (!CPU_STAT_PAGING) { \ | 
 | cpu_memorywrite_##width(addr, value); \ | cpu_memorywrite_##width(addr, value); \ | 
| Line 118  cpu_vmemorywrite_##width(int idx, UINT32 | Line 94  cpu_vmemorywrite_##width(int idx, UINT32 | 
 | return; \ | return; \ | 
 | \ | \ | 
 | range_failure: \ | range_failure: \ | 
| if (idx == CPU_SS_INDEX) { \ | VERBOSE(("cpu_vmemorywrite_" #width ": type = %d, offset = %08x, length = %d, limit = %08x", sdp->type, offset, length, sdp->u.seg.limit)); \ | 
| exc = SS_EXCEPTION; \ | exc = (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION; \ | 
| } else { \ |  | 
| exc = GP_EXCEPTION; \ |  | 
| } \ |  | 
| VERBOSE(("cpu_vmemorywrite: type = %d, offset = %08x, length = %d, limit = %08x", sd->type, offset, length, sd->u.seg.limit)); \ |  | 
 | err: \ | err: \ | 
 | EXCEPTION(exc, 0); \ | EXCEPTION(exc, 0); \ | 
 | } \ | } \ | 
| Line 131  err: \ | Line 103  err: \ | 
 | UINT32 MEMCALL \ | UINT32 MEMCALL \ | 
 | cpu_memory_access_va_RMW_##width(int idx, UINT32 offset, UINT32 (*func)(UINT32, void *), void *arg) \ | cpu_memory_access_va_RMW_##width(int idx, UINT32 offset, UINT32 (*func)(UINT32, void *), void *arg) \ | 
 | { \ | { \ | 
| descriptor_t *sd; \ | descriptor_t *sdp; \ | 
 | UINT32 addr; \ | UINT32 addr; \ | 
 | UINT32 res, dst; \ | UINT32 res, dst; \ | 
 | int exc; \ | int exc; \ | 
 | \ | \ | 
 | __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); \ | __ASSERT((unsigned int)idx < CPU_SEGREG_NUM); \ | 
 | \ | \ | 
| sd = &CPU_STAT_SREG(idx); \ | sdp = &CPU_STAT_SREG(idx); \ | 
| if (!sd->valid) { \ | if (!SEG_IS_VALID(sdp)) { \ | 
 | exc = GP_EXCEPTION; \ | exc = GP_EXCEPTION; \ | 
 | goto err; \ | goto err; \ | 
 | } \ | } \ | 
 | \ | \ | 
| if (!(sd->flag & CPU_DESC_FLAG_WRITABLE)) { \ | if (!(sdp->flag & CPU_DESC_FLAG_WRITABLE)) { \ | 
| cpu_memorywrite_check(sd, offset, (length), \ | cpu_memorywrite_check(sdp, offset, (length), \ | 
 | (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION); \ | (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION); \ | 
| } else { \ | } else if (!(sdp->flag & CPU_DESC_FLAG_WHOLEADR)) { \ | 
| switch (sd->type) { \ | if (!check_limit_upstairs(sdp, offset, (length))) \ | 
| case 6: case 7: \ | goto range_failure; \ | 
| if (offset - ((length) - 1) <= sd->u.seg.limit) \ |  | 
| goto range_failure; \ |  | 
| break; \ |  | 
| \ |  | 
| default: \ |  | 
| if (offset > sd->u.seg.limit - ((length) - 1)) \ |  | 
| goto range_failure; \ |  | 
| break; \ |  | 
| } \ |  | 
 | } \ | } \ | 
| addr = sd->u.seg.segbase + offset; \ | addr = sdp->u.seg.segbase + offset; \ | 
 | check_memory_break_point(addr, (length), CPU_DR7_RW_RW); \ | check_memory_break_point(addr, (length), CPU_DR7_RW_RW); \ | 
 | if (!CPU_STAT_PAGING) { \ | if (!CPU_STAT_PAGING) { \ | 
 | dst = cpu_memoryread_##width(addr); \ | dst = cpu_memoryread_##width(addr); \ | 
| Line 172  cpu_memory_access_va_RMW_##width(int idx | Line 135  cpu_memory_access_va_RMW_##width(int idx | 
 | return dst; \ | return dst; \ | 
 | \ | \ | 
 | range_failure: \ | range_failure: \ | 
| if (idx == CPU_SS_INDEX) { \ | VERBOSE(("cpu_memory_access_va_RMW_" #width ": type = %d, offset = %08x, length = %d, limit = %08x", sdp->type, offset, length, sdp->u.seg.limit)); \ | 
| exc = SS_EXCEPTION; \ | exc = (idx == CPU_SS_INDEX) ? SS_EXCEPTION : GP_EXCEPTION; \ | 
| } else { \ |  | 
| exc = GP_EXCEPTION; \ |  | 
| } \ |  | 
| VERBOSE(("cpu_memory_access_va_RMW: type = %d, offset = %08x, length = %d, limit = %08x", sd->type, offset, length, sd->u.seg.limit)); \ |  | 
 | err: \ | err: \ | 
 | EXCEPTION(exc, 0); \ | EXCEPTION(exc, 0); \ | 
 | return 0;       /* compiler happy */ \ | return 0;       /* compiler happy */ \ |