diff options
60 files changed, 1910 insertions, 2081 deletions
diff --git a/SConscript b/SConscript index 05515562f..cac083b6b 100644 --- a/SConscript +++ b/SConscript @@ -186,12 +186,25 @@ full_system_sources = Split(''' dev/alpha_console.cc dev/baddev.cc dev/disk_image.cc + dev/etherbus.cc + dev/etherdump.cc + dev/etherint.cc + dev/etherlink.cc + dev/etherpkt.cc + dev/ethertap.cc + dev/ide_ctrl.cc + dev/ide_disk.cc dev/io_device.cc dev/isa_fake.cc + dev/ns_gige.cc dev/pciconfigall.cc + dev/pcidev.cc + dev/pcifake.cc + dev/pktfifo.cc dev/platform.cc dev/simconsole.cc dev/simple_disk.cc + dev/sinic.cc dev/tsunami.cc dev/tsunami_cchip.cc dev/tsunami_io.cc @@ -213,19 +226,6 @@ full_system_sources = Split(''' sim/pseudo_inst.cc ''') -# dev/etherbus.cc -# dev/etherdump.cc -# dev/etherint.cc -# dev/etherlink.cc -# dev/etherpkt.cc -# dev/ethertap.cc -# dev/ide_ctrl.cc -# dev/ide_disk.cc -# dev/ns_gige.cc -# dev/pcidev.cc -# dev/pcifake.cc -# dev/pktfifo.cc -# dev/sinic.cc if env['TARGET_ISA'] == 'alpha': full_system_sources += Split(''' @@ -360,7 +360,7 @@ env.Append(CPPPATH='./libelf') # Debug binary debugEnv = env.Copy(OBJSUFFIX='.do') debugEnv.Label = 'debug' -debugEnv.Append(CCFLAGS=Split('-g -gstabs+ -O0')) +debugEnv.Append(CCFLAGS=Split('-g3 -gdwarf-2 -O0')) debugEnv.Append(CPPDEFINES='DEBUG') tlist = debugEnv.Program(target = 'm5.debug', source = make_objs(sources, debugEnv)) @@ -369,7 +369,7 @@ debugEnv.M5Binary = tlist[0] # Optimized binary optEnv = env.Copy() optEnv.Label = 'opt' -optEnv.Append(CCFLAGS=Split('-g -O5')) +optEnv.Append(CCFLAGS=Split('-g -O3')) tlist = optEnv.Program(target = 'm5.opt', source = make_objs(sources, optEnv)) optEnv.M5Binary = tlist[0] @@ -377,7 +377,7 @@ optEnv.M5Binary = tlist[0] # "Fast" binary fastEnv = env.Copy(OBJSUFFIX='.fo') fastEnv.Label = 'fast' -fastEnv.Append(CCFLAGS=Split('-O5')) +fastEnv.Append(CCFLAGS=Split('-O3')) fastEnv.Append(CPPDEFINES='NDEBUG') fastEnv.Program(target = 'm5.fast.unstripped', source = make_objs(sources, fastEnv)) @@ -389,7 +389,7 @@ fastEnv.M5Binary = tlist[0] # Profiled binary profEnv = env.Copy(OBJSUFFIX='.po') profEnv.Label = 'prof' -profEnv.Append(CCFLAGS=Split('-O5 -g -pg'), LINKFLAGS='-pg') +profEnv.Append(CCFLAGS=Split('-O3 -g -pg'), LINKFLAGS='-pg') tlist = profEnv.Program(target = 'm5.prof', source = make_objs(sources, profEnv)) profEnv.M5Binary = tlist[0] diff --git a/arch/isa_parser.py b/arch/isa_parser.py index 8279a6a5d..921a6fa82 100755 --- a/arch/isa_parser.py +++ b/arch/isa_parser.py @@ -1334,7 +1334,7 @@ class NPCOperand(Operand): return '' def makeRead(self): - return '%s = xc->readPC() + 4;\n' % self.base_name + return '%s = xc->readNextPC();\n' % self.base_name def makeWrite(self): return 'xc->setNextPC(%s);\n' % self.base_name @@ -1344,7 +1344,7 @@ class NNPCOperand(Operand): return '' def makeRead(self): - return '%s = xc->readPC() + 8;\n' % self.base_name + return '%s = xc->readNextNPC();\n' % self.base_name def makeWrite(self): return 'xc->setNextNPC(%s);\n' % self.base_name diff --git a/arch/mips/isa/decoder.isa b/arch/mips/isa/decoder.isa index 077f0afd0..6feaec7cb 100644 --- a/arch/mips/isa/decoder.isa +++ b/arch/mips/isa/decoder.isa @@ -394,36 +394,82 @@ decode OPCODE_HI default Unknown::unknown() { 0x0: decode RS_HI { 0x0: decode RS_LO { - format WarnUnimpl { - 0x0: mfc1();//{{ /*Rt.uw = Fs.ud<31:0>;*/ }} - 0x3: mfhc1();// /*Rt.uw = Fs.ud<63:32>*/; - 0x4: mtc1();// /*Fs = Rt.uw*/ - 0x7: mthc1();//{{/*Fs<63:32> = Rt.uw*/}} + format FloatOp { + 0x0: mfc1 ({{ Rt.uw = Fs.uw<31:0>; }}); + 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_lo = Fs.ud & 0x0000FFFF; + Fs.ud = fs_hi & fs_lo; + }}); } format System { 0x2: cfc1({{ uint32_t fcsr_reg = xc->readMiscReg(FCSR); - if (Fs == 0){ + switch (FS) + { + case 0: Rt = xc->readMiscReg(FIR); - } else if (Fs == 25) { + break; + case 25: Rt = 0 | (fcsr_reg & 0xFE000000) >> 24 | (fcsr_reg & 0x00800000) >> 23; - } else if (Fs == 26) { + break; + case 26: Rt = 0 | (fcsr_reg & 0x0003F07C); - } else if (Fs == 28) { + break; + case 28: Rt = 0 | (fcsr_reg); - } else if (Fs == 31) { + break; + case 31: Rt = fcsr_reg; - } else { + break; + default: panic("FP Control Value (%d) Not Available. Ignoring Access to" "Floating Control Status Register",fcsr_reg); } - }}); 0x6: ctc1({{ - /*xc->setMiscReg(FPCR[Fs],Rt);*/ + 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 + break; + + case 26: + temp = 0 | (fcsr_reg & 0xFFFC0000) // move 31...18 + | Rt.uw<17:12> << 12 // bit 17...12 + | (fcsr_reg & 0x00000F80) << 7// bit 11...7 + | Rt.uw<6:2> << 2 // bit 6...2 + | (fcsr_reg & 0x00000002); // bit 1...0 + break; + + case 28: + temp = 0 | (fcsr_reg & 0xFE000000) // move 31...25 + | Rt.uw<2:2> << 24 // bit 24 + | (fcsr_reg & 0x00FFF000) << 23// bit 23...12 + | Rt.uw<11:7> << 7 // bit 24 + | (fcsr_reg & 0x000007E) + | Rt.uw<1:0>;// bit 22...0 + break; + + case 31: + temp = Rt.uw; + break; + + default: + panic("FP Control Value (%d) Not Available. Ignoring Access to" + "Floating Control Status Register",fcsr_reg); + } + + xc->setMiscReg(FCSR,temp); }}); } } @@ -450,8 +496,8 @@ decode OPCODE_HI default Unknown::unknown() { //Table A-14 MIPS32 COP1 Encoding of Function Field When rs=S //(( single-word )) - 0x0: decode RS_HI { - 0x0: decode RS_LO { + 0x0: decode FUNCTION_HI { + 0x0: decode FUNCTION_LO { format FloatOp { 0x0: adds({{ Fd.sf = Fs.sf + Ft.sf;}}); 0x1: subs({{ Fd.sf = Fs.sf - Ft.sf;}}); @@ -464,24 +510,45 @@ decode OPCODE_HI default Unknown::unknown() { } } - 0x1: decode RS_LO { - //only legal for 64 bit-FP + 0x1: decode FUNCTION_LO { format Float64Op { - 0x0: round_l_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_LONG,FP_SINGLE);}}); - 0x1: trunc_l_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_LONG,FP_SINGLE);}}); - 0x2: ceil_l_s({{ Fd = convert_and_round(Fs.sf,RND_UP,FP_LONG,FP_SINGLE);}}); - 0x3: floor_l_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_LONG,FP_SINGLE);}}); + 0x0: round_l_s({{ + Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_NEAREST); + }}); + + 0x1: trunc_l_s({{ + Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_ZERO); + }}); + + 0x2: ceil_l_s({{ + Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_UP); + }}); + + 0x3: floor_l_s({{ + Fd = convert_and_round(Fs.uw, SINGLE_TO_LONG, RND_DOWN); + }}); } format FloatOp { - 0x4: round_w_s({{ Fd = convert_and_round(Fs.sf,RND_NEAREST,FP_WORD,FP_SINGLE);}}); - 0x5: trunc_w_s({{ Fd = convert_and_round(Fs.sf,RND_ZERO,FP_WORD,FP_SINGLE);}}); - 0x6: ceil_w_s({{ Fd = convert_and_round(Fs.sf,RND_UP,FP_WORD,FP_SINGLE);}}); - 0x7: floor_w_s({{ Fd = convert_and_round(Fs.sf,RND_DOWN,FP_WORD,FP_SINGLE);}}); + 0x4: round_w_s({{ + Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_NEAREST); + }}); + + 0x5: trunc_w_s({{ + Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_ZERO); + }}); + + 0x6: ceil_w_s({{ + Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_UP); + }}); + + 0x7: floor_w_s({{ + Fd = convert_and_round(Fs.uw, SINGLE_TO_WORD, RND_DOWN); + }}); } } - 0x2: decode RS_LO { + 0x2: decode FUNCTION_LO { 0x1: decode MOVCF { format FloatOp { 0x0: movfs({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs; }}); @@ -500,32 +567,37 @@ decode OPCODE_HI default Unknown::unknown() { } } - 0x4: decode RS_LO { + 0x4: decode FUNCTION_LO { format FloatOp { - 0x1: cvt_d_s({{ int rnd_mode = xc->readMiscReg(FCSR); - Fd = convert_and_round(Fs.sf,rnd_mode,FP_DOUBLE,FP_SINGLE); + 0x1: cvt_d_s({{ + int rnd_mode = xc->readMiscReg(FCSR) & 0x03; + Fd.uw = convert_and_round(Fs.ud, SINGLE_TO_DOUBLE, rnd_mode); }}); - 0x4: cvt_w_s({{ int rnd_mode = xc->readMiscReg(FCSR); - Fd = convert_and_round(Fs.sf,rnd_mode,FP_WORD,FP_SINGLE); + 0x4: cvt_w_s({{ + int rnd_mode = xc->readMiscReg(FCSR) & 0x03; + Fd.uw = convert_and_round(Fs.uw, SINGLE_TO_WORD, rnd_mode); }}); } //only legal for 64 bit format Float64Op { - 0x5: cvt_l_s({{ int rnd_mode = xc->readMiscReg(FCSR); - Fd = convert_and_round(Fs.sf,rnd_mode,FP_LONG,FP_SINGLE); + 0x5: cvt_l_s({{ + int rnd_mode = xc->readMiscReg(FCSR) & 0x03; + Fd.uw = convert_and_round(Fs.ud, SINGLE_TO_LONG, rnd_mode); }}); - 0x6: cvt_ps_s({{ /*Fd.df = Fs.df<31:0> | Ft.df<31:0>;*/ }}); + 0x6: cvt_ps_st({{ + Fd.ud = (uint64_t)Fs.uw << 32 | (uint64_t)Ft.uw; + }}); } } } //Table A-15 MIPS32 COP1 Encoding of Function Field When rs=D - 0x1: decode RS_HI { - 0x0: decode RS_LO { + 0x1: decode FUNCTION_HI { + 0x0: decode FUNCTION_LO { format FloatOp { 0x0: addd({{ Fd.df = Fs.df + Ft.df;}}); 0x1: subd({{ Fd.df = Fs.df - Ft.df;}}); @@ -538,24 +610,45 @@ decode OPCODE_HI default Unknown::unknown() { } } - 0x1: decode RS_LO { - //only legal for 64 bit + 0x1: decode FUNCTION_LO { format Float64Op { - 0x0: round_l_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }}); - 0x1: trunc_l_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE);}}); - 0x2: ceil_l_d({{ Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE);}}); - 0x3: floor_l_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE);}}); + 0x0: round_l_d({{ + Fd = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_NEAREST); + }}); + + 0x1: trunc_l_d({{ + Fd = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_ZERO); + }}); + + 0x2: ceil_l_d({{ + Fd = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_UP); + }}); + + 0x3: floor_l_d({{ + Fd = convert_and_round(Fs.ud, DOUBLE_TO_LONG, RND_DOWN); + }}); } format FloatOp { - 0x4: round_w_d({{ Fd = convert_and_round(Fs.df,RND_NEAREST,FP_LONG,FP_DOUBLE); }}); - 0x5: trunc_w_d({{ Fd = convert_and_round(Fs.df,RND_ZERO,FP_LONG,FP_DOUBLE); }}); - 0x6: ceil_w_d({{ Fd = convert_and_round(Fs.df,RND_UP,FP_LONG,FP_DOUBLE); }}); - 0x7: floor_w_d({{ Fd = convert_and_round(Fs.df,RND_DOWN,FP_LONG,FP_DOUBLE); }}); + 0x4: round_w_d({{ + Fd = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_NEAREST); + }}); + + 0x5: trunc_w_d({{ + Fd = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_ZERO); + }}); + + 0x6: ceil_w_d({{ + Fd = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_UP); + }}); + + 0x7: floor_w_d({{ + Fd = convert_and_round(Fs.ud, DOUBLE_TO_WORD, RND_DOWN); + }}); } } - 0x2: decode RS_LO { + 0x2: decode FUNCTION_LO { 0x1: decode MOVCF { format FloatOp { 0x0: movfd({{if (xc->readMiscReg(FPCR) != CC) Fd.df = Fs.df; }}); @@ -574,24 +667,24 @@ decode OPCODE_HI default Unknown::unknown() { } } - 0x4: decode RS_LO { + 0x4: decode FUNCTION_LO { format FloatOp { 0x0: cvt_s_d({{ - int rnd_mode = xc->readMiscReg(FCSR); - Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_DOUBLE); + int rnd_mode = xc->readMiscReg(FCSR) & 0x03; + Fd = convert_and_round(Fs.ud, DOUBLE_TO_SINGLE, rnd_mode); }}); 0x4: cvt_w_d({{ - int rnd_mode = xc->readMiscReg(FCSR); - Fd = convert_and_round(Fs.df,rnd_mode,FP_WORD,FP_DOUBLE); + int rnd_mode = xc->readMiscReg(FCSR) & 0x03; + Fd = convert_and_round(Fs.ud, DOUBLE_TO_WORD, rnd_mode); }}); } //only legal for 64 bit format Float64Op { 0x5: cvt_l_d({{ - int rnd_mode = xc->readMiscReg(FCSR); - Fd = convert_and_round(Fs.df,rnd_mode,FP_LONG,FP_DOUBLE); + int rnd_mode = xc->readMiscReg(FCSR) & 0x03; + Fd = convert_and_round(Fs.ud, DOUBLE_TO_LONG, rnd_mode); }}); } } @@ -600,14 +693,14 @@ decode OPCODE_HI default Unknown::unknown() { //Table A-16 MIPS32 COP1 Encoding of Function Field When rs=W 0x4: decode FUNCTION { format FloatOp { - 0x20: cvt_s({{ - int rnd_mode = xc->readMiscReg(FCSR); - Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_WORD); + 0x20: cvt_s_w({{ + int rnd_mode = xc->readMiscReg(FCSR) & 0x03; + Fd = convert_and_round(Fs.uw, WORD_TO_SINGLE, rnd_mode); }}); - 0x21: cvt_d({{ - int rnd_mode = xc->readMiscReg(FCSR); - Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_WORD); + 0x21: cvt_d_w({{ + int rnd_mode = xc->readMiscReg(FCSR) & 0x03; + Fd = convert_and_round(Fs.uw, WORD_TO_DOUBLE, rnd_mode); }}); } } @@ -616,15 +709,15 @@ decode OPCODE_HI default Unknown::unknown() { //Note: "1. Format type L is legal only if 64-bit floating point operations //are enabled." 0x5: decode FUNCTION_HI { - format FloatOp { + format Float64Op { 0x10: cvt_s_l({{ - int rnd_mode = xc->readMiscReg(FCSR); - Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_LONG); + int rnd_mode = xc->readMiscReg(FCSR) & 0x03; + Fd = convert_and_round(Fs.ud, LONG_TO_SINGLE, rnd_mode); }}); 0x11: cvt_d_l({{ - int rnd_mode = xc->readMiscReg(FCSR); - Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_LONG); + int rnd_mode = xc->readMiscReg(FCSR) & 0x03; + Fd = convert_and_round(Fs.ud, LONG_TO_DOUBLE, rnd_mode); }}); } } @@ -632,8 +725,8 @@ decode OPCODE_HI default Unknown::unknown() { //Table A-17 MIPS64 COP1 Encoding of Function Field When rs=PS1 //Note: "1. Format type PS is legal only if 64-bit floating point operations //are enabled. " - 0x6: decode RS_HI { - 0x0: decode RS_LO { + 0x6: decode FUNCTION_HI { + 0x0: decode FUNCTION_LO { format Float64Op { 0x0: addps({{ //Must Check for Exception Here... Supposed to Operate on Upper and //Lower Halves Independently but we take simulator shortcut @@ -667,7 +760,7 @@ decode OPCODE_HI default Unknown::unknown() { } } - 0x2: decode RS_LO { + 0x2: decode FUNCTION_LO { 0x1: decode MOVCF { format Float64Op { 0x0: movfps({{if (xc->readMiscReg(FPCR) != CC) Fd = Fs;}}); @@ -682,23 +775,25 @@ decode OPCODE_HI default Unknown::unknown() { } - 0x4: decode RS_LO { + 0x4: decode FUNCTION_LO { 0x0: Float64Op::cvt_s_pu({{ - int rnd_mode = xc->readMiscReg(FCSR); - Fd = convert_and_round(Fs.df,rnd_mode,FP_DOUBLE,FP_PS_HI); + int rnd_mode = xc->readMiscReg(FCSR) & 0x03; + Fd = convert_and_round(Fs.ud, PUPPER_TO_SINGLE, rnd_mode); }}); } - 0x5: decode RS_LO { + 0x5: decode FUNCTION_LO { format Float64Op { 0x0: cvt_s_pl({{ - int rnd_mode = xc->readMiscReg(FCSR); - Fd = convert_and_round(Fs.df,rnd_mode,FP_SINGLE,FP_PS_LO); + int rnd_mode = xc->readMiscReg(FCSR) & 0x03; + Fd = convert_and_round(Fs.ud, PLOWER_TO_SINGLE, + rnd_mode); }}); - 0x4: pll({{ /*Fd.df = Fs<31:0> | Ft<31:0>*/}}); - 0x5: plu({{ /*Fd.df = Fs<31:0> | Ft<63:32>*/}}); - 0x6: pul({{ /*Fd.df = Fs<63:32> | Ft<31:0>*/}}); - 0x7: puu({{ /*Fd.df = Fs<63:32 | Ft<63:32>*/}}); + + 0x4: pll({{ Fd.ud = Fs.ud<31:0> << 32 | Ft.ud<31:0>; }}); + 0x5: plu({{ Fd.ud = Fs.ud<31:0> << 32 | Ft.ud<63:32>;}}); + 0x6: pul({{ Fd.ud = Fs.ud<63:32> << 32 | Ft.ud<31:0>; }}); + 0x7: puu({{ Fd.ud = Fs.ud<63:32> << 32 | Ft.ud<63:32>;}}); } } } @@ -743,24 +838,24 @@ decode OPCODE_HI default Unknown::unknown() { //operations are enabled." 0x3: decode FUNCTION_HI { 0x0: decode FUNCTION_LO { - format LoadMemory2 { - 0x0: lwxc1({{ EA = Rs + Rt; }},{{ /*F_t<31:0> = Mem.sf; */}}); - 0x1: ldxc1({{ EA = Rs + Rt; }},{{ /*F_t<63:0> = Mem.df;*/ }}); - 0x5: luxc1({{ //Need to make EA<2:0> = 0 - EA = Rs + Rt; - }}, - {{ /*F_t<31:0> = Mem.df; */}}); + format LoadFloatMemory { + 0x0: lwxc1({{ /*F_t<31:0> = Mem.sf; */}}, {{ EA = Rs + Rt; }}); + 0x1: ldxc1({{ /*F_t<63:0> = Mem.df;*/ }}, {{ EA = Rs + Rt; }}); + 0x5: luxc1({{ /*F_t<31:0> = Mem.df; */}}, + {{ //Need to make EA<2:0> = 0 + EA = Rs + Rt; + }}); } } 0x1: decode FUNCTION_LO { - format StoreMemory2 { - 0x0: swxc1({{ EA = Rs + Rt; }},{{ /*Mem.sf = Ft<31:0>; */}}); - 0x1: sdxc1({{ EA = Rs + Rt; }},{{ /*Mem.df = Ft<63:0> */}}); - 0x5: suxc1({{ //Need to make EA<2:0> = 0 - EA = Rs + Rt; - }}, - {{ /*Mem.df = F_t<63:0>;*/}}); + format StoreFloatMemory { + 0x0: swxc1({{ /*Mem.sf = Ft<31:0>; */}},{{ EA = Rs + Rt; }}); + 0x1: sdxc1({{ /*Mem.df = Ft<63:0> */}}, {{ EA = Rs + Rt; }}); + 0x5: suxc1({{ /*Mem.df = F_t<63:0>;*/}}, + {{ //Need to make sure EA<2:0> = 0 + EA = Rs + Rt; + }}); } 0x7: WarnUnimpl::prefx(); @@ -1180,9 +1275,9 @@ decode OPCODE_HI default Unknown::unknown() { 0x6: decode OPCODE_LO default FailUnimpl::reserved() { 0x0: FailUnimpl::ll(); - format LoadMemory { - 0x1: lwc1({{ /*F_t<31:0> = Mem.sf; */}}); - 0x5: ldc1({{ /*F_t<63:0> = Mem.df; */}}); + format LoadFloatMemory { + 0x1: lwc1({{ Ft.uw = Mem.uw; }}); + 0x5: ldc1({{ Ft.ud = Mem.ud; }}); } } @@ -1190,9 +1285,9 @@ decode OPCODE_HI default Unknown::unknown() { 0x7: decode OPCODE_LO default FailUnimpl::reserved() { 0x0: FailUnimpl::sc(); - format StoreMemory { - 0x1: swc1({{ //Mem.sf = Ft<31:0>; }}); - 0x5: sdc1({{ //Mem.df = Ft<63:0>; }}); + format StoreFloatMemory { + 0x1: swc1({{ Mem.uw = Ft.uw; }}); + 0x5: sdc1({{ Mem.ud = Ft.ud; }}); } } } diff --git a/arch/mips/isa/formats/fp.isa b/arch/mips/isa/formats/fp.isa index 34b71acf7..65b259e20 100644 --- a/arch/mips/isa/formats/fp.isa +++ b/arch/mips/isa/formats/fp.isa @@ -30,7 +30,7 @@ output decoder {{ }}; -// Primary format for integer operate instructions: +// Primary format for float operate instructions: def format FloatOp(code, *flags) {{ iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) header_output = BasicDeclare.subst(iop) @@ -39,7 +39,7 @@ def format FloatOp(code, *flags) {{ exec_output = BasicExecute.subst(iop) }}; -// Primary format for integer operate instructions: +// Primary format for float64 operate instructions: def format Float64Op(code, *flags) {{ iop = InstObjParams(name, Name, 'MipsStaticInst', CodeBlock(code), flags) header_output = BasicDeclare.subst(iop) diff --git a/arch/mips/isa/formats/mem.isa b/arch/mips/isa/formats/mem.isa index df1dca4e1..e2afc7252 100644 --- a/arch/mips/isa/formats/mem.isa +++ b/arch/mips/isa/formats/mem.isa @@ -446,30 +446,28 @@ def format StoreMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, exec_template_base = 'Store') }}; -def format UnalignedStore(memacc_code, postacc_code, - ea_code = {{ EA = Rb + disp; }}, +//FP loads are offloaded to these formats for now ... +def format LoadFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, mem_flags = [], inst_flags = []) {{ (header_output, decoder_output, decode_block, exec_output) = \ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, - postacc_code, exec_template_base = 'Store') + decode_template = BasicDecode, + exec_template_base = 'Load') }}; -//FP loads are offloaded to these formats for now ... -def format LoadMemory2(ea_code = {{ EA = Rs + disp; }}, memacc_code = {{ }}, - mem_flags = [], inst_flags = []) {{ + +def format StoreFloatMemory(memacc_code, ea_code = {{ EA = Rs + disp; }}, + mem_flags = [], inst_flags = []) {{ (header_output, decoder_output, decode_block, exec_output) = \ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, - decode_template = LoadNopCheckDecode, - exec_template_base = 'Load') + exec_template_base = 'Store') }}; -//FP stores are offloaded to these formats for now ... -def format StoreMemory2(ea_code = {{ EA = Rs + disp; }},memacc_code = {{ }}, - mem_flags = [], inst_flags = []) {{ +def format UnalignedStore(memacc_code, postacc_code, + ea_code = {{ EA = Rb + disp; }}, + mem_flags = [], inst_flags = []) {{ (header_output, decoder_output, decode_block, exec_output) = \ LoadStoreBase(name, Name, ea_code, memacc_code, mem_flags, inst_flags, - decode_template = LoadNopCheckDecode, - exec_template_base = 'Store') + postacc_code, exec_template_base = 'Store') }}; - diff --git a/arch/mips/isa/formats/util.isa b/arch/mips/isa/formats/util.isa index dcdf46757..615160931 100644 --- a/arch/mips/isa/formats/util.isa +++ b/arch/mips/isa/formats/util.isa @@ -95,9 +95,6 @@ output exec {{ using namespace MipsISA; - - - /// CLEAR ALL CPU INST/EXE HAZARDS inline void clear_exe_inst_hazards() @@ -126,25 +123,7 @@ output exec {{ } #endif - double convert_and_round(float w, int x, int y, int z) - { - double temp = .34000; - - return temp; - } - enum FPTypes{ - FP_SINGLE, - FP_DOUBLE, - FP_LONG, - FP_PS_LO, - FP_PS_HI, - FP_WORD, - RND_NEAREST, - RND_ZERO, - RND_UP, - RND_DOWN - }; }}; diff --git a/arch/mips/isa_traits.cc b/arch/mips/isa_traits.cc index c6cfb2a0f..d23cdf367 100644 --- a/arch/mips/isa_traits.cc +++ b/arch/mips/isa_traits.cc @@ -33,7 +33,38 @@ using namespace MipsISA; +uint64_t +MipsISA::convert_and_round(uint64_t fp_val, ConvertType cvt_type, int rnd_mode) +{ + uint64_t ret_val = 0; + + switch (cvt_type) + { + case SINGLE_TO_DOUBLE: + break; + + case SINGLE_TO_WORD: + break; + + case SINGLE_TO_LONG: + break; + + case DOUBLE_TO_SINGLE: + break; + + case LONG_TO_SINGLE: + break; + + case WORD_TO_SINGLE: + break; + + default: + panic("Invalid Floating Point Conversion type being used.\n"); + } + + return ret_val; +} void MipsISA::copyRegs(ExecContext *src, ExecContext *dest) diff --git a/arch/mips/isa_traits.hh b/arch/mips/isa_traits.hh index 1f4ccbd90..3ea72bde2 100644 --- a/arch/mips/isa_traits.hh +++ b/arch/mips/isa_traits.hh @@ -30,8 +30,10 @@ #define __ARCH_MIPS_ISA_TRAITS_HH__ //#include "arch/mips/misc_regfile.hh" +#include "arch/mips/faults.hh" #include "base/misc.hh" #include "config/full_system.hh" +#include "sim/byteswap.hh" #include "sim/host.hh" #include "sim/faults.hh" @@ -105,7 +107,7 @@ namespace MipsISA const int NumPALShadowRegs = 8; const int NumFloatArchRegs = 32; // @todo: Figure out what this number really should be. - const int NumMiscArchRegs = 32; + const int NumMiscArchRegs = 265; const int NumIntRegs = NumIntArchRegs + NumPALShadowRegs; const int NumFloatRegs = NumFloatArchRegs; @@ -189,63 +191,166 @@ namespace MipsISA typedef double FloatReg; typedef uint64_t FloatRegBits; + + const int SingleWidth = 32; + const int SingleBytes = SingleWidth / 4; + + const int DoubleWidth = 64; + const int DoubleBytes = DoubleWidth / 4; + + const int QuadWidth = 128; + const int QuadBytes = QuadWidth / 4; + + const int FloatRegSize = SingleWidth / SingleBytes; + const int DoubleRegSize = FloatRegSize * 2; + class FloatRegFile { protected: - FloatRegBits q[NumFloatRegs]; // integer qword view - double d[NumFloatRegs]; // double-precision floating point view + //Since the floating point registers overlap each other, + //A generic storage space is used. The float to be returned is + //pulled from the appropriate section of this region. + char regSpace[FloatRegSize * NumFloatRegs]; public: - FloatReg readReg(int floatReg) + void clear() { - return d[floatReg]; + bzero(regSpace, sizeof(regSpace)); } FloatReg readReg(int floatReg, int width) { - return readReg(floatReg); - } + //In each of these cases, we have to copy the value into a temporary + //variable. This is because we may otherwise try to access an + //unaligned portion of memory. + switch(width) + { + case SingleWidth: + float result32; + memcpy(&result32, regSpace + 4 * floatReg, FloatRegSize); + return htog(result32); - FloatRegBits readRegBits(int floatReg) - { - return q[floatReg]; + case DoubleWidth: + double result64; + memcpy(&result64, regSpace + 4 * floatReg, DoubleRegSize); + return htog(result64); + + default: + panic("Attempted to read a %d bit floating point register!", width); + } } FloatRegBits readRegBits(int floatReg, int width) { - return readRegBits(floatReg); - } + //In each of these cases, we have to copy the value into a temporary + //variable. This is because we may otherwise try to access an + //unaligned portion of memory. + switch(width) + { + case SingleWidth: + uint32_t result32; + memcpy(&result32, regSpace + 4 * floatReg, FloatRegSize); + return htog(result32); - Fault setReg(int floatReg, const FloatReg &val) - { - d[floatReg] = val; - return NoFault; - } + case DoubleWidth: + uint64_t result64; + memcpy(&result64, regSpace + 4 * floatReg, DoubleRegSize); + return htog(result64); - Fault setReg(int floatReg, const FloatReg &val, int width) - { - return setReg(floatReg, val); + default: + panic("Attempted to read a %d bit floating point register!", width); + } } - Fault setRegBits(int floatReg, const FloatRegBits &val) + Fault setReg(int floatReg, const FloatReg &val, int width) { - q[floatReg] = val; + //In each of these cases, we have to copy the value into a temporary + //variable. This is because we may otherwise try to access an + //unaligned portion of memory. + switch(width) + { + case SingleWidth: + uint32_t result32; + result32 = gtoh((uint32_t)val); + memcpy(regSpace + 4 * floatReg, &result32, FloatRegSize); + break; + + case DoubleWidth: + uint64_t result64; + result64 = gtoh((uint64_t)val); + memcpy(regSpace + 4 * floatReg, &result64, DoubleRegSize); + break; + + + default: + panic("Attempted to read a %d bit floating point register!", width); + } return NoFault; } Fault setRegBits(int floatReg, const FloatRegBits &val, int width) { - return setRegBits(floatReg, val); + //In each of these cases, we have to copy the value into a temporary + //variable. This is because we may otherwise try to access an + //unaligned portion of memory. + switch(width) + { + case SingleWidth: + uint32_t result32; + result32 = gtoh((uint32_t)val); + memcpy(regSpace + 4 * floatReg, &result32, FloatRegSize); + break; + + case DoubleWidth: + uint64_t result64; + result64 = gtoh((uint64_t)val); + memcpy(regSpace + 4 * floatReg, &result64, DoubleRegSize); + break; + + default: + panic("Attempted to read a %d bit floating point register!", width); + } + return NoFault; } void serialize(std::ostream &os); void unserialize(Checkpoint *cp, const std::string §ion); - }; + enum ConvertType{ + SINGLE_TO_DOUBLE, + SINGLE_TO_WORD, + SINGLE_TO_LONG, + + DOUBLE_TO_SINGLE, + DOUBLE_TO_WORD, + DOUBLE_TO_LONG, + + LONG_TO_SINGLE, + LONG_TO_DOUBLE, + LONG_TO_WORD, + + WORD_TO_SINGLE, + WORD_TO_DOUBLE, + WORD_TO_LONG, + + PLOWER_TO_SINGLE, + PUPPER_TO_SINGLE + }; + + enum RoundMode{ + RND_ZERO, + RND_DOWN, + RND_UP, + RND_NEAREST + }; + + uint64_t convert_and_round(uint64_t fp_val,ConvertType cvt_type, int rnd_mode = 0); + + void copyRegs(ExecContext *src, ExecContext *dest); // cop-0/cop-1 system control register file @@ -532,44 +637,45 @@ extern const Addr PageOffset; return miscRegFile.setRegWithEffect(miscReg, val, xc); } + FloatReg readFloatReg(int floatReg) { - return floatRegFile.readReg(floatReg); + return floatRegFile.readReg(floatReg,SingleWidth); } FloatReg readFloatReg(int floatReg, int width) { - return readFloatReg(floatReg); + return floatRegFile.readReg(floatReg,width); } FloatRegBits readFloatRegBits(int floatReg) { - return floatRegFile.readRegBits(floatReg); + return floatRegFile.readRegBits(floatReg,SingleWidth); } FloatRegBits readFloatRegBits(int floatReg, int width) { - return readFloatRegBits(floatReg); + return floatRegFile.readRegBits(floatReg,width); } Fault setFloatReg(int floatReg, const FloatReg &val) { - return floatRegFile.setReg(floatReg, val); + return floatRegFile.setReg(floatReg, val, SingleWidth); } Fault setFloatReg(int floatReg, const FloatReg &val, int width) { - return setFloatReg(floatReg, val); + return floatRegFile.setReg(floatReg, val, width); } Fault setFloatRegBits(int floatReg, const FloatRegBits &val) { - return floatRegFile.setRegBits(floatReg, val); + return floatRegFile.setRegBits(floatReg, val, SingleWidth); } Fault setFloatRegBits(int floatReg, const FloatRegBits &val, int width) { - return setFloatRegBits(floatReg, val); + return floatRegFile.setRegBits(floatReg, val, width); } IntReg readIntReg(int intReg) diff --git a/base/chunk_generator.hh b/base/chunk_generator.hh index 1dca50db4..4f708bd4b 100644 --- a/base/chunk_generator.hh +++ b/base/chunk_generator.hh @@ -62,6 +62,8 @@ class ChunkGenerator int curSize; /** The number of bytes remaining in the region after the current chunk. */ int sizeLeft; + /** The start address so we can calculate offset in writing block. */ + const Addr startAddr; /** The maximum chunk size, e.g., the cache block size or page size. */ const int chunkSize; @@ -73,8 +75,8 @@ class ChunkGenerator * @param _chunkSize The size/alignment of chunks into which * the region should be decomposed. */ - ChunkGenerator(Addr startAddr, int totalSize, int _chunkSize) - : chunkSize(_chunkSize) + ChunkGenerator(Addr _startAddr, int totalSize, int _chunkSize) + : startAddr(_startAddr), chunkSize(_chunkSize) { // chunkSize must be a power of two assert(chunkSize == 0 || isPowerOf2(chunkSize)); @@ -107,6 +109,8 @@ class ChunkGenerator /** Return size in bytes of current chunk. */ int size() { return curSize; } + /** Number of bytes we have already chunked up. */ + int complete() { return curAddr - startAddr; } /** * Are we done? That is, did the last call to next() advance * past the end of the region? diff --git a/base/inet.hh b/base/inet.hh index e07e01935..e5d0473f9 100644 --- a/base/inet.hh +++ b/base/inet.hh @@ -117,11 +117,11 @@ class EthPtr { protected: friend class IpPtr; - PacketPtr p; + EthPacketPtr p; public: EthPtr() {} - EthPtr(const PacketPtr &ptr) : p(ptr) { } + EthPtr(const EthPacketPtr &ptr) : p(ptr) { } EthHdr *operator->() { return (EthHdr *)p->data; } EthHdr &operator*() { return *(EthHdr *)p->data; } @@ -131,10 +131,10 @@ class EthPtr const EthHdr &operator*() const { return *(const EthHdr *)p->data; } operator const EthHdr *() const { return (const EthHdr *)p->data; } - const EthPtr &operator=(const PacketPtr &ptr) { p = ptr; return *this; } + const EthPtr &operator=(const EthPacketPtr &ptr) { p = ptr; return *this; } - const PacketPtr packet() const { return p; } - PacketPtr packet() { return p; } + const EthPacketPtr packet() const { return p; } + EthPacketPtr packet() { return p; } bool operator!() const { return !p; } operator bool() const { return p; } }; @@ -174,13 +174,13 @@ class IpPtr protected: friend class TcpPtr; friend class UdpPtr; - PacketPtr p; + EthPacketPtr p; const IpHdr *h() const { return (const IpHdr *)(p->data + sizeof(eth_hdr)); } IpHdr *h() { return (IpHdr *)(p->data + sizeof(eth_hdr)); } - void set(const PacketPtr &ptr) + void set(const EthPacketPtr &ptr) { EthHdr *eth = (EthHdr *)ptr->data; if (eth->type() == ETH_TYPE_IP) @@ -191,7 +191,7 @@ class IpPtr public: IpPtr() {} - IpPtr(const PacketPtr &ptr) { set(ptr); } + IpPtr(const EthPacketPtr &ptr) { set(ptr); } IpPtr(const EthPtr &ptr) { set(ptr.p); } IpPtr(const IpPtr &ptr) : p(ptr.p) { } @@ -203,12 +203,12 @@ class IpPtr const IpHdr &operator*() const { return *h(); } operator const IpHdr *() const { return h(); } - const IpPtr &operator=(const PacketPtr &ptr) { set(ptr); return *this; } + const IpPtr &operator=(const EthPacketPtr &ptr) { set(ptr); return *this; } const IpPtr &operator=(const EthPtr &ptr) { set(ptr.p); return *this; } const IpPtr &operator=(const IpPtr &ptr) { p = ptr.p; return *this; } - const PacketPtr packet() const { return p; } - PacketPtr packet() { return p; } + const EthPacketPtr packet() const { return p; } + EthPacketPtr packet() { return p; } bool operator!() const { return !p; } operator bool() const { return p; } operator bool() { return p; } @@ -272,13 +272,13 @@ struct TcpHdr : public tcp_hdr class TcpPtr { protected: - PacketPtr p; + EthPacketPtr p; int off; const TcpHdr *h() const { return (const TcpHdr *)(p->data + off); } TcpHdr *h() { return (TcpHdr *)(p->data + off); } - void set(const PacketPtr &ptr, int offset) { p = ptr; off = offset; } + void set(const EthPacketPtr &ptr, int offset) { p = ptr; off = offset; } void set(const IpPtr &ptr) { if (ptr->proto() == IP_PROTO_TCP) @@ -303,8 +303,8 @@ class TcpPtr const TcpPtr &operator=(const IpPtr &i) { set(i); return *this; } const TcpPtr &operator=(const TcpPtr &t) { set(t.p, t.off); return *this; } - const PacketPtr packet() const { return p; } - PacketPtr packet() { return p; } + const EthPacketPtr packet() const { return p; } + EthPacketPtr packet() { return p; } bool operator!() const { return !p; } operator bool() const { return p; } operator bool() { return p; } @@ -362,13 +362,13 @@ struct UdpHdr : public udp_hdr class UdpPtr { protected: - PacketPtr p; + EthPacketPtr p; int off; const UdpHdr *h() const { return (const UdpHdr *)(p->data + off); } UdpHdr *h() { return (UdpHdr *)(p->data + off); } - void set(const PacketPtr &ptr, int offset) { p = ptr; off = offset; } + void set(const EthPacketPtr &ptr, int offset) { p = ptr; off = offset; } void set(const IpPtr &ptr) { if (ptr->proto() == IP_PROTO_UDP) @@ -393,8 +393,8 @@ class UdpPtr const UdpPtr &operator=(const IpPtr &i) { set(i); return *this; } const UdpPtr &operator=(const UdpPtr &t) { set(t.p, t.off); return *this; } - const PacketPtr packet() const { return p; } - PacketPtr packet() { return p; } + const EthPacketPtr packet() const { return p; } + EthPacketPtr packet() { return p; } bool operator!() const { return !p; } operator bool() const { return p; } operator bool() { return p; } diff --git a/configs/test/SysPaths.py b/configs/test/SysPaths.py new file mode 100644 index 000000000..7f231916c --- /dev/null +++ b/configs/test/SysPaths.py @@ -0,0 +1,32 @@ +from m5 import * + +import os.path +import sys + +# Edit the following list to include the possible paths to the binary +# and disk image directories. The first directory on the list that +# exists will be selected. +SYSTEMDIR_PATH = ['/n/poolfs/z/dist/m5/system'] + +SYSTEMDIR = None +for d in SYSTEMDIR_PATH: + if os.path.exists(d): + SYSTEMDIR = d + break + +if not SYSTEMDIR: + print >>sys.stderr, "Can't find a path to system files." + sys.exit(1) + +BINDIR = SYSTEMDIR + '/binaries' +DISKDIR = SYSTEMDIR + '/disks' + +def disk(file): + return '%s/%s' % (DISKDIR, file) + +def binary(file): + return '%s/%s' % (BINDIR, file) + +def script(file): + return '%s/%s' % ('/z/saidi/work/m5.newmem/configs/boot', file) + diff --git a/configs/test/fs.py b/configs/test/fs.py index d2e5381f0..6cd4185ed 100644 --- a/configs/test/fs.py +++ b/configs/test/fs.py @@ -1,9 +1,88 @@ +from m5 import * import os from SysPaths import * # Base for tests is directory containing this file. test_base = os.path.dirname(__file__) +linux_image = env.get('LINUX_IMAGE', disk('linux-latest.img')) + +class IdeControllerPciData(PciConfigData): + VendorID = 0x8086 + DeviceID = 0x7111 + Command = 0x0 + Status = 0x280 + Revision = 0x0 + ClassCode = 0x01 + SubClassCode = 0x01 + ProgIF = 0x85 + BAR0 = 0x00000001 + BAR1 = 0x00000001 + BAR2 = 0x00000001 + BAR3 = 0x00000001 + BAR4 = 0x00000001 + BAR5 = 0x00000001 + InterruptLine = 0x1f + InterruptPin = 0x01 + BAR0Size = '8B' + BAR1Size = '4B' + BAR2Size = '8B' + BAR3Size = '4B' + BAR4Size = '16B' + +class SinicPciData(PciConfigData): + VendorID = 0x1291 + DeviceID = 0x1293 + Status = 0x0290 + SubClassCode = 0x00 + ClassCode = 0x02 + ProgIF = 0x00 + BAR0 = 0x00000000 + BAR1 = 0x00000000 + BAR2 = 0x00000000 + BAR3 = 0x00000000 + BAR4 = 0x00000000 + BAR5 = 0x00000000 + MaximumLatency = 0x34 + MinimumGrant = 0xb0 + InterruptLine = 0x1e + InterruptPin = 0x01 + BAR0Size = '64kB' + +class NSGigEPciData(PciConfigData): + VendorID = 0x100B + DeviceID = 0x0022 + Status = 0x0290 + SubClassCode = 0x00 + ClassCode = 0x02 + ProgIF = 0x00 + BAR0 = 0x00000001 + BAR1 = 0x00000000 + BAR2 = 0x00000000 + BAR3 = 0x00000000 + BAR4 = 0x00000000 + BAR5 = 0x00000000 + MaximumLatency = 0x34 + MinimumGrant = 0xb0 + InterruptLine = 0x1e + InterruptPin = 0x01 + BAR0Size = '256B' + BAR1Size = '4kB' + +class LinuxRootDisk(IdeDisk): + raw_image = RawDiskImage(image_file=linux_image, read_only=True) + image = CowDiskImage(child=Parent.raw_image, read_only=False) + +class LinuxSwapDisk(IdeDisk): + raw_image = RawDiskImage(image_file = disk('linux-bigswap2.img'), + read_only=True) + image = CowDiskImage(child = Parent.raw_image, read_only=False) + +class SpecwebFilesetDisk(IdeDisk): + raw_image = RawDiskImage(image_file = disk('specweb-fileset.img'), + read_only=True) + image = CowDiskImage(child = Parent.raw_image, read_only=False) + class BaseTsunami(Tsunami): cchip = TsunamiCChip(pio_addr=0x801a0000000) pchip = TsunamiPChip(pio_addr=0x80180000000) @@ -36,9 +115,12 @@ class BaseTsunami(Tsunami): fb = BadDevice(pio_addr=0x801fc0003d0, devicename='FrameBuffer') io = TsunamiIO(pio_addr=0x801fc000000) uart = Uart8250(pio_addr=0x801fc0003f8) -# ethernet = NSGigE(configdata=NSGigEPciData(), + ethernet = NSGigE(configdata=NSGigEPciData(), + pci_bus=0, pci_dev=1, pci_func=0) + etherint = NSGigEInt(device=Parent.ethernet) +# ethernet = Sinic(configdata=SinicPciData(), # pci_bus=0, pci_dev=1, pci_func=0) -# etherint = NSGigEInt(device=Parent.ethernet) +# etherint = SinicInt(device=Parent.ethernet) console = AlphaConsole(pio_addr=0x80200000000, disk=Parent.simple_disk) # bridge = PciFake(configdata=BridgePciData(), pci_bus=0, pci_dev=2, pci_func=0) @@ -48,25 +130,31 @@ class BaseTsunami(Tsunami): # configdata=IdeControllerPciData(), # pci_func=0, pci_dev=0, pci_bus=0) -#class LinuxTsunami(BaseTsunami): -# disk0 = LinuxRootDisk(delay='0us', driveID='master') -# ide = IdeController(disks=[Parent.disk0], -# configdata=IdeControllerPciData(), -# pci_func=0, pci_dev=0, pci_bus=0) +class LinuxTsunami(BaseTsunami): + disk0 = LinuxRootDisk(driveID='master') + disk1 = SpecwebFilesetDisk(driveID='slave') + disk2 = LinuxSwapDisk(driveID='master') + ide = IdeController(disks=[Parent.disk0, Parent.disk1, Parent.disk2], + configdata=IdeControllerPciData(), + pci_func=0, pci_dev=0, pci_bus=0) class LinuxAlphaSystem(LinuxAlphaSystem): magicbus = Bus() physmem = PhysicalMemory(range = AddrRange('128MB')) c1 = Connector(side_a=Parent.physmem, side_b=Parent.magicbus) - tsunami = BaseTsunami() + tsunami = LinuxTsunami() c2 = Connector(side_a=Parent.tsunami.cchip, side_a_name='pio', side_b=Parent.magicbus) c3 = Connector(side_a=Parent.tsunami.pchip, side_a_name='pio', side_b=Parent.magicbus) c4 = Connector(side_a=Parent.tsunami.pciconfig, side_a_name='pio', side_b=Parent.magicbus) c5 = Connector(side_a=Parent.tsunami.fake_sm_chip, side_a_name='pio', side_b=Parent.magicbus) + c6 = Connector(side_a=Parent.tsunami.ethernet, side_a_name='pio', side_b=Parent.magicbus) + c6a = Connector(side_a=Parent.tsunami.ethernet, side_a_name='dma', side_b=Parent.magicbus) c7 = Connector(side_a=Parent.tsunami.fake_uart1, side_a_name='pio', side_b=Parent.magicbus) c8 = Connector(side_a=Parent.tsunami.fake_uart2, side_a_name='pio', side_b=Parent.magicbus) c9 = Connector(side_a=Parent.tsunami.fake_uart3, side_a_name='pio', side_b=Parent.magicbus) c10 = Connector(side_a=Parent.tsunami.fake_uart4, side_a_name='pio', side_b=Parent.magicbus) + c11 = Connector(side_a=Parent.tsunami.ide, side_a_name='pio', side_b=Parent.magicbus) + c13 = Connector(side_a=Parent.tsunami.ide, side_a_name='dma', side_b=Parent.magicbus) c12 = Connector(side_a=Parent.tsunami.fake_ppc, side_a_name='pio', side_b=Parent.magicbus) c14 = Connector(side_a=Parent.tsunami.fake_OROM, side_a_name='pio', side_b=Parent.magicbus) c16 = Connector(side_a=Parent.tsunami.fake_pnp_addr, side_a_name='pio', side_b=Parent.magicbus) @@ -85,25 +173,39 @@ class LinuxAlphaSystem(LinuxAlphaSystem): c31 = Connector(side_a=Parent.tsunami.io, side_a_name='pio', side_b=Parent.magicbus) c32 = Connector(side_a=Parent.tsunami.uart, side_a_name='pio', side_b=Parent.magicbus) c33 = Connector(side_a=Parent.tsunami.console, side_a_name='pio', side_b=Parent.magicbus) - raw_image = RawDiskImage(image_file=disk('linux.img'), + raw_image = RawDiskImage(image_file=disk('linux-latest.img'), read_only=True) simple_disk = SimpleDisk(disk=Parent.raw_image) intrctrl = IntrControl() cpu = SimpleCPU(mem=Parent.magicbus) sim_console = SimConsole(listener=ConsoleListener(port=3456)) - kernel = binary('vmlinux') + kernel = '/z/saidi/work/m5.newmem/build/vmlinux' pal = binary('ts_osfpal') console = binary('console') boot_osflags = 'root=/dev/hda1 console=ttyS0' - readfile = os.path.join(test_base, 'halt.sh') +# readfile = os.path.join(test_base, 'halt.sh') BaseCPU.itb = AlphaITB() BaseCPU.dtb = AlphaDTB() BaseCPU.system = Parent.any -class TsunamiRoot(Root): +class TsunamiRoot(System): pass -root = TsunamiRoot(clock = '2GHz', system = LinuxAlphaSystem()) +def DualRoot(ClientSystem, ServerSystem): + self = Root() + self.client = ClientSystem() + self.server = ServerSystem() + + self.etherdump = EtherDump(file='ethertrace') + self.etherlink = EtherLink(int1 = Parent.client.tsunami.etherint[0], + int2 = Parent.server.tsunami.etherint[0], + dump = Parent.etherdump) + self.clock = '5GHz' + return self + +root = DualRoot(ClientSystem = LinuxAlphaSystem(readfile=script('netperf-stream-nt-client.rcS')), + ServerSystem = LinuxAlphaSystem(readfile=script('netperf-server.rcS'))) + diff --git a/cpu/cpu_exec_context.cc b/cpu/cpu_exec_context.cc index 62419adcf..ec1e94561 100644 --- a/cpu/cpu_exec_context.cc +++ b/cpu/cpu_exec_context.cc @@ -310,7 +310,7 @@ CPUExecContext::getVirtPort(ExecContext *xc) void CPUExecContext::delVirtPort(VirtualPort *vp) { - assert(!vp->nullExecContext()); +// assert(!vp->nullExecContext()); delete vp->getPeer(); delete vp; } diff --git a/cpu/simple/cpu.cc b/cpu/simple/cpu.cc index 1a737fa6a..be34d1791 100644 --- a/cpu/simple/cpu.cc +++ b/cpu/simple/cpu.cc @@ -172,21 +172,27 @@ SimpleCPU::SimpleCPU(Params *p) #if SIMPLE_CPU_MEM_ATOMIC || SIMPLE_CPU_MEM_IMMEDIATE ifetch_req = new Request(true); ifetch_req->setAsid(0); + // @todo fix me and get the real cpu iD!!! + ifetch_req->setCpuNum(0); ifetch_req->setSize(sizeof(MachInst)); ifetch_pkt = new Packet; ifetch_pkt->cmd = Read; - ifetch_pkt->data = (uint8_t *)&inst; + ifetch_pkt->dataStatic(&inst); ifetch_pkt->req = ifetch_req; ifetch_pkt->size = sizeof(MachInst); data_read_req = new Request(true); + // @todo fix me and get the real cpu iD!!! + data_read_req->setCpuNum(0); data_read_req->setAsid(0); data_read_pkt = new Packet; data_read_pkt->cmd = Read; - data_read_pkt->data = new uint8_t[8]; + data_read_pkt->dataStatic(&dataReg); data_read_pkt->req = data_read_req; data_write_req = new Request(true); + // @todo fix me and get the real cpu iD!!! + data_write_req->setCpuNum(0); data_write_req->setAsid(0); data_write_pkt = new Packet; data_write_pkt->cmd = Write; @@ -474,8 +480,7 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags) // Fault fault = xc->read(memReq,data); // Not sure what to check for no fault... if (data_read_pkt->result == Success) { - memcpy(&data, data_read_pkt->data, sizeof(T)); - data = gtoh(data); + data = gtoh(data_read_pkt->get<T>()); } if (traceData) { @@ -518,8 +523,7 @@ SimpleCPU::read(Addr addr, T &data, unsigned flags) // Need to find a way to not duplicate code above. if (data_read_pkt->result == Success) { - memcpy(&data, data_read_pkt->data, sizeof(T)); - data = gtoh(data); + data = gtoh(data_read_pkt->get<T>()); } if (traceData) { @@ -623,13 +627,13 @@ SimpleCPU::write(T data, Addr addr, unsigned flags, uint64_t *res) data_write_pkt = new Packet; data_write_pkt->cmd = Write; data_write_pkt->req = data_write_req; - data_write_pkt->data = new uint8_t[64]; T hostData = htog(data); - memcpy(data_write_pkt->data, &hostData, sizeof(T)); + data_write_pkt->allocate(); + data_write_pkt->set(hostData); #else data_write_pkt->reset(); data = htog(data); - data_write_pkt->data = (uint8_t *)&data; + data_write_pkt->dataStatic(&data); #endif data_write_pkt->addr = data_write_req->getPaddr(); data_write_pkt->size = sizeof(T); @@ -820,7 +824,7 @@ SimpleCPU::processResponse(Packet &response) scheduleTickEvent(1); // Copy the icache data into the instruction itself. - memcpy(&inst, pkt->data, sizeof(inst)); + inst = pkt->get<MachInst>(); delete pkt; break; diff --git a/cpu/simple/cpu.hh b/cpu/simple/cpu.hh index c3ff5cf3d..3640348a3 100644 --- a/cpu/simple/cpu.hh +++ b/cpu/simple/cpu.hh @@ -207,6 +207,9 @@ class SimpleCPU : public BaseCPU // current instruction MachInst inst; + // Static data storage + TheISA::IntReg dataReg; + #if SIMPLE_CPU_MEM_TIMING Packet *retry_pkt; #elif SIMPLE_CPU_MEM_ATOMIC || SIMPLE_CPU_MEM_IMMEDIATE diff --git a/dev/alpha_console.cc b/dev/alpha_console.cc index fde8af6ae..e05337bfa 100644 --- a/dev/alpha_console.cc +++ b/dev/alpha_console.cc @@ -102,31 +102,24 @@ AlphaConsole::read(Packet &pkt) pkt.time = curTick + pioDelay; Addr daddr = pkt.addr - pioAddr; - uint32_t *data32; - uint64_t *data64; + pkt.allocate(); switch (pkt.size) { case sizeof(uint32_t): - if (!pkt.data) { - data32 = new uint32_t; - pkt.data = (uint8_t*)data32; - } else - data32 = (uint32_t*)pkt.data; - switch (daddr) { case offsetof(AlphaAccess, last_offset): - *data32 = alphaAccess->last_offset; + pkt.set(alphaAccess->last_offset); break; case offsetof(AlphaAccess, version): - *data32 = alphaAccess->version; + pkt.set(alphaAccess->version); break; case offsetof(AlphaAccess, numCPUs): - *data32 = alphaAccess->numCPUs; + pkt.set(alphaAccess->numCPUs); break; case offsetof(AlphaAccess, intrClockFrequency): - *data32 = alphaAccess->intrClockFrequency; + pkt.set(alphaAccess->intrClockFrequency); break; default: /* Old console code read in everyting as a 32bit int @@ -134,62 +127,59 @@ AlphaConsole::read(Packet &pkt) */ pkt.result = BadAddress; } - DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, *data32); + DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, + pkt.get<uint32_t>()); break; case sizeof(uint64_t): - if (!pkt.data) { - data64 = new uint64_t; - pkt.data = (uint8_t*)data64; - } else - data64 = (uint64_t*)pkt.data; switch (daddr) { case offsetof(AlphaAccess, inputChar): - *data64 = console->console_in(); + pkt.set(console->console_in()); break; case offsetof(AlphaAccess, cpuClock): - *data64 = alphaAccess->cpuClock; + pkt.set(alphaAccess->cpuClock); break; case offsetof(AlphaAccess, mem_size): - *data64 = alphaAccess->mem_size; + pkt.set(alphaAccess->mem_size); break; case offsetof(AlphaAccess, kernStart): - *data64 = alphaAccess->kernStart; + pkt.set(alphaAccess->kernStart); break; case offsetof(AlphaAccess, kernEnd): - *data64 = alphaAccess->kernEnd; + pkt.set(alphaAccess->kernEnd); break; case offsetof(AlphaAccess, entryPoint): - *data64 = alphaAccess->entryPoint; + pkt.set(alphaAccess->entryPoint); break; case offsetof(AlphaAccess, diskUnit): - *data64 = alphaAccess->diskUnit; + pkt.set(alphaAccess->diskUnit); break; case offsetof(AlphaAccess, diskCount): - *data64 = alphaAccess->diskCount; + pkt.set(alphaAccess->diskCount); break; case offsetof(AlphaAccess, diskPAddr): - *data64 = alphaAccess->diskPAddr; + pkt.set(alphaAccess->diskPAddr); break; case offsetof(AlphaAccess, diskBlock): - *data64 = alphaAccess->diskBlock; + pkt.set(alphaAccess->diskBlock); break; case offsetof(AlphaAccess, diskOperation): - *data64 = alphaAccess->diskOperation; + pkt.set(alphaAccess->diskOperation); break; case offsetof(AlphaAccess, outputChar): - *data64 = alphaAccess->outputChar; + pkt.set(alphaAccess->outputChar); break; default: int cpunum = (daddr - offsetof(AlphaAccess, cpuStack)) / sizeof(alphaAccess->cpuStack[0]); if (cpunum >= 0 && cpunum < 64) - *data64 = alphaAccess->cpuStack[cpunum]; + pkt.set(alphaAccess->cpuStack[cpunum]); else panic("Unknown 64bit access, %#x\n", daddr); } - DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, *data64); + DPRINTF(AlphaConsole, "read: offset=%#x val=%#x\n", daddr, + pkt.get<uint64_t>()); break; default: pkt.result = BadAddress; @@ -207,7 +197,7 @@ AlphaConsole::write(Packet &pkt) assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); Addr daddr = pkt.addr - pioAddr; - uint64_t val = *(uint64_t *)pkt.data; + uint64_t val = pkt.get<uint64_t>(); assert(pkt.size == sizeof(uint64_t)); switch (daddr) { diff --git a/dev/etherbus.cc b/dev/etherbus.cc index c6b131e8e..906e324d3 100644 --- a/dev/etherbus.cc +++ b/dev/etherbus.cc @@ -81,7 +81,7 @@ EtherBus::reg(EtherInt *dev) { devlist.push_back(dev); } bool -EtherBus::send(EtherInt *sndr, PacketPtr &pkt) +EtherBus::send(EtherInt *sndr, EthPacketPtr &pkt) { if (busy()) { DPRINTF(Ethernet, "ethernet packet not sent, bus busy\n", curTick); diff --git a/dev/etherbus.hh b/dev/etherbus.hh index ca859d85f..4a364abd8 100644 --- a/dev/etherbus.hh +++ b/dev/etherbus.hh @@ -61,7 +61,7 @@ class EtherBus : public SimObject }; DoneEvent event; - PacketPtr packet; + EthPacketPtr packet; EtherInt *sender; EtherDump *dump; @@ -73,7 +73,7 @@ class EtherBus : public SimObject void txDone(); void reg(EtherInt *dev); bool busy() const { return (bool)packet; } - bool send(EtherInt *sender, PacketPtr &packet); + bool send(EtherInt *sender, EthPacketPtr &packet); }; #endif // __ETHERBUS_H__ diff --git a/dev/etherdump.cc b/dev/etherdump.cc index d8a51fc5b..cb5f0b70e 100644 --- a/dev/etherdump.cc +++ b/dev/etherdump.cc @@ -102,7 +102,7 @@ EtherDump::init() } void -EtherDump::dumpPacket(PacketPtr &packet) +EtherDump::dumpPacket(EthPacketPtr &packet) { pcap_pkthdr pkthdr; pkthdr.seconds = curtime + (curTick / Clock::Int::s); diff --git a/dev/etherdump.hh b/dev/etherdump.hh index 149192cd7..8bba073fe 100644 --- a/dev/etherdump.hh +++ b/dev/etherdump.hh @@ -45,7 +45,7 @@ class EtherDump : public SimObject private: std::ofstream stream; const int maxlen; - void dumpPacket(PacketPtr &packet); + void dumpPacket(EthPacketPtr &packet); void init(); Tick curtime; @@ -53,7 +53,7 @@ class EtherDump : public SimObject public: EtherDump(const std::string &name, const std::string &file, int max); - inline void dump(PacketPtr &pkt) { dumpPacket(pkt); } + inline void dump(EthPacketPtr &pkt) { dumpPacket(pkt); } }; #endif // __ETHERDUMP_H__ diff --git a/dev/etherint.hh b/dev/etherint.hh index e397846ae..1f641fadb 100644 --- a/dev/etherint.hh +++ b/dev/etherint.hh @@ -58,9 +58,9 @@ class EtherInt : public SimObject void recvDone() { peer->sendDone(); } virtual void sendDone() = 0; - bool sendPacket(PacketPtr packet) + bool sendPacket(EthPacketPtr packet) { return peer ? peer->recvPacket(packet) : true; } - virtual bool recvPacket(PacketPtr packet) = 0; + virtual bool recvPacket(EthPacketPtr packet) = 0; }; #endif // __DEV_ETHERINT_HH__ diff --git a/dev/etherlink.cc b/dev/etherlink.cc index f68332926..5b6531c2e 100644 --- a/dev/etherlink.cc +++ b/dev/etherlink.cc @@ -102,7 +102,7 @@ EtherLink::unserialize(Checkpoint *cp, const string §ion) } void -EtherLink::Link::txComplete(PacketPtr packet) +EtherLink::Link::txComplete(EthPacketPtr packet) { DPRINTF(Ethernet, "packet received: len=%d\n", packet->length); DDUMP(EthernetData, packet->data, packet->length); @@ -113,12 +113,12 @@ class LinkDelayEvent : public Event { protected: EtherLink::Link *link; - PacketPtr packet; + EthPacketPtr packet; public: // non-scheduling version for createForUnserialize() LinkDelayEvent(); - LinkDelayEvent(EtherLink::Link *link, PacketPtr pkt, Tick when); + LinkDelayEvent(EtherLink::Link *link, EthPacketPtr pkt, Tick when); void process(); @@ -148,7 +148,7 @@ EtherLink::Link::txDone() } bool -EtherLink::Link::transmit(PacketPtr pkt) +EtherLink::Link::transmit(EthPacketPtr pkt) { if (busy()) { DPRINTF(Ethernet, "packet not sent, link busy\n"); @@ -195,7 +195,7 @@ EtherLink::Link::unserialize(const string &base, Checkpoint *cp, bool packet_exists; paramIn(cp, section, base + ".packet_exists", packet_exists); if (packet_exists) { - packet = new PacketData(16384); + packet = new EthPacketData(16384); packet->unserialize(base + ".packet", cp, section); } @@ -215,7 +215,7 @@ LinkDelayEvent::LinkDelayEvent() setFlags(AutoDelete); } -LinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, PacketPtr p, Tick when) +LinkDelayEvent::LinkDelayEvent(EtherLink::Link *l, EthPacketPtr p, Tick when) : Event(&mainEventQueue), link(l), packet(p) { setFlags(AutoSerialize); @@ -256,7 +256,7 @@ LinkDelayEvent::unserialize(Checkpoint *cp, const string §ion) link = parent->link[number]; - packet = new PacketData(16384); + packet = new EthPacketData(16384); packet->unserialize("packet", cp, section); } diff --git a/dev/etherlink.hh b/dev/etherlink.hh index 305007d9e..570444e1b 100644 --- a/dev/etherlink.hh +++ b/dev/etherlink.hh @@ -73,14 +73,14 @@ class EtherLink : public SimObject /* * Transfer is complete */ - PacketPtr packet; + EthPacketPtr packet; void txDone(); typedef EventWrapper<Link, &Link::txDone> DoneEvent; friend void DoneEvent::process(); DoneEvent doneEvent; friend class LinkDelayEvent; - void txComplete(PacketPtr packet); + void txComplete(EthPacketPtr packet); public: Link(const std::string &name, EtherLink *p, int num, @@ -90,7 +90,7 @@ class EtherLink : public SimObject const std::string name() const { return objName; } bool busy() const { return (bool)packet; } - bool transmit(PacketPtr packet); + bool transmit(EthPacketPtr packet); void setTxInt(Interface *i) { assert(!txint); txint = i; } void setRxInt(Interface *i) { assert(!rxint); rxint = i; } @@ -110,7 +110,7 @@ class EtherLink : public SimObject public: Interface(const std::string &name, Link *txlink, Link *rxlink); - bool recvPacket(PacketPtr packet) { return txlink->transmit(packet); } + bool recvPacket(EthPacketPtr packet) { return txlink->transmit(packet); } void sendDone() { peer->sendDone(); } }; diff --git a/dev/etherpkt.cc b/dev/etherpkt.cc index 44dbd7c18..85e18e981 100644 --- a/dev/etherpkt.cc +++ b/dev/etherpkt.cc @@ -35,7 +35,7 @@ using namespace std; void -PacketData::serialize(const string &base, ostream &os) +EthPacketData::serialize(const string &base, ostream &os) { paramOut(os, base + ".length", length); paramOut(os, base + ".slack", slack); @@ -43,7 +43,7 @@ PacketData::serialize(const string &base, ostream &os) } void -PacketData::unserialize(const string &base, Checkpoint *cp, +EthPacketData::unserialize(const string &base, Checkpoint *cp, const string §ion) { paramIn(cp, section, base + ".length", length); diff --git a/dev/etherpkt.hh b/dev/etherpkt.hh index cb9022d72..01741b3d5 100644 --- a/dev/etherpkt.hh +++ b/dev/etherpkt.hh @@ -44,7 +44,7 @@ * Reference counted class containing ethernet packet data */ class Checkpoint; -class PacketData : public RefCounted +class EthPacketData : public RefCounted { public: /* @@ -66,12 +66,12 @@ class PacketData : public RefCounted int slack; public: - PacketData() : data(NULL), length(0), slack(0) { } - explicit PacketData(size_t size) + EthPacketData() : data(NULL), length(0), slack(0) { } + explicit EthPacketData(size_t size) : data(new uint8_t[size]), length(0), slack(0) { } - PacketData(std::auto_ptr<uint8_t> d, int l, int s = 0) + EthPacketData(std::auto_ptr<uint8_t> d, int l, int s = 0) : data(d.release()), length(l), slack(s) { } - ~PacketData() { if (data) delete [] data; } + ~EthPacketData() { if (data) delete [] data; } public: void serialize(const std::string &base, std::ostream &os); @@ -79,6 +79,6 @@ class PacketData : public RefCounted const std::string §ion); }; -typedef RefCountingPtr<PacketData> PacketPtr; +typedef RefCountingPtr<EthPacketData> EthPacketPtr; #endif // __ETHERPKT_HH__ diff --git a/dev/ethertap.cc b/dev/ethertap.cc index 7589991ef..b5abb1d62 100644 --- a/dev/ethertap.cc +++ b/dev/ethertap.cc @@ -169,7 +169,7 @@ EtherTap::detach() } bool -EtherTap::recvPacket(PacketPtr packet) +EtherTap::recvPacket(EthPacketPtr packet) { if (dump) dump->dump(packet); @@ -218,8 +218,8 @@ EtherTap::process(int revent) } while (data_len != 0 && buffer_offset >= data_len + sizeof(u_int32_t)) { - PacketPtr packet; - packet = new PacketData(data_len); + EthPacketPtr packet; + packet = new EthPacketData(data_len); packet->length = data_len; memcpy(packet->data, data, data_len); @@ -250,7 +250,7 @@ EtherTap::retransmit() if (packetBuffer.empty()) return; - PacketPtr packet = packetBuffer.front(); + EthPacketPtr packet = packetBuffer.front(); if (sendPacket(packet)) { if (dump) dump->dump(packet); diff --git a/dev/ethertap.hh b/dev/ethertap.hh index 069ba734f..40ce6af0b 100644 --- a/dev/ethertap.hh +++ b/dev/ethertap.hh @@ -70,10 +70,10 @@ class EtherTap : public EtherInt protected: std::string device; - std::queue<PacketPtr> packetBuffer; + std::queue<EthPacketPtr> packetBuffer; void process(int revent); - void enqueue(PacketData *packet); + void enqueue(EthPacketData *packet); void retransmit(); /* @@ -97,7 +97,7 @@ class EtherTap : public EtherInt EtherTap(const std::string &name, EtherDump *dump, int port, int bufsz); virtual ~EtherTap(); - virtual bool recvPacket(PacketPtr packet); + virtual bool recvPacket(EthPacketPtr packet); virtual void sendDone(); virtual void serialize(std::ostream &os); diff --git a/dev/ide_ctrl.cc b/dev/ide_ctrl.cc index fed604867..638be9c3d 100644 --- a/dev/ide_ctrl.cc +++ b/dev/ide_ctrl.cc @@ -31,7 +31,6 @@ #include <string> #include <vector> -#include "arch/alpha/ev5.hh" #include "base/trace.hh" #include "cpu/intr_control.hh" #include "dev/ide_ctrl.hh" @@ -39,17 +38,12 @@ #include "dev/pciconfigall.hh" #include "dev/pcireg.h" #include "dev/platform.hh" -#include "mem/bus/bus.hh" -#include "mem/bus/dma_interface.hh" -#include "mem/bus/pio_interface.hh" -#include "mem/bus/pio_interface_impl.hh" -#include "mem/functional/memory_control.hh" -#include "mem/functional/physical.hh" +#include "mem/packet.hh" #include "sim/builder.hh" #include "sim/sim_object.hh" +#include "sim/byteswap.hh" using namespace std; -using namespace TheISA; //// // Initialization and destruction @@ -92,22 +86,6 @@ IdeController::IdeController(Params *p) bm_enabled = false; memset(cmd_in_progress, 0, sizeof(cmd_in_progress)); - pioInterface = NULL; - dmaInterface = NULL; - // create the PIO and DMA interfaces - if (params()->pio_bus) { - pioInterface = newPioInterface(name() + ".pio", params()->hier, - params()->pio_bus, this, - &IdeController::cacheAccess); - pioLatency = params()->pio_latency * params()->pio_bus->clockRate; - } - - if (params()->dma_bus) { - dmaInterface = new DMAInterface<Bus>(name() + ".dma", - params()->dma_bus, - params()->dma_bus, 1, true); - } - // setup the disks attached to controller memset(disks, 0, sizeof(disks)); dev[0] = 0; @@ -118,7 +96,7 @@ IdeController::IdeController(Params *p) for (int i = 0; i < params()->disks.size(); i++) { disks[i] = params()->disks[i]; - disks[i]->setController(this, dmaInterface); + disks[i]->setController(this); } } @@ -240,91 +218,158 @@ IdeController::setDmaComplete(IdeDisk *disk) } } -//// -// Bus timing and bus access functions -//// - -Tick -IdeController::cacheAccess(MemReqPtr &req) -{ - // @todo Add more accurate timing to cache access - return curTick + pioLatency; -} //// // Read and write handling //// void -IdeController::readConfig(int offset, int size, uint8_t *data) +IdeController::readConfig(int offset, uint8_t *data) { - int config_offset; - if (offset < PCI_DEVICE_SPECIFIC) { - PciDev::readConfig(offset, size, data); + PciDev::readConfig(offset, data); } else if (offset >= IDE_CTRL_CONF_START && - (offset + size) <= IDE_CTRL_CONF_END) { - - config_offset = offset - IDE_CTRL_CONF_START; + (offset + 1) <= IDE_CTRL_CONF_END) { - switch (size) { - case sizeof(uint8_t): - *data = config_regs.data[config_offset]; + switch (offset) { + case IDE_CTRL_CONF_DEV_TIMING: + *data = config_regs.sidetim; break; - case sizeof(uint16_t): - *(uint16_t*)data = *(uint16_t*)&config_regs.data[config_offset]; + case IDE_CTRL_CONF_UDMA_CNTRL: + *data = config_regs.udmactl; break; - case sizeof(uint32_t): - *(uint32_t*)data = *(uint32_t*)&config_regs.data[config_offset]; + case IDE_CTRL_CONF_PRIM_TIMING+1: + *data = htole(config_regs.idetim0) >> 8; + break; + case IDE_CTRL_CONF_SEC_TIMING+1: + *data = htole(config_regs.idetim1) >> 8; + break; + case IDE_CTRL_CONF_IDE_CONFIG: + *data = htole(config_regs.ideconfig) & 0xFF; + break; + case IDE_CTRL_CONF_IDE_CONFIG+1: + *data = htole(config_regs.ideconfig) >> 8; break; default: - panic("Invalid PCI configuration read size!\n"); + panic("Invalid PCI configuration read for size 1 at offset: %#x!\n", + offset); } - DPRINTF(IdeCtrl, "PCI read offset: %#x size: %#x data: %#x\n", - offset, size, *(uint32_t*)data); - } else { panic("Read of unimplemented PCI config. register: %x\n", offset); } + DPRINTF(IdeCtrl, "PCI read offset: %#x size: 1 data: %#x\n", + offset, (uint32_t)*data); } void -IdeController::writeConfig(int offset, int size, const uint8_t *data) +IdeController::readConfig(int offset, uint16_t *data) { - int config_offset; + if (offset < PCI_DEVICE_SPECIFIC) { + PciDev::readConfig(offset, data); + } else if (offset >= IDE_CTRL_CONF_START && + (offset + 2) <= IDE_CTRL_CONF_END) { + switch (offset) { + case IDE_CTRL_CONF_PRIM_TIMING: + *data = config_regs.idetim0; + break; + case IDE_CTRL_CONF_SEC_TIMING: + *data = config_regs.idetim1; + break; + case IDE_CTRL_CONF_UDMA_TIMING: + *data = config_regs.udmatim; + break; + case IDE_CTRL_CONF_IDE_CONFIG: + *data = config_regs.ideconfig; + break; + default: + panic("Invalid PCI configuration read for size 2 offset: %#x!\n", + offset); + } + + } else { + panic("Read of unimplemented PCI config. register: %x\n", offset); + } + DPRINTF(IdeCtrl, "PCI read offset: %#x size: 2 data: %#x\n", offset, *data); +} + +void +IdeController::readConfig(int offset, uint32_t *data) +{ + if (offset < PCI_DEVICE_SPECIFIC) { + PciDev::readConfig(offset, data); + } else { + panic("Read of unimplemented PCI config. register: %x\n", offset); + } + DPRINTF(IdeCtrl, "PCI read offset: %#x size: 4 data: %#x\n", offset, *data); +} +void +IdeController::writeConfig(int offset, const uint8_t data) +{ if (offset < PCI_DEVICE_SPECIFIC) { - PciDev::writeConfig(offset, size, data); + PciDev::writeConfig(offset, data); } else if (offset >= IDE_CTRL_CONF_START && - (offset + size) <= IDE_CTRL_CONF_END) { + (offset + 1) <= IDE_CTRL_CONF_END) { + + switch (offset) { + case IDE_CTRL_CONF_DEV_TIMING: + config_regs.sidetim = data; + break; + case IDE_CTRL_CONF_UDMA_CNTRL: + config_regs.udmactl = data; + break; + case IDE_CTRL_CONF_IDE_CONFIG: + config_regs.ideconfig = (config_regs.ideconfig & 0xFF00) | (data); + break; + case IDE_CTRL_CONF_IDE_CONFIG+1: + config_regs.ideconfig = (config_regs.ideconfig & 0x00FF) | data << 8; + break; + default: + panic("Invalid PCI configuration write for size 1 offset: %#x!\n", + offset); + } - config_offset = offset - IDE_CTRL_CONF_START; + } else { + panic("Read of unimplemented PCI config. register: %x\n", offset); + } + DPRINTF(IdeCtrl, "PCI write offset: %#x size: 1 data: %#x\n", + offset, (uint32_t)data); +} - switch(size) { - case sizeof(uint8_t): - config_regs.data[config_offset] = *data; +void +IdeController::writeConfig(int offset, const uint16_t data) +{ + if (offset < PCI_DEVICE_SPECIFIC) { + PciDev::writeConfig(offset, data); + } else if (offset >= IDE_CTRL_CONF_START && + (offset + 2) <= IDE_CTRL_CONF_END) { + + switch (offset) { + case IDE_CTRL_CONF_PRIM_TIMING: + config_regs.idetim0 = data; break; - case sizeof(uint16_t): - *(uint16_t*)&config_regs.data[config_offset] = *(uint16_t*)data; + case IDE_CTRL_CONF_SEC_TIMING: + config_regs.idetim1 = data; break; - case sizeof(uint32_t): - *(uint32_t*)&config_regs.data[config_offset] = *(uint32_t*)data; + case IDE_CTRL_CONF_UDMA_TIMING: + config_regs.udmatim = data; + break; + case IDE_CTRL_CONF_IDE_CONFIG: + config_regs.ideconfig = data; break; default: - panic("Invalid PCI configuration write size!\n"); + panic("Invalid PCI configuration write for size 2 offset: %#x!\n", + offset); } + } else { panic("Write of unimplemented PCI config. register: %x\n", offset); } + DPRINTF(IdeCtrl, "PCI write offset: %#x size: 2 data: %#x\n", offset, data); - DPRINTF(IdeCtrl, "PCI write offset: %#x size: %#x data: %#x\n", - offset, size, data); - - // Catch the writes to specific PCI registers that have side affects - // (like updating the PIO ranges) - switch (offset) { - case PCI_COMMAND: + /* Trap command register writes and enable IO/BM as appropriate. */ + if (offset == PCI_COMMAND) { if (letoh(config.command) & PCI_CMD_IOSE) io_enabled = true; else @@ -334,91 +379,83 @@ IdeController::writeConfig(int offset, int size, const uint8_t *data) bm_enabled = true; else bm_enabled = false; - break; + } + +} + +void +IdeController::writeConfig(int offset, const uint32_t data) +{ + if (offset < PCI_DEVICE_SPECIFIC) { + PciDev::writeConfig(offset, data); + } else { + panic("Read of unimplemented PCI config. register: %x\n", offset); + } + + DPRINTF(IdeCtrl, "PCI write offset: %#x size: 4 data: %#x\n", offset, data); + switch(offset) { case PCI0_BASE_ADDR0: - if (BARAddrs[0] != 0) { + if (BARAddrs[0] != 0) pri_cmd_addr = BARAddrs[0]; - if (pioInterface) - pioInterface->addAddrRange(RangeSize(pri_cmd_addr, - pri_cmd_size)); - - pri_cmd_addr &= EV5::PAddrUncachedMask; - } break; case PCI0_BASE_ADDR1: - if (BARAddrs[1] != 0) { + if (BARAddrs[1] != 0) pri_ctrl_addr = BARAddrs[1]; - if (pioInterface) - pioInterface->addAddrRange(RangeSize(pri_ctrl_addr, - pri_ctrl_size)); - - pri_ctrl_addr &= EV5::PAddrUncachedMask; - } break; case PCI0_BASE_ADDR2: - if (BARAddrs[2] != 0) { + if (BARAddrs[2] != 0) sec_cmd_addr = BARAddrs[2]; - if (pioInterface) - pioInterface->addAddrRange(RangeSize(sec_cmd_addr, - sec_cmd_size)); - - sec_cmd_addr &= EV5::PAddrUncachedMask; - } break; case PCI0_BASE_ADDR3: - if (BARAddrs[3] != 0) { + if (BARAddrs[3] != 0) sec_ctrl_addr = BARAddrs[3]; - if (pioInterface) - pioInterface->addAddrRange(RangeSize(sec_ctrl_addr, - sec_ctrl_size)); - - sec_ctrl_addr &= EV5::PAddrUncachedMask; - } break; case PCI0_BASE_ADDR4: - if (BARAddrs[4] != 0) { + if (BARAddrs[4] != 0) bmi_addr = BARAddrs[4]; - if (pioInterface) - pioInterface->addAddrRange(RangeSize(bmi_addr, bmi_size)); - - bmi_addr &= EV5::PAddrUncachedMask; - } break; } } -Fault -IdeController::read(MemReqPtr &req, uint8_t *data) +Tick +IdeController::read(Packet &pkt) { Addr offset; IdeChannel channel; IdeRegType reg_type; int disk; - parseAddr(req->paddr, offset, channel, reg_type); + pkt.time = curTick + pioDelay; + pkt.allocate(); + if (pkt.size != 1 && pkt.size != 2 && pkt.size !=4) + panic("Bad IDE read size: %d\n", pkt.size); + + parseAddr(pkt.addr, offset, channel, reg_type); - if (!io_enabled) - return NoFault; + if (!io_enabled) { + pkt.result = Success; + return pioDelay; + } switch (reg_type) { case BMI_BLOCK: - switch (req->size) { + switch (pkt.size) { case sizeof(uint8_t): - *data = bmi_regs.data[offset]; + pkt.set(bmi_regs.data[offset]); break; case sizeof(uint16_t): - *(uint16_t*)data = *(uint16_t*)&bmi_regs.data[offset]; + pkt.set(*(uint16_t*)&bmi_regs.data[offset]); break; case sizeof(uint32_t): - *(uint32_t*)data = *(uint32_t*)&bmi_regs.data[offset]; + pkt.set(*(uint32_t*)&bmi_regs.data[offset]); break; default: - panic("IDE read of BMI reg invalid size: %#x\n", req->size); + panic("IDE read of BMI reg invalid size: %#x\n", pkt.size); } break; @@ -426,44 +463,54 @@ IdeController::read(MemReqPtr &req, uint8_t *data) case CONTROL_BLOCK: disk = getDisk(channel); - if (disks[disk] == NULL) + if (disks[disk] == NULL) { + pkt.set<uint8_t>(0); break; + } switch (offset) { case DATA_OFFSET: - switch (req->size) { + switch (pkt.size) { case sizeof(uint16_t): - disks[disk]->read(offset, reg_type, data); + disks[disk]->read(offset, reg_type, pkt.getPtr<uint8_t>()); break; case sizeof(uint32_t): - disks[disk]->read(offset, reg_type, data); - disks[disk]->read(offset, reg_type, &data[2]); + disks[disk]->read(offset, reg_type, pkt.getPtr<uint8_t>()); + disks[disk]->read(offset, reg_type, + pkt.getPtr<uint8_t>() + sizeof(uint16_t)); break; default: - panic("IDE read of data reg invalid size: %#x\n", req->size); + panic("IDE read of data reg invalid size: %#x\n", pkt.size); } break; default: - if (req->size == sizeof(uint8_t)) { - disks[disk]->read(offset, reg_type, data); + if (pkt.size == sizeof(uint8_t)) { + disks[disk]->read(offset, reg_type, pkt.getPtr<uint8_t>()); } else - panic("IDE read of command reg of invalid size: %#x\n", req->size); + panic("IDE read of command reg of invalid size: %#x\n", pkt.size); } break; default: panic("IDE controller read of unknown register block type!\n"); } - + if (pkt.size == 1) DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n", - offset, req->size, *(uint32_t*)data); + offset, pkt.size, (uint32_t)pkt.get<uint8_t>()); + else if (pkt.size == 2) + DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n", + offset, pkt.size, pkt.get<uint16_t>()); + else + DPRINTF(IdeCtrl, "read from offset: %#x size: %#x data: %#x\n", + offset, pkt.size, pkt.get<uint32_t>()); - return NoFault; + pkt.result = Success; + return pioDelay; } -Fault -IdeController::write(MemReqPtr &req, const uint8_t *data) +Tick +IdeController::write(Packet &pkt) { Addr offset; IdeChannel channel; @@ -471,28 +518,35 @@ IdeController::write(MemReqPtr &req, const uint8_t *data) int disk; uint8_t oldVal, newVal; - parseAddr(req->paddr, offset, channel, reg_type); + pkt.time = curTick + pioDelay; - if (!io_enabled) - return NoFault; + parseAddr(pkt.addr, offset, channel, reg_type); + + if (!io_enabled) { + pkt.result = Success; + DPRINTF(IdeCtrl, "io not enabled\n"); + return pioDelay; + } switch (reg_type) { case BMI_BLOCK: - if (!bm_enabled) - return NoFault; + if (!bm_enabled) { + pkt.result = Success; + return pioDelay; + } switch (offset) { // Bus master IDE command register case BMIC1: case BMIC0: - if (req->size != sizeof(uint8_t)) - panic("Invalid BMIC write size: %x\n", req->size); + if (pkt.size != sizeof(uint8_t)) + panic("Invalid BMIC write size: %x\n", pkt.size); // select the current disk based on DEV bit disk = getDisk(channel); oldVal = bmi_regs.chan[channel].bmic; - newVal = *data; + newVal = pkt.get<uint8_t>(); // if a DMA transfer is in progress, R/W control cannot change if (oldVal & SSBM) { @@ -541,11 +595,11 @@ IdeController::write(MemReqPtr &req, const uint8_t *data) // Bus master IDE status register case BMIS0: case BMIS1: - if (req->size != sizeof(uint8_t)) - panic("Invalid BMIS write size: %x\n", req->size); + if (pkt.size != sizeof(uint8_t)) + panic("Invalid BMIS write size: %x\n", pkt.size); oldVal = bmi_regs.chan[channel].bmis; - newVal = *data; + newVal = pkt.get<uint8_t>(); // the BMIDEA bit is RO newVal |= (oldVal & BMIDEA); @@ -568,30 +622,28 @@ IdeController::write(MemReqPtr &req, const uint8_t *data) case BMIDTP0: case BMIDTP1: { - if (req->size != sizeof(uint32_t)) - panic("Invalid BMIDTP write size: %x\n", req->size); + if (pkt.size != sizeof(uint32_t)) + panic("Invalid BMIDTP write size: %x\n", pkt.size); - uint32_t host_data = letoh(*(uint32_t*)data); - host_data &= ~0x3; - bmi_regs.chan[channel].bmidtp = htole(host_data); + bmi_regs.chan[channel].bmidtp = htole(pkt.get<uint32_t>() & ~0x3); } break; default: - if (req->size != sizeof(uint8_t) && - req->size != sizeof(uint16_t) && - req->size != sizeof(uint32_t)) + if (pkt.size != sizeof(uint8_t) && + pkt.size != sizeof(uint16_t) && + pkt.size != sizeof(uint32_t)) panic("IDE controller write of invalid write size: %x\n", - req->size); + pkt.size); // do a default copy of data into the registers - memcpy(&bmi_regs.data[offset], data, req->size); + memcpy(&bmi_regs.data[offset], pkt.getPtr<uint8_t>(), pkt.size); } break; case COMMAND_BLOCK: if (offset == IDE_SELECT_OFFSET) { uint8_t *devBit = &dev[channel]; - *devBit = (letoh(*data) & IDE_SELECT_DEV_BIT) ? 1 : 0; + *devBit = (letoh(pkt.get<uint8_t>()) & IDE_SELECT_DEV_BIT) ? 1 : 0; } // fall-through ok! case CONTROL_BLOCK: @@ -602,34 +654,44 @@ IdeController::write(MemReqPtr &req, const uint8_t *data) switch (offset) { case DATA_OFFSET: - switch (req->size) { + switch (pkt.size) { case sizeof(uint16_t): - disks[disk]->write(offset, reg_type, data); + disks[disk]->write(offset, reg_type, pkt.getPtr<uint8_t>()); break; case sizeof(uint32_t): - disks[disk]->write(offset, reg_type, data); - disks[disk]->write(offset, reg_type, &data[2]); + disks[disk]->write(offset, reg_type, pkt.getPtr<uint8_t>()); + disks[disk]->write(offset, reg_type, pkt.getPtr<uint8_t>() + + sizeof(uint16_t)); break; default: - panic("IDE write of data reg invalid size: %#x\n", req->size); + panic("IDE write of data reg invalid size: %#x\n", pkt.size); } break; default: - if (req->size == sizeof(uint8_t)) { - disks[disk]->write(offset, reg_type, data); + if (pkt.size == sizeof(uint8_t)) { + disks[disk]->write(offset, reg_type, pkt.getPtr<uint8_t>()); } else - panic("IDE write of command reg of invalid size: %#x\n", req->size); + panic("IDE write of command reg of invalid size: %#x\n", pkt.size); } break; default: panic("IDE controller write of unknown register block type!\n"); } + if (pkt.size == 1) + DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n", + offset, pkt.size, (uint32_t)pkt.get<uint8_t>()); + else if (pkt.size == 2) DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n", - offset, req->size, *(uint32_t*)data); + offset, pkt.size, pkt.get<uint16_t>()); + else + DPRINTF(IdeCtrl, "write to offset: %#x size: %#x data: %#x\n", + offset, pkt.size, pkt.get<uint32_t>()); + - return NoFault; + pkt.result = Success; + return pioDelay; } //// @@ -698,51 +760,36 @@ IdeController::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(bm_enabled); UNSERIALIZE_ARRAY(cmd_in_progress, sizeof(cmd_in_progress) / sizeof(cmd_in_progress[0])); - - if (pioInterface) { - pioInterface->addAddrRange(RangeSize(pri_cmd_addr, pri_cmd_size)); - pioInterface->addAddrRange(RangeSize(pri_ctrl_addr, pri_ctrl_size)); - pioInterface->addAddrRange(RangeSize(sec_cmd_addr, sec_cmd_size)); - pioInterface->addAddrRange(RangeSize(sec_ctrl_addr, sec_ctrl_size)); - pioInterface->addAddrRange(RangeSize(bmi_addr, bmi_size)); - } + pioPort->sendStatusChange(Port::RangeChange); } #ifndef DOXYGEN_SHOULD_SKIP_THIS BEGIN_DECLARE_SIM_OBJECT_PARAMS(IdeController) - Param<Addr> addr; - SimObjectVectorParam<IdeDisk *> disks; - SimObjectParam<MemoryController *> mmu; + SimObjectParam<System *> system; + SimObjectParam<Platform *> platform; SimObjectParam<PciConfigAll *> configspace; SimObjectParam<PciConfigData *> configdata; - SimObjectParam<Platform *> platform; Param<uint32_t> pci_bus; Param<uint32_t> pci_dev; Param<uint32_t> pci_func; - SimObjectParam<Bus *> pio_bus; - SimObjectParam<Bus *> dma_bus; Param<Tick> pio_latency; - SimObjectParam<HierParams *> hier; + SimObjectVectorParam<IdeDisk *> disks; END_DECLARE_SIM_OBJECT_PARAMS(IdeController) BEGIN_INIT_SIM_OBJECT_PARAMS(IdeController) - INIT_PARAM(addr, "Device Address"), - INIT_PARAM(disks, "IDE disks attached to this controller"), - INIT_PARAM(mmu, "Memory controller"), + INIT_PARAM(system, "System pointer"), + INIT_PARAM(platform, "Platform pointer"), INIT_PARAM(configspace, "PCI Configspace"), INIT_PARAM(configdata, "PCI Config data"), - INIT_PARAM(platform, "Platform pointer"), INIT_PARAM(pci_bus, "PCI bus ID"), INIT_PARAM(pci_dev, "PCI device number"), INIT_PARAM(pci_func, "PCI function code"), - INIT_PARAM(pio_bus, ""), - INIT_PARAM(dma_bus, ""), INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1), - INIT_PARAM_DFLT(hier, "Hierarchy global variables", &defaultHierParams) + INIT_PARAM(disks, "IDE disks attached to this controller") END_INIT_SIM_OBJECT_PARAMS(IdeController) @@ -750,19 +797,15 @@ CREATE_SIM_OBJECT(IdeController) { IdeController::Params *params = new IdeController::Params; params->name = getInstanceName(); - params->mmu = mmu; + params->platform = platform; + params->system = system; params->configSpace = configspace; params->configData = configdata; - params->plat = platform; params->busNum = pci_bus; params->deviceNum = pci_dev; params->functionNum = pci_func; - + params->pio_delay = pio_latency; params->disks = disks; - params->pio_bus = pio_bus; - params->dma_bus = dma_bus; - params->pio_latency = pio_latency; - params->hier = hier; return new IdeController(params); } diff --git a/dev/ide_ctrl.hh b/dev/ide_ctrl.hh index 0fbaf9207..a074f4f97 100644 --- a/dev/ide_ctrl.hh +++ b/dev/ide_ctrl.hh @@ -70,6 +70,13 @@ #define IDE_CTRL_CONF_START 0x40 #define IDE_CTRL_CONF_END ((IDE_CTRL_CONF_START) + sizeof(config_regs)) +#define IDE_CTRL_CONF_PRIM_TIMING 0x40 +#define IDE_CTRL_CONF_SEC_TIMING 0x42 +#define IDE_CTRL_CONF_DEV_TIMING 0x44 +#define IDE_CTRL_CONF_UDMA_CNTRL 0x48 +#define IDE_CTRL_CONF_UDMA_TIMING 0x4A +#define IDE_CTRL_CONF_IDE_CONFIG 0x54 + enum IdeRegType { COMMAND_BLOCK, @@ -77,13 +84,9 @@ enum IdeRegType { BMI_BLOCK }; -class BaseInterface; -class Bus; -class HierParams; class IdeDisk; class IntrControl; class PciConfigAll; -class PhysicalMemory; class Platform; /** @@ -191,10 +194,6 @@ class IdeController : public PciDev { /** Array of disk objects */ std::vector<IdeDisk *> disks; - Bus *pio_bus; - Bus *dma_bus; - Tick pio_latency; - HierParams *hier; }; const Params *params() const { return (const Params *)_params; } @@ -202,26 +201,28 @@ class IdeController : public PciDev IdeController(Params *p); ~IdeController(); - virtual void writeConfig(int offset, int size, const uint8_t *data); - virtual void readConfig(int offset, int size, uint8_t *data); + virtual void writeConfig(int offset, const uint8_t data); + virtual void writeConfig(int offset, const uint16_t data); + virtual void writeConfig(int offset, const uint32_t data); + virtual void readConfig(int offset, uint8_t *data); + virtual void readConfig(int offset, uint16_t *data); + virtual void readConfig(int offset, uint32_t *data); void setDmaComplete(IdeDisk *disk); /** * Read a done field for a given target. - * @param req Contains the address of the field to read. - * @param data Return the field read. - * @return The fault condition of the access. + * @param pkt Packet describing what is to be read + * @return The amount of time to complete this request */ - virtual Fault read(MemReqPtr &req, uint8_t *data); + virtual Tick read(Packet &pkt); /** - * Write to the mmapped I/O control registers. - * @param req Contains the address to write to. - * @param data The data to write. - * @return The fault condition of the access. + * Write a done field for a given target. + * @param pkt Packet describing what is to be written + * @return The amount of time to complete this request */ - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Tick write(Packet &pkt); /** * Serialize this object to the given output stream. @@ -236,11 +237,5 @@ class IdeController : public PciDev */ virtual void unserialize(Checkpoint *cp, const std::string §ion); - /** - * Return how long this access will take. - * @param req the memory request to calcuate - * @return Tick when the request is done - */ - Tick cacheAccess(MemReqPtr &req); }; #endif // __IDE_CTRL_HH_ diff --git a/dev/ide_disk.cc b/dev/ide_disk.cc index 41400c590..6f4234a1d 100644 --- a/dev/ide_disk.cc +++ b/dev/ide_disk.cc @@ -35,6 +35,7 @@ #include <deque> #include <string> +#include "base/chunk_generator.hh" #include "base/cprintf.hh" // csprintf #include "base/trace.hh" #include "dev/disk_image.hh" @@ -42,11 +43,6 @@ #include "dev/ide_ctrl.hh" #include "dev/tsunami.hh" #include "dev/tsunami_pchip.hh" -#include "mem/functional/physical.hh" -#include "mem/bus/bus.hh" -#include "mem/bus/dma_interface.hh" -#include "mem/bus/pio_interface.hh" -#include "mem/bus/pio_interface_impl.hh" #include "sim/builder.hh" #include "sim/sim_object.hh" #include "sim/root.hh" @@ -55,11 +51,11 @@ using namespace std; using namespace TheISA; -IdeDisk::IdeDisk(const string &name, DiskImage *img, PhysicalMemory *phys, +IdeDisk::IdeDisk(const string &name, DiskImage *img, int id, Tick delay) - : SimObject(name), ctrl(NULL), image(img), physmem(phys), diskDelay(delay), - dmaTransferEvent(this), dmaReadWaitEvent(this), - dmaWriteWaitEvent(this), dmaPrdReadEvent(this), + : SimObject(name), ctrl(NULL), image(img), diskDelay(delay), + dmaTransferEvent(this), dmaReadCG(NULL), dmaReadWaitEvent(this), + dmaWriteCG(NULL), dmaWriteWaitEvent(this), dmaPrdReadEvent(this), dmaReadEvent(this), dmaWriteEvent(this) { // Reset the device state @@ -139,7 +135,6 @@ IdeDisk::reset(int id) memset(&cmdReg, 0, sizeof(CommandReg_t)); memset(&curPrd.entry, 0, sizeof(PrdEntry_t)); - dmaInterfaceBytes = 0; curPrdAddr = 0; curSector = 0; cmdBytes = 0; @@ -188,29 +183,6 @@ IdeDisk::pciToDma(Addr pciAddr) panic("Access to unset controller!\n"); } -uint32_t -IdeDisk::bytesInDmaPage(Addr curAddr, uint32_t bytesLeft) -{ - uint32_t bytesInPage = 0; - - // First calculate how many bytes could be in the page - if (bytesLeft > TheISA::PageBytes) - bytesInPage = TheISA::PageBytes; - else - bytesInPage = bytesLeft; - - // Next, see if we have crossed a page boundary, and adjust - Addr upperBound = curAddr + bytesInPage; - Addr pageBound = TheISA::TruncPage(curAddr) + TheISA::PageBytes; - - assert(upperBound >= curAddr && "DMA read wraps around address space!\n"); - - if (upperBound >= pageBound) - bytesInPage = pageBound - curAddr; - - return bytesInPage; -} - //// // Device registers read/write //// @@ -263,6 +235,8 @@ IdeDisk::read(const Addr &offset, IdeRegType reg_type, uint8_t *data) default: panic("Unknown register block!\n"); } + DPRINTF(IdeDisk, "Read to disk at offset: %#x data %#x\n", offset, + (uint32_t)*data); if (action != ACT_NONE) updateState(action); @@ -324,6 +298,8 @@ IdeDisk::write(const Addr &offset, IdeRegType reg_type, const uint8_t *data) panic("Unknown register block!\n"); } + DPRINTF(IdeDisk, "Write to disk at offset: %#x data %#x\n", offset, + (uint32_t)*data); if (action != ACT_NONE) updateState(action); } @@ -339,29 +315,17 @@ IdeDisk::doDmaTransfer() panic("Inconsistent DMA transfer state: dmaState = %d devState = %d\n", dmaState, devState); - // first read the current PRD - if (dmaInterface) { - if (dmaInterface->busy()) { - // reschedule after waiting period - dmaTransferEvent.schedule(curTick + DMA_BACKOFF_PERIOD); - return; - } - - dmaInterface->doDMA(Read, curPrdAddr, sizeof(PrdEntry_t), curTick, - &dmaPrdReadEvent); - } else { - dmaPrdReadDone(); - } + if (ctrl->dmaPending()) { + dmaTransferEvent.schedule(curTick + DMA_BACKOFF_PERIOD); + return; + } else + ctrl->dmaRead(curPrdAddr, sizeof(PrdEntry_t), &dmaPrdReadEvent, + (uint8_t*)&curPrd.entry); } void IdeDisk::dmaPrdReadDone() { - // actually copy the PRD from physical memory - memcpy((void *)&curPrd.entry, - physmem->dma_addr(curPrdAddr, sizeof(PrdEntry_t)), - sizeof(PrdEntry_t)); - DPRINTF(IdeDisk, "PRD: baseAddr:%#x (%#x) byteCount:%d (%d) eot:%#x sector:%d\n", curPrd.getBaseAddr(), pciToDma(curPrd.getBaseAddr()), @@ -372,38 +336,49 @@ IdeDisk::dmaPrdReadDone() curPrdAddr = curPrdAddr + sizeof(PrdEntry_t); if (dmaRead) - doDmaRead(); + doDmaDataRead(); else - doDmaWrite(); + doDmaDataWrite(); } void -IdeDisk::doDmaRead() +IdeDisk::doDmaDataRead() { /** @todo we need to figure out what the delay actually will be */ Tick totalDiskDelay = diskDelay + (curPrd.getByteCount() / SectorSize); DPRINTF(IdeDisk, "doDmaRead, diskDelay: %d totalDiskDelay: %d\n", diskDelay, totalDiskDelay); - if (dmaInterface) { - if (dmaInterface->busy()) { - // reschedule after waiting period - dmaReadWaitEvent.schedule(curTick + DMA_BACKOFF_PERIOD); - return; - } - Addr dmaAddr = pciToDma(curPrd.getBaseAddr()); + dmaReadWaitEvent.schedule(curTick + totalDiskDelay); +} - uint32_t bytesInPage = bytesInDmaPage(curPrd.getBaseAddr(), - (uint32_t)curPrd.getByteCount()); - dmaInterfaceBytes = bytesInPage; +void +IdeDisk::doDmaRead() +{ + + if (!dmaReadCG) { + // clear out the data buffer + memset(dataBuffer, 0, MAX_DMA_SIZE); + dmaReadCG = new ChunkGenerator(curPrd.getBaseAddr(), + curPrd.getByteCount(), TheISA::PageBytes); - dmaInterface->doDMA(Read, dmaAddr, bytesInPage, - curTick + totalDiskDelay, &dmaReadEvent); + } + if (ctrl->dmaPending()) { + panic("shouldn't be reentant??"); + dmaReadWaitEvent.schedule(curTick + DMA_BACKOFF_PERIOD); + return; + } else if (!dmaReadCG->done()) { + assert(dmaReadCG->complete() < MAX_DMA_SIZE); + ctrl->dmaRead(pciToDma(dmaReadCG->addr()), dmaReadCG->size(), + &dmaReadWaitEvent, dataBuffer + dmaReadCG->complete()); + dmaReadCG->next(); } else { - // schedule dmaReadEvent with sectorDelay (dmaReadDone) - dmaReadEvent.schedule(curTick + totalDiskDelay); + assert(dmaReadCG->done()); + delete dmaReadCG; + dmaReadCG = NULL; + dmaReadDone(); } } @@ -411,63 +386,14 @@ void IdeDisk::dmaReadDone() { - Addr curAddr = 0, dmaAddr = 0; - uint32_t bytesWritten = 0, bytesInPage = 0, bytesLeft = 0; - - // continue to use the DMA interface until all pages are read - if (dmaInterface && (dmaInterfaceBytes < curPrd.getByteCount())) { - // see if the interface is busy - if (dmaInterface->busy()) { - // reschedule after waiting period - dmaReadEvent.schedule(curTick + DMA_BACKOFF_PERIOD); - return; - } - - uint32_t bytesLeft = curPrd.getByteCount() - dmaInterfaceBytes; - curAddr = curPrd.getBaseAddr() + dmaInterfaceBytes; - dmaAddr = pciToDma(curAddr); - - bytesInPage = bytesInDmaPage(curAddr, bytesLeft); - dmaInterfaceBytes += bytesInPage; - - dmaInterface->doDMA(Read, dmaAddr, bytesInPage, - curTick, &dmaReadEvent); - - return; - } - - // set initial address - curAddr = curPrd.getBaseAddr(); - - // clear out the data buffer - memset(dataBuffer, 0, MAX_DMA_SIZE); + uint32_t bytesWritten = 0; - // read the data from memory via DMA into a data buffer - while (bytesWritten < curPrd.getByteCount()) { - if (cmdBytesLeft <= 0) - panic("DMA data is larger than # of sectors specified\n"); - - dmaAddr = pciToDma(curAddr); - - // calculate how many bytes are in the current page - bytesLeft = curPrd.getByteCount() - bytesWritten; - bytesInPage = bytesInDmaPage(curAddr, bytesLeft); - - // copy the data from memory into the data buffer - memcpy((void *)(dataBuffer + bytesWritten), - physmem->dma_addr(dmaAddr, bytesInPage), - bytesInPage); - - curAddr += bytesInPage; - bytesWritten += bytesInPage; - cmdBytesLeft -= bytesInPage; - } // write the data to the disk image - for (bytesWritten = 0; - bytesWritten < curPrd.getByteCount(); + for (bytesWritten = 0; bytesWritten < curPrd.getByteCount(); bytesWritten += SectorSize) { + cmdBytesLeft -= SectorSize; writeDisk(curSector++, (uint8_t *)(dataBuffer + bytesWritten)); } @@ -482,107 +408,55 @@ IdeDisk::dmaReadDone() } void -IdeDisk::doDmaWrite() +IdeDisk::doDmaDataWrite() { /** @todo we need to figure out what the delay actually will be */ Tick totalDiskDelay = diskDelay + (curPrd.getByteCount() / SectorSize); + uint32_t bytesRead = 0; DPRINTF(IdeDisk, "doDmaWrite, diskDelay: %d totalDiskDelay: %d\n", diskDelay, totalDiskDelay); - if (dmaInterface) { - if (dmaInterface->busy()) { - // reschedule after waiting period - dmaWriteWaitEvent.schedule(curTick + DMA_BACKOFF_PERIOD); - return; - } - - Addr dmaAddr = pciToDma(curPrd.getBaseAddr()); + memset(dataBuffer, 0, MAX_DMA_SIZE); + assert(cmdBytesLeft <= MAX_DMA_SIZE); + while (bytesRead < curPrd.getByteCount()) { + readDisk(curSector++, (uint8_t *)(dataBuffer + bytesRead)); + bytesRead += SectorSize; + cmdBytesLeft -= SectorSize; + } - uint32_t bytesInPage = bytesInDmaPage(curPrd.getBaseAddr(), - (uint32_t)curPrd.getByteCount()); + dmaWriteWaitEvent.schedule(curTick + totalDiskDelay); +} - dmaInterfaceBytes = bytesInPage; +void +IdeDisk::doDmaWrite() +{ - dmaInterface->doDMA(WriteInvalidate, dmaAddr, - bytesInPage, curTick + totalDiskDelay, - &dmaWriteEvent); + if (!dmaWriteCG) { + // clear out the data buffer + dmaWriteCG = new ChunkGenerator(curPrd.getBaseAddr(), + curPrd.getByteCount(), TheISA::PageBytes); + } + if (ctrl->dmaPending()) { + panic("shouldn't be reentant??"); + dmaWriteWaitEvent.schedule(curTick + DMA_BACKOFF_PERIOD); + return; + } else if (!dmaWriteCG->done()) { + assert(dmaWriteCG->complete() < MAX_DMA_SIZE); + ctrl->dmaWrite(pciToDma(dmaWriteCG->addr()), dmaWriteCG->size(), + &dmaWriteWaitEvent, dataBuffer + dmaWriteCG->complete()); + dmaWriteCG->next(); } else { - // schedule event with disk delay (dmaWriteDone) - dmaWriteEvent.schedule(curTick + totalDiskDelay); + assert(dmaWriteCG->done()); + delete dmaWriteCG; + dmaWriteCG = NULL; + dmaWriteDone(); } } void IdeDisk::dmaWriteDone() { - Addr curAddr = 0, pageAddr = 0, dmaAddr = 0; - uint32_t bytesRead = 0, bytesInPage = 0; - - // continue to use the DMA interface until all pages are read - if (dmaInterface && (dmaInterfaceBytes < curPrd.getByteCount())) { - // see if the interface is busy - if (dmaInterface->busy()) { - // reschedule after waiting period - dmaWriteEvent.schedule(curTick + DMA_BACKOFF_PERIOD); - return; - } - - uint32_t bytesLeft = curPrd.getByteCount() - dmaInterfaceBytes; - curAddr = curPrd.getBaseAddr() + dmaInterfaceBytes; - dmaAddr = pciToDma(curAddr); - - bytesInPage = bytesInDmaPage(curAddr, bytesLeft); - dmaInterfaceBytes += bytesInPage; - - dmaInterface->doDMA(WriteInvalidate, dmaAddr, - bytesInPage, curTick, - &dmaWriteEvent); - - return; - } - - // setup the initial page and DMA address - curAddr = curPrd.getBaseAddr(); - pageAddr = TheISA::TruncPage(curAddr); - dmaAddr = pciToDma(curAddr); - - // clear out the data buffer - memset(dataBuffer, 0, MAX_DMA_SIZE); - - while (bytesRead < curPrd.getByteCount()) { - // see if we have crossed into a new page - if (pageAddr != TheISA::TruncPage(curAddr)) { - // write the data to memory - memcpy(physmem->dma_addr(dmaAddr, bytesInPage), - (void *)(dataBuffer + (bytesRead - bytesInPage)), - bytesInPage); - - // update the DMA address and page address - pageAddr = TheISA::TruncPage(curAddr); - dmaAddr = pciToDma(curAddr); - - bytesInPage = 0; - } - - if (cmdBytesLeft <= 0) - panic("DMA requested data is larger than # sectors specified\n"); - - readDisk(curSector++, (uint8_t *)(dataBuffer + bytesRead)); - - curAddr += SectorSize; - bytesRead += SectorSize; - bytesInPage += SectorSize; - cmdBytesLeft -= SectorSize; - } - - // write the last page worth read to memory - if (bytesInPage != 0) { - memcpy(physmem->dma_addr(dmaAddr, bytesInPage), - (void *)(dataBuffer + (bytesRead - bytesInPage)), - bytesInPage); - } - // check for the EOT if (curPrd.getEOT()) { assert(cmdBytesLeft == 0); @@ -1138,13 +1012,13 @@ IdeDisk::serialize(ostream &os) SERIALIZE_SCALAR(curPrd.entry.endOfTable); SERIALIZE_SCALAR(curPrdAddr); + /** @todo need to serialized chunk generator stuff!! */ // Serialize current transfer related information SERIALIZE_SCALAR(cmdBytesLeft); SERIALIZE_SCALAR(cmdBytes); SERIALIZE_SCALAR(drqBytesLeft); SERIALIZE_SCALAR(curSector); SERIALIZE_SCALAR(dmaRead); - SERIALIZE_SCALAR(dmaInterfaceBytes); SERIALIZE_SCALAR(intrPending); SERIALIZE_ENUM(devState); SERIALIZE_ENUM(dmaState); @@ -1190,13 +1064,13 @@ IdeDisk::unserialize(Checkpoint *cp, const string §ion) UNSERIALIZE_SCALAR(curPrd.entry.endOfTable); UNSERIALIZE_SCALAR(curPrdAddr); + /** @todo need to serialized chunk generator stuff!! */ // Unserialize current transfer related information UNSERIALIZE_SCALAR(cmdBytes); UNSERIALIZE_SCALAR(cmdBytesLeft); UNSERIALIZE_SCALAR(drqBytesLeft); UNSERIALIZE_SCALAR(curSector); UNSERIALIZE_SCALAR(dmaRead); - UNSERIALIZE_SCALAR(dmaInterfaceBytes); UNSERIALIZE_SCALAR(intrPending); UNSERIALIZE_ENUM(devState); UNSERIALIZE_ENUM(dmaState); @@ -1210,7 +1084,6 @@ static const char *DriveID_strings[] = { "master", "slave" }; BEGIN_DECLARE_SIM_OBJECT_PARAMS(IdeDisk) SimObjectParam<DiskImage *> image; - SimObjectParam<PhysicalMemory *> physmem; SimpleEnumParam<DriveID> driveID; Param<int> delay; @@ -1219,7 +1092,6 @@ END_DECLARE_SIM_OBJECT_PARAMS(IdeDisk) BEGIN_INIT_SIM_OBJECT_PARAMS(IdeDisk) INIT_PARAM(image, "Disk image"), - INIT_PARAM(physmem, "Physical memory"), INIT_ENUM_PARAM(driveID, "Drive ID (0=master 1=slave)", DriveID_strings), INIT_PARAM_DFLT(delay, "Fixed disk delay in microseconds", 1) @@ -1228,7 +1100,7 @@ END_INIT_SIM_OBJECT_PARAMS(IdeDisk) CREATE_SIM_OBJECT(IdeDisk) { - return new IdeDisk(getInstanceName(), image, physmem, driveID, delay); + return new IdeDisk(getInstanceName(), image, driveID, delay); } REGISTER_SIM_OBJECT("IdeDisk", IdeDisk) diff --git a/dev/ide_disk.hh b/dev/ide_disk.hh index a656ca464..3d67abece 100644 --- a/dev/ide_disk.hh +++ b/dev/ide_disk.hh @@ -42,7 +42,7 @@ #define DMA_BACKOFF_PERIOD 200 -#define MAX_DMA_SIZE (65536) // 64K +#define MAX_DMA_SIZE (131072) // 128K #define MAX_MULTSECT (128) #define PRD_BASE_MASK 0xfffffffe @@ -190,12 +190,8 @@ class IdeDisk : public SimObject protected: /** The IDE controller for this disk. */ IdeController *ctrl; - /** The DMA interface to use for transfers */ - DMAInterface<Bus> *dmaInterface; /** The image that contains the data of this disk. */ DiskImage *image; - /** Pointer to physical memory for DMA transfers */ - PhysicalMemory *physmem; protected: /** The disk delay in microseconds. */ @@ -230,8 +226,6 @@ class IdeDisk : public SimObject uint32_t curPrdAddr; /** PRD entry */ PrdTableEntry curPrd; - /** Number of bytes transfered by DMA interface for current transfer */ - uint32_t dmaInterfaceBytes; /** Device ID (master=0/slave=1) */ int devID; /** Interrupt pending */ @@ -242,12 +236,10 @@ class IdeDisk : public SimObject * Create and initialize this Disk. * @param name The name of this disk. * @param img The disk image of this disk. - * @param phys Pointer to physical memory * @param id The disk ID (master=0/slave=1) * @param disk_delay The disk delay in milliseconds */ - IdeDisk(const std::string &name, DiskImage *img, PhysicalMemory *phys, - int id, Tick disk_delay); + IdeDisk(const std::string &name, DiskImage *img, int id, Tick disk_delay); /** * Delete the data buffer. @@ -263,10 +255,9 @@ class IdeDisk : public SimObject * Set the controller for this device * @param c The IDE controller */ - void setController(IdeController *c, DMAInterface<Bus> *dmaIntr) { + void setController(IdeController *c) { if (ctrl) panic("Cannot change the controller once set!\n"); ctrl = c; - dmaInterface = dmaIntr; } // Device register read/write @@ -289,11 +280,17 @@ class IdeDisk : public SimObject friend class EventWrapper<IdeDisk, &IdeDisk::doDmaTransfer>; EventWrapper<IdeDisk, &IdeDisk::doDmaTransfer> dmaTransferEvent; + void doDmaDataRead(); + void doDmaRead(); + ChunkGenerator *dmaReadCG; friend class EventWrapper<IdeDisk, &IdeDisk::doDmaRead>; EventWrapper<IdeDisk, &IdeDisk::doDmaRead> dmaReadWaitEvent; + void doDmaDataWrite(); + void doDmaWrite(); + ChunkGenerator *dmaWriteCG; friend class EventWrapper<IdeDisk, &IdeDisk::doDmaWrite>; EventWrapper<IdeDisk, &IdeDisk::doDmaWrite> dmaWriteWaitEvent; @@ -339,8 +336,6 @@ class IdeDisk : public SimObject inline Addr pciToDma(Addr pciAddr); - uint32_t bytesInDmaPage(Addr curAddr, uint32_t bytesLeft); - /** * Serialize this object to the given output stream. * @param os The stream to serialize to. diff --git a/dev/io_device.cc b/dev/io_device.cc index a2e5a8a0d..42b3c382f 100644 --- a/dev/io_device.cc +++ b/dev/io_device.cc @@ -105,23 +105,24 @@ BasicPioDevice::addressRanges(AddrRangeList &range_list) } -DmaPort::DmaPort(DmaDevice *dev) - : device(dev) +DmaPort::DmaPort(DmaDevice *dev, Platform *p) + : device(dev), platform(p), pendingCount(0) { } bool DmaPort::recvTiming(Packet &pkt) { - completionEvent->schedule(curTick+1); - completionEvent = NULL; + if (pkt.senderState) { + DmaReqState *state; + state = (DmaReqState*)pkt.senderState; + state->completionEvent->schedule(pkt.time - pkt.req->getTime()); + } return Success; } DmaDevice::DmaDevice(Params *p) - : PioDevice(p) -{ - dmaPort = new DmaPort(this); -} + : PioDevice(p), dmaPort(NULL) +{ } void DmaPort::SendEvent::process() @@ -140,8 +141,8 @@ DmaPort::recvRetry() return pkt; } void -DmaPort::dmaAction(Command cmd, DmaPort port, Addr addr, int size, - Event *event, uint8_t *data) +DmaPort::dmaAction(Command cmd, Addr addr, int size, Event *event, + uint8_t *data) { assert(event); @@ -161,8 +162,6 @@ DmaPort::dmaAction(Command cmd, DmaPort port, Addr addr, int size, // baseReq.nicReq = true; baseReq.setTime(curTick); - completionEvent = event; - for (ChunkGenerator gen(addr, size, peerBlockSize()); !gen.done(); gen.next()) { Packet *pkt = new Packet(basePkt); @@ -173,16 +172,28 @@ DmaPort::dmaAction(Command cmd, DmaPort port, Addr addr, int size, pkt->req->setPaddr(pkt->addr); pkt->req->setSize(pkt->size); // Increment the data pointer on a write - pkt->data = data ? data + prevSize : NULL ; + if (data) + pkt->dataStatic(data + prevSize) ; prevSize += pkt->size; - - sendDma(*pkt); + // Set the last bit of the dma as the final packet for this dma + // and set it's completion event. + if (prevSize == size) { + DmaReqState *state = new DmaReqState(event, true); + + pkt->senderState = (void*)state; + } + assert(pendingCount >= 0); + pendingCount++; + sendDma(pkt); } + // since this isn't getting used and we want a check to make sure that all + // packets had data in them at some point. + basePkt.dataStatic((uint8_t*)NULL); } void -DmaPort::sendDma(Packet &pkt) +DmaPort::sendDma(Packet *pkt) { // some kind of selction between access methods // more work is going to have to be done to make @@ -193,9 +204,16 @@ DmaPort::sendDma(Packet &pkt) if (sendTiming(pkt) == Failure) transmitList.push_back(&packet); } else if (state == Atomic) {*/ - sendAtomic(pkt); - completionEvent->schedule(pkt.time - pkt.req->getTime()); - completionEvent = NULL; + sendAtomic(*pkt); + if (pkt->senderState) { + DmaReqState *state = (DmaReqState*)pkt->senderState; + state->completionEvent->schedule(curTick + (pkt->time - pkt->req->getTime()) +1); + } + pendingCount--; + assert(pendingCount >= 0); + delete pkt->req; + delete pkt; + /* } else if (state == Functional) { sendFunctional(pkt); // Is this correct??? diff --git a/dev/io_device.hh b/dev/io_device.hh index 5379a664c..bc0160c46 100644 --- a/dev/io_device.hh +++ b/dev/io_device.hh @@ -113,13 +113,28 @@ class PioPort : public Port friend class PioPort::SendEvent; }; + +struct DmaReqState +{ + Event *completionEvent; + bool final; + DmaReqState(Event *ce, bool f) + : completionEvent(ce), final(f) + {} +}; + class DmaPort : public Port { protected: - PioDevice *device; + DmaDevice *device; std::list<Packet*> transmitList; - Event *completionEvent; + /** The platform that device/port are in. This is used to select which mode + * we are currently operating in. */ + Platform *platform; + + /** Number of outstanding packets the dma port has. */ + int pendingCount; virtual bool recvTiming(Packet &pkt); virtual Tick recvAtomic(Packet &pkt) @@ -152,13 +167,15 @@ class DmaPort : public Port friend class DmaPort; }; - void dmaAction(Command cmd, DmaPort port, Addr addr, int size, - Event *event, uint8_t *data = NULL); - void sendDma(Packet &pkt); public: - DmaPort(DmaDevice *dev); + DmaPort(DmaDevice *dev, Platform *p); + + void dmaAction(Command cmd, Addr addr, int size, Event *event, + uint8_t *data = NULL); + + bool dmaPending() { return pendingCount > 0; } friend class DmaPort::SendEvent; @@ -286,13 +303,27 @@ class DmaDevice : public PioDevice DmaDevice(Params *p); virtual ~DmaDevice(); + void dmaWrite(Addr addr, int size, Event *event, uint8_t *data) + { dmaPort->dmaAction(Write, addr, size, event, data) ; } + + void dmaRead(Addr addr, int size, Event *event, uint8_t *data = NULL) + { dmaPort->dmaAction(Read, addr, size, event, data); } + + bool dmaPending() { return dmaPort->dmaPending(); } + virtual Port *getPort(const std::string &if_name) { - if (if_name == "pio") + if (if_name == "pio") { + if (pioPort != NULL) + panic("pio port already connected to."); + pioPort = new PioPort(this, params()->platform); return pioPort; - else if (if_name == "dma") + } else if (if_name == "dma") { + if (dmaPort != NULL) + panic("dma port already connected to."); + dmaPort = new DmaPort(this, params()->platform); return dmaPort; - else + } else return NULL; } diff --git a/dev/isa_fake.cc b/dev/isa_fake.cc index 1ed355499..8060d1a7c 100644 --- a/dev/isa_fake.cc +++ b/dev/isa_fake.cc @@ -58,47 +58,17 @@ IsaFake::read(Packet &pkt) DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt.addr, pkt.size); - uint8_t *data8; - uint16_t *data16; - uint32_t *data32; - uint64_t *data64; - switch (pkt.size) { - case sizeof(uint64_t): - if (!pkt.data) { - data64 = new uint64_t; - pkt.data = (uint8_t*)data64; - } else { - data64 = (uint64_t*)pkt.data; - } - *data64 = 0xFFFFFFFFFFFFFFFFULL; + pkt.set(0xFFFFFFFFFFFFFFFFULL); break; case sizeof(uint32_t): - if (!pkt.data) { - data32 = new uint32_t; - pkt.data = (uint8_t*)data32; - } else { - data32 = (uint32_t*)pkt.data; - } - *data32 = 0xFFFFFFFF; + pkt.set((uint32_t)0xFFFFFFFF); break; case sizeof(uint16_t): - if (!pkt.data) { - data16 = new uint16_t; - pkt.data = (uint8_t*)data16; - } else { - data16 = (uint16_t*)pkt.data; - } - *data16 = 0xFFFF; + pkt.set((uint16_t)0xFFFF); break; case sizeof(uint8_t): - if (!pkt.data) { - data8 = new uint8_t; - pkt.data = data8; - } else { - data8 = (uint8_t*)pkt.data; - } - *data8 = 0xFF; + pkt.set((uint8_t)0xFF); break; default: panic("invalid access size(?) for PCI configspace!\n"); diff --git a/dev/ns_gige.cc b/dev/ns_gige.cc index f7e67811c..02c9bbca4 100644 --- a/dev/ns_gige.cc +++ b/dev/ns_gige.cc @@ -40,17 +40,12 @@ #include "dev/etherlink.hh" #include "dev/ns_gige.hh" #include "dev/pciconfigall.hh" -#include "mem/bus/bus.hh" -#include "mem/bus/dma_interface.hh" -#include "mem/bus/pio_interface.hh" -#include "mem/bus/pio_interface_impl.hh" -#include "mem/functional/memory_control.hh" -#include "mem/functional/physical.hh" +#include "mem/packet.hh" #include "sim/builder.hh" #include "sim/debug.hh" #include "sim/host.hh" #include "sim/stats.hh" -#include "arch/vtophys.hh" +#include "sim/system.hh" const char *NsRxStateStrings[] = { @@ -108,29 +103,9 @@ NSGigE::NSGigE(Params *p) txEvent(this), rxFilterEnable(p->rx_filter), acceptBroadcast(false), acceptMulticast(false), acceptUnicast(false), acceptPerfect(false), acceptArp(false), multicastHashEnable(false), - physmem(p->pmem), intrTick(0), cpuPendingIntr(false), + intrTick(0), cpuPendingIntr(false), intrEvent(0), interface(0) { - if (p->pio_bus) { - pioInterface = newPioInterface(name() + ".pio", p->hier, - p->pio_bus, this, - &NSGigE::cacheAccess); - pioLatency = p->pio_latency * p->pio_bus->clockRate; - } - - if (p->header_bus) { - if (p->payload_bus) - dmaInterface = new DMAInterface<Bus>(name() + ".dma", - p->header_bus, - p->payload_bus, 1, - p->dma_no_allocate); - else - dmaInterface = new DMAInterface<Bus>(name() + ".dma", - p->header_bus, - p->header_bus, 1, - p->dma_no_allocate); - } else if (p->payload_bus) - panic("Must define a header bus if defining a payload bus"); intrDelay = p->intr_delay; dmaReadDelay = p->dma_read_delay; @@ -484,30 +459,18 @@ NSGigE::regStats() rxPacketRate = rxPackets / simSeconds; } -/** - * This is to read the PCI general configuration registers - */ -void -NSGigE::readConfig(int offset, int size, uint8_t *data) -{ - if (offset < PCI_DEVICE_SPECIFIC) - PciDev::readConfig(offset, size, data); - else - panic("Device specific PCI config space not implemented!\n"); -} /** * This is to write to the PCI general configuration registers */ void -NSGigE::writeConfig(int offset, int size, const uint8_t* data) +NSGigE::writeConfig(int offset, const uint16_t data) { if (offset < PCI_DEVICE_SPECIFIC) - PciDev::writeConfig(offset, size, data); + PciDev::writeConfig(offset, data); else panic("Device specific PCI config space not implemented!\n"); - // Need to catch writes to BARs to update the PIO interface switch (offset) { // seems to work fine without all these PCI settings, but i // put in the IO to double check, an assertion will fail if we @@ -517,39 +480,6 @@ NSGigE::writeConfig(int offset, int size, const uint8_t* data) ioEnable = true; else ioEnable = false; - -#if 0 - if (config.data[offset] & PCI_CMD_BME) { - bmEnabled = true; - } - else { - bmEnabled = false; - } - - if (config.data[offset] & PCI_CMD_MSE) { - memEnable = true; - } - else { - memEnable = false; - } -#endif - break; - - case PCI0_BASE_ADDR0: - if (BARAddrs[0] != 0) { - if (pioInterface) - pioInterface->addAddrRange(RangeSize(BARAddrs[0], BARSize[0])); - - BARAddrs[0] &= EV5::PAddrUncachedMask; - } - break; - case PCI0_BASE_ADDR1: - if (BARAddrs[1] != 0) { - if (pioInterface) - pioInterface->addAddrRange(RangeSize(BARAddrs[1], BARSize[1])); - - BARAddrs[1] &= EV5::PAddrUncachedMask; - } break; } } @@ -558,15 +488,18 @@ NSGigE::writeConfig(int offset, int size, const uint8_t* data) * This reads the device registers, which are detailed in the NS83820 * spec sheet */ -Fault -NSGigE::read(MemReqPtr &req, uint8_t *data) +Tick +NSGigE::read(Packet &pkt) { assert(ioEnable); + pkt.time = curTick + pioDelay; + pkt.allocate(); + //The mask is to give you only the offset into the device register file - Addr daddr = req->paddr & 0xfff; - DPRINTF(EthernetPIO, "read da=%#x pa=%#x va=%#x size=%d\n", - daddr, req->paddr, req->vaddr, req->size); + Addr daddr = pkt.addr & 0xfff; + DPRINTF(EthernetPIO, "read da=%#x pa=%#x size=%d\n", + daddr, pkt.addr, pkt.size); // there are some reserved registers, you can see ns_gige_reg.h and @@ -574,240 +507,246 @@ NSGigE::read(MemReqPtr &req, uint8_t *data) if (daddr > LAST && daddr <= RESERVED) { panic("Accessing reserved register"); } else if (daddr > RESERVED && daddr <= 0x3FC) { - readConfig(daddr & 0xff, req->size, data); - return NoFault; + if (pkt.size == sizeof(uint8_t)) + readConfig(daddr & 0xff, pkt.getPtr<uint8_t>()); + if (pkt.size == sizeof(uint16_t)) + readConfig(daddr & 0xff, pkt.getPtr<uint16_t>()); + if (pkt.size == sizeof(uint32_t)) + readConfig(daddr & 0xff, pkt.getPtr<uint32_t>()); + pkt.result = Success; + return pioDelay; } else if (daddr >= MIB_START && daddr <= MIB_END) { // don't implement all the MIB's. hopefully the kernel // doesn't actually DEPEND upon their values // MIB are just hardware stats keepers - uint32_t ® = *(uint32_t *) data; - reg = 0; - return NoFault; + pkt.set<uint32_t>(0); + pkt.result = Success; + return pioDelay; } else if (daddr > 0x3FC) panic("Something is messed up!\n"); - switch (req->size) { - case sizeof(uint32_t): - { - uint32_t ® = *(uint32_t *)data; - uint16_t rfaddr; - - switch (daddr) { - case CR: - reg = regs.command; - //these are supposed to be cleared on a read - reg &= ~(CR_RXD | CR_TXD | CR_TXR | CR_RXR); - break; + assert(pkt.size == sizeof(uint32_t)); + uint32_t ® = *pkt.getPtr<uint32_t>(); + uint16_t rfaddr; - case CFGR: - reg = regs.config; - break; + switch (daddr) { + case CR: + reg = regs.command; + //these are supposed to be cleared on a read + reg &= ~(CR_RXD | CR_TXD | CR_TXR | CR_RXR); + break; - case MEAR: - reg = regs.mear; - break; + case CFGR: + reg = regs.config; + break; - case PTSCR: - reg = regs.ptscr; - break; + case MEAR: + reg = regs.mear; + break; - case ISR: - reg = regs.isr; - devIntrClear(ISR_ALL); - break; + case PTSCR: + reg = regs.ptscr; + break; - case IMR: - reg = regs.imr; - break; + case ISR: + reg = regs.isr; + devIntrClear(ISR_ALL); + break; - case IER: - reg = regs.ier; - break; + case IMR: + reg = regs.imr; + break; - case IHR: - reg = regs.ihr; - break; + case IER: + reg = regs.ier; + break; - case TXDP: - reg = regs.txdp; - break; + case IHR: + reg = regs.ihr; + break; - case TXDP_HI: - reg = regs.txdp_hi; - break; + case TXDP: + reg = regs.txdp; + break; - case TX_CFG: - reg = regs.txcfg; - break; + case TXDP_HI: + reg = regs.txdp_hi; + break; - case GPIOR: - reg = regs.gpior; - break; + case TX_CFG: + reg = regs.txcfg; + break; - case RXDP: - reg = regs.rxdp; - break; + case GPIOR: + reg = regs.gpior; + break; - case RXDP_HI: - reg = regs.rxdp_hi; - break; + case RXDP: + reg = regs.rxdp; + break; - case RX_CFG: - reg = regs.rxcfg; - break; + case RXDP_HI: + reg = regs.rxdp_hi; + break; - case PQCR: - reg = regs.pqcr; - break; + case RX_CFG: + reg = regs.rxcfg; + break; - case WCSR: - reg = regs.wcsr; - break; + case PQCR: + reg = regs.pqcr; + break; - case PCR: - reg = regs.pcr; - break; + case WCSR: + reg = regs.wcsr; + break; + + case PCR: + reg = regs.pcr; + break; + + // see the spec sheet for how RFCR and RFDR work + // basically, you write to RFCR to tell the machine + // what you want to do next, then you act upon RFDR, + // and the device will be prepared b/c of what you + // wrote to RFCR + case RFCR: + reg = regs.rfcr; + break; - // see the spec sheet for how RFCR and RFDR work - // basically, you write to RFCR to tell the machine - // what you want to do next, then you act upon RFDR, - // and the device will be prepared b/c of what you - // wrote to RFCR - case RFCR: - reg = regs.rfcr; + case RFDR: + rfaddr = (uint16_t)(regs.rfcr & RFCR_RFADDR); + switch (rfaddr) { + // Read from perfect match ROM octets + case 0x000: + reg = rom.perfectMatch[1]; + reg = reg << 8; + reg += rom.perfectMatch[0]; + break; + case 0x002: + reg = rom.perfectMatch[3] << 8; + reg += rom.perfectMatch[2]; break; + case 0x004: + reg = rom.perfectMatch[5] << 8; + reg += rom.perfectMatch[4]; + break; + default: + // Read filter hash table + if (rfaddr >= FHASH_ADDR && + rfaddr < FHASH_ADDR + FHASH_SIZE) { - case RFDR: - rfaddr = (uint16_t)(regs.rfcr & RFCR_RFADDR); - switch (rfaddr) { - // Read from perfect match ROM octets - case 0x000: - reg = rom.perfectMatch[1]; - reg = reg << 8; - reg += rom.perfectMatch[0]; - break; - case 0x002: - reg = rom.perfectMatch[3] << 8; - reg += rom.perfectMatch[2]; - break; - case 0x004: - reg = rom.perfectMatch[5] << 8; - reg += rom.perfectMatch[4]; - break; - default: - // Read filter hash table - if (rfaddr >= FHASH_ADDR && - rfaddr < FHASH_ADDR + FHASH_SIZE) { - - // Only word-aligned reads supported - if (rfaddr % 2) - panic("unaligned read from filter hash table!"); - - reg = rom.filterHash[rfaddr - FHASH_ADDR + 1] << 8; - reg += rom.filterHash[rfaddr - FHASH_ADDR]; - break; - } + // Only word-aligned reads supported + if (rfaddr % 2) + panic("unaligned read from filter hash table!"); - panic("reading RFDR for something other than pattern" - " matching or hashing! %#x\n", rfaddr); + reg = rom.filterHash[rfaddr - FHASH_ADDR + 1] << 8; + reg += rom.filterHash[rfaddr - FHASH_ADDR]; + break; } - break; - case SRR: - reg = regs.srr; - break; + panic("reading RFDR for something other than pattern" + " matching or hashing! %#x\n", rfaddr); + } + break; - case MIBC: - reg = regs.mibc; - reg &= ~(MIBC_MIBS | MIBC_ACLR); - break; + case SRR: + reg = regs.srr; + break; - case VRCR: - reg = regs.vrcr; - break; + case MIBC: + reg = regs.mibc; + reg &= ~(MIBC_MIBS | MIBC_ACLR); + break; - case VTCR: - reg = regs.vtcr; - break; + case VRCR: + reg = regs.vrcr; + break; - case VDR: - reg = regs.vdr; - break; + case VTCR: + reg = regs.vtcr; + break; - case CCSR: - reg = regs.ccsr; - break; + case VDR: + reg = regs.vdr; + break; - case TBICR: - reg = regs.tbicr; - break; + case CCSR: + reg = regs.ccsr; + break; - case TBISR: - reg = regs.tbisr; - break; + case TBICR: + reg = regs.tbicr; + break; - case TANAR: - reg = regs.tanar; - break; + case TBISR: + reg = regs.tbisr; + break; - case TANLPAR: - reg = regs.tanlpar; - break; + case TANAR: + reg = regs.tanar; + break; - case TANER: - reg = regs.taner; - break; + case TANLPAR: + reg = regs.tanlpar; + break; - case TESR: - reg = regs.tesr; - break; + case TANER: + reg = regs.taner; + break; - case M5REG: - reg = 0; - if (params()->rx_thread) - reg |= M5REG_RX_THREAD; - if (params()->tx_thread) - reg |= M5REG_TX_THREAD; - if (params()->rss) - reg |= M5REG_RSS; - break; + case TESR: + reg = regs.tesr; + break; - default: - panic("reading unimplemented register: addr=%#x", daddr); - } + case M5REG: + reg = 0; + if (params()->rx_thread) + reg |= M5REG_RX_THREAD; + if (params()->tx_thread) + reg |= M5REG_TX_THREAD; + if (params()->rss) + reg |= M5REG_RSS; + break; - DPRINTF(EthernetPIO, "read from %#x: data=%d data=%#x\n", - daddr, reg, reg); + default: + panic("reading unimplemented register: addr=%#x", daddr); } - break; - default: - panic("accessing register with invalid size: addr=%#x, size=%d", - daddr, req->size); - } + DPRINTF(EthernetPIO, "read from %#x: data=%d data=%#x\n", + daddr, reg, reg); - return NoFault; + pkt.result = Success; + return pioDelay; } -Fault -NSGigE::write(MemReqPtr &req, const uint8_t *data) +Tick +NSGigE::write(Packet &pkt) { assert(ioEnable); - Addr daddr = req->paddr & 0xfff; - DPRINTF(EthernetPIO, "write da=%#x pa=%#x va=%#x size=%d\n", - daddr, req->paddr, req->vaddr, req->size); + Addr daddr = pkt.addr & 0xfff; + DPRINTF(EthernetPIO, "write da=%#x pa=%#x size=%d\n", + daddr, pkt.addr, pkt.size); + + pkt.time = curTick + pioDelay; if (daddr > LAST && daddr <= RESERVED) { panic("Accessing reserved register"); } else if (daddr > RESERVED && daddr <= 0x3FC) { - writeConfig(daddr & 0xff, req->size, data); - return NoFault; + if (pkt.size == sizeof(uint8_t)) + writeConfig(daddr & 0xff, pkt.get<uint8_t>()); + if (pkt.size == sizeof(uint16_t)) + writeConfig(daddr & 0xff, pkt.get<uint16_t>()); + if (pkt.size == sizeof(uint32_t)) + writeConfig(daddr & 0xff, pkt.get<uint32_t>()); + pkt.result = Success; + return pioDelay; } else if (daddr > 0x3FC) panic("Something is messed up!\n"); - if (req->size == sizeof(uint32_t)) { - uint32_t reg = *(uint32_t *)data; + if (pkt.size == sizeof(uint32_t)) { + uint32_t reg = pkt.get<uint32_t>(); uint16_t rfaddr; DPRINTF(EthernetPIO, "write data=%d data=%#x\n", reg, reg); @@ -1193,8 +1132,8 @@ NSGigE::write(MemReqPtr &req, const uint8_t *data) } else { panic("Invalid Request Size"); } - - return NoFault; + pkt.result = Success; + return pioDelay; } void @@ -1444,42 +1383,17 @@ NSGigE::regsReset() acceptArp = false; } -void -NSGigE::rxDmaReadCopy() -{ - assert(rxDmaState == dmaReading); - - physmem->dma_read((uint8_t *)rxDmaData, rxDmaAddr, rxDmaLen); - rxDmaState = dmaIdle; - - DPRINTF(EthernetDMA, "rx dma read paddr=%#x len=%d\n", - rxDmaAddr, rxDmaLen); - DDUMP(EthernetDMA, rxDmaData, rxDmaLen); -} - bool NSGigE::doRxDmaRead() { assert(rxDmaState == dmaIdle || rxDmaState == dmaReadWaiting); rxDmaState = dmaReading; - if (dmaInterface && !rxDmaFree) { - if (dmaInterface->busy()) - rxDmaState = dmaReadWaiting; - else - dmaInterface->doDMA(Read, rxDmaAddr, rxDmaLen, curTick, - &rxDmaReadEvent, true); - return true; - } - - if (dmaReadDelay == 0 && dmaReadFactor == 0) { - rxDmaReadCopy(); - return false; - } + if (dmaPending()) + rxDmaState = dmaReadWaiting; + else + dmaRead(rxDmaAddr, rxDmaLen, &rxDmaReadEvent, (uint8_t*)rxDmaData); - Tick factor = ((rxDmaLen + ULL(63)) >> ULL(6)) * dmaReadFactor; - Tick start = curTick + dmaReadDelay + factor; - rxDmaReadEvent.schedule(start); return true; } @@ -1487,7 +1401,11 @@ void NSGigE::rxDmaReadDone() { assert(rxDmaState == dmaReading); - rxDmaReadCopy(); + rxDmaState = dmaIdle; + + DPRINTF(EthernetDMA, "rx dma read paddr=%#x len=%d\n", + rxDmaAddr, rxDmaLen); + DDUMP(EthernetDMA, rxDmaData, rxDmaLen); // If the transmit state machine has a pending DMA, let it go first if (txDmaState == dmaReadWaiting || txDmaState == dmaWriteWaiting) @@ -1496,42 +1414,16 @@ NSGigE::rxDmaReadDone() rxKick(); } -void -NSGigE::rxDmaWriteCopy() -{ - assert(rxDmaState == dmaWriting); - - physmem->dma_write(rxDmaAddr, (uint8_t *)rxDmaData, rxDmaLen); - rxDmaState = dmaIdle; - - DPRINTF(EthernetDMA, "rx dma write paddr=%#x len=%d\n", - rxDmaAddr, rxDmaLen); - DDUMP(EthernetDMA, rxDmaData, rxDmaLen); -} - bool NSGigE::doRxDmaWrite() { assert(rxDmaState == dmaIdle || rxDmaState == dmaWriteWaiting); rxDmaState = dmaWriting; - if (dmaInterface && !rxDmaFree) { - if (dmaInterface->busy()) - rxDmaState = dmaWriteWaiting; - else - dmaInterface->doDMA(WriteInvalidate, rxDmaAddr, rxDmaLen, curTick, - &rxDmaWriteEvent, true); - return true; - } - - if (dmaWriteDelay == 0 && dmaWriteFactor == 0) { - rxDmaWriteCopy(); - return false; - } - - Tick factor = ((rxDmaLen + ULL(63)) >> ULL(6)) * dmaWriteFactor; - Tick start = curTick + dmaWriteDelay + factor; - rxDmaWriteEvent.schedule(start); + if (dmaPending()) + rxDmaState = dmaWriteWaiting; + else + dmaWrite(rxDmaAddr, rxDmaLen, &rxDmaWriteEvent, (uint8_t*)rxDmaData); return true; } @@ -1539,7 +1431,11 @@ void NSGigE::rxDmaWriteDone() { assert(rxDmaState == dmaWriting); - rxDmaWriteCopy(); + rxDmaState = dmaIdle; + + DPRINTF(EthernetDMA, "rx dma write paddr=%#x len=%d\n", + rxDmaAddr, rxDmaLen); + DDUMP(EthernetDMA, rxDmaData, rxDmaLen); // If the transmit state machine has a pending DMA, let it go first if (txDmaState == dmaReadWaiting || txDmaState == dmaWriteWaiting) @@ -1936,42 +1832,17 @@ NSGigE::transmit() } } -void -NSGigE::txDmaReadCopy() -{ - assert(txDmaState == dmaReading); - - physmem->dma_read((uint8_t *)txDmaData, txDmaAddr, txDmaLen); - txDmaState = dmaIdle; - - DPRINTF(EthernetDMA, "tx dma read paddr=%#x len=%d\n", - txDmaAddr, txDmaLen); - DDUMP(EthernetDMA, txDmaData, txDmaLen); -} - bool NSGigE::doTxDmaRead() { assert(txDmaState == dmaIdle || txDmaState == dmaReadWaiting); txDmaState = dmaReading; - if (dmaInterface && !txDmaFree) { - if (dmaInterface->busy()) - txDmaState = dmaReadWaiting; - else - dmaInterface->doDMA(Read, txDmaAddr, txDmaLen, curTick, - &txDmaReadEvent, true); - return true; - } - - if (dmaReadDelay == 0 && dmaReadFactor == 0.0) { - txDmaReadCopy(); - return false; - } + if (dmaPending()) + txDmaState = dmaReadWaiting; + else + dmaRead(txDmaAddr, txDmaLen, &txDmaReadEvent, (uint8_t*)txDmaData); - Tick factor = ((txDmaLen + ULL(63)) >> ULL(6)) * dmaReadFactor; - Tick start = curTick + dmaReadDelay + factor; - txDmaReadEvent.schedule(start); return true; } @@ -1979,7 +1850,11 @@ void NSGigE::txDmaReadDone() { assert(txDmaState == dmaReading); - txDmaReadCopy(); + txDmaState = dmaIdle; + + DPRINTF(EthernetDMA, "tx dma read paddr=%#x len=%d\n", + txDmaAddr, txDmaLen); + DDUMP(EthernetDMA, txDmaData, txDmaLen); // If the receive state machine has a pending DMA, let it go first if (rxDmaState == dmaReadWaiting || rxDmaState == dmaWriteWaiting) @@ -1988,42 +1863,16 @@ NSGigE::txDmaReadDone() txKick(); } -void -NSGigE::txDmaWriteCopy() -{ - assert(txDmaState == dmaWriting); - - physmem->dma_write(txDmaAddr, (uint8_t *)txDmaData, txDmaLen); - txDmaState = dmaIdle; - - DPRINTF(EthernetDMA, "tx dma write paddr=%#x len=%d\n", - txDmaAddr, txDmaLen); - DDUMP(EthernetDMA, txDmaData, txDmaLen); -} - bool NSGigE::doTxDmaWrite() { assert(txDmaState == dmaIdle || txDmaState == dmaWriteWaiting); txDmaState = dmaWriting; - if (dmaInterface && !txDmaFree) { - if (dmaInterface->busy()) - txDmaState = dmaWriteWaiting; - else - dmaInterface->doDMA(WriteInvalidate, txDmaAddr, txDmaLen, curTick, - &txDmaWriteEvent, true); - return true; - } - - if (dmaWriteDelay == 0 && dmaWriteFactor == 0.0) { - txDmaWriteCopy(); - return false; - } - - Tick factor = ((txDmaLen + ULL(63)) >> ULL(6)) * dmaWriteFactor; - Tick start = curTick + dmaWriteDelay + factor; - txDmaWriteEvent.schedule(start); + if (dmaPending()) + txDmaState = dmaWriteWaiting; + else + dmaWrite(txDmaAddr, txDmaLen, &txDmaWriteEvent, (uint8_t*)txDmaData); return true; } @@ -2031,7 +1880,11 @@ void NSGigE::txDmaWriteDone() { assert(txDmaState == dmaWriting); - txDmaWriteCopy(); + txDmaState = dmaIdle; + + DPRINTF(EthernetDMA, "tx dma write paddr=%#x len=%d\n", + txDmaAddr, txDmaLen); + DDUMP(EthernetDMA, txDmaData, txDmaLen); // If the receive state machine has a pending DMA, let it go first if (rxDmaState == dmaReadWaiting || rxDmaState == dmaWriteWaiting) @@ -2148,7 +2001,7 @@ NSGigE::txKick() case txFifoBlock: if (!txPacket) { DPRINTF(EthernetSM, "****starting the tx of a new packet****\n"); - txPacket = new PacketData(16384); + txPacket = new EthPacketData(16384); txPacketBufPtr = txPacket->data; } @@ -2474,7 +2327,7 @@ NSGigE::transferDone() } bool -NSGigE::rxFilter(const PacketPtr &packet) +NSGigE::rxFilter(const EthPacketPtr &packet) { EthPtr eth = packet; bool drop = true; @@ -2517,7 +2370,7 @@ NSGigE::rxFilter(const PacketPtr &packet) } bool -NSGigE::recvPacket(PacketPtr packet) +NSGigE::recvPacket(EthPacketPtr packet) { rxBytes += packet->length; rxPackets++; @@ -2577,14 +2430,7 @@ NSGigE::serialize(ostream &os) /* * Finalize any DMA events now. */ - if (rxDmaReadEvent.scheduled()) - rxDmaReadCopy(); - if (rxDmaWriteEvent.scheduled()) - rxDmaWriteCopy(); - if (txDmaReadEvent.scheduled()) - txDmaReadCopy(); - if (txDmaWriteEvent.scheduled()) - txDmaWriteCopy(); + // @todo will mem system save pending dma? /* * Serialize the device registers @@ -2805,7 +2651,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) bool txPacketExists; UNSERIALIZE_SCALAR(txPacketExists); if (txPacketExists) { - txPacket = new PacketData(16384); + txPacket = new EthPacketData(16384); txPacket->unserialize("txPacket", cp, section); uint32_t txPktBufPtr; UNSERIALIZE_SCALAR(txPktBufPtr); @@ -2817,7 +2663,7 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(rxPacketExists); rxPacket = 0; if (rxPacketExists) { - rxPacket = new PacketData(16384); + rxPacket = new EthPacketData(16384); rxPacket->unserialize("rxPacket", cp, section); uint32_t rxPktBufPtr; UNSERIALIZE_SCALAR(rxPktBufPtr); @@ -2926,23 +2772,6 @@ NSGigE::unserialize(Checkpoint *cp, const std::string §ion) intrEvent = new IntrEvent(this, true); intrEvent->schedule(intrEventTick); } - - /* - * re-add addrRanges to bus bridges - */ - if (pioInterface) { - pioInterface->addAddrRange(RangeSize(BARAddrs[0], BARSize[0])); - pioInterface->addAddrRange(RangeSize(BARAddrs[1], BARSize[1])); - } -} - -Tick -NSGigE::cacheAccess(MemReqPtr &req) -{ - DPRINTF(EthernetPIO, "timing access to paddr=%#x (daddr=%#x)\n", - req->paddr, req->paddr & 0xfff); - - return curTick + pioLatency; } BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigEInt) @@ -2977,22 +2806,16 @@ REGISTER_SIM_OBJECT("NSGigEInt", NSGigEInt) BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE) - Param<Tick> clock; - - Param<Addr> addr; - SimObjectParam<MemoryController *> mmu; - SimObjectParam<PhysicalMemory *> physmem; + SimObjectParam<System *> system; + SimObjectParam<Platform *> platform; SimObjectParam<PciConfigAll *> configspace; SimObjectParam<PciConfigData *> configdata; - SimObjectParam<Platform *> platform; Param<uint32_t> pci_bus; Param<uint32_t> pci_dev; Param<uint32_t> pci_func; + Param<Tick> pio_latency; - SimObjectParam<HierParams *> hier; - SimObjectParam<Bus*> pio_bus; - SimObjectParam<Bus*> dma_bus; - SimObjectParam<Bus*> payload_bus; + Param<Tick> clock; Param<bool> dma_desc_free; Param<bool> dma_data_free; Param<Tick> dma_read_delay; @@ -3000,7 +2823,6 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(NSGigE) Param<Tick> dma_read_factor; Param<Tick> dma_write_factor; Param<bool> dma_no_allocate; - Param<Tick> pio_latency; Param<Tick> intr_delay; Param<Tick> rx_delay; @@ -3018,22 +2840,16 @@ END_DECLARE_SIM_OBJECT_PARAMS(NSGigE) BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE) - INIT_PARAM(clock, "State machine processor frequency"), - - INIT_PARAM(addr, "Device Address"), - INIT_PARAM(mmu, "Memory Controller"), - INIT_PARAM(physmem, "Physical Memory"), + INIT_PARAM(system, "System pointer"), + INIT_PARAM(platform, "Platform pointer"), INIT_PARAM(configspace, "PCI Configspace"), INIT_PARAM(configdata, "PCI Config data"), - INIT_PARAM(platform, "Platform"), - INIT_PARAM(pci_bus, "PCI bus"), + INIT_PARAM(pci_bus, "PCI bus ID"), INIT_PARAM(pci_dev, "PCI device number"), INIT_PARAM(pci_func, "PCI function code"), + INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1), + INIT_PARAM(clock, "State machine cycle time"), - INIT_PARAM(hier, "Hierarchy global variables"), - INIT_PARAM(pio_bus, ""), - INIT_PARAM(dma_bus, ""), - INIT_PARAM(payload_bus, "The IO Bus to attach to for payload"), INIT_PARAM(dma_desc_free, "DMA of Descriptors is free"), INIT_PARAM(dma_data_free, "DMA of Data is free"), INIT_PARAM(dma_read_delay, "fixed delay for dma reads"), @@ -3041,7 +2857,6 @@ BEGIN_INIT_SIM_OBJECT_PARAMS(NSGigE) INIT_PARAM(dma_read_factor, "multiplier for dma reads"), INIT_PARAM(dma_write_factor, "multiplier for dma writes"), INIT_PARAM(dma_no_allocate, "Should DMA reads allocate cache lines"), - INIT_PARAM(pio_latency, "Programmed IO latency in bus cycles"), INIT_PARAM(intr_delay, "Interrupt Delay in microseconds"), INIT_PARAM(rx_delay, "Receive Delay"), @@ -3063,22 +2878,16 @@ CREATE_SIM_OBJECT(NSGigE) NSGigE::Params *params = new NSGigE::Params; params->name = getInstanceName(); - - params->clock = clock; - - params->mmu = mmu; - params->pmem = physmem; + params->platform = platform; + params->system = system; params->configSpace = configspace; params->configData = configdata; - params->plat = platform; params->busNum = pci_bus; params->deviceNum = pci_dev; params->functionNum = pci_func; + params->pio_delay = pio_latency; - params->hier = hier; - params->pio_bus = pio_bus; - params->header_bus = dma_bus; - params->payload_bus = payload_bus; + params->clock = clock; params->dma_desc_free = dma_desc_free; params->dma_data_free = dma_data_free; params->dma_read_delay = dma_read_delay; @@ -3086,7 +2895,7 @@ CREATE_SIM_OBJECT(NSGigE) params->dma_read_factor = dma_read_factor; params->dma_write_factor = dma_write_factor; params->dma_no_allocate = dma_no_allocate; - params->pio_latency = pio_latency; + params->pio_delay = pio_latency; params->intr_delay = intr_delay; params->rx_delay = rx_delay; diff --git a/dev/ns_gige.hh b/dev/ns_gige.hh index 59c55056e..7bb422287 100644 --- a/dev/ns_gige.hh +++ b/dev/ns_gige.hh @@ -42,7 +42,6 @@ #include "dev/ns_gige_reg.h" #include "dev/pcidev.hh" #include "dev/pktfifo.hh" -#include "mem/bus/bus.hh" #include "sim/eventq.hh" // Hash filtering constants @@ -111,10 +110,7 @@ struct dp_rom { }; class NSGigEInt; -class PhysicalMemory; -class BaseInterface; -class HierParams; -class Bus; +class Packet; class PciConfigAll; /** @@ -165,10 +161,6 @@ class NSGigE : public PciDev eepromRead }; - private: - Addr addr; - static const Addr size = sizeof(dp_regs); - protected: /** device register file */ dp_regs regs; @@ -187,8 +179,8 @@ class NSGigE : public PciDev PacketFifo rxFifo; /** various helper vars */ - PacketPtr txPacket; - PacketPtr rxPacket; + EthPacketPtr txPacket; + EthPacketPtr rxPacket; uint8_t *txPacketBufPtr; uint8_t *rxPacketBufPtr; uint32_t txXferLen; @@ -258,16 +250,12 @@ class NSGigE : public PciDev int rxDmaLen; bool doRxDmaRead(); bool doRxDmaWrite(); - void rxDmaReadCopy(); - void rxDmaWriteCopy(); void *txDmaData; Addr txDmaAddr; int txDmaLen; bool doTxDmaRead(); bool doTxDmaWrite(); - void txDmaReadCopy(); - void txDmaWriteCopy(); void rxDmaReadDone(); friend class EventWrapper<NSGigE, &NSGigE::rxDmaReadDone>; @@ -331,7 +319,7 @@ class NSGigE : public PciDev * receive address filter */ bool rxFilterEnable; - bool rxFilter(const PacketPtr &packet); + bool rxFilter(const EthPacketPtr &packet); bool acceptBroadcast; bool acceptMulticast; bool acceptUnicast; @@ -339,8 +327,6 @@ class NSGigE : public PciDev bool acceptArp; bool multicastHashEnable; - PhysicalMemory *physmem; - /** * Interrupt management */ @@ -363,16 +349,10 @@ class NSGigE : public PciDev public: struct Params : public PciDev::Params { - PhysicalMemory *pmem; - HierParams *hier; - Bus *pio_bus; - Bus *header_bus; - Bus *payload_bus; Tick clock; Tick intr_delay; Tick tx_delay; Tick rx_delay; - Tick pio_latency; bool dma_desc_free; bool dma_data_free; Tick dma_read_delay; @@ -393,16 +373,15 @@ class NSGigE : public PciDev ~NSGigE(); const Params *params() const { return (const Params *)_params; } - virtual void writeConfig(int offset, int size, const uint8_t *data); - virtual void readConfig(int offset, int size, uint8_t *data); + virtual void writeConfig(int offset, const uint16_t data); - virtual Fault read(MemReqPtr &req, uint8_t *data); - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Tick read(Packet &pkt); + virtual Tick write(Packet &pkt); bool cpuIntrPending() const; void cpuIntrAck() { cpuIntrClear(); } - bool recvPacket(PacketPtr packet); + bool recvPacket(EthPacketPtr packet); void transferDone(); void setInterface(NSGigEInt *i) { assert(!interface); interface = i; } @@ -463,9 +442,6 @@ class NSGigE : public PciDev Stats::Formula coalescedTotal; Stats::Scalar<> postedInterrupts; Stats::Scalar<> droppedPackets; - - public: - Tick cacheAccess(MemReqPtr &req); }; /* @@ -480,7 +456,7 @@ class NSGigEInt : public EtherInt NSGigEInt(const std::string &name, NSGigE *d) : EtherInt(name), dev(d) { dev->setInterface(this); } - virtual bool recvPacket(PacketPtr pkt) { return dev->recvPacket(pkt); } + virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); } virtual void sendDone() { dev->transferDone(); } }; diff --git a/dev/pciconfigall.cc b/dev/pciconfigall.cc index 86a505b9a..c3597c486 100644 --- a/dev/pciconfigall.cc +++ b/dev/pciconfigall.cc @@ -37,7 +37,7 @@ #include "base/trace.hh" #include "dev/pciconfigall.hh" -//#include "dev/pcidev.hh" +#include "dev/pcidev.hh" #include "dev/pcireg.h" #include "dev/platform.hh" #include "mem/packet.hh" @@ -68,7 +68,7 @@ PciConfigAll::PciConfigAll(Params *p) void PciConfigAll::startup() { -/* bitset<256> intLines; + bitset<256> intLines; PciDev *tempDev; uint8_t intline; @@ -85,7 +85,7 @@ PciConfigAll::startup() } // devices != NULL } // PCI_FUNC } // PCI_DEV - */ + } Tick @@ -97,65 +97,32 @@ PciConfigAll::read(Packet &pkt) Addr daddr = pkt.addr - pioAddr; int device = (daddr >> 11) & 0x1F; int func = (daddr >> 8) & 0x7; - //int reg = daddr & 0xFF; + int reg = daddr & 0xFF; pkt.time = curTick + pioDelay; + pkt.allocate(); DPRINTF(PciConfigAll, "read va=%#x da=%#x size=%d\n", pkt.addr, daddr, pkt.size); - uint8_t *data8; - uint16_t *data16; - uint32_t *data32; - switch (pkt.size) { -/* case sizeof(uint64_t): - if (!pkt.data) { - data64 = new uint64_t; - pkt.data = (uint8_t*)data64; - } else { - data64 = (uint64_t*)pkt.data; - } - if (devices[device][func] == NULL) - *data64 = 0xFFFFFFFFFFFFFFFFULL; - else - devices[device][func]->readConfig(reg, req.size, data64); - break;*/ case sizeof(uint32_t): - if (!pkt.data) { - data32 = new uint32_t; - pkt.data = (uint8_t*)data32; - } else { - data32 = (uint32_t*)pkt.data; - } if (devices[device][func] == NULL) - *data32 = 0xFFFFFFFF; + pkt.set<uint32_t>(0xFFFFFFFF); else - ;//devices[device][func]->readConfig(reg, req.size, data32); + devices[device][func]->readConfig(reg, pkt.getPtr<uint32_t>()); break; case sizeof(uint16_t): - if (!pkt.data) { - data16 = new uint16_t; - pkt.data = (uint8_t*)data16; - } else { - data16 = (uint16_t*)pkt.data; - } if (devices[device][func] == NULL) - *data16 = 0xFFFF; + pkt.set<uint16_t>(0xFFFF); else - ;//devices[device][func]->readConfig(reg, req.size, data16); + devices[device][func]->readConfig(reg, pkt.getPtr<uint16_t>()); break; case sizeof(uint8_t): - if (!pkt.data) { - data8 = new uint8_t; - pkt.data = data8; - } else { - data8 = (uint8_t*)pkt.data; - } if (devices[device][func] == NULL) - *data8 = 0xFF; + pkt.set<uint8_t>(0xFF); else - ;//devices[device][func]->readConfig(reg, req.size, data8); + devices[device][func]->readConfig(reg, pkt.getPtr<uint8_t>()); break; default: panic("invalid access size(?) for PCI configspace!\n"); @@ -177,16 +144,27 @@ PciConfigAll::write(Packet &pkt) int device = (daddr >> 11) & 0x1F; int func = (daddr >> 8) & 0x7; -// int reg = daddr & 0xFF; + int reg = daddr & 0xFF; if (devices[device][func] == NULL) panic("Attempting to write to config space on non-existant device\n"); DPRINTF(PciConfigAll, "write - va=%#x size=%d data=%#x\n", - pkt.addr, pkt.size, *(uint32_t*)pkt.data); - -// devices[device][func]->writeConfig(reg, req->size, data); + pkt.addr, pkt.size, pkt.get<uint32_t>()); + switch (pkt.size) { + case sizeof(uint8_t): + devices[device][func]->writeConfig(reg, pkt.get<uint8_t>()); + break; + case sizeof(uint16_t): + devices[device][func]->writeConfig(reg, pkt.get<uint16_t>()); + break; + case sizeof(uint32_t): + devices[device][func]->writeConfig(reg, pkt.get<uint32_t>()); + break; + default: + panic("invalid pci config write size\n"); + } return pioDelay; } diff --git a/dev/pciconfigall.hh b/dev/pciconfigall.hh index b2034594c..2393b445e 100644 --- a/dev/pciconfigall.hh +++ b/dev/pciconfigall.hh @@ -54,8 +54,6 @@ class PciDev; class PciConfigAll : public BasicPioDevice { private: - static const Addr size = 0xffffff; - /** * Pointers to all the devices that are registered with this * particular config space. diff --git a/dev/pcidev.cc b/dev/pcidev.cc index a05ee3803..c40ef62e4 100644 --- a/dev/pcidev.cc +++ b/dev/pcidev.cc @@ -39,20 +39,20 @@ #include "base/misc.hh" #include "base/str.hh" // for to_number #include "base/trace.hh" -#include "dev/pcidev.hh" #include "dev/pciconfigall.hh" -#include "mem/bus/bus.hh" -#include "mem/functional/memory_control.hh" +#include "dev/pcidev.hh" +#include "dev/tsunamireg.h" +#include "mem/packet.hh" #include "sim/builder.hh" +#include "sim/byteswap.hh" #include "sim/param.hh" #include "sim/root.hh" -#include "dev/tsunamireg.h" using namespace std; PciDev::PciDev(Params *p) - : DmaDevice(p->name, p->plat), _params(p), plat(p->plat), - configData(p->configData) + : DmaDevice(p), plat(p->platform), configData(p->configData), + pioDelay(p->pio_delay) { // copy the config data from the PciConfigData object if (configData) { @@ -70,214 +70,180 @@ PciDev::PciDev(Params *p) p->configSpace->registerDevice(p->deviceNum, p->functionNum, this); } -Fault -PciDev::read(MemReqPtr &req, uint8_t *data) -{ return NoFault; } - -Fault -PciDev::write(MemReqPtr &req, const uint8_t *data) -{ return NoFault; } - -Fault -PciDev::readBar0(MemReqPtr &req, Addr daddr, uint8_t *data) -{ panic("not implemented"); } - -Fault -PciDev::readBar1(MemReqPtr &req, Addr daddr, uint8_t *data) -{ panic("not implemented"); } +void +PciDev::readConfig(int offset, uint8_t *data) +{ + if (offset >= PCI_DEVICE_SPECIFIC) + panic("Device specific PCI config space not implemented!\n"); -Fault -PciDev::readBar2(MemReqPtr &req, Addr daddr, uint8_t *data) -{ panic("not implemented"); } + *data = config.data[offset]; -Fault -PciDev::readBar3(MemReqPtr &req, Addr daddr, uint8_t *data) -{ panic("not implemented"); } + DPRINTF(PCIDEV, + "read device: %#x function: %#x register: %#x 1 bytes: data: %#x\n", + params()->deviceNum, params()->functionNum, offset, *data); +} -Fault -PciDev::readBar4(MemReqPtr &req, Addr daddr, uint8_t *data) -{ panic("not implemented"); } +void +PciDev::addressRanges(AddrRangeList &range_list) +{ + int x = 0; + range_list.clear(); + for (x = 0; x < 6; x++) + if (BARAddrs[x] != 0) + range_list.push_back(RangeSize(BARAddrs[x],BARSize[x])); +} -Fault -PciDev::readBar5(MemReqPtr &req, Addr daddr, uint8_t *data) -{ panic("not implemented"); } +void +PciDev::readConfig(int offset, uint16_t *data) +{ + if (offset >= PCI_DEVICE_SPECIFIC) + panic("Device specific PCI config space not implemented!\n"); -Fault -PciDev::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data) -{ panic("not implemented"); } + *data = *(uint16_t*)&config.data[offset]; -Fault -PciDev::writeBar1(MemReqPtr &req, Addr daddr, const uint8_t *data) -{ panic("not implemented"); } + DPRINTF(PCIDEV, + "read device: %#x function: %#x register: %#x 2 bytes: data: %#x\n", + params()->deviceNum, params()->functionNum, offset, *data); +} -Fault -PciDev::writeBar2(MemReqPtr &req, Addr daddr, const uint8_t *data) -{ panic("not implemented"); } +void +PciDev::readConfig(int offset, uint32_t *data) +{ + if (offset >= PCI_DEVICE_SPECIFIC) + panic("Device specific PCI config space not implemented!\n"); -Fault -PciDev::writeBar3(MemReqPtr &req, Addr daddr, const uint8_t *data) -{ panic("not implemented"); } + *data = *(uint32_t*)&config.data[offset]; -Fault -PciDev::writeBar4(MemReqPtr &req, Addr daddr, const uint8_t *data) -{ panic("not implemented"); } + DPRINTF(PCIDEV, + "read device: %#x function: %#x register: %#x 4 bytes: data: %#x\n", + params()->deviceNum, params()->functionNum, offset, *data); +} -Fault -PciDev::writeBar5(MemReqPtr &req, Addr daddr, const uint8_t *data) -{ panic("not implemented"); } void -PciDev::readConfig(int offset, int size, uint8_t *data) +PciDev::writeConfig(int offset, const uint8_t data) { if (offset >= PCI_DEVICE_SPECIFIC) panic("Device specific PCI config space not implemented!\n"); - switch(size) { - case sizeof(uint8_t): - *data = config.data[offset]; - break; - case sizeof(uint16_t): - *(uint16_t*)data = *(uint16_t*)&config.data[offset]; + DPRINTF(PCIDEV, + "write device: %#x function: %#x reg: %#x size: 1 data: %#x\n", + params()->deviceNum, params()->functionNum, offset, data); + + switch (offset) { + case PCI0_INTERRUPT_LINE: + config.interruptLine = data; + case PCI_CACHE_LINE_SIZE: + config.cacheLineSize = data; + case PCI_LATENCY_TIMER: + config.latencyTimer = data; break; - case sizeof(uint32_t): - *(uint32_t*)data = *(uint32_t*)&config.data[offset]; + /* Do nothing for these read-only registers */ + case PCI0_INTERRUPT_PIN: + case PCI0_MINIMUM_GRANT: + case PCI0_MAXIMUM_LATENCY: + case PCI_CLASS_CODE: + case PCI_REVISION_ID: break; default: - panic("Invalid PCI configuration read size!\n"); + panic("writing to a read only register"); } - - DPRINTF(PCIDEV, - "read device: %#x function: %#x register: %#x %d bytes: data: %#x\n", - params()->deviceNum, params()->functionNum, offset, size, - *(uint32_t*)data); } void -PciDev::writeConfig(int offset, int size, const uint8_t *data) +PciDev::writeConfig(int offset, const uint16_t data) { if (offset >= PCI_DEVICE_SPECIFIC) panic("Device specific PCI config space not implemented!\n"); - uint8_t &data8 = *(uint8_t*)data; - uint16_t &data16 = *(uint16_t*)data; - uint32_t &data32 = *(uint32_t*)data; - DPRINTF(PCIDEV, - "write device: %#x function: %#x reg: %#x size: %d data: %#x\n", - params()->deviceNum, params()->functionNum, offset, size, data32); - - switch (size) { - case sizeof(uint8_t): // 1-byte access - switch (offset) { - case PCI0_INTERRUPT_LINE: - config.interruptLine = data8; - case PCI_CACHE_LINE_SIZE: - config.cacheLineSize = data8; - case PCI_LATENCY_TIMER: - config.latencyTimer = data8; - break; - /* Do nothing for these read-only registers */ - case PCI0_INTERRUPT_PIN: - case PCI0_MINIMUM_GRANT: - case PCI0_MAXIMUM_LATENCY: - case PCI_CLASS_CODE: - case PCI_REVISION_ID: - break; - default: - panic("writing to a read only register"); - } + "write device: %#x function: %#x reg: %#x size: 2 data: %#x\n", + params()->deviceNum, params()->functionNum, offset, data); + + switch (offset) { + case PCI_COMMAND: + config.command = data; + case PCI_STATUS: + config.status = data; + case PCI_CACHE_LINE_SIZE: + config.cacheLineSize = data; break; + default: + panic("writing to a read only register"); + } +} - case sizeof(uint16_t): // 2-byte access - switch (offset) { - case PCI_COMMAND: - config.command = data16; - case PCI_STATUS: - config.status = data16; - case PCI_CACHE_LINE_SIZE: - config.cacheLineSize = data16; - break; - default: - panic("writing to a read only register"); - } - break; - case sizeof(uint32_t): // 4-byte access - switch (offset) { - case PCI0_BASE_ADDR0: - case PCI0_BASE_ADDR1: - case PCI0_BASE_ADDR2: - case PCI0_BASE_ADDR3: - case PCI0_BASE_ADDR4: - case PCI0_BASE_ADDR5: - - uint32_t barnum, bar_mask; - Addr base_addr, base_size, space_base; - - barnum = BAR_NUMBER(offset); - - if (BAR_IO_SPACE(letoh(config.baseAddr[barnum]))) { - bar_mask = BAR_IO_MASK; - space_base = TSUNAMI_PCI0_IO; - } else { - bar_mask = BAR_MEM_MASK; - space_base = TSUNAMI_PCI0_MEMORY; - } +void +PciDev::writeConfig(int offset, const uint32_t data) +{ + if (offset >= PCI_DEVICE_SPECIFIC) + panic("Device specific PCI config space not implemented!\n"); - // Writing 0xffffffff to a BAR tells the card to set the - // value of the bar to size of memory it needs - if (letoh(data32) == 0xffffffff) { - // This is I/O Space, bottom two bits are read only + DPRINTF(PCIDEV, + "write device: %#x function: %#x reg: %#x size: 4 data: %#x\n", + params()->deviceNum, params()->functionNum, offset, data); + + switch (offset) { + case PCI0_BASE_ADDR0: + case PCI0_BASE_ADDR1: + case PCI0_BASE_ADDR2: + case PCI0_BASE_ADDR3: + case PCI0_BASE_ADDR4: + case PCI0_BASE_ADDR5: + + uint32_t barnum, bar_mask; + Addr base_addr, base_size, space_base; + + barnum = BAR_NUMBER(offset); + + if (BAR_IO_SPACE(letoh(config.baseAddr[barnum]))) { + bar_mask = BAR_IO_MASK; + space_base = TSUNAMI_PCI0_IO; + } else { + bar_mask = BAR_MEM_MASK; + space_base = TSUNAMI_PCI0_MEMORY; + } - config.baseAddr[barnum] = letoh( - (~(BARSize[barnum] - 1) & ~bar_mask) | - (letoh(config.baseAddr[barnum]) & bar_mask)); - } else { - MemoryController *mmu = params()->mmu; + // Writing 0xffffffff to a BAR tells the card to set the + // value of the bar to size of memory it needs + if (letoh(data) == 0xffffffff) { + // This is I/O Space, bottom two bits are read only - config.baseAddr[barnum] = letoh( - (letoh(data32) & ~bar_mask) | + config.baseAddr[barnum] = letoh( + (~(BARSize[barnum] - 1) & ~bar_mask) | (letoh(config.baseAddr[barnum]) & bar_mask)); + } else { + config.baseAddr[barnum] = letoh( + (letoh(data) & ~bar_mask) | + (letoh(config.baseAddr[barnum]) & bar_mask)); + + if (letoh(config.baseAddr[barnum]) & ~bar_mask) { + base_addr = (letoh(data) & ~bar_mask) + space_base; + base_size = BARSize[barnum]; + BARAddrs[barnum] = base_addr; - if (letoh(config.baseAddr[barnum]) & ~bar_mask) { - base_addr = (letoh(data32) & ~bar_mask) + space_base; - base_size = BARSize[barnum]; - - // It's never been set - if (BARAddrs[barnum] == 0) - mmu->add_child((FunctionalMemory *)this, - RangeSize(base_addr, base_size)); - else - mmu->update_child((FunctionalMemory *)this, - RangeSize(BARAddrs[barnum], base_size), - RangeSize(base_addr, base_size)); - - BARAddrs[barnum] = base_addr; - } + pioPort->sendStatusChange(Port::RangeChange); } - break; - - case PCI0_ROM_BASE_ADDR: - if (letoh(data32) == 0xfffffffe) - config.expansionROM = htole((uint32_t)0xffffffff); - else - config.expansionROM = data32; - break; - - case PCI_COMMAND: - // This could also clear some of the error bits in the Status - // register. However they should never get set, so lets ignore - // it for now - config.command = data16; - break; - - default: - DPRINTF(PCIDEV, "Writing to a read only register"); } break; + case PCI0_ROM_BASE_ADDR: + if (letoh(data) == 0xfffffffe) + config.expansionROM = htole((uint32_t)0xffffffff); + else + config.expansionROM = data; + break; + + case PCI_COMMAND: + // This could also clear some of the error bits in the Status + // register. However they should never get set, so lets ignore + // it for now + config.command = data; + break; + default: - panic("invalid access size"); + DPRINTF(PCIDEV, "Writing to a read only register"); } } @@ -296,12 +262,6 @@ PciDev::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_ARRAY(BARAddrs, sizeof(BARAddrs) / sizeof(BARAddrs[0])); UNSERIALIZE_ARRAY(config.data, sizeof(config.data) / sizeof(config.data[0])); - - // Add the MMU mappings for the BARs - for (int i=0; i < 6; i++) { - if (BARAddrs[i] != 0) - params()->mmu->add_child(this, RangeSize(BARAddrs[i], BARSize[i])); - } } #ifndef DOXYGEN_SHOULD_SKIP_THIS diff --git a/dev/pcidev.hh b/dev/pcidev.hh index bdfc6b932..fc4773908 100644 --- a/dev/pcidev.hh +++ b/dev/pcidev.hh @@ -44,7 +44,6 @@ #define BAR_NUMBER(x) (((x) - PCI0_BASE_ADDR0) >> 0x2); class PciConfigAll; -class MemoryController; /** @@ -85,12 +84,8 @@ class PciConfigData : public SimObject class PciDev : public DmaDevice { public: - struct Params + struct Params : public ::PioDevice::Params { - std::string name; - Platform *plat; - MemoryController *mmu; - /** * A pointer to the configspace all object that calls us when * a read comes to this particular device/function. @@ -111,13 +106,13 @@ class PciDev : public DmaDevice /** The function number */ uint32_t functionNum; - }; - protected: - Params *_params; + /** The latency for pio accesses. */ + Tick pio_delay; + }; public: - const Params *params() const { return _params; } + const Params *params() const { return (const Params *)_params; } protected: /** The current config space. Unlike the PciConfigData this is @@ -164,6 +159,7 @@ class PciDev : public DmaDevice protected: Platform *plat; PciConfigData *configData; + Tick pioDelay; public: Addr pciToDma(Addr pciAddr) const @@ -181,7 +177,11 @@ class PciDev : public DmaDevice interruptLine() { return configData->config.interruptLine; } - public: + /** return the address ranges that this device responds to. + * @params range_list range list to populate with ranges + */ + void addressRanges(AddrRangeList &range_list); + /** * Constructor for PCI Dev. This function copies data from the * config file object PCIConfigData and registers the device with @@ -189,39 +189,6 @@ class PciDev : public DmaDevice */ PciDev(Params *params); - virtual Fault read(MemReqPtr &req, uint8_t *data); - virtual Fault write(MemReqPtr &req, const uint8_t *data); - - public: - /** - * Implement the read/write as BAR accesses - */ - Fault readBar(MemReqPtr &req, uint8_t *data); - Fault writeBar(MemReqPtr &req, const uint8_t *data); - - public: - /** - * Read from a specific BAR - */ - virtual Fault readBar0(MemReqPtr &req, Addr daddr, uint8_t *data); - virtual Fault readBar1(MemReqPtr &req, Addr daddr, uint8_t *data); - virtual Fault readBar2(MemReqPtr &req, Addr daddr, uint8_t *data); - virtual Fault readBar3(MemReqPtr &req, Addr daddr, uint8_t *data); - virtual Fault readBar4(MemReqPtr &req, Addr daddr, uint8_t *data); - virtual Fault readBar5(MemReqPtr &req, Addr daddr, uint8_t *data); - - public: - /** - * Write to a specific BAR - */ - virtual Fault writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data); - virtual Fault writeBar1(MemReqPtr &req, Addr daddr, const uint8_t *data); - virtual Fault writeBar2(MemReqPtr &req, Addr daddr, const uint8_t *data); - virtual Fault writeBar3(MemReqPtr &req, Addr daddr, const uint8_t *data); - virtual Fault writeBar4(MemReqPtr &req, Addr daddr, const uint8_t *data); - virtual Fault writeBar5(MemReqPtr &req, Addr daddr, const uint8_t *data); - - public: /** * Write to the PCI config space data that is stored locally. This may be * overridden by the device but at some point it will eventually call this @@ -230,7 +197,9 @@ class PciDev : public DmaDevice * @param size the size of the write * @param data the data to write */ - virtual void writeConfig(int offset, int size, const uint8_t* data); + virtual void writeConfig(int offset, const uint8_t data); + virtual void writeConfig(int offset, const uint16_t data); + virtual void writeConfig(int offset, const uint32_t data); /** @@ -241,7 +210,9 @@ class PciDev : public DmaDevice * @param size the size of the read * @param data pointer to the location where the read value should be stored */ - virtual void readConfig(int offset, int size, uint8_t *data); + virtual void readConfig(int offset, uint8_t *data); + virtual void readConfig(int offset, uint16_t *data); + virtual void readConfig(int offset, uint32_t *data); /** * Serialize this object to the given output stream. @@ -256,43 +227,4 @@ class PciDev : public DmaDevice */ virtual void unserialize(Checkpoint *cp, const std::string §ion); }; - -inline Fault -PciDev::readBar(MemReqPtr &req, uint8_t *data) -{ - using namespace TheISA; - if (isBAR(req->paddr, 0)) - return readBar0(req, req->paddr - BARAddrs[0], data); - if (isBAR(req->paddr, 1)) - return readBar1(req, req->paddr - BARAddrs[1], data); - if (isBAR(req->paddr, 2)) - return readBar2(req, req->paddr - BARAddrs[2], data); - if (isBAR(req->paddr, 3)) - return readBar3(req, req->paddr - BARAddrs[3], data); - if (isBAR(req->paddr, 4)) - return readBar4(req, req->paddr - BARAddrs[4], data); - if (isBAR(req->paddr, 5)) - return readBar5(req, req->paddr - BARAddrs[5], data); - return genMachineCheckFault(); -} - -inline Fault -PciDev::writeBar(MemReqPtr &req, const uint8_t *data) -{ - using namespace TheISA; - if (isBAR(req->paddr, 0)) - return writeBar0(req, req->paddr - BARAddrs[0], data); - if (isBAR(req->paddr, 1)) - return writeBar1(req, req->paddr - BARAddrs[1], data); - if (isBAR(req->paddr, 2)) - return writeBar2(req, req->paddr - BARAddrs[2], data); - if (isBAR(req->paddr, 3)) - return writeBar3(req, req->paddr - BARAddrs[3], data); - if (isBAR(req->paddr, 4)) - return writeBar4(req, req->paddr - BARAddrs[4], data); - if (isBAR(req->paddr, 5)) - return writeBar5(req, req->paddr - BARAddrs[5], data); - return genMachineCheckFault(); -} - #endif // __DEV_PCIDEV_HH__ diff --git a/dev/pktfifo.cc b/dev/pktfifo.cc index 639009be9..922a66912 100644 --- a/dev/pktfifo.cc +++ b/dev/pktfifo.cc @@ -38,8 +38,8 @@ PacketFifo::copyout(void *dest, int offset, int len) if (offset + len >= size()) return false; - list<PacketPtr>::iterator p = fifo.begin(); - list<PacketPtr>::iterator end = fifo.end(); + list<EthPacketPtr>::iterator p = fifo.begin(); + list<EthPacketPtr>::iterator end = fifo.end(); while (len > 0) { while (offset >= (*p)->length) { offset -= (*p)->length; @@ -70,8 +70,8 @@ PacketFifo::serialize(const string &base, ostream &os) paramOut(os, base + ".packets", fifo.size()); int i = 0; - list<PacketPtr>::iterator p = fifo.begin(); - list<PacketPtr>::iterator end = fifo.end(); + list<EthPacketPtr>::iterator p = fifo.begin(); + list<EthPacketPtr>::iterator end = fifo.end(); while (p != end) { (*p)->serialize(csprintf("%s.packet%d", base, i), os); ++p; @@ -92,7 +92,7 @@ PacketFifo::unserialize(const string &base, Checkpoint *cp, fifo.clear(); for (int i = 0; i < fifosize; ++i) { - PacketPtr p = new PacketData(16384); + EthPacketPtr p = new EthPacketData(16384); p->unserialize(csprintf("%s.packet%d", base, i), cp, section); fifo.push_back(p); } diff --git a/dev/pktfifo.hh b/dev/pktfifo.hh index e245840a8..336da22d8 100644 --- a/dev/pktfifo.hh +++ b/dev/pktfifo.hh @@ -40,11 +40,11 @@ class Checkpoint; class PacketFifo { public: - typedef std::list<PacketPtr> fifo_list; + typedef std::list<EthPacketPtr> fifo_list; typedef fifo_list::iterator iterator; protected: - std::list<PacketPtr> fifo; + std::list<EthPacketPtr> fifo; int _maxsize; int _size; int _reserved; @@ -71,9 +71,9 @@ class PacketFifo iterator begin() { return fifo.begin(); } iterator end() { return fifo.end(); } - PacketPtr front() { return fifo.front(); } + EthPacketPtr front() { return fifo.front(); } - bool push(PacketPtr ptr) + bool push(EthPacketPtr ptr) { assert(ptr->length); assert(_reserved <= ptr->length); @@ -92,7 +92,7 @@ class PacketFifo if (empty()) return; - PacketPtr &packet = fifo.front(); + EthPacketPtr &packet = fifo.front(); _size -= packet->length; _size -= packet->slack; packet->slack = 0; @@ -111,7 +111,7 @@ class PacketFifo void remove(iterator i) { - PacketPtr &packet = *i; + EthPacketPtr &packet = *i; if (i != fifo.begin()) { iterator prev = i; --prev; diff --git a/dev/sinic.cc b/dev/sinic.cc index 363994919..b91ef83b0 100644 --- a/dev/sinic.cc +++ b/dev/sinic.cc @@ -28,6 +28,7 @@ #include <cstdio> #include <deque> +#include <limits> #include <string> #include "base/inet.hh" @@ -36,12 +37,7 @@ #include "dev/etherlink.hh" #include "dev/sinic.hh" #include "dev/pciconfigall.hh" -#include "mem/bus/bus.hh" -#include "mem/bus/dma_interface.hh" -#include "mem/bus/pio_interface.hh" -#include "mem/bus/pio_interface_impl.hh" -#include "mem/functional/memory_control.hh" -#include "mem/functional/physical.hh" +#include "mem/packet.hh" #include "sim/builder.hh" #include "sim/debug.hh" #include "sim/eventq.hh" @@ -85,8 +81,7 @@ Base::Base(Params *p) } Device::Device(Params *p) - : Base(p), plat(p->plat), physmem(p->physmem), - rxFifo(p->rx_fifo_size), txFifo(p->tx_fifo_size), + : Base(p), rxFifo(p->rx_fifo_size), txFifo(p->tx_fifo_size), rxKickTick(0), txKickTick(0), txEvent(this), rxDmaEvent(this), txDmaEvent(this), dmaReadDelay(p->dma_read_delay), dmaReadFactor(p->dma_read_factor), @@ -94,25 +89,6 @@ Device::Device(Params *p) { reset(); - if (p->pio_bus) { - pioInterface = newPioInterface(p->name + ".pio", p->hier, p->pio_bus, - this, &Device::cacheAccess); - pioLatency = p->pio_latency * p->pio_bus->clockRate; - } - - if (p->header_bus) { - if (p->payload_bus) - dmaInterface = new DMAInterface<Bus>(p->name + ".dma", - p->header_bus, - p->payload_bus, 1, - p->dma_no_allocate); - else - dmaInterface = new DMAInterface<Bus>(p->name + ".dma", - p->header_bus, - p->header_bus, 1, - p->dma_no_allocate); - } else if (p->payload_bus) - panic("must define a header bus if defining a payload bus"); } Device::~Device() @@ -288,29 +264,6 @@ Device::regStats() rxPacketRate = rxPackets / simSeconds; } -/** - * This is to write to the PCI general configuration registers - */ -void -Device::writeConfig(int offset, int size, const uint8_t *data) -{ - switch (offset) { - case PCI0_BASE_ADDR0: - // Need to catch writes to BARs to update the PIO interface - PciDev::writeConfig(offset, size, data); - if (BARAddrs[0] != 0) { - if (pioInterface) - pioInterface->addAddrRange(RangeSize(BARAddrs[0], BARSize[0])); - - BARAddrs[0] &= EV5::PAddrUncachedMask; - } - break; - - default: - PciDev::writeConfig(offset, size, data); - } -} - void Device::prepareIO(int cpu, int index) { @@ -357,73 +310,64 @@ Device::prepareWrite(int cpu, int index) /** * I/O read of device register */ -Fault -Device::read(MemReqPtr &req, uint8_t *data) +Tick +Device::read(Packet &pkt) { assert(config.command & PCI_CMD_MSE); - Fault fault = readBar(req, data); - - if (fault->isMachineCheckFault()) { - panic("address does not map to a BAR pa=%#x va=%#x size=%d", - req->paddr, req->vaddr, req->size); - - return genMachineCheckFault(); - } + assert(pkt.addr >= BARAddrs[0] && pkt.size < BARSize[0]); - return fault; -} - -Fault -Device::readBar0(MemReqPtr &req, Addr daddr, uint8_t *data) -{ - int cpu = (req->xc->readMiscReg(TheISA::IPR_PALtemp16) >> 8) & 0xff; + int cpu = pkt.req->getCpuNum(); + Addr daddr = pkt.addr - BARAddrs[0]; Addr index = daddr >> Regs::VirtualShift; Addr raddr = daddr & Regs::VirtualMask; + pkt.time = curTick + pioDelay; + pkt.allocate(); + if (!regValid(raddr)) - panic("invalid register: cpu=%d, da=%#x pa=%#x va=%#x size=%d", - cpu, daddr, req->paddr, req->vaddr, req->size); + panic("invalid register: cpu=%d, da=%#x pa=%#x size=%d", + cpu, 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 va=%#x size=%d", - info.name, cpu, daddr, req->paddr, req->vaddr, req->size); + panic("reading %s (write only): cpu=%d da=%#x pa=%#x size=%d", + info.name, cpu, daddr, pkt.addr, pkt.size); - if (req->size != info.size) - panic("invalid size for reg %s: cpu=%d da=%#x pa=%#x va=%#x size=%d", - info.name, cpu, daddr, req->paddr, req->vaddr, req->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); prepareRead(cpu, index); uint64_t value = 0; - if (req->size == 4) { - uint32_t ® = *(uint32_t *)data; - reg = regData32(raddr); + if (pkt.size == 4) { + uint32_t reg = regData32(raddr); + pkt.set(reg); value = reg; } - if (req->size == 8) { - uint64_t ® = *(uint64_t *)data; - reg = regData64(raddr); + if (pkt.size == 8) { + uint64_t reg = regData64(raddr); + pkt.set(reg); value = reg; } DPRINTF(EthernetPIO, - "read %s cpu=%d da=%#x pa=%#x va=%#x size=%d val=%#x\n", - info.name, cpu, daddr, req->paddr, req->vaddr, req->size, value); + "read %s cpu=%d da=%#x pa=%#x size=%d val=%#x\n", + info.name, cpu, daddr, pkt.addr, pkt.size, value); // reading the interrupt status register has the side effect of // clearing it if (raddr == Regs::IntrStatus) devIntrClear(); - return NoFault; + return pioDelay; } /** * IPR read of device register - */ -Fault + + Fault Device::iprRead(Addr daddr, int cpu, uint64_t &result) { if (!regValid(daddr)) @@ -449,72 +393,60 @@ Device::iprRead(Addr daddr, int cpu, uint64_t &result) return NoFault; } - +*/ /** * I/O write of device register */ -Fault -Device::write(MemReqPtr &req, const uint8_t *data) +Tick +Device::write(Packet &pkt) { assert(config.command & PCI_CMD_MSE); - Fault fault = writeBar(req, data); - - if (fault->isMachineCheckFault()) { - panic("address does not map to a BAR pa=%#x va=%#x size=%d", - req->paddr, req->vaddr, req->size); + assert(pkt.addr >= BARAddrs[0] && pkt.size < BARSize[0]); - return genMachineCheckFault(); - } - - return fault; -} - -Fault -Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data) -{ - int cpu = (req->xc->readMiscReg(TheISA::IPR_PALtemp16) >> 8) & 0xff; + int cpu = pkt.req->getCpuNum(); + Addr daddr = pkt.addr - BARAddrs[0]; Addr index = daddr >> Regs::VirtualShift; Addr raddr = daddr & Regs::VirtualMask; + pkt.time = curTick + pioDelay; + if (!regValid(raddr)) - panic("invalid address: cpu=%d da=%#x pa=%#x va=%#x size=%d", - cpu, daddr, req->paddr, req->vaddr, req->size); + panic("invalid register: cpu=%d, da=%#x pa=%#x size=%d", + cpu, daddr, pkt.addr, pkt.size); const Regs::Info &info = regInfo(raddr); if (!info.write) - panic("writing %s (read only): cpu=%d da=%#x", - info.name, cpu, daddr); + panic("write %s (read only): cpu=%d da=%#x pa=%#x size=%d", + info.name, cpu, daddr, pkt.addr, pkt.size); - if (req->size != info.size) - panic("invalid size for %s: cpu=%d da=%#x pa=%#x va=%#x size=%d", - info.name, cpu, daddr, req->paddr, req->vaddr, req->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); - uint32_t reg32 = *(uint32_t *)data; - uint64_t reg64 = *(uint64_t *)data; VirtualReg &vnic = virtualRegs[index]; DPRINTF(EthernetPIO, - "write %s: cpu=%d val=%#x da=%#x pa=%#x va=%#x size=%d\n", - info.name, cpu, info.size == 4 ? reg32 : reg64, - daddr, req->paddr, req->vaddr, req->size); + "write %s: cpu=%d val=%#x da=%#x pa=%#x size=%d\n", + info.name, cpu, info.size == 4 ? pkt.get<uint32_t>() : + pkt.get<uint64_t>(), daddr, pkt.addr, pkt.size); prepareWrite(cpu, index); switch (raddr) { case Regs::Config: - changeConfig(reg32); + changeConfig(pkt.get<uint32_t>()); break; case Regs::Command: - command(reg32); + command(pkt.get<uint32_t>()); break; case Regs::IntrStatus: - devIntrClear(regs.IntrStatus & reg32); + devIntrClear(regs.IntrStatus & pkt.get<uint32_t>()); break; case Regs::IntrMask: - devIntrChangeMask(reg32); + devIntrChangeMask(pkt.get<uint32_t>()); break; case Regs::RxData: @@ -523,7 +455,7 @@ Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data) RxStateStrings[rxState]); vnic.RxDone = Regs::RxDone_Busy; - vnic.RxData = reg64; + vnic.RxData = pkt.get<uint64_t>(); rxList.push_back(index); if (rxEnable && rxState == rxIdle) { rxState = rxFifoBlock; @@ -537,7 +469,7 @@ Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data) TxStateStrings[txState]); vnic.TxDone = Regs::TxDone_Busy; - vnic.TxData = reg64; + vnic.TxData = pkt.get<uint64_t>(); if (txList.empty() || txList.front() != index) txList.push_back(index); if (txEnable && txState == txIdle && txList.front() == index) { @@ -547,7 +479,7 @@ Device::writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data) break; } - return NoFault; + return pioDelay; } void @@ -793,20 +725,13 @@ Device::reset() } void -Device::rxDmaCopy() +Device::rxDmaDone() { assert(rxState == rxCopy); rxState = rxCopyDone; - physmem->dma_write(rxDmaAddr, (uint8_t *)rxDmaData, rxDmaLen); DPRINTF(EthernetDMA, "rx dma write paddr=%#x len=%d\n", rxDmaAddr, rxDmaLen); DDUMP(EthernetData, rxDmaData, rxDmaLen); -} - -void -Device::rxDmaDone() -{ - rxDmaCopy(); // If the transmit state machine has a pending DMA, let it go first if (txState == txBeginCopy) @@ -892,29 +817,17 @@ Device::rxKick() break; case rxBeginCopy: - if (dmaInterface && dmaInterface->busy()) + if (dmaPending()) goto exit; - rxDmaAddr = plat->pciToDma(Regs::get_RxData_Addr(vnic->RxData)); - rxDmaLen = min<int>(Regs::get_RxData_Len(vnic->RxData), + rxDmaAddr = params()->platform->pciToDma( + Regs::get_RxData_Addr(vnic->RxData)); + rxDmaLen = std::min<int>(Regs::get_RxData_Len(vnic->RxData), vnic->rxPacketBytes); rxDmaData = (*vnic->rxPacket)->data + vnic->rxPacketOffset; rxState = rxCopy; - if (dmaInterface) { - dmaInterface->doDMA(WriteInvalidate, rxDmaAddr, rxDmaLen, - curTick, &rxDmaEvent, true); - goto exit; - } - - if (dmaWriteDelay != 0 || dmaWriteFactor != 0) { - Tick factor = ((rxDmaLen + ULL(63)) >> ULL(6)) * dmaWriteFactor; - Tick start = curTick + dmaWriteDelay + factor; - rxDmaEvent.schedule(start); - goto exit; - } - - rxDmaCopy(); + dmaWrite(rxDmaAddr, rxDmaLen, &rxDmaEvent, rxDmaData); break; case rxCopy: @@ -968,20 +881,13 @@ Device::rxKick() } void -Device::txDmaCopy() +Device::txDmaDone() { assert(txState == txCopy); txState = txCopyDone; - physmem->dma_read((uint8_t *)txDmaData, txDmaAddr, txDmaLen); DPRINTF(EthernetDMA, "tx dma read paddr=%#x len=%d\n", txDmaAddr, txDmaLen); DDUMP(EthernetData, txDmaData, txDmaLen); -} - -void -Device::txDmaDone() -{ - txDmaCopy(); // If the receive state machine has a pending DMA, let it go first if (rxState == rxBeginCopy) @@ -999,7 +905,7 @@ Device::transmit() } uint32_t interrupts; - PacketPtr packet = txFifo.front(); + EthPacketPtr packet = txFifo.front(); if (!interface->sendPacket(packet)) { DPRINTF(Ethernet, "Packet Transmit: failed txFifo available %d\n", txFifo.avail()); @@ -1065,7 +971,7 @@ Device::txKick() assert(Regs::get_TxDone_Busy(vnic->TxData)); if (!txPacket) { // Grab a new packet from the fifo. - txPacket = new PacketData(16384); + txPacket = new EthPacketData(16384); txPacketOffset = 0; } @@ -1079,28 +985,16 @@ Device::txKick() break; case txBeginCopy: - if (dmaInterface && dmaInterface->busy()) + if (dmaPending()) goto exit; - txDmaAddr = plat->pciToDma(Regs::get_TxData_Addr(vnic->TxData)); + txDmaAddr = params()->platform->pciToDma( + Regs::get_TxData_Addr(vnic->TxData)); txDmaLen = Regs::get_TxData_Len(vnic->TxData); txDmaData = txPacket->data + txPacketOffset; txState = txCopy; - if (dmaInterface) { - dmaInterface->doDMA(Read, txDmaAddr, txDmaLen, - curTick, &txDmaEvent, true); - goto exit; - } - - if (dmaReadDelay != 0 || dmaReadFactor != 0) { - Tick factor = ((txDmaLen + ULL(63)) >> ULL(6)) * dmaReadFactor; - Tick start = curTick + dmaReadDelay + factor; - txDmaEvent.schedule(start); - goto exit; - } - - txDmaCopy(); + dmaRead(txDmaAddr, txDmaLen, &txDmaEvent, txDmaData); break; case txCopy: @@ -1187,7 +1081,7 @@ Device::transferDone() } bool -Device::rxFilter(const PacketPtr &packet) +Device::rxFilter(const EthPacketPtr &packet) { if (!Regs::get_Config_Filter(regs.Config)) return false; @@ -1232,7 +1126,7 @@ Device::rxFilter(const PacketPtr &packet) } bool -Device::recvPacket(PacketPtr packet) +Device::recvPacket(EthPacketPtr packet) { rxBytes += packet->length; rxPackets++; @@ -1273,7 +1167,7 @@ Device::recvPacket(PacketPtr packet) // // void -Base::serialize(ostream &os) +Base::serialize(std::ostream &os) { // Serialize the PciDev base class PciDev::serialize(os); @@ -1317,7 +1211,7 @@ Base::unserialize(Checkpoint *cp, const std::string §ion) } void -Device::serialize(ostream &os) +Device::serialize(std::ostream &os) { // Serialize the PciDev base class Base::serialize(os); @@ -1352,7 +1246,7 @@ Device::serialize(ostream &os) for (int i = 0; i < virtualRegsSize; ++i) { VirtualReg *vnic = &virtualRegs[i]; - string reg = csprintf("vnic%d", i); + std::string reg = csprintf("vnic%d", i); paramOut(os, reg + ".RxData", vnic->RxData); paramOut(os, reg + ".RxDone", vnic->RxDone); paramOut(os, reg + ".TxData", vnic->TxData); @@ -1481,7 +1375,7 @@ Device::unserialize(Checkpoint *cp, const std::string §ion) UNSERIALIZE_SCALAR(txPacketExists); txPacket = 0; if (txPacketExists) { - txPacket = new PacketData(16384); + txPacket = new EthPacketData(16384); txPacket->unserialize("txPacket", cp, section); UNSERIALIZE_SCALAR(txPacketOffset); UNSERIALIZE_SCALAR(txPacketBytes); @@ -1499,7 +1393,7 @@ Device::unserialize(Checkpoint *cp, const std::string §ion) virtualRegs.resize(virtualRegsSize); for (int i = 0; i < virtualRegsSize; ++i) { VirtualReg *vnic = &virtualRegs[i]; - string reg = csprintf("vnic%d", i); + std::string reg = csprintf("vnic%d", i); paramIn(cp, section, reg + ".RxData", vnic->RxData); paramIn(cp, section, reg + ".RxDone", vnic->RxDone); @@ -1532,30 +1426,11 @@ Device::unserialize(Checkpoint *cp, const std::string §ion) if (transmitTick) txEvent.schedule(curTick + transmitTick); - /* - * re-add addrRanges to bus bridges - */ - if (pioInterface) { - pioInterface->addAddrRange(RangeSize(BARAddrs[0], BARSize[0])); - pioInterface->addAddrRange(RangeSize(BARAddrs[1], BARSize[1])); - } -} - -Tick -Device::cacheAccess(MemReqPtr &req) -{ - Addr daddr; - int bar; - if (!getBAR(req->paddr, daddr, bar)) - panic("address does not map to a BAR pa=%#x va=%#x size=%d", - req->paddr, req->vaddr, req->size); + pioPort->sendStatusChange(Port::RangeChange); - DPRINTF(EthernetPIO, "timing %s to paddr=%#x bar=%d daddr=%#x\n", - req->cmd.toString(), req->paddr, bar, daddr); - - return curTick + pioLatency; } + BEGIN_DECLARE_SIM_OBJECT_PARAMS(Interface) SimObjectParam<EtherInt *> peer; @@ -1588,29 +1463,22 @@ REGISTER_SIM_OBJECT("SinicInt", Interface) BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device) - Param<Tick> clock; - Param<Addr> addr; - SimObjectParam<MemoryController *> mmu; - SimObjectParam<PhysicalMemory *> physmem; + SimObjectParam<System *> system; + SimObjectParam<Platform *> platform; SimObjectParam<PciConfigAll *> configspace; SimObjectParam<PciConfigData *> configdata; - SimObjectParam<Platform *> platform; Param<uint32_t> pci_bus; Param<uint32_t> pci_dev; Param<uint32_t> pci_func; + Param<Tick> pio_latency; + Param<Tick> intr_delay; - SimObjectParam<HierParams *> hier; - SimObjectParam<Bus*> pio_bus; - SimObjectParam<Bus*> dma_bus; - SimObjectParam<Bus*> payload_bus; + Param<Tick> clock; Param<Tick> dma_read_delay; Param<Tick> dma_read_factor; Param<Tick> dma_write_delay; Param<Tick> dma_write_factor; - Param<bool> dma_no_allocate; - Param<Tick> pio_latency; - Param<Tick> intr_delay; Param<Tick> rx_delay; Param<Tick> tx_delay; @@ -1623,7 +1491,7 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(Device) Param<uint32_t> tx_fifo_threshold; Param<bool> rx_filter; - Param<string> hardware_address; + Param<std::string> hardware_address; Param<bool> rx_thread; Param<bool> tx_thread; Param<bool> rss; @@ -1632,29 +1500,22 @@ END_DECLARE_SIM_OBJECT_PARAMS(Device) BEGIN_INIT_SIM_OBJECT_PARAMS(Device) - INIT_PARAM(clock, "State machine cycle time"), - INIT_PARAM(addr, "Device Address"), - INIT_PARAM(mmu, "Memory Controller"), - INIT_PARAM(physmem, "Physical Memory"), + INIT_PARAM(system, "System pointer"), + INIT_PARAM(platform, "Platform pointer"), INIT_PARAM(configspace, "PCI Configspace"), INIT_PARAM(configdata, "PCI Config data"), - INIT_PARAM(platform, "Platform"), - INIT_PARAM(pci_bus, "PCI bus"), + INIT_PARAM(pci_bus, "PCI bus ID"), INIT_PARAM(pci_dev, "PCI device number"), INIT_PARAM(pci_func, "PCI function code"), + INIT_PARAM_DFLT(pio_latency, "Programmed IO latency in bus cycles", 1), + INIT_PARAM(intr_delay, "Interrupt Delay"), + INIT_PARAM(clock, "State machine cycle time"), - INIT_PARAM(hier, "Hierarchy global variables"), - INIT_PARAM(pio_bus, ""), - INIT_PARAM(dma_bus, ""), - INIT_PARAM(payload_bus, "The IO Bus to attach to for payload"), INIT_PARAM(dma_read_delay, "fixed delay for dma reads"), INIT_PARAM(dma_read_factor, "multiplier for dma reads"), INIT_PARAM(dma_write_delay, "fixed delay for dma writes"), INIT_PARAM(dma_write_factor, "multiplier for dma writes"), - INIT_PARAM(dma_no_allocate, "Should we allocat on read in cache"), - INIT_PARAM(pio_latency, "Programmed IO latency in bus cycles"), - INIT_PARAM(intr_delay, "Interrupt Delay"), INIT_PARAM(rx_delay, "Receive Delay"), INIT_PARAM(tx_delay, "Transmit Delay"), @@ -1678,31 +1539,22 @@ END_INIT_SIM_OBJECT_PARAMS(Device) CREATE_SIM_OBJECT(Device) { Device::Params *params = new Device::Params; - params->name = getInstanceName(); - - params->clock = clock; - - params->mmu = mmu; - params->physmem = physmem; + params->platform = platform; + params->system = system; params->configSpace = configspace; params->configData = configdata; - params->plat = platform; params->busNum = pci_bus; params->deviceNum = pci_dev; params->functionNum = pci_func; + params->pio_delay = pio_latency; + params->intr_delay = intr_delay; + params->clock = clock; - params->hier = hier; - params->pio_bus = pio_bus; - params->header_bus = dma_bus; - params->payload_bus = payload_bus; params->dma_read_delay = dma_read_delay; params->dma_read_factor = dma_read_factor; params->dma_write_delay = dma_write_delay; params->dma_write_factor = dma_write_factor; - params->dma_no_allocate = dma_no_allocate; - params->pio_latency = pio_latency; - params->intr_delay = intr_delay; params->tx_delay = tx_delay; params->rx_delay = rx_delay; diff --git a/dev/sinic.hh b/dev/sinic.hh index 25172fa45..63a8585dc 100644 --- a/dev/sinic.hh +++ b/dev/sinic.hh @@ -37,7 +37,6 @@ #include "dev/pcidev.hh" #include "dev/pktfifo.hh" #include "dev/sinicreg.hh" -#include "mem/bus/bus.hh" #include "sim/eventq.hh" namespace Sinic { @@ -91,10 +90,6 @@ class Base : public PciDev class Device : public Base { protected: - Platform *plat; - PhysicalMemory *physmem; - - protected: /** Receive State Machine States */ enum RxState { rxIdle, @@ -162,10 +157,6 @@ class Device : public Base uint32_t ®Data32(Addr daddr) { return *(uint32_t *)®Data8(daddr); } uint64_t ®Data64(Addr daddr) { return *(uint64_t *)®Data8(daddr); } - private: - Addr addr; - static const Addr size = Regs::Size; - protected: RxState rxState; PacketFifo rxFifo; @@ -178,7 +169,7 @@ class Device : public Base TxState txState; PacketFifo txFifo; bool txFull; - PacketPtr txPacket; + EthPacketPtr txPacket; int txPacketOffset; int txPacketBytes; Addr txDmaAddr; @@ -218,7 +209,7 @@ class Device : public Base /** * receive address filter */ - bool rxFilter(const PacketPtr &packet); + bool rxFilter(const EthPacketPtr &packet); /** * device configuration @@ -230,7 +221,7 @@ class Device : public Base * device ethernet interface */ public: - bool recvPacket(PacketPtr packet); + bool recvPacket(EthPacketPtr packet); void transferDone(); void setInterface(Interface *i) { assert(!interface); interface = i; } @@ -238,12 +229,10 @@ class Device : public Base * DMA parameters */ protected: - void rxDmaCopy(); void rxDmaDone(); friend class EventWrapper<Device, &Device::rxDmaDone>; EventWrapper<Device, &Device::rxDmaDone> rxDmaEvent; - void txDmaCopy(); void txDmaDone(); friend class EventWrapper<Device, &Device::txDmaDone>; EventWrapper<Device, &Device::txDmaDone> txDmaEvent; @@ -262,25 +251,16 @@ class Device : public Base void devIntrChangeMask(uint32_t newmask); /** - * PCI Configuration interface - */ - public: - virtual void writeConfig(int offset, int size, const uint8_t *data); - -/** * Memory Interface */ public: - virtual Fault read(MemReqPtr &req, uint8_t *data); - virtual Fault write(MemReqPtr &req, const uint8_t *data); + virtual Tick read(Packet &pkt); + virtual Tick write(Packet &pkt); void prepareIO(int cpu, int index); void prepareRead(int cpu, int index); void prepareWrite(int cpu, int index); - Fault iprRead(Addr daddr, int cpu, uint64_t &result); - Fault readBar0(MemReqPtr &req, Addr daddr, uint8_t *data); - Fault writeBar0(MemReqPtr &req, Addr daddr, const uint8_t *data); - Tick cacheAccess(MemReqPtr &req); + // Fault iprRead(Addr daddr, int cpu, uint64_t &result); /** * Statistics @@ -328,17 +308,8 @@ class Device : public Base public: struct Params : public Base::Params { - IntrControl *i; - PhysicalMemory *pmem; Tick tx_delay; Tick rx_delay; - HierParams *hier; - Bus *pio_bus; - Bus *header_bus; - Bus *payload_bus; - Tick pio_latency; - PhysicalMemory *physmem; - IntrControl *intctrl; bool rx_filter; Net::EthAddr eaddr; uint32_t rx_max_copy; @@ -352,7 +323,6 @@ class Device : public Base Tick dma_read_factor; Tick dma_write_delay; Tick dma_write_factor; - bool dma_no_allocate; bool rx_thread; bool tx_thread; bool rss; @@ -378,7 +348,7 @@ class Interface : public EtherInt Interface(const std::string &name, Device *d) : EtherInt(name), dev(d) { dev->setInterface(this); } - virtual bool recvPacket(PacketPtr pkt) { return dev->recvPacket(pkt); } + virtual bool recvPacket(EthPacketPtr pkt) { return dev->recvPacket(pkt); } virtual void sendDone() { dev->transferDone(); } }; diff --git a/dev/tsunami_cchip.cc b/dev/tsunami_cchip.cc index 81ad9a71d..f35c34138 100644 --- a/dev/tsunami_cchip.cc +++ b/dev/tsunami_cchip.cc @@ -80,72 +80,65 @@ TsunamiCChip::read(Packet &pkt) Addr regnum = (pkt.addr - pioAddr) >> 6; Addr daddr = (pkt.addr - pioAddr); - uint64_t *data64; - + pkt.allocate(); switch (pkt.size) { case sizeof(uint64_t): - if (!pkt.data) { - data64 = new uint64_t; - pkt.data = (uint8_t*)data64; - } else - data64 = (uint64_t*)pkt.data; - if (daddr & TSDEV_CC_BDIMS) { - *data64 = dim[(daddr >> 4) & 0x3F]; + pkt.set(dim[(daddr >> 4) & 0x3F]); break; } if (daddr & TSDEV_CC_BDIRS) { - *data64 = dir[(daddr >> 4) & 0x3F]; + pkt.set(dir[(daddr >> 4) & 0x3F]); break; } switch(regnum) { case TSDEV_CC_CSR: - *data64 = 0x0; + pkt.set(0x0); break; case TSDEV_CC_MTR: panic("TSDEV_CC_MTR not implemeted\n"); break; case TSDEV_CC_MISC: - *data64 = (ipint << 8) & 0xF | (itint << 4) & 0xF | - (pkt.req->getCpuNum() & 0x3); + pkt.set((ipint << 8) & 0xF | (itint << 4) & 0xF | + (pkt.req->getCpuNum() & 0x3)); break; case TSDEV_CC_AAR0: case TSDEV_CC_AAR1: case TSDEV_CC_AAR2: case TSDEV_CC_AAR3: - *data64 = 0; + pkt.set(0); break; case TSDEV_CC_DIM0: - *data64 = dim[0]; + pkt.set(dim[0]); break; case TSDEV_CC_DIM1: - *data64 = dim[1]; + pkt.set(dim[1]); break; case TSDEV_CC_DIM2: - *data64 = dim[2]; + pkt.set(dim[2]); break; case TSDEV_CC_DIM3: - *data64 = dim[3]; + pkt.set(dim[3]); break; case TSDEV_CC_DIR0: - *data64 = dir[0]; + pkt.set(dir[0]); break; case TSDEV_CC_DIR1: - *data64 = dir[1]; + pkt.set(dir[1]); break; case TSDEV_CC_DIR2: - *data64 = dir[2]; + pkt.set(dir[2]); break; case TSDEV_CC_DIR3: - *data64 = dir[3]; + pkt.set(dir[3]); break; case TSDEV_CC_DRIR: - *data64 = drir; + pkt.set(drir); break; case TSDEV_CC_PRBEN: panic("TSDEV_CC_PRBEN not implemented\n"); @@ -163,10 +156,10 @@ TsunamiCChip::read(Packet &pkt) panic("TSDEV_CC_MPRx not implemented\n"); break; case TSDEV_CC_IPIR: - *data64 = ipint; + pkt.set(ipint); break; case TSDEV_CC_ITIR: - *data64 = itint; + pkt.set(itint); break; default: panic("default in cchip read reached, accessing 0x%x\n"); @@ -180,7 +173,7 @@ TsunamiCChip::read(Packet &pkt) panic("invalid access size(?) for tsunami register!\n"); } DPRINTF(Tsunami, "Tsunami CChip: read regnum=%#x size=%d data=%lld\n", - regnum, pkt.size, *data64); + regnum, pkt.size, pkt.get<uint64_t>()); pkt.result = Success; return pioDelay; @@ -197,10 +190,9 @@ TsunamiCChip::write(Packet &pkt) Addr regnum = (pkt.addr - pioAddr) >> 6 ; - uint64_t val = *(uint64_t *)pkt.data; assert(pkt.size == sizeof(uint64_t)); - DPRINTF(Tsunami, "write - addr=%#x value=%#x\n", pkt.addr, val); + DPRINTF(Tsunami, "write - addr=%#x value=%#x\n", pkt.addr, pkt.get<uint64_t>()); bool supportedWrite = false; @@ -215,7 +207,7 @@ TsunamiCChip::write(Packet &pkt) olddim = dim[number]; olddir = dir[number]; - dim[number] = val; + dim[number] = pkt.get<uint64_t>(); dir[number] = dim[number] & drir; for(int x = 0; x < Tsunami::Max_CPUs; x++) { @@ -252,7 +244,7 @@ TsunamiCChip::write(Packet &pkt) panic("TSDEV_CC_MTR write not implemented\n"); case TSDEV_CC_MISC: uint64_t ipreq; - ipreq = (val >> 12) & 0xF; + ipreq = (pkt.get<uint64_t>() >> 12) & 0xF; //If it is bit 12-15, this is an IPI post if (ipreq) { reqIPI(ipreq); @@ -261,7 +253,7 @@ TsunamiCChip::write(Packet &pkt) //If it is bit 8-11, this is an IPI clear uint64_t ipintr; - ipintr = (val >> 8) & 0xF; + ipintr = (pkt.get<uint64_t>() >> 8) & 0xF; if (ipintr) { clearIPI(ipintr); supportedWrite = true; @@ -269,14 +261,14 @@ TsunamiCChip::write(Packet &pkt) //If it is the 4-7th bit, clear the RTC interrupt uint64_t itintr; - itintr = (val >> 4) & 0xF; + itintr = (pkt.get<uint64_t>() >> 4) & 0xF; if (itintr) { clearITI(itintr); supportedWrite = true; } // ignore NXMs - if (val & 0x10000000) + if (pkt.get<uint64_t>() & 0x10000000) supportedWrite = true; if(!supportedWrite) @@ -308,7 +300,7 @@ TsunamiCChip::write(Packet &pkt) olddim = dim[number]; olddir = dir[number]; - dim[number] = val; + dim[number] = pkt.get<uint64_t>(); dir[number] = dim[number] & drir; for(int x = 0; x < 64; x++) { @@ -358,13 +350,13 @@ TsunamiCChip::write(Packet &pkt) case TSDEV_CC_MPR3: panic("TSDEV_CC_MPRx write not implemented\n"); case TSDEV_CC_IPIR: - clearIPI(val); + clearIPI(pkt.get<uint64_t>()); break; case TSDEV_CC_ITIR: - clearITI(val); + clearITI(pkt.get<uint64_t>()); break; case TSDEV_CC_IPIQ: - reqIPI(val); + reqIPI(pkt.get<uint64_t>()); break; default: panic("default in cchip read reached, accessing 0x%x\n"); diff --git a/dev/tsunami_io.cc b/dev/tsunami_io.cc index ebf3492ac..ed526bdde 100644 --- a/dev/tsunami_io.cc +++ b/dev/tsunami_io.cc @@ -447,65 +447,51 @@ TsunamiIO::read(Packet &pkt) DPRINTF(Tsunami, "io read va=%#x size=%d IOPorrt=%#x\n", pkt.addr, pkt.size, daddr); - - uint8_t *data8; - uint64_t *data64; + pkt.allocate(); if (pkt.size == sizeof(uint8_t)) { - - if (!pkt.data) { - data8 = new uint8_t; - pkt.data = data8; - } else - data8 = pkt.data; switch(daddr) { // PIC1 mask read case TSDEV_PIC1_MASK: - *data8 = ~mask1; + pkt.set(~mask1); break; case TSDEV_PIC2_MASK: - *data8 = ~mask2; + pkt.set(~mask2); break; case TSDEV_PIC1_ISR: // !!! If this is modified 64bit case needs to be too // Pal code has to do a 64 bit physical read because there is // no load physical byte instruction - *data8 = picr; + pkt.set(picr); break; case TSDEV_PIC2_ISR: // PIC2 not implemnted... just return 0 - *data8 = 0x00; + pkt.set(0x00); break; case TSDEV_TMR0_DATA: - pitimer.counter0.read(data8); + pitimer.counter0.read(pkt.getPtr<uint8_t>()); break; case TSDEV_TMR1_DATA: - pitimer.counter1.read(data8); + pitimer.counter1.read(pkt.getPtr<uint8_t>()); break; case TSDEV_TMR2_DATA: - pitimer.counter2.read(data8); + pitimer.counter2.read(pkt.getPtr<uint8_t>()); break; case TSDEV_RTC_DATA: - rtc.readData(data8); + rtc.readData(pkt.getPtr<uint8_t>()); break; case TSDEV_CTRL_PORTB: if (pitimer.counter2.outputHigh()) - *data8 = PORTB_SPKR_HIGH; + pkt.set(PORTB_SPKR_HIGH); else - *data8 = 0x00; + pkt.set(0x00); break; default: panic("I/O Read - va%#x size %d\n", pkt.addr, pkt.size); } } else if (pkt.size == sizeof(uint64_t)) { - if (!pkt.data) { - data64 = new uint64_t; - pkt.data = (uint8_t*)data64; - } else - data64 = (uint64_t*)pkt.data; - if (daddr == TSDEV_PIC1_ISR) - *data64 = picr; + pkt.set<uint64_t>(picr); else panic("I/O Read - invalid addr - va %#x size %d\n", pkt.addr, pkt.size); @@ -524,20 +510,15 @@ TsunamiIO::write(Packet &pkt) assert(pkt.result == Unknown); assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); Addr daddr = pkt.addr - pioAddr; - uint8_t val = *pkt.data; - -#if TRACING_ON - uint64_t dt64 = val; -#endif DPRINTF(Tsunami, "io write - va=%#x size=%d IOPort=%#x Data=%#x\n", - pkt.addr, pkt.size, pkt.addr & 0xfff, dt64); + pkt.addr, pkt.size, pkt.addr & 0xfff, (uint32_t)pkt.get<uint8_t>()); assert(pkt.size == sizeof(uint8_t)); switch(daddr) { case TSDEV_PIC1_MASK: - mask1 = ~(val); + mask1 = ~(pkt.get<uint8_t>()); if ((picr & mask1) && !picInterrupting) { picInterrupting = true; tsunami->cchip->postDRIR(55); @@ -550,38 +531,38 @@ TsunamiIO::write(Packet &pkt) } break; case TSDEV_PIC2_MASK: - mask2 = val; + mask2 = pkt.get<uint8_t>(); //PIC2 Not implemented to interrupt break; case TSDEV_PIC1_ACK: // clear the interrupt on the PIC - picr &= ~(1 << (val & 0xF)); + picr &= ~(1 << (pkt.get<uint8_t>() & 0xF)); if (!(picr & mask1)) tsunami->cchip->clearDRIR(55); break; case TSDEV_DMA1_MODE: - mode1 = val; + mode1 = pkt.get<uint8_t>(); break; case TSDEV_DMA2_MODE: - mode2 = val; + mode2 = pkt.get<uint8_t>(); break; case TSDEV_TMR0_DATA: - pitimer.counter0.write(val); + pitimer.counter0.write(pkt.get<uint8_t>()); break; case TSDEV_TMR1_DATA: - pitimer.counter1.write(val); + pitimer.counter1.write(pkt.get<uint8_t>()); break; case TSDEV_TMR2_DATA: - pitimer.counter2.write(val); + pitimer.counter2.write(pkt.get<uint8_t>()); break; case TSDEV_TMR_CTRL: - pitimer.writeControl(val); + pitimer.writeControl(pkt.get<uint8_t>()); break; case TSDEV_RTC_ADDR: - rtc.writeAddr(val); + rtc.writeAddr(pkt.get<uint8_t>()); break; case TSDEV_RTC_DATA: - rtc.writeData(val); + rtc.writeData(pkt.get<uint8_t>()); break; case TSDEV_KBD: case TSDEV_DMA1_CMND: @@ -596,7 +577,7 @@ TsunamiIO::write(Packet &pkt) case TSDEV_CTRL_PORTB: break; default: - panic("I/O Write - va%#x size %d data %#x\n", pkt.addr, pkt.size, val); + panic("I/O Write - va%#x size %d data %#x\n", pkt.addr, pkt.size, pkt.get<uint8_t>()); } pkt.result = Success; diff --git a/dev/tsunami_pchip.cc b/dev/tsunami_pchip.cc index 66144b816..05b480cb8 100644 --- a/dev/tsunami_pchip.cc +++ b/dev/tsunami_pchip.cc @@ -70,75 +70,71 @@ TsunamiPChip::read(Packet &pkt) assert(pkt.result == Unknown); assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); + pkt.time = curTick + pioDelay; + pkt.allocate(); Addr daddr = (pkt.addr - pioAddr) >> 6;; + assert(pkt.size == sizeof(uint64_t)); - uint64_t *data64; - - if (!pkt.data) { - data64 = new uint64_t; - pkt.data = (uint8_t*)data64; - } else - data64 = (uint64_t*)pkt.data; DPRINTF(Tsunami, "read va=%#x size=%d\n", pkt.addr, pkt.size); switch(daddr) { case TSDEV_PC_WSBA0: - *data64 = wsba[0]; + pkt.set(wsba[0]); break; case TSDEV_PC_WSBA1: - *data64 = wsba[1]; + pkt.set(wsba[1]); break; case TSDEV_PC_WSBA2: - *data64 = wsba[2]; + pkt.set(wsba[2]); break; case TSDEV_PC_WSBA3: - *data64 = wsba[3]; + pkt.set(wsba[3]); break; case TSDEV_PC_WSM0: - *data64 = wsm[0]; + pkt.set(wsm[0]); break; case TSDEV_PC_WSM1: - *data64 = wsm[1]; + pkt.set(wsm[1]); break; case TSDEV_PC_WSM2: - *data64 = wsm[2]; + pkt.set(wsm[2]); break; case TSDEV_PC_WSM3: - *data64 = wsm[3]; + pkt.set(wsm[3]); break; case TSDEV_PC_TBA0: - *data64 = tba[0]; + pkt.set(tba[0]); break; case TSDEV_PC_TBA1: - *data64 = tba[1]; + pkt.set(tba[1]); break; case TSDEV_PC_TBA2: - *data64 = tba[2]; + pkt.set(tba[2]); break; case TSDEV_PC_TBA3: - *data64 = tba[3]; + pkt.set(tba[3]); break; case TSDEV_PC_PCTL: - *data64 = pctl; + pkt.set(pctl); break; case TSDEV_PC_PLAT: panic("PC_PLAT not implemented\n"); case TSDEV_PC_RES: panic("PC_RES not implemented\n"); case TSDEV_PC_PERROR: - *data64 = 0x00; + pkt.set((uint64_t)0x00); break; case TSDEV_PC_PERRMASK: - *data64 = 0x00; + pkt.set((uint64_t)0x00); break; case TSDEV_PC_PERRSET: panic("PC_PERRSET not implemented\n"); case TSDEV_PC_TLBIV: panic("PC_TLBIV not implemented\n"); case TSDEV_PC_TLBIA: - *data64 = 0x00; // shouldn't be readable, but linux + pkt.set((uint64_t)0x00); // shouldn't be readable, but linux break; case TSDEV_PC_PMONCTL: panic("PC_PMONCTL not implemented\n"); @@ -161,50 +157,49 @@ TsunamiPChip::write(Packet &pkt) assert(pkt.addr >= pioAddr && pkt.addr < pioAddr + pioSize); Addr daddr = (pkt.addr - pioAddr) >> 6; - uint64_t data64 = *(uint64_t *)pkt.data; assert(pkt.size == sizeof(uint64_t)); DPRINTF(Tsunami, "write - va=%#x size=%d \n", pkt.addr, pkt.size); switch(daddr) { case TSDEV_PC_WSBA0: - wsba[0] = data64; + wsba[0] = pkt.get<uint64_t>(); break; case TSDEV_PC_WSBA1: - wsba[1] = data64; + wsba[1] = pkt.get<uint64_t>(); break; case TSDEV_PC_WSBA2: - wsba[2] = data64; + wsba[2] = pkt.get<uint64_t>(); break; case TSDEV_PC_WSBA3: - wsba[3] = data64; + wsba[3] = pkt.get<uint64_t>(); break; case TSDEV_PC_WSM0: - wsm[0] = data64; + wsm[0] = pkt.get<uint64_t>(); break; case TSDEV_PC_WSM1: - wsm[1] = data64; + wsm[1] = pkt.get<uint64_t>(); break; case TSDEV_PC_WSM2: - wsm[2] = data64; + wsm[2] = pkt.get<uint64_t>(); break; case TSDEV_PC_WSM3: - wsm[3] = data64; + wsm[3] = pkt.get<uint64_t>(); break; case TSDEV_PC_TBA0: - tba[0] = data64; + tba[0] = pkt.get<uint64_t>(); break; case TSDEV_PC_TBA1: - tba[1] = data64; + tba[1] = pkt.get<uint64_t>(); break; case TSDEV_PC_TBA2: - tba[2] = data64; + tba[2] = pkt.get<uint64_t>(); break; case TSDEV_PC_TBA3: - tba[3] = data64; + tba[3] = pkt.get<uint64_t>(); break; case TSDEV_PC_PCTL: - pctl = data64; + pctl = pkt.get<uint64_t>(); break; case TSDEV_PC_PLAT: panic("PC_PLAT not implemented\n"); diff --git a/dev/uart8250.cc b/dev/uart8250.cc index 7e2f9d51f..84885456f 100644 --- a/dev/uart8250.cc +++ b/dev/uart8250.cc @@ -116,23 +116,17 @@ Uart8250::read(Packet &pkt) pkt.time = curTick + pioDelay; Addr daddr = pkt.addr - pioAddr; - uint8_t *data; + pkt.allocate(); DPRINTF(Uart, " read register %#x\n", daddr); - if (!pkt.data) { - data = new uint8_t; - pkt.data = data; - } else - data = pkt.data; - switch (daddr) { case 0x0: if (!(LCR & 0x80)) { // read byte if (cons->dataAvailable()) - cons->in(*data); + cons->in(*pkt.getPtr<uint8_t>()); else { - *data = 0; + pkt.set((uint8_t)0); // A limited amount of these are ok. DPRINTF(Uart, "empty read of RX register\n"); } @@ -147,7 +141,7 @@ Uart8250::read(Packet &pkt) break; case 0x1: if (!(LCR & 0x80)) { // Intr Enable Register(IER) - *data = IER; + pkt.set(IER); } else { // DLM divisor latch MSB ; } @@ -156,17 +150,17 @@ Uart8250::read(Packet &pkt) DPRINTF(Uart, "IIR Read, status = %#x\n", (uint32_t)status); if (status & RX_INT) /* Rx data interrupt has a higher priority */ - *data = IIR_RXID; + pkt.set(IIR_RXID); else if (status & TX_INT) - *data = IIR_TXID; + pkt.set(IIR_TXID); else - *data = IIR_NOPEND; + pkt.set(IIR_NOPEND); //Tx interrupts are cleared on IIR reads status &= ~TX_INT; break; case 0x3: // Line Control Register (LCR) - *data = LCR; + pkt.set(LCR); break; case 0x4: // Modem Control Register (MCR) break; @@ -177,13 +171,13 @@ Uart8250::read(Packet &pkt) if (cons->dataAvailable()) lsr = UART_LSR_DR; lsr |= UART_LSR_TEMT | UART_LSR_THRE; - *data = lsr; + pkt.set(lsr); break; case 0x6: // Modem Status Register (MSR) - *data = 0; + pkt.set((uint8_t)0); break; case 0x7: // Scratch Register (SCR) - *data = 0; // doesn't exist with at 8250. + pkt.set((uint8_t)0); // doesn't exist with at 8250. break; default: panic("Tried to access a UART port that doesn't exist\n"); @@ -207,14 +201,12 @@ Uart8250::write(Packet &pkt) pkt.time = curTick + pioDelay; Addr daddr = pkt.addr - pioAddr; - uint8_t *data = pkt.data; - - DPRINTF(Uart, " write register %#x value %#x\n", daddr, *data); + DPRINTF(Uart, " write register %#x value %#x\n", daddr, pkt.get<uint8_t>()); switch (daddr) { case 0x0: if (!(LCR & 0x80)) { // write byte - cons->out(*data); + cons->out(pkt.get<uint8_t>()); platform->clearConsoleInt(); status &= ~TX_INT; if (UART_IER_THRI & IER) @@ -225,7 +217,7 @@ Uart8250::write(Packet &pkt) break; case 0x1: if (!(LCR & 0x80)) { // Intr Enable Register(IER) - IER = *data; + IER = pkt.get<uint8_t>(); if (UART_IER_THRI & IER) { DPRINTF(Uart, "IER: IER_THRI set, scheduling TX intrrupt\n"); @@ -259,10 +251,10 @@ Uart8250::write(Packet &pkt) case 0x2: // FIFO Control Register (FCR) break; case 0x3: // Line Control Register (LCR) - LCR = *data; + LCR = pkt.get<uint8_t>(); break; case 0x4: // Modem Control Register (MCR) - if (*data == (UART_MCR_LOOP | 0x0A)) + if (pkt.get<uint8_t>() == (UART_MCR_LOOP | 0x0A)) MCR = 0x9A; break; case 0x7: // Scratch Register (SCR) diff --git a/dev/uart8250.hh b/dev/uart8250.hh index 76b17caf8..19e4438bc 100644 --- a/dev/uart8250.hh +++ b/dev/uart8250.hh @@ -44,13 +44,13 @@ * bit 2:1 ID of highest priority interrupt * bit 7:3 zeroes */ -#define IIR_NOPEND 0x1 +const uint8_t IIR_NOPEND = 0x1; // Interrupt IDs -#define IIR_MODEM 0x00 /* Modem Status (lowest priority) */ -#define IIR_TXID 0x02 /* Tx Data */ -#define IIR_RXID 0x04 /* Rx Data */ -#define IIR_LINE 0x06 /* Rx Line Status (highest priority)*/ +const uint8_t IIR_MODEM = 0x00; /* Modem Status (lowest priority) */ +const uint8_t IIR_TXID = 0x02; /* Tx Data */ +const uint8_t IIR_RXID = 0x04; /* Rx Data */ +const uint8_t IIR_LINE = 0x06; /* Rx Line Status (highest priority)*/ class SimConsole; class Platform; diff --git a/mem/bus.cc b/mem/bus.cc index 5e84beb83..86e834894 100644 --- a/mem/bus.cc +++ b/mem/bus.cc @@ -97,21 +97,30 @@ Bus::recvStatusChange(Port::Status status, int id) Port *port = interfaces[id]; AddrRangeList ranges; AddrRangeList snoops; + AddrRangeIter iter; + std::vector<DevMap>::iterator portIter; + + // Clean out any previously existent ids + for (portIter = portList.begin(); portIter != portList.end(); ) { + if (portIter->portId == id) + portIter = portList.erase(portIter); + else + portIter++; + } port->getPeerAddressRanges(ranges, snoops); // not dealing with snooping yet either assert(snoops.size() == 0); - // or multiple ranges - assert(ranges.size() == 1); - - DevMap dm; - dm.portId = id; - dm.range = ranges.front(); - - DPRINTF(MMU, "Adding range %llx - %llx for id %d\n", dm.range.start, - dm.range.end, id); - portList.push_back(dm); + for(iter = ranges.begin(); iter != ranges.end(); iter++) { + DevMap dm; + dm.portId = id; + dm.range = *iter; + + DPRINTF(MMU, "Adding range %llx - %llx for id %d\n", dm.range.start, + dm.range.end, id); + portList.push_back(dm); + } DPRINTF(MMU, "port list has %d entries\n", portList.size()); } diff --git a/mem/packet.hh b/mem/packet.hh index 843d34ac0..4329094d5 100644 --- a/mem/packet.hh +++ b/mem/packet.hh @@ -76,6 +76,26 @@ class Coherence{}; */ struct Packet { + private: + /** A pointer to the data being transfered. It can be differnt sizes + at each level of the heirarchy so it belongs in the packet, + not request. This may or may not be populated when a responder recieves + the packet. If not populated it memory should be allocated. + */ + PacketDataPtr data; + + /** Is the data pointer set to a value that shouldn't be freed when the + * packet is destroyed? */ + bool staticData; + /** The data pointer points to a value that should be freed when the packet + * is destroyed. */ + bool dynamicData; + /** the data pointer points to an array (thus delete [] ) needs to be called + * on it rather than simply delete.*/ + bool arrayData; + + + public: /** The address of the request, could be virtual or physical (depending on cache configurations). */ Addr addr; @@ -92,19 +112,10 @@ struct Packet // assert(dynamic_cast<Foo>) etc. /** A virtual base opaque structure used to hold the senders state. */ - SenderState *senderState; // virtual base opaque, + void *senderState; // virtual base opaque, // assert(dynamic_cast<Foo>) etc. - /** A pointer to the data being transfered. It can be differnt sizes - at each level of the heirarchy so it belongs in the packet, - not request. - This pointer may be NULL! If it isn't null when received by the producer - of data it refers to memory that has not been dynamically allocated. - Otherwise the producer should simply allocate dynamic memory to use. - */ - PacketDataPtr data; - - /** Indicates the size of the request. */ + /** Indicates the size of the request. */ int size; /** A index of the source of the transaction. */ @@ -130,10 +141,96 @@ struct Packet short getDest() const { return dest; } Packet() - : result(Unknown) + : data(NULL), staticData(false), dynamicData(false), arrayData(false), + result(Unknown) {} - void reset() { result = Unknown; } + ~Packet() + { deleteData(); } + + + /** Minimally reset a packet so something like simple cpu can reuse it. */ + void reset() { + result = Unknown; + if (dynamicData) { + deleteData(); + dynamicData = false; + arrayData = false; + } + } + + /** Set the data pointer to the following value that should not be freed. */ + template <typename T> + void dataStatic(T *p) { + assert(!dynamicData); + data = (PacketDataPtr)p; + staticData = true; + } + + /** Set the data pointer to a value that should have delete [] called on it. + */ + template <typename T> + void dataDynamicArray(T *p) { + assert(!staticData && !dynamicData); + data = (PacketDataPtr)p; + dynamicData = true; + arrayData = true; + } + + /** set the data pointer to a value that should have delete called on it. */ + template <typename T> + void dataDynamic(T *p) { + assert(!staticData && !dynamicData); + data = (PacketDataPtr)p; + dynamicData = true; + arrayData = false; + } + + /** return the value of what is pointed to in the packet. */ + template <typename T> + T get() { + assert(staticData || dynamicData); + assert(sizeof(T) <= size); + return *(T*)data; + } + + /** get a pointer to the data ptr. */ + template <typename T> + T* getPtr() { + assert(staticData || dynamicData); + return (T*)data; + } + + + /** set the value in the data pointer to v. */ + template <typename T> + void set(T v) { + assert(sizeof(T) <= size); + *(T*)data = v; + } + + /** delete the data pointed to in the data pointer. Ok to call to matter how + * data was allocted. */ + void deleteData() { + assert(staticData || dynamicData); + if (staticData) + return; + + if (arrayData) + delete [] data; + else + delete data; + } + + /** If there isn't data in the packet, allocate some. */ + void allocate() { + if (data) + return; + assert(!staticData); + dynamicData = true; + arrayData = true; + data = new uint8_t[size]; + } }; #endif //__MEM_PACKET_HH diff --git a/mem/physical.cc b/mem/physical.cc index b00935990..02a48b22b 100644 --- a/mem/physical.cc +++ b/mem/physical.cc @@ -69,8 +69,8 @@ PhysicalMemory::MemResponseEvent::description() return "Physical Memory Timing Access respnse event"; } -PhysicalMemory::PhysicalMemory(const string &n) - : MemObject(n), base_addr(0), pmem_addr(NULL), port(NULL) +PhysicalMemory::PhysicalMemory(const string &n, Tick latency) + : MemObject(n),base_addr(0), pmem_addr(NULL), port(NULL), lat(latency) { // Hardcoded to 128 MB for now. pmem_size = 1 << 27; @@ -137,6 +137,7 @@ Tick PhysicalMemory::doAtomicAccess(Packet &pkt) { doFunctionalAccess(pkt); + pkt.time = curTick + lat; return curTick + lat; } @@ -147,10 +148,12 @@ PhysicalMemory::doFunctionalAccess(Packet &pkt) switch (pkt.cmd) { case Read: - memcpy(pkt.data, pmem_addr + pkt.addr - base_addr, pkt.size); + memcpy(pkt.getPtr<uint8_t>(), pmem_addr + pkt.addr - base_addr, + pkt.size); break; case Write: - memcpy(pmem_addr + pkt.addr - base_addr, pkt.data, pkt.size); + memcpy(pmem_addr + pkt.addr - base_addr, pkt.getPtr<uint8_t>(), + pkt.size); break; default: panic("unimplemented"); @@ -344,20 +347,22 @@ BEGIN_DECLARE_SIM_OBJECT_PARAMS(PhysicalMemory) Param<string> file; Param<Range<Addr> > range; + Param<Tick> latency; END_DECLARE_SIM_OBJECT_PARAMS(PhysicalMemory) BEGIN_INIT_SIM_OBJECT_PARAMS(PhysicalMemory) INIT_PARAM_DFLT(file, "memory mapped file", ""), - INIT_PARAM(range, "Device Address Range") + INIT_PARAM(range, "Device Address Range"), + INIT_PARAM(latency, "Memory access latency") END_INIT_SIM_OBJECT_PARAMS(PhysicalMemory) CREATE_SIM_OBJECT(PhysicalMemory) { - return new PhysicalMemory(getInstanceName()); + return new PhysicalMemory(getInstanceName(), latency); } REGISTER_SIM_OBJECT("PhysicalMemory", PhysicalMemory) diff --git a/mem/physical.hh b/mem/physical.hh index ce0a2099c..f87683c45 100644 --- a/mem/physical.hh +++ b/mem/physical.hh @@ -71,7 +71,6 @@ class PhysicalMemory : public MemObject int numPorts; - int lat; struct MemResponseEvent : public Event { @@ -94,13 +93,14 @@ class PhysicalMemory : public MemObject uint8_t *pmem_addr; MemoryPort *port; int page_ptr; + Tick lat; public: Addr new_page(); uint64_t size() { return pmem_size; } public: - PhysicalMemory(const std::string &n); + PhysicalMemory(const std::string &n, Tick latency); virtual ~PhysicalMemory(); public: diff --git a/mem/port.cc b/mem/port.cc index d312f3e3c..32031d96c 100644 --- a/mem/port.cc +++ b/mem/port.cc @@ -45,7 +45,7 @@ Port::blobHelper(Addr addr, uint8_t *p, int size, Command cmd) !gen.done(); gen.next()) { req.setPaddr(pkt.addr = gen.addr()); req.setSize(pkt.size = gen.size()); - pkt.data = p; + pkt.dataStatic(p); sendFunctional(pkt); p += gen.size(); } diff --git a/python/m5/objects/Device.py b/python/m5/objects/Device.py index cda3b1824..2a71bbc65 100644 --- a/python/m5/objects/Device.py +++ b/python/m5/objects/Device.py @@ -12,3 +12,7 @@ class BasicPioDevice(PioDevice): abstract = True pio_addr = Param.Addr("Device Address") pio_latency = Param.Tick(1, "Programmed IO latency in simticks") + +class DmaDevice(PioDevice): + type = 'DmaDevice' + abstract = True diff --git a/python/m5/objects/Ethernet.py b/python/m5/objects/Ethernet.py index 22714e15c..0667fc6d7 100644 --- a/python/m5/objects/Ethernet.py +++ b/python/m5/objects/Ethernet.py @@ -67,14 +67,10 @@ class EtherDevBase(PciDevice): clock = Param.Clock('0ns', "State machine processor frequency") - physmem = Param.PhysicalMemory(Parent.any, "Physical Memory") - - payload_bus = Param.Bus(NULL, "The IO Bus to attach to for payload") dma_read_delay = Param.Latency('0us', "fixed delay for dma reads") dma_read_factor = Param.Latency('0us', "multiplier for dma reads") dma_write_delay = Param.Latency('0us', "fixed delay for dma writes") dma_write_factor = Param.Latency('0us', "multiplier for dma writes") - dma_no_allocate = Param.Bool(True, "Should we allocate cache on read") rx_delay = Param.Latency('1us', "Receive Delay") tx_delay = Param.Latency('1us', "Transmit Delay") @@ -92,6 +88,7 @@ class NSGigE(EtherDevBase): dma_data_free = Param.Bool(False, "DMA of Data is free") dma_desc_free = Param.Bool(False, "DMA of Descriptors is free") + dma_no_allocate = Param.Bool(True, "Should we allocate cache on read") class NSGigEInt(EtherInt): diff --git a/python/m5/objects/Ide.py b/python/m5/objects/Ide.py index 6855ec653..2403e6d36 100644 --- a/python/m5/objects/Ide.py +++ b/python/m5/objects/Ide.py @@ -8,7 +8,6 @@ class IdeDisk(SimObject): delay = Param.Latency('1us', "Fixed disk delay in microseconds") driveID = Param.IdeID('master', "Drive ID") image = Param.DiskImage("Disk image") - physmem = Param.PhysicalMemory(Parent.any, "Physical memory") class IdeController(PciDevice): type = 'IdeController' diff --git a/python/m5/objects/Pci.py b/python/m5/objects/Pci.py index f2ccce09f..85cefcd44 100644 --- a/python/m5/objects/Pci.py +++ b/python/m5/objects/Pci.py @@ -1,6 +1,5 @@ from m5 import * -from Device import BasicPioDevice -#, DmaDevice +from Device import BasicPioDevice, DmaDevice class PciConfigData(SimObject): type = 'PciConfigData' @@ -42,15 +41,15 @@ class PciConfigData(SimObject): class PciConfigAll(BasicPioDevice): type = 'PciConfigAll' -#class PciDevice(DmaDevice): -# type = 'PciDevice' -# abstract = True -# addr = 0xffffffffL -# pci_bus = Param.Int("PCI bus") -# pci_dev = Param.Int("PCI device number") -# pci_func = Param.Int("PCI function code") -# configdata = Param.PciConfigData(Parent.any, "PCI Config data") -# configspace = Param.PciConfigAll(Parent.any, "PCI Configspace") -# -#class PciFake(PciDevice): -# type = 'PciFake' +class PciDevice(DmaDevice): + type = 'PciDevice' + abstract = True + pci_bus = Param.Int("PCI bus") + pci_dev = Param.Int("PCI device number") + pci_func = Param.Int("PCI function code") + pio_latency = Param.Tick(1, "Programmed IO latency in simticks") + configdata = Param.PciConfigData(Parent.any, "PCI Config data") + configspace = Param.PciConfigAll(Parent.any, "PCI Configspace") + +class PciFake(PciDevice): + type = 'PciFake' diff --git a/python/m5/objects/PhysicalMemory.py b/python/m5/objects/PhysicalMemory.py index b69c969cb..e59e94e9b 100644 --- a/python/m5/objects/PhysicalMemory.py +++ b/python/m5/objects/PhysicalMemory.py @@ -1,7 +1,8 @@ from m5 import * -from Memory import Memory +from MemObject import * -class PhysicalMemory(Memory): +class PhysicalMemory(MemObject): type = 'PhysicalMemory' range = Param.AddrRange("Device Address") file = Param.String('', "memory mapped file") + latency = Param.Latency('10ns', "latency of an access") diff --git a/sim/byteswap.hh b/sim/byteswap.hh index 0dd0ba827..a8c5da9d7 100644 --- a/sim/byteswap.hh +++ b/sim/byteswap.hh @@ -38,6 +38,10 @@ // This lets us figure out what the byte order of the host system is #if defined(linux) #include <endian.h> +// If this is a linux system, lets used the optimized definitions if they exist. +// If one doesn't exist, we pretty much get what is listed below, so it all +// works out +#include <byteswap.h> #else #include <machine/endian.h> #endif @@ -47,6 +51,9 @@ static inline uint64_t swap_byte64(uint64_t x) { +#if defined(linux) + return bswap_64(x); +#else return (uint64_t)((((uint64_t)(x) & 0xff) << 56) | ((uint64_t)(x) & 0xff00ULL) << 40 | ((uint64_t)(x) & 0xff0000ULL) << 24 | @@ -55,22 +62,30 @@ swap_byte64(uint64_t x) ((uint64_t)(x) & 0xff0000000000ULL) >> 24 | ((uint64_t)(x) & 0xff000000000000ULL) >> 40 | ((uint64_t)(x) & 0xff00000000000000ULL) >> 56) ; +#endif } static inline uint32_t swap_byte32(uint32_t x) { +#if defined(linux) + return bswap_32(x); +#else return (uint32_t)(((uint32_t)(x) & 0xff) << 24 | ((uint32_t)(x) & 0xff00) << 8 | ((uint32_t)(x) & 0xff0000) >> 8 | ((uint32_t)(x) & 0xff000000) >> 24); - +#endif } static inline uint16_t swap_byte16(uint16_t x) { +#if defined(linux) + return bswap_16(x); +#else return (uint16_t)(((uint16_t)(x) & 0xff) << 8 | ((uint16_t)(x) & 0xff00) >> 8); +#endif } //This lets the compiler figure out how to call the swap_byte functions above |