mirror of
https://github.com/memtest86plus/memtest86plus.git
synced 2026-08-12 05:54:43 -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
170 lines
5.1 KiB
C
170 lines
5.1 KiB
C
// SPDX-License-Identifier: GPL-2.0
|
|
#ifndef MEMRW_H
|
|
#define MEMRW_H
|
|
/**
|
|
* \file
|
|
*
|
|
* Provides some 8/16/32/64-bit memory access functions. These stop the compiler
|
|
* optimizing accesses which need to be ordered and atomic. Mostly used
|
|
* for accessing memory-mapped hardware registers.
|
|
*
|
|
*//*
|
|
* Copyright (C) 2021-2022 Martin Whitaker.
|
|
* Copyright (C) 2024 Lionel Debroux.
|
|
*/
|
|
|
|
#include <stdint.h>
|
|
|
|
#if defined(__i386__) || defined(__x86_64__)
|
|
|
|
#define __MEMRW_SUFFIX_8BIT "b"
|
|
#define __MEMRW_SUFFIX_16BIT "w"
|
|
#define __MEMRW_SUFFIX_32BIT "l"
|
|
#define __MEMRW_SUFFIX_64BIT "q"
|
|
#define __MEMRW_READ_INSTRUCTIONS(bitwidth) "mov" __MEMRW_SUFFIX_##bitwidth##BIT " %1, %0"
|
|
#define __MEMRW_WRITE_INSTRUCTIONS(bitwidth) "mov" __MEMRW_SUFFIX_##bitwidth##BIT " %1, %0"
|
|
#define __MEMRW_FLUSH_INSTRUCTIONS(bitwidth) "mov" __MEMRW_SUFFIX_##bitwidth##BIT " %1, %0; mov" __MEMRW_SUFFIX_##bitwidth##BIT " %0, %1"
|
|
|
|
#elif defined(__loongarch_lp64)
|
|
|
|
#define __MEMRW_SUFFIX_8BIT "b"
|
|
#define __MEMRW_SUFFIX_16BIT "h"
|
|
#define __MEMRW_SUFFIX_32BIT "w"
|
|
#define __MEMRW_SUFFIX_64BIT "d"
|
|
#define __MEMRW_READ_INSTRUCTIONS(bitwidth) "ld." __MEMRW_SUFFIX_##bitwidth##BIT " %0, %1"
|
|
#define __MEMRW_WRITE_INSTRUCTIONS(bitwidth) "st." __MEMRW_SUFFIX_##bitwidth##BIT " %1, %0"
|
|
#define __MEMRW_FLUSH_INSTRUCTIONS(bitwidth) "st." __MEMRW_SUFFIX_##bitwidth##BIT " %1, %0; dbar 0"
|
|
|
|
#elif defined(__aarch64__)
|
|
|
|
#define __MEMRW_SUFFIX_8BIT "b"
|
|
#define __MEMRW_SUFFIX_16BIT "h"
|
|
#define __MEMRW_SUFFIX_32BIT ""
|
|
#define __MEMRW_SUFFIX_64BIT ""
|
|
#define __MEMRW_REG_8BIT "w"
|
|
#define __MEMRW_REG_16BIT "w"
|
|
#define __MEMRW_REG_32BIT "w"
|
|
#define __MEMRW_REG_64BIT "x"
|
|
#define __MEMRW_READ_INSTRUCTIONS(bitwidth) \
|
|
"ldr" __MEMRW_SUFFIX_##bitwidth##BIT " %" __MEMRW_REG_##bitwidth##BIT "0, %1"
|
|
#define __MEMRW_WRITE_INSTRUCTIONS(bitwidth) \
|
|
"str" __MEMRW_SUFFIX_##bitwidth##BIT " %" __MEMRW_REG_##bitwidth##BIT "1, %0"
|
|
#define __MEMRW_FLUSH_INSTRUCTIONS(bitwidth) \
|
|
"str" __MEMRW_SUFFIX_##bitwidth##BIT " %" __MEMRW_REG_##bitwidth##BIT "1, %0; dsb sy"
|
|
|
|
#endif
|
|
|
|
#define __MEMRW_READ_FUNC(bitwidth) \
|
|
static inline uint##bitwidth##_t read##bitwidth(const volatile uint##bitwidth##_t *ptr) \
|
|
{ \
|
|
uint##bitwidth##_t val; \
|
|
__asm__ __volatile__( \
|
|
__MEMRW_READ_INSTRUCTIONS(bitwidth) \
|
|
: "=r" (val) \
|
|
: "m" (*ptr) \
|
|
: "memory" \
|
|
); \
|
|
return val; \
|
|
}
|
|
|
|
#define __MEMRW_WRITE_FUNC(bitwidth) \
|
|
static inline void write##bitwidth(const volatile uint##bitwidth##_t *ptr, uint##bitwidth##_t val) \
|
|
{ \
|
|
__asm__ __volatile__( \
|
|
__MEMRW_WRITE_INSTRUCTIONS(bitwidth) \
|
|
: \
|
|
: "m" (*ptr), \
|
|
"r" (val) \
|
|
: "memory" \
|
|
); \
|
|
}
|
|
|
|
#define __MEMRW_FLUSH_FUNC(bitwidth) \
|
|
static inline void flush##bitwidth(const volatile uint##bitwidth##_t *ptr, uint##bitwidth##_t val) \
|
|
{ \
|
|
__asm__ __volatile__( \
|
|
__MEMRW_FLUSH_INSTRUCTIONS(bitwidth) \
|
|
: \
|
|
: "m" (*ptr), \
|
|
"r" (val) \
|
|
: "memory" \
|
|
); \
|
|
}
|
|
|
|
/**
|
|
* Reads and returns the value stored in the 8-bit memory location pointed to by ptr.
|
|
*/
|
|
__MEMRW_READ_FUNC(8)
|
|
/**
|
|
* Reads and returns the value stored in the 16-bit memory location pointed to by ptr.
|
|
*/
|
|
__MEMRW_READ_FUNC(16)
|
|
/**
|
|
* Reads and returns the value stored in the 32-bit memory location pointed to by ptr.
|
|
*/
|
|
__MEMRW_READ_FUNC(32)
|
|
/**
|
|
* Reads and returns the value stored in the 64-bit memory location pointed to by ptr.
|
|
*/
|
|
__MEMRW_READ_FUNC(64)
|
|
|
|
/**
|
|
* Writes val to the 8-bit memory location pointed to by ptr.
|
|
*/
|
|
__MEMRW_WRITE_FUNC(8)
|
|
/**
|
|
* Writes val to the 16-bit memory location pointed to by ptr.
|
|
*/
|
|
__MEMRW_WRITE_FUNC(16)
|
|
/**
|
|
* Writes val to the 32-bit memory location pointed to by ptr.
|
|
*/
|
|
__MEMRW_WRITE_FUNC(32)
|
|
/**
|
|
* Writes val to the 64-bit memory location pointed to by ptr.
|
|
*/
|
|
__MEMRW_WRITE_FUNC(64)
|
|
|
|
/**
|
|
* Writes val to the 8-bit memory location pointed to by ptr. Only returns when the write is complete.
|
|
*/
|
|
__MEMRW_FLUSH_FUNC(8)
|
|
/**
|
|
* Writes val to the 16-bit memory location pointed to by ptr. Only returns when the write is complete.
|
|
*/
|
|
__MEMRW_FLUSH_FUNC(16)
|
|
/**
|
|
* Writes val to the 32-bit memory location pointed to by ptr. Only returns when the write is complete.
|
|
*/
|
|
__MEMRW_FLUSH_FUNC(32)
|
|
/**
|
|
* Writes val to the 64-bit memory location pointed to by ptr. Only returns when the write is complete.
|
|
*/
|
|
__MEMRW_FLUSH_FUNC(64)
|
|
|
|
#if defined(__i386__) || defined(__x86_64__)
|
|
// The BDA helpers below dereference small constant addresses, which GCC's
|
|
// -Warray-bounds heuristic flags as likely null derefs. Suppress locally;
|
|
// the accesses are intentional reads/writes of the x86 BIOS Data Area.
|
|
#pragma GCC diagnostic push
|
|
#pragma GCC diagnostic ignored "-Warray-bounds"
|
|
/**
|
|
* Reads a 16-bit value from the x86 BIOS Data Area at the given linear address.
|
|
*/
|
|
static inline uint16_t bda_read16(uintptr_t address)
|
|
{
|
|
return read16((const volatile uint16_t *)address);
|
|
}
|
|
|
|
/**
|
|
* Writes a 16-bit value to the x86 BIOS Data Area at the given linear address.
|
|
*/
|
|
static inline void bda_write16(uintptr_t address, uint16_t value)
|
|
{
|
|
write16((const volatile uint16_t *)address, value);
|
|
}
|
|
#pragma GCC diagnostic pop
|
|
#endif
|
|
|
|
#endif // MEMRW_H
|