/*
 * Copyright 2010 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/fs.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/rwsem.h>
#include <linux/kprobes.h>
#include <linux/sched.h>
#include <linux/hardirq.h>
#include <linux/uaccess.h>
#include <linux/smp.h>
#include <linux/cdev.h>
#include <linux/compat.h>
#include <asm/hardwall.h>
#include <asm/traps.h>
#include <asm/siginfo.h>
#include <asm/irq_regs.h>

#include <arch/interrupts.h>
#include <arch/spr_def.h>


/*
 * Implement a per-cpu "hardwall" resource class such as UDN or IPI.
 * We use "hardwall" nomenclature throughout for historical reasons.
 * The lock here controls access to the list data structure as well as
 * to the items on the list.
 */
struct hardwall_type {
	int index;
	int is_xdn;
	int is_idn;
	int disabled;
	const char *name;
	struct list_head list;
	spinlock_t lock;
	struct proc_dir_entry *proc_dir;
};

enum hardwall_index {
	HARDWALL_UDN = 0,
#ifndef __tilepro__
	HARDWALL_IDN = 1,
	HARDWALL_IPI = 2,
#endif
	_HARDWALL_TYPES
};

static struct hardwall_type hardwall_types[] = {
	{  /* user-space access to UDN */
		0,
		1,
		0,
		0,
		"udn",
		LIST_HEAD_INIT(hardwall_types[HARDWALL_UDN].list),
		__SPIN_LOCK_INITIALIZER(hardwall_types[HARDWALL_UDN].lock),
		NULL
	},
#ifndef __tilepro__
	{  /* user-space access to IDN */
		1,
		1,
		1,
		1,  /* disabled pending hypervisor support */
		"idn",
		LIST_HEAD_INIT(hardwall_types[HARDWALL_IDN].list),
		__SPIN_LOCK_INITIALIZER(hardwall_types[HARDWALL_IDN].lock),
		NULL
	},
	{  /* access to user-space IPI */
		2,
		0,
		0,
		0,
		"ipi",
		LIST_HEAD_INIT(hardwall_types[HARDWALL_IPI].list),
		__SPIN_LOCK_INITIALIZER(hardwall_types[HARDWALL_IPI].lock),
		NULL
	},
#endif
};

/*
 * This data structure tracks the cpu data, etc., associated
 * one-to-one with a "struct file *" from opening a hardwall device file.
 * Note that the file's private data points back to this structure.
 */
struct hardwall_info {
	struct list_head list;             /* for hardwall_types.list */
	struct list_head task_head;        /* head of tasks in this hardwall */
	struct hardwall_type *type;        /* type of this resource */
	struct cpumask cpumask;            /* cpus reserved */
	int id;                            /* integer id for this hardwall */
	int teardown_in_progress;          /* are we tearing this one down? */

	/* Remaining fields only valid for user-network resources. */
	int ulhc_x;                        /* upper left hand corner x coord */
	int ulhc_y;                        /* upper left hand corner y coord */
	int width;                         /* rectangle width */
	int height;                        /* rectangle height */
#if CHIP_HAS_REV1_XDN()
	atomic_t xdn_pending_count;        /* cores in phase 1 of drain */
#endif
};


/* /proc/tile/hardwall */
static struct proc_dir_entry *hardwall_proc_dir;

/* Functions to manage files in /proc/tile/hardwall. */
static void hardwall_add_proc(struct hardwall_info *);
static void hardwall_remove_proc(struct hardwall_info *);

/* Allow disabling UDN access. */
static int __init noudn(char *str)
{
	pr_info("User-space UDN access is disabled\n");
	hardwall_types[HARDWALL_UDN].disabled = 1;
	return 0;
}
early_param("noudn", noudn);

#ifndef __tilepro__
/* Allow disabling IDN access. */
static int __init noidn(char *str)
{
	pr_info("User-space IDN access is disabled\n");
	hardwall_types[HARDWALL_IDN].disabled = 1;
	return 0;
}
early_param("noidn", noidn);

/* Allow disabling IPI access. */
static int __init noipi(char *str)
{
	pr_info("User-space IPI access is disabled\n");
	hardwall_types[HARDWALL_IPI].disabled = 1;
	return 0;
}
early_param("noipi", noipi);
#endif


/*
 * Low-level primitives for UDN/IDN
 */

#ifdef __tilepro__
#define mtspr_XDN(hwt, name, val) \
	do { (void)(hwt); __insn_mtspr(SPR_UDN_##name, (val)); } while (0)
#define mtspr_MPL_XDN(hwt, name, val) \
	do { (void)(hwt); __insn_mtspr(SPR_MPL_UDN_##name, (val)); } while (0)
#define mfspr_XDN(hwt, name) \
	((void)(hwt), __insn_mfspr(SPR_UDN_##name))
#else
#define mtspr_XDN(hwt, name, val)					\
	do {								\
		if ((hwt)->is_idn)					\
			__insn_mtspr(SPR_IDN_##name, (val));		\
		else							\
			__insn_mtspr(SPR_UDN_##name, (val));		\
	} while (0)
#define mtspr_MPL_XDN(hwt, name, val)					\
	do {								\
		if ((hwt)->is_idn)					\
			__insn_mtspr(SPR_MPL_IDN_##name, (val));	\
		else							\
			__insn_mtspr(SPR_MPL_UDN_##name, (val));	\
	} while (0)
#define mfspr_XDN(hwt, name) \
  ((hwt)->is_idn ? __insn_mfspr(SPR_IDN_##name) : __insn_mfspr(SPR_UDN_##name))
#endif

/* Set a CPU bit if the CPU is online. */
#define cpu_online_set(cpu, dst) do { \
	if (cpu_online(cpu))          \
		cpumask_set_cpu(cpu, dst);    \
} while (0)


/* Does the given rectangle contain the given x,y coordinate? */
static int contains(struct hardwall_info *r, int x, int y)
{
	return (x >= r->ulhc_x && x < r->ulhc_x + r->width) &&
		(y >= r->ulhc_y && y < r->ulhc_y + r->height);
}

/* Compute the rectangle parameters and validate the cpumask. */
static int check_rectangle(struct hardwall_info *r, struct cpumask *mask)
{
	int x, y, cpu, ulhc, lrhc;

	/* The first cpu is the ULHC, the last the LRHC. */
	ulhc = find_first_bit(cpumask_bits(mask), nr_cpumask_bits);
	lrhc = find_last_bit(cpumask_bits(mask), nr_cpumask_bits);

	/* Compute the rectangle attributes from the cpus. */
	r->ulhc_x = cpu_x(ulhc);
	r->ulhc_y = cpu_y(ulhc);
	r->width = cpu_x(lrhc) - r->ulhc_x + 1;
	r->height = cpu_y(lrhc) - r->ulhc_y + 1;

	/* Width and height must be positive */
	if (r->width <= 0 || r->height <= 0)
		return -EINVAL;

	/* Confirm that the cpumask is exactly the rectangle. */
	for (y = 0, cpu = 0; y < smp_height; ++y)
		for (x = 0; x < smp_width; ++x, ++cpu)
			if (cpumask_test_cpu(cpu, mask) != contains(r, x, y))
				return -EINVAL;

	/*
	 * Note that offline cpus can't be drained when this user network
	 * rectangle eventually closes.  We used to detect this
	 * situation and print a warning, but it annoyed users and
	 * they ignored it anyway, so now we just return without a
	 * warning.
	 */
	return 0;
}

/*
 * Hardware management of hardwall setup, teardown, trapping,
 * and enabling/disabling PL0 access to the networks.
 */

/* Bit field values to mask together for writes to SPR_XDN_DIRECTION_PROTECT */
enum direction_protect {
	N_PROTECT = (1 << 0),
	E_PROTECT = (1 << 1),
	S_PROTECT = (1 << 2),
	W_PROTECT = (1 << 3),
	C_PROTECT = (1 << 4),
};

static inline int xdn_which_interrupt(struct hardwall_type *hwt)
{
#ifndef __tilepro__
	if (hwt->is_idn)
		return INT_IDN_FIREWALL;
#endif
	return INT_UDN_FIREWALL;
}

static void enable_firewall_interrupts(struct hardwall_type *hwt)
{
	arch_local_irq_unmask_now(xdn_which_interrupt(hwt));
}

static void disable_firewall_interrupts(struct hardwall_type *hwt)
{
	arch_local_irq_mask_now(xdn_which_interrupt(hwt));
}

/* Set up hardwall on this cpu based on the passed hardwall_info. */
static void hardwall_setup_func(void *info)
{
	struct hardwall_info *r = info;
	struct hardwall_type *hwt = r->type;

	int cpu = smp_processor_id();
	int x = cpu % smp_width;
	int y = cpu / smp_width;
	int bits = 0;
	if (x == r->ulhc_x)
		bits |= W_PROTECT;
	if (x == r->ulhc_x + r->width - 1)
		bits |= E_PROTECT;
	if (y == r->ulhc_y)
		bits |= N_PROTECT;
	if (y == r->ulhc_y + r->height - 1)
		bits |= S_PROTECT;
	BUG_ON(bits == 0);
	mtspr_XDN(hwt, DIRECTION_PROTECT, bits);
	enable_firewall_interrupts(hwt);
}

/* Set up all cpus on edge of rectangle to enable/disable hardwall SPRs. */
static void hardwall_protect_rectangle(struct hardwall_info *r)
{
	int x, y, cpu, delta;
	struct cpumask rect_cpus;

	cpumask_clear(&rect_cpus);

	/* First include the top and bottom edges */
	cpu = r->ulhc_y * smp_width + r->ulhc_x;
	delta = (r->height - 1) * smp_width;
	for (x = 0; x < r->width; ++x, ++cpu) {
		cpu_online_set(cpu, &rect_cpus);
		cpu_online_set(cpu + delta, &rect_cpus);
	}

	/* Then the left and right edges */
	cpu -= r->width;
	delta = r->width - 1;
	for (y = 0; y < r->height; ++y, cpu += smp_width) {
		cpu_online_set(cpu, &rect_cpus);
		cpu_online_set(cpu + delta, &rect_cpus);
	}

	/* Then tell all the cpus to set up their protection SPR */
	on_each_cpu_mask(&rect_cpus, hardwall_setup_func, r, 1);
}

void __kprobes do_hardwall_trap(struct pt_regs* regs, int fault_num)
{
	struct hardwall_info *rect;
	struct hardwall_type *hwt;
	struct task_struct *p;
	struct siginfo info;
	int cpu = smp_processor_id();
	int found_processes;
	unsigned long flags;
	struct pt_regs *old_regs = set_irq_regs(regs);

	irq_enter();

	/* Figure out which network trapped. */
	switch (fault_num) {
#ifndef __tilepro__
	case INT_IDN_FIREWALL:
		hwt = &hardwall_types[HARDWALL_IDN];
		break;
#endif
	case INT_UDN_FIREWALL:
		hwt = &hardwall_types[HARDWALL_UDN];
		break;
	default:
		BUG();
	}
	BUG_ON(hwt->disabled);

	/* This tile trapped a network access; find the rectangle. */
	spin_lock_irqsave(&hwt->lock, flags);
	list_for_each_entry(rect, &hwt->list, list) {
		if (cpumask_test_cpu(cpu, &rect->cpumask))
			break;
	}

	/*
	 * It shouldn't be possible not to find this cpu on the
	 * rectangle list, since only cpus in rectangles get hardwalled.
	 * The hardwall is only removed after the user network is drained.
	 */
	BUG_ON(&rect->list == &hwt->list);

	/*
	 * If we already started teardown on this hardwall, don't worry;
	 * the abort signal has been sent and we are just waiting for things
	 * to quiesce.
	 */
	if (rect->teardown_in_progress) {
		pr_notice("cpu %d: detected %s hardwall violation %#lx"
		       " while teardown already in progress\n",
			  cpu, hwt->name,
			  (long)mfspr_XDN(hwt, DIRECTION_PROTECT));
		goto done;
	}

	/*
	 * Kill off any process that is activated in this rectangle.
	 * We bypass security to deliver the signal, since it must be
	 * one of the activated processes that generated the user network
	 * message that caused this trap, and all the activated
	 * processes shared a single open file so are pretty tightly
	 * bound together from a security point of view to begin with.
	 */
	rect->teardown_in_progress = 1;
	wmb(); /* Ensure visibility of rectangle before notifying processes. */
	pr_notice("cpu %d: detected %s hardwall violation %#lx...\n",
		  cpu, hwt->name, (long)mfspr_XDN(hwt, DIRECTION_PROTECT));
	info.si_signo = SIGILL;
	info.si_errno = 0;
	info.si_code = ILL_HARDWALL;
	found_processes = 0;
	list_for_each_entry(p, &rect->task_head,
			    thread.hardwall[hwt->index].list) {
		BUG_ON(p->thread.hardwall[hwt->index].info != rect);
		if (!(p->flags & PF_EXITING)) {
			found_processes = 1;
			pr_notice("hardwall: killing %d\n", p->pid);
			do_send_sig_info(info.si_signo, &info, p, false);
		}
	}
	if (!found_processes)
		pr_notice("hardwall: no associated processes!\n");

 done:
	spin_unlock_irqrestore(&hwt->lock, flags);

	/*
	 * We have to disable firewall interrupts now, or else when we
	 * return from this handler, we will simply re-interrupt back to
	 * it.  However, we can't clear the protection bits, since we
	 * haven't yet drained the network, and that would allow packets
	 * to cross out of the hardwall region.
	 */
	disable_firewall_interrupts(hwt);

	irq_exit();
	set_irq_regs(old_regs);
}

/* Allow access from user space to the user network. */
void grant_hardwall_mpls(struct hardwall_type *hwt)
{
#ifndef __tilepro__
	if (!hwt->is_xdn) {
		__insn_mtspr(SPR_MPL_IPI_0_SET_0, 1);
		return;
	}
#endif
	mtspr_MPL_XDN(hwt, ACCESS_SET_0, 1);
	mtspr_MPL_XDN(hwt, AVAIL_SET_0, 1);
	mtspr_MPL_XDN(hwt, COMPLETE_SET_0, 1);
	mtspr_MPL_XDN(hwt, TIMER_SET_0, 1);
#if !CHIP_HAS_REV1_XDN()
	mtspr_MPL_XDN(hwt, REFILL_SET_0, 1);
	mtspr_MPL_XDN(hwt, CA_SET_0, 1);
#endif
}

/* Deny access from user space to the user network. */
void restrict_hardwall_mpls(struct hardwall_type *hwt)
{
#ifndef __tilepro__
	if (!hwt->is_xdn) {
		__insn_mtspr(SPR_MPL_IPI_0_SET_1, 1);
		return;
	}
#endif
	mtspr_MPL_XDN(hwt, ACCESS_SET_1, 1);
	mtspr_MPL_XDN(hwt, AVAIL_SET_1, 1);
	mtspr_MPL_XDN(hwt, COMPLETE_SET_1, 1);
	mtspr_MPL_XDN(hwt, TIMER_SET_1, 1);
#if !CHIP_HAS_REV1_XDN()
	mtspr_MPL_XDN(hwt, REFILL_SET_1, 1);
	mtspr_MPL_XDN(hwt, CA_SET_1, 1);
#endif
}

/* Restrict or deny as necessary for the task we're switching to. */
void hardwall_switch_tasks(struct task_struct *prev,
			   struct task_struct *next)
{
	int i;
	for (i = 0; i < HARDWALL_TYPES; ++i) {
		if (prev->thread.hardwall[i].info != NULL) {
			if (next->thread.hardwall[i].info == NULL)
				restrict_hardwall_mpls(&hardwall_types[i]);
		} else if (next->thread.hardwall[i].info != NULL) {
			grant_hardwall_mpls(&hardwall_types[i]);
		}
	}
}

/* Does this task have the right to IPI the given cpu? */
int hardwall_ipi_valid(int cpu)
{
#ifdef __tilegx__
	struct hardwall_info *info =
		current->thread.hardwall[HARDWALL_IPI].info;
	return info && cpumask_test_cpu(cpu, &info->cpumask);
#else
	return 0;
#endif
}

/*
 * Code to create, activate, deactivate, and destroy hardwall resources.
 */

/* Create a hardwall for the given resource */
static struct hardwall_info *hardwall_create(struct hardwall_type *hwt,
					     size_t size,
					     const unsigned char __user *bits)
{
	struct hardwall_info *iter, *info;
	struct cpumask mask;
	unsigned long flags;
	int rc;

	/* Reject crazy sizes out of hand, a la sys_mbind(). */
	if (size > PAGE_SIZE)
		return ERR_PTR(-EINVAL);

	/* Copy whatever fits into a cpumask. */
	if (copy_from_user(&mask, bits, min(sizeof(struct cpumask), size)))
		return ERR_PTR(-EFAULT);

	/*
	 * If the size was short, clear the rest of the mask;
	 * otherwise validate that the rest of the user mask was zero
	 * (we don't try hard to be efficient when validating huge masks).
	 */
	if (size < sizeof(struct cpumask)) {
		memset((char *)&mask + size, 0, sizeof(struct cpumask) - size);
	} else if (size > sizeof(struct cpumask)) {
		size_t i;
		for (i = sizeof(struct cpumask); i < size; ++i) {
			char c;
			if (get_user(c, &bits[i]))
				return ERR_PTR(-EFAULT);
			if (c)
				return ERR_PTR(-EINVAL);
		}
	}

	/* Allocate a new hardwall_info optimistically. */
	info = kmalloc(sizeof(struct hardwall_info),
			GFP_KERNEL | __GFP_ZERO);
	if (info == NULL)
		return ERR_PTR(-ENOMEM);
	INIT_LIST_HEAD(&info->task_head);
	info->type = hwt;

	/* Compute the rectangle size and validate that it's plausible. */
	cpumask_copy(&info->cpumask, &mask);
	info->id = find_first_bit(cpumask_bits(&mask), nr_cpumask_bits);
	if (hwt->is_xdn) {
		rc = check_rectangle(info, &mask);
		if (rc != 0) {
			kfree(info);
			return ERR_PTR(rc);
		}
	}

	/* Confirm it doesn't overlap and add it to the list. */
	spin_lock_irqsave(&hwt->lock, flags);
	list_for_each_entry(iter, &hwt->list, list) {
		if (cpumask_intersects(&iter->cpumask, &info->cpumask)) {
			spin_unlock_irqrestore(&hwt->lock, flags);
			kfree(info);
			return ERR_PTR(-EBUSY);
		}
	}
	list_add_tail(&info->list, &hwt->list);
	spin_unlock_irqrestore(&hwt->lock, flags);

	/* Set up appropriate hardwalling on all affected cpus. */
	if (hwt->is_xdn)
		hardwall_protect_rectangle(info);

	/* Create a /proc/tile/hardwall entry. */
	hardwall_add_proc(info);

	return info;
}

/* Activate a given hardwall on this cpu for this process. */
static int hardwall_activate(struct hardwall_info *info)
{
	int cpu;
	unsigned long flags;
	struct task_struct *p = current;
	struct thread_struct *ts = &p->thread;
	struct hardwall_type *hwt;

	/* Require a hardwall. */
	if (info == NULL)
		return -ENODATA;

	/* Not allowed to activate a hardwall that is being torn down. */
	if (info->teardown_in_progress)
		return -EINVAL;

	/*
	 * Get our affinity; if we're not bound to this tile uniquely,
	 * we can't access the network registers.
	 */
	if (cpumask_weight(&p->cpus_allowed) != 1)
		return -EPERM;

	/* Make sure we are bound to a cpu assigned to this resource. */
	cpu = smp_processor_id();
	BUG_ON(cpumask_first(&p->cpus_allowed) != cpu);
	if (!cpumask_test_cpu(cpu, &info->cpumask))
		return -EINVAL;

	/* If we are already bound to this hardwall, it's a no-op. */
	hwt = info->type;
	if (ts->hardwall[hwt->index].info) {
		BUG_ON(ts->hardwall[hwt->index].info != info);
		return 0;
	}

	/* Success!  This process gets to use the resource on this cpu. */
	ts->hardwall[hwt->index].info = info;
	spin_lock_irqsave(&hwt->lock, flags);
	list_add(&ts->hardwall[hwt->index].list, &info->task_head);
	spin_unlock_irqrestore(&hwt->lock, flags);
	grant_hardwall_mpls(hwt);
	printk(KERN_DEBUG "Pid %d (%s) activated for %s hardwall: cpu %d\n",
	       p->pid, p->comm, hwt->name, cpu);
	return 0;
}

/*
 * Deactivate a task's hardwall.  Must hold lock for hardwall_type.
 * This method may be called from free_task(), so we don't want to
 * rely on too many fields of struct task_struct still being valid.
 * We assume the cpus_allowed, pid, and comm fields are still valid.
 */
static void _hardwall_deactivate(struct hardwall_type *hwt,
				 struct task_struct *task)
{
	struct thread_struct *ts = &task->thread;

	if (cpumask_weight(&task->cpus_allowed) != 1) {
		pr_err("pid %d (%s) releasing %s hardwall with"
		       " an affinity mask containing %d cpus!\n",
		       task->pid, task->comm, hwt->name,
		       cpumask_weight(&task->cpus_allowed));
		BUG();
	}

	BUG_ON(ts->hardwall[hwt->index].info == NULL);
	ts->hardwall[hwt->index].info = NULL;
	list_del(&ts->hardwall[hwt->index].list);
	if (task == current)
		restrict_hardwall_mpls(hwt);
}

/* Deactivate a task's hardwall. */
static int hardwall_deactivate(struct hardwall_type *hwt,
			       struct task_struct *task)
{
	unsigned long flags;
	int activated;

	spin_lock_irqsave(&hwt->lock, flags);
	activated = (task->thread.hardwall[hwt->index].info != NULL);
	if (activated)
		_hardwall_deactivate(hwt, task);
	spin_unlock_irqrestore(&hwt->lock, flags);

	if (!activated)
		return -EINVAL;

	printk(KERN_DEBUG "Pid %d (%s) deactivated for %s hardwall: cpu %d\n",
	       task->pid, task->comm, hwt->name, smp_processor_id());
	return 0;
}

void hardwall_deactivate_all(struct task_struct *task)
{
	int i;
	for (i = 0; i < HARDWALL_TYPES; ++i)
		if (task->thread.hardwall[i].info)
			hardwall_deactivate(&hardwall_types[i], task);
}

/* Stop the switch before draining the network. */
static void stop_xdn_switch(void *arg)
{
#if !CHIP_HAS_REV1_XDN()
	/* Freeze the switch and the demux. */
	__insn_mtspr(SPR_UDN_SP_FREEZE,
		     SPR_UDN_SP_FREEZE__SP_FRZ_MASK |
		     SPR_UDN_SP_FREEZE__DEMUX_FRZ_MASK |
		     SPR_UDN_SP_FREEZE__NON_DEST_EXT_MASK);
#else
	/*
	 * Drop all packets bound for the core or off the edge.
	 * We rely on the normal hardwall protection setup code
	 * to have set the low four bits to trigger firewall interrupts,
	 * and shift those bits up to trigger "drop on send" semantics,
	 * plus adding "drop on send to core" for all switches.
	 * In practice it seems the switches latch the DIRECTION_PROTECT
	 * SPR so they won't start dropping if they're already
	 * delivering the last message to the core, but it doesn't
	 * hurt to enable it here.
	 */
	struct hardwall_type *hwt = arg;
	unsigned long protect = mfspr_XDN(hwt, DIRECTION_PROTECT);
	mtspr_XDN(hwt, DIRECTION_PROTECT, (protect | C_PROTECT) << 5);
#endif
}

static void empty_xdn_demuxes(struct hardwall_type *hwt)
{
#ifndef __tilepro__
	if (hwt->is_idn) {
		while (__insn_mfspr(SPR_IDN_DATA_AVAIL) & (1 << 0))
			(void) __tile_idn0_receive();
		while (__insn_mfspr(SPR_IDN_DATA_AVAIL) & (1 << 1))
			(void) __tile_idn1_receive();
		return;
	}
#endif
	while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 0))
		(void) __tile_udn0_receive();
	while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 1))
		(void) __tile_udn1_receive();
	while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 2))
		(void) __tile_udn2_receive();
	while (__insn_mfspr(SPR_UDN_DATA_AVAIL) & (1 << 3))
		(void) __tile_udn3_receive();
}

/* Drain all the state from a stopped switch. */
static void drain_xdn_switch(void *arg)
{
	struct hardwall_info *info = arg;
	struct hardwall_type *hwt = info->type;

#if CHIP_HAS_REV1_XDN()
	/*
	 * The switches have been configured to drop any messages
	 * destined for cores (or off the edge of the rectangle).
	 * But the current message may continue to be delivered,
	 * so we wait until all the cores have finished any pending
	 * messages before we stop draining.
	 */
	int pending = mfspr_XDN(hwt, PENDING);
	while (pending--) {
		empty_xdn_demuxes(hwt);
		if (hwt->is_idn)
			__tile_idn_send(0);
		else
			__tile_udn_send(0);
	}
	atomic_dec(&info->xdn_pending_count);
	while (atomic_read(&info->xdn_pending_count))
		empty_xdn_demuxes(hwt);
#else
	int i;
	int from_tile_words, ca_count;

	/* Empty out the 5 switch point fifos. */
	for (i = 0; i < 5; i++) {
		int words, j;
		__insn_mtspr(SPR_UDN_SP_FIFO_SEL, i);
		words = __insn_mfspr(SPR_UDN_SP_STATE) & 0xF;
		for (j = 0; j < words; j++)
			(void) __insn_mfspr(SPR_UDN_SP_FIFO_DATA);
		BUG_ON((__insn_mfspr(SPR_UDN_SP_STATE) & 0xF) != 0);
	}

	/* Dump out the 3 word fifo at top. */
	from_tile_words = (__insn_mfspr(SPR_UDN_DEMUX_STATUS) >> 10) & 0x3;
	for (i = 0; i < from_tile_words; i++)
		(void) __insn_mfspr(SPR_UDN_DEMUX_WRITE_FIFO);

	/* Empty out demuxes. */
	empty_xdn_demuxes(hwt);

	/* Empty out catch all. */
	ca_count = __insn_mfspr(SPR_UDN_DEMUX_CA_COUNT);
	for (i = 0; i < ca_count; i++)
		(void) __insn_mfspr(SPR_UDN_CA_DATA);
	BUG_ON(__insn_mfspr(SPR_UDN_DEMUX_CA_COUNT) != 0);

	/* Clear demux logic. */
	__insn_mtspr(SPR_UDN_DEMUX_CTL, 1);

	/*
	 * Write switch state; experimentation indicates that 0xc3000
	 * is an idle switch point.
	 */
	for (i = 0; i < 5; i++) {
		__insn_mtspr(SPR_UDN_SP_FIFO_SEL, i);
		__insn_mtspr(SPR_UDN_SP_STATE, 0xc3000);
	}
#endif
}

/* Reset random XDN state registers at boot up and during hardwall teardown. */
static void reset_xdn_network_state(struct hardwall_type *hwt)
{
	if (hwt->disabled)
		return;

	/* Clear out other random registers so we have a clean slate. */
	mtspr_XDN(hwt, DIRECTION_PROTECT, 0);
	mtspr_XDN(hwt, AVAIL_EN, 0);
	mtspr_XDN(hwt, DEADLOCK_TIMEOUT, 0);

#if !CHIP_HAS_REV1_XDN()
	/* Reset UDN coordinates to their standard value */
	{
		unsigned int cpu = smp_processor_id();
		unsigned int x = cpu % smp_width;
		unsigned int y = cpu / smp_width;
		__insn_mtspr(SPR_UDN_TILE_COORD, (x << 18) | (y << 7));
	}

	/* Set demux tags to predefined values and enable them. */
	__insn_mtspr(SPR_UDN_TAG_VALID, 0xf);
	__insn_mtspr(SPR_UDN_TAG_0, (1 << 0));
	__insn_mtspr(SPR_UDN_TAG_1, (1 << 1));
	__insn_mtspr(SPR_UDN_TAG_2, (1 << 2));
	__insn_mtspr(SPR_UDN_TAG_3, (1 << 3));

	/* Set other rev0 random registers to a clean state. */
	__insn_mtspr(SPR_UDN_REFILL_EN, 0);
	__insn_mtspr(SPR_UDN_DEMUX_QUEUE_SEL, 0);
	__insn_mtspr(SPR_UDN_SP_FIFO_SEL, 0);

	/* Start the switch and demux. */
	__insn_mtspr(SPR_UDN_SP_FREEZE, 0);
#endif
}

void reset_network_state(void)
{
	reset_xdn_network_state(&hardwall_types[HARDWALL_UDN]);
#ifndef __tilepro__
	reset_xdn_network_state(&hardwall_types[HARDWALL_IDN]);
#endif
}

/* Restart an XDN switch after draining. */
static void restart_xdn_switch(void *arg)
{
	struct hardwall_type *hwt = arg;

#if CHIP_HAS_REV1_XDN()
	/* One last drain step to avoid races with injection and draining. */
	empty_xdn_demuxes(hwt);
#endif

	reset_xdn_network_state(hwt);

	/* Disable firewall interrupts. */
	disable_firewall_interrupts(hwt);
}

/* Last reference to a hardwall is gone, so clear the network. */
static void hardwall_destroy(struct hardwall_info *info)
{
	struct task_struct *task;
	struct hardwall_type *hwt;
	unsigned long flags;

	/* Make sure this file actually represents a hardwall. */
	if (info == NULL)
		return;

	/*
	 * Deactivate any remaining tasks.  It's possible to race with
	 * some other thread that is exiting and hasn't yet called
	 * deactivate (when freeing its thread_info), so we carefully
	 * deactivate any remaining tasks before freeing the
	 * hardwall_info object itself.
	 */
	hwt = info->type;
	info->teardown_in_progress = 1;
	spin_lock_irqsave(&hwt->lock, flags);
	list_for_each_entry(task, &info->task_head,
			    thread.hardwall[hwt->index].list)
		_hardwall_deactivate(hwt, task);
	spin_unlock_irqrestore(&hwt->lock, flags);

	if (hwt->is_xdn) {
		/* Configure the switches for draining the user network. */
		printk(KERN_DEBUG
		       "Clearing %s hardwall rectangle %dx%d %d,%d\n",
		       hwt->name, info->width, info->height,
		       info->ulhc_x, info->ulhc_y);
		on_each_cpu_mask(&info->cpumask, stop_xdn_switch, hwt, 1);

		/* Drain the network. */
#if CHIP_HAS_REV1_XDN()
		atomic_set(&info->xdn_pending_count,
			   cpumask_weight(&info->cpumask));
		on_each_cpu_mask(&info->cpumask, drain_xdn_switch, info, 0);
#else
		on_each_cpu_mask(&info->cpumask, drain_xdn_switch, info, 1);
#endif

		/* Restart switch and disable firewall. */
		on_each_cpu_mask(&info->cpumask, restart_xdn_switch, hwt, 1);
	}

	/* Remove the /proc/tile/hardwall entry. */
	hardwall_remove_proc(info);

	/* Now free the hardwall from the list. */
	spin_lock_irqsave(&hwt->lock, flags);
	BUG_ON(!list_empty(&info->task_head));
	list_del(&info->list);
	spin_unlock_irqrestore(&hwt->lock, flags);
	kfree(info);
}


static int hardwall_proc_show(struct seq_file *sf, void *v)
{
	struct hardwall_info *info = sf->private;
	char buf[256];

	int rc = cpulist_scnprintf(buf, sizeof(buf), &info->cpumask);
	buf[rc++] = '\n';
	seq_write(sf, buf, rc);
	return 0;
}

static int hardwall_proc_open(struct inode *inode,
			      struct file *file)
{
	return single_open(file, hardwall_proc_show, PDE_DATA(inode));
}

static const struct file_operations hardwall_proc_fops = {
	.open		= hardwall_proc_open,
	.read		= seq_read,
	.llseek		= seq_lseek,
	.release	= single_release,
};

static void hardwall_add_proc(struct hardwall_info *info)
{
	char buf[64];
	snprintf(buf, sizeof(buf), "%d", info->id);
	proc_create_data(buf, 0444, info->type->proc_dir,
			 &hardwall_proc_fops, info);
}

static void hardwall_remove_proc(struct hardwall_info *info)
{
	char buf[64];
	snprintf(buf, sizeof(buf), "%d", info->id);
	remove_proc_entry(buf, info->type->proc_dir);
}

int proc_pid_hardwall(struct task_struct *task, char *buffer)
{
	int i;
	int n = 0;
	for (i = 0; i < HARDWALL_TYPES; ++i) {
		struct hardwall_info *info = task->thread.hardwall[i].info;
		if (info)
			n += sprintf(&buffer[n], "%s: %d\n",
				     info->type->name, info->id);
	}
	return n;
}

void proc_tile_hardwall_init(struct proc_dir_entry *root)
{
	int i;
	for (i = 0; i < HARDWALL_TYPES; ++i) {
		struct hardwall_type *hwt = &hardwall_types[i];
		if (hwt->disabled)
			continue;
		if (hardwall_proc_dir == NULL)
			hardwall_proc_dir = proc_mkdir("hardwall", root);
		hwt->proc_dir = proc_mkdir(hwt->name, hardwall_proc_dir);
	}
}


/*
 * Character device support via ioctl/close.
 */

static long hardwall_ioctl(struct file *file, unsigned int a, unsigned long b)
{
	struct hardwall_info *info = file->private_data;
	int minor = iminor(file->f_mapping->host);
	struct hardwall_type* hwt;

	if (_IOC_TYPE(a) != HARDWALL_IOCTL_BASE)
		return -EINVAL;

	BUILD_BUG_ON(HARDWALL_TYPES != _HARDWALL_TYPES);
	BUILD_BUG_ON(HARDWALL_TYPES !=
		     sizeof(hardwall_types)/sizeof(hardwall_types[0]));

	if (minor < 0 || minor >= HARDWALL_TYPES)
		return -EINVAL;
	hwt = &hardwall_types[minor];
	WARN_ON(info && hwt != info->type);

	switch (_IOC_NR(a)) {
	case _HARDWALL_CREATE:
		if (hwt->disabled)
			return -ENOSYS;
		if (info != NULL)
			return -EALREADY;
		info = hardwall_create(hwt, _IOC_SIZE(a),
				       (const unsigned char __user *)b);
		if (IS_ERR(info))
			return PTR_ERR(info);
		file->private_data = info;
		return 0;

	case _HARDWALL_ACTIVATE:
		return hardwall_activate(info);

	case _HARDWALL_DEACTIVATE:
		if (current->thread.hardwall[hwt->index].info != info)
			return -EINVAL;
		return hardwall_deactivate(hwt, current);

	case _HARDWALL_GET_ID:
		return info ? info->id : -EINVAL;

	default:
		return -EINVAL;
	}
}

#ifdef CONFIG_COMPAT
static long hardwall_compat_ioctl(struct file *file,
				  unsigned int a, unsigned long b)
{
	/* Sign-extend the argument so it can be used as a pointer. */
	return hardwall_ioctl(file, a, (unsigned long)compat_ptr(b));
}
#endif

/* The user process closed the file; revoke access to user networks. */
static int hardwall_flush(struct file *file, fl_owner_t owner)
{
	struct hardwall_info *info = file->private_data;
	struct task_struct *task, *tmp;
	unsigned long flags;

	if (info) {
		/*
		 * NOTE: if multiple threads are activated on this hardwall
		 * file, the other threads will continue having access to the
		 * user network until they are context-switched out and back
		 * in again.
		 *
		 * NOTE: A NULL files pointer means the task is being torn
		 * down, so in that case we also deactivate it.
		 */
		struct hardwall_type *hwt = info->type;
		spin_lock_irqsave(&hwt->lock, flags);
		list_for_each_entry_safe(task, tmp, &info->task_head,
					 thread.hardwall[hwt->index].list) {
			if (task->files == owner || task->files == NULL)
				_hardwall_deactivate(hwt, task);
		}
		spin_unlock_irqrestore(&hwt->lock, flags);
	}

	return 0;
}

/* This hardwall is gone, so destroy it. */
static int hardwall_release(struct inode *inode, struct file *file)
{
	hardwall_destroy(file->private_data);
	return 0;
}

static const struct file_operations dev_hardwall_fops = {
	.open           = nonseekable_open,
	.unlocked_ioctl = hardwall_ioctl,
#ifdef CONFIG_COMPAT
	.compat_ioctl   = hardwall_compat_ioctl,
#endif
	.flush          = hardwall_flush,
	.release        = hardwall_release,
};

static struct cdev hardwall_dev;

static int __init dev_hardwall_init(void)
{
	int rc;
	dev_t dev;

	rc = alloc_chrdev_region(&dev, 0, HARDWALL_TYPES, "hardwall");
	if (rc < 0)
		return rc;
	cdev_init(&hardwall_dev, &dev_hardwall_fops);
	rc = cdev_add(&hardwall_dev, dev, HARDWALL_TYPES);
	if (rc < 0)
		return rc;

	return 0;
}
late_initcall(dev_hardwall_init);
