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 b1f3435d22c6acf82e8f20778e6b361ad08cafa4
Author: p-szafonimateusz <[email protected]>
AuthorDate: Mon Jun 17 14:05:01 2024 +0200

    arch/intel64: add support for MM_PGALLOC
    
    add support for MM_PGALLOC for x86_64
    
    Signed-off-by: p-szafonimateusz <[email protected]>
---
 arch/x86_64/include/intel64/arch.h           |  23 ++++--
 arch/x86_64/src/common/Kconfig               |   7 ++
 arch/x86_64/src/common/pgalloc.h             | 114 +++++++++++++++++++++++++++
 arch/x86_64/src/common/x86_64_allocateheap.c |  12 ++-
 arch/x86_64/src/intel64/CMakeLists.txt       |   4 +
 arch/x86_64/src/intel64/Make.defs            |   4 +
 arch/x86_64/src/intel64/intel64_pgalloc.c    |  73 +++++++++++++++++
 7 files changed, 229 insertions(+), 8 deletions(-)

diff --git a/arch/x86_64/include/intel64/arch.h 
b/arch/x86_64/include/intel64/arch.h
index 34964e3c2c..7539efaff8 100644
--- a/arch/x86_64/include/intel64/arch.h
+++ b/arch/x86_64/include/intel64/arch.h
@@ -42,6 +42,19 @@
 
 #define X86_64_LOAD_OFFSET 0x100000000
 
+/* Page pool configuration for CONFIG_ARCH_PGPOOL_MAPPING=n */
+
+#ifndef CONFIG_ARCH_X86_64_PGPOOL_SIZE
+#  define X86_64_PGPOOL_SIZE      (0)
+#else
+#  if CONFIG_ARCH_X86_64_PGPOOL_SIZE % CONFIG_MM_PGSIZE != 0
+#    error CONFIG_ARCH_X86_64_PGPOOL_SIZE must be multiple of page size
+#  endif
+#  define X86_64_PGPOOL_SIZE      (CONFIG_ARCH_X86_64_PGPOOL_SIZE)
+#endif
+
+#define X86_64_PGPOOL_BASE        (CONFIG_RAM_SIZE - X86_64_PGPOOL_SIZE)
+
 /* RFLAGS bits */
 
 #define X86_64_RFLAGS_CF          (1 << 0)  /* Bit 0:  Carry Flag */
@@ -71,13 +84,13 @@
 
 /* Starting from third selector to confirm the syscall interface */
 
-#define X86_GDT_ENTRY_SIZE      0x8
+#define X86_GDT_ENTRY_SIZE        0x8
 
-#define X86_GDT_CODE_SEL_NUM    1
-#  define X86_GDT_CODE_SEL      (X86_GDT_CODE_SEL_NUM * X86_GDT_ENTRY_SIZE)
+#define X86_GDT_CODE_SEL_NUM      1
+#  define X86_GDT_CODE_SEL        (X86_GDT_CODE_SEL_NUM * X86_GDT_ENTRY_SIZE)
 
-#define X86_GDT_DATA_SEL_NUM    2
-#  define X86_GDT_DATA_SEL      (X86_GDT_DATA_SEL_NUM * X86_GDT_ENTRY_SIZE)
+#define X86_GDT_DATA_SEL_NUM      2
+#  define X86_GDT_DATA_SEL        (X86_GDT_DATA_SEL_NUM * X86_GDT_ENTRY_SIZE)
 
 /* The first TSS entry */
 
diff --git a/arch/x86_64/src/common/Kconfig b/arch/x86_64/src/common/Kconfig
index bd8dd435b3..a20a456a31 100644
--- a/arch/x86_64/src/common/Kconfig
+++ b/arch/x86_64/src/common/Kconfig
@@ -6,6 +6,13 @@
 if ARCH_X86_64
 comment "Common Configuration Options"
 
+config ARCH_X86_64_PGPOOL_SIZE
+       int "Page pool size"
+       depends on !ARCH_PGPOOL_MAPPING && MM_PGALLOC
+       default 8192000
+       ---help---
+               Page pool size if ARCH_PGPOOL_MAPPING is not enabled
+
 config ARCH_X86_64_ACPI
        bool "ACPI support"
        default y
diff --git a/arch/x86_64/src/common/pgalloc.h b/arch/x86_64/src/common/pgalloc.h
new file mode 100644
index 0000000000..e85d4ee8b5
--- /dev/null
+++ b/arch/x86_64/src/common/pgalloc.h
@@ -0,0 +1,114 @@
+/****************************************************************************
+ * arch/x86_64/src/common/pgalloc.h
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+#ifndef __ARCH_X86_64_SRC_COMMON_PGALLOC_H
+#define __ARCH_X86_64_SRC_COMMON_PGALLOC_H
+
+#ifdef CONFIG_MM_PGALLOC
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <stdint.h>
+#include <string.h>
+
+#include "addrenv.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Public Function Prototypes
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: x86_64_pgvaddr
+ *
+ * Description:
+ *   Get virtual address for pgpool physical address. Note: this function
+ *   is minimalistic and is only usable for kernel mappings and only tests
+ *   if the paddr is in the pgpool. For user mapped addresses this does not
+ *   work.
+ *
+ * Input Parameters:
+ *   paddr - Physical pgpool address
+ *
+ * Return:
+ *   vaddr - Virtual address for physical address
+ *
+ ****************************************************************************/
+
+static inline uintptr_t x86_64_pgvaddr(uintptr_t paddr)
+{
+#ifdef CONFIG_ARCH_PGPOOL_MAPPING
+  if (paddr >= CONFIG_ARCH_PGPOOL_PBASE && paddr < CONFIG_ARCH_PGPOOL_PEND)
+    {
+      return CONFIG_ARCH_PGPOOL_VBASE + paddr - CONFIG_ARCH_PGPOOL_PBASE;
+    }
+  else
+#endif
+  if (paddr >= CONFIG_RAM_START && paddr < CONFIG_RAM_END && paddr != 0)
+    {
+      return X86_64_LOAD_OFFSET + paddr - CONFIG_RAM_START;
+    }
+
+  return 0;
+}
+
+static inline uintptr_t x86_64_pgpaddr(uintptr_t vaddr)
+{
+#ifdef CONFIG_ARCH_PGPOOL_MAPPING
+  if (vaddr >= CONFIG_ARCH_PGPOOL_VBASE && vaddr < CONFIG_ARCH_PGPOOL_VEND)
+    {
+      return CONFIG_ARCH_PGPOOL_PBASE + vaddr - CONFIG_ARCH_PGPOOL_VBASE;
+    }
+  else
+#endif
+    if (vaddr >= X86_64_LOAD_OFFSET && vaddr < X86_64_LOAD_OFFSET)
+    {
+      return CONFIG_RAM_START + vaddr - X86_64_LOAD_OFFSET;
+    }
+
+  return 0;
+}
+
+/****************************************************************************
+ * Name: x86_64_pgwipe
+ *
+ * Description:
+ *   Wipe a page of physical memory, first mapping it into virtual memory.
+ *
+ * Input Parameters:
+ *   paddr - Physical address of page
+ *
+ ****************************************************************************/
+
+static inline void x86_64_pgwipe(uintptr_t paddr)
+{
+  uintptr_t vaddr = x86_64_pgvaddr(paddr);
+  memset((void *)vaddr, 0, MM_PGSIZE);
+}
+
+#endif /* CONFIG_MM_PGALLOC */
+#endif  /* __ARCH_X86_64_SRC_COMMON_PGALLOC_H */
diff --git a/arch/x86_64/src/common/x86_64_allocateheap.c 
b/arch/x86_64/src/common/x86_64_allocateheap.c
index 12cafa2acc..0dbfc9a7f9 100644
--- a/arch/x86_64/src/common/x86_64_allocateheap.c
+++ b/arch/x86_64/src/common/x86_64_allocateheap.c
@@ -107,7 +107,13 @@ void up_allocate_heap(void **heap_start, size_t *heap_size)
   hstart = (topstack + PAGE_SIZE - 1) & PAGE_MASK;
   *heap_start = (void *)hstart;
 
-  /* The size is the rest of the RAM */
-
-  *heap_size = (size_t)(CONFIG_RAM_SIZE - (hstart - 0x100000000 - 1));
+  /* The size is the rest of the RAM minus page pool */
+
+#ifdef CONFIG_ARCH_PGPOOL_PBASE
+  *heap_size = (size_t)(CONFIG_ARCH_PGPOOL_PBASE -
+                        (hstart - X86_64_LOAD_OFFSET - 1));
+#else
+  *heap_size = (size_t)(X86_64_PGPOOL_BASE -
+                        (hstart - X86_64_LOAD_OFFSET - 1));
+#endif
 }
diff --git a/arch/x86_64/src/intel64/CMakeLists.txt 
b/arch/x86_64/src/intel64/CMakeLists.txt
index 5698d2b649..5bf42a106f 100644
--- a/arch/x86_64/src/intel64/CMakeLists.txt
+++ b/arch/x86_64/src/intel64/CMakeLists.txt
@@ -48,6 +48,10 @@ set(SRCS
     intel64_check_capability.c
     intel64_cpu.c)
 
+if(CONFIG_MM_PGALLOC)
+  list(APPEND SRCS intel64_pgalloc.c)
+endif()
+
 if(CONFIG_ARCH_HAVE_TESTSET)
   list(APPEND SRCS intel64_testset.S)
 endif()
diff --git a/arch/x86_64/src/intel64/Make.defs 
b/arch/x86_64/src/intel64/Make.defs
index a4f4adf2b8..479dd0235c 100644
--- a/arch/x86_64/src/intel64/Make.defs
+++ b/arch/x86_64/src/intel64/Make.defs
@@ -34,6 +34,10 @@ CHIP_CSRCS  = intel64_start.c intel64_handlers.c 
intel64_idle.c intel64_lowsetup
 CHIP_CSRCS += intel64_serial.c intel64_rng.c intel64_check_capability.c
 CHIP_CSRCS += intel64_cpu.c
 
+ifeq ($(CONFIG_MM_PGALLOC),y)
+CHIP_CSRCS += intel64_pgalloc.c
+endif
+
 ifeq ($(CONFIG_ARCH_HAVE_TESTSET), y)
 CHIP_ASRCS += intel64_testset.S
 endif
diff --git a/arch/x86_64/src/intel64/intel64_pgalloc.c 
b/arch/x86_64/src/intel64/intel64_pgalloc.c
new file mode 100644
index 0000000000..1d66e941cf
--- /dev/null
+++ b/arch/x86_64/src/intel64/intel64_pgalloc.c
@@ -0,0 +1,73 @@
+/****************************************************************************
+ * arch/x86_64/src/intel64/intel64_pgalloc.c
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.  The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/arch.h>
+#include <nuttx/config.h>
+
+#include <assert.h>
+#include <debug.h>
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+
+/* Additional checks for CONFIG_ARCH_PGPOOL_MAPPING */
+
+#ifdef CONFIG_ARCH_PGPOOL_MAPPING
+#  if CONFIG_ARCH_PGPOOL_VBASE != (CONFIG_ARCH_PGPOOL_PBASE + 
X86_64_LOAD_OFFSET)
+#    error invalid PGPOOL configuration
+#  endif
+#endif
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: up_allocate_pgheap
+ *
+ * Description:
+ *   If there is a page allocator in the configuration, then this function
+ *   must be provided by the platform-specific code.  The OS initialization
+ *   logic will call this function early in the initialization sequence to
+ *   get the page heap information needed to configure the page allocator.
+ *
+ ****************************************************************************/
+
+void up_allocate_pgheap(void **heap_start, size_t *heap_size)
+{
+  DEBUGASSERT(heap_start && heap_size);
+
+#ifndef CONFIG_ARCH_PGPOOL_MAPPING
+  /* pgheap at the end of RAM */
+
+  *heap_start = (void *)(X86_64_PGPOOL_BASE + X86_64_LOAD_OFFSET);
+  *heap_size  = (size_t)X86_64_PGPOOL_SIZE;
+#else
+  /* pgheap defined with Kconfig options */
+
+  *heap_start = (void *)CONFIG_ARCH_PGPOOL_VBASE;
+  *heap_size  = (size_t)CONFIG_ARCH_PGPOOL_SIZE;
+#endif
+}

Reply via email to