Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/x86/linux-2.6-x86: (77 commits) x86: UV startup of slave cpus x86: integrate pci-dma.c x86: don't do dma if mask is NULL. x86: return conditional to mmu x86: remove kludge from x86_64 x86: unify gfp masks x86: retry allocation if failed x86: don't try to allocate from DMA zone at first x86: use a fallback dev for i386 x86: use numa allocation function in i386 x86: remove virt_to_bus in pci-dma_64.c x86: adjust dma_free_coherent for i386 x86: move bad_dma_address x86: isolate coherent mapping functions x86: move dma_coherent functions to pci-dma.c x86: merge iommu initialization parameters x86: merge dma_supported x86: move pci fixup to pci-dma.c x86: move x86_64-specific to common code. x86: move initialization functions to pci-dma.c ...
This commit is contained in:
commit
5f033bb9bc
107 changed files with 1577 additions and 1117 deletions
|
|
@ -17,4 +17,12 @@
|
|||
+ (CONFIG_PHYSICAL_ALIGN - 1)) \
|
||||
& ~(CONFIG_PHYSICAL_ALIGN - 1))
|
||||
|
||||
#ifdef CONFIG_X86_64
|
||||
#define BOOT_HEAP_SIZE 0x7000
|
||||
#define BOOT_STACK_SIZE 0x4000
|
||||
#else
|
||||
#define BOOT_HEAP_SIZE 0x4000
|
||||
#define BOOT_STACK_SIZE 0x1000
|
||||
#endif
|
||||
|
||||
#endif /* _ASM_BOOT_H */
|
||||
|
|
|
|||
|
|
@ -1,5 +1,237 @@
|
|||
#ifndef _ASM_DMA_MAPPING_H_
|
||||
#define _ASM_DMA_MAPPING_H_
|
||||
|
||||
/*
|
||||
* IOMMU interface. See Documentation/DMA-mapping.txt and DMA-API.txt for
|
||||
* documentation.
|
||||
*/
|
||||
|
||||
#include <linux/scatterlist.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/swiotlb.h>
|
||||
|
||||
extern dma_addr_t bad_dma_address;
|
||||
extern int iommu_merge;
|
||||
extern struct device fallback_dev;
|
||||
extern int panic_on_overflow;
|
||||
extern int forbid_dac;
|
||||
extern int force_iommu;
|
||||
|
||||
struct dma_mapping_ops {
|
||||
int (*mapping_error)(dma_addr_t dma_addr);
|
||||
void* (*alloc_coherent)(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, gfp_t gfp);
|
||||
void (*free_coherent)(struct device *dev, size_t size,
|
||||
void *vaddr, dma_addr_t dma_handle);
|
||||
dma_addr_t (*map_single)(struct device *hwdev, phys_addr_t ptr,
|
||||
size_t size, int direction);
|
||||
/* like map_single, but doesn't check the device mask */
|
||||
dma_addr_t (*map_simple)(struct device *hwdev, phys_addr_t ptr,
|
||||
size_t size, int direction);
|
||||
void (*unmap_single)(struct device *dev, dma_addr_t addr,
|
||||
size_t size, int direction);
|
||||
void (*sync_single_for_cpu)(struct device *hwdev,
|
||||
dma_addr_t dma_handle, size_t size,
|
||||
int direction);
|
||||
void (*sync_single_for_device)(struct device *hwdev,
|
||||
dma_addr_t dma_handle, size_t size,
|
||||
int direction);
|
||||
void (*sync_single_range_for_cpu)(struct device *hwdev,
|
||||
dma_addr_t dma_handle, unsigned long offset,
|
||||
size_t size, int direction);
|
||||
void (*sync_single_range_for_device)(struct device *hwdev,
|
||||
dma_addr_t dma_handle, unsigned long offset,
|
||||
size_t size, int direction);
|
||||
void (*sync_sg_for_cpu)(struct device *hwdev,
|
||||
struct scatterlist *sg, int nelems,
|
||||
int direction);
|
||||
void (*sync_sg_for_device)(struct device *hwdev,
|
||||
struct scatterlist *sg, int nelems,
|
||||
int direction);
|
||||
int (*map_sg)(struct device *hwdev, struct scatterlist *sg,
|
||||
int nents, int direction);
|
||||
void (*unmap_sg)(struct device *hwdev,
|
||||
struct scatterlist *sg, int nents,
|
||||
int direction);
|
||||
int (*dma_supported)(struct device *hwdev, u64 mask);
|
||||
int is_phys;
|
||||
};
|
||||
|
||||
extern const struct dma_mapping_ops *dma_ops;
|
||||
|
||||
static inline int dma_mapping_error(dma_addr_t dma_addr)
|
||||
{
|
||||
if (dma_ops->mapping_error)
|
||||
return dma_ops->mapping_error(dma_addr);
|
||||
|
||||
return (dma_addr == bad_dma_address);
|
||||
}
|
||||
|
||||
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
|
||||
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
|
||||
|
||||
void *dma_alloc_coherent(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, gfp_t flag);
|
||||
|
||||
void dma_free_coherent(struct device *dev, size_t size,
|
||||
void *vaddr, dma_addr_t dma_handle);
|
||||
|
||||
|
||||
extern int dma_supported(struct device *hwdev, u64 mask);
|
||||
extern int dma_set_mask(struct device *dev, u64 mask);
|
||||
|
||||
static inline dma_addr_t
|
||||
dma_map_single(struct device *hwdev, void *ptr, size_t size,
|
||||
int direction)
|
||||
{
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
return dma_ops->map_single(hwdev, virt_to_phys(ptr), size, direction);
|
||||
}
|
||||
|
||||
static inline void
|
||||
dma_unmap_single(struct device *dev, dma_addr_t addr, size_t size,
|
||||
int direction)
|
||||
{
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
if (dma_ops->unmap_single)
|
||||
dma_ops->unmap_single(dev, addr, size, direction);
|
||||
}
|
||||
|
||||
static inline int
|
||||
dma_map_sg(struct device *hwdev, struct scatterlist *sg,
|
||||
int nents, int direction)
|
||||
{
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
return dma_ops->map_sg(hwdev, sg, nents, direction);
|
||||
}
|
||||
|
||||
static inline void
|
||||
dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
|
||||
int direction)
|
||||
{
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
if (dma_ops->unmap_sg)
|
||||
dma_ops->unmap_sg(hwdev, sg, nents, direction);
|
||||
}
|
||||
|
||||
static inline void
|
||||
dma_sync_single_for_cpu(struct device *hwdev, dma_addr_t dma_handle,
|
||||
size_t size, int direction)
|
||||
{
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
if (dma_ops->sync_single_for_cpu)
|
||||
dma_ops->sync_single_for_cpu(hwdev, dma_handle, size,
|
||||
direction);
|
||||
flush_write_buffers();
|
||||
}
|
||||
|
||||
static inline void
|
||||
dma_sync_single_for_device(struct device *hwdev, dma_addr_t dma_handle,
|
||||
size_t size, int direction)
|
||||
{
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
if (dma_ops->sync_single_for_device)
|
||||
dma_ops->sync_single_for_device(hwdev, dma_handle, size,
|
||||
direction);
|
||||
flush_write_buffers();
|
||||
}
|
||||
|
||||
static inline void
|
||||
dma_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dma_handle,
|
||||
unsigned long offset, size_t size, int direction)
|
||||
{
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
if (dma_ops->sync_single_range_for_cpu)
|
||||
dma_ops->sync_single_range_for_cpu(hwdev, dma_handle, offset,
|
||||
size, direction);
|
||||
|
||||
flush_write_buffers();
|
||||
}
|
||||
|
||||
static inline void
|
||||
dma_sync_single_range_for_device(struct device *hwdev, dma_addr_t dma_handle,
|
||||
unsigned long offset, size_t size,
|
||||
int direction)
|
||||
{
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
if (dma_ops->sync_single_range_for_device)
|
||||
dma_ops->sync_single_range_for_device(hwdev, dma_handle,
|
||||
offset, size, direction);
|
||||
|
||||
flush_write_buffers();
|
||||
}
|
||||
|
||||
static inline void
|
||||
dma_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
|
||||
int nelems, int direction)
|
||||
{
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
if (dma_ops->sync_sg_for_cpu)
|
||||
dma_ops->sync_sg_for_cpu(hwdev, sg, nelems, direction);
|
||||
flush_write_buffers();
|
||||
}
|
||||
|
||||
static inline void
|
||||
dma_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,
|
||||
int nelems, int direction)
|
||||
{
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
if (dma_ops->sync_sg_for_device)
|
||||
dma_ops->sync_sg_for_device(hwdev, sg, nelems, direction);
|
||||
|
||||
flush_write_buffers();
|
||||
}
|
||||
|
||||
static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
|
||||
size_t offset, size_t size,
|
||||
int direction)
|
||||
{
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
return dma_ops->map_single(dev, page_to_phys(page)+offset,
|
||||
size, direction);
|
||||
}
|
||||
|
||||
static inline void dma_unmap_page(struct device *dev, dma_addr_t addr,
|
||||
size_t size, int direction)
|
||||
{
|
||||
dma_unmap_single(dev, addr, size, direction);
|
||||
}
|
||||
|
||||
static inline void
|
||||
dma_cache_sync(struct device *dev, void *vaddr, size_t size,
|
||||
enum dma_data_direction dir)
|
||||
{
|
||||
flush_write_buffers();
|
||||
}
|
||||
|
||||
static inline int dma_get_cache_alignment(void)
|
||||
{
|
||||
/* no easy way to get cache size on all x86, so return the
|
||||
* maximum possible, to be safe */
|
||||
return boot_cpu_data.x86_clflush_size;
|
||||
}
|
||||
|
||||
#define dma_is_consistent(d, h) (1)
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
# include "dma-mapping_32.h"
|
||||
#else
|
||||
# include "dma-mapping_64.h"
|
||||
# define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY
|
||||
struct dma_coherent_mem {
|
||||
void *virt_base;
|
||||
u32 device_base;
|
||||
int size;
|
||||
int flags;
|
||||
unsigned long *bitmap;
|
||||
};
|
||||
|
||||
extern int
|
||||
dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
|
||||
dma_addr_t device_addr, size_t size, int flags);
|
||||
|
||||
extern void
|
||||
dma_release_declared_memory(struct device *dev);
|
||||
|
||||
extern void *
|
||||
dma_mark_declared_memory_occupied(struct device *dev,
|
||||
dma_addr_t device_addr, size_t size);
|
||||
#endif /* CONFIG_X86_32 */
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,187 +0,0 @@
|
|||
#ifndef _ASM_I386_DMA_MAPPING_H
|
||||
#define _ASM_I386_DMA_MAPPING_H
|
||||
|
||||
#include <linux/mm.h>
|
||||
#include <linux/scatterlist.h>
|
||||
|
||||
#include <asm/cache.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/bug.h>
|
||||
|
||||
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
|
||||
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
|
||||
|
||||
void *dma_alloc_coherent(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, gfp_t flag);
|
||||
|
||||
void dma_free_coherent(struct device *dev, size_t size,
|
||||
void *vaddr, dma_addr_t dma_handle);
|
||||
|
||||
static inline dma_addr_t
|
||||
dma_map_single(struct device *dev, void *ptr, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
WARN_ON(size == 0);
|
||||
flush_write_buffers();
|
||||
return virt_to_phys(ptr);
|
||||
}
|
||||
|
||||
static inline void
|
||||
dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
}
|
||||
|
||||
static inline int
|
||||
dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
struct scatterlist *sg;
|
||||
int i;
|
||||
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
WARN_ON(nents == 0 || sglist[0].length == 0);
|
||||
|
||||
for_each_sg(sglist, sg, nents, i) {
|
||||
BUG_ON(!sg_page(sg));
|
||||
|
||||
sg->dma_address = sg_phys(sg);
|
||||
}
|
||||
|
||||
flush_write_buffers();
|
||||
return nents;
|
||||
}
|
||||
|
||||
static inline dma_addr_t
|
||||
dma_map_page(struct device *dev, struct page *page, unsigned long offset,
|
||||
size_t size, enum dma_data_direction direction)
|
||||
{
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
return page_to_phys(page) + offset;
|
||||
}
|
||||
|
||||
static inline void
|
||||
dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
}
|
||||
|
||||
|
||||
static inline void
|
||||
dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
}
|
||||
|
||||
static inline void
|
||||
dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_handle, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void
|
||||
dma_sync_single_for_device(struct device *dev, dma_addr_t dma_handle, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
flush_write_buffers();
|
||||
}
|
||||
|
||||
static inline void
|
||||
dma_sync_single_range_for_cpu(struct device *dev, dma_addr_t dma_handle,
|
||||
unsigned long offset, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void
|
||||
dma_sync_single_range_for_device(struct device *dev, dma_addr_t dma_handle,
|
||||
unsigned long offset, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
flush_write_buffers();
|
||||
}
|
||||
|
||||
static inline void
|
||||
dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nelems,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
}
|
||||
|
||||
static inline void
|
||||
dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nelems,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
flush_write_buffers();
|
||||
}
|
||||
|
||||
static inline int
|
||||
dma_mapping_error(dma_addr_t dma_addr)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
extern int forbid_dac;
|
||||
|
||||
static inline int
|
||||
dma_supported(struct device *dev, u64 mask)
|
||||
{
|
||||
/*
|
||||
* we fall back to GFP_DMA when the mask isn't all 1s,
|
||||
* so we can't guarantee allocations that must be
|
||||
* within a tighter range than GFP_DMA..
|
||||
*/
|
||||
if(mask < 0x00ffffff)
|
||||
return 0;
|
||||
|
||||
/* Work around chipset bugs */
|
||||
if (forbid_dac > 0 && mask > 0xffffffffULL)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline int
|
||||
dma_set_mask(struct device *dev, u64 mask)
|
||||
{
|
||||
if(!dev->dma_mask || !dma_supported(dev, mask))
|
||||
return -EIO;
|
||||
|
||||
*dev->dma_mask = mask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
dma_get_cache_alignment(void)
|
||||
{
|
||||
/* no easy way to get cache size on all x86, so return the
|
||||
* maximum possible, to be safe */
|
||||
return (1 << INTERNODE_CACHE_SHIFT);
|
||||
}
|
||||
|
||||
#define dma_is_consistent(d, h) (1)
|
||||
|
||||
static inline void
|
||||
dma_cache_sync(struct device *dev, void *vaddr, size_t size,
|
||||
enum dma_data_direction direction)
|
||||
{
|
||||
flush_write_buffers();
|
||||
}
|
||||
|
||||
#define ARCH_HAS_DMA_DECLARE_COHERENT_MEMORY
|
||||
extern int
|
||||
dma_declare_coherent_memory(struct device *dev, dma_addr_t bus_addr,
|
||||
dma_addr_t device_addr, size_t size, int flags);
|
||||
|
||||
extern void
|
||||
dma_release_declared_memory(struct device *dev);
|
||||
|
||||
extern void *
|
||||
dma_mark_declared_memory_occupied(struct device *dev,
|
||||
dma_addr_t device_addr, size_t size);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,202 +0,0 @@
|
|||
#ifndef _X8664_DMA_MAPPING_H
|
||||
#define _X8664_DMA_MAPPING_H 1
|
||||
|
||||
/*
|
||||
* IOMMU interface. See Documentation/DMA-mapping.txt and DMA-API.txt for
|
||||
* documentation.
|
||||
*/
|
||||
|
||||
#include <linux/scatterlist.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/swiotlb.h>
|
||||
|
||||
struct dma_mapping_ops {
|
||||
int (*mapping_error)(dma_addr_t dma_addr);
|
||||
void* (*alloc_coherent)(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, gfp_t gfp);
|
||||
void (*free_coherent)(struct device *dev, size_t size,
|
||||
void *vaddr, dma_addr_t dma_handle);
|
||||
dma_addr_t (*map_single)(struct device *hwdev, void *ptr,
|
||||
size_t size, int direction);
|
||||
/* like map_single, but doesn't check the device mask */
|
||||
dma_addr_t (*map_simple)(struct device *hwdev, char *ptr,
|
||||
size_t size, int direction);
|
||||
void (*unmap_single)(struct device *dev, dma_addr_t addr,
|
||||
size_t size, int direction);
|
||||
void (*sync_single_for_cpu)(struct device *hwdev,
|
||||
dma_addr_t dma_handle, size_t size,
|
||||
int direction);
|
||||
void (*sync_single_for_device)(struct device *hwdev,
|
||||
dma_addr_t dma_handle, size_t size,
|
||||
int direction);
|
||||
void (*sync_single_range_for_cpu)(struct device *hwdev,
|
||||
dma_addr_t dma_handle, unsigned long offset,
|
||||
size_t size, int direction);
|
||||
void (*sync_single_range_for_device)(struct device *hwdev,
|
||||
dma_addr_t dma_handle, unsigned long offset,
|
||||
size_t size, int direction);
|
||||
void (*sync_sg_for_cpu)(struct device *hwdev,
|
||||
struct scatterlist *sg, int nelems,
|
||||
int direction);
|
||||
void (*sync_sg_for_device)(struct device *hwdev,
|
||||
struct scatterlist *sg, int nelems,
|
||||
int direction);
|
||||
int (*map_sg)(struct device *hwdev, struct scatterlist *sg,
|
||||
int nents, int direction);
|
||||
void (*unmap_sg)(struct device *hwdev,
|
||||
struct scatterlist *sg, int nents,
|
||||
int direction);
|
||||
int (*dma_supported)(struct device *hwdev, u64 mask);
|
||||
int is_phys;
|
||||
};
|
||||
|
||||
extern dma_addr_t bad_dma_address;
|
||||
extern const struct dma_mapping_ops* dma_ops;
|
||||
extern int iommu_merge;
|
||||
|
||||
static inline int dma_mapping_error(dma_addr_t dma_addr)
|
||||
{
|
||||
if (dma_ops->mapping_error)
|
||||
return dma_ops->mapping_error(dma_addr);
|
||||
|
||||
return (dma_addr == bad_dma_address);
|
||||
}
|
||||
|
||||
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
|
||||
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
|
||||
|
||||
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
|
||||
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h)
|
||||
|
||||
extern void *dma_alloc_coherent(struct device *dev, size_t size,
|
||||
dma_addr_t *dma_handle, gfp_t gfp);
|
||||
extern void dma_free_coherent(struct device *dev, size_t size, void *vaddr,
|
||||
dma_addr_t dma_handle);
|
||||
|
||||
static inline dma_addr_t
|
||||
dma_map_single(struct device *hwdev, void *ptr, size_t size,
|
||||
int direction)
|
||||
{
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
return dma_ops->map_single(hwdev, ptr, size, direction);
|
||||
}
|
||||
|
||||
static inline void
|
||||
dma_unmap_single(struct device *dev, dma_addr_t addr,size_t size,
|
||||
int direction)
|
||||
{
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
dma_ops->unmap_single(dev, addr, size, direction);
|
||||
}
|
||||
|
||||
#define dma_map_page(dev,page,offset,size,dir) \
|
||||
dma_map_single((dev), page_address(page)+(offset), (size), (dir))
|
||||
|
||||
#define dma_unmap_page dma_unmap_single
|
||||
|
||||
static inline void
|
||||
dma_sync_single_for_cpu(struct device *hwdev, dma_addr_t dma_handle,
|
||||
size_t size, int direction)
|
||||
{
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
if (dma_ops->sync_single_for_cpu)
|
||||
dma_ops->sync_single_for_cpu(hwdev, dma_handle, size,
|
||||
direction);
|
||||
flush_write_buffers();
|
||||
}
|
||||
|
||||
static inline void
|
||||
dma_sync_single_for_device(struct device *hwdev, dma_addr_t dma_handle,
|
||||
size_t size, int direction)
|
||||
{
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
if (dma_ops->sync_single_for_device)
|
||||
dma_ops->sync_single_for_device(hwdev, dma_handle, size,
|
||||
direction);
|
||||
flush_write_buffers();
|
||||
}
|
||||
|
||||
static inline void
|
||||
dma_sync_single_range_for_cpu(struct device *hwdev, dma_addr_t dma_handle,
|
||||
unsigned long offset, size_t size, int direction)
|
||||
{
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
if (dma_ops->sync_single_range_for_cpu) {
|
||||
dma_ops->sync_single_range_for_cpu(hwdev, dma_handle, offset, size, direction);
|
||||
}
|
||||
|
||||
flush_write_buffers();
|
||||
}
|
||||
|
||||
static inline void
|
||||
dma_sync_single_range_for_device(struct device *hwdev, dma_addr_t dma_handle,
|
||||
unsigned long offset, size_t size, int direction)
|
||||
{
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
if (dma_ops->sync_single_range_for_device)
|
||||
dma_ops->sync_single_range_for_device(hwdev, dma_handle,
|
||||
offset, size, direction);
|
||||
|
||||
flush_write_buffers();
|
||||
}
|
||||
|
||||
static inline void
|
||||
dma_sync_sg_for_cpu(struct device *hwdev, struct scatterlist *sg,
|
||||
int nelems, int direction)
|
||||
{
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
if (dma_ops->sync_sg_for_cpu)
|
||||
dma_ops->sync_sg_for_cpu(hwdev, sg, nelems, direction);
|
||||
flush_write_buffers();
|
||||
}
|
||||
|
||||
static inline void
|
||||
dma_sync_sg_for_device(struct device *hwdev, struct scatterlist *sg,
|
||||
int nelems, int direction)
|
||||
{
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
if (dma_ops->sync_sg_for_device) {
|
||||
dma_ops->sync_sg_for_device(hwdev, sg, nelems, direction);
|
||||
}
|
||||
|
||||
flush_write_buffers();
|
||||
}
|
||||
|
||||
static inline int
|
||||
dma_map_sg(struct device *hwdev, struct scatterlist *sg, int nents, int direction)
|
||||
{
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
return dma_ops->map_sg(hwdev, sg, nents, direction);
|
||||
}
|
||||
|
||||
static inline void
|
||||
dma_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nents,
|
||||
int direction)
|
||||
{
|
||||
BUG_ON(!valid_dma_direction(direction));
|
||||
dma_ops->unmap_sg(hwdev, sg, nents, direction);
|
||||
}
|
||||
|
||||
extern int dma_supported(struct device *hwdev, u64 mask);
|
||||
|
||||
/* same for gart, swiotlb, and nommu */
|
||||
static inline int dma_get_cache_alignment(void)
|
||||
{
|
||||
return boot_cpu_data.x86_clflush_size;
|
||||
}
|
||||
|
||||
#define dma_is_consistent(d, h) 1
|
||||
|
||||
extern int dma_set_mask(struct device *dev, u64 mask);
|
||||
|
||||
static inline void
|
||||
dma_cache_sync(struct device *dev, void *vaddr, size_t size,
|
||||
enum dma_data_direction dir)
|
||||
{
|
||||
flush_write_buffers();
|
||||
}
|
||||
|
||||
extern struct device fallback_dev;
|
||||
extern int panic_on_overflow;
|
||||
|
||||
#endif /* _X8664_DMA_MAPPING_H */
|
||||
|
|
@ -24,7 +24,7 @@ extern void update_e820(void);
|
|||
extern int e820_all_mapped(unsigned long start, unsigned long end,
|
||||
unsigned type);
|
||||
extern int e820_any_mapped(u64 start, u64 end, unsigned type);
|
||||
extern void find_max_pfn(void);
|
||||
extern void propagate_e820_map(void);
|
||||
extern void register_bootmem_low_pages(unsigned long max_low_pfn);
|
||||
extern void add_memory_region(unsigned long long start,
|
||||
unsigned long long size, int type);
|
||||
|
|
|
|||
|
|
@ -117,6 +117,7 @@ extern struct genapic *genapic;
|
|||
enum uv_system_type {UV_NONE, UV_LEGACY_APIC, UV_X2APIC, UV_NON_UNIQUE_APIC};
|
||||
#define get_uv_system_type() UV_NONE
|
||||
#define is_uv_system() 0
|
||||
#define uv_wakeup_secondary(a, b) 1
|
||||
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -21,8 +21,9 @@
|
|||
|
||||
extern void fpu_init(void);
|
||||
extern void mxcsr_feature_mask_init(void);
|
||||
extern void init_fpu(struct task_struct *child);
|
||||
extern int init_fpu(struct task_struct *child);
|
||||
extern asmlinkage void math_state_restore(void);
|
||||
extern void init_thread_xstate(void);
|
||||
|
||||
extern user_regset_active_fn fpregs_active, xfpregs_active;
|
||||
extern user_regset_get_fn fpregs_get, xfpregs_get, fpregs_soft_get;
|
||||
|
|
@ -117,24 +118,22 @@ static inline void __save_init_fpu(struct task_struct *tsk)
|
|||
/* Using "fxsaveq %0" would be the ideal choice, but is only supported
|
||||
starting with gas 2.16. */
|
||||
__asm__ __volatile__("fxsaveq %0"
|
||||
: "=m" (tsk->thread.i387.fxsave));
|
||||
: "=m" (tsk->thread.xstate->fxsave));
|
||||
#elif 0
|
||||
/* Using, as a workaround, the properly prefixed form below isn't
|
||||
accepted by any binutils version so far released, complaining that
|
||||
the same type of prefix is used twice if an extended register is
|
||||
needed for addressing (fix submitted to mainline 2005-11-21). */
|
||||
__asm__ __volatile__("rex64/fxsave %0"
|
||||
: "=m" (tsk->thread.i387.fxsave));
|
||||
: "=m" (tsk->thread.xstate->fxsave));
|
||||
#else
|
||||
/* This, however, we can work around by forcing the compiler to select
|
||||
an addressing mode that doesn't require extended registers. */
|
||||
__asm__ __volatile__("rex64/fxsave %P2(%1)"
|
||||
: "=m" (tsk->thread.i387.fxsave)
|
||||
: "cdaSDb" (tsk),
|
||||
"i" (offsetof(__typeof__(*tsk),
|
||||
thread.i387.fxsave)));
|
||||
__asm__ __volatile__("rex64/fxsave (%1)"
|
||||
: "=m" (tsk->thread.xstate->fxsave)
|
||||
: "cdaSDb" (&tsk->thread.xstate->fxsave));
|
||||
#endif
|
||||
clear_fpu_state(&tsk->thread.i387.fxsave);
|
||||
clear_fpu_state(&tsk->thread.xstate->fxsave);
|
||||
task_thread_info(tsk)->status &= ~TS_USEDFPU;
|
||||
}
|
||||
|
||||
|
|
@ -148,7 +147,7 @@ static inline int save_i387(struct _fpstate __user *buf)
|
|||
int err = 0;
|
||||
|
||||
BUILD_BUG_ON(sizeof(struct user_i387_struct) !=
|
||||
sizeof(tsk->thread.i387.fxsave));
|
||||
sizeof(tsk->thread.xstate->fxsave));
|
||||
|
||||
if ((unsigned long)buf % 16)
|
||||
printk("save_i387: bad fpstate %p\n", buf);
|
||||
|
|
@ -164,7 +163,7 @@ static inline int save_i387(struct _fpstate __user *buf)
|
|||
task_thread_info(tsk)->status &= ~TS_USEDFPU;
|
||||
stts();
|
||||
} else {
|
||||
if (__copy_to_user(buf, &tsk->thread.i387.fxsave,
|
||||
if (__copy_to_user(buf, &tsk->thread.xstate->fxsave,
|
||||
sizeof(struct i387_fxsave_struct)))
|
||||
return -1;
|
||||
}
|
||||
|
|
@ -201,7 +200,7 @@ static inline void restore_fpu(struct task_struct *tsk)
|
|||
"nop ; frstor %1",
|
||||
"fxrstor %1",
|
||||
X86_FEATURE_FXSR,
|
||||
"m" ((tsk)->thread.i387.fxsave));
|
||||
"m" (tsk->thread.xstate->fxsave));
|
||||
}
|
||||
|
||||
/* We need a safe address that is cheap to find and that is already
|
||||
|
|
@ -225,8 +224,8 @@ static inline void __save_init_fpu(struct task_struct *tsk)
|
|||
"fxsave %[fx]\n"
|
||||
"bt $7,%[fsw] ; jnc 1f ; fnclex\n1:",
|
||||
X86_FEATURE_FXSR,
|
||||
[fx] "m" (tsk->thread.i387.fxsave),
|
||||
[fsw] "m" (tsk->thread.i387.fxsave.swd) : "memory");
|
||||
[fx] "m" (tsk->thread.xstate->fxsave),
|
||||
[fsw] "m" (tsk->thread.xstate->fxsave.swd) : "memory");
|
||||
/* AMD K7/K8 CPUs don't save/restore FDP/FIP/FOP unless an exception
|
||||
is pending. Clear the x87 state here by setting it to fixed
|
||||
values. safe_address is a random variable that should be in L1 */
|
||||
|
|
@ -327,25 +326,25 @@ static inline void clear_fpu(struct task_struct *tsk)
|
|||
static inline unsigned short get_fpu_cwd(struct task_struct *tsk)
|
||||
{
|
||||
if (cpu_has_fxsr) {
|
||||
return tsk->thread.i387.fxsave.cwd;
|
||||
return tsk->thread.xstate->fxsave.cwd;
|
||||
} else {
|
||||
return (unsigned short)tsk->thread.i387.fsave.cwd;
|
||||
return (unsigned short)tsk->thread.xstate->fsave.cwd;
|
||||
}
|
||||
}
|
||||
|
||||
static inline unsigned short get_fpu_swd(struct task_struct *tsk)
|
||||
{
|
||||
if (cpu_has_fxsr) {
|
||||
return tsk->thread.i387.fxsave.swd;
|
||||
return tsk->thread.xstate->fxsave.swd;
|
||||
} else {
|
||||
return (unsigned short)tsk->thread.i387.fsave.swd;
|
||||
return (unsigned short)tsk->thread.xstate->fsave.swd;
|
||||
}
|
||||
}
|
||||
|
||||
static inline unsigned short get_fpu_mxcsr(struct task_struct *tsk)
|
||||
{
|
||||
if (cpu_has_xmm) {
|
||||
return tsk->thread.i387.fxsave.mxcsr;
|
||||
return tsk->thread.xstate->fxsave.mxcsr;
|
||||
} else {
|
||||
return MXCSR_DEFAULT;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -9,7 +9,8 @@ struct bootnode {
|
|||
u64 end;
|
||||
};
|
||||
|
||||
extern int compute_hash_shift(struct bootnode *nodes, int numnodes);
|
||||
extern int compute_hash_shift(struct bootnode *nodes, int numblks,
|
||||
int *nodeids);
|
||||
|
||||
#define ZONE_ALIGN (1UL << (MAX_ORDER+PAGE_SHIFT))
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ extern int (*pci_config_read)(int seg, int bus, int dev, int fn,
|
|||
extern int (*pci_config_write)(int seg, int bus, int dev, int fn,
|
||||
int reg, int len, u32 value);
|
||||
|
||||
extern void dma32_reserve_bootmem(void);
|
||||
extern void pci_iommu_alloc(void);
|
||||
|
||||
/* The PCI address space does equal the physical memory
|
||||
|
|
|
|||
|
|
@ -354,7 +354,7 @@ struct i387_soft_struct {
|
|||
u32 entry_eip;
|
||||
};
|
||||
|
||||
union i387_union {
|
||||
union thread_xstate {
|
||||
struct i387_fsave_struct fsave;
|
||||
struct i387_fxsave_struct fxsave;
|
||||
struct i387_soft_struct soft;
|
||||
|
|
@ -365,6 +365,9 @@ DECLARE_PER_CPU(struct orig_ist, orig_ist);
|
|||
#endif
|
||||
|
||||
extern void print_cpu_info(struct cpuinfo_x86 *);
|
||||
extern unsigned int xstate_size;
|
||||
extern void free_thread_xstate(struct task_struct *);
|
||||
extern struct kmem_cache *task_xstate_cachep;
|
||||
extern void init_scattered_cpuid_features(struct cpuinfo_x86 *c);
|
||||
extern unsigned int init_intel_cacheinfo(struct cpuinfo_x86 *c);
|
||||
extern unsigned short num_cache_leaves;
|
||||
|
|
@ -397,8 +400,8 @@ struct thread_struct {
|
|||
unsigned long cr2;
|
||||
unsigned long trap_no;
|
||||
unsigned long error_code;
|
||||
/* Floating point info: */
|
||||
union i387_union i387 __attribute__((aligned(16)));;
|
||||
/* floating point and extended processor state */
|
||||
union thread_xstate *xstate;
|
||||
#ifdef CONFIG_X86_32
|
||||
/* Virtual 86 mode info */
|
||||
struct vm86_struct __user *vm86_info;
|
||||
|
|
@ -918,4 +921,11 @@ extern void start_thread(struct pt_regs *regs, unsigned long new_ip,
|
|||
|
||||
#define KSTK_EIP(task) (task_pt_regs(task)->ip)
|
||||
|
||||
/* Get/set a process' ability to use the timestamp counter instruction */
|
||||
#define GET_TSC_CTL(adr) get_tsc_mode((adr))
|
||||
#define SET_TSC_CTL(val) set_tsc_mode((val))
|
||||
|
||||
extern int get_tsc_mode(unsigned long adr);
|
||||
extern int set_tsc_mode(unsigned int val);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -11,9 +11,7 @@ struct scatterlist {
|
|||
unsigned int offset;
|
||||
unsigned int length;
|
||||
dma_addr_t dma_address;
|
||||
#ifdef CONFIG_X86_64
|
||||
unsigned int dma_length;
|
||||
#endif
|
||||
};
|
||||
|
||||
#define ARCH_HAS_SG_CHAIN
|
||||
|
|
|
|||
|
|
@ -1,5 +1,14 @@
|
|||
#ifndef _ASM_X86_THREAD_INFO_H
|
||||
#ifdef CONFIG_X86_32
|
||||
# include "thread_info_32.h"
|
||||
#else
|
||||
# include "thread_info_64.h"
|
||||
#endif
|
||||
|
||||
#ifndef __ASSEMBLY__
|
||||
extern void arch_task_cache_init(void);
|
||||
extern void free_thread_info(struct thread_info *ti);
|
||||
extern int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src);
|
||||
#define arch_task_cache_init arch_task_cache_init
|
||||
#endif
|
||||
#endif /* _ASM_X86_THREAD_INFO_H */
|
||||
|
|
|
|||
|
|
@ -102,8 +102,6 @@ static inline struct thread_info *current_thread_info(void)
|
|||
__get_free_pages(GFP_KERNEL, get_order(THREAD_SIZE)))
|
||||
#endif
|
||||
|
||||
#define free_thread_info(info) free_pages((unsigned long)(info), get_order(THREAD_SIZE))
|
||||
|
||||
#else /* !__ASSEMBLY__ */
|
||||
|
||||
/* how to get the thread information struct from ASM */
|
||||
|
|
|
|||
|
|
@ -85,8 +85,6 @@ static inline struct thread_info *stack_thread_info(void)
|
|||
#define alloc_thread_info(tsk) \
|
||||
((struct thread_info *)__get_free_pages(THREAD_FLAGS, THREAD_ORDER))
|
||||
|
||||
#define free_thread_info(ti) free_pages((unsigned long) (ti), THREAD_ORDER)
|
||||
|
||||
#else /* !__ASSEMBLY__ */
|
||||
|
||||
/* how to get the thread information struct from ASM */
|
||||
|
|
@ -126,6 +124,7 @@ static inline struct thread_info *stack_thread_info(void)
|
|||
#define TIF_DEBUGCTLMSR 25 /* uses thread_struct.debugctlmsr */
|
||||
#define TIF_DS_AREA_MSR 26 /* uses thread_struct.ds_area_msr */
|
||||
#define TIF_BTS_TRACE_TS 27 /* record scheduling event timestamps */
|
||||
#define TIF_NOTSC 28 /* TSC is not accessible in userland */
|
||||
|
||||
#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE)
|
||||
#define _TIF_SIGPENDING (1 << TIF_SIGPENDING)
|
||||
|
|
@ -147,6 +146,7 @@ static inline struct thread_info *stack_thread_info(void)
|
|||
#define _TIF_DEBUGCTLMSR (1 << TIF_DEBUGCTLMSR)
|
||||
#define _TIF_DS_AREA_MSR (1 << TIF_DS_AREA_MSR)
|
||||
#define _TIF_BTS_TRACE_TS (1 << TIF_BTS_TRACE_TS)
|
||||
#define _TIF_NOTSC (1 << TIF_NOTSC)
|
||||
|
||||
/* work to do on interrupt/exception return */
|
||||
#define _TIF_WORK_MASK \
|
||||
|
|
@ -160,7 +160,7 @@ static inline struct thread_info *stack_thread_info(void)
|
|||
|
||||
/* flags to check in __switch_to() */
|
||||
#define _TIF_WORK_CTXSW \
|
||||
(_TIF_IO_BITMAP|_TIF_DEBUGCTLMSR|_TIF_DS_AREA_MSR|_TIF_BTS_TRACE_TS)
|
||||
(_TIF_IO_BITMAP|_TIF_DEBUGCTLMSR|_TIF_DS_AREA_MSR|_TIF_BTS_TRACE_TS|_TIF_NOTSC)
|
||||
#define _TIF_WORK_CTXSW_PREV _TIF_WORK_CTXSW
|
||||
#define _TIF_WORK_CTXSW_NEXT (_TIF_WORK_CTXSW|_TIF_DEBUG)
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ extern unsigned int cpu_khz;
|
|||
extern unsigned int tsc_khz;
|
||||
|
||||
extern void disable_TSC(void);
|
||||
extern void enable_TSC(void);
|
||||
|
||||
static inline cycles_t get_cycles(void)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
#include <linux/proc_fs.h>
|
||||
#include <linux/rtc.h>
|
||||
#include <linux/ioport.h>
|
||||
#include <linux/pfn.h>
|
||||
|
||||
#include <asm/page.h>
|
||||
#include <asm/system.h>
|
||||
|
|
@ -394,4 +395,10 @@ struct efi_generic_dev_path {
|
|||
u16 length;
|
||||
} __attribute ((packed));
|
||||
|
||||
static inline void memrange_efi_to_native(u64 *addr, u64 *npages)
|
||||
{
|
||||
*npages = PFN_UP(*addr + (*npages<<EFI_PAGE_SHIFT)) - PFN_DOWN(*addr);
|
||||
*addr &= PAGE_MASK;
|
||||
}
|
||||
|
||||
#endif /* _LINUX_EFI_H */
|
||||
|
|
|
|||
|
|
@ -84,10 +84,10 @@
|
|||
|
||||
#define irqs_disabled() \
|
||||
({ \
|
||||
unsigned long flags; \
|
||||
unsigned long _flags; \
|
||||
\
|
||||
raw_local_save_flags(flags); \
|
||||
raw_irqs_disabled_flags(flags); \
|
||||
raw_local_save_flags(_flags); \
|
||||
raw_irqs_disabled_flags(_flags); \
|
||||
})
|
||||
|
||||
#define irqs_disabled_flags(flags) raw_irqs_disabled_flags(flags)
|
||||
|
|
|
|||
|
|
@ -67,4 +67,10 @@
|
|||
#define PR_CAPBSET_READ 23
|
||||
#define PR_CAPBSET_DROP 24
|
||||
|
||||
/* Get/set the process' ability to use the timestamp counter instruction */
|
||||
#define PR_GET_TSC 25
|
||||
#define PR_SET_TSC 26
|
||||
# define PR_TSC_ENABLE 1 /* allow the use of the timestamp counter */
|
||||
# define PR_TSC_SIGSEGV 2 /* throw a SIGSEGV instead of reading the TSC */
|
||||
|
||||
#endif /* _LINUX_PRCTL_H */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue