summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/alpha/isa/decoder.isa2
-rw-r--r--arch/mips/isa/base.isa2
-rw-r--r--arch/mips/isa/decoder.isa286
-rw-r--r--arch/mips/isa/formats/branch.isa6
-rw-r--r--arch/mips/isa/formats/fp.isa8
-rw-r--r--arch/mips/isa/operands.isa22
-rw-r--r--arch/mips/isa_traits.cc62
-rw-r--r--arch/mips/isa_traits.hh17
-rw-r--r--arch/mips/regfile/float_regfile.hh76
-rw-r--r--arch/mips/regfile/int_regfile.hh31
-rw-r--r--arch/mips/regfile/regfile.hh (renamed from arch/mips/regfile.hh)52
-rw-r--r--dev/ide_disk.hh14
-rw-r--r--dev/sinic.cc289
-rw-r--r--dev/sinic.hh16
-rw-r--r--dev/sinicreg.hh62
-rw-r--r--python/m5/objects/Ethernet.py10
-rw-r--r--sim/serialize.cc12
-rw-r--r--sim/serialize.hh5
-rw-r--r--util/stats/barchart.py8
19 files changed, 539 insertions, 441 deletions
diff --git a/arch/alpha/isa/decoder.isa b/arch/alpha/isa/decoder.isa
index 3d38e91f9..1adcfb948 100644
--- a/arch/alpha/isa/decoder.isa
+++ b/arch/alpha/isa/decoder.isa
@@ -810,7 +810,7 @@ decode OPCODE default Unknown::unknown() {
AlphaPseudo::addsymbol(xc->xcBase(), R16, R17);
}}, IsNonSpeculative);
0x54: m5panic({{
- panic("M5 panic instruction called.");
+ panic("M5 panic instruction called at pc=%#x.", xc->readPC());
}}, IsNonSpeculative);
}
diff --git a/arch/mips/isa/base.isa b/arch/mips/isa/base.isa
index 9ed9651d2..b2a31c018 100644
--- a/arch/mips/isa/base.isa
+++ b/arch/mips/isa/base.isa
@@ -8,8 +8,6 @@
//Outputs to decoder.hh
output header {{
-#define R31 31
-
using namespace MipsISA;
diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa
index 5e1f02869..1454aba39 100644
--- a/arch/mips/isa/decoder.isa
+++ b/arch/mips/isa/decoder.isa
@@ -20,8 +20,8 @@ decode OPCODE_HI default Unknown::unknown() {
0x0: decode FUNCTION_LO {
0x1: decode MOVCI {
format BasicOp {
- 0: movf({{ if (getFPConditionCode(CC) == 0) Rd = Rs}});
- 1: movt({{ if (getFPConditionCode(CC) == 1) Rd = Rs}});
+ 0: movf({{ if (getFPConditionCode(FCSR, CC) == 0) Rd = Rs}});
+ 1: movt({{ if (getFPConditionCode(FCSR, CC) == 1) Rd = Rs}});
}
}
@@ -127,10 +127,10 @@ decode OPCODE_HI default Unknown::unknown() {
0x2: decode FUNCTION_LO {
format BasicOp {
- 0x0: mfhi({{ Rd = xc->readMiscReg(Hi); }});
- 0x1: mthi({{ xc->setMiscReg(Hi,Rs); }});
- 0x2: mflo({{ Rd = xc->readMiscReg(Lo); }});
- 0x3: mtlo({{ xc->setMiscReg(Lo,Rs); }});
+ 0x0: mfhi({{ Rd = HI; }});
+ 0x1: mthi({{ HI = Rs; }});
+ 0x2: mflo({{ Rd = LO; }});
+ 0x3: mtlo({{ LO = Rs; }});
}
}
@@ -138,24 +138,24 @@ decode OPCODE_HI default Unknown::unknown() {
format IntOp {
0x0: mult({{
int64_t temp1 = Rs.sd * Rt.sd;
- xc->setMiscReg(Hi,temp1<63:32>);
- xc->setMiscReg(Lo,temp1<31:0>);
+ HI = temp1<63:32>;
+ LO = temp1<31:0>;
}});
0x1: multu({{
uint64_t temp1 = Rs.ud * Rt.ud;
- xc->setMiscReg(Hi,temp1<63:32>);
- xc->setMiscReg(Lo,temp1<31:0>);
+ HI = temp1<63:32>;
+ LO = temp1<31:0>;
}});
0x2: div({{
- xc->setMiscReg(Hi,Rs.sd % Rt.sd);
- xc->setMiscReg(Lo,Rs.sd / Rt.sd);
+ HI = Rs.sd % Rt.sd;
+ LO = Rs.sd / Rt.sd;
}});
0x3: divu({{
- xc->setMiscReg(Hi,Rs.ud % Rt.ud);
- xc->setMiscReg(Lo,Rs.ud / Rt.ud);
+ HI = Rs.ud % Rt.ud;
+ LO = Rs.ud / Rt.ud;
}});
}
}
@@ -163,9 +163,9 @@ decode OPCODE_HI default Unknown::unknown() {
0x4: decode HINT {
0x0: decode FUNCTION_LO {
format IntOp {
- 0x0: add({{ Rd.sw = Rs.sw + Rt.sw;/*Trap on Overflow*/}});
+ 0x0: add({{ Rd.sw = Rs.sw + Rt.sw; /*Trap on Overflow*/}});
0x1: addu({{ Rd.sw = Rs.sw + Rt.sw;}});
- 0x2: sub({{ Rd.sw = Rs.sw - Rt.sw; /*Trap on Overflow*/}});
+ 0x2: sub({{ Rd.sw = Rs.sw - Rt.sw; /*Trap on Overflow*/}});
0x3: subu({{ Rd.sw = Rs.sw - Rt.sw;}});
0x4: and({{ Rd = Rs & Rt;}});
0x5: or({{ Rd = Rs | Rt;}});
@@ -299,6 +299,7 @@ decode OPCODE_HI default Unknown::unknown() {
//sel field. In those instances, the sel field must be zero.
//MT Code Needed Here
+
}});
0xC: mttr({{
@@ -397,78 +398,71 @@ decode OPCODE_HI default Unknown::unknown() {
0x3: mfhc1({{ Rt.uw = Fs.ud<63:32>;}});
0x4: mtc1 ({{ Fs.uw = Rt.uw; }});
0x7: mthc1({{
- uint64_t fs_hi = Rt.ud << 32;
+ uint64_t fs_hi = Rt.uw;
uint64_t fs_lo = Fs.ud & 0x0000FFFF;
- Fs.ud = fs_hi & fs_lo;
+ Fs.ud = fs_hi << 32 | fs_lo;
}});
}
format System {
0x2: cfc1({{
- uint32_t fcsr_reg = xc->readMiscReg(FCSR);
-
switch (FS)
{
case 0:
- Rt = xc->readMiscReg(FIR);
+ Rt = FIR;
break;
case 25:
- Rt = 0 | (fcsr_reg & 0xFE000000) >> 24 | (fcsr_reg & 0x00800000) >> 23;
+ Rt = 0 | (FCSR & 0xFE000000) >> 24 | (FCSR & 0x00800000) >> 23;
break;
case 26:
- Rt = 0 | (fcsr_reg & 0x0003F07C);
+ Rt = 0 | (FCSR & 0x0003F07C);
break;
case 28:
- Rt = 0 | (fcsr_reg);
+ Rt = 0 | (FCSR & 0x00000F80) | (FCSR & 0x01000000) >> 21 | (FCSR & 0x00000003);
break;
case 31:
- Rt = fcsr_reg;
+ Rt = FCSR;
break;
default:
panic("FP Control Value (%d) Not Available. Ignoring Access to"
- "Floating Control Status Register",fcsr_reg);
+ "Floating Control Status Register",FS);
}
}});
0x6: ctc1({{
- uint32_t fcsr_reg = xc->readMiscReg(FCSR);
- uint32_t temp;
-
switch (FS)
{
case 25:
- temp = 0 | (Rt.uw<7:1> << 25) // move 31...25
- | (fcsr_reg & 0x01000000) // bit 24
- | (fcsr_reg & 0x004FFFFF);// bit 22...0
+ FCSR = 0 | (Rt.uw<7:1> << 25) // move 31...25
+ | (FCSR & 0x01000000) // bit 24
+ | (FCSR & 0x004FFFFF);// bit 22...0
break;
case 26:
- temp = 0 | (fcsr_reg & 0xFFFC0000) // move 31...18
+ FCSR = 0 | (FCSR & 0xFFFC0000) // move 31...18
| Rt.uw<17:12> << 12 // bit 17...12
- | (fcsr_reg & 0x00000F80) << 7// bit 11...7
+ | (FCSR & 0x00000F80) << 7// bit 11...7
| Rt.uw<6:2> << 2 // bit 6...2
- | (fcsr_reg & 0x00000002); // bit 1...0
+ | (FCSR & 0x00000002); // bit 1...0
break;
case 28:
- temp = 0 | (fcsr_reg & 0xFE000000) // move 31...25
+ FCSR = 0 | (FCSR & 0xFE000000) // move 31...25
| Rt.uw<2:2> << 24 // bit 24
- | (fcsr_reg & 0x00FFF000) << 23// bit 23...12
+ | (FCSR & 0x00FFF000) << 23// bit 23...12
| Rt.uw<11:7> << 7 // bit 24
- | (fcsr_reg & 0x000007E)
+ | (FCSR & 0x000007E)
| Rt.uw<1:0>;// bit 22...0
break;
case 31:
- temp = Rt.uw;
+ FCSR = Rt.uw;
break;
default:
panic("FP Control Value (%d) Not Available. Ignoring Access to"
- "Floating Control Status Register",fcsr_reg);
+ "Floating Control Status Register", FS);
}
-
- xc->setMiscReg(FCSR,temp);
}});
}
}
@@ -476,15 +470,15 @@ decode OPCODE_HI default Unknown::unknown() {
0x1: decode ND {
0x0: decode TF {
format Branch {
- 0x0: bc1f({{ cond = (getFPConditionCode(CC) == 0); }});
- 0x1: bc1t({{ cond = (getFPConditionCode(CC) == 1); }});
+ 0x0: bc1f({{ cond = (getFPConditionCode(FCSR,CC) == 0); }});
+ 0x1: bc1t({{ cond = (getFPConditionCode(FCSR,CC) == 1); }});
}
}
0x1: decode TF {
format BranchLikely {
- 0x0: bc1fl({{ cond = (getFPConditionCode(CC) == 0); }});
- 0x1: bc1tl({{ cond = (getFPConditionCode(CC) == 1); }});
+ 0x0: bc1fl({{ cond = (getFPConditionCode(FCSR,CC) == 0); }});
+ 0x1: bc1tl({{ cond = (getFPConditionCode(FCSR,CC) == 1); }});
}
}
}
@@ -512,7 +506,7 @@ decode OPCODE_HI default Unknown::unknown() {
0x1: decode FUNCTION_LO {
format Float64Op {
0x0: round_l_s({{
- Fd.ud = fpConvert(roundFP(Fs.sf), SINGLE_TO_LONG);
+ Fd.ud = fpConvert(roundFP(Fs.sf,0), SINGLE_TO_LONG);
}});
0x1: trunc_l_s({{
@@ -530,7 +524,7 @@ decode OPCODE_HI default Unknown::unknown() {
format FloatOp {
0x4: round_w_s({{
- Fd.uw = fpConvert(roundFP(Fs.sf), SINGLE_TO_WORD);
+ Fd.uw = fpConvert(roundFP(Fs.sf,0), SINGLE_TO_WORD);
}});
0x5: trunc_w_s({{
@@ -550,8 +544,8 @@ decode OPCODE_HI default Unknown::unknown() {
0x2: decode FUNCTION_LO {
0x1: decode MOVCF {
format FloatOp {
- 0x0: movf_s({{if (getFPConditionCode(CC) == 0) Fd = Fs;}});
- 0x1: movt_s({{if (getFPConditionCode(CC) == 1) Fd = Fs;}});
+ 0x0: movf_s({{if (getFPConditionCode(FCSR,CC) == 0) Fd = Fs;}});
+ 0x1: movt_s({{if (getFPConditionCode(FCSR,CC) == 1) Fd = Fs;}});
}
}
@@ -591,49 +585,49 @@ decode OPCODE_HI default Unknown::unknown() {
0x0: c_f_s({{ cond = 0; }});
0x1: c_un_s({{
- if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf))
+ if (isnan(Fs.sf) || isnan(Ft.sf))
cond = 1;
else
cond = 0;
}});
0x2: c_eq_s({{
- if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf))
+ if (isnan(Fs.sf) || isnan(Ft.sf))
cond = 0;
else
cond = (Fs.sf == Ft.sf);
}});
0x3: c_ueq_s({{
- if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf))
+ if (isnan(Fs.sf) || isnan(Ft.sf))
cond = 1;
else
cond = (Fs.sf == Ft.sf);
}});
0x4: c_olt_s({{
- if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf))
+ if (isnan(Fs.sf) || isnan(Ft.sf))
cond = 0;
else
cond = (Fs.sf < Ft.sf);
}});
0x5: c_ult_s({{
- if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf))
+ if (isnan(Fs.sf) || isnan(Ft.sf))
cond = 1;
else
cond = (Fs.sf < Ft.sf);
}});
0x6: c_ole_s({{
- if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf))
+ if (isnan(Fs.sf) || isnan(Ft.sf))
cond = 0;
else
cond = (Fs.sf <= Ft.sf);
}});
0x7: c_ule_s({{
- if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf))
+ if (isnan(Fs.sf) || isnan(Ft.sf))
cond = 1;
else
cond = (Fs.sf <= Ft.sf);
@@ -646,49 +640,49 @@ decode OPCODE_HI default Unknown::unknown() {
0x0: c_sf_s({{ cond = 0; }});
0x1: c_ngle_s({{
- if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf))
+ if (isnan(Fs.sf) || isnan(Ft.sf))
cond = 1;
else
cond = 0;
}});
0x2: c_seq_s({{
- if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf))
+ if (isnan(Fs.sf) || isnan(Ft.sf))
cond = 0;
else
cond = (Fs.sf == Ft.sf);
}});
0x3: c_ngl_s({{
- if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf))
+ if (isnan(Fs.sf) || isnan(Ft.sf))
cond = 1;
else
cond = (Fs.sf == Ft.sf);
}});
0x4: c_lt_s({{
- if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf))
+ if (isnan(Fs.sf) || isnan(Ft.sf))
cond = 0;
else
cond = (Fs.sf < Ft.sf);
}});
0x5: c_nge_s({{
- if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf))
+ if (isnan(Fs.sf) || isnan(Ft.sf))
cond = 1;
else
cond = (Fs.sf < Ft.sf);
}});
0x6: c_le_s({{
- if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf))
+ if (isnan(Fs.sf) || isnan(Ft.sf))
cond = 0;
else
cond = (Fs.sf <= Ft.sf);
}});
0x7: c_ngt_s({{
- if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf))
+ if (isnan(Fs.sf) || isnan(Ft.sf))
cond = 1;
else
cond = (Fs.sf <= Ft.sf);
@@ -715,37 +709,37 @@ decode OPCODE_HI default Unknown::unknown() {
0x1: decode FUNCTION_LO {
format FloatOp {
0x0: round_l_d({{
- Fd.ud = fpConvert(roundFP(Fs.ud), DOUBLE_TO_LONG);
+ Fd.ud = fpConvert(roundFP(Fs.df,0), DOUBLE_TO_LONG);
}});
0x1: trunc_l_d({{
- Fd.ud = fpConvert(truncFP(Fs.ud), DOUBLE_TO_LONG);
+ Fd.ud = fpConvert(truncFP(Fs.df), DOUBLE_TO_LONG);
}});
0x2: ceil_l_d({{
- Fd.ud = fpConvert(ceil(Fs.ud), DOUBLE_TO_LONG);
+ Fd.ud = fpConvert(ceil(Fs.df), DOUBLE_TO_LONG);
}});
0x3: floor_l_d({{
- Fd.ud = fpConvert(floor(Fs.ud), DOUBLE_TO_LONG);
+ Fd.ud = fpConvert(floor(Fs.df), DOUBLE_TO_LONG);
}});
}
format FloatOp {
0x4: round_w_d({{
- Fd.uw = fpConvert(roundFP(Fs.ud), DOUBLE_TO_WORD);
+ Fd.uw = fpConvert(roundFP(Fs.df,0), DOUBLE_TO_WORD);
}});
0x5: trunc_w_d({{
- Fd.uw = fpConvert(truncFP(Fs.ud), DOUBLE_TO_WORD);
+ Fd.uw = fpConvert(truncFP(Fs.df), DOUBLE_TO_WORD);
}});
0x6: ceil_w_d({{
- Fd.uw = fpConvert(ceil(Fs.ud), DOUBLE_TO_WORD);
+ Fd.uw = fpConvert(ceil(Fs.df), DOUBLE_TO_WORD);
}});
0x7: floor_w_d({{
- Fd.uw = fpConvert(floor(Fs.ud), DOUBLE_TO_WORD);
+ Fd.uw = fpConvert(floor(Fs.df), DOUBLE_TO_WORD);
}});
}
}
@@ -753,8 +747,8 @@ decode OPCODE_HI default Unknown::unknown() {
0x2: decode FUNCTION_LO {
0x1: decode MOVCF {
format FloatOp {
- 0x0: movf_d({{if (getFPConditionCode(CC) == 0) Fd.df = Fs.df; }});
- 0x1: movt_d({{if (getFPConditionCode(CC) == 1) Fd.df = Fs.df; }});
+ 0x0: movf_d({{if (getFPConditionCode(FCSR,CC) == 0) Fd.df = Fs.df; }});
+ 0x1: movt_d({{if (getFPConditionCode(FCSR,CC) == 1) Fd.df = Fs.df; }});
}
}
@@ -772,15 +766,15 @@ decode OPCODE_HI default Unknown::unknown() {
0x4: decode FUNCTION_LO {
format FloatOp {
0x0: cvt_s_d({{
- Fd.uw = fpConvert(Fs.ud, DOUBLE_TO_SINGLE);
+ Fd.uw = fpConvert(Fs.df, DOUBLE_TO_SINGLE);
}});
0x4: cvt_w_d({{
- Fd.uw = fpConvert(Fs.ud, DOUBLE_TO_WORD);
+ Fd.uw = fpConvert(Fs.df, DOUBLE_TO_WORD);
}});
0x5: cvt_l_d({{
- Fd.ud = fpConvert(Fs.ud, DOUBLE_TO_LONG);
+ Fd.ud = fpConvert(Fs.df, DOUBLE_TO_LONG);
}});
}
}
@@ -790,49 +784,49 @@ decode OPCODE_HI default Unknown::unknown() {
0x0: c_f_d({{ cond = 0; }});
0x1: c_un_d({{
- if (unorderedFP(Fs.df) || unorderedFP(Ft.df))
+ if (isnan(Fs.df) || isnan(Ft.df))
cond = 1;
else
cond = 0;
}});
0x2: c_eq_d({{
- if (unorderedFP(Fs.df) || unorderedFP(Ft.df))
+ if (isnan(Fs.df) || isnan(Ft.df))
cond = 0;
else
cond = (Fs.df == Ft.df);
}});
0x3: c_ueq_d({{
- if (unorderedFP(Fs.df) || unorderedFP(Ft.df))
+ if (isnan(Fs.df) || isnan(Ft.df))
cond = 1;
else
cond = (Fs.df == Ft.df);
}});
0x4: c_olt_d({{
- if (unorderedFP(Fs.df) || unorderedFP(Ft.df))
+ if (isnan(Fs.df) || isnan(Ft.df))
cond = 0;
else
cond = (Fs.df < Ft.df);
}});
0x5: c_ult_d({{
- if (unorderedFP(Fs.df) || unorderedFP(Ft.df))
+ if (isnan(Fs.df) || isnan(Ft.df))
cond = 1;
else
cond = (Fs.df < Ft.df);
}});
0x6: c_ole_d({{
- if (unorderedFP(Fs.df) || unorderedFP(Ft.df))
+ if (isnan(Fs.df) || isnan(Ft.df))
cond = 0;
else
cond = (Fs.df <= Ft.df);
}});
0x7: c_ule_d({{
- if (unorderedFP(Fs.df) || unorderedFP(Ft.df))
+ if (isnan(Fs.df) || isnan(Ft.df))
cond = 1;
else
cond = (Fs.df <= Ft.df);
@@ -845,49 +839,49 @@ decode OPCODE_HI default Unknown::unknown() {
0x0: c_sf_d({{ cond = 0; }});
0x1: c_ngle_d({{
- if (unorderedFP(Fs.df) || unorderedFP(Ft.df))
+ if (isnan(Fs.df) || isnan(Ft.df))
cond = 1;
else
cond = 0;
}});
0x2: c_seq_d({{
- if (unorderedFP(Fs.df) || unorderedFP(Ft.df))
+ if (isnan(Fs.df) || isnan(Ft.df))
cond = 0;
else
cond = (Fs.df == Ft.df);
}});
0x3: c_ngl_d({{
- if (unorderedFP(Fs.df) || unorderedFP(Ft.df))
+ if (isnan(Fs.df) || isnan(Ft.df))
cond = 1;
else
cond = (Fs.df == Ft.df);
}});
0x4: c_lt_d({{
- if (unorderedFP(Fs.df) || unorderedFP(Ft.df))
+ if (isnan(Fs.df) || isnan(Ft.df))
cond = 0;
else
cond = (Fs.df < Ft.df);
}});
0x5: c_nge_d({{
- if (unorderedFP(Fs.df) || unorderedFP(Ft.df))
+ if (isnan(Fs.df) || isnan(Ft.df))
cond = 1;
else
cond = (Fs.df < Ft.df);
}});
0x6: c_le_d({{
- if (unorderedFP(Fs.df) || unorderedFP(Ft.df))
+ if (isnan(Fs.df) || isnan(Ft.df))
cond = 0;
else
cond = (Fs.df <= Ft.df);
}});
0x7: c_ngt_d({{
- if (unorderedFP(Fs.df) || unorderedFP(Ft.df))
+ if (isnan(Fs.df) || isnan(Ft.df))
cond = 1;
else
cond = (Fs.df <= Ft.df);
@@ -976,16 +970,16 @@ decode OPCODE_HI default Unknown::unknown() {
0x1: decode MOVCF {
format Float64Op {
0x0: movf_ps({{
- if (getFPConditionCode(CC) == 0)
+ if (getFPConditionCode(FCSR, CC) == 0)
Fd1 = Fs1;
- if (getFPConditionCode(CC+1) == 0)
+ if (getFPConditionCode(FCSR, CC+1) == 0)
Fd2 = Fs2;
}});
0x1: movt_ps({{
- if (getFPConditionCode(CC) == 1)
+ if (getFPConditionCode(FCSR, CC) == 1)
Fd1 = Fs1;
- if (getFPConditionCode(CC+1) == 1)
+ if (getFPConditionCode(FCSR, CC+1) == 1)
Fd2 = Fs2;
}});
}
@@ -993,16 +987,16 @@ decode OPCODE_HI default Unknown::unknown() {
format Float64Op {
0x2: movz_ps({{
- if (getFPConditionCode(CC) == 0)
+ if (getFPConditionCode(FCSR, CC) == 0)
Fd1 = Fs1;
- if (getFPConditionCode(CC) == 0)
+ if (getFPConditionCode(FCSR, CC) == 0)
Fd2 = Fs2;
}});
0x3: movn_ps({{
- if (getFPConditionCode(CC) == 1)
+ if (getFPConditionCode(FCSR, CC) == 1)
Fd1 = Fs1;
- if (getFPConditionCode(CC) == 1)
+ if (getFPConditionCode(FCSR, CC) == 1)
Fd2 = Fs2;
}});
}
@@ -1033,12 +1027,12 @@ decode OPCODE_HI default Unknown::unknown() {
0x0: c_f_ps({{ cond1 = 0; cond2 = 0; }});
0x1: c_un_ps({{
- if (unorderedFP(Fs1.sf) || unorderedFP(Ft1.sf))
+ if (isnan(Fs1.sf) || isnan(Ft1.sf))
cond1 = 1;
else
cond1 = 0;
- if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf))
+ if (isnan(Fs2.sf) || isnan(Ft2.sf))
cond2 = 1;
else
cond2 = 0;
@@ -1046,72 +1040,72 @@ decode OPCODE_HI default Unknown::unknown() {
}});
0x2: c_eq_ps({{
- if (unorderedFP(Fs1.sf) || unorderedFP(Ft1.sf))
+ if (isnan(Fs1.sf) || isnan(Ft1.sf))
cond1 = 0;
else
cond1 = (Fs1.sf == Ft1.sf);
- if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf))
+ if (isnan(Fs2.sf) || isnan(Ft2.sf))
cond2 = 0;
else
cond2 = (Fs2.sf == Ft2.sf);
}});
0x3: c_ueq_ps({{
- if (unorderedFP(Fs1.sf) || unorderedFP(Ft1.sf))
+ if (isnan(Fs1.sf) || isnan(Ft1.sf))
cond1 = 1;
else
cond1 = (Fs1.sf == Ft1.sf);
- if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf))
+ if (isnan(Fs2.sf) || isnan(Ft2.sf))
cond2 = 1;
else
cond2 = (Fs2.sf == Ft2.sf);
}});
0x4: c_olt_ps({{
- if (unorderedFP(Fs1.sf) || unorderedFP(Ft1.sf))
+ if (isnan(Fs1.sf) || isnan(Ft1.sf))
cond1 = 0;
else
cond1 = (Fs1.sf < Ft1.sf);
- if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf))
+ if (isnan(Fs2.sf) || isnan(Ft2.sf))
cond2 = 0;
else
cond2 = (Fs2.sf < Ft2.sf);
}});
0x5: c_ult_ps({{
- if (unorderedFP(Fs1.sf) || unorderedFP(Ft1.sf))
+ if (isnan(Fs1.sf) || isnan(Ft1.sf))
cond1 = 1;
else
cond1 = (Fs.sf < Ft.sf);
- if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf))
+ if (isnan(Fs2.sf) || isnan(Ft2.sf))
cond2 = 1;
else
cond2 = (Fs2.sf < Ft2.sf);
}});
0x6: c_ole_ps({{
- if (unorderedFP(Fs.sf) || unorderedFP(Ft.sf))
+ if (isnan(Fs.sf) || isnan(Ft.sf))
cond1 = 0;
else
cond1 = (Fs.sf <= Ft.sf);
- if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf))
+ if (isnan(Fs2.sf) || isnan(Ft2.sf))
cond2 = 0;
else
cond2 = (Fs2.sf <= Ft2.sf);
}});
0x7: c_ule_ps({{
- if (unorderedFP(Fs1.sf) || unorderedFP(Ft1.sf))
+ if (isnan(Fs1.sf) || isnan(Ft1.sf))
cond1 = 1;
else
cond1 = (Fs1.sf <= Ft1.sf);
- if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf))
+ if (isnan(Fs2.sf) || isnan(Ft2.sf))
cond2 = 1;
else
cond2 = (Fs2.sf <= Ft2.sf);
@@ -1124,84 +1118,84 @@ decode OPCODE_HI default Unknown::unknown() {
0x0: c_sf_ps({{ cond1 = 0; cond2 = 0; }});
0x1: c_ngle_ps({{
- if (unorderedFP(Fs1.sf) || unorderedFP(Ft1.sf))
+ if (isnan(Fs1.sf) || isnan(Ft1.sf))
cond1 = 1;
else
cond1 = 0;
- if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf))
+ if (isnan(Fs2.sf) || isnan(Ft2.sf))
cond2 = 1;
else
cond2 = 0;
}});
0x2: c_seq_ps({{
- if (unorderedFP(Fs1.sf) || unorderedFP(Ft1.sf))
+ if (isnan(Fs1.sf) || isnan(Ft1.sf))
cond1 = 0;
else
cond1 = (Fs1.sf == Ft1.sf);
- if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf))
+ if (isnan(Fs2.sf) || isnan(Ft2.sf))
cond2 = 0;
else
cond2 = (Fs2.sf == Ft2.sf);
}});
0x3: c_ngl_ps({{
- if (unorderedFP(Fs1.sf) || unorderedFP(Ft1.sf))
+ if (isnan(Fs1.sf) || isnan(Ft1.sf))
cond1 = 1;
else
cond1 = (Fs1.sf == Ft1.sf);
- if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf))
+ if (isnan(Fs2.sf) || isnan(Ft2.sf))
cond2 = 1;
else
cond2 = (Fs2.sf == Ft2.sf);
}});
0x4: c_lt_ps({{
- if (unorderedFP(Fs1.sf) || unorderedFP(Ft1.sf))
+ if (isnan(Fs1.sf) || isnan(Ft1.sf))
cond1 = 0;
else
cond1 = (Fs1.sf < Ft1.sf);
- if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf))
+ if (isnan(Fs2.sf) || isnan(Ft2.sf))
cond2 = 0;
else
cond2 = (Fs2.sf < Ft2.sf);
}});
0x5: c_nge_ps({{
- if (unorderedFP(Fs1.sf) || unorderedFP(Ft1.sf))
+ if (isnan(Fs1.sf) || isnan(Ft1.sf))
cond1 = 1;
else
cond1 = (Fs1.sf < Ft1.sf);
- if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf))
+ if (isnan(Fs2.sf) || isnan(Ft2.sf))
cond2 = 1;
else
cond2 = (Fs2.sf < Ft2.sf);
}});
0x6: c_le_ps({{
- if (unorderedFP(Fs1.sf) || unorderedFP(Ft1.sf))
+ if (isnan(Fs1.sf) || isnan(Ft1.sf))
cond1 = 0;
else
cond1 = (Fs1.sf <= Ft1.sf);
- if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf))
+ if (isnan(Fs2.sf) || isnan(Ft2.sf))
cond2 = 0;
else
cond2 = (Fs2.sf <= Ft2.sf);
}});
0x7: c_ngt_ps({{
- if (unorderedFP(Fs1.sf) || unorderedFP(Ft1.sf))
+ if (isnan(Fs1.sf) || isnan(Ft1.sf))
cond1 = 1;
else
cond1 = (Fs1.sf <= Ft1.sf);
- if (unorderedFP(Fs2.sf) || unorderedFP(Ft2.sf))
+ if (isnan(Fs2.sf) || isnan(Ft2.sf))
cond2 = 1;
else
cond2 = (Fs2.sf <= Ft2.sf);
@@ -1326,34 +1320,34 @@ decode OPCODE_HI default Unknown::unknown() {
0x0: decode FUNCTION_LO {
format IntOp {
0x0: madd({{
- int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32;
+ int64_t temp1 = (int64_t) HI << 32 | LO;
temp1 = temp1 + (Rs.sw * Rt.sw);
- xc->setMiscReg(Hi,temp1<63:32>);
- xc->setMiscReg(Lo,temp1<31:0>);
- }});
+ HI = temp1<63:32>;
+ LO = temp1<31:0>;
+ }});
0x1: maddu({{
- int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32;
+ int64_t temp1 = (int64_t) HI << 32 | LO;
temp1 = temp1 + (Rs.uw * Rt.uw);
- xc->setMiscReg(Hi,temp1<63:32>);
- xc->setMiscReg(Lo,temp1<31:0>);
- }});
+ HI = temp1<63:32>;
+ LO = temp1<31:0>;
+ }});
0x2: mul({{ Rd.sw = Rs.sw * Rt.sw; }});
0x4: msub({{
- int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32;
+ int64_t temp1 = (int64_t) HI << 32 | LO;
temp1 = temp1 - (Rs.sw * Rt.sw);
- xc->setMiscReg(Hi,temp1<63:32>);
- xc->setMiscReg(Lo,temp1<31:0>);
- }});
+ HI = temp1<63:32>;
+ LO = temp1<31:0>;
+ }});
0x5: msubu({{
- int64_t temp1 = xc->readMiscReg(Hi) << 32 | xc->readMiscReg(Lo) >> 32;
+ int64_t temp1 = (int64_t) HI << 32 | LO;
temp1 = temp1 - (Rs.uw * Rt.uw);
- xc->setMiscReg(Hi,temp1<63:32>);
- xc->setMiscReg(Lo,temp1<31:0>);
- }});
+ HI = temp1<63:32>;
+ LO = temp1<31:0>;
+ }});
}
}
@@ -1416,8 +1410,8 @@ decode OPCODE_HI default Unknown::unknown() {
0x02: FailUnimpl::wsbh();
format BasicOp {
- 0x10: seb({{ Rd.sw = Rt<7:0>}});
- 0x18: seh({{ Rd.sw = Rt<15:0>}});
+ 0x10: seb({{ Rd.sw = Rt.sw<7:0>}});
+ 0x18: seh({{ Rd.sw = Rt.sw<15:0>}});
}
}
@@ -1519,8 +1513,6 @@ decode OPCODE_HI default Unknown::unknown() {
}},
{{ EA = (Rs + disp) & ~3; }});
}
-
- 0x7: FailUnimpl::reserved();
}
0x5: decode OPCODE_LO default FailUnimpl::reserved() {
diff --git a/arch/mips/isa/formats/branch.isa b/arch/mips/isa/formats/branch.isa
index 39db88c23..8cfa37a20 100644
--- a/arch/mips/isa/formats/branch.isa
+++ b/arch/mips/isa/formats/branch.isa
@@ -261,7 +261,7 @@ def format Branch(code,*flags) {{
#Add Link Code if Link instruction
strlen = len(name)
if name[strlen-2:] == 'al':
- code += 'r31 = NNPC;\n'
+ code += 'R31 = NNPC;\n'
#Condition code
code = 'bool cond;\n' + code
@@ -285,7 +285,7 @@ def format BranchLikely(code,*flags) {{
#Add Link Code if Link instruction
strlen = len(name)
if name[strlen-3:] == 'all':
- code += 'r31 = NNPC;\n'
+ code += 'R31 = NNPC;\n'
#Condition code
code = 'bool cond;\n' + code
@@ -307,7 +307,7 @@ def format Jump(code,*flags) {{
#Add Link Code if Link instruction
strlen = len(name)
if strlen > 1 and name[1:] == 'al':
- code = 'r31 = NNPC;\n' + code
+ code = 'R31 = NNPC;\n' + code
iop = InstObjParams(name, Name, 'Jump', CodeBlock(code),\
diff --git a/arch/mips/isa/formats/fp.isa b/arch/mips/isa/formats/fp.isa
index 0414e30c3..9f2c24755 100644
--- a/arch/mips/isa/formats/fp.isa
+++ b/arch/mips/isa/formats/fp.isa
@@ -41,6 +41,7 @@ def format FloatOp(code, *flags) {{
def format FloatCompareOp(code, *flags) {{
code = 'bool cond;\n' + code
+ code += 'FCSR = makeCCVector(FCSR, CC,cond);\n'
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
@@ -50,6 +51,7 @@ def format FloatCompareOp(code, *flags) {{
def format FloatCompareWithXcptOp(code, *flags) {{
code = 'bool cond;\n' + code
+ code += 'FCSR = makeCCVector(FCSR, CC,cond);\n'
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
@@ -75,6 +77,8 @@ def format Float64Op(code, *flags) {{
}};
def format Float64ConvertOp(code, *flags) {{
+ code = 'bool cond;\n' + code
+ code += 'FCSR = makeCCVector(FCSR, CC,cond);\n'
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
@@ -84,6 +88,8 @@ def format Float64ConvertOp(code, *flags) {{
def format FloatPSCompareOp(code, *flags) {{
code = 'bool cond1;\nbool cond2;\n' + code
+ code += 'FCSR = makeCCVector(FCSR, CC+1, cond1);\n'
+ code += 'FCSR = makeCCVector(FCSR, CC, cond2);\n'
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
@@ -93,6 +99,8 @@ def format FloatPSCompareOp(code, *flags) {{
def format FloatPSCompareWithXcptOp(code, *flags) {{
code = 'bool cond1;\nbool cond2;\n' + code
+ code += 'FCSR = makeCCVector(FCSR, CC+1, cond1);\n'
+ code += 'FCSR = makeCCVector(FCSR, CC, cond2);\n'
iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags)
header_output = BasicDeclare.subst(iop)
decoder_output = BasicConstructor.subst(iop)
diff --git a/arch/mips/isa/operands.isa b/arch/mips/isa/operands.isa
index b6b7b09d9..0f9c74b48 100644
--- a/arch/mips/isa/operands.isa
+++ b/arch/mips/isa/operands.isa
@@ -13,20 +13,35 @@ def operand_types {{
}};
def operands {{
+ #General Purpose Integer Reg Operands
'Rd': ('IntReg', 'uw', 'RD', 'IsInteger', 1),
'Rs': ('IntReg', 'uw', 'RS', 'IsInteger', 2),
'Rt': ('IntReg', 'uw', 'RT', 'IsInteger', 3),
- 'r31': ('IntReg', 'uw','R31','IsInteger', 4),
- 'R0': ('IntReg', 'uw','R0', 'IsInteger', 5),
+
+ #Operands used for Link or Syscall Insts
+ 'R31': ('IntReg', 'uw','31','IsInteger', 4),
'R2': ('IntReg', 'uw','2', 'IsInteger', 5),
+ #Special Integer Reg operands
+ 'HI': ('IntReg', 'uw','32', 'IsInteger', 6),
+ 'LO': ('IntReg', 'uw','33', 'IsInteger', 7),
+
+ #Immediate Value operand
'IntImm': ('IntReg', 'uw', 'INTIMM', 'IsInteger', 3),
+ #Floating Point Reg Operands
'Fd': ('FloatReg', 'sf', 'FD', 'IsFloating', 1),
'Fs': ('FloatReg', 'sf', 'FS', 'IsFloating', 2),
'Ft': ('FloatReg', 'sf', 'FT', 'IsFloating', 3),
'Fr': ('FloatReg', 'sf', 'FR', 'IsFloating', 3),
+ #Special Floating Point Control Reg Operands
+ 'FIR': ('FloatReg', 'uw', '32', 'IsFloating', 1),
+ 'FCCR': ('FloatReg', 'uw', '33', 'IsFloating', 2),
+ 'FEXR': ('FloatReg', 'uw', '34', 'IsFloating', 3),
+ 'FENR': ('FloatReg', 'uw', '35', 'IsFloating', 3),
+ 'FCSR': ('FloatReg', 'uw', '36', 'IsFloating', 3),
+
#Operands For Paired Singles FP Operations
'Fd1': ('FloatReg', 'sf', 'FD', 'IsFloating', 4),
'Fd2': ('FloatReg', 'sf', 'FD+1', 'IsFloating', 4),
@@ -37,9 +52,10 @@ def operands {{
'Fr1': ('FloatReg', 'sf', 'FR', 'IsFloating', 7),
'Fr2': ('FloatReg', 'sf', 'FR+1', 'IsFloating', 7),
-
+ #Memory Operand
'Mem': ('Mem', 'uw', None, ('IsMemRef', 'IsLoad', 'IsStore'), 4),
+ #Program Counter Operands
'NPC': ('NPC', 'uw', None, ( None, None, 'IsControl' ), 4),
'NNPC':('NNPC', 'uw', None, ( None, None, 'IsControl' ), 4)
}};
diff --git a/arch/mips/isa_traits.cc b/arch/mips/isa_traits.cc
index 19ef46291..216a6e2ec 100644
--- a/arch/mips/isa_traits.cc
+++ b/arch/mips/isa_traits.cc
@@ -96,41 +96,15 @@ MipsISA::fpConvert(double fp_val, ConvertType cvt_type)
}
}
-float
-MipsISA::roundFP(float val)
-{
- return 1.5;
-}
-
-float
-MipsISA::roundFP(uint64_t val)
-{
- return 1.5;
-}
-
double
-MipsISA::roundFP(double val)
+MipsISA::roundFP(double val, int digits)
{
- double trunc_val = trunc(val);
- double fraction = val - trunc_val;
-
- if (fraction < 0.5)
- return val;
- else
- return val + 1;
-}
-
-float
-MipsISA::truncFP(float val)
-{
- return 1.0;
-}
-
-double
-MipsISA::truncFP(uint64_t val)
-{
- int trunc_val = (int) val;
- return (double) trunc_val;
+ double digit_offset = pow(10.0,digits);
+ val = val * digit_offset;
+ val = val + 0.5;
+ val = floor(val);
+ val = val / digit_offset;
+ return val;
}
double
@@ -141,26 +115,20 @@ MipsISA::truncFP(double val)
}
bool
-MipsISA::unorderedFP(float val)
+MipsISA::getFPConditionCode(uint32_t fcsr_reg, int cc)
{
- return false;
+ //uint32_t cc_bits = xc->readFloatReg(35);
+ return false;//regFile.floatRegfile.getConditionCode(cc);
}
-bool
-MipsISA::unorderedFP(double val)
+uint32_t
+MipsISA::makeCCVector(uint32_t fcsr, int num, bool val)
{
- return false;
-}
+ int shift = (num == 0) ? 22 : num + 23;
-bool
-MipsISA::getFPConditionCode(int cc)
-{
- return false;
-}
+ fcsr = fcsr | (val << shift);
-void
-MipsISA::setFPConditionCode(int num, bool val)
-{
+ return fcsr;
}
#if FULL_SYSTEM
diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh
index 6788806c1..148c405df 100644
--- a/arch/mips/isa_traits.hh
+++ b/arch/mips/isa_traits.hh
@@ -31,7 +31,7 @@
#include "arch/mips/constants.hh"
#include "arch/mips/types.hh"
-#include "arch/mips/regfile.hh"
+#include "arch/mips/regfile/regfile.hh"
#include "arch/mips/faults.hh"
#include "arch/mips/utility.hh"
#include "base/misc.hh"
@@ -138,19 +138,10 @@ namespace MipsISA
void copyRegs(ExecContext *src, ExecContext *dest);
uint64_t fpConvert(double fp_val, ConvertType cvt_type);
-
- float roundFP(float val);
- double roundFP(double val);
- float roundFP(uint64_t val);
-
- float truncFP(float val);
- double truncFP(uint64_t val);
+ double roundFP(double val, int digits);
double truncFP(double val);
-
- bool unorderedFP(float val);
- bool unorderedFP(double val);
- bool getFPConditionCode(int cc);
- void setFPConditionCode(int num, bool val);
+ bool getFPConditionCode(uint32_t fcsr_reg, int cc);
+ uint32_t makeCCVector(uint32_t fcsr, int num, bool val);
// Machine operations
diff --git a/arch/mips/regfile/float_regfile.hh b/arch/mips/regfile/float_regfile.hh
index 308d418a0..15c6f97f4 100644
--- a/arch/mips/regfile/float_regfile.hh
+++ b/arch/mips/regfile/float_regfile.hh
@@ -47,14 +47,6 @@ namespace MipsISA
{
protected:
FloatReg32 regs[NumFloatRegs];
- FloatReg32 fir;
- FloatReg32 fcsr;
-
- FloatReg32 fpcr;
-
- FloatReg32 fccr;
- FloatReg32 fexr;
- FloatReg32 fenr;
public:
@@ -65,8 +57,6 @@ namespace MipsISA
double readReg(int floatReg, int width)
{
- using namespace std;
-
switch(width)
{
case SingleWidth:
@@ -85,16 +75,23 @@ namespace MipsISA
FloatRegBits readRegBits(int floatReg, int width)
{
- switch(width)
- {
- case SingleWidth:
- return regs[floatReg];
-
- case DoubleWidth:
- return (FloatReg64)regs[floatReg + 1] << 32 | regs[floatReg];
+ if (floatReg < NumFloatArchRegs - 1) {
+ switch(width)
+ {
+ case SingleWidth:
+ return regs[floatReg];
+
+ case DoubleWidth:
+ return (FloatReg64)regs[floatReg + 1] << 32 | regs[floatReg];
+
+ default:
+ panic("Attempted to read a %d bit floating point register!", width);
+ }
+ } else {
+ if (width > SingleWidth)
+ assert("Control Regs are only 32 bits wide");
- default:
- panic("Attempted to read a %d bit floating point register!", width);
+ return regs[floatReg];
}
}
@@ -144,44 +141,19 @@ namespace MipsISA
return NoFault;
}
- MiscReg readFIR()
- {
- return fir;
- }
-
- Fault setFIR(const MiscReg &val)
- {
- fir = val;
- return NoFault;
- }
-
- MiscReg readFCSR()
- {
- return fcsr;
- }
-
- Fault setFCSR(const MiscReg &val)
- {
- fcsr = val;
- return NoFault;
- }
-
- MiscReg readFPCR()
- {
- return fpcr;
- }
-
- Fault setFPCR(const MiscReg &val)
- {
- fpcr = val;
- return NoFault;
- }
-
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
};
+ enum MiscFloatRegNums {
+ FIR = NumFloatArchRegs,
+ FCCR,
+ FEXR,
+ FENR,
+ FCSR
+ };
+
} // namespace MipsISA
#endif
diff --git a/arch/mips/regfile/int_regfile.hh b/arch/mips/regfile/int_regfile.hh
index cff9eb0d2..3cd87734d 100644
--- a/arch/mips/regfile/int_regfile.hh
+++ b/arch/mips/regfile/int_regfile.hh
@@ -31,6 +31,7 @@
#include "arch/mips/types.hh"
#include "arch/mips/constants.hh"
+#include "base/misc.hh"
#include "sim/faults.hh"
class Checkpoint;
@@ -43,8 +44,6 @@ namespace MipsISA
{
protected:
IntReg regs[NumIntRegs];
- IntReg hi;
- IntReg lo;
public:
IntReg readReg(int intReg)
@@ -58,33 +57,17 @@ namespace MipsISA
return NoFault;
}
- IntReg readHi()
- {
- return hi;
- }
-
- Fault setHi(const IntReg &val)
- {
- hi = val;
- return NoFault;
- }
-
- IntReg readLo()
- {
- return lo;
- }
-
- Fault setLo(const IntReg &val)
- {
- lo = val;
- return NoFault;
- }
-
void serialize(std::ostream &os);
void unserialize(Checkpoint *cp, const std::string &section);
};
+
+ enum MiscIntRegNums {
+ HI = NumIntArchRegs,
+ LO
+ };
+
} // namespace MipsISA
#endif
diff --git a/arch/mips/regfile.hh b/arch/mips/regfile/regfile.hh
index bd825d479..e77571b33 100644
--- a/arch/mips/regfile.hh
+++ b/arch/mips/regfile/regfile.hh
@@ -58,31 +58,7 @@ namespace MipsISA
MiscReg readMiscReg(int miscReg)
{
- if (miscReg < CtrlReg_DepTag)
- return miscRegFile.readReg(miscReg);
- else {
- switch (miscReg)
- {
- case Hi:
- return intRegFile.readHi();
-
- case Lo:
- return intRegFile.readLo();
-
- case FIR:
- return floatRegFile.readFIR();
-
- case FCSR:
- return floatRegFile.readFCSR();
-
- case FPCR:
- return floatRegFile.readFPCR();
-
- default:
- panic("Invalid Misc. Reg. Access\n");
- return 0;
- }
- }
+ return miscRegFile.readReg(miscReg);
}
MiscReg readMiscRegWithEffect(int miscReg,
@@ -94,31 +70,7 @@ namespace MipsISA
Fault setMiscReg(int miscReg, const MiscReg &val)
{
- if (miscReg < CtrlReg_DepTag)
- return miscRegFile.setReg(miscReg, val);
- else {
- switch (miscReg)
- {
- case Hi:
- return intRegFile.setHi(val);
-
- case Lo:
- return intRegFile.setLo(val);
-
- case FIR:
- return floatRegFile.setFIR(val);
-
- case FCSR:
- return floatRegFile.setFCSR(val);
-
- case FPCR:
- return floatRegFile.setFPCR(val);
-
- default:
- panic("Invalid Misc. Reg. Access\n");
- return 0;
- }
- }
+ return miscRegFile.setReg(miscReg, val);
}
Fault setMiscRegWithEffect(int miscReg, const MiscReg &val,
diff --git a/dev/ide_disk.hh b/dev/ide_disk.hh
index 3d67abece..891c462b5 100644
--- a/dev/ide_disk.hh
+++ b/dev/ide_disk.hh
@@ -33,6 +33,7 @@
#ifndef __IDE_DISK_HH__
#define __IDE_DISK_HH__
+#include "base/statistics.hh"
#include "dev/disk_image.hh"
#include "dev/ide_atareg.h"
#include "dev/ide_ctrl.hh"
@@ -231,6 +232,13 @@ class IdeDisk : public SimObject
/** Interrupt pending */
bool intrPending;
+ Stats::Scalar<> dmaReadFullPages;
+ Stats::Scalar<> dmaReadBytes;
+ Stats::Scalar<> dmaReadTxs;
+ Stats::Scalar<> dmaWriteFullPages;
+ Stats::Scalar<> dmaWriteBytes;
+ Stats::Scalar<> dmaWriteTxs;
+
public:
/**
* Create and initialize this Disk.
@@ -252,6 +260,12 @@ class IdeDisk : public SimObject
void reset(int id);
/**
+ * Register statistics.
+ */
+ void regStats();
+
+
+ /**
* Set the controller for this device
* @param c The IDE controller
*/
diff --git a/dev/sinic.cc b/dev/sinic.cc
index b5b6c6cf5..66ca88dbe 100644
--- a/dev/sinic.cc
+++ b/dev/sinic.cc
@@ -81,7 +81,8 @@ Base::Base(Params *p)
}
Device::Device(Params *p)
- : Base(p), rxFifo(p->rx_fifo_size), txFifo(p->tx_fifo_size),
+ : Base(p), plat(p->plat), physmem(p->physmem), rxUnique(0), txUnique(0),
+ virtualRegs(p->virtual_count < 1 ? 1 : p->virtual_count),
rxKickTick(0), txKickTick(0),
txEvent(this), rxDmaEvent(this), txDmaEvent(this),
dmaReadDelay(p->dma_read_delay), dmaReadFactor(p->dma_read_factor),
@@ -268,12 +269,9 @@ void
Device::prepareIO(int cpu, int index)
{
int size = virtualRegs.size();
- if (index < size)
- return;
-
- virtualRegs.resize(index + 1);
- for (int i = size; i <= index; ++i)
- virtualRegs[i].rxPacket = rxFifo.end();
+ if (index > size)
+ panic("Trying to access a vnic that doesn't exist %d > %d\n",
+ index, size);
}
void
@@ -286,7 +284,10 @@ Device::prepareRead(int cpu, int index)
// update rx registers
uint64_t rxdone = vnic.RxDone;
- rxdone = set_RxDone_Packets(rxdone, rxFifo.packets());
+ rxdone = set_RxDone_Packets(rxdone, rxFifo.countPacketsAfter(rxFifoPtr));
+ rxdone = set_RxDone_Empty(rxdone, rxFifo.empty());
+ rxdone = set_RxDone_High(rxdone, rxFifo.size() > regs.RxFifoMark);
+ rxdone = set_RxDone_NotHigh(rxdone, rxLow);
regs.RxData = vnic.RxData;
regs.RxDone = rxdone;
regs.RxWait = rxdone;
@@ -325,17 +326,18 @@ Device::read(Packet &pkt)
pkt.allocate();
if (!regValid(raddr))
- panic("invalid register: cpu=%d, da=%#x pa=%#x size=%d",
- cpu, daddr, pkt.addr, pkt.size);
+ panic("invalid register: cpu=%d vnic=%d da=%#x pa=%#x size=%d",
+ cpu, index, daddr, pkt.addr, pkt.size);
const Regs::Info &info = regInfo(raddr);
if (!info.read)
- panic("reading %s (write only): cpu=%d da=%#x pa=%#x size=%d",
- info.name, cpu, daddr, pkt.addr, pkt.size);
+ panic("read %s (write only): "
+ "cpu=%d vnic=%d da=%#x pa=%#x size=%d",
+ info.name, cpu, index, daddr, pkt.addr, pkt.size);
- if (pkt.size != info.size)
- panic("invalid size for reg %s: cpu=%d da=%#x pa=%#x size=%d",
- info.name, cpu, daddr, pkt.addr, pkt.size);
+ panic("read %s (invalid size): "
+ "cpu=%d vnic=%d da=%#x pa=%#x size=%d",
+ info.name, cpu, index, daddr, pkt.addr, pkt.size);
prepareRead(cpu, index);
@@ -353,8 +355,8 @@ Device::read(Packet &pkt)
}
DPRINTF(EthernetPIO,
- "read %s cpu=%d da=%#x pa=%#x size=%d val=%#x\n",
- info.name, cpu, daddr, pkt.addr, pkt.size, value);
+ "read %s: cpu=%d vnic=%d da=%#x pa=%#x size=%d val=%#x\n",
+ info.name, cpu, index, daddr, pkt.addr, pkt.size, value);
// reading the interrupt status register has the side effect of
// clearing it
@@ -416,18 +418,20 @@ Device::write(Packet &pkt)
const Regs::Info &info = regInfo(raddr);
if (!info.write)
- panic("write %s (read only): cpu=%d da=%#x pa=%#x size=%d",
- info.name, cpu, daddr, pkt.addr, pkt.size);
+ panic("write %s (read only): "
+ "cpu=%d vnic=%d da=%#x pa=%#x size=%d",
+ info.name, cpu, index, daddr, pkt.addr, pkt.size);
if (pkt.size != info.size)
- panic("invalid size for reg %s: cpu=%d da=%#x pa=%#x size=%d",
- info.name, cpu, daddr, pkt.addr, pkt.size);
+ panic("write %s (invalid size): "
+ "cpu=%d vnic=%d da=%#x pa=%#x size=%d",
+ info.name, cpu, index, daddr, pkt.addr, pkt.size);
VirtualReg &vnic = virtualRegs[index];
DPRINTF(EthernetPIO,
- "write %s: cpu=%d val=%#x da=%#x pa=%#x size=%d\n",
- info.name, cpu, info.size == 4 ? pkt.get<uint32_t>() :
+ "write %s vnic %d: cpu=%d val=%#x da=%#x pa=%#x size=%d\n",
+ info.name, index, cpu, info.size == 4 ? pkt.get<uint32_t>() :
pkt.get<uint64_t>(), daddr, pkt.addr, pkt.size);
prepareWrite(cpu, index);
@@ -454,10 +458,32 @@ Device::write(Packet &pkt)
panic("receive machine busy with another request! rxState=%s",
RxStateStrings[rxState]);
+ vnic.rxUnique = rxUnique++;
vnic.RxDone = Regs::RxDone_Busy;
vnic.RxData = pkt.get<uint64_t>();
- rxList.push_back(index);
- if (rxEnable && rxState == rxIdle) {
+
+ if (Regs::get_RxData_Vaddr(reg64)) {
+ Addr vaddr = Regs::get_RxData_Addr(reg64);
+ Addr paddr = vtophys(req->xc, vaddr);
+ DPRINTF(EthernetPIO, "write RxData vnic %d (rxunique %d): "
+ "vaddr=%#x, paddr=%#x\n",
+ index, vnic.rxUnique, vaddr, paddr);
+
+ vnic.RxData = Regs::set_RxData_Addr(vnic.RxData, paddr);
+ } else {
+ DPRINTF(EthernetPIO, "write RxData vnic %d (rxunique %d)\n",
+ index, vnic.rxUnique);
+ }
+
+ if (vnic.rxPacket == rxFifo.end()) {
+ DPRINTF(EthernetPIO, "request new packet...appending to rxList\n");
+ rxList.push_back(index);
+ } else {
+ DPRINTF(EthernetPIO, "packet exists...appending to rxBusy\n");
+ rxBusy.push_back(index);
+ }
+
+ if (rxEnable && (rxState == rxIdle || rxState == rxFifoBlock)) {
rxState = rxFifoBlock;
rxKick();
}
@@ -468,8 +494,23 @@ Device::write(Packet &pkt)
panic("transmit machine busy with another request! txState=%s",
TxStateStrings[txState]);
+ vnic.txUnique = txUnique++;
vnic.TxDone = Regs::TxDone_Busy;
- vnic.TxData = pkt.get<uint64_t>();
+
+ if (Regs::get_TxData_Vaddr(pkt.get<uint64_t>())) {
+ panic("vtophys won't work here in newmem.\n");
+ /*Addr vaddr = Regs::get_TxData_Addr(reg64);
+ Addr paddr = vtophys(req->xc, vaddr);
+ DPRINTF(EthernetPIO, "write TxData vnic %d (rxunique %d): "
+ "vaddr=%#x, paddr=%#x\n",
+ index, vnic.txUnique, vaddr, paddr);
+
+ vnic.TxData = Regs::set_TxData_Addr(vnic.TxData, paddr);*/
+ } else {
+ DPRINTF(EthernetPIO, "write TxData vnic %d (rxunique %d)\n",
+ index, vnic.txUnique);
+ }
+
if (txList.empty() || txList.front() != index)
txList.push_back(index);
if (txEnable && txState == txIdle && txList.front() == index) {
@@ -695,10 +736,21 @@ Device::reset()
regs.Config |= Config_TxThread;
if (params()->rss)
regs.Config |= Config_RSS;
+ if (params()->zero_copy)
+ regs.Config |= Config_ZeroCopy;
+ if (params()->delay_copy)
+ regs.Config |= Config_DelayCopy;
+ if (params()->virtual_addr)
+ regs.Config |= Config_Vaddr;
+
+ if (params()->delay_copy && params()->zero_copy)
+ panic("Can't delay copy and zero copy");
+
regs.IntrMask = Intr_Soft | Intr_RxHigh | Intr_RxPacket | Intr_TxLow;
regs.RxMaxCopy = params()->rx_max_copy;
regs.TxMaxCopy = params()->tx_max_copy;
regs.RxMaxIntr = params()->rx_max_intr;
+ regs.VirtualCount = params()->virtual_count;
regs.RxFifoSize = params()->rx_fifo_size;
regs.TxFifoSize = params()->tx_fifo_size;
regs.RxFifoMark = params()->rx_fifo_threshold;
@@ -706,6 +758,8 @@ Device::reset()
regs.HwAddr = params()->eaddr;
rxList.clear();
+ rxBusy.clear();
+ rxActive = -1;
txList.clear();
rxState = rxIdle;
@@ -715,6 +769,7 @@ Device::reset()
rxFifoPtr = rxFifo.end();
txFifo.clear();
rxEmpty = false;
+ rxLow = true;
txFull = false;
int size = virtualRegs.size();
@@ -729,7 +784,7 @@ Device::rxDmaDone()
{
assert(rxState == rxCopy);
rxState = rxCopyDone;
- DPRINTF(EthernetDMA, "rx dma write paddr=%#x len=%d\n",
+ DPRINTF(EthernetDMA, "end rx dma write paddr=%#x len=%d\n",
rxDmaAddr, rxDmaLen);
DDUMP(EthernetData, rxDmaData, rxDmaLen);
@@ -743,13 +798,13 @@ Device::rxDmaDone()
void
Device::rxKick()
{
- VirtualReg *vnic;
+ VirtualReg *vnic = NULL;
- DPRINTF(EthernetSM, "receive kick rxState=%s (rxFifo.size=%d)\n",
+ DPRINTF(EthernetSM, "rxKick: rxState=%s (rxFifo.size=%d)\n",
RxStateStrings[rxState], rxFifo.size());
if (rxKickTick > curTick) {
- DPRINTF(EthernetSM, "receive kick exiting, can't run till %d\n",
+ DPRINTF(EthernetSM, "rxKick: exiting, can't run till %d\n",
rxKickTick);
return;
}
@@ -758,16 +813,50 @@ Device::rxKick()
if (rxState == rxIdle)
goto exit;
- assert(!rxList.empty());
- vnic = &virtualRegs[rxList.front()];
+ if (rxActive == -1) {
+ if (rxState != rxFifoBlock)
+ panic("no active vnic while in state %s", RxStateStrings[rxState]);
- DPRINTF(EthernetSM, "processing rxState=%s for virtual nic %d\n",
- RxStateStrings[rxState], rxList.front());
+ DPRINTF(EthernetSM, "processing rxState=%s\n",
+ RxStateStrings[rxState]);
+ } else {
+ vnic = &virtualRegs[rxActive];
+ DPRINTF(EthernetSM,
+ "processing rxState=%s for vnic %d (rxunique %d)\n",
+ RxStateStrings[rxState], rxActive, vnic->rxUnique);
+ }
switch (rxState) {
case rxFifoBlock:
- if (vnic->rxPacket != rxFifo.end()) {
+ if (DTRACE(EthernetSM)) {
+ PacketFifo::iterator end = rxFifo.end();
+ int size = virtualRegs.size();
+ for (int i = 0; i < size; ++i) {
+ VirtualReg *vn = &virtualRegs[i];
+ if (vn->rxPacket != end &&
+ !Regs::get_RxDone_Busy(vn->RxDone)) {
+ DPRINTF(EthernetSM,
+ "vnic %d (rxunique %d), has outstanding packet %d\n",
+ i, vn->rxUnique,
+ rxFifo.countPacketsBefore(vn->rxPacket));
+ }
+ }
+ }
+
+ if (!rxBusy.empty()) {
+ rxActive = rxBusy.front();
+ rxBusy.pop_front();
+ vnic = &virtualRegs[rxActive];
+
+ if (vnic->rxPacket == rxFifo.end())
+ panic("continuing vnic without packet\n");
+
+ DPRINTF(EthernetSM,
+ "continue processing for vnic %d (rxunique %d)\n",
+ rxActive, vnic->rxUnique);
+
rxState = rxBeginCopy;
+
break;
}
@@ -776,8 +865,19 @@ Device::rxKick()
goto exit;
}
+ if (rxList.empty())
+ panic("Not idle, but nothing to do!");
+
assert(!rxFifo.empty());
+ rxActive = rxList.front();
+ rxList.pop_front();
+ vnic = &virtualRegs[rxActive];
+
+ DPRINTF(EthernetSM,
+ "processing new packet for vnic %d (rxunique %d)\n",
+ rxActive, vnic->rxUnique);
+
// Grab a new packet from the fifo.
vnic->rxPacket = rxFifoPtr++;
vnic->rxPacketOffset = 0;
@@ -788,6 +888,7 @@ Device::rxKick()
/* scope for variables */ {
IpPtr ip(*vnic->rxPacket);
if (ip) {
+ DPRINTF(Ethernet, "ID is %d\n", ip->id());
vnic->rxDoneData |= Regs::RxDone_IpPacket;
rxIpChecksums++;
if (cksum(ip) != 0) {
@@ -797,6 +898,10 @@ Device::rxKick()
TcpPtr tcp(ip);
UdpPtr udp(ip);
if (tcp) {
+ DPRINTF(Ethernet,
+ "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
+ tcp->sport(), tcp->dport(), tcp->seq(),
+ tcp->ack());
vnic->rxDoneData |= Regs::RxDone_TcpPacket;
rxTcpChecksums++;
if (cksum(tcp) != 0) {
@@ -826,6 +931,11 @@ Device::rxKick()
vnic->rxPacketBytes);
rxDmaData = (*vnic->rxPacket)->data + vnic->rxPacketOffset;
rxState = rxCopy;
+ if (rxDmaAddr == 1LL) {
+ rxState = rxCopyDone;
+ break;
+ }
+
dmaWrite(rxDmaAddr, rxDmaLen, &rxDmaEvent, rxDmaData);
break;
@@ -835,31 +945,44 @@ Device::rxKick()
goto exit;
case rxCopyDone:
- vnic->RxDone = vnic->rxDoneData | rxDmaLen;
+ vnic->RxDone = vnic->rxDoneData;
vnic->RxDone |= Regs::RxDone_Complete;
if (vnic->rxPacketBytes == rxDmaLen) {
- DPRINTF(EthernetSM, "rxKick: packet complete on vnic %d\n",
- rxList.front());
+ // Packet is complete. Indicate how many bytes were copied
+ vnic->RxDone = Regs::set_RxDone_CopyLen(vnic->RxDone, rxDmaLen);
+
+ DPRINTF(EthernetSM,
+ "rxKick: packet complete on vnic %d (rxunique %d)\n",
+ rxActive, vnic->rxUnique);
rxFifo.remove(vnic->rxPacket);
vnic->rxPacket = rxFifo.end();
} else {
- vnic->RxDone |= Regs::RxDone_More;
vnic->rxPacketBytes -= rxDmaLen;
vnic->rxPacketOffset += rxDmaLen;
+ vnic->RxDone |= Regs::RxDone_More;
+ vnic->RxDone = Regs::set_RxDone_CopyLen(vnic->RxDone,
+ vnic->rxPacketBytes);
DPRINTF(EthernetSM,
- "rxKick: packet not complete on vnic %d: %d bytes left\n",
- rxList.front(), vnic->rxPacketBytes);
+ "rxKick: packet not complete on vnic %d (rxunique %d): "
+ "%d bytes left\n",
+ rxActive, vnic->rxUnique, vnic->rxPacketBytes);
}
- rxList.pop_front();
- rxState = rxList.empty() ? rxIdle : rxFifoBlock;
+ rxActive = -1;
+ rxState = rxBusy.empty() && rxList.empty() ? rxIdle : rxFifoBlock;
if (rxFifo.empty()) {
devIntrPost(Regs::Intr_RxEmpty);
rxEmpty = true;
}
+ if (rxFifo.size() < params()->rx_fifo_low_mark)
+ rxLow = true;
+
+ if (rxFifo.size() > params()->rx_fifo_threshold)
+ rxLow = false;
+
devIntrPost(Regs::Intr_RxDMA);
break;
@@ -920,8 +1043,10 @@ Device::transmit()
DPRINTF(Ethernet, "ID is %d\n", ip->id());
TcpPtr tcp(ip);
if (tcp) {
- DPRINTF(Ethernet, "Src Port=%d, Dest Port=%d\n",
- tcp->sport(), tcp->dport());
+ DPRINTF(Ethernet,
+ "Src Port=%d, Dest Port=%d, Seq=%d, Ack=%d\n",
+ tcp->sport(), tcp->dport(), tcp->seq(),
+ tcp->ack());
}
}
}
@@ -950,11 +1075,11 @@ void
Device::txKick()
{
VirtualReg *vnic;
- DPRINTF(EthernetSM, "transmit kick txState=%s (txFifo.size=%d)\n",
+ DPRINTF(EthernetSM, "txKick: txState=%s (txFifo.size=%d)\n",
TxStateStrings[txState], txFifo.size());
if (txKickTick > curTick) {
- DPRINTF(EthernetSM, "transmit kick exiting, can't run till %d\n",
+ DPRINTF(EthernetSM, "txKick: exiting, can't run till %d\n",
txKickTick);
return;
}
@@ -968,7 +1093,7 @@ Device::txKick()
switch (txState) {
case txFifoBlock:
- assert(Regs::get_TxDone_Busy(vnic->TxData));
+ assert(Regs::get_TxDone_Busy(vnic->TxDone));
if (!txPacket) {
// Grab a new packet from the fifo.
txPacket = new EthPacketData(16384);
@@ -1213,6 +1338,8 @@ Base::unserialize(Checkpoint *cp, const std::string &section)
void
Device::serialize(std::ostream &os)
{
+ int count;
+
// Serialize the PciDev base class
Base::serialize(os);
@@ -1233,6 +1360,7 @@ Device::serialize(std::ostream &os)
SERIALIZE_SCALAR(regs.RxMaxCopy);
SERIALIZE_SCALAR(regs.TxMaxCopy);
SERIALIZE_SCALAR(regs.RxMaxIntr);
+ SERIALIZE_SCALAR(regs.VirtualCount);
SERIALIZE_SCALAR(regs.RxData);
SERIALIZE_SCALAR(regs.RxDone);
SERIALIZE_SCALAR(regs.TxData);
@@ -1252,8 +1380,6 @@ Device::serialize(std::ostream &os)
paramOut(os, reg + ".TxData", vnic->TxData);
paramOut(os, reg + ".TxDone", vnic->TxDone);
- PacketFifo::iterator rxFifoPtr;
-
bool rxPacketExists = vnic->rxPacket != rxFifo.end();
paramOut(os, reg + ".rxPacketExists", rxPacketExists);
if (rxPacketExists) {
@@ -1272,18 +1398,26 @@ Device::serialize(std::ostream &os)
paramOut(os, reg + ".rxDoneData", vnic->rxDoneData);
}
- VirtualList::iterator i, end;
- int count;
+ int rxFifoPtr = rxFifo.countPacketsBefore(this->rxFifoPtr);
+ SERIALIZE_SCALAR(rxFifoPtr);
- int rxListSize = rxList.size();
- SERIALIZE_SCALAR(rxListSize);
+ SERIALIZE_SCALAR(rxActive);
+
+ VirtualList::iterator i, end;
for (count = 0, i = rxList.begin(), end = rxList.end(); i != end; ++i)
paramOut(os, csprintf("rxList%d", count++), *i);
+ int rxListSize = count;
+ SERIALIZE_SCALAR(rxListSize);
+
+ for (count = 0, i = rxBusy.begin(), end = rxBusy.end(); i != end; ++i)
+ paramOut(os, csprintf("rxBusy%d", count++), *i);
+ int rxBusySize = count;
+ SERIALIZE_SCALAR(rxBusySize);
- int txListSize = txList.size();
- SERIALIZE_SCALAR(txListSize);
for (count = 0, i = txList.begin(), end = txList.end(); i != end; ++i)
paramOut(os, csprintf("txList%d", count++), *i);
+ int txListSize = count;
+ SERIALIZE_SCALAR(txListSize);
/*
* Serialize rx state machine
@@ -1291,6 +1425,7 @@ Device::serialize(std::ostream &os)
int rxState = this->rxState;
SERIALIZE_SCALAR(rxState);
SERIALIZE_SCALAR(rxEmpty);
+ SERIALIZE_SCALAR(rxLow);
rxFifo.serialize("rxFifo", os);
/*
@@ -1331,11 +1466,14 @@ Device::unserialize(Checkpoint *cp, const std::string &section)
UNSERIALIZE_SCALAR(regs.RxMaxCopy);
UNSERIALIZE_SCALAR(regs.TxMaxCopy);
UNSERIALIZE_SCALAR(regs.RxMaxIntr);
+ UNSERIALIZE_SCALAR(regs.VirtualCount);
UNSERIALIZE_SCALAR(regs.RxData);
UNSERIALIZE_SCALAR(regs.RxDone);
UNSERIALIZE_SCALAR(regs.TxData);
UNSERIALIZE_SCALAR(regs.TxDone);
+ UNSERIALIZE_SCALAR(rxActive);
+
int rxListSize;
UNSERIALIZE_SCALAR(rxListSize);
rxList.clear();
@@ -1345,6 +1483,15 @@ Device::unserialize(Checkpoint *cp, const std::string &section)
rxList.push_back(value);
}
+ int rxBusySize;
+ UNSERIALIZE_SCALAR(rxBusySize);
+ rxBusy.clear();
+ for (int i = 0; i < rxBusySize; ++i) {
+ int value;
+ paramIn(cp, section, csprintf("rxBusy%d", i), value);
+ rxBusy.push_back(value);
+ }
+
int txListSize;
UNSERIALIZE_SCALAR(txListSize);
txList.clear();
@@ -1360,9 +1507,16 @@ Device::unserialize(Checkpoint *cp, const std::string &section)
int rxState;
UNSERIALIZE_SCALAR(rxState);
UNSERIALIZE_SCALAR(rxEmpty);
+ UNSERIALIZE_SCALAR(rxLow);
this->rxState = (RxState) rxState;
rxFifo.unserialize("rxFifo", cp, section);
+ int rxFifoPtr;
+ UNSERIALIZE_SCALAR(rxFifoPtr);
+ this->rxFifoPtr = rxFifo.begin();
+ for (int i = 0; i < rxFifoPtr; ++i)
+ ++this->rxFifoPtr;
+
/*
* Unserialize tx state machine
*/
@@ -1400,6 +1554,9 @@ Device::unserialize(Checkpoint *cp, const std::string &section)
paramIn(cp, section, reg + ".TxData", vnic->TxData);
paramIn(cp, section, reg + ".TxDone", vnic->TxDone);
+ vnic->rxUnique = rxUnique++;
+ vnic->txUnique = txUnique++;
+
bool rxPacketExists;
paramIn(cp, section, reg + ".rxPacketExists", rxPacketExists);
if (rxPacketExists) {
@@ -1488,6 +1645,8 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device)
Param<uint32_t> rx_fifo_size;
Param<uint32_t> tx_fifo_size;
Param<uint32_t> rx_fifo_threshold;
+ Param<uint32_t> rx_fifo_low_mark;
+ Param<uint32_t> tx_fifo_high_mark;
Param<uint32_t> tx_fifo_threshold;
Param<bool> rx_filter;
@@ -1495,6 +1654,10 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device)
Param<bool> rx_thread;
Param<bool> tx_thread;
Param<bool> rss;
+ Param<uint32_t> virtual_count;
+ Param<bool> zero_copy;
+ Param<bool> delay_copy;
+ Param<bool> virtual_addr;
END_DECLARE_SIM_OBJECT_PARAMS(Device)
@@ -1525,13 +1688,19 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(Device)
INIT_PARAM(rx_fifo_size, "max size in bytes of rxFifo"),
INIT_PARAM(tx_fifo_size, "max size in bytes of txFifo"),
INIT_PARAM(rx_fifo_threshold, "max size in bytes of rxFifo"),
+ INIT_PARAM(rx_fifo_low_mark, "max size in bytes of rxFifo"),
+ INIT_PARAM(tx_fifo_high_mark, "max size in bytes of txFifo"),
INIT_PARAM(tx_fifo_threshold, "max size in bytes of txFifo"),
INIT_PARAM(rx_filter, "Enable Receive Filter"),
INIT_PARAM(hardware_address, "Ethernet Hardware Address"),
INIT_PARAM(rx_thread, ""),
INIT_PARAM(tx_thread, ""),
- INIT_PARAM(rss, "")
+ INIT_PARAM(rss, ""),
+ INIT_PARAM(virtual_count, ""),
+ INIT_PARAM(zero_copy, ""),
+ INIT_PARAM(delay_copy, ""),
+ INIT_PARAM(virtual_addr, "")
END_INIT_SIM_OBJECT_PARAMS(Device)
@@ -1564,6 +1733,8 @@ CREATE_SIM_OBJECT(Device)
params->rx_fifo_size = rx_fifo_size;
params->tx_fifo_size = tx_fifo_size;
params->rx_fifo_threshold = rx_fifo_threshold;
+ params->rx_fifo_low_mark = rx_fifo_low_mark;
+ params->tx_fifo_high_mark = tx_fifo_high_mark;
params->tx_fifo_threshold = tx_fifo_threshold;
params->rx_filter = rx_filter;
@@ -1571,6 +1742,10 @@ CREATE_SIM_OBJECT(Device)
params->rx_thread = rx_thread;
params->tx_thread = tx_thread;
params->rss = rss;
+ params->virtual_count = virtual_count;
+ params->zero_copy = zero_copy;
+ params->delay_copy = delay_copy;
+ params->virtual_addr = virtual_addr;
return new Device(params);
}
diff --git a/dev/sinic.hh b/dev/sinic.hh
index 63a8585dc..a786c3e44 100644
--- a/dev/sinic.hh
+++ b/dev/sinic.hh
@@ -117,7 +117,7 @@ class Device : public Base
uint32_t RxMaxCopy; // 0x10
uint32_t TxMaxCopy; // 0x14
uint32_t RxMaxIntr; // 0x18
- uint32_t Reserved0; // 0x1c
+ uint32_t VirtualCount; // 0x1c
uint32_t RxFifoSize; // 0x20
uint32_t TxFifoSize; // 0x24
uint32_t RxFifoMark; // 0x28
@@ -142,6 +142,9 @@ class Device : public Base
int rxPacketBytes;
uint64_t rxDoneData;
+ Counter rxUnique;
+ Counter txUnique;
+
VirtualReg()
: RxData(0), RxDone(0), TxData(0), TxDone(0),
rxPacketOffset(0), rxPacketBytes(0), rxDoneData(0)
@@ -149,8 +152,12 @@ class Device : public Base
};
typedef std::vector<VirtualReg> VirtualRegs;
typedef std::list<int> VirtualList;
+ Counter rxUnique;
+ Counter txUnique;
VirtualRegs virtualRegs;
VirtualList rxList;
+ VirtualList rxBusy;
+ int rxActive;
VirtualList txList;
uint8_t &regData8(Addr daddr) { return *((uint8_t *)&regs + daddr); }
@@ -162,6 +169,7 @@ class Device : public Base
PacketFifo rxFifo;
PacketFifo::iterator rxFifoPtr;
bool rxEmpty;
+ bool rxLow;
Addr rxDmaAddr;
uint8_t *rxDmaData;
int rxDmaLen;
@@ -318,6 +326,8 @@ class Device : public Base
uint32_t rx_fifo_size;
uint32_t tx_fifo_size;
uint32_t rx_fifo_threshold;
+ uint32_t rx_fifo_low_mark;
+ uint32_t tx_fifo_high_mark;
uint32_t tx_fifo_threshold;
Tick dma_read_delay;
Tick dma_read_factor;
@@ -326,6 +336,10 @@ class Device : public Base
bool rx_thread;
bool tx_thread;
bool rss;
+ uint32_t virtual_count;
+ bool zero_copy;
+ bool delay_copy;
+ bool virtual_addr;
};
protected:
diff --git a/dev/sinicreg.hh b/dev/sinicreg.hh
index f90432398..d41eb5b16 100644
--- a/dev/sinicreg.hh
+++ b/dev/sinicreg.hh
@@ -55,38 +55,40 @@
namespace Sinic {
namespace Regs {
-static const int VirtualMask = 0xff;
static const int VirtualShift = 8;
+static const int VirtualMask = 0xff;
// Registers
-__SINIC_REG32(Config, 0x00); // 32: configuration register
-__SINIC_REG32(Command, 0x04); // 32: command register
-__SINIC_REG32(IntrStatus, 0x08); // 32: interrupt status
-__SINIC_REG32(IntrMask, 0x0c); // 32: interrupt mask
-__SINIC_REG32(RxMaxCopy, 0x10); // 32: max bytes per rx copy
-__SINIC_REG32(TxMaxCopy, 0x14); // 32: max bytes per tx copy
-__SINIC_REG32(RxMaxIntr, 0x18); // 32: max receives per interrupt
-__SINIC_REG32(Reserved0, 0x1c); // 32: reserved
-__SINIC_REG32(RxFifoSize, 0x20); // 32: rx fifo capacity in bytes
-__SINIC_REG32(TxFifoSize, 0x24); // 32: tx fifo capacity in bytes
-__SINIC_REG32(RxFifoMark, 0x28); // 32: rx fifo high watermark
-__SINIC_REG32(TxFifoMark, 0x2c); // 32: tx fifo low watermark
-__SINIC_REG32(RxData, 0x30); // 64: receive data
-__SINIC_REG32(RxDone, 0x38); // 64: receive done
-__SINIC_REG32(RxWait, 0x40); // 64: receive done (busy wait)
-__SINIC_REG32(TxData, 0x48); // 64: transmit data
-__SINIC_REG32(TxDone, 0x50); // 64: transmit done
-__SINIC_REG32(TxWait, 0x58); // 64: transmit done (busy wait)
-__SINIC_REG32(HwAddr, 0x60); // 64: mac address
-__SINIC_REG32(Size, 0x68); // register addres space size
+__SINIC_REG32(Config, 0x00); // 32: configuration register
+__SINIC_REG32(Command, 0x04); // 32: command register
+__SINIC_REG32(IntrStatus, 0x08); // 32: interrupt status
+__SINIC_REG32(IntrMask, 0x0c); // 32: interrupt mask
+__SINIC_REG32(RxMaxCopy, 0x10); // 32: max bytes per rx copy
+__SINIC_REG32(TxMaxCopy, 0x14); // 32: max bytes per tx copy
+__SINIC_REG32(RxMaxIntr, 0x18); // 32: max receives per interrupt
+__SINIC_REG32(VirtualCount, 0x1c); // 32: number of virutal NICs
+__SINIC_REG32(RxFifoSize, 0x20); // 32: rx fifo capacity in bytes
+__SINIC_REG32(TxFifoSize, 0x24); // 32: tx fifo capacity in bytes
+__SINIC_REG32(RxFifoMark, 0x28); // 32: rx fifo high watermark
+__SINIC_REG32(TxFifoMark, 0x2c); // 32: tx fifo low watermark
+__SINIC_REG32(RxData, 0x30); // 64: receive data
+__SINIC_REG32(RxDone, 0x38); // 64: receive done
+__SINIC_REG32(RxWait, 0x40); // 64: receive done (busy wait)
+__SINIC_REG32(TxData, 0x48); // 64: transmit data
+__SINIC_REG32(TxDone, 0x50); // 64: transmit done
+__SINIC_REG32(TxWait, 0x58); // 64: transmit done (busy wait)
+__SINIC_REG32(HwAddr, 0x60); // 64: mac address
+__SINIC_REG32(Size, 0x68); // register addres space size
// Config register bits
+__SINIC_VAL32(Config_ZeroCopy, 12, 1); // enable zero copy
+__SINIC_VAL32(Config_DelayCopy,11, 1); // enable delayed copy
__SINIC_VAL32(Config_RSS, 10, 1); // enable receive side scaling
__SINIC_VAL32(Config_RxThread, 9, 1); // enable receive threads
__SINIC_VAL32(Config_TxThread, 8, 1); // enable transmit thread
__SINIC_VAL32(Config_Filter, 7, 1); // enable receive filter
__SINIC_VAL32(Config_Vlan, 6, 1); // enable vlan tagging
-__SINIC_VAL32(Config_Virtual, 5, 1); // enable virtual addressing
+__SINIC_VAL32(Config_Vaddr, 5, 1); // enable virtual addressing
__SINIC_VAL32(Config_Desc, 4, 1); // enable tx/rx descriptors
__SINIC_VAL32(Config_Poll, 3, 1); // enable polling
__SINIC_VAL32(Config_IntEn, 2, 1); // enable interrupts
@@ -112,13 +114,15 @@ __SINIC_REG32(Intr_NoDelay, 0x01cc); // interrupts that aren't coalesced
__SINIC_REG32(Intr_Res, ~0x01ff); // reserved interrupt bits
// RX Data Description
-__SINIC_VAL64(RxData_Len, 40, 20); // 0 - 1M
-__SINIC_VAL64(RxData_Addr, 0, 40); // Address 1TB
+__SINIC_VAL64(RxData_Vaddr, 60, 1); // Addr is virtual
+__SINIC_VAL64(RxData_Len, 40, 20); // 0 - 256k
+__SINIC_VAL64(RxData_Addr, 0, 40); // Address 1TB
// TX Data Description
__SINIC_VAL64(TxData_More, 63, 1); // Packet not complete (will dma more)
__SINIC_VAL64(TxData_Checksum, 62, 1); // do checksum
-__SINIC_VAL64(TxData_Len, 40, 20); // 0 - 1M
+__SINIC_VAL64(TxData_Vaddr, 60, 1); // Addr is virtual
+__SINIC_VAL64(TxData_Len, 40, 20); // 0 - 256k
__SINIC_VAL64(TxData_Addr, 0, 40); // Address 1TB
// RX Done/Busy Information
@@ -126,9 +130,9 @@ __SINIC_VAL64(RxDone_Packets, 32, 16); // number of packets in rx fifo
__SINIC_VAL64(RxDone_Busy, 31, 1); // receive dma busy copying
__SINIC_VAL64(RxDone_Complete, 30, 1); // valid data (packet complete)
__SINIC_VAL64(RxDone_More, 29, 1); // Packet has more data (dma again)
-__SINIC_VAL64(RxDone_Res0, 28, 1); // reserved
-__SINIC_VAL64(RxDone_Res1, 27, 1); // reserved
-__SINIC_VAL64(RxDone_Res2, 26, 1); // reserved
+__SINIC_VAL64(RxDone_Empty, 28, 1); // rx fifo is empty
+__SINIC_VAL64(RxDone_High, 27, 1); // rx fifo is above the watermark
+__SINIC_VAL64(RxDone_NotHigh, 26, 1); // rxfifo never hit the high watermark
__SINIC_VAL64(RxDone_TcpError, 25, 1); // TCP packet error (bad checksum)
__SINIC_VAL64(RxDone_UdpError, 24, 1); // UDP packet error (bad checksum)
__SINIC_VAL64(RxDone_IpError, 23, 1); // IP packet error (bad checksum)
@@ -175,7 +179,7 @@ regInfo(Addr daddr)
{ 4, true, false, "RxMaxCopy" },
{ 4, true, false, "TxMaxCopy" },
{ 4, true, false, "RxMaxIntr" },
- invalid,
+ { 4, true, false, "VirtualCount" },
{ 4, true, false, "RxFifoSize" },
{ 4, true, false, "TxFifoSize" },
{ 4, true, false, "RxFifoMark" },
diff --git a/python/m5/objects/Ethernet.py b/python/m5/objects/Ethernet.py
index 0667fc6d7..4286c71c8 100644
--- a/python/m5/objects/Ethernet.py
+++ b/python/m5/objects/Ethernet.py
@@ -101,8 +101,14 @@ class Sinic(EtherDevBase):
rx_max_copy = Param.MemorySize('1514B', "rx max copy")
tx_max_copy = Param.MemorySize('16kB', "tx max copy")
rx_max_intr = Param.UInt32(10, "max rx packets per interrupt")
- rx_fifo_threshold = Param.MemorySize('48kB', "rx fifo high threshold")
- tx_fifo_threshold = Param.MemorySize('16kB', "tx fifo low threshold")
+ rx_fifo_threshold = Param.MemorySize('384kB', "rx fifo high threshold")
+ rx_fifo_low_mark = Param.MemorySize('128kB', "rx fifo low threshold")
+ tx_fifo_high_mark = Param.MemorySize('384kB', "tx fifo high threshold")
+ tx_fifo_threshold = Param.MemorySize('128kB', "tx fifo low threshold")
+ virtual_count = Param.UInt32(1, "Virtualized SINIC")
+ zero_copy = Param.Bool(False, "Zero copy receive")
+ delay_copy = Param.Bool(False, "Delayed copy transmit")
+ virtual_addr = Param.Bool(False, "Virtual addressing")
class SinicInt(EtherInt):
type = 'SinicInt'
diff --git a/sim/serialize.cc b/sim/serialize.cc
index ec7241498..c4ef124bb 100644
--- a/sim/serialize.cc
+++ b/sim/serialize.cc
@@ -51,8 +51,9 @@
using namespace std;
-int Serializable::maxCount = 0;
-int Serializable::count = 0;
+int Serializable::ckptMaxCount = 0;
+int Serializable::ckptCount = 0;
+int Serializable::ckptPrevCount = -1;
void
Serializable::nameOut(ostream &os)
@@ -241,8 +242,11 @@ Serializable::serializeAll()
globals.serialize(outstream);
SimObject::serializeAll(outstream);
- if (maxCount && ++count >= maxCount)
+ assert(Serializable::ckptPrevCount + 1 == Serializable::ckptCount);
+ Serializable::ckptPrevCount++;
+ if (ckptMaxCount && ++ckptCount >= ckptMaxCount)
SimExit(curTick + 1, "Maximum number of checkpoints dropped");
+
}
@@ -352,7 +356,7 @@ SerializeParamContext::checkParams()
if (serialize_cycle > 0)
Checkpoint::setup(serialize_cycle, serialize_period);
- Serializable::maxCount = serialize_count;
+ Serializable::ckptMaxCount = serialize_count;
}
void
diff --git a/sim/serialize.hh b/sim/serialize.hh
index bc82bf9b8..d8f5f8fc5 100644
--- a/sim/serialize.hh
+++ b/sim/serialize.hh
@@ -119,8 +119,9 @@ class Serializable
static Serializable *create(Checkpoint *cp,
const std::string &section);
- static int count;
- static int maxCount;
+ static int ckptCount;
+ static int ckptMaxCount;
+ static int ckptPrevCount;
static void serializeAll();
static void unserializeGlobals(Checkpoint *cp);
};
diff --git a/util/stats/barchart.py b/util/stats/barchart.py
index 5d6dd0ab1..a477d1f3b 100644
--- a/util/stats/barchart.py
+++ b/util/stats/barchart.py
@@ -233,7 +233,7 @@ class BarChart(ChartOptions):
inner_axes.set_yticks(ticks)
inner_axes.set_yticklabels(self.yticks)
elif self.ylim is not None:
- self.inner_axes.set_ylim(self.ylim)
+ inner_axes.set_ylim(self.ylim)
if self.xticks is not None:
outer_axes.set_xticks(arange(cshape[2]) + .5)
@@ -242,9 +242,9 @@ class BarChart(ChartOptions):
if self.xsubticks is not None:
numticks = (cshape[0] + 1) * cshape[2]
inner_axes.set_xticks(arange(numticks) * width + 2 * center)
- self.xsubticks.append('')
- inner_axes.set_xticklabels(self.xsubticks * cshape[2], fontsize=7,
- rotation=90)
+ xsubticks = list(self.xsubticks) + [ '' ]
+ inner_axes.set_xticklabels(xsubticks * cshape[2], fontsize=7,
+ rotation=30)
if self.legend is not None:
if dim == 1: