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; } }
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); }
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; }
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; }
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; }