예제 #1
0
void
ps3_mem_regions(platform_t plat, struct mem_region *phys, int *physsz,
    struct mem_region *avail_regions, int *availsz)
{
	uint64_t lpar_id, junk, ppe_id;

	/* Get real mode memory region */
	avail_regions[0].mr_start = 0;
	lv1_get_logical_partition_id(&lpar_id);
	lv1_get_logical_ppe_id(&ppe_id);
	lv1_get_repository_node_value(lpar_id,
	    lv1_repository_string("bi") >> 32, lv1_repository_string("pu"),
	    ppe_id, lv1_repository_string("rm_size"),
	    &avail_regions[0].mr_size, &junk);

	/* Now get extended memory region */
	lv1_get_repository_node_value(lpar_id,
	    lv1_repository_string("bi") >> 32,
	    lv1_repository_string("rgntotal"), 0, 0,
	    &avail_regions[1].mr_size, &junk);

	/* Convert to maximum amount we can allocate in 16 MB pages */
	avail_regions[1].mr_size -= avail_regions[0].mr_size;
	avail_regions[1].mr_size -= avail_regions[1].mr_size % (16*1024*1024);
	*availsz = 2;

	if (phys != NULL) {
		memcpy(phys, avail_regions, sizeof(*phys)*2);
		*physsz = 2;
	}
}
예제 #2
0
static int
ps3_attach(platform_t plat)
{
	uint64_t lpar_id, junk, ppe_id;

	/* Get real mode memory region */
	avail_regions[0].mr_start = 0;
	lv1_get_logical_partition_id(&lpar_id);
	lv1_get_logical_ppe_id(&ppe_id);
	lv1_get_repository_node_value(lpar_id,
	    lv1_repository_string("bi") >> 32, lv1_repository_string("pu"),
	    ppe_id, lv1_repository_string("rm_size"),
	    &avail_regions[0].mr_size, &junk);

	/* Now get extended memory region */
	lv1_get_repository_node_value(lpar_id,
	    lv1_repository_string("bi") >> 32,
	    lv1_repository_string("rgntotal"), 0, 0,
	    &avail_regions[1].mr_size, &junk);

	/* Convert to maximum amount we can allocate in 16 MB pages */
	avail_regions[1].mr_size -= avail_regions[0].mr_size;
	avail_regions[1].mr_size -= avail_regions[1].mr_size % (16*1024*1024);

	lv1_allocate_memory(avail_regions[1].mr_size, 24 /* 16 MB pages */,
	    0, 0x04 /* any address */, &avail_regions[1].mr_start, &junk);

	pmap_mmu_install("mmu_ps3", BUS_PROBE_SPECIFIC);
	cpu_idle_hook = ps3_cpu_idle;

	/* Set a breakpoint to make NULL an invalid address */
	lv1_set_dabr(0x7 /* read and write, MMU on */, 2 /* kernel accesses */);

	return (0);
}
예제 #3
0
static int read_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4,
	u64 *_v1, u64 *_v2)
{
	int result;
	u64 v1;
	u64 v2;

	if (lpar_id == PS3_LPAR_ID_CURRENT) {
		u64 id;
		lv1_get_logical_partition_id(&id);
		lpar_id = id;
	}

	result = lv1_read_repository_node(lpar_id, n1, n2, n3, n4, &v1,
		&v2);

	if (result) {
		pr_warn("%s:%d: lv1_read_repository_node failed: %s\n",
			__func__, __LINE__, ps3_result(result));
		dump_node_name(lpar_id, n1, n2, n3, n4);
		return -ENOENT;
	}

	dump_node(lpar_id, n1, n2, n3, n4, v1, v2);

	if (_v1)
		*_v1 = v1;
	if (_v2)
		*_v2 = v2;

	if (v1 && !_v1)
		pr_devel("%s:%d: warning: discarding non-zero v1: %016llx\n",
			__func__, __LINE__, v1);
	if (v2 && !_v2)
		pr_devel("%s:%d: warning: discarding non-zero v2: %016llx\n",
			__func__, __LINE__, v2);

	return 0;
}
예제 #4
0
파일: ps3.c 프로젝트: PennPanda/linux-repo
static int ps3_repository_read_rm_size(u64 *rm_size)
{
	s64 result;
	u64 lpar_id;
	u64 ppe_id;
	u64 v2;

	result = lv1_get_logical_partition_id(&lpar_id);

	if (result)
		return -1;

	result = lv1_get_logical_ppe_id(&ppe_id);

	if (result)
		return -1;

	/*
	 * n1: 0000000062690000 : ....bi..
	 * n2: 7075000000000000 : pu......
	 * n3: 0000000000000001 : ........
	 * n4: 726d5f73697a6500 : rm_size.
	*/

	result = lv1_get_repository_node_value(lpar_id, 0x0000000062690000ULL,
		0x7075000000000000ULL, ppe_id, 0x726d5f73697a6500ULL, rm_size,
		&v2);

	printf("%s:%d: ppe_id  %lu \n", __func__, __LINE__,
		(unsigned long)ppe_id);
	printf("%s:%d: lpar_id %lu \n", __func__, __LINE__,
		(unsigned long)lpar_id);
	printf("%s:%d: rm_size %llxh \n", __func__, __LINE__, *rm_size);

	return result ? -1 : 0;
}
예제 #5
0
static int __init ps3_register_lpm_devices(void)
{
	int result;
	u64 tmp1;
	u64 tmp2;
	struct ps3_system_bus_device *dev;

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

	dev = kzalloc(sizeof(*dev), GFP_KERNEL);
	if (!dev)
		return -ENOMEM;

	dev->match_id = PS3_MATCH_ID_LPM;
	dev->dev_type = PS3_DEVICE_TYPE_LPM;

	/* The current lpm driver only supports a single BE processor. */

	result = ps3_repository_read_be_node_id(0, &dev->lpm.node_id);

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

	result = ps3_repository_read_lpm_privileges(dev->lpm.node_id, &tmp1,
		&dev->lpm.rights);

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

	lv1_get_logical_partition_id(&tmp2);

	if (tmp1 != tmp2) {
		pr_debug("%s:%d: wrong lpar\n",
			__func__, __LINE__);
		result = -ENODEV;
		goto fail_rights;
	}

	if (!(dev->lpm.rights & PS3_LPM_RIGHTS_USE_LPM)) {
		pr_debug("%s:%d: don't have rights to use lpm\n",
			__func__, __LINE__);
		result = -EPERM;
		goto fail_rights;
	}

	pr_debug("%s:%d: pu_id %llu, rights %llu(%llxh)\n",
		__func__, __LINE__, dev->lpm.pu_id, dev->lpm.rights,
		dev->lpm.rights);

	result = ps3_repository_read_pu_id(0, &dev->lpm.pu_id);

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

	result = ps3_system_bus_device_register(dev);

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

	pr_debug(" <- %s:%d\n", __func__, __LINE__);
	return 0;


fail_register:
fail_rights:
fail_read_repo:
	kfree(dev);
	pr_debug(" <- %s:%d: failed\n", __func__, __LINE__);
	return result;
}