Changeset 10ef708 in rtems


Ignore:
Timestamp:
07/14/22 23:10:45 (20 months ago)
Author:
Kinsey Moore <kinsey.moore@…>
Branches:
master
Children:
e584ee4
Parents:
6d4b390
git-author:
Kinsey Moore <kinsey.moore@…> (07/14/22 23:10:45)
git-committer:
Joel Sherrill <joel@…> (07/21/22 17:26:35)
Message:

aarch64: Use page table level 0

This alters the AArch64 page table generation and mapping code and MMU
configuration to use page table level 0 in addition to levels 1, 2, and

  1. This allows the mapping of up to 48 bits of memory space and is the

maximum that can be mapped without relying on additional processor
extensions. Mappings are restricted based on the number of physical
address bits that the CPU supports.

Files:
4 edited

Legend:

Unmodified
Added
Removed
  • bsps/aarch64/include/bsp/aarch64-mmu.h

    r6d4b390 r10ef708  
    3838#define LIBBSP_AARCH64_SHARED_AARCH64_MMU_H
    3939
     40#include <bsp/fatal.h>
     41#include <bsp/linker-symbols.h>
    4042#include <bsp/start.h>
    41 #include <bsp/linker-symbols.h>
     43#include <bsp/utility.h>
     44#include <bspopts.h>
     45#include <libcpu/mmu-vmsav8-64.h>
    4246#include <rtems/score/aarch64-system-registers.h>
    43 #include <bspopts.h>
    44 #include <bsp/utility.h>
    45 #include <libcpu/mmu-vmsav8-64.h>
    4647
    4748#ifdef __cplusplus
    4849extern "C" {
    4950#endif /* __cplusplus */
     51
     52/* AArch64 uses levels 0, 1, 2, and 3 */
     53#define MMU_MAX_SUBTABLE_PAGE_BITS ( 3 * MMU_BITS_PER_LEVEL + MMU_PAGE_BITS )
    5054
    5155typedef struct {
     
    217221BSP_START_TEXT_SECTION static inline rtems_status_code aarch64_mmu_map_block(
    218222  uint64_t *page_table,
    219   uintptr_t root_address,
    220   uintptr_t addr,
     223  uint64_t root_address,
     224  uint64_t addr,
    221225  uint64_t size,
    222   uint32_t level,
     226  int8_t level,
    223227  uint64_t flags
    224228)
    225229{
    226230  uint32_t shift = ( 2 - level ) * MMU_BITS_PER_LEVEL + MMU_PAGE_BITS;
    227   uintptr_t granularity = 1 << shift;
     231  uint64_t granularity = 1LLU << shift;
    228232  uint64_t page_flag = 0;
    229233
     
    234238  while ( size > 0 ) {
    235239    uintptr_t index = aarch64_mmu_get_index( root_address, addr, shift );
    236     uintptr_t block_bottom = RTEMS_ALIGN_DOWN( addr, granularity );
     240    uint64_t block_bottom = RTEMS_ALIGN_DOWN( addr, granularity );
    237241    uint64_t chunk_size = granularity;
    238242
     
    271275
    272276    /* Deal with any subtable modification  */
    273     uintptr_t new_root_address = root_address + index * granularity;
     277    uint64_t new_root_address = root_address + index * granularity;
    274278    uint64_t *sub_table = NULL;
    275279    rtems_status_code sc;
     
    312316  aarch64_mmu_config_table_size;
    313317
     318/* Get the maximum number of bits supported by this hardware */
     319BSP_START_TEXT_SECTION static inline uint64_t
     320aarch64_mmu_get_cpu_pa_bits( void )
     321{
     322  uint64_t id_reg = _AArch64_Read_id_aa64mmfr0_el1();
     323
     324  switch ( AARCH64_ID_AA64MMFR0_EL1_PARANGE_GET( id_reg ) ) {
     325  case 0:
     326          return 32;
     327  case 1:
     328          return 36;
     329  case 2:
     330          return 40;
     331  case 3:
     332          return 42;
     333  case 4:
     334          return 44;
     335  case 5:
     336          return 48;
     337  case 6:
     338          return 52;
     339  default:
     340          return 48;
     341  }
     342  return 48;
     343}
     344
    314345BSP_START_TEXT_SECTION static inline void
    315346aarch64_mmu_set_translation_table_entries(
     
    321352  uintptr_t begin = RTEMS_ALIGN_DOWN( config->begin, MMU_PAGE_SIZE );
    322353  uintptr_t end = RTEMS_ALIGN_UP( config->end, MMU_PAGE_SIZE );
     354  uint64_t max_mappable = 1LLU << aarch64_mmu_get_cpu_pa_bits();
    323355  rtems_status_code sc;
     356
     357  if ( begin >= max_mappable || end > max_mappable ) {
     358    bsp_fatal( BSP_FATAL_MMU_ADDRESS_INVALID );
     359  }
    324360
    325361  sc = aarch64_mmu_map_block(
     
    328364    begin,
    329365    end - begin,
    330     0,
     366    -1,
    331367    config->flags
    332368  );
     
    348384    ttb,
    349385    (uintptr_t) NULL,
    350     MMU_TOP_LEVEL_PAGE_BITS,
     386    MMU_MAX_SUBTABLE_PAGE_BITS,
    351387    0
    352388  );
     
    391427{
    392428  /* Set TCR */
    393   /* 128GB/36 bits mappable (64-0x1c) */
     429  /* 256TB/48 bits mappable (64-0x10) */
    394430  _AArch64_Write_tcr_el1(
    395     AARCH64_TCR_EL1_T0SZ( 0x1c ) | AARCH64_TCR_EL1_IRGN0( 0x1 ) |
    396     AARCH64_TCR_EL1_ORGN0( 0x1 ) | AARCH64_TCR_EL1_SH0( 0x3 ) | AARCH64_TCR_EL1_TG0( 0x0 )
     431    AARCH64_TCR_EL1_T0SZ( 0x10 ) | AARCH64_TCR_EL1_IRGN0( 0x1 ) |
     432    AARCH64_TCR_EL1_ORGN0( 0x1 ) | AARCH64_TCR_EL1_SH0( 0x3 ) |
     433    AARCH64_TCR_EL1_TG0( 0x0 ) | AARCH64_TCR_EL1_IPS( 0x5ULL )
    397434  );
    398435
  • bsps/aarch64/shared/mmu/vmsav8-64.c

    r6d4b390 r10ef708  
    4848{
    4949  rtems_status_code sc;
     50  uint64_t max_mappable = 1LLU << aarch64_mmu_get_cpu_pa_bits();
     51
     52  if ( addr >= max_mappable || (addr + size) > max_mappable ) {
     53    return RTEMS_INVALID_ADDRESS;
     54  }
    5055
    5156  aarch64_mmu_disable();
     
    5560    addr,
    5661    size,
    57     0,
     62    -1,
    5863    flags
    5964  );
  • bsps/include/bsp/fatal.h

    r6d4b390 r10ef708  
    7373  BSP_FATAL_CONSOLE_INSTALL_1,
    7474  BSP_FATAL_CONSOLE_REGISTER_DEV_2,
     75  BSP_FATAL_MMU_ADDRESS_INVALID,
    7576
    7677  /* ARM fatal codes */
  • cpukit/score/cpu/aarch64/include/libcpu/mmu-vmsav8-64.h

    r6d4b390 r10ef708  
    6161#define MMU_PAGE_SIZE           ( 1 << MMU_PAGE_BITS )
    6262#define MMU_BITS_PER_LEVEL      9
    63 #define MMU_TOP_LEVEL_PAGE_BITS ( 2 * MMU_BITS_PER_LEVEL + MMU_PAGE_BITS )
    6463
    6564#define AARCH64_MMU_FLAGS_BASE \
Note: See TracChangeset for help on using the changeset viewer.