提交 f0a08fcb 编写于 作者: L Linus Torvalds

Merge git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile

Pull arch/tile updates from Chris Metcalf:
 "These changes provide support for PCIe root complex and USB host mode
  for tilegx's on-chip I/Os.

  In addition, this pull provides the required underpinning for the
  on-chip networking support that was pulled into 3.5.  The changes have
  all been through LKML (with several rounds for PCIe RC) and on
  linux-next."

* git://git.kernel.org/pub/scm/linux/kernel/git/cmetcalf/linux-tile:
  tile: updates to pci root complex from community feedback
  bounce: allow use of bounce pool via config option
  usb: add host support for the tilegx architecture
  arch/tile: provide kernel support for the tilegx USB shim
  tile pci: enable IOMMU to support DMA for legacy devices
  arch/tile: enable ZONE_DMA for tilegx
  tilegx pci: support I/O to arbitrarily-cached pages
  tile: remove unused header
  arch/tile: tilegx PCI root complex support
  arch/tile: provide kernel support for the tilegx TRIO shim
  arch/tile: break out the "csum a long" function to <asm/checksum.h>
  arch/tile: provide kernel support for the tilegx mPIPE shim
  arch/tile: common DMA code for the GXIO IORPC subsystem
  arch/tile: support MMIO-based readb/writeb etc.
  arch/tile: introduce GXIO IORPC framework for tilegx
...@@ -3,6 +3,8 @@ ...@@ -3,6 +3,8 @@
config TILE config TILE
def_bool y def_bool y
select HAVE_DMA_ATTRS
select HAVE_DMA_API_DEBUG
select HAVE_KVM if !TILEGX select HAVE_KVM if !TILEGX
select GENERIC_FIND_FIRST_BIT select GENERIC_FIND_FIRST_BIT
select USE_GENERIC_SMP_HELPERS select USE_GENERIC_SMP_HELPERS
...@@ -79,6 +81,9 @@ config ARCH_DMA_ADDR_T_64BIT ...@@ -79,6 +81,9 @@ config ARCH_DMA_ADDR_T_64BIT
config NEED_DMA_MAP_STATE config NEED_DMA_MAP_STATE
def_bool y def_bool y
config ARCH_HAS_DMA_SET_COHERENT_MASK
bool
config LOCKDEP_SUPPORT config LOCKDEP_SUPPORT
def_bool y def_bool y
...@@ -212,6 +217,22 @@ config HIGHMEM ...@@ -212,6 +217,22 @@ config HIGHMEM
If unsure, say "true". If unsure, say "true".
config ZONE_DMA
def_bool y
config IOMMU_HELPER
bool
config NEED_SG_DMA_LENGTH
bool
config SWIOTLB
bool
default TILEGX
select IOMMU_HELPER
select NEED_SG_DMA_LENGTH
select ARCH_HAS_DMA_SET_COHERENT_MASK
# We do not currently support disabling NUMA. # We do not currently support disabling NUMA.
config NUMA config NUMA
bool # "NUMA Memory Allocation and Scheduler Support" bool # "NUMA Memory Allocation and Scheduler Support"
...@@ -345,6 +366,8 @@ config KERNEL_PL ...@@ -345,6 +366,8 @@ config KERNEL_PL
kernel will be built to run at. Generally you should use kernel will be built to run at. Generally you should use
the default value here. the default value here.
source "arch/tile/gxio/Kconfig"
endmenu # Tilera-specific configuration endmenu # Tilera-specific configuration
menu "Bus options" menu "Bus options"
...@@ -354,6 +377,9 @@ config PCI ...@@ -354,6 +377,9 @@ config PCI
default y default y
select PCI_DOMAINS select PCI_DOMAINS
select GENERIC_PCI_IOMAP select GENERIC_PCI_IOMAP
select TILE_GXIO_TRIO if TILEGX
select ARCH_SUPPORTS_MSI if TILEGX
select PCI_MSI if TILEGX
---help--- ---help---
Enable PCI root complex support, so PCIe endpoint devices can Enable PCI root complex support, so PCIe endpoint devices can
be attached to the Tile chip. Many, but not all, PCI devices be attached to the Tile chip. Many, but not all, PCI devices
...@@ -370,6 +396,22 @@ config NO_IOPORT ...@@ -370,6 +396,22 @@ config NO_IOPORT
source "drivers/pci/Kconfig" source "drivers/pci/Kconfig"
config TILE_USB
tristate "Tilera USB host adapter support"
default y
depends on USB
depends on TILEGX
select TILE_GXIO_USB_HOST
---help---
Provides USB host adapter support for the built-in EHCI and OHCI
interfaces on TILE-Gx chips.
# USB OHCI needs the bounce pool since tilegx will often have more
# than 4GB of memory, but we don't currently use the IOTLB to present
# a 32-bit address to OHCI. So we need to use a bounce pool instead.
config NEED_BOUNCE_POOL
def_bool USB_OHCI_HCD
config HOTPLUG config HOTPLUG
bool "Support for hot-pluggable devices" bool "Support for hot-pluggable devices"
---help--- ---help---
......
...@@ -59,6 +59,8 @@ libs-y += $(LIBGCC_PATH) ...@@ -59,6 +59,8 @@ libs-y += $(LIBGCC_PATH)
# See arch/tile/Kbuild for content of core part of the kernel # See arch/tile/Kbuild for content of core part of the kernel
core-y += arch/tile/ core-y += arch/tile/
core-$(CONFIG_TILE_GXIO) += arch/tile/gxio/
ifdef TILERA_ROOT ifdef TILERA_ROOT
INSTALL_PATH ?= $(TILERA_ROOT)/tile/boot INSTALL_PATH ?= $(TILERA_ROOT)/tile/boot
endif endif
......
# Support direct access to TILE-Gx hardware from user space, via the
# gxio library, or from kernel space, via kernel IORPC support.
config TILE_GXIO
bool
depends on TILEGX
# Support direct access to the common I/O DMA facility within the
# TILE-Gx mPIPE and Trio hardware from kernel space.
config TILE_GXIO_DMA
bool
select TILE_GXIO
# Support direct access to the TILE-Gx mPIPE hardware from kernel space.
config TILE_GXIO_MPIPE
bool
select TILE_GXIO
select TILE_GXIO_DMA
# Support direct access to the TILE-Gx TRIO hardware from kernel space.
config TILE_GXIO_TRIO
bool
select TILE_GXIO
select TILE_GXIO_DMA
# Support direct access to the TILE-Gx USB hardware from kernel space.
config TILE_GXIO_USB_HOST
bool
select TILE_GXIO
#
# Makefile for the Tile-Gx device access support.
#
obj-$(CONFIG_TILE_GXIO) += iorpc_globals.o kiorpc.o
obj-$(CONFIG_TILE_GXIO_DMA) += dma_queue.o
obj-$(CONFIG_TILE_GXIO_MPIPE) += mpipe.o iorpc_mpipe.o iorpc_mpipe_info.o
obj-$(CONFIG_TILE_GXIO_TRIO) += trio.o iorpc_trio.o
obj-$(CONFIG_TILE_GXIO_USB_HOST) += usb_host.o iorpc_usb_host.o
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
#include <linux/io.h>
#include <linux/atomic.h>
#include <linux/module.h>
#include <gxio/dma_queue.h>
/* Wait for a memory read to complete. */
#define wait_for_value(val) \
__asm__ __volatile__("move %0, %0" :: "r"(val))
/* The index is in the low 16. */
#define DMA_QUEUE_INDEX_MASK ((1 << 16) - 1)
/*
* The hardware descriptor-ring type.
* This matches the types used by mpipe (MPIPE_EDMA_POST_REGION_VAL_t)
* and trio (TRIO_PUSH_DMA_REGION_VAL_t or TRIO_PULL_DMA_REGION_VAL_t).
* See those types for more documentation on the individual fields.
*/
typedef union {
struct {
#ifndef __BIG_ENDIAN__
uint64_t ring_idx:16;
uint64_t count:16;
uint64_t gen:1;
uint64_t __reserved:31;
#else
uint64_t __reserved:31;
uint64_t gen:1;
uint64_t count:16;
uint64_t ring_idx:16;
#endif
};
uint64_t word;
} __gxio_ring_t;
void __gxio_dma_queue_init(__gxio_dma_queue_t *dma_queue,
void *post_region_addr, unsigned int num_entries)
{
/*
* Limit 65536 entry rings to 65535 credits because we only have a
* 16 bit completion counter.
*/
int64_t credits = (num_entries < 65536) ? num_entries : 65535;
memset(dma_queue, 0, sizeof(*dma_queue));
dma_queue->post_region_addr = post_region_addr;
dma_queue->hw_complete_count = 0;
dma_queue->credits_and_next_index = credits << DMA_QUEUE_CREDIT_SHIFT;
}
EXPORT_SYMBOL_GPL(__gxio_dma_queue_init);
void __gxio_dma_queue_update_credits(__gxio_dma_queue_t *dma_queue)
{
__gxio_ring_t val;
uint64_t count;
uint64_t delta;
uint64_t new_count;
/*
* Read the 64-bit completion count without touching the cache, so
* we later avoid having to evict any sharers of this cache line
* when we update it below.
*/
uint64_t orig_hw_complete_count =
cmpxchg(&dma_queue->hw_complete_count,
-1, -1);
/* Make sure the load completes before we access the hardware. */
wait_for_value(orig_hw_complete_count);
/* Read the 16-bit count of how many packets it has completed. */
val.word = __gxio_mmio_read(dma_queue->post_region_addr);
count = val.count;
/*
* Calculate the number of completions since we last updated the
* 64-bit counter. It's safe to ignore the high bits because the
* maximum credit value is 65535.
*/
delta = (count - orig_hw_complete_count) & 0xffff;
if (delta == 0)
return;
/*
* Try to write back the count, advanced by delta. If we race with
* another thread, this might fail, in which case we return
* immediately on the assumption that some credits are (or at least
* were) available.
*/
new_count = orig_hw_complete_count + delta;
if (cmpxchg(&dma_queue->hw_complete_count,
orig_hw_complete_count,
new_count) != orig_hw_complete_count)
return;
/*
* We succeeded in advancing the completion count; add back the
* corresponding number of egress credits.
*/
__insn_fetchadd(&dma_queue->credits_and_next_index,
(delta << DMA_QUEUE_CREDIT_SHIFT));
}
EXPORT_SYMBOL_GPL(__gxio_dma_queue_update_credits);
/*
* A separate 'blocked' method for put() so that backtraces and
* profiles will clearly indicate that we're wasting time spinning on
* egress availability rather than actually posting commands.
*/
int64_t __gxio_dma_queue_wait_for_credits(__gxio_dma_queue_t *dma_queue,
int64_t modifier)
{
int backoff = 16;
int64_t old;
do {
int i;
/* Back off to avoid spamming memory networks. */
for (i = backoff; i > 0; i--)
__insn_mfspr(SPR_PASS);
/* Check credits again. */
__gxio_dma_queue_update_credits(dma_queue);
old = __insn_fetchaddgez(&dma_queue->credits_and_next_index,
modifier);
/* Calculate bounded exponential backoff for next iteration. */
if (backoff < 256)
backoff *= 2;
} while (old + modifier < 0);
return old;
}
EXPORT_SYMBOL_GPL(__gxio_dma_queue_wait_for_credits);
int64_t __gxio_dma_queue_reserve_aux(__gxio_dma_queue_t *dma_queue,
unsigned int num, int wait)
{
return __gxio_dma_queue_reserve(dma_queue, num, wait != 0, true);
}
EXPORT_SYMBOL_GPL(__gxio_dma_queue_reserve_aux);
int __gxio_dma_queue_is_complete(__gxio_dma_queue_t *dma_queue,
int64_t completion_slot, int update)
{
if (update) {
if (ACCESS_ONCE(dma_queue->hw_complete_count) >
completion_slot)
return 1;
__gxio_dma_queue_update_credits(dma_queue);
}
return ACCESS_ONCE(dma_queue->hw_complete_count) > completion_slot;
}
EXPORT_SYMBOL_GPL(__gxio_dma_queue_is_complete);
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* This file is machine-generated; DO NOT EDIT! */
#include "gxio/iorpc_globals.h"
struct arm_pollfd_param {
union iorpc_pollfd pollfd;
};
int __iorpc_arm_pollfd(int fd, int pollfd_cookie)
{
struct arm_pollfd_param temp;
struct arm_pollfd_param *params = &temp;
params->pollfd.kernel.cookie = pollfd_cookie;
return hv_dev_pwrite(fd, 0, (HV_VirtAddr) params, sizeof(*params),
IORPC_OP_ARM_POLLFD);
}
EXPORT_SYMBOL(__iorpc_arm_pollfd);
struct close_pollfd_param {
union iorpc_pollfd pollfd;
};
int __iorpc_close_pollfd(int fd, int pollfd_cookie)
{
struct close_pollfd_param temp;
struct close_pollfd_param *params = &temp;
params->pollfd.kernel.cookie = pollfd_cookie;
return hv_dev_pwrite(fd, 0, (HV_VirtAddr) params, sizeof(*params),
IORPC_OP_CLOSE_POLLFD);
}
EXPORT_SYMBOL(__iorpc_close_pollfd);
struct get_mmio_base_param {
HV_PTE base;
};
int __iorpc_get_mmio_base(int fd, HV_PTE *base)
{
int __result;
struct get_mmio_base_param temp;
struct get_mmio_base_param *params = &temp;
__result =
hv_dev_pread(fd, 0, (HV_VirtAddr) params, sizeof(*params),
IORPC_OP_GET_MMIO_BASE);
*base = params->base;
return __result;
}
EXPORT_SYMBOL(__iorpc_get_mmio_base);
struct check_mmio_offset_param {
unsigned long offset;
unsigned long size;
};
int __iorpc_check_mmio_offset(int fd, unsigned long offset, unsigned long size)
{
struct check_mmio_offset_param temp;
struct check_mmio_offset_param *params = &temp;
params->offset = offset;
params->size = size;
return hv_dev_pwrite(fd, 0, (HV_VirtAddr) params, sizeof(*params),
IORPC_OP_CHECK_MMIO_OFFSET);
}
EXPORT_SYMBOL(__iorpc_check_mmio_offset);
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* This file is machine-generated; DO NOT EDIT! */
#include "gxio/iorpc_mpipe.h"
struct alloc_buffer_stacks_param {
unsigned int count;
unsigned int first;
unsigned int flags;
};
int gxio_mpipe_alloc_buffer_stacks(gxio_mpipe_context_t * context,
unsigned int count, unsigned int first,
unsigned int flags)
{
struct alloc_buffer_stacks_param temp;
struct alloc_buffer_stacks_param *params = &temp;
params->count = count;
params->first = first;
params->flags = flags;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params),
GXIO_MPIPE_OP_ALLOC_BUFFER_STACKS);
}
EXPORT_SYMBOL(gxio_mpipe_alloc_buffer_stacks);
struct init_buffer_stack_aux_param {
union iorpc_mem_buffer buffer;
unsigned int stack;
unsigned int buffer_size_enum;
};
int gxio_mpipe_init_buffer_stack_aux(gxio_mpipe_context_t * context,
void *mem_va, size_t mem_size,
unsigned int mem_flags, unsigned int stack,
unsigned int buffer_size_enum)
{
int __result;
unsigned long long __cpa;
pte_t __pte;
struct init_buffer_stack_aux_param temp;
struct init_buffer_stack_aux_param *params = &temp;
__result = va_to_cpa_and_pte(mem_va, &__cpa, &__pte);
if (__result != 0)
return __result;
params->buffer.kernel.cpa = __cpa;
params->buffer.kernel.size = mem_size;
params->buffer.kernel.pte = __pte;
params->buffer.kernel.flags = mem_flags;
params->stack = stack;
params->buffer_size_enum = buffer_size_enum;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params),
GXIO_MPIPE_OP_INIT_BUFFER_STACK_AUX);
}
EXPORT_SYMBOL(gxio_mpipe_init_buffer_stack_aux);
struct alloc_notif_rings_param {
unsigned int count;
unsigned int first;
unsigned int flags;
};
int gxio_mpipe_alloc_notif_rings(gxio_mpipe_context_t * context,
unsigned int count, unsigned int first,
unsigned int flags)
{
struct alloc_notif_rings_param temp;
struct alloc_notif_rings_param *params = &temp;
params->count = count;
params->first = first;
params->flags = flags;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_MPIPE_OP_ALLOC_NOTIF_RINGS);
}
EXPORT_SYMBOL(gxio_mpipe_alloc_notif_rings);
struct init_notif_ring_aux_param {
union iorpc_mem_buffer buffer;
unsigned int ring;
};
int gxio_mpipe_init_notif_ring_aux(gxio_mpipe_context_t * context, void *mem_va,
size_t mem_size, unsigned int mem_flags,
unsigned int ring)
{
int __result;
unsigned long long __cpa;
pte_t __pte;
struct init_notif_ring_aux_param temp;
struct init_notif_ring_aux_param *params = &temp;
__result = va_to_cpa_and_pte(mem_va, &__cpa, &__pte);
if (__result != 0)
return __result;
params->buffer.kernel.cpa = __cpa;
params->buffer.kernel.size = mem_size;
params->buffer.kernel.pte = __pte;
params->buffer.kernel.flags = mem_flags;
params->ring = ring;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params),
GXIO_MPIPE_OP_INIT_NOTIF_RING_AUX);
}
EXPORT_SYMBOL(gxio_mpipe_init_notif_ring_aux);
struct request_notif_ring_interrupt_param {
union iorpc_interrupt interrupt;
unsigned int ring;
};
int gxio_mpipe_request_notif_ring_interrupt(gxio_mpipe_context_t * context,
int inter_x, int inter_y,
int inter_ipi, int inter_event,
unsigned int ring)
{
struct request_notif_ring_interrupt_param temp;
struct request_notif_ring_interrupt_param *params = &temp;
params->interrupt.kernel.x = inter_x;
params->interrupt.kernel.y = inter_y;
params->interrupt.kernel.ipi = inter_ipi;
params->interrupt.kernel.event = inter_event;
params->ring = ring;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params),
GXIO_MPIPE_OP_REQUEST_NOTIF_RING_INTERRUPT);
}
EXPORT_SYMBOL(gxio_mpipe_request_notif_ring_interrupt);
struct enable_notif_ring_interrupt_param {
unsigned int ring;
};
int gxio_mpipe_enable_notif_ring_interrupt(gxio_mpipe_context_t * context,
unsigned int ring)
{
struct enable_notif_ring_interrupt_param temp;
struct enable_notif_ring_interrupt_param *params = &temp;
params->ring = ring;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params),
GXIO_MPIPE_OP_ENABLE_NOTIF_RING_INTERRUPT);
}
EXPORT_SYMBOL(gxio_mpipe_enable_notif_ring_interrupt);
struct alloc_notif_groups_param {
unsigned int count;
unsigned int first;
unsigned int flags;
};
int gxio_mpipe_alloc_notif_groups(gxio_mpipe_context_t * context,
unsigned int count, unsigned int first,
unsigned int flags)
{
struct alloc_notif_groups_param temp;
struct alloc_notif_groups_param *params = &temp;
params->count = count;
params->first = first;
params->flags = flags;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_MPIPE_OP_ALLOC_NOTIF_GROUPS);
}
EXPORT_SYMBOL(gxio_mpipe_alloc_notif_groups);
struct init_notif_group_param {
unsigned int group;
gxio_mpipe_notif_group_bits_t bits;
};
int gxio_mpipe_init_notif_group(gxio_mpipe_context_t * context,
unsigned int group,
gxio_mpipe_notif_group_bits_t bits)
{
struct init_notif_group_param temp;
struct init_notif_group_param *params = &temp;
params->group = group;
params->bits = bits;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_MPIPE_OP_INIT_NOTIF_GROUP);
}
EXPORT_SYMBOL(gxio_mpipe_init_notif_group);
struct alloc_buckets_param {
unsigned int count;
unsigned int first;
unsigned int flags;
};
int gxio_mpipe_alloc_buckets(gxio_mpipe_context_t * context, unsigned int count,
unsigned int first, unsigned int flags)
{
struct alloc_buckets_param temp;
struct alloc_buckets_param *params = &temp;
params->count = count;
params->first = first;
params->flags = flags;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_MPIPE_OP_ALLOC_BUCKETS);
}
EXPORT_SYMBOL(gxio_mpipe_alloc_buckets);
struct init_bucket_param {
unsigned int bucket;
MPIPE_LBL_INIT_DAT_BSTS_TBL_t bucket_info;
};
int gxio_mpipe_init_bucket(gxio_mpipe_context_t * context, unsigned int bucket,
MPIPE_LBL_INIT_DAT_BSTS_TBL_t bucket_info)
{
struct init_bucket_param temp;
struct init_bucket_param *params = &temp;
params->bucket = bucket;
params->bucket_info = bucket_info;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_MPIPE_OP_INIT_BUCKET);
}
EXPORT_SYMBOL(gxio_mpipe_init_bucket);
struct alloc_edma_rings_param {
unsigned int count;
unsigned int first;
unsigned int flags;
};
int gxio_mpipe_alloc_edma_rings(gxio_mpipe_context_t * context,
unsigned int count, unsigned int first,
unsigned int flags)
{
struct alloc_edma_rings_param temp;
struct alloc_edma_rings_param *params = &temp;
params->count = count;
params->first = first;
params->flags = flags;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_MPIPE_OP_ALLOC_EDMA_RINGS);
}
EXPORT_SYMBOL(gxio_mpipe_alloc_edma_rings);
struct init_edma_ring_aux_param {
union iorpc_mem_buffer buffer;
unsigned int ring;
unsigned int channel;
};
int gxio_mpipe_init_edma_ring_aux(gxio_mpipe_context_t * context, void *mem_va,
size_t mem_size, unsigned int mem_flags,
unsigned int ring, unsigned int channel)
{
int __result;
unsigned long long __cpa;
pte_t __pte;
struct init_edma_ring_aux_param temp;
struct init_edma_ring_aux_param *params = &temp;
__result = va_to_cpa_and_pte(mem_va, &__cpa, &__pte);
if (__result != 0)
return __result;
params->buffer.kernel.cpa = __cpa;
params->buffer.kernel.size = mem_size;
params->buffer.kernel.pte = __pte;
params->buffer.kernel.flags = mem_flags;
params->ring = ring;
params->channel = channel;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_MPIPE_OP_INIT_EDMA_RING_AUX);
}
EXPORT_SYMBOL(gxio_mpipe_init_edma_ring_aux);
int gxio_mpipe_commit_rules(gxio_mpipe_context_t * context, const void *blob,
size_t blob_size)
{
const void *params = blob;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params, blob_size,
GXIO_MPIPE_OP_COMMIT_RULES);
}
EXPORT_SYMBOL(gxio_mpipe_commit_rules);
struct register_client_memory_param {
unsigned int iotlb;
HV_PTE pte;
unsigned int flags;
};
int gxio_mpipe_register_client_memory(gxio_mpipe_context_t * context,
unsigned int iotlb, HV_PTE pte,
unsigned int flags)
{
struct register_client_memory_param temp;
struct register_client_memory_param *params = &temp;
params->iotlb = iotlb;
params->pte = pte;
params->flags = flags;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params),
GXIO_MPIPE_OP_REGISTER_CLIENT_MEMORY);
}
EXPORT_SYMBOL(gxio_mpipe_register_client_memory);
struct link_open_aux_param {
_gxio_mpipe_link_name_t name;
unsigned int flags;
};
int gxio_mpipe_link_open_aux(gxio_mpipe_context_t * context,
_gxio_mpipe_link_name_t name, unsigned int flags)
{
struct link_open_aux_param temp;
struct link_open_aux_param *params = &temp;
params->name = name;
params->flags = flags;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_MPIPE_OP_LINK_OPEN_AUX);
}
EXPORT_SYMBOL(gxio_mpipe_link_open_aux);
struct link_close_aux_param {
int mac;
};
int gxio_mpipe_link_close_aux(gxio_mpipe_context_t * context, int mac)
{
struct link_close_aux_param temp;
struct link_close_aux_param *params = &temp;
params->mac = mac;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_MPIPE_OP_LINK_CLOSE_AUX);
}
EXPORT_SYMBOL(gxio_mpipe_link_close_aux);
struct get_timestamp_aux_param {
uint64_t sec;
uint64_t nsec;
uint64_t cycles;
};
int gxio_mpipe_get_timestamp_aux(gxio_mpipe_context_t * context, uint64_t * sec,
uint64_t * nsec, uint64_t * cycles)
{
int __result;
struct get_timestamp_aux_param temp;
struct get_timestamp_aux_param *params = &temp;
__result =
hv_dev_pread(context->fd, 0, (HV_VirtAddr) params, sizeof(*params),
GXIO_MPIPE_OP_GET_TIMESTAMP_AUX);
*sec = params->sec;
*nsec = params->nsec;
*cycles = params->cycles;
return __result;
}
EXPORT_SYMBOL(gxio_mpipe_get_timestamp_aux);
struct set_timestamp_aux_param {
uint64_t sec;
uint64_t nsec;
uint64_t cycles;
};
int gxio_mpipe_set_timestamp_aux(gxio_mpipe_context_t * context, uint64_t sec,
uint64_t nsec, uint64_t cycles)
{
struct set_timestamp_aux_param temp;
struct set_timestamp_aux_param *params = &temp;
params->sec = sec;
params->nsec = nsec;
params->cycles = cycles;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_MPIPE_OP_SET_TIMESTAMP_AUX);
}
EXPORT_SYMBOL(gxio_mpipe_set_timestamp_aux);
struct adjust_timestamp_aux_param {
int64_t nsec;
};
int gxio_mpipe_adjust_timestamp_aux(gxio_mpipe_context_t * context,
int64_t nsec)
{
struct adjust_timestamp_aux_param temp;
struct adjust_timestamp_aux_param *params = &temp;
params->nsec = nsec;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params),
GXIO_MPIPE_OP_ADJUST_TIMESTAMP_AUX);
}
EXPORT_SYMBOL(gxio_mpipe_adjust_timestamp_aux);
struct arm_pollfd_param {
union iorpc_pollfd pollfd;
};
int gxio_mpipe_arm_pollfd(gxio_mpipe_context_t * context, int pollfd_cookie)
{
struct arm_pollfd_param temp;
struct arm_pollfd_param *params = &temp;
params->pollfd.kernel.cookie = pollfd_cookie;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_MPIPE_OP_ARM_POLLFD);
}
EXPORT_SYMBOL(gxio_mpipe_arm_pollfd);
struct close_pollfd_param {
union iorpc_pollfd pollfd;
};
int gxio_mpipe_close_pollfd(gxio_mpipe_context_t * context, int pollfd_cookie)
{
struct close_pollfd_param temp;
struct close_pollfd_param *params = &temp;
params->pollfd.kernel.cookie = pollfd_cookie;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_MPIPE_OP_CLOSE_POLLFD);
}
EXPORT_SYMBOL(gxio_mpipe_close_pollfd);
struct get_mmio_base_param {
HV_PTE base;
};
int gxio_mpipe_get_mmio_base(gxio_mpipe_context_t * context, HV_PTE *base)
{
int __result;
struct get_mmio_base_param temp;
struct get_mmio_base_param *params = &temp;
__result =
hv_dev_pread(context->fd, 0, (HV_VirtAddr) params, sizeof(*params),
GXIO_MPIPE_OP_GET_MMIO_BASE);
*base = params->base;
return __result;
}
EXPORT_SYMBOL(gxio_mpipe_get_mmio_base);
struct check_mmio_offset_param {
unsigned long offset;
unsigned long size;
};
int gxio_mpipe_check_mmio_offset(gxio_mpipe_context_t * context,
unsigned long offset, unsigned long size)
{
struct check_mmio_offset_param temp;
struct check_mmio_offset_param *params = &temp;
params->offset = offset;
params->size = size;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_MPIPE_OP_CHECK_MMIO_OFFSET);
}
EXPORT_SYMBOL(gxio_mpipe_check_mmio_offset);
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* This file is machine-generated; DO NOT EDIT! */
#include "gxio/iorpc_mpipe_info.h"
struct enumerate_aux_param {
_gxio_mpipe_link_name_t name;
_gxio_mpipe_link_mac_t mac;
};
int gxio_mpipe_info_enumerate_aux(gxio_mpipe_info_context_t * context,
unsigned int idx,
_gxio_mpipe_link_name_t * name,
_gxio_mpipe_link_mac_t * mac)
{
int __result;
struct enumerate_aux_param temp;
struct enumerate_aux_param *params = &temp;
__result =
hv_dev_pread(context->fd, 0, (HV_VirtAddr) params, sizeof(*params),
(((uint64_t) idx << 32) |
GXIO_MPIPE_INFO_OP_ENUMERATE_AUX));
*name = params->name;
*mac = params->mac;
return __result;
}
EXPORT_SYMBOL(gxio_mpipe_info_enumerate_aux);
struct get_mmio_base_param {
HV_PTE base;
};
int gxio_mpipe_info_get_mmio_base(gxio_mpipe_info_context_t * context,
HV_PTE *base)
{
int __result;
struct get_mmio_base_param temp;
struct get_mmio_base_param *params = &temp;
__result =
hv_dev_pread(context->fd, 0, (HV_VirtAddr) params, sizeof(*params),
GXIO_MPIPE_INFO_OP_GET_MMIO_BASE);
*base = params->base;
return __result;
}
EXPORT_SYMBOL(gxio_mpipe_info_get_mmio_base);
struct check_mmio_offset_param {
unsigned long offset;
unsigned long size;
};
int gxio_mpipe_info_check_mmio_offset(gxio_mpipe_info_context_t * context,
unsigned long offset, unsigned long size)
{
struct check_mmio_offset_param temp;
struct check_mmio_offset_param *params = &temp;
params->offset = offset;
params->size = size;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params),
GXIO_MPIPE_INFO_OP_CHECK_MMIO_OFFSET);
}
EXPORT_SYMBOL(gxio_mpipe_info_check_mmio_offset);
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* This file is machine-generated; DO NOT EDIT! */
#include "gxio/iorpc_trio.h"
struct alloc_asids_param {
unsigned int count;
unsigned int first;
unsigned int flags;
};
int gxio_trio_alloc_asids(gxio_trio_context_t * context, unsigned int count,
unsigned int first, unsigned int flags)
{
struct alloc_asids_param temp;
struct alloc_asids_param *params = &temp;
params->count = count;
params->first = first;
params->flags = flags;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_TRIO_OP_ALLOC_ASIDS);
}
EXPORT_SYMBOL(gxio_trio_alloc_asids);
struct alloc_memory_maps_param {
unsigned int count;
unsigned int first;
unsigned int flags;
};
int gxio_trio_alloc_memory_maps(gxio_trio_context_t * context,
unsigned int count, unsigned int first,
unsigned int flags)
{
struct alloc_memory_maps_param temp;
struct alloc_memory_maps_param *params = &temp;
params->count = count;
params->first = first;
params->flags = flags;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_TRIO_OP_ALLOC_MEMORY_MAPS);
}
EXPORT_SYMBOL(gxio_trio_alloc_memory_maps);
struct alloc_pio_regions_param {
unsigned int count;
unsigned int first;
unsigned int flags;
};
int gxio_trio_alloc_pio_regions(gxio_trio_context_t * context,
unsigned int count, unsigned int first,
unsigned int flags)
{
struct alloc_pio_regions_param temp;
struct alloc_pio_regions_param *params = &temp;
params->count = count;
params->first = first;
params->flags = flags;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_TRIO_OP_ALLOC_PIO_REGIONS);
}
EXPORT_SYMBOL(gxio_trio_alloc_pio_regions);
struct init_pio_region_aux_param {
unsigned int pio_region;
unsigned int mac;
uint32_t bus_address_hi;
unsigned int flags;
};
int gxio_trio_init_pio_region_aux(gxio_trio_context_t * context,
unsigned int pio_region, unsigned int mac,
uint32_t bus_address_hi, unsigned int flags)
{
struct init_pio_region_aux_param temp;
struct init_pio_region_aux_param *params = &temp;
params->pio_region = pio_region;
params->mac = mac;
params->bus_address_hi = bus_address_hi;
params->flags = flags;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_TRIO_OP_INIT_PIO_REGION_AUX);
}
EXPORT_SYMBOL(gxio_trio_init_pio_region_aux);
struct init_memory_map_mmu_aux_param {
unsigned int map;
unsigned long va;
uint64_t size;
unsigned int asid;
unsigned int mac;
uint64_t bus_address;
unsigned int node;
unsigned int order_mode;
};
int gxio_trio_init_memory_map_mmu_aux(gxio_trio_context_t * context,
unsigned int map, unsigned long va,
uint64_t size, unsigned int asid,
unsigned int mac, uint64_t bus_address,
unsigned int node,
unsigned int order_mode)
{
struct init_memory_map_mmu_aux_param temp;
struct init_memory_map_mmu_aux_param *params = &temp;
params->map = map;
params->va = va;
params->size = size;
params->asid = asid;
params->mac = mac;
params->bus_address = bus_address;
params->node = node;
params->order_mode = order_mode;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params),
GXIO_TRIO_OP_INIT_MEMORY_MAP_MMU_AUX);
}
EXPORT_SYMBOL(gxio_trio_init_memory_map_mmu_aux);
struct get_port_property_param {
struct pcie_trio_ports_property trio_ports;
};
int gxio_trio_get_port_property(gxio_trio_context_t * context,
struct pcie_trio_ports_property *trio_ports)
{
int __result;
struct get_port_property_param temp;
struct get_port_property_param *params = &temp;
__result =
hv_dev_pread(context->fd, 0, (HV_VirtAddr) params, sizeof(*params),
GXIO_TRIO_OP_GET_PORT_PROPERTY);
*trio_ports = params->trio_ports;
return __result;
}
EXPORT_SYMBOL(gxio_trio_get_port_property);
struct config_legacy_intr_param {
union iorpc_interrupt interrupt;
unsigned int mac;
unsigned int intx;
};
int gxio_trio_config_legacy_intr(gxio_trio_context_t * context, int inter_x,
int inter_y, int inter_ipi, int inter_event,
unsigned int mac, unsigned int intx)
{
struct config_legacy_intr_param temp;
struct config_legacy_intr_param *params = &temp;
params->interrupt.kernel.x = inter_x;
params->interrupt.kernel.y = inter_y;
params->interrupt.kernel.ipi = inter_ipi;
params->interrupt.kernel.event = inter_event;
params->mac = mac;
params->intx = intx;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_TRIO_OP_CONFIG_LEGACY_INTR);
}
EXPORT_SYMBOL(gxio_trio_config_legacy_intr);
struct config_msi_intr_param {
union iorpc_interrupt interrupt;
unsigned int mac;
unsigned int mem_map;
uint64_t mem_map_base;
uint64_t mem_map_limit;
unsigned int asid;
};
int gxio_trio_config_msi_intr(gxio_trio_context_t * context, int inter_x,
int inter_y, int inter_ipi, int inter_event,
unsigned int mac, unsigned int mem_map,
uint64_t mem_map_base, uint64_t mem_map_limit,
unsigned int asid)
{
struct config_msi_intr_param temp;
struct config_msi_intr_param *params = &temp;
params->interrupt.kernel.x = inter_x;
params->interrupt.kernel.y = inter_y;
params->interrupt.kernel.ipi = inter_ipi;
params->interrupt.kernel.event = inter_event;
params->mac = mac;
params->mem_map = mem_map;
params->mem_map_base = mem_map_base;
params->mem_map_limit = mem_map_limit;
params->asid = asid;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_TRIO_OP_CONFIG_MSI_INTR);
}
EXPORT_SYMBOL(gxio_trio_config_msi_intr);
struct set_mps_mrs_param {
uint16_t mps;
uint16_t mrs;
unsigned int mac;
};
int gxio_trio_set_mps_mrs(gxio_trio_context_t * context, uint16_t mps,
uint16_t mrs, unsigned int mac)
{
struct set_mps_mrs_param temp;
struct set_mps_mrs_param *params = &temp;
params->mps = mps;
params->mrs = mrs;
params->mac = mac;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_TRIO_OP_SET_MPS_MRS);
}
EXPORT_SYMBOL(gxio_trio_set_mps_mrs);
struct force_rc_link_up_param {
unsigned int mac;
};
int gxio_trio_force_rc_link_up(gxio_trio_context_t * context, unsigned int mac)
{
struct force_rc_link_up_param temp;
struct force_rc_link_up_param *params = &temp;
params->mac = mac;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_TRIO_OP_FORCE_RC_LINK_UP);
}
EXPORT_SYMBOL(gxio_trio_force_rc_link_up);
struct force_ep_link_up_param {
unsigned int mac;
};
int gxio_trio_force_ep_link_up(gxio_trio_context_t * context, unsigned int mac)
{
struct force_ep_link_up_param temp;
struct force_ep_link_up_param *params = &temp;
params->mac = mac;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_TRIO_OP_FORCE_EP_LINK_UP);
}
EXPORT_SYMBOL(gxio_trio_force_ep_link_up);
struct get_mmio_base_param {
HV_PTE base;
};
int gxio_trio_get_mmio_base(gxio_trio_context_t * context, HV_PTE *base)
{
int __result;
struct get_mmio_base_param temp;
struct get_mmio_base_param *params = &temp;
__result =
hv_dev_pread(context->fd, 0, (HV_VirtAddr) params, sizeof(*params),
GXIO_TRIO_OP_GET_MMIO_BASE);
*base = params->base;
return __result;
}
EXPORT_SYMBOL(gxio_trio_get_mmio_base);
struct check_mmio_offset_param {
unsigned long offset;
unsigned long size;
};
int gxio_trio_check_mmio_offset(gxio_trio_context_t * context,
unsigned long offset, unsigned long size)
{
struct check_mmio_offset_param temp;
struct check_mmio_offset_param *params = &temp;
params->offset = offset;
params->size = size;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_TRIO_OP_CHECK_MMIO_OFFSET);
}
EXPORT_SYMBOL(gxio_trio_check_mmio_offset);
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* This file is machine-generated; DO NOT EDIT! */
#include "gxio/iorpc_usb_host.h"
struct cfg_interrupt_param {
union iorpc_interrupt interrupt;
};
int gxio_usb_host_cfg_interrupt(gxio_usb_host_context_t * context, int inter_x,
int inter_y, int inter_ipi, int inter_event)
{
struct cfg_interrupt_param temp;
struct cfg_interrupt_param *params = &temp;
params->interrupt.kernel.x = inter_x;
params->interrupt.kernel.y = inter_y;
params->interrupt.kernel.ipi = inter_ipi;
params->interrupt.kernel.event = inter_event;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params), GXIO_USB_HOST_OP_CFG_INTERRUPT);
}
EXPORT_SYMBOL(gxio_usb_host_cfg_interrupt);
struct register_client_memory_param {
HV_PTE pte;
unsigned int flags;
};
int gxio_usb_host_register_client_memory(gxio_usb_host_context_t * context,
HV_PTE pte, unsigned int flags)
{
struct register_client_memory_param temp;
struct register_client_memory_param *params = &temp;
params->pte = pte;
params->flags = flags;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params),
GXIO_USB_HOST_OP_REGISTER_CLIENT_MEMORY);
}
EXPORT_SYMBOL(gxio_usb_host_register_client_memory);
struct get_mmio_base_param {
HV_PTE base;
};
int gxio_usb_host_get_mmio_base(gxio_usb_host_context_t * context, HV_PTE *base)
{
int __result;
struct get_mmio_base_param temp;
struct get_mmio_base_param *params = &temp;
__result =
hv_dev_pread(context->fd, 0, (HV_VirtAddr) params, sizeof(*params),
GXIO_USB_HOST_OP_GET_MMIO_BASE);
*base = params->base;
return __result;
}
EXPORT_SYMBOL(gxio_usb_host_get_mmio_base);
struct check_mmio_offset_param {
unsigned long offset;
unsigned long size;
};
int gxio_usb_host_check_mmio_offset(gxio_usb_host_context_t * context,
unsigned long offset, unsigned long size)
{
struct check_mmio_offset_param temp;
struct check_mmio_offset_param *params = &temp;
params->offset = offset;
params->size = size;
return hv_dev_pwrite(context->fd, 0, (HV_VirtAddr) params,
sizeof(*params),
GXIO_USB_HOST_OP_CHECK_MMIO_OFFSET);
}
EXPORT_SYMBOL(gxio_usb_host_check_mmio_offset);
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*
* TILE-Gx IORPC support for kernel I/O drivers.
*/
#include <linux/mmzone.h>
#include <linux/module.h>
#include <linux/io.h>
#include <gxio/iorpc_globals.h>
#include <gxio/kiorpc.h>
#ifdef DEBUG_IORPC
#define TRACE(FMT, ...) pr_info(SIMPLE_MSG_LINE FMT, ## __VA_ARGS__)
#else
#define TRACE(...)
#endif
/* Create kernel-VA-space MMIO mapping for an on-chip IO device. */
void __iomem *iorpc_ioremap(int hv_fd, resource_size_t offset,
unsigned long size)
{
pgprot_t mmio_base, prot = { 0 };
unsigned long pfn;
int err;
/* Look up the shim's lotar and base PA. */
err = __iorpc_get_mmio_base(hv_fd, &mmio_base);
if (err) {
TRACE("get_mmio_base() failure: %d\n", err);
return NULL;
}
/* Make sure the HV driver approves of our offset and size. */
err = __iorpc_check_mmio_offset(hv_fd, offset, size);
if (err) {
TRACE("check_mmio_offset() failure: %d\n", err);
return NULL;
}
/*
* mmio_base contains a base pfn and homing coordinates. Turn
* it into an MMIO pgprot and offset pfn.
*/
prot = hv_pte_set_lotar(prot, hv_pte_get_lotar(mmio_base));
pfn = pte_pfn(mmio_base) + PFN_DOWN(offset);
return ioremap_prot(PFN_PHYS(pfn), size, prot);
}
EXPORT_SYMBOL(iorpc_ioremap);
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/*
* Implementation of mpipe gxio calls.
*/
#include <linux/errno.h>
#include <linux/io.h>
#include <linux/module.h>
#include <gxio/iorpc_globals.h>
#include <gxio/iorpc_mpipe.h>
#include <gxio/iorpc_mpipe_info.h>
#include <gxio/kiorpc.h>
#include <gxio/mpipe.h>
/* HACK: Avoid pointless "shadow" warnings. */
#define link link_shadow
int gxio_mpipe_init(gxio_mpipe_context_t *context, unsigned int mpipe_index)
{
char file[32];
int fd;
int i;
snprintf(file, sizeof(file), "mpipe/%d/iorpc", mpipe_index);
fd = hv_dev_open((HV_VirtAddr) file, 0);
if (fd < 0) {
if (fd >= GXIO_ERR_MIN && fd <= GXIO_ERR_MAX)
return fd;
else
return -ENODEV;
}
context->fd = fd;
/* Map in the MMIO space. */
context->mmio_cfg_base = (void __force *)
iorpc_ioremap(fd, HV_MPIPE_CONFIG_MMIO_OFFSET,
HV_MPIPE_CONFIG_MMIO_SIZE);
if (context->mmio_cfg_base == NULL)
goto cfg_failed;
context->mmio_fast_base = (void __force *)
iorpc_ioremap(fd, HV_MPIPE_FAST_MMIO_OFFSET,
HV_MPIPE_FAST_MMIO_SIZE);
if (context->mmio_fast_base == NULL)
goto fast_failed;
/* Initialize the stacks. */
for (i = 0; i < 8; i++)
context->__stacks.stacks[i] = 255;
return 0;
fast_failed:
iounmap((void __force __iomem *)(context->mmio_cfg_base));
cfg_failed:
hv_dev_close(context->fd);
return -ENODEV;
}
EXPORT_SYMBOL_GPL(gxio_mpipe_init);
int gxio_mpipe_destroy(gxio_mpipe_context_t *context)
{
iounmap((void __force __iomem *)(context->mmio_cfg_base));
iounmap((void __force __iomem *)(context->mmio_fast_base));
return hv_dev_close(context->fd);
}
EXPORT_SYMBOL_GPL(gxio_mpipe_destroy);
static int16_t gxio_mpipe_buffer_sizes[8] =
{ 128, 256, 512, 1024, 1664, 4096, 10368, 16384 };
gxio_mpipe_buffer_size_enum_t gxio_mpipe_buffer_size_to_buffer_size_enum(size_t
size)
{
int i;
for (i = 0; i < 7; i++)
if (size <= gxio_mpipe_buffer_sizes[i])
break;
return i;
}
EXPORT_SYMBOL_GPL(gxio_mpipe_buffer_size_to_buffer_size_enum);
size_t gxio_mpipe_buffer_size_enum_to_buffer_size(gxio_mpipe_buffer_size_enum_t
buffer_size_enum)
{
if (buffer_size_enum > 7)
buffer_size_enum = 7;
return gxio_mpipe_buffer_sizes[buffer_size_enum];
}
EXPORT_SYMBOL_GPL(gxio_mpipe_buffer_size_enum_to_buffer_size);
size_t gxio_mpipe_calc_buffer_stack_bytes(unsigned long buffers)
{
const int BUFFERS_PER_LINE = 12;
/* Count the number of cachlines. */
unsigned long lines =
(buffers + BUFFERS_PER_LINE - 1) / BUFFERS_PER_LINE;
/* Convert to bytes. */
return lines * CHIP_L2_LINE_SIZE();
}
EXPORT_SYMBOL_GPL(gxio_mpipe_calc_buffer_stack_bytes);
int gxio_mpipe_init_buffer_stack(gxio_mpipe_context_t *context,
unsigned int stack,
gxio_mpipe_buffer_size_enum_t
buffer_size_enum, void *mem, size_t mem_size,
unsigned int mem_flags)
{
int result;
memset(mem, 0, mem_size);
result = gxio_mpipe_init_buffer_stack_aux(context, mem, mem_size,
mem_flags, stack,
buffer_size_enum);
if (result < 0)
return result;
/* Save the stack. */
context->__stacks.stacks[buffer_size_enum] = stack;
return 0;
}
EXPORT_SYMBOL_GPL(gxio_mpipe_init_buffer_stack);
int gxio_mpipe_init_notif_ring(gxio_mpipe_context_t *context,
unsigned int ring,
void *mem, size_t mem_size,
unsigned int mem_flags)
{
return gxio_mpipe_init_notif_ring_aux(context, mem, mem_size,
mem_flags, ring);
}
EXPORT_SYMBOL_GPL(gxio_mpipe_init_notif_ring);
int gxio_mpipe_init_notif_group_and_buckets(gxio_mpipe_context_t *context,
unsigned int group,
unsigned int ring,
unsigned int num_rings,
unsigned int bucket,
unsigned int num_buckets,
gxio_mpipe_bucket_mode_t mode)
{
int i;
int result;
gxio_mpipe_bucket_info_t bucket_info = { {
.group = group,
.mode = mode,
}
};
gxio_mpipe_notif_group_bits_t bits = { {0} };
for (i = 0; i < num_rings; i++)
gxio_mpipe_notif_group_add_ring(&bits, ring + i);
result = gxio_mpipe_init_notif_group(context, group, bits);
if (result != 0)
return result;
for (i = 0; i < num_buckets; i++) {
bucket_info.notifring = ring + (i % num_rings);
result = gxio_mpipe_init_bucket(context, bucket + i,
bucket_info);
if (result != 0)
return result;
}
return 0;
}
EXPORT_SYMBOL_GPL(gxio_mpipe_init_notif_group_and_buckets);
int gxio_mpipe_init_edma_ring(gxio_mpipe_context_t *context,
unsigned int ring, unsigned int channel,
void *mem, size_t mem_size,
unsigned int mem_flags)
{
memset(mem, 0, mem_size);
return gxio_mpipe_init_edma_ring_aux(context, mem, mem_size, mem_flags,
ring, channel);
}
EXPORT_SYMBOL_GPL(gxio_mpipe_init_edma_ring);
void gxio_mpipe_rules_init(gxio_mpipe_rules_t *rules,
gxio_mpipe_context_t *context)
{
rules->context = context;
memset(&rules->list, 0, sizeof(rules->list));
}
EXPORT_SYMBOL_GPL(gxio_mpipe_rules_init);
int gxio_mpipe_rules_begin(gxio_mpipe_rules_t *rules,
unsigned int bucket, unsigned int num_buckets,
gxio_mpipe_rules_stacks_t *stacks)
{
int i;
int stack = 255;
gxio_mpipe_rules_list_t *list = &rules->list;
/* Current rule. */
gxio_mpipe_rules_rule_t *rule =
(gxio_mpipe_rules_rule_t *) (list->rules + list->head);
unsigned int head = list->tail;
/*
* Align next rule properly.
*Note that "dmacs_and_vlans" will also be aligned.
*/
unsigned int pad = 0;
while (((head + pad) % __alignof__(gxio_mpipe_rules_rule_t)) != 0)
pad++;
/*
* Verify room.
* ISSUE: Mark rules as broken on error?
*/
if (head + pad + sizeof(*rule) >= sizeof(list->rules))
return GXIO_MPIPE_ERR_RULES_FULL;
/* Verify num_buckets is a power of 2. */
if (__builtin_popcount(num_buckets) != 1)
return GXIO_MPIPE_ERR_RULES_INVALID;
/* Add padding to previous rule. */
rule->size += pad;
/* Start a new rule. */
list->head = head + pad;
rule = (gxio_mpipe_rules_rule_t *) (list->rules + list->head);
/* Default some values. */
rule->headroom = 2;
rule->tailroom = 0;
rule->capacity = 16384;
/* Save the bucket info. */
rule->bucket_mask = num_buckets - 1;
rule->bucket_first = bucket;
for (i = 8 - 1; i >= 0; i--) {
int maybe =
stacks ? stacks->stacks[i] : rules->context->__stacks.
stacks[i];
if (maybe != 255)
stack = maybe;
rule->stacks.stacks[i] = stack;
}
if (stack == 255)
return GXIO_MPIPE_ERR_RULES_INVALID;
/* NOTE: Only entries at the end of the array can be 255. */
for (i = 8 - 1; i > 0; i--) {
if (rule->stacks.stacks[i] == 255) {
rule->stacks.stacks[i] = stack;
rule->capacity =
gxio_mpipe_buffer_size_enum_to_buffer_size(i -
1);
}
}
rule->size = sizeof(*rule);
list->tail = list->head + rule->size;
return 0;
}
EXPORT_SYMBOL_GPL(gxio_mpipe_rules_begin);
int gxio_mpipe_rules_add_channel(gxio_mpipe_rules_t *rules,
unsigned int channel)
{
gxio_mpipe_rules_list_t *list = &rules->list;
gxio_mpipe_rules_rule_t *rule =
(gxio_mpipe_rules_rule_t *) (list->rules + list->head);
/* Verify channel. */
if (channel >= 32)
return GXIO_MPIPE_ERR_RULES_INVALID;
/* Verify begun. */
if (list->tail == 0)
return GXIO_MPIPE_ERR_RULES_EMPTY;
rule->channel_bits |= (1UL << channel);
return 0;
}
EXPORT_SYMBOL_GPL(gxio_mpipe_rules_add_channel);
int gxio_mpipe_rules_set_headroom(gxio_mpipe_rules_t *rules, uint8_t headroom)
{
gxio_mpipe_rules_list_t *list = &rules->list;
gxio_mpipe_rules_rule_t *rule =
(gxio_mpipe_rules_rule_t *) (list->rules + list->head);
/* Verify begun. */
if (list->tail == 0)
return GXIO_MPIPE_ERR_RULES_EMPTY;
rule->headroom = headroom;
return 0;
}
EXPORT_SYMBOL_GPL(gxio_mpipe_rules_set_headroom);
int gxio_mpipe_rules_commit(gxio_mpipe_rules_t *rules)
{
gxio_mpipe_rules_list_t *list = &rules->list;
unsigned int size =
offsetof(gxio_mpipe_rules_list_t, rules) + list->tail;
return gxio_mpipe_commit_rules(rules->context, list, size);
}
EXPORT_SYMBOL_GPL(gxio_mpipe_rules_commit);
int gxio_mpipe_iqueue_init(gxio_mpipe_iqueue_t *iqueue,
gxio_mpipe_context_t *context,
unsigned int ring,
void *mem, size_t mem_size, unsigned int mem_flags)
{
/* The init call below will verify that "mem_size" is legal. */
unsigned int num_entries = mem_size / sizeof(gxio_mpipe_idesc_t);
iqueue->context = context;
iqueue->idescs = (gxio_mpipe_idesc_t *)mem;
iqueue->ring = ring;
iqueue->num_entries = num_entries;
iqueue->mask_num_entries = num_entries - 1;
iqueue->log2_num_entries = __builtin_ctz(num_entries);
iqueue->head = 1;
#ifdef __BIG_ENDIAN__
iqueue->swapped = 0;
#endif
/* Initialize the "tail". */
__gxio_mmio_write(mem, iqueue->head);
return gxio_mpipe_init_notif_ring(context, ring, mem, mem_size,
mem_flags);
}
EXPORT_SYMBOL_GPL(gxio_mpipe_iqueue_init);
int gxio_mpipe_equeue_init(gxio_mpipe_equeue_t *equeue,
gxio_mpipe_context_t *context,
unsigned int edma_ring_id,
unsigned int channel,
void *mem, unsigned int mem_size,
unsigned int mem_flags)
{
/* The init call below will verify that "mem_size" is legal. */
unsigned int num_entries = mem_size / sizeof(gxio_mpipe_edesc_t);
/* Offset used to read number of completed commands. */
MPIPE_EDMA_POST_REGION_ADDR_t offset;
int result = gxio_mpipe_init_edma_ring(context, edma_ring_id, channel,
mem, mem_size, mem_flags);
if (result < 0)
return result;
memset(equeue, 0, sizeof(*equeue));
offset.word = 0;
offset.region =
MPIPE_MMIO_ADDR__REGION_VAL_EDMA -
MPIPE_MMIO_ADDR__REGION_VAL_IDMA;
offset.ring = edma_ring_id;
__gxio_dma_queue_init(&equeue->dma_queue,
context->mmio_fast_base + offset.word,
num_entries);
equeue->edescs = mem;
equeue->mask_num_entries = num_entries - 1;
equeue->log2_num_entries = __builtin_ctz(num_entries);
return 0;
}
EXPORT_SYMBOL_GPL(gxio_mpipe_equeue_init);
int gxio_mpipe_set_timestamp(gxio_mpipe_context_t *context,
const struct timespec *ts)
{
cycles_t cycles = get_cycles();
return gxio_mpipe_set_timestamp_aux(context, (uint64_t)ts->tv_sec,
(uint64_t)ts->tv_nsec,
(uint64_t)cycles);
}
int gxio_mpipe_get_timestamp(gxio_mpipe_context_t *context,
struct timespec *ts)
{
int ret;
cycles_t cycles_prev, cycles_now, clock_rate;
cycles_prev = get_cycles();
ret = gxio_mpipe_get_timestamp_aux(context, (uint64_t *)&ts->tv_sec,
(uint64_t *)&ts->tv_nsec,
(uint64_t *)&cycles_now);
if (ret < 0) {
return ret;
}
clock_rate = get_clock_rate();
ts->tv_nsec -= (cycles_now - cycles_prev) * 1000000000LL / clock_rate;
if (ts->tv_nsec < 0) {
ts->tv_nsec += 1000000000LL;
ts->tv_sec -= 1;
}
return ret;
}
int gxio_mpipe_adjust_timestamp(gxio_mpipe_context_t *context, int64_t delta)
{
return gxio_mpipe_adjust_timestamp_aux(context, delta);
}
/* Get our internal context used for link name access. This context is
* special in that it is not associated with an mPIPE service domain.
*/
static gxio_mpipe_context_t *_gxio_get_link_context(void)
{
static gxio_mpipe_context_t context;
static gxio_mpipe_context_t *contextp;
static int tried_open = 0;
static DEFINE_MUTEX(mutex);
mutex_lock(&mutex);
if (!tried_open) {
int i = 0;
tried_open = 1;
/*
* "4" here is the maximum possible number of mPIPE shims; it's
* an exaggeration but we shouldn't ever go beyond 2 anyway.
*/
for (i = 0; i < 4; i++) {
char file[80];
snprintf(file, sizeof(file), "mpipe/%d/iorpc_info", i);
context.fd = hv_dev_open((HV_VirtAddr) file, 0);
if (context.fd < 0)
continue;
contextp = &context;
break;
}
}
mutex_unlock(&mutex);
return contextp;
}
int gxio_mpipe_link_enumerate_mac(int idx, char *link_name, uint8_t *link_mac)
{
int rv;
_gxio_mpipe_link_name_t name;
_gxio_mpipe_link_mac_t mac;
gxio_mpipe_context_t *context = _gxio_get_link_context();
if (!context)
return GXIO_ERR_NO_DEVICE;
rv = gxio_mpipe_info_enumerate_aux(context, idx, &name, &mac);
if (rv >= 0) {
strncpy(link_name, name.name, sizeof(name.name));
memcpy(link_mac, mac.mac, sizeof(mac.mac));
}
return rv;
}
EXPORT_SYMBOL_GPL(gxio_mpipe_link_enumerate_mac);
int gxio_mpipe_link_open(gxio_mpipe_link_t *link,
gxio_mpipe_context_t *context, const char *link_name,
unsigned int flags)
{
_gxio_mpipe_link_name_t name;
int rv;
strncpy(name.name, link_name, sizeof(name.name));
name.name[GXIO_MPIPE_LINK_NAME_LEN - 1] = '\0';
rv = gxio_mpipe_link_open_aux(context, name, flags);
if (rv < 0)
return rv;
link->context = context;
link->channel = rv >> 8;
link->mac = rv & 0xFF;
return 0;
}
EXPORT_SYMBOL_GPL(gxio_mpipe_link_open);
int gxio_mpipe_link_close(gxio_mpipe_link_t *link)
{
return gxio_mpipe_link_close_aux(link->context, link->mac);
}
EXPORT_SYMBOL_GPL(gxio_mpipe_link_close);
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/*
* Implementation of trio gxio calls.
*/
#include <linux/errno.h>
#include <linux/io.h>
#include <linux/module.h>
#include <gxio/trio.h>
#include <gxio/iorpc_globals.h>
#include <gxio/iorpc_trio.h>
#include <gxio/kiorpc.h>
int gxio_trio_init(gxio_trio_context_t *context, unsigned int trio_index)
{
char file[32];
int fd;
snprintf(file, sizeof(file), "trio/%d/iorpc", trio_index);
fd = hv_dev_open((HV_VirtAddr) file, 0);
if (fd < 0) {
context->fd = -1;
if (fd >= GXIO_ERR_MIN && fd <= GXIO_ERR_MAX)
return fd;
else
return -ENODEV;
}
context->fd = fd;
return 0;
}
EXPORT_SYMBOL_GPL(gxio_trio_init);
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/*
*
* Implementation of USB gxio calls.
*/
#include <linux/io.h>
#include <linux/errno.h>
#include <linux/module.h>
#include <gxio/iorpc_globals.h>
#include <gxio/iorpc_usb_host.h>
#include <gxio/kiorpc.h>
#include <gxio/usb_host.h>
int gxio_usb_host_init(gxio_usb_host_context_t * context, int usb_index,
int is_ehci)
{
char file[32];
int fd;
if (is_ehci)
snprintf(file, sizeof(file), "usb_host/%d/iorpc/ehci",
usb_index);
else
snprintf(file, sizeof(file), "usb_host/%d/iorpc/ohci",
usb_index);
fd = hv_dev_open((HV_VirtAddr) file, 0);
if (fd < 0) {
if (fd >= GXIO_ERR_MIN && fd <= GXIO_ERR_MAX)
return fd;
else
return -ENODEV;
}
context->fd = fd;
// Map in the MMIO space.
context->mmio_base =
(void __force *)iorpc_ioremap(fd, 0, HV_USB_HOST_MMIO_SIZE);
if (context->mmio_base == NULL) {
hv_dev_close(context->fd);
return -ENODEV;
}
return 0;
}
EXPORT_SYMBOL_GPL(gxio_usb_host_init);
int gxio_usb_host_destroy(gxio_usb_host_context_t * context)
{
iounmap((void __force __iomem *)(context->mmio_base));
hv_dev_close(context->fd);
context->mmio_base = NULL;
context->fd = -1;
return 0;
}
EXPORT_SYMBOL_GPL(gxio_usb_host_destroy);
void *gxio_usb_host_get_reg_start(gxio_usb_host_context_t * context)
{
return context->mmio_base;
}
EXPORT_SYMBOL_GPL(gxio_usb_host_get_reg_start);
size_t gxio_usb_host_get_reg_len(gxio_usb_host_context_t * context)
{
return HV_USB_HOST_MMIO_SIZE;
}
EXPORT_SYMBOL_GPL(gxio_usb_host_get_reg_len);
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_MPIPE_H__
#define __ARCH_MPIPE_H__
#include <arch/abi.h>
#include <arch/mpipe_def.h>
#ifndef __ASSEMBLER__
/*
* MMIO Ingress DMA Release Region Address.
* This is a description of the physical addresses used to manipulate ingress
* credit counters. Accesses to this address space should use an address of
* this form and a value like that specified in IDMA_RELEASE_REGION_VAL.
*/
__extension__
typedef union
{
struct
{
#ifndef __BIG_ENDIAN__
/* Reserved. */
uint_reg_t __reserved_0 : 3;
/* NotifRing to be released */
uint_reg_t ring : 8;
/* Bucket to be released */
uint_reg_t bucket : 13;
/* Enable NotifRing release */
uint_reg_t ring_enable : 1;
/* Enable Bucket release */
uint_reg_t bucket_enable : 1;
/*
* This field of the address selects the region (address space) to be
* accessed. For the iDMA release region, this field must be 4.
*/
uint_reg_t region : 3;
/* Reserved. */
uint_reg_t __reserved_1 : 6;
/* This field of the address indexes the 32 entry service domain table. */
uint_reg_t svc_dom : 5;
/* Reserved. */
uint_reg_t __reserved_2 : 24;
#else /* __BIG_ENDIAN__ */
uint_reg_t __reserved_2 : 24;
uint_reg_t svc_dom : 5;
uint_reg_t __reserved_1 : 6;
uint_reg_t region : 3;
uint_reg_t bucket_enable : 1;
uint_reg_t ring_enable : 1;
uint_reg_t bucket : 13;
uint_reg_t ring : 8;
uint_reg_t __reserved_0 : 3;
#endif
};
uint_reg_t word;
} MPIPE_IDMA_RELEASE_REGION_ADDR_t;
/*
* MMIO Ingress DMA Release Region Value - Release NotifRing and/or Bucket.
* Provides release of the associated NotifRing. The address of the MMIO
* operation is described in IDMA_RELEASE_REGION_ADDR.
*/
__extension__
typedef union
{
struct
{
#ifndef __BIG_ENDIAN__
/*
* Number of packets being released. The load balancer's count of
* inflight packets will be decremented by this amount for the associated
* Bucket and/or NotifRing
*/
uint_reg_t count : 16;
/* Reserved. */
uint_reg_t __reserved : 48;
#else /* __BIG_ENDIAN__ */
uint_reg_t __reserved : 48;
uint_reg_t count : 16;
#endif
};
uint_reg_t word;
} MPIPE_IDMA_RELEASE_REGION_VAL_t;
/*
* MMIO Buffer Stack Manager Region Address.
* This MMIO region is used for posting or fetching buffers to/from the
* buffer stack manager. On an MMIO load, this pops a buffer descriptor from
* the top of stack if one is available. On an MMIO store, this pushes a
* buffer to the stack. The value read or written is described in
* BSM_REGION_VAL.
*/
__extension__
typedef union
{
struct
{
#ifndef __BIG_ENDIAN__
/* Reserved. */
uint_reg_t __reserved_0 : 3;
/* BufferStack being accessed. */
uint_reg_t stack : 5;
/* Reserved. */
uint_reg_t __reserved_1 : 18;
/*
* This field of the address selects the region (address space) to be
* accessed. For the buffer stack manager region, this field must be 6.
*/
uint_reg_t region : 3;
/* Reserved. */
uint_reg_t __reserved_2 : 6;
/* This field of the address indexes the 32 entry service domain table. */
uint_reg_t svc_dom : 5;
/* Reserved. */
uint_reg_t __reserved_3 : 24;
#else /* __BIG_ENDIAN__ */
uint_reg_t __reserved_3 : 24;
uint_reg_t svc_dom : 5;
uint_reg_t __reserved_2 : 6;
uint_reg_t region : 3;
uint_reg_t __reserved_1 : 18;
uint_reg_t stack : 5;
uint_reg_t __reserved_0 : 3;
#endif
};
uint_reg_t word;
} MPIPE_BSM_REGION_ADDR_t;
/*
* MMIO Buffer Stack Manager Region Value.
* This MMIO region is used for posting or fetching buffers to/from the
* buffer stack manager. On an MMIO load, this pops a buffer descriptor from
* the top of stack if one is available. On an MMIO store, this pushes a
* buffer to the stack. The address of the MMIO operation is described in
* BSM_REGION_ADDR.
*/
__extension__
typedef union
{
struct
{
#ifndef __BIG_ENDIAN__
/* Reserved. */
uint_reg_t __reserved_0 : 7;
/*
* Base virtual address of the buffer. Must be sign extended by consumer.
*/
int_reg_t va : 35;
/* Reserved. */
uint_reg_t __reserved_1 : 6;
/*
* Index of the buffer stack to which this buffer belongs. Ignored on
* writes since the offset bits specify the stack being accessed.
*/
uint_reg_t stack_idx : 5;
/* Reserved. */
uint_reg_t __reserved_2 : 5;
/*
* Reads as one to indicate that this is a hardware managed buffer.
* Ignored on writes since all buffers on a given stack are the same size.
*/
uint_reg_t hwb : 1;
/*
* Encoded size of buffer (ignored on writes):
* 0 = 128 bytes
* 1 = 256 bytes
* 2 = 512 bytes
* 3 = 1024 bytes
* 4 = 1664 bytes
* 5 = 4096 bytes
* 6 = 10368 bytes
* 7 = 16384 bytes
*/
uint_reg_t size : 3;
/*
* Valid indication for the buffer. Ignored on writes.
* 0 : Valid buffer descriptor popped from stack.
* 3 : Could not pop a buffer from the stack. Either the stack is empty,
* or the hardware's prefetch buffer is empty for this stack.
*/
uint_reg_t c : 2;
#else /* __BIG_ENDIAN__ */
uint_reg_t c : 2;
uint_reg_t size : 3;
uint_reg_t hwb : 1;
uint_reg_t __reserved_2 : 5;
uint_reg_t stack_idx : 5;
uint_reg_t __reserved_1 : 6;
int_reg_t va : 35;
uint_reg_t __reserved_0 : 7;
#endif
};
uint_reg_t word;
} MPIPE_BSM_REGION_VAL_t;
/*
* MMIO Egress DMA Post Region Address.
* Used to post descriptor locations to the eDMA descriptor engine. The
* value to be written is described in EDMA_POST_REGION_VAL
*/
__extension__
typedef union
{
struct
{
#ifndef __BIG_ENDIAN__
/* Reserved. */
uint_reg_t __reserved_0 : 3;
/* eDMA ring being accessed */
uint_reg_t ring : 5;
/* Reserved. */
uint_reg_t __reserved_1 : 18;
/*
* This field of the address selects the region (address space) to be
* accessed. For the egress DMA post region, this field must be 5.
*/
uint_reg_t region : 3;
/* Reserved. */
uint_reg_t __reserved_2 : 6;
/* This field of the address indexes the 32 entry service domain table. */
uint_reg_t svc_dom : 5;
/* Reserved. */
uint_reg_t __reserved_3 : 24;
#else /* __BIG_ENDIAN__ */
uint_reg_t __reserved_3 : 24;
uint_reg_t svc_dom : 5;
uint_reg_t __reserved_2 : 6;
uint_reg_t region : 3;
uint_reg_t __reserved_1 : 18;
uint_reg_t ring : 5;
uint_reg_t __reserved_0 : 3;
#endif
};
uint_reg_t word;
} MPIPE_EDMA_POST_REGION_ADDR_t;
/*
* MMIO Egress DMA Post Region Value.
* Used to post descriptor locations to the eDMA descriptor engine. The
* address is described in EDMA_POST_REGION_ADDR.
*/
__extension__
typedef union
{
struct
{
#ifndef __BIG_ENDIAN__
/*
* For writes, this specifies the current ring tail pointer prior to any
* post. For example, to post 1 or more descriptors starting at location
* 23, this would contain 23 (not 24). On writes, this index must be
* masked based on the ring size. The new tail pointer after this post
* is COUNT+RING_IDX (masked by the ring size).
*
* For reads, this provides the hardware descriptor fetcher's head
* pointer. The descriptors prior to the head pointer, however, may not
* yet have been processed so this indicator is only used to determine
* how full the ring is and if software may post more descriptors.
*/
uint_reg_t ring_idx : 16;
/*
* For writes, this specifies number of contiguous descriptors that are
* being posted. Software may post up to RingSize descriptors with a
* single MMIO store. A zero in this field on a write will "wake up" an
* eDMA ring and cause it fetch descriptors regardless of the hardware's
* current view of the state of the tail pointer.
*
* For reads, this field provides a rolling count of the number of
* descriptors that have been completely processed. This may be used by
* software to determine when buffers associated with a descriptor may be
* returned or reused. When the ring's flush bit is cleared by software
* (after having been set by HW or SW), the COUNT will be cleared.
*/
uint_reg_t count : 16;
/*
* For writes, this specifies the generation number of the tail being
* posted. Note that if tail+cnt wraps to the beginning of the ring, the
* eDMA hardware assumes that the descriptors posted at the beginning of
* the ring are also valid so it is okay to post around the wrap point.
*
* For reads, this is the current generation number. Valid descriptors
* will have the inverse of this generation number.
*/
uint_reg_t gen : 1;
/* Reserved. */
uint_reg_t __reserved : 31;
#else /* __BIG_ENDIAN__ */
uint_reg_t __reserved : 31;
uint_reg_t gen : 1;
uint_reg_t count : 16;
uint_reg_t ring_idx : 16;
#endif
};
uint_reg_t word;
} MPIPE_EDMA_POST_REGION_VAL_t;
/*
* Load Balancer Bucket Status Data.
* Read/Write data for load balancer Bucket-Status Table. 4160 entries
* indexed by LBL_INIT_CTL.IDX when LBL_INIT_CTL.STRUCT_SEL is BSTS_TBL
*/
__extension__
typedef union
{
struct
{
#ifndef __BIG_ENDIAN__
/* NotifRing currently assigned to this bucket. */
uint_reg_t notifring : 8;
/* Current reference count. */
uint_reg_t count : 16;
/* Group associated with this bucket. */
uint_reg_t group : 5;
/* Mode select for this bucket. */
uint_reg_t mode : 3;
/* Reserved. */
uint_reg_t __reserved : 32;
#else /* __BIG_ENDIAN__ */
uint_reg_t __reserved : 32;
uint_reg_t mode : 3;
uint_reg_t group : 5;
uint_reg_t count : 16;
uint_reg_t notifring : 8;
#endif
};
uint_reg_t word;
} MPIPE_LBL_INIT_DAT_BSTS_TBL_t;
#endif /* !defined(__ASSEMBLER__) */
#endif /* !defined(__ARCH_MPIPE_H__) */
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
#ifndef __ARCH_MPIPE_CONSTANTS_H__
#define __ARCH_MPIPE_CONSTANTS_H__
#define MPIPE_NUM_CLASSIFIERS 10
#define MPIPE_CLS_MHZ 1200
#define MPIPE_NUM_EDMA_RINGS 32
#define MPIPE_NUM_SGMII_MACS 16
#define MPIPE_NUM_XAUI_MACS 4
#define MPIPE_NUM_LOOPBACK_CHANNELS 4
#define MPIPE_NUM_NON_LB_CHANNELS 28
#define MPIPE_NUM_IPKT_BLOCKS 1536
#define MPIPE_NUM_BUCKETS 4160
#define MPIPE_NUM_NOTIF_RINGS 256
#define MPIPE_NUM_NOTIF_GROUPS 32
#define MPIPE_NUM_TLBS_PER_ASID 16
#define MPIPE_TLB_IDX_WIDTH 4
#define MPIPE_MMIO_NUM_SVC_DOM 32
#endif /* __ARCH_MPIPE_CONSTANTS_H__ */
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_MPIPE_DEF_H__
#define __ARCH_MPIPE_DEF_H__
#define MPIPE_MMIO_ADDR__REGION_SHIFT 26
#define MPIPE_MMIO_ADDR__REGION_VAL_CFG 0x0
#define MPIPE_MMIO_ADDR__REGION_VAL_IDMA 0x4
#define MPIPE_MMIO_ADDR__REGION_VAL_EDMA 0x5
#define MPIPE_MMIO_ADDR__REGION_VAL_BSM 0x6
#define MPIPE_BSM_REGION_VAL__VA_SHIFT 7
#define MPIPE_BSM_INIT_DAT_1__SIZE_VAL_BSZ_128 0x0
#define MPIPE_BSM_INIT_DAT_1__SIZE_VAL_BSZ_256 0x1
#define MPIPE_BSM_INIT_DAT_1__SIZE_VAL_BSZ_512 0x2
#define MPIPE_BSM_INIT_DAT_1__SIZE_VAL_BSZ_1024 0x3
#define MPIPE_BSM_INIT_DAT_1__SIZE_VAL_BSZ_1664 0x4
#define MPIPE_BSM_INIT_DAT_1__SIZE_VAL_BSZ_4096 0x5
#define MPIPE_BSM_INIT_DAT_1__SIZE_VAL_BSZ_10368 0x6
#define MPIPE_BSM_INIT_DAT_1__SIZE_VAL_BSZ_16384 0x7
#define MPIPE_LBL_INIT_DAT_BSTS_TBL__MODE_VAL_DFA 0x0
#define MPIPE_LBL_INIT_DAT_BSTS_TBL__MODE_VAL_FIXED 0x1
#define MPIPE_LBL_INIT_DAT_BSTS_TBL__MODE_VAL_ALWAYS_PICK 0x2
#define MPIPE_LBL_INIT_DAT_BSTS_TBL__MODE_VAL_STICKY 0x3
#define MPIPE_LBL_INIT_DAT_BSTS_TBL__MODE_VAL_STICKY_RAND 0x7
#define MPIPE_LBL_NR_STATE__FIRST_WORD 0x2138
#endif /* !defined(__ARCH_MPIPE_DEF_H__) */
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_MPIPE_SHM_H__
#define __ARCH_MPIPE_SHM_H__
#include <arch/abi.h>
#include <arch/mpipe_shm_def.h>
#ifndef __ASSEMBLER__
/**
* MPIPE eDMA Descriptor.
* The eDMA descriptor is written by software and consumed by hardware. It
* is used to specify the location of egress packet data to be sent out of
* the chip via one of the packet interfaces.
*/
__extension__
typedef union
{
struct
{
/* Word 0 */
#ifndef __BIG_ENDIAN__
/**
* Generation number. Used to indicate a valid descriptor in ring. When
* a new descriptor is written into the ring, software must toggle this
* bit. The net effect is that the GEN bit being written into new
* descriptors toggles each time the ring tail pointer wraps.
*/
uint_reg_t gen : 1;
/** Reserved. Must be zero. */
uint_reg_t r0 : 7;
/** Checksum generation enabled for this transfer. */
uint_reg_t csum : 1;
/**
* Nothing to be sent. Used, for example, when software has dropped a
* packet but still wishes to return all of the associated buffers.
*/
uint_reg_t ns : 1;
/**
* Notification interrupt will be delivered when packet has been egressed.
*/
uint_reg_t notif : 1;
/**
* Boundary indicator. When 1, this transfer includes the EOP for this
* command. Must be clear on all but the last descriptor for an egress
* packet.
*/
uint_reg_t bound : 1;
/** Reserved. Must be zero. */
uint_reg_t r1 : 4;
/**
* Number of bytes to be sent for this descriptor. When zero, no data
* will be moved and the buffer descriptor will be ignored. If the
* buffer descriptor indicates that it is chained, the low 7 bits of the
* VA indicate the offset within the first buffer (e.g. 127 bytes is the
* maximum offset into the first buffer). If the size exceeds a single
* buffer, subsequent buffer descriptors will be fetched prior to
* processing the next eDMA descriptor in the ring.
*/
uint_reg_t xfer_size : 14;
/** Reserved. Must be zero. */
uint_reg_t r2 : 2;
/**
* Destination of checksum relative to CSUM_START relative to the first
* byte moved by this descriptor. Must be zero if CSUM=0 in this
* descriptor. Must be less than XFER_SIZE (e.g. the first byte of the
* CSUM_DEST must be within the span of this descriptor).
*/
uint_reg_t csum_dest : 8;
/**
* Start byte of checksum relative to the first byte moved by this
* descriptor. If this is not the first descriptor for the egress
* packet, CSUM_START is still relative to the first byte in this
* descriptor. Must be zero if CSUM=0 in this descriptor.
*/
uint_reg_t csum_start : 8;
/**
* Initial value for 16-bit 1's compliment checksum if enabled via CSUM.
* Specified in network order. That is, bits[7:0] will be added to the
* byte pointed to by CSUM_START and bits[15:8] will be added to the byte
* pointed to by CSUM_START+1 (with appropriate 1's compliment carries).
* Must be zero if CSUM=0 in this descriptor.
*/
uint_reg_t csum_seed : 16;
#else /* __BIG_ENDIAN__ */
uint_reg_t csum_seed : 16;
uint_reg_t csum_start : 8;
uint_reg_t csum_dest : 8;
uint_reg_t r2 : 2;
uint_reg_t xfer_size : 14;
uint_reg_t r1 : 4;
uint_reg_t bound : 1;
uint_reg_t notif : 1;
uint_reg_t ns : 1;
uint_reg_t csum : 1;
uint_reg_t r0 : 7;
uint_reg_t gen : 1;
#endif
/* Word 1 */
#ifndef __BIG_ENDIAN__
/** Virtual address. Must be sign extended by consumer. */
int_reg_t va : 42;
/** Reserved. */
uint_reg_t __reserved_0 : 6;
/** Index of the buffer stack to which this buffer belongs. */
uint_reg_t stack_idx : 5;
/** Reserved. */
uint_reg_t __reserved_1 : 3;
/**
* Instance ID. For devices that support more than one mPIPE instance,
* this field indicates the buffer owner. If the INST field does not
* match the mPIPE's instance number when a packet is egressed, buffers
* with HWB set will be returned to the other mPIPE instance.
*/
uint_reg_t inst : 1;
/** Reserved. */
uint_reg_t __reserved_2 : 1;
/**
* Always set to one by hardware in iDMA packet descriptors. For eDMA,
* indicates whether the buffer will be released to the buffer stack
* manager. When 0, software is responsible for releasing the buffer.
*/
uint_reg_t hwb : 1;
/**
* Encoded size of buffer. Set by the ingress hardware for iDMA packet
* descriptors. For eDMA descriptors, indicates the buffer size if .c
* indicates a chained packet. If an eDMA descriptor is not chained and
* the .hwb bit is not set, this field is ignored and the size is
* specified by the .xfer_size field.
* 0 = 128 bytes
* 1 = 256 bytes
* 2 = 512 bytes
* 3 = 1024 bytes
* 4 = 1664 bytes
* 5 = 4096 bytes
* 6 = 10368 bytes
* 7 = 16384 bytes
*/
uint_reg_t size : 3;
/**
* Chaining configuration for the buffer. Indicates that an ingress
* packet or egress command is chained across multiple buffers, with each
* buffer's size indicated by the .size field.
*/
uint_reg_t c : 2;
#else /* __BIG_ENDIAN__ */
uint_reg_t c : 2;
uint_reg_t size : 3;
uint_reg_t hwb : 1;
uint_reg_t __reserved_2 : 1;
uint_reg_t inst : 1;
uint_reg_t __reserved_1 : 3;
uint_reg_t stack_idx : 5;
uint_reg_t __reserved_0 : 6;
int_reg_t va : 42;
#endif
};
/** Word access */
uint_reg_t words[2];
} MPIPE_EDMA_DESC_t;
/**
* MPIPE Packet Descriptor.
* The packet descriptor is filled by the mPIPE's classification,
* load-balancing, and buffer management services. Some fields are consumed
* by mPIPE hardware, and others are consumed by Tile software.
*/
__extension__
typedef union
{
struct
{
/* Word 0 */
#ifndef __BIG_ENDIAN__
/**
* Notification ring into which this packet descriptor is written.
* Typically written by load balancer, but can be overridden by
* classification program if NR is asserted.
*/
uint_reg_t notif_ring : 8;
/** Source channel for this packet. Written by mPIPE DMA hardware. */
uint_reg_t channel : 5;
/** Reserved. */
uint_reg_t __reserved_0 : 1;
/**
* MAC Error.
* Generated by the MAC interface. Asserted if there was an overrun of
* the MAC's receive FIFO. This condition generally only occurs if the
* mPIPE clock is running too slowly.
*/
uint_reg_t me : 1;
/**
* Truncation Error.
* Written by the iDMA hardware. Asserted if packet was truncated due to
* insufficient space in iPkt buffer
*/
uint_reg_t tr : 1;
/**
* Written by the iDMA hardware. Indicates the number of bytes written
* to Tile memory. In general, this is the actual size of the packet as
* received from the MAC. But if the packet is truncated due to running
* out of buffers or due to the iPkt buffer filling up, then the L2_SIZE
* will be reduced to reflect the actual number of valid bytes written to
* Tile memory.
*/
uint_reg_t l2_size : 14;
/**
* CRC Error.
* Generated by the MAC. Asserted if MAC indicated an L2 CRC error or
* other L2 error (bad length etc.) on the packet.
*/
uint_reg_t ce : 1;
/**
* Cut Through.
* Written by the iDMA hardware. Asserted if packet was not completely
* received before being sent to classifier. L2_Size will indicate
* number of bytes received so far.
*/
uint_reg_t ct : 1;
/**
* Written by the classification program. Used by the load balancer to
* select the ring into which this packet descriptor is written.
*/
uint_reg_t bucket_id : 13;
/** Reserved. */
uint_reg_t __reserved_1 : 3;
/**
* Checksum.
* Written by classification program. When 1, the checksum engine will
* perform checksum based on the CSUM_SEED, CSUM_START, and CSUM_BYTES
* fields. The result will be placed in CSUM_VAL.
*/
uint_reg_t cs : 1;
/**
* Notification Ring Select.
* Written by the classification program. When 1, the NotifRingIDX is
* set by classification program rather than being set by load balancer.
*/
uint_reg_t nr : 1;
/**
* Written by classification program. Indicates whether packet and
* descriptor should both be dropped, both be delivered, or only the
* descriptor should be delivered.
*/
uint_reg_t dest : 2;
/**
* General Purpose Sequence Number Enable.
* Written by the classification program. When 1, the GP_SQN_SEL field
* contains the sequence number selector and the GP_SQN field will be
* replaced with the associated sequence number. When clear, the GP_SQN
* field is left intact and be used as "Custom" bytes.
*/
uint_reg_t sq : 1;
/**
* TimeStamp Enable.
* Enable TimeStamp insertion. When clear, timestamp field may be filled
* with custom data by classifier. When set, hardware inserts the
* timestamp when the start of packet is received from the MAC.
*/
uint_reg_t ts : 1;
/**
* Packet Sequence Number Enable.
* Enable PacketSQN insertion. When clear, PacketSQN field may be filled
* with custom data by classifier. When set, hardware inserts the packet
* sequence number when the packet descriptor is written to a
* notification ring.
*/
uint_reg_t ps : 1;
/**
* Buffer Error.
* Written by the iDMA hardware. Asserted if iDMA ran out of buffers
* while writing the packet. Software must still return any buffer
* descriptors whose C field indicates a valid descriptor was consumed.
*/
uint_reg_t be : 1;
/**
* Written by the classification program. The associated counter is
* incremented when the packet is sent.
*/
uint_reg_t ctr0 : 5;
/** Reserved. */
uint_reg_t __reserved_2 : 3;
#else /* __BIG_ENDIAN__ */
uint_reg_t __reserved_2 : 3;
uint_reg_t ctr0 : 5;
uint_reg_t be : 1;
uint_reg_t ps : 1;
uint_reg_t ts : 1;
uint_reg_t sq : 1;
uint_reg_t dest : 2;
uint_reg_t nr : 1;
uint_reg_t cs : 1;
uint_reg_t __reserved_1 : 3;
uint_reg_t bucket_id : 13;
uint_reg_t ct : 1;
uint_reg_t ce : 1;
uint_reg_t l2_size : 14;
uint_reg_t tr : 1;
uint_reg_t me : 1;
uint_reg_t __reserved_0 : 1;
uint_reg_t channel : 5;
uint_reg_t notif_ring : 8;
#endif
/* Word 1 */
#ifndef __BIG_ENDIAN__
/**
* Written by the classification program. The associated counter is
* incremented when the packet is sent.
*/
uint_reg_t ctr1 : 5;
/** Reserved. */
uint_reg_t __reserved_3 : 3;
/**
* Written by classification program. Indicates the start byte for
* checksum. Relative to 1st byte received from MAC.
*/
uint_reg_t csum_start : 8;
/**
* Checksum seed written by classification program. Overwritten with
* resultant checksum if CS bit is asserted. The endianness of the CSUM
* value bits when viewed by Tile software match the packet byte order.
* That is, bits[7:0] of the resulting checksum value correspond to
* earlier (more significant) bytes in the packet. To avoid classifier
* software from having to byte swap the CSUM_SEED, the iDMA checksum
* engine byte swaps the classifier's result before seeding the checksum
* calculation. Thus, the CSUM_START byte of packet data is added to
* bits[15:8] of the CSUM_SEED field generated by the classifier. This
* byte swap will be visible to Tile software if the CS bit is clear.
*/
uint_reg_t csum_seed_val : 16;
/**
* Written by the classification program. Not interpreted by mPIPE
* hardware.
*/
uint_reg_t custom0 : 32;
#else /* __BIG_ENDIAN__ */
uint_reg_t custom0 : 32;
uint_reg_t csum_seed_val : 16;
uint_reg_t csum_start : 8;
uint_reg_t __reserved_3 : 3;
uint_reg_t ctr1 : 5;
#endif
/* Word 2 */
#ifndef __BIG_ENDIAN__
/**
* Written by the classification program. Not interpreted by mPIPE
* hardware.
*/
uint_reg_t custom1 : 64;
#else /* __BIG_ENDIAN__ */
uint_reg_t custom1 : 64;
#endif
/* Word 3 */
#ifndef __BIG_ENDIAN__
/**
* Written by the classification program. Not interpreted by mPIPE
* hardware.
*/
uint_reg_t custom2 : 64;
#else /* __BIG_ENDIAN__ */
uint_reg_t custom2 : 64;
#endif
/* Word 4 */
#ifndef __BIG_ENDIAN__
/**
* Written by the classification program. Not interpreted by mPIPE
* hardware.
*/
uint_reg_t custom3 : 64;
#else /* __BIG_ENDIAN__ */
uint_reg_t custom3 : 64;
#endif
/* Word 5 */
#ifndef __BIG_ENDIAN__
/**
* Sequence number applied when packet is distributed. Classifier
* selects which sequence number is to be applied by writing the 13-bit
* SQN-selector into this field.
*/
uint_reg_t gp_sqn : 16;
/**
* Written by notification hardware. The packet sequence number is
* incremented for each packet that wasn't dropped.
*/
uint_reg_t packet_sqn : 48;
#else /* __BIG_ENDIAN__ */
uint_reg_t packet_sqn : 48;
uint_reg_t gp_sqn : 16;
#endif
/* Word 6 */
#ifndef __BIG_ENDIAN__
/**
* Written by hardware when the start-of-packet is received by the mPIPE
* from the MAC. This is the nanoseconds part of the packet timestamp.
*/
uint_reg_t time_stamp_ns : 32;
/**
* Written by hardware when the start-of-packet is received by the mPIPE
* from the MAC. This is the seconds part of the packet timestamp.
*/
uint_reg_t time_stamp_sec : 32;
#else /* __BIG_ENDIAN__ */
uint_reg_t time_stamp_sec : 32;
uint_reg_t time_stamp_ns : 32;
#endif
/* Word 7 */
#ifndef __BIG_ENDIAN__
/** Virtual address. Must be sign extended by consumer. */
int_reg_t va : 42;
/** Reserved. */
uint_reg_t __reserved_4 : 6;
/** Index of the buffer stack to which this buffer belongs. */
uint_reg_t stack_idx : 5;
/** Reserved. */
uint_reg_t __reserved_5 : 3;
/**
* Instance ID. For devices that support more than one mPIPE instance,
* this field indicates the buffer owner. If the INST field does not
* match the mPIPE's instance number when a packet is egressed, buffers
* with HWB set will be returned to the other mPIPE instance.
*/
uint_reg_t inst : 1;
/** Reserved. */
uint_reg_t __reserved_6 : 1;
/**
* Always set to one by hardware in iDMA packet descriptors. For eDMA,
* indicates whether the buffer will be released to the buffer stack
* manager. When 0, software is responsible for releasing the buffer.
*/
uint_reg_t hwb : 1;
/**
* Encoded size of buffer. Set by the ingress hardware for iDMA packet
* descriptors. For eDMA descriptors, indicates the buffer size if .c
* indicates a chained packet. If an eDMA descriptor is not chained and
* the .hwb bit is not set, this field is ignored and the size is
* specified by the .xfer_size field.
* 0 = 128 bytes
* 1 = 256 bytes
* 2 = 512 bytes
* 3 = 1024 bytes
* 4 = 1664 bytes
* 5 = 4096 bytes
* 6 = 10368 bytes
* 7 = 16384 bytes
*/
uint_reg_t size : 3;
/**
* Chaining configuration for the buffer. Indicates that an ingress
* packet or egress command is chained across multiple buffers, with each
* buffer's size indicated by the .size field.
*/
uint_reg_t c : 2;
#else /* __BIG_ENDIAN__ */
uint_reg_t c : 2;
uint_reg_t size : 3;
uint_reg_t hwb : 1;
uint_reg_t __reserved_6 : 1;
uint_reg_t inst : 1;
uint_reg_t __reserved_5 : 3;
uint_reg_t stack_idx : 5;
uint_reg_t __reserved_4 : 6;
int_reg_t va : 42;
#endif
};
/** Word access */
uint_reg_t words[8];
} MPIPE_PDESC_t;
#endif /* !defined(__ASSEMBLER__) */
#endif /* !defined(__ARCH_MPIPE_SHM_H__) */
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_MPIPE_SHM_DEF_H__
#define __ARCH_MPIPE_SHM_DEF_H__
#define MPIPE_EDMA_DESC_WORD1__C_VAL_UNCHAINED 0x0
#define MPIPE_EDMA_DESC_WORD1__C_VAL_CHAINED 0x1
#define MPIPE_EDMA_DESC_WORD1__C_VAL_NOT_RDY 0x2
#define MPIPE_EDMA_DESC_WORD1__C_VAL_INVALID 0x3
#endif /* !defined(__ARCH_MPIPE_SHM_DEF_H__) */
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_TRIO_H__
#define __ARCH_TRIO_H__
#include <arch/abi.h>
#include <arch/trio_def.h>
#ifndef __ASSEMBLER__
/*
* Tile PIO Region Configuration - CFG Address Format.
* This register describes the address format for PIO accesses when the
* associated region is setup with TYPE=CFG.
*/
__extension__
typedef union
{
struct
{
#ifndef __BIG_ENDIAN__
/* Register Address (full byte address). */
uint_reg_t reg_addr : 12;
/* Function Number */
uint_reg_t fn : 3;
/* Device Number */
uint_reg_t dev : 5;
/* BUS Number */
uint_reg_t bus : 8;
/* Config Type: 0 for access to directly-attached device. 1 otherwise. */
uint_reg_t type : 1;
/* Reserved. */
uint_reg_t __reserved_0 : 1;
/*
* MAC select. This must match the configuration in
* TILE_PIO_REGION_SETUP.MAC.
*/
uint_reg_t mac : 2;
/* Reserved. */
uint_reg_t __reserved_1 : 32;
#else /* __BIG_ENDIAN__ */
uint_reg_t __reserved_1 : 32;
uint_reg_t mac : 2;
uint_reg_t __reserved_0 : 1;
uint_reg_t type : 1;
uint_reg_t bus : 8;
uint_reg_t dev : 5;
uint_reg_t fn : 3;
uint_reg_t reg_addr : 12;
#endif
};
uint_reg_t word;
} TRIO_TILE_PIO_REGION_SETUP_CFG_ADDR_t;
#endif /* !defined(__ASSEMBLER__) */
#endif /* !defined(__ARCH_TRIO_H__) */
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
#ifndef __ARCH_TRIO_CONSTANTS_H__
#define __ARCH_TRIO_CONSTANTS_H__
#define TRIO_NUM_ASIDS 16
#define TRIO_NUM_TLBS_PER_ASID 16
#define TRIO_NUM_TPIO_REGIONS 8
#define TRIO_LOG2_NUM_TPIO_REGIONS 3
#define TRIO_NUM_MAP_MEM_REGIONS 16
#define TRIO_LOG2_NUM_MAP_MEM_REGIONS 4
#define TRIO_NUM_MAP_SQ_REGIONS 8
#define TRIO_LOG2_NUM_MAP_SQ_REGIONS 3
#define TRIO_LOG2_NUM_SQ_FIFO_ENTRIES 6
#define TRIO_NUM_PUSH_DMA_RINGS 32
#define TRIO_NUM_PULL_DMA_RINGS 32
#endif /* __ARCH_TRIO_CONSTANTS_H__ */
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_TRIO_DEF_H__
#define __ARCH_TRIO_DEF_H__
#define TRIO_CFG_REGION_ADDR__REG_SHIFT 0
#define TRIO_CFG_REGION_ADDR__INTFC_SHIFT 16
#define TRIO_CFG_REGION_ADDR__INTFC_VAL_TRIO 0x0
#define TRIO_CFG_REGION_ADDR__INTFC_VAL_MAC_INTERFACE 0x1
#define TRIO_CFG_REGION_ADDR__INTFC_VAL_MAC_STANDARD 0x2
#define TRIO_CFG_REGION_ADDR__INTFC_VAL_MAC_PROTECTED 0x3
#define TRIO_CFG_REGION_ADDR__MAC_SEL_SHIFT 18
#define TRIO_CFG_REGION_ADDR__PROT_SHIFT 20
#define TRIO_PIO_REGIONS_ADDR__REGION_SHIFT 32
#define TRIO_MAP_MEM_REG_INT0 0x1000000000
#define TRIO_MAP_MEM_REG_INT1 0x1000000008
#define TRIO_MAP_MEM_REG_INT2 0x1000000010
#define TRIO_MAP_MEM_REG_INT3 0x1000000018
#define TRIO_MAP_MEM_REG_INT4 0x1000000020
#define TRIO_MAP_MEM_REG_INT5 0x1000000028
#define TRIO_MAP_MEM_REG_INT6 0x1000000030
#define TRIO_MAP_MEM_REG_INT7 0x1000000038
#define TRIO_MAP_MEM_LIM__ADDR_SHIFT 12
#define TRIO_MAP_MEM_SETUP__ORDER_MODE_VAL_UNORDERED 0x0
#define TRIO_MAP_MEM_SETUP__ORDER_MODE_VAL_STRICT 0x1
#define TRIO_MAP_MEM_SETUP__ORDER_MODE_VAL_REL_ORD 0x2
#define TRIO_TILE_PIO_REGION_SETUP_CFG_ADDR__MAC_SHIFT 30
#endif /* !defined(__ARCH_TRIO_DEF_H__) */
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_TRIO_PCIE_INTFC_H__
#define __ARCH_TRIO_PCIE_INTFC_H__
#include <arch/abi.h>
#include <arch/trio_pcie_intfc_def.h>
#ifndef __ASSEMBLER__
/*
* Port Configuration.
* Configuration of the PCIe Port
*/
__extension__
typedef union
{
struct
{
#ifndef __BIG_ENDIAN__
/* Provides the state of the strapping pins for this port. */
uint_reg_t strap_state : 3;
/* Reserved. */
uint_reg_t __reserved_0 : 1;
/*
* When 1, the device type will be overridden using OVD_DEV_TYPE_VAL.
* When 0, the device type is determined based on the STRAP_STATE.
*/
uint_reg_t ovd_dev_type : 1;
/* Provides the device type when OVD_DEV_TYPE is 1. */
uint_reg_t ovd_dev_type_val : 4;
/* Determines how link is trained. */
uint_reg_t train_mode : 2;
/* Reserved. */
uint_reg_t __reserved_1 : 1;
/*
* For PCIe, used to flip physical RX lanes that were not properly wired.
* This is not the same as lane reversal which is handled automatically
* during link training. When 0, RX Lane0 must be wired to the link
* partner (either to its Lane0 or it's LaneN). When RX_LANE_FLIP is 1,
* the highest numbered lane for this port becomes Lane0 and Lane0 does
* NOT have to be wired to the link partner.
*/
uint_reg_t rx_lane_flip : 1;
/*
* For PCIe, used to flip physical TX lanes that were not properly wired.
* This is not the same as lane reversal which is handled automatically
* during link training. When 0, TX Lane0 must be wired to the link
* partner (either to its Lane0 or it's LaneN). When TX_LANE_FLIP is 1,
* the highest numbered lane for this port becomes Lane0 and Lane0 does
* NOT have to be wired to the link partner.
*/
uint_reg_t tx_lane_flip : 1;
/*
* For StreamIO port, configures the width of the port when TRAIN_MODE is
* not STRAP.
*/
uint_reg_t stream_width : 2;
/*
* For StreamIO port, configures the rate of the port when TRAIN_MODE is
* not STRAP.
*/
uint_reg_t stream_rate : 2;
/* Reserved. */
uint_reg_t __reserved_2 : 46;
#else /* __BIG_ENDIAN__ */
uint_reg_t __reserved_2 : 46;
uint_reg_t stream_rate : 2;
uint_reg_t stream_width : 2;
uint_reg_t tx_lane_flip : 1;
uint_reg_t rx_lane_flip : 1;
uint_reg_t __reserved_1 : 1;
uint_reg_t train_mode : 2;
uint_reg_t ovd_dev_type_val : 4;
uint_reg_t ovd_dev_type : 1;
uint_reg_t __reserved_0 : 1;
uint_reg_t strap_state : 3;
#endif
};
uint_reg_t word;
} TRIO_PCIE_INTFC_PORT_CONFIG_t;
/*
* Port Status.
* Status of the PCIe Port. This register applies to the StreamIO port when
* StreamIO is enabled.
*/
__extension__
typedef union
{
struct
{
#ifndef __BIG_ENDIAN__
/*
* Indicates the DL state of the port. When 1, the port is up and ready
* to receive traffic.
*/
uint_reg_t dl_up : 1;
/*
* Indicates the number of times the link has gone down. Clears on read.
*/
uint_reg_t dl_down_cnt : 7;
/* Indicates the SERDES PLL has spun up and is providing a valid clock. */
uint_reg_t clock_ready : 1;
/* Reserved. */
uint_reg_t __reserved_0 : 7;
/* Device revision ID. */
uint_reg_t device_rev : 8;
/* Link state (PCIe). */
uint_reg_t ltssm_state : 6;
/* Link power management state (PCIe). */
uint_reg_t pm_state : 3;
/* Reserved. */
uint_reg_t __reserved_1 : 31;
#else /* __BIG_ENDIAN__ */
uint_reg_t __reserved_1 : 31;
uint_reg_t pm_state : 3;
uint_reg_t ltssm_state : 6;
uint_reg_t device_rev : 8;
uint_reg_t __reserved_0 : 7;
uint_reg_t clock_ready : 1;
uint_reg_t dl_down_cnt : 7;
uint_reg_t dl_up : 1;
#endif
};
uint_reg_t word;
} TRIO_PCIE_INTFC_PORT_STATUS_t;
/*
* Transmit FIFO Control.
* Contains TX FIFO thresholds. These registers are for diagnostics purposes
* only. Changing these values causes undefined behavior.
*/
__extension__
typedef union
{
struct
{
#ifndef __BIG_ENDIAN__
/*
* Almost-Empty level for TX0 data. Typically set to at least
* roundup(38.0*M/N) where N=tclk frequency and M=MAC symbol rate in MHz
* for a x4 port (250MHz).
*/
uint_reg_t tx0_data_ae_lvl : 7;
/* Reserved. */
uint_reg_t __reserved_0 : 1;
/* Almost-Empty level for TX1 data. */
uint_reg_t tx1_data_ae_lvl : 7;
/* Reserved. */
uint_reg_t __reserved_1 : 1;
/* Almost-Full level for TX0 data. */
uint_reg_t tx0_data_af_lvl : 7;
/* Reserved. */
uint_reg_t __reserved_2 : 1;
/* Almost-Full level for TX1 data. */
uint_reg_t tx1_data_af_lvl : 7;
/* Reserved. */
uint_reg_t __reserved_3 : 1;
/* Almost-Full level for TX0 info. */
uint_reg_t tx0_info_af_lvl : 5;
/* Reserved. */
uint_reg_t __reserved_4 : 3;
/* Almost-Full level for TX1 info. */
uint_reg_t tx1_info_af_lvl : 5;
/* Reserved. */
uint_reg_t __reserved_5 : 3;
/*
* This register provides performance adjustment for high bandwidth
* flows. The MAC will assert almost-full to TRIO if non-posted credits
* fall below this level. Note that setting this larger than the initial
* PORT_CREDIT.NPH value will cause READS to never be sent. If the
* initial credit value from the link partner is smaller than this value
* when the link comes up, the value will be reset to the initial credit
* value to prevent lockup.
*/
uint_reg_t min_np_credits : 8;
/*
* This register provides performance adjustment for high bandwidth
* flows. The MAC will assert almost-full to TRIO if posted credits fall
* below this level. Note that setting this larger than the initial
* PORT_CREDIT.PH value will cause WRITES to never be sent. If the
* initial credit value from the link partner is smaller than this value
* when the link comes up, the value will be reset to the initial credit
* value to prevent lockup.
*/
uint_reg_t min_p_credits : 8;
#else /* __BIG_ENDIAN__ */
uint_reg_t min_p_credits : 8;
uint_reg_t min_np_credits : 8;
uint_reg_t __reserved_5 : 3;
uint_reg_t tx1_info_af_lvl : 5;
uint_reg_t __reserved_4 : 3;
uint_reg_t tx0_info_af_lvl : 5;
uint_reg_t __reserved_3 : 1;
uint_reg_t tx1_data_af_lvl : 7;
uint_reg_t __reserved_2 : 1;
uint_reg_t tx0_data_af_lvl : 7;
uint_reg_t __reserved_1 : 1;
uint_reg_t tx1_data_ae_lvl : 7;
uint_reg_t __reserved_0 : 1;
uint_reg_t tx0_data_ae_lvl : 7;
#endif
};
uint_reg_t word;
} TRIO_PCIE_INTFC_TX_FIFO_CTL_t;
#endif /* !defined(__ASSEMBLER__) */
#endif /* !defined(__ARCH_TRIO_PCIE_INTFC_H__) */
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_TRIO_PCIE_INTFC_DEF_H__
#define __ARCH_TRIO_PCIE_INTFC_DEF_H__
#define TRIO_PCIE_INTFC_MAC_INT_STS 0x0000
#define TRIO_PCIE_INTFC_MAC_INT_STS__INT_LEVEL_MASK 0xf000
#define TRIO_PCIE_INTFC_PORT_CONFIG 0x0018
#define TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_DISABLED 0x0
#define TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_AUTO_CONFIG_ENDPOINT 0x1
#define TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_AUTO_CONFIG_RC 0x2
#define TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_AUTO_CONFIG_ENDPOINT_G1 0x3
#define TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_AUTO_CONFIG_RC_G1 0x4
#define TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_AUTO_XLINK 0x5
#define TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_STREAM_X1 0x6
#define TRIO_PCIE_INTFC_PORT_CONFIG__STRAP_STATE_VAL_STREAM_X4 0x7
#define TRIO_PCIE_INTFC_PORT_STATUS 0x0020
#define TRIO_PCIE_INTFC_TX_FIFO_CTL 0x0050
#endif /* !defined(__ARCH_TRIO_PCIE_INTFC_DEF_H__) */
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_TRIO_PCIE_RC_H__
#define __ARCH_TRIO_PCIE_RC_H__
#include <arch/abi.h>
#include <arch/trio_pcie_rc_def.h>
#ifndef __ASSEMBLER__
/* Device Capabilities Register. */
__extension__
typedef union
{
struct
{
#ifndef __BIG_ENDIAN__
/*
* Max_Payload_Size Supported, writablethrough the MAC_STANDARD interface
*/
uint_reg_t mps_sup : 3;
/*
* This field is writable through the MAC_STANDARD interface. However,
* Phantom Function is not supported. Therefore, the application must
* not write any value other than 0x0 to this field.
*/
uint_reg_t phantom_function_supported : 2;
/* This bit is writable through the MAC_STANDARD interface. */
uint_reg_t ext_tag_field_supported : 1;
/* Reserved. */
uint_reg_t __reserved_0 : 3;
/* Endpoint L1 Acceptable Latency Must be 0x0 for non-Endpoint devices. */
uint_reg_t l1_lat : 3;
/*
* Undefined since PCI Express 1.1 (Was Attention Button Present for PCI
* Express 1.0a)
*/
uint_reg_t r1 : 1;
/*
* Undefined since PCI Express 1.1 (Was Attention Indicator Present for
* PCI Express 1.0a)
*/
uint_reg_t r2 : 1;
/*
* Undefined since PCI Express 1.1 (Was Power Indicator Present for PCI
* Express 1.0a)
*/
uint_reg_t r3 : 1;
/*
* Role-Based Error Reporting, writable through the MAC_STANDARD
* interface. Required to be set for device compliant to 1.1 spec and
* later.
*/
uint_reg_t rer : 1;
/* Reserved. */
uint_reg_t __reserved_1 : 2;
/* Captured Slot Power Limit Value Upstream port only. */
uint_reg_t slot_pwr_lim : 8;
/* Captured Slot Power Limit Scale Upstream port only. */
uint_reg_t slot_pwr_scale : 2;
/* Reserved. */
uint_reg_t __reserved_2 : 4;
/* Endpoint L0s Acceptable LatencyMust be 0x0 for non-Endpoint devices. */
uint_reg_t l0s_lat : 1;
/* Reserved. */
uint_reg_t __reserved_3 : 31;
#else /* __BIG_ENDIAN__ */
uint_reg_t __reserved_3 : 31;
uint_reg_t l0s_lat : 1;
uint_reg_t __reserved_2 : 4;
uint_reg_t slot_pwr_scale : 2;
uint_reg_t slot_pwr_lim : 8;
uint_reg_t __reserved_1 : 2;
uint_reg_t rer : 1;
uint_reg_t r3 : 1;
uint_reg_t r2 : 1;
uint_reg_t r1 : 1;
uint_reg_t l1_lat : 3;
uint_reg_t __reserved_0 : 3;
uint_reg_t ext_tag_field_supported : 1;
uint_reg_t phantom_function_supported : 2;
uint_reg_t mps_sup : 3;
#endif
};
uint_reg_t word;
} TRIO_PCIE_RC_DEVICE_CAP_t;
/* Device Control Register. */
__extension__
typedef union
{
struct
{
#ifndef __BIG_ENDIAN__
/* Correctable Error Reporting Enable */
uint_reg_t cor_err_ena : 1;
/* Non-Fatal Error Reporting Enable */
uint_reg_t nf_err_ena : 1;
/* Fatal Error Reporting Enable */
uint_reg_t fatal_err_ena : 1;
/* Unsupported Request Reporting Enable */
uint_reg_t ur_ena : 1;
/* Relaxed orderring enable */
uint_reg_t ro_ena : 1;
/* Max Payload Size */
uint_reg_t max_payload_size : 3;
/* Extended Tag Field Enable */
uint_reg_t ext_tag : 1;
/* Phantom Function Enable */
uint_reg_t ph_fn_ena : 1;
/* AUX Power PM Enable */
uint_reg_t aux_pm_ena : 1;
/* Enable NoSnoop */
uint_reg_t no_snoop : 1;
/* Max read request size */
uint_reg_t max_read_req_sz : 3;
/* Reserved. */
uint_reg_t __reserved : 49;
#else /* __BIG_ENDIAN__ */
uint_reg_t __reserved : 49;
uint_reg_t max_read_req_sz : 3;
uint_reg_t no_snoop : 1;
uint_reg_t aux_pm_ena : 1;
uint_reg_t ph_fn_ena : 1;
uint_reg_t ext_tag : 1;
uint_reg_t max_payload_size : 3;
uint_reg_t ro_ena : 1;
uint_reg_t ur_ena : 1;
uint_reg_t fatal_err_ena : 1;
uint_reg_t nf_err_ena : 1;
uint_reg_t cor_err_ena : 1;
#endif
};
uint_reg_t word;
} TRIO_PCIE_RC_DEVICE_CONTROL_t;
#endif /* !defined(__ASSEMBLER__) */
#endif /* !defined(__ARCH_TRIO_PCIE_RC_H__) */
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_TRIO_PCIE_RC_DEF_H__
#define __ARCH_TRIO_PCIE_RC_DEF_H__
#define TRIO_PCIE_RC_DEVICE_CAP 0x0074
#define TRIO_PCIE_RC_DEVICE_CONTROL 0x0078
#define TRIO_PCIE_RC_DEVICE_ID_VEN_ID 0x0000
#define TRIO_PCIE_RC_DEVICE_ID_VEN_ID__DEV_ID_SHIFT 16
#define TRIO_PCIE_RC_REVISION_ID 0x0008
#endif /* !defined(__ARCH_TRIO_PCIE_RC_DEF_H__) */
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_TRIO_SHM_H__
#define __ARCH_TRIO_SHM_H__
#include <arch/abi.h>
#include <arch/trio_shm_def.h>
#ifndef __ASSEMBLER__
/**
* TRIO DMA Descriptor.
* The TRIO DMA descriptor is written by software and consumed by hardware.
* It is used to specify the location of transaction data in the IO and Tile
* domains.
*/
__extension__
typedef union
{
struct
{
/* Word 0 */
#ifndef __BIG_ENDIAN__
/** Tile side virtual address. */
int_reg_t va : 42;
/**
* Encoded size of buffer used on push DMA when C=1:
* 0 = 128 bytes
* 1 = 256 bytes
* 2 = 512 bytes
* 3 = 1024 bytes
* 4 = 1664 bytes
* 5 = 4096 bytes
* 6 = 10368 bytes
* 7 = 16384 bytes
*/
uint_reg_t bsz : 3;
/**
* Chaining designation. Always zero for pull DMA
* 0 : Unchained buffer pointer
* 1 : Chained buffer pointer. Next buffer descriptor (e.g. VA) stored
* in 1st 8-bytes in buffer. For chained buffers, first 8-bytes of each
* buffer contain the next buffer descriptor formatted exactly like a PDE
* buffer descriptor. This allows a chained PDE buffer to be sent using
* push DMA.
*/
uint_reg_t c : 1;
/**
* Notification interrupt will be delivered when the transaction has
* completed (all data has been read from or written to the Tile-side
* buffer).
*/
uint_reg_t notif : 1;
/**
* When 0, the XSIZE field specifies the total byte count for the
* transaction. When 1, the XSIZE field is encoded as 2^(N+14) for N in
* {0..6}:
* 0 = 16KB
* 1 = 32KB
* 2 = 64KB
* 3 = 128KB
* 4 = 256KB
* 5 = 512KB
* 6 = 1MB
* All other encodings of the XSIZE field are reserved when SMOD=1
*/
uint_reg_t smod : 1;
/**
* Total number of bytes to move for this transaction. When SMOD=1,
* this field is encoded - see SMOD description.
*/
uint_reg_t xsize : 14;
/** Reserved. */
uint_reg_t __reserved_0 : 1;
/**
* Generation number. Used to indicate a valid descriptor in ring. When
* a new descriptor is written into the ring, software must toggle this
* bit. The net effect is that the GEN bit being written into new
* descriptors toggles each time the ring tail pointer wraps.
*/
uint_reg_t gen : 1;
#else /* __BIG_ENDIAN__ */
uint_reg_t gen : 1;
uint_reg_t __reserved_0 : 1;
uint_reg_t xsize : 14;
uint_reg_t smod : 1;
uint_reg_t notif : 1;
uint_reg_t c : 1;
uint_reg_t bsz : 3;
int_reg_t va : 42;
#endif
/* Word 1 */
#ifndef __BIG_ENDIAN__
/** IO-side address */
uint_reg_t io_address : 64;
#else /* __BIG_ENDIAN__ */
uint_reg_t io_address : 64;
#endif
};
/** Word access */
uint_reg_t words[2];
} TRIO_DMA_DESC_t;
#endif /* !defined(__ASSEMBLER__) */
#endif /* !defined(__ARCH_TRIO_SHM_H__) */
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_TRIO_SHM_DEF_H__
#define __ARCH_TRIO_SHM_DEF_H__
#endif /* !defined(__ARCH_TRIO_SHM_DEF_H__) */
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_USB_HOST_H__
#define __ARCH_USB_HOST_H__
#include <arch/abi.h>
#include <arch/usb_host_def.h>
#ifndef __ASSEMBLER__
#endif /* !defined(__ASSEMBLER__) */
#endif /* !defined(__ARCH_USB_HOST_H__) */
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* Machine-generated file; do not edit. */
#ifndef __ARCH_USB_HOST_DEF_H__
#define __ARCH_USB_HOST_DEF_H__
#endif /* !defined(__ARCH_USB_HOST_DEF_H__) */
...@@ -9,7 +9,6 @@ header-y += hardwall.h ...@@ -9,7 +9,6 @@ header-y += hardwall.h
generic-y += bug.h generic-y += bug.h
generic-y += bugs.h generic-y += bugs.h
generic-y += cputime.h generic-y += cputime.h
generic-y += device.h
generic-y += div64.h generic-y += div64.h
generic-y += emergency-restart.h generic-y += emergency-restart.h
generic-y += errno.h generic-y += errno.h
......
...@@ -27,11 +27,17 @@ ...@@ -27,11 +27,17 @@
#define L2_CACHE_ALIGN(x) (((x)+(L2_CACHE_BYTES-1)) & -L2_CACHE_BYTES) #define L2_CACHE_ALIGN(x) (((x)+(L2_CACHE_BYTES-1)) & -L2_CACHE_BYTES)
/* /*
* TILE-Gx is fully coherent so we don't need to define ARCH_DMA_MINALIGN. * TILEPro I/O is not always coherent (networking typically uses coherent
* I/O, but PCI traffic does not) and setting ARCH_DMA_MINALIGN to the
* L2 cacheline size helps ensure that kernel heap allocations are aligned.
* TILE-Gx I/O is always coherent when used on hash-for-home pages.
*
* However, it's possible at runtime to request not to use hash-for-home
* for the kernel heap, in which case the kernel will use flush-and-inval
* to manage coherence. As a result, we use L2_CACHE_BYTES for the
* DMA minimum alignment to avoid false sharing in the kernel heap.
*/ */
#ifndef __tilegx__
#define ARCH_DMA_MINALIGN L2_CACHE_BYTES #define ARCH_DMA_MINALIGN L2_CACHE_BYTES
#endif
/* use the cache line size for the L2, which is where it counts */ /* use the cache line size for the L2, which is where it counts */
#define SMP_CACHE_BYTES_SHIFT L2_CACHE_SHIFT #define SMP_CACHE_BYTES_SHIFT L2_CACHE_SHIFT
......
...@@ -21,4 +21,22 @@ ...@@ -21,4 +21,22 @@
__wsum do_csum(const unsigned char *buff, int len); __wsum do_csum(const unsigned char *buff, int len);
#define do_csum do_csum #define do_csum do_csum
/*
* Return the sum of all the 16-bit subwords in a long.
* This sums two subwords on a 32-bit machine, and four on 64 bits.
* The implementation does two vector adds to capture any overflow.
*/
static inline unsigned int csum_long(unsigned long x)
{
unsigned long ret;
#ifdef __tilegx__
ret = __insn_v2sadu(x, 0);
ret = __insn_v2sadu(ret, 0);
#else
ret = __insn_sadh_u(x, 0);
ret = __insn_sadh_u(ret, 0);
#endif
return ret;
}
#endif /* _ASM_TILE_CHECKSUM_H */ #endif /* _ASM_TILE_CHECKSUM_H */
...@@ -10,24 +10,24 @@ ...@@ -10,24 +10,24 @@
* MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for * NON INFRINGEMENT. See the GNU General Public License for
* more details. * more details.
* * Arch specific extensions to struct device
* The hypervisor's memory controller profiling infrastructure allows
* the programmer to find out what fraction of the available memory
* bandwidth is being consumed at each memory controller. The
* profiler provides start, stop, and clear operations to allows
* profiling over a specific time window, as well as an interface for
* reading the most recent profile values.
*
* This header declares IOCTL codes necessary to control memprof.
*/ */
#ifndef _ASM_TILE_MEMPROF_H
#define _ASM_TILE_MEMPROF_H
#include <linux/ioctl.h> #ifndef _ASM_TILE_DEVICE_H
#define _ASM_TILE_DEVICE_H
struct dev_archdata {
/* DMA operations on that device */
struct dma_map_ops *dma_ops;
/* Offset of the DMA address from the PA. */
dma_addr_t dma_offset;
/* Highest DMA address that can be generated by this device. */
dma_addr_t max_direct_dma_addr;
};
#define MEMPROF_IOCTL_TYPE 0xB4 struct pdev_archdata {
#define MEMPROF_IOCTL_START _IO(MEMPROF_IOCTL_TYPE, 0) };
#define MEMPROF_IOCTL_STOP _IO(MEMPROF_IOCTL_TYPE, 1)
#define MEMPROF_IOCTL_CLEAR _IO(MEMPROF_IOCTL_TYPE, 2)
#endif /* _ASM_TILE_MEMPROF_H */ #endif /* _ASM_TILE_DEVICE_H */
...@@ -20,69 +20,80 @@ ...@@ -20,69 +20,80 @@
#include <linux/cache.h> #include <linux/cache.h>
#include <linux/io.h> #include <linux/io.h>
/* extern struct dma_map_ops *tile_dma_map_ops;
* Note that on x86 and powerpc, there is a "struct dma_mapping_ops" extern struct dma_map_ops *gx_pci_dma_map_ops;
* that is used for all the DMA operations. For now, we don't have an extern struct dma_map_ops *gx_legacy_pci_dma_map_ops;
* equivalent on tile, because we only have a single way of doing DMA.
* (Tilera bug 7994 to use dma_mapping_ops.) static inline struct dma_map_ops *get_dma_ops(struct device *dev)
*/ {
if (dev && dev->archdata.dma_ops)
return dev->archdata.dma_ops;
else
return tile_dma_map_ops;
}
static inline dma_addr_t get_dma_offset(struct device *dev)
{
return dev->archdata.dma_offset;
}
static inline void set_dma_offset(struct device *dev, dma_addr_t off)
{
dev->archdata.dma_offset = off;
}
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) static inline dma_addr_t phys_to_dma(struct device *dev, phys_addr_t paddr)
#define dma_free_noncoherent(d, s, v, h) dma_free_coherent(d, s, v, h) {
return paddr + get_dma_offset(dev);
extern dma_addr_t dma_map_single(struct device *dev, void *ptr, size_t size, }
enum dma_data_direction);
extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, static inline phys_addr_t dma_to_phys(struct device *dev, dma_addr_t daddr)
size_t size, enum dma_data_direction); {
extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, return daddr - get_dma_offset(dev);
enum dma_data_direction); }
extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
int nhwentries, enum dma_data_direction); static inline void dma_mark_clean(void *addr, size_t size) {}
extern dma_addr_t dma_map_page(struct device *dev, struct page *page,
unsigned long offset, size_t size, #include <asm-generic/dma-mapping-common.h>
enum dma_data_direction);
extern void dma_unmap_page(struct device *dev, dma_addr_t dma_address, static inline void set_dma_ops(struct device *dev, struct dma_map_ops *ops)
size_t size, enum dma_data_direction); {
extern void dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, dev->archdata.dma_ops = ops;
int nelems, enum dma_data_direction); }
extern void dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg,
int nelems, enum dma_data_direction); static inline bool dma_capable(struct device *dev, dma_addr_t addr, size_t size)
{
if (!dev->dma_mask)
void *dma_alloc_coherent(struct device *dev, size_t size, return 0;
dma_addr_t *dma_handle, gfp_t flag);
return addr + size - 1 <= *dev->dma_mask;
void dma_free_coherent(struct device *dev, size_t size, }
void *vaddr, dma_addr_t dma_handle);
extern void dma_sync_single_for_cpu(struct device *, dma_addr_t, size_t,
enum dma_data_direction);
extern void dma_sync_single_for_device(struct device *, dma_addr_t,
size_t, enum dma_data_direction);
extern void dma_sync_single_range_for_cpu(struct device *, dma_addr_t,
unsigned long offset, size_t,
enum dma_data_direction);
extern void dma_sync_single_range_for_device(struct device *, dma_addr_t,
unsigned long offset, size_t,
enum dma_data_direction);
extern void dma_cache_sync(struct device *dev, void *vaddr, size_t,
enum dma_data_direction);
static inline int static inline int
dma_mapping_error(struct device *dev, dma_addr_t dma_addr) dma_mapping_error(struct device *dev, dma_addr_t dma_addr)
{ {
return 0; return get_dma_ops(dev)->mapping_error(dev, dma_addr);
} }
static inline int static inline int
dma_supported(struct device *dev, u64 mask) dma_supported(struct device *dev, u64 mask)
{ {
return 1; return get_dma_ops(dev)->dma_supported(dev, mask);
} }
static inline int static inline int
dma_set_mask(struct device *dev, u64 mask) dma_set_mask(struct device *dev, u64 mask)
{ {
struct dma_map_ops *dma_ops = get_dma_ops(dev);
/* Handle legacy PCI devices with limited memory addressability. */
if ((dma_ops == gx_pci_dma_map_ops) && (mask <= DMA_BIT_MASK(32))) {
set_dma_ops(dev, gx_legacy_pci_dma_map_ops);
set_dma_offset(dev, 0);
if (mask > dev->archdata.max_direct_dma_addr)
mask = dev->archdata.max_direct_dma_addr;
}
if (!dev->dma_mask || !dma_supported(dev, mask)) if (!dev->dma_mask || !dma_supported(dev, mask))
return -EIO; return -EIO;
...@@ -91,4 +102,43 @@ dma_set_mask(struct device *dev, u64 mask) ...@@ -91,4 +102,43 @@ dma_set_mask(struct device *dev, u64 mask)
return 0; return 0;
} }
static inline void *dma_alloc_attrs(struct device *dev, size_t size,
dma_addr_t *dma_handle, gfp_t flag,
struct dma_attrs *attrs)
{
struct dma_map_ops *dma_ops = get_dma_ops(dev);
void *cpu_addr;
cpu_addr = dma_ops->alloc(dev, size, dma_handle, flag, attrs);
debug_dma_alloc_coherent(dev, size, *dma_handle, cpu_addr);
return cpu_addr;
}
static inline void dma_free_attrs(struct device *dev, size_t size,
void *cpu_addr, dma_addr_t dma_handle,
struct dma_attrs *attrs)
{
struct dma_map_ops *dma_ops = get_dma_ops(dev);
debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
dma_ops->free(dev, size, cpu_addr, dma_handle, attrs);
}
#define dma_alloc_coherent(d, s, h, f) dma_alloc_attrs(d, s, h, f, NULL)
#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_attrs(d, s, h, f, NULL)
#define dma_free_coherent(d, s, v, h) dma_free_attrs(d, s, v, h, NULL)
#define dma_free_noncoherent(d, s, v, h) dma_free_attrs(d, s, v, h, NULL)
/*
* dma_alloc_noncoherent() is #defined to return coherent memory,
* so there's no need to do any flushing here.
*/
static inline void dma_cache_sync(struct device *dev, void *vaddr, size_t size,
enum dma_data_direction direction)
{
}
#endif /* _ASM_TILE_DMA_MAPPING_H */ #endif /* _ASM_TILE_DMA_MAPPING_H */
...@@ -45,14 +45,22 @@ ...@@ -45,14 +45,22 @@
* *
* TLB entries of such buffers will not be flushed across * TLB entries of such buffers will not be flushed across
* task switches. * task switches.
*
* We don't bother with a FIX_HOLE since above the fixmaps
* is unmapped memory in any case.
*/ */
enum fixed_addresses { enum fixed_addresses {
#ifdef __tilegx__
/*
* TILEPro has unmapped memory above so the hole isn't needed,
* and in any case the hole pushes us over a single 16MB pmd.
*/
FIX_HOLE,
#endif
#ifdef CONFIG_HIGHMEM #ifdef CONFIG_HIGHMEM
FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */ FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1, FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
#endif
#ifdef __tilegx__ /* see homecache.c */
FIX_HOMECACHE_BEGIN,
FIX_HOMECACHE_END = FIX_HOMECACHE_BEGIN+(NR_CPUS)-1,
#endif #endif
__end_of_permanent_fixed_addresses, __end_of_permanent_fixed_addresses,
......
...@@ -79,10 +79,17 @@ extern void homecache_change_page_home(struct page *, int order, int home); ...@@ -79,10 +79,17 @@ extern void homecache_change_page_home(struct page *, int order, int home);
/* /*
* Flush a page out of whatever cache(s) it is in. * Flush a page out of whatever cache(s) it is in.
* This is more than just finv, since it properly handles waiting * This is more than just finv, since it properly handles waiting
* for the data to reach memory on tilepro, but it can be quite * for the data to reach memory, but it can be quite
* heavyweight, particularly on hash-for-home memory. * heavyweight, particularly on incoherent or immutable memory.
*/ */
extern void homecache_flush_cache(struct page *, int order); extern void homecache_finv_page(struct page *);
/*
* Flush a page out of the specified home cache.
* Note that the specified home need not be the actual home of the page,
* as for example might be the case when coordinating with I/O devices.
*/
extern void homecache_finv_map_page(struct page *, int home);
/* /*
* Allocate a page with the given GFP flags, home, and optionally * Allocate a page with the given GFP flags, home, and optionally
...@@ -104,10 +111,10 @@ extern struct page *homecache_alloc_pages_node(int nid, gfp_t gfp_mask, ...@@ -104,10 +111,10 @@ extern struct page *homecache_alloc_pages_node(int nid, gfp_t gfp_mask,
* routines use homecache_change_page_home() to reset the home * routines use homecache_change_page_home() to reset the home
* back to the default before returning the page to the allocator. * back to the default before returning the page to the allocator.
*/ */
void __homecache_free_pages(struct page *, unsigned int order);
void homecache_free_pages(unsigned long addr, unsigned int order); void homecache_free_pages(unsigned long addr, unsigned int order);
#define homecache_free_page(page) \ #define __homecache_free_page(page) __homecache_free_pages((page), 0)
homecache_free_pages((page), 0) #define homecache_free_page(page) homecache_free_pages((page), 0)
/* /*
......
...@@ -62,6 +62,92 @@ extern void iounmap(volatile void __iomem *addr); ...@@ -62,6 +62,92 @@ extern void iounmap(volatile void __iomem *addr);
#define mm_ptov(addr) ((void *)phys_to_virt(addr)) #define mm_ptov(addr) ((void *)phys_to_virt(addr))
#define mm_vtop(addr) ((unsigned long)virt_to_phys(addr)) #define mm_vtop(addr) ((unsigned long)virt_to_phys(addr))
#if CHIP_HAS_MMIO()
/*
* We use inline assembly to guarantee that the compiler does not
* split an access into multiple byte-sized accesses as it might
* sometimes do if a register data structure is marked "packed".
* Obviously on tile we can't tolerate such an access being
* actually unaligned, but we want to avoid the case where the
* compiler conservatively would generate multiple accesses even
* for an aligned read or write.
*/
static inline u8 __raw_readb(const volatile void __iomem *addr)
{
return *(const volatile u8 __force *)addr;
}
static inline u16 __raw_readw(const volatile void __iomem *addr)
{
u16 ret;
asm volatile("ld2u %0, %1" : "=r" (ret) : "r" (addr));
barrier();
return le16_to_cpu(ret);
}
static inline u32 __raw_readl(const volatile void __iomem *addr)
{
u32 ret;
/* Sign-extend to conform to u32 ABI sign-extension convention. */
asm volatile("ld4s %0, %1" : "=r" (ret) : "r" (addr));
barrier();
return le32_to_cpu(ret);
}
static inline u64 __raw_readq(const volatile void __iomem *addr)
{
u64 ret;
asm volatile("ld %0, %1" : "=r" (ret) : "r" (addr));
barrier();
return le64_to_cpu(ret);
}
static inline void __raw_writeb(u8 val, volatile void __iomem *addr)
{
*(volatile u8 __force *)addr = val;
}
static inline void __raw_writew(u16 val, volatile void __iomem *addr)
{
asm volatile("st2 %0, %1" :: "r" (addr), "r" (cpu_to_le16(val)));
}
static inline void __raw_writel(u32 val, volatile void __iomem *addr)
{
asm volatile("st4 %0, %1" :: "r" (addr), "r" (cpu_to_le32(val)));
}
static inline void __raw_writeq(u64 val, volatile void __iomem *addr)
{
asm volatile("st %0, %1" :: "r" (addr), "r" (cpu_to_le64(val)));
}
/*
* The on-chip I/O hardware on tilegx is configured with VA=PA for the
* kernel's PA range. The low-level APIs and field names use "va" and
* "void *" nomenclature, to be consistent with the general notion
* that the addresses in question are virtualizable, but in the kernel
* context we are actually manipulating PA values. (In other contexts,
* e.g. access from user space, we do in fact use real virtual addresses
* in the va fields.) To allow readers of the code to understand what's
* happening, we direct their attention to this comment by using the
* following two functions that just duplicate __va() and __pa().
*/
typedef unsigned long tile_io_addr_t;
static inline tile_io_addr_t va_to_tile_io_addr(void *va)
{
BUILD_BUG_ON(sizeof(phys_addr_t) != sizeof(tile_io_addr_t));
return __pa(va);
}
static inline void *tile_io_addr_to_va(tile_io_addr_t tile_io_addr)
{
return __va(tile_io_addr);
}
#else /* CHIP_HAS_MMIO() */
#ifdef CONFIG_PCI #ifdef CONFIG_PCI
extern u8 _tile_readb(unsigned long addr); extern u8 _tile_readb(unsigned long addr);
...@@ -73,10 +159,19 @@ extern void _tile_writew(u16 val, unsigned long addr); ...@@ -73,10 +159,19 @@ extern void _tile_writew(u16 val, unsigned long addr);
extern void _tile_writel(u32 val, unsigned long addr); extern void _tile_writel(u32 val, unsigned long addr);
extern void _tile_writeq(u64 val, unsigned long addr); extern void _tile_writeq(u64 val, unsigned long addr);
#else #define __raw_readb(addr) _tile_readb((unsigned long)addr)
#define __raw_readw(addr) _tile_readw((unsigned long)addr)
#define __raw_readl(addr) _tile_readl((unsigned long)addr)
#define __raw_readq(addr) _tile_readq((unsigned long)addr)
#define __raw_writeb(val, addr) _tile_writeb(val, (unsigned long)addr)
#define __raw_writew(val, addr) _tile_writew(val, (unsigned long)addr)
#define __raw_writel(val, addr) _tile_writel(val, (unsigned long)addr)
#define __raw_writeq(val, addr) _tile_writeq(val, (unsigned long)addr)
#else /* CONFIG_PCI */
/* /*
* The Tile architecture does not support IOMEM unless PCI is enabled. * The tilepro architecture does not support IOMEM unless PCI is enabled.
* Unfortunately we can't yet simply not declare these methods, * Unfortunately we can't yet simply not declare these methods,
* since some generic code that compiles into the kernel, but * since some generic code that compiles into the kernel, but
* we never run, uses them unconditionally. * we never run, uses them unconditionally.
...@@ -88,65 +183,58 @@ static inline int iomem_panic(void) ...@@ -88,65 +183,58 @@ static inline int iomem_panic(void)
return 0; return 0;
} }
static inline u8 _tile_readb(unsigned long addr) static inline u8 readb(unsigned long addr)
{ {
return iomem_panic(); return iomem_panic();
} }
static inline u16 _tile_readw(unsigned long addr) static inline u16 _readw(unsigned long addr)
{ {
return iomem_panic(); return iomem_panic();
} }
static inline u32 _tile_readl(unsigned long addr) static inline u32 readl(unsigned long addr)
{ {
return iomem_panic(); return iomem_panic();
} }
static inline u64 _tile_readq(unsigned long addr) static inline u64 readq(unsigned long addr)
{ {
return iomem_panic(); return iomem_panic();
} }
static inline void _tile_writeb(u8 val, unsigned long addr) static inline void writeb(u8 val, unsigned long addr)
{ {
iomem_panic(); iomem_panic();
} }
static inline void _tile_writew(u16 val, unsigned long addr) static inline void writew(u16 val, unsigned long addr)
{ {
iomem_panic(); iomem_panic();
} }
static inline void _tile_writel(u32 val, unsigned long addr) static inline void writel(u32 val, unsigned long addr)
{ {
iomem_panic(); iomem_panic();
} }
static inline void _tile_writeq(u64 val, unsigned long addr) static inline void writeq(u64 val, unsigned long addr)
{ {
iomem_panic(); iomem_panic();
} }
#endif #endif /* CONFIG_PCI */
#endif /* CHIP_HAS_MMIO() */
#define readb(addr) _tile_readb((unsigned long)addr) #define readb __raw_readb
#define readw(addr) _tile_readw((unsigned long)addr) #define readw __raw_readw
#define readl(addr) _tile_readl((unsigned long)addr) #define readl __raw_readl
#define readq(addr) _tile_readq((unsigned long)addr) #define readq __raw_readq
#define writeb(val, addr) _tile_writeb(val, (unsigned long)addr) #define writeb __raw_writeb
#define writew(val, addr) _tile_writew(val, (unsigned long)addr) #define writew __raw_writew
#define writel(val, addr) _tile_writel(val, (unsigned long)addr) #define writel __raw_writel
#define writeq(val, addr) _tile_writeq(val, (unsigned long)addr) #define writeq __raw_writeq
#define __raw_readb readb
#define __raw_readw readw
#define __raw_readl readl
#define __raw_readq readq
#define __raw_writeb writeb
#define __raw_writew writew
#define __raw_writel writel
#define __raw_writeq writeq
#define readb_relaxed readb #define readb_relaxed readb
#define readw_relaxed readw #define readw_relaxed readw
......
...@@ -174,7 +174,9 @@ static inline __attribute_const__ int get_order(unsigned long size) ...@@ -174,7 +174,9 @@ static inline __attribute_const__ int get_order(unsigned long size)
#define MEM_LOW_END (HALF_VA_SPACE - 1) /* low half */ #define MEM_LOW_END (HALF_VA_SPACE - 1) /* low half */
#define MEM_HIGH_START (-HALF_VA_SPACE) /* high half */ #define MEM_HIGH_START (-HALF_VA_SPACE) /* high half */
#define PAGE_OFFSET MEM_HIGH_START #define PAGE_OFFSET MEM_HIGH_START
#define _VMALLOC_START _AC(0xfffffff500000000, UL) /* 4 GB */ #define FIXADDR_BASE _AC(0xfffffff400000000, UL) /* 4 GB */
#define FIXADDR_TOP _AC(0xfffffff500000000, UL) /* 4 GB */
#define _VMALLOC_START FIXADDR_TOP
#define HUGE_VMAP_BASE _AC(0xfffffff600000000, UL) /* 4 GB */ #define HUGE_VMAP_BASE _AC(0xfffffff600000000, UL) /* 4 GB */
#define MEM_SV_START _AC(0xfffffff700000000, UL) /* 256 MB */ #define MEM_SV_START _AC(0xfffffff700000000, UL) /* 256 MB */
#define MEM_SV_INTRPT MEM_SV_START #define MEM_SV_INTRPT MEM_SV_START
...@@ -185,9 +187,6 @@ static inline __attribute_const__ int get_order(unsigned long size) ...@@ -185,9 +187,6 @@ static inline __attribute_const__ int get_order(unsigned long size)
/* Highest DTLB address we will use */ /* Highest DTLB address we will use */
#define KERNEL_HIGH_VADDR MEM_SV_START #define KERNEL_HIGH_VADDR MEM_SV_START
/* Since we don't currently provide any fixmaps, we use an impossible VA. */
#define FIXADDR_TOP MEM_HV_START
#else /* !__tilegx__ */ #else /* !__tilegx__ */
/* /*
......
...@@ -15,9 +15,13 @@ ...@@ -15,9 +15,13 @@
#ifndef _ASM_TILE_PCI_H #ifndef _ASM_TILE_PCI_H
#define _ASM_TILE_PCI_H #define _ASM_TILE_PCI_H
#include <linux/dma-mapping.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/numa.h>
#include <asm-generic/pci_iomap.h> #include <asm-generic/pci_iomap.h>
#ifndef __tilegx__
/* /*
* Structure of a PCI controller (host bridge) * Structure of a PCI controller (host bridge)
*/ */
...@@ -40,6 +44,16 @@ struct pci_controller { ...@@ -40,6 +44,16 @@ struct pci_controller {
struct resource mem_resources[3]; struct resource mem_resources[3];
}; };
/*
* This flag tells if the platform is TILEmpower that needs
* special configuration for the PLX switch chip.
*/
extern int tile_plx_gen1;
static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {}
#define TILE_NUM_PCIE 2
/* /*
* The hypervisor maps the entirety of CPA-space as bus addresses, so * The hypervisor maps the entirety of CPA-space as bus addresses, so
* bus addresses are physical addresses. The networking and block * bus addresses are physical addresses. The networking and block
...@@ -47,15 +61,135 @@ struct pci_controller { ...@@ -47,15 +61,135 @@ struct pci_controller {
*/ */
#define PCI_DMA_BUS_IS_PHYS 1 #define PCI_DMA_BUS_IS_PHYS 1
/* generic pci stuff */
#include <asm-generic/pci.h>
#else
#include <asm/page.h>
#include <gxio/trio.h>
/**
* We reserve the hugepage-size address range at the top of the 64-bit address
* space to serve as the PCI window, emulating the BAR0 space of an endpoint
* device. This window is used by the chip-to-chip applications running on
* the RC node. The reason for carving out this window is that Mem-Maps that
* back up this window will not overlap with those that map the real physical
* memory.
*/
#define PCIE_HOST_BAR0_SIZE HPAGE_SIZE
#define PCIE_HOST_BAR0_START HPAGE_MASK
/**
* The first PAGE_SIZE of the above "BAR" window is mapped to the
* gxpci_host_regs structure.
*/
#define PCIE_HOST_REGS_SIZE PAGE_SIZE
/*
* This is the PCI address where the Mem-Map interrupt regions start.
* We use the 2nd to the last huge page of the 64-bit address space.
* The last huge page is used for the rootcomplex "bar", for C2C purpose.
*/
#define MEM_MAP_INTR_REGIONS_BASE (HPAGE_MASK - HPAGE_SIZE)
/*
* Each Mem-Map interrupt region occupies 4KB.
*/
#define MEM_MAP_INTR_REGION_SIZE (1 << TRIO_MAP_MEM_LIM__ADDR_SHIFT)
/*
* Allocate the PCI BAR window right below 4GB.
*/
#define TILE_PCI_BAR_WINDOW_TOP (1ULL << 32)
/*
* Allocate 1GB for the PCI BAR window.
*/
#define TILE_PCI_BAR_WINDOW_SIZE (1 << 30)
/*
* This is the highest bus address targeting the host memory that
* can be generated by legacy PCI devices with 32-bit or less
* DMA capability, dictated by the BAR window size and location.
*/
#define TILE_PCI_MAX_DIRECT_DMA_ADDRESS \
(TILE_PCI_BAR_WINDOW_TOP - TILE_PCI_BAR_WINDOW_SIZE - 1)
/*
* We shift the PCI bus range for all the physical memory up by the whole PA
* range. The corresponding CPA of an incoming PCI request will be the PCI
* address minus TILE_PCI_MEM_MAP_BASE_OFFSET. This also implies
* that the 64-bit capable devices will be given DMA addresses as
* the CPA plus TILE_PCI_MEM_MAP_BASE_OFFSET. To support 32-bit
* devices, we create a separate map region that handles the low
* 4GB.
*/
#define TILE_PCI_MEM_MAP_BASE_OFFSET (1ULL << CHIP_PA_WIDTH())
/*
* Start of the PCI memory resource, which starts at the end of the
* maximum system physical RAM address.
*/
#define TILE_PCI_MEM_START (1ULL << CHIP_PA_WIDTH())
/*
* Structure of a PCI controller (host bridge) on Gx.
*/
struct pci_controller {
/* Pointer back to the TRIO that this PCIe port is connected to. */
gxio_trio_context_t *trio;
int mac; /* PCIe mac index on the TRIO shim */
int trio_index; /* Index of TRIO shim that contains the MAC. */
int pio_mem_index; /* PIO region index for memory access */
/*
* Mem-Map regions for all the memory controllers so that Linux can
* map all of its physical memory space to the PCI bus.
*/
int mem_maps[MAX_NUMNODES];
int index; /* PCI domain number */
struct pci_bus *root_bus;
/* PCI memory space resource for this controller. */
struct resource mem_space;
char mem_space_name[32];
uint64_t mem_offset; /* cpu->bus memory mapping offset. */
int first_busno;
struct pci_ops *ops;
/* Table that maps the INTx numbers to Linux irq numbers. */
int irq_intx_table[4];
/* Address ranges that are routed to this controller/bridge. */
struct resource mem_resources[3];
};
extern struct pci_controller pci_controllers[TILEGX_NUM_TRIO * TILEGX_TRIO_PCIES];
extern gxio_trio_context_t trio_contexts[TILEGX_NUM_TRIO];
extern void pci_iounmap(struct pci_dev *dev, void __iomem *);
/*
* The PCI address space does not equal the physical memory address
* space (we have an IOMMU). The IDE and SCSI device layers use this
* boolean for bounce buffer decisions.
*/
#define PCI_DMA_BUS_IS_PHYS 0
#endif /* __tilegx__ */
int __init tile_pci_init(void); int __init tile_pci_init(void);
int __init pcibios_init(void); int __init pcibios_init(void);
static inline void pci_iounmap(struct pci_dev *dev, void __iomem *addr) {}
void __devinit pcibios_fixup_bus(struct pci_bus *bus); void __devinit pcibios_fixup_bus(struct pci_bus *bus);
#define TILE_NUM_PCIE 2
#define pci_domain_nr(bus) (((struct pci_controller *)(bus)->sysdata)->index) #define pci_domain_nr(bus) (((struct pci_controller *)(bus)->sysdata)->index)
/* /*
...@@ -79,19 +213,10 @@ static inline int pcibios_assign_all_busses(void) ...@@ -79,19 +213,10 @@ static inline int pcibios_assign_all_busses(void)
#define PCIBIOS_MIN_MEM 0 #define PCIBIOS_MIN_MEM 0
#define PCIBIOS_MIN_IO 0 #define PCIBIOS_MIN_IO 0
/*
* This flag tells if the platform is TILEmpower that needs
* special configuration for the PLX switch chip.
*/
extern int tile_plx_gen1;
/* Use any cpu for PCI. */ /* Use any cpu for PCI. */
#define cpumask_of_pcibus(bus) cpu_online_mask #define cpumask_of_pcibus(bus) cpu_online_mask
/* implement the pci_ DMA API in terms of the generic device dma_ one */ /* implement the pci_ DMA API in terms of the generic device dma_ one */
#include <asm-generic/pci-dma-compat.h> #include <asm-generic/pci-dma-compat.h>
/* generic pci stuff */
#include <asm-generic/pci.h>
#endif /* _ASM_TILE_PCI_H */ #endif /* _ASM_TILE_PCI_H */
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
#ifndef _GXIO_COMMON_H_
#define _GXIO_COMMON_H_
/*
* Routines shared between the various GXIO device components.
*/
#include <hv/iorpc.h>
#include <linux/types.h>
#include <linux/compiler.h>
#include <linux/io.h>
/* Define the standard gxio MMIO functions using kernel functions. */
#define __gxio_mmio_read8(addr) readb(addr)
#define __gxio_mmio_read16(addr) readw(addr)
#define __gxio_mmio_read32(addr) readl(addr)
#define __gxio_mmio_read64(addr) readq(addr)
#define __gxio_mmio_write8(addr, val) writeb((val), (addr))
#define __gxio_mmio_write16(addr, val) writew((val), (addr))
#define __gxio_mmio_write32(addr, val) writel((val), (addr))
#define __gxio_mmio_write64(addr, val) writeq((val), (addr))
#define __gxio_mmio_read(addr) __gxio_mmio_read64(addr)
#define __gxio_mmio_write(addr, val) __gxio_mmio_write64((addr), (val))
#endif /* !_GXIO_COMMON_H_ */
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
#ifndef _GXIO_DMA_QUEUE_H_
#define _GXIO_DMA_QUEUE_H_
/*
* DMA queue management APIs shared between TRIO and mPIPE.
*/
#include "common.h"
/* The credit counter lives in the high 32 bits. */
#define DMA_QUEUE_CREDIT_SHIFT 32
/*
* State object that tracks a DMA queue's head and tail indices, as
* well as the number of commands posted and completed. The
* structure is accessed via a thread-safe, lock-free algorithm.
*/
typedef struct {
/*
* Address of a MPIPE_EDMA_POST_REGION_VAL_t,
* TRIO_PUSH_DMA_REGION_VAL_t, or TRIO_PULL_DMA_REGION_VAL_t
* register. These register have identical encodings and provide
* information about how many commands have been processed.
*/
void *post_region_addr;
/*
* A lazily-updated count of how many edescs the hardware has
* completed.
*/
uint64_t hw_complete_count __attribute__ ((aligned(64)));
/*
* High 32 bits are a count of available egress command credits,
* low 24 bits are the next egress "slot".
*/
int64_t credits_and_next_index;
} __gxio_dma_queue_t;
/* Initialize a dma queue. */
extern void __gxio_dma_queue_init(__gxio_dma_queue_t *dma_queue,
void *post_region_addr,
unsigned int num_entries);
/*
* Update the "credits_and_next_index" and "hw_complete_count" fields
* based on pending hardware completions. Note that some other thread
* may have already done this and, importantly, may still be in the
* process of updating "credits_and_next_index".
*/
extern void __gxio_dma_queue_update_credits(__gxio_dma_queue_t *dma_queue);
/* Wait for credits to become available. */
extern int64_t __gxio_dma_queue_wait_for_credits(__gxio_dma_queue_t *dma_queue,
int64_t modifier);
/* Reserve slots in the queue, optionally waiting for slots to become
* available, and optionally returning a "completion_slot" suitable for
* direct comparison to "hw_complete_count".
*/
static inline int64_t __gxio_dma_queue_reserve(__gxio_dma_queue_t *dma_queue,
unsigned int num, bool wait,
bool completion)
{
uint64_t slot;
/*
* Try to reserve 'num' egress command slots. We do this by
* constructing a constant that subtracts N credits and adds N to
* the index, and using fetchaddgez to only apply it if the credits
* count doesn't go negative.
*/
int64_t modifier = (((int64_t)(-num)) << DMA_QUEUE_CREDIT_SHIFT) | num;
int64_t old =
__insn_fetchaddgez(&dma_queue->credits_and_next_index,
modifier);
if (unlikely(old + modifier < 0)) {
/*
* We're out of credits. Try once to get more by checking for
* completed egress commands. If that fails, wait or fail.
*/
__gxio_dma_queue_update_credits(dma_queue);
old = __insn_fetchaddgez(&dma_queue->credits_and_next_index,
modifier);
if (old + modifier < 0) {
if (wait)
old = __gxio_dma_queue_wait_for_credits
(dma_queue, modifier);
else
return GXIO_ERR_DMA_CREDITS;
}
}
/* The bottom 24 bits of old encode the "slot". */
slot = (old & 0xffffff);
if (completion) {
/*
* A "completion_slot" is a "slot" which can be compared to
* "hw_complete_count" at any time in the future. To convert
* "slot" into a "completion_slot", we access "hw_complete_count"
* once (knowing that we have reserved a slot, and thus, it will
* be "basically" accurate), and combine its high 40 bits with
* the 24 bit "slot", and handle "wrapping" by adding "1 << 24"
* if the result is LESS than "hw_complete_count".
*/
uint64_t complete;
complete = ACCESS_ONCE(dma_queue->hw_complete_count);
slot |= (complete & 0xffffffffff000000);
if (slot < complete)
slot += 0x1000000;
}
/*
* If any of our slots mod 256 were equivalent to 0, go ahead and
* collect some egress credits, and update "hw_complete_count", and
* make sure the index doesn't overflow into the credits.
*/
if (unlikely(((old + num) & 0xff) < num)) {
__gxio_dma_queue_update_credits(dma_queue);
/* Make sure the index doesn't overflow into the credits. */
#ifdef __BIG_ENDIAN__
*(((uint8_t *)&dma_queue->credits_and_next_index) + 4) = 0;
#else
*(((uint8_t *)&dma_queue->credits_and_next_index) + 3) = 0;
#endif
}
return slot;
}
/* Non-inlinable "__gxio_dma_queue_reserve(..., true)". */
extern int64_t __gxio_dma_queue_reserve_aux(__gxio_dma_queue_t *dma_queue,
unsigned int num, int wait);
/* Check whether a particular "completion slot" has completed.
*
* Note that this function requires a "completion slot", and thus
* cannot be used with the result of any "reserve_fast" function.
*/
extern int __gxio_dma_queue_is_complete(__gxio_dma_queue_t *dma_queue,
int64_t completion_slot, int update);
#endif /* !_GXIO_DMA_QUEUE_H_ */
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* This file is machine-generated; DO NOT EDIT! */
#ifndef __IORPC_LINUX_RPC_H__
#define __IORPC_LINUX_RPC_H__
#include <hv/iorpc.h>
#include <linux/string.h>
#include <linux/module.h>
#include <asm/pgtable.h>
#define IORPC_OP_ARM_POLLFD IORPC_OPCODE(IORPC_FORMAT_KERNEL_POLLFD, 0x9000)
#define IORPC_OP_CLOSE_POLLFD IORPC_OPCODE(IORPC_FORMAT_KERNEL_POLLFD, 0x9001)
#define IORPC_OP_GET_MMIO_BASE IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000)
#define IORPC_OP_CHECK_MMIO_OFFSET IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8001)
int __iorpc_arm_pollfd(int fd, int pollfd_cookie);
int __iorpc_close_pollfd(int fd, int pollfd_cookie);
int __iorpc_get_mmio_base(int fd, HV_PTE *base);
int __iorpc_check_mmio_offset(int fd, unsigned long offset, unsigned long size);
#endif /* !__IORPC_LINUX_RPC_H__ */
此差异已折叠。
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* This file is machine-generated; DO NOT EDIT! */
#ifndef __GXIO_MPIPE_INFO_LINUX_RPC_H__
#define __GXIO_MPIPE_INFO_LINUX_RPC_H__
#include <hv/iorpc.h>
#include <hv/drv_mpipe_intf.h>
#include <asm/page.h>
#include <gxio/kiorpc.h>
#include <gxio/mpipe.h>
#include <linux/string.h>
#include <linux/module.h>
#include <asm/pgtable.h>
#define GXIO_MPIPE_INFO_OP_ENUMERATE_AUX IORPC_OPCODE(IORPC_FORMAT_NONE, 0x1251)
#define GXIO_MPIPE_INFO_OP_GET_MMIO_BASE IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000)
#define GXIO_MPIPE_INFO_OP_CHECK_MMIO_OFFSET IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8001)
int gxio_mpipe_info_enumerate_aux(gxio_mpipe_info_context_t * context,
unsigned int idx,
_gxio_mpipe_link_name_t * name,
_gxio_mpipe_link_mac_t * mac);
int gxio_mpipe_info_get_mmio_base(gxio_mpipe_info_context_t * context,
HV_PTE *base);
int gxio_mpipe_info_check_mmio_offset(gxio_mpipe_info_context_t * context,
unsigned long offset, unsigned long size);
#endif /* !__GXIO_MPIPE_INFO_LINUX_RPC_H__ */
此差异已折叠。
/*
* Copyright 2012 Tilera Corporation. 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
* as published by the Free Software Foundation, version 2.
*
* 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, GOOD TITLE or
* NON INFRINGEMENT. See the GNU General Public License for
* more details.
*/
/* This file is machine-generated; DO NOT EDIT! */
#ifndef __GXIO_USB_HOST_LINUX_RPC_H__
#define __GXIO_USB_HOST_LINUX_RPC_H__
#include <hv/iorpc.h>
#include <hv/drv_usb_host_intf.h>
#include <asm/page.h>
#include <gxio/kiorpc.h>
#include <gxio/usb_host.h>
#include <linux/string.h>
#include <linux/module.h>
#include <asm/pgtable.h>
#define GXIO_USB_HOST_OP_CFG_INTERRUPT IORPC_OPCODE(IORPC_FORMAT_KERNEL_INTERRUPT, 0x1800)
#define GXIO_USB_HOST_OP_REGISTER_CLIENT_MEMORY IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x1801)
#define GXIO_USB_HOST_OP_GET_MMIO_BASE IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8000)
#define GXIO_USB_HOST_OP_CHECK_MMIO_OFFSET IORPC_OPCODE(IORPC_FORMAT_NONE_NOUSER, 0x8001)
int gxio_usb_host_cfg_interrupt(gxio_usb_host_context_t * context, int inter_x,
int inter_y, int inter_ipi, int inter_event);
int gxio_usb_host_register_client_memory(gxio_usb_host_context_t * context,
HV_PTE pte, unsigned int flags);
int gxio_usb_host_get_mmio_base(gxio_usb_host_context_t * context,
HV_PTE *base);
int gxio_usb_host_check_mmio_offset(gxio_usb_host_context_t * context,
unsigned long offset, unsigned long size);
#endif /* !__GXIO_USB_HOST_LINUX_RPC_H__ */
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -14,4 +14,9 @@ obj-$(CONFIG_SMP) += smpboot.o smp.o tlb.o ...@@ -14,4 +14,9 @@ obj-$(CONFIG_SMP) += smpboot.o smp.o tlb.o
obj-$(CONFIG_MODULES) += module.o obj-$(CONFIG_MODULES) += module.o
obj-$(CONFIG_EARLY_PRINTK) += early_printk.o obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel_$(BITS).o obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel_$(BITS).o
ifdef CONFIG_TILEGX
obj-$(CONFIG_PCI) += pci_gx.o
else
obj-$(CONFIG_PCI) += pci.o obj-$(CONFIG_PCI) += pci.o
endif
obj-$(CONFIG_TILE_USB) += usb.o
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
...@@ -575,13 +575,6 @@ void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size, ...@@ -575,13 +575,6 @@ void __iomem *ioremap_prot(resource_size_t phys_addr, unsigned long size,
} }
EXPORT_SYMBOL(ioremap_prot); EXPORT_SYMBOL(ioremap_prot);
/* Map a PCI MMIO bus address into VA space. */
void __iomem *ioremap(resource_size_t phys_addr, unsigned long size)
{
panic("ioremap for PCI MMIO is not supported");
}
EXPORT_SYMBOL(ioremap);
/* Unmap an MMIO VA mapping. */ /* Unmap an MMIO VA mapping. */
void iounmap(volatile void __iomem *addr_in) void iounmap(volatile void __iomem *addr_in)
{ {
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册