Aaron Durbin | bdf913a | 2014-02-24 14:56:34 -0600 | [diff] [blame] | 1 | /* |
| 2 | * This file is part of the coreboot project. |
| 3 | * |
Aaron Durbin | 04654a2 | 2015-03-17 11:43:44 -0500 | [diff] [blame] | 4 | * Copyright 2015 Google Inc. |
Ionela Voinescu | 00903e5 | 2015-01-09 13:14:20 +0000 | [diff] [blame] | 5 | * Copyright (C) 2014 Imagination Technologies |
Aaron Durbin | bdf913a | 2014-02-24 14:56:34 -0600 | [diff] [blame] | 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; version 2 of the License. |
| 10 | * |
| 11 | * This program is distributed in the hope that it will be useful, |
| 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 14 | * GNU General Public License for more details. |
| 15 | * |
| 16 | * You should have received a copy of the GNU General Public License |
| 17 | * along with this program; if not, write to the Free Software |
| 18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| 19 | */ |
Aaron Durbin | 04654a2 | 2015-03-17 11:43:44 -0500 | [diff] [blame] | 20 | #ifndef PROGRAM_LOADING_H |
| 21 | #define PROGRAM_LOADING_H |
Aaron Durbin | bdf913a | 2014-02-24 14:56:34 -0600 | [diff] [blame] | 22 | |
| 23 | #include <stdint.h> |
| 24 | #include <stddef.h> |
| 25 | |
Aaron Durbin | 6e76fff | 2015-03-20 09:42:05 -0500 | [diff] [blame] | 26 | enum { |
| 27 | /* Last segment of program. Can be used to take different actions for |
| 28 | * cache maintenance of a program load. */ |
| 29 | SEG_FINAL = 1 << 0, |
| 30 | }; |
Ionela Voinescu | 00903e5 | 2015-01-09 13:14:20 +0000 | [diff] [blame] | 31 | |
Aaron Durbin | 3948e53 | 2015-03-20 13:00:20 -0500 | [diff] [blame] | 32 | /* Called for each segment of a program loaded. The SEG_FINAL flag will be |
Aaron Durbin | 6e76fff | 2015-03-20 09:42:05 -0500 | [diff] [blame] | 33 | * set on the last segment loaded. */ |
| 34 | void arch_segment_loaded(uintptr_t start, size_t size, int flags); |
Ionela Voinescu | 00903e5 | 2015-01-09 13:14:20 +0000 | [diff] [blame] | 35 | |
Aaron Durbin | 3948e53 | 2015-03-20 13:00:20 -0500 | [diff] [blame] | 36 | struct buffer_area { |
| 37 | void *data; |
| 38 | size_t size; |
| 39 | }; |
| 40 | |
| 41 | enum prog_type { |
| 42 | PROG_ROMSTAGE, |
| 43 | PROG_RAMSTAGE, |
| 44 | PROG_PAYLOAD, |
| 45 | }; |
| 46 | |
| 47 | /* Representation of a program. */ |
| 48 | struct prog { |
| 49 | enum prog_type type; |
| 50 | const char *name; |
| 51 | /* The area can mean different things depending on what type the |
| 52 | * program is. e.g. a payload prog uses this field for the backing |
| 53 | * store of the payload_segments and data. */ |
| 54 | struct buffer_area area; |
| 55 | /* Entry to program with optional argument. It's up to the architecture |
| 56 | * to decide if argument is passed. */ |
| 57 | void (*entry)(void *); |
| 58 | void *arg; |
| 59 | }; |
| 60 | |
| 61 | static inline size_t prog_size(const struct prog *prog) |
| 62 | { |
| 63 | return prog->area.size; |
| 64 | } |
| 65 | |
| 66 | static inline void *prog_start(const struct prog *prog) |
| 67 | { |
| 68 | return prog->area.data; |
| 69 | } |
| 70 | |
| 71 | static inline void *prog_entry(const struct prog *prog) |
| 72 | { |
| 73 | return prog->entry; |
| 74 | } |
| 75 | |
| 76 | static inline void *prog_entry_arg(const struct prog *prog) |
| 77 | { |
| 78 | return prog->arg; |
| 79 | } |
| 80 | |
| 81 | static inline void prog_set_area(struct prog *prog, void *start, size_t size) |
| 82 | { |
| 83 | prog->area.data = start; |
| 84 | prog->area.size = size; |
| 85 | } |
| 86 | |
| 87 | static inline void prog_set_entry(struct prog *prog, void *e, void *arg) |
| 88 | { |
| 89 | prog->entry = e; |
| 90 | prog->arg = arg; |
| 91 | } |
| 92 | |
Aaron Durbin | b3847e6 | 2015-03-20 15:55:08 -0500 | [diff] [blame^] | 93 | /* Run the program described by prog. */ |
| 94 | void prog_run(struct prog *prog); |
| 95 | /* Per architecture implementation running a program. */ |
| 96 | void arch_prog_run(struct prog *prog); |
| 97 | /* Platform (SoC/chipset) specific overrides for running a program. This is |
| 98 | * called prior to calling the arch_prog_run. Thus, if there is anything |
| 99 | * special that needs to be done by the platform similar to the architecture |
| 100 | * code it needs to that as well. */ |
| 101 | void platform_prog_run(struct prog *prog); |
| 102 | |
Aaron Durbin | d1b0e87 | 2015-03-17 13:17:06 -0500 | [diff] [blame] | 103 | /************************ |
| 104 | * ROMSTAGE LOADING * |
| 105 | ************************/ |
| 106 | |
| 107 | /* Run romstage from bootblock. */ |
| 108 | void run_romstage(void); |
Aaron Durbin | 04654a2 | 2015-03-17 11:43:44 -0500 | [diff] [blame] | 109 | |
| 110 | /************************ |
| 111 | * RAMSTAGE LOADING * |
| 112 | ************************/ |
| 113 | |
Aaron Durbin | fcfdff8 | 2015-03-20 10:58:41 -0500 | [diff] [blame] | 114 | struct romstage_handoff; |
Aaron Durbin | 3948e53 | 2015-03-20 13:00:20 -0500 | [diff] [blame] | 115 | #if IS_ENABLED(CONFIG_RELOCATABLE_RAMSTAGE) |
| 116 | /* Cache the loaded ramstage described by prog. */ |
| 117 | void cache_loaded_ramstage(struct romstage_handoff *, struct prog *p); |
| 118 | /* Load ramstage from cache filling in struct prog. */ |
| 119 | void load_cached_ramstage(struct romstage_handoff *h, struct prog *p); |
| 120 | #else |
| 121 | static inline void cache_loaded_ramstage(struct romstage_handoff *h, |
| 122 | struct prog *p) {} |
| 123 | static inline void load_cached_ramstage(struct romstage_handoff *h, |
| 124 | struct prog *p) {} |
| 125 | #endif |
Aaron Durbin | fcfdff8 | 2015-03-20 10:58:41 -0500 | [diff] [blame] | 126 | |
Aaron Durbin | 04654a2 | 2015-03-17 11:43:44 -0500 | [diff] [blame] | 127 | /* Run ramstage from romstage. */ |
| 128 | void run_ramstage(void); |
| 129 | |
| 130 | struct ramstage_loader_ops { |
| 131 | const char *name; |
Aaron Durbin | 3948e53 | 2015-03-20 13:00:20 -0500 | [diff] [blame] | 132 | /* Returns 0 on succes. < 0 on error. */ |
| 133 | int (*load)(struct prog *ramstage); |
Aaron Durbin | 04654a2 | 2015-03-17 11:43:44 -0500 | [diff] [blame] | 134 | }; |
| 135 | |
| 136 | /*********************** |
| 137 | * PAYLOAD LOADING * |
| 138 | ***********************/ |
| 139 | |
Aaron Durbin | bdf913a | 2014-02-24 14:56:34 -0600 | [diff] [blame] | 140 | struct payload { |
Aaron Durbin | 3948e53 | 2015-03-20 13:00:20 -0500 | [diff] [blame] | 141 | struct prog prog; |
Aaron Durbin | e58a24b | 2014-02-24 22:11:45 -0600 | [diff] [blame] | 142 | /* Used when payload wants memory coreboot ramstage is running at. */ |
| 143 | struct buffer_area bounce; |
Aaron Durbin | bdf913a | 2014-02-24 14:56:34 -0600 | [diff] [blame] | 144 | }; |
| 145 | |
Aaron Durbin | ebf2ed4 | 2015-03-20 10:20:15 -0500 | [diff] [blame] | 146 | /* Load payload into memory in preparation to run. */ |
| 147 | void payload_load(void); |
Aaron Durbin | bdf913a | 2014-02-24 14:56:34 -0600 | [diff] [blame] | 148 | |
| 149 | /* Run the loaded payload. */ |
Aaron Durbin | ebf2ed4 | 2015-03-20 10:20:15 -0500 | [diff] [blame] | 150 | void payload_run(void); |
Aaron Durbin | bdf913a | 2014-02-24 14:56:34 -0600 | [diff] [blame] | 151 | |
Aaron Durbin | c34713d | 2014-02-25 20:36:56 -0600 | [diff] [blame] | 152 | /* Mirror the payload to be loaded. */ |
| 153 | void mirror_payload(struct payload *payload); |
| 154 | |
Aaron Durbin | 7d1996c | 2014-02-24 22:27:39 -0600 | [diff] [blame] | 155 | /* architecture specific function to run payload. */ |
Aaron Durbin | b3847e6 | 2015-03-20 15:55:08 -0500 | [diff] [blame^] | 156 | void arch_payload_run(struct payload *payload); |
Aaron Durbin | 7d1996c | 2014-02-24 22:27:39 -0600 | [diff] [blame] | 157 | |
Aaron Durbin | bdf913a | 2014-02-24 14:56:34 -0600 | [diff] [blame] | 158 | /* Payload loading operations. */ |
| 159 | struct payload_loader_ops { |
| 160 | const char *name; |
| 161 | /* |
| 162 | * Fill in payload_backing_store structure. Return 0 on success, < 0 |
| 163 | * on failure. |
| 164 | */ |
| 165 | int (*locate)(struct payload *payload); |
| 166 | }; |
| 167 | |
| 168 | /* Defined in src/lib/selfboot.c */ |
Aaron Durbin | ceebc05 | 2014-02-25 00:21:10 -0600 | [diff] [blame] | 169 | void *selfload(struct payload *payload); |
Aaron Durbin | bdf913a | 2014-02-24 14:56:34 -0600 | [diff] [blame] | 170 | |
Aaron Durbin | 04654a2 | 2015-03-17 11:43:44 -0500 | [diff] [blame] | 171 | |
| 172 | #endif /* PROGRAM_LOADING_H */ |