20 #include <linux/sched.h>
26 #include <asm/hardwall.h>
27 #include <asm/traps.h>
28 #include <asm/siginfo.h>
29 #include <asm/irq_regs.h>
32 #include <arch/spr_def.h>
114 #if CHIP_HAS_REV1_XDN()
130 pr_info(
"User-space UDN access is disabled\n");
140 pr_info(
"User-space IDN access is disabled\n");
149 pr_info(
"User-space IPI access is disabled\n");
162 #define mtspr_XDN(hwt, name, val) \
163 do { (void)(hwt); __insn_mtspr(SPR_UDN_##name, (val)); } while (0)
164 #define mtspr_MPL_XDN(hwt, name, val) \
165 do { (void)(hwt); __insn_mtspr(SPR_MPL_UDN_##name, (val)); } while (0)
166 #define mfspr_XDN(hwt, name) \
167 ((void)(hwt), __insn_mfspr(SPR_UDN_##name))
169 #define mtspr_XDN(hwt, name, val) \
172 __insn_mtspr(SPR_IDN_##name, (val)); \
174 __insn_mtspr(SPR_UDN_##name, (val)); \
176 #define mtspr_MPL_XDN(hwt, name, val) \
179 __insn_mtspr(SPR_MPL_IDN_##name, (val)); \
181 __insn_mtspr(SPR_MPL_UDN_##name, (val)); \
183 #define mfspr_XDN(hwt, name) \
184 ((hwt)->is_idn ? __insn_mfspr(SPR_IDN_##name) : __insn_mfspr(SPR_UDN_##name))
188 #define cpu_online_set(cpu, dst) do { \
189 if (cpu_online(cpu)) \
190 cpumask_set_cpu(cpu, dst); \
197 return (x >= r->
ulhc_x && x < r->ulhc_x + r->
width) &&
204 int x,
y,
cpu, ulhc, lrhc;
250 static inline int xdn_which_interrupt(
struct hardwall_type *hwt)
259 static void enable_firewall_interrupts(
struct hardwall_type *hwt)
264 static void disable_firewall_interrupts(
struct hardwall_type *hwt)
270 static void hardwall_setup_func(
void *
info)
289 enable_firewall_interrupts(hwt);
293 static void hardwall_protect_rectangle(
struct hardwall_info *r)
298 cpumask_clear(&rect_cpus);
302 delta = (r->
height - 1) * smp_width;
310 delta = r->
width - 1;
329 struct pt_regs *old_regs = set_irq_regs(regs);
368 pr_notice(
"cpu %d: detected %s hardwall violation %#lx"
369 " while teardown already in progress\n",
371 (
long)
mfspr_XDN(hwt, DIRECTION_PROTECT));
385 pr_notice(
"cpu %d: detected %s hardwall violation %#lx...\n",
400 if (!found_processes)
401 pr_notice(
"hardwall: no associated processes!\n");
404 spin_unlock_irqrestore(&hwt->
lock, flags);
413 disable_firewall_interrupts(hwt);
416 set_irq_regs(old_regs);
432 #if !CHIP_HAS_REV1_XDN()
451 #if !CHIP_HAS_REV1_XDN()
462 for (i = 0; i < HARDWALL_TYPES; ++
i) {
466 }
else if (next->
thread.hardwall[i].info !=
NULL) {
491 const unsigned char __user *bits)
511 if (size <
sizeof(
struct cpumask)) {
512 memset((
char *)&mask + size, 0,
sizeof(
struct cpumask) - size);
513 }
else if (size >
sizeof(
struct cpumask)) {
533 cpumask_copy(&info->
cpumask, &mask);
536 rc = check_rectangle(info, &mask);
547 spin_unlock_irqrestore(&hwt->
lock, flags);
549 return ERR_PTR(-
EBUSY);
553 spin_unlock_irqrestore(&hwt->
lock, flags);
557 hardwall_protect_rectangle(info);
560 hardwall_add_proc(info);
597 if (ts->hardwall[hwt->
index].info) {
606 spin_unlock_irqrestore(&hwt->
lock, flags);
625 pr_err(
"pid %d (%s) releasing %s hardwall with"
626 " an affinity mask containing %d cpus!\n",
649 _hardwall_deactivate(hwt, task);
650 spin_unlock_irqrestore(&hwt->
lock, flags);
663 for (i = 0; i < HARDWALL_TYPES; ++
i)
664 if (task->
thread.hardwall[i].info)
665 hardwall_deactivate(&hardwall_types[i], task);
669 static void stop_xdn_switch(
void *
arg)
671 #if !CHIP_HAS_REV1_XDN()
700 (
void) __tile_idn0_receive();
702 (
void) __tile_idn1_receive();
707 (
void) __tile_udn0_receive();
709 (
void) __tile_udn1_receive();
711 (
void) __tile_udn2_receive();
713 (
void) __tile_udn3_receive();
717 static void drain_xdn_switch(
void *arg)
722 #if CHIP_HAS_REV1_XDN()
732 empty_xdn_demuxes(hwt);
740 empty_xdn_demuxes(hwt);
743 int from_tile_words, ca_count;
746 for (i = 0; i < 5; i++) {
750 for (j = 0; j < words; j++)
757 for (i = 0; i < from_tile_words; i++)
761 empty_xdn_demuxes(hwt);
765 for (i = 0; i < ca_count; i++)
776 for (i = 0; i < 5; i++) {
784 static void reset_xdn_network_state(
struct hardwall_type *hwt)
794 #if !CHIP_HAS_REV1_XDN()
829 static void restart_xdn_switch(
void *arg)
833 #if CHIP_HAS_REV1_XDN()
835 empty_xdn_demuxes(hwt);
838 reset_xdn_network_state(hwt);
841 disable_firewall_interrupts(hwt);
867 _hardwall_deactivate(hwt, task);
868 spin_unlock_irqrestore(&hwt->
lock, flags);
873 "Clearing %s hardwall rectangle %dx%d %d,%d\n",
879 #if CHIP_HAS_REV1_XDN()
881 cpumask_weight(&info->
cpumask));
892 hardwall_remove_proc(info);
898 spin_unlock_irqrestore(&hwt->lock, flags);
903 static int hardwall_proc_show(
struct seq_file *
sf,
void *
v)
908 int rc = cpulist_scnprintf(buf,
sizeof(buf), &info->
cpumask);
914 static int hardwall_proc_open(
struct inode *
inode,
921 .open = hardwall_proc_open,
932 &hardwall_proc_fops, info);
946 for (i = 0; i < HARDWALL_TYPES; ++
i) {
949 n +=
sprintf(&buffer[n],
"%s: %d\n",
950 info->
type->name, info->
id);
958 for (i = 0; i < HARDWALL_TYPES; ++
i) {
962 if (hardwall_proc_dir ==
NULL)
963 hardwall_proc_dir =
proc_mkdir(
"hardwall", root);
973 static long hardwall_ioctl(
struct file *file,
unsigned int a,
unsigned long b)
984 sizeof(hardwall_types)/
sizeof(hardwall_types[0]));
986 if (minor < 0 || minor >= HARDWALL_TYPES)
988 hwt = &hardwall_types[minor];
997 info = hardwall_create(hwt,
_IOC_SIZE(a),
998 (
const unsigned char __user *)b);
1000 return PTR_ERR(info);
1005 return hardwall_activate(info);
1010 return hardwall_deactivate(hwt,
current);
1020 #ifdef CONFIG_COMPAT
1021 static long hardwall_compat_ioctl(
struct file *file,
1022 unsigned int a,
unsigned long b)
1025 return hardwall_ioctl(file, a, (
unsigned long)compat_ptr(b));
1034 unsigned long flags;
1051 _hardwall_deactivate(hwt, task);
1053 spin_unlock_irqrestore(&hwt->
lock, flags);
1060 static int hardwall_release(
struct inode *inode,
struct file *file)
1068 .unlocked_ioctl = hardwall_ioctl,
1069 #ifdef CONFIG_COMPAT
1070 .compat_ioctl = hardwall_compat_ioctl,
1072 .flush = hardwall_flush,
1073 .release = hardwall_release,
1076 static struct cdev hardwall_dev;
1078 static int __init dev_hardwall_init(
void)
1086 cdev_init(&hardwall_dev, &dev_hardwall_fops);
1087 rc =
cdev_add(&hardwall_dev, dev, HARDWALL_TYPES);