OpenOCD
nds32_tlb.c
Go to the documentation of this file.
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 
3 /***************************************************************************
4  * Copyright (C) 2013 Andes Technology *
5  * Hsiangkai Wang <hkwang@andestech.com> *
6  ***************************************************************************/
7 #ifdef HAVE_CONFIG_H
8 #include "config.h"
9 #endif
10 
11 #include "nds32_aice.h"
12 #include "nds32_tlb.h"
13 
14 int nds32_probe_tlb(struct nds32 *nds32, const target_addr_t virtual_address,
15  target_addr_t *physical_address)
16 {
17  struct target *target = nds32->target;
18  struct aice_port_s *aice = target_to_aice(target);
19 
20  return aice_read_tlb(aice, virtual_address, physical_address);
21 }
22 
24  /* 4K page */
25  {0xFFC00000, 20, 0x003FF000, 10, 0x00000FFF, 0xFFFFF000, 0xFFFFF000, 0xFFFFF000},
26  /* 8K page */
27  {0xFF000000, 22, 0x00FFE000, 11, 0x00001FFF, 0xFFFFF000, 0xFFFFE000, 0xFFFFE000},
28 };
29 
30 int nds32_walk_page_table(struct nds32 *nds32, const target_addr_t virtual_address,
31  target_addr_t *physical_address)
32 {
33  struct target *target = nds32->target;
34  uint32_t value_mr1;
35  uint32_t load_address;
36  uint32_t l1_page_table_entry;
37  uint32_t l2_page_table_entry;
38  uint32_t page_size_index = nds32->mmu_config.default_min_page_size;
39  struct page_table_walker_info_s *page_table_info_p =
40  &(page_table_info[page_size_index]);
41 
42  /* Read L1 Physical Page Table */
43  nds32_get_mapped_reg(nds32, MR1, &value_mr1);
44  load_address = (value_mr1 & page_table_info_p->l1_base_mask) |
45  ((virtual_address & page_table_info_p->l1_offset_mask) >>
46  page_table_info_p->l1_offset_shift);
47  /* load_address is physical address */
48  nds32_read_buffer(target, load_address, 4, (uint8_t *)&l1_page_table_entry);
49 
50  /* Read L2 Physical Page Table */
51  if (l1_page_table_entry & 0x1) /* L1_PTE not present */
52  return ERROR_FAIL;
53 
54  load_address = (l1_page_table_entry & page_table_info_p->l2_base_mask) |
55  ((virtual_address & page_table_info_p->l2_offset_mask) >>
56  page_table_info_p->l2_offset_shift);
57  /* load_address is physical address */
58  nds32_read_buffer(target, load_address, 4, (uint8_t *)&l2_page_table_entry);
59 
60  if ((l2_page_table_entry & 0x1) != 0x1) /* L2_PTE not valid */
61  return ERROR_FAIL;
62 
63  *physical_address = (l2_page_table_entry & page_table_info_p->ppn_mask) |
64  (virtual_address & page_table_info_p->va_offset_mask);
65 
66  return ERROR_OK;
67 }
#define ERROR_FAIL
Definition: log.h:161
#define ERROR_OK
Definition: log.h:155
int nds32_get_mapped_reg(struct nds32 *nds32, unsigned regnum, uint32_t *value)
Definition: nds32.c:513
int nds32_read_buffer(struct target *target, uint32_t address, uint32_t size, uint8_t *buffer)
Definition: nds32.c:713
static struct aice_port_s * target_to_aice(struct target *target)
Definition: nds32.h:429
int aice_read_tlb(struct aice_port_s *aice, target_addr_t virtual_address, target_addr_t *physical_address)
Definition: nds32_aice.c:34
@ MR1
Definition: nds32_reg.h:93
static struct page_table_walker_info_s page_table_info[PAGE_SIZE_NUM]
Definition: nds32_tlb.c:23
int nds32_walk_page_table(struct nds32 *nds32, const target_addr_t virtual_address, target_addr_t *physical_address)
Definition: nds32_tlb.c:30
int nds32_probe_tlb(struct nds32 *nds32, const target_addr_t virtual_address, target_addr_t *physical_address)
Definition: nds32_tlb.c:14
@ PAGE_SIZE_NUM
Definition: nds32_tlb.h:16
int default_min_page_size
Definition: nds32.h:196
Represents a generic Andes core.
Definition: nds32.h:226
struct target * target
Backpointer to the target.
Definition: nds32.h:346
struct nds32_mmu_config mmu_config
MMU configuration.
Definition: nds32.h:241
Definition: target.h:120
uint64_t target_addr_t
Definition: types.h:335