filename | src/sh4/mmux86.c |
changeset | 939:6f2302afeb89 |
next | 940:81e0d3051d5f |
author | nkeynes |
date | Sat Jan 03 03:30:26 2009 +0000 (15 years ago) |
branch | lxdream-mem |
permissions | -rw-r--r-- |
last change | MMU work-in-progress * Move SDRAM out into separate sdram.c * Move all page-table management into mmu.c * Convert UTLB management to use the new page-tables * Rip out all calls to mmu_vma_to_phys_* and replace with direct access |
file | annotate | diff | log | raw |
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +00001.2 +++ b/src/sh4/mmux86.c Sat Jan 03 03:30:26 2009 +00001.3 @@ -0,0 +1,109 @@1.4 +/**1.5 + * $Id: mmux86.c 957 2008-12-27 03:14:59Z nkeynes $1.6 + *1.7 + * x86-specific MMU code - this emits simple TLB stubs for TLB indirection.1.8 + *1.9 + * Copyright (c) 2008 Nathan Keynes.1.10 + *1.11 + * This program is free software; you can redistribute it and/or modify1.12 + * it under the terms of the GNU General Public License as published by1.13 + * the Free Software Foundation; either version 2 of the License, or1.14 + * (at your option) any later version.1.15 + *1.16 + * This program is distributed in the hope that it will be useful,1.17 + * but WITHOUT ANY WARRANTY; without even the implied warranty of1.18 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the1.19 + * GNU General Public License for more details.1.20 + */1.21 +1.22 +#include "lxdream.h"1.23 +#include "mem.h"1.24 +#include "sh4/sh4core.h"1.25 +#include "sh4/sh4mmio.h"1.26 +#include "sh4/sh4trans.h"1.27 +#include "sh4/mmu.h"1.28 +#include "sh4/x86op.h"1.29 +1.30 +#if SIZEOF_VOID_P == 81.31 +#define ARG1 R_EDI1.32 +#define ARG2 R_ESI1.33 +#define DECODE() \1.34 + MOV_imm64_r32((uintptr_t)ext_address_space, R_EAX); /* movq ptr, %rax */ \1.35 + REXW(); OP(0x8B); OP(0x0C); OP(0xC8) /* movq [%rax + %rcx*8], %rcx */1.36 +#else1.37 +#define ARG1 R_EAX1.38 +#define ARG2 R_EDX1.39 +#define DECODE() \1.40 + MOV_r32disp32x4_r32( R_ECX, (uintptr_t)ext_address_space, R_ECX );1.41 +#endif1.42 +1.43 +void mmu_utlb_init_vtable( struct utlb_entry *ent, struct utlb_page_entry *page, gboolean writable )1.44 +{1.45 + uint32_t mask = ent->mask;1.46 + uint32_t ppn = ent->ppn & mask;1.47 + int inc = writable ? 1 : 2;1.48 + int i;1.49 +1.50 + xlat_output = page->code;1.51 + uint8_t **fn = (uint8_t **)ext_address_space[ppn>>12];1.52 + uint8_t **out = (uint8_t **)&page->fn;1.53 +1.54 + for( i=0; i<8; i+= inc, fn += inc, out += inc ) {1.55 + *out = xlat_output;1.56 +#if SIZEOF_VOID_P == 81.57 + MOV_imm64_r32((uintptr_t)&mmu_urc, R_EAX );1.58 + OP(0x83); OP(0x00); OP(0x01); // ADD #1, [RAX]1.59 +#else1.60 + OP(0x83); MODRM_r32_disp32(0, (uintptr_t)&mmu_urc); OP(0x01); // ADD #1, mmu_urc1.61 +#endif1.62 + AND_imm32_r32( ~mask, ARG1 ); // 61.63 + OR_imm32_r32( ppn, ARG1 ); // 61.64 + if( ent->mask >= 0xFFFFF000 ) {1.65 + // Maps to a single page, so jump directly there1.66 + int rel = (*fn - xlat_output);1.67 + JMP_rel( rel ); // 51.68 + } else {1.69 + MOV_r32_r32( ARG1, R_ECX ); // 21.70 + SHR_imm8_r32( 12, R_ECX ); // 31.71 + DECODE(); // 141.72 + JMP_r32disp8(R_ECX, (((uintptr_t)out) - ((uintptr_t)&page->fn)) ); // 31.73 + }1.74 + }1.75 +}1.76 +1.77 +void mmu_utlb_1k_init_vtable( struct utlb_1k_entry *entry )1.78 +{1.79 + xlat_output = entry->code;1.80 + int i;1.81 + uint8_t **out = (uint8_t **)&entry->fn;1.82 +1.83 + for( i=0; i<8; i++, out++ ) {1.84 + *out = xlat_output;1.85 + MOV_r32_r32( ARG1, R_ECX );1.86 + SHR_imm8_r32( 10, R_ECX );1.87 + AND_imm8s_r32( 0x3, R_ECX );1.88 +#if SIZEOF_VOID_P == 81.89 + MOV_imm64_r32( (uintptr_t)&entry->subpages[0], R_EAX );1.90 + REXW(); OP(0x8B); OP(0x0C); OP(0xC8); /* movq [%rax + %rcx*8], %rcx */1.91 +#else1.92 + MOV_r32disp32x4_r32( R_ECX, ((uintptr_t)&entry->subpages[0]), R_ECX );1.93 +#endif1.94 + JMP_r32disp8(R_ECX, (((uintptr_t)out) - ((uintptr_t)&entry->fn)) ); // 31.95 + }1.96 +1.97 + out = (uint8_t **)&entry->user_fn;1.98 + for( i=0; i<8; i++, out++ ) {1.99 + *out = xlat_output;1.100 + MOV_r32_r32( ARG1, R_ECX );1.101 + SHR_imm8_r32( 10, R_ECX );1.102 + AND_imm8s_r32( 0x3, R_ECX );1.103 +#if SIZEOF_VOID_P == 81.104 + MOV_imm64_r32( (uintptr_t)&entry->user_subpages[0], R_EAX );1.105 + REXW(); OP(0x8B); OP(0x0C); OP(0xC8); /* movq [%rax + %rcx*8], %rcx */1.106 +#else1.107 + MOV_r32disp32x4_r32( R_ECX, ((uintptr_t)&entry->user_subpages[0]), R_ECX );1.108 +#endif1.109 + JMP_r32disp8(R_ECX, (((uintptr_t)out) - ((uintptr_t)&entry->user_fn)) ); // 31.110 + }1.111 +1.112 +}
.