#include <configurations/vm.h>

import <std_connector.camkes>;
import <global-connectors.camkes>;
import <seL4VMDTBPassthrough.idl4>;
import <FileServerInterface.camkes>;
import <FileServer/FileServer.camkes>;
import <SerialServer/SerialServer.camkes>;
import <TimeServer/TimeServer.camkes>;
import <vm-connectors.camkes>;
import <devices.camkes>;
// import <WasmServer/WasmServer.camkes>
#define FIRST_CROSS_VM_BADGE (1 << 3)

struct vswitch_mapping {
       string mac_addr;
       int send_id;
       int recv_id;
};

component Wasmc {
    control;
    consumes Ready ready;
    emits Done done;
    dataport Buf(4096) dest;
    dataport Buf(4096) src;
}
component TimeClient {
     control;
     uses Timer timeout;
}
component VM {
    /*
    VM_INIT_DEF()
    control; \
    uses FileServerInterface fs; \
    DEF_TK1DEVICEFWD \
    DEF_KERNELARMPLATFORM_EXYNOS5410 \
    maybe consumes restart restart_event; \
    has semaphore vm_sem; \
    maybe uses Batch batch; \
    maybe uses PutChar guest_putchar; \
    maybe uses GetChar serial_getchar; \
    maybe uses VirtQueueDev recv; \
    maybe uses VirtQueueDrv send; \
    consumes HaveNotification notification_ready; \
    emits HaveNotification notification_ready_connector; \
    maybe uses VMDTBPassthrough dtb_self; \
    provides VMDTBPassthrough dtb; \
    attribute int base_prio; \
    attribute int num_vcpus = 1; \
    attribute int num_extra_frame_caps; \
    attribute int extra_frame_map_address; \
    attribute { \
        string linux_ram_base; \
        string linux_ram_paddr_base; \
        string linux_ram_size; \
        string linux_ram_offset; \
        string dtb_addr; \
        string initrd_max_size; \
        string initrd_addr; \
    } linux_address_config; \
    attribute { \
        string linux_name = "linux"; \
        string dtb_name = "linux-dtb"; \
        string initrd_name = "linux-initrd"; \
        string linux_bootcmdline = ""; \
        string linux_stdout = ""; \
    } linux_image_config; \
    
    */
    VM_INIT_DEF()
    maybe uses VirtQueueDev recv1;
    maybe uses VirtQueueDrv send1;
    maybe uses VirtQueueDev recv2;
    maybe uses VirtQueueDrv send2;
    attribute vswitch_mapping vswitch_layout[] = [];
    attribute string vswitch_mac_address = "";
    //vm wasmc dataport 
    maybe dataport Buf(4096) crossvm_dp_0;
    maybe dataport Buf(4096) crossvm_dp_1;
    emits Ready ready;
    maybe consumes Done done;

    //vm timer connection
    uses Timer vm_timeout;


}


assembly {
    composition {

        /* Boilerplate composition settings */
        VM_GENERAL_COMPOSITION_DEF()  // component FileServer fserv;

        /* Other standard VM defintions (vm0, vm1, vm1) */
        /* 
        component VM vm##num; 
        connection seL4RPCDataport fs##num(from vm##num.fs, to fserv.fs_ctrl);
        connection seL4GlobalAsynch notify_ready_vm##num(from vm##num.notification_ready_connector, to vm##num.notification_ready); 
        */
        VM_COMPOSITION_DEF(0)
        VM_COMPOSITION_DEF(1)
        VM_COMPOSITION_DEF(2)
        //wasmc
        component Wasmc wasmc;
        component Wasmc wasmc1;
        component Wasmc wasmc2;
        /* vm0,vm1 & vm2 serial connections */
        VM_VIRTUAL_SERIAL_COMPOSITION_DEF(0,1,2) //contain a timeserver
                /*Timeserver*/
        //component TimeServer time_server;
        //timer-client TimeServer connection
        component TimeClient time_client;
        connection seL4TimeServer client_timer(from time_client.timeout,
                                               to   time_server.the_timer);
        //timeserver vm connection
        connection seL4TimeServer vm0_timer(from vm0.vm_timeout,
                                               to   time_server.the_timer);
        connection seL4TimeServer vm1_timer(from vm1.vm_timeout,
                                               to   time_server.the_timer);
        connection seL4TimeServer vm2_timer(from vm2.vm_timeout,
                                               to   time_server.the_timer);
        
        // component WasmServer wserv;
        /* vm0-[vm1,vm2] connection */
        component VirtQueueInit vm1_vm0;
        component VirtQueueInit vm2_vm0;
        connection seL4VirtQueues vm1_vm0_conn(to vm1_vm0.init, from vm0.send1, from vm0.recv1, from vm1.send1, from vm1.recv1);
        connection seL4VirtQueues vm2_vm0_conn(to vm2_vm0.init, from vm0.recv2, from vm0.send2, from vm2.recv1, from vm2.send1);

        //wasmc vm0 connection
        connection seL4Notification event_conn_0(from vm0.ready,
                                             to wasmc.ready);
        connection seL4GlobalAsynch event_conn_1(from wasmc.done,
                                             to vm0.done);
        connection seL4SharedDataWithCaps cross_vm_conn_0(from wasmc.dest,
                                                              to vm0.crossvm_dp_0);
        connection seL4SharedDataWithCaps cross_vm_conn_1(from wasmc.src,
                                                              to vm0.crossvm_dp_1);

        //wasmc vm0 connection
        connection seL4Notification event_conn_01(from vm1.ready,
                                             to wasmc1.ready);
        connection seL4GlobalAsynch event_conn_11(from wasmc1.done,
                                             to vm1.done);
        connection seL4SharedDataWithCaps cross_vm_conn_01(from wasmc1.dest,
                                                              to vm1.crossvm_dp_0);
        connection seL4SharedDataWithCaps cross_vm_conn_11(from wasmc1.src,
                                                              to vm1.crossvm_dp_1);                                                      
       //wasmc vm0 connection
        connection seL4Notification event_conn_02(from vm2.ready,
                                             to wasmc2.ready);
        connection seL4GlobalAsynch event_conn_12(from wasmc2.done,
                                             to vm2.done);
        connection seL4SharedDataWithCaps cross_vm_conn_02(from wasmc2.dest,
                                                              to vm2.crossvm_dp_0);
        connection seL4SharedDataWithCaps cross_vm_conn_12(from wasmc2.src,
                                                              to vm2.crossvm_dp_1);
        /* DTB Passthrough */
        connection seL4VMDTBPassthrough vm0_dtb(from vm0.dtb_self, to vm0.dtb);
        connection seL4VMDTBPassthrough vm1_dtb(from vm1.dtb_self, to vm1.dtb);
        connection seL4VMDTBPassthrough vm2_dtb(from vm2.dtb_self, to vm2.dtb);
    }
    configuration {
        VM_GENERAL_CONFIGURATION_DEF()
        VM_CONFIGURATION_DEF(0)
        VM_CONFIGURATION_DEF(1)
        VM_CONFIGURATION_DEF(2)
        VM_VIRTUAL_SERIAL_CONFIGURATION_DEF(0,1,2)

        vm0.num_extra_frame_caps = 0;
        vm0.extra_frame_map_address = 0;
        vm0.cnode_size_bits = 18;
        vm0.simple_untyped21_pool = 12;
        vm0.simple_untyped12_pool = 12;
        vm0.vswitch_mac_address = "02:00:00:00:AA:01";
        vm0.vswitch_layout = [{"mac_addr": "02:00:00:00:AA:02", "recv_id": 0, "send_id":1},
                              {"mac_addr": "02:00:00:00:AA:03", "recv_id": 2, "send_id":3}];

        vm1.num_extra_frame_caps = 0;
        vm1.extra_frame_map_address = 0;
        vm1.cnode_size_bits = 18;
        vm1.simple_untyped21_pool = 12;
        vm1.simple_untyped12_pool = 12;
        vm1.vswitch_mac_address = "02:00:00:00:AA:02";
        vm1.vswitch_layout = [{"mac_addr": "02:00:00:00:AA:01", "recv_id": 0, "send_id":1}];

        vm2.num_extra_frame_caps = 0;
        vm2.extra_frame_map_address = 0;
        vm2.cnode_size_bits = 18;
        vm2.simple_untyped21_pool = 12;
        vm2.simple_untyped12_pool = 12;
        vm2.vswitch_mac_address = "02:00:00:00:AA:03";
        vm2.vswitch_layout = [{"mac_addr": "02:00:00:00:AA:01", "recv_id": 0, "send_id":1}];

        /* VM0-VM1 virtqueue configurations */
        vm0.recv1_id = 0;
        vm0.recv1_shmem_size = 8192;
        vm0.send1_id = 1;
        vm0.send1_shmem_size = 8192;
        /* VM0-VM2 virtqueue configurations */
        vm0.recv2_id = 2;
        vm0.recv2_shmem_size = 8192;
        vm0.send2_id = 3;
        vm0.send2_shmem_size = 8192;

        /* VM1 virtqueue configurations */
        vm1.recv1_id = 0;
        vm1.recv1_shmem_size = 8192;
        vm1.send1_id = 1;
        vm1.send1_shmem_size = 8192;

        /* VM2 virtqueue configurations */
        vm2.recv1_id = 0;
        vm2.recv1_shmem_size = 8192;
        vm2.send1_id = 1;
        vm2.send1_shmem_size = 8192;

        /* Virtqueue Topology */
        vm1_vm0.init_topology = [{ "drv" : "vm0.send1", "dev" : "vm1.recv1"},
                                 { "drv" : "vm1.send1", "dev" : "vm0.recv1"}];

        vm2_vm0.init_topology = [{ "drv" : "vm0.send2", "dev" : "vm2.recv1"},
                                 { "drv" : "vm2.send1", "dev" : "vm0.recv2"}];
        //config wasmc heap size
        wasmc.heap_size=0x10000000;
        //Timeserver
        //time_server.timers_per_client = 1;

    }
}解释代码