?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE OS : OSM$CPU_CONFIGURATION_MGR_R1' ??
MODULE osm$cpu_configuration_mgr_r1;

{ PURPOSE:
{   This module contains the ring one procedures which support software reconfiguration of CPUS.

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc cml$element_state_change
*copyc cmt$cpu_element_definition
*copyc cmt$element_state
*copyc dst$change_processor_state
*copyc dst$log_ele_state_change
*copyc osc$processor_defined_registers
*copyc ost$processor_id
*copyc ost$processor_id_set
*copyc ost$status
?? POP ??
*copyc cmp$get_cpu_element_r1
*copyc dsp$change_processor_state
*copyc dsp$log_sys_msg_help
*copyc osp$get_global_cpu_model_def
?? EJECT ??
*IF $variable(mmv$test_forced_use_cache_maps, declared) <> 'UNKNOWN'
*copyc mmv$force_use_of_cache_and_maps;
*ELSE
{ -------- Variable declarations for forcing the use of cache and maps omitted at compile time --------
*IFEND
*copyc mmv$multiple_caches
*copyc mmv$multiple_page_maps
*copyc mtv$cst0
*copyc mtv$scb
*copyc osv$cpus_logically_on
*copyc osv$multiprocessor_running
*copyc osv$cpus_physically_configured
*copyc tmv$multiple_cpus_active
?? OLDTITLE ??
?? NEWTITLE := 'process_cpu_state_change_r1', EJECT ??

{ PURPOSE:
{   This procedure makes a call to change the state of the specified processor in the Mainframe
{   Reconfiguration Table (MRT) and then logs an element state change statistic (CM200) to the
{   engineering log.

   VAR
     mtv$cy2000_sp_recovery: [XREF] boolean,
     mtv$reset_all_cache_now: [XREF] boolean,
     mtv$recovery_lock3: [XREF] boolean;

  PROCEDURE process_cpu_state_change_r1
    (    processor_id: ost$processor_id);

    VAR
      cpu_element: cmt$cpu_element_definition,
      global_processor_model_def: ost$processor_model_definition,
      length: integer,
      local_status: ost$status,
      log_data_p: ^SEQ (*),
      logging_data: dst$log_ele_state_change,
      state_data: dst$change_processor_state,
      working_string: string (31);

    IF mtv$cy2000_sp_recovery THEN

{ The CPU has already been recovered by the Service Processor and
{ therefore the MRT has been updated. Just perform cleanup and exit.

      mmv$multiple_caches := global_processor_model_def.cache_present;
      mmv$multiple_page_maps := global_processor_model_def.maps_present;
      mtv$reset_all_cache_now := FALSE;
      mtv$cst0 [processor_id].cpu_alive_flag := #FREE_RUNNING_CLOCK (0);
      mtv$scb.cpus.logically_on := mtv$scb.cpus.logically_on + $ost$processor_id_set [processor_id];
      mtv$cst0 [processor_id].dispatching_priority_integer := 0;
      IF osv$cpus_logically_on > 1 THEN
        tmv$multiple_cpus_active := TRUE;
      IFEND;
      state_data.state := mtv$cst0 [processor_id].processor_state;
      dsp$change_processor_state (processor_id, state_data, mtv$cy2000_sp_recovery);
      mtv$cy2000_sp_recovery := FALSE;
      mtv$recovery_lock3 := FALSE;

      RETURN; {----->
    IFEND;


    { Make the request to change the processor state in the MRT.

    state_data.state := mtv$cst0 [processor_id].processor_state;
    IF mtv$cst0 [processor_id].processor_state = cmc$down THEN
      IF mtv$cst0 [processor_id].reason_for_current_state = osc$cdsr_downed_by_operator THEN
        state_data.down_reason := dsc$pdr_down_by_operator;
      ELSE
        state_data.down_reason := dsc$pdr_down_by_system;
      IFEND;
      state_data.halt_cpu_via_dft := (mtv$cst0 [processor_id].reason_for_current_state <>
            osc$cdsr_downed_by_dft);
    IFEND;
    dsp$change_processor_state (processor_id, state_data, FALSE);
    osp$get_global_cpu_model_def (global_processor_model_def);

    IF mtv$cst0 [processor_id].processor_state = cmc$on THEN

      { Determine whether cache and/or page maps are present for this processor model.  This code is
      { executed only when the second of two or more processors is restarted.

      mmv$multiple_caches := global_processor_model_def.cache_present;
      mmv$multiple_page_maps := global_processor_model_def.maps_present;

*IF $variable(mmv$test_forced_use_cache_maps, declared) <> 'UNKNOWN'
{ The following code is benchmark code to force use of cache and/or maps during benchmark runs.

      mmv$multiple_caches := mmv$multiple_caches OR mmv$force_use_of_cache_and_maps;
      mmv$multiple_page_maps := mmv$multiple_page_maps OR mmv$force_use_of_cache_and_maps;
*ELSE
{ -------- Code for forcing the use of cache and maps omitted at compile time --------
*IFEND
    IFEND;

    { Log the element state change to the engineering log.

    cmp$get_cpu_element_r1 (processor_id, {update_cst =} FALSE, cpu_element, local_status);
    IF NOT local_status.normal THEN
      RETURN;
    IFEND;

    STRINGREP (working_string, length, processor_id);
    logging_data.element_name := ' ';
    logging_data.element_name (1, 2) := 'CP';
    logging_data.element_name (3) := working_string (2);

    logging_data.product_id.product_number := ' ';

    logging_data.product_id.product_number (3, 3) := global_processor_model_def.model_number_string (1, 3);

    logging_data.product_id.underscore := '_';

    STRINGREP (working_string, length, cpu_element.model_number:#(16));
    logging_data.product_id.model_number := '   ';
    logging_data.product_id.model_number (1, 2) := working_string (2, 2);

    STRINGREP (working_string, length, cpu_element.serial_number:#(10));
    logging_data.serial_number := '      ';
    logging_data.serial_number (1, 5) := working_string (2, (length - 1));

    logging_data.old_state := mtv$cst0 [processor_id].previous_processor_state;
    logging_data.new_state := mtv$cst0 [processor_id].processor_state;
    CASE cpu_element.reason_for_current_state OF
    = osc$cdsr_downed_by_operator =
      logging_data.initiator := 'op';
    = osc$cdsr_downed_by_dft, osc$cdsr_due_threshold_exceeded, osc$cdsr_cpu_timeout,
          osc$cdsr_downed_by_system =
      logging_data.initiator := 'fail';
    ELSE
    CASEND;
    log_data_p := #SEQ (logging_data);
    dsp$log_sys_msg_help (cml$element_state_change, log_data_p);

  PROCEND  process_cpu_state_change_r1;
?? OLDTITLE ??
?? NEWTITLE := 'syp$mfh_cpu_config_change', EJECT ??

{ PURPOSE:
{   This procedure is the monitor flag handler for CPU configuration changes which are processed in monitor.
{   This code looks through the cpu state table for information which must be logged due to the state change.

  PROCEDURE [XDCL] syp$mfh_cpu_config_change;

    VAR
      processor_id: ost$processor_id;

    { Look for any information that may have come from monitor recently.  No interlocks are required to read
    { this information since the system job_monitor task is the only task that will ever execute this code.

    FOR processor_id := 0 TO (osv$cpus_physically_configured - 1) DO
      IF mtv$cst0 [processor_id].log_cpu_state_change THEN
        process_cpu_state_change_r1 (processor_id);
        mtv$cst0 [processor_id].log_cpu_state_change := FALSE;
      IFEND;
    FOREND;

  PROCEND syp$mfh_cpu_config_change;
?? OLDTITLE ??


?? TITLE := 'OSP$ENABLE_PICO_STATISTICS', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$enable_pico_statistics;

  VAR
    iov$accept_pico_statistics: [XREF] boolean;

    iov$accept_pico_statistics := TRUE;

  PROCEND osp$enable_pico_statistics;




?? TITLE := 'OSP$DISABLE_PICO_STATISTICS', EJECT ??

  PROCEDURE [XDCL, #GATE] osp$disable_pico_statistics;

  VAR
    iov$accept_pico_statistics: [XREF] boolean;

    iov$accept_pico_statistics := FALSE;

  PROCEND osp$disable_pico_statistics;

MODEND osm$cpu_configuration_mgr_r1;
