?? RIGHT := 110 ??
?? NEWTITLE := 'NOS/VE: Program Control - Monitor Faults' ??
MODULE tmm$manage_monitor_faults;

{ PURPOSE:
{   The purpose of this module is execute with the privileges necessary
{   to read the monitor fault buffers in the oss$job_fixed section and to
{   modify monitor fault structures in the oss$task_private section.
{
{ DESIGN:
{   The procedures in the module have an execution bracket of 2, 3 and
{   a call bracket of 13.

?? NEWTITLE := 'Global Declarations Referenced by This Module', EJECT ??
?? PUSH (LISTEXT := ON) ??
*copyc osd$code_base_pointer
*copyc osd$virtual_address
*copyc oss$job_paged_literal
*copyc oss$task_private
*copyc ost$execution_control_block
*copyc ost$stack_frame_save_area
*copyc ost$status
*copyc pmt$condition
*copyc pme$define_handler_exceptions
*copyc pme$exec_call_bracket_error
*copyc tmt$monitor_fault_buffer
*copyc tmt$monitor_fault_handler
?? POP ??
*copyc i#disable_traps
*copyc i#restore_traps
*copyc mmp$fetch_segment_attributes
*copyc mmp$segment_fault_handler
*copyc osp$set_status_abnormal
*copyc osp$verify_system_privilege
*copyc pmp$dispose_mcr_conditions
*copyc pmp$find_executing_task_xcb
*copyc tmp$dispose_of_broken_task
*copyc tmp$dispose_system_req_fault
*copyc tmp$get_monitor_fault
?? OLDTITLE ??
?? NEWTITLE := 'Global Declarations Declared by This Module', EJECT ??

  VAR
    tmv$monitor_fault_handler: [STATIC, READ, oss$job_paged_literal] array [0 .. osc$max_fault_id] of
          tmt$monitor_fault_handler := [NIL, ^tmp$dispose_of_broken_task, ^pmp$dispose_mcr_conditions,
          ^mmp$segment_fault_handler, NIL, ^tmp$dispose_system_req_fault, NIL, REP
          (osc$max_fault_id - tmc$last_fault_id_assigned) of NIL],

    tmv$monitor_fault_trapped_sfsa: [STATIC, oss$task_private] array [tmt$monitor_fault_buffers] of
          ^ost$stack_frame_save_area := [REP tmc$maximum_monitor_faults of NIL];

?? OLDTITLE ??
?? NEWTITLE := '[XDCL, #GATE] tmp$find_monitor_fault', EJECT ??
*copy tmh$find_monitor_fault

  PROCEDURE [XDCL, #GATE] tmp$find_monitor_fault
    (    sfsa: ^ost$stack_frame_save_area;
     VAR fault: ost$monitor_fault;
     VAR fault_found: boolean;
     VAR monitor_fault_handler: tmt$monitor_fault_handler);

    VAR
      fault_status: tmt$fault_status,
      fault_index: 1 .. (tmc$maximum_monitor_faults + 1),
      trap_enables: 0 .. 3,
      xcb_p: ^ost$execution_control_block;

    osp$verify_system_privilege;
    fault_found := FALSE;
    fault_index := LOWERVALUE (tmt$monitor_fault_buffers);
    pmp$find_executing_task_xcb (xcb_p);
    i#disable_traps (trap_enables);

    WHILE NOT fault_found AND (fault_index <= UPPERVALUE (tmt$monitor_fault_buffers)) DO
      IF ((xcb_p^.monitor_faults.present [fault_index]) AND
            (#SEGMENT (tmv$monitor_fault_trapped_sfsa [fault_index]) = #SEGMENT (sfsa)) AND
            (#OFFSET (tmv$monitor_fault_trapped_sfsa [fault_index]) = #OFFSET (sfsa))) THEN
        tmp$get_monitor_fault (fault_index, fault, fault_status);
        CASE fault_status OF
        = tmc$normal_fault_status =
          fault_found := TRUE;
          monitor_fault_handler := tmv$monitor_fault_handler [$INTEGER (fault.identifier)];
          tmv$monitor_fault_trapped_sfsa [fault_index] := NIL;
        = tmc$no_fault_present =
          ;
        = tmc$invalid_fault_index =
          ;
        ELSE
        CASEND;
      IFEND;
      fault_index := fault_index + 1;
    WHILEND;
    i#restore_traps (trap_enables);
  PROCEND tmp$find_monitor_fault;
?? OLDTITLE ??
?? TITLE := '[XDCL, #GATE] tmp$post_monitor_fault_sfsa', EJECT ??
*copy tmh$post_monitor_fault_sfsa

  PROCEDURE [XDCL, #GATE] tmp$post_monitor_fault_sfsa
    (    sfsa: ^ost$stack_frame_save_area;
     VAR monitor_fault_present: boolean);

    VAR
      fault_index: tmt$monitor_fault_buffers,
      xcb_p: ^ost$execution_control_block;

    osp$verify_system_privilege;
    monitor_fault_present := FALSE;
    pmp$find_executing_task_xcb (xcb_p);
    FOR fault_index := LOWERVALUE (tmt$monitor_fault_buffers) TO UPPERVALUE (tmt$monitor_fault_buffers) DO
      IF (xcb_p^.monitor_faults.present [fault_index] AND (tmv$monitor_fault_trapped_sfsa [fault_index] =
            NIL)) THEN
        tmv$monitor_fault_trapped_sfsa [fault_index] := sfsa;
        monitor_fault_present := TRUE;
      IFEND;
    FOREND;
  PROCEND tmp$post_monitor_fault_sfsa;
?? OLDTITLE ??
MODEND tmm$manage_monitor_faults;
