OpenCores
URL https://opencores.org/ocsvn/ao486/ao486/trunk

Subversion Repositories ao486

[/] [ao486/] [trunk/] [rtl/] [ao486/] [commands/] [CMD_CALL.txt] - Rev 2

Compare with Previous | Blame | View Log


<defines>

//------------------------------------------------------------------------------
`define CMD_CALL        #AUTOGEN_NEXT_CMD

`define CMDEX_CALL_Ev_STEP_0                4'd0
`define CMDEX_CALL_Jv_STEP_0                4'd1
`define CMDEX_CALL_Ep_STEP_0                4'd2
`define CMDEX_CALL_Ap_STEP_0                4'd3

`define CMDEX_CALL_Ev_Jv_STEP_1             4'd4

`define CMDEX_CALL_Ep_STEP_1                4'd5
`define CMDEX_CALL_Ap_STEP_1                4'd6

`define CMDEX_CALL_real_v8086_STEP_0        4'd7
`define CMDEX_CALL_real_v8086_STEP_1        4'd8
`define CMDEX_CALL_real_v8086_STEP_2        4'd9
`define CMDEX_CALL_real_v8086_STEP_3        4'd10

`define CMDEX_CALL_protected_STEP_0         4'd11
`define CMDEX_CALL_protected_STEP_1         4'd12

`define CMDEX_CALL_protected_seg_STEP_0     4'd13
`define CMDEX_CALL_protected_seg_STEP_1     4'd14
`define CMDEX_CALL_protected_seg_STEP_2     4'd15

//------------------------------------------------------------------------------
`define CMD_CALL_2      #AUTOGEN_NEXT_CMD

`define CMDEX_CALL_2_protected_seg_STEP_3   4'd0
`define CMDEX_CALL_2_protected_seg_STEP_4   4'd1

`define CMDEX_CALL_2_task_switch_STEP_0     4'd2

`define CMDEX_CALL_2_task_gate_STEP_0       4'd3
`define CMDEX_CALL_2_task_gate_STEP_1       4'd4

`define CMDEX_CALL_2_call_gate_STEP_0       4'd5
// glob_param_1[15:0]  -- CS selector
// glob_param_1[18:16] -- CS segment type
// glob_param_1[19]    -- 0: 286, 1: 386 CALL GATE
// glob_param_1[24:20] -- param count
// glob_param_2        -- eip

// glob_descriptor -- new cs descriptor

`define CMDEX_CALL_2_call_gate_STEP_1       4'd6
`define CMDEX_CALL_2_call_gate_STEP_2       4'd7

`define CMDEX_CALL_2_call_gate_same_STEP_0  4'd8
`define CMDEX_CALL_2_call_gate_same_STEP_1  4'd9
`define CMDEX_CALL_2_call_gate_same_STEP_2  4'd10
`define CMDEX_CALL_2_call_gate_same_STEP_3  4'd11

`define CMDEX_CALL_2_call_gate_more_STEP_0  4'd12
`define CMDEX_CALL_2_call_gate_more_STEP_1  4'd13
// glob_param_1[15:0]  -- CS selector
// glob_param_1[18:16] -- CS segment type
// glob_param_1[19]    -- 0: 286, 1: 386 CALL GATE
// glob_param_1[24:20] -- param count
// glob_param_2        -- eip
// glob_param_3[15:0]  -- new ss
// glob_param_4        -- new esp

// glob_descriptor -- new cs descriptor

//after exe:
// glob_param_1[15:0]  -- new ss
// glob_param_1[18:16] -- SS type
// glob_param_2        -- new eip
// glob_param_3        -- cs selector, type, call gate type, call gate param
// glob_param_4        -- new esp

// glob_descriptor_2   -- new cs descriptor

`define CMDEX_CALL_2_call_gate_more_STEP_2  4'd14
`define CMDEX_CALL_2_call_gate_more_STEP_3  4'd15

//------------------------------------------------------------------------------
`define CMD_CALL_3      #AUTOGEN_NEXT_CMD

`define CMDEX_CALL_3_call_gate_more_STEP_4  4'd0
// copy parameters - first
`define CMDEX_CALL_3_call_gate_more_STEP_5  4'd1
// copy parameters - second

`define CMDEX_CALL_3_call_gate_more_STEP_6  4'd2
// write return_CS
`define CMDEX_CALL_3_call_gate_more_STEP_7  4'd3
// write return_EIP; save esp

`define CMDEX_CALL_3_call_gate_more_STEP_8  4'd4
// check new_eip; load_ss()

`define CMDEX_CALL_3_call_gate_more_STEP_9  4'd5
// move glob_param,descriptor for cs save
// load_cs()

// glob_param_1[15:0]  -- new cs
// glob_param_1[18:16] -- CS type
// glob_param_2        -- new eip
// glob_descriptor -- new cs descriptor

`define CMDEX_CALL_3_call_gate_more_STEP_10 4'd6
// reset pipeline; save eip 
</defines>

<decode>
dec_ready_call_jmp_imm && (decoder[7:0] == 8'h9A || decoder[7:0] == 8'hE8)
`CMD_CALL
IF(decoder[1] == 1'b0); SET(dec_cmdex, `CMDEX_CALL_Jv_STEP_0); ELSE(); SET(dec_cmdex, `CMDEX_CALL_Ap_STEP_0); ENDIF();
SET(consume_call_jmp_imm);
SET(dec_is_complex);
</decode>

<decode>
dec_ready_modregrm_one && decoder[7:0] == 8'hFF && (decoder[13:11] == 3'd2 || decoder[13:11] == 3'd3)
prefix_group_1_lock || (decoder[13:11] == 3'd3 && `DEC_MODREGRM_IS_MOD_11)
`CMD_CALL
IF(decoder[11] == 1'b0); SET(dec_cmdex, `CMDEX_CALL_Ev_STEP_0); ELSE(); SET(dec_cmdex, `CMDEX_CALL_Ep_STEP_0); ENDIF();
SET(consume_modregrm_one);
SET(dec_is_complex);
</decode>

<microcode>
IF(`CMDEX_CALL_Ev_STEP_0);
    LOOP(`CMDEX_CALL_Ev_Jv_STEP_1);
ENDIF();

IF(`CMDEX_CALL_Jv_STEP_0);
    LOOP(`CMDEX_CALL_Ev_Jv_STEP_1);
ENDIF();

IF(`CMDEX_CALL_Ep_STEP_0);
    `CMDEX_CALL_Ep_STEP_1
ENDIF();

IF(`CMDEX_CALL_Ap_STEP_0);
    `CMDEX_CALL_Ap_STEP_1
ENDIF();

IF(mc_cmd == `CMD_CALL && (mc_cmdex_last == `CMDEX_CALL_Ep_STEP_1 || mc_cmdex_last == `CMDEX_CALL_Ap_STEP_1) && (real_mode || v8086_mode));
    `CMDEX_CALL_real_v8086_STEP_0
    `CMDEX_CALL_real_v8086_STEP_1
    `CMDEX_CALL_real_v8086_STEP_2
    CALL(`CMDEX_load_seg_STEP_1);
    LOOP(`CMDEX_CALL_real_v8086_STEP_3);
ENDIF();

IF(mc_cmd == `CMD_CALL && (mc_cmdex_last == `CMDEX_CALL_Ep_STEP_1 || mc_cmdex_last == `CMDEX_CALL_Ap_STEP_1) && (protected_mode));
    `CMDEX_CALL_protected_STEP_0
    `CMDEX_CALL_protected_STEP_1
    
    IF(`CMDEX_CALL_protected_STEP_1 && glob_descriptor[`DESC_BIT_SEG]);
        `CMDEX_CALL_protected_seg_STEP_0
        `CMDEX_CALL_protected_seg_STEP_1
        `CMDEX_CALL_protected_seg_STEP_2
        `CMDEX_CALL_2_protected_seg_STEP_3
        LOOP(`CMDEX_CALL_2_protected_seg_STEP_4);
    ENDIF();

    IF(`CMDEX_CALL_protected_STEP_1 && glob_descriptor[`DESC_BIT_SEG] == `FALSE && (glob_descriptor[`DESC_BITS_TYPE] == `DESC_TSS_AVAIL_386 || glob_descriptor[`DESC_BITS_TYPE] == `DESC_TSS_AVAIL_286));
        `CMDEX_CALL_2_task_switch_STEP_0
        
        //zero length
        IF(`CMDEX_CALL_2_task_switch_STEP_0 && glob_param_3[21:18] == 4'd0);
            `CMDEX_CALL_2_task_switch_STEP_0
        ENDIF();
        
        //not zero length
        IF(`CMDEX_CALL_2_task_switch_STEP_0 && glob_param_3[21:18] != 4'd0);
            JMP(`CMDEX_task_switch_STEP_1);
        ENDIF();
    ENDIF();
    
    IF(`CMDEX_CALL_protected_STEP_1 && glob_descriptor[`DESC_BIT_SEG] == `FALSE && glob_descriptor[`DESC_BITS_TYPE] == `DESC_TASK_GATE);
        `CMDEX_CALL_2_task_gate_STEP_0
        `CMDEX_CALL_2_task_gate_STEP_1
        JMP(`CMDEX_task_switch_STEP_1);
    ENDIF();
    
    IF(`CMDEX_CALL_protected_STEP_1 && glob_descriptor[`DESC_BIT_SEG] == `FALSE && (glob_descriptor[`DESC_BITS_TYPE] == `DESC_CALL_GATE_386 || glob_descriptor[`DESC_BITS_TYPE] == `DESC_CALL_GATE_286));
        `CMDEX_CALL_2_call_gate_STEP_0
        `CMDEX_CALL_2_call_gate_STEP_1
        `CMDEX_CALL_2_call_gate_STEP_2
        
        IF(`CMDEX_CALL_2_call_gate_STEP_2 && `DESC_IS_CODE_NON_CONFORMING(glob_descriptor) && glob_descriptor[`DESC_BITS_DPL] < cpl);
            `CMDEX_CALL_2_call_gate_more_STEP_0
            `CMDEX_CALL_2_call_gate_more_STEP_1
            `CMDEX_CALL_2_call_gate_more_STEP_2
            `CMDEX_CALL_2_call_gate_more_STEP_3
            
            IF(`CMDEX_CALL_2_call_gate_more_STEP_3 && glob_param_3[24:20] != 5'd0);
                `CMDEX_CALL_3_call_gate_more_STEP_4
                
                IF(`CMDEX_CALL_3_call_gate_more_STEP_4 && glob_param_3[24:20] == 5'd1);
                    `CMDEX_CALL_3_call_gate_more_STEP_6
                ENDIF();
                
                IF(`CMDEX_CALL_3_call_gate_more_STEP_4 && glob_param_3[24:20] != 5'd1);
                    `CMDEX_CALL_3_call_gate_more_STEP_5
                    
                    IF(`CMDEX_CALL_3_call_gate_more_STEP_5 && glob_param_3[24:20] == 5'd1);
                        `CMDEX_CALL_3_call_gate_more_STEP_6
                    ENDIF();
                    
                    IF(`CMDEX_CALL_3_call_gate_more_STEP_5 && glob_param_3[24:20] != 5'd1);
                        `CMDEX_CALL_3_call_gate_more_STEP_5
                    ENDIF();
            ENDIF();
            
            IF(`CMDEX_CALL_2_call_gate_more_STEP_3 && glob_param_3[24:20] == 5'd0);
                `CMDEX_CALL_3_call_gate_more_STEP_6
            ENDIF();
            
            IF(`CMDEX_CALL_3_call_gate_more_STEP_6);
                `CMDEX_CALL_3_call_gate_more_STEP_7
                `CMDEX_CALL_3_call_gate_more_STEP_8
                `CMDEX_CALL_3_call_gate_more_STEP_9
                LOOP(`CMDEX_CALL_3_call_gate_more_STEP_10);
            ENDIF();
        ENDIF();
        
        IF(`CMDEX_CALL_2_call_gate_STEP_2 && ~(`DESC_IS_CODE_NON_CONFORMING(glob_descriptor) && glob_descriptor[`DESC_BITS_DPL] < cpl));
            `CMDEX_CALL_2_call_gate_same_STEP_0
            `CMDEX_CALL_2_call_gate_same_STEP_1
            `CMDEX_CALL_2_call_gate_same_STEP_2
            LOOP(`CMDEX_CALL_2_call_gate_same_STEP_3);
        ENDIF();
    ENDIF();
ENDIF();
</microcode>

<read_local>
wire [4:0] rd_call_gate_param;

assign rd_call_gate_param = glob_param_3[24:20] - 5'd1;
</read_local>

<read>
IF(rd_cmd == `CMD_CALL && rd_cmdex == `CMDEX_CALL_Ev_STEP_0);
    
    IF(rd_modregrm_mod == 2'b11);
    
        SET(rd_src_is_rm);
        
        IF(rd_mutex_busy_modregrm_rm); SET(rd_waiting); ENDIF();
    ENDIF();

    IF(rd_modregrm_mod != 2'b11);
        
        SET(rd_src_is_memory);
        
        IF(rd_mutex_busy_memory); SET(rd_waiting);
        ELSE();
            SET(read_virtual);

            IF(~(read_for_rd_ready)); SET(rd_waiting); ENDIF();
        ENDIF();
    ENDIF();
ENDIF();
</read>

<read>
IF(rd_cmd == `CMD_CALL && rd_cmdex == `CMDEX_CALL_Jv_STEP_0);
    SET(rd_src_is_imm);
    SET(rd_dst_is_eip);
ENDIF();
</read>

<read>
IF(rd_cmd == `CMD_CALL && (rd_cmdex == `CMDEX_CALL_Ep_STEP_0 || rd_cmdex == `CMDEX_CALL_Ep_STEP_1));
    
    IF(rd_cmdex == `CMDEX_CALL_Ep_STEP_1);
        SET(address_ea_buffer);
        SET(read_length_word);
    ENDIF();

    SET(rd_src_is_memory);
    
    IF(rd_mutex_busy_memory); SET(rd_waiting);
    ELSE();
        SET(read_virtual);

        IF(~(read_for_rd_ready)); SET(rd_waiting); ENDIF();
    ENDIF();
ENDIF();
</read>

<read>
IF(rd_cmd == `CMD_CALL && rd_cmdex == `CMDEX_CALL_Ap_STEP_0);

    SET(rd_src_is_imm);
ENDIF();
</read>

<read>
IF(rd_cmd == `CMD_CALL && rd_cmdex == `CMDEX_CALL_Ap_STEP_1);
    SET(rd_extra_wire, rd_decoder[55:24]);
ENDIF();
</read>

<read>
IF(rd_cmd == `CMD_CALL && rd_cmdex == `CMDEX_CALL_protected_STEP_0);
    
    IF(rd_mutex_busy_active); SET(rd_waiting); // wait for previous step -- loading glob_param_1
    ELSE();
    
        IF(glob_param_1[15:2] != 14'd0); // load null

            SET(rd_error_code, `SELECTOR_FOR_CODE(glob_param_1));
            
            SET(rd_glob_descriptor_set);
            SET(rd_glob_descriptor_value, read_8);

            SET(rd_glob_param_3_set);
            SET(rd_glob_param_3_value, 32'd0);

            SET(read_system_descriptor);

            IF(~(read_for_rd_ready)); SET(rd_waiting); ENDIF();
        ENDIF();
    ENDIF();
ENDIF();
</read>

<read>
IF(rd_cmd == `CMD_CALL_2 && rd_cmdex == `CMDEX_CALL_2_task_gate_STEP_0);
    
    IF(rd_mutex_busy_active); SET(rd_waiting);  // wait for previous step -- loading glob_param_1
    ELSE();
        SET(rd_glob_param_1_set);
        SET(rd_glob_param_1_value, { 16'd0, glob_descriptor[31:16] });
    ENDIF();
ENDIF();
</read>

<read>
IF(rd_cmd == `CMD_CALL_2 && rd_cmdex == `CMDEX_CALL_2_task_gate_STEP_1);

//TODO: null not checked
    IF(glob_param_1[`SELECTOR_BIT_TI] == 1'b0); // skip if TI set
        
        SET(rd_error_code, `SELECTOR_FOR_CODE(glob_param_1));
        
        SET(rd_glob_descriptor_set);
        SET(rd_glob_descriptor_value, read_8);
        
        SET(read_system_descriptor);

        IF(~(read_for_rd_ready)); SET(rd_waiting); ENDIF();
    ENDIF();
ENDIF();
</read>

<read>
IF(rd_cmd == `CMD_CALL_2 && rd_cmdex == `CMDEX_CALL_2_call_gate_STEP_1);
    
    IF(rd_mutex_busy_active); SET(rd_waiting); // wait for previous step -- loading glob_param_1
    ELSE();
    
        IF(glob_param_1[15:2] != 14'd0); // load null

            SET(rd_error_code, `SELECTOR_FOR_CODE(glob_param_1));

            SET(rd_glob_descriptor_set);
            SET(rd_glob_descriptor_value, read_8);

            SET(read_system_descriptor);

            IF(~(read_for_rd_ready)); SET(rd_waiting); ENDIF();
        ENDIF();
    ENDIF();
ENDIF();
</read>

<read>
IF(rd_cmd == `CMD_CALL_3 && (rd_cmdex == `CMDEX_CALL_3_call_gate_more_STEP_4 || rd_cmdex == `CMDEX_CALL_3_call_gate_more_STEP_5));
    
    IF(~(glob_param_3[19])); SET(read_length_word);  ENDIF();
    IF(glob_param_3[19]);    SET(read_length_dword); ENDIF();
    
    IF(rd_ready);
        SET(rd_glob_param_3_set);
        SET(rd_glob_param_3_value, { 7'd0, rd_call_gate_param, glob_param_3[19:0] });
    ENDIF();
    
    SET(address_stack_pop_for_call);
    SET(address_stack_pop_next);
    
    IF(rd_cmdex == `CMDEX_CALL_3_call_gate_more_STEP_4);
        SET(address_stack_save);
        SET(address_stack_for_call_param_first);
    ENDIF();
    
    IF(rd_mutex_busy_active); SET(rd_waiting); // waiting for esp in 'address_waiting'
    ELSE();
        
        SET(read_virtual);
        
        SET(rd_glob_param_5_set);
        SET(rd_glob_param_5_value, read_4);
        
        IF(~(read_for_rd_ready)); SET(rd_waiting); ENDIF();
    ENDIF();
ENDIF();
</read>

<execute>
IF(exe_cmd == `CMD_CALL && exe_cmdex == `CMDEX_CALL_protected_STEP_1);
    SET(offset_esp);
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL_2  && exe_cmdex == `CMDEX_CALL_2_protected_seg_STEP_3);

    IF(glob_param_2 > glob_desc_limit);
        SET(exe_waiting);
        SET(exe_trigger_gp_fault); //exception GP(0)
    ENDIF();
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL && (exe_cmdex == `CMDEX_CALL_Ev_STEP_0 || exe_cmdex == `CMDEX_CALL_Ep_STEP_0 || exe_cmdex == `CMDEX_CALL_Ap_STEP_0));
    
    IF(exe_cmdex == `CMDEX_CALL_Ev_STEP_0);
        IF(exe_mutex_current[`MUTEX_ESP_BIT]); SET(exe_waiting); ENDIF();
    
        SET(exe_result_push, exe_eip);
    ENDIF();

    IF(exe_operand_32bit);
        SET(exe_glob_param_2_set);
        SET(exe_glob_param_2_value, src);
    ELSE();
        SET(exe_glob_param_2_set);
        SET(exe_glob_param_2_value, { 16'd0, src[15:0] }); 
    ENDIF();
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL && exe_cmdex == `CMDEX_CALL_Jv_STEP_0);
    
    SET(exe_result_push, exe_eip);

    IF(exe_mutex_current[`MUTEX_ESP_BIT]); SET(exe_waiting); ENDIF();

    IF(exe_operand_32bit);
        SET(exe_glob_param_2_set);
        SET(exe_glob_param_2_value, exe_arith_add[31:0]);
    ELSE();
        SET(exe_glob_param_2_set);
        SET(exe_glob_param_2_value, { 16'd0, exe_arith_add[15:0] });
    ENDIF();
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL && exe_cmdex == `CMDEX_CALL_Ev_Jv_STEP_1);

    SET(exe_eip_from_glob_param_2);

    IF(glob_param_2 > cs_limit);
        SET(exe_waiting);
        SET(exe_trigger_gp_fault); //exception GP(0)
    ENDIF();
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL && exe_cmdex == `CMDEX_CALL_Ep_STEP_1);
    
    SET(exe_glob_param_1_set);
    SET(exe_glob_param_1_value, { 13'd0, `SEGMENT_CS, src[15:0] });
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL && exe_cmdex == `CMDEX_CALL_Ap_STEP_1);

    IF(exe_operand_32bit);
        SET(exe_glob_param_1_set);
        SET(exe_glob_param_1_value, { 13'd0, `SEGMENT_CS, exe_extra[31:16] });
    ELSE();
        SET(exe_glob_param_1_set);
        SET(exe_glob_param_1_value, { 13'd0, `SEGMENT_CS, exe_extra[15:0] });
    ENDIF();
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL && exe_cmdex == `CMDEX_CALL_real_v8086_STEP_0);

    SET(exe_result_push, { 16'd0, cs[15:0] });
    
    IF(exe_operand_32bit && glob_param_2 > cs_limit);
        SET(exe_waiting);
        SET(exe_trigger_gp_fault); //exception GP(0)
    ENDIF();
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL && exe_cmdex == `CMDEX_CALL_real_v8086_STEP_1);

    SET(exe_result_push, exe_eip);

    IF(exe_mutex_current[`MUTEX_ACTIVE_BIT]); SET(exe_waiting); ENDIF(); // wait for write to finish (esp saved)
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL && exe_cmdex == `CMDEX_CALL_real_v8086_STEP_2);
    IF(exe_operand_16bit && glob_param_2 > cs_limit);
        SET(exe_waiting);
        SET(exe_trigger_gp_fault); //exception GP(0)
    ENDIF();
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL && exe_cmdex == `CMDEX_CALL_real_v8086_STEP_3);
    SET(exe_eip_from_glob_param_2);
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL && exe_cmdex == `CMDEX_CALL_protected_seg_STEP_0);
    
    SET(offset_call);

    SET(exe_result_push, { 16'd0, cs[15:0] });

    SET(exe_glob_descriptor_2_set);
    SET(exe_glob_descriptor_2_value, glob_descriptor);
    
    SET(exe_glob_descriptor_set);
    SET(exe_glob_descriptor_value,  ss_cache);
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL && exe_cmdex == `CMDEX_CALL_protected_seg_STEP_1);

    SET(offset_call);

    SET(exe_result_push, exe_eip);
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL && exe_cmdex == `CMDEX_CALL_protected_seg_STEP_2);
    
    SET(offset_call_keep);

    IF(exe_mutex_current[`MUTEX_ACTIVE_BIT]);
        SET(exe_waiting); // wait for ss write
    ELSE();
        SET(exe_glob_descriptor_set);
        SET(exe_glob_descriptor_value, glob_descriptor_2);
    ENDIF();
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL_2 && exe_cmdex == `CMDEX_CALL_2_protected_seg_STEP_4);
    SET(exe_eip_from_glob_param_2);
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL_2 && exe_cmdex == `CMDEX_CALL_2_call_gate_STEP_0);
    
    SET(exe_glob_param_1_set);
    SET(exe_glob_param_1_value, { 7'd0, glob_descriptor[36:32], glob_descriptor[`DESC_BITS_TYPE] == `DESC_CALL_GATE_386, `SEGMENT_CS, glob_descriptor[31:16] });
    
    SET(exe_glob_param_2_set);
    SET(exe_glob_param_2_value, (glob_descriptor[`DESC_BITS_TYPE] == `DESC_CALL_GATE_386)? { glob_descriptor[63:48], glob_descriptor[15:0] } : { 16'd0, glob_descriptor[15:0] });
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL_2 && exe_cmdex == `CMDEX_CALL_2_call_gate_same_STEP_0);
    
    SET(offset_call_int_same_first);

    SET(exe_result_push, { 16'd0, cs[15:0] });
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL_2 && exe_cmdex == `CMDEX_CALL_2_call_gate_same_STEP_1);
    
    SET(offset_call_int_same_next);

    SET(exe_result_push, exe_eip);
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL_2 && exe_cmdex == `CMDEX_CALL_2_call_gate_same_STEP_2);
    
    SET(offset_call_keep);

    IF(glob_param_2 > glob_desc_limit);
        SET(exe_waiting);
        SET(exe_trigger_gp_fault); //exception GP(0)
    ENDIF();
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL_2 && exe_cmdex == `CMDEX_CALL_2_protected_seg_STEP_3);
    SET(offset_call_keep);
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL_2 && exe_cmdex == `CMDEX_CALL_2_call_gate_same_STEP_3);
    SET(exe_eip_from_glob_param_2);
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL_2 && exe_cmdex == `CMDEX_CALL_2_call_gate_more_STEP_1);

    IF(glob_param_3[15:2] == 14'd0);
        SET(exe_waiting);
        SET(exe_trigger_ts_fault); //exception TS(0)
    ENDIF();
    
    IF(exe_ready);
        SET(exe_glob_param_1_set);
        SET(exe_glob_param_1_value, { 13'd0, `SEGMENT_SS, glob_param_3[15:0] });
        
        SET(exe_glob_param_3_set);
        SET(exe_glob_param_3_value, glob_param_1);
        
        SET(exe_glob_descriptor_2_set);
        SET(exe_glob_descriptor_2_value, glob_descriptor);
    ENDIF();
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL_2 && exe_cmdex == `CMDEX_CALL_2_call_gate_more_STEP_3);
    
    SET(offset_new_stack_continue);

    IF(ss_cache[`DESC_BIT_D_B]);
        SET(exe_result_push, esp);
    ELSE();
        SET(exe_result_push, { 16'd0, esp[15:0] });
    ENDIF();
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL_3 && (exe_cmdex == `CMDEX_CALL_3_call_gate_more_STEP_4 || exe_cmdex == `CMDEX_CALL_3_call_gate_more_STEP_5));
    
    SET(exe_result_push, glob_param_5);
    
    SET(offset_new_stack_continue);
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL_3 && exe_cmdex == `CMDEX_CALL_3_call_gate_more_STEP_6);

    SET(offset_new_stack_continue);

    SET(exe_result_push, { 16'd0, cs[15:0] });
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL_3 && exe_cmdex == `CMDEX_CALL_3_call_gate_more_STEP_7);

    SET(offset_new_stack_continue);

    IF(glob_descriptor_2[`DESC_BIT_D_B]);
        SET(exe_result_push, exe_eip);
    ELSE();
        SET(exe_result_push, { 16'd0, exe_eip[15:0] });
    ENDIF();
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL_3 && exe_cmdex == `CMDEX_CALL_3_call_gate_more_STEP_8);

    IF(glob_param_2 > glob_desc_2_limit);
        SET(exe_waiting);
        SET(exe_trigger_gp_fault); //exception GP(0)
    ENDIF();
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL_3 && exe_cmdex == `CMDEX_CALL_3_call_gate_more_STEP_9);
    IF(exe_ready);
        SET(exe_glob_descriptor_set);
        SET(exe_glob_descriptor_value, glob_descriptor_2);
        
        SET(exe_glob_param_1_set);
        SET(exe_glob_param_1_value, glob_param_3);
    ENDIF();
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_CALL_3 && exe_cmdex == `CMDEX_CALL_3_call_gate_more_STEP_10);
    SET(exe_eip_from_glob_param_2);
ENDIF();
</execute>
   
<write>
IF(wr_cmd == `CMD_CALL && (wr_cmdex == `CMDEX_CALL_Ep_STEP_0 || wr_cmdex == `CMDEX_CALL_Ap_STEP_0));
    SET(wr_not_finished);
ENDIF();
</write>

<write>
IF(wr_cmd == `CMD_CALL && (wr_cmdex == `CMDEX_CALL_Ep_STEP_1 || wr_cmdex == `CMDEX_CALL_Ap_STEP_1));
    SET(wr_not_finished);
    
    SET(wr_make_esp_speculative);
ENDIF();
</write>

<write>
IF(wr_cmd == `CMD_CALL && (wr_cmdex == `CMDEX_CALL_real_v8086_STEP_0 || wr_cmdex == `CMDEX_CALL_real_v8086_STEP_1));
    SET(wr_not_finished);

    SET(wr_push_ss_fault_check);
    SET(wr_one_cycle_wait);
    
    IF(~(write_for_wr_ready)); SET(wr_waiting); ENDIF();
    
    IF(~(wr_push_ss_fault));
        SET(write_stack_virtual);
        
        SAVE(esp, wr_stack_esp);
    ENDIF();
ENDIF();
</write>

<write>
IF(wr_cmd == `CMD_CALL && (wr_cmdex == `CMDEX_CALL_Ev_STEP_0 || wr_cmdex == `CMDEX_CALL_Jv_STEP_0));
    SET(wr_not_finished);
    
    SET(wr_push_ss_fault_check);
    SET(wr_one_cycle_wait);
    
    IF(~(write_for_wr_ready)); SET(wr_waiting); ENDIF();
    
    IF(~(wr_push_ss_fault));
        SET(write_stack_virtual);
        
        SET(wr_make_esp_speculative);
        SAVE(esp, wr_stack_esp);
    ENDIF();
ENDIF();
</write>

<write>
IF(wr_cmd == `CMD_CALL && (wr_cmdex == `CMDEX_CALL_Ev_Jv_STEP_1 || wr_cmdex == `CMDEX_CALL_real_v8086_STEP_3));
    SET(wr_make_esp_commit);
    
    // clear pipeline
    SET(wr_req_reset_pr);
    SET(wr_req_reset_dec);
    SET(wr_req_reset_micro);
    SET(wr_req_reset_rd);
    SET(wr_req_reset_exe);
ENDIF();
</write>

<write>
IF(wr_cmd == `CMD_CALL && wr_cmdex == `CMDEX_CALL_real_v8086_STEP_2);
    SET(wr_not_finished);
ENDIF();
</write>

<write>
IF(wr_cmd == `CMD_CALL && (wr_cmdex == `CMDEX_CALL_protected_seg_STEP_0 || wr_cmdex == `CMDEX_CALL_protected_seg_STEP_1));
    SET(wr_not_finished);
    
    SET(wr_new_push_ss_fault_check);
    SET(wr_one_cycle_wait);
    
    SET(wr_error_code, (ss[`SELECTOR_BITS_RPL] != cpl)? `SELECTOR_FOR_CODE(ss) : 16'd0);
    
    IF(~(write_for_wr_ready)); SET(wr_waiting); ENDIF();
    
    IF(~(wr_new_push_ss_fault));
        SET(write_new_stack_virtual);
        
        SAVE(esp, wr_new_stack_esp); // speculative set in 'wr_CALL_Ep_Ap_STEP_1'
    ENDIF();
ENDIF();
</write>

<write>
IF(wr_cmd == `CMD_CALL && wr_cmdex == `CMDEX_CALL_protected_seg_STEP_2);
    SET(wr_not_finished);
ENDIF();
</write>

<write>
IF(wr_cmd == `CMD_CALL_2 && wr_cmdex == `CMDEX_CALL_2_task_switch_STEP_0);
    SET(wr_not_finished);
ENDIF();
</write>

<write>
IF(wr_cmd == `CMD_CALL_2 && (wr_cmdex == `CMDEX_CALL_2_call_gate_more_STEP_2 || wr_cmdex == `CMDEX_CALL_2_call_gate_more_STEP_3));
    SET(wr_not_finished);
    
    SET(wr_new_push_ss_fault_check);
    SET(wr_one_cycle_wait);
    
    SET(wr_push_length_word,  ~(glob_param_3[19]));
    SET(wr_push_length_dword, glob_param_3[19]);
    
    SET(wr_error_code, (glob_param_1[`SELECTOR_BITS_RPL] != cpl)? `SELECTOR_FOR_CODE(glob_param_1) : 16'd0);
    
    IF(~(write_for_wr_ready)); SET(wr_waiting); ENDIF();
    
    IF(~(wr_new_push_ss_fault));
        SET(write_new_stack_virtual);
        
        //esp not yet updated
    ENDIF();
ENDIF();
</write>

<write>
IF(wr_cmd == `CMD_CALL_3 && (
    wr_cmdex == `CMDEX_CALL_3_call_gate_more_STEP_4 || wr_cmdex == `CMDEX_CALL_3_call_gate_more_STEP_5 ||
    wr_cmdex == `CMDEX_CALL_3_call_gate_more_STEP_6 || wr_cmdex == `CMDEX_CALL_3_call_gate_more_STEP_7));

    SET(wr_not_finished);
    
    SET(wr_new_push_ss_fault_check);
    SET(wr_one_cycle_wait);
    
    SET(wr_push_length_word,  ~(glob_param_3[19]));
    SET(wr_push_length_dword, glob_param_3[19]);
    
    SET(wr_error_code, (glob_param_1[`SELECTOR_BITS_RPL] != cpl)? `SELECTOR_FOR_CODE(glob_param_1) : 16'd0);
    
    IF(~(write_for_wr_ready)); SET(wr_waiting); ENDIF();
    
    IF(~(wr_new_push_ss_fault));
        SET(write_new_stack_virtual);
        
        IF(wr_cmdex == `CMDEX_CALL_3_call_gate_more_STEP_7);
            SAVE(esp, wr_new_stack_esp); // speculative set in 'wr_CALL_Ep_Ap_STEP_1'
        ENDIF();
    ENDIF();
ENDIF();
</write>

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.