建立工程,成功创建两个虚拟串口
This commit is contained in:
71
source/OpenAMP/open-amp/lib/include/openamp/compiler.h
Normal file
71
source/OpenAMP/open-amp/lib/include/openamp/compiler.h
Normal file
@@ -0,0 +1,71 @@
|
||||
#ifndef _COMPILER_H_
|
||||
#define _COMPILER_H_
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014, Mentor Graphics Corporation
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**************************************************************************
|
||||
* FILE NAME
|
||||
*
|
||||
* compiler.h
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This file defines compiler-specific macros.
|
||||
*
|
||||
***************************************************************************/
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* IAR ARM build tools */
|
||||
#if defined(__ICCARM__)
|
||||
|
||||
#ifndef OPENAMP_PACKED_BEGIN
|
||||
#define OPENAMP_PACKED_BEGIN __packed
|
||||
#endif
|
||||
|
||||
#ifndef OPENAMP_PACKED_END
|
||||
#define OPENAMP_PACKED_END
|
||||
#endif
|
||||
|
||||
/* GNUC */
|
||||
#elif defined(__GNUC__)
|
||||
|
||||
#ifndef OPENAMP_PACKED_BEGIN
|
||||
#define OPENAMP_PACKED_BEGIN
|
||||
#endif
|
||||
|
||||
#ifndef OPENAMP_PACKED_END
|
||||
#define OPENAMP_PACKED_END __attribute__((__packed__))
|
||||
#endif
|
||||
|
||||
/* ARM GCC */
|
||||
#elif defined(__CC_ARM)
|
||||
|
||||
#ifndef OPENAMP_PACKED_BEGIN
|
||||
#define OPENAMP_PACKED_BEGIN _Pragma("pack(1U)")
|
||||
#endif
|
||||
|
||||
#ifndef OPENAMP_PACKED_END
|
||||
#define OPENAMP_PACKED_END _Pragma("pack()")
|
||||
#endif
|
||||
|
||||
#else
|
||||
/*
|
||||
* There is no default definition here to avoid wrong structures packing in case
|
||||
* of not supported compiler
|
||||
*/
|
||||
#error Please implement the structure packing macros for your compiler here!
|
||||
#endif
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _COMPILER_H_ */
|
||||
428
source/OpenAMP/open-amp/lib/include/openamp/elf_loader.h
Normal file
428
source/OpenAMP/open-amp/lib/include/openamp/elf_loader.h
Normal file
@@ -0,0 +1,428 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Mentor Graphics Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef ELF_LOADER_H_
|
||||
#define ELF_LOADER_H_
|
||||
|
||||
#include <openamp/remoteproc.h>
|
||||
#include <openamp/remoteproc_loader.h>
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* ELF32 base types - 32-bit. */
|
||||
typedef uint32_t Elf32_Addr;
|
||||
typedef uint16_t Elf32_Half;
|
||||
typedef uint32_t Elf32_Off;
|
||||
typedef int32_t Elf32_Sword;
|
||||
typedef uint32_t Elf32_Word;
|
||||
|
||||
/* ELF64 base types - 64-bit. */
|
||||
typedef uint64_t Elf64_Addr;
|
||||
typedef uint16_t Elf64_Half;
|
||||
typedef uint64_t Elf64_Off;
|
||||
typedef int32_t Elf64_Sword;
|
||||
typedef uint32_t Elf64_Word;
|
||||
typedef uint64_t Elf64_Xword;
|
||||
typedef int64_t Elf64_Sxword;
|
||||
|
||||
/* Size of ELF identifier field in the ELF file header. */
|
||||
#define EI_NIDENT 16
|
||||
|
||||
/* ELF32 file header */
|
||||
typedef struct {
|
||||
unsigned char e_ident[EI_NIDENT];
|
||||
Elf32_Half e_type;
|
||||
Elf32_Half e_machine;
|
||||
Elf32_Word e_version;
|
||||
Elf32_Addr e_entry;
|
||||
Elf32_Off e_phoff;
|
||||
Elf32_Off e_shoff;
|
||||
Elf32_Word e_flags;
|
||||
Elf32_Half e_ehsize;
|
||||
Elf32_Half e_phentsize;
|
||||
Elf32_Half e_phnum;
|
||||
Elf32_Half e_shentsize;
|
||||
Elf32_Half e_shnum;
|
||||
Elf32_Half e_shstrndx;
|
||||
} Elf32_Ehdr;
|
||||
|
||||
/* ELF64 file header */
|
||||
typedef struct {
|
||||
unsigned char e_ident[EI_NIDENT];
|
||||
Elf64_Half e_type;
|
||||
Elf64_Half e_machine;
|
||||
Elf64_Word e_version;
|
||||
Elf64_Addr e_entry;
|
||||
Elf64_Off e_phoff;
|
||||
Elf64_Off e_shoff;
|
||||
Elf64_Word e_flags;
|
||||
Elf64_Half e_ehsize;
|
||||
Elf64_Half e_phentsize;
|
||||
Elf64_Half e_phnum;
|
||||
Elf64_Half e_shentsize;
|
||||
Elf64_Half e_shnum;
|
||||
Elf64_Half e_shstrndx;
|
||||
} Elf64_Ehdr;
|
||||
|
||||
/* e_ident */
|
||||
#define ET_NONE 0
|
||||
#define ET_REL 1 /* Re-locatable file */
|
||||
#define ET_EXEC 2 /* Executable file */
|
||||
#define ET_DYN 3 /* Shared object file */
|
||||
#define ET_CORE 4 /* Core file */
|
||||
#define ET_LOOS 0xfe00 /* Operating system-specific */
|
||||
#define ET_HIOS 0xfeff /* Operating system-specific */
|
||||
#define ET_LOPROC 0xff00 /* remote_proc-specific */
|
||||
#define ET_HIPROC 0xffff /* remote_proc-specific */
|
||||
|
||||
/* e_machine */
|
||||
#define EM_ARM 40 /* ARM/Thumb Architecture */
|
||||
|
||||
/* e_version */
|
||||
#define EV_CURRENT 1 /* Current version */
|
||||
|
||||
/* e_ident[] Identification Indexes */
|
||||
#define EI_MAG0 0 /* File identification */
|
||||
#define EI_MAG1 1 /* File identification */
|
||||
#define EI_MAG2 2 /* File identification */
|
||||
#define EI_MAG3 3 /* File identification */
|
||||
#define EI_CLASS 4 /* File class */
|
||||
#define EI_DATA 5 /* Data encoding */
|
||||
#define EI_VERSION 6 /* File version */
|
||||
#define EI_OSABI 7 /* Operating system/ABI identification */
|
||||
#define EI_ABIVERSION 8 /* ABI version */
|
||||
#define EI_PAD 9 /* Start of padding bytes */
|
||||
#define EI_NIDENT 16 /* Size of e_ident[] */
|
||||
|
||||
/*
|
||||
* EI_MAG0 to EI_MAG3 - A file's first 4 bytes hold amagic number, identifying
|
||||
* the file as an ELF object file
|
||||
*/
|
||||
#define ELFMAG0 0x7f /* e_ident[EI_MAG0] */
|
||||
#define ELFMAG1 'E' /* e_ident[EI_MAG1] */
|
||||
#define ELFMAG2 'L' /* e_ident[EI_MAG2] */
|
||||
#define ELFMAG3 'F' /* e_ident[EI_MAG3] */
|
||||
#define ELFMAG "\177ELF"
|
||||
#define SELFMAG 4
|
||||
|
||||
/*
|
||||
* EI_CLASS - The next byte, e_ident[EI_CLASS], identifies the file's class, or
|
||||
* capacity.
|
||||
*/
|
||||
#define ELFCLASSNONE 0 /* Invalid class */
|
||||
#define ELFCLASS32 1 /* 32-bit objects */
|
||||
#define ELFCLASS64 2 /* 64-bit objects */
|
||||
|
||||
/*
|
||||
* EI_DATA - Byte e_ident[EI_DATA] specifies the data encoding of the
|
||||
* remote_proc-specific data in the object file. The following encodings are
|
||||
* currently defined.
|
||||
*/
|
||||
#define ELFDATANONE 0 /* Invalid data encoding */
|
||||
#define ELFDATA2LSB 1 /* See Data encodings, below */
|
||||
#define ELFDATA2MSB 2 /* See Data encodings, below */
|
||||
|
||||
/* EI_OSABI - We do not define an OS specific ABI */
|
||||
#define ELFOSABI_NONE 0
|
||||
|
||||
/* ELF32 program header */
|
||||
typedef struct elf32_phdr{
|
||||
Elf32_Word p_type;
|
||||
Elf32_Off p_offset;
|
||||
Elf32_Addr p_vaddr;
|
||||
Elf32_Addr p_paddr;
|
||||
Elf32_Word p_filesz;
|
||||
Elf32_Word p_memsz;
|
||||
Elf32_Word p_flags;
|
||||
Elf32_Word p_align;
|
||||
} Elf32_Phdr;
|
||||
|
||||
/* ELF64 program header */
|
||||
typedef struct elf64_phdr {
|
||||
Elf64_Word p_type;
|
||||
Elf64_Word p_flags;
|
||||
Elf64_Off p_offset;
|
||||
Elf64_Addr p_vaddr;
|
||||
Elf64_Addr p_paddr;
|
||||
Elf64_Xword p_filesz;
|
||||
Elf64_Xword p_memsz;
|
||||
Elf64_Xword p_align;
|
||||
} Elf64_Phdr;
|
||||
|
||||
/* segment types */
|
||||
#define PT_NULL 0
|
||||
#define PT_LOAD 1
|
||||
#define PT_DYNAMIC 2
|
||||
#define PT_INTERP 3
|
||||
#define PT_NOTE 4
|
||||
#define PT_SHLIB 5
|
||||
#define PT_PHDR 6
|
||||
#define PT_TLS 7 /* Thread local storage segment */
|
||||
#define PT_LOOS 0x60000000 /* OS-specific */
|
||||
#define PT_HIOS 0x6fffffff /* OS-specific */
|
||||
#define PT_LOPROC 0x70000000
|
||||
#define PT_HIPROC 0x7fffffff
|
||||
|
||||
/* ELF32 section header. */
|
||||
typedef struct {
|
||||
Elf32_Word sh_name;
|
||||
Elf32_Word sh_type;
|
||||
Elf32_Word sh_flags;
|
||||
Elf32_Addr sh_addr;
|
||||
Elf32_Off sh_offset;
|
||||
Elf32_Word sh_size;
|
||||
Elf32_Word sh_link;
|
||||
Elf32_Word sh_info;
|
||||
Elf32_Word sh_addralign;
|
||||
Elf32_Word sh_entsize;
|
||||
} Elf32_Shdr;
|
||||
|
||||
/* ELF64 section header. */
|
||||
typedef struct {
|
||||
Elf64_Word sh_name;
|
||||
Elf64_Word sh_type;
|
||||
Elf64_Xword sh_flags;
|
||||
Elf64_Addr sh_addr;
|
||||
Elf64_Off sh_offset;
|
||||
Elf64_Xword sh_size;
|
||||
Elf64_Word sh_link;
|
||||
Elf64_Word sh_info;
|
||||
Elf64_Xword sh_addralign;
|
||||
Elf64_Xword sh_entsize;
|
||||
} Elf64_Shdr;
|
||||
|
||||
/* sh_type */
|
||||
#define SHT_NULL 0
|
||||
#define SHT_PROGBITS 1
|
||||
#define SHT_SYMTAB 2
|
||||
#define SHT_STRTAB 3
|
||||
#define SHT_RELA 4
|
||||
#define SHT_HASH 5
|
||||
#define SHT_DYNAMIC 6
|
||||
#define SHT_NOTE 7
|
||||
#define SHT_NOBITS 8
|
||||
#define SHT_REL 9
|
||||
#define SHT_SHLIB 10
|
||||
#define SHT_DYNSYM 11
|
||||
#define SHT_INIT_ARRAY 14
|
||||
#define SHT_FINI_ARRAY 15
|
||||
#define SHT_PREINIT_ARRAY 16
|
||||
#define SHT_GROUP 17
|
||||
#define SHT_SYMTAB_SHNDX 18
|
||||
#define SHT_LOOS 0x60000000
|
||||
#define SHT_HIOS 0x6fffffff
|
||||
#define SHT_LOPROC 0x70000000
|
||||
#define SHT_HIPROC 0x7fffffff
|
||||
#define SHT_LOUSER 0x80000000
|
||||
#define SHT_HIUSER 0xffffffff
|
||||
|
||||
/* sh_flags */
|
||||
#define SHF_WRITE 0x1
|
||||
#define SHF_ALLOC 0x2
|
||||
#define SHF_EXECINSTR 0x4
|
||||
#define SHF_MASKPROC 0xf0000000
|
||||
|
||||
/* Relocation entry (without addend) */
|
||||
typedef struct {
|
||||
Elf32_Addr r_offset;
|
||||
Elf32_Word r_info;
|
||||
|
||||
} Elf32_Rel;
|
||||
|
||||
typedef struct {
|
||||
Elf64_Addr r_offset;
|
||||
Elf64_Xword r_info;
|
||||
|
||||
} Elf64_Rel;
|
||||
|
||||
/* Relocation entry with addend */
|
||||
typedef struct {
|
||||
Elf32_Addr r_offset;
|
||||
Elf32_Word r_info;
|
||||
Elf32_Sword r_addend;
|
||||
|
||||
} Elf32_Rela;
|
||||
|
||||
typedef struct elf64_rela {
|
||||
Elf64_Addr r_offset;
|
||||
Elf64_Xword r_info;
|
||||
Elf64_Sxword r_addend;
|
||||
} Elf64_Rela;
|
||||
|
||||
/* Macros to extract information from 'r_info' field of relocation entries */
|
||||
#define ELF32_R_SYM(i) ((i) >> 8)
|
||||
#define ELF32_R_TYPE(i) ((unsigned char)(i))
|
||||
#define ELF64_R_SYM(i) ((i) >> 32)
|
||||
#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
|
||||
|
||||
/* Symbol table entry */
|
||||
typedef struct {
|
||||
Elf32_Word st_name;
|
||||
Elf32_Addr st_value;
|
||||
Elf32_Word st_size;
|
||||
unsigned char st_info;
|
||||
unsigned char st_other;
|
||||
Elf32_Half st_shndx;
|
||||
|
||||
} Elf32_Sym;
|
||||
|
||||
typedef struct elf64_sym {
|
||||
Elf64_Word st_name;
|
||||
unsigned char st_info;
|
||||
unsigned char st_other;
|
||||
Elf64_Half st_shndx;
|
||||
Elf64_Addr st_value;
|
||||
Elf64_Xword st_size;
|
||||
} Elf64_Sym;
|
||||
|
||||
/* ARM specific dynamic relocation codes */
|
||||
#define R_ARM_GLOB_DAT 21 /* 0x15 */
|
||||
#define R_ARM_JUMP_SLOT 22 /* 0x16 */
|
||||
#define R_ARM_RELATIVE 23 /* 0x17 */
|
||||
#define R_ARM_ABS32 2 /* 0x02 */
|
||||
|
||||
/* ELF decoding information */
|
||||
struct elf32_info {
|
||||
Elf32_Ehdr ehdr;
|
||||
unsigned int load_state;
|
||||
Elf32_Phdr *phdrs;
|
||||
Elf32_Shdr *shdrs;
|
||||
void *shstrtab;
|
||||
};
|
||||
|
||||
struct elf64_info {
|
||||
Elf64_Ehdr ehdr;
|
||||
unsigned int load_state;
|
||||
Elf64_Phdr *phdrs;
|
||||
Elf64_Shdr *shdrs;
|
||||
void *shstrtab;
|
||||
};
|
||||
|
||||
#define ELF_STATE_INIT 0x0UL
|
||||
#define ELF_STATE_WAIT_FOR_PHDRS 0x100UL
|
||||
#define ELF_STATE_WAIT_FOR_SHDRS 0x200UL
|
||||
#define ELF_STATE_WAIT_FOR_SHSTRTAB 0x400UL
|
||||
#define ELF_STATE_HDRS_COMPLETE 0x800UL
|
||||
#define ELF_STATE_MASK 0xFF00UL
|
||||
#define ELF_NEXT_SEGMENT_MASK 0x00FFUL
|
||||
|
||||
extern struct loader_ops elf_ops;
|
||||
|
||||
/**
|
||||
* elf_identify - check if it is an ELF file
|
||||
*
|
||||
* It will check if the input image header is an ELF header.
|
||||
*
|
||||
* @img_data: firmware private data which will be passed to user defined loader
|
||||
* operations
|
||||
* @len: firmware header length
|
||||
*
|
||||
* return 0 for success or negative value for failure.
|
||||
*/
|
||||
int elf_identify(const void *img_data, size_t len);
|
||||
|
||||
/**
|
||||
* elf_load_header - Load ELF headers
|
||||
*
|
||||
* It will get the ELF header, the program header, and the section header.
|
||||
*
|
||||
* @img_data: image data
|
||||
* @offset: input image data offset to the start of image file
|
||||
* @len: input image data length
|
||||
* @img_info: pointer to store image information data
|
||||
* @last_load_state: last state return by this function
|
||||
* @noffset: pointer to next offset required by loading ELF header
|
||||
* @nlen: pointer to next data length required by loading ELF header
|
||||
*
|
||||
* return ELF loading header state, or negative value for failure
|
||||
*/
|
||||
int elf_load_header(const void *img_data, size_t offset, size_t len,
|
||||
void **img_info, int last_load_state,
|
||||
size_t *noffset, size_t *nlen);
|
||||
|
||||
/**
|
||||
* elf_load - load ELF data
|
||||
*
|
||||
* It will parse the ELF image and return the target device address,
|
||||
* offset to the start of the ELF image of the data to load and the
|
||||
* length of the data to load.
|
||||
*
|
||||
* @rproc: pointer to remoteproc instance
|
||||
* @img_data: image data which will passed to the function.
|
||||
* it can be NULL, if image data doesn't need to be handled
|
||||
* by the load function. E.g. binary data which was
|
||||
* loaded to the target memory.
|
||||
* @offset: last loaded image data offset to the start of image file
|
||||
* @len: last loaded image data length
|
||||
* @img_info: pointer to store image information data
|
||||
* @last_load_state: the returned state of the last function call.
|
||||
* @da: target device address, if the data to load is not for target memory
|
||||
* the da will be set to ANY.
|
||||
* @noffset: pointer to next offset required by loading ELF header
|
||||
* @nlen: pointer to next data length required by loading ELF header
|
||||
* @padding: value to pad it is possible that a size of a segment in memory
|
||||
* is larger than what it is in the ELF image. e.g. a segment
|
||||
* can have stack section .bss. It doesn't need to copy image file
|
||||
* space, in this case, it will be packed with 0.
|
||||
* @nmemsize: pointer to next data target memory size. The size of a segment
|
||||
* in the target memory can be larger than the its size in the
|
||||
* image file.
|
||||
*
|
||||
* return 0 for success, otherwise negative value for failure
|
||||
*/
|
||||
int elf_load(struct remoteproc *rproc, const void *img_data,
|
||||
size_t offset, size_t len,
|
||||
void **img_info, int last_load_state,
|
||||
metal_phys_addr_t *da,
|
||||
size_t *noffset, size_t *nlen,
|
||||
unsigned char *padding, size_t *nmemsize);
|
||||
|
||||
/**
|
||||
* elf_release - Release ELF image information
|
||||
*
|
||||
* It will release ELF image information data.
|
||||
*
|
||||
* @img_info: pointer to ELF image information
|
||||
*/
|
||||
void elf_release(void *img_info);
|
||||
|
||||
/**
|
||||
* elf_get_entry - Get entry point
|
||||
*
|
||||
* It will return entry point specified in the ELF file.
|
||||
*
|
||||
* @img_info: pointer to ELF image information
|
||||
*
|
||||
* return entry address
|
||||
*/
|
||||
metal_phys_addr_t elf_get_entry(void *img_info);
|
||||
|
||||
/**
|
||||
* elf_locate_rsc_table - locate the resource table information
|
||||
*
|
||||
* It will return the length of the resource table, and the device address of
|
||||
* the resource table.
|
||||
*
|
||||
* @img_info: pointer to ELF image information
|
||||
* @da: pointer to the device address
|
||||
* @offset: pointer to the offset to in the ELF image of the resource
|
||||
* table section.
|
||||
* @size: pointer to the size of the resource table section.
|
||||
*
|
||||
* return 0 if successfully locate the resource table, negative value for
|
||||
* failure.
|
||||
*/
|
||||
int elf_locate_rsc_table(void *img_info, metal_phys_addr_t *da,
|
||||
size_t *offset, size_t *size);
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* ELF_LOADER_H_ */
|
||||
17
source/OpenAMP/open-amp/lib/include/openamp/open_amp.h
Normal file
17
source/OpenAMP/open-amp/lib/include/openamp/open_amp.h
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Mentor Graphics Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef OPEN_AMP_H_
|
||||
#define OPEN_AMP_H_
|
||||
|
||||
#include <openamp/rpmsg.h>
|
||||
#include <openamp/rpmsg_virtio.h>
|
||||
#include <openamp/remoteproc.h>
|
||||
#include <openamp/remoteproc_virtio.h>
|
||||
|
||||
|
||||
#endif /* OPEN_AMP_H_ */
|
||||
871
source/OpenAMP/open-amp/lib/include/openamp/remoteproc.h
Normal file
871
source/OpenAMP/open-amp/lib/include/openamp/remoteproc.h
Normal file
@@ -0,0 +1,871 @@
|
||||
/*
|
||||
* Remoteproc Framework
|
||||
*
|
||||
* Copyright(c) 2018 Xilinx Ltd.
|
||||
* Copyright(c) 2011 Texas Instruments, Inc.
|
||||
* Copyright(c) 2011 Google, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef REMOTEPROC_H
|
||||
#define REMOTEPROC_H
|
||||
|
||||
#include <metal/io.h>
|
||||
#include <metal/mutex.h>
|
||||
#include <openamp/compiler.h>
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define RSC_NOTIFY_ID_ANY 0xFFFFFFFFUL
|
||||
|
||||
/**
|
||||
* struct resource_table - firmware resource table header
|
||||
* @ver: version number
|
||||
* @num: number of resource entries
|
||||
* @reserved: reserved (must be zero)
|
||||
* @offset: array of offsets pointing at the various resource entries
|
||||
*
|
||||
* A resource table is essentially a list of system resources required
|
||||
* by the remote remote_proc. It may also include configuration entries.
|
||||
* If needed, the remote remote_proc firmware should contain this table
|
||||
* as a dedicated ".resource_table" ELF section.
|
||||
*
|
||||
* Some resources entries are mere announcements, where the host is informed
|
||||
* of specific remoteproc configuration. Other entries require the host to
|
||||
* do something (e.g. allocate a system resource). Sometimes a negotiation
|
||||
* is expected, where the firmware requests a resource, and once allocated,
|
||||
* the host should provide back its details (e.g. address of an allocated
|
||||
* memory region).
|
||||
*
|
||||
* The header of the resource table, as expressed by this structure,
|
||||
* contains a version number (should we need to change this format in the
|
||||
* future), the number of available resource entries, and their offsets
|
||||
* in the table.
|
||||
*
|
||||
* Immediately following this header are the resource entries themselves,
|
||||
* each of which begins with a resource entry header (as described below).
|
||||
*/
|
||||
OPENAMP_PACKED_BEGIN
|
||||
struct resource_table {
|
||||
uint32_t ver;
|
||||
uint32_t num;
|
||||
uint32_t reserved[2];
|
||||
uint32_t offset[0];
|
||||
} OPENAMP_PACKED_END;
|
||||
|
||||
/**
|
||||
* struct fw_rsc_hdr - firmware resource entry header
|
||||
* @type: resource type
|
||||
* @data: resource data
|
||||
*
|
||||
* Every resource entry begins with a 'struct fw_rsc_hdr' header providing
|
||||
* its @type. The content of the entry itself will immediately follow
|
||||
* this header, and it should be parsed according to the resource type.
|
||||
*/
|
||||
OPENAMP_PACKED_BEGIN
|
||||
struct fw_rsc_hdr {
|
||||
uint32_t type;
|
||||
uint8_t data[0];
|
||||
} OPENAMP_PACKED_END;
|
||||
|
||||
/**
|
||||
* enum fw_resource_type - types of resource entries
|
||||
*
|
||||
* @RSC_CARVEOUT: request for allocation of a physically contiguous
|
||||
* memory region.
|
||||
* @RSC_DEVMEM: request to iommu_map a memory-based peripheral.
|
||||
* @RSC_TRACE: announces the availability of a trace buffer into which
|
||||
* the remote remote_proc will be writing logs.
|
||||
* @RSC_VDEV: declare support for a virtio device, and serve as its
|
||||
* virtio header.
|
||||
* @RSC_VENDOR_START: start of the vendor specific resource types range
|
||||
* @RSC_VENDOR_END : end of the vendor specific resource types range
|
||||
* @RSC_LAST: just keep this one at the end
|
||||
*
|
||||
* For more details regarding a specific resource type, please see its
|
||||
* dedicated structure below.
|
||||
*
|
||||
* Please note that these values are used as indices to the rproc_handle_rsc
|
||||
* lookup table, so please keep them sane. Moreover, @RSC_LAST is used to
|
||||
* check the validity of an index before the lookup table is accessed, so
|
||||
* please update it as needed.
|
||||
*/
|
||||
enum fw_resource_type {
|
||||
RSC_CARVEOUT = 0,
|
||||
RSC_DEVMEM = 1,
|
||||
RSC_TRACE = 2,
|
||||
RSC_VDEV = 3,
|
||||
RSC_RPROC_MEM = 4,
|
||||
RSC_FW_CHKSUM = 5,
|
||||
RSC_LAST = 6,
|
||||
RSC_VENDOR_START = 128,
|
||||
RSC_VENDOR_END = 512,
|
||||
};
|
||||
|
||||
#define FW_RSC_ADDR_ANY (0xFFFFFFFFFFFFFFFF)
|
||||
#define FW_RSC_U32_ADDR_ANY (0xFFFFFFFF)
|
||||
|
||||
/**
|
||||
* struct fw_rsc_carveout - physically contiguous memory request
|
||||
* @da: device address
|
||||
* @pa: physical address
|
||||
* @len: length (in bytes)
|
||||
* @flags: iommu protection flags
|
||||
* @reserved: reserved (must be zero)
|
||||
* @name: human-readable name of the requested memory region
|
||||
*
|
||||
* This resource entry requests the host to allocate a physically contiguous
|
||||
* memory region.
|
||||
*
|
||||
* These request entries should precede other firmware resource entries,
|
||||
* as other entries might request placing other data objects inside
|
||||
* these memory regions (e.g. data/code segments, trace resource entries, ...).
|
||||
*
|
||||
* Allocating memory this way helps utilizing the reserved physical memory
|
||||
* (e.g. CMA) more efficiently, and also minimizes the number of TLB entries
|
||||
* needed to map it (in case @rproc is using an IOMMU). Reducing the TLB
|
||||
* pressure is important; it may have a substantial impact on performance.
|
||||
*
|
||||
* If the firmware is compiled with static addresses, then @da should specify
|
||||
* the expected device address of this memory region. If @da is set to
|
||||
* FW_RSC_ADDR_ANY, then the host will dynamically allocate it, and then
|
||||
* overwrite @da with the dynamically allocated address.
|
||||
*
|
||||
* We will always use @da to negotiate the device addresses, even if it
|
||||
* isn't using an iommu. In that case, though, it will obviously contain
|
||||
* physical addresses.
|
||||
*
|
||||
* Some remote remote_procs needs to know the allocated physical address
|
||||
* even if they do use an iommu. This is needed, e.g., if they control
|
||||
* hardware accelerators which access the physical memory directly (this
|
||||
* is the case with OMAP4 for instance). In that case, the host will
|
||||
* overwrite @pa with the dynamically allocated physical address.
|
||||
* Generally we don't want to expose physical addresses if we don't have to
|
||||
* (remote remote_procs are generally _not_ trusted), so we might want to
|
||||
* change this to happen _only_ when explicitly required by the hardware.
|
||||
*
|
||||
* @flags is used to provide IOMMU protection flags, and @name should
|
||||
* (optionally) contain a human readable name of this carveout region
|
||||
* (mainly for debugging purposes).
|
||||
*/
|
||||
OPENAMP_PACKED_BEGIN
|
||||
struct fw_rsc_carveout {
|
||||
uint32_t type;
|
||||
uint32_t da;
|
||||
uint32_t pa;
|
||||
uint32_t len;
|
||||
uint32_t flags;
|
||||
uint32_t reserved;
|
||||
uint8_t name[32];
|
||||
} OPENAMP_PACKED_END;
|
||||
|
||||
/**
|
||||
* struct fw_rsc_devmem - iommu mapping request
|
||||
* @da: device address
|
||||
* @pa: physical address
|
||||
* @len: length (in bytes)
|
||||
* @flags: iommu protection flags
|
||||
* @reserved: reserved (must be zero)
|
||||
* @name: human-readable name of the requested region to be mapped
|
||||
*
|
||||
* This resource entry requests the host to iommu map a physically contiguous
|
||||
* memory region. This is needed in case the remote remote_proc requires
|
||||
* access to certain memory-based peripherals; _never_ use it to access
|
||||
* regular memory.
|
||||
*
|
||||
* This is obviously only needed if the remote remote_proc is accessing memory
|
||||
* via an iommu.
|
||||
*
|
||||
* @da should specify the required device address, @pa should specify
|
||||
* the physical address we want to map, @len should specify the size of
|
||||
* the mapping and @flags is the IOMMU protection flags. As always, @name may
|
||||
* (optionally) contain a human readable name of this mapping (mainly for
|
||||
* debugging purposes).
|
||||
*
|
||||
* Note: at this point we just "trust" those devmem entries to contain valid
|
||||
* physical addresses, but this isn't safe and will be changed: eventually we
|
||||
* want remoteproc implementations to provide us ranges of physical addresses
|
||||
* the firmware is allowed to request, and not allow firmwares to request
|
||||
* access to physical addresses that are outside those ranges.
|
||||
*/
|
||||
OPENAMP_PACKED_BEGIN
|
||||
struct fw_rsc_devmem {
|
||||
uint32_t type;
|
||||
uint32_t da;
|
||||
uint32_t pa;
|
||||
uint32_t len;
|
||||
uint32_t flags;
|
||||
uint32_t reserved;
|
||||
uint8_t name[32];
|
||||
} OPENAMP_PACKED_END;
|
||||
|
||||
/**
|
||||
* struct fw_rsc_trace - trace buffer declaration
|
||||
* @da: device address
|
||||
* @len: length (in bytes)
|
||||
* @reserved: reserved (must be zero)
|
||||
* @name: human-readable name of the trace buffer
|
||||
*
|
||||
* This resource entry provides the host information about a trace buffer
|
||||
* into which the remote remote_proc will write log messages.
|
||||
*
|
||||
* @da specifies the device address of the buffer, @len specifies
|
||||
* its size, and @name may contain a human readable name of the trace buffer.
|
||||
*
|
||||
* After booting the remote remote_proc, the trace buffers are exposed to the
|
||||
* user via debugfs entries (called trace0, trace1, etc..).
|
||||
*/
|
||||
OPENAMP_PACKED_BEGIN
|
||||
struct fw_rsc_trace {
|
||||
uint32_t type;
|
||||
uint32_t da;
|
||||
uint32_t len;
|
||||
uint32_t reserved;
|
||||
uint8_t name[32];
|
||||
} OPENAMP_PACKED_END;
|
||||
|
||||
/**
|
||||
* struct fw_rsc_vdev_vring - vring descriptor entry
|
||||
* @da: device address
|
||||
* @align: the alignment between the consumer and producer parts of the vring
|
||||
* @num: num of buffers supported by this vring (must be power of two)
|
||||
* @notifyid is a unique rproc-wide notify index for this vring. This notify
|
||||
* index is used when kicking a remote remote_proc, to let it know that this
|
||||
* vring is triggered.
|
||||
* @reserved: reserved (must be zero)
|
||||
*
|
||||
* This descriptor is not a resource entry by itself; it is part of the
|
||||
* vdev resource type (see below).
|
||||
*
|
||||
* Note that @da should either contain the device address where
|
||||
* the remote remote_proc is expecting the vring, or indicate that
|
||||
* dynamically allocation of the vring's device address is supported.
|
||||
*/
|
||||
OPENAMP_PACKED_BEGIN
|
||||
struct fw_rsc_vdev_vring {
|
||||
uint32_t da;
|
||||
uint32_t align;
|
||||
uint32_t num;
|
||||
uint32_t notifyid;
|
||||
uint32_t reserved;
|
||||
} OPENAMP_PACKED_END;
|
||||
|
||||
/**
|
||||
* struct fw_rsc_vdev - virtio device header
|
||||
* @id: virtio device id (as in virtio_ids.h)
|
||||
* @notifyid is a unique rproc-wide notify index for this vdev. This notify
|
||||
* index is used when kicking a remote remote_proc, to let it know that the
|
||||
* status/features of this vdev have changes.
|
||||
* @dfeatures specifies the virtio device features supported by the firmware
|
||||
* @gfeatures is a place holder used by the host to write back the
|
||||
* negotiated features that are supported by both sides.
|
||||
* @config_len is the size of the virtio config space of this vdev. The config
|
||||
* space lies in the resource table immediate after this vdev header.
|
||||
* @status is a place holder where the host will indicate its virtio progress.
|
||||
* @num_of_vrings indicates how many vrings are described in this vdev header
|
||||
* @reserved: reserved (must be zero)
|
||||
* @vring is an array of @num_of_vrings entries of 'struct fw_rsc_vdev_vring'.
|
||||
*
|
||||
* This resource is a virtio device header: it provides information about
|
||||
* the vdev, and is then used by the host and its peer remote remote_procs
|
||||
* to negotiate and share certain virtio properties.
|
||||
*
|
||||
* By providing this resource entry, the firmware essentially asks remoteproc
|
||||
* to statically allocate a vdev upon registration of the rproc (dynamic vdev
|
||||
* allocation is not yet supported).
|
||||
*
|
||||
* Note: unlike virtualization systems, the term 'host' here means
|
||||
* the Linux side which is running remoteproc to control the remote
|
||||
* remote_procs. We use the name 'gfeatures' to comply with virtio's terms,
|
||||
* though there isn't really any virtualized guest OS here: it's the host
|
||||
* which is responsible for negotiating the final features.
|
||||
* Yeah, it's a bit confusing.
|
||||
*
|
||||
* Note: immediately following this structure is the virtio config space for
|
||||
* this vdev (which is specific to the vdev; for more info, read the virtio
|
||||
* spec). the size of the config space is specified by @config_len.
|
||||
*/
|
||||
OPENAMP_PACKED_BEGIN
|
||||
struct fw_rsc_vdev {
|
||||
uint32_t type;
|
||||
uint32_t id;
|
||||
uint32_t notifyid;
|
||||
uint32_t dfeatures;
|
||||
uint32_t gfeatures;
|
||||
uint32_t config_len;
|
||||
uint8_t status;
|
||||
uint8_t num_of_vrings;
|
||||
uint8_t reserved[2];
|
||||
struct fw_rsc_vdev_vring vring[0];
|
||||
} OPENAMP_PACKED_END;
|
||||
|
||||
/**
|
||||
* struct fw_rsc_vendor - remote processor vendor specific resource
|
||||
* @len: length of the resource
|
||||
*
|
||||
* This resource entry tells the host the vendor specific resource
|
||||
* required by the remote.
|
||||
*
|
||||
* These request entries should precede other shared resource entries
|
||||
* such as vdevs, vrings.
|
||||
*/
|
||||
OPENAMP_PACKED_BEGIN
|
||||
struct fw_rsc_vendor {
|
||||
uint32_t type;
|
||||
uint32_t len;
|
||||
} OPENAMP_PACKED_END;
|
||||
|
||||
/**
|
||||
* struct fw_rsc_rproc_mem - remote processor memory
|
||||
* @da: device address
|
||||
* @pa: physical address
|
||||
* @len: length (in bytes)
|
||||
* @reserved: reserved (must be zero)
|
||||
*
|
||||
* This resource entry tells the host to the remote processor
|
||||
* memory that the host can be used as shared memory.
|
||||
*
|
||||
* These request entries should precede other shared resource entries
|
||||
* such as vdevs, vrings.
|
||||
*/
|
||||
OPENAMP_PACKED_BEGIN
|
||||
struct fw_rsc_rproc_mem {
|
||||
uint32_t type;
|
||||
uint32_t da;
|
||||
uint32_t pa;
|
||||
uint32_t len;
|
||||
uint32_t reserved;
|
||||
} OPENAMP_PACKED_END;
|
||||
|
||||
/*
|
||||
* struct fw_rsc_fw_chksum - firmware checksum
|
||||
* @algo: algorithm to generate the cheksum
|
||||
* @chksum: checksum of the firmware loadable sections.
|
||||
*
|
||||
* This resource entry provides checksum for the firmware loadable sections.
|
||||
* It is used to check if the remote already runs with the expected firmware to
|
||||
* decide if it needs to start the remote if the remote is already running.
|
||||
*/
|
||||
OPENAMP_PACKED_BEGIN
|
||||
struct fw_rsc_fw_chksum {
|
||||
uint32_t type;
|
||||
uint8_t algo[16];
|
||||
uint8_t chksum[64];
|
||||
} OPENAMP_PACKED_END;
|
||||
|
||||
struct loader_ops;
|
||||
struct image_store_ops;
|
||||
struct remoteproc_ops;
|
||||
|
||||
/**
|
||||
* struct remoteproc_mem
|
||||
*
|
||||
* This structure presents the memory used by the remote processor
|
||||
*
|
||||
* @da: device memory
|
||||
* @pa: physical memory
|
||||
* @size: size of the memory
|
||||
* @io: pointer to the I/O region
|
||||
* @node: list node
|
||||
*/
|
||||
struct remoteproc_mem {
|
||||
metal_phys_addr_t da;
|
||||
metal_phys_addr_t pa;
|
||||
size_t size;
|
||||
char name[32];
|
||||
struct metal_io_region *io;
|
||||
struct metal_list node;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct remoteproc
|
||||
*
|
||||
* This structure is maintained by the remoteproc to represent the remote
|
||||
* processor instance. This structure acts as a prime parameter to use
|
||||
* the remoteproc APIs.
|
||||
*
|
||||
* @bootadd: boot address
|
||||
* @loader: executable loader
|
||||
* @lock: mutext lock
|
||||
* @ops: remoteproc operations
|
||||
* @rsc_table: pointer to resource table
|
||||
* @rsc_len: length of resource table
|
||||
* @rsc_io: metal I/O region of resource table
|
||||
* @mems: remoteproc memories
|
||||
* @vdevs: remoteproc virtio devices
|
||||
* @bitmap: bitmap for notify IDs for remoteproc subdevices
|
||||
* @state: remote processor state
|
||||
* @priv: private data
|
||||
*/
|
||||
struct remoteproc {
|
||||
metal_mutex_t lock;
|
||||
void *rsc_table;
|
||||
size_t rsc_len;
|
||||
struct metal_io_region *rsc_io;
|
||||
struct metal_list mems;
|
||||
struct metal_list vdevs;
|
||||
unsigned long bitmap;
|
||||
struct remoteproc_ops *ops;
|
||||
metal_phys_addr_t bootaddr;
|
||||
struct loader_ops *loader;
|
||||
unsigned int state;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct remoteproc_ops
|
||||
*
|
||||
* remoteproc operations needs to be implemented by each remoteproc driver
|
||||
*
|
||||
* @init: initialize the remoteproc instance
|
||||
* @remove: remove the remoteproc instance
|
||||
* @mmap: memory mapped the mempory with physical address or destination
|
||||
* address as input.
|
||||
* @handle_rsc: handle the vendor specific resource
|
||||
* @config: configure the remoteproc to make it ready to load and run
|
||||
* executable
|
||||
* @start: kick the remoteproc to run application
|
||||
* @stop: stop the remoteproc from running application, the resource such as
|
||||
* memory may not be off.
|
||||
* @shutdown: shutdown the remoteproc and release its resources.
|
||||
* @notify: notify the remote
|
||||
*/
|
||||
struct remoteproc_ops {
|
||||
struct remoteproc *(*init)(struct remoteproc *rproc,
|
||||
struct remoteproc_ops *ops, void *arg);
|
||||
void (*remove)(struct remoteproc *rproc);
|
||||
void *(*mmap)(struct remoteproc *rproc,
|
||||
metal_phys_addr_t *pa, metal_phys_addr_t *da,
|
||||
size_t size, unsigned int attribute,
|
||||
struct metal_io_region **io);
|
||||
int (*handle_rsc)(struct remoteproc *rproc, void *rsc, size_t len);
|
||||
int (*config)(struct remoteproc *rproc, void *data);
|
||||
int (*start)(struct remoteproc *rproc);
|
||||
int (*stop)(struct remoteproc *rproc);
|
||||
int (*shutdown)(struct remoteproc *rproc);
|
||||
int (*notify)(struct remoteproc *rproc, uint32_t id);
|
||||
};
|
||||
|
||||
/* Remoteproc error codes */
|
||||
#define RPROC_EBASE 0
|
||||
#define RPROC_ENOMEM (RPROC_EBASE + 1)
|
||||
#define RPROC_EINVAL (RPROC_EBASE + 2)
|
||||
#define RPROC_ENODEV (RPROC_EBASE + 3)
|
||||
#define RPROC_EAGAIN (RPROC_EBASE + 4)
|
||||
#define RPROC_ERR_RSC_TAB_TRUNC (RPROC_EBASE + 5)
|
||||
#define RPROC_ERR_RSC_TAB_VER (RPROC_EBASE + 6)
|
||||
#define RPROC_ERR_RSC_TAB_RSVD (RPROC_EBASE + 7)
|
||||
#define RPROC_ERR_RSC_TAB_VDEV_NRINGS (RPROC_EBASE + 9)
|
||||
#define RPROC_ERR_RSC_TAB_NP (RPROC_EBASE + 10)
|
||||
#define RPROC_ERR_RSC_TAB_NS (RPROC_EBASE + 11)
|
||||
#define RPROC_ERR_LOADER_STATE (RPROC_EBASE + 12)
|
||||
#define RPROC_EMAX (RPROC_EBASE + 16)
|
||||
#define RPROC_EPTR (void *)(-1)
|
||||
#define RPROC_EOF (void *)(-1)
|
||||
|
||||
static inline long RPROC_PTR_ERR(const void *ptr)
|
||||
{
|
||||
return (long)ptr;
|
||||
}
|
||||
|
||||
static inline int RPROC_IS_ERR(const void *ptr)
|
||||
{
|
||||
if ((unsigned long)ptr >= (unsigned long)(-RPROC_EMAX))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void *RPROC_ERR_PTR(long error)
|
||||
{
|
||||
return (void *)error;
|
||||
}
|
||||
|
||||
/**
|
||||
* enum rproc_state - remote processor states
|
||||
* @RPROC_OFFLINE: remote is offline
|
||||
* @RPROC_READY: remote is ready to start
|
||||
* @RPROC_RUNNING: remote is up and running
|
||||
* @RPROC_SUSPENDED: remote is suspended
|
||||
* @RPROC_ERROR: remote has error; need to recover
|
||||
* @RPROC_STOPPED: remote is stopped
|
||||
* @RPROC_LAST: just keep this one at the end
|
||||
*/
|
||||
enum remoteproc_state {
|
||||
RPROC_OFFLINE = 0,
|
||||
RPROC_CONFIGURED = 1,
|
||||
RPROC_READY = 2,
|
||||
RPROC_RUNNING = 3,
|
||||
RPROC_SUSPENDED = 4,
|
||||
RPROC_ERROR = 5,
|
||||
RPROC_STOPPED = 6,
|
||||
RPROC_LAST = 7,
|
||||
};
|
||||
|
||||
/**
|
||||
* remoteproc_init
|
||||
*
|
||||
* Initializes remoteproc resource.
|
||||
*
|
||||
* @rproc - pointer to remoteproc instance
|
||||
* @ops - pointer to remoteproc operations
|
||||
* @priv - pointer to private data
|
||||
*
|
||||
* @returns created remoteproc pointer
|
||||
*/
|
||||
struct remoteproc *remoteproc_init(struct remoteproc *rproc,
|
||||
struct remoteproc_ops *ops, void *priv);
|
||||
|
||||
/**
|
||||
* remoteproc_remove
|
||||
*
|
||||
* Remove remoteproc resource
|
||||
*
|
||||
* @rproc - pointer to remoteproc instance
|
||||
*
|
||||
* returns 0 for success, negative value for failure
|
||||
*/
|
||||
int remoteproc_remove(struct remoteproc *rproc);
|
||||
|
||||
/**
|
||||
* remoteproc_init_mem
|
||||
*
|
||||
* Initialize remoteproc memory
|
||||
*
|
||||
* @mem - pointer to remoteproc memory
|
||||
* @char - memory name
|
||||
* @pa - physcial address
|
||||
* @da - device address
|
||||
* @size - memory size
|
||||
* @io - pointer to the I/O region
|
||||
*/
|
||||
static inline void
|
||||
remoteproc_init_mem(struct remoteproc_mem *mem, const char *name,
|
||||
metal_phys_addr_t pa, metal_phys_addr_t da,
|
||||
size_t size, struct metal_io_region *io)
|
||||
{
|
||||
if (!mem)
|
||||
return;
|
||||
if (name)
|
||||
strncpy(mem->name, name, sizeof(mem->name));
|
||||
else
|
||||
mem->name[0] = 0;
|
||||
mem->pa = pa;
|
||||
mem->da = da;
|
||||
mem->io = io;
|
||||
mem->size = size;
|
||||
}
|
||||
|
||||
/**
|
||||
* remoteproc_add_mem
|
||||
*
|
||||
* Add remoteproc memory
|
||||
*
|
||||
* @rproc - pointer to remoteproc
|
||||
* @mem - pointer to remoteproc memory
|
||||
*/
|
||||
static inline void
|
||||
remoteproc_add_mem(struct remoteproc *rproc, struct remoteproc_mem *mem)
|
||||
{
|
||||
if (!rproc || !mem)
|
||||
return;
|
||||
metal_list_add_tail(&rproc->mems, &mem->node);
|
||||
}
|
||||
|
||||
/**
|
||||
* remoteproc_get_io_with_name
|
||||
*
|
||||
* get remoteproc memory I/O region with name
|
||||
*
|
||||
* @rproc - pointer to the remote processor
|
||||
* @name - name of the shared memory
|
||||
* @io - pointer to the pointer of the I/O region
|
||||
*
|
||||
* returns metal I/O region pointer, NULL for failure
|
||||
*/
|
||||
struct metal_io_region *
|
||||
remoteproc_get_io_with_name(struct remoteproc *rproc,
|
||||
const char *name);
|
||||
|
||||
/**
|
||||
* remoteproc_get_io_with_pa
|
||||
*
|
||||
* get remoteproc memory I/O region with physical address
|
||||
*
|
||||
* @rproc - pointer to the remote processor
|
||||
* @pa - physical address
|
||||
*
|
||||
* returns metal I/O region pointer, NULL for failure
|
||||
*/
|
||||
struct metal_io_region *
|
||||
remoteproc_get_io_with_pa(struct remoteproc *rproc,
|
||||
metal_phys_addr_t pa);
|
||||
|
||||
/**
|
||||
* remoteproc_get_io_with_da
|
||||
*
|
||||
* get remoteproc memory I/O region with device address
|
||||
*
|
||||
* @rproc - pointer to the remote processor
|
||||
* @da - device address
|
||||
* @offset - I/O region offset of the device address
|
||||
*
|
||||
* returns metal I/O region pointer, NULL for failure
|
||||
*/
|
||||
struct metal_io_region *
|
||||
remoteproc_get_io_with_da(struct remoteproc *rproc,
|
||||
metal_phys_addr_t da,
|
||||
unsigned long *offset);
|
||||
|
||||
/**
|
||||
* remoteproc_get_io_with_va
|
||||
*
|
||||
* get remoteproc memory I/O region with virtual address
|
||||
*
|
||||
* @rproc - pointer to the remote processor
|
||||
* @va - virtual address
|
||||
*
|
||||
* returns metal I/O region pointer, NULL for failure
|
||||
*/
|
||||
struct metal_io_region *
|
||||
remoteproc_get_io_with_va(struct remoteproc *rproc,
|
||||
void *va);
|
||||
|
||||
/**
|
||||
* remoteproc_mmap
|
||||
*
|
||||
* remoteproc mmap memory
|
||||
*
|
||||
* @rproc - pointer to the remote processor
|
||||
* @pa - physical address pointer
|
||||
* @da - device address pointer
|
||||
* @size - size of the memory
|
||||
* @attribute - memory attribute
|
||||
* @io - pointer to the I/O region
|
||||
*
|
||||
* returns pointer to the memory
|
||||
*/
|
||||
void *remoteproc_mmap(struct remoteproc *rproc,
|
||||
metal_phys_addr_t *pa, metal_phys_addr_t *da,
|
||||
size_t size, unsigned int attribute,
|
||||
struct metal_io_region **io);
|
||||
|
||||
/**
|
||||
* remoteproc_parse_rsc_table
|
||||
*
|
||||
* Parse resource table of remoteproc
|
||||
*
|
||||
* @rproc - pointer to remoteproc instance
|
||||
* @rsc_table - pointer to resource table
|
||||
* @rsc_size - resource table size
|
||||
*
|
||||
* returns 0 for success and negative value for errors
|
||||
*/
|
||||
int remoteproc_parse_rsc_table(struct remoteproc *rproc,
|
||||
struct resource_table *rsc_table,
|
||||
size_t rsc_size);
|
||||
|
||||
/**
|
||||
* remoteproc_set_rsc_table
|
||||
*
|
||||
* Parse and set resource table of remoteproc
|
||||
*
|
||||
* @rproc - pointer to remoteproc instance
|
||||
* @rsc_table - pointer to resource table
|
||||
* @rsc_size - resource table size
|
||||
*
|
||||
* returns 0 for success and negative value for errors
|
||||
*/
|
||||
int remoteproc_set_rsc_table(struct remoteproc *rproc,
|
||||
struct resource_table *rsc_table,
|
||||
size_t rsc_size);
|
||||
|
||||
/**
|
||||
* remoteproc_config
|
||||
*
|
||||
* This function configures the remote processor to get it
|
||||
* ready to load and run executable.
|
||||
*
|
||||
* @rproc - pointer to remoteproc instance to start
|
||||
* @data - configuration data
|
||||
*
|
||||
* returns 0 for success and negative value for errors
|
||||
*/
|
||||
int remoteproc_config(struct remoteproc *rproc, void *data);
|
||||
|
||||
/**
|
||||
* remoteproc_start
|
||||
*
|
||||
* This function starts the remote processor.
|
||||
* It assumes the firmware is already loaded,
|
||||
*
|
||||
* @rproc - pointer to remoteproc instance to start
|
||||
*
|
||||
* returns 0 for success and negative value for errors
|
||||
*/
|
||||
int remoteproc_start(struct remoteproc *rproc);
|
||||
|
||||
/**
|
||||
* remoteproc_stop
|
||||
*
|
||||
* This function stops the remote processor but it
|
||||
* will not release its resource.
|
||||
*
|
||||
* @rproc - pointer to remoteproc instance
|
||||
*
|
||||
* returns 0 for success and negative value for errors
|
||||
*/
|
||||
int remoteproc_stop(struct remoteproc *rproc);
|
||||
|
||||
/**
|
||||
* remoteproc_shutdown
|
||||
*
|
||||
* This function shutdown the remote processor and
|
||||
* release its resources.
|
||||
*
|
||||
* @rproc - pointer to remoteproc instance
|
||||
*
|
||||
* returns 0 for success and negative value for errors
|
||||
*/
|
||||
int remoteproc_shutdown(struct remoteproc *rproc);
|
||||
|
||||
/**
|
||||
* remoteproc_load
|
||||
*
|
||||
* load executable, it expects the user application defines how to
|
||||
* open the executable file and how to get data from the executable file
|
||||
* and how to load data to the target memory.
|
||||
*
|
||||
* @rproc: pointer to the remoteproc instance
|
||||
* @path: optional path to the image file
|
||||
* @store: pointer to user defined image store argument
|
||||
* @store_ops: pointer to image store operations
|
||||
* @image_info: pointer to memory which stores image information used
|
||||
* by remoteproc loader
|
||||
*
|
||||
* return 0 for success and negative value for failure
|
||||
*/
|
||||
int remoteproc_load(struct remoteproc *rproc, const char *path,
|
||||
void *store, struct image_store_ops *store_ops,
|
||||
void **img_info);
|
||||
|
||||
/**
|
||||
* remoteproc_load_noblock
|
||||
*
|
||||
* load executable, it expects the caller has loaded image data to local
|
||||
* memory and passed to the this function. If the function needs more
|
||||
* image data it will return the next expected image data offset and
|
||||
* the next expected image data length. If the function requires the
|
||||
* caller to download image data to the target memory, it will also
|
||||
* return the target physical address besides the offset and length.
|
||||
* This function can be used to load firmware in stream mode. In this
|
||||
* mode, you cannot do seek to the executable file. If the executable
|
||||
* is ELF, it cannot get the resource table section before it loads
|
||||
* the full ELF file. Furthermore, application usually don't store
|
||||
* the data which is loaded to local memory in streaming mode, and
|
||||
* thus, in this mode, it will load the binrary to the target memory
|
||||
* before it gets the resource table. And thus, when calling this funciton
|
||||
* don't put the target exectuable memory in the resource table, as
|
||||
* this function will parse the resource table after it loads the binary
|
||||
* to target memory.
|
||||
*
|
||||
* @rproc: pointer to the remoteproc instance
|
||||
* @img_data: pointer to image data for remoteproc loader to parse
|
||||
* @offset: image data offset to the beginning of the image file
|
||||
* @len: image data length
|
||||
* @image_info: pointer to memory which stores image information used
|
||||
* by remoteproc loader
|
||||
* @pa: pointer to the target memory physical address. If the next expected
|
||||
* data doesn't need to load to the target memory, the function will
|
||||
* set it to ANY.
|
||||
* @io: pointer to the target memory physical address. If the next expected
|
||||
* data doesn't need to load to the target memory, the function will
|
||||
* set it to ANY.
|
||||
* @noffset: pointer to the next image data offset to the beginning of
|
||||
* the image file needs to load to local or to the target
|
||||
* memory.
|
||||
* @nlen: pointer to the next image data length needs to load to local
|
||||
* or to the target memory.
|
||||
* @nmlen: pointer to the memory size. It is only used when the next
|
||||
* expected data is going to be loaded to the target memory. E.g.
|
||||
* in ELF, it is possible that loadable segment in memory is
|
||||
* larger that the segment data in the ELF file. In this case,
|
||||
* application will need to pad the rest of the memory with
|
||||
* padding.
|
||||
* @padding: pointer to the padding value. It is only used when the next
|
||||
* expected data is going to be loaded to the target memory.
|
||||
* and the target memory size is larger than the segment data in
|
||||
* the executable file.
|
||||
*
|
||||
* return 0 for success and negative value for failure
|
||||
*/
|
||||
int remoteproc_load_noblock(struct remoteproc *rproc,
|
||||
const void *img_data, size_t offset, size_t len,
|
||||
void **img_info,
|
||||
metal_phys_addr_t *pa, struct metal_io_region **io,
|
||||
size_t *noffset, size_t *nlen,
|
||||
size_t *nmlen, unsigned char *padding);
|
||||
|
||||
/**
|
||||
* remoteproc_allocate_id
|
||||
*
|
||||
* allocate notifyid for resource
|
||||
*
|
||||
* @rproc - pointer to the remoteproc instance
|
||||
* @start - start of the id range
|
||||
* @end - end of the id range
|
||||
*
|
||||
* return allocated notify id
|
||||
*/
|
||||
unsigned int remoteproc_allocate_id(struct remoteproc *rproc,
|
||||
unsigned int start,
|
||||
unsigned int end);
|
||||
|
||||
/* remoteproc_create_virtio
|
||||
*
|
||||
* create virtio device, it returns pointer to the created virtio device.
|
||||
*
|
||||
* @rproc: pointer to the remoteproc instance
|
||||
* @vdev_id: virtio device ID
|
||||
* @role: virtio device role
|
||||
* @rst_cb: virtio device reset callback
|
||||
*
|
||||
* return pointer to the created virtio device, NULL for failure.
|
||||
*/
|
||||
struct virtio_device *
|
||||
remoteproc_create_virtio(struct remoteproc *rproc,
|
||||
int vdev_id, unsigned int role,
|
||||
void (*rst_cb)(struct virtio_device *vdev));
|
||||
|
||||
/* remoteproc_remove_virtio
|
||||
*
|
||||
* Remove virtio device
|
||||
*
|
||||
* @rproc: pointer to the remoteproc instance
|
||||
* @vdev: pointer to the virtio device
|
||||
*
|
||||
*/
|
||||
void remoteproc_remove_virtio(struct remoteproc *rproc,
|
||||
struct virtio_device *vdev);
|
||||
|
||||
/* remoteproc_get_notification
|
||||
*
|
||||
* remoteproc is got notified, it will check its subdevices
|
||||
* for the notification
|
||||
*
|
||||
* @rproc - pointer to the remoteproc instance
|
||||
* @notifyid - notificatin id
|
||||
*
|
||||
* return 0 for succeed, negative value for failure
|
||||
*/
|
||||
int remoteproc_get_notification(struct remoteproc *rproc,
|
||||
uint32_t notifyid);
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* REMOTEPROC_H_ */
|
||||
108
source/OpenAMP/open-amp/lib/include/openamp/remoteproc_loader.h
Normal file
108
source/OpenAMP/open-amp/lib/include/openamp/remoteproc_loader.h
Normal file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Mentor Graphics Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
/**************************************************************************
|
||||
* FILE NAME
|
||||
*
|
||||
* remoteproc_loader.h
|
||||
*
|
||||
* COMPONENT
|
||||
*
|
||||
* OpenAMP stack.
|
||||
*
|
||||
* DESCRIPTION
|
||||
*
|
||||
* This file provides definitions for remoteproc loader
|
||||
*
|
||||
*
|
||||
**************************************************************************/
|
||||
#ifndef REMOTEPROC_LOADER_H_
|
||||
#define REMOTEPROC_LOADER_H_
|
||||
|
||||
#include <metal/io.h>
|
||||
#include <metal/list.h>
|
||||
#include <metal/sys.h>
|
||||
#include <openamp/remoteproc.h>
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Loader feature macros */
|
||||
#define SUPPORT_SEEK 1UL
|
||||
|
||||
/* Remoteproc loader any address */
|
||||
#define RPROC_LOAD_ANYADDR ((metal_phys_addr_t)-1)
|
||||
|
||||
/* Remoteproc loader Exectuable Image Parsing States */
|
||||
/* Remoteproc loader parser intial state */
|
||||
#define RPROC_LOADER_NOT_READY 0x0UL
|
||||
/* Remoteproc loader ready to load, even it can be not finish parsing */
|
||||
#define RPROC_LOADER_READY_TO_LOAD 0x10000UL
|
||||
/* Remoteproc loader post data load */
|
||||
#define RPROC_LOADER_POST_DATA_LOAD 0x20000UL
|
||||
/* Remoteproc loader finished loading */
|
||||
#define RPROC_LOADER_LOAD_COMPLETE 0x40000UL
|
||||
/* Remoteproc loader state mask */
|
||||
#define RPROC_LOADER_MASK 0x00FF0000UL
|
||||
/* Remoteproc loader private mask */
|
||||
#define RPROC_LOADER_PRIVATE_MASK 0x0000FFFFUL
|
||||
/* Remoteproc loader reserved mask */
|
||||
#define RPROC_LOADER_RESERVED_MASK 0x0F000000UL
|
||||
|
||||
/**
|
||||
* struct image_store_ops - user defined image store operations
|
||||
* @open: user defined callback to open the "firmware" to prepare loading
|
||||
* @close: user defined callback to close the "firmware" to clean up
|
||||
* after loading
|
||||
* @load: user defined callback to load the firmware contents to target
|
||||
* memory or local memory
|
||||
* @features: loader supported features. e.g. seek
|
||||
*/
|
||||
struct image_store_ops {
|
||||
int (*open)(void *store, const char *path, const void **img_data);
|
||||
void (*close)(void *store);
|
||||
int (*load)(void *store, size_t offset, size_t size,
|
||||
const void **data,
|
||||
metal_phys_addr_t pa,
|
||||
struct metal_io_region *io, char is_blocking);
|
||||
unsigned int features;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct loader_ops - loader oeprations
|
||||
* @load_header: define how to get the executable headers
|
||||
* @load_data: define how to load the target data
|
||||
* @locate_rsc_table: define how to get the resource table target address,
|
||||
* offset to the ELF image file and size of the resource
|
||||
* table.
|
||||
* @release: define how to release the loader
|
||||
* @get_entry: get entry address
|
||||
* @get_load_state: get load state from the image information
|
||||
*/
|
||||
struct loader_ops {
|
||||
int (*load_header)(const void *img_data, size_t offset, size_t len,
|
||||
void **img_info, int last_state,
|
||||
size_t *noffset, size_t *nlen);
|
||||
int (*load_data)(struct remoteproc *rproc,
|
||||
const void *img_data, size_t offset, size_t len,
|
||||
void **img_info, int last_load_state,
|
||||
metal_phys_addr_t *da,
|
||||
size_t *noffset, size_t *nlen,
|
||||
unsigned char *padding, size_t *nmemsize);
|
||||
int (*locate_rsc_table)(void *img_info, metal_phys_addr_t *da,
|
||||
size_t *offset, size_t *size);
|
||||
void (*release)(void *img_info);
|
||||
metal_phys_addr_t (*get_entry)(void *img_info);
|
||||
int (*get_load_state)(void *img_info);
|
||||
};
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* REMOTEPROC_LOADER_H_ */
|
||||
150
source/OpenAMP/open-amp/lib/include/openamp/remoteproc_virtio.h
Normal file
150
source/OpenAMP/open-amp/lib/include/openamp/remoteproc_virtio.h
Normal file
@@ -0,0 +1,150 @@
|
||||
/*
|
||||
* Remoteproc Virtio Framework
|
||||
*
|
||||
* Copyright(c) 2018 Xilinx Ltd.
|
||||
* Copyright(c) 2011 Texas Instruments, Inc.
|
||||
* Copyright(c) 2011 Google, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* * Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* * Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
* the documentation and/or other materials provided with the
|
||||
* distribution.
|
||||
* * Neither the name Texas Instruments nor the names of its
|
||||
* contributors may be used to endorse or promote products derived
|
||||
* from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
* "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 COPYRIGHT
|
||||
* OWNER OR CONTRIBUTORS 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.
|
||||
*/
|
||||
|
||||
#ifndef REMOTEPROC_VIRTIO_H
|
||||
#define REMOTEPROC_VIRTIO_H
|
||||
|
||||
#include <metal/io.h>
|
||||
#include <metal/list.h>
|
||||
#include <openamp/virtio.h>
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* define vdev notification funciton user should implement */
|
||||
typedef int (*rpvdev_notify_func)(void *priv, uint32_t id);
|
||||
|
||||
/**
|
||||
* struct remoteproc_virtio
|
||||
* @priv pointer to private data
|
||||
* @notifyid notification id
|
||||
* @vdev_rsc address of vdev resource
|
||||
* @vdev_rsc_io metal I/O region of vdev_info, can be NULL
|
||||
* @notify notification function
|
||||
* @vdev virtio device
|
||||
* @node list node
|
||||
*/
|
||||
struct remoteproc_virtio {
|
||||
void *priv;
|
||||
uint32_t notify_id;
|
||||
void *vdev_rsc;
|
||||
struct metal_io_region *vdev_rsc_io;
|
||||
rpvdev_notify_func notify;
|
||||
struct virtio_device vdev;
|
||||
struct metal_list node;
|
||||
};
|
||||
|
||||
/**
|
||||
* rproc_virtio_create_vdev
|
||||
*
|
||||
* Create rproc virtio vdev
|
||||
*
|
||||
* @role: 0 - virtio master, 1 - virtio slave
|
||||
* @notifyid: virtio device notification id
|
||||
* @rsc: pointer to the virtio device resource
|
||||
* @rsc_io: pointer to the virtio device resource I/O region
|
||||
* @priv: pointer to the private data
|
||||
* @notify: vdev and virtqueue notification function
|
||||
* @rst_cb: reset virtio device callback
|
||||
*
|
||||
* return pointer to the created virtio device for success,
|
||||
* NULL for failure.
|
||||
*/
|
||||
struct virtio_device *
|
||||
rproc_virtio_create_vdev(unsigned int role, unsigned int notifyid,
|
||||
void *rsc, struct metal_io_region *rsc_io,
|
||||
void *priv,
|
||||
rpvdev_notify_func notify,
|
||||
virtio_dev_reset_cb rst_cb);
|
||||
|
||||
/**
|
||||
* rproc_virtio_remove_vdev
|
||||
*
|
||||
* Create rproc virtio vdev
|
||||
*
|
||||
* @vdev - pointer to the virtio device
|
||||
*/
|
||||
void rproc_virtio_remove_vdev(struct virtio_device *vdev);
|
||||
|
||||
/**
|
||||
* rproc_virtio_create_vring
|
||||
*
|
||||
* Create rproc virtio vring
|
||||
*
|
||||
* @vdev: pointer to the virtio device
|
||||
* @index: vring index in the virtio device
|
||||
* @notifyid: remoteproc vring notification id
|
||||
* @va: vring virtual address
|
||||
* @io: pointer to vring I/O region
|
||||
* @num_desc: number of descriptors
|
||||
* @align: vring alignment
|
||||
*
|
||||
* return 0 for success, negative value for failure.
|
||||
*/
|
||||
int rproc_virtio_init_vring(struct virtio_device *vdev, unsigned int index,
|
||||
unsigned int notifyid, void *va,
|
||||
struct metal_io_region *io,
|
||||
unsigned int num_descs, unsigned int align);
|
||||
|
||||
/**
|
||||
* rproc_virtio_notified
|
||||
*
|
||||
* remoteproc virtio is got notified
|
||||
*
|
||||
* @vdev - pointer to the virtio device
|
||||
* @notifyid - notify id
|
||||
*
|
||||
* return 0 for successful, negative value for failure
|
||||
*/
|
||||
int rproc_virtio_notified(struct virtio_device *vdev, uint32_t notifyid);
|
||||
|
||||
/**
|
||||
* rproc_virtio_wait_remote_ready
|
||||
*
|
||||
* Blocking function, waiting for the remote core is ready to start
|
||||
* communications.
|
||||
*
|
||||
* @vdev - pointer to the virtio device
|
||||
*
|
||||
* return true when remote processor is ready.
|
||||
*/
|
||||
void rproc_virtio_wait_remote_ready(struct virtio_device *vdev);
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* REMOTEPROC_VIRTIO_H */
|
||||
358
source/OpenAMP/open-amp/lib/include/openamp/rpmsg.h
Normal file
358
source/OpenAMP/open-amp/lib/include/openamp/rpmsg.h
Normal file
@@ -0,0 +1,358 @@
|
||||
/*
|
||||
* Remote processor messaging
|
||||
*
|
||||
* Copyright (C) 2011 Texas Instruments, Inc.
|
||||
* Copyright (C) 2011 Google, Inc.
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _RPMSG_H_
|
||||
#define _RPMSG_H_
|
||||
|
||||
#include <openamp/compiler.h>
|
||||
#include <metal/mutex.h>
|
||||
#include <metal/list.h>
|
||||
#include <metal/utilities.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Configurable parameters */
|
||||
#define RPMSG_NAME_SIZE (32)
|
||||
#define RPMSG_ADDR_BMP_SIZE (128)
|
||||
|
||||
#define RPMSG_NS_EPT_ADDR (0x35)
|
||||
#define RPMSG_ADDR_ANY 0xFFFFFFFF
|
||||
|
||||
/* Error macros. */
|
||||
#define RPMSG_SUCCESS 0
|
||||
#define RPMSG_ERROR_BASE -2000
|
||||
#define RPMSG_ERR_NO_MEM (RPMSG_ERROR_BASE - 1)
|
||||
#define RPMSG_ERR_NO_BUFF (RPMSG_ERROR_BASE - 2)
|
||||
#define RPMSG_ERR_PARAM (RPMSG_ERROR_BASE - 3)
|
||||
#define RPMSG_ERR_DEV_STATE (RPMSG_ERROR_BASE - 4)
|
||||
#define RPMSG_ERR_BUFF_SIZE (RPMSG_ERROR_BASE - 5)
|
||||
#define RPMSG_ERR_INIT (RPMSG_ERROR_BASE - 6)
|
||||
#define RPMSG_ERR_ADDR (RPMSG_ERROR_BASE - 7)
|
||||
|
||||
struct rpmsg_endpoint;
|
||||
struct rpmsg_device;
|
||||
|
||||
typedef int (*rpmsg_ept_cb)(struct rpmsg_endpoint *ept, void *data,
|
||||
size_t len, uint32_t src, void *priv);
|
||||
typedef void (*rpmsg_ns_unbind_cb)(struct rpmsg_endpoint *ept);
|
||||
typedef void (*rpmsg_ns_bind_cb)(struct rpmsg_device *rdev,
|
||||
const char *name, uint32_t dest);
|
||||
|
||||
/**
|
||||
* struct rpmsg_endpoint - binds a local rpmsg address to its user
|
||||
* @name:name of the service supported
|
||||
* @rdev: pointer to the rpmsg device
|
||||
* @addr: local address of the endpoint
|
||||
* @dest_addr: address of the default remote endpoint binded.
|
||||
* @cb: user rx callback, return value of this callback is reserved
|
||||
* for future use, for now, only allow RPMSG_SUCCESS as return value.
|
||||
* @ns_unbind_cb: end point service service unbind callback, called when remote
|
||||
* ept is destroyed.
|
||||
* @node: end point node.
|
||||
* @addr: local rpmsg address
|
||||
* @priv: private data for the driver's use
|
||||
*
|
||||
* In essence, an rpmsg endpoint represents a listener on the rpmsg bus, as
|
||||
* it binds an rpmsg address with an rx callback handler.
|
||||
*/
|
||||
struct rpmsg_endpoint {
|
||||
char name[RPMSG_NAME_SIZE];
|
||||
struct rpmsg_device *rdev;
|
||||
uint32_t addr;
|
||||
uint32_t dest_addr;
|
||||
rpmsg_ept_cb cb;
|
||||
rpmsg_ns_unbind_cb ns_unbind_cb;
|
||||
struct metal_list node;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct rpmsg_device_ops - RPMsg device operations
|
||||
* @send_offchannel_raw: send RPMsg data
|
||||
*/
|
||||
struct rpmsg_device_ops {
|
||||
int (*send_offchannel_raw)(struct rpmsg_device *rdev,
|
||||
uint32_t src, uint32_t dst,
|
||||
const void *data, int size, int wait);
|
||||
};
|
||||
|
||||
/**
|
||||
* struct rpmsg_device - representation of a RPMsg device
|
||||
* @endpoints: list of endpoints
|
||||
* @ns_ept: name service endpoint
|
||||
* @bitmap: table endpoin address allocation.
|
||||
* @lock: mutex lock for rpmsg management
|
||||
* @ns_bind_cb: callback handler for name service announcement without local
|
||||
* endpoints waiting to bind.
|
||||
* @ops: RPMsg device operations
|
||||
*/
|
||||
struct rpmsg_device {
|
||||
struct metal_list endpoints;
|
||||
struct rpmsg_endpoint ns_ept;
|
||||
unsigned long bitmap[metal_bitmap_longs(RPMSG_ADDR_BMP_SIZE)];
|
||||
metal_mutex_t lock;
|
||||
rpmsg_ns_bind_cb ns_bind_cb;
|
||||
struct rpmsg_device_ops ops;
|
||||
};
|
||||
|
||||
/**
|
||||
* rpmsg_send_offchannel_raw() - send a message across to the remote processor,
|
||||
* specifying source and destination address.
|
||||
* @ept: the rpmsg endpoint
|
||||
* @data: payload of the message
|
||||
* @len: length of the payload
|
||||
*
|
||||
* This function sends @data of length @len to the remote @dst address from
|
||||
* the source @src address.
|
||||
* The message will be sent to the remote processor which the channel belongs
|
||||
* to.
|
||||
* In case there are no TX buffers available, the function will block until
|
||||
* one becomes available, or a timeout of 15 seconds elapses. When the latter
|
||||
* happens, -ERESTARTSYS is returned.
|
||||
*
|
||||
* Returns number of bytes it has sent or negative error value on failure.
|
||||
*/
|
||||
int rpmsg_send_offchannel_raw(struct rpmsg_endpoint *ept, uint32_t src,
|
||||
uint32_t dst, const void *data, int size,
|
||||
int wait);
|
||||
|
||||
/**
|
||||
* rpmsg_send() - send a message across to the remote processor
|
||||
* @ept: the rpmsg endpoint
|
||||
* @data: payload of the message
|
||||
* @len: length of the payload
|
||||
*
|
||||
* This function sends @data of length @len based on the @ept.
|
||||
* The message will be sent to the remote processor which the channel belongs
|
||||
* to, using @ept's source and destination addresses.
|
||||
* In case there are no TX buffers available, the function will block until
|
||||
* one becomes available, or a timeout of 15 seconds elapses. When the latter
|
||||
* happens, -ERESTARTSYS is returned.
|
||||
*
|
||||
* Returns number of bytes it has sent or negative error value on failure.
|
||||
*/
|
||||
static inline int rpmsg_send(struct rpmsg_endpoint *ept, const void *data,
|
||||
int len)
|
||||
{
|
||||
if (ept->dest_addr == RPMSG_ADDR_ANY)
|
||||
return RPMSG_ERR_ADDR;
|
||||
return rpmsg_send_offchannel_raw(ept, ept->addr, ept->dest_addr, data,
|
||||
len, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* rpmsg_sendto() - send a message across to the remote processor, specify dst
|
||||
* @ept: the rpmsg endpoint
|
||||
* @data: payload of message
|
||||
* @len: length of payload
|
||||
* @dst: destination address
|
||||
*
|
||||
* This function sends @data of length @len to the remote @dst address.
|
||||
* The message will be sent to the remote processor which the @ept
|
||||
* channel belongs to, using @ept's source address.
|
||||
* In case there are no TX buffers available, the function will block until
|
||||
* one becomes available, or a timeout of 15 seconds elapses. When the latter
|
||||
* happens, -ERESTARTSYS is returned.
|
||||
*
|
||||
* Returns number of bytes it has sent or negative error value on failure.
|
||||
*/
|
||||
static inline int rpmsg_sendto(struct rpmsg_endpoint *ept, const void *data,
|
||||
int len, uint32_t dst)
|
||||
{
|
||||
return rpmsg_send_offchannel_raw(ept, ept->addr, dst, data, len, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* rpmsg_send_offchannel() - send a message using explicit src/dst addresses
|
||||
* @ept: the rpmsg endpoint
|
||||
* @src: source address
|
||||
* @dst: destination address
|
||||
* @data: payload of message
|
||||
* @len: length of payload
|
||||
*
|
||||
* This function sends @data of length @len to the remote @dst address,
|
||||
* and uses @src as the source address.
|
||||
* The message will be sent to the remote processor which the @ept
|
||||
* channel belongs to.
|
||||
* In case there are no TX buffers available, the function will block until
|
||||
* one becomes available, or a timeout of 15 seconds elapses. When the latter
|
||||
* happens, -ERESTARTSYS is returned.
|
||||
*
|
||||
* Returns number of bytes it has sent or negative error value on failure.
|
||||
*/
|
||||
static inline int rpmsg_send_offchannel(struct rpmsg_endpoint *ept,
|
||||
uint32_t src, uint32_t dst,
|
||||
const void *data, int len)
|
||||
{
|
||||
return rpmsg_send_offchannel_raw(ept, src, dst, data, len, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* rpmsg_trysend() - send a message across to the remote processor
|
||||
* @ept: the rpmsg endpoint
|
||||
* @data: payload of message
|
||||
* @len: length of payload
|
||||
*
|
||||
* This function sends @data of length @len on the @ept channel.
|
||||
* The message will be sent to the remote processor which the @ept
|
||||
* channel belongs to, using @ept's source and destination addresses.
|
||||
* In case there are no TX buffers available, the function will immediately
|
||||
* return -ENOMEM without waiting until one becomes available.
|
||||
*
|
||||
* Returns number of bytes it has sent or negative error value on failure.
|
||||
*/
|
||||
static inline int rpmsg_trysend(struct rpmsg_endpoint *ept, const void *data,
|
||||
int len)
|
||||
{
|
||||
if (ept->dest_addr == RPMSG_ADDR_ANY)
|
||||
return RPMSG_ERR_ADDR;
|
||||
return rpmsg_send_offchannel_raw(ept, ept->addr, ept->dest_addr, data,
|
||||
len, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* rpmsg_trysendto() - send a message across to the remote processor,
|
||||
* specify dst
|
||||
* @ept: the rpmsg endpoint
|
||||
* @data: payload of message
|
||||
* @len: length of payload
|
||||
* @dst: destination address
|
||||
*
|
||||
* This function sends @data of length @len to the remote @dst address.
|
||||
* The message will be sent to the remote processor which the @ept
|
||||
* channel belongs to, using @ept's source address.
|
||||
* In case there are no TX buffers available, the function will immediately
|
||||
* return -ENOMEM without waiting until one becomes available.
|
||||
*
|
||||
* Returns number of bytes it has sent or negative error value on failure.
|
||||
*/
|
||||
static inline int rpmsg_trysendto(struct rpmsg_endpoint *ept, const void *data,
|
||||
int len, uint32_t dst)
|
||||
{
|
||||
return rpmsg_send_offchannel_raw(ept, ept->addr, dst, data, len, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* rpmsg_trysend_offchannel() - send a message using explicit src/dst addresses
|
||||
* @ept: the rpmsg endpoint
|
||||
* @src: source address
|
||||
* @dst: destination address
|
||||
* @data: payload of message
|
||||
* @len: length of payload
|
||||
*
|
||||
* This function sends @data of length @len to the remote @dst address,
|
||||
* and uses @src as the source address.
|
||||
* The message will be sent to the remote processor which the @ept
|
||||
* channel belongs to.
|
||||
* In case there are no TX buffers available, the function will immediately
|
||||
* return -ENOMEM without waiting until one becomes available.
|
||||
*
|
||||
* Returns number of bytes it has sent or negative error value on failure.
|
||||
*/
|
||||
static inline int rpmsg_trysend_offchannel(struct rpmsg_endpoint *ept,
|
||||
uint32_t src, uint32_t dst,
|
||||
const void *data, int len)
|
||||
{
|
||||
return rpmsg_send_offchannel_raw(ept, src, dst, data, len, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* rpmsg_init_ept - initialize rpmsg endpoint
|
||||
*
|
||||
* Initialize an RPMsg endpoint with a name, source address,
|
||||
* remoteproc address, endpoitn callback, and destroy endpoint callback.
|
||||
*
|
||||
* @ept: pointer to rpmsg endpoint
|
||||
* @name: service name associated to the endpoint
|
||||
* @src: local address of the endpoint
|
||||
* @dest: target address of the endpoint
|
||||
* @cb: endpoint callback
|
||||
* @ns_unbind_cb: end point service unbind callback, called when remote ept is
|
||||
* destroyed.
|
||||
*/
|
||||
static inline void rpmsg_init_ept(struct rpmsg_endpoint *ept,
|
||||
const char *name,
|
||||
uint32_t src, uint32_t dest,
|
||||
rpmsg_ept_cb cb,
|
||||
rpmsg_ns_unbind_cb ns_unbind_cb)
|
||||
{
|
||||
strncpy(ept->name, name, sizeof(ept->name));
|
||||
ept->addr = src;
|
||||
ept->dest_addr = dest;
|
||||
ept->cb = cb;
|
||||
ept->ns_unbind_cb = ns_unbind_cb;
|
||||
}
|
||||
|
||||
/**
|
||||
* rpmsg_create_ept - create rpmsg endpoint and register it to rpmsg device
|
||||
*
|
||||
* Create a RPMsg endpoint, initialize it with a name, source address,
|
||||
* remoteproc address, endpoitn callback, and destroy endpoint callback,
|
||||
* and register it to the RPMsg device.
|
||||
*
|
||||
* @ept: pointer to rpmsg endpoint
|
||||
* @name: service name associated to the endpoint
|
||||
* @src: local address of the endpoint
|
||||
* @dest: target address of the endpoint
|
||||
* @cb: endpoint callback
|
||||
* @ns_unbind_cb: end point service unbind callback, called when remote ept is
|
||||
* destroyed.
|
||||
*
|
||||
* In essence, an rpmsg endpoint represents a listener on the rpmsg bus, as
|
||||
* it binds an rpmsg address with an rx callback handler.
|
||||
*
|
||||
* Rpmsg client should create an endpoint to discuss with remote. rpmsg client
|
||||
* provide at least a channel name, a callback for message notification and by
|
||||
* default endpoint source address should be set to RPMSG_ADDR_ANY.
|
||||
*
|
||||
* As an option Some rpmsg clients can specify an endpoint with a specific
|
||||
* source address.
|
||||
*/
|
||||
|
||||
int rpmsg_create_ept(struct rpmsg_endpoint *ept, struct rpmsg_device *rdev,
|
||||
const char *name, uint32_t src, uint32_t dest,
|
||||
rpmsg_ept_cb cb, rpmsg_ns_unbind_cb ns_unbind_cb);
|
||||
|
||||
/**
|
||||
* rpmsg_destroy_ept - destroy rpmsg endpoint and unregister it from rpmsg
|
||||
* device
|
||||
*
|
||||
* @ept: pointer to the rpmsg endpoint
|
||||
*
|
||||
* It unregisters the rpmsg endpoint from the rpmsg device and calls the
|
||||
* destroy endpoint callback if it is provided.
|
||||
*/
|
||||
void rpmsg_destroy_ept(struct rpmsg_endpoint *ept);
|
||||
|
||||
/**
|
||||
* is_rpmsg_ept_ready - check if the rpmsg endpoint ready to send
|
||||
*
|
||||
* @ept: pointer to rpmsg endpoint
|
||||
*
|
||||
* Returns 1 if the rpmsg endpoint has both local addr and destination
|
||||
* addr set, 0 otherwise
|
||||
*/
|
||||
static inline unsigned int is_rpmsg_ept_ready(struct rpmsg_endpoint *ept)
|
||||
{
|
||||
return (ept->dest_addr != RPMSG_ADDR_ANY &&
|
||||
ept->addr != RPMSG_ADDR_ANY);
|
||||
}
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _RPMSG_H_ */
|
||||
119
source/OpenAMP/open-amp/lib/include/openamp/rpmsg_retarget.h
Normal file
119
source/OpenAMP/open-amp/lib/include/openamp/rpmsg_retarget.h
Normal file
@@ -0,0 +1,119 @@
|
||||
#ifndef RPMSG_RETARGET_H
|
||||
#define RPMSG_RETARGET_H
|
||||
|
||||
#include <metal/mutex.h>
|
||||
#include <openamp/open_amp.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* File Operations System call definitions */
|
||||
#define OPEN_SYSCALL_ID 0x1UL
|
||||
#define CLOSE_SYSCALL_ID 0x2UL
|
||||
#define WRITE_SYSCALL_ID 0x3UL
|
||||
#define READ_SYSCALL_ID 0x4UL
|
||||
#define ACK_STATUS_ID 0x5UL
|
||||
|
||||
#define TERM_SYSCALL_ID 0x6UL
|
||||
|
||||
#define DEFAULT_PROXY_ENDPOINT 0xFFUL
|
||||
|
||||
struct rpmsg_rpc_data;
|
||||
|
||||
typedef int (*rpmsg_rpc_poll)(void *arg);
|
||||
typedef void (*rpmsg_rpc_shutdown_cb)(struct rpmsg_rpc_data *rpc);
|
||||
|
||||
struct rpmsg_rpc_syscall_header {
|
||||
int32_t int_field1;
|
||||
int32_t int_field2;
|
||||
uint32_t data_len;
|
||||
};
|
||||
|
||||
struct rpmsg_rpc_syscall {
|
||||
uint32_t id;
|
||||
struct rpmsg_rpc_syscall_header args;
|
||||
};
|
||||
|
||||
struct rpmsg_rpc_data {
|
||||
struct rpmsg_endpoint ept;
|
||||
int ept_destroyed;
|
||||
atomic_int nacked;
|
||||
void *respbuf;
|
||||
size_t respbuf_len;
|
||||
rpmsg_rpc_poll poll;
|
||||
void *poll_arg;
|
||||
rpmsg_rpc_shutdown_cb shutdown_cb;
|
||||
metal_mutex_t lock;
|
||||
struct metal_spinlock buflock;
|
||||
};
|
||||
|
||||
/**
|
||||
* rpmsg_rpc_init - initialize RPMsg remote procedure call
|
||||
*
|
||||
* This function is to intialize the remote procedure call
|
||||
* global data. RPMsg RPC will send request to remote and
|
||||
* wait for callback.
|
||||
*
|
||||
* @rpc: pointer to the global remote procedure call data
|
||||
* @rdev: pointer to the rpmsg device
|
||||
* @ept_name: name of the endpoint used by RPC
|
||||
* @ept_addr: address of the endpoint used by RPC
|
||||
* @ept_raddr: remote address of the endpoint used by RPC
|
||||
* @poll_arg: pointer to poll function argument
|
||||
* @poll: poll function
|
||||
* @shutdown_cb: shutdown callback function
|
||||
*
|
||||
* return 0 for success, and negative value for failure.
|
||||
*/
|
||||
int rpmsg_rpc_init(struct rpmsg_rpc_data *rpc,
|
||||
struct rpmsg_device *rdev,
|
||||
const char *ept_name, uint32_t ept_addr,
|
||||
uint32_t ept_raddr,
|
||||
void *poll_arg, rpmsg_rpc_poll poll,
|
||||
rpmsg_rpc_shutdown_cb shutdown_cb);
|
||||
|
||||
/**
|
||||
* rpmsg_rpc_release - release RPMsg remote procedure call
|
||||
*
|
||||
* This function is to release remoteproc procedure call
|
||||
* global data.
|
||||
*
|
||||
* @rpc: pointer to the globacl remote procedure call
|
||||
*/
|
||||
void rpmsg_rpc_release(struct rpmsg_rpc_data *rpc);
|
||||
|
||||
/**
|
||||
* rpmsg_rpc_send - Request RPMsg RPC call
|
||||
*
|
||||
* This function sends RPC request it will return with the length
|
||||
* of data and the response buffer.
|
||||
*
|
||||
* @rpc: pointer to remoteproc procedure call data struct
|
||||
* @req: pointer to request buffer
|
||||
* @len: length of the request data
|
||||
* @resp: pointer to where store the response buffer
|
||||
* @resp_len: length of the response buffer
|
||||
*
|
||||
* return length of the received response, negative value for failure.
|
||||
*/
|
||||
int rpmsg_rpc_send(struct rpmsg_rpc_data *rpc,
|
||||
void *req, size_t len,
|
||||
void *resp, size_t resp_len);
|
||||
|
||||
/**
|
||||
* rpmsg_set_default_rpc - set default RPMsg RPC data
|
||||
*
|
||||
* The default RPC data is used to redirect standard C file operations
|
||||
* to RPMsg channels.
|
||||
*
|
||||
* @rpc: pointer to remoteproc procedure call data struct
|
||||
*/
|
||||
void rpmsg_set_default_rpc(struct rpmsg_rpc_data *rpc);
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* RPMSG_RETARGET_H */
|
||||
190
source/OpenAMP/open-amp/lib/include/openamp/rpmsg_virtio.h
Normal file
190
source/OpenAMP/open-amp/lib/include/openamp/rpmsg_virtio.h
Normal file
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* rpmsg based on virtio
|
||||
*
|
||||
* Copyright (C) 2018 Linaro, Inc.
|
||||
*
|
||||
* All rights reserved.
|
||||
* Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef _RPMSG_VIRTIO_H_
|
||||
#define _RPMSG_VIRTIO_H_
|
||||
|
||||
#include <metal/io.h>
|
||||
#include <metal/mutex.h>
|
||||
#include <openamp/rpmsg.h>
|
||||
#include <openamp/virtio.h>
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Configurable parameters */
|
||||
#ifndef RPMSG_BUFFER_SIZE
|
||||
#define RPMSG_BUFFER_SIZE (512)
|
||||
#endif
|
||||
|
||||
/* The feature bitmap for virtio rpmsg */
|
||||
#define VIRTIO_RPMSG_F_NS 0 /* RP supports name service notifications */
|
||||
|
||||
struct rpmsg_virtio_shm_pool;
|
||||
/**
|
||||
* struct rpmsg_virtio_shm_pool - shared memory pool used for rpmsg buffers
|
||||
* @get_buffer: function to get buffer from the pool
|
||||
* @base: base address of the memory pool
|
||||
* @avail: available memory size
|
||||
* @size: total pool size
|
||||
*/
|
||||
struct rpmsg_virtio_shm_pool {
|
||||
void *base;
|
||||
size_t avail;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct rpmsg_virtio_device - representation of a rpmsg device based on virtio
|
||||
* @rdev: rpmsg device, first property in the struct
|
||||
* @vdev: pointer to the virtio device
|
||||
* @rvq: pointer to receive virtqueue
|
||||
* @svq: pointer to send virtqueue
|
||||
* @shbuf_io: pointer to the shared buffer I/O region
|
||||
* @shpool: pointer to the shared buffers pool
|
||||
* @endpoints: list of endpoints.
|
||||
*/
|
||||
struct rpmsg_virtio_device {
|
||||
struct rpmsg_device rdev;
|
||||
struct virtio_device *vdev;
|
||||
struct virtqueue *rvq;
|
||||
struct virtqueue *svq;
|
||||
struct metal_io_region *shbuf_io;
|
||||
struct rpmsg_virtio_shm_pool *shpool;
|
||||
};
|
||||
|
||||
#define RPMSG_REMOTE VIRTIO_DEV_SLAVE
|
||||
#define RPMSG_MASTER VIRTIO_DEV_MASTER
|
||||
static inline unsigned int
|
||||
rpmsg_virtio_get_role(struct rpmsg_virtio_device *rvdev)
|
||||
{
|
||||
return rvdev->vdev->role;
|
||||
}
|
||||
|
||||
static inline void rpmsg_virtio_set_status(struct rpmsg_virtio_device *rvdev,
|
||||
uint8_t status)
|
||||
{
|
||||
rvdev->vdev->func->set_status(rvdev->vdev, status);
|
||||
}
|
||||
|
||||
static inline uint8_t rpmsg_virtio_get_status(struct rpmsg_virtio_device *rvdev)
|
||||
{
|
||||
return rvdev->vdev->func->get_status(rvdev->vdev);
|
||||
}
|
||||
|
||||
static inline uint32_t
|
||||
rpmsg_virtio_get_features(struct rpmsg_virtio_device *rvdev)
|
||||
{
|
||||
return rvdev->vdev->func->get_features(rvdev->vdev);
|
||||
}
|
||||
|
||||
static inline int
|
||||
rpmsg_virtio_create_virtqueues(struct rpmsg_virtio_device *rvdev,
|
||||
int flags, unsigned int nvqs,
|
||||
const char *names[],
|
||||
vq_callback * callbacks[])
|
||||
{
|
||||
return virtio_create_virtqueues(rvdev->vdev, flags, nvqs, names,
|
||||
callbacks);
|
||||
}
|
||||
|
||||
/**
|
||||
* rpmsg_virtio_get_buffer_size - get rpmsg virtio buffer size
|
||||
*
|
||||
* @rdev - pointer to the rpmsg device
|
||||
*
|
||||
* @return - next available buffer size for text, negative value for failure
|
||||
*/
|
||||
int rpmsg_virtio_get_buffer_size(struct rpmsg_device *rdev);
|
||||
|
||||
/**
|
||||
* rpmsg_init_vdev - initialize rpmsg virtio device
|
||||
* Master side:
|
||||
* Initialize RPMsg virtio queues and shared buffers, the address of shm can be
|
||||
* ANY. In this case, function will get shared memory from system shared memory
|
||||
* pools. If the vdev has RPMsg name service feature, this API will create an
|
||||
* name service endpoint.
|
||||
*
|
||||
* Slave side:
|
||||
* This API will not return until the driver ready is set by the master side.
|
||||
*
|
||||
* @param rvdev - pointer to the rpmsg virtio device
|
||||
* @param vdev - pointer to the virtio device
|
||||
* @param ns_bind_cb - callback handler for name service announcement without
|
||||
* local endpoints waiting to bind.
|
||||
* @param shm_io - pointer to the share memory I/O region.
|
||||
* @param shpool - pointer to shared memory pool. rpmsg_virtio_init_shm_pool has
|
||||
* to be called first to fill this structure.
|
||||
*
|
||||
* @return - status of function execution
|
||||
*/
|
||||
int rpmsg_init_vdev(struct rpmsg_virtio_device *rvdev,
|
||||
struct virtio_device *vdev,
|
||||
rpmsg_ns_bind_cb ns_bind_cb,
|
||||
struct metal_io_region *shm_io,
|
||||
struct rpmsg_virtio_shm_pool *shpool);
|
||||
|
||||
/**
|
||||
* rpmsg_deinit_vdev - deinitialize rpmsg virtio device
|
||||
*
|
||||
* @param rvdev - pointer to the rpmsg virtio device
|
||||
*/
|
||||
void rpmsg_deinit_vdev(struct rpmsg_virtio_device *rvdev);
|
||||
|
||||
/**
|
||||
* rpmsg_virtio_init_shm_pool - initialize default shared buffers pool
|
||||
*
|
||||
* RPMsg virtio has default shared buffers pool implementation.
|
||||
* The memory assigned to this pool will be dedicated to the RPMsg
|
||||
* virtio. This function has to be called before calling rpmsg_init_vdev,
|
||||
* to initialize the rpmsg_virtio_shm_pool structure.
|
||||
*
|
||||
* @param shpool - pointer to the shared buffers pool structure
|
||||
* @param shbuf - pointer to the beginning of shared buffers
|
||||
* @param size - shared buffers total size
|
||||
*/
|
||||
void rpmsg_virtio_init_shm_pool(struct rpmsg_virtio_shm_pool *shpool,
|
||||
void *shbuf, size_t size);
|
||||
|
||||
/**
|
||||
* rpmsg_virtio_get_rpmsg_device - get RPMsg device from RPMsg virtio device
|
||||
*
|
||||
* @param rvdev - pointer to RPMsg virtio device
|
||||
* @return - RPMsg device pointed by RPMsg virtio device
|
||||
*/
|
||||
static inline struct rpmsg_device *
|
||||
rpmsg_virtio_get_rpmsg_device(struct rpmsg_virtio_device *rvdev)
|
||||
{
|
||||
return &rvdev->rdev;
|
||||
}
|
||||
|
||||
/**
|
||||
* rpmsg_virtio_shm_pool_get_buffer - get buffer in the shared memory pool
|
||||
*
|
||||
* RPMsg virtio has default shared buffers pool implementation.
|
||||
* The memory assigned to this pool will be dedicated to the RPMsg
|
||||
* virtio. If you prefer to have other shared buffers allocation,
|
||||
* you can implement your rpmsg_virtio_shm_pool_get_buffer function.
|
||||
*
|
||||
* @param shpool - pointer to the shared buffers pool
|
||||
* @param size - shared buffers total size
|
||||
* @return - buffer pointer if free buffer is available, NULL otherwise.
|
||||
*/
|
||||
metal_weak void *
|
||||
rpmsg_virtio_shm_pool_get_buffer(struct rpmsg_virtio_shm_pool *shpool,
|
||||
size_t size);
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _RPMSG_VIRTIO_H_ */
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Mentor Graphics Corporation
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*/
|
||||
|
||||
#ifndef RSC_TABLE_PARSER_H
|
||||
#define RSC_TABLE_PARSER_H
|
||||
|
||||
#include <openamp/remoteproc.h>
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define RSC_TAB_SUPPORTED_VERSION 1
|
||||
#define RSC_TAB_HEADER_SIZE 12
|
||||
#define RSC_TAB_MAX_VRINGS 2
|
||||
|
||||
/* Standard control request handling. */
|
||||
typedef int (*rsc_handler) (struct remoteproc *rproc, void *rsc);
|
||||
|
||||
/**
|
||||
* handle_rsc_table
|
||||
*
|
||||
* This function parses resource table.
|
||||
*
|
||||
* @param rproc - pointer to remote remoteproc
|
||||
* @param rsc_table - resource table to parse
|
||||
* @param size - size of rsc table
|
||||
* @param io - pointer to the resource table I/O region
|
||||
* It can be NULL if the resource table
|
||||
* is in the local memory.
|
||||
*
|
||||
* @returns - execution status
|
||||
*
|
||||
*/
|
||||
int handle_rsc_table(struct remoteproc *rproc,
|
||||
struct resource_table *rsc_table, int len,
|
||||
struct metal_io_region *io);
|
||||
int handle_carve_out_rsc(struct remoteproc *rproc, void *rsc);
|
||||
int handle_trace_rsc(struct remoteproc *rproc, void *rsc);
|
||||
int handle_vdev_rsc(struct remoteproc *rproc, void *rsc);
|
||||
int handle_vendor_rsc(struct remoteproc *rproc, void *rsc);
|
||||
|
||||
/**
|
||||
* find_rsc
|
||||
*
|
||||
* find out location of a resource type in the resource table.
|
||||
*
|
||||
* @rsc_table - pointer to the resource table
|
||||
* @rsc_type - type of the resource
|
||||
* @index - index of the resource of the specified type
|
||||
*
|
||||
* return the offset to the resource on success, or 0 on failure
|
||||
*/
|
||||
size_t find_rsc(void *rsc_table, unsigned int rsc_type, unsigned int index);
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* RSC_TABLE_PARSER_H */
|
||||
176
source/OpenAMP/open-amp/lib/include/openamp/virtio.h
Normal file
176
source/OpenAMP/open-amp/lib/include/openamp/virtio.h
Normal file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef _VIRTIO_H_
|
||||
#define _VIRTIO_H_
|
||||
|
||||
#include <openamp/virtqueue.h>
|
||||
#include <metal/spinlock.h>
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* TODO: define this as compiler flags */
|
||||
#ifndef VIRTIO_MAX_NUM_VRINGS
|
||||
#define VIRTIO_MAX_NUM_VRINGS 2
|
||||
#endif
|
||||
|
||||
/* VirtIO device IDs. */
|
||||
#define VIRTIO_ID_NETWORK 0x01UL
|
||||
#define VIRTIO_ID_BLOCK 0x02UL
|
||||
#define VIRTIO_ID_CONSOLE 0x03UL
|
||||
#define VIRTIO_ID_ENTROPY 0x04UL
|
||||
#define VIRTIO_ID_BALLOON 0x05UL
|
||||
#define VIRTIO_ID_IOMEMORY 0x06UL
|
||||
#define VIRTIO_ID_RPMSG 0x07UL /* remote processor messaging */
|
||||
#define VIRTIO_ID_SCSI 0x08UL
|
||||
#define VIRTIO_ID_9P 0x09UL
|
||||
#define VIRTIO_DEV_ANY_ID (-1)UL
|
||||
|
||||
/* Status byte for guest to report progress. */
|
||||
#define VIRTIO_CONFIG_STATUS_ACK 0x01
|
||||
#define VIRTIO_CONFIG_STATUS_DRIVER 0x02
|
||||
#define VIRTIO_CONFIG_STATUS_DRIVER_OK 0x04
|
||||
#define VIRTIO_CONFIG_STATUS_NEEDS_RESET 0x40
|
||||
#define VIRTIO_CONFIG_STATUS_FAILED 0x80
|
||||
|
||||
/* Virtio device role */
|
||||
#define VIRTIO_DEV_MASTER 0UL
|
||||
#define VIRTIO_DEV_SLAVE 1UL
|
||||
|
||||
struct virtio_device_id {
|
||||
uint32_t device;
|
||||
uint32_t vendor;
|
||||
};
|
||||
|
||||
/*
|
||||
* Generate interrupt when the virtqueue ring is
|
||||
* completely used, even if we've suppressed them.
|
||||
*/
|
||||
#define VIRTIO_F_NOTIFY_ON_EMPTY (1 << 24)
|
||||
|
||||
/*
|
||||
* The guest should never negotiate this feature; it
|
||||
* is used to detect faulty drivers.
|
||||
*/
|
||||
#define VIRTIO_F_BAD_FEATURE (1 << 30)
|
||||
|
||||
/*
|
||||
* Some VirtIO feature bits (currently bits 28 through 31) are
|
||||
* reserved for the transport being used (eg. virtio_ring), the
|
||||
* rest are per-device feature bits.
|
||||
*/
|
||||
#define VIRTIO_TRANSPORT_F_START 28
|
||||
#define VIRTIO_TRANSPORT_F_END 32
|
||||
|
||||
typedef void (*virtio_dev_reset_cb)(struct virtio_device *vdev);
|
||||
|
||||
struct virtio_dispatch;
|
||||
|
||||
struct virtio_feature_desc {
|
||||
uint32_t vfd_val;
|
||||
const char *vfd_str;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct proc_shm
|
||||
*
|
||||
* This structure is maintained by hardware interface layer for
|
||||
* shared memory information. The shared memory provides buffers
|
||||
* for use by the vring to exchange messages between the cores.
|
||||
*
|
||||
*/
|
||||
struct virtio_buffer_info {
|
||||
/* Start address of shared memory used for buffers. */
|
||||
void *vaddr;
|
||||
/* Start physical address of shared memory used for buffers. */
|
||||
metal_phys_addr_t paddr;
|
||||
/* sharmed memory I/O region */
|
||||
struct metal_io_region *io;
|
||||
/* Size of shared memory. */
|
||||
unsigned long size;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct remoteproc_vring - remoteproc vring structure
|
||||
* @vq virtio queue
|
||||
* @va logical address
|
||||
* @notifyid vring notify id
|
||||
* @num_descs number of descriptors
|
||||
* @align vring alignment
|
||||
* @io metal I/O region of the vring memory, can be NULL
|
||||
*/
|
||||
struct virtio_vring_info {
|
||||
struct virtqueue *vq;
|
||||
struct vring_alloc_info info;
|
||||
uint32_t notifyid;
|
||||
struct metal_io_region *io;
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure definition for virtio devices for use by the
|
||||
* applications/drivers
|
||||
*/
|
||||
|
||||
struct virtio_device {
|
||||
uint32_t index; /**< unique position on the virtio bus */
|
||||
struct virtio_device_id id; /**< the device type identification
|
||||
* (used to match it with a driver
|
||||
*/
|
||||
uint64_t features; /**< the features supported by both ends. */
|
||||
unsigned int role; /**< if it is virtio backend or front end. */
|
||||
virtio_dev_reset_cb reset_cb; /**< user registered device callback */
|
||||
const struct virtio_dispatch *func; /**< Virtio dispatch table */
|
||||
void *priv; /**< TODO: remove pointer to virtio_device private data */
|
||||
unsigned int vrings_num; /**< number of vrings */
|
||||
struct virtio_vring_info *vrings_info;
|
||||
};
|
||||
|
||||
/*
|
||||
* Helper functions.
|
||||
*/
|
||||
const char *virtio_dev_name(uint16_t devid);
|
||||
void virtio_describe(struct virtio_device *dev, const char *msg,
|
||||
uint32_t features,
|
||||
struct virtio_feature_desc *feature_desc);
|
||||
|
||||
/*
|
||||
* Functions for virtio device configuration as defined in Rusty Russell's
|
||||
* paper.
|
||||
* Drivers are expected to implement these functions in their respective codes.
|
||||
*/
|
||||
|
||||
struct virtio_dispatch {
|
||||
uint8_t (*get_status)(struct virtio_device *dev);
|
||||
void (*set_status)(struct virtio_device *dev, uint8_t status);
|
||||
uint32_t (*get_features)(struct virtio_device *dev);
|
||||
void (*set_features)(struct virtio_device *dev, uint32_t feature);
|
||||
uint32_t (*negotiate_features)(struct virtio_device *dev,
|
||||
uint32_t features);
|
||||
|
||||
/*
|
||||
* Read/write a variable amount from the device specific (ie, network)
|
||||
* configuration region. This region is encoded in the same endian as
|
||||
* the guest.
|
||||
*/
|
||||
void (*read_config)(struct virtio_device *dev, uint32_t offset,
|
||||
void *dst, int length);
|
||||
void (*write_config)(struct virtio_device *dev, uint32_t offset,
|
||||
void *src, int length);
|
||||
void (*reset_device)(struct virtio_device *dev);
|
||||
void (*notify)(struct virtqueue *vq);
|
||||
};
|
||||
|
||||
int virtio_create_virtqueues(struct virtio_device *vdev, unsigned int flags,
|
||||
unsigned int nvqs, const char *names[],
|
||||
vq_callback *callbacks[]);
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* _VIRTIO_H_ */
|
||||
152
source/OpenAMP/open-amp/lib/include/openamp/virtio_ring.h
Normal file
152
source/OpenAMP/open-amp/lib/include/openamp/virtio_ring.h
Normal file
@@ -0,0 +1,152 @@
|
||||
/*
|
||||
* Copyright Rusty Russell IBM Corporation 2007.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-3-Clause
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#ifndef VIRTIO_RING_H
|
||||
#define VIRTIO_RING_H
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* This marks a buffer as continuing via the next field. */
|
||||
#define VRING_DESC_F_NEXT 1
|
||||
/* This marks a buffer as write-only (otherwise read-only). */
|
||||
#define VRING_DESC_F_WRITE 2
|
||||
/* This means the buffer contains a list of buffer descriptors. */
|
||||
#define VRING_DESC_F_INDIRECT 4
|
||||
|
||||
/* The Host uses this in used->flags to advise the Guest: don't kick me
|
||||
* when you add a buffer. It's unreliable, so it's simply an
|
||||
* optimization. Guest will still kick if it's out of buffers.
|
||||
*/
|
||||
#define VRING_USED_F_NO_NOTIFY 1
|
||||
/* The Guest uses this in avail->flags to advise the Host: don't
|
||||
* interrupt me when you consume a buffer. It's unreliable, so it's
|
||||
* simply an optimization.
|
||||
*/
|
||||
#define VRING_AVAIL_F_NO_INTERRUPT 1
|
||||
|
||||
/* VirtIO ring descriptors: 16 bytes.
|
||||
* These can chain together via "next".
|
||||
*/
|
||||
struct vring_desc {
|
||||
/* Address (guest-physical). */
|
||||
uint64_t addr;
|
||||
/* Length. */
|
||||
uint32_t len;
|
||||
/* The flags as indicated above. */
|
||||
uint16_t flags;
|
||||
/* We chain unused descriptors via this, too. */
|
||||
uint16_t next;
|
||||
};
|
||||
|
||||
struct vring_avail {
|
||||
uint16_t flags;
|
||||
uint16_t idx;
|
||||
uint16_t ring[0];
|
||||
};
|
||||
|
||||
/* uint32_t is used here for ids for padding reasons. */
|
||||
struct vring_used_elem {
|
||||
/* Index of start of used descriptor chain. */
|
||||
uint32_t id;
|
||||
/* Total length of the descriptor chain which was written to. */
|
||||
uint32_t len;
|
||||
};
|
||||
|
||||
struct vring_used {
|
||||
uint16_t flags;
|
||||
uint16_t idx;
|
||||
struct vring_used_elem ring[0];
|
||||
};
|
||||
|
||||
struct vring {
|
||||
unsigned int num;
|
||||
|
||||
struct vring_desc *desc;
|
||||
struct vring_avail *avail;
|
||||
struct vring_used *used;
|
||||
};
|
||||
|
||||
/* The standard layout for the ring is a continuous chunk of memory which
|
||||
* looks like this. We assume num is a power of 2.
|
||||
*
|
||||
* struct vring {
|
||||
* // The actual descriptors (16 bytes each)
|
||||
* struct vring_desc desc[num];
|
||||
*
|
||||
* // A ring of available descriptor heads with free-running index.
|
||||
* __u16 avail_flags;
|
||||
* __u16 avail_idx;
|
||||
* __u16 available[num];
|
||||
* __u16 used_event_idx;
|
||||
*
|
||||
* // Padding to the next align boundary.
|
||||
* char pad[];
|
||||
*
|
||||
* // A ring of used descriptor heads with free-running index.
|
||||
* __u16 used_flags;
|
||||
* __u16 used_idx;
|
||||
* struct vring_used_elem used[num];
|
||||
* __u16 avail_event_idx;
|
||||
* };
|
||||
*
|
||||
* NOTE: for VirtIO PCI, align is 4096.
|
||||
*/
|
||||
|
||||
/*
|
||||
* We publish the used event index at the end of the available ring, and vice
|
||||
* versa. They are at the end for backwards compatibility.
|
||||
*/
|
||||
#define vring_used_event(vr) ((vr)->avail->ring[(vr)->num])
|
||||
#define vring_avail_event(vr) ((vr)->used->ring[(vr)->num].id & 0xFFFF)
|
||||
|
||||
static inline int vring_size(unsigned int num, unsigned long align)
|
||||
{
|
||||
int size;
|
||||
|
||||
size = num * sizeof(struct vring_desc);
|
||||
size += sizeof(struct vring_avail) + (num * sizeof(uint16_t)) +
|
||||
sizeof(uint16_t);
|
||||
size = (size + align - 1) & ~(align - 1);
|
||||
size += sizeof(struct vring_used) +
|
||||
(num * sizeof(struct vring_used_elem)) + sizeof(uint16_t);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
static inline void
|
||||
vring_init(struct vring *vr, unsigned int num, uint8_t *p, unsigned long align)
|
||||
{
|
||||
vr->num = num;
|
||||
vr->desc = (struct vring_desc *)p;
|
||||
vr->avail = (struct vring_avail *)(p + num * sizeof(struct vring_desc));
|
||||
vr->used = (struct vring_used *)
|
||||
(((unsigned long)&vr->avail->ring[num] + sizeof(uint16_t) +
|
||||
align - 1) & ~(align - 1));
|
||||
}
|
||||
|
||||
/*
|
||||
* The following is used with VIRTIO_RING_F_EVENT_IDX.
|
||||
*
|
||||
* Assuming a given event_idx value from the other size, if we have
|
||||
* just incremented index from old to new_idx, should we trigger an
|
||||
* event?
|
||||
*/
|
||||
static inline int
|
||||
vring_need_event(uint16_t event_idx, uint16_t new_idx, uint16_t old)
|
||||
{
|
||||
return (uint16_t)(new_idx - event_idx - 1) <
|
||||
(uint16_t)(new_idx - old);
|
||||
}
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* VIRTIO_RING_H */
|
||||
236
source/OpenAMP/open-amp/lib/include/openamp/virtqueue.h
Normal file
236
source/OpenAMP/open-amp/lib/include/openamp/virtqueue.h
Normal file
@@ -0,0 +1,236 @@
|
||||
#ifndef VIRTQUEUE_H_
|
||||
#define VIRTQUEUE_H_
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2011, Bryan Venteicher <bryanv@FreeBSD.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#if defined __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef uint8_t boolean;
|
||||
|
||||
#include <openamp/virtio_ring.h>
|
||||
#include <metal/alloc.h>
|
||||
#include <metal/io.h>
|
||||
|
||||
/*Error Codes*/
|
||||
#define VQ_ERROR_BASE -3000
|
||||
#define ERROR_VRING_FULL (VQ_ERROR_BASE - 1)
|
||||
#define ERROR_INVLD_DESC_IDX (VQ_ERROR_BASE - 2)
|
||||
#define ERROR_EMPTY_RING (VQ_ERROR_BASE - 3)
|
||||
#define ERROR_NO_MEM (VQ_ERROR_BASE - 4)
|
||||
#define ERROR_VRING_MAX_DESC (VQ_ERROR_BASE - 5)
|
||||
#define ERROR_VRING_ALIGN (VQ_ERROR_BASE - 6)
|
||||
#define ERROR_VRING_NO_BUFF (VQ_ERROR_BASE - 7)
|
||||
#define ERROR_VQUEUE_INVLD_PARAM (VQ_ERROR_BASE - 8)
|
||||
|
||||
#define VQUEUE_SUCCESS 0
|
||||
|
||||
/* The maximum virtqueue size is 2^15. Use that value as the end of
|
||||
* descriptor chain terminator since it will never be a valid index
|
||||
* in the descriptor table. This is used to verify we are correctly
|
||||
* handling vq_free_cnt.
|
||||
*/
|
||||
#define VQ_RING_DESC_CHAIN_END 32768
|
||||
#define VIRTQUEUE_FLAG_INDIRECT 0x0001
|
||||
#define VIRTQUEUE_FLAG_EVENT_IDX 0x0002
|
||||
#define VIRTQUEUE_MAX_NAME_SZ 32
|
||||
|
||||
/* Support for indirect buffer descriptors. */
|
||||
#define VIRTIO_RING_F_INDIRECT_DESC (1 << 28)
|
||||
|
||||
/* Support to suppress interrupt until specific index is reached. */
|
||||
#define VIRTIO_RING_F_EVENT_IDX (1 << 29)
|
||||
|
||||
struct virtqueue_buf {
|
||||
void *buf;
|
||||
int len;
|
||||
};
|
||||
|
||||
struct virtqueue {
|
||||
struct virtio_device *vq_dev;
|
||||
const char *vq_name;
|
||||
uint16_t vq_queue_index;
|
||||
uint16_t vq_nentries;
|
||||
uint32_t vq_flags;
|
||||
void (*callback)(struct virtqueue *vq);
|
||||
void (*notify)(struct virtqueue *vq);
|
||||
struct vring vq_ring;
|
||||
uint16_t vq_free_cnt;
|
||||
uint16_t vq_queued_cnt;
|
||||
void *shm_io; /* opaque pointer to data needed to allow v2p & p2v */
|
||||
|
||||
/*
|
||||
* Head of the free chain in the descriptor table. If
|
||||
* there are no free descriptors, this will be set to
|
||||
* VQ_RING_DESC_CHAIN_END.
|
||||
*/
|
||||
uint16_t vq_desc_head_idx;
|
||||
|
||||
/*
|
||||
* Last consumed descriptor in the used table,
|
||||
* trails vq_ring.used->idx.
|
||||
*/
|
||||
uint16_t vq_used_cons_idx;
|
||||
|
||||
/*
|
||||
* Last consumed descriptor in the available table -
|
||||
* used by the consumer side.
|
||||
*/
|
||||
uint16_t vq_available_idx;
|
||||
|
||||
#ifdef VQUEUE_DEBUG
|
||||
boolean vq_inuse;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Used by the host side during callback. Cookie
|
||||
* holds the address of buffer received from other side.
|
||||
* Other fields in this structure are not used currently.
|
||||
*/
|
||||
|
||||
struct vq_desc_extra {
|
||||
void *cookie;
|
||||
uint16_t ndescs;
|
||||
} vq_descx[0];
|
||||
};
|
||||
|
||||
/* struct to hold vring specific information */
|
||||
struct vring_alloc_info {
|
||||
void *vaddr;
|
||||
uint32_t align;
|
||||
uint16_t num_descs;
|
||||
uint16_t pad;
|
||||
};
|
||||
|
||||
typedef void vq_callback(struct virtqueue *);
|
||||
typedef void vq_notify(struct virtqueue *);
|
||||
|
||||
#ifdef VQUEUE_DEBUG
|
||||
#include <metal/log.h>
|
||||
#include <metal/assert.h>
|
||||
|
||||
#define VQASSERT(_vq, _exp, _msg) \
|
||||
do { \
|
||||
if (!(_exp)) { \
|
||||
metal_log(METAL_LOG_EMERGENCY, \
|
||||
"%s: %s - _msg", __func__, (_vq)->vq_name); \
|
||||
metal_assert(_exp); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define VQ_RING_ASSERT_VALID_IDX(_vq, _idx) \
|
||||
VQASSERT((_vq), (_idx) < (_vq)->vq_nentries, "invalid ring index")
|
||||
|
||||
#define VQ_RING_ASSERT_CHAIN_TERM(_vq) \
|
||||
VQASSERT((_vq), (_vq)->vq_desc_head_idx == \
|
||||
VQ_RING_DESC_CHAIN_END, \
|
||||
"full ring terminated incorrectly: invalid head")
|
||||
|
||||
#define VQ_PARAM_CHK(condition, status_var, status_err) \
|
||||
do { \
|
||||
if (((status_var) == 0) && (condition)) { \
|
||||
status_var = status_err; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define VQUEUE_BUSY(vq) \
|
||||
do { \
|
||||
if (!(vq)->vq_inuse) \
|
||||
(vq)->vq_inuse = true; \
|
||||
else \
|
||||
VQASSERT(vq, !(vq)->vq_inuse,\
|
||||
"VirtQueue already in use") \
|
||||
} while (0)
|
||||
|
||||
#define VQUEUE_IDLE(vq) ((vq)->vq_inuse = false)
|
||||
|
||||
#else
|
||||
|
||||
#define KASSERT(cond, str)
|
||||
#define VQASSERT(_vq, _exp, _msg)
|
||||
#define VQ_RING_ASSERT_VALID_IDX(_vq, _idx)
|
||||
#define VQ_RING_ASSERT_CHAIN_TERM(_vq)
|
||||
#define VQ_PARAM_CHK(condition, status_var, status_err)
|
||||
#define VQUEUE_BUSY(vq)
|
||||
#define VQUEUE_IDLE(vq)
|
||||
|
||||
#endif
|
||||
|
||||
int virtqueue_create(struct virtio_device *device, unsigned short id,
|
||||
const char *name, struct vring_alloc_info *ring,
|
||||
void (*callback)(struct virtqueue *vq),
|
||||
void (*notify)(struct virtqueue *vq),
|
||||
struct virtqueue *v_queue);
|
||||
|
||||
/*
|
||||
* virtqueue_set_shmem_io
|
||||
*
|
||||
* set virtqueue shared memory I/O region
|
||||
*
|
||||
* @vq - virt queue
|
||||
* @io - pointer to the shared memory I/O region
|
||||
*/
|
||||
static inline void virtqueue_set_shmem_io(struct virtqueue *vq,
|
||||
struct metal_io_region *io)
|
||||
{
|
||||
vq->shm_io = io;
|
||||
}
|
||||
|
||||
int virtqueue_add_buffer(struct virtqueue *vq, struct virtqueue_buf *buf_list,
|
||||
int readable, int writable, void *cookie);
|
||||
|
||||
void *virtqueue_get_buffer(struct virtqueue *vq, uint32_t *len, uint16_t *idx);
|
||||
|
||||
void *virtqueue_get_available_buffer(struct virtqueue *vq, uint16_t *avail_idx,
|
||||
uint32_t *len);
|
||||
|
||||
int virtqueue_add_consumed_buffer(struct virtqueue *vq, uint16_t head_idx,
|
||||
uint32_t len);
|
||||
|
||||
void virtqueue_disable_cb(struct virtqueue *vq);
|
||||
|
||||
int virtqueue_enable_cb(struct virtqueue *vq);
|
||||
|
||||
void virtqueue_kick(struct virtqueue *vq);
|
||||
|
||||
static inline struct virtqueue *virtqueue_allocate(unsigned int num_desc_extra)
|
||||
{
|
||||
struct virtqueue *vqs;
|
||||
uint32_t vq_size = sizeof(struct virtqueue) +
|
||||
num_desc_extra * sizeof(struct vq_desc_extra);
|
||||
|
||||
vqs = (struct virtqueue *)metal_allocate_memory(vq_size);
|
||||
|
||||
if (vqs) {
|
||||
memset(vqs, 0x00, vq_size);
|
||||
}
|
||||
|
||||
return vqs;
|
||||
}
|
||||
|
||||
void virtqueue_free(struct virtqueue *vq);
|
||||
|
||||
void virtqueue_dump(struct virtqueue *vq);
|
||||
|
||||
void virtqueue_notification(struct virtqueue *vq);
|
||||
|
||||
uint32_t virtqueue_get_desc_size(struct virtqueue *vq);
|
||||
|
||||
uint32_t virtqueue_get_buffer_length(struct virtqueue *vq, uint16_t idx);
|
||||
|
||||
#if defined __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* VIRTQUEUE_H_ */
|
||||
Reference in New Issue
Block a user