Пример #1
0
int encdec_init(void)
{
	u64 muid, dma_bus_addr;
	int result;

	result = lv1_allocate_memory(ENCDEC_DMA_SIZE, ENCDEC_DMA_PAGE_SIZE, 0, 0,
		&encdec_buf_lpar_addr, &muid);
	if (result != 0)
		return result;

	result = lv1_allocate_device_dma_region(ENCDEC_BUS_ID, ENCDEC_DEV_ID,
		ENCDEC_DMA_SIZE, ENCDEC_DMA_PAGE_SIZE, 0, &dma_bus_addr);
	if (result != 0)
		return result;

	result = lv1_map_device_dma_region(ENCDEC_BUS_ID, ENCDEC_DEV_ID,
		encdec_buf_lpar_addr, dma_bus_addr, ENCDEC_DMA_SIZE, 0xF800000000000000ULL);
	if (result != 0)
		return result;

	MM_LOAD_BASE(encdec_buf, ENCDEC_DMA_OFFSET);

	result = mm_map_lpar_memory_region(0, MM_EA2VA((u64) encdec_buf), encdec_buf_lpar_addr,
		ENCDEC_DMA_SIZE, ENCDEC_DMA_PAGE_SIZE, 0, 0);
	if (result != 0)
		return result;

	memset(encdec_buf, 0, ENCDEC_DMA_SIZE);

	return 0;
}
Пример #2
0
int map_lv1(void)
{
    int result = lv1_undocumented_function_114(0, 0xC, HV_SIZE, &mmap_lpar_addr);
    if (result != 0) {
        return 0;
    }

    result = mm_map_lpar_memory_region(mmap_lpar_addr, HV_BASE, HV_SIZE, 0xC, 0);
    if (result) {
        return 0;
    }

    return 1;
}
Пример #3
0
int map_lv1() {
	int result = lv1_undocumented_function_114(0, 0xC, HV_SIZE, &mmap_lpar_addr);
	if (result != 0) {
		PRINTF("Error code %d calling lv1_undocumented_function_114\n", result);
		return 0;
	}
	
	result = mm_map_lpar_memory_region(mmap_lpar_addr, HV_BASE, HV_SIZE, 0xC, 0);
	if (result) {
		PRINTF("Error code %d calling mm_map_lpar_memory_region\n", result);
		return 0;
	}
	
	return 1;
}
Пример #4
0
int map_lv1()
{
	char buf[256];
	int result =
	    lv1_undocumented_function_114(0, 0xC, HV_SIZE, &mmap_lpar_addr);
	if (result != 0) {
		snprintf(buf, sizeof(buf),
			 "Error code %d calling lv1_undocumented_function_114",
			 result);
		xputs(buf);
		return 0;
	}
	result =
	    mm_map_lpar_memory_region(mmap_lpar_addr, HV_BASE, HV_SIZE, 0xC, 0);
	if (result) {
		snprintf(buf, sizeof(buf),
			 "Error code %d calling mm_map_lpar_memory_region",
			 result);
		xputs(buf);
		return 0;
	}
	return 1;
}
Пример #5
0
int aim_get_open_ps_id(void)
{
#define N(a)	(sizeof((a)) / sizeof((a)[0]))

	u64 vuart_lpar_addr, muid, nread, nwritten;
	u8 *msgbuf;
	struct dispmgr_header *dispmgr_header;
	struct ss_header *ss_header;
	struct ss_aim_get_open_ps_id *ss_aim_get_open_ps_id;
	int result;

	result = lv1_allocate_memory(AIM_GET_OPEN_PS_ID_SIZE, AIM_GET_OPEN_PS_ID_PAGE_SIZE,
		0, 0, &vuart_lpar_addr, &muid);
 	if (result != 0)
 		return result;

	MM_LOAD_BASE(msgbuf, AIM_GET_OPEN_PS_ID_OFFSET);

	result = mm_map_lpar_memory_region(0, MM_EA2VA((u64) msgbuf), vuart_lpar_addr,
		AIM_GET_OPEN_PS_ID_SIZE, AIM_GET_OPEN_PS_ID_PAGE_SIZE, 0, 0);
	if (result != 0)
		return result;

	memset(msgbuf, 0, AIM_GET_OPEN_PS_ID_SIZE);

	dispmgr_header = (struct dispmgr_header *) msgbuf;
	dispmgr_header->request_id = 1;
	dispmgr_header->function_id = 0x19000;
	dispmgr_header->request_size = sizeof(struct ss_header);
	dispmgr_header->response_size = sizeof(struct ss_header) +
			sizeof(struct ss_aim_get_open_ps_id);

	ss_header = (struct ss_header *) (dispmgr_header + 1);
	memset(ss_header, 0, sizeof(struct ss_header));
	ss_header->packet_id = 0x19005;
	ss_header->function_id = 0x19000;
	ss_header->laid = subject_id[0];
	ss_header->paid = subject_id[1];

	ss_aim_get_open_ps_id = (struct ss_aim_get_open_ps_id *) (ss_header + 1);
	memset(ss_aim_get_open_ps_id, 0, sizeof(struct ss_aim_get_open_ps_id));

	dispmgr_header->request_size += sizeof(struct ss_aim_get_open_ps_id);

	result = lv1_write_virtual_uart(DISPMGR_VUART_PORT, vuart_lpar_addr,
		sizeof(struct dispmgr_header) + dispmgr_header->request_size, &nwritten);
	if (result < 0)
		return result;

	result = vuart_wait_for_rx_data(DISPMGR_VUART_PORT);
	if (result < 0)
		return result;

	result = lv1_read_virtual_uart(DISPMGR_VUART_PORT, vuart_lpar_addr,
		AIM_GET_OPEN_PS_ID_SIZE, &nread);
	if (result < 0)
		return result;

	result = gelic_xmit_data(gelic_bcast_mac_addr, 0xBEEF, msgbuf, nread);
	if (result < 0)
		return result;

	beep(BEEP_DOUBLE);

	lv1_panic(1);

	return 0;

#undef N
}
Пример #6
0
int product_mode_off(void)
{
	u64 vuart_lpar_addr, muid, nread, nwritten;
	u8 *msgbuf;
	struct dispmgr_header *dispmgr_header;
	struct ss_header *ss_header;
	struct ss_update_mgr_write_eprom *ss_update_mgr_write_eprom;
	int result;

	result = lv1_allocate_memory(PRODUCT_MODE_SIZE, PRODUCT_MODE_PAGE_SIZE,
		0, 0, &vuart_lpar_addr, &muid);
 	if (result != 0)
 		return result;

	MM_LOAD_BASE(msgbuf, PRODUCT_MODE_OFFSET);

	result = mm_map_lpar_memory_region(0, (u64) msgbuf, vuart_lpar_addr,
		PRODUCT_MODE_SIZE, PRODUCT_MODE_PAGE_SIZE, 0, 0);
 	if (result != 0)
 		return result;

	memset(msgbuf, 0, PRODUCT_MODE_SIZE);

	dispmgr_header = (struct dispmgr_header *) msgbuf;
	dispmgr_header->request_id = 1;
	dispmgr_header->function_id = 0x6000;
	dispmgr_header->request_size = sizeof(struct ss_header);
	dispmgr_header->response_size = sizeof(struct ss_header) +
		sizeof(struct ss_update_mgr_write_eprom);

	ss_header = (struct ss_header *) (dispmgr_header + 1);
	memset(ss_header, 0, sizeof(struct ss_header));
	ss_header->packet_id = 0x600C;
	ss_header->function_id = 0x6000;
	ss_header->laid = subject_id[0];
	ss_header->paid = subject_id[1];

	ss_update_mgr_write_eprom =
		(struct ss_update_mgr_write_eprom *) (ss_header + 1);
	memset(ss_update_mgr_write_eprom, 0,
		sizeof(struct ss_update_mgr_write_eprom));
	ss_update_mgr_write_eprom->offset = 0x48C07;
	ss_update_mgr_write_eprom->value = 0xFF;

	dispmgr_header->request_size += sizeof(struct ss_update_mgr_write_eprom);

	result = lv1_write_virtual_uart(DISPMGR_VUART_PORT, vuart_lpar_addr,
		sizeof(struct dispmgr_header) + dispmgr_header->request_size, &nwritten);
	if (result < 0)
		return result;

	result = vuart_wait_for_rx_data(DISPMGR_VUART_PORT);
	if (result < 0)
		return result;

	result = lv1_read_virtual_uart(DISPMGR_VUART_PORT, vuart_lpar_addr, PRODUCT_MODE_SIZE,
		&nread);
	if (result < 0)
		return result;

	result = gelic_xmit_data(gelic_bcast_mac_addr, 0xBEEF, msgbuf, nread);
	if (result < 0)
		return result;

	beep(BEEP_DOUBLE);

	lv1_panic(1);

	return 0;
}
Пример #7
0
int payload_main(uint8_t* output_data, uint64_t output_size) {
	int result;

	uint64_t ticks;

	uint64_t hv_lpar_addr;
	uint64_t hv_mapped_size;
	uint8_t* hv;
	uint8_t* metldr;
	uint8_t* stuff;
	uint8_t* dumper;
	uint8_t* work_data;
	uint64_t metldr_offset, metldr_size;
	uint64_t stuff_lpar_addr;
	uint64_t gameos_lpar_base, gameos_lpar_size;

	uint64_t vas_id, spu_id;
	uint64_t esid, vsid;
	uint64_t priv2_addr, problem_phys, local_store_phys, shadow_addr;
	uint64_t intr_status, unused;

	struct spu_shadow volatile* spu_shadow;
	struct spu_problem volatile* spu_problem;
	struct spu_priv2 volatile* spu_priv2;

	uint8_t volatile* spu_ls;
	uint32_t spu_out_intr_mbox_value, spu_out_mbox_value;
	uint8_t mfc_cmd_tag;

	uint32_t force_exit;
	uint32_t i;

	lv2_extend_kstack(0);

	result = 0;

	hv = NULL;
	metldr = NULL;
	stuff = NULL;
	dumper = NULL;
	work_data = NULL;

	hv_lpar_addr = 0;
	stuff_lpar_addr = 0;

	if (!output_data || output_size < DUMP_SIZE) {
		result = EINVAL;
		goto error;
	}

	gameos_lpar_base = *(uint64_t*)GAMEOS_LPAR_BASE_PTR;
	gameos_lpar_size = *(uint64_t*)GAMEOS_LPAR_SIZE_PTR;
	if (!gameos_lpar_base || !gameos_lpar_size) {
		result = EFAULT;
		goto error;
	}

	metldr_offset = lv1_peek64(LOADERS_TAB_OFFSET + METLDR_TAB_OFFSET);
	metldr_size = lv1_peek64(LOADERS_TAB_OFFSET + METLDR_TAB_SIZE);
	if (!metldr_offset || !metldr_size) {
		result = EFAULT;
		goto error;
	}

	hv_mapped_size = align_up(metldr_offset + metldr_size, 1 << HV_PAGE_SIZE);

	result = lv1_undocumented_function_114(0, HV_PAGE_SIZE, hv_mapped_size, &hv_lpar_addr);
	if (result != 0)
		goto error;

	MM_LOAD_BASE(hv, HV_OFFSET);

	result = mm_map_lpar_memory_region(0, MM_EA2VA(hv), hv_lpar_addr, hv_mapped_size, HV_PAGE_SIZE, 0, 0);
	if (result != 0)
		goto error;

	stuff_lpar_addr = gameos_lpar_base + gameos_lpar_size - STUFF_SIZE;

	MM_LOAD_BASE(stuff, STUFF_OFFSET);

	result = mm_map_lpar_memory_region(0, MM_EA2VA(stuff), stuff_lpar_addr, STUFF_SIZE, STUFF_PAGE_SIZE, 0, 0);
	if (result != 0)
		goto error;

	metldr = stuff;
	dumper = ptr_align_up(metldr + metldr_size, 1 << STUFF_PAGE_SIZE);
	work_data = ptr_align_up(dumper + dumper_payload_size, 1 << STUFF_PAGE_SIZE);

	lv2_memcpy(metldr, hv + metldr_offset, metldr_size);
	lv2_memcpy(dumper, dumper_payload, dumper_payload_size);
	lv2_memset(work_data, 0, DUMP_SIZE);

	result = lv1_undocumented_function_115(hv_lpar_addr);
	if (result != 0)
		goto done;

	hv_lpar_addr = 0;

	vas_id = vas_get_id();

	result = lv1_construct_logical_spu(PAGE_SIZE_4KB, PAGE_SIZE_4KB, PAGE_SIZE_4KB, PAGE_SIZE_4KB, PAGE_SIZE_4KB, vas_id, 0, &priv2_addr, &problem_phys, &local_store_phys, &unused, &shadow_addr, &spu_id);
	if (result != 0)
		goto error;

	result = lv1_enable_logical_spu(spu_id, 6);
	if (result != 0)
		goto error;

	result = lv1_set_spu_interrupt_mask(spu_id, 0, 0x7);
	if (result != 0)
		goto error;

	result = lv1_set_spu_interrupt_mask(spu_id, 1, 0xF);
	if (result != 0)
		goto error;

	result = lv1_set_spu_interrupt_mask(spu_id, 2, 0xF);
	if (result != 0)
		goto error;

	MM_LOAD_BASE(spu_shadow, SPU_SHADOW_OFFSET);

	result = mm_map_lpar_memory_region(0, MM_EA2VA(spu_shadow), shadow_addr, SPU_SHADOW_SIZE, PAGE_SIZE_4KB, 0, 0x3);
	if (result != 0)
		goto error;

	MM_LOAD_BASE(spu_problem, SPU_PROBLEM_OFFSET);

	result = mm_map_lpar_memory_region(0, MM_EA2VA(spu_problem), problem_phys, SPU_PROBLEM_SIZE, PAGE_SIZE_4KB, 0, 0);
	if (result != 0)
		goto error;

	MM_LOAD_BASE(spu_priv2, SPU_PRIV2_OFFSET);

	result = mm_map_lpar_memory_region(0, MM_EA2VA(spu_priv2), priv2_addr, SPU_PRIV2_SIZE, PAGE_SIZE_4KB, 0, 0);
	if (result != 0)
		goto error;

	MM_LOAD_BASE(spu_ls, SPU_LS_OFFSET);

	result = mm_map_lpar_memory_region(0, MM_EA2VA(spu_ls), local_store_phys, SPU_LS_SIZE, PAGE_SIZE_4KB, 0, 0);
	if (result != 0)
		goto error;

	result = lv1_set_spu_privilege_state_area_1_register(spu_id, MFC_SR1, 0x10);
	if (result != 0)
		goto error;

	spu_slb_invalidate_all(spu_priv2);

	esid = 0x8000000018000000ULL;
	vsid = 0x0000000000001400ULL;

	spu_slb_set_entry(spu_priv2, 0, esid, vsid);

	spu_priv2->spu_cfg = 0;

	eieio();

	spu_in_mbox_write_64(spu_problem, (uint64_t)dumper);
	spu_sig_notify_1_2_write_64(spu_problem, (uint64_t)metldr);
	spu_iso_load_req_enable(spu_priv2);
	spu_iso_load_req(spu_problem);

	force_exit = 0;

	while (1) {
		if (force_exit) {
			result = ECANCELED;
			goto bad;
		}

		result = lv1_get_spu_interrupt_status(spu_id, 0, &intr_status);
		if (result != 0)
			goto error;

		if (intr_status) {
			result = lv1_clear_spu_interrupt_status(spu_id, 0, intr_status, 0);
			if (result != 0)
				goto error;
		}

		result = lv1_get_spu_interrupt_status(spu_id, 1, &intr_status);
		if (result != 0)
			goto error;
			
		if (intr_status) {
			result = lv1_clear_spu_interrupt_status(spu_id, 1, intr_status, 0);
			if (result != 0)
				goto error;
		}

		result = lv1_get_spu_interrupt_status(spu_id, 2, &intr_status);
		if (result != 0)
			goto error;

		if (intr_status) {
			result = lv1_clear_spu_interrupt_status(spu_id, 2, intr_status, 0);
			if (result != 0)
				goto error;

			if (intr_status & 0x1) {
				if (spu_mbox_stat_intr_out_mbox_count(spu_problem) != 0) {
					spu_out_intr_mbox_value = spu_priv2->spu_out_intr_mbox;

					if (spu_out_intr_mbox_value == 1) {
						if (spu_mbox_stat_out_mbox_count(spu_problem) == 0) {
							result = ECANCELED;
							goto bad;
						}

						spu_out_mbox_value = spu_problem->spu_out_mbox;
						if (spu_out_mbox_value != 1) {
							result = ECANCELED;
							break;
						}

						ticks = 3 * TB_TICKS_PER_SEC;
						sleep(ticks);

						mfc_cmd_tag = 1;

						if (spu_mfc_cmd_exec(spu_problem, DUMP_LS_ADDR, (uint64_t)work_data, DUMP_SIZE, mfc_cmd_tag, 0, MFC_CMD_PUT)) {
							result = ECANCELED;
							goto bad;
						}

						while (spu_mfc_cmd_tag_status(spu_problem, mfc_cmd_tag) == 0) {
							if (force_exit) {
								result = ECANCELED;
								goto bad;
							}
						}

						force_exit = 1;
					} else if (spu_out_intr_mbox_value == 2) {
						spu_out_mbox_value = spu_problem->spu_out_mbox;

						force_exit = 1;
					}
				}
			}
		}

		if ((spu_problem->spu_status & 0x1) == 0)
			break;

		ticks = 1 * TB_TICKS_PER_SEC;
		sleep(ticks);
	}

bad:
	if (spu_shadow) {
	}

	if (spu_problem) {
		spu_iso_exit_req(spu_problem);
		spu_stop_req(spu_problem);
	}

	if (spu_priv2) {
	}

	result = lv1_destruct_logical_spu(spu_id);
	if (result != 0)
		goto error;

	if (work_data)
		result = lv2_copy_to_user(work_data, output_data, DUMP_SIZE);

	ticks = 5 * TB_TICKS_PER_SEC;
	sleep(ticks);

error:
	if (hv_lpar_addr != 0)
		result = lv1_undocumented_function_115(hv_lpar_addr);

done:
	return result;
}