Skip to content
Snippets Groups Projects
interactive.c 71 KiB
Newer Older
  • Learn to ignore specific revisions
  • 					if (isdigit(c)) {
    						dst_ctlr_num = (c - '0');
    						break;
    					}
    				}
    			}
    
    			for (i = argc - 1; i >= argc - num_dest_parms; i--) {
    				if (argv[i][0] == 'd') {
    					char c = argv[i][1];
    					if (isdigit(c)) {
    						dst_dimm_num = (c - '0');
    						break;
    					}
    				}
    			}
    
    			/* TODO: validate inputs */
    
    			debug("src_ctlr_num = %u, src_dimm_num = %u, dst_ctlr_num = %u, dst_dimm_num = %u, step_mask = %x\n",
    				src_ctlr_num, src_dimm_num, dst_ctlr_num, dst_dimm_num, step_mask);
    
    
    			switch (step_mask) {
    
    			case STEP_GET_SPD:
    				memcpy(&(pinfo->spd_installed_dimms[dst_ctlr_num][dst_dimm_num]),
    					&(pinfo->spd_installed_dimms[src_ctlr_num][src_dimm_num]),
    					sizeof(pinfo->spd_installed_dimms[0][0]));
    				break;
    
    			case STEP_COMPUTE_DIMM_PARMS:
    				memcpy(&(pinfo->dimm_params[dst_ctlr_num][dst_dimm_num]),
    					&(pinfo->dimm_params[src_ctlr_num][src_dimm_num]),
    					sizeof(pinfo->dimm_params[0][0]));
    				break;
    
    			case STEP_COMPUTE_COMMON_PARMS:
    				memcpy(&(pinfo->common_timing_params[dst_ctlr_num]),
    					&(pinfo->common_timing_params[src_ctlr_num]),
    					sizeof(pinfo->common_timing_params[0]));
    				break;
    
    			case STEP_GATHER_OPTS:
    				memcpy(&(pinfo->memctl_opts[dst_ctlr_num]),
    					&(pinfo->memctl_opts[src_ctlr_num]),
    					sizeof(pinfo->memctl_opts[0]));
    				break;
    
    			/* someday be able to have addresses to copy addresses... */
    
    			case STEP_COMPUTE_REGS:
    				memcpy(&(pinfo->fsl_ddr_config_reg[dst_ctlr_num]),
    					&(pinfo->fsl_ddr_config_reg[src_ctlr_num]),
    					sizeof(pinfo->memctl_opts[0]));
    				break;
    
    			default:
    				printf("unexpected step_mask value\n");
    			}
    
    			continue;
    
    		}
    
    
    		if (strcmp(argv[0], "edit") == 0) {
    			unsigned int error = 0;
    			unsigned int step_mask = 0;
    			unsigned int ctlr_mask = 0;
    			unsigned int dimm_mask = 0;
    			char *p_element = NULL;
    			char *p_value = NULL;
    			unsigned int dimm_number_required = 0;
    			unsigned int ctrl_num;
    			unsigned int dimm_num;
    
    			if (argc == 1) {
    				/* Only the element and value must be last */
    				printf("edit <c#> <d#> "
    					"<spd|dimmparms|commonparms|opts|"
    					"addresses|regs> <element> <value>\n");
    				printf("for spd, specify byte number for "
    					"element\n");
    				continue;
    			}
    
    
    			error = fsl_ddr_parse_interactive_cmd(
    				argv, argc - 2,
    				&step_mask,
    				&ctlr_mask,
    				&dimm_mask,
    				&dimm_number_required
    			);
    
    
    			if (error)
    				continue;
    
    
    			/* Check arguments */
    
    			/* ERROR: If no steps were found */
    			if (step_mask == 0) {
    				printf("Error: No valid steps were specified "
    						"in argument.\n");
    				continue;
    			}
    
    			/* ERROR: If multiple steps were found */
    			if (step_mask & (step_mask - 1)) {
    				printf("Error: Multiple steps specified in "
    						"argument.\n");
    				continue;
    			}
    
    			/* ERROR: Controller not specified */
    			if (ctlr_mask == 0) {
    				printf("Error: controller number not "
    					"specified or no element and "
    					"value specified\n");
    				continue;
    			}
    
    			if (ctlr_mask & (ctlr_mask - 1)) {
    				printf("Error: multiple controllers "
    						"specified, %X\n", ctlr_mask);
    				continue;
    			}
    
    			/* ERROR: DIMM number not specified */
    			if (dimm_number_required && dimm_mask == 0) {
    				printf("Error: DIMM number number not "
    					"specified or no element and "
    					"value specified\n");
    				continue;
    			}
    
    			if (dimm_mask & (dimm_mask - 1)) {
    				printf("Error: multipled DIMMs specified\n");
    				continue;
    			}
    
    			p_element = argv[argc - 2];
    			p_value = argv[argc - 1];
    
    			ctrl_num = __ilog2(ctlr_mask);
    			dimm_num = __ilog2(dimm_mask);
    
    			switch (step_mask) {
    			case STEP_GET_SPD:
    				{
    					unsigned int element_num;
    					unsigned int value;
    
    					element_num = simple_strtoul(p_element,
    								     NULL, 0);
    					value = simple_strtoul(p_value,
    							       NULL, 0);
    					fsl_ddr_spd_edit(pinfo,
    							       ctrl_num,
    							       dimm_num,
    							       element_num,
    							       value);
    					next_step = STEP_COMPUTE_DIMM_PARMS;
    				}
    				break;
    
    			case STEP_COMPUTE_DIMM_PARMS:
    				fsl_ddr_dimm_parameters_edit(
    						 pinfo, ctrl_num, dimm_num,
    						 p_element, p_value);
    				next_step = STEP_COMPUTE_COMMON_PARMS;
    				break;
    
    			case STEP_COMPUTE_COMMON_PARMS:
    				lowest_common_dimm_parameters_edit(pinfo,
    						ctrl_num, p_element, p_value);
    				next_step = STEP_GATHER_OPTS;
    				break;
    
    			case STEP_GATHER_OPTS:
    				fsl_ddr_options_edit(pinfo, ctrl_num,
    							   p_element, p_value);
    				next_step = STEP_ASSIGN_ADDRESSES;
    				break;
    
    			case STEP_ASSIGN_ADDRESSES:
    				printf("editing of address assignment "
    						"not yet implemented\n");
    				break;
    
    			case STEP_COMPUTE_REGS:
    				{
    					fsl_ddr_regs_edit(pinfo,
    								ctrl_num,
    								p_element,
    								p_value);
    					next_step = STEP_PROGRAM_REGS;
    				}
    				break;
    
    			default:
    				printf("programming error\n");
    				while (1)
    					;
    				break;
    			}
    			continue;
    		}
    
    		if (strcmp(argv[0], "reset") == 0) {
    			/*
    			 * Reboot machine.
    			 * Args don't seem to matter because this
    			 * doesn't return
    			 */
    			do_reset(NULL, 0, 0, NULL);
    
    			printf("Reset didn't work\n");
    
    		}
    
    		if (strcmp(argv[0], "recompute") == 0) {
    			/*
    			 * Recalculate everything, starting with
    			 * loading SPD EEPROM from DIMMs
    			 */
    			next_step = STEP_GET_SPD;
    			ddrsize = fsl_ddr_compute(pinfo, next_step, 0);
    			continue;
    		}
    
    		if (strcmp(argv[0], "compute") == 0) {
    			/*
    			 * Compute rest of steps starting at
    			 * the current next_step/
    			 */
    			ddrsize = fsl_ddr_compute(pinfo, next_step, 0);
    			continue;
    		}
    
    		if (strcmp(argv[0], "print") == 0) {
    			unsigned int error = 0;
    			unsigned int step_mask = 0;
    			unsigned int ctlr_mask = 0;
    			unsigned int dimm_mask = 0;
    
    			unsigned int dimm_number_required = 0;
    
    
    			if (argc == 1) {
    				printf("print [c<n>] [d<n>] [spd] [dimmparms] "
    				  "[commonparms] [opts] [addresses] [regs]\n");
    				continue;
    			}
    
    
    			error = fsl_ddr_parse_interactive_cmd(
    				argv, argc,
    				&step_mask,
    				&ctlr_mask,
    				&dimm_mask,
    				&dimm_number_required
    			);
    
    
    			if (error)
    				continue;
    
    			/* If no particular controller was found, print all */
    			if (ctlr_mask == 0)
    				ctlr_mask = 0xFF;
    
    			/* If no particular dimm was found, print all dimms. */
    			if (dimm_mask == 0)
    				dimm_mask = 0xFF;
    
    			/* If no steps were found, print all steps. */
    			if (step_mask == 0)
    				step_mask = STEP_ALL;
    
    			fsl_ddr_printinfo(pinfo, ctlr_mask,
    						dimm_mask, step_mask);
    			continue;
    		}
    
    		if (strcmp(argv[0], "go") == 0) {
    			if (next_step)
    				ddrsize = fsl_ddr_compute(pinfo, next_step, 0);
    			break;
    		}
    
    		printf("unknown command %s\n", argv[0]);
    	}
    
    	debug("end of memory = %llu\n", (u64)ddrsize);
    
    	return ddrsize;
    }