diff --git a/arch/arm64/src/qemu/CMakeLists.txt b/arch/arm64/src/qemu/CMakeLists.txt index eda0e13e2ef..7c83bec2d2a 100644 --- a/arch/arm64/src/qemu/CMakeLists.txt +++ b/arch/arm64/src/qemu/CMakeLists.txt @@ -25,4 +25,7 @@ endif() if(CONFIG_ARCH_USE_TEXT_HEAP) list(APPEND SRCS qemu_textheap.c) endif() +if(CONFIG_PM) + list(APPEND SRCS qemu_initialize.c) +endif() target_sources(arch PRIVATE ${SRCS}) diff --git a/arch/arm64/src/qemu/Make.defs b/arch/arm64/src/qemu/Make.defs index 037ce804280..0816edca2d3 100644 --- a/arch/arm64/src/qemu/Make.defs +++ b/arch/arm64/src/qemu/Make.defs @@ -30,3 +30,7 @@ endif ifeq ($(CONFIG_ARCH_USE_TEXT_HEAP),y) CHIP_CSRCS += qemu_textheap.c endif + +ifeq ($(CONFIG_PM), y) +CHIP_CSRCS += qemu_initialize.c +endif diff --git a/arch/arm64/src/qemu/qemu_initialize.c b/arch/arm64/src/qemu/qemu_initialize.c new file mode 100644 index 00000000000..45d32f2c5e0 --- /dev/null +++ b/arch/arm64/src/qemu/qemu_initialize.c @@ -0,0 +1,116 @@ +/**************************************************************************** + * arch/arm64/src/qemu/qemu_initialize.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 + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +void arm64_pminitialize(void) +{ + pm_initialize(); +} + +#ifdef CONFIG_SMP +static bool pm_idle_handler(int cpu, + enum pm_state_e cpu_state, + enum pm_state_e system_state) +{ + bool first = false; + switch (cpu_state) + { + case PM_NORMAL: + case PM_IDLE: + case PM_STANDBY: + case PM_SLEEP: + + /* do cpu domain pm enter operations */ + + asm("NOP"); + + if (system_state >= PM_NORMAL) + { + switch (system_state) + { + case PM_NORMAL: + case PM_IDLE: + case PM_STANDBY: + case PM_SLEEP: + + /* do system domain pm enter operations */ + + asm("NOP"); + + break; + default: + break; + } + } + + pm_idle_unlock(); + + /* do no cross-core relative operations */ + + asm("WFI"); + + first = pm_idle_lock(cpu); + if (first) + { + /* do system domain pm leave operations */ + + asm("NOP"); + } + + /* do cpu domain pm leave operations */ + + asm("NOP"); + + break; + default: + break; + } + + return first; +} +#else + +static void pm_idle_handler(enum pm_state_e state) +{ + switch (state) + { + default: + asm("WFI"); + break; + } +} + +#endif + +void up_idle(void) +{ + pm_idle(pm_idle_handler); +}