diff options
author | Max Filippov <jcmvbkbc@gmail.com> | 2012-12-05 07:15:20 +0400 |
---|---|---|
committer | Blue Swirl <blauwirbel@gmail.com> | 2012-12-08 18:48:26 +0000 |
commit | fcc803d119a4c01a9b0ee5bda35fda1eeabffa33 (patch) | |
tree | bbd6697bd198b45b2322e5b43d3ab5159e093d98 /target-xtensa/helper.c | |
parent | 536b558f5896ebbd635b57fa393e82faaa32ad52 (diff) |
target-xtensa: implement ATOMCTL SR
ATOMCTL SR controls s32c1i opcode behavior depending on targeted memory
type. See ISA, 4.3.12.4 for details.
Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
Signed-off-by: Blue Swirl <blauwirbel@gmail.com>
Diffstat (limited to 'target-xtensa/helper.c')
-rw-r--r-- | target-xtensa/helper.c | 56 |
1 files changed, 42 insertions, 14 deletions
diff --git a/target-xtensa/helper.c b/target-xtensa/helper.c index d94bae210d..ecd0182281 100644 --- a/target-xtensa/helper.c +++ b/target-xtensa/helper.c @@ -390,6 +390,7 @@ int xtensa_tlb_lookup(const CPUXtensaState *env, uint32_t addr, bool dtlb, static unsigned mmu_attr_to_access(uint32_t attr) { unsigned access = 0; + if (attr < 12) { access |= PAGE_READ; if (attr & 0x1) { @@ -398,8 +399,22 @@ static unsigned mmu_attr_to_access(uint32_t attr) if (attr & 0x2) { access |= PAGE_WRITE; } + + switch (attr & 0xc) { + case 0: + access |= PAGE_CACHE_BYPASS; + break; + + case 4: + access |= PAGE_CACHE_WB; + break; + + case 8: + access |= PAGE_CACHE_WT; + break; + } } else if (attr == 13) { - access |= PAGE_READ | PAGE_WRITE; + access |= PAGE_READ | PAGE_WRITE | PAGE_CACHE_ISOLATE; } return access; } @@ -410,14 +425,17 @@ static unsigned mmu_attr_to_access(uint32_t attr) */ static unsigned region_attr_to_access(uint32_t attr) { - unsigned access = 0; - if ((attr < 6 && attr != 3) || attr == 14) { - access |= PAGE_READ | PAGE_WRITE; - } - if (attr > 0 && attr < 6) { - access |= PAGE_EXEC; - } - return access; + static const unsigned access[16] = { + [0] = PAGE_READ | PAGE_WRITE | PAGE_CACHE_WT, + [1] = PAGE_READ | PAGE_WRITE | PAGE_EXEC | PAGE_CACHE_WT, + [2] = PAGE_READ | PAGE_WRITE | PAGE_EXEC | PAGE_CACHE_BYPASS, + [3] = PAGE_EXEC | PAGE_CACHE_WB, + [4] = PAGE_READ | PAGE_WRITE | PAGE_EXEC | PAGE_CACHE_WB, + [5] = PAGE_READ | PAGE_WRITE | PAGE_EXEC | PAGE_CACHE_WB, + [14] = PAGE_READ | PAGE_WRITE | PAGE_CACHE_ISOLATE, + }; + + return access[attr & 0xf]; } static bool is_access_granted(unsigned access, int is_write) @@ -566,7 +584,7 @@ int xtensa_get_physical_addr(CPUXtensaState *env, bool update_tlb, } else { *paddr = vaddr; *page_size = TARGET_PAGE_SIZE; - *access = PAGE_READ | PAGE_WRITE | PAGE_EXEC; + *access = PAGE_READ | PAGE_WRITE | PAGE_EXEC | PAGE_CACHE_BYPASS; return 0; } } @@ -599,24 +617,34 @@ static void dump_tlb(FILE *f, fprintf_function cpu_fprintf, xtensa_tlb_get_entry(env, dtlb, wi, ei); if (entry->asid) { + static const char * const cache_text[8] = { + [PAGE_CACHE_BYPASS >> PAGE_CACHE_SHIFT] = "Bypass", + [PAGE_CACHE_WT >> PAGE_CACHE_SHIFT] = "WT", + [PAGE_CACHE_WB >> PAGE_CACHE_SHIFT] = "WB", + [PAGE_CACHE_ISOLATE >> PAGE_CACHE_SHIFT] = "Isolate", + }; unsigned access = attr_to_access(entry->attr); + unsigned cache_idx = (access & PAGE_CACHE_MASK) >> + PAGE_CACHE_SHIFT; if (print_header) { print_header = false; cpu_fprintf(f, "Way %u (%d %s)\n", wi, sz, sz_text); cpu_fprintf(f, - "\tVaddr Paddr ASID Attr RWX\n" - "\t---------- ---------- ---- ---- ---\n"); + "\tVaddr Paddr ASID Attr RWX Cache\n" + "\t---------- ---------- ---- ---- --- -------\n"); } cpu_fprintf(f, - "\t0x%08x 0x%08x 0x%02x 0x%02x %c%c%c\n", + "\t0x%08x 0x%08x 0x%02x 0x%02x %c%c%c %-7s\n", entry->vaddr, entry->paddr, entry->asid, entry->attr, (access & PAGE_READ) ? 'R' : '-', (access & PAGE_WRITE) ? 'W' : '-', - (access & PAGE_EXEC) ? 'X' : '-'); + (access & PAGE_EXEC) ? 'X' : '-', + cache_text[cache_idx] ? cache_text[cache_idx] : + "Invalid"); } } } |