aboutsummaryrefslogtreecommitdiff
path: root/include/opal-internal.h
blob: fd2187f09df121328ec16ab5b53d0f7a95bc2bf4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// SPDX-License-Identifier: Apache-2.0
/*
 * Internal header for OPAL API related things in skiboot
 *
 * Copyright 2013-2019 IBM Corp.
 */

#ifndef __OPAL_INTERNAL_H
#define __OPAL_INTERNAL_H


#include <skiboot.h>

/* An opal table entry */
struct opal_table_entry {
	void	*func;
	u32	token;
	u32	nargs;
};

#ifdef __CHECKER__
#define __opal_func_test_arg(__func, __nargs) 0
#else
#define __opal_func_test_arg(__func, __nargs) 				\
	sizeof(__func( __test_args##__nargs ))
#endif

#define opal_call(__tok, __func, __nargs)				\
static struct opal_table_entry __e_##__func __used __section(".opal_table") = \
{ .func = __func, .token = __tok,					\
  .nargs = __nargs + 0 * __opal_func_test_arg(__func, __nargs) }

/* Make sure function takes args they claim.  Look away now... */
#define __test_args0
#define __test_args1 0
#define __test_args2 0,0
#define __test_args3 0,0,0
#define __test_args4 0,0,0,0
#define __test_args5 0,0,0,0,0
#define __test_args6 0,0,0,0,0,0
#define __test_args7 0,0,0,0,0,0,0

extern struct opal_table_entry __opal_table_start[];
extern struct opal_table_entry __opal_table_end[];

extern uint64_t opal_pending_events;

extern struct dt_node *opal_node;

extern void opal_table_init(void);
extern void opal_update_pending_evt(uint64_t evt_mask, uint64_t evt_values);
__be64 opal_dynamic_event_alloc(void);
void opal_dynamic_event_free(__be64 event);
extern void add_opal_node(void);

#define opal_register(token, func, nargs)				\
	__opal_register((token) + 0*__opal_func_test_arg(func, nargs),	\
			(func), (nargs))
extern void __opal_register(uint64_t token, void *func, unsigned num_args);

int64_t opal_quiesce(uint32_t shutdown_type, int32_t cpu);

/* Warning: no locking at the moment, do at init time only
 *
 * XXX TODO: Add the big RCU-ish "opal API lock" to protect us here
 * which will also be used for other things such as runtime updates
 */
extern void opal_add_poller(void (*poller)(void *data), void *data);
extern void opal_del_poller(void (*poller)(void *data));
extern void opal_run_pollers(void);

/*
 * Warning: no locking, only call that from the init processor
 */
extern void opal_add_host_sync_notifier(bool (*notify)(void *data), void *data);
extern void opal_del_host_sync_notifier(bool (*notify)(void *data), void *data);

/*
 * Opal internal function prototype
 */
struct OpalHMIEvent;
extern int occ_msg_queue_occ_reset(void);

extern unsigned long top_of_ram;

/*
 * Returns true if the address is valid, false otherwise
 *
 * Checks if the passed address belongs to real address space
 * or 0xc000... kernel address space. It also checks that
 * addr <= total physical memory. The magic value 60 comes
 * from 60 bit real address mentioned in section 5.7 of the
 * Power ISA (Book 3S).
 */
static inline bool opal_addr_valid(const void *addr)
{
	unsigned long val = (unsigned long)addr;
	if ((val >> 60) != 0xc && (val >> 60) != 0x0)
		return false;
	val &= ~0xf000000000000000UL;
	if (val > top_of_ram)
		return false;
	return true;
}

#endif /* __OPAL_INTERNAL_H */