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 + +#include +#include + +#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 */ + /* The size is the rest of the RAM minus page pool */ - *heap_size = (size_t)(CONFIG_RAM_SIZE - (hstart - 0x100000000 - 1)); +#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 +#include + +#include +#include + +/**************************************************************************** + * 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 +}