blob: 481a8bc54acd11ad42524f44d76cbee7ff797907 [file] [log] [blame]
Aaron Durbin7e35efa2013-04-24 15:14:01 -05001/*
2 * This file is part of the coreboot project.
3 *
4 * Copyright (C) 2013 Google, Inc.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; version 2 of the License.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
Aaron Durbin7e35efa2013-04-24 15:14:01 -050014 */
15#ifndef BOOTSTATE_H
16#define BOOTSTATE_H
17
Aaron Durbin4d3de7e2015-09-02 17:34:04 -050018#include <rules.h>
Aaron Durbin7e35efa2013-04-24 15:14:01 -050019#include <string.h>
Aaron Durbin9ef9d852015-03-16 17:30:09 -050020#include <stdlib.h>
21#include <stddef.h>
22#include <stdint.h>
Aaron Durbin622eea72016-02-10 23:15:07 -060023/* Only declare main() when in ramstage. */
24#if ENV_RAMSTAGE
25#include <main_decl.h>
26#endif
Aaron Durbin7e35efa2013-04-24 15:14:01 -050027
Aaron Durbin7e35efa2013-04-24 15:14:01 -050028/*
29 * The boot state machine provides a mechanism for calls to be made through-
30 * out the main boot process. The boot process is separated into discrete
31 * states. Upon a state's entry and exit and callbacks can be made. For
32 * example:
33 *
34 * Enter State
35 * +
36 * |
37 * V
38 * +-----------------+
39 * | Entry callbacks |
40 * +-----------------+
41 * | State Actions |
42 * +-----------------+
43 * | Exit callbacks |
44 * +-------+---------+
45 * |
46 * V
47 * Next State
48 *
49 * Below is the current flow from top to bottom:
50 *
51 * start
52 * |
53 * BS_PRE_DEVICE
54 * |
55 * BS_DEV_INIT_CHIPS
56 * |
57 * BS_DEV_ENUMERATE
58 * |
59 * BS_DEV_RESOURCES
60 * |
61 * BS_DEV_ENABLE
62 * |
63 * BS_DEV_INIT
64 * |
65 * BS_POST_DEVICE
66 * |
67 * BS_OS_RESUME_CHECK -------- BS_OS_RESUME
68 * | |
69 * BS_WRITE_TABLES os handoff
70 * |
71 * BS_PAYLOAD_LOAD
72 * |
73 * BS_PAYLOAD_BOOT
74 * |
75 * payload run
76 *
77 * Brief description of states:
78 * BS_PRE_DEVICE - before any device tree actions take place
79 * BS_DEV_INIT_CHIPS - init all chips in device tree
80 * BS_DEV_ENUMERATE - device tree probing
81 * BS_DEV_RESOURCES - device tree resource allocation and assignment
82 * BS_DEV_ENABLE - device tree enabling/disabling of devices
83 * BS_DEV_INIT - device tree device initialization
84 * BS_POST_DEVICE - all device tree actions performed
85 * BS_OS_RESUME_CHECK - check for OS resume
86 * BS_OS_RESUME - resume to OS
87 * BS_WRITE_TABLES - write coreboot tables
88 * BS_PAYLOAD_LOAD - Load payload into memory
89 * BS_PAYLOAD_BOOT - Boot to payload
90 */
91
92typedef enum {
93 BS_PRE_DEVICE,
94 BS_DEV_INIT_CHIPS,
95 BS_DEV_ENUMERATE,
96 BS_DEV_RESOURCES,
97 BS_DEV_ENABLE,
98 BS_DEV_INIT,
99 BS_POST_DEVICE,
Aaron Durbin0a6c20a2013-04-24 22:33:08 -0500100 BS_OS_RESUME_CHECK,
Aaron Durbin7e35efa2013-04-24 15:14:01 -0500101 BS_OS_RESUME,
102 BS_WRITE_TABLES,
103 BS_PAYLOAD_LOAD,
104 BS_PAYLOAD_BOOT,
105} boot_state_t;
106
107/* The boot_state_sequence_t describes when a callback is to be made. It is
108 * called either before a state is entered or when a state is exited. */
109typedef enum {
110 BS_ON_ENTRY,
111 BS_ON_EXIT
112} boot_state_sequence_t;
113
114struct boot_state_callback {
115 void *arg;
116 void (*callback)(void *arg);
117 /* For use internal to the boot state machine. */
118 struct boot_state_callback *next;
Lee Leahy10605352016-02-14 17:01:40 -0800119#if IS_ENABLED(CONFIG_DEBUG_BOOT_STATE)
Aaron Durbin7e35efa2013-04-24 15:14:01 -0500120 const char *location;
121#endif
122};
123
Lee Leahy10605352016-02-14 17:01:40 -0800124#if IS_ENABLED(CONFIG_DEBUG_BOOT_STATE)
Aaron Durbin7e35efa2013-04-24 15:14:01 -0500125#define BOOT_STATE_CALLBACK_LOC __FILE__ ":" STRINGIFY(__LINE__)
126#define BOOT_STATE_CALLBACK_INIT_DEBUG .location = BOOT_STATE_CALLBACK_LOC,
127#define INIT_BOOT_STATE_CALLBACK_DEBUG(bscb_) \
128 bscb_->location = BOOT_STATE_CALLBACK_LOC;
129#else
130#define BOOT_STATE_CALLBACK_INIT_DEBUG
131#define INIT_BOOT_STATE_CALLBACK_DEBUG(bscb_)
132#endif
133
134#define BOOT_STATE_CALLBACK_INIT(func_, arg_) \
135 { \
136 .arg = arg_, \
137 .callback = func_, \
138 .next = NULL, \
139 BOOT_STATE_CALLBACK_INIT_DEBUG \
140 }
141
142#define BOOT_STATE_CALLBACK(name_, func_, arg_) \
143 struct boot_state_callback name_ = BOOT_STATE_CALLBACK_INIT(func_, arg_)
144
145/* Initialize an allocated boot_state_callback. */
146#define INIT_BOOT_STATE_CALLBACK(bscb_, func_, arg_) \
147 INIT_BOOT_STATE_CALLBACK_DEBUG(bscb_) \
148 bscb_->callback = func_; \
149 bscb_->arg = arg_
150
151/* The following 2 functions schedule a callback to be called on entry/exit
Martin Roth0cb07e32013-07-09 21:46:01 -0600152 * to a given state. Note that there are no ordering guarantees between the
Aaron Durbin7e35efa2013-04-24 15:14:01 -0500153 * individual callbacks on a given state. 0 is returned on success < 0 on
154 * error. */
155int boot_state_sched_on_entry(struct boot_state_callback *bscb,
156 boot_state_t state);
157int boot_state_sched_on_exit(struct boot_state_callback *bscb,
158 boot_state_t state);
Aaron Durbin9ef9d852015-03-16 17:30:09 -0500159/* Schedule an array of entries of size num. */
160struct boot_state_init_entry;
161void boot_state_sched_entries(struct boot_state_init_entry *entries,
162 size_t num);
Aaron Durbin7e35efa2013-04-24 15:14:01 -0500163
Aaron Durbin0748d302013-05-06 10:50:19 -0500164/* Block/Unblock the (state, seq) pair from transitioning. Returns 0 on
165 * success < 0 when the phase of the (state,seq) has already ran. */
166int boot_state_block(boot_state_t state, boot_state_sequence_t seq);
167int boot_state_unblock(boot_state_t state, boot_state_sequence_t seq);
168/* Block/Unblock current state phase from transitioning. */
169void boot_state_current_block(void);
170void boot_state_current_unblock(void);
171
Aaron Durbina4feddf2013-04-24 16:12:52 -0500172/* In order to schedule boot state callbacks at compile-time specify the
173 * entries in an array using the BOOT_STATE_INIT_ENTRIES and
174 * BOOT_STATE_INIT_ENTRY macros below. */
175struct boot_state_init_entry {
176 boot_state_t state;
177 boot_state_sequence_t when;
178 struct boot_state_callback bscb;
179};
180
Aaron Durbin4d3de7e2015-09-02 17:34:04 -0500181#if ENV_RAMSTAGE
Aaron Durbina4feddf2013-04-24 16:12:52 -0500182#define BOOT_STATE_INIT_ATTR __attribute__ ((used,section (".bs_init")))
Aaron Durbin4d3de7e2015-09-02 17:34:04 -0500183#else
184#define BOOT_STATE_INIT_ATTR __attribute__ ((unused))
185#endif
Aaron Durbina4feddf2013-04-24 16:12:52 -0500186
Aaron Durbin9ef9d852015-03-16 17:30:09 -0500187#define BOOT_STATE_INIT_ENTRY(state_, when_, func_, arg_) \
188 static struct boot_state_init_entry func_ ##_## state_ ##_## when_ = \
189 { \
190 .state = state_, \
191 .when = when_, \
192 .bscb = BOOT_STATE_CALLBACK_INIT(func_, arg_), \
193 }; \
194 static struct boot_state_init_entry * \
195 bsie_ ## func_ ##_## state_ ##_## when_ BOOT_STATE_INIT_ATTR = \
196 & func_ ##_## state_ ##_## when_;
Aaron Durbina4feddf2013-04-24 16:12:52 -0500197
Aaron Durbin16bd2672016-12-07 11:58:20 -0600198/* Hook per arch when coreboot is exiting to payload or ACPI OS resume. It's
199 * the very last thing done before the transition. */
200void arch_bootstate_coreboot_exit(void);
201
Aaron Durbin7e35efa2013-04-24 15:14:01 -0500202#endif /* BOOTSTATE_H */