?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE Program Management : Ring 1 Services' ??
MODULE pmm$program_services_ring_1;

{ PURPOSE:
{   This module contains the program-management ring 1 "service" interface procedures.

?? NEWTITLE := 'Global Declarations Referenced by this module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc oss$mainframe_pageable
*copyc pmt$cpu_data
*copyc pmt$mainframe_id
?? POP ??
*copyc dsp$get_cpu_attributes
*copyc osp$get_cpu_model_definition
*copyc osp$get_global_cpu_model_def
?? OLDTITLE ??
?? NEWTITLE := 'Global Variables Declared in this Module', EJECT ??

  VAR
    pmv$cpu_data: [XDCL, #GATE, oss$mainframe_pageable] pmt$cpu_data,
    pmv$mainframe_id: [XDCL, #GATE, oss$mainframe_pageable] pmt$mainframe_id;
?? OLDTITLE ??
?? NEWTITLE := 'pmp$initialize_cpu_attributes', EJECT ??

  PROCEDURE [XDCL, #GATE] pmp$initialize_cpu_attributes;

    CONST
      c$mainframe_id_prefix = '$SYSTEM_',
      c$mainframe_id_prefix_size = 8;

    TYPE
      t$serial_number_conversion = RECORD
        CASE boolean OF
        = TRUE =
          serial_number: ost$processor_serial_number,
        = FALSE =
          serial_number_array: PACKED ARRAY [1 .. pmc$processor_serial_num_size] OF 0 .. 0f(16),
        CASEND,
      RECEND;

    VAR
      converter: t$serial_number_conversion,
      cpu_attributes: dst$cpu_attributes,
      cpu_index: 0 .. osc$maximum_processor_number,
      definition_found: boolean,
      global_processor_model_def: ost$processor_model_definition,
      mainframe_id_index: 1 .. pmc$mainframe_id_size,
      model_number: pmt$processor_model_number,
      processor_model_definition: ost$processor_model_definition,
      search_data: ost$processor_search_data,
      serial_number: pmt$processor_serial_number,
      serial_number_index: 1 .. pmc$processor_serial_num_size;

?? NEWTITLE := 'change_space_to_zero', EJECT ??

    PROCEDURE change_space_to_zero
      (VAR data: string ( * ));

      VAR
        index: integer,
        length: integer;

      length := STRLENGTH (data);
      IF length > 0 THEN
        WHILE data (length) = ' ' DO
          FOR index := length DOWNTO 2 DO
            data (index) := data (index - 1);
          FOREND;
          data (1) := '0';
        WHILEND;
      IFEND;

    PROCEND change_space_to_zero;

?? OLDTITLE, EJECT ??

    dsp$get_cpu_attributes (cpu_attributes);
    osp$get_global_cpu_model_def (global_processor_model_def);

    pmv$cpu_data.binary_attributes.highest_defined_cpu_number := cpu_attributes.count - 1;
    pmv$cpu_data.attributes.highest_defined_cpu_number := cpu_attributes.count - 1;

    FOR cpu_index := 0 TO osc$maximum_processor_number DO

      { Assign values to the binary_attributes.  A kludge is needed to trap all S0 model numbers 50(16) and
      { 51(16).  They have to be translated into models 52(16) and 53(16) respectively.

      pmv$cpu_data.binary_attributes.cpu [cpu_index].processor_element_id :=
            cpu_attributes.cpu [cpu_index].element_id;
      IF pmv$cpu_data.binary_attributes.cpu [cpu_index].processor_element_id.model_number = 50(16) THEN
        pmv$cpu_data.binary_attributes.cpu [cpu_index].processor_element_id.model_number :=
               osc$cyber_180_model_9303;
      ELSEIF pmv$cpu_data.binary_attributes.cpu [cpu_index].processor_element_id.model_number = 51(16) THEN
        pmv$cpu_data.binary_attributes.cpu [cpu_index].processor_element_id.model_number :=
              osc$cyber_180_model_9301;
      IFEND;
      pmv$cpu_data.binary_attributes.cpu [cpu_index].processor_state := cpu_attributes.cpu [cpu_index].state;

      search_data.search_mode := osc$psm_by_real_model_number;
      search_data.real_model_number :=
            pmv$cpu_data.binary_attributes.cpu [cpu_index].processor_element_id.model_number;
      osp$get_cpu_model_definition (search_data, definition_found, processor_model_definition);
      pmv$cpu_data.pseudo_model_number [cpu_index] := processor_model_definition.pseudo_model_number;

      IF cpu_index < cpu_attributes.count THEN

        { Assign the processor model type.  The model type for all cpus is defined to be the same as the
        { global processor's model type.

        IF pmv$cpu_data.attributes.highest_defined_cpu_number > 0 THEN
          pmv$cpu_data.attributes.cpu [cpu_index].model_type :=
                global_processor_model_def.multiple_processor_model_type;
        ELSE
          pmv$cpu_data.attributes.cpu [cpu_index].model_type :=
                global_processor_model_def.processor_model_type;
        IFEND;

        { Assign the processor model number string.

        pmv$cpu_data.attributes.cpu [cpu_index].model_number :=
              global_processor_model_def.model_number_string;

        { Convert the integer serial number into a serial number string and convert the leading zeros to
        { blanks.

        converter.serial_number :=
              pmv$cpu_data.binary_attributes.cpu [cpu_index].processor_element_id.serial_number;
        FOR serial_number_index := 1 TO pmc$processor_serial_num_size DO
          pmv$cpu_data.attributes.cpu [cpu_index].serial_number (serial_number_index) :=
                $CHAR (converter.serial_number_array [serial_number_index] + $INTEGER ('0'));
        FOREND;
        WHILE pmv$cpu_data.attributes.cpu [cpu_index].serial_number (1) = '0' DO
          FOR serial_number_index := 1 TO pmc$processor_serial_num_size - 1 DO
            pmv$cpu_data.attributes.cpu [cpu_index].serial_number (serial_number_index) :=
                  pmv$cpu_data.attributes.cpu [cpu_index].serial_number (serial_number_index + 1);
          FOREND;
          pmv$cpu_data.attributes.cpu [cpu_index].serial_number (pmc$processor_serial_num_size) := ' ';
        WHILEND;

        { Retrieve the state of the processor.

        IF pmv$cpu_data.binary_attributes.cpu [cpu_index].processor_state = cmc$on THEN
          pmv$cpu_data.attributes.cpu [cpu_index].state := pmc$processor_state_on;
        ELSEIF pmv$cpu_data.binary_attributes.cpu [cpu_index].processor_state = cmc$off THEN
          pmv$cpu_data.attributes.cpu [cpu_index].state := pmc$processor_state_off;
        ELSE
          pmv$cpu_data.attributes.cpu [cpu_index].state := pmc$processor_state_down;
        IFEND;

      ELSE
        pmv$cpu_data.attributes.cpu [cpu_index].model_type := '';
        pmv$cpu_data.attributes.cpu [cpu_index].model_number := '';
        pmv$cpu_data.attributes.cpu [cpu_index].serial_number := '';
        pmv$cpu_data.attributes.cpu [cpu_index].state := '';
      IFEND;
    FOREND;

    serial_number := pmv$cpu_data.attributes.cpu [0].serial_number;
    model_number := pmv$cpu_data.attributes.cpu [0].model_number;
    change_space_to_zero (serial_number);
    change_space_to_zero (model_number);

    mainframe_id_index := 1;
    pmv$mainframe_id (mainframe_id_index, c$mainframe_id_prefix_size) := c$mainframe_id_prefix;
    mainframe_id_index := mainframe_id_index + c$mainframe_id_prefix_size;
    pmv$mainframe_id (mainframe_id_index, pmc$processor_model_number_size) := model_number;
    mainframe_id_index := mainframe_id_index + pmc$processor_model_number_size;
    pmv$mainframe_id (mainframe_id_index, 1) := '_';
    mainframe_id_index := mainframe_id_index + 1;
    pmv$mainframe_id (mainframe_id_index, pmc$processor_serial_num_size) := serial_number;

  PROCEND pmp$initialize_cpu_attributes;
?? OLDTITLE ??
MODEND pmm$program_services_ring_1;
