Esempio n. 1
0
void __init ps3_mm_vas_create(unsigned long* htab_size)
{
	int result;
	u64 start_address;
	u64 size;
	u64 access_right;
	u64 max_page_size;
	u64 flags;

	result = lv1_query_logical_partition_address_region_info(0,
		&start_address, &size, &access_right, &max_page_size,
		&flags);

	if (result) {
		DBG("%s:%d: lv1_query_logical_partition_address_region_info "
			"failed: %s\n", __func__, __LINE__,
			ps3_result(result));
		goto fail;
	}

	if (max_page_size < PAGE_SHIFT_16M) {
		DBG("%s:%d: bad max_page_size %llxh\n", __func__, __LINE__,
			max_page_size);
		goto fail;
	}

	BUILD_BUG_ON(CONFIG_PS3_HTAB_SIZE > HTAB_SIZE_MAX);
	BUILD_BUG_ON(CONFIG_PS3_HTAB_SIZE < HTAB_SIZE_MIN);

	result = lv1_construct_virtual_address_space(CONFIG_PS3_HTAB_SIZE,
			2, make_page_sizes(PAGE_SHIFT_16M, PAGE_SHIFT_64K),
			&map.vas_id, &map.htab_size);

	if (result) {
		DBG("%s:%d: lv1_construct_virtual_address_space failed: %s\n",
			__func__, __LINE__, ps3_result(result));
		goto fail;
	}

	result = lv1_select_virtual_address_space(map.vas_id);

	if (result) {
		DBG("%s:%d: lv1_select_virtual_address_space failed: %s\n",
			__func__, __LINE__, ps3_result(result));
		goto fail;
	}

	*htab_size = map.htab_size;

	debug_dump_map(&map);

	return;

fail:
	panic("ps3_mm_vas_create failed");
}
Esempio n. 2
0
u32 ps3_read_phys_ctr(u32 cpu, u32 phys_ctr)
{
	int result;
	u64 counter0415;
	u64 counter2637;

	if (phys_ctr >= NR_PHYS_CTRS) {
		dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__,
			__LINE__, phys_ctr);
		return 0;
	}

	result = lv1_set_lpm_counter(lpm_priv->lpm_id, 0, 0, 0, 0, &counter0415,
				     &counter2637);
	if (result) {
		dev_err(sbd_core(), "%s:%u: lv1_set_lpm_counter failed: "
			"phys_ctr %u, %s\n", __func__, __LINE__, phys_ctr,
			ps3_result(result));
		return 0;
	}

	switch (phys_ctr) {
	case 0:
		return counter0415 >> 32;
	case 1:
		return counter0415 & PS3_PM_COUNTER_MASK_LO;
	case 2:
		return counter2637 >> 32;
	case 3:
		return counter2637 & PS3_PM_COUNTER_MASK_LO;
	default:
		BUG();
	}
	return 0;
}
static int ps3_open_hv_device_sb(struct ps3_system_bus_device *dev)
{
	int result;

	BUG_ON(!dev->bus_id);
	mutex_lock(&usage_hack.mutex);

	if (ps3_is_device(dev, 1, 1)) {
		usage_hack.sb_11++;
		if (usage_hack.sb_11 > 1) {
			result = 0;
			goto done;
		}
	}

	if (ps3_is_device(dev, 1, 2)) {
		usage_hack.sb_12++;
		if (usage_hack.sb_12 > 1) {
			result = 0;
			goto done;
		}
	}

	result = lv1_open_device(dev->bus_id, dev->dev_id, 0);

	if (result) {
		pr_debug("%s:%d: lv1_open_device failed: %s\n", __func__,
			__LINE__, ps3_result(result));
			result = -EPERM;
	}

done:
	mutex_unlock(&usage_hack.mutex);
	return result;
}
Esempio n. 4
0
static int ps3_mm_region_create(struct mem_region *r, unsigned long size)
{
	int result;
	u64 muid;

	r->size = _ALIGN_DOWN(size, 1 << PAGE_SHIFT_16M);

	DBG("%s:%d requested  %lxh\n", __func__, __LINE__, size);
	DBG("%s:%d actual     %llxh\n", __func__, __LINE__, r->size);
	DBG("%s:%d difference %llxh (%lluMB)\n", __func__, __LINE__,
		size - r->size, (size - r->size) / 1024 / 1024);

	if (r->size == 0) {
		DBG("%s:%d: size == 0\n", __func__, __LINE__);
		result = -1;
		goto zero_region;
	}

	result = lv1_allocate_memory(r->size, PAGE_SHIFT_16M, 0,
		ALLOCATE_MEMORY_TRY_ALT_UNIT, &r->base, &muid);

	if (result || r->base < map.rm.size) {
		DBG("%s:%d: lv1_allocate_memory failed: %s\n",
			__func__, __LINE__, ps3_result(result));
		goto zero_region;
	}

	r->destroy = 1;
	r->offset = r->base - map.rm.size;
	return result;

zero_region:
	r->size = r->base = r->offset = 0;
	return result;
}
Esempio n. 5
0
int ps3_irq_plug_setup(enum ps3_cpu_binding cpu, unsigned long outlet,
	unsigned int *virq)
{
	int result;
	struct ps3_private *pd;

	result = ps3_virq_setup(cpu, outlet, virq);

	if (result) {
		pr_debug("%s:%d: ps3_virq_setup failed\n", __func__, __LINE__);
		goto fail_setup;
	}

	pd = irq_get_chip_data(*virq);

	/* Binds outlet to cpu + virq. */

	result = lv1_connect_irq_plug_ext(pd->ppe_id, pd->thread_id, *virq,
		outlet, 0);

	if (result) {
		pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n",
		__func__, __LINE__, ps3_result(result));
		result = -EPERM;
		goto fail_connect;
	}

	return result;

fail_connect:
	ps3_virq_destroy(*virq);
fail_setup:
	return result;
}
Esempio n. 6
0
File: spu.c Progetto: E-LLP/n900
static int __init enable_spu(struct spu *spu)
{
	int result;

	result = lv1_enable_logical_spe(spu_pdata(spu)->spe_id,
		spu_pdata(spu)->resource_id);

	if (result) {
		pr_debug("%s:%d: lv1_enable_logical_spe failed: %s\n",
			__func__, __LINE__, ps3_result(result));
		goto fail_enable;
	}

	result = setup_areas(spu);

	if (result)
		goto fail_areas;

	result = setup_interrupts(spu);

	if (result)
		goto fail_interrupts;

	return 0;

fail_interrupts:
	spu_unmap(spu);
fail_areas:
	lv1_disable_logical_spe(spu_pdata(spu)->spe_id, 0);
fail_enable:
	return result;
}
Esempio n. 7
0
int ps3_alloc_vuart_irq(void* virt_addr_bmp, unsigned int *virq)
{
	int result;
	unsigned long outlet;
	unsigned long lpar_addr;

	BUG_ON(!is_kernel_addr((unsigned long)virt_addr_bmp));

	lpar_addr = ps3_mm_phys_to_lpar(__pa(virt_addr_bmp));

	result = lv1_configure_virtual_uart_irq(lpar_addr, &outlet);

	if (result) {
		pr_debug("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n",
			__func__, __LINE__, ps3_result(result));
		return result;
	}

	*virq = irq_create_mapping(NULL, outlet);

	pr_debug("%s:%d: outlet %lu, virq %u\n", __func__, __LINE__,
		outlet, *virq);

	return 0;
}
Esempio n. 8
0
int ps3_sb_event_receive_port_setup(struct ps3_system_bus_device *dev,
	enum ps3_cpu_binding cpu, unsigned int *virq)
{
	/* this should go in system-bus.c */

	int result;

	result = ps3_event_receive_port_setup(cpu, virq);

	if (result)
		return result;

	result = lv1_connect_interrupt_event_receive_port(dev->bus_id,
		dev->dev_id, virq_to_hw(*virq), dev->interrupt_id);

	if (result) {
		pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port"
			" failed: %s\n", __func__, __LINE__,
			ps3_result(result));
		ps3_event_receive_port_destroy(*virq);
		*virq = NO_IRQ;
		return result;
	}

	pr_debug("%s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__,
		dev->interrupt_id, *virq);

	return 0;
}
Esempio n. 9
0
int ps3_connect_event_irq(const struct ps3_device_id *did,
	unsigned int interrupt_id, unsigned int *virq)
{
	int result;

	result = ps3_alloc_event_irq(virq);

	if (result)
		return result;

	result = lv1_connect_interrupt_event_receive_port(did->bus_id,
		did->dev_id, virq_to_hw(*virq), interrupt_id);

	if (result) {
		pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port"
			" failed: %s\n", __func__, __LINE__,
			ps3_result(result));
		ps3_free_event_irq(*virq);
		*virq = NO_IRQ;
		return result;
	}

	pr_debug("%s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__,
		interrupt_id, *virq);

	return 0;
}
Esempio n. 10
0
int ps3_sb_event_receive_port_destroy(struct ps3_system_bus_device *dev,
	unsigned int virq)
{
	/* this should go in system-bus.c */

	int result;

	pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__,
		dev->interrupt_id, virq);

	result = lv1_disconnect_interrupt_event_receive_port(dev->bus_id,
		dev->dev_id, virq_to_hw(virq), dev->interrupt_id);

	if (result)
		pr_debug("%s:%d: lv1_disconnect_interrupt_event_receive_port"
			" failed: %s\n", __func__, __LINE__,
			ps3_result(result));

	result = ps3_event_receive_port_destroy(virq);
	BUG_ON(result);

	/*
	 * ps3_event_receive_port_destroy() destroys the IRQ plug,
	 * so don't call ps3_irq_plug_destroy() here.
	 */

	result = ps3_virq_destroy(virq);
	BUG_ON(result);

	pr_debug(" <- %s:%d\n", __func__, __LINE__);
	return result;
}
Esempio n. 11
0
int ps3_sb_event_receive_port_destroy(struct ps3_system_bus_device *dev,
	unsigned int virq)
{
	/*                                */

	int result;

	DBG(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__,
		dev->interrupt_id, virq);

	result = lv1_disconnect_interrupt_event_receive_port(dev->bus_id,
		dev->dev_id, virq_to_hw(virq), dev->interrupt_id);

	if (result)
		FAIL("%s:%d: lv1_disconnect_interrupt_event_receive_port"
			" failed: %s\n", __func__, __LINE__,
			ps3_result(result));

	result = ps3_event_receive_port_destroy(virq);
	BUG_ON(result);

	/*
                                                           
                                              
  */

	result = ps3_virq_destroy(virq);
	BUG_ON(result);

	DBG(" <- %s:%d\n", __func__, __LINE__);
	return result;
}
Esempio n. 12
0
u32 ps3_read_pm(u32 cpu, enum pm_reg_name reg)
{
	int result = 0;
	u64 val = 0;

	switch (reg) {
	case pm_control:
		return lpm_priv->shadow.pm_control;
	case trace_address:
		return CBE_PM_TRACE_BUF_EMPTY;
	case pm_start_stop:
		return lpm_priv->shadow.pm_start_stop;
	case pm_interval:
		result = lv1_set_lpm_interval(lpm_priv->lpm_id, 0, 0, &val);
		if (result) {
			val = 0;
			dev_dbg(sbd_core(), "%s:%u: lv1 set_inteval failed: "
				"reg %u, %s\n", __func__, __LINE__, reg,
				ps3_result(result));
		}
		return (u32)val;
	case group_control:
		return lpm_priv->shadow.group_control;
	case debug_bus_control:
		return lpm_priv->shadow.debug_bus_control;
	case pm_status:
		result = lv1_get_lpm_interrupt_status(lpm_priv->lpm_id,
						      &val);
		if (result) {
			val = 0;
			dev_dbg(sbd_core(), "%s:%u: lv1 get_lpm_status failed: "
				"reg %u, %s\n", __func__, __LINE__, reg,
				ps3_result(result));
		}
		return (u32)val;
	case ext_tr_timer:
		return 0;
	default:
		dev_dbg(sbd_core(), "%s:%u: unknown reg: %d\n", __func__,
			__LINE__, reg);
		BUG();
		break;
	}

	return 0;
}
Esempio n. 13
0
static long ps3_hpte_insert(unsigned long hpte_group, unsigned long vpn,
	unsigned long pa, unsigned long rflags, unsigned long vflags,
	int psize, int apsize, int ssize)
{
	int result;
	u64 hpte_v, hpte_r;
	u64 inserted_index;
	u64 evicted_v, evicted_r;
	u64 hpte_v_array[4], hpte_rs;
	unsigned long flags;
	long ret = -1;

	/*
	 * lv1_insert_htab_entry() will search for victim
	 * entry in both primary and secondary pte group
	 */
	vflags &= ~HPTE_V_SECONDARY;

	hpte_v = hpte_encode_v(vpn, psize, apsize, ssize) | vflags | HPTE_V_VALID;
	hpte_r = hpte_encode_r(ps3_mm_phys_to_lpar(pa), psize, apsize) | rflags;

	spin_lock_irqsave(&ps3_htab_lock, flags);

	/* talk hvc to replace entries BOLTED == 0 */
	result = lv1_insert_htab_entry(PS3_LPAR_VAS_ID_CURRENT, hpte_group,
				       hpte_v, hpte_r,
				       HPTE_V_BOLTED, 0,
				       &inserted_index,
				       &evicted_v, &evicted_r);

	if (result) {
		/* all entries bolted !*/
		pr_info("%s:result=%s vpn=%lx pa=%lx ix=%lx v=%llx r=%llx\n",
			__func__, ps3_result(result), vpn, pa, hpte_group,
			hpte_v, hpte_r);
		BUG();
	}

	/*
	 * see if the entry is inserted into secondary pteg
	 */
	result = lv1_read_htab_entries(PS3_LPAR_VAS_ID_CURRENT,
				       inserted_index & ~0x3UL,
				       &hpte_v_array[0], &hpte_v_array[1],
				       &hpte_v_array[2], &hpte_v_array[3],
				       &hpte_rs);
	BUG_ON(result);

	if (hpte_v_array[inserted_index % 4] & HPTE_V_SECONDARY)
		ret = (inserted_index & 7) | (1 << 3);
	else
		ret = inserted_index & 7;

	spin_unlock_irqrestore(&ps3_htab_lock, flags);

	return ret;
}
Esempio n. 14
0
int ps3_alloc_irq(enum ps3_cpu_binding cpu, unsigned long outlet,
	unsigned int *virq)
{
	int result;
	struct ps3_private *pd;

	/* This defines the default interrupt distribution policy. */

	if (cpu == PS3_BINDING_CPU_ANY)
		cpu = 0;

	pd = &per_cpu(ps3_private, cpu);

	*virq = irq_create_mapping(NULL, outlet);

	if (*virq == NO_IRQ) {
		pr_debug("%s:%d: irq_create_mapping failed: outlet %lu\n",
			__func__, __LINE__, outlet);
		result = -ENOMEM;
		goto fail_create;
	}

	/* Binds outlet to cpu + virq. */

	result = lv1_connect_irq_plug_ext(pd->node, pd->cpu, *virq, outlet, 0);

	if (result) {
		pr_info("%s:%d: lv1_connect_irq_plug_ext failed: %s\n",
		__func__, __LINE__, ps3_result(result));
		result = -EPERM;
		goto fail_connect;
	}

	pr_debug("%s:%d: outlet %lu => cpu %u, virq %u\n", __func__, __LINE__,
		outlet, cpu, *virq);

	result = set_irq_chip_data(*virq, pd);

	if (result) {
		pr_debug("%s:%d: set_irq_chip_data failed\n",
			__func__, __LINE__);
		goto fail_set;
	}

	return result;

fail_set:
	lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, *virq);
fail_connect:
	irq_dispose_mapping(*virq);
fail_create:
	return result;
}
Esempio n. 15
0
void ps3_write_phys_ctr(u32 cpu, u32 phys_ctr, u32 val)
{
	u64 counter0415;
	u64 counter0415_mask;
	u64 counter2637;
	u64 counter2637_mask;
	int result;

	if (phys_ctr >= NR_PHYS_CTRS) {
		dev_dbg(sbd_core(), "%s:%u: phys_ctr too big: %u\n", __func__,
			__LINE__, phys_ctr);
		return;
	}

	switch (phys_ctr) {
	case 0:
		counter0415 = (u64)val << 32;
		counter0415_mask = PS3_PM_COUNTER_MASK_HI;
		counter2637 = 0x0;
		counter2637_mask = 0x0;
		break;
	case 1:
		counter0415 = (u64)val;
		counter0415_mask = PS3_PM_COUNTER_MASK_LO;
		counter2637 = 0x0;
		counter2637_mask = 0x0;
		break;
	case 2:
		counter0415 = 0x0;
		counter0415_mask = 0x0;
		counter2637 = (u64)val << 32;
		counter2637_mask = PS3_PM_COUNTER_MASK_HI;
		break;
	case 3:
		counter0415 = 0x0;
		counter0415_mask = 0x0;
		counter2637 = (u64)val;
		counter2637_mask = PS3_PM_COUNTER_MASK_LO;
		break;
	default:
		BUG();
	}

	result = lv1_set_lpm_counter(lpm_priv->lpm_id,
				     counter0415, counter0415_mask,
				     counter2637, counter2637_mask,
				     &counter0415, &counter2637);
	if (result)
		dev_err(sbd_core(), "%s:%u: lv1_set_lpm_counter failed: "
			"phys_ctr %u, val %u, %s\n", __func__, __LINE__,
			phys_ctr, val, ps3_result(result));
}
Esempio n. 16
0
void ps3_enable_pm(u32 cpu)
{
	int result;
	u64 tmp;
	int insert_bookmark = 0;

	lpm_priv->tb_count = 0;

	if (use_start_stop_bookmark) {
		if (!(lpm_priv->shadow.pm_start_stop &
			(PS3_PM_START_STOP_START_MASK
			| PS3_PM_START_STOP_STOP_MASK))) {
			result = lv1_set_lpm_trigger_control(lpm_priv->lpm_id,
				(PS3_PM_START_STOP_PPU_TH0_BOOKMARK_START |
				PS3_PM_START_STOP_PPU_TH1_BOOKMARK_START |
				PS3_PM_START_STOP_PPU_TH0_BOOKMARK_STOP |
				PS3_PM_START_STOP_PPU_TH1_BOOKMARK_STOP),
				0xFFFFFFFFFFFFFFFFULL, &tmp);

			if (result)
				dev_err(sbd_core(), "%s:%u: "
					"lv1_set_lpm_trigger_control failed: "
					"%s\n", __func__, __LINE__,
					ps3_result(result));

			insert_bookmark = !result;
		}
	}

	result = lv1_start_lpm(lpm_priv->lpm_id);

	if (result)
		dev_err(sbd_core(), "%s:%u: lv1_start_lpm failed: %s\n",
			__func__, __LINE__, ps3_result(result));

	if (use_start_stop_bookmark && !result && insert_bookmark)
		ps3_set_bookmark(get_tb() | PS3_PM_BOOKMARK_START);
}
Esempio n. 17
0
int ps3_free_io_irq(unsigned int virq)
{
	int result;

	result = lv1_destruct_io_irq_outlet(virq_to_hw(virq));

	if (result)
		pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n",
			__func__, __LINE__, ps3_result(result));

	irq_dispose_mapping(virq);

	return result;
}
Esempio n. 18
0
int ps3_lpm_copy_tb_to_user(unsigned long offset, void __user *buf,
			    unsigned long count, unsigned long *bytes_copied)
{
	int result;

	*bytes_copied = 0;

	if (!lpm_priv->tb_cache)
		return -EPERM;

	if (offset >= lpm_priv->tb_count)
		return 0;

	count = min_t(u64, count, lpm_priv->tb_count - offset);

	while (*bytes_copied < count) {
		const unsigned long request = count - *bytes_copied;
		u64 tmp;

		result = lv1_copy_lpm_trace_buffer(lpm_priv->lpm_id, offset,
						   request, &tmp);
		if (result) {
			dev_dbg(sbd_core(), "%s:%u: 0x%lx bytes at 0x%lx\n",
				__func__, __LINE__, request, offset);
			dev_err(sbd_core(), "%s:%u: lv1_copy_lpm_trace_buffer "
				"failed: %s\n", __func__, __LINE__,
				ps3_result(result));
			return result == LV1_WRONG_STATE ? -EBUSY : -EINVAL;
		}

		result = copy_to_user(buf, lpm_priv->tb_cache, tmp);

		if (result) {
			dev_dbg(sbd_core(), "%s:%u: 0x%llx bytes at 0x%p\n",
				__func__, __LINE__, tmp, buf);
			dev_err(sbd_core(), "%s:%u: copy_to_user failed: %d\n",
				__func__, __LINE__, result);
			return -EFAULT;
		}

		buf += tmp;
		*bytes_copied += tmp;
		offset += tmp;
	}
	dev_dbg(sbd_core(), "%s:%u: copied %lxh bytes\n", __func__, __LINE__,
		*bytes_copied);

	return 0;
}
static int ps3_sb_free_mmio_region(struct ps3_mmio_region *r)
{
	int result;

	dump_mmio_region(r);
	result = lv1_unmap_device_mmio_region(r->dev->bus_id, r->dev->dev_id,
		r->lpar_addr);

	if (result)
		pr_debug("%s:%d: lv1_unmap_device_mmio_region failed: %s\n",
			__func__, __LINE__, ps3_result(result));

	r->lpar_addr = 0;
	return result;
}
Esempio n. 20
0
int ps3_io_irq_destroy(unsigned int virq)
{
	int result;

	result = lv1_destruct_io_irq_outlet(virq_to_hw(virq));

	if (result)
		pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n",
			__func__, __LINE__, ps3_result(result));

	result = ps3_irq_plug_destroy(virq);
	BUG_ON(result);

	return result;
}
Esempio n. 21
0
int ps3_free_vuart_irq(unsigned int virq)
{
	int result;

	result = lv1_deconfigure_virtual_uart_irq();

	if (result) {
		pr_debug("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n",
			__func__, __LINE__, ps3_result(result));
		return result;
	}

	irq_dispose_mapping(virq);

	return result;
}
static int ps3_sb_mmio_region_create(struct ps3_mmio_region *r)
{
	int result;

	result = lv1_map_device_mmio_region(r->dev->bus_id, r->dev->dev_id,
		r->bus_addr, r->len, r->page_size, &r->lpar_addr);

	if (result) {
		pr_debug("%s:%d: lv1_map_device_mmio_region failed: %s\n",
			__func__, __LINE__, ps3_result(result));
		r->lpar_addr = 0;
	}

	dump_mmio_region(r);
	return result;
}
Esempio n. 23
0
static int delete_node(u64 n1, u64 n2, u64 n3, u64 n4)
{
	int result;

	dump_node(0, n1, n2, n3, n4, 0, 0);

	result = lv1_delete_repository_node(n1, n2, n3, n4);

	if (result) {
		pr_devel("%s:%d: lv1_delete_repository_node failed: %s\n",
			__func__, __LINE__, ps3_result(result));
		return -ENOENT;
	}

	return 0;
}
Esempio n. 24
0
static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp,
			      unsigned long vpn, int psize, int apsize,
			      int ssize, int local)
{
	int result;
	u64 hpte_v, want_v, hpte_rs;
	u64 hpte_v_array[4];
	unsigned long flags;
	long ret;

	want_v = hpte_encode_avpn(vpn, psize, ssize);

	spin_lock_irqsave(&ps3_htab_lock, flags);

	result = lv1_read_htab_entries(PS3_LPAR_VAS_ID_CURRENT, slot & ~0x3UL,
				       &hpte_v_array[0], &hpte_v_array[1],
				       &hpte_v_array[2], &hpte_v_array[3],
				       &hpte_rs);

	if (result) {
		pr_info("%s: result=%s read vpn=%lx slot=%lx psize=%d\n",
			__func__, ps3_result(result), vpn, slot, psize);
		BUG();
	}

	hpte_v = hpte_v_array[slot % 4];

	/*
	 * As lv1_read_htab_entries() does not give us the RPN, we can
	 * not synthesize the new hpte_r value here, and therefore can
	 * not update the hpte with lv1_insert_htab_entry(), so we
	 * instead invalidate it and ask the caller to update it via
	 * ps3_hpte_insert() by returning a -1 value.
	 */
	if (!HPTE_V_COMPARE(hpte_v, want_v) || !(hpte_v & HPTE_V_VALID)) {
		/* not found */
		ret = -1;
	} else {
		/* entry found, just invalidate it */
		result = lv1_write_htab_entry(PS3_LPAR_VAS_ID_CURRENT,
					      slot, 0, 0);
		ret = -1;
	}

	spin_unlock_irqrestore(&ps3_htab_lock, flags);
	return ret;
}
Esempio n. 25
0
int ps3_free_event_irq(unsigned int virq)
{
	int result;

	pr_debug(" -> %s:%d\n", __func__, __LINE__);

	result = lv1_destruct_event_receive_port(virq_to_hw(virq));

	if (result)
		pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n",
			__func__, __LINE__, ps3_result(result));

	irq_dispose_mapping(virq);

	pr_debug(" <- %s:%d\n", __func__, __LINE__);
	return result;
}
Esempio n. 26
0
int ps3_vuart_irq_destroy(unsigned int virq)
{
	int result;

	result = lv1_deconfigure_virtual_uart_irq();

	if (result) {
		pr_debug("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n",
			__func__, __LINE__, ps3_result(result));
		return result;
	}

	result = ps3_irq_plug_destroy(virq);
	BUG_ON(result);

	return result;
}
Esempio n. 27
0
static void ps3_hpte_invalidate(unsigned long slot, unsigned long vpn,
				int psize, int apsize, int ssize, int local)
{
	unsigned long flags;
	int result;

	spin_lock_irqsave(&ps3_htab_lock, flags);

	result = lv1_write_htab_entry(PS3_LPAR_VAS_ID_CURRENT, slot, 0, 0);

	if (result) {
		pr_info("%s: result=%s vpn=%lx slot=%lx psize=%d\n",
			__func__, ps3_result(result), vpn, slot, psize);
		BUG();
	}

	spin_unlock_irqrestore(&ps3_htab_lock, flags);
}
Esempio n. 28
0
int ps3_irq_plug_destroy(unsigned int virq)
{
	int result;
	const struct ps3_private *pd = get_irq_chip_data(virq);

	pr_debug("%s:%d: node %lu, cpu %d, virq %u\n", __func__, __LINE__,
		pd->node, pd->cpu, virq);

	result = lv1_disconnect_irq_plug_ext(pd->node, pd->cpu, virq);

	if (result)
		pr_info("%s:%d: lv1_disconnect_irq_plug_ext failed: %s\n",
		__func__, __LINE__, ps3_result(result));

	ps3_virq_destroy(virq);

	return result;
}
Esempio n. 29
0
int ps3_io_irq_setup(enum ps3_cpu_binding cpu, unsigned int interrupt_id,
	unsigned int *virq)
{
	int result;
	u64 outlet;

	result = lv1_construct_io_irq_outlet(interrupt_id, &outlet);

	if (result) {
		pr_debug("%s:%d: lv1_construct_io_irq_outlet failed: %s\n",
			__func__, __LINE__, ps3_result(result));
		return result;
	}

	result = ps3_irq_plug_setup(cpu, outlet, virq);
	BUG_ON(result);

	return result;
}
Esempio n. 30
0
int ps3_event_receive_port_setup(enum ps3_cpu_binding cpu, unsigned int *virq)
{
	int result;
	u64 outlet;

	result = lv1_construct_event_receive_port(&outlet);

	if (result) {
		pr_debug("%s:%d: lv1_construct_event_receive_port failed: %s\n",
			__func__, __LINE__, ps3_result(result));
		*virq = NO_IRQ;
		return result;
	}

	result = ps3_irq_plug_setup(cpu, outlet, virq);
	BUG_ON(result);

	return result;
}