linux-headers/arch/e2k/include/asm/tlb_regs_access.h

155 lines
3.7 KiB
C

#ifndef _E2K_TLB_REGS_ACCESS_H_
#define _E2K_TLB_REGS_ACCESS_H_
#include <asm/tlb_regs_types.h>
#include <asm/mmu_regs_access.h>
/*
* DTLB/ITLB registers operations
*/
/*
* Write Data TLB tag register
*/
static inline void
write_DTLB_tag_reg(tlb_addr_t tlb_addr, tlb_tag_t tlb_tag)
{
DebugMR("Write DTLB addr 0x%lx tag 0x%lx\n",
tlb_addr_val(tlb_addr), tlb_tag_val(tlb_tag));
WRITE_DTLB_REG(tlb_addr_val(tlb_addr), tlb_tag_val(tlb_tag));
}
/*
* Write Data TLB entry register
*/
static inline void
write_DTLB_entry_reg(tlb_addr_t tlb_addr, mmu_reg_t pte)
{
DebugMR("Write DTLB addr 0x%lx entry 0x%llx\n",
tlb_addr_val(tlb_addr), pte);
WRITE_DTLB_REG(tlb_addr_val(tlb_addr), pte);
}
/*
* Read Data TLB tag register
*/
static inline tlb_tag_t
read_DTLB_tag_reg(tlb_addr_t tlb_addr)
{
tlb_tag_t tlb_tag;
tlb_tag_val(tlb_tag) = READ_DTLB_REG(tlb_addr_val(tlb_addr));
DebugTLB("Read DTLB tag 0x%lx for addr 0x%lx\n",
tlb_tag_val(tlb_tag), tlb_addr_val(tlb_addr));
return tlb_tag;
}
static inline tlb_tag_t
read_DTLB_va_tag_reg(e2k_addr_t virt_addr, int set_num, int large_page)
{
tlb_addr_t tlb_addr;
tlb_addr = tlb_addr_tag_access;
tlb_addr = tlb_addr_set_vaddr_line_num(tlb_addr, virt_addr,
large_page);
tlb_addr = tlb_addr_set_set_num(tlb_addr, set_num);
return read_DTLB_tag_reg(tlb_addr);
}
/*
* Read Data TLB entry register
*/
static inline mmu_reg_t
read_DTLB_entry_reg(tlb_addr_t tlb_addr)
{
mmu_reg_t pte;
pte = READ_DTLB_REG(tlb_addr_val(tlb_addr));
DebugTLB("Read DTLB entry 0x%llx for addr 0x%lx\n",
pte, tlb_addr_val(tlb_addr));
return pte;
}
static inline mmu_reg_t
read_DTLB_va_entry_reg(e2k_addr_t virt_addr, int set_num, int large_page)
{
tlb_addr_t tlb_addr;
tlb_addr = tlb_addr_entry_access;
tlb_addr = tlb_addr_set_vaddr_line_num(tlb_addr, virt_addr,
large_page);
tlb_addr = tlb_addr_set_set_num(tlb_addr, set_num);
return read_DTLB_entry_reg(tlb_addr);
}
/*
* Get Entry probe for virtual address
*/
#define GET_MMU_DTLB_ENTRY(virt_addr) \
(unsigned long)ENTRY_PROBE_MMU_OP(probe_addr_val(virt_addr))
static inline probe_entry_t
get_MMU_DTLB_ENTRY(e2k_addr_t virt_addr)
{
DebugMR("Get DTLB entry probe for virtual address 0x%lx\n",
virt_addr);
return __probe_entry(GET_MMU_DTLB_ENTRY(virt_addr));
}
/*
* Get physical address for virtual address
*/
#define GET_MMU_PHYS_ADDR(virt_addr) \
((unsigned long)ADDRESS_PROBE_MMU_OP(probe_addr_val(virt_addr)))
static inline probe_entry_t
get_MMU_phys_addr(e2k_addr_t virt_addr)
{
DebugMR("Get physical address for virtual address 0x%lx\n",
virt_addr);
return __probe_entry(GET_MMU_PHYS_ADDR(virt_addr));
}
typedef struct tlb_set_state {
tlb_tag_t tlb_tag;
pte_t tlb_entry;
} tlb_set_state_t;
typedef struct tlb_line_state {
e2k_addr_t va;
bool huge;
tlb_set_state_t sets[NATIVE_TLB_SETS_NUM];
} tlb_line_state_t;
static inline tlb_tag_t
get_va_tlb_set_tag(e2k_addr_t addr, int set_no, bool large_page)
{
return read_DTLB_va_tag_reg(addr, set_no, large_page);
}
static inline pte_t
get_va_tlb_set_entry(e2k_addr_t addr, int set_no, bool large_page)
{
pte_t tlb_entry;
pte_val(tlb_entry) = read_DTLB_va_entry_reg(addr, set_no, large_page);
return tlb_entry;
}
static inline void
get_va_tlb_state(tlb_line_state_t *tlb, e2k_addr_t addr, bool large_page)
{
tlb_set_state_t *set_state;
int set_no;
tlb->va = addr;
tlb->huge = large_page;
for (set_no = 0; set_no < NATIVE_TLB_SETS_NUM; set_no++) {
tlb_tag_t tlb_tag;
pte_t tlb_entry;
set_state = &tlb->sets[set_no];
tlb_tag = get_va_tlb_set_tag(addr, set_no, large_page);
tlb_entry = get_va_tlb_set_entry(addr, set_no, large_page);
set_state->tlb_tag = tlb_tag;
set_state->tlb_entry = tlb_entry;
}
}
#endif /* !_E2K_TLB_REGS_ACCESS_H_ */