blob: 7ec20a6b63e6e3f9a4d9e379e8cbbf3a8d5ef303 [file] [log] [blame]
/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
* only version 2 as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
#ifndef VCM_TYPES_H
#define VCM_TYPES_H
#include <linux/device.h>
#include <linux/types.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/genalloc.h>
#include <linux/list.h>
/*
* Reservation Attributes
*
* Used in vcm_reserve(), vcm_reserve_at(), vcm_set_res_attr() and
* vcm_reserve_bound().
*
* VCM_READ Specifies that the reservation can be read.
* VCM_WRITE Specifies that the reservation can be written.
* VCM_EXECUTE Specifies that the reservation can be executed.
* VCM_USER Specifies that this reservation is used for
* userspace access.
* VCM_SUPERVISOR Specifies that this reservation is used for
* supervisor access.
* VCM_SECURE Specifies that the target of the reservation is
* secure. The usage of this setting is TBD.
*
* Caching behavior as a 4 bit field:
* VCM_NOTCACHED The VCM region is not cached.
* VCM_INNER_WB_WA The VCM region is inner cached
* and is write-back and write-allocate.
* VCM_INNER_WT_NWA The VCM region is inner cached and is
* write-through and no-write-allocate.
* VCM_INNER_WB_NWA The VCM region is inner cached and is
* write-back and no-write-allocate.
* VCM_OUTER_WB_WA The VCM region is outer cached and is
* write-back and write-allocate.
* VCM_OUTER_WT_NWA The VCM region is outer cached and is
* write-through and no-write-allocate.
* VCM_OUTER_WB_NWA The VCM region is outer cached and is
* write-back and no-write-allocate.
* VCM_WB_WA The VCM region is cached and is write
* -back and write-allocate.
* VCM_WT_NWA The VCM region is cached and is write
* -through and no-write-allocate.
* VCM_WB_NWA The VCM region is cached and is write
* -back and no-write-allocate.
*/
/* Order of alignment (power of 2). Ie, 12 = 4k, 13 = 8k, 14 = 16k
* Alignments of less than 1MB on buffers of size 1MB or greater should be
* avoided. Alignments of less than 64KB on buffers of size 64KB or greater
* should be avoided. Strictly speaking, it will work, but will result in
* suboptimal performance, and a warning will be printed to that effect if
* VCM_PERF_WARN is enabled.
*/
#define VCM_ALIGN_SHIFT 10
#define VCM_ALIGN_MASK 0x1F
#define VCM_ALIGN_ATTR(order) (((order) & VCM_ALIGN_MASK) << VCM_ALIGN_SHIFT)
#define VCM_ALIGN_DEFAULT 0
#define VCM_ALIGN_4K (VCM_ALIGN_ATTR(12))
#define VCM_ALIGN_8K (VCM_ALIGN_ATTR(13))
#define VCM_ALIGN_16K (VCM_ALIGN_ATTR(14))
#define VCM_ALIGN_32K (VCM_ALIGN_ATTR(15))
#define VCM_ALIGN_64K (VCM_ALIGN_ATTR(16))
#define VCM_ALIGN_128K (VCM_ALIGN_ATTR(17))
#define VCM_ALIGN_256K (VCM_ALIGN_ATTR(18))
#define VCM_ALIGN_512K (VCM_ALIGN_ATTR(19))
#define VCM_ALIGN_1M (VCM_ALIGN_ATTR(20))
#define VCM_ALIGN_2M (VCM_ALIGN_ATTR(21))
#define VCM_ALIGN_4M (VCM_ALIGN_ATTR(22))
#define VCM_ALIGN_8M (VCM_ALIGN_ATTR(23))
#define VCM_ALIGN_16M (VCM_ALIGN_ATTR(24))
#define VCM_ALIGN_32M (VCM_ALIGN_ATTR(25))
#define VCM_ALIGN_64M (VCM_ALIGN_ATTR(26))
#define VCM_ALIGN_128M (VCM_ALIGN_ATTR(27))
#define VCM_ALIGN_256M (VCM_ALIGN_ATTR(28))
#define VCM_ALIGN_512M (VCM_ALIGN_ATTR(29))
#define VCM_ALIGN_1GB (VCM_ALIGN_ATTR(30))
#define VCM_CACHE_POLICY (0xF << 0)
#define VCM_READ (1UL << 9)
#define VCM_WRITE (1UL << 8)
#define VCM_EXECUTE (1UL << 7)
#define VCM_USER (1UL << 6)
#define VCM_SUPERVISOR (1UL << 5)
#define VCM_SECURE (1UL << 4)
#define VCM_NOTCACHED (0UL << 0)
#define VCM_WB_WA (1UL << 0)
#define VCM_WB_NWA (2UL << 0)
#define VCM_WT (3UL << 0)
/*
* Physical Allocation Attributes
*
* Used in vcm_phys_alloc().
*
* Alignment as a power of 2 starting at 4 KB. 5 bit field.
* 1 = 4KB, 2 = 8KB, etc.
*
* Specifies that the reservation should have the
* alignment specified.
*
* VCM_4KB Specifies that the reservation should use 4KB pages.
* VCM_64KB Specifies that the reservation should use 64KB pages.
* VCM_1MB specifies that the reservation should use 1MB pages.
* VCM_ALL Specifies that the reservation should use all
* available page sizes.
* VCM_PHYS_CONT Specifies that a reservation should be backed with
* physically contiguous memory.
* VCM_COHERENT Specifies that the reservation must be kept coherent
* because it's shared.
*/
#define VCM_4KB (1UL << 5)
#define VCM_64KB (1UL << 4)
#define VCM_1MB (1UL << 3)
#define VCM_ALL (1UL << 2)
#define VCM_PAGE_SEL_MASK (0xFUL << 2)
#define VCM_PHYS_CONT (1UL << 1)
#define VCM_COHERENT (1UL << 0)
#define SHIFT_4KB (12)
#define ALIGN_REQ_BYTES(attr) (1UL << (((attr & VCM_ALIGNMENT_MASK) >> 6) + 12))
/* set the alignment in pow 2, 0 = 4KB */
#define SET_ALIGN_REQ_BYTES(attr, align) \
((attr & ~VCM_ALIGNMENT_MASK) | ((align << 6) & VCM_ALIGNMENT_MASK))
/*
* Association Attributes
*
* Used in vcm_assoc(), vcm_set_assoc_attr().
*
* VCM_USE_LOW_BASE Use the low base register.
* VCM_USE_HIGH_BASE Use the high base register.
*
* VCM_SPLIT A 5 bit field that defines the
* high/low split. This value defines
* the number of 0's left-filled into the
* split register. Addresses that match
* this will use VCM_USE_LOW_BASE
* otherwise they'll use
* VCM_USE_HIGH_BASE. An all 0's value
* directs all translations to
* VCM_USE_LOW_BASE.
*/
#define VCM_SPLIT (1UL << 3)
#define VCM_USE_LOW_BASE (1UL << 2)
#define VCM_USE_HIGH_BASE (1UL << 1)
/*
* External VCMs
*
* Used in vcm_create_from_prebuilt()
*
* Externally created VCM IDs for creating kernel and user space
* mappings to VCMs and kernel and user space buffers out of
* VCM_MEMTYPE_0,1,2, etc.
*
*/
#define VCM_PREBUILT_KERNEL 1
#define VCM_PREBUILT_USER 2
/**
* enum memtarget_t - A logical location in a VCM.
* @VCM_START: Indicates the start of a VCM_REGION.
*/
enum memtarget_t {
VCM_START
};
/**
* enum memtype_t - A logical location in a VCM.
* @VCM_MEMTYPE_0: Generic memory type 0
* @VCM_MEMTYPE_1: Generic memory type 1
* @VCM_MEMTYPE_2: Generic memory type 2
*
* A memtype encapsulates a platform specific memory arrangement. The
* memtype needn't refer to a single type of memory, it can refer to a
* set of memories that can back a reservation.
*
*/
enum memtype_t {
VCM_MEMTYPE_0 = 0,
VCM_MEMTYPE_1 = 1,
VCM_MEMTYPE_2 = 2,
VCM_MEMTYPE_3 = 3,
VCM_INVALID = 4,
};
/**
* vcm_handler - The signature of the fault hook.
* @dev: The device id of the faulting device.
* @data: The generic data pointer.
* @fault_data: System specific common fault data.
*
* The handler should return 0 for success. This indicates that the
* fault was handled. A non-zero return value is an error and will be
* propagated up the stack.
*/
typedef int (*vcm_handler)(struct device *dev, void *data, void *fault_data);
/**
* enum vcm_type - The type of VCM.
* @VCM_DEVICE: VCM used for device mappings
* @VCM_EXT_KERNEL: VCM used for kernel-side mappings
* @VCM_EXT_USER: VCM used for userspace mappings
* @VCM_ONE_TO_ONE: VCM used for devices without SMMUs
*
*/
enum vcm_type {
VCM_DEVICE,
VCM_EXT_KERNEL,
VCM_EXT_USER,
VCM_ONE_TO_ONE,
};
/**
* struct vcm - A Virtually Contiguous Memory region.
* @start_addr: The starting address of the VCM region.
* @len: The len of the VCM region. This must be at least
* vcm_min() bytes.
*/
struct vcm {
/* public */
unsigned long start_addr;
size_t len;
/* private */
enum vcm_type type;
struct device *dev; /* opaque device control */
struct iommu_domain *domain;
/* allocator dependent */
struct gen_pool *pool;
struct list_head res_head;
/* this will be a very short list */
struct list_head assoc_head;
};
/**
* struct avcm - A VCM to device association
* @vcm: The VCM region of interest.
* @dev: The device to associate the VCM with.
* @attr: See 'Association Attributes'.
*/
struct avcm {
/* public */
struct vcm *vcm;
struct device *dev;
u32 attr;
/* private */
struct list_head assoc_elm;
int is_active; /* is this particular association active */
};
/**
* struct bound - A boundary to reserve from in a VCM region.
* @vcm: The VCM that needs a bound.
* @len: The len of the bound.
*/
struct bound {
struct vcm *vcm;
size_t len;
};
struct phys_chunk {
struct list_head list;
struct list_head allocated; /* used to record is allocated */
struct list_head refers_to;
phys_addr_t pa;
int pool_idx;
int size;
};
/**
* struct physmem - A physical memory allocation.
* @memtype: The memory type of the VCM region.
* @len: The len of the physical memory allocation.
* @attr: See 'Physical Allocation Attributes'.
*/
struct physmem {
/* public */
enum memtype_t memtype;
size_t len;
u32 attr;
/* private */
struct phys_chunk alloc_head;
/* if the physmem is cont then use the built in VCM */
int is_cont;
struct res *res;
};
/**
* struct res - A reservation in a VCM region.
* @vcm: The VCM region to reserve from.
* @len: The length of the reservation. Must be at least
* vcm_min() bytes.
* @attr: See 'Reservation Attributes'.
* @dev_addr: The device-side address.
*/
struct res {
/* public */
struct vcm *vcm;
size_t len;
u32 attr;
unsigned long dev_addr;
/* private */
struct physmem *physmem;
/* allocator dependent */
size_t alignment_req;
size_t aligned_len;
unsigned long ptr;
struct list_head res_elm;
/* type VCM_EXT_KERNEL */
struct vm_struct *vm_area;
int mapped;
};
#endif /* VCM_TYPES_H */