You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2024/07/01 05:27:39 UTC

(nuttx) branch master updated (66516918ce -> 0083ae1b2c)

This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git


    from 66516918ce x86_64/irq.h: use 32bit operations in up_cpu_index()
     new 2192d83200 arch/x86_64: add support for XSAVE/XRSTOR
     new bd73a915bd arch/x86_64: add support for FMA, AVX-2 and AVX-512
     new 0083ae1b2c boards/qemu-intel64: simplify STACKSIZE configuration

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 arch/x86_64/Kconfig                                |   7 ++
 arch/x86_64/include/intel64/arch.h                 |  64 ++++++++++
 arch/x86_64/include/intel64/irq.h                  | 134 ++++++++++++++++-----
 arch/x86_64/src/cmake/Toolchain.cmake              |  40 ++++++
 arch/x86_64/src/common/Kconfig                     |  48 ++++++++
 arch/x86_64/src/common/Toolchain.defs              |  70 +++++++++--
 arch/x86_64/src/intel64/Kconfig                    |   7 --
 arch/x86_64/src/intel64/intel64_check_capability.c |  82 +++++++++++--
 arch/x86_64/src/intel64/intel64_cpu.c              |   4 +-
 .../src/intel64/intel64_fullcontextrestore.S       |  12 +-
 arch/x86_64/src/intel64/intel64_head.S             |  37 +++++-
 arch/x86_64/src/intel64/intel64_initialstate.c     |  37 +++++-
 arch/x86_64/src/intel64/intel64_saveusercontext.S  |   8 +-
 arch/x86_64/src/intel64/intel64_sigdeliver.c       |   6 +-
 arch/x86_64/src/intel64/intel64_vectors.S          |  44 +++++--
 .../intel64/qemu-intel64/configs/earlyfb/defconfig |   4 +-
 .../intel64/qemu-intel64/configs/nsh/defconfig     |   4 +-
 .../intel64/qemu-intel64/configs/ostest/defconfig  |   4 +-
 .../intel64/qemu-intel64/configs/pcitest/defconfig |   4 +-
 sched/misc/assert.c                                |   9 +-
 20 files changed, 522 insertions(+), 103 deletions(-)


(nuttx) 03/03: boards/qemu-intel64: simplify STACKSIZE configuration

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 0083ae1b2c20aea85a91340493276a81f3c1f6ac
Author: p-szafonimateusz <p-...@xiaomi.com>
AuthorDate: Fri Jun 28 18:33:34 2024 +0200

    boards/qemu-intel64: simplify STACKSIZE configuration
    
    simplify STACKSIZE configuration by using CONFIG_DEFAULT_TASK_STACKSIZE
    
    Signed-off-by: p-szafonimateusz <p-...@xiaomi.com>
---
 boards/x86_64/intel64/qemu-intel64/configs/earlyfb/defconfig | 4 +---
 boards/x86_64/intel64/qemu-intel64/configs/nsh/defconfig     | 4 +---
 boards/x86_64/intel64/qemu-intel64/configs/ostest/defconfig  | 4 +---
 boards/x86_64/intel64/qemu-intel64/configs/pcitest/defconfig | 4 +---
 4 files changed, 4 insertions(+), 12 deletions(-)

diff --git a/boards/x86_64/intel64/qemu-intel64/configs/earlyfb/defconfig b/boards/x86_64/intel64/qemu-intel64/configs/earlyfb/defconfig
index 7b23a3c833..c72dac96fa 100644
--- a/boards/x86_64/intel64/qemu-intel64/configs/earlyfb/defconfig
+++ b/boards/x86_64/intel64/qemu-intel64/configs/earlyfb/defconfig
@@ -24,12 +24,11 @@ CONFIG_DEBUG_PCI_ERROR=y
 CONFIG_DEBUG_PCI_INFO=y
 CONFIG_DEBUG_PCI_WARN=y
 CONFIG_DEBUG_SYMBOLS=y
+CONFIG_DEFAULT_TASK_STACKSIZE=4194304
 CONFIG_EXAMPLES_HELLO=y
-CONFIG_EXAMPLES_HELLO_STACKSIZE=4194304
 CONFIG_FS_PROCFS=y
 CONFIG_IDLETHREAD_STACKSIZE=4194304
 CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=4194304
 CONFIG_LIBM=y
 CONFIG_MULTBOOT2_FB_TERM=y
 CONFIG_NSH_ARCHINIT=y
@@ -42,7 +41,6 @@ CONFIG_NXFONT_MONO5X8=y
 CONFIG_PREALLOC_CHILDSTATUS=16
 CONFIG_PRIORITY_INHERITANCE=y
 CONFIG_PTHREAD_MUTEX_TYPES=y
-CONFIG_PTHREAD_STACK_DEFAULT=4194304
 CONFIG_PTHREAD_STACK_MIN=4194304
 CONFIG_RAM_SIZE=268435456
 CONFIG_SCHED_CHILD_STATUS=y
diff --git a/boards/x86_64/intel64/qemu-intel64/configs/nsh/defconfig b/boards/x86_64/intel64/qemu-intel64/configs/nsh/defconfig
index e487c9031d..b1e799c472 100644
--- a/boards/x86_64/intel64/qemu-intel64/configs/nsh/defconfig
+++ b/boards/x86_64/intel64/qemu-intel64/configs/nsh/defconfig
@@ -27,12 +27,11 @@ CONFIG_BOOT_RUNFROMEXTSRAM=y
 CONFIG_BUILTIN=y
 CONFIG_CONSOLE_SYSLOG=y
 CONFIG_DEBUG_SYMBOLS=y
+CONFIG_DEFAULT_TASK_STACKSIZE=4194304
 CONFIG_EXAMPLES_HELLO=y
-CONFIG_EXAMPLES_HELLO_STACKSIZE=4194304
 CONFIG_FS_PROCFS=y
 CONFIG_IDLETHREAD_STACKSIZE=4194304
 CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=4194304
 CONFIG_LIBM=y
 CONFIG_NSH_ARCHINIT=y
 CONFIG_NSH_BUILTIN_APPS=y
@@ -42,7 +41,6 @@ CONFIG_PREALLOC_CHILDSTATUS=16
 CONFIG_PRIORITY_INHERITANCE=y
 CONFIG_PTHREAD_MUTEX_DEFAULT_PRIO_INHERIT=y
 CONFIG_PTHREAD_MUTEX_TYPES=y
-CONFIG_PTHREAD_STACK_DEFAULT=4194304
 CONFIG_PTHREAD_STACK_MIN=4194304
 CONFIG_RAM_SIZE=268435456
 CONFIG_SCHED_CHILD_STATUS=y
diff --git a/boards/x86_64/intel64/qemu-intel64/configs/ostest/defconfig b/boards/x86_64/intel64/qemu-intel64/configs/ostest/defconfig
index c6ca8f3d85..f2bbf3d71f 100644
--- a/boards/x86_64/intel64/qemu-intel64/configs/ostest/defconfig
+++ b/boards/x86_64/intel64/qemu-intel64/configs/ostest/defconfig
@@ -27,15 +27,14 @@ CONFIG_BOOT_RUNFROMEXTSRAM=y
 CONFIG_CONSOLE_SYSLOG=y
 CONFIG_DEBUG_FULLOPT=y
 CONFIG_DEBUG_SYMBOLS=y
+CONFIG_DEFAULT_TASK_STACKSIZE=4194304
 CONFIG_IDLETHREAD_STACKSIZE=4194304
 CONFIG_INIT_ENTRYPOINT="ostest_main"
-CONFIG_INIT_STACKSIZE=4194304
 CONFIG_LIBM=y
 CONFIG_PREALLOC_CHILDSTATUS=16
 CONFIG_PRIORITY_INHERITANCE=y
 CONFIG_PTHREAD_MUTEX_DEFAULT_PRIO_INHERIT=y
 CONFIG_PTHREAD_MUTEX_TYPES=y
-CONFIG_PTHREAD_STACK_DEFAULT=4194304
 CONFIG_PTHREAD_STACK_MIN=4194304
 CONFIG_RAM_SIZE=268435456
 CONFIG_SCHED_CHILD_STATUS=y
@@ -50,5 +49,4 @@ CONFIG_START_MONTH=3
 CONFIG_START_YEAR=2011
 CONFIG_SYSTEM_TIME64=y
 CONFIG_TESTING_OSTEST=y
-CONFIG_TESTING_OSTEST_STACKSIZE=4194304
 CONFIG_USEC_PER_TICK=1
diff --git a/boards/x86_64/intel64/qemu-intel64/configs/pcitest/defconfig b/boards/x86_64/intel64/qemu-intel64/configs/pcitest/defconfig
index 5f2c44e58a..13527e6104 100644
--- a/boards/x86_64/intel64/qemu-intel64/configs/pcitest/defconfig
+++ b/boards/x86_64/intel64/qemu-intel64/configs/pcitest/defconfig
@@ -32,12 +32,11 @@ CONFIG_DEBUG_PCI_ERROR=y
 CONFIG_DEBUG_PCI_INFO=y
 CONFIG_DEBUG_PCI_WARN=y
 CONFIG_DEBUG_SYMBOLS=y
+CONFIG_DEFAULT_TASK_STACKSIZE=4194304
 CONFIG_EXAMPLES_HELLO=y
-CONFIG_EXAMPLES_HELLO_STACKSIZE=4194304
 CONFIG_FS_PROCFS=y
 CONFIG_IDLETHREAD_STACKSIZE=4194304
 CONFIG_INIT_ENTRYPOINT="nsh_main"
-CONFIG_INIT_STACKSIZE=4194304
 CONFIG_LIBM=y
 CONFIG_NSH_ARCHINIT=y
 CONFIG_NSH_BUILTIN_APPS=y
@@ -47,7 +46,6 @@ CONFIG_NSH_READLINE=y
 CONFIG_PREALLOC_CHILDSTATUS=16
 CONFIG_PRIORITY_INHERITANCE=y
 CONFIG_PTHREAD_MUTEX_TYPES=y
-CONFIG_PTHREAD_STACK_DEFAULT=4194304
 CONFIG_PTHREAD_STACK_MIN=4194304
 CONFIG_RAM_SIZE=268435456
 CONFIG_SCHED_CHILD_STATUS=y


(nuttx) 01/03: arch/x86_64: add support for XSAVE/XRSTOR

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit 2192d83200cfda460d00e3e65918654fb2e47793
Author: p-szafonimateusz <p-...@xiaomi.com>
AuthorDate: Mon Apr 22 15:49:05 2024 +0200

    arch/x86_64: add support for XSAVE/XRSTOR
    
    Add support for XSAVE/XRSTOR to handle x86_64 procesor extended states.
    Support for these instructions is required to support AVX instruction set
    
    Signed-off-by: p-szafonimateusz <p-...@xiaomi.com>
---
 arch/x86_64/include/intel64/arch.h                 |  62 ++++++++++
 arch/x86_64/include/intel64/irq.h                  | 134 ++++++++++++++++-----
 arch/x86_64/src/common/Kconfig                     |   7 ++
 arch/x86_64/src/intel64/Kconfig                    |   7 --
 arch/x86_64/src/intel64/intel64_check_capability.c |  16 ++-
 arch/x86_64/src/intel64/intel64_cpu.c              |   4 +-
 .../src/intel64/intel64_fullcontextrestore.S       |  12 +-
 arch/x86_64/src/intel64/intel64_head.S             |  37 +++++-
 arch/x86_64/src/intel64/intel64_initialstate.c     |  37 +++++-
 arch/x86_64/src/intel64/intel64_saveusercontext.S  |   8 +-
 arch/x86_64/src/intel64/intel64_sigdeliver.c       |   6 +-
 arch/x86_64/src/intel64/intel64_vectors.S          |  44 +++++--
 sched/misc/assert.c                                |   9 +-
 13 files changed, 312 insertions(+), 71 deletions(-)

diff --git a/arch/x86_64/include/intel64/arch.h b/arch/x86_64/include/intel64/arch.h
index 0dc2a6fd9e..d0e7a61607 100644
--- a/arch/x86_64/include/intel64/arch.h
+++ b/arch/x86_64/include/intel64/arch.h
@@ -114,6 +114,30 @@
 #define X86_CR4_XMMEXCPT 0x00000400
 #define X86_CR4_FGSBASE  0x00010000
 #define X86_CR4_PCIDE    0x00020000
+#define X86_CR4_OSXSAVE  0x00040000
+
+/* XCR0 */
+
+#define X86_XCR0_X87       (1 << 0)
+#define X86_XCR0_SSE       (1 << 1)
+#define X86_XCR0_AVX       (1 << 2)
+#define X86_XCR0_BNDREG    (1 << 3)
+#define X86_XCR0_BNDCSR    (1 << 4)
+#define X86_XCR0_OPMASK    (1 << 5)
+#define X86_XCR0_HI256     (1 << 6)
+#define X86_XCR0_HI16      (1 << 7)
+#define X86_XCR0_PT        (1 << 8)
+#define X86_XCR0_PKRU      (1 << 9)
+#define X86_XCR0_PASID     (1 << 10)
+#define X86_XCR0_CETU      (1 << 11)
+#define X86_XCR0_CETS      (1 << 12)
+#define X86_XCR0_HDC       (1 << 13)
+#define X86_XCR0_UINTR     (1 << 14)
+#define X86_XCR0_LBR       (1 << 15)
+#define X86_XCR0_HWP       (1 << 16)
+#define X86_XCR0_XTILECFG  (1 << 17)
+#define X86_XCR0_XTILEDATA (1 << 18)
+#define X86_XCR0_APX       (1 << 19)
 
 /* PAGE TABLE ENTRY Definitions */
 
@@ -161,6 +185,7 @@
 #  define X86_64_CPUID_07_AVX512CD    (1 << 28)
 #  define X86_64_CPUID_07_AVX512BW    (1 << 30)
 #  define X86_64_CPUID_07_AVX512VL    (1 << 31)
+#define X86_64_CPUID_XSAVE            0x0d
 #define X86_64_CPUID_TSC              0x15
 
 /* MSR Definitions */
@@ -243,6 +268,7 @@
 #define MSR_X2APIC_TMICT        0x838
 #define MSR_X2APIC_TMCCT        0x839
 #define MSR_X2APIC_TDCR         0x83e
+#define MSR_IA32_XSS            0xda0
 
 /* IOAPIC related Definitions */
 
@@ -281,6 +307,42 @@
 #  define X86_RST_CNT_CPU_RST  0x04
 #  define X86_RST_CNT_FULL_RST 0x08
 
+/* XSAVE state component bitmap */
+
+#define X86_XSAVE_X87           (1 << 0)  /* Bit 0: X87 state */
+#define X86_XSAVE_SSE           (1 << 1)  /* Bit 1: SSE state (512 bytes) */
+#define X86_XSAVE_AVX           (1 << 2)  /* Bit 2: AVX state (256 bytes) */
+#define X86_XSAVE_MPX_BNDREGS   (1 << 3)  /* Bit 3: MPX BNDREGS (64 bytes) */
+#define X86_XSAVE_MPX_BNDCSR    (1 << 4)  /* Bit 4: MPX BNDCSR (16 bytes) */
+#define X86_XSAVE_AVX512_OPMASK (1 << 5)  /* Bit 5: AVX-512 opmask (64 bytes) */
+#define X86_XSAVE_AVX512_HI256  (1 << 6)  /* Bit 6: AVX-512 ZMM_Hi256 (512 bytes) */
+#define X86_XSAVE_AVX512_HI16   (1 << 7)  /* Bit 7: AVX-512 Hi16_ZMM (1024 bytes) */
+#define X86_XSAVE_PT            (1 << 8)  /* Bit 8: PT (72 bytes) */
+#define X86_XSAVE_PKRU          (1 << 9)  /* Bit 9: PKRU (4 bytes) */
+#define X86_XSAVE_PASID         (1 << 10) /* Bit 10: PASID state */
+#define X86_XSAVE_CET_U         (1 << 11) /* Bit 11: CET_U state */
+#define X86_XSAVE_CET_S         (1 << 12) /* Bit 12: CET_S state */
+#define X86_XSAVE_HDC           (1 << 13) /* Bit 13: HDC */
+#define X86_XSAVE_UINTR         (1 << 14) /* Bit 14: UINTR state */
+#define X86_XSAVE_LBR           (1 << 15) /* Bit 15: LBR state */
+#define X86_XSAVE_HWP           (1 << 16) /* Bit 16: HWP state */
+#define X86_XSAVE_AMX_TILECFG   (1 << 17) /* Bit 17: AMX TILECFG state (64 bytes) */
+#define X86_XSAVE_AMX_TILEDATA  (1 << 18) /* Bit 18: AMX TILEDATA state (8192 bytes) */
+
+/* XSAVE area size */
+
+#define XSAVE_LEGACY_SIZE       (512) /* X87 + SSE */
+#define XSAVE_HEADER_SIZE       (64)  /* XSAVE header */
+#define XSAVE_AVX_SIZE          (256)
+#define XSAVE_MXP_BNDREGS_SIZE  (64)
+#define XSAVE_MXP_BNDCSR_SIZE   (16)
+#define XSAVE_AVX512OPMASK_SIZE (64)
+#define XSAVE_AVX512HI256_SIZE  (512)
+#define XSAVE_AVX512HI16_SIZE   (1024)
+#define XSAVE_PT_SIZE           (72)
+#define XSAVE_PKRU_SIZE         (4)
+#define XSAVE_HDC_SIZE          (8)
+
 #ifndef __ASSEMBLY__
 
 /****************************************************************************
diff --git a/arch/x86_64/include/intel64/irq.h b/arch/x86_64/include/intel64/irq.h
index dd9ab02876..3f3d27c2d9 100644
--- a/arch/x86_64/include/intel64/irq.h
+++ b/arch/x86_64/include/intel64/irq.h
@@ -34,10 +34,11 @@
 #ifndef __ASSEMBLY__
 #  include <stdint.h>
 #  include <stdbool.h>
-#  include <arch/arch.h>
 #  include <time.h>
 #endif
 
+#include <arch/arch.h>
+
 /****************************************************************************
  * Pre-processor Definitions
  ****************************************************************************/
@@ -353,53 +354,120 @@
  * ISR/IRQ interrupt processing.
  */
 
-#define XCPTCONTEXT_XMM_AREA_SIZE 512
-#define XMMAREA_OFFSET            (XCPTCONTEXT_XMM_AREA_SIZE / 8)
+#ifndef CONFIG_ARCH_X86_64_HAVE_XSAVE
+
+/* Only legacy area if XSAVE not supported */
+
+#  define XCPTCONTEXT_XMM_AREA_SIZE 512
+#else
+
+/* XSAVE state depneds on enabled features */
+
+#  ifdef CONFIG_ARCH_X86_64_AVX
+#    define XSTATE_AVX_STATE    X86_XSAVE_AVX
+#    define XSTATE_AVX_SIZE     XSAVE_AVX_SIZE
+#  else
+#    define XSTATE_AVX_STATE    0
+#    define XSTATE_AVX_SIZE     0
+#  endif
+
+#  ifdef CONFIG_ARCH_X86_64_AVX512
+#    define XSTATE_AVX512_STATE (X86_XSAVE_AVX512_OPMASK |  \
+                                 X86_XSAVE_AVX512_HI256 |   \
+                                 X86_XSAVE_AVX512_HI16)
+#    define XSTATE_AVX512_SIZE  (XSAVE_MXP_BNDREGS_SIZE +   \
+                                 XSAVE_MXP_BNDCSR_SIZE +    \
+                                 XSAVE_AVX512OPMASK_SIZE +  \
+                                 XSAVE_AVX512HI256_SIZE +   \
+                                 XSAVE_AVX512HI16_SIZE)
+#  else
+#    define XSTATE_AVX512_STATE 0
+#    define XSTATE_AVX512_SIZE  0
+#  endif
+
+/* State component bitmap */
+
+#  define XSAVE_STATE_COMPONENTS    (X86_XSAVE_X87 |    \
+                                     X86_XSAVE_SSE |    \
+                                     XSTATE_AVX_STATE | \
+                                     XSTATE_AVX512_STATE)
+
+/* Area for XSAVE - standard area format */
+
+#  define XCPTCONTEXT_XMM_AREA_SIZE (XSAVE_LEGACY_SIZE +  \
+                                     XSAVE_HEADER_SIZE +  \
+                                     XSTATE_AVX_SIZE +    \
+                                     XSTATE_AVX512_SIZE)
+#endif
+
+/* Align registers to 64-bytes */
+
+#ifdef CONFIG_ARCH_X86_64_AVX512
+#  define XMMAREA_REG_ALIGN (13)
+#else
+#  define XMMAREA_REG_ALIGN (7)
+#endif
+
+/* Register offset in XMMAREA */
+
+#define XMMAREA_OFFSET     (XCPTCONTEXT_XMM_AREA_SIZE / 8)
+#define XMMAREA_REG_OFFSET (XMMAREA_REG_ALIGN + XMMAREA_OFFSET)
 
 /* Data segments */
 
-#define REG_ALIGN         (0 + XMMAREA_OFFSET)  /* "    " "" "     " "" "       " "        " */
-#define REG_FS            (1 + XMMAREA_OFFSET)  /* "    " "" "     " "" "       " "        " */
-#define REG_GS            (2 + XMMAREA_OFFSET)  /* "    " "" "     " "" "       " "        " */
-#define REG_ES            (3 + XMMAREA_OFFSET)  /* "    " "" "     " "" "       " "        " */
-#define REG_DS            (4 + XMMAREA_OFFSET)  /* Data segment selector */
+#define REG_FS            (0 + XMMAREA_REG_OFFSET)  /* "    " "" "     " "" "       " "        " */
+#define REG_GS            (1 + XMMAREA_REG_OFFSET)  /* "    " "" "     " "" "       " "        " */
+#define REG_ES            (2 + XMMAREA_REG_OFFSET)  /* "    " "" "     " "" "       " "        " */
+#define REG_DS            (3 + XMMAREA_REG_OFFSET)  /* Data segment selector */
 
 /* Remaining regs */
 
-#define REG_RAX           (5 + XMMAREA_OFFSET)  /* "   " "" "   " */
-#define REG_RBX           (6 + XMMAREA_OFFSET)  /* "   " "" "   " */
-#define REG_RBP           (7 + XMMAREA_OFFSET)  /* "   " "" "   " */
-#define REG_R10           (8 + XMMAREA_OFFSET)  /* "   " "" "   " */
-#define REG_R11           (9 + XMMAREA_OFFSET)  /* "   " "" "   " */
-#define REG_R12          (10 + XMMAREA_OFFSET)  /* "   " "" "   " */
-#define REG_R13          (11 + XMMAREA_OFFSET)  /* "   " "" "   " */
-#define REG_R14          (12 + XMMAREA_OFFSET)  /* "   " "" "   " */
-#define REG_R15          (13 + XMMAREA_OFFSET)  /* "   " "" "   " */
+#define REG_RAX           (4 + XMMAREA_REG_OFFSET)  /* "   " "" "   " */
+#define REG_RBX           (5 + XMMAREA_REG_OFFSET)  /* "   " "" "   " */
+#define REG_RBP           (6 + XMMAREA_REG_OFFSET)  /* "   " "" "   " */
+#define REG_R10           (7 + XMMAREA_REG_OFFSET)  /* "   " "" "   " */
+#define REG_R11           (8 + XMMAREA_REG_OFFSET)  /* "   " "" "   " */
+#define REG_R12           (9 + XMMAREA_REG_OFFSET)  /* "   " "" "   " */
+#define REG_R13          (10 + XMMAREA_REG_OFFSET)  /* "   " "" "   " */
+#define REG_R14          (11 + XMMAREA_REG_OFFSET)  /* "   " "" "   " */
+#define REG_R15          (12 + XMMAREA_REG_OFFSET)  /* "   " "" "   " */
 
 /* ABI calling convention */
 
-#define REG_R9           (14 + XMMAREA_OFFSET)  /* "   " "" "   " */
-#define REG_R8           (15 + XMMAREA_OFFSET)  /* "   " "" "   " */
-#define REG_RCX          (16 + XMMAREA_OFFSET)  /* "   " "" "   " */
-#define REG_RDX          (17 + XMMAREA_OFFSET)  /* "   " "" "   " */
-#define REG_RSI          (18 + XMMAREA_OFFSET)  /* "   " "" "   " */
-#define REG_RDI          (19 + XMMAREA_OFFSET)  /* "   " "" "   " */
+#define REG_R9           (13 + XMMAREA_REG_OFFSET)  /* "   " "" "   " */
+#define REG_R8           (14 + XMMAREA_REG_OFFSET)  /* "   " "" "   " */
+#define REG_RCX          (15 + XMMAREA_REG_OFFSET)  /* "   " "" "   " */
+#define REG_RDX          (16 + XMMAREA_REG_OFFSET)  /* "   " "" "   " */
+#define REG_RSI          (17 + XMMAREA_REG_OFFSET)  /* "   " "" "   " */
+#define REG_RDI          (18 + XMMAREA_REG_OFFSET)  /* "   " "" "   " */
 
 /* IRQ saved */
 
-#define REG_ERRCODE      (20 + XMMAREA_OFFSET)  /* Error code */
-#define REG_RIP          (21 + XMMAREA_OFFSET)  /* Pushed by process on interrupt processing */
-#define REG_CS           (22 + XMMAREA_OFFSET)  /* "    " "" "     " "" "       " "        " */
-#define REG_RFLAGS       (23 + XMMAREA_OFFSET)  /* "    " "" "     " "" "       " "        " */
-#define REG_RSP          (24 + XMMAREA_OFFSET)  /* "    " "" "     " "" "       " "        " */
-#define REG_SS           (25 + XMMAREA_OFFSET)  /* "    " "" "     " "" "       " "        " */
+#define REG_ERRCODE      (19 + XMMAREA_REG_OFFSET)  /* Error code */
+#define REG_RIP          (20 + XMMAREA_REG_OFFSET)  /* Pushed by process on interrupt processing */
+#define REG_CS           (21 + XMMAREA_REG_OFFSET)  /* "    " "" "     " "" "       " "        " */
+#define REG_RFLAGS       (22 + XMMAREA_REG_OFFSET)  /* "    " "" "     " "" "       " "        " */
+#define REG_RSP          (23 + XMMAREA_REG_OFFSET)  /* "    " "" "     " "" "       " "        " */
+#define REG_SS           (24 + XMMAREA_REG_OFFSET)  /* "    " "" "     " "" "       " "        " */
+
+#define XMMAREA_REGS     (25)
 
 /* NOTE 2: This is not really state data.  Rather, this is just a convenient
  *   way to pass parameters from the interrupt handler to C code.
  */
 
-#define XCPTCONTEXT_REGS (26 + XCPTCONTEXT_XMM_AREA_SIZE / 8)
-#define XCPTCONTEXT_SIZE (8 * XCPTCONTEXT_REGS + XCPTCONTEXT_XMM_AREA_SIZE)
+#define XCPTCONTEXT_REGS (XMMAREA_REGS + XMMAREA_REG_ALIGN + \
+                          XCPTCONTEXT_XMM_AREA_SIZE / 8)
+
+#define XCPTCONTEXT_SIZE (8 * XCPTCONTEXT_REGS)
+
+/* Always align XCPTCONTEXT to 64-bytes to support XSAVE */
+
+#define XCPTCONTEXT_ALIGN (64)
+
+#define XCP_ALIGN_MASK    (XCPTCONTEXT_ALIGN - 1)
+#define XCP_ALIGN_DOWN(a) ((a) & ~XCP_ALIGN_MASK)
+#define XCP_ALIGN_UP(a)   (((a) + XCP_ALIGN_MASK) & ~XCP_ALIGN_MASK)
 
 /****************************************************************************
  * Public Types
@@ -432,9 +500,9 @@ struct xcptcontext
   uint64_t saved_rflags;
   uint64_t saved_rsp;
 
-  /* Register save area */
+  /* Register save area - allocated from stack in up_initial_state() */
 
-  uint64_t regs[XCPTCONTEXT_REGS] aligned_data(16);
+  uint64_t *regs;
 };
 #endif
 
diff --git a/arch/x86_64/src/common/Kconfig b/arch/x86_64/src/common/Kconfig
index fc4235a69b..fbe6661d18 100644
--- a/arch/x86_64/src/common/Kconfig
+++ b/arch/x86_64/src/common/Kconfig
@@ -28,6 +28,13 @@ config ARCH_X86_64_ACPI_BIOS
 
 endif # ARCH_X86_64_ACPI
 
+config ARCH_X86_64_HAVE_XSAVE
+	bool "XSAVE support"
+	default y
+	---help---
+		Select to enable the use of XSAVE and FPU/SSE/AVX functions
+		of x86_64
+
 config ARCH_X86_64_MMX
 	bool "MMX support"
 	depends on ARCH_HAVE_MMX
diff --git a/arch/x86_64/src/intel64/Kconfig b/arch/x86_64/src/intel64/Kconfig
index 4c62c4e69b..86d96138e2 100644
--- a/arch/x86_64/src/intel64/Kconfig
+++ b/arch/x86_64/src/intel64/Kconfig
@@ -150,13 +150,6 @@ config INTEL64_ONESHOT_MAXTIMERS
 
 endif
 
-config ARCH_INTEL64_HAVE_XSAVE
-	bool "XSAVE support"
-	default y
-	---help---
-		Select to enable the use of XSAVE and FPU/SSE/AVX functions
-		of x86_64
-
 config ARCH_INTEL64_HAVE_PCID
 	bool "PCID support"
 	default y
diff --git a/arch/x86_64/src/intel64/intel64_check_capability.c b/arch/x86_64/src/intel64/intel64_check_capability.c
index e777b8554b..87dad14a7e 100644
--- a/arch/x86_64/src/intel64/intel64_check_capability.c
+++ b/arch/x86_64/src/intel64/intel64_check_capability.c
@@ -108,10 +108,24 @@ void x86_64_check_and_enable_capability(void)
       goto err;
     }
 
-#ifdef CONFIG_ARCH_INTEL64_HAVE_XSAVE
+#if defined(CONFIG_ARCH_HAVE_SSE) || defined(CONFIG_ARCH_X86_64_AVX) || \
+    defined(CONFIG_ARCH_X86_64_AVX512)
   __enable_sse_avx();
 #endif
 
+#ifdef CONFIG_ARCH_X86_64_HAVE_XSAVE
+  /* Check XSAVE state area size for the current XCR0 state */
+
+  asm volatile("cpuid" : "=b" (ebx)
+               : "a" (X86_64_CPUID_XSAVE), "c" (0)
+               : "rdx", "memory");
+
+  if (XCPTCONTEXT_XMM_AREA_SIZE < ebx)
+    {
+      goto err;
+    }
+#endif
+
 #ifdef CONFIG_ARCH_INTEL64_HAVE_PCID
   __enable_pcid();
 #endif
diff --git a/arch/x86_64/src/intel64/intel64_cpu.c b/arch/x86_64/src/intel64/intel64_cpu.c
index 17f7497ae8..d46ebd98c0 100644
--- a/arch/x86_64/src/intel64/intel64_cpu.c
+++ b/arch/x86_64/src/intel64/intel64_cpu.c
@@ -64,8 +64,8 @@ struct intel64_cpu_s g_cpu_priv[CONFIG_SMP_NCPUS];
 
 /* Allocate stack for interrupts and isr */
 
-uint8_t  g_intstackalloc[IRQ_STACK_ALLOC] aligned_data(16);
-uint8_t  g_isrstackalloc[IRQ_STACK_ALLOC] aligned_data(16);
+uint8_t  g_intstackalloc[IRQ_STACK_ALLOC] aligned_data(64);
+uint8_t  g_isrstackalloc[IRQ_STACK_ALLOC] aligned_data(64);
 
 /****************************************************************************
  * Private Functions
diff --git a/arch/x86_64/src/intel64/intel64_fullcontextrestore.S b/arch/x86_64/src/intel64/intel64_fullcontextrestore.S
index 545bb3bdd0..d52b7da744 100644
--- a/arch/x86_64/src/intel64/intel64_fullcontextrestore.S
+++ b/arch/x86_64/src/intel64/intel64_fullcontextrestore.S
@@ -53,6 +53,15 @@ x86_64_fullcontextrestore:
 
 	cli
 
+#ifndef CONFIG_ARCH_X86_64_HAVE_XSAVE
+	/* Restore xmm registers */
+	fxrstorq (%rdi)
+#else
+	movl     $XSAVE_STATE_COMPONENTS, %eax
+	xor      %edx, %edx
+	xrstor   (%rdi)
+#endif
+
 	/* Create an interrupt stack frame for the final iret.
 	*
 	*
@@ -115,9 +124,6 @@ x86_64_fullcontextrestore:
 	* XXX: Should use wrgsbase and wrfsbase to restore the gs and fs register
 	*/
 
-	/* restore xmm registers */
-	fxrstorq (%rdi)
-
 	/* Restore the correct value of EAX and then return */
 
 	popq    %rdi
diff --git a/arch/x86_64/src/intel64/intel64_head.S b/arch/x86_64/src/intel64/intel64_head.S
index f6f294f2b5..54f63f3b5b 100644
--- a/arch/x86_64/src/intel64/intel64_head.S
+++ b/arch/x86_64/src/intel64/intel64_head.S
@@ -24,6 +24,7 @@
 
 #include <nuttx/config.h>
 #include <arch/arch.h>
+#include <arch/irq.h>
 #include <arch/multiboot2.h>
 #include <sys/types.h>
 
@@ -33,6 +34,25 @@
  * Pre-processor definitions
  ****************************************************************************/
 
+/* Get XCR0 register value */
+
+#if defined(CONFIG_ARCH_X86_64_AVX512)
+#  define X86_XCR0_VAL (X86_XCR0_X87 | X86_XCR0_SSE | X86_XCR0_AVX | \
+                        X86_XCR0_OPMASK | X86_XCR0_HI256 | X86_XCR0_HI16)
+#elif defined(CONFIG_ARCH_X86_64_AVX)
+#  define X86_XCR0_VAL (X86_XCR0_X87 | X86_XCR0_SSE | X86_XCR0_AVX)
+#else
+#  define X86_XCR0_VAL (X86_XCR0_X87 | X86_XCR0_SSE)
+#endif
+
+/* Get CR4 register value */
+
+#ifdef CONFIG_ARCH_X86_64_HAVE_XSAVE
+#  define X86_CR4_FPU_VAL (X86_CR4_OSXSAVE | X86_CR4_OSXFSR | X86_CR4_XMMEXCPT)
+#else
+#  define X86_CR4_FPU_VAL (X86_CR4_OSXFSR | X86_CR4_XMMEXCPT)
+#endif
+
 /* Memory Map: _sbss is the start of the BSS region (see ld.script) _ebss is
  * the end of the BSS region (see ld.script). The idle task stack starts at
  * the end of BSS and is of size CONFIG_IDLETHREAD_STACKSIZE.  The IDLE thread
@@ -319,6 +339,9 @@ start64:
 	movabs  $g_idle_topstack,    %rbx
 	mov     (%rbx),   %rsp
 
+	/* Allocate space XCPTCONTEXT */
+	leaq    -XCPTCONTEXT_SIZE(%rsp), %rsp
+
 	/* Set bsp_done flag */
 	movl     $1, bsp_done
 
@@ -352,7 +375,7 @@ ap_start:
 	.size   __pmode_entry, . - __pmode_entry
 
 g_cpu_count:
-       .long 1
+	.long 1
 
 /****************************************************************************
  * Name: __revoke_low_memory
@@ -408,11 +431,21 @@ __enable_sse_avx:
 
 	/* Enable Saving XMM context */
 	mov     %cr4,   %rax
-	or      $(X86_CR4_OSXFSR | X86_CR4_XMMEXCPT),   %rax
+	or      $X86_CR4_FPU_VAL,   %rax
 	mov     %rax,   %cr4
 
+#ifdef CONFIG_ARCH_X86_64_HAVE_XSAVE
+	/* Configure XSAVE/XRSTOR for user state*/
+	mov     $X86_XCR0_VAL, %eax
+
+	xor     %rdx,  %rdx
+	xor     %rcx,  %rcx
+	xsetbv
+
+#else
 	/* Setup MXCSR, masking all SSE precision exception */
 	ldmxcsr mxcsr_mem
+#endif
 
 	ret
 
diff --git a/arch/x86_64/src/intel64/intel64_initialstate.c b/arch/x86_64/src/intel64/intel64_initialstate.c
index 5aa9fa8c49..389b6d95b9 100644
--- a/arch/x86_64/src/intel64/intel64_initialstate.c
+++ b/arch/x86_64/src/intel64/intel64_initialstate.c
@@ -33,6 +33,14 @@
 #include "x86_64_internal.h"
 #include "sched/sched.h"
 
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+#if XCPTCONTEXT_SIZE % XCPTCONTEXT_ALIGN != 0
+#  error XCPTCONTEXT_SIZE must be aligned to XCPTCONTEXT_ALIGN !
+#endif
+
 /****************************************************************************
  * Public Functions
  ****************************************************************************/
@@ -83,22 +91,39 @@ void up_initial_state(struct tcb_s *tcb)
 
   memset(xcp, 0, sizeof(struct xcptcontext));
 
-  /* set the FCW to 1f80 */
+  /* Allocate area for XCPTCONTEXT */
+
+  xcp->regs = (uint64_t *)XCP_ALIGN_DOWN((uintptr_t)tcb->stack_base_ptr +
+                                         tcb->adj_stack_size -
+                                         XCPTCONTEXT_SIZE);
+
+  /* Reset the xcp registers */
+
+  memset(xcp->regs, 0, XCPTCONTEXT_SIZE);
+
+#ifndef CONFIG_ARCH_X86_64_HAVE_XSAVE
+  /* Set the FCW to 1f80 */
 
   xcp->regs[1]          = (uint64_t)0x0000037f00000000;
 
-  /* set the MXCSR to 1f80 */
+  /* Set the MXCSR to 1f80 */
 
   xcp->regs[3]          = (uint64_t)0x0000000000001f80;
+#else
+  /* Initialize XSAVE region with a valid state */
+
+  asm volatile("xsave %0"
+               : "=m" (*xcp->regs)
+               : "a" (XSAVE_STATE_COMPONENTS), "d" (0)
+               : "memory");
+#endif
 
   /* Save the initial stack pointer... the value of the stackpointer before
    * the "interrupt occurs."
    */
 
-  xcp->regs[REG_RSP]    = (uint64_t)tcb->stack_base_ptr +
-                                    tcb->adj_stack_size;
-  xcp->regs[REG_RBP]    = (uint64_t)tcb->stack_base_ptr +
-                                    tcb->adj_stack_size;
+  xcp->regs[REG_RSP]    = (uint64_t)xcp->regs - 8;
+  xcp->regs[REG_RBP]    = (uint64_t)xcp->regs - 8;
 
   /* Save the task entry point */
 
diff --git a/arch/x86_64/src/intel64/intel64_saveusercontext.S b/arch/x86_64/src/intel64/intel64_saveusercontext.S
index 1c5a14a9f5..b5bad4fbf1 100644
--- a/arch/x86_64/src/intel64/intel64_saveusercontext.S
+++ b/arch/x86_64/src/intel64/intel64_saveusercontext.S
@@ -68,8 +68,14 @@ up_saveusercontext:
 	movq    %r14, (8*REG_R14)(%rdi)
 	movq    %r15, (8*REG_R15)(%rdi)
 
-	/* save xmm registers */
+#ifndef CONFIG_ARCH_X86_64_HAVE_XSAVE
+	/* Save xmm registers */
 	fxsaveq (%rdi)
+#else
+	movl    $XSAVE_STATE_COMPONENTS, %eax
+	xor     %edx, %edx
+	xsave   (%rdi)
+#endif
 
 	/* Save the value of SP as will be at the time of the IRET that will
 	 * appear to be the return from this function.
diff --git a/arch/x86_64/src/intel64/intel64_sigdeliver.c b/arch/x86_64/src/intel64/intel64_sigdeliver.c
index 819d689c87..a7f5763b42 100644
--- a/arch/x86_64/src/intel64/intel64_sigdeliver.c
+++ b/arch/x86_64/src/intel64/intel64_sigdeliver.c
@@ -54,7 +54,7 @@
 void x86_64_sigdeliver(void)
 {
   struct tcb_s *rtcb = this_task();
-  uint64_t regs_area[XCPTCONTEXT_REGS + 2];
+  uint64_t regs_area[XCPTCONTEXT_REGS + 8];
   uint64_t *regs;
 
 #ifdef CONFIG_SMP
@@ -72,9 +72,9 @@ void x86_64_sigdeliver(void)
         rtcb, rtcb->xcp.sigdeliver, rtcb->sigpendactionq.head);
   DEBUGASSERT(rtcb->xcp.sigdeliver != NULL);
 
-  /* Align regs to 16 byte boundary for SSE instructions. */
+  /* Align regs to 64 byte boundary for XSAVE */
 
-  regs = (uint64_t *)(((uint64_t)(regs_area) + 15) & (~(uint64_t)15));
+  regs = (uint64_t *)(((uint64_t)(regs_area) + 63) & (~(uint64_t)63));
 
   /* Save the real return state on the stack ASAP before any chance we went
    * sleeping and break the register profile.  We entered this function with
diff --git a/arch/x86_64/src/intel64/intel64_vectors.S b/arch/x86_64/src/intel64/intel64_vectors.S
index 7abaa88bfe..113a2855cc 100644
--- a/arch/x86_64/src/intel64/intel64_vectors.S
+++ b/arch/x86_64/src/intel64/intel64_vectors.S
@@ -729,12 +729,18 @@ isr_common:
 	mov     %fs, %ax      /* Lower 16-bits of rax. */
 	pushq   %rax          /* Save the data segment descriptor */
 
-	/* align to 16-bytes boundary */
-	leaq    -8(%rsp), %rsp
+	/* Align to 64-bytes boundary */
+	leaq    -(XMMAREA_REG_ALIGN * 8)(%rsp), %rsp
 
-	/* save xmm registers */
-	leaq    -512(%rsp), %rsp
+	/* Save xmm registers */
+	leaq    -XCPTCONTEXT_XMM_AREA_SIZE(%rsp), %rsp
+#ifndef CONFIG_ARCH_X86_64_HAVE_XSAVE
 	fxsaveq (%rsp)
+#else
+	movl $XSAVE_STATE_COMPONENTS, %eax
+	xor     %edx, %edx
+	xsave   (%rsp)
+#endif
 
 	/* The current value of the SP points to the beginning of the state save
 	 * structure.  Save that in RDI as the input parameter to isr_handler.
@@ -786,12 +792,18 @@ irq_common:
 	mov     %fs, %ax      /* Lower 16-bits of rax. */
 	pushq   %rax          /* Save the data segment descriptor */
 
-	/* align to 16-bytes boundary */
-	leaq    -8(%rsp), %rsp
+	/* Align to 64-bytes boundary */
+	leaq    -(XMMAREA_REG_ALIGN * 8)(%rsp), %rsp
 
-	/* save xmm registers */
-	leaq    -512(%rsp), %rsp
+	/* Save xmm registers */
+	leaq    -XCPTCONTEXT_XMM_AREA_SIZE(%rsp), %rsp
+#ifndef CONFIG_ARCH_X86_64_HAVE_XSAVE
 	fxsaveq (%rsp)
+#else
+	movl    $XSAVE_STATE_COMPONENTS, %eax
+	xor     %edx, %edx
+	xsave   (%rsp)
+#endif
 
 	/* The current value of the SP points to the beginning of the state save
 	 * structure.  Save that in RDI as the input parameter to irq_handler.
@@ -811,20 +823,28 @@ irq_common:
 	je      .Lnoswitch
 
 	/* A context swith will be performed. EAX holds the address of the new
-   * register save structure.
+	 * register save structure.
 	 *
 	 * Jump to x86_64_fullcontextrestore().  We perform a call here, but that function
 	 * never returns.  The address of the new register save block is the argument
 	 * to the x86_64_fullcontextrestore().
-	*/
+	 */
 
 	mov     %rax, %rdi
 	call    x86_64_fullcontextrestore
 
 .Lnoswitch:
+#ifndef CONFIG_ARCH_X86_64_HAVE_XSAVE
 	fxrstorq (%rsp)
-	leaq    512(%rsp), %rsp
-	leaq    8(%rsp), %rsp
+#else
+	movl $XSAVE_STATE_COMPONENTS, %eax
+	xor     %edx, %edx
+	xrstor  (%rsp)
+#endif
+	leaq    XCPTCONTEXT_XMM_AREA_SIZE(%rsp), %rsp
+
+	/* Align to 64-bytes boundary */
+	leaq    (XMMAREA_REG_ALIGN * 8)(%rsp), %rsp
 
 	popq    %rax
 	mov     %fs, %ax
diff --git a/sched/misc/assert.c b/sched/misc/assert.c
index 6d87199eb1..fa9b8c8916 100644
--- a/sched/misc/assert.c
+++ b/sched/misc/assert.c
@@ -79,11 +79,18 @@
 #  define DUMP_FORMAT " %016" PRIxPTR ""
 #endif
 
+/* Architecture can overwrite the default XCPTCONTEXT alignment */
+
+#ifndef XCPTCONTEXT_ALIGN
+#  define XCPTCONTEXT_ALIGN 16
+#endif
+
 /****************************************************************************
  * Private Data
  ****************************************************************************/
 
-static uintptr_t g_last_regs[XCPTCONTEXT_REGS] aligned_data(16);
+static uintptr_t
+g_last_regs[XCPTCONTEXT_REGS] aligned_data(XCPTCONTEXT_ALIGN);
 static FAR const char *g_policy[4] =
 {
   "FIFO", "RR", "SPORADIC"


(nuttx) 02/03: arch/x86_64: add support for FMA, AVX-2 and AVX-512

Posted by xi...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

xiaoxiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git

commit bd73a915bd016376405d8f318b3fa87277101cb4
Author: p-szafonimateusz <p-...@xiaomi.com>
AuthorDate: Mon Apr 22 15:49:18 2024 +0200

    arch/x86_64: add support for FMA, AVX-2 and AVX-512
    
    add support for FMA, AVX-2 and AVX-512 instruction sets for x86_64
    
    Signed-off-by: p-szafonimateusz <p-...@xiaomi.com>
---
 arch/x86_64/Kconfig                                |  7 +++
 arch/x86_64/include/intel64/arch.h                 |  2 +
 arch/x86_64/src/cmake/Toolchain.cmake              | 40 +++++++++++++
 arch/x86_64/src/common/Kconfig                     | 41 +++++++++++++
 arch/x86_64/src/common/Toolchain.defs              | 70 ++++++++++++++++++----
 arch/x86_64/src/intel64/intel64_check_capability.c | 66 +++++++++++++++++---
 6 files changed, 206 insertions(+), 20 deletions(-)

diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index 064cbf8b09..a22b9310b3 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -30,6 +30,9 @@ config ARCH_INTEL64
 	select ARCH_HAVE_SSE41
 	select ARCH_HAVE_SSE42
 	select ARCH_HAVE_SSE4A
+	select ARCH_HAVE_FMA if ARCH_X86_64_HAVE_XSAVE
+	select ARCH_HAVE_AVX if ARCH_X86_64_HAVE_XSAVE
+	select ARCH_HAVE_AVX512 if ARCH_X86_64_HAVE_XSAVE
 	select ARCH_ICACHE
 	select ARCH_DCACHE
 	select ARCH_HAVE_IRQTRIGGER
@@ -78,6 +81,10 @@ config ARCH_HAVE_SSE4A
 	bool
 	default n
 
+config ARCH_HAVE_FMA
+	bool
+	default n
+
 config ARCH_HAVE_AVX
 	bool
 	default n
diff --git a/arch/x86_64/include/intel64/arch.h b/arch/x86_64/include/intel64/arch.h
index d0e7a61607..34964e3c2c 100644
--- a/arch/x86_64/include/intel64/arch.h
+++ b/arch/x86_64/include/intel64/arch.h
@@ -165,12 +165,14 @@
 #define X86_64_CPUID_CAP              0x01
 #  define X86_64_CPUID_01_SSE3        (1 << 0)
 #  define X86_64_CPUID_01_SSSE3       (1 << 9)
+#  define X86_64_CPUID_01_FMA         (1 << 12)
 #  define X86_64_CPUID_01_PCID        (1 << 17)
 #  define X86_64_CPUID_01_SSE41       (1 << 19)
 #  define X86_64_CPUID_01_SSE42       (1 << 20)
 #  define X86_64_CPUID_01_X2APIC      (1 << 21)
 #  define X86_64_CPUID_01_TSCDEA      (1 << 24)
 #  define X86_64_CPUID_01_XSAVE       (1 << 26)
+#  define X86_64_CPUID_01_AVX         (1 << 28)
 #  define X86_64_CPUID_01_RDRAND      (1 << 30)
 #  define X86_64_CPUID_01_APICID(ebx) ((ebx) >> 24)
 #define X86_64_CPUID_EXTCAP           0x07
diff --git a/arch/x86_64/src/cmake/Toolchain.cmake b/arch/x86_64/src/cmake/Toolchain.cmake
index 3d79887381..aae29d7d9b 100644
--- a/arch/x86_64/src/cmake/Toolchain.cmake
+++ b/arch/x86_64/src/cmake/Toolchain.cmake
@@ -143,3 +143,43 @@ endif()
 if(CONFIG_ARCH_X86_64_SSE4A)
   add_compile_options(-msse4a)
 endif()
+
+if(CONFIG_ARCH_X86_64_AVX)
+  add_compile_options(-mavx)
+endif()
+
+if(CONFIG_ARCH_X86_64_AVX512)
+  add_compile_options(-mavx512f)
+endif()
+
+if(CONFIG_ARCH_X86_64_AVX512PF)
+  add_compile_options(-mavx512pf)
+endif()
+
+if(CONFIG_ARCH_X86_64_AVX512ER)
+  add_compile_options(-mavx512er)
+endif()
+
+if(CONFIG_ARCH_X86_64_AVX512CD)
+  add_compile_options(-mavx512cd)
+endif()
+
+if(CONFIG_ARCH_X86_64_AVX512VL)
+  add_compile_options(-mavx512vl)
+endif()
+
+if(CONFIG_ARCH_X86_64_AVX512BW)
+  add_compile_options(-mavx512bw)
+endif()
+
+if(CONFIG_ARCH_X86_64_AVX512DQ)
+  add_compile_options(-mavx512dq)
+endif()
+
+if(CONFIG_ARCH_X86_64_AVX512IFMA)
+  add_compile_options(-mavx512ifma)
+endif()
+
+if(CONFIG_ARCH_X86_64_AVX512VBMI)
+  add_compile_options(-mavx512vbmi)
+endif()
diff --git a/arch/x86_64/src/common/Kconfig b/arch/x86_64/src/common/Kconfig
index fbe6661d18..bd8dd435b3 100644
--- a/arch/x86_64/src/common/Kconfig
+++ b/arch/x86_64/src/common/Kconfig
@@ -75,6 +75,11 @@ config ARCH_X86_64_SSE4A
 	depends on ARCH_HAVE_SSE4A
 	default n
 
+config ARCH_X86_64_FMA
+	bool "FMA support"
+	depends on ARCH_HAVE_FMA && ARCH_X86_64_AVX
+	default n
+
 config ARCH_X86_64_AVX
 	bool "AVX support"
 	depends on ARCH_HAVE_AVX
@@ -85,4 +90,40 @@ config ARCH_X86_64_AVX512
 	depends on ARCH_HAVE_AVX512
 	default n
 
+if ARCH_X86_64_AVX512
+
+config ARCH_X86_64_AVX512PF
+	bool "AVX512 Prefetch Instructions (AVX512PF)"
+	default n
+
+config ARCH_X86_64_AVX512ER
+	bool "AVX512 Exponential and Reciprocal Instructions (AVX512ER)"
+	default n
+
+config ARCH_X86_64_AVX512CD
+	bool "AVX512 Conflict Detection Instructions (AVX512CD)"
+	default n
+
+config ARCH_X86_64_AVX512VL
+	bool "AVX512 Vector Length Extensions (AVX512VL)"
+	default n
+
+config ARCH_X86_64_AVX512BW
+	bool "AVX512 Byte and Word Instructions (AVX512BW)"
+	default n
+
+config ARCH_X86_64_AVX512DQ
+	bool "AVX512 Doubleword and Quadword Instructions (AVX512DQ)"
+	default n
+
+config ARCH_X86_64_AVX512IFMA
+	bool "AVX512 Integer Fused Multiply-Add Instructions (AVX512IFMA)"
+	default n
+
+config ARCH_X86_64_AVX512VBMI
+	bool "AVX512 Vector Bit Manipulation Instructions (AVX512VBMI)"
+	default n
+
+endif # ARCH_X86_64_AVX512
+
 endif
diff --git a/arch/x86_64/src/common/Toolchain.defs b/arch/x86_64/src/common/Toolchain.defs
index 32264de3cc..2f0a4cdd6d 100644
--- a/arch/x86_64/src/common/Toolchain.defs
+++ b/arch/x86_64/src/common/Toolchain.defs
@@ -56,16 +56,6 @@ NM = $(CROSSDEV)nm
 OBJCOPY = $(CROSSDEV)objcopy
 OBJDUMP = $(CROSSDEV)objdump
 
-CFLAGS := $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe
-CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS)
-AFLAGS := $(CFLAGS) -D__ASSEMBLY__
-
-ifeq ($(CONFIG_HOST_MACOS),y)
-AFLAGS += -Wa,--divide
-endif
-
-EXEEXT = .elf
-
 ifeq ($(CONFIG_ARCH_X86_64_SSE3),y)
   ARCHCPUFLAGS += -msse3
 endif
@@ -75,13 +65,67 @@ ifeq ($(CONFIG_ARCH_X86_64_SSSE3),y)
 endif
 
 ifeq ($(CONFIG_ARCH_X86_64_SSE41),y)
-  ARCHCPUFLAGS += -msse41
+  ARCHCPUFLAGS += -msse4.1
 endif
 
 ifeq ($(CONFIG_ARCH_X86_64_SSE42),y)
-  ARCHCPUFLAGS += -msse42
+  ARCHCPUFLAGS += -msse4.2
 endif
 
-ifeq ($(CONFIG_ARCH_X86_64_SSE4a),y)
+ifeq ($(CONFIG_ARCH_X86_64_SSE4A),y)
   ARCHCPUFLAGS += -msse4a
 endif
+
+ifeq ($(CONFIG_ARCH_X86_64_FMA),y)
+  ARCHCPUFLAGS += -mfma
+endif
+
+ifeq ($(CONFIG_ARCH_X86_64_AVX),y)
+  ARCHCPUFLAGS += -mavx
+endif
+
+ifeq ($(CONFIG_ARCH_X86_64_AVX512),y)
+  ARCHCPUFLAGS += -mavx512f
+endif
+
+ifeq ($(CONFIG_ARCH_X86_64_AVX512PF),y)
+  ARCHCPUFLAGS += -mavx512pf
+endif
+
+ifeq ($(CONFIG_ARCH_X86_64_AVX512ER),y)
+  ARCHCPUFLAGS += -mavx512er
+endif
+
+ifeq ($(CONFIG_ARCH_X86_64_AVX512CD),y)
+  ARCHCPUFLAGS += -mavx512cd
+endif
+
+ifeq ($(CONFIG_ARCH_X86_64_AVX512VL),y)
+  ARCHCPUFLAGS += -mavx512vl
+endif
+
+ifeq ($(CONFIG_ARCH_X86_64_AVX512BW),y)
+  ARCHCPUFLAGS += -mavx512bw
+endif
+
+ifeq ($(CONFIG_ARCH_X86_64_AVX512DQ),y)
+  ARCHCPUFLAGS += -mavx512dq
+endif
+
+ifeq ($(CONFIG_ARCH_X86_64_AVX512IFMA),y)
+  ARCHCPUFLAGS += -mavx512ifma
+endif
+
+ifeq ($(CONFIG_ARCH_X86_64_AVX512VBMI),y)
+  ARCHCPUFLAGS += -mavx512vbmi
+endif
+
+CFLAGS := $(ARCHWARNINGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -pipe
+CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS)
+AFLAGS := $(CFLAGS) -D__ASSEMBLY__
+
+ifeq ($(CONFIG_HOST_MACOS),y)
+AFLAGS += -Wa,--divide
+endif
+
+EXEEXT = .elf
diff --git a/arch/x86_64/src/intel64/intel64_check_capability.c b/arch/x86_64/src/intel64/intel64_check_capability.c
index 87dad14a7e..067a5786e1 100644
--- a/arch/x86_64/src/intel64/intel64_check_capability.c
+++ b/arch/x86_64/src/intel64/intel64_check_capability.c
@@ -58,9 +58,47 @@ void x86_64_check_and_enable_capability(void)
 {
   unsigned long ebx;
   unsigned long ecx;
-  unsigned long require;
+  unsigned long require = 0;
 
-  require = X86_64_CPUID_01_X2APIC;
+  /* Check SSE3 instructions availability */
+
+#ifdef CONFIG_ARCH_X86_64_SSE3
+  require |= X86_64_CPUID_01_SSE3;
+#endif
+
+  /* Check Suplement SSE3 instructions availability */
+
+#ifdef CONFIG_ARCH_X86_64_SSEE3
+  require |= X86_64_CPUID_01_SSEE3;
+#endif
+
+  /* Check Fused multiply-add (FMA) instructions availability */
+
+#ifdef CONFIG_ARCH_X86_64_FMA
+  require |= X86_64_CPUID_01_FMA;
+#endif
+
+  /* Check process context identifiers availability */
+
+#ifdef CONFIG_ARCH_INTEL64_HAVE_PCID
+  require |= X86_64_CPUID_01_PCID;
+#endif
+
+  /* Check SSE4.1 instructions availability */
+
+#ifdef CONFIG_ARCH_X86_64_SSE41
+  require |= X86_64_CPUID_01_SSE41;
+#endif
+
+  /* Check SSE4.2 instructions availability */
+
+#ifdef CONFIG_ARCH_X86_64_SSE42
+  require |= X86_64_CPUID_01_SSE42;
+#endif
+
+  /* Check x2APIC availability */
+
+  require |= X86_64_CPUID_01_X2APIC;
 
   /* Check timer availability */
 
@@ -68,16 +106,22 @@ void x86_64_check_and_enable_capability(void)
   require |= X86_64_CPUID_01_TSCDEA;
 #endif
 
-#ifdef CONFIG_ARCH_INTEL64_HAVE_XSAVE
+  /* Check XSAVE/XRSTOR availability */
+
+#ifdef CONFIG_ARCH_X86_64_HAVE_XSAVE
   require |= X86_64_CPUID_01_XSAVE;
 #endif
 
-#ifdef CONFIG_ARCH_INTEL64_HAVE_RDRAND
-  require |= X86_64_CPUID_01_RDRAND;
+  /* Check AVX instructions availability */
+
+#ifdef CONFIG_ARCH_X86_64_AVX
+  require |= X86_64_CPUID_01_AVX;
 #endif
 
-#ifdef CONFIG_ARCH_INTEL64_HAVE_PCID
-  require |= X86_64_CPUID_01_PCID;
+  /* Check RDRAND feature availability */
+
+#ifdef CONFIG_ARCH_INTEL64_HAVE_RDRAND
+  require |= X86_64_CPUID_01_RDRAND;
 #endif
 
   asm volatile("cpuid" : "=c" (ecx) : "a" (X86_64_CPUID_CAP)
@@ -94,6 +138,14 @@ void x86_64_check_and_enable_capability(void)
 
   require = 0;
 
+  /* Check AVX512 Foundation instructions availability */
+
+#ifdef CONFIG_ARCH_X86_64_AVX512
+  require |= X86_64_CPUID_07_AVX512F;
+#endif
+
+  /* Check CLWB instruction availability */
+
 #ifdef CONFIG_ARCH_INTEL64_HAVE_CLWB
   require |= X86_64_CPUID_07_CLWB;
 #endif