[dev][power][psci] refactor out of the qemu-virt-arm module
This commit is contained in:
committed by
Travis Geiselbrecht
parent
baca46e133
commit
f4b2fa9a6b
20
dev/power/psci/include/dev/power/psci.h
Normal file
20
dev/power/psci/include/dev/power/psci.h
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 Travis Geiselbrecht
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a MIT-style
|
||||||
|
* license that can be found in the LICENSE file or at
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <lk/compiler.h>
|
||||||
|
|
||||||
|
__BEGIN_CDECLS
|
||||||
|
|
||||||
|
uint32_t psci_version(void);
|
||||||
|
int psci_cpu_on(int corenr, ulong entrypoint);
|
||||||
|
void psci_system_off(void);
|
||||||
|
void psci_system_reset(void);
|
||||||
|
|
||||||
|
__END_CDECLS
|
||||||
57
dev/power/psci/psci.c
Normal file
57
dev/power/psci/psci.c
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 Travis Geiselbrecht
|
||||||
|
*
|
||||||
|
* Use of this source code is governed by a MIT-style
|
||||||
|
* license that can be found in the LICENSE file or at
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
#include <dev/power/psci.h>
|
||||||
|
|
||||||
|
#if WITH_LIB_CONSOLE
|
||||||
|
#include <lk/console_cmd.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define PSCI_VERSION 0x84000000
|
||||||
|
#define SYSTEM_OFF 0x84000008
|
||||||
|
#define SYSTEM_RESET 0x84000009
|
||||||
|
|
||||||
|
#if ARCH_ARM
|
||||||
|
#define CPU_ON 0x84000003
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if ARCH_ARM64
|
||||||
|
#define CPU_ON 0xC4000003
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* low level ASM routine to make the raw PSCI call */
|
||||||
|
int psci_call(ulong arg0, ulong arg1, ulong arg2, ulong arg3);
|
||||||
|
|
||||||
|
uint32_t psci_version(void) {
|
||||||
|
return psci_call(PSCI_VERSION, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int psci_cpu_on(int corenr, ulong entrypoint) {
|
||||||
|
return psci_call(CPU_ON, corenr, entrypoint, corenr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void psci_system_off(void) {
|
||||||
|
psci_call(SYSTEM_OFF, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void psci_system_reset(void) {
|
||||||
|
psci_call(SYSTEM_RESET, 0, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if WITH_LIB_CONSOLE
|
||||||
|
|
||||||
|
static int cmd_psci_version(int argc, const console_cmd_args *argv) {
|
||||||
|
int ret = psci_version();
|
||||||
|
printf("PSCI VERSION: 0x%x\n", ret);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
STATIC_COMMAND_START
|
||||||
|
STATIC_COMMAND("psci_version", "show psci version", &cmd_psci_version)
|
||||||
|
STATIC_COMMAND_END(psci);
|
||||||
|
#endif
|
||||||
10
dev/power/psci/rules.mk
Normal file
10
dev/power/psci/rules.mk
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
LOCAL_DIR := $(GET_LOCAL_DIR)
|
||||||
|
|
||||||
|
MODULE := $(LOCAL_DIR)
|
||||||
|
|
||||||
|
MODULE_SRCS += \
|
||||||
|
$(LOCAL_DIR)/psci.c \
|
||||||
|
$(LOCAL_DIR)/psci_asm.S \
|
||||||
|
|
||||||
|
include make/module.mk
|
||||||
|
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
#include <lk/trace.h>
|
#include <lk/trace.h>
|
||||||
#include <dev/bus/pci.h>
|
#include <dev/bus/pci.h>
|
||||||
#include <dev/interrupt/arm_gic.h>
|
#include <dev/interrupt/arm_gic.h>
|
||||||
|
#include <dev/power/psci.h>
|
||||||
#include <dev/timer/arm_generic.h>
|
#include <dev/timer/arm_generic.h>
|
||||||
#include <dev/uart.h>
|
#include <dev/uart.h>
|
||||||
#include <dev/virtio.h>
|
#include <dev/virtio.h>
|
||||||
@@ -65,8 +66,6 @@ static pmm_arena_t arena = {
|
|||||||
.flags = PMM_ARENA_FLAG_KMAP,
|
.flags = PMM_ARENA_FLAG_KMAP,
|
||||||
};
|
};
|
||||||
|
|
||||||
extern int psci_call(ulong arg0, ulong arg1, ulong arg2, ulong arg3);
|
|
||||||
|
|
||||||
// callbacks to the fdt_walk routine
|
// callbacks to the fdt_walk routine
|
||||||
static void memcallback(uint64_t base, uint64_t len, void *cookie) {
|
static void memcallback(uint64_t base, uint64_t len, void *cookie) {
|
||||||
bool *found_mem = (bool *)cookie;
|
bool *found_mem = (bool *)cookie;
|
||||||
@@ -157,13 +156,9 @@ void platform_early_init(void) {
|
|||||||
LTRACEF("booting %d cpus\n", cpu_count);
|
LTRACEF("booting %d cpus\n", cpu_count);
|
||||||
|
|
||||||
/* boot the secondary cpus using the Power State Coordintion Interface */
|
/* boot the secondary cpus using the Power State Coordintion Interface */
|
||||||
ulong psci_call_num = 0x84000000 + 3; /* SMC32 CPU_ON */
|
|
||||||
#if ARCH_ARM64
|
|
||||||
psci_call_num += 0x40000000; /* SMC64 */
|
|
||||||
#endif
|
|
||||||
for (int cpuid = 1; cpuid < cpu_count; cpuid++) {
|
for (int cpuid = 1; cpuid < cpu_count; cpuid++) {
|
||||||
/* note: assumes cpuids are numbered like MPIDR 0:0:0:N */
|
/* note: assumes cpuids are numbered like MPIDR 0:0:0:N */
|
||||||
int ret = psci_call(psci_call_num, cpuid, MEMBASE + KERNEL_LOAD_OFFSET, cpuid);
|
int ret = psci_cpu_on(cpuid, MEMBASE + KERNEL_LOAD_OFFSET);
|
||||||
if (ret != 0) {
|
if (ret != 0) {
|
||||||
printf("ERROR: psci CPU_ON returns %d\n", ret);
|
printf("ERROR: psci CPU_ON returns %d\n", ret);
|
||||||
}
|
}
|
||||||
@@ -287,7 +282,7 @@ status_t platform_allocate_interrupts(size_t count, uint align_log2, bool msi, u
|
|||||||
}
|
}
|
||||||
|
|
||||||
status_t platform_compute_msi_values(unsigned int vector, unsigned int cpu, bool edge,
|
status_t platform_compute_msi_values(unsigned int vector, unsigned int cpu, bool edge,
|
||||||
uint64_t *msi_address_out, uint16_t *msi_data_out) {
|
uint64_t *msi_address_out, uint16_t *msi_data_out) {
|
||||||
|
|
||||||
// only handle edge triggered at the moment
|
// only handle edge triggered at the moment
|
||||||
DEBUG_ASSERT(edge);
|
DEBUG_ASSERT(edge);
|
||||||
@@ -301,3 +296,18 @@ status_t platform_compute_msi_values(unsigned int vector, unsigned int cpu, bool
|
|||||||
|
|
||||||
return NO_ERROR;
|
return NO_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void platform_halt(platform_halt_action suggested_action, platform_halt_reason reason) {
|
||||||
|
switch (suggested_action) {
|
||||||
|
case HALT_ACTION_SHUTDOWN:
|
||||||
|
case HALT_ACTION_HALT:
|
||||||
|
psci_system_off();
|
||||||
|
break;
|
||||||
|
case HALT_ACTION_REBOOT:
|
||||||
|
psci_system_reset();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
dprintf(ALWAYS, "HALT: spinning forever... (reason = %d)\n", reason);
|
||||||
|
arch_disable_ints();
|
||||||
|
for (;;);
|
||||||
|
}
|
||||||
|
|||||||
@@ -18,7 +18,6 @@ LK_HEAP_IMPLEMENTATION ?= dlmalloc
|
|||||||
MODULE_SRCS += \
|
MODULE_SRCS += \
|
||||||
$(LOCAL_DIR)/debug.c \
|
$(LOCAL_DIR)/debug.c \
|
||||||
$(LOCAL_DIR)/platform.c \
|
$(LOCAL_DIR)/platform.c \
|
||||||
$(LOCAL_DIR)/secondary_boot.S \
|
|
||||||
$(LOCAL_DIR)/uart.c
|
$(LOCAL_DIR)/uart.c
|
||||||
|
|
||||||
MEMBASE := 0x40000000
|
MEMBASE := 0x40000000
|
||||||
@@ -26,15 +25,16 @@ MEMSIZE ?= 0x08000000 # 512MB
|
|||||||
KERNEL_LOAD_OFFSET := 0x100000 # 1MB
|
KERNEL_LOAD_OFFSET := 0x100000 # 1MB
|
||||||
|
|
||||||
MODULE_DEPS += \
|
MODULE_DEPS += \
|
||||||
lib/cbuf \
|
|
||||||
lib/fdtwalk \
|
|
||||||
dev/bus/pci \
|
dev/bus/pci \
|
||||||
dev/bus/pci/drivers \
|
dev/bus/pci/drivers \
|
||||||
dev/interrupt/arm_gic \
|
dev/interrupt/arm_gic \
|
||||||
|
dev/power/psci \
|
||||||
dev/timer/arm_generic \
|
dev/timer/arm_generic \
|
||||||
dev/virtio/block \
|
dev/virtio/block \
|
||||||
dev/virtio/gpu \
|
dev/virtio/gpu \
|
||||||
dev/virtio/net \
|
dev/virtio/net \
|
||||||
|
lib/cbuf \
|
||||||
|
lib/fdtwalk \
|
||||||
|
|
||||||
GLOBAL_DEFINES += \
|
GLOBAL_DEFINES += \
|
||||||
MEMBASE=$(MEMBASE) \
|
MEMBASE=$(MEMBASE) \
|
||||||
|
|||||||
Reference in New Issue
Block a user