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

Subversion Repositories ao486

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

Compare with Previous | Blame | View Log


<defines>
`define CMD_IRET        #AUTOGEN_NEXT_CMD
// mc_param_1       --> cs
// mc_param_2       --> eip
// mc_param_3       --> eflags

`define CMDEX_IRET_real_v86_STEP_0      4'd0
`define CMDEX_IRET_real_v86_STEP_1      4'd1
`define CMDEX_IRET_real_v86_STEP_2      4'd2
`define CMDEX_IRET_real_v86_STEP_3      4'd3

`define CMDEX_IRET_protected_STEP_0     4'd4
`define CMDEX_IRET_task_switch_STEP_0   4'd5
`define CMDEX_IRET_task_switch_STEP_1   4'd6

`define CMDEX_IRET_protected_STEP_1     4'd7
`define CMDEX_IRET_protected_STEP_2     4'd8
`define CMDEX_IRET_protected_STEP_3     4'd9

`define CMDEX_IRET_protected_to_v86_STEP_0  4'd10
`define CMDEX_IRET_protected_to_v86_STEP_1  4'd11
`define CMDEX_IRET_protected_to_v86_STEP_2  4'd12
`define CMDEX_IRET_protected_to_v86_STEP_3  4'd13
`define CMDEX_IRET_protected_to_v86_STEP_4  4'd14
`define CMDEX_IRET_protected_to_v86_STEP_5  4'd15

//------------------------------------------------------------------------------

`define CMD_IRET_2      #AUTOGEN_NEXT_CMD

`define CMDEX_IRET_2_idle                   4'd0
`define CMDEX_IRET_2_protected_same_STEP_0  4'd1
`define CMDEX_IRET_2_protected_same_STEP_1  4'd2

`define CMDEX_IRET_2_protected_outer_STEP_0 4'd3
// glob_param_1           --> ss
// glob_param_2           --> eip
// glob_descriptor        --> ss desc
// glob_param_3           --> saved cs
// glob_descriptor_2      --> saved cs desc
`define CMDEX_IRET_2_protected_outer_STEP_1 4'd4
`define CMDEX_IRET_2_protected_outer_STEP_2 4'd5
`define CMDEX_IRET_2_protected_outer_STEP_3 4'd6
// glob_param_2           --> eip
// glob_param_4           --> esp
// glob_param_5           --> eflags

// after step 3/exe:
// glob_param_1           --> cs
// glob_descriptor        --> cs desc
// glob_param_3           --> ss
// glob_descriptor_2      --> ss desc
// glob_param_2           --> eip
// glob_param_4           --> esp
// glob_param_5           --> eflags

`define CMDEX_IRET_2_protected_outer_STEP_4 4'd7
`define CMDEX_IRET_2_protected_outer_STEP_5 4'd8
// after step 5/exe:
// glob_param_1           --> ss
// glob_descriptor        --> ss desc
// glob_param_3           --> cs
// glob_descriptor_2      --> cs desc
// glob_param_2           --> eip
// glob_param_4           --> esp
// glob_param_5           --> eflags

`define CMDEX_IRET_2_protected_outer_STEP_6     4'd9

`define CMDEX_IRET_2_protected_to_v86_STEP_6    4'd10
</defines>

<decode>
dec_ready_one && decoder[7:0] == 8'hCF
`CMD_IRET
IF(~(protected_mode)); SET(dec_cmdex, `CMDEX_IRET_real_v86_STEP_0); ELSE(); SET(dec_cmdex, `CMDEX_IRET_protected_STEP_0); ENDIF();
SET(consume_one);
SET(dec_is_complex);
</decode>

<microcode>
IF(`CMDEX_IRET_real_v86_STEP_0);
    `CMDEX_IRET_real_v86_STEP_1
    `CMDEX_IRET_real_v86_STEP_2
    CALL(`CMDEX_load_seg_STEP_1);
    LOOP(`CMDEX_IRET_real_v86_STEP_3);
ENDIF();

IF(`CMDEX_IRET_protected_STEP_0 && ntflag);
    `CMDEX_IRET_task_switch_STEP_0
    `CMDEX_IRET_task_switch_STEP_1
    JMP(`CMDEX_task_switch_STEP_1);
ENDIF();

IF(`CMDEX_IRET_protected_STEP_0 && ~(ntflag));
    `CMDEX_IRET_protected_STEP_1
    `CMDEX_IRET_protected_STEP_2
    `CMDEX_IRET_protected_STEP_3
    
    //iret to v86
    IF(`CMDEX_IRET_protected_STEP_3 && mc_operand_32bit && glob_param_3[`EFLAGS_BIT_VM] && cpl == 2'd0);
        `CMDEX_IRET_protected_to_v86_STEP_0
        
        IF(mc_cmd == `CMD_IRET && mc_cmdex_last >= `CMDEX_IRET_protected_to_v86_STEP_0 && mc_cmdex_last < `CMDEX_IRET_protected_to_v86_STEP_5);
            DIRECT(`CMD_IRET, mc_cmdex_last + 4'd1);
        ENDIF();
        
        IF(`CMDEX_IRET_protected_to_v86_STEP_5);
            `CMDEX_IRET_2_protected_to_v86_STEP_6
            LOOP(`CMDEX_IRET_2_idle);
        ENDIF();
    ENDIF();
    
    //iret same or outer
    IF(`CMDEX_IRET_protected_STEP_3 && ~(mc_operand_32bit && glob_param_3[`EFLAGS_BIT_VM] && cpl == 2'd0));
        CALL(`CMDEX_load_seg_STEP_1);
        DIRECT(`CMD_IRET_2, (glob_param_1[`SELECTOR_BITS_RPL] == cpl)? `CMDEX_IRET_2_protected_same_STEP_0 : `CMDEX_IRET_2_protected_outer_STEP_0);
    ENDIF();
    
    IF(`CMDEX_IRET_2_protected_same_STEP_0);
        `CMDEX_IRET_2_protected_same_STEP_1
        LOOP(`CMDEX_IRET_2_idle);
    ENDIF();
        
    IF(`CMDEX_IRET_2_protected_outer_STEP_0);
        CALL(`CMDEX_load_seg_STEP_1);
        `CMDEX_IRET_2_protected_outer_STEP_1
        
        IF(mc_cmd == `CMD_IRET_2 && mc_cmdex_last >= `CMDEX_IRET_2_protected_outer_STEP_1 && mc_cmdex_last < `CMDEX_IRET_2_protected_outer_STEP_6);
            DIRECT(`CMD_IRET_2, mc_cmdex_last + 4'd1);
        ENDIF();
        
        IF(`CMDEX_IRET_2_protected_outer_STEP_6);
            LOOP(`CMDEX_IRET_2_idle);
        ENDIF();
    ENDIF();
ENDIF();
</microcode>

<read>
IF(rd_cmd == `CMD_IRET && rd_cmdex <= `CMDEX_IRET_real_v86_STEP_2);
            
    SET(address_stack_pop);
    IF(rd_cmdex >`CMDEX_IRET_real_v86_STEP_0); SET(address_stack_pop_speedup); ENDIF();

    IF(rd_cmdex == `CMDEX_IRET_real_v86_STEP_0); 
        SET(rd_glob_param_2_set);
        SET(rd_glob_param_2_value, (rd_operand_16bit)? { 16'd0, read_4[15:0] } : read_4); // read eip
    ENDIF();
    
    IF(rd_cmdex == `CMDEX_IRET_real_v86_STEP_1);
        SET(rd_glob_param_1_set);
        SET(rd_glob_param_1_value, { 13'd0, `SEGMENT_CS, read_4[15:0] }); // read cs
    ENDIF();
    
    IF(rd_cmdex == `CMDEX_IRET_real_v86_STEP_2);
        SET(rd_glob_param_3_set);
        SET(rd_glob_param_3_value, (rd_operand_16bit)? { 16'd0, read_4[15:0] } : read_4); // read eflags
    ENDIF();
    
    IF(rd_mutex_busy_memory || (rd_mutex_busy_eflags && v8086_mode)); SET(rd_waiting); // waiting for esp in 'address_waiting'
    ELSE();
        IF(~(v8086_mode) || iopl == 2'd3);
    
            SET(read_virtual);

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

<read>
IF(rd_cmd == `CMD_IRET && rd_cmdex == `CMDEX_IRET_protected_STEP_0);
            
    IF(rd_mutex_busy_memory || rd_mutex_busy_eflags); SET(rd_waiting); ENDIF(); // waiting for esp in 'address_waiting'
ENDIF();
</read>

<read>
IF(rd_cmd == `CMD_IRET && rd_cmdex == `CMDEX_IRET_task_switch_STEP_0);
    
    SET(rd_system_linear, tr_base);

    SET(read_system_word);
    
    SET(rd_glob_param_1_set);
    SET(rd_glob_param_1_value, { 14'd0, `TASK_SWITCH_FROM_IRET, read_4[15:0] });
    
    IF(~(read_for_rd_ready)); SET(rd_waiting); ENDIF();
ENDIF();
</read>

<read>
IF(rd_cmd == `CMD_IRET && rd_cmdex == `CMDEX_IRET_task_switch_STEP_1);
         
    SET(rd_glob_param_3_set);
    SET(rd_glob_param_3_value, { 10'd0, rd_consumed, 18'd0 });

    IF(rd_mutex_busy_active); SET(rd_waiting); // wait for previous step -- exception possible
    ELSE();
        
        IF(~(rd_descriptor_not_in_limits));
    
            SET(rd_glob_descriptor_set);
            SET(rd_glob_descriptor_value, read_8);
            
            SET(rd_glob_param_2_set);
            SET(rd_glob_param_2_value, 32'd0);
            
            SET(read_system_descriptor);

            IF(~(read_for_rd_ready)); SET(rd_waiting); ENDIF();
            
        ELSE();
            SET(rd_glob_param_2_set);
            SET(rd_glob_param_2_value, { 30'd0, rd_descriptor_not_in_limits, glob_param_1[15:2] == 14'd0 });
        ENDIF();
    ENDIF();
ENDIF();
</read>

<read>
IF(rd_cmd == `CMD_IRET && rd_cmdex >= `CMDEX_IRET_protected_STEP_1 && rd_cmdex <= `CMDEX_IRET_protected_STEP_3);
            
    SET(address_stack_pop_next);
    
    IF(rd_cmdex == `CMDEX_IRET_protected_STEP_1);
        SET(address_stack_save);
        SET(address_stack_for_iret_first);
        
        SET(rd_glob_param_3_set);
        SET(rd_glob_param_3_value, (rd_operand_16bit)? { 16'd0, read_4[15:0] } : read_4); //eflags
    ENDIF();
    
    IF(rd_cmdex == `CMDEX_IRET_protected_STEP_2);
        SET(rd_glob_param_1_set);
        SET(rd_glob_param_1_value, { `MC_PARAM_1_FLAG_NO_WRITE, `SEGMENT_CS, read_4[15:0] }); //cs
    ENDIF();
    
    IF(rd_cmdex == `CMDEX_IRET_protected_STEP_3);
        SET(rd_glob_param_2_set);
        SET(rd_glob_param_2_value, (rd_operand_16bit)? { 16'd0, read_4[15:0] } : read_4); //eip
    ENDIF();
    
    SET(read_virtual);

    IF(~(read_for_rd_ready)); SET(rd_waiting); ENDIF();

ENDIF();
</read>

<read>
IF(rd_cmd == `CMD_IRET && rd_cmdex >= `CMDEX_IRET_protected_to_v86_STEP_0);
    SET(address_stack_pop_next);
    SET(address_stack_add_4_to_saved);
    
    IF(rd_cmdex == `CMDEX_IRET_protected_to_v86_STEP_0);
        SET(address_stack_save);
        SET(address_stack_for_iret_to_v86);
    ENDIF();
    
    SET(rd_src_is_memory);
    
    SET(read_virtual);

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

<read>
IF(rd_cmd == `CMD_IRET_2 && rd_cmdex == `CMDEX_IRET_2_protected_outer_STEP_0);

    SET(address_stack_pop_next);
    SET(address_stack_for_iret_second);
    
    SET(rd_glob_param_1_set, rd_ready);
    SET(rd_glob_param_1_value, { `MC_PARAM_1_FLAG_NP_NOT_SS | `MC_PARAM_1_FLAG_CPL_FROM_PARAM_3, `SEGMENT_SS, read_4[15:0] }); // read ss
    
    SET(rd_glob_param_3_set);
    SET(rd_glob_param_3_value, glob_param_1); 
    
    SET(rd_glob_descriptor_2_set);
    SET(rd_glob_descriptor_2_value, glob_descriptor); 
    
    SET(read_length_word);
    SET(read_virtual);

    IF(~(read_for_rd_ready)); SET(rd_waiting); ENDIF();
ENDIF();
</read>
    
<read>
IF(rd_cmd == `CMD_IRET_2 && rd_cmdex >= `CMDEX_IRET_2_protected_outer_STEP_1 && rd_cmdex <= `CMDEX_IRET_2_protected_outer_STEP_3);
            
    SET(address_stack_pop_next);

    IF(rd_cmdex == `CMDEX_IRET_2_protected_outer_STEP_1);
        SET(address_stack_save);
        SET(address_stack_for_iret_third);
        
        SET(rd_glob_param_4_set);
        SET(rd_glob_param_4_value, (rd_operand_16bit)? { 16'd0, read_4[15:0] } : read_4); // read esp
    ENDIF();
    
    IF(rd_cmdex == `CMDEX_IRET_2_protected_outer_STEP_2);
        SET(rd_glob_param_5_set);
        SET(rd_glob_param_5_value, (rd_operand_16bit)? { 16'd0, read_4[15:0] } : read_4); // read eflags
    ENDIF();
    
    IF(rd_cmdex == `CMDEX_IRET_2_protected_outer_STEP_3);
        SET(address_stack_for_iret_last);
        
        SET(rd_glob_param_2_set);
        SET(rd_glob_param_2_value, (rd_operand_16bit)? { 16'd0, read_4[15:0] } : read_4); // read eip
    ENDIF();
    
    SET(read_virtual);
    
    IF(~(read_for_rd_ready)); SET(rd_waiting); ENDIF();
ENDIF();
</read>

<read>
IF(rd_cmd == `CMD_IRET_2 && rd_cmdex >= `CMDEX_IRET_2_protected_outer_STEP_6);
    IF(rd_mutex_busy_active); SET(rd_waiting); ENDIF(); // wait for previous step -- loading ss
ENDIF();
</read>

<execute>
IF(exe_cmd == `CMD_IRET_2 && exe_cmdex == `CMDEX_IRET_2_protected_same_STEP_0);
    
    SET(offset_iret);

    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_IRET_2 && exe_cmdex == `CMDEX_IRET_2_protected_same_STEP_1);
    SET(exe_eip_from_glob_param_2);
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_IRET_2  && exe_cmdex == `CMDEX_IRET_2_protected_outer_STEP_3);
            
    IF(glob_param_2 > glob_desc_2_limit);
    
        SET(exe_waiting);
        SET(exe_trigger_gp_fault); //exception GP(0)
    ELSE();
        SET(exe_glob_descriptor_set);
        SET(exe_glob_descriptor_value, glob_descriptor_2);
        
        SET(exe_glob_descriptor_2_set);
        SET(exe_glob_descriptor_2_value, glob_descriptor);
        
        SET(exe_glob_param_1_set);
        SET(exe_glob_param_1_value, glob_param_3);
        
        SET(exe_glob_param_3_set);
        SET(exe_glob_param_3_value, glob_param_1);
    ENDIF();
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_IRET_2  && exe_cmdex == `CMDEX_IRET_2_protected_outer_STEP_5);
    
    SET(exe_glob_descriptor_set);
    SET(exe_glob_descriptor_value, glob_descriptor_2);
    
    SET(exe_glob_descriptor_2_set);
    SET(exe_glob_descriptor_2_value, glob_descriptor);

    SET(exe_glob_param_1_set);
    SET(exe_glob_param_1_value, glob_param_3);
    
    SET(exe_glob_param_3_set);
    SET(exe_glob_param_3_value, glob_param_1);
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_IRET_2 && exe_cmdex == `CMDEX_IRET_2_protected_outer_STEP_6);

    SET(offset_iret_glob_param_4);
    SET(exe_eip_from_glob_param_2);
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_IRET && exe_cmdex == `CMDEX_IRET_real_v86_STEP_0);
    
    SET(offset_pop);

    IF(v8086_mode && iopl < 2'd3);
        SET(exe_waiting);
        SET(exe_trigger_gp_fault); //exception GP(0)
    ENDIF();
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_IRET && exe_cmdex == `CMDEX_IRET_real_v86_STEP_1);
    SET(offset_pop);
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_IRET && exe_cmdex == `CMDEX_IRET_real_v86_STEP_2);

    SET(offset_pop);

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

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

<execute>
IF(exe_cmd == `CMD_IRET && exe_cmdex == `CMDEX_IRET_task_switch_STEP_0);
    IF(glob_param_1[`SELECTOR_BIT_TI]);
        SET(exe_waiting);
        
        SET(exe_trigger_ts_fault);
        SET(exe_error_code, `SELECTOR_FOR_CODE(glob_param_1));
    ENDIF();
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_IRET && exe_cmdex == `CMDEX_IRET_task_switch_STEP_1);
    
    IF(glob_param_2[1] || exe_descriptor[`DESC_BIT_SEG] || (exe_descriptor[`DESC_BITS_TYPE] != `DESC_TSS_BUSY_386 && exe_descriptor[`DESC_BITS_TYPE] != `DESC_TSS_BUSY_286));
        SET(exe_waiting);

        SET(exe_trigger_ts_fault);
        SET(exe_error_code, `SELECTOR_FOR_CODE(glob_param_1));
    ENDIF();
    
    IF(glob_param_2[1] == 1'b0 && ~(exe_trigger_ts_fault) && ~(exe_descriptor[`DESC_BIT_P]));
        SET(exe_waiting);

        SET(exe_trigger_np_fault);
        SET(exe_error_code, `SELECTOR_FOR_CODE(glob_param_1));
    ENDIF();
ENDIF();
</execute>
    
<execute>
IF(exe_cmd == `CMD_IRET && exe_cmdex >= `CMDEX_IRET_protected_to_v86_STEP_0);
    IF(exe_ready);
        SAVE(exe_buffer, src);
        SET(exe_buffer_shift);
    ENDIF();
ENDIF();
</execute>

<execute>
IF(exe_cmd == `CMD_IRET_2 && exe_cmdex == `CMDEX_IRET_2_protected_to_v86_STEP_6);
    SET(exe_eip_from_glob_param_2_16bit);
ENDIF();
</execute>

<execute>
// special case: check if (cs.rpl != ss.rpl) before LOAD_SEG
IF(exe_cmd == `CMD_IRET_2 && exe_cmdex == `CMDEX_IRET_2_protected_outer_STEP_0);
    
    IF(glob_param_1[`SELECTOR_BITS_RPL] != glob_param_3[`SELECTOR_BITS_RPL]); // new_ss.rpl != new_cs.rpl
    
        SET(exe_waiting);
        SET(exe_trigger_gp_fault); //exception GP(val)
        SET(exe_error_code, { glob_param_1[15:2], 2'd0 });
    ENDIF();
ENDIF();
</execute>

<write>
IF(wr_cmd == `CMD_IRET && wr_cmdex <= `CMDEX_IRET_real_v86_STEP_2);
    SET(wr_not_finished);
    
    SAVE(esp, wr_stack_esp);
    IF(wr_cmdex == `CMDEX_IRET_real_v86_STEP_0); SET(wr_make_esp_speculative); ENDIF(); //NOTE: esp update can not be every cycle; must be at least every second cycle
ENDIF();
</write>

<write>
IF(wr_cmd == `CMD_IRET && wr_cmdex == `CMDEX_IRET_real_v86_STEP_3);
    
    SET(wr_make_esp_commit);
    
    SAVE(cflag,  glob_param_3[0]);
    SAVE(pflag,  glob_param_3[2]);
    SAVE(aflag,  glob_param_3[4]);
    SAVE(zflag,  glob_param_3[6]);
    SAVE(sflag,  glob_param_3[7]);
    SAVE(tflag,  glob_param_3[8]);
    SAVE(iflag,  glob_param_3[9]);
    SAVE(dflag,  glob_param_3[10]);
    SAVE(oflag,  glob_param_3[11]);
    SAVE(ntflag, glob_param_3[14]);
    
    IF(real_mode);
        SAVE(iopl,  glob_param_3[13:12]);
    ENDIF();
    
    IF(wr_operand_32bit);
        SAVE(rflag,  glob_param_3[16]);
        SAVE(acflag, glob_param_3[18]);
        SAVE(idflag, glob_param_3[21]);
    ENDIF();
    
    // 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_IRET && (wr_cmdex == `CMDEX_IRET_protected_STEP_0 || wr_cmdex == `CMDEX_IRET_task_switch_STEP_0 || wr_cmdex == `CMDEX_IRET_task_switch_STEP_1));
    SET(wr_not_finished);
ENDIF();
</write>

<write>
IF(wr_cmd == `CMD_IRET && wr_cmdex >= `CMDEX_IRET_protected_STEP_1 && wr_cmdex <= `CMDEX_IRET_protected_STEP_3);
    SET(wr_not_finished);
ENDIF();
</write>

<write>
IF(wr_cmd == `CMD_IRET && wr_cmdex >= `CMDEX_IRET_protected_to_v86_STEP_0 && wr_cmdex <= `CMDEX_IRET_protected_to_v86_STEP_4);
    SET(wr_not_finished);
ENDIF();
</write>

<write_local>
wire [15:0] wr_IRET_to_v86_es;
wire [15:0] wr_IRET_to_v86_cs;
wire [15:0] wr_IRET_to_v86_ss;
wire [15:0] wr_IRET_to_v86_ds;
wire [15:0] wr_IRET_to_v86_fs;
wire [15:0] wr_IRET_to_v86_gs;

assign wr_IRET_to_v86_es = exe_buffer_shifted[79:64];
assign wr_IRET_to_v86_cs = glob_param_1[15:0];
assign wr_IRET_to_v86_ss = exe_buffer_shifted[111:96];
assign wr_IRET_to_v86_ds = exe_buffer_shifted[47:32];
assign wr_IRET_to_v86_fs = exe_buffer_shifted[15:0];
assign wr_IRET_to_v86_gs = exe_buffer[15:0];
</write_local>

<write>
IF(wr_cmd == `CMD_IRET && wr_cmdex == `CMDEX_IRET_protected_to_v86_STEP_5);
    
    SET(wr_not_finished);
    
    SAVE(cflag,  glob_param_3[0]);
    SAVE(pflag,  glob_param_3[2]);
    SAVE(aflag,  glob_param_3[4]);
    SAVE(zflag,  glob_param_3[6]);
    SAVE(sflag,  glob_param_3[7]);
    SAVE(tflag,  glob_param_3[8]);
    SAVE(iflag,  glob_param_3[9]);
    SAVE(dflag,  glob_param_3[10]);
    SAVE(oflag,  glob_param_3[11]);
    SAVE(iopl,   glob_param_3[13:12]);
    SAVE(ntflag, glob_param_3[14]);
    SAVE(rflag,  glob_param_3[16]);
    SAVE(vmflag, glob_param_3[`EFLAGS_BIT_VM]);
    SAVE(acflag, glob_param_3[18]);
    SAVE(idflag, glob_param_3[21]);
    
    SAVE(esp, exe_buffer_shifted[159:128]);
    
    //seg
    SAVE(es, wr_IRET_to_v86_es);
    SAVE(cs, wr_IRET_to_v86_cs);
    SAVE(ss, wr_IRET_to_v86_ss);
    SAVE(ds, wr_IRET_to_v86_ds);
    SAVE(fs, wr_IRET_to_v86_fs);
    SAVE(gs, wr_IRET_to_v86_gs);
    
    SAVE(es_rpl, 2'd3);
    SAVE(cs_rpl, 2'd3);
    SAVE(ss_rpl, 2'd3);
    SAVE(ds_rpl, 2'd3);
    SAVE(fs_rpl, 2'd3);
    SAVE(gs_rpl, 2'd3);
    
    SAVE(es_cache_valid, `TRUE);
    SAVE(cs_cache_valid, `TRUE);
    SAVE(ss_cache_valid, `TRUE);
    SAVE(ds_cache_valid, `TRUE);
    SAVE(fs_cache_valid, `TRUE);
    SAVE(gs_cache_valid, `TRUE);
    
    SAVE(es_cache, `DESC_MASK_P | `DESC_MASK_DPL | `DESC_MASK_SEG | `DESC_MASK_DATA_RWA | { 24'd0, 4'd0,wr_IRET_to_v86_es[15:12], wr_IRET_to_v86_es[11:0],4'd0, 16'hFFFF });
    SAVE(cs_cache, `DESC_MASK_P | `DESC_MASK_DPL | `DESC_MASK_SEG | `DESC_MASK_DATA_RWA | { 24'd0, 4'd0,wr_IRET_to_v86_cs[15:12], wr_IRET_to_v86_cs[11:0],4'd0, 16'hFFFF });
    SAVE(ss_cache, `DESC_MASK_P | `DESC_MASK_DPL | `DESC_MASK_SEG | `DESC_MASK_DATA_RWA | { 24'd0, 4'd0,wr_IRET_to_v86_ss[15:12], wr_IRET_to_v86_ss[11:0],4'd0, 16'hFFFF });
    SAVE(ds_cache, `DESC_MASK_P | `DESC_MASK_DPL | `DESC_MASK_SEG | `DESC_MASK_DATA_RWA | { 24'd0, 4'd0,wr_IRET_to_v86_ds[15:12], wr_IRET_to_v86_ds[11:0],4'd0, 16'hFFFF });
    SAVE(fs_cache, `DESC_MASK_P | `DESC_MASK_DPL | `DESC_MASK_SEG | `DESC_MASK_DATA_RWA | { 24'd0, 4'd0,wr_IRET_to_v86_fs[15:12], wr_IRET_to_v86_fs[11:0],4'd0, 16'hFFFF });
    SAVE(gs_cache, `DESC_MASK_P | `DESC_MASK_DPL | `DESC_MASK_SEG | `DESC_MASK_DATA_RWA | { 24'd0, 4'd0,wr_IRET_to_v86_gs[15:12], wr_IRET_to_v86_gs[11:0],4'd0, 16'hFFFF });
ENDIF();
</write>

<write>
IF(wr_cmd == `CMD_IRET_2 && wr_cmdex == `CMDEX_IRET_2_protected_to_v86_STEP_6);

    // 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_IRET_2 && wr_cmdex == `CMDEX_IRET_2_protected_same_STEP_1);
    
    // save eflags
    SAVE(cflag,  glob_param_3[0]);
    SAVE(pflag,  glob_param_3[2]);
    SAVE(aflag,  glob_param_3[4]);
    SAVE(zflag,  glob_param_3[6]);
    SAVE(sflag,  glob_param_3[7]);
    SAVE(tflag,  glob_param_3[8]);
    SAVE(dflag,  glob_param_3[10]);
    SAVE(oflag,  glob_param_3[11]);
    SAVE(ntflag, glob_param_3[14]);
    
    IF(cpl <= iopl);
        SAVE(iflag,  glob_param_3[9]);
    ENDIF();
    
    IF(cpl == 2'd0);
        SAVE(iopl,  glob_param_3[13:12]);
    ENDIF();
    
    IF(wr_operand_32bit);
        SAVE(rflag,  glob_param_3[16]);
        SAVE(acflag, glob_param_3[18]);
        SAVE(idflag, glob_param_3[21]);
    ENDIF();
    
    // 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_IRET_2 && wr_cmdex >= `CMDEX_IRET_2_protected_outer_STEP_0 && wr_cmdex <= `CMDEX_IRET_2_protected_outer_STEP_2);
    SET(wr_not_finished);
ENDIF();
</write>

<write>
IF(wr_cmd == `CMD_IRET_2 && wr_cmdex == `CMDEX_IRET_2_protected_outer_STEP_4);
    SET(wr_not_finished);
    
    // save eflags
    
    SAVE(cflag,  glob_param_5[0]);
    SAVE(pflag,  glob_param_5[2]);
    SAVE(aflag,  glob_param_5[4]);
    SAVE(zflag,  glob_param_5[6]);
    SAVE(sflag,  glob_param_5[7]);
    SAVE(tflag,  glob_param_5[8]);
    SAVE(dflag,  glob_param_5[10]);
    SAVE(oflag,  glob_param_5[11]);
    SAVE(ntflag, glob_param_5[14]);
    
    IF(wr_task_rpl <= iopl);
        SAVE(iflag,  glob_param_5[9]);
    ENDIF();
    
    IF(wr_task_rpl == 2'd0);
        SAVE(iopl,  glob_param_5[13:12]);
    ENDIF();
    
    IF(wr_operand_32bit);
        SAVE(rflag,  glob_param_5[16]);
        SAVE(acflag, glob_param_5[18]);
        SAVE(idflag, glob_param_5[21]);
    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.