Fabian 6 tahun lalu
induk
melakukan
76343ce3c8
3 mengubah file dengan 32 tambahan dan 21 penghapusan
  1. 22 20
      src/native/cpu.c
  2. 10 0
      src/native/cpu.h
  3. 0 1
      src/native/js_imports.h

+ 22 - 20
src/native/cpu.c

@@ -27,7 +27,6 @@ uint32_t jit_jump = 0;
 int32_t hot_code_addresses[HASH_PRIME] = {0};
 uint32_t group_dirtiness[GROUP_DIRTINESS_LENGTH] = {0};
 
-#define VALID_TLB_ENTRY_MAX 10000
 int32_t valid_tlb_entries[VALID_TLB_ENTRY_MAX] = {0};
 int32_t valid_tlb_entries_count = 0;
 
@@ -260,7 +259,6 @@ int32_t do_page_translation(int32_t addr, bool for_writing, bool user)
             if(valid_tlb_entries_count > VALID_TLB_ENTRY_MAX * 3 / 4)
             {
                 profiler_stat_increment(S_TLB_GLOBAL_FULL);
-                dbg_log("full clear tlb due to more than half the tlb being filled with global pages after clear_tlb()");
                 full_clear_tlb();
             }
         }
@@ -269,7 +267,13 @@ int32_t do_page_translation(int32_t addr, bool for_writing, bool user)
     }
 
     // TODO: Consider if cr0.wp is not set
-    int32_t info_bits = !can_write << 0 | !allow_user << 1 | in_mapped_range(high) << 2 | 1 << 3 | (global && (cr[4] & CR4_PGE)) << 4;
+
+    int32_t info_bits =
+        TLB_VALID |
+        (can_write ? 0 : TLB_READONLY) |
+        (allow_user ? 0 : TLB_NO_USER) |
+        (in_mapped_range(high) ? TLB_IN_MAPPED_RANGE : 0) |
+        (global && (cr[4] & CR4_PGE) ? TLB_GLOBAL : 0);
 
     tlb_data[page] = high ^ page << 12 | info_bits;
 
@@ -287,8 +291,8 @@ void writable_or_pagefault(int32_t addr, int32_t size)
     }
 
     bool user = cpl[0] == 3 ? true : false;
-    int32_t mask = 1 << 3 | 1 << 0 | user << 1;
-    int32_t expect = 1 << 3 | 0 << 0 | 0 << 1;
+    int32_t mask = TLB_READONLY | TLB_VALID | (user ? TLB_NO_USER : 0);
+    int32_t expect = TLB_VALID;
     int32_t page = (uint32_t)addr >> 12;
 
     if((tlb_data[page] & mask) == expect)
@@ -313,13 +317,13 @@ uint32_t translate_address_read(int32_t address)
     int32_t base = (uint32_t)address >> 12;
     int32_t entry = tlb_data[base];
     bool user = cpl[0] == 3 ? true : false;
-    if((entry & (1 << 3 | user << 1)) == (1 << 3 | 0 << 1))
+    if((entry & (TLB_VALID | (user ? TLB_NO_USER : 0))) == TLB_VALID)
     {
         return entry & ~0xFFF ^ address;
     }
     else
     {
-        return do_page_translation(address, false, *cpl == 3) | address & 0xFFF;
+        return do_page_translation(address, false, user) | address & 0xFFF;
     }
 }
 
@@ -330,13 +334,13 @@ uint32_t translate_address_write(int32_t address)
     int32_t base = (uint32_t)address >> 12;
     int32_t entry = tlb_data[base];
     bool user = cpl[0] == 3 ? true : false;
-    if((entry & (1 << 3 | user << 1 | 1 << 0)) == (1 << 3 | 0 << 1 | 0 << 0))
+    if((entry & (TLB_VALID | (user ? TLB_NO_USER : 0) | TLB_READONLY)) == TLB_VALID)
     {
         return entry & ~0xFFF ^ address;
     }
     else
     {
-        return do_page_translation(address, true, *cpl == 3) | address & 0xFFF;
+        return do_page_translation(address, true, user) | address & 0xFFF;
     }
 }
 
@@ -346,7 +350,7 @@ uint32_t translate_address_system_read(int32_t address)
 
     int32_t base = (uint32_t)address >> 12;
     int32_t entry = tlb_data[base];
-    if(entry & 1 << 3)
+    if(entry & TLB_VALID)
     {
         return entry & ~0xFFF ^ address;
     }
@@ -362,7 +366,7 @@ uint32_t translate_address_system_write(int32_t address)
 
     int32_t base = (uint32_t)address >> 12;
     int32_t entry = tlb_data[base];
-    if((entry & (1 << 3 | 1 << 0)) == (1 << 3 | 0 << 0))
+    if((entry & (TLB_VALID | TLB_READONLY)) == TLB_VALID)
     {
         return entry & ~0xFFF ^ address;
     }
@@ -1167,17 +1171,16 @@ int32_t safe_read32s(int32_t address)
 {
 #if 1
     int32_t base = (uint32_t)address >> 12;
-    int32_t entry = tlb_data[base] & ~0x001;
-    int32_t info_bits = entry & 0xFFF;
+    int32_t entry = tlb_data[base];
+    int32_t info_bits = entry & 0xFFF & ~TLB_READONLY & ~TLB_GLOBAL;
 
     // XXX: Paging check
 
-    if(info_bits == (1 << 3) && (address & 0xFFF) <= (0x1000 - 4))
+    if(info_bits == TLB_VALID && (address & 0xFFF) <= (0x1000 - 4))
     {
         // - not in memory mapped area
         // - can be accessed from any cpl
 
-        assert((entry & 0xFFF) == (1 << 3));
         uint32_t phys_address = entry & ~0xFFF ^ address;
         assert(!in_mapped_range(phys_address));
         return *(int32_t*)(mem8 + phys_address);
@@ -1264,17 +1267,16 @@ void safe_write32(int32_t address, int32_t value)
 #if 1
     int32_t base = (uint32_t)address >> 12;
     int32_t entry = tlb_data[base];
-    int32_t info_bits = entry & 0xFFF;
+    int32_t info_bits = entry & 0xFFF & ~TLB_GLOBAL;
 
     // XXX: Paging check
 
-    if(info_bits == (1 << 3) && (address & 0xFFF) <= (0x1000 - 4))
+    if(info_bits == TLB_VALID && (address & 0xFFF) <= (0x1000 - 4))
     {
         // - allowed to write in user-mode
         // - not in memory mapped area
         // - can be accessed from any cpl
 
-        assert((entry & 0xFFF) == (1 << 3));
         uint32_t phys_address = entry & ~0xFFF ^ address;
         jit_dirty_cache_single(phys_address);
         assert(!in_mapped_range(phys_address));
@@ -1430,7 +1432,7 @@ void clear_tlb()
         int32_t page = valid_tlb_entries[i];
         int32_t entry = tlb_data[page];
 
-        if(entry & 1 << 4)
+        if(entry & TLB_GLOBAL)
         {
             // reinsert at the front
             valid_tlb_entries[global_page_offset++] = page;
@@ -1446,7 +1448,7 @@ void clear_tlb()
 #if 1
     for(int32_t i = 0; i < 0x100000; i++)
     {
-        assert(tlb_data[i] == 0 || (tlb_data[i] & 1 << 4) == (1 << 4));
+        assert(tlb_data[i] == 0 || (tlb_data[i] & TLB_GLOBAL));
     }
 #endif
 }

+ 10 - 0
src/native/cpu.h

@@ -69,6 +69,15 @@ extern int32_t hot_code_addresses[HASH_PRIME];
 // to the same group due to the shift
 extern uint32_t group_dirtiness[GROUP_DIRTINESS_LENGTH];
 
+#define VALID_TLB_ENTRY_MAX 10000
+int32_t valid_tlb_entries[VALID_TLB_ENTRY_MAX];
+int32_t valid_tlb_entries_count;
+
+#define TLB_VALID (1 << 0)
+#define TLB_READONLY (1 << 1)
+#define TLB_NO_USER (1 << 2)
+#define TLB_IN_MAPPED_RANGE (1 << 3)
+#define TLB_GLOBAL (1 << 4)
 
 // defined in call-indirect.ll
 extern void call_indirect(int32_t index);
@@ -144,6 +153,7 @@ void write_xmm64(int32_t r, union reg64 data);
 void write_xmm128(int32_t r, int32_t i0, int32_t i1, int32_t i2, int32_t i3);
 void write_xmm_reg128(int32_t r, union reg128 data);
 void clear_tlb(void);
+void full_clear_tlb(void);
 void task_switch_test(void);
 void task_switch_test_mmx(void);
 int32_t read_moffs(void);

+ 0 - 1
src/native/js_imports.h

@@ -30,7 +30,6 @@ extern void enter16(int32_t, int32_t);
 extern void enter32(int32_t, int32_t);
 extern void far_jump(int32_t, int32_t, int32_t);
 extern void far_return(int32_t, int32_t, int32_t);
-extern void full_clear_tlb(void);
 extern void handle_irqs(void);
 extern void hlt_op(void);
 extern void invlpg(int32_t);