diff options
author | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2003-08-08 23:58:05 +0000 |
---|---|---|
committer | bellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162> | 2003-08-08 23:58:05 +0000 |
commit | b92e5a22ec3af6e697827d388897c9ab2ddd2975 (patch) | |
tree | 4434aaf2f864c1beac2c8eee6b5a7009eac4ddea /softmmu_header.h | |
parent | 17b0018b4200b674bfcb7c946fce89f0a5ffaa24 (diff) |
Software MMU support (used for memory mapped devices such as VGA)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@347 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'softmmu_header.h')
-rw-r--r-- | softmmu_header.h | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/softmmu_header.h b/softmmu_header.h new file mode 100644 index 000000000..12306a666 --- /dev/null +++ b/softmmu_header.h @@ -0,0 +1,111 @@ +/* + * Software MMU support + * + * Copyright (c) 2003 Fabrice Bellard + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ +#if DATA_SIZE == 8 +#define SUFFIX q +#define DATA_TYPE uint64_t +#elif DATA_SIZE == 4 +#define SUFFIX l +#define DATA_TYPE uint32_t +#elif DATA_SIZE == 2 +#define SUFFIX w +#define DATA_TYPE uint16_t +#define DATA_STYPE int16_t +#elif DATA_SIZE == 1 +#define SUFFIX b +#define DATA_TYPE uint8_t +#define DATA_STYPE int8_t +#else +#error unsupported data size +#endif + +#if MEMUSER == 0 +#define MEMSUFFIX _kernel +#else +#define MEMSUFFIX _user +#endif + +#if DATA_SIZE == 8 +#define RES_TYPE uint64_t +#else +#define RES_TYPE int +#endif + + +#if MEMUSER == 0 +DATA_TYPE __attribute((regparm(1))) glue(glue(__ld, SUFFIX), _mmu)(unsigned long addr); +void __attribute((regparm(2))) glue(glue(__st, SUFFIX), _mmu)(unsigned long addr, DATA_TYPE v); +#endif + +static inline int glue(glue(ldu, SUFFIX), MEMSUFFIX)(void *ptr) +{ + int index; + RES_TYPE res; + unsigned long addr, physaddr; + addr = (unsigned long)ptr; + index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); + if (__builtin_expect(env->tlb_read[MEMUSER][index].address != + (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { + res = glue(glue(__ld, SUFFIX), _mmu)(addr); + } else { + physaddr = addr + env->tlb_read[MEMUSER][index].addend; + res = glue(glue(ldu, SUFFIX), _raw)((uint8_t *)physaddr); + } + return res; +} + +#if DATA_SIZE <= 2 +static inline int glue(glue(lds, SUFFIX), MEMSUFFIX)(void *ptr) +{ + int res, index; + unsigned long addr, physaddr; + addr = (unsigned long)ptr; + index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); + if (__builtin_expect(env->tlb_read[MEMUSER][index].address != + (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { + res = (DATA_STYPE)glue(glue(__ld, SUFFIX), _mmu)(addr); + } else { + physaddr = addr + env->tlb_read[MEMUSER][index].addend; + res = glue(glue(lds, SUFFIX), _raw)((uint8_t *)physaddr); + } + return res; +} +#endif + +static inline void glue(glue(st, SUFFIX), MEMSUFFIX)(void *ptr, RES_TYPE v) +{ + int index; + unsigned long addr, physaddr; + addr = (unsigned long)ptr; + index = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1); + if (__builtin_expect(env->tlb_write[MEMUSER][index].address != + (addr & (TARGET_PAGE_MASK | (DATA_SIZE - 1))), 0)) { + glue(glue(__st, SUFFIX), _mmu)(addr, v); + } else { + physaddr = addr + env->tlb_write[MEMUSER][index].addend; + glue(glue(st, SUFFIX), _raw)((uint8_t *)physaddr, v); + } +} + +#undef RES_TYPE +#undef DATA_TYPE +#undef DATA_STYPE +#undef SUFFIX +#undef DATA_SIZE +#undef MEMSUFFIX |