Import U-Boot v2026.07 (unmodified upstream source, base for rtwo patches)

This commit is contained in:
2026-09-16 23:15:56 -03:00
commit 391981275c
38022 changed files with 8370285 additions and 0 deletions
+47
View File
@@ -0,0 +1,47 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2003
* Steven Scholz, imc Measurement & Control, steven.scholz@imc-berlin.de
*
* (C) Copyright 2002
* Rich Ireland, Enterasys Networks, rireland@enterasys.com.
*/
#ifndef _ACEX1K_H_
#define _ACEX1K_H_
#include <altera.h>
extern int CYC2_load(Altera_desc *desc, const void *image, size_t size);
extern int CYC2_dump(Altera_desc *desc, const void *buf, size_t bsize);
extern int CYC2_info(Altera_desc *desc);
/* Slave Serial Implementation function table */
typedef struct {
Altera_pre_fn pre;
Altera_config_fn config;
Altera_status_fn status;
Altera_done_fn done;
Altera_write_fn write;
Altera_abort_fn abort;
Altera_post_fn post;
} Altera_CYC2_Passive_Serial_fns;
/* Device Image Sizes
*********************************************************************/
#define Altera_EP2C8_SIZE 247942
#define Altera_EP2C20_SIZE 586562
#define Altera_EP2C35_SIZE 883905
#define Altera_EP3C5_SIZE 368011 /* .rbf size in bytes */
#define ALTERA_EP4CE6_SIZE 368011 /* 2944088 Bits */
#define ALTERA_EP4CE10_SIZE 368011 /* 2944088 Bits */
#define ALTERA_EP4CE15_SIZE 510856 /* 4086848 Bits */
#define ALTERA_EP4CE22_SIZE 718569 /* 5748552 Bits */
#define ALTERA_EP4CE30_SIZE 1191788 /* 9534304 Bits */
#define ALTERA_EP4CE40_SIZE 1191788 /* 9534304 Bits */
#define ALTERA_EP4CE55_SIZE 1861195 /* 14889560 Bits */
#define ALTERA_EP4CE75_SIZE 2495719 /* 19965752 Bits */
#define ALTERA_EP4CE115_SIZE 3571462 /* 28571696 Bits */
#endif /* _ACEX1K_H_ */
+86
View File
@@ -0,0 +1,86 @@
/*
* You need to use #ifdef around functions that may not exist
* in the final configuration (such as i2c).
* As an example see the CONFIG_CMD_I2C section below
*/
#ifndef EXPORT_FUNC
#define EXPORT_FUNC(a, b, c, ...)
#endif
EXPORT_FUNC(get_version, unsigned long, get_version, void)
EXPORT_FUNC(getchar, int, getc, void)
EXPORT_FUNC(tstc, int, tstc, void)
EXPORT_FUNC(putc, void, putc, const char)
EXPORT_FUNC(puts, void, puts, const char *)
#ifdef CONFIG_CONSOLE_FLUSH_SUPPORT
EXPORT_FUNC(flush, void, flush, void)
#endif
EXPORT_FUNC(printf, int, printf, const char*, ...)
EXPORT_FUNC(vprintf, int, vprintf, const char *, va_list)
#if (defined(CONFIG_X86) && !defined(CONFIG_X86_64)) || defined(CONFIG_PPC)
EXPORT_FUNC(irq_install_handler, void, install_hdlr,
int, interrupt_handler_t, void*)
EXPORT_FUNC(irq_free_handler, void, free_hdlr, int)
#endif
EXPORT_FUNC(malloc, void *, malloc, size_t)
EXPORT_FUNC(realloc, void *, realloc, void *, size_t)
EXPORT_FUNC(calloc, void *, calloc, size_t, size_t)
#if !CONFIG_IS_ENABLED(SYS_MALLOC_SIMPLE)
EXPORT_FUNC(free, void, free, void *)
#endif
EXPORT_FUNC(mdelay, void, mdelay, unsigned long msec)
EXPORT_FUNC(udelay, void, udelay, unsigned long)
EXPORT_FUNC(get_timer, unsigned long, get_timer, unsigned long)
EXPORT_FUNC(do_reset, int, do_reset, struct cmd_tbl *,
int , int , char * const [])
EXPORT_FUNC(env_get, char *, env_get, const char*)
EXPORT_FUNC(env_set, int, env_set, const char *, const char *)
EXPORT_FUNC(simple_strtoul, unsigned long, simple_strtoul,
const char *, char **, unsigned int)
EXPORT_FUNC(strict_strtoul, int, strict_strtoul,
const char *, unsigned int , unsigned long *)
EXPORT_FUNC(simple_strtol, long, simple_strtol,
const char *, char **, unsigned int)
EXPORT_FUNC(ustrtoul, unsigned long, ustrtoul,
const char *, char **, unsigned int)
EXPORT_FUNC(ustrtoull, unsigned long long, ustrtoull,
const char *, char **, unsigned int)
EXPORT_FUNC(memcmp, int, memcmp, const void *, const void *, size_t)
EXPORT_FUNC(memcpy, void *, memcpy, void *, const void *, size_t)
EXPORT_FUNC(memmove, void *, memmove, void *, const void *, size_t)
EXPORT_FUNC(memset, void *, memset, void *, int, size_t)
EXPORT_FUNC(strchr, char *, strchr, const char *cs, int c)
EXPORT_FUNC(strlen, size_t, strlen, const char *s)
EXPORT_FUNC(strncmp, int, strncmp, const char *cs, const char *ct, size_t n)
EXPORT_FUNC(strncpy, char *, strncpy, char *dest, const char *src, size_t n)
EXPORT_FUNC(strnlen, size_t, strnlen, const char *s, size_t n)
EXPORT_FUNC(strcmp, int, strcmp, const char *cs, const char *ct)
EXPORT_FUNC(strcpy, char *, strcpy, char *dest, const char *src)
EXPORT_FUNC(sprintf, int, sprintf, char *, const char *, ...)
EXPORT_FUNC(snprintf, int, snprintf, char *, size_t, const char *, ...)
EXPORT_FUNC(vsprintf, int, vsprintf, char *, const char *, va_list)
EXPORT_FUNC(vsnprintf, int, vsnprintf, char *, size_t, const char *, va_list)
#if defined(CONFIG_CMD_I2C) && CONFIG_IS_ENABLED(SYS_I2C_LEGACY)
EXPORT_FUNC(i2c_write, int, i2c_write, uchar, uint, int , uchar * , int)
EXPORT_FUNC(i2c_read, int, i2c_read, uchar, uint, int , uchar * , int)
#endif
#if defined(CONFIG_CMD_SPI)
EXPORT_FUNC(spi_setup_slave, struct spi_slave *, spi_setup_slave,
unsigned int, unsigned int, unsigned int, unsigned int)
EXPORT_FUNC(spi_free_slave, void, spi_free_slave, struct spi_slave *)
EXPORT_FUNC(spi_claim_bus, int, spi_claim_bus, struct spi_slave *)
EXPORT_FUNC(spi_release_bus, void, spi_release_bus, struct spi_slave *)
EXPORT_FUNC(spi_xfer, int, spi_xfer, struct spi_slave *,
unsigned int, const void *, void *, unsigned long)
#endif
#ifdef CONFIG_PHY_AQUANTIA
EXPORT_FUNC(mdio_get_current_dev, struct mii_dev *,
mdio_get_current_dev, void)
EXPORT_FUNC(phy_find_by_mask, struct phy_device *, phy_find_by_mask,
struct mii_dev *bus, unsigned phy_mask)
EXPORT_FUNC(mdio_phydev_for_ethname, struct phy_device *,
mdio_phydev_for_ethname, const char *ethname)
EXPORT_FUNC(miiphy_set_current_dev, int, miiphy_set_current_dev,
const char *devname)
#endif
+236
View File
@@ -0,0 +1,236 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Handles a buffer that can be allocated and freed
*
* Copyright 2021 Google LLC
* Written by Simon Glass <sjg@chromium.org>
*/
#ifndef __ABUF_H
#define __ABUF_H
#ifdef USE_HOSTCC
#include <sys/types.h>
#else
#include <linux/types.h>
#endif
/**
* struct abuf - buffer that can be allocated and freed
*
* This is useful for a block of data which may be allocated with malloc(), or
* not, so that it needs to be freed correctly when finished with.
*
* For now it has a very simple purpose.
*
* Using memset() to zero all fields is guaranteed to be equivalent to
* abuf_init().
*
* @data: Pointer to data
* @size: Size of data in bytes
* @alloced: true if allocated with malloc(), so must be freed after use
*/
struct abuf {
void *data;
size_t size;
bool alloced;
};
static inline void *abuf_data(const struct abuf *abuf)
{
return abuf->data;
}
static inline size_t abuf_size(const struct abuf *abuf)
{
return abuf->size;
}
/**
* abuf_addr() - Get the address of a buffer's data
*
* @abuf: Buffer to check
* Return: address of buffer
*/
ulong abuf_addr(const struct abuf *abuf);
/**
* abuf_set() - set the (unallocated) data in a buffer
*
* This simply makes the abuf point to the supplied data, which must be live
* for the lifetime of the abuf. It is not alloced.
*
* Any existing data in the abuf is freed and the alloced member is set to
* false.
*
* @abuf: abuf to adjust
* @data: New contents of abuf
* @size: New size of abuf
*/
void abuf_set(struct abuf *abuf, void *data, size_t size);
/**
* abuf_map_sysmem() - calls map_sysmem() to set up an abuf
*
* This is equivalent to abuf_set(abuf, map_sysmem(addr, size), size)
*
* Any existing data in the abuf is freed and the alloced member is set to
* false.
*
* @abuf: abuf to adjust
* @addr: Address to set the abuf to
* @size: New size of abuf
*/
void abuf_map_sysmem(struct abuf *abuf, ulong addr, size_t size);
/**
* abuf_realloc() - Change the size of a buffer
*
* This uses realloc() to change the size of the buffer, with the same semantics
* as that function. If the abuf is not currently alloced, then it will alloc
* it if the size needs to increase (i.e. set the alloced member to true)
*
* @abuf: abuf to adjust
* @new_size: new size in bytes.
* if 0, the abuf is freed
* if greater than the current size, the abuf is extended and the new
* space is not inited. The alloced member is set to true
* if less than the current size, the abuf is contracted and the data at
* the end is lost. If @new_size is 0, this sets the alloced member to
* false
* Return: true if OK, false if out of memory
*/
bool abuf_realloc(struct abuf *abuf, size_t new_size);
/**
* abuf_realloc_inc() - Increment abuf size by a given amount
*
* @abuf: abuf to adjust
* @inc: Size incrmement to use (the buffer size will be increased by this much)
* Return: true if OK, false if out of memory
*/
bool abuf_realloc_inc(struct abuf *abuf, size_t inc);
/**
* abuf_copy() - Make a copy of an abuf
*
* Creates an allocated copy of @old in @new
*
* @old: abuf to copy
* @new: new abuf to hold the copy (inited by this function)
* Return: true if OK, false if out of memory
*/
bool abuf_copy(const struct abuf *old, struct abuf *new);
/**
* abuf_printf() - Format a string and place it in an abuf
*
* @buf: The buffer to place the result into
* @fmt: The format string to use
* @...: Arguments for the format string
* Return: the number of characters writtenwhich would be
* generated for the given input, excluding the trailing null,
* as per ISO C99.
*
* The abuf is expanded as necessary to fit the formated string
*
* See the vsprintf() documentation for format string extensions over C99.
*
* Returns: number of characters written (excluding trailing nul) on success,
* -E2BIG if the size exceeds 4K, -ENOMEM if out of memory, -EFAULT if there is
* an internal bug in the vsnprintf() implementation
*/
int abuf_printf(struct abuf *buf, const char *fmt, ...)
__attribute__ ((format (__printf__, 2, 3)));
/**
* abuf_uninit_move() - Return the allocated contents and uninit the abuf
*
* This returns the abuf data to the caller, allocating it if necessary, so that
* the caller receives data that it can be sure will hang around. The caller is
* responsible for freeing the data.
*
* If the abuf has allocated data, it is returned. If the abuf has data but it
* is not allocated, then it is first allocated, then returned.
*
* If the abuf size is 0, this returns NULL
*
* The abuf is uninited as part of this, except if the allocation fails, in
* which NULL is returned and the abuf remains untouched.
*
* The abuf must be inited before this can be called.
*
* @abuf: abuf to uninit
* @sizep: if non-NULL, returns the size of the returned data
* Return: data contents, allocated with malloc(), or NULL if the data could not
* be allocated, or the data size is 0
*/
void *abuf_uninit_move(struct abuf *abuf, size_t *sizep);
/**
* abuf_init_move() - Make abuf take over the management of an allocated region
*
* After this, @data must not be used. All access must be via the abuf.
*
* @abuf: abuf to init
* @data: Existing allocated buffer to place in the abuf
* @size: Size of allocated buffer
*/
void abuf_init_move(struct abuf *abuf, void *data, size_t size);
/**
* abuf_init_set() - Set up a new abuf
*
* Inits a new abuf and sets up its (unallocated) data
*
* @abuf: abuf to set up
* @data: New contents of abuf
* @size: New size of abuf
*/
void abuf_init_set(struct abuf *abuf, void *data, size_t size);
/**
* abuf_init_const() - Set up a new const abuf
*
* Inits a new abuf and sets up its (unallocated) data. The only current
* difference between this and abuf_init_set() is the 'data' parameter is a
* const pointer. At some point a flag could be used to indicate const-ness.
*
* @abuf: abuf to set up
* @data: New contents of abuf
* @size: New size of abuf
*/
void abuf_init_const(struct abuf *abuf, const void *data, size_t size);
/**
* abuf_init_size() - Set up an allocated abuf
*
* Init a new abuf and allocate its size.
*
* @abuf: abuf to set up
* @data: New contents of abuf
* @size: New size of abuf
*/
bool abuf_init_size(struct abuf *buf, size_t size);
/**
* abuf_uninit() - Free any memory used by an abuf
*
* The buffer must be inited before this can be called.
*
* @abuf: abuf to uninit
*/
void abuf_uninit(struct abuf *abuf);
/**
* abuf_init() - Set up a new abuf
*
* This initially has no data and alloced is set to false. This is equivalent to
* setting all fields to 0, e.g. with memset(), so callers can do that instead
* if desired.
*
* @abuf: abuf to set up
*/
void abuf_init(struct abuf *abuf);
#endif
+498
View File
@@ -0,0 +1,498 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Generation of tables for particular device types
*
* Copyright 2019 Google LLC
* Mostly taken from coreboot file of the same name
*/
#ifndef __ACPI_DEVICE_H
#define __ACPI_DEVICE_H
#include <i2c.h>
#include <irq.h>
#include <spi.h>
#include <asm-generic/gpio.h>
#include <linux/bitops.h>
struct acpi_ctx;
struct gpio_desc;
struct irq;
struct udevice;
/* ACPI descriptor values for common descriptors: SERIAL_BUS means I2C */
#define ACPI_DESCRIPTOR_LARGE BIT(7)
#define ACPI_DESCRIPTOR_REGISTER (ACPI_DESCRIPTOR_LARGE | 2)
#define ACPI_DESCRIPTOR_INTERRUPT (ACPI_DESCRIPTOR_LARGE | 9)
#define ACPI_DESCRIPTOR_GPIO (ACPI_DESCRIPTOR_LARGE | 12)
#define ACPI_DESCRIPTOR_SERIAL_BUS (ACPI_DESCRIPTOR_LARGE | 14)
/* Length of a full path to an ACPI device */
#define ACPI_PATH_MAX 30
/* UUID for an I2C _DSM method */
#define ACPI_DSM_I2C_HID_UUID "3cdff6f7-4267-4555-ad05-b30a3d8938de"
/* Values that can be returned for ACPI device _STA method */
enum acpi_dev_status {
ACPI_DSTATUS_PRESENT = BIT(0),
ACPI_DSTATUS_ENABLED = BIT(1),
ACPI_DSTATUS_SHOW_IN_UI = BIT(2),
ACPI_DSTATUS_OK = BIT(3),
ACPI_DSTATUS_HAS_BATTERY = BIT(4),
ACPI_DSTATUS_ALL_OFF = 0,
ACPI_DSTATUS_HIDDEN_ON = ACPI_DSTATUS_PRESENT | ACPI_DSTATUS_ENABLED |
ACPI_DSTATUS_OK,
ACPI_DSTATUS_ALL_ON = ACPI_DSTATUS_HIDDEN_ON |
ACPI_DSTATUS_SHOW_IN_UI,
};
/** enum acpi_irq_mode - edge/level trigger mode */
enum acpi_irq_mode {
ACPI_IRQ_EDGE_TRIGGERED,
ACPI_IRQ_LEVEL_TRIGGERED,
};
/**
* enum acpi_irq_polarity - polarity of interrupt
*
* @ACPI_IRQ_ACTIVE_LOW - for ACPI_IRQ_EDGE_TRIGGERED this means falling edge
* @ACPI_IRQ_ACTIVE_HIGH - for ACPI_IRQ_EDGE_TRIGGERED this means rising edge
* @ACPI_IRQ_ACTIVE_BOTH - not meaningful for ACPI_IRQ_EDGE_TRIGGERED
*/
enum acpi_irq_polarity {
ACPI_IRQ_ACTIVE_LOW,
ACPI_IRQ_ACTIVE_HIGH,
ACPI_IRQ_ACTIVE_BOTH,
};
/**
* enum acpi_irq_shared - whether interrupt is shared or not
*
* @ACPI_IRQ_EXCLUSIVE: only this device uses the interrupt
* @ACPI_IRQ_SHARED: other devices may use this interrupt
*/
enum acpi_irq_shared {
ACPI_IRQ_EXCLUSIVE,
ACPI_IRQ_SHARED,
};
/** enum acpi_irq_wake - indicates whether this interrupt can wake the device */
enum acpi_irq_wake {
ACPI_IRQ_NO_WAKE,
ACPI_IRQ_WAKE,
};
/**
* struct acpi_irq - representation of an ACPI interrupt
*
* @pin: ACPI pin that is monitored for the interrupt
* @mode: Edge/level triggering
* @polarity: Interrupt polarity
* @shared: Whether interrupt is shared or not
* @wake: Whether interrupt can wake the device from sleep
*/
struct acpi_irq {
unsigned int pin;
enum acpi_irq_mode mode;
enum acpi_irq_polarity polarity;
enum acpi_irq_shared shared;
enum acpi_irq_wake wake;
};
/**
* enum acpi_gpio_type - type of the descriptor
*
* @ACPI_GPIO_TYPE_INTERRUPT: GpioInterrupt
* @ACPI_GPIO_TYPE_IO: GpioIo
*/
enum acpi_gpio_type {
ACPI_GPIO_TYPE_INTERRUPT,
ACPI_GPIO_TYPE_IO,
};
/**
* enum acpi_gpio_pull - pull direction
*
* @ACPI_GPIO_PULL_DEFAULT: Use default value for pin
* @ACPI_GPIO_PULL_UP: Pull up
* @ACPI_GPIO_PULL_DOWN: Pull down
* @ACPI_GPIO_PULL_NONE: No pullup/pulldown
*/
enum acpi_gpio_pull {
ACPI_GPIO_PULL_DEFAULT,
ACPI_GPIO_PULL_UP,
ACPI_GPIO_PULL_DOWN,
ACPI_GPIO_PULL_NONE,
};
/**
* enum acpi_gpio_io_restrict - controls input/output of pin
*
* @ACPI_GPIO_IO_RESTRICT_NONE: no restrictions
* @ACPI_GPIO_IO_RESTRICT_INPUT: input only (no output)
* @ACPI_GPIO_IO_RESTRICT_OUTPUT: output only (no input)
* @ACPI_GPIO_IO_RESTRICT_PRESERVE: preserve settings when driver not active
*/
enum acpi_gpio_io_restrict {
ACPI_GPIO_IO_RESTRICT_NONE,
ACPI_GPIO_IO_RESTRICT_INPUT,
ACPI_GPIO_IO_RESTRICT_OUTPUT,
ACPI_GPIO_IO_RESTRICT_PRESERVE,
};
/** enum acpi_gpio_polarity - controls the GPIO polarity */
enum acpi_gpio_polarity {
ACPI_GPIO_ACTIVE_HIGH = 0,
ACPI_GPIO_ACTIVE_LOW = 1,
};
#define ACPI_GPIO_REVISION_ID 1
#define ACPI_GPIO_MAX_PINS 2
/**
* struct acpi_gpio - representation of an ACPI GPIO
*
* @pin_count: Number of pins represented
* @pins: List of pins
* @pin0_addr: Address in memory of the control registers for pin 0. This is
* used when generating ACPI tables
* @type: GPIO type
* @pull: Pullup/pulldown setting
* @resource: Resource name for this GPIO controller
* For GpioInt:
* @interrupt_debounce_timeout: Debounce timeout in units of 10us
* @irq: Interrupt
*
* For GpioIo:
* @output_drive_strength: Drive strength in units of 10uA
* @io_shared; true if GPIO is shared
* @io_restrict: I/O restriction setting
* @polarity: GPIO polarity
*
* Note that GpioIo() doesn't have any means of Active Low / High setting, so a
* _DSD must be provided to mitigate this. This parameter does not make sense
* for GpioInt() since it has its own means to define it.
*
* GpioIo() doesn't properly communicate the initial state of the output pin,
* thus Linux assumes the simple rule:
*
* Pull Bias Polarity Requested...
*
* Implicit x AS IS (assumed firmware configured for us)
* Explicit x (no _DSD) as Pull Bias (Up == High, Down == Low),
* assuming non-active (Polarity = !Pull Bias)
*
* Down Low as low, assuming active
* Down High as low, assuming non-active
* Up Low as high, assuming non-active
* Up High as high, assuming active
*
* GpioIo() can be used as interrupt and in this case the IoRestriction mustn't
* be OutputOnly. It also requires active_low flag from _DSD in cases where it's
* needed (better to always provide than rely on above assumption made on OS
* level).
*/
struct acpi_gpio {
int pin_count;
u16 pins[ACPI_GPIO_MAX_PINS];
ulong pin0_addr;
enum acpi_gpio_type type;
enum acpi_gpio_pull pull;
char resource[ACPI_PATH_MAX];
/* GpioInt */
u16 interrupt_debounce_timeout;
struct acpi_irq irq;
/* GpioIo */
u16 output_drive_strength;
bool io_shared;
enum acpi_gpio_io_restrict io_restrict;
enum acpi_gpio_polarity polarity;
};
/* ACPI Descriptors for Serial Bus interfaces */
#define ACPI_SERIAL_BUS_TYPE_I2C 1
#define ACPI_SERIAL_BUS_TYPE_SPI 2
#define ACPI_I2C_SERIAL_BUS_REVISION_ID 1 /* TODO: upgrade to 2 */
#define ACPI_I2C_TYPE_SPECIFIC_REVISION_ID 1
#define ACPI_SPI_SERIAL_BUS_REVISION_ID 1
#define ACPI_SPI_TYPE_SPECIFIC_REVISION_ID 1
/**
* struct acpi_i2c - representation of an ACPI I2C device
*
* @address: 7-bit or 10-bit I2C address
* @mode_10bit: Which address size is used
* @speed: Bus speed in Hz
* @resource: Resource name for the I2C controller
*/
struct acpi_i2c {
u16 address;
enum i2c_address_mode mode_10bit;
enum i2c_speed_rate speed;
const char *resource;
};
/**
* struct acpi_spi - representation of an ACPI SPI device
*
* @device_select: Chip select used by this device (typically 0)
* @device_select_polarity: Polarity for the device
* @wire_mode: Number of wires used for SPI
* @speed: Bus speed in Hz
* @data_bit_length: Word length for SPI (typically 8)
* @clock_phase: Clock phase to capture data
* @clock_polarity: Bus polarity
* @resource: Resource name for the SPI controller
*/
struct acpi_spi {
u16 device_select;
enum spi_polarity device_select_polarity;
enum spi_wire_mode wire_mode;
unsigned int speed;
u8 data_bit_length;
enum spi_clock_phase clock_phase;
enum spi_polarity clock_polarity;
const char *resource;
};
/**
* struct acpi_i2c_priv - Information read from device tree
*
* This is used by devices which want to specify various pieces of ACPI
* information, including power control. It allows a generic function to
* generate the information for ACPI, based on device-tree properties.
*
* @disable_gpio_export_in_crs: Don't export GPIOs in the CRS
* @reset_gpio: GPIO used to assert reset to the device
* @enable_gpio: GPIO used to enable the device
* @stop_gpio: GPIO used to stop the device
* @irq_gpio: GPIO used for interrupt (if @irq is not used)
* @irq: IRQ used for interrupt (if @irq_gpio is not used)
* @hid: _HID value for device (required)
* @uid: _UID value for device
* @desc: _DDN value for device
* @wake: Wake event, e.g. GPE0_DW1_15; 0 if none
* @property_count: Number of other DSD properties (currently always 0)
* @probed: true set set 'linux,probed' property
* @compat_string: Device tree compatible string to report through ACPI
* @has_power_resource: true if this device has a power resource
* @reset_delay_ms: Delay after de-asserting reset, in ms
* @reset_off_delay_ms: Delay after asserting reset (during power off)
* @enable_delay_ms: Delay after asserting enable
* @enable_off_delay_ms: Delay after de-asserting enable (during power off)
* @stop_delay_ms: Delay after de-aserting stop
* @stop_off_delay_ms: Delay after asserting stop (during power off)
* @hid_desc_reg_offset: HID register offset (for Human Interface Devices)
*/
struct acpi_i2c_priv {
bool disable_gpio_export_in_crs;
struct gpio_desc reset_gpio;
struct gpio_desc enable_gpio;
struct gpio_desc irq_gpio;
struct gpio_desc stop_gpio;
struct irq irq;
const char *hid;
u32 uid;
const char *desc;
u32 wake;
u32 property_count;
bool probed;
const char *compat_string;
bool has_power_resource;
u32 reset_delay_ms;
u32 reset_off_delay_ms;
u32 enable_delay_ms;
u32 enable_off_delay_ms;
u32 stop_delay_ms;
u32 stop_off_delay_ms;
u32 hid_desc_reg_offset;
};
/**
* acpi_device_path() - Get the full path to an ACPI device
*
* This gets the full path in the form XXXX.YYYY.ZZZZ where XXXX is the root
* and ZZZZ is the device. All parent devices are added to the path.
*
* @dev: Device to check
* @buf: Buffer to place the path in (should be ACPI_PATH_MAX long)
* @maxlen: Size of buffer (typically ACPI_PATH_MAX)
* Return: 0 if OK, -ve on error
*/
int acpi_device_path(const struct udevice *dev, char *buf, int maxlen);
/**
* acpi_device_scope() - Get the scope of an ACPI device
*
* This gets the scope which is the full path of the parent device, as per
* acpi_device_path().
*
* @dev: Device to check
* @buf: Buffer to place the path in (should be ACPI_PATH_MAX long)
* @maxlen: Size of buffer (typically ACPI_PATH_MAX)
* Return: 0 if OK, -EINVAL if the device has no parent, other -ve on other
* error
*/
int acpi_device_scope(const struct udevice *dev, char *scope, int maxlen);
/**
* acpi_device_status() - Get the status of a device
*
* This currently just returns ACPI_DSTATUS_ALL_ON. It does not support
* inactive or hidden devices.
*
* @dev: Device to check
* Return: device status, as ACPI_DSTATUS_...
*/
enum acpi_dev_status acpi_device_status(const struct udevice *dev);
/**
* acpi_device_write_interrupt_irq() - Write an interrupt descriptor
*
* This writes an ACPI interrupt descriptor for the given interrupt, converting
* fields as needed.
*
* @ctx: ACPI context pointer
* @req_irq: Interrupt to output
* Return: IRQ pin number if OK, -ve on error
*/
int acpi_device_write_interrupt_irq(struct acpi_ctx *ctx,
const struct irq *req_irq);
/**
* acpi_device_write_gpio() - Write GpioIo() or GpioInt() descriptor
*
* @gpio: GPIO information to write
* Return: GPIO pin number of first GPIO if OK, -ve on error
*/
int acpi_device_write_gpio(struct acpi_ctx *ctx, const struct acpi_gpio *gpio);
/**
* acpi_device_write_gpio_desc() - Write a GPIO to ACPI
*
* This creates a GPIO descriptor for a GPIO, including information ACPI needs
* to use it.
*
* @ctx: ACPI context pointer
* @desc: GPIO to write
* Return: 0 if OK, -ve on error
*/
int acpi_device_write_gpio_desc(struct acpi_ctx *ctx,
const struct gpio_desc *desc);
/**
* acpi_device_write_interrupt_or_gpio() - Write interrupt or GPIO to ACPI
*
* This reads an interrupt from the device tree "interrupts-extended" property,
* if available. If not it reads the first GPIO with the name @prop.
*
* If an interrupt is found, an ACPI interrupt descriptor is written to the ACPI
* output. If not, but if a GPIO is found, a GPIO descriptor is written.
*
* Return: irq or GPIO pin number if OK, -ve if neither an interrupt nor a GPIO
* could be found, or some other error occurred
*/
int acpi_device_write_interrupt_or_gpio(struct acpi_ctx *ctx,
struct udevice *dev, const char *prop);
/**
* acpi_device_write_dsm_i2c_hid() - Write a device-specific method for HID
*
* This writes a DSM for an I2C Human-Interface Device based on the config
* provided
*
* @hid_desc_reg_offset: HID register offset
*/
int acpi_device_write_dsm_i2c_hid(struct acpi_ctx *ctx,
int hid_desc_reg_offset);
/**
* acpi_device_write_i2c_dev() - Write an I2C device to ACPI
*
* This creates a I2cSerialBusV2 descriptor for an I2C device, including
* information ACPI needs to use it.
*
* @ctx: ACPI context pointer
* @dev: I2C device to write
* Return: I2C address of device if OK, -ve on error
*/
int acpi_device_write_i2c_dev(struct acpi_ctx *ctx, const struct udevice *dev);
/**
* acpi_device_write_spi_dev() - Write a SPI device to ACPI
*
* This writes a serial bus descriptor for the SPI device so that ACPI can use
* it
*
* @ctx: ACPI context pointer
* @dev: SPI device to write
* Return: 0 if OK, -ve on error
*/
int acpi_device_write_spi_dev(struct acpi_ctx *ctx, const struct udevice *dev);
/**
* acpi_device_add_power_res() - Add a basic PowerResource block for a device
*
* This includes GPIOs to control enable, reset and stop operation of the
* device. Each GPIO is optional, but at least one must be provided.
* This can be applied to any device that has power control, so is fairly
* generic.
*
* Reset - Put the device into / take the device out of reset.
* Enable - Enable / disable power to device.
* Stop - Stop / start operation of device.
*
* @ctx: ACPI context pointer
* @tx_state_val: Mask to use to toggle the TX state on the GPIO pin, e,g.
* PAD_CFG0_TX_STATE
* @dw0_read: Name to use to read dw0, e.g. "\\_SB.GPC0"
* @dw0_write: Name to use to read dw0, e.g. "\\_SB.SPC0"
* @reset_gpio: GPIO used to take device out of reset or to put it into reset
* @reset_delay_ms: Delay to be inserted after device is taken out of reset
* (_ON method delay)
* @reset_off_delay_ms: Delay to be inserted after device is put into reset
* (_OFF method delay)
* @enable_gpio: GPIO used to enable device
* @enable_delay_ms: Delay to be inserted after device is enabled
* @enable_off_delay_ms: Delay to be inserted after device is disabled
* (_OFF method delay)
* @stop_gpio: GPIO used to stop operation of device
* @stop_delay_ms: Delay to be inserted after disabling stop (_ON method delay)
* @stop_off_delay_ms: Delay to be inserted after enabling stop.
* (_OFF method delay)
*
* Return: 0 if OK, -ve if at least one GPIO is not provided
*/
int acpi_device_add_power_res(struct acpi_ctx *ctx, u32 tx_state_val,
const char *dw0_read, const char *dw0_write,
const struct gpio_desc *reset_gpio,
uint reset_delay_ms, uint reset_off_delay_ms,
const struct gpio_desc *enable_gpio,
uint enable_delay_ms, uint enable_off_delay_ms,
const struct gpio_desc *stop_gpio,
uint stop_delay_ms, uint stop_off_delay_ms);
/**
* acpi_device_infer_name() - Infer the name from its uclass or parent
*
* Many ACPI devices have a standard name that can be inferred from the uclass
* they are in, or the uclass of their parent. These rules are implemented in
* this function. It attempts to produce a name for a device based on these
* rules.
*
* NOTE: This currently supports only x86 devices. Feel free to enhance it for
* other architectures as needed.
*
* @dev: Device to check
* @out_name: Place to put the name (must hold ACPI_NAME_MAX bytes)
* Return: 0 if a name was found, -ENOENT if not found, -ENXIO if the device
* sequence number could not be determined
*/
int acpi_device_infer_name(const struct udevice *dev, char *out_name);
#endif
+287
View File
@@ -0,0 +1,287 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Device properties, a temporary data structure for adding to ACPI code
*
* Copyright 2019 Google LLC
* Mostly taken from coreboot file acpi_device.h
*/
#ifndef __ACPI_DP_H
#define __ACPI_DP_H
struct acpi_ctx;
#include <acpi/acpi_device.h>
/*
* Writing Device Properties objects via _DSD
*
* This is described in ACPI 6.3 section 6.2.5
*
* This provides a structure to handle nested device-specific data which ends
* up in a _DSD table.
*
* https://www.kernel.org/doc/html/latest/firmware-guide/acpi/DSD-properties-rules.html
* https://uefi.org/sites/default/files/resources/_DSD-device-properties-UUID.pdf
* https://uefi.org/sites/default/files/resources/_DSD-hierarchical-data-extension-UUID-v1.1.pdf
*
* The Device Property Hierarchy can be multiple levels deep with multiple
* children possible in each level. In order to support this flexibility
* the device property hierarchy must be built up before being written out.
*
* For example:
*
* Child table with string and integer:
* struct acpi_dp *child = acpi_dp_new_table("CHLD");
* acpi_dp_add_string(child, "childstring", "CHILD");
* acpi_dp_add_integer(child, "childint", 100);
*
* _DSD table with integer and gpio and child pointer:
* struct acpi_dp *dsd = acpi_dp_new_table("_DSD");
* acpi_dp_add_integer(dsd, "number1", 1);
* acpi_dp_add_gpio(dsd, "gpio", "\_SB.PCI0.GPIO", 0, 0, 1);
* acpi_dp_add_child(dsd, "child", child);
*
* Write entries into SSDT and clean up resources:
* acpi_dp_write(dsd);
*
* Name(_DSD, Package() {
* ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301")
* Package() {
* Package() { "gpio", Package() { \_SB.PCI0.GPIO, 0, 0, 0 } }
* Package() { "number1", 1 }
* }
* ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b")
* Package() {
* Package() { "child", CHLD }
* }
* }
* Name(CHLD, Package() {
* ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301")
* Package() {
* Package() { "childstring", "CHILD" }
* Package() { "childint", 100 }
* }
* }
*/
#define ACPI_DP_UUID "daffd814-6eba-4d8c-8a91-bc9bbf4aa301"
#define ACPI_DP_CHILD_UUID "dbb8e3e6-5886-4ba6-8795-1319f52a966b"
/**
* enum acpi_dp_type - types of device property objects
*
* These refer to the types defined by struct acpi_dp below
*
* @ACPI_DP_TYPE_UNKNOWN: Unknown / do not use
* @ACPI_DP_TYPE_INTEGER: Integer value (u64) in @integer
* @ACPI_DP_TYPE_STRING: String value in @string
* @ACPI_DP_TYPE_REFERENCE: Reference to another object, with value in @string
* @ACPI_DP_TYPE_TABLE: Type for a top-level table which may have children
* @ACPI_DP_TYPE_ARRAY: Array of items with first item in @array and following
* items linked from that item's @next
* @ACPI_DP_TYPE_CHILD: Child object, with siblings in that child's @next
*/
enum acpi_dp_type {
ACPI_DP_TYPE_UNKNOWN,
ACPI_DP_TYPE_INTEGER,
ACPI_DP_TYPE_STRING,
ACPI_DP_TYPE_REFERENCE,
ACPI_DP_TYPE_TABLE,
ACPI_DP_TYPE_ARRAY,
ACPI_DP_TYPE_CHILD,
};
/**
* struct acpi_dp - ACPI device properties
*
* @type: Table type
* @name: Name of object, typically _DSD but could be CHLD for a child object.
* This can be NULL if there is no name
* @next: Next object in list (next array element or next sibling)
* @child: Pointer to first child, if @type == ACPI_DP_TYPE_CHILD, else NULL
* @array: First array element, if @type == ACPI_DP_TYPE_ARRAY, else NULL
* @integer: Integer value of the property, if @type == ACPI_DP_TYPE_INTEGER
* @string: String value of the property, if @type == ACPI_DP_TYPE_STRING;
* child name if @type == ACPI_DP_TYPE_CHILD;
* reference name if @type == ACPI_DP_TYPE_REFERENCE;
*/
struct acpi_dp {
enum acpi_dp_type type;
const char *name;
struct acpi_dp *next;
union {
struct acpi_dp *child;
struct acpi_dp *array;
};
union {
u64 integer;
const char *string;
};
};
/**
* acpi_dp_new_table() - Start a new Device Property table
*
* @ref: ACPI reference (e.g. "_DSD")
* Return: pointer to table, or NULL if out of memory
*/
struct acpi_dp *acpi_dp_new_table(const char *ref);
/**
* acpi_dp_add_integer() - Add integer Device Property
*
* A new node is added to the end of the property list of @dp
*
* @dp: Table to add this property to
* @name: Name of property, or NULL for none
* @value: Integer value
* Return: pointer to new node, or NULL if out of memory
*/
struct acpi_dp *acpi_dp_add_integer(struct acpi_dp *dp, const char *name,
u64 value);
/**
* acpi_dp_add_string() - Add string Device Property
*
* A new node is added to the end of the property list of @dp
*
* @dp: Table to add this property to
* @name: Name of property, or NULL for none
* @string: String value
* Return: pointer to new node, or NULL if out of memory
*/
struct acpi_dp *acpi_dp_add_string(struct acpi_dp *dp, const char *name,
const char *string);
/**
* acpi_dp_add_reference() - Add reference Device Property
*
* A new node is added to the end of the property list of @dp
*
* @dp: Table to add this property to
* @name: Name of property, or NULL for none
* @reference: Reference value
* Return: pointer to new node, or NULL if out of memory
*/
struct acpi_dp *acpi_dp_add_reference(struct acpi_dp *dp, const char *name,
const char *reference);
/**
* acpi_dp_add_array() - Add array Device Property
*
* A new node is added to the end of the property list of @dp, with the array
* attached to that.
*
* @dp: Table to add this property to
* @name: Name of property, or NULL for none
* Return: pointer to new node, or NULL if out of memory
*/
struct acpi_dp *acpi_dp_add_array(struct acpi_dp *dp, struct acpi_dp *array);
/**
* acpi_dp_add_integer_array() - Add an array of integers
*
* A new node is added to the end of the property list of @dp, with the array
* attached to that. Each element of the array becomes a new node.
*
* @dp: Table to add this property to
* @name: Name of property, or NULL for none
* Return: pointer to new array node, or NULL if out of memory
*/
struct acpi_dp *acpi_dp_add_integer_array(struct acpi_dp *dp, const char *name,
u64 *array, int len);
/**
* acpi_dp_add_child() - Add a child table of Device Properties
*
* A new node is added as a child of @dp
*
* @dp: Table to add this child to
* @name: Name of child, or NULL for none
* @child: Child node to add
* Return: pointer to new child node, or NULL if out of memory
*/
struct acpi_dp *acpi_dp_add_child(struct acpi_dp *dp, const char *name,
struct acpi_dp *child);
/**
* acpi_dp_add_gpio() - Add a GPIO to a list of Device Properties
*
* A new node is added to the end of the property list of @dp, with the
* GPIO properties added to the the new node
*
* @dp: Table to add this property to
* @name: Name of property
* @ref: Reference to device with a _CRS containing GpioIO or GpioInt
* @index: Index of the GPIO resource in _CRS starting from zero
* @pin: Pin in the GPIO resource, typically zero
* @polarity: GPIO polarity. Note that ACPI_IRQ_ACTIVE_BOTH is not supported
* Return: pointer to new node, or NULL if out of memory
*/
struct acpi_dp *acpi_dp_add_gpio(struct acpi_dp *dp, const char *name,
const char *ref, int index, int pin,
enum acpi_gpio_polarity polarity);
/**
* acpi_dp_write() - Write Device Property hierarchy and clean up resources
*
* This writes the table using acpigen and then frees it
*
* @ctx: ACPI context
* @table: Table to write
* Return: 0 if OK, -ve on error
*/
int acpi_dp_write(struct acpi_ctx *ctx, struct acpi_dp *table);
/**
* acpi_dp_ofnode_copy_int() - Copy a property from device tree to DP
*
* This copies an integer property from the device tree to the ACPI DP table.
*
* @node: Node to copy from
* @dp: DP to copy to
* @prop: Property name to copy
* Return: 0 if OK, -ve on error
*/
int acpi_dp_ofnode_copy_int(ofnode node, struct acpi_dp *dp, const char *prop);
/**
* acpi_dp_ofnode_copy_str() - Copy a property from device tree to DP
*
* This copies a string property from the device tree to the ACPI DP table.
*
* @node: Node to copy from
* @dp: DP to copy to
* @prop: Property name to copy
* Return: 0 if OK, -ve on error
*/
int acpi_dp_ofnode_copy_str(ofnode node, struct acpi_dp *dp, const char *prop);
/**
* acpi_dp_dev_copy_int() - Copy a property from device tree to DP
*
* This copies an integer property from the device tree to the ACPI DP table.
*
* @dev: Device to copy from
* @dp: DP to copy to
* @prop: Property name to copy
* Return: 0 if OK, -ve on error
*/
int acpi_dp_dev_copy_int(const struct udevice *dev, struct acpi_dp *dp,
const char *prop);
/**
* acpi_dp_dev_copy_str() - Copy a property from device tree to DP
*
* This copies a string property from the device tree to the ACPI DP table.
*
* @dev: Device to copy from
* @dp: DP to copy to
* @prop: Property name to copy
* Return: 0 if OK, -ve on error
*/
int acpi_dp_dev_copy_str(const struct udevice *dev, struct acpi_dp *dp,
const char *prop);
#endif
+137
View File
@@ -0,0 +1,137 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2017, Bin Meng <bmeng.cn@gmail.com>
*/
#ifndef __ASM_ACPI_S3_H__
#define __ASM_ACPI_S3_H__
#define WAKEUP_BASE 0x600
/* PM1_STATUS register */
#define WAK_STS (1 << 15)
#define PCIEXPWAK_STS (1 << 14)
#define RTC_STS (1 << 10)
#define SLPBTN_STS (1 << 9)
#define PWRBTN_STS (1 << 8)
#define GBL_STS (1 << 5)
#define BM_STS (1 << 4)
#define TMR_STS (1 << 0)
/* PM1_CNT register */
#define SLP_EN (1 << 13)
#define SLP_TYP_SHIFT 10
#define SLP_TYP (7 << SLP_TYP_SHIFT)
#define SLP_TYP_S0 0
#define SLP_TYP_S1 1
#define SLP_TYP_S3 5
#define SLP_TYP_S4 6
#define SLP_TYP_S5 7
/* PM1_STS register */
#define RTC_EN BIT(10)
#define PWRBTN_EN BIT(8)
/* Memory size reserved for S3 resume */
#define S3_RESERVE_SIZE 0x1000
#ifndef __ASSEMBLY__
#include <linux/errno.h>
#include <linux/types.h>
extern char __wakeup[];
extern int __wakeup_size;
enum acpi_sleep_state {
ACPI_S0,
ACPI_S1,
ACPI_S2,
ACPI_S3,
ACPI_S4,
ACPI_S5,
};
/**
* acpi_ss_string() - get ACPI-defined sleep state string
*
* @pm1_cnt: ACPI-defined sleep state
* @return: a pointer to the sleep state string.
*/
static inline char *acpi_ss_string(enum acpi_sleep_state state)
{
char *ss_string[] = { "S0", "S1", "S2", "S3", "S4", "S5"};
return ss_string[state];
}
/**
* acpi_sleep_from_pm1() - get ACPI-defined sleep state from PM1_CNT register
*
* @pm1_cnt: PM1_CNT register value
* @return: ACPI-defined sleep state if given valid PM1_CNT register value,
* -EINVAL otherwise.
*/
static inline enum acpi_sleep_state acpi_sleep_from_pm1(u32 pm1_cnt)
{
switch ((pm1_cnt & SLP_TYP) >> SLP_TYP_SHIFT) {
case SLP_TYP_S0:
return ACPI_S0;
case SLP_TYP_S1:
return ACPI_S1;
case SLP_TYP_S3:
return ACPI_S3;
case SLP_TYP_S4:
return ACPI_S4;
case SLP_TYP_S5:
return ACPI_S5;
}
return -EINVAL;
}
/**
* chipset_prev_sleep_state() - Get chipset previous sleep state
*
* This returns chipset previous sleep state from ACPI registers.
* Platform codes must supply this routine in order to support ACPI S3.
*
* Return: ACPI_S0/S1/S2/S3/S4/S5.
*/
enum acpi_sleep_state chipset_prev_sleep_state(void);
/**
* chipset_clear_sleep_state() - Clear chipset sleep state
*
* This clears chipset sleep state in ACPI registers.
* Platform codes must supply this routine in order to support ACPI S3.
*/
void chipset_clear_sleep_state(void);
struct acpi_fadt;
/**
* acpi_resume() - Do ACPI S3 resume
*
* This calls U-Boot wake up assembly stub and jumps to OS's wake up vector.
*
* @fadt: FADT table pointer in the ACPI table
* @return: Never returns
*/
void acpi_resume(struct acpi_fadt *fadt);
/**
* acpi_s3_reserve() - Reserve memory for ACPI S3 resume
*
* This copies memory where real mode interrupt handler stubs reside to the
* reserved place on the stack.
*
* This routine should be called by reserve_arch() before U-Boot is relocated
* when ACPI S3 resume is enabled.
*
* @return: 0 always
*/
int acpi_s3_reserve(void);
#endif /* __ASSEMBLY__ */
#endif /* __ASM_ACPI_S3_H__ */
File diff suppressed because it is too large Load Diff
+993
View File
@@ -0,0 +1,993 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Core ACPI (Advanced Configuration and Power Interface) support
*
* Copyright 2019 Google LLC
*
* Modified from coreboot file acpigen.h
*/
#ifndef __ACPI_ACPIGEN_H
#define __ACPI_ACPIGEN_H
#include <acpi/acpi_table.h>
#include <linux/types.h>
struct acpi_cstate;
struct acpi_ctx;
struct acpi_gen_regaddr;
struct acpi_gpio;
/* Top 4 bits of the value used to indicate a three-byte length value */
#define ACPI_PKG_LEN_3_BYTES 0x80
#define ACPI_METHOD_NARGS_MASK 0x7
#define ACPI_METHOD_SERIALIZED_MASK BIT(3)
#define ACPI_END_TAG 0x79
/* ACPI Op/Prefix codes */
enum {
ZERO_OP = 0x00,
ONE_OP = 0x01,
NAME_OP = 0x08,
BYTE_PREFIX = 0x0a,
WORD_PREFIX = 0x0b,
DWORD_PREFIX = 0x0c,
STRING_PREFIX = 0x0d,
QWORD_PREFIX = 0x0e,
SCOPE_OP = 0x10,
BUFFER_OP = 0x11,
PACKAGE_OP = 0x12,
METHOD_OP = 0x14,
SLEEP_OP = 0x22,
DUAL_NAME_PREFIX = 0x2e,
MULTI_NAME_PREFIX = 0x2f,
DEBUG_OP = 0x31,
EXT_OP_PREFIX = 0x5b,
ROOT_PREFIX = 0x5c,
LOCAL0_OP = 0x60,
LOCAL1_OP = 0x61,
LOCAL2_OP = 0x62,
LOCAL3_OP = 0x63,
LOCAL4_OP = 0x64,
LOCAL5_OP = 0x65,
LOCAL6_OP = 0x66,
LOCAL7_OP = 0x67,
ARG0_OP = 0x68,
ARG1_OP = 0x69,
ARG2_OP = 0x6a,
ARG3_OP = 0x6b,
ARG4_OP = 0x6c,
ARG5_OP = 0x6d,
ARG6_OP = 0x6e,
STORE_OP = 0x70,
AND_OP = 0x7b,
OR_OP = 0x7d,
NOT_OP = 0x80,
DEVICE_OP = 0x82,
PROCESSOR_OP = 0x83,
POWER_RES_OP = 0x84,
NOTIFY_OP = 0x86,
LEQUAL_OP = 0x93,
TO_BUFFER_OP = 0x96,
TO_INTEGER_OP = 0x99,
IF_OP = 0xa0,
ELSE_OP = 0xa1,
RETURN_OP = 0xa4,
};
/**
* enum psd_coord - Coordination types for P-states
*
* The type of coordination that exists (hardware) or is required (software) as
* a result of the underlying hardware dependency
*/
enum psd_coord {
SW_ALL = 0xfc,
SW_ANY = 0xfd,
HW_ALL = 0xfe
};
/**
* enum csd_coord - Coordination types for C-states
*
* The type of coordination that exists (hardware) or is required (software) as
* a result of the underlying hardware dependency
*/
enum csd_coord {
CSD_HW_ALL = 0xfe,
};
/**
* struct acpi_cstate - Information about a C-State
*
* @ctype: C State type (1=C1, 2=C2, 3=C3)
* @latency: Worst-case latency to enter and exit the C State (in uS)
* @power: Average power consumption of the processor when in this C-State (mW)
* @resource: Register to read to place the processor in this state
*/
struct acpi_cstate {
uint ctype;
uint latency;
uint power;
struct acpi_gen_regaddr resource;
};
/**
* struct acpi_tstate - Information about a Throttling Supported State
*
* See ACPI v6.3 section 8.4.5.2: _TSS (Throttling Supported States)
*
* @percent: Percent of the core CPU operating frequency that will be
* available when this throttling state is invoked
* @power: Throttling state's maximum power dissipation (mw)
* @latency: Worst-case latency (uS) that the CPU is unavailable during a
* transition from any throttling state to this throttling state
* @control: Value to be written to the Processor Control Register
* (THROTTLE_CTRL) to initiate a transition to this throttling state
* @status: Value in THROTTLE_STATUS when in this state
*/
struct acpi_tstate {
uint percent;
uint power;
uint latency;
uint control;
uint status;
};
/**
* acpigen_get_current() - Get the current ACPI code output pointer
*
* @ctx: ACPI context pointer
* Return: output pointer
*/
u8 *acpigen_get_current(struct acpi_ctx *ctx);
/**
* acpigen_emit_byte() - Emit a byte to the ACPI code
*
* @ctx: ACPI context pointer
* @data: Value to output
*/
void acpigen_emit_byte(struct acpi_ctx *ctx, uint data);
/**
* acpigen_emit_word() - Emit a 16-bit word to the ACPI code
*
* @ctx: ACPI context pointer
* @data: Value to output
*/
void acpigen_emit_word(struct acpi_ctx *ctx, uint data);
/**
* acpigen_emit_dword() - Emit a 32-bit 'double word' to the ACPI code
*
* @ctx: ACPI context pointer
* @data: Value to output
*/
void acpigen_emit_dword(struct acpi_ctx *ctx, uint data);
/**
* acpigen_emit_stream() - Emit a stream of bytes
*
* @ctx: ACPI context pointer
* @data: Data to output
* @size: Size of data in bytes
*/
void acpigen_emit_stream(struct acpi_ctx *ctx, const char *data, int size);
/**
* acpigen_emit_string() - Emit a string
*
* Emit a string with a null terminator
*
* @ctx: ACPI context pointer
* @str: String to output, or NULL for an empty string
*/
void acpigen_emit_string(struct acpi_ctx *ctx, const char *str);
/**
* acpigen_write_len_f() - Write a 'forward' length placeholder
*
* This adds space for a length value in the ACPI stream and pushes the current
* position (before the length) on the stack. After calling this you can write
* some data and then call acpigen_pop_len() to update the length value.
*
* Usage:
*
* acpigen_write_len_f() ------\
* acpigen_write...() |
* acpigen_write...() |
* acpigen_write_len_f() --\ |
* acpigen_write...() | |
* acpigen_write...() | |
* acpigen_pop_len() ------/ |
* acpigen_write...() |
* acpigen_pop_len() ----------/
*
* See ACPI 6.3 section 20.2.4 Package Length Encoding
*
* This implementation always uses a 3-byte packet length for simplicity. It
* could be adjusted to support other lengths.
*
* @ctx: ACPI context pointer
*/
void acpigen_write_len_f(struct acpi_ctx *ctx);
/**
* acpigen_pop_len() - Update the previously stacked length placeholder
*
* Call this after the data for the block has been written. It updates the
* top length value in the stack and pops it off.
*
* @ctx: ACPI context pointer
*/
void acpigen_pop_len(struct acpi_ctx *ctx);
/**
* acpigen_write_package() - Start writing a package
*
* A package collects together a number of elements in the ACPI code. To write
* a package use:
*
* acpigen_write_package(ctx, 3);
* ...write things
* acpigen_pop_len()
*
* If you don't know the number of elements in advance, acpigen_write_package()
* returns a pointer to the value so you can update it later:
*
* char *num_elements = acpigen_write_package(ctx, 0);
* ...write things
* *num_elements += 1;
* ...write things
* *num_elements += 1;
* acpigen_pop_len()
*
* @ctx: ACPI context pointer
* @nr_el: Number of elements (0 if not known)
* @returns pointer to the number of elements, which can be updated by the
* caller if needed
*/
char *acpigen_write_package(struct acpi_ctx *ctx, int nr_el);
/**
* acpigen_write_byte() - Write a byte
*
* @ctx: ACPI context pointer
* @data: Value to write
*/
void acpigen_write_byte(struct acpi_ctx *ctx, unsigned int data);
/**
* acpigen_write_word() - Write a word
*
* @ctx: ACPI context pointer
* @data: Value to write
*/
void acpigen_write_word(struct acpi_ctx *ctx, unsigned int data);
/**
* acpigen_write_dword() - Write a dword
*
* @ctx: ACPI context pointer
* @data: Value to write
*/
void acpigen_write_dword(struct acpi_ctx *ctx, unsigned int data);
/**
* acpigen_write_qword() - Write a qword
*
* @ctx: ACPI context pointer
* @data: Value to write
*/
void acpigen_write_qword(struct acpi_ctx *ctx, u64 data);
/**
* acpigen_write_zero() - Write zero
*
* @ctx: ACPI context pointer
*/
void acpigen_write_zero(struct acpi_ctx *ctx);
/**
* acpigen_write_one() - Write one
*
* @ctx: ACPI context pointer
*/
void acpigen_write_one(struct acpi_ctx *ctx);
/**
* acpigen_write_integer() - Write an integer
*
* This writes an operation (BYTE_OP, WORD_OP, DWORD_OP, QWORD_OP depending on
* the integer size) and an integer value. Note that WORD means 16 bits in ACPI.
*
* @ctx: ACPI context pointer
* @data: Integer to write
*/
void acpigen_write_integer(struct acpi_ctx *ctx, u64 data);
/**
* acpigen_write_name_zero() - Write a named zero value
*
* @ctx: ACPI context pointer
* @name: Name of the value
*/
void acpigen_write_name_zero(struct acpi_ctx *ctx, const char *name);
/**
* acpigen_write_name_one() - Write a named one value
*
* @ctx: ACPI context pointer
* @name: Name of the value
*/
void acpigen_write_name_one(struct acpi_ctx *ctx, const char *name);
/**
* acpigen_write_name_byte() - Write a named byte value
*
* @ctx: ACPI context pointer
* @name: Name of the value
* @val: Value to write
*/
void acpigen_write_name_byte(struct acpi_ctx *ctx, const char *name, uint val);
/**
* acpigen_write_name_word() - Write a named word value
*
* @ctx: ACPI context pointer
* @name: Name of the value
* @val: Value to write
*/
void acpigen_write_name_word(struct acpi_ctx *ctx, const char *name, uint val);
/**
* acpigen_write_name_dword() - Write a named dword value
*
* @ctx: ACPI context pointer
* @name: Name of the value
* @val: Value to write
*/
void acpigen_write_name_dword(struct acpi_ctx *ctx, const char *name, uint val);
/**
* acpigen_write_name_qword() - Write a named qword value
*
* @ctx: ACPI context pointer
* @name: Name of the value
* @val: Value to write
*/
void acpigen_write_name_qword(struct acpi_ctx *ctx, const char *name, u64 val);
/**
* acpigen_write_name_integer() - Write a named integer value
*
* @ctx: ACPI context pointer
* @name: Name of the value
* @val: Value to write
*/
void acpigen_write_name_integer(struct acpi_ctx *ctx, const char *name,
u64 val);
/**
* acpigen_write_name_string() - Write a named string value
*
* @ctx: ACPI context pointer
* @name: Name of the value
* @string: String to write
*/
void acpigen_write_name_string(struct acpi_ctx *ctx, const char *name,
const char *string);
/**
* acpigen_write_string() - Write a string
*
* This writes a STRING_PREFIX followed by a null-terminated string
*
* @ctx: ACPI context pointer
* @str: String to write
*/
void acpigen_write_string(struct acpi_ctx *ctx, const char *str);
/**
* acpigen_emit_namestring() - Emit an ACPI name
*
* This writes out an ACPI name or path in the required special format. It does
* not add the NAME_OP prefix.
*
* @ctx: ACPI context pointer
* @namepath: Name / path to emit
*/
void acpigen_emit_namestring(struct acpi_ctx *ctx, const char *namepath);
/**
* acpigen_write_name() - Write out an ACPI name
*
* This writes out an ACPI name or path in the required special format with a
* NAME_OP prefix.
*
* @ctx: ACPI context pointer
* @namepath: Name / path to emit
*/
void acpigen_write_name(struct acpi_ctx *ctx, const char *namepath);
/**
* acpigen_write_scope() - Write a scope
*
* @ctx: ACPI context pointer
* @scope: Scope to write (e.g. "\\_SB.ABCD")
*/
void acpigen_write_scope(struct acpi_ctx *ctx, const char *scope);
/**
* acpigen_write_uuid() - Write a UUID
*
* This writes out a UUID in the format used by ACPI, with a BUFFER_OP prefix.
*
* @ctx: ACPI context pointer
* @uuid: UUID to write in the form aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
* Return: 0 if OK, -EINVAL if the format is incorrect
*/
int acpigen_write_uuid(struct acpi_ctx *ctx, const char *uuid);
/**
* acpigen_emit_ext_op() - Emit an extended op with the EXT_OP_PREFIX prefix
*
* @ctx: ACPI context pointer
* @op: Operation code (e.g. SLEEP_OP)
*/
void acpigen_emit_ext_op(struct acpi_ctx *ctx, uint op);
/**
* acpigen_write_method() - Write a method header
*
* @ctx: ACPI context pointer
* @name: Method name (4 characters)
* @nargs: Number of method arguments (0 if none)
*/
void acpigen_write_method(struct acpi_ctx *ctx, const char *name, int nargs);
/**
* acpigen_write_method_serialized() - Write a method header
*
* This sets the 'serialized' flag so that the method is thread-safe
*
* @ctx: ACPI context pointer
* @name: Method name (4 characters)
* @nargs: Number of method arguments (0 if none)
*/
void acpigen_write_method_serialized(struct acpi_ctx *ctx, const char *name,
int nargs);
/**
* acpigen_write_device() - Write an ACPI device
*
* @ctx: ACPI context pointer
* @name: Device name to write
*/
void acpigen_write_device(struct acpi_ctx *ctx, const char *name);
/**
* acpigen_write_sta() - Write a _STA method
*
* @ctx: ACPI context pointer
* @status: Status value to return
*/
void acpigen_write_sta(struct acpi_ctx *ctx, uint status);
/**
* acpigen_write_resourcetemplate_header() - Write a ResourceTemplate header
*
* @ctx: ACPI context pointer
*/
void acpigen_write_resourcetemplate_header(struct acpi_ctx *ctx);
/**
* acpigen_write_resourcetemplate_footer() - Write a ResourceTemplate footer
*
* @ctx: ACPI context pointer
*/
void acpigen_write_resourcetemplate_footer(struct acpi_ctx *ctx);
/**
* acpigen_write_register_resource() - Write a register resource
*
* This writes a header, the address information and a footer
*
* @ctx: ACPI context pointer
* @addr: Address to write
*/
void acpigen_write_register_resource(struct acpi_ctx *ctx,
const struct acpi_gen_regaddr *addr);
/**
* acpigen_write_sleep() - Write a sleep operation
*
* @ctx: ACPI context pointer
* @sleep_ms: Number of milliseconds to sleep for
*/
void acpigen_write_sleep(struct acpi_ctx *ctx, u64 sleep_ms);
/**
* acpigen_write_store() - Write a store operation
*
* @ctx: ACPI context pointer
*/
void acpigen_write_store(struct acpi_ctx *ctx);
/**
* acpigen_write_debug_string() - Write a debug string
*
* This writes a debug operation with an associated string
*
* @ctx: ACPI context pointer
* @str: String to write
*/
void acpigen_write_debug_string(struct acpi_ctx *ctx, const char *str);
/**
* acpigen_write_or() - Write a bitwise OR operation
*
* res = arg1 | arg2
*
* @ctx: ACPI context pointer
* @arg1: ACPI opcode for operand 1 (e.g. LOCAL0_OP)
* @arg2: ACPI opcode for operand 2 (e.g. LOCAL1_OP)
* @res: ACPI opcode for result (e.g. LOCAL2_OP)
*/
void acpigen_write_or(struct acpi_ctx *ctx, u8 arg1, u8 arg2, u8 res);
/**
* acpigen_write_and() - Write a bitwise AND operation
*
* res = arg1 & arg2
*
* @ctx: ACPI context pointer
* @arg1: ACPI opcode for operand 1 (e.g. LOCAL0_OP)
* @arg2: ACPI opcode for operand 2 (e.g. LOCAL1_OP)
* @res: ACPI opcode for result (e.g. LOCAL2_OP)
*/
void acpigen_write_and(struct acpi_ctx *ctx, u8 arg1, u8 arg2, u8 res);
/**
* acpigen_write_not() - Write a bitwise NOT operation
*
* res = ~arg1
*
* @ctx: ACPI context pointer
* @arg: ACPI opcode for operand (e.g. LOCAL0_OP)
* @res: ACPI opcode for result (e.g. LOCAL2_OP)
*/
void acpigen_write_not(struct acpi_ctx *ctx, u8 arg, u8 res);
/**
* acpigen_write_power_res() - Write a power resource
*
* Name (_PRx, Package(One) { name })
* ...
* PowerResource (name, level, order)
*
* The caller should fill in the rest of the power resource and then call
* acpigen_pop_len() to close it off
*
* @ctx: ACPI context pointer
* @name: Name of power resource (e.g. "PRIC")
* @level: Deepest sleep level that this resource must be kept on (0=S0, 3=S3)
* @order: Order that this must be enabled/disabled (e.g. 0)
* @dev_stats: List of states to define, e.g. {"_PR0", "_PR3"}
* @dev_states_count: Number of dev states
*/
void acpigen_write_power_res(struct acpi_ctx *ctx, const char *name, uint level,
uint order, const char *const dev_states[],
size_t dev_states_count);
/**
* acpigen_set_enable_tx_gpio() - Emit ACPI code to enable/disable a GPIO
*
* This emits code to either enable to disable a Tx GPIO. It takes account of
* the GPIO polarity.
*
* The code needs access to the DW0 register for the pad being used. This is
* provided by gpio->pin0_addr and ACPI methods must be defined for the board
* which can read and write the pad's DW0 register given this address:
* @dw0_read: takes a single argument, the DW0 address
* returns the DW0 value
* @dw0:write: takes two arguments, the DW0 address and the value to write
* no return value
*
* Example code (-- means comment):
*
* -- Get Pad Configuration DW0 register value
* Method (GPC0, 0x1, Serialized)
* {
* -- Arg0 - GPIO DW0 address
* Store (Arg0, Local0)
* OperationRegion (PDW0, SystemMemory, Local0, 4)
* Field (PDW0, AnyAcc, NoLock, Preserve) {
* TEMP, 32
* }
* Return (TEMP)
* }
*
* -- Set Pad Configuration DW0 register value
* Method (SPC0, 0x2, Serialized)
* {
* -- Arg0 - GPIO DW0 address
* -- Arg1 - Value for DW0 register
* Store (Arg0, Local0)
* OperationRegion (PDW0, SystemMemory, Local0, 4)
* Field (PDW0, AnyAcc, NoLock, Preserve) {
* TEMP,32
* }
* Store (Arg1, TEMP)
* }
*
*
* @ctx: ACPI context pointer
* @tx_state_val: Mask to use to toggle the TX state on the GPIO pin, e,g.
* PAD_CFG0_TX_STATE
* @dw0_read: Method name to use to read dw0, e.g. "\\_SB.GPC0"
* @dw0_write: Method name to use to read dw0, e.g. "\\_SB.SPC0"
* @gpio: GPIO to change
* @enable: true to enable GPIO, false to disable
* Returns 0 on success, -ve on error.
*/
int acpigen_set_enable_tx_gpio(struct acpi_ctx *ctx, u32 tx_state_val,
const char *dw0_read, const char *dw0_write,
struct acpi_gpio *gpio, bool enable);
/**
* acpigen_write_prw() - Write a power resource for wake (_PRW)
*
* @ctx: ACPI context pointer
* @wake: GPE that wakes up the device
* @level: Deepest power system sleeping state that can be entered while still
* providing wake functionality
*/
void acpigen_write_prw(struct acpi_ctx *ctx, uint wake, uint level);
/**
* acpigen_write_if() - Write an If block
*
* This requires a call to acpigen_pop_len() to complete the block
*
* @ctx: ACPI context pointer
*/
void acpigen_write_if(struct acpi_ctx *ctx);
/**
* acpigen_write_if_lequal_op_int() - Write comparison between op and integer
*
* Generates ACPI code for checking if operand1 and operand2 are equal
*
* If (Lequal (op, val))
*
* @ctx: ACPI context pointer
* @op: Operand to check
* @val: Value to check against
*/
void acpigen_write_if_lequal_op_int(struct acpi_ctx *ctx, uint op, u64 val);
/**
* acpigen_write_else() - Write an Ef block
*
* This requires a call to acpigen_pop_len() to complete the block
*
* @ctx: ACPI context pointer
*/
void acpigen_write_else(struct acpi_ctx *ctx);
/**
* acpigen_write_to_buffer() - Write a ToBuffer operation
*
* E.g.: to generate: ToBuffer (Arg0, Local0)
* use acpigen_write_to_buffer(ctx, ARG0_OP, LOCAL0_OP)
*
* @ctx: ACPI context pointer
* @src: Source argument
* @dst: Destination argument
*/
void acpigen_write_to_buffer(struct acpi_ctx *ctx, uint src, uint dst);
/**
* acpigen_write_to_integer() - Write a ToInteger operation
*
* E.g.: to generate: ToInteger (Arg0, Local0)
* use acpigen_write_to_integer(ctx, ARG0_OP, LOCAL0_OP)
*
* @ctx: ACPI context pointer
* @src: Source argument
* @dst: Destination argument
*/
void acpigen_write_to_integer(struct acpi_ctx *ctx, uint src, uint dst);
/**
* acpigen_write_return_byte_buffer() - Write a return of a byte buffer
*
* @ctx: ACPI context pointer
* @arr: Array of bytes to return
* @size: Number of bytes
*/
void acpigen_write_return_byte_buffer(struct acpi_ctx *ctx, u8 *arr,
size_t size);
/**
* acpigen_write_return_singleton_buffer() - Write a return of a 1-byte buffer
*
* @ctx: ACPI context pointer
* @arg: Byte to return
*/
void acpigen_write_return_singleton_buffer(struct acpi_ctx *ctx, uint arg);
/**
* acpigen_write_return_byte() - Write a return of a byte
*
* @ctx: ACPI context pointer
* @arg: Byte to return
*/
void acpigen_write_return_byte(struct acpi_ctx *ctx, uint arg);
/**
* acpigen_write_dsm_start() - Start a _DSM method
*
* Generate ACPI AML code to start the _DSM method.
*
* The functions need to be called in the correct sequence as below.
*
* Within the <generate-code-here> region, Local0 and Local1 must be are left
* untouched, but Local2-Local7 can be used
*
* Arguments passed into _DSM method:
* Arg0 = UUID
* Arg1 = Revision
* Arg2 = Function index
* Arg3 = Function-specific arguments
*
* AML code generated looks like this:
* Method (_DSM, 4, Serialized) { -- acpigen_write_dsm_start)
* ToBuffer (Arg0, Local0)
* If (LEqual (Local0, ToUUID(uuid))) { -- acpigen_write_dsm_uuid_start
* ToInteger (Arg2, Local1)
* If (LEqual (Local1, 0)) { -- acpigen_write_dsm_uuid_start_cond
* <generate-code-here>
* } -- acpigen_write_dsm_uuid_end_cond
* ...
* If (LEqual (Local1, n)) { -- acpigen_write_dsm_uuid_start_cond
* <generate-code-here>
* } -- acpigen_write_dsm_uuid_end_cond
* Return (Buffer (One) { 0x0 })
* } -- acpigen_write_dsm_uuid_end
* ...
* If (LEqual (Local0, ToUUID(uuidn))) {
* ...
* }
* Return (Buffer (One) { 0x0 }) -- acpigen_write_dsm_end
* }
*
* @ctx: ACPI context pointer
*/
void acpigen_write_dsm_start(struct acpi_ctx *ctx);
/**
* acpigen_write_dsm_uuid_start() - Start a new UUID block
*
* This starts generation of code to handle a particular UUID:
*
* If (LEqual (Local0, ToUUID(uuid))) {
* ToInteger (Arg2, Local1)
*
* @ctx: ACPI context pointer
*/
int acpigen_write_dsm_uuid_start(struct acpi_ctx *ctx, const char *uuid);
/**
* acpigen_write_dsm_uuid_start_cond() - Start a new condition block
*
* This starts generation of condition-checking code to handle a particular
* function:
*
* If (LEqual (Local1, i))
*
* @ctx: ACPI context pointer
*/
void acpigen_write_dsm_uuid_start_cond(struct acpi_ctx *ctx, int seq);
/**
* acpigen_write_dsm_uuid_end_cond() - Start a new condition block
*
* This ends generation of condition-checking code to handle a particular
* function:
*
* }
*
* @ctx: ACPI context pointer
*/
void acpigen_write_dsm_uuid_end_cond(struct acpi_ctx *ctx);
/**
* acpigen_write_dsm_uuid_end() - End a UUID block
*
* This ends generation of code to handle a particular UUID:
*
* Return (Buffer (One) { 0x0 })
*
* @ctx: ACPI context pointer
*/
void acpigen_write_dsm_uuid_end(struct acpi_ctx *ctx);
/**
* acpigen_write_dsm_end() - End a _DSM method
*
* This ends generates of the _DSM block:
*
* Return (Buffer (One) { 0x0 })
*
* @ctx: ACPI context pointer
*/
void acpigen_write_dsm_end(struct acpi_ctx *ctx);
/**
* acpigen_write_processor() - Write a Processor package
*
* This emits a Processor package header with the required information. The
* caller must complete the information and call acpigen_pop_len() at the end
* Deprecated since ACPI 6.0.
*
* @ctx: ACPI context pointer
* @cpuindex: CPU number
* @pblock_addr: PBlk system IO address
* @pblock_len: PBlk length
*/
void acpigen_write_processor(struct acpi_ctx *ctx, uint cpuindex,
u32 pblock_addr, uint pblock_len);
/**
* acpigen_write_processor_device() - Write a Processor device
*
* Write a device with _HID ACPI0007 identifying a processor.
* Replacement for the Processor OpCode.
*
* @ctx: ACPI context pointer
* @cpuindex: CPU number
*/
void acpigen_write_processor_device(struct acpi_ctx *ctx, uint cpuindex);
/**
* acpigen_write_processor_package() - Write a package containing the processors
*
* The package containins the name of each processor in the SoC
*
* @ctx: ACPI context pointer
* @name: Package name (.e.g "PPKG")
* @first_core: Number of the first core (e.g. 0)
* @core_count: Number of cores (e.g. 4)
*/
void acpigen_write_processor_package(struct acpi_ctx *ctx, const char *name,
uint first_core, uint core_count);
/**
* acpigen_write_processor_cnot() - Write a processor notification method
*
* This writes a method that notifies all CPU cores
*
* @ctx: ACPI context pointer
* @num_cores: Number of CPU cores
*/
void acpigen_write_processor_cnot(struct acpi_ctx *ctx, const uint num_cores);
/**
* acpigen_write_ppc() - generates a function returning max P-states
*
* @ctx: ACPI context pointer
* @num_pstates: Number of pstates to return
*/
void acpigen_write_ppc(struct acpi_ctx *ctx, uint num_pstates);
/**
* acpigen_write_ppc() - generates a function returning PPCM
*
* This returns the maximum number of supported P-states, as saved in the
* variable PPCM
*
* @ctx: ACPI context pointer
*/
void acpigen_write_ppc_nvs(struct acpi_ctx *ctx);
/**
* acpigen_write_tpc() - Write a _TPC method that returns the TPC limit
*
* @ctx: ACPI context pointer
* @gnvs_tpc_limit: Variable that holds the TPC limit
*/
void acpigen_write_tpc(struct acpi_ctx *ctx, const char *gnvs_tpc_limit);
/**
* acpigen_write_pss_package() - Write a PSS package
*
* See ACPI v6.3 section 8.4.6: Processor Performance Control
*
* @ctx: ACPI context pointer
* @corefreq: CPU core frequency in MHz
* @translat: worst-case latency in uS that the CPU is unavailable during a
* transition from any performance state to this performance state
* @busmlat: worst-case latency in microseconds that Bus Masters are prevented
* from accessing memory during a transition from any performance state to
* this performance state
* @control: Value to write to PERF_CTRL to move to this performance state
* @status: Expected PERF_STATUS value when in this state
*/
void acpigen_write_pss_package(struct acpi_ctx *ctx, uint corefreq, uint power,
uint translat, uint busmlat, uint control,
uint status);
/**
* acpigen_write_psd_package() - Write a PSD package
*
* Writes a P-State dependency package
*
* See ACPI v6.3 section 8.4.6.5: _PSD (P-State Dependency)
*
* @ctx: ACPI context pointer
* @domain: Dependency domain number to which this P state entry belongs
* @numprocs: Number of processors belonging to the domain for this logical
* processor's P-states
* @coordtype: Coordination type
*/
void acpigen_write_psd_package(struct acpi_ctx *ctx, uint domain, uint numprocs,
enum psd_coord coordtype);
/**
* acpigen_write_cst_package() - Write a _CST package
*
* See ACPI v6.3 section 8.4.2.1: _CST (C States)
*
* @ctx: ACPI context pointer
* @entry: Array of entries
* @nentries; Number of entries
*/
void acpigen_write_cst_package(struct acpi_ctx *ctx,
const struct acpi_cstate *entry, int nentries);
/**
* acpigen_write_csd_package() - Write a _CSD Package
*
* See ACPI v6.3 section 8.4.2.2: _CSD (C-State Dependency)
*
* @ctx: ACPI context pointer
* @domain: dependency domain number to which this C state entry belongs
* @numprocs: number of processors belonging to the domain for the particular
* C-state
* @coordtype: Co-ordination type
* @index: Index of the C-State entry in the _CST object for which the
* dependency applies
*/
void acpigen_write_csd_package(struct acpi_ctx *ctx, uint domain, uint numprocs,
enum csd_coord coordtype, uint index);
/**
* acpigen_write_tss_package() - Write a _TSS package
*
* @ctx: ACPI context pointer
* @entry: Entries to write
* @nentries: Number of entries to write
*/
void acpigen_write_tss_package(struct acpi_ctx *ctx,
struct acpi_tstate *entry, int nentries);
/**
* acpigen_write_tsd_package() - Write a _TSD package
*
* See ACPI v6.3 section 8.4.5.4: _TSD (T-State Dependency)
*
* @ctx: ACPI context pointer
* @domain: dependency domain number to which this T state entry belongs
* @numprocs: Number of processors belonging to the domain for this logical
* processor's T-states
* @coordtype: Coordination type
*/
void acpigen_write_tsd_package(struct acpi_ctx *ctx, uint domain, uint numprocs,
enum psd_coord coordtype);
#endif
+310
View File
@@ -0,0 +1,310 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2015 Samsung Electronics
* Przemyslaw Marczak <p.marczak@samsung.com>
*/
#ifndef _ADC_H_
#define _ADC_H_
#include <stdbool.h>
/* ADC_CHANNEL() - ADC channel bit mask, to select only required channels */
#define ADC_CHANNEL(x) (1 << x)
/* The last possible selected channel with 32-bit mask */
#define ADC_MAX_CHANNEL 31
/**
* adc_data_format: define the ADC output data format, can be useful when
* the device's input Voltage range is bipolar.
* - ADC_DATA_FORMAT_BIN - binary offset
* - ADC_DATA_FORMAT_2S - two's complement
*
* Note: Device's driver should fill the 'data_format' field of its uclass's
* platform data using one of the above data format types.
*/
enum adc_data_format {
ADC_DATA_FORMAT_BIN,
ADC_DATA_FORMAT_2S,
};
/**
* struct adc_channel - structure to hold channel conversion data.
* Useful to keep the result of a multi-channel conversion output.
*
* @id - channel id
* @data - channel conversion data
*/
struct adc_channel {
int id;
unsigned int data;
};
/**
* struct adc_uclass_plat - basic ADC info
*
* Note: The positive/negative reference Voltage is only a name and it doesn't
* provide an information about the value polarity. It is possible, for both
* values to be a negative or positive. For this purpose the uclass's platform
* data provides a bool fields: 'vdd/vss_supply_is_negative'. This is useful,
* since the regulator API returns only a positive Voltage values.
*
* To get the reference Voltage values with polarity, use functions:
* - adc_vdd_value()
* - adc_vss_value()
* Those are useful for some cases of ADC's references, e.g.:
* * Vdd: +3.3V; Vss: -3.3V -> 6.6 Vdiff
* * Vdd: +3.3V; Vss: +0.3V -> 3.0 Vdiff
* * Vdd: +3.3V; Vss: 0.0V -> 3.3 Vdiff
* The last one is usually standard and doesn't require the fdt polarity info.
*
* For more informations read binding info:
* - doc/device-tree-bindings/adc/adc.txt
*
* @data_mask - conversion output data mask
* @data_timeout_us - single channel conversion timeout
* @multidata_timeout_us - multi channel conversion timeout
* @channel_mask - bit mask of available channels [0:31]
* @vdd_supply - positive reference Voltage supply (regulator)
* @vss_supply - negative reference Voltage supply (regulator)
* @vdd_polarity_negative - positive reference Voltage has negative polarity
* @vss_polarity_negative - negative reference Voltage has negative polarity
* @vdd_microvolts - positive reference Voltage value
* @vss_microvolts - negative reference Voltage value
*/
struct adc_uclass_plat {
int data_format;
unsigned int data_mask;
unsigned int data_timeout_us;
unsigned int multidata_timeout_us;
unsigned int channel_mask;
struct udevice *vdd_supply;
struct udevice *vss_supply;
bool vdd_polarity_negative;
bool vss_polarity_negative;
int vdd_microvolts;
int vss_microvolts;
};
/**
* struct adc_ops - ADC device operations for single/multi-channel operation.
*/
struct adc_ops {
/**
* start_channel() - start conversion with its default parameters
* for the given channel number.
*
* @dev: ADC device to init
* @channel: analog channel number
* @return: 0 if OK, -ve on error
*/
int (*start_channel)(struct udevice *dev, int channel);
/**
* start_channels() - start conversion with its default parameters
* for the channel numbers selected by the bit mask.
*
* This is optional, useful when the hardware supports multichannel
* conversion by the single software trigger.
*
* @dev: ADC device to init
* @channel_mask: bit mask of selected analog channels
* @return: 0 if OK, -ve on error
*/
int (*start_channels)(struct udevice *dev, unsigned int channel_mask);
/**
* channel_data() - get conversion output data for the given channel.
*
* Note: The implementation of this function should only check, that
* the conversion data is available at the call time. If the hardware
* requires some delay to get the data, then this function should
* return with -EBUSY value. The ADC API will call it in a loop,
* until the data is available or the timeout expires. The maximum
* timeout for this operation is defined by the field 'data_timeout_us'
* in ADC uclasses platform data structure.
*
* @dev: ADC device to trigger
* @channel: selected analog channel number
* @data: returned pointer to selected channel's output data
* @return: 0 if OK, -EBUSY if busy, and other negative on error
*/
int (*channel_data)(struct udevice *dev, int channel,
unsigned int *data);
/**
* channels_data() - get conversion data for the selected channels.
*
* This is optional, useful when multichannel conversion is supported
* by the hardware, by the single software trigger.
*
* For the proper implementation, please look at the 'Note' for the
* above method. The only difference is in used timeout value, which
* is defined by field 'multidata_timeout_us'.
*
* @dev: ADC device to trigger
* @channel_mask: bit mask of selected analog channels
* @channels: returned pointer to array of output data for channels
* selected by the given mask
* @return: 0 if OK, -ve on error
*/
int (*channels_data)(struct udevice *dev, unsigned int channel_mask,
struct adc_channel *channels);
/**
* stop() - stop conversion of the given ADC device
*
* @dev: ADC device to stop
* @return: 0 if OK, -ve on error
*/
int (*stop)(struct udevice *dev);
};
/**
* adc_start_channel() - start conversion for given device/channel and exit.
*
* @dev: ADC device
* @channel: analog channel number
* @return: 0 if OK, -ve on error
*/
int adc_start_channel(struct udevice *dev, int channel);
/**
* adc_start_channels() - start conversion for given device/channels and exit.
*
* Note:
* To use this function, device must implement method: start_channels().
*
* @dev: ADC device to start
* @channel_mask: channel selection - a bit mask
* @channel_mask: bit mask of analog channels
* @return: 0 if OK, -ve on error
*/
int adc_start_channels(struct udevice *dev, unsigned int channel_mask);
/**
* adc_channel_data() - get conversion data for the given device channel number.
*
* @dev: ADC device to read
* @channel: analog channel number
* @data: pointer to returned channel's data
* @return: 0 if OK, -ve on error
*/
int adc_channel_data(struct udevice *dev, int channel, unsigned int *data);
/**
* adc_channels_data() - get conversion data for the channels selected by mask
*
* Note:
* To use this function, device must implement methods:
* - start_channels()
* - channels_data()
*
* @dev: ADC device to read
* @channel_mask: channel selection - a bit mask
* @channels: pointer to structure array of returned data for each channel
* @return: 0 if OK, -ve on error
*/
int adc_channels_data(struct udevice *dev, unsigned int channel_mask,
struct adc_channel *channels);
/**
* adc_data_mask() - get data mask (ADC resolution bitmask) for given ADC device
*
* This can be used if adc uclass platform data is filled.
*
* @dev: ADC device to check
* @data_mask: pointer to the returned data bitmask
* @return: 0 if OK, -ve on error
*/
int adc_data_mask(struct udevice *dev, unsigned int *data_mask);
/**
* adc_channel_mask() - get channel mask for given ADC device
*
* This can be used if adc uclass platform data is filled.
*
* @dev: ADC device to check
* @channel_mask: pointer to the returned channel bitmask
* @return: 0 if OK, -ve on error
*/
int adc_channel_mask(struct udevice *dev, unsigned int *channel_mask);
/**
* adc_channel_single_shot() - get output data of conversion for the ADC
* device's channel. This function searches for the device with the given name,
* starts the given channel conversion and returns the output data.
*
* Note: To use this function, device must implement metods:
* - start_channel()
* - channel_data()
*
* @name: device's name to search
* @channel: device's input channel to init
* @data: pointer to conversion output data
* @return: 0 if OK, -ve on error
*/
int adc_channel_single_shot(const char *name, int channel, unsigned int *data);
/**
* adc_channels_single_shot() - get ADC conversion output data for the selected
* device's channels. This function searches for the device by the given name,
* starts the selected channels conversion and returns the output data as array
* of type 'struct adc_channel'.
*
* Note: This function can be used if device implements one of ADC's single
* or multi-channel operation API. If multi-channel operation is not supported,
* then each selected channel is triggered by the sequence start/data in a loop.
*
* @name: device's name to search
* @channel_mask: channel selection - a bit mask
* @channels: pointer to conversion output data for the selected channels
* @return: 0 if OK, -ve on error
*/
int adc_channels_single_shot(const char *name, unsigned int channel_mask,
struct adc_channel *channels);
/**
* adc_vdd_value() - get the ADC device's positive reference Voltage value
*
* Note: Depending on bool value 'vdd_supply_is_negative' of platform data,
* the returned uV value can be negative, and it's not an error.
*
* @dev: ADC device to check
* @uV: Voltage value with polarization sign (uV)
* @return: 0 on success or -ve on error
*/
int adc_vdd_value(struct udevice *dev, int *uV);
/**
* adc_vss_value() - get the ADC device's negative reference Voltage value
*
* Note: Depending on bool value 'vdd_supply_is_negative' of platform data,
* the returned uV value can be negative, and it's not an error.
*
* @dev: ADC device to check
* @uV: Voltage value with polarization sign (uV)
* @return: 0 on success or -ve on error
*/
int adc_vss_value(struct udevice *dev, int *uV);
/**
* adc_stop() - stop operation for given ADC device.
*
* @dev: ADC device to stop
* @return: 0 if OK, -ve on error
*/
int adc_stop(struct udevice *dev);
/**
* adc_raw_to_uV() - converts raw value to microvolts for given ADC device.
*
* @dev: ADC device used from conversion
* @raw: raw value to convert
* @uV: converted value in microvolts
* @return: 0 on success or -ve on error
*/
int adc_raw_to_uV(struct udevice *dev, unsigned int raw, int *uV);
#endif
+26
View File
@@ -0,0 +1,26 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ADDR_MAP_H
#define __ADDR_MAP_H
/*
* Copyright 2008 Freescale Semiconductor, Inc.
*/
#include <asm/types.h>
struct addrmap {
phys_addr_t paddr;
phys_size_t size;
unsigned long vaddr;
};
#ifdef CONFIG_ADDR_MAP
extern struct addrmap address_map[CONFIG_SYS_NUM_ADDR_MAP];
#endif
phys_addr_t addrmap_virt_to_phys(void *vaddr);
void *addrmap_phys_to_virt(phys_addr_t paddr);
void addrmap_set_entry(unsigned long vaddr, phys_addr_t paddr,
phys_size_t size, int idx);
#endif
+281
View File
@@ -0,0 +1,281 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) Freescale Semiconductor, Inc. 2006.
* Author: Jason Jin<Jason.jin@freescale.com>
* Zhang Wei<wei.zhang@freescale.com>
*/
#ifndef _AHCI_H_
#define _AHCI_H_
#include <linux/types.h>
#define AHCI_PCI_BAR 0x24
#define AHCI_MAX_SG 56 /* hardware max is 64K */
#define AHCI_CMD_SLOT_SZ 32
#define AHCI_MAX_CMD_SLOT 32
#define AHCI_RX_FIS_SZ 256
#define AHCI_CMD_TBL_HDR 0x80
#define AHCI_CMD_TBL_CDB 0x40
#define AHCI_CMD_TBL_SZ AHCI_CMD_TBL_HDR + (AHCI_MAX_SG * 16)
#define AHCI_PORT_PRIV_DMA_SZ (AHCI_CMD_SLOT_SZ * AHCI_MAX_CMD_SLOT + \
AHCI_CMD_TBL_SZ + AHCI_RX_FIS_SZ)
#define AHCI_CMD_ATAPI (1 << 5)
#define AHCI_CMD_WRITE (1 << 6)
#define AHCI_CMD_PREFETCH (1 << 7)
#define AHCI_CMD_RESET (1 << 8)
#define AHCI_CMD_CLR_BUSY (1 << 10)
#define RX_FIS_D2H_REG 0x40 /* offset of D2H Register FIS data */
/* Global controller registers */
#define HOST_CAP 0x00 /* host capabilities */
#define HOST_CTL 0x04 /* global host control */
#define HOST_IRQ_STAT 0x08 /* interrupt status */
#define HOST_PORTS_IMPL 0x0c /* bitmap of implemented ports */
#define HOST_VERSION 0x10 /* AHCI spec. version compliancy */
#define HOST_CAP2 0x24 /* host capabilities, extended */
/* HOST_CTL bits */
#define HOST_RESET (1 << 0) /* reset controller; self-clear */
#define HOST_IRQ_EN (1 << 1) /* global IRQ enable */
#define HOST_AHCI_EN (1 << 31) /* AHCI enabled */
/* Registers for each SATA port */
#define PORT_LST_ADDR 0x00 /* command list DMA addr */
#define PORT_LST_ADDR_HI 0x04 /* command list DMA addr hi */
#define PORT_FIS_ADDR 0x08 /* FIS rx buf addr */
#define PORT_FIS_ADDR_HI 0x0c /* FIS rx buf addr hi */
#define PORT_IRQ_STAT 0x10 /* interrupt status */
#define PORT_IRQ_MASK 0x14 /* interrupt enable/disable mask */
#define PORT_CMD 0x18 /* port command */
#define PORT_TFDATA 0x20 /* taskfile data */
#define PORT_SIG 0x24 /* device TF signature */
#define PORT_CMD_ISSUE 0x38 /* command issue */
#define PORT_SCR 0x28 /* SATA phy register block */
#define PORT_SCR_STAT 0x28 /* SATA phy register: SStatus */
#define PORT_SCR_CTL 0x2c /* SATA phy register: SControl */
#define PORT_SCR_ERR 0x30 /* SATA phy register: SError */
#define PORT_SCR_ACT 0x34 /* SATA phy register: SActive */
#ifdef CONFIG_SUNXI_AHCI
#define PORT_P0DMACR 0x70 /* SUNXI specific "DMA register" */
#endif
/* PORT_IRQ_{STAT,MASK} bits */
#define PORT_IRQ_COLD_PRES (1 << 31) /* cold presence detect */
#define PORT_IRQ_TF_ERR (1 << 30) /* task file error */
#define PORT_IRQ_HBUS_ERR (1 << 29) /* host bus fatal error */
#define PORT_IRQ_HBUS_DATA_ERR (1 << 28) /* host bus data error */
#define PORT_IRQ_IF_ERR (1 << 27) /* interface fatal error */
#define PORT_IRQ_IF_NONFATAL (1 << 26) /* interface non-fatal error */
#define PORT_IRQ_OVERFLOW (1 << 24) /* xfer exhausted available S/G */
#define PORT_IRQ_BAD_PMP (1 << 23) /* incorrect port multiplier */
#define PORT_IRQ_PHYRDY (1 << 22) /* PhyRdy changed */
#define PORT_IRQ_DEV_ILCK (1 << 7) /* device interlock */
#define PORT_IRQ_CONNECT (1 << 6) /* port connect change status */
#define PORT_IRQ_SG_DONE (1 << 5) /* descriptor processed */
#define PORT_IRQ_UNK_FIS (1 << 4) /* unknown FIS rx'd */
#define PORT_IRQ_SDB_FIS (1 << 3) /* Set Device Bits FIS rx'd */
#define PORT_IRQ_DMAS_FIS (1 << 2) /* DMA Setup FIS rx'd */
#define PORT_IRQ_PIOS_FIS (1 << 1) /* PIO Setup FIS rx'd */
#define PORT_IRQ_D2H_REG_FIS (1 << 0) /* D2H Register FIS rx'd */
#define PORT_IRQ_FATAL PORT_IRQ_TF_ERR | PORT_IRQ_HBUS_ERR \
| PORT_IRQ_HBUS_DATA_ERR | PORT_IRQ_IF_ERR
#define DEF_PORT_IRQ PORT_IRQ_FATAL | PORT_IRQ_PHYRDY \
| PORT_IRQ_CONNECT | PORT_IRQ_SG_DONE \
| PORT_IRQ_UNK_FIS | PORT_IRQ_SDB_FIS \
| PORT_IRQ_DMAS_FIS | PORT_IRQ_PIOS_FIS \
| PORT_IRQ_D2H_REG_FIS
/* PORT_SCR_STAT bits */
#define PORT_SCR_STAT_DET_MASK 0x3
#define PORT_SCR_STAT_DET_COMINIT 0x1
#define PORT_SCR_STAT_DET_PHYRDY 0x3
/* PORT_CMD bits */
#define PORT_CMD_ATAPI (1 << 24) /* Device is ATAPI */
#define PORT_CMD_LIST_ON (1 << 15) /* cmd list DMA engine running */
#define PORT_CMD_FIS_ON (1 << 14) /* FIS DMA engine running */
#define PORT_CMD_FIS_RX (1 << 4) /* Enable FIS receive DMA engine */
#define PORT_CMD_CLO (1 << 3) /* Command list override */
#define PORT_CMD_POWER_ON (1 << 2) /* Power up device */
#define PORT_CMD_SPIN_UP (1 << 1) /* Spin up device */
#define PORT_CMD_START (1 << 0) /* Enable port DMA engine */
#define PORT_CMD_ICC_ACTIVE (0x1 << 28) /* Put i/f in active state */
#define PORT_CMD_ICC_PARTIAL (0x2 << 28) /* Put i/f in partial state */
#define PORT_CMD_ICC_SLUMBER (0x6 << 28) /* Put i/f in slumber state */
#define AHCI_MAX_PORTS 32
#define ATA_FLAG_SATA (1 << 3)
#define ATA_FLAG_NO_LEGACY (1 << 4) /* no legacy mode check */
#define ATA_FLAG_MMIO (1 << 6) /* use MMIO, not PIO */
#define ATA_FLAG_SATA_RESET (1 << 7) /* (obsolete) use COMRESET */
#define ATA_FLAG_PIO_DMA (1 << 8) /* PIO cmds via DMA */
#define ATA_FLAG_NO_ATAPI (1 << 11) /* No ATAPI support */
struct ahci_cmd_hdr {
u32 opts;
u32 status;
u32 tbl_addr;
u32 tbl_addr_hi;
u32 reserved[4];
};
struct ahci_sg {
u32 addr;
u32 addr_hi;
u32 reserved;
u32 flags_size;
};
struct ahci_ioports {
void __iomem *port_mmio;
struct ahci_cmd_hdr *cmd_slot;
struct ahci_sg *cmd_tbl_sg;
void *cmd_tbl;
void *rx_fis;
};
/**
* struct ahci_uc_priv - information about an AHCI controller
*
* When driver model is used, this is accessible using dev_get_uclass_priv(dev)
* where dev is the controller (although at present it sometimes stands alone).
*/
struct ahci_uc_priv {
/*
* TODO(sjg@chromium.org): Drop this once this structure is only used
* in a driver-model context (i.e. attached to a device with
* dev_get_uclass_priv()
*/
struct udevice *dev;
struct ahci_ioports port[AHCI_MAX_PORTS];
u16 *ataid[AHCI_MAX_PORTS];
u32 n_ports;
u32 hard_port_no;
u32 host_flags;
u32 host_set_flags;
void __iomem *mmio_base;
u32 pio_mask;
u32 udma_mask;
u32 flags;
u32 cap; /* cache of HOST_CAP register */
u32 port_map; /* cache of HOST_PORTS_IMPL reg */
u32 link_port_map; /*linkup port map*/
};
struct ahci_ops {
/**
* reset() - reset the controller
*
* @dev: Controller to reset
* @return 0 if OK, -ve on error
*/
int (*reset)(struct udevice *dev);
/**
* port_status() - get the status of a SATA port
*
* @dev: Controller to reset
* @port: Port number to check (0 for first)
* @return 0 if detected, -ENXIO if nothing on port, other -ve on error
*/
int (*port_status)(struct udevice *dev, int port);
/**
* scan() - scan SATA ports
*
* @dev: Controller to scan
* @return 0 if OK, -ve on error
*/
int (*scan)(struct udevice *dev);
};
#define ahci_get_ops(dev) ((struct ahci_ops *)(dev)->driver->ops)
/**
* sata_reset() - reset the controller
*
* @dev: Controller to reset
* Return: 0 if OK, -ve on error
*/
int sata_reset(struct udevice *dev);
/**
* sata_port_status() - get the status of a SATA port
*
* @dev: Controller to reset
* @port: Port number to check (0 for first)
* Return: 0 if detected, -ENXIO if nothin on port, other -ve on error
*/
int sata_dm_port_status(struct udevice *dev, int port);
/**
* sata_scan() - scan SATA ports
*
* @dev: Controller to scan
* Return: 0 if OK, -ve on error
*/
int sata_scan(struct udevice *dev);
/**
* ahci_init_one_dm() - set up a single AHCI port
*
* @dev: Controller to init
*/
int ahci_init_one_dm(struct udevice *dev);
/**
* ahci_start_ports_dm() - start all AHCI ports for a controller
*
* @dev: Controller containing ports to start
*/
int ahci_start_ports_dm(struct udevice *dev);
/**
* ahci_init_dm() - init AHCI for a controller, finding all ports
*
* @dev: Device to init
*/
int ahci_init_dm(struct udevice *dev, void __iomem *base);
/**
* ahci_bind_scsi() - bind a new SCSI bus as a child
*
* Note that the SCSI bus device will itself bind block devices
*
* @ahci_dev: AHCI parent device
* @devp: Returns new SCSI bus device
* Return: 0 if OK, -ve on error
*/
int ahci_bind_scsi(struct udevice *ahci_dev, struct udevice **devp);
/**
* ahci_probe_scsi() - probe and scan the attached SCSI bus
*
* Note that the SCSI device will itself bind block devices for any storage
* devices it finds.
*
* @ahci_dev: AHCI parent device
* @base: Base address of AHCI port
* Return: 0 if OK, -ve on error
*/
int ahci_probe_scsi(struct udevice *ahci_dev, ulong base);
/**
* ahci_probe_scsi_pci() - probe and scan the attached SCSI bus on PCI
*
* Note that the SCSI device will itself bind block devices for any storage
* devices it finds.
*
* @ahci_dev: AHCI parent device
* Return: 0 if OK, -ve on error
*/
int ahci_probe_scsi_pci(struct udevice *ahci_dev);
#endif
+372
View File
@@ -0,0 +1,372 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Handles a contiguous list of pointers which be allocated and freed
*
* Copyright 2023 Google LLC
* Written by Simon Glass <sjg@chromium.org>
*/
#ifndef __ALIST_H
#define __ALIST_H
#include <stdbool.h>
#include <linux/bitops.h>
#include <linux/types.h>
/**
* struct alist - object list that can be allocated and freed
*
* Holds a list of objects, each of the same size. The object is typically a
* C struct. The array is alloced in memory can change in size.
*
* The list rememebers the size of the list, but has a separate count of how
* much space is allocated, This allows it increase in size in steps as more
* elements are added, which is more efficient that reallocating the list every
* time a single item is added
*
* Two types of access are provided:
*
* alist_get...(index)
* gets an existing element, if its index is less that size
*
* alist_ensure(index)
* address an existing element, or creates a new one if not present
*
* @data: object data of size `@obj_size * @alloc`. The list can grow as
* needed but never shrinks
* @obj_size: Size of each object in bytes
* @count: number of objects in array
* @alloc: allocated length of array, to which @count can grow
* @flags: flags for the alist (ALISTF_...)
*/
struct alist {
void *data;
u16 obj_size;
u16 count;
u16 alloc;
u16 flags;
};
/**
* enum alist_flags - Flags for the alist
*
* @ALIST_FAIL: true if any allocation has failed. Once this has happened, the
* alist is dead and cannot grow further
*/
enum alist_flags {
ALISTF_FAIL = BIT(0),
};
/**
* alist_has() - Check if an index is within the list range
*
* Checks if index is within the current alist count
*
* @lst: alist to check
* @index: Index to check
* Returns: true if value, else false
*/
static inline bool alist_has(struct alist *lst, uint index)
{
return index < lst->count;
}
/**
* alist_calc_index() - Calculate the index of an item in the list
*
* The returned element number will be -1 if the list is empty or the pointer
* pointers to before the list starts.
*
* If the pointer points to after the last item, the calculated element-number
* will be returned, even though it is greater than lst->count
*
* @lst: alist to check
* @ptr: pointer to check
* Return: element number of the pointer
*/
int alist_calc_index(const struct alist *lst, const void *ptr);
/**
* alist_err() - Check if the alist is still valid
*
* @lst: List to check
* Return: false if OK, true if any previous allocation failed
*/
static inline bool alist_err(struct alist *lst)
{
return lst->flags & ALISTF_FAIL;
}
/**
* alist_full() - Check if the alist is full
*
* @lst: List to check
* Return: true if full, false otherwise
*/
static inline bool alist_full(struct alist *lst)
{
return lst->count == lst->alloc;
}
/**
* alist_get_ptr() - Get the value of a pointer
*
* @lst: alist to check
* @index: Index to read from
* Returns: pointer, if present, else NULL
*/
const void *alist_get_ptr(const struct alist *lst, uint index);
/**
* alist_getd() - Get the value of a pointer directly, with no checking
*
* This must only be called on indexes for which alist_has() returns true
*
* @lst: alist to check
* @index: Index to read from
* Returns: pointer value (may be NULL)
*/
static inline const void *alist_getd(struct alist *lst, uint index)
{
return lst->data + index * lst->obj_size;
}
/**
* alist_get() - get an entry as a constant
*
* Use as (to obtain element 2 of the list):
* const struct my_struct *ptr = alist_get(lst, 2, struct my_struct)
*/
#define alist_get(_lst, _index, _struct) \
((const _struct *)alist_get_ptr(_lst, _index))
/** get an entry which can be written to */
#define alist_getw(_lst, _index, _struct) \
((_struct *)alist_get_ptr(_lst, _index))
/**
* alist_ensure_ptr() - Ensure an object exists at a given index
*
* This provides read/write access to an array element. If it does not exist,
* it is allocated, reading for the caller to store the object into
*
* Allocates a object at the given index if needed
*
* @lst: alist to check
* @index: Index to address
* Returns: pointer where struct can be read/written, or NULL if out of memory
*/
void *alist_ensure_ptr(struct alist *lst, uint index);
/**
* alist_ensure() - Address a struct, the correct object type
*
* Use as:
* struct my_struct *ptr = alist_ensure(&lst, 4, struct my_struct);
*/
#define alist_ensure(_lst, _index, _struct) \
((_struct *)alist_ensure_ptr(_lst, _index))
/**
* alist_add_placeholder() - Add a new item to the end of the list
*
* @lst: alist to add to
* Return: Pointer to the newly added position, or NULL if out of memory. Note
* that this is not inited so the caller must copy the requested struct to the
* returned pointer
*/
void *alist_add_placeholder(struct alist *lst);
/**
* alist_add_ptr() - Ad a new object to the list
*
* @lst: alist to add to
* @obj: Pointer to object to copy in
* Returns: pointer to where the object was copied, or NULL if out of memory
*/
void *alist_add_ptr(struct alist *lst, void *obj);
/**
* alist_expand_by() - Expand a list by the given amount
*
* @lst: alist to expand
* @inc_by: Amount to expand by
* Return: true if OK, false if out of memory
*/
bool alist_expand_by(struct alist *lst, uint inc_by);
/**
* alist_add() - Used to add an object type with the correct type
*
* Use as:
* struct my_struct obj;
* struct my_struct *ptr = alist_add(&lst, &obj);
*/
#define alist_add(_lst, _obj) \
((typeof(_obj) *)alist_add_ptr(_lst, &(_obj)))
/** get next entry as a constant */
#define alist_next(_lst, _objp) \
((const typeof(_objp))alist_next_ptrd(_lst, _objp))
/** get next entry, which can be written to */
#define alist_nextw(_lst, _objp) \
((typeof(_objp))alist_next_ptrd(_lst, _objp))
/**
* alist_next_ptrd() - Get a pointer to the next list element
*
* This returns NULL if the requested element is beyond lst->count
*
* @lst: List to check
* @ptr: Pointer to current element (must be valid)
* Return: Pointer to next element, or NULL if @ptr is the last
*/
const void *alist_next_ptrd(const struct alist *lst, const void *ptr);
/**
* alist_chk_ptr() - Check whether a pointer is within a list
*
* Checks if the pointer points to an existing element of the list. The pointer
* must point to the start of an element, either in the list, or just outside of
* it. This function is only useful for handling for() loops
*
* Return: true if @ptr is within the list (0..count-1), else false
*/
bool alist_chk_ptr(const struct alist *lst, const void *ptr);
/**
* alist_start() - Get the start of the list (first element)
*
* Note that this will always return ->data even if it is not NULL
*
* Usage:
* const struct my_struct *obj; # 'const' is optional
*
* alist_start(&lst, struct my_struct)
*/
#define alist_start(_lst, _struct) \
((_struct *)(_lst)->data)
/**
* alist_end() - Get the end of the list (just after last element)
*
* Usage:
* const struct my_struct *obj; # 'const' is optional
*
* alist_end(&lst, struct my_struct)
*/
#define alist_end(_lst, _struct) \
((_struct *)(_lst)->data + (_lst)->count)
/**
* alist_for_each() - Iterate over an alist (with constant pointer)
*
* Use as:
* const struct my_struct *obj; # 'const' is optional
*
* alist_for_each(obj, &lst) {
* obj->...
* }
*/
#define alist_for_each(_pos, _lst) \
for (_pos = alist_start(_lst, typeof(*(_pos))); \
_pos < alist_end(_lst, typeof(*(_pos))); \
_pos++)
/**
* alist_for_each_filter() - version which sets up a 'from' pointer too
*
* This is used for filtering out information in the list. It works by iterating
* through the list, copying elements down over the top of elements to be
* deleted.
*
* In this example, 'from' iterates through the list from start to end,, 'to'
* also begins at the start, but only increments if the element at 'from' should
* be kept. This provides an O(n) filtering operation. Note that
* alist_update_end() must be called after the loop, to update the count.
*
* alist_for_each_filter(from, to, &lst) {
* if (from->val != 2)
* *to++ = *from;
* }
* alist_update_end(&lst, to);
*/
#define alist_for_each_filter(_pos, _from, _lst) \
for (_pos = _from = alist_start(_lst, typeof(*(_pos))); \
_pos < alist_end(_lst, typeof(*(_pos))); \
_pos++)
/**
* alist_update_end() - Set the element count based on a given pointer
*
* Set the given element as the final one
*/
void alist_update_end(struct alist *lst, const void *end);
/**
* alist_empty() - Empty an alist
*
* This removes all entries from the list, without changing the allocated size
*/
void alist_empty(struct alist *lst);
/**
* alist_init() - Set up a new object list
*
* Sets up a list of objects, initially empty
*
* @lst: alist to set up
* @obj_size: Size of each element in bytes
* @alloc_size: Number of items to allowed to start, before reallocation is
* needed (0 to start with no space)
* Return: true if OK, false if out of memory
*/
bool alist_init(struct alist *lst, uint obj_size, uint alloc_size);
/**
* alist_init_struct() - Typed version of alist_init()
*
* Use as:
* alist_init(&lst, struct my_struct);
*/
#define alist_init_struct(_lst, _struct) \
alist_init(_lst, sizeof(_struct), 0)
/**
* alist_uninit_move_ptr() - Return the allocated contents and uninit the alist
*
* This returns the alist data to the caller, so that the caller receives data
* that it can be sure will hang around. The caller is responsible for freeing
* the data.
*
* If the alist size is 0, this returns NULL
*
* The alist is uninited as part of this.
*
* The alist must be inited before this can be called.
*
* @alist: alist to uninit
* @countp: if non-NULL, returns the number of objects in the returned data
* (which is @alist->size)
* Return: data contents, allocated with malloc(), or NULL if the data could not
* be allocated, or the data size is 0
*/
void *alist_uninit_move_ptr(struct alist *alist, size_t *countp);
/**
* alist_uninit_move() - Typed version of alist_uninit_move_ptr()
*/
#define alist_uninit_move(_lst, _countp, _struct) \
(_struct *)alist_uninit_move_ptr(_lst, _countp)
/**
* alist_uninit() - Free any memory used by an alist
*
* The alist must be inited before this can be called.
*
* @alist: alist to uninit
*/
void alist_uninit(struct alist *alist);
#endif /* __ALIST_H */
+128
View File
@@ -0,0 +1,128 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2002
* Rich Ireland, Enterasys Networks, rireland@enterasys.com.
*/
#include <fpga.h>
#ifndef _ALTERA_H_
#define _ALTERA_H_
/*
* For the StratixV FPGA programming via SPI, the following
* information is coded in the 32bit cookie:
* Bit 31 ... Bit 0
* SPI-Bus | SPI-Dev | Config-Pin | Done-Pin
*/
#define FPGA_COOKIE(bus, dev, config, done) \
(((bus) << 24) | ((dev) << 16) | ((config) << 8) | (done))
#define COOKIE2SPI_BUS(c) (((c) >> 24) & 0xff)
#define COOKIE2SPI_DEV(c) (((c) >> 16) & 0xff)
#define COOKIE2CONFIG(c) (((c) >> 8) & 0xff)
#define COOKIE2DONE(c) ((c) & 0xff)
enum altera_iface {
/* insert all new types after this */
min_altera_iface_type,
/* serial data and external clock */
passive_serial,
/* parallel data */
passive_parallel_synchronous,
/* parallel data */
passive_parallel_asynchronous,
/* serial data w/ internal clock (not used) */
passive_serial_asynchronous,
/* jtag/tap serial (not used ) */
altera_jtag_mode,
/* fast passive parallel (FPP) */
fast_passive_parallel,
/* fast passive parallel with security (FPPS) */
fast_passive_parallel_security,
/* secure device manager (SDM) mailbox */
secure_device_manager_mailbox,
/* insert all new types before this */
max_altera_iface_type,
};
enum altera_family {
/* insert all new types after this */
min_altera_type,
/* ACEX1K Family */
Altera_ACEX1K,
/* CYCLONII Family */
Altera_CYC2,
/* StratixII Family */
Altera_StratixII,
/* StratixV Family */
Altera_StratixV,
/* SoCFPGA Family */
Altera_SoCFPGA,
/* Intel FPGA Family with SDM (Secure Device Manager) Mailbox */
Intel_FPGA_SDM_Mailbox,
/* Add new models here */
/* insert all new types before this */
max_altera_type,
};
typedef struct {
/* part type */
enum altera_family family;
/* interface type */
enum altera_iface iface;
/* bytes of data part can accept */
size_t size;
/* interface function table */
void *iface_fns;
/* base interface address */
void *base;
/* implementation specific cookie */
int cookie;
} Altera_desc;
/* Generic Altera Functions
*********************************************************************/
extern int altera_load(Altera_desc *desc, const void *image, size_t size);
extern int altera_dump(Altera_desc *desc, const void *buf, size_t bsize);
extern int altera_info(Altera_desc *desc);
/* Board specific implementation specific function types
*********************************************************************/
typedef int (*Altera_pre_fn)( int cookie );
typedef int (*Altera_config_fn)( int assert_config, int flush, int cookie );
typedef int (*Altera_status_fn)( int cookie );
typedef int (*Altera_done_fn)( int cookie );
typedef int (*Altera_clk_fn)( int assert_clk, int flush, int cookie );
typedef int (*Altera_data_fn)( int assert_data, int flush, int cookie );
typedef int(*Altera_write_fn)(const void *buf, size_t len, int flush, int cookie);
typedef int (*Altera_abort_fn)( int cookie );
typedef int (*Altera_post_fn)( int cookie );
typedef struct {
Altera_pre_fn pre;
Altera_config_fn config;
Altera_status_fn status;
Altera_done_fn done;
Altera_clk_fn clk;
Altera_data_fn data;
Altera_write_fn write;
Altera_abort_fn abort;
Altera_post_fn post;
} altera_board_specific_func;
#ifdef CONFIG_FPGA_SOCFPGA
int socfpga_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size);
#endif
#ifdef CONFIG_FPGA_STRATIX_V
int stratixv_load(Altera_desc *desc, const void *rbf_data, size_t rbf_size);
#endif
#ifdef CONFIG_FPGA_INTEL_SDM_MAILBOX
int intel_sdm_mb_load(Altera_desc *desc, const void *rbf_data,
size_t rbf_size);
#endif
#endif /* _ALTERA_H_ */
+49
View File
@@ -0,0 +1,49 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (C) 2017 The Android Open Source Project
*/
#ifndef __ANDROID_AB_H
#define __ANDROID_AB_H
#include <stdbool.h>
struct blk_desc;
struct disk_partition;
/* Android standard boot slot names are 'a', 'b', 'c', ... */
#define BOOT_SLOT_NAME(slot_num) ('a' + (slot_num))
/* Number of slots */
#define NUM_SLOTS 2
/**
* ab_select_slot() - Select the slot where to boot from.
*
* @dev_desc: Place to store the device description pointer
* @part_info: Place to store the partition information
*
* On Android devices with more than one boot slot (multiple copies of the
* kernel and system images) selects which slot should be used to boot from and
* registers the boot attempt. This is used in by the new A/B update model where
* one slot is updated in the background while running from the other slot. If
* the selected slot did not successfully boot in the past, a boot attempt is
* registered before returning from this function so it isn't selected
* indefinitely.
*
* Return: The slot number (>= 0) on success, or a negative on error
*/
int ab_select_slot(struct blk_desc *dev_desc, struct disk_partition *part_info,
bool dec_tries);
/**
* ab_dump_abc() - Dump ABC information for specific partition.
*
* @dev_desc: Device description pointer
* @part_info: Partition information
*
* Return: 0 on success, or a negative on error
*/
int ab_dump_abc(struct blk_desc *dev_desc, struct disk_partition *part_info);
#endif /* __ANDROID_AB_H */
+256
View File
@@ -0,0 +1,256 @@
/*
* This is from the Android Project,
* Repository: https://android.googlesource.com/platform/bootable/recovery
* File: bootloader_message/include/bootloader_message/bootloader_message.h
* Commit: See U-Boot commit description
*
* Copyright (C) 2008 The Android Open Source Project
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#ifndef __ANDROID_BOOTLOADER_MESSAGE_H
#define __ANDROID_BOOTLOADER_MESSAGE_H
#ifndef __UBOOT__
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#else
/* compiler.h defines the types that otherwise are included from stdint.h and
* stddef.h
*/
#include <compiler.h>
#endif
// Spaces used by misc partition are as below:
// 0 - 2K For bootloader_message
// 2K - 16K Used by Vendor's bootloader (the 2K - 4K range may be optionally used
// as bootloader_message_ab struct)
// 16K - 64K Used by uncrypt and recovery to store wipe_package for A/B devices
// Note that these offsets are admitted by bootloader,recovery and uncrypt, so they
// are not configurable without changing all of them.
static const size_t BOOTLOADER_MESSAGE_OFFSET_IN_MISC = 0;
static const size_t WIPE_PACKAGE_OFFSET_IN_MISC = 16 * 1024;
/* Bootloader Message (2-KiB)
*
* This structure describes the content of a block in flash
* that is used for recovery and the bootloader to talk to
* each other.
*
* The command field is updated by linux when it wants to
* reboot into recovery or to update radio or bootloader firmware.
* It is also updated by the bootloader when firmware update
* is complete (to boot into recovery for any final cleanup)
*
* The status field was used by the bootloader after the completion
* of an "update-radio" or "update-hboot" command, which has been
* deprecated since Froyo.
*
* The recovery field is only written by linux and used
* for the system to send a message to recovery or the
* other way around.
*
* The stage field is written by packages which restart themselves
* multiple times, so that the UI can reflect which invocation of the
* package it is. If the value is of the format "#/#" (eg, "1/3"),
* the UI will add a simple indicator of that status.
*
* We used to have slot_suffix field for A/B boot control metadata in
* this struct, which gets unintentionally cleared by recovery or
* uncrypt. Move it into struct bootloader_message_ab to avoid the
* issue.
*/
struct bootloader_message {
char command[32];
char status[32];
char recovery[768];
// The 'recovery' field used to be 1024 bytes. It has only ever
// been used to store the recovery command line, so 768 bytes
// should be plenty. We carve off the last 256 bytes to store the
// stage string (for multistage packages) and possible future
// expansion.
char stage[32];
// The 'reserved' field used to be 224 bytes when it was initially
// carved off from the 1024-byte recovery field. Bump it up to
// 1184-byte so that the entire bootloader_message struct rounds up
// to 2048-byte.
char reserved[1184];
};
/**
* We must be cautious when changing the bootloader_message struct size,
* because A/B-specific fields may end up with different offsets.
*/
#ifndef __UBOOT__
#if (__STDC_VERSION__ >= 201112L) || defined(__cplusplus)
static_assert(sizeof(struct bootloader_message) == 2048,
"struct bootloader_message size changes, which may break A/B devices");
#endif
#endif /* __UBOOT__ */
/**
* The A/B-specific bootloader message structure (4-KiB).
*
* We separate A/B boot control metadata from the regular bootloader
* message struct and keep it here. Everything that's A/B-specific
* stays after struct bootloader_message, which should be managed by
* the A/B-bootloader or boot control HAL.
*
* The slot_suffix field is used for A/B implementations where the
* bootloader does not set the androidboot.ro.boot.slot_suffix kernel
* commandline parameter. This is used by fs_mgr to mount /system and
* other partitions with the slotselect flag set in fstab. A/B
* implementations are free to use all 32 bytes and may store private
* data past the first NUL-byte in this field. It is encouraged, but
* not mandatory, to use 'struct bootloader_control' described below.
*
* The update_channel field is used to store the Omaha update channel
* if update_engine is compiled with Omaha support.
*/
struct bootloader_message_ab {
struct bootloader_message message;
char slot_suffix[32];
char update_channel[128];
// Round up the entire struct to 4096-byte.
char reserved[1888];
};
/**
* Be cautious about the struct size change, in case we put anything post
* bootloader_message_ab struct (b/29159185).
*/
#ifndef __UBOOT__
#if (__STDC_VERSION__ >= 201112L) || defined(__cplusplus)
static_assert(sizeof(struct bootloader_message_ab) == 4096,
"struct bootloader_message_ab size changes");
#endif
#endif /* __UBOOT__ */
#define BOOT_CTRL_MAGIC 0x42414342 /* Bootloader Control AB */
#define BOOT_CTRL_VERSION 1
struct slot_metadata {
// Slot priority with 15 meaning highest priority, 1 lowest
// priority and 0 the slot is unbootable.
uint8_t priority : 4;
// Number of times left attempting to boot this slot.
uint8_t tries_remaining : 3;
// 1 if this slot has booted successfully, 0 otherwise.
uint8_t successful_boot : 1;
// 1 if this slot is corrupted from a dm-verity corruption, 0
// otherwise.
uint8_t verity_corrupted : 1;
// Reserved for further use.
uint8_t reserved : 7;
} __attribute__((packed));
/* Bootloader Control AB
*
* This struct can be used to manage A/B metadata. It is designed to
* be put in the 'slot_suffix' field of the 'bootloader_message'
* structure described above. It is encouraged to use the
* 'bootloader_control' structure to store the A/B metadata, but not
* mandatory.
*/
struct bootloader_control {
// NUL terminated active slot suffix.
char slot_suffix[4];
// Bootloader Control AB magic number (see BOOT_CTRL_MAGIC).
uint32_t magic;
// Version of struct being used (see BOOT_CTRL_VERSION).
uint8_t version;
// Number of slots being managed.
uint8_t nb_slot : 3;
// Number of times left attempting to boot recovery.
uint8_t recovery_tries_remaining : 3;
// Ensure 4-bytes alignment for slot_info field.
uint8_t reserved0[2];
// Per-slot information. Up to 4 slots.
struct slot_metadata slot_info[4];
// Reserved for further use.
uint8_t reserved1[8];
// CRC32 of all 28 bytes preceding this field (little endian
// format).
uint32_t crc32_le;
} __attribute__((packed));
#ifndef __UBOOT__
#if (__STDC_VERSION__ >= 201112L) || defined(__cplusplus)
static_assert(sizeof(struct bootloader_control) ==
sizeof(((struct bootloader_message_ab *)0)->slot_suffix),
"struct bootloader_control has wrong size");
#endif
#endif /* __UBOOT__ */
#ifndef __UBOOT__
#ifdef __cplusplus
#include <string>
#include <vector>
// Return the block device name for the bootloader message partition and waits
// for the device for up to 10 seconds. In case of error returns the empty
// string.
std::string get_bootloader_message_blk_device(std::string* err);
// Read bootloader message into boot. Error message will be set in err.
bool read_bootloader_message(bootloader_message* boot, std::string* err);
// Read bootloader message from the specified misc device into boot.
bool read_bootloader_message_from(bootloader_message* boot, const std::string& misc_blk_device,
std::string* err);
// Write bootloader message to BCB.
bool write_bootloader_message(const bootloader_message& boot, std::string* err);
// Write bootloader message to the specified BCB device.
bool write_bootloader_message_to(const bootloader_message& boot,
const std::string& misc_blk_device, std::string* err);
// Write bootloader message (boots into recovery with the options) to BCB. Will
// set the command and recovery fields, and reset the rest.
bool write_bootloader_message(const std::vector<std::string>& options, std::string* err);
// Write bootloader message (boots into recovery with the options) to the specific BCB device. Will
// set the command and recovery fields, and reset the rest.
bool write_bootloader_message_to(const std::vector<std::string>& options,
const std::string& misc_blk_device, std::string* err);
// Update bootloader message (boots into recovery with the options) to BCB. Will
// only update the command and recovery fields.
bool update_bootloader_message(const std::vector<std::string>& options, std::string* err);
// Update bootloader message (boots into recovery with the |options|) in |boot|. Will only update
// the command and recovery fields.
bool update_bootloader_message_in_struct(bootloader_message* boot,
const std::vector<std::string>& options);
// Clear BCB.
bool clear_bootloader_message(std::string* err);
// Writes the reboot-bootloader reboot reason to the bootloader_message.
bool write_reboot_bootloader(std::string* err);
// Read the wipe package from BCB (from offset WIPE_PACKAGE_OFFSET_IN_MISC).
bool read_wipe_package(std::string* package_data, size_t size, std::string* err);
// Write the wipe package into BCB (to offset WIPE_PACKAGE_OFFSET_IN_MISC).
bool write_wipe_package(const std::string& package_data, std::string* err);
#else
#include <stdbool.h>
// C Interface.
bool write_bootloader_message(const char* options);
bool write_reboot_bootloader(void);
#endif // ifdef __cplusplus
#endif /* __UBOOT__ */
#endif /* __ANDROID_BOOTLOADER_MESSAGE_H */
+363
View File
@@ -0,0 +1,363 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/*
* This is from the Android Project,
* Repository: https://android.googlesource.com/platform/system/tools/mkbootimg
* File: include/bootimg/bootimg.h
* Commit: cce5b1923e3cd2fcb765b512610bdc5c42bc501d
*
* Copyright (C) 2007 The Android Open Source Project
*/
#ifndef _ANDROID_IMAGE_H_
#define _ANDROID_IMAGE_H_
#include <linux/compiler.h>
#include <linux/types.h>
#define ANDR_GKI_PAGE_SIZE 4096
#define ANDR_BOOT_MAGIC "ANDROID!"
#define ANDR_BOOT_MAGIC_SIZE 8
#define ANDR_BOOT_NAME_SIZE 16
#define ANDR_BOOT_ARGS_SIZE 512
#define ANDR_BOOT_EXTRA_ARGS_SIZE 1024
#define VENDOR_BOOT_MAGIC "VNDRBOOT"
#define ANDR_VENDOR_BOOT_V3_SIZE 2112 /* sz(andr_vnd_boot_img_hdr) - sz(vendor_ramdisk_table*) */
#define ANDR_VENDOR_BOOT_V4_SIZE 2128 /* sz(andr_vnd_boot_img_hdr) */
#define ANDR_VENDOR_BOOT_MAGIC_SIZE 8
#define ANDR_VENDOR_BOOT_ARGS_SIZE 2048
#define ANDR_VENDOR_BOOT_NAME_SIZE 16
#define BOOTCONFIG_MAGIC "#BOOTCONFIG\n"
#define BOOTCONFIG_MAGIC_SIZE 12
#define BOOTCONFIG_SIZE_SIZE 4
#define BOOTCONFIG_CHECKSUM_SIZE 4
#define BOOTCONFIG_TRAILER_SIZE BOOTCONFIG_MAGIC_SIZE + \
BOOTCONFIG_SIZE_SIZE + \
BOOTCONFIG_CHECKSUM_SIZE
struct andr_boot_img_hdr_v3 {
u8 magic[ANDR_BOOT_MAGIC_SIZE];
u32 kernel_size; /* size in bytes */
u32 ramdisk_size; /* size in bytes */
u32 os_version;
u32 header_size; /* size of boot image header in bytes */
u32 reserved[4];
u32 header_version; /* offset remains constant for version check */
u8 cmdline[ANDR_BOOT_ARGS_SIZE + ANDR_BOOT_EXTRA_ARGS_SIZE];
/* for boot image header v4 only */
u32 signature_size; /* size in bytes */
};
struct andr_vnd_boot_img_hdr {
u8 magic[ANDR_VENDOR_BOOT_MAGIC_SIZE];
u32 header_version;
u32 page_size; /* flash page size we assume */
u32 kernel_addr; /* physical load addr */
u32 ramdisk_addr; /* physical load addr */
u32 vendor_ramdisk_size; /* size in bytes */
u8 cmdline[ANDR_VENDOR_BOOT_ARGS_SIZE];
u32 tags_addr; /* physical addr for kernel tags */
u8 name[ANDR_VENDOR_BOOT_NAME_SIZE]; /* asciiz product name */
u32 header_size; /* size of vendor boot image header in bytes */
u32 dtb_size; /* size of dtb image */
u64 dtb_addr; /* physical load address */
/* for boot image header v4 only */
u32 vendor_ramdisk_table_size; /* size in bytes for the vendor ramdisk table */
u32 vendor_ramdisk_table_entry_num; /* number of entries in the vendor ramdisk table */
u32 vendor_ramdisk_table_entry_size; /* size in bytes for a vendor ramdisk table entry */
u32 bootconfig_size; /* size in bytes for the bootconfig section */
};
/* The bootloader expects the structure of andr_boot_img_hdr_v0 with header
* version 0 to be as follows: */
struct andr_boot_img_hdr_v0 {
/* Must be ANDR_BOOT_MAGIC. */
char magic[ANDR_BOOT_MAGIC_SIZE];
u32 kernel_size; /* size in bytes */
u32 kernel_addr; /* physical load addr */
u32 ramdisk_size; /* size in bytes */
u32 ramdisk_addr; /* physical load addr */
u32 second_size; /* size in bytes */
u32 second_addr; /* physical load addr */
u32 tags_addr; /* physical addr for kernel tags */
u32 page_size; /* flash page size we assume */
/* Version of the boot image header. */
u32 header_version;
/* Operating system version and security patch level.
* For version "A.B.C" and patch level "Y-M-D":
* (7 bits for each of A, B, C; 7 bits for (Y-2000), 4 bits for M)
* os_version = A[31:25] B[24:18] C[17:11] (Y-2000)[10:4] M[3:0] */
u32 os_version;
char name[ANDR_BOOT_NAME_SIZE]; /* asciiz product name */
char cmdline[ANDR_BOOT_ARGS_SIZE];
u32 id[8]; /* timestamp / checksum / sha1 / etc */
/* Supplemental command line data; kept here to maintain
* binary compatibility with older versions of mkbootimg. */
char extra_cmdline[ANDR_BOOT_EXTRA_ARGS_SIZE];
/* Fields in boot_img_hdr_v1 and newer. */
u32 recovery_dtbo_size; /* size in bytes for recovery DTBO/ACPIO image */
u64 recovery_dtbo_offset; /* offset to recovery dtbo/acpio in boot image */
u32 header_size;
/* Fields in boot_img_hdr_v2 and newer. */
u32 dtb_size; /* size in bytes for DTB image */
u64 dtb_addr; /* physical load address for DTB image */
} __attribute__((packed));
/* When a boot header is of version 0, the structure of boot image is as
* follows:
*
* +-----------------+
* | boot header | 1 page
* +-----------------+
* | kernel | n pages
* +-----------------+
* | ramdisk | m pages
* +-----------------+
* | second stage | o pages
* +-----------------+
*
* n = (kernel_size + page_size - 1) / page_size
* m = (ramdisk_size + page_size - 1) / page_size
* o = (second_size + page_size - 1) / page_size
*
* 0. all entities are page_size aligned in flash
* 1. kernel and ramdisk are required (size != 0)
* 2. second is optional (second_size == 0 -> no second)
* 3. load each element (kernel, ramdisk, second) at
* the specified physical address (kernel_addr, etc)
* 4. prepare tags at tag_addr. kernel_args[] is
* appended to the kernel commandline in the tags.
* 5. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr
* 6. if second_size != 0: jump to second_addr
* else: jump to kernel_addr
*/
/* When the boot image header has a version of 2, the structure of the boot
* image is as follows:
*
* +---------------------+
* | boot header | 1 page
* +---------------------+
* | kernel | n pages
* +---------------------+
* | ramdisk | m pages
* +---------------------+
* | second stage | o pages
* +---------------------+
* | recovery dtbo/acpio | p pages
* +---------------------+
* | dtb | q pages
* +---------------------+
*
* n = (kernel_size + page_size - 1) / page_size
* m = (ramdisk_size + page_size - 1) / page_size
* o = (second_size + page_size - 1) / page_size
* p = (recovery_dtbo_size + page_size - 1) / page_size
* q = (dtb_size + page_size - 1) / page_size
*
* 0. all entities are page_size aligned in flash
* 1. kernel, ramdisk and DTB are required (size != 0)
* 2. recovery_dtbo/recovery_acpio is required for recovery.img in non-A/B
* devices(recovery_dtbo_size != 0)
* 3. second is optional (second_size == 0 -> no second)
* 4. load each element (kernel, ramdisk, second, dtb) at
* the specified physical address (kernel_addr, etc)
* 5. If booting to recovery mode in a non-A/B device, extract recovery
* dtbo/acpio and apply the correct set of overlays on the base device tree
* depending on the hardware/product revision.
* 6. prepare tags at tag_addr. kernel_args[] is
* appended to the kernel commandline in the tags.
* 7. r0 = 0, r1 = MACHINE_TYPE, r2 = tags_addr
* 8. if second_size != 0: jump to second_addr
* else: jump to kernel_addr
*/
/* When the boot image header has a version of 3, the structure of the boot
* image is as follows:
*
* +---------------------+
* | boot header | 4096 bytes
* +---------------------+
* | kernel | m pages
* +---------------------+
* | ramdisk | n pages
* +---------------------+
*
* m = (kernel_size + 4096 - 1) / 4096
* n = (ramdisk_size + 4096 - 1) / 4096
*
* Note that in version 3 of the boot image header, page size is fixed at 4096 bytes.
*
* The structure of the vendor boot image (introduced with version 3 and
* required to be present when a v3 boot image is used) is as follows:
*
* +---------------------+
* | vendor boot header | o pages
* +---------------------+
* | vendor ramdisk | p pages
* +---------------------+
* | dtb | q pages
* +---------------------+
* o = (2112 + page_size - 1) / page_size
* p = (vendor_ramdisk_size + page_size - 1) / page_size
* q = (dtb_size + page_size - 1) / page_size
*
* 0. all entities in the boot image are 4096-byte aligned in flash, all
* entities in the vendor boot image are page_size (determined by the vendor
* and specified in the vendor boot image header) aligned in flash
* 1. kernel, ramdisk, vendor ramdisk, and DTB are required (size != 0)
* 2. load the kernel and DTB at the specified physical address (kernel_addr,
* dtb_addr)
* 3. load the vendor ramdisk at ramdisk_addr
* 4. load the generic ramdisk immediately following the vendor ramdisk in
* memory
* 5. set up registers for kernel entry as required by your architecture
* 6. if the platform has a second stage bootloader jump to it (must be
* contained outside boot and vendor boot partitions), otherwise
* jump to kernel_addr
*/
/* When the boot image header has a version of 4, the structure of the boot
* image is as follows:
*
* +---------------------+
* | boot header | 4096 bytes
* +---------------------+
* | kernel | m pages
* +---------------------+
* | ramdisk | n pages
* +---------------------+
* | boot signature | g pages
* +---------------------+
*
* m = (kernel_size + 4096 - 1) / 4096
* n = (ramdisk_size + 4096 - 1) / 4096
* g = (signature_size + 4096 - 1) / 4096
*
* Note that in version 4 of the boot image header, page size is fixed at 4096
* bytes.
*
* The structure of the vendor boot image version 4, which is required to be
* present when a version 4 boot image is used, is as follows:
*
* +------------------------+
* | vendor boot header | o pages
* +------------------------+
* | vendor ramdisk section | p pages
* +------------------------+
* | dtb | q pages
* +------------------------+
* | vendor ramdisk table | r pages
* +------------------------+
* | bootconfig | s pages
* +------------------------+
*
* o = (2128 + page_size - 1) / page_size
* p = (vendor_ramdisk_size + page_size - 1) / page_size
* q = (dtb_size + page_size - 1) / page_size
* r = (vendor_ramdisk_table_size + page_size - 1) / page_size
* s = (vendor_bootconfig_size + page_size - 1) / page_size
*
* Note that in version 4 of the vendor boot image, multiple vendor ramdisks can
* be included in the vendor boot image. The bootloader can select a subset of
* ramdisks to load at runtime. To help the bootloader select the ramdisks, each
* ramdisk is tagged with a type tag and a set of hardware identifiers
* describing the board, soc or platform that this ramdisk is intended for.
*
* The vendor ramdisk section is consist of multiple ramdisk images concatenated
* one after another, and vendor_ramdisk_size is the size of the section, which
* is the total size of all the ramdisks included in the vendor boot image.
*
* The vendor ramdisk table holds the size, offset, type, name and hardware
* identifiers of each ramdisk. The type field denotes the type of its content.
* The vendor ramdisk names are unique. The hardware identifiers are specified
* in the board_id field in each table entry. The board_id field is consist of a
* vector of unsigned integer words, and the encoding scheme is defined by the
* hardware vendor.
*
* For the different type of ramdisks, there are:
* - VENDOR_RAMDISK_TYPE_NONE indicates the value is unspecified.
* - VENDOR_RAMDISK_TYPE_PLATFORM ramdisks contain platform specific bits, so
* the bootloader should always load these into memory.
* - VENDOR_RAMDISK_TYPE_RECOVERY ramdisks contain recovery resources, so
* the bootloader should load these when booting into recovery.
* - VENDOR_RAMDISK_TYPE_DLKM ramdisks contain dynamic loadable kernel
* modules.
*
* Version 4 of the vendor boot image also adds a bootconfig section to the end
* of the image. This section contains Boot Configuration parameters known at
* build time. The bootloader is responsible for placing this section directly
* after the generic ramdisk, followed by the bootconfig trailer, before
* entering the kernel.
*
* 0. all entities in the boot image are 4096-byte aligned in flash, all
* entities in the vendor boot image are page_size (determined by the vendor
* and specified in the vendor boot image header) aligned in flash
* 1. kernel, ramdisk, and DTB are required (size != 0)
* 2. load the kernel and DTB at the specified physical address (kernel_addr,
* dtb_addr)
* 3. load the vendor ramdisks at ramdisk_addr
* 4. load the generic ramdisk immediately following the vendor ramdisk in
* memory
* 5. load the bootconfig immediately following the generic ramdisk. Add
* additional bootconfig parameters followed by the bootconfig trailer.
* 6. set up registers for kernel entry as required by your architecture
* 7. if the platform has a second stage bootloader jump to it (must be
* contained outside boot and vendor boot partitions), otherwise
* jump to kernel_addr
*/
/* Private struct */
struct andr_image_data {
ulong kernel_ptr; /* kernel address */
u32 kernel_size; /* size in bytes */
u32 ramdisk_size; /* size in bytes */
ulong vendor_ramdisk_ptr; /* vendor ramdisk address */
u32 vendor_ramdisk_size; /* vendor ramdisk size*/
u32 boot_ramdisk_size; /* size in bytes */
ulong second_ptr; /* secondary bootloader address */
u32 second_size; /* secondary bootloader size */
ulong dtb_ptr; /* address of dtb image */
u32 dtb_size; /* size of dtb image */
ulong recovery_dtbo_ptr; /* size in bytes for recovery DTBO/ACPIO image */
u32 recovery_dtbo_size; /* offset to recovery dtbo/acpio in boot image */
const char *kcmdline; /* boot kernel cmdline */
const char *kcmdline_extra; /* vendor-boot extra kernel cmdline */
const char *image_name; /* asciiz product name */
ulong bootconfig_addr; /* bootconfig image address */
ulong bootconfig_size; /* bootconfig image size */
ulong kernel_addr; /* physical load addr */
ulong ramdisk_addr; /* physical load addr */
ulong ramdisk_ptr; /* ramdisk address */
ulong dtb_load_addr; /* physical load address for DTB image */
ulong tags_addr; /* physical addr for kernel tags */
u32 header_version; /* version of the boot image header */
u32 boot_img_total_size; /* boot image size */
u32 vendor_boot_img_total_size; /* vendor boot image size */
};
#endif
+25
View File
@@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2012
* Pali Rohár <pali@kernel.org>
*/
/*
* ANSI terminal
*/
#define ANSI_CURSOR_UP "\e[%dA"
#define ANSI_CURSOR_DOWN "\e[%dB"
#define ANSI_CURSOR_FORWARD "\e[%dC"
#define ANSI_CURSOR_BACK "\e[%dD"
#define ANSI_CURSOR_NEXTLINE "\e[%dE"
#define ANSI_CURSOR_PREVIOUSLINE "\e[%dF"
#define ANSI_CURSOR_COLUMN "\e[%dG"
#define ANSI_CURSOR_POSITION "\e[%d;%dH"
#define ANSI_CURSOR_SHOW "\e[?25h"
#define ANSI_CURSOR_HIDE "\e[?25l"
#define ANSI_CLEAR_CONSOLE "\e[2J"
#define ANSI_CLEAR_LINE_TO_END "\e[0K"
#define ANSI_CLEAR_LINE "\e[2K"
#define ANSI_COLOR_RESET "\e[0m"
#define ANSI_COLOR_REVERSE "\e[7m"
+20
View File
@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2017 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*/
#ifndef __API_H
#define __API_H
/**
* api_init() - Initialize API for external applications
*
* Initialize API for external (standalone) applications running on top of
* U-Boot. It is called during the generic post-relocation init sequence.
*
* Return: 0 if OK
*/
int api_init(void);
#endif
+142
View File
@@ -0,0 +1,142 @@
/* SPDX-License-Identifier: GPL-2.0+ OR BSD-2-Clause */
/*
* (C) Copyright 2007-2008 Semihalf
*
* Written by: Rafal Jaworowski <raj@semihalf.com>
*/
#ifndef _API_PUBLIC_H_
#define _API_PUBLIC_H_
#include <linux/types.h>
#define API_EINVAL 1 /* invalid argument(s) */
#define API_ENODEV 2 /* no device */
#define API_ENOMEM 3 /* no memory */
#define API_EBUSY 4 /* busy, occupied etc. */
#define API_EIO 5 /* I/O error */
#define API_ESYSC 6 /* syscall error */
typedef int (*scp_t)(int, int *, ...);
#define API_SIG_VERSION 1
#define API_SIG_MAGIC "UBootAPI"
#define API_SIG_MAGLEN 8
struct api_signature {
char magic[API_SIG_MAGLEN]; /* magic string */
uint16_t version; /* API version */
uint32_t checksum; /* checksum of this sig struct */
scp_t syscall; /* entry point to the API */
};
enum {
API_RSVD = 0,
API_GETC,
API_PUTC,
API_TSTC,
API_PUTS,
API_RESET,
API_GET_SYS_INFO,
API_UDELAY,
API_GET_TIMER,
API_DEV_ENUM,
API_DEV_OPEN,
API_DEV_CLOSE,
API_DEV_READ,
API_DEV_WRITE,
API_ENV_ENUM,
API_ENV_GET,
API_ENV_SET,
API_DISPLAY_GET_INFO,
API_DISPLAY_DRAW_BITMAP,
API_DISPLAY_CLEAR,
API_MAXCALL
};
#define MR_ATTR_FLASH 0x0001
#define MR_ATTR_DRAM 0x0002
#define MR_ATTR_SRAM 0x0003
struct mem_region {
unsigned long start;
unsigned long size;
int flags;
};
struct sys_info {
unsigned long clk_bus;
unsigned long clk_cpu;
unsigned long bar;
struct mem_region *mr;
int mr_no; /* number of memory regions */
};
/*
* FIXME: Previously this code was:
*
* #undef CONFIG_SYS_64BIT_LBA
* #ifdef CONFIG_SYS_64BIT_LBA
* typedef u_int64_t lbasize_t;
* #else
* typedef unsigned long lbasize_t;
* #endif
*
* But we cannot just undefine CONFIG_SYS_64BIT_LBA, because then in
* api/api_storage.c the type signature of lbaint_t will be different if
* CONFIG_SYS_64BIT_LBA is enabled for the board, which can result in various
* bugs.
* So simply define lbasize_t as an unsigned long, since this was what was done
* anyway for at least 13 years, but don't undefine CONFIG_SYS_64BIT_LBA.
*/
typedef unsigned long lbasize_t;
typedef unsigned long lbastart_t;
#define DEV_TYP_NONE 0x0000
#define DEV_TYP_NET 0x0001
#define DEV_TYP_STOR 0x0002
#define DT_STOR_IDE 0x0010
#define DT_STOR_SCSI 0x0020
#define DT_STOR_USB 0x0040
#define DT_STOR_MMC 0x0080
#define DT_STOR_SATA 0x0100
#define DEV_STA_CLOSED 0x0000 /* invalid, closed */
#define DEV_STA_OPEN 0x0001 /* open i.e. active */
struct device_info {
int type;
void *cookie;
union {
struct {
lbasize_t block_count; /* no of blocks */
unsigned long block_size; /* size of one block */
} storage;
struct {
unsigned char hwaddr[6];
} net;
} info;
#define di_stor info.storage
#define di_net info.net
int state;
};
#define DISPLAY_TYPE_LCD 0x0001
#define DISPLAY_TYPE_VIDEO 0x0002
struct display_info {
int type;
/* screen size in pixels */
int pixel_width;
int pixel_height;
/* screen size in rows and columns of text */
int screen_rows;
int screen_cols;
};
#endif /* _API_PUBLIC_H_ */
+213
View File
@@ -0,0 +1,213 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
*
* Authors:
* Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
*/
#ifndef __ARM_FFA_H
#define __ARM_FFA_H
#include <linux/types.h>
/*
* This header is public. It can be used by clients to access
* data structures and definitions they need
*/
/*
* struct ffa_partition_info - Partition information descriptor
* @id: Partition ID
* @exec_ctxt: Execution context count
* @properties: Partition properties
*
* Data structure containing information about partitions instantiated in the system
* This structure is filled with the data queried by FFA_PARTITION_INFO_GET
*/
struct ffa_partition_info {
u16 id;
u16 exec_ctxt;
/* partition supports receipt of direct requests */
#define FFA_PARTITION_DIRECT_RECV BIT(0)
/* partition can send direct requests. */
#define FFA_PARTITION_DIRECT_SEND BIT(1)
/* partition can send and receive indirect messages. */
#define FFA_PARTITION_INDIRECT_MSG BIT(2)
u32 properties;
};
/*
* struct ffa_partition_uuid - 16 bytes UUID transmitted by FFA_PARTITION_INFO_GET
* @a1-4: 32-bit words access to the UUID data
*
*/
struct ffa_partition_uuid {
u32 a1; /* w1 */
u32 a2; /* w2 */
u32 a3; /* w3 */
u32 a4; /* w4 */
};
/**
* struct ffa_partition_desc - the secure partition descriptor
* @info: partition information
* @sp_uuid: the secure partition UUID
*
* Each partition has its descriptor containing the partitions information and the UUID
*/
struct ffa_partition_desc {
struct ffa_partition_info info;
struct ffa_partition_uuid sp_uuid;
};
/*
* struct ffa_send_direct_data - Data structure hosting the data
* used by FFA_MSG_SEND_DIRECT_{REQ,RESP}
* @data0-4: Data read/written from/to x3-x7 registers
*
* Data structure containing the data to be sent by FFA_MSG_SEND_DIRECT_REQ
* or read from FFA_MSG_SEND_DIRECT_RESP
*/
/* For use with FFA_MSG_SEND_DIRECT_{REQ,RESP} which pass data via registers */
struct ffa_send_direct_data {
ulong data0; /* w3/x3 */
ulong data1; /* w4/x4 */
ulong data2; /* w5/x5 */
ulong data3; /* w6/x6 */
ulong data4; /* w7/x7 */
};
struct udevice;
/**
* struct ffa_bus_ops - Operations for FF-A
* @partition_info_get: callback for the FFA_PARTITION_INFO_GET
* @sync_send_receive: callback for the FFA_MSG_SEND_DIRECT_REQ
* @rxtx_unmap: callback for the FFA_RXTX_UNMAP
*
* The data structure providing all the operations supported by the driver.
* This structure is EFI runtime resident.
*/
struct ffa_bus_ops {
int (*partition_info_get)(struct udevice *dev, const char *uuid_str,
u32 *sp_count, struct ffa_partition_desc **sp_descs);
int (*sync_send_receive)(struct udevice *dev, u16 dst_part_id,
struct ffa_send_direct_data *msg,
bool is_smc64);
int (*rxtx_unmap)(struct udevice *dev);
};
#define ffa_get_ops(dev) ((struct ffa_bus_ops *)(dev)->driver->ops)
/**
* ffa_rxtx_unmap() - FFA_RXTX_UNMAP driver operation
* Please see ffa_unmap_rxtx_buffers_hdlr() description for more details.
*/
int ffa_rxtx_unmap(struct udevice *dev);
/**
* ffa_unmap_rxtx_buffers_hdlr() - FFA_RXTX_UNMAP handler function
* @dev: The arm_ffa bus device
*
* This function implements FFA_RXTX_UNMAP FF-A function
* to unmap the RX/TX buffers
*
* Return:
*
* 0 on success. Otherwise, failure
*/
int ffa_unmap_rxtx_buffers_hdlr(struct udevice *dev);
/**
* ffa_sync_send_receive() - FFA_MSG_SEND_DIRECT_{REQ,RESP} driver operation
* Please see ffa_msg_send_direct_req_hdlr() description for more details.
*/
int ffa_sync_send_receive(struct udevice *dev, u16 dst_part_id,
struct ffa_send_direct_data *msg, bool is_smc64);
/**
* ffa_msg_send_direct_req_hdlr() - FFA_MSG_SEND_DIRECT_{REQ,RESP} handler function
* @dev: The arm_ffa bus device
* @dst_part_id: destination partition ID
* @msg: pointer to the message data preallocated by the client (in/out)
* @is_smc64: select 64-bit or 32-bit FF-A ABI
*
* This function implements FFA_MSG_SEND_DIRECT_{REQ,RESP}
* FF-A functions.
*
* FFA_MSG_SEND_DIRECT_REQ is used to send the data to the secure partition.
* The response from the secure partition is handled by reading the
* FFA_MSG_SEND_DIRECT_RESP arguments.
*
* The maximum size of the data that can be exchanged is 40 bytes which is
* sizeof(struct ffa_send_direct_data) as defined by the FF-A specification 1.0
* in the section relevant to FFA_MSG_SEND_DIRECT_{REQ,RESP}
*
* Return:
*
* 0 on success. Otherwise, failure
*/
int ffa_msg_send_direct_req_hdlr(struct udevice *dev, u16 dst_part_id,
struct ffa_send_direct_data *msg, bool is_smc64);
/**
* ffa_partition_info_get() - FFA_PARTITION_INFO_GET driver operation
* Please see ffa_get_partitions_info_hdlr() description for more details.
*/
int ffa_partition_info_get(struct udevice *dev, const char *uuid_str,
u32 *sp_count, struct ffa_partition_desc **sp_descs);
/**
* ffa_get_partitions_info_hdlr() - FFA_PARTITION_INFO_GET handler function
* @uuid_str: pointer to the UUID string
* @sp_count: address of the variable containing the number of partitions matching the UUID
* The variable is set by the driver
* @sp_descs: address of the descriptors of the partitions matching the UUID
* The address is set by the driver
*
* Return the number of partitions and their descriptors matching the UUID
*
* Query the secure partition data from uc_priv.
* If not found, invoke FFA_PARTITION_INFO_GET
* FF-A function to query the partition information from secure world.
*
* A client of the FF-A driver should know the UUID of the service it wants to
* access. It should use the UUID to request the FF-A driver to provide the
* partition(s) information of the service. The FF-A driver uses
* PARTITION_INFO_GET to obtain this information. This is implemented through
* ffa_get_partitions_info_hdlr() function.
* A new FFA_PARTITION_INFO_GET call is issued (first one performed through
* ffa_cache_partitions_info) allowing to retrieve the partition(s) information.
* They are not saved (already done). We only update the UUID in the cached area.
* This assumes that partitions data does not change in the secure world.
* Otherwise u-boot will have an outdated partition data. The benefit of caching
* the information in the FF-A driver is to accommodate discovery after
* ExitBootServices().
*
* Return:
*
* @sp_count: the number of partitions
* @sp_descs: address of the partitions descriptors
*
* On success 0 is returned. Otherwise, failure
*/
int ffa_get_partitions_info_hdlr(struct udevice *dev, const char *uuid_str,
u32 *sp_count, struct ffa_partition_desc **sp_descs);
struct ffa_priv;
/**
* ffa_set_smc_conduit() - Set the SMC conduit
* @dev: The FF-A bus device
*
* Selects the SMC conduit by setting the FF-A ABI invoke function.
*
* Return:
*
* 0 on success. Otherwise, failure
*/
int ffa_set_smc_conduit(struct udevice *dev);
#endif
+246
View File
@@ -0,0 +1,246 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2022-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
*
* Authors:
* Abdellatif El Khlifi <abdellatif.elkhlifi@arm.com>
*/
#ifndef __ARM_FFA_PRV_H
#define __ARM_FFA_PRV_H
#include <mapmem.h>
#include <linux/bitfield.h>
#include <linux/bitops.h>
/* This header is exclusively used by the FF-A Uclass and FF-A driver(s) */
/* Arm FF-A driver name */
#define FFA_DRV_NAME "arm_ffa"
/* The FF-A SMC function definitions */
#if CONFIG_IS_ENABLED(SANDBOX)
/* Providing Arm SMCCC declarations to sandbox */
/**
* struct sandbox_smccc_1_2_regs - emulated SMC call arguments or results
* @a0-a17 argument values from registers 0 to 17
*/
struct sandbox_smccc_1_2_regs {
ulong a0;
ulong a1;
ulong a2;
ulong a3;
ulong a4;
ulong a5;
ulong a6;
ulong a7;
ulong a8;
ulong a9;
ulong a10;
ulong a11;
ulong a12;
ulong a13;
ulong a14;
ulong a15;
ulong a16;
ulong a17;
};
typedef struct sandbox_smccc_1_2_regs ffa_value_t;
#define ARM_SMCCC_FAST_CALL 1UL
#define ARM_SMCCC_OWNER_STANDARD 4
#define ARM_SMCCC_SMC_32 0
#define ARM_SMCCC_SMC_64 1
#define ARM_SMCCC_TYPE_SHIFT 31
#define ARM_SMCCC_CALL_CONV_SHIFT 30
#define ARM_SMCCC_OWNER_MASK 0x3f
#define ARM_SMCCC_OWNER_SHIFT 24
#define ARM_SMCCC_FUNC_MASK 0xffff
#define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \
(((type) << ARM_SMCCC_TYPE_SHIFT) | \
((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \
(((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \
((func_num) & ARM_SMCCC_FUNC_MASK))
#else
/* CONFIG_ARM64 */
#include <linux/arm-smccc.h>
typedef struct arm_smccc_1_2_regs ffa_value_t;
#endif
/* Defining the function pointer type for the function executing the FF-A ABIs */
typedef void (*invoke_ffa_fn_t)(ffa_value_t args, ffa_value_t *res);
/* FF-A driver version definitions */
#define MAJOR_VERSION_MASK GENMASK(30, 16)
#define MINOR_VERSION_MASK GENMASK(15, 0)
#define GET_FFA_MAJOR_VERSION(x) \
((u16)(FIELD_GET(MAJOR_VERSION_MASK, (x))))
#define GET_FFA_MINOR_VERSION(x) \
((u16)(FIELD_GET(MINOR_VERSION_MASK, (x))))
#define PACK_VERSION_INFO(major, minor) \
(FIELD_PREP(MAJOR_VERSION_MASK, (major)) | \
FIELD_PREP(MINOR_VERSION_MASK, (minor)))
#define FFA_MAJOR_VERSION (1)
#define FFA_MINOR_VERSION (0)
#define FFA_VERSION_1_0 \
PACK_VERSION_INFO(FFA_MAJOR_VERSION, FFA_MINOR_VERSION)
/* Endpoint ID mask (u-boot endpoint ID) */
#define GET_SELF_ENDPOINT_ID_MASK GENMASK(15, 0)
#define GET_SELF_ENDPOINT_ID(x) \
((u16)(FIELD_GET(GET_SELF_ENDPOINT_ID_MASK, (x))))
#define PREP_SELF_ENDPOINT_ID_MASK GENMASK(31, 16)
#define PREP_SELF_ENDPOINT_ID(x) \
(FIELD_PREP(PREP_SELF_ENDPOINT_ID_MASK, (x)))
/* Partition endpoint ID mask (partition with which u-boot communicates with) */
#define PREP_PART_ENDPOINT_ID_MASK GENMASK(15, 0)
#define PREP_PART_ENDPOINT_ID(x) \
(FIELD_PREP(PREP_PART_ENDPOINT_ID_MASK, (x)))
/* Definitions of the Arm FF-A interfaces supported by the Arm FF-A driver */
#define FFA_SMC(calling_convention, func_num) \
ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, (calling_convention), \
ARM_SMCCC_OWNER_STANDARD, (func_num))
#define FFA_SMC_32(func_num) FFA_SMC(ARM_SMCCC_SMC_32, (func_num))
#define FFA_SMC_64(func_num) FFA_SMC(ARM_SMCCC_SMC_64, (func_num))
enum ffa_abis {
FFA_ERROR = 0x60,
FFA_SUCCESS = 0x61,
FFA_INTERRUPT = 0x62,
FFA_VERSION = 0x63,
FFA_FEATURES = 0x64,
FFA_RX_RELEASE = 0x65,
FFA_RXTX_MAP = 0x66,
FFA_RXTX_UNMAP = 0x67,
FFA_PARTITION_INFO_GET = 0x68,
FFA_ID_GET = 0x69,
FFA_RUN = 0x6d,
FFA_MSG_SEND_DIRECT_REQ = 0x6f,
FFA_MSG_SEND_DIRECT_RESP = 0x70,
/* To be updated when adding new FFA IDs */
FFA_FIRST_ID = FFA_ERROR, /* Lowest number ID */
FFA_LAST_ID = FFA_MSG_SEND_DIRECT_RESP, /* Highest number ID */
};
enum ffa_abi_errcode {
NOT_SUPPORTED = 1,
INVALID_PARAMETERS,
NO_MEMORY,
BUSY,
INTERRUPTED,
DENIED,
RETRY,
ABORTED,
MAX_NUMBER_FFA_ERR
};
extern int ffa_to_std_errmap[MAX_NUMBER_FFA_ERR];
/* Container structure and helper macros to map between an FF-A error and relevant error log */
struct ffa_abi_errmap {
char *err_str[MAX_NUMBER_FFA_ERR];
};
#define FFA_ERRMAP_COUNT (FFA_LAST_ID - FFA_FIRST_ID + 1)
#define FFA_ID_TO_ERRMAP_ID(ffa_id) ((ffa_id) - FFA_FIRST_ID)
/**
* enum ffa_rxtx_buf_sizes - minimum sizes supported
* for the RX/TX buffers
*/
enum ffa_rxtx_buf_sizes {
RXTX_4K,
RXTX_64K,
RXTX_16K
};
/**
* struct ffa_rxtxpair - Hosts the RX/TX buffers virtual addresses
* @rxbuf: virtual address of the RX buffer
* @txbuf: virtual address of the TX buffer
* @rxtx_min_pages: RX/TX buffers minimum size in pages
*
* Hosts the virtual addresses of the mapped RX/TX buffers
* These addresses are used by the FF-A functions that use the RX/TX buffers
*/
struct ffa_rxtxpair {
void *rxbuf; /* Virtual address returned by memalign */
void *txbuf; /* Virtual address returned by memalign */
size_t rxtx_min_pages; /* Minimum number of pages in each of the RX/TX buffers */
};
struct ffa_partition_desc;
/**
* struct ffa_partitions - descriptors for all secure partitions
* @count: The number of partitions descriptors
* @descs The partitions descriptors table
*
* Contains the partitions descriptors table
*/
struct ffa_partitions {
u32 count;
struct ffa_partition_desc *descs; /* Virtual address */
};
/**
* struct ffa_priv - the driver private data structure
*
* @fwk_version: FF-A framework version
* @emul: FF-A sandbox emulator
* @id: u-boot endpoint ID
* @partitions: The partitions descriptors structure
* @pair: The RX/TX buffers pair
*
* The device private data structure containing all the
* data read from secure world.
*/
struct ffa_priv {
u32 fwk_version;
struct udevice *emul;
u16 id;
struct ffa_partitions partitions;
struct ffa_rxtxpair pair;
};
/**
* ffa_get_version_hdlr() - FFA_VERSION handler function
* @dev: The FF-A bus device
*
* Implement FFA_VERSION FF-A function
* to get from the secure world the FF-A framework version
* FFA_VERSION is used to discover the FF-A framework.
*
* Return:
*
* 0 on success. Otherwise, failure
*/
int ffa_get_version_hdlr(struct udevice *dev);
/**
* invoke_ffa_fn() - SMC wrapper
* @args: FF-A ABI arguments to be copied to Xn registers
* @res: FF-A ABI return data to be copied from Xn registers
*
* Calls low level SMC implementation.
* This function should be implemented by the user driver.
*/
void invoke_ffa_fn(ffa_value_t args, ffa_value_t *res);
#endif
+39
View File
@@ -0,0 +1,39 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2005
* ARM Ltd.
* Peter Pearse, <Peter.Pearse@arm.com>
* Configuration for ARM Core Modules.
* No standalonw port yet available
* - this file is included by both integratorap.h & integratorcp.h
*/
#ifndef __ARMCOREMODULE_H
#define __ARMCOREMODULE_H
#define CM_BASE 0x10000000
/* CM registers common to all CMs */
/* Note that observed values after reboot into the ARM Boot Monitor
have been used as defaults, rather than the POR values */
#define OS_CTRL 0x0000000C
#define CMMASK_REMAP 0x00000005 /* set remap & led */
#define CMMASK_RESET 0x00000008
#define OS_LOCK 0x00000014
#define CMVAL_LOCK1 0x0000A000 /* locking value */
#define CMVAL_LOCK2 0x0000005F /* locking value */
#define CMVAL_UNLOCK 0x00000000 /* any value != CM_LOCKVAL */
#define OS_SDRAM 0x00000020
#define OS_INIT 0x00000024
#define CMMASK_MAP_SIMPLE 0xFFFDFFFF /* simple mapping */
#define CMMASK_TCRAM_DISABLE 0xFFFEFFFF /* TCRAM disabled */
#define CMMASK_LOWVEC 0x00000000 /* vectors @ 0x00000000 */
#define CMMASK_LE 0xFFFFFFF7 /* little endian */
#define CMMASK_CMxx6_COMMON 0x00000013 /* Common value for CMxx6 */
/* - observed reset value of */
/* CM926EJ-S */
/* CM1136-EJ-S */
#define OS_SPD 0x00000100 /* The SDRAM SPD data is copied here */
#endif /* __ARMCOREMODULE_H */
+262
View File
@@ -0,0 +1,262 @@
#ifndef _ASM_GENERIC_ATOMIC_LONG_H
#define _ASM_GENERIC_ATOMIC_LONG_H
/*
* Copyright (C) 2005 Silicon Graphics, Inc.
* Christoph Lameter
*
* Allows to provide arch independent atomic definitions without the need to
* edit all arch specific atomic.h files.
*/
#include <asm/types.h>
/*
* Suppport for atomic_long_t
*
* Casts for parameters are avoided for existing atomic functions in order to
* avoid issues with cast-as-lval under gcc 4.x and other limitations that the
* macros of a platform may have.
*/
#if BITS_PER_LONG == 64
typedef atomic64_t atomic_long_t;
#define ATOMIC_LONG_INIT(i) ATOMIC64_INIT(i)
static inline long atomic_long_read(atomic_long_t *l)
{
atomic64_t *v = (atomic64_t *)l;
return (long)atomic64_read(v);
}
static inline void atomic_long_set(atomic_long_t *l, long i)
{
atomic64_t *v = (atomic64_t *)l;
atomic64_set(v, i);
}
static inline void atomic_long_inc(atomic_long_t *l)
{
atomic64_t *v = (atomic64_t *)l;
atomic64_inc(v);
}
static inline void atomic_long_dec(atomic_long_t *l)
{
atomic64_t *v = (atomic64_t *)l;
atomic64_dec(v);
}
static inline void atomic_long_add(long i, atomic_long_t *l)
{
atomic64_t *v = (atomic64_t *)l;
atomic64_add(i, v);
}
static inline void atomic_long_sub(long i, atomic_long_t *l)
{
atomic64_t *v = (atomic64_t *)l;
atomic64_sub(i, v);
}
#ifndef __UBOOT__
static inline int atomic_long_sub_and_test(long i, atomic_long_t *l)
{
atomic64_t *v = (atomic64_t *)l;
return atomic64_sub_and_test(i, v);
}
static inline int atomic_long_dec_and_test(atomic_long_t *l)
{
atomic64_t *v = (atomic64_t *)l;
return atomic64_dec_and_test(v);
}
static inline int atomic_long_inc_and_test(atomic_long_t *l)
{
atomic64_t *v = (atomic64_t *)l;
return atomic64_inc_and_test(v);
}
static inline int atomic_long_add_negative(long i, atomic_long_t *l)
{
atomic64_t *v = (atomic64_t *)l;
return atomic64_add_negative(i, v);
}
static inline long atomic_long_add_return(long i, atomic_long_t *l)
{
atomic64_t *v = (atomic64_t *)l;
return (long)atomic64_add_return(i, v);
}
static inline long atomic_long_sub_return(long i, atomic_long_t *l)
{
atomic64_t *v = (atomic64_t *)l;
return (long)atomic64_sub_return(i, v);
}
static inline long atomic_long_inc_return(atomic_long_t *l)
{
atomic64_t *v = (atomic64_t *)l;
return (long)atomic64_inc_return(v);
}
static inline long atomic_long_dec_return(atomic_long_t *l)
{
atomic64_t *v = (atomic64_t *)l;
return (long)atomic64_dec_return(v);
}
static inline long atomic_long_add_unless(atomic_long_t *l, long a, long u)
{
atomic64_t *v = (atomic64_t *)l;
return (long)atomic64_add_unless(v, a, u);
}
#define atomic_long_inc_not_zero(l) atomic64_inc_not_zero((atomic64_t *)(l))
#define atomic_long_cmpxchg(l, old, new) \
(atomic64_cmpxchg((atomic64_t *)(l), (old), (new)))
#define atomic_long_xchg(v, new) \
(atomic64_xchg((atomic64_t *)(v), (new)))
#endif /* __UBOOT__ */
#else /* BITS_PER_LONG == 64 */
typedef atomic_t atomic_long_t;
#define ATOMIC_LONG_INIT(i) ATOMIC_INIT(i)
static inline long atomic_long_read(atomic_long_t *l)
{
atomic_t *v = (atomic_t *)l;
return (long)atomic_read(v);
}
static inline void atomic_long_set(atomic_long_t *l, long i)
{
atomic_t *v = (atomic_t *)l;
atomic_set(v, i);
}
static inline void atomic_long_inc(atomic_long_t *l)
{
atomic_t *v = (atomic_t *)l;
atomic_inc(v);
}
static inline void atomic_long_dec(atomic_long_t *l)
{
atomic_t *v = (atomic_t *)l;
atomic_dec(v);
}
static inline void atomic_long_add(long i, atomic_long_t *l)
{
atomic_t *v = (atomic_t *)l;
atomic_add(i, v);
}
static inline void atomic_long_sub(long i, atomic_long_t *l)
{
atomic_t *v = (atomic_t *)l;
atomic_sub(i, v);
}
#ifndef __UBOOT__
static inline int atomic_long_sub_and_test(long i, atomic_long_t *l)
{
atomic_t *v = (atomic_t *)l;
return atomic_sub_and_test(i, v);
}
static inline int atomic_long_dec_and_test(atomic_long_t *l)
{
atomic_t *v = (atomic_t *)l;
return atomic_dec_and_test(v);
}
static inline int atomic_long_inc_and_test(atomic_long_t *l)
{
atomic_t *v = (atomic_t *)l;
return atomic_inc_and_test(v);
}
static inline int atomic_long_add_negative(long i, atomic_long_t *l)
{
atomic_t *v = (atomic_t *)l;
return atomic_add_negative(i, v);
}
static inline long atomic_long_add_return(long i, atomic_long_t *l)
{
atomic_t *v = (atomic_t *)l;
return (long)atomic_add_return(i, v);
}
static inline long atomic_long_sub_return(long i, atomic_long_t *l)
{
atomic_t *v = (atomic_t *)l;
return (long)atomic_sub_return(i, v);
}
static inline long atomic_long_inc_return(atomic_long_t *l)
{
atomic_t *v = (atomic_t *)l;
return (long)atomic_inc_return(v);
}
static inline long atomic_long_dec_return(atomic_long_t *l)
{
atomic_t *v = (atomic_t *)l;
return (long)atomic_dec_return(v);
}
static inline long atomic_long_add_unless(atomic_long_t *l, long a, long u)
{
atomic_t *v = (atomic_t *)l;
return (long)atomic_add_unless(v, a, u);
}
#define atomic_long_inc_not_zero(l) atomic_inc_not_zero((atomic_t *)(l))
#define atomic_long_cmpxchg(l, old, new) \
(atomic_cmpxchg((atomic_t *)(l), (old), (new)))
#define atomic_long_xchg(v, new) \
(atomic_xchg((atomic_t *)(v), (new)))
#endif /* __UBOOT__ */
#endif /* BITS_PER_LONG == 64 */
#endif /* _ASM_GENERIC_ATOMIC_LONG_H */
+150
View File
@@ -0,0 +1,150 @@
/* SPDX-License-Identifier: GPL-2.0+ */
#ifndef _ASM_GENERIC_ATOMIC_H
#define _ASM_GENERIC_ATOMIC_H
typedef struct { volatile int counter; } atomic_t;
#if BITS_PER_LONG == 32
typedef struct { volatile long long counter; } atomic64_t;
#else /* BIT_PER_LONG == 32 */
typedef struct { volatile long counter; } atomic64_t;
#endif
#define ATOMIC_INIT(i) { (i) }
#define atomic_read(v) ((v)->counter)
#define atomic_set(v, i) ((v)->counter = (i))
#define atomic64_read(v) atomic_read(v)
#define atomic64_set(v, i) atomic_set(v, i)
static inline void atomic_add(int i, atomic_t *v)
{
unsigned long flags = 0;
local_irq_save(flags);
v->counter += i;
local_irq_restore(flags);
}
static inline void atomic_sub(int i, atomic_t *v)
{
unsigned long flags = 0;
local_irq_save(flags);
v->counter -= i;
local_irq_restore(flags);
}
static inline void atomic_inc(atomic_t *v)
{
unsigned long flags = 0;
local_irq_save(flags);
++v->counter;
local_irq_restore(flags);
}
static inline void atomic_dec(atomic_t *v)
{
unsigned long flags = 0;
local_irq_save(flags);
--v->counter;
local_irq_restore(flags);
}
static inline int atomic_dec_and_test(volatile atomic_t *v)
{
unsigned long flags = 0;
int val;
local_irq_save(flags);
val = v->counter;
v->counter = val -= 1;
local_irq_restore(flags);
return val == 0;
}
static inline int atomic_add_negative(int i, volatile atomic_t *v)
{
unsigned long flags = 0;
int val;
local_irq_save(flags);
val = v->counter;
v->counter = val += i;
local_irq_restore(flags);
return val < 0;
}
static inline void atomic_clear_mask(unsigned long mask, unsigned long *addr)
{
unsigned long flags = 0;
local_irq_save(flags);
*addr &= ~mask;
local_irq_restore(flags);
}
#if BITS_PER_LONG == 32
static inline void atomic64_add(long long i, volatile atomic64_t *v)
{
unsigned long flags = 0;
local_irq_save(flags);
v->counter += i;
local_irq_restore(flags);
}
static inline void atomic64_sub(long long i, volatile atomic64_t *v)
{
unsigned long flags = 0;
local_irq_save(flags);
v->counter -= i;
local_irq_restore(flags);
}
#else /* BIT_PER_LONG == 32 */
static inline void atomic64_add(long i, volatile atomic64_t *v)
{
unsigned long flags = 0;
local_irq_save(flags);
v->counter += i;
local_irq_restore(flags);
}
static inline void atomic64_sub(long i, volatile atomic64_t *v)
{
unsigned long flags = 0;
local_irq_save(flags);
v->counter -= i;
local_irq_restore(flags);
}
#endif
static inline void atomic64_inc(volatile atomic64_t *v)
{
unsigned long flags = 0;
local_irq_save(flags);
v->counter += 1;
local_irq_restore(flags);
}
static inline void atomic64_dec(volatile atomic64_t *v)
{
unsigned long flags = 0;
local_irq_save(flags);
v->counter -= 1;
local_irq_restore(flags);
}
#endif
+43
View File
@@ -0,0 +1,43 @@
#ifndef _ASM_GENERIC_BITOPS___FFS_H_
#define _ASM_GENERIC_BITOPS___FFS_H_
#include <asm/types.h>
/**
* __ffs - find first bit in word.
* @word: The word to search
*
* Undefined if no bit exists, so code should check against 0 first.
*/
static __always_inline unsigned long __ffs(unsigned long word)
{
int num = 0;
#if BITS_PER_LONG == 64
if ((word & 0xffffffff) == 0) {
num += 32;
word >>= 32;
}
#endif
if ((word & 0xffff) == 0) {
num += 16;
word >>= 16;
}
if ((word & 0xff) == 0) {
num += 8;
word >>= 8;
}
if ((word & 0xf) == 0) {
num += 4;
word >>= 4;
}
if ((word & 0x3) == 0) {
num += 2;
word >>= 2;
}
if ((word & 0x1) == 0)
num += 1;
return num;
}
#endif /* _ASM_GENERIC_BITOPS___FFS_H_ */
+43
View File
@@ -0,0 +1,43 @@
#ifndef _ASM_GENERIC_BITOPS___FLS_H_
#define _ASM_GENERIC_BITOPS___FLS_H_
#include <asm/types.h>
/**
* __fls - find last (most-significant) set bit in a long word
* @word: the word to search
*
* Undefined if no set bit exists, so code should check against 0 first.
*/
static __always_inline unsigned long __fls(unsigned long word)
{
int num = BITS_PER_LONG - 1;
#if BITS_PER_LONG == 64
if (!(word & (~0ul << 32))) {
num -= 32;
word <<= 32;
}
#endif
if (!(word & (~0ul << (BITS_PER_LONG-16)))) {
num -= 16;
word <<= 16;
}
if (!(word & (~0ul << (BITS_PER_LONG-8)))) {
num -= 8;
word <<= 8;
}
if (!(word & (~0ul << (BITS_PER_LONG-4)))) {
num -= 4;
word <<= 4;
}
if (!(word & (~0ul << (BITS_PER_LONG-2)))) {
num -= 2;
word <<= 2;
}
if (!(word & (~0ul << (BITS_PER_LONG-1))))
num -= 1;
return num;
}
#endif /* _ASM_GENERIC_BITOPS___FLS_H_ */
@@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_GENERIC_BITOPS_BUILTIN___FFS_H_
#define _ASM_GENERIC_BITOPS_BUILTIN___FFS_H_
/**
* __ffs - find first bit in word.
* @word: The word to search
*
* Undefined if no bit exists, so code should check against 0 first.
*/
static __always_inline unsigned long __ffs(unsigned long word)
{
return __builtin_ctzl(word);
}
#endif
@@ -0,0 +1,16 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_GENERIC_BITOPS_BUILTIN___FLS_H_
#define _ASM_GENERIC_BITOPS_BUILTIN___FLS_H_
/**
* __fls - find last (most-significant) set bit in a long word
* @word: the word to search
*
* Undefined if no set bit exists, so code should check against 0 first.
*/
static __always_inline unsigned long __fls(unsigned long word)
{
return (sizeof(word) * 8) - 1 - __builtin_clzl(word);
}
#endif
+15
View File
@@ -0,0 +1,15 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_GENERIC_BITOPS_BUILTIN_FFS_H_
#define _ASM_GENERIC_BITOPS_BUILTIN_FFS_H_
/**
* ffs - find first bit set
* @x: the word to search
*
* This is defined the same way as
* the libc and compiler builtin ffs routines, therefore
* differs in spirit from ffz (man ffs).
*/
#define ffs(x) __builtin_ffs(x)
#endif
+17
View File
@@ -0,0 +1,17 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _ASM_GENERIC_BITOPS_BUILTIN_FLS_H_
#define _ASM_GENERIC_BITOPS_BUILTIN_FLS_H_
/**
* fls - find last (most-significant) bit set
* @x: the word to search
*
* This is defined the same way as ffs.
* Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
*/
static __always_inline int fls(unsigned int x)
{
return x ? sizeof(x) * 8 - __builtin_clz(x) : 0;
}
#endif
+41
View File
@@ -0,0 +1,41 @@
#ifndef _ASM_GENERIC_BITOPS_FLS_H_
#define _ASM_GENERIC_BITOPS_FLS_H_
/**
* fls - find last (most-significant) bit set
* @x: the word to search
*
* This is defined the same way as ffs.
* Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
*/
static __always_inline int fls(int x)
{
int r = 32;
if (!x)
return 0;
if (!(x & 0xffff0000u)) {
x <<= 16;
r -= 16;
}
if (!(x & 0xff000000u)) {
x <<= 8;
r -= 8;
}
if (!(x & 0xf0000000u)) {
x <<= 4;
r -= 4;
}
if (!(x & 0xc0000000u)) {
x <<= 2;
r -= 2;
}
if (!(x & 0x80000000u)) {
x <<= 1;
r -= 1;
}
return r;
}
#endif /* _ASM_GENERIC_BITOPS_FLS_H_ */
+36
View File
@@ -0,0 +1,36 @@
#ifndef _ASM_GENERIC_BITOPS_FLS64_H_
#define _ASM_GENERIC_BITOPS_FLS64_H_
#include <asm/types.h>
/**
* fls64 - find last set bit in a 64-bit word
* @x: the word to search
*
* This is defined in a similar way as the libc and compiler builtin
* ffsll, but returns the position of the most significant set bit.
*
* fls64(value) returns 0 if value is 0 or the position of the last
* set bit if value is nonzero. The last (most significant) bit is
* at position 64.
*/
#if BITS_PER_LONG == 32
static __always_inline int fls64(__u64 x)
{
__u32 h = x >> 32;
if (h)
return fls(h) + 32;
return fls(x);
}
#elif BITS_PER_LONG == 64
static __always_inline int fls64(__u64 x)
{
if (x == 0)
return 0;
return __fls(x) + 1;
}
#else
#error BITS_PER_LONG not 32 or 64
#endif
#endif /* _ASM_GENERIC_BITOPS_FLS64_H_ */
+8
View File
@@ -0,0 +1,8 @@
#ifndef __ASM_GENERIC_BITS_PER_LONG
#define __ASM_GENERIC_BITS_PER_LONG
#ifndef BITS_PER_LONG_LONG
#define BITS_PER_LONG_LONG 64
#endif
#endif /* __ASM_GENERIC_BITS_PER_LONG */
+709
View File
@@ -0,0 +1,709 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2012 The Chromium OS Authors.
* (C) Copyright 2002-2010
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*/
#ifndef __ASM_GENERIC_GBL_DATA_H
#define __ASM_GENERIC_GBL_DATA_H
/*
* The following data structure is placed in some memory which is
* available very early after boot (like DPRAM on MPC8xx/MPC82xx, or
* some locked parts of the data cache) to allow for a minimum set of
* global variables during system initialization (until we have set
* up the memory controller so that we can use RAM).
*
* Keep it *SMALL* and remember to set GENERATED_GBL_DATA_SIZE > sizeof(gd_t)
*
* Each architecture has its own private fields. For now all are private
*/
#ifndef __ASSEMBLY__
#include <board_f.h>
#include <event_internal.h>
#include <fdtdec.h>
#include <membuf.h>
#include <linux/list.h>
#include <linux/build_bug.h>
#include <asm-offsets.h>
struct acpi_ctx;
struct driver_rt;
struct upl;
typedef struct global_data gd_t;
/**
* struct global_data - global data structure
*/
struct global_data {
/**
* @bd: board information
*/
struct bd_info *bd;
/**
* @new_gd: pointer to relocated global data
*/
struct global_data *new_gd;
/**
* @fdt_blob: U-Boot's own device tree, NULL if none
*/
const void *fdt_blob;
/**
* @cur_serial_dev: current serial device
*/
struct udevice *cur_serial_dev;
#ifndef CONFIG_XPL_BUILD
/**
* @jt: jump table
*
* The jump table contains pointers to exported functions. A pointer to
* the jump table is passed to standalone applications.
*/
struct jt_funcs *jt;
/**
* @boardf: information only used before relocation
*/
struct board_f *boardf;
#endif
/**
* @ram_size: RAM size in bytes
*/
phys_size_t ram_size;
/**
* @ram_top: top address of RAM used by U-Boot
*/
phys_addr_t ram_top;
/**
* @flags: global data flags
*
* See &enum gd_flags
*/
unsigned long flags;
/**
* @cpu_clk: CPU clock rate in Hz
*/
unsigned long cpu_clk;
#if CONFIG_IS_ENABLED(ENV_SUPPORT)
/**
* @env_addr: address of environment structure
*
* @env_addr contains the address of the structure holding the
* environment variables.
*/
unsigned long env_addr;
#endif /* ENV_SUPPORT */
/**
* @ram_base: base address of RAM used by U-Boot
*/
unsigned long ram_base;
/**
* @relocaddr: start address of U-Boot in RAM
*
* After relocation this field indicates the address to which U-Boot
* has been relocated. It can be displayed using the bdinfo command.
* Its value is needed to display the source code when debugging with
* GDB using the 'add-symbol-file u-boot <relocaddr>' command.
*/
unsigned long relocaddr;
/**
* @irq_sp: IRQ stack pointer
*/
unsigned long irq_sp;
/**
* @start_addr_sp: initial stack pointer address
*/
unsigned long start_addr_sp;
/**
* @reloc_off: relocation offset
*/
unsigned long reloc_off;
/**
* @bus_clk: platform clock rate in Hz
*/
unsigned int bus_clk;
/**
* @mem_clk: memory clock rate in Hz
*/
unsigned int mem_clk;
/**
* @mon_len: monitor length in bytes
*/
unsigned int mon_len;
/**
* @baudrate: baud rate of the serial interface
*/
unsigned int baudrate;
#if CONFIG_IS_ENABLED(ENV_SUPPORT)
/**
* @env_has_init: bit mask indicating environment locations
*
* &enum env_location defines which bit relates to which location
*/
unsigned short env_has_init;
/**
* @env_valid: environment is valid
*
* See &enum env_valid
*/
unsigned char env_valid;
/**
* @env_load_prio: priority of the loaded environment
*/
char env_load_prio;
/**
* @env_buf: buffer for env_get() before reloc
*/
char env_buf[32];
#endif /* ENV_SUPPORT */
/**
* @fdt_src: Source of FDT
*/
enum fdt_source_t fdt_src;
/**
* @arch: architecture-specific data
*/
struct arch_global_data arch;
/**
* @dmtag_list: List of DM tags
*/
struct list_head dmtag_list;
/**
* @timebase_h: high 32 bits of timer
*/
unsigned int timebase_h;
/**
* @timebase_l: low 32 bits of timer
*/
unsigned int timebase_l;
#if defined(CONFIG_POST)
/**
* @post_log_word: active POST tests
*
* @post_log_word is a bit mask defining which POST tests are recorded
* (see constants POST_*).
*/
unsigned long post_log_word;
/**
* @post_log_res: POST results
*
* @post_log_res is a bit mask with the POST results. A bit with value 1
* indicates successful execution.
*/
unsigned long post_log_res;
/**
* @post_init_f_time: time in ms when post_init_f() started
*/
unsigned long post_init_f_time;
#endif
#ifdef CONFIG_BOARD_TYPES
/**
* @board_type: board type
*
* If a U-Boot configuration supports multiple board types, the actual
* board type may be stored in this field.
*/
unsigned long board_type;
#endif
#if CONFIG_IS_ENABLED(PRE_CONSOLE_BUFFER)
/**
* @precon_buf_idx: pre-console buffer index
*
* @precon_buf_idx indicates the current position of the
* buffer used to collect output before the console becomes
* available. When negative, the pre-console buffer is
* temporarily disabled (used when the pre-console buffer is
* being written out, to prevent adding its contents to
* itself).
*/
long precon_buf_idx;
#endif
#ifdef CONFIG_DM
/**
* @dm_root: root instance for Driver Model
*/
struct udevice *dm_root;
/**
* @uclass_root_s:
* head of core tree when uclasses are not in read-only memory.
*
* When uclasses are in read-only memory, @uclass_root_s is not used and
* @uclass_root points to the root node generated by dtoc.
*/
struct list_head uclass_root_s;
/**
* @uclass_root:
* pointer to head of core tree, if uclasses are in read-only memory and
* cannot be adjusted to use @uclass_root as a list head.
*
* When not in read-only memory, @uclass_root_s is used to hold the
* uclass root, and @uclass_root points to the address of
* @uclass_root_s.
*/
struct list_head *uclass_root;
# if CONFIG_IS_ENABLED(OF_PLATDATA_DRIVER_RT)
/** @dm_driver_rt: Dynamic info about the driver */
struct driver_rt *dm_driver_rt;
# endif
#if CONFIG_IS_ENABLED(OF_PLATDATA_RT)
/** @dm_udevice_rt: Dynamic info about the udevice */
struct udevice_rt *dm_udevice_rt;
/**
* @dm_priv_base: Base address of the priv/plat region used when
* udevices and uclasses are in read-only memory. This is NULL if not
* used
*/
void *dm_priv_base;
# endif
#endif
#ifdef CONFIG_TIMER
/**
* @timer: timer instance for Driver Model
*/
struct udevice *timer;
#endif
#if CONFIG_IS_ENABLED(OF_LIVE)
/**
* @of_root: root node of the live tree
*/
struct device_node *of_root;
#endif
#if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
/**
* @multi_dtb_fit: pointer to uncompressed multi-dtb FIT image
*/
const void *multi_dtb_fit;
#endif
#ifdef CONFIG_TRACE
/**
* @trace_buff: trace buffer
*
* When tracing function in U-Boot this field points to the buffer
* recording the function calls.
*/
void *trace_buff;
#endif
#if CONFIG_IS_ENABLED(SYS_I2C_LEGACY)
/**
* @cur_i2c_bus: currently used I2C bus
*/
int cur_i2c_bus;
#endif
#if CONFIG_IS_ENABLED(CMD_BDINFO_EXTRA)
/**
* @malloc_start: start of malloc() region
*/
unsigned long malloc_start;
#endif
#if CONFIG_IS_ENABLED(SYS_MALLOC_F)
/**
* @malloc_base: base address of early malloc()
*/
unsigned long malloc_base;
/**
* @malloc_limit: maximum size of early malloc()
*/
unsigned int malloc_limit;
/**
* @malloc_ptr: currently used bytes of early malloc()
*/
unsigned int malloc_ptr;
#endif
#ifdef CONFIG_CONSOLE_RECORD
/**
* @console_out: output buffer for console recording
*
* This buffer is used to collect output during console recording.
*/
struct membuf console_out;
/**
* @console_in: input buffer for console recording
*
* If console recording is activated, this buffer can be used to
* emulate input.
*/
struct membuf console_in;
#endif
#if CONFIG_IS_ENABLED(VIDEO)
/**
* @video_top: top of video frame buffer area
*/
ulong video_top;
/**
* @video_bottom: bottom of video frame buffer area
*/
ulong video_bottom;
#endif
#ifdef CONFIG_BOOTSTAGE
/**
* @bootstage: boot stage information
*/
struct bootstage_data *bootstage;
#endif
#ifdef CONFIG_LOG
/**
* @log_head: list of logging devices
*/
struct list_head log_head;
/**
* @log_fmt: bit mask for logging format
*
* The @log_fmt bit mask selects the fields to be shown in log messages.
* &enum log_fmt defines the bits of the bit mask.
*/
/**
* @log_drop_count: number of dropped log messages
*
* This counter is incremented for each log message which can not
* be processed because logging is not yet available as signaled by
* flag %GD_FLG_LOG_READY in @flags.
*/
int log_drop_count;
/**
* @default_log_level: default logging level
*
* For logging devices without filters @default_log_level defines the
* logging level, cf. &enum log_level_t.
*/
char default_log_level;
char log_fmt;
/**
* @logc_prev: logging category of previous message
*
* This value is used as logging category for continuation messages.
*/
unsigned char logc_prev;
/**
* @logl_prev: logging level of the previous message
*
* This value is used as logging level for continuation messages.
*/
unsigned char logl_prev;
/**
* @log_cont: Previous log line did not finished wtih \n
*
* This allows for chained log messages on the same line
*/
bool log_cont;
/**
* @processing_msg: a log message is being processed
*
* This flag is used to suppress the creation of additional messages
* while another message is being processed.
*/
bool processing_msg;
#endif
#if CONFIG_IS_ENABLED(BLOBLIST)
/**
* @bloblist: blob list information
*/
struct bloblist_hdr *bloblist;
#endif
#if CONFIG_IS_ENABLED(HANDOFF)
/**
* @spl_handoff: SPL hand-off information
*/
struct spl_handoff *spl_handoff;
#endif
#if defined(CONFIG_TRANSLATION_OFFSET)
/**
* @translation_offset: optional translation offset
*
* See CONFIG_TRANSLATION_OFFSET.
*/
fdt_addr_t translation_offset;
#endif
#ifdef CONFIG_ACPI
/**
* @acpi_ctx: ACPI context pointer
*/
struct acpi_ctx *acpi_ctx;
/**
* @acpi_start: Start address of ACPI tables
*/
ulong acpi_start;
#endif
#if CONFIG_IS_ENABLED(GENERATE_SMBIOS_TABLE)
/**
* @smbios_version: Points to SMBIOS type 0 version
*/
char *smbios_version;
#endif
#if CONFIG_IS_ENABLED(EVENT)
/**
* @event_state: Points to the current state of events
*/
struct event_state event_state;
#endif
#if CONFIG_IS_ENABLED(CYCLIC)
/**
* @cyclic_list: list of registered cyclic functions
*/
struct hlist_head cyclic_list;
#endif
#if CONFIG_IS_ENABLED(UPL)
/**
* @upl: Universal Payload-handoff information
*/
struct upl *upl;
#endif
};
#ifndef DO_DEPS_ONLY
static_assert(sizeof(struct global_data) == GD_SIZE);
#endif
/**
* gd_board_type() - retrieve board type
*
* Return: global board type
*/
#ifdef CONFIG_BOARD_TYPES
#define gd_board_type() gd->board_type
#else
#define gd_board_type() 0
#endif
/* These macros help avoid #ifdefs in the code */
#if CONFIG_IS_ENABLED(OF_LIVE)
#define gd_of_root() gd->of_root
#define gd_of_root_ptr() &gd->of_root
#define gd_set_of_root(_root) gd->of_root = (_root)
#else
#define gd_of_root() NULL
#define gd_of_root_ptr() NULL
#define gd_set_of_root(_root)
#endif
#if CONFIG_IS_ENABLED(OF_PLATDATA_DRIVER_RT)
#define gd_set_dm_driver_rt(dyn) gd->dm_driver_rt = dyn
#define gd_dm_driver_rt() gd->dm_driver_rt
#else
#define gd_set_dm_driver_rt(dyn)
#define gd_dm_driver_rt() NULL
#endif
#if CONFIG_IS_ENABLED(OF_PLATDATA_RT)
#define gd_set_dm_udevice_rt(dyn) gd->dm_udevice_rt = dyn
#define gd_dm_udevice_rt() gd->dm_udevice_rt
#define gd_set_dm_priv_base(dyn) gd->dm_priv_base = dyn
#define gd_dm_priv_base() gd->dm_priv_base
#else
#define gd_set_dm_udevice_rt(dyn)
#define gd_dm_udevice_rt() NULL
#define gd_set_dm_priv_base(dyn)
#define gd_dm_priv_base() NULL
#endif
#ifdef CONFIG_ACPI
#define gd_acpi_ctx() gd->acpi_ctx
#define gd_acpi_start() gd->acpi_start
#define gd_set_acpi_start(addr) gd->acpi_start = addr
#else
#define gd_acpi_ctx() NULL
#define gd_acpi_start() 0UL
#define gd_set_acpi_start(addr)
#endif
#ifdef CONFIG_SMBIOS
#define gd_smbios_start() gd->arch.smbios_start
#define gd_set_smbios_start(addr) gd->arch.smbios_start = addr
#else
#define gd_smbios_start() 0UL
#define gd_set_smbios_start(addr)
#endif
#if CONFIG_IS_ENABLED(MULTI_DTB_FIT)
#define gd_multi_dtb_fit() gd->multi_dtb_fit
#define gd_set_multi_dtb_fit(_dtb) gd->multi_dtb_fit = _dtb
#else
#define gd_multi_dtb_fit() NULL
#define gd_set_multi_dtb_fit(_dtb)
#endif
#if CONFIG_IS_ENABLED(EVENT_DYNAMIC)
#define gd_event_state() ((struct event_state *)&gd->event_state)
#else
#define gd_event_state() NULL
#endif
#if CONFIG_IS_ENABLED(CMD_BDINFO_EXTRA)
#define gd_malloc_start() gd->malloc_start
#define gd_set_malloc_start(_val) gd->malloc_start = (_val)
#else
#define gd_malloc_start() 0
#define gd_set_malloc_start(val)
#endif
#if CONFIG_VAL(SYS_MALLOC_F_LEN)
#define gd_malloc_ptr() gd->malloc_ptr
#else
#define gd_malloc_ptr() 0L
#endif
#if CONFIG_IS_ENABLED(UPL)
#define gd_upl() gd->upl
#define gd_set_upl(_val) gd->upl = (_val)
#else
#define gd_upl() NULL
#define gd_set_upl(val)
#endif
#if CONFIG_IS_ENABLED(BLOBLIST)
#define gd_bloblist() gd->bloblist
#define gd_set_bloblist(_val) gd->bloblist = (_val)
#else
#define gd_bloblist() NULL
#define gd_set_bloblist(_val)
#endif
#if CONFIG_IS_ENABLED(BOOTSTAGE)
#define gd_bootstage() gd->bootstage
#else
#define gd_bootstage() NULL
#endif
#if CONFIG_IS_ENABLED(TRACE)
#define gd_trace_buff() gd->trace_buff
#define gd_trace_size() CONFIG_TRACE_BUFFER_SIZE
#else
#define gd_trace_buff() NULL
#define gd_trace_size() 0
#endif
#if CONFIG_IS_ENABLED(VIDEO)
#define gd_video_top() gd->video_top
#define gd_video_bottom() gd->video_bottom
#define gd_video_size() (gd->video_top - gd->video_bottom)
#else
#define gd_video_top() 0
#define gd_video_bottom() 0
#define gd_video_size() 0
#endif
/**
* enum gd_flags - global data flags
*
* See field flags of &struct global_data.
*/
enum gd_flags {
/**
* @GD_FLG_RELOC: code was relocated to RAM
*/
GD_FLG_RELOC = 0x00001,
/**
* @GD_FLG_DEVINIT: devices have been initialized
*/
GD_FLG_DEVINIT = 0x00002,
/**
* @GD_FLG_SILENT: silent mode
*/
GD_FLG_SILENT = 0x00004,
/**
* @GD_FLG_POSTFAIL: critical POST test failed
*/
GD_FLG_POSTFAIL = 0x00008,
/**
* @GD_FLG_POSTSTOP: POST sequence aborted
*/
GD_FLG_POSTSTOP = 0x00010,
/**
* @GD_FLG_LOGINIT: log Buffer has been initialized
*/
GD_FLG_LOGINIT = 0x00020,
/**
* @GD_FLG_DISABLE_CONSOLE: disable console (in & out)
*/
GD_FLG_DISABLE_CONSOLE = 0x00040,
/**
* @GD_FLG_ENV_READY: environment imported into hash table
*/
GD_FLG_ENV_READY = 0x00080,
/**
* @GD_FLG_SERIAL_READY: pre-relocation serial console ready
*/
GD_FLG_SERIAL_READY = 0x00100,
/**
* @GD_FLG_FULL_MALLOC_INIT: full malloc() is ready
*/
GD_FLG_FULL_MALLOC_INIT = 0x00200,
/**
* @GD_FLG_SPL_INIT: spl_init() has been called
*/
GD_FLG_SPL_INIT = 0x00400,
/**
* @GD_FLG_SKIP_RELOC: don't relocate
*/
GD_FLG_SKIP_RELOC = 0x00800,
/**
* @GD_FLG_RECORD: record console
*/
GD_FLG_RECORD = 0x01000,
/**
* @GD_FLG_RECORD_OVF: record console overflow
*/
GD_FLG_RECORD_OVF = 0x02000,
/**
* @GD_FLG_ENV_DEFAULT: default variable flag
*/
GD_FLG_ENV_DEFAULT = 0x04000,
/**
* @GD_FLG_SPL_EARLY_INIT: early SPL initialization is done
*/
GD_FLG_SPL_EARLY_INIT = 0x08000,
/**
* @GD_FLG_LOG_READY: log system is ready for use
*/
GD_FLG_LOG_READY = 0x10000,
/**
* @GD_FLG_CYCLIC_RUNNING: cyclic_run is in progress
*/
GD_FLG_CYCLIC_RUNNING = 0x20000,
/**
* @GD_FLG_SKIP_LL_INIT: don't perform low-level initialization
*/
GD_FLG_SKIP_LL_INIT = 0x40000,
/**
* @GD_FLG_SMP_READY: SMP initialization is complete
*/
GD_FLG_SMP_READY = 0x80000,
/**
* @GD_FLG_FDT_CHANGED: Device tree change has been detected by tests
*/
GD_FLG_FDT_CHANGED = 0x100000,
/*
* @GD_FLG_OF_TAG_MIGRATE: Previously had the value of 0x200000 but was
* freed when migration support was removed.
*/
/**
* @GD_FLG_DM_DEAD: Driver model is not accessible. This can be set when
* the memory used to holds its tables has been mapped out.
*/
GD_FLG_DM_DEAD = 0x400000,
/**
* @GD_FLG_BLOBLIST_READY: bloblist is ready for use
*/
GD_FLG_BLOBLIST_READY = 0x800000,
/**
* @GD_FLG_HUSH_OLD_PARSER: Use hush old parser.
*/
GD_FLG_HUSH_OLD_PARSER = 0x1000000,
/**
* @GD_FLG_HUSH_MODERN_PARSER: Use hush 2021 parser.
*/
GD_FLG_HUSH_MODERN_PARSER = 0x2000000,
/**
* @GD_FLG_UPL: Read/write a Universal Payload (UPL) handoff
*/
GD_FLG_UPL = 0x4000000,
/**
* @GD_FLG_HAVE_CONSOLE: serial_init() was called and a console
* is available. When not set, indicates that console input and output
* drivers shall not be called.
*/
GD_FLG_HAVE_CONSOLE = 0x8000000,
};
#endif /* __ASSEMBLY__ */
#endif /* __ASM_GENERIC_GBL_DATA_H */
+868
View File
@@ -0,0 +1,868 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2011 The Chromium OS Authors.
* Copyright (c) 2011, NVIDIA Corp. All rights reserved.
*/
#ifndef _ASM_GENERIC_GPIO_H_
#define _ASM_GENERIC_GPIO_H_
#include <dm/ofnode.h>
#include <linux/bitops.h>
struct acpi_gpio;
struct ofnode_phandle_args;
/*
* Generic GPIO API for U-Boot
*
* --
* NB: This is deprecated. Please use the driver model functions instead:
*
* - gpio_request_by_name()
* - dm_gpio_get_value() etc.
*
* For now we need a dm_ prefix on some functions to avoid name collision.
* --
*
* GPIOs are numbered from 0 to GPIO_COUNT-1 which value is defined
* by the SOC/architecture.
*
* Each GPIO can be an input or output. If an input then its value can
* be read as 0 or 1. If an output then its value can be set to 0 or 1.
* If you try to write an input then the value is undefined. If you try
* to read an output, barring something very unusual, you will get
* back the value of the output that you previously set.
*
* In some cases the operation may fail, for example if the GPIO number
* is out of range, or the GPIO is not available because its pin is
* being used by another function. In that case, functions may return
* an error value of -1.
*/
/**
* @deprecated Please use driver model instead
* Request a GPIO. This should be called before any of the other functions
* are used on this GPIO.
*
* Note: With driver model, the label is allocated so there is no need for
* the caller to preserve it.
*
* @param gpio GPIO number
* @param label User label for this GPIO
* Return: 0 if ok, -1 on error
*/
int gpio_request(unsigned gpio, const char *label);
/**
* @deprecated Please use driver model instead
* Stop using the GPIO. This function should not alter pin configuration.
*
* @param gpio GPIO number
* Return: 0 if ok, -1 on error
*/
int gpio_free(unsigned gpio);
/**
* @deprecated Please use driver model instead
* Make a GPIO an input.
*
* @param gpio GPIO number
* Return: 0 if ok, -1 on error
*/
int gpio_direction_input(unsigned gpio);
/**
* @deprecated Please use driver model instead
* Make a GPIO an output, and set its value.
*
* @param gpio GPIO number
* @param value GPIO value (0 for low or 1 for high)
* Return: 0 if ok, -1 on error
*/
int gpio_direction_output(unsigned gpio, int value);
/**
* @deprecated Please use driver model instead
* Get a GPIO's value. This will work whether the GPIO is an input
* or an output.
*
* @param gpio GPIO number
* Return: 0 if low, 1 if high, -1 on error
*/
int gpio_get_value(unsigned gpio);
/**
* @deprecated Please use driver model instead
* Set an output GPIO's value. The GPIO must already be an output or
* this function may have no effect.
*
* @param gpio GPIO number
* @param value GPIO value (0 for low or 1 for high)
* Return: 0 if ok, -1 on error
*/
int gpio_set_value(unsigned gpio, int value);
/* State of a GPIO, as reported by get_function() */
enum gpio_func_t {
GPIOF_INPUT = 0,
GPIOF_OUTPUT,
GPIOF_UNUSED, /* Not claimed */
GPIOF_UNKNOWN, /* Not known */
GPIOF_FUNC, /* Not used as a GPIO */
GPIOF_COUNT,
};
struct udevice;
struct gpio_desc {
struct udevice *dev; /* Device, NULL for invalid GPIO */
unsigned long flags;
#define GPIOD_IS_OUT BIT(1) /* GPIO is an output */
#define GPIOD_IS_IN BIT(2) /* GPIO is an input */
#define GPIOD_ACTIVE_LOW BIT(3) /* GPIO is active when value is low */
#define GPIOD_IS_OUT_ACTIVE BIT(4) /* set output active */
#define GPIOD_OPEN_DRAIN BIT(5) /* GPIO is open drain type */
#define GPIOD_OPEN_SOURCE BIT(6) /* GPIO is open source type */
#define GPIOD_PULL_UP BIT(7) /* GPIO has pull-up enabled */
#define GPIOD_PULL_DOWN BIT(8) /* GPIO has pull-down enabled */
#define GPIOD_IS_AF BIT(9) /* GPIO is an alternate function */
/* Flags for updating the above */
#define GPIOD_MASK_DIR (GPIOD_IS_OUT | GPIOD_IS_IN | \
GPIOD_IS_OUT_ACTIVE)
#define GPIOD_MASK_DSTYPE (GPIOD_OPEN_DRAIN | GPIOD_OPEN_SOURCE)
#define GPIOD_MASK_PULL (GPIOD_PULL_UP | GPIOD_PULL_DOWN)
uint offset; /* GPIO offset within the device */
/*
* We could consider adding the GPIO label in here. Possibly we could
* use this structure for internal GPIO information.
*/
};
/**
* dm_gpio_is_valid() - Check if a GPIO is valid
*
* @desc: GPIO description containing device, offset and flags,
* previously returned by gpio_request_by_name()
* Return: true if valid, false if not
*/
static inline bool dm_gpio_is_valid(const struct gpio_desc *desc)
{
return desc->dev != NULL;
}
/**
* gpio_get_status() - get the current GPIO status as a string
*
* Obtain the current GPIO status as a string which can be presented to the
* user. A typical string is:
*
* "b4: in: 1 [x] sdmmc_cd"
*
* which means this is GPIO bank b, offset 4, currently set to input, current
* value 1, [x] means that it is requested and the owner is 'sdmmc_cd'
*
* TODO(sjg@chromium.org): This should use struct gpio_desc
*
* @dev: Device to check
* @offset: Offset of device GPIO to check
* @buf: Place to put string
* @buffsize: Size of string including \0
*/
int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize);
/**
* gpio_get_function() - get the current function for a GPIO pin
*
* Note this returns GPIOF_UNUSED if the GPIO is not requested.
*
* TODO(sjg@chromium.org): This should use struct gpio_desc
*
* @dev: Device to check
* @offset: Offset of device GPIO to check
* @namep: If non-NULL, this is set to the name given when the GPIO
* was requested, or -1 if it has not been requested
* Return: -ENODATA if the driver returned an unknown function,
* -ENODEV if the device is not active, -EINVAL if the offset is invalid.
* GPIOF_UNUSED if the GPIO has not been requested. Otherwise returns the
* function from enum gpio_func_t.
*/
int gpio_get_function(struct udevice *dev, int offset, const char **namep);
/**
* gpio_get_raw_function() - get the current raw function for a GPIO pin
*
* Note this does not return GPIOF_UNUSED - it will always return the GPIO
* driver's view of a pin function, even if it is not correctly set up.
*
* TODO(sjg@chromium.org): This should use struct gpio_desc
*
* @dev: Device to check
* @offset: Offset of device GPIO to check
* @namep: If non-NULL, this is set to the name given when the GPIO
* was requested, or -1 if it has not been requested
* Return: -ENODATA if the driver returned an unknown function,
* -ENODEV if the device is not active, -EINVAL if the offset is invalid.
* Otherwise returns the function from enum gpio_func_t.
*/
int gpio_get_raw_function(struct udevice *dev, int offset, const char **namep);
/**
* gpio_requestf() - request a GPIO using a format string for the owner
*
* This is a helper function for gpio_request(). It allows you to provide
* a printf()-format string for the GPIO owner. It calls gpio_request() with
* the string that is created
*/
int gpio_requestf(unsigned gpio, const char *fmt, ...)
__attribute__ ((format (__printf__, 2, 3)));
struct fdtdec_phandle_args;
/**
* gpio_flags_xlate() - convert DT flags to internal flags
*
* This routine converts the GPIO_* flags from the generic DT binding to the
* GPIOD_* flags used internally. It can be called from driver xlate functions.
*/
unsigned long gpio_flags_xlate(uint32_t arg);
/**
* gpio_xlate_offs_flags() - implementation for common use of dm_gpio_ops.xlate
*
* This routine sets the offset field to args[0] and the flags field to
* GPIOD_ACTIVE_LOW if the GPIO_ACTIVE_LOW flag is present in args[1].
*/
int gpio_xlate_offs_flags(struct udevice *dev, struct gpio_desc *desc,
struct ofnode_phandle_args *args);
/**
* struct struct dm_gpio_ops - Driver model GPIO operations
*
* Refer to functions above for description. These function largely copy
* the old API.
*
* This is trying to be close to Linux GPIO API. Once the U-Boot uses the
* new DM GPIO API, this should be really easy to flip over to the Linux
* GPIO API-alike interface.
*
* Also it would be useful to standardise additional functions like
* pullup, slew rate and drive strength.
*
* gpio_request() and gpio_free() are optional - if NULL then they will
* not be called.
*
* Note that @offset is the offset from the base GPIO of the device. So
* offset 0 is the device's first GPIO and offset o-1 is the last GPIO,
* where o is the number of GPIO lines controlled by the device. A device
* is typically used to control a single bank of GPIOs. Within complex
* SoCs there may be many banks and therefore many devices all referring
* to the different IO addresses within the SoC.
*
* The uclass combines all GPIO devices together to provide a consistent
* numbering from 0 to n-1, where n is the number of GPIOs in total across
* all devices. Be careful not to confuse offset with gpio in the parameters.
*/
struct dm_gpio_ops {
int (*request)(struct udevice *dev, unsigned offset, const char *label);
int (*rfree)(struct udevice *dev, unsigned int offset);
/**
* direction_input() - deprecated
*
* Equivalent to set_flags(...GPIOD_IS_IN)
*/
int (*direction_input)(struct udevice *dev, unsigned offset);
/**
* direction_output() - deprecated
*
* Equivalent to set_flags(...GPIOD_IS_OUT) with GPIOD_IS_OUT_ACTIVE
* also set if @value
*/
int (*direction_output)(struct udevice *dev, unsigned offset,
int value);
int (*get_value)(struct udevice *dev, unsigned offset);
/**
* set_value() - Sets the GPIO value of an output
*
* If the driver provides an @set_flags() method then that is used
* in preference to this, with GPIOD_IS_OUT_ACTIVE set according to
* @value.
*/
int (*set_value)(struct udevice *dev, unsigned offset, int value);
/**
* get_function() Get the GPIO function
*
* @dev: Device to check
* @offset: GPIO offset within that device
* @return current function - GPIOF_...
*/
int (*get_function)(struct udevice *dev, unsigned offset);
/**
* xlate() - Translate phandle arguments into a GPIO description
*
* This function should set up the fields in desc according to the
* information in the arguments. The uclass will have set up:
*
* @desc->dev to @dev
* @desc->flags to 0
* @desc->offset to 0
*
* This method is optional and defaults to gpio_xlate_offs_flags,
* which will parse offset and the GPIO_ACTIVE_LOW flag in the first
* two arguments.
*
* Note that @dev is passed in as a parameter to follow driver model
* uclass conventions, even though it is already available as
* desc->dev.
*
* @dev: GPIO device
* @desc: Place to put GPIO description
* @args: Arguments provided in description
* @return 0 if OK, -ve on error
*/
int (*xlate)(struct udevice *dev, struct gpio_desc *desc,
struct ofnode_phandle_args *args);
/**
* set_flags() - Adjust GPIO flags
*
* This function should set up the GPIO configuration according to the
* information provided by @flags.
*
* If any flags cannot be set (e.g. the driver or hardware does not
* support them or this particular GPIO does not have the requested
* feature), the driver should return -EINVAL.
*
* The uclass checks that flags do not obviously conflict (e.g. input
* and output). If the driver finds other conflicts it should return
* -ERECALLCONFLICT
*
* Note that GPIOD_ACTIVE_LOW should be ignored, since the uclass
* adjusts for it automatically. For example, for an output GPIO,
* GPIOD_ACTIVE_LOW causes GPIOD_IS_OUT_ACTIVE to be inverted by the
* uclass, so the driver always sees the value that should be set at the
* pin (1=high, 0=low).
*
* This method is required and should be implemented by new drivers. At
* some point, it will supersede direction_input() and
* direction_output(), which wil be removed.
*
* @dev: GPIO device
* @offset: GPIO offset within that device
* @flags: New flags value (GPIOD_...)
*
* @return 0 if OK, -EINVAL if unsupported, -ERECALLCONFLICT if flags
* conflict in some * non-obvious way and were not applied,
* other -ve on error
*/
int (*set_flags)(struct udevice *dev, unsigned int offset, ulong flags);
/**
* get_flags() - Get GPIO flags
*
* This function return the GPIO flags used. It should read this from
* the hardware directly.
*
* This method is optional.
*
* @dev: GPIO device
* @offset: GPIO offset within that device
* @flagsp: place to put the current flags value
* @return 0 if OK, -ve on error
*/
int (*get_flags)(struct udevice *dev, unsigned int offset,
ulong *flagsp);
#if CONFIG_IS_ENABLED(ACPIGEN)
/**
* get_acpi() - Get the ACPI info for a GPIO
*
* This converts a GPIO to an ACPI structure for adding to the ACPI
* tables.
*
* @desc: GPIO description to convert
* @gpio: Output ACPI GPIO information
* @return ACPI pin number or -ve on error
*/
int (*get_acpi)(const struct gpio_desc *desc, struct acpi_gpio *gpio);
#endif
};
/**
* struct gpio_dev_priv - information about a device used by the uclass
*
* The uclass combines all active GPIO devices into a unified numbering
* scheme. To do this it maintains some private information about each
* device.
*
* To implement driver model support in your GPIO driver, add a probe
* handler, and set @gpio_count and @bank_name correctly in that handler.
* This tells the uclass the name of the GPIO bank and the number of GPIOs
* it contains.
*
* @bank_name: Name of the GPIO device (e.g 'a' means GPIOs will be called
* 'A0', 'A1', etc.
* @gpio_count: Number of GPIOs in this device
* @gpio_base: Base GPIO number for this device. For the first active device
* this will be 0; the numbering for others will follow sequentially so that
* @gpio_base for device 1 will equal the number of GPIOs in device 0.
* @claimed: Array of bits indicating which GPIOs in the bank are claimed.
* @name: Array of pointers to the name for each GPIO in this bank. The
* value of the pointer will be NULL if the GPIO has not been claimed.
*/
struct gpio_dev_priv {
const char *bank_name;
unsigned gpio_count;
unsigned gpio_base;
u32 *claimed;
char **name;
};
/* Access the GPIO operations for a device */
#define gpio_get_ops(dev) ((struct dm_gpio_ops *)(dev)->driver->ops)
/**
* gpio_get_bank_info - Return information about a GPIO bank/device
*
* This looks up a device and returns both its GPIO base name and the number
* of GPIOs it controls.
*
* @dev: Device to look up
* @offset_count: Returns number of GPIOs within this bank
* Return: bank name of this device
*/
const char *gpio_get_bank_info(struct udevice *dev, int *offset_count);
/**
* dm_gpio_lookup_name() - Look up a named GPIO and return its description
*
* The name of a GPIO is typically its bank name followed by a number from 0.
* For example A0 is the first GPIO in bank A. Each bank is a separate driver
* model device.
*
* @name: Name to look up
* @desc: Returns description, on success
* Return: 0 if OK, -ve on error
*/
int dm_gpio_lookup_name(const char *name, struct gpio_desc *desc);
/**
* gpio_hog_lookup_name() - Look up a named GPIO and return the gpio descr.
*
* @name: Name to look up
* @desc: Returns GPIO description, on success, else NULL
* @return: Returns 0 if OK, else -ENODEV
*/
int gpio_hog_lookup_name(const char *name, struct gpio_desc **desc);
/**
* gpio_lookup_name - Look up a GPIO name and return its details
*
* This is used to convert a named GPIO into a device, offset and GPIO
* number.
*
* @name: GPIO name to look up
* @devp: Returns pointer to device which contains this GPIO
* @offsetp: Returns the offset number within this device
* @gpiop: Returns the absolute GPIO number, numbered from 0
*/
int gpio_lookup_name(const char *name, struct udevice **devp,
unsigned int *offsetp, unsigned int *gpiop);
/**
* gpio_get_values_as_int() - Turn the values of a list of GPIOs into an int
*
* This puts the value of the first GPIO into bit 0, the second into bit 1,
* etc. then returns the resulting integer.
*
* @gpio_list: List of GPIOs to collect
* Return: resulting integer value, or -ve on error
*/
int gpio_get_values_as_int(const int *gpio_list);
/**
* dm_gpio_get_values_as_int() - Turn the values of a list of GPIOs into an int
*
* This puts the value of the first GPIO into bit 0, the second into bit 1,
* etc. then returns the resulting integer.
*
* @desc_list: List of GPIOs to collect
* @count: Number of GPIOs
* Return: resulting integer value, or -ve on error
*/
int dm_gpio_get_values_as_int(const struct gpio_desc *desc_list, int count);
/**
* dm_gpio_get_values_as_int_base3() - Create a base-3 int from a list of GPIOs
*
* This uses pull-ups/pull-downs to figure out whether a GPIO line is externally
* pulled down, pulled up or floating. This allows three different strap values
* for each pin:
* 0 : external pull-down
* 1 : external pull-up
* 2 : floating
*
* With this it is possible to obtain more combinations from the same number of
* strapping pins, when compared to dm_gpio_get_values_as_int(). The external
* pull resistors should be made stronger that the internal SoC pull resistors,
* for this to work.
*
* With 2 pins, 6 combinations are possible, compared with 4
* With 3 pins, 27 are possible, compared with 8
*
* @desc_list: List of GPIOs to collect
* @count: Number of GPIOs
* Return: resulting integer value, or -ve on error
*/
int dm_gpio_get_values_as_int_base3(struct gpio_desc *desc_list,
int count);
/**
* gpio_claim_vector() - claim a number of GPIOs for input
*
* @gpio_num_array: array of gpios to claim, terminated by -1
* @fmt: format string for GPIO names, e.g. "board_id%d"
* Return: 0 if OK, -ve on error
*/
int gpio_claim_vector(const int *gpio_num_array, const char *fmt);
/**
* gpio_request_by_name() - Locate and request a GPIO by name
*
* This operates by looking up the given list name in the device (device
* tree property) and requesting the GPIO for use. The property must exist
* in @dev's node.
*
* Use @flags to specify whether the GPIO should be an input or output. In
* principle this can also come from the device tree binding but most
* bindings don't provide this information. Specifically, when the GPIO uclass
* calls the xlate() method, it can return default flags, which are then
* ORed with this @flags.
*
* If we find that requesting the GPIO is not always needed we could add a
* new function or a new GPIOD_NO_REQUEST flag.
*
* At present driver model has no reference counting so if one device
* requests a GPIO which subsequently is unbound, the @desc->dev pointer
* will be invalid. However this will only happen if the GPIO device is
* unbound, not if it is removed, so this seems like a reasonable limitation
* for now. There is no real use case for unbinding drivers in normal
* operation.
*
* The device tree binding is doc/device-tree-bindings/gpio/gpio.txt in
* generate terms and each specific device may add additional details in
* a binding file in the same directory.
*
* @dev: Device requesting the GPIO
* @list_name: Name of GPIO list (e.g. "board-id-gpios")
* @index: Index number of the GPIO in that list use request (0=first)
* @desc: Returns GPIO description information. If there is no such
* GPIO, @desc->dev will be NULL.
* @flags: Indicates the GPIO input/output settings (GPIOD_...)
* Return: 0 if OK, -ENOENT if the GPIO does not exist, -EINVAL if there is
* something wrong with the list, or other -ve for another error (e.g.
* -EBUSY if a GPIO was already requested)
*/
int gpio_request_by_name(struct udevice *dev, const char *list_name,
int index, struct gpio_desc *desc, int flags);
/* gpio_request_by_line_name - Locate and request a GPIO by line name
*
* Request a GPIO using the offset of the provided line name in the
* gpio-line-names property found in the OF node of the GPIO udevice.
*
* This allows boards to implement common behaviours using GPIOs while not
* requiring specific GPIO offsets be used.
*
* @dev: An instance of a GPIO controller udevice, or NULL to search
* all GPIO controller devices
* @line_name: The name of the GPIO (e.g. "bmc-secure-boot")
* @desc: A GPIO descriptor that is populated with the requested GPIO
* upon return
* @flags: The GPIO settings apply to the request
* @return 0 if the named line was found and requested successfully, or a
* negative error code if the GPIO cannot be found or the request failed.
*/
int gpio_request_by_line_name(struct udevice *dev, const char *line_name,
struct gpio_desc *desc, int flags);
/**
* gpio_request_list_by_name() - Request a list of GPIOs
*
* Reads all the GPIOs from a list and requests them. See
* gpio_request_by_name() for additional details. Lists should not be
* misused to hold unrelated or optional GPIOs. They should only be used
* for things like parallel data lines. A zero phandle terminates the list
* the list.
*
* This function will either succeed, and request all GPIOs in the list, or
* fail and request none (it will free already-requested GPIOs in case of
* an error part-way through).
*
* @dev: Device requesting the GPIO
* @list_name: Name of GPIO list (e.g. "board-id-gpios")
* @desc_list: Returns a list of GPIO description information
* @max_count: Maximum number of GPIOs to return (@desc_list must be at least
* this big)
* @flags: Indicates the GPIO input/output settings (GPIOD_...)
* Return: number of GPIOs requested, or -ve on error
*/
int gpio_request_list_by_name(struct udevice *dev, const char *list_name,
struct gpio_desc *desc_list, int max_count,
int flags);
/**
* dm_gpio_request() - manually request a GPIO
*
* Note: This function should only be used for testing / debugging. Instead.
* use gpio_request_by_name() to pull GPIOs from the device tree.
*
* @desc: GPIO description of GPIO to request (see dm_gpio_lookup_name())
* @label: Label to attach to the GPIO while claimed
* Return: 0 if OK, -ve on error
*/
int dm_gpio_request(struct gpio_desc *desc, const char *label);
struct phandle_2_arg;
int gpio_request_by_phandle(struct udevice *dev,
const struct phandle_2_arg *cells,
struct gpio_desc *desc, int flags);
/**
* gpio_get_list_count() - Returns the number of GPIOs in a list
*
* Counts the GPIOs in a list. See gpio_request_by_name() for additional
* details.
*
* @dev: Device requesting the GPIO
* @list_name: Name of GPIO list (e.g. "board-id-gpios")
* Return: number of GPIOs (0 for an empty property) or -ENOENT if the list
* does not exist
*/
int gpio_get_list_count(struct udevice *dev, const char *list_name);
/**
* gpio_request_by_name_nodev() - request GPIOs without a device
*
* This is a version of gpio_request_list_by_name() that does not use a
* device. Avoid it unless the caller is not yet using driver model
*/
int gpio_request_by_name_nodev(ofnode node, const char *list_name, int index,
struct gpio_desc *desc, int flags);
/**
* gpio_request_list_by_name_nodev() - request GPIOs without a device
*
* This is a version of gpio_request_list_by_name() that does not use a
* device. Avoid it unless the caller is not yet using driver model
*/
int gpio_request_list_by_name_nodev(ofnode node, const char *list_name,
struct gpio_desc *desc_list, int max_count,
int flags);
/**
* gpio_dev_request_index() - request single GPIO from gpio device
*
* @dev: GPIO device
* @nodename: Name of node for which gpio gets requested, used
* for the gpio label name
* @list_name: Name of GPIO list (e.g. "board-id-gpios")
* @index: Index number of the GPIO in that list use request (0=first)
* @flags: GPIOD_* flags
* @dtflags: GPIO flags read from DT defined see GPIOD_*
* @desc: returns GPIO descriptor filled from this function
* @return: return value from gpio_request_tail()
*/
int gpio_dev_request_index(struct udevice *dev, const char *nodename,
char *list_name, int index, int flags,
int dtflags, struct gpio_desc *desc);
/**
* dm_gpio_free() - Free a single GPIO
*
* This frees a single GPIOs previously returned from gpio_request_by_name().
*
* @dev: Device which requested the GPIO
* @desc: GPIO to free
* Return: 0 if OK, -ve on error
*/
int dm_gpio_free(struct udevice *dev, struct gpio_desc *desc);
/**
* gpio_free_list() - Free a list of GPIOs
*
* This frees a list of GPIOs previously returned from
* gpio_request_list_by_name().
*
* @dev: Device which requested the GPIOs
* @desc: List of GPIOs to free
* @count: Number of GPIOs in the list
* Return: 0 if OK, -ve on error
*/
int gpio_free_list(struct udevice *dev, struct gpio_desc *desc, int count);
/**
* gpio_free_list_nodev() - free GPIOs without a device
*
* This is a version of gpio_free_list() that does not use a
* device. Avoid it unless the caller is not yet using driver model
*/
int gpio_free_list_nodev(struct gpio_desc *desc, int count);
/**
* dm_gpio_get_value() - Get the value of a GPIO
*
* This is the driver model version of the existing gpio_get_value() function
* and should be used instead of that.
*
* For now, these functions have a dm_ prefix since they conflict with
* existing names.
*
* @desc: GPIO description containing device, offset and flags,
* previously returned by gpio_request_by_name()
* Return: GPIO value (0 for inactive, 1 for active) or -ve on error
*/
int dm_gpio_get_value(const struct gpio_desc *desc);
int dm_gpio_set_value(const struct gpio_desc *desc, int value);
/**
* dm_gpio_clrset_flags() - Update flags
*
* This updates the flags as directled. Note that desc->flags is updated by this
* function on success. If any changes cannot be made, best efforts are made.
*
* By use of @clr and @set any of flags can be individually updated, or left
* alone
*
* @desc: GPIO description containing device, offset and flags,
* previously returned by gpio_request_by_name()
* @clr: Flags to clear (GPIOD_...)
* @set: Flags to set (GPIOD_...)
* Return: 0 if OK, -EINVAL if the flags had obvious conflicts,
* -ERECALLCONFLICT if there was a non-obvious hardware conflict when attempting
* to set the flags
*/
int dm_gpio_clrset_flags(struct gpio_desc *desc, ulong clr, ulong set);
/**
* dm_gpio_set_dir_flags() - Set direction using description and added flags
*
* This sets up the direction according to the provided flags and the GPIO
* description (desc->flags) which include direction information.
* Note that desc->flags is updated by this function.
*
* @desc: GPIO description containing device, offset and flags,
* previously returned by gpio_request_by_name()
* @flags: New flags to use
* Return: 0 if OK, -ve on error, in which case desc->flags is not updated
*/
int dm_gpio_set_dir_flags(struct gpio_desc *desc, ulong flags);
/**
* dm_gpios_clrset_flags() - Sets flags for a set of GPIOs
*
* This clears and sets flags individually for each GPIO.
*
* @desc: List of GPIOs to update
* @count: Number of GPIOs in the list
* @clr: Flags to clear (GPIOD_...), e.g. GPIOD_MASK_DIR if you are
* changing the direction
* @set: Flags to set (GPIOD_...)
* Return: 0 if OK, -ve on error
*/
int dm_gpios_clrset_flags(struct gpio_desc *desc, int count, ulong clr,
ulong set);
/**
* dm_gpio_get_flags() - Get flags
*
* Read the current flags
*
* @desc: GPIO description containing device, offset and flags,
* previously returned by gpio_request_by_name()
* @flags: place to put the used flags
* Return: 0 if OK, -ve on error, in which case desc->flags is not updated
*/
int dm_gpio_get_flags(struct gpio_desc *desc, ulong *flags);
/**
* gpio_get_number() - Get the global GPIO number of a GPIO
*
* This should only be used for debugging or interest. It returns the number
* that should be used for gpio_get_value() etc. to access this GPIO.
*
* @desc: GPIO description containing device, offset and flags,
* previously returned by gpio_request_by_name()
* Return: GPIO number, or -ve if not found
*/
int gpio_get_number(const struct gpio_desc *desc);
/**
* gpio_get_acpi() - Get the ACPI pin for a GPIO
*
* This converts a GPIO to an ACPI pin number for adding to the ACPI
* tables. If the GPIO is invalid, the pin_count and pins[0] are set to 0
*
* @desc: GPIO description to convert
* @gpio: Output ACPI GPIO information
* Return: ACPI pin number or -ve on error
*/
int gpio_get_acpi(const struct gpio_desc *desc, struct acpi_gpio *gpio);
/**
* devm_gpiod_get_index - Resource-managed gpiod_get()
* @dev: GPIO consumer
* @con_id: function within the GPIO consumer
* @index: index of the GPIO to obtain in the consumer
* @flags: optional GPIO initialization flags
*
* Managed gpiod_get(). GPIO descriptors returned from this function are
* automatically disposed on device unbind.
* Return the GPIO descriptor corresponding to the function con_id of device
* dev, -ENOENT if no GPIO has been assigned to the requested function, or
* another IS_ERR() code if an error occurred while trying to acquire the GPIO.
*/
struct gpio_desc *devm_gpiod_get_index(struct udevice *dev, const char *id,
unsigned int index, int flags);
#define devm_gpiod_get(dev, id, flags) devm_gpiod_get_index(dev, id, 0, flags)
/**
* gpiod_get_optional - obtain an optional GPIO for a given GPIO function
* @dev: GPIO consumer, can be NULL for system-global GPIOs
* @con_id: function within the GPIO consumer
* @index: index of the GPIO to obtain in the consumer
* @flags: optional GPIO initialization flags
*
* This is equivalent to devm_gpiod_get(), except that when no GPIO was
* assigned to the requested function it will return NULL. This is convenient
* for drivers that need to handle optional GPIOs.
*/
struct gpio_desc *devm_gpiod_get_index_optional(struct udevice *dev,
const char *id,
unsigned int index,
int flags);
#define devm_gpiod_get_optional(dev, id, flags) \
devm_gpiod_get_index_optional(dev, id, 0, flags)
/**
* devm_gpiod_put - Resource-managed gpiod_put()
* @dev: GPIO consumer
* @desc: GPIO descriptor to dispose of
*
* Dispose of a GPIO descriptor obtained with devm_gpiod_get() or
* devm_gpiod_get_index(). Normally this function will not be called as the GPIO
* will be disposed of by the resource management code.
*/
void devm_gpiod_put(struct udevice *dev, struct gpio_desc *desc);
#endif /* _ASM_GENERIC_GPIO_H_ */
+46
View File
@@ -0,0 +1,46 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* asm-generic/int-ll64.h
*
* Integer declarations for architectures which use "long long"
* for 64-bit types.
*/
#ifndef _ASM_GENERIC_INT_LL64_H
#define _ASM_GENERIC_INT_LL64_H
#ifndef __ASSEMBLY__
/*
* __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
* header files exported to user space
*/
typedef __signed__ char __s8;
typedef unsigned char __u8;
typedef __signed__ short __s16;
typedef unsigned short __u16;
typedef __signed__ int __s32;
typedef unsigned int __u32;
#ifdef __GNUC__
__extension__ typedef __signed__ long long __s64;
__extension__ typedef unsigned long long __u64;
#else
typedef __signed__ long long __s64;
typedef unsigned long long __u64;
#endif
typedef __s8 s8;
typedef __u8 u8;
typedef __s16 s16;
typedef __u16 u16;
typedef __s32 s32;
typedef __u32 u32;
typedef __s64 s64;
typedef __u64 u64;
#endif /* __ASSEMBLY__ */
#endif /* _ASM_GENERIC_INT_LL64_H */
+457
View File
@@ -0,0 +1,457 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Generic I/O functions.
*
* Copyright (c) 2016 Imagination Technologies Ltd.
*/
#ifndef __ASM_GENERIC_IO_H__
#define __ASM_GENERIC_IO_H__
/*
* This file should be included at the end of each architecture-specific
* asm/io.h such that we may provide generic implementations without
* conflicting with architecture-specific code.
*/
#ifndef __ASSEMBLY__
/**
* phys_to_virt() - Return a virtual address mapped to a given physical address
* @paddr: the physical address
*
* Returns a virtual address which the CPU can access that maps to the physical
* address @paddr. This should only be used where it is known that no dynamic
* mapping is required. In general, map_physmem should be used instead.
*
* Returns: a virtual address which maps to @paddr
*/
#ifndef phys_to_virt
static inline void *phys_to_virt(phys_addr_t paddr)
{
return (void *)(unsigned long)paddr;
}
#endif
/**
* virt_to_phys() - Return the physical address that a virtual address maps to
* @vaddr: the virtual address
*
* Returns the physical address which the CPU-accessible virtual address @vaddr
* maps to.
*
* Returns: the physical address which @vaddr maps to
*/
#ifndef virt_to_phys
static inline phys_addr_t virt_to_phys(void *vaddr)
{
return (phys_addr_t)((unsigned long)vaddr);
}
#endif
/*
* Flags for use with map_physmem() & unmap_physmem(). Architectures need not
* support all of these, in which case they will be defined as zero here &
* ignored. Callers that may run on multiple architectures should therefore
* treat them as hints rather than requirements.
*/
#ifndef MAP_NOCACHE
# define MAP_NOCACHE 0 /* Produce an uncached mapping */
#endif
#ifndef MAP_WRCOMBINE
# define MAP_WRCOMBINE 0 /* Allow write-combining on the mapping */
#endif
#ifndef MAP_WRBACK
# define MAP_WRBACK 0 /* Map using write-back caching */
#endif
#ifndef MAP_WRTHROUGH
# define MAP_WRTHROUGH 0 /* Map using write-through caching */
#endif
/**
* map_physmem() - Return a virtual address mapped to a given physical address
* @paddr: the physical address
* @len: the length of the required mapping
* @flags: flags affecting the type of mapping
*
* Return a virtual address through which the CPU may access the memory at
* physical address @paddr. The mapping will be valid for at least @len bytes,
* and may be affected by flags passed to the @flags argument. This function
* may create new mappings, so should generally be paired with a matching call
* to unmap_physmem once the caller is finished with the memory in question.
*
* Returns: a virtual address suitably mapped to @paddr
*/
#ifndef map_physmem
static inline void *map_physmem(phys_addr_t paddr, unsigned long len,
unsigned long flags)
{
return phys_to_virt(paddr);
}
#endif
/**
* unmap_physmem() - Remove mappings created by a prior call to map_physmem()
* @vaddr: the virtual address which map_physmem() previously returned
* @flags: flags matching those originally passed to map_physmem()
*
* Unmap memory which was previously mapped by a call to map_physmem(). If
* map_physmem() dynamically created a mapping for the memory in question then
* unmap_physmem() will remove that mapping.
*/
#ifndef unmap_physmem
static inline void unmap_physmem(void *vaddr, unsigned long flags)
{
}
#endif
/*
* __raw_{read,write}{b,w,l,q}() access memory in native endianness.
*
* On some architectures memory mapped IO needs to be accessed differently.
* On the simple architectures, we just read/write the memory location
* directly.
*/
#ifndef __raw_readb
#define __raw_readb __raw_readb
static inline u8 __raw_readb(const volatile void __iomem *addr)
{
return *(const volatile u8 __force *)addr;
}
#endif
#ifndef __raw_readw
#define __raw_readw __raw_readw
static inline u16 __raw_readw(const volatile void __iomem *addr)
{
return *(const volatile u16 __force *)addr;
}
#endif
#ifndef __raw_readl
#define __raw_readl __raw_readl
static inline u32 __raw_readl(const volatile void __iomem *addr)
{
return *(const volatile u32 __force *)addr;
}
#endif
#ifdef CONFIG_64BIT
#ifndef __raw_readq
#define __raw_readq __raw_readq
static inline u64 __raw_readq(const volatile void __iomem *addr)
{
return *(const volatile u64 __force *)addr;
}
#endif
#endif /* CONFIG_64BIT */
#ifndef __raw_writeb
#define __raw_writeb __raw_writeb
static inline void __raw_writeb(u8 value, volatile void __iomem *addr)
{
*(volatile u8 __force *)addr = value;
}
#endif
#ifndef __raw_writew
#define __raw_writew __raw_writew
static inline void __raw_writew(u16 value, volatile void __iomem *addr)
{
*(volatile u16 __force *)addr = value;
}
#endif
#ifndef __raw_writel
#define __raw_writel __raw_writel
static inline void __raw_writel(u32 value, volatile void __iomem *addr)
{
*(volatile u32 __force *)addr = value;
}
#endif
#ifdef CONFIG_64BIT
#ifndef __raw_writeq
#define __raw_writeq __raw_writeq
static inline void __raw_writeq(u64 value, volatile void __iomem *addr)
{
*(volatile u64 __force *)addr = value;
}
#endif
#endif /* CONFIG_64BIT */
/*
* {read,write}s{b,w,l,q}() repeatedly access the same memory address in
* native endianness in 8-, 16-, 32- or 64-bit chunks (@count times).
*/
#ifndef readsb
#define readsb readsb
static inline void readsb(const volatile void __iomem *addr, void *buffer,
unsigned int count)
{
if (count) {
u8 *buf = buffer;
do {
u8 x = __raw_readb(addr);
*buf++ = x;
} while (--count);
}
}
#endif
#ifndef readsw
#define readsw readsw
static inline void readsw(const volatile void __iomem *addr, void *buffer,
unsigned int count)
{
if (count) {
u16 *buf = buffer;
do {
u16 x = __raw_readw(addr);
*buf++ = x;
} while (--count);
}
}
#endif
#ifndef readsl
#define readsl readsl
static inline void readsl(const volatile void __iomem *addr, void *buffer,
unsigned int count)
{
if (count) {
u32 *buf = buffer;
do {
u32 x = __raw_readl(addr);
*buf++ = x;
} while (--count);
}
}
#endif
#ifdef CONFIG_64BIT
#ifndef readsq
#define readsq readsq
static inline void readsq(const volatile void __iomem *addr, void *buffer,
unsigned int count)
{
if (count) {
u64 *buf = buffer;
do {
u64 x = __raw_readq(addr);
*buf++ = x;
} while (--count);
}
}
#endif
#endif /* CONFIG_64BIT */
#ifndef writesb
#define writesb writesb
static inline void writesb(volatile void __iomem *addr, const void *buffer,
unsigned int count)
{
if (count) {
const u8 *buf = buffer;
do {
__raw_writeb(*buf++, addr);
} while (--count);
}
}
#endif
#ifndef writesw
#define writesw writesw
static inline void writesw(volatile void __iomem *addr, const void *buffer,
unsigned int count)
{
if (count) {
const u16 *buf = buffer;
do {
__raw_writew(*buf++, addr);
} while (--count);
}
}
#endif
#ifndef writesl
#define writesl writesl
static inline void writesl(volatile void __iomem *addr, const void *buffer,
unsigned int count)
{
if (count) {
const u32 *buf = buffer;
do {
__raw_writel(*buf++, addr);
} while (--count);
}
}
#endif
#ifdef CONFIG_64BIT
#ifndef writesq
#define writesq writesq
static inline void writesq(volatile void __iomem *addr, const void *buffer,
unsigned int count)
{
if (count) {
const u64 *buf = buffer;
do {
__raw_writeq(*buf++, addr);
} while (--count);
}
}
#endif
#endif /* CONFIG_64BIT */
#ifndef PCI_IOBASE
#define PCI_IOBASE ((void __iomem *)0)
#endif
/*
* {in,out}s{b,w,l}{,_p}() are variants of the above that repeatedly access a
* single I/O port multiple times.
*/
#ifndef insb
#define insb insb
static inline void insb(unsigned long addr, void *buffer, unsigned int count)
{
readsb(PCI_IOBASE + addr, buffer, count);
}
#endif
#ifndef insw
#define insw insw
static inline void insw(unsigned long addr, void *buffer, unsigned int count)
{
readsw(PCI_IOBASE + addr, buffer, count);
}
#endif
#ifndef insl
#define insl insl
static inline void insl(unsigned long addr, void *buffer, unsigned int count)
{
readsl(PCI_IOBASE + addr, buffer, count);
}
#endif
#ifndef outsb
#define outsb outsb
static inline void outsb(unsigned long addr, const void *buffer,
unsigned int count)
{
writesb(PCI_IOBASE + addr, buffer, count);
}
#endif
#ifndef outsw
#define outsw outsw
static inline void outsw(unsigned long addr, const void *buffer,
unsigned int count)
{
writesw(PCI_IOBASE + addr, buffer, count);
}
#endif
#ifndef outsl
#define outsl outsl
static inline void outsl(unsigned long addr, const void *buffer,
unsigned int count)
{
writesl(PCI_IOBASE + addr, buffer, count);
}
#endif
#ifndef ioread8_rep
#define ioread8_rep ioread8_rep
static inline void ioread8_rep(const volatile void __iomem *addr, void *buffer,
unsigned int count)
{
readsb(addr, buffer, count);
}
#endif
#ifndef ioread16_rep
#define ioread16_rep ioread16_rep
static inline void ioread16_rep(const volatile void __iomem *addr,
void *buffer, unsigned int count)
{
readsw(addr, buffer, count);
}
#endif
#ifndef ioread32_rep
#define ioread32_rep ioread32_rep
static inline void ioread32_rep(const volatile void __iomem *addr,
void *buffer, unsigned int count)
{
readsl(addr, buffer, count);
}
#endif
#ifdef CONFIG_64BIT
#ifndef ioread64_rep
#define ioread64_rep ioread64_rep
static inline void ioread64_rep(const volatile void __iomem *addr,
void *buffer, unsigned int count)
{
readsq(addr, buffer, count);
}
#endif
#endif /* CONFIG_64BIT */
#ifndef iowrite8_rep
#define iowrite8_rep iowrite8_rep
static inline void iowrite8_rep(volatile void __iomem *addr,
const void *buffer,
unsigned int count)
{
writesb(addr, buffer, count);
}
#endif
#ifndef iowrite16_rep
#define iowrite16_rep iowrite16_rep
static inline void iowrite16_rep(volatile void __iomem *addr,
const void *buffer,
unsigned int count)
{
writesw(addr, buffer, count);
}
#endif
#ifndef iowrite32_rep
#define iowrite32_rep iowrite32_rep
static inline void iowrite32_rep(volatile void __iomem *addr,
const void *buffer,
unsigned int count)
{
writesl(addr, buffer, count);
}
#endif
#ifdef CONFIG_64BIT
#ifndef iowrite64_rep
#define iowrite64_rep iowrite64_rep
static inline void iowrite64_rep(volatile void __iomem *addr,
const void *buffer,
unsigned int count)
{
writesq(addr, buffer, count);
}
#endif
#endif /* CONFIG_64BIT */
#endif /* !__ASSEMBLY__ */
#endif /* __ASM_GENERIC_IO_H__ */
+105
View File
@@ -0,0 +1,105 @@
#ifndef _ASM_GENERIC_IOCTL_H
#define _ASM_GENERIC_IOCTL_H
/* ioctl command encoding: 32 bits total, command in lower 16 bits,
* size of the parameter structure in the lower 14 bits of the
* upper 16 bits.
* Encoding the size of the parameter structure in the ioctl request
* is useful for catching programs compiled with old versions
* and to avoid overwriting user space outside the user buffer area.
* The highest 2 bits are reserved for indicating the ``access mode''.
* NOTE: This limits the max parameter size to 16kB -1 !
*/
/*
* The following is for compatibility across the various Linux
* platforms. The generic ioctl numbering scheme doesn't really enforce
* a type field. De facto, however, the top 8 bits of the lower 16
* bits are indeed used as a type field, so we might just as well make
* this explicit here. Please be sure to use the decoding macros
* below from now on.
*/
#define _IOC_NRBITS 8
#define _IOC_TYPEBITS 8
/*
* Let any architecture override either of the following before
* including this file.
*/
#ifndef _IOC_SIZEBITS
# define _IOC_SIZEBITS 14
#endif
#ifndef _IOC_DIRBITS
# define _IOC_DIRBITS 2
#endif
#define _IOC_NRMASK ((1 << _IOC_NRBITS)-1)
#define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1)
#define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1)
#define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1)
#define _IOC_NRSHIFT 0
#define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS)
#define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS)
#define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS)
/*
* Direction bits, which any architecture can choose to override
* before including this file.
*/
#ifndef _IOC_NONE
# define _IOC_NONE 0U
#endif
#ifndef _IOC_WRITE
# define _IOC_WRITE 1U
#endif
#ifndef _IOC_READ
# define _IOC_READ 2U
#endif
#define _IOC(dir,type,nr,size) \
(((dir) << _IOC_DIRSHIFT) | \
((type) << _IOC_TYPESHIFT) | \
((nr) << _IOC_NRSHIFT) | \
((size) << _IOC_SIZESHIFT))
#ifdef __KERNEL__
/* provoke compile error for invalid uses of size argument */
extern unsigned int __invalid_size_argument_for_IOC;
#define _IOC_TYPECHECK(t) \
((sizeof(t) == sizeof(t[1]) && \
sizeof(t) < (1 << _IOC_SIZEBITS)) ? \
sizeof(t) : __invalid_size_argument_for_IOC)
#else
#define _IOC_TYPECHECK(t) (sizeof(t))
#endif
/* used to create numbers */
#define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0)
#define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size)))
#define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
#define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size)))
#define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size))
#define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size))
#define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
/* used to decode ioctl numbers.. */
#define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
#define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
#define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
#define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
/* ...and for the drivers/sound files... */
#define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT)
#define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT)
#define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT)
#define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT)
#define IOCSIZE_SHIFT (_IOC_SIZESHIFT)
#endif /* _ASM_GENERIC_IOCTL_H */
+72
View File
@@ -0,0 +1,72 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Portable Executable and Common Object Constants
*
* Copyright (c) 2018 Heinrich Schuchardt
*
* based on the "Microsoft Portable Executable and Common Object File Format
* Specification", revision 11, 2017-01-23
*/
#ifndef _ASM_PE_H
#define _ASM_PE_H
/* Characteristics */
#define IMAGE_FILE_RELOCS_STRIPPED 0x0001
#define IMAGE_FILE_EXECUTABLE_IMAGE 0x0002
#define IMAGE_FILE_LINE_NUMS_STRIPPED 0x0004
#define IMAGE_FILE_LOCAL_SYMS_STRIPPED 0x0008
#define IMAGE_FILE_AGGRESSIVE_WS_TRIM 0x0010
#define IMAGE_FILE_LARGE_ADDRESS_AWARE 0x0020
/* Reserved 0x0040 */
#define IMAGE_FILE_BYTES_REVERSED_LO 0x0080
#define IMAGE_FILE_32BIT_MACHINE 0x0100
#define IMAGE_FILE_DEBUG_STRIPPED 0x0200
#define IMAGE_FILE_REMOVABLE_RUN_FROM_SWAP 0x0400
#define IMAGE_FILE_NET_RUN_FROM_SWAP 0x0800
#define IMAGE_FILE_SYSTEM 0x1000
#define IMAGE_FILE_DLL 0x2000
#define IMAGE_FILE_UP_SYSTEM_ONLY 0x4000
#define IMAGE_FILE_BYTES_REVERSED_HI 0x8000
/* Machine types */
#define IMAGE_FILE_MACHINE_I386 0x014c
#define IMAGE_FILE_MACHINE_ARM 0x01c0
#define IMAGE_FILE_MACHINE_THUMB 0x01c2
#define IMAGE_FILE_MACHINE_ARMNT 0x01c4
#define IMAGE_FILE_MACHINE_AMD64 0x8664
#define IMAGE_FILE_MACHINE_ARM64 0xaa64
#define IMAGE_FILE_MACHINE_RISCV32 0x5032
#define IMAGE_FILE_MACHINE_RISCV64 0x5064
/* Header magic constants */
#define IMAGE_NT_OPTIONAL_HDR32_MAGIC 0x010b
#define IMAGE_NT_OPTIONAL_HDR64_MAGIC 0x020b
#define IMAGE_DOS_SIGNATURE 0x5a4d /* MZ */
#define IMAGE_NT_SIGNATURE 0x00004550 /* PE00 */
/* Subsystem type */
#define IMAGE_SUBSYSTEM_EFI_APPLICATION 10
#define IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER 11
#define IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER 12
#define IMAGE_SUBSYSTEM_EFI_ROM 13
/* DLL characteristics */
#define IMAGE_DLLCHARACTERISTICS_NX_COMPAT 0x100
/* Section flags */
#define IMAGE_SCN_CNT_CODE 0x00000020
#define IMAGE_SCN_CNT_INITIALIZED_DATA 0x00000040
#define IMAGE_SCN_CNT_UNINITIALIZED_ DATA 0x00000080
#define IMAGE_SCN_LNK_NRELOC_OVFL 0x01000000
#define IMAGE_SCN_MEM_DISCARDABLE 0x02000000
#define IMAGE_SCN_MEM_NOT_CACHED 0x04000000
#define IMAGE_SCN_MEM_NOT_PAGED 0x08000000
#define IMAGE_SCN_MEM_SHARED 0x10000000
#define IMAGE_SCN_MEM_EXECUTE 0x20000000
#define IMAGE_SCN_MEM_READ 0x40000000
#define IMAGE_SCN_MEM_WRITE 0x80000000
#define LINUX_ARM64_MAGIC 0x644d5241
#endif /* _ASM_PE_H */
+119
View File
@@ -0,0 +1,119 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2011 The Chromium OS Authors.
*/
/* Taken from Linux kernel, commit f56c3196 */
#ifndef _ASM_GENERIC_SECTIONS_H_
#define _ASM_GENERIC_SECTIONS_H_
#include <linux/types.h>
#include <stdbool.h>
/* References to section boundaries */
extern char _text[], _stext[], _etext[];
extern char _data[], _sdata[], _edata[];
extern char __bss_start[], __bss_stop[];
extern char __init_begin[], __init_end[];
extern char _sinittext[], _einittext[];
extern char _end[], _init[];
extern char __per_cpu_load[], __per_cpu_start[], __per_cpu_end[];
extern char __kprobes_text_start[], __kprobes_text_end[];
extern char __entry_text_start[], __entry_text_end[];
extern char __initdata_begin[], __initdata_end[];
extern char __start_rodata[], __end_rodata[];
extern char __start_data[], __end_data[];
extern char __efi_helloworld_begin[];
extern char __efi_helloworld_end[];
extern char __efi_var_file_begin[];
extern char __efi_var_file_end[];
extern char __efi_capsule_sig_begin[];
extern char __efi_capsule_sig_end[];
/* Private data used by of-platdata devices/uclasses */
extern char __priv_data_start[], __priv_data_end[];
/* Start and end of .ctors section - used for constructor calls. */
extern char __ctors_start[], __ctors_end[];
extern char __efi_runtime_rel_start[], __efi_runtime_rel_stop[];
extern char __efi_runtime_start[], __efi_runtime_stop[];
/* function descriptor handling (if any). Override
* in asm/sections.h */
#ifndef dereference_function_descriptor
#define dereference_function_descriptor(p) (p)
#endif
/* random extra sections (if any). Override
* in asm/sections.h */
#ifndef arch_is_kernel_text
static inline int arch_is_kernel_text(unsigned long addr)
{
return 0;
}
#endif
#ifndef arch_is_kernel_data
static inline int arch_is_kernel_data(unsigned long addr)
{
return 0;
}
#endif
/**
* is_kernel_rodata - checks if the pointer address is located in the
* .rodata section
*
* @addr: address to check
*
* Returns: true if the address is located in .rodata, false otherwise.
*/
static inline bool is_kernel_rodata(unsigned long addr)
{
#ifdef CONFIG_ARM64
return addr >= (unsigned long)__start_rodata &&
addr < (unsigned long)__end_rodata;
#else
return false;
#endif
}
/* U-Boot-specific things begin here */
/* Start of U-Boot text region */
extern char __text_start[];
extern char __text_end[];
/* This marks the text region which must be relocated */
extern char __image_copy_start[], __image_copy_end[];
/* This marks the rcode region used for SPL relocation */
extern char _rcode_start[], _rcode_end[];
extern char __bss_end[];
extern char __rel_dyn_start[], __rel_dyn_end[];
extern char _image_binary_end[];
/*
* This is the U-Boot entry point - prior to relocation it should be same
* as __text_start
*/
extern void _start(void);
#ifndef USE_HOSTCC
#if CONFIG_IS_ENABLED(RELOC_LOADER)
#define __rcode __section(".text.rcode")
#define __rdata __section(".text.rdata")
#else
#define __rcode
#define __rdata
#endif
#else
#define __rcode
#define __rdata
#endif
#endif /* _ASM_GENERIC_SECTIONS_H_ */
+101
View File
@@ -0,0 +1,101 @@
#ifndef __ASM_GENERIC_SIGNAL_H
#define __ASM_GENERIC_SIGNAL_H
#include <linux/types.h>
#define _NSIG 64
#define _NSIG_BPW BITS_PER_LONG
#define _NSIG_WORDS (_NSIG / _NSIG_BPW)
#define SIGHUP 1
#define SIGINT 2
#define SIGQUIT 3
#define SIGILL 4
#define SIGTRAP 5
#define SIGABRT 6
#define SIGIOT 6
#define SIGBUS 7
#define SIGFPE 8
#define SIGKILL 9
#define SIGUSR1 10
#define SIGSEGV 11
#define SIGUSR2 12
#define SIGPIPE 13
#define SIGALRM 14
#define SIGTERM 15
#define SIGSTKFLT 16
#define SIGCHLD 17
#define SIGCONT 18
#define SIGSTOP 19
#define SIGTSTP 20
#define SIGTTIN 21
#define SIGTTOU 22
#define SIGURG 23
#define SIGXCPU 24
#define SIGXFSZ 25
#define SIGVTALRM 26
#define SIGPROF 27
#define SIGWINCH 28
#define SIGIO 29
#define SIGPOLL SIGIO
/*
#define SIGLOST 29
*/
#define SIGPWR 30
#define SIGSYS 31
#define SIGUNUSED 31
/* These should not be considered constants from userland. */
#define SIGRTMIN 32
#ifndef SIGRTMAX
#define SIGRTMAX _NSIG
#endif
/*
* SA_FLAGS values:
*
* SA_ONSTACK indicates that a registered stack_t will be used.
* SA_RESTART flag to get restarting signals (which were the default long ago)
* SA_NOCLDSTOP flag to turn off SIGCHLD when children stop.
* SA_RESETHAND clears the handler when the signal is delivered.
* SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies.
* SA_NODEFER prevents the current signal from being masked in the handler.
*
* SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single
* Unix names RESETHAND and NODEFER respectively.
*/
#define SA_NOCLDSTOP 0x00000001
#define SA_NOCLDWAIT 0x00000002
#define SA_SIGINFO 0x00000004
#define SA_ONSTACK 0x08000000
#define SA_RESTART 0x10000000
#define SA_NODEFER 0x40000000
#define SA_RESETHAND 0x80000000
#define SA_NOMASK SA_NODEFER
#define SA_ONESHOT SA_RESETHAND
/*
* New architectures should not define the obsolete
* SA_RESTORER 0x04000000
*/
/*
* sigaltstack controls
*/
#define SS_ONSTACK 1
#define SS_DISABLE 2
#define MINSIGSTKSZ 2048
#define SIGSTKSZ 8192
#ifndef __ASSEMBLY__
typedef struct {
unsigned long sig[_NSIG_WORDS];
} sigset_t;
/* not actually used, but required for linux/syscalls.h */
#endif /* __ASSEMBLY__ */
#endif /* _ASM_GENERIC_SIGNAL_H */
+70
View File
@@ -0,0 +1,70 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2011 The Chromium OS Authors.
*
* (C) Copyright 2000 - 2002
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
********************************************************************
* NOTE: This header file defines an interface to U-Boot. Including
* this (unmodified) header file in another file is considered normal
* use of U-Boot, and does *not* fall under the heading of "derived
* work".
********************************************************************
*/
#ifndef __ASM_GENERIC_U_BOOT_H__
#define __ASM_GENERIC_U_BOOT_H__
/*
* Board information passed to Linux kernel from U-Boot
*
* include/asm-ppc/u-boot.h
*/
#ifndef __ASSEMBLY__
#include <asm/types.h>
#include <linux/types.h>
struct bd_info {
unsigned long bi_flashstart; /* start of FLASH memory */
unsigned long bi_flashsize; /* size of FLASH memory */
unsigned long bi_flashoffset; /* reserved area for startup monitor */
#ifdef CONFIG_ARM
unsigned long bi_arm_freq; /* arm frequency */
unsigned long bi_dsp_freq; /* dsp core frequency */
unsigned long bi_ddr_freq; /* ddr frequency */
#endif
#if defined(CONFIG_MPC8xx) || defined(CONFIG_E500) || defined(CONFIG_MPC86xx)
unsigned long bi_immr_base; /* base of IMMR register */
#endif
#if defined(CONFIG_M68K)
unsigned long bi_mbar_base; /* base of internal registers */
#endif
#if defined(CONFIG_MPC83xx)
unsigned long bi_immrbar;
#endif
unsigned long bi_bootflags; /* boot / reboot flag (Unused) */
unsigned long bi_ip_addr; /* IP Address */
unsigned short bi_ethspeed; /* Ethernet speed in Mbps */
unsigned long bi_intfreq; /* Internal Freq, in MHz */
unsigned long bi_busfreq; /* Bus Freq, in MHz */
#if defined(CONFIG_M68K)
unsigned long bi_pcifreq; /* PCI Bus Freq, in MHz */
#endif
#if defined(CONFIG_EXTRA_CLOCK)
unsigned long bi_inpfreq; /* input Freq in MHz */
unsigned long bi_vcofreq; /* vco Freq in MHz */
unsigned long bi_flbfreq; /* Flexbus Freq in MHz */
#endif
ulong bi_arch_number; /* unique id for this board */
ulong bi_boot_params; /* where this board expects params */
struct { /* RAM configuration */
phys_addr_t start;
phys_size_t size;
} bi_dram[CONFIG_NR_DRAM_BANKS];
};
#endif /* __ASSEMBLY__ */
#endif /* __ASM_GENERIC_U_BOOT_H__ */
+83
View File
@@ -0,0 +1,83 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _GENERIC_UNALIGNED_H
#define _GENERIC_UNALIGNED_H
#include <asm/byteorder.h>
#define __get_unaligned_t(type, ptr) ({ \
const struct { type x; } __packed * __pptr = (typeof(__pptr))(ptr); \
__pptr->x; \
})
#define __put_unaligned_t(type, val, ptr) do { \
struct { type x; } __packed * __pptr = (typeof(__pptr))(ptr); \
__pptr->x = (val); \
} while (0)
#define get_unaligned(ptr) __get_unaligned_t(typeof(*(ptr)), (ptr))
#define put_unaligned(val, ptr) __put_unaligned_t(typeof(*(ptr)), (val), (ptr))
static inline u16 get_unaligned_le16(const void *p)
{
return le16_to_cpu(__get_unaligned_t(__le16, p));
}
static inline u32 get_unaligned_le32(const void *p)
{
return le32_to_cpu(__get_unaligned_t(__le32, p));
}
static inline u64 get_unaligned_le64(const void *p)
{
return le64_to_cpu(__get_unaligned_t(__le64, p));
}
static inline void put_unaligned_le16(u16 val, void *p)
{
__put_unaligned_t(__le16, cpu_to_le16(val), p);
}
static inline void put_unaligned_le32(u32 val, void *p)
{
__put_unaligned_t(__le32, cpu_to_le32(val), p);
}
static inline void put_unaligned_le64(u64 val, void *p)
{
__put_unaligned_t(__le64, cpu_to_le64(val), p);
}
static inline u16 get_unaligned_be16(const void *p)
{
return be16_to_cpu(__get_unaligned_t(__be16, p));
}
static inline u32 get_unaligned_be32(const void *p)
{
return be32_to_cpu(__get_unaligned_t(__be32, p));
}
static inline u64 get_unaligned_be64(const void *p)
{
return be64_to_cpu(__get_unaligned_t(__be64, p));
}
static inline void put_unaligned_be16(u16 val, void *p)
{
__put_unaligned_t(__be16, cpu_to_be16(val), p);
}
static inline void put_unaligned_be32(u32 val, void *p)
{
__put_unaligned_t(__be32, cpu_to_be32(val), p);
}
static inline void put_unaligned_be64(u64 val, void *p)
{
__put_unaligned_t(__be64, cpu_to_be64(val), p);
}
/* Allow unaligned memory access */
void allow_unaligned(void);
#endif
+6
View File
@@ -0,0 +1,6 @@
#ifndef DO_DEPS_ONLY
#include <generated/generic-asm-offsets.h>
/* #include <generated/asm-offsets.h> */
#endif
+208
View File
@@ -0,0 +1,208 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*/
/*
* Most of the following information was derived from the document
* "Information Technology - AT Attachment-3 Interface (ATA-3)",
* ANSI X3.298-1997.
*/
#ifndef _ATA_H
#define _ATA_H
#include <libata.h>
/* Register addressing depends on the hardware design; for instance,
* 8-bit (register) and 16-bit (data) accesses might use different
* address spaces. This is implemented by the following definitions.
*/
#define ATA_IO_DATA(x) (CONFIG_SYS_ATA_DATA_OFFSET+((x) * CONFIG_SYS_ATA_STRIDE))
#define ATA_IO_REG(x) (CONFIG_SYS_ATA_REG_OFFSET +((x) * CONFIG_SYS_ATA_STRIDE))
#define ATA_IO_ALT(x) (CONFIG_SYS_ATA_ALT_OFFSET +((x) * CONFIG_SYS_ATA_STRIDE))
/*
* I/O Register Descriptions
*/
#define ATA_DATA_REG ATA_IO_DATA(0)
#define ATA_ERROR_REG ATA_IO_REG(1)
#define ATA_SECT_CNT ATA_IO_REG(2)
#define ATA_SECT_NUM ATA_IO_REG(3)
#define ATA_CYL_LOW ATA_IO_REG(4)
#define ATA_CYL_HIGH ATA_IO_REG(5)
#define ATA_DEV_HD ATA_IO_REG(6)
#define ATA_COMMAND ATA_IO_REG(7)
#define ATA_DATA_EVEN ATA_IO_REG(8)
#define ATA_DATA_ODD ATA_IO_REG(9)
#define ATA_STATUS ATA_COMMAND
#define ATA_DEV_CTL ATA_IO_ALT(6)
#define ATA_LBA_LOW ATA_SECT_NUM
#define ATA_LBA_MID ATA_CYL_LOW
#define ATA_LBA_HIGH ATA_CYL_HIGH
#define ATA_LBA_SEL ATA_DEV_CTL
/*
* Status register bits
*/
#define ATA_STAT_BUSY 0x80 /* Device Busy */
#define ATA_STAT_READY 0x40 /* Device Ready */
#define ATA_STAT_FAULT 0x20 /* Device Fault */
#define ATA_STAT_SEEK 0x10 /* Device Seek Complete */
#define ATA_STAT_DRQ 0x08 /* Data Request (ready) */
#define ATA_STAT_CORR 0x04 /* Corrected Data Error */
#define ATA_STAT_INDEX 0x02 /* Vendor specific */
#define ATA_STAT_ERR 0x01 /* Error */
/*
* Device / Head Register Bits
*/
#ifndef ATA_DEVICE
#define ATA_DEVICE(x) ((x & 1)<<4)
#endif /* ATA_DEVICE */
#define ATA_LBA 0xE0
/*
* ATAPI Commands
*/
#define ATAPI_CMD_INQUIRY 0x12
#define ATAPI_CMD_REQ_SENSE 0x03
#define ATAPI_CMD_READ_CAP 0x25
#define ATAPI_CMD_START_STOP 0x1B
#define ATAPI_CMD_READ_12 0xA8
#define ATA_GET_ERR() inb(ATA_STATUS)
#define ATA_GET_STAT() inb(ATA_STATUS)
#define ATA_OK_STAT(stat,good,bad) (((stat)&((good)|(bad)))==(good))
#define ATA_BAD_R_STAT (ATA_STAT_BUSY | ATA_STAT_ERR)
#define ATA_BAD_W_STAT (ATA_BAD_R_STAT | ATA_STAT_FAULT)
#define ATA_BAD_STAT (ATA_BAD_R_STAT | ATA_STAT_DRQ)
#define ATA_DRIVE_READY (ATA_READY_STAT | ATA_STAT_SEEK)
#define ATA_DATA_READY (ATA_STAT_DRQ)
#define ATA_BLOCKSIZE 512 /* bytes */
#define ATA_BLOCKSHIFT 9 /* 2 ^ ATA_BLOCKSIZESHIFT = 512 */
#define ATA_SECTORWORDS (512 / sizeof(uint32_t))
#ifndef ATA_RESET_TIME
#define ATA_RESET_TIME 60 /* spec allows up to 31 seconds */
#endif
/* ------------------------------------------------------------------------- */
/*
* structure returned by ATA_CMD_IDENT, as per ANSI ATA2 rev.2f spec
*/
typedef struct hd_driveid {
unsigned short config; /* lots of obsolete bit flags */
unsigned short cyls; /* "physical" cyls */
unsigned short reserved2; /* reserved (word 2) */
unsigned short heads; /* "physical" heads */
unsigned short track_bytes; /* unformatted bytes per track */
unsigned short sector_bytes; /* unformatted bytes per sector */
unsigned short sectors; /* "physical" sectors per track */
unsigned short vendor0; /* vendor unique */
unsigned short vendor1; /* vendor unique */
unsigned short vendor2; /* vendor unique */
unsigned char serial_no[20]; /* 0 = not_specified */
unsigned short buf_type;
unsigned short buf_size; /* 512 byte increments; 0 = not_specified */
unsigned short ecc_bytes; /* for r/w long cmds; 0 = not_specified */
unsigned char fw_rev[8]; /* 0 = not_specified */
unsigned char model[40]; /* 0 = not_specified */
unsigned char max_multsect; /* 0=not_implemented */
unsigned char vendor3; /* vendor unique */
unsigned short dword_io; /* 0=not_implemented; 1=implemented */
unsigned char vendor4; /* vendor unique */
unsigned char capability; /* bits 0:DMA 1:LBA 2:IORDYsw 3:IORDYsup*/
unsigned short reserved50; /* reserved (word 50) */
unsigned char vendor5; /* vendor unique */
unsigned char tPIO; /* 0=slow, 1=medium, 2=fast */
unsigned char vendor6; /* vendor unique */
unsigned char tDMA; /* 0=slow, 1=medium, 2=fast */
unsigned short field_valid; /* bits 0:cur_ok 1:eide_ok */
unsigned short cur_cyls; /* logical cylinders */
unsigned short cur_heads; /* logical heads */
unsigned short cur_sectors; /* logical sectors per track */
unsigned short cur_capacity0; /* logical total sectors on drive */
unsigned short cur_capacity1; /* (2 words, misaligned int) */
unsigned char multsect; /* current multiple sector count */
unsigned char multsect_valid; /* when (bit0==1) multsect is ok */
unsigned short lba_capacity[2];/* two words containing total number of sectors */
unsigned short dma_1word; /* single-word dma info */
unsigned short dma_mword; /* multiple-word dma info */
unsigned short eide_pio_modes; /* bits 0:mode3 1:mode4 */
unsigned short eide_dma_min; /* min mword dma cycle time (ns) */
unsigned short eide_dma_time; /* recommended mword dma cycle time (ns) */
unsigned short eide_pio; /* min cycle time (ns), no IORDY */
unsigned short eide_pio_iordy; /* min cycle time (ns), with IORDY */
unsigned short words69_70[2]; /* reserved words 69-70 */
unsigned short words71_74[4]; /* reserved words 71-74 */
unsigned short queue_depth; /* */
unsigned short words76_79[4]; /* reserved words 76-79 */
unsigned short major_rev_num; /* */
unsigned short minor_rev_num; /* */
unsigned short command_set_1; /* bits 0:Smart 1:Security 2:Removable 3:PM */
unsigned short command_set_2; /* bits 14:Smart Enabled 13:0 zero 10:lba48 support*/
unsigned short cfsse; /* command set-feature supported extensions */
unsigned short cfs_enable_1; /* command set-feature enabled */
unsigned short cfs_enable_2; /* command set-feature enabled */
unsigned short csf_default; /* command set-feature default */
unsigned short dma_ultra; /* */
unsigned short word89; /* reserved (word 89) */
unsigned short word90; /* reserved (word 90) */
unsigned short CurAPMvalues; /* current APM values */
unsigned short word92; /* reserved (word 92) */
unsigned short hw_config; /* hardware config */
unsigned short words94_99[6];/* reserved words 94-99 */
/*unsigned long long lba48_capacity; /--* 4 16bit values containing lba 48 total number of sectors */
unsigned short lba48_capacity[4]; /* 4 16bit values containing lba 48 total number of sectors */
unsigned short words104_125[22];/* reserved words 104-125 */
unsigned short last_lun; /* reserved (word 126) */
unsigned short word127; /* reserved (word 127) */
unsigned short dlf; /* device lock function
* 15:9 reserved
* 8 security level 1:max 0:high
* 7:6 reserved
* 5 enhanced erase
* 4 expire
* 3 frozen
* 2 locked
* 1 en/disabled
* 0 capability
*/
unsigned short csfo; /* current set features options
* 15:4 reserved
* 3 auto reassign
* 2 reverting
* 1 read-look-ahead
* 0 write cache
*/
unsigned short words130_155[26];/* reserved vendor words 130-155 */
unsigned short word156;
unsigned short words157_159[3];/* reserved vendor words 157-159 */
unsigned short words160_162[3];/* reserved words 160-162 */
unsigned short cf_advanced_caps;
unsigned short words164_255[92];/* reserved words 164-255 */
} hd_driveid_t;
/*
* PIO Mode Configuration
*
* See ATA-3 (AT Attachment-3 Interface) documentation, Figure 14 / Table 21
*/
typedef struct {
unsigned int t_setup; /* Setup Time in [ns] or clocks */
unsigned int t_length; /* Length Time in [ns] or clocks */
unsigned int t_hold; /* Hold Time in [ns] or clocks */
}
pio_config_t;
#define IDE_MAX_PIO_MODE 4 /* max suppurted PIO mode */
/* ------------------------------------------------------------------------- */
#endif /* _ATA_H */
+200
View File
@@ -0,0 +1,200 @@
/* SPDX-License-Identifier: BSD-3-Clause */
/*
* This is from the ARM TF Project,
* Repository: https://github.com/TrustedFirmware-A/trusted-firmware-a.git
* File: include/common/bl_common.h
* Portions copyright (c) 2013-2016, ARM Limited and Contributors. All rights
* reserved.
* Copyright (C) 2016-2017 Rockchip Electronic Co.,Ltd
*/
#ifndef __BL_COMMON_H__
#define __BL_COMMON_H__
#define ATF_PARAM_EP 0x01
#define ATF_PARAM_IMAGE_BINARY 0x02
#define ATF_PARAM_BL31 0x03
#define ATF_PARAM_BL_PARAMS 0x05
#define ATF_VERSION_1 0x01
#define ATF_VERSION_2 0x02
#define ATF_BL31_IMAGE_ID 0x03
#define ATF_BL32_IMAGE_ID 0x04
#define ATF_BL33_IMAGE_ID 0x05
#define ATF_EP_SECURE 0x0
#define ATF_EP_NON_SECURE 0x1
#define SET_PARAM_HEAD(_p, _type, _ver, _attr) do { \
(_p)->h.type = (uint8_t)(_type); \
(_p)->h.version = (uint8_t)(_ver); \
(_p)->h.size = (uint16_t)sizeof(*_p); \
(_p)->h.attr = (uint32_t)(_attr) ; \
} while (0)
#define MODE_RW_SHIFT 0x4
#define MODE_RW_MASK 0x1
#define MODE_RW_64 0x0
#define MODE_RW_32 0x1
#define MODE_EL_SHIFT 0x2
#define MODE_EL_MASK 0x3
#define MODE_EL3 0x3
#define MODE_EL2 0x2
#define MODE_EL1 0x1
#define MODE_EL0 0x0
#define MODE_SP_SHIFT 0x0
#define MODE_SP_MASK 0x1
#define MODE_SP_EL0 0x0
#define MODE_SP_ELX 0x1
#define SPSR_DAIF_SHIFT 6
#define SPSR_DAIF_MASK 0x0f
#define SPSR_64(el, sp, daif) \
(MODE_RW_64 << MODE_RW_SHIFT | \
((el) & MODE_EL_MASK) << MODE_EL_SHIFT | \
((sp) & MODE_SP_MASK) << MODE_SP_SHIFT | \
((daif) & SPSR_DAIF_MASK) << SPSR_DAIF_SHIFT)
#define SPSR_FIQ (1 << 6)
#define SPSR_IRQ (1 << 7)
#define SPSR_SERROR (1 << 8)
#define SPSR_DEBUG (1 << 9)
#define SPSR_EXCEPTION_MASK (SPSR_FIQ | SPSR_IRQ | SPSR_SERROR | SPSR_DEBUG)
#define DAIF_FIQ_BIT (1<<0)
#define DAIF_IRQ_BIT (1<<1)
#define DAIF_ABT_BIT (1<<2)
#define DAIF_DBG_BIT (1<<3)
#define DISABLE_ALL_EXECPTIONS \
(DAIF_FIQ_BIT | DAIF_IRQ_BIT | DAIF_ABT_BIT | DAIF_DBG_BIT)
#ifndef __ASSEMBLY__
#include <linux/types.h>
/*******************************************************************************
* Structure used for telling the next BL how much of a particular type of
* memory is available for its use and how much is already used.
******************************************************************************/
struct aapcs64_params {
unsigned long arg0;
unsigned long arg1;
unsigned long arg2;
unsigned long arg3;
unsigned long arg4;
unsigned long arg5;
unsigned long arg6;
unsigned long arg7;
};
/***************************************************************************
* This structure provides version information and the size of the
* structure, attributes for the structure it represents
***************************************************************************/
struct param_header {
uint8_t type; /* type of the structure */
uint8_t version; /* version of this structure */
uint16_t size; /* size of this structure in bytes */
uint32_t attr; /* attributes: unused bits SBZ */
};
/*****************************************************************************
* This structure represents the superset of information needed while
* switching exception levels. The only two mechanisms to do so are
* ERET & SMC. Security state is indicated using bit zero of header
* attribute
* NOTE: BL1 expects entrypoint followed by spsr at an offset from the start
* of this structure defined by the macro `ENTRY_POINT_INFO_PC_OFFSET` while
* processing SMC to jump to BL31.
*****************************************************************************/
struct entry_point_info {
struct param_header h;
uintptr_t pc;
uint32_t spsr;
struct aapcs64_params args;
};
/*****************************************************************************
* Image info binary provides information from the image loader that
* can be used by the firmware to manage available trusted RAM.
* More advanced firmware image formats can provide additional
* information that enables optimization or greater flexibility in the
* common firmware code
*****************************************************************************/
struct atf_image_info {
struct param_header h;
uintptr_t image_base; /* physical address of base of image */
uint32_t image_size; /* bytes read from image file */
#if CONFIG_IS_ENABLED(ATF_LOAD_IMAGE_V2)
uint32_t image_max_size;
#endif
};
/*****************************************************************************
* The image descriptor struct definition.
*****************************************************************************/
struct image_desc {
/* Contains unique image id for the image. */
unsigned int image_id;
/*
* This member contains Image state information.
* Refer IMAGE_STATE_XXX defined above.
*/
unsigned int state;
uint32_t copied_size; /* image size copied in blocks */
struct atf_image_info atf_image_info;
struct entry_point_info ep_info;
};
/*******************************************************************************
* This structure represents the superset of information that can be passed to
* BL31 e.g. while passing control to it from BL2. The BL32 parameters will be
* populated only if BL2 detects its presence. A pointer to a structure of this
* type should be passed in X0 to BL31's cold boot entrypoint.
*
* Use of this structure and the X0 parameter is not mandatory: the BL31
* platform code can use other mechanisms to provide the necessary information
* about BL32 and BL33 to the common and SPD code.
*
* BL31 image information is mandatory if this structure is used. If either of
* the optional BL32 and BL33 image information is not provided, this is
* indicated by the respective image_info pointers being zero.
******************************************************************************/
struct bl31_params {
struct param_header h;
struct atf_image_info *bl31_image_info;
struct entry_point_info *bl32_ep_info;
struct atf_image_info *bl32_image_info;
struct entry_point_info *bl33_ep_info;
struct atf_image_info *bl33_image_info;
};
/* BL image node in the BL image execution sequence */
struct bl_params_node {
unsigned int image_id;
struct atf_image_info *image_info;
struct entry_point_info *ep_info;
struct bl_params_node *next_params_info;
};
/*
* BL image head node in the BL image execution sequence
* It is also used to pass information to next BL image.
*/
struct bl_params {
struct param_header h;
struct bl_params_node *head;
};
#define for_each_bl_params_node(bl_params, node) \
for ((node) = (bl_params)->head; \
(node); \
(node) = (node)->next_params_info)
#endif /*__ASSEMBLY__ */
#endif /* __BL_COMMON_H__ */
+225
View File
@@ -0,0 +1,225 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Header file for AT91/AT32 MULTI LAYER LCD Controller
*
* Data structure and register user interface
*
* Copyright (C) 2012 Atmel Corporation
*/
#ifndef __ATMEL_HLCDC_H__
#define __ATMEL_HLCDC_H__
/* Atmel multi layer lcdc hardware registers */
struct atmel_hlcd_regs {
u32 lcdc_lcdcfg0;
u32 lcdc_lcdcfg1;
u32 lcdc_lcdcfg2;
u32 lcdc_lcdcfg3;
u32 lcdc_lcdcfg4;
u32 lcdc_lcdcfg5;
u32 lcdc_lcdcfg6;
u32 res1;
u32 lcdc_lcden;
u32 lcdc_lcddis;
u32 lcdc_lcdsr;
u32 res2;
u32 lcdc_lcdidr;
u32 res3[3];
u32 lcdc_basecher;
u32 res4[3];
u32 lcdc_baseidr;
u32 res5[3];
u32 lcdc_baseaddr;
u32 lcdc_basectrl;
u32 lcdc_basenext;
u32 lcdc_basecfg0;
u32 lcdc_basecfg1;
u32 lcdc_basecfg2;
u32 lcdc_basecfg3;
u32 lcdc_basecfg4;
};
#define LCDC_LCDCFG0_CLKPOL (0x1 << 0)
#define LCDC_LCDCFG0_CLKSEL (0x1 << 2)
#define LCDC_LCDCFG0_CLKPWMSEL (0x1 << 3)
#define LCDC_LCDCFG0_CGDISBASE (0x1 << 8)
#define LCDC_LCDCFG0_CGDISOVR1 (0x1 << 9)
#define LCDC_LCDCFG0_CGDISHEO (0x1 << 11)
#define LCDC_LCDCFG0_CGDISHCR (0x1 << 12)
#define LCDC_LCDCFG0_CLKDIV_Pos 16
#define LCDC_LCDCFG0_CLKDIV_Msk (0xff << LCDC_LCDCFG0_CLKDIV_Pos)
#define LCDC_LCDCFG0_CLKDIV(value) \
((LCDC_LCDCFG0_CLKDIV_Msk & ((value) << LCDC_LCDCFG0_CLKDIV_Pos)))
#define LCDC_LCDCFG1_HSPW_Pos 0
#define LCDC_LCDCFG1_HSPW_Msk (0x3f << LCDC_LCDCFG1_HSPW_Pos)
#define LCDC_LCDCFG1_HSPW(value) \
((LCDC_LCDCFG1_HSPW_Msk & ((value) << LCDC_LCDCFG1_HSPW_Pos)))
#define LCDC_LCDCFG1_VSPW_Pos 16
#define LCDC_LCDCFG1_VSPW_Msk (0x3f << LCDC_LCDCFG1_VSPW_Pos)
#define LCDC_LCDCFG1_VSPW(value) \
((LCDC_LCDCFG1_VSPW_Msk & ((value) << LCDC_LCDCFG1_VSPW_Pos)))
#define LCDC_LCDCFG2_VFPW_Pos 0
#define LCDC_LCDCFG2_VFPW_Msk (0x3f << LCDC_LCDCFG2_VFPW_Pos)
#define LCDC_LCDCFG2_VFPW(value) \
((LCDC_LCDCFG2_VFPW_Msk & ((value) << LCDC_LCDCFG2_VFPW_Pos)))
#define LCDC_LCDCFG2_VBPW_Pos 16
#define LCDC_LCDCFG2_VBPW_Msk (0x3f << LCDC_LCDCFG2_VBPW_Pos)
#define LCDC_LCDCFG2_VBPW(value) \
((LCDC_LCDCFG2_VBPW_Msk & ((value) << LCDC_LCDCFG2_VBPW_Pos)))
#define LCDC_LCDCFG3_HFPW_Pos 0
#define LCDC_LCDCFG3_HFPW_Msk (0xff << LCDC_LCDCFG3_HFPW_Pos)
#define LCDC_LCDCFG3_HFPW(value) \
((LCDC_LCDCFG3_HFPW_Msk & ((value) << LCDC_LCDCFG3_HFPW_Pos)))
#define LCDC_LCDCFG3_HBPW_Pos 16
#define LCDC_LCDCFG3_HBPW_Msk (0xff << LCDC_LCDCFG3_HBPW_Pos)
#define LCDC_LCDCFG3_HBPW(value) \
((LCDC_LCDCFG3_HBPW_Msk & ((value) << LCDC_LCDCFG3_HBPW_Pos)))
#define LCDC_LCDCFG4_PPL_Pos 0
#define LCDC_LCDCFG4_PPL_Msk (0x7ff << LCDC_LCDCFG4_PPL_Pos)
#define LCDC_LCDCFG4_PPL(value) \
((LCDC_LCDCFG4_PPL_Msk & ((value) << LCDC_LCDCFG4_PPL_Pos)))
#define LCDC_LCDCFG4_RPF_Pos 16
#define LCDC_LCDCFG4_RPF_Msk (0x7ff << LCDC_LCDCFG4_RPF_Pos)
#define LCDC_LCDCFG4_RPF(value) \
((LCDC_LCDCFG4_RPF_Msk & ((value) << LCDC_LCDCFG4_RPF_Pos)))
#define LCDC_LCDCFG5_HSPOL (0x1 << 0)
#define LCDC_LCDCFG5_VSPOL (0x1 << 1)
#define LCDC_LCDCFG5_VSPDLYS (0x1 << 2)
#define LCDC_LCDCFG5_VSPDLYE (0x1 << 3)
#define LCDC_LCDCFG5_DISPPOL (0x1 << 4)
#define LCDC_LCDCFG5_SERIAL (0x1 << 5)
#define LCDC_LCDCFG5_DITHER (0x1 << 6)
#define LCDC_LCDCFG5_DISPDLY (0x1 << 7)
#define LCDC_LCDCFG5_MODE_Pos 8
#define LCDC_LCDCFG5_MODE_Msk (0x3 << LCDC_LCDCFG5_MODE_Pos)
#define LCDC_LCDCFG5_MODE_OUTPUT_12BPP (0x0 << 8)
#define LCDC_LCDCFG5_MODE_OUTPUT_16BPP (0x1 << 8)
#define LCDC_LCDCFG5_MODE_OUTPUT_18BPP (0x2 << 8)
#define LCDC_LCDCFG5_MODE_OUTPUT_24BPP (0x3 << 8)
#define LCDC_LCDCFG5_VSPSU (0x1 << 12)
#define LCDC_LCDCFG5_VSPHO (0x1 << 13)
#define LCDC_LCDCFG5_GUARDTIME_Pos 16
#define LCDC_LCDCFG5_GUARDTIME_Msk (0x1f << LCDC_LCDCFG5_GUARDTIME_Pos)
#define LCDC_LCDCFG5_GUARDTIME(value) \
((LCDC_LCDCFG5_GUARDTIME_Msk & ((value) << LCDC_LCDCFG5_GUARDTIME_Pos)))
#define LCDC_LCDCFG6_PWMPS_Pos 0
#define LCDC_LCDCFG6_PWMPS_Msk (0x7 << LCDC_LCDCFG6_PWMPS_Pos)
#define LCDC_LCDCFG6_PWMPS(value) \
((LCDC_LCDCFG6_PWMPS_Msk & ((value) << LCDC_LCDCFG6_PWMPS_Pos)))
#define LCDC_LCDCFG6_PWMPOL (0x1 << 4)
#define LCDC_LCDCFG6_PWMCVAL_Pos 8
#define LCDC_LCDCFG6_PWMCVAL_Msk (0xff << LCDC_LCDCFG6_PWMCVAL_Pos)
#define LCDC_LCDCFG6_PWMCVAL(value) \
((LCDC_LCDCFG6_PWMCVAL_Msk & ((value) << LCDC_LCDCFG6_PWMCVAL_Pos)))
#define LCDC_LCDEN_CLKEN (0x1 << 0)
#define LCDC_LCDEN_SYNCEN (0x1 << 1)
#define LCDC_LCDEN_DISPEN (0x1 << 2)
#define LCDC_LCDEN_PWMEN (0x1 << 3)
#define LCDC_LCDDIS_CLKDIS (0x1 << 0)
#define LCDC_LCDDIS_SYNCDIS (0x1 << 1)
#define LCDC_LCDDIS_DISPDIS (0x1 << 2)
#define LCDC_LCDDIS_PWMDIS (0x1 << 3)
#define LCDC_LCDDIS_CLKRST (0x1 << 8)
#define LCDC_LCDDIS_SYNCRST (0x1 << 9)
#define LCDC_LCDDIS_DISPRST (0x1 << 10)
#define LCDC_LCDDIS_PWMRST (0x1 << 11)
#define LCDC_LCDSR_CLKSTS (0x1 << 0)
#define LCDC_LCDSR_LCDSTS (0x1 << 1)
#define LCDC_LCDSR_DISPSTS (0x1 << 2)
#define LCDC_LCDSR_PWMSTS (0x1 << 3)
#define LCDC_LCDSR_SIPSTS (0x1 << 4)
#define LCDC_LCDIDR_SOFID (0x1 << 0)
#define LCDC_LCDIDR_DISID (0x1 << 1)
#define LCDC_LCDIDR_DISPID (0x1 << 2)
#define LCDC_LCDIDR_FIFOERRID (0x1 << 4)
#define LCDC_LCDIDR_BASEID (0x1 << 8)
#define LCDC_LCDIDR_OVR1ID (0x1 << 9)
#define LCDC_LCDIDR_HEOID (0x1 << 11)
#define LCDC_LCDIDR_HCRID (0x1 << 12)
#define LCDC_BASECHER_CHEN (0x1 << 0)
#define LCDC_BASECHER_UPDATEEN (0x1 << 1)
#define LCDC_BASECHER_A2QEN (0x1 << 2)
#define LCDC_BASEIDR_DMA (0x1 << 2)
#define LCDC_BASEIDR_DSCR (0x1 << 3)
#define LCDC_BASEIDR_ADD (0x1 << 4)
#define LCDC_BASEIDR_DONE (0x1 << 5)
#define LCDC_BASEIDR_OVR (0x1 << 6)
#define LCDC_BASECTRL_DFETCH (0x1 << 0)
#define LCDC_BASECTRL_LFETCH (0x1 << 1)
#define LCDC_BASECTRL_DMAIEN (0x1 << 2)
#define LCDC_BASECTRL_DSCRIEN (0x1 << 3)
#define LCDC_BASECTRL_ADDIEN (0x1 << 4)
#define LCDC_BASECTRL_DONEIEN (0x1 << 5)
#define LCDC_BASECFG0_BLEN_Pos 4
#define LCDC_BASECFG0_BLEN_AHB_SINGLE (0x0 << 4)
#define LCDC_BASECFG0_BLEN_AHB_INCR4 (0x1 << 4)
#define LCDC_BASECFG0_BLEN_AHB_INCR8 (0x2 << 4)
#define LCDC_BASECFG0_BLEN_AHB_INCR16 (0x3 << 4)
#define LCDC_BASECFG0_DLBO (0x1 << 8)
#define LCDC_BASECFG1_RGBMODE_12BPP_RGB_444 (0x0 << 4)
#define LCDC_BASECFG1_RGBMODE_16BPP_ARGB_4444 (0x1 << 4)
#define LCDC_BASECFG1_RGBMODE_16BPP_RGBA_4444 (0x2 << 4)
#define LCDC_BASECFG1_RGBMODE_16BPP_RGB_565 (0x3 << 4)
#define LCDC_BASECFG1_RGBMODE_16BPP_TRGB_1555 (0x4 << 4)
#define LCDC_BASECFG1_RGBMODE_18BPP_RGB_666 (0x5 << 4)
#define LCDC_BASECFG1_RGBMODE_18BPP_RGB_666_PACKED (0x6 << 4)
#define LCDC_BASECFG1_RGBMODE_19BPP_TRGB_1666 (0x7 << 4)
#define LCDC_BASECFG1_RGBMODE_19BPP_TRGB_PACKED (0x8 << 4)
#define LCDC_BASECFG1_RGBMODE_24BPP_RGB_888 (0x9 << 4)
#define LCDC_BASECFG1_RGBMODE_24BPP_RGB_888_PACKED (0xA << 4)
#define LCDC_BASECFG1_RGBMODE_25BPP_TRGB_1888 (0xB << 4)
#define LCDC_BASECFG1_RGBMODE_32BPP_ARGB_8888 (0xC << 4)
#define LCDC_BASECFG1_RGBMODE_32BPP_RGBA_8888 (0xD << 4)
#define LCDC_BASECFG2_XSTRIDE_Pos 0
#define LCDC_BASECFG2_XSTRIDE_Msk (0xffffffff << LCDC_BASECFG2_XSTRIDE_Pos)
#define LCDC_BASECFG2_XSTRIDE(value) \
((LCDC_BASECFG2_XSTRIDE_Msk & ((value) << LCDC_BASECFG2_XSTRIDE_Pos)))
#define LCDC_BASECFG3_BDEF_Pos 0
#define LCDC_BASECFG3_BDEF_Msk (0xff << LCDC_BASECFG3_BDEF_Pos)
#define LCDC_BASECFG3_BDEF(value) \
((LCDC_BASECFG3_BDEF_Msk & ((value) << LCDC_BASECFG3_BDEF_Pos)))
#define LCDC_BASECFG3_GDEF_Pos 8
#define LCDC_BASECFG3_GDEF_Msk (0xff << LCDC_BASECFG3_GDEF_Pos)
#define LCDC_BASECFG3_GDEF(value) \
((LCDC_BASECFG3_GDEF_Msk & ((value) << LCDC_BASECFG3_GDEF_Pos)))
#define LCDC_BASECFG3_RDEF_Pos 16
#define LCDC_BASECFG3_RDEF_Msk (0xff << LCDC_BASECFG3_RDEF_Pos)
#define LCDC_BASECFG3_RDEF(value) \
((LCDC_BASECFG3_RDEF_Msk & ((value) << LCDC_BASECFG3_RDEF_Pos)))
#define LCDC_BASECLUT_BCLUT_Pos 0
#define LCDC_BASECLUT_BCLUT_Msk (0xff << LCDC_BASECLUT_BCLUT_Pos)
#define LCDC_BASECLUT_GCLUT_Pos 8
#define LCDC_BASECLUT_GCLUT_Msk (0xff << LCDC_BASECLUT_GCLUT_Pos)
#define LCDC_BASECLUT_RCLUT_Pos 16
#define LCDC_BASECLUT_RCLUT_Msk (0xff << LCDC_BASECLUT_RCLUT_Pos)
#define LCDC_BASECFG4_DMA (0x1 << 8)
#define LCDC_BASECFG4_REP (0x1 << 9)
struct lcd_dma_desc {
u32 address;
u32 control;
u32 next;
};
#define ATMEL_LCDC_LUT(n) (0x0400 + ((n)*4))
#endif /* __ATMEL_HLCDC_H__ */
+58
View File
@@ -0,0 +1,58 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* atmel_lcd.h - Atmel LCD Controller structures
*
* (C) Copyright 2001
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*/
#ifndef _ATMEL_LCD_H_
#define _ATMEL_LCD_H_
#include <linux/types.h>
/**
* struct atmel_lcd_plat - platform data for Atmel LCDs with driver model
*
* @timing_index: Index of LCD timing to use in device tree node
*/
struct atmel_lcd_plat {
int timing_index;
};
typedef struct vidinfo {
ushort vl_col; /* Number of columns (i.e. 640) */
ushort vl_row; /* Number of rows (i.e. 480) */
ushort vl_rot; /* Rotation of Display (0, 1, 2, 3) */
u_long vl_clk; /* pixel clock in ps */
/* LCD configuration register */
u_long vl_sync; /* Horizontal / vertical sync */
u_long vl_bpix; /* Bits per pixel, 0 = 1, 1 = 2, 2 = 4, 3 = 8, 4 = 16 */
u_long vl_tft; /* 0 = passive, 1 = TFT */
u_long vl_cont_pol_low; /* contrast polarity is low */
u_long vl_clk_pol; /* clock polarity */
/* Horizontal control register. */
u_long vl_hsync_len; /* Length of horizontal sync */
u_long vl_left_margin; /* Time from sync to picture */
u_long vl_right_margin; /* Time from picture to sync */
/* Vertical control register. */
u_long vl_vsync_len; /* Length of vertical sync */
u_long vl_upper_margin; /* Time from sync to picture */
u_long vl_lower_margin; /* Time from picture to sync */
u_long mmio; /* Memory mapped registers */
u_int logo_width;
u_int logo_height;
int logo_x_offset;
int logo_y_offset;
u_long logo_addr;
} vidinfo_t;
void atmel_logo_info(vidinfo_t *info);
void microchip_logo_info(vidinfo_t *info);
#endif
+164
View File
@@ -0,0 +1,164 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Header file for AT91/AT32 LCD Controller
*
* Data structure and register user interface
*
* Copyright (C) 2007 Atmel Corporation
*/
#ifndef __ATMEL_LCDC_H__
#define __ATMEL_LCDC_H__
#define ATMEL_LCDC_DMABADDR1 0x00
#define ATMEL_LCDC_DMABADDR2 0x04
#define ATMEL_LCDC_DMAFRMPT1 0x08
#define ATMEL_LCDC_DMAFRMPT2 0x0c
#define ATMEL_LCDC_DMAFRMADD1 0x10
#define ATMEL_LCDC_DMAFRMADD2 0x14
#define ATMEL_LCDC_DMAFRMCFG 0x18
#define ATMEL_LCDC_FRSIZE (0x7fffff << 0)
#define ATMEL_LCDC_BLENGTH_OFFSET 24
#define ATMEL_LCDC_BLENGTH (0x7f << ATMEL_LCDC_BLENGTH_OFFSET)
#define ATMEL_LCDC_DMACON 0x1c
#define ATMEL_LCDC_DMAEN (0x1 << 0)
#define ATMEL_LCDC_DMARST (0x1 << 1)
#define ATMEL_LCDC_DMABUSY (0x1 << 2)
#define ATMEL_LCDC_DMAUPDT (0x1 << 3)
#define ATMEL_LCDC_DMA2DEN (0x1 << 4)
#define ATMEL_LCDC_DMA2DCFG 0x20
#define ATMEL_LCDC_ADDRINC_OFFSET 0
#define ATMEL_LCDC_ADDRINC (0xffff)
#define ATMEL_LCDC_PIXELOFF_OFFSET 24
#define ATMEL_LCDC_PIXELOFF (0x1f << 24)
#define ATMEL_LCDC_LCDCON1 0x0800
#define ATMEL_LCDC_BYPASS (1 << 0)
#define ATMEL_LCDC_CLKVAL_OFFSET 12
#define ATMEL_LCDC_CLKVAL (0x1ff << ATMEL_LCDC_CLKVAL_OFFSET)
#define ATMEL_LCDC_LINCNT (0x7ff << 21)
#define ATMEL_LCDC_LCDCON2 0x0804
#define ATMEL_LCDC_DISTYPE (3 << 0)
#define ATMEL_LCDC_DISTYPE_STNMONO (0 << 0)
#define ATMEL_LCDC_DISTYPE_STNCOLOR (1 << 0)
#define ATMEL_LCDC_DISTYPE_TFT (2 << 0)
#define ATMEL_LCDC_SCANMOD (1 << 2)
#define ATMEL_LCDC_SCANMOD_SINGLE (0 << 2)
#define ATMEL_LCDC_SCANMOD_DUAL (1 << 2)
#define ATMEL_LCDC_IFWIDTH (3 << 3)
#define ATMEL_LCDC_IFWIDTH_4 (0 << 3)
#define ATMEL_LCDC_IFWIDTH_8 (1 << 3)
#define ATMEL_LCDC_IFWIDTH_16 (2 << 3)
#define ATMEL_LCDC_PIXELSIZE (7 << 5)
#define ATMEL_LCDC_PIXELSIZE_1 (0 << 5)
#define ATMEL_LCDC_PIXELSIZE_2 (1 << 5)
#define ATMEL_LCDC_PIXELSIZE_4 (2 << 5)
#define ATMEL_LCDC_PIXELSIZE_8 (3 << 5)
#define ATMEL_LCDC_PIXELSIZE_16 (4 << 5)
#define ATMEL_LCDC_PIXELSIZE_24 (5 << 5)
#define ATMEL_LCDC_PIXELSIZE_32 (6 << 5)
#define ATMEL_LCDC_INVVD (1 << 8)
#define ATMEL_LCDC_INVVD_NORMAL (0 << 8)
#define ATMEL_LCDC_INVVD_INVERTED (1 << 8)
#define ATMEL_LCDC_INVFRAME (1 << 9 )
#define ATMEL_LCDC_INVFRAME_NORMAL (0 << 9)
#define ATMEL_LCDC_INVFRAME_INVERTED (1 << 9)
#define ATMEL_LCDC_INVLINE (1 << 10)
#define ATMEL_LCDC_INVLINE_NORMAL (0 << 10)
#define ATMEL_LCDC_INVLINE_INVERTED (1 << 10)
#define ATMEL_LCDC_INVCLK (1 << 11)
#define ATMEL_LCDC_INVCLK_NORMAL (0 << 11)
#define ATMEL_LCDC_INVCLK_INVERTED (1 << 11)
#define ATMEL_LCDC_INVDVAL (1 << 12)
#define ATMEL_LCDC_INVDVAL_NORMAL (0 << 12)
#define ATMEL_LCDC_INVDVAL_INVERTED (1 << 12)
#define ATMEL_LCDC_CLKMOD (1 << 15)
#define ATMEL_LCDC_CLKMOD_ACTIVEDISPLAY (0 << 15)
#define ATMEL_LCDC_CLKMOD_ALWAYSACTIVE (1 << 15)
#define ATMEL_LCDC_MEMOR (1 << 31)
#define ATMEL_LCDC_MEMOR_BIG (0 << 31)
#define ATMEL_LCDC_MEMOR_LITTLE (1 << 31)
#define ATMEL_LCDC_TIM1 0x0808
#define ATMEL_LCDC_VFP (0xffU << 0)
#define ATMEL_LCDC_VBP_OFFSET 8
#define ATMEL_LCDC_VBP (0xffU << ATMEL_LCDC_VBP_OFFSET)
#define ATMEL_LCDC_VPW_OFFSET 16
#define ATMEL_LCDC_VPW (0x3fU << ATMEL_LCDC_VPW_OFFSET)
#define ATMEL_LCDC_VHDLY_OFFSET 24
#define ATMEL_LCDC_VHDLY (0xfU << ATMEL_LCDC_VHDLY_OFFSET)
#define ATMEL_LCDC_TIM2 0x080c
#define ATMEL_LCDC_HBP (0xffU << 0)
#define ATMEL_LCDC_HPW_OFFSET 8
#define ATMEL_LCDC_HPW (0x3fU << ATMEL_LCDC_HPW_OFFSET)
#define ATMEL_LCDC_HFP_OFFSET 21
#define ATMEL_LCDC_HFP (0x7ffU << ATMEL_LCDC_HFP_OFFSET)
#define ATMEL_LCDC_LCDFRMCFG 0x0810
#define ATMEL_LCDC_LINEVAL (0x7ff << 0)
#define ATMEL_LCDC_HOZVAL_OFFSET 21
#define ATMEL_LCDC_HOZVAL (0x7ff << ATMEL_LCDC_HOZVAL_OFFSET)
#define ATMEL_LCDC_FIFO 0x0814
#define ATMEL_LCDC_FIFOTH (0xffff)
#define ATMEL_LCDC_MVAL 0x0818
#define ATMEL_LCDC_DP1_2 0x081c
#define ATMEL_LCDC_DP4_7 0x0820
#define ATMEL_LCDC_DP3_5 0x0824
#define ATMEL_LCDC_DP2_3 0x0828
#define ATMEL_LCDC_DP5_7 0x082c
#define ATMEL_LCDC_DP3_4 0x0830
#define ATMEL_LCDC_DP4_5 0x0834
#define ATMEL_LCDC_DP6_7 0x0838
#define ATMEL_LCDC_DP1_2_VAL (0xff)
#define ATMEL_LCDC_DP4_7_VAL (0xfffffff)
#define ATMEL_LCDC_DP3_5_VAL (0xfffff)
#define ATMEL_LCDC_DP2_3_VAL (0xfff)
#define ATMEL_LCDC_DP5_7_VAL (0xfffffff)
#define ATMEL_LCDC_DP3_4_VAL (0xffff)
#define ATMEL_LCDC_DP4_5_VAL (0xfffff)
#define ATMEL_LCDC_DP6_7_VAL (0xfffffff)
#define ATMEL_LCDC_PWRCON 0x083c
#define ATMEL_LCDC_PWR (1 << 0)
#define ATMEL_LCDC_GUARDT_OFFSET 1
#define ATMEL_LCDC_GUARDT (0x7f << ATMEL_LCDC_GUARDT_OFFSET)
#define ATMEL_LCDC_BUSY (1 << 31)
#define ATMEL_LCDC_CONTRAST_CTR 0x0840
#define ATMEL_LCDC_PS (3 << 0)
#define ATMEL_LCDC_PS_DIV1 (0 << 0)
#define ATMEL_LCDC_PS_DIV2 (1 << 0)
#define ATMEL_LCDC_PS_DIV4 (2 << 0)
#define ATMEL_LCDC_PS_DIV8 (3 << 0)
#define ATMEL_LCDC_POL (1 << 2)
#define ATMEL_LCDC_POL_NEGATIVE (0 << 2)
#define ATMEL_LCDC_POL_POSITIVE (1 << 2)
#define ATMEL_LCDC_ENA (1 << 3)
#define ATMEL_LCDC_ENA_PWMDISABLE (0 << 3)
#define ATMEL_LCDC_ENA_PWMENABLE (1 << 3)
#define ATMEL_LCDC_CONTRAST_VAL 0x0844
#define ATMEL_LCDC_CVAL (0xff)
#define ATMEL_LCDC_IER 0x0848
#define ATMEL_LCDC_IDR 0x084c
#define ATMEL_LCDC_IMR 0x0850
#define ATMEL_LCDC_ISR 0x0854
#define ATMEL_LCDC_ICR 0x0858
#define ATMEL_LCDC_LNI (1 << 0)
#define ATMEL_LCDC_LSTLNI (1 << 1)
#define ATMEL_LCDC_EOFI (1 << 2)
#define ATMEL_LCDC_UFLWI (1 << 4)
#define ATMEL_LCDC_OWRI (1 << 5)
#define ATMEL_LCDC_MERI (1 << 6)
#define ATMEL_LCDC_LUT(n) (0x0c00 + ((n)*4))
#endif /* __ATMEL_LCDC_H__ */
+217
View File
@@ -0,0 +1,217 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2005-2006 Atmel Corporation
*/
#ifndef __ATMEL_MCI_H__
#define __ATMEL_MCI_H__
int atmel_mci_init(void *regs);
#ifndef __ASSEMBLY__
/*
* Structure for struct SoC access.
* Names starting with '_' are fillers.
*/
typedef struct atmel_mci {
/* reg Offset */
u32 cr; /* 0x00 */
u32 mr; /* 0x04 */
u32 dtor; /* 0x08 */
u32 sdcr; /* 0x0c */
u32 argr; /* 0x10 */
u32 cmdr; /* 0x14 */
u32 blkr; /* 0x18 */
u32 _1c; /* 0x1c */
u32 rspr; /* 0x20 */
u32 rspr1; /* 0x24 */
u32 rspr2; /* 0x28 */
u32 rspr3; /* 0x2c */
u32 rdr; /* 0x30 */
u32 tdr; /* 0x34 */
u32 _38; /* 0x38 */
u32 _3c; /* 0x3c */
u32 sr; /* 0x40 */
u32 ier; /* 0x44 */
u32 idr; /* 0x48 */
u32 imr; /* 0x4c */
u32 dma; /* 0x50 */
u32 cfg; /* 0x54 */
u32 reserved[41];
u32 version;
} atmel_mci_t;
#endif /* __ASSEMBLY__ */
/* Bitfields in CR */
#define MMCI_MCIEN_OFFSET 0
#define MMCI_MCIEN_SIZE 1
#define MMCI_MCIDIS_OFFSET 1
#define MMCI_MCIDIS_SIZE 1
#define MMCI_PWSEN_OFFSET 2
#define MMCI_PWSEN_SIZE 1
#define MMCI_PWSDIS_OFFSET 3
#define MMCI_PWSDIS_SIZE 1
#define MMCI_SWRST_OFFSET 7
#define MMCI_SWRST_SIZE 1
/* Bitfields in MR */
#define MMCI_CLKDIV_OFFSET 0
#define MMCI_CLKDIV_SIZE 8
#define MMCI_PWSDIV_OFFSET 8
#define MMCI_PWSDIV_SIZE 3
#define MMCI_RDPROOF_OFFSET 11
#define MMCI_RDPROOF_SIZE 1
#define MMCI_WRPROOF_OFFSET 12
#define MMCI_WRPROOF_SIZE 1
#define MMCI_PDCPADV_OFFSET 14
#define MMCI_PDCPADV_SIZE 1
#define MMCI_PDCMODE_OFFSET 15
#define MMCI_PDCMODE_SIZE 1
/* MCI IP version >= 0x500, MR bit 16 used for CLKODD */
#define MMCI_CLKODD_OFFSET 16
#define MMCI_CLKODD_SIZE 1
/* MCI IP version < 0x200, MR higher 16bits for BLKLEN */
#define MMCI_BLKLEN_OFFSET 16
#define MMCI_BLKLEN_SIZE 16
/* Bitfields in DTOR */
#define MMCI_DTOCYC_OFFSET 0
#define MMCI_DTOCYC_SIZE 4
#define MMCI_DTOMUL_OFFSET 4
#define MMCI_DTOMUL_SIZE 3
/* Bitfields in SDCR */
#define MMCI_SCDSEL_OFFSET 0
#define MMCI_SCDSEL_SIZE 4
#define MMCI_SCDBUS_OFFSET 7
#define MMCI_SCDBUS_SIZE 1
/* Bitfields in ARGR */
#define MMCI_ARG_OFFSET 0
#define MMCI_ARG_SIZE 32
/* Bitfields in CMDR */
#define MMCI_CMDNB_OFFSET 0
#define MMCI_CMDNB_SIZE 6
#define MMCI_RSPTYP_OFFSET 6
#define MMCI_RSPTYP_SIZE 2
#define MMCI_SPCMD_OFFSET 8
#define MMCI_SPCMD_SIZE 3
#define MMCI_OPDCMD_OFFSET 11
#define MMCI_OPDCMD_SIZE 1
#define MMCI_MAXLAT_OFFSET 12
#define MMCI_MAXLAT_SIZE 1
#define MMCI_TRCMD_OFFSET 16
#define MMCI_TRCMD_SIZE 2
#define MMCI_TRDIR_OFFSET 18
#define MMCI_TRDIR_SIZE 1
#define MMCI_TRTYP_OFFSET 19
#define MMCI_TRTYP_SIZE 2
/* Bitfields in BLKR */
/* MMCI_BLKLEN_OFFSET/SIZE already defined in MR */
#define MMCI_BCNT_OFFSET 0
#define MMCI_BCNT_SIZE 16
/* Bitfields in RSPRx */
#define MMCI_RSP_OFFSET 0
#define MMCI_RSP_SIZE 32
/* Bitfields in SR/IER/IDR/IMR */
#define MMCI_CMDRDY_OFFSET 0
#define MMCI_CMDRDY_SIZE 1
#define MMCI_RXRDY_OFFSET 1
#define MMCI_RXRDY_SIZE 1
#define MMCI_TXRDY_OFFSET 2
#define MMCI_TXRDY_SIZE 1
#define MMCI_BLKE_OFFSET 3
#define MMCI_BLKE_SIZE 1
#define MMCI_DTIP_OFFSET 4
#define MMCI_DTIP_SIZE 1
#define MMCI_NOTBUSY_OFFSET 5
#define MMCI_NOTBUSY_SIZE 1
#define MMCI_ENDRX_OFFSET 6
#define MMCI_ENDRX_SIZE 1
#define MMCI_ENDTX_OFFSET 7
#define MMCI_ENDTX_SIZE 1
#define MMCI_RXBUFF_OFFSET 14
#define MMCI_RXBUFF_SIZE 1
#define MMCI_TXBUFE_OFFSET 15
#define MMCI_TXBUFE_SIZE 1
#define MMCI_RINDE_OFFSET 16
#define MMCI_RINDE_SIZE 1
#define MMCI_RDIRE_OFFSET 17
#define MMCI_RDIRE_SIZE 1
#define MMCI_RCRCE_OFFSET 18
#define MMCI_RCRCE_SIZE 1
#define MMCI_RENDE_OFFSET 19
#define MMCI_RENDE_SIZE 1
#define MMCI_RTOE_OFFSET 20
#define MMCI_RTOE_SIZE 1
#define MMCI_DCRCE_OFFSET 21
#define MMCI_DCRCE_SIZE 1
#define MMCI_DTOE_OFFSET 22
#define MMCI_DTOE_SIZE 1
#define MMCI_OVRE_OFFSET 30
#define MMCI_OVRE_SIZE 1
#define MMCI_UNRE_OFFSET 31
#define MMCI_UNRE_SIZE 1
/* Constants for DTOMUL */
#define MMCI_DTOMUL_1_CYCLE 0
#define MMCI_DTOMUL_16_CYCLES 1
#define MMCI_DTOMUL_128_CYCLES 2
#define MMCI_DTOMUL_256_CYCLES 3
#define MMCI_DTOMUL_1024_CYCLES 4
#define MMCI_DTOMUL_4096_CYCLES 5
#define MMCI_DTOMUL_65536_CYCLES 6
#define MMCI_DTOMUL_1048576_CYCLES 7
/* Constants for RSPTYP */
#define MMCI_RSPTYP_NO_RESP 0
#define MMCI_RSPTYP_48_BIT_RESP 1
#define MMCI_RSPTYP_136_BIT_RESP 2
/* Constants for SPCMD */
#define MMCI_SPCMD_NO_SPEC_CMD 0
#define MMCI_SPCMD_INIT_CMD 1
#define MMCI_SPCMD_SYNC_CMD 2
#define MMCI_SPCMD_INT_CMD 4
#define MMCI_SPCMD_INT_RESP 5
/* Constants for TRCMD */
#define MMCI_TRCMD_NO_TRANS 0
#define MMCI_TRCMD_START_TRANS 1
#define MMCI_TRCMD_STOP_TRANS 2
/* Constants for TRTYP */
#define MMCI_TRTYP_BLOCK 0
#define MMCI_TRTYP_MULTI_BLOCK 1
#define MMCI_TRTYP_STREAM 2
/* Bitfields in CFG */
#define MMCI_FIFOMODE_OFFSET 0
#define MMCI_FIFOMODE_SIZE 1
#define MMCI_FERRCTRL_OFFSET 4
#define MMCI_FERRCTRL_SIZE 1
#define MMCI_HSMODE_OFFSET 8
#define MMCI_HSMODE_SIZE 1
#define MMCI_LSYNC_OFFSET 12
#define MMCI_LSYNC_SIZE 1
/* Bit manipulation macros */
#define MMCI_BIT(name) \
(1 << MMCI_##name##_OFFSET)
#define MMCI_BF(name,value) \
(((value) & ((1 << MMCI_##name##_SIZE) - 1)) \
<< MMCI_##name##_OFFSET)
#define MMCI_BFEXT(name,value) \
(((value) >> MMCI_##name##_OFFSET)\
& ((1 << MMCI_##name##_SIZE) - 1))
#define MMCI_BFINS(name,value,old) \
(((old) & ~(((1 << MMCI_##name##_SIZE) - 1) \
<< MMCI_##name##_OFFSET)) \
| MMCI_BF(name,value))
#endif /* __ATMEL_MCI_H__ */
+69
View File
@@ -0,0 +1,69 @@
/*
* I2C Driver for Atmel ATSHA204 over I2C
*
* Copyright (C) 2014 Josh Datko, Cryptotronix, jbd@cryptotronix.com
* 2016 Tomas Hlavacek, CZ.NIC, tmshlvck@gmail.com
* 2017 Marek Behún, CZ.NIC, kabel@kernel.org
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#ifndef _ATSHA204_I2C_H_
#define _ATSHA204_I2C_H_
enum atsha204a_zone
{
ATSHA204A_ZONE_CONFIG = 0,
ATSHA204A_ZONE_OTP = 1,
ATSHA204A_ZONE_DATA = 2,
};
enum atsha204a_status
{
ATSHA204A_STATUS_SUCCESS = 0x00,
ATSHA204A_STATUS_MISCOMPARE = 0x01,
ATSHA204A_STATUS_PARSE_ERROR = 0x03,
ATSHA204A_STATUS_EXEC_ERROR = 0x0F,
ATSHA204A_STATUS_AFTER_WAKE = 0x11,
ATSHA204A_STATUS_CRC_ERROR = 0xFF,
};
enum atsha204a_func
{
ATSHA204A_FUNC_RESET = 0x00,
ATSHA204A_FUNC_SLEEP = 0x01,
ATSHA204A_FUNC_IDLE = 0x02,
ATSHA204A_FUNC_COMMAND = 0x03,
};
enum atsha204a_cmd
{
ATSHA204A_CMD_READ = 0x02,
ATSHA204A_CMD_RANDOM = 0x1B,
};
struct atsha204a_resp
{
u8 length;
u8 code;
u8 data[82];
} __attribute__ ((packed));
struct atsha204a_req
{
u8 function;
u8 length;
u8 command;
u8 param1;
u16 param2;
u8 data[78];
} __attribute__ ((packed));
int atsha204a_wakeup(struct udevice *);
int atsha204a_idle(struct udevice *);
int atsha204a_sleep(struct udevice *);
int atsha204a_read(struct udevice *, enum atsha204a_zone, bool, u16, u8 *);
int atsha204a_get_random(struct udevice *, u8 *, size_t);
#endif /* _ATSHA204_I2C_H_ */
+52
View File
@@ -0,0 +1,52 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2018 Google LLC
* Written by Simon Glass <sjg@chromium.org>
*/
#ifndef __AUDIO_CODEC_H__
#define __AUDIO_CODEC_H__
#include <linux/types.h>
struct udevice;
/*
* An audio codec turns digital data into sound with various parameters to
* control its operation.
*/
/* Operations for sound */
struct audio_codec_ops {
/**
* set_params() - Set audio codec parameters
*
* @dev: Sound device
* @inteface: Interface number to use on codec
* @rate: Sampling rate in Hz
* @mclk_freq: Codec clock frequency in Hz
* @bits_per_sample: Must be 16 or 24
* @channels: Number of channels to use (1=mono, 2=stereo)
* @return 0 if OK, -ve on error
*/
int (*set_params)(struct udevice *dev, int interface, int rate,
int mclk_freq, int bits_per_sample, uint channels);
};
#define audio_codec_get_ops(dev) ((struct audio_codec_ops *)(dev)->driver->ops)
/**
* audio_codec_set_params() - Set audio codec parameters
*
* @dev: Sound device
* @inteface: Interface number to use on codec
* @rate: Sampling rate in Hz
* @mclk_freq: Codec clock frequency in Hz
* @bits_per_sample: Must be 16 or 24
* @channels: Number of channels to use (1=mono, 2=stereo)
* Return: 0 if OK, -ve on error
*/
int audio_codec_set_params(struct udevice *dev, int interface, int rate,
int mclk_freq, int bits_per_sample, uint channels);
#endif /* __AUDIO_CODEC_H__ */
+83
View File
@@ -0,0 +1,83 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* Add to readline cmdline-editing by
* (C) Copyright 2005
* JinHua Luo, GuangDong Linux Center, <luo.jinhua@gd-linux.com>
*/
#ifndef __AUTOBOOT_H
#define __AUTOBOOT_H
#include <stdbool.h>
#include <stddef.h>
#ifdef CONFIG_SANDBOX
/**
* autoboot_keyed() - check whether keyed autoboot should be used
*
* This is only implemented for sandbox since other platforms don't have a way
* of controlling the feature at runtime.
*
* Return: true if enabled, false if not
*/
bool autoboot_keyed(void);
/**
* autoboot_set_keyed() - set whether keyed autoboot should be used
*
* @autoboot_keyed: true to enable the feature, false to disable
* Return: old value of the flag
*/
bool autoboot_set_keyed(bool autoboot_keyed);
#else
static inline bool autoboot_keyed(void)
{
/* There is no runtime flag, so just use the CONFIG */
return IS_ENABLED(CONFIG_AUTOBOOT_KEYED);
}
static inline bool autoboot_set_keyed(bool autoboot_keyed)
{
/* There is no runtime flag to set */
return false;
}
#endif
#ifdef CONFIG_AUTOBOOT
/**
* bootdelay_process() - process the bootd delay
*
* Process the boot delay, boot limit, then get the value of either
* bootcmd, failbootcmd or altbootcmd depending on the current state.
* Return this command so it can be executed.
*
* Return: command to executed
*/
const char *bootdelay_process(void);
/**
* autoboot_command() - run the autoboot command
*
* If enabled, run the autoboot command returned from bootdelay_process().
* Also do the CONFIG_AUTOBOOT_MENUKEY processing if enabled.
*
* @cmd: Command to run
*/
void autoboot_command(const char *cmd);
#else
static inline const char *bootdelay_process(void)
{
return NULL;
}
static inline void autoboot_command(const char *s)
{
}
#endif
#endif
+100
View File
@@ -0,0 +1,100 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2018, Linaro Limited
*/
#ifndef _AVB_VERIFY_H
#define _AVB_VERIFY_H
#include <../lib/libavb/libavb.h>
#include <mapmem.h>
#include <mmc.h>
#define AVB_MAX_ARGS 1024
#define VERITY_TABLE_OPT_RESTART "restart_on_corruption"
#define VERITY_TABLE_OPT_LOGGING "ignore_corruption"
#define ALLOWED_BUF_ALIGN 8
enum avb_boot_state {
AVB_GREEN,
AVB_YELLOW,
AVB_ORANGE,
AVB_RED,
};
struct AvbOpsData {
struct AvbOps ops;
int mmc_dev;
enum avb_boot_state boot_state;
#ifdef CONFIG_OPTEE_TA_AVB
struct udevice *tee;
u32 session;
#endif
};
struct mmc_part {
int dev_num;
struct mmc *mmc;
struct blk_desc *mmc_blk;
struct disk_partition info;
};
enum mmc_io_type {
IO_READ,
IO_WRITE
};
AvbOps *avb_ops_alloc(int boot_device);
void avb_ops_free(AvbOps *ops);
char *avb_set_state(AvbOps *ops, enum avb_boot_state boot_state);
char *avb_set_enforce_verity(const char *cmdline);
char *avb_set_ignore_corruption(const char *cmdline);
char *append_cmd_line(char *cmdline_orig, char *cmdline_new);
const char *str_avb_io_error(AvbIOResult res);
const char *str_avb_slot_error(AvbSlotVerifyResult res);
/**
* ============================================================================
* I/O helper inline functions
* ============================================================================
*/
static inline uint64_t calc_offset(struct mmc_part *part, int64_t offset)
{
u64 part_size = part->info.size * part->info.blksz;
if (offset < 0)
return part_size + offset;
return offset;
}
static inline size_t get_sector_buf_size(void)
{
return (size_t)CONFIG_AVB_BUF_SIZE;
}
static inline void *get_sector_buf(void)
{
return map_sysmem(CONFIG_AVB_BUF_ADDR, CONFIG_AVB_BUF_SIZE);
}
static inline bool is_buf_unaligned(void *buffer)
{
return (bool)((uintptr_t)buffer % ALLOWED_BUF_ALIGN);
}
static inline int get_boot_device(AvbOps *ops)
{
struct AvbOpsData *data;
if (ops) {
data = ops->user_data;
if (data)
return data->mmc_dev;
}
return -1;
}
#endif /* _AVB_VERIFY_H */
+122
View File
@@ -0,0 +1,122 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2017, 2018
* Mario Six, Guntermann & Drunck GmbH, mario.six@gdsys.cc
*/
#ifndef _AXI_H_
#define _AXI_H_
#include <linux/types.h>
struct udevice;
/**
* enum axi_size_t - Determine size of AXI transfer
* @AXI_SIZE_8: AXI sransfer is 8-bit wide
* @AXI_SIZE_16: AXI sransfer is 16-bit wide
* @AXI_SIZE_32: AXI sransfer is 32-bit wide
*/
enum axi_size_t {
AXI_SIZE_8,
AXI_SIZE_16,
AXI_SIZE_32,
};
struct axi_ops {
/**
* read() - Read a single value from a specified address on a AXI bus
* @dev: AXI bus to read from.
* @address: The address to read from.
* @data: Pointer to a variable that takes the data value read
* from the address on the AXI bus.
* @size: The size of the data to be read.
*
* Return: 0 if OK, -ve on error.
*/
int (*read)(struct udevice *dev, ulong address, void *data,
enum axi_size_t size);
/**
* write() - Write a single value to a specified address on a AXI bus
* @dev: AXI bus to write to.
* @address: The address to write to.
* @data: Pointer to the data value to be written to the address
* on the AXI bus.
* @size: The size of the data to write.
*
* Return 0 if OK, -ve on error.
*/
int (*write)(struct udevice *dev, ulong address, void *data,
enum axi_size_t size);
};
#define axi_get_ops(dev) ((struct axi_ops *)(dev)->driver->ops)
/**
* axi_read() - Read a single value from a specified address on a AXI bus
* @dev: AXI bus to read from.
* @address: The address to read from.
* @data: Pointer to a variable that takes the data value read from the
* address on the AXI bus.
* @size: The size of the data to write.
*
* Return: 0 if OK, -ve on error.
*/
int axi_read(struct udevice *dev, ulong address, void *data,
enum axi_size_t size);
/**
* axi_write() - Write a single value to a specified address on a AXI bus
* @dev: AXI bus to write to.
* @address: The address to write to.
* @data: Pointer to the data value to be written to the address on the
* AXI bus.
* @size: The size of the data to write.
*
* Return: 0 if OK, -ve on error.
*/
int axi_write(struct udevice *dev, ulong address, void *data,
enum axi_size_t size);
struct axi_emul_ops {
/**
* read() - Read a single value from a specified address on a AXI bus
* @dev: AXI bus to read from.
* @address: The address to read from.
* @data: Pointer to a variable that takes the data value read
* from the address on the AXI bus.
* @size: The size of the data to be read.
*
* Return: 0 if OK, -ve on error.
*/
int (*read)(struct udevice *dev, ulong address, void *data,
enum axi_size_t size);
/**
* write() - Write a single value to a specified address on a AXI bus
* @dev: AXI bus to write to.
* @address: The address to write to.
* @data: Pointer to the data value to be written to the address
* on the AXI bus.
* @size: The size of the data to write.
*
* Return: 0 if OK, -ve on error.
*/
int (*write)(struct udevice *dev, ulong address, void *data,
enum axi_size_t size);
/**
* get_store() - Get address of internal storage of a emulated AXI
* device
* @dev: Emulated AXI device to get the pointer of the internal
* storage for.
* @storep: Pointer to the internal storage of the emulated AXI
* device.
*
* Return: 0 if OK, -ve on error.
*/
int (*get_store)(struct udevice *dev, u8 **storep);
};
#endif
+30
View File
@@ -0,0 +1,30 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2012 Henrik Nordstrom <henrik@henriknordstrom.net>
*/
enum axp152_reg {
AXP152_CHIP_VERSION = 0x3,
AXP152_DCDC2_VOLTAGE = 0x23,
AXP152_DCDC3_VOLTAGE = 0x27,
AXP152_DCDC4_VOLTAGE = 0x2B,
AXP152_LDO2_VOLTAGE = 0x2A,
AXP152_SHUTDOWN = 0x32,
};
#define AXP152_POWEROFF (1 << 7)
/* For axp_gpio.c */
#ifdef CONFIG_AXP152_POWER
#define AXP_POWER_STATUS 0x00
#define AXP_POWER_STATUS_ALDO_IN BIT(0)
#define AXP_GPIO0_CTRL 0x90
#define AXP_GPIO1_CTRL 0x91
#define AXP_GPIO2_CTRL 0x92
#define AXP_GPIO3_CTRL 0x93
#define AXP_GPIO_CTRL_OUTPUT_LOW 0x00 /* Drive pin low */
#define AXP_GPIO_CTRL_OUTPUT_HIGH 0x01 /* Drive pin high */
#define AXP_GPIO_CTRL_INPUT 0x02 /* Input */
#define AXP_GPIO_STATE 0x97
#define AXP_GPIO_STATE_OFFSET 0
#endif
+88
View File
@@ -0,0 +1,88 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2012 Henrik Nordstrom <henrik@henriknordstrom.net>
*/
#include <linux/bitops.h>
enum axp209_reg {
AXP209_POWER_STATUS = 0x00,
AXP209_CHIP_VERSION = 0x03,
AXP209_OUTPUT_CTRL = 0x12,
AXP209_DCDC2_VOLTAGE = 0x23,
AXP209_VRC_DCDC2_LDO3 = 0x25,
AXP209_DCDC3_VOLTAGE = 0x27,
AXP209_LDO24_VOLTAGE = 0x28,
AXP209_LDO3_VOLTAGE = 0x29,
AXP209_IRQ_ENABLE1 = 0x40,
AXP209_IRQ_ENABLE2 = 0x41,
AXP209_IRQ_ENABLE3 = 0x42,
AXP209_IRQ_ENABLE4 = 0x43,
AXP209_IRQ_ENABLE5 = 0x44,
AXP209_IRQ_STATUS5 = 0x4c,
AXP209_SHUTDOWN = 0x32,
};
#define AXP209_POWER_STATUS_ON_BY_DC BIT(0)
#define AXP209_POWER_STATUS_VBUS_USABLE BIT(4)
#define AXP209_CHIP_VERSION_MASK 0x0f
#define AXP209_OUTPUT_CTRL_EXTEN BIT(0)
#define AXP209_OUTPUT_CTRL_DCDC3 BIT(1)
#define AXP209_OUTPUT_CTRL_LDO2 BIT(2)
#define AXP209_OUTPUT_CTRL_LDO4 BIT(3)
#define AXP209_OUTPUT_CTRL_DCDC2 BIT(4)
#define AXP209_OUTPUT_CTRL_LDO3 BIT(6)
/*
* AXP209 datasheet contains wrong information about LDO3 VRC:
* - VRC is actually enabled when BIT(1) is True
* - VRC is actually not enabled by default (BIT(3) = 0 after reset)
*/
#define AXP209_VRC_LDO3_EN BIT(3)
#define AXP209_VRC_DCDC2_EN BIT(2)
#define AXP209_VRC_LDO3_800uV_uS (BIT(1) | AXP209_VRC_LDO3_EN)
#define AXP209_VRC_LDO3_1600uV_uS AXP209_VRC_LDO3_EN
#define AXP209_VRC_DCDC2_800uV_uS (BIT(0) | AXP209_VRC_DCDC2_EN)
#define AXP209_VRC_DCDC2_1600uV_uS AXP209_VRC_DCDC2_EN
#define AXP209_VRC_LDO3_MASK 0xa
#define AXP209_VRC_DCDC2_MASK 0x5
#define AXP209_VRC_DCDC2_SLOPE_SET(reg, cfg) \
(((reg) & ~AXP209_VRC_DCDC2_MASK) | \
((cfg) & AXP209_VRC_DCDC2_MASK))
#define AXP209_VRC_LDO3_SLOPE_SET(reg, cfg) \
(((reg) & ~AXP209_VRC_LDO3_MASK) | \
((cfg) & AXP209_VRC_LDO3_MASK))
#define AXP209_LDO24_LDO2_MASK 0xf0
#define AXP209_LDO24_LDO4_MASK 0x0f
#define AXP209_LDO24_LDO2_SET(reg, cfg) \
(((reg) & ~AXP209_LDO24_LDO2_MASK) | \
(((cfg) << 4) & AXP209_LDO24_LDO2_MASK))
#define AXP209_LDO24_LDO4_SET(reg, cfg) \
(((reg) & ~AXP209_LDO24_LDO4_MASK) | \
(((cfg) << 0) & AXP209_LDO24_LDO4_MASK))
#define AXP209_LDO3_VOLTAGE_FROM_LDO3IN BIT(7)
#define AXP209_LDO3_VOLTAGE_MASK 0x7f
#define AXP209_LDO3_VOLTAGE_SET(x) ((x) & AXP209_LDO3_VOLTAGE_MASK)
#define AXP209_IRQ5_PEK_UP BIT(6)
#define AXP209_IRQ5_PEK_DOWN BIT(5)
#define AXP209_POWEROFF BIT(7)
/* For axp_gpio.c */
#ifdef CONFIG_AXP209_POWER
#define AXP_POWER_STATUS 0x00
#define AXP_POWER_STATUS_ALDO_IN BIT(0)
#define AXP_GPIO0_CTRL 0x90
#define AXP_GPIO1_CTRL 0x92
#define AXP_GPIO2_CTRL 0x93
#define AXP_GPIO_CTRL_OUTPUT_LOW 0x00 /* Drive pin low */
#define AXP_GPIO_CTRL_OUTPUT_HIGH 0x01 /* Drive pin high */
#define AXP_GPIO_CTRL_INPUT 0x02 /* Input */
#define AXP_GPIO_STATE 0x94
#define AXP_GPIO_STATE_OFFSET 4
#endif
+63
View File
@@ -0,0 +1,63 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2013 Oliver Schinagl <oliver@schinagl.nl>
*
* X-Powers AXP221 Power Management IC driver
*/
/* Page 0 addresses */
#define AXP221_CHIP_ID 0x03
#define AXP221_OUTPUT_CTRL1 0x10
#define AXP221_OUTPUT_CTRL1_DCDC0_EN (1 << 0)
#define AXP221_OUTPUT_CTRL1_DCDC1_EN (1 << 1)
#define AXP221_OUTPUT_CTRL1_DCDC2_EN (1 << 2)
#define AXP221_OUTPUT_CTRL1_DCDC3_EN (1 << 3)
#define AXP221_OUTPUT_CTRL1_DCDC4_EN (1 << 4)
#define AXP221_OUTPUT_CTRL1_DCDC5_EN (1 << 5)
#define AXP221_OUTPUT_CTRL1_ALDO1_EN (1 << 6)
#define AXP221_OUTPUT_CTRL1_ALDO2_EN (1 << 7)
#define AXP221_OUTPUT_CTRL2 0x12
#define AXP221_OUTPUT_CTRL2_ELDO1_EN (1 << 0)
#define AXP221_OUTPUT_CTRL2_ELDO2_EN (1 << 1)
#define AXP221_OUTPUT_CTRL2_ELDO3_EN (1 << 2)
#define AXP221_OUTPUT_CTRL2_DLDO1_EN (1 << 3)
#define AXP221_OUTPUT_CTRL2_DLDO2_EN (1 << 4)
#define AXP221_OUTPUT_CTRL2_DLDO3_EN (1 << 5)
#define AXP221_OUTPUT_CTRL2_DLDO4_EN (1 << 6)
#define AXP221_OUTPUT_CTRL2_DCDC1SW_EN (1 << 7)
#define AXP221_OUTPUT_CTRL3 0x13
#define AXP221_OUTPUT_CTRL3_ALDO3_EN (1 << 7)
#define AXP221_DLDO1_CTRL 0x15
#define AXP221_DLDO2_CTRL 0x16
#define AXP221_DLDO3_CTRL 0x17
#define AXP221_DLDO4_CTRL 0x18
#define AXP221_ELDO1_CTRL 0x19
#define AXP221_ELDO2_CTRL 0x1a
#define AXP221_ELDO3_CTRL 0x1b
#define AXP221_DCDC1_CTRL 0x21
#define AXP221_DCDC2_CTRL 0x22
#define AXP221_DCDC3_CTRL 0x23
#define AXP221_DCDC4_CTRL 0x24
#define AXP221_DCDC5_CTRL 0x25
#define AXP221_ALDO1_CTRL 0x28
#define AXP221_ALDO2_CTRL 0x29
#define AXP221_ALDO3_CTRL 0x2a
#define AXP221_SHUTDOWN 0x32
#define AXP221_SHUTDOWN_POWEROFF (1 << 7)
#define AXP221_PAGE 0xff
/* Page 1 addresses */
#define AXP221_SID 0x20
/* For axp_gpio.c */
#ifdef CONFIG_AXP221_POWER
#define AXP_POWER_STATUS 0x00
#define AXP_POWER_STATUS_ALDO_IN BIT(0)
#define AXP_GPIO0_CTRL 0x90
#define AXP_GPIO1_CTRL 0x92
#define AXP_GPIO_CTRL_OUTPUT_LOW 0x00 /* Drive pin low */
#define AXP_GPIO_CTRL_OUTPUT_HIGH 0x01 /* Drive pin high */
#define AXP_GPIO_CTRL_INPUT 0x02 /* Input */
#define AXP_GPIO_STATE 0x94
#define AXP_GPIO_STATE_OFFSET 0
#endif
+20
View File
@@ -0,0 +1,20 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2020 Jernej Skrabec <jernej.skrabec@siol.net>
*/
enum axp305_reg {
AXP305_CHIP_VERSION = 0x3,
AXP305_OUTPUT_CTRL1 = 0x10,
AXP305_DCDCD_VOLTAGE = 0x15,
AXP305_SHUTDOWN = 0x32,
};
#define AXP305_CHIP_VERSION_MASK 0xcf
#define AXP305_OUTPUT_CTRL1_DCDCD_EN (1 << 3)
#define AXP305_POWEROFF (1 << 7)
#define AXP_POWER_STATUS 0x00
#define AXP_POWER_STATUS_ALDO_IN BIT(0)
+57
View File
@@ -0,0 +1,57 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2016 Chen-Yu Tsai <wens@csie.org>
*
* X-Powers AXP809 Power Management IC driver
*/
#define AXP809_CHIP_ID 0x03
#define AXP809_OUTPUT_CTRL1 0x10
#define AXP809_OUTPUT_CTRL1_DC5LDO_EN (1 << 0)
#define AXP809_OUTPUT_CTRL1_DCDC1_EN (1 << 1)
#define AXP809_OUTPUT_CTRL1_DCDC2_EN (1 << 2)
#define AXP809_OUTPUT_CTRL1_DCDC3_EN (1 << 3)
#define AXP809_OUTPUT_CTRL1_DCDC4_EN (1 << 4)
#define AXP809_OUTPUT_CTRL1_DCDC5_EN (1 << 5)
#define AXP809_OUTPUT_CTRL1_ALDO1_EN (1 << 6)
#define AXP809_OUTPUT_CTRL1_ALDO2_EN (1 << 7)
#define AXP809_OUTPUT_CTRL2 0x12
#define AXP809_OUTPUT_CTRL2_ELDO1_EN (1 << 0)
#define AXP809_OUTPUT_CTRL2_ELDO2_EN (1 << 1)
#define AXP809_OUTPUT_CTRL2_ELDO3_EN (1 << 2)
#define AXP809_OUTPUT_CTRL2_DLDO1_EN (1 << 3)
#define AXP809_OUTPUT_CTRL2_DLDO2_EN (1 << 4)
#define AXP809_OUTPUT_CTRL2_ALDO3_EN (1 << 5)
#define AXP809_OUTPUT_CTRL2_SWOUT_EN (1 << 6)
#define AXP809_OUTPUT_CTRL2_DC1SW_EN (1 << 7)
#define AXP809_DLDO1_CTRL 0x15
#define AXP809_DLDO2_CTRL 0x16
#define AXP809_ELDO1_CTRL 0x19
#define AXP809_ELDO2_CTRL 0x1a
#define AXP809_ELDO3_CTRL 0x1b
#define AXP809_DC5LDO_CTRL 0x1c
#define AXP809_DCDC1_CTRL 0x21
#define AXP809_DCDC2_CTRL 0x22
#define AXP809_DCDC3_CTRL 0x23
#define AXP809_DCDC4_CTRL 0x24
#define AXP809_DCDC5_CTRL 0x25
#define AXP809_ALDO1_CTRL 0x28
#define AXP809_ALDO2_CTRL 0x29
#define AXP809_ALDO3_CTRL 0x2a
#define AXP809_SHUTDOWN 0x32
#define AXP809_SHUTDOWN_POWEROFF (1 << 7)
/* For axp_gpio.c */
#ifdef CONFIG_AXP809_POWER
#define AXP_POWER_STATUS 0x00
#define AXP_POWER_STATUS_ALDO_IN BIT(0)
#define AXP_GPIO0_CTRL 0x90
#define AXP_GPIO1_CTRL 0x92
#define AXP_GPIO_CTRL_OUTPUT_LOW 0x00 /* Drive pin low */
#define AXP_GPIO_CTRL_OUTPUT_HIGH 0x01 /* Drive pin high */
#define AXP_GPIO_CTRL_INPUT 0x02 /* Input */
#define AXP_GPIO_STATE 0x94
#define AXP_GPIO_STATE_OFFSET 0
#endif
+71
View File
@@ -0,0 +1,71 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2015 Vishnu Patekar <vishnupatekar0510@gmail.com>
*
* X-Powers AXP818 Power Management IC driver
*/
#define AXP818_CHIP_ID 0x03
#define AXP818_OUTPUT_CTRL1 0x10
#define AXP818_OUTPUT_CTRL1_DCDC1_EN (1 << 0)
#define AXP818_OUTPUT_CTRL1_DCDC2_EN (1 << 1)
#define AXP818_OUTPUT_CTRL1_DCDC3_EN (1 << 2)
#define AXP818_OUTPUT_CTRL1_DCDC4_EN (1 << 3)
#define AXP818_OUTPUT_CTRL1_DCDC5_EN (1 << 4)
#define AXP818_OUTPUT_CTRL1_DCDC6_EN (1 << 5)
#define AXP818_OUTPUT_CTRL1_DCDC7_EN (1 << 6)
#define AXP818_OUTPUT_CTRL2 0x12
#define AXP818_OUTPUT_CTRL2_ELDO1_EN (1 << 0)
#define AXP818_OUTPUT_CTRL2_ELDO2_EN (1 << 1)
#define AXP818_OUTPUT_CTRL2_ELDO3_EN (1 << 2)
#define AXP818_OUTPUT_CTRL2_DLDO1_EN (1 << 3)
#define AXP818_OUTPUT_CTRL2_DLDO2_EN (1 << 4)
#define AXP818_OUTPUT_CTRL2_DLDO3_EN (1 << 5)
#define AXP818_OUTPUT_CTRL2_DLDO4_EN (1 << 6)
#define AXP818_OUTPUT_CTRL2_SW_EN (1 << 7)
#define AXP818_OUTPUT_CTRL3 0x13
#define AXP818_OUTPUT_CTRL3_FLDO1_EN (1 << 2)
#define AXP818_OUTPUT_CTRL3_FLDO2_EN (1 << 3)
#define AXP818_OUTPUT_CTRL3_FLDO3_EN (1 << 4)
#define AXP818_OUTPUT_CTRL3_ALDO1_EN (1 << 5)
#define AXP818_OUTPUT_CTRL3_ALDO2_EN (1 << 6)
#define AXP818_OUTPUT_CTRL3_ALDO3_EN (1 << 7)
#define AXP818_DLDO1_CTRL 0x15
#define AXP818_DLDO2_CTRL 0x16
#define AXP818_DLDO3_CTRL 0x17
#define AXP818_DLDO4_CTRL 0x18
#define AXP818_ELDO1_CTRL 0x19
#define AXP818_ELDO2_CTRL 0x1a
#define AXP818_ELDO3_CTRL 0x1b
#define AXP818_FLDO1_CTRL 0x1c
#define AXP818_FLDO2_3_CTRL 0x1d
#define AXP818_FLDO2_3_CTRL_FLDO3_VOL (1 << 4)
#define AXP818_DCDC1_CTRL 0x20
#define AXP818_DCDC2_CTRL 0x21
#define AXP818_DCDC3_CTRL 0x22
#define AXP818_DCDC4_CTRL 0x23
#define AXP818_DCDC5_CTRL 0x24
#define AXP818_DCDC6_CTRL 0x25
#define AXP818_DCDC7_CTRL 0x26
#define AXP818_ALDO1_CTRL 0x28
#define AXP818_ALDO2_CTRL 0x29
#define AXP818_ALDO3_CTRL 0x2a
#define AXP818_SHUTDOWN 0x32
#define AXP818_SHUTDOWN_POWEROFF (1 << 7)
/* For axp_gpio.c */
#ifdef CONFIG_AXP818_POWER
#define AXP_POWER_STATUS 0x00
#define AXP_POWER_STATUS_ALDO_IN BIT(0)
#define AXP_GPIO0_CTRL 0x90
#define AXP_GPIO1_CTRL 0x92
#define AXP_GPIO_CTRL_OUTPUT_LOW 0x00 /* Drive pin low */
#define AXP_GPIO_CTRL_OUTPUT_HIGH 0x01 /* Drive pin high */
#define AXP_GPIO_CTRL_INPUT 0x02 /* Input */
#define AXP_GPIO_STATE 0x94
#define AXP_GPIO_STATE_OFFSET 0
#endif
+61
View File
@@ -0,0 +1,61 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2015 Hans de Goede <hdegoede@redhat.com>
*
* X-Powers AX Power Management IC support header
*/
#ifndef _AXP_PMIC_H_
#define _AXP_PMIC_H_
#include <stdbool.h>
#include <axp152.h>
#include <axp209.h>
#include <axp221.h>
#include <axp305.h>
#include <axp809.h>
#include <axp818.h>
#define AXP_PMIC_MODE_REG 0x3e
#define AXP_PMIC_MODE_I2C 0x00
#define AXP_PMIC_MODE_P2WI 0x3e
#define AXP_PMIC_MODE_RSB 0x7c
#define AXP_PMIC_PRI_DEVICE_ADDR 0x3a3
#define AXP_PMIC_PRI_RUNTIME_ADDR 0x2d
#define AXP_PMIC_SEC_DEVICE_ADDR 0x745
#define AXP_PMIC_SEC_RUNTIME_ADDR 0x3a
enum {
AXP152_ID,
AXP202_ID,
AXP209_ID,
AXP221_ID,
AXP223_ID,
AXP313_ID,
AXP323_ID,
AXP717_ID,
AXP803_ID,
AXP806_ID,
AXP809_ID,
AXP813_ID,
AXP318_ID,
};
int axp_set_dcdc1(unsigned int mvolt);
int axp_set_dcdc2(unsigned int mvolt);
int axp_set_dcdc3(unsigned int mvolt);
int axp_set_dcdc4(unsigned int mvolt);
int axp_set_dcdc5(unsigned int mvolt);
int axp_set_aldo1(unsigned int mvolt);
int axp_set_aldo2(unsigned int mvolt);
int axp_set_aldo3(unsigned int mvolt);
int axp_set_aldo4(unsigned int mvolt);
int axp_set_dldo(int dldo_num, unsigned int mvolt);
int axp_set_eldo(int eldo_num, unsigned int mvolt);
int axp_set_fldo(int fldo_num, unsigned int mvolt);
int axp_set_sw(bool on);
int axp_init(void);
int axp_get_sid(unsigned int *sid);
#endif
+57
View File
@@ -0,0 +1,57 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2016 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
*/
#ifndef _BACKLIGHT_H
#define _BACKLIGHT_H
struct udevice;
enum {
BACKLIGHT_MAX = 100,
BACKLIGHT_MIN = 0,
BACKLIGHT_OFF = -1,
BACKLIGHT_DEFAULT = -2,
};
struct backlight_ops {
/**
* enable() - Enable a backlight
*
* @dev: Backlight device to enable
* @return 0 if OK, -ve on error
*/
int (*enable)(struct udevice *dev);
/**
* set_brightness - Set brightness
*
* @dev: Backlight device to update
* @percent: Brightness value (0 to 100, or BACKLIGHT_... value)
* @return 0 if OK, -ve on error
*/
int (*set_brightness)(struct udevice *dev, int percent);
};
#define backlight_get_ops(dev) ((struct backlight_ops *)(dev)->driver->ops)
/**
* backlight_enable() - Enable a backlight
*
* @dev: Backlight device to enable
* Return: 0 if OK, -ve on error
*/
int backlight_enable(struct udevice *dev);
/**
* backlight_set_brightness - Set brightness
*
* @dev: Backlight device to update
* @percent: Brightness value (0 to 100, or BACKLIGHT_... value)
* Return: 0 if OK, -ve on error
*/
int backlight_set_brightness(struct udevice *dev, int percent);
#endif
+77
View File
@@ -0,0 +1,77 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* Copyright (C) 2020 Eugeniu Rosca <rosca.eugeniu@gmail.com>
*
* Android Bootloader Control Block Header
*/
#ifndef __BCB_H__
#define __BCB_H__
#include <part.h>
enum bcb_field {
BCB_FIELD_COMMAND,
BCB_FIELD_STATUS,
BCB_FIELD_RECOVERY,
BCB_FIELD_STAGE
};
#if IS_ENABLED(CONFIG_CMD_BCB)
int bcb_find_partition_and_load(const char *iface,
int devnum, char *partp);
int bcb_load(struct blk_desc *block_description,
struct disk_partition *disk_partition);
int bcb_set(enum bcb_field field, const char *value);
/**
* bcb_get() - get the field value.
* @field: field to get
* @value_out: buffer to copy bcb field value to
* @value_size: buffer size to avoid overflow in case
* value_out is smaller then the field value
*/
int bcb_get(enum bcb_field field, char *value_out, size_t value_size);
int bcb_store(void);
void bcb_reset(void);
#else
#include <linux/errno.h>
static inline int bcb_load(struct blk_desc *block_description,
struct disk_partition *disk_partition)
{
return -EOPNOTSUPP;
}
static inline int bcb_find_partition_and_load(const char *iface,
int devnum, char *partp)
{
return -EOPNOTSUPP;
}
static inline int bcb_set(enum bcb_field field, const char *value)
{
return -EOPNOTSUPP;
}
static inline int bcb_get(enum bcb_field field,
char *value_out, size_t value_size)
{
return -EOPNOTSUPP;
}
static inline int bcb_store(void)
{
return -EOPNOTSUPP;
}
static inline void bcb_reset(void)
{
}
#endif
#endif /* __BCB_H__ */
+25
View File
@@ -0,0 +1,25 @@
/* Permission is hereby granted to copy, modify and redistribute this code
* in terms of the GNU Library General Public License, Version 2 or later,
* at your option.
*/
/* inline functions to translate to/from binary and binary-coded decimal
* (frequently found in RTC chips).
*/
#ifndef _BCD_H
#define _BCD_H
static inline unsigned int bcd2bin(unsigned int val)
{
return ((val) & 0x0f) + ((val & 0xff) >> 4) * 10;
}
static inline unsigned int bin2bcd(unsigned int val)
{
const unsigned int t = (val * 103) >> 10;
return (t << 4) | (val - t * 10);
}
#endif /* _BCD_H */
+96
View File
@@ -0,0 +1,96 @@
/* SPDX-License-Identifier: Intel */
/*
* Access to binman information at runtime
*
* Copyright 2019 Google LLC
* Written by Simon Glass <sjg@chromium.org>
*/
#ifndef _BINMAN_H_
#define _BINMAN_H_
#include <dm/ofnode.h>
/**
*struct binman_entry - information about a binman entry
*
* @image_pos: Position of entry in the image
* @size: Size of entry
*/
struct binman_entry {
u32 image_pos;
u32 size;
};
/**
* binman_entry_map() - Look up the address of an entry in memory
*
* @parent: Parent binman node
* @name: Name of entry
* @bufp: Returns a pointer to the entry
* @sizep: Returns the size of the entry
* Return: 0 on success, -EPERM if the ROM offset is not set, -ENOENT if the
* entry cannot be found, other error code other error
*/
int binman_entry_map(ofnode parent, const char *name, void **bufp, int *sizep);
/**
* binman_set_rom_offset() - Set the ROM memory-map offset
*
* @rom_offset: Offset from an image_pos to the memory-mapped address. This
* tells binman that ROM image_pos x can be addressed at rom_offset + x
*/
void binman_set_rom_offset(int rom_offset);
/**
* binman_get_rom_offset() - Get the ROM memory-map offset
*
* @returns offset from an image_pos to the memory-mapped address
*/
int binman_get_rom_offset(void);
/**
* binman_entry_find() - Find a binman symbol
*
* This searches the binman information in the device tree for a symbol of the
* given name
*
* @name: Path to entry to examine (e.g. "/read-only/u-boot")
* @entry: Returns information about the entry
* Return: 0 if OK, -ENOENT if the path is not found, other -ve value if the
* binman information is invalid (missing image-pos or size)
*/
int binman_entry_find(const char *name, struct binman_entry *entry);
/**
* binman_section_find_node() - Find a binman node
*
* @name: Name of node to look for
* Return: Node that was found, ofnode_null() if not found
*/
ofnode binman_section_find_node(const char *name);
/**
* binman_select_subnode() - Select a subnode to use to find entries
*
* Normally binman selects the top-level node for future entry requests, such as
* binman_entry_find(). This function allows a subnode to be chosen instead.
*
* @name: Name of subnode, typically a section. This must be in the top-level
* binman node
* Return: 0 if OK, -EINVAL if there is no /binman node, -ECHILD if multiple
* images are being used but the first image is not available, -ENOENT if
* the requested subnode cannot be found
*/
int binman_select_subnode(const char *name);
/**
* binman_init() - Set up the binman symbol information
*
* This locates the binary symbol information in the device tree ready for use
*
* Return: 0 if OK, -ENOMEM if out of memory, -EINVAL if there is no binman node
*/
int binman_init(void);
#endif
+133
View File
@@ -0,0 +1,133 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Symbol access for symbols set up by binman as part of the build.
*
* This allows C code to access the position of a particular part of the image
* assembled by binman.
*
* Copyright (c) 2017 Google, Inc
*/
#ifndef __BINMAN_SYM_H
#define __BINMAN_SYM_H
/* BSYM in little endian, keep in sync with tools/binman/elf.py */
#define BINMAN_SYM_MAGIC_VALUE (0x4d595342UL)
#define BINMAN_SYM_MISSING (-1UL)
#if CONFIG_IS_ENABLED(BINMAN_SYMBOLS)
/**
* binman_symname() - Internal function to get a binman symbol name
*
* @entry_name: Name of the entry to look for (e.g. 'u_boot_spl')
* @_prop_name: Property value to get from that entry (e.g. 'pos')
* @returns name of the symbol for that entry and property
*/
#define binman_symname(_entry_name, _prop_name) \
_binman_ ## _entry_name ## _prop_ ## _prop_name
/**
* binman_sym_declare() - Declare a symbol that will be used at run-time
*
* @_type: Type f the symbol (e.g. unsigned long)
* @entry_name: Name of the entry to look for (e.g. 'u_boot_spl')
* @_prop_name: Property value to get from that entry (e.g. 'pos')
*/
#define binman_sym_declare(_type, _entry_name, _prop_name) \
_type binman_symname(_entry_name, _prop_name) \
__attribute__((aligned(4), unused, section(".binman_sym")))
/**
* binman_sym_extern() - Declare a extern symbol that will be used at run-time
*
* @_type: Type f the symbol (e.g. unsigned long)
* @entry_name: Name of the entry to look for (e.g. 'u_boot_spl')
* @_prop_name: Property value to get from that entry (e.g. 'pos')
*/
#define binman_sym_extern(_type, _entry_name, _prop_name) \
extern _type binman_symname(_entry_name, _prop_name) \
__attribute__((aligned(4), unused, section(".binman_sym")))
/**
* binman_sym_declare_optional() - Declare an optional symbol
*
* If this symbol cannot be provided by binman, an error will not be generated.
* Instead the image will be assigned the value BINMAN_SYM_MISSING.
*
* @_type: Type f the symbol (e.g. unsigned long)
* @entry_name: Name of the entry to look for (e.g. 'u_boot_spl')
* @_prop_name: Property value to get from that entry (e.g. 'pos')
*/
#define binman_sym_declare_optional(_type, _entry_name, _prop_name) \
_type binman_symname(_entry_name, _prop_name) \
__attribute__((aligned(4), weak, unused, \
section(".binman_sym")))
/**
* _binman_sym_magic - Internal magic symbol for validity checks
*
* When building images, binman fills in this symbol with the magic
* value #defined above. This is used to check at runtime if the
* symbol values were filled in and are OK to use.
*/
extern unsigned long _binman_sym_magic;
/**
* DECLARE_BINMAN_MAGIC_SYM - Declare the internal magic symbol
*
* This macro declares the _binman_sym_magic symbol so that it exists.
* Declaring it here would cause errors during linking due to multiple
* definitions of the symbol.
*/
#define DECLARE_BINMAN_MAGIC_SYM \
unsigned long _binman_sym_magic \
__attribute__((aligned(4), section(".binman_sym")))
/**
* BINMAN_SYMS_OK - Check if the symbol values are valid
*
* This macro checks if the magic symbol's value is filled properly,
* which indicates that other symbols are OK to use as well.
*
* Return: 1 if binman symbol values are usable, 0 if not
*/
#define BINMAN_SYMS_OK \
(*(unsigned long *)&_binman_sym_magic == BINMAN_SYM_MAGIC_VALUE)
/**
* binman_sym() - Access a previously declared symbol
*
* This is used to get the value of a symbol. E.g.:
*
* unsigned long address = binman_sym(unsigned long, u_boot_spl, pos);
*
* @_type: Type f the symbol (e.g. unsigned long)
* @entry_name: Name of the entry to look for (e.g. 'u_boot_spl')
* @_prop_name: Property value to get from that entry (e.g. 'pos')
*
* Return: value of that property (filled in by binman), or
* BINMAN_SYM_MISSING if the value is unavailable
*/
#define binman_sym(_type, _entry_name, _prop_name) \
(BINMAN_SYMS_OK ? \
(*(_type *)&binman_symname(_entry_name, _prop_name)) : \
BINMAN_SYM_MISSING)
#else /* !CONFIG_IS_ENABLED(BINMAN_SYMBOLS) */
#define binman_sym_declare(_type, _entry_name, _prop_name)
#define binman_sym_declare_optional(_type, _entry_name, _prop_name)
#define binman_sym_extern(_type, _entry_name, _prop_name)
#define DECLARE_BINMAN_MAGIC_SYM
#define BINMAN_SYMS_OK (0)
#define binman_sym(_type, _entry_name, _prop_name) BINMAN_SYM_MISSING
#endif /* CONFIG_IS_ENABLED(BINMAN_SYMBOLS) */
#endif
+66
View File
@@ -0,0 +1,66 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (C) 1996-1999 SciTech Software, Inc.
*/
#ifndef _BIOS_EMUL_H
#define _BIOS_EMUL_H
/* Include the register header directly here */
#include "../drivers/bios_emulator/include/x86emu/regs.h"
#include <linux/types.h>
/****************************************************************************
REMARKS:
Data structure used to describe the details for the BIOS emulator system
environment as used by the X86 emulator library.
HEADER:
biosemu.h
MEMBERS:
vgaInfo - VGA BIOS information structure
biosmem_base - Base of the BIOS image
biosmem_limit - Limit of the BIOS image
busmem_base - Base of the VGA bus memory
****************************************************************************/
typedef struct {
int function;
int device;
int bus;
u32 VendorID;
u32 DeviceID;
struct udevice *pcidev;
void *BIOSImage;
u32 BIOSImageLen;
u8 LowMem[1536];
} BE_VGAInfo;
struct vesa_state;
int BootVideoCardBIOS(struct udevice *pcidev, BE_VGAInfo **pVGAInfo,
int clean_up);
/* Run a BIOS ROM natively (only supported on x86 machines) */
void bios_run_on_x86(struct udevice *dev, unsigned long addr, int vesa_mode,
struct vesa_state *mode_info);
/**
* bios_set_interrupt_handler() - Install an interrupt handler for the BIOS
*
* This installs an interrupt handler that the BIOS will call when needed.
*
* @intnum: Interrupt number to install a handler for
* @int_handler_func: Function to call to handle interrupt
*/
void bios_set_interrupt_handler(int intnum, int (*int_handler_func)(void));
void biosemu_set_interrupt_handler(int intnum, int (*int_func)(void));
int biosemu_setup(struct udevice *pcidev, BE_VGAInfo **pVGAInfo);
int biosemu_run(struct udevice *dev, uchar *bios_rom, int bios_len,
BE_VGAInfo *vga_info, int clean_up, int vesa_mode,
struct vesa_state *mode_info);
#endif
+90
View File
@@ -0,0 +1,90 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2013 Broadcom Corporation.
*/
/*
* Bitfield operations
*
* These are generic bitfield operations which allow manipulation of variable
* width bitfields within a word. One use of this would be to use data tables
* to determine how to reprogram fields within R/W hardware registers.
*
* Example:
*
* old_reg_val
* +--------+----+---+--+-----+----------+
* | | | | | old | |
* +--------+----+---+--+-----+----------+
*
* new_reg_val
* +--------+----+---+--+-----+----------+
* | | | | | new | |
* +--------+----+---+--+-----+----------+
*
* mask = bitfield_mask(10, 5);
* old = bitfield_extract(old_reg_val, 10, 5);
* new_reg_val = bitfield_replace(old_reg_val, 10, 5, new);
*
* or
*
* mask = bitfield_mask(10, 5);
* old = bitfield_extract_by_mask(old_reg_val, mask);
* new_reg_val = bitfield_replace_by_mask(old_reg_val, mask, new);
*
* The numbers 10 and 5 could for example come from data
* tables which describe all bitfields in all registers.
*/
#include <linux/bitops.h>
#include <linux/types.h>
/* Produces a mask of set bits covering a range of a uint value */
static inline uint bitfield_mask(uint shift, uint width)
{
return ((1 << width) - 1) << shift;
}
/* Extract the value of a bitfield found within a given register value */
static inline uint bitfield_extract(uint reg_val, uint shift, uint width)
{
return (reg_val & bitfield_mask(shift, width)) >> shift;
}
/*
* Replace the value of a bitfield found within a given register value
* Returns the newly modified uint value with the replaced field.
*/
static inline uint bitfield_replace(uint reg_val, uint shift, uint width,
uint bitfield_val)
{
uint mask = bitfield_mask(shift, width);
return (reg_val & ~mask) | ((bitfield_val << shift) & mask);
}
/* Produces a shift of the bitfield given a mask */
static inline uint bitfield_shift(uint mask)
{
return mask ? ffs(mask) - 1 : 0;
}
/* Extract the value of a bitfield found within a given register value */
static inline uint bitfield_extract_by_mask(uint reg_val, uint mask)
{
uint shift = bitfield_shift(mask);
return (reg_val & mask) >> shift;
}
/*
* Replace the value of a bitfield found within a given register value
* Returns the newly modified uint value with the replaced field.
*/
static inline uint bitfield_replace_by_mask(uint reg_val, uint mask,
uint bitfield_val)
{
uint shift = bitfield_shift(mask);
return (reg_val & ~mask) | ((bitfield_val << shift) & mask);
}
+808
View File
@@ -0,0 +1,808 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2000-2004
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*/
#ifndef BLK_H
#define BLK_H
#include <bouncebuf.h>
#include <dm/uclass-id.h>
#include <efi.h>
#ifdef CONFIG_SYS_64BIT_LBA
typedef uint64_t lbaint_t;
#define LBAFlength "ll"
#else
typedef ulong lbaint_t;
#define LBAFlength "l"
#endif
#define LBAF "%" LBAFlength "x"
#define LBAFU "%" LBAFlength "u"
#define DEFAULT_BLKSZ 512
struct udevice;
static inline bool blk_enabled(void)
{
return CONFIG_IS_ENABLED(BLK) || IS_ENABLED(CONFIG_SPL_LEGACY_BLOCK);
}
#define BLK_VEN_SIZE 40
#define BLK_PRD_SIZE 20
#define BLK_REV_SIZE 8
#define PART_FORMAT_PCAT 0x1
#define PART_FORMAT_GPT 0x2
/*
* Identifies the partition table type (ie. MBR vs GPT GUID) signature
*/
enum sig_type {
SIG_TYPE_NONE,
SIG_TYPE_MBR,
SIG_TYPE_GUID,
SIG_TYPE_COUNT /* Number of signature types */
};
/*
* With driver model (CONFIG_BLK) this is uclass platform data, accessible
* with dev_get_uclass_plat(dev)
*/
struct blk_desc {
/*
* TODO: With driver model we should be able to use the parent
* device's uclass instead.
*/
enum uclass_id uclass_id; /* type of the interface */
int devnum; /* device number */
unsigned char part_type; /* partition type */
unsigned char target; /* target SCSI ID */
unsigned char lun; /* target LUN */
unsigned char hwpart; /* HW partition, e.g. for eMMC */
unsigned char type; /* device type */
unsigned char removable; /* removable device */
/* device can use 48bit addr (ATA/ATAPI v7) */
bool lba48;
unsigned char atapi; /* Use ATAPI protocol */
unsigned char bb; /* Use bounce buffer */
lbaint_t lba; /* number of blocks */
unsigned long blksz; /* block size */
int log2blksz; /* for convenience: log2(blksz) */
char vendor[BLK_VEN_SIZE + 1]; /* device vendor string */
char product[BLK_PRD_SIZE + 1]; /* device product number */
char revision[BLK_REV_SIZE + 1]; /* firmware revision */
enum sig_type sig_type; /* Partition table signature type */
union {
uint32_t mbr_sig; /* MBR integer signature */
efi_guid_t guid_sig; /* GPT GUID Signature */
};
#if CONFIG_IS_ENABLED(BLK)
/*
* For now we have a few functions which take struct blk_desc as a
* parameter. This field allows them to look up the associated
* device. Once these functions are removed we can drop this field.
*/
struct udevice *bdev;
#else
unsigned long (*block_read)(struct blk_desc *block_dev,
lbaint_t start,
lbaint_t blkcnt,
void *buffer);
unsigned long (*block_write)(struct blk_desc *block_dev,
lbaint_t start,
lbaint_t blkcnt,
const void *buffer);
unsigned long (*block_erase)(struct blk_desc *block_dev,
lbaint_t start,
lbaint_t blkcnt);
void *priv; /* driver private struct pointer */
#endif
};
#define BLOCK_CNT(size, blk_desc) (PAD_COUNT(size, blk_desc->blksz))
#define PAD_TO_BLOCKSIZE(size, blk_desc) \
(PAD_SIZE(size, blk_desc->blksz))
#if CONFIG_IS_ENABLED(BLOCK_CACHE)
/**
* blkcache_read() - attempt to read a set of blocks from cache
*
* @param iftype - uclass_id_x for type of device
* @param dev - device index of particular type
* @param start - starting block number
* @param blkcnt - number of blocks to read
* @param blksz - size in bytes of each block
* @param buffer - buffer to contain cached data
*
* Return: - 1 if block returned from cache, 0 otherwise.
*/
int blkcache_read(int iftype, int dev,
lbaint_t start, lbaint_t blkcnt,
unsigned long blksz, void *buffer);
/**
* blkcache_fill() - make data read from a block device available
* to the block cache
*
* @param iftype - uclass_id_x for type of device
* @param dev - device index of particular type
* @param start - starting block number
* @param blkcnt - number of blocks available
* @param blksz - size in bytes of each block
* @param buffer - buffer containing data to cache
*
*/
void blkcache_fill(int iftype, int dev,
lbaint_t start, lbaint_t blkcnt,
unsigned long blksz, void const *buffer);
/**
* blkcache_invalidate() - discard the cache for a set of blocks
* because of a write or device (re)initialization.
*
* @iftype - UCLASS_ID_ for type of device, or -1 for any
* @dev - device index of particular type, if @iftype is not -1
*/
void blkcache_invalidate(int iftype, int dev);
/**
* blkcache_configure() - configure block cache
*
* @param blocks - maximum blocks per entry
* @param entries - maximum entries in cache
*/
void blkcache_configure(unsigned blocks, unsigned entries);
/*
* statistics of the block cache
*/
struct block_cache_stats {
unsigned hits;
unsigned misses;
unsigned entries; /* current entry count */
unsigned max_blocks_per_entry;
unsigned max_entries;
};
/**
* get_blkcache_stats() - return statistics and reset
*
* @param stats - statistics are copied here
*/
void blkcache_stats(struct block_cache_stats *stats);
/** blkcache_free() - free all memory allocated to the block cache */
void blkcache_free(void);
#else
static inline int blkcache_read(int iftype, int dev,
lbaint_t start, lbaint_t blkcnt,
unsigned long blksz, void *buffer)
{
return 0;
}
static inline void blkcache_fill(int iftype, int dev,
lbaint_t start, lbaint_t blkcnt,
unsigned long blksz, void const *buffer) {}
static inline void blkcache_invalidate(int iftype, int dev) {}
static inline void blkcache_free(void) {}
#endif
struct udevice;
/* Operations on block devices */
struct blk_ops {
/**
* read() - read from a block device
*
* @dev: Device to read from
* @start: Start block number to read (0=first)
* @blkcnt: Number of blocks to read
* @buffer: Destination buffer for data read
* @return number of blocks read, or -ve error number (see the
* IS_ERR_VALUE() macro
*/
unsigned long (*read)(struct udevice *dev, lbaint_t start,
lbaint_t blkcnt, void *buffer);
/**
* write() - write to a block device
*
* @dev: Device to write to
* @start: Start block number to write (0=first)
* @blkcnt: Number of blocks to write
* @buffer: Source buffer for data to write
* @return number of blocks written, or -ve error number (see the
* IS_ERR_VALUE() macro
*/
unsigned long (*write)(struct udevice *dev, lbaint_t start,
lbaint_t blkcnt, const void *buffer);
/**
* erase() - erase a section of a block device
*
* @dev: Device to (partially) erase
* @start: Start block number to erase (0=first)
* @blkcnt: Number of blocks to erase
* @return number of blocks erased, or -ve error number (see the
* IS_ERR_VALUE() macro
*/
unsigned long (*erase)(struct udevice *dev, lbaint_t start,
lbaint_t blkcnt);
/**
* select_hwpart() - select a particular hardware partition
*
* Some devices (e.g. MMC) can support partitioning at the hardware
* level. This is quite separate from the normal idea of
* software-based partitions. MMC hardware partitions must be
* explicitly selected. Once selected only the region of the device
* covered by that partition is accessible.
*
* The MMC standard provides for two boot partitions (numbered 1 and 2),
* rpmb (3), and up to 4 addition general-purpose partitions (4-7).
*
* @dev: Block device to update
* @hwpart: Hardware partition number to select. 0 means the raw
* device, 1 is the first partition, 2 is the second, etc.
* @return 0 if OK, -ve on error
*/
int (*select_hwpart)(struct udevice *dev, int hwpart);
#if IS_ENABLED(CONFIG_BOUNCE_BUFFER)
/**
* buffer_aligned() - test memory alignment of block operation buffer
*
* Some devices have limited DMA capabilities and require that the
* buffers passed to them fit specific properties. This optional
* callback can be used to indicate whether a buffer alignment is
* suitable for the device DMA or not, and trigger use of generic
* bounce buffer implementation to help use of unsuitable buffers
* at the expense of performance degradation.
*
* @dev: Block device associated with the request
* @state: Bounce buffer state
* @return 1 if OK, 0 if unaligned
*/
int (*buffer_aligned)(struct udevice *dev, struct bounce_buffer *state);
#endif /* CONFIG_BOUNCE_BUFFER */
};
#if CONFIG_IS_ENABLED(BLK)
/*
* These functions should take struct udevice instead of struct blk_desc,
* but this is convenient for migration to driver model. Add a 'd' prefix
* to the function operations, so that blk_read(), etc. can be reserved for
* functions with the correct arguments.
*/
unsigned long blk_dread(struct blk_desc *block_dev, lbaint_t start,
lbaint_t blkcnt, void *buffer);
unsigned long blk_dwrite(struct blk_desc *block_dev, lbaint_t start,
lbaint_t blkcnt, const void *buffer);
unsigned long blk_derase(struct blk_desc *block_dev, lbaint_t start,
lbaint_t blkcnt);
#endif /* BLK */
/**
* blk_read() - Read from a block device
*
* @dev: Device to read from
* @start: Start block for the read
* @blkcnt: Number of blocks to read
* @buf: Place to put the data
* @return number of blocks read (which may be less than @blkcnt),
* or -ve on error. This never returns 0 unless @blkcnt is 0
*/
long blk_read(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
void *buffer);
/**
* blk_write() - Write to a block device
*
* @dev: Device to write to
* @start: Start block for the write
* @blkcnt: Number of blocks to write
* @buf: Data to write
* @return number of blocks written (which may be less than @blkcnt),
* or -ve on error. This never returns 0 unless @blkcnt is 0
*/
long blk_write(struct udevice *dev, lbaint_t start, lbaint_t blkcnt,
const void *buffer);
/**
* blk_erase() - Erase part of a block device
*
* @dev: Device to erase
* @start: Start block for the erase
* @blkcnt: Number of blocks to erase
* @return number of blocks erased (which may be less than @blkcnt),
* or -ve on error. This never returns 0 unless @blkcnt is 0
*/
long blk_erase(struct udevice *dev, lbaint_t start, lbaint_t blkcnt);
/**
* blk_find_device() - Find a block device
*
* This function does not activate the device. The device will be returned
* whether or not it is activated.
*
* @uclass_id: Interface type (enum uclass_id_t)
* @devnum: Device number (specific to each interface type)
* @devp: the device, if found
* Return: 0 if found, -ENODEV if no device found, or other -ve error value
*/
int blk_find_device(int uclass_id, int devnum, struct udevice **devp);
/**
* blk_get_device() - Find and probe a block device ready for use
*
* @uclass_id: Interface type (enum uclass_id_t)
* @devnum: Device number (specific to each interface type)
* @devp: the device, if found
* Return: 0 if found, -ENODEV if no device found, or other -ve error value
*/
int blk_get_device(int uclass_id, int devnum, struct udevice **devp);
/**
* blk_first_device() - Find the first device for a given interface
*
* The device is probed ready for use
*
* @devnum: Device number (specific to each interface type)
* @devp: the device, if found
* Return: 0 if found, -ENODEV if no device, or other -ve error value
*/
int blk_first_device(int uclass_id, struct udevice **devp);
/**
* blk_next_device() - Find the next device for a given interface
*
* This can be called repeatedly after blk_first_device() to iterate through
* all devices of the given interface type.
*
* The device is probed ready for use
*
* @devp: On entry, the previous device returned. On exit, the next
* device, if found
* Return: 0 if found, -ENODEV if no device, or other -ve error value
*/
int blk_next_device(struct udevice **devp);
/**
* blk_create_devicef() - Create a new named block device
*
* @parent: Parent of the new device
* @drv_name: Driver name to use for the block device
* @name: Name for the device (parent name is prepended)
* @uclass_id: Interface type (enum uclass_id_t)
* @devnum: Device number, specific to the interface type, or -1 to
* allocate the next available number
* @blksz: Block size of the device in bytes (typically 512)
* @lba: Total number of blocks of the device
* @devp: the new device (which has not been probed)
*/
int blk_create_devicef(struct udevice *parent, const char *drv_name,
const char *name, int uclass_id, int devnum, int blksz,
lbaint_t lba, struct udevice **devp);
/**
* blk_probe_or_unbind() - Try to probe
*
* Try to probe the device, primarily for enumerating partitions.
* If it fails, the device itself is unbound since it means that it won't
* work any more.
*
* @dev: The device to probe
* Return: 0 if OK, -ve on error
*/
int blk_probe_or_unbind(struct udevice *dev);
/**
* blk_unbind_all() - Unbind all device of the given interface type
*
* The devices are removed and then unbound.
*
* @uclass_id: Interface type to unbind
* Return: 0 if OK, -ve on error
*/
int blk_unbind_all(int uclass_id);
/**
* blk_find_max_devnum() - find the maximum device number for an interface type
*
* Finds the last allocated device number for an interface type @uclass_id. The
* next number is safe to use for a newly allocated device.
*
* @uclass_id: Interface type to scan
* Return: maximum device number found, or -ENODEV if none, or other -ve on
* error
*/
int blk_find_max_devnum(enum uclass_id uclass_id);
/**
* blk_next_free_devnum() - get the next device number for an interface type
*
* Finds the next number that is safe to use for a newly allocated device for
* an interface type @uclass_id.
*
* @uclass_id: Interface type to scan
* Return: next device number safe to use, or -ve on error
*/
int blk_next_free_devnum(enum uclass_id uclass_id);
/**
* blk_select_hwpart() - select a hardware partition
*
* Select a hardware partition if the device supports it (typically MMC does)
*
* @dev: Device to update
* @hwpart: Partition number to select
* Return: 0 if OK, -ve on error
*/
int blk_select_hwpart(struct udevice *dev, int hwpart);
/**
* blk_find_from_parent() - find a block device by looking up its parent
*
* All block devices have a parent 'media' device which provides the block
* driver for the block device, ensuring that access to the underlying medium
* is available.
*
* The block device is not activated by this function. See
* blk_get_from_parent() for that.
*
* @parent: Media device
* @devp: Returns the associated block device, if any
* Returns: 0 if OK, -ENODEV if @parent is not a media device and has no
* UCLASS_BLK child
*/
int blk_find_from_parent(struct udevice *parent, struct udevice **devp);
/**
* blk_get_from_parent() - obtain a block device by looking up its parent
*
* All block devices have a parent 'media' device which provides the block
* driver for the block device, ensuring that access to the underlying medium
* is available.
*
* The block device is probed and ready for use.
*
* @parent: Media device
* @devp: Returns the associated block device, if any
* Returns: 0 if OK, -ENODEV if @parent is not a media device and has no
* UCLASS_BLK child
*/
int blk_get_from_parent(struct udevice *parent, struct udevice **devp);
/**
* blk_get_devtype() - Get the device type of a block device
*
* @dev: Block device to check
* Return: device tree, i.e. the uclass name of its parent, e.g. "mmc"
*/
const char *blk_get_devtype(struct udevice *dev);
/**
* blk_get_by_device() - Get the block device descriptor for the given device
* @dev: Instance of a storage device (the parent of the block device)
*
* Return: With block device descriptor on success , NULL if there is no such
* block device.
*/
struct blk_desc *blk_get_by_device(struct udevice *dev);
/**
* blk_get_desc() - Get the block device descriptor for the given device number
*
* @uclass_id: Interface type
* @devnum: Device number (0 = first)
* @descp: Returns block device descriptor on success
* Return: 0 on success, -ENODEV if there is no such device and no device
* with a higher device number, -ENOENT if there is no such device but there
* is one with a higher number, or other -ve on other error.
*/
int blk_get_desc(enum uclass_id uclass_id, int devnum, struct blk_desc **descp);
#if !CONFIG_IS_ENABLED(BLK)
#include <errno.h>
/*
* These functions should take struct udevice instead of struct blk_desc,
* but this is convenient for migration to driver model. Add a 'd' prefix
* to the function operations, so that blk_read(), etc. can be reserved for
* functions with the correct arguments.
*/
static inline ulong blk_dread(struct blk_desc *block_dev, lbaint_t start,
lbaint_t blkcnt, void *buffer)
{
ulong blks_read;
if (blkcache_read(block_dev->uclass_id, block_dev->devnum,
start, blkcnt, block_dev->blksz, buffer))
return blkcnt;
/*
* We could check if block_read is NULL and return -ENOSYS. But this
* bloats the code slightly (cause some board to fail to build), and
* it would be an error to try an operation that does not exist.
*/
blks_read = block_dev->block_read(block_dev, start, blkcnt, buffer);
if (blks_read == blkcnt)
blkcache_fill(block_dev->uclass_id, block_dev->devnum,
start, blkcnt, block_dev->blksz, buffer);
return blks_read;
}
static inline ulong blk_dwrite(struct blk_desc *block_dev, lbaint_t start,
lbaint_t blkcnt, const void *buffer)
{
blkcache_invalidate(block_dev->uclass_id, block_dev->devnum);
return block_dev->block_write(block_dev, start, blkcnt, buffer);
}
static inline ulong blk_derase(struct blk_desc *block_dev, lbaint_t start,
lbaint_t blkcnt)
{
blkcache_invalidate(block_dev->uclass_id, block_dev->devnum);
return block_dev->block_erase(block_dev, start, blkcnt);
}
/**
* struct blk_driver - Driver for block interface types
*
* This provides access to the block devices for each interface type. One
* driver should be provided using U_BOOT_LEGACY_BLK() for each interface
* type that is to be supported.
*
* @uclass_idname: Interface type name
* @uclass_id: Interface type
* @max_devs: Maximum number of devices supported
* @desc: Pointer to list of devices for this interface type,
* or NULL to use @get_dev() instead
*/
struct blk_driver {
const char *uclass_idname;
enum uclass_id uclass_id;
int max_devs;
struct blk_desc *desc;
/**
* get_dev() - get a pointer to a block device given its number
*
* Each interface allocates its own devices and typically
* struct blk_desc is contained with the interface's data structure.
* There is no global numbering for block devices. This method allows
* the device for an interface type to be obtained when @desc is NULL.
*
* @devnum: Device number (0 for first device on that interface,
* 1 for second, etc.
* @descp: Returns pointer to the block device on success
* @return 0 if OK, -ve on error
*/
int (*get_dev)(int devnum, struct blk_desc **descp);
/**
* select_hwpart() - Select a hardware partition
*
* Some devices (e.g. MMC) can support partitioning at the hardware
* level. This is quite separate from the normal idea of
* software-based partitions. MMC hardware partitions must be
* explicitly selected. Once selected only the region of the device
* covered by that partition is accessible.
*
* The MMC standard provides for two boot partitions (numbered 1 and 2),
* rpmb (3), and up to 4 addition general-purpose partitions (4-7).
* Partition 0 is the main user-data partition.
*
* @desc: Block device descriptor
* @hwpart: Hardware partition number to select. 0 means the main
* user-data partition, 1 is the first partition, 2 is
* the second, etc.
* @return 0 if OK, other value for an error
*/
int (*select_hwpart)(struct blk_desc *desc, int hwpart);
};
/*
* Declare a new U-Boot legacy block driver. New drivers should use driver
* model (UCLASS_BLK).
*/
#define U_BOOT_LEGACY_BLK(__name) \
ll_entry_declare(struct blk_driver, __name, blk_driver)
struct blk_driver *blk_driver_lookup_type(int uclass_id);
#endif /* !CONFIG_BLK */
/**
* blk_get_devnum_by_uclass_idname() - Get a block device by type and number
*
* This looks through the available block devices of the given type, returning
* the one with the given @devnum.
*
* @uclass_id: Block device type
* @devnum: Device number
* Return: point to block device descriptor, or NULL if not found
*/
struct blk_desc *blk_get_devnum_by_uclass_id(enum uclass_id uclass_id, int devnum);
/**
* blk_get_devnum_by_uclass_idname() - Get block device by type name and number
*
* This looks up the block device type based on @uclass_idname, then calls
* blk_get_devnum_by_uclass_id().
*
* @uclass_idname: Block device type name
* @devnum: Device number
* Return: point to block device descriptor, or NULL if not found
*/
struct blk_desc *blk_get_devnum_by_uclass_idname(const char *uclass_idname,
int devnum);
/**
* blk_dselect_hwpart() - select a hardware partition
*
* This selects a hardware partition (such as is supported by MMC). The block
* device size may change as this effectively points the block device to a
* partition at the hardware level. See the select_hwpart() method above.
*
* @desc: Block device descriptor for the device to select
* @hwpart: Partition number to select
* Return: 0 if OK, -ve on error
*/
int blk_dselect_hwpart(struct blk_desc *desc, int hwpart);
/**
* blk_list_part() - list the partitions for block devices of a given type
*
* This looks up the partition type for each block device of type @uclass_id,
* then displays a list of partitions.
*
* @uclass_id: Block device type
* Return: 0 if OK, -ENODEV if there is none of that type
*/
int blk_list_part(enum uclass_id uclass_id);
/**
* blk_list_devices() - list the block devices of a given type
*
* This lists each block device of the type @uclass_id, showing the capacity
* as well as type-specific information.
*
* @uclass_id: Block device type
*/
void blk_list_devices(enum uclass_id uclass_id);
/**
* blk_show_device() - show information about a given block device
*
* This shows the block device capacity as well as type-specific information.
*
* @uclass_id: Block device type
* @devnum: Device number
* Return: 0 if OK, -ENODEV for invalid device number
*/
int blk_show_device(enum uclass_id uclass_id, int devnum);
/**
* blk_print_device_num() - show information about a given block device
*
* This is similar to blk_show_device() but returns an error if the block
* device type is unknown.
*
* @uclass_id: Block device type
* @devnum: Device number
* Return: 0 if OK, -ENODEV for invalid device number, -ENOENT if the block
* device is not connected
*/
int blk_print_device_num(enum uclass_id uclass_id, int devnum);
/**
* blk_print_part_devnum() - print the partition information for a device
*
* @uclass_id: Block device type
* @devnum: Device number
* Return: 0 if OK, -ENOENT if the block device is not connected, -ENOSYS if
* the interface type is not supported, other -ve on other error
*/
int blk_print_part_devnum(enum uclass_id uclass_id, int devnum);
/**
* blk_select_hwpart_devnum() - select a hardware partition
*
* This is similar to blk_dselect_hwpart() but it looks up the interface and
* device number.
*
* @uclass_id: Block device type
* @devnum: Device number
* @hwpart: Partition number to select
* Return: 0 if OK, -ve on error
*/
int blk_select_hwpart_devnum(enum uclass_id uclass_id, int devnum, int hwpart);
/**
* blk_get_uclass_name() - Get the name of an interface type
*
* @uclass_id: Interface type to check
* Return: name of interface, or NULL if none
*/
const char *blk_get_uclass_name(enum uclass_id uclass_id);
/**
* blk_common_cmd() - handle common commands with block devices
*
* @args: Number of arguments to the command (argv[0] is the command itself)
* @argv: Command arguments
* @uclass_id: Interface type
* @cur_devnump: Current device number for this interface type
* Return: 0 if OK, CMD_RET_ERROR on error
*/
int blk_common_cmd(int argc, char *const argv[], enum uclass_id uclass_id,
int *cur_devnump);
enum blk_flag_t {
BLKF_FIXED = 1 << 0,
BLKF_REMOVABLE = 1 << 1,
BLKF_BOTH = BLKF_FIXED | BLKF_REMOVABLE,
};
/**
* blk_first_device_err() - Get the first block device
*
* The device returned is probed if necessary, and ready for use
*
* @flags: Indicates type of device to return
* @devp: Returns pointer to the first device in that uclass, or NULL if none
* Return: 0 if found, -ENODEV if not found, other -ve on error
*/
int blk_first_device_err(enum blk_flag_t flags, struct udevice **devp);
/**
* blk_next_device_err() - Get the next block device
*
* The device returned is probed if necessary, and ready for use
*
* @flags: Indicates type of device to return
* @devp: On entry, pointer to device to lookup. On exit, returns pointer
* to the next device in the uclass if no error occurred, or -ENODEV if
* there is no next device.
* Return: 0 if found, -ENODEV if not found, other -ve on error
*/
int blk_next_device_err(enum blk_flag_t flags, struct udevice **devp);
/**
* blk_foreach_probe() - Helper function to iteration through block devices
*
* This creates a for() loop which works through the available devices in
* a uclass in order from start to end. Devices are probed if necessary,
* and ready for use.
*
* @flags: Indicates type of device to return
* @dev: struct udevice * to hold the current device. Set to NULL when there
* are no more devices.
*/
#define blk_foreach_probe(flags, pos) \
for (int _ret = blk_first_device_err(flags, &(pos)); \
!_ret && pos; \
_ret = blk_next_device_err(flags, &(pos)))
/**
* blk_count_devices() - count the number of devices of a particular type
*
* @flags: Indicates type of device to find
* Return: number of devices matching those flags
*/
int blk_count_devices(enum blk_flag_t flag);
#endif
+136
View File
@@ -0,0 +1,136 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2023 Addiva Elektronik
* Author: Tobias Waldekranz <tobias@waldekranz.com>
*/
#ifndef _BLKMAP_H
#define _BLKMAP_H
#include <blk.h>
#include <dm/lists.h>
/**
* struct blkmap - Block map
*
* Data associated with a blkmap.
*
* @label: Human readable name of this blkmap
* @blk: Underlying block device
* @slices: List of slices associated with this blkmap
*/
struct blkmap {
char *label;
struct udevice *blk;
struct list_head slices;
};
/**
* blkmap_map_linear() - Map region of other block device
*
* @dev: Blkmap to create the mapping on
* @blknr: Start block number of the mapping
* @blkcnt: Number of blocks to map
* @lblk: The target block device of the mapping
* @lblknr: The start block number of the target device
* Returns: 0 on success, negative error code on failure
*/
int blkmap_map_linear(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
struct udevice *lblk, lbaint_t lblknr);
/**
* blkmap_map_mem() - Map region of memory
*
* @dev: Blkmap to create the mapping on
* @blknr: Start block number of the mapping
* @blkcnt: Number of blocks to map
* @addr: The target memory address of the mapping
* Returns: 0 on success, negative error code on failure
*/
int blkmap_map_mem(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
void *addr);
/**
* blkmap_map_pmem() - Map region of physical memory
*
* Ensures that a valid physical to virtual memory mapping for the
* requested region is valid for the lifetime of the mapping, on
* architectures that require it (sandbox).
*
* @dev: Blkmap to create the mapping on
* @blknr: Start block number of the mapping
* @blkcnt: Number of blocks to map
* @paddr: The target physical memory address of the mapping
* @preserve: Mapping intended to be preserved for subsequent stages,
* like the OS (e.g. ISO installer)
* Returns: 0 on success, negative error code on failure
*/
int blkmap_map_pmem(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt,
phys_addr_t paddr, bool preserve);
/**
* blkmap_from_label() - Find blkmap from label
*
* @label: Label of the requested blkmap
* Returns: A pointer to the blkmap on success, NULL on failure
*/
struct udevice *blkmap_from_label(const char *label);
/**
* blkmap_create() - Create new blkmap
*
* @label: Label of the new blkmap
* @devp: If not NULL, updated with the address of the resulting device
* Returns: 0 on success, negative error code on failure
*/
int blkmap_create(const char *label, struct udevice **devp);
/**
* blkmap_destroy() - Destroy blkmap
*
* @dev: The blkmap to be destroyed
* Returns: 0 on success, negative error code on failure
*/
int blkmap_destroy(struct udevice *dev);
/**
* blkmap_create_ramdisk() - Create new ramdisk with blkmap
*
* @label: Label of the new blkmap
* @image_addr: Target memory start address of this mapping
* @image_size: Target memory size of this mapping
* @devp: Updated with the address of the created blkmap device
* Returns: 0 on success, negative error code on failure
*/
int blkmap_create_ramdisk(const char *label, ulong image_addr, ulong image_size,
struct udevice **devp);
/**
* blkmap_get_preserved_pmem_slices() - Look for memory mapped preserved slices
* @cb: Callback function to call for the blkmap slice
* @ctx: Argument to be passed to the callback function
*
* The function is used to iterate through all the blkmap slices, looking
* specifically for memory mapped blkmap mapping which has been
* created with the preserve attribute. The function looks for such slices
* with the relevant attributes and then calls the callback function which
* then does additional configuration as needed. The callback function is
* invoked for all the discovered slices, unless there is an error returned
* by the callback, in which case the function returns that error.
*
* The callback function has the following arguments
* @ctx: Argument to be passed to the callback function
* @addr: Start address of the memory mapped slice
* @size: Size of the memory mapped slice
*
* Typically, the callback will perform some configuration needed for the
* information passed on to it. An example of this would be setting up the
* pmem node in a device-tree(passed through the ctx argument) with the
* parameters passed on to the callback.
*
* Return: 0 on success, negative error on failure
*/
int blkmap_get_preserved_pmem_slices(int (*cb)(void *ctx, u64 addr,
u64 size), void *ctx);
#endif /* _BLKMAP_H */
+549
View File
@@ -0,0 +1,549 @@
/* SPDX-License-Identifier: GPL-2.0+ BSD-3-Clause */
/*
* This provides a standard way of passing information between boot phases
* (TPL -> SPL -> U-Boot proper.)
*
* It consists of a list of blobs of data, tagged with their owner / contents.
* The list resides in memory and can be updated by SPL, U-Boot, etc.
*
* Design goals for bloblist:
*
* 1. Small and efficient structure. This avoids UUIDs or 16-byte name fields,
* since a 32-bit tag provides enough space for all the tags we will even need.
* If UUIDs are desired, they can be added inside a particular blob.
*
* 2. Avoids use of pointers, so the structure can be relocated in memory. The
* data in each blob is inline, rather than using pointers.
*
* 3. Bloblist is designed to start small in TPL or SPL, when only a few things
* are needed, like the memory size or whether console output should be enabled.
* Then it can grow in U-Boot proper, e.g. to include space for ACPI tables.
*
* 4. The bloblist structure is simple enough that it can be implemented in a
* small amount of C code. The API does not require use of strings or UUIDs,
* which would add to code size. For Thumb-2 the code size needed in SPL is
* approximately 940 bytes (e.g. for chromebook_bob).
*
* 5. Bloblist uses 8-byte alignment internally and is designed to start on a
* 8-byte boundary. Its headers are 8 bytes long. It is possible to achieve
* larger alignment (e.g. 16 bytes) by adding a dummy header, For use in SPL and
* TPL the alignment can be relaxed, since it can be relocated to an aligned
* address in U-Boot proper.
*
* 6. Bloblist is designed to be passed to Linux as reserved memory. While linux
* doesn't understand the bloblist header, it can be passed the indivdual blobs.
* For example, ACPI tables can reside in a blob and the address of those is
* passed to Linux, without Linux ever being away of the existence of a
* bloblist. Having all the blobs contiguous in memory simplifies the
* reserved-memory space.
*
* 7. Bloblist tags are defined in the enum below. There is an area for
* project-specific stuff (e.g. U-Boot, TF-A) and vendor-specific stuff, e.g.
* something used only on a particular SoC. There is also a private area for
* temporary, local use.
*
* 8. Bloblist includes a simple checksum, so that each boot phase can update
* this and allow the next phase to check that all is well. While the bloblist
* is small, this is quite cheap to calculate. When it grows (e.g. in U-Boot\
* proper), the CPU is likely running faster, so it is not prohibitive. Having
* said that, U-Boot is often the last phase that uses bloblist, so calculating
* the checksum there may not be necessary.
*
* 9. It would be possible to extend bloblist to support a non-contiguous
* structure, e.g. by creating a blob type that points to the next bloblist.
* This does not seem necessary for now. It adds complexity and code. We can
* always just copy it.
*
* 10. Bloblist is designed for simple structures, those that can be defined by
* a single C struct. More complex structures should be passed in a device tree.
* There are some exceptions, chiefly the various binary structures that Intel
* is fond of creating. But device tree provides a dictionary-type format which
* is fairly efficient (for use in U-Boot proper and Linux at least), along with
* a schema and a good set of tools. New formats should be designed around
* device tree rather than creating new binary formats, unless they are needed
* early in boot (where libfdt's 3KB of overhead is too large) and are trival
* enough to be described by a C struct.
*
* Copyright 2018 Google, Inc
* Written by Simon Glass <sjg@chromium.org>
* Adjusted July 2023 to match Firmware handoff specification, Release 0.9
*/
#ifndef __BLOBLIST_H
#define __BLOBLIST_H
#include <mapmem.h>
#include <linux/errno.h>
enum {
BLOBLIST_VERSION = 1,
BLOBLIST_MAGIC = 0x4a0fb10b,
BLOBLIST_REGCONV_SHIFT_64 = 32,
BLOBLIST_REGCONV_SHIFT_32 = 24,
BLOBLIST_REGCONV_MASK = 0xff,
BLOBLIST_REGCONV_VER = 1,
BLOBLIST_BLOB_ALIGN_LOG2 = 3,
BLOBLIST_BLOB_ALIGN = 1 << BLOBLIST_BLOB_ALIGN_LOG2,
BLOBLIST_ALIGN_LOG2 = 3,
BLOBLIST_ALIGN = 1 << BLOBLIST_ALIGN_LOG2,
};
/* Supported tags - add new ones to tag_name in bloblist.c */
enum bloblist_tag_t {
BLOBLISTT_VOID = 0,
/*
* Standard area to allocate blobs used across firmware components, for
* things that are very commonly used, particularly in multiple
* projects.
*/
BLOBLISTT_AREA_FIRMWARE_TOP = 0x1,
/*
* Devicetree for use by firmware. On some platforms this is passed to
* the OS also
*/
BLOBLISTT_CONTROL_FDT = 1,
BLOBLISTT_HOB_BLOCK = 2,
BLOBLISTT_HOB_LIST = 3,
BLOBLISTT_ACPI_TABLES = 4,
BLOBLISTT_TPM_EVLOG = 5,
BLOBLISTT_TPM_CRB_BASE = 6,
BLOBLISTT_FDT_OVERLAY = 7,
BLOBLISTT_ACPI_PP = 8,
/* Standard area to allocate blobs used across firmware components */
BLOBLISTT_AREA_FIRMWARE = 0x10,
BLOBLISTT_TPM2_TCG_LOG = 0x10, /* TPM v2 log space */
BLOBLISTT_TCPA_LOG = 0x11, /* TPM log space */
/*
* Advanced Configuration and Power Interface Global Non-Volatile
* Sleeping table. This forms part of the ACPI tables passed to Linux.
*/
BLOBLISTT_ACPI_GNVS = 0x12,
/* Standard area to allocate blobs used for Trusted Firmware */
BLOBLISTT_AREA_TF = 0x100,
BLOBLISTT_OPTEE_PAGABLE_PART = 0x100,
/* Other standard area to allocate blobs */
BLOBLISTT_AREA_OTHER = 0x200,
BLOBLISTT_INTEL_VBT = 0x200, /* Intel Video-BIOS table */
BLOBLISTT_SMBIOS_TABLES = 0x201, /* SMBIOS tables for x86 */
BLOBLISTT_VBOOT_CTX = 0x202, /* Chromium OS verified boot context */
/*
* Tags from here are on reserved for private use within a single
* firmware binary (i.e. a single executable or phase of a project).
* These tags can be passed between binaries within a local
* implementation, but cannot be used in upstream code. Allocate a
* tag in one of the areas above if you want that.
*
* Project-specific tags are permitted here. Projects can be open source
* or not, but the format of the data must be fuily documented in an
* open source project, including all fields, bits, etc. Naming should
* be: BLOBLISTT_<project>_<purpose_here>
*
* Vendor-specific tags are also permitted. Projects can be open source
* or not, but the format of the data must be fuily documented in an
* open source project, including all fields, bits, etc. Naming should
* be BLOBLISTT_<vendor>_<purpose_here>
*/
BLOBLISTT_PRIVATE_AREA = 0xfff000,
BLOBLISTT_U_BOOT_SPL_HANDOFF = 0xfff000, /* Hand-off info from SPL */
BLOBLISTT_VBE = 0xfff001, /* VBE per-phase state */
BLOBLISTT_U_BOOT_VIDEO = 0xfff002, /* Video info from SPL */
};
/**
* struct bloblist_hdr - header for the bloblist
*
* This is stored at the start of the bloblist which is always on a 16-byte
* boundary. Records follow this header. The bloblist normally stays in the
* same place in memory as SPL and U-Boot execute, but it can be safely moved
* around.
*
* None of the bloblist headers themselves contain pointers but it is possible
* to put pointers inside a bloblist record if desired. This is not encouraged,
* since it can make part of the bloblist inaccessible if the pointer is
* no-longer valid. It is better to just store all the data inside a bloblist
* record.
*
* Each bloblist record is aligned to a 16-byte boundary and follows immediately
* from the last.
*
* @magic: BLOBLIST_MAGIC
* @chksum: checksum for the entire bloblist allocated area. Since any of the
* blobs can be altered after being created, this checksum is only valid
* when the bloblist is finalized before jumping to the next stage of boot.
* This is the value needed to make all checksummed bytes sum to 0
* @version: BLOBLIST_VERSION
* @hdr_size: Size of this header, normally sizeof(struct bloblist_hdr). The
* first bloblist_rec starts at this offset from the start of the header
* @align_log2: Power of two of the maximum alignment required by this list
* @used_size: Size allocated so far for this bloblist. This starts out as
* sizeof(bloblist_hdr) since we need at least that much space to store a
* valid bloblist
* @total_size: The number of total bytes that the bloblist can occupy.
* Any blob producer must check if there is sufficient space before adding
* a record to the bloblist.
* @flags: Space for BLOBLISTF... flags (none yet)
* @spare: Spare space (for future use)
*/
struct bloblist_hdr {
u32 magic;
u8 chksum;
u8 version;
u8 hdr_size;
u8 align_log2;
u32 used_size;
u32 total_size;
u32 flags;
u32 spare;
};
/**
* struct bloblist_rec - record for the bloblist
*
* The bloblist contains a number of records each consisting of this record
* structure followed by the data contained. Each records is 16-byte aligned.
*
* NOTE: Only exported for testing purposes. Do not use this struct.
*
* @tag_and_hdr_size: Tag indicating what the record contains (bottom 24 bits), and
* size of this header (top 8 bits), normally sizeof(struct bloblist_rec).
* The record's data starts at this offset from the start of the record
* @size: Size of record in bytes, excluding the header size. This does not
* need to be aligned (e.g. 3 is OK).
*/
struct bloblist_rec {
u32 tag_and_hdr_size;
u32 size;
};
enum {
BLOBLISTR_TAG_SHIFT = 0,
BLOBLISTR_TAG_MASK = 0xffffffU << BLOBLISTR_TAG_SHIFT,
BLOBLISTR_HDR_SIZE_SHIFT = 24,
BLOBLISTR_HDR_SIZE_MASK = 0xffU << BLOBLISTR_HDR_SIZE_SHIFT,
BLOBLIST_HDR_SIZE = sizeof(struct bloblist_hdr),
BLOBLIST_REC_HDR_SIZE = sizeof(struct bloblist_rec),
};
/*
* struct dto_blob_hdr - Blob inline header for BLOBLISTT_FDT_OVERLAY
*
* @subtype: IMP-DEF per the agreement between the DT overlay producer and
* consumer. Default value is 0.
*/
struct dto_blob_hdr {
u64 subtype;
};
/**
* bloblist_check_magic() - return a bloblist if the magic matches
*
* @addr: Address to check
* Return: pointer to bloblist, if the magic matches, else NULL
*/
static inline void *bloblist_check_magic(ulong addr)
{
u32 *ptr;
if (!addr)
return NULL;
ptr = map_sysmem(addr, 0);
if (*ptr != BLOBLIST_MAGIC)
return NULL;
return ptr;
}
#if CONFIG_IS_ENABLED(BLOBLIST)
/**
* bloblist_get_blob() - Find a blob and get the size of it
*
* Searches the bloblist and returns the blob with the matching tag
*
* @tag: Tag to search for (enum bloblist_tag_t)
* @sizep: Size of the blob found
* Return: pointer to bloblist if found, or NULL if not found
*/
void *bloblist_get_blob(uint tag, int *sizep);
#else
static inline void *bloblist_get_blob(uint tag, int *sizep)
{
return NULL;
}
#endif
#if CONFIG_IS_ENABLED(BLOBLIST)
/**
* bloblist_apply_blobs() - Apply the data of blobs by tag
*
* Scan the bloblist, find the blobs with the matching tag and apply the data
* of blobs
*
* @tag: Tag to search for (enum bloblist_tag_t)
* @func: Function to apply the data of blobs
* Return: 0 if OK, otherwise error.
*/
int bloblist_apply_blobs(uint tag, int (*func)(void **data, int size));
#else
static inline int bloblist_apply_blobs(uint tag,
int (*func)(void **data, int size))
{
return -EPERM;
}
#endif
/**
* bloblist_find() - Find a blob
*
* Searches the bloblist and returns the blob with the matching tag
*
* @tag: Tag to search for (enum bloblist_tag_t)
* @size: Expected size of the blob, or 0 for any size
* Return: pointer to blob if found, or NULL if not found, or a blob was found
* but it is the wrong size
*/
void *bloblist_find(uint tag, int size);
/**
* bloblist_add() - Add a new blob
*
* Add a new blob to the bloblist
*
* This should only be called if you konw there is no existing blob for a
* particular tag. It is typically safe to call in the first phase of U-Boot
* (e.g. TPL or SPL). After that, bloblist_ensure() should be used instead.
*
* @tag: Tag to add (enum bloblist_tag_t)
* @size: Size of the blob
* @align_log2: Alignment of the blob (in bytes log2), 0 for default
* Return: pointer to the newly added block, or NULL if there is not enough
* space for the blob
*/
void *bloblist_add(uint tag, int size, int align_log2);
/**
* bloblist_ensure_size() - Find or add a blob
*
* Find an existing blob, or add a new one if not found
*
* @tag: Tag to add (enum bloblist_tag_t)
* @size: Size of the blob
* @blobp: Returns a pointer to blob on success
* @align_log2: Alignment of the blob (in bytes log2), 0 for default
* Return: 0 if OK, -ENOSPC if it is missing and could not be added due to lack
* of space, or -ESPIPE it exists but has the wrong size
*/
int bloblist_ensure_size(uint tag, int size, int align_log2, void **blobp);
/**
* bloblist_ensure() - Find or add a blob
*
* Find an existing blob, or add a new one if not found
*
* @tag: Tag to add (enum bloblist_tag_t)
* @size: Size of the blob
* Return: pointer to blob, or NULL if it is missing and could not be added due
* to lack of space, or it exists but has the wrong size
*/
void *bloblist_ensure(uint tag, int size);
/**
* bloblist_ensure_size_ret() - Find or add a blob
*
* Find an existing blob, or add a new one if not found
*
* @tag: Tag to add (enum bloblist_tag_t)
* @sizep: Size of the blob to create; returns size of actual blob
* @blobp: Returns a pointer to blob on success
* Return: 0 if OK, -ENOSPC if it is missing and could not be added due to lack
* of space
*/
int bloblist_ensure_size_ret(uint tag, int *sizep, void **blobp);
/**
* bloblist_resize() - resize a blob
*
* Any blobs above this one are relocated up or down. The resized blob remains
* in the same place.
*
* @tag: Tag to add (enum bloblist_tag_t)
* @new_size: New size of the blob (>0 to expand, <0 to contract)
* Return: 0 if OK, -ENOSPC if the bloblist does not have enough space, -ENOENT
* if the tag is not found
*/
int bloblist_resize(uint tag, int new_size);
/**
* bloblist_new() - Create a new, empty bloblist of a given size
*
* @addr: Address of bloblist
* @size: Initial size for bloblist
* @flags: Flags to use for bloblist
* @align_log2: Log base 2 of maximum alignment provided by this bloblist
* Return: 0 if OK, -EFAULT if addr is not aligned correctly, -ENOSPC is the
* area is not large enough
*/
int bloblist_new(ulong addr, uint size, uint flags, uint align_log2);
/**
* bloblist_check() - Check if a bloblist exists
*
* @addr: Address of bloblist
* @size: Reserved space size for blobsize, or 0 to use the total size
* Return: 0 if OK, -ENOENT if the magic number doesn't match (indicating that
* there problem is no bloblist at the given address) or any fields for header
* size, used size and total size do not match, -EPROTONOSUPPORT
* if the version does not match, -EIO if the checksum does not match,
* -EFBIG if the reserved space size is small than the total size or total size
* is 0
*/
int bloblist_check(ulong addr, uint size);
#if CONFIG_IS_ENABLED(BLOBLIST)
/**
* bloblist_finish() - Set up the bloblist for the next U-Boot part
*
* This sets the correct checksum for the bloblist. This ensures that the
* bloblist will be detected correctly by the next phase of U-Boot.
*
* Return: 0
*/
int bloblist_finish(void);
#else
static inline int bloblist_finish(void)
{
return 0;
}
#endif /* BLOBLIST */
/**
* bloblist_get_stats() - Get information about the bloblist
*
* This returns useful information about the bloblist
*
* @basep: Returns base address of bloblist
* @tsizep: Returns the total number of bytes of the bloblist
* @usizep: Returns the number of used bytes of the bloblist
*/
void bloblist_get_stats(ulong *basep, ulong *tsizep, ulong *usizep);
/**
* bloblist_get_base() - Get the base address of the bloblist
*
* Return: base address of bloblist
*/
ulong bloblist_get_base(void);
/**
* bloblist_get_size() - Get the size of the bloblist
*
* Return: the size in bytes
*/
ulong bloblist_get_size(void);
/**
* bloblist_get_total_size() - Get the total size of the bloblist
*
* Return: the size in bytes
*/
ulong bloblist_get_total_size(void);
/**
* bloblist_show_stats() - Show information about the bloblist
*
* This shows useful information about the bloblist on the console
*/
void bloblist_show_stats(void);
/**
* bloblist_show_list() - Show a list of blobs in the bloblist
*
* This shows a list of blobs, showing their address, size and tag.
*/
void bloblist_show_list(void);
/**
* bloblist_tag_name() - Get the name for a tag
*
* @tag: Tag to check
* Return: name of tag, or "invalid" if an invalid tag is provided
*/
const char *bloblist_tag_name(enum bloblist_tag_t tag);
/**
* bloblist_reloc() - Relocate the bloblist and optionally resize it
*
* @to: Pointer to new bloblist location (must not overlap old location)
* @to_size: New size for bloblist
* Return: 0 if OK, -ENOSPC if the new size is small than the bloblist total
* size.
*/
int bloblist_reloc(void *to, uint to_size);
/**
* bloblist_init() - Init the bloblist system with a single bloblist
*
* This locates and sets up the blocklist for use.
*
* If CONFIG_BLOBLIST_FIXED is selected, it uses CONFIG_BLOBLIST_ADDR and
* CONFIG_BLOBLIST_SIZE to set up a bloblist for use by U-Boot.
*
* If CONFIG_BLOBLIST_ALLOC is selected, it allocates memory for a bloblist of
* size CONFIG_BLOBLIST_SIZE.
*
* If CONFIG_BLOBLIST_PASSAGE_MANDATORY is selected, bloblist in the incoming
* standard passage is mandatorily required.
*
* Sets GD_FLG_BLOBLIST_READY in global_data flags on success
*
* Return: 0 if OK, -ve on error
*/
int bloblist_init(void);
#if CONFIG_IS_ENABLED(BLOBLIST)
/**
* bloblist_maybe_init() - Init the bloblist system if not already done
*
* Calls bloblist_init() if the GD_FLG_BLOBLIST_READY flag is not set
*
* Return: 0 if OK, -ve on error
*/
int bloblist_maybe_init(void);
#else
static inline int bloblist_maybe_init(void)
{
return 0;
}
#endif /* BLOBLIST */
/**
* bloblist_check_reg_conv() - Check whether the bloblist is compliant to
* the register conventions according to the
* Firmware Handoff spec.
*
* @rfdt: Register that holds the FDT base address.
* @rzero: Register that must be zero.
* @rsig: Register that holds signature and register conventions version.
* @xlist: Register that holds the transfer list.
* Return: 0 if OK, -EIO if the bloblist is not compliant to the register
* conventions.
*/
int bloblist_check_reg_conv(ulong rfdt, ulong rzero, ulong rsig, ulong xlist);
/**
* xferlist_from_boot_arg() - Get bloblist from the boot args.
*
* @addr: Address of the bloblist
* Return: 0 if OK, else on error
*/
int xferlist_from_boot_arg(ulong *addr);
#endif /* __BLOBLIST_H */
+61
View File
@@ -0,0 +1,61 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/* (C) Copyright 2002
* Detlev Zundel, DENX Software Engineering, dzu@denx.de.
*/
/************************************************************************/
/* ** Layout of a bmp file */
/************************************************************************/
#ifndef _BMP_H_
#define _BMP_H_
#include <linux/compiler.h>
struct __packed bmp_color_table_entry {
__u8 blue;
__u8 green;
__u8 red;
__u8 reserved;
};
/* When accessing these fields, remember that they are stored in little
endian format, so use linux macros, e.g. le32_to_cpu(width) */
struct __packed bmp_header {
/* Header */
char signature[2];
__u32 file_size;
__u32 reserved;
__u32 data_offset;
/* InfoHeader */
__u32 size;
__u32 width;
__u32 height;
__u16 planes;
__u16 bit_count;
__u32 compression;
__u32 image_size;
__u32 x_pixels_per_m;
__u32 y_pixels_per_m;
__u32 colors_used;
__u32 colors_important;
/* ColorTable */
};
struct bmp_image {
struct bmp_header header;
/* We use a zero sized array just as a placeholder for variable
sized array */
struct bmp_color_table_entry color_table[0];
};
/* Data in the bmp_image is aligned to this length */
#define BMP_DATA_ALIGN 4
/* Constants for the compression field */
#define BMP_BI_RGB 0
#define BMP_BI_RLE8 1
#define BMP_BI_RLE4 2
#endif /* _BMP_H_ */
+35
View File
@@ -0,0 +1,35 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2024 Google LLC
* Written by: Simon Glass <sjg@chromeium.org>
*/
#ifndef __BOARD_F
#define __BOARD_F
/**
* struct board_f: Information used only before relocation
*
* This struct is set up in board_init_f() and used to deal with relocation. It
* is not available after relocation.
*/
struct board_f {
/**
* @new_fdt: relocated device tree
*/
void *new_fdt;
/**
* @fdt_size: space reserved for relocated device space
*/
unsigned long fdt_size;
/**
* @new_bootstage: relocated boot stage information
*/
struct bootstage_data *new_bootstage;
/**
* @new_bloblist: relocated blob list information
*/
struct bloblist_hdr *new_bloblist;
};
#endif
+13
View File
@@ -0,0 +1,13 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2017 Texas Instruments
* Written by Franklin Cooper Jr. <fcooper@ti.com>
*/
/**
* locate_dtb_in_fit - Find a DTB matching the board in a FIT image
* @fit: pointer to the FIT image
*
* Return: a pointer to a matching DTB blob if found, NULL otherwise
*/
void *locate_dtb_in_fit(const void *fit);
+141
View File
@@ -0,0 +1,141 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2012
* Stefan Roese, DENX Software Engineering, sr@denx.de.
*/
#ifndef _BOOTCOUNT_H__
#define _BOOTCOUNT_H__
#include <asm/global_data.h>
#include <asm/io.h>
#include <asm/byteorder.h>
#include <env.h>
#include <linux/bitops.h>
#ifdef CONFIG_DM_BOOTCOUNT
struct bootcount_ops {
/**
* get() - get the current bootcount value
*
* Returns the current counter value of the bootcount backing
* store.
*
* @dev: Device to read from
* @bootcount: Address to put the current bootcount value
*/
int (*get)(struct udevice *dev, u32 *bootcount);
/**
* set() - set a bootcount value (e.g. to reset or increment)
*
* Sets the value in the bootcount backing store.
*
* @dev: Device to read from
* @bootcount: New bootcount value to store
*/
int (*set)(struct udevice *dev, const u32 bootcount);
};
/* Access the operations for a bootcount device */
#define bootcount_get_ops(dev) ((struct bootcount_ops *)(dev)->driver->ops)
/**
* dm_bootcount_get() - Read the current value from a bootcount storage
*
* @dev: Device to read from
* @bootcount: Place to put the current bootcount
* Return: 0 if OK, -ve on error
*/
int dm_bootcount_get(struct udevice *dev, u32 *bootcount);
/**
* dm_bootcount_set() - Write a value to a bootcount storage
*
* @dev: Device to read from
* @bootcount: Value to be written to the backing storage
* Return: 0 if OK, -ve on error
*/
int dm_bootcount_set(struct udevice *dev, u32 bootcount);
#endif
/* Bit masks for magic and count parts in single word scheme */
#define BOOTCOUNT_MAGIC_MASK GENMASK(31, 16)
#define BOOTCOUNT_COUNT_MASK GENMASK(15, 0)
/** bootcount_store() - store the current bootcount */
void bootcount_store(ulong);
/**
* bootcount_load() - load the current bootcount
*
* Return: bootcount, read from the appropriate location
*/
ulong bootcount_load(void);
#if defined(CONFIG_SPL_BOOTCOUNT_LIMIT) || defined(CONFIG_TPL_BOOTCOUNT_LIMIT) || defined(CONFIG_BOOTCOUNT_LIMIT)
#ifdef CONFIG_SYS_BOOTCOUNT_LE
static inline void raw_bootcount_store(volatile u32 *addr, u32 data)
{
out_le32(addr, data);
}
static inline u32 raw_bootcount_load(volatile u32 *addr)
{
return in_le32(addr);
}
#else
static inline void raw_bootcount_store(volatile u32 *addr, u32 data)
{
out_be32(addr, data);
}
static inline u32 raw_bootcount_load(volatile u32 *addr)
{
return in_be32(addr);
}
#endif
DECLARE_GLOBAL_DATA_PTR;
static inline int bootcount_error(void)
{
unsigned long bootcount = bootcount_load();
unsigned long bootlimit = env_get_ulong("bootlimit", 10, 0);
if (bootlimit && bootcount > bootlimit) {
printf("Warning: Bootlimit (%lu) exceeded.", bootlimit);
if (!(gd->flags & GD_FLG_SPL_INIT))
printf(" Using altbootcmd.");
printf("\n");
return 1;
}
return 0;
}
static inline void bootcount_inc(void)
{
unsigned long bootcount = bootcount_load();
if (gd->flags & GD_FLG_SPL_INIT) {
bootcount_store(++bootcount);
return;
}
#ifndef CONFIG_XPL_BUILD
/* Only increment bootcount when no bootcount support in SPL */
#if !defined(CONFIG_SPL_BOOTCOUNT_LIMIT) && !defined(CONFIG_TPL_BOOTCOUNT_LIMIT)
bootcount_store(++bootcount);
#endif
env_set_ulong("bootcount", bootcount);
#endif /* !CONFIG_XPL_BUILD */
}
#else
static inline int bootcount_error(void) { return 0; }
static inline void bootcount_inc(void) {}
#endif /* CONFIG_SPL_BOOTCOUNT_LIMIT || CONFIG_TPL_BOOTCOUNT_LIMIT || CONFIG_BOOTCOUNT_LIMIT */
#endif /* _BOOTCOUNT_H__ */
+443
View File
@@ -0,0 +1,443 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2021 Google LLC
* Written by Simon Glass <sjg@chromium.org>
*/
#ifndef __bootdev_h
#define __bootdev_h
#include <dm/uclass-id.h>
#include <linux/list.h>
struct bootflow;
struct bootflow_iter;
struct bootstd_priv;
struct udevice;
/**
* enum bootdev_prio_t - priority of each bootdev
*
* These values are associated with each bootdev and set up by the driver.
*
* Smallest value is the highest priority. By default, bootdevs are scanned from
* highest to lowest priority
*
* BOOTDEVP_0_NONE: Invalid value, do not use
* @BOOTDEVP_6_PRE_SCAN: Scan bootdevs with this priority always, before
* starting any bootflow scan
* @BOOTDEVP_2_INTERNAL_FAST: Internal devices which don't need scanning and
* generally very quick to access, e.g. less than 100ms
* @BOOTDEVP_3_INTERNAL_SLOW: Internal devices which don't need scanning but
* take a significant fraction of a second to access
* @BOOTDEVP_4_SCAN_FAST: External devices which need scanning or bus
* enumeration to find, but this enumeration happens quickly, typically under
* 100ms
* @BOOTDEVP_5_SCAN_SLOW: External devices which need scanning or bus
* enumeration to find. The enumeration takes significant fraction of a second
* to complete
* @BOOTDEVP_6_NET_BASE: Basic network devices which are quickly and easily
* available. Typically used for an internal Ethernet device
* @BOOTDEVP_7_NET_FALLBACK: Secondary network devices which require extra time
* to start up, or are less desirable. Typically used for secondary Ethernet
* devices. Note that USB ethernet devices are found during USB enumeration,
* so do not use this priority
*/
enum bootdev_prio_t {
BOOTDEVP_0_NONE,
BOOTDEVP_1_PRE_SCAN,
BOOTDEVP_2_INTERNAL_FAST,
BOOTDEVP_3_INTERNAL_SLOW,
BOOTDEVP_4_SCAN_FAST,
BOOTDEVP_5_SCAN_SLOW,
BOOTDEVP_6_NET_BASE,
BOOTDEVP_7_NET_FALLBACK,
BOOTDEVP_COUNT,
};
struct bootdev_hunter;
/**
* bootdev_hunter_func - function to probe for bootdevs of a given type
*
* This should hunt around for bootdevs of the given type, binding them as it
* finds them. This may involve bus enumeration, etc.
*
* @info: Info structure describing this hunter
* @show: true to show information from the hunter
* Returns: 0 if OK, -ENOENT on device not found, otherwise -ve on error
*/
typedef int (*bootdev_hunter_func)(struct bootdev_hunter *info, bool show);
/**
* struct bootdev_hunter - information about how to hunt for bootdevs
*
* @prio: Scanning priority of this hunter
* @uclass: Uclass ID for the media associated with this bootdev
* @drv: bootdev driver for the things found by this hunter
* @hunt: Function to call to hunt for bootdevs of this type (NULL if none)
*
* Some bootdevs are not visible until other devices are enumerated. For
* example, USB bootdevs only appear when the USB bus is enumerated.
*
* On the other hand, we don't always want to enumerate all the buses just to
* find the first valid bootdev. Ideally we want to work through them in
* priority order, so that the fastest bootdevs are discovered first.
*
* This struct holds information about the bootdev so we can determine the probe
* order and how to hunt for bootdevs of this type
*/
struct bootdev_hunter {
enum bootdev_prio_t prio;
enum uclass_id uclass;
struct driver *drv;
bootdev_hunter_func hunt;
};
/* declare a new bootdev hunter */
#define BOOTDEV_HUNTER(__name) \
ll_entry_declare(struct bootdev_hunter, __name, bootdev_hunter)
/* access a bootdev hunter by name */
#define BOOTDEV_HUNTER_GET(__name) \
ll_entry_get(struct bootdev_hunter, __name, bootdev_hunter)
/**
* struct bootdev_uc_plat - uclass information about a bootdev
*
* This is attached to each device in the bootdev uclass and accessible via
* dev_get_uclass_plat(dev)
*
* @piro: Priority of this bootdev
*/
struct bootdev_uc_plat {
enum bootdev_prio_t prio;
};
/** struct bootdev_ops - Operations for the bootdev uclass */
struct bootdev_ops {
/**
* get_bootflow() - get a bootflow (optional)
*
* If this is NULL then the default implementaton is used, which is
* default_get_bootflow()
*
* @dev: Bootflow device to check
* @iter: Provides current dev, part, method to get. Should update
* max_part if there is a partition table. Should update state,
* subdir, fname, buf, size according to progress
* @bflow: Updated bootflow if found
* Return: 0 if OK, -ESHUTDOWN if there are no more bootflows on this
* device, -ENOSYS if this device doesn't support bootflows,
* other -ve value on other error
*/
int (*get_bootflow)(struct udevice *dev, struct bootflow_iter *iter,
struct bootflow *bflow);
};
#define bootdev_get_ops(dev) ((struct bootdev_ops *)(dev)->driver->ops)
/**
* bootdev_get_bootflow() - get a bootflow
*
* @dev: Bootflow device to check
* @iter: Provides current part, method to get
* @bflow: Returns bootflow if found
* Return: 0 if OK, -ESHUTDOWN if there are no more bootflows on this device,
* -ENOSYS if this device doesn't support bootflows, other -ve value on
* other error
*/
int bootdev_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
struct bootflow *bflow);
/**
* bootdev_bind() - Bind a new named bootdev device
*
* @parent: Parent of the new device
* @drv_name: Driver name to use for the bootdev device
* @name: Name for the device (parent name is prepended)
* @devp: the new device (which has not been probed)
*/
int bootdev_bind(struct udevice *parent, const char *drv_name, const char *name,
struct udevice **devp);
/**
* bootdev_find_in_blk() - Find a bootdev in a block device
*
* @dev: Bootflow device associated with this block device
* @blk: Block device to search
* @iter: Provides current dev, part, method to get. Should update
* max_part if there is a partition table
* @bflow: On entry, provides information about the partition and device to
* check. On exit, returns bootflow if found
* Return: 0 if found, -ESHUTDOWN if no more bootflows, other -ve on error
*/
int bootdev_find_in_blk(struct udevice *dev, struct udevice *blk,
struct bootflow_iter *iter, struct bootflow *bflow);
/**
* bootdev_list() - List all available bootdevs
*
* @probe: true to probe devices, false to leave them as is
*/
void bootdev_list(bool probe);
/**
* bootdev_first_bootflow() - Get the first bootflow from a bootdev
*
* Returns the first bootflow attached to a bootdev
*
* @dev: bootdev device
* @bflowp: Returns a pointer to the bootflow
* Return: 0 if found, -ENOENT if there are no bootflows
*/
int bootdev_first_bootflow(struct udevice *dev, struct bootflow **bflowp);
/**
* bootdev_next_bootflow() - Get the next bootflow from a bootdev
*
* Returns the next bootflow attached to a bootdev
*
* @bflowp: On entry, the last bootflow returned , e.g. from
* bootdev_first_bootflow()
* Return: 0 if found, -ENOENT if there are no more bootflows
*/
int bootdev_next_bootflow(struct bootflow **bflowp);
/**
* bootdev_find_by_label() - Look up a bootdev by label
*
* Each bootdev has a label which contains the media-uclass name and a number,
* e.g. 'mmc2'. This looks up the label and returns the associated bootdev
*
* The lookup is performed based on the media device's sequence number. So for
* 'mmc2' this looks for a device in UCLASS_MMC with a dev_seq() of 2.
*
* @label: Label to look up (e.g. "mmc1" or "mmc0")
* @devp: Returns the bootdev device found, or NULL if none (note it does not
* return the media device, but its bootdev child)
* @method_flagsp: If non-NULL, returns any flags implied by the label
* (enum bootflow_meth_flags_t), 0 if none. Unset if function fails
* Return: 0 if OK, -EINVAL if the uclass is not supported by this board,
* -ENOENT if there is no device with that number
*/
int bootdev_find_by_label(const char *label, struct udevice **devp,
int *method_flagsp);
/**
* bootdev_find_by_any() - Find a bootdev by name, label or sequence
*
* @name: name (e.g. "mmc2.bootdev"), label ("mmc2"), or sequence ("2") to find
* @devp: returns the device found, on success
* @method_flagsp: If non-NULL, returns any flags implied by the label
* (enum bootflow_meth_flags_t), 0 if none. Unset if function fails
* Return: 0 if OK, -EPFNOSUPPORT if the uclass is not supported by this board,
* -ENOENT if there is no device with that number
*/
int bootdev_find_by_any(const char *name, struct udevice **devp,
int *method_flagsp);
/**
* bootdev_setup_iter() - Set up iteration through bootdevs
*
* This sets up the an interation, based on the provided device or label. If
* neither is provided, the iteration is based on the priority of each bootdev,
* the * bootdev-order property in the bootstd node (or the boot_targets env
* var).
*
* @iter: Iterator to update with the order
* @label: label to scan, or NULL to scan all
* @devp: On entry, *devp is NULL to scan all, otherwise this is the (single)
* device to scan. Returns the first device to use, which is the passed-in
* @devp if it was non-NULL
* @method_flagsp: If non-NULL, returns any flags implied by the label
* (enum bootflow_meth_flags_t), 0 if none
* Return: 0 if OK, -ENOENT if no bootdevs, -ENOMEM if out of memory, other -ve
* on other error
*/
int bootdev_setup_iter(struct bootflow_iter *iter, const char *label,
struct udevice **devp, int *method_flagsp);
/**
* bootdev_list_hunters() - List the available bootdev hunters
*
* These provide a way to find new bootdevs by enumerating buses, etc. This
* function lists the available hunters
*
* @std: Pointer to bootstd private info
*/
void bootdev_list_hunters(struct bootstd_priv *std);
/**
* bootdev_hunt() - Hunt for bootdevs matching a particular spec
*
* This runs the selected hunter (or all if @spec is NULL) to try to find new
* bootdevs.
*
* @spec: Spec to match, e.g. "mmc0", or NULL for any. If provided, this must
* match a uclass name so that the hunter can be determined. Any trailing number
* is ignored
* @show: true to show each hunter before using it
* Returns: 0 if OK, -ve on error
*/
int bootdev_hunt(const char *spec, bool show);
/**
* bootdev_hunt_prio() - Hunt for bootdevs of a particular priority
*
* This runs all hunters which can find bootdevs of the given priority.
*
* @prio: Priority to use
* @show: true to show each hunter as it is used
* Returns: 0 if OK, -ve on error
*/
int bootdev_hunt_prio(enum bootdev_prio_t prio, bool show);
/**
* bootdev_unhunt() - Mark a device as needing to be hunted again
*
* @id: uclass ID to update
* Return: 0 if done, -EALREADY if already in this state, -ENOENT if no hunter
* found for that uclass
*/
int bootdev_unhunt(enum uclass_id id);
/**
* bootdev_hunt_and_find_by_label() - Hunt for bootdevs by label
*
* Runs the hunter for the label, then tries to find the bootdev, possible
* created by the hunter
*
* @label: Label to look up (e.g. "mmc1" or "mmc0")
* @devp: Returns the bootdev device found, or NULL if none (note it does not
* return the media device, but its bootdev child)
* @method_flagsp: If non-NULL, returns any flags implied by the label
* (enum bootflow_meth_flags_t), 0 if none. Unset if function fails
* Return: 0 if OK, -EINVAL if the uclass is not supported by this board,
* -ENOENT if there is no device with that number
*/
int bootdev_hunt_and_find_by_label(const char *label, struct udevice **devp,
int *method_flagsp);
/**
* bootdev_next_label() - Move to the next bootdev in the label sequence
*
* Looks through the remaining labels until it finds one that matches a bootdev.
* Bootdev scanners are used as needed. For example a label "mmc1" results in
* running the "mmc" bootdrv.
*
* @iter: Iteration info, containing iter->cur_label
* @devp: New bootdev found, if any was found
* @method_flagsp: If non-NULL, returns any flags implied by the label
* (enum bootflow_meth_flags_t), 0 if none
* Returns 0 if OK, -ENODEV if no bootdev was found
*/
int bootdev_next_label(struct bootflow_iter *iter, struct udevice **devp,
int *method_flagsp);
/**
* bootdev_next_prio() - Find the next bootdev in priority order
*
* This moves @devp to the next bootdev with the current priority. If there is
* none, then it moves to the next priority and scans for new bootdevs there.
*
* @iter: Iteration info, containing iter->cur_prio
* @devp: On entry this is the previous bootdev that was considered. On exit
* this is the new bootdev, if any was found
* Returns 0 on success (*devp is updated), -ENODEV if there are no more
* bootdevs at any priority
*/
int bootdev_next_prio(struct bootflow_iter *iter, struct udevice **devp);
#if CONFIG_IS_ENABLED(BOOTSTD)
/**
* bootdev_setup_for_dev() - Bind a new bootdev device (deprecated)
*
* Please use bootdev_setup_for_sibling_blk() instead since it supports multiple
* (child) block devices for each media device.
*
* Creates a bootdev device as a child of @parent. This should be called from
* the driver's bind() method or its uclass' post_bind() method.
*
* If a child bootdev already exists, this function does nothing
*
* @parent: Parent device (e.g. MMC or Ethernet)
* @drv_name: Name of bootdev driver to bind
* Return: 0 if OK, -ve on error
*/
int bootdev_setup_for_dev(struct udevice *parent, const char *drv_name);
#if CONFIG_IS_ENABLED(BOOTSTD)
/**
* bootdev_setup_for_sibling_blk() - Bind a new bootdev device for a blk device
*
* Creates a bootdev device as a sibling of @blk. This should be called from
* the driver's bind() method or its uclass' post_bind() method, at the same
* time as the bould device is bound
*
* If a device of the same name already exists, this function does nothing
*
* @parent: Parent device (e.g. MMC or Ethernet)
* @drv_name: Name of bootdev driver to bind
* Return: 0 if OK, -ve on error
*/
int bootdev_setup_for_sibling_blk(struct udevice *blk, const char *drv_name);
#else
static int bootdev_setup_for_sibling_blk(struct udevice *blk,
const char *drv_name)
{
return 0;
}
#endif
/**
* bootdev_get_sibling_blk() - Locate the block device for a bootdev
*
* @dev: bootdev to check
* @blkp: returns associated block device
* Return: 0 if OK, -EINVAL if @dev is not a bootdev device, other -ve on other
* error
*/
int bootdev_get_sibling_blk(struct udevice *dev, struct udevice **blkp);
/**
* bootdev_get_from_blk() - Get the bootdev given a block device
*
* @blk: Block device to check
* @bootdebp: Returns the bootdev found, if any
* Return 0 if OK, -ve on error
*/
int bootdev_get_from_blk(struct udevice *blk, struct udevice **bootdevp);
/**
* bootdev_unbind_dev() - Unbind a bootdev device
*
* Remove and unbind a bootdev device which is a child of @parent. This should
* be called from the driver's unbind() method or its uclass' post_bind()
* method.
*
* @parent: Parent device (e.g. MMC or Ethernet)
* Return: 0 if OK, -ve on error
*/
int bootdev_unbind_dev(struct udevice *parent);
#else
static inline int bootdev_setup_for_dev(struct udevice *parent,
const char *drv_name)
{
return 0;
}
static inline int bootdev_setup_for_sibling_blk(struct udevice *blk,
const char *drv_name)
{
return 0;
}
static inline int bootdev_unbind_dev(struct udevice *parent)
{
return 0;
}
#endif
#endif
+710
View File
@@ -0,0 +1,710 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2021 Google LLC
* Written by Simon Glass <sjg@chromium.org>
*/
#ifndef __bootflow_h
#define __bootflow_h
#include <alist.h>
#include <bootdev.h>
#include <image.h>
#include <dm/ofnode_decl.h>
#include <linux/list.h>
#include <linux/build_bug.h>
struct bootstd_priv;
struct expo;
struct scene;
enum {
BOOTFLOW_MAX_USED_DEVS = 16,
};
/**
* enum bootflow_state_t - states that a particular bootflow can be in
*
* Only bootflows in state BOOTFLOWST_READY can be used to boot.
*
* See bootflow_state[] for the names for each of these
*/
enum bootflow_state_t {
BOOTFLOWST_BASE, /**< Nothing known yet */
BOOTFLOWST_MEDIA, /**< Media exists */
BOOTFLOWST_PART, /**< Partition exists */
BOOTFLOWST_FS, /**< Filesystem exists */
BOOTFLOWST_FILE, /**< Bootflow file exists */
BOOTFLOWST_READY, /**< Bootflow file loaded */
BOOTFLOWST_COUNT
};
/**
* enum bootflow_flags_t - flags for bootflows
*
* @BOOTFLOWF_USE_PRIOR_FDT: Indicates that an FDT was not found by the bootmeth
* and it is using the prior-stage FDT, which is the U-Boot control FDT.
* This is only possible with the EFI bootmeth (distro-efi) and only when
* CONFIG_OF_HAS_PRIOR_STAGE is enabled
* @BOOTFLOWF_STATIC_BUF: Indicates that @bflow->buf is statically set, rather
* than being allocated by malloc().
* @BOOTFLOWF_USE_BUILTIN_FDT : Indicates that current bootflow uses built-in FDT
*/
enum bootflow_flags_t {
BOOTFLOWF_USE_PRIOR_FDT = 1 << 0,
BOOTFLOWF_STATIC_BUF = 1 << 1,
BOOTFLOWF_USE_BUILTIN_FDT = 1 << 2,
};
/**
* struct bootflow - information about a bootflow
*
* All bootflows are listed in bootstd's bootflow alist in struct bootstd_priv
*
* @dev: Bootdev device which produced this bootflow, NULL for flows created by
* BOOTMETHF_GLOBAL bootmeths
* @blk: Block device which contains this bootflow, NULL if this is a network
* device or sandbox 'host' device
* @part: Partition number (0 for whole device)
* @fs_type: Filesystem type (FS_TYPE...) if this is fixed by the media, else 0.
* For example, the sandbox host-filesystem bootdev sets this to
* FS_TYPE_SANDBOX
* @method: Bootmethod device used to perform the boot and read files
* @name: Name of bootflow (allocated)
* @state: Current state (enum bootflow_state_t)
* @subdir: Subdirectory to fetch files from (with trailing /), or NULL if none
* @fname: Filename of bootflow file (allocated)
* @logo: Logo to display for this bootflow (BMP format)
* @logo_size: Size of the logo in bytes
* @buf: Bootflow file contents (allocated unless @flags & BOOTFLOWF_STATIC_BUF)
* @size: Size of bootflow file in bytes
* @err: Error number received (0 if OK)
* @os_name: Name of the OS / distro being booted, or NULL if not known
* (allocated)
* @fdt_fname: Filename of FDT file
* @fdt_size: Size of FDT file
* @fdt_addr: Address of loaded fdt
* @flags: Flags for the bootflow (see enum bootflow_flags_t)
* @cmdline: OS command line, or NULL if not known (allocated)
* @x86_setup: Pointer to x86 setup block inside @buf, NULL if not present
* @bootmeth_priv: Private data for the bootmeth
* @images: List of loaded images (struct bootstd_img)
*/
struct bootflow {
struct udevice *dev;
struct udevice *blk;
int part;
int fs_type;
struct udevice *method;
char *name;
enum bootflow_state_t state;
char *subdir;
char *fname;
void *logo;
uint logo_size;
char *buf;
int size;
int err;
char *os_name;
char *fdt_fname;
int fdt_size;
ulong fdt_addr;
int flags;
char *cmdline;
void *x86_setup;
void *bootmeth_priv;
struct alist images;
};
/**
* bootflow_img_t: Supported image types
*
* This uses image_type_t for most types, but extends it
*
* @BFI_EXTLINUX_CFG: extlinux configuration-file
* @BFI_LOGO: logo image
* @BFI_EFI: EFI PE image
* @BFI_CMDLINE: OS command-line string
*/
enum bootflow_img_t {
BFI_FIRST = IH_TYPE_COUNT,
BFI_EXTLINUX_CFG = BFI_FIRST,
BFI_LOGO,
BFI_EFI,
BFI_CMDLINE,
BFI_COUNT,
};
/**
* struct bootflow_img - Information about an image which has been loaded
*
* This keeps track of a single, loaded image.
*
* @fname: Filename used to load the image (allocated)
* @type: Image type (IH_TYPE_...)
* @addr: Address to which the image was loaded, 0 if not yet loaded
* @size: Size of the image
*/
struct bootflow_img {
char *fname;
enum bootflow_img_t type;
ulong addr;
ulong size;
};
/**
* enum bootflow_iter_flags_t - flags for the bootflow iterator
*
* @BOOTFLOWIF_FIXED: Only used fixed/internal media
* @BOOTFLOWIF_SHOW: Show each bootdev before scanning it; show each hunter
* before using it
* @BOOTFLOWIF_ALL: Return bootflows with errors as well
* @BOOTFLOWIF_HUNT: Hunt for new bootdevs using the bootdrv hunters
* @BOOTFLOWIF_ONLY_BOOTABLE: Only consider partitions marked 'bootable'
*
* Internal flags:
* @BOOTFLOWIF_SINGLE_DEV: (internal) Just scan one bootdev
* @BOOTFLOWIF_SKIP_GLOBAL: (internal) Don't scan global bootmeths
* @BOOTFLOWIF_SINGLE_UCLASS: (internal) Keep scanning through all devices in
* this uclass (used with things like "mmc")
* @BOOTFLOWIF_SINGLE_MEDIA: (internal) Scan one media device in the uclass (used
* with things like "mmc1")
* @BOOTFLOWIF_SINGLE_PARTITION: (internal) Scan one partition in media device
* (used with things like "mmc1:3")
*/
enum bootflow_iter_flags_t {
BOOTFLOWIF_FIXED = 1 << 0,
BOOTFLOWIF_SHOW = 1 << 1,
BOOTFLOWIF_ALL = 1 << 2,
BOOTFLOWIF_HUNT = 1 << 3,
BOOTFLOWIF_ONLY_BOOTABLE = BIT(4),
/*
* flags used internally by standard boot - do not set these when
* calling bootflow_scan_bootdev() etc.
*/
BOOTFLOWIF_SINGLE_DEV = 1 << 16,
BOOTFLOWIF_SKIP_GLOBAL = 1 << 17,
BOOTFLOWIF_SINGLE_UCLASS = 1 << 18,
BOOTFLOWIF_SINGLE_MEDIA = 1 << 19,
BOOTFLOWIF_SINGLE_PARTITION = 1 << 20,
};
/**
* enum bootflow_meth_flags_t - flags controlling which bootmeths are used
*
* Used during iteration, e.g. by bootdev_find_by_label(), to determine which
* bootmeths are used for the current bootdev. The flags reset when the bootdev
* changes
*
* @BOOTFLOW_METHF_DHCP_ONLY: Only use dhcp (scripts and EFI)
* @BOOTFLOW_METHF_PXE_ONLY: Only use pxe (PXE boot)
* @BOOTFLOW_METHF_SINGLE_DEV: Scan only a single bootdev (used for labels like
* "3"). This is used if a sequence number is provided instead of a label
* @BOOTFLOW_METHF_SINGLE_UCLASS: Scan all bootdevs in this one uclass (used
* with things like "mmc"). If this is not set, then the bootdev has an integer
* value in the label (like "mmc2")
*/
enum bootflow_meth_flags_t {
BOOTFLOW_METHF_DHCP_ONLY = 1 << 0,
BOOTFLOW_METHF_PXE_ONLY = 1 << 1,
BOOTFLOW_METHF_SINGLE_DEV = 1 << 2,
BOOTFLOW_METHF_SINGLE_UCLASS = 1 << 3,
};
enum {
BOOTMETH_MAX_COUNT = 32,
};
/**
* struct bootflow_iter - state for iterating through bootflows
*
* This starts at with the first bootdev/partition/bootmeth and can be used to
* iterate through all of them.
*
* Iteration starts with the bootdev. The first partition (0, i.e. whole device)
* is scanned first. For partition 0, it iterates through all the available
* bootmeths to see which one(s) can provide a bootflow. Then it moves to
* parition 1 (if there is one) and the process continues. Once all partitions
* are examined, it moves to the next bootdev.
*
* Initially @max_part is 0, meaning that only the whole device (@part=0) can be
* used. During scanning, if a partition table is found, then @max_part is
* updated to a larger value, no less than the number of available partitions.
* This ensures that iteration works through all partitions on the bootdev.
*
* @flags: Flags to use (see enum bootflow_iter_flags_t). If
* BOOTFLOWIF_GLOBAL_FIRST is enabled then the global bootmeths are being
* scanned, otherwise we have moved onto the bootdevs
* @dev: Current bootdev, NULL if none. This is only ever updated in
* bootflow_iter_set_dev()
* @part: Current partition number (0 for whole device)
* @method: Current bootmeth
* @max_part: Maximum hardware partition number in @dev, 0 if there is no
* partition table
* @first_bootable: First bootable partition, or 0 if none
* @err: Error obtained from checking the last iteration. This is used to skip
* forward (e.g. to skip the current partition because it is not valid)
* -ESHUTDOWN: try next bootdev
* @num_devs: Number of bootdevs in @dev_used
* @max_devs: Maximum number of entries in @dev_used
* @dev_used: List of bootdevs used during iteration
* @labels: List of labels to scan for bootdevs
* @cur_label: Current label being processed
* @num_methods: Number of bootmeth devices in @method_order
* @cur_method: Current method number, an index into @method_order
* @first_glob_method: Index of first global method within @method_order[], if
* any, else -1
* @cur_prio: Current priority being scanned
* @method_order: List of bootmeth devices to use, in order. The normal methods
* appear first, then the global ones, if any
* @have_global: true if we have global bootmeths in @method_order[]
* @doing_global: true if we are iterating through the global bootmeths (which
* generally happens before the normal ones)
* @method_flags: flags controlling which methods should be used for this @dev
* (enum bootflow_meth_flags_t)
* @methods_done: indicates which methods have been processed, one bit for
* each method in @method_order[]
* @pending_bootdev: if non-NULL, bootdev which will be used when the global
* bootmeths are done
* @pending_method_flags: method flags which will be used with @pending_bootdev
*/
struct bootflow_iter {
int flags;
struct udevice *dev;
int part;
struct udevice *method;
int max_part;
int first_bootable;
int err;
int num_devs;
int max_devs;
struct udevice *dev_used[BOOTFLOW_MAX_USED_DEVS];
const char *const *labels;
int cur_label;
int num_methods;
int cur_method;
int first_glob_method;
enum bootdev_prio_t cur_prio;
struct udevice **method_order;
bool have_global;
bool doing_global;
int method_flags;
uint methods_done;
struct udevice *pending_bootdev;
int pending_method_flags;
};
/**
* bootflow_init() - Set up a bootflow struct
*
* The bootflow is zeroed and set to state BOOTFLOWST_BASE
*
* @bflow: Struct to set up
* @bootdev: Bootdev to use
* @meth: Bootmeth to use
*/
void bootflow_init(struct bootflow *bflow, struct udevice *bootdev,
struct udevice *meth);
/**
* bootflow_iter_init() - Reset a bootflow iterator
*
* This sets everything to the starting point, ready for use.
*
* @iter: Place to store private info (inited by this call)
* @flags: Flags to use (see enum bootflow_iter_flags_t)
*/
void bootflow_iter_init(struct bootflow_iter *iter, int flags);
/**
* bootflow_iter_uninit() - Free memory used by an interator
*
* @iter: Iterator to free
*/
void bootflow_iter_uninit(struct bootflow_iter *iter);
/**
* bootflow_iter_drop_bootmeth() - Remove a bootmeth from an iterator
*
* Update the iterator so that the bootmeth will not be used again while this
* iterator is in use
*
* @iter: Iterator to update
* @bmeth: Boot method to remove
*/
int bootflow_iter_drop_bootmeth(struct bootflow_iter *iter,
const struct udevice *bmeth);
/**
* bootflow_scan_first() - find the first bootflow for a device or label
*
* If @flags includes BOOTFLOWIF_ALL then bootflows with errors are returned too
*
* @dev: Boot device to scan, NULL to work through all of them until it
* finds one that can supply a bootflow
* @label: Label to control the scan, NULL to work through all devices
* until it finds one that can supply a bootflow
* @iter: Place to store private info (inited by this call)
* @flags: Flags for iterator (enum bootflow_iter_flags_t). Note that if
* @dev is NULL, then BOOTFLOWIF_SKIP_GLOBAL is set automatically by this
* function
* @bflow: Place to put the bootflow if found
* Return: 0 if found, -ENODEV if no device, other -ve on other error
* (iteration can continue)
*/
int bootflow_scan_first(struct udevice *dev, const char *label,
struct bootflow_iter *iter, int flags,
struct bootflow *bflow);
/**
* bootflow_scan_next() - find the next bootflow
*
* This works through the available bootdev devices until it finds one that
* can supply a bootflow. It then returns that bootflow
*
* @iter: Private info (as set up by bootflow_scan_first())
* @bflow: Place to put the bootflow if found
* Return: 0 if found, -ENODEV if no device, -ESHUTDOWN if no more bootflows,
* other -ve on other error (iteration can continue)
*/
int bootflow_scan_next(struct bootflow_iter *iter, struct bootflow *bflow);
/**
* bootflow_first_glob() - Get the first bootflow from the global list
*
* Returns the first bootflow in the global list, no matter what bootflow it is
* attached to
*
* @bflowp: Returns a pointer to the bootflow
* Return: 0 if found, -ENOENT if there are no bootflows
*/
int bootflow_first_glob(struct bootflow **bflowp);
/**
* bootflow_next_glob() - Get the next bootflow from the global list
*
* Returns the next bootflow in the global list, no matter what bootflow it is
* attached to
*
* @bflowp: On entry, the last bootflow returned , e.g. from
* bootflow_first_glob()
* Return: 0 if found, -ENOENT if there are no more bootflows
*/
int bootflow_next_glob(struct bootflow **bflowp);
/**
* bootflow_free() - Free memory used by a bootflow
*
* This frees fields within @bflow, but not the @bflow pointer itself
*/
void bootflow_free(struct bootflow *bflow);
/**
* bootflow_boot() - boot a bootflow
*
* @bflow: Bootflow to boot
* Return: -EPROTO if bootflow has not been loaded, -ENOSYS if the bootflow
* type is not supported, -EFAULT if the boot returned without an error
* when we are expecting it to boot, -ENOTSUPP if trying method resulted in
* finding out that is not actually supported for this boot and should not
* be tried again unless something changes
*/
int bootflow_boot(struct bootflow *bflow);
/**
* bootflow_read_all() - Read all bootflow files
*
* Some bootmeths delay reading of large files until booting is requested. This
* causes those files to be read.
*
* @bflow: Bootflow to read
* Return: result of trying to read
*/
int bootflow_read_all(struct bootflow *bflow);
/**
* bootflow_run_boot() - Try to boot a bootflow
*
* @iter: Current iteration (or NULL if none). Used to disable a bootmeth if the
* boot returns -ENOTSUPP
* @bflow: Bootflow to boot
* Return: result of trying to boot
*/
int bootflow_run_boot(struct bootflow_iter *iter, struct bootflow *bflow);
/**
* bootflow_state_get_name() - Get the name of a bootflow state
*
* @state: State to check
* Return: name, or "?" if invalid
*/
const char *bootflow_state_get_name(enum bootflow_state_t state);
/**
* bootflow_remove() - Remove a bootflow and free its memory
*
* This updates the 'global' linked list containing the bootflow, then frees it.
* It does not remove it from bootflows alist in struct bootstd_priv
*
* This does not free bflow itself, since this is assumed to be in an alist
*
* @bflow: Bootflow to remove
*/
void bootflow_remove(struct bootflow *bflow);
/**
* bootflow_iter_check_blk() - Check that a bootflow uses a block device
*
* This checks the bootdev in the bootflow to make sure it uses a block device
*
* Return: 0 if OK, -ENOTSUPP if some other device is used (e.g. ethernet)
*/
int bootflow_iter_check_blk(const struct bootflow_iter *iter);
/**
* bootflow_iter_check_mmc() - Check that a bootflow uses a MMC device
*
* This checks the bootdev in the bootflow to make sure it uses a mmc device
*
* Return: 0 if OK, -ENOTSUPP if some other device is used (e.g. ethernet)
*/
int bootflow_iter_check_mmc(const struct bootflow_iter *iter);
/**
* bootflow_iter_check_sf() - Check that a bootflow uses SPI FLASH
*
* This checks the bootdev in the bootflow to make sure it uses SPI flash
*
* Return: 0 if OK, -ENOTSUPP if some other device is used (e.g. ethernet)
*/
int bootflow_iter_check_sf(const struct bootflow_iter *iter);
/**
* bootflow_iter_check_net() - Check that a bootflow uses a network device
*
* This checks the bootdev in the bootflow to make sure it uses a network
* device
*
* Return: 0 if OK, -ENOTSUPP if some other device is used (e.g. MMC)
*/
int bootflow_iter_check_net(const struct bootflow_iter *iter);
/**
* bootflow_iter_check_system() - Check that a bootflow uses the bootstd device
*
* This checks the bootdev in the bootflow to make sure it uses the bootstd
* device
*
* Return: 0 if OK, -ENOTSUPP if some other device is used (e.g. MMC)
*/
int bootflow_iter_check_system(const struct bootflow_iter *iter);
/**
* bootflow_menu_new() - Create a new bootflow menu
*
* This is initially empty. Call bootflow_menu_add_all() to add all the
* bootflows to it.
*
* @expp: Returns the expo created
* Returns 0 on success, -ve on error
*/
int bootflow_menu_new(struct expo **expp);
/**
* bootflow_menu_add_all() - Add all bootflows to a menu
*
* Loops through all bootflows and adds them to the menu
*
* @exp: Menu to update
* Return 0 on success, -ve on error
*/
int bootflow_menu_add_all(struct expo *exp);
/**
* bootflow_menu_add() - Add a bootflow to a menu
*
* Adds a new bootflow to the end of a menu. The caller must be careful to pass
* seq=0 for the first bootflow added, 1 for the second, etc.
*
* @exp: Menu to update
* @bflow: Bootflow to add
* @seq: Sequence number of this bootflow (0 = first)
* @scnp: Returns a pointer to the scene
* Return 0 on success, -ve on error
*/
int bootflow_menu_add(struct expo *exp, struct bootflow *bflow, int seq,
struct scene **scnp);
/**
* bootflow_menu_apply_theme() - Apply a theme to a bootmenu
*
* @exp: Expo to update
* @node: Node containing the theme information
* Returns 0 on success, -ve on error
*/
int bootflow_menu_apply_theme(struct expo *exp, ofnode node);
#define BOOTFLOWCL_EMPTY ((void *)1)
/**
* cmdline_set_arg() - Update or read an argument in a cmdline string
*
* Handles updating a single arg in a cmdline string, returning it in a supplied
* buffer; also reading an arg from a cmdline string
*
* When updating, consecutive spaces are squashed as are spaces at the start and
* end.
*
* @buf: Working buffer to use (initial contents are ignored). Use NULL when
* reading
* @maxlen: Length of working buffer. Use 0 when reading
* @cmdline: Command line to update, in the form:
*
* fred mary= jane=123 john="has spaces"
*
* @set_arg: Argument to set or read (may or may not exist)
* @new_val: Value for the new argument. May not include quotes (") but may
* include embedded spaces, in which case it will be quoted when added to the
* command line. Use NULL to delete the argument from @cmdline, BOOTFLOWCL_EMPTY
* to set it to an empty value (no '=' sign after arg), "" to add an '=' sign
* but with an empty value. Use NULL when reading.
* @posp: Ignored when setting an argument; when getting an argument, returns
* the start position of its value in @cmdline, after the first quote, if any
*
* Return:
* For updating:
* length of new buffer (including \0 terminator) on success, -ENOENT if
* @new_val is NULL and @set_arg does not exist in @from, -EINVAL if a
* quoted arg-value in @from is not terminated with a quote, -EBADF if
* @new_val has spaces but does not start and end with quotes (or it has
* quotes in the middle of the string), -E2BIG if @maxlen is too small
* For reading:
* length of arg value (excluding quotes), -ENOENT if not found
*/
int cmdline_set_arg(char *buf, int maxlen, const char *cmdline,
const char *set_arg, const char *new_val, int *posp);
/**
* bootflow_cmdline_set_arg() - Set a single argument for a bootflow
*
* Update the allocated cmdline and set the bootargs variable
*
* @bflow: Bootflow to update
* @arg: Argument to update (e.g. "console")
* @val: Value to set (e.g. "ttyS2") or NULL to delete the argument if present,
* "" to set it to an empty value (e.g. "console=") and BOOTFLOWCL_EMPTY to add
* it without any value ("initrd")
* @set_env: true to set the "bootargs" environment variable too
*
* Return: 0 if OK, -ENOMEM if out of memory
*/
int bootflow_cmdline_set_arg(struct bootflow *bflow, const char *arg,
const char *val, bool set_env);
/**
* cmdline_get_arg() - Read an argument from a cmdline
*
* @cmdline: Command line to read, in the form:
*
* fred mary= jane=123 john="has spaces"
* @arg: Argument to read (may or may not exist)
* @posp: Returns position of argument (after any leading quote) if present
* Return: Length of argument value excluding quotes if found, -ENOENT if not
* found
*/
int cmdline_get_arg(const char *cmdline, const char *arg, int *posp);
/**
* bootflow_cmdline_get_arg() - Read an argument from a cmdline
*
* @bootflow: Bootflow to read from
* @arg: Argument to read (may or may not exist)
* @valp: Returns a pointer to the argument (after any leading quote) if present
* Return: Length of argument value excluding quotes if found, -ENOENT if not
* found
*/
int bootflow_cmdline_get_arg(struct bootflow *bflow, const char *arg,
const char **val);
/**
* bootflow_cmdline_auto() - Automatically set a value for a known argument
*
* This handles a small number of known arguments, for Linux in particular. It
* adds suitable kernel parameters automatically, e.g. to enable the console.
*
* @bflow: Bootflow to update
* @arg: Name of argument to set (e.g. "earlycon" or "console")
* Return: 0 if OK -ve on error
*/
int bootflow_cmdline_auto(struct bootflow *bflow, const char *arg);
/**
* bootflow_img_type_name() - Get the name for an image type
*
* @type: Type to check (either enum bootflow_img_t or enum image_type_t
* Return: Image name, or "unknown" if not known
*/
const char *bootflow_img_type_name(enum bootflow_img_t type);
/**
* bootflow_img_add() - Add a new image to a bootflow
*
* @bflow: Bootflow to add to
* @fname: Image filename (will be allocated)
* @type: Image type
* @addr: Address the image was loaded to, or 0 if not loaded
* @size: Image size
* Return: pointer to the added image, or NULL if out of memory
*/
struct bootflow_img *bootflow_img_add(struct bootflow *bflow, const char *fname,
enum bootflow_img_t type, ulong addr,
ulong size);
/**
* bootflow_get_seq() - Get the sequence number of a bootflow
*
* Bootflows are numbered by their position in the bootstd list.
*
* Return: Sequence number of bootflow (0 = first)
*/
int bootflow_get_seq(const struct bootflow *bflow);
/**
* bootflow_menu_setup() - Set up a menu for bootflows
*
* Set up the expo, initially empty
*
* @std: bootstd information
* @text_mode: true to show the menu in text mode, false to use video display
* @expp: Returns the expo created, on success
* Return: 0 if OK, -ve on error
*/
int bootflow_menu_setup(struct bootstd_priv *std, bool text_mode,
struct expo **expp);
/**
* bootflow_menu_start() - Start up a menu for bootflows
*
* Set up the expo and add items
*
* @std: bootstd information
* @text_mode: true to show the menu in text mode, false to use video display
* @expp: Returns the expo created, on success
* Return: 0 if OK, -ve on error
*/
int bootflow_menu_start(struct bootstd_priv *std, bool text_mode,
struct expo **expp);
/**
* bootflow_menu_poll() - Poll a menu for user action
*
* @exp: Expo to poll
* @seqp: Returns the bootflow chosen or currently pointed to (numbered from 0)
* Return: 0 if a bootflow was chosen, -EAGAIN if nothing is chosen yet, -EPIPE
* if the user quit, -ERESTART if the expo needs refreshing
*/
int bootflow_menu_poll(struct expo *exp, int *seqp);
#endif
+334
View File
@@ -0,0 +1,334 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2000-2009
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*/
#ifndef _BOOTM_H
#define _BOOTM_H
#include <image.h>
struct boot_params;
struct cmd_tbl;
#define BOOTM_ERR_RESET (-1)
#define BOOTM_ERR_OVERLAP (-2)
#define BOOTM_ERR_UNIMPLEMENTED (-3)
/**
* struct bootm_info() - information used when processing images to boot
*
* These mirror the first three arguments of the bootm command. They are
* designed to handle any type of image, but typically it is a FIT.
*
* @addr_img: Address of image to bootm, as passed to
* genimg_get_kernel_addr_fit() for processing:
*
* NULL: Uses default load address, i.e. image_load_addr
* <addr>: Uses hex address
*
* For FIT:
* "[<addr>]#<conf>": Uses address (or image_load_addr) and also specifies
* the FIT configuration to use
* "[<addr>]:<subimage>": Uses address (or image_load_addr) and also
* specifies the subimage name containing the OS
*
* @conf_ramdisk: Address (or with FIT, the name) of the ramdisk image, as
* passed to boot_get_ramdisk() for processing, or NULL for none
* @conf_fdt: Address (or with FIT, the name) of the FDT image, as passed to
* boot_get_fdt() for processing, or NULL for none
* @boot_progress: true to show boot progress
* @images: images information
* @cmd_name: command which invoked this operation, e.g. "bootm"
* @argc: Number of arguments to the command (excluding the actual command).
* This is 0 if there are no arguments
* @argv: NULL-terminated list of arguments, or NULL if there are no arguments
*/
struct bootm_info {
const char *addr_img;
const char *conf_ramdisk;
const char *conf_fdt;
bool boot_progress;
struct bootm_headers *images;
const char *cmd_name;
int argc;
char *const *argv;
};
/**
* bootm_init() - Set up a bootm_info struct with useful defaults
*
* Set up the struct with default values for all members:
* @boot_progress is set to true and @images is set to the global images
* variable. Everything else is set to NULL except @argc which is 0
*/
void bootm_init(struct bootm_info *bmi);
/*
* Continue booting an OS image; caller already has:
* - copied image header to global variable `header'
* - checked header magic number, checksums (both header & image),
* - verified image architecture (PPC) and type (KERNEL or MULTI),
* - loaded (first part of) image to header load address,
* - disabled interrupts.
*
* @flag: Flags indicating what to do (BOOTM_STATE_...)
* bmi: Bootm information
* Return: 1 on error. On success the OS boots so this function does
* not return.
*/
typedef int boot_os_fn(int flag, struct bootm_info *bmi);
extern boot_os_fn do_bootm_linux;
extern boot_os_fn do_bootm_vxworks;
int do_bootelf(struct cmd_tbl *cmdtp, int fglag, int argc, char *const argv[]);
boot_os_fn *bootm_os_get_boot_func(int os);
#if defined(CONFIG_FIT_SIGNATURE)
int bootm_host_load_images(const void *fit, int cfg_noffset);
#endif
int boot_selected_os(int state, struct bootm_info *bmi, boot_os_fn *boot_fn);
ulong bootm_disable_interrupts(void);
/**
* bootm_find_images() - find and locate various images
*
* @img_addr: Address of image being loaded
* @conf_ramdisk: Indicates the ramdisk to use (typically second arg of bootm)
* @conf_fdt: Indicates the FDT to use (typically third arg of bootm)
* @start: OS image start address
* @size: OS image size
*
* boot_find_images() will attempt to load an available ramdisk,
* flattened device tree, as well as specifically marked
* "loadable" images (loadables are FIT only)
*
* Note: bootm_find_images will skip an image if it is not found
*
* This is a special function used by booti/bootz
*
* Return:
* 0, if all existing images were loaded correctly
* 1, if an image is found but corrupted, or invalid
*/
int bootm_find_images(ulong img_addr, const char *conf_ramdisk,
const char *conf_fdt, ulong start, ulong size);
/*
* Measure the boot images. Measurement is the process of hashing some binary
* data and storing it into secure memory, i.e. TPM PCRs. In addition, each
* measurement is logged into the platform event log such that the operating
* system can access it and perform attestation of the boot.
*
* @images: The structure containing the various images to boot (linux,
* initrd, dts, etc.)
*/
int bootm_measure(struct bootm_headers *images);
/**
* bootm_run_states() - Execute selected states of the bootm command.
*
* Note that if states contains more than one flag it MUST contain
* BOOTM_STATE_START, since this handles the addr_fit, conf_ramdisk and conf_fit
* members of @bmi
*
* Also note that aside from boot_os_fn functions and bootm_load_os, no other
* functions store the return value of in 'ret' may use a negative return
* value, without special handling.
*
* @bmi: bootm information
* @states Mask containing states to run (BOOTM_STATE_...)
* Return: 0 if ok, something else on error. Some errors will cause this
* function to perform a reboot! If states contains BOOTM_STATE_OS_GO
* then the intent is to boot an OS, so this function will not return
* unless the image type is standalone.
*/
int bootm_run_states(struct bootm_info *bmi, int states);
/**
* boot_run() - Run the entire bootm/booti/bootz process
*
* This runs through the boot process from start to finish, with a base set of
* states, along with the extra ones supplied.
*
* This uses bootm_run_states().
*
* Note that it is normally easier to use bootm_run(), etc. since they handle
* the extra states correctly.
*
* @bmi: bootm information
* @cmd: command being run, NULL if none
* @extra_states: Mask of extra states to use for the boot
* Return: 0 if ok, something else on error
*/
int boot_run(struct bootm_info *bmi, const char *cmd, int extra_states);
/**
* bootm_run() - Run the entire bootm process
*
* This runs through the bootm process from start to finish, using the default
* set of states.
*
* This uses bootm_run_states().
*
* @bmi: bootm information
* Return: 0 if ok, something else on error
*/
int bootm_run(struct bootm_info *bmi);
/**
* bootz_run() - Run the entire bootz process
*
* This runs through the bootz process from start to finish, using the default
* set of states.
*
* This uses bootm_run_states().
*
* @bmi: bootm information
* Return: 0 if ok, something else on error
*/
int bootz_run(struct bootm_info *bmi);
/**
* booti_run() - Run the entire booti process
*
* This runs through the booti process from start to finish, using the default
* set of states.
*
* This uses bootm_run_states().
*
* @bmi: bootm information
* Return: 0 if ok, something else on error
*/
int booti_run(struct bootm_info *bmi);
void arch_preboot_os(void);
/*
* boards should define this to disable devices when EFI exits from boot
* services.
*
* TODO(sjg@chromium.org>): Update this to use driver model's device_remove().
*/
void board_quiesce_devices(void);
/**
* switch_to_non_secure_mode() - switch to non-secure mode
*/
void switch_to_non_secure_mode(void);
/* Flags to control bootm_process_cmdline() */
enum bootm_cmdline_t {
BOOTM_CL_SILENT = 1 << 0, /* Do silent console processing */
BOOTM_CL_SUBST = 1 << 1, /* Do substitution */
BOOTM_CL_ALL = 3, /* All substitutions */
};
/**
* arch_preboot_os() - arch specific configuration before booting
*/
void arch_preboot_os(void);
/**
* board_preboot_os() - board specific configuration before booting
*/
void board_preboot_os(void);
/*
* bootm_process_cmdline() - Process fix-ups for the command line
*
* This handles:
*
* - making Linux boot silently if requested ('silent_linux' envvar)
* - performing substitutions in the command line ('bootargs_subst' envvar)
*
* @maxlen must provide enough space for the string being processed plus the
* resulting string
*
* @buf: buffer holding commandline string to adjust
* @maxlen: Maximum length of buffer at @buf (including \0)
* @flags: Flags to control what happens (see bootm_cmdline_t)
* Return: 0 if OK, -ENOMEM if out of memory, -ENOSPC if the commandline is too
* long
*/
int bootm_process_cmdline(char *buf, int maxlen, int flags);
/**
* bootm_process_cmdline_env() - Process fix-ups for the command line
*
* Updates the 'bootargs' envvar as required. This handles:
*
* - making Linux boot silently if requested ('silent_linux' envvar)
* - performing substitutions in the command line ('bootargs_subst' envvar)
*
* @flags: Flags to control what happens (see bootm_cmdline_t)
* Return: 0 if OK, -ENOMEM if out of memory
*/
int bootm_process_cmdline_env(int flags);
/**
* zboot_run() - Run through the various steps to boot a zimage
*
* Boot a zimage, given the component parts
*
* @addr: Address where the bzImage is moved before booting, either
* BZIMAGE_LOAD_ADDR or ZIMAGE_LOAD_ADDR
* @size: Size of bzImage, or 0 to detect this
* @initrd: Address of the initial ramdisk, or 0 if none
* @initrd_size: Size of the initial ramdisk, or 0 if none
* @base_addr: If non-zero, this indicates that the boot parameters have already
* been loaded by the caller to this address, so the load_zimage() call
* in zboot_load() will be skipped when booting
* @cmdline: If non-NULL, the environment variable containing the command line
* to use for booting
* Return: -EFAULT on error (normally it does not return)
*/
int zboot_run(ulong addr, ulong size, ulong initrd, ulong initrd_size,
ulong base, char *cmdline);
/*
* zimage_get_kernel_version() - Get the version string from a kernel
*
* @params: boot_params pointer
* @kernel_base: base address of kernel
* Return: Kernel version as a NUL-terminated string
*/
const char *zimage_get_kernel_version(struct boot_params *params,
void *kernel_base);
/**
* zimage_dump() - Dump the metadata of a zimage
*
* This shows all available information in a zimage that has been loaded.
*
* @base_ptr: Pointer to the boot parameters, typically at address
* DEFAULT_SETUP_BASE
* @show_cmdline: true to show the full command line
*/
void zimage_dump(struct boot_params *base_ptr, bool show_cmdline);
/*
* bootm_boot_start() - Boot an image at the given address
*
* @addr: Image address
* @cmdline: Command line to set
*/
int bootm_boot_start(ulong addr, const char *cmdline);
/**
* bootm_final() - Announce and do cleanup before boot
*
* This performs the common pre-boot steps: printing the "Starting kernel"
* message, recording bootstage data, and removing active devices.
*
* @flag: Boot state flags (BOOTM_STATE_OS_FAKE_GO prints a fake-run message)
*/
void bootm_final(int flag);
#endif
+428
View File
@@ -0,0 +1,428 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2021 Google LLC
* Written by Simon Glass <sjg@chromium.org>
*/
#ifndef __bootmeth_h
#define __bootmeth_h
#include <bootflow.h>
#include <linux/bitops.h>
struct blk_desc;
struct udevice;
/**
* enum bootmeth_flags - Flags for bootmeths
*
* @BOOTMETHF_GLOBAL: bootmeth handles bootdev selection automatically
* @BOOTMETHF_ANY_PART: bootmeth is willing to check any partition, even if it
* has no filesystem
*/
enum bootmeth_flags {
BOOTMETHF_GLOBAL = BIT(0),
BOOTMETHF_ANY_PART = BIT(1),
};
/**
* struct bootmeth_uc_plat - information the uclass keeps about each bootmeth
*
* @desc: A long description of the bootmeth
* @flags: Flags for this bootmeth (enum bootmeth_flags)
* @glob_prio: Priority for this bootmeth. If unset (0) the bootmeth is started
* before all other bootmeths. Otherwise it is started before the iteration
* reaches the given priority.
*/
struct bootmeth_uc_plat {
const char *desc;
int flags;
enum bootdev_prio_t glob_prio;
};
/** struct bootmeth_ops - Operations for boot methods */
struct bootmeth_ops {
/**
* get_state_desc() - get detailed state information
*
* Produces a textual description of the state of the boot method. This
* can include newline characters if it extends to multiple lines. It
* must be a nul-terminated string.
*
* This may involve reading state from the system, e.g. some data in
* the firmware area.
*
* @dev: Bootmethod device to check
* @buf: Buffer to place the info in (terminator must fit)
* @maxsize: Size of buffer
* Returns: 0 if OK, -ENOSPC is buffer is too small, other -ve error if
* something else went wrong
*/
int (*get_state_desc)(struct udevice *dev, char *buf, int maxsize);
/**
* check_supported() - check if a bootmeth supports this bootdev
*
* This is optional. If not provided, the bootdev is assumed to be
* supported
*
* The bootmeth can check the bootdev (e.g. to make sure it is a
* network device) or the partition information. The following fields
* in @iter are available:
*
* name, dev, state, part
* max_part may be set if part != 0 (i.e. there is a valid partition
* table). Otherwise max_part is 0
* method is available but is the same as @dev
* the partition has not yet been read, nor has the filesystem been
* checked
*
* It may update only the flags in @iter
*
* @dev: Bootmethod device to check against
* @iter: On entry, provides bootdev, hwpart, part
* Return: 0 if OK, -ENOTSUPP if this bootdev is not supported
*/
int (*check)(struct udevice *dev, struct bootflow_iter *iter);
/**
* read_bootflow() - read a bootflow for a device
*
* @dev: Bootmethod device to use
* @bflow: On entry, provides dev, hwpart, part and method.
* Returns updated bootflow if found
* Return: 0 if OK, -ve on error
*/
int (*read_bootflow)(struct udevice *dev, struct bootflow *bflow);
/**
* set_bootflow() - set the bootflow for a device
*
* This provides a bootflow file to the bootmeth, to see if it is valid.
* If it is, the bootflow is set up accordingly.
*
* @dev: Bootmethod device to use
* @bflow: On entry, provides bootdev.
* Returns updated bootflow if found
* @buf: Buffer containing the possible bootflow file
* @size: Size of file
* Return: 0 if OK, -ve on error
*/
int (*set_bootflow)(struct udevice *dev, struct bootflow *bflow,
char *buf, int size);
/**
* read_file() - read a file needed for a bootflow
*
* Read a file from the same place as the bootflow came from
*
* @dev: Bootmethod device to use
* @bflow: Bootflow providing info on where to read from
* @file_path: Path to file (may be absolute or relative)
* @addr: Address to load file
* @type: File type (IH_TYPE_...)
* @sizep: On entry provides the maximum permitted size; on exit
* returns the size of the file
* Return: 0 if OK, -ENOSPC if the file is too large for @sizep, other
* -ve value if something else goes wrong
*/
int (*read_file)(struct udevice *dev, struct bootflow *bflow,
const char *file_path, ulong addr,
enum bootflow_img_t type, ulong *sizep);
#if CONFIG_IS_ENABLED(BOOTSTD_FULL)
/**
* readall() - read all files for a bootflow
*
* @dev: Bootmethod device to boot
* @bflow: Bootflow to read
* Return: 0 if OK, -EIO on I/O error, other -ve on other error
*/
int (*read_all)(struct udevice *dev, struct bootflow *bflow);
#endif /* BOOTSTD_FULL */
/**
* boot() - boot a bootflow
*
* @dev: Bootmethod device to boot
* @bflow: Bootflow to boot
* Return: does not return on success, since it should boot the
* operating system. Returns -EFAULT if that fails, -ENOTSUPP if
* trying method resulted in finding out that is not actually
* supported for this boot and should not be tried again unless
* something changes, other -ve on other error
*/
int (*boot)(struct udevice *dev, struct bootflow *bflow);
/**
* set_property() - set the bootmeth property
*
* This allows the setting of boot method specific properties to enable
* automated finer grain control of the boot process
*
* @name: String containing the name of the relevant boot method
* @property: String containing the name of the property to set
* @value: String containing the value to be set for the specified
* property
* Return: 0 if OK, -ENODEV if an unknown bootmeth or property is
* provided, -ENOENT if there are no bootmeth devices
*/
int (*set_property)(struct udevice *dev, const char *property,
const char *value);
};
#define bootmeth_get_ops(dev) ((struct bootmeth_ops *)(dev)->driver->ops)
/**
* bootmeth_get_state_desc() - get detailed state information
*
* Produces a textual description of the state of the boot method. This
* can include newline characters if it extends to multiple lines. It
* must be a nul-terminated string.
*
* This may involve reading state from the system, e.g. some data in
* the firmware area.
*
* @dev: Bootmethod device to check
* @buf: Buffer to place the info in (terminator must fit)
* @maxsize: Size of buffer
* Returns: 0 if OK, -ENOSPC is buffer is too small, other -ve error if
* something else went wrong
*/
int bootmeth_get_state_desc(struct udevice *dev, char *buf, int maxsize);
/**
* bootmeth_check() - check if a bootmeth supports this bootflow
*
* This is optional. If not provided, the bootdev is assumed to be
* supported
*
* The bootmeth can check the bootdev (e.g. to make sure it is a
* network device) or the partition information. The following fields
* in @iter are available:
*
* name, dev, state, part
* max_part may be set if part != 0 (i.e. there is a valid partition
* table). Otherwise max_part is 0
* method is available but is the same as @dev
* the partition has not yet been read, nor has the filesystem been
* checked
*
* It may update only the flags in @iter
*
* @dev: Bootmethod device to check against
* @iter: On entry, provides bootdev, hwpart, part
* Return: 0 if OK, -ENOTSUPP if this bootdev is not supported
*/
int bootmeth_check(struct udevice *dev, struct bootflow_iter *iter);
/**
* bootmeth_read_bootflow() - set up a bootflow for a device
*
* @dev: Bootmethod device to check
* @bflow: On entry, provides dev, hwpart, part and method.
* Returns updated bootflow if found
* Return: 0 if OK, -ve on error
*/
int bootmeth_read_bootflow(struct udevice *dev, struct bootflow *bflow);
/**
* bootmeth_set_bootflow() - set the bootflow for a device
*
* This provides a bootflow file to the bootmeth, to see if it is valid.
* If it is, the bootflow is set up accordingly.
*
* @dev: Bootmethod device to use
* @bflow: On entry, provides bootdev.
* Returns updated bootflow if found
* @buf: Buffer containing the possible bootflow file (must be allocated
* by caller to @size + 1 bytes)
* @size: Size of file
* Return: 0 if OK, -ve on error
*/
int bootmeth_set_bootflow(struct udevice *dev, struct bootflow *bflow,
char *buf, int size);
/**
* bootmeth_read_file() - read a file needed for a bootflow
*
* Read a file from the same place as the bootflow came from
*
* @dev: Bootmethod device to use
* @bflow: Bootflow providing info on where to read from
* @file_path: Path to file (may be absolute or relative)
* @addr: Address to load file
* @type: File type (IH_TYPE_...)
* @sizep: On entry provides the maximum permitted size; on exit
* returns the size of the file
* Return: 0 if OK, -ENOSPC if the file is too large for @sizep, other
* -ve value if something else goes wrong
*/
int bootmeth_read_file(struct udevice *dev, struct bootflow *bflow,
const char *file_path, ulong addr,
enum bootflow_img_t type, ulong *sizep);
/**
* bootmeth_read_all() - read all bootflow files
*
* Some bootmeths delay reading of large files until booting is requested. This
* causes those files to be read.
*
* @dev: Bootmethod device to use
* @bflow: Bootflow to read
* Return: does not return on success, since it should boot the
* operating system. Returns -EFAULT if that fails, other -ve on
* other error
*/
int bootmeth_read_all(struct udevice *dev, struct bootflow *bflow);
/**
* bootmeth_boot() - boot a bootflow
*
* @dev: Bootmethod device to boot
* @bflow: Bootflow to boot
* Return: does not return on success, since it should boot the
* operating system. Returns -EFAULT if that fails, other -ve on
* other error
*/
int bootmeth_boot(struct udevice *dev, struct bootflow *bflow);
/**
* bootmeth_setup_iter_order() - Set up the ordering of bootmeths to scan
*
* This sets up the ordering information in @iter, based on the selected
* ordering of the boot methods in bootstd_priv->bootmeth_order. If there is no
* ordering there, then all bootmethods are added
*
* @iter: Iterator to update with the order
* @include_global: true to add the global bootmeths, in which case they appear
* first
* Return: 0 if OK, -ENOENT if no bootdevs, -ENOMEM if out of memory, other -ve
* on other error
*/
int bootmeth_setup_iter_order(struct bootflow_iter *iter, bool include_global);
/**
* bootmeth_set_order() - Set the bootmeth order
*
* This selects the ordering to use for bootmeths
*
* @order_str: String containing the ordering. This is a comma-separate list of
* bootmeth-device names, e.g. "extlinux,efi". If empty then a default ordering
* is used, based on the sequence number of devices (i.e. using aliases)
* Return: 0 if OK, -ENODEV if an unknown bootmeth is mentioned, -ENOMEM if
* out of memory, -ENOENT if there are no bootmeth devices
*/
int bootmeth_set_order(const char *order_str);
/**
* bootmeth_set_property() - Set the bootmeth property
*
* This allows the setting of boot method specific properties to enable
* automated finer grain control of the boot process
*
* @name: String containing the name of the relevant boot method
* @property: String containing the name of the property to set
* @value: String containing the value to be set for the specified property
* Return: 0 if OK, -ENODEV if an unknown bootmeth or property is provided,
* -ENOENT if there are no bootmeth devices
*/
int bootmeth_set_property(const char *name, const char *property,
const char *value);
/**
* bootmeth_setup_fs() - Set up read to read a file
*
* We must redo the setup before each filesystem operation. This function
* handles that, including setting the filesystem type if a block device is not
* being used
*
* @bflow: Information about file to try
* @desc: Block descriptor to read from (NULL if not a block device)
* Return: 0 if OK, -ve on error
*/
int bootmeth_setup_fs(struct bootflow *bflow, struct blk_desc *desc);
/**
* bootmeth_try_file() - See we can access a given file
*
* Check for a file with a given name. If found, the filename is allocated in
* @bflow
*
* Sets the state to BOOTFLOWST_FILE on success. It also calls
* fs_set_blk_dev_with_part() so that this does not need to be done by the
* caller before reading the file.
*
* @bflow: Information about file to try
* @desc: Block descriptor to read from (NULL for sandbox host)
* @prefix: Filename prefix to prepend to @fname (NULL for none)
* @fname: Filename to read
* Return: 0 if OK, -ENOMEM if not enough memory to allocate bflow->fname,
* other -ve value on other error
*/
int bootmeth_try_file(struct bootflow *bflow, struct blk_desc *desc,
const char *prefix, const char *fname);
/**
* bootmeth_alloc_file() - Allocate and read a bootflow file
*
* Allocates memory for a bootflow file and reads it in. Sets the state to
* BOOTFLOWST_READY on success
*
* Note that fs_set_blk_dev_with_part() must have been called previously.
*
* @bflow: Information about file to read
* @size_limit: Maximum file size to permit
* @align: Allocation alignment (1 for unaligned)
* @type: File type (IH_TYPE_...)
* Return: 0 if OK, -E2BIG if file is too large, -ENOMEM if out of memory,
* other -ve on other error
*/
int bootmeth_alloc_file(struct bootflow *bflow, uint size_limit, uint align,
enum bootflow_img_t type);
/**
* bootmeth_alloc_other() - Allocate and read a file for a bootflow
*
* This reads an arbitrary file in the same directory as the bootflow,
* allocating memory for it. The buffer is one byte larger than the file length,
* so that it can be nul-terminated.
*
* @bflow: Information about file to read
* @fname: Filename to read from (within bootflow->subdir)
* @type: File type (IH_TYPE_...)
* @bufp: Returns a pointer to the allocated buffer
* @sizep: Returns the size of the buffer
* Return: 0 if OK, -ENOMEM if out of memory, other -ve on other error
*/
int bootmeth_alloc_other(struct bootflow *bflow, const char *fname,
enum bootflow_img_t type, void **bufp, uint *sizep);
/**
* bootmeth_common_read_file() - Common handler for reading a file
*
* Reads a named file from the same location as the bootflow file.
*
* @dev: bootmeth device to read from
* @bflow: Bootflow information
* @file_path: Path to file
* @addr: Address to load file to
* @type: File type (IH_TYPE_...)
* @sizep: On entry, the maximum file size to accept, on exit the actual file
* size read
*/
int bootmeth_common_read_file(struct udevice *dev, struct bootflow *bflow,
const char *file_path, ulong addr,
enum bootflow_img_t type, ulong *sizep);
/**
* bootmeth_get_bootflow() - Get a bootflow from a global bootmeth
*
* Check the bootmeth for a bootflow which can be used. In this case the
* bootmeth handles all bootdev selection, etc.
*
* @dev: bootmeth device to read from
* @bflow: Bootflow information
* @return 0 on success, -ve if a bootflow could not be found or had an error
*/
int bootmeth_get_bootflow(struct udevice *dev, struct bootflow *bflow);
#endif
+58
View File
@@ -0,0 +1,58 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2000
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*/
#ifndef __BOOTRETRY_H
#define __BOOTRETRY_H
#ifdef CONFIG_BOOT_RETRY_TIME
/**
* bootretry_tstc_timeout() - ensure we get a keypress before timeout
*
* Check for a keypress repeatedly, resetting the watchdog each time. If a
* keypress is not received within the command timeout, return an error.
*
* Return: 0 if a key is received in time, -ETIMEDOUT if not
*/
int bootretry_tstc_timeout(void);
/**
* bootretry_init_cmd_timeout() - set up command timeout
*
* Get the required command timeout from the environment.
*/
void bootretry_init_cmd_timeout(void);
/**
* bootretry_reset_cmd_timeout() - reset command timeout
*
* Reset the command timeout so that the user has a fresh start. This is
* typically used when input is received from the user.
*/
void bootretry_reset_cmd_timeout(void);
/** bootretry_dont_retry() - Indicate that we should not retry the boot */
void bootretry_dont_retry(void);
#else
static inline int bootretry_tstc_timeout(void)
{
return 0;
}
static inline void bootretry_init_cmd_timeout(void)
{
}
static inline void bootretry_reset_cmd_timeout(void)
{
}
static inline void bootretry_dont_retry(void)
{
}
#endif
#endif
+492
View File
@@ -0,0 +1,492 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* This file implements recording of each stage of the boot process. It is
* intended to implement timing of each stage, reporting this information
* to the user and passing it to the OS for logging / further analysis.
* Note that it requires timer_get_boot_us() to be defined by the board
*
* Copyright (c) 2011 The Chromium OS Authors.
*/
#ifndef _BOOTSTAGE_H
#define _BOOTSTAGE_H
#include <linux/types.h>
#ifdef USE_HOSTCC
#include <linux/kconfig.h>
#endif
/* Flags for each bootstage record */
enum bootstage_flags {
BOOTSTAGEF_ERROR = 1 << 0, /* Error record */
BOOTSTAGEF_ALLOC = 1 << 1, /* Allocate an id */
};
/* bootstate sub-IDs used for kernel and ramdisk ranges */
enum {
BOOTSTAGE_SUB_FORMAT,
BOOTSTAGE_SUB_FORMAT_OK,
BOOTSTAGE_SUB_NO_UNIT_NAME,
BOOTSTAGE_SUB_UNIT_NAME,
BOOTSTAGE_SUB_SUBNODE,
BOOTSTAGE_SUB_CHECK,
BOOTSTAGE_SUB_HASH = 5,
BOOTSTAGE_SUB_CHECK_ARCH = 5,
BOOTSTAGE_SUB_CHECK_ALL,
BOOTSTAGE_SUB_GET_DATA,
BOOTSTAGE_SUB_CHECK_ALL_OK = 7,
BOOTSTAGE_SUB_GET_DATA_OK,
BOOTSTAGE_SUB_LOAD,
};
/*
* A list of boot stages that we know about. Each of these indicates the
* state that we are at, and the action that we are about to perform. For
* errors, we issue an error for an item when it fails. Therefore the
* normal sequence is:
*
* progress action1
* progress action2
* progress action3
*
* and an error condition where action 3 failed would be:
*
* progress action1
* progress action2
* progress action3
* error on action3
*/
enum bootstage_id {
BOOTSTAGE_ID_START = 0,
BOOTSTAGE_ID_CHECK_MAGIC, /* Checking image magic */
BOOTSTAGE_ID_CHECK_HEADER, /* Checking image header */
BOOTSTAGE_ID_CHECK_CHECKSUM, /* Checking image checksum */
BOOTSTAGE_ID_CHECK_ARCH, /* Checking architecture */
BOOTSTAGE_ID_CHECK_IMAGETYPE = 5,/* Checking image type */
BOOTSTAGE_ID_DECOMP_IMAGE, /* Decompressing image */
BOOTSTAGE_ID_KERNEL_LOADED, /* Kernel has been loaded */
BOOTSTAGE_ID_DECOMP_UNIMPL = 7, /* Odd decompression algorithm */
BOOTSTAGE_ID_CHECK_BOOT_OS, /* Calling OS-specific boot function */
BOOTSTAGE_ID_BOOT_OS_RETURNED, /* Tried to boot OS, but it returned */
BOOTSTAGE_ID_CHECK_RAMDISK = 9, /* Checking ram disk */
BOOTSTAGE_ID_RD_MAGIC, /* Checking ram disk magic */
BOOTSTAGE_ID_RD_HDR_CHECKSUM, /* Checking ram disk header checksum */
BOOTSTAGE_ID_RD_CHECKSUM, /* Checking ram disk checksum */
BOOTSTAGE_ID_COPY_RAMDISK = 12, /* Copying ram disk into place */
BOOTSTAGE_ID_RAMDISK, /* Checking for valid ramdisk */
BOOTSTAGE_ID_NO_RAMDISK, /* No ram disk found (not an error) */
BOOTSTAGE_ID_RUN_OS = 15, /* Exiting U-Boot, entering OS */
BOOTSTAGE_ID_NEED_RESET = 30,
BOOTSTAGE_ID_POST_FAIL, /* Post failure */
BOOTSTAGE_ID_POST_FAIL_R, /* Post failure reported after reloc */
/*
* This set is reported only by x86, and the meaning is different. In
* this case we are reporting completion of a particular stage.
* This should probably change in the x86 code (which doesn't report
* errors in any case), but discussion this can perhaps wait until we
* have a generic board implementation.
*/
BOOTSTAGE_ID_BOARD_INIT_R, /* We have relocated */
BOOTSTAGE_ID_BOARD_GLOBAL_DATA, /* Global data is set up */
BOOTSTAGE_ID_BOARD_INIT_SEQ, /* We completed the init sequence */
BOOTSTAGE_ID_BOARD_FLASH, /* We have configured flash banks */
BOOTSTAGE_ID_BOARD_FLASH_37, /* In case you didn't hear... */
BOOTSTAGE_ID_BOARD_ENV, /* Environment is relocated & ready */
BOOTSTAGE_ID_BOARD_PCI, /* PCI is up */
BOOTSTAGE_ID_BOARD_INTERRUPTS, /* Exceptions / interrupts ready */
BOOTSTAGE_ID_BOARD_DONE, /* Board init done, off to main loop */
/* ^^^ here ends the x86 sequence */
/* Boot stages related to loading a kernel from an IDE device */
BOOTSTAGE_ID_IDE_START = 41,
BOOTSTAGE_ID_IDE_ADDR,
BOOTSTAGE_ID_IDE_BOOT_DEVICE,
BOOTSTAGE_ID_IDE_TYPE,
BOOTSTAGE_ID_IDE_PART,
BOOTSTAGE_ID_IDE_PART_INFO,
BOOTSTAGE_ID_IDE_PART_TYPE,
BOOTSTAGE_ID_IDE_PART_READ,
BOOTSTAGE_ID_IDE_FORMAT,
BOOTSTAGE_ID_IDE_CHECKSUM, /* 50 */
BOOTSTAGE_ID_IDE_READ,
/* Boot stages related to loading a kernel from an NAND device */
BOOTSTAGE_ID_NAND_PART,
BOOTSTAGE_ID_NAND_SUFFIX,
BOOTSTAGE_ID_NAND_BOOT_DEVICE,
BOOTSTAGE_ID_NAND_HDR_READ = 55,
BOOTSTAGE_ID_NAND_AVAILABLE = 55,
BOOTSTAGE_ID_NAND_TYPE = 57,
BOOTSTAGE_ID_NAND_READ,
/* Boot stages related to loading a kernel from an network device */
BOOTSTAGE_ID_NET_CHECKSUM = 60,
BOOTSTAGE_ID_NET_ETH_START = 64,
BOOTSTAGE_ID_NET_ETH_INIT,
BOOTSTAGE_ID_NET_START = 80,
BOOTSTAGE_ID_NET_NETLOOP_OK,
BOOTSTAGE_ID_NET_LOADED,
BOOTSTAGE_ID_NET_DONE_ERR,
BOOTSTAGE_ID_NET_DONE,
BOOTSTAGE_ID_FIT_FDT_START = 90,
/*
* Boot stages related to loading a FIT image. Some of these are a
* bit wonky.
*/
BOOTSTAGE_ID_FIT_KERNEL_START = 100,
BOOTSTAGE_ID_FIT_CONFIG = 110,
BOOTSTAGE_ID_FIT_TYPE,
BOOTSTAGE_ID_FIT_COMPRESSION,
BOOTSTAGE_ID_FIT_OS,
BOOTSTAGE_ID_FIT_LOADADDR,
BOOTSTAGE_ID_OVERWRITTEN,
/* Next 10 IDs used by BOOTSTAGE_SUB_... */
BOOTSTAGE_ID_FIT_RD_START = 120, /* Ramdisk stages */
/* Next 10 IDs used by BOOTSTAGE_SUB_... */
BOOTSTAGE_ID_FIT_SETUP_START = 130, /* x86 setup stages */
BOOTSTAGE_ID_IDE_FIT_READ = 140,
BOOTSTAGE_ID_IDE_FIT_READ_OK,
BOOTSTAGE_ID_NAND_FIT_READ = 150,
BOOTSTAGE_ID_NAND_FIT_READ_OK,
BOOTSTAGE_ID_FIT_LOADABLE_START = 160, /* for Loadable Images */
BOOTSTAGE_ID_FIT_SPL_START = 170, /* for SPL Images */
/*
* These boot stages are new, higher level, and not directly related
* to the old boot progress numbers. They are useful for recording
* rough boot timing information.
*/
BOOTSTAGE_ID_AWAKE,
BOOTSTAGE_ID_START_TPL,
BOOTSTAGE_ID_END_TPL,
BOOTSTAGE_ID_START_SPL,
BOOTSTAGE_ID_END_SPL,
BOOTSTAGE_ID_START_VPL,
BOOTSTAGE_ID_END_VPL,
BOOTSTAGE_ID_START_UBOOT_F,
BOOTSTAGE_ID_START_UBOOT_R,
BOOTSTAGE_ID_USB_START,
BOOTSTAGE_ID_ETH_START,
BOOTSTAGE_ID_BOOTP_START,
BOOTSTAGE_ID_BOOTP_STOP,
BOOTSTAGE_ID_BOOTM_START,
BOOTSTAGE_ID_BOOTM_HANDOFF,
BOOTSTAGE_ID_MAIN_LOOP,
BOOTSTAGE_ID_ENTER_CLI_LOOP,
BOOTSTAGE_KERNELREAD_START,
BOOTSTAGE_KERNELREAD_STOP,
BOOTSTAGE_ID_BOARD_INIT,
BOOTSTAGE_ID_BOARD_INIT_DONE,
BOOTSTAGE_ID_CPU_AWAKE,
BOOTSTAGE_ID_MAIN_CPU_AWAKE,
BOOTSTAGE_ID_MAIN_CPU_READY,
BOOTSTAGE_ID_ACCUM_LCD,
BOOTSTAGE_ID_ACCUM_SCSI,
BOOTSTAGE_ID_ACCUM_SPI,
BOOTSTAGE_ID_ACCUM_DECOMP,
BOOTSTAGE_ID_ACCUM_OF_LIVE,
BOOTSTAGE_ID_FPGA_INIT,
BOOTSTAGE_ID_ACCUM_DM_SPL,
BOOTSTAGE_ID_ACCUM_DM_F,
BOOTSTAGE_ID_ACCUM_DM_R,
BOOTSTAGE_ID_ACCUM_FSP_M,
BOOTSTAGE_ID_ACCUM_FSP_S,
BOOTSTAGE_ID_ACCUM_MMAP_SPI,
/* a few spare for the user, from here */
BOOTSTAGE_ID_USER,
BOOTSTAGE_ID_ALLOC,
};
/*
* Return the time since boot in microseconds, This is needed for bootstage
* and should be defined in CPU- or board-specific code. If undefined then
* you will get a link error.
*/
ulong timer_get_boot_us(void);
#if defined(USE_HOSTCC) || !CONFIG_IS_ENABLED(SHOW_BOOT_PROGRESS)
#define show_boot_progress(val) do {} while (0)
#else
/**
* Board code can implement show_boot_progress() if needed.
*
* @param val Progress state (enum bootstage_id), or -id if an error
* has occurred.
*/
void show_boot_progress(int val);
#endif
#if !defined(USE_HOSTCC)
#if CONFIG_IS_ENABLED(BOOTSTAGE)
#define ENABLE_BOOTSTAGE
#endif
#endif
#ifdef ENABLE_BOOTSTAGE
#include <mapmem.h>
/* This is the full bootstage implementation */
/**
* Relocate existing bootstage records
*
* Call this after relocation has happened and after malloc has been initted.
* We need to copy any pointers in bootstage records that were added pre-
* relocation, since memory can be overwritten later.
* Return: Always returns 0, to indicate success
*/
int bootstage_relocate(void *to);
/**
* Add a new bootstage record
*
* @param id Bootstage ID to use (ignored if flags & BOOTSTAGEF_ALLOC)
* @param name Name of record, or NULL for none
* @param flags Flags (BOOTSTAGEF_...)
* @param mark Time to record in this record, in microseconds
*/
ulong bootstage_add_record(enum bootstage_id id, const char *name,
int flags, ulong mark);
/**
* Mark a time stamp for the current boot stage.
*/
#define bootstage_mark(id) bootstage_mark_name(id, __func__)
#define bootstage_error(id) bootstage_error_name(id, __func__)
/**
* bootstage_mark_name - record bootstage with passing id and name
* @id: Bootstage id to record this timestamp against
* @name: Textual name to display for this id in the report
*
* Return: recorded time stamp
*/
ulong bootstage_mark_name(enum bootstage_id id, const char *name);
/**
* bootstage_error_name - record bootstage error with passing id and name
* @id: Bootstage id to record this timestamp against
* @name: Textual name to display for this id in the report
*
* Return: recorded time stamp
*/
ulong bootstage_error_name(enum bootstage_id id, const char *name);
/**
* Mark a time stamp in the given function and line number
*
* See BOOTSTAGE_MARKER() for a convenient macro.
*
* @param file Filename to record (NULL if none)
* @param func Function name to record
* @param linenum Line number to record
* Return: recorded time stamp
*/
ulong bootstage_mark_code(const char *file, const char *func,
int linenum);
/**
* Mark the start of a bootstage activity. The end will be marked later with
* bootstage_accum() and at that point we accumulate the time taken. Calling
* this function turns the given id into a accumulator rather than and
* absolute mark in time. Accumulators record the total amount of time spent
* in an activty during boot.
*
* @param id Bootstage id to record this timestamp against
* @param name Textual name to display for this id in the report (maybe NULL)
* Return: start timestamp in microseconds
*/
uint32_t bootstage_start(enum bootstage_id id, const char *name);
/**
* Mark the end of a bootstage activity
*
* After previously marking the start of an activity with bootstage_start(),
* call this function to mark the end. You can call these functions in pairs
* as many times as you like.
*
* @param id Bootstage id to record this timestamp against
* Return: time spent in this iteration of the activity (i.e. the time now
* less the start time recorded in the last bootstage_start() call
* with this id.
*/
uint32_t bootstage_accum(enum bootstage_id id);
/* Print a report about boot time */
void bootstage_report(void);
/**
* Add bootstage information to the device tree
*
* Return: 0 if ok, -ve on error
*/
int bootstage_fdt_add_report(void);
/**
* Stash bootstage data into memory
*
* @param base Base address of memory buffer
* @param size Size of memory buffer
* Return: 0 if stashed ok, -1 if out of space
*/
int bootstage_stash(void *base, int size);
/**
* Read bootstage data from memory
*
* Bootstage data is read from memory and placed in the bootstage table
* in the user records.
*
* @param base Base address of memory buffer
* @param size Size of memory buffer (-1 if unknown)
* Return: 0 if unstashed ok, -ENOENT if bootstage info not found, -ENOSPC if
* there is not space for read the stashed data, or other error if
* something else went wrong
*/
int bootstage_unstash(const void *base, int size);
/**
* bootstage_get_size() - Get the size of the bootstage data
*
* @add_strings: true to add the size of attached strings (for stashing)
* Return: size of boostage data in bytes
*/
int bootstage_get_size(bool add_strings);
/**
* bootstage_init() - Prepare bootstage for use
*
* @first: true if this is the first time bootstage is set up. This causes it
* to add a 'reset' record with a time of 0.
*/
int bootstage_init(bool first);
#else
static inline ulong bootstage_add_record(enum bootstage_id id,
const char *name, int flags, ulong mark)
{
return 0;
}
/*
* This is a dummy implementation which just calls show_boot_progress(),
* and won't even do that unless CONFIG_SHOW_BOOT_PROGRESS is defined
*/
static inline int bootstage_relocate(void *to)
{
return 0;
}
static inline ulong bootstage_mark(enum bootstage_id id)
{
show_boot_progress(id);
return 0;
}
static inline ulong bootstage_error(enum bootstage_id id)
{
show_boot_progress(-id);
return 0;
}
static inline ulong bootstage_mark_name(enum bootstage_id id, const char *name)
{
show_boot_progress(id);
return 0;
}
static inline ulong bootstage_mark_code(const char *file, const char *func,
int linenum)
{
return 0;
}
static inline uint32_t bootstage_start(enum bootstage_id id, const char *name)
{
return 0;
}
static inline uint32_t bootstage_accum(enum bootstage_id id)
{
return 0;
}
static inline void bootstage_report(void)
{
}
static inline void bootstage_fdt_add_report(void)
{
}
static inline int bootstage_stash(void *base, int size)
{
return 0; /* Pretend to succeed */
}
static inline int bootstage_unstash(const void *base, int size)
{
return 0; /* Pretend to succeed */
}
static inline int bootstage_get_size(bool add_strings)
{
return 0;
}
static inline int bootstage_init(bool first)
{
return 0;
}
#endif /* ENABLE_BOOTSTAGE */
/* helpers for SPL */
int _bootstage_stash_default(void);
int _bootstage_unstash_default(void);
static inline int bootstage_stash_default(void)
{
if (CONFIG_IS_ENABLED(BOOTSTAGE) && IS_ENABLED(CONFIG_BOOTSTAGE_STASH))
return _bootstage_stash_default();
return 0;
}
static inline int bootstage_unstash_default(void)
{
if (CONFIG_IS_ENABLED(BOOTSTAGE) && IS_ENABLED(CONFIG_BOOTSTAGE_STASH))
return _bootstage_unstash_default();
return 0;
}
/* Helper macro for adding a bootstage to a line of code */
#define BOOTSTAGE_MARKER() \
bootstage_mark_code(__FILE__, __func__, __LINE__)
#endif
+156
View File
@@ -0,0 +1,156 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Standard U-Boot boot framework
*
* Copyright 2021 Google LLC
* Written by Simon Glass <sjg@chromium.org>
*/
#ifndef __bootstd_h
#define __bootstd_h
#include <alist.h>
#include <dm/ofnode_decl.h>
#include <linux/types.h>
struct udevice;
/**
* struct bootstd_priv - priv data for the bootstd driver
*
* This is attached to the (only) bootstd device, so there is only one instance
* of this struct. It provides overall information about bootdevs and bootflows.
*
* TODO(sjg@chromium.org): Convert prefixes, bootdev_order and env_order to use
* alist
*
* @prefixes: NULL-terminated list of prefixes to use for bootflow filenames,
* e.g. "/", "/boot/"; NULL if none
* @bootdev_order: Order to use for bootdevs (or NULL if none), with each item
* being a bootdev label, e.g. "mmc2", "mmc1" (NULL terminated)
* @env_order: Order as specified by the boot_targets env var (or NULL if none),
* with each item being a bootdev label, e.g. "mmc2", "mmc1" (NULL
* terminated)
* @cur_bootdev: Currently selected bootdev (for commands)
* @cur_bootflow: Currently selected bootflow (for commands)
* @bootflows: (struct bootflow) Global list of all bootflows across all
* bootdevs
* @bootmeth_count: Number of bootmeth devices in @bootmeth_order
* @bootmeth_order: List of bootmeth devices to use, in order, NULL-terminated
* @vbe_bootmeth: Currently selected VBE bootmeth, NULL if none
* @theme: Node containing the theme information
* @hunters_used: Bitmask of used hunters, indexed by their position in the
* linker list. The bit is set if the hunter has been used already
*/
struct bootstd_priv {
const char **prefixes;
const char **bootdev_order;
const char **env_order;
struct udevice *cur_bootdev;
struct bootflow *cur_bootflow;
struct alist bootflows;
int bootmeth_count;
struct udevice **bootmeth_order;
struct udevice *vbe_bootmeth;
ofnode theme;
uint hunters_used;
};
/**
* bootstd_get_bootdev_order() - Get the boot-order list
*
* This reads the boot order, e.g. {"mmc0", "mmc2", NULL}
*
* The list is alloced by the bootstd driver so should not be freed. That is the
* reason for all the const stuff in the function signature
*
* @dev: bootstd device
* @okp: returns true if OK, false if out of memory
* Return: list of string pointers, terminated by NULL; or NULL if no boot
* order. Note that this returns NULL in the case of an empty list
*/
const char *const *const bootstd_get_bootdev_order(struct udevice *dev,
bool *okp);
/**
* bootstd_get_prefixes() - Get the filename-prefixes list
*
* This reads the prefixes, e.g. {"/", "/boot", NULL}
*
* The list is alloced by the bootstd driver so should not be freed. That is the
* reason for all the const stuff in the function signature
*
* Return: list of string points, terminated by NULL; or NULL if no boot order
*/
const char *const *const bootstd_get_prefixes(struct udevice *dev);
/**
* bootstd_get_priv() - Get the (single) state for the bootstd system
*
* The state holds a global list of all bootflows that have been found.
*
* Return: 0 if OK, -ve if the uclass does not exist
*/
int bootstd_get_priv(struct bootstd_priv **stdp);
/**
* bootstd_try_priv() - Try to get the (single) state for the bootstd system
*
* The state holds a global list of all bootflows that have been found. This
* function returns the state if available, but takes care not to create the
* device (or uclass) if it doesn't exist.
*
* This function is safe to use in the 'unbind' path. It will always return NULL
* unless the bootstd device is probed and ready, e.g. bootstd_get_priv() has
* previously been called.
*
* TODO(sjg@chromium.org): Consider adding a bootstd pointer to global_data
*
* Return: pointer if the device exists, else NULL
*/
struct bootstd_priv *bootstd_try_priv(void);
/**
* bootstd_clear_glob() - Clear the global list of bootflows
*
* This removes all bootflows globally and across all bootdevs.
*/
void bootstd_clear_glob(void);
/**
* bootstd_prog_boot() - Run standard boot in a fully programmatic mode
*
* Attempts to boot without making any use of U-Boot commands
*
* Returns: -ve error value (does not return except on failure to boot)
*/
int bootstd_prog_boot(void);
/**
* bootstd_add_bootflow() - Add a bootflow to the global list
*
* All fields in @bflow must be set up. Note that @bflow->dev is used to add the
* bootflow to that device.
*
* The bootflow is also added to the global list of all bootflows
*
* @dev: Bootdev device to add to
* @bflow: Bootflow to add. Note that fields within bflow must be allocated
* since this function takes over ownership of these. This functions makes
* a copy of @bflow itself (without allocating its fields again), so the
* caller must dispose of the memory used by the @bflow pointer itself
* Return: element number in the list, if OK, -ENOMEM if out of memory
*/
int bootstd_add_bootflow(struct bootflow *bflow);
/**
* bootstd_clear_bootflows_for_bootdev() - Clear bootflows from a bootdev
*
* Each bootdev maintains a list of discovered bootflows. This provides a
* way to clear it. These bootflows are removed from the global list too.
*
* @dev: bootdev device to update
*/
int bootstd_clear_bootflows_for_bootdev(struct udevice *dev);
#endif
+86
View File
@@ -0,0 +1,86 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Generic bounce buffer implementation
*
* Copyright (C) 2012 Marek Vasut <marex@denx.de>
*/
#ifndef __INCLUDE_BOUNCEBUF_H__
#define __INCLUDE_BOUNCEBUF_H__
#include <linux/types.h>
/*
* GEN_BB_READ -- Data are read from the buffer eg. by DMA hardware.
* The source buffer is copied into the bounce buffer (if unaligned, otherwise
* the source buffer is used directly) upon start() call, then the operation
* requiring the aligned transfer happens, then the bounce buffer is lost upon
* stop() call.
*/
#define GEN_BB_READ (1 << 0)
/*
* GEN_BB_WRITE -- Data are written into the buffer eg. by DMA hardware.
* The source buffer starts in an undefined state upon start() call, then the
* operation requiring the aligned transfer happens, then the bounce buffer is
* copied into the destination buffer (if unaligned, otherwise destination
* buffer is used directly) upon stop() call.
*/
#define GEN_BB_WRITE (1 << 1)
/*
* GEN_BB_RW -- Data are read and written into the buffer eg. by DMA hardware.
* The source buffer is copied into the bounce buffer (if unaligned, otherwise
* the source buffer is used directly) upon start() call, then the operation
* requiring the aligned transfer happens, then the bounce buffer is copied
* into the destination buffer (if unaligned, otherwise destination buffer is
* used directly) upon stop() call.
*/
#define GEN_BB_RW (GEN_BB_READ | GEN_BB_WRITE)
struct bounce_buffer {
/* Copy of data parameter passed to start() */
void *user_buffer;
/*
* DMA-aligned buffer. This field is always set to the value that
* should be used for DMA; either equal to .user_buffer, or to a
* freshly allocated aligned buffer.
*/
void *bounce_buffer;
/* Copy of len parameter passed to start() */
size_t len;
/* DMA-aligned buffer length */
size_t len_aligned;
/* Copy of flags parameter passed to start() */
unsigned int flags;
};
/**
* bounce_buffer_start() -- Start the bounce buffer session
* state: stores state passed between bounce_buffer_{start,stop}
* data: pointer to buffer to be aligned
* len: length of the buffer
* flags: flags describing the transaction, see above.
*/
int bounce_buffer_start(struct bounce_buffer *state, void *data,
size_t len, unsigned int flags);
/**
* bounce_buffer_start() -- Start the bounce buffer session with external align check function
* state: stores state passed between bounce_buffer_{start,stop}
* data: pointer to buffer to be aligned
* len: length of the buffer
* flags: flags describing the transaction, see above.
* alignment: alignment of the newly allocated bounce buffer
* addr_is_aligned: function for checking the alignment instead of the default one
*/
int bounce_buffer_start_extalign(struct bounce_buffer *state, void *data,
size_t len, unsigned int flags,
size_t alignment,
int (*addr_is_aligned)(struct bounce_buffer *state));
/**
* bounce_buffer_stop() -- Finish the bounce buffer session
* state: stores state passed between bounce_buffer_{start,stop}
*/
int bounce_buffer_stop(struct bounce_buffer *state);
#endif
+55
View File
@@ -0,0 +1,55 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2020 Broadcom.
*
*/
#ifndef __CHIMP_H__
#define __CHIMP_H__
#include <linux/compiler.h>
/*
* Chimp binary has health status like initialization complete,
* crash or running fine
*/
#define BCM_CHIMP_RUNNIG_GOOD 0x8000
enum {
CHIMP_HANDSHAKE_SUCCESS = 0,
CHIMP_HANDSHAKE_WAIT_ERROR,
CHIMP_HANDSHAKE_WAIT_TIMEOUT,
};
/**
* chimp_fastboot_optee() - api to load bnxt firmware
*
* @return: 0 on success and -ve on failure
*/
int chimp_fastboot_optee(void);
/**
* chimp_health_status_optee() - get chimp health status
*
* Chimp health status could be firmware is in good condition or
* bad condition because of crash/hang.
*
* @status: pointer to get chimp health status
*
* @return: 0 on success and -ve on failure
*/
int chimp_health_status_optee(u32 *status);
/**
* chimp_handshake_status_optee() - get chimp handshake status.
*
* To know firmware is loaded and running.
*
* @timeout: timeout value, if 0 then default timeout is considered by op-tee
* @hstatus: pointer to chimp handshake status
*
* @return: 0 on success and -ve on failure
*/
int chimp_handshake_status_optee(u32 timeout, u32 *hstatus);
#endif
+24
View File
@@ -0,0 +1,24 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* BTRFS filesystem implementation for U-Boot
*
* 2017 Marek Behún, CZ.NIC, kabel@kernel.org
*/
#ifndef __U_BOOT_BTRFS_H__
#define __U_BOOT_BTRFS_H__
struct blk_desc;
struct disk_partition;
int btrfs_probe(struct blk_desc *fs_dev_desc,
struct disk_partition *fs_partition);
int btrfs_ls(const char *);
int btrfs_exists(const char *);
int btrfs_size(const char *, loff_t *);
int btrfs_read(const char *, void *, loff_t, loff_t, loff_t *);
void btrfs_close(void);
int btrfs_uuid(char *);
void btrfs_list_subvols(void);
#endif /* __U_BOOT_BTRFS_H__ */
+19
View File
@@ -0,0 +1,19 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2005-2009
* Jens Scharsig @ BuS Elektronik GmbH & Co. KG, <esw@bus-elektronik.de>
*/
#ifndef __BUS_VCXK_H_
#define __BUS_VCXK_H_
extern int vcxk_init(unsigned long width, unsigned long height);
extern void vcxk_setpixel(int x, int y, unsigned long color);
extern int vcxk_acknowledge_wait(void);
extern int vcxk_request(void);
extern void vcxk_loadimage(ulong source);
extern int vcxk_display_bitmap(ulong addr, int x, int y);
extern void vcxk_setbrightness(unsigned int side, short brightness);
extern int video_display_bitmap(ulong addr, int x, int y);
#endif
+86
View File
@@ -0,0 +1,86 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (C) 2020 Philippe Reynes <philippe.reynes@softathome.com>
*/
#ifndef __BUTTON_H
#define __BUTTON_H
struct udevice;
/**
* struct button_uc_plat - Platform data the uclass stores about each device
*
* @label: Button label
*/
struct button_uc_plat {
const char *label;
};
/**
* enum button_state_t - State used for button
* - BUTTON_OFF - Button is not pressed
* - BUTTON_ON - Button is pressed
* - BUTTON_COUNT - Number of button state
*/
enum button_state_t {
BUTTON_OFF = 0,
BUTTON_ON = 1,
BUTTON_COUNT,
};
struct button_ops {
/**
* get_state() - get the state of a button
*
* @dev: button device to change
* @return button state button_state_t, or -ve on error
*/
enum button_state_t (*get_state)(struct udevice *dev);
/**
* get_code() - get linux event code of a button
*
* @dev: button device to change
* @return button code, or -ENODATA on error
*/
int (*get_code)(struct udevice *dev);
};
#define button_get_ops(dev) ((struct button_ops *)(dev)->driver->ops)
/**
* button_get_by_label() - Find a button device by label
*
* @label: button label to look up
* @devp: Returns the associated device, if found
* Return: 0 if found, -ENODEV if not found, other -ve on error
*/
int button_get_by_label(const char *label, struct udevice **devp);
/**
* button_get_state() - get the state of a button
*
* @dev: button device to change
* Return: button state button_state_t, or -ve on error
*/
enum button_state_t button_get_state(struct udevice *dev);
/**
* button_get_code() - get linux event code of a button
*
* @dev: button device to change
* @return button code, or -ve on error
*/
int button_get_code(struct udevice *dev);
#if IS_ENABLED(CONFIG_BUTTON_CMD)
/* Process button command mappings specified in the environment,
* running the commands for buttons which are pressed
*/
void process_button_cmds(void);
#else
static inline void process_button_cmds(void) {}
#endif /* CONFIG_BUTTON_CMD */
#endif
+326
View File
@@ -0,0 +1,326 @@
/*
* This file is a modified version of bzlib.h from the bzip2-1.0.2
* distribution which can be found at http://sources.redhat.com/bzip2/
*/
/*-------------------------------------------------------------*/
/*--- Public header file for the library. ---*/
/*--- bzlib.h ---*/
/*-------------------------------------------------------------*/
/*--
This file is a part of bzip2 and/or libbzip2, a program and
library for lossless, block-sorting data compression.
Copyright (C) 1996-2002 Julian R Seward. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. The origin of this software must not be misrepresented; you must
not claim that you wrote the original software. If you use this
software in a product, an acknowledgment in the product
documentation would be appreciated but is not required.
3. Altered source versions must be plainly marked as such, and must
not be misrepresented as being the original software.
4. The name of the author may not be used to endorse or promote
products derived from this software without specific prior written
permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Julian Seward, Cambridge, UK.
jseward@acm.org
bzip2/libbzip2 version 1.0 of 21 March 2000
This program is based on (at least) the work of:
Mike Burrows
David Wheeler
Peter Fenwick
Alistair Moffat
Radford Neal
Ian H. Witten
Robert Sedgewick
Jon L. Bentley
For more information on these sources, see the manual.
--*/
#ifndef _BZLIB_H
#define _BZLIB_H
/* Configure for U-Boot environment */
#define BZ_NO_STDIO
#ifndef CONFIG_SANDBOX
#define BZ_NO_COMPRESS
#endif
/* End of configuration for U-Boot environment */
#ifdef __cplusplus
extern "C" {
#endif
#define BZ_RUN 0
#define BZ_FLUSH 1
#define BZ_FINISH 2
#define BZ_OK 0
#define BZ_RUN_OK 1
#define BZ_FLUSH_OK 2
#define BZ_FINISH_OK 3
#define BZ_STREAM_END 4
#define BZ_SEQUENCE_ERROR (-1)
#define BZ_PARAM_ERROR (-2)
#define BZ_MEM_ERROR (-3)
#define BZ_DATA_ERROR (-4)
#define BZ_DATA_ERROR_MAGIC (-5)
#define BZ_IO_ERROR (-6)
#define BZ_UNEXPECTED_EOF (-7)
#define BZ_OUTBUFF_FULL (-8)
#define BZ_CONFIG_ERROR (-9)
typedef
struct {
char *next_in;
unsigned int avail_in;
unsigned int total_in_lo32;
unsigned int total_in_hi32;
char *next_out;
unsigned int avail_out;
unsigned int total_out_lo32;
unsigned int total_out_hi32;
void *state;
void *(*bzalloc)(void *,int,int);
void (*bzfree)(void *,void *);
void *opaque;
}
bz_stream;
#ifndef BZ_IMPORT
#define BZ_EXPORT
#endif
#ifdef _WIN32
# include <windows.h>
# ifdef small
/* windows.h define small to char */
# undef small
# endif
# ifdef BZ_EXPORT
# define BZ_API(func) WINAPI func
# define BZ_EXTERN extern
# else
/* import windows dll dynamically */
# define BZ_API(func) (WINAPI * func)
# define BZ_EXTERN
# endif
#else
# define BZ_API(func) func
# define BZ_EXTERN extern
#endif
/*-- Core (low-level) library functions --*/
BZ_EXTERN int BZ_API(BZ2_bzCompressInit) (
bz_stream* strm,
int blockSize100k,
int verbosity,
int workFactor
);
BZ_EXTERN int BZ_API(BZ2_bzCompress) (
bz_stream* strm,
int action
);
BZ_EXTERN int BZ_API(BZ2_bzCompressEnd) (
bz_stream* strm
);
BZ_EXTERN int BZ_API(BZ2_bzDecompressInit) (
bz_stream *strm,
int verbosity,
int small
);
BZ_EXTERN int BZ_API(BZ2_bzDecompress) (
bz_stream* strm
);
BZ_EXTERN int BZ_API(BZ2_bzDecompressEnd) (
bz_stream *strm
);
/*-- High(er) level library functions --*/
#ifndef BZ_NO_STDIO
#define BZ_MAX_UNUSED 5000
/* Need a definitition for FILE */
#include <stdio.h>
typedef void BZFILE;
BZ_EXTERN BZFILE* BZ_API(BZ2_bzReadOpen) (
int* bzerror,
FILE* f,
int verbosity,
int small,
void* unused,
int nUnused
);
BZ_EXTERN void BZ_API(BZ2_bzReadClose) (
int* bzerror,
BZFILE* b
);
BZ_EXTERN void BZ_API(BZ2_bzReadGetUnused) (
int* bzerror,
BZFILE* b,
void** unused,
int* nUnused
);
BZ_EXTERN int BZ_API(BZ2_bzRead) (
int* bzerror,
BZFILE* b,
void* buf,
int len
);
BZ_EXTERN BZFILE* BZ_API(BZ2_bzWriteOpen) (
int* bzerror,
FILE* f,
int blockSize100k,
int verbosity,
int workFactor
);
BZ_EXTERN void BZ_API(BZ2_bzWrite) (
int* bzerror,
BZFILE* b,
void* buf,
int len
);
BZ_EXTERN void BZ_API(BZ2_bzWriteClose) (
int* bzerror,
BZFILE* b,
int abandon,
unsigned int* nbytes_in,
unsigned int* nbytes_out
);
BZ_EXTERN void BZ_API(BZ2_bzWriteClose64) (
int* bzerror,
BZFILE* b,
int abandon,
unsigned int* nbytes_in_lo32,
unsigned int* nbytes_in_hi32,
unsigned int* nbytes_out_lo32,
unsigned int* nbytes_out_hi32
);
#endif
/*-- Utility functions --*/
BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffCompress) (
char* dest,
unsigned int* destLen,
char* source,
unsigned int sourceLen,
int blockSize100k,
int verbosity,
int workFactor
);
BZ_EXTERN int BZ_API(BZ2_bzBuffToBuffDecompress) (
char* dest,
unsigned int* destLen,
char* source,
unsigned int sourceLen,
int small,
int verbosity
);
/*--
Code contributed by Yoshioka Tsuneo
(QWF00133@niftyserve.or.jp/tsuneo-y@is.aist-nara.ac.jp),
to support better zlib compatibility.
This code is not _officially_ part of libbzip2 (yet);
I haven't tested it, documented it, or considered the
threading-safeness of it.
If this code breaks, please contact both Yoshioka and me.
--*/
BZ_EXTERN const char * BZ_API(BZ2_bzlibVersion) (
void
);
#ifndef BZ_NO_STDIO
BZ_EXTERN BZFILE * BZ_API(BZ2_bzopen) (
const char *path,
const char *mode
);
BZ_EXTERN BZFILE * BZ_API(BZ2_bzdopen) (
int fd,
const char *mode
);
BZ_EXTERN int BZ_API(BZ2_bzread) (
BZFILE* b,
void* buf,
int len
);
BZ_EXTERN int BZ_API(BZ2_bzwrite) (
BZFILE* b,
void* buf,
int len
);
BZ_EXTERN int BZ_API(BZ2_bzflush) (
BZFILE* b
);
BZ_EXTERN void BZ_API(BZ2_bzclose) (
BZFILE* b
);
BZ_EXTERN const char * BZ_API(BZ2_bzerror) (
BZFILE *b,
int *errnum
);
#endif
#ifdef __cplusplus
}
#endif
#endif
/*-------------------------------------------------------------*/
/*--- end bzlib.h ---*/
/*-------------------------------------------------------------*/
+73
View File
@@ -0,0 +1,73 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2019 Intel Corporation <www.intel.com>
*/
#ifndef __CACHE_H
#define __CACHE_H
#include <linux/types.h>
struct udevice;
/*
* Structure for the cache controller
*/
struct cache_info {
phys_addr_t base; /* Base physical address of cache device. */
};
struct cache_ops {
/**
* get_info() - Get basic cache info
*
* @dev: Device to check (UCLASS_CACHE)
* @info: Place to put info
* @return 0 if OK, -ve on error
*/
int (*get_info)(struct udevice *dev, struct cache_info *info);
/**
* enable() - Enable cache
*
* @dev: Device to check (UCLASS_CACHE)
* @return 0 if OK, -ve on error
*/
int (*enable)(struct udevice *dev);
/**
* disable() - Flush and disable cache
*
* @dev: Device to check (UCLASS_CACHE)
* @return 0 if OK, -ve on error
*/
int (*disable)(struct udevice *dev);
};
#define cache_get_ops(dev) ((struct cache_ops *)(dev)->driver->ops)
/**
* cache_get_info() - Get information about a cache controller
*
* @dev: Device to check (UCLASS_CACHE)
* @info: Returns cache info
* Return: 0 if OK, -ve on error
*/
int cache_get_info(struct udevice *dev, struct cache_info *info);
/**
* cache_enable() - Enable cache
*
* @dev: Device to check (UCLASS_CACHE)
* Return: 0 if OK, -ve on error
*/
int cache_enable(struct udevice *dev);
/**
* cache_disable() - Flush and disable cache
*
* @dev: Device to check (UCLASS_CACHE)
* Return: 0 if OK, -ve on error
*/
int cache_disable(struct udevice *dev);
#endif
+529
View File
@@ -0,0 +1,529 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Cadence NAND flash controller driver
*
* Copyright (C) 2019 Cadence
*
* Author: Piotr Sroka <piotrs@cadence.com>
*
*/
#ifndef _CADENCE_NAND_H_
#define _CADENCE_NAND_H_
#include <clk.h>
#include <reset.h>
#include <linux/types.h>
#include <linux/mtd/rawnand.h>
/*
* HPNFC can work in 3 modes:
* - PIO - can work in master or slave DMA
* - CDMA - needs Master DMA for accessing command descriptors.
* - Generic mode - can use only slave DMA.
* CDMA and PIO modes can be used to execute only base commands.
* CDMA and PIO modes can be used to execute only base commands.
* Generic mode can be used to execute any command
* on NAND flash memory. Driver uses CDMA mode for
* block erasing, page reading, page programing.
* Generic mode is used for executing rest of commands.
*/
#define DMA_DATA_SIZE_ALIGN 8
/* Register definition. */
/*
* Command register 0.
* Writing data to this register will initiate a new transaction
* of the NF controller.
*/
#define CMD_REG0 0x0000
/* Command type field mask. */
#define CMD_REG0_CT GENMASK(31, 30)
/* Command type CDMA. */
#define CMD_REG0_CT_CDMA 0uL
/* Command type generic. */
#define CMD_REG0_CT_GEN 3uL
/* Command thread number field mask. */
#define CMD_REG0_TN GENMASK(27, 24)
/* Command register 2. */
#define CMD_REG2 0x0008
/* Command register 3. */
#define CMD_REG3 0x000C
/* Pointer register to select which thread status will be selected. */
#define CMD_STATUS_PTR 0x0010
/* Command status register for selected thread. */
#define CMD_STATUS 0x0014
/* Interrupt status register. */
#define INTR_STATUS 0x0110
#define INTR_STATUS_SDMA_ERR BIT(22)
#define INTR_STATUS_SDMA_TRIGG BIT(21)
#define INTR_STATUS_UNSUPP_CMD BIT(19)
#define INTR_STATUS_DDMA_TERR BIT(18)
#define INTR_STATUS_CDMA_TERR BIT(17)
#define INTR_STATUS_CDMA_IDL BIT(16)
/* Interrupt enable register. */
#define INTR_ENABLE 0x0114
#define INTR_ENABLE_INTR_EN BIT(31)
/* Controller internal state. */
#define CTRL_STATUS 0x0118
#define CTRL_STATUS_INIT_COMP BIT(9)
#define CTRL_STATUS_CTRL_BUSY BIT(8)
/* Command Engine threads state. */
#define TRD_STATUS 0x0120
/* Command Engine interrupt thread error status. */
#define TRD_ERR_INT_STATUS 0x0128
/* Command Engine interrupt thread error enable. */
#define TRD_ERR_INT_STATUS_EN 0x0130
/* Command Engine interrupt thread complete status. */
#define TRD_COMP_INT_STATUS 0x0138
/*
* Transfer config 0 register.
* Configures data transfer parameters.
*/
#define TRAN_CFG_0 0x0400
/* Offset value from the beginning of the page. */
#define TRAN_CFG_0_OFFSET GENMASK(31, 16)
/* Numbers of sectors to transfer within singlNF device's page. */
#define TRAN_CFG_0_SEC_CNT GENMASK(7, 0)
/*
* Transfer config 1 register.
* Configures data transfer parameters.
*/
#define TRAN_CFG_1 0x0404
/* Size of last data sector. */
#define TRAN_CFG_1_LAST_SEC_SIZE GENMASK(31, 16)
/* Size of not-last data sector. */
#define TRAN_CFG_1_SECTOR_SIZE GENMASK(15, 0)
/* ECC engine configuration register 0. */
#define ECC_CONFIG_0 0x0428
/* Correction strength. */
#define ECC_CONFIG_0_CORR_STR GENMASK(10, 8)
/* Enable erased pages detection mechanism. */
#define ECC_CONFIG_0_ERASE_DET_EN BIT(1)
/* Enable controller ECC check bits generation and correction. */
#define ECC_CONFIG_0_ECC_EN BIT(0)
/* ECC engine configuration register 1. */
#define ECC_CONFIG_1 0x042C
/* Multiplane settings register. */
#define MULTIPLANE_CFG 0x0434
/* Cache operation settings. */
#define CACHE_CFG 0x0438
/* Transferred data block size for the slave DMA module. */
#define SDMA_SIZE 0x0440
/* Thread number associated with transferred data block
* for the slave DMA module.
*/
#define SDMA_TRD_NUM 0x0444
/* Thread number mask. */
#define SDMA_TRD_NUM_SDMA_TRD GENMASK(2, 0)
#define CONTROL_DATA_CTRL 0x0494
/* Thread number mask. */
#define CONTROL_DATA_CTRL_SIZE GENMASK(15, 0)
#define CTRL_VERSION 0x800
#define CTRL_VERSION_REV GENMASK(7, 0)
/* Available hardware features of the controller. */
#define CTRL_FEATURES 0x804
/* Support for NV-DDR2/3 work mode. */
#define CTRL_FEATURES_NVDDR_2_3 BIT(28)
/* Support for NV-DDR work mode. */
#define CTRL_FEATURES_NVDDR BIT(27)
/* Support for asynchronous work mode. */
#define CTRL_FEATURES_ASYNC BIT(26)
/* Support for asynchronous work mode. */
#define CTRL_FEATURES_N_BANKS GENMASK(25, 24)
/* Slave and Master DMA data width. */
#define CTRL_FEATURES_DMA_DWITH64 BIT(21)
/* Availability of Control Data feature.*/
#define CTRL_FEATURES_CONTROL_DATA BIT(10)
/* BCH Engine identification register 0 - correction strengths. */
#define BCH_CFG_0 0x838
#define BCH_CFG_0_CORR_CAP_0 GENMASK(7, 0)
#define BCH_CFG_0_CORR_CAP_1 GENMASK(15, 8)
#define BCH_CFG_0_CORR_CAP_2 GENMASK(23, 16)
#define BCH_CFG_0_CORR_CAP_3 GENMASK(31, 24)
/* BCH Engine identification register 1 - correction strengths. */
#define BCH_CFG_1 0x83C
#define BCH_CFG_1_CORR_CAP_4 GENMASK(7, 0)
#define BCH_CFG_1_CORR_CAP_5 GENMASK(15, 8)
#define BCH_CFG_1_CORR_CAP_6 GENMASK(23, 16)
#define BCH_CFG_1_CORR_CAP_7 GENMASK(31, 24)
/* BCH Engine identification register 2 - sector sizes. */
#define BCH_CFG_2 0x840
#define BCH_CFG_2_SECT_0 GENMASK(15, 0)
#define BCH_CFG_2_SECT_1 GENMASK(31, 16)
/* BCH Engine identification register 3. */
#define BCH_CFG_3 0x844
#define BCH_CFG_3_METADATA_SIZE GENMASK(23, 16)
/* Ready/Busy# line status. */
#define RBN_SETINGS 0x1004
/* Common settings. */
#define COMMON_SET 0x1008
/* 16 bit device connected to the NAND Flash interface. */
#define COMMON_SET_DEVICE_16BIT BIT(8)
/* Skip_bytes registers. */
#define SKIP_BYTES_CONF 0x100C
#define SKIP_BYTES_MARKER_VALUE GENMASK(31, 16)
#define SKIP_BYTES_NUM_OF_BYTES GENMASK(7, 0)
#define SKIP_BYTES_OFFSET 0x1010
#define SKIP_BYTES_OFFSET_VALUE GENMASK(23, 0)
/* Timings configuration. */
#define ASYNC_TOGGLE_TIMINGS 0x101c
#define ASYNC_TOGGLE_TIMINGS_TRH GENMASK(28, 24)
#define ASYNC_TOGGLE_TIMINGS_TRP GENMASK(20, 16)
#define ASYNC_TOGGLE_TIMINGS_TWH GENMASK(12, 8)
#define ASYNC_TOGGLE_TIMINGS_TWP GENMASK(4, 0)
#define TIMINGS0 0x1024
#define TIMINGS0_TADL GENMASK(31, 24)
#define TIMINGS0_TCCS GENMASK(23, 16)
#define TIMINGS0_TWHR GENMASK(15, 8)
#define TIMINGS0_TRHW GENMASK(7, 0)
#define TIMINGS1 0x1028
#define TIMINGS1_TRHZ GENMASK(31, 24)
#define TIMINGS1_TWB GENMASK(23, 16)
#define TIMINGS1_TVDLY GENMASK(7, 0)
#define TIMINGS2 0x102c
#define TIMINGS2_TFEAT GENMASK(25, 16)
#define TIMINGS2_CS_HOLD_TIME GENMASK(13, 8)
#define TIMINGS2_CS_SETUP_TIME GENMASK(5, 0)
/* Configuration of the resynchronization of slave DLL of PHY. */
#define DLL_PHY_CTRL 0x1034
#define DLL_PHY_CTRL_DLL_RST_N BIT(24)
#define DLL_PHY_CTRL_EXTENDED_WR_MODE BIT(17)
#define DLL_PHY_CTRL_EXTENDED_RD_MODE BIT(16)
#define DLL_PHY_CTRL_RS_HIGH_WAIT_CNT GENMASK(11, 8)
#define DLL_PHY_CTRL_RS_IDLE_CNT GENMASK(7, 0)
/* TODO: - Identify better way to handle PHY address */
#define PHY_OFFSET 0x10000
/* Register controlling DQ related timing. */
#define PHY_DQ_TIMING PHY_OFFSET + 0x2000
/* Register controlling DSQ related timing. */
#define PHY_DQS_TIMING PHY_OFFSET + 0x2004
#define PHY_DQS_TIMING_DQS_SEL_OE_END GENMASK(3, 0)
#define PHY_DQS_TIMING_PHONY_DQS_SEL BIT(16)
#define PHY_DQS_TIMING_USE_PHONY_DQS BIT(20)
/* Register controlling the gate and loopback control related timing. */
#define PHY_GATE_LPBK_CTRL PHY_OFFSET + 0x2008
#define PHY_GATE_LPBK_CTRL_RDS GENMASK(24, 19)
/* Register holds the control for the master DLL logic. */
#define PHY_DLL_MASTER_CTRL PHY_OFFSET + 0x200C
#define PHY_DLL_MASTER_CTRL_BYPASS_MODE BIT(23)
/* Register holds the control for the slave DLL logic. */
#define PHY_DLL_SLAVE_CTRL PHY_OFFSET + 0x2010
/* This register handles the global control settings for the PHY. */
#define PHY_CTRL PHY_OFFSET + 0x2080
#define PHY_CTRL_SDR_DQS BIT(14)
#define PHY_CTRL_PHONY_DQS GENMASK(9, 4)
/*
* This register handles the global control settings
* for the termination selects for reads.
*/
#define PHY_TSEL PHY_OFFSET + 0x2084
/* Generic command layout. */
#define GCMD_LAY_CS GENMASK_ULL(11, 8)
/*
* This bit informs the minicotroller if it has to wait for tWB
* after sending the last CMD/ADDR/DATA in the sequence.
*/
#define GCMD_LAY_TWB BIT_ULL(6)
/* Type of generic instruction. */
#define GCMD_LAY_INSTR GENMASK_ULL(5, 0)
/* Generic CMD sequence type. */
#define GCMD_LAY_INSTR_CMD 0
/* Generic ADDR sequence type. */
#define GCMD_LAY_INSTR_ADDR 1
/* Generic data transfer sequence type. */
#define GCMD_LAY_INSTR_DATA 2
/* Input part of generic command type of input is command. */
#define GCMD_LAY_INPUT_CMD GENMASK_ULL(23, 16)
/* Generic command address sequence - address fields. */
#define GCMD_LAY_INPUT_ADDR GENMASK_ULL(63, 16)
/* Generic command address sequence - address size. */
#define GCMD_LAY_INPUT_ADDR_SIZE GENMASK_ULL(13, 11)
/* Transfer direction field of generic command data sequence. */
#define GCMD_DIR BIT_ULL(11)
/* Read transfer direction of generic command data sequence. */
#define GCMD_DIR_READ 0
/* Write transfer direction of generic command data sequence. */
#define GCMD_DIR_WRITE 1
/* ECC enabled flag of generic command data sequence - ECC enabled. */
#define GCMD_ECC_EN BIT_ULL(12)
/* Generic command data sequence - sector size. */
#define GCMD_SECT_SIZE GENMASK_ULL(31, 16)
/* Generic command data sequence - sector count. */
#define GCMD_SECT_CNT GENMASK_ULL(39, 32)
/* Generic command data sequence - last sector size. */
#define GCMD_LAST_SIZE GENMASK_ULL(55, 40)
/* CDMA descriptor fields. */
/* Erase command type of CDMA descriptor. */
#define CDMA_CT_ERASE 0x1000
/* Program page command type of CDMA descriptor. */
#define CDMA_CT_WR 0x2100
/* Read page command type of CDMA descriptor. */
#define CDMA_CT_RD 0x2200
/* Flash pointer memory shift. */
#define CDMA_CFPTR_MEM_SHIFT 24
/* Flash pointer memory mask. */
#define CDMA_CFPTR_MEM GENMASK(26, 24)
/*
* Command DMA descriptor flags. If set causes issue interrupt after
* the completion of descriptor processing.
*/
#define CDMA_CF_INT BIT(8)
/*
* Command DMA descriptor flags - the next descriptor
* address field is valid and descriptor processing should continue.
*/
#define CDMA_CF_CONT BIT(9)
/* DMA master flag of command DMA descriptor. */
#define CDMA_CF_DMA_MASTER BIT(10)
/* Operation complete status of command descriptor. */
#define CDMA_CS_COMP BIT(15)
/* Operation complete status of command descriptor. */
/* Command descriptor status - operation fail. */
#define CDMA_CS_FAIL BIT(14)
/* Command descriptor status - page erased. */
#define CDMA_CS_ERP BIT(11)
/* Command descriptor status - timeout occurred. */
#define CDMA_CS_TOUT BIT(10)
/*
* Maximum amount of correction applied to one ECC sector.
* It is part of command descriptor status.
*/
#define CDMA_CS_MAXERR GENMASK(9, 2)
/* Command descriptor status - uncorrectable ECC error. */
#define CDMA_CS_UNCE BIT(1)
/* Command descriptor status - descriptor error. */
#define CDMA_CS_ERR BIT(0)
/* Status of operation - OK. */
#define STAT_OK 0
/* Status of operation - FAIL. */
#define STAT_FAIL 2
/* Status of operation - uncorrectable ECC error. */
#define STAT_ECC_UNCORR 3
/* Status of operation - page erased. */
#define STAT_ERASED 5
/* Status of operation - correctable ECC error. */
#define STAT_ECC_CORR 6
/* Status of operation - unsuspected state. */
#define STAT_UNKNOWN 7
/* Status of operation - operation is not completed yet. */
#define STAT_BUSY 0xFF
#define BCH_MAX_NUM_CORR_CAPS 8
#define BCH_MAX_NUM_SECTOR_SIZES 2
#define ONE_CYCLE 1
#define TIMEOUT_US 1000000
struct cadence_nand_timings {
u32 async_toggle_timings;
u32 timings0;
u32 timings1;
u32 timings2;
u32 dll_phy_ctrl;
u32 phy_ctrl;
u32 phy_dqs_timing;
u32 phy_gate_lpbk_ctrl;
};
/* Command DMA descriptor. */
struct cadence_nand_cdma_desc {
/* Next descriptor address. */
u64 next_pointer;
/* Flash address is a 32-bit address comprising of BANK and ROW ADDR. */
u32 flash_pointer;
/*field appears in HPNFC version 13*/
u16 bank;
u16 rsvd0;
/* Operation the controller needs to perform. */
u16 command_type;
u16 rsvd1;
/* Flags for operation of this command. */
u16 command_flags;
u16 rsvd2;
/* System/host memory address required for data DMA commands. */
u64 memory_pointer;
/* Status of operation. */
u32 status;
u32 rsvd3;
/* Address pointer to sync buffer location. */
u64 sync_flag_pointer;
/* Controls the buffer sync mechanism. */
u32 sync_arguments;
u32 rsvd4;
/* Control data pointer. */
u64 ctrl_data_ptr;
};
/* Interrupt status. */
struct cadence_nand_irq_status {
/* Thread operation complete status. */
u32 trd_status;
/* Thread operation error. */
u32 trd_error;
/* Controller status. */
u32 status;
};
/* Cadence NAND flash controller capabilities get from driver data. */
struct cadence_nand_dt_devdata {
/* Skew value of the output signals of the NAND Flash interface. */
u32 if_skew;
/* It informs if slave DMA interface is connected to DMA engine. */
unsigned int has_dma:1;
};
/* Cadence NAND flash controller capabilities read from registers. */
struct cdns_nand_caps {
/* Maximum number of banks supported by hardware. */
u8 max_banks;
/* Slave and Master DMA data width in bytes (4 or 8). */
u8 data_dma_width;
/* Control Data feature supported. */
bool data_control_supp;
/* Is PHY type DLL. */
bool is_phy_type_dll;
};
struct cadence_nand_info {
struct nand_hw_control controller;
struct udevice *dev;
struct reset_ctl softphy_reset;
struct reset_ctl nand_reset;
struct cadence_nand_cdma_desc *cdma_desc;
/* IP capability. */
const struct cadence_nand_dt_devdata *caps1;
struct cdns_nand_caps caps2;
u8 ctrl_rev;
dma_addr_t dma_cdma_desc;
/* command interface buffers */
u8 *buf;
u32 buf_size;
u8 *stat;
u8 cmd;
u32 buf_index;
u8 curr_corr_str_idx;
/* Register interface. */
void __iomem *reg;
struct {
void __iomem *virt;
dma_addr_t dma;
} io;
int irq;
/* Interrupts that have happened. */
struct cadence_nand_irq_status irq_status;
/* Interrupts we are waiting for. */
struct cadence_nand_irq_status irq_mask;
int ecc_strengths[BCH_MAX_NUM_CORR_CAPS];
struct nand_ecc_step_info ecc_stepinfos[BCH_MAX_NUM_SECTOR_SIZES];
struct nand_ecc_caps ecc_caps;
int curr_trans_type;
struct clk clk;
u32 nf_clk_rate;
/*
* Estimated Board delay. The value includes the total
* round trip delay for the signals and is used for deciding on values
* associated with data read capture.
*/
u32 board_delay;
struct nand_chip *selected_chip;
unsigned long assigned_cs;
struct list_head chips;
u8 bch_metadata_size;
};
struct cdns_nand_chip {
struct cadence_nand_timings timings;
struct nand_chip chip;
u8 nsels;
struct list_head node;
/*
* part of oob area of NAND flash memory page.
* This part is available for user to read or write.
*/
u32 avail_oob_size;
/* Sector size. There are few sectors per mtd->writesize */
u32 sector_size;
u32 sector_count;
/* Offset of BBM. */
u8 bbm_offs;
/* Number of bytes reserved for BBM. */
u8 bbm_len;
/* ECC strength index. */
u8 corr_str_idx;
u8 cs[];
};
struct ecc_info {
int (*calc_ecc_bytes)(int step_size, int strength);
int max_step_size;
};
#endif /*_CADENCE_NAND_H_*/
File diff suppressed because it is too large Load Diff
+21
View File
@@ -0,0 +1,21 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/**
* (C) Copyright 2014, Cavium Inc.
**/
#ifndef __ATF_H__
#define __ATF_H__
#include <cavium/atf_part.h>
ssize_t atf_read_mmc(uintptr_t offset, void *buffer, size_t size);
ssize_t atf_read_nor(uintptr_t offset, void *buffer, size_t size);
ssize_t atf_get_pcount(void);
ssize_t atf_get_part(struct storage_partition *part, unsigned int index);
ssize_t atf_erase_nor(uintptr_t offset, size_t size);
ssize_t atf_write_nor(uintptr_t offset, const void *buffer, size_t size);
ssize_t atf_write_mmc(uintptr_t offset, const void *buffer, size_t size);
ssize_t atf_dram_size(unsigned int node);
ssize_t atf_node_count(void);
ssize_t atf_env_count(void);
ssize_t atf_env_string(size_t index, char *str);
#endif
+25
View File
@@ -0,0 +1,25 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/**
* (C) Copyright 2014, Cavium Inc.
**/
#ifndef __ATF_PART_H__
#define __ATF_PART_H__
struct storage_partition {
unsigned int type;
unsigned int size;
unsigned long offset;
};
enum {
PARTITION_NBL1FW_REST = 0,
PARTITION_BL2_BL31 = 1,
PARTITION_UBOOT = 2,
PARTITION_UEFI = 2,
PARTITION_KERNEL = 3,
PARTITION_DEVICE_TREE = 4,
PARTITION_LAST,
};
#endif
+66
View File
@@ -0,0 +1,66 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/**
* (C) Copyright 2014, Cavium Inc.
**/
#ifndef __THUNDERX_SVC_H__
#define __THUNDERX_SVC_H__
/* SMC function IDs for general purpose queries */
#define THUNDERX_SVC_CALL_COUNT 0x4300ff00
#define THUNDERX_SVC_UID 0x4300ff01
#define THUNDERX_SVC_VERSION 0x4300ff03
#define ARM_STD_SVC_VERSION 0x8400ff03
/* ThunderX Service Calls version numbers */
#define THUNDERX_VERSION_MAJOR 0x0
#define THUNDERX_VERSION_MINOR 0x1
#define THUNDERX_MMC_READ 0x43000101
/* x1 - block address
* x2 - size
* x3 - buffer address
*/
#define THUNDERX_MMC_WRITE 0x43000102
/* x1 - block address
* x2 - size
* x3 - buffer address
*/
#define THUNDERX_NOR_READ 0x43000111
/* x1 - block address
* x2 - size
* x3 - buffer address
*/
#define THUNDERX_NOR_WRITE 0x43000112
/* x1 - block address
* x2 - size
* x3 - buffer address
*/
#define THUNDERX_NOR_ERASE 0x43000113
/* x1 - block address
*/
#define THUNDERX_PART_COUNT 0x43000201
#define THUNDERX_GET_PART 0x43000202
/* x1 - pointer to the buffer
* x2 - index
*/
#define THUNDERX_DRAM_SIZE 0x43000301
/* x1 - node number
*/
#define THUNDERX_GTI_SYNC 0x43000401
#define THUNDERX_ENV_COUNT 0x43000501
#define THUNDERX_ENV_STRING 0x43000502
/* x1 - index
*/
#define THUNDERX_NODE_COUNT 0x43000601
#endif /* __THUNDERX_SVC_H__ */
+340
View File
@@ -0,0 +1,340 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
*/
#ifndef __CBFS_H
#define __CBFS_H
#include <linux/compiler.h>
#include <linux/types.h>
struct cbfs_priv;
enum cbfs_result {
CBFS_SUCCESS = 0,
CBFS_NOT_INITIALIZED,
CBFS_BAD_HEADER,
CBFS_BAD_FILE,
CBFS_FILE_NOT_FOUND
};
enum cbfs_filetype {
CBFS_TYPE_BOOTBLOCK = 0x01,
CBFS_TYPE_CBFSHEADER = 0x02,
CBFS_TYPE_LEGACY_STAGE = 0x10,
CBFS_TYPE_PAYLOAD = 0x20,
CBFS_TYPE_SELF = CBFS_TYPE_PAYLOAD,
CBFS_TYPE_FIT = 0x21,
CBFS_TYPE_OPTIONROM = 0x30,
CBFS_TYPE_BOOTSPLASH = 0x40,
CBFS_TYPE_RAW = 0x50,
CBFS_TYPE_VSA = 0x51,
CBFS_TYPE_MBI = 0x52,
CBFS_TYPE_MICROCODE = 0x53,
CBFS_TYPE_FSP = 0x60,
CBFS_TYPE_MRC = 0x61,
CBFS_TYPE_MMA = 0x62,
CBFS_TYPE_EFI = 0x63,
CBFS_TYPE_STRUCT = 0x70,
CBFS_TYPE_CMOS_DEFAULT = 0xaa,
CBFS_TYPE_SPD = 0xab,
CBFS_TYPE_MRC_CACHE = 0xac,
CBFS_TYPE_CMOS_LAYOUT = 0x01aa
};
enum {
CBFS_HEADER_MAGIC = 0x4f524243,
CBFS_SIZE_UNKNOWN = 0xffffffff,
CBFS_ALIGN_SIZE = 0x40,
};
/**
* struct cbfs_header - header at the start of a CBFS region
*
* All fields use big-endian format.
*
* @magic: Magic number (CBFS_HEADER_MAGIC)
*/
struct cbfs_header {
u32 magic;
u32 version;
u32 rom_size;
u32 boot_block_size;
u32 align;
u32 offset;
u32 pad[2];
} __packed;
struct cbfs_fileheader {
u8 magic[8];
u32 len;
u32 type;
/* offset to struct cbfs_file_attribute or 0 */
u32 attributes_offset;
u32 offset;
char filename[];
} __packed;
/**
* These are standard values for the known compression alogrithms that coreboot
* knows about for stages and payloads. Of course, other CBFS users can use
* whatever values they want, as long as they understand them.
*/
#define CBFS_COMPRESS_NONE 0
#define CBFS_COMPRESS_LZMA 1
#define CBFS_COMPRESS_LZ4 2
/*
* Depending on how the header was initialized, it may be backed with 0x00 or
* 0xff, so support both
*/
#define CBFS_FILE_ATTR_TAG_UNUSED 0
#define CBFS_FILE_ATTR_TAG_UNUSED2 0xffffffff
#define CBFS_FILE_ATTR_TAG_COMPRESSION 0x42435a4c
#define CBFS_FILE_ATTR_TAG_HASH 0x68736148
/*
* The common fields of extended cbfs file attributes. Attributes are expected
* to start with tag/len, then append their specific fields
*/
struct cbfs_file_attribute {
u32 tag;
/* len covers the whole structure, incl. tag and len */
u32 len;
u8 data[0];
} __packed;
struct cbfs_file_attr_compression {
u32 tag;
u32 len;
/* whole file compression format. 0 if no compression. */
u32 compression;
u32 decompressed_size;
} __packed;
struct cbfs_file_attr_hash {
u32 tag;
u32 len;
u32 hash_type;
/* hash_data is len - sizeof(struct) bytes */
u8 hash_data[];
} __packed;
/*** Component sub-headers ***/
/* Following are component sub-headers for the "standard" component types */
/**
* struct cbfs_stage - sub-header for stage components
*
* Stages are loaded by coreboot during the normal boot process
*/
struct cbfs_stage {
u32 compression; /** Compression type */
u64 entry; /** entry point */
u64 load; /** Where to load in memory */
u32 len; /** length of data to load */
u32 memlen; /** total length of object in memory */
} __packed;
/**
* struct cbfs_payload_segment - sub-header for payload components
*
* Payloads are loaded by coreboot at the end of the boot process
*/
struct cbfs_payload_segment {
u32 type;
u32 compression;
u32 offset;
u64 load_addr;
u32 len;
u32 mem_len;
} __packed;
struct cbfs_payload {
struct cbfs_payload_segment segments;
};
#define PAYLOAD_SEGMENT_CODE 0x45444F43
#define PAYLOAD_SEGMENT_DATA 0x41544144
#define PAYLOAD_SEGMENT_BSS 0x20535342
#define PAYLOAD_SEGMENT_PARAMS 0x41524150
#define PAYLOAD_SEGMENT_ENTRY 0x52544E45
struct cbfs_cachenode {
struct cbfs_cachenode *next;
void *data;
char *name;
u32 type;
u32 data_length;
u32 name_length;
u32 attr_offset;
u32 comp_algo;
u32 decomp_size;
};
/**
* file_cbfs_error() - Return a string describing the most recent error
* condition.
*
* Return: A pointer to the constant string.
*/
const char *file_cbfs_error(void);
/**
* cbfs_get_result() - Get the result of the last CBFS operation
*
*Return: last result
*/
enum cbfs_result cbfs_get_result(void);
/**
* file_cbfs_init() - Initialize the CBFS driver and load metadata into RAM.
*
* @end_of_rom: Points to the end of the ROM the CBFS should be read from
* Return: 0 if OK, -ve on error
*/
int file_cbfs_init(ulong end_of_rom);
/**
* file_cbfs_get_header() - Get the header structure for the current CBFS.
*
* Return: A pointer to the constant structure, or NULL if there is none.
*/
const struct cbfs_header *file_cbfs_get_header(void);
/**
* cbfs_get_first() - Get the first file in a CBFS
*
* Return: pointer to first file, or NULL if it is empty
*/
const struct cbfs_cachenode *cbfs_get_first(const struct cbfs_priv *priv);
/**
* cbfs_get_next() - Get the next file in a CBFS
*
* @filep: Pointer to current file; updated to point to the next file, if any,
* else NULL
*/
void cbfs_get_next(const struct cbfs_cachenode **filep);
/**
* file_cbfs_get_first() - Get a handle for the first file in CBFS.
*
* Return: A handle for the first file in CBFS, NULL on error.
*/
const struct cbfs_cachenode *file_cbfs_get_first(void);
/**
* file_cbfs_get_next() - Get a handle to the file after this one in CBFS.
*
* @file: A pointer to the handle to advance.
*/
void file_cbfs_get_next(const struct cbfs_cachenode **file);
/**
* file_cbfs_find() - Find a file with a particular name in CBFS.
*
* @name: The name to search for.
*
* Return: A handle to the file, or NULL on error.
*/
const struct cbfs_cachenode *file_cbfs_find(const char *name);
/**
* cbfs_find_file() - Find a file in a given CBFS
*
* @cbfs: CBFS to look in (use cbfs_init_mem() to set it up)
* @name: Filename to look for
* Return: pointer to CBFS node if found, else NULL
*/
const struct cbfs_cachenode *cbfs_find_file(struct cbfs_priv *cbfs,
const char *name);
/**
* cbfs_init_mem() - Set up a new CBFS
*
* @base: Base address of CBFS
* @size: Size of CBFS if known, else CBFS_SIZE_UNKNOWN
* @require_header: true to read a header at the start, false to not require one
* @cbfsp: Returns a pointer to CBFS on success
* Return: 0 if OK, -ve on error
*/
int cbfs_init_mem(ulong base, ulong size, bool require_hdr,
struct cbfs_priv **privp);
/***************************************************************************/
/* All of the functions below can be used without first initializing CBFS. */
/***************************************************************************/
/**
* file_cbfs_find_uncached() - Find a file in CBFS given the end of the ROM
*
* Note that @node should be declared by the caller. This design is to avoid
* the need for allocation here.
*
* @end_of_rom: Points to the end of the ROM the CBFS should be read from
* @name: The name to search for
* @node: Returns the contents of the node if found (i.e. copied into *node)
* Return: 0 on success, -ENOENT if not found, -EFAULT on bad header
*/
int file_cbfs_find_uncached(ulong end_of_rom, const char *name,
struct cbfs_cachenode *node);
/**
* file_cbfs_find_uncached_base() - Find a file in CBFS given the base address
*
* Note that @node should be declared by the caller. This design is to avoid
* the need for allocation here.
*
* @base: Points to the base of the CBFS
* @name: The name to search for
* @node: Returns the contents of the node if found (i.e. copied into *node)
* Return: 0 on success, -ENOENT if not found, -EFAULT on bad header
*/
int file_cbfs_find_uncached_base(ulong base, const char *name,
struct cbfs_cachenode *node);
/**
* file_cbfs_name() - Get the name of a file in CBFS.
*
* @file: The handle to the file.
*
* Return: The name of the file, NULL on error.
*/
const char *file_cbfs_name(const struct cbfs_cachenode *file);
/**
* file_cbfs_size() - Get the size of a file in CBFS.
*
* @file: The handle to the file.
*
* Return: The size of the file, zero on error.
*/
u32 file_cbfs_size(const struct cbfs_cachenode *file);
/**
* file_cbfs_type() - Get the type of a file in CBFS.
*
* @file: The handle to the file.
*
* Return: The type of the file, zero on error.
*/
u32 file_cbfs_type(const struct cbfs_cachenode *file);
/**
* file_cbfs_read() - Read a file from CBFS into RAM
*
* @file: A handle to the file to read.
* @buffer: Where to read it into memory.
* @maxsize: Maximum number of bytes to read
*
* Return: If positive or zero, the number of characters read. If negative, an
* error occurred.
*/
long file_cbfs_read(const struct cbfs_cachenode *file, void *buffer,
unsigned long maxsize);
#endif /* __CBFS_H */
+142
View File
@@ -0,0 +1,142 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* Copyright 2023 Google LLC
* Written by Simon Glass <sjg@chromium.org>
*/
#ifndef __CEDIT_H
#define __CEDIT_H
#include <stdbool.h>
#include <dm/ofnode_decl.h>
#include <linux/types.h>
struct abuf;
struct expo;
struct expo_action;
struct scene;
struct udevice;
struct video_priv;
struct udevice;
enum {
/* size increment for writing FDT */
CEDIT_SIZE_INC = 1024,
};
/* Name of the cedit node in the devicetree */
#define CEDIT_NODE_NAME "cedit-values"
extern struct expo *cur_exp;
/**
* cedit_arange() - Arrange objects in a configuration-editor scene
*
* @exp: Expo to update
* @vid_priv: Private info of the video device
* @scene_id: scene ID to arrange
* Returns: 0 if OK, -ve on error
*/
int cedit_arange(struct expo *exp, struct video_priv *vid_priv, uint scene_id);
/**
* cedit_run() - Run a configuration editor
*
* This accepts input until the user quits with Escape
*
* @exp: Expo to use
* Returns: 0 if OK, -ve on error
*/
int cedit_run(struct expo *exp);
/**
* cedit_prepare() - Prepare to run a cedit
*
* Set up the video device, select the first scene and highlight the first item.
* This ensures that all menus have a selected item.
*
* @exp: Expo to use
* @dev: Video device to use
* @scnp: Set to the first scene
* Return: scene ID of first scene if OK, -ve on error
*/
int cedit_prepare(struct expo *exp, struct udevice *vid_dev,
struct scene **scnp);
/**
* cedit_do_action() - Process an action on a cedit
*
* @exp: Expo to use
* @scn: Current scene
* @vid_priv: Private data for the video device
* @act: Action to process
* Return: 0 on success, -EAGAIN if there was no action taken
*/
int cedit_do_action(struct expo *exp, struct scene *scn,
struct video_priv *vid_priv, struct expo_action *act);
/**
* cedit_write_settings() - Write settings in FDT format
*
* Sets up an FDT with the settings
*
* @exp: Expo to write settings from
* @buf: Returns abuf containing the settings FDT (inited by this function)
* Return: 0 if OK, -ve on error
*/
int cedit_write_settings(struct expo *exp, struct abuf *buf);
/**
* cedit_read_settings() - Read settings in FDT format
*
* Read an FDT with the settings
*
* @exp: Expo to read settings into
* @tree: Tree to read from
* Return: 0 if OK, -ve on error
*/
int cedit_read_settings(struct expo *exp, oftree tree);
/**
* cedit_write_settings_env() - Write settings to envrionment variables
*
* @exp: Expo to write settings from
* @verbose: true to print each var as it is set
* Return: 0 if OK, -ve on error
*/
int cedit_write_settings_env(struct expo *exp, bool verbose);
/*
* cedit_read_settings_env() - Read settings from the environment
*
* @exp: Expo to read settings into
* @verbose: true to print each var before it is read
*/
int cedit_read_settings_env(struct expo *exp, bool verbose);
/**
* cedit_write_settings_cmos() - Write settings to CMOS RAM
*
* Write settings to the defined places in CMOS RAM
*
* @exp: Expo to write settings from
* @dev: UCLASS_RTC device containing space for this information
* Returns 0 if OK, -ve on error
* @verbose: true to print a summary at the end
*/
int cedit_write_settings_cmos(struct expo *exp, struct udevice *dev,
bool verbose);
/**
* cedit_read_settings_cmos() - Read settings from CMOS RAM
*
* Read settings from the defined places in CMO RAM
*
* @exp: Expo to read settings into
* @dev: RTC device to read settings from
* @verbose: true to print a summary at the end
*/
int cedit_read_settings_cmos(struct expo *exp, struct udevice *dev,
bool verbose);
#endif /* __CEDIT_H */
+345
View File
@@ -0,0 +1,345 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* charset conversion utils
*
* Copyright (c) 2017 Rob Clark
*/
#ifndef __CHARSET_H_
#define __CHARSET_H_
#include <linux/kernel.h>
#include <linux/types.h>
#define MAX_UTF8_PER_UTF16 3
/*
* codepage_437 - Unicode to codepage 437 translation table
*/
extern const u16 codepage_437[160];
/**
* console_read_unicode() - read Unicode code point from console
*
* @code: pointer to store Unicode code point
* Return: 0 = success
*/
int console_read_unicode(s32 *code);
/**
* utf8_get() - get next UTF-8 code point from buffer
*
* @src: pointer to current byte, updated to point to next byte
* Return: code point, or 0 for end of string, or -1 if no legal
* code point is found. In case of an error src points to
* the incorrect byte.
*/
s32 utf8_get(const char **src);
/**
* utf8_put() - write UTF-8 code point to buffer
*
* @code: code point
* @dst: pointer to destination buffer, updated to next position
* Return: -1 if the input parameters are invalid
*/
int utf8_put(s32 code, char **dst);
/**
* utf8_utf16_strnlen() - length of a truncated utf-8 string after conversion
* to utf-16
*
* @src: utf-8 string
* @count: maximum number of code points to convert
* Return: length in u16 after conversion to utf-16 without the
* trailing \0. If an invalid UTF-8 sequence is hit one
* u16 will be reserved for a replacement character.
*/
size_t utf8_utf16_strnlen(const char *src, size_t count);
/**
* utf8_utf16_strlen() - length of a utf-8 string after conversion to utf-16
*
* @a: utf-8 string
* Return: length in u16 after conversion to utf-16 without the
* trailing \0. If an invalid UTF-8 sequence is hit one
* u16 will be reserved for a replacement character.
*/
#define utf8_utf16_strlen(a) utf8_utf16_strnlen((a), SIZE_MAX)
/**
* utf8_utf16_strncpy() - copy utf-8 string to utf-16 string
*
* @dst: destination buffer
* @src: source buffer
* @count: maximum number of code points to copy
* Return: -1 if the input parameters are invalid
*/
int utf8_utf16_strncpy(u16 **dst, const char *src, size_t count);
/**
* utf8_utf16_strcpy() - copy utf-8 string to utf-16 string
*
* @d: destination buffer
* @s: source buffer
* Return: -1 if the input parameters are invalid
*/
#define utf8_utf16_strcpy(d, s) utf8_utf16_strncpy((d), (s), SIZE_MAX)
/**
* utf16_get() - get next UTF-16 code point from buffer
*
* @src: pointer to current word, updated to point to next word
* Return: code point, or 0 for end of string, or -1 if no legal
* code point is found. In case of an error src points to
* the incorrect word.
*/
s32 utf16_get(const u16 **src);
/**
* utf16_put() - write UTF-16 code point to buffer
*
* @code: code point
* @dst: pointer to destination buffer, updated to next position
* Return: -1 if the input parameters are invalid
*/
int utf16_put(s32 code, u16 **dst);
/**
* utf16_strnlen() - length of a truncated utf-16 string
*
* @src: utf-16 string
* @count: maximum number of code points to convert
* Return: length in code points. If an invalid UTF-16 sequence is
* hit one position will be reserved for a replacement
* character.
*/
size_t utf16_strnlen(const u16 *src, size_t count);
/**
* utf16_utf8_strnlen() - length of a truncated utf-16 string after conversion
* to utf-8
*
* @src: utf-16 string
* @count: maximum number of code points to convert
* Return: length in bytes after conversion to utf-8 without the
* trailing \0. If an invalid UTF-16 sequence is hit one
* byte will be reserved for a replacement character.
*/
size_t utf16_utf8_strnlen(const u16 *src, size_t count);
/**
* utf16_utf8_strlen() - length of a utf-16 string after conversion to utf-8
*
* @a: utf-16 string
* Return: length in bytes after conversion to utf-8 without the
* trailing \0. If an invalid UTF-16 sequence is hit one
* byte will be reserved for a replacement character.
*/
#define utf16_utf8_strlen(a) utf16_utf8_strnlen((a), SIZE_MAX)
/**
* utf16_utf8_strncpy() - copy utf-16 string to utf-8 string
*
* @dst: destination buffer
* @src: source buffer
* @count: maximum number of code points to copy
* Return: -1 if the input parameters are invalid
*/
int utf16_utf8_strncpy(char **dst, const u16 *src, size_t count);
/**
* utf16_utf8_strcpy() - copy utf-16 string to utf-8 string
*
* @d: destination buffer
* @s: source buffer
* Return: -1 if the input parameters are invalid
*/
#define utf16_utf8_strcpy(d, s) utf16_utf8_strncpy((d), (s), SIZE_MAX)
/**
* utf_to_lower() - convert a Unicode letter to lower case
*
* @code: letter to convert
* Return: lower case letter or unchanged letter
*/
s32 utf_to_lower(const s32 code);
/**
* utf_to_upper() - convert a Unicode letter to upper case
*
* @code: letter to convert
* Return: upper case letter or unchanged letter
*/
s32 utf_to_upper(const s32 code);
/**
* u16_strcasecmp() - compare two u16 strings case insensitively
*
* @s1: first string to compare
* @s2: second string to compare
* Return: 0 if the first n u16 are the same in s1 and s2
* < 0 if the first different u16 in s1 is less than the
* corresponding u16 in s2
* > 0 if the first different u16 in s1 is greater than the
*/
int u16_strcasecmp(const u16 *s1, const u16 *s2);
/**
* u16_strncmp() - compare two u16 string
*
* @s1: first string to compare
* @s2: second string to compare
* @n: maximum number of u16 to compare
* Return: 0 if the first n u16 are the same in s1 and s2
* < 0 if the first different u16 in s1 is less than the
* corresponding u16 in s2
* > 0 if the first different u16 in s1 is greater than the
* corresponding u16 in s2
*/
int u16_strncmp(const u16 *s1, const u16 *s2, size_t n);
/**
* u16_strcmp() - compare two u16 string
*
* @s1: first string to compare
* @s2: second string to compare
* Return: 0 if the first n u16 are the same in s1 and s2
* < 0 if the first different u16 in s1 is less than the
* corresponding u16 in s2
* > 0 if the first different u16 in s1 is greater than the
* corresponding u16 in s2
*/
#define u16_strcmp(s1, s2) u16_strncmp((s1), (s2), SIZE_MAX)
/**
* u16_strsize() - count size of u16 string in bytes including the null
* character
*
* Counts the number of bytes occupied by a u16 string
*
* @in: null terminated u16 string
* Return: bytes in a u16 string
*/
size_t u16_strsize(const void *in);
/**
* u16_strnlen() - count non-zero words
*
* This function matches wscnlen_s() if the -fshort-wchar compiler flag is set.
* In the EFI context we explicitly need a function handling u16 strings.
*
* @in: null terminated u16 string
* @count: maximum number of words to count
* Return: number of non-zero words.
* This is not the number of utf-16 letters!
*/
size_t u16_strnlen(const u16 *in, size_t count);
/**
* u16_strlen - count non-zero words
*
* This function matches wsclen() if the -fshort-wchar compiler flag is set.
* In the EFI context we explicitly need a function handling u16 strings.
*
* @in: null terminated u16 string
* Return: number of non-zero words.
* This is not the number of utf-16 letters!
*/
size_t u16_strlen(const void *in);
#define u16_strlen(in) u16_strnlen(in, SIZE_MAX)
/**
* u16_strcpy() - copy u16 string
*
* Copy u16 string pointed to by src, including terminating null word, to
* the buffer pointed to by dest.
*
* @dest: destination buffer
* @src: source buffer (null terminated)
* Return: 'dest' address
*/
u16 *u16_strcpy(u16 *dest, const u16 *src);
/**
* u16_strdup() - duplicate u16 string
*
* Copy u16 string pointed to by src, including terminating null word, to a
* newly allocated buffer.
*
* @src: source buffer (null terminated)
* Return: allocated new buffer on success, NULL on failure
*/
u16 *u16_strdup(const void *src);
/**
* u16_strlcat() - Append a length-limited, %NUL-terminated string to another
*
* Append the source string @src to the destination string @dest, overwriting
* null word at the end of @dest adding a terminating null word.
*
* @dest: zero terminated u16 destination string
* @src: zero terminated u16 source string
* @count: size of buffer in u16 words including taling 0x0000
* Return: required size including trailing 0x0000 in u16 words
* If return value >= count, truncation occurred.
*/
size_t u16_strlcat(u16 *dest, const u16 *src, size_t count);
/**
* utf16_to_utf8() - Convert an utf16 string to utf8
*
* Converts 'size' characters of the utf16 string 'src' to utf8
* written to the 'dest' buffer.
*
* NOTE that a single utf16 character can generate up to 3 utf8
* characters. See MAX_UTF8_PER_UTF16.
*
* @dest: the destination buffer to write the utf8 characters
* @src: the source utf16 string
* @size: the number of utf16 characters to convert
* Return: the pointer to the first unwritten byte in 'dest'
*/
uint8_t *utf16_to_utf8(uint8_t *dest, const uint16_t *src, size_t size);
/**
* utf_to_cp() - translate Unicode code point to 8bit codepage
*
* Codepoints that do not exist in the codepage are rendered as question mark.
*
* @c: pointer to Unicode code point to be translated
* @codepage: Unicode to codepage translation table
* Return: 0 on success, -ENOENT if codepoint cannot be translated
*/
int utf_to_cp(s32 *c, const u16 *codepage);
/**
* utf8_to_cp437_stream() - convert UTF-8 stream to codepage 437
*
* @c: next UTF-8 character to convert
* @buffer: buffer, at least 5 characters
* Return: next codepage 437 character or 0
*/
int utf8_to_cp437_stream(u8 c, char *buffer);
/**
* utf8_to_utf32_stream() - convert UTF-8 byte stream to Unicode code points
*
* The function is called for each byte @c in a UTF-8 stream. The byte is
* appended to the temporary storage @buffer until the UTF-8 stream in
* @buffer describes a Unicode code point.
*
* When a new code point has been decoded it is returned and buffer[0] is
* set to '\0', otherwise the return value is 0.
*
* The buffer must be at least 5 characters long. Before the first function
* invocation buffer[0] must be set to '\0'."
*
* @c: next UTF-8 character to convert
* @buffer: buffer, at least 5 characters
* Return: Unicode code point or 0
*/
int utf8_to_utf32_stream(u8 c, char *buffer);
#endif /* __CHARSET_H_ */
+26
View File
@@ -0,0 +1,26 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2003
* Gerry Hamel, geh@ti.com, Texas Instruments
*/
#ifndef __CIRCBUF_H__
#define __CIRCBUF_H__
typedef struct circbuf {
unsigned int size; /* current number of bytes held */
unsigned int totalsize; /* number of bytes allocated */
char *top; /* pointer to current buffer start */
char *tail; /* pointer to space for next element */
char *data; /* all data */
char *end; /* end of data buffer */
} circbuf_t;
int buf_init (circbuf_t * buf, unsigned int size);
int buf_free (circbuf_t * buf);
int buf_pop (circbuf_t * buf, char *dest, unsigned int len);
int buf_push (circbuf_t * buf, const char *src, unsigned int len);
#endif
+285
View File
@@ -0,0 +1,285 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2014 Google, Inc
* Simon Glass <sjg@chromium.org>
*/
#ifndef __CLI_H
#define __CLI_H
#include <stdbool.h>
#include <linux/types.h>
/**
* struct cli_ch_state - state information for reading cmdline characters
*
* @esc_len: Number of escape characters read so far
* @esc_save: Escape characters collected so far
* @emit_upto: Next index to emit from esc_save
* @emitting: true if emitting from esc_save
* @shortcut_key: Selected shortcut option index
*/
struct cli_ch_state {
int esc_len;
char esc_save[8];
int emit_upto;
bool emitting;
int shortcut_key;
};
/**
* struct cli_line_state - state of the line editor
*
* @num: Current cursor position, where 0 is the start
* @eol_num: Number of characters in the buffer
* @insert: true if in 'insert' mode
* @history: true if history should be accessible
* @cmd_complete: true if tab completion should be enabled (requires @prompt to
* be set)
* @buf: Buffer containing line
* @prompt: Prompt for the line
*/
struct cli_line_state {
uint num;
uint eol_num;
uint len;
bool insert;
bool history;
bool cmd_complete;
char *buf;
const char *prompt;
};
/**
* Go into the command loop
*
* This will return if we get a timeout waiting for a command. See
* CONFIG_BOOT_RETRY_TIME.
*/
void cli_simple_loop(void);
/**
* cli_simple_run_command() - Execute a command with the simple CLI
*
* @cmd: String containing the command to execute
* @flag Flag value - see CMD_FLAG_...
* Return: 1 - command executed, repeatable
* 0 - command executed but not repeatable, interrupted commands are
* always considered not repeatable
* -1 - not executed (unrecognized, bootd recursion or too many args)
* (If cmd is NULL or "" or longer than CONFIG_SYS_CBSIZE-1 it is
* considered unrecognized)
*/
int cli_simple_run_command(const char *cmd, int flag);
/**
* cli_simple_process_macros() - Expand $() and ${} format env. variables
*
* @param input Input string possible containing $() / ${} vars
* @param output Output string with $() / ${} vars expanded
* @param max_size Maximum size of @output (including terminator)
* Return: 0 if OK, -ENOSPC if we ran out of space in @output
*/
int cli_simple_process_macros(const char *input, char *output, int max_size);
/**
* cli_simple_run_command_list() - Execute a list of command
*
* The commands should be separated by ; or \n and will be executed
* by the built-in parser.
*
* This function cannot take a const char * for the command, since if it
* finds newlines in the string, it replaces them with \0.
*
* @param cmd String containing list of commands
* @param flag Execution flags (CMD_FLAG_...)
* Return: 0 on success, or != 0 on error.
*/
int cli_simple_run_command_list(char *cmd, int flag);
/**
* cli_readline() - read a line into the console_buffer
*
* This is a convenience function which calls cli_readline_into_buffer().
*
* @prompt: Prompt to display
* Return: command line length excluding terminator, or -ve on error
*/
int cli_readline(const char *const prompt);
/**
* readline_into_buffer() - read a line into a buffer
*
* Display the prompt, then read a command line into @buffer. The
* maximum line length is CONFIG_SYS_CBSIZE including a \0 terminator, which
* will always be added.
*
* The command is echoed as it is typed. Command editing is supported if
* CONFIG_CMDLINE_EDITING is defined. Tab auto-complete is supported if
* CONFIG_AUTO_COMPLETE is defined. If CONFIG_BOOT_RETRY_TIME is defined,
* then a timeout will be applied.
*
* If CONFIG_BOOT_RETRY_TIME is defined and retry_time >= 0,
* time out when time goes past endtime (timebase time in ticks).
*
* @prompt: Prompt to display
* @buffer: Place to put the line that is entered
* @timeout: Timeout in seconds, 0 if none
* Return: command line length excluding terminator, or -ve on error: if the
* timeout is exceeded (either CONFIG_BOOT_RETRY_TIME or the timeout
* parameter), then -2 is returned. If a break is detected (Ctrl-C) then
* -1 is returned.
*/
int cli_readline_into_buffer(const char *const prompt, char *buffer,
int timeout);
/**
* parse_line() - split a command line down into separate arguments
*
* The argv[] array is filled with pointers into @line, and each argument
* is terminated by \0 (i.e. @line is changed in the process unless there
* is only one argument).
*
* #argv is terminated by a NULL after the last argument pointer.
*
* At most CONFIG_SYS_MAXARGS arguments are permited - if there are more
* than that then an error is printed, and this function returns
* CONFIG_SYS_MAXARGS, with argv[] set up to that point.
*
* @line: Command line to parse
* @args: Array to hold arguments
* Return: number of arguments
*/
int cli_simple_parse_line(char *line, char *argv[]);
#if CONFIG_IS_ENABLED(OF_CONTROL)
/**
* cli_process_fdt() - process the boot command from the FDT
*
* If bootcmmd is defined in the /config node of the FDT, we use that
* as the boot command. Further, if bootsecure is set to 1 (in the same
* node) then we return true, indicating that the command should be executed
* as securely as possible, avoiding the CLI parser.
*
* @cmdp: On entry, the command that will be executed if the FDT does
* not have a command. Returns the command to execute after
* checking the FDT.
* Return: true to execute securely, else false
*/
bool cli_process_fdt(const char **cmdp);
/** cli_secure_boot_cmd() - execute a command as securely as possible
*
* This avoids using the parser, thus executing the command with the
* smallest amount of code. Parameters are not supported.
*/
void cli_secure_boot_cmd(const char *cmd);
#else
static inline bool cli_process_fdt(const char **cmdp)
{
return false;
}
static inline void cli_secure_boot_cmd(const char *cmd)
{
}
#endif /* CONFIG_OF_CONTROL */
/**
* Go into the command loop
*
* This will return if we get a timeout waiting for a command, but only for
* the simple parser (not hush). See CONFIG_BOOT_RETRY_TIME.
*/
void cli_loop(void);
/** Set up the command line interpreter ready for action */
void cli_init(void);
#define endtick(seconds) (get_ticks() + (uint64_t)(seconds) * get_tbclk())
#define CTL_CH(c) ((c) - 'a' + 1)
/**
* cli_ch_init() - Set up the initial state to process input characters
*
* @cch: State to set up
*/
void cli_ch_init(struct cli_ch_state *cch);
/**
* cli_ch_process() - Process an input character
*
* When @ichar is 0, this function returns any characters from an invalid escape
* sequence which are still pending in the buffer
*
* Otherwise it processes the input character. If it is an escape character,
* then an escape sequence is started and the function returns 0. If we are in
* the middle of an escape sequence, the character is processed and may result
* in returning 0 (if more characters are needed) or a valid character (if
* @ichar finishes the sequence).
*
* If @ichar is a valid character and there is no escape sequence in progress,
* then it is returned as is.
*
* If the Enter key is pressed, '\n' is returned.
*
* Usage should be like this::
*
* struct cli_ch_state cch;
*
* cli_ch_init(cch);
* do
* {
* int ichar, ch;
*
* ichar = cli_ch_process(cch, 0);
* if (!ichar) {
* ch = getchar();
* ichar = cli_ch_process(cch, ch);
* }
* (handle the ichar character)
* } while (!done)
*
* If tstc() is used to look for keypresses, this function can be called with
* @ichar set to -ETIMEDOUT if there is no character after 5-10ms. This allows
* the ambgiuity between the Escape key and the arrow keys (which generate an
* escape character followed by other characters) to be resolved.
*
* @cch: Current state
* @ichar: Input character to process, or 0 if none, or -ETIMEDOUT if no
* character has been received within a small number of milliseconds (this
* cancels any existing escape sequence and allows pressing the Escape key to
* work)
* Returns: Resulting input character after processing, 0 if none, '\e' if
* an existing escape sequence was cancelled
*/
int cli_ch_process(struct cli_ch_state *cch, int ichar);
/**
* cread_line_process_ch() - Process a character for line input
*
* @cls: CLI line state
* @ichar: Character to process
* Return: 0 if input is complete, with line in cls->buf, -EINTR if input was
* cancelled with Ctrl-C, -EAGAIN if more characters are needed
*/
int cread_line_process_ch(struct cli_line_state *cls, char ichar);
/**
* cli_cread_init() - Set up a new cread struct
*
* Sets up a new cread state, with history and cmd_complete set to false
*
* After calling this, you can use cread_line_process_ch() to process characters
* received from the user.
*
* @cls: CLI line state
* @buf: Text buffer containing the initial text
* @buf_size: Buffer size, including nul terminator
*/
void cli_cread_init(struct cli_line_state *cls, char *buf, uint buf_size);
/** cread_print_hist_list() - Print the command-line history list */
void cread_print_hist_list(void);
#endif

Some files were not shown because too many files have changed in this diff Show More