aboutsummaryrefslogtreecommitdiff
path: root/include/platform.h
blob: d113e6eb9109dbb8b7859efb61f144a11e2ebd61 (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
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
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
// SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
/* Copyright 2013-2019 IBM Corp. */

#ifndef __PLATFORM_H
#define __PLATFORM_H

/* Some fwd declarations for types used further down */
struct phb;
struct pci_device;
struct pci_slot;
struct errorlog;
struct npu2;
struct npu3;

enum resource_id {
	RESOURCE_ID_KERNEL,
	RESOURCE_ID_INITRAMFS,
	RESOURCE_ID_CAPP,
	RESOURCE_ID_IMA_CATALOG,
	RESOURCE_ID_VERSION,
	RESOURCE_ID_KERNEL_FW,
};
#define RESOURCE_SUBID_NONE 0
#define RESOURCE_SUBID_SUPPORTED 1


struct bmc_hw_config {
	uint32_t scu_revision_id;
	uint32_t mcr_configuration;
	uint32_t mcr_scu_mpll;
	uint32_t mcr_scu_strap;
};

struct bmc_sw_config {
	/*
	 * Map IPMI_OEM_X to vendor commands for this BMC
	 * 0 = unimplimented
	 */
	uint32_t ipmi_oem_partial_add_esel;
	uint32_t ipmi_oem_pnor_access_status;
	uint32_t ipmi_oem_hiomap_cmd;
};

struct bmc_platform {
	const char *name;
	const struct bmc_hw_config *hw;
	const struct bmc_sw_config *sw;
};

struct ocapi_phy_setup {
	int tx_ffe_pre_coeff;
	int tx_ffe_post_coeff;
	int tx_ffe_boost_en;
};

/* OpenCAPI platform-specific I2C information */
struct platform_ocapi {
	uint8_t i2c_engine;		/* I2C engine number */
	uint8_t i2c_port;		/* I2C port number */
	uint8_t i2c_reset_addr;		/* I2C address for reset */
	uint8_t i2c_reset_brick2;	/* I2C pin to write to reset brick 2 */
	uint8_t i2c_reset_brick3;	/* I2C pin to write to reset brick 3 */
	uint8_t i2c_reset_brick4;	/* I2C pin to write to reset brick 4 */
	uint8_t i2c_reset_brick5;	/* I2C pin to write to reset brick 5 */
	uint8_t i2c_presence_addr;	/* I2C address for presence detection */
	uint8_t i2c_presence_brick2;	/* I2C pin to read for presence on brick 2 */
	uint8_t i2c_presence_brick3;	/* I2C pin to read for presence on brick 3 */
	uint8_t i2c_presence_brick4;	/* I2C pin to read for presence on brick 4 */
	uint8_t i2c_presence_brick5;	/* I2C pin to read for presence on brick 5 */
	bool odl_phy_swap;		/* Swap ODL1 to use brick 2 rather than
					 * brick 1 lanes */
	const char *(*ocapi_slot_label)(uint32_t chip_id, uint32_t brick_index);
	const struct ocapi_phy_setup *phy_setup;
};

struct dt_node;

/*
 * Just for FSP platforms, allows us to partly decouple
 * FSP specific code from core code.
 */
struct platform_psi {
	void (*psihb_interrupt)(void);
	void (*link_established)(void);
	void (*fsp_interrupt)(void);
};

/*
 * Some PRD functionality is platform specific.
 */
struct platform_prd {
	void (*msg_response)(uint32_t rc);
	int (*send_error_log)(uint32_t plid, uint32_t dsize, void *data);
	int (*send_hbrt_msg)(void *data, u64 dsize);
	int (*wakeup)(uint32_t i_core, uint32_t i_mode);
	int (*fsp_occ_load_start_status)(u64 chipid, s64 status);
	int (*fsp_occ_reset_status)(u64 chipid, s64 status);
};

/*
 * Each platform can provide a set of hooks
 * that can affect the generic code
 */
struct platform {
	const char	*name;

	/*
	 * If BMC is constant, bmc platform specified here.
	 * Platforms can also call set_bmc_platform() if BMC platform is
	 * not a constant.
	 */
	const struct bmc_platform *bmc;

	/*
	 * PSI handling code. FSP specific.
	 */
	const struct platform_psi *psi;

	/*
	 * Platform specific PRD handling
	 */
	const struct platform_prd *prd;

	/* OpenCAPI platform-specific I2C information */
	const struct platform_ocapi *ocapi;

	/* NPU device detection */
	void		(*npu2_device_detect)(struct npu2 *npu);
	void		(*npu3_device_detect)(struct npu3 *npu);

	/*
	 * Probe platform, return true on a match, called before
	 * any allocation has been performed outside of the heap
	 * so the platform can perform additional memory reservations
	 * here if needed.
	 *
	 * Only the boot CPU is running at this point and the cpu_thread
	 * structure for secondaries have not been initialized yet. The
	 * timebases are not synchronized.
	 *
	 * Services available:
	 *
	 * - Memory allocations / reservations
	 * - XSCOM
	 * - FSI
	 * - Host Services
	 */
	bool		(*probe)(void);

	/*
	 * This is called right after the secondary processors are brought
	 * up and the timebases in sync to perform any additional platform
	 * specific initializations. On FSP based machines, this is where
	 * the FSP driver is brought up.
	 */
	void		(*init)(void);

	/*
	 * Called once every thread is back in skiboot as part of fast reboot.
	 */
	void		(*fast_reboot_init)(void);

	/*
	 * These are used to power down and reboot the machine
	 */
	int64_t		(*cec_power_down)(uint64_t request);
	int64_t		(*cec_reboot)(void);

	/*
	 * This is called once per PHB before probing. It allows the
	 * platform to setup some PHB private data that can be used
	 * later on by calls such as pci_get_slot_info() below. The
	 * "index" argument is the PHB index within the IO HUB (or
	 * P8 chip).
	 *
	 * This is called before the PHB HW has been initialized.
	 */
	void		(*pci_setup_phb)(struct phb *phb, unsigned int index);

	/*
	 * This is called before resetting the PHBs (lift PERST) and
	 * probing the devices. The PHBs have already been initialized.
	 */
	void		(*pre_pci_fixup)(void);
	/*
	 * Called during PCI scan for each device. For bridges, this is
	 * called before its children are probed. This is called for
	 * every device and for the PHB itself with a NULL pd though
	 * typically the implementation will only populate the slot
	 * info structure for bridge ports
	 */
	void		(*pci_get_slot_info)(struct phb *phb,
					     struct pci_device *pd);

	/*
	 * Called for each device during pci_add_device_nodes() descend
	 * to create the device tree, in order to get the correct per-platform
	 * preference for the ibm,loc-code property
	 */
	void		(*pci_add_loc_code)(struct dt_node *np,
					     struct pci_device *pd);

	/*
	 * Called after PCI probe is complete and before inventory is
	 * displayed in console. This can either run platform fixups or
	 * can be used to send the inventory to a service processor.
	 */
	void		(*pci_probe_complete)(void);

	/*
	 * If the above is set to skiboot, the handler is here
	 */
	void		(*external_irq)(unsigned int chip_id);

	/*
	 * nvram ops.
	 *
	 * Note: To keep the FSP driver simple, we only ever read the
	 * whole nvram once at boot and we do this passing a dst buffer
	 * that is 4K aligned. The read is asynchronous, the backend
	 * must call nvram_read_complete() when done (it's allowed to
	 * do it recursively from nvram_read though).
	 */
	int		(*nvram_info)(uint32_t *total_size);
	int		(*nvram_start_read)(void *dst, uint32_t src,
					    uint32_t len);
	int		(*nvram_write)(uint32_t dst, void *src, uint32_t len);

	int (*secvar_init)(void);

	/*
	 * OCC timeout. This return how long we should wait for the OCC
	 * before timing out. This lets us use a high value on larger FSP
	 * machines and cut it off completely on BML boots and OpenPower
	 * machines without pre-existing OCC firmware. Returns a value in
	 * seconds.
	 */
	uint32_t	(*occ_timeout)(void);

	int		(*elog_commit)(struct errorlog *buf);

	/*
	 * Initiate loading an external resource (e.g. kernel payload, OCC)
	 * into a preallocated buffer.
	 * This is designed to asynchronously load external resources.
	 * Returns OPAL_SUCCESS or error.
	 */
	int		(*start_preload_resource)(enum resource_id id,
						  uint32_t idx,
						  void *buf, size_t *len);

	/*
	 * Returns true when resource is loaded.
	 * Only has to return true once, for the
	 * previous start_preload_resource call for this resource.
	 * If not implemented, will return true and start_preload_resource
	 * *must* have synchronously done the load.
	 * Returns OPAL_SUCCESS, OPAL_BUSY or an error code
	 */
	int		(*resource_loaded)(enum resource_id id, uint32_t idx);

	/*
	 * Executed just prior to creating the dtb for the kernel.
	 */
	void		(*finalise_dt)(bool is_reboot);

	/*
	 * Executed just prior to handing control over to the payload.
	 * Used to terminate watchdogs, etc.
	 */
	void		(*exit)(void);

	/*
	 * Read a sensor value
	 */
	int64_t		(*sensor_read)(uint32_t sensor_hndl, int token,
				       __be64 *sensor_data);
	/*
	 * Return the heartbeat time
	 */
	int		(*heartbeat_time)(void);

	/*
	 * OPAL terminate
	 */
	void __attribute__((noreturn)) (*terminate)(const char *msg);

	/*
	 * SEEPROM update routine
	 */
	void		(*seeprom_update)(void);

	/*
	 * Operator Panel display
	 * Physical FSP op panel or LPC port 80h
	 * or any other "get boot status out to the user" thing.
	 */
	void (*op_display)(enum op_severity sev, enum op_module mod,
			   uint16_t code);

	/*
	 * VPD load.
	 * Currently FSP specific.
	 */
	void (*vpd_iohub_load)(struct dt_node *hub_node);
};

extern struct platform __platforms_start;
extern struct platform __platforms_end;

extern struct platform	platform;
extern const struct bmc_platform *bmc_platform;

extern bool manufacturing_mode;

#define DECLARE_PLATFORM(name)\
static const struct platform __used __section(".platforms") name ##_platform

extern void probe_platform(void);

extern int start_preload_resource(enum resource_id id, uint32_t subid,
				  void *buf, size_t *len);

extern int resource_loaded(enum resource_id id, uint32_t idx);

extern int wait_for_resource_loaded(enum resource_id id, uint32_t idx);

extern void set_bmc_platform(const struct bmc_platform *bmc);

#endif /* __PLATFORM_H */