mirror of
https://github.com/memtest86plus/memtest86plus.git
synced 2026-09-03 20:53:06 -05:00
* Initial commit for ARM64 (header.S & startup.S) * Add Aarch64 interrupt handler * Adapt lib/ to Aarch64 * Small ASM addition for AArch64 * Rewrite Aarch64 system/ - cpuid.c/cpuinfo.c for CPU detection (Qualcomm, Apple, Nvidia, etc) - Add ARM Power State Coordination Interface (PSCI) functions - vmem.c for Virtual Memory MAnagement on ARM64 - Various functions placeholders * Add pseudo-TSC correction for Aarch64 * Add pseudo-tsc measurement for Aarch64 * Add Aarch64 if/elif on basic IO/MMIO/MEM RW functions * Add support for Surface 13 / Snapdragon X KB USB Fix an issue with the XHCI.c drivers with packets > 8 bytes * Add MMIO Serial support for ARM64 * Add ARM64 ASM for block_move & mov_inv_fixed. Fix VM start pointer * Add ARM Serial MMIO configuration * Revert previous commit & reintroduce ARM64 cache functions * Add ACPI MCFG Table description & SMP parsing. This requires careful review/testing to avoid BC issues! * Revert previous commmit and reintroduce relocation and heap change for ARM64 * ARM64 does not support CPU PNS. Use DMI type4 parsing instead. Add SMBIOS v3 support (ARM64 does not support v2) * Fix typo in pci.h * Move Aarch64 load-limit computation from main.c to pmem.c * Add .arm64 to version string. Use PMU for clock computation display. Fix D5 Temp NULL not handled * Add Makefile and linker scripts for aarch64. Set cross-compiler from x86 by default * Attempt to add aarch64 to workflow * Remove a remaining internal debug flag * Correct typos * Fix ARM64 SMP freeze assign heap when RAM is one contiguous region, keep it below 3GB for DMA (RPi5), add DSB before SEV to avoid missed barrier wakeups Sync I-cache with D-cache after program relocation to prevent stale instruction fetch * Validate MADT entry lengths to avoid reading past the table (or looping forever) on malformed ACPI tables * aarch64: add NEON kernels for the vector PRSG tests Tests 3 (bus stress) and 5 (moving inversions, random) now dispatch to 128-bit NEON fill/scan instead of scalar. * Fix ARM64 data abort from the per-second DMI check & fix unbounded strstr() * Fix ARM64 data abort when saving results to USB after a relocation * Update README.md with AArch64 (ARM64) support * aarch64: shrink static string tables, harden MCFG/paging Replace pointer-based name tables with inline char arrays (saves ~1.5KB + relocs) alidate MCFG length/bus ranges, and bound pm_map/vm_map fills against overflows * Add NVIDIA & latest Apple ARM SoC to cpuid.c * Fix stale pointers read by the report writer after a program relocation cpu_model gets a static init (creates its reloc record)SPD type becomes an inline char array
100 lines
3.3 KiB
C
100 lines
3.3 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
// Copyright (C) 2024 Loongson Technology Corporation Limited. All rights reserved.
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
#include <larchintrin.h>
|
|
#include <string.h>
|
|
|
|
#include "boot.h"
|
|
|
|
#include "cpuid.h"
|
|
|
|
#include "vmem.h"
|
|
|
|
extern bool map_numa_memory_range;
|
|
extern uint8_t highest_map_bit;
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Constants
|
|
//------------------------------------------------------------------------------
|
|
|
|
#define MAX_REGION_PAGES 256 // VM pages
|
|
#define PCI_IO_PERFIX 0xEULL << 40
|
|
#define DMW0_BASE 0x8000000000000000
|
|
#define MMIO_BASE DMW0_BASE | PCI_IO_PERFIX
|
|
|
|
#define PCIE32_LOW_ADDRESS 0x30000000
|
|
#define PCIE32_HIGH_ADDRESS 0x80000000
|
|
#define PCIE40_LOW_ADDRESS 0x4000000000ULL
|
|
#define PCIE40_HIGH_ADDRESS 0xC000000000ULL
|
|
#define PCIE64_LOW_ADDRESS 0x8000000000ULL
|
|
#define PCIE64_HIGH_ADDRESS 0xFD00000000ULL
|
|
//------------------------------------------------------------------------------
|
|
// Public Variables
|
|
//------------------------------------------------------------------------------
|
|
|
|
bool paging_incomplete = false; // never set on this architecture
|
|
|
|
//------------------------------------------------------------------------------
|
|
// Public Functions
|
|
//------------------------------------------------------------------------------
|
|
|
|
uintptr_t map_region(uintptr_t base_addr, size_t size __attribute__((unused)), bool only_for_startup __attribute__((unused)))
|
|
{
|
|
const bool is_2k_or_3b6000m =
|
|
(strstr(cpuid_info.brand_id.str, "2K") != NULL) ||
|
|
(strstr(cpuid_info.brand_id.str, "3B6000M") != NULL);
|
|
|
|
// 32-bit PCI memory space base differs by platform
|
|
const uintptr_t pci32_lo = PCIE32_LOW_ADDRESS;
|
|
const uintptr_t pci32_hi = PCIE32_HIGH_ADDRESS;
|
|
// 64-bit PCI memory space base differs by platform
|
|
const uintptr_t pci64_lo = is_2k_or_3b6000m ? PCIE40_LOW_ADDRESS : PCIE64_LOW_ADDRESS;
|
|
const uintptr_t pci64_hi = is_2k_or_3b6000m ? PCIE40_HIGH_ADDRESS : PCIE64_HIGH_ADDRESS;
|
|
|
|
if (((base_addr < pci32_hi) && (base_addr >= pci32_lo)) || // 32-bit PCI memory space
|
|
((base_addr < pci64_hi) && (base_addr >= pci64_lo)) || // 64-bit PCI memory space
|
|
((base_addr & PCI_IO_PERFIX) != 0x0)) {
|
|
return MMIO_BASE | base_addr;
|
|
} else if ((base_addr < 0x20000000) && (base_addr > 0x10000000)) {
|
|
return DMW0_BASE | base_addr;
|
|
} else {
|
|
return base_addr;
|
|
}
|
|
}
|
|
|
|
bool map_window(uintptr_t start_page __attribute__((unused)))
|
|
{
|
|
return true;
|
|
}
|
|
|
|
void *first_word_mapping(uintptr_t page)
|
|
{
|
|
void *result;
|
|
|
|
if (map_numa_memory_range == true) {
|
|
if ((page >> (highest_map_bit - PAGE_SHIFT)) & 0xF) {
|
|
uintptr_t alias = (((uintptr_t)(page >> (highest_map_bit - PAGE_SHIFT)) & 0xF) << 32) ;
|
|
alias |= page & ~(0xF << (highest_map_bit - PAGE_SHIFT));
|
|
result = (void *)(alias << PAGE_SHIFT);
|
|
} else {
|
|
result = (void *)(page << PAGE_SHIFT);
|
|
}
|
|
} else {
|
|
result = (void *)(page << PAGE_SHIFT);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void *last_word_mapping(uintptr_t page, size_t word_size)
|
|
{
|
|
return (uint8_t *)first_word_mapping(page) + (PAGE_SIZE - word_size);
|
|
}
|
|
|
|
uintptr_t page_of(void *addr)
|
|
{
|
|
uintptr_t page = (uintptr_t)addr >> PAGE_SHIFT;
|
|
return page;
|
|
}
|