<!--
  Muen system policy for a basic NetHSM system.

  TODO: Consider dropping dependency on or using a copy of upstream's
  mirageos/cspec_src.xml, in order to be 100% self-contained?
-->
<system>
  <config>
    <boolean name="xhcidbg_enabled" value="false"/>
    <boolean name="dbgserver_serial_enabled" value="true"/>
    <boolean name="dbgserver_sink_pcspkr" value="false"/>
    <boolean name="dbgserver_sink_shmem" value="false"/>
    <boolean name="pciconf_emulation_enabled" value="false"/>
    <boolean name="ahci_drv_active" value="false"/>
    <string name="logchannel_size" value="16#0002_0000#"/>
  </config>
  <include href="common_expressions.xml"/>
  <memory>
    <include href="common_memory.xml"/>
  </memory>
  <deviceDomains>
    <include href="common_device_domains.xml"/>
  </deviceDomains>
  <events>
    <event name="resume_linux_1" mode="switch"/>
    <event name="resume_linux_2" mode="switch"/>
    <event name="trap_to_sm_1" mode="switch"/>
    <event name="trap_to_sm_2" mode="switch"/>
    <event name="reset_linux_1" mode="switch"/>
    <event name="reset_linux_2" mode="switch"/>
    <event name="serial_irq4_linux_1" mode="async"/>
    <event name="serial_irq4_linux_2" mode="async"/>
    <event name="timer_linux_1" mode="self"/>
    <event name="timer_linux_2" mode="self"/>
    <event name="resume_unikernel_1" mode="switch"/>
    <event name="trap_to_sm_3" mode="switch"/>
    <event name="system_reboot" mode="kernel"/>
    <event name="system_poweroff" mode="kernel"/>
    <event name="system_panic" mode="kernel"/>
  </events>
  <channels>
    <channel name="time_info" size="16#1000#"/>

    <channel name="debuglog_net_external" size="$logchannel_size"/>
    <channel name="debuglog_platform" size="$logchannel_size"/>
    <channel name="debuglog_time" size="$logchannel_size"/>
    <channel name="debuglog_keyfender_sm" size="$logchannel_size"/>
    <channel name="debuglog_keyfender" size="$logchannel_size"/>

    <channel name="keyfender_external_in" size="16#0010_0000#"/>
    <channel name="keyfender_external_out" size="16#0010_0000#"/>
    <channel name="keyfender_internal_in" size="16#0010_0000#"/>
    <channel name="keyfender_internal_out" size="16#0010_0000#"/>
  </channels>
  <components>
    <!--
      Generated by solo5-muen-gencspec.py from
      <upstream policy dir>/mirageos/cspec_src.xml.
    -->
    <include href="component_unikernel.xml"/>
  </components>
  <subjects>
    <include href="subject_net_external_sm.xml"/>
    <include href="subject_platform_sm.xml"/>
    <include href="subject_time.xml"/>
    <subject name="dbgserver">
      <events>
        <source>
          <group name="vmx_exit">
            <default physical="system_panic">
              <system_panic/>
            </default>
          </group>
        </source>
      </events>
      <component ref="dbgserver">
        <map logical="log_channel1" physical="debuglog_net_external"/>
        <map logical="log_channel2" physical="debuglog_platform"/>
        <map logical="log_channel3" physical="debuglog_time"/>
        <map logical="log_channel4" physical="debuglog_keyfender_sm"/>
        <map logical="log_channel5" physical="debuglog_keyfender"/>
        <include href="subject_dbgserver_common.xml"/>
      </component>
    </subject>
    <subject name="net_external">
      <bootparams>console=ttyS0 pci=noearly uroot.uinitargs=net_external</bootparams>
      <memory>
        <memory logical="initramfs" physical="initramfs" virtualAddress="16#9000_0000#" writable="false" executable="false"/>
      </memory>
      <devices>
        <device logical="eth0" physical="ethernet_controller_1"/>
      </devices>
      <events>
        <source>
          <group name="vmx_exit">
            <default physical="trap_to_sm_1"/>
          </group>
          <group name="vmcall">
            <event id="31" logical="timer" physical="timer_linux_1"/>
          </group>
        </source>
        <target>
          <event logical="resume_after_trap" physical="resume_linux_1"/>
          <event logical="reset" physical="reset_linux_1">
            <reset/>
          </event>
          <event logical="serial_irq4" physical="serial_irq4_linux_1">
            <inject_interrupt vector="52"/>
          </event>
          <event logical="timer" physical="timer_linux_1">
            <inject_interrupt vector="236"/>
          </event>
        </target>
      </events>
      <channels>
        <writer logical="external|in" physical="keyfender_external_in" virtualAddress="16#000e_0300_0000#"/>
        <reader logical="external|out" physical="keyfender_external_out" virtualAddress="16#000e_0310_0000#"/>
      </channels>
      <component ref="linux">
        <map logical="lowmem" physical="net_external|lowmem"/>
        <map logical="ram" physical="net_external|ram"/>
      </component>
    </subject>
    <subject name="platform">
      <bootparams>console=ttyS0 pci=noearly uroot.uinitargs=platform</bootparams>
      <memory>
        <memory logical="initramfs" physical="initramfs" virtualAddress="16#9000_0000#" writable="false" executable="false"/>
        <memory logical="ram_2" physical="platform|ram_2" virtualAddress="16#0001_0000_0000#" writable="true" executable="true"/>
      </memory>
      <devices>
        <device logical="storage_controller" physical="storage_controller">
          <pci bus="16#00#" device="16#17#" function="0"/>
        </device>
        <device logical="tpm" physical="tpm">
        </device>
        <if variable="trng_available" value="true">
          <device logical="trng" physical="trng">
            <pci bus="16#00#" device="16#19#" function="2"/>
          </device>
        </if>
      </devices>
      <events>
        <source>
          <group name="vmx_exit">
            <default physical="trap_to_sm_2"/>
          </group>
          <group name="vmcall">
            <event id="31" logical="timer" physical="timer_linux_2"/>
            <event id="30" logical="poweroff" physical="system_poweroff">
              <system_poweroff/>
            </event>
            <event id="29" logical="reboot" physical="system_reboot">
              <system_reboot/>
            </event>
          </group>
        </source>
        <target>
          <event logical="resume_after_trap" physical="resume_linux_2"/>
          <event logical="reset" physical="reset_linux_2">
            <reset/>
          </event>
          <event logical="serial_irq4" physical="serial_irq4_linux_2">
            <inject_interrupt vector="52"/>
          </event>
          <event logical="timer" physical="timer_linux_2">
            <inject_interrupt vector="236"/>
          </event>
        </target>
      </events>
      <channels>
        <writer logical="internal|in" physical="keyfender_internal_in" virtualAddress="16#000e_0320_0000#"/>
        <reader logical="internal|out" physical="keyfender_internal_out" virtualAddress="16#000e_0330_0000#"/>
      </channels>
      <component ref="linux">
        <map logical="lowmem" physical="platform|lowmem"/>
        <map logical="ram" physical="platform|ram"/>
      </component>
    </subject>
    <subject name="keyfender_sm">
      <events>
        <source>
          <group name="vmx_exit">
            <default physical="system_panic">
              <system_panic/>
            </default>
          </group>
        </source>
      </events>
      <monitor>
        <state subject="keyfender" logical="monitor_state" virtualAddress="16#001e_0000#" writable="true"/>
        <loader logical="reload" subject="keyfender_sm" virtualAddress="16#0000#"/>
      </monitor>
      <component ref="sm">
        <map logical="time_info" physical="time_info"/>
        <map logical="debuglog" physical="debuglog_keyfender_sm"/>
        <map logical="resume_subject" physical="resume_unikernel_1"/>
        <map logical="handle_subject_trap" physical="trap_to_sm_3"/>
        <map logical="status" physical="status_keyfender_sm"/>
        <map logical="control" physical="control_keyfender_sm"/>
      </component>
    </subject>
    <subject name="keyfender">
      <vcpu> <!-- <vcpu> must come first -->
        <vmx>
          <controls>
            <proc>
              <!-- Enable access to full-precision RDTSC -->
              <RDTSCExiting>0</RDTSCExiting>
            </proc>
          </controls>
        </vmx>
      </vcpu>
      <bootparams></bootparams>
      <events>
        <source>
          <group name="vmx_exit">
            <default physical="trap_to_sm_3"/>
          </group>
        </source>
        <target>
          <event logical="resume_after_trap" physical="resume_unikernel_1"/>
        </target>
      </events>
      <component ref="unikernel">
        <map logical="time_info" physical="time_info"/>
        <map logical="debuglog" physical="debuglog_keyfender"/>
        <map logical="external|in" physical="keyfender_external_in"/>
        <map logical="external|out" physical="keyfender_external_out"/>
        <map logical="internal|in" physical="keyfender_internal_in"/>
        <map logical="internal|out" physical="keyfender_internal_out"/>
      </component>
    </subject>
  </subjects>
  <!--
    Static scheduling plan is included here directly, no dependency on
    upstream's policy/scheduling/...
  -->
  <scheduling tickRate="100000"> <!-- 1 tick = 10us -->
    <majorFrame>
      <cpu id="0">
        <minorFrame subject="tau0" ticks="1"/>
        <minorFrame subject="dbgserver" ticks="9"/>
        <minorFrame subject="dbgserver" ticks="10"/>
        <minorFrame subject="dbgserver" ticks="10"/>
        <minorFrame subject="dbgserver" ticks="10"/>
        <minorFrame subject="dbgserver" ticks="10"/>
        <minorFrame subject="dbgserver" ticks="10"/>
        <minorFrame subject="dbgserver" ticks="10"/>
        <minorFrame subject="dbgserver" ticks="10"/>
        <minorFrame subject="dbgserver" ticks="10"/>
        <minorFrame subject="dbgserver" ticks="10"/>
      </cpu>
      <cpu id="1">
        <minorFrame subject="net_external" ticks="10"/>
        <minorFrame subject="net_external" ticks="10"/>
        <minorFrame subject="net_external" ticks="10"/>
        <minorFrame subject="net_external" ticks="10"/>
        <minorFrame subject="net_external" ticks="10"/>
        <minorFrame subject="net_external" ticks="10"/>
        <minorFrame subject="net_external" ticks="10"/>
        <minorFrame subject="net_external" ticks="10"/>
        <minorFrame subject="net_external" ticks="10"/>
        <minorFrame subject="net_external" ticks="10"/>
      </cpu>
      <cpu id="2">
        <minorFrame subject="keyfender" ticks="10"/>
        <minorFrame subject="keyfender" ticks="10"/>
        <minorFrame subject="keyfender" ticks="10"/>
        <minorFrame subject="keyfender" ticks="10"/>
        <minorFrame subject="keyfender" ticks="10"/>
        <minorFrame subject="keyfender" ticks="10"/>
        <minorFrame subject="keyfender" ticks="10"/>
        <minorFrame subject="keyfender" ticks="10"/>
        <minorFrame subject="keyfender" ticks="10"/>
        <minorFrame subject="keyfender" ticks="10"/>
      </cpu>
      <cpu id="3">
        <minorFrame subject="platform" ticks="10"/>
        <minorFrame subject="platform" ticks="10"/>
        <minorFrame subject="platform" ticks="10"/>
        <minorFrame subject="platform" ticks="10"/>
        <minorFrame subject="platform" ticks="10"/>
        <minorFrame subject="platform" ticks="10"/>
        <minorFrame subject="platform" ticks="10"/>
        <minorFrame subject="platform" ticks="10"/>
        <minorFrame subject="platform" ticks="10"/>
        <minorFrame subject="platform" ticks="10"/>
      </cpu>
    </majorFrame>
    <majorFrame>
      <cpu id="0">
        <minorFrame subject="time" ticks="1"/>
        <minorFrame subject="dbgserver" ticks="9"/>
        <minorFrame subject="dbgserver" ticks="10"/>
        <minorFrame subject="dbgserver" ticks="10"/>
        <minorFrame subject="dbgserver" ticks="10"/>
        <minorFrame subject="dbgserver" ticks="10"/>
        <minorFrame subject="dbgserver" ticks="10"/>
        <minorFrame subject="dbgserver" ticks="10"/>
        <minorFrame subject="dbgserver" ticks="10"/>
        <minorFrame subject="dbgserver" ticks="10"/>
        <minorFrame subject="dbgserver" ticks="10"/>
      </cpu>
      <cpu id="1">
        <minorFrame subject="net_external" ticks="10"/>
        <minorFrame subject="net_external" ticks="10"/>
        <minorFrame subject="net_external" ticks="10"/>
        <minorFrame subject="net_external" ticks="10"/>
        <minorFrame subject="net_external" ticks="10"/>
        <minorFrame subject="net_external" ticks="10"/>
        <minorFrame subject="net_external" ticks="10"/>
        <minorFrame subject="net_external" ticks="10"/>
        <minorFrame subject="net_external" ticks="10"/>
        <minorFrame subject="net_external" ticks="10"/>
      </cpu>
      <cpu id="2">
        <minorFrame subject="keyfender" ticks="10"/>
        <minorFrame subject="keyfender" ticks="10"/>
        <minorFrame subject="keyfender" ticks="10"/>
        <minorFrame subject="keyfender" ticks="10"/>
        <minorFrame subject="keyfender" ticks="10"/>
        <minorFrame subject="keyfender" ticks="10"/>
        <minorFrame subject="keyfender" ticks="10"/>
        <minorFrame subject="keyfender" ticks="10"/>
        <minorFrame subject="keyfender" ticks="10"/>
        <minorFrame subject="keyfender" ticks="10"/>
      </cpu>
      <cpu id="3">
        <minorFrame subject="platform" ticks="10"/>
        <minorFrame subject="platform" ticks="10"/>
        <minorFrame subject="platform" ticks="10"/>
        <minorFrame subject="platform" ticks="10"/>
        <minorFrame subject="platform" ticks="10"/>
        <minorFrame subject="platform" ticks="10"/>
        <minorFrame subject="platform" ticks="10"/>
        <minorFrame subject="platform" ticks="10"/>
        <minorFrame subject="platform" ticks="10"/>
        <minorFrame subject="platform" ticks="10"/>
      </cpu>
    </majorFrame>
  </scheduling>
</system>
