mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-22 06:57:51 +00:00
hw: Add interface for making basic ARM PSCI calls.
So far this only exposes two functions allowing the code to turn on additional CPUs. There is much more functionality defined by PSCI spec but so far its not needed by Genode. Fixes #3672
This commit is contained in:
parent
6f1357c6f8
commit
dad1de1865
61
repos/base-hw/src/include/hw/spec/arm/psci.h
Normal file
61
repos/base-hw/src/include/hw/spec/arm/psci.h
Normal file
@ -0,0 +1,61 @@
|
||||
/**
|
||||
* \brief Power State Coordination Interface 1.0
|
||||
* \author Piotr Tworek
|
||||
* \date 2019-11-27
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2019 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _SRC__INCLUDE__HW__SPEC__ARM__PSCI_H_
|
||||
#define _SRC__INCLUDE__HW__SPEC__ARM__PSCI_H_
|
||||
|
||||
namespace Hw { template <typename CONDUIT_FUNCTOR> class Psci; }
|
||||
|
||||
template <typename CONDUIT_FUNCTOR>
|
||||
class Hw::Psci
|
||||
{
|
||||
private:
|
||||
|
||||
enum {
|
||||
PSCI_32_BASE = 0x84000000,
|
||||
PSCI_64_BASE = 0xC4000000,
|
||||
};
|
||||
|
||||
enum {
|
||||
CPU_OFF = 2,
|
||||
CPU_ON = 3,
|
||||
};
|
||||
|
||||
static inline constexpr bool _arch_32() {
|
||||
return sizeof(unsigned long) == 4; }
|
||||
|
||||
static inline constexpr unsigned long _psci_func(int func,
|
||||
bool only_32)
|
||||
{
|
||||
return ((only_32 || _arch_32()) ? PSCI_32_BASE
|
||||
: PSCI_64_BASE) + func;
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
static bool cpu_on(unsigned long cpu_id, void *entrypoint)
|
||||
{
|
||||
return CONDUIT_FUNCTOR::call(_psci_func(CPU_ON, false),
|
||||
cpu_id,
|
||||
(unsigned long)entrypoint,
|
||||
cpu_id) == 0;
|
||||
}
|
||||
|
||||
static bool cpu_off()
|
||||
{
|
||||
return CONDUIT_FUNCTOR::call(_psci_func(CPU_OFF, true),
|
||||
0, 0, 0) == 0;
|
||||
}
|
||||
};
|
||||
|
||||
#endif /* _SRC__INCLUDE__HW__SPEC__ARM__PSCI_H_ */
|
42
repos/base-hw/src/include/hw/spec/arm/psci_call.h
Normal file
42
repos/base-hw/src/include/hw/spec/arm/psci_call.h
Normal file
@ -0,0 +1,42 @@
|
||||
/**
|
||||
* \brief PSCI call macro for arm_v7
|
||||
* \author Piotr Tworek
|
||||
* \date 2019-11-27
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2019 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _SRC__INCLUDE__HW__SPEC__ARM__PSCI_CALL_H_
|
||||
#define _SRC__INCLUDE__HW__SPEC__ARM__PSCI_CALL_H_
|
||||
|
||||
#include <hw/spec/arm/psci.h>
|
||||
|
||||
#define PSCI_CALL_IMPL(instr) \
|
||||
static inline int call(unsigned int func, unsigned long a0, \
|
||||
unsigned int a1, unsigned int a2) { \
|
||||
unsigned long result = 0; \
|
||||
asm volatile ("mov r0, %1 \n" \
|
||||
"mov r1, %2 \n" \
|
||||
"mov r2, %3 \n" \
|
||||
"mov r3, %4 \n" \
|
||||
#instr " #0 \n" \
|
||||
"mov %0, r0 \n" \
|
||||
: "=r"(result) \
|
||||
: "r"(func), "r"(a0), "r"(a1), "r"(a2) \
|
||||
: "r0", "r1", "r2", "r3"); \
|
||||
return result; \
|
||||
}
|
||||
|
||||
namespace Hw {
|
||||
struct Psci_hvc_functor { PSCI_CALL_IMPL(hvc); };
|
||||
struct Psci_smc_functor { PSCI_CALL_IMPL(smc); };
|
||||
}
|
||||
|
||||
#undef PSCI_CALL_IMPL
|
||||
|
||||
#endif /* _SRC__INCLUDE__HW__SPEC__ARM__PSCI_CALL_H_ */
|
43
repos/base-hw/src/include/hw/spec/arm_64/psci_call.h
Normal file
43
repos/base-hw/src/include/hw/spec/arm_64/psci_call.h
Normal file
@ -0,0 +1,43 @@
|
||||
/**
|
||||
* \brief PSCI call macro for arm_v8
|
||||
* \author Piotr Tworek
|
||||
* \date 2019-11-27
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2019 Genode Labs GmbH
|
||||
*
|
||||
* This file is part of the Genode OS framework, which is distributed
|
||||
* under the terms of the GNU Affero General Public License version 3.
|
||||
*/
|
||||
|
||||
#ifndef _SRC__INCLUDE__HW__SPEC__ARM__PSCI_CALL_H_
|
||||
#define _SRC__INCLUDE__HW__SPEC__ARM__PSCI_CALL_H_
|
||||
|
||||
#include <hw/spec/arm/psci.h>
|
||||
|
||||
#define PSCI_CALL_IMPL(instr) \
|
||||
static inline int call(unsigned int func, unsigned long a0, \
|
||||
unsigned int a1, unsigned int a2) { \
|
||||
unsigned long result = 0; \
|
||||
asm volatile ("mov x0, %1 \n" \
|
||||
"mov x1, %2 \n" \
|
||||
"mov x2, %3 \n" \
|
||||
"mov x3, %4 \n" \
|
||||
#instr " #0 \n" \
|
||||
"mov %0, x0 \n" \
|
||||
: "=r"(result) \
|
||||
: "r"(func), "r"(a0), "r"(a1), "r"(a2) \
|
||||
: "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7", \
|
||||
"x8", "x9", "x10", "x11", "x12", "x13", "x14"); \
|
||||
return result; \
|
||||
}
|
||||
|
||||
namespace Hw {
|
||||
struct Psci_hvc_functor { PSCI_CALL_IMPL(hvc); };
|
||||
struct Psci_smc_functor { PSCI_CALL_IMPL(smc); };
|
||||
}
|
||||
|
||||
#undef PSCI_CALL_IMPL
|
||||
|
||||
#endif /* _SRC__INCLUDE__HW__SPEC__ARM__PSCI_CALL_H_ */
|
Loading…
Reference in New Issue
Block a user