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
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
/*
* This file is part of the coreboot project.
*
* Copyright 2015 Google Inc.
* Copyright (C) 2014 Imagination Technologies
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef PROGRAM_LOADING_H
#define PROGRAM_LOADING_H
#include <stdint.h>
#include <stddef.h>
enum {
/* Last segment of program. Can be used to take different actions for
* cache maintenance of a program load. */
SEG_FINAL = 1 << 0,
};
/* Called for each segment of a program loaded. The SEG_FINAL flag will be
* set on the last segment loaded. */
void arch_segment_loaded(uintptr_t start, size_t size, int flags);
struct buffer_area {
void *data;
size_t size;
};
enum prog_type {
PROG_ROMSTAGE,
PROG_RAMSTAGE,
PROG_PAYLOAD,
};
/* Representation of a program. */
struct prog {
enum prog_type type;
const char *name;
/* The area can mean different things depending on what type the
* program is. e.g. a payload prog uses this field for the backing
* store of the payload_segments and data. */
struct buffer_area area;
/* Entry to program with optional argument. It's up to the architecture
* to decide if argument is passed. */
void (*entry)(void *);
void *arg;
};
static inline size_t prog_size(const struct prog *prog)
{
return prog->area.size;
}
static inline void *prog_start(const struct prog *prog)
{
return prog->area.data;
}
static inline void *prog_entry(const struct prog *prog)
{
return prog->entry;
}
static inline void *prog_entry_arg(const struct prog *prog)
{
return prog->arg;
}
static inline void prog_set_area(struct prog *prog, void *start, size_t size)
{
prog->area.data = start;
prog->area.size = size;
}
static inline void prog_set_entry(struct prog *prog, void *e, void *arg)
{
prog->entry = e;
prog->arg = arg;
}
/* Run the program described by prog. */
void prog_run(struct prog *prog);
/* Per architecture implementation running a program. */
void arch_prog_run(struct prog *prog);
/* Platform (SoC/chipset) specific overrides for running a program. This is
* called prior to calling the arch_prog_run. Thus, if there is anything
* special that needs to be done by the platform similar to the architecture
* code it needs to that as well. */
void platform_prog_run(struct prog *prog);
/************************
* ROMSTAGE LOADING *
************************/
/* Run romstage from bootblock. */
void run_romstage(void);
/************************
* RAMSTAGE LOADING *
************************/
struct romstage_handoff;
#if IS_ENABLED(CONFIG_RELOCATABLE_RAMSTAGE)
/* Cache the loaded ramstage described by prog. */
void cache_loaded_ramstage(struct romstage_handoff *, struct prog *p);
/* Load ramstage from cache filling in struct prog. */
void load_cached_ramstage(struct romstage_handoff *h, struct prog *p);
#else
static inline void cache_loaded_ramstage(struct romstage_handoff *h,
struct prog *p) {}
static inline void load_cached_ramstage(struct romstage_handoff *h,
struct prog *p) {}
#endif
/* Run ramstage from romstage. */
void run_ramstage(void);
struct ramstage_loader_ops {
const char *name;
/* Returns 0 on succes. < 0 on error. */
int (*load)(struct prog *ramstage);
};
/***********************
* PAYLOAD LOADING *
***********************/
struct payload {
struct prog prog;
/* Used when payload wants memory coreboot ramstage is running at. */
struct buffer_area bounce;
};
/* Load payload into memory in preparation to run. */
void payload_load(void);
/* Run the loaded payload. */
void payload_run(void);
/* Mirror the payload to be loaded. */
void mirror_payload(struct payload *payload);
/* architecture specific function to run payload. */
void arch_payload_run(struct payload *payload);
/* Payload loading operations. */
struct payload_loader_ops {
const char *name;
/*
* Fill in payload_backing_store structure. Return 0 on success, < 0
* on failure.
*/
int (*locate)(struct payload *payload);
};
/* Defined in src/lib/selfboot.c */
void *selfload(struct payload *payload);
#endif /* PROGRAM_LOADING_H */
|