Commit 6fa4cea9e8e904f7aac0c3d4f73a883c9e1e53bd

Authored by j_mayer
1 parent 876d4b07

Infrastructure to support more than 2 MMU modes.

Add example for Alpha and PowerPC hypervisor mode.


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@2596 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 2 changed files with 48 additions and 1 deletions
cpu-defs.h
... ... @@ -108,6 +108,15 @@ typedef struct CPUTLBEntry {
108 108 target_phys_addr_t addend;
109 109 } CPUTLBEntry;
110 110  
  111 +/* Alpha has 4 different running levels */
  112 +#if defined(TARGET_ALPHA)
  113 +#define NB_MMU_MODES 4
  114 +#elif defined(TARGET_PPC64H) /* PowerPC 64 with hypervisor mode support */
  115 +#define NB_MMU_MODES 3
  116 +#else
  117 +#define NB_MMU_MODES 2
  118 +#endif
  119 +
111 120 #define CPU_COMMON \
112 121 struct TranslationBlock *current_tb; /* currently executing TB */ \
113 122 /* soft mmu support */ \
... ... @@ -119,7 +128,7 @@ typedef struct CPUTLBEntry {
119 128 target_ulong mem_write_vaddr; /* target virtual addr at which the \
120 129 memory was written */ \
121 130 /* 0 = kernel, 1 = user */ \
122   - CPUTLBEntry tlb_table[2][CPU_TLB_SIZE]; \
  131 + CPUTLBEntry tlb_table[NB_MMU_MODES][CPU_TLB_SIZE]; \
123 132 struct TranslationBlock *tb_jmp_cache[TB_JMP_CACHE_SIZE]; \
124 133 \
125 134 /* from this point: preserved by CPU reset */ \
... ...
... ... @@ -1300,6 +1300,16 @@ void tlb_flush(CPUState *env, int flush_global)
1300 1300 env->tlb_table[1][i].addr_read = -1;
1301 1301 env->tlb_table[1][i].addr_write = -1;
1302 1302 env->tlb_table[1][i].addr_code = -1;
  1303 +#if (NB_MMU_MODES >= 3)
  1304 + env->tlb_table[2][i].addr_read = -1;
  1305 + env->tlb_table[2][i].addr_write = -1;
  1306 + env->tlb_table[2][i].addr_code = -1;
  1307 +#if (NB_MMU_MODES == 4)
  1308 + env->tlb_table[3][i].addr_read = -1;
  1309 + env->tlb_table[3][i].addr_write = -1;
  1310 + env->tlb_table[3][i].addr_code = -1;
  1311 +#endif
  1312 +#endif
1303 1313 }
1304 1314  
1305 1315 memset (env->tb_jmp_cache, 0, TB_JMP_CACHE_SIZE * sizeof (void *));
... ... @@ -1345,6 +1355,12 @@ void tlb_flush_page(CPUState *env, target_ulong addr)
1345 1355 i = (addr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1346 1356 tlb_flush_entry(&env->tlb_table[0][i], addr);
1347 1357 tlb_flush_entry(&env->tlb_table[1][i], addr);
  1358 +#if (NB_MMU_MODES >= 3)
  1359 + tlb_flush_entry(&env->tlb_table[2][i], addr);
  1360 +#if (NB_MMU_MODES == 4)
  1361 + tlb_flush_entry(&env->tlb_table[3][i], addr);
  1362 +#endif
  1363 +#endif
1348 1364  
1349 1365 /* Discard jump cache entries for any tb which might potentially
1350 1366 overlap the flushed page. */
... ... @@ -1434,6 +1450,14 @@ void cpu_physical_memory_reset_dirty(ram_addr_t start, ram_addr_t end,
1434 1450 tlb_reset_dirty_range(&env->tlb_table[0][i], start1, length);
1435 1451 for(i = 0; i < CPU_TLB_SIZE; i++)
1436 1452 tlb_reset_dirty_range(&env->tlb_table[1][i], start1, length);
  1453 +#if (NB_MMU_MODES >= 3)
  1454 + for(i = 0; i < CPU_TLB_SIZE; i++)
  1455 + tlb_reset_dirty_range(&env->tlb_table[2][i], start1, length);
  1456 +#if (NB_MMU_MODES == 4)
  1457 + for(i = 0; i < CPU_TLB_SIZE; i++)
  1458 + tlb_reset_dirty_range(&env->tlb_table[3][i], start1, length);
  1459 +#endif
  1460 +#endif
1437 1461 }
1438 1462  
1439 1463 #if !defined(CONFIG_SOFTMMU)
... ... @@ -1486,6 +1510,14 @@ void cpu_tlb_update_dirty(CPUState *env)
1486 1510 tlb_update_dirty(&env->tlb_table[0][i]);
1487 1511 for(i = 0; i < CPU_TLB_SIZE; i++)
1488 1512 tlb_update_dirty(&env->tlb_table[1][i]);
  1513 +#if (NB_MMU_MODES >= 3)
  1514 + for(i = 0; i < CPU_TLB_SIZE; i++)
  1515 + tlb_update_dirty(&env->tlb_table[2][i]);
  1516 +#if (NB_MMU_MODES == 4)
  1517 + for(i = 0; i < CPU_TLB_SIZE; i++)
  1518 + tlb_update_dirty(&env->tlb_table[3][i]);
  1519 +#endif
  1520 +#endif
1489 1521 }
1490 1522  
1491 1523 static inline void tlb_set_dirty1(CPUTLBEntry *tlb_entry,
... ... @@ -1511,6 +1543,12 @@ static inline void tlb_set_dirty(CPUState *env,
1511 1543 i = (vaddr >> TARGET_PAGE_BITS) & (CPU_TLB_SIZE - 1);
1512 1544 tlb_set_dirty1(&env->tlb_table[0][i], addr);
1513 1545 tlb_set_dirty1(&env->tlb_table[1][i], addr);
  1546 +#if (NB_MMU_MODES >= 3)
  1547 + tlb_set_dirty1(&env->tlb_table[2][i], addr);
  1548 +#if (NB_MMU_MODES == 4)
  1549 + tlb_set_dirty1(&env->tlb_table[3][i], addr);
  1550 +#endif
  1551 +#endif
1514 1552 }
1515 1553  
1516 1554 /* add a new TLB entry. At most one entry for a given virtual address
... ...