323 lines
9 KiB
C
323 lines
9 KiB
C
/* Copyright 2013-2016 IBM Corp.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
* implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#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;
|
|
|
|
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;
|
|
};
|
|
|
|
/* 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 */
|
|
};
|
|
|
|
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;
|
|
|
|
/* NPU2 device detection */
|
|
void (*npu2_device_detect)(struct npu2 *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 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);
|
|
|
|
/*
|
|
* 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
|
|
* preivous start_preload_resource call for this resource.
|
|
* If not implemented, will return true and start_preload_resource
|
|
* *must* have synchronously done the load.
|
|
* Retruns 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,
|
|
uint64_t *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 */
|