|
|
| version 1.3, 2004/03/25 15:08:32 | version 1.6, 2011/01/15 17:17:23 |
|---|---|
| Line 1 | Line 1 |
| /* $Id$ */ | |
| /* | /* |
| * Copyright (c) 2004 NONAKA Kimihiro | * Copyright (c) 2004 NONAKA Kimihiro |
| * All rights reserved. | * All rights reserved. |
| Line 12 | Line 10 |
| * 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 27 |
| 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 63 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 92 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 101 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 133 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 */ \ |