summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--SConscript34
-rwxr-xr-xarch/isa_parser.py4
-rw-r--r--arch/mips/isa/decoder.isa291
-rw-r--r--arch/mips/isa/formats/fp.isa4
-rw-r--r--arch/mips/isa/formats/mem.isa26
-rw-r--r--arch/mips/isa/formats/util.isa21
-rw-r--r--arch/mips/isa_traits.cc31
-rw-r--r--arch/mips/isa_traits.hh170
-rw-r--r--base/chunk_generator.hh8
-rw-r--r--base/inet.hh38
-rw-r--r--configs/test/SysPaths.py32
-rw-r--r--configs/test/fs.py128
-rw-r--r--cpu/cpu_exec_context.cc2
-rw-r--r--cpu/simple/cpu.cc24
-rw-r--r--cpu/simple/cpu.hh3
-rw-r--r--dev/alpha_console.cc56
-rw-r--r--dev/etherbus.cc2
-rw-r--r--dev/etherbus.hh4
-rw-r--r--dev/etherdump.cc2
-rw-r--r--dev/etherdump.hh4
-rw-r--r--dev/etherint.hh4
-rw-r--r--dev/etherlink.cc14
-rw-r--r--dev/etherlink.hh8
-rw-r--r--dev/etherpkt.cc4
-rw-r--r--dev/etherpkt.hh12
-rw-r--r--dev/ethertap.cc8
-rw-r--r--dev/ethertap.hh6
-rw-r--r--dev/ide_ctrl.cc429
-rw-r--r--dev/ide_ctrl.hh45
-rw-r--r--dev/ide_disk.cc290
-rw-r--r--dev/ide_disk.hh23
-rw-r--r--dev/io_device.cc56
-rw-r--r--dev/io_device.hh49
-rw-r--r--dev/isa_fake.cc38
-rw-r--r--dev/ns_gige.cc695
-rw-r--r--dev/ns_gige.hh42
-rw-r--r--dev/pciconfigall.cc74
-rw-r--r--dev/pciconfigall.hh2
-rw-r--r--dev/pcidev.cc318
-rw-r--r--dev/pcidev.hh102
-rw-r--r--dev/pktfifo.cc10
-rw-r--r--dev/pktfifo.hh12
-rw-r--r--dev/sinic.cc334
-rw-r--r--dev/sinic.hh44
-rw-r--r--dev/tsunami_cchip.cc66
-rw-r--r--dev/tsunami_io.cc69
-rw-r--r--dev/tsunami_pchip.cc69
-rw-r--r--dev/uart8250.cc40
-rw-r--r--dev/uart8250.hh10
-rw-r--r--mem/bus.cc29
-rw-r--r--mem/packet.hh123
-rw-r--r--mem/physical.cc17
-rw-r--r--mem/physical.hh4
-rw-r--r--mem/port.cc2
-rw-r--r--python/m5/objects/Device.py4
-rw-r--r--python/m5/objects/Ethernet.py5
-rw-r--r--python/m5/objects/Ide.py1
-rw-r--r--python/m5/objects/Pci.py27
-rw-r--r--python/m5/objects/PhysicalMemory.py5
-rw-r--r--sim/byteswap.hh17
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 &section);
-
};
+ 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 &section)
}
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 &section)
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 &section)
{
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 &section);
};
-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 &section)
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 &section);
- /**
- * 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 &section)
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 &reg = *(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 &reg = *(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 &reg = *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 &section)
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 &section)
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 &section)
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 &section)
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 &section);
};
-
-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 &reg = *(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 &reg = *(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 &section)
}
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 &section)
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 &section)
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 &section)
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 &regData32(Addr daddr) { return *(uint32_t *)&regData8(daddr); }
uint64_t &regData64(Addr daddr) { return *(uint64_t *)&regData8(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